Add In-Reply-To and References headers to the outgoing message.
Showing
1 changed file
with
147 additions
and
1 deletions
... | @@ -17,6 +17,150 @@ | ... | @@ -17,6 +17,150 @@ |
17 | 17 | ||
18 | #include "mail.h" | 18 | #include "mail.h" |
19 | 19 | ||
20 | #define DATEBUFSIZE 128 | ||
21 | |||
22 | static char * | ||
23 | concat (const char *s1, const char *s2) | ||
24 | { | ||
25 | int len = (s1 ? strlen (s1) : 0) + (s2 ? strlen (s2) : 0) + 2; | ||
26 | char *s = malloc (len); | ||
27 | if (s) | ||
28 | { | ||
29 | char *p = s; | ||
30 | |||
31 | if (s1) | ||
32 | { | ||
33 | strcpy (p, s1); | ||
34 | p += strlen (s1); | ||
35 | *p++ = ' '; | ||
36 | } | ||
37 | if (s2) | ||
38 | strcpy (p, s2); | ||
39 | } | ||
40 | return s; | ||
41 | } | ||
42 | |||
43 | void | ||
44 | make_in_reply_to (compose_env_t *env, message_t msg) | ||
45 | { | ||
46 | char *value, *s1 = NULL, *s2 = NULL; | ||
47 | header_t hdr; | ||
48 | |||
49 | if (message_get_header (msg, &hdr)) | ||
50 | return; | ||
51 | |||
52 | if (header_aget_value (hdr, MU_HEADER_DATE, &value)) | ||
53 | { | ||
54 | envelope_t envelope = NULL; | ||
55 | value = malloc (DATEBUFSIZE); | ||
56 | if (value) | ||
57 | { | ||
58 | message_get_envelope (msg, &envelope); | ||
59 | envelope_date (envelope, value, DATEBUFSIZE, NULL); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | if (value) | ||
64 | asprintf (&s1, "Your message of %s", value); | ||
65 | |||
66 | if (header_aget_value (hdr, MU_HEADER_MESSAGE_ID, &value) == 0) | ||
67 | { | ||
68 | asprintf (&s2, "\n\t%s", value); | ||
69 | free (value); | ||
70 | } | ||
71 | |||
72 | if (s1 || s2) | ||
73 | { | ||
74 | value = concat (s1, s2); | ||
75 | free (s1); | ||
76 | free (s2); | ||
77 | compose_header_set (env, MU_HEADER_IN_REPLY_TO, value, | ||
78 | COMPOSE_REPLACE); | ||
79 | free (value); | ||
80 | } | ||
81 | } | ||
82 | |||
83 | int | ||
84 | strip_message_id (char *msgid, char **val) | ||
85 | { | ||
86 | address_t addr; | ||
87 | char *p = strchr (msgid, '<'); | ||
88 | if (!p) | ||
89 | p = msgid; | ||
90 | if (address_create (&addr, p) == 0) | ||
91 | { | ||
92 | size_t count = 0; | ||
93 | char *p; | ||
94 | |||
95 | address_get_count (addr, &count); | ||
96 | if (count != 1) | ||
97 | { | ||
98 | address_destroy (&addr); | ||
99 | return 1; | ||
100 | } | ||
101 | if (address_aget_email (addr, 1, &p)) | ||
102 | return -1; | ||
103 | address_destroy (&addr); | ||
104 | *val = malloc (strlen (p) + 3); | ||
105 | if (!*val) | ||
106 | { | ||
107 | free (p); | ||
108 | return -1; | ||
109 | } | ||
110 | sprintf (*val, "<%s>", p); | ||
111 | free (p); | ||
112 | return 0; | ||
113 | } | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | int | ||
118 | get_msgid_header (header_t hdr, const char *name, char **val) | ||
119 | { | ||
120 | char *p; | ||
121 | int status = header_aget_value (hdr, name, &p); | ||
122 | if (status) | ||
123 | return status; | ||
124 | status = strip_message_id (p, val); | ||
125 | free (p); | ||
126 | return status; | ||
127 | } | ||
128 | |||
129 | /* rfc2822: | ||
130 | |||
131 | The "References:" field will contain the contents of the parent's | ||
132 | "References:" field (if any) followed by the contents of the parent's | ||
133 | "Message-ID:" field (if any). If the parent message does not contain | ||
134 | a "References:" field but does have an "In-Reply-To:" field | ||
135 | containing a single message identifier, then the "References:" field | ||
136 | will contain the contents of the parent's "In-Reply-To:" field | ||
137 | followed by the contents of the parent's "Message-ID:" field (if | ||
138 | any). If the parent has none of the "References:", "In-Reply-To:", | ||
139 | or "Message-ID:" fields, then the new message will have no | ||
140 | References:" field. */ | ||
141 | |||
142 | void | ||
143 | make_references (compose_env_t *env, message_t msg) | ||
144 | { | ||
145 | char *ref = NULL, *msgid = NULL; | ||
146 | header_t hdr; | ||
147 | |||
148 | if (message_get_header (msg, &hdr)) | ||
149 | return; | ||
150 | |||
151 | get_msgid_header (hdr, MU_HEADER_MESSAGE_ID, &msgid); | ||
152 | if (get_msgid_header (hdr, MU_HEADER_REFERENCES, &ref)) | ||
153 | get_msgid_header (hdr, MU_HEADER_IN_REPLY_TO, &ref); | ||
154 | |||
155 | if (ref || msgid) | ||
156 | { | ||
157 | char *s = concat (ref, msgid); | ||
158 | free (ref); | ||
159 | free (msgid); | ||
160 | compose_header_set (env, MU_HEADER_REFERENCES, s, COMPOSE_REPLACE); | ||
161 | } | ||
162 | } | ||
163 | |||
20 | /* | 164 | /* |
21 | * r[eply] [msglist] -- GNU extension | 165 | * r[eply] [msglist] -- GNU extension |
22 | * r[espond] [msglist] -- GNU extension | 166 | * r[espond] [msglist] -- GNU extension |
... | @@ -39,7 +183,7 @@ mail_reply (int argc, char **argv) | ... | @@ -39,7 +183,7 @@ mail_reply (int argc, char **argv) |
39 | 183 | ||
40 | compose_init (&env); | 184 | compose_init (&env); |
41 | 185 | ||
42 | if (util_get_message (mbox, cursor, &msg, 1)) | 186 | if (util_get_message (mbox, cursor, &msg, MSG_NODELETED)) |
43 | return 1; | 187 | return 1; |
44 | 188 | ||
45 | message_get_header (msg, &hdr); | 189 | message_get_header (msg, &hdr); |
... | @@ -99,6 +243,8 @@ mail_reply (int argc, char **argv) | ... | @@ -99,6 +243,8 @@ mail_reply (int argc, char **argv) |
99 | fprintf (ofile, "Subject: %s\n\n", | 243 | fprintf (ofile, "Subject: %s\n\n", |
100 | compose_header_get (&env, MU_HEADER_SUBJECT, "")); | 244 | compose_header_get (&env, MU_HEADER_SUBJECT, "")); |
101 | 245 | ||
246 | make_in_reply_to (&env, msg); | ||
247 | make_references (&env, msg); | ||
102 | status = mail_send0 (&env, 0); | 248 | status = mail_send0 (&env, 0); |
103 | compose_destroy (&env); | 249 | compose_destroy (&env); |
104 | return status; | 250 | return status; | ... | ... |
-
Please register or sign in to post a comment