Commit 594d8574 594d8574f36387da2ac1bc819d2193f999f73cfe by Alain Magloire

* mailbox2/stream.c: stream_read() and stream_write()

	change prototype to be void * instead of char *.
	* mailbox2/bstream.c: Adjust bstream_{read,write} to the
	new prototypes.
	* mailbox2/pop3/pop3_stream.c: Likewised.
	* mailbox2/Makefile.am: New file.
	* mailbox2/pop3/Makefile.am: New file.
	* mailbox2/mstream.c: Mapfile stream Implementation.
	* mailbox2/fstream.c: File stream implementation.
	* mailbox2/include/mailutils/sys/fstream.h: New file.
	* mailbox2/include/mailutils/sys/mstream.h: New file.
	* mailbox2/tcp.c: rename to tcpstream.c.
	* mailbox2/include/mailutils/sys/tcp.h: Rename to tcpstream.h
1 parent 2ca6f6be
# Use automake to process this file -*-Makefile-*-
AUTOMAKE_OPTIONS = ../lib/ansi2knr
#INCLUDES = -I${top_srcdir}/include
INCLUDES = -I${top_srcdir}/mailbox2/include
SUBDIRS = include pop3 mbox
lib_LTLIBRARIES = libmailbox.la
libmailbox_la_SOURCES = \
bstream.c \
fstream.c \
iterator.c \
md5-rsa.c \
mstream.c \
stream.c \
tcp.c
......@@ -118,7 +118,7 @@ _bs_close (stream_t stream)
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, char *buf, size_t count, size_t *pnread)
_bs_read (stream_t stream, void *buf, size_t count, size_t *pnread)
{
int status = 0;
struct _bs *bs = (struct _bs *)stream;
......@@ -138,6 +138,7 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread)
else
{
size_t residue = count;
char *p = buf;
int r;
monitor_lock (bs->lock);
......@@ -151,12 +152,12 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread)
/* Drain our buffer first. */
if (bs->rbuffer.count > 0)
{
memcpy(buf, bs->rbuffer.ptr, bs->rbuffer.count);
memcpy(p, bs->rbuffer.ptr, bs->rbuffer.count);
residue -= bs->rbuffer.count;
buf += bs->rbuffer.count;
p += bs->rbuffer.count;
}
bs->rbuffer.count = 0; /* Signal we will need to refill. */
status = stream_read (bs->stream, buf, residue, &r);
status = stream_read (bs->stream, p, residue, &r);
residue -= r;
if (pnread)
*pnread = count - residue;
......@@ -172,10 +173,10 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread)
/* Drain the buffer, if we have less then requested. */
while (residue > (size_t)(r = bs->rbuffer.count))
{
(void)memcpy (buf, bs->rbuffer.ptr, (size_t)r);
(void)memcpy (p, bs->rbuffer.ptr, (size_t)r);
bs->rbuffer.ptr += r;
/* bs->rbuffer.count = 0 ... done in refill */
buf += r;
p += r;
residue -= r;
status = refill (bs);
/* Did we reach the end. */
......@@ -192,7 +193,7 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread)
}
if (!done)
{
memcpy(buf, bs->rbuffer.ptr, residue);
memcpy(p, bs->rbuffer.ptr, residue);
bs->rbuffer.count -= residue;
bs->rbuffer.ptr += residue;
if (pnread)
......@@ -290,23 +291,24 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread)
}
static int
_bs_write (stream_t stream, const char *buf, size_t count, size_t *pnwrite)
_bs_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, buf, nleft, &nwriten);
err = stream_write (bs->stream, p, nleft, &nwriten);
if (err != 0 || nwriten == 0)
break;
nleft -= nwriten;
total += nwriten;
buf += nwriten;
p += nwriten;
}
if (pnwrite)
*pnwrite = total;
......
/* 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. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <mailutils/sys/fstream.h>
#include <mailutils/error.h>
static int
_fs_add_ref (stream_t stream)
{
struct _fs *fs = (struct _fs *)stream;
int status;
monitor_lock (fs->lock);
status = ++fs->ref;
monitor_unlock (fs->lock);
return status;
}
static int
_fs_destroy (stream_t stream)
{
struct _fs *fs = (struct _fs *)stream;
if (fs->file)
fclose (fs->file);
monitor_destroy (fs->lock);
free (fs);
return 0;
}
static int
_fs_release (stream_t stream)
{
int status;
struct _fs *fs = (struct _fs *)stream;
monitor_lock (fs->lock);
status = --fs->ref;
if (status <= 0)
{
monitor_unlock (fs->lock);
_fs_destroy (stream);
return 0;
}
monitor_unlock (fs->lock);
return status;
}
static int
_fs_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
{
struct _fs *fs = (struct _fs *)stream;
size_t n;
int err = 0;
if (fs->file)
{
n = fread (optr, 1, osize, fs->file);
if (n == 0)
{
if (ferror(fs->file))
err = MU_ERROR_IO;
}
}
if (nbytes)
*nbytes = n;
return err;
}
static int
_fs_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
{
struct _fs *fs = (struct _fs *)stream;
size_t n = 0;
int err = 0;
if (fs->file)
{
if (fgets (optr, osize, fs->file) != NULL)
{
n = strlen (optr);
}
else
{
if (ferror (fs->file))
err = MU_ERROR_IO;
}
}
if (nbytes)
*nbytes = n;
return err;
}
static int
_fs_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
{
struct _fs *fs = (struct _fs *)stream;
size_t n;
int err = 0;
if (fs->file)
{
n = fwrite (iptr, 1, isize, fs->file);
if (n != isize)
{
if (feof (fs->file) == 0)
err = MU_ERROR_IO;
clearerr(fs->file);
n = 0;
}
}
if (nbytes)
*nbytes = n;
return err;
}
static int
_fs_truncate (stream_t stream, off_t len)
{
struct _fs *fs = (struct _fs *)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)
{
struct _fs *fs = (struct _fs *)stream;
struct stat stbuf;
stbuf.st_size = 0;
if (fs->file)
{
fflush (fs->file);
if (fstat(fileno(fs->file), &stbuf) == -1)
return errno;
}
if (psize)
*psize = stbuf.st_size;
return 0;
}
static int
_fs_flush (stream_t stream)
{
struct _fs *fs = (struct _fs *)stream;
if (fs->file)
return fflush (fs->file);
return 0;
}
static int
_fs_get_fd (stream_t stream, int *pfd)
{
struct _fs *fs = (struct _fs *)stream;
int status = 0;
if (pfd)
{
if (fs->file)
*pfd = fileno (fs->file);
else
status = MU_ERROR_INVALID_PARAMETER;
}
return status;
}
static int
_fs_seek (stream_t stream, off_t off, enum stream_whence whence)
{
struct _fs *fs = (struct _fs *)stream;
int err = 0;
if (fs->file)
{
errno = MU_ERROR_INVALID_PARAMETER;
if (whence == MU_STREAM_WHENCE_SET)
err = fseek (fs->file, off, SEEK_SET);
else if (whence == MU_STREAM_WHENCE_CUR)
err = fseek (fs->file, off, SEEK_CUR);
else if (whence == MU_STREAM_WHENCE_END)
err = fseek (fs->file, off, SEEK_END);
else
err = MU_ERROR_INVALID_PARAMETER;
if (err != 0)
err = errno;
}
return err;
}
static int
_fs_tell (stream_t stream, off_t *off)
{
struct _fs *fs = (struct _fs *)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)
{
struct _fs *fs = (struct _fs *)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)
{
(void)stream;
if (state == NULL)
return MU_ERROR_INVALID_PARAMETER;
*state = MU_STREAM_NO_STATE;
return 0;
}
static int
_fs_close (stream_t stream)
{
struct _fs *fs = (struct _fs *)stream;
int err = 0;
if (fs->file)
{
if (fclose (fs->file) != 0)
err = errno;
fs->file = NULL;
}
return err;
}
static int
_fs_open (stream_t stream, const char *filename, int port, int flags)
{
struct _fs *fs = (struct _fs *)stream;
int flg;
int fd;
const char *mode;
(void)port; /* Ignored. */
if (fs->file)
{
fclose (fs->file);
fs->file = NULL;
}
/* Map the flags to the system equivalent. */
if (flags & MU_STREAM_WRITE && flags & MU_STREAM_READ)
return EINVAL;
else if (flags & MU_STREAM_WRITE)
flg = O_WRONLY;
else if (flags & MU_STREAM_RDWR)
flg = O_RDWR;
else /* default */
flg = O_RDONLY;
/* Local folders should not block it is local disk ???
We simply ignore the O_NONBLOCK flag
But take care of the APPEND. */
if (flags & MU_STREAM_APPEND)
flg |= O_APPEND;
/* Handle CREAT with care, not to follow symlinks. */
if (flags & MU_STREAM_CREAT)
{
/* First see if the file already exists. */
fd = open(filename, flg);
if (fd == -1)
{
/* Oops bail out. */
if (errno != ENOENT)
return errno;
/* Race condition here when creating the file ??. */
fd = open(filename, flg|O_CREAT|O_EXCL, 0600);
if (fd < 0)
return errno;
}
}
else
{
fd = open (filename, flg);
if (fd < 0)
return errno;
}
/* We have to make sure that We did not open
a symlink. From Casper D. in bugtraq. */
if ((flg & MU_STREAM_CREAT) ||
(flg & MU_STREAM_RDWR) ||
(flg & MU_STREAM_WRITE))
{
struct stat fdbuf, filebuf;
/* The next two stats should never fail. */
if (fstat(fd, &fdbuf) == -1)
return errno;
if (lstat(filename, &filebuf) == -1)
return errno;
/* Now check that: file and fd reference the same file,
file only has one link, file is plain file. */
if (fdbuf.st_dev != filebuf.st_dev
|| fdbuf.st_ino != filebuf.st_ino
|| fdbuf.st_nlink != 1
|| filebuf.st_nlink != 1
|| (fdbuf.st_mode & S_IFMT) != S_IFREG)
{
mu_error ("%s must be a plain file with one link\n", filename);
close (fd);
return EINVAL;
}
}
/* We use FILE * object. */
if (flags & MU_STREAM_APPEND)
mode = "a";
else if (flags & MU_STREAM_RDWR)
mode = "r+b";
else if (flags & MU_STREAM_WRITE)
mode = "wb";
else /* Default readonly. */
mode = "rb";
fs->file = fdopen (fd, mode);
if (fs->file == NULL)
{
int ret = errno;
free (fs);
return ret;
}
fs->flags = flags;
return 0;
}
static struct _stream_vtable _fs_vtable =
{
_fs_add_ref,
_fs_release,
_fs_destroy,
_fs_open,
_fs_close,
_fs_read,
_fs_readline,
_fs_write,
_fs_seek,
_fs_tell,
_fs_get_size,
_fs_truncate,
_fs_flush,
_fs_get_fd,
_fs_get_flags,
_fs_get_state
};
int
stream_file_create (stream_t *pstream)
{
struct _fs *fs;
if (pstream == NULL)
return MU_ERROR_INVALID_PARAMETER;
fs = calloc (1, sizeof *fs);
if (fs == NULL)
return MU_ERROR_NO_MEMORY ;
fs->base.vtable = &_fs_vtable;
fs->ref = 1;
fs->file = NULL;
fs->flags = 0;
*pstream = &fs->base;
return 0;
}
......@@ -34,9 +34,23 @@ extern int mbox_uidnext __P ((mbox_t, unsigned long));
extern int mbox_open __P ((mbox_t, const char *, int));
extern int mbox_close __P ((mbox_t));
extern int mbox_get_message __P ((mbox_t, unsigned int, message_t *));
extern int mbox_get_envelope __P ((mbox_t, unsigned int, envelope_t *));
extern int mbox_set_envelope __P ((mbox_t, unsigned int, envelope_t));
extern int mbox_get_size __P ((mbox_t, unsigned long *));
extern int mbox_get_header __P ((mbox_t, unsigned int, stream_t *));
extern int mbox_set_header __P ((mbox_t, unsigned int, stream_t));
extern int mbox_header_size __P ((mbox_t, unsigned int, size_t *));
extern int mbox_hdr_get_value __P ((mbox_t, unsigned int, char *, size_t, size_t *));
extern int mbox_hdr_set_value __P ((mbox_t, unsigned int, char *, size_t, int));
extern int mbox_get_body __P ((mbox_t, unsigned int, stream_t *));
extern int mbox_set_body __P ((mbox_t, unsigned int, stream_t));
extern int mbox_body_size __P ((mbox_t, unsigned int, size_t *));
extern int mbox_get_flags __P ((mbox_t, unsigned int, int *));
extern int mbox_set_flags __P ((mbox_t, unsigned int, int));
extern int mbox_size __P ((mbox_t, unsigned long *));
extern int mbox_save_attributes __P ((mbox_t));
extern int mbox_expunge __P ((mbox_t));
......
......@@ -53,9 +53,9 @@ extern int stream_destroy __P ((stream_t));
extern int stream_open __P ((stream_t, const char *, int, int));
extern int stream_close __P ((stream_t));
extern int stream_read __P ((stream_t, char *, size_t, size_t *));
extern int stream_read __P ((stream_t, void *, size_t, size_t *));
extern int stream_readline __P ((stream_t, char *, size_t, size_t *));
extern int stream_write __P ((stream_t, const char *, size_t, size_t*));
extern int stream_write __P ((stream_t, const void *, size_t, size_t*));
extern int stream_seek __P ((stream_t, off_t, enum stream_whence));
extern int stream_tell __P ((stream_t, off_t *));
......
......@@ -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_SYS_TCP_H
#define MAILUTILS_SYS_TCP_H
#ifndef MAILUTILS_SYS_BSTREAM_H
#define MAILUTILS_SYS_BSTREAM_H
#include <mailutils/sys/stream.h>
#include <mailutils/monitor.h>
......@@ -39,4 +39,4 @@ struct _bs
monitor_t lock;
};
#endif /* _MAILUTILS_SYS_TCP_H */
#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 Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU 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_FSTREAM_H
#define MAILUTILS_SYS_FSTREAM_H
#include <mailutils/sys/stream.h>
#include <mailutils/monitor.h>
struct _fs
{
struct _stream base;
int ref;
int flags;
FILE *file;
monitor_t lock;
};
#endif /* _MAILUTILS_SYS_FSTREAM_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 Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU 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_MSTREAM_H
#define MAILUTILS_SYS_MSTREAM_H
#include <mailutils/sys/stream.h>
#include <mailutils/monitor.h>
struct _ms
{
struct _stream base;
int ref;
int fd;
int flags;
int mflags;
char *ptr;
size_t size;
off_t offset;
monitor_t lock;
};
#endif /* _MAILUTILS_SYS_MSTREAM_H */
......@@ -23,6 +23,7 @@
#include <mailutils/pop3.h>
#include <mailutils/sys/stream.h>
#include <mailutils/sys/iterator.h>
#include <mailutils/monitor.h>
#include <mailutils/error.h>
#ifdef DMALLOC
......@@ -59,6 +60,7 @@ struct p_iterator
unsigned int ref;
int done;
void *item;
monitor_t lock;
};
struct p_stream
......@@ -67,6 +69,7 @@ struct p_stream
pop3_t pop3;
unsigned ref;
int done;
monitor_t lock;
};
struct work_buf
......@@ -99,10 +102,12 @@ struct _pop3
enum pop3_state state;
stream_t stream; /* TCP Connection. */
monitor_t lock;
};
extern int pop3_iterator_create __P ((pop3_t, iterator_t *));
extern int pop3_stream_create __P ((pop3_t, stream_t *));
extern void pop3_cleanup __P ((void *));
/* Check for non recoverable error. */
#define POP3_CHECK_EAGAIN(pop3, status) \
......
......@@ -32,9 +32,9 @@ struct _stream_vtable
int (*open) __P ((stream_t, const char *, int, int));
int (*close) __P ((stream_t));
int (*read) __P ((stream_t, char *, size_t, size_t *));
int (*read) __P ((stream_t, void *, size_t, size_t *));
int (*readline) __P ((stream_t, char *, size_t, size_t *));
int (*write) __P ((stream_t, const char *, size_t, size_t *));
int (*write) __P ((stream_t, const void *, size_t, size_t *));
int (*seek) __P ((stream_t, off_t, enum stream_whence));
int (*tell) __P ((stream_t, off_t *));
......
/* 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. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <mailutils/sys/mstream.h>
#include <mailutils/error.h>
#ifdef _POSIX_MAPPED_FILES
#include <sys/mman.h>
#ifndef MAP_FAILED
# define MAP_FAILED (void*)-1
#endif
static int
_ms_add_ref (stream_t stream)
{
int status;
struct _ms *ms = (struct _ms *)stream;
monitor_lock (ms->lock);
status = ++ms->ref;
monitor_unlock (ms->lock);
return status;
}
static int
_ms_destroy (stream_t stream)
{
struct _ms *ms = (struct _ms *)stream;
if (ms->ptr != MAP_FAILED)
{
if (ms->ptr)
munmap (ms->ptr, ms->size);
if (ms->fd != -1)
close (ms->fd);
monitor_destroy (ms->lock);
}
free (ms);
return 0;
}
static int
_ms_release (stream_t stream)
{
int status;
struct _ms *ms = (struct _ms *)stream;
monitor_lock (ms->lock);
status = --ms->ref;
if (status <= 0)
{
monitor_unlock (ms->lock);
_ms_destroy (stream);
return 0;
}
monitor_unlock (ms->lock);
return status;
}
static int
_ms_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
{
struct _ms *ms = (struct _ms *)stream;
size_t n = 0;
monitor_lock (ms->lock);
if (ms->ptr != MAP_FAILED && ms->ptr)
{
if (ms->offset < (off_t)ms->size)
{
n = ((ms->offset + osize) > ms->size) ?
ms->size - ms->offset : osize;
memcpy (optr, ms->ptr + ms->offset, n);
ms->offset += n;
}
}
monitor_unlock (ms->lock);
if (nbytes)
*nbytes = n;
return 0;
}
static int
_ms_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
{
struct _ms *ms = (struct _ms *)stream;
size_t n = 0;
monitor_lock (ms->lock);
if (ms->ptr != MAP_FAILED && ms->ptr)
{
if (ms->offset < (off_t)ms->size)
{
/* Save space for the null byte. */
char *nl;
osize--;
nl = memchr (ms->ptr + ms->offset, '\n', ms->size - ms->offset);
n = (nl) ? nl - (ms->ptr + ms->offset) + 1 : ms->size - ms->offset;
n = (n > osize) ? osize : n;
memcpy (optr, ms->ptr + ms->offset, n);
optr[n] = '\0';
ms->offset += n;
}
}
monitor_unlock (ms->lock);
if (nbytes)
*nbytes = n;
return 0;
}
static int
_ms_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
{
struct _ms *ms = (struct _ms *)stream;
int err = 0;
size_t n = 0;
monitor_lock (ms->lock);
if (ms->mflags & PROT_WRITE)
{
/* Bigger we have to remmap. */
if (ms->size < (ms->offset + isize))
{
if (ms->ptr != MAP_FAILED && munmap (ms->ptr, ms->size) == 0)
{
ms->ptr = MAP_FAILED;
if (ftruncate (ms->fd, ms->offset + isize) == 0)
{
ms->ptr = mmap (0, ms->offset + isize, ms->mflags,
MAP_SHARED, ms->fd, 0);
if (ms->ptr != MAP_FAILED)
ms->size = ms->offset + isize;
}
}
}
if (ms->ptr != MAP_FAILED)
{
if (isize > 0)
memcpy (ms->ptr + ms->offset, iptr, isize);
ms->offset += isize;
n = isize;
}
else
err = MU_ERROR_IO;
}
else
err = MU_ERROR_IO;
monitor_unlock (ms->lock);
if (nbytes)
*nbytes = n;
return err;
}
static int
_ms_truncate (stream_t stream, off_t len)
{
struct _ms *ms = (struct _ms *)stream;
int err = 0;
monitor_lock (ms->lock);
if (ms->ptr != MAP_FAILED)
{
/* Remap. */
if (ms->ptr && munmap (ms->ptr, ms->size) == 0)
{
if (ftruncate (ms->fd, len) == 0)
{
ms->ptr = (len) ?
mmap (0, len, ms->mflags, MAP_SHARED, ms->fd, 0) : NULL;
if (ms->ptr != MAP_FAILED)
{
ms->size = len;
}
else
err = errno;
}
else
err = errno;
}
}
monitor_unlock (ms->lock);
return err;
}
static int
_ms_get_size (stream_t stream, off_t *psize)
{
struct _ms *ms = (struct _ms *)stream;
struct stat stbuf;
int err = 0;
monitor_lock (ms->lock);
stbuf.st_size = 0;
if (ms->ptr != MAP_FAILED)
{
if (ms->ptr)
msync (ms->ptr, ms->size, MS_SYNC);
if (fstat(ms->fd, &stbuf) == 0)
{
/* Remap. */
if (ms->size != (size_t)stbuf.st_size)
{
if (ms->ptr && munmap (ms->ptr, ms->size) == 0)
{
if (ms->size)
{
ms->ptr = mmap (0, ms->size, ms->mflags , MAP_SHARED,
ms->fd, 0);
if (ms->ptr != MAP_FAILED)
ms->size = stbuf.st_size;
else
err = errno;
}
else
ms->ptr = NULL;
}
else
err = errno;
}
}
}
monitor_unlock (ms->lock);
if (psize)
*psize = stbuf.st_size;
return err;
}
static int
_ms_flush (stream_t stream)
{
int err = 0;
struct _ms *ms = (struct _ms *)stream;
monitor_lock (ms->lock);
if (ms->ptr != MAP_FAILED && ms->ptr != NULL)
err = msync (ms->ptr, ms->size, MS_SYNC);
monitor_unlock (ms->lock);
return 0;
}
static int
_ms_get_fd (stream_t stream, int *pfd)
{
struct _ms *ms = (struct _ms *)stream;
if (pfd)
*pfd = ms->fd;
return 0;
}
static int
_ms_get_flags (stream_t stream, int *flags)
{
struct _ms *ms = (struct _ms *)stream;
if (flags == NULL)
return MU_ERROR_INVALID_PARAMETER;
*flags = ms->flags;
return 0;
}
static int
_ms_get_state (stream_t stream, enum stream_state *state)
{
(void)stream;
if (state == NULL)
return MU_ERROR_INVALID_PARAMETER;
*state = MU_STREAM_NO_STATE;
return 0;
}
static int
_ms_seek (stream_t stream, off_t off, enum stream_whence whence)
{
struct _ms *ms = (struct _ms *)stream;
off_t noff = ms->offset;
int err = 0;
if (whence == MU_STREAM_WHENCE_SET)
noff = off;
else if (whence == MU_STREAM_WHENCE_CUR)
noff += off;
else if (whence == MU_STREAM_WHENCE_END)
noff = ms->size + off;
else
noff = -1; /* error. */
if (noff >= 0)
{
if (noff > ms->offset)
_ms_truncate (stream, noff);
ms->offset = noff;
}
else
err = MU_ERROR_INVALID_PARAMETER;
return err;
}
static int
_ms_tell (stream_t stream, off_t *off)
{
struct _ms *ms = (struct _ms *)stream;
if (off == NULL)
return MU_ERROR_INVALID_PARAMETER;
*off = ms->offset;
return 0;
}
static int
_ms_close (stream_t stream)
{
struct _ms *ms = (struct _ms *)stream;
int err = 0;
monitor_lock (ms->lock);
if (ms->ptr != MAP_FAILED)
{
if (ms->ptr && munmap (ms->ptr, ms->size) != 0)
err = errno;
ms->ptr = MAP_FAILED;
}
if (ms->fd != -1)
if (close (ms->fd) != 0)
err = errno;
ms->fd = -1;
monitor_unlock (ms->lock);
return err;
}
static int
_ms_open (stream_t stream, const char *filename, int port, int flags)
{
struct _ms *ms = (struct _ms *)stream;
int mflag, flg;
struct stat st;
(void)port; /* Ignored. */
/* Close any previous file. */
if (ms->ptr != MAP_FAILED)
{
if (ms->ptr)
munmap (ms->ptr, ms->size);
ms->ptr = MAP_FAILED;
}
if (ms->fd != -1)
{
close (ms->fd);
ms->fd = -1;
}
/* Map the flags to the system equivalent */
if ((flags & MU_STREAM_WRITE) && (flags & MU_STREAM_READ))
return EINVAL;
else if (flags & MU_STREAM_WRITE)
{
mflag = PROT_WRITE;
flg = O_WRONLY;
}
else if (flags & MU_STREAM_RDWR)
{
mflag = PROT_READ | PROT_WRITE;
flg = O_RDWR;
}
else if (flags & MU_STREAM_CREAT)
return ENOSYS;
else /* default */
{
mflag = PROT_READ;
flg = O_RDONLY;
}
ms->fd = open (filename, flg);
if (ms->fd < 0)
return errno;
if (fstat (ms->fd, &st) != 0)
{
int err = errno;
close (ms->fd);
return err;
}
ms->size = st.st_size;
if (ms->size)
{
ms->ptr = mmap (0, ms->size, mflag , MAP_SHARED, ms->fd, 0);
if (ms->ptr == MAP_FAILED)
{
int err = errno;
close (ms->fd);
ms->ptr = MAP_FAILED;
return err;
}
}
else
ms->ptr = NULL;
ms->mflags = mflag;
ms->flags = flags;
return 0;
}
static struct _stream_vtable _ms_vtable =
{
_ms_add_ref,
_ms_release,
_ms_destroy,
_ms_open,
_ms_close,
_ms_read,
_ms_readline,
_ms_write,
_ms_seek,
_ms_tell,
_ms_get_size,
_ms_truncate,
_ms_flush,
_ms_get_fd,
_ms_get_flags,
_ms_get_state,
};
#endif /* _POSIX_MAPPED_FILES */
int
stream_mapfile_create (stream_t *pstream)
{
#ifndef _POSIX_MAPPED_FILES
return ENOSYS;
#else
struct _ms *ms;
if (pstream == NULL)
return MU_ERROR_INVALID_PARAMETER;
ms = calloc (1, sizeof *ms);
if (ms == NULL)
return MU_ERROR_NO_MEMORY;
ms->base.vtable = &_ms_vtable;
ms->ref = 1;
ms->fd = -1;
ms->offset = -1;
ms->flags = 0;
ms->mflags = 0;
*pstream = &ms->base;
return 0;
#endif /* _POSIX_MAPPED_FILES */
}
# Use automake to process this file -*-Makefile-*-
AUTOMAKE_OPTIONS = ../lib/ansi2knr
#INCLUDES = -I${top_srcdir}/include
INCLUDES = -I${top_srcdir}/mailbox2/include
lib_LTLIBRARIES = libpop3.la
libmailbox_la_SOURCES = \
pop3_apop.c \
pop3_capa.c \
pop3_cleanup.c \
pop3_connect.c \
pop3_create.c \
pop3_dele.c \
pop3_destroy.c \
pop3_disconnect.c \
pop3_iterator.c \
pop3_list.c \
pop3_lista.c \
pop3_noop.c \
pop3_pass.c \
pop3_quit.c \
pop3_readline.c \
pop3_response.c \
pop3_retr.c \
pop3_rset.c \
pop3_sendline.c \
pop3_stat.c \
pop3_stream.c \
pop3_timeout.c \
pop3_top.c \
pop3_uidl.c \
pop3_uidla.c \
pop3_user.c
......@@ -49,10 +49,10 @@ pop3_get_stream (pop3_t pop3, stream_t *pstream)
if (pop3->stream == NULL)
{
stream_t stream = NULL;
int status = stream_tcp_create (&stream));
int status = stream_tcp_create (&stream);
if (status)
return status;
stream_buffer_create (&(pop3->stream), stream, 1024); */
stream_buffer_create (&(pop3->stream), stream, 1024);
}
*pstream = pop3->stream;
return 0;
......@@ -66,9 +66,9 @@ static int p_destroy __P ((stream_t));
static int p_open __P ((stream_t, const char *, int, int));
static int p_close __P ((stream_t));
static int p_read __P ((stream_t, char *, size_t, size_t *));
static int p_read __P ((stream_t, void *, size_t, size_t *));
static int p_readline __P ((stream_t, char *, size_t, size_t *));
static int p_write __P ((stream_t, const char *, size_t, size_t *));
static int p_write __P ((stream_t, const void *, size_t, size_t *));
static int p_seek __P ((stream_t, off_t, enum stream_whence));
static int p_tell __P ((stream_t, off_t *));
......@@ -191,11 +191,12 @@ p_close (stream_t stream)
}
static int
p_read (stream_t stream, char *buf, size_t buflen, size_t *pn)
p_read (stream_t stream, void *buf, size_t buflen, size_t *pn)
{
struct p_stream *p_stream = (struct p_stream *)stream;
size_t n = 0;
int status = 0;
char *p = buf;
if (p_stream)
{
monitor_lock (p_stream->lock);
......@@ -208,17 +209,17 @@ p_read (stream_t stream, char *buf, size_t buflen, size_t *pn)
/* The pop3_readline () function will always read one less to
be able to terminate the buffer, this will cause serious grief
for stream_read() where it is legitimate to have a buffer of
1 char. So we must catch here or change the behavoiour of
1 char. So we must catch it here or change the behaviour of
XXX_readline. */
if (buflen == 1)
{
char buffer[2];
*buffer = '\0';
status = pop3_readline (p_stream->pop3, buffer, 2, &nread);
*buf = *buffer;
*p = *buffer;
}
else
status = pop3_readline (p_stream->pop3, buf, buflen, &nread);
status = pop3_readline (p_stream->pop3, p, buflen, &nread);
if (status != 0)
break;
......@@ -230,7 +231,7 @@ p_read (stream_t stream, char *buf, size_t buflen, size_t *pn)
}
n += nread;
buflen -= nread;
buf += nread;
p += nread;
}
while (buflen > 0);
}
......@@ -267,7 +268,7 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn)
}
static int
p_write (stream_t stream, const char *buf, size_t buflen, size_t *pn)
p_write (stream_t stream, const void *buf, size_t buflen, size_t *pn)
{
struct p_stream *p_stream = (struct p_stream *)stream;
return stream_write (p_stream->pop3->stream, buf, buflen, pn);
......
......@@ -125,7 +125,7 @@ main (int argc, char **argv)
for ( ; done == 0; )
{
line = readline ("pop3> ");
line = readline ((char *)"pop3> ");
if (!line)
break;
......
......@@ -69,7 +69,7 @@ int
}
int
(stream_read) (stream_t stream, char *buf, size_t buflen, size_t *n)
(stream_read) (stream_t stream, void *buf, size_t buflen, size_t *n)
{
if (stream == NULL || stream->vtable == NULL
|| stream->vtable->read == NULL)
......@@ -87,7 +87,7 @@ int
}
int
(stream_write) (stream_t stream, const char *buf, size_t buflen, size_t *n)
(stream_write) (stream_t stream, const void *buf, size_t buflen, size_t *n)
{
if (stream == NULL || stream->vtable == NULL
|| stream->vtable->write == NULL)
......
......@@ -24,7 +24,6 @@
#include <errno.h>
#include <netdb.h>
#include <fcntl.h>
//#define __USE_BSD
#include <string.h>
#include <strings.h>
#include <sys/types.h>
......@@ -33,7 +32,7 @@
#include <arpa/inet.h>
#include <unistd.h>
#include <mailutils/sys/tcp.h>
#include <mailutils/sys/tcpstream.h>
#include <mailutils/error.h>
/* On solaris inet_addr() return -1. */
......@@ -226,7 +225,7 @@ _tcp_get_fd (stream_t stream, int *fd)
}
static int
_tcp_read (stream_t stream, char *buf, size_t buf_size, size_t *br)
_tcp_read (stream_t stream, void *buf, size_t buf_size, size_t *br)
{
struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
int bytes;
......@@ -282,7 +281,7 @@ _tcp_readline (stream_t stream, char *buf, size_t buf_size, size_t *br)
}
static int
_tcp_write (stream_t stream, const char *buf, size_t buf_size, size_t *bw)
_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;
......@@ -339,6 +338,8 @@ 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;
}
......@@ -347,6 +348,8 @@ 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;
}
......@@ -381,6 +384,9 @@ stream_tcp_create (stream_t *pstream)
{
struct _tcp_instance *tcp;
if (pstream == NULL)
return MU_ERROR_INVALID_PARAMETER;
tcp = calloc (1, sizeof *tcp);
if (tcp == NULL)
return MU_ERROR_NO_MEMORY;
......