|
|
1.1 root 1: /*
2: * get date from wwv network clock
3: */
4: #include <stdio.h>
5: #include <time.h>
6: #include <sys/types.h>
7: #include <sys/timeb.h>
8: #include <utmp.h>
9: #include <signal.h>
10:
11: #define ARB 50
12: char buf[ARB];
13:
14: int uflag;
15: int sflag;
16: int bflag;
17: int fflag;
18: char *timezone();
19:
20: char *clocks[5] = {
21: "dk!nj/mhe/mhpbs.clock",
22: "dk!nj/astro/clock",
23: NULL
24: };
25:
26: struct utmp wtmp[2] = { {"|", "", 0}, {"{", "", 0}};
27:
28: char *ctime();
29: char *asctime();
30: struct tm *localtime();
31: struct tm *gmtime();
32: long labs();
33:
34: main(argc, argv)
35: char *argv[];
36: {
37: int rc;
38: time_t wwvtime, readnet();
39: extern char *optarg;
40:
41: rc = 0;
42: for(;;) {
43: switch(getopt(argc, argv, "usbfc:")) {
44: case 's':
45: sflag++;
46: continue;
47:
48: case 'u':
49: uflag++;
50: continue;
51:
52: case 'b':
53: bflag++;
54: continue;
55:
56: case 'f':
57: fflag++;
58: continue;
59:
60: case 'c':
61: clocks[0] = optarg;
62: clocks[1] = NULL;
63: continue;
64:
65: case '?':
66: exit(1);
67:
68: case EOF:
69: goto OK;
70: }
71: }
72: OK:
73: wwvtime = readnet();
74: if (wwvtime==0)
75: exit(1);
76: if (sflag)
77: rc = settime(wwvtime);
78: if (bflag) {
79: printf("WWV: "); prt(wwvtime);
80: printf("you: "); prt(time((time_t)0));
81: } else
82: prt(wwvtime);
83: exit(rc);
84: }
85:
86: prt(t)
87: time_t t;
88: {
89: struct timeb info;
90: char *ap, *tzn;
91:
92: if (uflag) {
93: ap = asctime(gmtime(&t));
94: tzn = "GMT";
95: } else {
96: struct tm *tp;
97: ftime(&info.time);
98: tp = localtime(&t);
99: ap = asctime(tp);
100: tzn = timezone(info.timezone, tp->tm_isdst);
101: }
102: printf("%.20s", ap);
103: if (tzn)
104: printf("%s", tzn);
105: printf("%s", ap+19);
106: }
107:
108: /*
109: * set the time
110: */
111:
112: settime(wwvtime)
113: time_t wwvtime;
114: {
115: time_t nowtime = time((time_t)0);
116: int wf;
117:
118: if (fflag == 0 && labs(nowtime-wwvtime) >= 20*60) {
119: fprintf(stderr, "wwv: >20min difference; force with wwv -sf\n");
120: bflag++;
121: return (1);
122: }
123: wtmp[0].ut_time = nowtime;
124: if(stime(&wwvtime) < 0) {
125: fprintf(stderr, "wwv: no permission\n");
126: return (1);
127: }
128: if (wwvtime >= nowtime)
129: printf("advanced %ld sec\n", wwvtime-nowtime);
130: else
131: printf("retarded %ld sec\n", nowtime-wwvtime);
132: if ((wf = open("/usr/adm/wtmp", 1)) >= 0) {
133: time(&wtmp[1].ut_time);
134: lseek(wf, 0L, 2);
135: write(wf, (char *)wtmp, sizeof(wtmp));
136: close(wf);
137: }
138: return (0);
139: }
140:
141: /*
142: * read time from the network
143: * takes only the modern version;
144: * see settod.c if the heath code is ever needed again
145: */
146:
147: time_t
148: readnet()
149: {
150: register int i;
151: int f;
152: int alcatch();
153:
154: signal(SIGALRM, alcatch);
155: alarm(30);
156: for (i=0; clocks[i]; i++) {
157: if ((f = ipcopen(ipcpath(clocks[i], "dk", ""), "light")) >= 0)
158: break;
159: }
160: if (f < 0) {
161: alarm(0);
162: fprintf(stderr, "wwv: can't open clock\n");
163: return(0);
164: }
165: do {
166: if (read(f, buf, 1) <= 0) {
167: fprintf(stderr, "wwv: read error\n");
168: alarm(0);
169: close(f);
170: return (0);
171: }
172: buf[0] &= 0177;
173: } while (buf[0]!='\r' && buf[0]!='\n');
174: for (i=0; i < sizeof(buf); i++) {
175: if (read(f, &buf[i], 1) <= 0) {
176: fprintf(stderr, "wwv: read error\n");
177: alarm(0);
178: close(f);
179: return (0);
180: }
181: buf[i] &= 0177;
182: if (buf[i] == '\n' || buf[i] == '\r') {
183: if (i)
184: break;
185: i--; /* ignore empty line */
186: }
187: }
188: alarm(0);
189: close(f);
190: if (i < 10 || i == sizeof(buf)) { /* plausibility check */
191: fprintf(stderr, "wwv: clock format error: %s\n", buf);
192: return (0);
193: }
194: buf[i] = 0; /* just to make sure */
195: return (atol(buf));
196: }
197:
198: alcatch() {}
199:
200: long
201: labs(t)
202: long t;
203: {
204: if (t < 0)
205: return(-t);
206: return(t);
207: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.