1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 7 /* All Rights Reserved */ 8 9 /* 10 * Copyright (c) 1980 Regents of the University of California. 11 * All rights reserved. The Berkeley software License Agreement 12 * specifies the terms and conditions for redistribution. 13 */ 14 15 #include <stdio.h> 16 17 #define unopen(fil) {if (fil != NULL) {fclose(fil); fil = NULL; }} 18 19 extern char refdir[]; 20 int lmaster = 1000; 21 int reached = 0; 22 FILE *fd = 0; 23 int *hfreq, hfrflg; 24 int colevel = 0; 25 static union firetruck { 26 unsigned *a; 27 long *b; 28 } master; 29 int iflong; 30 extern char *fgnames[], **fgnamp; 31 extern FILE *iopen(); 32 int prfreqs = 0; 33 int typeindex = 0; 34 char usedir[100]; 35 static int full = 1000; 36 static int tags = 0; 37 char *sinput, *soutput, *tagout; 38 long indexdate = 0, gdate(); 39 int soutlen = 1000; 40 int taglen = 1000; 41 42 extern int baddrop(); 43 extern int ckexist(); 44 extern int doquery(); 45 extern void err(); 46 extern int getq(); 47 extern void grepcall(); 48 extern int makefgrep(); 49 extern void restodir(); 50 extern void result(); 51 extern void savedir(); 52 extern void *zalloc(); 53 54 static int setfrom(char); 55 char *todir(char *); 56 57 void 58 huntmain(int argc, char *argv[]) 59 { 60 /* read query from stdin, expect name of indexes in argv[1] */ 61 static FILE *fa, *fb, *fc; 62 char indexname[100], *qitem[100], *rprog = 0; 63 char grepquery[200]; 64 static char oldname[30]; 65 static int nhash = 0; 66 static int maxhash = 0; 67 int falseflg = 0, nitem, nfound, frtbl; 68 static long *hpt = 0; 69 unsigned *masterp; 70 71 #if D1 72 fprintf(stderr, "in glue1 argc %d argv %o %o\n", 73 argc, argv[0], argv[1]); 74 #endif 75 savedir(); 76 while (argv[1][0] == '-') { 77 #if D1 78 fprintf(stderr, "argv.1 is %s\n", argv[1]); 79 #endif 80 switch (argv[1][1]) { 81 case 'a': /* all output, incl. false drops */ 82 falseflg = 1; 83 break; 84 case 'r': 85 argc--; 86 argv++; 87 rprog = argv[1]; 88 break; 89 case 'F': /* put out full text */ 90 full = setfrom(argv[1][2]); 91 break; 92 case 'T': /* put out tags */ 93 tags = setfrom(argv[1][2]); 94 break; 95 case 'i': /* input in argument string */ 96 argc--; 97 argv++; 98 sinput = argv[1]; 99 break; 100 case 's': /* text output to string */ 101 case 'o': 102 argc--; 103 argv++; 104 soutput = argv[1]; 105 if ((int)argv[2] < 16000) { 106 soutlen = (int)argv[2]; 107 argc--; 108 argv++; 109 } 110 break; 111 case 't': /* tag output to string */ 112 argc--; 113 argv++; 114 tagout = argv[1]; 115 if ((int)argv[2] < 16000) { 116 taglen = (int)argv[2]; 117 argc--; 118 argv++; 119 } 120 break; 121 case 'l': /* specify length of lists */ 122 argc--; 123 argv++; 124 lmaster = atoi(argv[1]); 125 #if D1 126 fprintf(stderr, "lmaster now %d\n", lmaster); 127 #endif 128 break; 129 case 'C': 130 argc--; 131 argv++; 132 colevel = atoi(argv[1]); 133 break; 134 } 135 argc--; 136 argv++; 137 } 138 strcpy(indexname, todir(argv[1])); 139 #if D1 140 fprintf(stderr, "in huntmain indexname %s typeindex %d\n", 141 indexname, typeindex); 142 #endif 143 if (typeindex == 0 || strcmp(oldname, indexname) != 0) { 144 strcpy(oldname, indexname); 145 unopen(fa); 146 unopen(fb); 147 unopen(fc); 148 149 if (ckexist(indexname, ".ib")) { 150 #if D1 151 fprintf(stderr, "found old index\n"); 152 #endif 153 fa = iopen(indexname, ".ia"); 154 fb = iopen(indexname, ".ib"); 155 fc = iopen(indexname, ".ic"); 156 typeindex = 1; 157 #if D1 158 fprintf(stderr, "opened f's as %o %o %o\n", fa, fb, fc); 159 #endif 160 indexdate = gdate(fb); 161 fread(&nhash, sizeof (nhash), 1, fa); 162 fread(&iflong, sizeof (iflong), 1, fa); 163 if (nhash > maxhash) { 164 if (hpt) 165 free(hpt, maxhash, sizeof (*hpt)); 166 hpt = 0; 167 if (hfreq) 168 free(hfreq, maxhash, sizeof (*hfreq)); 169 hfreq = 0; 170 maxhash = nhash; 171 #if D1 172 fprintf(stderr, "Freed if needed maxhash %d\n", 173 maxhash); 174 #endif 175 } 176 if (hpt == 0) 177 hpt = (long *)zalloc(nhash, sizeof (*hpt)); 178 #if D1 179 fprintf(stderr, "hpt now %o\n", hpt); 180 #endif 181 if (hpt == NULL) 182 /* 183 * TRANSLATION_NOTE 184 * %d is the size of the hash table - not 185 * very interesting info for the end users. 186 * Hash is a computer science terminology. 187 */ 188 err(gettext("No space for hash list (%d)"), 189 nhash); 190 fread(hpt, sizeof (*hpt), nhash, fa); 191 if (hfreq == 0) 192 hfreq = (int *)zalloc(nhash, sizeof (*hfreq)); 193 if (hfreq == NULL) 194 /* 195 * TRANSLATION_NOTE 196 * %d is the size of the hash table. 197 */ 198 err(gettext( 199 "No space for hash frequencies (%d)"), 200 nhash); 201 frtbl = fread(hfreq, sizeof (*hfreq), nhash, fa); 202 hfrflg = (frtbl == nhash); 203 #if D1 204 fprintf(stderr, "Read pointer files\n"); 205 #endif 206 if (master.a == NULL) 207 if (iflong) 208 master.b = (long *)zalloc(lmaster, 209 sizeof (long)); 210 else 211 master.a = (unsigned *)zalloc(lmaster, 212 sizeof (int)); 213 if (master.a == NULL) 214 err(gettext("no space for answer list"), 0); 215 } else 216 if (makefgrep(indexname)) 217 typeindex = 2; 218 else { 219 err(gettext("No files %s\n"), indexname); 220 exit(1); 221 } 222 } 223 224 if (iflong) 225 masterp = (unsigned *)master.b; 226 else 227 masterp = master.a; 228 229 #if D1 230 fprintf(stderr, "typeindex now %d\n", typeindex); 231 #endif 232 tagout[0] = 0; 233 if (typeindex == 2) { 234 grepcall(sinput, tagout, indexname); 235 #if D1 236 fprintf(stderr, " back from grepcall\n"); 237 #endif 238 restodir(); 239 return; 240 } 241 nitem = getq(qitem); 242 #if D1 243 fprintf(stderr, "approaching doquery fb %o\n", fb); 244 #endif 245 nfound = doquery(hpt, nhash, fb, nitem, qitem, masterp); 246 #ifdef D1 247 fprintf(stderr, "return from doquery with nfound %d\n", nfound); 248 #endif 249 if (falseflg == 0) 250 nfound = baddrop(masterp, nfound, fc, nitem, qitem, 251 rprog, full); 252 #ifdef D1 253 fprintf(stderr, "after baddrop with nfound %d\n", nfound); 254 fprintf(stderr, "tagout is /%s/, sout /%s/\n", tagout, soutput); 255 #endif 256 if (tags) 257 result(masterp, nfound > tags ? tags : nfound, fc); 258 #if D1 259 fprintf(stderr, "done with huntmain\n"); 260 fprintf(stderr, "tagout is /%s/\n", tagout); 261 fprintf(stderr, "string out is /%s/\n", soutput); 262 #endif 263 if (fgnamp > fgnames) { 264 char **fgp; 265 int k; 266 #if D1 267 fprintf(stderr, "were %d bad files\n", fgnamp-fgnames); 268 #endif 269 grepquery[0] = 0; 270 for (k = 0; k < nitem; k++) { 271 strcat(grepquery, " "); 272 strcat(grepquery, qitem[k]); 273 } 274 for (fgp = fgnames; fgp < fgnamp; fgp++) { 275 #if D1 276 fprintf(stderr, "Now on %s query /%s/\n", 277 *fgp, grepquery); 278 #endif 279 makefgrep(*fgp); 280 grepcall(grepquery, tagout, *fgp); 281 #if D1 282 fprintf(stderr, "tagout now /%s/\n", tagout); 283 #endif 284 } 285 } 286 restodir(); 287 } 288 289 char * 290 todir(char *t) 291 { 292 char *s; 293 294 usedir[0] = 0; 295 s = t; 296 while (*s) s++; 297 while (s >= t && *s != '/') s--; 298 if (s < t) 299 return (t); 300 *s++ = 0; 301 t = (*t ? t : "/"); 302 chdir(t); 303 strcpy(usedir, t); 304 return (s); 305 } 306 307 static int 308 setfrom(char c) 309 { 310 switch (c) { 311 case 'y': 312 case '\0': 313 default: 314 return (1000); 315 case '1': 316 case '2': 317 case '3': 318 case '4': 319 case '5': 320 case '6': 321 case '7': 322 case '8': 323 case '9': 324 return (c-'0'); 325 case 'n': 326 case '0': 327 return (0); 328 } 329 } 330