home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / com / utils / elm / sources / pattern.c < prev    next >
C/C++ Source or Header  |  1992-02-01  |  7KB  |  256 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: pattern.c,v 4.1 90/04/28 22:43:42 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    pattern.c,v $
  17.  * Revision 4.1  90/04/28  22:43:42  syd
  18.  * checkin of Elm 2.3 as of Release PL0
  19.  *
  20.  *
  21.  ******************************************************************************/
  22.  
  23. /**    General pattern matching for the ELM mailer.
  24.  
  25. **/
  26.  
  27. #include <errno.h>
  28.  
  29. #include "headers.h"
  30.  
  31. static char pattern[SLEN] = { "" };
  32. static char alt_pattern[SLEN] = { "" };
  33.  
  34. #ifndef OS2
  35. extern int errno;
  36. #endif
  37.  
  38. char *error_name(), *shift_lower(), *strcpy();
  39.  
  40. int
  41. meta_match(function)
  42. int function;
  43. {
  44.     char    ch;
  45.  
  46.     /** Perform specific function based on whether an entered string
  47.         matches either the From or Subject lines..
  48.         Return TRUE if the current message was matched, else FALSE.
  49.     **/
  50.  
  51.     register int i, tagged=0, count=0, curtag = 0;
  52.     static char     meta_pattern[SLEN];
  53.  
  54.     PutLine1(LINES-3, strlen("Command: "),
  55.          "%s messages that match pattern...",
  56.          function==TAGGED?"Tag": function==DELETED?"Delete":"Undelete");
  57.  
  58.     if (function == TAGGED) {    /* are messages already tagged??? */
  59.       for (i=0; i < message_count; i++)
  60.         if (ison(headers[i]->status,TAGGED))
  61.           tagged++;
  62.  
  63.       if (tagged) {
  64.         if (tagged > 2)
  65.           PutLine0(LINES-2,0, "Some messages are already tagged.");
  66.         else
  67.           PutLine0(LINES-2,0, "A message is already tagged.");
  68.  
  69.         Write_to_screen("Remove tag%s? y%c", 2, plural(tagged),BACKSPACE);
  70.  
  71.         ch = ReadCh();
  72.         if (tolower(ch) != 'n') {    /* remove tags... */
  73.           Write_to_screen("Yes.", 0);
  74.           for (i=0; i < message_count; i++) {
  75.             clearit(headers[i]->status,TAGGED);
  76.         show_new_status(i);
  77.           }
  78.         } else
  79.           Write_to_screen("No.", 0);
  80.       }
  81.     }
  82.  
  83.     PutLine0(LINES-2,0, "Enter pattern: "); CleartoEOLN();
  84.  
  85.     optionally_enter(meta_pattern, LINES-2, strlen("Enter pattern: "),
  86.       FALSE, FALSE);
  87.  
  88.     if (strlen(meta_pattern) == 0) {
  89.       ClearLine(LINES-2);
  90.       return(curtag);
  91.     }
  92.  
  93.     strcpy(meta_pattern, shift_lower(meta_pattern));   /* lowercase it */
  94.  
  95.     for (i = 0; i < message_count; i++) {
  96.       if (from_matches(i, meta_pattern)) {
  97.         if ((selected && headers[i]->status & VISIBLE) || ! selected) {
  98.           if (function == UNDELETE)
  99.             clearit(headers[i]->status, DELETED);
  100.           else
  101.             setit(headers[i]->status, function);
  102.           show_new_status(i);
  103.           if(i == current - 1) curtag++;
  104.           count++;
  105.         }
  106.       }
  107.       else if (subject_matches(i, meta_pattern)) {
  108.         if ((selected && headers[i]->status & VISIBLE) || ! selected) {
  109.           if (function == UNDELETE)
  110.             clearit(headers[i]->status, DELETED);
  111.           else
  112.             setit(headers[i]->status, function);
  113.           show_new_status(i);
  114.           if(i == current - 1) curtag++;
  115.           count++;
  116.         }
  117.       }
  118.     }
  119.  
  120.     ClearLine(LINES-2);    /* remove "pattern: " prompt */
  121.  
  122.     if (count > 0)
  123.       error3("%s %d messsage%s.",
  124.              function==TAGGED? "Tagged" :
  125.            function==DELETED? "Marked for deletion" : "Undeleted",
  126.          count, plural(count));
  127.     else
  128.       error1("No matches. No messages %s.",
  129.          function==TAGGED? "tagged" :
  130.            function==DELETED? "marked for deletion": "undeleted");
  131.  
  132.     return(curtag);
  133. }
  134.  
  135. int
  136. pattern_match()
  137. {
  138.     /** Get a pattern from the user and try to match it with the
  139.         from/subject lines being displayed.  If matched (ignoring
  140.         case), move current message pointer to that message, if
  141.         not, error and return ZERO **/
  142.  
  143.     register int i;
  144.  
  145.     PutLine0(LINES-3,40,"/ = Match anywhere in messages.");
  146.  
  147.     PutLine0(LINES-1,0, "Match pattern:");
  148.  
  149.     if (pattern_enter(pattern, alt_pattern, LINES-1, 16,
  150.         "Match pattern (in entire folder):"))
  151.       if (strlen(alt_pattern) > 0) {
  152.         strcpy(alt_pattern, shift_lower(alt_pattern));
  153.         return(match_in_message(alt_pattern));
  154.       }
  155.       else
  156.         return(1);
  157.  
  158.     if (strlen(pattern) == 0)
  159.       return(0);
  160.     else
  161.       strcpy(pattern, shift_lower(pattern));
  162.  
  163.     for (i = current; i < message_count; i++) {
  164.       if (from_matches(i, pattern)) {
  165.         if (!selected || (selected && headers[i]->status & VISIBLE)) {
  166.           current = ++i;
  167.           return(1);
  168.         }
  169.       }
  170.       else if (subject_matches(i, pattern)) {
  171.         if (!selected || (selected && headers[i]->status & VISIBLE)) {
  172.           current = ++i;
  173.           return(1);
  174.         }
  175.       }
  176.     }
  177.  
  178.     return(0);
  179. }
  180.  
  181. int
  182. from_matches(message_number, pat)
  183. int message_number;
  184. char *pat;
  185. {
  186.     /** Returns true iff the pattern occurs in it's entirety
  187.         in the from line of the indicated message **/
  188.  
  189.     return( in_string(shift_lower(headers[message_number]->from),
  190.         pat) );
  191. }
  192.  
  193. int
  194. subject_matches(message_number, pat)
  195. int message_number;
  196. char *pat;
  197. {
  198.     /** Returns true iff the pattern occurs in it's entirety
  199.         in the subject line of the indicated message **/
  200.  
  201.     return( in_string(shift_lower(headers[message_number]->subject),
  202.         pat) );
  203. }
  204.  
  205. match_in_message(pat)
  206. char *pat;
  207. {
  208.     /** Match a string INSIDE a message...starting at the current
  209.         message read each line and try to find the pattern.  As
  210.         soon as we do, set current and leave!
  211.         Returns 1 if found, 0 if not
  212.     **/
  213.  
  214.     char buffer[LONG_STRING];
  215.     int  message_number, lines, line;
  216.  
  217.     message_number = current-1;
  218.  
  219.     error("Searching folder for pattern...");
  220.  
  221.     while (message_number < message_count) {
  222.  
  223.       if (fseek(mailfile, headers[message_number]->offset, 0) == -1) {
  224.  
  225.         dprint(1, (debugfile,
  226.         "Error: seek %ld bytes into file failed. errno %d (%s)\n",
  227.         headers[message_number]->offset, errno,
  228.         "match_in_message"));
  229.         error2("ELM [match] failed looking %ld bytes into file (%s).",
  230.            headers[message_number]->offset, error_name(errno));
  231.         return(1);    /* fake it out to avoid replacing error message */
  232.       }
  233.  
  234.       line = 0;
  235.       lines = headers[message_number]->lines;
  236.  
  237.       while (fgets(buffer, LONG_STRING, mailfile) != NULL && line < lines) {
  238.  
  239.         if(buffer[strlen(buffer)-1] == '\n') line++;
  240.  
  241.         if (in_string(shift_lower(buffer), pat)) {
  242.           current = message_number+1;
  243.           clear_error();
  244.           return(1);
  245.         }
  246.       }
  247.  
  248.       /** now we've passed the end of THIS message...increment and
  249.           continue the search with the next message! **/
  250.  
  251.       message_number++;
  252.     }
  253.  
  254.     return(0);
  255. }
  256.