2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * File: spc-env.c $TOG: spc-env.c /main/9 1998/04/10 08:27:04 mgreess $
27 * (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
29 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
30 * (c) Copyright 1993, 1994 International Business Machines Corp. *
31 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
32 * (c) Copyright 1993, 1994 Novell, Inc. *
37 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
41 #include <bms/MemoryMgr.h>
42 #include "DtSvcLock.h"
44 #include <XlationSvc.h>
45 #include <LocaleXlate.h>
47 /* External declarations */
49 extern XeString official_hostname; /* from spc-net.c */
51 /*----------------------------------------------------------------------+*/
52 XeString SPC_Getenv(XeString var,
54 /*----------------------------------------------------------------------+*/
61 /* First, check that we have real values */
63 if(!var || !envp || !*envp)
64 return(XeString_NULL);
68 idx=strchr(var, Equal);
71 /* No '='. Just use the entire var string */
74 /* found '='. Diddle pointers to get index of var */
75 len=(strchr(var, Equal))-var;
77 for(envidx=envp; *envidx; envidx++) {
78 if(!strncmp(*envidx, var, len))
79 /* Found a match. Return value part */
80 return(*envidx+len+1);
83 return(XeString_NULL);
89 ** The purpose of SPC_Putenv is to maintain the environment pointers
90 ** associated with a given channel. It differs from the normal putenv
91 ** routine in the following ways:
92 ** 1. It copies its arguments (and frees any arguments which get a "hit")
93 ** 2. It takes an environment pointer which will be used to store the
94 ** new value. This new pointer may change (via realloc).
96 ** Note: This routine makes a number of assumptions:
97 ** 1. The envp pointer was allocated via malloc.
98 ** 2. That it is okay to ignore error conditions. In particular,
99 ** it will ignore incorrect pointers (which is okay, as this
100 ** guy is an internal routine which means that these pointers
101 ** have been already checked), and it will ignore syntax errors
102 ** in the passed value. The latter ignore may be slightly
103 ** problematical, but it happens.
104 ** 3. That memory allocation errors cause the program to bomb.
108 /*----------------------------------------------------------------------+*/
109 XeString *SPC_Putenv(XeString val,
111 /*----------------------------------------------------------------------+*/
117 int remove_command = 0;
119 int is_multibyte = 0;
129 /* Again, check for real values */
137 len=(strchr(val, (XeChar)'='))-val;
140 * This string doesn't contain an '='. This may be OK if
141 * the string contains a 'remove environment variable' keyword.
142 * If this keyword is found, treat it like a variable and
143 * the SPC daemon will find it and remove it from the
144 * environment before it exec's a subprocess.
146 * If the string contains some white space before the variable
147 * or keyword, skip the white space.
152 (!is_multibyte || (mblen (pch, MB_CUR_MAX) == 1)) &&
154 isspace ((u_char)*pch))
158 if (strncmp (pch, SPC_REMOVE_VAR, strlen (SPC_REMOVE_VAR)))
162 len = strlen (SPC_REMOVE_VAR);
165 for(envptr=envp; *envptr; envptr++) {
166 if(!strncmp(*envptr, val, len) && !remove_command) {
167 /* Found a match. Replace this value with the one passed */
169 *envptr=SPC_copy_string(val);
174 /* No match. We need to expand this env pointer, and stash the
175 new value at the end */
179 /* calculate new size needed:
180 len=ptr to null element
181 newsize=len+2 (one for NULL, one for new element)
184 newsize=(len+2)*sizeof(XeString *);
186 /* Expand envp. This is a potentially expensive operation, if the
187 realloc routine is not smart. */
189 if(!(envp=(XeString *)realloc((char *)envp, newsize))) {
190 SPC_Error(SPC_Out_Of_Memory);
194 /* Okay. We got the new memory. Stash the new variable into it &
195 return the new envp.*/
197 envp[len]=SPC_copy_string(val);
198 envp[len+1]=XeChar_NULL;
204 /*----------------------------------------------------------------------+*/
205 XeString *SPC_Add_Env_File(XeString filename,
207 /*----------------------------------------------------------------------+*/
212 XeChar fbuffer[BUFSIZ];
219 if(!(f=fopen(filename, "r")))
222 while(fgets(fbuffer, BUFSIZ, f)) {
224 if(fbuffer[n-1]==Newline)
225 fbuffer[--n]=Pad; /* get rid of the extra newline */
227 /* Should we skip this line? */
229 if(n==XeChar_NULL || fbuffer[0]==Pad || fbuffer[0]==Pound) continue;
231 envp=SPC_Putenv(fbuffer, envp);
239 /*----------------------------------------------------------------------+*/
240 XeString *SPC_Create_Default_Envp(XeString *old_envp)
241 /*----------------------------------------------------------------------+*/
247 XeString sys_env_path = NULL;
252 envp=(XeString *)XeMalloc(sizeof(XeString) * DEFAULT_ENVP_SIZE);
256 if(!(envVar=getenv("DISPLAY")))
258 display = (XeChar *)malloc(
259 (strlen(official_hostname) + 11) * sizeof(XeChar));
260 if (display != (XeChar *)NULL)
261 sprintf(display, "DISPLAY=%s:0", official_hostname);
265 display = (XeChar *)malloc((strlen(envVar) + 9) * sizeof(XeChar));
266 if (display != (XeChar *)NULL)
267 sprintf(display, "DISPLAY=%s", envVar);
270 if (display != (XeChar *)NULL)
272 envp=SPC_Putenv(display, envp);
277 * Should we pick a default value for LANG (e.g. "C")?
278 * For now we ignore it if it is not already set.
280 if ((envVar = getenv("LANG")) != (XeString)NULL)
284 if ((langBuf = (XeChar *)malloc((strlen(envVar) + 6) * sizeof(XeChar)))
287 sprintf(langBuf, "LANG=%s", envVar);
288 envp = SPC_Putenv(langBuf, envp);
295 * First add the installed environment file.
297 sys_env_path = (XeString) malloc (strlen(SPCD_ENV_INSTALL_DIRECTORY) +
298 strlen(SPCD_ENV_FILE) + 3);
299 (void) sprintf (sys_env_path, "%s/%s",
300 SPCD_ENV_INSTALL_DIRECTORY,
302 envp=SPC_Add_Env_File(sys_env_path, envp);
305 * Next add the configured environment file.
307 sys_env_path = (XeString) realloc (sys_env_path,
308 strlen(SPCD_ENV_CONFIG_DIRECTORY) +
309 strlen(SPCD_ENV_FILE) + 3);
310 (void) sprintf (sys_env_path, "%s/%s",
311 SPCD_ENV_CONFIG_DIRECTORY,
313 envp=SPC_Add_Env_File(sys_env_path, envp);
316 * Now add the user environment file
319 envp=SPC_Add_Env_File(spc_user_environment_file, envp);
320 _DtSvcProcessUnlock();
327 /* Final cleanup of environment pointer */
329 /*----------------------------------------------------------------------+*/
330 XeString *SPC_Fixup_Environment(XeString *envp,
331 SPC_Channel_Ptr channel)
332 /*----------------------------------------------------------------------+*/
337 if (IS_REMOTE(channel))
339 XeString disp, myLang;
341 disp=SPC_Getenv((XeString)"DISPLAY", envp);
343 /* I don't particularly like hard coding these values here.
344 I have been bitten before by doing so, and probably will again... */
345 if (!strncmp(disp, (XeString)"unix", 4) ||
346 !strncmp(disp, (XeString)"local", 5) ||
347 !strncmp(disp, (XeString)":", 1))
349 XeChar *dispBuf = NULL;
351 XeChar null=XeChar_NULL;
354 (XeChar*) malloc(MAXHOSTNAMELEN + sizeof((XeString)"DISPLAY=:0.0") + 1);
357 screenptr=strchr(disp, Colon);
358 sprintf(dispBuf, "DISPLAY=%s%s",
360 screenptr ? screenptr : &null);
362 envp=SPC_Putenv(dispBuf, envp);
367 myLang = SPC_Getenv((XeString)"LANG", envp);
370 _DtXlateDb db = NULL;
371 char platform[_DtPLATFORM_MAX_LEN];
377 if (_DtLcxOpenAllDbs(&db) == 0)
379 if ((_DtXlateGetXlateEnv(db, platform, &execVer, &compVer) == 0) &&
380 (_DtLcxXlateOpToStd(db, platform, compVer, DtLCX_OPER_SETLOCALE,
381 myLang, &stdLang, NULL, NULL, NULL) == 0))
383 if ((langBuf = (XeChar *)malloc((strlen(stdLang) + 6) *
387 sprintf(langBuf, "LANG=%s", stdLang);
388 envp = SPC_Putenv(langBuf, envp);
403 /*----------------------------------------------------------------------+*/
404 XeString *SPC_Merge_Envp(XeString *dest_envp,
405 XeString *source_envp)
406 /*----------------------------------------------------------------------+*/
409 if(!dest_envp || !source_envp)
411 for(; *source_envp; source_envp++)
412 dest_envp=SPC_Putenv(*source_envp, dest_envp);
417 /*----------------------------------------------------------------------+*/
418 void SPC_Free_Envp(XeString *envp)
419 /*----------------------------------------------------------------------+*/
421 XeString *envptr=envp;