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