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 |
/* |
/* |
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) |
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, |
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; |
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; |
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 |
} |
} |
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 |
|
} |