/[imapfilter]/imapfilter/request.c
ViewVC logotype

Diff of /imapfilter/request.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by lefcha, Tue Sep 11 16:13:51 2001 UTC revision 1.3 by lefcha, Sun Sep 30 20:23:37 2001 UTC
# Line 1  Line 1 
1  #include <stdio.h>  #include <stdio.h>
2  #include <stdlib.h>  #include <stdlib.h>
3  #include <string.h>  #include <string.h>
4    #include <errno.h>
5    
6  #include "config.h"  #include "config.h"
7  #include "imapfilter.h"  #include "imapfilter.h"
# Line 9  Line 10 
10    
11  extern unsigned int options;  extern unsigned int options;
12    
13    
14  #ifdef DEBUG  #ifdef DEBUG
15  /*  /*
16   * Test/ping server.   * Test/ping server.
# Line 16  extern unsigned int options; Line 18  extern unsigned int options;
18  int test(void)  int test(void)
19  {  {
20      imap_noop();      imap_noop();
21      return server_response();      return server_response("NOOP");
22  }  }
23  #endif  #endif
24    
# Line 26  int test(void) Line 28  int test(void)
28  int login(char *user, char *pass)  int login(char *user, char *pass)
29  {  {
30      imap_login(user, pass);      imap_login(user, pass);
31      return server_response();      return server_response("LOGIN");
32  }  }
33    
34    
35  /*  /*
36   * Open mailbox in read-only mode and print information about it's status.   * Open mailbox in read-write mode.
37   */   */
38  int examine_mailbox(char *mbox)  int select_mailbox(char *mbox)
39  {  {
40      int r;      int r;
   
     imap_examine(mbox);  
     r = server_response();  
41            
42      if (!(options & OPTION_DETAILS_QUITE) && !r) {      imap_select(mbox);
43          imap_status(mbox, "MESSAGES RECENT UNSEEN");      r = server_response("SELECT");
44          status_response();      
45          info("at %s.\n", mbox);      if (!r)
46      }          mailbox_status(mbox);
47        
48        log_info(2, mbox);
49        
50      return r;      return r;
51  }  }
52    
53    
54  /*  /*
55   * Open mailbox in read-write mode.   * Get mailbox's status.
56   */   */
57  int select_mailbox(char *mbox)  int mailbox_status(char *mbox)
58  {  {
59      imap_select(mbox);      int r = 0;
60      return server_response();      
61        if (!(options & OPTION_DETAILS_QUITE)) {
62            imap_status(mbox, "MESSAGES RECENT UNSEEN");
63            r = status_response();
64            info(" in mailbox %s.\n", mbox);
65        }
66        
67        return r;
68  }  }
   
   
69  /*  /*
70   * Close examined/selected mailbox.   * Close examined/selected mailbox.
71   */   */
72  int close_mailbox(void)  int close_mailbox(void)
73  {  {
74      imap_close();      imap_close();
75      return server_response();      return server_response("CLOSE");
76  }  }
77    
78    
# Line 76  int close_mailbox(void) Line 82  int close_mailbox(void)
82  int logout(void)  int logout(void)
83  {  {
84      imap_logout();      imap_logout();
85      return server_response();      return server_response("LOGOUT");
86  }  }
87    
88    
# Line 85  int logout(void) Line 91  int logout(void)
91   */   */
92  int apply_filters(filter_t ** filters, char *mbox)  int apply_filters(filter_t ** filters, char *mbox)
93  {  {
94      int i, ro;      int i;
95      char mesgs[SEARCH_MESSAGES_BUF];      char mesgs[SEARCH_MESSAGES_BUF];
96    
     ro = 1;  
   
97      for (i = 0; filters[i]; i++) {      for (i = 0; filters[i]; i++) {
98    
99          mesgs[0] = 0;          mesgs[0] = 0;
# Line 97  int apply_filters(filter_t ** filters, c Line 101  int apply_filters(filter_t ** filters, c
101          if (match_filter(filters[i], mesgs))          if (match_filter(filters[i], mesgs))
102              continue;              continue;
103    
104          if (ro) {          apply_action(mesgs, &(filters[i]->action.type),
105              close_mailbox();                       filters[i]->action.destmbox, filters[i]->action.args);
             select_mailbox(mbox);  
         } else  
             ro = 0;  
   
         apply_action(mesgs, filters[i]->action.type, filters[i]->action.args);  
106      }      }
107    
108      return 0;      return 0;
# Line 116  int apply_filters(filter_t ** filters, c Line 115  int apply_filters(filter_t ** filters, c
115   */   */
116  int match_filter(filter_t * filter, char *mesgs)  int match_filter(filter_t * filter, char *mesgs)
117  {  {
118      char search[SEARCH_BUF];    /* Search string generated. */      char *search;
119      
     search[0] = 0;  
   
120      if (filter->mode == FILTER_MODE_OR)      if (filter->mode == FILTER_MODE_OR)
121          generate_filter_or(search, filter->masks);          search = generate_filter_or(filter->masks, filter->masknum, filter->masklen);
122      else      else
123          generate_filter_and(search, filter->masks);          search = generate_filter_and(filter->masks, filter->masknum, filter->masklen);
124    
125      if (imap_search(search) || search_response(mesgs) || !mesgs[0])      imap_search(search);
126        search_response(mesgs);
127        
128        free(search);
129        
130        if (!*mesgs)
131          return 1;          return 1;
132            
133      return 0;      return 0;
134  }  }
135    
# Line 139  void empty_fifo(mask_t ** mfifo) Line 141  void empty_fifo(mask_t ** mfifo)
141  {  {
142      mfifo[0] = NULL;      mfifo[0] = NULL;
143    
144      to_fifo(NULL, NULL);      queue_fifo(NULL, NULL);
145      from_fifo(NULL);      dequeue_fifo(NULL);
146  }  }
147    
148    
149  /*  /*
150   * Add item to FIFO inventory.   * Add item to FIFO inventory.
151   */   */
152  void to_fifo(mask_t ** mfifo, mask_t * mask)  void queue_fifo(mask_t ** mfifo, mask_t * mask)
153  {  {
154      static int i;      static int i;
155    
# Line 164  void to_fifo(mask_t ** mfifo, mask_t * m Line 166  void to_fifo(mask_t ** mfifo, mask_t * m
166  /*  /*
167   * Get next item from FIFO inventory.   * Get next item from FIFO inventory.
168   */   */
169  mask_t *from_fifo(mask_t ** mfifo)  mask_t *dequeue_fifo(mask_t ** mfifo)
170  {  {
171      static int j;      static int j;
172    
# Line 181  mask_t *from_fifo(mask_t ** mfifo) Line 183  mask_t *from_fifo(mask_t ** mfifo)
183   * Generate the filter search command from the masks, assuming that   * Generate the filter search command from the masks, assuming that
184   * masks are AND-ed.   * masks are AND-ed.
185   */   */
186  void generate_filter_and(char *search, mask_t * mask)  char *generate_filter_and(mask_t * mask, unsigned int masknum, unsigned int masklen)
187  {  {
188        const unsigned int searchbuf = masklen + masknum * 6 + 8;
189      int len = 0;      int len = 0;
190      mask_t *mfifo[FIFO_MAX];    /* Mailbox FIFO queue. */      char *search;
191        mask_t **mfifo;             /* Mailbox FIFO queue. */
192      mask_t *mf;                 /* Mask returned from FIFO. */      mask_t *mf;                 /* Mask returned from FIFO. */
193        
194        search = (char *) malloc(sizeof(char) * searchbuf);
195        mfifo = (mask_t **) malloc(sizeof(mask_t *) * (masknum + 1));
196        
197        if (!search || !mfifo)
198            fatal(ERROR_MEMORY_ALLOCATION, "imapfilter: allocating memory; %s\n",
199                  strerror(errno));
200        
201        search[0] = 0;
202      empty_fifo(mfifo);      empty_fifo(mfifo);
203    
204      strncat(search, "ALL ", SEARCH_BUF - len - 1);      strncat(search, "ALL ", searchbuf - len - 1);
205      len += 5;      len += 4;
206    
207      while (mask) {      while (mask) {
208          if (mask->type == MASK_TYPE_OR) {          if (mask->type == MASK_TYPE_OR) {
209    
210              if (len == 5 && strstr(search, "ALL ")) {              if (len == 4 && search[0] == 'A')
211                  search[0] = 0;                  search[0] = len = 0;
                 len = 0;  
             }  
212    
213              strncat(search, "OR (", SEARCH_BUF - len - 1);              strncat(search, "OR (", searchbuf - len - 1);
214              len += 4;              len += 4;
215    
216              while ((mf = from_fifo(mfifo))) {              while ((mf = dequeue_fifo(mfifo))) {
217                  strncat(search, mf->body, SEARCH_BUF - len - 1);                  strncat(search, mf->body, searchbuf - len - 1);
218                  len = strlen(search);                  len = strlen(search);
219                  search[len++] = ' ';                  search[len] = ' ';
220                  search[len] = 0;                  search[++len] = 0;
221              }              }
222    
223              empty_fifo(mfifo);              empty_fifo(mfifo);
224                
225              strncpy(search + len - 1, ") ", SEARCH_BUF - len - 1);              search[len - 1] = ')';
226              len += 2;              search[len] = ' ';
227                search[++len] = 0;
228          }          }
229    
230          to_fifo(mfifo, mask);          queue_fifo(mfifo, mask);
231    
232          mask = mask->next;          mask = mask->next;
233      }      }
234    
235      search[len - 1] = '(';      if (search[0] != 'A') {
236      search[len] = 0;          search[len] = '(';
237            search[++len] = 0;
238        }
239    
240      while ((mf = from_fifo(mfifo))) {      while ((mf = dequeue_fifo(mfifo))) {
241          strncat(search, mf->body, SEARCH_BUF - len - 1);          strncat(search, mf->body, searchbuf - len - 1);
242          len = strlen(search);          len = strlen(search);
243          search[len++] = ' ';          search[len] = ' ';
244          search[len] = 0;          search[++len] = 0;
245      }      }
246        
247      if (strchr(search, '(')) {      if (strchr(search, '(')) {
248          search[len - 1] = ')';          search[len - 1] = ')';
249          search[len] = 0;          search[len] = 0;
250      }      }
251    
252        if (search[len - 1] == ' ')
253            search[len - 1] = 0;
254        
255        return search;
256  }  }
257    
258    
# Line 242  void generate_filter_and(char *search, m Line 260  void generate_filter_and(char *search, m
260   * Generate the filter search command from the masks, assuming that   * Generate the filter search command from the masks, assuming that
261   * masks are OR-ed   * masks are OR-ed
262   */   */
263  void generate_filter_or(char *search, mask_t * mask)  char *generate_filter_or(mask_t * mask, unsigned int masknum, unsigned int masklen)
264  {  {
265        const unsigned int searchbuf = masklen + masknum * 6 + 8;
266      int len = 0;      int len = 0;
267      mask_t *mfifo[FIFO_MAX];    /* Mailbox FIFO queue. */      char *search;
268        mask_t **mfifo;             /* Mailbox FIFO queue. */
269      mask_t *mf;                 /* Mask returned from FIFO. */      mask_t *mf;                 /* Mask returned from FIFO. */
270        
271        search = (char *) malloc(sizeof(char) * searchbuf);
272        mfifo = (mask_t **) malloc(sizeof(mask_t *) * (masknum + 1));
273        
274        if (!search || !mfifo)
275            fatal(ERROR_MEMORY_ALLOCATION, "imapfilter: allocating memory; %s\n",
276                  strerror(errno));
277    
278        search[0] = 0;
279      empty_fifo(mfifo);      empty_fifo(mfifo);
280    
281      strncat(search, "ALL ", SEARCH_BUF - len - 1);      strncat(search, "ALL ", searchbuf - len - 1);
282      len += 4;      len += 4;
283    
284      while (mask) {      while (mask) {
285          to_fifo(mfifo, mask);          queue_fifo(mfifo, mask);
286          mask = mask->next;          mask = mask->next;
287    
288          while (mask && mask->type == MASK_TYPE_AND) {          while (mask && mask->type == MASK_TYPE_AND) {
289              to_fifo(mfifo, mask);              queue_fifo(mfifo, mask);
290              mask = mask->next;              mask = mask->next;
291          }          }
292    
293          if (mask) {          if (mask) {
294              if (len == 4 && strstr(search, "ALL ")) {              if (len == 4 && search[0] == 'A')
295                  search[0] = 0;                  search[0] = len = 0;
296                  len = 0;              
297              }              strncat(search, "OR ", searchbuf - len - 1);
             strncat(search, "OR ", SEARCH_BUF - len - 1);  
298              len += 3;              len += 3;
299          }          }
300    
301          search[len++] = '(';          if (search[0] != 'A') {
302          search[len] = 0;              search[len] = '(';
303                search[++len] = 0;
304            }
305    
306          while ((mf = from_fifo(mfifo))) {          while ((mf = dequeue_fifo(mfifo))) {
307              strncat(search, mf->body, SEARCH_BUF - len - 1);              strncat(search, mf->body, searchbuf - len - 1);
308              len = strlen(search);              len = strlen(search);
309              search[len++] = ' ';              search[len] = ' ';
310              search[len] = 0;              search[++len] = 0;
311          }          }
312    
313          strncpy(search + len - 1, ") ", SEARCH_BUF - len - 1);          if (strchr(search, '(')) {
314          len++;              search[len - 1] = ')';
315                search[len] = ' ';
316                search[++len] = 0;
317            }
318    
319          empty_fifo(mfifo);          empty_fifo(mfifo);
320      }      }
321    
322      search[len - 1] = 0;      search[len - 1] = 0;
323    
324        return search;
325  }  }
326    
327    
328  /*  /*
329   * Apply the appropriate action.   * Apply the appropriate action.
330   */   */
331  int apply_action(char *mesgs, unsigned int type, char *args)  int apply_action(char *mesgs, unsigned int *type, char *destmbox, char *args)
332  {  {
333      unsigned int num;      unsigned int cnt;
334            
335      if (!mesgs[0])      if (!*mesgs)
336          return 0;          return 0;
337        
338      num = convert_messages(mesgs);      log_info(3, type);
339        log_info(4, destmbox);
340      switch (type) {      
341        cnt = convert_messages(mesgs);
342        
343        switch (*type) {
344      case FILTER_ACTION_DELETE:      case FILTER_ACTION_DELETE:
345            info("%d messages deleted.\n", cnt);
346          action_delete(mesgs, args);          action_delete(mesgs, args);
         info("%d messages deleted.\n", num);  
347          break;          break;
348      case FILTER_ACTION_COPY:      case FILTER_ACTION_COPY:
349          action_copy(mesgs, args);          info("%d messages copied to mailbox %s.\n", cnt, destmbox);
350          info("%d messages copied to mailbox %s.\n", num, args);          action_copy(mesgs, destmbox, args);
351          break;          break;
352      case FILTER_ACTION_MOVE:      case FILTER_ACTION_MOVE:
353          action_move(mesgs, args);          info("%d messages moved to mailbox %s.\n", cnt, destmbox);
354          info("%d messages moved to mailbox %s.\n", num, args);          action_move(mesgs, destmbox, args);
355          break;          break;
356      case FILTER_ACTION_LIST:      case FILTER_ACTION_LIST:
357            info("%d messages listed.\n", cnt);
358          action_list(mesgs, args);          action_list(mesgs, args);
359          break;          break;
360      }      }
361        
362        if(!*args)
363            log_info(0, NULL);
364        
365      return 0;      return 0;
366  }  }
367    
# Line 331  int apply_action(char *mesgs, unsigned i Line 372  int apply_action(char *mesgs, unsigned i
372  int action_delete(char *mesgs, char *args)  int action_delete(char *mesgs, char *args)
373  {  {
374      const char *delim = " ";      const char *delim = " ";
375      char *tok, *cp;      char *tok, *mcp, *m, *acp, *occur;
     char headers[HEADERS_BUF];  
376    
377      cp = strdup(mesgs);      m = mcp = strdup(mesgs);
378        acp = strdup(args);
379        
380        while((occur = strchr(acp, ',')))
381            *occur = ' ';
382    
383      while ((tok = strsep(&cp, delim))) {      while ((tok = strsep(&m, delim))) {
384          if (*args) {          if (*args) {
385              imap_fetch(tok, args);              imap_fetch(0, tok, acp);
386              fetch_response(headers);              fetch_response();
             log_info(headers);  
387          }          }
388          imap_store(tok, "\\Deleted");          imap_store(tok, "\\Deleted");
389          server_response();          server_response("STORE");
390      }      }
391        
392      free(cp);      free(mcp);
393    
394      return 0;      return 0;
395  }  }
# Line 355  int action_delete(char *mesgs, char *arg Line 398  int action_delete(char *mesgs, char *arg
398  /*  /*
399   * Copy messages to specified mailbox.   * Copy messages to specified mailbox.
400   */   */
401  int action_copy(char *mesgs, char *mbox)  int action_copy(char *mesgs, char *destmbox, char *args)
402  {  {
403      const char *delim = " ";      const char *delim = " ";
404      char *tok, *cp;      char *tok, *mcp, *m, *acp, *occur;
405    
406      cp = strdup(mesgs);      m = mcp = strdup(mesgs);
407        acp = strdup(args);
408        
409        while ((occur = strchr(acp, ',')))
410            *occur = ' ';
411    
412      while ((tok = strsep(&cp, delim))) {      while ((tok = strsep(&m, delim))) {
413          imap_copy(tok, mbox);          if (acp) {
414                imap_fetch(1, tok, acp);
415                fetch_response();
416            }
417    
418            imap_copy(tok, destmbox);
419          if (copy_response() == 1) {          if (copy_response() == 1) {
420              imap_create(mbox);              imap_create(destmbox);
421              if (!server_response()) {              if (!server_response("CREATE")) {
422                  imap_copy(tok, mbox);                  imap_copy(tok, destmbox);
423                  copy_response();                  copy_response();
424              }              }
425          }          }
426      }      }
427    
428      free(cp);      free(mcp);
429        free(acp);
430    
431      return 0;      return 0;
432  }  }
# Line 382  int action_copy(char *mesgs, char *mbox) Line 435  int action_copy(char *mesgs, char *mbox)
435  /*  /*
436   * Move messages to specified mailbox.   * Move messages to specified mailbox.
437   */   */
438  int action_move(char *mesgs, char *mbox)  int action_move(char *mesgs, char *destmbox, char *args)
439  {  {
440      action_copy(mesgs, mbox);      action_copy(mesgs, destmbox, args);
441      action_delete(mesgs, "\0");      action_delete(mesgs, "\0");
442      imap_expunge();      imap_expunge();
443      server_response();      server_response("EXPUNGE");
444    
445      return 0;      return 0;
446  }  }
# Line 399  int action_move(char *mesgs, char *mbox) Line 452  int action_move(char *mesgs, char *mbox)
452  int action_list(char *mesgs, char *args)  int action_list(char *mesgs, char *args)
453  {  {
454      const char *delim = " ";      const char *delim = " ";
455      char *tok, *cp, *occur;      char *tok, *mcp, *m, *occur;
     char headers[HEADERS_BUF];  
456            
457      if (!*args)      if (!*args)
458          return 0;          return 0;
# Line 408  int action_list(char *mesgs, char *args) Line 460  int action_list(char *mesgs, char *args)
460      while ((occur = strchr(args, ',')))      while ((occur = strchr(args, ',')))
461          *occur = ' ';          *occur = ' ';
462    
463      cp = strdup(mesgs);      m = mcp = strdup(mesgs);
464    
465      while ((tok = strsep(&cp, delim))) {      while ((tok = strsep(&m, delim))) {
466          imap_fetch(tok, args);          imap_fetch(1, tok, args);
467          fetch_response(headers);          fetch_response();
         info(headers);  
468      }      }
469    
470      free(cp);      free(mcp);
471    
472      return 0;      return 0;
473  }  }
# Line 428  int action_list(char *mesgs, char *args) Line 479  int action_list(char *mesgs, char *args)
479   */   */
480  unsigned int convert_messages(char *mesgs)  unsigned int convert_messages(char *mesgs)
481  {  {
482      unsigned int num, len;      unsigned int cnt, len;
483      unsigned int start, end, tmp;      unsigned int start, end, tmp;
484      char *cp, *tail = NULL;      char *cp, *tail = NULL;
485            
486      num = len = start = end = tmp = 0;      cnt = len = start = end = tmp = 0;
487    
488      cp = strdup(mesgs);      cp = strdup(mesgs);
489    
490      start = (unsigned int) strtoul(cp, &tail, 0);      start = (unsigned int) strtoul(cp, &tail, 0);
491      num++;      cnt++;
492      end = start;      end = start;
493    
494      do {      do {
495          if (tail) {          if (tail) {
496              tmp = (unsigned int) strtoul(tail, &tail, 0);              tmp = (unsigned int) strtoul(tail, &tail, 0);
497              if (tmp)              if (tmp)
498                  num++;                  cnt++;
499          }          }
500    
501          if (tmp == end + 1)          if (tmp == end + 1)
# Line 466  unsigned int convert_messages(char *mesg Line 517  unsigned int convert_messages(char *mesg
517    
518      free(cp);      free(cp);
519            
520      return num;      return cnt;
521  }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26