Commit e267ac86 e267ac86e2c3a78979fe12bdd16392f30f8d1725 by Sergey Poznyakoff

Finish conversion of MH utilities to mh_parseopt

This finishes work started at commit bc73fc65.

* include/mailutils/opt.h (mu_option_cache) <cache_arg>: Made const.
* libmailutils/opt/opt.c (mu_option_cache_destroy): Don't free cache_arg.
* doc/texinfo/mu-mh.texi: Update.

* po/POTFILES.in: Remove obsolete files.
* mh/tests/refile.at: Don't use double-dash options.

* mh/mh_getopt.c (mh_opt_set_folder): New function.
* mh/mh_getopt.h: Likewise.

* mh/mhn.c: Convert to mh_getopt.
* mh/mhparam.c: Likewise.
* mh/mhpath.c: Likewise.
* mh/mhseq.c: Likewise.
* mh/msgchk.c: Likewise.
* mh/pick.c: Likewise.
* mh/pick.h: Likewise.
* mh/pick.y: Likewise.
* mh/prompter.c: Likewise.
* mh/refile.c: Likewise.
* mh/repl.c: Likewise.
* mh/rmf.c: Likewise.
* mh/rmm.c: Likewise.
* mh/scan.c: Likewise.
* mh/send.c: Likewise.
* mh/show.c: Likewise.
* mh/sortm.c: Likewise.
* mh/whatnow.c: Likewise.
* mh/whom.c: Likewise.
1 parent f434857b
......@@ -27,9 +27,6 @@ distribution directory.
@subsection Major differences between Mailutils MH and other MH implementations
@enumerate 1
@item All programs use usual GNU long options. The support for MH single-dash
options is provided for backward compatibility;
@item UUCP addresses are not supported;
@item Mailutils supports a set of new format specifications
......@@ -38,6 +35,12 @@ options is provided for backward compatibility;
@item Mailutils provides a set of new profile variables
(@pxref{Profile Variable Diffs});
@item All programs recognize @option{--help} and @option{--version} options
These options are recognized only if no other arguments are present in
the command line. Abbreviations are not recognized. This makes Mailutils
MH implementation compatible with the standard usage for GNU tools.
@item Several programs behave differently (@pxref{Program
Diffs});
......@@ -150,7 +153,7 @@ This expression is used in default @file{replcomps} and
@deftypefn {MH Format} boolean rcpt (@samp{to} | @samp{cc} | @samp{me} | @samp{all})
This function returns true if the given element is present in the
recipient mask (as modified by @option{--cc} or @option{--nocc} options) and
recipient mask (as modified by @option{-cc} or @option{-nocc} options) and
false otherwise. It is used in default formats for @command{repl} and
@command{comp}, e.g.:
......@@ -159,7 +162,7 @@ false otherwise. It is used in default formats for @command{repl} and
@end smallexample
Notice that this means that usual @file{replcomps} file will be ignoring
@option{--cc} and @option{--nocc} options, unless it has been modified
@option{-cc} and @option{-nocc} options, unless it has been modified
as shown above.
@end deftypefn
......@@ -226,12 +229,12 @@ RAND @command{anno} displays the prompt anyway.
The utility is able to burst both RFC 934 digest messages and MIME
multipart messages. It provides two additional command line options:
@option{--recurse} and @option{--length}.
@option{-recurse} and @option{-length}.
The @option{--recurse} option instructs the utility to recursively
The @option{-recurse} option instructs the utility to recursively
expand the digest.
The @option{--length} option can be used to set the minimal encapsulation
The @option{-length} option can be used to set the minimal encapsulation
boundary length for RFC 934 digests. Default length is 1,
i.e. encountering one dash immediately following a newline triggers
digest decoding. It is OK for messages that follow RFC 934
......@@ -239,12 +242,12 @@ specification. However, many user agents do not precisely follow it,
in particular, they often do not escape lines starting with a dash by
@samp{- } sequence. @command{Mailman} is one of such agents. To cope
with such digests you can set encapsulation boundary length to a higher
value. For example, @command{bounce --length=8} has been found to be
value. For example, @command{bounce -length 8} has been found to be
sufficient for most Mailman-generated digests.
@item comp
Understands @option{--build} option.
Understands @option{-build} option.
@item fmtdump
......@@ -252,24 +255,24 @@ This command is not provided. Use @option{fmtcheck} instead.
@item inc
@itemize @bullet
@item The @option{--moveto} option.
The @option{--moveto} option instructs @command{inc} to move
@item The @option{-moveto} option.
The @option{-moveto} option instructs @command{inc} to move
messages into another folder after incorporating them. This option
has effect only if the @option{--truncate} option has also been
has effect only if the @option{-truncate} option has also been
specified and the underlying mailbox supports the @samp{move}
operation. Currently only @samp{imap} and @samp{imaps} mailboxes
support it. For example, the following command moves incorporated
messages into the @samp{archive} folder:
@example
inc --file imaps://imap.gmail.com --moveto=archive
inc -file imaps://imap.gmail.com -moveto=archive
@end example
The @samp{moveto} URL parameter can be used instead of this option,
e.g.:
@example
inc --file 'imaps://imap.gmail.com;moveto=archive'
inc -file 'imaps://imap.gmail.com;moveto=archive'
@end example
@item Multiple sources
......@@ -294,7 +297,7 @@ Moves incorporated messages into another folder. This was discussed
above.
@item nomoveto
Disables the previous @option{--moveto} option.
Disables the previous @option{-moveto} option.
@item truncate[=@var{bool}]
Controls source mailbox truncation. If @var{bool} is not given or it is
......@@ -333,13 +336,13 @@ The following format variables are silently ignored: @samp{center},
@itemize @bullet
@item New option
New option @option{--compose} forces @command{mhn} editing mode. This
New option @option{-compose} forces @command{mhn} editing mode. This
is also the default mode. This differs from the standard
@command{mhn}, which switches to the editing mode only if no other
options were given and the input file name coincides with the value of
@env{mhdraft} environment variable.
@item Show mode (@option{--show})
@item Show mode (@option{-show})
If an appropriate mhn-show-type[/subtype] was not found, GNU @command{mhn}
prints the decoded message content using @code{moreproc}
variable. Standard @command{mhn} in this case used to print @samp{don't
......@@ -349,47 +352,28 @@ The default behaviour is to pipe the content to the standard input
of the mhn-show-type[/subtype] command. This is altered to using a
temporary file if the command contains @code{%f} or @code{%F} escapes.
@item Store mode (@option{--store})
@item Store mode (@option{-store})
If the @code{Content-Disposition} header contains @samp{filename=},
and @command{mhn} is invoked with @option{--auto} switch, it
and @command{mhn} is invoked with @option{-auto} switch, it
transforms the file name into the absolute notation and uses it only
if it lies below the current mhn-storage directory. Standard
@command{mhn} only requires that the file name do not begin with @samp{/}.
Before saving a message part, GNU @command{mhn} checks if the file already
exists. If so, it asks whether the user wishes to rewrite it. This
behaviour is disabled when @option{--quiet} option was given.
behaviour is disabled when @option{-quiet} option was given.
@end itemize
@item mhparam
The @option{--all} mode does not display commented out entries.
The @option{-all} mode does not display commented out entries.
@item pick
The command line syntax @option{--@var{component} @var{string}}) is
recognized only if at least one of the following conditions is met:
@itemize @bullet
@item The word @var{component} contains at least one capital letter.
E.g. @option{--User-Agent Mailutils}.
@item The word @var{component} ends with a colon, as in
@option{user-agent: Mailutils}.
@item Standard input is not connected to a terminal.
@end itemize
The GNU syntax for component matching is:
@smallexample
pick --component @var{field} --pattern @var{string}
@end smallexample
New command line option @option{--cflags} allows to control the type of
New command line option @option{-cflags} allows to control the type of
regular expressions used. The option must occur right before
@option{--pattern} or @option{--component} option (or one of its
aliases, like @option{--cc}, @option{--from}, etc.)
@option{--@var{component} @var{pattern}} or equivalent construct (like
@option{-cc}, @option{-from}, etc.)
The argument to this option is a string of type specifications:
......@@ -402,24 +386,24 @@ The argument to this option is a string of type specifications:
Default is @samp{EI}.
The flags remain in effect until the next occurrence of @option{--cflags}
The flags remain in effect until the next occurrence of @option{-cflags}
option.
Sample usage:
@smallexample
pick --cflag BC --subject '*a string'
pick -cflag BC -subject '*a string'
@end smallexample
The date comparison options (@option{--before} and @option{--after}
The date comparison options (@option{-before} and @option{-after}
accept date specifications in a wide variety of formats, e.g.:
@smallexample
pick --after 20030301
pick --after 2003-03-01
pick --after 01-mar-2003
pick --after 2003-mar-01
pick --before '1 year ago'
pick -after 20030301
pick -after 2003-03-01
pick -after 01-mar-2003
pick -after 2003-mar-01
pick -before '1 year ago'
etc...
@end smallexample
......@@ -454,11 +438,11 @@ will add it automatically.
@item
Linking messages between folders goes against the logic of Mailutils,
so @command{refile} never makes links even if called with
@option{--link} option. The latter is actually a synonym for @option{--copy},
@option{-link} option. The latter is actually a synonym for @option{-copy},
which preserves the original message.
@item
The @option{--preserve} option is not implemented. It is retained for backward
The @option{-preserve} option is not implemented. It is retained for backward
compatibility only.
@item
......@@ -467,7 +451,7 @@ Message specs and folder names may be interspersed.
@item repl
Understands @option{--use} option. Disposition shell provides
Understands @option{-use} option. Disposition shell provides
@code{use} command.
@item rmm
......@@ -491,14 +475,14 @@ rmmproc:
@item sortm
New option @option{--numfield} specifies numeric comparison for the
New option @option{-numfield} specifies numeric comparison for the
given field.
Any number of @option{--datefield}, @option{--textfield} and
@option{--numfield} options may be given, thus allowing to build sort
Any number of @option{-datefield}, @option{-textfield} and
@option{-numfield} options may be given, thus allowing to build sort
criteria of arbitrary complexity.
The order of @option{--.*field} options sets the ordering priority. This
The order of @option{-.*field} options sets the ordering priority. This
differs from the behaviour of the standard @command{sortm}, which
always orders datefield-major, textfield-minor.
......@@ -506,11 +490,11 @@ Apart from sorting the mailfolder the following actions may be
specified:
@table @option
@item --list
@item -list
List the ordered messages using a format string given by
@option{--form} or @option{--format} option.
@option{-form} or @option{-format} option.
@item --dry-run
@item -dry-run
Do not actually sort messages, rather print what would have been
done. This is useful for debugging purposes.
@end table
......
......@@ -71,7 +71,7 @@ typedef struct mu_option_cache *mu_option_cache_ptr_t;
struct mu_option_cache
{
struct mu_option *cache_opt;
char *cache_arg;
char const *cache_arg;
};
#define MU_PARSEOPT_DEFAULT 0
......
......@@ -136,7 +136,6 @@ static void
mu_option_cache_destroy (void *ptr)
{
struct mu_option_cache *cache = ptr;
free (cache->cache_arg);
free (cache);
}
......@@ -150,7 +149,7 @@ add_option_cache (struct mu_parseopt *po, struct mu_option *opt,
{
struct mu_option_cache *cache = mu_alloc (sizeof (*cache));
cache->cache_opt = opt;
cache->cache_arg = arg ? mu_strdup (arg) : NULL;
cache->cache_arg = arg;
if ((po->po_flags & MU_PARSEOPT_IMMEDIATE)
|| (opt->opt_flags & MU_OPTION_IMMEDIATE))
......@@ -774,7 +773,7 @@ mu_option_set_value (struct mu_parseopt *po, struct mu_option *opt,
free (errmsg);
if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
exit (EXIT_ERROR);
exit (po->po_exit_error);
}
}
}
......
......@@ -79,6 +79,23 @@ augment_argv (int *pargc, char ***pargv)
}
static void
process_std_options (int argc, char **argv, struct mu_parseopt *po)
{
if (argc != 1)
return;
if (strcmp (argv[0], "--help") == 0)
{
mu_program_help (po, mu_strout);
exit (0);
}
if (strcmp (argv[0], "--version") == 0)
{
mu_program_version (po, mu_strout);
exit (0);
}
}
static void
process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po)
{
int i, j;
......@@ -109,8 +126,9 @@ process_folder_arg (int *pargc, char **argv, struct mu_parseopt *po)
*pargc = j;
}
static void
set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
void
mh_opt_set_folder (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
mh_set_current_folder (arg);
}
......@@ -118,7 +136,45 @@ set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
static struct mu_option folder_option[] = {
{ "folder", 0, NULL, MU_OPTION_DEFAULT,
N_("set current folder"),
mu_c_string, NULL, set_folder },
mu_c_string, NULL, mh_opt_set_folder },
MU_OPTION_END
};
void
mh_version_hook (struct mu_parseopt *po, mu_stream_t stream)
{
extern const char mu_version_copyright[];
#ifdef GIT_DESCRIBE
mu_stream_printf (stream, "%s (GNU MH, %s) %s [%s]\n",
mu_program_name, PACKAGE_NAME, PACKAGE_VERSION,
GIT_DESCRIBE);
#else
mu_stream_printf (stream, "%s (GNU MH, %s) %s\n", mu_program_name,
PACKAGE_NAME, PACKAGE_VERSION);
#endif
/* TRANSLATORS: Translate "(C)" to the copyright symbol
(C-in-a-circle), if this symbol is available in the user's
locale. Otherwise, do not translate "(C)"; leave it as-is. */
mu_stream_printf (stream, mu_version_copyright, _("(C)"));
mu_stream_printf (stream, _("\
\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is free software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n\
\n\
"));
}
static void
fn_version (struct mu_parseopt *po, struct mu_option *opt, char const *unused)
{
mu_program_version (po, mu_strout);
exit (0);
}
static struct mu_option version_option[] = {
{ "version", 0, NULL, MU_OPTION_DEFAULT,
N_("print program version"),
mu_c_string, NULL, fn_version },
MU_OPTION_END
};
......@@ -132,7 +188,7 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
struct mu_parseopt po;
struct mu_option *optv[3];
struct getopt_data getopt_data;
char const *args[2];
char const *args[3];
int flags = MU_PARSEOPT_SINGLE_DASH | MU_PARSEOPT_IMMEDIATE;
int i;
......@@ -177,6 +233,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
//po.po_extra_info = gnu_general_help_url;
//flags |= MU_PARSEOPT_EXTRA_INFO;
po.po_version_hook = mh_version_hook;
flags |= MU_PARSEOPT_VERSION_HOOK;
mu_set_program_name (argv[0]);
mh_init ();
augment_argv (&argc, &argv);
......@@ -184,7 +243,9 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
i = 0;
if (mhflags & MH_GETOPT_DEFAULT_FOLDER)
optv[i++] = folder_option;
optv[i++] = options;
if (options)
optv[i++] = options;
optv[i++] = version_option;
optv[i] = NULL;
if (mu_parseopt (&po, argc, argv, optv, flags))
......@@ -193,6 +254,8 @@ mh_getopt (int *pargc, char ***pargv, struct mu_option *options,
argc -= po.po_arg_start;
argv += po.po_arg_start;
process_std_options (argc, argv, &po);
process_folder_arg (&argc, argv, &po);
if (!argdoc && argc)
......
......@@ -35,5 +35,7 @@ void mh_opt_find_file (struct mu_parseopt *po, struct mu_option *opt,
char const *arg);
void mh_opt_read_formfile (struct mu_parseopt *po, struct mu_option *opt,
char const *arg);
void mh_opt_set_folder (struct mu_parseopt *po, struct mu_option *opt,
char const *arg);
......
......@@ -22,99 +22,9 @@
#include <mailutils/mime.h>
#include <setjmp.h>
static char doc[] = N_("GNU MH mhn")"\v"
N_("Options marked with `*' are not yet implemented.\n\
Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH mhn");
static char args_doc[] = N_("[MSGLIST]");
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon"), 0},
{"file", ARG_FILE, N_("FILE"), 0,
N_("specify file to operate upon"), 0},
#define GRID 10
{N_("MIME editing options"), 0, NULL, OPTION_DOC, NULL, GRID},
{"compose", ARG_COMPOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("compose the MIME message (default)"), GRID+1},
{"build", 0, NULL, OPTION_ALIAS,
NULL, GRID+1 },
{"nocompose", ARG_NOCOMPOSE, NULL, OPTION_HIDDEN, NULL, GRID+1},
{"nobuild", ARG_NOCOMPOSE, NULL, OPTION_HIDDEN|OPTION_ALIAS,
NULL, GRID+1},
#undef GRID
#define GRID 20
{N_("Listing options"), 0, NULL, OPTION_DOC, NULL, GRID},
{"list", ARG_LIST, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("list the table of contents"), GRID+1 },
{"nolist", ARG_NOLIST, NULL, OPTION_HIDDEN, "", GRID+1 },
{"headers", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("print the banner above the listing"), GRID+1 },
{"noheaders", ARG_NOHEADERS, NULL, OPTION_HIDDEN, "", GRID+1 },
{"realsize", ARG_REALSIZE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("list the decoded sizes"), GRID+1 },
{"norealsize", ARG_NOREALSIZE, NULL, OPTION_HIDDEN, "", GRID+1 },
#undef GRID
#define GRID 40
{N_("Display options"), 0, NULL, OPTION_DOC, NULL, GRID},
{"show", ARG_SHOW, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("display the contents of the messages"), GRID+1},
{"noshow", ARG_NOSHOW, NULL, OPTION_HIDDEN, "", GRID+1 },
{"serialonly", ARG_SERIALONLY, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* display messages serially"), GRID+1},
{"noserialonly", ARG_NOSERIALONLY, NULL, OPTION_HIDDEN, "", GRID+1 },
{"form", ARG_FORM, N_("FILE"), 0,
N_("read mhl format from FILE"), GRID+1},
{"pause", ARG_PAUSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("pause prior to displaying content"), GRID+1},
{"nopause", ARG_NOPAUSE, NULL, OPTION_HIDDEN, "", GRID+1 },
#undef GRID
#define GRID 50
{N_("Saving options"), 0, NULL, OPTION_DOC, NULL, GRID},
{"store", ARG_STORE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("write extracted message parts to disk"), GRID+1},
{"nostore", ARG_NOSTORE, NULL, OPTION_HIDDEN, "", GRID+1 },
{"auto", ARG_AUTO, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("use filenames from the content headers"), GRID+1},
{"noauto", ARG_NOAUTO, NULL, OPTION_HIDDEN, "", GRID+1 },
{"charset", ARG_CHARSET, N_("NAME"), 0,
N_("use this charset to represent attachment file names"), GRID+1},
#undef GRID
#define GRID 60
{N_("Other options"), 0, NULL, OPTION_DOC, NULL, GRID},
{"part", ARG_PART, N_("PART"), 0,
N_("limit the scope of the operation to the given part"), GRID+1},
{"type", ARG_TYPE, N_("CONTENT"), 0,
N_("operate on message part with given multipart content"), GRID+1 },
{"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("print additional information"), GRID+1 },
{"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "", GRID+1 },
{"quiet", ARG_QUIET, 0, 0,
N_("be quiet"), GRID+1},
#undef GRID
{NULL}
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "file", MH_OPT_ARG, "filename" },
{ "compose" },
{ "build" },
{ "list", MH_OPT_BOOL },
{ "headers", MH_OPT_BOOL },
{ "realsize", MH_OPT_BOOL },
{ "show", MH_OPT_BOOL },
{ "serialonly", MH_OPT_BOOL },
{ "form", MH_OPT_ARG, "formfile" },
{ "pause", MH_OPT_BOOL },
{ "store", MH_OPT_BOOL },
{ "auto", MH_OPT_BOOL },
{ "part", MH_OPT_ARG, "part" },
{ "type", MH_OPT_ARG, "type" },
{ "verbose", MH_OPT_BOOL },
{ NULL }
};
typedef struct _msg_part *msg_part_t;
static msg_part_t msg_part_create (size_t num);
......@@ -124,28 +34,22 @@ static void msg_part_incr (msg_part_t p);
static void msg_part_decr (msg_part_t p);
static void msg_part_set_subpart (msg_part_t p, size_t subpart);
static void msg_part_print (msg_part_t p, int width);
static msg_part_t msg_part_parse (char *str);
static msg_part_t msg_part_parse (char const *str);
static int msg_part_level (msg_part_t p);
static size_t msg_part_subpart (msg_part_t p, int level);
enum mhn_mode
{
mode_compose,
mode_list,
mode_show,
mode_store,
};
static enum mhn_mode mode = mode_compose;
static int compose_option;
static int list_option;
static int show_option;
static int store_option;
#define OPT_HEADERS 001
#define OPT_REALSIZE 002
#define OPT_AUTO 004
#define OPT_SERIALONLY 010
#define OPT_VERBOSE 020
#define OPT_QUIET 040
static int headers_option = 1;
static int realsize_option;
static int auto_option;
/*static int serialonly_option;*/
static int verbose_option;
static int quiet_option;
static int mode_options = OPT_HEADERS;
static int pause_option = -1; /* -pause option. -1 means "not given" */
static char *formfile;
static char *content_type;
......@@ -260,173 +164,88 @@ _get_content_encoding (mu_header_t hdr, char **value)
*value = encoding;
return 0;
}
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
set_part (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
case ARG_FILE:
input_file = arg;
break;
/* Operation mode */
case ARG_COMPOSE:
if (is_true (arg))
{
mode = mode_compose;
break;
}
/*FALLTHRU*/
case ARG_NOCOMPOSE:
if (mode == mode_compose)
mode = mode_compose;
break;
case ARG_LIST:
if (is_true (arg))
{
mode = mode_list;
break;
}
/*FALLTHRU*/
case ARG_NOLIST:
if (mode == mode_list)
mode = mode_compose;
break;
case ARG_SHOW:
if (is_true (arg))
{
mode = mode_show;
break;
}
/*FALLTHRU*/
case ARG_NOSHOW:
if (mode == mode_show)
mode = mode_compose;
break;
case ARG_STORE:
if (is_true (arg))
{
mode = mode_store;
break;
}
/*FALLTHRU*/
case ARG_NOSTORE:
if (mode == mode_store)
mode = mode_compose;
break;
/* List options */
case ARG_HEADER:
if (is_true (arg))
{
mode_options |= OPT_HEADERS;
break;
}
/*FALLTHRU*/
case ARG_NOHEADERS:
mode_options &= ~OPT_HEADERS;
break;
case ARG_REALSIZE:
if (is_true (arg))
{
mode_options |= OPT_REALSIZE;
break;
}
/*FALLTHRU*/
case ARG_NOREALSIZE:
mode_options &= ~OPT_REALSIZE;
break;
/* Display options */
case ARG_SERIALONLY:
mh_opt_notimpl_warning ("-[no]serialonly");
if (is_true (arg))
{
mode_options |= OPT_SERIALONLY;
break;
}
/*FALLTHRU*/
case ARG_NOSERIALONLY:
mode_options &= ~OPT_SERIALONLY;
break;
case ARG_PAUSE:
pause_option = is_true (arg);
break;
case ARG_NOPAUSE:
pause_option = 0;
break;
/* Store options */
case ARG_AUTO:
if (is_true (arg))
{
mode_options |= OPT_AUTO;
break;
}
/*FALLTHRU*/
case ARG_NOAUTO:
mode_options &= ~OPT_AUTO;
break;
case ARG_FORM:
mh_find_file (arg, &formfile);
break;
/* Common options */
case ARG_VERBOSE:
if (is_true (arg))
{
mode_options |= OPT_VERBOSE;
break;
}
/*FALLTHRU*/
case ARG_NOVERBOSE:
mode_options &= ~OPT_VERBOSE;
break;
case ARG_TYPE:
sfree (&content_type);
sfree (&content_subtype);
split_content (arg, &content_type, &content_subtype);
break;
case ARG_PART:
req_part = msg_part_parse (arg);
break;
case ARG_QUIET:
mode_options |= OPT_QUIET;
break;
case ARG_CHARSET:
charset = arg;
break;
case ARGP_KEY_FINI:
if (!formfile)
mh_find_file ("mhl.headers", &formfile);
if (!isatty (0))
pause_option = 0;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
req_part = msg_part_parse (arg);
}
static void
set_type (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
sfree (&content_type);
sfree (&content_subtype);
split_content (arg, &content_type, &content_subtype);
}
static struct mu_option options[] = {
{ "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify folder to operate upon"),
mu_c_string, NULL, mh_opt_set_folder },
{ "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("specify file to operate upon"),
mu_c_string, &input_file },
MU_OPTION_GROUP (N_("MIME editing options")),
{ "compose", 0, NULL, MU_OPTION_DEFAULT,
N_("compose the MIME message (default)"),
mu_c_bool, &compose_option },
{ "build", 0, NULL, MU_OPTION_ALIAS },
MU_OPTION_GROUP (N_("Listing options")),
{ "list", 0, NULL, MU_OPTION_DEFAULT,
N_("list the table of contents"),
mu_c_bool, &list_option },
{ "headers", 0, NULL, MU_OPTION_DEFAULT,
N_("print the banner above the listing"),
mu_c_bool, &headers_option },
{ "realsize", 0, NULL, MU_OPTION_DEFAULT,
N_("list the decoded sizes"),
mu_c_bool, &realsize_option },
MU_OPTION_GROUP (N_("Display options")),
{ "show", 0, NULL, MU_OPTION_DEFAULT,
N_("display the contents of the messages"),
mu_c_bool, &show_option },
{ "serialonly", 0, NULL, MU_OPTION_HIDDEN,
"",
mu_c_bool, NULL, mh_opt_notimpl_warning },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read mhl format from FILE"),
mu_c_string, &formfile, mh_opt_find_file },
{ "pause", 0, NULL, MU_OPTION_DEFAULT,
N_("pause prior to displaying content"),
mu_c_bool, &pause_option },
MU_OPTION_GROUP (N_("Saving options")),
{ "store", 0, NULL, MU_OPTION_DEFAULT,
N_("write extracted message parts to disk"),
mu_c_bool, &store_option },
{ "auto", 0, NULL, MU_OPTION_DEFAULT,
N_("use filenames from the content headers"),
mu_c_bool, &auto_option },
{ "charset", 0, N_("NAME"), MU_OPTION_DEFAULT,
N_("use this charset to represent attachment file names"),
mu_c_string, &charset },
MU_OPTION_GROUP (N_("Other options")),
{ "part", 0, N_("PART"), MU_OPTION_DEFAULT,
N_("limit the scope of the operation to the given part"),
mu_c_string, NULL, set_part },
{ "type", 0, N_("CONTENT"), MU_OPTION_DEFAULT,
N_("operate on message part with given multipart content"),
mu_c_string, NULL, set_type },
{ "verbose", 0, NULL, MU_OPTION_DEFAULT,
N_("print additional information"),
mu_c_bool, &verbose_option },
{ "quiet", 0, NULL, MU_OPTION_DEFAULT,
N_("be quiet"),
mu_c_bool, &quiet_option },
MU_OPTION_END
};
/* *********************** Message part functions ************************* */
......@@ -555,7 +374,7 @@ msg_part_format_pool (mu_opool_t pool, msg_part_t p)
}
msg_part_t
msg_part_parse (char *str)
msg_part_parse (char const *str)
{
msg_part_t p = msg_part_create (0);
......@@ -1267,7 +1086,7 @@ mhn_message_size (mu_message_t msg, mu_off_t *psize)
*psize = 0;
mu_message_get_body (msg, &body);
if (mode_options & OPT_REALSIZE)
if (realsize_option)
{
mu_stream_t dstr = NULL, bstr = NULL;
......@@ -1389,7 +1208,7 @@ mhn_list ()
{
int rc;
if (mode_options & OPT_HEADERS)
if (headers_option)
printf (_(" msg part type/subtype size description\n"));
if (message)
......@@ -1672,7 +1491,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
if (mu_message_is_multipart (msg, &ismime) == 0 && ismime)
return 0;
if (mode_options & OPT_AUTO)
if (auto_option)
{
char *val;
int rc = mu_message_aget_decoded_attachment_name (msg, charset,
......@@ -1773,7 +1592,7 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
printf (_("storing message %s part %s as file %s\n"),
prefix, partstr, name);
if (!(mode_options & OPT_QUIET) && access (name, R_OK) == 0)
if (!quiet_option && access (name, R_OK) == 0)
{
int ok;
......@@ -2939,17 +2758,18 @@ int
main (int argc, char **argv)
{
int rc;
int index;
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
argc -= index;
argv += index;
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
if (!formfile)
mh_find_file ("mhl.headers", &formfile);
if (!isatty (0))
pause_option = 0;
if (!compose_option && !list_option && !show_option && !store_option)
show_option = 1;
signal (SIGPIPE, SIG_IGN);
if (input_file)
......@@ -2966,45 +2786,36 @@ main (int argc, char **argv)
if (!message)
return 1;
}
else if (mode == mode_compose)
if (compose_option)
{
if (argc > 1)
{
mu_error (_("extra arguments"));
return 1;
}
input_file = mh_expand_name (mu_folder_directory (),
argc == 1 ? argv[0] : "draft", NAME_ANY);
message = mh_file_to_message (NULL, input_file);
if (!message)
return 1;
if (!input_file)
{
input_file = mh_expand_name (mu_folder_directory (),
argc == 1
? argv[0] : "draft", NAME_ANY);
message = mh_file_to_message (NULL, input_file);
if (!message)
return 1;
}
rc = mhn_compose ();
}
else
{
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
}
switch (mode)
{
case mode_compose:
rc = mhn_compose ();
break;
case mode_list:
rc = mhn_list ();
break;
case mode_show:
rc = mhn_show ();
break;
case mode_store:
rc = mhn_store ();
break;
default:
abort ();
/* FIXME: Combine the three */
if (list_option)
rc = mhn_list ();
if (show_option)
rc |= mhn_show ();
if (store_option)
rc |= mhn_store ();
}
return rc ? 1 : 0;
}
......
......@@ -19,48 +19,22 @@
#include <mh.h>
static char doc[] = N_("GNU MH mhparam")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH mhparam");
static char args_doc[] = N_("[COMPONENT [COMPONENT...]]");
/* GNU options */
static struct argp_option options[] = {
{"all", ARG_ALL, NULL, 0,
N_("display all components from the MH profile. All other arguments are ignored")},
{"component", ARG_COMPONENT, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("always display the component name") },
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "all" },
{ "component", MH_OPT_BOOL },
{ NULL }
};
static int display_all;
static int display_comp_name = -1;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_ALL:
display_all = 1;
break;
case ARG_COMPONENT:
display_comp_name = is_true (arg);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "all", 0, NULL, MU_OPTION_DEFAULT,
N_("display all components from the MH profile. All other arguments are ignored"),
mu_c_bool, &display_all },
{ "component", 0, NULL, MU_OPTION_DEFAULT,
N_("always display the component name"),
mu_c_bool, &display_comp_name },
MU_OPTION_END
};
static struct {
char *comp;
char *val;
......@@ -81,7 +55,8 @@ mhparam_defval (char *comp)
}
int
mhparam_iterator (const char *comp, const char *value, void *data MU_ARG_UNUSED)
mhparam_iterator (const char *comp, const char *value,
void *data MU_ARG_UNUSED)
{
if (display_comp_name)
printf("%s:\t", comp);
......@@ -112,14 +87,10 @@ mhparam (char *comp)
int
main (int argc, char **argv)
{
int index;
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
if (display_all)
{
......@@ -129,11 +100,13 @@ main (int argc, char **argv)
}
else
{
int i;
if (display_comp_name == -1)
display_comp_name = argc - index > 1;
display_comp_name = argc > 1;
for (; index < argc; index++)
mhparam (argv[index]);
for (i = 0; i < argc; i++)
mhparam (argv[i]);
}
return 0;
}
......
......@@ -19,37 +19,9 @@
#include <mh.h>
static char doc[] = N_("GNU MH mhpath")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH mhpath");
static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ NULL }
};
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static int
mhpath (size_t num, mu_message_t msg, void *data)
{
......@@ -63,7 +35,6 @@ mhpath (size_t num, mu_message_t msg, void *data)
int
main (int argc, char **argv)
{
int index = 0;
mu_mailbox_t mbox = NULL;
mu_url_t url = NULL;
char *mhdir;
......@@ -75,9 +46,8 @@ main (int argc, char **argv)
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
mh_getopt (&argc, &argv, NULL, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
current_folder = mh_current_folder ();
/* If the only argument is `+', your MH Path is output; this
......@@ -98,7 +68,7 @@ main (int argc, char **argv)
/* If no `msgs' are specified, mhpath outputs the folder pathname
instead. */
if (index == argc)
if (argc == 0)
{
printf ("%s\n", mhdir);
exit (0);
......@@ -112,7 +82,7 @@ main (int argc, char **argv)
The "new" message may not be used as part of a message
range. */
if (argc - index == 1 && strcmp (argv[index], "new") == 0)
if (argc == 1 && strcmp (argv[0], "new") == 0)
{
mu_message_t msg = NULL;
size_t num;
......@@ -126,7 +96,7 @@ main (int argc, char **argv)
/* Mhpath expands and sorts the message list `msgs' and
writes the full pathnames of the messages to the standard
output separated by newlines. */
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
status = mu_msgset_foreach_message (msgset, mhpath, mhdir);
mu_mailbox_close (mbox);
mu_mailbox_destroy (&mbox);
......
......@@ -18,51 +18,21 @@
#include <mh.h>
static char doc[] = N_("GNU MH mhseq")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH mhseq");
static char args_doc[] = N_("[SEQUENCE]");
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify the folder to use")},
{ "uids", 'u', NULL, 0,
N_("show message UIDs (default)")},
{ "numbers", 'n', NULL, 0,
N_("show message numbers") },
{ NULL }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "uid" },
{ NULL }
};
static int uid_option = 1;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
case 'n':
uid_option = 0;
break;
case 'u':
uid_option = 1;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "uids", 0, NULL, MU_OPTION_DEFAULT,
N_("show message UIDs (default)"),
mu_c_int, &uid_option, NULL, "1" },
{ "numbers", 0, NULL, MU_OPTION_DEFAULT,
N_("show message numbers"),
mu_c_int, &uid_option, NULL, "0" },
MU_OPTION_END
};
static int
_print_number (size_t n, void *data)
{
......@@ -73,19 +43,15 @@ _print_number (size_t n, void *data)
int
main (int argc, char **argv)
{
int index;
mu_mailbox_t mbox;
mu_msgset_t msgset;
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
argc -= index;
argv += index;
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_READ);
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
......
......@@ -21,42 +21,9 @@
#include "mailutils/datetime.h"
#include <pwd.h>
static char doc[] = N_("GNU MH msgchk")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH msgchk");
static char args_doc[] = N_("USER [USER...]");
/* GNU options */
static struct argp_option options[] = {
{"date", ARG_DATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("print out the last date mail was read") },
{"nodate", ARG_NODATE, NULL, OPTION_HIDDEN,
N_("don't print out the last date mail was read") },
{"notify", ARG_NOTIFY, "all|mail|nomail", 0,
N_("produce a message upon these events") },
{"nonotify", ARG_NONOTIFY, "all|mail|nomail", 0,
N_("disable notification") },
{"host", ARG_HOST, N_("URL"), 0,
N_("check mail on this host or URL") },
{"user", ARG_USER, N_("NAME"), 0,
N_("set user name for remote mailbox access") },
{"apop", ARG_APOP, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("enable APOP") },
{"noapop", ARG_NOAPOP, NULL, OPTION_HIDDEN,
N_("disable APOP") },
{NULL}
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "date", MH_OPT_BOOL },
{ "notify", MH_OPT_ARG, "all|mail|nomail" },
{ "nonotify", MH_OPT_ARG, "all|mail|nomail" },
{ "host", MH_OPT_ARG, "host-or-url" },
{ "user", MH_OPT_ARG, "name" },
{ "apop", MH_OPT_BOOL },
{ NULL }
};
int date_option = 1;
int apop_option;
char *remote_host;
......@@ -75,55 +42,53 @@ static struct mu_kwd notifytab[] = {
{ NULL }
};
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
set_notify (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
int n;
switch (key)
if (mu_kwd_xlat_name (notifytab, arg, &n))
{
case ARG_DATE:
date_option = is_true (arg);
break;
case ARG_NODATE:
date_option = 0;
break;
case ARG_APOP:
apop_option = is_true (arg);
break;
case ARG_NOAPOP:
apop_option = 0;
break;
case ARG_NOTIFY:
if (mu_kwd_xlat_name (notifytab, arg, &n))
argp_error (state, "unknown notify argument: %s", arg);
notify |= n;
break;
case ARG_NONOTIFY:
if (mu_kwd_xlat_name (notifytab, arg, &n))
argp_error (state, "unknown notify argument: %s", arg);
notify &= ~n;
break;
case ARG_USER:
remote_user = arg;
break;
case ARG_HOST:
remote_host = arg;
break;
default:
return ARGP_ERR_UNKNOWN;
mu_parseopt_error (po, "unknown notify argument: %s", arg);
exit (po->po_exit_error);
}
return 0;
notify |= n;
}
static void
clr_notify (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
int n;
if (mu_kwd_xlat_name (notifytab, arg, &n))
{
mu_parseopt_error (po, "unknown notify argument: %s", arg);
exit (po->po_exit_error);
}
notify &= ~n;
}
static struct mu_option options[] = {
{ "date", 0, NULL, MU_OPTION_DEFAULT,
N_("print out the last date mail was read"),
mu_c_bool, &date_option },
{ "notify", 0, "all|mail|nomail", MU_OPTION_DEFAULT,
N_("produce a message upon these events"),
mu_c_string, NULL, set_notify },
{ "nonotify", 0, "all|mail|nomail", MU_OPTION_DEFAULT,
N_("disable notification"),
mu_c_string, NULL, clr_notify },
{ "host", 0, N_("URL"), MU_OPTION_DEFAULT,
N_("check mail on this host or URL"),
mu_c_string, &remote_host },
{ "user", 0, N_("NAME"), MU_OPTION_DEFAULT,
N_("set user name for remote mailbox access"),
mu_c_string, &remote_user },
{ "apop", 0, NULL, MU_OPTION_DEFAULT,
N_("enable APOP"),
mu_c_bool, &apop_option },
MU_OPTION_END
};
static char *
attach_auth_ticket (mu_mailbox_t mbox)
{
......@@ -185,7 +150,7 @@ checkmail (const char *username, int personal)
{
static mu_url_t pop_hint;
if (pop_hint)
if (!pop_hint)
{
rc = mu_url_create (&pop_hint, "pop://");
if (rc)
......@@ -382,17 +347,11 @@ checkmail (const char *username, int personal)
int
main (int argc, char **argv)
{
int index;
int rc = 0;
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
argc -= index;
argv += index;
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
if (argc == 0)
{
......
......@@ -22,119 +22,11 @@
#include <pick.h>
#include <pick-gram.h>
static char doc[] = N_("GNU MH pick")"\v"
N_("Compatibility syntax for picking a matching component is:\n\
\n\
--Component pattern\n\
\n\
where Component is the component name, containing at least one capital\n\
letter or followed by a colon, e.g.:\n\
\n\
--User-Agent Mailutils\n\
--user-agent: Mailutils\n\
\n\
Use -help to obtain a list of traditional MH options.");
static char args_doc[] = N_("[MSGLIST]");
/* GNU options */
static struct argp_option options[] = {
#define GRID 10
{ "folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon"), GRID },
#undef GRID
#define GRID 20
{ N_("Search patterns"), 0, NULL, OPTION_DOC, NULL, GRID },
{ "component", ARG_COMPONENT, N_("FIELD"), 0,
N_("search the named header field"), GRID+1},
{ "pattern", ARG_PATTERN, N_("STRING"), 0,
N_("set pattern to look for"), GRID+1 },
{ "search", 0, NULL, OPTION_ALIAS, NULL, GRID+1 },
{ "cflags", ARG_CFLAGS, N_("STRING"), 0,
N_("flags controlling the type of regular expressions. STRING must consist of one or more of the following letters: B=basic, E=extended, I=ignore case, C=case sensitive. Default is \"EI\". The flags remain in effect until the next occurrence of --cflags option. The option must occur right before --pattern or --component option (or its alias)."), GRID+1 },
{ "cc", ARG_CC, N_("STRING"), 0,
N_("same as --component cc --pattern STRING"), GRID+1 },
{ "date", ARG_DATE, N_("STRING"), 0,
N_("same as --component date --pattern STRING"), GRID+1 },
{ "from", ARG_FROM, N_("STRING"), 0,
N_("same as --component from --pattern STRING"), GRID+1 },
{ "subject", ARG_SUBJECT, N_("STRING"), 0,
N_("same as --component subject --pattern STRING"), GRID+1 },
{ "to", ARG_TO, N_("STRING"), 0,
N_("same as --component to --pattern STRING"), GRID+1 },
#undef GRID
#define GRID 30
{ N_("Date constraint operations"), 0, NULL, OPTION_DOC, NULL, GRID },
{ "datefield",ARG_DATEFIELD, N_("STRING"), 0,
N_("search in the named date header field (default is `Date:')"), GRID+1 },
{ "after", ARG_AFTER, N_("DATE"), 0,
N_("match messages after the given date"), GRID+1 },
{ "before", ARG_BEFORE, N_("DATE"), 0,
N_("match messages before the given date"), GRID+1 },
#undef GRID
#define GRID 40
{ N_("Logical operations and grouping"), 0, NULL, OPTION_DOC, NULL, GRID },
{ "and", ARG_AND, NULL, 0,
N_("logical AND (default)"), GRID+1 },
{ "or", ARG_OR, NULL, 0,
N_("logical OR"), GRID+1 },
{ "not", ARG_NOT, NULL, 0,
N_("logical NOT"), GRID+1 },
{ "lbrace", ARG_LBRACE, NULL, 0,
N_("open group"), GRID+1 },
{ "(", 0, NULL, OPTION_ALIAS, NULL, GRID+1 },
{ "rbrace", ARG_RBRACE, NULL, 0,
N_("close group"), GRID+1},
{ ")", 0, NULL, OPTION_ALIAS, NULL, GRID+1 },
#undef GRID
#define GRID 50
{ N_("Operations over the selected messages"), 0, NULL, OPTION_DOC, NULL,
GRID },
{ "list", ARG_LIST, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("list the numbers of the selected messages (default)"), GRID+1 },
{ "nolist", ARG_NOLIST, NULL, OPTION_HIDDEN, "", GRID+1 },
{ "sequence", ARG_SEQUENCE, N_("NAME"), 0,
N_("add matching messages to the given sequence"), GRID+1 },
{ "public", ARG_PUBLIC, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("create public sequence"), GRID+1 },
{ "nopublic", ARG_NOPUBLIC, NULL, OPTION_HIDDEN, "", GRID+1 },
{ "zero", ARG_ZERO, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("empty the sequence before adding messages"), GRID+1 },
{ "nozero", ARG_NOZERO, NULL, OPTION_HIDDEN, "", GRID+1 },
#undef GRID
{ NULL }
};
static char prog_doc[] = N_("GNU MH pick");
static char args_doc[] = N_("[--COMPONENT PATTERN]... [MSGLIST]");
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "component", MH_OPT_ARG, "field" },
{ "pattern", MH_OPT_ARG, "pattern" },
{ "search", MH_OPT_ARG, "pattern" },
{ "cc", MH_OPT_ARG, "pattern" },
{ "date", MH_OPT_ARG, "pattern" },
{ "from", MH_OPT_ARG, "pattern" },
{ "subject", MH_OPT_ARG, "pattern" },
{ "to", MH_OPT_ARG, "pattern" },
{ "datefield", MH_OPT_ARG, "field" },
{ "after", MH_OPT_ARG, "date" },
{ "before", MH_OPT_ARG, "date" },
{ "and" },
{ "or" },
{ "not" },
{ "lbrace" },
{ "rbrace" },
{ "list", MH_OPT_BOOL },
{ "sequence", MH_OPT_ARG, "name" },
{ "public", MH_OPT_BOOL },
{ "zero", MH_OPT_BOOL },
{ NULL }
};
static int public_option = 1;
static int zero_option = 0;
static int list = 1;
static int seq_flags = 0; /* Create public sequences;
......@@ -146,138 +38,177 @@ static mu_list_t lexlist; /* List of input tokens */
static mu_msgset_t picked_message_uids;
static void
add_sequence (char *name)
add_component_name (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
if (!seq_list && mu_list_create (&seq_list))
{
mu_error (_("cannot create sequence list"));
exit (1);
}
mu_list_append (seq_list, name);
pick_add_token (&lexlist, T_COMP, arg);
}
static void
add_component_pattern (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
pick_add_token (&lexlist, T_STRING, arg);
}
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
add_cflags (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
pick_add_token (&lexlist, T_CFLAGS, arg);
}
static void
add_comp_match (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
pick_add_token (&lexlist, T_COMP, opt->opt_default);
pick_add_token (&lexlist, T_STRING, arg);
}
static void
add_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
pick_add_token (&lexlist, T_DATEFIELD, arg);
}
static void
add_after (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
pick_add_token (&lexlist, T_AFTER, NULL);
pick_add_token (&lexlist, T_STRING, arg);
}
static void
add_before (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
pick_add_token (&lexlist, T_BEFORE, NULL);
pick_add_token (&lexlist, T_STRING, arg);
}
static void
add_and (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
pick_add_token (&lexlist, T_AND, NULL);
}
static void
add_or (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
pick_add_token (&lexlist, T_OR, NULL);
}
static void
add_not (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
pick_add_token (&lexlist, T_NOT, NULL);
}
static void
add_lbrace (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
pick_add_token (&lexlist, T_LBRACE, NULL);
}
static void
add_rbrace (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
pick_add_token (&lexlist, T_RBRACE, NULL);
}
static void
add_to_sequence (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
if (!seq_list && mu_list_create (&seq_list))
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
case ARG_SEQUENCE:
add_sequence (arg);
list = 0;
break;
case ARG_LIST:
list = is_true (arg);
break;
case ARG_NOLIST:
list = 0;
break;
case ARG_COMPONENT:
pick_add_token (&lexlist, T_COMP, arg);
break;
case ARG_PATTERN:
pick_add_token (&lexlist, T_STRING, arg);
break;
case ARG_CC:
pick_add_token (&lexlist, T_COMP, "cc");
pick_add_token (&lexlist, T_STRING, arg);
break;
case ARG_DATE:
pick_add_token (&lexlist, T_COMP, "date");
pick_add_token (&lexlist, T_STRING, arg);
break;
case ARG_FROM:
pick_add_token (&lexlist, T_COMP, "from");
pick_add_token (&lexlist, T_STRING, arg);
break;
case ARG_SUBJECT:
pick_add_token (&lexlist, T_COMP, "subject");
pick_add_token (&lexlist, T_STRING, arg);
break;
case ARG_TO:
pick_add_token (&lexlist, T_COMP, "to");
pick_add_token (&lexlist, T_STRING, arg);
break;
case ARG_DATEFIELD:
pick_add_token (&lexlist, T_DATEFIELD, arg);
break;
case ARG_AFTER:
pick_add_token (&lexlist, T_AFTER, NULL);
pick_add_token (&lexlist, T_STRING, arg);
break;
case ARG_BEFORE:
pick_add_token (&lexlist, T_BEFORE, NULL);
pick_add_token (&lexlist, T_STRING, arg);
break;
case ARG_AND:
pick_add_token (&lexlist, T_AND, NULL);
break;
case ARG_OR:
pick_add_token (&lexlist, T_OR, NULL);
break;
case ARG_NOT:
pick_add_token (&lexlist, T_NOT, NULL);
break;
case ARG_LBRACE:
pick_add_token (&lexlist, T_LBRACE, NULL);
break;
case ARG_RBRACE:
pick_add_token (&lexlist, T_RBRACE, NULL);
break;
case ARG_CFLAGS:
pick_add_token (&lexlist, T_CFLAGS, arg);
break;
case ARG_PUBLIC:
if (is_true (arg))
seq_flags &= ~SEQ_PRIVATE;
else
seq_flags |= SEQ_PRIVATE;
break;
case ARG_NOPUBLIC:
seq_flags |= SEQ_PRIVATE;
break;
case ARG_ZERO:
if (is_true (arg))
seq_flags |= SEQ_ZERO;
else
seq_flags &= ~SEQ_ZERO;
break;
case ARG_NOZERO:
seq_flags &= ~SEQ_ZERO;
break;
default:
return ARGP_ERR_UNKNOWN;
mu_error (_("cannot create sequence list"));
exit (1);
}
return 0;
mu_list_append (seq_list, mu_strdup (arg));
list = 0;
}
static struct mu_option options[] = {
MU_OPTION_GROUP (N_("Search patterns")),
{ "component", 0, N_("FIELD"), MU_OPTION_DEFAULT,
N_("search the named header field"),
mu_c_string, NULL, add_component_name },
{ "pattern", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("set pattern to look for"),
mu_c_string, NULL, add_component_pattern },
{ "search", 0, NULL, MU_OPTION_ALIAS },
{ "cflags", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("flags controlling the type of regular expressions. "
"STRING must consist of one or more of the following letters: "
"B=basic, E=extended, I=ignore case, C=case sensitive. "
"Default is \"EI\". The flags remain in effect until the next "
"occurrence of --cflags option. The option must occur right "
"before --pattern or --component option (or its alias)."),
mu_c_string, NULL, add_cflags },
{ "cc", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("search for Cc matching STRING"),
mu_c_string, NULL, add_comp_match, "cc" },
{ "date", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("search for Date matching STRING"),
mu_c_string, NULL, add_comp_match, "date" },
{ "from", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("search for From matching STRING"),
mu_c_string, NULL, add_comp_match, "from" },
{ "subject", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("search for Subject matching STRING"),
mu_c_string, NULL, add_comp_match, "subject" },
{ "to", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("search for To matching STRING"),
mu_c_string, NULL, add_comp_match, "to" },
MU_OPTION_GROUP (N_("Date constraint operations")),
{ "datefield", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("search in the named date header field (default is `Date:')"),
mu_c_string, NULL, add_datefield },
{ "after", 0, N_("DATE"), MU_OPTION_DEFAULT,
N_("match messages after the given date"),
mu_c_string, NULL, add_after },
{ "before", 0, N_("DATE"), MU_OPTION_DEFAULT,
N_("match messages before the given date"),
mu_c_string, NULL, add_before },
MU_OPTION_GROUP (N_("Logical operations and grouping")),
{ "and", 0, NULL, MU_OPTION_DEFAULT,
N_("logical AND (default)"),
mu_c_string, NULL, add_and },
{ "or", 0, NULL, MU_OPTION_DEFAULT,
N_("logical OR"),
mu_c_string, NULL, add_or },
{ "not", 0, NULL, MU_OPTION_DEFAULT,
N_("logical NOT"),
mu_c_string, NULL, add_not },
{ "lbrace", 0, NULL, MU_OPTION_DEFAULT,
N_("open group"),
mu_c_string, NULL, add_lbrace },
{ "(", 0, NULL, MU_OPTION_ALIAS },
{ "rbrace", 0, NULL, MU_OPTION_DEFAULT,
N_("close group"),
mu_c_string, NULL, add_rbrace },
{ ")", 0, NULL, MU_OPTION_ALIAS },
MU_OPTION_GROUP (N_("Operations over the selected messages")),
{ "list", 0, NULL, MU_OPTION_ALIAS,
N_("list the numbers of the selected messages (default)"),
mu_c_bool, &list },
{ "sequence", 0, N_("NAME"), MU_OPTION_DEFAULT,
N_("add matching messages to the given sequence"),
mu_c_string, NULL, add_to_sequence },
{ "public", 0, NULL, MU_OPTION_DEFAULT,
N_("create public sequence"),
mu_c_bool, &public_option },
{ "zero", 0, NULL, MU_OPTION_DEFAULT,
N_("empty the sequence before adding messages"),
mu_c_bool, &zero_option },
MU_OPTION_END
};
static int
pick_message (size_t num, mu_message_t msg, void *data)
{
......@@ -301,89 +232,56 @@ action_add (void *item, void *data)
return 0;
}
void
pick_help_hook (void)
static void
parse_comp_match (int *pargc, char **argv)
{
printf ("\n");
printf (_("To match another component, use:\n\n"));
printf (_(" --Component pattern\n\n"));
printf (_("Note, that the component name must either be capitalized,\n"
"or followed by a colon.\n"));
printf ("\n");
}
/* NOTICE: For compatibility with RAND MH we have to support
the following command line syntax:
--COMP STRING
where `COMP' may be any string and which is equivalent to
`--component FIELD --pattern STRING'. Obviously this is in conflict
with the usual GNU long options paradigm which requires that any
unrecognized long option produce an error. The following
compromise solution is used:
The arguments `--COMP STRING' is recognized as a component matching
request if any of the following conditions is met:
1. The word `COMP' contains at least one capital letter. E.g.:
int i, j;
int argc = *pargc;
--User-Agent Mailutils
2. The word `COMP' ends with a colon, e.g.:
--user-agent: Mailutils
3. Standard input is not connected to a terminal. This is always
true when pick is invoked from mh-pick.el Emacs module.
*/
for (i = j = 0; i < argc; i++)
{
if (strncmp (argv[i], "--", 2) == 0)
{
if (++i < argc)
{
pick_add_token (&lexlist, T_COMP, argv[i-1] + 2);
pick_add_token (&lexlist, T_STRING, argv[i]);
}
else
{
mu_error (_("%s: must be followed by a pattern"), argv[i-1]);
exit (1);
}
}
else
argv[j++] = argv[i];
}
argv[j] = NULL;
*pargc = j;
}
int
main (int argc, char **argv)
{
int status;
int index;
mu_mailbox_t mbox;
mu_msgset_t msgset;
int interactive = mh_interactive_mode_p ();
MU_APP_INIT_NLS ();
for (index = 1; index < argc; index++)
{
int colon = 0, cpos;
if (argv[index][0] == '-' && argv[index][1] == '-' &&
!strchr (argv[index], '=') &&
(!interactive ||
(colon = argv[index][cpos = strlen (argv[index]) - 1] == ':') ||
*mu_str_skip_class_comp (argv[index], MU_CTYPE_UPPER)) &&
index + 1 < argc)
{
if (colon)
{
cpos -= 2;
mu_asprintf (&argv[index], "--component=%*.*s", cpos, cpos,
argv[index] + 2);
}
else
mu_asprintf (&argv[index], "--component=%s", argv[index] + 2);
mu_asprintf (&argv[index + 1], "--pattern=%s", argv[index + 1]);
index++;
}
}
mh_help_hook = pick_help_hook;
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option,
args_doc, doc, opt_handler, NULL, &index);
mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
parse_comp_match (&argc, argv);
if (pick_parse (lexlist))
return 1;
seq_flags = (public_option ? 0 : SEQ_PRIVATE) | (zero_option ? SEQ_ZERO : 0);
mbox = mh_open_folder (mh_current_folder (),
seq_list ? MU_STREAM_RDWR : MU_STREAM_READ);
argc -= index;
argv += index;
if (seq_list)
mu_msgset_create (&picked_message_uids, NULL, MU_MSGSET_UID);
......
......@@ -56,6 +56,6 @@ struct node
} v;
};
void pick_add_token (mu_list_t *list, int tok, char *val);
void pick_add_token (mu_list_t *list, int tok, char const *val);
int pick_parse (mu_list_t toklist);
int pick_eval (mu_message_t msg);
......
......@@ -189,28 +189,28 @@ tokname (int tok)
switch (tok)
{
case T_DATEFIELD:
return "--datefield";
return "-datefield";
case T_BEFORE:
return "--before";
return "-before";
case T_AFTER:
return "--after";
return "-after";
case T_LBRACE:
return "--lbrace";
return "-lbrace";
case T_RBRACE:
return "--rbrace";
return "-rbrace";
case T_OR:
return "--or";
return "-or";
case T_AND:
return "--and";
return "-and";
case T_NOT:
return "--not";
return "-not";
}
return NULL;
}
......@@ -236,7 +236,7 @@ yyerror (const char *s)
}
void
pick_add_token (mu_list_t *list, int tok, char *val)
pick_add_token (mu_list_t *list, int tok, char const *val)
{
struct token *tp;
int rc;
......
......@@ -19,98 +19,33 @@
#include <mh.h>
#include "prompter.h"
static char doc[] = N_("GNU MH prompter")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH prompter");
static char args_doc[] = N_("FILE");
enum {
ARG_ERASE=256,
ARG_KILL,
ARG_PREPEND,
ARG_NOPREPEND,
ARG_RAPID,
ARG_NORAPID,
ARG_DOTEOF,
ARG_NODOTEOF
};
static struct argp_option options[] = {
{ "erase", ARG_ERASE, N_("CHAR"), 0,
N_("set erase character") },
{ "kill", ARG_KILL, N_("CHAR"), 0,
N_("set kill character") },
{ "prepend", ARG_PREPEND, N_("BOOL"), 0,
N_("prepend user input to the message body") },
{ "noprepend", ARG_NOPREPEND, NULL, OPTION_HIDDEN,
NULL },
{ "rapid", ARG_RAPID, N_("BOOL"), 0,
N_("do not display message body") },
{ "norapid", ARG_NORAPID, NULL, OPTION_HIDDEN,
NULL },
{ "doteof", ARG_DOTEOF, N_("BOOL"), 0,
N_("a period on a line marks end-of-file") },
{ "nodoteof", ARG_NODOTEOF, NULL, OPTION_HIDDEN,
NULL },
{ NULL }
};
struct mh_option mh_option[] = {
{ "erase", MH_OPT_ARG, "chr" },
{ "kill", MH_OPT_ARG, "chr" },
{ "prepend", MH_OPT_BOOL },
{ "rapid", MH_OPT_BOOL },
{ "doteof", MH_OPT_BOOL },
{ NULL }
};
char *erase_seq;
char *kill_seq;
int prepend_option;
int rapid_option;
int doteof_option;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_ERASE:
erase_seq = arg;
break;
case ARG_KILL:
kill_seq = arg;
break;
case ARG_PREPEND:
prepend_option = is_true (arg);
break;
case ARG_NOPREPEND:
prepend_option = 0;
break;
case ARG_RAPID:
rapid_option = is_true (arg);
break;
case ARG_NORAPID:
rapid_option = 0;
break;
case ARG_DOTEOF:
doteof_option = is_true (arg);
break;
case ARG_NODOTEOF:
doteof_option = 0;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "erase", 0, N_("CHAR"), MU_OPTION_DEFAULT,
N_("set erase character"),
mu_c_string, &erase_seq },
{ "kill", 0, N_("CHAR"), MU_OPTION_DEFAULT,
N_("set kill character"),
mu_c_string, &kill_seq },
{ "prepend", 0, NULL, MU_OPTION_DEFAULT,
N_("prepend user input to the message body"),
mu_c_bool, &prepend_option },
{ "rapid", 0, NULL, MU_OPTION_DEFAULT,
N_("do not display message body"),
mu_c_bool, &rapid_option },
{ "doteof", 0, NULL, MU_OPTION_DEFAULT,
N_("a period on a line marks end-of-file"),
mu_c_bool, &doteof_option },
MU_OPTION_END
};
static int
is_empty_string (const char *str)
......@@ -142,7 +77,6 @@ mu_stream_t strout;
int
main (int argc, char **argv)
{
int index;
int rc;
mu_stream_t in, tmp;
mu_message_t msg;
......@@ -156,16 +90,20 @@ main (int argc, char **argv)
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
if (index == argc)
if (argc == 0)
{
mu_error (_("file name not given"));
exit (1);
}
file = argv[index];
else if (argc > 1)
{
mu_error (_("too many arguments"));
exit (1);
}
file = argv[0];
prompter_init ();
if (erase_seq)
......@@ -178,7 +116,7 @@ main (int argc, char **argv)
mu_error (_("cannot open stdout: %s"), mu_strerror (rc));
return 1;
}
if ((rc = mu_file_stream_create (&in, file, MU_STREAM_RDWR)))
{
mu_error (_("cannot open input file `%s': %s"),
......@@ -186,14 +124,13 @@ main (int argc, char **argv)
return 1;
}
rc = mu_stream_to_message (in, &msg);
mu_stream_unref (in);
if (rc)
{
mu_error (_("input stream %s is not a message (%s)"),
file, mu_strerror (rc));
return 1;
}
if ((rc = mu_temp_file_stream_create (&tmp, NULL, 0)))
{
mu_error (_("Cannot open temporary file: %s"),
......
......@@ -23,39 +23,9 @@
#include <errno.h>
#include <fcntl.h>
static char doc[] = N_("GNU MH refile")"\v"
N_("Options marked with `*' are not yet implemented.\n\
Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH refile");
static char args_doc[] = N_("MSGLIST FOLDER [FOLDER...]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{"draft", ARG_DRAFT, NULL, 0,
N_("use <mh-dir>/draft as the source message")},
{"copy", ARG_LINK, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("preserve the source folder copy")},
{"link", 0, NULL, OPTION_ALIAS, NULL},
{"preserve", ARG_PRESERVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* try to preserve message sequence numbers")},
{"source", ARG_SOURCE, N_("FOLDER"), 0,
N_("specify source folder; it will become the current folder after the program exits")},
{"src", 0, NULL, OPTION_ALIAS, NULL},
{"file", ARG_FILE, N_("FILE"), 0, N_("use FILE as the source message")},
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "file", MH_OPT_ARG, "input-file"},
{ "draft" },
{ "link", MH_OPT_BOOL },
{ "preserve", MH_OPT_BOOL },
{ "src", MH_OPT_ARG, "folder" },
{ NULL }
};
int link_flag = 0;
int preserve_flag = 0;
char *source_file = NULL;
......@@ -72,9 +42,40 @@ add_folder (const char *folder)
}
mu_list_append (folder_name_list, mu_strdup (folder));
}
static void
add_folder_option (struct mu_parseopt *po, struct mu_option *opt,
const char *arg)
{
add_folder (arg);
}
static struct mu_option options[] = {
{ "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify folder to operate upon"),
mu_c_string, NULL, add_folder_option },
{ "draft", 0, NULL, MU_OPTION_DEFAULT,
N_("use <mh-dir>/draft as the source message"),
mu_c_string, &source_file, NULL, "draft" },
{ "copy", 0, NULL, MU_OPTION_DEFAULT,
N_("preserve the source folder copy"),
mu_c_bool, &link_flag },
{ "link", 0, NULL, MU_OPTION_ALIAS },
{ "preserve", 0, NULL, MU_OPTION_HIDDEN,
N_("try to preserve message sequence numbers"),
mu_c_string, NULL, mh_opt_notimpl_warning },
{ "source", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify source folder; it will become the current folder after the program exits"),
mu_c_string, NULL, mh_opt_set_folder },
{ "src", 0, NULL, MU_OPTION_ALIAS },
{ "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("use FILE as the source message"),
mu_c_string, &source_file },
MU_OPTION_END
};
void
open_folders ()
open_folders (void)
{
int rc;
mu_iterator_t itr;
......@@ -139,47 +140,11 @@ _close_folder (void *unused, mu_mailbox_t mbox)
}
void
close_folders ()
close_folders (void)
{
enumerate_folders (_close_folder, NULL);
}
static int
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_FOLDER:
add_folder (arg);
break;
case ARG_DRAFT:
source_file = "draft";
break;
case ARG_LINK:
link_flag = is_true(arg);
break;
case ARG_PRESERVE:
mh_opt_notimpl_warning ("-preserve");
preserve_flag = is_true(arg);
break;
case ARG_SOURCE:
mh_set_current_folder (arg);
break;
case ARG_FILE:
source_file = arg;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
void
refile_folder (void *data, mu_mailbox_t mbox)
{
......@@ -216,7 +181,6 @@ refile_iterator (size_t num, mu_message_t msg, void *data)
int
main (int argc, char **argv)
{
int index;
mu_msgset_t msgset;
mu_mailbox_t mbox;
int status, i, j;
......@@ -224,13 +188,7 @@ main (int argc, char **argv)
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
argc -= index;
argv += index;
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
/* Collect any surplus folders */
for (i = j = 0; i < argc; i++)
{
......
......@@ -22,89 +22,9 @@
#include <sys/stat.h>
#include <unistd.h>
static char doc[] = N_("GNU MH repl")"\v"
N_("Options marked with `*' are not yet implemented.\n\
Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH repl");
static char args_doc[] = N_("[+FOLDER] [MESSAGE]");
/* GNU options */
static struct argp_option options[] = {
{"annotate", ARG_ANNOTATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("add Replied: header to the message being replied to")},
{"build", ARG_BUILD, 0, 0,
N_("build the draft and quit immediately")},
{"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
N_("specify the folder for message drafts")},
{"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0,
N_("undo the effect of the last --draftfolder option")},
{"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0,
N_("invoke the draftmessage facility")},
{"cc", ARG_CC, "{all|to|cc|me}", 0,
N_("specify whom to place on the Cc: list of the reply")},
{"nocc", ARG_NOCC, "{all|to|cc|me}", 0,
N_("specify whom to remove from the Cc: list of the reply")},
{"folder", ARG_FOLDER, N_("FOLDER"), 0, N_("specify folder to operate upon")},
{"group", ARG_GROUP, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("construct a group or followup reply") },
{"editor", ARG_EDITOR, N_("PROG"), 0, N_("set the editor program to use")},
{"noedit", ARG_NOEDIT, 0, 0, N_("suppress the initial edit")},
{"fcc", ARG_FCC, N_("FOLDER"), 0, N_("set the folder to receive Fcc's")},
{"filter", ARG_FILTER, N_("MHL-FILTER"), 0,
N_("set the mhl filter to preprocess the body of the message being replied")},
{"form", ARG_FORM, N_("FILE"), 0, N_("read format from given file")},
{"format", ARG_FORMAT, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("include a copy of the message being replied; the message will be processed using either the default filter \"mhl.reply\", or the filter specified by --filter option") },
{"noformat", ARG_NOFORMAT, 0, OPTION_HIDDEN, "" },
{"inplace", ARG_INPLACE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* annotate the message in place")},
{"query", ARG_QUERY, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* query for addresses to place in To: and Cc: lists")},
{"width", ARG_WIDTH, N_("NUMBER"), 0, N_("set output width")},
{"whatnowproc", ARG_WHATNOWPROC, N_("PROG"), 0,
N_("set the replacement for whatnow program")},
{"nowhatnowproc", ARG_NOWHATNOWPROC, NULL, 0,
N_("don't run whatnowproc")},
{"use", ARG_USE, N_("BOOL"), OPTION_ARG_OPTIONAL, N_("use draft file preserved after the last session") },
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "annotate", MH_OPT_BOOL },
{ "build" },
{ "cc", MH_OPT_ARG, "all/to/cc/me"},
{ "nocc", MH_OPT_ARG, "all/to/cc/me"},
{ "form", MH_OPT_ARG, "formatfile"},
{ "width", MH_OPT_ARG, "number"},
{ "draftfolder", MH_OPT_ARG, "folder"},
{ "nodraftfolder" },
{ "draftmessage" },
{ "editor", MH_OPT_ARG, "program"},
{ "noedit" },
{ "fcc", MH_OPT_ARG, "folder"},
{ "filter", MH_OPT_ARG, "program"},
{ "format", MH_OPT_BOOL },
{ "group", MH_OPT_BOOL },
{ "inplace", MH_OPT_BOOL },
{ "query", MH_OPT_BOOL },
{ "whatnowproc", MH_OPT_ARG, "program"},
{ "nowhatnowproc" },
{ NULL }
};
static char default_format_str[] =
"%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)"
"%<(nonnull)%(void(width))%(putaddr To: )\\n%>"
"%(lit)%<(rcpt to)%(formataddr{to})%>%<(rcpt cc)%(formataddr{cc})%>%<(rcpt me)%(formataddr(me))%>"
"%<(nonnull)%(void(width))%(putaddr cc: )\\n%>"
"%<{fcc}Fcc: %{fcc}\\n%>"
"%<{subject}Subject: Re: %(unre{subject})\\n%>"
"%(lit)%(concat(in_reply_to))%<(nonnull)%(void(width))%(printhdr In-reply-to: )\\n%>"
"%(lit)%(concat(references))%<(nonnull)%(void(width))%(printhdr References: )\\n%>"
"X-Mailer: MH \\(%(package_string)\\)\\n"
"--------\n";
static char *format_str = NULL;
static mh_format_t format;
static int width = 80;
......@@ -114,12 +34,11 @@ static int initial_edit = 1;
static const char *whatnowproc;
static mu_msgset_t msgset;
static mu_mailbox_t mbox;
static int build_only = 0; /* --build flag */
static int nowhatnowproc = 0; /* --nowhatnowproc */
static int query_mode = 0; /* --query flag */
static int use_draft = 0; /* --use flag */
static char *mhl_filter = NULL; /* --filter flag */
static int annotate; /* --annotate flag */
static int build_only = 0; /* -build flag */
static int nowhatnowproc = 0; /* -nowhatnowproc */
static int use_draft = 0; /* -use flag */
static char *mhl_filter = NULL; /* -filter flag */
static int annotate; /* -annotate flag */
static char *draftmessage = "new";
static const char *draftfolder = NULL;
static mu_opool_t fcc_pool;
......@@ -136,146 +55,136 @@ decode_cc_flag (const char *opt, const char *arg)
}
return rc;
}
static void
set_cc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
rcpt_mask |= decode_cc_flag ("-cc", arg);
}
static void
clr_cc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
rcpt_mask &= ~decode_cc_flag ("-nocc", arg);
}
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
set_fcc (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
if (!has_fcc)
{
case ARGP_KEY_INIT:
draftfolder = mh_global_profile_get ("Draft-Folder", NULL);
whatnowproc = mh_global_profile_get ("whatnowproc", NULL);
break;
case ARG_ANNOTATE:
annotate = is_true (arg);
break;
case ARG_BUILD:
build_only = 1;
break;
case ARG_CC:
rcpt_mask |= decode_cc_flag ("-cc", arg);
break;
mu_opool_create (&fcc_pool, 1);
has_fcc = 1;
}
else
mu_opool_append (fcc_pool, ", ", 2);
mu_opool_appendz (fcc_pool, arg);
}
case ARG_NOCC:
rcpt_mask &= ~decode_cc_flag ("-nocc", arg);
break;
case ARG_DRAFTFOLDER:
draftfolder = arg;
break;
case ARG_EDITOR:
wh_env.editor = arg;
break;
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
static void
set_whatnowproc (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
whatnowproc = mu_strdup (arg);
nowhatnowproc = 0;
}
case ARG_FORM:
static void
set_group (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
if (strcmp (arg, "1") == 0)
{
if (mh_read_formfile ("replgroupcomps", &format_str))
exit (1);
rcpt_mask |= RCPT_ALL;
}
else
{
free (format_str);
format_str = NULL;
if (mh_read_formfile (arg, &format_str))
exit (1);
break;
case ARG_GROUP:
if (is_true (arg))
{
if (mh_read_formfile ("replgroupcomps", &format_str))
exit (1);
rcpt_mask |= RCPT_ALL;
}
else
{
free (format_str);
format_str = NULL;
}
break;
case ARG_DRAFTMESSAGE:
draftmessage = arg;
break;
case ARG_USE:
use_draft = is_true (arg);
break;
case ARG_WIDTH:
width = strtoul (arg, NULL, 0);
if (!width)
{
argp_error (state, _("invalid width"));
exit (1);
}
break;
case ARG_NODRAFTFOLDER:
draftfolder = NULL;
break;
case ARG_NOEDIT:
initial_edit = 0;
break;
case ARG_QUERY:
query_mode = is_true (arg);
if (query_mode)
mh_opt_notimpl_warning ("-query");
break;
case ARG_FILTER:
mh_find_file (arg, &mhl_filter);
break;
case ARG_FORMAT:
if (is_true (arg))
mh_find_file ("mhl.repl", &mhl_filter);
else
mhl_filter = NULL;
break;
case ARG_NOFORMAT:
mhl_filter = NULL;
break;
case ARG_FCC:
if (!has_fcc)
{
mu_opool_create (&fcc_pool, 1);
has_fcc = 1;
}
else
mu_opool_append (fcc_pool, ", ", 2);
mu_opool_appendz (fcc_pool, arg);
break;
case ARG_INPLACE:
mh_opt_notimpl_warning ("-inplace");
break;
case ARG_WHATNOWPROC:
whatnowproc = arg;
break;
case ARG_NOWHATNOWPROC:
nowhatnowproc = 1;
break;
case ARGP_KEY_FINI:
if (!format_str)
format_str = default_format_str;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "annotate", 0, NULL, MU_OPTION_DEFAULT,
N_("add Replied: header to the message being replied to"),
mu_c_bool, &annotate },
{ "build", 0, NULL, MU_OPTION_DEFAULT,
N_("build the draft and quit immediately"),
mu_c_bool, &build_only },
{ "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify the folder for message drafts"),
mu_c_string, &draftfolder },
{ "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
N_("undo the effect of the last --draftfolder option"),
mu_c_string, &draftfolder, mh_opt_clear_string },
{ "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT,
N_("invoke the draftmessage facility"),
mu_c_string, &draftmessage },
{ "cc", 0, "{all|to|cc|me}", 0,
N_("specify whom to place on the Cc: list of the reply"),
mu_c_string, NULL, set_cc },
{ "nocc", 0, "{all|to|cc|me}", 0,
N_("specify whom to remove from the Cc: list of the reply"),
mu_c_string, NULL, clr_cc },
{ "group", 0, NULL, MU_OPTION_DEFAULT,
N_("construct a group or followup reply"),
mu_c_string, NULL, set_group },
{ "editor", 0, N_("PROG"), MU_OPTION_DEFAULT,
N_("set the editor program to use"),
mu_c_string, &wh_env.editor },
{ "noedit", 0, NULL, MU_OPTION_DEFAULT,
N_("suppress the initial edit"),
mu_c_int, &initial_edit, NULL, "0" },
{ "fcc", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("set the folder to receive Fcc's"),
mu_c_string, NULL, set_fcc },
{ "filter", 0, N_("MHL-FILTER"), MU_OPTION_DEFAULT,
N_("set the mhl filter to preprocess the body of the message being replied"),
mu_c_string, &mhl_filter, mh_opt_find_file },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file") ,
mu_c_string, &format_str, mh_opt_read_formfile },
{ "format", 0, NULL, MU_OPTION_DEFAULT,
N_("include a copy of the message being replied; the message will be processed using either the default filter \"mhl.reply\", or the filter specified by --filter option"),
mu_c_string, &mhl_filter, mh_opt_find_file, "mhl.repl" },
{ "noformat", 0, NULL, MU_OPTION_DEFAULT,
N_("cancels the effect of the recent -format option"),
mu_c_string, &mhl_filter, mh_opt_clear_string },
{ "inplace", 0, NULL, MU_OPTION_HIDDEN,
N_("annotate the message in place"),
mu_c_string, NULL, mh_opt_notimpl_warning },
{ "query", 0, NULL, MU_OPTION_HIDDEN,
N_("query for addresses to place in To: and Cc: lists"),
mu_c_string, NULL, mh_opt_notimpl_warning },
{ "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output width"),
mu_c_int, &width },
{ "whatnowproc", 0, N_("PROG"), MU_OPTION_DEFAULT,
N_("set the replacement for whatnow program"),
mu_c_string, NULL, set_whatnowproc },
{ "nowhatnowproc", 0, NULL, MU_OPTION_DEFAULT,
N_("don't run whatnowproc"),
mu_c_int, &nowhatnowproc, NULL, "1" },
{ "use", 0, NULL, MU_OPTION_DEFAULT,
N_("use draft file preserved after the last session"),
mu_c_bool, &use_draft },
MU_OPTION_END
};
static char default_format_str[] =
"%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)"
"%<(nonnull)%(void(width))%(putaddr To: )\\n%>"
"%(lit)%<(rcpt to)%(formataddr{to})%>%<(rcpt cc)%(formataddr{cc})%>%<(rcpt me)%(formataddr(me))%>"
"%<(nonnull)%(void(width))%(putaddr cc: )\\n%>"
"%<{fcc}Fcc: %{fcc}\\n%>"
"%<{subject}Subject: Re: %(unre{subject})\\n%>"
"%(lit)%(concat(in_reply_to))%<(nonnull)%(void(width))%(printhdr In-reply-to: )\\n%>"
"%(lit)%(concat(references))%<(nonnull)%(void(width))%(printhdr References: )\\n%>"
"X-Mailer: MH \\(%(package_string)\\)\\n"
"--------\n";
void
make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
{
......@@ -396,15 +305,20 @@ make_draft (mu_mailbox_t mbox, int disp, struct mh_whatnow_env *wh)
int
main (int argc, char **argv)
{
int index, rc;
int rc;
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
draftfolder = mh_global_profile_get ("Draft-Folder", NULL);
whatnowproc = mh_global_profile_get ("whatnowproc", NULL);
mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
if (!format_str)
format_str = default_format_str;
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
if (mh_format_parse (format_str, &format))
{
mu_error (_("Bad format string"));
......@@ -412,7 +326,7 @@ main (int argc, char **argv)
}
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
if (!mh_msgset_single_message (msgset))
{
mu_error (_("only one message at a time!"));
......
......@@ -28,29 +28,9 @@
#include <dirent.h>
static char doc[] = N_("GNU MH rmf")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH rmf");
static char args_doc[] = N_("[+FOLDER]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify the folder to delete")},
{"interactive", ARG_INTERACTIVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("interactive mode: ask for confirmation before removing each folder")},
{"nointeractive", ARG_NOINTERACTIVE, NULL, OPTION_HIDDEN, ""},
{"recursive", ARG_RECURSIVE, NULL, 0,
N_("recursively delete all subfolders")},
{"norecursive", ARG_NORECURSIVE, NULL, OPTION_HIDDEN, ""},
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "interactive", MH_OPT_BOOL },
{ 0 }
};
int explicit_folder; /* Was the folder explicitly given */
int interactive; /* Ask for confirmation before deleting */
int recursive; /* Recursively process all the sub-directories */
......@@ -59,38 +39,26 @@ static char *cur_folder_path; /* Full pathname of the current folder */
static char *folder_name; /* Name of the (topmost) folder to be
deleted */
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
set_folder (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
{
case ARG_FOLDER:
explicit_folder = 1;
folder_name = arg;
break;
case ARG_INTERACTIVE:
interactive = is_true (arg);
break;
case ARG_NOINTERACTIVE:
interactive = 0;
break;
case ARG_RECURSIVE:
recursive = is_true (arg);
break;
case ARG_NORECURSIVE:
recursive = 0;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
explicit_folder = 1;
folder_name = mu_strdup (arg);
}
static struct mu_option options[] = {
{ "folder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify the folder to delete"),
mu_c_string, NULL, set_folder },
{ "interactive", 0, NULL, MU_OPTION_DEFAULT,
N_("interactive mode: ask for confirmation before removing each folder"),
mu_c_bool, &interactive },
{ "recursive", 0, NULL, MU_OPTION_DEFAULT,
N_("recursively delete all subfolders"),
mu_c_bool, &recursive },
MU_OPTION_END
};
static char *
current_folder_path (void)
{
......@@ -185,9 +153,7 @@ main (int argc, char **argv)
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, NULL);
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
cur_folder_path = current_folder_path ();
......
......@@ -19,37 +19,9 @@
#include <mh.h>
static char doc[] = N_("GNU MH rmm")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH rmm");
static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ NULL }
};
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static int
rmm (size_t num, mu_message_t msg, void *data)
{
......@@ -79,7 +51,6 @@ rmseq (const char *name, const char *value, void *data)
int
main (int argc, char **argv)
{
int index = 0;
mu_mailbox_t mbox;
mu_msgset_t msgset;
int status;
......@@ -88,13 +59,12 @@ main (int argc, char **argv)
/* Native Language Support */
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
mh_getopt (&argc, &argv, NULL, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
mh_msgset_parse (&msgset, mbox, argc - index, argv + index, "cur");
mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
status = mu_msgset_foreach_message (msgset, rmm, NULL);
......
......@@ -26,7 +26,7 @@
#include <time.h>
#include <mailutils/observer.h>
static char progdoc[] = N_("GNU MH scan");
static char prog_doc[] = N_("GNU MH scan");
static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
static int clear;
......@@ -107,7 +107,7 @@ main (int argc, char **argv)
MU_APP_INIT_NLS ();
mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, progdoc, NULL);
args_doc, prog_doc, NULL);
if (mh_format_parse (format_str, &format))
{
......
......@@ -23,91 +23,13 @@
#include <stdarg.h>
#include <pwd.h>
static char doc[] = N_("GNU MH send")"\v"
N_("Options marked with `*' are not yet implemented.\n\
Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH send");
static char args_doc[] = N_("FILE [FILE...]");
/* GNU options */
static struct argp_option options[] = {
{"alias", ARG_ALIAS, N_("FILE"), 0,
N_("specify additional alias file") },
{"draft", ARG_DRAFT, NULL, 0,
N_("use prepared draft") },
{"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
N_("specify the folder for message drafts") },
{"draftmessage", ARG_DRAFTMESSAGE, N_("MSG"), 0,
N_("use MSG from the draftfolder as a draft") },
{"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0,
N_("undo the effect of the last --draftfolder option") },
{"filter", ARG_FILTER, N_("FILE"), 0,
N_("* use filter FILE to preprocess the body of the message") },
{"nofilter", ARG_NOFILTER, NULL, 0,
N_("* undo the effect of the last --filter option") },
{"format", ARG_FORMAT, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* reformat To: and Cc: addresses") },
{"noformat", ARG_NOFORMAT, NULL, OPTION_HIDDEN, "" },
{"forward", ARG_FORWARD, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* in case of failure forward the draft along with the failure notice to the sender") },
{"noforward", ARG_NOFORWARD, NULL, OPTION_HIDDEN, "" },
{"mime", ARG_MIME, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("* use MIME encapsulation") },
{"nomime", ARG_NOMIME, NULL, OPTION_HIDDEN, "" },
{"msgid", ARG_MSGID, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("add Message-ID: field") },
{"nomsgid", ARG_NOMSGID, NULL, OPTION_HIDDEN, ""},
{"push", ARG_PUSH, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("run in the background") },
{"nopush", ARG_NOPUSH, NULL, OPTION_HIDDEN, "" },
{"preserve", ARG_PRESERVE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("keep draft files") },
{"keep", 0, NULL, OPTION_ALIAS, NULL},
{"split", ARG_SPLIT, N_("SECONDS"), 0,
N_("split the draft into several partial messages and send them with SECONDS interval") },
{"chunksize", ARG_CHUNKSIZE, N_("NUMBER"), 0,
N_("set the size of chunk for --split (in bytes)") },
{"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("print the transcript of interactions with the transport system") },
{"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "" },
{"watch", ARG_WATCH, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("monitor the delivery of mail") },
{"nowatch", ARG_NOWATCH, NULL, OPTION_HIDDEN, "" },
{"width", ARG_WIDTH, N_("NUMBER"), 0,
N_("* make header fields no longer than NUMBER columns") },
{ 0 }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "alias", MH_OPT_ARG, "aliasfile" },
{ "draft" },
{ "draftfolder", MH_OPT_ARG, "folder" },
{ "draftmessage", MH_OPT_ARG, "message" },
{ "nodraftfolder" },
{ "filter", MH_OPT_ARG, "filterfile" },
{ "nofilter" },
{ "format", MH_OPT_BOOL },
{ "forward", MH_OPT_BOOL },
{ "mime", MH_OPT_BOOL },
{ "msgid", MH_OPT_BOOL },
{ "push", MH_OPT_BOOL },
{ "preserve", MH_OPT_BOOL },
{ "keep", MH_OPT_BOOL },
{ "split", MH_OPT_ARG, "seconds" },
{ "verbose", MH_OPT_BOOL },
{ "watch", MH_OPT_BOOL },
{ "width" },
{ NULL }
};
static const char *draftfolder; /* Use this draft folder */
static int use_draftfolder = 1;
static int use_draft;
static int reformat_recipients; /* --format option */
static int forward_notice; /* Forward the failure notice to the sender,
--forward flag */
static int mime_encaps; /* Use MIME encapsulation */
static int append_msgid; /* Append Message-ID: header */
static int background; /* Operate in the background */
......@@ -117,7 +39,6 @@ static unsigned long split_interval; /* Interval in seconds between sending two
static size_t split_size = 76*632; /* Size of split parts */
static int verbose; /* Produce verbose diagnostics */
static int watch; /* Watch the delivery process */
static unsigned width = 76; /* Maximum width of header fields */
static int keep_files; /* Keep draft files */
......@@ -128,147 +49,116 @@ static int keep_files; /* Keep draft files */
watch_printf c;\
} while (0)
static int add_file (char *name);
static int add_file (char const *name);
static void mesg_list_fixup (void);
static void
add_alias (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
mh_alias_read (arg, 1);
}
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
set_draftfolder (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
char *p;
switch (key)
{
case ARG_ALIAS:
mh_alias_read (arg, 1);
break;
draftfolder = mu_strdup (arg);
use_draftfolder = 1;
}
case ARG_CHUNKSIZE:
split_size = strtoul (arg, &p, 10);
if (*p)
{
argp_error (state, "%s: %s", arg, _("invalid number"));
exit (1);
}
break;
case ARG_DRAFT:
use_draft = 1;
break;
case ARG_DRAFTFOLDER:
draftfolder = arg;
use_draftfolder = 1;
break;
case ARG_NODRAFTFOLDER:
draftfolder = NULL;
use_draftfolder = 0;
break;
case ARG_DRAFTMESSAGE:
add_file (arg);
break;
case ARG_FILTER:
mh_opt_notimpl ("-filter");
break;
static void
add_draftmessage (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
add_file (arg);
}
case ARG_NOFILTER:
mh_opt_notimpl ("-nofilter");
break;
case ARG_FORMAT:
mh_opt_notimpl_warning ("-format");
reformat_recipients = is_true (arg);
break;
case ARG_NOFORMAT:
mh_opt_notimpl_warning ("-noformat");
reformat_recipients = 0;
break;
case ARG_FORWARD:
mh_opt_notimpl_warning ("-forward");
forward_notice = is_true (arg);
break;
case ARG_NOFORWARD:
mh_opt_notimpl_warning ("-noforward");
forward_notice = 0;
break;
case ARG_MIME:
mh_opt_notimpl_warning ("-mime");
mime_encaps = is_true (arg);
break;
case ARG_NOMIME:
mh_opt_notimpl_warning ("-nomime");
mime_encaps = 0;
break;
case ARG_MSGID:
append_msgid = is_true (arg);
break;
case ARG_NOMSGID:
append_msgid = 0;
break;
static void
set_split_opt (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
char *errmsg;
int rc = mu_str_to_c (arg, opt->opt_type, opt->opt_ptr, &errmsg);
if (rc)
{
char const *errtext;
if (errmsg)
errtext = errmsg;
else
errtext = mu_strerror (rc);
case ARG_PRESERVE:
keep_files = is_true (arg);
break;
case ARG_PUSH:
background = is_true (arg);
break;
case ARG_NOPUSH:
background = 0;
break;
case ARG_SPLIT:
split_message = 1;
split_interval = strtoul (arg, &p, 10);
if (*p)
{
argp_error (state, "%s: %s", arg, _("invalid number"));
exit (1);
}
break;
case ARG_VERBOSE:
verbose = is_true (arg);
break;
case ARG_NOVERBOSE:
verbose = 0;
break;
case ARG_WATCH:
watch = is_true (arg);
break;
case ARG_NOWATCH:
watch = 0;
break;
case ARG_WIDTH:
mh_opt_notimpl_warning ("-width");
width = strtoul (arg, &p, 10);
if (*p)
{
argp_error (state, _("invalid number"));
exit (1);
}
break;
default:
return ARGP_ERR_UNKNOWN;
mu_parseopt_error (po, "%s%s: %s", po->po_long_opt_start,
opt->opt_long, errtext);
free (errmsg);
if (!(po->po_flags & MU_PARSEOPT_NO_ERREXIT))
exit (po->po_exit_error);
}
return 0;
split_message = 1;
}
static struct mu_option options[] = {
{ "alias", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("specify additional alias file"),
mu_c_string, NULL, add_alias },
{ "draft", 0, NULL, MU_OPTION_DEFAULT,
N_("use prepared draft"),
mu_c_bool, &use_draft },
{ "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify the folder for message drafts"),
mu_c_string, NULL, set_draftfolder },
{ "draftmessage", 0, N_("MSG"), MU_OPTION_DEFAULT,
N_("use MSG from the draftfolder as a draft"),
mu_c_string, NULL, add_draftmessage },
{ "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
N_("undo the effect of the last --draftfolder option"),
mu_c_int, &use_draftfolder, NULL, "1" },
{ "filter", 0, N_("FILE"), MU_OPTION_HIDDEN,
N_("use filter FILE to preprocess the body of the message"),
mu_c_string, NULL, mh_opt_notimpl },
{ "nofilter", 0, NULL, MU_OPTION_HIDDEN,
N_("undo the effect of the last --filter option"),
mu_c_string, NULL, mh_opt_notimpl },
{ "format", 0, NULL, MU_OPTION_HIDDEN,
N_("reformat To: and Cc: addresses"),
mu_c_string, NULL, mh_opt_notimpl_warning },
{ "noformat", 0, NULL, MU_OPTION_HIDDEN },
{ "forward", 0, NULL, MU_OPTION_HIDDEN,
N_("in case of failure forward the draft along with the failure notice to the sender"),
mu_c_string, NULL, mh_opt_notimpl_warning },
{ "noforward", 0, NULL, MU_OPTION_HIDDEN, "" },
{ "mime", 0, NULL, MU_OPTION_HIDDEN,
N_("use MIME encapsulation"),
mu_c_bool, NULL, mh_opt_notimpl_warning },
{ "msgid", 0, NULL, MU_OPTION_DEFAULT,
N_("add Message-ID: field"),
mu_c_bool, &append_msgid },
{ "push", 0, NULL, MU_OPTION_DEFAULT,
N_("run in the background"),
mu_c_bool, &background },
{ "preserve", 0, NULL, MU_OPTION_DEFAULT,
N_("keep draft files"),
mu_c_bool, &keep_files },
{ "keep", 0, NULL, MU_OPTION_ALIAS },
{ "split", 0, N_("SECONDS"), MU_OPTION_DEFAULT,
N_("split the draft into several partial messages and send them with SECONDS interval"),
mu_c_ulong, &split_interval, set_split_opt },
{ "chunksize", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set the size of chunk for --split (in bytes)"),
mu_c_size, &split_size },
{ "verbose", 0, NULL, MU_OPTION_DEFAULT,
N_("print the transcript of interactions with the transport system"),
mu_c_bool, &verbose },
{ "watch", 0, NULL, MU_OPTION_DEFAULT,
N_("monitor the delivery of mail"),
mu_c_bool, &watch },
{ "width", 0, N_("NUMBER"), MU_OPTION_HIDDEN,
N_("make header fields no longer than NUMBER columns"),
mu_c_string, NULL, mh_opt_notimpl_warning },
MU_OPTION_END
};
static void
watch_printf (const char *fmt, ...)
{
......@@ -291,7 +181,7 @@ static mu_list_t mesg_list;
static mu_property_t mts_profile;
int
add_file (char *name)
add_file (char const *name)
{
struct list_elt *elt;
......@@ -859,17 +749,12 @@ int
main (int argc, char **argv)
{
mu_mailbox_t mbox = NULL;
int index;
char *p;
int rc;
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
argc -= index;
argv += index;
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
mh_read_aliases ();
/* Process the mtstailor file */
......
......@@ -19,55 +19,9 @@
#include <mh.h>
static char doc[] = N_("GNU MH show")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH show");
static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
#define ARG_PASS ARG_MAX
static struct argp_option options[] = {
{"draft", ARG_DRAFT, NULL, 0,
N_("show the draft file") },
{"file", ARG_FILE, N_("FILE"), 0,
N_("show this file") },
{"header", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("display a description of the message before the message itself") },
{"noheader", ARG_HEADER, NULL, OPTION_HIDDEN, "" },
{"showproc", ARG_SHOWPROC, N_("PROGRAM"), 0,
N_("use PROGRAM to show messages")},
{"noshowproc", ARG_NOSHOWPROC, NULL, 0,
N_("disable the use of the \"showproc:\" profile component") },
{"form", ARG_FORM, N_("FILE"), 0,
N_("read format from given file")},
{"moreproc", ARG_MOREPROC, N_("PROG"), 0,
N_("use this PROG as pager"), },
{"nomoreproc", ARG_NOMOREPROC, NULL, 0,
N_("disable the use of moreproc") },
{"length", ARG_LENGTH, N_("NUMBER"), 0,
N_("set output screen length")},
{"width", ARG_WIDTH, N_("NUMBER"), 0,
N_("set output width")},
{NULL}
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "draft" },
{ "file", MH_OPT_ARG, "file" },
{ "header", MH_OPT_BOOL },
{ "showproc", MH_OPT_ARG, "program" },
{ "noshowproc" },
{ "form", MH_OPT_ARG, "formatfile"},
{ "width", MH_OPT_ARG, "number"},
{ "length", MH_OPT_ARG, "number"},
{ "moreproc", MH_OPT_ARG, "program"},
{ "nomoreproc" },
{ NULL }
};
int use_draft;
int use_showproc = 1;
int header_option = 1;
......@@ -100,71 +54,75 @@ insarg (char *arg)
showargv[1] = p;
}
}
static const char *
findopt (int key)
static void
set_draft (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
struct argp_option *p;
for (p = options; p->name; p++)
if (p->key == key)
return p->name;
abort ();
if (use_draft || file)
{
mu_parseopt_error (po, _("only one file at a time!"));
exit (po->po_exit_error);
}
use_draft = 1;
}
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
set_file (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
if (use_draft || file)
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
case ARG_DRAFT:
if (use_draft || file)
argp_error (state, _("only one file at a time!"));
use_draft = 1;
break;
case ARG_FILE:
if (use_draft || file)
argp_error (state, _("only one file at a time!"));
file = mh_expand_name (NULL, arg, NAME_FILE);
break;
case ARG_HEADER:
header_option = is_true (arg);
break;
case ARG_NOHEADER:
header_option = 0;
break;
case ARG_SHOWPROC:
showproc = arg;
break;
case ARG_NOSHOWPROC:
use_showproc = 0;
break;
case ARG_NOMOREPROC:
case ARG_FORM:
case ARG_MOREPROC:
case ARG_LENGTH:
case ARG_WIDTH:
addarg (findopt (key));
if (arg)
addarg (arg);
break;
default:
return ARGP_ERR_UNKNOWN;
mu_parseopt_error (po, _("only one file at a time!"));
exit (po->po_exit_error);
}
return 0;
file = mh_expand_name (NULL, arg, NAME_FILE);
}
static void
add_show_arg (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
char *name = mu_alloc (strlen (opt->opt_long) + 2);
name[0] = '-';
strcpy (name + 1, opt->opt_long);
addarg (name);
if (arg)
addarg (arg);
}
static struct mu_option options[] = {
{ "draft", 0, NULL, MU_OPTION_DEFAULT,
N_("show the draft file"),
mu_c_string, NULL, set_draft },
{ "file", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("show this file"),
mu_c_string, NULL, set_file },
{ "header", 0, NULL, MU_OPTION_DEFAULT,
N_("display a description of the message before the message itself"),
mu_c_bool, &header_option },
{ "showproc", 0, N_("PROGRAM"), MU_OPTION_DEFAULT,
N_("use PROGRAM to show messages"),
mu_c_string, &showproc },
{ "noshowproc", 0, NULL, MU_OPTION_DEFAULT,
N_("disable the use of the \"showproc:\" profile component"),
mu_c_int, &use_showproc, NULL, "0" },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file"),
mu_c_string, NULL, add_show_arg },
{ "moreproc", 0, N_("PROG"), MU_OPTION_DEFAULT,
N_("use this PROG as pager"),
mu_c_string, NULL, add_show_arg },
{ "nomoreproc", 0, NULL, MU_OPTION_DEFAULT,
N_("disable the use of moreproc"),
mu_c_string, NULL, add_show_arg },
{ "length", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output screen length"),
mu_c_string, NULL, add_show_arg },
{ "width", 0, N_("NUMBER"), MU_OPTION_DEFAULT,
N_("set output width"),
mu_c_string, NULL, add_show_arg },
MU_OPTION_END
};
static int
resolve_mime (size_t num, mu_message_t msg, void *data)
{
......@@ -222,7 +180,6 @@ checkfile (char *file)
int
main (int argc, char **argv)
{
int index = 0;
mu_mailbox_t mbox;
mu_msgset_t msgset;
const char *p;
......@@ -233,15 +190,13 @@ main (int argc, char **argv)
showargmax = 2;
showargc = 1;
showargv = mu_calloc (showargmax, sizeof showargv[0]);
mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
argc -= index;
argv += index;
if (use_draft || file)
{
if (argc)
......
......@@ -22,72 +22,10 @@
#include <unistd.h>
#include <signal.h>
static char doc[] = N_("GNU MH sortm")"\v"
static char prog_doc[] = N_("GNU MH sortm")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char args_doc[] = N_("[MSGLIST]");
#define ARG_QUICKSORT 1024
#define ARG_SHELL 1025
/* GNU options */
static struct argp_option options[] = {
{"folder", ARG_FOLDER, N_("FOLDER"), 0,
N_("specify folder to operate upon")},
{N_("Setting sort keys:"), 0, NULL, OPTION_DOC, NULL, 0},
{"datefield", ARG_DATEFIELD, N_("STRING"), 0,
N_("sort on the date field (default `Date:')"), 10},
{"nodatefield", ARG_NODATEFIELD, NULL, 0,
N_("undo the effect of the last --datefield option"), 10},
{"limit", ARG_LIMIT, N_("DAYS"), 0,
N_("consider two datefields equal if their difference lies within the given nuber of DAYS."), 11},
{"nolimit", ARG_NOLIMIT, NULL, 0,
N_("undo the effect of the last --limit option"), 11},
{"textfield", ARG_TEXTFIELD, N_("STRING"), 0,
N_("sort on the text field"), 15},
{"notextfield", ARG_NOTEXTFIELD, NULL, 0,
N_("undo the effect of the last --textfield option"), 15},
{"numfield", ARG_NUMFIELD, N_("STRING"), 0,
N_("sort on the numeric field"), 16},
{N_("Actions:"), 0, NULL, OPTION_DOC, NULL, 16},
{"reorder", ARG_REORDER, 0, 0,
N_("reorder the messages (default)"), 20 },
{"dry-run", ARG_DRY_RUN, 0, 0,
N_("do not do anything, only show what would have been done"), 20 },
{"list", ARG_LIST, 0, 0,
N_("list the sorted messages"), 20 },
{"form", ARG_FORM, N_("FILE"), 0,
N_("read format from given file"), 23},
{"format", ARG_FORMAT, N_("FORMAT"), 0,
N_("use this format string"), 23},
{"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("verbosely list executed actions"), 30 },
{"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "" },
{N_("Select sort algorithm:"), 0, NULL, OPTION_DOC, NULL, 30},
{"shell", ARG_SHELL, 0, 0,
N_("use shell algorithm"), 40 },
{"quicksort", ARG_QUICKSORT, 0, 0,
N_("use quicksort algorithm (default)"), 40 },
{ NULL },
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "datefield", MH_OPT_ARG, "field" },
{ "nodatefield" },
{ "textfield", MH_OPT_ARG, "field" },
{ "notextfield" },
{ "limit", MH_OPT_ARG, "days" },
{ "nolimit" },
{ "verbose", MH_OPT_BOOL },
{ NULL },
};
static int limit;
static int verbose;
static mu_mailbox_t mbox;
......@@ -98,115 +36,175 @@ static size_t msgcount;
static size_t current_num;
#define ACTION_REORDER 0
#define ACTION_DRY_RUN 1
#define ACTION_LIST 2
static int algorithm = ARG_QUICKSORT;
enum
{
ACTION_REORDER,
ACTION_DRY_RUN,
ACTION_LIST
};
enum
{
algo_quicksort,
algo_shell
};
static int algorithm = algo_quicksort;
static int action = ACTION_REORDER;
static char *format_str = mh_list_format;
static mh_format_t format;
typedef int (*compfun) (void *, void *);
static void addop (char *field, compfun comp);
static void addop (char const *field, compfun comp);
static void remop (compfun comp);
static int comp_text (void *a, void *b);
static int comp_date (void *a, void *b);
static int comp_number (void *a, void *b);
static void
add_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
addop (arg, comp_date);
}
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
add_numfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
{
case ARG_FOLDER:
mh_set_current_folder (arg);
break;
case ARG_DATEFIELD:
addop (arg, comp_date);
break;
case ARG_NUMFIELD:
addop (arg, comp_number);
break;
addop (arg, comp_number);
}
case ARG_NODATEFIELD:
remop (comp_date);
break;
case ARG_TEXTFIELD:
addop (arg, comp_text);
break;
case ARG_NOTEXTFIELD:
remop (comp_text);
break;
case ARG_LIMIT:
limit = strtoul (arg, NULL, 0);
break;
case ARG_NOLIMIT:
limit = -1;
break;
case ARG_VERBOSE:
if (!arg || mu_isalpha (arg[0]))
verbose = is_true (arg);
else
verbose = arg[0] - '0';
break;
case ARG_NOVERBOSE:
verbose = 0;
break;
case ARG_FORM:
mh_read_formfile (arg, &format_str);
break;
case ARG_FORMAT:
format_str = arg;
break;
static void
add_textfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
addop (arg, comp_text);
}
case ARG_REORDER:
action = ACTION_REORDER;
break;
case ARG_LIST:
action = ACTION_LIST;
break;
static void
rem_datefield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
remop (comp_date);
}
case ARG_DRY_RUN:
action = ACTION_DRY_RUN;
if (!verbose)
verbose = 1;
break;
static void
rem_numfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
remop (comp_number);
}
case ARG_SHELL:
case ARG_QUICKSORT:
algorithm = key;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
static void
rem_textfield (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
remop (comp_text);
}
static void
set_action_reorder (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
action = ACTION_REORDER;
}
static void
set_action_list (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
action = ACTION_LIST;
}
static void
set_action_dry_run (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
action = ACTION_DRY_RUN;
if (!verbose)
verbose = 1;
}
static void
set_algo_shell (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
algorithm = algo_shell;
}
static void
set_algo_quicksort (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
algorithm = algo_quicksort;
}
static struct mu_option options[] = {
MU_OPTION_GROUP (N_("Setting sort keys:")),
{ "datefield", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("sort on the date field (default `Date:')"),
mu_c_string, NULL, add_datefield },
{ "nodatefield", 0, NULL, MU_OPTION_DEFAULT,
N_("don't sort on the date field"),
mu_c_string, NULL, rem_datefield },
{ "limit", 0, N_("DAYS"), MU_OPTION_DEFAULT,
N_("consider two datefields equal if their difference lies within the given nuber of DAYS."),
mu_c_int, &limit },
{ "nolimit", 0, NULL, MU_OPTION_DEFAULT,
N_("undo the effect of the last -limit option"),
mu_c_int, &limit, NULL, "-1" },
{ "textfield", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("sort on the text field"),
mu_c_string, NULL, add_textfield },
{ "notextfield", 0, NULL, MU_OPTION_DEFAULT,
N_("don't sort on the text field"),
mu_c_string, NULL, rem_textfield },
{ "numfield", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("sort on the numeric field"),
mu_c_string, NULL, add_numfield },
{ "nonumfield", 0, NULL, MU_OPTION_DEFAULT,
N_("don't sort on the numeric field"),
mu_c_string, NULL, rem_numfield },
MU_OPTION_GROUP (N_("Actions:")),
{ "reorder", 0, NULL, MU_OPTION_DEFAULT,
N_("reorder the messages (default)"),
mu_c_string, NULL, set_action_reorder },
{ "dry-run", 0, NULL, MU_OPTION_DEFAULT,
N_("do not do anything, only show what would have been done"),
mu_c_string, NULL, set_action_dry_run },
{ "list", 0, NULL, MU_OPTION_DEFAULT,
N_("list the sorted messages"),
mu_c_string, NULL, set_action_list },
{ "form", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("read format from given file"),
mu_c_string, &format_str, mh_opt_read_formfile },
{ "format", 0, N_("FORMAT"), MU_OPTION_DEFAULT,
N_("use this format string"),
mu_c_string, &format_str },
{ "verbose", 0, NULL, MU_OPTION_DEFAULT,
N_("verbosely list executed actions"),
mu_c_bool, &verbose },
MU_OPTION_GROUP (N_("Select sort algorithm:")),
{ "shell", 0, NULL, MU_OPTION_DEFAULT,
N_("use shell algorithm"),
mu_c_string, NULL, set_algo_shell },
{ "quicksort", 0, NULL, MU_OPTION_DEFAULT,
N_("use quicksort algorithm (default)"),
mu_c_string, NULL, set_algo_quicksort },
MU_OPTION_END
};
/* *********************** Comparison functions **************************** */
struct comp_op
{
char *field;
char const *field;
compfun comp;
};
static mu_list_t oplist;
static void
addop (char *field, compfun comp)
addop (char const *field, compfun comp)
{
struct comp_op *op = mu_alloc (sizeof (*op));
......@@ -497,11 +495,11 @@ sort ()
switch (algorithm)
{
case ARG_QUICKSORT:
case algo_quicksort:
qsort (msgarr, msgcount, sizeof (msgarr[0]), comp);
break;
case ARG_SHELL:
case algo_shell:
shell_sort ();
break;
}
......@@ -599,19 +597,17 @@ fill_msgarr (mu_msgset_t msgset)
}
/* Main */
int
main (int argc, char **argv)
{
int index;
mu_url_t url;
mu_msgset_t msgset;
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option,
args_doc, doc, opt_handler, NULL, &index);
mh_getopt (&argc, &argv, options, MH_GETOPT_DEFAULT_FOLDER,
args_doc, prog_doc, NULL);
if (!oplist)
addop ("date", comp_date);
......@@ -627,9 +623,6 @@ main (int argc, char **argv)
if (memcmp (mbox_path, "mh:", 3) == 0)
mbox_path += 3;
argc -= index;
argv += index;
mh_mailbox_get_cur (mbox, &current_num);
mh_msgset_parse (&msgset, mbox, argc, argv, "all");
......
......@@ -53,11 +53,11 @@ Mail/inbox/5
Mail/inbox/6
])
MH_CHECK([refile --copy],[refile02 refile--copy],[
MH_CHECK([refile -copy],[refile02 refile-copy],[
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox])
MUT_MBCOPY($abs_top_srcdir/testsuite/mh/teaparty,[Mail/teaparty])
echo 'Current-Folder: teaparty' > Mail/context
refile --copy 3 4 +inbox || exit $?
refile -copy 3 4 +inbox || exit $?
find Mail/inbox -name '[[0-9]]' | sort
cmp Mail/inbox/6 Mail/teaparty/3 >/dev/null || echo "Message 3 differs"
cmp Mail/inbox/7 Mail/teaparty/4 >/dev/null || echo "Message 4 differs"
......
......@@ -19,88 +19,45 @@
#include <mh.h>
static char doc[] = "GNU MH whatnow";
static char prog_doc[] = "GNU MH whatnow";
static char args_doc[] = N_("[FILE]");
/* GNU options */
static struct argp_option options[] = {
{"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
N_("specify the folder for message drafts")},
{"nodraftfolder", ARG_NODRAFTFOLDER, 0, 0,
N_("undo the effect of the last --draftfolder option")},
{"draftmessage" , ARG_DRAFTMESSAGE, N_("MSG"), 0,
N_("invoke the draftmessage facility")},
{"editor", ARG_EDITOR, N_("PROG"), 0, N_("set the editor program to use")},
{"noedit", ARG_NOEDIT, 0, 0, N_("suppress the initial edit")},
{"prompt", ARG_PROMPT, N_("STRING"), 0, N_("set the prompt")},
{ NULL }
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "draftfolder", MH_OPT_ARG, "folder" },
{ "nodraftfolder" },
{ "draftmessage" },
{ "editor", MH_OPT_ARG, "program" },
{ "noedit" },
{ "prompt" },
{ NULL }
};
struct mh_whatnow_env wh_env = { 0 };
static int initial_edit = 1;
static char *draftmessage = "cur";
static const char *draftfolder = NULL;
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case ARG_DRAFTFOLDER:
draftfolder = arg;
break;
case ARG_EDITOR:
wh_env.editor = arg;
break;
case ARG_NODRAFTFOLDER:
draftfolder = NULL;
break;
case ARG_NOEDIT:
initial_edit = 0;
break;
case ARG_DRAFTMESSAGE:
draftmessage = arg;
break;
case ARG_PROMPT:
wh_env.prompt = arg;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct mu_option options[] = {
{ "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify the folder for message drafts"),
mu_c_string, &draftfolder },
{ "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
N_("undo the effect of the last -draftfolder option"),
mu_c_string, &draftfolder, mh_opt_clear_string },
{ "draftmessage" , 0, N_("MSG"), MU_OPTION_DEFAULT,
N_("invoke the draftmessage facility"),
mu_c_string, &draftmessage },
{ "editor", 0, N_("PROG"), MU_OPTION_DEFAULT,
N_("set the editor program to use"),
mu_c_string, &wh_env.editor },
{ "noedit", 0, NULL, MU_OPTION_DEFAULT,
N_("suppress the initial edit"),
mu_c_int, &initial_edit, NULL, "0" },
{ "prompt", 0, N_("STRING"), MU_OPTION_DEFAULT,
N_("set the prompt"),
mu_c_string, &wh_env.prompt },
MU_OPTION_END
};
int
main (int argc, char **argv)
{
int index;
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_whatnow_env_from_environ (&wh_env);
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
argc -= index;
argv += index;
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
if (argc)
wh_env.draftfile = argv[0];
else if (draftfolder)
......
......@@ -17,99 +17,58 @@
#include <mh.h>
static char doc[] = N_("GNU MH whom")"\v"
N_("Use -help to obtain the list of traditional MH options.");
static char prog_doc[] = N_("GNU MH whom");
static char args_doc[] = "[FILE]";
/* GNU options */
static struct argp_option options[] = {
{"alias", ARG_ALIAS, N_("FILE"), 0,
N_("specify additional alias file") },
{"draft", ARG_DRAFT, NULL, 0,
N_("use prepared draft") },
{"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
N_("specify the folder for message drafts") },
{"draftmessage", ARG_DRAFTMESSAGE, NULL, 0,
N_("treat the arguments as a list of messages from the draftfolder") },
{"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0,
N_("undo the effect of the last --draftfolder option") },
{"check", ARG_CHECK, N_("BOOL"), OPTION_ARG_OPTIONAL,
N_("check if addresses are deliverable") },
{"nocheck", ARG_NOCHECK, NULL, OPTION_HIDDEN, "" },
{NULL}
};
/* Traditional MH options */
struct mh_option mh_option[] = {
{ "alias", MH_OPT_ARG, "aliasfile" },
{ "draft" },
{ "draftfolder", MH_OPT_ARG, "folder" },
{ "draftmessage", MH_OPT_ARG, "message" },
{ "nodraftfolder" },
{ "check", MH_OPT_BOOL },
{NULL}
};
static int check_recipients;
static int use_draft; /* Use the prepared draft */
static const char *draft_folder; /* Use this draft folder */
static error_t
opt_handler (int key, char *arg, struct argp_state *state)
static void
add_alias (struct mu_parseopt *po, struct mu_option *opt, char const *arg)
{
switch (key)
{
case ARG_ALIAS:
mh_alias_read (arg, 1);
break;
case ARG_DRAFT:
use_draft = 1;
break;
case ARG_DRAFTFOLDER:
draft_folder = arg;
break;
case ARG_NODRAFTFOLDER:
draft_folder = NULL;
break;
case ARG_DRAFTMESSAGE:
if (!draft_folder)
draft_folder = mh_global_profile_get ("Draft-Folder",
mu_folder_directory ());
break;
case ARG_CHECK:
check_recipients = is_true (arg);
break;
case ARG_NOCHECK:
check_recipients = 0;
break;
mh_alias_read (arg, 1);
}
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
static void
set_draftmessage (struct mu_parseopt *po, struct mu_option *opt,
char const *arg)
{
if (!draft_folder)
draft_folder = mh_global_profile_get ("Draft-Folder",
mu_folder_directory ());
}
static struct mu_option options[] = {
{ "alias", 0, N_("FILE"), MU_OPTION_DEFAULT,
N_("specify additional alias file"),
mu_c_string, NULL, add_alias },
{ "draft", 0, NULL, MU_OPTION_DEFAULT,
N_("use prepared draft"),
mu_c_bool, &use_draft },
{ "draftfolder", 0, N_("FOLDER"), MU_OPTION_DEFAULT,
N_("specify the folder for message drafts"),
mu_c_string, &draft_folder },
{ "nodraftfolder", 0, NULL, MU_OPTION_DEFAULT,
N_("undo the effect of the last -draftfolder option"),
mu_c_string, &draft_folder, mh_opt_clear_string },
{ "draftmessage", 0, NULL, MU_OPTION_DEFAULT,
N_("treat the arguments as a list of messages from the draftfolder"),
mu_c_string, NULL, set_draftmessage },
{ "check", 0, NULL, MU_OPTION_DEFAULT,
N_("check if addresses are deliverable"),
mu_c_bool, &check_recipients },
MU_OPTION_END
};
int
main (int argc, char **argv)
{
int index;
char *name = "draft";
MU_APP_INIT_NLS ();
mh_argp_init ();
mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
opt_handler, NULL, &index);
argc -= index;
argv += index;
mh_getopt (&argc, &argv, options, 0, args_doc, prog_doc, NULL);
if (!use_draft && argc > 0)
name = argv[0];
......
......@@ -144,7 +144,6 @@ mh/inc.c
mh/install-mh.c
mh/mark.c
mh/mboxprop.c
mh/mh_argp.c
mh/mh_fmtgram.y
mh/mh_format.c
mh/mh_getopt.c
......