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

Diff of /imapfilter/action.c

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

revision 1.16 by lefcha, Sat Feb 14 22:48:04 2004 UTC revision 1.17 by lefcha, Sun Feb 15 15:32:38 2004 UTC
# Line 24  int action_list(char *mesgs, char *args) Line 24  int action_list(char *mesgs, char *args)
24  unsigned int count_messages(char *mesgs);  unsigned int count_messages(char *mesgs);
25  char *convert_messages(char *mesgs);  char *convert_messages(char *mesgs);
26  int substitute_date(char *str);  int substitute_date(char *str);
27  void current_date(char *destmbox);  void system_date(char *destmbox);
28  void message_date(char *mesg, char *destmbox);  void message_date(char *mesg, char *destmbox);
29  void default_variables(char *mbox, char *destmbox);  void default_variables(char *mbox, char *destmbox);
30    void headers_variables(char *mesg, char *destmbox);
31    
32    
33  /*  /*
# Line 136  action_copy(char *mbox, char *mesgs, cha Line 137  action_copy(char *mbox, char *mesgs, cha
137    
138          r = 0;          r = 0;
139          tok = NULL;          tok = NULL;
140            *dm[0] = *dm[1] = '\0';
141    
142          action_list(mesgs, args);          action_list(mesgs, args);
143    
144          if (strchr(destmbox, '@'))          if (strchr(destmbox, '@') || strchr(destmbox, '&'))
145                  m = mcp = xstrdup(mesgs);                  m = mcp = xstrdup(mesgs);
146          else          else
147                  m = mcp = convert_messages(mesgs);                  m = mcp = convert_messages(mesgs);
148    
149          xstrncpy(dm[0], destmbox, MBOX_LEN - 1);          xstrncpy(dm[0], destmbox, MBOX_LEN - 1);
150          default_variables(mbox, dm[0]);          default_variables(mbox, dm[0]);
151          current_date(dm[0]);          system_date(dm[0]);
152          tok = strtok_r(m, " ", &m);          tok = strtok_r(m, " ", &m);
153          while (tok != NULL) {          while (tok != NULL) {
154                  xstrncpy(dm[1], dm[0], MBOX_LEN - 1);                  xstrncpy(dm[1], dm[0], MBOX_LEN - 1);
155                  message_date(tok, dm[1]);                  message_date(tok, dm[1]);
156                    headers_variables(tok, dm[1]);
157    
158                  if ((r = response_copy(&connpri, imap_copy(&connpri, tok,                  if ((r = response_copy(&connpri, imap_copy(&connpri, tok,
159                      dm[1]))) == RESPONSE_TRYCREATE)                      dm[1]))) == RESPONSE_TRYCREATE)
# Line 247  action_rcopy(char *mbox, char *mesgs, ac Line 250  action_rcopy(char *mbox, char *mesgs, ac
250    
251          xstrncpy(dm[1], destmbox, MBOX_LEN - 1);          xstrncpy(dm[1], destmbox, MBOX_LEN - 1);
252          default_variables(mbox, dm[1]);          default_variables(mbox, dm[1]);
253          current_date(dm[1]);          system_date(dm[1]);
254    
255          tok = strtok_r(m, " ", &m);          tok = strtok_r(m, " ", &m);
256          while (tok != NULL) {          while (tok != NULL) {
257                  xstrncpy(dm[2], dm[1], MBOX_LEN - 1);                  xstrncpy(dm[2], dm[1], MBOX_LEN - 1);
258                  message_date(tok, dm[2]);                  message_date(tok, dm[2]);
259                    headers_variables(tok, dm[2]);
260    
261                  /* apply_namespace() returns a pointer to a static buffer. */                  /* apply_namespace() returns a pointer to a static buffer. */
262                  ndm = apply_namespace(dm[2], connaux.ns.prefix,                  ndm = apply_namespace(dm[2], connaux.ns.prefix,
# Line 544  substitute_date(char *str) Line 548  substitute_date(char *str)
548   * specifiers.   * specifiers.
549   */   */
550  void  void
551  current_date(char *destmbox)  system_date(char *destmbox)
552  {  {
553          char s[MBOX_LEN];          char s[MBOX_LEN];
554          time_t te;          time_t te;
# Line 571  message_date(char *mesg, char *destmbox) Line 575  message_date(char *mesg, char *destmbox)
575          unsigned int t;          unsigned int t;
576          char s[MBOX_LEN];          char s[MBOX_LEN];
577          struct tm tl;          struct tm tl;
578          char dbuf[RESPONSE_BUF + 1];          char buf[RESPONSE_BUF + 1];
579    
580          if (!strchr(destmbox, '@'))          if (!strchr(destmbox, '@'))
581                  return;                  return;
# Line 583  message_date(char *mesg, char *destmbox) Line 587  message_date(char *mesg, char *destmbox)
587              "BODY.PEEK[HEADER.FIELDS (DATE)]" :              "BODY.PEEK[HEADER.FIELDS (DATE)]" :
588              "BODY[HEADER.FIELDS (DATE)]");              "BODY[HEADER.FIELDS (DATE)]");
589    
590          while (response_fetch(&connpri, t, 0, dbuf) == RESPONSE_NONE);          while (response_fetch(&connpri, t, 0, buf) == RESPONSE_NONE);
591    
592          if (((strptime(dbuf, "Date: %a, %d %b %Y %H:%M:%S", &tl) ||          if (((strptime(buf, "Date: %a, %d %b %Y %H:%M:%S", &tl) ||
593              strptime(dbuf, "Date: %d %b %Y %H:%M:%S", &tl)) &&              strptime(buf, "Date: %d %b %Y %H:%M:%S", &tl)) &&
594              strftime(s, MBOX_LEN - 1, destmbox, &tl)))              strftime(s, MBOX_LEN - 1, destmbox, &tl)))
595                  xstrncpy(destmbox, s, MBOX_LEN - 1);                  xstrncpy(destmbox, s, MBOX_LEN - 1);
596  }  }
# Line 636  default_variables(char *mbox, char *dest Line 640  default_variables(char *mbox, char *dest
640    
641          xfree(s);          xfree(s);
642  }  }
643    
644    
645    /*
646     * Format the destination mailbox according to "headers variables" specifiers.
647     */
648    void
649    headers_variables(char *mesg, char *destmbox)
650    {
651            int i;
652            unsigned int t;
653            char *c, *r, *w, *s;
654            regex_t creg[2];
655            regmatch_t match[3];
656            char buf[RESPONSE_BUF + 1];
657            struct {
658                    char *s;
659                    char *e;
660            } user, domain;
661            const char *reg[2] = {
662                    "From:[[:blank:]]+([[:graph:]]+)@([[:graph:]]+)"
663                    "[[:blank:]]*\r\n",
664    
665                    "From:[[:print:]]+<([[:graph:]]+)@([[:graph:]]+)>"
666                    "[[:blank:]]*\r\n"
667            };
668    
669            if (!strchr(destmbox, '&'))
670                    return;
671    
672            response_fetch(&connpri, 0, 1, NULL);
673            t = imap_fetch(&connpri, mesg, opts.peek ?
674                "BODY.PEEK[HEADER.FIELDS (FROM)]" :
675                "BODY[HEADER.FIELDS (FROM)]");
676            while (response_fetch(&connpri, t, 0, buf) == RESPONSE_NONE);
677    
678            for (i = 0; i < 2; i++)
679                    regcomp(&creg[i], reg[i], REG_EXTENDED | REG_ICASE);
680    
681            if (!regexec(&creg[0], buf, 3, match, 0) ||
682                !regexec(&creg[1], buf, 3, match, 0)) {
683                    user.s = buf + match[1].rm_so;
684                    user.e = buf + match[1].rm_eo;
685                    domain.s = buf + match[2].rm_so;
686                    domain.e = buf + match[2].rm_eo;
687            } else {
688                    for (i = 0; i < 2; i++)
689                            regfree(&creg[i]);
690                    return;
691            }
692    
693            s = xstrdup(destmbox);
694    
695            for (r = s, w = destmbox; *r != '\0';) {
696                    if (w - destmbox >= MBOX_LEN - 1)
697                            break;
698                    if (*r == '&') {
699                            switch (*(r + 1)) {
700                            case 'f':
701                                    if (w + (user.e - user.s) +
702                                        (domain.s - domain.e) + 1 -
703                                        destmbox > MBOX_LEN) {
704                                            r += 2;
705                                            break;
706                                    }
707                                    for (c = user.s; c < user.e; c++, w++)
708                                            *w = *c;
709                                    *w++ = '@';
710                                    for (c = domain.s; c < domain.e; c++, w++)
711                                            *w = *c;
712                                    r += 2;
713                                    break;
714                            case 'u':
715                                    if (w + (user.e - user.s) - destmbox >
716                                        MBOX_LEN - 1) {
717                                            r += 2;
718                                            break;
719                                    }
720                                    for (c = user.s; c < user.e; c++, w++)
721                                            *w = *c;
722                                    r += 2;
723                                    break;
724                            case 'd':
725                                    if (w + (domain.e - domain.s) - destmbox >
726                                        MBOX_LEN - 1) {
727                                            r += 2;
728                                            break;
729                                    }
730                                    for (c = domain.s; c < domain.e; c++, w++)
731                                            *w = *c;
732                                    r += 2;
733                                    break;
734                            case '&':
735                                    *w++ = '&';
736                                    r += 2;
737                                    break;
738                            default:
739                                    *w++ = *r++;
740                                    break;
741                            }
742                    } else {
743                            *w++ = *r++;
744                    }
745            }
746            *w = '\0';
747    
748            for (i = 0; i < 2; i++)
749                    regfree(&creg[i]);
750            xfree(s);
751    }

Legend:
Removed from v.1.16  
changed lines
  Added in v.1.17

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26