Commit 0d65dd09 0d65dd09b50588c3546bfe2a4131bd10fdd77a8f by Alain Magloire

Another big change we're trying, for the future to be able to load

via dlopen() different type of mailboxes and mailer.  For that
the client must register the mailbox.  So in the future
we can have something like plugin  ... still a hack/draft.

Commited some code to be able to send mail with sendmail or
via SMTP.
1 parent 9924892e
......@@ -145,41 +145,61 @@ int message_save_attachment(message_t msg, const char *filename, void **data)
if ( ret == 0 && ( ret = _attachment_setup( &info, msg, &stream, data) ) != 0 )
return ret;
if ( ret != EAGAIN && info )
_attachment_free(info, ret);
return ret;
}
#if 0
int message_encapsulate(message_t msg, message_t *newmsg, void **data)
{
stream_t stream;
char *header;
stream_t istream, ostream;
const char *header;
struct _msg_info *info = NULL;
int ret;
int ret = 0;
size_t nbytes;
body_t body;
if ( msg == NULL || newmsg == NULL)
return EINVAL;
if ( ( ret = message_create(&(info->msg), NULL) ) == 0 ) {
if ( ( ret = _attachment_setup( &info, msg, &ostream, data) ) != 0 )
return ret;
if ( info->msg == NULL && ( ret = message_create(&(info->msg), NULL) ) == 0 ) {
header = "Content-Type: message/rfc822\nContent-Transfer-Encoding: 7bit\n\n";
if ( ( ret = header_create( &(info->hdr), header, strlen(header), msg ) ) == 0 ) {
message_set_header(info->msg, info->hdr, NULL);
if ( ( ret = header_create( &(info->hdr), header, strlen(header), msg ) ) == 0 )
ret = message_set_header(info->msg, info->hdr, NULL);
}
if ( ret == 0 && ( ret = message_get_stream(msg, &istream ) ) == 0 ) {
if ( ( ret = message_get_body(info->msg, &body) ) == 0 &&
( ret = body_get_stream(body, &ostream) ) == 0 ) {
if ( info->nbytes )
memmove( info->buf, info->buf + (BUF_SIZE - info->nbytes), info->nbytes);
while ( (ret == 0 && info->nbytes) || ( ( ret = stream_read(istream, info->buf, BUF_SIZE, info->ioffset, &info->nbytes) ) == 0 && info->nbytes ) ) {
info->ioffset += info->nbytes;
while( info->nbytes ) {
if ( ( ret = stream_write(ostream, info->buf, info->nbytes, info->ooffset, &nbytes ) ) != 0 )
break;
info->nbytes -= nbytes;
info->ooffset += nbytes;
}
}
}
}
if ( ret == 0 )
*newmsg = info->msg;
if ( ret != EAGAIN && info )
_attachment_free(info, ret);
return ret;
}
#endif
/* If the message interface parsed headers on write this would be easy */
int message_unencapsulate(message_t msg, message_t *newmsg, void **data)
{
size_t size, nbytes;
int ret = 0, header_done = 0;
char *content_type, *cp;
int ret = 0;
char *content_type;
header_t hdr;
body_t body;
stream_t istream, ostream;
struct _msg_info *info = NULL;
......@@ -190,60 +210,22 @@ int message_unencapsulate(message_t msg, message_t *newmsg, void **data)
header_get_value(hdr, "Content-Type", NULL, 0, &size);
if ( size ) {
if ( ( content_type = alloca(size+1) ) == NULL )
ret = ENOMEM;
return ENOMEM;
header_get_value(hdr, "Content-Type", content_type, size+1, 0);
if ( strncasecmp(content_type, "message/rfc822", strlen(content_type)) != 0 )
ret = EINVAL;
return EINVAL;
} else
return EINVAL;
}
if ( ret == 0 && ( ret = _attachment_setup( &info, msg, &istream, data) ) != 0 )
if ( ( ret = _attachment_setup( &info, msg, &istream, data) ) != 0 )
return ret;
if ( ret == 0 && info->hdr == NULL ) {
while ( !header_done && ( ret = stream_read(istream, info->buf, BUF_SIZE, info->ioffset, &info->nbytes) ) == 0 && info->nbytes ) {
cp = info->buf;
while ( info->nbytes && !header_done ) {
info->line[info->line_ndx] = *cp;
info->line_ndx++;
if ( *cp == '\n' ) {
if ( info->header_len + info->line_ndx > info->header_size) {
char *nhb;
if ( ( nhb = realloc( info->header_buf, info->header_len + info->line_ndx + 128 ) ) == NULL ) {
header_done = 1;
ret = ENOMEM;
break;
}
info->header_buf = nhb;
info->header_size = info->header_len + info->line_ndx + 128;
}
info->header_len += info->line_ndx;
memcpy(info->header_buf, info->line, info->line_ndx);
if ( info->line_ndx == 1 ) {
header_done = 1;
break;
}
info->line_ndx = 0;
}
if ( info->line_ndx == MAX_HDR_LEN ) /* prevent overflow */
info->line_ndx--;
info->ioffset++;
info->nbytes--;
cp++;
}
}
}
if ( ret == 0 && info->msg == NULL ) {
if ( ( ret = message_create(&(info->msg), NULL) ) == 0)
if ( ( ret = header_create(&(info->hdr), info->header_buf, info->header_len, info->msg) ) == 0 )
ret = message_set_header(info->msg, hdr, NULL);
}
if ( info->msg == NULL )
ret = message_create(&(info->msg), NULL);
if ( ret == 0 ) {
message_get_body(info->msg, &body);
body_get_stream( body, &ostream);
message_get_stream(info->msg, &ostream);
if ( info->nbytes )
memmove( info->buf, info->buf + (BUF_SIZE - info->nbytes), info->nbytes);
while ( info->nbytes || ( ( ret = stream_read(istream, info->buf, BUF_SIZE, info->ioffset, &info->nbytes) ) == 0 && info->nbytes ) ) {
while ( (ret == 0 && info->nbytes) || ( ( ret = stream_read(istream, info->buf, BUF_SIZE, info->ioffset, &info->nbytes) ) == 0 && info->nbytes ) ) {
info->ioffset += info->nbytes;
while( info->nbytes ) {
if ( ( ret = stream_write(ostream, info->buf, info->nbytes, info->ooffset, &nbytes ) ) != 0 )
......@@ -253,6 +235,8 @@ int message_unencapsulate(message_t msg, message_t *newmsg, void **data)
}
}
}
if ( ret == 0 )
*newmsg = info->msg;
if ( ret != EAGAIN && info )
_attachment_free(info, ret);
return ret;
......
......@@ -14,6 +14,9 @@
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <stdlib.h>
......@@ -50,6 +53,12 @@ attribute_destroy (attribute_t *pattr, void *owner)
return;
}
void *
attribute_get_owner (attribute_t attr)
{
return (attr) ? attr->owner : NULL;
}
int
attribute_get_flags (attribute_t attr, int *pflags)
{
......
......@@ -14,96 +14,206 @@
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>
#include <mailutils/mailbox.h>
#include <auth0.h>
#include <cpystr.h>
#include <misc.h>
static void
echo_off(struct termios *stored_settings)
{
struct termios new_settings;
tcgetattr (0, stored_settings);
new_settings = *stored_settings;
new_settings.c_lflag &= (~ECHO);
tcsetattr (0, TCSANOW, &new_settings);
}
static void
echo_on(struct termios *stored_settings)
{
tcsetattr (0, TCSANOW, stored_settings);
}
int
auth_create (auth_t *pauth, void *owner)
ticket_create (ticket_t *pticket, void *owner)
{
auth_t auth;
if (pauth == NULL)
ticket_t ticket;
if (pticket == NULL)
return EINVAL;
auth = calloc (1, sizeof (*auth));
if (auth == NULL)
ticket = calloc (1, sizeof (*ticket));
if (ticket == NULL)
return ENOMEM;
auth->owner = owner;
*pauth = auth;
ticket->owner = owner;
*pticket = ticket;
return 0;
}
void
auth_destroy (auth_t *pauth, void *owner)
ticket_destroy (ticket_t *pticket, void *owner)
{
if (pauth && *pauth)
if (pticket && *pticket)
{
auth_t auth = *pauth;
if (auth->owner == owner)
free (auth);
*pauth = NULL;
ticket_t ticket = *pticket;
if (ticket->owner == owner)
{
if (ticket->type)
free (ticket->type);
free (ticket);
}
}
*pticket = NULL;
}
void *
ticket_get_owner (ticket_t ticket)
{
return (ticket) ? ticket->owner : NULL;
}
int
auth_set_authenticate (auth_t auth,
int (*_authenticate)(auth_t, char **, char **),
void *owner)
ticket_pop (ticket_t ticket, const char *challenge, char **parg)
{
if (auth == NULL)
if (ticket == NULL || parg == NULL)
return EINVAL;
if (auth->owner != owner)
return EPERM;
auth->_authenticate = _authenticate;
if (ticket->_pop)
return ticket->_pop (ticket, challenge, parg);
else
{
char arg[256];
struct termios stored_settings;
int echo = 1;
/* Being smart if we see "Passwd" and turning off echo. */
if (strstr (challenge, "ass") != NULL
|| strstr (challenge, "ASS") != NULL)
echo = 0;
printf ("%s", challenge);
fflush (stdout);
if (!echo)
echo_off (&stored_settings);
fgets (arg, sizeof (arg), stdin);
if (!echo)
echo_on (&stored_settings);
arg [strlen (arg) - 1] = '\0'; /* nuke the trailing line. */
*parg = strdup (arg);
}
return 0;
}
int
ticket_get_type (ticket_t ticket, char *type, size_t len, size_t *pwriten)
{
size_t n;
if (ticket == NULL || type == NULL)
return EINVAL;
n = _cpystr (type, ticket->type, len);
if (pwriten)
*pwriten = n;
return 0;
}
int
auth_authenticate (auth_t auth, char **user, char **passwd)
ticket_set_type (ticket_t ticket, char *type)
{
if (auth == NULL || auth->_authenticate == NULL)
if (ticket == NULL)
return EINVAL;
return auth->_authenticate (auth, user, passwd);
ticket->type = strdup ((type) ? type : "");
return 0;
}
int
auth_set_epilogue (auth_t auth, int (*_epilogue)(auth_t), void *owner)
authority_create (authority_t *pauthority, ticket_t ticket, void *owner)
{
if (auth == NULL)
authority_t authority;
if (pauthority == NULL)
return EINVAL;
if (auth->owner != owner)
return EPERM;
auth->_epilogue = _epilogue;
authority = calloc (1, sizeof (*authority));
if (authority == NULL)
return ENOMEM;
authority->ticket = ticket;
authority->owner = owner;
*pauthority = authority;
return 0;
}
void
authority_destroy (authority_t *pauthority, void *owner)
{
if (pauthority && *pauthority)
{
authority_t authority = *pauthority;
if (authority->owner == owner)
{
ticket_destroy (&(authority->ticket), authority);
free (authority);
}
*pauthority = NULL;
}
}
void *
authority_get_owner (authority_t authority)
{
return (authority) ? authority->owner : NULL;
}
int
auth_epilogue (auth_t auth)
authority_set_ticket (authority_t authority, ticket_t ticket)
{
if (auth == NULL || auth->_epilogue == NULL)
if (authority == NULL)
return EINVAL;
return auth->_epilogue (auth);
ticket_destroy (&(authority->ticket), authority);
authority->ticket = ticket;
return 0;
}
int
auth_set_prologue (auth_t auth, int (*_prologue)(auth_t), void *owner)
authority_get_ticket (authority_t authority, ticket_t *pticket)
{
if (auth == NULL)
if (authority == NULL || pticket == NULL)
return EINVAL;
if (auth->owner != owner)
return EPERM;
auth->_prologue = _prologue;
if (authority->ticket == NULL)
{
int status = ticket_create (&(authority->ticket), authority);
if (status != 0)
return status;
}
*pticket = authority->ticket;
return 0;
}
int
authority_authenticate (authority_t authority)
{
if (authority && authority->_authenticate)
{
return authority->_authenticate (authority);
}
return 0;
}
int
auth_prologue (auth_t auth)
authority_set_authenticate (authority_t authority,
int (*_authenticate) __P ((authority_t)),
void *owner)
{
if (auth == NULL || auth->_prologue == NULL)
if (authority == NULL)
return EINVAL;
return auth->_prologue (auth);
if (authority->owner != owner)
return EACCES;
authority->_authenticate = _authenticate;
return 0;
}
......
......@@ -14,6 +14,9 @@
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <stdlib.h>
......@@ -187,7 +190,7 @@ bio_write (bio_t bio, const char *ptr, size_t n, size_t *pnwriten)
int
bio_readline (bio_t bio, char *ptr, size_t maxlen, size_t *pwriten)
{
int rc = 0;
size_t rc = 0;
size_t n = 0;
int err;
char c;
......
......@@ -14,6 +14,9 @@
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdio.h>
......@@ -21,8 +24,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <mailutils/stream.h>
#include <body0.h>
#include <stream0.h>
static int body_read (stream_t is, char *buf, size_t buflen,
......@@ -66,6 +69,12 @@ body_destroy (body_t *pbody, void *owner)
}
}
void *
body_get_owner (body_t body)
{
return (body) ? body->owner : NULL;
}
int
body_get_stream (body_t body, stream_t *pstream)
{
......@@ -182,10 +191,10 @@ static int
body_read (stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread )
{
body_t body;
body_t body = stream_get_owner (is);
size_t nread = 0;
if (is == NULL || (body = is->owner) == NULL)
if (body == NULL)
return EINVAL;
/* check if they want to read from a file */
......@@ -232,10 +241,10 @@ static int
body_write (stream_t os, const char *buf, size_t buflen,
off_t off, size_t *pnwrite)
{
body_t body;
body_t body = stream_get_owner (os);
size_t nwrite = 0;
if (os == NULL || (body = os->owner) == NULL)
if (body == NULL)
return EINVAL;
/* FIXME: security issues, Refuse to write to an unknow file */
......@@ -275,9 +284,9 @@ body_write (stream_t os, const char *buf, size_t buflen,
static int
body_get_fd (stream_t stream, int *pfd)
{
body_t body;
body_t body = stream_get_owner (stream);
if (stream == NULL || (body = stream->owner) == NULL)
if (body == NULL)
return EINVAL;
/* Probably being lazy, then create a body for the stream */
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <debug0.h>
int
debug_create (debug_t *pdebug, void *owner)
{
debug_t debug;
if (pdebug == NULL)
return EINVAL;
debug = calloc (sizeof (*debug), 1);
if (debug == NULL)
return ENOMEM;
debug->owner = owner;
*pdebug = debug;
return 0;
}
void
debug_destroy (debug_t *pdebug, void *owner)
{
if (pdebug && *pdebug)
{
debug_t debug = *pdebug;
if (debug->owner == owner)
{
free (*pdebug);
*pdebug = NULL;
}
}
}
void *
debug_get_owner (debug_t debug)
{
return (debug) ? debug->owner : NULL;
}
int
debug_set_level (debug_t debug, size_t level)
{
if (debug == NULL)
return EINVAL;
debug->level = level;
return 0;
}
int
debug_get_level (debug_t debug, size_t *plevel)
{
if (debug == NULL)
return EINVAL;
if (plevel)
*plevel = debug->level;
return 0;
}
int
debug_set_print (debug_t debug, int (*_print)
__P ((debug_t, const char *, va_list)), void *owner)
{
if (debug == NULL)
return EINVAL;
if (debug->owner != owner)
return EACCES;
debug->_print = _print;
return 0;
}
/* FIXME: We use a fix size, we should use vasprinf or something
similar to get rid of this arbitrary limitation. */
int
debug_print (debug_t debug, size_t level, const char *format, ...)
{
va_list ap;
if (debug == NULL)
return EINVAL;
if (!(debug->level & level))
return 0;
va_start (ap, format);
if (debug->_print)
debug->_print (debug, format, ap);
else
vfprintf (stderr, format, ap);
va_end (ap);
return 0;
}
......@@ -15,6 +15,9 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdio.h>
......@@ -26,7 +29,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <stream0.h>
#include <mailutils/stream.h>
struct _file_stream
{
......@@ -37,7 +40,7 @@ struct _file_stream
static void
_file_destroy (stream_t stream)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
if (fs && fs->file)
fclose (fs->file);
......@@ -48,7 +51,7 @@ static int
_file_read (stream_t stream, char *optr, size_t osize,
off_t offset, size_t *nbytes)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
size_t n;
int err = 0;
......@@ -80,7 +83,7 @@ static int
_file_readline (stream_t stream, char *optr, size_t osize,
off_t offset, size_t *nbytes)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
size_t n = 0;
int err = 0;
......@@ -116,7 +119,7 @@ static int
_file_write (stream_t stream, const char *iptr, size_t isize,
off_t offset, size_t *nbytes)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
size_t n;
int err;
......@@ -147,7 +150,7 @@ _file_write (stream_t stream, const char *iptr, size_t isize,
static int
_file_truncate (stream_t stream, off_t len)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
if (fs == NULL)
return EINVAL;
......@@ -159,7 +162,7 @@ _file_truncate (stream_t stream, off_t len)
static int
_file_size (stream_t stream, off_t *psize)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
struct stat stbuf;
if (fs == NULL)
......@@ -175,7 +178,7 @@ _file_size (stream_t stream, off_t *psize)
static int
_file_flush (stream_t stream)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
if (fs == NULL)
return EINVAL;
......@@ -185,7 +188,7 @@ _file_flush (stream_t stream)
static int
_file_get_fd (stream_t stream, int *pfd)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
if (fs == NULL)
return EINVAL;
......@@ -197,7 +200,7 @@ _file_get_fd (stream_t stream, int *pfd)
static int
_file_close (stream_t stream)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
int err = 0;
if (fs == NULL)
......@@ -214,7 +217,7 @@ _file_close (stream_t stream)
static int
_file_open (stream_t stream, const char *filename, int port, int flags)
{
struct _file_stream *fs = stream->owner;
struct _file_stream *fs = stream_get_owner (stream);
int flg;
int fd;
const char *mode;
......@@ -313,7 +316,7 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
free (iobuffer);
}
#endif
stream_set_flags (stream, flags |MU_STREAM_NO_CHECK, fs);
stream_set_flags (stream, flags |MU_STREAM_NO_CHECK);
return 0;
}
......
......@@ -19,13 +19,14 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <mailutils/stream.h>
#include <header0.h>
#include <stream0.h>
static int header_parse (header_t h, const char *blurb, int len);
static int header_read (stream_t is, char *buf, size_t buflen,
......@@ -72,6 +73,12 @@ header_destroy (header_t *ph, void *owner)
}
}
void *
header_get_owner (header_t header)
{
return (header) ? header->owner : NULL;
}
/* 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
......@@ -243,14 +250,29 @@ header_set_value (header_t header, const char *fn, const char *fv, int replace)
}
/* 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);
header. Really not cute.
COLON SPACE NL = 3 ; */
len = strlen (fn) + strlen (fv) + 3;
/* Add one for the NULL and leak a bit by adding one more
it will be the separtor \n from the body if the first
blurb did not have it. */
blurb = calloc (header->blurb_len + len + 2, 1);
if (blurb == NULL)
return ENOMEM;
sprintf (blurb, "%s: %s\n", fn, fv);
memcpy (blurb + len - 1, header->blurb, header->blurb_len);
free (header->blurb);
if (header->blurb)
{
memcpy (blurb + len, header->blurb, header->blurb_len);
free (header->blurb);
}
/* before parsing the new blurb make sure it is properly terminated
by \n\n. The trailing NL separtor. */
if (blurb[header->blurb_len + len - 1] != '\n'
|| blurb[header->blurb_len + len - 2] != '\n')
{
blurb[header->blurb_len + len] = '\n';
len++;
}
header_parse (header, blurb, len + header->blurb_len);
free (blurb);
return 0;
......@@ -469,17 +491,20 @@ fill_blurb (header_t header)
}
return status;
}
tbuf = realloc (header->temp_blurb, header->temp_blurb_len + nread);
if (tbuf == NULL)
if (nread > 0)
{
free (header->temp_blurb);
header->temp_blurb = NULL;
header->temp_blurb_len = 0;
return ENOMEM;
tbuf = realloc (header->temp_blurb, header->temp_blurb_len + nread);
if (tbuf == NULL)
{
free (header->temp_blurb);
header->temp_blurb = NULL;
header->temp_blurb_len = 0;
return ENOMEM;
}
header->temp_blurb = tbuf;
memcpy (header->temp_blurb + header->temp_blurb_len, buf, nread);
header->temp_blurb_len += nread;
}
header->temp_blurb = tbuf;
memcpy (header->temp_blurb + header->temp_blurb_len, buf, nread);
header->temp_blurb_len += nread;
}
while (nread > 0);
......@@ -495,8 +520,8 @@ static int
header_write (stream_t os, const char *buf, size_t buflen,
off_t off, size_t *pnwrite)
{
header_t header;
if (os == NULL || (header = (header_t)os->owner) == NULL)
header_t header = stream_get_owner (os);
if (os == NULL || header == NULL)
return EINVAL;
(void)buf; (void)off;
......@@ -513,10 +538,10 @@ static int
header_read (stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread)
{
header_t header;
header_t header = stream_get_owner (is);
int len;
if (is == NULL || (header = (header_t)is->owner) == NULL)
if (is == NULL || header == NULL)
return EINVAL;
len = header->blurb_len - off;
......
......@@ -33,13 +33,19 @@
extern "C" {
#endif
struct _auth
struct _ticket
{
void *owner;
char *challenge;
char *type;
int (*_pop) __P ((ticket_t, const char *challenge, char **));
};
int (*_prologue) (auth_t);
int (*_authenticate) (auth_t, char **user, char **passwd);
int (*_epilogue) (auth_t);
struct _authority
{
void *owner;
ticket_t ticket;
int (*_authenticate) __P ((authority_t));
};
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MAILUTILS_DEBUG0_H
#define _MAILUTILS_DEBUG0_H
#ifndef __P
#ifdef __STDC__
#define __P(args) args
#else
#define __P(args) ()
#endif
#endif /*__P */
#include <mailutils/debug.h>
#ifdef _cplusplus
extern "C" {
#endif
struct _debug
{
size_t level;
char *buffer;
size_t buflen;
void *owner;
int (*_print) __P ((debug_t, const char *, va_list));
};
#ifdef _cplusplus
}
#endif
#endif /* _MAILUTILS_DEBUG0_H */
......@@ -19,7 +19,6 @@
#define _HEADER0_H
#include <mailutils/header.h>
#include <stream0.h>
#include <sys/types.h>
#ifdef _cplusplus
......
......@@ -2,7 +2,7 @@
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 Library General Public License as published by
it under the terms of the GNU General Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
......@@ -15,22 +15,33 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MBX_UNIX_H
#define _MBX_UNIX_H 1
#ifndef _ITERATOR0_H
#define _ITERATOR0_H
#include <mailbox0.h>
#include <mailutils/iterator.h>
#ifdef __cplucplus
#ifndef __P
#ifdef __STDC__
#define __P(args) args
#else
#define __P(args) ()
#endif
#endif /*__P */
#ifdef _cplusplus
extern "C" {
#endif
extern int mailbox_unix_create __P ((mailbox_t *mbox, const char *name));
extern void mailbox_unix_destroy __P ((mailbox_t *mbox));
struct _iterator
{
list_t list;
size_t index;
};
extern struct mailbox_type _mailbox_unix_type;
#ifdef __cplucplus
#ifdef _cplusplus
}
#endif
#endif /* _MBX_UNIX_H */
#endif /* _ITERATOR0_H */
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _LIST0_H
#define _LIST0_H
#ifdef HAVE_PTHREAD_H
# define __USE_UNIX98 /* ?? */
# include <pthread.h>
#endif
#include <mailutils/list.h>
#include <sys/types.h>
#ifndef __P
#ifdef __STDC__
#define __P(args) args
#else
#define __P(args) ()
#endif
#endif /*__P */
#ifdef _cplusplus
extern "C" {
#endif
struct list_data
{
void *item;
struct list_data *next;
struct list_data *prev;
};
struct _list
{
struct list_data head;
size_t count;
#ifdef WITH_PTHREAD
pthread_rwlock_t rwlock;
#endif
};
#ifdef _cplusplus
}
#endif
#endif /* _LIST0_H */
......@@ -18,12 +18,16 @@
#ifndef _MAILBOX0_H
#define _MAILBOX0_H
#include <mailutils/mailbox.h>
#include <mailutils/event.h>
#ifdef HAVE_PTHREAD_H
# define __USE_UNIX98 /* ?? */
# include <pthread.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#include <mailutils/mailbox.h>
#ifdef __cplusplus
extern "C" {
#endif
......@@ -39,30 +43,26 @@ extern "C" {
struct _mailbox
{
/* Data */
char *name;
auth_t auth;
observable_t observable;
debug_t debug;
ticket_t ticket;
authority_t authority;
locker_t locker;
stream_t stream;
url_t url;
int flags;
/* register events */
event_t event;
size_t event_num;
/* debug information */
int debug_level;
void *debug_arg;
char *debug_buffer;
size_t debug_bufsize;
int (*debug_print) __P ((void *arg, const char *, size_t));
#ifdef WITH_PTHREAD
pthread_rwlock_t rwlock;
#endif
/* Back pointer to the specific mailbox */
void *data;
/* Public methods */
int (*_create) __P ((mailbox_t *, const char *));
void (*_destroy) __P ((mailbox_t *));
int (*_init) __P ((mailbox_t));
void (*_destroy) __P ((mailbox_t));
int (*_open) __P ((mailbox_t, int flag));
int (*_close) __P ((mailbox_t));
......@@ -78,16 +78,27 @@ struct _mailbox
int (*_size) __P ((mailbox_t, off_t *size));
/* private */
int (*_num_deleted) __P ((mailbox_t, size_t *));
};
/* private */
extern int mailbox_num_deleted __P ((mailbox_t, size_t *));
extern int mailbox_notification __P ((mailbox_t mbox, size_t type));
extern int mailbox_debug __P ((mailbox_t, int level, const char *fmt, ...));
/* To manipulate mailbox rwlock. */
extern int mailbox_rdlock __P ((mailbox_t));
extern int mailbox_wrlock __P ((mailbox_t));
extern int mailbox_unlock __P ((mailbox_t));
#define MAILBOX_NOTIFY(mbox, type) \
if (mbox->observer) observer_notify (mbox->observer, type)
/* Moro(?)ic kluge. */
#define MAILBOX_DEBUG0(mbox, type, format) \
if (mbox->debug) debug_print (mbox->debug, type, format)
#define MAILBOX_DEBUG1(mbox, type, format, arg1) \
if (mbox->debug) debug_print (mbox->debug, type, format, arg1)
#define MAILBOX_DEBUG2(mbox, type, format, arg1, arg2) \
if (mbox->debug) debug_print (mbox->debug, type, format, arg1, arg2)
#define MAILBOX_DEBUG3(mbox, type, format, arg1, arg2, arg3) \
if (mbox->debug) debug_print (mbox->debug, type, format, arg1, arg2, arg3)
#define MAILBOX_DEBUG4(mbox, type, format, arg1, arg2, arg3, arg4) \
if (mbox->debug) debug_print (mbox->debug, type, format, arg1, arg2, arg3, arg4)
#ifdef __cplusplus
}
......
......@@ -20,7 +20,10 @@
#include <sys/types.h>
#include <mailutils/mailer.h>
#ifdef HAVE_PTHREAD_H
# define __USE_UNIX98 /* ?? */
# include <pthread.h>
#endif
#ifdef _cplusplus
extern "C" {
#endif
......@@ -50,16 +53,32 @@ extern "C" {
struct _mailer
{
int socket;
char *hostname;
char line_buf[MAILER_LINE_BUF_SIZE];
int offset;
int state;
int add_dot;
stream_t stream;
char last_char;
stream_t stream;
observable_t observable;
debug_t debug;
url_t url;
int flags;
#ifdef WITH_PTHREAD
pthread_rwlock_t rwlock;
#endif
/* Pointer to the specific mailer data. */
void *data;
/* Public methods. */
int (*_init) __P ((mailer_t));
void (*_destroy) __P ((mailer_t));
int (*_open) __P ((mailer_t, int flags));
int (*_close) __P ((mailer_t));
int (*_send_message) __P ((mailer_t, const char *from, const char *rcpt,
int dsn, message_t));
};
/* Mail locks. */
extern int mailer_rdlock __P ((mailer_t));
extern int mailer_wrlock __P ((mailer_t));
extern int mailer_unlock __P ((mailer_t));
#ifdef _cplusplus
}
#endif
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MBX_IMAP_H
#define _MBX_IMAP_H 1
#include <mailbox0.h>
extern int mailbox_imap_create __P ((mailbox_t *mbox, const char *name));
extern void mailbox_imap_destroy __P ((mailbox_t *mbox));
extern struct mailbox_type _mailbox_imap_type;
#endif /* _MBX_IMAP_H */
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MBX_MBOX_H
#define _MBX_MBOX_H 1
#include <mailutils/mailbox.h>
extern int mailbox_mbox_create __P ((mailbox_t *mbox, const char *name));
extern void mailbox_mbox_destroy __P ((mailbox_t *mbox));
extern struct mailbox_type _mailbox_mbox_type;
#endif /* _MBX_MBOX_H */
/* GNU mailutils - a suite of utilities for electronic mail
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 Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MBX_MDIR_H
#define _MBX_MDIR_H 1
#include <mailbox0.h>
extern int mailbox_maildir_create __P ((mailbox_t *mbox, const char *name));
extern void mailbox_maildir_destroy __P ((mailbox_t *mbox));
extern struct mailbox_type _mailbox_maildir_type;
#endif /* _MBX_MDIR_H */
/* GNU mailutils - a suite of utilities for electronic mail
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 Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MBX_MMDF_H
#define _MBX_MMDF_H 1
#include <mailbox0.h>
extern int mailbox_mmdf_create __P ((mailbox_t *mbox, const char *name));
extern void mailbox_mmdf_destroy __P ((mailbox_t *mbox));
extern struct mailbox_type _mailbox_mmdf_type;
#endif /* _MBX_MMDF_H */
/* GNU mailutils - a suite of utilities for electronic mail
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 Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MBX_POP_H
#define _MBX_POP_H 1
#include <mailbox0.h>
extern int mailbox_pop_create __P ((mailbox_t *mbox, const char *name));
extern void mailbox_pop_destroy __P ((mailbox_t *mbox));
extern struct mailbox_type _mailbox_pop_type;
#endif /* _MBX_POP_H */
......@@ -18,12 +18,8 @@
#ifndef _MESSAGE0_H
#define _MESSAGE0_H
#include <mailutils/attribute.h>
#include <mailutils/header.h>
#include <mailutils/message.h>
#include <mailutils/mime.h>
#include <mailutils/mailbox.h>
#include <mailutils/event.h>
#include <sys/types.h>
#include <stdio.h>
......@@ -50,9 +46,7 @@ struct _message
body_t body;
attribute_t attribute;
mime_t mime;
event_t event;
size_t event_num;
observable_t observable;
/* Holder for message_write. */
char *hdr_buf;
......@@ -73,5 +67,4 @@ struct _message
}
#endif
extern void message_notification (message_t msg, size_t type);
#endif /* _MESSAGE_H */
#endif /* _MESSAGE0_H */
......
......@@ -47,6 +47,9 @@ extern "C" {
#define MIME_PARSER_ACTIVE 0x80000000
#define MIME_PARSER_HAVE_CR 0x40000000
#define MIME_NEW_MESSAGE 0x20000000
#define MIME_ADDED_CONTENT_TYPE 0x10000000
#define MIME_ADDED_MULTIPART 0x08000000
#define MIME_INSERT_BOUNDARY 0x04000000
struct _mime
{
......@@ -59,12 +62,14 @@ struct _mime
int tparts;
int nmtp_parts;
struct _mime_part **mtp_parts; /* list of parts in the msg */
char *boundary;
int cur_offset;
int cur_part;
int part_offset;
/* parser state */
char *boundary;
char *cur_line;
int line_ndx;
int cur_offset;
char *cur_buf;
int buf_size;
char *header_buf;
......@@ -72,17 +77,17 @@ struct _mime
int header_length;
int body_offset;
int body_length;
int body_lines;
int parser_state;
};
struct _mime_part
{
char sig[4];
mime_t mime;
header_t hdr;
message_t msg;
int body_offset;
int body_len;
int offset;
size_t len;
size_t lines;
};
#ifdef _cplusplus
......
......@@ -15,8 +15,12 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _CPYSTR_H
#define _CPYSTR_H
#ifndef _MISC_H
#define _MISC_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
......@@ -32,9 +36,45 @@ extern "C" {
# endif
#endif
extern size_t _cpystr __P ((char *dst, const char *src, size_t size));
extern int parseaddr __P ((const char *addr, char *buf, size_t bufsz));
#ifdef HAVE_PTHREAD_H
# define __USE_UNIX98
# include <pthread.h>
#endif
#ifdef WITH_PTHREAD
# if 0
# define RWLOCK_INIT(rwl, attr) pthread_mutex_init (rwl, attr)
# define RWLOCK_DESTROY(rwl) pthread_mutex_destroy (rwl)
# define RWLOCK_RDLOCK(rwl) pthread_mutex_lock (rwl)
# define RWLOCK_TRYRDLOCK(rwl) pthread_mutex_trylock (rwl)
# define RWLOCK_WRLOCK(rwl) pthread_mutex_lock (rwl)
# define RWLOCK_TRYWRLOCK(rwl) pthread_mutex_trylock (rwl)
# define RWLOCK_UNLOCK(rwl) pthread_mutex_unlock (rwl)
# else
# define RWLOCK_INIT(rwl, attr) pthread_rwlock_init (rwl, attr)
# define RWLOCK_DESTROY(rwl) pthread_rwlock_destroy (rwl)
# define RWLOCK_RDLOCK(rwl) pthread_rwlock_rdlock (rwl)
# define RWLOCK_TRYRDLOCK(rwl) pthread_rwlock_tryrdlock (rwl)
# define RWLOCK_WRLOCK(rwl) pthread_rwlock_wrlock (rwl)
# define RWLOCK_TRYWRLOCK(rwl) pthread_rwlock_trywrlock (rwl)
# define RWLOCK_UNLOCK(rwl) pthread_rwlock_unlock (rwl)
# endif
#else
# define RWLOCK_INIT(rwl, attr) 0
# define RWLOCK_DESTROY(rwl)
# define RWLOCK_RDLOCK(rwl)
# define RWLOCK_TRYRDLOCK(rwl)
# define RWLOCK_WRLOCK(rwl)
# define RWLOCK_TRYWRLOCK(rwl)
# define RWLOCK_UNLOCK(rwl)
# define flockfile(arg)
# define funlockfile(arg)
#endif
#ifdef __cplusplus
}
#endif
#endif
#endif /* _MISC_H */
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _OBSERVER0_H
#define _OBSERVER0_H
#include <mailutils/observer.h>
#ifndef __P
#ifdef __STDC__
#define __P(args) args
#else
#define __P(args) ()
#endif
#endif /*__P */
#ifdef _cplusplus
extern "C" {
#endif
struct _observer
{
int flags;
void *owner;
int (*_action) __P ((observer_t, size_t));
int (*_destroy) __P ((observer_t));
};
struct _observable
{
void *owner;
list_t list;
};
#ifdef _cplusplus
}
#endif
#endif /* _OBSERVER0_H */
......@@ -20,7 +20,6 @@
#include <mailutils/registrar.h>
#ifdef __cplusplus
extern "C" {
#endif
......@@ -33,58 +32,18 @@ extern "C" {
# endif
#endif /*__P */
/*
Builtin mailbox types.
A circular list is use for the builtin.
Proper locking is not done when accessing the list.
FIXME: not thread-safe. */
struct _registrar
struct _record
{
struct url_registrar *ureg;
struct mailbox_registrar *mreg;
const char *scheme;
mailbox_entry_t mailbox;
mailer_entry_t mailer;
int is_allocated;
struct _registrar *next;
void *onwer;
int (*_is_scheme) __P ((record_t, const char *));
int (*_get_mailbox) __P ((record_t, mailbox_entry_t *_mailbox));
int (*_get_mailer) __P ((record_t, mailer_entry_t *_mailer));
};
/* This is function is obsolete use the registrar_entry_*() ones */
extern int registrar_list __P ((struct url_registrar **ureg,
struct mailbox_registrar **mreg,
int *id, registrar_t *reg));
extern int registrar_entry_count __P ((size_t *num));
extern int registrar_entry __P ((size_t num, struct url_registrar **ureg,
struct mailbox_registrar **mreg,
int *id));
/* IMAP */
extern struct mailbox_registrar _mailbox_imap_registrar;
extern struct url_registrar _url_imap_registrar;
/* FILE */
extern struct url_registrar _url_file_registrar;
/* MBOX */
extern struct mailbox_registrar _mailbox_mbox_registrar;
extern struct url_registrar _url_mbox_registrar;
/* MAILTO */
extern struct mailbox_registrar _mailbox_mailto_registrar;
extern struct url_registrar _url_mailto_registrar;
/* MDIR */
extern struct mailbox_registrar _mailbox_maildir_registrar;
extern struct url_registrar _url_maildir_registrar;
/* MMDF */
extern struct mailbox_registrar _mailbox_mmdf_registrar;
extern struct url_registrar _url_mmdf_registrar;
/* UNIX */
extern struct mailbox_registrar _mailbox_unix_registrar;
extern struct url_registrar _url_unix_registrar;
/* POP */
extern struct mailbox_registrar _mailbox_pop_registrar;
extern struct url_registrar _url_pop_registrar;
#ifdef __cplusplus
}
#endif
......
......@@ -35,62 +35,34 @@ extern "C" {
struct _url
{
/* Data */
char *name;
char *scheme;
char *user;
char *passwd; /* encoded ?? */
char *auth;
char *host;
long port;
char *path;
char *query;
int id;
void *data;
int (*_create) __P ((url_t *url, const char *name));
void (*_destroy) __P ((url_t *url));
int (*_init) __P ((url_t url));
void (*_destroy) __P ((url_t url));
/* Methods */
int (*_get_id) __P ((const url_t, int *id));
int (*_get_scheme) __P ((const url_t, char *scheme,
size_t len, size_t *n));
int (*_get_user) __P ((const url_t, char *user,
size_t len, size_t *n));
int (*_get_passwd) __P ((const url_t, char *passwd,
size_t len, size_t *n));
int (*_get_host) __P ((const url_t, char *host,
size_t len, size_t *n));
int (*_get_port) __P ((const url_t, long *port));
int (*_get_path) __P ((const url_t, char *path,
size_t len, size_t *n));
int (*_get_query) __P ((const url_t, char *query,
size_t len, size_t *n));
int (*_get_scheme) __P ((const url_t, char *, size_t, size_t *));
int (*_get_user) __P ((const url_t, char *, size_t, size_t *));
int (*_get_passwd) __P ((const url_t, char *, size_t, size_t *));
int (*_get_auth) __P ((const url_t, char *, size_t, size_t *));
int (*_get_host) __P ((const url_t, char *, size_t, size_t *));
int (*_get_port) __P ((const url_t, long *));
int (*_get_path) __P ((const url_t, char *, size_t, size_t *));
int (*_get_query) __P ((const url_t, char *, size_t, size_t *));
};
/* IMAP */
/* Mailto */
/* UNIX MBOX */
/* Maildir */
/* MMDF */
/* POP3 */
#define MU_POP_PORT 110
/* UNIX MBOX */
#ifdef __cplusplus
}
#endif
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <iterator0.h>
int
iterator_create (iterator_t *piterator, list_t list)
{
iterator_t iterator;
if (piterator == NULL || list == NULL)
return EINVAL;
iterator = calloc (sizeof (*iterator), 1);
if (iterator == NULL)
return ENOMEM;
iterator->list = list;
*piterator = iterator;
return 0;
}
void
iterator_destroy (iterator_t *piterator)
{
if (piterator && *piterator)
{
free (*piterator);
*piterator = NULL;
}
}
int
iterator_first (iterator_t iterator)
{
iterator->index = 0;
return 0;
}
int
iterator_next (iterator_t iterator)
{
iterator->index++;
return 0;
}
int
iterator_current (iterator_t iterator, void **pitem)
{
return list_get (iterator->list, iterator->index, pitem);
}
int
iterator_is_done (iterator_t iterator)
{
size_t count;
int status;
if (iterator == NULL)
return 1;
status = list_count (iterator->list, &count);
if (status != 0)
return 1;
return (iterator->index >= count);
}
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <misc.h>
#include <list0.h>
int
list_create (list_t *plist)
{
list_t list;
int status;
if (plist == NULL)
return EINVAL;
list = calloc (sizeof (*list), 1);
if (list == NULL)
return ENOMEM;
status = RWLOCK_INIT (&(list->rwlock), NULL);
if (status != 0)
{
free (list);
return status;
}
list->head.next = &(list->head);
list->head.prev = &(list->head);
*plist = list;
return 0;
}
void
list_destroy (list_t *plist)
{
if (plist && *plist)
{
list_t list = *plist;
struct list_data *current;
struct list_data *previous;
RWLOCK_WRLOCK (&(list->rwlock));
for (current = list->head.next; current != &(list->head);)
{
previous = current;
current = current->next;
free (previous);
}
RWLOCK_UNLOCK (&(list->rwlock));
RWLOCK_DESTROY (&(list->rwlock));
free (list);
*plist = NULL;
}
}
int
list_append (list_t list, void *item)
{
struct list_data *ldata;
struct list_data *last = list->head.prev;
ldata = calloc (sizeof (*ldata), 1);
if (ldata == NULL)
return ENOMEM;
ldata->item = item;
RWLOCK_WRLOCK (&(list->rwlock));
ldata->next = &(list->head);
ldata->prev = list->head.prev;
last->next = ldata;
list->head.prev = ldata;
list->count++;
RWLOCK_UNLOCK (&(list->rwlock));
return 0;
}
int
list_prepend (list_t list, void *item)
{
struct list_data *ldata;
struct list_data *first = list->head.next;
ldata = calloc (sizeof (*ldata), 1);
if (ldata == NULL)
return ENOMEM;
ldata->item = item;
RWLOCK_WRLOCK (&(list->rwlock));
ldata->prev = &(list->head);
ldata->next = list->head.next;
first->prev = ldata;
list->head.next = ldata;
list->count++;
RWLOCK_UNLOCK (&(list->rwlock));
return 0;
}
int
list_count (list_t list, size_t *pcount)
{
if (list == NULL || pcount == NULL)
return EINVAL;
*pcount = list->count;
return 0;
}
int
list_remove (list_t list, void *item)
{
struct list_data *current, *previous;
if (list == NULL)
return EINVAL;
RWLOCK_WRLOCK (&(list->rwlock));
for (previous = &(list->head), current = list->head.next;
current != &(list->head); previous = current, current = current->next)
{
if ((int)current->item == (int)item)
{
previous->next = current->next;
free (current);
list->count--;
RWLOCK_UNLOCK (&(list->rwlock));
return 0;
}
}
RWLOCK_UNLOCK (&(list->rwlock));
return ENOENT;
}
int
list_get (list_t list, size_t index, void **pitem)
{
struct list_data *current;
size_t count;
if (list == NULL || pitem == NULL)
return EINVAL;
RWLOCK_RDLOCK (&(list->rwlock));
for (current = list->head.next, count = 0; current != &(list->head);
current = current->next, count++)
{
if (count == index)
{
*pitem = current->item;
RWLOCK_UNLOCK (&(list->rwlock));
return 0;
}
}
RWLOCK_UNLOCK (&(list->rwlock));
return ENOENT;
}
......@@ -15,6 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <sys/types.h>
#include <stdlib.h>
......
......@@ -19,56 +19,92 @@
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <mailbox0.h>
#include <message0.h>
#include <mailutils/registrar.h>
#include <mailutils/locker.h>
#include <mailutils/iterator.h>
#include <mailutils/registrar.h>
#include <misc.h>
#include <mailbox0.h>
/*
* Point of entry.
* Simple, first check if they ask for something specific; with the ID.
* Then try to discover the type of mailbox with the url(name).
* Then we call the appropriate mailbox_*type*_create() function.
*/
/* The Mailbox Factory.
We create an iterator for the mailbox_register and see if any scheme
match, if not we check in the mailbox_manager register for a match.
Then we call the mailbox's >url_create() to parse the URL. Last
initiliaze the concrete mailbox. */
int
mailbox_create (mailbox_t *pmbox, const char *name, int id)
{
int status = EINVAL;
struct mailbox_registrar *mreg;
url_t url = NULL;
record_t record = NULL;
mailbox_entry_t entry = NULL;
iterator_t iterator;
list_t list;
int found = 0;
(void)id;
if (pmbox == NULL)
return EINVAL;
url_create (&url, name);
/* 1st guest: if an ID is specify, shortcut */
if (id)
/* Look in the mailbox_register, for a match */
registrar_get_list (&list);
status = iterator_create (&iterator, list);
if (status != 0)
return status;
for (iterator_first (iterator); !iterator_is_done (iterator);
iterator_next (iterator))
{
status = registrar_get (id, NULL, &mreg);
if (status == 0)
status = mreg->_create (pmbox, name);
iterator_current (iterator, (void **)&record);
if (record_is_scheme (record, name))
{
status = record_get_mailbox (record, &entry);
if (status == 0)
found = 1;
break;
}
}
/* 2nd fallback: Use the URL */
else if (url != NULL)
iterator_destroy (&iterator);
if (found)
{
url_get_id (url, &id);
status = registrar_get (id, NULL, &mreg);
if (status == 0)
status = mreg->_create (pmbox, name);
url_t url = NULL;
mailbox_t mbox = NULL;
/* Allocate memory for mbox. */
mbox = calloc (1, sizeof (*mbox));
if (mbox == NULL)
return ENOMEM;
/* Initialize the internal lock, now so the concrete mailbox
could use it. */
status = RWLOCK_INIT (&(mbox->rwlock), NULL);
if (status != 0)
{
mailbox_destroy (&mbox);
return status;
}
/* Parse the url, it may be a bad one and we should bailout if this
failed. */
if ((status = url_create (&url, name)) != 0
|| (status = entry->_url_init (url)) != 0)
{
mailbox_destroy (&mbox);
return status;
}
mbox->url = url;
/* Create the concrete mailbox type. */
status = entry->_mailbox_init (mbox);
if (status != 0)
{
mailbox_destroy (&mbox);
}
else
*pmbox = mbox;
}
/* set the URL */
if (status == 0)
(*pmbox)->url = url;
else
url_destroy (&url);
return status;
}
......@@ -76,9 +112,52 @@ void
mailbox_destroy (mailbox_t *pmbox)
{
if (pmbox && *pmbox)
(*pmbox)->_destroy (pmbox);
{
mailbox_t mbox = *pmbox;
#ifdef WITH_PTHREAD
pthread_rwlock_t rwlock = mbox->rwlock;
#endif
/* Notify the observers. */
if (mbox->observable)
{
observable_notify (mbox->observable, MU_EVT_MAILBOX_DESTROY);
observable_destroy (&(mbox->observable), mbox);
}
/* Call the concrete mailbox. */
if (mbox->_destroy)
mbox->_destroy (mbox);
RWLOCK_WRLOCK (&(rwlock));
/* Nuke the stream and close it */
if (mbox->stream)
{
stream_close (mbox->stream);
stream_destroy (&(mbox->stream), mbox);
}
if (mbox->authority)
authority_destroy (&(mbox->authority), mbox);
if (mbox->url)
url_destroy (&(mbox->url));
if (mbox->locker)
locker_destroy (&(mbox->locker));
if (mbox->debug)
debug_destroy (&(mbox->debug), mbox);
free (mbox);
*pmbox = NULL;
RWLOCK_UNLOCK (&(rwlock));
RWLOCK_DESTROY (&(rwlock));
}
}
/* -------------- stub functions ------------------- */
int
......@@ -131,14 +210,6 @@ mailbox_expunge (mailbox_t mbox)
}
int
mailbox_num_deleted (mailbox_t mbox, size_t *num)
{
if (mbox == NULL || mbox->_num_deleted == NULL)
return ENOSYS;
return mbox->_num_deleted (mbox, num);
}
int
mailbox_is_updated (mailbox_t mbox)
{
if (mbox == NULL || mbox->_is_updated == NULL)
......@@ -185,21 +256,21 @@ mailbox_get_locker (mailbox_t mbox, locker_t *plocker)
}
int
mailbox_set_auth (mailbox_t mbox, auth_t auth)
mailbox_set_ticket (mailbox_t mbox, ticket_t ticket)
{
if (mbox == NULL)
return EINVAL;
mbox->auth = auth;
mbox->ticket = ticket;
return 0;
}
int
mailbox_get_auth (mailbox_t mbox, auth_t *pauth)
mailbox_get_ticket (mailbox_t mbox, ticket_t *pticket)
{
if (mbox == NULL || pauth == NULL)
if (mbox == NULL || pticket == NULL)
return EINVAL;
if (pauth)
*pauth = mbox->auth;
if (pticket)
*pticket = mbox->ticket;
return 0;
}
......@@ -223,132 +294,81 @@ mailbox_get_stream (mailbox_t mbox, stream_t *pstream)
}
int
mailbox_register (mailbox_t mbox, size_t type,
int (*action) (size_t type, void *arg),
void *arg)
mailbox_get_observable (mailbox_t mbox, observable_t *pobservable)
{
size_t i;
event_t event;
/* FIXME: I should check for invalid types */
if (mbox == NULL || action == NULL)
if (mbox == NULL || pobservable == NULL)
return EINVAL;
/* find a free spot */
for (i = 0; i < mbox->event_num; i++)
if (mbox->observable == NULL)
{
event = &(mbox->event[i]);
if (event->_action == NULL)
{
event->_action = action;
event->type = type;
event->arg = arg;
return 0;
}
int status = observable_create (&(mbox->observable), mbox);
if (status != 0)
return status;
}
/* a new one */
event = realloc (mbox->event, (mbox->event_num + 1) * sizeof (*event));
if (event == NULL)
return ENOMEM;
mbox->event = event;
event[mbox->event_num]._action = action;
event[mbox->event_num].type = type;
event[mbox->event_num].arg = arg;
mbox->event_num++;
*pobservable = mbox->observable;
return 0;
}
int
mailbox_deregister (mailbox_t mbox, void *action)
mailbox_set_debug (mailbox_t mbox, debug_t debug)
{
size_t i;
event_t event;
for (i = 0; i < mbox->event_num; i++)
{
event = &(mbox->event[i]);
if ((int)event->_action == (int)action)
{
event->type = 0;
event->_action = NULL;
event->arg = NULL;
return 0;
}
}
return ENOENT;
if (mbox == NULL)
return EINVAL;
debug_destroy (&(mbox->debug), mbox);
mbox->debug = debug;
return 0;
}
int
mailbox_notification (mailbox_t mbox, size_t type)
mailbox_get_debug (mailbox_t mbox, debug_t *pdebug)
{
size_t i;
event_t event;
int status = 0;
for (i = 0; i < mbox->event_num; i++)
if (mbox == NULL || pdebug == NULL)
return EINVAL;
if (mbox->debug == NULL)
{
event = &(mbox->event[i]);
if ((event->_action) && (event->type & type))
status |= event->_action (type, event->arg);
int status = debug_create (&(mbox->debug), mbox);
if (status != 0)
return status;
}
return status;
}
int
mailbox_set_debug_level (mailbox_t mbox, size_t level)
{
if (mbox == NULL)
return EINVAL;
mbox->debug_level = level;
*pdebug = mbox->debug;
return 0;
}
/* Mailbox Internal Locks. Put the name of the functions in parenteses To make
sure it will not be redefine by a macro. If the flags was non-blocking we
should not block on the lock, so we try with pthread_rwlock_try*lock(). */
int
mailbox_get_debug_level (mailbox_t mbox, size_t *plevel)
(mailbox_rdlock) (mailbox_t mbox)
{
if (mbox == NULL || plevel == NULL)
return EINVAL;
*plevel = mbox->debug_level;
#ifdef WITH_PTHREAD
int err = (mbox->flags & MU_STREAM_NONBLOCK) ?
RWLOCK_TRYRDLOCK (&(mbox->rwlock)) :
RWLOCK_RDLOCK (&(mbox->rwlock)) ;
if (err != 0 && err != EDEADLK)
return err;
#endif
return 0;
}
int
mailbox_set_debug_print (mailbox_t mbox, int (*debug_print)
(void *arg, const char *, size_t), void *arg)
(mailbox_wrlock) (mailbox_t mbox)
{
if (mbox == NULL)
return EINVAL;
mbox->debug_print = debug_print;
mbox->debug_arg = arg;
#ifdef WITH_PTHREAD
int err = (mbox->flags & MU_STREAM_NONBLOCK) ?
RWLOCK_TRYWRLOCK (&(mbox->rwlock)) :
RWLOCK_WRLOCK (&(mbox->rwlock)) ;
if (err != 0 && err != EDEADLK)
return err;
#endif
return 0;
}
int
mailbox_debug (mailbox_t mbox, int level, const char *fmt, ...)
(mailbox_unlock) (mailbox_t mbox)
{
va_list ap;
if (mbox == NULL)
return EINVAL;
if (!(mbox->debug_level & level))
return 0;
va_start (ap, fmt);
if (mbox->debug_print)
{
int writen;
if (mbox->debug_buffer == NULL)
{
mbox->debug_bufsize = 255;
mbox->debug_buffer = malloc (mbox->debug_bufsize);
if (mbox->debug_buffer)
return ENOMEM; }
writen = vsnprintf (mbox->debug_buffer, mbox->debug_bufsize, fmt, ap);
mbox->debug_print (mbox->debug_arg, mbox->debug_buffer, writen);
}
else
vfprintf (stderr, fmt, ap);
va_end (ap);
#ifdef WITH_PTHREAD
return RWLOCK_UNLOCK (&(mbox->rwlock));
#else
return 0;
#endif
}
......
......@@ -15,6 +15,9 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdio.h>
......@@ -26,12 +29,12 @@
#include <fcntl.h>
#include <unistd.h>
#include <stream0.h>
#include <mailutils/stream.h>
#ifdef _POSIX_MAPPED_FILES
#include <sys/mman.h>
struct _mapfile_stream
{
int fd;
......@@ -43,7 +46,7 @@ struct _mapfile_stream
static void
_mapfile_destroy (stream_t stream)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
if (mfs && mfs->ptr)
{
......@@ -57,7 +60,7 @@ static int
_mapfile_read (stream_t stream, char *optr, size_t osize,
off_t offset, size_t *nbytes)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
size_t n;
if (mfs == NULL || mfs->ptr == NULL)
......@@ -82,7 +85,7 @@ static int
_mapfile_readline (stream_t stream, char *optr, size_t osize,
off_t offset, size_t *nbytes)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
char *nl;
size_t n = 0;
......@@ -111,7 +114,7 @@ static int
_mapfile_write (stream_t stream, const char *iptr, size_t isize,
off_t offset, size_t *nbytes)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
if (mfs == NULL || mfs->ptr == NULL)
return EINVAL;
......@@ -151,7 +154,7 @@ _mapfile_write (stream_t stream, const char *iptr, size_t isize,
static int
_mapfile_truncate (stream_t stream, off_t len)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
if (mfs == NULL || mfs->ptr == NULL)
return EINVAL;
/* Remap. */
......@@ -178,7 +181,7 @@ _mapfile_truncate (stream_t stream, off_t len)
static int
_mapfile_size (stream_t stream, off_t *psize)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
struct stat stbuf;
if (mfs == NULL || mfs->ptr == NULL)
......@@ -194,7 +197,7 @@ _mapfile_size (stream_t stream, off_t *psize)
static int
_mapfile_flush (stream_t stream)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
if (mfs == NULL)
return EINVAL;
return msync (mfs->ptr, mfs->size, MS_SYNC);
......@@ -203,7 +206,7 @@ _mapfile_flush (stream_t stream)
static int
_mapfile_get_fd (stream_t stream, int *pfd)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
if (mfs == NULL)
return EINVAL;
if (pfd)
......@@ -214,7 +217,7 @@ _mapfile_get_fd (stream_t stream, int *pfd)
static int
_mapfile_close (stream_t stream)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
int err = 0;
if (mfs && mfs->ptr)
{
......@@ -231,7 +234,7 @@ _mapfile_close (stream_t stream)
static int
_mapfile_open (stream_t stream, const char *filename, int port, int flags)
{
struct _mapfile_stream *mfs = stream->owner;
struct _mapfile_stream *mfs = stream_get_owner (stream);
int mflag, flg;
struct stat st;
......@@ -277,7 +280,7 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags)
return err;
}
mfs->flags = mflag;
stream_set_flags (stream, flags |MU_STREAM_NO_CHECK, mfs);
stream_set_flags (stream, flags |MU_STREAM_NO_CHECK);
return 0;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <paths.h>
#include <errno.h>
#include <stdio.h>
#include <mailutils/mailbox.h>
#ifndef _PATH_MAILDIR
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <mailbox0.h>
#include <registrar0.h>
static int mailbox_file_init (mailbox_t mbox);
/* Register variables. */
static struct mailbox_entry _file_entry =
{
url_file_init, mailbox_file_init
};
mailbox_entry_t file_entry = &_file_entry;
static struct _record _file_record =
{
MU_FILE_SCHEME,
&_file_entry, /* Mailbox entry. */
NULL, /* Mailer entry. */
0, /* Not malloc()ed. */
NULL, /* No need for an owner. */
NULL, /* is_scheme method. */
NULL, /* get_mailbox method. */
NULL /* get_mailer method. */
};
record_t file_record = &_file_record;
/* Register variables. */
static struct mailbox_entry _path_entry =
{
url_path_init, mailbox_file_init
};
mailbox_entry_t path_entry = &_path_entry;
static struct _record _path_record =
{
MU_PATH_SCHEME,
&_path_entry, /* Mailbox entry. */
NULL, /* Mailer entry. */
0, /* Not malloc()ed. */
NULL, /* No need for an owner. */
NULL, /* is_scheme method. */
NULL, /* get_mailbox method. */
NULL /* get_mailer method. */
};
record_t path_record = &_path_record;
/*
Caveat there is no specific URL for file mailbox or simple path name,
<path_name>
file:<path_name>
It would be preferrable to use :
maildir:<path>
unix:<path>
mmdf:<path>
This would eliminate heuristic discovery that would turn
out to be wrong.
*/
static int
mailbox_file_init (mailbox_t mbox)
{
struct stat st;
size_t len = 0;
char *path;
int status;
status = url_get_path (mbox->url, NULL, 0, &len);
if (status != 0)
return status;
path = calloc (len + 1, sizeof (char));
if (path == NULL)
return ENOMEM;
status = url_get_path (mbox->url, path, len + 1, NULL);
if (status != 0)
{
free (path);
return status;
}
/* Sigh, if they want to creat ??? they should know the type of ???
What is the best course of action ? For the default is mbox if the
file does not exist. */
if (stat (path, &st) < 0)
{
status = mbox_entry->_mailbox_init (mbox);
}
else if (S_ISREG (st.st_mode))
{
/*
FIXME: We should do an open() and try
to do a better reconnaissance of the type,
maybe MMDF. For now assume Unix MBox */
status = mbox_entry->_mailbox_init (mbox);
}
/* Is that true ? Are all directories Maildir ?? */
else if (S_ISDIR (st.st_mode))
{
/*status = maildir_entry._mailbox_init (mbox);*/
status = EINVAL;
}
free (path);
return status;
}
......@@ -15,9 +15,9 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stream0.h>
#include <message0.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdio.h>
......@@ -28,9 +28,10 @@
#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,
size_t *pnwrite);
#include <mailutils/stream.h>
#include <misc.h>
#include <message0.h>
static int message_read (stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread );
static int message_write (stream_t os, const char *buf, size_t buflen,
......@@ -64,34 +65,26 @@ message_destroy (message_t *pmsg, void *owner)
{
/* Notify the listeners. */
/* FIXME: to be removed since we do not supoort this event. */
if (msg->event_num)
if (msg->observable)
{
message_notification (msg, MU_EVT_MSG_DESTROY);
free (msg->event);
observable_notify (msg->observable, MU_EVT_MESSAGE_DESTROY);
observable_destroy (&(msg->observable), msg);
}
/* Header. */
if (msg->header)
header_destroy (&(msg->header), owner);
if (msg->header)
header_destroy (&(msg->header), msg);
/* Attribute. */
if (msg->attribute)
attribute_destroy (&(msg->attribute), owner);
if (msg->attribute)
attribute_destroy (&(msg->attribute), msg);
/* Stream. */
if (msg->stream)
stream_destroy (&(msg->stream), owner);
if (msg->stream)
stream_destroy (&(msg->stream), msg);
/* Body. */
if (msg->body)
body_destroy (&(msg->body), owner);
if (msg->body)
body_destroy (&(msg->body), msg);
/* Mime. */
......@@ -105,6 +98,12 @@ message_destroy (message_t *pmsg, void *owner)
}
}
void *
message_get_owner (message_t msg)
{
return (msg == NULL) ? NULL : msg->owner;
}
int
message_get_header (message_t msg, header_t *phdr)
{
......@@ -198,7 +197,7 @@ message_get_stream (message_t msg, stream_t *pstream)
stream_set_read (stream, message_read, msg);
stream_set_write (stream, message_write, msg);
stream_set_fd (stream, message_get_fd, msg);
stream_set_flags (stream, MU_STREAM_RDWR, msg);
stream_set_flags (stream, MU_STREAM_RDWR);
msg->stream = stream;
}
......@@ -222,6 +221,8 @@ int
message_lines (message_t msg, size_t *plines)
{
size_t hlines, blines;
int ret = 0;
if (msg == NULL)
return EINVAL;
/* Overload. */
......@@ -230,11 +231,11 @@ message_lines (message_t msg, size_t *plines)
if (plines)
{
hlines = blines = 0;
header_lines (msg->header, &hlines);
body_lines (msg->body, &blines);
if ( ( ret = header_lines (msg->header, &hlines) ) == 0 )
ret = body_lines (msg->body, &blines);
*plines = hlines + blines;
}
return 0;
return ret;
}
int
......@@ -253,6 +254,8 @@ int
message_size (message_t msg, size_t *psize)
{
size_t hsize, bsize;
int ret = 0;
if (msg == NULL)
return EINVAL;
/* Overload ? */
......@@ -261,11 +264,11 @@ message_size (message_t msg, size_t *psize)
if (psize)
{
hsize = bsize = 0;
header_size (msg->header, &hsize);
body_size (msg->body, &bsize);
if ( ( ret = header_size (msg->header, &hsize) ) == 0 )
ret = body_size (msg->body, &bsize);
*psize = hsize + bsize;
}
return 0;
return ret;
}
int
......@@ -300,12 +303,22 @@ message_from (message_t msg, char *buf, size_t len, size_t *pnwrite)
status = header_get_value (header, MU_HEADER_FROM, NULL, 0, &n);
if (status == 0 && n != 0)
{
char *from = calloc (1, n + 1);
char *from;
char *addr;
from = calloc (1, n + 1);
if (from == NULL)
return ENOMEM;
addr = calloc (1, n + 1);
if (addr == NULL)
{
free (from);
return ENOMEM;
}
header_get_value (header, MU_HEADER_FROM, from, n + 1, NULL);
if (extract_addr (from, n, &addr, &n) == 0)
if (parseaddr (from, addr, n + 1) == 0)
{
n = (n > len) ? len : n;
size_t i = strlen (addr);
n = (i > len) ? len : i;
if (buf && len > 0)
{
memcpy (buf, addr, n);
......@@ -563,77 +576,26 @@ message_set_get_part (message_t msg, int (*_get_part)
}
int
message_register (message_t msg, size_t type,
int (*action) (size_t typ, void *arg), void *arg)
message_get_observable (message_t msg, observable_t *pobservable)
{
event_t event;
size_t i;
if (msg == NULL || action == NULL || type == 0)
if (msg == NULL || pobservable == NULL)
return EINVAL;
/* Find a free spot. */
for (i = 0; i < msg->event_num; i++)
if (msg->observable == NULL)
{
event = &(msg->event[i]);
if (event->_action == NULL)
{
event->type = type;
event->_action = action;
event->arg = arg;
return 0;
}
int status = observable_create (&(msg->observable), msg);
if (status != 0)
return status;
}
event = realloc (msg->event, (msg->event_num + 1)*sizeof (*event));
if (event == NULL)
return ENOMEM;
msg->event = event;
event[msg->event_num]._action = action;
event[msg->event_num].type = type;
event[msg->event_num].arg = arg;
msg->event_num++;
*pobservable = msg->observable;
return 0;
}
int
message_deregister (message_t msg, void *action)
{
size_t i;
event_t event;
if (msg == NULL || action == NULL)
return EINVAL;
for (i = 0; i < msg->event_num; i++)
{
event = &(msg->event[i]);
if ((int)event->_action == (int)action)
{
event->type = 0;
event->_action = NULL;
event->arg = NULL;
return 0;
}
}
return ENOENT;
}
void
message_notification (message_t msg, size_t type)
{
size_t i;
event_t event;
for (i = 0; i < msg->event_num; i++)
{
event = &(msg->event[i]);
if ((event->_action) && (event->type & type))
event->_action (type, event->arg);
}
}
static int
message_read (stream_t is, char *buf, size_t buflen,
off_t off, size_t *pnread )
{
message_t msg = is->owner;
message_t msg = stream_get_owner (is);
stream_t his, bis;
size_t hread, hsize, bread, bsize;
......@@ -670,11 +632,11 @@ static int
message_write (stream_t os, const char *buf, size_t buflen,
off_t off, size_t *pnwrite)
{
message_t msg;
message_t msg = stream_get_owner (os);
int status = 0;
size_t bufsize = buflen;
if (os == NULL || (msg = os->owner) == NULL)
if (msg == NULL)
return EINVAL;
/* Skip the obvious. */
......@@ -772,11 +734,11 @@ message_write (stream_t os, const char *buf, size_t buflen,
static int
message_get_fd (stream_t stream, int *pfd)
{
message_t msg;
message_t msg = stream_get_owner (stream);
body_t body;
stream_t is;
if (stream == NULL || (msg = stream->owner) == NULL)
if (msg == NULL)
return EINVAL;
/* Probably being lazy, then create a body for the stream. */
......@@ -794,72 +756,3 @@ message_get_fd (stream_t stream, int *pfd)
body_get_stream (body, &is);
return stream_get_fd (is, pfd);
}
static int
extract_addr (const char *s, size_t n, char **presult, size_t *pnwrite)
{
char *p, *p1, *p2;
if (s == NULL || n == 0 || presult == NULL)
return EINVAL;
/* Skip the double quotes. */
p = memchr (s, '\"', n);
if (p != NULL)
{
p1 = memchr (s, '<', p - s);
p2 = memchr (s, '@', p - s);
if (p1 == NULL && p2 == NULL)
{
p1 = memchr (p + 1, '\"', n - ((p + 1) - s));
if (p1 != NULL)
{
n -= (p1 + 1) - s;
s = p1 + 1;
}
}
}
/* <name@hostname> ?? */
p = memchr (s, '<', n);
if (p != NULL)
{
p1 = memchr (p, '>', n - (p - s));
if (p1 != NULL && (p1 - p) > 1)
{
p2 = memchr (p, ' ', p1 - p);
if (p2 == NULL)
{
/* The NULL is already accounted for. */
*presult = calloc (1, p1 - p);
if (*presult == NULL)
return ENOMEM;
memcpy (*presult, p + 1, (p1 - p) - 1);
if (pnwrite)
*pnwrite = (p1 - p) - 1;
return 0;
}
}
}
/* name@domain */
p = memchr (s, '@', n);
if (p != NULL)
{
p1 = p;
while (*p != ' ' && p != s)
p--;
while (*p1 != ' ' && p1 < (s + n))
p1++;
*presult = calloc (1, (p1 - p) + 1);
if (*presult == NULL)
return ENOMEM;
memcpy (*presult, p, p1 - p);
if (pnwrite)
*pnwrite = p1 - p;
return 0;
}
*presult = NULL;
return EINVAL;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <misc.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
size_t
_cpystr (char *dst, const char *src, size_t size)
{
size_t len = src ? strlen (src) : 0 ;
if (dst == NULL || size == 0)
return len;
if (len >= size)
len = size - 1;
memcpy (dst, src, len);
dst[len] = '\0';
return len;
}
/*
* parseaddr.c Read a valid RFC822 address with all the comments
* etc in it, and return _just_ the email address.
*
* Version: @(#)parseaddr.c 1.00 02-Apr-1999 miquels@cistron.nl
*
*/
struct token
{
struct token *next;
char word[1];
};
#define SKIPSPACE(p) do { while(*p && isspace(*p)) p++; } while(0)
/* Skip everything between quotes. */
static void
quotes (char **ptr)
{
char *p = *ptr;
p++;
while (*p && *p != '"')
{
if (*p == '\\' && p[1])
p++;
p++;
}
*ptr = p;
}
/* Return the next token. A token can be "<>()," or any "word". */
static struct token *
gettoken (char **ptr)
{
struct token *tok;
char *p = *ptr;
char *begin;
int l, quit = 0;
SKIPSPACE(p);
begin = p;
while (!quit)
{
switch (*p)
{
case 0:
case ' ':
case '\t':
case '\n':
quit = 1;
break;
case '(':
case ')':
case '<':
case '>':
case ',':
if (p == begin)
p++;
quit = 1;
break;
case '\\':
if (p[1])
p++;
break;
case '"':
quotes (&p);
break;
}
if (!quit)
p++;
}
l = p - begin;
if (l == 0)
return NULL;
tok = malloc (sizeof (struct token) + l);
if (tok == NULL)
return NULL;
tok->next = NULL;
strncpy (tok->word, begin, l);
tok->word[l] = 0;
SKIPSPACE (p);
*ptr = p;
return tok;
}
/* Get email address from rfc822 address. */
int
parseaddr (const char *addr, char *buf, size_t bufsz)
{
const char *p;
struct token *t, *tok, *last;
struct token *brace = NULL;
int comment = 0;
tok = last = NULL;
/* Read address, remove comments right away. */
p = addr;
while ((t = gettoken(&p)) != NULL && t->word[0] != ',')
{
if (t->word[0] == '(' || t->word[0] == ')' || comment)
{
free (t);
if (t->word[0] == '(')
comment++;
if (t->word[0] == ')')
comment--;
continue;
}
if (t->word[0] == '<')
brace = t;
if (tok)
last->next = t;
else
tok = t;
last = t;
}
/* Put extracted address into "buf" */
buf[0] = 0;
t = brace ? brace->next : tok;
for (; t && t->word[0] != ',' && t->word[0] != '>'; t = t->next)
{
if (strlen (t->word) >= bufsz)
return -1;
bufsz -= strlen (t->word);
strcat (buf, t->word);
}
/* Free list of tokens. */
for (t = tok; t; t = last)
{
last = t->next;
free (t);
}
return 0;
}
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <mailutils/iterator.h>
#include <observer0.h>
int
observer_create (observer_t *pobserver, void *owner)
{
observer_t observer;
observer = calloc (sizeof (*observer), 1);
if (observer == NULL)
return ENOMEM;
observer->owner = owner;
*pobserver = observer;
return 0;
}
void
observer_destroy (observer_t *pobserver, void *owner)
{
if (pobserver && *pobserver)
{
observer_t observer = *pobserver;
if (observer->owner == owner || observer->flags & MU_OBSERVER_NO_CHECK)
{
if (observer->_destroy)
observer->_destroy (observer);
free (observer);
}
*pobserver = NULL;
}
}
void *
observer_get_owner (observer_t observer)
{
return (observer) ? observer->owner : NULL;
}
int
observer_action (observer_t observer, size_t type)
{
if (observer == NULL)
return EINVAL;
if (observer->_action)
return observer->_action (observer, type);
return 0;
}
int
observer_set_action (observer_t observer, int (*_action)
__P ((observer_t, size_t)), void *owner)
{
if (observer == NULL)
return EINVAL;
if (observer->owner != owner)
return EACCES;
observer->_action = _action;
return 0;
}
int
observer_set_destroy (observer_t observer, int (*_destroy) __P((observer_t)),
void *owner)
{
if (observer == NULL)
return EINVAL;
if (observer->owner != owner)
return EACCES;
observer->_destroy = _destroy;
return 0;
}
int
observer_set_flags (observer_t observer, int flags)
{
if (observer == NULL)
return EINVAL;
observer->flags |= flags;
return 0;
}
int
observable_create (observable_t *pobservable, void *owner)
{
observable_t observable;
int status;
if (pobservable == NULL)
return EINVAL;
observable = calloc (sizeof (*observable), 1);
if (observable == NULL)
return ENOMEM;
status = list_create (&(observable->list));
if (status != 0 )
{
free (observable);
return status;
}
observable->owner = owner;
*pobservable = observable;
return 0;
}
void
observable_destroy (observable_t *pobservable, void *owner)
{
iterator_t iterator;
if (pobservable && *pobservable)
{
observable_t observable = *pobservable;
if (observable->owner == owner)
{
int status = iterator_create (&iterator, observable->list);
if (status == 0)
{
observer_t observer = NULL;
for (iterator_first (iterator); !iterator_is_done (iterator);
iterator_next (iterator))
{
iterator_current (iterator, (void **)&observer);
if (observer != NULL)
observer_destroy (&observer, NULL);
}
}
list_destroy (&((*pobservable)->list));
free (*pobservable);
}
*pobservable = NULL;
}
}
void *
observable_get_owner (observable_t observable)
{
return (observable) ? observable->owner : NULL;
}
int
observable_attach (observable_t observable, observer_t observer)
{
if (observable == NULL || observer == NULL)
return EINVAL;
return list_append (observable->list, observer);
}
int
observable_detach (observable_t observable, observer_t observer)
{
iterator_t iterator;
int status;
int found = 0;
observer_t current;
if (observable == NULL ||observer == NULL)
return EINVAL;
status = iterator_create (&iterator, observable->list);
if (status != 0)
return status;
for (iterator_first (iterator); !iterator_is_done (iterator);
iterator_next (iterator))
{
iterator_current (iterator, (void **)&current);
if ((int)(current) == (int)observer)
{
found = 1;
break;
}
}
iterator_destroy (&iterator);
return (found) ? list_remove (observable->list, observer) : ENOENT;
}
int
observable_notify (observable_t observable, int type)
{
iterator_t iterator;
observer_t observer = NULL;
int status = 0;
if (observable == NULL)
return EINVAL;
status = iterator_create (&iterator, observable->list);
if (status != 0)
return status;
for (iterator_first (iterator); !iterator_is_done (iterator);
iterator_next (iterator))
{
iterator_current (iterator, (void **)&observer);
if (observer)
{
status |= observer_action (observer, type);
observer = NULL;
}
}
iterator_destroy (&iterator);
return status;
}
......@@ -19,225 +19,73 @@
#include <config.h>
#endif
#include <registrar0.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
/* Builtin mailbox types. A circular list is use for the builtin.
Proper locking is not done when accessing the list.
FIXME: not thread-safe. */
#include <mailutils/iterator.h>
#include <registrar0.h>
static struct _registrar registrar [] =
{
{ NULL, NULL, 0, &registrar[1] }, /* sentinel, head list */
{ &_url_file_registrar, &_mailbox_mbox_registrar, 0, &registrar[2] },
{ &_url_mbox_registrar, &_mailbox_mbox_registrar, 0, &registrar[3] },
{ &_url_unix_registrar, &_mailbox_unix_registrar, 0, &registrar[4] },
{ &_url_maildir_registrar, &_mailbox_maildir_registrar, 0, &registrar[5] },
{ &_url_mmdf_registrar, &_mailbox_mmdf_registrar, 0, &registrar[6] },
{ &_url_pop_registrar, &_mailbox_pop_registrar, 0, &registrar[7] },
{ &_url_imap_registrar, &_mailbox_imap_registrar, 0, &registrar[0] },
};
static void
free_ureg (struct url_registrar *ureg)
{
if (ureg)
{
free ((char *)ureg->scheme);
free (ureg);
}
}
static list_t reg_list;
static void
free_mreg (struct mailbox_registrar *mreg)
int
registrar_get_list (list_t *plist)
{
if (mreg)
if (plist == NULL)
return EINVAL;
if (reg_list == NULL)
{
free ((char *)mreg->name);
free (mreg);
int status = list_create (&reg_list);
if (status != 0)
return status;
}
*plist = reg_list;
return 0;
}
int
registrar_add (struct url_registrar *new_ureg,
struct mailbox_registrar *new_mreg, int *id)
record_is_scheme (record_t record, const char *scheme)
{
struct _registrar *entry;
struct url_registrar *ureg = NULL;
struct mailbox_registrar *mreg;
if (record == NULL)
return 0;
/* Must registrar a mailbox */
if (new_mreg == NULL)
return EINVAL;
/* Mailbox */
mreg = calloc (1, sizeof (*mreg));
if (mreg == NULL)
return ENOMEM;
/* Overload. */
if (record->_is_scheme)
return record->_is_scheme (record, scheme);
if (new_mreg->name)
{
mreg->name = strdup (new_mreg->name);
if (mreg->name == NULL)
{
free (mreg);
return ENOMEM;
}
}
mreg->_create = new_mreg->_create;
mreg->_destroy = new_mreg->_destroy;
if (record->scheme && strncasecmp (record->scheme, scheme,
strlen (record->scheme)) == 0)
return 1;
/* URL */
if (new_ureg)
{
ureg = calloc (1, sizeof (*ureg));
if (ureg == NULL)
{
free_mreg (mreg);
return ENOMEM;
}
if (new_ureg->scheme)
{
ureg->scheme = strdup (new_ureg->scheme);
if (ureg->scheme == NULL)
{
free_mreg (mreg);
free_ureg (ureg);
return ENOMEM;
}
}
ureg->_create = new_ureg->_create;
ureg->_destroy = new_ureg->_destroy;
}
/* Register them to the list */
entry = calloc (1, sizeof (*entry));
if (entry == NULL)
{
free_mreg (mreg);
free_ureg (ureg);
return ENOMEM;
}
entry->ureg = ureg;
entry->mreg = mreg;
entry->is_allocated = 1;
entry->next = registrar->next;
registrar->next = entry;
if (id)
*id = (int)entry;
return 0;
}
int
registrar_remove (int id)
record_get_mailbox (record_t record, mailbox_entry_t *pmbox)
{
struct _registrar *current, *previous;
for (previous = registrar, current = registrar->next;
current != registrar;
previous = current, current = current->next)
{
if ((int)current == id)
{
previous->next = current->next;
if (current->is_allocated)
{
free_ureg (current->ureg);
free_mreg (current->mreg);
}
free (current);
return 0;;
}
}
return EINVAL;
}
if (record == NULL)
return EINVAL;
int
registrar_get (int id,
struct url_registrar **ureg, struct mailbox_registrar **mreg)
{
struct _registrar *current;
for (current = registrar->next; current != registrar;
current = current->next)
{
if ((int)current == id)
{
if (mreg)
*mreg = current->mreg;
if (ureg)
*ureg = current->ureg;
return 0;
}
}
return EINVAL;
}
/* Overload. */
if (record->_get_mailbox)
return record->_get_mailbox (record, pmbox);
int
registrar_entry_count (size_t *num)
{
struct _registrar *current;
size_t count;
for (count = 0, current = registrar->next; current != registrar;
current = current->next, count++)
;
if (num)
*num = count;
if (pmbox)
*pmbox = record->mailbox;
return 0;
}
int
registrar_entry (size_t num, struct url_registrar **ureg,
struct mailbox_registrar **mreg, int *id)
{
struct _registrar *current;
size_t count, status;
for (status = ENOENT, count = 0, current = registrar->next;
current != registrar; current = current->next, count++)
{
if (num == count)
{
if (ureg)
*ureg = current->ureg;
if (mreg)
*mreg = current->mreg;
if (id)
*id = (int)current;
status = 0;
break;
}
}
return status;
}
int
registrar_list (struct url_registrar **ureg, struct mailbox_registrar **mreg,
int *id, registrar_t *reg)
record_get_mailer (record_t record, mailer_entry_t *pml)
{
struct _registrar *current;
if (reg == NULL)
if (record == NULL)
return EINVAL;
current = *reg;
if (current == NULL)
current = registrar;
if (current->next == registrar)
return -1;
if (ureg)
*ureg = current->ureg;
if (mreg)
*mreg = current->mreg;
if (id)
*id = (int)current;
*reg = current->next;
/* Overload. */
if (record->_get_mailer)
return record->_get_mailer (record, pml);
if (pml)
*pml = record->mailer;
return 0;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <mailutils/stream.h>
#include <mailer0.h>
#include <registrar0.h>
#include <misc.h>
static int sendmail_init (mailer_t);
static struct mailer_entry _sendmail_entry =
{
url_sendmail_init, sendmail_init
};
static struct _record _sendmail_record =
{
MU_SENDMAIL_SCHEME,
NULL, /* Mailbox entry. */
&_sendmail_entry, /* Mailer entry. */
0, /* Not malloc()ed. */
NULL, /* No need for an owner. */
NULL, /* is_scheme method. */
NULL, /* get_mailbox method. */
NULL /* get_mailer method. */
};
/* We export two functions: url parsing and the initialisation of
the mailbox, via the register entry/record. */
record_t sendmail_record = &_sendmail_record;
mailer_entry_t sendmail_entry = &_sendmail_entry;
struct _sendmail
{
int dsn;
char *path;
pid_t pid;
off_t offset;
int fd;
enum sendmail_state { SENDMAIL_NO_STATE, SENDMAIL_SEND } state;
};
typedef struct _sendmail * sendmail_t;
static void sendmail_destroy (mailer_t);
static int sendmail_open (mailer_t, int);
static int sendmail_close (mailer_t);
static int sendmail_send_message (mailer_t, const char *from, const char *rcpt,
int dsn, message_t);
int
sendmail_init (mailer_t mailer)
{
sendmail_t sendmail;
/* Allocate memory specific to sendmail mailer. */
sendmail = mailer->data = calloc (1, sizeof (*sendmail));
if (mailer->data == NULL)
return ENOMEM;
sendmail->state = SENDMAIL_NO_STATE;
mailer->_init = sendmail_init;
mailer->_destroy = sendmail_destroy;
mailer->_open = sendmail_open;
mailer->_close = sendmail_close;
mailer->_send_message = sendmail_send_message;
return 0;
}
static void
sendmail_destroy(mailer_t mailer)
{
sendmail_t sendmail = mailer->data;
if (sendmail)
{
if (sendmail->path)
free (sendmail->path);
free (sendmail);
mailer->data = NULL;
}
}
static int
sendmail_open (mailer_t mailer, int flags)
{
sendmail_t sendmail = mailer->data;
int status;
size_t pathlen = 0;
char *path;
/* Sanity checks. */
if (sendmail == NULL)
return EINVAL;
mailer->flags = flags | MU_STREAM_SENDMAIL;
/* Fetch the mailer server name and the port in the url_t. */
if ((status = url_get_path (mailer->url, NULL, 0, &pathlen)) != 0
|| pathlen == 0)
return status;
path = calloc (pathlen + 1, sizeof (char));
url_get_path (mailer->url, path, pathlen + 1, NULL);
if (access (path, X_OK) == -1)
{
free (path);
return errno;
}
sendmail->path = path;
return 0;
}
static int
sendmail_close (mailer_t mailer)
{
(void)mailer;
return 0;
}
static int
sendmail_send_message (mailer_t mailer, const char *from, const char *rcpt,
int dsn, message_t msg)
{
sendmail_t sendmail = mailer->data;
int status = 0;
if (sendmail == NULL || msg == NULL)
return EINVAL;
sendmail->dsn = dsn;
switch (sendmail->state)
{
case SENDMAIL_NO_STATE:
{
int tunnel[2];
int argc = 3;
char **argvec = NULL;
argvec = realloc (argvec, argc * (sizeof (*argvec)));
argvec[0] = sendmail->path;
/* do not treat '.' as message terminator*/
argvec[1] = strdup ("-oi");
argvec[2] = strdup ("-t");
if (from)
{
size_t len = strlen (from) + 1;
char *addr = calloc (len, sizeof (char));
if (parseaddr (from, addr, len) == 0)
{
argc++;
argvec = realloc (argvec, argc * (sizeof (*argvec)));
argvec[argc - 1] = strdup ("-f");
argc++;
argvec = realloc (argvec, argc * (sizeof (*argvec)));
argvec[argc - 1] = addr;
}
else
free (addr);
}
if (rcpt)
{
const char *p = rcpt;
do
{
size_t len = strlen (p) + 1;
char *addr = calloc (len, sizeof (char));
if (parseaddr (rcpt, addr, len) == 0)
{
argc++;
argvec = realloc (argvec, argc * (sizeof (*argvec)));
argvec[argc - 1] = addr;
}
else
free (addr);
p = strchr (p, ',');
if (p != NULL)
p++;
}
while (p != NULL && *p != '\0');
}
argc++;
argvec = realloc (argvec, argc * (sizeof (*argvec)));
argvec[argc - 1] = NULL;
if (pipe (tunnel) == 0)
{
sendmail->fd = tunnel [1];
sendmail->pid = fork ();
if (sendmail->pid == 0) /* Child. */
{
close (STDIN_FILENO);
close (STDOUT_FILENO);
close (STDERR_FILENO);
close (tunnel[1]);
dup2 (tunnel[0], STDIN_FILENO);
execv (sendmail->path, argvec);
exit (1);
}
else if (sendmail->pid == -1)
status = errno;
}
else
status = errno;
for (argc = 0; argvec[argc]; argc++)
free (argvec[argc]);
free (argvec);
close (tunnel[0]);
if (status != 0)
{
close (sendmail->fd);
break;
}
sendmail->state = SENDMAIL_SEND;
}
case SENDMAIL_SEND: /* Parent. */
{
stream_t stream = NULL;
char buffer[512];
size_t len = 0;
int rc;
message_get_stream (msg, &stream);
while ((status = stream_read (stream, buffer, sizeof (buffer),
sendmail->offset, &len)) == 0
&& len != 0)
{
if (write (sendmail->fd, buffer, len) == -1)
{
status = errno;
break;
}
sendmail->offset += len;
}
if (status == EAGAIN)
return status;
close (sendmail->fd);
rc = waitpid(sendmail->pid, &status, 0);
if (rc < 0)
status = errno;
else if (WIFEXITED(status))
status = WEXITSTATUS(status);
}
default:
break;
}
sendmail->state = SENDMAIL_NO_STATE;
return status;
}
......@@ -15,6 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
......@@ -65,6 +69,13 @@ stream_set_destroy (stream_t stream, void (*_destroy) (stream_t), void *owner)
return 0;
}
void *
stream_get_owner (stream_t stream)
{
return (stream) ? stream->owner : NULL;
}
int
stream_open (stream_t stream, const char *name, int port, int flags)
{
......@@ -253,13 +264,11 @@ stream_get_flags (stream_t stream, int *pfl)
}
int
stream_set_flags (stream_t stream, int fl, void *owner)
stream_set_flags (stream_t stream, int fl)
{
if (stream == NULL)
return EINVAL;
if (stream->owner != owner)
return EACCES;
stream->flags = fl;
stream->flags |= fl;
return 0;
}
......
......@@ -15,6 +15,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
......@@ -27,12 +31,12 @@
#include <arpa/inet.h>
#include <unistd.h>
#include <stream0.h>
#include <mailutils/stream.h>
#include <tcp0.h>
static int _tcp_close(stream_t stream)
{
struct _tcp_instance *tcp = stream->owner;
struct _tcp_instance *tcp = stream_get_owner(stream);
if ( tcp->fd != -1 )
close(tcp->fd);
......@@ -43,7 +47,7 @@ static int _tcp_close(stream_t stream)
static int _tcp_open(stream_t stream, const char *host, int port, int flags)
{
struct _tcp_instance *tcp = stream->owner;
struct _tcp_instance *tcp = stream_get_owner(stream);
int flgs, ret;
size_t namelen;
struct sockaddr_in peer_addr;
......@@ -66,7 +70,7 @@ static int _tcp_open(stream_t stream, const char *host, int port, int flags)
flgs = fcntl(tcp->fd, F_GETFL);
flgs |= O_NONBLOCK;
fcntl(tcp->fd, F_SETFL, flgs);
stream->flags |= MU_STREAM_NONBLOCK;
stream_set_flags (stream, MU_STREAM_NONBLOCK);
}
tcp->state = TCP_STATE_RESOLVING;
case TCP_STATE_RESOLVING:
......@@ -115,7 +119,7 @@ static int _tcp_open(stream_t stream, const char *host, int port, int flags)
static int _tcp_get_fd(stream_t stream, int *fd)
{
struct _tcp_instance *tcp = stream->owner;
struct _tcp_instance *tcp = stream_get_owner(stream);
if ( fd == NULL || tcp->fd == EINVAL )
return EINVAL;
......@@ -126,7 +130,7 @@ static int _tcp_get_fd(stream_t stream, int *fd)
static int _tcp_read(stream_t stream, char *buf, size_t buf_size, off_t offset, size_t *br)
{
struct _tcp_instance *tcp = stream->owner;
struct _tcp_instance *tcp = stream_get_owner(stream);
int bytes;
offset = offset;
......@@ -143,7 +147,7 @@ static int _tcp_read(stream_t stream, char *buf, size_t buf_size, off_t offset,
static int _tcp_write(stream_t stream, const char *buf, size_t buf_size, off_t offset, size_t *bw)
{
struct _tcp_instance *tcp = stream->owner;
struct _tcp_instance *tcp = stream_get_owner(stream);
int bytes;
offset = offset;
......@@ -160,7 +164,7 @@ static int _tcp_write(stream_t stream, const char *buf, size_t buf_size, off_t o
static void _tcp_destroy(stream_t stream)
{
struct _tcp_instance *tcp = stream->owner;
struct _tcp_instance *tcp = stream_get_owner(stream);
if ( tcp->host )
free(tcp->host);
......
......@@ -15,13 +15,16 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stream0.h>
#include <mailutils/stream.h>
struct _ts_desc {
const char *encoding;
......@@ -45,7 +48,7 @@ int _qp_decode(const char *iptr, size_t isize, char *optr, size_t *nbytes);
int _qp_encode(const char *iptr, size_t isize, char *optr, size_t *nbytes);
#define NUM_TRANSCODERS 5
struct _ts_desc tslist[NUM_TRANSCODERS] = { { "base64", _base64_decode, _base64_encode},
struct _ts_desc tslist[NUM_TRANSCODERS] = { { "base64", _base64_decode, _base64_encode},
{ "quoted-printable", _qp_decode, _qp_encode},
{ "7bit", NULL, NULL},
{ "8bit", NULL, NULL},
......@@ -54,28 +57,28 @@ struct _ts_desc tslist[NUM_TRANSCODERS] = { { "base64", _base64_decode,
static void _trans_destroy(stream_t stream)
{
struct _trans_stream *ts = stream->owner;
struct _trans_stream *ts = stream_get_owner(stream);
stream_destroy(&(ts->stream), NULL);
if ( ts->leftover )
free(ts->leftover);
free(ts);
free(ts->leftover);
free(ts);
}
static int _trans_read(stream_t stream, char *optr, size_t osize, off_t offset, size_t *nbytes)
{
struct _trans_stream *ts = stream->owner;
struct _trans_stream *ts = stream_get_owner(stream);
size_t isize = osize;
char *iptr;
int consumed, ret;
if ( nbytes == NULL || optr == NULL || osize == 0 )
return EINVAL;
*nbytes = 0;
if ( offset == 0 )
ts->cur_offset = 0;
ts->cur_offset = 0;
if ( ( iptr = alloca(isize) ) == NULL )
return ENOMEM;
if ( ts->leftover ) {
......@@ -83,16 +86,16 @@ static int _trans_read(stream_t stream, char *optr, size_t osize, off_t offset,
free( ts->leftover );
ts->leftover = NULL;
ts->offset = 0; // encase of error;
}
if ( ( ret = stream_read(ts->stream, iptr + ts->llen, isize - ts->llen, ts->cur_offset, &osize) ) != 0 )
}
if ( ( ret = stream_read(ts->stream, iptr + ts->llen, isize - ts->llen, ts->cur_offset, &osize) ) != 0 )
return ret;
ts->cur_offset += osize;
consumed = ts->transcoder(iptr, osize + ts->llen, optr, nbytes);
if ( ( ts->llen = ((osize + ts->llen) - consumed ) ) )
if ( ( ts->llen = ((osize + ts->llen) - consumed ) ) )
{
if ( ( ts->leftover = malloc(ts->llen) ) == NULL )
return ENOMEM;
memcpy(ts->leftover, iptr + consumed, ts->llen);
memcpy(ts->leftover, iptr + consumed, ts->llen);
}
return 0;
}
......@@ -100,11 +103,11 @@ static int _trans_read(stream_t stream, char *optr, size_t osize, off_t offset,
static int _trans_write(stream_t stream, const char *iptr, size_t isize, off_t offset, size_t *nbytes)
{
struct _trans_stream *ts = stream->owner;
struct _trans_stream *ts = stream_get_owner(stream);
size_t osize = isize;
char *optr;
int ret;
if ( nbytes == NULL || iptr == NULL || isize == 0 )
return EINVAL;
......@@ -113,16 +116,16 @@ static int _trans_write(stream_t stream, const char *iptr, size_t isize, off_t o
if ( offset && ts->cur_offset != offset )
return ESPIPE;
if ( offset == 0 )
ts->cur_offset = 0;
ts->cur_offset = 0;
if ( ( optr = alloca(osize) ) == NULL )
return ENOMEM;
*nbytes = ts->transcoder(iptr, isize, optr, &osize);
if ( ( ret = stream_write(ts->stream, optr, osize, ts->cur_offset, &osize) ) != 0 )
if ( ( ret = stream_write(ts->stream, optr, osize, ts->cur_offset, &osize) ) != 0 )
return ret;
ts->cur_offset += osize;
return 0;
}
......@@ -130,10 +133,10 @@ int encoder_stream_create(stream_t *stream, stream_t iostream, const char *encod
{
struct _trans_stream *ts;
int i, ret;
if ( stream == NULL || iostream == NULL || encoding == NULL )
return EINVAL;
if ( ( ts = calloc(sizeof(struct _trans_stream), 1) ) == NULL )
return ENOMEM;
for( i = 0; i < NUM_TRANSCODERS; i++ ) {
......@@ -145,7 +148,7 @@ int encoder_stream_create(stream_t *stream, stream_t iostream, const char *encod
if ( ( ret = stream_create(stream, MU_STREAM_RDWR, ts) ) != 0 )
return ret;
ts->transcoder = tslist[i].encode;
ts->transcoder = tslist[i].encode;
stream_set_read(*stream, _trans_read, ts );
stream_set_write(*stream, _trans_write, ts );
stream_set_destroy(*stream, _trans_destroy, ts );
......@@ -157,10 +160,10 @@ int decoder_stream_create(stream_t *stream, stream_t iostream, const char *encod
{
struct _trans_stream *ts;
int i, ret;
if ( stream == NULL || iostream == NULL || encoding == NULL )
return EINVAL;
if ( ( ts = calloc(sizeof(struct _trans_stream), 1) ) == NULL )
return ENOMEM;
for( i = 0; i < NUM_TRANSCODERS; i++ ) {
......@@ -172,7 +175,7 @@ int decoder_stream_create(stream_t *stream, stream_t iostream, const char *encod
if ( ( ret = stream_create(stream, MU_STREAM_RDWR, ts) ) != 0 )
return ret;
ts->transcoder = tslist[i].decode;
ts->transcoder = tslist[i].decode;
stream_set_read(*stream, _trans_read, ts );
stream_set_write(*stream, _trans_write, ts );
stream_set_destroy(*stream, _trans_destroy, ts );
......@@ -209,7 +212,7 @@ int _base64_decode(const char *iptr, size_t isize, char *optr, size_t *nbytes)
int i = 0, tmp = 0;
size_t consumed = 0;
char data[4];
while ( consumed < isize ) {
while ( ( i < 4 ) && ( consumed < isize ) ) {
tmp = _b64_input(*iptr++);
......@@ -273,7 +276,7 @@ int _qp_decode(const char *iptr, size_t isize, char *optr, size_t *nbytes)
char c;
int last_char = 0;
size_t consumed = 0;
while (consumed < isize) {
c = *iptr++;
if ( ((c >= 33) && (c <= 60)) || ((c >= 62) && (c <= 126)) || ((c == '=') && !_ishex(*iptr)) ) {
......@@ -285,7 +288,7 @@ int _qp_decode(const char *iptr, size_t isize, char *optr, size_t *nbytes)
// there must be 2 more characters before I consume this
if ((isize - consumed) < 3) {
return consumed;
}
}
else {
// you get =XX where XX are hex characters
char chr[2];
......@@ -336,7 +339,7 @@ int _qp_encode(const char *iptr, size_t isize, char *optr, size_t *nbytes)
{
int count = 0, c;
size_t consumed = 0;
while (consumed < isize && (*nbytes + 4) < isize) {
if (count == QP_LINE_MAX) {
*optr++ = '=';
......
......@@ -15,13 +15,16 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <steam0.h>
#include <mailutils/sys/steam0.h>
#include <mailutils/transcode.h>
int _base64_decode(stream_t stream, char *optr, size_t osize, off_t offset, size_t *nbytes);
......
......@@ -19,98 +19,23 @@
# include <config.h>
#endif
#include <url0.h>
#include <registrar0.h>
#include <cpystr.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
/* Forward prototypes */
static int get_scheme (const url_t, char *, size_t, size_t *);
static int get_user (const url_t, char *, size_t, size_t *);
static int get_passwd (const url_t, char *, size_t, size_t *);
static int get_host (const url_t, char *, size_t, size_t *);
static int get_port (const url_t, long *);
static int get_path (const url_t, char *, size_t, size_t *);
static int get_query (const url_t, char *, size_t, size_t *);
static int get_id (const url_t, int *);
#include <mailutils/registrar.h>
#include <misc.h>
#include <url0.h>
int
url_create (url_t * purl, const char *name)
url_create (url_t *purl, const char *name)
{
int status = EINVAL;
struct url_registrar *ureg;
struct mailbox_registrar *mreg;
size_t name_len;
int id;
size_t i, entry_count = 0;
/* Sanity checks */
if (name == NULL || *name == '\0')
return status;
name_len = strlen (name);
/* Search for a known scheme */
registrar_entry_count (&entry_count);
for (i = 0; i < entry_count; i++)
{
if (registrar_entry (i, &ureg, &mreg, &id) == 0)
{
size_t scheme_len;
if (ureg && ureg->scheme &&
name_len > (scheme_len = strlen (ureg->scheme)) &&
memcmp (name, ureg->scheme, scheme_len) == 0)
{
status = 0;
break;
}
}
}
/*
while (registrar_list (&ureg, &mreg, &id, &reg) == 0)
{
size_t scheme_len;
if (ureg && ureg->scheme &&
name_len > (scheme_len = strlen (ureg->scheme)) &&
memcmp (name, ureg->scheme, scheme_len) == 0)
{
status = 0;
break;
}
}
*/
/* Found one initialize it */
if (status == 0)
{
status = ureg->_create (purl, name);
if (status == 0)
{
url_t url = *purl;
url->id = id;
if (url->_get_id == NULL)
url->_get_id = get_id;
if (url->_get_scheme == NULL)
url->_get_scheme = get_scheme;
if (url->_get_user == NULL)
url->_get_user = get_user;
if (url->_get_passwd == NULL)
url->_get_passwd = get_passwd;
if (url->_get_host == NULL)
url->_get_host = get_host;
if (url->_get_port == NULL)
url->_get_port = get_port;
if (url->_get_path == NULL)
url->_get_path = get_path;
if (url->_get_query == NULL)
url->_get_query = get_query;
}
}
return status;
url_t url = calloc(1, sizeof (*url));
if (url == NULL)
return ENOMEM;
url->name = strdup (name);
*purl = url;
return 0;
}
void
......@@ -118,142 +43,144 @@ url_destroy (url_t *purl)
{
if (purl && *purl)
{
struct url_registrar *ureg;
int id;
url_get_id (*purl, &id);
registrar_get (id, &ureg, NULL);
ureg->_destroy(purl);
(*purl) = NULL;
}
}
url_t url = (*purl);
if (url->_destroy)
url->_destroy (url);
int (url_get_scheme) (const url_t url, char *scheme, size_t len, size_t *n)
{
return (url) ? url->_get_scheme(url, scheme, len, n) : EINVAL;
}
if (url->name)
free (url->name);
int (url_get_user) (const url_t url, char *user, size_t len, size_t *n)
{
return (url) ? url->_get_user(url, user, len, n) : EINVAL;
}
int (url_get_passwd) (const url_t url, char *passwd, size_t len, size_t *n)
{
return (url) ? url->_get_passwd(url, passwd, len, n) : EINVAL;
}
if (url->scheme)
free (url->scheme);
int (url_get_host) (const url_t url, char *host, size_t len, size_t *n)
{
return (url) ? url->_get_host(url, host, len, n) : EINVAL;
}
if (url->user)
free (url->user);
int (url_get_port) (const url_t url, long *port)
{
return (url) ? url->_get_port(url, port) : EINVAL;
}
if (url->passwd)
free (url->passwd);
int (url_get_path) (const url_t url, char *path, size_t len, size_t *n)
{
return (url) ? url->_get_path(url, path, len, n) : EINVAL;
}
if (url->host)
free (url->host);
int (url_get_query) (const url_t url, char *query, size_t len, size_t *n)
{
return (url) ? url->_get_query(url, query, len, n) : EINVAL;
*purl = NULL;
}
}
int (url_get_id) (const url_t url, int *id)
int
url_get_scheme (const url_t url, char *scheme, size_t len, size_t *n)
{
return (url) ? url->_get_id (url, id) : EINVAL;
size_t i;
if (url == NULL)
return EINVAL;
if (url->_get_scheme)
return url->_get_scheme (url, scheme, len, n);
i = _cpystr (scheme, url->scheme, len);
if (n)
*n = i;
return 0;
}
/* Simple stub functions they all call _cpystr */
static int
get_scheme (const url_t u, char *s, size_t len, size_t *n)
int
url_get_user (const url_t url, char *user, size_t len, size_t *n)
{
size_t i;
if (u == NULL)
if (url == NULL)
return EINVAL;
i = _cpystr (s, u->scheme, len);
if (url->_get_user)
return url->_get_user (url, user, len, n);
i = _cpystr (user, url->user, len);
if (n)
*n = i;
return 0;
}
static int
get_user (const url_t u, char *s, size_t len, size_t *n)
/* FIXME: We should not store passwd in clear, but rather
have a simple encoding, and decoding mechanism */
int
url_get_passwd (const url_t url, char *passwd, size_t len, size_t *n)
{
size_t i;
if (u == NULL)
if (url == NULL)
return EINVAL;
i = _cpystr (s, u->user, len);
if (url->_get_passwd)
return url->_get_passwd (url, passwd, len, n);
i = _cpystr (passwd, url->passwd, len);
if (n)
*n = i;
return 0;
}
/* FIXME: We should not store passwd in clear, but rather
have a simple encoding, and decoding mechanism */
static int
get_passwd (const url_t u, char *s, size_t len, size_t *n)
int
url_get_auth (const url_t url, char *auth, size_t len, size_t *n)
{
size_t i;
if (u == NULL)
if (url == NULL)
return EINVAL;
i = _cpystr (s, u->passwd, len);
if (url->_get_auth)
return url->_get_auth (url, auth, len, n);
i = _cpystr (auth, url->auth, len);
if (n)
*n = i;
return 0;
}
static int
get_host (const url_t u, char *s, size_t len, size_t *n)
int
url_get_host (const url_t url, char *host, size_t len, size_t *n)
{
size_t i;
if (u == NULL)
if (url == NULL)
return EINVAL;
i = _cpystr (s, u->host, len);
if (url->_get_host)
return url->_get_host (url, host, len, n);
i = _cpystr (host, url->host, len);
if (n)
*n = i;
return 0;
}
static int
get_port (const url_t u, long * p)
int
url_get_port (const url_t url, long *pport)
{
*p = u->port;
if (url == NULL)
return EINVAL;
if (url->_get_port)
return url->_get_port (url, pport);
*pport = url->port;
return 0;
}
static int
get_path (const url_t u, char *s, size_t len, size_t *n)
int
url_get_path (const url_t url, char *path, size_t len, size_t *n)
{
size_t i;
if (u == NULL)
if (url == NULL)
return EINVAL;
i = _cpystr(s, u->path, len);
if (url->_get_path)
return url->_get_path (url, path, len, n);
i = _cpystr(path, url->path, len);
if (n)
*n = i;
return 0;
}
static int
get_query (const url_t u, char *s, size_t len, size_t *n)
int
url_get_query (const url_t url, char *query, size_t len, size_t *n)
{
size_t i;
if (u == NULL)
if (url == NULL)
return EINVAL;
i = _cpystr(s, u->query, len);
if (url->_get_query)
return url->_get_query (url, query, len, n);
i = _cpystr(query, url->query, len);
if (n)
*n = i;
return 0;
}
static int
get_id (const url_t u, int *id)
const char *
url_to_string (const url_t url)
{
if (id)
*id = u->id;
return 0;
if (url == NULL || url->name == NULL)
return "";
return url->name;
}
......
......@@ -15,74 +15,63 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <url0.h>
#include <registrar0.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
static void url_file_destroy (url_t *purl);
static int url_file_create (url_t *purl, const char *name);
#include <mailutils/registrar.h>
#include <url0.h>
struct url_registrar _url_file_registrar =
{
"file:",
url_file_create, url_file_destroy
};
int url_file_init (url_t purl);
static void url_file_destroy (url_t purl);
static void
url_file_destroy (url_t *purl)
url_file_destroy (url_t url)
{
if (purl && *purl)
{
url_t url = *purl;
free (url->scheme);
free (url->path);
free (url);
*purl = NULL;
}
(void) url;
}
/*
UNIX box
UNIX File
file:path
*/
static int
url_file_create (url_t *purl, const char *name)
int
url_file_init (url_t url)
{
url_t url;
struct url_registrar *ureg = &_url_mbox_registrar;
const char *name = url_to_string (url);
size_t len = strlen (name);
/* reject the obvious */
if (name == NULL || *name == '\0')
if (name == NULL || strncmp (MU_FILE_SCHEME, name, MU_FILE_SCHEME_LEN) != 0
|| len < (MU_FILE_SCHEME_LEN + 1) /* (scheme)+1(path)*/)
return EINVAL;
/* FIXME: do I need to decode url encoding '% hex hex' ? */
url = calloc(1, sizeof (*url));
if (url == NULL)
return ENOMEM;
/* do I need to decode url encoding '% hex hex' ? */
/* TYPE */
url->_create = ureg->_create;
url->_destroy = ureg->_destroy;
url->_init = url_file_init;
url->_destroy = url_file_destroy;
/* SCHEME */
url->scheme = strdup (ureg->scheme);
url->scheme = strdup (MU_FILE_SCHEME);
if (url->scheme == NULL)
{
ureg->_destroy (&url);
url_file_destroy (url);
return ENOMEM;
}
/* PATH */
name += MU_FILE_SCHEME_LEN; /* pass the scheme */
url->path = strdup (name);
if (url->path == NULL)
{
ureg->_destroy (&url);
url_file_destroy (url);
return ENOMEM;
}
*purl = url;
return 0;
}
......
......@@ -15,74 +15,63 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <url0.h>
#include <mailutils/registrar.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
static void url_mbox_destroy (url_t *purl);
static int url_mbox_create (url_t *purl, const char *name);
#include <mailutils/registrar.h>
#include <url0.h>
struct url_registrar _url_mbox_registrar =
{
"/",
url_mbox_create, url_mbox_destroy
};
int url_mbox_init (url_t purl);
static void url_mbox_destroy (url_t purl);
static void
url_mbox_destroy (url_t *purl)
url_mbox_destroy (url_t url)
{
if (purl && *purl)
{
url_t url = *purl;
free (url->scheme);
free (url->path);
free (url);
*purl = NULL;
}
(void) url;
}
/*
UNIX box
UNIX Mbox
mbox:path
*/
static int
url_mbox_create (url_t *purl, const char *name)
int
url_mbox_init (url_t url)
{
url_t url;
struct url_registrar *ureg = &_url_mbox_registrar;
const char *name = url_to_string (url);
size_t len = strlen (name);
/* reject the obvious */
if (name == NULL || *name == '\0')
if (name == NULL || strncmp (MU_MBOX_SCHEME, name, MU_MBOX_SCHEME_LEN) != 0
|| len < (MU_MBOX_SCHEME_LEN + 1) /* (scheme)+1(path)*/)
return EINVAL;
/* FIXME: do I need to decode url encoding '% hex hex' ? */
url = calloc(1, sizeof (*url));
if (url == NULL)
return ENOMEM;
/* do I need to decode url encoding '% hex hex' ? */
/* TYPE */
url->_create = ureg->_create;
url->_destroy = ureg->_destroy;
url->_init = url_mbox_init;
url->_destroy = url_mbox_destroy;
/* SCHEME */
url->scheme = strdup (ureg->scheme);
url->scheme = strdup (MU_MBOX_SCHEME);
if (url->scheme == NULL)
{
ureg->_destroy (&url);
url_mbox_destroy (url);
return ENOMEM;
}
/* PATH */
name += MU_MBOX_SCHEME_LEN; /* pass the scheme */
url->path = strdup (name);
if (url->path == NULL)
{
ureg->_destroy (&url);
url_mbox_destroy (url);
return ENOMEM;
}
*purl = url;
return 0;
}
......
/* GNU mailutils - a suite of utilities for electronic mail
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 Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <mailutils/registrar.h>
#include <url0.h>
static void url_path_destroy (url_t);
int url_path_init (url_t);
static void
url_path_destroy (url_t url)
{
(void)url;
}
int
url_path_init (url_t url)
{
const char *name = url_to_string (url);
/* reject the obvious */
if (name == NULL || *name == '\0')
return EINVAL;
/* FIXME: do I need to decode url encoding '% hex hex' ? */
/* TYPE */
url->_init = url_path_init;
url->_destroy = url_path_destroy;
/* SCHEME */
url->scheme = strdup (MU_PATH_SCHEME);
if (url->scheme == NULL)
{
url_path_destroy (url);
return ENOMEM;
}
/* PATH */
url->path = strdup (name);
if (url->path == NULL)
{
url_path_destroy (url);
return ENOMEM;
}
return 0;
}
......@@ -15,73 +15,55 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <url0.h>
#include <mailutils/registrar.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
static void url_pop_destroy (url_t *purl);
static int url_pop_create (url_t *purl, const char *name);
#include <mailutils/registrar.h>
#include <url0.h>
struct url_registrar _url_pop_registrar =
{
"pop://",
url_pop_create, url_pop_destroy
};
static void url_pop_destroy (url_t url);
static void
url_pop_destroy (url_t *purl)
url_pop_destroy (url_t url)
{
if (purl && *purl)
{
url_t url = *purl;
free (url->scheme);
free (url->user);
free (url->passwd);
free (url->host);
free (url);
*purl = NULL;
}
(void)url;
}
/*
POP URL
pop://[<user>;AUTH=<auth>@]<host>[:<port>]
*/
static int
url_pop_create (url_t *purl, const char *name)
int
url_pop_init (url_t url)
{
const char *host_port, *indexe;
struct url_registrar *ureg = &_url_pop_registrar;
size_t scheme_len = strlen (ureg->scheme);
url_t url;
char *name = url->name;
/* reject the obvious */
if (name == NULL || strncmp (ureg->scheme, name, scheme_len) != 0)
if (name == NULL || strncmp (MU_POP_SCHEME, name, MU_POP_SCHEME_LEN) != 0)
return EINVAL;
/* do I need to decode url encoding '% hex hex' ? */
url = calloc(1, sizeof (*url));
if (url == NULL)
return ENOMEM;
/* TYPE */
url->_create = _url_pop_registrar._create;
url->_destroy = _url_pop_registrar._destroy;
url->_init = url_pop_init;
url->_destroy = url_pop_destroy;
/* SCHEME */
url->scheme = strdup ("pop://");
url->scheme = strdup (MU_POP_SCHEME);
if (url->scheme == NULL)
{
url_pop_destroy (&url);
url_pop_destroy (url);
return ENOMEM;
}
name += scheme_len; /* pass the scheme */
name += MU_POP_SCHEME_LEN; /* pass the scheme */
host_port = strchr (name, '@');
if (host_port == NULL)
......@@ -103,7 +85,7 @@ url_pop_create (url_t *purl, const char *name)
url->user = malloc(indexe - name + 1);
if (url->user == NULL)
{
url_pop_destroy (&url);
url_pop_destroy (url);
return -1;
}
((char *)memcpy(url->user, name, indexe - name))[indexe - name] = '\0';
......@@ -112,28 +94,28 @@ url_pop_create (url_t *purl, const char *name)
if (indexe == host_port)
{
/* Use default AUTH '*' */
url->passwd = malloc (1 + 1);
if (url->passwd)
url->auth = malloc (1 + 1);
if (url->auth)
{
url->passwd[0] = '*';
url->passwd[1] = '\0';
url->auth[0] = '*';
url->auth[1] = '\0';
}
}
else
{
/* move pass AUTH= */
indexe += 6;
url->passwd = malloc (host_port - indexe + 1);
if (url->passwd)
url->auth = malloc (host_port - indexe + 1);
if (url->auth)
{
((char *)memcpy (url->passwd, indexe, host_port - indexe))
((char *)memcpy (url->auth, indexe, host_port - indexe))
[host_port - indexe] = '\0';
}
}
if (url->passwd == NULL)
if (url->auth == NULL)
{
url_pop_destroy (&url);
url_pop_destroy (url);
return -1;
}
......@@ -161,7 +143,7 @@ url_pop_create (url_t *purl, const char *name)
if (url->host == NULL)
{
url_pop_destroy (&url);
url_pop_destroy (url);
return ENOMEM;
}
else
......@@ -172,6 +154,5 @@ url_pop_create (url_t *purl, const char *name)
url->host[len - 1] = '\0'; /* leak a bit */
}
*purl = url;
return 0;
}
......