MH send: improve compatibility with MH/nmh.
Showing
1 changed file
with
153 additions
and
63 deletions
... | @@ -35,8 +35,8 @@ static struct argp_option options[] = { | ... | @@ -35,8 +35,8 @@ static struct argp_option options[] = { |
35 | N_("use prepared draft") }, | 35 | N_("use prepared draft") }, |
36 | {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0, | 36 | {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0, |
37 | N_("specify the folder for message drafts") }, | 37 | N_("specify the folder for message drafts") }, |
38 | {"draftmessage", ARG_DRAFTMESSAGE, NULL, 0, | 38 | {"draftmessage", ARG_DRAFTMESSAGE, N_("MSG"), 0, |
39 | N_("treat the arguments as a list of messages from the draftfolder") }, | 39 | N_("use MSG from the draftfolder as a draft") }, |
40 | {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0, | 40 | {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0, |
41 | N_("undo the effect of the last --draftfolder option") }, | 41 | N_("undo the effect of the last --draftfolder option") }, |
42 | {"filter", ARG_FILTER, N_("FILE"), 0, | 42 | {"filter", ARG_FILTER, N_("FILE"), 0, |
... | @@ -99,9 +99,10 @@ struct mh_option mh_option[] = { | ... | @@ -99,9 +99,10 @@ struct mh_option mh_option[] = { |
99 | { NULL } | 99 | { NULL } |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static int use_draft; /* Use the prepared draft */ | ||
103 | static const char *draftfolder; /* Use this draft folder */ | 102 | static const char *draftfolder; /* Use this draft folder */ |
104 | static char *draftmessage = "cur"; | 103 | static int use_draftfolder = 1; |
104 | static int use_draft; | ||
105 | |||
105 | static int reformat_recipients; /* --format option */ | 106 | static int reformat_recipients; /* --format option */ |
106 | static int forward_notice; /* Forward the failure notice to the sender, | 107 | static int forward_notice; /* Forward the failure notice to the sender, |
107 | --forward flag */ | 108 | --forward flag */ |
... | @@ -126,6 +127,9 @@ static int keep_files; /* Keep draft files */ | ... | @@ -126,6 +127,9 @@ static int keep_files; /* Keep draft files */ |
126 | watch_printf c;\ | 127 | watch_printf c;\ |
127 | } while (0) | 128 | } while (0) |
128 | 129 | ||
130 | static int add_file (char *name); | ||
131 | static void mesg_list_fixup (void); | ||
132 | |||
129 | static error_t | 133 | static error_t |
130 | opt_handler (int key, char *arg, struct argp_state *state) | 134 | opt_handler (int key, char *arg, struct argp_state *state) |
131 | { | 135 | { |
... | @@ -152,14 +156,16 @@ opt_handler (int key, char *arg, struct argp_state *state) | ... | @@ -152,14 +156,16 @@ opt_handler (int key, char *arg, struct argp_state *state) |
152 | 156 | ||
153 | case ARG_DRAFTFOLDER: | 157 | case ARG_DRAFTFOLDER: |
154 | draftfolder = arg; | 158 | draftfolder = arg; |
159 | use_draftfolder = 1; | ||
155 | break; | 160 | break; |
156 | 161 | ||
157 | case ARG_NODRAFTFOLDER: | 162 | case ARG_NODRAFTFOLDER: |
158 | draftfolder = NULL; | 163 | draftfolder = NULL; |
164 | use_draftfolder = 0; | ||
159 | break; | 165 | break; |
160 | 166 | ||
161 | case ARG_DRAFTMESSAGE: | 167 | case ARG_DRAFTMESSAGE: |
162 | draftmessage = arg; | 168 | add_file (arg); |
163 | break; | 169 | break; |
164 | 170 | ||
165 | case ARG_FILTER: | 171 | case ARG_FILTER: |
... | @@ -284,30 +290,58 @@ static mu_list_t mesg_list; | ... | @@ -284,30 +290,58 @@ static mu_list_t mesg_list; |
284 | static mu_property_t mts_profile; | 290 | static mu_property_t mts_profile; |
285 | 291 | ||
286 | int | 292 | int |
287 | check_file (char *name) | 293 | add_file (char *name) |
288 | { | 294 | { |
289 | struct list_elt *elt; | 295 | struct list_elt *elt; |
290 | mu_message_t msg; | 296 | |
291 | char *file_name = mh_expand_name (draftfolder, name, 0); | ||
292 | |||
293 | msg = mh_file_to_message (NULL, file_name); | ||
294 | if (!msg) | ||
295 | { | ||
296 | free (file_name); | ||
297 | return 1; | ||
298 | } | ||
299 | if (!mesg_list && mu_list_create (&mesg_list)) | 297 | if (!mesg_list && mu_list_create (&mesg_list)) |
300 | { | 298 | { |
301 | free (file_name); | ||
302 | mu_error (_("cannot create message list")); | 299 | mu_error (_("cannot create message list")); |
303 | return 1; | 300 | return 1; |
304 | } | 301 | } |
302 | |||
305 | elt = mu_alloc (sizeof *elt); | 303 | elt = mu_alloc (sizeof *elt); |
306 | elt->file_name = file_name; | 304 | elt->file_name = name; |
307 | elt->msg = msg; | 305 | elt->msg = NULL; |
308 | return mu_list_append (mesg_list, elt); | 306 | return mu_list_append (mesg_list, elt); |
309 | } | 307 | } |
310 | 308 | ||
309 | int | ||
310 | checkdraft (const char *name) | ||
311 | { | ||
312 | struct stat st; | ||
313 | |||
314 | if (stat (name, &st)) | ||
315 | { | ||
316 | mu_error (_("unable to stat draft file %s: %s"), name, | ||
317 | mu_strerror (errno)); | ||
318 | return 1; | ||
319 | } | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | int | ||
324 | elt_fixup (void *item, void *data) | ||
325 | { | ||
326 | struct list_elt *elt = item; | ||
327 | |||
328 | elt->file_name = mh_expand_name (draftfolder, elt->file_name, 0); | ||
329 | if (checkdraft (elt->file_name)) | ||
330 | exit (1); | ||
331 | elt->msg = mh_file_to_message (NULL, elt->file_name); | ||
332 | if (!elt->msg) | ||
333 | return 1; | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | void | ||
339 | mesg_list_fixup () | ||
340 | { | ||
341 | if (mesg_list && mu_list_foreach (mesg_list, elt_fixup, NULL)) | ||
342 | exit (1); | ||
343 | } | ||
344 | |||
311 | void | 345 | void |
312 | read_mts_profile () | 346 | read_mts_profile () |
313 | { | 347 | { |
... | @@ -741,11 +775,25 @@ _add_to_mesg_list (size_t num, mu_message_t msg, void *data) | ... | @@ -741,11 +775,25 @@ _add_to_mesg_list (size_t num, mu_message_t msg, void *data) |
741 | struct list_elt *elt; | 775 | struct list_elt *elt; |
742 | size_t uid; | 776 | size_t uid; |
743 | int rc; | 777 | int rc; |
778 | char *file_name; | ||
779 | |||
780 | if (!mesg_list && mu_list_create (&mesg_list)) | ||
781 | { | ||
782 | mu_error (_("cannot create message list")); | ||
783 | return 1; | ||
784 | } | ||
785 | |||
786 | mu_message_get_uid (msg, &uid); | ||
787 | file_name = mu_make_file_name (path, mu_umaxtostr (0, uid)); | ||
788 | if (!use_draft) | ||
789 | { | ||
790 | if (!mh_usedraft (file_name)) | ||
791 | exit (0); | ||
792 | } | ||
744 | 793 | ||
745 | elt = mu_alloc (sizeof *elt); | 794 | elt = mu_alloc (sizeof *elt); |
746 | elt->msg = msg; | 795 | elt->msg = msg; |
747 | mu_message_get_uid (msg, &uid); | 796 | elt->file_name = file_name; |
748 | elt->file_name = mu_make_file_name (path, mu_umaxtostr (0, uid)); | ||
749 | rc = mu_list_append (mesg_list, elt); | 797 | rc = mu_list_append (mesg_list, elt); |
750 | if (rc) | 798 | if (rc) |
751 | { | 799 | { |
... | @@ -755,6 +803,57 @@ _add_to_mesg_list (size_t num, mu_message_t msg, void *data) | ... | @@ -755,6 +803,57 @@ _add_to_mesg_list (size_t num, mu_message_t msg, void *data) |
755 | return 0; | 803 | return 0; |
756 | } | 804 | } |
757 | 805 | ||
806 | static void | ||
807 | addfolder (const char *folder, int argc, char **argv) | ||
808 | { | ||
809 | mu_url_t url; | ||
810 | const char *path; | ||
811 | mu_msgset_t msgset; | ||
812 | |||
813 | mu_mailbox_t mbox = mh_open_folder (folder, MU_STREAM_READ); | ||
814 | if (!mbox) | ||
815 | { | ||
816 | mu_error (_("cannot open folder %s: %s"), folder, | ||
817 | mu_strerror (errno)); | ||
818 | exit (1); | ||
819 | } | ||
820 | |||
821 | mh_msgset_parse (&msgset, mbox, argc, argv, "cur"); | ||
822 | if (!use_draft) | ||
823 | { | ||
824 | size_t count = 0; | ||
825 | mu_msgset_count (msgset, &count); | ||
826 | if (count > 1) | ||
827 | use_draft = 1; | ||
828 | } | ||
829 | |||
830 | mu_mailbox_get_url (mbox, &url); | ||
831 | mu_url_sget_path (url, &path); | ||
832 | mu_msgset_foreach_message (msgset, _add_to_mesg_list, (void*)path); | ||
833 | |||
834 | mu_msgset_free (msgset); | ||
835 | } | ||
836 | |||
837 | /* Usage cases: | ||
838 | * | ||
839 | * 1. send | ||
840 | * a) If Draft-Folder is set: ask whether to use "cur" message from that | ||
841 | * folder as a draft; | ||
842 | * b) If Draft-Folder is not set: ask whether to use $(Path)/draft; | ||
843 | * 2. send -draft | ||
844 | * Use $(Path)/draft | ||
845 | * 3. send MSG | ||
846 | * Use $(Path)/MSG | ||
847 | * 4. send -draftmessage MSG | ||
848 | * Same as (3) | ||
849 | * 5. send -draftfolder DIR | ||
850 | * Use "cur" from that folder | ||
851 | * 6. send -draftfolder DIR MSG | ||
852 | * Use MSG from folder DIR | ||
853 | * 7. send -draftfolder DIR -draftmessage MSG | ||
854 | * Same as 6. | ||
855 | */ | ||
856 | |||
758 | int | 857 | int |
759 | main (int argc, char **argv) | 858 | main (int argc, char **argv) |
760 | { | 859 | { |
... | @@ -768,61 +867,52 @@ main (int argc, char **argv) | ... | @@ -768,61 +867,52 @@ main (int argc, char **argv) |
768 | mh_argp_init (); | 867 | mh_argp_init (); |
769 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, | 868 | mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc, |
770 | opt_handler, NULL, &index); | 869 | opt_handler, NULL, &index); |
870 | argc -= index; | ||
871 | argv += index; | ||
771 | 872 | ||
772 | mh_read_aliases (); | 873 | mh_read_aliases (); |
773 | /* Process the mtstailor file */ | 874 | /* Process the mtstailor file */ |
774 | read_mts_profile (); | 875 | read_mts_profile (); |
775 | 876 | ||
776 | argc -= index; | 877 | if (!draftfolder) |
777 | argv += index; | ||
778 | |||
779 | if (draftfolder) | ||
780 | { | 878 | { |
781 | mu_msgset_t msgset; | 879 | if (mu_list_is_empty (mesg_list) && argc == 0) |
782 | mu_url_t url; | ||
783 | const char *path; | ||
784 | |||
785 | mbox = mh_open_folder (draftfolder, MU_STREAM_RDWR|MU_STREAM_CREAT); | ||
786 | mh_msgset_parse (&msgset, mbox, argc, argv, draftmessage); | ||
787 | mu_mailbox_get_url (mbox, &url); | ||
788 | mu_url_sget_path (url, &path); | ||
789 | if ((rc = mu_list_create (&mesg_list))) | ||
790 | { | 880 | { |
791 | mu_error (_("cannot create message list: %s"), mu_strerror (rc)); | 881 | char *dfolder = |
792 | exit (1); | 882 | (!use_draft && use_draftfolder) ? |
793 | } | 883 | mh_global_profile_get ("Draft-Folder", NULL) : NULL; |
794 | mu_msgset_foreach_message (msgset, _add_to_mesg_list, (void*)path); | ||
795 | |||
796 | mu_msgset_free (msgset); | ||
797 | } | ||
798 | else | ||
799 | { | ||
800 | int i; | ||
801 | |||
802 | if (argc == 0) | ||
803 | { | ||
804 | char *xargv[2]; | ||
805 | struct stat st; | ||
806 | |||
807 | xargv[0] = mh_draft_name (); | ||
808 | 884 | ||
809 | if (stat (xargv[0], &st)) | 885 | if (dfolder) |
886 | addfolder (dfolder, 0, NULL); | ||
887 | else | ||
810 | { | 888 | { |
811 | mu_diag_funcall (MU_DIAG_ERROR, "stat", xargv[0], errno); | 889 | char *df = mh_expand_name (mu_folder_directory (), "draft", 0); |
812 | return 1; | 890 | if (checkdraft (df)) |
891 | exit (1); | ||
892 | if (!use_draft && !mh_usedraft (df)) | ||
893 | exit (0); | ||
894 | add_file (df); | ||
895 | mesg_list_fixup (); | ||
813 | } | 896 | } |
814 | |||
815 | if (!use_draft && !mh_usedraft (xargv[0])) | ||
816 | exit (0); | ||
817 | xargv[1] = NULL; | ||
818 | argv = xargv; | ||
819 | argc = 1; | ||
820 | } | 897 | } |
821 | for (i = 0; i < argc; i++) | 898 | else |
822 | if (check_file (argv[i])) | 899 | { |
823 | return 1; | 900 | while (argc--) |
901 | add_file (*argv++); | ||
902 | mesg_list_fixup (); | ||
903 | } | ||
824 | } | 904 | } |
825 | 905 | else | |
906 | { | ||
907 | /* -draftfolder is supplied */ | ||
908 | draftfolder = mh_expand_name (mu_folder_directory (), | ||
909 | draftfolder, 0); | ||
910 | use_draft = 1; | ||
911 | mesg_list_fixup (); | ||
912 | if (mu_list_is_empty (mesg_list) || argc != 0) | ||
913 | addfolder (draftfolder, argc, argv); | ||
914 | } | ||
915 | |||
826 | /* Detach from the console if required */ | 916 | /* Detach from the console if required */ |
827 | if (background && daemon (0, 0) < 0) | 917 | if (background && daemon (0, 0) < 0) |
828 | { | 918 | { | ... | ... |
-
Please register or sign in to post a comment