1: #include <ar.h> 2: #include <a.out.h> 3: #include <stdio.h> 4: #define MAGIC exp.a_magic 5: #define BADMAG MAGIC!=A_MAGIC1 && MAGIC!=A_MAGIC2 \ 6: && MAGIC!=A_MAGIC3 && MAGIC!=A_MAGIC4 7: struct ar_hdr arp; 8: struct exec exp; 9: FILE *fi, *fo; 10: long off, oldoff; 11: long ftell(); 12: #define TABSZ 700 13: struct tab 14: { char cname[8]; 15: long cloc; 16: } tab[TABSZ]; 17: int tnum; 18: int new; 19: char tempnm[] = "__.SYMDEF"; 20: char firstname[17]; 21: long offdelta; 22: 23: main(argc, argv) 24: char **argv; 25: { 26: char buf[256]; 27: 28: --argc; 29: while(argc--) { 30: fi = fopen(*++argv,"r"); 31: if (fi == NULL) { 32: fprintf(stderr, "nm: cannot open %s\n", *argv); 33: continue; 34: } 35: off = sizeof(exp.a_magic); 36: fread((char *)&exp, 1, sizeof(MAGIC), fi); /* get magic no. */ 37: if (MAGIC != ARMAG) 38: { fprintf(stderr, "not archive: %s\n", *argv); 39: continue; 40: } 41: fseek(fi, 0L, 0); 42: new = tnum = 0; 43: if(nextel(fi) == 0) 44: { fclose(fi); 45: continue; 46: } 47: do { 48: long o; 49: register n; 50: struct nlist sym; 51: 52: fread((char *)&exp, 1, sizeof(struct exec), fi); 53: if (BADMAG) /* archive element not in */ 54: continue; /* proper format - skip it */ 55: o = (long)exp.a_text + exp.a_data; 56: if ((exp.a_flag & 01) == 0) 57: o *= 2; 58: fseek(fi, o, 1); 59: n = exp.a_syms / sizeof(struct nlist); 60: if (n == 0) { 61: fprintf(stderr, "nm: %s-- no name list\n", arp.ar_name); 62: continue; 63: } 64: while (--n >= 0) { 65: fread((char *)&sym, 1, sizeof(sym), fi); 66: if ((sym.n_type&N_EXT)==0) 67: continue; 68: switch (sym.n_type&N_TYPE) { 69: 70: case N_UNDF: 71: continue; 72: 73: default: 74: stash(&sym); 75: continue; 76: } 77: } 78: } while(nextel(fi)); 79: new = fixsize(); 80: fclose(fi); 81: fo = fopen(tempnm, "w"); 82: if(fo == NULL) 83: { fprintf(stderr, "can't create temporary\n"); 84: exit(1); 85: } 86: fwrite((char *)tab, tnum, sizeof(struct tab), fo); 87: fclose(fo); 88: if(new) 89: sprintf(buf, "ar rlb %s %s %s\n", firstname, *argv, tempnm); 90: else sprintf(buf, "ar rl %s %s\n", *argv, tempnm); 91: if(system(buf)) 92: fprintf(stderr, "can't execute %s\n", buf); 93: else fixdate(*argv); 94: unlink(tempnm); 95: } 96: exit(0); 97: } 98: 99: nextel(af) 100: FILE *af; 101: { 102: register r; 103: 104: oldoff = off; 105: fseek(af, off, 0); 106: r = fread((char *)&arp, 1, sizeof(struct ar_hdr), af); /* read archive header */ 107: if (r <= 0) 108: return(0); 109: if (arp.ar_size & 1) 110: ++arp.ar_size; 111: off = ftell(af) + arp.ar_size; /* offset to next element */ 112: return(1); 113: } 114: 115: stash(s) struct nlist *s; 116: { int i; 117: if(tnum >= TABSZ) 118: { fprintf(stderr, "symbol table overflow\n"); 119: exit(1); 120: } 121: for(i=0; i<8; i++) 122: tab[tnum].cname[i] = s->n_name[i]; 123: tab[tnum].cloc = oldoff; 124: tnum++; 125: } 126: 127: fixsize() 128: { int i; 129: offdelta = tnum * sizeof(struct tab) + sizeof(arp); 130: off = sizeof(MAGIC); 131: nextel(fi); 132: if(strncmp(arp.ar_name, tempnm, 14) == 0) 133: { new = 0; 134: offdelta -= sizeof(arp) + arp.ar_size; 135: } 136: else 137: { new = 1; 138: strncpy(firstname, arp.ar_name, 14); 139: } 140: for(i=0; i<tnum; i++) 141: tab[i].cloc += offdelta; 142: return(new); 143: } 144: 145: /* patch time */ 146: fixdate(s) char *s; 147: { long timex, time(); 148: int fd; 149: fd = open(s, 1); 150: if(fd < 0) 151: { fprintf(stderr, "can't reopen %s\n", s); 152: return; 153: } 154: timex = time(NULL) + 5; /* should be enough time */ 155: lseek(fd, (long)sizeof(exp.a_magic) + ((char *)&arp.ar_date-(char *)&arp), 0); 156: write(fd, (char *)&timex, sizeof(timex)); 157: close(fd); 158: }