Commit 30bf4d54 30bf4d542198abc23b897dd81fc280354903e49f by Sergey Poznyakoff

Initial implementation of log streams.

* include/mailutils/mailutils.h: Include mailutils/log.h.
* include/mailutils/stream.h (MU_IOCTL_LOGSTREAM_GET_SEVERITY)
(MU_IOCTL_LOGSTREAM_SET_SEVERITY)
(MU_IOCTL_LOGSTREAM_GET_LOCUS,MU_IOCTL_LOGSTREAM_SET_LOCUS)
(MU_IOCTL_LOGSTREAM_GET_MODE,MU_IOCTL_LOGSTREAM_SET_MODE): New ioctls.
* include/mailutils/sys/logstream.h: New file.
* include/mailutils/sys/syslogstream.h: New file.
* include/mailutils/sys/Makefile.am (sysinclude_HEADERS): Add logstream.h
and syslogstream.h
* include/mailutils/types.hin (mu_locus): New struct.

* libmailutils/stream/Makefile.am (libstream_la_SOURCES): Add logstream.c
and syslogstream.c.

* mu/logger.c: New file.
* mu/template.c: New file.
* mu/Makefile.am (MODULES): Add logger.c
(EXTRA_DIST): Add template.c.
1 parent 554f80a1
......@@ -65,5 +65,6 @@
#include <mailutils/cctype.h>
#include <mailutils/cstr.h>
#include <mailutils/wordsplit.h>
#include <mailutils/log.h>
/* EOF */
......
......@@ -76,7 +76,7 @@ enum mu_buffer_type
#define MU_IOCTL_GET_ECHO 12
#define MU_IOCTL_SET_ECHO 13
/* The following ioctls are for nullstreams only: */
#define MU_IOCTL_NULLSTREAM_SET_PATTERN 14
/* Set read pattern.
......@@ -89,6 +89,23 @@ enum mu_buffer_type
/* Limit stream size. Argument: mu_off_t *psize; */
#define MU_IOCTL_NULLSTREAM_CLRSIZE 17
/* Lift the size limit. Argument: NULL */
/* The following are for logstreams */
/* Get or set logging severity.
Arg: unsigned *
*/
#define MU_IOCTL_LOGSTREAM_GET_SEVERITY 18
#define MU_IOCTL_LOGSTREAM_SET_SEVERITY 19
/* Get or set locus.
Arg: struct mu_locus *
*/
#define MU_IOCTL_LOGSTREAM_GET_LOCUS 20
#define MU_IOCTL_LOGSTREAM_SET_LOCUS 21
/* Get or set log mode.
Arg: int *
*/
#define MU_IOCTL_LOGSTREAM_GET_MODE 22
#define MU_IOCTL_LOGSTREAM_SET_MODE 23
#define MU_TRANSPORT_INPUT 0
#define MU_TRANSPORT_OUTPUT 1
......
......@@ -33,6 +33,7 @@ sysinclude_HEADERS = \
iterator.h\
iostream.h\
list.h\
logstream.h\
mailbox.h\
mailer.h\
mapfile_stream.h\
......@@ -53,6 +54,7 @@ sysinclude_HEADERS = \
streamref.h\
streamtrans.h\
stream.h\
syslogstream.h\
temp_file_stream.h\
tls-stream.h\
url.h\
......
/* 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_LOGSTREAM_H
#define _MAILUTILS_SYS_LOGSTREAM_H
#include <mailutils/types.h>
#include <mailutils/sys/stream.h>
struct _mu_log_stream
{
struct _mu_stream base;
mu_stream_t transport;
unsigned severity;
int logmode;
struct mu_locus locus;
};
#endif
/* 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_SYSLOGSTREAM_H
#define _MAILUTILS_SYS_SYSLOGSTREAM_H
#include <mailutils/types.h>
#include <mailutils/sys/stream.h>
struct _mu_syslog_stream
{
struct _mu_stream base;
int prio;
};
#endif
......@@ -129,6 +129,13 @@ typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t;
#define MU_DEFAULT_RECORD _MU_DEFAULT_RECORD_
struct mu_locus
{
char *mu_file;
unsigned mu_line;
unsigned mu_col;
};
enum mu_gocs_op
{
mu_gocs_op_set,
......
......@@ -22,6 +22,7 @@ libstream_la_SOURCES = \
file_stream.c\
fltstream.c\
iostream.c\
logstream.c\
mapfile_stream.c\
memory_stream.c\
message_stream.c\
......@@ -35,6 +36,7 @@ libstream_la_SOURCES = \
stream_vprintf.c\
streamcpy.c\
streamref.c\
syslogstream.c\
tcp.c\
temp_file_stream.c\
xscript-stream.c
......
......@@ -63,8 +63,8 @@ _dbg_done (struct _mu_stream *str)
}
int
mu_dbgstream_create(mu_stream_t *pref, mu_debug_t debug, mu_log_level_t level,
int flags)
mu_dbgstream_create (mu_stream_t *pref, mu_debug_t debug, mu_log_level_t level,
int flags)
{
int rc;
mu_stream_t stream;
......
/* 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/errno.h>
#include <mailutils/cctype.h>
#include <mailutils/log.h>
#include <mailutils/nls.h>
#include <mailutils/stream.h>
#include <mailutils/sys/logstream.h>
char *_mu_severity_str[] = {
N_("DEBUG"),
N_("INFO"),
N_("NOTICE"),
N_("WARNING"),
N_("ERROR"),
N_("CRIT"),
N_("ALERT"),
N_("EMERG"),
};
int _mu_severity_num = MU_ARRAY_SIZE (_mu_severity_str);
static int
_locus_set_file (struct mu_locus *loc, const char *file, size_t len)
{
free (loc->mu_file);
if (file)
{
loc->mu_file = malloc (len + 1);
if (!loc->mu_file)
return ENOMEM;
memcpy (loc->mu_file, file, len);
loc->mu_file[len] = 0;
}
else
loc->mu_file = NULL;
return 0;
}
#define _locus_set_line(loc, line) ((loc)->mu_line = line)
#define _locus_set_col(loc, col) ((loc)->mu_col = col)
static int
_log_write (struct _mu_stream *str, const char *buf, size_t size,
size_t *pnwrite)
{
struct _mu_log_stream *sp = (struct _mu_log_stream *)str;
unsigned severity = sp->severity;
int logmode = sp->logmode;
struct mu_locus loc = sp->locus;
const char *fname = NULL;
unsigned flen = 0;
int save_locus = 0;
int rc;
#define NEXT do { buf++; size--; if (size == 0) return EINVAL; } while (0)
#define READNUM(n) do { \
unsigned __x = 0; \
if (*buf != '<') \
return EINVAL; \
NEXT; \
while (*buf != '>') \
{ \
if (!mu_isdigit (*buf)) \
return EINVAL; \
__x = __x * 10 + (*buf - '0'); \
NEXT; \
} \
NEXT; \
n = __x; \
} while (0)
/* Tell them we've consumed everything */
*pnwrite = size;
/* Process escapes */
while (*buf == '\033')
{
int code;
unsigned n;
NEXT;
code = *buf;
NEXT;
switch (code)
{
case 'S':
/* Save locus */
save_locus = 1;
break;
case 's':
/* Severity code in decimal (single digit) */
if (!mu_isdigit (*buf))
return EINVAL;
severity = *buf - '0';
NEXT;
break;
case 'O':
/* Flags on. Followed by a bitmask of MU_LOGMODE_*, in decimal */
READNUM (n);
logmode |= n;
break;
case 'X':
/* Flags off. Followed by a bitmask of MU_LOGMODE_*, in decimal */
READNUM (n);
logmode &= ~n;
break;
case 'l':
/* Input line (decimal) */
READNUM (n);
_locus_set_line (&loc, n);
break;
case 'c':
/* Column in input line (decimal) */
READNUM (n);
_locus_set_col (&loc, n);
break;
case 'f':
/* File name. Format: <N>S */
READNUM (flen);
fname = buf;
buf += flen;
size -= flen;
break;
default:
return EINVAL;
}
}
if (severity >= _mu_severity_num)
severity = MU_LOG_EMERG;
if (logmode & MU_LOGMODE_LOCUS)
{
if (fname)
_locus_set_file (&loc, fname, flen);
if (loc.mu_file)
{
mu_stream_write (sp->transport, loc.mu_file,
strlen (loc.mu_file), NULL);
mu_stream_write (sp->transport, ":", 1, NULL);
if (loc.mu_line)
mu_stream_printf (sp->transport, "%u", loc.mu_line);
mu_stream_write (sp->transport, ":", 1, NULL);
if (loc.mu_col)
mu_stream_printf (sp->transport, "%u:", loc.mu_col);
mu_stream_write (sp->transport, " ", 1, NULL);
}
}
if (save_locus)
{
_locus_set_file (&sp->locus, loc.mu_file, strlen (loc.mu_file));
_locus_set_line (&sp->locus, loc.mu_line);
_locus_set_col (&sp->locus, loc.mu_col);
}
if (fname)
free (loc.mu_file);
if (logmode & MU_LOGMODE_SEVERITY)
{
char *s = gettext (_mu_severity_str[severity]);
rc = mu_stream_write (sp->transport, s, strlen (s), NULL);
if (rc)
return rc;
mu_stream_write (sp->transport, ": ", 2, NULL);
}
return mu_stream_write (sp->transport, buf, size, NULL);
}
static int
_log_flush (struct _mu_stream *str)
{
struct _mu_log_stream *sp = (struct _mu_log_stream *)str;
return mu_stream_flush (sp->transport);
}
static void
_log_done (struct _mu_stream *str)
{
struct _mu_log_stream *sp = (struct _mu_log_stream *)str;
if (str->flags & MU_STREAM_AUTOCLOSE)
mu_stream_destroy (&sp->transport);
}
static int
_log_close (struct _mu_stream *str)
{
struct _mu_log_stream *sp = (struct _mu_log_stream *)str;
if (str->flags & MU_STREAM_AUTOCLOSE)
return mu_stream_close (sp->transport);
return 0;
}
static int
_log_setbuf_hook (mu_stream_t str, enum mu_buffer_type type, size_t size)
{
if (type != mu_buffer_line)
return EACCES;
return 0;
}
static int
_log_ctl (struct _mu_stream *str, int op, void *arg)
{
struct _mu_log_stream *sp = (struct _mu_log_stream *)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;
ptrans[1] = NULL;
break;
case MU_IOCTL_SET_TRANSPORT:
if (!arg)
return EINVAL;
ptrans = arg;
if (ptrans[0])
sp->transport = (mu_stream_t) ptrans[0];
break;
case MU_IOCTL_LOGSTREAM_GET_SEVERITY:
if (!arg)
return EINVAL;
*(unsigned*)arg = sp->severity;
break;
case MU_IOCTL_LOGSTREAM_SET_SEVERITY:
if (!arg)
return EINVAL;
if (*(unsigned*)arg >= _mu_severity_num)
return EINVAL;
sp->severity = *(unsigned*)arg;
break;
case MU_IOCTL_LOGSTREAM_GET_MODE:
if (!arg)
return EINVAL;
*(int*)arg = sp->logmode;
break;
case MU_IOCTL_LOGSTREAM_SET_MODE:
if (!arg)
return EINVAL;
sp->logmode = *(int*)arg;
break;
case MU_IOCTL_LOGSTREAM_GET_LOCUS:
{
struct mu_locus *ploc = arg;
if (!arg)
return EINVAL;
if (sp->locus.mu_file)
{
ploc->mu_file = strdup (sp->locus.mu_file);
if (!ploc->mu_file)
return ENOMEM;
}
else
ploc->mu_file = NULL;
ploc->mu_line = sp->locus.mu_line;
ploc->mu_col = sp->locus.mu_col;
break;
}
case MU_IOCTL_LOGSTREAM_SET_LOCUS:
{
struct mu_locus *ploc = arg;
if (!arg)
{
free (sp->locus.mu_file);
sp->locus.mu_file = NULL;
sp->locus.mu_line = 0;
sp->locus.mu_col = 0;
}
else
{
if (ploc->mu_file)
_locus_set_file (&sp->locus, ploc->mu_file,
strlen (ploc->mu_file));
if (ploc->mu_line)
_locus_set_line (&sp->locus, ploc->mu_line);
if (ploc->mu_col)
_locus_set_col (&sp->locus, ploc->mu_col);
}
break;
}
default:
return ENOSYS;
}
return 0;
}
int
mu_log_stream_create (mu_stream_t *pstr, mu_stream_t transport)
{
struct _mu_log_stream *sp;
mu_stream_t stream;
int rc;
sp = (struct _mu_log_stream *)
_mu_stream_create (sizeof (*sp), MU_STREAM_WRITE);
if (!sp)
return ENOMEM;
sp->base.write = _log_write;
sp->base.flush = _log_flush;
sp->base.close = _log_close;
sp->base.done = _log_done;
sp->base.setbuf_hook = _log_setbuf_hook;
sp->base.ctl = _log_ctl;
sp->transport = transport;
mu_stream_ref (transport);
sp->severity = MU_LOG_ERROR;
sp->logmode = 0;
stream = (mu_stream_t) sp;
mu_stream_set_buffer (stream, mu_buffer_line, 0);
rc = mu_stream_open (stream);
if (rc)
mu_stream_destroy (&stream);
else
*pstr = stream;
return rc;
}
/* 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 <syslog.h>
#include <errno.h>
#include <string.h>
#include <mailutils/stream.h>
#include <mailutils/sys/syslogstream.h>
static int
_syslog_stream_write (struct _mu_stream *stream, const char *buf,
size_t size, size_t *pret)
{
struct _mu_syslog_stream *lsp = (struct _mu_syslog_stream *)stream;
*pret = size;
if (size > 0 && buf[size-1] == '\n')
size--;
if (size == 0)
return 0;
syslog (lsp->prio, "%*.*s", (int) size, (int) size, buf);
return 0;
}
static int
_syslog_ctl (struct _mu_stream *str, int op, void *arg)
{
struct _mu_syslog_stream *sp = (struct _mu_syslog_stream *)str;
switch (op)
{
case MU_IOCTL_LOGSTREAM_GET_SEVERITY:
if (!arg)
return EINVAL;
*(int*)arg = sp->prio;
break;
case MU_IOCTL_LOGSTREAM_SET_SEVERITY:
if (!arg)
return EINVAL;
sp->prio = *(int*)arg;
break;
default:
return ENOSYS;
}
return 0;
}
int
_syslog_setbuf_hook (mu_stream_t str, enum mu_buffer_type type, size_t size)
{
if (type != mu_buffer_line)
return EACCES;
return 0;
}
int
mu_syslog_stream_create (mu_stream_t *pstream, int prio)
{
struct _mu_syslog_stream *str =
(struct _mu_syslog_stream *) _mu_stream_create (sizeof (*str),
MU_STREAM_WRITE);
if (!str)
return ENOMEM;
str->prio = prio;
str->base.write = _syslog_stream_write;
str->base.ctl = _syslog_ctl;
str->base.setbuf_hook = _syslog_setbuf_hook;
*pstream = (mu_stream_t) str;
mu_stream_set_buffer (*pstream, mu_buffer_line, 0);
return 0;
}
......@@ -41,6 +41,7 @@ MODULES = \
help.c\
info.c\
ldflags.c\
logger.c\
$(POP_C)\
query.c\
wicket.c
......@@ -79,7 +80,7 @@ AM_CPPFLAGS = \
-DI18NLIBS="\"$(LIBINTL)\""
BUILT_SOURCES=mu-setup.c mu-setup.h
EXTRA_DIST=mu-setup.c mu-setup.h
EXTRA_DIST=mu-setup.c mu-setup.h template.c
mu-setup.h: Makefile.am $(MODULES) $(IDLE_MODULES)
$(AM_V_GEN)$(AWK) -f $(top_srcdir)/mu/mu-setup.awk -v mode=h \
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils 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 General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
#if defined(HAVE_CONFIG_H)
# include <config.h>
#endif
#include <mailutils/mailutils.h>
#include "argp.h"
#include "mu.h"
static char logger_doc[] = N_("mu logger - log data using Mailutils log facility");
char logger_docstring[] = N_("log data using Mailutils log facility");
static char logger_args_doc[] = N_("[TEXT]");
#define OPT_SYSLOG 256
#define OPT_STDERR 257
static struct argp_option logger_options[] = {
{ "file", 'f', N_("FILE"), 0, N_("read message from FILE") },
{ "priority", 'p', N_("[FACILITY.LEVEL]"), 0,
N_("log at the specified syslog priority (implies --syslog)") },
{ "syslog", OPT_SYSLOG, NULL, 0, N_("log via syslog") },
{ "stderr", OPT_STDERR, NULL, 0, N_("log to the standard error") },
{ "severity", 's', N_("SEV"), 0,
N_("log at Mailutils severity level SEV") },
{ "locus", 'l', N_("FILE:LINE[:COL]"), 0,
N_("set locus for logging") },
{ "tag", 't', N_("syslog tag"), 0,
N_("set syslog tag") },
{ NULL }
};
static char *input_file = NULL;
static int use_syslog = 0;
static int log_severity = MU_LOG_ERROR;
static struct mu_locus locus;
static int syslog_facility = LOG_USER;
static int syslog_priority = LOG_ERR;
static char *syslog_tag = NULL;
static error_t
logger_parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case 'f':
input_file = arg;
break;
case OPT_SYSLOG:
use_syslog = 1;
break;
case OPT_STDERR:
use_syslog = 0;
break;
case 's':
{
int i;
for (i = 0; i < _mu_severity_num; i++)
if (mu_c_strcasecmp (_mu_severity_str[i], arg) == 0)
{
log_severity = i;
return 0;
}
argp_error (state, _("unknown severity: %s"), arg);
break;
}
case 't':
syslog_tag = arg;
use_syslog = 1;
break;
case 'p':
{
char *s = strchr (arg, '.');
if (s)
*s++ = 0;
if (mu_string_to_syslog_facility (arg, &syslog_facility))
argp_error (state, _("unknown facility: %s"), arg);
if (s &&
mu_string_to_syslog_priority (s, &syslog_priority))
argp_error (state, _("unknown priority: %s"), s);
use_syslog = 1;
break;
}
case 'l':
{
char *s;
locus.mu_file = arg;
s = strchr (arg, ':');
if (s)
{
*s++ = 0;
locus.mu_line = strtoul (s, &s, 10);
if (*s == ':')
{
locus.mu_col = strtoul (s + 1, &s, 10);
if (*s)
argp_error (state, _("bad column number: %s"), arg);
}
else if (*s)
argp_error (state, _("bad line number: %s"), arg);
}
break;
}
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp logger_argp = {
logger_options,
logger_parse_opt,
logger_args_doc,
logger_doc,
NULL,
NULL,
NULL
};
int
mutool_logger (int argc, char **argv)
{
int index;
mu_stream_t transport, logger;
int rc, mode;
if (argp_parse (&logger_argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
return 1;
argc -= index;
argv += index;
if (argc && input_file)
{
mu_error (_("both input file and message text given"));
exit (1);
}
if (use_syslog)
{
if (!syslog_tag)
syslog_tag = "mu-logger";
openlog (syslog_tag, LOG_PID, syslog_facility);
rc = mu_syslog_stream_create (&transport, syslog_priority);
if (rc)
{
mu_error (_("cannot create syslog stream: %s"),
mu_strerror (rc));
exit (1);
}
}
else
{
rc = mu_stdio_stream_create (&transport, MU_STDERR_FD, 0);
if (rc)
{
mu_error (_("cannot open error stream: %s"), mu_strerror (rc));
return 1;
}
}
rc = mu_log_stream_create (&logger, transport);
mu_stream_unref (transport);
if (rc)
{
mu_error (_("cannot open logger stream: %s"), mu_strerror (rc));
return 1;
}
mode = MU_LOGMODE_SEVERITY | MU_LOGMODE_LOCUS;
mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM_SET_MODE, &mode);
if (locus.mu_file)
mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM_SET_LOCUS, &locus);
mu_stream_ioctl (logger, MU_IOCTL_LOGSTREAM_SET_SEVERITY, &log_severity);
if (argc)
{
int i;
for (i = 0; i < argc; i++)
{
if (i > 0)
mu_stream_write (logger, " ", 1, NULL);
mu_stream_write (logger, argv[i], strlen (argv[i]), NULL);
}
mu_stream_write (logger, "\n", 1, NULL);
}
else if (!input_file || strcmp (input_file, "-") == 0)
{
rc = mu_stdio_stream_create (&transport, MU_STDIN_FD, 0);
if (rc)
{
mu_error (_("cannot open input stream: %s"), mu_strerror (rc));
return 1;
}
}
else
{
rc = mu_file_stream_create (&transport, input_file, MU_STREAM_READ);
if (rc)
{
mu_error (_("cannot open input stream %s: %s"),
input_file, mu_strerror (rc));
return 1;
}
}
return !!mu_stream_copy (logger, transport, 0, NULL);
}
/*
MU Setup: logger
mu-handler: mutool_logger
mu-docstring: logger_docstring
End MU Setup:
*/
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2010 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Mailutils 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 General Public License
along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
/* This file is a template for writing modules for the `mu' utility.
It defines an imaginary module FOO, which does nothing.
Usage checklist:
1. [ ] Copy this file to another location.
2. [ ] Replace FOO with the desired module name.
3. [ ] Edit the text strings marked with `#warning', removing the warnings
when ready.
4. [ ] Implement the desired functionality.
5. [ ] Add the module to Makefile.am
6. [ ] Remove this comment.
*/
#if defined(HAVE_CONFIG_H)
# include <config.h>
#endif
#include <mailutils/mailutils.h>
#include "argp.h"
#include "mu.h"
#warning "Replace DESCRIPTION with a short description of this module."
static char FOO_doc[] = N_("mu FOO - DESCRIPTION");
#warning "Usually DESCRIPTION is the same text as the one used in FOO_doc."
char FOO_docstring[] = N_("DESCRIPTION");
#warning "Edit ARGDOC or remove this variable if module does not take arguments"
static char FOO_args_doc[] = N_("ARGDOC");
static struct argp_option FOO_options[] = {
{ NULL }
};
static error_t
FOO_parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp FOO_argp = {
FOO_options,
FOO_parse_opt,
FOO_args_doc,
FOO_doc,
NULL,
NULL,
NULL
};
int
mutool_FOO (int argc, char **argv)
{
int index;
if (argp_parse (&FOO_argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
return 1;
#warning "Add the necessary functionality here"
return 0;
}
/*
MU Setup: FOO
mu-handler: mutool_FOO
mu-docstring: FOO_docstring
End MU Setup:
*/