doc/manual.xml.head |   18 ++++++++
 init.c              |  113 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 init.h              |    3 +
 main.c              |   15 ++++++-
 system.c            |    4 +-
 5 files changed, 151 insertions(+), 2 deletions(-)


# HG changeset patch
# User David Champion <[email protected]>
# Date 1472604759 25200
#      Tue Aug 30 17:52:39 2016 -0700
# Node ID be92ca7a461efd7815d5f6b170292798b7c79b3c
# Parent  788059e7b1182f283c6d21139beaf9dd0d587035
setenv/unsetenv for altering process environment (to affect children)

diff --git a/doc/manual.xml.head b/doc/manual.xml.head
--- a/doc/manual.xml.head
+++ b/doc/manual.xml.head
@@ -5769,6 +5769,24 @@
 
 </sect1>
 
+<sect1 id="setenv">
+<title>Managing the Environment</title>
+
+<para>
+You can alter the environment that Mutt passes on to its child processes
+using the <quote>setenv</quote> and <quote>unsetenv</quote> operators.
+(N.B. These follow Mutt-style syntax, not shell-style!)  You can also
+query current environment values by prefixing a <quote>?</quote> character.
+</para>
+
+<screen>
+setenv TERM vt100
+setenv ORGANIZATION "The Mutt Development Team"
+unsetenv DISPLAY
+setenv ?LESS
+</screen>
+</sect1>
+
 <sect1 id="query">
 <title>External Address Queries</title>
 
diff --git a/init.c b/init.c
--- a/init.c
+++ b/init.c
@@ -76,6 +76,8 @@
 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,117 @@
   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))
+  {
+    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 (!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 (!strncmp(tmp->data, *envp, len) && (*envp)[len] == '=')
+        {
+          /* shuffle down */
+          save = envp++;
+          while (*envp) {
+            *save++ = *envp++;
+            count++;
+          }
+          *save = NULL;
+          envlist = realloc(envlist, sizeof(char *) * (count+1));
+          return 0;
+        }
+        envp++;
+        count++;
+      }
+      return -1;
+    }
+
+    /* Look for current slot to overwrite */
+    count = 0;
+    while (envp && *envp)
+    {
+      if (!strncmp(tmp->data, *envp, len) && (*envp)[len] == '=')
+      {
+        FREE(envp);
+        break;
+      }
+      envp++;
+      count++;
+    }
+
+    /* Format var=value string */
+    strncpy(work, tmp->data, sizeof(work));
+    len = strlen(work);
+       work[len++] = '=';
+    mutt_extract_token (tmp, s, 0);
+    strncpy(&work[len], tmp->data, sizeof(work)-len);
+
+    /* If slot found, overwrite */
+    if (*envp) {
+      *envp = strdup(work);
+    }
+
+    /* If not found, add new slot */
+    else {
+      *envp = strdup(work);
+      count++;
+      envlist = realloc(envlist, sizeof(char *) * (count + 1));
+      envlist[count] = NULL;
+    }
+
+    return 0;
+  }
+
+  return -1;
+}
+
 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
--- a/init.h
+++ b/init.h
@@ -3873,6 +3873,7 @@
 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 *);
@@ -3945,6 +3946,7 @@
   { "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 },
 #endif
@@ -3964,6 +3966,7 @@
   { "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
--- a/main.c
+++ b/main.c
@@ -105,6 +105,8 @@
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
USA.\n\
 ");
 
+char **envlist;
+
 void mutt_exit (int code)
 {
   mutt_endwin (NULL);
@@ -565,7 +567,7 @@
 #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;
@@ -613,6 +615,17 @@
   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
--- a/system.c
+++ b/system.c
@@ -32,6 +32,8 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+extern char **envlist;
+
 int _mutt_system (const char *cmd, int flags)
 {
   int rc = -1;
@@ -114,7 +116,7 @@
     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)

Reply via email to