|
|
1.1 ! root 1: /* ! 2: * Make libraries more accessible to the loader ! 3: * by copying all the globally defined symbols ! 4: * into a special module at the front of the archive. ! 5: * Speed up by simply overwriting the header in the archive ! 6: * if it fits, which it will more often than not. ! 7: */ ! 8: #include <stdio.h> ! 9: #include <ar.h> ! 10: #include <canon.h> ! 11: ! 12: static struct ldheader ldh; ! 13: ! 14: main(argc, argv) ! 15: int argc; ! 16: char *argv[]; ! 17: { ! 18: register int i, errors = 0; ! 19: ! 20: if (argc==1) { ! 21: fprintf(stderr, "Usage: %s [ archive]+\n", argv[0]); ! 22: exit(1); ! 23: } ! 24: for (i=1; i<argc; i++) { ! 25: errors += ranlib(argv[i]); ! 26: } ! 27: unlink(HDRNAME); ! 28: exit(errors); ! 29: } ! 30: ! 31: static ! 32: void ! 33: complain(plaint) ! 34: char *plaint; ! 35: { ! 36: fprintf(stderr, "ranlib: %r\n", &plaint); ! 37: } ! 38: ! 39: static ! 40: void ! 41: xwrite(sym, fp) ! 42: ar_sym *sym; ! 43: FILE *fp; ! 44: { ! 45: if (fwrite(sym, sizeof(ar_sym), 1, fp)!=1) { ! 46: complain("write error on header file"); ! 47: exit(1); ! 48: } ! 49: } ! 50: ! 51: static ! 52: void ! 53: addhdr(base, arhp, hdrfp, arfp, archive) ! 54: fsize_t base; ! 55: struct ar_hdr *arhp; ! 56: FILE *hdrfp, *arfp; ! 57: char *archive; ! 58: { ! 59: fsize_t off; ! 60: int seg, nsym; ! 61: fsize_t offset; ! 62: ! 63: cansize(arhp->ar_size); ! 64: arhp->ar_size += off = ftell(arfp); ! 65: off -= base; ! 66: ldh.l_magic = 0; /* in case fread fails */ ! 67: if (fread(&ldh, sizeof ldh, 1, arfp)!=1) ! 68: goto done; ! 69: canshort(ldh.l_magic); ! 70: if (ldh.l_magic!=L_MAGIC) ! 71: goto done; ! 72: canshort(ldh.l_flag); ! 73: if ((ldh.l_flag & LF_32) == 0) ! 74: ldh.l_tbase = sizeof(ldh) - 2*sizeof(short); ! 75: else ! 76: canshort(ldh.l_tbase); ! 77: offset = ldh.l_tbase - (fsize_t)sizeof(ldh); ! 78: for (seg=0; seg<L_SYM; seg++) { ! 79: if (seg==L_BSSI || seg==L_BSSD) ! 80: continue; ! 81: cansize(ldh.l_ssize[seg]); ! 82: offset += ldh.l_ssize[seg]; ! 83: } ! 84: fseek(arfp, offset, 1); ! 85: cansize(ldh.l_ssize[L_SYM]); ! 86: if ((ldh.l_flag & LF_32) == 0) ! 87: nsym = ldh.l_ssize[L_SYM] ! 88: / (sizeof(struct ldsym) - sizeof(short)); ! 89: else ! 90: nsym = ldh.l_ssize[L_SYM]/sizeof(struct ldsym); ! 91: while (nsym--) { ! 92: union {struct ldsym u_ldsym; ar_sym u_ar_sym;} sym; ! 93: ! 94: if (readsym((struct ldsym *)&sym, arfp) == 0) { ! 95: complain("truncated module %.*s in %s", ! 96: DIRSIZ, arhp->ar_name, archive); ! 97: exit(1); ! 98: } ! 99: if ((sym.ls_type&L_GLOBAL) == 0) ! 100: continue; ! 101: if ((sym.ls_type&LR_SEG) != L_REF) { ! 102: sym.ar_off = off; ! 103: cansize(sym.ar_off); ! 104: xwrite(&sym, hdrfp); ! 105: } ! 106: } ! 107: done: ! 108: fseek(arfp, arhp->ar_size, 0); /* to end of module */ ! 109: return; ! 110: } ! 111: ! 112: static ! 113: readsym(sp, fp) ! 114: register struct ldsym *sp; ! 115: FILE *fp; ! 116: { ! 117: register int r; ! 118: union { long l; unsigned u[2]; } u; ! 119: ! 120: if ((ldh.l_flag & LF_32) == 0) { ! 121: r = fread(sp, sizeof(struct ldsym)-sizeof(short), 1, fp); ! 122: u.l = sp->ls_addr; ! 123: canshort(u.u[0]); ! 124: sp->ls_addr = u.u[0]; ! 125: } else { ! 126: r = fread(sp, sizeof(struct ldsym), 1, fp); ! 127: canlong(sp->ls_addr); ! 128: } ! 129: canshort(sp->ls_type); ! 130: return (r); ! 131: } ! 132: ! 133: static ! 134: int ! 135: ranlib(archive) ! 136: char *archive; ! 137: { ! 138: FILE *arfile, *hdrfile; ! 139: char arcmd[256]; ! 140: struct ar_hdr arhdr; ! 141: struct ar_sym arsym; ! 142: fsize_t ohdrsize, nhdrsize; ! 143: int armagic = 0; ! 144: fsize_t arbase = sizeof armagic+sizeof arhdr; ! 145: extern time_t time(); ! 146: ! 147: if ((arfile=fopen(archive, "rb"))==NULL) { ! 148: complain("can't open archive %s", archive); ! 149: return (1); ! 150: } ! 151: fread(&armagic, sizeof armagic, 1, arfile); ! 152: canint(armagic); ! 153: if (armagic!=ARMAG) { ! 154: complain("%s is not an archive", archive); ! 155: fclose(arfile); ! 156: return (1); ! 157: } ! 158: if (fread(&arhdr, sizeof arhdr, 1, arfile)!=1) { ! 159: fclose(arfile); /* void archive */ ! 160: return (0); ! 161: } ! 162: if ((hdrfile=fopen(HDRNAME, "wb"))==NULL) { ! 163: complain("can't create header file"); ! 164: fclose(arfile); ! 165: exit(1); ! 166: } ! 167: if (strncmp(arhdr.ar_name, HDRNAME, DIRSIZ)==0) { ! 168: sprintf(arcmd, "ar ru %s %s", archive, HDRNAME); ! 169: cansize(arhdr.ar_size); ! 170: ohdrsize = arhdr.ar_size; ! 171: fseek(arfile, arhdr.ar_size, 1); ! 172: arbase += arhdr.ar_size+sizeof arhdr; ! 173: } else { ! 174: sprintf(arcmd, "ar rub %.*s %s %s", DIRSIZ, arhdr.ar_name, ! 175: archive, HDRNAME); ! 176: ohdrsize = 0; ! 177: addhdr(arbase, &arhdr, hdrfile, arfile, archive); ! 178: } ! 179: while(fread(&arhdr, sizeof arhdr, 1, arfile)==1) ! 180: addhdr(arbase, &arhdr, hdrfile, arfile, archive); ! 181: nhdrsize = ftell(hdrfile); ! 182: if (fclose(hdrfile)==EOF) { ! 183: complain("close error on header file"); ! 184: exit(1); ! 185: } ! 186: if (ferror(arfile)) { ! 187: complain("read error on archive %s", archive); ! 188: fclose(arfile); ! 189: return (1); ! 190: } ! 191: fclose(arfile); ! 192: if (ohdrsize < nhdrsize) ! 193: return system(arcmd); ! 194: if (ohdrsize == 0) { ! 195: complain("zero length header file"); ! 196: return (0); ! 197: } ! 198: if ((arfile=fopen(archive, "rwb"))==NULL) { ! 199: complain("can't reopen archive %s", archive); ! 200: return (1); ! 201: } ! 202: fread(&armagic, sizeof armagic, 1, arfile); ! 203: canint(armagic); ! 204: if (armagic!=ARMAG) { ! 205: complain("%s is no longer an archive", archive); ! 206: fclose(arfile); ! 207: return (1); ! 208: } ! 209: if ((hdrfile=fopen(HDRNAME, "rb"))==NULL) { ! 210: complain("can't reopen header file"); ! 211: fclose(arfile); ! 212: exit(1); ! 213: } ! 214: if (fread(&arhdr, sizeof arhdr, 1, arfile)!=1) { ! 215: complain("can't read archive: %s", archive); ! 216: fclose(arfile); ! 217: fclose(hdrfile); ! 218: return (1); ! 219: } ! 220: arhdr.ar_date = time(NULL); ! 221: cantime(arhdr.ar_date); ! 222: fseek(arfile, (long)-sizeof arhdr, 1); ! 223: fwrite(&arhdr, sizeof arhdr, 1, arfile); ! 224: while (fread(&arsym, sizeof arsym, 1, hdrfile) == 1) { ! 225: fwrite(&arsym, sizeof arsym, 1, arfile); ! 226: ohdrsize -= sizeof arsym; ! 227: } ! 228: while (ohdrsize > 0) { ! 229: fwrite(&arsym, sizeof arsym, 1, arfile); ! 230: ohdrsize -= sizeof arsym; ! 231: } ! 232: if (fclose(arfile) == EOF) ! 233: complain("close error on overwritten archive: %s", archive); ! 234: if (fclose(hdrfile) == EOF) ! 235: complain("close error on reread header file"); ! 236: return (0); ! 237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.