main (argc,argv)
int argc;
char *argv[];
{
/*
	client process to connect to  the time service via port 37 using
	udp.  The client process uses the time message received to check 
	(and optionally to set) the time of the local clock.  the comparison 
	assumes that the local clock keeps time in seconds from 1/1/70 
	which is the UNIX standard, and it assumes that the received time
	is in seconds since 1900.0 to conform to rfc868.  It computes the
	time difference by subtracting 2208988800 from the received time
	to convert it to seconds since 1970 and then makes the comparison
	directly. If the local machine keeps time in some other way, then 
	the comparison method will have to change, but the rest should be 
	okay.

	This software was developed with US Government support
	and it may not be sold, restricted or licensed.  You 
	may duplicate this program provided that this notice
	remains in all of the copies, and you may give it to
	others provided they understand and agree to this
	condition.

	This program and the time protocol it uses are under 
	development and the implementation may change without 
	notice.

	For questions or additional information, contact:

	Judah Levine
	Time and Frequency Division
	NIST/847
	325 Broadway
	Boulder, Colorado 80303
	(303) 492 7785
	jlevine@time_a.timefreq.bldrdoc.gov
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <ctype.h>
long int address;		/* holds ip address */
int pserv = 37;		/* daytime port number on server */
char *cp;			/* server address in . notation */
struct sockaddr_in sin;		/* socket address structure */
int s;				/* socket number */
int length;			/* size of message */
char buf[10];			/* holds message */
unsigned long recdtime;		/* received time in local byte order */
unsigned long dorg = 2208988800ul;	/*seconds from 1900.0 -> 1970.0*/
unsigned long netcons;		/*received time in network order */
struct timeval tvv,tgg;		/* holds local time */
long int diff;			/* time difference, local - NIST */
char cc;
int stat;
/*
	internet address of server named time_a.timefreq.bldrdoc.gov
*/
	cp="132.163.135.130";
/*
	convert address to internal format
*/
	if( (address=inet_addr(cp) ) == -1)
	   {
	   fprintf(stderr,"\n Internet address error.");
	   exit(1);
	}
	bzero( (char *)&sin,sizeof(sin));
	sin.sin_addr.s_addr=address;
	sin.sin_family=AF_INET;
	sin.sin_port=htons(pserv);
/*
	create the socket and then connect to the server
	note that this is a UDP datagram socket 
*/
	if( (s=socket(AF_INET,SOCK_DGRAM,0) ) < 0)
	   {
	   fprintf(stderr,"\n Socket creation error.");
	   exit(1);
	}
	if(connect(s, (struct sockaddr *) &sin, sizeof(sin) ) < 0)
	   {
	   perror(" time server Connect failed --");
	   exit(1);
	}
/*
	send a UDP datagram to start the server 
	going.
*/
	write(s,buf,10);
	length=read(s,&netcons,4);
	gettimeofday(&tvv,0);	/*get time as soon as read completes*/
	if(length <= 0) 
	   {
	   fprintf(stderr,"\n No response from server.");
	   close(s);
	   exit(1);
	}
	recdtime=ntohl(netcons);	/*convert to local byte order */
	recdtime -= dorg;	/*convert to seconds since 1970*/
	close(s);
/*
	now compute difference between local time and
	received time.
*/
	diff=tvv.tv_sec - recdtime;
	if(tvv.tv_usec >= 500000l) diff++;	/*round microseconds */
	printf("\nLocal Clock - NIST = %ld second(s).",diff);
	if(diff == 0)
	   {
	   printf("\n No adjustment is needed.\n");
	   exit(0);
	}
	printf("\n Do you want to adjust the local clock ? [y/n] ");
	cc=getchar();
	if( (cc == 'y') || (cc == 'Y') )
	   {
	   if(diff > 2100l)
	      {
	      printf("\n Adjustment limited to -2100 s.");
	      diff= 2100l;
	   }
	   if(diff < -2100l)
	      {
	      printf("\n Adjustment limited to +2100 s.");
	     diff= -2100l;
	   }
	   tvv.tv_sec= -diff;
	   tvv.tv_usec = 0;
	   stat=adjtime(&tvv,&tgg);
	   if(stat == 0) printf("\n Adjustment was performed.\n");
	   else perror("Adjustment failed. ");
	}
}

