Commit e6b45504 e6b45504d9554377517401c4c149e9c98ab18a3b by Sergey Poznyakoff

(mu_rfc2822_references,mu_rfc2822_in_reply_to): New functions.

1 parent 097aeaad
...@@ -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 }
......