Commit 27f9a867 27f9a867f4fcfaf29a22349043eaddcb60c2694e by Sergey Poznyakoff

Fix body start calculation in message_stream. Fix compose parser in mhn.

* libmailutils/stream/message_stream.c (scan_stream): Merge
with _message_open.
* mh/mhn.c (edit_forw): Do not set ws_delim.
Fix message addressing.
(mhn_edit): Remove the trailing newline.
1 parent 43853ce8
...@@ -145,51 +145,62 @@ copy_trimmed_value (const char *str) ...@@ -145,51 +145,62 @@ copy_trimmed_value (const char *str)
145 } 145 }
146 146
147 static int 147 static int
148 scan_stream (struct _mu_message_stream *str) 148 _message_open (mu_stream_t stream)
149 { 149 {
150 struct _mu_message_stream *str = (struct _mu_message_stream*) stream;
150 char *from = NULL; 151 char *from = NULL;
151 char *env_from = NULL; 152 char *env_from = NULL;
152 char *env_date = NULL; 153 char *env_date = NULL;
153 int rc; 154 int rc;
154 char *buffer = NULL; 155 char *buffer = NULL;
155 size_t bufsize = 0; 156 size_t bufsize = 0;
156 size_t len; 157 size_t offset, len;
157 mu_off_t body_start, body_end; 158 mu_off_t body_start, body_end;
158 mu_stream_t stream = str->transport; 159 mu_stream_t transport = str->transport;
159 160
160 if (str->envelope) 161 rc = mu_stream_seek (transport, 0, MU_SEEK_SET, NULL);
162 if (rc)
163 return rc;
164 offset = 0;
165 while ((rc = mu_stream_getline (transport, &buffer, &bufsize, &len)) == 0
166 && len > 0)
161 { 167 {
162 char *s = str->envelope + 5; 168 if (offset == 0 && memcmp (buffer, "From ", 5) == 0)
163 char *p = strchr (s, ' ');
164 size_t len;
165
166 if (p)
167 { 169 {
168 len = p - s; 170 char *s, *p;
169 env_from = mu_alloc (len + 1); 171
170 if (!env_from) 172 str->envelope_length = len;
173 str->envelope = mu_strdup (buffer);
174 if (!str->envelope)
171 return ENOMEM; 175 return ENOMEM;
172 memcpy (env_from, s, len); 176 str->envelope[len - 1] = 0;
173 env_from[len] = 0; 177
174 env_date = mu_strdup (p + 1); 178 s = str->envelope + 5;
175 if (!env_date) 179 p = strchr (s, ' ');
180
181 if (p)
176 { 182 {
177 free (env_from); 183 len = p - s;
178 return ENOMEM; 184 env_from = mu_alloc (len + 1);
185 if (!env_from)
186 return ENOMEM;
187 memcpy (env_from, s, len);
188 env_from[len] = 0;
189 env_date = mu_strdup (p + 1);
190 if (!env_date)
191 {
192 free (env_from);
193 return ENOMEM;
194 }
179 } 195 }
180 } 196 }
181 } 197 else if (mu_mh_delim (buffer))
182 198 {
183 rc = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL); 199 str->mark_offset = offset;
184 if (rc) 200 str->mark_length = len - 1; /* do not count the terminating newline */
185 return rc; 201 break;
186 while ((rc = mu_stream_getline (stream, &buffer, &bufsize, &len)) == 0 202 }
187 && len > 0) 203 else if (!env_from || !env_date)
188 {
189 if (buffer[0] == '\n')
190 break;
191
192 if (!env_from || !env_date)
193 { 204 {
194 if (!from && mu_c_strncasecmp (buffer, MU_HEADER_FROM, 205 if (!from && mu_c_strncasecmp (buffer, MU_HEADER_FROM,
195 sizeof (MU_HEADER_FROM) - 1) == 0) 206 sizeof (MU_HEADER_FROM) - 1) == 0)
...@@ -206,14 +217,15 @@ scan_stream (struct _mu_message_stream *str) ...@@ -206,14 +217,15 @@ scan_stream (struct _mu_message_stream *str)
206 env_date = copy_trimmed_value (buffer + 217 env_date = copy_trimmed_value (buffer +
207 sizeof (MU_HEADER_ENV_DATE)); 218 sizeof (MU_HEADER_ENV_DATE));
208 } 219 }
220 offset += len;
209 } 221 }
210 222
211 free (buffer); 223 free (buffer);
212 224
213 rc = mu_stream_seek (stream, 0, MU_SEEK_CUR, &body_start); 225 rc = mu_stream_seek (transport, 0, MU_SEEK_CUR, &body_start);
214 if (rc) 226 if (rc)
215 return rc; 227 return rc;
216 rc = mu_stream_size (stream, &body_end); 228 rc = mu_stream_size (transport, &body_end);
217 if (rc) 229 if (rc)
218 return rc; 230 return rc;
219 231
...@@ -256,43 +268,6 @@ scan_stream (struct _mu_message_stream *str) ...@@ -256,43 +268,6 @@ scan_stream (struct _mu_message_stream *str)
256 } 268 }
257 269
258 static int 270 static int
259 _message_open (mu_stream_t stream)
260 {
261 struct _mu_message_stream *s = (struct _mu_message_stream*) stream;
262 size_t offset, len;
263 char *buffer = NULL;
264 size_t bufsize = 0;
265 int rc;
266
267 offset = 0;
268 mu_stream_seek (s->transport, 0, MU_SEEK_SET, NULL);
269 while ((rc = mu_stream_getline (s->transport, &buffer, &bufsize,
270 &len)) == 0
271 && len > 0)
272 {
273 if (offset == 0 && memcmp (buffer, "From ", 5) == 0)
274 {
275 s->envelope_length = len;
276 s->envelope = mu_strdup (buffer);
277 if (!s->envelope)
278 return ENOMEM;
279 s->envelope[len - 1] = 0;
280 }
281 else if (mu_mh_delim (buffer))
282 {
283 s->mark_offset = offset;
284 s->mark_length = len - 1; /* do not count the terminating newline */
285 break;
286 }
287
288 offset += len;
289 }
290 free (buffer);
291
292 return scan_stream (s);
293 }
294
295 static int
296 _message_close (mu_stream_t stream) 271 _message_close (mu_stream_t stream)
297 { 272 {
298 struct _mu_message_stream *s = (struct _mu_message_stream*) stream; 273 struct _mu_message_stream *s = (struct _mu_message_stream*) stream;
......
...@@ -2083,9 +2083,7 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level) ...@@ -2083,9 +2083,7 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
2083 if (status) 2083 if (status)
2084 return status; 2084 return status;
2085 2085
2086 ws.ws_delim = "\n"; 2086 if (mu_wordsplit (cmd, &ws, MU_WRDSF_DEFFLAGS))
2087 if (mu_wordsplit (cmd, &ws,
2088 MU_WRDSF_DEFFLAGS | MU_WRDSF_DELIM | MU_WRDSF_WS))
2089 { 2087 {
2090 mu_error (_("%s:%lu: cannot split line: %s"), 2088 mu_error (_("%s:%lu: cannot split line: %s"),
2091 input_file, 2089 input_file,
...@@ -2100,7 +2098,19 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level) ...@@ -2100,7 +2098,19 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
2100 for (i = 1; i < ws.ws_wordc; i++) 2098 for (i = 1; i < ws.ws_wordc; i++)
2101 { 2099 {
2102 mu_message_t input_msg; 2100 mu_message_t input_msg;
2103 if (mh_get_message (mbox, i, &input_msg) == 0) 2101 char *endp;
2102 size_t n = strtoul (ws.ws_wordv[i], &endp, 10);
2103
2104 if (*endp)
2105 {
2106 mu_error (_("%s:%lu: malformed directive near %s"),
2107 input_file,
2108 (unsigned long) mhn_error_loc (env),
2109 endp);
2110 return 1;
2111 }
2112
2113 if (mh_get_message (mbox, n, &input_msg) == 0)
2104 { 2114 {
2105 mu_error (_("%s:%lu: no such message: %lu"), 2115 mu_error (_("%s:%lu: no such message: %lu"),
2106 input_file, 2116 input_file,
...@@ -2326,6 +2336,8 @@ mhn_edit (struct compose_env *env, int level) ...@@ -2326,6 +2336,8 @@ mhn_edit (struct compose_env *env, int level)
2326 if (line_count) 2336 if (line_count)
2327 /* Close and append the previous part */ 2337 /* Close and append the previous part */
2328 finish_text_msg (env, &msg, ascii_buf); 2338 finish_text_msg (env, &msg, ascii_buf);
2339
2340 mu_rtrim_cset (buf, "\n");
2329 2341
2330 /* Execute the directive */ 2342 /* Execute the directive */
2331 tok = buf; 2343 tok = buf;
......