1 #include <lib9.h> 2 #include <bio.h> 3 #include <mach.h> 4 5 int conly; 6 int exists; 7 8 enum { 9 Maxroot = 10, 10 }; 11 12 int nroot; 13 char *root[Maxroot]; 14 int rootlen[Maxroot]; 15 16 void usage(void); 17 void error(char *); 18 void addroot(char *); 19 void addroots(char *); 20 void chomp(char *); 21 22 extern char *mygetwd(char*, int); 23 24 void 25 main(int argc, char **argv) 26 { 27 char buf[1024], *cwd; 28 29 cwd = mygetwd(buf, sizeof(buf)); 30 ARGBEGIN { 31 case 'c': 32 conly = 1; 33 break; 34 case 'e': 35 exists = 1; 36 break; 37 case 'r': 38 addroots(EARGF(usage())); 39 break; 40 default: 41 usage(); 42 } ARGEND 43 44 if(argc != 1) 45 usage(); 46 47 if(cwd != nil) 48 chdir(cwd); 49 setbinmode(); 50 chomp(argv[0]); 51 52 exits(0); 53 } 54 55 void 56 addroot(char *x) 57 { 58 if(nroot >= Maxroot){ 59 fprint(2, "srclist: too many root directories\n"); 60 exits("usage"); 61 } 62 root[nroot] = x; 63 rootlen[nroot] = strlen(x); 64 nroot++; 65 } 66 67 void 68 addrootnt(char *r) 69 { 70 addroot(r); 71 if(r[1] != ':') 72 return; /* phew! */ 73 if(*r >= 'a' && *r <= 'z' || *r >= 'A' && *r <= 'Z') 74 addroot(r+2); 75 } 76 77 void 78 addroots(char *r) 79 { 80 char buf[1024], *r2; 81 82 addrootnt(r); 83 if(chdir(r) < 0) 84 return; 85 r2 = mygetwd(buf, sizeof(buf)); 86 if(r2 && strcmp(r2, r) != 0) 87 addrootnt(r2); 88 } 89 90 void 91 chomp(char *file) 92 { 93 int fd, i, j, len; 94 Fhdr fhdr; 95 Dir *td; 96 char fname[1024]; 97 98 fd = open(file, OREAD); 99 if(fd < 0) 100 error("open"); 101 102 if(crackhdr(fd, &fhdr) == 0) 103 error("crackhdr"); 104 105 if(syminit(fd, &fhdr) < 0) 106 error("syminit"); 107 108 for(i = 0; i < 1000; i++) 109 if(filesym(i, fname, sizeof(fname)-1)){ 110 cleanname(fname); 111 if(conly){ 112 len = strlen(fname); 113 if(len < 2 || strcmp(fname+len-2, ".c") != 0) 114 continue; 115 } 116 if(exists){ 117 if((td = dirstat(fname)) == nil) 118 continue; 119 free(td); 120 } 121 if(nroot){ 122 for(j = 0; j < nroot; j++) 123 if(strncmp(fname, root[j], rootlen[j]) == 0) 124 break; 125 if(j == nroot) 126 continue; 127 } 128 print("%s\n", fname); 129 } 130 } 131 132 void 133 usage(void) 134 { 135 fprint(2, "usage: srclist [-ce] [-r root] <objfile>\n"); 136 exits("usage"); 137 } 138 139 void 140 error(char *s) 141 { 142 fprint(2, "srclist: %s: %r\n", s); 143 exits(s); 144 } 145