diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-08-30 10:48:54 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-08-30 10:57:15 +0300 |
commit | a783f8c35ed0fc9a7a18dc82f43bbe34a37aae37 (patch) | |
tree | ae8201215126ac3b29abca8def32b4cc537afd40 | |
parent | 286657e78705d061fc68c000cd3823608c522c04 (diff) | |
download | mailutils-a783f8c35ed0fc9a7a18dc82f43bbe34a37aae37.tar.gz mailutils-a783f8c35ed0fc9a7a18dc82f43bbe34a37aae37.tar.bz2 |
Add a framework for printing I/O transcripts; modify pop3d to use it.
* include/mailutils/stream.h (MU_STREAM_RDTHRU)
(MU_STREAM_WRTHRU,MU_IOCTL_SET_TRANSPORT): New flags.
(mu_xscript_stream_create, mu_iostream_create)
(mu_dbgstream_create): New prototypes.
* include/mailutils/sys/dbgstream.h: New header.
* include/mailutils/sys/iostream.h: New header.
* include/mailutils/sys/xscript-stream.h: New header.
* include/mailutils/sys/Makefile.am (sysinclude_HEADERS): Add
dbgstream.h, iostream.h and xscript-stream.h
* mailbox/dbgstream.c: New file.
* mailbox/iostream.c: New file.
* mailbox/xscript-stream.c: New file.
* mailbox/Makefile.am (libmailutils_la_SOURCES): Add dbgstream.c,
iostream.c and xscript-stream.c
* mailbox/filter_iconv.c (_icvt_ioctl): Simplify the declaration
of ptrans.
* mailbox/mapfile_stream.c (_mapfile_ioctl): Likewise.
* mailbox/memory_stream.c (_memory_ioctl): Likewise.
* mailbox/prog_stream.c (_prog_ioctl): Likewise.
* mailbox/tcp.c (_tcp_ioctl): Likewise.
* mailbox/fltstream.c (filter_ctl): Likewise.
(filter_read_through, filter_write_through): New methods.
(mu_filter_stream_create): Allow for use of MU_STREAM_RDTHRU
and MU_STREAM_WRTHRU to create two-way filters (writing
triggers filtering while reading is transparent or vice versa).
* pop3d/extra.c (istream, ostream): Remove globals.
(iostream): New variable.
(real_istream, real_ostream): New variables.
(pop3d_setio): Set transcript stream on top of the I/O one,
if required.
(pop3d_init_tls_server): Rewrite. Revert the meaning of the
return code to match the usual convention (0 - success).
(transcript): Removed.
(pop3d_outf): Remove calls to transcript.
* pop3d/pop3d.h (istream, ostream): Remove externs.
(iostream): New extern.
* pop3d/retr.c: Use iostream, instear of ostream.
* pop3d/top.c: Likewise.
* pop3d/stls.c: Update the call to pop3d_init_tls_server.
* mailbox/stream_vprintf.c (mu_stream_vprintf): Fix return
value to match the usual convention.
-rw-r--r-- | include/mailutils/stream.h | 12 | ||||
-rw-r--r-- | include/mailutils/sys/Makefile.am | 5 | ||||
-rw-r--r-- | include/mailutils/sys/dbgstream.h | 31 | ||||
-rw-r--r-- | include/mailutils/sys/iostream.h | 34 | ||||
-rw-r--r-- | include/mailutils/sys/xscript-stream.h | 33 | ||||
-rw-r--r-- | mailbox/Makefile.am | 5 | ||||
-rw-r--r-- | mailbox/dbgstream.c | 86 | ||||
-rw-r--r-- | mailbox/file_stream.c | 6 | ||||
-rw-r--r-- | mailbox/filter_iconv.c | 6 | ||||
-rw-r--r-- | mailbox/fltstream.c | 45 | ||||
-rw-r--r-- | mailbox/iostream.c | 249 | ||||
-rw-r--r-- | mailbox/mapfile_stream.c | 6 | ||||
-rw-r--r-- | mailbox/memory_stream.c | 6 | ||||
-rw-r--r-- | mailbox/prog_stream.c | 6 | ||||
-rw-r--r-- | mailbox/stream_vprintf.c | 2 | ||||
-rw-r--r-- | mailbox/tcp.c | 6 | ||||
-rw-r--r-- | mailbox/xscript-stream.c | 300 | ||||
-rw-r--r-- | pop3d/extra.c | 111 | ||||
-rw-r--r-- | pop3d/pop3d.h | 2 | ||||
-rw-r--r-- | pop3d/retr.c | 2 | ||||
-rw-r--r-- | pop3d/stls.c | 2 | ||||
-rw-r--r-- | pop3d/top.c | 2 |
22 files changed, 876 insertions, 81 deletions
diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h index 1aee88493..1b74651c7 100644 --- a/include/mailutils/stream.h +++ b/include/mailutils/stream.h @@ -47,6 +47,9 @@ enum mu_buffer_type /* FIXME: This one affects only mailboxes */ #define MU_STREAM_QACCESS 0x00000200 +#define MU_STREAM_RDTHRU 0x00000400 +#define MU_STREAM_WRTHRU 0x00000800 + #define MU_STREAM_IRGRP 0x00001000 #define MU_STREAM_IWGRP 0x00002000 #define MU_STREAM_IROTH 0x00004000 @@ -59,6 +62,7 @@ enum mu_buffer_type #define MU_IOCTL_SET_SEEK_LIMITS 4 #define MU_IOCTL_ABRIDGE_SEEK MU_IOCTL_SET_SEEK_LIMITS #define MU_IOCTL_GET_SEEK_LIMITS 5 +#define MU_IOCTL_SET_TRANSPORT 6 void mu_stream_ref (mu_stream_t stream); void mu_stream_unref (mu_stream_t stream); @@ -145,4 +149,12 @@ int mu_tcp_stream_create_with_source_host (mu_stream_t *stream, int mu_tcp_stream_create (mu_stream_t *stream, const char *host, int port, int flags); +int mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport, + mu_stream_t logstr, + const char *prefix[]); +int mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out, + int flags); +int mu_dbgstream_create(mu_stream_t *pref, mu_debug_t debug, + mu_log_level_t level, int flags); + #endif diff --git a/include/mailutils/sys/Makefile.am b/include/mailutils/sys/Makefile.am index 34f995b59..ce37112b0 100644 --- a/include/mailutils/sys/Makefile.am +++ b/include/mailutils/sys/Makefile.am @@ -19,10 +19,12 @@ sysincludedir=$(pkgincludedir)/sys sysinclude_HEADERS = \ + dbgstream.h\ file_stream.h\ filter.h\ header_stream.h\ header.h\ + iostream.h\ mapfile_stream.h\ memory_stream.h\ message_stream.h\ @@ -36,4 +38,5 @@ sysinclude_HEADERS = \ stream.h\ tls-stream.h\ pop3.h\ - nntp.h + nntp.h\ + xscript-stream.h diff --git a/include/mailutils/sys/dbgstream.h b/include/mailutils/sys/dbgstream.h new file mode 100644 index 000000000..6934372b6 --- /dev/null +++ b/include/mailutils/sys/dbgstream.h @@ -0,0 +1,31 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _MAILUTILS_SYS_DBGSTREAM_H +# define _MAILUTILS_SYS_DBGSTREAM_H + +# include <mailutils/types.h> +# include <mailutils/stream.h> +# include <mailutils/sys/stream.h> + +struct _mu_dbgstream +{ + struct _mu_stream stream; + mu_debug_t debug; + mu_log_level_t level; +}; + +#endif diff --git a/include/mailutils/sys/iostream.h b/include/mailutils/sys/iostream.h new file mode 100644 index 000000000..d8922f6a5 --- /dev/null +++ b/include/mailutils/sys/iostream.h @@ -0,0 +1,34 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _MAILUTILS_SYS_IOSTREAM_H +# define _MAILUTILS_SYS_IOSTREAM_H + +# include <mailutils/types.h> +# include <mailutils/stream.h> +# include <mailutils/sys/stream.h> + +# define _MU_STREAM_INPUT 0 +# define _MU_STREAM_OUTPUT 1 + +struct _mu_iostream +{ + struct _mu_stream stream; + mu_stream_t transport[2]; + int last_err_str; +}; + +#endif diff --git a/include/mailutils/sys/xscript-stream.h b/include/mailutils/sys/xscript-stream.h new file mode 100644 index 000000000..c6b45387a --- /dev/null +++ b/include/mailutils/sys/xscript-stream.h @@ -0,0 +1,33 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _MAILUTILS_SYS_XSCRIPT_STREAM_H +# define _MAILUTILS_SYS_XSCRIPT_STREAM_H + +# include <mailutils/types.h> +# include <mailutils/stream.h> +# include <mailutils/sys/stream.h> + +struct _mu_xscript_stream +{ + struct _mu_stream stream; + mu_stream_t transport; + mu_stream_t logstr; + int flags; + char *prefix[2]; +}; + +#endif diff --git a/mailbox/Makefile.am b/mailbox/Makefile.am index 0d0493033..1fd892dfa 100644 --- a/mailbox/Makefile.am +++ b/mailbox/Makefile.am @@ -69,6 +69,7 @@ libmailutils_la_SOURCES = \ daemon.c\ date.c\ dbgstderr.c\ + dbgstream.c\ dbgsyslog.c\ debug.c\ diag.c\ @@ -84,6 +85,7 @@ libmailutils_la_SOURCES = \ gocs.c\ hdritr.c\ header.c\ + iostream.c\ iterator.c\ ipsrv.c\ kwd.c\ @@ -150,7 +152,8 @@ libmailutils_la_SOURCES = \ vartab.c\ vasnprintf.c\ version.c\ - wicket.c + wicket.c\ + xscript-stream.c BUILT_SOURCES = parsedate.c muerrno.c cfg_parser.c cfg_parser.h cfg_lexer.c MOSTLYCLEANFILES= diff --git a/mailbox/dbgstream.c b/mailbox/dbgstream.c new file mode 100644 index 000000000..19c137d3f --- /dev/null +++ b/mailbox/dbgstream.c @@ -0,0 +1,86 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2002, 2004, + 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <mailutils/types.h> +#include <mailutils/alloc.h> +#include <mailutils/errno.h> + +#include <mailutils/nls.h> +#include <mailutils/stream.h> +#include <mailutils/sys/stream.h> +#include <mailutils/sys/dbgstream.h> +#include <mailutils/debug.h> + +static int +_dbg_write (struct _mu_stream *str, const char *buf, size_t size, + size_t *pnwrite) +{ + struct _mu_dbgstream *sp = (struct _mu_dbgstream *)str; + if (pnwrite) + *pnwrite = size; + while (size > 0 && (buf[size-1] == '\n' || buf[size-1] == '\r')) + size--; + if (size) + mu_debug_printf (sp->debug, sp->level, "%.*s\n", size, buf); + return 0; +} + +static int +_dbg_flush (struct _mu_stream *str) +{ + struct _mu_dbgstream *sp = (struct _mu_dbgstream *)str; + mu_debug_printf (sp->debug, sp->level, "\n"); + return 0; +} + +static void +_dbg_done (struct _mu_stream *str) +{ + struct _mu_dbgstream *sp = (struct _mu_dbgstream *)str; + if (!(str->flags & MU_STREAM_NO_CLOSE)) + mu_debug_destroy (&sp->debug, NULL); +} + +int +mu_dbgstream_create(mu_stream_t *pref, mu_debug_t debug, mu_log_level_t level, + int flags) +{ + struct _mu_dbgstream *sp; + + sp = (struct _mu_dbgstream *) + _mu_stream_create (sizeof (*sp), MU_STREAM_WRITE | + (flags & MU_STREAM_NO_CLOSE)); + if (!sp) + return ENOMEM; + sp->stream.write = _dbg_write; + sp->stream.flush = _dbg_flush; + sp->stream.done = _dbg_done; + + sp->debug = debug; + sp->level = level; + mu_stream_set_buffer ((mu_stream_t) sp, mu_buffer_line, 1024); + *pref = (mu_stream_t) sp; + return 0; +} + diff --git a/mailbox/file_stream.c b/mailbox/file_stream.c index c97075f5f..7dc8c90fa 100644 --- a/mailbox/file_stream.c +++ b/mailbox/file_stream.c @@ -192,7 +192,7 @@ static int fd_ioctl (struct _mu_stream *str, int code, void *ptr) { struct _mu_file_stream *fstr = (struct _mu_file_stream *) str; - mu_transport_t (*ptrans)[2]; + mu_transport_t *ptrans; switch (code) { @@ -200,8 +200,8 @@ fd_ioctl (struct _mu_stream *str, int code, void *ptr) if (!ptr) return EINVAL; ptrans = ptr; - (*ptrans)[0] = (mu_transport_t) fstr->fd; - (*ptrans)[1] = NULL; + ptrans[0] = (mu_transport_t) fstr->fd; + ptrans[1] = NULL; break; default: diff --git a/mailbox/filter_iconv.c b/mailbox/filter_iconv.c index 6674ba4ea..c948df407 100644 --- a/mailbox/filter_iconv.c +++ b/mailbox/filter_iconv.c @@ -390,7 +390,7 @@ static int _icvt_ioctl (mu_stream_t stream, int code, void *ptr) { struct icvt_stream *s = (struct icvt_stream *)stream; - mu_transport_t (*ptrans)[2]; + mu_transport_t *ptrans; switch (code) { @@ -398,8 +398,8 @@ _icvt_ioctl (mu_stream_t stream, int code, void *ptr) if (!ptr) return EINVAL; ptrans = ptr; - (*ptrans)[0] = (mu_transport_t) s->transport; - (*ptrans)[1] = NULL; + ptrans[0] = (mu_transport_t) s->transport; + ptrans[1] = NULL; break; default: diff --git a/mailbox/fltstream.c b/mailbox/fltstream.c index 8f6260aa2..c75913489 100644 --- a/mailbox/fltstream.c +++ b/mailbox/fltstream.c @@ -335,7 +335,7 @@ static int filter_ctl (struct _mu_stream *stream, int op, void *ptr) { struct _mu_filter_stream *fs = (struct _mu_filter_stream *)stream; - mu_transport_t (*ptrans)[2]; + mu_transport_t *ptrans; switch (op) { @@ -343,8 +343,8 @@ filter_ctl (struct _mu_stream *stream, int op, void *ptr) if (!ptr) return EINVAL; ptrans = ptr; - (*ptrans)[0] = (mu_transport_t) fs->transport; - (*ptrans)[1] = NULL; + ptrans[0] = (mu_transport_t) fs->transport; + ptrans[1] = NULL; break; default: @@ -390,6 +390,26 @@ filter_close (mu_stream_t stream) return mu_stream_close (fs->transport); } + +static int +filter_read_through (struct _mu_stream *stream, + char *buf, size_t bufsize, + size_t *pnread) +{ + struct _mu_filter_stream *fs = (struct _mu_filter_stream *)stream; + return mu_stream_read (fs->transport, buf, bufsize, pnread); +} + +static int +filter_write_through (struct _mu_stream *stream, + const char *buf, size_t bufsize, + size_t *pnwrite) +{ + struct _mu_filter_stream *fs = (struct _mu_filter_stream *)stream; + return mu_stream_write (fs->transport, buf, bufsize, pnwrite); +} + + int mu_filter_stream_create (mu_stream_t *pflt, mu_stream_t str, @@ -402,7 +422,14 @@ mu_filter_stream_create (mu_stream_t *pflt, if ((flags & MU_STREAM_RDWR) == MU_STREAM_RDWR || !(flags & MU_STREAM_RDWR) - || (flags & (MU_STREAM_WRITE|MU_STREAM_SEEK)) == (MU_STREAM_WRITE|MU_STREAM_SEEK)) + || (flags & (MU_STREAM_WRITE|MU_STREAM_SEEK)) == + (MU_STREAM_WRITE|MU_STREAM_SEEK) + || (flags & (MU_STREAM_RDTHRU|MU_STREAM_WRTHRU)) == + (MU_STREAM_RDTHRU|MU_STREAM_WRTHRU) + || (flags & (MU_STREAM_READ|MU_STREAM_RDTHRU)) == + (MU_STREAM_READ|MU_STREAM_RDTHRU) + || (flags & (MU_STREAM_WRITE|MU_STREAM_WRTHRU)) == + (MU_STREAM_WRITE|MU_STREAM_WRTHRU)) return EINVAL; fs = (struct _mu_filter_stream *) _mu_stream_create (sizeof (*fs), flags); @@ -413,11 +440,21 @@ mu_filter_stream_create (mu_stream_t *pflt, { fs->stream.read = filter_read; fs->stream.flush = filter_rd_flush; + if (flags & MU_STREAM_WRTHRU) + { + flags |= MU_STREAM_WRITE; + fs->stream.write = filter_write_through; + } } else { fs->stream.write = filter_write; fs->stream.flush = filter_wr_flush; + if (flags & MU_STREAM_RDTHRU) + { + flags |= MU_STREAM_READ; + fs->stream.read = filter_read_through; + } } fs->stream.done = filter_done; fs->stream.close = filter_close; diff --git a/mailbox/iostream.c b/mailbox/iostream.c new file mode 100644 index 000000000..4b76d3ab4 --- /dev/null +++ b/mailbox/iostream.c @@ -0,0 +1,249 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <mailutils/types.h> +#include <mailutils/alloc.h> +#include <mailutils/errno.h> + +#include <mailutils/nls.h> +#include <mailutils/stream.h> +#include <mailutils/sys/stream.h> +#include <mailutils/sys/iostream.h> + +static int +_iostream_read (struct _mu_stream *str, char *buf, size_t bufsize, + size_t *pnread) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + int rc = mu_stream_read (sp->transport[_MU_STREAM_INPUT], buf, bufsize, + pnread); + if (rc) + sp->last_err_str = _MU_STREAM_INPUT; + return rc; +} + +static int +_iostream_readdelim (struct _mu_stream *str, char *buf, size_t bufsize, + int delim, size_t *pnread) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + int rc = mu_stream_readdelim (sp->transport[_MU_STREAM_INPUT], buf, + bufsize, delim, pnread); + if (rc) + sp->last_err_str = _MU_STREAM_INPUT; + return rc; +} + +static int +_iostream_write (struct _mu_stream *str, const char *buf, size_t bufsize, + size_t *pnwrite) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + int rc = mu_stream_write (sp->transport[_MU_STREAM_OUTPUT], buf, bufsize, + pnwrite); + if (rc) + sp->last_err_str = _MU_STREAM_OUTPUT; + return rc; +} + +static int +_iostream_flush (struct _mu_stream *str) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + int rc = mu_stream_flush (sp->transport[_MU_STREAM_INPUT]); + if (rc) + { + sp->last_err_str = _MU_STREAM_INPUT; + return rc; + } + if (sp->transport[_MU_STREAM_INPUT] != sp->transport[_MU_STREAM_OUTPUT]) + { + rc = mu_stream_flush (sp->transport[_MU_STREAM_OUTPUT]); + if (rc) + sp->last_err_str = _MU_STREAM_OUTPUT; + } + return rc; +} + +static int +_iostream_open (struct _mu_stream *str) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + int rc; + rc = mu_stream_open (sp->transport[_MU_STREAM_INPUT]); + if (rc) + { + sp->last_err_str = _MU_STREAM_INPUT; + return rc; + } + if (sp->transport[_MU_STREAM_INPUT] != sp->transport[_MU_STREAM_OUTPUT]) + { + rc = mu_stream_open (sp->transport[_MU_STREAM_OUTPUT]); + if (rc) + { + sp->last_err_str = _MU_STREAM_OUTPUT; + mu_stream_close (sp->transport[_MU_STREAM_INPUT]); + } + } + return rc; +} + +static int +_iostream_close (struct _mu_stream *str) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + if (sp->stream.flags & MU_STREAM_NO_CLOSE) + return 0; + mu_stream_close (sp->transport[_MU_STREAM_INPUT]); + if (sp->transport[_MU_STREAM_INPUT] != sp->transport[_MU_STREAM_OUTPUT]) + mu_stream_close (sp->transport[_MU_STREAM_OUTPUT]); + return 0; +} + +static void +_iostream_done (struct _mu_stream *str) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + mu_stream_unref (sp->transport[_MU_STREAM_INPUT]); + if (sp->transport[_MU_STREAM_INPUT] != sp->transport[_MU_STREAM_OUTPUT]) + mu_stream_unref (sp->transport[_MU_STREAM_OUTPUT]); +} + +static int +_iostream_ctl (struct _mu_stream *str, int op, void *arg) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + mu_transport_t *ptrans; + + switch (op) + { + case MU_IOCTL_GET_TRANSPORT: + if (!arg) + return EINVAL; + ptrans = arg; + ptrans[0] = (mu_transport_t) sp->transport[_MU_STREAM_INPUT]; + ptrans[1] = (mu_transport_t) sp->transport[_MU_STREAM_OUTPUT]; + break; + + case MU_IOCTL_SET_TRANSPORT: + if (!arg) + return EINVAL; + ptrans = arg; + sp->transport[_MU_STREAM_INPUT] = (mu_stream_t) ptrans[0]; + sp->transport[_MU_STREAM_OUTPUT] = (mu_stream_t) ptrans[1]; + break; + + default: + return EINVAL; + } + return 0; +} + +static int +_iostream_wait (struct _mu_stream *str, int *pflags, struct timeval *tvp) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + int rc = EINVAL; + + if (*pflags == MU_STREAM_READY_RD) + { + rc = mu_stream_wait (sp->transport[_MU_STREAM_INPUT], pflags, tvp); + if (rc) + sp->last_err_str = _MU_STREAM_INPUT; + } + else if (*pflags == MU_STREAM_READY_WR) + { + rc = mu_stream_wait (sp->transport[_MU_STREAM_OUTPUT], pflags, tvp); + if (rc) + sp->last_err_str = _MU_STREAM_OUTPUT; + } + return rc; +} + +static int +_iostream_shutdown (struct _mu_stream *str, int how) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + int rc = EINVAL; + switch (how) + { + case MU_STREAM_READ: + rc = mu_stream_shutdown (sp->transport[_MU_STREAM_INPUT], how); + if (rc) + sp->last_err_str = _MU_STREAM_INPUT; + break; + + case MU_STREAM_WRITE: + rc = mu_stream_shutdown (sp->transport[_MU_STREAM_OUTPUT], how); + if (rc) + sp->last_err_str = _MU_STREAM_OUTPUT; + } + return rc; +} + +static const char * +_iostream_error_string (struct _mu_stream *str, int rc) +{ + struct _mu_iostream *sp = (struct _mu_iostream *)str; + mu_stream_t transport = sp->transport[sp->last_err_str]; + if (transport) + return mu_stream_strerror (transport, rc); + return mu_strerror (rc); +} + +int +mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out, + int flags) +{ + struct _mu_iostream *sp; + + sp = (struct _mu_iostream *) + _mu_stream_create (sizeof (*sp), + MU_STREAM_READ | MU_STREAM_WRITE | + (flags & MU_STREAM_NO_CLOSE)); + if (!sp) + return ENOMEM; + + sp->stream.read = _iostream_read; + sp->stream.readdelim = _iostream_readdelim; + sp->stream.write = _iostream_write; + sp->stream.flush = _iostream_flush; + sp->stream.open = _iostream_open; + sp->stream.close = _iostream_close; + sp->stream.done = _iostream_done; + sp->stream.ctl = _iostream_ctl; + sp->stream.wait = _iostream_wait; + sp->stream.shutdown = _iostream_shutdown; + sp->stream.error_string = _iostream_error_string; + + mu_stream_ref (in); + sp->transport[_MU_STREAM_INPUT] = in; + mu_stream_ref (out); + sp->transport[_MU_STREAM_OUTPUT] = out; + + mu_stream_set_buffer ((mu_stream_t) sp, mu_buffer_line, 1024); + *pref = (mu_stream_t) sp; + return 0; +} + + diff --git a/mailbox/mapfile_stream.c b/mailbox/mapfile_stream.c index 89b3e4776..aeb85e5fe 100644 --- a/mailbox/mapfile_stream.c +++ b/mailbox/mapfile_stream.c @@ -209,13 +209,13 @@ static int _mapfile_ioctl (struct _mu_stream *str, int code, void *ptr) { struct _mu_mapfile_stream *mfs = (struct _mu_mapfile_stream *) str; - mu_transport_t (*ptrans)[2]; + mu_transport_t ptrans[2]; switch (code) { case MU_IOCTL_GET_TRANSPORT: - (*ptrans)[0] = (mu_transport_t) mfs->fd; - (*ptrans)[1] = NULL; + ptrans[0] = (mu_transport_t) mfs->fd; + ptrans[1] = NULL; break; default: diff --git a/mailbox/memory_stream.c b/mailbox/memory_stream.c index ecb091fa9..19d459083 100644 --- a/mailbox/memory_stream.c +++ b/mailbox/memory_stream.c @@ -147,7 +147,7 @@ static int _memory_ioctl (struct _mu_stream *stream, int code, void *ptr) { struct _mu_memory_stream *mfs = (struct _mu_memory_stream *) stream; - mu_transport_t (*ptrans)[2]; + mu_transport_t *ptrans; switch (code) { @@ -155,8 +155,8 @@ _memory_ioctl (struct _mu_stream *stream, int code, void *ptr) if (!ptr) return EINVAL; ptrans = ptr; - (*ptrans)[0] = (mu_transport_t) mfs->ptr; - (*ptrans)[1] = NULL; + ptrans[0] = (mu_transport_t) mfs->ptr; + ptrans[1] = NULL; break; default: diff --git a/mailbox/prog_stream.c b/mailbox/prog_stream.c index 7c6594048..4c0bb8eaf 100644 --- a/mailbox/prog_stream.c +++ b/mailbox/prog_stream.c @@ -367,7 +367,7 @@ _prog_ioctl (struct _mu_stream *str, int code, void *ptr) { struct _mu_prog_stream *fstr = (struct _mu_prog_stream *) str; mu_transport_t t[2]; - mu_transport_t (*ptrans)[2]; + mu_transport_t *ptrans; switch (code) { @@ -375,9 +375,9 @@ _prog_ioctl (struct _mu_stream *str, int code, void *ptr) if (!ptr) return EINVAL; mu_stream_ioctl (fstr->in, MU_IOCTL_GET_TRANSPORT, t); - (*ptrans)[0] = t[0]; + ptrans[0] = t[0]; mu_stream_ioctl (fstr->out, MU_IOCTL_GET_TRANSPORT, t); - (*ptrans)[1] = t[1]; + ptrans[1] = t[1]; break; case MU_IOCTL_GET_STATUS: diff --git a/mailbox/stream_vprintf.c b/mailbox/stream_vprintf.c index db0bff38b..5bd9c09e0 100644 --- a/mailbox/stream_vprintf.c +++ b/mailbox/stream_vprintf.c @@ -37,6 +37,6 @@ mu_stream_vprintf (mu_stream_t str, const char *fmt, va_list ap) n = strlen (buf); rc = mu_stream_write (str, buf, n, NULL); free (buf); - return rc == 0 ? n : -1; + return rc; } diff --git a/mailbox/tcp.c b/mailbox/tcp.c index a03eedb7c..081072825 100644 --- a/mailbox/tcp.c +++ b/mailbox/tcp.c @@ -196,7 +196,7 @@ static int _tcp_ioctl (mu_stream_t stream, int code, void *ptr) { struct _tcp_instance *tcp = (struct _tcp_instance *)stream; - mu_transport_t (*ptrans)[2]; + mu_transport_t *ptrans; switch (code) { @@ -204,8 +204,8 @@ _tcp_ioctl (mu_stream_t stream, int code, void *ptr) if (!ptr) return EINVAL; ptrans = ptr; - (*ptrans)[0] = (mu_transport_t) tcp->fd; - (*ptrans)[1] = NULL; + ptrans[0] = (mu_transport_t) tcp->fd; + ptrans[1] = NULL; break; default: diff --git a/mailbox/xscript-stream.c b/mailbox/xscript-stream.c new file mode 100644 index 000000000..c3a5c4081 --- /dev/null +++ b/mailbox/xscript-stream.c @@ -0,0 +1,300 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 1999, 2000, 2001, 2002, 2004, + 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <mailutils/types.h> +#include <mailutils/alloc.h> +#include <mailutils/errno.h> + +#include <mailutils/nls.h> +#include <mailutils/stream.h> +#include <mailutils/sys/stream.h> +#include <mailutils/sys/xscript-stream.h> + +/* A "transcript stream" transparently writes data to and reads data from + an underlying transport stream, writing each lineful of data to a "log + stream". Writes to log stream are prefixed with a string indicating + direction of the data (read/write). Default prefixes are those used in + RFCs -- "S: ", for data written ("Server"), and "C: ", for data read + ("Client"). */ + +#define TRANS_READ 0x1 +#define TRANS_WRITE 0x2 +#define FLAG_TO_PFX(c) ((c) - 1) + +static void +print_transcript (struct _mu_xscript_stream *str, int flag, + const char *buf, size_t size) +{ + while (size) + { + const char *p; + size_t len; + |