From: David Champion Date: Mon, 12 Dec 2016 02:56:59 +0000 (-0800) Subject: Add setenv/unsetenv commands. X-Git-Tag: neomutt-20170113~15^2~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ea3ceeb312dc36038f34c088026b22931d6b0411;p=neomutt Add setenv/unsetenv commands. These can be used to add and remove environment variables passed to children via mutt_system(). Commited by Kevin McCarthy with some cleanup. --- diff --git a/doc/manual.xml.head b/doc/manual.xml.head index c5a83d450..0f2b2ba57 100644 --- a/doc/manual.xml.head +++ b/doc/manual.xml.head @@ -6480,6 +6480,24 @@ if the mailbox shortcut results in an empty regexp. + +Managing the Environment + + +You can alter the environment that Mutt passes on to its child processes +using the setenv and unsetenv operators. +(N.B. These follow Mutt-style syntax, not shell-style!) You can also +query current environment values by prefixing a ? character. + + + +setenv TERM vt100 +setenv ORGANIZATION "The Mutt Development Team" +unsetenv DISPLAY +setenv ?LESS + + + External Address Queries @@ -14983,6 +15001,23 @@ The following are the commands understood by Mutt: + + + setenv + + [?]variable + + + value + + + unsetenv + + variable + + + + sidebar_whitelist diff --git a/init.c b/init.c index ee271538c..e3e33f80e 100644 --- a/init.c +++ b/init.c @@ -85,6 +85,8 @@ static char **nm_tags; #endif +extern char **envlist; + static void toggle_quadoption (int opt) { int n = opt/4; @@ -1830,6 +1832,133 @@ static int check_charset (struct option_t *opt, const char *val) return rc; } +static int parse_setenv(BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err) +{ + int query, unset, len; + char work[LONG_STRING]; + char **save, **envp = envlist; + int count = 0; + + query = 0; + unset = data & MUTT_SET_UNSET; + + if (!MoreArgs (s)) + { + strfcpy (err->data, _("too few arguments"), err->dsize); + return -1; + } + + if (*s->dptr == '?') + { + query = 1; + s->dptr++; + } + + /* get variable name */ + mutt_extract_token (tmp, s, MUTT_TOKEN_EQUAL); + len = strlen (tmp->data); + + if (query) + { + int found = 0; + while (envp && *envp) + { + if (!mutt_strncmp (tmp->data, *envp, len)) + { + if (!found) + { + mutt_endwin (NULL); + found = 1; + } + puts (*envp); + } + envp++; + } + + if (found) + { + set_option (OPTFORCEREDRAWINDEX); + set_option (OPTFORCEREDRAWPAGER); + mutt_any_key_to_continue (NULL); + return 0; + } + + snprintf (err->data, err->dsize, _("%s is unset"), tmp->data); + return -1; + } + + if (unset) + { + count = 0; + while (envp && *envp) + { + if (!mutt_strncmp (tmp->data, *envp, len) && (*envp)[len] == '=') + { + /* shuffle down */ + save = envp++; + while (*envp) + { + *save++ = *envp++; + count++; + } + *save = NULL; + safe_realloc (&envlist, sizeof(char *) * (count+1)); + return 0; + } + envp++; + count++; + } + return -1; + } + + if (*s->dptr == '=') + { + s->dptr++; + SKIPWS (s->dptr); + } + + if (!MoreArgs (s)) + { + strfcpy (err->data, _("too few arguments"), err->dsize); + return -1; + } + + /* Look for current slot to overwrite */ + count = 0; + while (envp && *envp) + { + if (!mutt_strncmp (tmp->data, *envp, len) && (*envp)[len] == '=') + { + FREE (envp); /* __FREE_CHECKED__ */ + break; + } + envp++; + count++; + } + + /* Format var=value string */ + strfcpy (work, tmp->data, sizeof(work)); + len = strlen (work); + work[len++] = '='; + mutt_extract_token (tmp, s, 0); + strfcpy (&work[len], tmp->data, sizeof(work)-len); + + /* If slot found, overwrite */ + if (*envp) + *envp = safe_strdup (work); + + /* If not found, add new slot */ + else + { + *envp = safe_strdup (work); + count++; + safe_realloc (&envlist, sizeof(char *) * (count + 1)); + envlist[count] = NULL; + } + + return 0; +} + static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err) { int query, unset, inv, reset, r = 0; diff --git a/init.h b/init.h index 0229bf9b1..e146a66ba 100644 --- a/init.h +++ b/init.h @@ -4334,6 +4334,7 @@ static int parse_ignore (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_unignore (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_source (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_set (BUFFER *, BUFFER *, unsigned long, BUFFER *); +static int parse_setenv (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_my_hdr (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_unmy_hdr (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_subscribe (BUFFER *, BUFFER *, unsigned long, BUFFER *); @@ -4423,6 +4424,7 @@ const struct command_t Commands[] = { { "send-hook", mutt_parse_hook, MUTT_SENDHOOK }, { "send2-hook", mutt_parse_hook, MUTT_SEND2HOOK }, { "set", parse_set, 0 }, + { "setenv", parse_setenv, 0 }, #ifdef USE_SIDEBAR { "sidebar_whitelist",parse_list, UL &SidebarWhitelist }, { "unsidebar_whitelist",parse_unlist, UL &SidebarWhitelist }, @@ -4446,6 +4448,7 @@ const struct command_t Commands[] = { { "unmy_hdr", parse_unmy_hdr, 0 }, { "unscore", mutt_parse_unscore, 0 }, { "unset", parse_set, MUTT_SET_UNSET }, + { "unsetenv", parse_setenv, MUTT_SET_UNSET }, { "unsubscribe", parse_unsubscribe, 0 }, { NULL, NULL, 0 } }; diff --git a/main.c b/main.c index 12c29e7f8..1958c98f8 100644 --- a/main.c +++ b/main.c @@ -70,6 +70,8 @@ #include "nntp.h" #endif +char **envlist; + void mutt_exit (int code) { mutt_endwin (NULL); @@ -177,7 +179,7 @@ init_extended_keys(); #define MUTT_NEWS (1<<5) /* -g and -G */ #endif -int main (int argc, char **argv) +int main (int argc, char **argv, char **environ) { char folder[_POSIX_PATH_MAX] = ""; char *subject = NULL; @@ -225,6 +227,17 @@ int main (int argc, char **argv) memset (Options, 0, sizeof (Options)); memset (QuadOptions, 0, sizeof (QuadOptions)); + /* Init envlist */ + { + char **srcp, **dstp; + int count = 0; + for (srcp = environ; srcp && *srcp; srcp++) + count++; + envlist = safe_calloc(count+1, sizeof(char *)); + for (srcp = environ, dstp = envlist; srcp && *srcp; srcp++, dstp++) + *dstp = safe_strdup(*srcp); + } + for (optind = 1; optind < double_dash; ) { /* We're getopt'ing POSIXLY, so we'll be here every time getopt() diff --git a/system.c b/system.c index 36b80fb82..97dc2a8e7 100644 --- a/system.c +++ b/system.c @@ -32,6 +32,8 @@ #include #include +extern char **envlist; + int _mutt_system (const char *cmd, int flags) { int rc = -1; @@ -114,7 +116,7 @@ int _mutt_system (const char *cmd, int flags) sigaction (SIGTSTP, &act, NULL); sigaction (SIGCONT, &act, NULL); - execl (EXECSHELL, "sh", "-c", cmd, NULL); + execle (EXECSHELL, "sh", "-c", cmd, NULL, envlist); _exit (127); /* execl error */ } else if (thepid != -1)