SUMMARY: safer rdate

From: Fletcher B. Cocquyt (
Date: Tue Feb 18 1997 - 09:57:42 CST

I asked:

Has anyone run across a smarter version of rdate that will take a
threshold argument? Something to say, don't synch the date to the
remote machine if it is more than N seconds off the current time?

Thanks to:

Arthur Darren Dunham <>
"Roger Salisbury" <>

They suggested:
1) Perl scripts to kill old rdates
2) xntp (which I already use to sync my time server to the atmoic clock)

I have modified the rdate source to date a 3rd argument. If the date
between the server and client differs by more than N seconds, the
client's clock is not reset, but a warning message is printed.

I have attached the modified source code; it compiles and tests fine
on my Solaris 2.5 system with:
cc -o saferdate saferdate.c -lsocket -lnsl
using Sun's compiler.

Fletcher B. Cocquyt	System Administrator 	Trout Trading		Hamilton, Bermuda

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <netdb.h>
#include <time.h>

#include <stdio.h>

#define BASE1970 2208988800L /* difference between Unix time and net time */

main (argc,argv)
int argc;
char *argv[];
        int i;

        if (argc != 3) {
                printf("USAGE: %s <host> <N>\n",argv[0]);
                printf("Syncs the local clock to that of <host> ONLY if\n");
                printf("the two clocks are less than N seconds apart.\n");


char *host;
long thresh;
        struct hostent *him; /* host table entry */
        struct servent *timeServ; /* sevice file entry */
        struct sockaddr_in sin; /* socket address */
        int fd; /* network file descriptor */
        long unixTime; /* time in Unix format */
        long localTime;
        u_char netTime[4]; /* time in network format */
        int i; /* loop variable */
        int diff;
        char *ctime();

        if ((him = gethostbyname(host)) == NULL) {
                fprintf(stderr, "rdate: Unknown host %s\n", host);

        if ((timeServ = getservbyname("time","tcp")) == NULL) {
                fprintf(stderr, "rdate: time/tcp: unknown service\n");

        if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

        sin.sin_family = him->h_addrtype;
        bcopy(him->h_addr, (caddr_t)&sin.sin_addr, him->h_length);
        sin.sin_port = timeServ->s_port;

        if (connect(fd, &sin, sizeof(sin)) < 0) {

        /* read in the response */
        for (i = 0; i < 4; i++)
                if (read(fd, &netTime[i], 1) != 1) {

        unixTime = ntohl(* (long *) netTime) - BASE1970;
        printf("[%s] \t %ld\n",him->h_name,unixTime);
        printf("Local \t\t %ld\n",localTime);
        diff = (int) abs(localTime - unixTime);
        printf("Time difference [%d] seconds\n",diff);
        if (diff>(int)thresh) {
                printf("WARNING: NOT RESETTING local clock (diff>thresh) [%d]>[%ld]\n",diff,thresh);
        else {
                printf("OK, adjusting local clock by [%d] seconds (diff<=thresh) [%d]<=[%ld]\n",diff,diff,thresh);
                if ((int) getuid()==0)
                        printf("Sorry, must be root to adjust clock - no changes made\n");

This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:11:46 CDT