home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / UUPC11XT.ZIP / RN / ARTSRCH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-21  |  9.7 KB  |  387 lines

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