Commit bee00121 bee001217ceaed8c188f1048e20dcffbcea31cf2 by Alain Magloire

attribute.c auth.c body.c header.c io.c mailbox.c mbx_pop.c

 	mbx_unix.c mbx_unixscan.c message.c mime.c tcp.c transcode.c
 	include/private/attribute0.h include/private/io0.h
 	include/private/mailbox0.h include/private/tcp.h
 	include/public/attribute.h include/public/auth.h
 	include/public/io.h include/public/mailbox.h
 	include/public/message.h
added the first basic support for pop.
 	include/private/auth0.h

move the definition of auth_t struct here.
 	net.c include/private/net0.h include/public/net.h

Overhaul change of the net_t by D. I.
1 parent 4ccdee87
......@@ -23,26 +23,24 @@
#include <errno.h>
int
attribute_create (attribute_t *pattr, void *owner)
attribute_create (attribute_t *pattr)
{
attribute_t attr;
if (pattr == NULL || owner == NULL)
if (pattr == NULL)
return EINVAL;
attr = calloc (1, sizeof(*attr));
if (attr == NULL)
return ENOMEM;
attr->owner = owner;
*pattr = attr;
return 0;
}
void
attribute_destroy (attribute_t *pattr, void *owner)
attribute_destroy (attribute_t *pattr)
{
if (pattr && *pattr)
{
attribute_t attr = *pattr;
if (attr->owner == owner)
free (attr);
/* loose the link */
*pattr = NULL;
......@@ -254,12 +252,12 @@ attribute_copy (attribute_t dest, attribute_t src)
}
int
string_to_attribute (const char *buffer, attribute_t *pattr, void *owner)
string_to_attribute (const char *buffer, attribute_t *pattr)
{
char *sep;
const char *sep;
int status;
status = attribute_create (pattr, owner);
status = attribute_create (pattr);
if (status != 0)
return status;
......@@ -268,6 +266,10 @@ string_to_attribute (const char *buffer, attribute_t *pattr, void *owner)
{
sep = strchr(buffer, ':'); /* pass the ':' */
sep++;
}
else
sep = buffer;
while (*sep == ' ') sep++; /* glob spaces */
if (strchr (sep, 'R') != NULL || strchr (sep, 'r') != NULL)
attribute_set_read (*pattr);
......@@ -277,7 +279,6 @@ string_to_attribute (const char *buffer, attribute_t *pattr, void *owner)
attribute_set_answered (*pattr);
if (strchr (sep, 'F') != NULL || strchr (sep, 'f') != NULL)
attribute_set_flagged (*pattr);
}
return 0;
}
......
......@@ -15,7 +15,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <auth.h>
#include <auth0.h>
#include <cpystr.h>
#include <errno.h>
......@@ -23,14 +23,6 @@
#include <string.h>
#include <stdlib.h>
struct _auth
{
void *owner;
int (*_prologue) (auth_t);
int (*_authenticate) (auth_t);
int (*_epilogue) (auth_t);
};
int
auth_create (auth_t *pauth, void *owner)
{
......@@ -58,7 +50,8 @@ auth_destroy (auth_t *pauth, void *owner)
}
int
auth_set_authenticate (auth_t auth, int (*_authenticate)(auth_t),
auth_set_authenticate (auth_t auth,
int (*_authenticate)(auth_t, char **, char **),
void *owner)
{
if (auth == NULL)
......@@ -70,11 +63,11 @@ auth_set_authenticate (auth_t auth, int (*_authenticate)(auth_t),
}
int
auth_authenticate (auth_t auth)
auth_authenticate (auth_t auth, char **user, char **passwd)
{
if (auth == NULL || auth->_authenticate == NULL)
return EINVAL;
return auth->_authenticate (auth);
return auth->_authenticate (auth, user, passwd);
}
int
......@@ -91,7 +84,7 @@ auth_set_epilogue (auth_t auth, int (*_epilogue)(auth_t), void *owner)
int
auth_epilogue (auth_t auth)
{
if (auth == NULL && auth->_epilogue == NULL)
if (auth == NULL || auth->_epilogue == NULL)
return EINVAL;
return auth->_epilogue (auth);
}
......@@ -110,7 +103,7 @@ auth_set_prologue (auth_t auth, int (*_prologue)(auth_t), void *owner)
int
auth_prologue (auth_t auth)
{
if (auth == NULL && auth->_prologue == NULL)
if (auth == NULL || auth->_prologue == NULL)
return EINVAL;
return auth->_prologue (auth);
}
......
......@@ -82,7 +82,7 @@ body_get_stream (body_t body, stream_t *pstream)
/* lazy floating body it is created when
* doing the first body_write call
*/
status = stream_create (&stream, 0, body);
status = stream_create (&stream, MU_STREAM_RDWR, body);
if (status != 0)
return status;
stream_set_read (stream, body_read, body);
......
......@@ -68,7 +68,7 @@ header_create (header_t *ph, const char *blurb, size_t len, void *owner)
header_parse (h, (char *)blurb, len);
status = stream_create (&(h->stream), 0, h);
status = stream_create (&(h->stream), MU_STREAM_READ|MU_STREAM_WRITE, h);
if (status != 0)
return status;
......
......@@ -35,7 +35,6 @@ extern "C" {
struct _attribute
{
size_t flag;
void *owner;
};
#define MU_ATTRIBUTE_SEEN ((int)1)
......
......@@ -2,30 +2,25 @@
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
it under the terms of the GNU General Library Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
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.
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 _NET_H
#define _NET_H
#ifndef _AUTH0_H
#define _AUTH0_H
#include <auth.h>
#include <sys/types.h>
#include <io.h>
#ifdef _cplusplus
extern "C" {
#endif
#ifndef __P
#ifdef __STDC__
#define __P(args) args
......@@ -34,24 +29,21 @@ extern "C" {
#endif
#endif /*__P */
struct _net;
typedef struct _net *net_t;
extern int net_api_create __P((net_t *, net_t, const char *type));
extern int net_api_set_option __P((net_t net, const char *name, const char *value));
extern int net_api_destroy __P((net_t *));
#ifdef _cplusplus
extern "C" {
#endif
struct _netinstance;
typedef struct _netinstance *netinstance_t;
struct _auth
{
void *owner;
int (*_prologue) (auth_t);
int (*_authenticate) (auth_t, char **user, char **passwd);
int (*_epilogue) (auth_t);
};
extern int net_new __P((net_t, netinstance_t *));
extern int net_connect __P((netinstance_t, const char *host, int port));
extern int net_get_stream __P((netinstance_t, stream_t *iostr));
extern int net_close __P((netinstance_t));
extern int net_free __P((netinstance_t *));
#ifdef _cplusplus
}
#endif
#endif /* NET_H */
#endif /* _AUTH0_H */
......
......@@ -36,7 +36,9 @@ struct _stream
{
void *owner;
int flags;
void (*_destroy) __P ((void *));
void (*_destroy) __P ((stream_t));
int (*_open) __P ((stream_t, const char *, int port, int flags));
int (*_close) __P ((stream_t));
int (*_get_fd) __P ((stream_t, int *));
int (*_read) __P ((stream_t, char *, size_t, off_t, size_t *));
int (*_write) __P ((stream_t, const char *, size_t, off_t, size_t *));
......
......@@ -42,7 +42,7 @@ struct _mailbox
char *name;
auth_t auth;
locker_t locker;
netinstance_t netinstance;
stream_t stream;
url_t url;
/* register events */
......
/* 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 _NET0_H
#define _NET0_H
#include <sys/types.h>
#include <io.h>
#include <net.h>
#ifdef _cplusplus
extern "C" {
#endif
#ifndef __P
#ifdef __STDC__
#define __P(args) args
#else
#define __P(args) ()
#endif
#endif /*__P */
struct _net_api {
int (*new)(void *netdata, net_t parent, void **data);
int (*connect)(void *data, const char *host, int port);
int (*get_stream)(void *data, stream_t *iostr);
int (*close)(void *data);
int (*free)(void **data);
};
struct _netregistrar {
const char *type;
int (*create)(void **netdata, struct _net_api **api);
int (*set_option)(void *netdata, const char *name, const char *value);
int (*destroy)(void **netdata);
};
struct _net {
struct _net_api *api;
void *data;
struct _net *parent;
struct _netregistrar *net_reg;
};
struct _netinstance {
struct _net_api *api;
void *data;
};
int _tcp_create(void **data, struct _net_api **api);
int _tcp_set_option(void *data, const char *name, const char *value);
int _tcp_destroy(void **data);
#ifdef _cplusplus
}
#endif
#endif /* NET0_H */
......@@ -15,25 +15,16 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <net0.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_options {
int non_block;
int net_timeout;
};
struct _tcp_instance {
struct _tcp_options *options;
int fd;
char *host;
int port;
int state;
stream_t stream;
unsigned long address;
};
......
......@@ -35,8 +35,8 @@ extern "C" {
struct _attribute;
typedef struct _attribute * attribute_t;
extern int attribute_create __P ((attribute_t *, void *owner));
extern void attribute_destroy __P ((attribute_t *, void *owner));
extern int attribute_create __P ((attribute_t *));
extern void attribute_destroy __P ((attribute_t *));
extern int attribute_is_seen __P ((attribute_t));
extern int attribute_is_answered __P ((attribute_t));
......@@ -68,10 +68,10 @@ extern int attribute_copy __P ((attribute_t dst,
attribute_t src));
extern int string_to_attribute __P ((const char *buf,
attribute_t *pattr, void *owner));
attribute_t *pattr));
extern int attribute_to_string __P ((attribute_t attr, char *buf,
size_t len, size_t *));
extern int attribute_get_owner __P ((attribute_t attr, void **owner));
#ifdef __cplusplus
}
#endif
......
......@@ -44,9 +44,10 @@ extern int auth_set_prologue __P ((auth_t auth,
int (*_prologue) __P ((auth_t)),
void *owner));
extern int auth_authenticate __P ((auth_t));
extern int auth_authenticate __P ((auth_t, char **, char **));
extern int auth_set_authenticate __P ((auth_t auth,
int (*_authenticate) __P ((auth_t)),
int (*_authenticate)
__P ((auth_t, char **, char **)),
void *owner));
extern int auth_epilogue __P ((auth_t));
......
......@@ -36,32 +36,58 @@ struct _stream;
typedef struct _stream *stream_t;
/* stream will be destroy on stream_destroy */
#define MU_STREAM_NO_CHECK 1
#define MU_STREAM_READ 0x00000001
#define MU_STREAM_WRITE 0x00000002
#define MU_STREAM_RDWR 0x00000004
#define MU_STREAM_APPEND 0x00000008
#define MU_STREAM_CREAT 0x00000010
#define MU_STREAM_NONBLOCK 0x00000020
#define MU_STREAM_NO_CHECK 0x00000040
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 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_set_destroy __P ((stream_t,
void (*_destroy) __P ((void *)),
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_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_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_get_fd __P ((stream_t , int *));
extern int stream_read __P ((stream_t, char *, size_t, off_t, size_t *));
extern int stream_write __P ((stream_t, const char *, size_t,
off_t, size_t *));
extern int stream_get_flags __P ((stream_t , int *flags));
/* misc */
extern int file_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 int tcp_stream_create __P ((stream_t *stream));
#ifdef __cplusplus
}
......
......@@ -23,7 +23,7 @@
#include <attribute.h>
#include <auth.h>
#include <locker.h>
#include <net.h>
#include <io.h>
#include <sys/types.h>
......@@ -48,12 +48,12 @@ extern int mailbox_create __P ((mailbox_t *, const char *, int id));
extern void mailbox_destroy __P ((mailbox_t *));
/* flags for mailbox_open () */
#define MU_MAILBOX_RDONLY ((int)1)
#define MU_MAILBOX_WRONLY (MU_MAILBOX_RDONLY << 1)
#define MU_MAILBOX_RDWR (MU_MAILBOX_WRONLY << 1)
#define MU_MAILBOX_APPEND (MU_MAILBOX_RDWR << 1)
#define MU_MAILBOX_CREAT (MU_MAILBOX_APPEND << 1)
#define MU_MAILBOX_NONBLOCK (MU_MAILBOX_CREAT << 1)
#define MU_MAILBOX_RDONLY MU_STREAM_READ
#define MU_MAILBOX_WRONLY MU_STREAM_WRITE
#define MU_MAILBOX_RDWR MU_STREAM_RDWR
#define MU_MAILBOX_APPEND MU_STREAM_APPEND
#define MU_MAILBOX_CREAT MU_STREAM_CREAT
#define MU_MAILBOX_NONBLOCK MU_STREAM_NONBLOCK
extern int mailbox_open __P ((mailbox_t, int flag));
extern int mailbox_close __P ((mailbox_t));
......@@ -64,9 +64,9 @@ extern int mailbox_append_message __P ((mailbox_t, message_t msg));
extern int mailbox_messages_count __P ((mailbox_t, size_t *num));
extern int mailbox_expunge __P ((mailbox_t));
/* netinstance settings */
extern int mailbox_get_netinstance __P ((mailbox_t, netinstance_t *net));
extern int mailbox_set_netinstance __P ((mailbox_t, netinstance_t net));
/* stream settings */
extern int mailbox_get_stream __P ((mailbox_t, stream_t *pstream));
extern int mailbox_set_stream __P ((mailbox_t, stream_t stream));
/* Lock settings */
extern int mailbox_get_locker __P ((mailbox_t, locker_t *locker));
......
......@@ -80,14 +80,25 @@ extern int message_set_received __P ((message_t,
extern int message_get_attribute __P ((message_t, attribute_t *));
extern int message_set_attribute __P ((message_t, attribute_t, void *owner));
//extern int message_clone __P ((message_t));
/* events */
#define MU_EVT_MSG_DESTROY 32
extern int message_register __P ((message_t msg, size_t type,
int (*action) (size_t typ, void *arg),
void *arg));
extern int message_deregister __P ((message_t msg, void *action));
/* misc functions */
extern int message_create_attachment __P ((const char *content_type,
const char *encoding,
const char *filename,
message_t *newmsg));
extern int message_save_attachment __P ((message_t msg,
const char *filename, void **data));
extern int message_encapsulate __P ((message_t msg, message_t *newmsg,
void **data));
extern int message_unencapsulate __P ((message_t msg, message_t *newmsg,
void **data));
#ifdef _cplusplus
}
#endif
......
......@@ -42,18 +42,17 @@ stream_destroy (stream_t *pstream, void *owner)
if (pstream && *pstream)
{
stream_t stream = *pstream;
if (!(stream->flags & MU_STREAM_NO_CHECK) && stream->owner != owner)
return;
if (stream->_destroy)
stream->_destroy (owner);
if ((stream->flags & MU_STREAM_NO_CHECK) || stream->owner == owner)
stream->_destroy (stream);
free (stream);
*pstream = NULL;
}
}
int
stream_set_destroy (stream_t stream, void (*_destroy) (void *),
void *owner)
stream_set_destroy (stream_t stream, void (*_destroy) (stream_t), void *owner)
{
if (stream == NULL)
return EINVAL;
......@@ -66,6 +65,53 @@ stream_set_destroy (stream_t stream, void (*_destroy) (void *),
}
int
stream_open (stream_t stream, const char *name, int port, int flags)
{
if (stream == NULL)
return EINVAL;
if (stream->_open)
return stream->_open (stream, name, port, flags);
return 0;
}
int
stream_set_open (stream_t stream,
int (*_open) (stream_t, const char *, int, int), void *owner)
{
if (stream == NULL)
return EINVAL;
if (owner == stream->owner)
{
stream->_open = _open;
return 0;
}
return EACCES;
}
int
stream_close (stream_t stream)
{
if (stream == NULL)
return EINVAL;
if (stream->_close)
return stream->_close (stream);
return 0;
}
int
stream_set_close (stream_t stream, int (*_close) (stream_t), void *owner)
{
if (stream == NULL)
return EINVAL;
if (owner == stream->owner)
{
stream->_close = _close;
return 0;
}
return EACCES;
}
int
stream_set_fd (stream_t stream, int (*_get_fd) (stream_t, int *), void *owner)
{
if (stream == NULL)
......@@ -85,7 +131,9 @@ stream_set_read (stream_t stream, int (*_read)
{
if (stream == NULL)
return EINVAL;
if (owner == stream->owner)
if (owner == stream->owner &&
((stream->flags & MU_STREAM_READ) ||
(stream->flags & MU_STREAM_RDWR)))
{
stream->_read = _read;
return 0;
......@@ -100,7 +148,10 @@ stream_set_write (stream_t stream, int (*_write)
{
if (stream == NULL)
return EINVAL;
if (stream->owner == owner)
if (stream->owner == owner &&
((stream->flags & MU_STREAM_WRITE) ||
(stream->flags & MU_STREAM_RDWR) ||
(stream->flags & MU_STREAM_APPEND)))
{
stream->_write = _write;
return 0;
......@@ -133,3 +184,12 @@ stream_get_fd (stream_t stream, int *pfd)
return EINVAL;
return stream->_get_fd (stream, pfd);
}
int
stream_get_flags (stream_t stream, int *pfl)
{
if (stream == NULL && pfl == NULL )
return EINVAL;
*pfl = stream->flags;
return 0;
}
......
......@@ -23,7 +23,6 @@
#include <message0.h>
#include <registrar.h>
#include <locker.h>
#include <net.h>
#include <stdlib.h>
#include <string.h>
......@@ -163,11 +162,12 @@ mailbox_set_locker (mailbox_t mbox, locker_t locker)
}
int
mailbox_get_locker (mailbox_t mbox, locker_t *locker)
mailbox_get_locker (mailbox_t mbox, locker_t *plocker)
{
if (mbox == NULL || locker == NULL)
if (mbox == NULL || plocker == NULL)
return EINVAL;
*locker = mbox->locker;
if (plocker)
*plocker = mbox->locker;
return 0;
}
......@@ -185,25 +185,27 @@ mailbox_get_auth (mailbox_t mbox, auth_t *pauth)
{
if (mbox == NULL || pauth == NULL)
return EINVAL;
if (pauth)
*pauth = mbox->auth;
return 0;
}
int
mailbox_set_netinstance (mailbox_t mbox, netinstance_t netinstance)
mailbox_set_stream (mailbox_t mbox, stream_t stream)
{
if (mbox == NULL)
return EINVAL;
mbox->netinstance = netinstance;
mbox->stream = stream;
return 0;
}
int
mailbox_get_netinstance (mailbox_t mbox, netinstance_t *pnetinstance)
mailbox_get_stream (mailbox_t mbox, stream_t *pstream)
{
if (mbox == NULL || pnetinstance == NULL)
if (mbox == NULL || pstream == NULL)
return EINVAL;
*pnetinstance = mbox->netinstance;
if (pstream)
*pstream = mbox->stream;
return 0;
}
......
......@@ -313,8 +313,8 @@ mailbox_unix_destroy (mailbox_t *pmbox)
continue;
/* Destroy the attach messages */
message_destroy (&(mum->message), mum);
attribute_destroy (&(mum->old_attr), mbox);
attribute_destroy (&(mum->new_attr), mbox);
attribute_destroy (&(mum->old_attr));
attribute_destroy (&(mum->new_attr));
free (mum);
}
free (mud->umessages);
......@@ -399,7 +399,11 @@ mailbox_unix_open (mailbox_t mbox, int flags)
/* Authentication */
if (mbox->auth)
{
int status = auth_authenticate (mbox->auth);
char *user = NULL;
char *passwd = NULL;
int status = auth_authenticate (mbox->auth, &user, &passwd);
free (user);
free (passwd);
if (status != 0)
return status;
}
......@@ -516,7 +520,7 @@ mailbox_unix_is_updated (mailbox_t mbox)
}
static int
mailbox_unix_num_deleted (mailbox_t mbox, size_t *num)
mailbox_unix_num_deleted (mailbox_t mbox, size_t *pnum)
{
mailbox_unix_data_t mud;
mailbox_unix_message_t mum;
......@@ -531,8 +535,8 @@ mailbox_unix_num_deleted (mailbox_t mbox, size_t *num)
total++;
}
if (num)
*num = total;
if (pnum)
*pnum = total;
return 0;
}
......@@ -894,7 +898,7 @@ mailbox_unix_getfd (stream_t is, int *pfd)
{
mailbox_unix_message_t mum;
if (is == NULL || (mum = (mailbox_unix_message_t)is->owner) == NULL)
if (is == NULL || (mum = is->owner) == NULL)
return EINVAL;
if (pfd)
*pfd = fileno (mum->file);
......@@ -908,7 +912,7 @@ mailbox_unix_readstream (stream_t is, char *buffer, size_t buflen,
mailbox_unix_message_t mum;
size_t nread = 0;
if (is == NULL || (mum = is->owner) == NULL)
if (is == NULL || (mum = (mailbox_unix_message_t)is->owner) == NULL)
return EINVAL;
if (buffer == NULL || buflen == 0)
......@@ -1169,7 +1173,7 @@ mailbox_unix_get_message (mailbox_t mbox, size_t msgno, message_t *pmsg)
}
message_set_body (msg, body, mum);
status = stream_create (&stream, 0, mum);
status = stream_create (&stream, MU_STREAM_READ, mum);
if (status != 0)
{
message_destroy (&msg, mum);
......
......@@ -254,7 +254,7 @@ do \
} while (0)
/* skip a function call, ?? do we gain that much */
#define ATTRIBUTE_CREATE(attr,own) \
#define ATTRIBUTE_CREATE(attr,mbox) \
do \
{ \
attr = calloc (1, sizeof(*(attr))); \
......@@ -265,7 +265,6 @@ do \
mailbox_unix_unlock (mbox); \
return ENOMEM; \
} \
(attr)->owner = own; \
} while (0)
/* allocate slots for the new messages */
......
......@@ -47,7 +47,7 @@ message_create (message_t *pmsg, void *owner)
msg = calloc (1, sizeof (*msg));
if (msg == NULL)
return ENOMEM;
status = stream_create (&stream, 0, msg);
status = stream_create (&stream, MU_STREAM_RDWR, msg);
if (status != 0)
{
free (msg);
......@@ -92,7 +92,7 @@ message_destroy (message_t *pmsg, void *owner)
/* header */
header_destroy (&header, owner);
/* attribute */
attribute_destroy (&attribute, owner);
attribute_destroy (&attribute);
/* stream */
stream_destroy (&stream, owner);
......@@ -188,7 +188,7 @@ message_get_stream (message_t msg, stream_t *pstream)
{
stream_t stream;
int status;
status = stream_create (&stream, 0, msg);
status = stream_create (&stream, MU_STREAM_RDWR, msg);
if (status != 0)
return status;
stream_set_read (stream, message_read, msg);
......@@ -350,7 +350,7 @@ message_get_attribute (message_t msg, attribute_t *pattribute)
if (msg->attribute == NULL && msg->owner == NULL)
{
attribute_t attribute;
int status = attribute_create (&attribute, msg);
int status = attribute_create (&attribute);
if (status != 0)
return status;
msg->attribute = attribute;
......@@ -366,7 +366,7 @@ message_set_attribute (message_t msg, attribute_t attribute, void *owner)
return EINVAL;
if (msg->owner != owner)
return EACCES;
attribute_destroy (&(msg->attribute), msg);
attribute_destroy (&(msg->attribute));
msg->attribute = attribute;
return 0;
}
......
......@@ -83,17 +83,6 @@ static int _mime_append_part(mime_t mime, message_t msg, int body_offset, int bo
return 0;
}
static struct _mime_part *_mime_get_owner(mime_t mime, message_t msg)
{
int i;
for ( i = 0; i < mime->nmtp_parts; i++ ) {
if ( mime->mtp_parts[i] == msg->owner )
return mime->mtp_parts[i];
}
return NULL;
}
static char *_strltrim(char *str)
{
char *p;
......@@ -119,7 +108,7 @@ char *_strtrim(char *str);
#define _ISSPECIAL(c) ( \
((c) == '(') || ((c) == ')') || ((c) == '<') || ((c) == '>') \
|| ((c) == '@') || ((c) == ',') || ((c) == ';') || ((c) == ':') \
|| ((c) == '\\') || ((c) == '"') || ((c) == '.') || ((c) == '[') \
|| ((c) == '\\') || ((c) == '.') || ((c) == '[') \
|| ((c) == ']') )
static void _mime_munge_content_header(char *field_body )
......@@ -129,8 +118,10 @@ static void _mime_munge_content_header(char *field_body )
_strtrim(field_body);
if ( ( e = p = strchr(str, ';') ) == NULL )
if ( ( e = strchr(str, ';') ) == NULL )
return;
while( *e == ';' ) {
p = e;
e++;
while ( *e && isspace(*e) ) /* remove space upto param */
e++;
......@@ -140,13 +131,14 @@ static void _mime_munge_content_header(char *field_body )
while ( *e && *e != '=' ) /* find end of value */
e++;
e = p = e+1;
while ( *e && (quoted || !_ISSPECIAL(*e) || !isspace(*e) ) ) {
while ( *e && (quoted || ( !_ISSPECIAL(*e) && !isspace(*e) ) ) ) {
if ( *e == '\\' ) { /* escaped */
memmove(e, e+1, strlen(e)+2);
} else if ( *e == '\"' )
quoted = ~quoted;
e++;
}
}
}
static char *_mime_get_param(char *field_body, const char *param, int *len)
......@@ -164,7 +156,7 @@ static char *_mime_get_param(char *field_body, const char *param, int *len)
break;
*len = 0;
v = e = v + 1;
while ( *e && (quoted || !_ISSPECIAL(*e) || !isspace(*e) ) ) { /* skip pass value and calc len */
while ( *e && (quoted || ( !_ISSPECIAL(*e) && !isspace(*e) ) ) ) { /* skip pass value and calc len */
if ( *e == '\"' )
quoted = ~quoted, was_quoted = 1;
else
......@@ -256,6 +248,8 @@ static int _mime_parse_mpart_message(mime_t mime)
_mime_append_part(mime, NULL, body_offset, body_length, FALSE );
if ( ( cp2 + blength + 2 < cp && !strncasecmp(cp2+2+blength, "--",2) ) ||
!strncasecmp(cp2+blength, "--",2) ) { /* very last boundary */
mime->parser_state = MIME_STATE_BEGIN_LINE;
mime->header_length = 0;
break;
}
mime->line_ndx = -1; /* headers parsing requires empty line */
......@@ -293,6 +287,8 @@ static int _mime_parse_mpart_message(mime_t mime)
mime->body_length = body_length;
mime->body_offset = body_offset;
if ( ret != EAGAIN ) { /* finished cleanup */
if ( mime->header_length ) /* this skips the preamble */
_mime_append_part(mime, NULL, body_offset, body_length, FALSE );
mime->flags &= ~MIME_PARSER_ACTIVE;
mime->body_offset = mime->body_length = mime->header_length = 0;
}
......@@ -365,7 +361,7 @@ int mime_create(mime_t *pmime, message_t msg, int flags)
}
}
else {
if ( ( ret = message_create( &msg, mime ) ) == 0 ) {
if ( ( ret = message_create( &(mime->msg), mime ) ) == 0 ) {
mime->flags |= MIME_NEW_MESSAGE;
}
}
......@@ -449,7 +445,7 @@ int mime_get_part(mime_t mime, int part, message_t *msg)
message_set_header(mime_part->msg, mime_part->hdr, mime_part);
header_size(mime_part->hdr, &hsize);
if ( ( ret = body_create(&body, mime_part) ) == 0 ) {
if ( ( ret = stream_create(&stream, 0, mime_part) ) == 0 ) {
if ( ( ret = stream_create(&stream, MU_STREAM_READ, mime_part) ) == 0 ) {
body_set_size (body, _mime_body_size, mime_part);
stream_set_read(stream, _mime_message_read, mime_part);
body_set_stream(body, stream, mime_part);
......@@ -464,82 +460,6 @@ int mime_get_part(mime_t mime, int part, message_t *msg)
return ret;
}
int mime_unencapsulate(mime_t mime, message_t msg, message_t *newmsg)
{
size_t size, nbytes;
int ret, body_offset = 0, body_length = 0, done = 0;
char *content_type, *cp;
header_t hdr;
stream_t stream;
body_t body;
struct _mime_part *mime_part;
if ( mime == NULL || msg == NULL || newmsg == NULL || mime->flags & MIME_NEW_MESSAGE )
return EINVAL;
if ( mime->msg != msg && ( mime_part = _mime_get_owner( mime, msg ) ) == NULL ) /* I don't know about or own this message */
return EPERM;
if ( ( ret = message_get_header(msg, &hdr) ) == 0 ) {
if ( ( ret = header_get_value(hdr, "Content-Type", NULL, 0, &size) ) == 0 && size ) {
if ( ( content_type = malloc(size+1) ) == NULL )
ret = ENOMEM;
else if ( ( ret = header_get_value(hdr, "Content-Type", content_type, size+1, 0) ) == 0 ) {
_mime_munge_content_header(content_type);
if ( strncasecmp(content_type, "message/rfc822", strlen(content_type)) != 0 )
ret = EINVAL;
else {
if ( mime_part ) {
body_offset = mime_part->body_offset;
body_length = mime_part->body_len;
}
if ( ( ret = _mime_setup_buffers(mime) ) == 0 ) {
mime->line_ndx = 0;
mime->cur_offset = body_offset;
while ( !done && ( ret = stream_read(mime->stream, mime->cur_buf, mime->buf_size, mime->cur_offset, &nbytes) ) == 0 && nbytes ) {
cp = mime->cur_buf;
while ( nbytes ) {
mime->cur_line[mime->line_ndx] = *cp;
mime->line_ndx++;
if ( *cp == '\n' ) {
_mime_append_header_line(mime);
if ( mime->line_ndx == 1 ) {
done = 1;
break;
}
mime->line_ndx = 0;
}
mime->cur_offset++;
nbytes--;
cp++;
}
}
body_length -= mime->cur_offset - body_offset;
body_offset = mime->cur_offset + 1;
if ( ( ret = _mime_append_part( mime, NULL, body_offset, body_length, TRUE ) ) == 0 ) {
mime_part = mime->cap_msgs[mime->ncap_msgs - 1];
if ( ( ret = message_create(&(mime_part->msg), mime_part) ) == 0) {
message_set_header(mime_part->msg, mime_part->hdr, mime_part);
if ( ( ret = body_create(&body, mime_part) ) == 0 ) {
if ( ( ret = stream_create(&stream, 0, mime_part) ) == 0 ) {
stream_set_read(stream, _mime_message_read, mime_part);
body_set_size (body, _mime_body_size, mime_part);
body_set_stream( body, stream, mime_part);
*newmsg = mime_part->msg;
return 0;
}
message_destroy(&mime_part->msg, mime_part);
}
}
}
}
}
}
}
}
return ret;
}
int mime_get_num_parts(mime_t mime, int *nmtp_parts)
{
int ret = 0;
......
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU 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. */
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <net0.h>
static struct _netregistrar _netreg[1] = { "tcp", _tcp_create, _tcp_set_option, _tcp_destroy };
int net_api_create(net_t *net, net_t parent, const char *type)
{
net_t n;
int i, napis, ret = 0;
if ( net == NULL || type == NULL )
return EINVAL;
*net = NULL;
if ( ( n = calloc(1, sizeof(*n)) ) == NULL )
return ENOMEM;
napis = sizeof(_netreg) / sizeof(_netreg[0]);
for( i = 0; i < napis; i++ ) {
if ( strcasecmp(_netreg[i].type, type) == 0 )
break;
}
if ( i == napis )
return ENOTSUP;
if ( (ret = ( _netreg[i].create(&(n->data), &(n->api)) )) != 0 )
free(n);
n->parent = parent;
n->net_reg = &_netreg[i];
*net = n;
return 0;
}
int net_api_set_option(net_t net, const char *name, const char *value)
{
if ( net && name && value )
return net->net_reg->set_option(net->data, name, value);
return EINVAL;
}
int net_api_destroy(net_t *net)
{
net_t n;
if ( net == NULL || *net == NULL )
return EINVAL;
n = *net;
n->net_reg->destroy(&n->data);
free(n);
*net = NULL;
return 0;
}
int net_new(net_t net, netinstance_t *inst)
{
netinstance_t netinst;
int ret = 0;
if ( net == NULL || inst == NULL )
return EINVAL;
*inst = NULL;
if ( ( netinst = calloc(1, sizeof(*netinst)) ) == NULL )
return ENOMEM;
netinst->api = net->api;
if ( ( ret = net->api->new(net->data, net->parent, &(netinst->data)) ) != 0 ) {
free(netinst);
return ret;
}
*inst = netinst;
return 0;
}
int net_connect(netinstance_t inst, const char *host, int port)
{
if ( inst == NULL || host == NULL )
return EINVAL;
return inst->api->connect(inst->data, host, port);
}
int net_get_stream(netinstance_t inst, stream_t *iostr)
{
if ( inst == NULL || iostr == NULL )
return EINVAL;
return inst->api->get_stream(inst->data, iostr);
}
int net_close(netinstance_t inst)
{
if ( inst == NULL )
return EINVAL;
return inst->api->close(inst->data);
}
int net_free(netinstance_t *pinst)
{
int ret;
netinstance_t inst;
if ( pinst == NULL || *pinst == NULL )
return EINVAL;
inst = *pinst;
ret = inst->api->free(&(inst->data));
free(inst);
*pinst = NULL;
return ret;
}
......@@ -26,30 +26,46 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net0.h>
#include <io0.h>
#include <tcp.h>
static int _tcp_close(void *data);
static int _tcp_close(stream_t stream)
{
struct _tcp_instance *tcp = stream->owner;
static int _tcp_doconnect(struct _tcp_instance *tcp)
if ( tcp->fd != -1 )
close(tcp->fd);
tcp->fd = -1;
tcp->state = TCP_STATE_INIT;
return 0;
}
static int _tcp_open(stream_t stream, const char *host, int port, int flags)
{
struct _tcp_instance *tcp = stream->owner;
int flgs, ret;
size_t namelen;
struct sockaddr_in peer_addr;
struct hostent *phe;
struct sockaddr_in soc_addr;
if ( tcp->state == TCP_STATE_INIT ) {
tcp->port = port;
if ( ( tcp->host = strdup(host) ) == NULL )
return ENOMEM;
}
switch( tcp->state ) {
case TCP_STATE_INIT:
if ( tcp->fd == -1 ) {
if ( ( tcp->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
return errno;
}
if ( tcp->options->non_block ) {
if ( flags & MU_STREAM_NONBLOCK ) {
flgs = fcntl(tcp->fd, F_GETFL);
flgs |= O_NONBLOCK;
fcntl(tcp->fd, F_SETFL, flgs);
stream->flags |= MU_STREAM_NONBLOCK;
}
tcp->state = TCP_STATE_RESOLVING;
case TCP_STATE_RESOLVING:
......@@ -59,7 +75,7 @@ static int _tcp_doconnect(struct _tcp_instance *tcp)
if (tcp->address == INADDR_NONE) {
phe = gethostbyname(tcp->host);
if ( !phe ) {
_tcp_close(tcp);
_tcp_close(stream);
return EINVAL;
}
tcp->address = *(((unsigned long **)phe->h_addr_list)[0]);
......@@ -77,7 +93,7 @@ static int _tcp_doconnect(struct _tcp_instance *tcp)
tcp->state = TCP_STATE_CONNECTING;
ret = EAGAIN;
} else
_tcp_close(tcp);
_tcp_close(stream);
return ret;
}
tcp->state = TCP_STATE_CONNECTING;
......@@ -87,7 +103,7 @@ static int _tcp_doconnect(struct _tcp_instance *tcp)
tcp->state = TCP_STATE_CONNECTED;
else {
ret = errno;
_tcp_close(tcp);
_tcp_close(stream);
return ret;
}
break;
......@@ -95,17 +111,14 @@ static int _tcp_doconnect(struct _tcp_instance *tcp)
return 0;
}
static int _tcp_get_fd(stream_t stream, int *fd)
{
struct _tcp_instance *tcp = stream->owner;
if ( fd == NULL )
if ( fd == NULL || tcp->fd == EINVAL )
return EINVAL;
if ( tcp->fd == -1 ) {
if ( ( tcp->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
return errno;
}
*fd = tcp->fd;
return 0;
}
......@@ -113,152 +126,67 @@ static int _tcp_get_fd(stream_t stream, int *fd)
static int _tcp_read(stream_t stream, char *buf, size_t buf_size, off_t offset, size_t *br)
{
struct _tcp_instance *tcp = stream->owner;
int bytes;
offset;
offset = offset;
if ( br == NULL )
return EINVAL;
*br = 0;
if ( ( *br = recv(tcp->fd, buf, buf_size, 0) ) == -1 ) {
if ( ( bytes = recv(tcp->fd, buf, buf_size, 0) ) == -1 ) {
*br = 0;
return errno;
}
*br = bytes;
return 0;
}
static int _tcp_write(stream_t stream, const char *buf, size_t buf_size, off_t offset, size_t *bw)
{
struct _tcp_instance *tcp = stream->owner;
int bytes;
offset;
offset = offset;
if ( bw == NULL )
return EINVAL;
*bw = 0;
if ( ( *bw = send(tcp->fd, buf, buf_size, 0) ) == -1 ) {
if ( ( bytes = send(tcp->fd, buf, buf_size, 0) ) == -1 ) {
*bw = 0;
return errno;
}
*bw = bytes;
return 0;
}
static int _tcp_new(void *netdata, net_t parent, void **data)
{
struct _tcp_instance *tcp;
if ( parent ) /* tcp must be top level api */
return EINVAL;
if ( ( tcp = malloc(sizeof(*tcp)) ) == NULL )
return ENOMEM;
tcp->options = (struct _tcp_options *)netdata;
tcp->fd = -1;
tcp->host = NULL;
tcp->port = -1;
tcp->state = TCP_STATE_INIT;
stream_create(&tcp->stream, 0, tcp);
stream_set_read(tcp->stream, _tcp_read, tcp);
stream_set_write(tcp->stream, _tcp_write, tcp);
stream_set_fd(tcp->stream, _tcp_get_fd, tcp);
*data = tcp;
return 0;
}
static int _tcp_connect(void *data, const char *host, int port)
static void _tcp_destroy(stream_t stream)
{
struct _tcp_instance *tcp = data;
if ( tcp->state == TCP_STATE_INIT ) {
tcp->port = port;
if ( ( tcp->host = strdup(host) ) == NULL )
return ENOMEM;
}
if ( tcp->state < TCP_STATE_CONNECTED )
return _tcp_doconnect(tcp);
return 0;
}
static int _tcp_get_stream(void *data, stream_t *stream)
{
struct _tcp_instance *tcp = data;
*stream = tcp->stream;
return 0;
}
static int _tcp_close(void *data)
{
struct _tcp_instance *tcp = data;
if ( tcp->fd != -1 )
close(tcp->fd);
tcp->fd = -1;
tcp->state = TCP_STATE_INIT;
return 0;
}
static int _tcp_free(void **data)
{
struct _tcp_instance *tcp;
if ( data == NULL || *data == NULL )
return EINVAL;
tcp = *data;
struct _tcp_instance *tcp = stream->owner;
if ( tcp->host )
free(tcp->host);
if ( tcp->fd != -1 )
close(tcp->fd);
free(*data);
*data = NULL;
return 0;
free(tcp);
}
static struct _net_api _tcp_net_api = {
_tcp_new,
_tcp_connect,
_tcp_get_stream,
_tcp_close,
_tcp_free
};
int _tcp_create(void **netdata, struct _net_api **netapi)
int tcp_stream_create(stream_t *stream)
{
struct _tcp_options *options;
struct _tcp_instance *tcp;
int ret;
if ( ( options = malloc(sizeof(*options)) ) == NULL )
if ( ( tcp = malloc(sizeof(*tcp)) ) == NULL )
return ENOMEM;
options->non_block = 0;
options->net_timeout = -1; /* system default */
*netdata = options;
*netapi = &_tcp_net_api;
return 0;
}
int _tcp_set_option(void *netdata, const char *name, const char *value)
{
struct _tcp_options *options = netdata;
if ( strcasecmp(name, "tcp_non_block") == 0 ) {
if ( value[0] == 't' || value[0] == 'T' || value[0] == '1' || value[0] == 'y' || value[0] == 'Y')
options->non_block = 1;
else
options->non_block = 0;
}
else if ( strcasecmp(name, "tcp_timeout") == 0 )
options->net_timeout = atoi(value);
else
return EINVAL;
return 0;
}
int _tcp_destroy(void **netdata)
{
struct _tcp_options *options = *netdata;
free(options);
*netdata = NULL;
tcp->fd = -1;
tcp->host = NULL;
tcp->port = -1;
tcp->state = TCP_STATE_INIT;
if ( ( ret = stream_create(stream, MU_STREAM_NO_CHECK|MU_STREAM_RDWR, tcp) ) != 0 )
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;
}
......