Changes for Win32 support
1 | /* |
2 | * The contents of this file are subject to the AOLserver Public License |
3 | * Version 1.1 (the "License"); you may not use this file except in |
4 | * compliance with the License. You may obtain a copy of the License at |
5 | * http://aolserver.com/. |
6 | * |
7 | * Software distributed under the License is distributed on an "AS IS" |
8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
9 | * the License for the specific language governing rights and limitations |
10 | * under the License. |
11 | * |
12 | * The Original Code is AOLserver Code and related documentation |
13 | * distributed by AOL. |
14 | * |
15 | * The Initial Developer of the Original Code is America Online, |
16 | * Inc. Portions created by AOL are Copyright (C) 1999 America Online, |
17 | * Inc. All Rights Reserved. |
18 | * |
19 | * Alternatively, the contents of this file may be used under the terms |
20 | * of the GNU General Public License (the "GPL"), in which case the |
21 | * provisions of GPL are applicable instead of those above. If you wish |
22 | * to allow use of your version of this file only under the terms of the |
23 | * GPL and not to allow others to use your version of this file under the |
24 | * License, indicate your decision by deleting the provisions above and |
25 | * replace them with the notice and other provisions required by the GPL. |
26 | * If you do not delete the provisions above, a recipient may use your |
27 | * version of this file under either the License or the GPL. |
28 | */ |
29 | |
30 | |
31 | /* |
32 | * tclenv.c -- |
33 | * |
34 | * Implement the "ns_env" command. |
35 | */ |
36 | |
37 | static const char *RCSID = "@(#) $Header: /cvsroot-fuse/aolserver/aolserver/nsd/tclenv.c,v 1.14 2003/02/04 23:10:49 jrasmuss23 Exp $, compiled: " __DATE__ " " __TIME__; |
38 | |
39 | #include "nsd.h" |
40 | |
41 | static int <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_PutEnv">PutEnv</a>(Tcl_Interp *interp, char *name, char *value); |
42 | static Ns_Mutex lock; |
43 | #ifdef HAVE__NSGETENVIRON |
44 | #include <crt_externs.h> |
45 | #elif !defined(_WIN32) |
46 | extern char **environ; |
47 | #endif |
48 | |
49 | |
50 | /* |
51 | *---------------------------------------------------------------------- |
52 | * |
53 | * <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_Ns_CopyEnviron">Ns_CopyEnviron</a> -- |
54 | * |
55 | * Copy the environment to the given dstring along with |
56 | * an argv vector. |
57 | * |
58 | * Results: |
59 | * Pointer to dsPtr->string. |
60 | * |
61 | * Side effects: |
62 | * None. |
63 | * |
64 | *---------------------------------------------------------------------- |
65 | */ |
66 | |
67 | char ** |
68 | <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_Ns_CopyEnviron">Ns_CopyEnviron</a>(Ns_DString *dsPtr) |
69 | { |
70 | char *s, **envp; |
71 | int i; |
72 | |
73 | Ns_MutexLock(&lock); |
74 | envp = <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_Ns_GetEnviron">Ns_GetEnviron</a>(); |
75 | for (i = 0; (s = envp[i]) != NULL; ++i) { |
76 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringAppendArg">Ns_DStringAppendArg</a>(dsPtr, s); |
77 | } |
78 | Ns_MutexUnlock(&lock); |
79 | return <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringAppendArgv">Ns_DStringAppendArgv</a>(dsPtr); |
80 | } |
81 | |
82 | |
83 | /* |
84 | *---------------------------------------------------------------------- |
85 | * |
86 | * <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_NsTclEnvCmd">NsTclEnvCmd</a> -- |
87 | * |
88 | * Implement the "env" command. Read the code to see what it does. |
89 | * NOTE: The getenv() and putenv() routines are assumed MT safe |
90 | * and there's no attempt to avoid the race condition between |
91 | * finding a variable and using it. The reason is it's assumed |
92 | * the environment would only be modified, if ever, at startup. |
93 | * |
94 | * Results: |
95 | * A standard Tcl result. |
96 | * |
97 | * Side effects: |
98 | * Environment variables may be updated. |
99 | * |
100 | *---------------------------------------------------------------------- |
101 | */ |
102 | |
103 | int |
104 | <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_NsTclEnvCmd">NsTclEnvCmd</a>(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) |
105 | { |
106 | char *name, *value, **envp; |
107 | int status, i; |
108 | Tcl_DString ds; |
109 | |
110 | if (argc < 2) { |
111 | Tcl_AppendResult(interp, "wrong # args: should be \"", |
112 | argv[0], " command ?args ...?\"", NULL); |
113 | return TCL_ERROR; |
114 | } |
115 | |
116 | status = TCL_OK; |
117 | Ns_MutexLock(&lock); |
118 | if (STREQ(argv[1], "names")) { |
119 | if (argc != 2) { |
120 | Tcl_AppendResult(interp, "wrong # args: should be \"", |
121 | argv[0], " names\"", NULL); |
122 | status = TCL_ERROR; |
123 | } else { |
124 | Tcl_DStringInit(&ds); |
125 | envp = <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_Ns_GetEnviron">Ns_GetEnviron</a>(); |
126 | for (i = 0; envp[i] != NULL; ++i) { |
127 | name = envp[i]; |
128 | value = strchr(name, '='); |
129 | Tcl_DStringAppend(&ds, name, value ? value - name : -1); |
130 | Tcl_AppendElement(interp, ds.string); |
131 | Tcl_DStringTrunc(&ds, 0); |
132 | } |
133 | Tcl_DStringFree(&ds); |
134 | } |
135 | |
136 | } else if (STREQ(argv[1], "exists")) { |
137 | if (argc != 3) { |
138 | Tcl_AppendResult(interp, "wrong # args: should be \"", |
139 | argv[0], " exists name\"", NULL); |
140 | status = TCL_ERROR; |
141 | } else { |
142 | Tcl_SetResult(interp, getenv(argv[2]) ? "1" : "0", TCL_STATIC); |
143 | } |
144 | |
145 | } else if (STREQ(argv[1], "get")) { |
146 | if ((argc != 3 && argc != 4) || |
147 | (argc == 4 && !STREQ(argv[2], "-nocomplain"))) { |
148 | badargs: |
149 | Tcl_AppendResult(interp, "wrong # args: should be \"", |
150 | argv[0], " ", argv[1], " ?-nocomplain? name\"", NULL); |
151 | status = TCL_ERROR; |
152 | } |
153 | name = argv[argc-1]; |
154 | value = getenv(name); |
155 | if (value != NULL) { |
156 | Tcl_SetResult(interp, value, TCL_VOLATILE); |
157 | } else if (argc == 4) { |
158 | Tcl_AppendResult(interp, "no such environment variable: ", |
159 | argv[argc-1], NULL); |
160 | status = TCL_ERROR; |
161 | } |
162 | |
163 | } else if (STREQ(argv[1], "set")) { |
164 | if (argc != 4) { |
165 | Tcl_AppendResult(interp, "wrong # args: should be \"", |
166 | argv[0], " set name value\"", NULL); |
167 | status = TCL_ERROR; |
168 | } else { |
169 | status = <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_PutEnv">PutEnv</a>(interp, argv[2], argv[3]); |
170 | } |
171 | |
172 | } else if (STREQ(argv[1], "unset")) { |
173 | if ((argc != 3 && argc != 4) || |
174 | (argc == 4 && !STREQ(argv[2], "-nocomplain"))) { |
175 | goto badargs; |
176 | } |
177 | name = argv[argc-1]; |
178 | if (argc == 3 && getenv(name) == NULL) { |
179 | Tcl_AppendResult(interp, "no such environment variable: ", name, |
180 | NULL); |
181 | status = TCL_ERROR; |
182 | } else { |
183 | status = <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_PutEnv">PutEnv</a>(interp, name, ""); |
184 | } |
185 | |
186 | } else { |
187 | Tcl_AppendResult(interp, "unknown command \"", |
188 | argv[1], "\": should be exists, names, get, set, or unset", NULL); |
189 | status = TCL_ERROR; |
190 | } |
191 | |
192 | Ns_MutexUnlock(&lock); |
193 | return status; |
194 | } |
195 | |
196 | |
197 | /* |
198 | *---------------------------------------------------------------------- |
199 | * |
200 | * <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_PutEnv">PutEnv</a> -- |
201 | * |
202 | * <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_NsTclEnvCmd">NsTclEnvCmd</a> helper routine to update an environment variable. |
203 | * |
204 | * Results: |
205 | * TCL_OK or TCL_ERROR. |
206 | * |
207 | * Side effects: |
208 | * Environment variable is set. |
209 | * |
210 | *---------------------------------------------------------------------- |
211 | */ |
212 | |
213 | static int |
214 | <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_PutEnv">PutEnv</a>(Tcl_Interp *interp, char *name, char *value) |
215 | { |
216 | char *s; |
217 | size_t len; |
218 | |
219 | len = strlen(name); |
220 | if (value != NULL) { |
221 | len += strlen(value) + 1; |
222 | } |
223 | /* NB: Use malloc() directly as putenv() would expect. */ |
224 | s = malloc(len + 1); |
225 | if (s == NULL) { |
226 | Tcl_SetResult(interp, |
227 | "could not allocate memory for new env entry", TCL_STATIC); |
228 | return TCL_ERROR; |
229 | } |
230 | strcpy(s, name); |
231 | if (value != NULL) { |
232 | strcat(s, "="); |
233 | strcat(s, value); |
234 | } |
235 | if (putenv(s) != 0) { |
236 | Tcl_AppendResult(interp, "could not put environment entry \"", |
237 | s, "\": ", Tcl_PosixError(interp), NULL); |
238 | free(s); |
239 | return TCL_ERROR; |
240 | } |
241 | return TCL_OK; |
242 | } |
243 | |
244 | |
245 | /* |
246 | *---------------------------------------------------------------------- |
247 | * |
248 | * <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_Ns_GetEnviron">Ns_GetEnviron</a> -- |
249 | * |
250 | * Return the environment vector. |
251 | * |
252 | * Results: |
253 | * Pointer to environment. |
254 | * |
255 | * Side effects: |
256 | * None. |
257 | * |
258 | *---------------------------------------------------------------------- |
259 | */ |
260 | |
261 | char ** |
262 | <a href="/cvs/aolserver/aolserver/nsd/tclenv.c#A_Ns_GetEnviron">Ns_GetEnviron</a>(void) |
263 | { |
264 | char **envp; |
265 | |
266 | #ifdef HAVE__NSGETENVIRON |
267 | envp = *_NSGetEnviron(); |
268 | #else |
269 | envp = environ; |
270 | #endif |
271 | return envp; |
272 | } |
Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use