Commit d685b048 d685b04800dd59ede5b854f61aaeea8c565d243b by Alain Magloire

Implemented most of the pop3d functions, technically we have

pop server base on the new API, but .. needs more testing.
The new mailbox is not tested/mature enough for wide deployment.
message_get_uidl:  checks for X-UIDL to be compatible with qpopper
and fall back to Message-ID, we need some sort of checksum or
modify the header like the qpopper.
1 parent 7096a7d8
......@@ -26,6 +26,7 @@
#include <sys/stat.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
/* FIXME: This should be part of the address_t object when implemented. */
static int extract_addr(const char *s, size_t n, char **presult,
......@@ -408,18 +409,40 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner)
}
int
message_get_uidl (message_t msg, char *buffer, size_t buflen, size_t *pwritten)
message_get_uidl (message_t msg, char *buffer, size_t buflen, size_t *pwriten)
{
header_t header = NULL;
size_t n = 0;
int status;
if (msg == NULL || buffer == NULL || buflen == 0)
return EINVAL;
buffer[0] = '0';
if (msg->_get_uidl)
return msg->_get_uidl (msg, buffer, buflen, pwritten);
return msg->_get_uidl (msg, buffer, buflen, pwriten);
/* Be compatible with Qpopper ? qppoper saves the UIDL in "X-UIDL".
We use "Message-ID" as a fallback. Is this bad ? should we generate
a chksum or do the same as Qpopper save it in the header. */
message_get_header (msg, &header);
return header_get_value (header, "X-UIDL", buffer, buflen, pwritten);
if ((status = header_get_value (header, "X-UIDL", buffer, buflen, &n)) == 0
|| (status = header_get_value (header, "Message-ID", buffer,
buflen, &n)) == 0)
{
/* We need to collapse the header if it was mutiline. */
/* FIXME: Is header_get_value suppose to do this ? */
char *s, *e;
for (s = buffer, e = buffer + n; s <= e; s++)
{
if (isspace (*s))
memmove (s, s + 1, e - s);
}
return 0;
}
if (pwriten)
*pwriten = n;
return status;
}
int
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -175,7 +175,7 @@ pop3_apop (const char *arg)
state = AUTHORIZATION;
return ERR_UNKNOWN;
}
else if (mailbox_open (mbox, 0) != 0)
else if (mailbox_open (mbox, MU_STREAM_RDWR) != 0)
{
free (username);
state = AUTHORIZATION;
......@@ -188,4 +188,3 @@ pop3_apop (const char *arg)
syslog (LOG_INFO, "User %s logged in with mailbox %s", username, NULL);
return OK;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -23,6 +23,8 @@ int
pop3_dele (const char *arg)
{
int num = 0;
message_t msg;
attribute_t attr;
if ((arg == NULL) || (strchr (arg, ' ') != NULL))
return ERR_BAD_ARGS;
......@@ -31,9 +33,12 @@ pop3_dele (const char *arg)
return ERR_WRONG_STATE;
num = atoi (arg);
if (/* FIXME: mailbox_delete (mbox, num) != */ 0)
if (mailbox_get_message (mbox, num, &msg) != 0)
return ERR_NO_MESG;
message_get_attribute (msg, &attr);
attribute_set_deleted (attr);
fprintf (ofile, "+OK Message %d marked\r\n", num);
return OK;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -22,8 +22,10 @@
int
pop3_list (const char *arg)
{
unsigned int mesg = 0, size = 0;
size_t mesgno;
size_t size = 0;
message_t msg;
attribute_t attr;
if (state != TRANSACTION)
return ERR_WRONG_STATE;
......@@ -35,27 +37,31 @@ pop3_list (const char *arg)
if (strlen (arg) == 0)
{
unsigned int total;
mailbox_messages_count (mbox, &total);
size_t total = 0;
fprintf (ofile, "+OK\r\n");
for (mesg = 1; mesg <= total; mesg++)
mailbox_messages_count (mbox, &total);
for (mesgno = 1; mesgno <= total; mesgno++)
{
mailbox_get_message (mbox, mesg, &msg);
if ( /* deleted == 0 */ 1)
mailbox_get_message (mbox, mesgno, &msg);
message_get_attribute (msg, &attr);
if (!attribute_is_deleted (attr))
{
message_size (msg, &size);
fprintf (ofile, "%d %d\r\n", mesg, size);
fprintf (ofile, "%d %d\r\n", mesgno, size);
}
}
fprintf (ofile, ".\r\n");
}
else
{
mesg = atoi (arg);
if (mailbox_get_message (mbox, mesg, &msg) != 0)
mesgno = atoi (arg);
if (mailbox_get_message (mbox, mesgno, &msg) != 0)
return ERR_NO_MESG;
message_get_attribute (msg, &attr);
if (attribute_is_deleted (attr))
return ERR_MESG_DELE;
message_size (msg, &size);
fprintf (ofile, "+OK %d %d\r\n", mesg, size);
fprintf (ofile, "+OK %d %d\r\n", mesgno, size);
}
return OK;
......
......@@ -260,6 +260,8 @@ pop3_mainloop (int infile, int outfile)
fprintf (ofile, "-ERR " BAD_ARGS "\r\n");
else if (status == ERR_NO_MESG)
fprintf (ofile, "-ERR " NO_MESG "\r\n");
else if (status == ERR_MESG_DELE)
fprintf (ofile, "-ERR " MESG_DELE "\r\n");
else if (status == ERR_NOT_IMPL)
fprintf (ofile, "-ERR " NOT_IMPL "\r\n");
else if (status == ERR_BAD_CMD)
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -39,6 +39,9 @@
/* An action on a message that doesn't exist */
#define NO_MESG "No such message"
/* An action on a message that doesn't exist */
#define MESG_DELE "Message has been deleted"
/* A command that is known but not implemented */
#define NOT_IMPL "Not implemented"
......@@ -51,7 +54,7 @@
/* The command argument was > 40 characters */
#define TOO_LONG "Argument too long"
/* APOP password file, without .db or .passwd, which are added based on file
/* APOP password file, without .db or .passwd, which are added based on file
type automatically */
#define APOP_PASSFILE "/etc/apop"
......@@ -129,17 +132,18 @@
#define ERR_BAD_ARGS 2
#define ERR_BAD_LOGIN 3
#define ERR_NO_MESG 4
#define ERR_NOT_IMPL 5
#define ERR_BAD_CMD 6
#define ERR_MBOX_LOCK 7
#define ERR_TOO_LONG 8
#define ERR_NO_MEM 9
#define ERR_DEAD_SOCK 10
#define ERR_SIGNAL 11
#define ERR_FILE 12
#define ERR_NO_OFILE 13
#define ERR_TIMEOUT 14
#define ERR_UNKNOWN 15
#define ERR_MESG_DELE 5
#define ERR_NOT_IMPL 6
#define ERR_BAD_CMD 7
#define ERR_MBOX_LOCK 8
#define ERR_TOO_LONG 9
#define ERR_NO_MEM 10
#define ERR_DEAD_SOCK 11
#define ERR_SIGNAL 12
#define ERR_FILE 13
#define ERR_NO_OFILE 14
#define ERR_TIMEOUT 15
#define ERR_UNKNOWN 16
mailbox_t mbox;
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -42,7 +42,3 @@ pop3_quit (const char *arg)
fprintf (ofile, "+OK\r\n");
return OK;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -22,12 +22,12 @@
int
pop3_retr (const char *arg)
{
unsigned int mesg, size, read = 0;
size_t mesgno, n;
char buf[BUFFERSIZE];
message_t msg;
header_t hdr;
body_t body;
attribute_t attr;
stream_t stream;
off_t off;
if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL))
return ERR_BAD_ARGS;
......@@ -35,37 +35,32 @@ pop3_retr (const char *arg)
if (state != TRANSACTION)
return ERR_WRONG_STATE;
mesg = atoi (arg);
mesgno = atoi (arg);
if (mailbox_get_message (mbox, mesg, &msg) != 0)
if (mailbox_get_message (mbox, mesgno, &msg) != 0)
return ERR_NO_MESG;
message_get_header (msg, &hdr);
message_get_body (msg, &body);
message_get_attribute (msg, &attr);
if (attribute_is_deleted (attr))
return ERR_MESG_DELE;
/* Header */
message_get_stream (msg, &stream);
fprintf (ofile, "+OK\r\n");
header_get_stream (hdr, &stream);
header_size (hdr, &size);
while (read < size)
off = n = 0;
while (stream_readline (stream, buf, sizeof (buf) - 1, off, &n) == 0
&& n > 0)
{
stream_read (stream, buf, BUFFERSIZE, 0, NULL);
fprintf (ofile, "%s", buf);
read += BUFFERSIZE;
/* Nuke the trainline newline. */
if (buf[n - 1] == '\n')
buf[n - 1] = '\0';
if (buf[0] == '.')
fprintf (ofile, ".%s\r\n", buf);
else
fprintf (ofile, "%s\r\n", buf);
off += n;
}
/* body */
body_get_stream (body, &stream);
body_lines (body, &size);
while (read < size)
{
stream_read (stream, buf, BUFFERSIZE, 0, NULL);
fprintf (ofile, "%s", buf);
read += BUFFERSIZE;
}
fprintf (ofile, ".\r\n");
return OK;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -22,7 +22,8 @@
int
pop3_rset (const char *arg)
{
int i = 0, total = 0;
size_t i;
size_t total = 0;
if (strlen (arg) != 0)
return ERR_BAD_ARGS;
......@@ -33,8 +34,14 @@ pop3_rset (const char *arg)
mailbox_messages_count (mbox, &total);
for (i = 1; i <= total; i++)
/* FIXME: undelete message i */ ;
{
message_t msg;
attribute_t attr;
mailbox_get_message (mbox, i, &msg);
message_get_attribute (msg, &attr);
if (attribute_is_deleted (attr))
attribute_unset_deleted (attr);
}
fprintf (ofile, "+OK\r\n");
return OK;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -17,18 +17,21 @@
#include "pop3d.h"
/* Prints the header of a message plus a specified number of lines */
/* Prints the header of a message plus a specified number of lines. */
int
pop3_top (const char *arg)
{
int mesg, lines, size;
int mesg, lines;
message_t msg;
attribute_t attr;
header_t hdr;
body_t body;
stream_t stream;
char *mesgc, *linesc;
char *buf;
char buf[BUFFERSIZE];
size_t n;
off_t off;
if (strlen (arg) == 0)
return ERR_BAD_ARGS;
......@@ -49,25 +52,47 @@ pop3_top (const char *arg)
if (mailbox_get_message (mbox, mesg, &msg) != 0)
return ERR_NO_MESG;
message_get_header (msg, &hdr);
message_get_body (msg, &body);
message_get_attribute (msg, &attr);
if (attribute_is_deleted (attr))
return ERR_MESG_DELE;
fprintf (ofile, "+OK\r\n");
/* Header */
/* Header. */
message_get_header (msg, &hdr);
header_get_stream (hdr, &stream);
header_size (hdr, &size);
buf = malloc (size);
stream_read (stream, buf, size, 0, NULL);
fprintf (ofile, "+OK\r\n%s", buf);
free(buf);
/* lines lines of body */
body_get_stream (body, &stream);
body_lines (body, &size);
buf = malloc (size);
stream_read (stream, buf, size, 0, NULL); /* FIXME: read lines lines */
fprintf (ofile, "%s.\r\n", buf);
free (buf);
off = n = 0;
while (stream_readline (stream, buf, sizeof (buf) - 1, off, &n) == 0)
{
if (n == 0)
break;
/* Nuke the trainline newline. */
if (buf[n - 1] == '\n')
buf [n - 1] = '\0';
off += n;
fprintf (ofile, "%s\r\n", buf);
}
/* Lines of body. */
if (lines)
{
message_get_body (msg, &body);
body_get_stream (body, &stream);
for (n = off = 0; lines > 0; lines--, off += n)
{
int status = stream_readline (stream, buf, sizeof (buf), off, &n);
if (status != 0 || n == 0)
break;
/* Nuke the trainline newline. */
if (buf[n - 1] == '\n')
buf[n - 1] = '\0';
if (buf[0] == '.')
fprintf (ofile, ".%s\r\n", buf);
else
fprintf (ofile, "%s\r\n", buf);
}
}
fprintf (ofile, ".\r\n");
return OK;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -20,8 +20,45 @@
int
pop3_uidl (const char *arg)
{
size_t mesgno;
char uidl[128];
message_t msg;
attribute_t attr;
if (state != TRANSACTION)
return ERR_WRONG_STATE;
return ERR_NOT_IMPL;
if (strchr (arg, ' ') != NULL)
return ERR_BAD_ARGS;
if (strlen (arg) == 0)
{
size_t total = 0;
fprintf (ofile, "+OK\r\n");
mailbox_messages_count (mbox, &total);
for (mesgno = 1; mesgno <= total; mesgno++)
{
mailbox_get_message (mbox, mesgno, &msg);
message_get_attribute (msg, &attr);
if (!attribute_is_deleted (attr))
{
message_get_uidl (msg, uidl, sizeof (uidl), NULL);
fprintf (ofile, "%d %s\r\n", mesgno, uidl);
}
}
fprintf (ofile, ".\r\n");
}
else
{
mesgno = atoi (arg);
if (mailbox_get_message (mbox, mesgno, &msg) != 0)
return ERR_NO_MESG;
message_get_attribute (msg, &attr);
if (attribute_is_deleted (attr))
return ERR_MESG_DELE;
message_get_uidl (msg, uidl, sizeof (uidl), NULL);
fprintf (ofile, "+OK %d %s\r\n", mesgno, uidl);
}
return OK;
}
......