|
|
researchv8 Dan Cross
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/clock.h>
#include <utmp.h>
#include <signal.h>
#define CLOCK "mh/astro/clock"
/* buffer to read time into and print it from */
char buf[24]; /* HH:MM:SS.S DD/MM/YY */
typedef unsigned long tod_t;
tod_t settod(), readnet();
long labs();
int sflag, vflag;
static char dmsize[12] =
{
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
main (argc, argv)
int argc;
char **argv;
{
tod_t ourtime, wwvtime;
long delta;
int c;
while ((c = getopt (argc, argv, "vs")) != EOF) {
switch (c) {
case 's':
sflag++;
break;
case 'v':
vflag++;
break;
case '?':
return 1;
}
}
if (!sflag)
vflag++;
wwvtime = readnet();
if (wwvtime) {
ourtime = settod(0L);
delta = wwvtime - ourtime;
if (sflag) {
if (settod (wwvtime) == -1)
printf ("not super-user, hence not set\n");
}
if (vflag) {
printf("%.23s ", buf);
if (delta == 0)
printf ("exact\n");
else
printf ("%s %ld.%.2ld\n",
delta < 0? "retard": "advance",
labs (delta) / 100, labs (delta) % 100);
}
}
return 0;
}
tod_t
readnet()
{
int i, j, year, mon;
int day, hour, mins, secs, tenth;
int f;
int alcatch();
tod_t timbuf;
extern errno, sys_nerr;
extern char *sys_errlist[];
extern dkp_ld;
int retry = 30; /* max number of retries */
do {
int err;
signal(SIGALRM, alcatch);
alarm(15);
f = tdkdial(CLOCK, 2);
if (f < 0) {
alarm(0);
printf("settod: can't open clock\n");
return(0);
}
if (dkproto(f, dkp_ld) < 0) {
alarm(0);
printf("settod: can't turn on DK proto\n");
return(0);
}
do {
if ((j = read(f, buf, 1)) <= 0)
goto readerr;
} while ((buf[0]&0177) != '\r');
for (i=0; i<24; i += j) {
if ((j = read(f, buf+i, 24-i)) <= 0)
goto readerr;
}
alarm(0);
for (i=0; i<24; i++)
buf[i] &= 0177;
/* accept '?' for tenths */
if (buf[9]=='?')
buf[9] = '0';
if (sscanf(buf, "%d:%d:%d.%d %d/%d/%d\r", &hour, &mins, &secs,
&tenth, &mon, &day, &year) != 7)
goto formerr;
if( mon<1 || mon>12 ||
day<0 || day>31 || /* June 30, 1984 == July 0, 1984 !!?? */
mins<0 || mins>59 ||
secs<0 || secs>59 ||
tenth<0 || tenth>9 ||
hour<0 || hour>23)
goto formerr;
/* leap year */
timbuf = 0;
if (year % 4 == 0 && mon >= 3)
timbuf++;
while(--mon)
timbuf += dmsize[mon-1];
timbuf += day-1;
timbuf = 24*timbuf + hour;
timbuf = 60*timbuf + mins;
timbuf = 60*timbuf + secs;
timbuf = 10*timbuf + tenth;
timbuf = timbuf * 10 + TODRZERO;
return timbuf;
formerr:
printf("settod: clock format error: %.24s\n", buf);
return(0);
readerr:
err = errno;
close(f);
alarm(0);
if (j < 0) {
printf("settod: clock read ");
if (err == EINTR) {
printf ("timeout\n");
return 0;
} else if (err < sys_nerr)
printf("error: %s\n", sys_errlist[err]);
else
printf("error: %d\n", err);
}
sleep (1 + (int)((getpid() + time ((time_t) 0)) % 7));
} while (--retry >= 0);
return 0;
}
alcatch() {}
long
labs (n)
long n;
{
if (n >= 0)
return n;
return -n;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.