xref: /illumos-gate/usr/src/cmd/refer/glue1.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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
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 *
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
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