Commit a52aac19 a52aac19b2a9f3c5b890160052376bed1a3b69f7 by Sergey Poznyakoff

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.
1 parent b8c5000a
...@@ -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;
......