V10/cmd/wwv.c

Compare this file to the similar file:
Show the results in this format:

/*
 * get date from wwv network clock
 */
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <utmp.h>
#include <signal.h>

#define	ARB	50
char buf[ARB];

int	uflag;
int	sflag;
int	bflag;
int	fflag;
char	*timezone();

char	*clocks[5] = {
	"dk!nj/mhe/mhpbs.clock",
	"dk!nj/astro/clock",
	NULL
};

struct utmp wtmp[2] = { {"|", "", 0}, {"{", "", 0}};

char	*ctime();
char	*asctime();
struct	tm *localtime();
struct	tm *gmtime();
long	labs();

main(argc, argv)
char *argv[];
{
	int rc;
	time_t wwvtime, readnet();
	extern char *optarg;

	rc = 0;
	for(;;) {
		switch(getopt(argc, argv, "usbfc:")) {
		case 's':
			sflag++;
			continue;

		case 'u':
			uflag++;
			continue;

		case 'b':
			bflag++;
			continue;

		case 'f':
			fflag++;
			continue;

		case 'c':
			clocks[0] = optarg;
			clocks[1] = NULL;
			continue;

		case '?':
			exit(1);

		case EOF:
			goto OK;
		}
	}
OK:
	wwvtime = readnet();
	if (wwvtime==0)
		exit(1);
	if (sflag)
		rc = settime(wwvtime);
	if (bflag) {
		printf("WWV: "); prt(wwvtime);
		printf("you: "); prt(time((time_t)0));
	} else
		prt(wwvtime);
	exit(rc);
}

prt(t)
time_t t;
{
	struct timeb info;
	char *ap, *tzn;

	if (uflag) {
		ap = asctime(gmtime(&t));
		tzn = "GMT";
	} else {
		struct tm *tp;
		ftime(&info.time);
		tp = localtime(&t);
		ap = asctime(tp);
		tzn = timezone(info.timezone, tp->tm_isdst);
	}
	printf("%.20s", ap);
	if (tzn)
		printf("%s", tzn);
	printf("%s", ap+19);
}

/*
 * set the time
 */

settime(wwvtime)
time_t wwvtime;
{
	time_t nowtime = time((time_t)0);
	int wf;

	if (fflag == 0 && labs(nowtime-wwvtime) >= 20*60) {
		fprintf(stderr, "wwv: >20min difference; force with  wwv -sf\n");
		bflag++;
		return (1);
	}
	wtmp[0].ut_time = nowtime;
	if(stime(&wwvtime) < 0) {
		fprintf(stderr, "wwv: no permission\n");
		return (1);
	}
	if (wwvtime >= nowtime)
		printf("advanced %ld sec\n", wwvtime-nowtime);
	else
		printf("retarded %ld sec\n", nowtime-wwvtime);
	if ((wf = open("/usr/adm/wtmp", 1)) >= 0) {
		time(&wtmp[1].ut_time);
		lseek(wf, 0L, 2);
		write(wf, (char *)wtmp, sizeof(wtmp));
		close(wf);
	}
	return (0);
}

/*
 * read time from the network
 * takes only the modern version;
 * see settod.c if the heath code is ever needed again
 */

time_t
readnet()
{
	register int i;
	int f;
	int alcatch();

	signal(SIGALRM, alcatch);
	alarm(30);
	for (i=0; clocks[i]; i++) {
		if ((f = ipcopen(ipcpath(clocks[i], "dk", ""), "light")) >= 0)
			break;
	}
	if (f < 0) {
		alarm(0);
		fprintf(stderr, "wwv: can't open clock\n");
		return(0);
	}
	do {
		if (read(f, buf, 1) <= 0) {
			fprintf(stderr, "wwv: read error\n");
			alarm(0);
			close(f);
			return (0);
		}
		buf[0] &= 0177;
	} while (buf[0]!='\r' && buf[0]!='\n');
	for (i=0; i < sizeof(buf); i++) {
		if (read(f, &buf[i], 1) <= 0) {
			fprintf(stderr, "wwv: read error\n");
			alarm(0);
			close(f);
			return (0);
		}
		buf[i] &= 0177;
		if (buf[i] == '\n' || buf[i] == '\r') {
			if (i)
				break;
			i--;		/* ignore empty line */
		}
	}
	alarm(0);
	close(f);
	if (i < 10 || i == sizeof(buf)) {	/* plausibility check */
		fprintf(stderr, "wwv: clock format error: %s\n", buf);
		return (0);
	}
	buf[i] = 0;		/* just to make sure */
	return (atol(buf));
}

alcatch() {}

long
labs(t)
long t;
{
	if (t < 0)
		return(-t);
	return(t);
}