core: Do not crash if CMS plaintext is ignored
[gpgme.git] / src / get-env.c
1 /* get_env.c - A getenv() replacement.
2    Copyright (C) 2003, 2004 g10 Code GmbH
3
4    This file is part of GPGME.
5
6    GPGME is free software; you can redistribute it and/or modify it
7    under the terms of the GNU Lesser General Public License as
8    published by the Free Software Foundation; either version 2.1 of
9    the License, or (at your option) any later version.
10
11    GPGME is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19    02111-1307, USA.  */
20
21 #if HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <string.h>
27
28 #include "util.h"
29
30 \f
31 /* Retrieve the environment variable NAME and return a copy of it in a
32    malloc()'ed buffer in *VALUE.  If the environment variable is not
33    set, return NULL in *VALUE.  */
34
35 #ifdef HAVE_GETENV_R
36 #define INITIAL_GETENV_SIZE 32
37
38 gpgme_error_t
39 _gpgme_getenv (const char *name, char **value)
40 {
41   size_t len = INITIAL_GETENV_SIZE;
42   char *env_value;
43
44   env_value = malloc (len);
45
46   while (1)
47     {
48       *value = env_value;
49       if (!env_value)
50         return gpg_error_from_syserror ();
51
52       if (getenv_r (name, env_value, len) == 0)
53         break;
54
55       if (errno == ERANGE)
56         {
57           len *= 2;
58           env_value = realloc (env_value, len);
59         }
60       else
61         {
62           int saved = errno;
63
64           free (env_value);
65           *value = NULL;
66           if (errno == ENOENT)
67             return 0;
68           else
69           return gpg_error_from_errno (saved);
70         }
71     }
72
73   return 0;
74 }
75 #else
76 #ifndef HAVE_THREAD_SAFE_GETENV
77 GPGRT_LOCK_DEFINE (environ_lock);
78 #endif
79
80 gpgme_error_t
81 _gpgme_getenv (const char *name, char **value)
82 {
83   char *env_value;
84   gpgme_error_t err = 0;
85
86 #ifndef HAVE_THREAD_SAFE_GETENV
87   gpg_err_code_t rc;
88
89   rc= gpgrt_lock_lock (&environ_lock);
90   if (rc)
91     {
92       err = gpg_error (rc);
93       goto leave;
94     }
95 #endif
96   env_value = getenv (name);
97   if (!env_value)
98     *value = NULL;
99   else
100     {
101       *value = strdup (env_value);
102       if (!*value)
103         err = gpg_error_from_syserror ();
104     }
105 #ifndef HAVE_THREAD_SAFE_GETENV
106   rc = gpgrt_lock_unlock (&environ_lock);
107   if (rc)
108     err = gpg_error (rc);
109  leave:
110 #endif
111   return err;
112 }
113 #endif