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: }

Defined functions

fixdate defined in line 366; used 2 times
fixsize defined in line 338; used 1 times
main defined in line 61; never used
nextel defined in line 214; used 3 times
segalloc defined in line 286; used 4 times
segclean defined in line 301; used 2 times
stash defined in line 235; used 3 times

Defined variables

archdr defined in line 26; used 21 times
arsize defined in line 28; used 5 times
copyright defined in line 8; never used
exp defined in line 29; used 6 times
firstname defined in line 41; used 2 times
new defined in line 39; used 6 times
off defined in line 31; used 6 times
oldoff defined in line 31; used 2 times
pstrseg defined in line 59; used 22 times
ptabseg defined in line 54; used 16 times
sccsid defined in line 14; never used
ssiz defined in line 38; used 10 times
strbase defined in line 59; used 3 times
strtab defined in line 37; used 9 times
tabbase defined in line 54; used 4 times
tempnm defined in line 40; used 8 times
tnum defined in line 34; used 8 times
tssiz defined in line 36; used 11 times

Defined struct's

strsegment defined in line 55; used 14 times
tabsegment defined in line 50; used 12 times

Defined macros

OARMAG defined in line 27; used 1 times
  • in line 89
STRTABSZ defined in line 35; used 3 times
TABSZ defined in line 33; used 2 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2106
Valid CSS Valid XHTML 1.0 Strict