Commit 1485ab7d 1485ab7d2666042b20b0caa64beb3ddfeb4577fe by Sergey Poznyakoff

mhn: fixes in compose mode.

* mh/mhn.c (edit_forw): Accept directives without explicit folder
spec.
Fix creation of individual mime parts; set Content-Type: message/rfc822
for each of them.
(mhn_edit): Fix some coredumps.
(main): Use -file argument, if it is given.
* mh/tests/atlocal.in (mimeflt): New function.
* mh/tests/mhn.at: Add tests for compose mode.
1 parent 3260bd74
...@@ -2223,15 +2223,14 @@ edit_extern (char *cmd, struct compose_env *env, mu_message_t *msg, int level) ...@@ -2223,15 +2223,14 @@ edit_extern (char *cmd, struct compose_env *env, mu_message_t *msg, int level)
2223 int 2223 int
2224 edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level) 2224 edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
2225 { 2225 {
2226 char *sp, *id = NULL, *descr = NULL; 2226 char *id = NULL, *descr = NULL;
2227 int stop = 0, status = 0; 2227 int stop = 0, status = 0;
2228 size_t i; 2228 size_t i, npart;
2229 struct mu_wordsplit ws; 2229 struct mu_wordsplit ws;
2230 mu_header_t hdr; 2230 mu_header_t hdr;
2231 mu_mime_t mime; 2231 mu_mime_t mime;
2232 mu_message_t msg; 2232 mu_message_t msg;
2233 const char *val; 2233 const char *val;
2234 char *newval;
2235 2234
2236 skipws (cmd); 2235 skipws (cmd);
2237 while (stop == 0 && status == 0 && *cmd) 2236 while (stop == 0 && status == 0 && *cmd)
...@@ -2283,10 +2282,22 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level) ...@@ -2283,10 +2282,22 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
2283 2282
2284 mu_mime_create (&mime, NULL, 0); 2283 mu_mime_create (&mime, NULL, 0);
2285 2284
2285 if (ws.ws_wordv[0][0] == '+')
2286 {
2286 mbox = mh_open_folder (ws.ws_wordv[0], 0); 2287 mbox = mh_open_folder (ws.ws_wordv[0], 0);
2287 for (i = 1; i < ws.ws_wordc; i++) 2288 i = 1;
2289 }
2290 else
2288 { 2291 {
2289 mu_message_t input_msg; 2292 mbox = mh_open_folder (mh_current_folder (), 0);
2293 i = 0;
2294 }
2295
2296 for (npart = 1; i < ws.ws_wordc; i++, npart++)
2297 {
2298 mu_message_t input_msg, newmsg;
2299 mu_body_t body;
2300 mu_stream_t input_str, bstr;
2290 char *endp; 2301 char *endp;
2291 size_t n = strtoul (ws.ws_wordv[i], &endp, 10); 2302 size_t n = strtoul (ws.ws_wordv[i], &endp, 10);
2292 2303
...@@ -2308,9 +2319,47 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level) ...@@ -2308,9 +2319,47 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
2308 return 1; 2319 return 1;
2309 } 2320 }
2310 2321
2311 if ((status = mu_message_create_copy (&msg, input_msg))) 2322 status = mu_message_get_streamref (input_msg, &input_str);
2312 break; 2323 if (status)
2313 mu_mime_add_part (mime, msg); 2324 {
2325 mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_streamref", NULL,
2326 status);
2327 exit (1);
2328 }
2329
2330 status = mu_message_create (&newmsg, NULL);
2331 if (status)
2332 {
2333 mu_diag_funcall (MU_DIAG_ERROR, "mu_message_create", NULL, status);
2334 exit (1);
2335 }
2336 status = mu_message_get_body (newmsg, &body);
2337 if (status)
2338 {
2339 mu_diag_funcall (MU_DIAG_ERROR, "mu_message_get_body", NULL,
2340 status);
2341 exit (1);
2342 }
2343 status = mu_body_get_streamref (body, &bstr);
2344 if (status)
2345 {
2346 mu_diag_funcall (MU_DIAG_ERROR, "mu_body_get_streamref", NULL,
2347 status);
2348 exit (1);
2349 }
2350 status = mu_stream_copy (bstr, input_str, 0, NULL);
2351 if (status)
2352 {
2353 mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_copy", NULL,
2354 status);
2355 exit (1);
2356 }
2357 mu_stream_unref (bstr);
2358 mu_stream_unref (input_str);
2359
2360 mu_message_get_header (newmsg, &hdr);
2361 mu_header_set_value (hdr, MU_HEADER_CONTENT_TYPE, "message/rfc822", 1);
2362 mu_mime_add_part (mime, newmsg);
2314 } 2363 }
2315 mu_wordsplit_free (&ws); 2364 mu_wordsplit_free (&ws);
2316 2365
...@@ -2322,13 +2371,20 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level) ...@@ -2322,13 +2371,20 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
2322 2371
2323 mu_mime_get_message (mime, &msg); 2372 mu_mime_get_message (mime, &msg);
2324 mu_message_get_header (msg, &hdr); 2373 mu_message_get_header (msg, &hdr);
2374
2375 if (npart > 2)
2376 {
2377 char *newval, *sp;
2378
2325 mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &val); 2379 mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &val);
2326 sp = strchr (val, ';'); 2380 sp = strchr (val, ';');
2327 if (!sp) 2381 if (sp)
2328 abort (); 2382 {
2329 mu_asprintf (&newval, "multipart/digest%s", sp); 2383 mu_asprintf (&newval, "multipart/digest%s", sp);
2330 mu_header_set_value (hdr, MU_HEADER_CONTENT_TYPE, newval, 1); 2384 mu_header_set_value (hdr, MU_HEADER_CONTENT_TYPE, newval, 1);
2331 free (newval); 2385 free (newval);
2386 }
2387 }
2332 2388
2333 if (!id) 2389 if (!id)
2334 id = mh_create_message_id (env->subpart); 2390 id = mh_create_message_id (env->subpart);
...@@ -2463,7 +2519,6 @@ mhn_edit (struct compose_env *env, int level) ...@@ -2463,7 +2519,6 @@ mhn_edit (struct compose_env *env, int level)
2463 int status = 0; 2519 int status = 0;
2464 char *buf = NULL; 2520 char *buf = NULL;
2465 size_t bufsize = 0, n; 2521 size_t bufsize = 0, n;
2466 mu_body_t body;
2467 mu_stream_t output = NULL; 2522 mu_stream_t output = NULL;
2468 mu_message_t msg = NULL; 2523 mu_message_t msg = NULL;
2469 size_t line_count = 0; 2524 size_t line_count = 0;
...@@ -2483,6 +2538,11 @@ mhn_edit (struct compose_env *env, int level) ...@@ -2483,6 +2538,11 @@ mhn_edit (struct compose_env *env, int level)
2483 /* Create new message */ 2538 /* Create new message */
2484 mu_message_create (&msg, NULL); 2539 mu_message_create (&msg, NULL);
2485 mu_message_get_header (msg, &hdr); 2540 mu_message_get_header (msg, &hdr);
2541 }
2542 if (!output)
2543 {
2544 mu_body_t body;
2545
2486 mu_message_get_body (msg, &body); 2546 mu_message_get_body (msg, &body);
2487 mu_body_get_streamref (body, &output); 2547 mu_body_get_streamref (body, &output);
2488 line_count = 0; 2548 line_count = 0;
...@@ -2849,9 +2909,9 @@ main (int argc, char **argv) ...@@ -2849,9 +2909,9 @@ main (int argc, char **argv)
2849 mu_error (_("extra arguments")); 2909 mu_error (_("extra arguments"));
2850 return 1; 2910 return 1;
2851 } 2911 }
2852 input_file = mh_expand_name (mu_folder_directory (), 2912 message = mh_file_to_message (NULL,
2853 argc == 1 ? argv[0] : "draft", 0); 2913 mu_tilde_expansion (input_file,
2854 message = mh_file_to_message (NULL, input_file); 2914 "/", NULL));
2855 if (!message) 2915 if (!message)
2856 return 1; 2916 return 1;
2857 } 2917 }
......
...@@ -6,3 +6,34 @@ PATH=@abs_builddir@:@abs_top_builddir@/mh:$top_srcdir:$srcdir:$PATH ...@@ -6,3 +6,34 @@ PATH=@abs_builddir@:@abs_top_builddir@/mh:$top_srcdir:$srcdir:$PATH
6 remove_curdir() { 6 remove_curdir() {
7 sed "s|$curdir/*||;s| *$||" $* 7 sed "s|$curdir/*||;s| *$||" $*
8 } 8 }
9 # mimeflt [FILE]
10 # Filter out all variable information from a MIME message in FILE.
11 # If FILE is not given, filter stdin.
12 # "Variable information" means part boundary and Content-ID header values.
13 # These elements are likely to change between invocations of mhn -build.
14 mimeflt() {
15 awk '
16 /^Content-Type:/ {
17 if (match($0, /boundary=".*"/)) {
18 s=substr($0,RSTART+10,RLENGTH-11)
19 boundary[++boundary_num] = s
20 sub(/boundary=".*"/,"boundary=\"BOUNDARY-" boundary_num "\"")
21 }
22 }
23 /^X-IMAPbase:/ { next }
24 /^Content-ID:/ {
25 content_id[$2]++
26 print "Content-ID:", ++content_id_num
27 next
28 }
29 {
30 if ($0 == ("--" boundary[boundary_num])) {
31 print "--BOUNDARY-" boundary_num
32 } else if ($0 == ("--" boundary[boundary_num] "--")) {
33 print "--BOUNDARY-" boundary_num "--"
34 boundary_num--
35 } else
36 print
37 }
38 ' $*
39 }
......