|
|
1.1 root 1: /* $Header: artsrch.c,v 4.3 85/05/01 11:35:47 lwall Exp $
2: *
3: * $Log: artsrch.c,v $
4: * Revision 4.3 85/05/01 11:35:47 lwall
5: * Baseline for release with 4.3bsd.
6: *
7: */
8:
9: #include "EXTERN.h"
10: #include "common.h"
11: #include "search.h"
12: #include "term.h"
13: #include "util.h"
14: #include "intrp.h"
15: #include "bits.h"
16: #include "kfile.h"
17: #include "head.h"
18: #include "final.h"
19: #include "cheat.h"
20: #include "ng.h"
21: #include "artio.h"
22: #include "INTERN.h"
23: #include "artsrch.h"
24:
25: void
26: artsrch_init()
27: {
28: #ifdef ARTSEARCH
29: #ifdef ZEROGLOB
30: init_compex(&sub_compex);
31: init_compex(&art_compex);
32: #endif
33: #endif
34: }
35:
36: /* search for an article containing some pattern */
37:
38: #ifdef ARTSEARCH
39: int
40: art_search(patbuf,patbufsiz,get_cmd)
41: char *patbuf; /* if patbuf != buf, get_cmd must */
42: int patbufsiz;
43: int get_cmd; /* be set to FALSE!!! */
44: {
45: char *pattern; /* unparsed pattern */
46: register char cmdchr = *patbuf; /* what kind of search? */
47: register char *s;
48: bool backward = cmdchr == '?' || cmdchr == Ctl('p');
49: /* direction of search */
50: COMPEX *compex; /* which compiled expression */
51: char *cmdlst = Nullch; /* list of commands to do */
52: int normal_return = SRCH_NOTFOUND; /* assume no commands */
53: bool saltaway = FALSE; /* store in KILL file? */
54: char howmuch; /* search just the subjects */
55: bool doread; /* search read articles? */
56: bool foldcase = TRUE; /* fold upper and lower case? */
57:
58: int_count = 0;
59: if (cmdchr == '/' || cmdchr == '?') { /* normal search? */
60: if (get_cmd && buf == patbuf)
61: if (!finish_command(FALSE)) /* get rest of command */
62: return SRCH_ABORT;
63: compex = &art_compex;
64: if (patbuf[1]) {
65: howmuch = 0;
66: doread = FALSE;
67: }
68: else {
69: howmuch = art_howmuch;
70: doread = art_doread;
71: }
72: s = cpytill(buf,patbuf+1,cmdchr);/* ok to cpy buf+1 to buf */
73: pattern = buf;
74: if (*pattern) {
75: if (*lastpat)
76: free(lastpat);
77: lastpat = savestr(pattern);
78: }
79: if (*s) { /* modifiers or commands? */
80: for (s++; *s && index("Kharc",*s); s++) {
81: if (*s == 'h') /* scan header */
82: howmuch = 1;
83: else if (*s == 'a') /* scan article */
84: howmuch = 2;
85: else if (*s == 'r') /* scan read articles */
86: doread = TRUE;
87: else if (*s == 'K') /* put into KILL file */
88: saltaway = TRUE;
89: else if (*s == 'c') /* make search case sensitive */
90: foldcase = FALSE;
91: }
92: }
93: while (isspace(*s) || *s == ':')
94: s++;
95: if (*s) {
96: if (*s == 'm' || *s == 'M')
97: doread = TRUE;
98: if (*s == 'k') /* grandfather clause */
99: *s = 'j';
100: cmdlst = savestr(s);
101: normal_return = SRCH_DONE;
102: }
103: art_howmuch = howmuch;
104: art_doread = doread;
105: if (srchahead)
106: srchahead = -1;
107: }
108: else {
109: register char *h;
110:
111: howmuch = 0; /* just search subjects */
112: doread = (cmdchr == Ctl('p'));
113: if (cmdchr == Ctl('n'))
114: normal_return = SRCH_SUBJDONE;
115: compex = &sub_compex;
116: pattern = patbuf+1;
117: strcpy(pattern,": *");
118: h = pattern + strlen(pattern);
119: interp(h,patbufsiz - (h-patbuf),"%s"); /* fetch current subject */
120: if (cmdchr == 'K') {
121: saltaway = TRUE;
122: cmdchr = 'k';
123: }
124: if (cmdchr == 'k') {
125: normal_return = SRCH_DONE;
126: cmdlst = savestr("j");
127: mark_as_read(art); /* this article has this subject */
128: if (!*h) {
129: #ifdef VERBOSE
130: IF(verbose)
131: fputs("\nCannot delete null subject.\n",stdout) FLUSH;
132: ELSE
133: #endif
134: #ifdef TERSE
135: fputs("\nNull subject.\n",stdout) FLUSH;
136: #endif
137: return SRCH_ABORT;
138: }
139: #ifdef VERBOSE
140: else if (verbose)
141: printf("\nMarking subject \"%s\" as read.\n",h) FLUSH;
142: #endif
143: }
144: else if (!srchahead)
145: srchahead = -1;
146: h[24] = '\0'; /* compensate for notesfiles */
147: while (*h) {
148: if (index("/\\[.^*$'\"",*h) != Nullch)
149: *h++ = '.';
150: else
151: h++;
152: }
153: #ifdef DEBUGGING
154: if (debug) {
155: printf("\npattern = %s\n",pattern) FLUSH;
156: }
157: #endif
158: }
159: if ((s = compile(compex,pattern,TRUE,foldcase)) != Nullch) {
160: /* compile regular expression */
161: printf("\n%s\n",s) FLUSH;
162: return SRCH_ABORT;
163: }
164: #ifdef KILLFILES
165: if (saltaway) {
166: char saltbuf[LBUFLEN];
167:
168: s = saltbuf;
169: sprintf(s,"/%s/",pattern);
170: s += strlen(s);
171: if (doread)
172: *s++ = 'r';
173: if (howmuch==1)
174: *s++ = 'h';
175: else if (howmuch==2)
176: *s++ = 'a';
177: *s++ = ':';
178: if (!cmdlst)
179: cmdlst = savestr("j");
180: safecpy(s,cmdlst,LBUFLEN-(s-saltbuf));
181: kf_append(saltbuf);
182: }
183: #endif
184: if (cmdlst && index(cmdlst,'='))
185: normal_return = SRCH_ERROR; /* listing subjects is an error? */
186: if (get_cmd) {
187: fputs("\nSearching...\n",stdout) FLUSH;
188: /* give them something to read */
189: }
190: if (backward) {
191: if (cmdlst && art < lastart)
192: art++; /* include current article */
193: if (doread)
194: check_first(absfirst);
195: }
196: else {
197: if (art > lastart)
198: art = (doread ? absfirst : firstart) - 1;
199: else if (cmdlst && art > absfirst)
200: art--; /* include current article */
201: check_first(art);
202: }
203: if (srchahead > 0) {
204: if (!backward)
205: art = srchahead - 1;
206: srchahead = -1;
207: }
208: assert(!cmdlst || *cmdlst);
209: for (;;) {
210: if (int_count) {
211: int_count = 0;
212: if (cmdlst)
213: free(cmdlst);
214: return SRCH_INTR;
215: }
216: if (backward ?
217: (--art < absfirst || (!doread && art < firstart)) :
218: (++art > lastart)
219: ) { /* out of articles? */
220: if (cmdlst)
221: free(cmdlst);
222: return normal_return;
223: }
224: /*NOSTRICT*/
225: if (doread || !was_read(art)) {
226: if (wanted(compex,art,howmuch)) {
227: /* does the shoe fit? */
228: if (cmdlst) {
229: if (perform(cmdlst,TRUE)) {
230: if (cmdlst)
231: free(cmdlst);
232: return SRCH_INTR;
233: }
234: }
235: else {
236: if (cmdlst)
237: free(cmdlst);
238: return SRCH_FOUND;
239: }
240: }
241: else if (!cmdlst && ! (art%50)) {
242: printf("...%ld",(long)art);
243: fflush(stdout);
244: }
245: }
246: }
247: }
248:
249: /* determine if article fits pattern */
250: /* returns TRUE if it exists and fits pattern, FALSE otherwise */
251:
252: bool
253: wanted(compex, artnum, scope)
254: COMPEX *compex;
255: ART_NUM artnum;
256: char scope;
257: {
258: if (!scope) {
259: char subj_buf[266];
260:
261: strcpy(subj_buf, "Subject: ");
262: strncpy(subj_buf+9,fetchsubj(artnum,FALSE,FALSE),256);
263: #ifdef DEBUGGING
264: if (debug & DEB_SEARCH_AHEAD)
265: printf("%s\n",subj_buf) FLUSH;
266: #endif
267: return execute(compex,subj_buf) != Nullch;
268: }
269: #ifdef CACHESUBJ
270: else
271: fetchsubj(artnum,FALSE,FALSE);/* might as well get subject handy */
272: #endif
273:
274: if (artopen(artnum) == Nullfp) /* ensure that article is open */
275: return FALSE; /* if not, return NO MATCH */
276: scope--;
277: while (fgets(buf,LBUFLEN,artfp) != Nullch) {
278: /* for each line of article */
279: if (!scope && index(buf,':') == Nullch && *buf != ' ' && *buf != '\t')
280: /* if headers only and out of header */
281: return FALSE; /* say no go */
282: if (execute(compex,buf) != Nullch) {
283: /* does pattern matcher match? */
284: return TRUE; /* say Eureka */
285: }
286: }
287: return FALSE; /* out of article, so no match */
288: }
289: #endif
290:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.