xref: /illumos-gate/usr/src/cmd/refer/hunt1.c (revision 4283d10e18fc3904736c7c067fb29de9bb67d25d)
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 <locale.h>
16 #include <stdio.h>
17 #include <assert.h>
18 extern char refdir[];
19 extern int keepold;
20 extern char *fgnames[];
21 extern char **fgnamp;
22 FILE *fd = NULL;
23 int lmaster = 500;
24 int *hfreq, hfrflg;
25 int colevel = 0;
26 int measure = 0;
27 int soutlen = 1000;
28 int reached = 0;
29 int iflong = 0;
30 int prfreqs = 0;
31 char usedir[100];
32 char *calloc();
33 char *todir();
34 char gfile[50];
35 static int full = 1000;
36 static int tags = 0;
37 char *sinput, *soutput, *tagout;
38 long indexdate = 0, gdate();
39 
40 extern int baddrop();
41 extern int doquery();
42 extern void err();
43 extern long findline();
44 extern int getq();
45 extern void grepcall();
46 extern int makefgrep();
47 extern void result();
48 extern void tick();
49 extern void tock();
50 
51 static int setfrom(char);
52 
53 int
54 main(int argc, char *argv[])
55 {
56 	/* read query from stdin, expect name of indexes in argv[1] */
57 	static FILE *fa, *fb, *fc;
58 	char nma[100], nmb[100], nmc[100], *qitem[100], *rprog = NULL;
59 	char nmd[100], grepquery[256];
60 	static char oldname[30];
61 	static int was = 0;
62 	/* these pointers are unions of pointer to int and pointer to long */
63 	long *hpt;
64 	unsigned *master = 0;
65 	int falseflg, nhash, nitem, nfound, frtbl, kk;
66 
67 	/* special wart for refpart: default is tags only */
68 
69 	(void) setlocale(LC_ALL, "");
70 
71 #if !defined(TEXT_DOMAIN)
72 #define	TEXT_DOMAIN "SYS_TEST"
73 #endif
74 	(void) textdomain(TEXT_DOMAIN);
75 
76 	falseflg = 0;
77 
78 	while (argc > 1 && argv[1][0] == '-') {
79 		switch (argv[1][1]) {
80 		case 'a': /* all output, incl. false drops */
81 			falseflg = 1;
82 			break;
83 		case 'r':
84 			argc--;
85 			argv++;
86 			rprog = argv[1];
87 			break;
88 		case 'F': /* put out full text */
89 			full = setfrom(argv[1][2]);
90 			break;
91 		case 'T': /* put out tags */
92 			tags = setfrom(argv[1][2]);
93 			break;
94 		case 'i': /* input in argument string */
95 			argc--;
96 			argv++;
97 			sinput = argv[1];
98 			break;
99 		case 's': /* text output to string */
100 		case 'o':
101 			argc--;
102 			argv++;
103 			soutput = argv[1];
104 			if ((int)argv[2] < 16000) {
105 				soutlen = (int)argv[2];
106 				argc--;
107 				argv++;
108 			}
109 			break;
110 		case 't': /* tag output to string */
111 			argc--;
112 			argv++;
113 			tagout = argv[1];
114 			break;
115 		case 'l': /* length of internal lists */
116 			argc--;
117 			argv++;
118 			lmaster = atoi(argv[1]);
119 			break;
120 		case 'g': /* suppress fgrep search on old files */
121 			keepold = 0;
122 			break;
123 		case 'C': /* coordination level */
124 			colevel = atoi(argv[1]+2);
125 #if D1
126 			fprintf(stderr, "colevel set to %d\n", colevel);
127 #endif
128 			break;
129 		case 'P': /* print term freqs */
130 			prfreqs = 1;
131 			break;
132 		case 'm':
133 			measure = 1;
134 			break;
135 		}
136 		argc--;
137 		argv++;
138 	}
139 	if (argc < 2)
140 		exit(1);
141 	strcpy(nma, todir(argv[1]));
142 	if (was == 0 || strcmp(oldname, nma) != 0) {
143 		strcpy(oldname, nma);
144 		strcpy(nmb, nma);
145 		strcpy(nmc, nmb);
146 		strcpy(nmd, nma);
147 		strcat(nma, ".ia");
148 		strcat(nmb, ".ib");
149 		strcat(nmc, ".ic");
150 		strcat(nmd, ".id");
151 		if (was) {
152 			fclose(fa);
153 			fclose(fb);
154 			fclose(fc);
155 		}
156 
157 		fa = fopen(nma, "r");
158 		if (fa == NULL) {
159 			strcpy(*fgnamp++ = calloc(strlen(oldname)+2, 1),
160 			    oldname);
161 			fb = NULL;
162 			goto search;
163 		}
164 		fb = fopen(nmb, "r");
165 		fc = fopen(nmc, "r");
166 		was = 1;
167 		if (fb == NULL || fc == NULL) {
168 			err(gettext("Index incomplete %s"), nmb);
169 			exit(1);
170 		}
171 		indexdate = gdate(fb);
172 		fd = fopen(nmd, "r");
173 	}
174 	fseek(fa, 0L, 0);
175 	fread(&nhash, sizeof (nhash), 1, fa);
176 	fread(&iflong, sizeof (iflong), 1, fa);
177 	if (master == 0)
178 		master = (unsigned *)calloc(lmaster, iflong ?
179 		    sizeof (long) : sizeof (unsigned));
180 	hpt = (long *)calloc(nhash, sizeof (*hpt));
181 	kk = fread(hpt, sizeof (*hpt), nhash, fa);
182 #if D1
183 	fprintf(stderr, "read %d hashes, iflong %d, nhash %d\n",
184 	    kk, iflong, nhash);
185 #endif
186 	assert(kk == nhash);
187 	hfreq = (int *)calloc(nhash, sizeof (*hfreq));
188 	assert(hfreq != NULL);
189 	frtbl = fread(hfreq, sizeof (*hfreq), nhash, fa);
190 	hfrflg = (frtbl == nhash);
191 #if D1
192 	fprintf(stderr, "read freqs %d\n", frtbl);
193 #endif
194 
195 search:
196 	while (1) {
197 		nitem = getq(qitem);
198 		if (measure) tick();
199 		if (nitem == 0) continue;
200 		if (nitem < 0) break;
201 		if (tagout) tagout[0] = 0;
202 		if (fb != NULL) {
203 			nfound = doquery(hpt, nhash, fb, nitem, qitem, master);
204 #if D1
205 			fprintf(stderr, "after doquery nfound %d\n", nfound);
206 #endif
207 			fgnamp = fgnames;
208 			if (falseflg == 0)
209 				nfound = baddrop(master, nfound, fc,
210 				    nitem, qitem, rprog, full);
211 #if D1
212 			fprintf(stderr, "after baddrop nfound %d\n", nfound);
213 #endif
214 		}
215 		if (fgnamp > fgnames) {
216 			char **fgp, tgbuff[100];
217 			int k;
218 #if D1
219 			fprintf(stderr, "were %d bad files\n", fgnamp-fgnames);
220 #endif
221 			(void) memset(tgbuff, 0, sizeof (tgbuff));
222 			grepquery[0] = 0;
223 			for (k = 0; k < nitem; k++) {
224 				strcat(grepquery, " ");
225 				strcat(grepquery, qitem[k]);
226 			}
227 #if D1
228 			fprintf(stderr, "grepquery %s\n", grepquery);
229 #endif
230 			for (fgp = fgnames; fgp < fgnamp; fgp++) {
231 #if D1
232 				fprintf(stderr, "Now on %s query /%s/\n",
233 				    *fgp, grepquery);
234 #endif
235 				makefgrep(*fgp);
236 #if D1
237 				fprintf(stderr, "grepmade\n");
238 #endif
239 				if (tagout == 0)
240 					tagout = tgbuff;
241 				grepcall(grepquery, tagout, *fgp);
242 #if D1
243 				fprintf(stderr, "tagout now /%s/\n", tagout);
244 #endif
245 				if (full) {
246 					int nout;
247 					char *bout;
248 					char *tagp;
249 					char *oldtagp;
250 					tagp = tagout;
251 					while (*tagp) {
252 						oldtagp = tagp;
253 						while (*tagp &&
254 						    (*tagp != '\n'))
255 							tagp++;
256 						if (*tagp)
257 							tagp++;
258 						nout = findline(oldtagp, &bout,
259 						    1000, 0L);
260 						if (nout > 0) {
261 							fputs(bout, stdout);
262 							free(bout);
263 						}
264 					}
265 				}
266 			}
267 		}
268 		if (tags)
269 			result(master, nfound > tags ? tags : nfound, fc);
270 		if (measure) tock();
271 	}
272 	return (0);
273 }
274 
275 char *
276 todir(char *t)
277 {
278 	char *s;
279 	s = t;
280 	while (*s) s++;
281 	while (s >= t && *s != '/') s--;
282 	if (s < t)
283 		return (t);
284 	*s++ = 0;
285 	t = (*t ? t : "/");
286 	chdir(t);
287 	strcpy(usedir, t);
288 	return (s);
289 }
290 
291 static int
292 setfrom(char c)
293 {
294 	switch (c) {
295 	case 'y':
296 	case '\0':
297 	default:
298 		return (1000);
299 	case '1':
300 	case '2':
301 	case '3':
302 	case '4':
303 	case '5':
304 	case '6':
305 	case '7':
306 	case '8':
307 	case '9':
308 		return (c-'0');
309 	case 'n':
310 	case '0':
311 		return (0);
312 	}
313 }
314