NeoMutt  2025-12-11-694-ga89709
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
envlist.c
Go to the documentation of this file.
1
23
29
30#include "config.h"
31#include <stdbool.h>
32#include <stdio.h>
33#include <string.h>
34#include "envlist.h"
35#include "memory.h"
36#include "string2.h"
37
42void envlist_free(char ***envp)
43{
44 if (!envp || !*envp)
45 return;
46
47 for (char **p = *envp; p && *p; p++)
48 FREE(p);
49
50 FREE(envp);
51}
52
58char **envlist_init(char **envp)
59{
60 if (!envp)
61 return NULL;
62
63 char **src = NULL;
64 char **dst = NULL;
65 int count = 0;
66 for (src = envp; src && *src; src++)
67 count++;
68
69 char **env_copy = MUTT_MEM_CALLOC(count + 1, char *);
70 for (src = envp, dst = env_copy; src && *src; src++, dst++)
71 *dst = mutt_str_dup(*src);
72
73 return env_copy;
74}
75
88bool envlist_set(char ***envp, const char *name, const char *value, bool overwrite)
89{
90 if (!envp || !*envp || !name || (name[0] == '\0'))
91 return false;
92
93 // Find a matching entry
94 int count = 0;
95 int match = -1;
96 char *str = NULL;
97 for (; (str = (*envp)[count]); count++)
98 {
99 size_t len = mutt_str_startswith(str, name);
100 if ((len != 0) && (str[len] == '='))
101 {
102 if (!overwrite)
103 return false;
104 match = count;
105 break;
106 }
107 }
108
109 // Format var=value string dynamically to avoid truncation
110 const char *val = NONULL(value);
111 size_t nlen = mutt_str_len(name);
112 size_t vlen = mutt_str_len(val);
113 char *work = MUTT_MEM_MALLOC(nlen + 1 + vlen + 1, char);
114 snprintf(work, nlen + 1 + vlen + 1, "%s=%s", name, val);
115
116 if (match >= 0)
117 {
118 // match found, overwrite
119 FREE(&(*envp)[match]);
120 (*envp)[match] = work;
121 }
122 else
123 {
124 // not found, add a new entry
125 MUTT_MEM_REALLOC(envp, count + 2, char *);
126 (*envp)[count] = work;
127 (*envp)[count + 1] = NULL;
128 }
129
130 return true;
131}
132
140bool envlist_unset(char ***envp, const char *name)
141{
142 if (!envp || !*envp || !name || (name[0] == '\0'))
143 return false;
144
145 int count = 0;
146 for (; (*envp)[count]; count++)
147 ; // do nothing
148
149 char *str = NULL;
150 for (int match = 0; (str = (*envp)[match]); match++)
151 {
152 size_t len = mutt_str_startswith(str, name);
153 if ((len != 0) && (str[len] == '='))
154 {
155 FREE(&(*envp)[match]);
156 // Move down the later entries
157 memmove(&(*envp)[match], &(*envp)[match + 1], (count - match) * sizeof(char *));
158 // Shrink the array
159 MUTT_MEM_REALLOC(envp, count, char *);
160 return true;
161 }
162 }
163 return false;
164}
void envlist_free(char ***envp)
Free the private copy of the environment.
Definition envlist.c:42
char ** envlist_init(char **envp)
Create a copy of the environment.
Definition envlist.c:58
bool envlist_set(char ***envp, const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition envlist.c:88
bool envlist_unset(char ***envp, const char *name)
Unset an environment variable.
Definition envlist.c:140
Private copy of the environment variables.
Memory management wrappers.
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
#define MUTT_MEM_REALLOC(pptr, n, type)
Definition memory.h:55
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition string.c:234
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
String manipulation functions.
#define NONULL(x)
Definition string2.h:44