Commit cbc00871 cbc008712897959c17cde4b9afcb18925da267a7 by Sergey Poznyakoff

pop3d: cleanup

* pop3d/pop3d.h: Include filter.h.
(istream, ostream): New externs.
* pop3d/extra.c (pop3d_setio): Set a crlf filter on the
output stream. This allows to forget about \r in the rest of
the code.
* pop3d/retr.c (pop3d_retr): Use mu_stream_copy instead of
copying streams manually.
* pop3d/top.c (pop3d_top): Rewrite using streamrefs and
mu_stream_copy.
* all sources: Use \n instead of \r\n in output strings.
1 parent dca7b761
......@@ -35,30 +35,30 @@ pop3d_capa (char *arg)
if (state != initial_state && state != TRANSACTION)
return ERR_WRONG_STATE;
pop3d_outf ("+OK Capability list follows\r\n");
pop3d_outf ("TOP\r\n");
pop3d_outf ("USER\r\n");
pop3d_outf ("UIDL\r\n");
pop3d_outf ("RESP-CODES\r\n");
pop3d_outf ("PIPELINING\r\n");
pop3d_outf ("+OK Capability list follows\n");
pop3d_outf ("TOP\n");
pop3d_outf ("USER\n");
pop3d_outf ("UIDL\n");
pop3d_outf ("RESP-CODES\n");
pop3d_outf ("PIPELINING\n");
#ifdef WITH_TLS
if (tls_available && tls_done == 0)
pop3d_outf ("STLS\r\n");
pop3d_outf ("STLS\n");
#endif /* WITH_TLS */
login_delay_capa ();
/* This can be implemented by setting an header field on the message. */
if (expire == EXPIRE_NEVER)
pop3d_outf ("EXPIRE NEVER\r\n");
pop3d_outf ("EXPIRE NEVER\n");
else
pop3d_outf ("EXPIRE %s\r\n", mu_umaxtostr (0, expire));
pop3d_outf ("EXPIRE %s\n", mu_umaxtostr (0, expire));
if (state == INITIAL)
pop3d_outf ("XTLSREQUIRED\r\n");
pop3d_outf ("XTLSREQUIRED\n");
if (state == TRANSACTION) /* let's not advertise to just anyone */
pop3d_outf ("IMPLEMENTATION %s\r\n", PACKAGE_STRING);
pop3d_outf (".\r\n");
pop3d_outf ("IMPLEMENTATION %s\n", PACKAGE_STRING);
pop3d_outf (".\n");
return OK;
}
......
......@@ -39,6 +39,6 @@ pop3d_dele (char *arg)
mu_message_get_attribute (msg, &attr);
pop3d_mark_deleted (attr);
pop3d_outf ("+OK Message %s marked\r\n", mu_umaxtostr (0, num));
pop3d_outf ("+OK Message %s marked\n", mu_umaxtostr (0, num));
return OK;
}
......
......@@ -20,7 +20,7 @@
#include "pop3d.h"
#include "mailutils/libargp.h"
static mu_stream_t istream, ostream;
mu_stream_t istream, ostream;
void
pop3d_parse_command (char *cmd, char **pcmd, char **parg)
......@@ -61,7 +61,7 @@ pop3d_abquit (int reason)
{
case ERR_NO_MEM:
code = EX_SOFTWARE;
pop3d_outf ("-ERR %s\r\n", pop3d_error_string (reason));
pop3d_outf ("-ERR %s\n", pop3d_error_string (reason));
mu_diag_output (MU_DIAG_ERROR, _("not enough memory"));
break;
......@@ -77,7 +77,7 @@ pop3d_abquit (int reason)
case ERR_TIMEOUT:
code = EX_TEMPFAIL;
pop3d_outf ("-ERR %s\r\n", pop3d_error_string (reason));
pop3d_outf ("-ERR %s\n", pop3d_error_string (reason));
if (state == TRANSACTION)
mu_diag_output (MU_DIAG_INFO, _("session timed out for user: %s"),
username);
......@@ -111,12 +111,12 @@ pop3d_abquit (int reason)
_("mailbox was updated by other party: %s"),
username);
pop3d_outf
("-ERR [OUT-SYNC] Mailbox updated by other party or corrupt\r\n");
("-ERR [OUT-SYNC] Mailbox updated by other party or corrupt\n");
break;
default:
code = EX_SOFTWARE;
pop3d_outf ("-ERR Quitting: %s\r\n", pop3d_error_string (reason));
pop3d_outf ("-ERR Quitting: %s\n", pop3d_error_string (reason));
mu_diag_output (MU_DIAG_ERROR, _("quitting (numeric reason %d)"),
reason);
break;
......@@ -129,6 +129,8 @@ pop3d_abquit (int reason)
void
pop3d_setio (FILE *in, FILE *out)
{
mu_stream_t str;
if (!in)
pop3d_abquit (ERR_NO_IFILE);
if (!out)
......@@ -136,9 +138,13 @@ pop3d_setio (FILE *in, FILE *out)
if (mu_stdio_stream_create (&istream, fileno (in), MU_STREAM_NO_CLOSE))
pop3d_abquit (ERR_NO_IFILE);
if (mu_stdio_stream_create (&ostream, fileno (out), MU_STREAM_NO_CLOSE))
pop3d_abquit (ERR_NO_OFILE);
mu_stream_set_buffer (istream, mu_buffer_line, 1024);
if (mu_stdio_stream_create (&str, fileno (out), MU_STREAM_NO_CLOSE))
pop3d_abquit (ERR_NO_OFILE);
if (mu_filter_create (&ostream, str, "rfc822", MU_FILTER_ENCODE,
MU_STREAM_WRITE|MU_STREAM_NO_CLOSE))
pop3d_abquit (ERR_NO_IFILE);
mu_stream_set_buffer (ostream, mu_buffer_line, 1024);
}
......
......@@ -37,7 +37,7 @@ pop3d_list (char *arg)
if (strlen (arg) == 0)
{
size_t total = 0;
pop3d_outf ("+OK\r\n");
pop3d_outf ("+OK\n");
mu_mailbox_messages_count (mbox, &total);
for (mesgno = 1; mesgno <= total; mesgno++)
{
......@@ -47,12 +47,12 @@ pop3d_list (char *arg)
{
mu_message_size (msg, &size);
mu_message_lines (msg, &lines);
pop3d_outf ("%s %s\r\n",
pop3d_outf ("%s %s\n",
mu_umaxtostr (0, mesgno),
mu_umaxtostr (1, size + lines));
}
}
pop3d_outf (".\r\n");
pop3d_outf (".\n");
}
else
{
......@@ -64,7 +64,7 @@ pop3d_list (char *arg)
return ERR_MESG_DELE;
mu_message_size (msg, &size);
mu_message_lines (msg, &lines);
pop3d_outf ("+OK %s %s\r\n",
pop3d_outf ("+OK %s %s\n",
mu_umaxtostr (0, mesgno),
mu_umaxtostr (1, size + lines));
}
......
......@@ -126,7 +126,7 @@ login_delay_capa ()
if (login_delay && open_stat_db (&db, MU_STREAM_RDWR) == 0)
{
pop3d_outf ("LOGIN-DELAY %s\r\n", mu_umaxtostr (0, login_delay));
pop3d_outf ("LOGIN-DELAY %s\n", mu_umaxtostr (0, login_delay));
mu_dbm_close (db);
}
}
......
......@@ -26,6 +26,6 @@ pop3d_noop (char *arg)
return ERR_BAD_ARGS;
if (state != TRANSACTION)
return ERR_WRONG_STATE;
pop3d_outf ("+OK\r\n");
pop3d_outf ("+OK\n");
return OK;
}
......
......@@ -248,7 +248,7 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile)
}
/* Lets boogie. */
pop3d_outf ("+OK POP3 Ready %s\r\n", md5shared);
pop3d_outf ("+OK POP3 Ready %s\n", md5shared);
while (state != UPDATE && state != ABORT)
{
......@@ -291,7 +291,7 @@ pop3d_mainloop (int fd, FILE *infile, FILE *outfile)
status = ERR_BAD_CMD;
if (status != OK)
pop3d_outf ("-ERR %s\r\n", pop3d_error_string (status));
pop3d_outf ("-ERR %s\n", pop3d_error_string (status));
}
pop3d_bye ();
......
......@@ -125,6 +125,7 @@ extern int expire_on_exit;
#include <mailutils/md5.h>
#include <mailutils/acl.h>
#include <mailutils/server.h>
#include <mailutils/filter.h>
/* For Berkley DB2 APOP password file */
#ifdef HAVE_DB_H
......@@ -188,6 +189,7 @@ struct pop3d_command
pop3d_command_handler_t handler;
};
extern mu_stream_t istream, ostream;
extern mu_pop_server_t pop3srv;
extern mu_mailbox_t mbox;
extern int state;
......
......@@ -53,7 +53,7 @@ pop3d_quit (char *arg)
free (md5shared);
if (err == OK)
pop3d_outf ("+OK\r\n");
pop3d_outf ("+OK\n");
return err;
}
......
......@@ -22,12 +22,10 @@
int
pop3d_retr (char *arg)
{
size_t mesgno, n;
char buf[BUFFERSIZE];
size_t mesgno;
mu_message_t msg = NULL;
mu_attribute_t attr = NULL;
mu_stream_t stream = NULL;
int prev_nl;
mu_stream_t stream;
if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL))
return ERR_BAD_ARGS;
......@@ -44,42 +42,19 @@ pop3d_retr (char *arg)
if (pop3d_is_deleted (attr))
return ERR_MESG_DELE;
/* FIXME: Use crlf filter + mu_stream_copy instead of the loop below */
if (mu_message_get_stream (msg, &stream)
|| mu_stream_seek (stream, 0, MU_SEEK_SET, NULL))
if (mu_message_get_streamref (msg, &stream))
return ERR_UNKNOWN;
pop3d_outf ("+OK\r\n");
prev_nl = 1;
while (mu_stream_readline (stream, buf, sizeof(buf), &n) == 0
&& n > 0)
{
if (prev_nl && buf[0] == '.')
pop3d_outf (".");
if (buf[n - 1] == '\n')
{
buf[n - 1] = '\0';
pop3d_outf ("%s\r\n", buf);
prev_nl = 1;
}
else
{
pop3d_outf ("%s", buf);
prev_nl = 0;
}
}
if (!prev_nl)
pop3d_outf ("\r\n");
pop3d_outf ("+OK\n");
mu_stream_copy (ostream, stream, 0);
mu_stream_destroy (&stream);
if (!mu_attribute_is_read (attr))
mu_attribute_set_read (attr);
pop3d_mark_retr (attr);
pop3d_outf (".\r\n");
pop3d_outf (".\n");
return OK;
}
......
......@@ -41,6 +41,6 @@ pop3d_rset (char *arg)
mu_message_get_attribute (msg, &attr);
pop3d_unset_deleted (attr);
}
pop3d_outf ("+OK\r\n");
pop3d_outf ("+OK\n");
return OK;
}
......
......@@ -57,7 +57,7 @@ pop3d_stat (char *arg)
num++;
}
}
pop3d_outf ("+OK %s %s\r\n", mu_umaxtostr (0, num), mu_umaxtostr (1, tsize));
pop3d_outf ("+OK %s %s\n", mu_umaxtostr (0, num), mu_umaxtostr (1, tsize));
return OK;
}
......
......@@ -32,7 +32,7 @@ pop3d_stls (char *arg)
if (tls_done)
return ERR_TLS_ACTIVE;
pop3d_outf ("+OK Begin TLS negotiation\r\n");
pop3d_outf ("+OK Begin TLS negotiation\n");
pop3d_flush_output ();
tls_done = pop3d_init_tls_server ();
......
......@@ -23,15 +23,13 @@ int
pop3d_top (char *arg)
{
size_t mesgno;
int lines;
unsigned long lines;
mu_message_t msg;
mu_attribute_t attr;
mu_header_t hdr;
mu_body_t body;
mu_stream_t stream;
char *mesgc, *linesc;
char buf[BUFFERSIZE];
size_t n;
char *mesgc, *linesc, *p;
if (strlen (arg) == 0)
return ERR_BAD_ARGS;
......@@ -40,11 +38,14 @@ pop3d_top (char *arg)
return ERR_WRONG_STATE;
pop3d_parse_command (arg, &mesgc, &linesc);
if (linesc[0] == 0)
return ERR_BAD_ARGS;
mesgno = strtoul (mesgc, NULL, 10);
lines = *linesc ? strtol (linesc, NULL, 10) : -1;
if (lines < 0)
mesgno = strtoul (mesgc, &p, 10);
if (*p)
return ERR_BAD_ARGS;
lines = strtoul (linesc, &p, 10);
if (*p)
return ERR_BAD_ARGS;
if (mu_mailbox_get_message (mbox, mesgno, &msg) != 0)
......@@ -55,63 +56,34 @@ pop3d_top (char *arg)
return ERR_MESG_DELE;
pop3d_mark_retr (attr);
pop3d_outf ("+OK\r\n");
/* Header. */
mu_message_get_header (msg, &hdr);
/* FIXME: Use crlf filter + mu_stream_copy instead of the below loop */
if (mu_header_get_stream (hdr, &stream)
|| mu_stream_seek (stream, 0, MU_SEEK_SET, NULL))
if (mu_header_get_streamref (hdr, &stream))
return ERR_UNKNOWN;
n = 0;
while (mu_stream_readline (stream, buf, sizeof(buf), &n) == 0
&& n > 0)
{
/* Nuke the trainline newline. */
if (buf[n - 1] == '\n')
{
buf[n - 1] = '\0';
pop3d_outf ("%s\r\n", buf);
}
else
pop3d_outf ("%s", buf);
}
pop3d_outf ("+OK\n");
/* Lines of body. */
if (lines)
{
int prev_nl = 1;
mu_stream_copy (ostream, stream, 0);
pop3d_outf ("\n");
mu_stream_destroy (&stream);
mu_message_get_body (msg, &body);
/* FIXME: Use the crlf filter + mu_stream_copy */
if (mu_body_get_stream (body, &stream)
|| mu_stream_seek (stream, 0, MU_SEEK_SET, NULL))
return ERR_UNKNOWN;
n = 0;
while (mu_stream_readline (stream, buf, sizeof(buf), &n) == 0
&& n > 0 && lines > 0)
{
if (prev_nl && buf[0] == '.')
pop3d_outf (".");
if (buf[n - 1] == '\n')
if (mu_body_get_streamref (body, &stream) == 0)
{
buf[n - 1] = '\0';
pop3d_outf ("%s\r\n", buf);
prev_nl = 1;
lines--;
}
else
char *buf = NULL;
size_t size = 0, n;
while (lines > 0 &&
mu_stream_getline (stream, &buf, &size, &n) == 0 &&
n > 0)
{
pop3d_outf ("%s", buf);
prev_nl = 0;
}
if (buf[0] == '.')
pop3d_outf (".");
pop3d_outf ("%s\n", buf);
}
if (!prev_nl)
pop3d_outf ("\r\n");
mu_stream_destroy (&stream);
free (buf);
}
pop3d_outf (".\r\n");
pop3d_outf (".\n");
return OK;
}
......
......@@ -34,7 +34,7 @@ pop3d_uidl (char *arg)
if (strlen (arg) == 0)
{
size_t total = 0;
pop3d_outf ("+OK\r\n");
pop3d_outf ("+OK\n");
mu_mailbox_messages_count (mbox, &total);
for (mesgno = 1; mesgno <= total; mesgno++)
{
......@@ -43,10 +43,10 @@ pop3d_uidl (char *arg)
if (!pop3d_is_deleted (attr))
{
mu_message_get_uidl (msg, uidl, sizeof (uidl), NULL);
pop3d_outf ("%s %s\r\n", mu_umaxtostr (0, mesgno), uidl);
pop3d_outf ("%s %s\n", mu_umaxtostr (0, mesgno), uidl);
}
}
pop3d_outf (".\r\n");
pop3d_outf (".\n");
}
else
{
......@@ -57,7 +57,7 @@ pop3d_uidl (char *arg)
if (pop3d_is_deleted (attr))
return ERR_MESG_DELE;
mu_message_get_uidl (msg, uidl, sizeof (uidl), NULL);
pop3d_outf ("+OK %s %s\r\n", mu_umaxtostr (0, mesgno), uidl);
pop3d_outf ("+OK %s %s\n", mu_umaxtostr (0, mesgno), uidl);
}
return OK;
......
......@@ -63,7 +63,7 @@ pop3d_begin_session ()
pop3d_abquit (ERR_NO_MEM);
state = TRANSACTION;
pop3d_outf ("+OK opened mailbox for %s\r\n", username);
pop3d_outf ("+OK opened mailbox for %s\n", username);
if (undelete_on_startup)
pop3d_undelete_all ();
......@@ -98,7 +98,7 @@ pop3d_user (char *arg)
if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL))
return ERR_BAD_ARGS;
pop3d_outf ("+OK\r\n");
pop3d_outf ("+OK\n");
pop3d_flush_output ();
buf = pop3d_readline (buffer, sizeof (buffer));
......