|
|
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.