EnvControl.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  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
  22. */
  23. /****************************<+>*************************************
  24. ********************************************************************
  25. **
  26. ** File: EnvControl.c
  27. **
  28. ** $TOG: EnvControl.c /main/21 1999/01/28 17:59:53 mgreess $
  29. **
  30. ** Project: DtSvc Runtime Library
  31. **
  32. ** Description: Get/Set the client's shell environment
  33. **
  34. **(c) Copyright 1992,1993,1994 by Hewlett-Packard Company
  35. **(c) Copyright 1993,1994 International Business Machines Corp.
  36. **(c) Copyright 1993,1994 Sun Microsystems, Inc.
  37. **(c) Copyright 1993,1994 Unix System Labs, Inc., a subsidiary of Novell, Inc.
  38. **
  39. ********************************************************************
  40. ****************************<+>*************************************/
  41. #include <stdlib.h>
  42. #include <stdio.h>
  43. #define X_INCLUDE_STRING_H
  44. #define XOS_USE_XT_LOCKING
  45. #include <X11/Xos_r.h>
  46. #include <X11/Intrinsic.h>
  47. #include <X11/Xatom.h>
  48. #include <Dt/DtosP.h>
  49. #include <Dt/DtNlUtils.h>
  50. #include "EnvControlP.h"
  51. #include "EnvControlI.h"
  52. #include "DtSvcLock.h"
  53. static int _DtEnvRemove(char *str, int length);
  54. extern char **environ;
  55. /*
  56. * We assume that the following fields of these static structures
  57. * are initialized at runtime to NULL pointers.
  58. */
  59. static struct environStruct _postDtEnvironment;
  60. static struct environStruct _preDtEnvironment;
  61. /* envBitVector is used to determine whether an environment
  62. * variable has been put to the environment by the application.
  63. * The flag values are in EnvControlI.h.
  64. */
  65. static unsigned int envBitVector = 0;
  66. static void _EnvAdd (char *, char *, unsigned int);
  67. /****************************************************************
  68. * NOTES on an application's environ(5):
  69. *
  70. * The environment variable is an array of NULL-terminated strings.
  71. * char **environ is defined in crt.o and is publicly extern-ed to
  72. * all applications. There is one such variable per UN*X application.
  73. *
  74. * To deference an environment string, as in the debugger, use:
  75. *
  76. * environ[0] -- environ[n-1], where n is the number of
  77. * name=value pairs.
  78. *
  79. * E.g, in xdb:
  80. *
  81. * >p environ[0]
  82. *
  83. * You must manually malloc() space to keep a specific environment string
  84. * around.
  85. *
  86. * putenv() is useless at NULLing out an environment variable. It will
  87. * create a new value and will replace an existing value; however,
  88. * in terms of getting rid of an environment variable, putenv() will only
  89. * replace it with a NULL string ("") rather than freeing the space
  90. * for it and NULLing the pointer. Afterwards, getenv() will return
  91. * the NULL string rather than a NULL pointer, and hence give "incorrect"
  92. * information to an application querying for a non-set environment
  93. * variable.
  94. *
  95. * E.g., there's a big difference between the following pairs
  96. * to XmGetPixmap():
  97. *
  98. * XBMLANGPATH=""
  99. *
  100. * --and--
  101. *
  102. * XBMLANGPATH=<null pointer>
  103. *
  104. * The first will cause XmGetPixmap() to look nowhere for an icon image;
  105. * the second will cause a lookup in all the default locations, which
  106. * is what you want.
  107. *
  108. * Bottom line is that you have to NULL out an unneeded environ manually.
  109. *
  110. * The environment array is able to be jerked any which way you'd like,
  111. * using direct string/pointer manipulations. However, for safety:
  112. * make a local copy of **environ.
  113. *
  114. ********************************************************************/
  115. /*
  116. * Common suffixes for icon pixmap and icon bitmap paths. Each array must end
  117. * with a null pointer. Note: the unusual string concatenation is necessary
  118. * in order to prevent expansion of SCCS id keywords.
  119. */
  120. static const char *iconPmSuffixes[] = {
  121. "%B" "%M.pm",
  122. "%B" "%M.bm",
  123. "%B",
  124. NULL
  125. };
  126. static const char *iconBmSuffixes[] = {
  127. "%B" "%M.bm",
  128. "%B" "%M.pm",
  129. "%B",
  130. NULL
  131. };
  132. /*
  133. * makeDefaultIconPath
  134. *
  135. * Construct the icon pixmap or bitmap search path by constructing the values
  136. * from the home directory, and then appending the system default path. The
  137. * output is of the form "var=value", suitable for passing to putenv().
  138. *
  139. * Output:
  140. *
  141. * outbuf A pointer to the memory to receive the output value. This
  142. * must be large enough to accommodate the largest anticipated
  143. * environment variable; no bounds checking is done!
  144. *
  145. * Inputs:
  146. *
  147. * varname The environment variable name.
  148. * basedefault The default value to be appended to the end.
  149. * suffixes An array of suffixes used in constructing the path elements in
  150. * the user's home directory. Must have a trailing NULL pointer.
  151. */
  152. static char *
  153. makeDefaultIconPath(
  154. const char *varname,
  155. const char *basedefault,
  156. const char **suffixes)
  157. {
  158. char *fmt = "%s/.dt/icons/%s:";
  159. char *homedir;
  160. char *outbuf;
  161. int bytes_needed, fmt_bytes, homedir_bytes;
  162. bytes_needed = strlen(varname) + strlen(basedefault) + 2;
  163. homedir = getenv("HOME");
  164. if (NULL != homedir)
  165. {
  166. homedir_bytes = strlen(homedir);
  167. fmt_bytes = strlen(fmt);
  168. for ( ; *suffixes ; ++suffixes)
  169. bytes_needed += (homedir_bytes + fmt_bytes + strlen(*suffixes));
  170. }
  171. outbuf = XtMalloc(bytes_needed);
  172. (void)sprintf(outbuf, "%s=", varname);
  173. if (homedir != NULL)
  174. {
  175. char *temp = XtMalloc(bytes_needed);
  176. for ( ; *suffixes ; ++suffixes)
  177. {
  178. (void)sprintf(temp, fmt, homedir, *suffixes);
  179. (void)strcat(outbuf, temp);
  180. }
  181. if (temp) XtFree(temp);
  182. }
  183. (void)strcat(outbuf, basedefault);
  184. return outbuf;
  185. }
  186. /*
  187. * Construct a default value for XMICONSEARCHPATH into outbuf.
  188. */
  189. static char *
  190. makeDefaultIconPmPath(void)
  191. {
  192. static char *defaultIconPmPath = NULL;
  193. if (NULL == defaultIconPmPath)
  194. defaultIconPmPath =
  195. makeDefaultIconPath(PM_PATH_ENVIRON, DTPMSYSDEFAULT, iconPmSuffixes);
  196. return XtNewString(defaultIconPmPath);
  197. }
  198. /*
  199. * Construct a default value for XMICONBMSEARCHPATH into outbuf.
  200. */
  201. static char *
  202. makeDefaultIconBmPath(void)
  203. {
  204. static char *defaultIconBmPath = NULL;
  205. if (NULL == defaultIconBmPath)
  206. defaultIconBmPath =
  207. makeDefaultIconPath(BM_PATH_ENVIRON, DTBMSYSDEFAULT, iconBmSuffixes);
  208. return XtNewString(defaultIconBmPath);
  209. }
  210. /*****************************<->*************************************
  211. *
  212. * _DtEnvSessionManager ()
  213. *
  214. *
  215. * Description:
  216. * -----------
  217. * Sets the SESSION_MANAGER environment variable if not already set.
  218. *
  219. * Inputs:
  220. * ------
  221. * NONE
  222. *
  223. * Returns:
  224. * --------
  225. * void
  226. *
  227. *****************************<->***********************************/
  228. void
  229. _DtEnvSessionManager(void)
  230. {
  231. #define SESSION_MANAGER "SESSION_MANAGER"
  232. char *session_manager = getenv(SESSION_MANAGER);
  233. if (NULL == session_manager)
  234. {
  235. Display *display;
  236. Atom sm_atom;
  237. display = XOpenDisplay(NULL);
  238. if (NULL != display)
  239. {
  240. sm_atom = XInternAtom(display, SESSION_MANAGER, True);
  241. if (None != sm_atom)
  242. {
  243. Atom actual_type;
  244. unsigned long nitems, leftover;
  245. int actual_format;
  246. if (Success == XGetWindowProperty(
  247. display, XDefaultRootWindow(display),
  248. sm_atom, 0L, 256, False, XA_STRING,
  249. &actual_type, &actual_format,
  250. &nitems, &leftover,
  251. (unsigned char **) &session_manager))
  252. {
  253. if (NULL != session_manager && None != actual_format)
  254. {
  255. char *envstr;
  256. envstr = (char*) malloc(
  257. strlen(SESSION_MANAGER) +
  258. strlen(session_manager) + 2);
  259. sprintf(
  260. envstr, "%s=%s",
  261. SESSION_MANAGER,
  262. session_manager);
  263. putenv(envstr);
  264. XtFree(session_manager);
  265. }
  266. }
  267. }
  268. XCloseDisplay(display);
  269. }
  270. }
  271. }
  272. /*****************************<->*************************************
  273. *
  274. * _DtEnvControl ( int mode )
  275. *
  276. *
  277. * Description:
  278. * -----------
  279. * Gets/Sets the application's environment
  280. *
  281. * Inputs:
  282. * ------
  283. * mode - the command to the function; e.g., to set the
  284. * DT environment, to restore the originial env., etc.
  285. *
  286. * Returns:
  287. * --------
  288. * Returns a success code--usually just the value of the original
  289. * mode parameter. If an error occurs, returns DT_ENV_NO_OP.
  290. *
  291. *****************************<->***********************************/
  292. int
  293. _DtEnvControl(
  294. int mode )
  295. {
  296. static int environSetup = 0;
  297. char *tempString;
  298. char *ptr; /* used for indexing into the $PATH */
  299. int returnValue = DT_ENV_NO_OP;
  300. int bytes_needed;
  301. _DtSvcProcessLock();
  302. switch (mode) {
  303. case DT_ENV_SET:
  304. if (!environSetup) /* first time through */
  305. {
  306. /*
  307. * Make sure the SESSION_MANAGER variable is set.
  308. */
  309. _DtEnvSessionManager();
  310. /*
  311. * Set up DT environment in the application
  312. * environment, while stashing the old environment
  313. * in the _preDtEnvironment structure
  314. *
  315. * Note: this code will not check for duplicate
  316. * environment values--it will append or prepend
  317. * the DT environment values regardless of what's
  318. * in the current environment.
  319. *
  320. * Of the form:
  321. *
  322. * PATH = /opt/dt/bin : originalPath
  323. * %s %s %s %s %s
  324. *
  325. *
  326. * XBMLANGPATH = originalPath : dtPath
  327. * %s %s %s %s %s
  328. *
  329. * Note: Of all the environmental vars, ONLY $PATH
  330. * is jammed with the DT value first.
  331. *
  332. * Check for NULL environment strings before the sprintf
  333. *
  334. */
  335. /*
  336. * Get the application's original environment
  337. * to save it in the _preDtEnvironment structure
  338. *
  339. * We save in the _preDtEnvironment structure
  340. * only existing (non-NULL getenv()) values.
  341. *
  342. */
  343. /*
  344. * Prepend BIN_PATH_STRING to the PATH component.
  345. */
  346. tempString = getenv(BIN_PATH_ENVIRON);
  347. /*
  348. * First, ensure that BIN_PATH_STRING isn't already there.
  349. */
  350. if (!tempString || !(strstr(tempString, BIN_PATH_STRING)))
  351. {
  352. if (!tempString)
  353. {
  354. /*
  355. * No existing PATH environment variable.
  356. * Just create the new DT environment.
  357. */
  358. bytes_needed =
  359. strlen(BIN_PATH_ENVIRON) + strlen(BIN_PATH_STRING) +2;
  360. _postDtEnvironment.binPath = XtMalloc(bytes_needed);
  361. sprintf(_postDtEnvironment.binPath,
  362. "%s=%s",
  363. BIN_PATH_ENVIRON,
  364. BIN_PATH_STRING);
  365. }
  366. else
  367. {
  368. /*
  369. * Save the existing PATH.
  370. */
  371. bytes_needed =
  372. strlen(BIN_PATH_ENVIRON) + strlen(tempString) + 2;
  373. _preDtEnvironment.binPath = XtMalloc(bytes_needed);
  374. sprintf(_preDtEnvironment.binPath,
  375. "%s=%s",
  376. BIN_PATH_ENVIRON,
  377. tempString);
  378. bytes_needed =
  379. strlen(tempString) +
  380. strlen(BIN_PATH_ENVIRON) +
  381. strlen(BIN_PATH_STRING) + 4;
  382. _postDtEnvironment.binPath = XtMalloc(bytes_needed);
  383. #ifdef sun
  384. if ((ptr = strstr(tempString, "/usr/openwin/bin")))
  385. #elif defined(CSRG_BASED)
  386. if ((ptr = strstr(tempString, "/usr/X11R6/bin")))
  387. #elif defined(__linux__)
  388. if ((ptr = strstr(tempString, "/usr/bin")))
  389. #else
  390. if ((ptr = strstr(tempString, "/usr/bin/X11")))
  391. #endif
  392. {
  393. /*
  394. * Shorten the string in tempString
  395. * to the initial segment, up to the
  396. * initial slash in "/usr/bin/X11"
  397. */
  398. if (ptr != tempString)
  399. {
  400. /*
  401. * then put our dt string just ahead of
  402. * "/usr/bin/X11" in the new PATH
  403. */
  404. *(ptr - 1) = '\0';
  405. sprintf(_postDtEnvironment.binPath,
  406. "%s=%s:%s:%s",
  407. BIN_PATH_ENVIRON,
  408. tempString,
  409. BIN_PATH_STRING,
  410. ptr);
  411. }
  412. else
  413. {
  414. /*
  415. * Turns out that "/usr/bin/X11"
  416. * is at the front of the PATH, so...
  417. */
  418. sprintf(_postDtEnvironment.binPath,
  419. "%s=%s:%s",
  420. BIN_PATH_ENVIRON,
  421. BIN_PATH_STRING,
  422. tempString);
  423. }
  424. }
  425. else if (ptr = strstr(tempString, "/usr/bin"))
  426. {
  427. /*
  428. * Shorten the string in tempString
  429. * to the initial segment, up to the
  430. * initial slash in "/usr/bin"
  431. */
  432. if (ptr != tempString)
  433. {
  434. /*
  435. * then put our dt string just ahead of
  436. * "/usr/bin" in the new PATH
  437. */
  438. *(ptr - 1) = '\0';
  439. sprintf(_postDtEnvironment.binPath,
  440. "%s=%s:%s:%s",
  441. BIN_PATH_ENVIRON,
  442. tempString,
  443. BIN_PATH_STRING,
  444. ptr);
  445. }
  446. else
  447. {
  448. /*
  449. * Turns out that "/usr/bin"
  450. * is at the front of the PATH, so...
  451. */
  452. sprintf(_postDtEnvironment.binPath,
  453. "%s=%s:%s",
  454. BIN_PATH_ENVIRON,
  455. BIN_PATH_STRING,
  456. tempString);
  457. }
  458. }
  459. else
  460. {
  461. /*
  462. * Put our dt string on the front of the PATH
  463. */
  464. sprintf(_postDtEnvironment.binPath,
  465. "%s=%s:%s",
  466. BIN_PATH_ENVIRON,
  467. BIN_PATH_STRING,
  468. tempString);
  469. }
  470. }
  471. _EnvAdd (BIN_PATH_ENVIRON,
  472. _postDtEnvironment.binPath,
  473. BV_BINPATH);
  474. }
  475. tempString = getenv(PM_PATH_ENVIRON);
  476. if (tempString)
  477. {
  478. bytes_needed =
  479. strlen(PM_PATH_ENVIRON) + strlen(tempString) + 2;
  480. _preDtEnvironment.pmPath = XtMalloc(bytes_needed);
  481. sprintf(_preDtEnvironment.pmPath,
  482. "%s=%s",
  483. PM_PATH_ENVIRON,
  484. tempString);
  485. }
  486. else
  487. {
  488. /* it doesn't exist, so generate a default value */
  489. _postDtEnvironment.pmPath = makeDefaultIconPmPath();
  490. _EnvAdd(PM_PATH_ENVIRON, _postDtEnvironment.pmPath,
  491. BV_PMPATH);
  492. }
  493. tempString = getenv(BM_PATH_ENVIRON);
  494. if (tempString)
  495. {
  496. bytes_needed =
  497. strlen(BM_PATH_ENVIRON) + strlen(tempString) + 2;
  498. _preDtEnvironment.bmPath = XtMalloc(bytes_needed);
  499. sprintf(_preDtEnvironment.bmPath,
  500. "%s=%s",
  501. BM_PATH_ENVIRON,
  502. tempString);
  503. }
  504. else
  505. {
  506. /* it doesn't exist, so generate a default value */
  507. _postDtEnvironment.bmPath = makeDefaultIconBmPath();
  508. _EnvAdd(BM_PATH_ENVIRON, _postDtEnvironment.bmPath,
  509. BV_BMPATH);
  510. }
  511. /* Do the admin for the NLSPATH env variable */
  512. tempString = getenv(NLS_PATH_ENVIRON);
  513. if (!tempString)
  514. {
  515. /* If it doesn't exist, set it to the CDE default */
  516. bytes_needed =
  517. strlen(NLS_PATH_ENVIRON) + strlen(NLS_PATH_STRING) + 2;
  518. _postDtEnvironment.nlsPath = XtMalloc(bytes_needed);
  519. sprintf(_postDtEnvironment.nlsPath,
  520. "%s=%s",
  521. NLS_PATH_ENVIRON,
  522. NLS_PATH_STRING);
  523. }
  524. else
  525. {
  526. /* If it does exist, store it away so it can be
  527. * restored afterwards.....
  528. */
  529. bytes_needed =
  530. strlen(NLS_PATH_ENVIRON) + strlen(tempString) + 2;
  531. _preDtEnvironment.nlsPath = XtMalloc(bytes_needed);
  532. sprintf(_preDtEnvironment.nlsPath,
  533. "%s=%s",
  534. NLS_PATH_ENVIRON,
  535. tempString);
  536. /* ... then append the CDE default to the existing
  537. * value
  538. */
  539. bytes_needed =
  540. strlen(NLS_PATH_ENVIRON) +
  541. strlen(tempString) +
  542. strlen(NLS_PATH_STRING) + 3;
  543. _postDtEnvironment.nlsPath = XtMalloc(bytes_needed);
  544. sprintf(_postDtEnvironment.nlsPath,
  545. "%s=%s:%s",
  546. NLS_PATH_ENVIRON,
  547. tempString,
  548. NLS_PATH_STRING);
  549. }
  550. _EnvAdd(NLS_PATH_ENVIRON, _postDtEnvironment.nlsPath,
  551. BV_NLSPATH);
  552. tempString = getenv(SYSTEM_APPL_PATH_ENVIRON);
  553. if (!tempString)
  554. {
  555. bytes_needed =
  556. strlen(SYSTEM_APPL_PATH_ENVIRON) +
  557. strlen(SYSTEM_APPL_PATH_STRING) + 2;
  558. _postDtEnvironment.sysApplPath = XtMalloc(bytes_needed);
  559. sprintf(_postDtEnvironment.sysApplPath,
  560. "%s=%s",
  561. SYSTEM_APPL_PATH_ENVIRON,
  562. SYSTEM_APPL_PATH_STRING);
  563. }
  564. else
  565. {
  566. bytes_needed =
  567. strlen(SYSTEM_APPL_PATH_ENVIRON) + strlen(tempString) + 2;
  568. _preDtEnvironment.sysApplPath = XtMalloc(bytes_needed);
  569. sprintf(_preDtEnvironment.sysApplPath,
  570. "%s=%s",
  571. SYSTEM_APPL_PATH_ENVIRON,
  572. tempString);
  573. bytes_needed =
  574. strlen(SYSTEM_APPL_PATH_ENVIRON) +
  575. strlen(tempString) +
  576. strlen(SYSTEM_APPL_PATH_STRING) + 3;
  577. _postDtEnvironment.sysApplPath = XtMalloc(bytes_needed);
  578. sprintf(_postDtEnvironment.sysApplPath,
  579. "%s=%s:%s",
  580. SYSTEM_APPL_PATH_ENVIRON,
  581. tempString,
  582. SYSTEM_APPL_PATH_STRING);
  583. }
  584. _EnvAdd (SYSTEM_APPL_PATH_ENVIRON,
  585. _postDtEnvironment.sysApplPath,
  586. BV_SYSAPPLPATH);
  587. environSetup = 1;
  588. returnValue = DT_ENV_SET;
  589. }
  590. else /* we've already been here -- do nothing */
  591. {
  592. returnValue = DT_ENV_NO_OP;
  593. }
  594. break;
  595. case DT_ENV_RESTORE_PRE_DT:
  596. if (environSetup)
  597. {
  598. if (_preDtEnvironment.nlsPath) {
  599. _EnvAdd (NLS_PATH_ENVIRON,
  600. _preDtEnvironment.nlsPath,
  601. BV_NLSPATH);
  602. }
  603. else {
  604. _DtEnvRemove(NLS_PATH_ENVIRON, 0);
  605. envBitVector &= ~BV_NLSPATH;
  606. }
  607. if (_preDtEnvironment.sysApplPath) {
  608. _EnvAdd (SYSTEM_APPL_PATH_ENVIRON,
  609. _preDtEnvironment.sysApplPath,
  610. BV_SYSAPPLPATH);
  611. }
  612. else {
  613. _DtEnvRemove(SYSTEM_APPL_PATH_ENVIRON, 0);
  614. envBitVector &= ~BV_SYSAPPLPATH;
  615. }
  616. if (_preDtEnvironment.pmPath) {
  617. _EnvAdd (PM_PATH_ENVIRON,
  618. _preDtEnvironment.pmPath,
  619. BV_PMPATH);
  620. }
  621. else {
  622. _DtEnvRemove(PM_PATH_ENVIRON, 0);
  623. envBitVector &= ~BV_PMPATH;
  624. }
  625. if (_preDtEnvironment.bmPath) {
  626. _EnvAdd (BM_PATH_ENVIRON,
  627. _preDtEnvironment.bmPath,
  628. BV_BMPATH);
  629. }
  630. else {
  631. _DtEnvRemove(BM_PATH_ENVIRON, 0);
  632. envBitVector &= ~BV_BMPATH;
  633. }
  634. returnValue = DT_ENV_RESTORE_PRE_DT;
  635. }
  636. else
  637. {
  638. returnValue = DT_ENV_NO_OP;
  639. }
  640. break;
  641. case DT_ENV_RESTORE_POST_DT:
  642. if (environSetup)
  643. {
  644. if (_postDtEnvironment.nlsPath) {
  645. _EnvAdd (NLS_PATH_ENVIRON,
  646. _postDtEnvironment.nlsPath,
  647. BV_NLSPATH);
  648. }
  649. if (_postDtEnvironment.pmPath) {
  650. _EnvAdd (PM_PATH_ENVIRON,
  651. _postDtEnvironment.pmPath,
  652. BV_PMPATH);
  653. }
  654. if (_postDtEnvironment.bmPath) {
  655. _EnvAdd (BM_PATH_ENVIRON,
  656. _postDtEnvironment.bmPath,
  657. BV_BMPATH);
  658. }
  659. if (_postDtEnvironment.sysApplPath) {
  660. _EnvAdd (SYSTEM_APPL_PATH_ENVIRON,
  661. _postDtEnvironment.sysApplPath,
  662. BV_SYSAPPLPATH);
  663. }
  664. returnValue = DT_ENV_RESTORE_POST_DT;
  665. }
  666. else
  667. {
  668. returnValue = DT_ENV_NO_OP;
  669. }
  670. break;
  671. default:
  672. /* do nothing */
  673. break;
  674. }
  675. _DtSvcProcessUnlock();
  676. #ifdef DEBUG
  677. switch (mode) {
  678. case DT_ENV_SET:
  679. printf("DT environment set:\n");
  680. printf("-------------------------------\n");
  681. break;
  682. case DT_ENV_RESTORE_PRE_DT:
  683. printf("Pre-DT environment restored:\n");
  684. printf("-------------------------------\n");
  685. break;
  686. case DT_ENV_RESTORE_POST_DT:
  687. printf("Post-DT environment restored:\n");
  688. printf("-------------------------------\n");
  689. break;
  690. case DT_ENV_NO_OP:
  691. printf("No change from last invocation:\n");
  692. printf("-------------------------------\n");
  693. break;
  694. }
  695. tempString = getenv(BIN_PATH_ENVIRON);
  696. printf("%s=|%s|\n", BIN_PATH_ENVIRON, tempString);
  697. tempString = getenv(SYSTEM_APPL_PATH_ENVIRON);
  698. printf("%s=|%s|\n", SYSTEM_APPL_PATH_ENVIRON, tempString);
  699. tempString = getenv(NLS_PATH_ENVIRON);
  700. printf("%s=|%s|\n", NLS_PATH_ENVIRON, tempString);
  701. tempString = getenv(PM_PATH_ENVIRON);
  702. printf("%s=|%s|\n", PM_PATH_ENVIRON, tempString);
  703. tempString = getenv(BM_PATH_ENVIRON);
  704. printf("%s=|%s|\n", BM_PATH_ENVIRON, tempString);
  705. #endif /* DEBUG */
  706. return (returnValue);
  707. } /* END OF FUNCTION _DtEnvControl */
  708. /*****************************<->*************************************
  709. *
  710. * _EnvAdd(char * str)
  711. *
  712. *
  713. * Description:
  714. * -----------
  715. * Adds the given string to the application's environment
  716. * If the existing environment variable string was allocated
  717. * by this application, the space is freed.
  718. *
  719. * Inputs:
  720. * ------
  721. * envVar The environment variable. E.g. NLSPATH
  722. * envVarSetting The environment variable setting.
  723. * E.g. NLSPATH=/usr/lib/nls
  724. * bv_flag The constant denoting which environment variable
  725. * is being set.
  726. *
  727. *****************************<->***********************************/
  728. static void _EnvAdd
  729. (
  730. char * envVar,
  731. char * envVarSetting,
  732. unsigned int bv_flag
  733. )
  734. {
  735. _DtSvcProcessLock();
  736. if (envBitVector & bv_flag) {
  737. #if defined(CSRG_BASED) || defined(__linux__)
  738. setenv(envVar, envVarSetting + strlen(envVar) + 1, 1);
  739. #else
  740. int i;
  741. size_t envVarLen = strlen(envVar);
  742. char *envPtr = NULL;
  743. /* if we have previously put this environment variable out to the
  744. * environment, we can retrieve it and reuse it rather than letting
  745. * it disappear into the ether
  746. */
  747. for ( i = 0; environ[i] ; i++ )
  748. {
  749. if ( environ[i][0] == envVar[0]
  750. && ( strlen(environ[i]) >= envVarLen )
  751. && ( environ[i][envVarLen] == '=' )
  752. && !strncmp(envVar,environ[i],envVarLen))
  753. {
  754. envPtr = environ[i];
  755. break;
  756. }
  757. }
  758. if ( envPtr )
  759. {
  760. XtFree(envPtr);
  761. envPtr = strdup(envVarSetting);
  762. strcpy(envPtr,envVarSetting);
  763. environ[i] = envPtr;
  764. }
  765. else
  766. {
  767. /* This should never happen */
  768. putenv(strdup(envVarSetting));
  769. }
  770. #endif /* linux || CSRG_BASED */
  771. }
  772. else
  773. putenv(strdup(envVarSetting));
  774. envBitVector |= bv_flag;
  775. _DtSvcProcessUnlock();
  776. }
  777. /*****************************<->*************************************
  778. *
  779. * _DtEnvRemove(
  780. * char *str,
  781. * int length )
  782. *
  783. *
  784. * Description:
  785. * -----------
  786. * Removes the given string from the application's environment
  787. * Uses the char **extern environment string array.
  788. *
  789. * Inputs:
  790. * ------
  791. * str - the name of the variable to remove (e.g., "NLSPATH")
  792. * length - the length of the variable--we compute it dynamically.
  793. *
  794. * Returns:
  795. * --------
  796. * Returns a success code--"0" if the variable is found and removed.
  797. * "1" if the variable isn't found.
  798. *
  799. *****************************<->***********************************/
  800. int
  801. _DtEnvRemove(
  802. char *str,
  803. int length )
  804. {
  805. char **pEnviron, **pEnviron2 = environ;
  806. char *p, *freeMe;
  807. int temp;
  808. int count = 0; /* count is the number of items in the */
  809. /* environ */
  810. int index; /* index will range from 0 to count - 1 */
  811. size_t len;
  812. if (!(len = strlen(str)))
  813. return(1);
  814. pEnviron = pEnviron2;
  815. p = *pEnviron;
  816. while (p)
  817. {
  818. pEnviron++;
  819. count++;
  820. p = *pEnviron;
  821. }
  822. pEnviron = pEnviron2;
  823. p = *pEnviron;
  824. for (index = 0; index < count; index++)
  825. {
  826. if ( p[0] == str[0]
  827. && ( strlen(p) >= len )
  828. && ( p[len] == '=' )
  829. && !strncmp(p, str, len))
  830. {
  831. #if defined(__linux__) || defined(CSRG_BASED)
  832. /* JET - 2/19/99
  833. It seems much safer to let libc worry about this
  834. rather than try to do it ourselves.
  835. */
  836. unsetenv(str);
  837. #else
  838. freeMe = pEnviron2[index];
  839. /* just move the last one into the gap - any
  840. * putenv destroyed the initial lexical ordering
  841. * anyway
  842. */
  843. pEnviron2[index] = pEnviron2[count - 1];
  844. pEnviron2[count - 1] = NULL;
  845. XtFree (freeMe);
  846. #endif /* linux || CSRG_BASED */
  847. return(0);
  848. }
  849. pEnviron++;
  850. p = *pEnviron;
  851. }
  852. return(1);
  853. }
  854. #if 0
  855. int
  856. _EnvPrint( void )
  857. {
  858. char **p, *q;
  859. p = (char **)(environ);
  860. q = *p;
  861. while (q)
  862. {
  863. printf("%s\n", q);
  864. p++;
  865. q = *p;
  866. }
  867. return 0;
  868. }
  869. #endif
  870. /*************************************<->*************************************
  871. *
  872. * _AddToPath (sPath, sDir)
  873. *
  874. *
  875. * Description:
  876. * -----------
  877. * Append a directory to a directory path.
  878. *
  879. * Inputs:
  880. * ------
  881. * sPath - the old path (must be a pointer to malloc'ed memory)
  882. * sDir - the directory to add to the path
  883. *
  884. *
  885. * Returns:
  886. * --------
  887. * A pointer to the new path if successful.
  888. * NULL on memory allocation failures.
  889. *
  890. * Comment:
  891. * --------
  892. * This functions adds sDir to the path of directories already in
  893. * sPath. Each directory is separated by a colon (':'). The function
  894. * is designed to work off the heap. sPath should be a pointer into
  895. * the heap on entry, or NULL. If sPath is NULL, then new memory is
  896. * allocated and returned. If sPath is not NULL, the storage for sPath
  897. * is reallocated to include space for the new string. In this case,
  898. * the pointer returned may point to a different value than sPath
  899. * that was passed in. If the pointer returned is different than sPath,
  900. * then sPath is invalid and should be reassigned.
  901. *
  902. *************************************<->***********************************/
  903. static char *
  904. _AddToPath (
  905. char * sPath,
  906. char * sDir)
  907. {
  908. char * sNew;
  909. if (sPath != NULL)
  910. {
  911. sNew = XtRealloc (sPath, strlen(sPath) + 1 + strlen(sDir) + 1);
  912. }
  913. else
  914. {
  915. sNew = XtMalloc (1 + strlen(sDir) + 1);
  916. }
  917. strcat (sNew, ":");
  918. strcat (sNew, sDir);
  919. return (sNew);
  920. }
  921. /*************************************<->*************************************
  922. *
  923. * _DtWsmSetBackdropSearchPath(screen, backdropPath, useMultiColorIcons)
  924. *
  925. *
  926. * Description:
  927. * -----------
  928. * Append the specified directories to DTICONSEARCHPATH environment
  929. * variable. This must be done before any icon lookup by XmGetPixmap.
  930. * Each directory in backdropPath is modified so the backdrop file
  931. * names can be matched (%B, %M, etc.).
  932. *
  933. * _DtEnvControl( DT_ENV_RESTORE_PRE_DT ) will restore the original
  934. * environment.
  935. *
  936. * Inputs:
  937. * ------
  938. * screen - screen of display
  939. * backdropPath - a colon-separated list of directories
  940. * useMultiColorIcons - True if color backdrops are desired.
  941. *
  942. * Returns:
  943. * --------
  944. * Returns a success code: success: DT_ENV_SET
  945. * failure: DT_ENV_NO_OP
  946. *
  947. *************************************<->***********************************/
  948. int
  949. _DtWsmSetBackdropSearchPath (
  950. Screen *screen,
  951. char *backdropPath,
  952. Boolean useMultiColorIcons)
  953. {
  954. char *sBackDirs;
  955. char *sOldEnv;
  956. char *sNext;
  957. char *bm_pm_fmt = "%s/%%B.bm:%s/%%B.pm:%s/%%B";
  958. char *pm_bm_fmt = "%s/%%B.pm:%s/%%B.bm:%s/%%B";
  959. int fmtlen = strlen(pm_bm_fmt);
  960. int returnValue = DT_ENV_NO_OP;
  961. int bytes_needed;
  962. _Xstrtokparams strtok_buf;
  963. /* for creating the name=value string */
  964. char postDtEnvironmentStringBuf[MAX_ENV_STRING];
  965. char *postDtEnvironmentString;
  966. if (backdropPath == NULL) return (returnValue);
  967. sOldEnv = getenv(PM_PATH_ENVIRON);
  968. DtNlInitialize();
  969. _DtSvcProcessLock();
  970. if (!sOldEnv)
  971. {
  972. /*
  973. * The user has no existing value for this
  974. * environment variable. Don't save it.
  975. * Just create the new DT environment.
  976. */
  977. /* make a copy that we can modify locally */
  978. sBackDirs = strdup(backdropPath);
  979. strcpy (sBackDirs, backdropPath);
  980. /*
  981. * Initialize path string
  982. */
  983. if (useMultiColorIcons)
  984. _postDtEnvironment.pmPath = makeDefaultIconPmPath();
  985. else
  986. _postDtEnvironment.pmPath = makeDefaultIconBmPath();
  987. /* get first directory */
  988. sNext = _XStrtok(sBackDirs, ":", strtok_buf);
  989. /* process each directory individually */
  990. while (sNext != NULL)
  991. {
  992. bytes_needed = (3 * (strlen(sNext) + fmtlen));
  993. if (bytes_needed >= MAX_ENV_STRING)
  994. postDtEnvironmentString = XtMalloc(bytes_needed);
  995. else
  996. postDtEnvironmentString = postDtEnvironmentStringBuf;
  997. if (useMultiColorIcons)
  998. sprintf(postDtEnvironmentString, pm_bm_fmt, sNext, sNext, sNext);
  999. else
  1000. sprintf(postDtEnvironmentString, bm_pm_fmt, sNext, sNext, sNext);
  1001. _postDtEnvironment.pmPath =
  1002. _AddToPath(_postDtEnvironment.pmPath, postDtEnvironmentString);
  1003. if (postDtEnvironmentString != postDtEnvironmentStringBuf)
  1004. {
  1005. if (postDtEnvironmentString) XtFree(postDtEnvironmentString);
  1006. postDtEnvironmentString = NULL;
  1007. }
  1008. /* get next directory */
  1009. sNext = _XStrtok(NULL, ":", strtok_buf);
  1010. }
  1011. XtFree (sBackDirs);
  1012. }
  1013. else
  1014. {
  1015. /*
  1016. * Save the old path if not previously saved
  1017. */
  1018. if (!_preDtEnvironment.pmPath)
  1019. {
  1020. bytes_needed = strlen(PM_PATH_ENVIRON) + strlen(sOldEnv) + 2;
  1021. _preDtEnvironment.pmPath = XtMalloc(bytes_needed);
  1022. sprintf(_preDtEnvironment.pmPath,"%s=%s", PM_PATH_ENVIRON, sOldEnv);
  1023. }
  1024. /* make a copy that we can modify locally */
  1025. sBackDirs = strdup(backdropPath);
  1026. strcpy (sBackDirs, backdropPath);
  1027. /*
  1028. * Initialize path environment string
  1029. */
  1030. bytes_needed = strlen(PM_PATH_ENVIRON) + strlen(sOldEnv) + 2;
  1031. _postDtEnvironment.pmPath = XtMalloc(bytes_needed);
  1032. sprintf(_postDtEnvironment.pmPath, "%s=%s", PM_PATH_ENVIRON, sOldEnv);
  1033. /* get first directory */
  1034. sNext = _XStrtok(sBackDirs, ":", strtok_buf);
  1035. /* process each directory individually */
  1036. while (sNext != NULL)
  1037. {
  1038. bytes_needed = (3 * (strlen(sNext) + fmtlen));
  1039. if (bytes_needed >= MAX_ENV_STRING)
  1040. postDtEnvironmentString = XtMalloc(bytes_needed);
  1041. else
  1042. postDtEnvironmentString = postDtEnvironmentStringBuf;
  1043. if (useMultiColorIcons)
  1044. sprintf(postDtEnvironmentString, pm_bm_fmt, sNext, sNext, sNext);
  1045. else
  1046. sprintf(postDtEnvironmentString, bm_pm_fmt, sNext, sNext, sNext);
  1047. _postDtEnvironment.pmPath =
  1048. _AddToPath(_postDtEnvironment.pmPath, postDtEnvironmentString);
  1049. if (postDtEnvironmentString != postDtEnvironmentStringBuf)
  1050. {
  1051. XtFree(postDtEnvironmentString);
  1052. postDtEnvironmentString = NULL;
  1053. }
  1054. /* get next directory */
  1055. sNext = _XStrtok(NULL, ":", strtok_buf);
  1056. }
  1057. XtFree (sBackDirs);
  1058. }
  1059. putenv(strdup(_postDtEnvironment.pmPath));
  1060. envBitVector |= BV_PMPATH;
  1061. /*
  1062. * Now do the same thing for the bitmap lookup path
  1063. */
  1064. sOldEnv = getenv(BM_PATH_ENVIRON);
  1065. if (!sOldEnv)
  1066. {
  1067. /*
  1068. * The user has no existing value for this
  1069. * environment variable. Don't save it.
  1070. * Just create the new DT environment.
  1071. */
  1072. /* make a copy that we can modify locally */
  1073. sBackDirs = strdup(backdropPath);
  1074. strcpy (sBackDirs, backdropPath);
  1075. /*
  1076. * Initialize path string
  1077. */
  1078. _postDtEnvironment.bmPath = makeDefaultIconBmPath();
  1079. /* get first directory */
  1080. sNext = _XStrtok(sBackDirs, ":", strtok_buf);
  1081. /* process each directory individually */
  1082. while (sNext != NULL)
  1083. {
  1084. bytes_needed = (3 * (strlen(sNext) + fmtlen));
  1085. if (bytes_needed >= MAX_ENV_STRING)
  1086. postDtEnvironmentString = XtMalloc(bytes_needed);
  1087. else
  1088. postDtEnvironmentString = postDtEnvironmentStringBuf;
  1089. sprintf(postDtEnvironmentString, bm_pm_fmt, sNext, sNext, sNext);
  1090. _postDtEnvironment.bmPath =
  1091. _AddToPath(_postDtEnvironment.bmPath, postDtEnvironmentString);
  1092. if (postDtEnvironmentString != postDtEnvironmentStringBuf)
  1093. {
  1094. if (postDtEnvironmentString) XtFree(postDtEnvironmentString);
  1095. postDtEnvironmentString = NULL;
  1096. }
  1097. /* get next directory */
  1098. sNext = _XStrtok(NULL, ":", strtok_buf);
  1099. }
  1100. XtFree (sBackDirs);
  1101. }
  1102. else
  1103. {
  1104. /*
  1105. * Save the old path if not previously saved
  1106. */
  1107. if (!_preDtEnvironment.bmPath)
  1108. {
  1109. bytes_needed = strlen(BM_PATH_ENVIRON) + strlen(sOldEnv) + 2;
  1110. _preDtEnvironment.pmPath = XtMalloc(bytes_needed);
  1111. sprintf(_preDtEnvironment.pmPath,"%s=%s", BM_PATH_ENVIRON, sOldEnv);
  1112. }
  1113. /* make a copy that we can modify locally */
  1114. sBackDirs = strdup(backdropPath);
  1115. strcpy (sBackDirs, backdropPath);
  1116. /*
  1117. * Initialize path environment string
  1118. */
  1119. bytes_needed = strlen(BM_PATH_ENVIRON) + strlen(sOldEnv) + 2;
  1120. _postDtEnvironment.bmPath = XtMalloc(bytes_needed);
  1121. sprintf(_postDtEnvironment.bmPath, "%s=%s", BM_PATH_ENVIRON, sOldEnv);
  1122. /* get first directory */
  1123. sNext = _XStrtok(sBackDirs, ":", strtok_buf);
  1124. /* process each directory individually */
  1125. while (sNext != NULL)
  1126. {
  1127. bytes_needed = (3 * (strlen(sNext) + fmtlen));
  1128. if (bytes_needed >= MAX_ENV_STRING)
  1129. postDtEnvironmentString = XtMalloc(bytes_needed);
  1130. else
  1131. postDtEnvironmentString = postDtEnvironmentStringBuf;
  1132. sprintf(postDtEnvironmentString, bm_pm_fmt, sNext, sNext, sNext);
  1133. _postDtEnvironment.bmPath =
  1134. _AddToPath(_postDtEnvironment.bmPath, postDtEnvironmentString);
  1135. if (postDtEnvironmentString != postDtEnvironmentStringBuf)
  1136. {
  1137. XtFree(postDtEnvironmentString);
  1138. postDtEnvironmentString = NULL;
  1139. }
  1140. /* get next directory */
  1141. sNext = _XStrtok(NULL, ":", strtok_buf);
  1142. }
  1143. XtFree (sBackDirs);
  1144. }
  1145. putenv(strdup(_postDtEnvironment.bmPath));
  1146. envBitVector |= BV_BMPATH;
  1147. _DtSvcProcessUnlock();
  1148. returnValue = DT_ENV_SET;
  1149. return (returnValue);
  1150. } /* END OF FUNCTION _DtWsmSetBackdropSearchPath */
  1151. /********************* eof *************************/