From: barrett@daisy.ee.und.ac.za (Alan P Barrett)
Newsgroups: comp.sys.hp
Subject: Re: rdate for HPUX...
Date: 22 Jan 1993 17:45:36 +0200
Organization: Dept. Elec. Eng., Univ. Natal, Durban, S. Africa
NNTP-Posting-Host: daisy.ee.und.ac.za

In article <8579@tivoli.UUCP>,
stuart@TIVOLI.COM (Stuart Jarriel) writes:
> I have been looking at the HP-specific ftp sites for rdate and havent
> come across it.  I already have xntp, timed, etc..., but would like rdate 
> as a simpler client for some systems.

I don't have an rdate client, but I append source for an rdate server,
which I call rfc868time.

Install in /etc/inetd.conf as follows:

time	stream tcp  nowait  nobody  /usr/local/lib/rfc868time rfc868time
time	dgram  udp  wait    nobody  /usr/local/lib/rfc868time rfc868time

--apb
Alan Barrett, Dept. of Electronic Eng., Univ. of Natal, Durban, South Africa
RFC822: barrett@ee.und.ac.za

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Alan P Barrett <barrett@undeed> on Fri Jan 22 17:44:03 1993
#
# This archive contains:
#	rfc868time.c	
#

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - rfc868time.c
cat >rfc868time.c <<'@EOF'
/* rfc868time.c
 * A P Barrett, 1991.  Public domain.
 *
 * Outputs the number of seconds since 1 Jan 1900 00:00:00 UTC,
 * as a 32 bit number in network byte order.
 * See RFC868.
 *
 * Contains lots of ugly code to help it deal with UDP packets,
 * and with the way some inetd implementations may invoke it with
 * stdout closed.  Sorry.
 *
 * Tell /etc/inetd.conf something like this:
 *  time  stream tcp  nowait  nobody  /usr/local/lib/rfc868time rfc868time
 *  time  dgram  udp  wait    nobody  /usr/local/lib/rfc868time rfc868time
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>

/* #define DEBUGLOG "/usr/tmp/rfc868.log" /**/

main(argc, argv)
    int argc;
    char **argv;
{
#ifdef DEBUGLOG
    FILE *logfp;		/* for debug messages */
#endif
    unsigned long ultime;	/* the time, in seconds from 1 Jan 1900. */
    char chtime[4];		/* the four output octets */
    struct stat statbuf;	/* to check if fd 1 is open */
    struct sockaddr localsock;	/* our socket address */
    int localsocklen = sizeof(localsock);
    struct sockaddr remsock;	/* who is talking to us */
    int remsocklen = sizeof(remsock);
    int flags, oldflags;	/* fcntl flags */
    char buf[BUFSIZ];		/* for input packet, if any */
    int len;
    int no_stdout = 0;		/* whether stdout was not open */
    int use_sendto = 0;		/* whether we have to use sendto() */

    /*
     * if fd 1 is not open then dup fd 0 to fd 1,
     * in case inetd didn't do it
     */
    if (fstat(1, &statbuf) < 0) {
	(void) dup2(0, 1);
	no_stdout = 1;
    }

#ifdef DEBUGLOG
    /*
     * open the debug log after ensuring fd 1 is open
     */
    logfp = fopen(DEBUGLOG, "a");
#endif

#ifdef DEBUGLOG
    /*
     * report if stdout was not open
     */
    if (no_stdout) {
	(void) fprintf(logfp, "%s: stdout was not open\n", argv[0]);
    }
#endif

    /*
     * If we are being called due to a UDP packet, we have to use
     * recvfrom() to read the packet and get the source address.
     * Later, we will have to use sendto() instead of write() for output.
     *
     * Set the O_NDELAY flag to prevent the read from blocking, and
     * restore the flag afterwards.
     */
    if (getsockname(0, &localsock, &localsocklen) == 0) {
	/* our stdin is a socket */
#ifdef DEBUGLOG
	(void) fprintf(logfp, "%s: stdin is a socket\n", argv[0]);
#endif
	if (localsock.sa_family == AF_INET) {
	    /* it's an Internet socket */
#ifdef DEBUGLOG
	    (void) fprintf(logfp, "%s: stdin is an AF_INET socket\n", argv[0]);
#endif
	    /* I don't know how to tell if it's a UDP socket, so
	     * just set O_NDELAY and try the recvfrom now */
	    oldflags = fcntl(0, F_GETFL, 0);
	    flags = oldflags | O_NDELAY;
	    (void) fcntl(0, F_SETFL, flags);
	    len = recvfrom(0, buf, sizeof(buf), 0, &remsock, &remsocklen);
	    if (len > 0 && remsocklen > 0) {
		/* must have been a UDP socket.
		 * remember to use sendto() instead of write() later. */
#ifdef DEBUGLOG
		(void) fprintf(logfp, "%s: stdin is a UDP socket\n", argv[0]);
#endif
		use_sendto = 1;
	    }
	    (void) fcntl(0, F_SETFL, oldflags);
	}
    }

#ifdef DEBUGLOG
    /*
     * report if stdout is a socket
     */
    if (getsockname(1, &localsock, &localsocklen) == 0) {
	(void) fprintf(logfp, "%s: stdout is a socket\n", argv[0]);
	if (localsock.sa_family == AF_INET) {
	    /* it's an Internet socket */
	    (void) fprintf(logfp, "%s: stdout is an AF_INET socket\n", argv[0]);
	}
    }
#endif /* DEBUGLOG */

    /*
     * get time in seconds since 1970, and hence seconds since 1900.
     *
     * there were 2208988800 seconds between 1 Jan 1900 and 1 Jan 1970
     */
    ultime = 2208988800L + (unsigned long) time((time_t *)0);

    /*
     * convert to network byte order
     * (could be more efficient at the expense of portability)
     */
    chtime[0] = (char) ((ultime>>24) & 0xff);
    chtime[1] = (char) ((ultime>>16) & 0xff);
    chtime[2] = (char) ((ultime>>8) & 0xff);
    chtime[3] = (char) (ultime & 0xff); /* XXX:  lint says 'conversion
					from long may lose accuracy' on
					this line, but not on the
					preceding lines.  Why?  */

    /*
     * output result
     *
     * XXX: hope that it all goes into one UDP packet, if we are being called
     * via UDP.
     */
    if (use_sendto) {
	len = sendto(1, chtime, 4, 0, &remsock, remsocklen);
    } else {
	len = write(1, chtime, 4);
    }
    if (len != 4) {
	(void) fprintf(stderr, "%s: (time %lu) write failed: %s\n", argv[0],
			ultime, strerror(errno));
#ifdef DEBUGLOG
	(void) fprintf(logfp, "%s: (time %lu) write failed: %s\n", argv[0],
			ultime, strerror(errno));
#endif
	exit(1);
    }
#ifdef DEBUGLOG
	(void) fprintf(logfp, "%s: (time %lu) successful\n", argv[0],
			ultime);
#endif
    exit (0);
}
@EOF

chmod 644 rfc868time.c

exit 0
Newsgroups: comp.sys.hp,comp.sys.ibm.pc.hardware