Commit 543739df 543739df4672bf881d91d0fa8fe03a0b46039f75 by Alain Magloire

attribute.c

		I broke it ... sigh.

file_stream.c header.c locker.c mapfile_stream.c mbx_default.c mbx_pop.c
		code cleanup put some comments in there ;-)
1 parent 29eb4e30
......@@ -108,7 +108,7 @@ attribute_set_recent (attribute_t attr)
return EINVAL;
if (attr == NULL)
{
attr->flag |= MU_ATTRIBUTE_RECENT;
attr->flag = 0;
return 0;
}
return EACCES;
......@@ -167,7 +167,7 @@ attribute_is_recent (attribute_t attr)
{
if (attr == NULL)
return 0;
return attr->flag & MU_ATTRIBUTE_RECENT;
return attr->flag == 0;
}
int
......@@ -229,7 +229,7 @@ attribute_unset_recent (attribute_t attr)
{
if (attr == NULL)
return 0;
attr->flag &= ~MU_ATTRIBUTE_RECENT;
attr->flag |= MU_ATTRIBUTE_SEEN;
return 0;
}
......
......@@ -39,7 +39,7 @@ _file_destroy (stream_t stream)
{
struct _file_stream *fs = stream->owner;
if (fs->file)
if (fs && fs->file)
fclose (fs->file);
free (fs);
}
......@@ -50,26 +50,30 @@ _file_read (stream_t stream, char *optr, size_t osize,
{
struct _file_stream *fs = stream->owner;
size_t n;
int err = 0;
if (fs == NULL)
return EINVAL;
if (fs->offset != offset)
{
fseek (fs->file, offset, SEEK_SET);
if (fseek (fs->file, offset, SEEK_SET) != 0)
return errno;
fs->offset = offset;
}
n = fread (optr, sizeof(char), osize, fs->file);
if (n == 0)
{
if (ferror(fs->file))
return errno;
err = errno;
}
else
fs->offset += n;
if (nbytes)
*nbytes = n;
return 0;
return err;
}
static int
......@@ -80,9 +84,13 @@ _file_readline (stream_t stream, char *optr, size_t osize,
size_t n = 0;
int err = 0;
if (fs == NULL)
return EINVAL;
if (fs->offset != offset)
{
fseek (fs->file, offset, SEEK_SET);
if (fseek (fs->file, offset, SEEK_SET) != 0)
return errno;
fs->offset = offset;
}
......@@ -110,32 +118,39 @@ _file_write (stream_t stream, const char *iptr, size_t isize,
{
struct _file_stream *fs = stream->owner;
size_t n;
int err;
if (fs == NULL)
return EINVAL;
if (fs->offset != offset)
{
fseek (fs->file, offset, SEEK_SET);
if (fseek (fs->file, offset, SEEK_SET) != 0)
return errno;
fs->offset = offset;
}
n = fwrite (iptr, sizeof(char), isize, fs->file);
if (*nbytes == 0)
if (n == 0)
{
if (ferror (fs->file))
return errno;
err = errno;
}
else
fs->offset += *nbytes;
if (nbytes)
*nbytes = n;
return 0;
return err;
}
static int
_file_truncate (stream_t stream, off_t len)
{
struct _file_stream *fs = stream->owner;
if (fs == NULL)
return EINVAL;
if (ftruncate (fileno(fs->file), len) != 0)
return errno;
return 0;
......@@ -146,6 +161,9 @@ _file_size (stream_t stream, off_t *psize)
{
struct _file_stream *fs = stream->owner;
struct stat stbuf;
if (fs == NULL)
return EINVAL;
fflush (fs->file);
if (fstat(fileno(fs->file), &stbuf) == -1)
return errno;
......@@ -158,6 +176,9 @@ static int
_file_flush (stream_t stream)
{
struct _file_stream *fs = stream->owner;
if (fs == NULL)
return EINVAL;
return fflush (fs->file);
}
......@@ -165,6 +186,9 @@ static int
_file_get_fd (stream_t stream, int *pfd)
{
struct _file_stream *fs = stream->owner;
if (fs == NULL)
return EINVAL;
if (pfd)
*pfd = fileno (fs->file);
return 0;
......@@ -174,10 +198,17 @@ static int
_file_close (stream_t stream)
{
struct _file_stream *fs = stream->owner;
int err = 0;
if (fs == NULL)
return EINVAL;
if (fs->file)
if (fclose (fs->file) != 0)
return errno;
return 0;
{
if (fclose (fs->file) != 0)
err = errno;
fs->file = NULL;
}
return err;
}
static int
......@@ -188,8 +219,12 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
int fd;
const char *mode;
(void)port; /* shutup gcc */
/* map the flags to the system equivalent */
(void)port; /* Ignored. */
if (fs == NULL)
return EINVAL;
/* Map the flags to the system equivalent. */
if (flags & MU_STREAM_WRITE)
flg = O_WRONLY;
else if (flags & MU_STREAM_RDWR)
......@@ -197,24 +232,23 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
else /* default */
flg = O_RDONLY;
/* local folders should not block it is local disk ???
* We simply ignore the O_NONBLOCK flag
* But take care of the APPEND.
*/
/* Local folders should not block it is local disk ???
We simply ignore the O_NONBLOCK flag
But take care of the APPEND. */
if (flags & MU_STREAM_APPEND)
flg |= O_APPEND;
/* handle CREAT with care, not to follow symlinks */
/* Handle CREAT with care, not to follow symlinks. */
if (flags & MU_STREAM_CREAT)
{
/* first see if the file already exists */
/* First see if the file already exists. */
fd = open(filename, flg);
if (fd == -1)
{
/* oops bail out */
/* Oops bail out. */
if (errno != ENOENT)
return errno;
/* Race condition here when creating the file ?? */
/* Race condition here when creating the file ??. */
fd = open(filename, flg|O_CREAT|O_EXCL, 0600);
if (fd < 0)
return errno;
......@@ -227,23 +261,22 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
return errno;
}
/* we have to make sure that We did not open
* a symlink. From Casper D. in bugtraq.
*/
/* We have to make sure that We did not open
a symlink. From Casper D. in bugtraq. */
if ((flg & MU_STREAM_CREAT) ||
(flg & MU_STREAM_RDWR) ||
(flg & MU_STREAM_WRITE))
{
struct stat fdbuf, filebuf;
/* the next two stats should never fail */
/* The next two stats should never fail. */
if (fstat(fd, &fdbuf) == -1)
return errno;
if (lstat(filename, &filebuf) == -1)
return errno;
/* Now check that: file and fd reference the same file,
file only has one link, file is plain file */
file only has one link, file is plain file. */
if (fdbuf.st_dev != filebuf.st_dev ||
fdbuf.st_ino != filebuf.st_ino ||
fdbuf.st_nlink != 1 ||
......@@ -253,14 +286,14 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
return EINVAL;
}
}
/* we use FILE * object */
/* We use FILE * object. */
if (flags & MU_STREAM_APPEND)
mode = "a";
else if (flags & MU_STREAM_RDWR)
mode = "r+b";
else if (flags & MU_STREAM_WRITE)
mode = "wb";
else /* default readonly*/
else /* Default readonly. */
mode = "rb";
fs->file = fopen (filename, mode);
......@@ -271,6 +304,7 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
return ret;
}
#if BUFSIZ <= 1024
/* Give us some roo to breathe, for OS with two small stdio buffers. */
{
char *iobuffer;
iobuffer = malloc (8192);
......
......@@ -27,7 +27,7 @@
#include <stdio.h>
#include <errno.h>
static int header_parse (header_t h, char *blurb, int len);
static int header_parse (header_t h, const char *blurb, int len);
static int header_read (stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread);
static int header_write (stream_t os, const char *buf, size_t buflen,
......@@ -43,18 +43,18 @@ struct _hdr
struct _header
{
/* Data */
/* Owner. */
void *owner;
/* Data. */
char *blurb;
size_t blurb_len;
size_t hdr_count;
struct _hdr *hdr;
/* streams */
/* Streams. */
stream_t stream;
int (*_get_value) __P ((header_t, const char *, char *, size_t , size_t *));
/* owner ? */
void *owner;
};
int
......@@ -66,7 +66,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner)
return ENOMEM;
h->owner = owner;
header_parse (h, (char *)blurb, len);
header_parse (h, blurb, len);
*ph = h;
return 0;
......@@ -79,10 +79,9 @@ header_destroy (header_t *ph, void *owner)
{
header_t h = *ph;
/* can we destroy ? */
/* Can we destroy ?. */
if (h->owner == owner)
{
/* io */
stream_destroy (&(h->stream), h);
free (h->hdr);
free (h->blurb);
......@@ -92,25 +91,23 @@ header_destroy (header_t *ph, void *owner)
}
}
/*
* Parsing is done in a rather simple fashion.
* meaning we just consider an entry to be
* a field-name an a field-value. So they
* maybe duplicate of field-name like "Received"
* they are just put in the array, see _get_value()
* on how to handle the case.
* in the case of error .i.e a bad header construct
* we do a full stop and return what we have so far.
*/
/* Parsing is done in a rather simple fashion.
meaning we just consider an entry to be
a field-name an a field-value. So they
maybe duplicate of field-name like "Received"
they are just put in the array, see _get_value()
on how to handle the case.
in the case of error .i.e a bad header construct
we do a full stop and return what we have so far. */
static int
header_parse (header_t header, char *blurb, int len)
header_parse (header_t header, const char *blurb, int len)
{
char *header_end;
char *header_start;
char *header_start2;
struct _hdr *hdr;
/* nothing to parse */
/* Nothing to parse. */
if (blurb == NULL || len == 0)
return 0;
......@@ -120,22 +117,26 @@ header_parse (header_t header, char *blurb, int len)
return ENOMEM;
memcpy (header->blurb, blurb, header->blurb_len);
free (header->hdr);
if (header->hdr)
free (header->hdr);
header->hdr = NULL;
header->hdr_count = 0;
/* Get a header, a header is :
field-name ':' ' ' field-value '\r' '\n'
[ (' ' | '\t') field-value '\r' '\n' ]
*/
/* First loop goes throught the blurb */
for (header_start = header->blurb;; header_start = ++header_end)
{
char *fn, *fn_end, *fv, *fv_end;
/* get a header, a header is :
* field-name ':' ' ' field-value '\r' '\n'
* [ (' ' | '\t') field-value '\r' '\n' ]
*/
if (header_start[0] == ' ' ||
header_start[0] == '\t' ||
header_start[0]== '\n')
break;
/* Second loop extract one header field. */
for (header_start2 = header_start;;header_start2 = ++header_end)
{
header_end = memchr (header_start2, '\n', len);
......@@ -151,15 +152,17 @@ header_parse (header_t header, char *blurb, int len)
}
if (header_end[1] != ' '
&& header_end[1] != '\t')
break; /* new header break the inner for */
break; /* New header break the inner for. */
}
/* *header_end = ' '; smash LF ? NO */
}
if (header_end == NULL)
break; /* bail out */
break; /* Bail out. */
/* Treats unix "From " specially */
/* Now save the header in the data structure. */
/* Treats unix "From " specially. */
if ((header_end - header_start >= 5)
&& strncmp (header_start, "From ", 5) == 0)
{
......@@ -168,23 +171,23 @@ header_parse (header_t header, char *blurb, int len)
fv = header_start + 5;
fv_end = header_end;
}
else
else /* Break the header in key: value */
{
char *colon = memchr (header_start, ':', header_end - header_start);
/* Houston we have a problem */
/* Houston we have a problem. */
if (colon == NULL)
break; /* disregard the rest and bailout */
break; /* Disregard the rest and bailout. */
fn = header_start;
fn_end = colon;
/* skip leading spaces */
/* Skip leading spaces. */
while (*(++colon) == ' ');
fv = colon;
fv_end = header_end;
}
/* allocate a new slot for the field:value */
/* Allocate a new slot for the field:value. */
hdr = realloc (header->hdr, (header->hdr_count + 1) * sizeof (*hdr));
if (hdr == NULL)
{
......@@ -216,42 +219,40 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
return EINVAL;
/* Easy approach: if replace, overwrite the field-{namve,value}
* and readjust the pointers by calling header_parse ()
* this is wastefull and bad, we're just fragmenting the memory
* it can be done better. But that may imply a rewite of the headers
* So for another day.
*/
{
size_t name_len;
size_t i;
size_t fn_len;
size_t fv_len;
len = header->blurb_len;
for (name_len = strlen (fn), i = 0; i < header->hdr_count; i++)
{
fn_len = header->hdr[i].fn_end - header->hdr[i].fn;
fv_len = header->hdr[i].fv_end - header->hdr[i].fv;
if (fn_len == name_len &&
strncasecmp (header->hdr[i].fn, fn, fn_len) == 0)
{
if (replace)
{
blurb = header->blurb;
memmove (header->hdr[i].fn, header->hdr[i + 1].fn,
header->hdr[header->hdr_count - 1].fv_end
- header->hdr[i + 1].fn + 1 + 1);
/* readjust the pointers if move */
len -= fn_len + fv_len + 2;
i--;
blurb = header->blurb;
header_parse (header, blurb, len);
free (blurb);
}
}
}
}
/* and it's getting worse, we free/malloc at will */
and readjust the pointers by calling header_parse ()
this is wastefull, we're just fragmenting the memory
it can be done better. But that may imply a rewite of the headers
So for another day. */
if (replace)
{
size_t name_len;
size_t i;
size_t fn_len;
size_t fv_len;
len = header->blurb_len;
for (name_len = strlen (fn), i = 0; i < header->hdr_count; i++)
{
fn_len = header->hdr[i].fn_end - header->hdr[i].fn;
fv_len = header->hdr[i].fv_end - header->hdr[i].fv;
if (fn_len == name_len &&
strncasecmp (header->hdr[i].fn, fn, fn_len) == 0)
{
blurb = header->blurb;
memmove (header->hdr[i].fn, header->hdr[i + 1].fn,
header->hdr[header->hdr_count - 1].fv_end
- header->hdr[i + 1].fn + 1 + 1);
/* readjust the pointers if move */
len -= fn_len + fv_len + 2;
i--;
blurb = header->blurb;
header_parse (header, blurb, len);
free (blurb);
}
}
}
/* Replacing was taking care of above now just add to
the end the new header. Really not cute. */
len = strlen (fn) + strlen (fv) + 1 + 1 + 1 + 1;
blurb = calloc (header->blurb_len + len, 1);
if (blurb == NULL)
......@@ -290,18 +291,16 @@ header_get_value (header_t header, const char *name, char *buffer,
if (header == NULL || name == NULL)
return EINVAL;
/* we set the threshold to be 1 less for the null */
/* We set the threshold to be 1 less for the null. */
threshold = --buflen;
/*
* Caution: We may have more then one value for a field
* name, for example a "Received" field-name is added by
* each passing MTA. The way that the parsing (_parse())
* is done it's not take to account. So we just stuff in
* the buffer all the field-values to a corresponding field-name.
* FIXME: Should we kosher the output ? meaning replace
* occurences of " \t\r\n" for spaces ? for now we don't.
*/
/* Caution: We may have more then one value for a field
name, for example a "Received" field-name is added by
each passing MTA. The way that the parsing (_parse())
is done it's not take to account. So we just stuff in
the buffer all the field-values to a corresponding field-name.
FIXME: Should we kosher the output ? meaning replace
occurences of " \t\r\n" for spaces ? for now we don't. */
for (name_len = strlen (name), i = 0; i < header->hdr_count; i++)
{
fn_len = header->hdr[i].fn_end - header->hdr[i].fn;
......@@ -310,7 +309,7 @@ header_get_value (header_t header, const char *name, char *buffer,
{
fv_len = (header->hdr[i].fv_end - header->hdr[i].fv);
total += fv_len;
/* can everything fit in the buffer */
/* Can everything fit in the buffer. */
if (buffer && threshold > 0)
{
threshold -= fv_len;
......@@ -330,16 +329,16 @@ header_get_value (header_t header, const char *name, char *buffer,
}
}
if (buffer)
*buffer = '\0'; /* null terminated */
*buffer = '\0'; /* Null terminated. */
if (pn)
*pn = total;
if (total == 0)
{
int err = ENOENT;
/* check if they provided a hook */
/* Check if they provided a hook. */
if (header->_get_value != NULL)
err = header->_get_value (header, name, buffer, buflen, pn);
/* cache it locally */
/* Cache it locally. */
if (err == 0)
header_set_value (header, name, buffer, 0);
return err;
......@@ -421,7 +420,7 @@ header_entry_value (header_t header, size_t num, char *buf,
if (header->hdr_count == 0 || num > header->hdr_count)
return ENOENT;
len = header->hdr[num].fv_end - header->hdr[num].fv;
/* save one for the null */
/* Save one for the null. */
--buflen;
if (buf && buflen > 0)
{
......
......@@ -32,15 +32,12 @@
#define LOCKFILE_ATTR 0444
#define LOCK_EXPIRE_TIME (5 * 60)
/*
* Waiting for Brian E. to implement this.
*/
/* First draft by Brian Edmond. */
struct _locker
{
int fd;
char *fname;
int locked;
int flags;
};
......@@ -59,7 +56,7 @@ locker_create (locker_t *plocker, char *filename, size_t len, int flags)
if (l == NULL)
return ENOMEM;
l->fname = calloc (len + 5 + 1, sizeof(char));
l->fname = calloc (len + 5 /*strlen(".lock")*/ + 1, sizeof(char));
if (l->fname == NULL)
{
free (l);
......@@ -68,11 +65,10 @@ locker_create (locker_t *plocker, char *filename, size_t len, int flags)
memcpy (l->fname, filename, len);
strcat (l->fname, ".lock");
l->locked = 0;
if (flags)
l->flags = flags;
else
l->flags = MU_LOCKER_TIME;
l->flags = MU_LOCKER_TIME; /* Default is time lock implementation. */
l->fd = -1;
*plocker = l;
return 0;
......@@ -101,30 +97,32 @@ locker_lock (locker_t lock, int flags)
if (lock == NULL)
return EINVAL;
/* check for lock existance
* if it exists but the process is gone the lock can be removed
*/
/*
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)
{
/* Check to see if this process is still running. */
if (lock->flags & MU_LOCKER_PID)
{
if (read(fd, buf, sizeof (pid_t)) > 0)
{
/* check to see if this process is still running */
if ((pid = atoi(buf)) > 0)
{
/* process is gone so we try to remove the lock */
/* Process is gone so we try to remove the lock. */
if (kill(pid, 0) == -1)
removed = 1;
}
}
}
/* Check to see if the lock expired. */
if (lock->flags & MU_LOCKER_TIME)
{
struct stat stbuf;
fstat(fd, &stbuf);
/* the lock has expired */
/* The lock has expired. */
if ((time(NULL) - stbuf.st_mtime) > LOCK_EXPIRE_TIME)
removed = 1;
}
......@@ -134,15 +132,15 @@ locker_lock (locker_t lock, int flags)
unlink(lock->fname);
}
/* try to create the lockfile */
/* Try to create the lockfile. */
if ((fd = open(lock->fname,
O_WRONLY | O_CREAT | O_EXCL, LOCKFILE_ATTR)) == -1)
return (-1);
/* success */
return errno;
/* Success. */
sprintf(buf, "%d", getpid());
write(fd, buf, strlen(buf));
/* try to get a file lock */
/* Try to get a file lock. */
if (lock->flags & MU_LOCKER_FCNTL)
{
struct flock fl;
......@@ -151,10 +149,11 @@ locker_lock (locker_t lock, int flags)
fl.l_type = F_WRLCK;
if (fcntl(fd, F_SETLK, &fl) == -1)
{
/* could not get the file lock */
int err = errno;
/* Could not get the file lock. */
close (fd);
unlink(lock->fname); /* remove the file I created */
return -1;
unlink(lock->fname); /* Remove the file I created. */
return err;
}
}
......@@ -165,7 +164,7 @@ locker_lock (locker_t lock, int flags)
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));
}
......@@ -173,7 +172,7 @@ locker_touchlock (locker_t lock)
int
locker_unlock (locker_t lock)
{
if (!lock || !lock->fname || (lock->fd == -1))
if (!lock || ! lock->fname || (lock->fd == -1))
return EINVAL;
if (lock->flags & MU_LOCKER_FCNTL)
......@@ -182,11 +181,10 @@ locker_unlock (locker_t lock)
memset(&fl, 0, sizeof(struct flock));
fl.l_type = F_UNLCK;
/* unlock failed ? */
/* Unlock failed ? */
if (fcntl(lock->fd, F_SETLK, &fl) == -1)
return errno;
}
lock->locked = 0;
close(lock->fd);
lock->fd = -1;
unlink(lock->fname);
......
......@@ -45,7 +45,7 @@ _mapfile_destroy (stream_t stream)
{
struct _mapfile_stream *mfs = stream->owner;
if (mfs->ptr)
if (mfs && mfs->ptr)
{
munmap (mfs->ptr, mfs->size);
close (mfs->fd);
......@@ -60,8 +60,9 @@ _mapfile_read (stream_t stream, char *optr, size_t osize,
struct _mapfile_stream *mfs = stream->owner;
size_t n;
if (mfs->ptr == NULL)
if (mfs == NULL || mfs->ptr == NULL)
return EINVAL;
if (offset >= (off_t)mfs->size)
{
if (nbytes)
......@@ -85,9 +86,9 @@ _mapfile_readline (stream_t stream, char *optr, size_t osize,
char *nl;
size_t n = 0;
if (mfs->ptr == NULL)
if (mfs == NULL || mfs->ptr == NULL)
return EINVAL;
/* save space for the null byte */
/* Save space for the null byte. */
osize--;
if (offset >= (off_t)mfs->size)
{
......@@ -112,13 +113,14 @@ _mapfile_write (stream_t stream, const char *iptr, size_t isize,
{
struct _mapfile_stream *mfs = stream->owner;
if (mfs->ptr == NULL)
if (mfs == NULL || mfs->ptr == NULL)
return EINVAL;
if (! (mfs->flags & PROT_WRITE))
return EACCES;
/* not recommanded, really */
/* bigger we have to remmap */
/* Not recommanded, really. */
/* Bigger we have to remmap. */
if (mfs->size < (offset + isize))
{
if (munmap (mfs->ptr, mfs->size) != 0)
......@@ -150,9 +152,9 @@ static int
_mapfile_truncate (stream_t stream, off_t len)
{
struct _mapfile_stream *mfs = stream->owner;
if (mfs->ptr == NULL)
if (mfs == NULL || mfs->ptr == NULL)
return EINVAL;
/* remap */
/* Remap. */
if (munmap (mfs->ptr, mfs->size) != 0)
{
int err = errno;
......@@ -178,7 +180,8 @@ _mapfile_size (stream_t stream, off_t *psize)
{
struct _mapfile_stream *mfs = stream->owner;
struct stat stbuf;
if (mfs->ptr == NULL)
if (mfs == NULL || mfs->ptr == NULL)
return EINVAL;
msync (mfs->ptr, mfs->size, MS_SYNC);
if (fstat(mfs->fd, &stbuf) != 0)
......@@ -192,6 +195,8 @@ static int
_mapfile_flush (stream_t stream)
{
struct _mapfile_stream *mfs = stream->owner;
if (mfs == NULL)
return EINVAL;
return msync (mfs->ptr, mfs->size, MS_SYNC);
}
......@@ -199,6 +204,8 @@ static int
_mapfile_get_fd (stream_t stream, int *pfd)
{
struct _mapfile_stream *mfs = stream->owner;
if (mfs == NULL)
return EINVAL;
if (pfd)
*pfd = mfs->fd;
return 0;
......@@ -208,16 +215,17 @@ static int
_mapfile_close (stream_t stream)
{
struct _mapfile_stream *mfs = stream->owner;
if (mfs->ptr)
int err = 0;
if (mfs && mfs->ptr)
{
if (munmap (mfs->ptr, mfs->size) != 0)
return errno;
mfs->ptr = NULL;
err = errno;
if (close (mfs->fd) != 0)
return errno;
err = errno;
mfs->ptr = NULL;
mfs->fd = -1;
}
return 0;
return err;
}
static int
......@@ -227,9 +235,12 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags)
int mflag, flg;
struct stat st;
(void)port; /* shutup gcc */
(void)port; /* Ignored. */
if (mfs == NULL)
return EINVAL;
/* map the flags to the system equivalent */
/* Map the flags to the system equivalent */
if (flags & MU_STREAM_WRITE)
{
mflag = PROT_WRITE;
......
......@@ -22,13 +22,13 @@ mailbox_create_default (mailbox_t *pmbox, const char *mail)
if (mail)
{
/* is it a fullpath ? */
/* Is it a fullpath ? */
if (mail[0] != '/')
{
/* is it a URL ? */
/* Is it a URL ? */
if (strchr (mail, ':') == NULL)
{
/* a user name */
/* A user name. */
user = mail;
mail = NULL;
}
......@@ -44,7 +44,7 @@ mailbox_create_default (mailbox_t *pmbox, const char *mail)
user = (getenv ("LOGNAME")) ? getenv ("LOGNAME") : getenv ("USER");
if (user == NULL)
{
fprintf (stderr, "who am I?\n");
fprintf (stderr, "Who am I ?\n");
return EINVAL;
}
}
......
......@@ -63,28 +63,28 @@ static int mailbox_pop_body_size (body_t, size_t *psize);
/* According to the rfc:
* RFC 2449 POP3 Extension Mechanism November 1998
RFC 2449 POP3 Extension Mechanism November 1998
* 4. Parameter and Response Lengths
4. Parameter and Response Lengths
* This specification increases the length restrictions on commands and
* parameters imposed by RFC 1939.
This specification increases the length restrictions on commands and
parameters imposed by RFC 1939.
* The maximum length of a command is increased from 47 characters (4
* character command, single space, 40 character argument, CRLF) to 255
* octets, including the terminating CRLF.
The maximum length of a command is increased from 47 characters (4
character command, single space, 40 character argument, CRLF) to 255
octets, including the terminating CRLF.
* Servers which support the CAPA command MUST support commands up to
* 255 octets. Servers MUST also support the largest maximum command
* length specified by any supported capability.
Servers which support the CAPA command MUST support commands up to
255 octets. Servers MUST also support the largest maximum command
length specified by any supported capability.
* The maximum length of the first line of a command response (including
* the initial greeting) is unchanged at 512 octets (including the
* terminating CRLF).
*/
The maximum length of the first line of a command response (including
the initial greeting) is unchanged at 512 octets (including the
terminating CRLF). */
/* buffered IO */
struct _bio {
struct _bio
{
#define POP_BUFSIZ 512
int fd;
size_t maxlen;
......@@ -150,7 +150,7 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name)
size_t name_len;
int status;
/* sanity check */
/* Sanity check. */
if (pmbox == NULL || name == NULL || *name == '\0')
return MU_ERROR_INVALID_ARG;
......@@ -160,7 +160,7 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name)
#define POP_SCHEME_LEN 6
#define SEPARATOR '/'
/* skip the url scheme */
/* Skip the url scheme. */
if (name_len > POP_SCHEME_LEN &&
(name[0] == 'p' || name[0] == 'P') &&
(name[1] == 'o' || name[1] == 'O') &&
......@@ -171,12 +171,12 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name)
name_len -= POP_SCHEME_LEN;
}
/* allocate memory for mbox */
/* Allocate memory for mbox. */
mbox = calloc (1, sizeof (*mbox));
if (mbox == NULL)
return MU_ERROR_OUT_OF_MEMORY;
/* allocate specific pop box data */
/* Allocate specific pop box data. */
mpd = mbox->data = calloc (1, sizeof (*mpd));
if (mbox->data == NULL)
{
......@@ -184,7 +184,7 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name)
return MU_ERROR_OUT_OF_MEMORY;
}
/* allocate the struct for buffered I/O */
/* Allocate the struct for buffered I/O. */
status = bio_create (&(mpd->bio), -1);
if (status != 0)
{
......@@ -192,7 +192,7 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name)
return status;
}
/* copy the name */
/* Copy the name. */
mbox->name = calloc (name_len + 1, sizeof (char));
if (mbox->name == NULL)
{
......@@ -202,19 +202,19 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name)
memcpy (mbox->name, name, name_len);
#ifdef HAVE_PHTREAD_H
/* mutex when accessing the structure fields */
/* FIXME: should we use rdwr locks instead ?? */
/* Mutex when accessing the structure fields. */
/* FIXME: should we use rdwr locks instead ?? */
pthread_mutex_init (&(mud->mutex), NULL);
#endif
/* initialize the structure */
/* Initialize the structure. */
mbox->_create = mailbox_pop_create;
mbox->_destroy = mailbox_pop_destroy;
mbox->_open = mailbox_pop_open;
mbox->_close = mailbox_pop_close;
/* messages */
/* Messages. */
mbox->_get_message = mailbox_pop_get_message;
mbox->_messages_count = mailbox_pop_messages_count;
mbox->_expunge = mailbox_pop_expunge;
......@@ -227,7 +227,7 @@ mailbox_pop_create (mailbox_t *pmbox, const char *name)
(*pmbox) = mbox;
return 0; /* okdoke */
return 0; /* Okdoke. */
}
static void
......@@ -328,11 +328,11 @@ mailbox_pop_open (mailbox_t mbox, int flags)
char host[256] ;
long port;
/* sanity checks */
/* Sanity checks. */
if (mbox == NULL || mbox->url == NULL || (mpd = mbox->data) == NULL)
return EINVAL;
/* create the networking stack */
/* Create the networking stack. */
if (!mbox->stream)
{
if ((status = url_get_host (mbox->url, host, sizeof(host), NULL)) != 0 ||
......@@ -345,20 +345,20 @@ mailbox_pop_open (mailbox_t mbox, int flags)
}
}
/* flag busy */
/* Flag busy. */
if (mpd->func && mpd->func != func)
return EBUSY;
mpd->func = func;
bio = mpd->bio;
/* spawn the prologue */
/* Spawn the prologue. */
if (mbox->auth)
auth_prologue (mbox->auth);
/* enter the state machine */
/* Enter the state machine. */
switch (mpd->state)
{
/* establish the connection */
/* Establish the connection. */
case 0:
status = stream_open (mbox->stream, host, port, flags);
if (status != 0)
......@@ -370,11 +370,11 @@ mailbox_pop_open (mailbox_t mbox, int flags)
}
return status;
}
/* get the fd */
/* Get the fd. */
stream_get_fd (mbox->stream, &fd);
mpd->bio->fd = mpd->fd = fd;
mpd->state = 1;
/* glob the Greetings */
/* Glob the greetings. */
case 1:
status = bio_readline (bio);
if (status != 0)
......@@ -394,8 +394,8 @@ mailbox_pop_open (mailbox_t mbox, int flags)
mpd->bio->fd = -1;
return EACCES;
}
/* Dealing whith Authentication */
/* so far only normal user/pass supported */
/* Dealing whith Authentication. */
/* So far only normal user/pass supported. */
if (mbox->auth == NULL)
{
status = auth_create (&(mbox->auth), mbox);
......@@ -409,14 +409,14 @@ mailbox_pop_open (mailbox_t mbox, int flags)
}
auth_authenticate (mbox->auth, &mpd->user, &mpd->passwd);
/* FIXME use snprintf */
/* FIXME: Use snprintf. */
//mpd->len = sprintf (pop->buffer, POP_BUFSIZ, "USER %s\r\n", user);
bio->len = sprintf (bio->buffer, "USER %s\r\n", mpd->user);
bio->ptr = bio->buffer;
mailbox_debug (mbox, MU_MAILBOX_DEBUG_PROT, bio->buffer);
free (mpd->user); mpd->user = NULL;
mpd->state = 2;
/* send username */
/* Send username. */
case 2:
status = bio_write (bio);
if (status != 0)
......@@ -429,7 +429,7 @@ mailbox_pop_open (mailbox_t mbox, int flags)
return status;
}
mpd->state = 3;
/* get the ack */
/* Get the ack. */
case 3:
status = bio_readline (bio);
if (status != 0)
......@@ -445,14 +445,14 @@ mailbox_pop_open (mailbox_t mbox, int flags)
if (strncasecmp (bio->buffer, "+OK", 3) != 0)
return EACCES;
/* FIXME use snprintf */
/* FIXME Use snprintf. */
//mpd->len = snprintf (mpd->buffer, POP_BUFSIZ, "PASS %s\r\n", passwd);
bio->len = sprintf (bio->buffer, "PASS %s\r\n", mpd->passwd);
bio->ptr = bio->buffer;
mailbox_debug (mbox, MU_MAILBOX_DEBUG_PROT, bio->buffer);
free (mpd->passwd); mpd->passwd = NULL;
mpd->state = 4;
/* send Passwd */
/* Send passwd. */
case 4:
status = bio_write (bio);
if (status != 0)
......@@ -465,7 +465,7 @@ mailbox_pop_open (mailbox_t mbox, int flags)
return status;
}
mpd->state = 5;
/* get the ack from passwd */
/* Get the ack from passwd. */
case 5:
status = bio_readline (bio);
if (status != 0)
......@@ -480,13 +480,13 @@ mailbox_pop_open (mailbox_t mbox, int flags)
mailbox_debug (mbox, MU_MAILBOX_DEBUG_PROT, bio->buffer);
if (strncasecmp (bio->buffer, "+OK", 3) != 0)
return EACCES;
}/* swith state */
}/* Swith state. */
/* spawn cleanup functions */
/* Spawn cleanup functions. */
if (mbox->auth)
auth_epilogue (mbox->auth);
/* clear any state */
/* Clear any state. */
mpd->func = NULL;
mpd->state = 0;
......@@ -564,11 +564,11 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
size_t i;
void *func = (void *)mailbox_pop_get_message;
/* sanity */
/* Sanity. */
if (mbox == NULL || pmsg == NULL || (mpd = mbox->data) == NULL)
return EINVAL;
/* see if we already have this message */
/* See if we already have this message. */
for (i = 0; i < mpd->pmessages_count; i++)
{
if (mpd->pmessages[i])
......@@ -581,7 +581,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
}
}
/* are we busy in another function ? */
/* Are we busy in another function ? */
if (mpd->func && mpd->func != func)
return EBUSY;
......@@ -592,10 +592,10 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
mpd->func = func;
bio = mpd->bio;
/* Ok men, we're going in */
/* Ok men, we're going in. */
switch (mpd->state)
{
/* the message */
/* The message. */
case 0:
{
message_t msg;
......@@ -605,7 +605,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
if (mpm == NULL)
return ENOMEM;
/* we'll use the bio to store headers */
/* We'll use the bio to store headers. */
mpm->bio = calloc (1, sizeof (*(mpm->bio)));
if (mpm->bio == NULL)
{
......@@ -614,7 +614,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
return ENOMEM;
}
/* create the message */
/* Create the message. */
status = message_create (&msg, mpm);
if (status != 0)
{
......@@ -624,7 +624,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
return status;
}
/* the message */
/* The message. */
mpm->message = msg;
mpm->num = msgno;
mpd->mpm = mpm;
......@@ -633,20 +633,18 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
/* set the busy request state */
mpd->id = (void *)msg;
/*
* Get the header.
* FIXME: TOP is an optionnal command, if we want to
* be compliant we can not count on it to exists.
* So we should be prepare when it fails and fall to
* a second scheme
*/
/* Get the header.
FIXME: TOP is an optionnal command, if we want to
be compliant we can not count on it to exists.
So we should be prepare when it fails and fall to
a second scheme. */
/*bio->len = snprintf (bio->buffer, POP_BUFSIZ, "TOP %d 0\r\n", msgno);*/
bio->len = sprintf (bio->buffer, "TOP %d 0\r\n", msgno);
bio->ptr = bio->buffer;
mailbox_debug (mbox, MU_MAILBOX_DEBUG_PROT, bio->buffer);
mpd->state = 1;
}
/* send the TOP */
/* Send the TOP. */
case 1:
{
status = bio_write (bio);
......@@ -665,7 +663,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
}
mpd->state = 2;
}
/* ack from TOP */
/* Ack from TOP. */
case 2:
{
status = bio_readline (bio);
......@@ -695,7 +693,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
}
}
mpd->state = 5;
/* get the header */
/* Get the header. */
case 5:
{
char *tbuf;
......@@ -705,7 +703,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
status = bio_readline (bio);
if (status != 0)
{
/* recoverable */
/* Recoverable. */
if (status != EAGAIN && status != EINTR)
{
mpd->func = mpd->id = NULL;
......@@ -718,7 +716,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
return status;
}
/* our ticket out */
/* Our ticket out. */
if (bio->buffer[0] == '\0')
break;
......@@ -745,15 +743,15 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
} /* case 5: */
break;
default:
/* error here unknow case */
/* Error here unknow case. */
fprintf (stderr, "Pop unknown state(get_message)\n");
} /* switch (state) */
/* no need to carry a state anymore */
/* No need to carry a state anymore. */
mpd->func = mpd->id = NULL;
mpd->state = 0;
/* create the header */
/* Create the header. */
{
header_t header;
status = header_create (&header, mpd->mpm->bio->buffer,
......@@ -769,10 +767,10 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
message_set_header ((mpd->mpm->message), header, mpd->mpm);
}
/* reallocate the working buffer */
/* Reallocate the working buffer. */
bio_create (&(mpd->mpm->bio), mpd->fd);
/* create the attribute */
/* Create the attribute. */
{
attribute_t attribute;
char hdr_status[64];
......@@ -780,7 +778,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
hdr_status[0] = '\0';
message_get_header (mpd->mpm->message, &header);
header_get_value (header, "Status", hdr_status, sizeof (hdr_status), NULL);
/* create the attribute */
/* Create the attribute. */
status = string_to_attribute (hdr_status, &attribute);
if (status != 0)
{
......@@ -793,7 +791,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
message_set_attribute (mpd->mpm->message, attribute, mpd->mpm);
}
/* create the body */
/* Create the body. */
{
stream_t stream;
body_t body;
......@@ -824,7 +822,7 @@ mailbox_pop_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
body_set_stream (body, stream, mpd->mpm);
}
/* add it to the list */
/* Add it to the list. */
{
mailbox_pop_message_t *m ;
m = realloc (mpd->pmessages, (mpd->pmessages_count + 1)*sizeof (*m));
......@@ -875,13 +873,13 @@ mailbox_pop_messages_count (mailbox_t mbox, size_t *pcount)
bio->ptr = bio->buffer;
mailbox_debug (mbox, MU_MAILBOX_DEBUG_PROT, bio->buffer);
mpd->state = 1;
/* Send the STAT */
/* Send the STAT. */
case 1:
status = bio_write (bio);
if (status != 0)
return status;
mpd->state = 2;
/* get the ACK */
/* Get the ACK. */
case 2:
status = bio_readline (bio);
if (status != 0)
......@@ -905,7 +903,7 @@ mailbox_pop_messages_count (mailbox_t mbox, size_t *pcount)
}
/* update and scanning*/
/* Update and scanning. */
static int
mailbox_pop_is_updated (mailbox_t mbox)
{
......@@ -938,7 +936,7 @@ mailbox_pop_num_deleted (mailbox_t mbox, size_t *pnum)
return 0;
}
/* We just simulated */
/* We just simulated. */
static int
mailbox_pop_scan (mailbox_t mbox, size_t msgno, size_t *pcount)
{
......@@ -953,7 +951,7 @@ mailbox_pop_scan (mailbox_t mbox, size_t msgno, size_t *pcount)
return 0;
}
/* This were we actually sending the DELE command */
/* This were we actually sending the DELE command. */
static int
mailbox_pop_expunge (mailbox_t mbox)
{
......@@ -968,7 +966,7 @@ mailbox_pop_expunge (mailbox_t mbox)
(mpd = (mailbox_pop_data_t) mbox->data) == NULL)
return EINVAL;
/* busy ? */
/* Busy ? */
if (mpd->func && mpd->func != func)
return EBUSY;
......@@ -979,7 +977,7 @@ mailbox_pop_expunge (mailbox_t mbox)
{
if (message_get_attribute (mpd->pmessages[i]->message, &attr) == 0)
{
/* send DELETE */
/* Send DELETE. */
if (attribute_is_deleted (attr))
{
switch (mpd->state)
......@@ -1030,13 +1028,13 @@ mailbox_pop_expunge (mailbox_t mbox)
} /* for */
mpd->func = mpd->id = NULL;
mpd->state = 0;
/* invalidate */
/* Invalidate. */
mpd->is_updated = 0;
return 0;
}
/* mailbox size ? */
/* Mailbox size ? */
static int
mailbox_pop_size (mailbox_t mbox, off_t *psize)
{
......@@ -1106,11 +1104,11 @@ mailbox_pop_readstream (stream_t is, char *buffer, size_t buflen,
bio = mpm->bio;
mpd = mpm->mpd;
/* busy ? */
/* Busy ? */
if (mpd->func && mpd->func != func)
return EBUSY;
/* which request */
/* Which request. */
if (mpd->id && mpd->id != mpm)
return EBUSY;
......@@ -1119,7 +1117,7 @@ mailbox_pop_readstream (stream_t is, char *buffer, size_t buflen,
switch (mpd->state)
{
/* send the RETR command */
/* Send the RETR command. */
case 0:
bio->len = sprintf (bio->buffer, "RETR %d\r\n", mpm->num);
mpd->state = 1;
......@@ -1135,7 +1133,7 @@ mailbox_pop_readstream (stream_t is, char *buffer, size_t buflen,
return status;
}
mpd->state = 2;
/* RETR ACK */
/* RETR ACK. */
case 2:
status = bio_readline (bio);
if (status != 0)
......@@ -1150,7 +1148,7 @@ mailbox_pop_readstream (stream_t is, char *buffer, size_t buflen,
if (strncasecmp (bio->buffer, "+OK", 3) != 0)
return EINVAL;
mpd->state = 3;
/* skip the header */
/* Skip the header. */
case 3:
while (!mpm->inbody)
{
......@@ -1170,15 +1168,15 @@ mailbox_pop_readstream (stream_t is, char *buffer, size_t buflen,
break;
}
}
/* skip the newline */
/* Skip the newline. */
bio_readline (bio);
/* start taking the header */
/* Start taking the header. */
mpd->state = 4;
bio->current = bio->buffer;
case 4:
{
int nleft, n;
/* do we need to fill up */
/* Do we need to fill up. */
if (bio->current >= bio->nl)
{
bio->current = bio->buffer;
......@@ -1194,7 +1192,7 @@ mailbox_pop_readstream (stream_t is, char *buffer, size_t buflen,
}
n = bio->nl - bio->current;
nleft = buflen - n;
/* we got more then requested */
/* We got more then requested. */
if (nleft <= 0)
{
memcpy (buffer, bio->current, buflen);
......@@ -1203,13 +1201,13 @@ mailbox_pop_readstream (stream_t is, char *buffer, size_t buflen,
}
else
{
/* drain the buffer */
/* Drain the buffer. */
memcpy (buffer, bio->current, n);
bio->current += n;
nread = n;
}
}
} /* switch state */
} /* Switch state. */
if (nread == 0)
{
......@@ -1291,14 +1289,12 @@ bio_read (bio_t bio)
return 0;
}
/*
* Responses to certain commands are multi-line. In these cases, which
* are clearly indicated below, after sending the first line of the
* response and a CRLF, any additional lines are sent, each terminated
* by a CRLF pair. When all lines of the response have been sent, a
* final line is sent, consisting of a termination octet (decimal code
* 046, ".") and a CRLF pair.
*/
/* Responses to certain commands are multi-line. In these cases, which
are clearly indicated below, after sending the first line of the
response and a CRLF, any additional lines are sent, each terminated
by a CRLF pair. When all lines of the response have been sent, a
final line is sent, consisting of a termination octet (decimal code
046, ".") and a CRLF pair. */
static int
bio_readline (bio_t bio)
{
......@@ -1323,7 +1319,7 @@ bio_readline (bio_t bio)
if (status < 0)
return status;
len = bio->ptr - bio->buffer;
/* a newline */
/* Newline. */
bio->nl = memchr (bio->buffer, '\n', len);
if (bio->nl == NULL)
{
......@@ -1344,12 +1340,10 @@ bio_readline (bio_t bio)
}
}
/*
* When examining a multi-line response, the client checks
* to see if the line begins with the termination octet "."(DOT).
* If so and if octets other than CRLF follow, the first octet
* of the line (the termination octet) is stripped away.
*/
/* When examining a multi-line response, the client checks
to see if the line begins with the termination octet "."(DOT).
If so and if octets other than CRLF follow, the first octet
of the line (the termination octet) is stripped away. */
if (bio->buffer[0] == '.')
{
if (bio->buffer[1] != '\r' && bio->buffer[2] != '\n')
......@@ -1359,10 +1353,9 @@ bio_readline (bio_t bio)
bio->nl--;
}
/* If so and if CRLF immediately
* follows the termination character, then the response from the POP
* server is ended and the line containing ".CRLF" is not considered
* part of the multi-line response.
*/
follows the termination character, then the response from the POP
server is ended and the line containing ".CRLF" is not considered
part of the multi-line response. */
else if (bio->buffer[1] == '\r' && bio->buffer[2] == '\n')
{
bio->buffer[0] = '\0';
......@@ -1371,7 +1364,7 @@ bio_readline (bio_t bio)
}
}
/* \r\n --> \n\0 */
/* \r\n --> \n\0 */
if (bio->nl > bio->buffer)
{
*(bio->nl - 1) = '\n';
......