Commit 2af56852 2af5685242353fc7de4a1bcc3c01971066c66e16 by Alain Magloire

A little cleanup and we prepare support for IMAP.

1 parent b80bbd87
......@@ -40,6 +40,7 @@ extern int ticket_create __P ((ticket_t *, void *owner));
extern void ticket_destroy __P ((ticket_t *, void *owner));
extern void * ticket_get_owner __P ((ticket_t));
extern int ticket_set_pop __P ((ticket_t, int (*_pop) __P ((ticket_t, const char *, char **)), void *));
extern int ticket_pop __P ((ticket_t, const char *, char **));
extern int ticket_get_type __P ((ticket_t, char *, size_t, size_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 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 _MAILUTILS_FOLDER_H
# define _MAILUTILS_FOLDER_H
#include <sys/types.h>
#include <mailutils/url.h>
#include <mailutils/observer.h>
#include <mailutils/debug.h>
#include <mailutils/list.h>
#include <mailutils/auth.h>
#include <mailutils/stream.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __P
# ifdef __STDC__
# define __P(args) args
# else
# define __P(args) ()
# endif
#endif /*__P */
/* Forward declaration. */
struct _folder;
typedef struct _folder *folder_t;
/* Constructor/destructor and possible types. */
extern int folder_create __P ((folder_t *, const char *));
extern void folder_destroy __P ((folder_t *));
extern int folder_open __P ((folder_t, int flag));
extern int folder_close __P ((folder_t));
extern int folder_delete_mailbox __P ((folder_t, const char *));
extern int folder_list __P ((folder_t, list_t *list));
/* Stream settings. */
extern int folder_get_stream __P ((folder_t, stream_t *));
extern int folder_set_stream __P ((folder_t, stream_t));
/* Notifications. */
extern int folder_get_observable __P ((folder_t, observable_t *));
extern int folder_set_observable __P ((folder_t, observable_t));
extern int folder_get_debug __P ((folder_t, debug_t *));
extern int folder_set_debug __P ((folder_t, debug_t));
/* Authentication. */
extern int folder_get_authority __P ((folder_t, authority_t *));
extern int folder_set_authority __P ((folder_t, authority_t));
extern int folder_get_ticket __P ((folder_t, ticket_t *));
extern int folder_set_ticket __P ((folder_t, ticket_t));
/* URL. */
extern int folder_get_url __P ((folder_t, url_t *));
extern int folder_set_url __P ((folder_t, url_t));
extern int folder_decremente __P ((folder_t));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_FOLDER_H */
......@@ -39,6 +39,7 @@ extern int list_create __P ((list_t *));
extern void list_destroy __P ((list_t *));
extern int list_append __P ((list_t, void *item));
extern int list_prepend __P ((list_t, void *item));
extern int list_is_empty __P ((list_t));
extern int list_count __P ((list_t, size_t *pcount));
extern int list_remove __P ((list_t, void *item));
extern int list_get __P ((list_t, size_t _index, void **pitem));
......
......@@ -46,7 +46,7 @@ struct _mailbox;
typedef struct _mailbox *mailbox_t;
/* Constructor/destructor and possible types. */
extern int mailbox_create __P ((mailbox_t *, const char *, int));
extern int mailbox_create __P ((mailbox_t *, const char *));
extern void mailbox_destroy __P ((mailbox_t *));
extern int mailbox_create_default __P ((mailbox_t *, const char *));
......@@ -73,6 +73,8 @@ extern int mailbox_get_locker __P ((mailbox_t, locker_t *));
extern int mailbox_set_locker __P ((mailbox_t, locker_t));
/* Authentication. */
extern int mailbox_get_authority __P ((mailbox_t, authority_t *));
extern int mailbox_set_authority __P ((mailbox_t, authority_t));
extern int mailbox_get_ticket __P ((mailbox_t, ticket_t *));
extern int mailbox_set_ticket __P ((mailbox_t, ticket_t));
......
......@@ -57,8 +57,7 @@ extern int mailer_set_stream __P ((mailer_t, stream_t));
extern int mailer_get_debug __P ((mailer_t, debug_t *));
extern int mailer_set_debug __P ((mailer_t, debug_t));
extern int mailer_attach __P ((mailer_t, observer_t));
extern int mailer_detach __P ((mailer_t, observer_t));
extern int mailer_get_observable __P ((mailer_t, observable_t *));
extern int mailer_get_url __P ((mailer_t, url_t *));
......
......@@ -38,6 +38,7 @@ typedef struct _observer* observer_t;
typedef struct _observable* observable_t;
#define MU_EVT_MAILBOX_DESTROY 0x001
#define MU_EVT_FOLDER_DESTROY 0x001
#define MU_EVT_MAILER_DESTROY 0x002
#define MU_EVT_MESSAGE_DESTROY 0x004
#define MU_EVT_MESSAGE_ADD 0x008
......@@ -57,7 +58,7 @@ extern int observer_set_flags __P ((observer_t, int flags));
extern int observable_create __P ((observable_t *, void *owner));
extern void observable_destroy __P ((observable_t *, void *owner));
extern void * observable_get_owner __P ((observable_t));
extern int observable_attach __P ((observable_t, observer_t observer));
extern int observable_attach __P ((observable_t, size_t type, observer_t observer));
extern int observable_detach __P ((observable_t, observer_t observer));
extern int observable_notify __P ((observable_t, int type));
......
......@@ -23,6 +23,7 @@
#include <mailutils/url.h>
#include <mailutils/mailbox.h>
#include <mailutils/mailer.h>
#include <mailutils/folder.h>
#include <mailutils/list.h>
#ifndef __P
......@@ -41,6 +42,8 @@ struct mailbox_entry;
typedef struct mailbox_entry* mailbox_entry_t;
struct mailer_entry;
typedef struct mailer_entry* mailer_entry_t;
struct folder_entry;
typedef struct folder_entry* folder_entry_t;
struct _registrar_record;
typedef struct _registrar_record* registrar_record_t;
......@@ -54,6 +57,11 @@ struct mailer_entry
int (*_url_init) __P ((url_t));
int (*_mailer_init) __P ((mailer_t));
};
struct folder_entry
{
int (*_url_init) __P ((url_t));
int (*_folder_init) __P ((folder_t));
};
struct _record;
typedef struct _record* record_t;
......@@ -77,6 +85,10 @@ extern int record_get_mailer __P ((record_t, mailer_entry_t *));
extern int record_set_mailer __P ((record_t, mailer_entry_t));
extern int record_set_get_mailer __P ((record_t, int (*_get_mailer)
__P ((mailer_entry_t *))));
extern int record_get_folder __P ((record_t, folder_entry_t *));
extern int record_set_folder __P ((record_t, folder_entry_t));
extern int record_set_get_folder __P ((record_t, int (*_get_folder)
__P ((folder_entry_t *))));
#define MU_POP_PORT 110
#define MU_POP_SCHEME "pop://"
......@@ -85,6 +97,13 @@ extern int url_pop_init __P ((url_t));
extern mailbox_entry_t pop_entry;
extern record_t pop_record;
#define MU_IMAP_PORT 143
#define MU_IMAP_SCHEME "imap://"
#define MU_IMAP_SCHEME_LEN 7
extern int url_imap_init __P ((url_t));
extern folder_entry_t imap_entry;
extern record_t imap_record;
#define MU_MBOX_SCHEME "mbox:"
#define MU_MBOX_SCHEME_LEN 5
extern int url_mbox_init __P ((url_t));
......
......@@ -55,7 +55,7 @@ mail_copy (int argc, char **argv)
/* filename = login name part */
}
mailbox_create (&mbx, filename, 0);
mailbox_create (&mbx, filename);
mailbox_open (mbx, MU_STREAM_WRITE | MU_STREAM_CREAT);
if (num > 0)
......
......@@ -208,7 +208,7 @@ main (int argc, char **argv)
if (mailbox_create_default (&mbox, args.user) != 0)
exit (EXIT_FAILURE);
}
else if (mailbox_create (&mbox, args.file, 0) != 0)
else if (mailbox_create (&mbox, args.file) != 0)
exit (EXIT_FAILURE);
if (mailbox_open (mbox, MU_STREAM_READ) != 0)
......
......@@ -302,6 +302,8 @@ address_destroy (address_t *paddress)
address_t current;
for (; address; address = current)
{
if (address->addr)
free (address->addr);
if (address->comments)
free (address->comments);
if (address->personal)
......
......@@ -71,8 +71,8 @@ ticket_destroy (ticket_t *pticket, void *owner)
free (ticket->type);
free (ticket);
}
*pticket = NULL;
}
*pticket = NULL;
}
void *
......@@ -145,6 +145,8 @@ ticket_set_type (ticket_t ticket, char *type)
{
if (ticket == NULL)
return EINVAL;
if (ticket->type)
free (ticket->type);
ticket->type = strdup ((type) ? type : "");
return 0;
}
......@@ -190,7 +192,8 @@ authority_set_ticket (authority_t authority, ticket_t ticket)
{
if (authority == NULL)
return EINVAL;
ticket_destroy (&(authority->ticket), authority);
if (authority->ticket)
ticket_destroy (&(authority->ticket), authority);
authority->ticket = ticket;
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/registrar.h>
#include <mailutils/iterator.h>
#include <misc.h>
#include <folder0.h>
int
folder_create (folder_t *pfolder, const char *name)
{
int status = EINVAL;
record_t record = NULL;
folder_entry_t entry = NULL;
iterator_t iterator;
list_t list;
int found = 0;
if (pfolder == NULL)
return EINVAL;
/* Look in the registrar, 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))
{
iterator_current (iterator, (void **)&record);
if (record_is_scheme (record, name))
{
record_get_folder (record, &entry);
if (entry)
{
found = 1;
break;
}
}
}
iterator_destroy (&iterator);
if (found)
{
url_t url = NULL;
folder_t folder = NULL;
/* Allocate memory for mbox. */
folder = calloc (1, sizeof (*folder));
if (folder == NULL)
return ENOMEM;
/* Initialize the internal lock, now so the concrete mailbox
could use it. */
status = RWLOCK_INIT (&(folder->rwlock), NULL);
if (status != 0)
{
folder_destroy (&folder);
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)
{
folder_destroy (&folder);
return status;
}
folder->url = url;
/* Create the concrete folder type. */
status = entry->_folder_init (folder);
if (status != 0)
{
folder_destroy (&folder);
}
else
*pfolder = folder;
}
else
status = ENOENT;
return status;
}
void
folder_destroy (folder_t *pfolder)
{
if (pfolder && *pfolder)
{
folder_t folder = *pfolder;
int destroy_lock = 0;
#ifdef WITH_PTHREAD
pthread_rwlock_t rwlock = folder->rwlock;
#endif
RWLOCK_WRLOCK (&(rwlock));
if (folder_decremente (folder) == 0)
{
RWLOCK_UNLOCK (&(rwlock));
destroy_lock = 1;
/* Notify the observers. */
if (folder->observable)
{
observable_notify (folder->observable, MU_EVT_FOLDER_DESTROY);
observable_destroy (&(folder->observable), folder);
}
if (folder->_destroy)
folder->_destroy (folder);
RWLOCK_WRLOCK (&(rwlock));
if (folder->ticket)
ticket_destroy (&(folder->ticket), folder);
if (folder->authority)
authority_destroy (&(folder->authority), folder);
if (folder->stream)
stream_destroy (&(folder->stream), folder);
if (folder->url)
url_destroy (&(folder->url));
free (folder);
}
RWLOCK_UNLOCK (&(rwlock));
if (destroy_lock)
RWLOCK_DESTROY (&(rwlock));
*pfolder = NULL;
}
}
int
folder_open (folder_t folder, int flags)
{
if (folder == NULL || folder->_open == NULL)
return ENOSYS;
return folder->_open (folder, flags);
}
int
folder_close (folder_t folder)
{
if (folder == NULL || folder->_close == NULL)
return ENOSYS;
return folder->_close (folder);
}
int
folder_set_stream (folder_t folder, stream_t stream)
{
if (folder == NULL)
return EINVAL;
if (folder->stream)
stream_destroy (&(folder->stream), folder);
folder->stream = stream;
return 0;
}
int
folder_get_stream (folder_t folder, stream_t *pstream)
{
if (folder == NULL || pstream == NULL)
return EINVAL;
*pstream = folder->stream;
return 0;
}
int
folder_set_authority (folder_t folder, authority_t authority)
{
if (folder == NULL)
return EINVAL;
if (folder->authority)
authority_destroy (&(folder->authority), folder);
folder->authority = authority;
return 0;
}
int
folder_get_authority (folder_t folder, authority_t *pauthority)
{
if (folder == NULL || pauthority == NULL)
return EINVAL;
*pauthority = folder->authority;
return 0;
}
int
folder_set_ticket (folder_t folder, ticket_t ticket)
{
if (folder == NULL)
return EINVAL;
if (folder->ticket)
ticket_destroy (&(folder->ticket), folder);
folder->ticket = ticket;
return 0;
}
int
folder_get_ticket (folder_t folder, ticket_t *pticket)
{
if (folder == NULL || pticket == NULL)
return EINVAL;
*pticket = folder->ticket;
return 0;
}
int
folder_get_observable (folder_t folder, observable_t *pobservable)
{
if (folder == NULL || pobservable == NULL)
return EINVAL;
if (folder->observable == NULL)
{
int status = observable_create (&(folder->observable), folder);
if (status != 0)
return status;
}
*pobservable = folder->observable;
return 0;
}
int
folder_set_debug (folder_t folder, debug_t debug)
{
if (folder == NULL)
return EINVAL;
if (folder->debug)
debug_destroy (&(folder->debug), folder);
folder->debug = debug;
return 0;
}
int
folder_get_debug (folder_t folder, debug_t *pdebug)
{
if (folder == NULL || pdebug == NULL)
return EINVAL;
if (folder->debug == NULL)
{
int status = debug_create (&(folder->debug), folder);
if (status != 0)
return status;
}
*pdebug = folder->debug;
return 0;
}
int
folder_list (folder_t folder, list_t *plist)
{
if (folder == NULL || folder->_list == NULL)
return ENOSYS;
return folder->_list (folder, plist);
}
int
folder_delete_mailbox (folder_t folder, const char *name)
{
if (folder == NULL || folder->_delete_mailbox == NULL)
return ENOSYS;
return folder->_delete_mailbox (folder, name);
}
int
folder_decremente (folder_t folder)
{
if (folder && folder->_decremente)
return folder->_decremente (folder);
return (folder->ref--);
}
......@@ -18,6 +18,10 @@
#ifndef _ADDRESS0_H
#define _ADDRESS_0H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/address.h>
#ifndef __P
......
......@@ -18,6 +18,10 @@
#ifndef _ATTRIBUTE0_H
# define _ATTRIBUTE0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/attribute.h>
#ifdef __cplusplus
......
......@@ -18,6 +18,10 @@
#ifndef _AUTH0_H
#define _AUTH0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/auth.h>
#include <sys/types.h>
......
......@@ -18,6 +18,10 @@
#ifndef _BIO_H
# define _BIO_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <sys/types.h>
#include <mailutils/stream.h>
......
......@@ -18,6 +18,10 @@
#ifndef _BODY0_H
#define _BODY0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/stream.h>
#include <mailutils/body.h>
......
......@@ -18,6 +18,10 @@
#ifndef _MAILUTILS_DEBUG0_H
#define _MAILUTILS_DEBUG0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#ifndef __P
#ifdef __STDC__
#define __P(args) args
......
/* 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 _FOLDER_H
#define _FOLDER0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#ifdef HAVE_PTHREAD_H
# define __USE_UNIX98 /* ?? */
# include <pthread.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#include <mailutils/folder.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __P
# ifdef __STDC__
# define __P(args) args
# else
# define __P(args) ()
# endif
#endif /*__P */
struct _folder
{
/* Data */
ticket_t ticket;
authority_t authority;
observable_t observable;
debug_t debug;
stream_t stream;
url_t url;
int flags;
size_t ref;
size_t uid;
#ifdef WITH_PTHREAD
pthread_rwlock_t rwlock;
#endif
/* Back pointer to the specific mailbox */
void *data;
/* Public methods */
int (*_init) __P ((folder_t));
void (*_destroy) __P ((folder_t));
int (*_open) __P ((folder_t, int flag));
int (*_close) __P ((folder_t));
int (*_list) __P ((folder_t, list_t *));
int (*_delete_mailbox) __P ((folder_t, const char *));
int (*_decremente) __P ((folder_t));
};
/* To manipulate mailbox rwlock. */
extern int folder_rdlock __P ((folder_t));
extern int folder_wrlock __P ((folder_t));
extern int folder_unlock __P ((folder_t));
#ifdef __cplusplus
}
#endif
#endif /* _MAILBOX0_H */
......@@ -18,6 +18,10 @@
#ifndef _HEADER0_H
#define _HEADER0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/header.h>
#include <sys/types.h>
......
......@@ -18,6 +18,10 @@
#ifndef _ITERATOR0_H
#define _ITERATOR0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/iterator.h>
#ifndef __P
......
......@@ -18,6 +18,10 @@
#ifndef _LIST0_H
#define _LIST0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#ifdef HAVE_PTHREAD_H
# define __USE_UNIX98 /* ?? */
# include <pthread.h>
......
......@@ -18,6 +18,10 @@
#ifndef _MAILBOX0_H
#define _MAILBOX0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#ifdef HAVE_PTHREAD_H
# define __USE_UNIX98 /* ?? */
# include <pthread.h>
......@@ -27,6 +31,7 @@
#include <stdio.h>
#include <mailutils/mailbox.h>
#include <mailutils/folder.h>
#ifdef __cplusplus
extern "C" {
......@@ -50,6 +55,7 @@ struct _mailbox
locker_t locker;
stream_t stream;
url_t url;
folder_t folder;
int flags;
#ifdef WITH_PTHREAD
......
......@@ -18,6 +18,10 @@
#ifndef _MAILER0_H
#define _MAILER0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <sys/types.h>
#include <mailutils/mailer.h>
#ifdef HAVE_PTHREAD_H
......
......@@ -18,6 +18,10 @@
#ifndef _MESSAGE0_H
#define _MESSAGE0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/message.h>
#include <mailutils/mime.h>
......
......@@ -18,6 +18,10 @@
#ifndef _MIME0_H
#define _MIME0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <sys/types.h>
#include <mailutils/mime.h>
......
......@@ -18,6 +18,10 @@
#ifndef _MISC_H
#define _MISC_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
......
......@@ -18,6 +18,10 @@
#ifndef _OBSERVER0_H
#define _OBSERVER0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/observer.h>
#ifndef __P
......@@ -46,6 +50,15 @@ struct _observable
list_t list;
};
struct _event
{
size_t type;
observer_t observer;
};
typedef struct _event *event_t;
#ifdef _cplusplus
}
......
......@@ -18,6 +18,10 @@
#ifndef _REGISTRAR0_H
#define _REGISTRAR0_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/registrar.h>
#ifdef __cplusplus
......@@ -37,11 +41,13 @@ struct _record
const char *scheme;
mailbox_entry_t mailbox;
mailer_entry_t mailer;
folder_entry_t folder;
int is_allocated;
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));
int (*_get_folder) __P ((record_t, folder_entry_t *_mailer));
};
#ifdef __cplusplus
......
......@@ -19,6 +19,9 @@
# define _IO0_H
#include <mailutils/stream.h>
#ifdef DMALLOC
#include <dmalloc.h>
#endif
#ifdef __cplusplus
extern "C" {
......
......@@ -18,6 +18,10 @@
#ifndef _URL0_H
#define _URL0_H 1
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/url.h>
#ifdef __cplusplus
......
......@@ -108,6 +108,14 @@ list_prepend (list_t list, void *item)
}
int
list_is_empty (list_t list)
{
size_t n = 0;
list_count (list, &n);
return n;
}
int
list_count (list_t list, size_t *pcount)
{
if (list == NULL || pcount == NULL)
......
......@@ -34,7 +34,7 @@
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)
mailbox_create (mailbox_t *pmbox, const char *name)
{
int status = EINVAL;
record_t record = NULL;
......@@ -43,7 +43,6 @@ mailbox_create (mailbox_t *pmbox, const char *name, int id)
list_t list;
int found = 0;
(void)id;
if (pmbox == NULL)
return EINVAL;
......@@ -58,10 +57,12 @@ mailbox_create (mailbox_t *pmbox, const char *name, int id)
iterator_current (iterator, (void **)&record);
if (record_is_scheme (record, name))
{
status = record_get_mailbox (record, &entry);
if (status == 0)
found = 1;
break;
record_get_mailbox (record, &entry);
if (entry)
{
found = 1;
break;
}
}
}
iterator_destroy (&iterator);
......@@ -140,6 +141,9 @@ mailbox_destroy (mailbox_t *pmbox)
stream_destroy (&(mbox->stream), mbox);
}
if (mbox->ticket)
ticket_destroy (&(mbox->ticket), mbox);
if (mbox->authority)
authority_destroy (&(mbox->authority), mbox);
......@@ -152,6 +156,9 @@ mailbox_destroy (mailbox_t *pmbox)
if (mbox->debug)
debug_destroy (&(mbox->debug), mbox);
if (mbox->folder)
folder_destroy (&(mbox->folder));
free (mbox);
*pmbox = NULL;
RWLOCK_UNLOCK (&(rwlock));
......@@ -241,7 +248,7 @@ mailbox_set_locker (mailbox_t mbox, locker_t locker)
{
if (mbox == NULL)
return EINVAL;
if (mbox->locker != NULL)
if (mbox->locker)
locker_destroy (&mbox->locker);
mbox->locker = locker;
return 0;
......@@ -252,8 +259,27 @@ mailbox_get_locker (mailbox_t mbox, locker_t *plocker)
{
if (mbox == NULL || plocker == NULL)
return EINVAL;
if (plocker)
*plocker = mbox->locker;
*plocker = mbox->locker;
return 0;
}
int
mailbox_set_authority (mailbox_t mbox, authority_t authority)
{
if (mbox == NULL)
return EINVAL;
if (mbox->authority)
authority_destroy (&(mbox->authority), mbox);
mbox->authority = authority;
return 0;
}
int
mailbox_get_authority (mailbox_t mbox, authority_t *pauthority)
{
if (mbox == NULL || pauthority == NULL)
return EINVAL;
*pauthority = mbox->authority;
return 0;
}
......@@ -262,6 +288,8 @@ mailbox_set_ticket (mailbox_t mbox, ticket_t ticket)
{
if (mbox == NULL)
return EINVAL;
if (mbox->ticket)
ticket_destroy (&(mbox->ticket), mbox);
mbox->ticket = ticket;
return 0;
}
......@@ -271,8 +299,7 @@ mailbox_get_ticket (mailbox_t mbox, ticket_t *pticket)
{
if (mbox == NULL || pticket == NULL)
return EINVAL;
if (pticket)
*pticket = mbox->ticket;
*pticket = mbox->ticket;
return 0;
}
......@@ -281,6 +308,8 @@ mailbox_set_stream (mailbox_t mbox, stream_t stream)
{
if (mbox == NULL)
return EINVAL;
if (mbox->stream)
stream_destroy (&(mbox->stream), mbox);
mbox->stream = stream;
return 0;
}
......@@ -290,8 +319,7 @@ mailbox_get_stream (mailbox_t mbox, stream_t *pstream)
{
if (mbox == NULL || pstream == NULL)
return EINVAL;
if (pstream)
*pstream = mbox->stream;
*pstream = mbox->stream;
return 0;
}
......@@ -316,7 +344,8 @@ mailbox_set_debug (mailbox_t mbox, debug_t debug)
{
if (mbox == NULL)
return EINVAL;
debug_destroy (&(mbox->debug), mbox);
if (mbox->debug)
debug_destroy (&(mbox->debug), mbox);
mbox->debug = debug;
return 0;
}
......
......@@ -184,10 +184,10 @@ mailer_get_stream (mailer_t mailer, stream_t *pstream)
}
int
mailer_attach (mailer_t mailer, observer_t observer)
mailer_get_observable (mailer_t mailer, observable_t *pobservable)
{
/* FIXME: I should check for invalid types */
if (mailer == NULL || observer == NULL)
if (mailer == NULL || pobservable == NULL)
return EINVAL;
if (mailer->observable == NULL)
......@@ -196,18 +196,8 @@ mailer_attach (mailer_t mailer, observer_t observer)
if (status != 0)
return status;
}
return observable_attach (mailer->observable, observer);
}
int
mailer_detach (mailer_t mailer, observer_t observer)
{
/* FIXME: I should check for invalid types */
if (mailer == NULL || observer == NULL)
return EINVAL;
if (mailer->observable == NULL)
return 0;
return observable_detach (mailer->observable, observer);
*pobservable = mailer->observable;
return 0;
}
int
......
......@@ -74,9 +74,9 @@ mailbox_create_default (mailbox_t *pmbox, const char *mail)
if (mail0 == NULL)
return ENOMEM;
sprintf (mail0, "%s/%s", _PATH_MAILDIR, user);
status = mailbox_create (pmbox, mail0, 0);
status = mailbox_create (pmbox, mail0);
free (mail0);
return status;
}
return mailbox_create (pmbox, mail, 0);
return mailbox_create (pmbox, mail);
}
......
......@@ -41,11 +41,13 @@ static struct _record _file_record =
MU_FILE_SCHEME,
&_file_entry, /* Mailbox entry. */
NULL, /* Mailer entry. */
NULL, /* Folder entry. */
0, /* Not malloc()ed. */
NULL, /* No need for an owner. */
NULL, /* is_scheme method. */
NULL, /* get_mailbox method. */
NULL /* get_mailer method. */
NULL, /* get_mailer method. */
NULL /* get_folder method. */
};
record_t file_record = &_file_record;
......@@ -61,11 +63,13 @@ static struct _record _path_record =
MU_PATH_SCHEME,
&_path_entry, /* Mailbox entry. */
NULL, /* Mailer entry. */
NULL, /* Folder entry. */
0, /* Not malloc()ed. */
NULL, /* No need for an owner. */
NULL, /* is_scheme method. */
NULL, /* get_mailbox method. */
NULL /* get_mailer method. */
NULL, /* get_mailer method. */
NULL /* get_folder method. */
};
record_t path_record = &_path_record;
......
......@@ -60,11 +60,13 @@ static struct _record _mbox_record =
MU_MBOX_SCHEME,
&_mbox_entry, /* Mailbox entry. */
NULL, /* Mailer entry. */
NULL, /* Folder entry. */
0, /* Not malloc()ed. */
NULL, /* No need for an owner. */
NULL, /* is_scheme method. */
NULL, /* get_mailbox method. */
NULL /* get_mailer method. */
NULL, /* get_mailer method. */
NULL /* get_folder method. */
};
record_t mbox_record = &_mbox_record;
......@@ -249,7 +251,7 @@ mbox_destroy (mailbox_t mailbox)
free (mud->umessages);
if (mud->name)
free (mud->name);
free (mailbox->data);
free (mud);
mailbox->data = NULL;
mailbox_unlock (mailbox);
}
......
......@@ -50,11 +50,13 @@ static struct _record _pop_record =
MU_POP_SCHEME,
&_pop_entry, /* Mailbox entry. */
NULL, /* Mailer entry. */
NULL, /* folder entry. */
0, /* Not malloc()ed. */
NULL, /* No need for an owner. */
NULL, /* is_scheme method. */
NULL, /* get_mailbox method. */
NULL /* get_mailer method. */
NULL, /* get_mailer method. */
NULL /* get_folder method. */
};
/* We export two functions: url parsing and the initialisation of
......@@ -312,10 +314,10 @@ pop_destroy (mailbox_t mbox)
}
}
bio_destroy (&(mpd->bio));
free (mpd->buffer);
mpd->buffer = NULL;
free (mpd->pmessages);
mpd->pmessages = NULL;
if (mpd->buffer)
free (mpd->buffer);
if (mpd->pmessages)
free (mpd->pmessages);
free (mpd);
mbox->data = NULL;
mailbox_unlock (mbox);
......@@ -335,9 +337,8 @@ pop_user (authority_t auth)
{
case POP_AUTH:
authority_get_ticket (auth, &ticket);
/* Fetch the user/passwd from them. */
/* Fetch the user from them. */
ticket_pop (ticket, "Pop User: ", &mpd->user);
ticket_pop (ticket, "Pop Passwd: ", &mpd->passwd);
status = pop_writeline (mpd, "USER %s\r\n", mpd->user);
CHECK_ERROR_CLOSE(mbox, mpd, status);
MAILBOX_DEBUG0 (mbox, MU_DEBUG_PROT, mpd->buffer);
......@@ -360,9 +361,12 @@ pop_user (authority_t auth)
{
observable_t observable = NULL;
mailbox_get_observable (mbox, &observable);
CLEAR_STATE (mpd);
observable_notify (observable, MU_EVT_AUTHORITY_FAILED);
CHECK_ERROR_CLOSE (mbox, mpd, EACCES);
}
/* Fetch the passwd from them. */
ticket_pop (ticket, "Pop Passwd: ", &mpd->passwd);
status = pop_writeline (mpd, "PASS %s\r\n", mpd->passwd);
/* We have to nuke the passwd. */
memset (mpd->passwd, 0, strlen (mpd->passwd));
......@@ -389,6 +393,7 @@ pop_user (authority_t auth)
{
observable_t observable = NULL;
mailbox_get_observable (mbox, &observable);
CLEAR_STATE (mpd);
observable_notify (observable, MU_EVT_AUTHORITY_FAILED);
CHECK_ERROR_CLOSE (mbox, mpd, EACCES);
}
......@@ -435,13 +440,18 @@ pop_open (mailbox_t mbox, int flags)
if (mpd->buffer == NULL)
{
mpd->buflen = 255;
mpd->buffer = malloc (mpd->buflen + 1);
mpd->buffer = calloc (mpd->buflen + 1, sizeof (char));
if (mpd->buffer == NULL)
{
CHECK_ERROR (mpd, ENOMEM);
}
mpd->ptr = mpd->buffer;
}
else
{
memset (mpd->buffer, '\0', mpd->buflen);
mpd->ptr = mpd->buffer;
}
/* Create the networking stack. */
if (mbox->stream == NULL)
......@@ -479,19 +489,22 @@ pop_open (mailbox_t mbox, int flags)
CHECK_ERROR_CLOSE (mbox, mpd, EACCES);
}
url_get_auth (mbox->url, auth, 64, &n);
if (n == 0 || strcasecmp (auth, "*") == 0)
{
authority_create (&(mbox->authority), mbox->ticket, mbox);
authority_set_authenticate (mbox->authority, pop_user, mbox);
}
else if (strcasecmp (auth, "+apop") == 0)
if (mbox->authority == NULL)
{
/* Not supported. */
}
else
{
/* What can do flag an error ? */
url_get_auth (mbox->url, auth, 64, &n);
if (n == 0 || strcasecmp (auth, "*") == 0)
{
authority_create (&(mbox->authority), mbox->ticket, mbox);
authority_set_authenticate (mbox->authority, pop_user, mbox);
}
else if (strcasecmp (auth, "+apop") == 0)
{
/* Not supported. */
}
else
{
/* What can we do ? flag an error ? */
}
}
mpd->state = POP_AUTH;
}
......
......@@ -576,9 +576,12 @@ void mime_destroy(mime_t *pmime)
if ( mime->mtp_parts != NULL ) {
for ( i = 0; i < mime->nmtp_parts; i++ ) {
mime_part = mime->mtp_parts[i];
if ( mime_part->msg )
if ( mime_part->msg ) {
message_destroy(&mime_part->msg, mime_part);
free (mime_part);
}
}
free (mime->mtp_parts);
}
if ( mime->content_type )
free(mime->content_type);
......
......@@ -134,13 +134,17 @@ observable_destroy (observable_t *pobservable, void *owner)
int status = iterator_create (&iterator, observable->list);
if (status == 0)
{
observer_t observer = NULL;
event_t event = NULL;
for (iterator_first (iterator); !iterator_is_done (iterator);
iterator_next (iterator))
{
iterator_current (iterator, (void **)&observer);
if (observer != NULL)
observer_destroy (&observer, NULL);
event = NULL;
iterator_current (iterator, (void **)&event);
if (event != NULL)
{
observer_destroy (&(event->observer), NULL);
free (event);
}
}
}
list_destroy (&((*pobservable)->list));
......@@ -157,11 +161,17 @@ observable_get_owner (observable_t observable)
}
int
observable_attach (observable_t observable, observer_t observer)
observable_attach (observable_t observable, size_t type, observer_t observer)
{
event_t event;
if (observable == NULL || observer == NULL)
return EINVAL;
return list_append (observable->list, observer);
event = calloc (1, sizeof (*event));
if (event == NULL)
return ENOMEM;
event->type = type;
event->observer = observer;
return list_append (observable->list, event);
}
int
......@@ -170,7 +180,7 @@ observable_detach (observable_t observable, observer_t observer)
iterator_t iterator;
int status;
int found = 0;
observer_t current;
event_t event = NULL;
if (observable == NULL ||observer == NULL)
return EINVAL;
status = iterator_create (&iterator, observable->list);
......@@ -179,22 +189,30 @@ observable_detach (observable_t observable, observer_t observer)
for (iterator_first (iterator); !iterator_is_done (iterator);
iterator_next (iterator))
{
iterator_current (iterator, (void **)&current);
if ((int)(current) == (int)observer)
event = NULL;
iterator_current (iterator, (void **)&event);
if (event && (int)(event->observer) == (int)observer)
{
found = 1;
break;
}
}
iterator_destroy (&iterator);
return (found) ? list_remove (observable->list, observer) : ENOENT;
if (found)
{
status = list_remove (observable->list, event);
free (event);
}
else
status = ENOENT;
return status;
}
int
observable_notify (observable_t observable, int type)
{
iterator_t iterator;
observer_t observer = NULL;
event_t event = NULL;
int status = 0;
if (observable == NULL)
return EINVAL;
......@@ -204,11 +222,11 @@ observable_notify (observable_t observable, int type)
for (iterator_first (iterator); !iterator_is_done (iterator);
iterator_next (iterator))
{
iterator_current (iterator, (void **)&observer);
if (observer)
event = NULL;
iterator_current (iterator, (void **)&event);
if (event && event->type & type)
{
status |= observer_action (observer, type);
observer = NULL;
status |= observer_action (event->observer, type);
}
}
iterator_destroy (&iterator);
......
......@@ -63,29 +63,41 @@ record_is_scheme (record_t record, const char *scheme)
int
record_get_mailbox (record_t record, mailbox_entry_t *pmbox)
{
if (record == NULL)
if (record == NULL || pmbox == NULL)
return EINVAL;
/* Overload. */
if (record->_get_mailbox)
return record->_get_mailbox (record, pmbox);
if (pmbox)
*pmbox = record->mailbox;
*pmbox = record->mailbox;
return 0;
}
int
record_get_mailer (record_t record, mailer_entry_t *pml)
{
if (record == NULL)
if (record == NULL || pml == NULL)
return EINVAL;
/* Overload. */
if (record->_get_mailer)
return record->_get_mailer (record, pml);
if (pml)
*pml = record->mailer;
*pml = record->mailer;
return 0;
}
int
record_get_folder (record_t record, folder_entry_t *pfolder)
{
if (record == NULL || pfolder == NULL)
return EINVAL;
/* Overload. */
if (record->_get_folder)
return record->_get_folder (record, pfolder);
*pfolder = record->folder;
return 0;
}
......
......@@ -43,11 +43,13 @@ static struct _record _sendmail_record =
MU_SENDMAIL_SCHEME,
NULL, /* Mailbox entry. */
&_sendmail_entry, /* Mailer entry. */
NULL, /* Folder entry. */
0, /* Not malloc()ed. */
NULL, /* No need for an owner. */
NULL, /* is_scheme method. */
NULL, /* get_mailbox method. */
NULL /* get_mailer method. */
NULL, /* get_mailer method. */
NULL /* get_folder method. */
};
/* We export two functions: url parsing and the initialisation of
......
......@@ -45,11 +45,13 @@ static struct _record _smtp_record =
MU_SMTP_SCHEME,
NULL, /* Mailbox entry. */
&_smtp_entry, /* Mailer 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. */
NULL, /* get_mailer method. */
NULL /* get_folder method. */
};
/* We export two functions: url parsing and the initialisation of
......@@ -287,8 +289,6 @@ smtp_open (mailer_t mailer, int flags)
}
smtp->ptr = smtp->buffer;
}
status = bio_create (&(smtp->bio), mailer->stream);
CHECK_ERROR (smtp, status);
/* Create a TCP stack if one is not given. */
if (mailer->stream == NULL)
......@@ -296,6 +296,8 @@ smtp_open (mailer_t mailer, int flags)
status = tcp_stream_create (&(mailer->stream));
CHECK_ERROR (smtp, status);
}
status = bio_create (&(smtp->bio), mailer->stream);
CHECK_ERROR (smtp, status);
smtp->state = SMTP_OPEN;
case SMTP_OPEN:
......
......@@ -44,6 +44,7 @@ url_destroy (url_t *purl)
if (purl && *purl)
{
url_t url = (*purl);
if (url->_destroy)
url->_destroy (url);
......@@ -59,9 +60,18 @@ url_destroy (url_t *purl)
if (url->passwd)
free (url->passwd);
if (url->auth)
free (url->auth);
if (url->host)
free (url->host);
if (url->path)
free (url->path);
if (url->query)
free (url->query);
free (url);
*purl = NULL;
......