Commit 379426a1 379426a154fe7ef116f2610acd0d0fa2e6a35cc7 by Sergey Poznyakoff

Fix prog streams.

* libmailutils/prog_stream.c (REDIRECT_STDIN_P)
(REDIRECT_STDOUT_P): Fix macros.
* libmailutils/stream.c (mu_stream_open): If stream is open
with MU_STREAM_APPEND, reposition to its end.
(_stream_write_unbuffered): Do not signal EACCESS for MU_STREAM_APPEND
streams.

* mail/pipe.c (mail_pipe): Rewrite using streams instead of FILEs.
* mail/send.c (fill_body): Likewise.
* mail/write.c (mail_write): Likewise.
1 parent 6eff29e9
......@@ -67,8 +67,8 @@ _prog_stream_unregister (struct _mu_prog_stream *stream)
# define getmaxfd() 64
#endif
#define REDIRECT_STDIN_P(f) ((f) & (MU_STREAM_WRITE|MU_STREAM_RDWR))
#define REDIRECT_STDOUT_P(f) ((f) & (MU_STREAM_READ|MU_STREAM_RDWR))
#define REDIRECT_STDIN_P(f) ((f) & MU_STREAM_WRITE)
#define REDIRECT_STDOUT_P(f) ((f) & MU_STREAM_READ)
static int
start_program_filter (pid_t *pid, int *p, int argc, char **argv,
......
......@@ -294,8 +294,15 @@ mu_stream_open (mu_stream_t stream)
{
int rc;
if (stream->open && (rc = stream->open (stream)))
if (stream->open)
{
if ((rc = stream->open (stream)))
return mu_stream_seterr (stream, rc, 1);
if ((stream->flags & (MU_STREAM_APPEND|MU_STREAM_SEEK)) ==
(MU_STREAM_APPEND|MU_STREAM_SEEK) &&
(rc = mu_stream_seek (stream, 0, MU_SEEK_END, NULL)))
return mu_stream_seterr (stream, rc, 1);
}
stream->bytes_in = stream->bytes_out = 0;
return 0;
}
......@@ -596,7 +603,7 @@ _stream_write_unbuffered (mu_stream_t stream,
if (!stream->write)
return mu_stream_seterr (stream, ENOSYS, 0);
if (!(stream->flags & MU_STREAM_WRITE))
if (!(stream->flags & (MU_STREAM_WRITE|MU_STREAM_APPEND)))
return mu_stream_seterr (stream, EACCES, 1);
if (stream->flags & _MU_STR_ERR)
......
......@@ -27,13 +27,10 @@
int
mail_pipe (int argc, char **argv)
{
mu_message_t msg;
mu_stream_t stream;
int rc;
mu_stream_t outstr;
char *cmd;
FILE *tube;
msgset_t *list, *mp;
char buffer[512];
size_t n = 0;
if (argc > 2)
cmd = argv[--argc];
......@@ -43,28 +40,33 @@ mail_pipe (int argc, char **argv)
if (msgset_parse (argc, argv, MSG_NODELETED|MSG_SILENT, &list))
return 1;
tube = popen (cmd, "w");
rc = mu_prog_stream_create (&outstr, cmd, MU_STREAM_WRITE);
if (rc == 0)
rc = mu_stream_open (outstr);
if (rc)
{
mu_error (_("cannot open `%s': %s"), cmd, mu_strerror (rc));
return 1;
}
for (mp = list; mp; mp = mp->next)
{
mu_message_t msg;
mu_stream_t stream;
if (util_get_message (mbox, mp->msg_part[0], &msg) == 0)
{
mu_message_get_streamref (msg, &stream);
/* FIXME: Use mu_stream_copy */
while (mu_stream_read (stream, buffer, sizeof (buffer) - 1, &n) == 0
&& n != 0)
{
buffer[n] = '\0';
fprintf (tube, "%s", buffer);
}
mu_stream_copy (outstr, stream, 0, NULL);
mu_stream_destroy (&stream);
if (mailvar_get (NULL, "page", mailvar_type_boolean, 0) == 0)
fprintf (tube, "\f\n");
mu_stream_write (outstr, "\f\n", 2, NULL);
}
util_mark_read (msg);
}
mu_stream_close (outstr);
mu_stream_destroy (&outstr);
msgset_free (list);
pclose (tube);
return 0;
}
......
......@@ -299,32 +299,27 @@ compose_destroy (compose_env_t *env)
free (env->outfiles);
}
/* FIXME: Can we use mu_stream_t instead of FILE? If so,
replace the loop with a call to mu_stream_copy. */
static int
fill_body (mu_message_t msg, FILE *file)
fill_body (mu_message_t msg, mu_stream_t instr)
{
int rc;
mu_body_t body = NULL;
mu_stream_t stream = NULL;
char *buf = NULL;
size_t n = 0;
int nullbody = 1;
mu_off_t n;
mu_message_get_body (msg, &body);
mu_body_get_streamref (body, &stream);
while (getline (&buf, &n, file) >= 0)
rc = mu_stream_copy (stream, instr, 0, &n);
mu_stream_destroy (&stream);
if (rc)
{
size_t len = strlen (buf);
if (len)
nullbody = 0;
mu_stream_write (stream, buf, len, NULL);
mu_error (_("cannot copy temporary stream: %s"), mu_strerror (rc));
return 1;
}
mu_stream_destroy (&stream);
if (buf)
free (buf);
if (nullbody)
if (n == 0)
{
if (mailvar_get (NULL, "nullbody", mailvar_type_boolean, 0) == 0)
{
......@@ -437,7 +432,6 @@ mail_send0 (compose_env_t * env, int save_to)
int done = 0;
int fd;
char *filename;
FILE *file;
char *savefile = NULL;
int int_cnt;
char *escape;
......@@ -570,8 +564,16 @@ mail_send0 (compose_env_t * env, int save_to)
if (util_header_expand (&env->header) == 0)
{
file = fopen (filename, "r");
if (file != NULL)
int rc;
mu_stream_t instr;
rc = mu_file_stream_create (&instr, filename, MU_STREAM_READ);
if (rc == 0)
rc = mu_stream_open (instr);
if (rc)
mu_error (_("cannot open temporary stream `%s' for reading: %s"),
filename, mu_strerror (rc));
else
{
mu_message_t msg = NULL;
int rc;
......@@ -580,8 +582,8 @@ mail_send0 (compose_env_t * env, int save_to)
mu_message_create (&msg, NULL);
/* Fill the body. */
rc = fill_body (msg, file);
fclose (file);
rc = fill_body (msg, instr);
mu_stream_destroy (&instr);
if (rc == 0)
{
......
......@@ -28,10 +28,8 @@
int
mail_write (int argc, char **argv)
{
mu_message_t msg;
mu_body_t bod;
mu_stream_t stream;
FILE *output;
int rc;
mu_stream_t output;
char *filename = NULL;
msgset_t *msglist = NULL, *mp;
int sender = 0;
......@@ -72,54 +70,58 @@ mail_write (int argc, char **argv)
}
}
output = fopen (filename, "a");
if (!output)
rc = mu_file_stream_create (&output, filename,
MU_STREAM_APPEND|MU_STREAM_CREAT);
if (rc == 0)
rc = mu_stream_open (output);
if (rc)
{
util_error (_("can't open %s: %s"), filename, strerror (errno));
util_error (_("can't open %s: %s"), filename, mu_strerror (rc));
free (filename);
fclose (output);
msgset_free (msglist);
return 1;
}
for (mp = msglist; mp; mp = mp->next)
{
mu_message_t msg;
mu_body_t body;
mu_stream_t stream;
mu_attribute_t attr;
char buffer[512];
size_t n = 0;
if (util_get_message (mbox, mp->msg_part[0], &msg))
continue;
mu_message_get_body (msg, &bod);
mu_message_get_body (msg, &body);
mu_body_size (bod, &size);
total_size += size;
mu_body_lines (bod, &size);
total_lines += size;
mu_body_get_streamref (body, &stream);
rc = mu_stream_copy (output, stream, 0, NULL);
mu_stream_destroy (&stream);
/* FIXME: Use mu_stream_copy */
mu_body_get_streamref (bod, &stream);
/* should there be a separator? */
while (mu_stream_read (stream, buffer, sizeof (buffer) - 1, &n) == 0
&& n != 0)
if (rc == 0)
{
buffer[n] = '\0';
fprintf (output, "%s", buffer);
}
mu_stream_destroy (&stream);
mu_body_size (body, &size);
total_size += size;
mu_body_lines (body, &size);
total_lines += size;
/* mark as saved. */
mu_message_get_attribute (msg, &attr);
mu_attribute_set_userflag (attr, MAIL_ATTRIBUTE_SAVED);
}
else
mu_error (_("cannot save %lu: %s"),
(unsigned long) mp->msg_part[0], mu_strerror (rc));
}
mu_stream_close (output);
mu_stream_destroy (&output);
fprintf (ofile, "\"%s\" %3lu/%-5lu\n", filename,
(unsigned long) total_lines, (unsigned long) total_size);
free (filename);
fclose (output);
msgset_free (msglist);
return 0;
}
......