2 * Copyright 1989 - 1994, Julianne Frances Haugh
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * Separated from setup.c. --marekm
37 RCSID("$Id: setupenv.c,v 1.11 2001/11/06 15:50:25 kloczek Exp $")
39 #include <sys/types.h>
45 #include "prototypes.h"
51 addenv_path(const char *varname, const char *dirname, const char *filename)
55 buf = xmalloc(strlen(dirname) + strlen(filename) + 2);
56 sprintf(buf, "%s/%s", dirname, filename);
64 read_env_file(const char *filename)
68 char *cp, *name, *val;
70 fp = fopen(filename, "r");
73 while (fgets(buf, sizeof buf, fp) == buf) {
74 cp = strrchr(buf, '\n');
80 /* ignore whitespace and comments */
81 while (*cp && isspace(*cp))
83 if (*cp == '\0' || *cp == '#')
86 * ignore lines which don't follow the name=value format
87 * (for example, the "export NAME" shell commands)
90 while (*cp && !isspace(*cp) && *cp != '=')
94 /* NUL-terminate the name */
97 #if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */
99 (state, char_type) -> (state, action)
101 state: unquoted, single_quoted, double_quoted, escaped, double_quoted_escaped
102 char_type: normal, white, backslash, single, double
103 action: remove_curr, remove_curr_skip_next, remove_prev, finish XXX
107 /* remove the backslash */
109 /* skip over the next character */
113 } else if (*cp == '\'') {
114 /* remove the quote */
116 /* now within single quotes */
118 } else if (*cp == '"') {
119 /* remove the quote */
121 /* now within double quotes */
123 } else if (*cp == '\0') {
126 } else if (isspace(*cp)) {
127 /* unescaped whitespace - end of string */
136 /* remove the quote */
140 } else if (*cp == '\0') {
144 /* preserve everything within single quotes */
150 /* remove the quote */
154 } else if (*cp == '\\') {
156 /* if backslash followed by double quote, remove backslash
157 else skip over the backslash and following char */
163 } eise if (*cp == '\0') {
167 /* preserve everything within double quotes */
173 * XXX - should handle quotes, backslash escapes, etc.
174 * like the shell does.
184 * change to the user's home directory
185 * set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental
190 setup_env(struct passwd *info)
198 * Change the current working directory to be the home directory
199 * of the user. It is a fatal error for this process to be unable
200 * to change to that directory. There is no "default" home
203 * We no longer do it as root - should work better on NFS-mounted
204 * home directories. Some systems default to HOME=/, so we make
205 * this a configurable option. --marekm
208 if (chdir(info->pw_dir) == -1) {
209 static char temp_pw_dir[] = "/";
210 if (!getdef_bool("DEFAULT_HOME") || chdir("/") == -1) {
211 fprintf(stderr, _("Unable to cd to \"%s\"\n"),
214 "unable to cd to `%s' for user `%s'\n",
215 info->pw_dir, info->pw_name));
219 puts(_("No directory, logging in with HOME=/"));
220 info->pw_dir = temp_pw_dir;
224 * Create the HOME environmental variable and export it.
227 addenv("HOME", info->pw_dir);
230 * Create the SHELL environmental variable and export it.
233 if (info->pw_shell == (char *) 0 || ! *info->pw_shell) {
234 static char temp_pw_shell[] = "/bin/sh";
235 info->pw_shell = temp_pw_shell;
238 addenv("SHELL", info->pw_shell);
241 * Create the PATH environmental variable and export it.
244 cp = getdef_str((info->pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH");
246 addenv(cp ? cp : "PATH=/bin:/usr/bin", NULL);
249 /* not specified, use a minimal default */
250 addenv("PATH=/bin:/usr/bin", NULL);
251 } else if (strchr(cp, '=')) {
252 /* specified as name=value (PATH=...) */
255 /* only value specified without "PATH=" */
261 * Export the user name. For BSD derived systems, it's "USER", for
262 * all others it's "LOGNAME". We set both of them.
265 addenv("USER", info->pw_name);
266 addenv("LOGNAME", info->pw_name);
269 * MAILDIR environment variable for Qmail
271 if ((cp=getdef_str("QMAIL_DIR")))
272 addenv_path("MAILDIR", info->pw_dir, cp);
275 * Create the MAIL environmental variable and export it. login.defs
279 if ((cp=getdef_str("MAIL_DIR")))
280 addenv_path("MAIL", cp, info->pw_name);
281 else if ((cp=getdef_str("MAIL_FILE")))
282 addenv_path("MAIL", info->pw_dir, cp);
284 #if defined(MAIL_SPOOL_FILE)
285 addenv_path("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
286 #elif defined(MAIL_SPOOL_DIR)
287 addenv_path("MAIL", MAIL_SPOOL_DIR, info->pw_name);
293 * Read environment from optional config file. --marekm
295 if ((envf = getdef_str("ENVIRON_FILE")))