From: Operator (root@fir.canberra.edu.au)
Date: 08/07/93


From: root@fir.canberra.edu.au (Operator)
Subject: Re: rdate for linux
Date:  7 Aug 1993 14:43:41 GMT

In <23jr86$pfj@info2.rus.uni-stuttgart.de> weinmann@izfm.uni-stuttgart.de (Michael Weinmann) writes:

>Does anyone have a rdate programm for linux. I want to set the time and date of
>our linux-box.

>Michael

Here's a version with minor mods from an original I found somewhere on
the net. It has been compiled and run successfully under Linux 0.99pl9.

rdate.8 and rdate.c follow.

        Ross Johnson <rpj@ise.canberra.edu.au>

==================================cut here==============================
.TH RDATE 8 "26 May 1993"
.SH NAME
rdate \- set system date from a remote host
.SH SYNOPSIS
.B rdate
.B [\fI -p\fB ]
.I hostname
.SH DESCRIPTION
.LP
.B rdate
sets the local date and
time from the
.I hostname
given as argument.
You must be super-user on the local system.
The \fI-p\fR option allows printing the date from the remote machine
without attempting to set the local machines date and time. Use of the
option doesn't require super-user priviledge.

Typically
.B rdate
can be inserted as part of your
.B /etc/rc.local
startup script.
.SH FILES
.PD 0
.TP 20
.B /etc/rc.local
.PD
.SH BUGS
.LP
None.

==================================cut here==============================
/*
 * rdate.c: Set the date from the specified host
 *
 * Uses the rfc868 time protocol at socket 37.
 * Time is returned as the number of seconds since
 * midnight January 1st 1900.
 *
 * Original revision 1.3 89/11/10 00:23:06 christos
 * Initial revision
 *
 * Modified by Ross Johnson
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>

extern int errno, sys_nerr;
extern char *sys_errlist[];

#define strerror(e) \
        ((e) >= 0 || (e) < sys_nerr ? sys_errlist[(e)] : "Unknown error")

# define PROGNAME(b) ((((char *) strrchr(*(b), '/')) != (char *) 0) ? \
                        ((char *) (strrchr(*(b), '/') + 1)) : *(b))

static char *pname;

#define DIFFERENCE 2208988800UL /* seconds from midnight Jan 1900 - 1970 */

int
main(argc, argv)
int argc;
char *argv[];
{
    int pr, s, tim;
    char *hname;
    struct hostent *hp;
    struct protoent *pp;
    struct servent *sp, ssp;
    struct sockaddr_in sa;

    pname = PROGNAME(argv);

    if (argc == 1) {
        (void) fprintf(stderr, "Usage: %s [-p] <hostname>.\n", pname);
        exit(1);
    }
    pr = (strcmp(argv[1], "-p") == 0);
    if (argc < pr + 2) {
        (void) fprintf(stderr, "Usage: %s [-p] <hostname>.\n", pname);
        exit(1);
    }
    hname = argv[pr + 1];

    if (isdigit(hname[0])) {
        unsigned long i_addr;

        if ((i_addr = inet_addr(hname)) == -1) {
            (void) fprintf(stderr, "%s: Invalid host name `%s'. (%s)\n",
                pname, hname, strerror(errno));
                exit(errno);
        }
        sa.sin_addr.s_addr = i_addr;
        sa.sin_family = htons(AF_INET);

        if ((hp = gethostbyaddr((char *)&i_addr, sizeof(unsigned long), AF_INET))
                == (struct hostent *) 0) {
            (void) fprintf(stderr, "%s: Unknown host `%s'. (%s).\n",
                pname, hname, strerror(errno));
            exit(errno);
        }
    }
    else {
        if ((hp = gethostbyname(hname)) == (struct hostent *) 0) {
            (void) fprintf(stderr, "%s: Unknown host `%s'. (%s).\n",
                pname, hname, strerror(errno));
            exit(errno);
        } else {
                sa.sin_family = hp->h_addrtype;
                bcopy (hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
        }
    }

    if ((sp = getservbyname("time", "tcp")) == (struct servent *) 0) {
        fprintf(stderr, "%s: unknown service `time'. (%s)\n",
                pname, strerror(errno));
        exit(errno);
    }
    if ((pp = getprotobyname(sp->s_proto)) == (struct protoent *) 0) {
        (void) fprintf(stderr, "%s: Could not get protocol `tcp'. (%s).\n",
            pname, strerror(errno));
        exit(errno);
    }

    if ((s = socket(AF_INET, SOCK_STREAM, pp->p_proto)) == -1) {
        (void) fprintf(stderr, "%s: Could not create socket. (%s).\n",
            pname, strerror(errno));
        exit(errno);
    }
    sa.sin_port = sp->s_port;

    if ( connect(s, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
        (void) fprintf(stderr, "%s: Could not connect socket. (%s).\n",
            pname, strerror(errno));
        exit(errno);
    }

    if (read(s, &tim, sizeof(time_t)) != sizeof(time_t)) {
        (void) fprintf(stderr, "%s: Read failed. (%s).\n",
            pname, strerror(errno));
        exit(errno);
    }
    (void) close(s);
    tim = ntohl(tim) - DIFFERENCE;

    if ( !pr )
        if (stime(&tim) == -1) {
            (void) fprintf(stderr, "%s: Could not set time of day. (%s)\n",
                pname, strerror(errno));
            exit(errno);
        }

    (void) fprintf(stdout, ctime(&tim));
    exit(0);
} /* end main */