]> granicus.if.org Git - neomutt/commitdiff
refactor: move the envlist code to the library
authorRichard Russon <rich@flatcap.org>
Thu, 29 Mar 2018 15:40:03 +0000 (16:40 +0100)
committerRichard Russon <rich@flatcap.org>
Fri, 30 Mar 2018 11:28:13 +0000 (12:28 +0100)
The envlist code keeps a private copy of the environment.

Makefile.autosetup
conn/tunnel.c
filter.c
init.c
main.c
mutt/envlist.c [new file with mode: 0644]
mutt/envlist.h [new file with mode: 0644]
mutt/mutt.h
protos.h
sendlib.c
system.c

index 7d17bc473c2121c091dfcf8b79b8f91b211de311..4b2787eceb6c26ef23639ff9a26d993d4d548eed 100644 (file)
@@ -91,11 +91,11 @@ ALLOBJS+=   $(NEOMUTTOBJS)
 # libmutt
 LIBMUTT=       libmutt.a
 LIBMUTTOBJS=   mutt/address.o mutt/base64.o mutt/buffer.o mutt/charset.o \
-               mutt/date.o mutt/exit.o mutt/file.o mutt/hash.o mutt/idna.o \
-               mutt/list.o mutt/logging.o mutt/mapping.o mutt/mbyte.o \
-               mutt/md5.o mutt/memory.o mutt/mime.o mutt/parameter.o \
-               mutt/regex.o mutt/rfc2047.o mutt/sha1.o mutt/signal.o \
-               mutt/string.o
+               mutt/date.o mutt/envlist.o mutt/exit.o mutt/file.o mutt/hash.o \
+               mutt/idna.o mutt/list.o mutt/logging.o mutt/mapping.o \
+               mutt/mbyte.o mutt/md5.o mutt/memory.o mutt/mime.o \
+               mutt/parameter.o mutt/regex.o mutt/rfc2047.o mutt/sha1.o \
+               mutt/signal.o mutt/string.o
 CLEANFILES+=   $(LIBMUTT) $(LIBMUTTOBJS)
 MUTTLIBS+=     $(LIBMUTT)
 ALLOBJS+=      $(LIBMUTTOBJS)
index 640a79e940c3dc079f7275fa6b25cba89e95e9d4..d1fd987e7334a148096a6ab8c75473d200b9745c 100644 (file)
@@ -108,7 +108,7 @@ static int tunnel_socket_open(struct Connection *conn)
     /* Don't let the subprocess think it can use the controlling tty */
     setsid();
 
-    execle(EXECSHELL, "sh", "-c", Tunnel, NULL, mutt_envlist());
+    execle(EXECSHELL, "sh", "-c", Tunnel, NULL, mutt_envlist_getlist());
     _exit(127);
   }
   mutt_sig_unblock_system(1);
index a286dbbb86dfaff0d5498fb2cdef3646225b725e..9d172c1f02f7be55b5c80096590cfb24affb8a08 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -148,7 +148,7 @@ pid_t mutt_create_filter_fd(const char *cmd, FILE **in, FILE **out, FILE **err,
       mutt_envlist_set("COLUMNS", columns, 1);
     }
 
-    execle(EXECSHELL, "sh", "-c", cmd, NULL, mutt_envlist());
+    execle(EXECSHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
     _exit(127);
   }
   else if (thepid == -1)
diff --git a/init.c b/init.c
index dc835e6929173d4349c51bb514fc188468e8e5fb..fd75bb4f1e5b5b079c3fa3a178f6c8d6cbedd7fa 100644 (file)
--- a/init.c
+++ b/init.c
@@ -124,8 +124,6 @@ static void myvar_del(const char *var)
 static char **nm_tags;
 #endif
 
