Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include <string.h>
7 : #include <stdlib.h>
8 : #include "primpl.h"
9 : #include "prmem.h"
10 :
11 : #if defined(XP_UNIX)
12 : #include <unistd.h>
13 : #if defined(DARWIN)
14 : #if defined(HAVE_CRT_EXTERNS_H)
15 : #include <crt_externs.h>
16 : #endif /* HAVE_CRT_EXTERNS_H */
17 : #else /* DARWIN */
18 : PR_IMPORT_DATA(char **) environ;
19 : #endif /* DARWIN */
20 : #endif /* XP_UNIX */
21 :
22 : #if !defined(HAVE_SECURE_GETENV) && defined(HAVE___SECURE_GETENV)
23 : #define secure_getenv __secure_getenv
24 : #define HAVE_SECURE_GETENV 1
25 : #endif
26 :
27 : /* Lock used to lock the environment */
28 : #if defined(_PR_NO_PREEMPT)
29 : #define _PR_NEW_LOCK_ENV()
30 : #define _PR_DELETE_LOCK_ENV()
31 : #define _PR_LOCK_ENV()
32 : #define _PR_UNLOCK_ENV()
33 : #elif defined(_PR_LOCAL_THREADS_ONLY)
34 : extern _PRCPU * _pr_primordialCPU;
35 : static PRIntn _is;
36 : #define _PR_NEW_LOCK_ENV()
37 : #define _PR_DELETE_LOCK_ENV()
38 : #define _PR_LOCK_ENV() if (_pr_primordialCPU) _PR_INTSOFF(_is);
39 : #define _PR_UNLOCK_ENV() if (_pr_primordialCPU) _PR_INTSON(_is);
40 : #else
41 : static PRLock *_pr_envLock = NULL;
42 : #define _PR_NEW_LOCK_ENV() {_pr_envLock = PR_NewLock();}
43 : #define _PR_DELETE_LOCK_ENV() \
44 : { if (_pr_envLock) { PR_DestroyLock(_pr_envLock); _pr_envLock = NULL; } }
45 : #define _PR_LOCK_ENV() { if (_pr_envLock) PR_Lock(_pr_envLock); }
46 : #define _PR_UNLOCK_ENV() { if (_pr_envLock) PR_Unlock(_pr_envLock); }
47 : #endif
48 :
49 : /************************************************************************/
50 :
51 3 : void _PR_InitEnv(void)
52 : {
53 3 : _PR_NEW_LOCK_ENV();
54 3 : }
55 :
56 0 : void _PR_CleanupEnv(void)
57 : {
58 0 : _PR_DELETE_LOCK_ENV();
59 0 : }
60 :
61 : PR_IMPLEMENT(char*) PR_GetEnv(const char *var)
62 : {
63 : char *ev;
64 :
65 1359 : if (!_pr_initialized) _PR_ImplicitInitialization();
66 :
67 1359 : _PR_LOCK_ENV();
68 1359 : ev = _PR_MD_GET_ENV(var);
69 1359 : _PR_UNLOCK_ENV();
70 1359 : return ev;
71 : }
72 :
73 : PR_IMPLEMENT(char*) PR_GetEnvSecure(const char *var)
74 : {
75 : #ifdef HAVE_SECURE_GETENV
76 : char *ev;
77 :
78 : if (!_pr_initialized) _PR_ImplicitInitialization();
79 :
80 : _PR_LOCK_ENV();
81 : ev = secure_getenv(var);
82 : _PR_UNLOCK_ENV();
83 :
84 : return ev;
85 : #else
86 : #ifdef XP_UNIX
87 : /*
88 : ** Fall back to checking uids and gids. This won't detect any other
89 : ** privilege-granting mechanisms the platform may have. This also
90 : ** can't detect the case where the process already called
91 : ** setuid(geteuid()) and/or setgid(getegid()).
92 : */
93 42 : if (getuid() != geteuid() || getgid() != getegid()) {
94 0 : return NULL;
95 : }
96 : #endif /* XP_UNIX */
97 42 : return PR_GetEnv(var);
98 : #endif /* HAVE_SECURE_GETENV */
99 : }
100 :
101 : PR_IMPLEMENT(PRStatus) PR_SetEnv(const char *string)
102 : {
103 : PRIntn result;
104 :
105 15 : if (!_pr_initialized) _PR_ImplicitInitialization();
106 :
107 15 : if (!strchr(string, '=')) return(PR_FAILURE);
108 :
109 15 : _PR_LOCK_ENV();
110 15 : result = _PR_MD_PUT_ENV((char*)string);
111 15 : _PR_UNLOCK_ENV();
112 15 : return result ? PR_FAILURE : PR_SUCCESS;
113 : }
114 :
115 : #if defined(XP_UNIX) && (!defined(DARWIN) || defined(HAVE_CRT_EXTERNS_H))
116 : PR_IMPLEMENT(char **) PR_DuplicateEnvironment(void)
117 : {
118 : char **the_environ, **result, **end, **src, **dst;
119 :
120 3 : _PR_LOCK_ENV();
121 : #ifdef DARWIN
122 : the_environ = *(_NSGetEnviron());
123 : #else
124 3 : the_environ = environ;
125 : #endif
126 :
127 3 : for (end = the_environ; *end != NULL; end++)
128 : /* empty loop body */;
129 :
130 3 : result = (char **)PR_Malloc(sizeof(char *) * (end - the_environ + 1));
131 3 : if (result != NULL) {
132 294 : for (src = the_environ, dst = result; src != end; src++, dst++) {
133 : size_t len;
134 :
135 291 : len = strlen(*src) + 1;
136 291 : *dst = PR_Malloc(len);
137 291 : if (*dst == NULL) {
138 : /* Allocation failed. Must clean up the half-copied env. */
139 : char **to_delete;
140 :
141 0 : for (to_delete = result; to_delete != dst; to_delete++) {
142 0 : PR_Free(*to_delete);
143 : }
144 0 : PR_Free(result);
145 0 : result = NULL;
146 0 : goto out;
147 : }
148 291 : memcpy(*dst, *src, len);
149 : }
150 3 : *dst = NULL;
151 : }
152 : out:
153 3 : _PR_UNLOCK_ENV();
154 3 : return result;
155 : }
156 : #else
157 : /* This platform doesn't support raw access to the environ block. */
158 : PR_IMPLEMENT(char **) PR_DuplicateEnvironment(void)
159 : {
160 : return NULL;
161 : }
162 : #endif
|