home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / trn / part12 / artsrch.c next >
C/C++ Source or Header  |  1991-08-22  |  8KB  |  348 lines

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