[comp.sources.misc] v03i079: N.B.S. Time Service program

mike@whutt.UUCP (BALDWIN) (07/12/88)

Posting-number: Volume 3, Issue 79
Submitted-by: "BALDWIN" <mike@whutt.UUCP>
Archive-name: utc

I've been running such a program, which I wrote, at home for over six
months now.  It's written in C, and runs under System V (or any UNIX
system with an stime(2) system call).  It consists of a single program
called "utc" (universal time coordinated).  When invoked with options,
it reads the Naval clock and does one or both of these things:

	-s	sets the time via stime(2)
	-p	prints the time via ctime(3C)

If it can't read the time from the standard input, it exits non-zero.
When invoked without options, it prints the time in Naval clock format
for about a minute.  Thus, it can be installed as a login shell to provide
time service for your other systems without having them all call DC.
As a test, "utc | utc -p" should print the current time.  You can pipe
cu right into it, so set up a crontab entry to execute

	cu 1-201-653-0351 | utc -s

You may have to fix your cu to die properly when it receives a SIGPIPE.
I have my crontab entry run once a day, but it only calls DC if the
time hasn't been set in over a week.  A simple shell file accomplishes
this:

	LAST=/etc/.lastutc
	[ -z "`find $LAST -mtime -7 -print`" ] &&
	cu 1-202-653-0351 | utc -s && >$LAST

---8<--------8<---------- cut here for utc.c ------------8<--------------8<---
echo x - utc.c
sed 's/^X//' << \EOF > utc.c
X/*
X * The Naval Observatory clock (+1 202 653 0351) prints this every second:
X *
X *	*
X *	jjjjj ddd hhmmss UTC
X *
X * jjjjj	Julian date modulo 2400000
X * ddd		days since beginning of year
X * hhmmss	time of day in Universal Time Coordinated
X */
X
X#include <stdio.h>
X#include <time.h>
X#include <sys/types.h>
X
X#define	EPOCH		40587			/* UNIX starts JD 2440587, */
X#define	leap(y, m)	((y+m-1 - 70%m) / m)	/* also known as 1/1/70 */
X#define	TONE		'*'
X#define	TIME		"\n%05ld %03d %02d%02d%02d UTC"
X
Xmain(argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X	int	setflg = 0, prtflg = 0;
X	int	y, d, h, m, s;
X	long	j;
X	time_t	now;
X	int	c;
X
X	while ((c = getopt(argc, argv, "sp")) != EOF)
X		switch (c) {
X		case 's': setflg++; break;
X		case 'p': prtflg++; break;
X		default:
X			fprintf(stderr, "usage: %s [-s] [-p]\n", argv[0]);
X			return 1;
X		}
X	if (setflg || prtflg) {
X		while ((c = getchar()) != TONE)
X			if (c == EOF)
X				return 1;
X		if (scanf(TIME, &j, &d, &h, &m, &s) != 5)
X			return 1;
X		now = (((j - EPOCH) * 24 + h) * 60 + m) * 60 + s;
X		if (setflg && stime(&now) == -1)
X			perror(argv[0]);
X		if (prtflg)
X			fputs(ctime(&now), stdout);
X	} else {
X		for (c = 0; c < 60; c++) {
X			time(&now);
X			s = (now % 60);
X			m = (now /= 60) % 60;
X			h = (now /= 60) % 24;
X			d = (now /= 24) % 365;
X			j = now + EPOCH;
X			y = (now /= 365);
X			d += 1 - leap(y, 4) + leap(y, 100) - leap(y, 400);
X			putchar(TONE);
X			printf(TIME, j, d, h, m, s);
X			putchar('\n');
X			fflush(stdout);
X			sleep(1);
X		}
X	}
X	return 0;
X}
EOF
exit 0
-- 
Michael Scott Baldwin		research!mike	attmail!mike	mike@att.arpa
AT&T Bell Laboratories		+1 201 386 3052