Commit 69a7eacb 69a7eacb090fe733c8ffe108a5b0f8841abde1cf by Sam Roberts

Modified stream creation and opening. The *_stream_create() functions now

take the specific arguments appropriate to them and setup a stream_t
so that stream_open(), which now takes no arguments, can perform whatever
actions are appropriate when opening that particular kind of stream.

I have tested the changes with the example programs and sieve, but not with
the imap or pop servers.
1 parent 7cf404b6
......@@ -481,7 +481,7 @@ notify_user (const char *user, const char *device, const char *path, off_t offse
return;
}
if ((status = memory_stream_create (&stream)))
if ((status = memory_stream_create (&stream, 0, 0)))
{
syslog (LOG_ERR, "can't create temporary stream: %s",
strerror (status));
......
......@@ -78,7 +78,7 @@ imap4d_append0 (mailbox_t mbox, int flags, char *text)
if (mailbox_open (tmp, MU_STREAM_READ) != 0)
return 1;
if (memory_stream_create (&stream))
if (memory_stream_create (&stream, 0, 0))
{
mailbox_close (tmp);
return 1;
......
......@@ -1174,7 +1174,7 @@ fetch_header_fields (message_t msg, char **arg, unsigned long start,
stream_t stream = NULL;
int status;
status = memory_stream_create (&stream);
status = memory_stream_create (&stream, 0, 0);
if (status != 0)
imap4d_bye (ERR_NO_MEM);
......@@ -1275,7 +1275,7 @@ fetch_header_fields_not (message_t msg, char **arg, unsigned long start,
stream_t stream = NULL;
int status;
status = memory_stream_create (&stream);
status = memory_stream_create (&stream, 0, 0);
if (status)
imap4d_bye (ERR_NO_MEM);
......
......@@ -18,6 +18,7 @@
#ifndef _MAILUTILS_STREAM_H
# define _MAILUTILS_STREAM_H
#include <stdio.h>
#include <sys/types.h>
#include <mailutils/property.h>
......@@ -43,66 +44,41 @@ typedef struct _stream *stream_t;
#define MU_STREAM_APPEND 0x00000008
#define MU_STREAM_CREAT 0x00000010
#define MU_STREAM_NONBLOCK 0x00000020
/* Stream will be destroy on stream_destroy whitout checking the owner. */
/* Stream will be destroy on stream_destroy without checking the owner. */
#define MU_STREAM_NO_CHECK 0x00000040
#define MU_STREAM_SEEKABLE 0x00000080
#define MU_STREAM_NO_CLOSE 0x00000100
extern int stream_create __P ((stream_t *, int flags, void *owner));
extern void stream_destroy __P ((stream_t *, void *owner));
extern int stream_set_destroy __P ((stream_t, void (*_destroy) __P ((stream_t)), void *owner));
extern void * stream_get_owner __P ((stream_t));
extern int stream_open __P ((stream_t, const char *, int, int));
extern int stream_set_open __P ((stream_t, int (*_open)
__P ((stream_t, const char *, int, int)),
void *owner));
extern int stream_close __P ((stream_t));
extern int stream_set_close __P ((stream_t, int (*_close) __P ((stream_t)),
void *owner));
extern int stream_is_seekable __P ((stream_t));
extern int stream_get_fd __P ((stream_t , int *));
extern int stream_set_fd __P ((stream_t, int (*_get_fd)(stream_t, int *),
void *owner));
extern int stream_read __P ((stream_t, char *, size_t,
off_t, size_t *));
extern int stream_set_read __P ((stream_t, int
(*_read) __P ((stream_t, char *, size_t,
off_t, size_t *)),
void *owner));
extern int stream_readline __P ((stream_t, char *, size_t,
off_t, size_t *));
extern int stream_set_readline __P ((stream_t, int
(*_readline) __P ((stream_t, char *,
size_t, off_t,
size_t *)),
void *owner));
extern int stream_size __P ((stream_t, off_t *));
extern int stream_set_size __P ((stream_t, int
(*_size) __P ((stream_t, off_t *)),
void *owner));
extern int stream_truncate __P ((stream_t, off_t));
extern int stream_set_truncate __P ((stream_t, int
(*_truncate) __P ((stream_t, off_t)),
void *owner));
extern int stream_write __P ((stream_t, const char *, size_t,
off_t, size_t *));
extern int stream_set_write __P ((stream_t, int
(*_write) __P ((stream_t, const char *,
size_t, off_t, size_t *)),
void *owner));
extern int stream_setbufsiz __P ((stream_t stream, size_t size));
extern int stream_flush __P ((stream_t));
extern int stream_set_flush __P ((stream_t, int (*_flush)
__P ((stream_t)), void *owner));
/* Functions useful to users of the pre-defined stream types. */
extern int file_stream_create __P ((stream_t *stream, const char* filename, int flags));
extern int tcp_stream_create __P ((stream_t *stream, const char* host, int port, int flags));
extern int mapfile_stream_create __P ((stream_t *stream, const char* filename, int flags));
extern int memory_stream_create __P ((stream_t *stream, const char* filename, int flags));
extern int encoder_stream_create __P ((stream_t *stream, stream_t iostream, const char *encoding));
extern int decoder_stream_create __P ((stream_t *stream, stream_t iostream, const char *encoding));
extern void stream_destroy __P ((stream_t *, void *owner));
extern int stream_open __P ((stream_t));
extern int stream_close __P ((stream_t));
extern int stream_is_seekable __P ((stream_t));
extern int stream_get_fd __P ((stream_t , int *));
extern int stream_read __P ((stream_t, char *, size_t, off_t, size_t *));
extern int stream_readline __P ((stream_t, char *, size_t, off_t, size_t *));
extern int stream_size __P ((stream_t, off_t *));
extern int stream_truncate __P ((stream_t, off_t));
extern int stream_write __P ((stream_t, const char *, size_t, off_t, size_t *));
extern int stream_setbufsiz __P ((stream_t stream, size_t size));
extern int stream_flush __P ((stream_t));
/* Functions useful to implementors of new stream types. */
extern int stream_create __P ((stream_t *stream, int flags, void* owner));
extern void* stream_get_owner __P ((stream_t));
extern void stream_set_owner __P ((stream_t, void* owner));
extern int stream_get_flags __P ((stream_t, int *pflags));
extern int stream_set_flags __P ((stream_t, int flags));
......@@ -116,18 +92,39 @@ extern int stream_set_property __P ((stream_t, property_t, void *));
#define MU_STREAM_STATE_CLOSE 8
extern int stream_get_state __P ((stream_t, int *pstate));
/* Misc. */
extern int file_stream_create __P ((stream_t *stream));
extern int mapfile_stream_create __P ((stream_t *stream));
extern int memory_stream_create __P ((stream_t *stream));
extern int tcp_stream_create __P ((stream_t *stream));
extern int encoder_stream_create __P ((stream_t *stream, stream_t iostream,
const char *encoding));
extern int decoder_stream_create __P ((stream_t *stream, stream_t iostream,
const char *encoding));
extern int stream_set_destroy __P ((stream_t,
void (*_destroy) __P ((stream_t)), void *owner));
extern int stream_set_open __P ((stream_t,
int (*_open) __P ((stream_t)), void *owner));
extern int stream_set_close __P ((stream_t,
int (*_close) __P ((stream_t)), void *owner));
extern int stream_set_fd __P ((stream_t,
int (*_get_fd)(stream_t, int *), void *owner));
extern int stream_set_read __P ((stream_t,
int (*_read) __P ((stream_t, char *, size_t, off_t, size_t *)), void *owner));
extern int stream_set_readline __P ((stream_t,
int (*_readline) __P ((stream_t, char *, size_t, off_t, size_t *)), void *owner));
extern int stream_set_size __P ((stream_t,
int (*_size) __P ((stream_t, off_t *)), void *owner));
extern int stream_set_truncate __P ((stream_t,
int (*_truncate) __P ((stream_t, off_t)), void *owner));
extern int stream_set_write __P ((stream_t,
int (*_write) __P ((stream_t, const char *, size_t, off_t, size_t *)), void *owner));
extern int stream_set_flush __P ((stream_t,
int (*_flush) __P ((stream_t)), void *owner));
#ifdef __cplusplus
}
#endif
#endif /* _MAILUTILS_STREAM_H */
......
......@@ -92,8 +92,8 @@ int message_create_attachment(const char *content_type, const char *encoding, co
sprintf(header, MSG_HDR, content_type, name, encoding, name);
if ( ( ret = header_create( &hdr, header, strlen(header), *newmsg ) ) == 0 ) {
message_get_body(*newmsg, &body);
if ( ( ret = file_stream_create(&fstream) ) == 0 ) {
if ( ( ret = stream_open(fstream, filename, 0, MU_STREAM_READ) ) == 0 ) {
if ( ( ret = file_stream_create(&fstream, filename, MU_STREAM_READ) ) == 0 ) {
if ( ( ret = stream_open(fstream) ) == 0 ) {
if ( ( ret = filter_create(&tstream, fstream, encoding, MU_FILTER_ENCODE, MU_STREAM_READ) ) == 0 ) {
body_set_stream(body, tstream, *newmsg);
message_set_header(*newmsg, hdr, NULL);
......@@ -255,8 +255,8 @@ int message_save_attachment(message_t msg, const char *filename, void **data)
ret = message_attachment_filename(msg, &fname);
else
fname = filename;
if ( fname && ( ret = file_stream_create(&info->fstream) ) == 0 ) {
if ( ( ret = stream_open(info->fstream, fname, 0, MU_STREAM_WRITE|MU_STREAM_CREAT) ) == 0 ) {
if ( fname && ( ret = file_stream_create(&info->fstream, fname, MU_STREAM_WRITE|MU_STREAM_CREAT) ) == 0 ) {
if ( ( ret = stream_open(info->fstream) ) == 0 ) {
header_get_value(hdr, "Content-Transfer-Encoding", NULL, 0, &size);
if ( size ) {
if ( ( content_encoding = alloca(size+1) ) == NULL )
......
......@@ -147,16 +147,16 @@ body_get_stream (body_t body, stream_t *pstream)
if (body->stream == NULL)
{
int fd;
int status = stream_create (&(body->stream), MU_STREAM_RDWR, body);
int status = stream_create (&body->stream, MU_STREAM_RDWR, body);
if (status != 0)
return status;
status = file_stream_create (&(body->fstream));
status = file_stream_create (&body->fstream, body->filename, MU_STREAM_RDWR);
if (status != 0)
return status;
fd = lazy_create (body);
if (fd == -1)
return errno;
status = stream_open (body->fstream, body->filename, 0, MU_STREAM_RDWR);
status = stream_open (body->fstream);
close (fd);
if (status != 0)
return status;
......
......@@ -19,6 +19,7 @@
# include <config.h>
#endif
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -34,16 +35,22 @@
struct _file_stream
{
FILE *file;
int offset;
FILE *file;
int offset;
char *filename;
};
static void
_file_destroy (stream_t stream)
{
struct _file_stream *fs = stream_get_owner (stream);
if (fs->file)
fclose (fs->file);
stream_close (stream);
if (fs->filename)
free (fs->filename);
free (fs);
}
......@@ -222,24 +229,42 @@ _file_close (stream_t stream)
{
struct _file_stream *fs = stream_get_owner (stream);
int err = 0;
if (!stream)
return EINVAL;
if (fs->file)
{
if (fclose (fs->file) != 0)
err = errno;
int flags = 0;
stream_get_flags (stream, &flags);
if ((flags & MU_STREAM_NO_CLOSE) == 0)
{
if (fclose (fs->file) != 0)
err = errno;
}
fs->file = NULL;
}
return err;
}
static int
_file_open (stream_t stream, const char *filename, int port, int flags)
_file_open (stream_t stream)
{
struct _file_stream *fs = stream_get_owner (stream);
int flg;
int fd;
const char *mode;
char* filename = 0;
int flags = 0;
assert(fs);
(void)port; /* Ignored. */
filename = fs->filename;
assert(filename);
if (fs->file)
{
......@@ -247,6 +272,8 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
fs->file = NULL;
}
stream_get_flags(stream, &flags);
/* Map the flags to the system equivalent. */
if (flags & MU_STREAM_WRITE && flags & MU_STREAM_READ)
return EINVAL;
......@@ -327,15 +354,14 @@ _file_open (stream_t stream, const char *filename, int port, int flags)
if (fs->file == NULL)
{
int ret = errno;
free (fs);
return ret;
}
stream_set_flags (stream, flags |MU_STREAM_NO_CHECK);
return 0;
}
int
file_stream_create (stream_t *stream)
file_stream_create (stream_t *stream, const char* filename, int flags)
{
struct _file_stream *fs;
int ret;
......@@ -347,10 +373,17 @@ file_stream_create (stream_t *stream)
if (fs == NULL)
return ENOMEM;
ret = stream_create (stream, MU_STREAM_NO_CHECK, fs);
if ((fs->filename = strdup(filename)) == NULL)
{
free (fs);
return ENOMEM;
}
ret = stream_create (stream, flags|MU_STREAM_NO_CHECK, fs);
if (ret != 0)
{
free (fs);
free (fs->filename);
return ret;
}
......@@ -364,5 +397,46 @@ file_stream_create (stream_t *stream)
stream_set_size (*stream, _file_size, fs);
stream_set_flush (*stream, _file_flush, fs);
stream_set_destroy (*stream, _file_destroy, fs);
return 0;
}
int
stdio_stream_create (stream_t *stream, FILE* file, int flags)
{
struct _file_stream *fs;
int ret;
if (stream == NULL)
return EINVAL;
if (file == NULL)
return EINVAL;
fs = calloc (1, sizeof (struct _file_stream));
if (fs == NULL)
return ENOMEM;
fs->file = file;
ret = stream_create (stream, flags|MU_STREAM_NO_CHECK, fs);
if (ret != 0)
{
free (fs);
return ret;
}
/* We don't need to open the FILE, just return success. */
stream_set_open (*stream, NULL, fs);
stream_set_close (*stream, _file_close, fs);
stream_set_fd (*stream, _file_get_fd, fs);
stream_set_read (*stream, _file_read, fs);
stream_set_readline (*stream, _file_readline, fs);
stream_set_write (*stream, _file_write, fs);
stream_set_flush (*stream, _file_flush, fs);
stream_set_destroy (*stream, _file_destroy, fs);
return 0;
}
......
......@@ -80,11 +80,11 @@ filter_write (stream_t stream, const char *buffer, size_t buflen,
}
static int
filter_open (stream_t stream, const char *filename, int port, int flags)
filter_open (stream_t stream)
{
filter_t filter = stream_get_owner (stream);
stream_set_flags (stream, flags);
return stream_open (filter->stream, filename, port, flags);
return stream_open (filter->stream);
}
static int
......
......@@ -434,9 +434,9 @@ folder_imap_open (folder_t folder, int flags)
{
CHECK_ERROR (f_imap, ENOMEM);
}
status = memory_stream_create (&f_imap->string.stream);
status = memory_stream_create (&f_imap->string.stream, NULL, MU_STREAM_RDWR);
CHECK_ERROR (f_imap, status);
stream_open (f_imap->string.stream, NULL, 0, MU_STREAM_RDWR);
stream_open (f_imap->string.stream);
}
else
{
......@@ -451,7 +451,7 @@ folder_imap_open (folder_t folder, int flags)
/* Create the networking stack. */
if (folder->stream == NULL)
{
status = tcp_stream_create (&(folder->stream));
status = tcp_stream_create (&folder->stream, host, port, folder->flags);
CHECK_ERROR (f_imap, status);
/* Ask for the stream internal buffering mechanism scheme. */
stream_setbufsiz (folder->stream, BUFSIZ);
......@@ -463,7 +463,7 @@ folder_imap_open (folder_t folder, int flags)
case IMAP_OPEN_CONNECTION:
/* Establish the connection. */
status = stream_open (folder->stream, host, port, folder->flags);
status = stream_open (folder->stream);
CHECK_EAGAIN (f_imap, status);
/* Can't recover bailout. */
CHECK_ERROR_CLOSE (folder, f_imap, status);
......
......@@ -864,10 +864,10 @@ fill_blurb (header_t header)
if (header->mstream == NULL)
{
status = memory_stream_create (&(header->mstream));
status = memory_stream_create (&header->mstream, NULL, MU_STREAM_RDWR);
if (status != 0)
return status;
stream_open (header->mstream, NULL, 0, MU_STREAM_RDWR);
stream_open (header->mstream);
header->stream_len = 0;
}
......@@ -940,10 +940,15 @@ header_write (stream_t os, const char *buf, size_t buflen,
if (header->mstream == NULL)
{
status = memory_stream_create (&(header->mstream));
status = memory_stream_create (&header->mstream, NULL, MU_STREAM_RDWR);
if (status != 0)
return status;
stream_open (header->mstream, NULL, 0, MU_STREAM_RDWR);
status = stream_open (header->mstream);
if (status != 0)
{
stream_destroy(&header->mstream, NULL);
return status;
}
header->stream_len = 0;
}
......
......@@ -20,5 +20,4 @@ observer0.h \
property0.h \
registrar0.h \
stream0.h \
tcp0.h \
url0.h
......
......@@ -58,7 +58,7 @@ struct _stream
struct rbuffer rbuffer;
void (*_destroy) __P ((stream_t));
int (*_open) __P ((stream_t, const char *, int port, int flags));
int (*_open) __P ((stream_t));
int (*_close) __P ((stream_t));
int (*_get_fd) __P ((stream_t, int *));
int (*_read) __P ((stream_t, char *, size_t, off_t, size_t *));
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU 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 _TCP0_H
#define _TCP0_H
#define TCP_STATE_INIT 1
#define TCP_STATE_RESOLVE 2
#define TCP_STATE_RESOLVING 3
#define TCP_STATE_CONNECTING 4
#define TCP_STATE_CONNECTED 5
struct _tcp_instance {
int fd;
char *host;
int port;
int state;
unsigned long address;
};
#endif /* _TCP0_H */
......@@ -44,6 +44,7 @@ struct _mapfile_stream
int flags;
char *ptr;
size_t size;
char* filename;
};
static void
......@@ -57,6 +58,7 @@ _mapfile_destroy (stream_t stream)
munmap (mfs->ptr, mfs->size);
close (mfs->fd);
}
free (mfs->filename);
free (mfs);
}
......@@ -259,13 +261,15 @@ _mapfile_close (stream_t stream)
}
static int
_mapfile_open (stream_t stream, const char *filename, int port, int flags)
_mapfile_open (stream_t stream)
{
struct _mapfile_stream *mfs = stream_get_owner (stream);
int mflag, flg;
struct stat st;
char* filename = mfs->filename;
int flags;
(void)port; /* Ignored. */
stream_get_flags (stream, &flags);
/* Close any previous file. */
if (mfs->ptr != MAP_FAILED)
......@@ -331,7 +335,7 @@ _mapfile_open (stream_t stream, const char *filename, int port, int flags)
#endif /* _POSIX_MAPPED_FILES */
int
mapfile_stream_create (stream_t *stream)
mapfile_stream_create (stream_t *stream, const char* filename, int flags)
{
#ifndef _POSIX_MAPPED_FILES
return ENOSYS;
......@@ -339,19 +343,27 @@ mapfile_stream_create (stream_t *stream)
struct _mapfile_stream *fs;
int ret;
if (stream == NULL)
if (stream == NULL || filename == NULL)
return EINVAL;
fs = calloc (1, sizeof (struct _mapfile_stream));
if (fs == NULL)
return ENOMEM;
fs->filename = strdup (filename);
if (!fs->filename)
{
free (fs);
return ENOMEM;
}
fs->fd = -1;
fs->ptr = MAP_FAILED;
ret = stream_create (stream, MU_STREAM_NO_CHECK, fs);
ret = stream_create (stream, flags | MU_STREAM_NO_CHECK, fs);
if (ret != 0)
{
free (fs->filename);
free (fs);
return ret;
}
......
......@@ -345,34 +345,34 @@ mbox_open (mailbox_t mailbox, int flags)
/* Try to mmap () the file first. */
if (status == 0)
{
status = mapfile_stream_create (&(mailbox->stream));
status = mapfile_stream_create (&mailbox->stream, mud->name, mailbox->flags);
if (status == 0)
{
status = stream_open (mailbox->stream, mud->name, 0,
mailbox->flags);
if (status != 0)
stream_destroy (&mailbox->stream, NULL);
status = stream_open (mailbox->stream);
}
}
/* Fall back to normal file if mmap() failed. */
if (status != 0)
{
status = file_stream_create (&(mailbox->stream));
status = file_stream_create (&mailbox->stream, mud->name, mailbox->flags);
if (status != 0)
return status;
status = stream_open (mailbox->stream, mud->name, 0, mailbox->flags);
status = stream_open (mailbox->stream);
}
/* All failed, bail out. */
if (status != 0)
{
stream_destroy (&mailbox->stream, NULL);
return status;
}
/* Even on top, of normal FILE *, lets agressively cache. But this
may not be suitable for system tight on memory. */
stream_setbufsiz (mailbox->stream, BUFSIZ);
}
else
{
status = stream_open (mailbox->stream, mud->name, 0, mailbox->flags);
status = stream_open (mailbox->stream);
if (status != 0)
return status;
}
......
......@@ -1164,18 +1164,25 @@ mh_message_stream_open (struct _mh_message *mhm)
char *filename = NULL;
int status;
if (file_stream_create (&mhm->stream))
return errno;
filename = _mh_message_name (mhm, mhm->deleted);
if (!filename)
return ENOMEM;
status = stream_open (mhm->stream, filename, 0, mhd->mailbox->flags);
status = file_stream_create (&mhm->stream, filename, mhd->mailbox->flags);
free (filename);
if (status != 0)
return status;
status = stream_open (mhm->stream);
if (status != 0)
{
stream_destroy (&mhm->stream, NULL);
}
if (status == 0)
status = mh_scan_message (mhm);
......
......@@ -587,7 +587,7 @@ pop_open (mailbox_t mbox, int flags)
/* Create the networking stack. */
if (mbox->stream == NULL)
{
status = tcp_stream_create (&(mbox->stream));
status = tcp_stream_create (&mbox->stream, host, port, mbox->flags);
CHECK_ERROR(mpd, status);
/* Using the awkward stream_t buffering. */
stream_setbufsiz (mbox->stream, BUFSIZ);
......@@ -610,7 +610,7 @@ pop_open (mailbox_t mbox, int flags)
case POP_OPEN_CONNECTION:
/* Establish the connection. */
MAILBOX_DEBUG2 (mbox, MU_DEBUG_PROT, "open (%s:%d)\n", host, port);
status = stream_open (mbox->stream, host, port, mbox->flags);
status = stream_open (mbox->stream);
CHECK_EAGAIN (mpd, status);
/* Can't recover bailout. */
CHECK_ERROR_CLOSE (mbox, mpd, status);
......
......@@ -37,6 +37,7 @@
struct _memory_stream
{
char *filename;
char *ptr;
size_t size;
size_t capacity;
......@@ -48,6 +49,8 @@ _memory_destroy (stream_t stream)
struct _memory_stream *mfs = stream_get_owner (stream);
if (mfs && mfs->ptr != NULL)
free (mfs->ptr);
if(mfs->filename)
free (mfs->filename);
free (mfs);
}
......@@ -160,26 +163,23 @@ _memory_close (stream_t stream)
}
static int
_memory_open (stream_t stream, const char *filename, int port, int flags)
_memory_open (stream_t stream)
{
struct _memory_stream *mfs = stream_get_owner (stream);
int status = 0;
(void)port; /* Ignored. */
(void)filename; /* Ignored. */
(void)flags; /* Ignored. */
/* Close any previous file. */
if (mfs->ptr)
free (mfs->ptr);
mfs->ptr = NULL;
mfs->size = 0;
mfs->capacity = 0;
stream_set_flags (stream, flags |MU_STREAM_NO_CHECK);
if (filename)
/* Initialize the data with file contents, if a filename was provided. */
if (mfs->filename)
{
struct stat statbuf;
if (stat (filename, &statbuf) == 0)
if (stat (mfs->filename, &statbuf) == 0)
{
mfs->ptr = calloc (statbuf.st_size, 1);
if (mfs->ptr)
......@@ -187,7 +187,7 @@ _memory_open (stream_t stream, const char *filename, int port, int flags)
FILE *fp;
mfs->capacity = statbuf.st_size;
mfs->size = statbuf.st_size;
fp = fopen (filename, "r");
fp = fopen (mfs->filename, "r");
if (fp)
{
size_t r = fread (mfs->ptr, mfs->size, 1, fp);
......@@ -215,7 +215,7 @@ _memory_open (stream_t stream, const char *filename, int port, int flags)
}
int
memory_stream_create (stream_t *stream)
memory_stream_create (stream_t * stream, const char *filename, int flags)
{
struct _memory_stream *mfs;
int ret;
......@@ -224,16 +224,29 @@ memory_stream_create (stream_t *stream)
return EINVAL;
mfs = calloc (1, sizeof (*mfs));
if (mfs == NULL)
return ENOMEM;
if (filename)
{
mfs->filename = strdup (filename);
if (!mfs->filename)
{
free (mfs);
return ENOMEM;
}
}
mfs->ptr = NULL;
mfs->size = 0;
ret = stream_create (stream, MU_STREAM_NO_CHECK, mfs);
ret = stream_create (stream, flags | MU_STREAM_NO_CHECK, mfs);
if (ret != 0)
{
free (mfs->filename);
free (mfs);
return ret;
}
......@@ -245,5 +258,6 @@ memory_stream_create (stream_t *stream)
stream_set_truncate (*stream, _memory_truncate, mfs);
stream_set_size (*stream, _memory_size, mfs);
stream_set_destroy (*stream, _memory_destroy, mfs);
return 0;
}
......
......@@ -302,7 +302,7 @@ smtp_open (mailer_t mailer, int flags)
/* Create a TCP stack if one is not given. */
if (mailer->stream == NULL)
{
status = tcp_stream_create (&(mailer->stream));
status = tcp_stream_create (&mailer->stream, smtp->mailhost, port, mailer->flags);
CHECK_ERROR (smtp, status);
stream_setbufsiz (mailer->stream, BUFSIZ);
}
......@@ -312,8 +312,7 @@ smtp_open (mailer_t mailer, int flags)
case SMTP_OPEN:
MAILER_DEBUG2 (mailer, MU_DEBUG_PROT, "smtp_open (%s:%d)\n",
smtp->mailhost, port);
status = stream_open (mailer->stream, smtp->mailhost, port,
mailer->flags);
status = stream_open (mailer->stream);
CHECK_EAGAIN (smtp, status);
smtp->state = SMTP_GREETINGS;
......
......@@ -71,8 +71,7 @@ stream_destroy (stream_t *pstream, void *owner)
stream_t stream = *pstream;
if ((stream->flags & MU_STREAM_NO_CHECK) || stream->owner == owner)
{
if (stream->_destroy)
stream->_destroy (stream);
stream_close(stream);
if (stream->rbuffer.base)
free (stream->rbuffer.base);
free (stream);
......@@ -88,14 +87,14 @@ stream_get_owner (stream_t stream)
}
int
stream_open (stream_t stream, const char *name, int port, int flags)
stream_open (stream_t stream)
{
if (stream == NULL)
return EINVAL;
stream->state = MU_STREAM_STATE_OPEN;
stream->flags |= flags;
if (stream->_open)
return stream->_open (stream, name, port, flags);
return stream->_open (stream);
return 0;
}
......@@ -424,7 +423,7 @@ stream_get_fd (stream_t stream, int *pfd)
int
stream_get_flags (stream_t stream, int *pfl)
{
if (stream == NULL && pfl == NULL )
if (stream == NULL || pfl == NULL )
return EINVAL;
*pfl = stream->flags;
return 0;
......@@ -509,7 +508,7 @@ stream_set_destroy (stream_t stream, void (*_destroy) (stream_t), void *owner)
int
stream_set_open (stream_t stream,
int (*_open) (stream_t, const char *, int, int), void *owner)
int (*_open) (stream_t), void *owner)
{
if (stream == NULL)
return EINVAL;
......
......@@ -32,7 +32,20 @@
#include <unistd.h>
#include <mailutils/stream.h>
#include <tcp0.h>
#define TCP_STATE_INIT 1
#define TCP_STATE_RESOLVE 2
#define TCP_STATE_RESOLVING 3
#define TCP_STATE_CONNECTING 4
#define TCP_STATE_CONNECTED 5
struct _tcp_instance {
int fd;
char *host;
int port;
int state;
unsigned long address;
};
/* On solaris inet_addr() return -1. */
#ifndef INADDR_NONE
......@@ -52,7 +65,7 @@ _tcp_close (stream_t stream)
}
static int
_tcp_open (stream_t stream, const char *host, int port, int flags)
_tcp_open (stream_t stream)
{
struct _tcp_instance *tcp = stream_get_owner (stream);
int flgs, ret;
......@@ -60,6 +73,11 @@ _tcp_open (stream_t stream, const char *host, int port, int flags)
struct sockaddr_in peer_addr;
struct hostent *phe;
struct sockaddr_in soc_addr;
char* host = tcp->host;
int port = tcp->port;
int flags;
stream_get_flags(stream, &flags);
if (tcp->state == TCP_STATE_INIT)
{
......@@ -197,11 +215,13 @@ _tcp_destroy (stream_t stream)
if (tcp->fd != -1)
close (tcp->fd);
if(tcp->host)
free (tcp->host);
free (tcp);
}
int
tcp_stream_create (stream_t * stream)
tcp_stream_create (stream_t * stream, const char* host, int port, int flags)
{
struct _tcp_instance *tcp;
int ret;
......@@ -209,17 +229,30 @@ tcp_stream_create (stream_t * stream)
if ((tcp = malloc (sizeof (*tcp))) == NULL)
return ENOMEM;
tcp->fd = -1;
tcp->host = NULL;
tcp->port = -1;
tcp->host = strdup (host);
if(!tcp->host)
{
free (tcp);
return ENOMEM;
}
tcp->port = port;
tcp->state = TCP_STATE_INIT;
if ((ret =
stream_create (stream, MU_STREAM_NO_CHECK | MU_STREAM_RDWR, tcp)) != 0)
if ((ret = stream_create (stream,
flags | MU_STREAM_NO_CHECK | MU_STREAM_RDWR, tcp)) != 0)
{
free (tcp->host);
free (tcp);
return ret;
}
stream_set_open (*stream, _tcp_open, tcp);
stream_set_close (*stream, _tcp_close, tcp);
stream_set_read (*stream, _tcp_read, tcp);
stream_set_write (*stream, _tcp_write, tcp);
stream_set_fd (*stream, _tcp_get_fd, tcp);
stream_set_destroy (*stream, _tcp_destroy, tcp);
return 0;
}
......