c0500ea0b1f24ccbb6f3f5778a1f37471c199535
[gnupg.git] / common / session-env.c
1 /* session-env.c - Session environment helper functions.
2  * Copyright (C) 2009 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * This file is free software; you can redistribute it and/or modify
7  * it under the terms of either
8  *
9  *   - the GNU Lesser General Public License as published by the Free
10  *     Software Foundation; either version 3 of the License, or (at
11  *     your option) any later version.
12  *
13  * or
14  *
15  *   - the GNU General Public License as published by the Free
16  *     Software Foundation; either version 2 of the License, or (at
17  *     your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * This file is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 #include <config.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <ctype.h>
34 #include <assert.h>
35 #include <unistd.h>
36
37 #include "util.h"
38 #include "session-env.h"
39
40
41 struct variable_s
42 {
43   char *value;    /* Pointer into NAME to the Nul terminated value. */
44   int is_default; /* The value is a default one.  */
45   char name[1];   /* Nul terminated Name and space for the value.  */
46 };
47
48
49
50 /* The session environment object.  */
51 struct session_environment_s
52 {
53   size_t arraysize;          /* Allocated size or ARRAY.  */
54   size_t arrayused;          /* Used size of ARRAY.  */
55   struct variable_s **array; /* Array of variables.  NULL slots are unused.  */
56 };
57
58
59 /* A list of environment variables we pass from the actual user
60   (e.g. gpgme) down to the pinentry.  We do not handle the locale
61   settings because they do not only depend on envvars.  */
62 static struct
63 {
64   const char *name;
65   const char *assname;  /* Name used by Assuan or NULL.  */
66 } stdenvnames[] = {
67   { "GPG_TTY", "ttyname" },      /* GnuPG specific envvar.  */
68   { "TERM",    "ttytype" },      /* Used to set ttytype. */
69   { "DISPLAY", "display" },      /* The X-Display.  */
70   { "XAUTHORITY","xauthority"},  /* Xlib Authentication.  */
71   { "XMODIFIERS" },              /* Used by Xlib to select X input
72                                       modules (eg "@im=SCIM").  */
73   { "GTK_IM_MODULE" },           /* Used by gtk to select gtk input
74                                     modules (eg "scim-bridge").  */
75   { "QT_IM_MODULE" },            /* Used by Qt to select qt input
76                                       modules (eg "xim").  */
77   { "INSIDE_EMACS" },            /* Set by Emacs before running a
78                                     process.  */
79   { "PINENTRY_USER_DATA", "pinentry-user-data"}
80                                  /* Used for communication with
81                                     non-standard Pinentries.  */
82 };
83
84
85 /* Track last allocated arraysize of all objects ever created.  If
86    nothing has ever been allocated we use INITIAL_ARRAYSIZE and we
87    will never use more than MAXDEFAULT_ARRAYSIZE for initial
88    allocation.  Note that this is not reentrant if used with a
89    preemptive thread model.  */
90 static size_t lastallocatedarraysize;
91 #define INITIAL_ARRAYSIZE 8  /* Let's use the number of stdenvnames.  */
92 #define CHUNK_ARRAYSIZE 10
93 #define MAXDEFAULT_ARRAYSIZE (INITIAL_ARRAYSIZE + CHUNK_ARRAYSIZE * 5)
94
95
96 /* Return the names of standard environment variables one after the
97    other.  The caller needs to set the value at the address of
98    ITERATOR initally to 0 and then call this function until it returns
99    NULL.  */
100 const char *
101 session_env_list_stdenvnames (int *iterator, const char **r_assname)
102 {
103   int idx = *iterator;
104
105   if (idx < 0 || idx >= DIM (stdenvnames))
106     return NULL;
107   *iterator = idx + 1;
108   if (r_assname)
109     *r_assname = stdenvnames[idx].assname;
110   return stdenvnames[idx].name;
111 }
112
113
114 /* Create a new session environment object.  Return NULL and sets
115    ERRNO on failure. */
116 session_env_t
117 session_env_new (void)
118 {
119   session_env_t se;
120
121   se = xtrycalloc (1, sizeof *se);
122   if (se)
123     {
124       se->arraysize = (lastallocatedarraysize?
125                        lastallocatedarraysize : INITIAL_ARRAYSIZE);
126       se->array = xtrycalloc (se->arraysize, sizeof *se->array);
127       if (!se->array)
128         {
129           xfree (se);
130           se = NULL;
131         }
132     }
133
134   return se;
135 }
136
137
138 /* Release a session environment object.  */
139 void
140 session_env_release (session_env_t se)
141 {
142   int idx;
143
144   if (!se)
145     return;
146
147   if (se->arraysize > INITIAL_ARRAYSIZE
148       && se->arraysize <= MAXDEFAULT_ARRAYSIZE
149       && se->arraysize > lastallocatedarraysize)
150     lastallocatedarraysize = se->arraysize;
151
152   for (idx=0; idx < se->arrayused; idx++)
153     if (se->array[idx])
154       xfree (se->array[idx]);
155   xfree (se->array);
156   xfree (se);
157 }
158
159
160 static gpg_error_t
161 delete_var (session_env_t se, const char *name)
162 {
163   int idx;
164
165   for (idx=0; idx < se->arrayused; idx++)
166     if (se->array[idx] && !strcmp (se->array[idx]->name, name))
167       {
168         xfree (se->array[idx]);
169         se->array[idx] = NULL;
170       }
171   return 0;
172 }
173
174
175 static gpg_error_t
176 update_var (session_env_t se, const char *string, size_t namelen,
177             const char *explicit_value, int set_default)
178 {
179   int idx;
180   int freeidx = -1;
181   const char *value;
182   size_t valuelen;
183   struct variable_s *var;
184
185   if (explicit_value)
186     value = explicit_value;
187   else
188     value = string + namelen + 1;
189   valuelen = strlen (value);
190
191   for (idx=0; idx < se->arrayused; idx++)
192     {
193       if (!se->array[idx])
194         freeidx = idx;
195       else if (!strncmp (se->array[idx]->name, string, namelen)
196                && strlen (se->array[idx]->name) == namelen)
197         {
198           if (strlen (se->array[idx]->value) == valuelen)
199             {
200               /* The new value has the same length.  We can update it
201                  in-place.  */
202               memcpy (se->array[idx]->value, value, valuelen);
203               se->array[idx]->is_default = !!set_default;
204               return 0;
205             }
206           /* Prepare for update.  */
207           freeidx = idx;
208         }
209     }
210
211   if (freeidx == -1)
212     {
213       if (se->arrayused == se->arraysize)
214         {
215           /* Reallocate the array. */
216           size_t newsize;
217           struct variable_s **newarray;
218
219           newsize = se->arraysize + CHUNK_ARRAYSIZE;
220           newarray = xtrycalloc (newsize, sizeof *newarray);
221           if (!newarray)
222             return gpg_error_from_syserror ();
223           for (idx=0; idx < se->arrayused; idx++)
224             newarray[idx] = se->array[idx];
225           se->arraysize = newsize;
226           xfree (se->array);
227           se->array = newarray;
228         }
229       freeidx = se->arrayused++;
230     }
231
232   /* Allocate new memory and return an error if that didn't worked.
233      Allocating it first allows us to keep the old value; it doesn't
234      matter that arrayused has already been incremented in case of a
235      new entry - it will then pint to a NULL slot.  */
236   var = xtrymalloc (sizeof *var + namelen + 1 + valuelen);
237   if (!var)
238     return gpg_error_from_syserror ();
239   var->is_default = !!set_default;
240   memcpy (var->name, string, namelen);
241   var->name[namelen] = '\0';
242   var->value = var->name + namelen + 1;
243   strcpy (var->value, value);
244
245   xfree (se->array[freeidx]);
246   se->array[freeidx] = var;
247   return 0;
248 }
249
250
251 /* Set or update an environment variable of the session environment.
252    String is similar to the putval(3) function but it is reentrant and
253    takes a copy.  In particular it exhibits this behaviour:
254
255           <NAME>            Delete envvar NAME
256           <KEY>=            Set envvar NAME to the empty string
257           <KEY>=<VALUE>     Set envvar NAME to VALUE
258
259    On success 0 is returned; on error an gpg-error code.  */
260 gpg_error_t
261 session_env_putenv (session_env_t se, const char *string)
262 {
263   const char *s;
264
265   if (!string || !*string)
266     return gpg_error (GPG_ERR_INV_VALUE);
267   s = strchr (string, '=');
268   if (s == string)
269     return gpg_error (GPG_ERR_INV_VALUE);
270   if (!s)
271     return delete_var (se, string);
272   else
273     return update_var (se, string, s - string, NULL, 0);
274 }
275
276
277 /* Same as session_env_putenv but with name and value given as distict
278    values.  */
279 gpg_error_t
280 session_env_setenv (session_env_t se, const char *name, const char *value)
281 {
282   if (!name || !*name)
283     return gpg_error (GPG_ERR_INV_VALUE);
284   if (!value)
285     return delete_var (se, name);
286   else
287     return update_var (se, name, strlen (name), value, 0);
288 }
289
290
291
292
293 /* Return the value of the environment variable NAME from the SE
294    object.  If the variable does not exist, NULL is returned.  The
295    returned value is valid as long as SE is valid and as long it has
296    not been removed or updated by a call to session_env_putenv.  The
297    caller MUST not change the returned value. */
298 char *
299 session_env_getenv (session_env_t se, const char *name)
300 {
301   int idx;
302
303   if (!se || !name || !*name)
304     return NULL;
305
306   for (idx=0; idx < se->arrayused; idx++)
307     if (se->array[idx] && !strcmp (se->array[idx]->name, name))
308       return se->array[idx]->is_default? NULL : se->array[idx]->value;
309   return NULL;
310 }
311
312
313 /* Return the value of the environment variable NAME from the SE
314    object.  The returned value is valid as long as SE is valid and as
315    long it has not been removed or updated by a call to
316    session_env_putenv.  If the variable does not exist, the function
317    tries to return the value trough a call to getenv; if that returns
318    a value, this value is recorded and and used.  If no value could be
319    found, returns NULL.  The caller must not change the returned
320    value. */
321 char *
322 session_env_getenv_or_default (session_env_t se, const char *name,
323                                int *r_default)
324 {
325   int idx;
326   char *defvalue;
327
328   if (r_default)
329     *r_default = 0;
330   if (!se || !name || !*name)
331     return NULL;
332
333   for (idx=0; idx < se->arrayused; idx++)
334     if (se->array[idx] && !strcmp (se->array[idx]->name, name))
335       {
336         if (r_default && se->array[idx]->is_default)
337           *r_default = 1;
338         return se->array[idx]->value;
339       }
340
341   /* Get the default value with an additional fallback for GPG_TTY.  */
342   defvalue = getenv (name);
343   if ((!defvalue || !*defvalue) && !strcmp (name, "GPG_TTY")
344       && gnupg_ttyname (0))
345     {
346       defvalue = gnupg_ttyname (0);
347     }
348   if (defvalue)
349     {
350       /* Record the default value for later use so that we are safe
351          from later modifications of the environment.  We need to take
352          a copy to better cope with the rules of putenv(3).  We ignore
353          the error of the update function because we can't return an
354          explicit error anyway and the following scan would then fail
355          anyway. */
356       update_var (se, name, strlen (name), defvalue, 1);
357
358       for (idx=0; idx < se->arrayused; idx++)
359         if (se->array[idx] && !strcmp (se->array[idx]->name, name))
360           {
361             if (r_default && se->array[idx]->is_default)
362               *r_default = 1;
363             return se->array[idx]->value;
364           }
365     }
366
367   return NULL;
368 }
369
370
371 /* List the entire environment stored in SE.  The caller initially
372    needs to set the value of ITERATOR to 0 and then call this function
373    until it returns NULL.  The value is retruned at R_VALUE.  If
374    R_DEFAULT is not NULL, the default flag is stored on return.  The
375    default flag indicates that the value has been taken from the
376    process' environment.  The caller must not change the returned
377    name or value.  */
378 char *
379 session_env_listenv (session_env_t se, int *iterator,
380                      const char **r_value, int *r_default)
381 {
382   int idx = *iterator;
383
384   if (!se || idx < 0)
385     return NULL;
386
387   for (; idx < se->arrayused; idx++)
388     if (se->array[idx])
389       {
390         *iterator = idx+1;
391         if (r_default)
392           *r_default = se->array[idx]->is_default;
393         if (r_value)
394           *r_value = se->array[idx]->value;
395         return se->array[idx]->name;
396       }
397   return NULL;
398 }