home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / trn_12.zip / src / artsrch.c < prev    next >
C/C++ Source or Header  |  1993-12-04  |  9KB  |  358 lines

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