Commit 42ca2c2e 42ca2c2ef8ed0987f302cc360359c5b2ce4427c8 by Sergey Poznyakoff

User-defined headers in vacation extension

New tag :header allows to set headers in the reply message
generated by the vacation extension.
1 parent 6880edb2
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
28 [:mime] 28 [:mime]
29 [:always_reply] 29 [:always_reply]
30 [:return_address <email: string>] 30 [:return_address <email: string>]
31 [:header <header-list: list>]
31 <reply: string> 32 <reply: string>
32 */ 33 */
33 34
...@@ -533,6 +534,81 @@ vacation_subject (mu_sieve_machine_t mach, mu_list_t tags, ...@@ -533,6 +534,81 @@ vacation_subject (mu_sieve_machine_t mach, mu_list_t tags,
533 free (subject); 534 free (subject);
534 } 535 }
535 536
537 static int
538 header_split (const char *str, char **hname, char **hval)
539 {
540 char *p, *q, *fn, *fv;
541 size_t n;
542
543 q = strchr (str, ':');
544 if (!q)
545 return MU_ERR_FORMAT;
546
547 for (p = q; p > str && mu_isspace (p[-1]); --p)
548 ;
549 if (p == str)
550 return MU_ERR_FORMAT;
551
552 n = p - str;
553 fn = malloc (n + 1);
554 if (!fn)
555 return ENOMEM;
556
557 memcpy (fn, str, n);
558 fn[n] = 0;
559
560 for (++q; *q && mu_isspace (*q); ++q)
561 ;
562
563 fv = strdup (q);
564 if (!fv)
565 {
566 free (fn);
567 return ENOMEM;
568 }
569
570 *hname = fn;
571 *hval = fv;
572
573 return 0;
574 }
575
576 struct header_closure
577 {
578 mu_sieve_machine_t mach;
579 mu_header_t hdr;
580 };
581
582 static int
583 add_header (void *item, void *data)
584 {
585 char const *str = item;
586 struct header_closure *hc = data;
587 char *fn, *fv;
588 int rc;
589
590 rc = header_split (str, &fn, &fv);
591 if (rc)
592 {
593 mu_sieve_error (hc->mach,
594 _("%lu: can't add header \"%s\": %s"),
595 (unsigned long) mu_sieve_get_message_num (hc->mach),
596 str, mu_strerror (rc));
597 return 0;
598 }
599
600 rc = mu_header_append (hc->hdr, fn, fv);
601 free (fn);
602 free (fv);
603
604 if (rc)
605 mu_sieve_error (hc->mach,
606 _("%lu: can't add header \"%s\": %s"),
607 (unsigned long) mu_sieve_get_message_num (hc->mach),
608 str, mu_strerror (rc));
609 return 0;
610 }
611
536 /* Generate and send the reply message */ 612 /* Generate and send the reply message */
537 static int 613 static int
538 vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, mu_message_t msg, 614 vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, mu_message_t msg,
...@@ -545,6 +621,7 @@ vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, mu_message_t msg, ...@@ -545,6 +621,7 @@ vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, mu_message_t msg,
545 char *value; 621 char *value;
546 mu_mailer_t mailer; 622 mu_mailer_t mailer;
547 int rc; 623 int rc;
624 mu_sieve_value_t *val;
548 625
549 if (mu_sieve_tag_lookup (tags, "file", NULL)) 626 if (mu_sieve_tag_lookup (tags, "file", NULL))
550 { 627 {
...@@ -594,6 +671,14 @@ vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, mu_message_t msg, ...@@ -594,6 +671,14 @@ vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, mu_message_t msg,
594 { 671 {
595 mu_header_set_value (newhdr, MU_HEADER_TO, to, 0); 672 mu_header_set_value (newhdr, MU_HEADER_TO, to, 0);
596 673
674 if (mu_sieve_tag_lookup (tags, "header", &val))
675 {
676 struct header_closure hc;
677 hc.mach = mach;
678 hc.hdr = newhdr;
679 mu_sieve_vlist_do (val, add_header, &hc);
680 }
681
597 vacation_subject (mach, tags, msg, newhdr); 682 vacation_subject (mach, tags, msg, newhdr);
598 683
599 if (from) 684 if (from)
...@@ -636,7 +721,7 @@ int ...@@ -636,7 +721,7 @@ int
636 sieve_action_vacation (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) 721 sieve_action_vacation (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
637 { 722 {
638 int rc; 723 int rc;
639 char *text, *from; 724 char *text, *from = NULL;
640 char const *return_address; 725 char const *return_address;
641 mu_sieve_value_t *val; 726 mu_sieve_value_t *val;
642 mu_message_t msg; 727 mu_message_t msg;
...@@ -670,15 +755,17 @@ sieve_action_vacation (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags) ...@@ -670,15 +755,17 @@ sieve_action_vacation (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
670 mu_sieve_abort (mach); 755 mu_sieve_abort (mach);
671 } 756 }
672 } 757 }
673 else if (mu_sieve_get_message_sender (msg, &from)) 758 else if ((rc = mu_sieve_get_message_sender (msg, &from)) != 0)
674 { 759 {
675 mu_sieve_error (mach, 760 mu_sieve_error (mach,
676 _("%lu: cannot get sender address"), 761 _("%lu: cannot get sender address: %s"),
677 (unsigned long) mu_sieve_get_message_num (mach)); 762 (unsigned long) mu_sieve_get_message_num (mach),
763 mu_strerror (rc));
678 mu_sieve_abort (mach); 764 mu_sieve_abort (mach);
679 } 765 }
680 766
681 my_address = mu_get_user_email (NULL); 767 my_address = mu_get_user_email (NULL);
768
682 if (mu_sieve_tag_lookup (tags, "always_reply", NULL)) 769 if (mu_sieve_tag_lookup (tags, "always_reply", NULL))
683 return_address = my_address; 770 return_address = my_address;
684 else 771 else
...@@ -726,6 +813,7 @@ static mu_sieve_tag_def_t vacation_tags[] = { ...@@ -726,6 +813,7 @@ static mu_sieve_tag_def_t vacation_tags[] = {
726 {"file", SVT_VOID}, 813 {"file", SVT_VOID},
727 {"always_reply", SVT_VOID}, 814 {"always_reply", SVT_VOID},
728 {"return_address", SVT_STRING}, 815 {"return_address", SVT_STRING},
816 {"header", SVT_STRING_LIST},
729 {NULL} 817 {NULL}
730 }; 818 };
731 819
......