/*
 * synctime.c
 *
 * A program to synchronize the time of the local machine with that of
 * the remote time server.
 *
 * Copyright (c) 2001-2003 Wu Yongwei. All rights reserved.
 *
 * Last updated on 16 September 2003
 *
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define DEFAULTTIMESERVER   "129.6.15.29"   /* time-b.nist.gov */
#define INVALID_SOCKET      (-1)            /* borrowed from Windows */

#ifdef __CYGWIN__
#define timezone ((long)_timezone)          /* for Cygwin compatibility */
#endif

char *progname = "synctime";
int  uflag, vflag;
int  accuracy;

void reporterror(const char *msg)
{
    fprintf(stderr, "%s: %s\n", progname, msg);
}

u_int32_t resolvehost(const char *hostname)
{
    struct in_addr addr;
    struct hostent *hostent_ptr;
    if ( (addr.s_addr = inet_addr(hostname)) == INADDR_NONE) {
        if (!(hostent_ptr = gethostbyname(hostname))) {
            return INADDR_NONE;
        }
        memcpy(&addr, hostent_ptr->h_addr, hostent_ptr->h_length);
    }
    return addr.s_addr;
}

int main(int argc, char *argv[])
{
    u_int32_t           timeserver;
    char                buf[512], optch;
    int                 connfd;
    int                 len, n, diff;
    time_t              to;
    char                *timeline;
    unsigned            tmp, year, mon, mday, hour, min, sec, health;
    struct sockaddr_in  servaddr;
    struct tm           when;
    struct timeval      tv;

    /* Initialize */
    uflag = 0;
    vflag = 0;
    accuracy = 1;
    timeserver = inet_addr(DEFAULTTIMESERVER);

    /* Get command-line options */
    while ( (optch = getopt(argc, argv, "huvA:S:")) != EOF) {
        switch (optch) {
        case 'h':
            printf("Usage: %s [-huv] [-A accuracy] [-S timeserver]\n", progname);
            puts  ("  h : help");
            puts  ("  u : auto-update");
            puts  ("  v : verbose");
            puts  ("  A accuracy   : specify accuracy required in seconds [ default: 1 ]");
            puts  ("  S timeserver : choose timeserver [ default: " DEFAULTTIMESERVER " ]");
            puts  ("\nA list of time servers can be got from ftp://time-b.nist.gov/pub/nist-srv.lst");
            exit(0);
            break;
        case 'u':
            uflag = 1;
            break;
        case 'v':
            vflag = 1;
            break;
        case 'A':
            accuracy = atoi(optarg);
            break;
        case 'S':
            if ( (timeserver = resolvehost(optarg)) == INADDR_NONE) {
                fprintf(stderr, "Unknown remote host\n");
                exit(1);
            }
            break;
        default:
            fprintf(stderr, "Type '%s -h' to get help\n", progname);
            exit(1);
        }
    }

    /* Set time server IP and port */
    memset(&servaddr, 0, sizeof servaddr);
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = timeserver;
    servaddr.sin_port = htons(13);

    /* Connect to time server */
    connfd = socket(AF_INET, SOCK_STREAM, 0);
    if (connfd == INVALID_SOCKET) {
        reporterror("Socket error");
        exit(1);
    }
    if (connect(connfd, (struct sockaddr *)&servaddr, sizeof servaddr) < 0) {
        reporterror("Unable to connect to remote host");
        exit(1);
    }

    /* Receive data */
    len = 0;
    do {
        n = recv(connfd, buf + len, sizeof buf - len - 1, 0);
        len += n;
    } while (n > 0);

    /* Close socket */
    close(connfd);

    /* Error handling */
    if (len == 0) {
        reporterror("Remote server does not return any data");
        exit(1);
    }

    /* Clean extra LFs */
    if (len && buf[len - 1] == '\n') {
        buf[--len] = '\0';
    } else {
        buf[len] = '\0';
    }
    if (buf[0] == '\n') {
        memmove(buf, buf + 1, len--);
    }

    /* Display remote time */
    if (!uflag || vflag) {
        printf("Remote: %s\n", buf);
    }

    /* Get and display local-machine time */
    tzset();
    gettimeofday(&tv, NULL);
    timeline = ctime(&(tv.tv_sec));
    if (!uflag || vflag) {
        printf("Local machine: %.19s.%.3hu %.4s %+.2d%.2d\n",
               timeline,
               (unsigned)(tv.tv_usec / 1000),
               &timeline[20],
               (int)(-timezone / 3600),
               abs(timezone) / 60 % 60);
    }

    /* Analyse remote time */
    if (sscanf(buf, "%u %u-%u-%u %u:%u:%u %u %u %u",
               &tmp, &year, &mon, &mday, &hour, &min, &sec,
               &tmp, &tmp, &health) != 10) {
        /*
         * For an explanation of the code format, check
         *   http://www.bldrdoc.gov/timefreq/service/its.htm
         */
        reporterror("Time string format incorrect");
        exit(1);
    } else {

        /* Check health state */
        if (health >= 2) {
            reporterror("Time server is not fully healthy");
            if (uflag) {
                reporterror("Synchronization will not be performed");
            }
            exit(2);
        } else if (health == 1) {
            if (vflag) {
                puts("Remote time may be in error by up to 5 seconds.");
            }
            if (accuracy < 5) {
                accuracy = 5;
            }
        }

        /* Construct four-digit year from local century data */
        if (year < 100) {
            year += ((timeline[20] - '0') * 10 + (timeline[21] - '0')) * 100;
        }

        /* Fill in struct tm */
        memset(&when, 0, sizeof when);
        when.tm_sec = sec;
        when.tm_min = min;
        when.tm_hour = hour;
        when.tm_mday = mday;
        when.tm_mon = mon - 1;
        when.tm_year = year - 1900;

        /* Convert remote time to time_t (in UTC) */
        to = mktime(&when) - timezone;

        /* Calculate difference in seconds */
        diff = tv.tv_sec + (tv.tv_usec > 500000 ? 1 : 0) - to;

        /* Display information and/or do adjustments */
        if (abs(diff) < accuracy) {
            if (!uflag || vflag) {
                puts("Clocks match!");
            }
        } else {
            if (!uflag || vflag) {
                printf("%d second%s %s\n",
                       abs(diff),
                       abs(diff) > 1 ? "s" : "",
                       diff > 0 ? "fast" : "behind");
            }
            tv.tv_sec = to;
            tv.tv_usec = 0;
            if (uflag) {
                if (settimeofday(&tv, NULL) == 0) {
                    if (vflag) {
                        puts("Time synchronized");
                    }
                } else {
                    reporterror("root privilege needed to set time");
                }
            }
        }
    }

    return 0;
}

    Source: geocities.com/yongweiwu