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