summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-08-30 10:48:54 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-08-30 10:57:15 +0300
commita783f8c35ed0fc9a7a18dc82f43bbe34a37aae37 (patch)
treeae8201215126ac3b29abca8def32b4cc537afd40
parent286657e78705d061fc68c000cd3823608c522c04 (diff)
downloadmailutils-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.h12
-rw-r--r--include/mailutils/sys/Makefile.am5
-rw-r--r--include/mailutils/sys/dbgstream.h31
-rw-r--r--include/mailutils/sys/iostream.h34
-rw-r--r--include/mailutils/sys/xscript-stream.h33
-rw-r--r--mailbox/Makefile.am5
-rw-r--r--mailbox/dbgstream.c86
-rw-r--r--mailbox/file_stream.c6
-rw-r--r--mailbox/filter_iconv.c6
-rw-r--r--mailbox/fltstream.c45
-rw-r--r--mailbox/iostream.c249
-rw-r--r--mailbox/mapfile_stream.c6
-rw-r--r--mailbox/memory_stream.c6
-rw-r--r--mailbox/prog_stream.c6
-rw-r--r--mailbox/stream_vprintf.c2
-rw-r--r--mailbox/tcp.c6
-rw-r--r--mailbox/xscript-stream.c300
-rw-r--r--pop3d/extra.c111
-rw-r--r--pop3d/pop3d.h2
-rw-r--r--pop3d/retr.c2
-rw-r--r--pop3d/stls.c2
-rw-r--r--pop3d/top.c2
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;
+