Commit 27f9a867 27f9a867f4fcfaf29a22349043eaddcb60c2694e by Sergey Poznyakoff

Fix body start calculation in message_stream. Fix compose parser in mhn.

* libmailutils/stream/message_stream.c (scan_stream): Merge
with _message_open.
* mh/mhn.c (edit_forw): Do not set ws_delim.
Fix message addressing.
(mhn_edit): Remove the trailing newline.
1 parent 43853ce8
......@@ -145,51 +145,62 @@ copy_trimmed_value (const char *str)
}
static int
scan_stream (struct _mu_message_stream *str)
_message_open (mu_stream_t stream)
{
struct _mu_message_stream *str = (struct _mu_message_stream*) stream;
char *from = NULL;
char *env_from = NULL;
char *env_date = NULL;
int rc;
char *buffer = NULL;
size_t bufsize = 0;
size_t len;
size_t offset, len;
mu_off_t body_start, body_end;
mu_stream_t stream = str->transport;
if (str->envelope)
mu_stream_t transport = str->transport;
rc = mu_stream_seek (transport, 0, MU_SEEK_SET, NULL);
if (rc)
return rc;
offset = 0;
while ((rc = mu_stream_getline (transport, &buffer, &bufsize, &len)) == 0
&& len > 0)
{
char *s = str->envelope + 5;
char *p = strchr (s, ' ');
size_t len;
if (p)
if (offset == 0 && memcmp (buffer, "From ", 5) == 0)
{
len = p - s;
env_from = mu_alloc (len + 1);
if (!env_from)
char *s, *p;
str->envelope_length = len;
str->envelope = mu_strdup (buffer);
if (!str->envelope)
return ENOMEM;
memcpy (env_from, s, len);
env_from[len] = 0;
env_date = mu_strdup (p + 1);
if (!env_date)
str->envelope[len - 1] = 0;
s = str->envelope + 5;
p = strchr (s, ' ');
if (p)
{
free (env_from);
return ENOMEM;
len = p - s;
env_from = mu_alloc (len + 1);
if (!env_from)
return ENOMEM;
memcpy (env_from, s, len);
env_from[len] = 0;
env_date = mu_strdup (p + 1);
if (!env_date)
{
free (env_from);
return ENOMEM;
}
}
}
}
rc = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
if (rc)
return rc;
while ((rc = mu_stream_getline (stream, &buffer, &bufsize, &len)) == 0
&& len > 0)
{
if (buffer[0] == '\n')
break;
if (!env_from || !env_date)
else if (mu_mh_delim (buffer))
{
str->mark_offset = offset;
str->mark_length = len - 1; /* do not count the terminating newline */
break;
}
else if (!env_from || !env_date)
{
if (!from && mu_c_strncasecmp (buffer, MU_HEADER_FROM,
sizeof (MU_HEADER_FROM) - 1) == 0)
......@@ -206,14 +217,15 @@ scan_stream (struct _mu_message_stream *str)
env_date = copy_trimmed_value (buffer +
sizeof (MU_HEADER_ENV_DATE));
}
offset += len;
}
free (buffer);
rc = mu_stream_seek (stream, 0, MU_SEEK_CUR, &body_start);
rc = mu_stream_seek (transport, 0, MU_SEEK_CUR, &body_start);
if (rc)
return rc;
rc = mu_stream_size (stream, &body_end);
rc = mu_stream_size (transport, &body_end);
if (rc)
return rc;
......@@ -256,43 +268,6 @@ scan_stream (struct _mu_message_stream *str)
}
static int
_message_open (mu_stream_t stream)
{
struct _mu_message_stream *s = (struct _mu_message_stream*) stream;
size_t offset, len;
char *buffer = NULL;
size_t bufsize = 0;
int rc;
offset = 0;
mu_stream_seek (s->transport, 0, MU_SEEK_SET, NULL);
while ((rc = mu_stream_getline (s->transport, &buffer, &bufsize,
&len)) == 0
&& len > 0)
{
if (offset == 0 && memcmp (buffer, "From ", 5) == 0)
{
s->envelope_length = len;
s->envelope = mu_strdup (buffer);
if (!s->envelope)
return ENOMEM;
s->envelope[len - 1] = 0;
}
else if (mu_mh_delim (buffer))
{
s->mark_offset = offset;
s->mark_length = len - 1; /* do not count the terminating newline */
break;
}
offset += len;
}
free (buffer);
return scan_stream (s);
}
static int
_message_close (mu_stream_t stream)
{
struct _mu_message_stream *s = (struct _mu_message_stream*) stream;
......
......@@ -2083,9 +2083,7 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
if (status)
return status;
ws.ws_delim = "\n";
if (mu_wordsplit (cmd, &ws,
MU_WRDSF_DEFFLAGS | MU_WRDSF_DELIM | MU_WRDSF_WS))
if (mu_wordsplit (cmd, &ws, MU_WRDSF_DEFFLAGS))
{
mu_error (_("%s:%lu: cannot split line: %s"),
input_file,
......@@ -2100,7 +2098,19 @@ edit_forw (char *cmd, struct compose_env *env, mu_message_t *pmsg, int level)
for (i = 1; i < ws.ws_wordc; i++)
{
mu_message_t input_msg;
if (mh_get_message (mbox, i, &input_msg) == 0)
char *endp;
size_t n = strtoul (ws.ws_wordv[i], &endp, 10);
if (*endp)
{
mu_error (_("%s:%lu: malformed directive near %s"),
input_file,
(unsigned long) mhn_error_loc (env),
endp);
return 1;
}
if (mh_get_message (mbox, n, &input_msg) == 0)
{
mu_error (_("%s:%lu: no such message: %lu"),
input_file,
......@@ -2326,6 +2336,8 @@ mhn_edit (struct compose_env *env, int level)
if (line_count)
/* Close and append the previous part */
finish_text_msg (env, &msg, ascii_buf);
mu_rtrim_cset (buf, "\n");
/* Execute the directive */
tok = buf;
......