Commit 36d9df9d 36d9df9d53122a0d0009ff0a73df40cb9e013065 by Sean 'Shaleh' Perry

cleaned up unixmbox.c and mailbox.c

added optional argument to from.c
added items to TODO
added Makefile for from.c in examples
1 parent 6cfd1a84
Sean 'Shaleh' Perry <shaleh@debian.org> Fri, 8 Oct 1999 01:08:42 -0700
* fixed the "if empty mailbox, return not implemented"
NB: seems there was a large assumption being made:
if unixmbox_open() failed, it was because it was not mbox
this was wrong for many reasons, so on actual "not mbox", return EBADMSG.
Prolly want to come up with a better error, but this works for now
* more cleaning in the mailbox code
a) added stat() call -- we can bomb earlier, plus detect if passed object
is a directory or file
b) unixmbox_close() free()'s mbox. This will hamper the use when we add
support for more mailboxes later. Need to find a solution. Perhaps
a unixmbox_free() call.
There was also a small leak there -- mbox->name was being left.
c) To aid checking in unixbox_open(), added checks around fgets call.
Now properly detects EOF, errors, etc. This was a large cause of the
spurious "not implemented" bug.
d) all of unixmbox_open()'s function calls should now be checked
NB: need to do the same for rest of file
Sean 'Shaleh' Perry <shaleh@debian.org> Thu, 7 Oct 1999 22:33:24 -0700
* removed spurious code in from.c
......
+ --> fixed/done
- --> pending
= --> on hold
* --> in progress
- autogen.sh (libtool) complains about libmailbox.la in noinst
- libmailbox has a nasty bug -- if the mailbox is empty, the library has no idea
+ libmailbox has a nasty bug -- if the mailbox is empty, the library has no idea
what to do
- libmailbox needs an interface to set flags for each message
- libmailbox needs an interface to set and create values in the header
- crypt is linked even if pam was detected, it should be one or the other
- test daemon code
......
CFLAGS = -Wall -pedantic -g
INCLUDES = -I../libmailbox
LIBS = ../libmailbox/.libs/libmailbox.al
from: from.c $(LIBS)
gcc $(CFLAGS) $(INCLUDES) -o from from.c $(LIBS)
clean:
rm -f from
......@@ -22,23 +22,32 @@ int main(int argc, char *argv[]) {
fprintf(stderr, "who am I?\n");
exit(-1);
}
if (!strcmp(user, "root") && argc == 2)
user = argv[1];
else if (argc > 2)
{
fprintf(stderr,
"Usage: from [username] (argument valid when ran as root)\n");
exit(-1);
}
snprintf (mailpath, 256, "%s/%s", _PATH_MAILDIR, user);
mail = mbox_open(mailpath);
if( mail == NULL ) {
perror("mbox_open: ");
perror("mbox_open");
exit(-1);
}
for(i = 0; i < mail->messages; ++i) {
from = mbox_header_line(mail, i, "From");
if (from == NULL)
{
perror("mbox_header_line: ");
perror("mbox_header_line");
exit(-1);
}
date = mbox_header_line(mail, i, "Date");
if (date == NULL)
{
perror("mbox_header_line: ");
perror("mbox_header_line");
exit(-1);
}
printf("%s %s\n", from, date);
......
......@@ -26,6 +26,9 @@
#include <errno.h>
#endif
#include <sys/stat.h>
#include <unistd.h>
int _mbox_dummy1 (mailbox * mbox);
int _mbox_dummy2 (mailbox * mbox, unsigned int num);
int _mbox_dummy3 (mailbox * mbox, char *c);
......@@ -35,6 +38,7 @@ mailbox *
mbox_open (const char *name)
{
mailbox *mbox;
struct stat st;
if ( name == NULL )
{
......@@ -57,6 +61,14 @@ mbox_open (const char *name)
free (mbox);
return NULL;
}
/* check if we can look at file, prep for checks later in function */
if (stat (mbox->name, &st) == -1)
{
free (mbox->name);
free (mbox);
return NULL; /* errno set by stat() */
}
mbox->messages = 0;
mbox->num_deleted = 0;
mbox->sizes = NULL;
......@@ -71,27 +83,38 @@ mbox_open (const char *name)
mbox->_get_body = _mbox_dummy4;
mbox->_get_header = _mbox_dummy4;
if (unixmbox_open (mbox) == 0)
return mbox;
else
if (S_ISDIR (st.st_mode))
{
/*
* Check errno to find out why it failed, if it's simply not a
* unix mbox format message, then try other mailbox types,
* otherwise, leave errno set and return NULL
/* for example...
if (maildir_open (mbox, name) == 1)
return mbox;
else if (errno != 0)
return NULL;
else
errno = 0;
*/
errno = ENOSYS;
}
else if (S_ISREG (st.st_mode))
{
if (unixmbox_open (mbox) == 0)
return mbox;
else
{
/*
* Check errno to find out why it failed, if it's simply not a
* unix mbox format message, then try other mailbox types,
* otherwise, leave errno set and return NULL
*/
if (errno == EBADMSG)
errno = ENOSYS; /* no other mailboxes supported right now */
}
}
else
errno = EINVAL; /* neither directory nor file, so bomb */
/* for example...
if (maildir_open (mbox, name) == 1)
return mbox;
else if (errno != 0)
return NULL;
else
errno = 0;
*/
errno = ENOSYS;
free (mbox->name);
free (mbox);
return NULL;
}
......
......@@ -38,10 +38,8 @@
#define mbox_lock(m,n) m->_lock(m,n)
/* Lock settings */
/*
* define this way so that it is opaque and can later become a struct w/o
/* define this way so that it is opaque and can later become a struct w/o
* people noticing (-:
*
*/
enum _mailbox_lock_t {MO_ULOCK, MO_RLOCK, MO_WLOCK}; /* new type */
typedef enum _mailbox_lock_t mailbox_lock_t;
......
......@@ -64,12 +64,18 @@ unixmbox_open (mailbox * mbox)
return -1;
}
fgets (buf, 80, data->file);
if (fgets (buf, 80, data->file) == NULL)
{
if (feof(data->file))
goto END; /* empty file, no messages */
unixmbox_close (mbox);
return -1;
}
if (strncmp (buf, "From ", 5))
{
/* This is NOT an mbox file */
unixmbox_close (mbox);
errno = 0;
errno = EBADMSG; /* use this to signify wrong mbox type */
return -1;
}
......@@ -79,7 +85,13 @@ unixmbox_open (mailbox * mbox)
{
/* Beginning of a header */
while (strchr (buf, '\n') == NULL)
fgets (buf, 80, data->file); /* eat the From line */
if (fgets (buf, 80, data->file) == NULL) /* eat the From line */
{
if (feof (data->file))
errno = EIO; /* corrupted mailbox? */
unixmbox_close (mbox);
return -1;
}
mbox->messages++;
......@@ -117,6 +129,13 @@ unixmbox_open (mailbox * mbox)
}
while (fgets (buf, 80, data->file));
if (!feof (data->file)) /* stopped due to error, not EOF */
{
unixmbox_close (mbox);
return -1; /* errno is set */
}
END:
mbox->_close = unixmbox_close;
mbox->_delete = unixmbox_delete;
mbox->_undelete = unixmbox_undelete;
......@@ -149,7 +168,6 @@ unixmbox_close (mailbox * mbox)
free (data->messages);
free (mbox->sizes);
free (data);
free (mbox);
return 0;
}
......