Commit aa082652 aa0826526df4dc51cafc2297b7b8306831c38f98 by Sergey Poznyakoff

New utility: mu

The `mu' program is a multi-purpose tool for doing various mail-
and mailutils-related operations.  It includes a pop3 shell,
a coder/decoder for all filter formats supported by Mailutils,
a utility to extract arbitrary values from the MU configuration
files, a configuration information utility and many more, in the
short run.  It supercedes examples/pop3client and (partially)
mailutils-config, both of which will be removed in the future.

* Makefile.am (SUBDIRS): Add mu.
* configure.ac: Likewise.
* po/POTFILES.in: Add new files.
* mu/.gitignore: New file.
* mu/Makefile.am: New file.
* mu/filter.c: New file.
* mu/flt2047.c: New file.
* mu/info.c: New file.
* mu/mu.c: New file.
* mu/mu.h: New file.
* mu/pop.c: New file.
* mu/query.c: New file.
* mu/shell.c: New file.
1 parent af4665d4
......@@ -109,6 +109,7 @@ SUBDIRS = . \
doc\
config\
examples\
mu\
$(FRM_DIR)\
$(POP3D_DIR)\
$(IMAP4D_DIR)\
......
......@@ -1389,6 +1389,7 @@ AC_CONFIG_FILES([
mu-aux/Makefile
mu-aux/mailutils.spec
sieve/Makefile
mu/Makefile
])
AC_OUTPUT
......
## This file is part of GNU Mailutils.
## Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 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 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 General Public License
## along with this program. If not, see <http://www.gnu.org/licenses/>.
bin_PROGRAMS = mu
mu_SOURCES = \
info.c\
mu.h\
mu.c\
filter.c\
flt2047.c\
pop.c\
query.c\
shell.c
mu_LDADD = \
${MU_APP_LIBRARIES}\
${MU_LIB_MBOX}\
${MU_LIB_IMAP}\
${MU_LIB_POP}\
${MU_LIB_NNTP}\
${MU_LIB_MH}\
${MU_LIB_MAILDIR}\
${MU_LIB_MAILER}\
${MU_LIB_AUTH}\
@MU_AUTHLIBS@\
${MU_LIB_MAILUTILS}\
@READLINE_LIBS@ @MU_COMMON_LIBRARIES@
INCLUDES = @MU_APP_COMMON_INCLUDES@ @MU_AUTHINCS@
/* 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 <stdlib.h>
#include <string.h>
#include <mailutils/mailutils.h>
#include "argp.h"
#include "mu.h"
static char filter_doc[] = N_("mu filter");
static char filter_args_doc[] = N_("[OPTIONS] NAME");
static struct argp_option filter_options[] = {
{ "encode", 'e', NULL, 0, N_("encode the input (default)") },
{ "decode", 'd', NULL, 0, N_("decode the input") },
{ "line-length", 'l', NULL, 0, N_("limit output line length") },
{ "newline", 'n', NULL, 0, N_("print additional newline") },
{ NULL }
};
static int filter_mode = MU_FILTER_ENCODE;
static int newline_option = 0;
static size_t line_length;
static int line_length_option = 0;
static error_t
filter_parse_opt (int key, char *arg, struct argp_state *state)
{
char *p;
switch (key)
{
case 'e':
filter_mode = MU_FILTER_ENCODE;
break;
case 'd':
filter_mode = MU_FILTER_DECODE;
break;
case 'n':
newline_option = 1;
break;
case 'l':
line_length = strtoul (arg, &p, 10);
if (*p)
argp_error (state, N_("not a number"));
line_length_option = 1;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp filter_argp = {
filter_options,
filter_parse_opt,
filter_args_doc,
filter_doc,
NULL,
NULL,
NULL
};
/* FIXME: This is definitely a kludge. The API should provide a function
for that. */
static void
reset_line_length (const char *name, size_t length)
{
mu_list_t list;
int status;
mu_filter_record_t frec;
mu_filter_get_list (&list);
status = mu_list_locate (list, (void*)name, (void**)&frec);
if (status == 0)
frec->max_line_length = length;
/* don't bail out, leave that to mu_filter_create */
}
int
mutool_filter (int argc, char **argv)
{
int rc, index;
mu_stream_t in, out, flt;
const char *fltname;
if (argp_parse (&filter_argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
return 1;
argc -= index;
argv += index;
if (argc != 1)
{
mu_error (_("what filter do you want?"));
return 1;
}
fltname = argv[0];
rc = mu_stdio_stream_create (&in, MU_STDIN_FD, 0);
if (rc)
{
mu_error (_("cannot open input stream: %s"), mu_strerror (rc));
return 1;
}
rc = mu_stdio_stream_create (&out, MU_STDOUT_FD, 0);
if (rc)
{
mu_error (_("cannot open output stream: %s"), mu_strerror (rc));
return 1;
}
if (line_length_option)
reset_line_length (fltname, line_length);
rc = mu_filter_create (&flt, in, fltname, filter_mode, MU_STREAM_READ);
if (rc)
{
mu_error (_("cannot open filter stream: %s"), mu_strerror (rc));
return 1;
}
rc = mu_stream_copy (out, flt, 0, NULL);
if (rc)
{
mu_error ("%s", mu_strerror (rc));
return 1;
}
if (newline_option)
mu_stream_write (out, "\n", 1, NULL);
mu_stream_flush (out);
return 0;
}
/* 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 <stdlib.h>
#include <string.h>
#include <mailutils/mailutils.h>
#include "argp.h"
#include "mu.h"
static char flt2047_doc[] = N_("mu 2047 - decode/encode message headers");
static char flt2047_args_doc[] = N_("[OPTIONS] [text]");
static struct argp_option flt2047_options[] = {
{ "encode", 'e', NULL, 0, N_("encode the input (default)") },
{ "decode", 'd', NULL, 0, N_("decode the input") },
{ "newline", 'n', NULL, 0, N_("print additional newline") },
{ "charset", 'c', NULL, 0, N_("set charset (default: iso-8859-1)") },
{ "encoding", 'E', NULL, 0, N_("set encoding (default: quoted-printable)") },
{ NULL }
};
static int decode_mode = 0;
static int newline_option = 0;
static const char *charset = "iso-8859-1";
static const char *encoding = "quoted-printable";
static error_t
flt2047_parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case 'c':
charset = arg;
break;
case 'e':
decode_mode = 0;
break;
case 'E':
encoding = arg;
break;
case 'd':
decode_mode = 1;
break;
case 'n':
newline_option = 0;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp flt2047_argp = {
flt2047_options,
flt2047_parse_opt,
flt2047_args_doc,
flt2047_doc,
NULL,
NULL,
NULL
};
int
mutool_flt2047 (int argc, char **argv)
{
int rc, index;
mu_stream_t in, out;
char *p;
if (argp_parse (&flt2047_argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
return 1;
argc -= index;
argv += index;
rc = mu_stdio_stream_create (&in, MU_STDIN_FD, 0);
if (rc)
{
mu_error (_("cannot open input stream: %s"), mu_strerror (rc));
return 1;
}
rc = mu_stdio_stream_create (&out, MU_STDOUT_FD, 0);
if (rc)
{
mu_error (_("cannot open output stream: %s"), mu_strerror (rc));
return 1;
}
if (argc)
{
char *p;
while (argc--)
{
const char *text = *argv++;
if (decode_mode)
rc = mu_rfc2047_decode (charset, text, &p);
else
rc = mu_rfc2047_encode (charset, encoding, text, &p);
if (rc)
{
mu_error ("%s", mu_strerror (rc));
return 1;
}
mu_stream_printf (out, "%s\n", p);
}
}
else
{
size_t size = 0, n;
char *buf = NULL;
while ((rc = mu_stream_getline (in, &buf, &size, &n)) == 0 && n > 0)
{
mu_rtrim_class (buf, MU_CTYPE_SPACE);
if (decode_mode)
rc = mu_rfc2047_decode (charset, buf, &p);
else
rc = mu_rfc2047_encode (charset, encoding, buf, &p);
if (rc)
{
mu_error ("%s", mu_strerror (rc));
return 1;
}
mu_stream_printf (out, "%s\n", p);
}
}
mu_stream_flush (out);
return 0;
}
/* 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 <stdlib.h>
#include <string.h>
#include <mailutils/mailutils.h>
#include "argp.h"
#include "mu.h"
static char info_doc[] = N_("mu info - print a list of configuration\
options used to build mailutils; optional arguments are interpreted\
as a list of configuration options to check for.");
static char info_args_doc[] = N_("[OPTIONS] [capa...]");
static struct argp_option info_options[] = {
{ "verbose", 'v', NULL, 0,
N_("increase output verbosity"), 0},
{ NULL }
};
static int verbose;
static error_t
info_parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case 'v':
verbose++;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp info_argp = {
info_options,
info_parse_opt,
info_args_doc,
info_doc,
NULL,
NULL,
NULL
};
int
mutool_info (int argc, char **argv)
{
int index;
if (argp_parse (&info_argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
return 1;
argc -= index;
argv += index;
if (argc == 0)
mu_fprint_options (stdout, verbose);
else
{
int i, found = 0;
for (i = 0; i < argc; i++)
{
const struct mu_conf_option *opt = mu_check_option (argv[i]);
if (opt)
{
found++;
mu_fprint_conf_option (stdout, opt, verbose);
}
}
return found == argc ? 0 : 1;
}
return 0;
}
/* 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 <stdlib.h>
#include <string.h>
#include <mailutils/mailutils.h>
#include <mailutils/tls.h>
#include "mailutils/libargp.h"
#include "mu.h"
static char args_doc[] = N_("[OPTIONS] COMMAND [CMDOPTS]");
static char doc[] = N_("mu -- GNU Mailutils test tool.\n\
Commands are:\n\
mu info - show Mailutils configuration\n\
mu query - query configuration values\n\
mu pop - POP3 client program\n\
mu filter - filter program\n\
mu 2047 - decode/encode message headers as per RFC 2047\n\
\n\
Try `mu COMMAND --help' to get help on a particular COMMAND\n\
\n\
Options are:\n");
/* FIXME: add
mu imap
mu send [opts]
*/
static struct argp_option options[] = {
{ NULL }
};
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp argp = {
options,
parse_opt,
args_doc,
doc,
NULL,
NULL,
NULL
};
static const char *mu_tool_capa[] = {
"common",
"debug",
"license",
"locking",
"mailbox",
"auth",
NULL
};
struct mu_cfg_param mu_tool_param[] = {
{ NULL }
};
struct mutool_action_tab
{
const char *name;
mutool_action_t action;
};
struct mutool_action_tab mutool_action_tab[] = {
{ "info", mutool_info },
{ "pop", mutool_pop },
{ "filter", mutool_filter },
{ "2047", mutool_flt2047 },
{ "query", mutool_query },
{ NULL }
};
static mutool_action_t
find_action (const char *name)
{
struct mutool_action_tab *p;
for (p = mutool_action_tab; p->name; p++)
if (strcmp (p->name, name) == 0)
return p->action;
return NULL;
}
int
main (int argc, char **argv)
{
int index;
mutool_action_t action;
/* Native Language Support */
MU_APP_INIT_NLS ();
MU_AUTH_REGISTER_ALL_MODULES ();
/* Register the desired mailbox formats. */
mu_register_all_mbox_formats ();
#ifdef WITH_TLS
mu_gocs_register ("tls", mu_tls_module_init);
#endif
mu_argp_init (NULL, NULL);
if (mu_app_init (&argp, mu_tool_capa, mu_tool_param,
argc, argv, ARGP_IN_ORDER, &index, NULL))
exit (1);
argc -= index;
argv += index;
if (argc < 1)
{
mu_error (_("what do you want me to do?"));
exit (1);
}
action = find_action (argv[0]);
if (!action)
{
mu_error (_("don't know what %s is"), argv[0]);
exit (1);
}
exit (action (argc, argv));
}
/* 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/>. */
typedef int (*mutool_action_t) (int argc, char **argv);
struct mutool_command
{
const char *name; /* User printable name of the function. */
int argmin; /* Min. acceptable number of arguments (-1 means
pass all arguments as a single string */
int argmax; /* Max. allowed number of arguments (-1 means not
limited */
mutool_action_t func; /* Function to call to do the job. */
const char *doc; /* Documentation for this function. */
};
int mutool_pop (int argc, char **argv);
int mutool_filter (int argc, char **argv);
int mutool_flt2047 (int argc, char **argv);
int mutool_info (int argc, char **argv);
int mutool_query (int argc, char **argv);
extern char *mutool_shell_prompt;
extern mu_vartab_t mutool_prompt_vartab;
int mutool_shell (const char *name, struct mutool_command *cmd);
This diff is collapsed. Click to expand it.
/* 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 <stdlib.h>
#include <string.h>
#include <mailutils/mailutils.h>
#include <mailutils/libcfg.h>
#include "argp.h"
#include "mu.h"
static char query_doc[] = N_("mu query - query configuration values.");
static char query_args_doc[] = N_("[OPTIONS]");
char *file_name;
int verbose_option;
static struct argp_option query_options[] = {
{ "file", 'f', N_("FILE"), 0,
N_("query configuration values from FILE (default mailutils.rc)"),
0 },
{ "verbose", 'v', NULL, 0,
N_("increase output verbosity"), 0},
{ NULL }
};
static error_t
query_parse_opt (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case 'f':
file_name = arg;
break;
case 'v':
verbose_option++;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp query_argp = {
query_options,
query_parse_opt,
query_args_doc,
query_doc,
NULL,
NULL,
NULL
};
int
mutool_query (int argc, char **argv)
{
int rc, index;
mu_cfg_tree_t *tree = NULL;
int fmtflags = 0;
mu_stream_t stream;
if (argp_parse (&query_argp, argc, argv, ARGP_IN_ORDER, &index, NULL))
return 1;
argc -= index;
argv += index;
if (argc == 0)
{
mu_error (_("query what?"));
return 1;
}
if (file_name)
{
mu_load_site_rcfile = 0;
mu_load_user_rcfile = 0;
mu_load_rcfile = file_name;
}
if (mu_libcfg_parse_config (&tree))
return 1;
if (!tree)
return 0;
rc = mu_stdio_stream_create (&stream, MU_STDOUT_FD, 0);
if (rc)
{
mu_error ("mu_stdio_stream_create: %s", mu_strerror (rc));
return 1;
}
if (verbose_option)
fmtflags = MU_CFG_FMT_LOCUS;
for ( ; argc > 0; argc--, argv++)
{
char *path = *argv;
mu_cfg_node_t *node;
if (mu_cfg_find_node (tree, path, &node) == 0)
mu_cfg_format_node (stream, node, fmtflags);
}
return 0;
}
This diff is collapsed. Click to expand it.
......@@ -197,5 +197,13 @@ sieve/sieve.c
sql/mysql.c
mu/filter.c
mu/flt2047.c
mu/info.c
mu/mu.c
mu/pop.c
mu/query.c
mu/shell.c
# EOF
......