summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlain Magloire <alainm@gnu.org>2001-05-02 04:45:12 +0000
committerAlain Magloire <alainm@gnu.org>2001-05-02 04:45:12 +0000
commit12c3088414a4e581901e8bb48648c8249b0b5775 (patch)
tree5aea271781266334a3fbfa4307f43747e2e64ce3
parent4d68dc112dfd2c8213b5448c1c6038a374fe12eb (diff)
downloadmailutils-12c3088414a4e581901e8bb48648c8249b0b5775.tar.gz
mailutils-12c3088414a4e581901e8bb48648c8249b0b5775.tar.bz2
See ChangeLog
-rw-r--r--ChangeLog69
-rw-r--r--argp/Makefile.am1
-rw-r--r--configure.in5
-rw-r--r--frm/Makefile.am1
-rw-r--r--imap4d/Makefile.am1
-rw-r--r--imap4d/util.c64
-rw-r--r--include/mailutils/locker.h12
-rw-r--r--lib/Makefile.am1
-rw-r--r--mail/Makefile.am2
-rw-r--r--mailbox/Makefile.am1
-rw-r--r--mailbox/locker.c103
-rw-r--r--mailbox/mbx_pop.c8
-rw-r--r--mailbox/mime.c4
-rw-r--r--pop3d/Makefile.am5
-rw-r--r--pop3d/apop.c207
-rw-r--r--pop3d/capa.c13
-rw-r--r--pop3d/dele.c4
-rw-r--r--pop3d/extra.c111
-rw-r--r--pop3d/list.c4
-rw-r--r--pop3d/pop3d.c131
-rw-r--r--pop3d/pop3d.h72
-rw-r--r--pop3d/quit.c1
-rw-r--r--pop3d/retr.c6
-rw-r--r--pop3d/rset.c4
-rw-r--r--pop3d/signal.c10
-rw-r--r--pop3d/stat.c8
-rw-r--r--pop3d/user.c80
27 files changed, 565 insertions, 363 deletions
diff --git a/ChangeLog b/ChangeLog
index d767fcc62..7eadcfb4a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,23 +1,78 @@
+2001-05-02 Alain Magloire
+
+ Some of the Makefile.am contain gcc specific options
+ like -Wall, -pedantic or -ansi remove them.
+
+ * configure.in: Check for stdarg and sysconf.
+ * mailbox/mime.c (_mime_set_content_type): Delayed the
+ creation of the header-field content-type until the message
+ is requested via mime_get_message().
+ * pop3d/lock.: new File to implement the locking.
+ * pop3d/apop.c: Rearrange the code around the #ifdefs
+ to be clearrer.
+ Make sure that when we use strncpy() that the buffer is
+ null terminated. Added the locking propose by Sergey to apop.
+ * pop3d/capa.c: Announce we support PIPELINING.
+ * pop3d/extra.c (pop3d_abquit): Remove ERR_DEAD_SOCK.
+ Remove the extra fflush(), the call to exit() always
+ flush the buffers.
+ (pop3d_readline): Implement PIPELINING.
+ * pop3d/pop3d.c: Remove the typedef struct sockaddr SA
+ for more clarity since it is not use that often.
+ port is not longer a global variable.
+ children should have the volatile qualification.
+
+2001-04-29 Alain Magloire
+
+ * pop3d/extra.c (pop3d_readline): Modify the loop to be able
+ to support PIPELINING.
+ * pop3d/capa.c: Advertise that we support PIPELINING.
+
+2001-04-29 Sergey Poznyakoff
+
+ Return values of all signal handlers are changed to RETSIGTYPE
+ and configure.in is modified accordingly. This is more portable.
+
+ * configure.in: New Macro AC_TYPE_SIGNAL.
+
+ * mailbox/locker.c (locker_lock): while trying to read pid value
+ from the pidfile passed wrong buffer length to read() call, namely:
+ read(fd, buf, sizeof (pid_t)).
+
+2001-04-29 Sergey Poznyakoff
+
+ I have modified locker.c to implement reference count. The
+ struct _locker is now:
+ struct _locker { int fd; int refcnt; char *fname; int flags; };
+ The refcnt member gets incremented each time locker_lock is called and
+ decremented each time locker_unlock is called. Actual locking is
+ performed only if refcnt == 0 on entry to locker_lock. Similarly,
+ unlocking is performed only when refcnt gets decremented to 0 by
+ locker_unlock. Also I have added basic support for NFS-secure
+ locking.
+
+ * mailbox/locker.c: Reference count implementation.
+
2001-04-25 Alain Magloire
* imap4d/store.c: First implementation.
- * mailbox/attribute.c (attribute_unsee_flags): New function.
+ * mailbox/attribute.c (attribute_unset_flags): New function.
2001-04-23 Sergey Poznyakoff
* mailbox/mbx_mbox.c (mbx_expunge): It assumes that mbox_get_message()
will place the pointer to message into mum->message member. But
mbox_get_message() relies on 1-based message numbers, whereas `mum'
- pointer is obtained using 0-based indexing:
+ pointer is obtained using 0-based indexing.
2001-04-23 Alain Magloire
- Sergey Poznyakoff noted: When the user's mailbox ha zeor size mmap
- fails on Solaris. On GNU/Linux it reuturn NULL buf subsequet munmap
+ Sergey Poznyakoff noted: When the user's mailbox has zero size, mmap
+ fails on Solaris. On GNU/Linux it reuturn NULL buf subsequent munmap
fails.
- * mailbox/mapfile_stream.c: To take care of this will set
- the mfs->ptr to NULL for len == 0;
+ * mailbox/mapfile_stream.c: To take care of this, mfs->ptr is set
+ to NULL for len == 0;
*mailbox/mbx_mbox.c (mbox_is_updated): Should I have return 0 (FALSE)
when size change.
@@ -48,7 +103,7 @@
2001-04-23 Sergey Poznyakoff
- It is often convenient to separte log outputs from POP and SMTP
+ It is often convenient to separate log outputs from POP and SMTP
servers. --with-log-facility flag which allows to specify to which
log facility the loggin output should be directed.
System administrators often prefere to have more information about
diff --git a/argp/Makefile.am b/argp/Makefile.am
index 1204127e3..448db0434 100644
--- a/argp/Makefile.am
+++ b/argp/Makefile.am
@@ -15,4 +15,3 @@ noinst_HEADERS = argp-fmtstream.h argp-namefrob.h argp.h
libargp_a_LIBADD = ../lib/libmailutils.a
-CFLAGS = -Wall -g
diff --git a/configure.in b/configure.in
index f6b70b474..04d3fe111 100644
--- a/configure.in
+++ b/configure.in
@@ -56,7 +56,7 @@ AC_HEADER_STDC
AC_HEADER_DIRENT
AM_C_PROTOTYPES
AC_CHECK_HEADERS(argp.h errno.h fcntl.h inttypes.h libgen.h limits.h malloc.h \
- paths.h shadow.h stdio.h stdlib.h string.h strings.h sys/file.h syslog.h \
+ paths.h shadow.h stdarg.h stdio.h stdlib.h string.h strings.h sys/file.h syslog.h \
unistd.h)
dnl Checks for typedefs, structures, and compiler characteristics.
@@ -66,6 +66,7 @@ AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
+AC_TYPE_SIGNAL
dnl Check for working functions
@@ -80,7 +81,7 @@ if test "$ac_cv_func_fnmatch_works" = "no"; then
: LIBOBJS="$LIBOBJS fnmatch.o"
fi
AC_REPLACE_FUNCS(setenv snprintf strtok_r strncasecmp strcasecmp vasprintf)
-AC_CHECK_FUNCS(mkstemp sigaction)
+AC_CHECK_FUNCS(mkstemp sigaction sysconf)
dnl Check for libraries
AC_CHECK_FUNCS(argp_parse)
diff --git a/frm/Makefile.am b/frm/Makefile.am
index ac35dee7b..0f0a5bf2c 100644
--- a/frm/Makefile.am
+++ b/frm/Makefile.am
@@ -1,5 +1,4 @@
AUTOMAKE_OPTIONS = ../lib/ansi2knr
-CFLAGS = -Wall -pedantic -g
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib
bin_PROGRAMS = frm
diff --git a/imap4d/Makefile.am b/imap4d/Makefile.am
index ec54db9a8..9aad1f3aa 100644
--- a/imap4d/Makefile.am
+++ b/imap4d/Makefile.am
@@ -1,6 +1,5 @@
AUTOMAKE_OPTIONS = ../lib/ansi2knr
INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/include
-CFLAGS = -Wall -ansi
sbin_PROGRAMS = imap4d
diff --git a/imap4d/util.c b/imap4d/util.c
index fbf409dfd..fb4941b55 100644
--- a/imap4d/util.c
+++ b/imap4d/util.c
@@ -18,11 +18,11 @@
#include "imap4d.h"
#include <ctype.h>
-static int add2set (int **set, int *n, unsigned long val, size_t max);
-static const char * sc2string (int rc);
+static int add2set __P ((int **, int *, unsigned long, size_t));
+static const char *sc2string __P ((int));
-/* FIXME: Some words are:
- between double quotes, between parenthesis. */
+/* Get the next space/CR/NL separated word, some words are between double
+ quotes, strtok() can not handle it. */
char *
util_getword (char *s, char **save)
{
@@ -50,6 +50,7 @@ util_getword (char *s, char **save)
return strtok_r (s, " \r\n", save);
}
+/* Stop a the first char that IMAP4 represent as a special characters. */
int
util_token (char *buf, size_t len, char **ptr)
{
@@ -142,7 +143,8 @@ util_tilde_expansion (const char *ref, const char *delim)
return p;
}
-/* Absolute path. */
+/* Get the absolute path. */
+/* NOTE: Path is allocated and must be free()d by the caller. */
char *
util_getfullpath (char *name, const char *delim)
{
@@ -158,7 +160,6 @@ util_getfullpath (char *name, const char *delim)
}
/* Return in set an allocated array contain (n) numbers, for imap messsage set
-
set ::= sequence_num / (sequence_num ":" sequence_num) / (set "," set)
sequence_num ::= nz_number / "*"
;; * is the largest number in use. For message
@@ -182,6 +183,7 @@ util_msgset (char *s, int **set, int *n, int isuid)
status = mailbox_messages_count (mbox, &max);
if (status != 0)
return status;
+ /* If it is a uid sequence, override max with the UID. */
if (isuid)
{
message_t msg = NULL;
@@ -227,11 +229,20 @@ util_msgset (char *s, int **set, int *n, int isuid)
break;
}
+ /* A pair of numbers separated by a ':' character indicates a
+ contiguous set of mesages ranging from the first number to the
+ second:
+ 3:5 --> 3 4 5
+ */
case ':':
low = val + 1;
s++;
break;
+ /* As a convenience. '*' is provided to refer to the highest message
+ number int the mailbox:
+ 5:* --> 5 6 7 8
+ */
case '*':
{
if (status != 0)
@@ -246,6 +257,10 @@ util_msgset (char *s, int **set, int *n, int isuid)
break;
}
+ /* IMAP also allows a set of noncontiguous numbers to be specified
+ with the ',' character:
+ 1,3,5,7 --> 1 3 5 7
+ */
case ',':
s++;
break;
@@ -275,6 +290,7 @@ util_msgset (char *s, int **set, int *n, int isuid)
return 0;
}
+/* Use vfprintf for the dirty work. */
int
util_send (const char *format, ...)
{
@@ -286,40 +302,42 @@ util_send (const char *format, ...)
return status;
}
+/* Send an unsolicited response. */
int
util_out (int rc, const char *format, ...)
{
char *buf = NULL;
+ int status;
va_list ap;
-
+ asprintf (&buf, "* %s%s\r\n", sc2string (rc), format);
va_start (ap, format);
- vasprintf (&buf, format, ap);
+ status = vfprintf (ofile, buf, ap);
va_end (ap);
-
- fprintf (ofile, "* %s%s\r\n", sc2string (rc), buf);
free (buf);
- return 0;
+ return status;
}
+/* Send the tag response and reset the state. */
int
util_finish (struct imap4d_command *command, int rc, const char *format, ...)
{
char *buf = NULL;
- const char *resp;
int new_state;
+ int status;
va_list ap;
+ asprintf (&buf, "%s %s%s %s\r\n", command->tag, sc2string (rc),
+ command->name, format);
+
va_start (ap, format);
- vasprintf (&buf, format, ap);
+ status = vfprintf (ofile, buf, ap);
va_end(ap);
-
- resp = sc2string (rc);
- fprintf (ofile, "%s %s%s %s\r\n", command->tag, resp, command->name, buf);
free (buf);
+ /* Reset the state. */
new_state = (rc == RESP_OK) ? command->success : command->failure;
if (new_state != STATE_NONE)
state = new_state;
- return 0;
+ return status;
}
char *
@@ -339,29 +357,27 @@ imap4d_readline (int fd)
do
{
- if (timeout > 0)
+ if (timeout)
{
available = select (fd + 1, &rfds, NULL, NULL, &tv);
if (!available)
- util_quit (1); /* FIXME: Timeout, send a "* BYE". */
+ util_quit (1);
}
nread = read (fd, buf, sizeof (buf) - 1);
if (nread < 1)
- util_quit (1); /* FIXME: dead socket, need to do something? */
+ util_quit (1);
buf[nread] = '\0';
ret = realloc (ret, (total + nread + 1) * sizeof (char));
if (ret == NULL)
- util_quit (1); /* FIXME: ENOMEM, send a "* BYE" to the client. */
+ util_quit (1);
memcpy (ret + total, buf, nread + 1);
total += nread;
-
- /* FIXME: handle literal strings here. */
-
}
while (memchr (buf, '\n', nread) == NULL);
+ /* Nuke CR'\r' */
for (nread = total; nread > 0; nread--)
if (ret[nread] == '\r' || ret[nread] == '\n')
ret[nread] = '\0';
diff --git a/include/mailutils/locker.h b/include/mailutils/locker.h
index 52b131693..0a0192f9b 100644
--- a/include/mailutils/locker.h
+++ b/include/mailutils/locker.h
@@ -1,5 +1,5 @@
/* GNU mailutils - a suite of utilities for electronic mail
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
@@ -35,7 +35,7 @@ extern "C" {
struct _locker;
typedef struct _locker *locker_t;
-extern int locker_create __P ((locker_t *, char *filename,
+extern int locker_create __P ((locker_t *, const char *filename,
size_t len, int flags));
extern void locker_destroy __P ((locker_t *));
@@ -47,9 +47,11 @@ extern void locker_destroy __P ((locker_t *));
#define MU_LOCKER_FCNTL 2
#define MU_LOCKER_TIME 4
-extern int locker_lock __P ((locker_t, int flag));
-extern int locker_touchlock __P ((locker_t));
-extern int locker_unlock __P ((locker_t));
+#define MU_LOCKER_EXPIRE_TIME (5 * 60)
+
+extern int locker_lock __P ((locker_t, int flag));
+extern int locker_touchlock __P ((locker_t));
+extern int locker_unlock __P ((locker_t));
#ifdef __cplusplus
}
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 792c16172..02b8dcb34 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,4 +12,3 @@ noinst_HEADERS = argcv.h error.h fnmatch.h getline.h getopt.h md5.h \
libmailutils_a_LIBADD = @LIBOBJS@ @ALLOCA@
-CFLAGS = -Wall -pedantic -g
diff --git a/mail/Makefile.am b/mail/Makefile.am
index a529e6d8d..8cf289443 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -1,7 +1,5 @@
AUTOMAKE_OPTIONS = ../lib/ansi2knr no-dependencies
-CFLAGS = -Wall -g
-
INCLUDES = -I${top_srcdir}/include -I${top_srcdir}/lib @ARGPINCS@
bin_PROGRAMS = mail
diff --git a/mailbox/Makefile.am b/mailbox/Makefile.am
index 34c047897..f1f2e001b 100644
--- a/mailbox/Makefile.am
+++ b/mailbox/Makefile.am
@@ -4,7 +4,6 @@ AUTOMAKE_OPTIONS = ../lib/ansi2knr
INCLUDES = -I${top_srcdir}/include -I${top_srcdir}/mailbox/include \
-I${top_srcdir}/lib
-CFLAGS = -Wall -g
SUBDIRS = include
diff --git a/mailbox/locker.c b/mailbox/locker.c
index a23666d33..b78b0ce9e 100644
--- a/mailbox/locker.c
+++ b/mailbox/locker.c
@@ -1,5 +1,5 @@
/* GNU mailutils - a suite of utilities for electronic mail
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
@@ -35,33 +35,30 @@
#include <mailutils/locker.h>
#define LOCKFILE_ATTR 0444
-#define LOCK_EXPIRE_TIME (5 * 60)
/* First draft by Brian Edmond. */
struct _locker
{
int fd;
+ int refcnt;
char *fname;
int flags;
};
int
-locker_create (locker_t *plocker, char *filename, size_t len, int flags)
+locker_create (locker_t *plocker, const char *filename, size_t len, int flags)
{
locker_t l;
- if (plocker == NULL)
+ if (plocker == NULL || filename == NULL || len == 0)
return EINVAL;
- if (filename == NULL || len == 0)
- return EINVAL;
-
- l = malloc (sizeof(*l));
+ l = malloc (sizeof (*l));
if (l == NULL)
return ENOMEM;
- l->fname = calloc (len + 5 /*strlen(".lock")*/ + 1, sizeof(char));
+ l->fname = calloc (len + 5 /*strlen(".lock")*/ + 1, sizeof (*(l->fname)));
if (l->fname == NULL)
{
free (l);
@@ -75,6 +72,7 @@ locker_create (locker_t *plocker, char *filename, size_t len, int flags)
else
l->flags = MU_LOCKER_TIME; /* Default is time lock implementation. */
l->fd = -1;
+ l->refcnt = 0;
*plocker = l;
return 0;
}
@@ -98,27 +96,41 @@ locker_lock (locker_t lock, int flags)
pid_t pid;
int removed = 0;
- (void)flags;
+ (void)flags; /* Ignore for now. */
if (lock == NULL)
return EINVAL;
+ /* Is the lock already applied?
+ FIXME: should we check flags != lock->flags ?? */
+ if (lock->fd != -1)
+ {
+ lock->refcnt++;
+ return 0;
+ }
+
/*
Check for lock existance:
if it exists but the process is gone the lock can be removed,
- if if the lock is expired and remove it. */
- if ((fd = open(lock->fname, O_RDONLY)) != -1)
+ if the lock is expired, remove it. */
+ fd = open (lock->fname, O_RDONLY);
+ if (fd != -1)
{
/* Check to see if this process is still running. */
if (lock->flags & MU_LOCKER_PID)
{
- if (read(fd, buf, sizeof (pid_t)) > 0)
+ int nread = read (fd, buf, sizeof (buf) - 1);
+ if (nread > 0)
{
- if ((pid = atoi(buf)) > 0)
+ buf[nread] = '\0';
+ pid = strtol (buf, NULL, 10);
+ if (pid > 0)
{
/* Process is gone so we try to remove the lock. */
- if (kill(pid, 0) == -1)
+ if (kill (pid, 0) == -1)
removed = 1;
}
+ else
+ removed = 1; /* Corrupted file, remove the lock. */
}
}
/* Check to see if the lock expired. */
@@ -126,72 +138,95 @@ locker_lock (locker_t lock, int flags)
{
struct stat stbuf;
- fstat(fd, &stbuf);
+ fstat (fd, &stbuf);
/* The lock has expired. */
- if ((time(NULL) - stbuf.st_mtime) > LOCK_EXPIRE_TIME)
+ if ((time (NULL) - stbuf.st_mtime) > MU_LOCKER_EXPIRE_TIME)
removed = 1;
}
- close(fd);
+ close (fd);
if (removed)
- unlink(lock->fname);
+ unlink (lock->fname);
}
/* Try to create the lockfile. */
- if ((fd = open(lock->fname,
- O_WRONLY | O_CREAT | O_EXCL, LOCKFILE_ATTR)) == -1)
+ fd = open (lock->fname, O_WRONLY | O_CREAT | O_EXCL, LOCKFILE_ATTR);
+ if (fd == -1)
return errno;
+ else
+ {
+ struct stat fn_stat;
+ struct stat fd_stat;
+
+ if (lstat (lock->fname, &fn_stat)
+ || fstat(fd, &fd_stat)
+ || fn_stat.st_nlink != 1
+ || fn_stat.st_dev != fd_stat.st_dev
+ || fn_stat.st_ino != fd_stat.st_ino
+ || fn_stat.st_uid != fd_stat.st_uid
+ || fn_stat.st_gid != fd_stat.st_gid)
+ {
+ close (fd);
+ unlink (lock->fname);
+ return EPERM;
+ }
+ }
+
/* Success. */
- sprintf(buf, "%ld", (long)getpid());
- write(fd, buf, strlen(buf));
+ sprintf (buf, "%ld", (long)getpid ());
+ write (fd, buf, strlen (buf));
/* Try to get a file lock. */
if (lock->flags & MU_LOCKER_FCNTL)
{
struct flock fl;
- memset(&fl, 0, sizeof(struct flock));
+ memset (&fl, 0, sizeof (struct flock));
fl.l_type = F_WRLCK;
- if (fcntl(fd, F_SETLK, &fl) == -1)
+ if (fcntl (fd, F_SETLK, &fl) == -1)
{
int err = errno;
/* Could not get the file lock. */
close (fd);
- unlink(lock->fname); /* Remove the file I created. */
+ unlink (lock->fname); /* Remove the file I created. */
return err;
}
}
lock->fd = fd;
+ lock->refcnt++;
return 0;
}
int
locker_touchlock (locker_t lock)
{
- if (!lock || ! lock->fname || (lock->fd == -1))
+ if (!lock || !lock->fname || lock->fd == -1)
return EINVAL;
- return (utime(lock->fname, NULL));
+ return utime (lock->fname, NULL);
}
int
locker_unlock (locker_t lock)
{
- if (!lock || ! lock->fname || (lock->fd == -1))
+ if (!lock || !lock->fname || lock->fd == -1 || lock->refcnt <= 0)
return EINVAL;
+ if (--lock->refcnt > 0)
+ return 0;
+
if (lock->flags & MU_LOCKER_FCNTL)
{
struct flock fl;
- memset(&fl, 0, sizeof(struct flock));
+ memset (&fl, 0, sizeof (struct flock));
fl.l_type = F_UNLCK;
- /* Unlock failed ? */
- if (fcntl(lock->fd, F_SETLK, &fl) == -1)
+ /* Unlock failed? */
+ if (fcntl (lock->fd, F_SETLK, &fl) == -1)
return errno;
}
- close(lock->fd);
+ close (lock->fd);
lock->fd = -1;
- unlink(lock->fname);
+ unlink (lock->fname);
return 0;
}
diff --git a/mailbox/mbx_pop.c b/mailbox/mbx_pop.c
index 764cd3ebc..710f2bf86 100644
--- a/mailbox/mbx_pop.c
+++ b/mailbox/mbx_pop.c
@@ -127,7 +127,7 @@ static int pop_write __P ((pop_data_t));
If the POP server supports TOP, we can cleanly fetch the header.
But otherwise we use the clumsy approach. .i.e for the header we read 'til
^\n then discard the rest, for the body we read after ^\n and discard the
- beginning. This a waste, Pop was not conceive for this obviously. */
+ beginning. This is a waste, Pop was not conceive for this obviously. */
struct _pop_message
{
int inbody;
@@ -175,8 +175,8 @@ struct _pop_data
/* Usefull little Macros, since these are very repetitive. */
/* Check if we're busy ? */
-/* POP is a one channel dowload protocol, so if someone
- is trying to do another command while another is running
+/* POP is a one channel download protocol, so if someone
+ is trying to execute a command while another is running
something is seriously incorrect, So the best course
of action is to close down the connection and start a new one.
For example mime_t only reads part of the message. If a client
@@ -193,7 +193,7 @@ struct _pop_data
}
if in the while of the readline, one try to get another email. The pop
server will get seriously confused, and the second message will still
- be the first one, There is no way to tell POP servers ye! stop/abort.
+ be the first one, There is no way to tell POP servers yo! stop/abort.
The approach is to close the stream and reopen again. So every time
we go in to a function our state is preserve by the triplets
mpd->{func,state,id}. The macro CHECK_BUSY checks if we are not
diff --git a/mailbox/mime.c b/mailbox/mime.c
index 951d24a32..1f1167109 100644
--- a/mailbox/mime.c
+++ b/mailbox/mime.c
@@ -395,6 +395,10 @@ _mime_set_content_type(mime_t mime)
header_t hdr = NULL;
size_t size;
+ /* Delayed the creation of the header 'til they create the final message via
+ mime_get_message() */
+ if (mime->hdrs == NULL)
+ return 0;
if ( mime->nmtp_parts > 1 ) {
if ( mime->flags & MIME_ADDED_MULTIPART_CT )
return 0;
diff --git a/pop3d/Makefile.am b/pop3d/Makefile.am
index ee510e6b4..e8d06ebe8 100644
--- a/pop3d/Makefile.am
+++ b/pop3d/Makefile.am
@@ -1,10 +1,9 @@
AUTOMAKE_OPTIONS = ../lib/ansi2knr
INCLUDES =-I$(srcdir) -I$(top_srcdir)/lib -I$(top_srcdir)/include
-CFLAGS = -Wall -g
sbin_PROGRAMS = pop3d
-pop3d_SOURCES = apop.c auth.c capa.c dele.c extra.c pop3d.c pop3d.h\
- list.c noop.c quit.c retr.c rset.c stat.c top.c uidl.c user.c signal.c
+pop3d_SOURCES = apop.c auth.c capa.c dele.c extra.c pop3d.c pop3d.h \
+ list.c lock.c noop.c quit.c retr.c rset.c stat.c top.c uidl.c user.c signal.c
pop3d_LDADD = ../mailbox/libmailbox.la ../lib/libmailutils.a @AUTHLIBS@
diff --git a/pop3d/apop.c b/pop3d/apop.c
index 74fe4cf26..761e210be 100644
--- a/pop3d/apop.c
+++ b/pop3d/apop.c
@@ -17,6 +17,24 @@
#include "pop3d.h"
+/*
+ APOP name digest
+
+ Arguments:
+ a string identifying a mailbox and a MD5 digest string
+ (both required)
+
+ Restrictions:
+ may only be given in the AUTHORIZATION state after the POP3
+ greeting or after an unsuccessful USER or PASS command
+
+ When the POP3 server receives the APOP command, it verifies
+ the digest provided. If the digest is correct, the POP3
+ server issues a positive response, and the POP3 session
+ enters the TRANSACTION state. Otherwise, a negative
+ response is issued and the POP3 session remains in the
+ AUTHORIZATION state. */
+
/* Check if a username exists in APOP password file
returns pointer to password if found, otherwise NULL */
char *
@@ -25,16 +43,11 @@ pop3d_apopuser (const char *user)
char *password;
char buf[POP_MAXCMDLEN];
struct stat st;
-#ifdef WITH_BDB2
- int errno;
- DB *dbp;
- DBT key, data;
+ /* Check the mode, for security reasons. */
+#ifdef WITH_BDB2
if (stat (APOP_PASSFILE ".db", &st) != -1)
#else
- char *tmp;
- FILE *apop_file;
-
if (stat (APOP_PASSFILE ".passwd", &st) != -1)
#endif
if ((st.st_mode & 0777) != 0600)
@@ -44,80 +57,91 @@ pop3d_apopuser (const char *user)
}
#ifdef WITH_BDB2
- errno = db_open (APOP_PASSFILE ".db", DB_HASH, DB_RDONLY, 0600, NULL,
- NULL, &dbp);
- if (errno != 0)
- {
- syslog (LOG_ERR, "Unable to open APOP database: %s", strerror (errno));
- return NULL;
- }
+ {
+ int status;
+ DB *dbp;
+ DBT key, data;
+ status = db_open (APOP_PASSFILE ".db", DB_HASH, DB_RDONLY, 0600, NULL,
+ NULL, &dbp);
+ if (status != 0)
+ {
+ syslog (LOG_ERR, "Unable to open APOP db: %s", strerror (status));
+ return NULL;
+ }
- memset (&key, 0, sizeof (DBT));
- memset (&data, 0, sizeof (DBT));
+ memset (&key, 0, sizeof (DBT));
+ memset (&data, 0, sizeof (DBT));
- strncpy (buf, user, sizeof (buf));
- key.data = buf;
- key.size = strlen (user);
- errno = dbp->get (dbp, NULL, &key, &data, 0);
- if (errno != 0)
- {
- syslog (LOG_ERR, "db_get error: %s", strerror (errno));
- dbp->close (dbp, 0);
- return NULL;
- }
+ strncpy (buf, user, sizeof buf);
+ /* strncpy () is lame and does not NULL terminate. */
+ buf[sizeof (buf) - 1] = '\0';
+ key.data = buf;
+ key.size = strlen (buf);
+ status = dbp->get (dbp, NULL, &key, &data, 0);
+ if (status != 0)
+ {
+ syslog (LOG_ERR, "db_get error: %s", strerror (status));
+ dbp->close (dbp, 0);
+ return NULL;
+ }
- password = malloc (sizeof (char) * data.size);
- if (password == NULL)
- {
- dbp->close (dbp, 0);
- return NULL;
- }
+ password = calloc (data.size + 1, sizeof (*password));
+ if (password == NULL)
+ {
+ dbp->close (dbp, 0);
+ return NULL;
+ }
- sprintf (password, "%.*s", (int) data.size, (char *) data.data);
- dbp->close (dbp, 0);
- return password;
+ sprintf (password, "%.*s", (int) data.size, (char *) data.data);
+ dbp->close (dbp, 0);
+ return password;
+ }
#else /* !WITH_BDBD2 */
- apop_file = fopen (APOP_PASSFILE ".passwd", "r");
- if (apop_file == NULL)
- {
- syslog (LOG_INFO, "Unable to open APOP password file");
- return NULL;
- }
+ {
+ char *tmp;
+ FILE *apop_file;
+ apop_file = fopen (APOP_PASSFILE ".passwd", "r");
+ if (apop_file == NULL)
+ {
+ syslog (LOG_INFO, "Unable to open APOP password file");
+ return NULL;
+ }
- password = malloc (sizeof (char) * APOP_DIGEST);
- if (password == NULL)
- {
- fclose (apop_file);
- pop3d_abquit (ERR_NO_MEM);
- }
- password[0] = '\0';
+ password = calloc (APOP_DIGEST, sizeof (*password));
+ if (password == NULL)
+ {
+ fclose (apop_file);
+ pop3d_abquit (ERR_NO_MEM);
+ }
- while (fgets (buf, sizeof (buf) - 1, apop_file) != NULL)
- {
- tmp = strchr (buf, ':');
- if (tmp == NULL)
- continue;
- *tmp = '\0';
- tmp++;
-
- if (strncmp (user, buf, strlen (user)))