|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: char copyright[] = ! 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)ranlib.c 5.3 (Berkeley) 1/22/86"; ! 15: #endif not lint ! 16: ! 17: /* ! 18: * ranlib - create table of contents for archive; string table version ! 19: */ ! 20: #include <sys/types.h> ! 21: #include <ar.h> ! 22: #include <ranlib.h> ! 23: #include <a.out.h> ! 24: #include <stdio.h> ! 25: ! 26: struct ar_hdr archdr; ! 27: #define OARMAG 0177545 ! 28: long arsize; ! 29: struct exec exp; ! 30: FILE *fi, *fo; ! 31: long off, oldoff; ! 32: long atol(), ftell(); ! 33: #define TABSZ 3000 ! 34: int tnum; ! 35: #define STRTABSZ 30000 ! 36: int tssiz; ! 37: char *strtab; ! 38: int ssiz; ! 39: int new; ! 40: char tempnm[] = "__.SYMDEF"; ! 41: char firstname[17]; ! 42: void stash(); ! 43: char *malloc(), *calloc(); ! 44: ! 45: /* ! 46: * table segment definitions ! 47: */ ! 48: char *segalloc(); ! 49: void segclean(); ! 50: struct tabsegment { ! 51: struct tabsegment *pnext; ! 52: unsigned nelem; ! 53: struct ranlib tab[TABSZ]; ! 54: } tabbase, *ptabseg; ! 55: struct strsegment { ! 56: struct strsegment *pnext; ! 57: unsigned nelem; ! 58: char stab[STRTABSZ]; ! 59: } strbase, *pstrseg; ! 60: ! 61: main(argc, argv) ! 62: char **argv; ! 63: { ! 64: char cmdbuf[BUFSIZ]; ! 65: /* magbuf must be an int array so it is aligned on an int-ish ! 66: boundary, so that we may access its first word as an int! */ ! 67: int magbuf[(SARMAG+sizeof(int))/sizeof(int)]; ! 68: register int just_touch = 0; ! 69: register struct tabsegment *ptab; ! 70: register struct strsegment *pstr; ! 71: ! 72: /* check for the "-t" flag" */ ! 73: if (argc > 1 && strcmp(argv[1], "-t") == 0) { ! 74: just_touch++; ! 75: argc--; ! 76: argv++; ! 77: } ! 78: ! 79: --argc; ! 80: while(argc--) { ! 81: fi = fopen(*++argv,"r"); ! 82: if (fi == NULL) { ! 83: fprintf(stderr, "ranlib: cannot open %s\n", *argv); ! 84: continue; ! 85: } ! 86: off = SARMAG; ! 87: fread((char *)magbuf, 1, SARMAG, fi); ! 88: if (strncmp((char *)magbuf, ARMAG, SARMAG)) { ! 89: if (magbuf[0] == OARMAG) ! 90: fprintf(stderr, "old format "); ! 91: else ! 92: fprintf(stderr, "not an "); ! 93: fprintf(stderr, "archive: %s\n", *argv); ! 94: continue; ! 95: } ! 96: if (just_touch) { ! 97: register int len; ! 98: ! 99: fseek(fi, (long) SARMAG, 0); ! 100: if (fread(cmdbuf, sizeof archdr.ar_name, 1, fi) != 1) { ! 101: fprintf(stderr, "malformed archive: %s\n", ! 102: *argv); ! 103: continue; ! 104: } ! 105: len = strlen(tempnm); ! 106: if (bcmp(cmdbuf, tempnm, len) != 0 || ! 107: cmdbuf[len] != ' ') { ! 108: fprintf(stderr, "no symbol table: %s\n", *argv); ! 109: continue; ! 110: } ! 111: fclose(fi); ! 112: fixdate(*argv); ! 113: continue; ! 114: } ! 115: fseek(fi, 0L, 0); ! 116: new = tssiz = tnum = 0; ! 117: segclean(); ! 118: if (nextel(fi) == 0) { ! 119: fclose(fi); ! 120: continue; ! 121: } ! 122: do { ! 123: long o; ! 124: register n; ! 125: struct nlist sym; ! 126: ! 127: fread((char *)&exp, 1, sizeof(struct exec), fi); ! 128: if (N_BADMAG(exp)) ! 129: continue; ! 130: if (!strncmp(tempnm, archdr.ar_name, sizeof(archdr.ar_name))) ! 131: continue; ! 132: if (exp.a_syms == 0) { ! 133: fprintf(stderr, "ranlib: warning: %s(%s): no symbol table\n", *argv, archdr.ar_name); ! 134: continue; ! 135: } ! 136: o = N_STROFF(exp) - sizeof (struct exec); ! 137: if (ftell(fi)+o+sizeof(ssiz) >= off) { ! 138: fprintf(stderr, "ranlib: warning: %s(%s): old format .o file\n", *argv, archdr.ar_name); ! 139: continue; ! 140: } ! 141: fseek(fi, o, 1); ! 142: fread((char *)&ssiz, 1, sizeof (ssiz), fi); ! 143: if (ssiz < sizeof ssiz){ ! 144: /* sanity check */ ! 145: fprintf(stderr, "ranlib: warning: %s(%s): mangled string table\n", *argv, archdr.ar_name); ! 146: continue; ! 147: } ! 148: strtab = (char *)calloc(1, ssiz); ! 149: if (strtab == 0) { ! 150: fprintf(stderr, "ranlib: ran out of memory\n"); ! 151: exit(1); ! 152: } ! 153: fread(strtab+sizeof(ssiz), ssiz - sizeof(ssiz), 1, fi); ! 154: fseek(fi, -(exp.a_syms+ssiz), 1); ! 155: n = exp.a_syms / sizeof(struct nlist); ! 156: while (--n >= 0) { ! 157: fread((char *)&sym, 1, sizeof(sym), fi); ! 158: if (sym.n_un.n_strx == 0) ! 159: continue; ! 160: sym.n_un.n_name = strtab + sym.n_un.n_strx; ! 161: if ((sym.n_type&N_EXT)==0) ! 162: continue; ! 163: switch (sym.n_type&N_TYPE) { ! 164: ! 165: case N_UNDF: ! 166: if (sym.n_value!=0) ! 167: stash(&sym); ! 168: continue; ! 169: ! 170: default: ! 171: stash(&sym); ! 172: continue; ! 173: } ! 174: } ! 175: free(strtab); ! 176: } while(nextel(fi)); ! 177: new = fixsize(); ! 178: fclose(fi); ! 179: fo = fopen(tempnm, "w"); ! 180: if(fo == NULL) { ! 181: fprintf(stderr, "can't create temporary\n"); ! 182: exit(1); ! 183: } ! 184: tnum *= sizeof (struct ranlib); ! 185: fwrite(&tnum, 1, sizeof (tnum), fo); ! 186: tnum /= sizeof (struct ranlib); ! 187: ptab = &tabbase; ! 188: do { ! 189: fwrite((char *)ptab->tab, ptab->nelem, ! 190: sizeof(struct ranlib), fo); ! 191: } while (ptab = ptab->pnext); ! 192: fwrite(&tssiz, 1, sizeof (tssiz), fo); ! 193: pstr = &strbase; ! 194: do { ! 195: fwrite(pstr->stab, pstr->nelem, 1, fo); ! 196: tssiz -= pstr->nelem; ! 197: } while (pstr = pstr->pnext); ! 198: /* pad with nulls */ ! 199: while (tssiz--) putc('\0', fo); ! 200: fclose(fo); ! 201: if(new) ! 202: sprintf(cmdbuf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); ! 203: else ! 204: sprintf(cmdbuf, "ar rl %s %s\n", *argv, tempnm); ! 205: if(system(cmdbuf)) ! 206: fprintf(stderr, "ranlib: ``%s'' failed\n", cmdbuf); ! 207: else ! 208: fixdate(*argv); ! 209: unlink(tempnm); ! 210: } ! 211: exit(0); ! 212: } ! 213: ! 214: nextel(af) ! 215: FILE *af; ! 216: { ! 217: register r; ! 218: register char *cp; ! 219: ! 220: oldoff = off; ! 221: fseek(af, off, 0); ! 222: r = fread((char *)&archdr, 1, sizeof(struct ar_hdr), af); ! 223: if (r != sizeof(struct ar_hdr)) ! 224: return(0); ! 225: for (cp=archdr.ar_name; cp < & archdr.ar_name[sizeof(archdr.ar_name)]; cp++) ! 226: if (*cp == ' ') ! 227: *cp = '\0'; ! 228: arsize = atol(archdr.ar_size); ! 229: if (arsize & 1) ! 230: arsize++; ! 231: off = ftell(af) + arsize; ! 232: return(1); ! 233: } ! 234: ! 235: void ! 236: stash(s) ! 237: struct nlist *s; ! 238: { ! 239: register char *cp; ! 240: register char *strtab; ! 241: register strsiz; ! 242: register struct ranlib *tab; ! 243: register tabsiz; ! 244: ! 245: if (ptabseg->nelem >= TABSZ) { ! 246: /* allocate a new symbol table segment */ ! 247: ptabseg = ptabseg->pnext = ! 248: (struct tabsegment *) segalloc(sizeof(struct tabsegment)); ! 249: ptabseg->pnext = NULL; ! 250: ptabseg->nelem = 0; ! 251: } ! 252: tabsiz = ptabseg->nelem; ! 253: tab = ptabseg->tab; ! 254: ! 255: if (pstrseg->nelem >= STRTABSZ) { ! 256: /* allocate a new string table segment */ ! 257: pstrseg = pstrseg->pnext = ! 258: (struct strsegment *) segalloc(sizeof(struct strsegment)); ! 259: pstrseg->pnext = NULL; ! 260: pstrseg->nelem = 0; ! 261: } ! 262: strsiz = pstrseg->nelem; ! 263: strtab = pstrseg->stab; ! 264: ! 265: tab[tabsiz].ran_un.ran_strx = tssiz; ! 266: tab[tabsiz].ran_off = oldoff; ! 267: redo: ! 268: for (cp = s->n_un.n_name; strtab[strsiz++] = *cp++;) ! 269: if (strsiz >= STRTABSZ) { ! 270: /* allocate a new string table segment */ ! 271: pstrseg = pstrseg->pnext = ! 272: (struct strsegment *) segalloc(sizeof(struct strsegment)); ! 273: pstrseg->pnext = NULL; ! 274: strsiz = pstrseg->nelem = 0; ! 275: strtab = pstrseg->stab; ! 276: goto redo; ! 277: } ! 278: ! 279: tssiz += strsiz - pstrseg->nelem; /* length of the string */ ! 280: pstrseg->nelem = strsiz; ! 281: tnum++; ! 282: ptabseg->nelem++; ! 283: } ! 284: ! 285: /* allocate a zero filled segment of size bytes */ ! 286: char * ! 287: segalloc(size) ! 288: unsigned size; ! 289: { ! 290: char *pseg = NULL; ! 291: ! 292: pseg = malloc(size); ! 293: if (pseg == NULL) { ! 294: fprintf(stderr, "ranlib: ran out of memeory\n"); ! 295: exit(1); ! 296: } ! 297: return(pseg); ! 298: } ! 299: ! 300: /* free segments */ ! 301: void ! 302: segclean() ! 303: { ! 304: register struct tabsegment *ptab; ! 305: register struct strsegment *pstr; ! 306: ! 307: /* ! 308: * symbol table ! 309: * ! 310: * The first entry is static. ! 311: */ ! 312: ptabseg = &tabbase; ! 313: ptab = ptabseg->pnext; ! 314: while (ptabseg = ptab) { ! 315: ptab = ptabseg->pnext; ! 316: free((char *)ptabseg); ! 317: } ! 318: ptabseg = &tabbase; ! 319: ptabseg->pnext = NULL; ! 320: ptabseg->nelem = 0; ! 321: ! 322: /* ! 323: * string table ! 324: * ! 325: * The first entry is static. ! 326: */ ! 327: pstrseg = &strbase; ! 328: pstr = pstrseg->pnext; ! 329: while (pstrseg = pstr) { ! 330: pstr = pstrseg->pnext; ! 331: free((char *)pstrseg); ! 332: } ! 333: pstrseg = &strbase; ! 334: pstrseg->pnext = NULL; ! 335: pstrseg->nelem = 0; ! 336: } ! 337: ! 338: fixsize() ! 339: { ! 340: int i; ! 341: off_t offdelta; ! 342: register struct tabsegment *ptab; ! 343: ! 344: if (tssiz&1) ! 345: tssiz++; ! 346: offdelta = sizeof(archdr) + sizeof (tnum) + tnum * sizeof(struct ranlib) + ! 347: sizeof (tssiz) + tssiz; ! 348: off = SARMAG; ! 349: nextel(fi); ! 350: if(strncmp(archdr.ar_name, tempnm, sizeof (archdr.ar_name)) == 0) { ! 351: new = 0; ! 352: offdelta -= sizeof(archdr) + arsize; ! 353: } else { ! 354: new = 1; ! 355: strncpy(firstname, archdr.ar_name, sizeof(archdr.ar_name)); ! 356: } ! 357: ptab = &tabbase; ! 358: do { ! 359: for (i = 0; i < ptab->nelem; i++) ! 360: ptab->tab[i].ran_off += offdelta; ! 361: } while (ptab = ptab->pnext); ! 362: return(new); ! 363: } ! 364: ! 365: /* patch time */ ! 366: fixdate(s) ! 367: char *s; ! 368: { ! 369: long time(); ! 370: char buf[24]; ! 371: int fd; ! 372: ! 373: fd = open(s, 1); ! 374: if(fd < 0) { ! 375: fprintf(stderr, "ranlib: can't reopen %s\n", s); ! 376: return; ! 377: } ! 378: sprintf(buf, "%-*ld", sizeof(archdr.ar_date), time((long *)NULL)+5); ! 379: lseek(fd, (long)SARMAG + ((char *)archdr.ar_date-(char *)&archdr), 0); ! 380: write(fd, buf, sizeof(archdr.ar_date)); ! 381: close(fd); ! 382: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.