home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / nisttime / part01 < prev    next >
Encoding:
Text File  |  1992-12-26  |  17.5 KB  |  534 lines

  1. Newsgroups: comp.sources.unix
  2. From: rushpc!jjr@csn.org (John Rushford)
  3. Subject: v26i081: nisttime - Set the system clock to the NIST master clock, Part01/01
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: rushpc!jjr@csn.org (John Rushford)
  8. Posting-Number: Volume 26, Issue 81
  9. Archive-Name: nisttime/part01
  10.  
  11. Saw settime.c from John Walker in comp.unix.sources for a SPARC II.
  12. Attached is a program similar to settime.c however, it is written
  13. for System V Release 3.  This shell archive includes a manual page
  14. and a Makefile.  Just unbundle this archive using "sh".  You must
  15. be logged in as root to 'make install' this program.
  16.  
  17. John Rushford
  18. rushpc!jjr@csn.org
  19.  
  20. [ moderator's extract of the included man page...
  21.  
  22. NAME
  23.      nisttime - Set the system clock to the NIST master clock
  24.      usnotime - Set the system clock to the USNO master clock
  25.  
  26. SYNOPSIS
  27.      nisttime [ -sv ]
  28.      usnotime [ -sv ]
  29.  
  30. DESCRIPTION
  31.      This program calls a master clock reference and compares the
  32.      system clock with the reference. nisttime calls the National
  33.      Institute of Standards and Technology's master clock in
  34.      Boulder Colorado, (303) 494-4774 @ 1200 baud.  usnotime
  35.      calls the U.S. Naval Observatory master clock in Washington
  36.      DC, (202) 653-0351 @ 1200 baud.
  37.  
  38.   --vix ]
  39.  
  40. #! /bin/sh
  41. # This is a shell archive.  Remove anything before this line, then unpack
  42. # it by saving it into a file and typing "sh file".  To overwrite existing
  43. # files, type "sh file -c".  You can also feed this as standard input via
  44. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  45. # will see the following message at the end:
  46. #        "End of archive 1 (of 1)."
  47. # Contents:  MANIFEST Makefile README nisttime.1 nisttime.c
  48. # Wrapped by vixie@cognition.pa.dec.com on Sun Dec 27 15:21:47 1992
  49. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  50. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  51.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  52. else
  53. echo shar: Extracting \"'MANIFEST'\" \(269 characters\)
  54. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  55. X   File Name        Archive #    Description
  56. X-----------------------------------------------------------
  57. X MANIFEST                   1    This shipping list
  58. X Makefile                   1    
  59. X README                     1    
  60. X nisttime.1                 1    
  61. X nisttime.c                 1    
  62. END_OF_FILE
  63. if test 269 -ne `wc -c <'MANIFEST'`; then
  64.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  65. fi
  66. # end of 'MANIFEST'
  67. fi
  68. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  69.   echo shar: Will not clobber existing file \"'Makefile'\"
  70. else
  71. echo shar: Extracting \"'Makefile'\" \(603 characters\)
  72. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  73. X# Makefile for 'nisttime' and 'usnotime'
  74. X#
  75. X# Log in as 'root' and type 'make install'
  76. X#
  77. X
  78. DESTROOT = 
  79. DESTPATH = $(DESTROOT)/usr/local
  80. DESTBIN = $(DESTPATH)/bin
  81. DESTMAN = $(DESTPATH)/man
  82. X
  83. CFLAGS= -O
  84. LDFLAGS= -s
  85. X
  86. all: nisttime
  87. X
  88. install: nisttime
  89. X    cp nisttime $(DESTBIN)/nisttime
  90. X    chown uucp $(DESTBIN)/nisttime
  91. X    chgrp uucp $(DESTBIN)/nisttime
  92. X    chmod 4111 $(DESTBIN)/nisttime
  93. X    ln $(DESTBIN)/nisttime $(DESTBIN)/usnotime
  94. X
  95. install.man: nisttime.1
  96. X    cp nisttime.1 $(DESTMAN)/man1/nisttime.1
  97. X    echo .so $(DESTMAN)/man1/nisttime.1 >$(DESTMAN)/man1/usnotime.1
  98. X
  99. clean:; rm -f *.o *.CKP *.BAK *~ a.out core nisttime
  100. END_OF_FILE
  101. if test 603 -ne `wc -c <'Makefile'`; then
  102.     echo shar: \"'Makefile'\" unpacked with wrong size!
  103. fi
  104. # end of 'Makefile'
  105. fi
  106. if test -f 'README' -a "${1}" != "-c" ; then 
  107.   echo shar: Will not clobber existing file \"'README'\"
  108. else
  109. echo shar: Extracting \"'README'\" \(969 characters\)
  110. sed "s/^X//" >'README' <<'END_OF_FILE'
  111. Saw settime.c from John Walker in comp.unix.sources for a SPARC II.
  112. Attached is a program similar to settime.c however, it is written
  113. for System V Release 3.  This shell archive includes a manual page
  114. and a Makefile.  Just unbundle this archive using "sh".  You must
  115. be logged in as root to 'make install' this program.
  116. X
  117. John Rushford
  118. rushpc!jjr@csn.org
  119. X
  120. X[ moderator's extract of the included man page...
  121. X
  122. NAME
  123. X     nisttime - Set the system clock to the NIST master clock
  124. X     usnotime - Set the system clock to the USNO master clock
  125. X
  126. SYNOPSIS
  127. X     nisttime [ -sv ]
  128. X     usnotime [ -sv ]
  129. X
  130. DESCRIPTION
  131. X     This program calls a master clock reference and compares the
  132. X     system clock with the reference. nisttime calls the National
  133. X     Institute of Standards and Technology's master clock in
  134. X     Boulder Colorado, (303) 494-4774 @ 1200 baud.  usnotime
  135. X     calls the U.S. Naval Observatory master clock in Washington
  136. X     DC, (202) 653-0351 @ 1200 baud.
  137. X
  138. X  --vix ]
  139. END_OF_FILE
  140. if test 969 -ne `wc -c <'README'`; then
  141.     echo shar: \"'README'\" unpacked with wrong size!
  142. fi
  143. # end of 'README'
  144. fi
  145. if test -f 'nisttime.1' -a "${1}" != "-c" ; then 
  146.   echo shar: Will not clobber existing file \"'nisttime.1'\"
  147. else
  148. echo shar: Extracting \"'nisttime.1'\" \(1324 characters\)
  149. sed "s/^X//" >'nisttime.1' <<'END_OF_FILE'
  150. X.TH NISTTIME 1 
  151. X.UC 4
  152. X.SH NAME
  153. nisttime \- Set the system clock to the NIST master clock
  154. usnotime \- Set the system clock to the USNO master clock
  155. X.SH SYNOPSIS
  156. X.B nisttime 
  157. X[
  158. X.B \-sv
  159. X]
  160. X.br
  161. X.B usnotime 
  162. X[
  163. X.B \-sv
  164. X] 
  165. X.SH DESCRIPTION
  166. This program calls a master clock reference and compares the
  167. system clock with the reference.  
  168. X.B
  169. nisttime 
  170. calls the National Institute of Standards and Technology's 
  171. master clock in Boulder Colorado, (303) 494-4774 @ 1200 baud.
  172. X.B
  173. usnotime 
  174. calls the U.S. Naval Observatory master clock in Washington DC,
  175. X(202) 653-0351 @ 1200 baud.
  176. X.SH OPTIONS
  177. X.TP 10
  178. X.B \-s
  179. The system clock will be reset to the time of the called master clock.
  180. Only root may use this option.
  181. X.TP 10
  182. X.B \-v 
  183. The program will print to stdout all data received from the master
  184. clock time service.
  185. X.SH NOTE
  186. UNIX System V. Release 3 using BNU UUCP.  Requires entries in the
  187. UUCP Systems file for 
  188. X.B nisttime
  189. and
  190. X.B usnotime:
  191. X.PP
  192. nisttime Never ACU 1200 13034944774
  193. X.br
  194. usnotime Never ACU 1200 12026530351
  195. X.PP
  196. This program should be owned by 'uucp' and set to mode O'4111.
  197. X.B nisttime
  198. and
  199. X.B usnotime
  200. should be linked.
  201. X.SH FILES
  202. X/usr/lib/uucp/Devices
  203. X.br
  204. X/usr/lib/uucp/Dialcodes
  205. X.br
  206. X/usr/lib/uucp/Dialers
  207. X.br
  208. X/usr/lib/uucp/Systems
  209. X.SH AUTHOR
  210. X   John J. Rushford
  211. X.br
  212. X   Phone:  (303) 465-4070
  213. X.br
  214. X   Usenet: rushpc!jjr@csn.org
  215. END_OF_FILE
  216. if test 1324 -ne `wc -c <'nisttime.1'`; then
  217.     echo shar: \"'nisttime.1'\" unpacked with wrong size!
  218. fi
  219. # end of 'nisttime.1'
  220. fi
  221. if test -f 'nisttime.c' -a "${1}" != "-c" ; then 
  222.   echo shar: Will not clobber existing file \"'nisttime.c'\"
  223. else
  224. echo shar: Extracting \"'nisttime.c'\" \(10373 characters\)
  225. sed "s/^X//" >'nisttime.c' <<'END_OF_FILE'
  226. X/*
  227. X**    NAME
  228. X**        nisttime - set the system clock to the NIST master clock.
  229. X**        usnotime - set the system clock to the USNO master clock.
  230. X**
  231. X**    SYNOPSIS
  232. X**        nisttime [-sv]
  233. X**        usnotime [-sv]
  234. X**
  235. X**    DESCRIPTION
  236. X**        This  program calls a master  clock reference  and compares the
  237. X**        system clock  with the reference.  nisttime calls  the National
  238. X**        Institute of Standards and Technology's master clock in Boulder
  239. X**        Colorado, (303) 494-4774 @ 1200  baud.  usnotime calls the U.S.
  240. X**        Naval Observatory master clock in Washington DC, (202) 653-0351
  241. X**        @ 1200 baud.
  242. X**
  243. X**        If the -s option is used, the system clock is reset to the time 
  244. X**        of the called master clock.   Only root may use the  -s option. 
  245. X**        If the -v  option is used,  the program will  print to 'stdout' 
  246. X**        all data received from the master clock time service.
  247. X**
  248. X**    NOTE
  249. X**        UNIX System  V. Release 3 using BNU UUCP.  Requires  entries in
  250. X**        the UUCP Systems file for 'nisttime' and 'usnotime':
  251. X**
  252. X**             nisttime Never ACU 1200 13034944774
  253. X**             usnotime Never ACU 1200 12026530351
  254. X**
  255. X**        This program should be owned by 'uucp'  and set to mode O'4111.
  256. X**        nisttime and usnotime should be linked.
  257. X**
  258. X**    FILES
  259. X**        /usr/lib/uucp/Devices
  260. X**        /usr/lib/uucp/Dialcodes
  261. X**        /usr/lib/uucp/Dialers
  262. X**        /usr/lib/uucp/Systems
  263. X**
  264. X**    COMPILE AND INSTALLATION
  265. X**        cc -s -O nisttime.c -o /usr/bin/nisttime
  266. X**        chown uucp /usr/bin/nisttime
  267. X**        chgrp uucp /usr/bin/nisttime
  268. X**        ln /usr/bin/nisttime /usr/bin/usnotime
  269. X**        chmod 4111 /usr/bin/nisttime
  270. X**
  271. X**    PROGRAMMER
  272. X**        John J. Rushford
  273. X**        (303) 465-4070
  274. X**        rushpc!jjr@csn.org
  275. X*/
  276. X
  277. static char Sccsid[] = "@(#)rushpc!jjr@csn.org:nisttime.c 2.7, 11 Mar 1992";
  278. X
  279. X#include <dial.h>
  280. X#include <errno.h>
  281. X#include <stdio.h>
  282. X#include <string.h>
  283. X#include <sys/types.h>
  284. X#include <time.h>
  285. X
  286. X#define BAUD          1200         /* modem speed */
  287. X#define EPOCH         40587        /* MJD for Jan 1, 1970 00:00:00 GMT */
  288. X#define HOUR          (60 * 60)    /* seconds in an hour */
  289. X#define LINE          80           /* input line buffer size */
  290. X#define NIST_SYSNAME  "nisttime"   /* system name for NIST */
  291. X#define OTMA          '*'          /* nominal on-time mark for USNO & NIST */
  292. X#define OTMB          '#'          /* on-time mark after delay compensation */
  293. X#define ONEDAY        (HOUR * 24)  /* seconds in a day */
  294. X#define USNO_SYSNAME  "usnotime"   /* system name for Naval Observatory */
  295. X
  296. X/* scanf(3S) format strings: */
  297. X#define NISTFMT "%d%*s%2d%*[:]%2d%*[:]%2d"  /* for nisttime */
  298. X#define USNOFMT "%d%*d%2d%2d%2d"            /* for usnotime */
  299. X
  300. X/* output message macros: */
  301. X#define CLKERR(a)     (void)fprintf(stderr, \
  302. X                     "%s: cannot set the clock, difference > one day.\n", a)
  303. X#define CLKSET(a)     (void)fprintf(stdout,"%s: reset the system clock.\n", a)
  304. X#define DATAERR(a)    (void)fprintf(stderr,"%s: received invalid data.\n", a)
  305. X#define DELTA(a,b,c)  (void)fprintf(stdout, \
  306. X                     "%s: the system clock is %ld second(s) %s.\n", a, b, c)
  307. X#define DIALERR(a,b)  (void)fprintf(stderr, "%s: %s.\n", a, b)
  308. X#define ONTIME(a)     (void)fprintf(stdout, \
  309. X                     "%s: the system clock is on time.\n", a)
  310. X#define SETERR(a)     (void)fprintf(stderr, \
  311. X                     "%s: only root may set the system clock.\n", a)
  312. X#define USAGE(a)      (void)fprintf(stderr, "Usage: %s [-sv]\n", a)
  313. X
  314. X#ifndef __STDC__    
  315. X   typedef enum    boolean { B_FALSE, B_TRUE } boolean_t;
  316. X#endif    /* __STDC__ */
  317. X
  318. X/* dial(3C) error messages indexed by translated error return code: */
  319. static char *error_msg[13] = {
  320. X   "interrupt occured",
  321. X   "dialer hung, no return from write",
  322. X   "no answer, caller script failed",
  323. X   "illegal baud-rate",
  324. X   "acu problem, open() failure",
  325. X   "line problem, open() failure",
  326. X   "can't open Devices file",
  327. X   "requested device not available",
  328. X   "requested device not known",
  329. X   "no device available at requested baud rate",
  330. X   "no device known at requested baud rate",
  331. X   "requested speed does not match",
  332. X   "system not known and/or can't read Systems file"
  333. X};
  334. X
  335. X/* returns a pointer to the base name component of the path name: */
  336. static char *
  337. X#ifndef __STDC__
  338. basename(pathname)
  339. char *pathname;
  340. X#else
  341. basename(char *pathname)
  342. X#endif
  343. X{
  344. X   char *Basename;    /* pointer to resulting basename */
  345. X
  346. X   if ((Basename = strrchr(pathname, '/')) == NULL)
  347. X    Basename = pathname;    /* not a path name*/
  348. X   else Basename++;    /* move past last slash in the path name */
  349. X
  350. X   return Basename;
  351. X}
  352. X
  353. X/* returns the number of seconds since 00:00:00 GMT on January 1, 1970 */
  354. static time_t 
  355. X#ifndef __STDC__
  356. Since1970(Julian, Hour, Min, Sec)
  357. int Julian, Hour, Min, Sec;
  358. X#else
  359. Since1970(int Julian, int Hour, int Min, int Sec)
  360. X#endif
  361. X{
  362. X   int no_days = 0;    /* days since January 1, 1970 */
  363. X
  364. X   no_days = Julian - EPOCH;
  365. X   return ((no_days * ONEDAY) + (Hour * HOUR) + (Min * 60) + Sec);
  366. X}
  367. X
  368. X#ifndef __STDC__
  369. main(argc, argv)
  370. int argc;
  371. char **argv;
  372. X#else
  373. main(int argc, char **argv)
  374. X#endif
  375. X{
  376. X   boolean_t      clkset   = B_FALSE,  /* clock was reset flag */
  377. X           complete = B_FALSE,  /* call complete flag */
  378. X           errflag  = B_FALSE,  /* invalid option flag */
  379. X           no_data  = B_FALSE,  /* invalid time data flag */
  380. X           sflag    = B_FALSE,  /* reset the system clock flag */
  381. X           usnoflag = B_FALSE,  /* U.S Naval Observatory flag */
  382. X           vflag    = B_FALSE;  /* verbose output flag */
  383. X   CALL           call;                /* dial structure */
  384. X   char           line[LINE],          /* input line storage buffer */
  385. X           *prog;               /* base name of this program */
  386. X   FILE           *modem_rfp;          /* stream pointer to modem */
  387. X   int            c,                   /* option character */
  388. X           Hour     = 0,        /* hours (00 - 23) */
  389. X           lineno   = 0,        /* number of received input lines */
  390. X           Min      = 0,        /* minutes (00 - 59) */
  391. X           Mjd      = 0,        /* modified julian Date */
  392. X           modem_fd,            /* dial(3C) file descriptor */
  393. X           Sample   = 0,        /* number of USNO Samples */
  394. X           Sec      = 0,        /* seconds (00 - 60) */
  395. X           getopt(),            /* getopt(3C) */
  396. X           stime();             /* stime(2) */
  397. X   extern int     optind;              /* index of next argument */
  398. X   struct termio  la;                  /* termio table */
  399. X   time_t         delta    = 0,        /* diff. between sysclk & timbuf */
  400. X           sysclk,              /* seconds since the epoch */
  401. X           timbuf;              /* seconds since the epoch */
  402. X   unsigned short getuid();            /* getuid(2) */
  403. X   void           exit();              /* exit(2) */
  404. X
  405. X   /* initialize the termio structure */
  406. X   la.c_iflag = (0 | IGNBRK | IGNPAR | IXON | IXOFF);
  407. X   la.c_oflag = 0;
  408. X   la.c_cflag = (0 | B1200 | CS8 | CREAD | HUPCL);
  409. X   la.c_lflag = (0 | ICANON | ECHO | ECHONL);
  410. X
  411. X   /* initialize the call structure */
  412. X   call.attr  = &la;
  413. X   call.baud  = -1;
  414. X   call.speed = BAUD;
  415. X   call.telno = NIST_SYSNAME;    /* call the NIST, default */
  416. X
  417. X   /* get the program base name: */
  418. X   prog = basename(argv[0]);
  419. X
  420. X   /* process command-line arguments: */
  421. X   while ((c = getopt(argc, argv, "sv")) != EOF) {
  422. X    switch(c) {
  423. X        case 's': /* request to set the system clock */
  424. X              if (getuid() == 0) sflag = B_TRUE;
  425. X              else {
  426. X              SETERR(prog);
  427. X              errflag = B_TRUE;
  428. X                     }
  429. X                     break;
  430. X           case 'v': /* request for verbose output */
  431. X              vflag = B_TRUE;
  432. X              break;
  433. X           case '?': /* unknown request */
  434. X              errflag = B_TRUE;
  435. X              break;
  436. X       }  /* end of switch statement */
  437. X   }  /* end of while loop */
  438. X   
  439. X   /* exit on command line errors: */
  440. X   if (argc > optind || errflag) {
  441. X    USAGE(prog);
  442. X    exit(1);
  443. X   }
  444. X   /* check to see if this is a call to the U.S. Naval Observatory: */
  445. X   if (strcmp(prog, USNO_SYSNAME) == 0) {
  446. X    usnoflag = B_TRUE;
  447. X    call.telno = USNO_SYSNAME;  /* reset the call structure */
  448. X   }
  449. X   /* connect to the remote system: */
  450. X   if ((modem_fd = dial(call)) < 0) {
  451. X    DIALERR(prog, error_msg[((modem_fd * -1) - 1)]);
  452. X    exit(2);
  453. X   }
  454. X   if ((modem_rfp = fdopen(modem_fd, "r")) == NULL) {
  455. X    perror(prog);
  456. X    exit(3);
  457. X   }
  458. X   /* read and process input from the remote system: */
  459. X   while (!complete && fgets(line, LINE, modem_rfp) != NULL) {
  460. X    if (usnoflag) {  /* process Naval Observatory data */
  461. X        if (line[0] == OTMA) ++Sample;   /* saw an on-time mark */
  462. X           if (Sample == 5) complete = B_TRUE;  /* 5 samples is good enough */
  463. X        else  /* process input data: */
  464. X        (void)sscanf(line, USNOFMT, &Mjd, &Hour, &Min, &Sec);
  465. X       }  
  466. X    else {  /* else process NIST data */
  467. X             (void)sscanf(line, NISTFMT, &Mjd, &Hour, &Min, &Sec);
  468. X         /* check for on-time mark, prefer an OTMB mark */
  469. X         if(line[49] == OTMB || (lineno > 20 && line[49] == OTMA)) 
  470. X                 complete = B_TRUE;  
  471. X       }  
  472. X    if (complete) {           /* done sampling the remote system so */
  473. X        (void)time(&sysclk);  /* get the local system clocks time */
  474. X        /* compute the current time according to the remote system: */
  475. X           timbuf = Since1970(Mjd, Hour, Min, Sec); 
  476. X        /* calculate the difference: */
  477. X        if (timbuf > sysclk) delta = timbuf - sysclk;
  478. X        else delta = sysclk - timbuf;
  479. X        /* check to see if the difference is out of bounds: */
  480. X        if (delta > ONEDAY || delta == 0) sflag = B_FALSE;
  481. X           /* if everything is ok, reset the system clock: */
  482. X        if (sflag && stime(&timbuf) == 0) clkset = B_TRUE;
  483. X       }
  484. X    if (vflag) {  /* if verbose output was requested then print it: */
  485. X        (void)fflush(modem_rfp); 
  486. X        (void)fprintf(stdout, "%s", line);
  487. X       }
  488. X    /* if all we've got is bum data, give up: */
  489. X       if (++lineno > 30 && !complete) complete = no_data = B_TRUE;
  490. X   }  /* end of while loop */
  491. X   
  492. X   /* terminate the call and close the modem stream: */
  493. X   undial(modem_fd);  
  494. X   (void)fclose(modem_rfp);
  495. X   
  496. X   /* if there were no good samples, report and exit: */
  497. X   if (no_data) {
  498. X    DATAERR(prog);
  499. X    exit(4);
  500. X   }
  501. X   /* call succeeded so report the results: */
  502. X   if (timbuf > sysclk) DELTA(prog, delta, "slow");
  503. X   if (sysclk > timbuf) DELTA(prog, delta, "fast");
  504. X   if (sysclk == timbuf) ONTIME(prog);
  505. X   if (delta > ONEDAY) CLKERR(prog);
  506. X   if (clkset) CLKSET(prog);
  507. X
  508. X   return 0;
  509. X}
  510. X
  511. END_OF_FILE
  512. if test 10373 -ne `wc -c <'nisttime.c'`; then
  513.     echo shar: \"'nisttime.c'\" unpacked with wrong size!
  514. fi
  515. # end of 'nisttime.c'
  516. fi
  517. echo shar: End of archive 1 \(of 1\).
  518. cp /dev/null ark1isdone
  519. MISSING=""
  520. for I in 1 ; do
  521.     if test ! -f ark${I}isdone ; then
  522.     MISSING="${MISSING} ${I}"
  523.     fi
  524. done
  525. if test "${MISSING}" = "" ; then
  526.     echo You have the archive.
  527.     rm -f ark[1-9]isdone
  528. else
  529.     echo You still need to unpack the following archives:
  530.     echo "        " ${MISSING}
  531. fi
  532. ##  End of shell archive.
  533. exit 0
  534.