The envlist code keeps a private copy of the environment.
# 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)
/* 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);
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)
static char **nm_tags;
#endif
-extern char **envlist;
-
#ifndef DOMAIN
/**
* getmailname - Try to retrieve the FQDN from mailname files
(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))
{
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" */
if (!found)
{
mutt_endwin();
- found = 1;
+ found = true;
}
puts(*envp);
}
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;
}
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);
#include "nntp.h"
#endif
-char **envlist = NULL;
-
void mutt_exit(int code)
{
mutt_endwin();
* @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;
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;)
{
if (repeat_error && ErrorBufMessage)
puts(ErrorBuf);
main_exit:
+ mutt_envlist_free();
return rc;
}
--- /dev/null
+/**
+ * @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;
+}
--- /dev/null
+/**
+ * @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 */
* | 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 |
#include "charset.h"
#include "date.h"
#include "exit.h"
+#include "envlist.h"
#include "file.h"
#include "hash.h"
#include "idna2.h"
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);
}
/* execvpe is a glibc extension */
- /* execvpe (path, args, mutt_envlist ()); */
+ /* execvpe (path, args, mutt_envlist_getlist()); */
execvp(path, args);
_exit(S_ERR);
}
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)