|
|
1.1 root 1: # include <sccs.h>
2:
3: SCCSID(@(#)timefix.c 7.1 2/5/81)
4:
5: /*
6: ** TIMEFIX -- patch binary program to correct for timezone changes.
7: **
8: ** Timefix is compiled with the ctime(III) variables:
9: ** daylight,
10: ** timezone,
11: ** tzname[]
12: **
13: ** Each file specified is examined to see if it contains
14: ** all of these variables. If it does then the current values
15: ** of those variables for that file are given. If the "-u" flag
16: ** is specified then the values are not overwritten.
17: **
18: ** The other flags can be used to override the values of the
19: ** variables; specifically:
20: ** -sxxx --> timezone (xxx converted from ascii to binary)
21: ** -dx --> daylight (x converted from ascii to binary)
22: ** -tXXXYYY -> tzname[0] = "XXX" and tzname[1] = "YYY"
23: */
24:
25: struct header
26: {
27: int magic;
28: int tsize;
29: int dsize;
30: int bss;
31: int ssize;
32: int start_ad;
33: int unused;
34: int reloc_flag;
35: };
36:
37: struct sym
38: {
39: char symname[8];
40: int type;
41: int value;
42: };
43:
44:
45: /* these values are defined in the unix ctime() routine */
46: extern int daylight;
47: extern int timezone;
48: extern char *tzname[];
49:
50: int Noupdate;
51:
52: main(argc, argv)
53: int argc;
54: char *argv[];
55: {
56:
57: if (argc < 2)
58: {
59: printf("usage: timefix filename ...\n");
60: exit (1);
61: }
62:
63: argc--;
64: argv++;
65:
66: if (checkflags(&argc, argv))
67: exit (1);
68:
69: pr_values("your installation", timezone, tzname[0], tzname[1], daylight);
70:
71: while (argc--)
72: newtime(*argv++);
73: }
74: /*
75: ** NEWTIME
76: */
77:
78: newtime(filename)
79: char *filename;
80: {
81: struct sym timez, name_st, name_dy, dayflag;
82: struct header head;
83: register int i, fdes;
84: int adr, secs;
85: char std[4], dyl[4];
86:
87: if ((fdes = openheader(&head, filename)) < 0)
88: return (-1);
89:
90: bmove("_timezon", timez.symname, 8);
91: bmove("_tzname\0", name_st.symname, 8);
92: bmove("_dayligh", dayflag.symname, 8);
93:
94: /* pick up addresses from symbol table */
95: i = findsymbol(&head, fdes, &timez);
96: i |= findsymbol(&head, fdes, &name_st);
97: i |= findsymbol(&head, fdes, &dayflag);
98:
99: if (i)
100: {
101: printf("File %s does not need to be corrected\n", filename);
102: close(fdes);
103: return (-2);
104: }
105:
106: /* form entries for pointer to "PST" and "PDT" */
107: i = getvalue(&head, fdes, &name_st, &adr, 2);
108: name_st.value += 2;
109: i |= getvalue(&head, fdes, &name_st, &name_dy.value, 2);
110: name_dy.type = name_st.type;
111: name_st.value = adr;
112:
113: if (i)
114: {
115: printf("can't find pointers to timezone names in %s\n", filename);
116: close(fdes);
117: return (-3);
118: }
119:
120: /* now print out current values */
121: i = getvalue(&head, fdes, &timez, &secs, 2);
122: i |= getvalue(&head, fdes, &name_st, std, 4);
123: i |= getvalue(&head, fdes, &name_dy, dyl, 4);
124: i |= getvalue(&head, fdes, &dayflag, &adr, 2);
125:
126: if (i)
127: {
128: printf("one or more symbols cannot be read from %s\n", filename);
129: close(fdes);
130: return (-4);
131: }
132:
133: pr_values(filename, secs, std, dyl, adr);
134:
135: if (!Noupdate)
136: {
137: if (putvalue(&head, fdes, &timez, &timezone, 2)
138: || putvalue(&head, fdes, &name_st, tzname[0], 4)
139: || putvalue(&head, fdes, &name_dy, tzname[1], 4)
140: || putvalue(&head, fdes, &dayflag, &daylight, 2))
141: {
142: printf("cannot update %s with new values\n", filename);
143: close(fdes);
144: return (-2);
145: }
146: else
147: printf("File %s updated.\n", filename);
148: }
149:
150:
151: close(fdes);
152:
153: return (0);
154: }
155: /*
156: ** Open the indicated file and read & verify header
157: */
158:
159: openheader(hd, filename)
160: struct header *hd;
161: char *filename;
162: {
163: register int fd, i;
164:
165: if ((fd = open(filename, 2)) < 0)
166: {
167: printf("can't open file %s\n", filename);
168: return (-1);
169: }
170:
171: if ((i = read(fd, hd, sizeof (*hd))) != sizeof (*hd))
172: {
173: printf("can't read in header\n");
174: close(fd);
175: return (-2);
176: }
177:
178: switch (hd->magic)
179: {
180:
181: case 0407:
182: case 0410:
183: case 0411:
184: if (hd->ssize)
185: break;
186: printf("File %s does not have a symbol table.\n", filename);
187: return (-4);
188:
189: default:
190: printf("%s not an object file\n", filename);
191: return (-3);
192: }
193:
194: return (fd);
195: }
196: /*
197: ** Seek to beginning of symbol table
198: */
199:
200: startsymbol(hd, fdx)
201: struct header *hd;
202: int fdx;
203: {
204: register int i, fd;
205: register struct header *h;
206: long offset;
207: long itol();
208:
209: h = hd;
210: fd = fdx;
211:
212: /* seek past header */
213: i = lseek(fd, 16L, 0);
214:
215: /* seek to start of symbol table */
216: offset = itol(h->tsize);
217: offset = offset + itol(h->dsize);
218: if (h->reloc_flag == 0)
219: offset += offset;
220:
221: i |= lseek(fd, offset, 1);
222:
223: if (i < 0)
224: {
225: printf("can't seek to symbol table\n");
226: return (-1);
227: }
228:
229: return (0);
230: }
231: /*
232: ** Locate symbol in symbol table and return sucess-failure
233: */
234:
235: findsymbol(hd, fd, s)
236: struct header *hd;
237: int fd;
238: struct sym *s;
239: {
240: register int i, j;
241: struct sym next;
242:
243: if (startsymbol(hd, fd))
244: return (-1);
245:
246: for (i = hd->ssize; i--; )
247: {
248: j = read(fd, &next, sizeof (next));
249:
250: if (j != sizeof (next))
251: {
252: if (j)
253: printf("symbol table error %d,%d,%d\n", hd->ssize, i, j);
254: return (-1);
255: }
256:
257: if (bequal(next.symname, s->symname, sizeof (next.symname)))
258: {
259: s->type = next.type;
260: s->value = next.value;
261: return (0);
262: }
263: }
264:
265: return (1);
266: }
267: /*
268: ** GETVALUE
269: */
270:
271: getvalue(hd, fd, s, cp, len)
272: struct header *hd;
273: int fd;
274: struct sym *s;
275: char *cp;
276: int len;
277: {
278: register int i;
279: long getaddr(), addr;
280:
281: addr = getaddr(hd, s);
282: if (addr == -1)
283: return (-1);
284:
285: if (lseek(fd, addr, 0) < 0)
286: return (-1);
287:
288: if ((i = read(fd, cp, len)) != len)
289: return (-1);
290:
291: return (0);
292: }
293: /*
294: ** PUTVALUE
295: */
296:
297:
298: putvalue(hd, fd, s, loc, len)
299: struct header *hd;
300: int fd;
301: struct sym *s;
302: char *loc;
303: int len;
304: {
305: long adr, getaddr();
306:
307: adr = getaddr(hd, s);
308: if (adr == -1)
309: return (-1);
310:
311: if (lseek(fd, adr, 0) < 0)
312: return (-1);
313:
314: if (write(fd, loc, len) != len)
315: return (-2);
316:
317: return (0);
318: }
319: /*
320: ** PR_VALUES
321: */
322:
323: pr_values(str, secs, std, dyl, flag)
324: char *str;
325: int secs;
326: char *std;
327: char *dyl;
328: int flag;
329: {
330: printf("\nCurrent values for %s are:\n\t# seconds past greenwich: %d\n", str, secs);
331: printf("\ttimezones: %.4s and %.4s\n\tdaylight saving flag: %d\n", std, dyl, flag);
332: }
333: /*
334: ** CHECKFLAGS
335: */
336:
337: checkflags(argc, argv)
338: int *argc;
339: char *argv[];
340: {
341: register char *cp, **nargv;
342: register int cnt;
343: int ret;
344:
345: ret = 0;
346: cnt = *argc;
347: nargv = argv;
348: while (cnt--)
349: {
350: cp = *argv++;
351: if (*cp == '-')
352: {
353: (*argc)--;
354: cp++;
355: switch (*cp++)
356: {
357:
358: case 's':
359: timezone = atoi(cp);
360: break;
361:
362: case 't':
363: bmove(cp, tzname[0], 3);
364: bmove(cp+3, tzname[1], 3);
365: break;
366:
367: case 'd':
368: daylight = atoi(cp);
369: break;
370:
371: case 'u':
372: Noupdate++;
373: break;
374:
375: default:
376: printf("bad flag %s\n", cp - 2);
377: ret = -1;
378: }
379: }
380: else
381: *nargv++ = cp;
382: }
383:
384: return (ret);
385: }
386:
387:
388: bmove(src, dst, len)
389: char *src;
390: char *dst;
391: int len;
392: {
393: register int i;
394: register char *s, *d;
395:
396: s = src;
397: d = dst;
398: i = len;
399:
400: while (i--)
401: *d++ = *s++;
402: }
403:
404:
405: bequal(s1, s2, len)
406: char *s1;
407: char *s2;
408: int len;
409: {
410: register int i;
411: register char *s, *d;
412:
413: s = s1;
414: d = s2;
415: i = len;
416:
417: while (i--)
418: if (*s++ != *d++)
419: return (0);
420:
421: return (1);
422: }
423: /*
424: ** GETADDR
425: */
426:
427: long
428: getaddr(hd, s)
429: struct header *hd;
430: struct sym *s;
431: {
432: long addr;
433: int i;
434: long l;
435: long itol();
436:
437: addr = s->value + 16; /* offset past header */
438:
439: switch (s->type)
440: {
441:
442: /* extern text segment */
443: case 042:
444: return (addr);
445:
446: /* data segment extern */
447: case 043:
448: switch (hd->magic)
449: {
450:
451: case 0407:
452: return (addr);
453:
454: case 0410:
455: /* subtract space between text and data */
456: l = itol(hd->tsize) + 017777;
457: l &= ~017777;
458:
459: return (addr - (l - itol(hd->tsize)));
460:
461: case 0411:
462: return (addr + itol(hd->tsize));
463:
464: }
465: default:
466: printf("Invalid symbol type %o\n", s->type);
467: return (-1);
468: }
469: }
470:
471:
472: long itol(value)
473: int value;
474: {
475: long ret;
476: int *ip;
477:
478: ret = value;
479: ip = &ret;
480: *ip = 0;
481:
482: return (ret);
483: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.