From: David Champion Date: Mon, 12 Dec 2016 02:56:59 +0000 (-0800) Subject: Add setenv/unsetenv commands. X-Git-Tag: mutt-1-8-rel~59 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b32f0034cb956c47094e89b58521562d73eaab71;p=mutt 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 5e133827..80cfd578 100644 --- a/doc/manual.xml.head +++ b/doc/manual.xml.head @@ -5769,6 +5769,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 @@ -9894,6 +9912,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 09999c89..fc83b3dc 100644 --- a/init.c +++ b/init.c @@ -76,6 +76,8 @@ static void myvar_set (const char* var, const char* val); static const char* myvar_get (const char* var); static void myvar_del (const char* var); +extern char **envlist; + static void toggle_quadoption (int opt) { int n = opt/4; @@ -1696,6 +1698,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 34103a46..6bec1e9e 100644 --- a/init.h +++ b/init.h @@ -3876,6 +3876,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 *); @@ -3953,6 +3954,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 }, @@ -3973,6 +3975,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 25b1d04b..cafb830d 100644 --- a/main.c +++ b/main.c @@ -105,6 +105,8 @@ static const char *Obtaining = N_("\ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n\ "); +char **envlist; + void mutt_exit (int code) { mutt_endwin (NULL); @@ -571,7 +573,7 @@ init_extended_keys(); #define MUTT_RO (1<<3) /* -R */ #define MUTT_SELECT (1<<4) /* -y */ -int main (int argc, char **argv) +int main (int argc, char **argv, char **environ) { char folder[_POSIX_PATH_MAX] = ""; char *subject = NULL; @@ -619,6 +621,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 36b80fb8..97dc2a8e 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)