summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-05-02 22:38:06 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-05-02 22:38:06 +0300
commitb4ed41dcc3d0617358b9497d93c675e786109c5c (patch)
tree281b88f80f872d49c3efcb0d797789024a10db53
parent9289484606db997acfff0f832049de9bae537a35 (diff)
downloadmailutils-b4ed41dcc3d0617358b9497d93c675e786109c5c.tar.gz
mailutils-b4ed41dcc3d0617358b9497d93c675e786109c5c.tar.bz2
Various fixes in imap4d.
Imap4d successfully passes all tests. * imap4d/close.c (imap4d_close0): Fix improper use of MU_STREAM_READ (flags changed their semantics since then). * imap4d/fetch.c: Send \n terminated lines, rely on filters to recode line terminators to \r\n. (fetch_io): Rewrite using CRLF encoder and util_copy_out. (_frt_header_fields): Rewind memory stream before reading from it. * imap4d/auth_gsasl.c: Send \n terminated lines, rely on filters to recode line terminators to \r\n. * imap4d/auth_gss.c: Likewise. * imap4d/capability.c: Likewise. * imap4d/copy.c: Likewise. * imap4d/id.c: Likewise. * imap4d/idle.c: Likewise. * imap4d/list.c: Likewise. * imap4d/namespace.c: Likewise. * imap4d/preauth.c: Likewise. * imap4d/search.c: Likewise. * imap4d/status.c: Likewise. * imap4d/store.c: Likewise. * imap4d/select.c: Likewise. (imap4d_select_status): Fix improper use of MU_STREAM_READ. * imap4d/util.c: Send \n terminated lines, rely on filters to recode line terminators to \r\n. (util_setio): Apply CRLF filters to both input and output streams (in opposite directions). (util_copy_out): New function. (remove_cr): Remove. * imap4d/imap4d.h (util_copy_out): New prototype.
-rw-r--r--imap4d/auth_gsasl.c4
-rw-r--r--imap4d/auth_gss.c8
-rw-r--r--imap4d/capability.c2
-rw-r--r--imap4d/close.c2
-rw-r--r--imap4d/copy.c2
-rw-r--r--imap4d/fetch.c36
-rw-r--r--imap4d/id.c2
-rw-r--r--imap4d/idle.c2
-rw-r--r--imap4d/imap4d.h4
-rw-r--r--imap4d/list.c6
-rw-r--r--imap4d/namespace.c2
-rw-r--r--imap4d/preauth.c2
-rw-r--r--imap4d/search.c2
-rw-r--r--imap4d/select.c8
-rw-r--r--imap4d/status.c2
-rw-r--r--imap4d/store.c2
-rw-r--r--imap4d/util.c58
17 files changed, 66 insertions, 78 deletions
diff --git a/imap4d/auth_gsasl.c b/imap4d/auth_gsasl.c
index 8676c4f57..15e55ce08 100644
--- a/imap4d/auth_gsasl.c
+++ b/imap4d/auth_gsasl.c
@@ -95,7 +95,7 @@ auth_gsasl (struct imap4d_command *command, char *auth_type, char **username)
while ((rc = gsasl_step64 (sess_ctx, input_str, &output))
== GSASL_NEEDS_MORE)
{
- util_send ("+ %s\r\n", output);
+ util_send ("+ %s\n", output);
imap4d_getline (&input_str, &input_size, &input_len);
}
@@ -112,7 +112,7 @@ auth_gsasl (struct imap4d_command *command, char *auth_type, char **username)
returned, and clients must respond with an empty response. */
if (output[0])
{
- util_send ("+ %s\r\n", output);
+ util_send ("+ %s\n", output);
imap4d_getline (&input_str, &input_size, &input_len);
if (input_len != 0)
{
diff --git a/imap4d/auth_gss.c b/imap4d/auth_gss.c
index e85c25897..1a7fd9548 100644
--- a/imap4d/auth_gss.c
+++ b/imap4d/auth_gss.c
@@ -163,7 +163,7 @@ auth_gssapi (struct imap4d_command *command,
/* Start the dialogue */
- util_send ("+ \r\n");
+ util_send ("+ \n");
util_flush_output ();
context = GSS_C_NO_CONTEXT;
@@ -192,7 +192,7 @@ auth_gssapi (struct imap4d_command *command,
if (outbuf.length)
{
mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size);
- util_send ("+ %s\r\n", tmp);
+ util_send ("+ %s\n", tmp);
free (tmp);
gss_release_buffer (&min_stat, &outbuf);
}
@@ -212,7 +212,7 @@ auth_gssapi (struct imap4d_command *command,
if (outbuf.length)
{
mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size);
- util_send ("+ %s\r\n", tmp);
+ util_send ("+ %s\n", tmp);
free (tmp);
gss_release_buffer (&min_stat, &outbuf);
imap4d_getline (&token_str, &token_size, &token_len);
@@ -232,7 +232,7 @@ auth_gssapi (struct imap4d_command *command,
}
mu_base64_encode (outbuf.value, outbuf.length, &tmp, &size);
- util_send ("+ %s\r\n", tmp);
+ util_send ("+ %s\n", tmp);
free (tmp);
imap4d_getline (&token_str, &token_size, &token_len);
diff --git a/imap4d/capability.c b/imap4d/capability.c
index c88bc60c3..b52d92696 100644
--- a/imap4d/capability.c
+++ b/imap4d/capability.c
@@ -80,7 +80,7 @@ imap4d_capability (struct imap4d_command *command, imap4d_tokbuf_t tok)
mu_list_do (capa_list, print_capa, NULL);
imap4d_auth_capability ();
- util_send ("\r\n");
+ util_send ("\n");
return util_finish (command, RESP_OK, "Completed");
}
diff --git a/imap4d/close.c b/imap4d/close.c
index 732e8499d..e730268c9 100644
--- a/imap4d/close.c
+++ b/imap4d/close.c
@@ -30,7 +30,7 @@ imap4d_close0 (struct imap4d_command *command, imap4d_tokbuf_t tok,
return util_finish (command, RESP_BAD, "Invalid arguments");
mu_mailbox_get_flags (mbox, &flags);
- if ((flags & MU_STREAM_READ) == 0)
+ if (flags & MU_STREAM_WRITE)
{
status = mu_mailbox_flush (mbox, expunge);
if (status)
diff --git a/imap4d/copy.c b/imap4d/copy.c
index b25e1ee30..7f9acad08 100644
--- a/imap4d/copy.c
+++ b/imap4d/copy.c
@@ -52,7 +52,7 @@ imap4d_copy (struct imap4d_command *command, imap4d_tokbuf_t tok)
int new_state = (rc == RESP_OK) ? command->success : command->failure;
if (new_state != STATE_NONE)
state = new_state;
- return util_send ("%s %s\r\n", command->tag, text);
+ return util_send ("%s %s\n", command->tag, text);
}
return util_finish (command, rc, "%s", text);
}
diff --git a/imap4d/fetch.c b/imap4d/fetch.c
index a36a097bd..ef8ae9a51 100644
--- a/imap4d/fetch.c
+++ b/imap4d/fetch.c
@@ -689,39 +689,36 @@ static int
fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max)
{
mu_stream_t rfc = NULL;
+
size_t n = 0;
mu_filter_create (&rfc, stream, "rfc822", MU_FILTER_ENCODE,
- MU_STREAM_READ|MU_STREAM_NO_CHECK|MU_STREAM_NO_CLOSE);
-
+ MU_STREAM_READ|MU_STREAM_SEEK|MU_STREAM_NO_CLOSE);
+
if (start == 0 && size == (size_t) -1)
{
- char *buffer;
- size_t bufsize;
int rc;
- for (bufsize = max; (buffer = malloc (bufsize)) == NULL; bufsize /= 2)
- if (bufsize < 512)
- imap4d_bye (ERR_NO_MEM);
-
rc = mu_stream_seek (rfc, 0, MU_SEEK_SET, NULL);
if (rc)
{
- mu_error ("seek error: %s", mu_stream_strerror (rfc, rc));
+ mu_error ("seek error: %s", mu_stream_strerror (stream, rc));
return RESP_BAD;
}
if (max)
{
- util_send (" {%lu}\r\n", (unsigned long) max);
- while (mu_stream_read (rfc, buffer, bufsize, &n) == 0 && n > 0)
- util_send_bytes (buffer, n);
-
+ util_send (" {%lu}\n", (unsigned long) max);
+ util_copy_out (rfc, max);
/* FIXME: Make sure exactly max bytes were sent */
- free (buffer);
}
else
util_send (" \"\"");
}
+ else if (start > max)
+ {
+ util_send ("<%lu>", (unsigned long) start);
+ util_send (" \"\"");
+ }
else if (size + 2 < size) /* Check for integer overflow */
{
mu_stream_destroy (&rfc);
@@ -737,16 +734,17 @@ fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max)
if (!p)
imap4d_bye (ERR_NO_MEM);
- rc = mu_stream_seek (stream, start, MU_SEEK_SET, NULL);
+ rc = mu_stream_seek (rfc, start, MU_SEEK_SET, NULL);
if (rc)
{
mu_error ("seek error: %s", mu_stream_strerror (rfc, rc));
free (buffer);
+ mu_stream_destroy (&rfc);
return RESP_BAD;
}
while (total < size
- && mu_stream_read (rfc, p, size - total + 1, &n) == 0
+ && mu_stream_read (rfc, p, size - total, &n) == 0
&& n > 0)
{
total += n;
@@ -756,7 +754,7 @@ fetch_io (mu_stream_t stream, size_t start, size_t size, size_t max)
util_send ("<%lu>", (unsigned long) start);
if (total)
{
- util_send (" {%lu}\r\n", (unsigned long) total);
+ util_send (" {%lu}\n", (unsigned long) total);
util_send_bytes (buffer, total);
}
else
@@ -1085,6 +1083,7 @@ _frt_header_fields (struct fetch_function_closure *ffc,
/* Output collected data */
mu_stream_size (stream, &size);
+ mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
status = fetch_io (stream, ffc->start, ffc->size, size + lines);
mu_stream_destroy (&stream);
@@ -1657,7 +1656,7 @@ imap4d_fetch0 (imap4d_tokbuf_t tok, int isuid, char **err_text)
util_send ("* %lu FETCH (", (unsigned long) frc.msgno);
frc.eltno = 0;
rc = mu_list_do (pclos.fnlist, _do_fetch, &frc);
- util_send (")\r\n");
+ util_send (")\n");
}
}
}
@@ -1693,4 +1692,3 @@ imap4d_fetch (struct imap4d_command *command, imap4d_tokbuf_t tok)
rc = imap4d_fetch0 (tok, 0, &err_text);
return util_finish (command, rc, "%s", err_text);
}
-
diff --git a/imap4d/id.c b/imap4d/id.c
index f8c261cc4..353d3fe81 100644
--- a/imap4d/id.c
+++ b/imap4d/id.c
@@ -202,7 +202,7 @@ imap4d_id (struct imap4d_command *command, imap4d_tokbuf_t tok)
}
mu_iterator_destroy (&itr);
if (outcnt)
- util_send (")\r\n");
+ util_send (")\n");
}
return util_finish (command, RESP_OK, "Completed");
}
diff --git a/imap4d/idle.c b/imap4d/idle.c
index e3ddd6cdc..e8e7b8cdb 100644
--- a/imap4d/idle.c
+++ b/imap4d/idle.c
@@ -32,7 +32,7 @@ imap4d_idle (struct imap4d_command *command, imap4d_tokbuf_t tok)
if (util_wait_input (0) == -1)
return util_finish (command, RESP_NO, "Cannot idle");
- util_send ("+ idling\r\n");
+ util_send ("+ idling\n");
util_flush_output ();
start = time (NULL);
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index 1d9378d20..6a01e464e 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -202,7 +202,7 @@ extern int imap4d_transcript;
extern mu_list_t imap4d_id_list;
extern int imap4d_argc;
extern char **imap4d_argv;
-
+
#ifndef HAVE_STRTOK_R
extern char *strtok_r (char *s, const char *delim, char **save_ptr);
#endif
@@ -334,6 +334,8 @@ extern int util_send (const char *, ...) MU_PRINTFLIKE(1,2);
extern int util_send_bytes (const char *buf, size_t size);
extern int util_send_qstring (const char *);
extern int util_send_literal (const char *);
+extern int util_copy_out (mu_stream_t str, size_t size);
+
extern int util_start (char *);
extern int util_finish (struct imap4d_command *, int, const char *, ...)
MU_PRINTFLIKE(3,4);
diff --git a/imap4d/list.c b/imap4d/list.c
index 7ee42bea4..c7f42e4f9 100644
--- a/imap4d/list.c
+++ b/imap4d/list.c
@@ -97,11 +97,11 @@ list_fun (mu_folder_t folder, struct mu_list_response *resp, void *data)
name = refinfo->buf;
if (strpbrk (name, "\"{}"))
- util_send ("{%lu}\r\n%s\r\n", (unsigned long) strlen (name), name);
+ util_send ("{%lu}\n%s\n", (unsigned long) strlen (name), name);
else if (is_atom (name))
- util_send ("%s\r\n", name);
+ util_send ("%s\n", name);
else
- util_send ("\"%s\"\r\n", name);
+ util_send ("\"%s\"\n", name);
return 0;
}
diff --git a/imap4d/namespace.c b/imap4d/namespace.c
index abe21cdc9..5fd140868 100644
--- a/imap4d/namespace.c
+++ b/imap4d/namespace.c
@@ -126,7 +126,7 @@ imap4d_namespace (struct imap4d_command *command, imap4d_tokbuf_t tok)
print_namespace (NS_OTHER);
util_send (" ");
print_namespace (NS_SHARED);
- util_send ("\r\n");
+ util_send ("\n");
return util_finish (command, RESP_OK, "Completed");
}
diff --git a/imap4d/preauth.c b/imap4d/preauth.c
index 316828628..d26efc86a 100644
--- a/imap4d/preauth.c
+++ b/imap4d/preauth.c
@@ -366,7 +366,7 @@ do_preauth_ident (struct sockaddr *clt_sa, struct sockaddr *srv_sa)
return NULL;
}
- mu_stream_printf (stream, "%u , %u\r\n",
+ mu_stream_printf (stream, "%u , %u\n",
ntohs (clt_addr->sin_port),
ntohs (srv_addr->sin_port));
mu_stream_shutdown (stream, MU_STREAM_WRITE);
diff --git a/imap4d/search.c b/imap4d/search.c
index 33d2aa222..1163ce941 100644
--- a/imap4d/search.c
+++ b/imap4d/search.c
@@ -363,7 +363,7 @@ do_search (struct parsebuf *pb)
util_send (" %s", mu_umaxtostr (0, pb->msgno));
}
}
- util_send ("\r\n");
+ util_send ("\n");
}
/* Parse buffer functions */
diff --git a/imap4d/select.c b/imap4d/select.c
index dcf3fe043..2e2142b2d 100644
--- a/imap4d/select.c
+++ b/imap4d/select.c
@@ -74,9 +74,9 @@ imap4d_select0 (struct imap4d_command *command, const char *mboxname,
{
free (mailbox_name);
/* Need to set the state explicitely for select. */
- return util_send ("%s OK [%s] %s Completed\r\n", command->tag,
- (flags & MU_STREAM_READ) ?
- "READ-ONLY" : "READ-WRITE", command->name);
+ return util_send ("%s OK [%s] %s Completed\n", command->tag,
+ ((flags & MU_STREAM_RDWR) == MU_STREAM_RDWR) ?
+ "READ-WRITE" : "READ-ONLY", command->name);
}
}
@@ -119,7 +119,7 @@ imap4d_select_status ()
/* FIXME:
- '\*' can be supported if we use the attribute_set userflag()
- Answered is still not set in the mailbox code. */
- if (select_flags & MU_STREAM_READ)
+ if (!(select_flags & MU_STREAM_WRITE))
util_out (RESP_OK, "[PERMANENTFLAGS ()] No Permanent flags");
else
util_out (RESP_OK, "[PERMANENTFLAGS (%s)] Permanent flags", pflags);
diff --git a/imap4d/status.c b/imap4d/status.c
index 3933a7956..3622c4700 100644
--- a/imap4d/status.c
+++ b/imap4d/status.c
@@ -136,7 +136,7 @@ imap4d_status (struct imap4d_command *command, imap4d_tokbuf_t tok)
if (count > 0)
- util_send (")\r\n");
+ util_send (")\n");
mu_mailbox_close (smbox);
}
mu_mailbox_destroy (&smbox);
diff --git a/imap4d/store.c b/imap4d/store.c
index ac06bdc80..c043a3ece 100644
--- a/imap4d/store.c
+++ b/imap4d/store.c
@@ -157,7 +157,7 @@ imap4d_store0 (imap4d_tokbuf_t tok, int isuid, char **ptext)
util_send ("UID %lu ", (unsigned long) msgno);
util_send ("FLAGS (");
util_print_flags (attr);
- util_send ("))\r\n");
+ util_send ("))\n");
}
/* Update the flags of uid table. */
imap4d_sync_flags (pclos.set[i]);
diff --git a/imap4d/util.c b/imap4d/util.c
index 848716185..26a1a8db3 100644
--- a/imap4d/util.c
+++ b/imap4d/util.c
@@ -270,6 +270,12 @@ util_msgset (char *s, size_t ** set, int *n, int isuid)
}
int
+util_copy_out (mu_stream_t str, size_t size)
+{
+ return mu_stream_copy (ostream, str, size);
+}
+
+int
util_send_bytes (const char *buf, size_t size)
{
return mu_stream_write (ostream, buf, size, NULL);
@@ -325,7 +331,7 @@ util_send_qstring (const char *buffer)
int
util_send_literal (const char *buffer)
{
- return util_send ("{%lu}\r\n%s", (unsigned long) strlen (buffer), buffer);
+ return util_send ("{%lu}\n%s", (unsigned long) strlen (buffer), buffer);
}
/* Send an unsolicited response. */
@@ -337,7 +343,7 @@ util_out (int rc, const char *format, ...)
int status = 0;
va_list ap;
- asprintf (&tempbuf, "* %s%s\r\n", sc2string (rc), format);
+ asprintf (&tempbuf, "* %s%s\n", sc2string (rc), format);
va_start (ap, format);
vasprintf (&buf, tempbuf, ap);
va_end (ap);
@@ -346,7 +352,7 @@ util_out (int rc, const char *format, ...)
if (imap4d_transcript)
{
- int len = strcspn (buf, "\r\n");
+ int len = strcspn (buf, "\n");
mu_diag_output (MU_DIAG_DEBUG, "sent: %*.*s", len, len, buf);
}
@@ -393,7 +399,7 @@ util_finish (struct imap4d_command *command, int rc, const char *format, ...)
mu_stream_write (ostream, buf, strlen (buf), NULL);
free (buf);
- mu_stream_write (ostream, "\r\n", 2, NULL);
+ mu_stream_write (ostream, "\n", 2, NULL);
/* Reset the state. */
if (rc == RESP_OK)
@@ -800,16 +806,24 @@ util_uidvalidity (mu_mailbox_t smbox, unsigned long *uidvp)
void
util_setio (FILE *in, FILE *out)
{
+ mu_stream_t tmp;
+
if (!in)
imap4d_bye (ERR_NO_IFILE);
if (!out)
imap4d_bye (ERR_NO_OFILE);
- if (mu_stdio_stream_create (&istream, fileno (in), MU_STREAM_NO_CLOSE))
+ if (mu_stdio_stream_create (&tmp, fileno (in), MU_STREAM_NO_CLOSE))
imap4d_bye (ERR_NO_IFILE);
- if (mu_stdio_stream_create (&ostream, fileno (out), MU_STREAM_NO_CLOSE))
- imap4d_bye (ERR_NO_OFILE);
+ mu_stream_set_buffer (tmp, mu_buffer_line, 1024);
+ mu_filter_create (&istream, tmp, "rfc822", MU_FILTER_DECODE, MU_STREAM_READ);
mu_stream_set_buffer (istream, mu_buffer_line, 1024);
+
+ if (mu_stdio_stream_create (&tmp, fileno (out), MU_STREAM_NO_CLOSE))
+ imap4d_bye (ERR_NO_OFILE);
+ mu_stream_set_buffer (tmp, mu_buffer_line, 1024);
+ mu_filter_create (&ostream, tmp, "rfc822", MU_FILTER_ENCODE,
+ MU_STREAM_WRITE);
mu_stream_set_buffer (ostream, mu_buffer_line, 1024);
}
@@ -917,7 +931,7 @@ void
util_bye ()
{
int rc = istream != ostream;
-
+
mu_stream_close (istream);
mu_stream_destroy (&istream);
@@ -926,7 +940,6 @@ util_bye ()
mu_stream_close (ostream);
mu_stream_destroy (&ostream);
}
-
mu_list_do (atexit_list, atexit_run, 0);
}
@@ -1021,30 +1034,6 @@ is_atom (const char *s)
static size_t
-remove_cr (char *line, size_t len)
-{
- char *prev = NULL;
- size_t rlen = len;
- char *p;
- while ((p = memchr (line, '\r', len)))
- {
- if (prev)
- {
- memmove (prev, line, p - line);
- prev += p - line;
- }
- else
- prev = p;
- rlen--;
- len -= p - line + 1;
- line = p + 1;
- }
- if (prev)
- memmove (prev, line, len);
- return rlen;
-}
-
-static size_t
unquote (char *line, size_t len)
{
char *prev = NULL;
@@ -1318,7 +1307,7 @@ imap4d_readline (struct imap4d_tokbuf *tok)
/* Client can ask for non-synchronised literal,
if a '+' is appended to the octet count. */
if (*sp == '}')
- util_send ("+ GO AHEAD\r\n");
+ util_send ("+ GO AHEAD\n");
else if (*sp != '+')
break;
imap4d_tokbuf_expand (tok, number + 1);
@@ -1334,7 +1323,6 @@ imap4d_readline (struct imap4d_tokbuf *tok)
len += sz;
}
check_input_err (rc, len);
- len = remove_cr (buf, len);
imap4d_tokbuf_unquote (tok, &off, &len);
tok->level += len;
tok->buffer[tok->level++] = 0;

Return to:

Send suggestions and report system problems to the System administrator.