Commit 6892ffb9 6892ffb9bbb27182da907fa7fd8149fcae6acdf8 by Sergey Poznyakoff

(split_args): New function

(_message_is_external_body ): Use split_args to parse
additional arguments
(mhn_edit): Fix invocation of edit_modify (was not getting
additional arguments after ';')
(parse_header_directive): New function
(mhn_header): New function
(mhn_compose): Bugfix: initialize env.line
Call mhn_header to optionally encode Subject line
1 parent 3e239111
Showing 1 changed file with 172 additions and 26 deletions
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003, 2005 Free Software Foundation, Inc. 2 Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
3 3
4 GNU Mailutils is free software; you can redistribute it and/or modify 4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 5 it under the terms of the GNU General Public License as published by
...@@ -519,7 +519,7 @@ msg_part_format_stk (struct obstack *stk, msg_part_t p) ...@@ -519,7 +519,7 @@ msg_part_format_stk (struct obstack *stk, msg_part_t p)
519 for (i = 1; i <= p->level; i++) 519 for (i = 1; i <= p->level; i++)
520 { 520 {
521 int len; 521 int len;
522 char *buf; 522 const char *buf;
523 523
524 if (i > 1) 524 if (i > 1)
525 obstack_1grow (stk, '.'); 525 obstack_1grow (stk, '.');
...@@ -793,7 +793,6 @@ mhn_store_command (mu_message_t msg, msg_part_t part, char *name) ...@@ -793,7 +793,6 @@ mhn_store_command (mu_message_t msg, msg_part_t part, char *name)
793 char *typestr, *type, *subtype, *typeargs; 793 char *typestr, *type, *subtype, *typeargs;
794 struct obstack stk; 794 struct obstack stk;
795 mu_header_t hdr; 795 mu_header_t hdr;
796 char *buf;
797 796
798 mu_message_get_header (msg, &hdr); 797 mu_message_get_header (msg, &hdr);
799 _get_content_type (hdr, &typestr, &typeargs); 798 _get_content_type (hdr, &typestr, &typeargs);
...@@ -823,7 +822,7 @@ mhn_store_command (mu_message_t msg, msg_part_t part, char *name) ...@@ -823,7 +822,7 @@ mhn_store_command (mu_message_t msg, msg_part_t part, char *name)
823 obstack_grow (&stk, name, strlen (name)); 822 obstack_grow (&stk, name, strlen (name));
824 else 823 else
825 { 824 {
826 buf = mu_umaxtostr (0, msg_part_subpart (part, 0)); 825 const char *buf = mu_umaxtostr (0, msg_part_subpart (part, 0));
827 obstack_grow (&stk, buf, strlen (buf)); 826 obstack_grow (&stk, buf, strlen (buf));
828 } 827 }
829 break; 828 break;
...@@ -881,6 +880,32 @@ mhn_store_command (mu_message_t msg, msg_part_t part, char *name) ...@@ -881,6 +880,32 @@ mhn_store_command (mu_message_t msg, msg_part_t part, char *name)
881 880
882 /* ************************* Auxiliary functions ************************** */ 881 /* ************************* Auxiliary functions ************************** */
883 882
883 static void
884 split_args (char *argstr, int *pargc, char ***pargv)
885 {
886 int argc;
887 char **argv;
888
889 if (mu_argcv_get (argstr, ";", NULL, &argc, &argv) == 0)
890 {
891 int i, j;
892
893 for (i = j = 0; i < argc; i++)
894 {
895 if (argv[i][0] != ';')
896 argv[j++] = argv[i];
897 }
898 argv[j] = NULL;
899 *pargc = j;
900 *pargv = argv;
901 }
902 else
903 {
904 *pargc = 0;
905 *pargv = NULL;
906 }
907 }
908
884 int 909 int
885 _message_is_external_body (mu_message_t msg, char ***env) 910 _message_is_external_body (mu_message_t msg, char ***env)
886 { 911 {
...@@ -895,22 +920,8 @@ _message_is_external_body (mu_message_t msg, char ***env) ...@@ -895,22 +920,8 @@ _message_is_external_body (mu_message_t msg, char ***env)
895 rc = subtype && strcmp (subtype, "external-body") == 0; 920 rc = subtype && strcmp (subtype, "external-body") == 0;
896 if (rc && env) 921 if (rc && env)
897 { 922 {
898 int argc; 923 int c;
899 char **argv; 924 split_args (argstr, &c, env);
900 if (mu_argcv_get (argstr, ";", NULL, &argc, &argv) == 0)
901 {
902 int i, j;
903
904 for (i = j = 0; i < argc; i++)
905 {
906 if (argv[i][0] != ';')
907 argv[j++] = argv[i];
908 }
909 argv[j] = NULL;
910 *env = argv;
911 }
912 else
913 *env = NULL;
914 } 925 }
915 926
916 free (typestr); 927 free (typestr);
...@@ -1371,7 +1382,7 @@ show_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, ...@@ -1371,7 +1382,7 @@ show_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
1371 return 0; 1382 return 0;
1372 1383
1373 mu_stream_get_transport (out, &trans); 1384 mu_stream_get_transport (out, &trans);
1374 fd = trans; 1385 fd = (int) trans; /* FIXME */
1375 1386
1376 if (mode_options & OPT_PAUSE) 1387 if (mode_options & OPT_PAUSE)
1377 flags |= MHN_CONFIRM; 1388 flags |= MHN_CONFIRM;
...@@ -1381,7 +1392,7 @@ show_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, ...@@ -1381,7 +1392,7 @@ show_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
1381 if (flags & MHN_LISTING) 1392 if (flags & MHN_LISTING)
1382 { 1393 {
1383 char *str; 1394 char *str;
1384 char *p; 1395 const char *p;
1385 size_t size = 0; 1396 size_t size = 0;
1386 1397
1387 str = _("part "); 1398 str = _("part ");
...@@ -2016,7 +2027,7 @@ finish_text_msg (struct compose_env *env, mu_message_t *msg, int ascii) ...@@ -2016,7 +2027,7 @@ finish_text_msg (struct compose_env *env, mu_message_t *msg, int ascii)
2016 mu_message_create (&newmsg, NULL); 2027 mu_message_create (&newmsg, NULL);
2017 mu_message_get_header (newmsg, &hdr); 2028 mu_message_get_header (newmsg, &hdr);
2018 mu_header_set_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, 2029 mu_header_set_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING,
2019 "quoted-printable", 0); 2030 "quoted-printable", 0);
2020 2031
2021 mu_message_get_body (newmsg, &body); 2032 mu_message_get_body (newmsg, &body);
2022 mu_body_get_stream (body, &output); 2033 mu_body_get_stream (body, &output);
...@@ -2408,7 +2419,10 @@ mhn_edit (struct compose_env *env, int level) ...@@ -2408,7 +2419,10 @@ mhn_edit (struct compose_env *env, int level)
2408 if (tok[1] == 0) 2419 if (tok[1] == 0)
2409 /* starts a new message */; 2420 /* starts a new message */;
2410 else if (tok[1] == '<') 2421 else if (tok[1] == '<')
2411 status = edit_modify (tok+2, env, &msg); 2422 {
2423 *sp = c;
2424 status = edit_modify (tok+2, env, &msg);
2425 }
2412 else if (tok[1] == '@') 2426 else if (tok[1] == '@')
2413 { 2427 {
2414 *sp = c; 2428 *sp = c;
...@@ -2499,6 +2513,136 @@ copy_header (mu_message_t msg, mu_stream_t stream) ...@@ -2499,6 +2513,136 @@ copy_header (mu_message_t msg, mu_stream_t stream)
2499 } 2513 }
2500 2514
2501 int 2515 int
2516 parse_header_directive (char *val, char **encoding, char **charset, char **subject)
2517 {
2518 char *p;
2519
2520 /* Provide default values */
2521 *encoding = NULL;
2522 *charset = NULL;
2523 *subject = val;
2524
2525 if (*val != '#')
2526 return 1;
2527 val++;
2528
2529 switch (*val)
2530 {
2531 case '#':
2532 *subject = val;
2533 return 1;
2534
2535 case '<':
2536 for (p = val; *p; p++)
2537 if (*p == '>')
2538 {
2539 int i, argc;
2540 char **argv;
2541
2542 *subject = p + 1;
2543 *p = 0;
2544 split_args (val + 1, &argc, &argv);
2545 for (i = 0; i < argc; i++)
2546 {
2547 if (strlen (argv[i]) > 8
2548 && memcmp (argv[i], "charset=", 8) == 0)
2549 {
2550 free (*charset);
2551 *charset = strdup (argv[i] + 8);
2552 }
2553 else if (strlen (argv[i]) > 9
2554 && memcmp (argv[i], "encoding=", 9) == 0)
2555 {
2556 free (*encoding);
2557 *encoding = strdup (argv[i] + 9);
2558 }
2559 }
2560 mu_argcv_free (argc, argv);
2561 return 0;
2562 }
2563 break;
2564 }
2565 return 1;
2566 }
2567
2568
2569 void
2570 mhn_header (mu_message_t msg, mu_message_t omsg)
2571 {
2572 mu_header_t hdr = NULL;
2573 char *val;
2574
2575 mu_message_get_header (msg, &hdr);
2576 if (mu_header_aget_value (hdr, MU_HEADER_SUBJECT, &val) == 0)
2577 {
2578 char *subject, *encoding, *charset;
2579
2580 if (parse_header_directive (val, &encoding, &charset, &subject))
2581 {
2582 if (has_nonascii (val, strlen (val)))
2583 {
2584 int ismime = 0;
2585 mu_message_t part = NULL;
2586
2587 mu_message_is_multipart (omsg, &ismime);
2588 if (ismime)
2589 mu_message_get_part (omsg, 1, &part);
2590 else
2591 part = omsg;
2592 if (part);
2593 {
2594 mu_header_t parthdr = NULL;
2595 char *typestr, *typeargs;
2596
2597 mu_message_get_header (part, &parthdr);
2598 _get_content_type (parthdr, &typestr, &typeargs);
2599 _get_content_encoding (parthdr, &encoding);
2600 if (typeargs)
2601 {
2602 int i, argc;
2603 char **argv;
2604
2605 split_args (typeargs, &argc, &argv);
2606 for (i = 0; i < argc; i++)
2607 if (strlen (argv[i]) > 8
2608 && memcmp (argv[i], "charset=", 8) == 0)
2609 {
2610 charset = strdup (argv[i]+8);
2611 break;
2612 }
2613 mu_argcv_free (argc, argv);
2614 }
2615 free (typestr);
2616 }
2617 }
2618 }
2619
2620 if (charset)
2621 {
2622 char *p;
2623 int rc;
2624
2625 if (!encoding || strcmp (encoding, "7bit") == 0)
2626 {
2627 free (encoding);
2628 encoding = strdup ("base64");
2629 }
2630 rc = mu_rfc2047_encode (charset, encoding, subject, &p);
2631 if (rc)
2632 mu_error (_("cannot encode subject using %s, %s: %s"),
2633 charset, encoding, mu_strerror (rc));
2634 else
2635 {
2636 mu_header_set_value (hdr, MU_HEADER_SUBJECT, p, 1);
2637 free (p);
2638 }
2639 }
2640 free (charset);
2641 free (encoding);
2642 }
2643 }
2644
2645 int
2502 mhn_compose () 2646 mhn_compose ()
2503 { 2647 {
2504 int rc; 2648 int rc;
...@@ -2518,12 +2662,13 @@ mhn_compose () ...@@ -2518,12 +2662,13 @@ mhn_compose ()
2518 env.mime = mime; 2662 env.mime = mime;
2519 env.input = stream; 2663 env.input = stream;
2520 env.subpart = 0; 2664 env.subpart = 0;
2665 env.line = 0;
2521 rc = mhn_edit (&env, 0); 2666 rc = mhn_edit (&env, 0);
2522 if (rc) 2667 if (rc)
2523 return rc; 2668 return rc;
2524 2669
2525 mu_mime_get_message (mime, &msg); 2670 mu_mime_get_message (mime, &msg);
2526 2671
2527 p = strrchr (input_file, '/'); 2672 p = strrchr (input_file, '/');
2528 /* Prepare file names */ 2673 /* Prepare file names */
2529 if (p) 2674 if (p)
...@@ -2558,7 +2703,8 @@ mhn_compose () ...@@ -2558,7 +2703,8 @@ mhn_compose ()
2558 mu_stream_destroy (&stream, mu_stream_get_owner (stream)); 2703 mu_stream_destroy (&stream, mu_stream_get_owner (stream));
2559 return rc; 2704 return rc;
2560 } 2705 }
2561 2706
2707 mhn_header (message, msg);
2562 copy_header (message, stream); 2708 copy_header (message, stream);
2563 mu_message_get_stream (msg, &in); 2709 mu_message_get_stream (msg, &in);
2564 cat_message (stream, in); 2710 cat_message (stream, in);
......