Commit 3dea5890 3dea5890547c7ec7f941660d011fb82fed1b174a by Alain Magloire

In order to provide inheritance, it is necessary to make

	the base functions/methods visible so the extended object
	could reuse some base methods if necessary.  Inheritance
	is possible because we always add to the end of the vtable
	structure new functions.
	For example, mime_t object will be also a message_t.
	and it will be possible to do
	{
	  mime_t mime;
	  header_t header;
	  ...
	  message_get_header ((message_t)mime, header);
	}
	Another example is tcpstream(socket stream) extends
	fdstream(file description stream);
	Also the name of the functions have change to match better
	there purpose.

	* mailbox2/Makefile.am: lockfile.c added.
	* mailbox2/bstream.c: Reoganisation to make the
	functions visible.
	* mailbox2/dattribute.c: Likewise.
	* mailbox2/dotlock.c: Likewise.
	* mailbox2/fdstream.c: Likewise.
	* mailbox2/fstream.c: Likewise.
	* mailbox2/mapstream.c: Likewise.
	* mailbox2/memstream.c: Likewise.
	* mailbox2/pticket.c: Likewise.
	* mailbox2/sdebug.c: Likewise.
	* mailbox2/tcpstream.c: Likewise.

	* mailbox2/include/mailutils/Makefile.am: lockfile.h added.
	* mailbox2/include/mailutils/attribute.h: Add the new prototypes.
	* mailbox2/include/mailutils/mbox.h: Add the new prototypes.
	* mailbox2/include/mailutils/stream.h: Add the new prototypes.

	* mailbox2/include/mailutils/sys/Makefile.am: dattribute.h lockfile.h
	mapstream.h pticket.h added.
	* mailbox2/include/mailutils/sys/bstream.h: Add new prototypes.
	* mailbox2/include/mailutils/sys/fdstream.h: Likewise.
	* mailbox2/include/mailutils/sys/fstream.h: Likewise.
	* mailbox2/include/mailutils/sys/mbox.h: Likewise.
	* mailbox2/include/mailutils/sys/memstream.h: Likewise.
	* mailbox2/include/mailutils/sys/sdebug.h: Likewise.
	* mailbox2/include/mailutils/sys/tcpstream.h: Likewise.
