(mu_rfc2822_references,mu_rfc2822_in_reply_to): New functions.
Showing
2 changed files
with
179 additions
and
0 deletions
... | @@ -111,6 +111,9 @@ extern int mu_unroll_symlink __P((char *out, size_t outsz, const char *in)); | ... | @@ -111,6 +111,9 @@ extern int mu_unroll_symlink __P((char *out, size_t outsz, const char *in)); |
111 | 111 | ||
112 | extern char * mu_expand_path_pattern __P((const char *pattern, | 112 | extern char * mu_expand_path_pattern __P((const char *pattern, |
113 | const char *username)); | 113 | const char *username)); |
114 | |||
115 | extern int mu_rfc2822_references __P((message_t msg, char **pstr)); | ||
116 | extern int mu_rfc2822_in_reply_to __P((message_t msg, char **pstr)); | ||
114 | 117 | ||
115 | #ifdef __cplusplus | 118 | #ifdef __cplusplus |
116 | } | 119 | } | ... | ... |
... | @@ -45,6 +45,8 @@ | ... | @@ -45,6 +45,8 @@ |
45 | #include <mailutils/mutil.h> | 45 | #include <mailutils/mutil.h> |
46 | #include <mailutils/parse822.h> | 46 | #include <mailutils/parse822.h> |
47 | #include <mailutils/mu_auth.h> | 47 | #include <mailutils/mu_auth.h> |
48 | #include <mailutils/header.h> | ||
49 | #include <mailutils/message.h> | ||
48 | 50 | ||
49 | /* convert a sequence of hex characters into an integer */ | 51 | /* convert a sequence of hex characters into an integer */ |
50 | 52 | ||
... | @@ -839,3 +841,177 @@ mu_expand_path_pattern (const char *pattern, const char *username) | ... | @@ -839,3 +841,177 @@ mu_expand_path_pattern (const char *pattern, const char *username) |
839 | mu_auth_data_free (auth); | 841 | mu_auth_data_free (auth); |
840 | return path; | 842 | return path; |
841 | } | 843 | } |
844 | |||
845 | #define ST_INIT 0 | ||
846 | #define ST_MSGID 1 | ||
847 | |||
848 | static int | ||
849 | strip_message_id (char *msgid, char **pval) | ||
850 | { | ||
851 | char *p, *q; | ||
852 | int state; | ||
853 | |||
854 | *pval = strdup (msgid); | ||
855 | if (!*pval) | ||
856 | return ENOMEM; | ||
857 | state = ST_INIT; | ||
858 | for (p = q = *pval; *p; p++) | ||
859 | { | ||
860 | switch (state) | ||
861 | { | ||
862 | case ST_INIT: | ||
863 | if (*p == '<') | ||
864 | { | ||
865 | *q++ = *p; | ||
866 | state = ST_MSGID; | ||
867 | } | ||
868 | else if (isspace (*p)) | ||
869 | *q++ = *p; | ||
870 | break; | ||
871 | |||
872 | case ST_MSGID: | ||
873 | *q++ = *p; | ||
874 | if (*p == '>') | ||
875 | state = ST_INIT; | ||
876 | break; | ||
877 | } | ||
878 | } | ||
879 | *q = 0; | ||
880 | return 0; | ||
881 | } | ||
882 | |||
883 | int | ||
884 | get_msgid_header (header_t hdr, const char *name, char **val) | ||
885 | { | ||
886 | char *p; | ||
887 | int status = header_aget_value (hdr, name, &p); | ||
888 | if (status) | ||
889 | return status; | ||
890 | status = strip_message_id (p, val); | ||
891 | free (p); | ||
892 | return status; | ||
893 | } | ||
894 | |||
895 | static char * | ||
896 | concat (const char *s1, const char *s2) | ||
897 | { | ||
898 | int len = (s1 ? strlen (s1) : 0) + (s2 ? strlen (s2) : 0) + 2; | ||
899 | char *s = malloc (len); | ||
900 | if (s) | ||
901 | { | ||
902 | char *p = s; | ||
903 | |||
904 | if (s1) | ||
905 | { | ||
906 | strcpy (p, s1); | ||
907 | p += strlen (s1); | ||
908 | *p++ = ' '; | ||
909 | } | ||
910 | if (s2) | ||
911 | strcpy (p, s2); | ||
912 | } | ||
913 | return s; | ||
914 | } | ||
915 | |||
916 | /* rfc2822: | ||
917 | |||
918 | The "References:" field will contain the contents of the parent's | ||
919 | "References:" field (if any) followed by the contents of the parent's | ||
920 | "Message-ID:" field (if any). If the parent message does not contain | ||
921 | a "References:" field but does have an "In-Reply-To:" field | ||
922 | containing a single message identifier, then the "References:" field | ||
923 | will contain the contents of the parent's "In-Reply-To:" field | ||
924 | followed by the contents of the parent's "Message-ID:" field (if | ||
925 | any). If the parent has none of the "References:", "In-Reply-To:", | ||
926 | or "Message-ID:" fields, then the new message will have no | ||
927 | References:" field. */ | ||
928 | |||
929 | int | ||
930 | mu_rfc2822_references (message_t msg, char **pstr) | ||
931 | { | ||
932 | char *ref = NULL, *msgid = NULL; | ||
933 | header_t hdr; | ||
934 | int rc; | ||
935 | |||
936 | rc = message_get_header (msg, &hdr); | ||
937 | if (rc) | ||
938 | return rc; | ||
939 | get_msgid_header (hdr, MU_HEADER_MESSAGE_ID, &msgid); | ||
940 | if (get_msgid_header (hdr, MU_HEADER_REFERENCES, &ref)) | ||
941 | get_msgid_header (hdr, MU_HEADER_IN_REPLY_TO, &ref); | ||
942 | |||
943 | if (ref || msgid) | ||
944 | { | ||
945 | *pstr = concat (ref, msgid); | ||
946 | free (ref); | ||
947 | free (msgid); | ||
948 | } | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | #define DATEBUFSIZE 128 | ||
953 | #define COMMENT "Your message of " | ||
954 | |||
955 | /* | ||
956 | The "In-Reply-To:" field will contain the contents of the "Message- | ||
957 | ID:" field of the message to which this one is a reply (the "parent | ||
958 | message"). If there is more than one parent message, then the "In- | ||
959 | Reply-To:" field will contain the contents of all of the parents' | ||
960 | "Message-ID:" fields. If there is no "Message-ID:" field in any of | ||
961 | the parent messages, then the new message will have no "In-Reply-To:" | ||
962 | field. | ||
963 | */ | ||
964 | int | ||
965 | mu_rfc2822_in_reply_to (message_t msg, char **pstr) | ||
966 | { | ||
967 | char *value, *s1 = NULL, *s2 = NULL; | ||
968 | header_t hdr; | ||
969 | int rc; | ||
970 | |||
971 | rc = message_get_header (msg, &hdr); | ||
972 | if (rc) | ||
973 | return rc; | ||
974 | |||
975 | if (header_aget_value (hdr, MU_HEADER_DATE, &value)) | ||
976 | { | ||
977 | envelope_t envelope = NULL; | ||
978 | value = malloc (DATEBUFSIZE); | ||
979 | if (value) | ||
980 | { | ||
981 | message_get_envelope (msg, &envelope); | ||
982 | envelope_date (envelope, value, DATEBUFSIZE, NULL); | ||
983 | } | ||
984 | } | ||
985 | |||
986 | if (value) | ||
987 | { | ||
988 | s1 = malloc (sizeof (COMMENT) + strlen (value)); | ||
989 | if (s1) | ||
990 | strcat (strcpy (s1, COMMENT), value); | ||
991 | free (value); | ||
992 | if (!s1) | ||
993 | return ENOMEM; | ||
994 | } | ||
995 | |||
996 | if (header_aget_value (hdr, MU_HEADER_MESSAGE_ID, &value) == 0) | ||
997 | { | ||
998 | s2 = malloc (strlen (value) + 3); | ||
999 | if (s2) | ||
1000 | strcat (strcpy (s2, "\n\t"), value); | ||
1001 | |||
1002 | free (value); | ||
1003 | if (!s2) | ||
1004 | { | ||
1005 | free (s1); | ||
1006 | return ENOMEM; | ||
1007 | } | ||
1008 | } | ||
1009 | |||
1010 | if (s1 || s2) | ||
1011 | { | ||
1012 | *pstr = concat (s1, s2); | ||
1013 | free (s1); | ||
1014 | free (s2); | ||
1015 | } | ||
1016 | return 0; | ||
1017 | } | ... | ... |
-
Please register or sign in to post a comment