diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-07-11 19:16:33 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-07-11 19:16:33 +0300 |
commit | 61295ae0e724c62ac016dfc374d6064c63270288 (patch) | |
tree | 8578f2bfb814260f8ffa5a83814d07803d7d5de7 /mail | |
parent | f6b40b8d77c08636e90ae23b86dd01f7e70f080e (diff) | |
download | mailutils-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.am | 2 | ||||
-rw-r--r-- | mail/alias.c | 2 | ||||
-rw-r--r-- | mail/decode.c | 10 | ||||
-rw-r--r-- | mail/delete.c | 2 | ||||
-rw-r--r-- | mail/envelope.c | 51 | ||||
-rw-r--r-- | mail/escape.c | 32 | ||||
-rw-r--r-- | mail/file.c | 2 | ||||
-rw-r--r-- | mail/folders.c | 2 | ||||
-rw-r--r-- | mail/from.c | 74 | ||||
-rw-r--r-- | mail/if.c | 2 | ||||
-rw-r--r-- | mail/mail.c | 40 | ||||
-rw-r--r-- | mail/mail.h | 79 | ||||
-rw-r--r-- | mail/mailline.c | 28 | ||||
-rw-r--r-- | mail/mailvar.c | 763 | ||||
-rw-r--r-- | mail/msgset.y | 4 | ||||
-rw-r--r-- | mail/pipe.c | 4 | ||||
-rw-r--r-- | mail/print.c | 7 | ||||
-rw-r--r-- | mail/quit.c | 6 | ||||
-rw-r--r-- | mail/reply.c | 4 | ||||
-rw-r--r-- | mail/send.c | 40 | ||||
-rw-r--r-- | mail/set.c | 12 | ||||
-rw-r--r-- | mail/shell.c | 7 | ||||
-rw-r--r-- | mail/table.c | 8 | ||||
-rw-r--r-- | mail/testsuite/mail/if.exp | 10 | ||||
-rw-r--r-- | mail/top.c | 2 | ||||
-rw-r--r-- | mail/unset.c | 2 | ||||
-rw-r--r-- | mail/util.c | 312 |
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; @@ -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 |