-extern char **envlist;
-
 #ifndef DOMAIN
 /**
  * getmailname - Try to retrieve the FQDN from mailname files
@@ -2070,66 +2068,13 @@ static bool valid_show_multipart_alternative(const char *val)
           (mutt_str_strcmp(val, "info") == 0) || !val || (*val == 0));
 }
 
-char **mutt_envlist(void)
-{
-  return envlist;
-}
-
-/**
- * mutt_envlist_set - Helper function for parse_setenv()
- * @param name      Name of the environment variable
- * @param value     Value the envionment variable should have
- * @param overwrite Whether the environment variable should be overwritten
- *
- * It's broken out because some other parts of neomutt (filter.c) need
- * to set/overwrite environment variables in envlist before execing.
- */
-void mutt_envlist_set(const char *name, const char *value, bool overwrite)
-{
-  char **envp = envlist;
-  char work[LONG_STRING];
-  int count, len;
-
-  len = mutt_str_strlen(name);
-
-  /* Look for current slot to overwrite */
-  count = 0;
-  while (envp && *envp)
-  {
-    if ((mutt_str_strncmp(name, *envp, len) == 0) && (*envp)[len] == '=')
-    {
-      if (!overwrite)
-        return;
-      break;
-    }
-    envp++;
-    count++;
-  }
-
-  /* Format var=value string */
-  snprintf(work, sizeof(work), "%s=%s", NONULL(name), NONULL(value));
-
-  /* If slot found, overwrite */
-  if (envp && *envp)
-    mutt_str_replace(envp, work);
-
-  /* If not found, add new slot */
-  else
-  {
-    mutt_mem_realloc(&envlist, sizeof(char *) * (count + 2));
-    envlist[count] = mutt_str_strdup(work);
-    envlist[count + 1] = NULL;
-  }
-}
-
 static int parse_setenv(struct Buffer *tmp, struct Buffer *s,
                         unsigned long data, struct Buffer *err)
 {
-  int query, unset, len;
-  char *name = NULL, **save = NULL, **envp = envlist;
+  char **envp = mutt_envlist_getlist();
 
-  query = 0;
-  unset = data & MUTT_SET_UNSET;
+  bool query = false;
+  bool unset = data & MUTT_SET_UNSET;
 
   if (!MoreArgs(s))
   {
@@ -2139,17 +2084,17 @@ static int parse_setenv(struct Buffer *tmp, struct Buffer *s,
 
   if (*s->dptr == '?')
   {
-    query = 1;
+    query = true;
     s->dptr++;
   }
 
   /* get variable name */
   mutt_extract_token(tmp, s, MUTT_TOKEN_EQUAL);
-  len = strlen(tmp->data);
+  int len = strlen(tmp->data);
 
   if (query)
   {
-    int found = 0;
+    bool found = false;
     while (envp && *envp)
     {
       /* This will display all matches for "^QUERY" */
@@ -2158,7 +2103,7 @@ static int parse_setenv(struct Buffer *tmp, struct Buffer *s,
         if (!found)
         {
           mutt_endwin();
-          found = 1;
+          found = true;
         }
         puts(*envp);
       }
@@ -2177,25 +2122,8 @@ static int parse_setenv(struct Buffer *tmp, struct Buffer *s,
 
   if (unset)
   {
-    int count = 0;
-    while (envp && *envp)
-    {
-      if ((mutt_str_strncmp(tmp->data, *envp, len) == 0) && (*envp)[len] == '=')
-      {
-        /* shuffle down */
-        save = envp++;
-        while (*envp)
-        {
-          *save++ = *envp++;
-          count++;
-        }
-        *save = NULL;
-        mutt_mem_realloc(&envlist, sizeof(char *) * (count + 1));
-        return 0;
-      }
-      envp++;
-      count++;
-    }
+    if (mutt_envlist_unset(tmp->data))
+      return 0;
     return -1;
   }
 
@@ -2213,7 +2141,7 @@ static int parse_setenv(struct Buffer *tmp, struct Buffer *s,
     return -1;
   }
 
-  name = mutt_str_strdup(tmp->data);
+  char *name = mutt_str_strdup(tmp->data);
   mutt_extract_token(tmp, s, 0);
   mutt_envlist_set(name, tmp->data, true);
   FREE(&name);
diff --git a/main.c b/main.c
index ff8a145086e781d16c0e83e79a27fb8d94b8e6c9..e8359daf4f5b602cdb5f6a4a11b76780cfada75a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -68,8 +68,6 @@
 #include "nntp.h"
 #endif
 
-char **envlist = NULL;
-
 void mutt_exit(int code)
 {
   mutt_endwin();
@@ -235,7 +233,7 @@ static int get_user_info(void)
  * @retval 0 on success
  * @retval 1 on error
  */
-int main(int argc, char **argv, char **env)
+int main(int argc, char *argv[], char *envp[])
 {
   char folder[_POSIX_PATH_MAX] = "";
   char *subject = NULL;
@@ -295,16 +293,7 @@ int main(int argc, char **argv, char **env)
 
   umask(077);
 
-  /* Init envlist */
-  {
-    char **srcp, **dstp;
-    int count = 0;
-    for (srcp = env; srcp && *srcp; srcp++)
-      count++;
-    envlist = mutt_mem_calloc(count + 1, sizeof(char *));
-    for (srcp = env, dstp = envlist; srcp && *srcp; srcp++, dstp++)
-      *dstp = mutt_str_strdup(*srcp);
-  }
+  mutt_envlist_init(envp);
 
   for (optind = 1; optind < double_dash;)
   {
@@ -1053,5 +1042,6 @@ main_curses:
   if (repeat_error && ErrorBufMessage)
     puts(ErrorBuf);
 main_exit:
+  mutt_envlist_free();
   return rc;
 }
diff --git a/mutt/envlist.c b/mutt/envlist.c
new file mode 100644 (file)
index 0000000..2c5d362
--- /dev/null
@@ -0,0 +1,169 @@
+/**
+ * @file
+ * Private copy of the environment variables
+ *
+ * @authors
+ * Copyright (C) 2018 Richard Russon <rich@flatcap.org>
+ *
+ * @copyright
+ * This program 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 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program 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
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @page envlist Private copy of the environment variables
+ *
+ * Private copy of the environment variables
+ */
+
+#include "config.h"
+#include <stdbool.h>
+#include <stdio.h>
+#include "memory.h"
+#include "string2.h"
+
+char **EnvList = NULL; /**< Private copy of the environment variables */
+
+/**
+ * mutt_envlist_free - Free the private copy of the environment
+ */
+void mutt_envlist_free(void)
+{
+  if (!EnvList)
+    return;
+
+  for (char **p = EnvList; p && *p; p++)
+    FREE(p);
+
+  FREE(&EnvList);
+}
+
+/**
+ * mutt_envlist_init - Create a copy of the environment
+ * @param envp Environment variables
+ */
+void mutt_envlist_init(char *envp[])
+{
+  if (EnvList)
+    mutt_envlist_free();
+
+  if (!envp)
+    return;
+
+  char **src, **dst;
+  int count = 0;
+  for (src = envp; src && *src; src++)
+    count++;
+
+  EnvList = mutt_mem_calloc(count + 1, sizeof(char *));
+  for (src = envp, dst = EnvList; src && *src; src++, dst++)
+    *dst = mutt_str_strdup(*src);
+}
+
+/**
+ * mutt_envlist_set - Set an environment variable
+ * @param name      Name of the variable
+ * @param value     New value
+ * @param overwrite Should the variable be overwritten?
+ * @retval true  Success: variable set, or overwritten
+ * @retval false Variable exists and overwrite was false
+ *
+ * It's broken out because some other parts of neomutt (filter.c) need to
+ * set/overwrite environment variables in EnvList before calling exec().
+ */
+bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
+{
+  char **envp = EnvList;
+  char work[LONG_STRING];
+  int count, len;
+
+  len = mutt_str_strlen(name);
+
+  /* Look for current slot to overwrite */
+  count = 0;
+  while (envp && *envp)
+  {
+    if ((mutt_str_strncmp(name, *envp, len) == 0) && (*envp)[len] == '=')
+    {
+      if (!overwrite)
+        return false;
+      break;
+    }
+    envp++;
+    count++;
+  }
+
+  /* Format var=value string */
+  snprintf(work, sizeof(work), "%s=%s", NONULL(name), NONULL(value));
+
+  if (envp && *envp)
+  {
+    /* slot found, overwrite */
+    mutt_str_replace(envp, work);
+  }
+  else
+  {
+    /* not found, add new slot */
+    mutt_mem_realloc(&EnvList, sizeof(char *) * (count + 2));
+    EnvList[count] = mutt_str_strdup(work);
+    EnvList[count + 1] = NULL;
+  }
+  return true;
+}
+
+/**
+ * mutt_envlist_unset - Unset an environment variable
+ * @param name Variable to unset
+ * @retval true  Success: Variable unset
+ * @retval false Error: Variable doesn't exist
+ */
+bool mutt_envlist_unset(const char *name)
+{
+  int len = mutt_str_strlen(name);
+  if (len == 0)
+    return false;
+
+  char **envp = EnvList;
+
+  int count = 0;
+  while (envp && *envp)
+  {
+    if ((mutt_str_strncmp(name, *envp, len) == 0) && (*envp)[len] == '=')
+    {
+      /* shuffle down */
+      char **save = envp++;
+      while (*envp)
+      {
+        *save++ = *envp++;
+        count++;
+      }
+      *save = NULL;
+      mutt_mem_realloc(&EnvList, sizeof(char *) * (count + 1));
+      return true;
+    }
+    envp++;
+    count++;
+  }
+  return false;
+}
+
+/**
+ * mutt_envlist_getlist - Get the private environment
+ * @retval ptr Array of strings
+ *
+ * @note: The caller must not free the strings
+ */
+char **mutt_envlist_getlist(void)
+{
+  return EnvList;
+}
diff --git a/mutt/envlist.h b/mutt/envlist.h
new file mode 100644 (file)
index 0000000..e797181
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * @file
+ * Private copy of the environment variables
+ *
+ * @authors
+ * Copyright (C) 2018 Richard Russon <rich@flatcap.org>
+ *
+ * @copyright
+ * This program 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 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program 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
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdbool.h>
+
+#ifndef _MUTT_ENVLIST_H
+#define _MUTT_ENVLIST_H
+
+void   mutt_envlist_free(void);
+char **mutt_envlist_getlist(void);
+void   mutt_envlist_init(char *envp[]);
+bool   mutt_envlist_set(const char *name, const char *value, bool overwrite);
+bool   mutt_envlist_unset(const char *name);
+
+#endif /* _MUTT_ENVLIST_H */
index e19b05bd5819ea095015bcfa881e4d42909f8fcb..3a2a0cee45febad994273eb8610148b00b9d6f67 100644 (file)
@@ -32,6 +32,7 @@
  * | mutt/buffer.c    | @subpage buffer    |
  * | mutt/charset.c   | @subpage charset   |
  * | mutt/date.c      | @subpage date      |
+ * | mutt/envlist.c   | @subpage envlist   |
  * | mutt/exit.c      | @subpage exit      |
  * | mutt/file.c      | @subpage file      |
  * | mutt/hash.c      | @subpage hash      |
@@ -63,6 +64,7 @@
 #include "charset.h"
 #include "date.h"
 #include "exit.h"
+#include "envlist.h"
 #include "file.h"
 #include "hash.h"
 #include "idna2.h"
index 10fe555c527ab5fbf640f64d223bc085d8940950..fd3fbe5bb2eebda1b182b9d4a339b30b61fbc05a 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -159,8 +159,6 @@ int mutt_edit_content_type (struct Header *h, struct Body *b, FILE *fp);
 void mutt_edit_file(const char *editor, const char *data);
 void mutt_edit_headers(const char *editor, const char *body, struct Header *msg,
                        char *fcc, size_t fcclen);
-char **mutt_envlist(void);
-void mutt_envlist_set(const char *name, const char *value, bool overwrite);
 int mutt_label_message(struct Header *hdr);
 void mutt_make_label_hash(struct Context *ctx);
 void mutt_label_hash_add(struct Context *ctx, struct Header *hdr);
index abb6982ba8034a6a345f533ccf48882257b4c865..cc781c33fb993cfdc22ea3208f94278a8e147b57 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -2348,7 +2348,7 @@ static int send_msg(const char *path, char **args, const char *msg, char **tempf
       }
 
       /* execvpe is a glibc extension */
-      /* execvpe (path, args, mutt_envlist ()); */
+      /* execvpe (path, args, mutt_envlist_getlist()); */
       execvp(path, args);
       _exit(S_ERR);
     }
index 22c6cdc538e00cfde7d66559ce46c94f45ab7a16..98f3019ed691c466e50d489aaee9625c53934d3e 100644 (file)
--- a/system.c
+++ b/system.c
@@ -80,7 +80,7 @@ int mutt_system(const char *cmd)
     sigaction(SIGTSTP, &act, NULL);
     sigaction(SIGCONT, &act, NULL);
 
-    execle(EXECSHELL, "sh", "-c", cmd, NULL, mutt_envlist());
+    execle(EXECSHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
     _exit(127); /* execl error */
   }
   else if (thepid != -1)