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