home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume23
/
trn
/
part12
/
artsrch.c
next >
Wrap
C/C++ Source or Header
|
1991-08-22
|
8KB
|
348 lines
/* $Header: artsrch.c,v 4.3.3.1 90/07/21 20:13:13 davison Trn $
*
* $Log: artsrch.c,v $
* Revision 4.3.3.1 90/07/21 20:13:13 davison
* Initial Trn Release
*
* Revision 4.3.2.4 89/11/27 01:30:00 sob
* Altered NNTP code per ideas suggested by Bela Lubkin
* <filbo@gorn.santa-cruz.ca.us>
*
* Revision 4.3.2.3 89/11/26 22:54:37 sob
* Added new patches to make rrn faster.
*
* Revision 4.3.2.2 89/11/26 22:20:57 sob
* Added better NNTP support.
*
* Revision 4.3.2.1 89/11/26 22:13:10 sob
* Added support for NNTP
*
* Revision 4.3 85/05/01 11:35:47 lwall
* Baseline for release with 4.3bsd.
*
*/
#include "EXTERN.h"
#include "common.h"
#include "search.h"
#include "term.h"
#include "util.h"
#include "intrp.h"
#include "bits.h"
#include "kfile.h"
#include "head.h"
#include "final.h"
#include "cheat.h"
#ifdef SERVER
#include "server.h"
#endif
#include "ng.h"
#include "artio.h"
#ifdef USETHREADS
#include "rthreads.h"
#include "ngdata.h"
#endif
#include "INTERN.h"
#include "artsrch.h"
void
artsrch_init()
{
#ifdef ARTSEARCH
#ifdef ZEROGLOB
init_compex(&sub_compex);
init_compex(&art_compex);
#endif
#endif
}
/* search for an article containing some pattern */
#ifdef ARTSEARCH
int
art_search(patbuf,patbufsiz,get_cmd)
char *patbuf; /* if patbuf != buf, get_cmd must */
int patbufsiz;
int get_cmd; /* be set to FALSE!!! */
{
char *pattern; /* unparsed pattern */
register char cmdchr = *patbuf; /* what kind of search? */
register char *s;
bool backward = cmdchr == '?' || cmdchr == Ctl('p');
/* direction of search */
COMPEX *compex; /* which compiled expression */
char *cmdlst = Nullch; /* list of commands to do */
int normal_return = SRCH_NOTFOUND; /* assume no commands */
bool saltaway = FALSE; /* store in KILL file? */
char howmuch; /* search just the subjects */
bool doread; /* search read articles? */
bool foldcase = TRUE; /* fold upper and lower case? */
int_count = 0;
if (cmdchr == '/' || cmdchr == '?') { /* normal search? */
if (get_cmd && buf == patbuf)
if (!finish_command(FALSE)) /* get rest of command */
return SRCH_ABORT;
compex = &art_compex;
if (patbuf[1]) {
howmuch = 0;
doread = FALSE;
}
else {
howmuch = art_howmuch;
doread = art_doread;
}
s = cpytill(buf,patbuf+1,cmdchr);/* ok to cpy buf+1 to buf */
pattern = buf;
if (*pattern) {
if (*lastpat)
free(lastpat);
lastpat = savestr(pattern);
}
if (*s) { /* modifiers or commands? */
for (s++; *s && index("Kharc",*s); s++) {
if (*s == 'h') /* scan header */
howmuch = 1;
else if (*s == 'a') /* scan article */
howmuch = 2;
else if (*s == 'r') /* scan read articles */
doread = TRUE;
else if (*s == 'K') /* put into KILL file */
saltaway = TRUE;
else if (*s == 'c') /* make search case sensitive */
foldcase = FALSE;
}
}
while (isspace(*s) || *s == ':')
s++;
if (*s) {
if (*s == 'm' || *s == 'M')
doread = TRUE;
if (*s == 'k') /* grandfather clause */
*s = 'j';
cmdlst = savestr(s);
normal_return = SRCH_DONE;
}
art_howmuch = howmuch;
art_doread = doread;
if (srchahead)
srchahead = -1;
}
else {
register char *h;
howmuch = 0; /* just search subjects */
doread = (cmdchr == Ctl('p'));
if (cmdchr == Ctl('n'))
normal_return = SRCH_SUBJDONE;
compex = &sub_compex;
pattern = patbuf+1;
strcpy(pattern,": *");
h = pattern + strlen(pattern);
interp(h,patbufsiz - (h-patbuf),"%s"); /* fetch current subject */
if (cmdchr == 'K') {
saltaway = TRUE;
cmdchr = 'k';
}
if (cmdchr == 'k') {
normal_return = SRCH_DONE;
cmdlst = savestr("j");
mark_as_read(); /* this article has this subject */
if (!*h) {
#ifdef VERBOSE
IF(verbose)
fputs("\nCannot delete null subject.\n",stdout) FLUSH;
ELSE
#endif
#ifdef TERSE
fputs("\nNull subject.\n",stdout) FLUSH;
#endif
return SRCH_ABORT;
}
#ifdef VERBOSE
else if (verbose)
printf("\nMarking subject \"%s\" as read.\n",h) FLUSH;
#endif
}
else if (!srchahead)
srchahead = -1;
h[24] = '\0'; /* compensate for notesfiles */
while (*h) {
if (index("/\\[.^*$'\"",*h) != Nullch)
*h++ = '.';
else
h++;
}
#ifdef DEBUGGING
if (debug) {
printf("\npattern = %s\n",pattern) FLUSH;
}
#endif
}
if ((s = compile(compex,pattern,TRUE,foldcase)) != Nullch) {
/* compile regular expression */
printf("\n%s\n",s) FLUSH;
return SRCH_ABORT;
}
#ifdef KILLFILES
if (saltaway) {
char saltbuf[LBUFLEN];
s = saltbuf;
sprintf(s,"/%s/",pattern);
s += strlen(s);
if (doread)
*s++ = 'r';
if (howmuch==1)
*s++ = 'h';
else if (howmuch==2)
*s++ = 'a';
*s++ = ':';
if (!cmdlst)
cmdlst = savestr("j");
safecpy(s,cmdlst,LBUFLEN-(s-saltbuf));
kf_append(saltbuf);
}
#endif
if (cmdlst && index(cmdlst,'='))
normal_return = SRCH_ERROR; /* listing subjects is an error? */
if (get_cmd) {
fputs("\nSearching...\n",stdout) FLUSH;
/* give them something to read */
}
#ifdef USETHREADS
if (mode == 't') {
if (!cmdlst)
cmdlst = savestr("+"); /* thread selector's default command */
if (unread_selector)
doread = TRUE;
normal_return = SRCH_DONE;
}
#endif
if (backward) {
if (cmdlst && art <= lastart)
art++; /* include current article */
if (doread)
check_first(absfirst);
}
else {
if (art > lastart) {
art = (doread ? absfirst : firstart);
check_first(art--);
}
else if (cmdlst && art >= absfirst)
art--; /* include current article */
}
if (srchahead > 0) {
if (!backward)
art = srchahead - 1;
srchahead = -1;
}
assert(!cmdlst || *cmdlst);
perform_cnt = 0;
for (;;) {
if (backward ?
(--art < absfirst || (!doread && art < firstart)) :
(++art > lastart)
) { /* out of articles? */
if (cmdlst)
free(cmdlst);
return normal_return;
}
if (int_count) {
int_count = 0;
if (cmdlst)
free(cmdlst);
return SRCH_INTR;
}
/*NOSTRICT*/
if (doread || !was_read(art)) {
if (wanted(compex,art,howmuch)) {
/* does the shoe fit? */
if (cmdlst) {
if (perform(cmdlst,TRUE)) {
if (cmdlst)
free(cmdlst);
return SRCH_INTR;
}
}
else {
if (cmdlst)
free(cmdlst);
return SRCH_FOUND;
}
}
else if (!cmdlst && ! (art%50)) {
printf("...%ld",(long)art);
fflush(stdout);
}
}
}
}
/* determine if article fits pattern */
/* returns TRUE if it exists and fits pattern, FALSE otherwise */
bool
wanted(compex, artnum, scope)
COMPEX *compex;
ART_NUM artnum;
char scope;
{
if (!scope) {
char subj_buf[266];
#ifdef USETHREADS
if (ThreadedGroup)
find_article(art);
if (p_art) {
if (mode != 't')
strcpy(subj_buf, "Subject: ");
else
*subj_buf = '\0';
if (p_art->subject != -1)
strcat(subj_buf,subject_ptrs[p_art->subject]);
}
else
#endif
{
strcpy(subj_buf, "Subject: ");
strncpy(subj_buf+9,fetchsubj(artnum,FALSE,FALSE),256);
}
#ifdef DEBUGGING
if (debug & DEB_SEARCH_AHEAD)
printf("%s\n",subj_buf) FLUSH;
#endif
return execute(compex,subj_buf) != Nullch;
}
#ifdef CACHESUBJ
else
fetchsubj(artnum,FALSE,FALSE);/* might as well get subject handy */
#endif
#ifdef SERVER
if (scope == 1){
if (nntpopen(artnum,GET_HEADER) == Nullfp) /* we only need the header */
return FALSE;
}
else
#endif
if (artopen(artnum) == Nullfp) /* ensure that article is open */
return FALSE; /* if not, return NO MATCH */
scope--;
while (fgets(buf,LBUFLEN,artfp) != Nullch) {
/* for each line of article */
if (!scope && index(buf,':') == Nullch && *buf != ' ' && *buf != '\t')
/* if headers only and out of header */
return FALSE; /* say no go */
if (execute(compex,buf) != Nullch) {
/* does pattern matcher match? */
return TRUE; /* say Eureka */
}
}
return FALSE; /* out of article, so no match */
}
#endif