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)
return errno;
}
#ifdef HAVE_VFORK
pid = vfork ();
#else
pid = fork ();
#endif
if (pid < 0)
{
......@@ -88,11 +84,7 @@ mu_spawnvp (const char *prog, char *av[], int *stat)
sigprocmask (SIG_SETMASK, &savemask, NULL);
execvp (prog, av);
#ifdef HAVE__EXIT
_exit (127); /* exec error */
#else
exit (127);
#endif
}
else
{ /* parent */
......
......@@ -46,7 +46,8 @@ mu_stdstream_setup ()
{
int rc;
int fd;
int yes = 1;
/* If the streams are already open, close them */
mu_stream_destroy (&mu_strin);
mu_stream_destroy (&mu_strout);
......@@ -90,6 +91,8 @@ mu_stdstream_setup ()
MU_STDIN_FD, mu_strerror (rc));
abort ();
}
mu_stream_ioctl (mu_strin, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
rc = mu_stdio_stream_create (&mu_strout, MU_STDOUT_FD, 0);
if (rc)
{
......@@ -97,6 +100,7 @@ mu_stdstream_setup ()
MU_STDOUT_FD, mu_strerror (rc));
abort ();
}
mu_stream_ioctl (mu_strout, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
if (mu_stdstream_strerr_create (&mu_strerr, MU_STRERR_STDERR, 0, 0,
mu_program_name, NULL))
......
......@@ -36,9 +36,9 @@ alias_free (void *data)
static void
alias_print_group (const char *name, alias_t al)
{
fprintf (ofile, "%s ", name);
mu_stream_printf (ostream, "%s ", name);
util_slist_print (al->list, 0);
fprintf (ofile, "\n");
mu_stream_printf (ostream, "\n");
}
static alias_t
......
......@@ -34,7 +34,7 @@ mail_alt (int argc, char **argv)
if (alternate_names)
{
util_slist_print (alternate_names, 0);
fprintf (ofile, "\n");
mu_stream_printf (ostream, "\n");
}
}
else
......
......@@ -106,7 +106,7 @@ mail_copy0 (int argc, char **argv, int mark)
}
if (status == 0)
fprintf (ofile, "\"%s\" %3lu/%-5lu\n", filename,
mu_stream_printf (ostream, "\"%s\" %3lu/%-5lu\n", filename,
(unsigned long) total_lines, (unsigned long) total_size);
mu_mailbox_close (mbx);
......
......@@ -29,7 +29,7 @@ struct decode_closure
int select_hdr;
};
static int print_stream (mu_stream_t, FILE *);
static int print_stream (mu_stream_t, mu_stream_t);
static int display_message (mu_message_t, msgset_t *msgset, void *closure);
static int display_submessage (struct mime_descend_closure *closure,
void *data);
......@@ -81,7 +81,7 @@ display_message (mu_message_t mesg, msgset_t *msgset, void *arg)
}
static void
display_headers (FILE *out, mu_message_t mesg,
display_headers (mu_stream_t out, mu_message_t mesg,
const msgset_t *msgset MU_ARG_UNUSED,
int select_hdr)
{
......@@ -102,13 +102,13 @@ display_headers (FILE *out, mu_message_t mesg,
continue;
if (mail_header_is_visible (sptr))
{
fprintf (out, "%s: ", sptr);
mu_stream_printf (out, "%s: ", sptr);
if (mu_header_sget_field_value (hdr, i, &sptr))
sptr = "";
fprintf (out, "%s\n", sptr);
mu_stream_printf (out, "%s\n", sptr);
}
}
fprintf (out, "\n");
mu_stream_printf (out, "\n");
}
else /* Print displays all headers. */
{
......@@ -122,43 +122,50 @@ display_headers (FILE *out, mu_message_t mesg,
}
}
size_t
fprint_msgset (FILE *fp, const msgset_t *msgset)
void
format_msgset (mu_stream_t str, const msgset_t *msgset, size_t *count)
{
int i;
size_t n = 0;
n = fprintf (fp, "%lu", (unsigned long) msgset->msg_part[0]);
mu_stream_stat_buffer stat;
if (count)
mu_stream_set_stat (str, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT),
stat);
mu_stream_printf (str, "%lu", (unsigned long) msgset->msg_part[0]);
for (i = 1; i < msgset->npart; i++)
n += fprintf (fp, "[%lu", (unsigned long) msgset->msg_part[i]);
mu_stream_printf (str, "[%lu", (unsigned long) msgset->msg_part[i]);
for (i = 1; i < msgset->npart; i++)
n += fprintf (fp, "]");
return n;
mu_stream_printf (str, "]");
if (count)
{
*count = stat[MU_STREAM_STAT_OUT];
mu_stream_set_stat (str, 0, NULL);
}
}
static void
display_part_header (FILE *out, const msgset_t *msgset,
display_part_header (mu_stream_t str, const msgset_t *msgset,
const char *type, const char *encoding)
{
int size = util_screen_columns () - 3;
unsigned int i;
fputc ('+', out);
mu_stream_printf (str, "+");
for (i = 0; (int)i <= size; i++)
fputc ('-', out);
fputc ('+', out);
fputc ('\n', out);
fprintf (out, "%s", _("| Message="));
fprint_msgset (out, msgset);
fprintf (out, "\n");
fprintf (out, _("| Type=%s\n"), type);
fprintf (out, _("| Encoding=%s\n"), encoding);
fputc ('+', out);
for (i = 0; (int)i <= size; i++)
fputc ('-', out);
fputc ('+', out);
fputc ('\n', out);
mu_stream_printf (str, "-");
mu_stream_printf (str, "+");
mu_stream_printf (str, "\n");
mu_stream_printf (str, "%s", _("| Message="));
format_msgset (str, msgset, NULL);
mu_stream_printf (str, "\n");
mu_stream_printf (str, _("| Type=%s\n"), type);
mu_stream_printf (str, _("| Encoding=%s\n"), encoding);
mu_stream_printf (str, "+");
for (i = 0; i <= size; i++)
mu_stream_printf (str, "-");
mu_stream_printf (str, "+");
mu_stream_printf (str, "\n");
}
int
......@@ -268,7 +275,8 @@ display_submessage (struct mime_descend_closure *closure, void *data)
else
stream = b_stream;
display_part_header (ofile, closure->msgset,
display_part_header (ostream,
closure->msgset,
closure->type, closure->encoding);
/* If `metamail' is set to true, enable internal mailcap
......@@ -290,22 +298,17 @@ display_submessage (struct mime_descend_closure *closure, void *data)
if (builtin_display)
{
size_t lines = 0;
int pagelines = util_get_crt ();
FILE *out;
mu_stream_t str;
mu_message_lines (closure->message, &lines);
if (pagelines && lines > pagelines)
out = popen (getenv ("PAGER"), "w");
else
out = ofile;
str = open_pager (lines);
display_headers (out, closure->message, closure->msgset,
display_headers (str, closure->message, closure->msgset,
closure->hints & MDHINT_SELECTED_HEADERS);
print_stream (stream, out);
if (out != ofile)
pclose (out);
print_stream (stream, str);
mu_stream_unref (str);
}
mu_stream_destroy (&stream);
}
......@@ -315,7 +318,7 @@ display_submessage (struct mime_descend_closure *closure, void *data)
/* FIXME: Try to use mu_stream_copy instead */
static int
print_stream (mu_stream_t stream, FILE *out)
print_stream (mu_stream_t stream, mu_stream_t out)
{
char buffer[512];
size_t n = 0;
......@@ -329,7 +332,7 @@ print_stream (mu_stream_t stream, FILE *out)
break;
}
buffer[n] = '\0';
fprintf (out, "%s", buffer);
mu_stream_printf (out, "%s", buffer);
}
return 0;
}
......
......@@ -21,129 +21,55 @@
* ec[ho] string ...
*/
static int echo (char *s);
int
mail_echo (int argc, char **argv)
static int
echo (char *s)
{
int i = 0;
if (argc > 1)
struct mu_wordsplit ws;
size_t len = strlen (s);
int rc = 1;
/* FIXME: This logic is flawed */
if (len > 0 && s[len - 1] == '\\')
{
for (i = 1; i < argc - 1; i++)
if (len == 1)
return 0;
if (s[len-2] != '\\')
{
echo (argv[i]);
fputc (' ', ofile);
--len;
rc = 0;
}
/* Last argument. */
if (echo(argv[argc - 1]) == 0)
fputc ('\n', ofile);
}
return 0;
if (mu_wordsplit_len (s, len, &ws,
MU_WRDSF_NOSPLIT |
MU_WRDSF_NOCMD | MU_WRDSF_NOVAR | MU_WRDSF_QUOTE))
{
mu_error (_("cannot split `%s': %s"), s,
mu_wordsplit_strerror (&ws));
}
else
{
mu_stream_printf (ostream, "%s", ws.ws_wordv[0]);
mu_wordsplit_free (&ws);
}
return rc;
}
/* Cumbersome switch for checking escape char '\'
if present replace with appropriately.
Return of 1 means to not print newline. */
static int
echo (char *s)
int
mail_echo (int argc, char **argv)
{
int process_escape = 0;
int c;
if (s == NULL)
return 0;
for (; (c = *s) != 0; s++)
if (argc > 1)
{
if (process_escape)
int i = 0;
for (i = 1; i < argc; i++)
{
switch (c)
{
/* \a Bell. */
case 'a':
c = '\a';
break;
/* \b Backspace. */
case 'b':
c = '\b';
break;
/* \c means not to print ending newline. */
/* Bail out and tell the caller not to print newline. */
case 'c':
return 1;
break;
/* \f Formfeed. */
case 'f':
c = '\f';
break;
/* \n Newline. */
case 'n':
c = '\n';
break;
/* \r Carriage return. */
case 'r':
c = '\r';
break;
/* \t Tab. */
case 't':
c = '\t';
break;
/* \v Vertical Tab. */
case 'v':
c = '\v';
break;
/* Escape sequence. */
case '\\':
c = '\\';
break;
/* \0x99 for example, let strtol() handle it. */
/* WARNING: Side effects because of strtol(). */
case '0':
{
long number = strtol (s, &s, 0);
switch (number)
{
case LONG_MIN:
case LONG_MAX:
/* if (errno == ERANGE) */
/* fputc (c, ofile); */
break;
default:
fprintf (ofile, "%ld", number);
s--;
continue;
}
}
break;
/* Can not be here. */
case '\0':
return 0;
break;
/* \\ means \ It was not an escape char. */
default:
fputc ('\\', ofile);
}
process_escape =0;
}
else if (c == '\\') /* Find the escape char, go back and process. */
{
process_escape = 1;
continue;
if (echo (argv[i]))
mu_stream_printf (ostream, " ");
}
fputc (c, ofile);
mu_stream_printf (ostream, "\n");
}
return 0;
}
......
......@@ -38,8 +38,8 @@ print_envelope (msgset_t *mspec, mu_message_t msg, void *data)
mu_envelope_sget_sender (env, &sender);
mu_envelope_sget_date (env, &date);
if (data)
fprintf (ofile, "%s ", (char*) data);
fprintf (ofile, "%s %s", sender, date);
mu_stream_printf (ostream, "%s ", (char*) data);
mu_stream_printf (ostream, "%s %s", sender, date);
}
return 0;
}
......
......@@ -34,7 +34,7 @@ mail_eq (int argc, char **argv)
if (n == 0)
util_error (_("No applicable message"));
else
fprintf (ofile, "%lu\n", (unsigned long) n);
mu_stream_printf (ostream, "%lu\n", (unsigned long) n);
break;
case 2:
......@@ -43,7 +43,8 @@ mail_eq (int argc, char **argv)
if (list->msg_part[0] <= total)
{
set_cursor (list->msg_part[0]);
fprintf (ofile, "%lu\n", (unsigned long) list->msg_part[0]);
mu_stream_printf (ostream, "%lu\n",
(unsigned long) list->msg_part[0]);
}
else
util_error_range (list->msg_part[0]);
......
......@@ -21,11 +21,9 @@
#include <sys/stat.h>
static void
dump_headers (FILE *fp, compose_env_t *env)
dump_headers (mu_stream_t out, compose_env_t *env)
{
char buffer[512];
mu_stream_t stream = NULL;
size_t n;
int rc;
rc = mu_header_get_streamref (env->header, &stream);
......@@ -35,13 +33,7 @@ dump_headers (FILE *fp, compose_env_t *env)
mu_stream_strerror (stream, rc));
return;
}
/* FIXME: Use mu_stream_copy */
while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0
&& n != 0)
{
buffer[n] = 0;
fprintf (fp, "%s", buffer);
}
mu_stream_copy (out, stream, 0, NULL);
mu_stream_destroy (&stream);
}
......@@ -50,15 +42,15 @@ dump_headers (FILE *fp, compose_env_t *env)
#define STATE_BODY 2
static int
parse_headers (FILE *fp, compose_env_t *env)
parse_headers (mu_stream_t input, compose_env_t *env)
{
int status;
mu_header_t header;
char *name = NULL;
char *value = NULL;
char *buf = NULL;
int state = STATE_INIT;
size_t n = 0;
char *buf = NULL;
size_t size = 0, n;
int errcnt = 0, line = 0;
if ((status = mu_header_create (&header, NULL, 0)) != 0)
......@@ -67,12 +59,12 @@ parse_headers (FILE *fp, compose_env_t *env)
return 1;
}
while (state != STATE_BODY
&& errcnt == 0 && getline (&buf, &n, fp) > 0 && n > 0)
mu_stream_seek (input, 0, MU_SEEK_SET, NULL);
while (state != STATE_BODY &&
errcnt == 0 &&
mu_stream_getline (input, &buf, &size, &n) == 0 && n > 0)
{
int len = strlen (buf);
if (len > 0 && buf[len-1] == '\n')
buf[len-1] = 0;
mu_rtrim_class (buf, MU_CTYPE_SPACE);
line++;
switch (state)
......@@ -161,7 +153,7 @@ parse_headers (FILE *fp, compose_env_t *env)
static void
escape_continue (void)
{
fprintf (stdout, _("(continue)\n"));
mu_stream_printf (ostream, _("(continue)\n"));
}
static int
......@@ -181,12 +173,7 @@ escape_check_args (int argc, char **argv)
int
escape_shell (int argc, char **argv, compose_env_t *env)
{
int status;
ofile = env->ofile;
++*argv;
status = mail_execute (1, argc, argv);
ofile = env->file;
return status;
return mail_execute (1, argc - 1, argv + 1);
}
/* ~:[mail-command] */
......@@ -196,7 +183,8 @@ escape_command (int argc, char **argv, compose_env_t *env)
{
const struct mail_command_entry *entry;
int status;
mu_stream_t s;
if (escape_check_args (argc, argv))
return 1;
if (argv[1][0] == '#')
......@@ -213,9 +201,11 @@ escape_command (int argc, char **argv, compose_env_t *env)
return 1;
}
ofile = env->ofile;
/* FIXME: Do we need this? */
s = ostream;
ostream = env->compstr;
status = (*entry->func) (argc - 1, argv + 1);
ofile = env->file;
ostream = s;
return status;
}
......@@ -236,37 +226,32 @@ escape_help (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED)
/* ~A */
/* ~a */
int
escape_sign (int argc MU_ARG_UNUSED, char **argv, compose_env_t *env MU_ARG_UNUSED)
escape_sign (int argc MU_ARG_UNUSED, char **argv, compose_env_t *env)
{
char *p;
if (mailvar_get (&p, mu_isupper (argv[0][0]) ? "Sign" : "sign",
mailvar_type_string, 1) == 0)
{
fputs ("-- \n", ofile);
mu_stream_printf (env->compstr, "-- \n");
if (mu_isupper (argv[0][0]))
{
char *name = util_fullpath (p);
FILE *fp = fopen (name, "r");
char *buf = NULL;
size_t n = 0;
int rc;
mu_stream_t signstr;
if (!fp)
rc = mu_file_stream_create (&signstr, name, MU_STREAM_READ);
if (rc)
util_error (_("Cannot open %s: %s"), name, mu_strerror (rc));
else
{
util_error (_("Cannot open %s: %s"), name, mu_strerror (errno));
free (name);
mu_stream_printf (ostream, _("Reading %s\n"), name);
mu_stream_copy (env->compstr, signstr, 0, NULL);
mu_stream_destroy (&signstr);
}
fprintf (stdout, _("Reading %s\n"), name);
while (getline (&buf, &n, fp) > 0)
fprintf (ofile, "%s", buf);
fclose (fp);
free (buf);
free (name);
}
else
fprintf (ofile, "%s", p);
mu_stream_printf (env->compstr, "%s\n", p);
escape_continue ();
}
return 0;
......@@ -290,20 +275,50 @@ escape_cc (int argc, char **argv, compose_env_t *env)
return 0;
}
static int
verbose_copy (mu_stream_t dest, mu_stream_t src, const char *filename,
mu_off_t *psize)
{
int rc;
char *buf = NULL;
size_t size = 0, n;
size_t lines;
mu_off_t total;
total = lines = 0;
while ((rc = mu_stream_getline (src, &buf, &size, &n)) == 0 && n > 0)
{
lines++;
rc = mu_stream_write (dest, buf, n, NULL);
if (rc)
break;
total += n;
}
if (rc)
mu_error (_("error copying data: %s"), mu_strerror (rc));
mu_stream_printf (ostream, "\"%s\" %lu/%lu\n", filename,
(unsigned long) lines, (unsigned long) total);
if (psize)
*psize = total;
return rc;
}
/* ~d */
int
escape_deadletter (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED,
compose_env_t *env MU_ARG_UNUSED)
compose_env_t *env)
{
FILE *dead = fopen (getenv ("DEAD"), "r");
int c;
if (dead)
const char *name = getenv ("DEAD");
mu_stream_t str;
int rc = mu_file_stream_create (&str, name, MU_STREAM_READ);
if (rc)
{
while ((c = fgetc (dead)) != EOF)
fputc (c, ofile);
fclose (dead);
util_error (_("Cannot open file %s: %s"), name, strerror (rc));
return 1;
}
verbose_copy (env->compstr, str, name, NULL);
mu_stream_destroy (&str);
return 0;
}
......@@ -321,60 +336,80 @@ run_editor (char *ed, char *arg)
static int
escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env)
{
if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0))
char *filename;
int fd;
mu_stream_t tempstream;
int rc;
rc = mu_tempfile (NULL, 0, &fd, &filename);
if (rc)
{
char *filename;
int fd;
FILE *fp;
char buffer[512];
int rc;
rc = mu_tempfile (NULL, 0, &fd, &filename);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_tempfile", NULL, rc);
return rc;
}
fp = fdopen (fd, "w+");
dump_headers (fp, env);
mu_diag_funcall (MU_DIAG_ERROR, "mu_tempfile", NULL, rc);
return rc;
}
rc = mu_fd_stream_create (&tempstream, filename, fd, MU_STREAM_RDWR);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_fd_stream_create", filename, rc);
unlink (filename);
free (filename);
close (fd);
return rc;
}
rewind (env->file);
while (fgets (buffer, sizeof (buffer), env->file))
fputs (buffer, fp);
mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL);
if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0))
{
dump_headers (tempstream, env);
fclose (env->file);
mu_stream_copy (tempstream, env->compstr, 0, NULL);
do
{
fclose (fp);
mu_stream_destroy (&tempstream);
run_editor (ed, filename);
fp = fopen (filename, "r");
}
while ((rc = parse_headers (fp, env)) < 0);
if (rc == 0)
{
env->file = fopen (env->filename, "w");
while (fgets (buffer, sizeof (buffer), fp))
fputs (buffer, env->file);
fclose (env->file);
rc = mu_file_stream_create (&tempstream, filename, MU_STREAM_RDWR);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_file_stream_create",
filename, rc);
unlink (filename);
free (filename);
return rc;
}
}
fclose (fp);
unlink (filename);
free (filename);
while ((rc = parse_headers (tempstream, env)) < 0);
}
else
{
fclose (env->file);
ofile = env->ofile;
run_editor (ed, env->filename);
mu_stream_copy (tempstream, env->compstr, 0, NULL);
mu_stream_destroy (&tempstream);
run_editor (ed, filename);
rc = mu_file_stream_create (&tempstream, filename, MU_STREAM_RDWR);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_file_stream_create",
filename, rc);
unlink (filename);
free (filename);
return rc;
}
}
env->file = fopen (env->filename, "a+");
ofile = env->file;
if (rc == 0)
{
mu_off_t size;
mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL);
mu_stream_copy (env->compstr, tempstream, 0, &size);
mu_stream_truncate (env->compstr, size);
}
mu_stream_destroy (&tempstream);
unlink (filename);
free (filename);
mu_stream_seek (env->compstr, 0, MU_SEEK_END, NULL);
escape_continue ();
return 0;
}
......@@ -425,57 +460,53 @@ escape_headers (int argc, char **argv, compose_env_t *env)
/* ~i[var-name] */
int
escape_insert (int argc, char **argv, compose_env_t *send_env MU_ARG_UNUSED)
escape_insert (int argc, char **argv, compose_env_t *env)
{
if (escape_check_args (argc, argv))
return 1;
mailvar_variable_format (ofile, mailvar_find_variable (argv[1], 0), NULL);
mailvar_variable_format (env->compstr, mailvar_find_variable (argv[1], 0),
NULL);
return 0;
}
/* ~m[mesg-list] */
/* ~M[mesg-list] */
struct quote_closure
{
mu_stream_t str;
int islower;
};
int
quote0 (msgset_t *mspec, mu_message_t mesg, void *data)
{
struct quote_closure *clos = data;
int rc;
mu_stream_t stream;
char *prefix = "\t";
mu_stream_t outstr, flt;
mu_stream_t flt;
char *argv[3];
int yes = 1;
fprintf (stdout, _("Interpolating: %lu\n"),
(unsigned long) mspec->msg_part[0]);
mu_stream_printf (ostream, _("Interpolating: %lu\n"),
(unsigned long) mspec->msg_part[0]);
mailvar_get (&prefix, "indentprefix", mailvar_type_string, 0);
fflush (ofile);
rc = mu_stdio_stream_create (&outstr, fileno (ofile), MU_STREAM_WRITE);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", NULL, rc);
return rc;
}
/* Set borrow flag to prevent fileno (ofile) from being closed on
destroying outstr. */
mu_stream_ioctl (outstr, MU_IOCTL_FD, MU_IOCTL_FD_SET_BORROW, &yes);
argv[0] = "INLINE-COMMENT";
argv[1] = prefix;
argv[2] = NULL;
rc = mu_filter_create_args (&flt, outstr, "INLINE-COMMENT",
rc = mu_filter_create_args (&flt, clos->str, "INLINE-COMMENT",
2, (const char**) argv,
MU_FILTER_ENCODE,
MU_STREAM_WRITE);
mu_stream_unref (outstr);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_filter_create_args", NULL, rc);
return rc;
}
if (*(int*)data)
if (clos->islower)
{
mu_header_t hdr;
mu_body_t body;
......@@ -518,8 +549,11 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data)
int
escape_quote (int argc, char **argv, compose_env_t *env)
{
int lower = mu_islower (argv[0][0]);
util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT, quote0, &lower);
struct quote_closure clos;
clos.str = env->compstr;
clos.islower = mu_islower (argv[0][0]);
util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT, quote0, &clos);
escape_continue ();
return 0;
}
......@@ -528,18 +562,12 @@ escape_quote (int argc, char **argv, compose_env_t *env)
int
escape_type_input (int argc, char **argv, compose_env_t *env)
{
char buffer[512];
fprintf (env->ofile, _("Message contains:\n"));
dump_headers (env->ofile, env);
rewind (env->file);
while (fgets (buffer, sizeof (buffer), env->file))
fputs (buffer, env->ofile);
/* FIXME: Enable paging */
mu_stream_printf (ostream, _("Message contains:\n"));
dump_headers (ostream, env);
mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL);
mu_stream_copy (ostream, env->compstr, 0, NULL);
escape_continue ();
return 0;
}
......@@ -548,31 +576,23 @@ int
escape_read (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED)
{
char *filename;
FILE *inf;
size_t size, lines;
char buf[512];
mu_stream_t instr;
int rc;
if (escape_check_args (argc, argv))
return 1;
filename = util_fullpath (argv[1]);
inf = fopen (filename, "r");
if (!inf)
rc = mu_file_stream_create (&instr, filename, MU_STREAM_READ);
if (rc)
{
util_error (_("Cannot open %s: %s"), filename, mu_strerror (errno));
util_error (_("Cannot open %s: %s"), filename, mu_strerror (rc));
free (filename);
return 1;
}
size = lines = 0;
while (fgets (buf, sizeof (buf), inf))
{
lines++;
size += strlen (buf);
fputs (buf, ofile);
}
fclose (inf);
fprintf (stdout, "\"%s\" %lu/%lu\n", filename,
(unsigned long) lines, (unsigned long) size);
verbose_copy (env->compstr, instr, filename, NULL);
mu_stream_destroy (&instr);
free (filename);
return 0;
}
......@@ -581,9 +601,12 @@ escape_read (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED)
int
escape_subj (int argc, char **argv, compose_env_t *env)
{
char *buf;
if (escape_check_args (argc, argv))
return 1;
compose_header_set (env, MU_HEADER_SUBJECT, argv[1], COMPOSE_REPLACE);
mu_argcv_string (argc - 1, argv + 1, &buf);
compose_header_set (env, MU_HEADER_SUBJECT, buf, COMPOSE_REPLACE);
free (buf);
return 0;
}
......@@ -601,34 +624,28 @@ int
escape_write (int argc, char **argv, compose_env_t *env)
{
char *filename;
FILE *fp;
size_t size, lines;
char buf[512];
mu_stream_t wstr;
int rc;
mu_off_t size;
if (escape_check_args (argc, argv))
return 1;
filename = util_fullpath (argv[1]);
fp = fopen (filename, "w"); /*FIXME: check for the existence first */
if (!fp)
/* FIXME: check for existence first */
rc = mu_file_stream_create (&wstr, filename,
MU_STREAM_WRITE|MU_STREAM_CREAT);
if (rc)
{
util_error (_("Cannot open %s: %s"), filename, mu_strerror (errno));
util_error (_("Cannot open %s for writing: %s"),
filename, mu_strerror (rc));
free (filename);
return 1;
}
rewind (env->file);
size = lines = 0;
while (fgets (buf, sizeof (buf), env->file))
{
lines++;
size += strlen (buf);
fputs (buf, fp);
}
fclose (fp);
fprintf (stdout, "\"%s\" %lu/%lu\n", filename,
(unsigned long) lines, (unsigned long) size);
mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL);
verbose_copy (wstr, env->compstr, filename, &size);
mu_stream_truncate (wstr, size);
mu_stream_destroy (&wstr);
free (filename);
return 0;
}
......@@ -637,17 +654,13 @@ escape_write (int argc, char **argv, compose_env_t *env)
int
escape_pipe (int argc, char **argv, compose_env_t *env)
{
int rc, status;
int p[2];
pid_t pid;
int fd;
if (argc == 1)
{
/* TRANSLATORS: 'pipe' is a command name. Do not translate it! */
util_error (_("pipe: no command specified"));
return 1;
}
mu_off_t isize, osize = 0;
mu_stream_t tstr;
if (pipe (p))
{
util_error ("pipe: %s", mu_strerror (errno));
......@@ -668,10 +681,8 @@ escape_pipe (int argc, char **argv, compose_env_t *env)
else if (pid == 0)
{
/* Child */
int i;
char **xargv;
/* Attache the pipes */
/* Attach the pipes */
close (0);
dup (p[0]);
close (p[0]);
......@@ -681,94 +692,61 @@ escape_pipe (int argc, char **argv, compose_env_t *env)
dup (fd);
close (fd);
/* Execute the process */
xargv = xcalloc (argc, sizeof (xargv[0]));
for (i = 0; i < argc - 1; i++)
xargv[i] = argv[i + 1];
xargv[i] = NULL;
execvp (xargv[0], xargv);
util_error (_("Cannot exec process `%s': %s"), xargv[0], mu_strerror (errno));
exit (1);
execvp (argv[1], argv + 1);
util_error (_("Cannot execute `%s': %s"), argv[1], mu_strerror (errno));
_exit (127);
}
else
{
FILE *fp;
char *buf = NULL;
size_t n;
size_t lines, size;
int rc = 1;
int status;
close (p[0]);
close (p[0]);
/* Parent */
fp = fdopen (p[1], "w");
fclose (env->file);
env->file = fopen (env->filename, "r");
rc = mu_stdio_stream_create (&tstr, p[1], MU_STREAM_WRITE);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_stdio_stream_create", NULL, rc);
kill (pid, SIGKILL);
close (fd);
return rc;
}
lines = size = 0;
while (getline (&buf, &n, env->file) > 0)
{
lines++;
size += n;
fputs (buf, fp);
}
fclose (env->file);
fclose (fp); /* Closes p[1] */
mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL);
mu_stream_copy (tstr, env->compstr, 0, &isize);
mu_stream_destroy (&tstr);
waitpid (pid, &status, 0);
if (!WIFEXITED (status))
{
util_error (_("Child terminated abnormally: %d"), WEXITSTATUS (status));
}
waitpid (pid, &status, 0);
if (!WIFEXITED (status))
util_error (_("Child terminated abnormally: %d"),
WEXITSTATUS (status));
else
{
struct stat st;
if (fstat (fd, &st))
util_error (_("Cannot stat output file: %s"), mu_strerror (errno));
else
{
struct stat st;
if (fstat (fd, &st))
{
util_error (_("Cannot stat output file: %s"), mu_strerror (errno));
}
else if (st.st_size > 0)
rc = 0;
}
osize = st.st_size;
}
fprintf (stdout, "\"|%s\" in: %lu/%lu ", argv[1],
(unsigned long) lines, (unsigned long) size);
mu_stream_printf (mu_strout, "\"|%s\" in: %lu ", argv[1],
(unsigned long) isize);
if (osize == 0)
mu_stream_printf (mu_strout, _("no lines out\n"));
else
{
mu_stream_t str;
mu_stream_printf (mu_strout, "out: %lu\n", (unsigned long) osize);
rc = mu_fd_stream_create (&str, NULL, fd,
MU_STREAM_RDWR | MU_STREAM_SEEK);
if (rc)
{
fprintf (stdout, _("no lines out\n"));
util_error (_("Cannot open composition stream: %s"),
mu_strerror (rc));
close (fd);
}
else
{
/* Ok, replace the old tempfile */
fp = fdopen (fd, "r");
rewind (fp);
env->file = fopen (env->filename, "w+");
lines = size = 0;
while (getline (&buf, &n, fp) > 0)
{
lines++;
size += n;
fputs (buf, env->file);
}
fclose (env->file);
fprintf (stdout, "out: %lu/%lu\n",
(unsigned long) lines, (unsigned long) size);
mu_stream_destroy (&env->compstr);
env->compstr = str;
}
/* Clean up the things */
if (buf)
free (buf);
env->file = fopen (env->filename, "a+");
ofile = env->file;
}
close (fd);
return 0;
}
......
......@@ -77,9 +77,10 @@ mail_followup (int argc, char **argv)
msgset_free (msglist);
fprintf (ofile, "To: %s\n", compose_header_get (&env, MU_HEADER_TO, ""));
fprintf (ofile, "Subject: %s\n\n",
compose_header_get (&env, MU_HEADER_SUBJECT, ""));
mu_stream_printf (ostream, "To: %s\n",
compose_header_get (&env, MU_HEADER_TO, ""));
mu_stream_printf (ostream, "Subject: %s\n\n",
compose_header_get (&env, MU_HEADER_SUBJECT, ""));
status = mail_send0 (&env, mu_isupper (argv[0][0]));
compose_destroy (&env);
......
......@@ -72,7 +72,7 @@ static void
format_pad (size_t n)
{
for (; n; n--)
fputc (' ', ofile);
mu_stream_write (ostream, " ", 1, NULL);
}
static void
......@@ -113,17 +113,17 @@ format_headline (struct header_segm *seg, msgset_t *mspec, mu_message_t msg)
if (seg->align == ALIGN_RIGHT)
{
format_pad (width - len);
fprintf (ofile, "%*.*s", (int) len, (int) len, p);
mu_stream_printf (ostream, "%*.*s", (int) len, (int) len, p);
}
else
{
fprintf (ofile, "%*.*s", (int) len, (int) len, p);
mu_stream_printf (ostream, "%*.*s", (int) len, (int) len, p);
format_pad (width - len);
}
out_cols += width;
}
fprintf (ofile, "\n");
mu_stream_printf (ostream, "\n");
free (args.buf);
}
......
......@@ -27,10 +27,10 @@ mail_inc (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
if (!mu_mailbox_is_updated (mbox))
{
mu_mailbox_messages_count (mbox, &total);
fprintf (ofile, _("New mail has arrived.\n"));
mu_stream_printf (ostream, _("New mail has arrived.\n"));
}
else
fprintf (ofile, _("No new mail for %s\n"), mail_whoami());
mu_stream_printf (ostream, _("No new mail for %s\n"), mail_whoami ());
return 0;
}
......
......@@ -21,7 +21,7 @@
/* Global variables and constants*/
mu_mailbox_t mbox; /* Mailbox being operated upon */
size_t total; /* Total number of messages in the mailbox */
FILE *ofile; /* Output file */
mu_stream_t ostream; /* Output stream */
int interactive; /* Is the session interactive */
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)
{
mu_mailbox_messages_count (mbox, &total);
page_invalidate (0);
fprintf (ofile, _("New mail has arrived.\n"));
mu_stream_printf (ostream, _("New mail has arrived.\n"));
}
rc = ml_readline (prompt);
......@@ -324,7 +324,9 @@ main (int argc, char **argv)
struct arguments args;
int i, rc;
ofile = stdout;
mu_stdstream_setup ();
ostream = mu_strout;
mu_stream_ref (mu_strout);
set_cursor (1);
/* Native Language Support */
......@@ -399,7 +401,18 @@ main (int argc, char **argv)
util_run_cached_commands (&command_list);
if (interactive)
/* nothing? */;
{
/* Reset standard error stream so that it does not print program
name before the actual diagnostic message. */
mu_stream_t errstr;
int rc = mu_stdstream_strerr_create (&errstr, MU_STRERR_STDERR, 0, 0,
NULL, NULL);
if (rc == 0)
{
mu_stream_destroy (&mu_strerr);
mu_strerr = errstr;
}
}
else
{
util_do_command ("set nocrt");
......@@ -485,10 +498,10 @@ main (int argc, char **argv)
|| mailvar_get (NULL, "emptystart", mailvar_type_boolean, 0)))
{
if (args.file)
fprintf (ofile, _("%s: 0 messages\n"), args.file);
mu_stream_printf (ostream, _("%s: 0 messages\n"), args.file);
else
fprintf (ofile, _("No mail for %s\n"),
args.user ? args.user : mail_whoami ());
mu_stream_printf (ostream, _("No mail for %s\n"),
args.user ? args.user : mail_whoami ());
return 1;
}
......@@ -501,7 +514,7 @@ main (int argc, char **argv)
mailvar_get (&prompt, "prompt", mailvar_type_string, 0);
mail_mainloop (mail_cmdline, (void*) prompt, 1);
fprintf (ofile, "\n");
mu_stream_printf (ostream, "\n");
util_do_command ("quit");
return 0;
}
......@@ -551,11 +564,11 @@ mail_mainloop (char *(*input) (void *, int),
int
mail_warranty (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
{
fputs (_("GNU Mailutils -- a suite of utilities for electronic mail\n"
mu_stream_printf (ostream,
_("GNU Mailutils -- a suite of utilities for electronic mail\n"
"Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,\n"
"2007, 2009 Free Software Foundation, Inc.\n\n"),
ofile);
fputs (
"2007, 2009 Free Software Foundation, Inc.\n\n"));
mu_stream_printf (ostream,
_(" GNU Mailutils is free software; you can redistribute it and/or modify\n"
" it under the terms of the GNU General Public License as published by\n"
" 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)
" with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.\n"
"\n"
"\n"
),
ofile);
));
return 0;
}
......
......@@ -102,9 +102,7 @@ typedef int function_t (int, char **);
typedef struct compose_env
{
mu_header_t header; /* The message headers */
char *filename; /* Name of the temporary compose file */
FILE *file; /* Temporary compose file */
FILE *ofile; /* Diagnostics output channel */
mu_stream_t compstr; /* Temporary compose stream */
char **outfiles; /* Names of the output files. The message is to be
saved in each of these. */
int nfiles; /* Number of output files */
......@@ -174,7 +172,7 @@ typedef int (*msg_handler_t) (msgset_t *mp, mu_message_t mesg, void *data);
/* Global variables and constants*/
extern mu_mailbox_t mbox;
extern size_t total;
extern FILE *ofile;
extern mu_stream_t ostream;
extern int interactive;
extern const char *program_version;
......@@ -358,7 +356,7 @@ extern int mailvar_get (void *ptr, const char *variable,
enum mailvar_type type, int warn);
extern void mailvar_print (int set);
extern void mailvar_variable_format (FILE *fp,
extern void mailvar_variable_format (mu_stream_t,
const struct mailvar_variable *,
const char *defval);
......@@ -403,7 +401,9 @@ void util_mark_read (mu_message_t msg);
const char *util_url_to_string (mu_url_t url);
size_t fprint_msgset (FILE *fp, const msgset_t *msgset);
mu_stream_t open_pager (size_t lines);
void format_msgset (mu_stream_t str, const msgset_t *msgset, size_t *count);
int is_address_field (const char *name);
......
......@@ -118,58 +118,24 @@ ml_readline_init ()
char *
ml_readline_internal ()
{
char *line;
char *p;
size_t alloclen, linelen;
p = line = xcalloc (1, 255);
alloclen = 255;
linelen = 0;
for (;;)
char *buf = NULL;
size_t size = 0, n;
int rc;
rc = mu_stream_getline (mu_strin, &buf, &size, &n);
if (rc)
{
size_t n;
p = fgets (p, alloclen - linelen, stdin);
if (p)
n = strlen(p);
else if (_interrupted)
{
free (line);
return NULL;
}
else
n = 0;
linelen += n;
/* Error. */
if (linelen == 0)
{
free (line);
return NULL;
}
/* Ok. */
if (line[linelen - 1] == '\n')
{
line[linelen - 1] = '\0';
return line;
}
else
{
char *tmp;
alloclen *= 2;
tmp = realloc (line, alloclen);
if (tmp == NULL)
{
free (line);
return NULL;
}
line = tmp;
p = line + linelen;
}
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_getline", NULL, rc);
return NULL;
}
if (_interrupted)
{
free (buf);
return NULL;
}
if (n == 0)
return NULL;
return buf;
}
char *
......@@ -185,7 +151,7 @@ ml_readline_with_intr (const char *prompt)
{
char *str = ml_readline (prompt);
if (_interrupted)
printf ("\n");
mu_stream_printf (ostream, "\n");
return str;
}
......@@ -959,8 +925,8 @@ readline (char *prompt)
{
if (prompt)
{
fprintf (ofile, "%s", prompt);
fflush (ofile);
mu_stream_printf (ostream, "%s", prompt);
mu_stream_flush (ostream);
}
return ml_readline_internal ();
......
......@@ -285,21 +285,27 @@ find_mailvar_symbol (const char *var)
}
static void
print_descr (FILE *out, const char *s, int n,
print_descr (mu_stream_t out, const char *s, int n,
int doc_col, int rmargin, char *pfx)
{
mu_stream_stat_buffer stat;
if (!s)
return;
mu_stream_set_stat (out, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT),
stat);
stat[MU_STREAM_STAT_OUT] = n;
do
{
const char *p;
const char *space = NULL;
if (n == 1 && pfx)
n += fprintf (out, "%s", pfx);
if (stat[MU_STREAM_STAT_OUT] && pfx)
mu_stream_printf (out, "%s", pfx);
for (; n < doc_col; n++)
fputc (' ', out);
while (stat[MU_STREAM_STAT_OUT] < doc_col)
mu_stream_write (out, " ", 1, NULL);
for (p = s; *p && p < s + (rmargin - doc_col); p++)
if (mu_isspace (*p))
......@@ -307,20 +313,21 @@ print_descr (FILE *out, const char *s, int n,
if (!space || p < s + (rmargin - doc_col))
{
fprintf (out, "%s", s);
mu_stream_printf (out, "%s", s);
s += strlen (s);
}
else
{
for (; s < space; s++)
fputc (*s, out);
mu_stream_write (out, s, 1, NULL);
for (; *s && mu_isspace (*s); s++)
;
}
fputc ('\n', out);
n = 1;
mu_stream_printf (out, "\n");
stat[MU_STREAM_STAT_OUT] = 1;
}
while (*s);
mu_stream_set_stat (out, 0, NULL);
}
/* Functions for dealing with internal mailvar_list variables */
......@@ -680,17 +687,15 @@ void
mailvar_print (int set)
{
struct mailvar_variable **vartab;
FILE *out = ofile;
mu_stream_t out;
size_t i, count;
int pagelines = util_get_crt ();
int width = util_getcols ();
int prettyprint = mailvar_get (NULL, "variable-pretty-print",
mailvar_type_boolean, 0) == 0;
vartab = mailvar_make_array (set, &count);
if (pagelines && count > pagelines)
out = popen (getenv ("PAGER"), "w");
out = open_pager (count);
for (i = 0; i < count; i++)
{
......@@ -704,40 +709,41 @@ mailvar_print (int set)
if (sym->flags & MAILVAR_HIDDEN)
continue;
if (sym->flags & MAILVAR_RDONLY)
fprintf (out, "# %s:\n", _("Read-only variable"));
mu_stream_printf (out, "# %s:\n", _("Read-only variable"));
print_descr (out, gettext (sym->descr), 1, 3, width - 1, "# ");
}
}
switch (vartab[i]->type)
{
case mailvar_type_number:
fprintf (out, "%s=%d", vartab[i]->name, vartab[i]->value.number);
mu_stream_printf (out, "%s=%d",
vartab[i]->name, vartab[i]->value.number);
break;
case mailvar_type_string:
fprintf (out, "%s=\"%s\"", vartab[i]->name, vartab[i]->value.string);
mu_stream_printf (out, "%s=\"%s\"",
vartab[i]->name, vartab[i]->value.string);
break;
case mailvar_type_boolean:
if (!vartab[i]->value.bool)
fprintf (out, "no");
fprintf (out, "%s", vartab[i]->name);
mu_stream_printf (out, "no");
mu_stream_printf (out, "%s", vartab[i]->name);
break;
case mailvar_type_whatever:
fprintf (out, "%s %s", vartab[i]->name, _("oops?"));
mu_stream_printf (out, "%s %s", vartab[i]->name, _("oops?"));
}
fprintf (out, "\n");
mu_stream_printf (out, "\n");
}
free (vartab);
if (out != ofile)
pclose (out);
mu_stream_unref (out);
}
void
mailvar_variable_format (FILE *fp,
mailvar_variable_format (mu_stream_t stream,
const struct mailvar_variable *var,
const char *defval)
{
......@@ -745,20 +751,20 @@ mailvar_variable_format (FILE *fp,
switch (var->type)
{
case mailvar_type_string:
fprintf (fp, "%s", var->value.string);
mu_stream_printf (stream, "%s", var->value.string);
break;
case mailvar_type_number:
fprintf (fp, "%d", var->value.number);
mu_stream_printf (stream, "%d", var->value.number);
break;
case mailvar_type_boolean:
fprintf (fp, "%s", var->set ? "yes" : "no");
mu_stream_printf (stream, "%s", var->set ? "yes" : "no");
break;
default:
if (defval)
fprintf (fp, "%s", defval);
mu_stream_printf (stream, "%s", defval);
break;
}
}
......@@ -773,45 +779,51 @@ static char *typestr[] =
};
static void
describe_symbol (FILE *out, int width, const struct mailvar_symbol *sym)
describe_symbol (mu_stream_t out, int width, const struct mailvar_symbol *sym)
{
int n;
int i, t;
const struct mailvar_symbol *ali;
mu_stream_stat_buffer stat;
n = fprintf (out, "%s", sym->var.name);
mu_stream_set_stat (out, MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT),
stat);
mu_stream_printf (out, "%s", sym->var.name);
for (ali = sym + 1; ali->var.name && ali->flags & MAILVAR_ALIAS; ali++)
{
size_t len = strlen (ali->var.name) + 2;
if (n + len > width)
n = fprintf (out, "\n%s", ali->var.name);
if (stat[MU_STREAM_STAT_OUT] + len > width)
{
stat[MU_STREAM_STAT_OUT] = 0;
mu_stream_printf (out, "\n%s", ali->var.name);
}
else
n = fprintf (out, ", %s", ali->var.name);
mu_stream_printf (out, ", %s", ali->var.name);
}
fputc ('\n', out);
mu_stream_printf (out, "\n");
mu_stream_set_stat (out, 0, NULL);
fprintf (out, _("Type: "));
mu_stream_printf (out, _("Type: "));
for (i = 0, t = 0; i < sizeof (typestr) / sizeof (typestr[0]); i++)
if (sym->flags & MAILVAR_TYPEMASK (i))
{
if (t++)
fprintf (out, " %s ", _("or"));
fprintf (out, "%s", gettext (typestr[i]));
mu_stream_printf (out, " %s ", _("or"));
mu_stream_printf (out, "%s", gettext (typestr[i]));
}
if (!t)
fprintf (out, "%s", gettext (typestr[0]));
fputc ('\n', out);
mu_stream_printf (out, "%s", gettext (typestr[0]));
mu_stream_printf (out, "\n");
fprintf (out, "%s", _("Current value: "));
mu_stream_printf (out, "%s", _("Current value: "));
mailvar_variable_format (out, &sym->var, _("[not set]"));
if (sym->flags & MAILVAR_RDONLY)
fprintf (out, " [%s]", _("read-only"));
fputc ('\n', out);
mu_stream_printf (out, " [%s]", _("read-only"));
mu_stream_printf (out, "\n");
print_descr (out, gettext (sym->descr ? sym->descr : N_("Not documented")),
1, 1, width - 1, NULL);
fputc ('\n', out);
mu_stream_printf (out, "\n");
}
int
......@@ -819,10 +831,7 @@ mail_variable (int argc, char **argv)
{
int pagelines = util_get_crt ();
int width = util_getcols ();
FILE *out = ofile;
if (pagelines)
out = popen (getenv ("PAGER"), "w");
mu_stream_t out = open_pager (pagelines + 1);
if (argc == 1)
{
......@@ -840,13 +849,12 @@ mail_variable (int argc, char **argv)
{
struct mailvar_symbol *sym = find_mailvar_symbol (argv[i]);
if (!sym)
fprintf (out, "%s: unknown\n", argv[i]);
mu_stream_printf (out, "%s: unknown\n", argv[i]);
else
describe_symbol (out, width, sym);
}
}
if (out != ofile)
pclose (out);
mu_stream_unref (out);
return 0;
}
......
......@@ -241,21 +241,21 @@ static char *cur_p;
int
yyerror (const char *s)
{
fprintf (stderr, "%s: ", xargv[0]);
fprintf (stderr, "%s", s);
mu_stream_printf (mu_strerr, "%s: ", xargv[0]);
mu_stream_printf (mu_strerr, "%s", s);
if (!cur_p)
fprintf (stderr, _(" near end"));
mu_stream_printf (mu_strerr, _(" near end"));
else if (*cur_p == 0)
{
int i = (*cur_p == 0) ? cur_ind + 1 : cur_ind;
if (i == xargc)
fprintf (stderr, _(" near end"));
mu_stream_printf (mu_strerr, _(" near end"));
else
fprintf (stderr, _(" near %s"), xargv[i]);
mu_stream_printf (mu_strerr, _(" near %s"), xargv[i]);
}
else
fprintf (stderr, _(" near %s"), cur_p);
fprintf (stderr, "\n");
mu_stream_printf (mu_strerr, _(" near %s"), cur_p);
mu_stream_printf (mu_strerr, "\n");
return 0;
}
......@@ -756,13 +756,13 @@ void
msgset_print (msgset_t *mset)
{
int i;
printf ("(");
printf ("%d .", mset->msg_part[0]);
mu_printf ("(");
mu_printf ("%d .", mset->msg_part[0]);
for (i = 1; i < mset->npart; i++)
{
printf (" %d", mset->msg_part[i]);
mu_printf (" %d", mset->msg_part[i]);
}
printf (")\n");
mu_printf (")\n");
}
int
......
......@@ -30,9 +30,8 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data)
mu_header_t hdr;
mu_body_t body;
mu_stream_t stream;
char buffer[512];
size_t n = 0, lines = 0;
FILE *out = ofile;
size_t lines = 0;
mu_stream_t out;
int pagelines = util_get_crt ();
int status;
......@@ -56,8 +55,7 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data)
}
}
if (pagelines && lines > pagelines)
out = popen (getenv ("PAGER"), "w");
out = open_pager (lines);
if (mailvar_get (NULL, "showenvelope", mailvar_type_boolean, 0) == 0)
print_envelope (mspec, mesg, "From");
......@@ -77,16 +75,16 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data)
continue;
if (mail_header_is_visible (sptr))
{
fprintf (out, "%s: ", sptr);
mu_stream_printf (out, "%s: ", sptr);
mu_header_aget_field_value (hdr, i, &tmp);
if (mail_header_is_unfoldable (sptr))
mu_string_unfold (tmp, NULL);
util_rfc2047_decode (&tmp);
fprintf (out, "%s\n", tmp);
mu_stream_printf (out, "%s\n", tmp);
free (tmp);
}
}
fprintf (out, "\n");
mu_stream_printf (out, "\n");
mu_message_get_body (mesg, &body);
status = mu_body_get_streamref (body, &stream);
}
......@@ -96,26 +94,20 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void *data)
if (status)
{
mu_error (_("get_stream error: %s"), mu_strerror (status));
if (out != ofile)
pclose (out);
mu_stream_unref (out);
return 0;
}
/* FIXME: Use mu_stream_copy instead? */
while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0
&& n != 0)
{
mu_stream_copy (out, stream, 0, NULL);
/* FIXME:
if (ml_got_interrupt())
{
util_error (_("\nInterrupt"));
break;
}
buffer[n] = '\0';
fprintf (out, "%s", buffer);
}
*/
mu_stream_destroy (&stream);
if (out != ofile)
pclose (out);
mu_stream_destroy (&out);
util_mark_read (mesg);
......
......@@ -49,7 +49,7 @@ mail_mbox_close ()
mu_mailbox_get_url (mbox, &url);
mu_mailbox_messages_count (mbox, &held_count);
fprintf (ofile,
mu_stream_printf (ostream,
ngettext ("Held %d message in %s\n",
"Held %d messages in %s\n",
held_count),
......@@ -153,7 +153,7 @@ mail_mbox_commit ()
mu_url_t u = NULL;
mu_mailbox_get_url (dest_mbox, &u);
fprintf(ofile,
mu_stream_printf (ostream,
ngettext ("Saved %d message in %s\n",
"Saved %d messages in %s\n",
saved_count),
......
......@@ -111,13 +111,13 @@ reply0 (msgset_t *mspec, mu_message_t msg, void *data)
else
compose_header_set (&env, MU_HEADER_SUBJECT, "", COMPOSE_REPLACE);
fprintf (ofile, "To: %s\n",
mu_stream_printf (ostream, "To: %s\n",
compose_header_get (&env, MU_HEADER_TO, ""));
str = compose_header_get (&env, MU_HEADER_CC, NULL);
if (str)
fprintf (ofile, "Cc: %s\n", str);
fprintf (ofile, "Subject: %s\n\n",
compose_header_get (&env, MU_HEADER_SUBJECT, ""));
mu_stream_printf (ostream, "Cc: %s\n", str);
mu_stream_printf (ostream, "Subject: %s\n\n",
compose_header_get (&env, MU_HEADER_SUBJECT, ""));
make_in_reply_to (&env, msg);
make_references (&env, msg);
......
......@@ -31,7 +31,7 @@ process_list (int argc, char **argv,
if (argc == 1)
{
if (mu_list_is_empty (*list))
fprintf (ofile, _(msg));
mu_stream_printf (ostream, "%s", _(msg));
else
util_slist_print (*list, 1);
return 0;
......@@ -125,7 +125,8 @@ mail_nosender (int argc, char **argv)
if (argc == 1)
{
util_slist_destroy (&sender_headers);
fprintf (ofile, _("Sender address is obtained from the envelope\n"));
mu_stream_printf (ostream,
_("Sender address is obtained from the envelope\n"));
}
else
while (--argc)
......
......@@ -52,7 +52,7 @@ list_headers (void *item, void *data)
if (!name || strcmp (name, hp->name) == 0)
{
printf ("%s: %s\n", hp->name, hp->value);
mu_stream_printf (ostream, "%s: %s\n", hp->name, hp->value);
}
return 0;
}
......@@ -347,27 +347,27 @@ save_dead_message (compose_env_t *env)
{
if (mailvar_get (NULL, "save", mailvar_type_boolean, 0) == 0)
{
FILE *fp = fopen (getenv ("DEAD"),
mailvar_get (NULL, "appenddeadletter",
mailvar_type_boolean, 0) == 0 ?
"a" : "w");
if (!fp)
mu_stream_t dead_letter;
int rc;
const char *name = getenv ("DEAD");
/* FIXME: Use MU_STREAM_APPEND if appenddeadletter, instead of the
stream manipulations below */
rc = mu_file_stream_create (&dead_letter, name, MU_STREAM_WRITE);
if (rc)
{
util_error (_("Cannot open file %s: %s"), getenv ("DEAD"),
strerror (errno));
util_error (_("Cannot open file %s: %s"), name, strerror (rc));
return 1;
}
if (mailvar_get (NULL, "appenddeadletter",
mailvar_type_boolean, 0) == 0)
mu_stream_seek (dead_letter, 0, MU_SEEK_END, NULL);
else
{
char *buf = NULL;
size_t n;
rewind (env->file);
while (getline (&buf, &n, env->file) > 0)
fputs (buf, fp);
fclose (fp);
free (buf);
}
mu_stream_truncate (dead_letter, 0);
mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL);
mu_stream_copy (dead_letter, env->compstr, 0, NULL);
mu_stream_destroy (&dead_letter);
}
return 0;
}
......@@ -433,28 +433,22 @@ send_message (mu_message_t msg)
addresses on the command line and message contents on standard input. */
int
mail_send0 (compose_env_t * env, int save_to)
mail_send0 (compose_env_t *env, int save_to)
{
int done = 0;
int fd, rc;
char *filename;
int rc;
char *savefile = NULL;
int int_cnt;
char *escape;
rc = mu_tempfile (NULL, 0, &fd, &filename);
/* Prepare environment */
rc = mu_temp_file_stream_create (&env->compstr, NULL, 0);
if (rc)
{
util_error (_("Cannot open temporary file: %s"), mu_strerror (rc));
return 1;
}
/* Prepare environment */
env = env;
env->filename = filename;
env->file = fdopen (fd, "w+");
env->ofile = ofile;
ml_clear_interrupt ();
int_cnt = 0;
while (!done)
......@@ -466,7 +460,7 @@ mail_send0 (compose_env_t * env, int save_to)
{
if (mailvar_get (NULL, "ignore", mailvar_type_boolean, 0) == 0)
{
fprintf (stdout, "@\n");
mu_stream_printf (ostream, "@\n");
}
else
{
......@@ -502,7 +496,7 @@ mail_send0 (compose_env_t * env, int save_to)
&& buf[0] == escape[0])
{
if (buf[1] == buf[0])
fprintf (env->file, "%s\n", buf + 1);
mu_stream_printf (env->compstr, "%s\n", buf + 1);
else if (buf[1] == '.')
done = 1;
else if (buf[1] == 'x')
......@@ -515,8 +509,6 @@ mail_send0 (compose_env_t * env, int save_to)
struct mu_wordsplit ws;
int status;
ofile = env->file;
if (mu_wordsplit (buf + 1, &ws, MU_WRDSF_DEFFLAGS) == 0)
{
if (ws.ws_wordc > 0)
......@@ -539,13 +531,11 @@ mail_send0 (compose_env_t * env, int save_to)
util_error (_("Cannot parse escape sequence: %s"),
mu_wordsplit_strerror (&ws));
}
ofile = env->ofile;
}
}
else
fprintf (env->file, "%s\n", buf);
fflush (env->file);
mu_stream_printf (env->compstr, "%s\n", buf);
mu_stream_flush (env->compstr);
free (buf);
}
......@@ -553,9 +543,7 @@ mail_send0 (compose_env_t * env, int save_to)
if (int_cnt)
{
save_dead_message (env);
fclose (env->file);
remove (filename);
free (filename);
mu_stream_destroy (&env->compstr);
return 1;
}
......@@ -571,115 +559,100 @@ mail_send0 (compose_env_t * env, int save_to)
if (util_header_expand (&env->header) == 0)
{
mu_message_t msg = NULL;
int rc;
mu_stream_t instr;
int status = 0;
mu_message_create (&msg, NULL);
/* Fill the body. */
mu_stream_seek (env->compstr, 0, MU_SEEK_SET, NULL);
rc = fill_body (msg, env->compstr);
rc = mu_file_stream_create (&instr, filename, MU_STREAM_READ);
if (rc)
mu_error (_("cannot open temporary stream `%s' for reading: %s"),
filename, mu_strerror (rc));
else
if (rc == 0)
{
mu_message_t msg = NULL;
int rc;
int status = 0;
mu_message_create (&msg, NULL);
/* Fill the body. */
rc = fill_body (msg, instr);
mu_stream_destroy (&instr);
if (rc == 0)
/* Save outgoing message */
if (save_to)
{
/* Save outgoing message */
if (save_to)
{
char *tmp = compose_header_get (env, MU_HEADER_TO, NULL);
mu_address_t addr = NULL;
char *tmp = compose_header_get (env, MU_HEADER_TO, NULL);
mu_address_t addr = NULL;
mu_address_create (&addr, tmp);
mu_address_aget_email (addr, 1, &savefile);
mu_address_destroy (&addr);
if (savefile)
{
char *p = strchr (savefile, '@');
if (p)
*p = 0;
}
}
util_save_outgoing (msg, savefile);
mu_address_create (&addr, tmp);
mu_address_aget_email (addr, 1, &savefile);
mu_address_destroy (&addr);
if (savefile)
free (savefile);
{
char *p = strchr (savefile, '@');
if (p)
*p = 0;
}
}
util_save_outgoing (msg, savefile);
if (savefile)
free (savefile);
/* Check if we need to save the message to files or pipes. */
if (env->outfiles)
/* Check if we need to save the message to files or pipes. */
if (env->outfiles)
{
int i;
for (i = 0; i < env->nfiles; i++)
{
int i;
for (i = 0; i < env->nfiles; i++)
/* Pipe to a cmd. */
if (env->outfiles[i][0] == '|')
status = msg_to_pipe (env->outfiles[i] + 1, msg);
/* Save to a file. */
else
{
/* Pipe to a cmd. */
if (env->outfiles[i][0] == '|')
status = msg_to_pipe (env->outfiles[i] + 1, msg);
/* Save to a file. */
else
mu_mailbox_t mbx = NULL;
status = mu_mailbox_create_default (&mbx,
env->outfiles[i]);
if (status == 0)
{
mu_mailbox_t mbx = NULL;
status = mu_mailbox_create_default (&mbx,
env->outfiles[i]);
status = mu_mailbox_open (mbx, MU_STREAM_WRITE
| MU_STREAM_CREAT);
if (status == 0)
{
status = mu_mailbox_open (mbx, MU_STREAM_WRITE
| MU_STREAM_CREAT);
if (status == 0)
{
status = mu_mailbox_append_message (mbx, msg);
if (status)
util_error (_("Cannot append message: %s"),
mu_strerror (status));
mu_mailbox_close (mbx);
}
mu_mailbox_destroy (&mbx);
status = mu_mailbox_append_message (mbx, msg);
if (status)
util_error (_("Cannot append message: %s"),
mu_strerror (status));
mu_mailbox_close (mbx);
}
if (status)
util_error (_("Cannot create mailbox %s: %s"),
env->outfiles[i],
mu_strerror (status));
mu_mailbox_destroy (&mbx);
}
if (status)
util_error (_("Cannot create mailbox %s: %s"),
env->outfiles[i],
mu_strerror (status));
}
}
/* Do we need to Send the message on the wire? */
if (status == 0 &&
(compose_header_get (env, MU_HEADER_TO, NULL) ||
compose_header_get (env, MU_HEADER_CC, NULL) ||
compose_header_get (env, MU_HEADER_BCC, NULL)))
}
/* Do we need to Send the message on the wire? */
if (status == 0 &&
(compose_header_get (env, MU_HEADER_TO, NULL) ||
compose_header_get (env, MU_HEADER_CC, NULL) ||
compose_header_get (env, MU_HEADER_BCC, NULL)))
{
mu_message_set_header (msg, env->header, NULL);
env->header = NULL;
status = send_message (msg);
if (status)
{
mu_message_set_header (msg, env->header, NULL);
env->header = NULL;
status = send_message (msg);
if (status)
{
mu_error (_("cannot send message: %s"),
mu_strerror (status));
save_dead_message (env);
}
mu_error (_("cannot send message: %s"),
mu_strerror (status));
save_dead_message (env);
}
}
fclose (env->file);
mu_message_destroy (&msg, NULL);
remove (filename);
free (filename);
return status;
}
}
mu_stream_destroy (&env->compstr);
mu_message_destroy (&msg, NULL);
return status;
}
else
save_dead_message (env);
fclose (env->file);
remove (filename);
free (filename);
mu_stream_destroy (&env->compstr);
return 1;
}
......
......@@ -29,7 +29,7 @@ mail_setenv (int argc, char **argv)
char **p;
for (p = environ; *p; p++)
printf ("%s\n", *p);
mu_stream_printf (ostream, "%s\n", *p);
}
else
{
......
......@@ -60,81 +60,65 @@ expand_bang (char **pbuf)
int
mail_execute (int shell, int argc, char **argv)
{
pid_t pid;
char *buf = NULL;
char *argv0 = NULL;
int xargc, i, status, rc;
char **xargv;
char *buf;
if (argc)
if (argc == 0)
{
argv0 = argv[0];
/* Skip leading whitespace from argv[0] */
while (mu_isspace (**argv))
(*argv)++;
/* No arguments mean execute a copy of the user shell */
shell = 1;
}
xargc = argc;
if (shell && argc < 3)
xargc = 3;
xargv = xcalloc (xargc + 1, sizeof (xargv[0]));
for (i = 0; i < argc; i++)
xargv[i] = argv[i];
/* Expand arguments if required */
if (mailvar_get (NULL, "bang", mailvar_type_boolean, 0) == 0)
{
int i;
for (i = 0; i < argc; i++)
expand_bang (argv + i);
for (i = 0; i < xargc; i++)
expand_bang (xargv + i);
}
/* Construct command line and save it to gnu-last-command variable */
mu_argcv_string (argc, argv, &buf);
/* Reconstruct the command line and save it to gnu-last-command variable.
Important: use argc (not xargc)!
*/
mu_argcv_string (argc, xargv, &buf);
mailvar_set ("gnu-last-command", buf, mailvar_type_string,
MOPTF_QUIET|MOPTF_OVERWRITE);
MOPTF_QUIET | MOPTF_OVERWRITE);
/* Do actual work */
pid = fork ();
if (pid == 0)
if (shell)
{
if (shell)
xargv[0] = getenv ("SHELL");
if (argc == 0)
xargv[1] = NULL;
else
{
if (argc == 0)
{
argv = xmalloc (sizeof (argv[0]) * 2);
argv[0] = getenv ("SHELL");
argv[1] = NULL;
argc = 1;
}
else
{
/* 1(shell) + 1 (-c) + 1(arg) + 1 (null) = 4 */
argv = xmalloc (4 * (sizeof (argv[0])));
argv[0] = getenv ("SHELL");
argv[1] = "-c";
argv[2] = buf;
argv[3] = NULL;
argc = 3;
}
xargv[1] = "-c";
xargv[2] = buf;
xargv[3] = NULL;
}
execvp (argv[0], argv);
exit (1);
}
else
}
rc = mu_spawnvp (xargv[0], xargv, &status);
if (rc)
{
if (argv0) /* Restore argv[0], else mu_argcv_free will coredump */
argv[0] = argv0;
free (buf);
if (pid > 0)
{
while (waitpid (pid, NULL, 0) == -1)
/* do nothing */;
return 0;
}
else /* if (pid < 0) */
{
mu_error ("fork failed: %s", mu_strerror (errno));
return 1;
}
mu_diag_funcall (MU_DIAG_ERROR, "mu_spawnvp", xargv[0], rc);
}
/* FIXME:
else if (status)
mu_diag_output (MU_DIAG_NOTICE, ....
*/
free (buf);
free (xargv);
return rc;
}
/*
......
......@@ -29,11 +29,11 @@ size0 (msgset_t *mspec, mu_message_t msg, void *data)
mu_message_size (msg, &size);
mu_message_lines (msg, &lines);
fprintf (ofile, "%c%2lu %3lu/%-5lu\n",
is_current_message (mspec->msg_part[0]) ? '>' : ' ',
(unsigned long) mspec->msg_part[0],
(unsigned long) lines,
(unsigned long) size);
mu_stream_printf (ostream, "%c%2lu %3lu/%-5lu\n",
is_current_message (mspec->msg_part[0]) ? '>' : ' ',
(unsigned long) mspec->msg_part[0],
(unsigned long) lines,
(unsigned long) size);
return 0;
}
......
......@@ -20,19 +20,24 @@
static char *
source_readline (void *closure, int cont MU_ARG_UNUSED)
{
FILE *fp = closure;
size_t s = 0;
mu_stream_t input = closure;
size_t size = 0, n;
char *buf = NULL;
if (getline (&buf, &s, fp) >= 0)
int rc;
rc = mu_stream_getline (input, &buf, &size, &n);
if (rc)
{
mu_rtrim_class (buf, MU_CTYPE_SPACE);
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE, NULL);
return buf;
mu_diag_funcall (MU_DIAG_ERROR, "mu_stream_getline", NULL, rc);
return NULL;
}
return NULL;
if (n == 0)
return NULL;
mu_rtrim_class (buf, MU_CTYPE_SPACE);
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_ADVANCE_LOCUS_LINE, NULL);
return buf;
}
/*
......@@ -42,9 +47,10 @@ source_readline (void *closure, int cont MU_ARG_UNUSED)
int
mail_source (int argc, char **argv)
{
FILE *fp;
mu_stream_t input;
int save_term;
struct mu_locus locus;
int rc;
if (argc != 2)
{
......@@ -52,12 +58,12 @@ mail_source (int argc, char **argv)
util_error (_("source requires a single argument"));
return 1;
}
fp = fopen (argv[1], "r");
if (!fp)
rc = mu_file_stream_create (&input, argv[1], MU_STREAM_READ);
if (rc)
{
if (errno != ENOENT)
util_error(_("Cannot open `%s': %s"), argv[1], strerror(errno));
if (rc != ENOENT)
util_error(_("Cannot open `%s': %s"), argv[1], strerror (rc));
return 1;
}
......@@ -68,10 +74,10 @@ mail_source (int argc, char **argv)
locus.mu_col = 0;
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_SET_LOCUS, &locus);
mail_mainloop (source_readline, fp, 0);
mail_mainloop (source_readline, input, 0);
interactive = save_term;
mu_stream_ioctl (mu_strerr, MU_IOCTL_LOGSTREAM,
MU_IOCTL_LOGSTREAM_SET_LOCUS, NULL);
fclose (fp);
mu_stream_unref (input);
return 0;
}
......
......@@ -24,21 +24,20 @@ show_part (struct mime_descend_closure *closure, void *data)
size_t width;
size_t size = 0;
width = fprint_msgset (ofile, closure->msgset);
format_msgset (ostream, closure->msgset, &width);
for (; width < 5; width++)
fputc (' ', ofile);
mu_stream_write (ostream, " ", 1, NULL);
fprintf (ofile, " %-25s", closure->type);
mu_stream_printf (ostream, " %-25s", closure->type);
mu_message_size (closure->message, &size);
if (size < 1024)
fprintf (ofile, " %4lu", (unsigned long) size);
mu_stream_printf (ostream, " %4lu", (unsigned long) size);
else if (size < 1024*1024)
fprintf (ofile, "%4luK", (unsigned long) size / 1024);
mu_stream_printf (ostream, "%4luK", (unsigned long) size / 1024);
else
fprintf (ofile, "%4luM", (unsigned long) size / 1024 / 1024);
fprintf (ofile, "\n");
mu_stream_printf (ostream, "%4luM", (unsigned long) size / 1024 / 1024);
mu_stream_printf (ostream, "\n");
return 0;
}
......
......@@ -60,16 +60,20 @@ mail_summary (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
{
mu_url_t url = NULL;
mu_mailbox_get_url (mbox, &url);
printf("\"%s\": ", util_url_to_string (url));
mu_stream_printf (ostream, "\"%s\": ", util_url_to_string (url));
}
printf (ngettext ("%d message", "%d messages", count), count);
mu_stream_printf (ostream,
ngettext ("%d message", "%d messages", count), count);
if (mnew > 0)
printf (ngettext (" %d new", " %d new", mnew), mnew);
mu_stream_printf (ostream, ngettext (" %d new", " %d new", mnew), mnew);
if (mseen > 0)
printf (ngettext (" %d unread", " %d unread", mseen), mseen);
mu_stream_printf (ostream, ngettext (" %d unread", " %d unread", mseen),
mseen);
if (mdelete > 0)
printf (ngettext (" %d deleted", " %d deleted", mdelete), mdelete);
printf("\n");
mu_stream_printf (ostream,
ngettext (" %d deleted", " %d deleted", mdelete),
mdelete);
mu_stream_printf (ostream, "\n");
/* Set the cursor. */
set_cursor ((first_new == 0) ? ((first_unread == 0) ?
......
......@@ -25,23 +25,23 @@ static int
top0 (msgset_t *mspec, mu_message_t msg, void *data)
{
mu_stream_t stream;
char buf[512];
size_t n;
char *buf = NULL;
size_t size = 0, n;
int lines;
if (mailvar_get (&lines, "toplines", mailvar_type_number, 1)
|| lines < 0)
return 1;
/* FIXME: Use mu_stream_copy */
mu_message_get_streamref (msg, &stream);
for (; lines > 0; lines--)
{
int status = mu_stream_readline (stream, buf, sizeof (buf), &n);
int status = mu_stream_getline (stream, &buf, &size, &n);
if (status != 0 || n == 0)
break;
fprintf (ofile, "%s", buf);
mu_stream_printf (ostream, "%s", buf);
}
free (buf);
mu_stream_destroy (&stream);
set_cursor (mspec->msg_part[0]);
......
......@@ -31,7 +31,7 @@ mail_unset (int argc, char **argv)
else
{
int status = 0, i = 1;
for (i=1; i < argc; i++)
for (i = 1; i < argc; i++)
{
char *buf = xmalloc ((7+strlen (argv[i])) * sizeof (char));
strcpy (buf, "set no");
......
......@@ -278,22 +278,20 @@ util_help (void *table, size_t nmemb, size_t size, const char *word)
if (!word)
{
int i = 0;
FILE *out = stdout;
mu_stream_t out;
char *p;
if (mailvar_get (NULL, "crt", mailvar_type_boolean, 0) == 0)
out = popen (getenv ("PAGER"), "w");
out = open_pager (util_screen_lines () + 1);
for (p = table, i = 0; i < nmemb; i++, p += size)
{
struct mail_command *cp = (struct mail_command *)p;
if (cp->synopsis == NULL)
continue;
fprintf (out, "%s\n", cp->synopsis);
mu_stream_printf (out, "%s\n", cp->synopsis);
}
if (out != stdout)
pclose (out);
mu_stream_unref (out);
return 0;
}
......@@ -302,11 +300,11 @@ util_help (void *table, size_t nmemb, size_t size, const char *word)
int status = 0;
struct mail_command *cp = util_find_entry (table, nmemb, size, word);
if (cp && cp->synopsis)
fprintf (stdout, "%s\n", cp->synopsis);
mu_stream_printf (ostream, "%s\n", cp->synopsis);
else
{
status = 1;
fprintf (stdout, _("Unknown command: %s\n"), word);
mu_stream_printf (ostream, _("Unknown command: %s\n"), word);
}
return status;
}
......@@ -339,12 +337,12 @@ util_command_list (void *table, size_t nmemb, size_t size)
if (pos >= cols)
{
pos = len + 1;
fprintf (ofile, "\n%s ", cmd);
mu_stream_printf (ostream, "\n%s ", cmd);
}
else
fprintf (ofile, "%s ", cmd);
mu_stream_printf (ostream, "%s ", cmd);
}
fprintf (ofile, "\n");
mu_stream_printf (ostream, "\n");
return 0;
}
......@@ -572,8 +570,7 @@ util_slist_print (mu_list_t list, int nl)
for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr))
{
mu_iterator_current (itr, (void **)&name);
fprintf (ofile, "%s%c", name, nl ? '\n' : ' ');
mu_stream_printf (ostream, "%s%c", name, nl ? '\n' : ' ');
}
mu_iterator_destroy (&itr);
}
......@@ -760,8 +757,8 @@ util_error (const char *format, ...)
va_start (ap, format);
vfprintf (stderr, format, ap);
fprintf (stderr, "\n");
mu_stream_vprintf (mu_strerr, format, ap);
mu_stream_printf (mu_strerr, "\n");
va_end(ap);
}
......@@ -1150,3 +1147,29 @@ util_url_to_string (mu_url_t url)
}
return mu_url_to_string (url);
}
mu_stream_t
open_pager (size_t lines)
{
const char *pager;
unsigned pagelines = util_get_crt ();
mu_stream_t str;
if (pagelines && lines > pagelines && (pager = getenv ("PAGER")))
{
int rc = mu_command_stream_create (&str, pager, MU_STREAM_WRITE);
if (rc)
{
mu_diag_funcall (MU_DIAG_ERROR, "mu_prog_stream_create",
pager, rc);
str = ostream;
mu_stream_ref (str);
}
}
else
{
str = ostream;
mu_stream_ref (str);
}
return str;
}
......
......@@ -39,16 +39,16 @@ static const char *with_defs[] =
int
mail_version (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
{
fprintf (ofile, "%s", program_version);
mu_stream_printf (ostream, "%s", program_version);
if (with_defs[0] != NULL)
{
int i;
fprintf (ofile, " (");
mu_stream_printf (ostream, " (");
for (i = 0; with_defs[i]; i++)
fprintf (ofile, " %s", with_defs[i]);
fprintf (ofile, " )");
mu_stream_printf (ostream, " %s", with_defs[i]);
mu_stream_printf (ostream, " )");
}
fprintf (ofile, "\n");
mu_stream_printf (ostream, "\n");
return 0;
}
......
......@@ -114,8 +114,8 @@ mail_write (int argc, char **argv)
mu_stream_close (output);
mu_stream_destroy (&output);
fprintf (ofile, "\"%s\" %3lu/%-5lu\n", filename,
(unsigned long) total_lines, (unsigned long) total_size);
mu_stream_printf (ostream, "\"%s\" %3lu/%-5lu\n", filename,
(unsigned long) total_lines, (unsigned long) total_size);
free (filename);
msgset_free (msglist);
......
......@@ -120,7 +120,7 @@ mail_z (int argc, char **argv)
case D_BWD:
if (page_move (-count) == 0)
{
fprintf (stdout, _("On first screenful of messages\n"));
mu_stream_printf (ostream, _("On first screenful of messages\n"));
return 0;
}
break;
......@@ -128,7 +128,7 @@ mail_z (int argc, char **argv)
case D_FWD:
if (page_move (count) == 0)
{
fprintf (stdout, _("On last screenful of messages\n"));
mu_stream_printf (ostream, _("On last screenful of messages\n"));
return 0;
}
break;
......