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 librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* @(#)$XConsortium: env.c /main/9 1996/10/30 05:57:27 pascale $ */
30 P_Shell, /* posix shell */
31 K_Shell, /* Korn shell */
37 static int shell_type(/* shell */);
42 char **aliases = (char **)0;
44 UserEnv *uenv = &userEnv;
46 if ((ret = get_user_environ()) != NoError)
49 if ((ret = read_cmd_conf()) != NoError)
53 p = get_real_locale(uenv->locale, &aliases);
55 uenv->real_locale = NEWSTR(p);
56 uenv->locale_aliases = aliases;
58 # endif /* old_hpux */
66 int get_user_environ()
71 UserEnv *uenv = &userEnv;
75 CLR(&userEnv, UserEnv);
77 if ((p = getenv("LANG")) && *p)
78 uenv->locale = NEWSTR(p);
82 /* find the CDE generic locale name */
83 if (find_CDE_locale_name() != NoError)
84 return ErrNoCDELocale;
86 if ((p = getenv("HOME")) && *p)
87 uenv->homedir = NEWSTR(p);
89 if (OpMode != MODE_LIST && OpMode != MODE_REMCONF) {
92 uenv->homedir = NEWSTR(p);
95 #endif /* ALLOW_NOHOME */
99 if ((p = Opt.DisplayName) && *p) {
100 strcpy(buf, "DISPLAY=");
104 p = getenv("DISPLAY");
106 uenv->displayname = NEWSTR(p);
108 if (OpMode == MODE_START /* || OpMode == MODE_CURRENT */
109 || (OpMode == MODE_MODE && (OpFlag & USE_WINDOW_MASK)))
113 if (p = getenv("XMODIFIERS"))
114 uenv->xmodifiers = NEWSTR(p);
116 uenv->xmodifiers = NULL;
118 gethostname(buf, BUFSIZ);
119 uenv->hostname = NEWSTR(buf);
121 if (!(p = getlogin()))
124 pw = getpwuid(getuid());
128 uenv->username = NEWSTR(p);
131 if (p = std_dpy_str(uenv->displayname, &n))
132 uenv->displaydir = p;
134 uenv->displaydir = NEWSTR(uenv->displayname);
135 uenv->screen_num = n;
141 int expand_string(in_str, out_str, out_len, ims)
142 char *in_str, *out_str;
146 register char *p, *q, *ep;
149 UserEnv *uenv = &userEnv;
150 CmdConf *conf = &Conf;
152 p = in_str; q = out_str;
153 if (*p == '~' && p[1] == '/') {
154 q = strcpyx(q, uenv->homedir);
157 out_len -= q - out_str;
159 while (*p && out_len > 0) {
164 case 'I': ep = conf->imsConfDir; break;
165 case 'R': ep = conf->imsAppDir; break;
166 case 'G': ep = conf->imsLogDir; break;
167 case 'g': ep = conf->imsLogFile; break;
168 case 'b': ep = conf->imsDir; break;
169 case 'S': ep = conf->userImsDir; break;
170 case 'T': ep = conf->userTmpDir; break;
171 case 'A': ep = conf->userAltDir; break;
172 case 'C': ep = conf->dt->confDir; break;
173 case 'U': ep = conf->dt->userDir; break;
175 case 'V': ep = conf->vue->confDir; break;
176 case 'X': ep = conf->vue->userDir; break;
177 # endif /* old_hpux */
179 case 'L': if (ep = uenv->real_locale) break;
180 case 'l': ep = uenv->locale; break;
181 case 'H': ep = uenv->homedir; break;
182 case 'u': ep = uenv->username; break;
183 case 'h': ep = uenv->hostname; break;
184 case 'D': ep = uenv->displayname; break;
185 case 'd': ep = uenv->displaydir; break;
187 case 'N': if (ims && (ep = ims->servername2)) break;
188 case 'n': if (ims) ep = ims->servername; break;
189 case 'c': if (ims) ep = ims->classname; break;
190 case 's': sprintf(str, "%ld", (long) uenv->screen_num);
191 if (str[0] != '\0') ep = str;
193 case 'r': ep = userSel.hostname; break;
196 default: DPR2(("expand_string: '%%%c' unknown\n"));
200 if ((out_len -= (int) strlen(ep)) <= 0) break;
206 if (--out_len <= 0) break;
213 DPR3(("expand_string(\"%s\"):\t\"%s\"\n", in_str, out_str));
216 DPR(("expand_string(): buffer overflow (len=%d)\n", len));
223 static int shell_type(shell)
229 if (!shell || !*shell) {
230 shell = getenv("SHELL");
231 if (!shell || !*shell) return P_Shell;
234 if (strchr(p = shell, '/')) {
235 for (len = strlen(p); len > 1 && p[len - 1] == '/'; len--) ;
237 if (p = strrchr(shell, '/')) shell = p + 1;
239 if (strstr(shell, "ksh") != NULL)
241 else if (strstr(shell, "csh") != NULL)
248 int make_new_environ(oenv, sel)
257 char buf[BUFSIZ], *bp;
259 char **setp, **unsetp;
260 bool xmod_done, xinput_done;
263 /* if (!oenv) return ErrInternal; */
264 if (!sel) sel = &userSel;
269 xmod = ENV_XMODIFIERS;
272 xinput = xhp_xinput_name(NULL);
275 # endif /* old_hpux */
276 xinput_done = (xinput) ? False : True;
277 proto = renv ? renv->proto : default_protocol(ims);
280 if (ims->env_set) setp = parse_strlist(ims->env_set, ' ');
281 if (ims->env_unset) unsetp = parse_strlist(ims->env_unset, ' ');
283 /* set: ims->env_set, XMODIFIERS & X?INPUT */
285 if (setp) for (pp = setp; *pp; pp++, num++) ;
286 ep = oenv->set = ALLOC(num + 2 + 1, EnvEnt);
288 for (i = 0; i < num && (p = setp[i]); i++)
289 if (strcmp(p, xmod) && strcmp(p, xinput)) {
290 ep->name = NEWSTR(p);
293 if (renv && renv->im_mod) {
294 ep->name = NEWSTR(xmod);
295 bp = strcpyx(bp = buf, ENV_MOD_IM); /* "@im=" */
296 bp = strcpyx(bp, renv->im_mod);
297 ep->value = NEWSTR(buf);
302 if (!xinput_done && (proto == Proto_Xhp)) {
304 if (!ims->servername) {
305 DPR(("make_new_environ(): '%s' servername not defined\n",
309 ep->name = NEWSTR(xinput);
310 ep->value = NEWSTR(ims->servername);
314 # endif /* old_hpux */
315 if (ep == oenv->set) {
316 FREE(oenv->set); oenv->set = (EnvEnt *)0;
320 /* unset: XMODIFIERS & X?INPUT, ims->env_unset */
322 if (unsetp) for (pp = unsetp; *pp; pp++, num++) ;
323 ep = oenv->unset = ALLOC(num + 2 + 1, EnvEnt);
326 ep->name = NEWSTR(xmod);
332 ep->name = NEWSTR(xinput);
336 # endif /* old_hpux */
337 for (i = 0; i < num && (p = unsetp[i]); i++) {
338 if (strcmp(p, xmod) == 0 || strcmp(p, xinput) == 0)
341 for (ep2 = oenv->set; ep2->name; ep2++)
342 if (strcmp(p, ep2->name) == 0) {
348 ep->name = NEWSTR(p);
352 if (ep == oenv->unset) {
353 FREE(oenv->unset); oenv->unset = (EnvEnt *)0;
364 int put_new_environ(oenv) /* print modified environment variables */
368 char tmpbuf[BUFSIZ], *bp, *vp;
369 int typ = shell_type(Opt.ShellName);
372 /* if (!oenv) return ErrInternal; */
378 if (!oenv->set && !oenv->unset) return NoError;
381 if (typ == C_Shell) { /* C-Shell format */
382 bp = strcpyx(tmpbuf, "set noglob;\n");
384 for (ep = oenv->set; ep->name; ep++) {
385 if (!(vp = ep->value) && (vp = strchr(ep->name, '=')))
387 sprintf(bp, "setenv %s '%s';\n", ep->name, vp);
392 bp = strcpyx(bp, "unsetenv ");
393 for (ep = oenv->unset; ep->name; ep++) {
395 bp = strcpyx(bp, ep->name);
398 bp = strcpyx(bp, ";\nunset noglob;\n");
399 } else { /* B-Shell format */
402 for (ep = oenv->set; ep->name; ep++) {
403 if (!(vp = ep->value) && (vp = strchr(ep->name, '=')))
405 sprintf(bp, "%s='%s';\n", ep->name, vp);
408 bp = strcpyx(bp, "export ");
409 for (ep = oenv->set; ep->name; ep++) {
411 bp = strcpyx(bp, ep->name);
413 bp = strcpyx(bp, ";\n");
416 bp = strcpyx(bp, "unset ");
417 for (ep = oenv->unset; ep->name; ep++) {
419 bp = strcpyx(bp, ep->name);
421 bp = strcpyx(bp, ";\n");
426 DPR3(("put_new_environ(len=%d):\t%s\n", len, tmpbuf));
429 write(1, tmpbuf, len);
435 int set_remote_env(ptr, env_pass)
436 char *ptr, *env_pass;
439 char **ls, **ls2, **pp, **pp2;
443 if (Conf.remote->passEnv
444 && (ls = parse_strlist(Conf.remote->passEnv, ' '))) {
445 for (pp = ls; *pp; pp++)
446 if (ep = getenv(*pp)) {
447 *bp++ = ' '; bp = strcpyx(bp, *pp); *bp++ = '=';
448 *bp++ = '"'; bp = strcpyx(bp, ep); *bp++ = '"';
451 if (env_pass && (ls2 = parse_strlist(env_pass, ' '))) {
452 for (pp2 = ls2; *pp2; pp2++) {
454 if (ls) { /* eliminate duplicate entries */
455 for (pp = ls; *pp; pp++)
456 if (strcmp(*pp, *pp2) == 0) {
461 if (!dup_ent && (ep = getenv(*pp2))) {
462 *bp++ = ' '; bp = strcpyx(bp, *pp2); *bp++ = '=';
463 *bp++ = '"'; bp = strcpyx(bp, ep); *bp++ = '"';
469 if (ls) FREE_LIST(ls);
470 /* if (bp != ptr) *bp++ = ' '; */
473 DPR2(("set_remote_env('%s' & '%s'):\n\t'%s'\n",
474 Conf.remote->passEnv, env_pass, ptr));
479 char *xhp_xinput_name(locale)
482 char *xinput_name = "X@INPUT";
485 XhpLocale *xhp = Conf.xhp;
489 if (!xhp) return NULL;
490 if (!locale) locale = userEnv.locale;
492 for (i = 0; !typ && i < XHP_LANG_NUM; i++) {
493 if (!(ls = parse_strlist(xhp[i].locales, ' '))) continue;
494 for (pp = ls; *pp; pp++) {
495 if (locale[0] != (*pp)[0]) continue;
496 len = strlen(p = *pp);
497 if ((p[len - 1] == '*' && strncmp(locale, p, len - 1) == 0)
498 || strcmp(locale, p) == 0) {
506 DPR2(("xhp_xinput_name(%s): unknown locale\n", locale));
510 xinput_name[1] = typ;
511 return NEWSTR(xinput_name);
515 char *get_real_locale(locale, aliases)
516 char *locale, ***aliases;
520 LocaleAlias **alias = Conf.alias, *ap;
522 char *real_locale = NULL;
524 if (!locale || !alias) return NULL;
526 for (i = 0; match_idx < 0 && (ap = alias[i]); i++) {
527 if (strcmp(ap->name, locale) == 0) {
530 ls = parse_strlist(ap->aliases, ' ');
533 if (ls = parse_strlist(ap->aliases, ' ')) {
534 for (pp = ls; *pp; pp++)
535 if (strcmp(locale, *pp) == 0) {
544 if (match_idx >= 0) {
545 real_locale = alias[match_idx]->name;
552 if (aliases) *aliases = (char **) NULL;
554 if (ls) FREE_LIST(ls);
556 DPR(("get_real_locale(%s): real_locale=%s aliases=%s\n",
557 locale, real_locale, aliases ? *aliases : NULL));
562 # endif /* old_hpux */