1 parent 1e6107e6
2001-09-22 Alain Magloire
In order to provide inheritance, it is necessary to make
the base functions/methods visible so the extended object
could reuse some base methods if necessary. Inheritance
is possible because we always add to the end of the vtable
structure new functions.
For example, mime_t object will be also a message_t.
and it will be possible to do
{
mime_t mime;
header_t header;
...
message_get_header ((message_t)mime, header);
}
Another example is tcpstream(socket stream) extends
fdstream(file description stream);
Also the name of the functions have change to match better
there purpose.
* mailbox2/Makefile.am: lockfile.c added.
* mailbox2/bstream.c: Reoganisation to make the
functions visible.
* mailbox2/dattribute.c: Likewise.
* mailbox2/dotlock.c: Likewise.
* mailbox2/fdstream.c: Likewise.
* mailbox2/fstream.c: Likewise.
* mailbox2/mapstream.c: Likewise.
* mailbox2/memstream.c: Likewise.
* mailbox2/pticket.c: Likewise.
* mailbox2/sdebug.c: Likewise.
* mailbox2/tcpstream.c: Likewise.
* mailbox2/include/mailutils/Makefile.am: lockfile.h added.
* mailbox2/include/mailutils/attribute.h: Add the new prototypes.
* mailbox2/include/mailutils/mbox.h: Add the new prototypes.
* mailbox2/include/mailutils/stream.h: Add the new prototypes.
* mailbox2/include/mailutils/sys/Makefile.am: dattribute.h lockfile.h
mapstream.h pticket.h added.
* mailbox2/include/mailutils/sys/bstream.h: Add new prototypes.
* mailbox2/include/mailutils/sys/fdstream.h: Likewise.
* mailbox2/include/mailutils/sys/fstream.h: Likewise.
* mailbox2/include/mailutils/sys/mbox.h: Likewise.
* mailbox2/include/mailutils/sys/memstream.h: Likewise.
* mailbox2/include/mailutils/sys/sdebug.h: Likewise.
* mailbox2/include/mailutils/sys/tcpstream.h: Likewise.
2001-09-20 Sergey Poznyakoff
* frm/frm.c: Print newline not depending on the presence
......@@ -21,22 +69,21 @@
* mailbox2/sdebug.c (mu_debug_stream_create): New function
replace mu_debug_stdio_create().
* mailbox2/fdstream.c (_fds_desroy): Do not close the stream
when distroying, it should have been done explicitely with
when destroying, it should have been done explicitely with
stream_close ();
* mailbox2/fstream.c (_fs_desroy): Do not close the stream
when distroying, it should have been done explicitely with
when destroying, it should have been done explicitely with
stream_close ();
* mailbox2/mapstream.c (_map_desroy): Do not close the stream
when distroying, it should have been done explicitely with
when destroying, it should have been done explicitely with
stream_close ();
* mailbox2/memstream.c (_memory_desroy): Do not close the stream
when distroying, it should have been done explicitely with
when destroying, it should have been done explicitely with
stream_close ();
* mailbox2/tcpstream.c (_tcp_desroy): Do not close the stream
when distroying, it should have been done explicitely with
when destroying, it should have been done explicitely with
stream_close ();
2001-09-18 Sam Roberts
* mailbox/mbx_pop.c: Check url authentication type at
......@@ -2144,7 +2191,7 @@
2001-04-23 Alain Magloire
Sergey Poznyakoff noted: When the user's mailbox has zero size, mmap
fails on Solaris. On GNU/Linux it reuturn NULL buf subsequent munmap
fails on Solaris. On GNU/Linux it return NULL buf subsequent munmap
fails.
* mailbox/mapfile_stream.c: To take care of this, mfs->ptr is set
......
......@@ -25,7 +25,7 @@ libmailbox_la_SOURCES = \
header.c \
iterator.c \
list.c \
locker.c \
lockfile.c \
mailbox.c \
md5-rsa.c \
memstream.c \
......
......@@ -37,14 +37,14 @@
#include <mailutils/sys/bstream.h>
static void
_bs_cleanup (void *arg)
_stream_buffer_cleanup (void *arg)
{
struct _bs *bs = arg;
struct _stream_buffer *bs = arg;
mu_refcount_unlock (bs->refcount);
}
static int
refill (struct _bs *bs)
refill (struct _stream_buffer *bs)
{
int status;
if (bs->rbuffer.base == NULL)
......@@ -60,17 +60,17 @@ refill (struct _bs *bs)
return status;
}
static int
_bs_ref (stream_t stream)
int
_stream_buffer_ref (stream_t stream)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return mu_refcount_inc (bs->refcount);
}
static void
_bs_destroy (stream_t *pstream)
void
_stream_buffer_destroy (stream_t *pstream)
{
struct _bs *bs = (struct _bs *)*pstream;
struct _stream_buffer *bs = (struct _stream_buffer *)*pstream;
if (mu_refcount_dec (bs->refcount) == 0)
{
stream_destroy (&bs->stream);
......@@ -79,17 +79,17 @@ _bs_destroy (stream_t *pstream)
}
}
static int
_bs_open (stream_t stream, const char *name, int port, int flags)
int
_stream_buffer_open (stream_t stream, const char *name, int port, int flags)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_open (bs->stream, name, port, flags);
}
static int
_bs_close (stream_t stream)
int
_stream_buffer_close (stream_t stream)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
mu_refcount_lock (bs->refcount);
/* Clear the buffer of any residue left. */
if (bs->rbuffer.base && bs->rbuffer.bufsize)
......@@ -106,11 +106,11 @@ _bs_close (stream_t stream)
use as a fully fledge buffer mechanism. It is a simple mechanims for
networking. Lots of code between POP and IMAP can be share this way.
The buffering is on the read only, the writes fall through. */
static int
_bs_read (stream_t stream, void *buf, size_t count, size_t *pnread)
int
_stream_buffer_read (stream_t stream, void *buf, size_t count, size_t *pnread)
{
int status = 0;
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
/* Noop. */
if (count == 0)
......@@ -131,7 +131,7 @@ _bs_read (stream_t stream, void *buf, size_t count, size_t *pnread)
int r;
mu_refcount_lock (bs->refcount);
monitor_cleanup_push (_bs_cleanup, bs);
monitor_cleanup_push (_stream_buffer_cleanup, bs);
/* If the amount requested is bigger then the buffer cache size
bypass it. Do no waste time and let it through. */
......@@ -199,11 +199,11 @@ _bs_read (stream_t stream, void *buf, size_t count, size_t *pnread)
* Read at most n-1 characters.
* Stop when a newline has been read, or the count runs out.
*/
static int
_bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread)
int
_stream_buffer_readline (stream_t stream, char *buf, size_t count, size_t *pnread)
{
int status = 0;
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
/* Noop. */
if (count == 0)
......@@ -224,7 +224,7 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread)
size_t total = 0;
mu_refcount_lock (bs->refcount);
monitor_cleanup_push (_bs_cleanup, bs);
monitor_cleanup_push (_stream_buffer_cleanup, bs);
count--; /* Leave space for the null. */
......@@ -277,91 +277,74 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread)
return status;
}
static int
_bs_write (stream_t stream, const void *buf, size_t count, size_t *pnwrite)
int
_stream_buffer_write (stream_t stream, const void *buf, size_t count,
size_t *pnwrite)
{
struct _bs *bs = (struct _bs *)stream;
int err = 0;
size_t nwriten = 0;
size_t total = 0;
int nleft = count;
const char *p = buf;
/* First try to send it all. */
while (nleft > 0)
{
err = stream_write (bs->stream, p, nleft, &nwriten);
if (err != 0 || nwriten == 0)
break;
nleft -= nwriten;
total += nwriten;
p += nwriten;
}
if (pnwrite)
*pnwrite = total;
return err;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_write (bs->stream, buf, count, pnwrite);
}
static int
_bs_get_fd (stream_t stream, int *pfd)
int
_stream_buffer_get_fd (stream_t stream, int *pfd)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_get_fd (bs->stream, pfd);
}
static int
_bs_get_flags (stream_t stream, int *pfl)
int
_stream_buffer_get_flags (stream_t stream, int *pfl)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_get_flags (bs->stream, pfl);
}
static int
_bs_get_size (stream_t stream, off_t *psize)
int
_stream_buffer_get_size (stream_t stream, off_t *psize)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_get_size (bs->stream, psize);
}
static int
_bs_truncate (stream_t stream, off_t len)
int
_stream_buffer_truncate (stream_t stream, off_t len)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_truncate (bs->stream, len);
}
static int
_bs_flush (stream_t stream)
int
_stream_buffer_flush (stream_t stream)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_flush (bs->stream);
}
static int
_bs_get_state (stream_t stream, enum stream_state *pstate)
int
_stream_buffer_get_state (stream_t stream, enum stream_state *pstate)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_get_state (bs->stream, pstate);
}
static int
_bs_seek (stream_t stream, off_t off, enum stream_whence whence)
int
_stream_buffer_seek (stream_t stream, off_t off, enum stream_whence whence)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_seek (bs->stream, off, whence);
}
static int
_bs_tell (stream_t stream, off_t *off)
int
_stream_buffer_tell (stream_t stream, off_t *off)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_tell (bs->stream, off);
}
static int
_bs_is_readready (stream_t stream, int timeout)
int
_stream_buffer_is_readready (stream_t stream, int timeout)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
/* Drain our buffer first. */
mu_refcount_lock (bs->refcount);
if (bs->rbuffer.count > 0)
......@@ -373,62 +356,84 @@ _bs_is_readready (stream_t stream, int timeout)
return stream_is_readready (bs->stream, timeout);
}
static int
_bs_is_writeready (stream_t stream, int timeout)
int
_stream_buffer_is_writeready (stream_t stream, int timeout)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_is_writeready (bs->stream, timeout);
}
static int
_bs_is_exceptionpending (stream_t stream, int timeout)
int
_stream_buffer_is_exceptionpending (stream_t stream, int timeout)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_is_exceptionpending (bs->stream, timeout);
}
static int
_bs_is_open (stream_t stream)
int
_stream_buffer_is_open (stream_t stream)
{
struct _bs *bs = (struct _bs *)stream;
struct _stream_buffer *bs = (struct _stream_buffer *)stream;
return stream_is_open (bs->stream);
}
static struct _stream_vtable _bs_vtable =
static struct _stream_vtable _stream_buffer_vtable =
{
_bs_ref,
_bs_destroy,
_stream_buffer_ref,
_stream_buffer_destroy,
_bs_open,
_bs_close,
_stream_buffer_open,
_stream_buffer_close,
_bs_read,
_bs_readline,
_bs_write,
_stream_buffer_read,
_stream_buffer_readline,
_stream_buffer_write,
_bs_seek,
_bs_tell,
_stream_buffer_seek,
_stream_buffer_tell,
_bs_get_size,
_bs_truncate,
_bs_flush,
_stream_buffer_get_size,
_stream_buffer_truncate,
_stream_buffer_flush,
_bs_get_fd,
_bs_get_flags,
_bs_get_state,
_stream_buffer_get_fd,
_stream_buffer_get_flags,
_stream_buffer_get_state,
_bs_is_readready,
_bs_is_writeready,
_bs_is_exceptionpending,
_stream_buffer_is_readready,
_stream_buffer_is_writeready,
_stream_buffer_is_exceptionpending,
_bs_is_open
_stream_buffer_is_open
};
int
_stream_buffer_ctor (struct _stream_buffer *bs, stream_t stream,
size_t bufsize)
{
mu_refcount_create (&(bs->refcount));
if (bs->refcount == NULL)
return MU_ERROR_NO_MEMORY;
bs->stream = stream;
bs->rbuffer.bufsize = bufsize;
bs->base.vtable = &_stream_buffer_vtable;
return 0;
}
void
_stream_buffer_dtor (struct _stream_buffer *bs)
{
stream_destroy (&bs->stream);
mu_refcount_destroy (&bs->refcount);
}
int
stream_buffer_create (stream_t *pstream, stream_t stream, size_t bufsize)
{
struct _bs *bs;
struct _stream_buffer *bs;
int status;
if (pstream == NULL || stream == NULL || bufsize == 0)
return MU_ERROR_INVALID_PARAMETER;
......@@ -437,16 +442,9 @@ stream_buffer_create (stream_t *pstream, stream_t stream, size_t bufsize)
if (bs == NULL)
return MU_ERROR_NO_MEMORY;
mu_refcount_create (&(bs->refcount));
if (bs->refcount == NULL)
{
free (bs);
return MU_ERROR_NO_MEMORY;
}
bs->stream = stream;
bs->rbuffer.bufsize = bufsize;
bs->base.vtable = &_bs_vtable;
status = _stream_buffer_ctor (bs, stream, bufsize);
if (status != 0)
return status;
*pstream = &bs->base;
return 0;
}
......
......@@ -28,19 +28,19 @@
#endif
#include <mailutils/error.h>
#include <mailutils/sys/attribute.h>
#include <mailutils/sys/dattribute.h>
static int
_da_ref (attribute_t attribute)
int
_attribute_default_ref (attribute_t attribute)
{
struct _da *da = (struct _da *)attribute;
struct _attribute_default *da = (struct _attribute_default *)attribute;
return mu_refcount_inc (da->refcount);
}
static void
_da_destroy (attribute_t *pattribute)
void
_attribute_default_destroy (attribute_t *pattribute)
{
struct _da *da = (struct _da *)*pattribute;
struct _attribute_default *da = (struct _attribute_default *)*pattribute;
if (mu_refcount_dec (da->refcount) == 0)
{
mu_refcount_destroy (&da->refcount);
......@@ -48,10 +48,10 @@ _da_destroy (attribute_t *pattribute)
}
}
static int
_da_get_flags (attribute_t attribute, int *pflags)
int
_attribute_default_get_flags (attribute_t attribute, int *pflags)
{
struct _da *da = (struct _da *)attribute;
struct _attribute_default *da = (struct _attribute_default *)attribute;
mu_refcount_lock (da->refcount);
if (pflags)
*pflags = da->flags;
......@@ -59,20 +59,20 @@ _da_get_flags (attribute_t attribute, int *pflags)
return 0;
}
static int
_da_set_flags (attribute_t attribute, int flags)
int
_attribute_default_set_flags (attribute_t attribute, int flags)
{
struct _da *da = (struct _da *)attribute;
struct _attribute_default *da = (struct _attribute_default *)attribute;
mu_refcount_lock (da->refcount);
da->flags |= (flags | MU_ATTRIBUTE_MODIFIED);
mu_refcount_unlock (da->refcount);
return 0;
}
static int
_da_unset_flags (attribute_t attribute, int flags)
int
_attribute_default_unset_flags (attribute_t attribute, int flags)
{
struct _da *da = (struct _da *)attribute;
struct _attribute_default *da = (struct _attribute_default *)attribute;
mu_refcount_lock (da->refcount);
da->flags &= ~flags;
/* If Modified was being unset do not reset it. */
......@@ -82,45 +82,115 @@ _da_unset_flags (attribute_t attribute, int flags)
return 0;
}
static int
_da_clear_flags (attribute_t attribute)
int
_attribute_default_clear_flags (attribute_t attribute)
{
struct _da *da = (struct _da *)attribute;
struct _attribute_default *da = (struct _attribute_default *)attribute;
mu_refcount_lock (da->refcount);
da->flags = 0;
mu_refcount_unlock (da->refcount);
return 0;
}
static struct _attribute_vtable _da_vtable =
static struct _attribute_vtable _attribute_default_vtable =
{
_da_ref,
_da_destroy,
_attribute_default_ref,
_attribute_default_destroy,
_da_get_flags,
_da_set_flags,
_da_unset_flags,
_da_clear_flags
_attribute_default_get_flags,
_attribute_default_set_flags,
_attribute_default_unset_flags,
_attribute_default_clear_flags
};
int
attribute_create (attribute_t *pattribute)
_attribute_default_ctor (struct _attribute_default *da)
{
mu_refcount_create (&(da->refcount));
if (da->refcount == NULL)
return MU_ERROR_NO_MEMORY;
da->flags = 0;
da->base.vtable = &_attribute_default_vtable;
return 0;
}
void
_attribute_default_dtor (struct _attribute_default *da)
{
mu_refcount_destroy (&da->refcount);
}
int
attribute_default_create (attribute_t *pattribute)
{
struct _da *da;
struct _attribute_default *da;
int status;
if (pattribute == NULL)
return MU_ERROR_INVALID_PARAMETER;
da = calloc (1, sizeof *da);
if (da == NULL)
return MU_ERROR_NO_MEMORY;
mu_refcount_create (&(da->refcount));
if (da->refcount == NULL)
status = _attribute_default_ctor (da);
if (status != 0)
{
free (da);
return status;
}
*pattribute = &da->base;
return 0;
}
int
attribute_status_create (attribute_t *pattribute, const char *field)
{
struct _attribute_default *da;
int status;
char *colon;
if (pattribute == NULL || field == NULL)
return MU_ERROR_INVALID_PARAMETER;
da = calloc (1, sizeof *da);
if (da == NULL)
return MU_ERROR_NO_MEMORY;
status = _attribute_default_ctor (da);
if (status != 0)
{
free (da);
return status;
}
da->flags = 0;
da->base.vtable = &_da_vtable;
*pattribute = &da->base;
colon = strchr (field, ':');
if (colon)
field = ++colon;
for (; *field; field++)
{
switch (*field)
{
case 'r':
case 'R':
attribute_set_read (*pattribute);
break;
case 'O':
case 'o':
attribute_set_seen (*pattribute);
break;
case 'a':
case 'A':
attribute_set_answered (*pattribute);
break;
case 'd':
case 'D':
attribute_set_deleted (*pattribute);
break;
}
}
attribute_unset_modified (*pattribute);
return 0;
}
......
......@@ -33,53 +33,35 @@
#include <signal.h>
#include <mailutils/error.h>
#include <mailutils/sys/locker.h>
#include <mailutils/sys/dotlock.h>
#include <mailutils/refcount.h>
/* locking flags */
#define MU_DOTLOCK_PID 1
#define MU_DOTLOCK_FCNTL 2
#define MU_DOTLOCK_TIME 4
#define MU_DOTLOCK_EXPIRE_TIME (5 * 60)
#define LOCKFILE_ATTR 0444
/* First draft by Brian Edmond. */
struct _dotlock
{
struct _locker base;
mu_refcount_t refcount;
int fd;
int refcnt;
char *fname;
int flags;
};
static int
_dotlock_ref (locker_t locker)
int
_lockfile_dotlock_ref (lockfile_t lockfile)
{
struct _dotlock *dotlock = (struct _dotlock *)locker;
struct _lockfile_dotlock *dotlock = (struct _lockfile_dotlock *)lockfile;
return mu_refcount_inc (dotlock->refcount);
}
static void
_dotlock_destroy (locker_t *plocker)
void
_lockfile_dotlock_destroy (lockfile_t *plockfile)
{
struct _dotlock *dotlock = (struct _dotlock *)*plocker;
struct _lockfile_dotlock *dotlock = (struct _lockfile_dotlock *)*plockfile;
if (mu_refcount_dec (dotlock->refcount) == 0)
{
mu_refcount_destroy (&dotlock->refcount);
if (dotlock->fname)
free (dotlock->fname);
free (dotlock);
}
}
static int
_dotlock_lock (locker_t locker)
int
_lockfile_dotlock_lock (lockfile_t lockfile)
{
struct _dotlock *dotlock = (struct _dotlock *)locker;
struct _lockfile_dotlock *dotlock = (struct _lockfile_dotlock *)lockfile;
int fd = -1;
char buf[16];
pid_t pid;
......@@ -104,31 +86,34 @@ _dotlock_lock (locker_t locker)
if (fd != -1)
{
/* Check to see if this process is still running. */
if (dotlock->flags & MU_DOTLOCK_PID)
if (dotlock->flags & MU_LOCKFILE_DOTLOCK_PID)
{
int nread = read (fd, buf, sizeof (buf) - 1);
if (nread > 0)
{
buf[nread] = '\0';
pid = strtol (buf, NULL, 10);
if (pid > 0)
switch (pid = strtol (buf, NULL, 10))
{
case LONG_MIN:
case LONG_MAX:
if (errno == ERANGE)
removed = 1;
break;
default:
/* Process is gone so we try to remove the lock. */
if (kill (pid, 0) == -1)
removed = 1;
}
else
removed = 1; /* Corrupted file, remove the lock. */
}
}
/* Check to see if the lock expired. */
if (dotlock->flags & MU_DOTLOCK_TIME)
if (dotlock->flags & MU_LOCKFILE_DOTLOCK_TIME)
{
struct stat stbuf;
fstat (fd, &stbuf);
/* The lock has expired. */
if ((time (NULL) - stbuf.st_mtime) > MU_DOTLOCK_EXPIRE_TIME)
if ((time (NULL) - stbuf.st_mtime) > MU_LOCKFILE_DOTLOCK_EXPIRE_TIME)
removed = 1;
}
......@@ -138,7 +123,7 @@ _dotlock_lock (locker_t locker)
}
/* Try to create the lockfile. */
fd = open (dotlock->fname, O_WRONLY | O_CREAT | O_EXCL, LOCKFILE_ATTR);
fd = open (dotlock->fname, O_WRONLY | O_CREAT | O_EXCL, MU_LOCKFILE_DOTLOCK_ATTR);
if (fd == -1)
return errno;
else
......@@ -165,7 +150,7 @@ _dotlock_lock (locker_t locker)
write (fd, buf, strlen (buf));
/* Try to get a file lock. */
if (dotlock->flags & MU_DOTLOCK_FCNTL)
if (dotlock->flags & MU_LOCKFILE_DOTLOCK_FCNTL)
{
struct flock fl;
......@@ -186,26 +171,26 @@ _dotlock_lock (locker_t locker)
return 0;
}
static int
_dotlock_touchlock (locker_t locker)
int
_lockfile_dotlock_touchlock (lockfile_t lockfile)
{
struct _dotlock *dotlock = (struct _dotlock *)locker;
struct _lockfile_dotlock *dotlock = (struct _lockfile_dotlock *)lockfile;
if (!dotlock || !dotlock->fname || dotlock->fd == -1)
return MU_ERROR_INVALID_PARAMETER;
return utime (dotlock->fname, NULL);
}
static int
_dotlock_unlock (locker_t locker)
int
_lockfile_dotlock_unlock (lockfile_t lockfile)
{
struct _dotlock *dotlock = (struct _dotlock *)locker;
struct _lockfile_dotlock *dotlock = (struct _lockfile_dotlock *)lockfile;
if (!dotlock || !dotlock->fname || dotlock->fd == -1 || dotlock->refcnt <= 0)
return EINVAL;
if (--dotlock->refcnt > 0)
return 0;
if (dotlock->flags & MU_DOTLOCK_FCNTL)
if (dotlock->flags & MU_LOCKFILE_DOTLOCK_FCNTL)
{
struct flock fl;
......@@ -221,48 +206,68 @@ _dotlock_unlock (locker_t locker)
return 0;
}
static struct _locker_vtable _dotlock_vtable =
static struct _lockfile_vtable _lockfile_dotlock_vtable =
{
_dotlock_ref,
_dotlock_destroy,
_lockfile_dotlock_ref,
_lockfile_dotlock_destroy,
_dotlock_lock,
_dotlock_touchlock,
_dotlock_unlock,
_lockfile_dotlock_lock,
_lockfile_dotlock_touchlock,
_lockfile_dotlock_unlock,
};
int
locker_dotlock_create (locker_t *plocker, const char *filename)
_lockfile_dotlock_ctor (struct _lockfile_dotlock *dotlock,
const char *filename)
{
struct _dotlock *dotlock;
if (plocker == NULL || filename == NULL)
return MU_ERROR_INVALID_PARAMETER;
dotlock = calloc (1, sizeof *dotlock);
if (dotlock == NULL)
return MU_ERROR_NO_MEMORY;
mu_refcount_create (&dotlock->refcount);
if (dotlock->refcount)
{
free (dotlock);
return MU_ERROR_NO_MEMORY;
}
dotlock->fname = calloc (strlen (filename) + 5 /*strlen(".lock")*/ + 1, 1);
if (dotlock->fname == NULL)
{
free (dotlock);
mu_refcount_destroy (&dotlock->refcount);
return MU_ERROR_NO_MEMORY;
}
strcpy (dotlock->fname, filename);
strcat (dotlock->fname, ".lock");
dotlock->flags = MU_DOTLOCK_PID | MU_DOTLOCK_TIME | MU_DOTLOCK_FCNTL;
dotlock->flags = MU_LOCKFILE_DOTLOCK_PID | MU_LOCKFILE_DOTLOCK_TIME
| MU_LOCKFILE_DOTLOCK_FCNTL;
dotlock->fd = -1;
dotlock->refcnt = 0;
dotlock->base.vtable = &_dotlock_vtable;
*plocker = &dotlock->base;
dotlock->base.vtable = &_lockfile_dotlock_vtable;
return 0;
}
void
_lockfile_dotlock_dtor (struct _lockfile_dotlock *dotlock)
{
mu_refcount_destroy (&dotlock->refcount);
if (dotlock->fname)
free (dotlock->fname);
}
int
lockfile_dotlock_create (lockfile_t *plockfile, const char *filename)
{
struct _lockfile_dotlock *dotlock;
int status;
if (plockfile == NULL || filename == NULL)
return MU_ERROR_INVALID_PARAMETER;
dotlock = calloc (1, sizeof *dotlock);
if (dotlock == NULL)
return MU_ERROR_NO_MEMORY;
status = _lockfile_dotlock_ctor (dotlock, filename);
if (status != 0)
{
free (dotlock);
return status;
}
*plockfile = &dotlock->base;
return 0;
}
......
......@@ -33,23 +33,23 @@
#include <mailutils/error.h>
static void
_fds_cleanup (void *arg)
_stream_fd_cleanup (void *arg)
{
struct _fds *fds = arg;
struct _stream_fd *fds = arg;
mu_refcount_unlock (fds->refcount);
}
static int
_fds_ref (stream_t stream)
int
_stream_fd_ref (stream_t stream)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
return mu_refcount_inc (fds->refcount);
}
static void
_fds_destroy (stream_t *pstream)
void
_stream_fd_destroy (stream_t *pstream)
{
struct _fds *fds = (struct _fds *)*pstream;
struct _stream_fd *fds = (struct _stream_fd *)*pstream;
if (mu_refcount_dec (fds->refcount) == 0)
{
mu_refcount_destroy (&fds->refcount);
......@@ -58,39 +58,40 @@ _fds_destroy (stream_t *pstream)
}
static int
_fds_close0 (stream_t stream)
_stream_fd_close0 (stream_t stream)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
fds->state = MU_STREAM_STATE_CLOSE;
if (fds->fd != -1)
close (fds->fd);
fds->fd = -1;
return 0;
}
static int
_fds_close (stream_t stream)
int
_stream_fd_close (stream_t stream)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
mu_refcount_lock (fds->refcount);
monitor_cleanup_push (_fds_cleanup, fds);
_fds_close0 (stream);
monitor_cleanup_push (_stream_fd_cleanup, fds);
_stream_fd_close0 (stream);
mu_refcount_unlock (fds->refcount);
monitor_cleanup_pop (0);
return 0;
}
static int
_fds_open (stream_t stream, const char *name, int port, int flags)
int
_stream_fd_open (stream_t stream, const char *name, int port, int flags)
{
(void)stream; (void)name; (void)port; (void)flags;
return MU_ERROR_NOT_SUPPORTED;
}
static int
_fds_get_fd (stream_t stream, int *fd)
int
_stream_fd_get_fd (stream_t stream, int *fd)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
if (fd == NULL || fds->fd == -1)
return MU_ERROR_INVALID_PARAMETER;
......@@ -99,13 +100,14 @@ _fds_get_fd (stream_t stream, int *fd)
return 0;
}
static int
_fds_read (stream_t stream, void *buf, size_t buf_size, size_t *br)
int
_stream_fd_read (stream_t stream, void *buf, size_t buf_size, size_t *br)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int bytes = 0;
int status = 0;
fds->state = MU_STREAM_STATE_READ;
bytes = read (fds->fd, buf, buf_size);
if (bytes == -1)
{
......@@ -117,15 +119,16 @@ _fds_read (stream_t stream, void *buf, size_t buf_size, size_t *br)
return status;
}
static int
_fds_readline (stream_t stream, char *buf, size_t buf_size, size_t *br)
int
_stream_fd_readline (stream_t stream, char *buf, size_t buf_size, size_t *br)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int status = 0;
size_t n;
int nr = 0;
char c;
fds->state = MU_STREAM_STATE_READ;
/* Grossly inefficient hopefully they override this */
for (n = 1; n < buf_size; n++)
{
......@@ -154,13 +157,14 @@ _fds_readline (stream_t stream, char *buf, size_t buf_size, size_t *br)
return status;
}
static int
_fds_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw)
int
_stream_fd_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int bytes = 0;
int status = 0;
fds->state = MU_STREAM_STATE_WRITE;
bytes = write (fds->fd, buf, buf_size);
if (bytes == -1)
{
......@@ -172,10 +176,10 @@ _fds_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw)
return status;
}
static int
_fds_seek (stream_t stream, off_t off, enum stream_whence whence)
int
_stream_fd_seek (stream_t stream, off_t off, enum stream_whence whence)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int err = 0;
if (fds->fd)
{
......@@ -193,10 +197,10 @@ _fds_seek (stream_t stream, off_t off, enum stream_whence whence)
return err;
}
static int
_fds_tell (stream_t stream, off_t *off)
int
_stream_fd_tell (stream_t stream, off_t *off)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int err = 0;
if (off)
{
......@@ -207,13 +211,13 @@ _fds_tell (stream_t stream, off_t *off)
*off = 0;
}
}
return err;;
return err;
}
static int
_fds_get_size (stream_t stream, off_t *psize)
int
_stream_fd_get_size (stream_t stream, off_t *psize)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
struct stat stbuf;
int err = 0;
stbuf.st_size = 0;
......@@ -224,47 +228,47 @@ _fds_get_size (stream_t stream, off_t *psize)
return err;
}
static int
_fds_truncate (stream_t stream, off_t len)
int
_stream_fd_truncate (stream_t stream, off_t len)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int err = 0;
if (ftruncate (fds->fd, len) == -1)
err = errno ;
err = errno;
return err;
}
static int
_fds_flush (stream_t stream)
int
_stream_fd_flush (stream_t stream)
{
(void)stream;
return 0;
}
static int
_fds_get_flags (stream_t stream, int *flags)
int
_stream_fd_get_flags (stream_t stream, int *flags)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
if (flags == NULL)
return MU_ERROR_INVALID_PARAMETER;
*flags = fds->flags;
return 0;
}
static int
_fds_get_state (stream_t stream, enum stream_state *state)
int
_stream_fd_get_state (stream_t stream, enum stream_state *state)
{
(void)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
if (state == NULL)
return MU_ERROR_INVALID_PARAMETER;
*state = MU_STREAM_NO_STATE;
*state = fds->state;
return 0;
}
static int
_fds_is_readready (stream_t stream, int timeout)
int
_stream_fd_is_readready (stream_t stream, int timeout)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int ready = 0;
if (fds->fd >= 0)
......@@ -285,13 +289,13 @@ _fds_is_readready (stream_t stream, int timeout)
return ready;
}
static int
_fds_is_writeready (stream_t stream, int timeout)
int
_stream_fd_is_writeready (stream_t stream, int timeout)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int ready = 0;
if (fds->fd)
if (fds->fd >= 0)
{
struct timeval tv;
fd_set fset;
......@@ -309,13 +313,13 @@ _fds_is_writeready (stream_t stream, int timeout)
return ready;
}
static int
_fds_is_exceptionpending (stream_t stream, int timeout)
int
_stream_fd_is_exceptionpending (stream_t stream, int timeout)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
int ready = 0;
if (fds->fd)
if (fds->fd >= 0)
{
struct timeval tv;
fd_set fset;
......@@ -333,47 +337,66 @@ _fds_is_exceptionpending (stream_t stream, int timeout)
return 0;
}
static int
_fds_is_open (stream_t stream)
int
_stream_fd_is_open (stream_t stream)
{
struct _fds *fds = (struct _fds *)stream;
struct _stream_fd *fds = (struct _stream_fd *)stream;
return fds->fd >= 0;
}
static struct _stream_vtable _fds_vtable =
static struct _stream_vtable _stream_fd_vtable =
{
_fds_ref,
_fds_destroy,
_stream_fd_ref,
_stream_fd_destroy,
_fds_open,
_fds_close,
_stream_fd_open,
_stream_fd_close,
_fds_read,
_fds_readline,
_fds_write,
_stream_fd_read,
_stream_fd_readline,
_stream_fd_write,
_fds_seek,
_fds_tell,
_stream_fd_seek,
_stream_fd_tell,
_fds_get_size,
_fds_truncate,
_fds_flush,
_stream_fd_get_size,
_stream_fd_truncate,
_stream_fd_flush,
_fds_get_fd,
_fds_get_flags,
_fds_get_state,
_stream_fd_get_fd,
_stream_fd_get_flags,
_stream_fd_get_state,
_fds_is_readready,
_fds_is_writeready,
_fds_is_exceptionpending,
_stream_fd_is_readready,
_stream_fd_is_writeready,
_stream_fd_is_exceptionpending,
_fds_is_open
_stream_fd_is_open
};
int
_stream_fd_ctor (struct _stream_fd *fds, int fd)
{
mu_refcount_create (&fds->refcount);
if (fds->refcount == NULL)
return MU_ERROR_NO_MEMORY;
fds->fd = fd;
fds->base.vtable = &_stream_fd_vtable;
return 0;
}
void
_stream_fd_dtor (struct _stream_fd *fds)
{
mu_refcount_destroy (&fds->refcount);
}
int
stream_fd_create (stream_t *pstream, int fd)
{
struct _fds *fds;
struct _stream_fd *fds;
int status;
if (pstream == NULL || fd < 0)
return MU_ERROR_INVALID_PARAMETER;
......@@ -382,14 +405,12 @@ stream_fd_create (stream_t *pstream, int fd)
if (fds == NULL)
return MU_ERROR_NO_MEMORY;
mu_refcount_create (&fds->refcount);
if (fds->refcount == NULL)
status = _stream_fd_ctor (fds, fd);
if (status != 0)
{
free (fds);
return MU_ERROR_NO_MEMORY;
return status;
}
fds->fd = fd;
fds->base.vtable = &_fds_vtable;
*pstream = &fds->base;
return 0;
}
......
......@@ -34,17 +34,17 @@
#include <mailutils/error.h>
static int
_fs_ref (stream_t stream)
int
_stream_stdio_ref (stream_t stream)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
return mu_refcount_inc (fs->refcount);
}
static void
_fs_destroy (stream_t *pstream)
void
_stream_stdio_destroy (stream_t *pstream)
{
struct _fs *fs = (struct _fs *)*pstream;
struct _stream_stdio *fs = (struct _stream_stdio *)*pstream;
if (mu_refcount_dec (fs->refcount) == 0)
{
mu_refcount_destroy (&fs->refcount);
......@@ -52,10 +52,10 @@ _fs_destroy (stream_t *pstream)
}
}
static int
_fs_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
int
_stream_stdio_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
size_t n = 0;
int err = 0;
......@@ -74,10 +74,10 @@ _fs_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
return err;
}
static int
_fs_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
int
_stream_stdio_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
size_t n = 0;
int err = 0;
......@@ -99,10 +99,10 @@ _fs_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
return err;
}
static int
_fs_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
int
_stream_stdio_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
size_t n = 0;
int err = 0;
......@@ -123,19 +123,19 @@ _fs_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
return err;
}
static int
_fs_truncate (stream_t stream, off_t len)
int
_stream_stdio_truncate (stream_t stream, off_t len)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
if (fs->file && ftruncate (fileno (fs->file), len) != 0)
return MU_ERROR_IO;
return 0;
}
static int
_fs_get_size (stream_t stream, off_t *psize)
int
_stream_stdio_get_size (stream_t stream, off_t *psize)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
struct stat stbuf;
stbuf.st_size = 0;
if (fs->file)
......@@ -149,19 +149,19 @@ _fs_get_size (stream_t stream, off_t *psize)
return 0;
}
static int
_fs_flush (stream_t stream)
int
_stream_stdio_flush (stream_t stream)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
if (fs->file)
return fflush (fs->file);
return 0;
}
static int
_fs_get_fd (stream_t stream, int *pfd)
int
_stream_stdio_get_fd (stream_t stream, int *pfd)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
int status = 0;
if (pfd)
{
......@@ -173,10 +173,10 @@ _fs_get_fd (stream_t stream, int *pfd)
return status;
}
static int
_fs_seek (stream_t stream, off_t off, enum stream_whence whence)
int
_stream_stdio_seek (stream_t stream, off_t off, enum stream_whence whence)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
int err = 0;
if (fs->file)
{
......@@ -194,28 +194,28 @@ _fs_seek (stream_t stream, off_t off, enum stream_whence whence)
return err;
}
static int
_fs_tell (stream_t stream, off_t *off)
int
_stream_stdio_tell (stream_t stream, off_t *off)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
if (off == NULL)
return MU_ERROR_INVALID_PARAMETER;
*off = (fs->file) ? ftell (fs->file) : 0;
return 0;
}
static int
_fs_get_flags (stream_t stream, int *flags)
int
_stream_stdio_get_flags (stream_t stream, int *flags)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
if (flags == NULL)
return MU_ERROR_INVALID_PARAMETER;
*flags = fs->flags;
return 0;
}
static int
_fs_get_state (stream_t stream, enum stream_state *state)
int
_stream_stdio_get_state (stream_t stream, enum stream_state *state)
{
(void)stream;
if (state == NULL)
......@@ -224,40 +224,39 @@ _fs_get_state (stream_t stream, enum stream_state *state)
return 0;
}
static int
_fs_is_open (stream_t stream)
int
_stream_stdio_is_open (stream_t stream)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
return (fs->file) ? 1 : 0;
}
static int
_fs_is_readready (stream_t stream, int timeout)
int
_stream_stdio_is_readready (stream_t stream, int timeout)
{
(void)timeout;
return _fs_is_open (stream);
return _stream_stdio_is_open (stream);
}
static int
_fs_is_writeready (stream_t stream, int timeout)
int
_stream_stdio_is_writeready (stream_t stream, int timeout)
{
(void)timeout;
return _fs_is_open (stream);
return _stream_stdio_is_open (stream);
}
static int
_fs_is_exceptionpending (stream_t stream, int timeout)
int
_stream_stdio_is_exceptionpending (stream_t stream, int timeout)
{
(void)stream;
(void)timeout;
return 0;
}
static int
_fs_close (stream_t stream)
int
_stream_stdio_close (stream_t stream)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
int err = 0;
if (fs->file)
{
......@@ -268,10 +267,10 @@ _fs_close (stream_t stream)
return err;
}
static int
_fs_open (stream_t stream, const char *filename, int port, int flags)
int
_stream_stdio_open (stream_t stream, const char *filename, int port, int flags)
{
struct _fs *fs = (struct _fs *)stream;
struct _stream_stdio *fs = (struct _stream_stdio *)stream;
int flg;
int fd;
const char *mode;
......@@ -371,40 +370,60 @@ _fs_open (stream_t stream, const char *filename, int port, int flags)
return 0;
}
static struct _stream_vtable _fs_vtable =
static struct _stream_vtable _stream_stdio_vtable =
{
_fs_ref,
_fs_destroy,
_stream_stdio_ref,
_stream_stdio_destroy,
_fs_open,
_fs_close,
_stream_stdio_open,
_stream_stdio_close,
_fs_read,
_fs_readline,
_fs_write,
_stream_stdio_read,
_stream_stdio_readline,
_stream_stdio_write,
_fs_seek,
_fs_tell,
_stream_stdio_seek,
_stream_stdio_tell,
_fs_get_size,
_fs_truncate,
_fs_flush,
_stream_stdio_get_size,
_stream_stdio_truncate,
_stream_stdio_flush,
_fs_get_fd,
_fs_get_flags,
_fs_get_state,
_stream_stdio_get_fd,
_stream_stdio_get_flags,
_stream_stdio_get_state,
_fs_is_readready,
_fs_is_writeready,
_fs_is_exceptionpending,
_stream_stdio_is_readready,
_stream_stdio_is_writeready,
_stream_stdio_is_exceptionpending,
_fs_is_open
_stream_stdio_is_open
};
int
_stream_stdio_ctor (struct _stream_stdio *fs, FILE *fp)
{
mu_refcount_create (&fs->refcount);
if (fs->refcount == NULL)
return MU_ERROR_NO_MEMORY ;
fs->file = fp;
fs->flags = 0;
fs->base.vtable = &_stream_stdio_vtable;
return 0;
}
void
_stream_stdio_dtor (struct _stream_stdio *fs)
{
mu_refcount_destroy (&fs->refcount);
/* We may leak if they did not close the FILE * */
fs->file = NULL;
}
int
stream_file_create (stream_t *pstream)
{
struct _fs *fs;
struct _stream_stdio *fs;
if (pstream == NULL)
return MU_ERROR_INVALID_PARAMETER;
......@@ -421,7 +440,7 @@ stream_file_create (stream_t *pstream)
}
fs->file = NULL;
fs->flags = 0;
fs->base.vtable = &_fs_vtable;
fs->base.vtable = &_stream_stdio_vtable;
*pstream = &fs->base;
return 0;
}
......@@ -429,7 +448,7 @@ stream_file_create (stream_t *pstream)
int
stream_stdio_create (stream_t *pstream, FILE *fp)
{
struct _fs *fs;
struct _stream_stdio *fs;
if (pstream == NULL)
return MU_ERROR_INVALID_PARAMETER;
......@@ -446,7 +465,7 @@ stream_stdio_create (stream_t *pstream, FILE *fp)
}
fs->file = fp;
fs->flags = 0;
fs->base.vtable = &_fs_vtable;
fs->base.vtable = &_stream_stdio_vtable;
*pstream = &fs->base;
return 0;
}
......
......@@ -15,7 +15,7 @@ pkginclude_HEADERS = \
header.h \
iterator.h \
list.h \
locker.h \
lockfile.h \
mailbox.h \
mbox.h \
md5-rsa.h \
......
......@@ -42,8 +42,6 @@ typedef struct _attribute * attribute_t;
#define MU_ATTRIBUTE_MODIFIED 0x1000
#define MU_ATTRIBUTE_RECENT 0x0000
extern int attribute_create __P ((attribute_t *));
extern int attribute_ref __P ((attribute_t));
extern void attribute_destroy __P ((attribute_t *));
......@@ -83,6 +81,8 @@ extern int attribute_clear_flags __P ((attribute_t));
extern int attribute_is_equal __P ((attribute_t, attribute_t));
extern int attribute_copy __P ((attribute_t dst, attribute_t src));
extern int attribute_default_create __P ((attribute_t *));
extern int attribute_status_create __P ((attribute_t *, const char *));
#ifdef __cplusplus
}
......
......@@ -15,8 +15,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MAILUTILS_LOCKER_H
#define _MAILUTILS_LOCKER_H
#ifndef _MAILUTILS_LOCKFILE_H
#define _MAILUTILS_LOCKFILE_H
#include <sys/types.h>
......@@ -32,21 +32,21 @@ extern "C" {
# endif
#endif /*__P */
struct _locker;
typedef struct _locker *locker_t;
struct _lockfile;
typedef struct _lockfile *lockfile_t;
extern int locker_ref __P ((locker_t));
extern void locker_destroy __P ((locker_t *));
extern int lockfile_ref __P ((lockfile_t));
extern void lockfile_destroy __P ((lockfile_t *));
extern int locker_lock __P ((locker_t));
extern int locker_touchlock __P ((locker_t));
extern int locker_unlock __P ((locker_t));
extern int lockfile_lock __P ((lockfile_t));
extern int lockfile_touchlock __P ((lockfile_t));
extern int lockfile_unlock __P ((lockfile_t));
extern int locker_dotlock_create __P ((locker_t *, const char *filename));
extern int locker_nfslock_create __P ((locker_t *, const char *filename));
extern int lockfile_dotlock_create __P ((lockfile_t *, const char *filename));
extern int lockfile_nfslock_create __P ((lockfile_t *, const char *filename));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_MAILBOX_H */
#endif /* _MAILUTILS_LOCKFILE_H */
......
......@@ -41,7 +41,7 @@ extern int mbox_create __P ((mbox_t *));
extern void mbox_destroy __P ((mbox_t *));
extern int mbox_get_uidvalidity __P ((mbox_t, unsigned long *));
extern int mbox_get_uidnext __P ((mbox_t, unsigned long));
extern int mbox_get_uidnext __P ((mbox_t, unsigned long *));
extern int mbox_open __P ((mbox_t, const char *, int));
extern int mbox_close __P ((mbox_t));
......@@ -57,7 +57,7 @@ extern int mbox_set_hstream __P ((mbox_t, unsigned int, stream_t));
extern int mbox_get_hsize __P ((mbox_t, unsigned int, unsigned int *));
extern int mbox_get_hlines __P ((mbox_t, unsigned int, unsigned int *));
extern int mbox_get_bstream __P ((mbox_t, unsigned int, stream_t int *));
extern int mbox_get_bstream __P ((mbox_t, unsigned int, stream_t *));
extern int mbox_set_bstream __P ((mbox_t, unsigned int, stream_t));
extern int mbox_get_bsize __P ((mbox_t, unsigned int, unsigned int *));
extern int mbox_get_blines __P ((mbox_t, unsigned int, unsigned int *));
......@@ -75,12 +75,18 @@ extern int mbox_set_newmsg_cb __P ((mbox_t, int (*) __P ((int, void *)), void
extern int mbox_newmsg_cb __P ((mbox_t, int));
extern int mbox_progress_cb __P ((mbox_t, int));
extern int mbox_scan __P ((mbox_t, unsigned int, unsigned int *));
extern int mbox_scan __P ((mbox_t, unsigned int, unsigned int *, int));
extern int mbox_messages_count __P ((mbox_t, unsigned int *));
extern int mbox_append __P ((mbox_t, const char *, stream_t));
extern int mbox_append_hb __P ((mbox_t, const char *, stream_t, stream_t));
extern int mbox_get_carrier __P ((mbox_t, stream_t *));
extern int mbox_set_carrier __P ((mbox_t, stream_t));
extern int mbox_set_hcache __P ((mbox_t, char **, unsigned int));
extern int mbox_hcache_get_value __P ((mbox_t, const char *, char *, size_t,
size_t *));
#ifdef __cplusplus
}
......
......@@ -81,8 +81,8 @@ extern int stream_is_open __P ((stream_t));
/* Misc. */
extern int stream_file_create __P ((stream_t *));
extern int stream_stdio_create __P ((stream_t *, FILE *));
extern int stream_mapfile_create __P ((stream_t *));
extern int stream_memory_create __P ((stream_t *));
extern int stream_mmap_create __P ((stream_t *));
extern int stream_memory_create __P ((stream_t *, size_t));
extern int stream_tcp_create __P ((stream_t *));
extern int stream_fd_create __P ((stream_t *, int));
extern int stream_buffer_create __P ((stream_t *, stream_t, size_t));
......
......@@ -5,6 +5,7 @@ pkginclude_HEADERS = \
attribute.h \
authority.h \
bstream.h \
dattribute.h \
debug.h \
envelope.h \
folder.h \
......@@ -12,15 +13,16 @@ pkginclude_HEADERS = \
header.h \
iterator.h \
list.h \
locker.h \
lockfile.h \
mailbox.h \
mbox.h \
mapstream.h \
memstream.h \
message.h \
mstream.h \
observable.h \
observer.h \
pop3.h \
pticket.h \
refcount.h \
sdebug.h \
stream.h \
......
......@@ -21,6 +21,10 @@
#include <mailutils/sys/stream.h>
#include <mailutils/refcount.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Read buffer */
struct _rbuffer
{
......@@ -30,7 +34,7 @@ struct _rbuffer
size_t bufsize;
};
struct _bs
struct _stream_buffer
{
struct _stream base;
mu_refcount_t refcount;
......@@ -38,4 +42,30 @@ struct _bs
struct _rbuffer rbuffer;
};
extern int _stream_buffer_ctor __P ((struct _stream_buffer *, stream_t, size_t));
extern void _stream_buffer_dtor __P ((struct _stream_buffer *));
extern int _stream_buffer_ref __P ((stream_t));
extern void _stream_buffer_destroy __P ((stream_t *));
extern int _stream_buffer_open __P ((stream_t, const char *, int, int));
extern int _stream_buffer_close __P ((stream_t));
extern int _stream_buffer_read __P ((stream_t, void *, size_t, size_t *));
extern int _stream_buffer_readline __P ((stream_t, char *, size_t, size_t *));
extern int _stream_buffer_write __P ((stream_t, const void *, size_t, size_t *));
extern int _stream_buffer_get_fd __P ((stream_t, int *));
extern int _stream_buffer_get_flags __P ((stream_t, int *));
extern int _stream_buffer_get_size __P ((stream_t, off_t *));
extern int _stream_buffer_truncate __P ((stream_t, off_t));
extern int _stream_buffer_flush __P ((stream_t));
extern int _stream_buffer_get_state __P ((stream_t, enum stream_state *));
extern int _stream_buffer_seek __P ((stream_t, off_t, enum stream_whence));
extern int _stream_buffer_tell __P ((stream_t, off_t *));
extern int _stream_buffer_is_readready __P ((stream_t, int ));
extern int _stream_buffer_is_writeready __P ((stream_t, int));
extern int _stream_buffer_is_exceptionpending __P ((stream_t, int));
extern int _stream_buffer_is_open __P ((stream_t));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_BSTREAM_H */
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
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_SYS_DATTRIBUTE_H
# define _MAILUTILS_SYS_DATTRIBUTE_H
#ifdef DMALLOC
# include <dmalloc.h>
#endif
#include <mailutils/sys/attribute.h>
#include <mailutils/refcount.h>
#ifdef __cplusplus
extern "C" {
#endif
/* A simple default attribute implementation. */
struct _attribute_default
{
struct _attribute base;
mu_refcount_t refcount;
int flags;
};
extern int _attribute_default_ctor __P ((struct _attribute_default *));
extern void _attribute_default_dtor __P ((struct _attribute_default *));
extern int _attribute_default_ref __P ((attribute_t));
extern void _attribute_default_destroy __P ((attribute_t *));
extern int _attribute_default_get_flags __P ((attribute_t, int *));
extern int _attribute_default_set_flags __P ((attribute_t, int));
extern int _attribute_default_unset_flags __P ((attribute_t, int));
extern int _attribute_default_clear_flags __P ((attribute_t));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_ATTRIBUTE_H */
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
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_SYS_DOTLOCK_H
#define _MAILUTILS_SYS_DOTLOCK_H
#ifdef DMALLOC
#include <dmalloc.h>
#endif
#include <mailutils/refcount.h>
#include <mailutils/sys/lockfile.h>
#ifdef __cplusplus
extern "C" {
#endif
/* locking flags */
#define MU_LOCKFILE_DOTLOCK_PID 1
#define MU_LOCKFILE_DOTLOCK_FCNTL 2
#define MU_LOCKFILE_DOTLOCK_TIME 4
#define MU_LOCKFILE_DOTLOCK_EXPIRE_TIME (5 * 60)
#define MU_LOCKFILE_DOTLOCK_ATTR 0444
struct _lockfile_dotlock
{
struct _lockfile base;
mu_refcount_t refcount;
int fd;
int refcnt; /* For recursive file locking. */
char *fname;
int flags;
};
extern int _lockfile_dotlock_ctor __P ((struct _lockfile_dotlock *, const char *));
extern void _lockfile_dotlock_dtor __P ((struct _lockfile_dotlock *));
extern int _lockfile_dotlock_ref __P ((lockfile_t));
extern void _lockfile_dotlock_destroy __P ((lockfile_t *));
extern int _lockfile_dotlock_lock __P ((lockfile_t));
extern int _lockfile_dotlock_touchlock __P ((lockfile_t));
extern int _lockfile_dotlock_unlock __P ((lockfile_t));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_DOTLOCK_H */
......@@ -21,7 +21,11 @@
#include <mailutils/refcount.h>
#include <mailutils/sys/stream.h>
struct _fds
#ifdef __cplusplus
extern "C" {
#endif
struct _stream_fd
{
struct _stream base;
mu_refcount_t refcount;
......@@ -30,4 +34,31 @@ struct _fds
int flags;
};
int _stream_fd_ctor __P ((struct _stream_fd *, int));
void _stream_fd_dtor __P ((struct _stream_fd *));
int _stream_fd_ref __P ((stream_t));
void _stream_fd_destroy __P ((stream_t *));
int _stream_fd_open __P ((stream_t, const char *, int, int));
int _stream_fd_close __P ((stream_t));
int _stream_fd_read __P ((stream_t, void *, size_t, size_t *));
int _stream_fd_readline __P ((stream_t, char *, size_t, size_t *));
int _stream_fd_write __P ((stream_t, const void *, size_t, size_t *));
int _stream_fd_get_fd __P ((stream_t, int *));
int _stream_fd_get_flags __P ((stream_t, int *));
int _stream_fd_get_size __P ((stream_t, off_t *));
int _stream_fd_truncate __P ((stream_t, off_t));
int _stream_fd_flush __P ((stream_t));
int _stream_fd_get_state __P ((stream_t, enum stream_state *));
int _stream_fd_seek __P ((stream_t, off_t, enum stream_whence));
int _stream_fd_tell __P ((stream_t, off_t *));
int _stream_fd_is_readready __P ((stream_t, int ));
int _stream_fd_is_writeready __P ((stream_t, int));
int _stream_fd_is_exceptionpending __P ((stream_t, int));
int _stream_fd_is_open __P ((stream_t));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_FDSTREAM_H */
......
......@@ -21,7 +21,11 @@
#include <mailutils/sys/stream.h>
#include <mailutils/refcount.h>
struct _fs
#ifdef __cplusplus
extern "C" {
#endif
struct _stream_stdio
{
struct _stream base;
mu_refcount_t refcount;
......@@ -29,4 +33,30 @@ struct _fs
FILE *file;
};
extern int _stream_stdio_ctor __P ((struct _stream_stdio *, FILE *));
extern void _stream_stdio_dtor __P ((struct _stream_stdio *));
extern int _stream_stdio_ref __P ((stream_t));
extern void _stream_stdio_destroy __P ((stream_t *));
extern int _stream_stdio_open __P ((stream_t, const char *, int, int));
extern int _stream_stdio_close __P ((stream_t));
extern int _stream_stdio_read __P ((stream_t, void *, size_t, size_t *));
extern int _stream_stdio_readline __P ((stream_t, char *, size_t, size_t *));
extern int _stream_stdio_write __P ((stream_t, const void *, size_t, size_t *));
extern int _stream_stdio_get_fd __P ((stream_t, int *));
extern int _stream_stdio_get_flags __P ((stream_t, int *));
extern int _stream_stdio_get_size __P ((stream_t, off_t *));
extern int _stream_stdio_truncate __P ((stream_t, off_t));
extern int _stream_stdio_flush __P ((stream_t));
extern int _stream_stdio_get_state __P ((stream_t, enum stream_state *));
extern int _stream_stdio_seek __P ((stream_t, off_t, enum stream_whence));
extern int _stream_stdio_tell __P ((stream_t, off_t *));
extern int _stream_stdio_is_readready __P ((stream_t, int ));
extern int _stream_stdio_is_writeready __P ((stream_t, int));
extern int _stream_stdio_is_exceptionpending __P ((stream_t, int));
extern int _stream_stdio_is_open __P ((stream_t));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_FSTREAM_H */
......
......@@ -15,14 +15,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MAILUTILS_SYS_LOCKER_H
#define _MAILUTILS_SYS_LOCKER_H
#ifndef _MAILUTILS_SYS_LOCKFILE_H
#define _MAILUTILS_SYS_LOCKFILE_H
#ifdef DMALLOC
#include <dmalloc.h>
#endif
#include <mailutils/locker.h>
#include <mailutils/lockfile.h>
#ifdef __cplusplus
extern "C" {
......@@ -36,23 +36,23 @@ extern "C" {
# endif
#endif /*__P */
struct _locker_vtable
struct _lockfile_vtable
{
int (*ref) __P ((locker_t));
void (*destroy) __P ((locker_t *));
int (*ref) __P ((lockfile_t));
void (*destroy) __P ((lockfile_t *));
int (*lock) __P ((locker_t));
int (*touchlock) __P ((locker_t));
int (*unlock) __P ((locker_t));
int (*lock) __P ((lockfile_t));
int (*touchlock) __P ((lockfile_t));
int (*unlock) __P ((lockfile_t));
};
struct _locker
struct _lockfile
{
struct _locker_vtable *vtable;
struct _lockfile_vtable *vtable;
};
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_ENVELOPE_H */
#endif /* _MAILUTILS_SYS_LOCKFILE_H */
......
......@@ -18,10 +18,18 @@
#ifndef MAILUTILS_SYS_MSTREAM_H
#define MAILUTILS_SYS_MSTREAM_H
#include <unistd.h>
#include <mailutils/sys/stream.h>
#include <mailutils/refcount.h>
struct _ms
#ifdef _POSIX_MAPPED_FILES
#ifdef __cplusplus
extern "C" {
#endif
struct _stream_mmap
{
struct _stream base;
mu_refcount_t refcount;
......@@ -33,4 +41,31 @@ struct _ms
off_t offset;
};
extern int _stream_mmap_ctor __P ((struct _stream_mmap *));
extern void _stream_mmap_dtor __P ((struct _stream_mmap *));
extern int _stream_mmap_ref __P ((stream_t));
extern void _stream_mmap_destroy __P ((stream_t *));
extern int _stream_mmap_open __P ((stream_t, const char *, int, int));
extern int _stream_mmap_close __P ((stream_t));
extern int _stream_mmap_read __P ((stream_t, void *, size_t, size_t *));
extern int _stream_mmap_readline __P ((stream_t, char *, size_t, size_t *));
extern int _stream_mmap_write __P ((stream_t, const void *, size_t, size_t *));
extern int _stream_mmap_get_fd __P ((stream_t, int *));
extern int _stream_mmap_get_flags __P ((stream_t, int *));
extern int _stream_mmap_get_size __P ((stream_t, off_t *));
extern int _stream_mmap_truncate __P ((stream_t, off_t));
extern int _stream_mmap_flush __P ((stream_t));
extern int _stream_mmap_get_state __P ((stream_t, enum stream_state *));
extern int _stream_mmap_seek __P ((stream_t, off_t, enum stream_whence));
extern int _stream_mmap_tell __P ((stream_t, off_t *));
extern int _stream_mmap_is_readready __P ((stream_t, int ));
extern int _stream_mmap_is_writeready __P ((stream_t, int));
extern int _stream_mmap_is_exceptionpending __P ((stream_t, int));
extern int _stream_mmap_is_open __P ((stream_t));
#endif
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_MSTREAM_H */
......
......@@ -19,7 +19,7 @@
#define _MAILUTILS_SYS_MBOX_H
#include <time.h>
#include <mailutils/locker.h>
#include <mailutils/lockfile.h>
#include <mailutils/mbox.h>
#ifdef __cplusplus
......@@ -28,35 +28,6 @@ extern "C" {
typedef struct _mbox_message* mbox_message_t;
/* Keep the file positions of where the headers and bodies start and end.
attribute is the "Status:" message. */
struct _mbox_message
{
/* Offset of the messages in the mailbox. */
off_t from_;
/* Fast header retrieve, we save here the most common headers. This will
speed the header search. The entire headers are copied, when modified,
by the header_t object, we do not have to worry about updating them. */
char **fhdr;
struct
{
stream_t stream;
unsigned int lines;
unsigned int size;
off_t start;
off_t end;
} header, body;
/* UID i.e. see IMAP */
unsigned long uid;
attribute_t attribute; /* The attr_flags contains the "Status:" attribute */
mbox_t mbox; /* Back pointer. */
};
/* The umessages is an array of pointers that contains umessages_count of
mbox_message_t*; umessages[umessages_count]. We do it this way because
realloc() can move everything to a new memory region and invalidate all
......@@ -85,8 +56,7 @@ struct _mbox
MBOX_STATE_APPEND_BODY
} state ;
locker_t locker;
lockfile_t lockfile;
struct
{
int (*cb) __P ((int, void *));
......@@ -94,6 +64,35 @@ struct _mbox
} newmsg, progress, corrupt;
};
/* Keep the file positions of where the headers and bodies start and end.
attribute is the "Status:" message. */
struct _mbox_message
{
/* Offset of the messages in the mailbox. */
off_t from_;
/* Fast header retrieve, we save here the most common headers. This will
speed the header search. The entire headers are copied, when modified,
by the header_t object, we do not have to worry about updating them. */
char **fhdr;
struct
{
stream_t stream;
unsigned int lines;
unsigned int size;
off_t start;
off_t end;
} header, body;
/* UID i.e. see IMAP */
unsigned long uid;
unsigned int attr_flags;
attribute_t attribute; /* The attr_flags contains the "Status:" attribute */
mbox_t mbox; /* Back pointer. */
};
#ifdef __cplusplus
}
#endif
......
......@@ -23,14 +23,49 @@
#include <mailutils/refcount.h>
#include <mailutils/sys/stream.h>
struct _memory_stream
#ifdef __cplusplus
extern "C" {
#endif
#ifndef MU_STREAM_MEMORY_BLOCKSIZE
#define MU_STREAM_MEMORY_BLOCKSIZE 512
#endif
struct _stream_memory
{
struct _stream base;
mu_refcount_t refcount;
char *ptr;
size_t capacity;
size_t size;
off_t offset;
int flags;
};
extern int _stream_memory_ctor __P ((struct _stream_memory *, size_t));
extern void _stream_memory_dtor __P ((struct _stream_memory *));
extern int _stream_memory_ref __P ((stream_t));
extern void _stream_memory_destroy __P ((stream_t *));
extern int _stream_memory_open __P ((stream_t, const char *, int, int));
extern int _stream_memory_close __P ((stream_t));
extern int _stream_memory_read __P ((stream_t, void *, size_t, size_t *));
extern int _stream_memory_readline __P ((stream_t, char *, size_t, size_t *));
extern int _stream_memory_write __P ((stream_t, const void *, size_t, size_t *));
extern int _stream_memory_get_fd __P ((stream_t, int *));
extern int _stream_memory_get_flags __P ((stream_t, int *));
extern int _stream_memory_get_size __P ((stream_t, off_t *));
extern int _stream_memory_truncate __P ((stream_t, off_t));
extern int _stream_memory_flush __P ((stream_t));
extern int _stream_memory_get_state __P ((stream_t, enum stream_state *));
extern int _stream_memory_seek __P ((stream_t, off_t, enum stream_whence));
extern int _stream_memory_tell __P ((stream_t, off_t *));
extern int _stream_memory_is_readready __P ((stream_t, int ));
extern int _stream_memory_is_writeready __P ((stream_t, int));
extern int _stream_memory_is_exceptionpending __P ((stream_t, int));
extern int _stream_memory_is_open __P ((stream_t));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_MEMSTREAM_H */
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Library Public License as published by
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_SYS_PTICKET_H
#define _MAILUTILS_SYS_PTICKET_H
#include <mailutils/sys/ticket.h>
#ifdef __cplusplus
extern "C" {
#endif
struct _ticket_prompt
{
struct _ticket base;
mu_refcount_t refcount;
};
extern int _ticket_prompt_ctor __P ((struct _ticket_prompt *));
extern void _ticket_prompt_dtor __P ((struct _ticket_prompt *));
extern int _ticket_prompt_ref __P ((ticket_t));
extern void _ticket_prompt_destroy __P ((ticket_t *));
extern int _ticket_prompt_pop __P ((ticket_t, const char *, char **));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_PTICKET_H */
......@@ -29,15 +29,7 @@
extern "C" {
#endif
#ifndef __P
# ifdef __STDC__
# define __P(args) args
# else
# define __P(args) ()
# endif
#endif /*__P */
struct _sdebug
struct _mu_debug_stream
{
struct _mu_debug base;
mu_refcount_t refcount;
......@@ -46,6 +38,14 @@ struct _sdebug
int close_on_destroy;
};
int _mu_debug_stream_ctor __P ((struct _mu_debug_stream *));
int _mu_debug_stream_dtor __P ((struct _mu_debug_stream *));
int _mu_debug_stream_ref __P ((mu_debug_t));
void _mu_debug_stream_destroy __P ((mu_debug_t *));
int _mu_debug_stream_set_level __P ((mu_debug_t, size_t));
int _mu_debug_stream_get_level __P ((mu_debug_t, size_t *));
int _mu_debug_stream_print __P ((mu_debug_t, size_t, const char *));
#ifdef __cplusplus
}
#endif
......
......@@ -19,9 +19,13 @@
#define MAILUTILS_SYS_TCP_H
#include <mailutils/refcount.h>
#include <mailutils/sys/stream.h>
#include <mailutils/sys/fdstream.h>
enum _tcp_state
#ifdef __cplusplus
extern "C" {
#endif
enum _stream_tcp_state
{
TCP_STATE_INIT,
TCP_STATE_RESOLVE,
......@@ -30,16 +34,21 @@ enum _tcp_state
TCP_STATE_CONNECTED
};
struct _tcp_instance
struct _stream_tcp
{
struct _stream base;
mu_refcount_t refcount;
int fd;
struct _stream_fd base;
char *host;
int port;
int state;
int flags;
unsigned long address;
};
void _stream_tcp_destroy __P ((stream_t *));
int _stream_tcp_close __P ((stream_t));
int _stream_tcp_open __P ((stream_t, const char *, int, int));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_SYS_TCP_H */
......
......@@ -21,52 +21,52 @@
#include <stdlib.h>
#include <mailutils/error.h>
#include <mailutils/sys/locker.h>
#include <mailutils/sys/lockfile.h>
int
locker_ref (locker_t locker)
lockfile_ref (lockfile_t lockfile)
{
if (locker == NULL || locker->vtable == NULL
|| locker->vtable->ref == NULL)
if (lockfile == NULL || lockfile->vtable == NULL
|| lockfile->vtable->ref == NULL)
return MU_ERROR_NOT_SUPPORTED;
return locker->vtable->ref (locker);
return lockfile->vtable->ref (lockfile);
}
void
locker_destroy (locker_t *plocker)
lockfile_destroy (lockfile_t *plockfile)
{
if (plocker && *plocker)
if (plockfile && *plockfile)
{
locker_t locker = *plocker;
if (locker->vtable && locker->vtable->destroy)
locker->vtable->destroy (plocker);
*plocker = NULL;
lockfile_t lockfile = *plockfile;
if (lockfile->vtable && lockfile->vtable->destroy)
lockfile->vtable->destroy (plockfile);
*plockfile = NULL;
}
}
int
locker_lock (locker_t locker)
lockfile_lock (lockfile_t lockfile)
{
if (locker == NULL || locker->vtable == NULL
|| locker->vtable->lock == NULL)
if (lockfile == NULL || lockfile->vtable == NULL
|| lockfile->vtable->lock == NULL)
return MU_ERROR_NOT_SUPPORTED;
return locker->vtable->lock (locker);
return lockfile->vtable->lock (lockfile);
}
int
locker_touchlock (locker_t locker)
lockfile_touchlock (lockfile_t lockfile)
{
if (locker == NULL || locker->vtable == NULL
|| locker->vtable->lock == NULL)
if (lockfile == NULL || lockfile->vtable == NULL
|| lockfile->vtable->lock == NULL)
return MU_ERROR_NOT_SUPPORTED;
return locker->vtable->lock (locker);
return lockfile->vtable->lock (lockfile);
}
int
locker_unlock (locker_t locker)
lockfile_unlock (lockfile_t lockfile)
{
if (locker == NULL || locker->vtable == NULL
|| locker->vtable->lock == NULL)
if (lockfile == NULL || lockfile->vtable == NULL
|| lockfile->vtable->lock == NULL)
return MU_ERROR_NOT_SUPPORTED;
return locker->vtable->lock (locker);
return lockfile->vtable->lock (lockfile);
}
......
......@@ -29,7 +29,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <mailutils/sys/mstream.h>
#include <mailutils/sys/mapstream.h>
#include <mailutils/error.h>
#ifdef _POSIX_MAPPED_FILES
......@@ -39,17 +39,17 @@
# define MAP_FAILED (void*)-1
#endif
static int
_map_ref (stream_t stream)
int
_stream_mmap_ref (stream_t stream)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
return mu_refcount_inc (ms->refcount);
}
static void
_map_destroy (stream_t *pstream)
void
_stream_mmap_destroy (stream_t *pstream)
{
struct _ms *ms = (struct _ms *)*pstream;
struct _stream_mmap *ms = (struct _stream_mmap *)*pstream;
if (mu_refcount_dec (ms->refcount) == 0)
{
......@@ -58,10 +58,10 @@ _map_destroy (stream_t *pstream)
}
}
static int
_map_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
int
_stream_mmap_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
size_t n = 0;
mu_refcount_lock (ms->refcount);
......@@ -82,10 +82,10 @@ _map_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
return 0;
}
static int
_map_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
int
_stream_mmap_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
size_t n = 0;
mu_refcount_lock (ms->refcount);
......@@ -111,10 +111,10 @@ _map_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
return 0;
}
static int
_map_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
int
_stream_mmap_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
int err = 0;
size_t n = 0;
......@@ -157,10 +157,10 @@ _map_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
return err;
}
static int
_map_truncate (stream_t stream, off_t len)
int
_stream_mmap_truncate (stream_t stream, off_t len)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
int err = 0;
mu_refcount_lock (ms->refcount);
......@@ -188,10 +188,10 @@ _map_truncate (stream_t stream, off_t len)
return err;
}
static int
_map_get_size (stream_t stream, off_t *psize)
int
_stream_mmap_get_size (stream_t stream, off_t *psize)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
struct stat stbuf;
int err = 0;
......@@ -232,11 +232,11 @@ _map_get_size (stream_t stream, off_t *psize)
return err;
}
static int
_map_flush (stream_t stream)
int
_stream_mmap_flush (stream_t stream)
{
int err = 0;
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
mu_refcount_lock (ms->refcount);
if (ms->ptr != MAP_FAILED && ms->ptr != NULL)
err = msync (ms->ptr, ms->size, MS_SYNC);
......@@ -244,27 +244,27 @@ _map_flush (stream_t stream)
return 0;
}
static int
_map_get_fd (stream_t stream, int *pfd)
int
_stream_mmap_get_fd (stream_t stream, int *pfd)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
if (pfd)
*pfd = ms->fd;
return 0;
}
static int
_map_get_flags (stream_t stream, int *flags)
int
_stream_mmap_get_flags (stream_t stream, int *flags)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
if (flags == NULL)
return MU_ERROR_INVALID_PARAMETER;
*flags = ms->flags;
return 0;
}
static int
_map_get_state (stream_t stream, enum stream_state *state)
int
_stream_mmap_get_state (stream_t stream, enum stream_state *state)
{
(void)stream;
if (state == NULL)
......@@ -273,10 +273,10 @@ _map_get_state (stream_t stream, enum stream_state *state)
return 0;
}
static int
_map_seek (stream_t stream, off_t off, enum stream_whence whence)
int
_stream_mmap_seek (stream_t stream, off_t off, enum stream_whence whence)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
off_t noff = ms->offset;
int err = 0;
if (whence == MU_STREAM_WHENCE_SET)
......@@ -290,7 +290,7 @@ _map_seek (stream_t stream, off_t off, enum stream_whence whence)
if (noff >= 0)
{
if (noff > ms->offset)
_map_truncate (stream, noff);
_stream_mmap_truncate (stream, noff);
ms->offset = noff;
}
else
......@@ -298,20 +298,20 @@ _map_seek (stream_t stream, off_t off, enum stream_whence whence)
return err;
}
static int
_map_tell (stream_t stream, off_t *off)
int
_stream_mmap_tell (stream_t stream, off_t *off)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
if (off == NULL)
return MU_ERROR_INVALID_PARAMETER;
*off = ms->offset;
return 0;
}
static int
_map_close (stream_t stream)
int
_stream_mmap_close (stream_t stream)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
int err = 0;
mu_refcount_lock (ms->refcount);
if (ms->ptr != MAP_FAILED)
......@@ -328,40 +328,39 @@ _map_close (stream_t stream)
return err;
}
static int
_map_is_open (stream_t stream)
int
_stream_mmap_is_open (stream_t stream)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
return (ms->ptr == MAP_FAILED) ? 0 : 1;
}
static int
_map_is_readready (stream_t stream, int timeout)
int
_stream_mmap_is_readready (stream_t stream, int timeout)
{
(void)timeout;
return _map_is_open (stream);
return _stream_mmap_is_open (stream);
}
static int
_map_is_writeready (stream_t stream, int timeout)
int
_stream_mmap_is_writeready (stream_t stream, int timeout)
{
(void)timeout;
return _map_is_open (stream);
return _stream_mmap_is_open (stream);
}
static int
_map_is_exceptionpending (stream_t stream, int timeout)
int
_stream_mmap_is_exceptionpending (stream_t stream, int timeout)
{
(void)stream;
(void)timeout;
return 0;
}
static int
_map_open (stream_t stream, const char *filename, int port, int flags)
int
_stream_mmap_open (stream_t stream, const char *filename, int port, int flags)
{
struct _ms *ms = (struct _ms *)stream;
struct _stream_mmap *ms = (struct _stream_mmap *)stream;
int mflag, flg;
struct stat st;
......@@ -400,7 +399,19 @@ _map_open (stream_t stream, const char *filename, int port, int flags)
flg = O_RDONLY;
}
/* Anonymous Mapping. */
if (filename == NULL)
{
#ifdef MAP_ANON
mflag |= MAP_ANON;
#else
filename = "/dev/zero";
ms->fd = open (filename, flg);
#endif
}
else
ms->fd = open (filename, flg);
if (ms->fd < 0)
return errno;
if (fstat (ms->fd, &st) != 0)
......@@ -428,45 +439,70 @@ _map_open (stream_t stream, const char *filename, int port, int flags)
return 0;
}
static struct _stream_vtable _map_vtable =
static struct _stream_vtable _stream_mmap_vtable =
{
_map_ref,
_map_destroy,
_stream_mmap_ref,
_stream_mmap_destroy,
_map_open,
_map_close,
_stream_mmap_open,
_stream_mmap_close,
_map_read,
_map_readline,
_map_write,
_stream_mmap_read,
_stream_mmap_readline,
_stream_mmap_write,
_map_seek,
_map_tell,
_stream_mmap_seek,
_stream_mmap_tell,
_map_get_size,
_map_truncate,
_map_flush,
_stream_mmap_get_size,
_stream_mmap_truncate,
_stream_mmap_flush,
_map_get_fd,
_map_get_flags,
_map_get_state,
_stream_mmap_get_fd,
_stream_mmap_get_flags,
_stream_mmap_get_state,
_map_is_readready,
_map_is_writeready,
_map_is_exceptionpending,
_stream_mmap_is_readready,
_stream_mmap_is_writeready,
_stream_mmap_is_exceptionpending,
_map_is_open
_stream_mmap_is_open
};
int
_stream_mmap_ctor (struct _stream_mmap *ms)
{
mu_refcount_create (&ms->refcount);
if (ms->refcount == NULL)
return MU_ERROR_NO_MEMORY;
ms->fd = -1;
ms->offset = -1;
ms->flags = 0;
ms->mflags = 0;
ms->base.vtable = &_stream_mmap_vtable;
return 0;
}
void
_stream_mmap_dtor (struct _stream_mmap *ms)
{
mu_refcount_destroy (&ms->refcount);
ms->fd = -1;
ms->offset = -1;
ms->mflags = 0;
ms->ptr = MAP_FAILED;
}
#endif /* _POSIX_MAPPED_FILES */
int
stream_mapfile_create (stream_t *pstream)
stream_mmap_create (stream_t *pstream)
{
#ifndef _POSIX_MAPPED_FILES
return ENOSYS;
#else
struct _ms *ms;
struct _stream_mmap *ms;
int status;
if (pstream == NULL)
return MU_ERROR_INVALID_PARAMETER;
......@@ -475,19 +511,10 @@ stream_mapfile_create (stream_t *pstream)
if (ms == NULL)
return MU_ERROR_NO_MEMORY;
mu_refcount_create (&ms->refcount);
if (ms->refcount == NULL)
{
free (ms);
return MU_ERROR_NO_MEMORY;
}
ms->fd = -1;
ms->offset = -1;
ms->flags = 0;
ms->mflags = 0;
ms->base.vtable = &_map_vtable;
status = _stream_mmap_ctor (ms);
if (status != 0)
return status;
*pstream = &ms->base;
return 0;
#endif /* _POSIX_MAPPED_FILES */
}
......
......@@ -21,22 +21,25 @@
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <mailutils/error.h>
#include <mailutils/sys/memstream.h>
static int
_memory_ref (stream_t stream)
int
_stream_memory_ref (stream_t stream)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
return mu_refcount_inc (mem->refcount);
}
static void
_memory_destroy (stream_t *pstream)
void
_stream_memory_destroy (stream_t *pstream)
{
struct _memory_stream *mem = (struct _memory_stream *)*pstream;
struct _stream_memory *mem = (struct _stream_memory *)*pstream;
if (mu_refcount_dec (mem->refcount) == 0)
{
mu_refcount_destroy (&mem->refcount);
......@@ -44,10 +47,10 @@ _memory_destroy (stream_t *pstream)
}
}
static int
_memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
int
_stream_memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
size_t n = 0;
mu_refcount_lock (mem->refcount);
......@@ -64,10 +67,10 @@ _memory_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
return 0;
}
static int
_memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
int
_stream_memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
char *nl;
size_t n = 0;
mu_refcount_lock (mem->refcount);
......@@ -88,20 +91,25 @@ _memory_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
return 0;
}
static int
_memory_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
int
_stream_memory_write (stream_t stream, const void *iptr, size_t isize,
size_t *nbytes)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
mu_refcount_lock (mem->refcount);
/* Bigger we have to realloc. */
if (mem->size < (mem->offset + isize))
if (mem->capacity < (mem->offset + isize))
{
char *tmp = realloc (mem->ptr, mem->offset + isize);
/* Realloc by blocks of 512. */
int newsize = MU_STREAM_MEMORY_BLOCKSIZE *
(((mem->offset + isize)/MU_STREAM_MEMORY_BLOCKSIZE) + 1);
char *tmp = realloc (mem->ptr, newsize);
if (tmp == NULL)
return ENOMEM;
mem->ptr = tmp;
mem->size = mem->offset + isize;
mem->capacity = newsize;
}
memcpy (mem->ptr + mem->offset, iptr, isize);
......@@ -112,10 +120,10 @@ _memory_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
return 0;
}
static int
_memory_truncate (stream_t stream, off_t len)
int
_stream_memory_truncate (stream_t stream, off_t len)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
mu_refcount_lock (mem->refcount);
if (len == 0)
......@@ -130,16 +138,17 @@ _memory_truncate (stream_t stream, off_t len)
return ENOMEM;
mem->ptr = tmp;
}
mem->capacity = len;
mem->size = len;
mem->offset = len;
mu_refcount_unlock (mem->refcount);
return 0;
}
static int
_memory_get_size (stream_t stream, off_t *psize)
int
_stream_memory_get_size (stream_t stream, off_t *psize)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
mu_refcount_lock (mem->refcount);
if (psize)
*psize = mem->size;
......@@ -147,46 +156,47 @@ _memory_get_size (stream_t stream, off_t *psize)
return 0;
}
static int
_memory_close (stream_t stream)
int
_stream_memory_close (stream_t stream)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
mu_refcount_lock (mem->refcount);
if (mem->ptr)
free (mem->ptr);
mem->ptr = NULL;
mem->capacity = 0;
mem->size = 0;
mem->offset = 0;
mu_refcount_unlock (mem->refcount);
return 0;
}
static int
_memory_flush (stream_t stream)
int
_stream_memory_flush (stream_t stream)
{
(void)stream;
return 0;
}
static int
_memory_get_fd (stream_t stream, int *pfd)
int
_stream_memory_get_fd (stream_t stream, int *pfd)
{
(void)stream; (void)pfd;
return MU_ERROR_NOT_SUPPORTED;
}
static int
_memory_get_flags (stream_t stream, int *flags)
int
_stream_memory_get_flags (stream_t stream, int *flags)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
if (flags == NULL)
return MU_ERROR_INVALID_PARAMETER;
*flags = mem->flags;
return 0;
}
static int
_memory_get_state (stream_t stream, enum stream_state *state)
int
_stream_memory_get_state (stream_t stream, enum stream_state *state)
{
(void)stream;
if (state == NULL)
......@@ -195,10 +205,10 @@ _memory_get_state (stream_t stream, enum stream_state *state)
return 0;
}
static int
_memory_seek (stream_t stream, off_t off, enum stream_whence whence)
int
_stream_memory_seek (stream_t stream, off_t off, enum stream_whence whence)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
off_t noff = mem->offset;
int err = 0;
if (whence == MU_STREAM_WHENCE_SET)
......@@ -212,7 +222,7 @@ _memory_seek (stream_t stream, off_t off, enum stream_whence whence)
if (noff >= 0)
{
if (noff > mem->offset)
_memory_truncate (stream, noff);
_stream_memory_truncate (stream, noff);
mem->offset = noff;
}
else
......@@ -220,41 +230,41 @@ _memory_seek (stream_t stream, off_t off, enum stream_whence whence)
return err;
}
static int
_memory_tell (stream_t stream, off_t *off)
int
_stream_memory_tell (stream_t stream, off_t *off)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
if (off == NULL)
return MU_ERROR_INVALID_PARAMETER;
*off = mem->offset;
return 0;
}
static int
_memory_is_open (stream_t stream)
int
_stream_memory_is_open (stream_t stream)
{
(void)stream;
return 1;
}
static int
_memory_is_readready (stream_t stream, int timeout)
int
_stream_memory_is_readready (stream_t stream, int timeout)
{
(void)stream;
(void)timeout;
return 1;
}
static int
_memory_is_writeready (stream_t stream, int timeout)
int
_stream_memory_is_writeready (stream_t stream, int timeout)
{
(void)stream;
(void)timeout;
return 1;
}
static int
_memory_is_exceptionpending (stream_t stream, int timeout)
int
_stream_memory_is_exceptionpending (stream_t stream, int timeout)
{
(void)stream;
(void)timeout;
......@@ -262,61 +272,134 @@ _memory_is_exceptionpending (stream_t stream, int timeout)
}
static int
_memory_open (stream_t stream, const char *filename, int port, int flags)
int
_stream_memory_open (stream_t stream, const char *filename, int port,
int flags)
{
struct _memory_stream *mem = (struct _memory_stream *)stream;
struct _stream_memory *mem = (struct _stream_memory *)stream;
int status = 0;
(void)port; /* Ignored. */
(void)filename; /* Ignored. */
(void)flags; /* Ignored. */
mu_refcount_lock (mem->refcount);
/* Close any previous file. */
/* Free any previous memory. */
if (mem->ptr)
free (mem->ptr);
mem->ptr = NULL;
mem->capacity = 0;
mem->size = 0;
mem->offset = 0;
mem->flags = flags;
if (filename)
{
struct stat statbuf;
if (stat (filename, &statbuf) == 0)
{
mem->ptr = calloc (1, statbuf.st_size);
if (mem->ptr)
{
FILE *fp;
mem->capacity = statbuf.st_size;
mem->size = statbuf.st_size;
fp = fopen (filename, "r");
if (fp)
{
size_t r = fread (mem->ptr, mem->size, 1, fp);
if (r != mem->size)
status = MU_ERROR_IO;
fclose (fp);
}
else
status = errno;
if (status != 0)
{
free (mem->ptr);
mem->ptr = NULL;
mem->capacity = 0;
mem->size = 0;
}
}
else
status = MU_ERROR_NO_MEMORY;
}
else
status = MU_ERROR_IO;
}
mu_refcount_unlock (mem->refcount);
return 0;
return status;
}
static struct _stream_vtable _mem_vtable =
static struct _stream_vtable _stream_memory_vtable =
{
_memory_ref,
_memory_destroy,
_stream_memory_ref,
_stream_memory_destroy,
_memory_open,
_memory_close,
_stream_memory_open,
_stream_memory_close,
_memory_read,
_memory_readline,
_memory_write,
_stream_memory_read,
_stream_memory_readline,
_stream_memory_write,
_memory_seek,
_memory_tell,
_stream_memory_seek,
_stream_memory_tell,
_memory_get_size,
_memory_truncate,
_memory_flush,
_stream_memory_get_size,
_stream_memory_truncate,
_stream_memory_flush,
_memory_get_fd,
_memory_get_flags,
_memory_get_state,
_stream_memory_get_fd,
_stream_memory_get_flags,
_stream_memory_get_state,
_memory_is_readready,
_memory_is_writeready,
_memory_is_exceptionpending,
_stream_memory_is_readready,
_stream_memory_is_writeready,
_stream_memory_is_exceptionpending,
_memory_is_open
_stream_memory_is_open
};
int
stream_memory_create (stream_t *pstream)
_stream_memory_ctor (struct _stream_memory *mem, size_t capacity)
{
mu_refcount_create (&mem->refcount);
if (mem->refcount == NULL)
return MU_ERROR_NO_MEMORY;
if (capacity)
{
mem->ptr = calloc (1, capacity);
if (mem->ptr == NULL)
{
mu_refcount_destroy (&mem->refcount);
return MU_ERROR_NO_MEMORY;
}
mem->capacity = capacity;
}
else
mem->capacity = 0;
mem->size = 0;
mem->offset = 0;
mem->flags = 0;
mem->base.vtable = &_stream_memory_vtable;
return 0;
}
void
_stream_memory_dtor (struct _stream_memory *mem)
{
mu_refcount_destroy (&mem->refcount);
mem->ptr = NULL;
mem->capacity = 0;
mem->size = 0;
mem->offset = 0;
mem->flags = 0;
}
int
stream_memory_create (stream_t *pstream, size_t capacity)
{
struct _memory_stream *mem;
struct _stream_memory *mem;
int status;
if (pstream == NULL)
return MU_ERROR_INVALID_PARAMETER;
......@@ -325,17 +408,13 @@ stream_memory_create (stream_t *pstream)
if (mem == NULL)
return MU_ERROR_NO_MEMORY;
mu_refcount_create (&mem->refcount);
if (mem->refcount == NULL)
status = _stream_memory_ctor (mem, capacity);
if (status != 0)
{
free (mem);
return MU_ERROR_NO_MEMORY;
return status;
}
mem->ptr = NULL;
mem->size = 0;
mem->offset = 0;
mem->flags = 0;
mem->base.vtable = &_mem_vtable;
mem->base.vtable = &_stream_memory_vtable;
*pstream = &mem->base;
return 0;
}
......
......@@ -27,14 +27,7 @@
#include <mailutils/error.h>
#include <mailutils/refcount.h>
#include <mailutils/sys/ticket.h>
struct _prompt_ticket
{
struct _ticket base;
int ref;
mu_refcount_t refcount;
};
#include <mailutils/sys/pticket.h>
static void
echo_off(struct termios *stored_settings)
......@@ -52,17 +45,17 @@ echo_on(struct termios *stored_settings)
tcsetattr (0, TCSANOW, stored_settings);
}
static int
_prompt_ref (ticket_t ticket)
int
_ticket_prompt_ref (ticket_t ticket)
{
struct _prompt_ticket *prompt = (struct _prompt_ticket *)ticket;
struct _ticket_prompt *prompt = (struct _ticket_prompt *)ticket;
return mu_refcount_inc (prompt->refcount);
}
static void
_prompt_destroy (ticket_t *pticket)
void
_ticket_prompt_destroy (ticket_t *pticket)
{
struct _prompt_ticket *prompt = (struct _prompt_ticket *)*pticket;
struct _ticket_prompt *prompt = (struct _ticket_prompt *)*pticket;
if (mu_refcount_dec (prompt->refcount) == 0)
{
mu_refcount_destroy (&prompt->refcount);
......@@ -70,8 +63,8 @@ _prompt_destroy (ticket_t *pticket)
}
}
static int
_prompt_pop (ticket_t ticket, const char *challenge, char **parg)
int
_ticket_prompt_pop (ticket_t ticket, const char *challenge, char **parg)
{
char arg[256];
struct termios stored_settings;
......@@ -98,18 +91,35 @@ _prompt_pop (ticket_t ticket, const char *challenge, char **parg)
return 0;
}
static struct _ticket_vtable _prompt_vtable =
static struct _ticket_vtable _ticket_prompt_vtable =
{
_prompt_ref,
_prompt_destroy,
_ticket_prompt_ref,
_ticket_prompt_destroy,
_prompt_pop,
_ticket_prompt_pop,
};
int
_ticket_prompt_ctor (struct _ticket_prompt *prompt)
{
mu_refcount_create (&prompt->refcount);
if (prompt->refcount == NULL)
return MU_ERROR_NO_MEMORY;
prompt->base.vtable = &_ticket_prompt_vtable;
return 0;
}
void
_ticket_prompt_dtor (struct _ticket_prompt *prompt)
{
mu_refcount_destroy (&prompt->refcount);
}
int
ticket_prompt_create (ticket_t *pticket)
{
struct _prompt_ticket *prompt;
struct _ticket_prompt *prompt;
int status;
if (pticket == NULL)
return MU_ERROR_INVALID_PARAMETER;
......@@ -118,14 +128,12 @@ ticket_prompt_create (ticket_t *pticket)
if (prompt == NULL)
return MU_ERROR_NO_MEMORY;
mu_refcount_create (&prompt->refcount);
if (prompt->refcount == NULL)
status = _ticket_prompt_ctor (prompt);
if (status != 0)
{
free (prompt);
return MU_ERROR_NO_MEMORY;
return status;
}
*pticket = &prompt->base;
prompt->base.vtable = &_prompt_vtable;
return 0;
}
......
......@@ -27,19 +27,19 @@
#include <mailutils/sys/sdebug.h>
#include <mailutils/error.h>
static int
_sdebug_ref (mu_debug_t debug)
int
_mu_debug_stream_ref (mu_debug_t debug)
{
struct _sdebug *sdebug = (struct _sdebug *)debug;
struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug;
return mu_refcount_inc (sdebug->refcount);
}
static void
_sdebug_destroy (mu_debug_t *pdebug)
void
_mu_debug_stream_destroy (mu_debug_t *pdebug)
{
if (pdebug && *pdebug)
{
struct _sdebug *sdebug = (struct _sdebug *)*pdebug;
struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)*pdebug;
if (mu_refcount_dec (sdebug->refcount) == 0)
{
if (sdebug->stream)
......@@ -55,27 +55,27 @@ _sdebug_destroy (mu_debug_t *pdebug)
}
}
static int
_sdebug_set_level (mu_debug_t debug, size_t level)
int
_mu_debug_stream_set_level (mu_debug_t debug, size_t level)
{
struct _sdebug *sdebug = (struct _sdebug *)debug;
struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug;
sdebug->level = level;
return 0;
}
static int
_sdebug_get_level (mu_debug_t debug, size_t *plevel)
int
_mu_debug_stream_get_level (mu_debug_t debug, size_t *plevel)
{
struct _sdebug *sdebug = (struct _sdebug *)debug;
struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug;
if (plevel)
*plevel = sdebug->level;
return 0;
}
static int
_sdebug_print (mu_debug_t debug, size_t level, const char *mesg)
int
_mu_debug_stream_print (mu_debug_t debug, size_t level, const char *mesg)
{
struct _sdebug *sdebug = (struct _sdebug *)debug;
struct _mu_debug_stream *sdebug = (struct _mu_debug_stream *)debug;
if (mesg == NULL)
return MU_ERROR_INVALID_PARAMETER;
......@@ -86,21 +86,21 @@ _sdebug_print (mu_debug_t debug, size_t level, const char *mesg)
return stream_write (sdebug->stream, mesg, strlen (mesg), NULL);
}
struct _mu_debug_vtable _sdebug_vtable =
static struct _mu_debug_vtable _mu_debug_stream_vtable =
{
_sdebug_ref,
_sdebug_destroy,
_mu_debug_stream_ref,
_mu_debug_stream_destroy,
_sdebug_get_level,
_sdebug_set_level,
_sdebug_print
_mu_debug_stream_get_level,
_mu_debug_stream_set_level,
_mu_debug_stream_print
};
int
mu_debug_stream_create (mu_debug_t *pdebug, stream_t stream,
int close_on_destroy)
{
struct _sdebug *sdebug;
struct _mu_debug_stream *sdebug;
if (pdebug == NULL || stream == NULL)
return MU_ERROR_INVALID_PARAMETER;
......@@ -119,7 +119,7 @@ mu_debug_stream_create (mu_debug_t *pdebug, stream_t stream,
sdebug->level = 0;
sdebug->stream = stream;
sdebug->close_on_destroy = close_on_destroy;
sdebug->base.vtable = &_sdebug_vtable;
sdebug->base.vtable = &_mu_debug_stream_vtable;
*pdebug = &sdebug->base;
return 0;
}
......
......@@ -43,39 +43,33 @@
#endif
static void
_tcp_cleanup (void *arg)
_stream_tcp_cleanup (void *arg)
{
struct _tcp_instance *tcp = arg;
mu_refcount_unlock (tcp->refcount);
struct _stream_tcp *tcp = arg;
mu_refcount_unlock (tcp->base.refcount);
}
static int
_tcp_ref (stream_t stream)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
return mu_refcount_inc (tcp->refcount);
}
static void
_tcp_destroy (stream_t *pstream)
void
_stream_tcp_destroy (stream_t *pstream)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)*pstream;
if (mu_refcount_dec (tcp->refcount) == 0)
struct _stream_tcp *tcp = (struct _stream_tcp *)*pstream;
if (mu_refcount_dec (tcp->base.refcount) == 0)
{
_stream_fd_dtor (&tcp->base);
if (tcp->host)
free (tcp->host);
mu_refcount_destroy (&tcp->refcount);
free (tcp);
}
}
static int
_tcp_close0 (stream_t stream)
_stream_tcp_close0 (stream_t stream)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
if (tcp->fd != -1)
close (tcp->fd);
tcp->fd = -1;
struct _stream_tcp *tcp = (struct _stream_tcp *)stream;
tcp->base.state = MU_STREAM_STATE_CLOSE;
if (tcp->base.fd >= 0)
close (tcp->base.fd);
if (tcp->host)
free (tcp->host);
tcp->host = NULL;
......@@ -83,29 +77,30 @@ _tcp_close0 (stream_t stream)
return 0;
}
static int
_tcp_close (stream_t stream)
int
_stream_tcp_close (stream_t stream)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
struct _stream_tcp *tcp = (struct _stream_tcp *)stream;
mu_refcount_lock (tcp->refcount);
monitor_cleanup_push (_tcp_cleanup, tcp);
_tcp_close0 (stream);
mu_refcount_unlock (tcp->refcount);
monitor_cleanup_pop (0);
_stream_fd_close (stream);
if (tcp->host)
free (tcp->host);
tcp->host = NULL;
tcp->state = TCP_STATE_INIT;
return 0;
}
static int
_tcp_open0 (stream_t stream, const char *host, int port, int flags)
_stream_tcp_open0 (stream_t stream, const char *host, int port, int flags)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
struct _stream_tcp *tcp = (struct _stream_tcp *)stream;
int flgs, ret;
size_t namelen;
struct sockaddr_in peer_addr;
struct hostent *phe;
struct sockaddr_in soc_addr;
tcp->base.state = MU_STREAM_STATE_OPEN;
if (tcp->state == TCP_STATE_INIT)
{
tcp->port = port;
......@@ -114,23 +109,23 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags)
tcp->host = strdup (host);
if (tcp->host == NULL)
return MU_ERROR_NO_MEMORY;
tcp->flags = flags;
tcp->base.flags = flags;
}
switch (tcp->state)
{
case TCP_STATE_INIT:
if (tcp->fd == -1)
if (tcp->base.fd == -1)
{
tcp->fd = socket (AF_INET, SOCK_STREAM, 0);
if (tcp->fd == -1)
tcp->base.fd = socket (AF_INET, SOCK_STREAM, 0);
if (tcp->base.fd == -1)
return errno;
}
if (tcp->flags & MU_STREAM_NONBLOCK)
if (tcp->base.flags & MU_STREAM_NONBLOCK)
{
flgs = fcntl (tcp->fd, F_GETFL);
flgs = fcntl (tcp->base.fd, F_GETFL);
flgs |= O_NONBLOCK;
fcntl (tcp->fd, F_SETFL, flgs);
fcntl (tcp->base.fd, F_SETFL, flgs);
}
tcp->state = TCP_STATE_RESOLVING;
......@@ -143,7 +138,7 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags)
phe = gethostbyname (tcp->host);
if (!phe)
{
_tcp_close0 (stream);
_stream_tcp_close0 (stream);
return MU_ERROR_INVALID_PARAMETER;
}
tcp->address = *(((unsigned long **)phe->h_addr_list)[0]);
......@@ -156,7 +151,8 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags)
soc_addr.sin_port = htons (tcp->port);
soc_addr.sin_addr.s_addr = tcp->address;
if ((connect (tcp->fd, (struct sockaddr *)&soc_addr, sizeof soc_addr)) == -1)
if ((connect (tcp->base.fd, (struct sockaddr *)&soc_addr,
sizeof soc_addr)) == -1)
{
ret = errno;
if (ret == EINPROGRESS || ret == EAGAIN)
......@@ -165,19 +161,20 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags)
ret = MU_ERROR_TRY_AGAIN;
}
else
_tcp_close0 (stream);
_stream_tcp_close0 (stream);
return ret;
}
tcp->state = TCP_STATE_CONNECTING;
case TCP_STATE_CONNECTING:
namelen = sizeof peer_addr;
if (getpeername (tcp->fd, (struct sockaddr *)&peer_addr, &namelen) == 0)
if (getpeername (tcp->base.fd, (struct sockaddr *)&peer_addr,
&namelen) == 0)
tcp->state = TCP_STATE_CONNECTED;
else
{
ret = errno;
_tcp_close0 (stream);
_stream_tcp_close0 (stream);
return ret;
}
break;
......@@ -185,289 +182,53 @@ _tcp_open0 (stream_t stream, const char *host, int port, int flags)
return 0;
}
static int
_tcp_open (stream_t stream, const char *host, int port, int flags)
int
_stream_tcp_open (stream_t stream, const char *host, int port, int flags)
{
int status;
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
mu_refcount_lock (tcp->refcount);
monitor_cleanup_push (_tcp_cleanup, tcp);
status = _tcp_open0 (stream, host, port, flags);
mu_refcount_unlock (tcp->refcount);
struct _stream_tcp *tcp = (struct _stream_tcp *)stream;
mu_refcount_lock (tcp->base.refcount);
monitor_cleanup_push (_stream_tcp_cleanup, tcp);
status = _stream_tcp_open0 (stream, host, port, flags);
mu_refcount_unlock (tcp->base.refcount);
monitor_cleanup_pop (0);
return status;
}
static int
_tcp_get_fd (stream_t stream, int *fd)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
if (fd == NULL || tcp->fd == -1)
return MU_ERROR_INVALID_PARAMETER;
*fd = tcp->fd;
return 0;
}
static int
_tcp_read (stream_t stream, void *buf, size_t buf_size, size_t *br)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
int bytes = 0;
int status = 0;
bytes = recv (tcp->fd, buf, buf_size, 0);
if (bytes == -1)
{
bytes = 0;
status = errno;
}
if (br)
*br = bytes;
return status;
}
static int
_tcp_readline (stream_t stream, char *buf, size_t buf_size, size_t *br)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
int status = 0;
size_t n;
int nr = 0;
char c;
/* Grossly inefficient hopefully they override this */
for (n = 1; n < buf_size; n++)
{
nr = recv (tcp->fd, &c, 1, 0);
if (nr == -1) /* Error. */
{
status = errno;
break;
}
else if (nr == 1)
{
*buf++ = c;
if (c == '\n') /* Newline is stored like fgets(). */
break;
}
else if (nr == 0)
{
if (n == 1) /* EOF, no data read. */
n = 0;
break; /* EOF, some data was read. */
}
}
*buf = '\0';
if (br)
*br = (n == buf_size) ? n - 1: n;
return status;
}
static int
_tcp_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
int bytes = 0;
int status = 0;
bytes = send (tcp->fd, buf, buf_size, 0);
if (bytes == -1)
{
bytes = 0;
status = errno;
}
if (bw)
*bw = bytes;
return status;
}
static int
_tcp_seek (stream_t stream, off_t off, enum stream_whence whence)
{
(void)stream; (void)off; (void)whence;
return MU_ERROR_NOT_SUPPORTED;
}
static int
_tcp_tell (stream_t stream, off_t *off)
{
(void)stream; (void)off;
return MU_ERROR_NOT_SUPPORTED;
}
static int
_tcp_get_size (stream_t stream, off_t *off)
{
(void)stream; (void)off;
return MU_ERROR_NOT_SUPPORTED;
}
static int
_tcp_truncate (stream_t stream, off_t off)
{
(void)stream; (void)off;
return MU_ERROR_NOT_SUPPORTED;
}
static int
_tcp_flush (stream_t stream)
{
(void)stream;
return 0;
}
static int
_tcp_get_flags (stream_t stream, int *flags)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
if (flags == NULL)
return MU_ERROR_INVALID_PARAMETER;
*flags = tcp->flags;
return 0;
}
static int
_tcp_get_state (stream_t stream, enum stream_state *state)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
if (state == NULL)
return MU_ERROR_INVALID_PARAMETER;
*state = tcp->state;
return 0;
}
static int
_tcp_is_readready (stream_t stream, int timeout)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
int ready = 0;
if (tcp->fd >= 0)
{
struct timeval tv;
fd_set fds;
FD_ZERO (&fds);
FD_SET (tcp->fd, &fds);
tv.tv_sec = timeout / 100;
tv.tv_usec = (timeout % 1000) * 1000;
ready = select (tcp->fd + 1, &fds, NULL, NULL,
(timeout == -1) ? NULL: &tv);
ready = (ready == -1) ? 0 : 1;
}
return ready;
}
static int
_tcp_is_writeready (stream_t stream, int timeout)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
int ready = 0;
if (tcp->fd >= 0)
{
struct timeval tv;
fd_set fds;
FD_ZERO (&fds);
FD_SET (tcp->fd, &fds);
tv.tv_sec = timeout / 100;
tv.tv_usec = (timeout % 1000) * 1000;
ready = select (tcp->fd + 1, NULL, &fds, NULL,
(timeout == -1) ? NULL: &tv);
ready = (ready == -1) ? 0 : 1;
}
return ready;
}
static int
_tcp_is_exceptionpending (stream_t stream, int timeout)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
int ready = 0;
if (tcp->fd >= 0)
{
struct timeval tv;
fd_set fds;
FD_ZERO (&fds);
FD_SET (tcp->fd, &fds);
tv.tv_sec = timeout / 100;
tv.tv_usec = (timeout % 1000) * 1000;
ready = select (tcp->fd + 1, NULL, NULL, &fds,
(timeout == -1) ? NULL: &tv);
ready = (ready == -1) ? 0 : 1;
}
return ready;
}
static int
_tcp_is_open (stream_t stream)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
return tcp->fd >= 0;
}
static struct _stream_vtable _tcp_vtable =
{
_tcp_ref,
_tcp_destroy,
_tcp_open,
_tcp_close,
_tcp_read,
_tcp_readline,
_tcp_write,
_tcp_seek,
_tcp_tell,
_tcp_get_size,
_tcp_truncate,
_tcp_flush,
_tcp_get_fd,
_tcp_get_flags,
_tcp_get_state,
_tcp_is_readready,
_tcp_is_writeready,
_tcp_is_exceptionpending,
_tcp_is_open
};
static struct _stream_vtable _stream_tcp_vtable;
int
stream_tcp_create (stream_t *pstream)
{
struct _tcp_instance *tcp;
struct _stream_tcp *tcp;
stream_t stream;
int status;
if (pstream == NULL)
return MU_ERROR_INVALID_PARAMETER;
tcp = calloc (1, sizeof *tcp);
if (tcp == NULL)
return MU_ERROR_NO_MEMORY;
mu_refcount_create (&tcp->refcount);
if (tcp->refcount == NULL)
{
free (tcp);
stream_destroy (&stream);
return MU_ERROR_NO_MEMORY;
}
tcp->fd = -1;
/* Create the base. */
status = _stream_fd_ctor (&tcp->base, -1);
if (status != 0)
return status;
tcp->host = NULL;
tcp->port = -1;
tcp->state = TCP_STATE_INIT;
tcp->base.vtable = &_tcp_vtable;
*pstream = &tcp->base;
_stream_tcp_vtable = *(tcp->base.base.vtable);
/* Overload. */
_stream_tcp_vtable.open = _stream_tcp_open;
_stream_tcp_vtable.close = _stream_tcp_close;
_stream_tcp_vtable.destroy = _stream_tcp_destroy;
tcp->base.base.vtable = &_stream_tcp_vtable;
*pstream = &tcp->base.base;
return 0;
}
......