mail: rewrite using MU streams.
* libmailutils/base/spawnvp.c (mu_spawnvp): Use fork and _exit, unconditionally. * libmailutils/stdstream/basestr.c (mu_stdstream_setup): Borrow descriptors 0, 1, 2. * mail/mail.h (compose_env) <filename, file, ofile>: Remove. <compstr>: New member. * mail/alias.c: Use MU streams instead of stdlib. * mail/alt.c: Likewise. * mail/copy.c: Likewise. * mail/decode.c: Likewise. * mail/echo.c: Likewise. * mail/envelope.c: Likewise. * mail/eq.c: Likewise. * mail/escape.c: Likewise. * mail/followup.c: Likewise. * mail/from.c: Likewise. * mail/inc.c: Likewise. * mail/mail.c: Likewise. * mail/mailline.c: Likewise. * mail/mailvar.c: Likewise. * mail/msgset.y: Likewise. * mail/print.c: Likewise. * mail/quit.c: Likewise. * mail/reply.c: Likewise. * mail/retain.c: Likewise. * mail/send.c: Likewise. * mail/setenv.c: Likewise. * mail/shell.c: Likewise. * mail/size.c: Likewise. * mail/source.c: Likewise. * mail/summary.c: Likewise. * mail/top.c: Likewise. * mail/unset.c: Likewise. * mail/util.c: Likewise. * mail/version.c: Likewise. * mail/write.c: Likewise. * mail/z.c: Likewise.
Showing
35 changed files
with
714 additions
and
841 deletions
... | @@ -70,11 +70,7 @@ mu_spawnvp (const char *prog, char *av[], int *stat) | ... | @@ -70,11 +70,7 @@ mu_spawnvp (const char *prog, char *av[], int *stat) |
70 | return errno; | 70 | return errno; |
71 | } | 71 | } |
72 | 72 | ||
73 | #ifdef HAVE_VFORK | ||
74 | pid = vfork (); | ||
75 | #else | ||
76 | pid = fork (); | 73 | pid = fork (); |
77 | #endif | ||
78 | 74 | ||
79 | if (pid < 0) | 75 | if (pid < 0) |
80 | { | 76 | { |
... | @@ -88,11 +84,7 @@ mu_spawnvp (const char *prog, char *av[], int *stat) | ... | @@ -88,11 +84,7 @@ mu_spawnvp (const char *prog, char *av[], int *stat) |
88 | sigprocmask (SIG_SETMASK, &savemask, NULL); | 84 | sigprocmask (SIG_SETMASK, &savemask, NULL); |
89 | 85 | ||
90 | execvp (prog, av); | 86 | execvp (prog, av); |
91 | #ifdef HAVE__EXIT | ||
92 | _exit (127); /* exec error */ | 87 | _exit (127); /* exec error */ |
93 | #else | ||
94 | exit (127); | ||
95 | #endif | ||
96 | } | 88 | } |
97 | else | 89 | else |
98 | { /* parent */ | 90 | { /* parent */ | ... | ... |
... | @@ -46,7 +46,8 @@ mu_stdstream_setup () | ... | @@ -46,7 +46,8 @@ mu_stdstream_setup () |
46 | { | 46 | { |
47 | int rc; | 47 | int rc; |
48 | int fd; | 48 | int fd; |
49 | 49 | int yes = 1; | |
50 | |||
50 | /* If the streams are already open, close them */ | 51 | /* If the streams are already open, close them */ |
51 | mu_stream_destroy (&mu_strin); | 52 | mu_stream_destroy (&mu_strin); |
52 | mu_stream_destroy (&mu_strout); | 53 | mu_stream_destroy (&mu_strout); |
... | @@ -90,6 +91,8 @@ mu_stdstream_setup () | ... | @@ -90,6 +91,8 @@ mu_stdstream_setup () |
90 | MU_STDIN_FD, mu_strerror (rc)); | 91 | MU_STDIN_FD, mu_strerror (rc)); |
91 | abort (); | 92 | abort (); |
92 | } | 93 | } |
94 | mu_stream_ioctl (mu_strin, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes); | ||
95 | |||
93 | rc = mu_stdio_stream_create (&mu_strout, MU_STDOUT_FD, 0); | 96 | rc = mu_stdio_stream_create (&mu_strout, MU_STDOUT_FD, 0); |
94 | if (rc) | 97 | if (rc) |
95 | { | 98 | { |
... | @@ -97,6 +100,7 @@ mu_stdstream_setup () | ... | @@ -97,6 +100,7 @@ mu_stdstream_setup () |
97 | MU_STDOUT_FD, mu_strerror (rc)); | 100 | MU_STDOUT_FD, mu_strerror (rc)); |
98 | abort (); | 101 | abort (); |
99 | } | 102 | } |
103 | mu_stream_ioctl (mu_strout, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes); | ||
100 | 104 | ||
101 | if (mu_stdstream_strerr_create (&mu_strerr, MU_STRERR_STDERR, 0, 0, | 105 | if (mu_stdstream_strerr_create (&mu_strerr, MU_STRERR_STDERR, 0, 0, |
102 | mu_program_name, NULL)) | 106 | mu_program_name, NULL)) | ... | ... |
... | @@ -36,9 +36,9 @@ alias_free (void *data) | ... | @@ -36,9 +36,9 @@ alias_free (void *data) |
36 | static void | 36 | static void |
37 | alias_print_group (const char *name, alias_t al) | 37 | alias_print_group (const char *name, alias_t al) |
38 | { | 38 | { |
39 | fprintf (ofile, "%s ", name); | 39 | mu_stream_printf (ostream, "%s ", name); |
40 | util_slist_print (al->list, 0); | 40 | util_slist_print (al->list, 0); |
41 | fprintf (ofile, "\n"); | 41 | mu_stream_printf (ostream, "\n"); |
42 | } | 42 | } |
43 | 43 | ||
44 | static alias_t | 44 | static alias_t | ... | ... |
... | @@ -34,7 +34,7 @@ mail_alt (int argc, char **argv) | ... | @@ -34,7 +34,7 @@ mail_alt (int argc, char **argv) |
34 | if (alternate_names) | 34 | if (alternate_names) |
35 | { | 35 | { |
36 | util_slist_print (alternate_names, 0); | 36 | util_slist_print (alternate_names, 0); |
37 | fprintf (ofile, "\n"); | 37 | mu_stream_printf (ostream, "\n"); |
38 | } | 38 | } |
39 | } | 39 | } |
40 | else | 40 | else | ... | ... |
... | @@ -106,7 +106,7 @@ mail_copy0 (int argc, char **argv, int mark) | ... | @@ -106,7 +106,7 @@ mail_copy0 (int argc, char **argv, int mark) |
106 | } | 106 | } |
107 | 107 | ||
108 | if (status == 0) | 108 | if (status == 0) |
109 | fprintf (ofile, "\"%s\" %3lu/%-5lu\n", filename, | 109 | mu_stream_printf (ostream, "\"%s\" %3lu/%-5lu\n", filename, |
110 | (unsigned long) total_lines, (unsigned long) total_size); | 110 | (unsigned long) total_lines, (unsigned long) total_size); |
111 | 111 | ||
112 | mu_mailbox_close (mbx); | 112 | mu_mailbox_close (mbx); | ... | ... |
... | @@ -29,7 +29,7 @@ struct decode_closure | ... | @@ -29,7 +29,7 @@ struct decode_closure |
29 | int select_hdr; | 29 | int select_hdr; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | static int print_stream (mu_stream_t, FILE *); | 32 | static int print_stream (mu_stream_t, mu_stream_t); |
33 | static int display_message (mu_message_t, msgset_t *msgset, void *closure); | 33 | static int display_message (mu_message_t, msgset_t *msgset, void *closure); |
34 | static int display_submessage (struct mime_descend_closure *closure, | 34 | static int display_submessage (struct mime_descend_closure *closure, |
35 | void *data); | 35 | void *data); |
... | @@ -81,7 +81,7 @@ display_message (mu_message_t mesg, msgset_t *msgset, void *arg) | ... | @@ -81,7 +81,7 @@ display_message (mu_message_t mesg, msgset_t *msgset, void *arg) |
81 | } | 81 | } |
82 | 82 | ||
83 | static void | 83 | static void |
84 | display_headers (FILE *out, mu_message_t mesg, | 84 | display_headers (mu_stream_t out, mu_message_t mesg, |
85 | const msgset_t *msgset MU_ARG_UNUSED, | 85 | const msgset_t *msgset MU_ARG_UNUSED, |
86 | int select_hdr) | 86 | int select_hdr) |
87 | { | 87 | { |
... | @@ -102,13 +102,13 @@ display_headers (FILE *out, mu_message_t mesg, | ... | @@ -102,13 +102,13 @@ display_headers (FILE *out, mu_message_t mesg, |
102 | continue; | 102 | continue; |
103 | if (mail_header_is_visible (sptr)) | 103 | if (mail_header_is_visible (sptr)) |
104 | { | 104 | { |
105 | fprintf (out, "%s: ", sptr); | 105 | mu_stream_printf (out, "%s: ", sptr); |
106 | if (mu_header_sget_field_value (hdr, i, &sptr)) | 106 | if (mu_header_sget_field_value (hdr, i, &sptr)) |
107 | sptr = ""; | 107 | sptr = ""; |
108 | fprintf (out, "%s\n", sptr); | 108 | mu_stream_printf (out, "%s\n", sptr); |
109 | } | 109 | } |
110 | } | 110 | } |
111 | fprintf (out, "\n"); | 111 | mu_stream_printf (out, "\n"); |
112 | } | 112 | } |
113 | else /* Print displays all headers. */ | 113 | else /* Print displays all headers. */ |
114 | { | 114 | { |
... | @@ -122,43 +122,50 @@ display_headers (FILE *out, mu_message_t mesg, | ... | @@ -122,43 +122,50 @@ display_headers (FILE *out, mu_message_t mesg, |
122 | } | 122 | } |
123 | } | 123 | } |
124 | 124 | ||
125 | size_t | 125 | void |
126 | fprint_msgset (FILE *fp, const msgset_t *msgset) | 126 | format_msgset (mu_stream_t str, const msgset_t *msgset, size_t *count) |
127 | { | 127 | { |
128 | int i; | 128 | int i; |
129 | size_t n = 0; | 129 | mu_stream_stat_buffer stat; |
130 | 130 | ||
131 | n = fprintf (fp, "%lu", (unsigned long) msgset->msg_part[0]); | 131 | if (count) |
132 | mu_stream_set_stat (str, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT), | ||
133 | stat); | ||
134 | mu_stream_printf (str, "%lu", (unsigned long) msgset->msg_part[0]); | ||
132 | for (i = 1; i < msgset->npart; i++) | 135 | for (i = 1; i < msgset->npart; i++) |
133 | n += fprintf (fp, "[%lu", (unsigned long) msgset->msg_part[i]); | 136 | mu_stream_printf (str, "[%lu", (unsigned long) msgset->msg_part[i]); |
134 | for (i = 1; i < msgset->npart; i++) | 137 | for (i = 1; i < msgset->npart; i++) |
135 | n += fprintf (fp, "]"); | 138 | mu_stream_printf (str, "]"); |
136 | return n; | 139 | if (count) |
140 | { | ||
141 | *count = stat[MU_STREAM_STAT_OUT]; | ||
142 | mu_stream_set_stat (str, 0, NULL); | ||
143 | } | ||
137 | } | 144 | } |
138 | 145 | ||
139 | static void | 146 | static void |
140 | display_part_header (FILE *out, const msgset_t *msgset, | 147 | display_part_header (mu_stream_t str, const msgset_t *msgset, |
141 | const char *type, const char *encoding) | 148 | const char *type, const char *encoding) |
142 | { | 149 | { |
143 | int size = util_screen_columns () - 3; | 150 | int size = util_screen_columns () - 3; |
144 | unsigned int i; | 151 | unsigned int i; |
145 | 152 | ||
146 | fputc ('+', out); | 153 | mu_stream_printf (str, "+"); |
147 | for (i = 0; (int)i <= size; i++) | 154 | for (i = 0; (int)i <= size; i++) |
148 | fputc ('-', out); | 155 | mu_stream_printf (str, "-"); |
149 | fputc ('+', out); | 156 | mu_stream_printf (str, "+"); |
150 | fputc ('\n', out); | 157 | mu_stream_printf (str, "\n"); |
151 | fprintf (out, "%s", _("| Message=")); | 158 | mu_stream_printf (str, "%s", _("| Message=")); |
152 | fprint_msgset (out, msgset); | 159 | format_msgset (str, msgset, NULL); |
153 | fprintf (out, "\n"); | 160 | mu_stream_printf (str, "\n"); |
154 | 161 | ||
155 | fprintf (out, _("| Type=%s\n"), type); | 162 | mu_stream_printf (str, _("| Type=%s\n"), type); |
156 | fprintf (out, _("| Encoding=%s\n"), encoding); | 163 | mu_stream_printf (str, _("| Encoding=%s\n"), encoding); |
157 | fputc ('+', out); | 164 | mu_stream_printf (str, "+"); |
158 | for (i = 0; (int)i <= size; i++) | 165 | for (i = 0; i <= size; i++) |
159 | fputc ('-', out); | 166 | mu_stream_printf (str, "-"); |
160 | fputc ('+', out); | 167 | mu_stream_printf (str, "+"); |
161 | fputc ('\n', out); | 168 | mu_stream_printf (str, "\n"); |
162 | } | 169 | } |
163 | 170 | ||
164 | int | 171 | int |
... | @@ -268,7 +275,8 @@ display_submessage (struct mime_descend_closure *closure, void *data) | ... | @@ -268,7 +275,8 @@ display_submessage (struct mime_descend_closure *closure, void *data) |
268 | else | 275 | else |
269 | stream = b_stream; | 276 | stream = b_stream; |
270 | 277 | ||
271 | display_part_header (ofile, closure->msgset, | 278 | display_part_header (ostream, |
279 | closure->msgset, | ||
272 | closure->type, closure->encoding); | 280 | closure->type, closure->encoding); |
273 | 281 | ||
274 | /* If `metamail' is set to true, enable internal mailcap | 282 | /* If `metamail' is set to true, enable internal mailcap |
... | @@ -290,22 +298,17 @@ display_submessage (struct mime_descend_closure *closure, void *data) | ... | @@ -290,22 +298,17 @@ display_submessage (struct mime_descend_closure *closure, void *data) |
290 | if (builtin_display) | 298 | if (builtin_display) |
291 | { | 299 | { |
292 | size_t lines = 0; | 300 | size_t lines = 0; |
293 | int pagelines = util_get_crt (); | 301 | mu_stream_t str; |
294 | FILE *out; | ||
295 | 302 | ||
296 | mu_message_lines (closure->message, &lines); | 303 | mu_message_lines (closure->message, &lines); |
297 | if (pagelines && lines > pagelines) | 304 | str = open_pager (lines); |
298 | out = popen (getenv ("PAGER"), "w"); | ||
299 | else | ||
300 | out = ofile; | ||
301 | 305 | ||
302 | display_headers (out, closure->message, closure->msgset, | 306 | display_headers (str, closure->message, closure->msgset, |
303 | closure->hints & MDHINT_SELECTED_HEADERS); | 307 | closure->hints & MDHINT_SELECTED_HEADERS); |
304 | 308 | ||
305 | print_stream (stream, out); | 309 | print_stream (stream, str); |
306 | 310 | ||
307 | if (out != ofile) | 311 | mu_stream_unref (str); |
308 | pclose (out); | ||
309 | } | 312 | } |
310 | mu_stream_destroy (&stream); | 313 | mu_stream_destroy (&stream); |
311 | } | 314 | } |
... | @@ -315,7 +318,7 @@ display_submessage (struct mime_descend_closure *closure, void *data) | ... | @@ -315,7 +318,7 @@ display_submessage (struct mime_descend_closure *closure, void *data) |
315 | 318 | ||
316 | /* FIXME: Try to use mu_stream_copy instead */ | 319 | /* FIXME: Try to use mu_stream_copy instead */ |
317 | static int | 320 | static int |
318 | print_stream (mu_stream_t stream, FILE *out) | 321 | print_stream (mu_stream_t stream, mu_stream_t out) |
319 | { | 322 | { |
320 | char buffer[512]; | 323 | char buffer[512]; |
321 | size_t n = 0; | 324 | size_t n = 0; |
... | @@ -329,7 +332,7 @@ print_stream (mu_stream_t stream, FILE *out) | ... | @@ -329,7 +332,7 @@ print_stream (mu_stream_t stream, FILE *out) |
329 | break; | 332 | break; |
330 | } | 333 | } |
331 | buffer[n] = '\0'; | 334 | buffer[n] = '\0'; |
332 | fprintf (out, "%s", buffer); | 335 | mu_stream_printf (out, "%s", buffer); |
333 | } | 336 | } |
334 | return 0; | 337 | return 0; |
335 | } | 338 | } | ... | ... |
... | @@ -21,129 +21,55 @@ | ... | @@ -21,129 +21,55 @@ |
21 | * ec[ho] string ... | 21 | * ec[ho] string ... |
22 | */ | 22 | */ |
23 | 23 | ||
24 | static int echo (char *s); | 24 | static int |
25 | 25 | echo (char *s) | |
26 | int | ||
27 | mail_echo (int argc, char **argv) | ||
28 | { | 26 | { |
29 | int i = 0; | 27 | struct mu_wordsplit ws; |
30 | if (argc > 1) | 28 | size_t len = strlen (s); |
29 | int rc = 1; | ||
30 | |||
31 | /* FIXME: This logic is flawed */ | ||
32 | if (len > 0 && s[len - 1] == '\\') | ||
31 | { | 33 | { |
32 | for (i = 1; i < argc - 1; i++) | 34 | if (len == 1) |
35 | return 0; | ||
36 | if (s[len-2] != '\\') | ||
33 | { | 37 | { |
34 | echo (argv[i]); | 38 | --len; |
35 | fputc (' ', ofile); | 39 | rc = 0; |
36 | } | 40 | } |
37 | /* Last argument. */ | ||
38 | if (echo(argv[argc - 1]) == 0) | ||
39 | fputc ('\n', ofile); | ||
40 | } | 41 | } |
41 | return 0; | 42 | |
43 | |||
44 | if (mu_wordsplit_len (s, len, &ws, | ||
45 | MU_WRDSF_NOSPLIT | | ||
46 | MU_WRDSF_NOCMD | MU_WRDSF_NOVAR | MU_WRDSF_QUOTE)) | ||
47 | { | ||
48 | mu_error (_("cannot split `%s': %s"), s, | ||
49 | mu_wordsplit_strerror (&ws)); | ||
50 | } | ||
51 | else | ||
52 | { | ||
53 | mu_stream_printf (ostream, "%s", ws.ws_wordv[0]); | ||
54 | mu_wordsplit_free (&ws); | ||
55 | } | ||
56 | return rc; | ||
42 | } | 57 | } |
43 | 58 | ||
44 | /* Cumbersome switch for checking escape char '\' | 59 | int |
45 | if present replace with appropriately. | 60 | mail_echo (int argc, char **argv) |
46 | Return of 1 means to not print newline. */ | ||
47 | static int | ||
48 | echo (char *s) | ||
49 | { | 61 | { |
50 | int process_escape = 0; | 62 | if (argc > 1) |
51 | int c; | ||
52 | |||
53 | if (s == NULL) | ||
54 | return 0; | ||
55 | |||
56 | for (; (c = *s) != 0; s++) | ||
57 | { | 63 | { |
58 | if (process_escape) | 64 | int i = 0; |
65 | |||
66 | for (i = 1; i < argc; i++) | ||
59 | { | 67 | { |
60 | switch (c) | 68 | if (echo (argv[i])) |
61 | { | 69 | mu_stream_printf (ostream, " "); |
62 | /* \a Bell. */ | ||
63 | case 'a': | ||
64 | c = '\a'; | ||
65 | break; | ||
66 | |||
67 | /* \b Backspace. */ | ||
68 | case 'b': | ||
69 | c = '\b'; | ||
70 | break; | ||
71 | |||
72 | /* \c means not to print ending newline. */ | ||
73 | /* Bail out and tell the caller not to print newline. */ | ||
74 | case 'c': | ||
75 | return 1; | ||
76 | break; | ||
77 | |||
78 | /* \f Formfeed. */ | ||
79 | case 'f': | ||
80 | c = '\f'; | ||
81 | break; | ||
82 | |||
83 | /* \n Newline. */ | ||
84 | case 'n': | ||
85 | c = '\n'; | ||
86 | break; | ||
87 | |||
88 | /* \r Carriage return. */ | ||
89 | case 'r': | ||
90 | c = '\r'; | ||
91 | break; | ||
92 | |||
93 | /* \t Tab. */ | ||
94 | case 't': | ||
95 | c = '\t'; | ||
96 | break; | ||
97 | |||
98 | /* \v Vertical Tab. */ | ||
99 | case 'v': | ||
100 | c = '\v'; | ||
101 | break; | ||
102 | |||
103 | /* Escape sequence. */ | ||
104 | case '\\': | ||
105 | c = '\\'; | ||
106 | break; | ||
107 | |||
108 | /* \0x99 for example, let strtol() handle it. */ | ||
109 | /* WARNING: Side effects because of strtol(). */ | ||
110 | case '0': | ||
111 | { | ||
112 | long number = strtol (s, &s, 0); | ||
113 | switch (number) | ||
114 | { | ||
115 | case LONG_MIN: | ||
116 | case LONG_MAX: | ||
117 | /* if (errno == ERANGE) */ | ||
118 | /* fputc (c, ofile); */ | ||
119 | break; | ||
120 | |||
121 | default: | ||
122 | fprintf (ofile, "%ld", number); | ||
123 | s--; | ||
124 | continue; | ||
125 | } | ||
126 | } | ||
127 | break; | ||
128 | |||
129 | /* Can not be here. */ | ||
130 | case '\0': | ||
131 | return 0; | ||
132 | break; | ||
133 | |||
134 | /* \\ means \ It was not an escape char. */ | ||
135 | default: | ||
136 | fputc ('\\', ofile); | ||
137 | |||
138 | } | ||
139 | process_escape =0; | ||
140 | } | ||
141 | else if (c == '\\') /* Find the escape char, go back and process. */ | ||
142 | { | ||
143 | process_escape = 1; | ||
144 | continue; | ||
145 | } | 70 | } |
146 | fputc (c, ofile); | 71 | mu_stream_printf (ostream, "\n"); |
147 | } | 72 | } |
148 | return 0; | 73 | return 0; |
149 | } | 74 | } |
75 | ... | ... |
... | @@ -38,8 +38,8 @@ print_envelope (msgset_t *mspec, mu_message_t msg, void *data) | ... | @@ -38,8 +38,8 @@ print_envelope (msgset_t *mspec, mu_message_t msg, void *data) |
38 | mu_envelope_sget_sender (env, &sender); | 38 | mu_envelope_sget_sender (env, &sender); |
39 | mu_envelope_sget_date (env, &date); | 39 | mu_envelope_sget_date (env, &date); |
40 | if (data) | 40 | if (data) |
41 | fprintf (ofile, "%s ", (char*) data); | 41 | mu_stream_printf (ostream, "%s ", (char*) data); |
42 | fprintf (ofile, "%s %s", sender, date); | 42 | mu_stream_printf (ostream, "%s %s", sender, date); |
43 | } | 43 | } |
44 | return 0; | 44 | return 0; |
45 | } | 45 | } | ... | ... |
... | @@ -34,7 +34,7 @@ mail_eq (int argc, char **argv) | ... | @@ -34,7 +34,7 @@ mail_eq (int argc, char **argv) |
34 | if (n == 0) | 34 | if (n == 0) |
35 | util_error (_("No applicable message")); | 35 | util_error (_("No applicable message")); |
36 | else | 36 | else |
37 | fprintf (ofile, "%lu\n", (unsigned long) n); | 37 | mu_stream_printf (ostream, "%lu\n", (unsigned long) n); |
38 | break; | 38 | break; |
39 | 39 | ||
40 | case 2: | 40 | case 2: |
... | @@ -43,7 +43,8 @@ mail_eq (int argc, char **argv) | ... | @@ -43,7 +43,8 @@ mail_eq (int argc, char **argv) |
43 | if (list->msg_part[0] <= total) | 43 | if (list->msg_part[0] <= total) |
44 | { | 44 | { |
45 | set_cursor (list->msg_part[0]); | 45 | set_cursor (list->msg_part[0]); |
46 | fprintf (ofile, "%lu\n", (unsigned long) list->msg_part[0]); | 46 | mu_stream_printf (ostream, "%lu\n", |
47 | (unsigned long) list->msg_part[0]); | ||
47 | } | 48 | } |
48 | else | 49 | else |
49 | util_error_range (list->msg_part[0]); | 50 | util_error_range (list->msg_part[0]); | ... | ... |
... | @@ -21,11 +21,9 @@ | ... | @@ -21,11 +21,9 @@ |
21 | #include <sys/stat.h> | 21 | #include <sys/stat.h> |
22 | 22 | ||
23 | static void | 23 | static void |
24 | dump_headers (FILE *fp, compose_env_t *env) | 24 | dump_headers (mu_stream_t out, compose_env_t *env) |
25 | { | 25 | { |
26 | char buffer[512]; | ||
27 | mu_stream_t stream = NULL; | 26 | mu_stream_t stream = NULL; |
28 | size_t n; | ||
29 | int rc; | 27 | int rc; |
30 | 28 | ||
31 | rc = mu_header_get_streamref (env->header, &stream); | 29 | rc = mu_header_get_streamref (env->header, &stream); |
... | @@ -35,13 +33,7 @@ dump_headers (FILE *fp, compose_env_t *env) | ... | @@ -35,13 +33,7 @@ dump_headers (FILE *fp, compose_env_t *env) |
35 | mu_stream_strerror (stream, rc)); | 33 | mu_stream_strerror (stream, rc)); |
36 | return; | 34 | return; |
37 | } | 35 | } |
38 | /* FIXME: Use mu_stream_copy */ | 36 | mu_stream_copy (out, stream, 0, NULL); |
39 | while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0 | ||
40 | && n != 0) | ||
41 | { | ||
42 | buffer[n] = 0; | ||
43 | fprintf (fp, "%s", buffer); | ||
44 | } | ||
45 | mu_stream_destroy (&stream); | 37 | mu_stream_destroy (&stream); |
46 | } | 38 | } |
47 | 39 | ||
... | @@ -50,15 +42,15 @@ dump_headers (FILE *fp, compose_env_t *env) | ... | @@ -50,15 +42,15 @@ dump_headers (FILE *fp, compose_env_t *env) |
50 | #define STATE_BODY 2 | 42 | #define STATE_BODY 2 |
51 | 43 | ||
52 | static int | 44 | static int |
53 | parse_headers (FILE *fp, compose_env_t *env) | 45 | parse_headers (mu_stream_t input, compose_env_t *env) |
54 | { | 46 | { |
55 | int status; | 47 | int status; |
56 | mu_header_t header; | 48 | mu_header_t header; |
57 | char *name = NULL; | 49 | char *name = NULL; |
58 | char *value = NULL; | 50 | char *value = NULL; |
59 | char *buf = NULL; | ||
60 | int state = STATE_INIT; | 51 | int state = STATE_INIT; |
61 | size_t n = 0; | 52 | char *buf = NULL; |
53 | size_t size = 0, n; | ||
62 | int errcnt = 0, line = 0; | 54 | int errcnt = 0, line = 0; |
63 | 55 | ||
64 | if ((status = mu_header_create (&header, NULL, 0)) != 0) | 56 | if ((status = mu_header_create (&header, NULL, 0)) != 0) |
... | @@ -67,12 +59,12 @@ parse_headers (FILE *fp, compose_env_t *env) | ... | @@ -67,12 +59,12 @@ parse_headers (FILE *fp, compose_env_t *env) |
67 | return 1; | 59 | return 1; |
68 | } | 60 | } |
69 | 61 | ||
70 | while (state != STATE_BODY | 62 | mu_stream_seek (input, 0, MU_SEEK_SET, NULL); |
71 | && errcnt == 0 && getline (&buf, &n, fp) > 0 && n > 0) | 63 | while (state != STATE_BODY && |
64 | errcnt == 0 && | ||
65 | mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0) | ||
72 | { | 66 | { |
73 | int len = strlen (buf); | 67 | mu_rtrim_class (buf, MU_CTYPE_SPACE); |
74 | if (len > 0 && buf[len-1] == '\n') | ||
75 | buf[len-1] = 0; | ||
76 | 68 | ||
77 | line++; | 69 | line++; |
78 | switch (state) | 70 | switch (state) |
... | @@ -161,7 +153,7 @@ parse_headers (FILE *fp, compose_env_t *env) | ... | @@ -161,7 +153,7 @@ parse_headers (FILE *fp, compose_env_t *env) |
161 | static void | 153 | static void |
162 | escape_continue (void) | 154 | escape_continue (void) |
163 | { | 155 | { |
164 | fprintf (stdout, _("(continue)\n")); | 156 | mu_stream_printf (ostream, _("(continue)\n")); |
165 | } | 157 | } |
166 | 158 | ||
167 | static int | 159 | static int |
... | @@ -181,12 +173,7 @@ escape_check_args (int argc, char **argv) | ... | @@ -181,12 +173,7 @@ escape_check_args (int argc, char **argv) |
181 | int | 173 | int |
182 | escape_shell (int argc, char **argv, compose_env_t *env) | 174 | escape_shell (int argc, char **argv, compose_env_t *env) |
183 | { | 175 | { |
184 | int status; | 176 | return mail_execute (1, argc - 1, argv + 1); |
185 | ofile = env->ofile; | ||
186 | ++*argv; | ||
187 | status = mail_execute (1, argc, argv); | ||
188 | ofile = env->file; | ||
189 | return status; | ||
190 | } | 177 | } |
191 | 178 | ||
192 | /* ~:[mail-command] */ | 179 | /* ~:[mail-command] */ |
... | @@ -196,7 +183,8 @@ escape_command (int argc, char **argv, compose_env_t *env) | ... | @@ -196,7 +183,8 @@ escape_command (int argc, char **argv, compose_env_t *env) |
196 | { | 183 | { |
197 | const struct mail_command_entry *entry; | 184 | const struct mail_command_entry *entry; |
198 | int status; | 185 | int status; |
199 | 186 | mu_stream_t s; | |
187 | |||
200 | if (escape_check_args (argc, argv)) | 188 | if (escape_check_args (argc, argv)) |
201 | return 1; | 189 | return 1; |
202 | if (argv[1][0] == '#') | 190 | if (argv[1][0] == '#') |
... | @@ -213,9 +201,11 @@ escape_command (int argc, char **argv, compose_env_t *env) | ... | @@ -213,9 +201,11 @@ escape_command (int argc, char **argv, compose_env_t *env) |
213 | return 1; | 201 | return 1; |
214 | } | 202 | } |
215 | 203 | ||
216 | ofile = env->ofile; | 204 | /* FIXME: Do we need this? */ |
205 | s = ostream; | ||
206 | ostream = env->compstr; | ||
217 | status = (*entry->func) (argc - 1, argv + 1); | 207 | status = (*entry->func) (argc - 1, argv + 1); |
218 | ofile = env->file; | 208 | ostream = s; |
219 | return status; | 209 | return status; |
220 | } | 210 | } |
221 | 211 | ||
... | @@ -236,37 +226,32 @@ escape_help (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED) | ... | @@ -236,37 +226,32 @@ escape_help (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED) |
236 | /* ~A */ | 226 | /* ~A */ |
237 | /* ~a */ | 227 | /* ~a */ |
238 | int | 228 | int |
239 | escape_sign (int argc MU_ARG_UNUSED, char **argv, compose_env_t *env MU_ARG_UNUSED) | 229 | escape_sign (int argc MU_ARG_UNUSED, char **argv, compose_env_t *env) |
240 | { | 230 | { |
241 | char *p; | 231 | char *p; |
242 | 232 | ||
243 | if (mailvar_get (&p, mu_isupper (argv[0][0]) ? "Sign" : "sign", | 233 | if (mailvar_get (&p, mu_isupper (argv[0][0]) ? "Sign" : "sign", |
244 | mailvar_type_string, 1) == 0) | 234 | mailvar_type_string, 1) == 0) |
245 | { | 235 | { |
246 | fputs ("-- \n", ofile); | 236 | mu_stream_printf (env->compstr, "-- \n"); |
247 | if (mu_isupper (argv[0][0])) | 237 | if (mu_isupper (argv[0][0])) |
248 | { | 238 | { |
249 | char *name = util_fullpath (p); | 239 | char *name = util_fullpath (p); |
250 | FILE *fp = fopen (name, "r"); | 240 | int rc; |
251 | char *buf = NULL; | 241 | mu_stream_t signstr; |
252 | size_t n = 0; | ||
253 | 242 | ||
254 | if (!fp) | 243 | rc = mu_file_stream_create (&signstr, name, MU_STREAM_READ); |
244 | if (rc) | ||
245 | util_error (_("Cannot open %s: %s"), name, mu_strerror (rc)); | ||
246 | else | ||
255 | { | 247 | { |
256 | util_error (_("Cannot open %s: %s"), name, mu_strerror (errno)); | 248 | mu_stream_printf (ostream, _("Reading %s\n"), name); |
257 | free (name); | 249 | mu_stream_copy (env->compstr, signstr, 0, NULL); |
250 | mu_stream_destroy (&signstr); | ||
258 | } | 251 | } |
259 | |||
260 | fprintf (stdout, _("Reading %s\n"), name); | ||
261 | while (getline (&buf, &n, fp) > 0) | ||
262 | fprintf (ofile, "%s", buf); | ||
263 | |||
264 | fclose (fp); | ||
265 | free (buf); | ||
266 | free (name); | ||
267 | } | 252 | } |
268 | else | 253 | else |
269 | fprintf (ofile, "%s", p); | 254 | mu_stream_printf (env->compstr, "%s\n", p); |
270 | escape_continue (); | 255 | escape_continue (); |
271 | } | 256 | } |
272 | return 0; | 257 | return 0; |
... | @@ -290,20 +275,50 @@ escape_cc (int argc, char **argv, compose_env_t *env) | ... | @@ -290,20 +275,50 @@ escape_cc (int argc, char **argv, compose_env_t *env) |
290 | return 0; | 275 | return 0; |
291 | } | 276 | } |
292 | 277 | ||
278 | static int | ||
279 | verbose_copy (mu_stream_t dest, mu_stream_t src, const char *filename, | ||
280 | mu_off_t *psize) | ||
281 | { | ||
282 | int rc; | ||
283 | char *buf = NULL; | ||
284 | size_t size = 0, n; | ||
285 | size_t lines; | ||
286 | mu_off_t total; | ||
287 | |||
288 | total = lines = 0; | ||
289 | |||
290 | while ((rc = mu_stream_getline (src, &buf, &size, &n)) == 0 && n > 0) | ||
291 | { | ||
292 | lines++; | ||
293 | rc = mu_stream_write (dest, buf, n, NULL); | ||
294 | if (rc) | ||
295 | break; | ||
296 | total += n; | ||
297 | } | ||
298 | if (rc) | ||
299 | mu_error (_("error copying data: %s"), mu_strerror (rc)); | ||
300 | mu_stream_printf (ostream, "\"%s\" %lu/%lu\n", filename, | ||
301 | (unsigned long) lines, (unsigned long) total); | ||
302 | if (psize) | ||
303 | *psize = total; | ||
304 | return rc; | ||
305 | } | ||
306 | |||
293 | /* ~d */ | 307 | /* ~d */ |
294 | int | 308 | int |
295 | escape_deadletter (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED, | 309 | escape_deadletter (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED, |
296 | compose_env_t *env MU_ARG_UNUSED) | 310 | compose_env_t *env) |
297 | { | 311 | { |
298 | FILE *dead = fopen (getenv ("DEAD"), "r"); | 312 | const char *name = getenv ("DEAD"); |
299 | int c; | 313 | mu_stream_t str; |
300 | 314 | int rc = mu_file_stream_create (&str, name, MU_STREAM_READ); | |
301 | if (dead) | 315 | if (rc) |
302 | { | 316 | { |
303 | while ((c = fgetc (dead)) != EOF) | 317 | util_error (_("Cannot open file %s: %s"), name, strerror (rc)); |
304 | fputc (c, ofile); | 318 | return 1; |
305 | fclose (dead); | ||
306 | } | 319 | } |
320 | verbose_copy (env->compstr, str, name, NULL); | ||
321 | mu_stream_destroy (&str); | ||
307 | return 0; | 322 | return 0; |
308 | } | 323 | } |
309 | 324 | ||
... | @@ -321,60 +336,80 @@ run_editor (char *ed, char *arg) | ... | @@ -321,60 +336,80 @@ run_editor (char *ed, char *arg) |
321 | static int | 336 | static int |
322 | escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env) | 337 | escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env) |
323 | { | 338 | { |
324 | if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0)) | 339 | char *filename; |
340 | int fd; | ||
341 | mu_stream_t tempstream; | ||
342 | int rc; | ||
343 | |||
344 | rc = mu_tempfile (NULL, 0, &fd, &filename); | ||
345 | if (rc) | ||
325 | { | 346 | { |
326 | char *filename; | 347 | mu_diag_funcall (MU_DIAG_ERROR, "mu_tempfile", NULL, rc); |
327 | int fd; | 348 | return rc; |
328 | FILE *fp; | 349 | } |
329 | char buffer[512]; | 350 | rc = mu_fd_stream_create (&tempstream, filename, fd, MU_STREAM_RDWR); |
330 | int rc; | 351 | if (rc) |
331 | 352 | { | |
332 | rc = mu_tempfile (NULL, 0, &fd, &filename); | 353 | mu_diag_funcall (MU_DIAG_ERROR, "mu_fd_stream_create", filename, rc); |
333 | if (rc) | 354 | unlink (filename); |
334 | { | 355 | free (filename); |
335 | mu_diag_funcall (MU_DIAG_ERROR, "mu_tempfile", NULL, rc); | 356 | close (fd); |
336 | return rc; | 357 | return rc; |
337 | } | 358 | } |
338 | |||
339 | fp = fdopen (fd, "w+"); | ||
340 | dump_headers (fp, env); | ||
341 | 359 | ||
342 | rewind (env->file); | 360 | mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL); |
343 | while (fgets (buffer, sizeof (buffer), env->file)) | 361 | if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0)) |
344 | fputs (buffer, fp); | 362 | { |
363 | dump_headers (tempstream, env); | ||
345 | 364 | ||
346 | fclose (env->file); | 365 | mu_stream_copy (tempstream, env->compstr, 0, NULL); |
347 | 366 | ||
348 | do | 367 | do |
349 | { | 368 | { |
350 | fclose (fp); | 369 | mu_stream_destroy (&tempstream); |
351 | run_editor (ed, filename); | 370 | run_editor (ed, filename); |
352 | fp = fopen (filename, "r"); | 371 | rc = mu_file_stream_create (&tempstream, filename, MU_STREAM_RDWR); |
353 | } | 372 | if (rc) |
354 | while ((rc = parse_headers (fp, env)) < 0); | 373 | { |
355 | 374 | mu_diag_funcall (MU_DIAG_ERROR, "mu_file_stream_create", | |
356 | if (rc == 0) | 375 | filename, rc); |
357 | { | 376 | unlink (filename); |
358 | env->file = fopen (env->filename, "w"); | 377 | free (filename); |
359 | while (fgets (buffer, sizeof (buffer), fp)) | 378 | return rc; |
360 | fputs (buffer, env->file); | 379 | } |
361 | |||
362 | fclose (env->file); | ||
363 | } | 380 | } |
364 | fclose (fp); | 381 | while ((rc = parse_headers (tempstream, env)) < 0); |
365 | unlink (filename); | ||
366 | free (filename); | ||
367 | } | 382 | } |
368 | else | 383 | else |
369 | { | 384 | { |
370 | fclose (env->file); | 385 | mu_stream_copy (tempstream, env->compstr, 0, NULL); |
371 | ofile = env->ofile; | 386 | mu_stream_destroy (&tempstream); |
372 | run_editor (ed, env->filename); | 387 | run_editor (ed, filename); |
388 | rc = mu_file_stream_create (&tempstream, filename, MU_STREAM_RDWR); | ||
389 | if (rc) | ||
390 | { | ||
391 | mu_diag_funcall (MU_DIAG_ERROR, "mu_file_stream_create", | ||
392 | filename, rc); | ||
393 | unlink (filename); | ||
394 | free (filename); | ||
395 | return rc; | ||
396 | } | ||
373 | } | 397 | } |
374 | 398 | ||
375 | env->file = fopen (env->filename, "a+"); | 399 | if (rc == 0) |
376 | ofile = env->file; | 400 | { |
401 | mu_off_t size; | ||
377 | 402 | ||
403 | mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL); | ||
404 | mu_stream_copy (env->compstr, tempstream, 0, &size); | ||
405 | mu_stream_truncate (env->compstr, size); | ||
406 | } | ||
407 | mu_stream_destroy (&tempstream); | ||
408 | unlink (filename); | ||
409 | free (filename); | ||
410 | |||
411 | mu_stream_seek (env->compstr, 0, MU_SEEK_END, NULL); | ||
412 | |||
378 | escape_continue (); | 413 | escape_continue (); |
379 | return 0; | 414 | return 0; |
380 | } | 415 | } |
... | @@ -425,57 +460,53 @@ escape_headers (int argc, char **argv, compose_env_t *env) | ... | @@ -425,57 +460,53 @@ escape_headers (int argc, char **argv, compose_env_t *env) |
425 | 460 | ||
426 | /* ~i[var-name] */ | 461 | /* ~i[var-name] */ |
427 | int | 462 | int |
428 | escape_insert (int argc, char **argv, compose_env_t *send_env MU_ARG_UNUSED) | 463 | escape_insert (int argc, char **argv, compose_env_t *env) |
429 | { | 464 | { |
430 | if (escape_check_args (argc, argv)) | 465 | if (escape_check_args (argc, argv)) |
431 | return 1; | 466 | return 1; |
432 | mailvar_variable_format (ofile, mailvar_find_variable (argv[1], 0), NULL); | 467 | mailvar_variable_format (env->compstr, mailvar_find_variable (argv[1], 0), |
468 | NULL); | ||
433 | return 0; | 469 | return 0; |
434 | } | 470 | } |
435 | 471 | ||
436 | /* ~m[mesg-list] */ | 472 | /* ~m[mesg-list] */ |
437 | /* ~M[mesg-list] */ | 473 | /* ~M[mesg-list] */ |
438 | 474 | ||
475 | struct quote_closure | ||
476 | { | ||
477 | mu_stream_t str; | ||
478 | int islower; | ||
479 | }; | ||
480 | |||
439 | int | 481 | int |
440 | quote0 (msgset_t *mspec, mu_message_t mesg, void *data) | 482 | quote0 (msgset_t *mspec, mu_message_t mesg, void *data) |
441 | { | 483 | { |
484 | struct quote_closure *clos = data; | ||
442 | int rc; | 485 | int rc; |
443 | mu_stream_t stream; | 486 | mu_stream_t stream; |
444 | char *prefix = "\t"; | 487 | char *prefix = "\t"; |
445 | mu_stream_t outstr, flt; | 488 | mu_stream_t flt; |
446 | char *argv[3]; | 489 | char *argv[3]; |
447 | int yes = 1; | ||
448 | 490 | ||
449 | fprintf (stdout, _("Interpolating: %lu\n"), | 491 | mu_stream_printf (ostream, _("Interpolating: %lu\n"), |
450 | (unsigned long) mspec->msg_part[0]); | 492 | (unsigned long) mspec->msg_part[0]); |
451 | 493 | ||
452 | mailvar_get (&prefix, "indentprefix", mailvar_type_string, 0); | 494 | mailvar_get (&prefix, "indentprefix", mailvar_type_string, 0); |
453 | 495 | ||
454 | fflush (ofile); | ||
455 | rc = mu_stdio_stream_create (&outstr, fileno (ofile), MU_STREAM_WRITE); | ||
456 | if (rc) | ||
457 | { | ||
458 | mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", NULL, rc); | ||
459 | return rc; | ||
460 | } | ||
461 | /* Set borrow flag to prevent fileno (ofile) from being closed on | ||
462 | destroying outstr. */ | ||
463 | mu_stream_ioctl (outstr, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes); | ||
464 | argv[0] = "INLINE-COMMENT"; | 496 | argv[0] = "INLINE-COMMENT"; |
465 | argv[1] = prefix; | 497 | argv[1] = prefix; |
466 | argv[2] = NULL; | 498 | argv[2] = NULL; |
467 | rc = mu_filter_create_args (&flt, outstr, "INLINE-COMMENT", | 499 | rc = mu_filter_create_args (&flt, clos->str, "INLINE-COMMENT", |
468 | 2, (const char**) argv, | 500 | 2, (const char**) argv, |
469 | MU_FILTER_ENCODE, | 501 | MU_FILTER_ENCODE, |
470 | MU_STREAM_WRITE); | 502 | MU_STREAM_WRITE); |
471 | mu_stream_unref (outstr); | ||
472 | if (rc) | 503 | if (rc) |
473 | { | 504 | { |
474 | mu_diag_funcall (MU_DIAG_ERROR, "mu_filter_create_args", NULL, rc); | 505 | mu_diag_funcall (MU_DIAG_ERROR, "mu_filter_create_args", NULL, rc); |
475 | return rc; | 506 | return rc; |
476 | } | 507 | } |
477 | 508 | ||
478 | if (*(int*)data) | 509 | if (clos->islower) |
479 | { | 510 | { |
480 | mu_header_t hdr; | 511 | mu_header_t hdr; |
481 | mu_body_t body; | 512 | mu_body_t body; |
... | @@ -518,8 +549,11 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data) | ... | @@ -518,8 +549,11 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data) |
518 | int | 549 | int |
519 | escape_quote (int argc, char **argv, compose_env_t *env) | 550 | escape_quote (int argc, char **argv, compose_env_t *env) |
520 | { | 551 | { |
521 | int lower = mu_islower (argv[0][0]); | 552 | struct quote_closure clos; |
522 | util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT, quote0, &lower); | 553 | |
554 | clos.str = env->compstr; | ||
555 | clos.islower = mu_islower (argv[0][0]); | ||
556 | util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT, quote0, &clos); | ||
523 | escape_continue (); | 557 | escape_continue (); |
524 | return 0; | 558 | return 0; |
525 | } | 559 | } |
... | @@ -528,18 +562,12 @@ escape_quote (int argc, char **argv, compose_env_t *env) | ... | @@ -528,18 +562,12 @@ escape_quote (int argc, char **argv, compose_env_t *env) |
528 | int | 562 | int |
529 | escape_type_input (int argc, char **argv, compose_env_t *env) | 563 | escape_type_input (int argc, char **argv, compose_env_t *env) |
530 | { | 564 | { |
531 | char buffer[512]; | 565 | /* FIXME: Enable paging */ |
532 | 566 | mu_stream_printf (ostream, _("Message contains:\n")); | |
533 | fprintf (env->ofile, _("Message contains:\n")); | 567 | dump_headers (ostream, env); |
534 | 568 | mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL); | |
535 | dump_headers (env->ofile, env); | 569 | mu_stream_copy (ostream, env->compstr, 0, NULL); |
536 | |||
537 | rewind (env->file); | ||
538 | while (fgets (buffer, sizeof (buffer), env->file)) | ||
539 | fputs (buffer, env->ofile); | ||
540 | |||
541 | escape_continue (); | 570 | escape_continue (); |
542 | |||
543 | return 0; | 571 | return 0; |
544 | } | 572 | } |
545 | 573 | ||
... | @@ -548,31 +576,23 @@ int | ... | @@ -548,31 +576,23 @@ int |
548 | escape_read (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED) | 576 | escape_read (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED) |
549 | { | 577 | { |
550 | char *filename; | 578 | char *filename; |
551 | FILE *inf; | 579 | mu_stream_t instr; |
552 | size_t size, lines; | 580 | int rc; |
553 | char buf[512]; | 581 | |
554 | |||
555 | if (escape_check_args (argc, argv)) | 582 | if (escape_check_args (argc, argv)) |
556 | return 1; | 583 | return 1; |
557 | filename = util_fullpath (argv[1]); | 584 | filename = util_fullpath (argv[1]); |
558 | inf = fopen (filename, "r"); | 585 | |
559 | if (!inf) | 586 | rc = mu_file_stream_create (&instr, filename, MU_STREAM_READ); |
587 | if (rc) | ||
560 | { | 588 | { |
561 | util_error (_("Cannot open %s: %s"), filename, mu_strerror (errno)); | 589 | util_error (_("Cannot open %s: %s"), filename, mu_strerror (rc)); |
562 | free (filename); | 590 | free (filename); |
563 | return 1; | 591 | return 1; |
564 | } | 592 | } |
565 | 593 | ||
566 | size = lines = 0; | 594 | verbose_copy (env->compstr, instr, filename, NULL); |
567 | while (fgets (buf, sizeof (buf), inf)) | 595 | mu_stream_destroy (&instr); |
568 | { | ||
569 | lines++; | ||
570 | size += strlen (buf); | ||
571 | fputs (buf, ofile); | ||
572 | } | ||
573 | fclose (inf); | ||
574 | fprintf (stdout, "\"%s\" %lu/%lu\n", filename, | ||
575 | (unsigned long) lines, (unsigned long) size); | ||
576 | free (filename); | 596 | free (filename); |
577 | return 0; | 597 | return 0; |
578 | } | 598 | } |
... | @@ -581,9 +601,12 @@ escape_read (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED) | ... | @@ -581,9 +601,12 @@ escape_read (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED) |
581 | int | 601 | int |
582 | escape_subj (int argc, char **argv, compose_env_t *env) | 602 | escape_subj (int argc, char **argv, compose_env_t *env) |
583 | { | 603 | { |
604 | char *buf; | ||
584 | if (escape_check_args (argc, argv)) | 605 | if (escape_check_args (argc, argv)) |
585 | return 1; | 606 | return 1; |
586 | compose_header_set (env, MU_HEADER_SUBJECT, argv[1], COMPOSE_REPLACE); | 607 | mu_argcv_string (argc - 1, argv + 1, &buf); |
608 | compose_header_set (env, MU_HEADER_SUBJECT, buf, COMPOSE_REPLACE); | ||
609 | free (buf); | ||
587 | return 0; | 610 | return 0; |
588 | } | 611 | } |
589 | 612 | ||
... | @@ -601,34 +624,28 @@ int | ... | @@ -601,34 +624,28 @@ int |
601 | escape_write (int argc, char **argv, compose_env_t *env) | 624 | escape_write (int argc, char **argv, compose_env_t *env) |
602 | { | 625 | { |
603 | char *filename; | 626 | char *filename; |
604 | FILE *fp; | 627 | mu_stream_t wstr; |
605 | size_t size, lines; | 628 | int rc; |
606 | char buf[512]; | 629 | mu_off_t size; |
607 | 630 | ||
608 | if (escape_check_args (argc, argv)) | 631 | if (escape_check_args (argc, argv)) |
609 | return 1; | 632 | return 1; |
610 | |||
611 | filename = util_fullpath (argv[1]); | 633 | filename = util_fullpath (argv[1]); |
612 | fp = fopen (filename, "w"); /*FIXME: check for the existence first */ | 634 | /* FIXME: check for existence first */ |
613 | 635 | rc = mu_file_stream_create (&wstr, filename, | |
614 | if (!fp) | 636 | MU_STREAM_WRITE|MU_STREAM_CREAT); |
637 | if (rc) | ||
615 | { | 638 | { |
616 | util_error (_("Cannot open %s: %s"), filename, mu_strerror (errno)); | 639 | util_error (_("Cannot open %s for writing: %s"), |
640 | filename, mu_strerror (rc)); | ||
617 | free (filename); | 641 | free (filename); |
618 | return 1; | 642 | return 1; |
619 | } | 643 | } |
620 | 644 | ||
621 | rewind (env->file); | 645 | mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL); |
622 | size = lines = 0; | 646 | verbose_copy (wstr, env->compstr, filename, &size); |
623 | while (fgets (buf, sizeof (buf), env->file)) | 647 | mu_stream_truncate (wstr, size); |
624 | { | 648 | mu_stream_destroy (&wstr); |
625 | lines++; | ||
626 | size += strlen (buf); | ||
627 | fputs (buf, fp); | ||
628 | } | ||
629 | fclose (fp); | ||
630 | fprintf (stdout, "\"%s\" %lu/%lu\n", filename, | ||
631 | (unsigned long) lines, (unsigned long) size); | ||
632 | free (filename); | 649 | free (filename); |
633 | return 0; | 650 | return 0; |
634 | } | 651 | } |
... | @@ -637,17 +654,13 @@ escape_write (int argc, char **argv, compose_env_t *env) | ... | @@ -637,17 +654,13 @@ escape_write (int argc, char **argv, compose_env_t *env) |
637 | int | 654 | int |
638 | escape_pipe (int argc, char **argv, compose_env_t *env) | 655 | escape_pipe (int argc, char **argv, compose_env_t *env) |
639 | { | 656 | { |
657 | int rc, status; | ||
640 | int p[2]; | 658 | int p[2]; |
641 | pid_t pid; | 659 | pid_t pid; |
642 | int fd; | 660 | int fd; |
643 | 661 | mu_off_t isize, osize = 0; | |
644 | if (argc == 1) | 662 | mu_stream_t tstr; |
645 | { | 663 | |
646 | /* TRANSLATORS: 'pipe' is a command name. Do not translate it! */ | ||
647 | util_error (_("pipe: no command specified")); | ||
648 | return 1; | ||
649 | } | ||
650 | |||
651 | if (pipe (p)) | 664 | if (pipe (p)) |
652 | { | 665 | { |
653 | util_error ("pipe: %s", mu_strerror (errno)); | 666 | util_error ("pipe: %s", mu_strerror (errno)); |
... | @@ -668,10 +681,8 @@ escape_pipe (int argc, char **argv, compose_env_t *env) | ... | @@ -668,10 +681,8 @@ escape_pipe (int argc, char **argv, compose_env_t *env) |
668 | else if (pid == 0) | 681 | else if (pid == 0) |
669 | { | 682 | { |
670 | /* Child */ | 683 | /* Child */ |
671 | int i; | ||
672 | char **xargv; | ||
673 | 684 | ||
674 | /* Attache the pipes */ | 685 | /* Attach the pipes */ |
675 | close (0); | 686 | close (0); |
676 | dup (p[0]); | 687 | dup (p[0]); |
677 | close (p[0]); | 688 | close (p[0]); |
... | @@ -681,94 +692,61 @@ escape_pipe (int argc, char **argv, compose_env_t *env) | ... | @@ -681,94 +692,61 @@ escape_pipe (int argc, char **argv, compose_env_t *env) |
681 | dup (fd); | 692 | dup (fd); |
682 | close (fd); | 693 | close (fd); |
683 | 694 | ||
684 | /* Execute the process */ | 695 | execvp (argv[1], argv + 1); |
685 | xargv = xcalloc (argc, sizeof (xargv[0])); | 696 | util_error (_("Cannot execute `%s': %s"), argv[1], mu_strerror (errno)); |
686 | for (i = 0; i < argc - 1; i++) | 697 | _exit (127); |
687 | xargv[i] = argv[i + 1]; | ||
688 | xargv[i] = NULL; | ||
689 | execvp (xargv[0], xargv); | ||
690 | util_error (_("Cannot exec process `%s': %s"), xargv[0], mu_strerror (errno)); | ||
691 | exit (1); | ||
692 | } | 698 | } |
693 | else | ||
694 | { | ||
695 | FILE *fp; | ||
696 | char *buf = NULL; | ||
697 | size_t n; | ||
698 | size_t lines, size; | ||
699 | int rc = 1; | ||
700 | int status; | ||
701 | 699 | ||
702 | close (p[0]); | 700 | close (p[0]); |
703 | 701 | ||
704 | /* Parent */ | 702 | rc = mu_stdio_stream_create (&tstr, p[1], MU_STREAM_WRITE); |
705 | fp = fdopen (p[1], "w"); | 703 | if (rc) |
706 | 704 | { | |
707 | fclose (env->file); | 705 | mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", NULL, rc); |
708 | env->file = fopen (env->filename, "r"); | 706 | kill (pid, SIGKILL); |
707 | close (fd); | ||
708 | return rc; | ||
709 | } | ||
709 | 710 | ||
710 | lines = size = 0; | 711 | mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL); |
711 | while (getline (&buf, &n, env->file) > 0) | 712 | mu_stream_copy (tstr, env->compstr, 0, &isize); |
712 | { | 713 | mu_stream_destroy (&tstr); |
713 | lines++; | ||
714 | size += n; | ||
715 | fputs (buf, fp); | ||
716 | } | ||
717 | fclose (env->file); | ||
718 | fclose (fp); /* Closes p[1] */ | ||
719 | 714 | ||
720 | waitpid (pid, &status, 0); | 715 | waitpid (pid, &status, 0); |
721 | if (!WIFEXITED (status)) | 716 | if (!WIFEXITED (status)) |
722 | { | 717 | util_error (_("Child terminated abnormally: %d"), |
723 | util_error (_("Child terminated abnormally: %d"), WEXITSTATUS (status)); | 718 | WEXITSTATUS (status)); |
724 | } | 719 | else |
720 | { | ||
721 | struct stat st; | ||
722 | if (fstat (fd, &st)) | ||
723 | util_error (_("Cannot stat output file: %s"), mu_strerror (errno)); | ||
725 | else | 724 | else |
726 | { | 725 | osize = st.st_size; |
727 | struct stat st; | 726 | } |
728 | if (fstat (fd, &st)) | ||
729 | { | ||
730 | util_error (_("Cannot stat output file: %s"), mu_strerror (errno)); | ||
731 | } | ||
732 | else if (st.st_size > 0) | ||
733 | rc = 0; | ||
734 | } | ||
735 | 727 | ||
736 | fprintf (stdout, "\"|%s\" in: %lu/%lu ", argv[1], | 728 | mu_stream_printf (mu_strout, "\"|%s\" in: %lu ", argv[1], |
737 | (unsigned long) lines, (unsigned long) size); | 729 | (unsigned long) isize); |
730 | if (osize == 0) | ||
731 | mu_stream_printf (mu_strout, _("no lines out\n")); | ||
732 | else | ||
733 | { | ||
734 | mu_stream_t str; | ||
735 | |||
736 | mu_stream_printf (mu_strout, "out: %lu\n", (unsigned long) osize); | ||
737 | rc = mu_fd_stream_create (&str, NULL, fd, | ||
738 | MU_STREAM_RDWR | MU_STREAM_SEEK); | ||
738 | if (rc) | 739 | if (rc) |
739 | { | 740 | { |
740 | fprintf (stdout, _("no lines out\n")); | 741 | util_error (_("Cannot open composition stream: %s"), |
742 | mu_strerror (rc)); | ||
743 | close (fd); | ||
741 | } | 744 | } |
742 | else | 745 | else |
743 | { | 746 | { |
744 | /* Ok, replace the old tempfile */ | 747 | mu_stream_destroy (&env->compstr); |
745 | fp = fdopen (fd, "r"); | 748 | env->compstr = str; |
746 | rewind (fp); | ||
747 | |||
748 | env->file = fopen (env->filename, "w+"); | ||
749 | |||
750 | lines = size = 0; | ||
751 | while (getline (&buf, &n, fp) > 0) | ||
752 | { | ||
753 | lines++; | ||
754 | size += n; | ||
755 | fputs (buf, env->file); | ||
756 | } | ||
757 | fclose (env->file); | ||
758 | |||
759 | fprintf (stdout, "out: %lu/%lu\n", | ||
760 | (unsigned long) lines, (unsigned long) size); | ||
761 | } | 749 | } |
762 | |||
763 | /* Clean up the things */ | ||
764 | if (buf) | ||
765 | free (buf); | ||
766 | |||
767 | env->file = fopen (env->filename, "a+"); | ||
768 | ofile = env->file; | ||
769 | } | 750 | } |
770 | |||
771 | close (fd); | ||
772 | |||
773 | return 0; | 751 | return 0; |
774 | } | 752 | } | ... | ... |
... | @@ -77,9 +77,10 @@ mail_followup (int argc, char **argv) | ... | @@ -77,9 +77,10 @@ mail_followup (int argc, char **argv) |
77 | 77 | ||
78 | msgset_free (msglist); | 78 | msgset_free (msglist); |
79 | 79 | ||
80 | fprintf (ofile, "To: %s\n", compose_header_get (&env, MU_HEADER_TO, "")); | 80 | mu_stream_printf (ostream, "To: %s\n", |
81 | fprintf (ofile, "Subject: %s\n\n", | 81 | compose_header_get (&env, MU_HEADER_TO, "")); |
82 | compose_header_get (&env, MU_HEADER_SUBJECT, "")); | 82 | mu_stream_printf (ostream, "Subject: %s\n\n", |
83 | compose_header_get (&env, MU_HEADER_SUBJECT, "")); | ||
83 | 84 | ||
84 | status = mail_send0 (&env, mu_isupper (argv[0][0])); | 85 | status = mail_send0 (&env, mu_isupper (argv[0][0])); |
85 | compose_destroy (&env); | 86 | compose_destroy (&env); | ... | ... |
... | @@ -72,7 +72,7 @@ static void | ... | @@ -72,7 +72,7 @@ static void |
72 | format_pad (size_t n) | 72 | format_pad (size_t n) |
73 | { | 73 | { |
74 | for (; n; n--) | 74 | for (; n; n--) |
75 | fputc (' ', ofile); | 75 | mu_stream_write (ostream, " ", 1, NULL); |
76 | } | 76 | } |
77 | 77 | ||
78 | static void | 78 | static void |
... | @@ -113,17 +113,17 @@ format_headline (struct header_segm *seg, msgset_t *mspec, mu_message_t msg) | ... | @@ -113,17 +113,17 @@ format_headline (struct header_segm *seg, msgset_t *mspec, mu_message_t msg) |
113 | if (seg->align == ALIGN_RIGHT) | 113 | if (seg->align == ALIGN_RIGHT) |
114 | { | 114 | { |
115 | format_pad (width - len); | 115 | format_pad (width - len); |
116 | fprintf (ofile, "%*.*s", (int) len, (int) len, p); | 116 | mu_stream_printf (ostream, "%*.*s", (int) len, (int) len, p); |
117 | } | 117 | } |
118 | else | 118 | else |
119 | { | 119 | { |
120 | fprintf (ofile, "%*.*s", (int) len, (int) len, p); | 120 | mu_stream_printf (ostream, "%*.*s", (int) len, (int) len, p); |
121 | format_pad (width - len); | 121 | format_pad (width - len); |
122 | } | 122 | } |
123 | out_cols += width; | 123 | out_cols += width; |
124 | } | 124 | } |
125 | 125 | ||
126 | fprintf (ofile, "\n"); | 126 | mu_stream_printf (ostream, "\n"); |
127 | free (args.buf); | 127 | free (args.buf); |
128 | } | 128 | } |
129 | 129 | ... | ... |
... | @@ -27,10 +27,10 @@ mail_inc (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | ... | @@ -27,10 +27,10 @@ mail_inc (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
27 | if (!mu_mailbox_is_updated (mbox)) | 27 | if (!mu_mailbox_is_updated (mbox)) |
28 | { | 28 | { |
29 | mu_mailbox_messages_count (mbox, &total); | 29 | mu_mailbox_messages_count (mbox, &total); |
30 | fprintf (ofile, _("New mail has arrived.\n")); | 30 | mu_stream_printf (ostream, _("New mail has arrived.\n")); |
31 | } | 31 | } |
32 | else | 32 | else |
33 | fprintf (ofile, _("No new mail for %s\n"), mail_whoami()); | 33 | mu_stream_printf (ostream, _("No new mail for %s\n"), mail_whoami ()); |
34 | 34 | ||
35 | return 0; | 35 | return 0; |
36 | } | 36 | } | ... | ... |
... | @@ -21,7 +21,7 @@ | ... | @@ -21,7 +21,7 @@ |
21 | /* Global variables and constants*/ | 21 | /* Global variables and constants*/ |
22 | mu_mailbox_t mbox; /* Mailbox being operated upon */ | 22 | mu_mailbox_t mbox; /* Mailbox being operated upon */ |
23 | size_t total; /* Total number of messages in the mailbox */ | 23 | size_t total; /* Total number of messages in the mailbox */ |
24 | FILE *ofile; /* Output file */ | 24 | mu_stream_t ostream; /* Output stream */ |
25 | int interactive; /* Is the session interactive */ | 25 | int interactive; /* Is the session interactive */ |
26 | 26 | ||
27 | static mu_list_t command_list; /* List of commands to be executed after parsing | 27 | static mu_list_t command_list; /* List of commands to be executed after parsing |
... | @@ -221,7 +221,7 @@ mail_cmdline (void *closure, int cont MU_ARG_UNUSED) | ... | @@ -221,7 +221,7 @@ mail_cmdline (void *closure, int cont MU_ARG_UNUSED) |
221 | { | 221 | { |
222 | mu_mailbox_messages_count (mbox, &total); | 222 | mu_mailbox_messages_count (mbox, &total); |
223 | page_invalidate (0); | 223 | page_invalidate (0); |
224 | fprintf (ofile, _("New mail has arrived.\n")); | 224 | mu_stream_printf (ostream, _("New mail has arrived.\n")); |
225 | } | 225 | } |
226 | 226 | ||
227 | rc = ml_readline (prompt); | 227 | rc = ml_readline (prompt); |
... | @@ -324,7 +324,9 @@ main (int argc, char **argv) | ... | @@ -324,7 +324,9 @@ main (int argc, char **argv) |
324 | struct arguments args; | 324 | struct arguments args; |
325 | int i, rc; | 325 | int i, rc; |
326 | 326 | ||
327 | ofile = stdout; | 327 | mu_stdstream_setup (); |
328 | ostream = mu_strout; | ||
329 | mu_stream_ref (mu_strout); | ||
328 | set_cursor (1); | 330 | set_cursor (1); |
329 | 331 | ||
330 | /* Native Language Support */ | 332 | /* Native Language Support */ |
... | @@ -399,7 +401,18 @@ main (int argc, char **argv) | ... | @@ -399,7 +401,18 @@ main (int argc, char **argv) |
399 | util_run_cached_commands (&command_list); | 401 | util_run_cached_commands (&command_list); |
400 | 402 | ||
401 | if (interactive) | 403 | if (interactive) |
402 | /* nothing? */; | 404 | { |
405 | /* Reset standard error stream so that it does not print program | ||
406 | name before the actual diagnostic message. */ | ||
407 | mu_stream_t errstr; | ||
408 | int rc = mu_stdstream_strerr_create (&errstr, MU_STRERR_STDERR, 0, 0, | ||
409 | NULL, NULL); | ||
410 | if (rc == 0) | ||
411 | { | ||
412 | mu_stream_destroy (&mu_strerr); | ||
413 | mu_strerr = errstr; | ||
414 | } | ||
415 | } | ||
403 | else | 416 | else |
404 | { | 417 | { |
405 | util_do_command ("set nocrt"); | 418 | util_do_command ("set nocrt"); |
... | @@ -485,10 +498,10 @@ main (int argc, char **argv) | ... | @@ -485,10 +498,10 @@ main (int argc, char **argv) |
485 | || mailvar_get (NULL, "emptystart", mailvar_type_boolean, 0))) | 498 | || mailvar_get (NULL, "emptystart", mailvar_type_boolean, 0))) |
486 | { | 499 | { |
487 | if (args.file) | 500 | if (args.file) |
488 | fprintf (ofile, _("%s: 0 messages\n"), args.file); | 501 | mu_stream_printf (ostream, _("%s: 0 messages\n"), args.file); |
489 | else | 502 | else |
490 | fprintf (ofile, _("No mail for %s\n"), | 503 | mu_stream_printf (ostream, _("No mail for %s\n"), |
491 | args.user ? args.user : mail_whoami ()); | 504 | args.user ? args.user : mail_whoami ()); |
492 | return 1; | 505 | return 1; |
493 | } | 506 | } |
494 | 507 | ||
... | @@ -501,7 +514,7 @@ main (int argc, char **argv) | ... | @@ -501,7 +514,7 @@ main (int argc, char **argv) |
501 | 514 | ||
502 | mailvar_get (&prompt, "prompt", mailvar_type_string, 0); | 515 | mailvar_get (&prompt, "prompt", mailvar_type_string, 0); |
503 | mail_mainloop (mail_cmdline, (void*) prompt, 1); | 516 | mail_mainloop (mail_cmdline, (void*) prompt, 1); |
504 | fprintf (ofile, "\n"); | 517 | mu_stream_printf (ostream, "\n"); |
505 | util_do_command ("quit"); | 518 | util_do_command ("quit"); |
506 | return 0; | 519 | return 0; |
507 | } | 520 | } |
... | @@ -551,11 +564,11 @@ mail_mainloop (char *(*input) (void *, int), | ... | @@ -551,11 +564,11 @@ mail_mainloop (char *(*input) (void *, int), |
551 | int | 564 | int |
552 | mail_warranty (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | 565 | mail_warranty (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
553 | { | 566 | { |
554 | fputs (_("GNU Mailutils -- a suite of utilities for electronic mail\n" | 567 | mu_stream_printf (ostream, |
568 | _("GNU Mailutils -- a suite of utilities for electronic mail\n" | ||
555 | "Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,\n" | 569 | "Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,\n" |
556 | "2007, 2009 Free Software Foundation, Inc.\n\n"), | 570 | "2007, 2009 Free Software Foundation, Inc.\n\n")); |
557 | ofile); | 571 | mu_stream_printf (ostream, |
558 | fputs ( | ||
559 | _(" GNU Mailutils is free software; you can redistribute it and/or modify\n" | 572 | _(" GNU Mailutils is free software; you can redistribute it and/or modify\n" |
560 | " it under the terms of the GNU General Public License as published by\n" | 573 | " it under the terms of the GNU General Public License as published by\n" |
561 | " the Free Software Foundation; either version 3 of the License, or\n" | 574 | " the Free Software Foundation; either version 3 of the License, or\n" |
... | @@ -570,8 +583,7 @@ mail_warranty (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | ... | @@ -570,8 +583,7 @@ mail_warranty (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
570 | " with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.\n" | 583 | " with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.\n" |
571 | "\n" | 584 | "\n" |
572 | "\n" | 585 | "\n" |
573 | ), | 586 | )); |
574 | ofile); | ||
575 | 587 | ||
576 | return 0; | 588 | return 0; |
577 | } | 589 | } | ... | ... |
... | @@ -102,9 +102,7 @@ typedef int function_t (int, char **); | ... | @@ -102,9 +102,7 @@ typedef int function_t (int, char **); |
102 | typedef struct compose_env | 102 | typedef struct compose_env |
103 | { | 103 | { |
104 | mu_header_t header; /* The message headers */ | 104 | mu_header_t header; /* The message headers */ |
105 | char *filename; /* Name of the temporary compose file */ | 105 | mu_stream_t compstr; /* Temporary compose stream */ |
106 | FILE *file; /* Temporary compose file */ | ||
107 | FILE *ofile; /* Diagnostics output channel */ | ||
108 | char **outfiles; /* Names of the output files. The message is to be | 106 | char **outfiles; /* Names of the output files. The message is to be |
109 | saved in each of these. */ | 107 | saved in each of these. */ |
110 | int nfiles; /* Number of output files */ | 108 | int nfiles; /* Number of output files */ |
... | @@ -174,7 +172,7 @@ typedef int (*msg_handler_t) (msgset_t *mp, mu_message_t mesg, void *data); | ... | @@ -174,7 +172,7 @@ typedef int (*msg_handler_t) (msgset_t *mp, mu_message_t mesg, void *data); |
174 | /* Global variables and constants*/ | 172 | /* Global variables and constants*/ |
175 | extern mu_mailbox_t mbox; | 173 | extern mu_mailbox_t mbox; |
176 | extern size_t total; | 174 | extern size_t total; |
177 | extern FILE *ofile; | 175 | extern mu_stream_t ostream; |
178 | extern int interactive; | 176 | extern int interactive; |
179 | extern const char *program_version; | 177 | extern const char *program_version; |
180 | 178 | ||
... | @@ -358,7 +356,7 @@ extern int mailvar_get (void *ptr, const char *variable, | ... | @@ -358,7 +356,7 @@ extern int mailvar_get (void *ptr, const char *variable, |
358 | enum mailvar_type type, int warn); | 356 | enum mailvar_type type, int warn); |
359 | 357 | ||
360 | extern void mailvar_print (int set); | 358 | extern void mailvar_print (int set); |
361 | extern void mailvar_variable_format (FILE *fp, | 359 | extern void mailvar_variable_format (mu_stream_t, |
362 | const struct mailvar_variable *, | 360 | const struct mailvar_variable *, |
363 | const char *defval); | 361 | const char *defval); |
364 | 362 | ||
... | @@ -403,7 +401,9 @@ void util_mark_read (mu_message_t msg); | ... | @@ -403,7 +401,9 @@ void util_mark_read (mu_message_t msg); |
403 | 401 | ||
404 | const char *util_url_to_string (mu_url_t url); | 402 | const char *util_url_to_string (mu_url_t url); |
405 | 403 | ||
406 | size_t fprint_msgset (FILE *fp, const msgset_t *msgset); | 404 | mu_stream_t open_pager (size_t lines); |
405 | |||
406 | void format_msgset (mu_stream_t str, const msgset_t *msgset, size_t *count); | ||
407 | 407 | ||
408 | int is_address_field (const char *name); | 408 | int is_address_field (const char *name); |
409 | 409 | ... | ... |
... | @@ -118,58 +118,24 @@ ml_readline_init () | ... | @@ -118,58 +118,24 @@ ml_readline_init () |
118 | char * | 118 | char * |
119 | ml_readline_internal () | 119 | ml_readline_internal () |
120 | { | 120 | { |
121 | char *line; | 121 | char *buf = NULL; |
122 | char *p; | 122 | size_t size = 0, n; |
123 | size_t alloclen, linelen; | 123 | int rc; |
124 | 124 | ||
125 | p = line = xcalloc (1, 255); | 125 | rc = mu_stream_getline (mu_strin, &buf, &size, &n); |
126 | alloclen = 255; | 126 | if (rc) |
127 | linelen = 0; | ||
128 | for (;;) | ||
129 | { | 127 | { |
130 | size_t n; | 128 | mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_getline", NULL, rc); |
131 | 129 | return NULL; | |
132 | p = fgets (p, alloclen - linelen, stdin); | ||
133 | |||
134 | if (p) | ||
135 | n = strlen(p); | ||
136 | else if (_interrupted) | ||
137 | { | ||
138 | free (line); | ||
139 | return NULL; | ||
140 | } | ||
141 | else | ||
142 | n = 0; | ||
143 | |||
144 | linelen += n; | ||
145 | |||
146 | /* Error. */ | ||
147 | if (linelen == 0) | ||
148 | { | ||
149 | free (line); | ||
150 | return NULL; | ||
151 | } | ||
152 | |||
153 | /* Ok. */ | ||
154 | if (line[linelen - 1] == '\n') | ||
155 | { | ||
156 | line[linelen - 1] = '\0'; | ||
157 | return line; | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | char *tmp; | ||
162 | alloclen *= 2; | ||
163 | tmp = realloc (line, alloclen); | ||
164 | if (tmp == NULL) | ||
165 | { | ||
166 | free (line); | ||
167 | return NULL; | ||
168 | } | ||
169 | line = tmp; | ||
170 | p = line + linelen; | ||
171 | } | ||
172 | } | 130 | } |
131 | if (_interrupted) | ||
132 | { | ||
133 | free (buf); | ||
134 | return NULL; | ||
135 | } | ||
136 | if (n == 0) | ||
137 | return NULL; | ||
138 | return buf; | ||
173 | } | 139 | } |
174 | 140 | ||
175 | char * | 141 | char * |
... | @@ -185,7 +151,7 @@ ml_readline_with_intr (const char *prompt) | ... | @@ -185,7 +151,7 @@ ml_readline_with_intr (const char *prompt) |
185 | { | 151 | { |
186 | char *str = ml_readline (prompt); | 152 | char *str = ml_readline (prompt); |
187 | if (_interrupted) | 153 | if (_interrupted) |
188 | printf ("\n"); | 154 | mu_stream_printf (ostream, "\n"); |
189 | return str; | 155 | return str; |
190 | } | 156 | } |
191 | 157 | ||
... | @@ -959,8 +925,8 @@ readline (char *prompt) | ... | @@ -959,8 +925,8 @@ readline (char *prompt) |
959 | { | 925 | { |
960 | if (prompt) | 926 | if (prompt) |
961 | { | 927 | { |
962 | fprintf (ofile, "%s", prompt); | 928 | mu_stream_printf (ostream, "%s", prompt); |
963 | fflush (ofile); | 929 | mu_stream_flush (ostream); |
964 | } | 930 | } |
965 | 931 | ||
966 | return ml_readline_internal (); | 932 | return ml_readline_internal (); | ... | ... |
... | @@ -285,21 +285,27 @@ find_mailvar_symbol (const char *var) | ... | @@ -285,21 +285,27 @@ find_mailvar_symbol (const char *var) |
285 | } | 285 | } |
286 | 286 | ||
287 | static void | 287 | static void |
288 | print_descr (FILE *out, const char *s, int n, | 288 | print_descr (mu_stream_t out, const char *s, int n, |
289 | int doc_col, int rmargin, char *pfx) | 289 | int doc_col, int rmargin, char *pfx) |
290 | { | 290 | { |
291 | mu_stream_stat_buffer stat; | ||
292 | |||
291 | if (!s) | 293 | if (!s) |
292 | return; | 294 | return; |
295 | |||
296 | mu_stream_set_stat (out, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT), | ||
297 | stat); | ||
298 | stat[MU_STREAM_STAT_OUT] = n; | ||
293 | do | 299 | do |
294 | { | 300 | { |
295 | const char *p; | 301 | const char *p; |
296 | const char *space = NULL; | 302 | const char *space = NULL; |
297 | 303 | ||
298 | if (n == 1 && pfx) | 304 | if (stat[MU_STREAM_STAT_OUT] && pfx) |
299 | n += fprintf (out, "%s", pfx); | 305 | mu_stream_printf (out, "%s", pfx); |
300 | 306 | ||
301 | for (; n < doc_col; n++) | 307 | while (stat[MU_STREAM_STAT_OUT] < doc_col) |
302 | fputc (' ', out); | 308 | mu_stream_write (out, " ", 1, NULL); |
303 | 309 | ||
304 | for (p = s; *p && p < s + (rmargin - doc_col); p++) | 310 | for (p = s; *p && p < s + (rmargin - doc_col); p++) |
305 | if (mu_isspace (*p)) | 311 | if (mu_isspace (*p)) |
... | @@ -307,20 +313,21 @@ print_descr (FILE *out, const char *s, int n, | ... | @@ -307,20 +313,21 @@ print_descr (FILE *out, const char *s, int n, |
307 | 313 | ||
308 | if (!space || p < s + (rmargin - doc_col)) | 314 | if (!space || p < s + (rmargin - doc_col)) |
309 | { | 315 | { |
310 | fprintf (out, "%s", s); | 316 | mu_stream_printf (out, "%s", s); |
311 | s += strlen (s); | 317 | s += strlen (s); |
312 | } | 318 | } |
313 | else | 319 | else |
314 | { | 320 | { |
315 | for (; s < space; s++) | 321 | for (; s < space; s++) |
316 | fputc (*s, out); | 322 | mu_stream_write (out, s, 1, NULL); |
317 | for (; *s && mu_isspace (*s); s++) | 323 | for (; *s && mu_isspace (*s); s++) |
318 | ; | 324 | ; |
319 | } | 325 | } |
320 | fputc ('\n', out); | 326 | mu_stream_printf (out, "\n"); |
321 | n = 1; | 327 | stat[MU_STREAM_STAT_OUT] = 1; |
322 | } | 328 | } |
323 | while (*s); | 329 | while (*s); |
330 | mu_stream_set_stat (out, 0, NULL); | ||
324 | } | 331 | } |
325 | 332 | ||
326 | /* Functions for dealing with internal mailvar_list variables */ | 333 | /* Functions for dealing with internal mailvar_list variables */ |
... | @@ -680,17 +687,15 @@ void | ... | @@ -680,17 +687,15 @@ void |
680 | mailvar_print (int set) | 687 | mailvar_print (int set) |
681 | { | 688 | { |
682 | struct mailvar_variable **vartab; | 689 | struct mailvar_variable **vartab; |
683 | FILE *out = ofile; | 690 | mu_stream_t out; |
684 | size_t i, count; | 691 | size_t i, count; |
685 | int pagelines = util_get_crt (); | ||
686 | int width = util_getcols (); | 692 | int width = util_getcols (); |
687 | int prettyprint = mailvar_get (NULL, "variable-pretty-print", | 693 | int prettyprint = mailvar_get (NULL, "variable-pretty-print", |
688 | mailvar_type_boolean, 0) == 0; | 694 | mailvar_type_boolean, 0) == 0; |
689 | 695 | ||
690 | vartab = mailvar_make_array (set, &count); | 696 | vartab = mailvar_make_array (set, &count); |
691 | 697 | ||
692 | if (pagelines && count > pagelines) | 698 | out = open_pager (count); |
693 | out = popen (getenv ("PAGER"), "w"); | ||
694 | 699 | ||
695 | for (i = 0; i < count; i++) | 700 | for (i = 0; i < count; i++) |
696 | { | 701 | { |
... | @@ -704,40 +709,41 @@ mailvar_print (int set) | ... | @@ -704,40 +709,41 @@ mailvar_print (int set) |
704 | if (sym->flags & MAILVAR_HIDDEN) | 709 | if (sym->flags & MAILVAR_HIDDEN) |
705 | continue; | 710 | continue; |
706 | if (sym->flags & MAILVAR_RDONLY) | 711 | if (sym->flags & MAILVAR_RDONLY) |
707 | fprintf (out, "# %s:\n", _("Read-only variable")); | 712 | mu_stream_printf (out, "# %s:\n", _("Read-only variable")); |
708 | print_descr (out, gettext (sym->descr), 1, 3, width - 1, "# "); | 713 | print_descr (out, gettext (sym->descr), 1, 3, width - 1, "# "); |
709 | } | 714 | } |
710 | } | 715 | } |
711 | switch (vartab[i]->type) | 716 | switch (vartab[i]->type) |
712 | { | 717 | { |
713 | case mailvar_type_number: | 718 | case mailvar_type_number: |
714 | fprintf (out, "%s=%d", vartab[i]->name, vartab[i]->value.number); | 719 | mu_stream_printf (out, "%s=%d", |
720 | vartab[i]->name, vartab[i]->value.number); | ||
715 | break; | 721 | break; |
716 | 722 | ||
717 | case mailvar_type_string: | 723 | case mailvar_type_string: |
718 | fprintf (out, "%s=\"%s\"", vartab[i]->name, vartab[i]->value.string); | 724 | mu_stream_printf (out, "%s=\"%s\"", |
725 | vartab[i]->name, vartab[i]->value.string); | ||
719 | break; | 726 | break; |
720 | 727 | ||
721 | case mailvar_type_boolean: | 728 | case mailvar_type_boolean: |
722 | if (!vartab[i]->value.bool) | 729 | if (!vartab[i]->value.bool) |
723 | fprintf (out, "no"); | 730 | mu_stream_printf (out, "no"); |
724 | fprintf (out, "%s", vartab[i]->name); | 731 | mu_stream_printf (out, "%s", vartab[i]->name); |
725 | break; | 732 | break; |
726 | 733 | ||
727 | case mailvar_type_whatever: | 734 | case mailvar_type_whatever: |
728 | fprintf (out, "%s %s", vartab[i]->name, _("oops?")); | 735 | mu_stream_printf (out, "%s %s", vartab[i]->name, _("oops?")); |
729 | } | 736 | } |
730 | fprintf (out, "\n"); | 737 | mu_stream_printf (out, "\n"); |
731 | } | 738 | } |
732 | free (vartab); | 739 | free (vartab); |
733 | 740 | ||
734 | if (out != ofile) | 741 | mu_stream_unref (out); |
735 | pclose (out); | ||
736 | } | 742 | } |
737 | 743 | ||
738 | 744 | ||
739 | void | 745 | void |
740 | mailvar_variable_format (FILE *fp, | 746 | mailvar_variable_format (mu_stream_t stream, |
741 | const struct mailvar_variable *var, | 747 | const struct mailvar_variable *var, |
742 | const char *defval) | 748 | const char *defval) |
743 | { | 749 | { |
... | @@ -745,20 +751,20 @@ mailvar_variable_format (FILE *fp, | ... | @@ -745,20 +751,20 @@ mailvar_variable_format (FILE *fp, |
745 | switch (var->type) | 751 | switch (var->type) |
746 | { | 752 | { |
747 | case mailvar_type_string: | 753 | case mailvar_type_string: |
748 | fprintf (fp, "%s", var->value.string); | 754 | mu_stream_printf (stream, "%s", var->value.string); |
749 | break; | 755 | break; |
750 | 756 | ||
751 | case mailvar_type_number: | 757 | case mailvar_type_number: |
752 | fprintf (fp, "%d", var->value.number); | 758 | mu_stream_printf (stream, "%d", var->value.number); |
753 | break; | 759 | break; |
754 | 760 | ||
755 | case mailvar_type_boolean: | 761 | case mailvar_type_boolean: |
756 | fprintf (fp, "%s", var->set ? "yes" : "no"); | 762 | mu_stream_printf (stream, "%s", var->set ? "yes" : "no"); |
757 | break; | 763 | break; |
758 | 764 | ||
759 | default: | 765 | default: |
760 | if (defval) | 766 | if (defval) |
761 | fprintf (fp, "%s", defval); | 767 | mu_stream_printf (stream, "%s", defval); |
762 | break; | 768 | break; |
763 | } | 769 | } |
764 | } | 770 | } |
... | @@ -773,45 +779,51 @@ static char *typestr[] = | ... | @@ -773,45 +779,51 @@ static char *typestr[] = |
773 | }; | 779 | }; |
774 | 780 | ||
775 | static void | 781 | static void |
776 | describe_symbol (FILE *out, int width, const struct mailvar_symbol *sym) | 782 | describe_symbol (mu_stream_t out, int width, const struct mailvar_symbol *sym) |
777 | { | 783 | { |
778 | int n; | ||
779 | int i, t; | 784 | int i, t; |
780 | const struct mailvar_symbol *ali; | 785 | const struct mailvar_symbol *ali; |
786 | mu_stream_stat_buffer stat; | ||
781 | 787 | ||
782 | n = fprintf (out, "%s", sym->var.name); | 788 | mu_stream_set_stat (out, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT), |
789 | stat); | ||
790 | mu_stream_printf (out, "%s", sym->var.name); | ||
783 | for (ali = sym + 1; ali->var.name && ali->flags & MAILVAR_ALIAS; ali++) | 791 | for (ali = sym + 1; ali->var.name && ali->flags & MAILVAR_ALIAS; ali++) |
784 | { | 792 | { |
785 | size_t len = strlen (ali->var.name) + 2; | 793 | size_t len = strlen (ali->var.name) + 2; |
786 | if (n + len > width) | 794 | if (stat[MU_STREAM_STAT_OUT] + len > width) |
787 | n = fprintf (out, "\n%s", ali->var.name); | 795 | { |
796 | stat[MU_STREAM_STAT_OUT] = 0; | ||
797 | mu_stream_printf (out, "\n%s", ali->var.name); | ||
798 | } | ||
788 | else | 799 | else |
789 | n = fprintf (out, ", %s", ali->var.name); | 800 | mu_stream_printf (out, ", %s", ali->var.name); |
790 | } | 801 | } |
791 | fputc ('\n', out); | 802 | mu_stream_printf (out, "\n"); |
803 | mu_stream_set_stat (out, 0, NULL); | ||
792 | 804 | ||
793 | fprintf (out, _("Type: ")); | 805 | mu_stream_printf (out, _("Type: ")); |
794 | for (i = 0, t = 0; i < sizeof (typestr) / sizeof (typestr[0]); i++) | 806 | for (i = 0, t = 0; i < sizeof (typestr) / sizeof (typestr[0]); i++) |
795 | if (sym->flags & MAILVAR_TYPEMASK (i)) | 807 | if (sym->flags & MAILVAR_TYPEMASK (i)) |
796 | { | 808 | { |
797 | if (t++) | 809 | if (t++) |
798 | fprintf (out, " %s ", _("or")); | 810 | mu_stream_printf (out, " %s ", _("or")); |
799 | fprintf (out, "%s", gettext (typestr[i])); | 811 | mu_stream_printf (out, "%s", gettext (typestr[i])); |
800 | } | 812 | } |
801 | if (!t) | 813 | if (!t) |
802 | fprintf (out, "%s", gettext (typestr[0])); | 814 | mu_stream_printf (out, "%s", gettext (typestr[0])); |
803 | fputc ('\n', out); | 815 | mu_stream_printf (out, "\n"); |
804 | 816 | ||
805 | fprintf (out, "%s", _("Current value: ")); | 817 | mu_stream_printf (out, "%s", _("Current value: ")); |
806 | mailvar_variable_format (out, &sym->var, _("[not set]")); | 818 | mailvar_variable_format (out, &sym->var, _("[not set]")); |
807 | 819 | ||
808 | if (sym->flags & MAILVAR_RDONLY) | 820 | if (sym->flags & MAILVAR_RDONLY) |
809 | fprintf (out, " [%s]", _("read-only")); | 821 | mu_stream_printf (out, " [%s]", _("read-only")); |
810 | fputc ('\n', out); | 822 | mu_stream_printf (out, "\n"); |
811 | 823 | ||
812 | print_descr (out, gettext (sym->descr ? sym->descr : N_("Not documented")), | 824 | print_descr (out, gettext (sym->descr ? sym->descr : N_("Not documented")), |
813 | 1, 1, width - 1, NULL); | 825 | 1, 1, width - 1, NULL); |
814 | fputc ('\n', out); | 826 | mu_stream_printf (out, "\n"); |
815 | } | 827 | } |
816 | 828 | ||
817 | int | 829 | int |
... | @@ -819,10 +831,7 @@ mail_variable (int argc, char **argv) | ... | @@ -819,10 +831,7 @@ mail_variable (int argc, char **argv) |
819 | { | 831 | { |
820 | int pagelines = util_get_crt (); | 832 | int pagelines = util_get_crt (); |
821 | int width = util_getcols (); | 833 | int width = util_getcols (); |
822 | FILE *out = ofile; | 834 | mu_stream_t out = open_pager (pagelines + 1); |
823 | |||
824 | if (pagelines) | ||
825 | out = popen (getenv ("PAGER"), "w"); | ||
826 | 835 | ||
827 | if (argc == 1) | 836 | if (argc == 1) |
828 | { | 837 | { |
... | @@ -840,13 +849,12 @@ mail_variable (int argc, char **argv) | ... | @@ -840,13 +849,12 @@ mail_variable (int argc, char **argv) |
840 | { | 849 | { |
841 | struct mailvar_symbol *sym = find_mailvar_symbol (argv[i]); | 850 | struct mailvar_symbol *sym = find_mailvar_symbol (argv[i]); |
842 | if (!sym) | 851 | if (!sym) |
843 | fprintf (out, "%s: unknown\n", argv[i]); | 852 | mu_stream_printf (out, "%s: unknown\n", argv[i]); |
844 | else | 853 | else |
845 | describe_symbol (out, width, sym); | 854 | describe_symbol (out, width, sym); |
846 | } | 855 | } |
847 | } | 856 | } |
848 | if (out != ofile) | 857 | mu_stream_unref (out); |
849 | pclose (out); | ||
850 | return 0; | 858 | return 0; |
851 | } | 859 | } |
852 | 860 | ... | ... |
... | @@ -241,21 +241,21 @@ static char *cur_p; | ... | @@ -241,21 +241,21 @@ static char *cur_p; |
241 | int | 241 | int |
242 | yyerror (const char *s) | 242 | yyerror (const char *s) |
243 | { | 243 | { |
244 | fprintf (stderr, "%s: ", xargv[0]); | 244 | mu_stream_printf (mu_strerr, "%s: ", xargv[0]); |
245 | fprintf (stderr, "%s", s); | 245 | mu_stream_printf (mu_strerr, "%s", s); |
246 | if (!cur_p) | 246 | if (!cur_p) |
247 | fprintf (stderr, _(" near end")); | 247 | mu_stream_printf (mu_strerr, _(" near end")); |
248 | else if (*cur_p == 0) | 248 | else if (*cur_p == 0) |
249 | { | 249 | { |
250 | int i = (*cur_p == 0) ? cur_ind + 1 : cur_ind; | 250 | int i = (*cur_p == 0) ? cur_ind + 1 : cur_ind; |
251 | if (i == xargc) | 251 | if (i == xargc) |
252 | fprintf (stderr, _(" near end")); | 252 | mu_stream_printf (mu_strerr, _(" near end")); |
253 | else | 253 | else |
254 | fprintf (stderr, _(" near %s"), xargv[i]); | 254 | mu_stream_printf (mu_strerr, _(" near %s"), xargv[i]); |
255 | } | 255 | } |
256 | else | 256 | else |
257 | fprintf (stderr, _(" near %s"), cur_p); | 257 | mu_stream_printf (mu_strerr, _(" near %s"), cur_p); |
258 | fprintf (stderr, "\n"); | 258 | mu_stream_printf (mu_strerr, "\n"); |
259 | return 0; | 259 | return 0; |
260 | } | 260 | } |
261 | 261 | ||
... | @@ -756,13 +756,13 @@ void | ... | @@ -756,13 +756,13 @@ void |
756 | msgset_print (msgset_t *mset) | 756 | msgset_print (msgset_t *mset) |
757 | { | 757 | { |
758 | int i; | 758 | int i; |
759 | printf ("("); | 759 | mu_printf ("("); |
760 | printf ("%d .", mset->msg_part[0]); | 760 | mu_printf ("%d .", mset->msg_part[0]); |
761 | for (i = 1; i < mset->npart; i++) | 761 | for (i = 1; i < mset->npart; i++) |
762 | { | 762 | { |
763 | printf (" %d", mset->msg_part[i]); | 763 | mu_printf (" %d", mset->msg_part[i]); |
764 | } | 764 | } |
765 | printf (")\n"); | 765 | mu_printf (")\n"); |
766 | } | 766 | } |
767 | 767 | ||
768 | int | 768 | int | ... | ... |
... | @@ -30,9 +30,8 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data) | ... | @@ -30,9 +30,8 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data) |
30 | mu_header_t hdr; | 30 | mu_header_t hdr; |
31 | mu_body_t body; | 31 | mu_body_t body; |
32 | mu_stream_t stream; | 32 | mu_stream_t stream; |
33 | char buffer[512]; | 33 | size_t lines = 0; |
34 | size_t n = 0, lines = 0; | 34 | mu_stream_t out; |
35 | FILE *out = ofile; | ||
36 | int pagelines = util_get_crt (); | 35 | int pagelines = util_get_crt (); |
37 | int status; | 36 | int status; |
38 | 37 | ||
... | @@ -56,8 +55,7 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data) | ... | @@ -56,8 +55,7 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data) |
56 | } | 55 | } |
57 | } | 56 | } |
58 | 57 | ||
59 | if (pagelines && lines > pagelines) | 58 | out = open_pager (lines); |
60 | out = popen (getenv ("PAGER"), "w"); | ||
61 | 59 | ||
62 | if (mailvar_get (NULL, "showenvelope", mailvar_type_boolean, 0) == 0) | 60 | if (mailvar_get (NULL, "showenvelope", mailvar_type_boolean, 0) == 0) |
63 | print_envelope (mspec, mesg, "From"); | 61 | print_envelope (mspec, mesg, "From"); |
... | @@ -77,16 +75,16 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data) | ... | @@ -77,16 +75,16 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data) |
77 | continue; | 75 | continue; |
78 | if (mail_header_is_visible (sptr)) | 76 | if (mail_header_is_visible (sptr)) |
79 | { | 77 | { |
80 | fprintf (out, "%s: ", sptr); | 78 | mu_stream_printf (out, "%s: ", sptr); |
81 | mu_header_aget_field_value (hdr, i, &tmp); | 79 | mu_header_aget_field_value (hdr, i, &tmp); |
82 | if (mail_header_is_unfoldable (sptr)) | 80 | if (mail_header_is_unfoldable (sptr)) |
83 | mu_string_unfold (tmp, NULL); | 81 | mu_string_unfold (tmp, NULL); |
84 | util_rfc2047_decode (&tmp); | 82 | util_rfc2047_decode (&tmp); |
85 | fprintf (out, "%s\n", tmp); | 83 | mu_stream_printf (out, "%s\n", tmp); |
86 | free (tmp); | 84 | free (tmp); |
87 | } | 85 | } |
88 | } | 86 | } |
89 | fprintf (out, "\n"); | 87 | mu_stream_printf (out, "\n"); |
90 | mu_message_get_body (mesg, &body); | 88 | mu_message_get_body (mesg, &body); |
91 | status = mu_body_get_streamref (body, &stream); | 89 | status = mu_body_get_streamref (body, &stream); |
92 | } | 90 | } |
... | @@ -96,26 +94,20 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data) | ... | @@ -96,26 +94,20 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data) |
96 | if (status) | 94 | if (status) |
97 | { | 95 | { |
98 | mu_error (_("get_stream error: %s"), mu_strerror (status)); | 96 | mu_error (_("get_stream error: %s"), mu_strerror (status)); |
99 | if (out != ofile) | 97 | mu_stream_unref (out); |
100 | pclose (out); | ||
101 | return 0; | 98 | return 0; |
102 | } | 99 | } |
103 | 100 | ||
104 | /* FIXME: Use mu_stream_copy instead? */ | 101 | mu_stream_copy (out, stream, 0, NULL); |
105 | while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0 | 102 | /* FIXME: |
106 | && n != 0) | ||
107 | { | ||
108 | if (ml_got_interrupt()) | 103 | if (ml_got_interrupt()) |
109 | { | 104 | { |
110 | util_error (_("\nInterrupt")); | 105 | util_error (_("\nInterrupt")); |
111 | break; | 106 | break; |
112 | } | 107 | } |
113 | buffer[n] = '\0'; | 108 | */ |
114 | fprintf (out, "%s", buffer); | ||
115 | } | ||
116 | mu_stream_destroy (&stream); | 109 | mu_stream_destroy (&stream); |
117 | if (out != ofile) | 110 | mu_stream_destroy (&out); |
118 | pclose (out); | ||
119 | 111 | ||
120 | util_mark_read (mesg); | 112 | util_mark_read (mesg); |
121 | 113 | ... | ... |
... | @@ -49,7 +49,7 @@ mail_mbox_close () | ... | @@ -49,7 +49,7 @@ mail_mbox_close () |
49 | 49 | ||
50 | mu_mailbox_get_url (mbox, &url); | 50 | mu_mailbox_get_url (mbox, &url); |
51 | mu_mailbox_messages_count (mbox, &held_count); | 51 | mu_mailbox_messages_count (mbox, &held_count); |
52 | fprintf (ofile, | 52 | mu_stream_printf (ostream, |
53 | ngettext ("Held %d message in %s\n", | 53 | ngettext ("Held %d message in %s\n", |
54 | "Held %d messages in %s\n", | 54 | "Held %d messages in %s\n", |
55 | held_count), | 55 | held_count), |
... | @@ -153,7 +153,7 @@ mail_mbox_commit () | ... | @@ -153,7 +153,7 @@ mail_mbox_commit () |
153 | mu_url_t u = NULL; | 153 | mu_url_t u = NULL; |
154 | 154 | ||
155 | mu_mailbox_get_url (dest_mbox, &u); | 155 | mu_mailbox_get_url (dest_mbox, &u); |
156 | fprintf(ofile, | 156 | mu_stream_printf (ostream, |
157 | ngettext ("Saved %d message in %s\n", | 157 | ngettext ("Saved %d message in %s\n", |
158 | "Saved %d messages in %s\n", | 158 | "Saved %d messages in %s\n", |
159 | saved_count), | 159 | saved_count), | ... | ... |
... | @@ -111,13 +111,13 @@ reply0 (msgset_t *mspec, mu_message_t msg, void *data) | ... | @@ -111,13 +111,13 @@ reply0 (msgset_t *mspec, mu_message_t msg, void *data) |
111 | else | 111 | else |
112 | compose_header_set (&env, MU_HEADER_SUBJECT, "", COMPOSE_REPLACE); | 112 | compose_header_set (&env, MU_HEADER_SUBJECT, "", COMPOSE_REPLACE); |
113 | 113 | ||
114 | fprintf (ofile, "To: %s\n", | 114 | mu_stream_printf (ostream, "To: %s\n", |
115 | compose_header_get (&env, MU_HEADER_TO, "")); | 115 | compose_header_get (&env, MU_HEADER_TO, "")); |
116 | str = compose_header_get (&env, MU_HEADER_CC, NULL); | 116 | str = compose_header_get (&env, MU_HEADER_CC, NULL); |
117 | if (str) | 117 | if (str) |
118 | fprintf (ofile, "Cc: %s\n", str); | 118 | mu_stream_printf (ostream, "Cc: %s\n", str); |
119 | fprintf (ofile, "Subject: %s\n\n", | 119 | mu_stream_printf (ostream, "Subject: %s\n\n", |
120 | compose_header_get (&env, MU_HEADER_SUBJECT, "")); | 120 | compose_header_get (&env, MU_HEADER_SUBJECT, "")); |
121 | 121 | ||
122 | make_in_reply_to (&env, msg); | 122 | make_in_reply_to (&env, msg); |
123 | make_references (&env, msg); | 123 | make_references (&env, msg); | ... | ... |
... | @@ -31,7 +31,7 @@ process_list (int argc, char **argv, | ... | @@ -31,7 +31,7 @@ process_list (int argc, char **argv, |
31 | if (argc == 1) | 31 | if (argc == 1) |
32 | { | 32 | { |
33 | if (mu_list_is_empty (*list)) | 33 | if (mu_list_is_empty (*list)) |
34 | fprintf (ofile, _(msg)); | 34 | mu_stream_printf (ostream, "%s", _(msg)); |
35 | else | 35 | else |
36 | util_slist_print (*list, 1); | 36 | util_slist_print (*list, 1); |
37 | return 0; | 37 | return 0; |
... | @@ -125,7 +125,8 @@ mail_nosender (int argc, char **argv) | ... | @@ -125,7 +125,8 @@ mail_nosender (int argc, char **argv) |
125 | if (argc == 1) | 125 | if (argc == 1) |
126 | { | 126 | { |
127 | util_slist_destroy (&sender_headers); | 127 | util_slist_destroy (&sender_headers); |
128 | fprintf (ofile, _("Sender address is obtained from the envelope\n")); | 128 | mu_stream_printf (ostream, |
129 | _("Sender address is obtained from the envelope\n")); | ||
129 | } | 130 | } |
130 | else | 131 | else |
131 | while (--argc) | 132 | while (--argc) | ... | ... |
... | @@ -52,7 +52,7 @@ list_headers (void *item, void *data) | ... | @@ -52,7 +52,7 @@ list_headers (void *item, void *data) |
52 | 52 | ||
53 | if (!name || strcmp (name, hp->name) == 0) | 53 | if (!name || strcmp (name, hp->name) == 0) |
54 | { | 54 | { |
55 | printf ("%s: %s\n", hp->name, hp->value); | 55 | mu_stream_printf (ostream, "%s: %s\n", hp->name, hp->value); |
56 | } | 56 | } |
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
... | @@ -347,27 +347,27 @@ save_dead_message (compose_env_t *env) | ... | @@ -347,27 +347,27 @@ save_dead_message (compose_env_t *env) |
347 | { | 347 | { |
348 | if (mailvar_get (NULL, "save", mailvar_type_boolean, 0) == 0) | 348 | if (mailvar_get (NULL, "save", mailvar_type_boolean, 0) == 0) |
349 | { | 349 | { |
350 | FILE *fp = fopen (getenv ("DEAD"), | 350 | mu_stream_t dead_letter; |
351 | mailvar_get (NULL, "appenddeadletter", | 351 | int rc; |
352 | mailvar_type_boolean, 0) == 0 ? | 352 | const char *name = getenv ("DEAD"); |
353 | "a" : "w"); | 353 | |
354 | 354 | /* FIXME: Use MU_STREAM_APPEND if appenddeadletter, instead of the | |
355 | if (!fp) | 355 | stream manipulations below */ |
356 | rc = mu_file_stream_create (&dead_letter, name, MU_STREAM_WRITE); | ||
357 | if (rc) | ||
356 | { | 358 | { |
357 | util_error (_("Cannot open file %s: %s"), getenv ("DEAD"), | 359 | util_error (_("Cannot open file %s: %s"), name, strerror (rc)); |
358 | strerror (errno)); | ||
359 | return 1; | 360 | return 1; |
360 | } | 361 | } |
362 | if (mailvar_get (NULL, "appenddeadletter", | ||
363 | mailvar_type_boolean, 0) == 0) | ||
364 | mu_stream_seek (dead_letter, 0, MU_SEEK_END, NULL); | ||
361 | else | 365 | else |
362 | { | 366 | mu_stream_truncate (dead_letter, 0); |
363 | char *buf = NULL; | 367 | |
364 | size_t n; | 368 | mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL); |
365 | rewind (env->file); | 369 | mu_stream_copy (dead_letter, env->compstr, 0, NULL); |
366 | while (getline (&buf, &n, env->file) > 0) | 370 | mu_stream_destroy (&dead_letter); |
367 | fputs (buf, fp); | ||
368 | fclose (fp); | ||
369 | free (buf); | ||
370 | } | ||
371 | } | 371 | } |
372 | return 0; | 372 | return 0; |
373 | } | 373 | } |
... | @@ -433,28 +433,22 @@ send_message (mu_message_t msg) | ... | @@ -433,28 +433,22 @@ send_message (mu_message_t msg) |
433 | addresses on the command line and message contents on standard input. */ | 433 | addresses on the command line and message contents on standard input. */ |
434 | 434 | ||
435 | int | 435 | int |
436 | mail_send0 (compose_env_t * env, int save_to) | 436 | mail_send0 (compose_env_t *env, int save_to) |
437 | { | 437 | { |
438 | int done = 0; | 438 | int done = 0; |
439 | int fd, rc; | 439 | int rc; |
440 | char *filename; | ||
441 | char *savefile = NULL; | 440 | char *savefile = NULL; |
442 | int int_cnt; | 441 | int int_cnt; |
443 | char *escape; | 442 | char *escape; |
444 | 443 | ||
445 | rc = mu_tempfile (NULL, 0, &fd, &filename); | 444 | /* Prepare environment */ |
445 | rc = mu_temp_file_stream_create (&env->compstr, NULL, 0); | ||
446 | if (rc) | 446 | if (rc) |
447 | { | 447 | { |
448 | util_error (_("Cannot open temporary file: %s"), mu_strerror (rc)); | 448 | util_error (_("Cannot open temporary file: %s"), mu_strerror (rc)); |
449 | return 1; | 449 | return 1; |
450 | } | 450 | } |
451 | 451 | ||
452 | /* Prepare environment */ | ||
453 | env = env; | ||
454 | env->filename = filename; | ||
455 | env->file = fdopen (fd, "w+"); | ||
456 | env->ofile = ofile; | ||
457 | |||
458 | ml_clear_interrupt (); | 452 | ml_clear_interrupt (); |
459 | int_cnt = 0; | 453 | int_cnt = 0; |
460 | while (!done) | 454 | while (!done) |
... | @@ -466,7 +460,7 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -466,7 +460,7 @@ mail_send0 (compose_env_t * env, int save_to) |
466 | { | 460 | { |
467 | if (mailvar_get (NULL, "ignore", mailvar_type_boolean, 0) == 0) | 461 | if (mailvar_get (NULL, "ignore", mailvar_type_boolean, 0) == 0) |
468 | { | 462 | { |
469 | fprintf (stdout, "@\n"); | 463 | mu_stream_printf (ostream, "@\n"); |
470 | } | 464 | } |
471 | else | 465 | else |
472 | { | 466 | { |
... | @@ -502,7 +496,7 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -502,7 +496,7 @@ mail_send0 (compose_env_t * env, int save_to) |
502 | && buf[0] == escape[0]) | 496 | && buf[0] == escape[0]) |
503 | { | 497 | { |
504 | if (buf[1] == buf[0]) | 498 | if (buf[1] == buf[0]) |
505 | fprintf (env->file, "%s\n", buf + 1); | 499 | mu_stream_printf (env->compstr, "%s\n", buf + 1); |
506 | else if (buf[1] == '.') | 500 | else if (buf[1] == '.') |
507 | done = 1; | 501 | done = 1; |
508 | else if (buf[1] == 'x') | 502 | else if (buf[1] == 'x') |
... | @@ -515,8 +509,6 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -515,8 +509,6 @@ mail_send0 (compose_env_t * env, int save_to) |
515 | struct mu_wordsplit ws; | 509 | struct mu_wordsplit ws; |
516 | int status; | 510 | int status; |
517 | 511 | ||
518 | ofile = env->file; | ||
519 | |||
520 | if (mu_wordsplit (buf + 1, &ws, MU_WRDSF_DEFFLAGS) == 0) | 512 | if (mu_wordsplit (buf + 1, &ws, MU_WRDSF_DEFFLAGS) == 0) |
521 | { | 513 | { |
522 | if (ws.ws_wordc > 0) | 514 | if (ws.ws_wordc > 0) |
... | @@ -539,13 +531,11 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -539,13 +531,11 @@ mail_send0 (compose_env_t * env, int save_to) |
539 | util_error (_("Cannot parse escape sequence: %s"), | 531 | util_error (_("Cannot parse escape sequence: %s"), |
540 | mu_wordsplit_strerror (&ws)); | 532 | mu_wordsplit_strerror (&ws)); |
541 | } | 533 | } |
542 | |||
543 | ofile = env->ofile; | ||
544 | } | 534 | } |
545 | } | 535 | } |
546 | else | 536 | else |
547 | fprintf (env->file, "%s\n", buf); | 537 | mu_stream_printf (env->compstr, "%s\n", buf); |
548 | fflush (env->file); | 538 | mu_stream_flush (env->compstr); |
549 | free (buf); | 539 | free (buf); |
550 | } | 540 | } |
551 | 541 | ||
... | @@ -553,9 +543,7 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -553,9 +543,7 @@ mail_send0 (compose_env_t * env, int save_to) |
553 | if (int_cnt) | 543 | if (int_cnt) |
554 | { | 544 | { |
555 | save_dead_message (env); | 545 | save_dead_message (env); |
556 | fclose (env->file); | 546 | mu_stream_destroy (&env->compstr); |
557 | remove (filename); | ||
558 | free (filename); | ||
559 | return 1; | 547 | return 1; |
560 | } | 548 | } |
561 | 549 | ||
... | @@ -571,115 +559,100 @@ mail_send0 (compose_env_t * env, int save_to) | ... | @@ -571,115 +559,100 @@ mail_send0 (compose_env_t * env, int save_to) |
571 | 559 | ||
572 | if (util_header_expand (&env->header) == 0) | 560 | if (util_header_expand (&env->header) == 0) |
573 | { | 561 | { |
562 | mu_message_t msg = NULL; | ||
574 | int rc; | 563 | int rc; |
575 | mu_stream_t instr; | 564 | int status = 0; |
565 | |||
566 | mu_message_create (&msg, NULL); | ||
567 | |||
568 | /* Fill the body. */ | ||
569 | mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL); | ||
570 | rc = fill_body (msg, env->compstr); | ||
576 | 571 | ||
577 | rc = mu_file_stream_create (&instr, filename, MU_STREAM_READ); | 572 | if (rc == 0) |
578 | if (rc) | ||
579 | mu_error (_("cannot open temporary stream `%s' for reading: %s"), | ||
580 | filename, mu_strerror (rc)); | ||
581 | else | ||
582 | { | 573 | { |
583 | mu_message_t msg = NULL; | 574 | /* Save outgoing message */ |
584 | int rc; | 575 | if (save_to) |
585 | int status = 0; | ||
586 | |||
587 | mu_message_create (&msg, NULL); | ||
588 | |||
589 | /* Fill the body. */ | ||
590 | rc = fill_body (msg, instr); | ||
591 | mu_stream_destroy (&instr); | ||
592 | |||
593 | if (rc == 0) | ||
594 | { | 576 | { |
595 | /* Save outgoing message */ | 577 | char *tmp = compose_header_get (env, MU_HEADER_TO, NULL); |
596 | if (save_to) | 578 | mu_address_t addr = NULL; |
597 | { | ||
598 | char *tmp = compose_header_get (env, MU_HEADER_TO, NULL); | ||
599 | mu_address_t addr = NULL; | ||
600 | 579 | ||
601 | mu_address_create (&addr, tmp); | 580 | mu_address_create (&addr, tmp); |
602 | mu_address_aget_email (addr, 1, &savefile); | 581 | mu_address_aget_email (addr, 1, &savefile); |
603 | mu_address_destroy (&addr); | 582 | mu_address_destroy (&addr); |
604 | if (savefile) | ||
605 | { | ||
606 | char *p = strchr (savefile, '@'); | ||
607 | if (p) | ||
608 | *p = 0; | ||
609 | } | ||
610 | } | ||
611 | util_save_outgoing (msg, savefile); | ||
612 | if (savefile) | 583 | if (savefile) |
613 | free (savefile); | 584 | { |
585 | char *p = strchr (savefile, '@'); | ||
586 | if (p) | ||
587 | *p = 0; | ||
588 | } | ||
589 | } | ||
590 | util_save_outgoing (msg, savefile); | ||
591 | if (savefile) | ||
592 | free (savefile); | ||
614 | 593 | ||
615 | /* Check if we need to save the message to files or pipes. */ | 594 | /* Check if we need to save the message to files or pipes. */ |
616 | if (env->outfiles) | 595 | if (env->outfiles) |
596 | { | ||
597 | int i; | ||
598 | for (i = 0; i < env->nfiles; i++) | ||
617 | { | 599 | { |
618 | int i; | 600 | /* Pipe to a cmd. */ |
619 | for (i = 0; i < env->nfiles; i++) | 601 | if (env->outfiles[i][0] == '|') |
602 | status = msg_to_pipe (env->outfiles[i] + 1, msg); | ||
603 | /* Save to a file. */ | ||
604 | else | ||
620 | { | 605 | { |
621 | /* Pipe to a cmd. */ | 606 | mu_mailbox_t mbx = NULL; |
622 | if (env->outfiles[i][0] == '|') | 607 | status = mu_mailbox_create_default (&mbx, |
623 | status = msg_to_pipe (env->outfiles[i] + 1, msg); | 608 | env->outfiles[i]); |
624 | /* Save to a file. */ | 609 | if (status == 0) |
625 | else | ||
626 | { | 610 | { |
627 | mu_mailbox_t mbx = NULL; | 611 | status = mu_mailbox_open (mbx, MU_STREAM_WRITE |
628 | status = mu_mailbox_create_default (&mbx, | 612 | | MU_STREAM_CREAT); |
629 | env->outfiles[i]); | ||
630 | if (status == 0) | 613 | if (status == 0) |
631 | { | 614 | { |
632 | status = mu_mailbox_open (mbx, MU_STREAM_WRITE | 615 | status = mu_mailbox_append_message (mbx, msg); |
633 | | MU_STREAM_CREAT); | 616 | if (status) |
634 | if (status == 0) | 617 | util_error (_("Cannot append message: %s"), |
635 | { | 618 | mu_strerror (status)); |
636 | status = mu_mailbox_append_message (mbx, msg); | 619 | mu_mailbox_close (mbx); |
637 | if (status) | ||
638 | util_error (_("Cannot append message: %s"), | ||
639 | mu_strerror (status)); | ||
640 | mu_mailbox_close (mbx); | ||
641 | } | ||
642 | mu_mailbox_destroy (&mbx); | ||
643 | } | 620 | } |
644 | if (status) | 621 | mu_mailbox_destroy (&mbx); |
645 | util_error (_("Cannot create mailbox %s: %s"), | ||
646 | env->outfiles[i], | ||
647 | mu_strerror (status)); | ||
648 | } | 622 | } |
623 | if (status) | ||
624 | util_error (_("Cannot create mailbox %s: %s"), | ||
625 | env->outfiles[i], | ||
626 | mu_strerror (status)); | ||
649 | } | 627 | } |
650 | } | 628 | } |
651 | 629 | } | |
652 | /* Do we need to Send the message on the wire? */ | 630 | |
653 | if (status == 0 && | 631 | /* Do we need to Send the message on the wire? */ |
654 | (compose_header_get (env, MU_HEADER_TO, NULL) || | 632 | if (status == 0 && |
655 | compose_header_get (env, MU_HEADER_CC, NULL) || | 633 | (compose_header_get (env, MU_HEADER_TO, NULL) || |
656 | compose_header_get (env, MU_HEADER_BCC, NULL))) | 634 | compose_header_get (env, MU_HEADER_CC, NULL) || |
635 | compose_header_get (env, MU_HEADER_BCC, NULL))) | ||
636 | { | ||
637 | mu_message_set_header (msg, env->header, NULL); | ||
638 | env->header = NULL; | ||
639 | status = send_message (msg); | ||
640 | if (status) | ||
657 | { | 641 | { |
658 | mu_message_set_header (msg, env->header, NULL); | 642 | mu_error (_("cannot send message: %s"), |
659 | env->header = NULL; | 643 | mu_strerror (status)); |
660 | status = send_message (msg); | 644 | save_dead_message (env); |
661 | if (status) | ||
662 | { | ||
663 | mu_error (_("cannot send message: %s"), | ||
664 | mu_strerror (status)); | ||
665 | save_dead_message (env); | ||
666 | } | ||
667 | } | 645 | } |
668 | } | 646 | } |
669 | fclose (env->file); | 647 | } |
670 | mu_message_destroy (&msg, NULL); | 648 | mu_stream_destroy (&env->compstr); |
671 | remove (filename); | 649 | mu_message_destroy (&msg, NULL); |
672 | free (filename); | 650 | return status; |
673 | return status; | ||
674 | } | ||
675 | } | 651 | } |
676 | else | 652 | else |
677 | save_dead_message (env); | 653 | save_dead_message (env); |
678 | 654 | ||
679 | fclose (env->file); | 655 | mu_stream_destroy (&env->compstr); |
680 | |||
681 | remove (filename); | ||
682 | free (filename); | ||
683 | return 1; | 656 | return 1; |
684 | } | 657 | } |
685 | 658 | ... | ... |
... | @@ -29,7 +29,7 @@ mail_setenv (int argc, char **argv) | ... | @@ -29,7 +29,7 @@ mail_setenv (int argc, char **argv) |
29 | char **p; | 29 | char **p; |
30 | 30 | ||
31 | for (p = environ; *p; p++) | 31 | for (p = environ; *p; p++) |
32 | printf ("%s\n", *p); | 32 | mu_stream_printf (ostream, "%s\n", *p); |
33 | } | 33 | } |
34 | else | 34 | else |
35 | { | 35 | { | ... | ... |
... | @@ -60,81 +60,65 @@ expand_bang (char **pbuf) | ... | @@ -60,81 +60,65 @@ expand_bang (char **pbuf) |
60 | int | 60 | int |
61 | mail_execute (int shell, int argc, char **argv) | 61 | mail_execute (int shell, int argc, char **argv) |
62 | { | 62 | { |
63 | pid_t pid; | 63 | int xargc, i, status, rc; |
64 | char *buf = NULL; | 64 | char **xargv; |
65 | char *argv0 = NULL; | 65 | char *buf; |
66 | 66 | ||
67 | if (argc) | 67 | if (argc == 0) |
68 | { | 68 | { |
69 | argv0 = argv[0]; | 69 | /* No arguments mean execute a copy of the user shell */ |
70 | 70 | shell = 1; | |
71 | /* Skip leading whitespace from argv[0] */ | ||
72 | while (mu_isspace (**argv)) | ||
73 | (*argv)++; | ||
74 | } | 71 | } |
72 | |||
73 | xargc = argc; | ||
74 | if (shell && argc < 3) | ||
75 | xargc = 3; | ||
76 | xargv = xcalloc (xargc + 1, sizeof (xargv[0])); | ||
77 | |||
78 | for (i = 0; i < argc; i++) | ||
79 | xargv[i] = argv[i]; | ||
75 | 80 | ||
76 | /* Expand arguments if required */ | 81 | /* Expand arguments if required */ |
77 | if (mailvar_get (NULL, "bang", mailvar_type_boolean, 0) == 0) | 82 | if (mailvar_get (NULL, "bang", mailvar_type_boolean, 0) == 0) |
78 | { | 83 | { |
79 | int i; | 84 | int i; |
80 | 85 | ||
81 | for (i = 0; i < argc; i++) | 86 | for (i = 0; i < xargc; i++) |
82 | expand_bang (argv + i); | 87 | expand_bang (xargv + i); |
83 | } | 88 | } |
84 | 89 | ||
85 | /* Construct command line and save it to gnu-last-command variable */ | 90 | /* Reconstruct the command line and save it to gnu-last-command variable. |
86 | mu_argcv_string (argc, argv, &buf); | 91 | Important: use argc (not xargc)! |
92 | */ | ||
93 | mu_argcv_string (argc, xargv, &buf); | ||
87 | mailvar_set ("gnu-last-command", buf, mailvar_type_string, | 94 | mailvar_set ("gnu-last-command", buf, mailvar_type_string, |
88 | MOPTF_QUIET|MOPTF_OVERWRITE); | 95 | MOPTF_QUIET | MOPTF_OVERWRITE); |
89 | 96 | ||
90 | /* Do actual work */ | 97 | if (shell) |
91 | |||
92 | pid = fork (); | ||
93 | if (pid == 0) | ||
94 | { | 98 | { |
95 | if (shell) | 99 | xargv[0] = getenv ("SHELL"); |
100 | if (argc == 0) | ||
101 | xargv[1] = NULL; | ||
102 | else | ||
96 | { | 103 | { |
97 | if (argc == 0) | 104 | xargv[1] = "-c"; |
98 | { | 105 | xargv[2] = buf; |
99 | argv = xmalloc (sizeof (argv[0]) * 2); | 106 | xargv[3] = NULL; |
100 | argv[0] = getenv ("SHELL"); | ||
101 | argv[1] = NULL; | ||
102 | argc = 1; | ||
103 | } | ||
104 | else | ||
105 | { | ||
106 | /* 1(shell) + 1 (-c) + 1(arg) + 1 (null) = 4 */ | ||
107 | argv = xmalloc (4 * (sizeof (argv[0]))); | ||
108 | |||
109 | argv[0] = getenv ("SHELL"); | ||
110 | argv[1] = "-c"; | ||
111 | argv[2] = buf; | ||
112 | argv[3] = NULL; | ||
113 | |||
114 | argc = 3; | ||
115 | } | ||
116 | } | 107 | } |
117 | 108 | } | |
118 | execvp (argv[0], argv); | 109 | |
119 | exit (1); | 110 | rc = mu_spawnvp (xargv[0], xargv, &status); |
120 | } | 111 | if (rc) |
121 | else | ||
122 | { | 112 | { |
123 | if (argv0) /* Restore argv[0], else mu_argcv_free will coredump */ | 113 | mu_diag_funcall (MU_DIAG_ERROR, "mu_spawnvp", xargv[0], rc); |
124 | argv[0] = argv0; | ||
125 | free (buf); | ||
126 | if (pid > 0) | ||
127 | { | ||
128 | while (waitpid (pid, NULL, 0) == -1) | ||
129 | /* do nothing */; | ||
130 | return 0; | ||
131 | } | ||
132 | else /* if (pid < 0) */ | ||
133 | { | ||
134 | mu_error ("fork failed: %s", mu_strerror (errno)); | ||
135 | return 1; | ||
136 | } | ||
137 | } | 114 | } |
115 | /* FIXME: | ||
116 | else if (status) | ||
117 | mu_diag_output (MU_DIAG_NOTICE, .... | ||
118 | */ | ||
119 | free (buf); | ||
120 | free (xargv); | ||
121 | return rc; | ||
138 | } | 122 | } |
139 | 123 | ||
140 | /* | 124 | /* | ... | ... |
... | @@ -29,11 +29,11 @@ size0 (msgset_t *mspec, mu_message_t msg, void *data) | ... | @@ -29,11 +29,11 @@ size0 (msgset_t *mspec, mu_message_t msg, void *data) |
29 | mu_message_size (msg, &size); | 29 | mu_message_size (msg, &size); |
30 | mu_message_lines (msg, &lines); | 30 | mu_message_lines (msg, &lines); |
31 | 31 | ||
32 | fprintf (ofile, "%c%2lu %3lu/%-5lu\n", | 32 | mu_stream_printf (ostream, "%c%2lu %3lu/%-5lu\n", |
33 | is_current_message (mspec->msg_part[0]) ? '>' : ' ', | 33 | is_current_message (mspec->msg_part[0]) ? '>' : ' ', |
34 | (unsigned long) mspec->msg_part[0], | 34 | (unsigned long) mspec->msg_part[0], |
35 | (unsigned long) lines, | 35 | (unsigned long) lines, |
36 | (unsigned long) size); | 36 | (unsigned long) size); |
37 | return 0; | 37 | return 0; |
38 | } | 38 | } |
39 | 39 | ... | ... |
... | @@ -20,19 +20,24 @@ | ... | @@ -20,19 +20,24 @@ |
20 | static char * | 20 | static char * |
21 | source_readline (void *closure, int cont MU_ARG_UNUSED) | 21 | source_readline (void *closure, int cont MU_ARG_UNUSED) |
22 | { | 22 | { |
23 | FILE *fp = closure; | 23 | mu_stream_t input = closure; |
24 | size_t s = 0; | 24 | size_t size = 0, n; |
25 | char *buf = NULL; | 25 | char *buf = NULL; |
26 | 26 | int rc; | |
27 | if (getline (&buf, &s, fp) >= 0) | 27 | |
28 | rc = mu_stream_getline (input, &buf, &size, &n); | ||
29 | if (rc) | ||
28 | { | 30 | { |
29 | mu_rtrim_class (buf, MU_CTYPE_SPACE); | 31 | mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_getline", NULL, rc); |
30 | mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, | 32 | return NULL; |
31 | MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE, NULL); | ||
32 | return buf; | ||
33 | } | 33 | } |
34 | 34 | if (n == 0) | |
35 | return NULL; | 35 | return NULL; |
36 | |||
37 | mu_rtrim_class (buf, MU_CTYPE_SPACE); | ||
38 | mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, | ||
39 | MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE, NULL); | ||
40 | return buf; | ||
36 | } | 41 | } |
37 | 42 | ||
38 | /* | 43 | /* |
... | @@ -42,9 +47,10 @@ source_readline (void *closure, int cont MU_ARG_UNUSED) | ... | @@ -42,9 +47,10 @@ source_readline (void *closure, int cont MU_ARG_UNUSED) |
42 | int | 47 | int |
43 | mail_source (int argc, char **argv) | 48 | mail_source (int argc, char **argv) |
44 | { | 49 | { |
45 | FILE *fp; | 50 | mu_stream_t input; |
46 | int save_term; | 51 | int save_term; |
47 | struct mu_locus locus; | 52 | struct mu_locus locus; |
53 | int rc; | ||
48 | 54 | ||
49 | if (argc != 2) | 55 | if (argc != 2) |
50 | { | 56 | { |
... | @@ -52,12 +58,12 @@ mail_source (int argc, char **argv) | ... | @@ -52,12 +58,12 @@ mail_source (int argc, char **argv) |
52 | util_error (_("source requires a single argument")); | 58 | util_error (_("source requires a single argument")); |
53 | return 1; | 59 | return 1; |
54 | } | 60 | } |
55 | 61 | ||
56 | fp = fopen (argv[1], "r"); | 62 | rc = mu_file_stream_create (&input, argv[1], MU_STREAM_READ); |
57 | if (!fp) | 63 | if (rc) |
58 | { | 64 | { |
59 | if (errno != ENOENT) | 65 | if (rc != ENOENT) |
60 | util_error(_("Cannot open `%s': %s"), argv[1], strerror(errno)); | 66 | util_error(_("Cannot open `%s': %s"), argv[1], strerror (rc)); |
61 | return 1; | 67 | return 1; |
62 | } | 68 | } |
63 | 69 | ||
... | @@ -68,10 +74,10 @@ mail_source (int argc, char **argv) | ... | @@ -68,10 +74,10 @@ mail_source (int argc, char **argv) |
68 | locus.mu_col = 0; | 74 | locus.mu_col = 0; |
69 | mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, | 75 | mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, |
70 | MU_IOCTL_LOGSTREAM_SET_LOCUS, &locus); | 76 | MU_IOCTL_LOGSTREAM_SET_LOCUS, &locus); |
71 | mail_mainloop (source_readline, fp, 0); | 77 | mail_mainloop (source_readline, input, 0); |
72 | interactive = save_term; | 78 | interactive = save_term; |
73 | mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, | 79 | mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM, |
74 | MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL); | 80 | MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL); |
75 | fclose (fp); | 81 | mu_stream_unref (input); |
76 | return 0; | 82 | return 0; |
77 | } | 83 | } | ... | ... |
... | @@ -24,21 +24,20 @@ show_part (struct mime_descend_closure *closure, void *data) | ... | @@ -24,21 +24,20 @@ show_part (struct mime_descend_closure *closure, void *data) |
24 | size_t width; | 24 | size_t width; |
25 | size_t size = 0; | 25 | size_t size = 0; |
26 | 26 | ||
27 | width = fprint_msgset (ofile, closure->msgset); | 27 | format_msgset (ostream, closure->msgset, &width); |
28 | for (; width < 5; width++) | 28 | for (; width < 5; width++) |
29 | fputc (' ', ofile); | 29 | mu_stream_write (ostream, " ", 1, NULL); |
30 | 30 | ||
31 | fprintf (ofile, " %-25s", closure->type); | 31 | mu_stream_printf (ostream, " %-25s", closure->type); |
32 | 32 | ||
33 | mu_message_size (closure->message, &size); | 33 | mu_message_size (closure->message, &size); |
34 | if (size < 1024) | 34 | if (size < 1024) |
35 | fprintf (ofile, " %4lu", (unsigned long) size); | 35 | mu_stream_printf (ostream, " %4lu", (unsigned long) size); |
36 | else if (size < 1024*1024) | 36 | else if (size < 1024*1024) |
37 | fprintf (ofile, "%4luK", (unsigned long) size / 1024); | 37 | mu_stream_printf (ostream, "%4luK", (unsigned long) size / 1024); |
38 | else | 38 | else |
39 | fprintf (ofile, "%4luM", (unsigned long) size / 1024 / 1024); | 39 | mu_stream_printf (ostream, "%4luM", (unsigned long) size / 1024 / 1024); |
40 | 40 | mu_stream_printf (ostream, "\n"); | |
41 | fprintf (ofile, "\n"); | ||
42 | return 0; | 41 | return 0; |
43 | } | 42 | } |
44 | 43 | ... | ... |
... | @@ -60,16 +60,20 @@ mail_summary (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | ... | @@ -60,16 +60,20 @@ mail_summary (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
60 | { | 60 | { |
61 | mu_url_t url = NULL; | 61 | mu_url_t url = NULL; |
62 | mu_mailbox_get_url (mbox, &url); | 62 | mu_mailbox_get_url (mbox, &url); |
63 | printf("\"%s\": ", util_url_to_string (url)); | 63 | mu_stream_printf (ostream, "\"%s\": ", util_url_to_string (url)); |
64 | } | 64 | } |
65 | printf (ngettext ("%d message", "%d messages", count), count); | 65 | mu_stream_printf (ostream, |
66 | ngettext ("%d message", "%d messages", count), count); | ||
66 | if (mnew > 0) | 67 | if (mnew > 0) |
67 | printf (ngettext (" %d new", " %d new", mnew), mnew); | 68 | mu_stream_printf (ostream, ngettext (" %d new", " %d new", mnew), mnew); |
68 | if (mseen > 0) | 69 | if (mseen > 0) |
69 | printf (ngettext (" %d unread", " %d unread", mseen), mseen); | 70 | mu_stream_printf (ostream, ngettext (" %d unread", " %d unread", mseen), |
71 | mseen); | ||
70 | if (mdelete > 0) | 72 | if (mdelete > 0) |
71 | printf (ngettext (" %d deleted", " %d deleted", mdelete), mdelete); | 73 | mu_stream_printf (ostream, |
72 | printf("\n"); | 74 | ngettext (" %d deleted", " %d deleted", mdelete), |
75 | mdelete); | ||
76 | mu_stream_printf (ostream, "\n"); | ||
73 | 77 | ||
74 | /* Set the cursor. */ | 78 | /* Set the cursor. */ |
75 | set_cursor ((first_new == 0) ? ((first_unread == 0) ? | 79 | set_cursor ((first_new == 0) ? ((first_unread == 0) ? | ... | ... |
... | @@ -25,23 +25,23 @@ static int | ... | @@ -25,23 +25,23 @@ static int |
25 | top0 (msgset_t *mspec, mu_message_t msg, void *data) | 25 | top0 (msgset_t *mspec, mu_message_t msg, void *data) |
26 | { | 26 | { |
27 | mu_stream_t stream; | 27 | mu_stream_t stream; |
28 | char buf[512]; | 28 | char *buf = NULL; |
29 | size_t n; | 29 | size_t size = 0, n; |
30 | int lines; | 30 | int lines; |
31 | 31 | ||
32 | if (mailvar_get (&lines, "toplines", mailvar_type_number, 1) | 32 | if (mailvar_get (&lines, "toplines", mailvar_type_number, 1) |
33 | || lines < 0) | 33 | || lines < 0) |
34 | return 1; | 34 | return 1; |
35 | 35 | ||
36 | /* FIXME: Use mu_stream_copy */ | ||
37 | mu_message_get_streamref (msg, &stream); | 36 | mu_message_get_streamref (msg, &stream); |
38 | for (; lines > 0; lines--) | 37 | for (; lines > 0; lines--) |
39 | { | 38 | { |
40 | int status = mu_stream_readline (stream, buf, sizeof (buf), &n); | 39 | int status = mu_stream_getline (stream, &buf, &size, &n); |
41 | if (status != 0 || n == 0) | 40 | if (status != 0 || n == 0) |
42 | break; | 41 | break; |
43 | fprintf (ofile, "%s", buf); | 42 | mu_stream_printf (ostream, "%s", buf); |
44 | } | 43 | } |
44 | free (buf); | ||
45 | mu_stream_destroy (&stream); | 45 | mu_stream_destroy (&stream); |
46 | set_cursor (mspec->msg_part[0]); | 46 | set_cursor (mspec->msg_part[0]); |
47 | 47 | ... | ... |
... | @@ -31,7 +31,7 @@ mail_unset (int argc, char **argv) | ... | @@ -31,7 +31,7 @@ mail_unset (int argc, char **argv) |
31 | else | 31 | else |
32 | { | 32 | { |
33 | int status = 0, i = 1; | 33 | int status = 0, i = 1; |
34 | for (i=1; i < argc; i++) | 34 | for (i = 1; i < argc; i++) |
35 | { | 35 | { |
36 | char *buf = xmalloc ((7+strlen (argv[i])) * sizeof (char)); | 36 | char *buf = xmalloc ((7+strlen (argv[i])) * sizeof (char)); |
37 | strcpy (buf, "set no"); | 37 | strcpy (buf, "set no"); | ... | ... |
... | @@ -278,22 +278,20 @@ util_help (void *table, size_t nmemb, size_t size, const char *word) | ... | @@ -278,22 +278,20 @@ util_help (void *table, size_t nmemb, size_t size, const char *word) |
278 | if (!word) | 278 | if (!word) |
279 | { | 279 | { |
280 | int i = 0; | 280 | int i = 0; |
281 | FILE *out = stdout; | 281 | mu_stream_t out; |
282 | char *p; | 282 | char *p; |
283 | 283 | ||
284 | if (mailvar_get (NULL, "crt", mailvar_type_boolean, 0) == 0) | 284 | out = open_pager (util_screen_lines () + 1); |
285 | out = popen (getenv ("PAGER"), "w"); | ||
286 | 285 | ||
287 | for (p = table, i = 0; i < nmemb; i++, p += size) | 286 | for (p = table, i = 0; i < nmemb; i++, p += size) |
288 | { | 287 | { |
289 | struct mail_command *cp = (struct mail_command *)p; | 288 | struct mail_command *cp = (struct mail_command *)p; |
290 | if (cp->synopsis == NULL) | 289 | if (cp->synopsis == NULL) |
291 | continue; | 290 | continue; |
292 | fprintf (out, "%s\n", cp->synopsis); | 291 | mu_stream_printf (out, "%s\n", cp->synopsis); |
293 | } | 292 | } |
294 | 293 | ||
295 | if (out != stdout) | 294 | mu_stream_unref (out); |
296 | pclose (out); | ||
297 | 295 | ||
298 | return 0; | 296 | return 0; |
299 | } | 297 | } |
... | @@ -302,11 +300,11 @@ util_help (void *table, size_t nmemb, size_t size, const char *word) | ... | @@ -302,11 +300,11 @@ util_help (void *table, size_t nmemb, size_t size, const char *word) |
302 | int status = 0; | 300 | int status = 0; |
303 | struct mail_command *cp = util_find_entry (table, nmemb, size, word); | 301 | struct mail_command *cp = util_find_entry (table, nmemb, size, word); |
304 | if (cp && cp->synopsis) | 302 | if (cp && cp->synopsis) |
305 | fprintf (stdout, "%s\n", cp->synopsis); | 303 | mu_stream_printf (ostream, "%s\n", cp->synopsis); |
306 | else | 304 | else |
307 | { | 305 | { |
308 | status = 1; | 306 | status = 1; |
309 | fprintf (stdout, _("Unknown command: %s\n"), word); | 307 | mu_stream_printf (ostream, _("Unknown command: %s\n"), word); |
310 | } | 308 | } |
311 | return status; | 309 | return status; |
312 | } | 310 | } |
... | @@ -339,12 +337,12 @@ util_command_list (void *table, size_t nmemb, size_t size) | ... | @@ -339,12 +337,12 @@ util_command_list (void *table, size_t nmemb, size_t size) |
339 | if (pos >= cols) | 337 | if (pos >= cols) |
340 | { | 338 | { |
341 | pos = len + 1; | 339 | pos = len + 1; |
342 | fprintf (ofile, "\n%s ", cmd); | 340 | mu_stream_printf (ostream, "\n%s ", cmd); |
343 | } | 341 | } |
344 | else | 342 | else |
345 | fprintf (ofile, "%s ", cmd); | 343 | mu_stream_printf (ostream, "%s ", cmd); |
346 | } | 344 | } |
347 | fprintf (ofile, "\n"); | 345 | mu_stream_printf (ostream, "\n"); |
348 | return 0; | 346 | return 0; |
349 | } | 347 | } |
350 | 348 | ||
... | @@ -572,8 +570,7 @@ util_slist_print (mu_list_t list, int nl) | ... | @@ -572,8 +570,7 @@ util_slist_print (mu_list_t list, int nl) |
572 | for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) | 570 | for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) |
573 | { | 571 | { |
574 | mu_iterator_current (itr, (void **)&name); | 572 | mu_iterator_current (itr, (void **)&name); |
575 | fprintf (ofile, "%s%c", name, nl ? '\n' : ' '); | 573 | mu_stream_printf (ostream, "%s%c", name, nl ? '\n' : ' '); |
576 | |||
577 | } | 574 | } |
578 | mu_iterator_destroy (&itr); | 575 | mu_iterator_destroy (&itr); |
579 | } | 576 | } |
... | @@ -760,8 +757,8 @@ util_error (const char *format, ...) | ... | @@ -760,8 +757,8 @@ util_error (const char *format, ...) |
760 | 757 | ||
761 | va_start (ap, format); | 758 | va_start (ap, format); |
762 | 759 | ||
763 | vfprintf (stderr, format, ap); | 760 | mu_stream_vprintf (mu_strerr, format, ap); |
764 | fprintf (stderr, "\n"); | 761 | mu_stream_printf (mu_strerr, "\n"); |
765 | 762 | ||
766 | va_end(ap); | 763 | va_end(ap); |
767 | } | 764 | } |
... | @@ -1150,3 +1147,29 @@ util_url_to_string (mu_url_t url) | ... | @@ -1150,3 +1147,29 @@ util_url_to_string (mu_url_t url) |
1150 | } | 1147 | } |
1151 | return mu_url_to_string (url); | 1148 | return mu_url_to_string (url); |
1152 | } | 1149 | } |
1150 | |||
1151 | mu_stream_t | ||
1152 | open_pager (size_t lines) | ||
1153 | { | ||
1154 | const char *pager; | ||
1155 | unsigned pagelines = util_get_crt (); | ||
1156 | mu_stream_t str; | ||
1157 | |||
1158 | if (pagelines && lines > pagelines && (pager = getenv ("PAGER"))) | ||
1159 | { | ||
1160 | int rc = mu_command_stream_create (&str, pager, MU_STREAM_WRITE); | ||
1161 | if (rc) | ||
1162 | { | ||
1163 | mu_diag_funcall (MU_DIAG_ERROR, "mu_prog_stream_create", | ||
1164 | pager, rc); | ||
1165 | str = ostream; | ||
1166 | mu_stream_ref (str); | ||
1167 | } | ||
1168 | } | ||
1169 | else | ||
1170 | { | ||
1171 | str = ostream; | ||
1172 | mu_stream_ref (str); | ||
1173 | } | ||
1174 | return str; | ||
1175 | } | ... | ... |
... | @@ -39,16 +39,16 @@ static const char *with_defs[] = | ... | @@ -39,16 +39,16 @@ static const char *with_defs[] = |
39 | int | 39 | int |
40 | mail_version (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) | 40 | mail_version (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) |
41 | { | 41 | { |
42 | fprintf (ofile, "%s", program_version); | 42 | mu_stream_printf (ostream, "%s", program_version); |
43 | if (with_defs[0] != NULL) | 43 | if (with_defs[0] != NULL) |
44 | { | 44 | { |
45 | int i; | 45 | int i; |
46 | fprintf (ofile, " ("); | 46 | mu_stream_printf (ostream, " ("); |
47 | for (i = 0; with_defs[i]; i++) | 47 | for (i = 0; with_defs[i]; i++) |
48 | fprintf (ofile, " %s", with_defs[i]); | 48 | mu_stream_printf (ostream, " %s", with_defs[i]); |
49 | fprintf (ofile, " )"); | 49 | mu_stream_printf (ostream, " )"); |
50 | } | 50 | } |
51 | fprintf (ofile, "\n"); | 51 | mu_stream_printf (ostream, "\n"); |
52 | 52 | ||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } | ... | ... |
... | @@ -114,8 +114,8 @@ mail_write (int argc, char **argv) | ... | @@ -114,8 +114,8 @@ mail_write (int argc, char **argv) |
114 | mu_stream_close (output); | 114 | mu_stream_close (output); |
115 | mu_stream_destroy (&output); | 115 | mu_stream_destroy (&output); |
116 | 116 | ||
117 | fprintf (ofile, "\"%s\" %3lu/%-5lu\n", filename, | 117 | mu_stream_printf (ostream, "\"%s\" %3lu/%-5lu\n", filename, |
118 | (unsigned long) total_lines, (unsigned long) total_size); | 118 | (unsigned long) total_lines, (unsigned long) total_size); |
119 | 119 | ||
120 | free (filename); | 120 | free (filename); |
121 | msgset_free (msglist); | 121 | msgset_free (msglist); | ... | ... |
... | @@ -120,7 +120,7 @@ mail_z (int argc, char **argv) | ... | @@ -120,7 +120,7 @@ mail_z (int argc, char **argv) |
120 | case D_BWD: | 120 | case D_BWD: |
121 | if (page_move (-count) == 0) | 121 | if (page_move (-count) == 0) |
122 | { | 122 | { |
123 | fprintf (stdout, _("On first screenful of messages\n")); | 123 | mu_stream_printf (ostream, _("On first screenful of messages\n")); |
124 | return 0; | 124 | return 0; |
125 | } | 125 | } |
126 | break; | 126 | break; |
... | @@ -128,7 +128,7 @@ mail_z (int argc, char **argv) | ... | @@ -128,7 +128,7 @@ mail_z (int argc, char **argv) |
128 | case D_FWD: | 128 | case D_FWD: |
129 | if (page_move (count) == 0) | 129 | if (page_move (count) == 0) |
130 | { | 130 | { |
131 | fprintf (stdout, _("On last screenful of messages\n")); | 131 | mu_stream_printf (ostream, _("On last screenful of messages\n")); |
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | break; | 134 | break; | ... | ... |
-
Please register or sign in to post a comment