summaryrefslogtreecommitdiff
path: root/mail
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-07-11 19:16:33 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2009-07-11 19:16:33 +0300
commit61295ae0e724c62ac016dfc374d6064c63270288 (patch)
tree8578f2bfb814260f8ffa5a83814d07803d7d5de7 /mail
parentf6b40b8d77c08636e90ae23b86dd01f7e70f080e (diff)
downloadmailutils-61295ae0e724c62ac016dfc374d6064c63270288.tar.gz
mailutils-61295ae0e724c62ac016dfc374d6064c63270288.tar.bz2
Improve internal variable handling in mail. Implement envelope and variable commands.
* NEWS: Update. * doc/texinfo/programs.texi: Document new variables and commands. * mail/envelope.c: New file. * mail/mailvar.c: New file. * mail/Makefile.am (mail_SOURCES): Add envelope.c and mailvar.c. * mail/mail.h (EF_HIDDEN): New constant (mail_env_data_t, mail_env_entry, mail_env_entry_is_set) (mail_env_entry, util_getenv, util_printenv, util_setenv) (var_iterator_t, var_iterate_next, var_iterate_first) (var_iterate_end, var_compl): Removed. (union mailvar_value, struct mailvar_variable (mail_variable, mail_envelope, print_envelope) (mailvar_find_variable, mailvar_get, mailvar_print) (mailvar_variable_format, mailvar_set, mailvar_set_compl): Add prototypes. (MOPTF_OVERWRITE, MOPTF_QUIET) * mail/table.c: List new commands: envelope, setq, variable. Implement completion for `set'. * mail/testsuite/mail/if.exp: Use setq to set a read-only variable. mail/alias.c, mail/decode.c, mail/delete.c, mail/escape.c mail/file.c, mail/folders.c, mail/from.c, mail/if.c, mail/mail.c, mail/mailline.c, mail/msgset.y, mail/pipe.c, mail/print.c, mail/quit.c, mail/reply.c, mail/send.c, mail/set.c, mail/shell.c, mail/top.c, mail/unset.c, mail/util.c: Use mailvar functions.
Diffstat (limited to 'mail')
-rw-r--r--mail/Makefile.am2
-rw-r--r--mail/alias.c2
-rw-r--r--mail/decode.c10
-rw-r--r--mail/delete.c2
-rw-r--r--mail/envelope.c51
-rw-r--r--mail/escape.c32
-rw-r--r--mail/file.c2
-rw-r--r--mail/folders.c2
-rw-r--r--mail/from.c74
-rw-r--r--mail/if.c2
-rw-r--r--mail/mail.c40
-rw-r--r--mail/mail.h79
-rw-r--r--mail/mailline.c28
-rw-r--r--mail/mailvar.c763
-rw-r--r--mail/msgset.y4
-rw-r--r--mail/pipe.c4
-rw-r--r--mail/print.c7
-rw-r--r--mail/quit.c6
-rw-r--r--mail/reply.c4
-rw-r--r--mail/send.c40
-rw-r--r--mail/set.c12
-rw-r--r--mail/shell.c7
-rw-r--r--mail/table.c8
-rw-r--r--mail/testsuite/mail/if.exp10
-rw-r--r--mail/top.c2
-rw-r--r--mail/unset.c2
-rw-r--r--mail/util.c312
27 files changed, 1014 insertions, 493 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 7b7682ce7..a47694bc5 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -49,6 +49,7 @@ mail_SOURCES = \
dp.c\
echo.c\
edit.c\
+ envelope.c\
eq.c\
escape.c\
exit.c\
@@ -65,6 +66,7 @@ mail_SOURCES = \
mail.c\
mail.h\
mailline.c\
+ mailvar.c\
mbox.c\
msgset.y\
next.c\
diff --git a/mail/alias.c b/mail/alias.c
index 515f8904a..613c17ac8 100644
--- a/mail/alias.c
+++ b/mail/alias.c
@@ -152,7 +152,7 @@ alias_expand (const char *name)
alias_t al;
mu_list_t list;
- if (util_getenv (NULL, "recursivealiases", Mail_env_boolean, 0) == 0)
+ if (mailvar_get (NULL, "recursivealiases", mailvar_type_boolean, 0) == 0)
{
char *s;
mu_list_t origlist;
diff --git a/mail/decode.c b/mail/decode.c
index 159f4139e..369ed7626 100644
--- a/mail/decode.c
+++ b/mail/decode.c
@@ -182,7 +182,7 @@ display_message0 (mu_message_t mesg, const msgset_t *msgset,
if (mu_message_unencapsulate (mesg, &submsg, NULL) == 0)
display_message0 (submsg, msgset, select_hdr);
}
- else if (util_getenv (&tmp, "metamail", Mail_env_string, 0) == 0)
+ else if (mailvar_get (&tmp, "metamail", mailvar_type_string, 0) == 0)
{
/* If `metamail' is set to a string, treat it as command line
of external metamail program. */
@@ -212,13 +212,13 @@ display_message0 (mu_message_t mesg, const msgset_t *msgset,
/* If `metamail' is set to true, enable internal mailcap
support */
- if (util_getenv (NULL, "metamail", Mail_env_boolean, 0) == 0)
+ if (mailvar_get (NULL, "metamail", mailvar_type_boolean, 0) == 0)
{
char *no_ask = NULL;
int debug = 0;
- util_getenv (&no_ask, "mimenoask", Mail_env_string, 0);
- if (util_getenv (&debug, "verbose", Mail_env_boolean, 0) == 0
+ mailvar_get (&no_ask, "mimenoask", mailvar_type_string, 0);
+ if (mailvar_get (&debug, "verbose", mailvar_type_boolean, 0) == 0
&& debug)
debug = 9;
@@ -347,7 +347,7 @@ run_metamail (const char *mailcap_cmd, mu_message_t mesg)
char *no_ask;
setenv ("METAMAIL_PAGER", getenv ("PAGER"), 0);
- if (util_getenv (&no_ask, "mimenoask", Mail_env_string, 0))
+ if (mailvar_get (&no_ask, "mimenoask", mailvar_type_string, 0))
setenv ("MM_NOASK", no_ask, 1);
status = mu_message_get_stream (mesg, &stream);
diff --git a/mail/delete.c b/mail/delete.c
index 07e853a9d..83dae90f2 100644
--- a/mail/delete.c
+++ b/mail/delete.c
@@ -40,7 +40,7 @@ mail_delete (int argc, char **argv)
int rc = util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT,
mail_delete_msg, NULL);
- if (util_getenv (NULL, "autoprint", Mail_env_boolean, 0) == 0)
+ if (mailvar_get (NULL, "autoprint", mailvar_type_boolean, 0) == 0)
util_do_command("print");
return rc;
diff --git a/mail/envelope.c b/mail/envelope.c
new file mode 100644
index 000000000..24d93916c
--- /dev/null
+++ b/mail/envelope.c
@@ -0,0 +1,51 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2009 Free Software Foundation, Inc.
+
+ GNU Mailutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Mailutils is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "mail.h"
+
+/*
+ * env[elope] [msglist]
+ */
+
+int
+print_envelope (msgset_t *mspec, mu_message_t msg, void *data)
+{
+ int status;
+ mu_envelope_t env = NULL;
+ const char *sender = NULL, *date = NULL;
+
+ status = mu_message_get_envelope (msg, &env);
+ if (status)
+ {
+ mu_error (_("%d: Cannot get envelope"), mspec->msg_part[0]);
+ }
+ else
+ {
+ mu_envelope_sget_sender (env, &sender);
+ mu_envelope_sget_date (env, &date);
+ if (data)
+ fprintf (ofile, "%s ", (char*) data);
+ fprintf (ofile, "%s %s", sender, date);
+ }
+ return 0;
+}
+
+int
+mail_envelope (int argc, char **argv)
+{
+ return util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT,
+ print_envelope, NULL);
+}
diff --git a/mail/escape.c b/mail/escape.c
index a95528a3d..e44283e42 100644
--- a/mail/escape.c
+++ b/mail/escape.c
@@ -164,7 +164,7 @@ escape_check_args (int argc, char **argv)
if (argc == 1)
{
char *escape = "~";
- util_getenv (&escape, "escape", Mail_env_string, 0);
+ mailvar_get (&escape, "escape", mailvar_type_string, 0);
util_error (_("%c%s requires an argument"), escape[0], argv[0]);
return 1;
}
@@ -234,8 +234,8 @@ escape_sign (int argc MU_ARG_UNUSED, char **argv, compose_env_t *env MU_ARG_UNUS
{
char *p;
- if (util_getenv (&p, mu_isupper (argv[0][0]) ? "Sign" : "sign",
- Mail_env_string, 1) == 0)
+ if (mailvar_get (&p, mu_isupper (argv[0][0]) ? "Sign" : "sign",
+ mailvar_type_string, 1) == 0)
{
fputs ("-- \n", ofile);
if (mu_isupper (argv[0][0]))
@@ -315,7 +315,7 @@ run_editor (char *ed, char *arg)
static int
escape_run_editor (char *ed, int argc, char **argv, compose_env_t *env)
{
- if (!util_getenv (NULL, "editheaders", Mail_env_boolean, 0))
+ if (!mailvar_get (NULL, "editheaders", mailvar_type_boolean, 0))
{
char *filename;
int fd = mu_tempfile (NULL, &filename);
@@ -413,29 +413,9 @@ escape_headers (int argc, char **argv, compose_env_t *env)
int
escape_insert (int argc, char **argv, compose_env_t *send_env MU_ARG_UNUSED)
{
- struct mail_env_entry *env;
-
if (escape_check_args (argc, argv))
return 1;
- env = util_find_env (argv[1], 0);
- if (env)
- switch (env->type)
- {
- case Mail_env_string:
- fprintf (ofile, "%s", env->value.string);
- break;
-
- case Mail_env_number:
- fprintf (ofile, "%d", env->value.number);
- break;
-
- case Mail_env_boolean:
- fprintf (ofile, "%s", env->set ? "yes" : "no");
- break;
-
- default:
- break;
- }
+ mailvar_variable_format (ofile, mailvar_find_variable (argv[1], 0), NULL);
return 0;
}
@@ -455,7 +435,7 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data)
fprintf (stdout, _("Interpolating: %d\n"), mspec->msg_part[0]);
- util_getenv (&prefix, "indentprefix", Mail_env_string, 0);
+ mailvar_get (&prefix, "indentprefix", mailvar_type_string, 0);
if (*(int*)data)
{
diff --git a/mail/file.c b/mail/file.c
index 2230438a0..803bb86ce 100644
--- a/mail/file.c
+++ b/mail/file.c
@@ -118,7 +118,7 @@ mail_file (int argc, char **argv)
mbox = newbox;
mu_mailbox_messages_count (mbox, &total);
set_cursor (1);
- if (util_getenv (NULL, "header", Mail_env_boolean, 0) == 0)
+ if (mailvar_get (NULL, "header", mailvar_type_boolean, 0) == 0)
{
util_do_command ("summary");
util_do_command ("z.");
diff --git a/mail/folders.c b/mail/folders.c
index 379bbfecd..1eaedf403 100644
--- a/mail/folders.c
+++ b/mail/folders.c
@@ -27,7 +27,7 @@ mail_folders (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
{
char *path;
- if (util_getenv (&path, "folder", Mail_env_string, 1))
+ if (mailvar_get (&path, "folder", mailvar_type_string, 1))
return 1;
if (path[0] != '/' && path[0] != '~')
diff --git a/mail/from.c b/mail/from.c
index a148d3c66..383ae5617 100644
--- a/mail/from.c
+++ b/mail/from.c
@@ -36,48 +36,60 @@ mail_from0 (msgset_t *mspec, mu_message_t msg, void *data)
int cflag;
size_t m_size = 0, m_lines = 0;
- mu_message_get_header (msg, &hdr);
- if (mu_header_aget_value_unfold (hdr, MU_HEADER_FROM, &from) == 0)
- {
- mu_address_t address = NULL;
- if (mu_address_create (&address, from) == 0)
+ if (mailvar_get (NULL, "fromfield", mailvar_type_boolean, 0) == 0)
+ {
+ mu_message_get_header (msg, &hdr);
+ if (mu_header_aget_value_unfold (hdr, MU_HEADER_FROM, &from) == 0)
{
- char *name;
- const char *email;
-
- if (mu_address_sget_email (address, 1, &email) == 0)
+ mu_address_t address = NULL;
+ if (mu_address_create (&address, from) == 0)
{
- if (util_getenv (NULL, "showto", Mail_env_boolean, 0) == 0
- && mail_is_my_name (email))
+ char *name;
+ const char *email;
+
+ if (mu_address_sget_email (address, 1, &email) == 0)
{
- char *tmp;
-
- if (mu_header_aget_value_unfold (hdr, MU_HEADER_TO,
- &tmp) == 0)
+ if (mailvar_get (NULL, "showto", mailvar_type_boolean, 0) == 0
+ && mail_is_my_name (email))
{
- mu_address_t addr_to;
- if (mu_address_create (&addr_to, tmp) == 0)
+ char *tmp;
+
+ if (mu_header_aget_value_unfold (hdr, MU_HEADER_TO,
+ &tmp) == 0)
{
- mu_address_destroy (&address);
- address = addr_to;
+ mu_address_t addr_to;
+ if (mu_address_create (&addr_to, tmp) == 0)
+ {
+ mu_address_destroy (&address);
+ address = addr_to;
+ }
+ free (tmp);
}
- free (tmp);
}
}
- }
- if ((mu_address_aget_personal (address, 1, &name) == 0
- && name)
- || (mu_address_aget_email (address, 1, &name) == 0
- && name))
- {
- free (from);
- from = name;
+ if ((mu_address_aget_personal (address, 1, &name) == 0
+ && name)
+ || (mu_address_aget_email (address, 1, &name) == 0
+ && name))
+ {
+ free (from);
+ from = name;
+ }
+ mu_address_destroy (&address);
}
- mu_address_destroy (&address);
}
+ util_rfc2047_decode (&from);
+ }
+ else
+ {
+ mu_envelope_t env = NULL;
+ const char *sender = "";
+
+ if (mu_message_get_envelope (msg, &env) == 0)
+ mu_envelope_sget_sender (env, &sender);
+ from = strdup (sender);
}
- util_rfc2047_decode (&from);
mu_header_aget_value_unfold (hdr, MU_HEADER_SUBJECT, &subj);
util_rfc2047_decode (&subj);
@@ -100,7 +112,7 @@ mail_from0 (msgset_t *mspec, mu_message_t msg, void *data)
cflag = ' ';
date[0] = 0;
- if (util_getenv (NULL, "datefield", Mail_env_boolean, 0) == 0
+ if (mailvar_get (NULL, "datefield", mailvar_type_boolean, 0) == 0
&& mu_header_get_value (hdr, MU_HEADER_DATE, date, sizeof (date), NULL) == 0)
{
time_t t;
diff --git a/mail/if.c b/mail/if.c
index bd7460711..f94f79ac5 100644
--- a/mail/if.c
+++ b/mail/if.c
@@ -97,7 +97,7 @@ mail_if (int argc, char **argv)
return 1;
}
- if (util_getenv (&mode, "mode", Mail_env_string, 1))
+ if (mailvar_get (&mode, "mode", mailvar_type_string, 1))
exit (EXIT_FAILURE);
if (if_cond() == 0)
diff --git a/mail/mail.c b/mail/mail.c
index 3ebf90b42..ff98d9cb5 100644
--- a/mail/mail.c
+++ b/mail/mail.c
@@ -77,7 +77,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'e':
- util_cache_command (&command_list, "set mode=exist");
+ util_cache_command (&command_list, "setq mode=exist");
break;
case 'f':
@@ -102,7 +102,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'p':
case 'r':
- util_cache_command (&command_list, "set mode=print");
+ util_cache_command (&command_list, "setq mode=print");
break;
case 'q':
@@ -110,11 +110,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 't':
- util_cache_command (&command_list, "set mode=send");
+ util_cache_command (&command_list, "setq mode=send");
break;
case 'H':
- util_cache_command (&command_list, "set mode=headers");
+ util_cache_command (&command_list, "setq mode=headers");
break;
case 'i':
@@ -144,7 +144,8 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'F':
- util_cache_command (&command_list, "set byname");
+ /* FIXME */
+ util_cache_command (&command_list, "setq byname");
break;
case ARGP_KEY_ARG:
@@ -157,7 +158,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case ARGP_KEY_FINI:
if (args->send_mode)
- util_cache_command (&command_list, "set mode=send");
+ util_cache_command (&command_list, "setq mode=send");
break;
default:
@@ -192,7 +193,7 @@ mail_cmdline (void *closure, int cont MU_ARG_UNUSED)
while (1)
{
- if (util_getenv (NULL, "autoinc", Mail_env_boolean, 0) == 0
+ if (mailvar_get (NULL, "autoinc", mailvar_type_boolean, 0) == 0
&& !mu_mailbox_is_updated (mbox))
{
mu_mailbox_messages_count (mbox, &total);
@@ -208,7 +209,7 @@ mail_cmdline (void *closure, int cont MU_ARG_UNUSED)
continue;
}
- if (!rc && util_getenv (NULL, "ignoreeof", Mail_env_boolean, 0) == 0)
+ if (!rc && mailvar_get (NULL, "ignoreeof", mailvar_type_boolean, 0) == 0)
{
util_error (_("Use \"quit\" to quit."));
continue;
@@ -220,8 +221,8 @@ mail_cmdline (void *closure, int cont MU_ARG_UNUSED)
}
static char *default_setup[] = {
- "set noallnet",
- "set noappend",
+ /* "set noallnet", */
+ "setq append",
"set asksub",
"set crt",
"set noaskbcc",
@@ -239,7 +240,7 @@ static char *default_setup[] = {
"set noignore",
"set noignoreeof",
"set indentprefix=\"\t\"",
- "set nokeep",
+ "setq keep",
"set nokeepsave",
"set nometoo",
"set noonehop",
@@ -265,9 +266,10 @@ static char *default_setup[] = {
"set metamail",
"set recursivealiases",
"set noinplacealiases",
+ "set fromfield",
/* Start in mail reading mode */
- "set mode=read",
+ "setq mode=read",
"set noquit",
"set rc",
@@ -343,7 +345,7 @@ main (int argc, char **argv)
char *mailer_name = alloca (strlen ("sendmail:")
+ strlen (PATH_SENDMAIL) + 1);
sprintf (mailer_name, "sendmail:%s", PATH_SENDMAIL);
- util_setenv ("sendmail", mailer_name, Mail_env_string, 1);
+ mailvar_set ("sendmail", mailer_name, mailvar_type_string, MOPTF_OVERWRITE);
}
@@ -361,7 +363,7 @@ main (int argc, char **argv)
exit (1);
/* read system-wide mail.rc and user's .mailrc */
- if (util_getenv (NULL, "rc", Mail_env_boolean, 0) == 0)
+ if (mailvar_get (NULL, "rc", mailvar_type_boolean, 0) == 0)
util_do_command ("source %s", SITE_MAIL_RC);
util_do_command ("source %s", getenv ("MAILRC"));
@@ -376,7 +378,7 @@ main (int argc, char **argv)
}
/* how should we be running? */
- if (util_getenv (&mode, "mode", Mail_env_string, 1))
+ if (mailvar_get (&mode, "mode", mailvar_type_string, 1))
exit (EXIT_FAILURE);
/* Interactive mode */
@@ -396,7 +398,7 @@ main (int argc, char **argv)
num++;
mu_argcv_string (num, args.args, &buf);
rc = util_do_command ("mail %s", buf);
- return util_getenv (NULL, "mailx", Mail_env_boolean, 0) ? rc : 0;
+ return mailvar_get (NULL, "mailx", mailvar_type_boolean, 0) ? rc : 0;
}
/* Or acting as a normal reader */
else
@@ -474,7 +476,7 @@ main (int argc, char **argv)
if (total == 0
&& (strcmp (mode, "read")
- || util_getenv (NULL, "emptystart", Mail_env_boolean, 0)))
+ || mailvar_get (NULL, "emptystart", mailvar_type_boolean, 0)))
{
if (args.file)
fprintf (ofile, _("%s: 0 messages\n"), args.file);
@@ -485,13 +487,13 @@ main (int argc, char **argv)
}
/* initial commands */
- if (util_getenv (NULL, "header", Mail_env_boolean, 0) == 0)
+ if (mailvar_get (NULL, "header", mailvar_type_boolean, 0) == 0)
{
util_do_command ("summary");
util_do_command ("z.");
}
- util_getenv (&prompt, "prompt", Mail_env_string, 0);
+ mailvar_get (&prompt, "prompt", mailvar_type_string, 0);
mail_mainloop (mail_cmdline, (void*) prompt, 1);
fprintf (ofile, "\n");
util_do_command ("quit");
diff --git a/mail/mail.h b/mail/mail.h
index 9883250d6..cc9a4a7c6 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -98,10 +98,11 @@ typedef int function_t (int, char **);
#endif
/* Values for mail_command_entry.flags */
-#define EF_REG 0x00 /* Regular command */
-#define EF_FLOW 0x01 /* Flow control command */
-#define EF_SEND 0x02 /* Send command */
-
+#define EF_REG 0x00 /* Regular command */
+#define EF_FLOW 0x01 /* Flow control command */
+#define EF_SEND 0x02 /* Send command */
+#define EF_HIDDEN 0x04 /* Hiddent command */
+
typedef struct compose_env
{
mu_header_t header; /* The message headers */
@@ -139,31 +140,29 @@ struct mail_escape_entry
int (*escfunc) (int, char **, compose_env_t *);
};
-typedef enum
+enum mailvar_type
{
- Mail_env_whatever,
- Mail_env_number,
- Mail_env_string,
- Mail_env_boolean
- }
-mail_env_data_t;
-
-struct mail_env_entry
+ mailvar_type_whatever,
+ mailvar_type_number,
+ mailvar_type_string,
+ mailvar_type_boolean
+ };
+
+union mailvar_value
+{
+ char *string;
+ int number;
+ int bool;
+};
+
+struct mailvar_variable
{
- const char *var;
- mail_env_data_t type;
+ char *name;
+ enum mailvar_type type;
int set;
- union
- {
- char *string;
- int number;
- int bool;
- }
- value;
+ union mailvar_value value;
};
-#define mail_env_entry_is_set(ep) ((ep) && (ep)->set)
-
typedef struct message_set msgset_t;
struct message_set
@@ -212,6 +211,7 @@ extern int mail_send (int argc, char **argv); /* command mail */
extern int mail_mbox (int argc, char **argv);
extern int mail_next (int argc, char **argv);
extern int mail_nounfold (int argc, char **argv);
+extern int mail_variable (int argc, char **argv);
extern int mail_pipe (int argc, char **argv);
extern int mail_previous (int argc, char **argv);
extern int mail_print (int argc, char **argv);
@@ -240,6 +240,8 @@ extern int mail_write (int argc, char **argv);
extern int mail_z (int argc, char **argv);
extern int mail_eq (int argc, char **argv); /* command = */
extern int mail_setenv (int argc, char **argv);
+extern int mail_envelope (int argc, char **argv);
+extern int print_envelope (msgset_t *mspec, mu_message_t msg, void *data);
extern int if_cond (void);
@@ -331,13 +333,19 @@ extern int util_getlines (void);
extern int util_screen_lines (void);
extern int util_screen_columns (void);
extern int util_get_crt (void);
-extern struct mail_env_entry *util_find_env (const char *var, int create);
-extern int util_getenv (void *ptr, const char *variable,
- mail_env_data_t type, int warn);
-
-extern void util_printenv (int set);
-extern int util_setenv (const char *name, void *value,
- mail_env_data_t type, int overwrite);
+extern struct mailvar_variable *mailvar_find_variable (const char *var, int create);
+extern int mailvar_get (void *ptr, const char *variable,
+ enum mailvar_type type, int warn);
+
+extern void mailvar_print (int set);
+extern void mailvar_variable_format (FILE *fp,
+ const struct mailvar_variable *,
+ const char *defval);
+
+#define MOPTF_OVERWRITE 0x001
+#define MOPTF_QUIET 0x002
+extern int mailvar_set (const char *name, void *value,
+ enum mailvar_type type, int flags);
extern int util_isdeleted (size_t msgno);
extern char *util_get_homedir (void);
extern char *util_fullpath (const char *inpath);
@@ -396,11 +404,6 @@ extern int mail_sender (int argc, char **argv);
extern int mail_nosender (int argc, char **argv);
extern mu_address_t get_sender_address (mu_message_t msg);
-typedef struct var_iterator *var_iterator_t;
-extern const char *var_iterate_next (var_iterator_t itr);
-extern const char *var_iterate_first (const char *prefix, var_iterator_t *pitr);
-extern void var_iterate_end (var_iterator_t *itr);
-
#define COMPOSE_APPEND 0
#define COMPOSE_REPLACE 1
#define COMPOSE_SINGLE_LINE 2
@@ -427,6 +430,8 @@ extern char *readline (char *prompt);
#define MAIL_ATTRIBUTE_TAGGED 0x0004
#define MAIL_ATTRIBUTE_SHOWN 0x0008
+extern void ml_attempted_completion_over (void);
+
#ifdef WITH_READLINE
extern char **file_compl (int argc, char **argv, int ws);
extern char **no_compl (int argc, char **argv, int ws);
@@ -435,7 +440,7 @@ extern char **msglist_file_compl (int argc, char **argv, int ws);
extern char **dir_compl (int argc, char **argv, int ws);
extern char **command_compl (int argc, char **argv, int ws);
extern char **alias_compl (int argc, char **argv, int ws);
-extern char **var_compl (int argc, char **argv, int ws);
+extern char **mailvar_set_compl (int argc, char **argv, int ws);
extern char **exec_compl (int argc, char **argv, int ws);
#else
# define file_compl NULL
diff --git a/mail/mailline.c b/mail/mailline.c
index 863c8e12b..4ed1c3ab9 100644
--- a/mail/mailline.c
+++ b/mail/mailline.c
@@ -35,7 +35,7 @@ sig_handler (int signo)
switch (signo)
{
case SIGINT:
- if (util_getenv (NULL, "quit", Mail_env_boolean, 0) == 0)
+ if (mailvar_get (NULL, "quit", mailvar_type_boolean, 0) == 0)
exit (0);
_interrupted++;
break;
@@ -564,32 +564,6 @@ alias_compl (int argc, char **argv, int ws)
}
static char *
-var_generator (const char *text, int state)
-{
- static var_iterator_t itr;
- const char *p;
-
- if (!state)
- p = var_iterate_first (text, &itr);
- else
- p = var_iterate_next (itr);
-
- if (!p)
- {
- var_iterate_end (&itr);
- return NULL;
- }
- return strdup (p);
-}
-
-char **
-var_compl (int argc, char **argv, int ws)
-{
- ml_attempted_completion_over ();
- return rl_completion_matches (ws ? "" : argv[argc-1], var_generator);
-}
-
-static char *
mkfilename (const char *dir, const char *file)
{
size_t len = strlen (dir) + 1 + strlen (file) + 1;
diff --git a/mail/mailvar.c b/mail/mailvar.c
new file mode 100644
index 000000000..6550b398f
--- /dev/null
+++ b/mail/mailvar.c
@@ -0,0 +1,763 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2009 Free Software Foundation, Inc.
+
+ GNU Mailutils is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GNU Mailutils is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "mail.h"
+
+#define MAILVAR_ALIAS 0x0001
+#define MAILVAR_RDONLY 0x0002
+#define MAILVAR_HIDDEN 0x0004
+
+struct mailvar_symbol
+{
+ struct mailvar_variable var;
+ enum mailvar_type type;
+ int flags;
+ char *descr;
+};
+
+mu_list_t mailvar_list = NULL;
+
+struct mailvar_symbol mailvar_tab[] =
+ {
+ /* For compatibility with other mailx implementations.
+ Never used, always true. */
+ { { "append", }, mailvar_type_boolean, MAILVAR_RDONLY,
+ N_("messages saved in mbox are appended to the end rather than prepended") },
+ { { "appenddeadletter", }, mailvar_type_boolean, 0,
+ N_("append the contents of canceled letter to dead.letter file") },
+ { { "askbcc", }, mailvar_type_boolean, 0,
+ N_("prompt user for bcc before composing the message") },
+ { { "askcc", }, mailvar_type_boolean, 0,
+ N_("prompt user for cc before composing the message") },
+ { { "ask", }, mailvar_type_boolean, 0,
+ N_("prompt user for subject before composing the message") },
+ { { "asksub", }, mailvar_type_whatever, MAILVAR_ALIAS, NULL },
+ { { "autoinc", }, mailvar_type_boolean, 0,
+ N_("automatically incorporate newly arrived messages")},
+ { { "autoprint", }, mailvar_type_boolean, 0,
+ N_("delete command behaves like dp") },
+ { { "bang", }, mailvar_type_boolean, 0,
+ N_("replace every occurrence of ! in arguments to the shell command"
+ " with the last executed command") },
+ { { "charset", }, mailvar_type_string, 0,
+ N_("output character set for decoded header fields") },
+ { { "cmd", }, mailvar_type_string, 0,
+ N_("default shell command for pipe") },
+ { { "columns", }, mailvar_type_number, 0,
+ N_("number of columns on terminal screen") },
+ { { "crt", }, mailvar_type_number, 0,
+ N_("if numeric, sets the minimum number of output lines needed "
+ "to engage paging; if boolean, use the height of the terminal "
+ "screen to compute the threshold") },
+ { { "datefield", }, mailvar_type_boolean, 0,
+ N_("get date from the `Date:' header, instead of the envelope") },
+ { { "dot", }, mailvar_type_boolean, 0,
+ N_("input message is terminated with a dot alone on a line") },
+ { { "editheaders", }, mailvar_type_boolean, 0,
+ N_("allow to edit message headers while composing") },
+ { { "emptystart", }, mailvar_type_boolean, 0,
+ N_("start interactive mode if the mailbox is empty") },
+ { { "escape", }, mailvar_type_string, 0,
+ N_("character denoting escapes") },
+ { { "flipr", }, mailvar_type_boolean, 0,
+ N_("swap the meaning of reply and Reply commands") },
+ { { "folder", }, mailvar_type_string, 0,
+ N_("folder directory name") },
+ { { "fromfield", }, mailvar_type_boolean, 0,
+ N_("get sender address from the `From:' header, instead of "
+ "the envelope") },
+ { { "gnu-last-command", }, mailvar_type_boolean, MAILVAR_RDONLY,
+ N_("last executed command line") },
+ { { "header", }, mailvar_type_boolean, 0,
+ N_("run the `headers' command after entering interactive mode") },
+ { { "hold", }, mailvar_type_boolean