2 * Copyright (c) 1989 - 1994, Julianne Frances Haugh
3 * Copyright (c) 1996 - 2000, Marek Michałkiewicz
4 * Copyright (c) 2001 - 2006, Tomasz Kłoczko
5 * Copyright (c) 2007 - 2008, Nicolas François
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the copyright holders or contributors may not be used to
17 * endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Separated from setup.c. --marekm
41 #include <sys/types.h>
45 #include "prototypes.h"
52 addenv_path (const char *varname, const char *dirname, const char *filename)
56 buf = xmalloc (strlen (dirname) + strlen (filename) + 2);
57 sprintf (buf, "%s/%s", dirname, filename);
58 addenv (varname, buf);
62 static void read_env_file (const char *filename)
66 char *cp, *name, *val;
68 fp = fopen (filename, "r");
71 while (fgets (buf, sizeof buf, fp) == buf) {
72 cp = strrchr (buf, '\n');
78 /* ignore whitespace and comments */
79 while (*cp && isspace (*cp))
81 if (*cp == '\0' || *cp == '#')
84 * ignore lines which don't follow the name=value format
85 * (for example, the "export NAME" shell commands)
88 while (*cp && !isspace (*cp) && *cp != '=')
92 /* NUL-terminate the name */
95 #if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */
97 (state, char_type) -> (state, action)
99 state: unquoted, single_quoted, double_quoted, escaped, double_quoted_escaped
100 char_type: normal, white, backslash, single, double
101 action: remove_curr, remove_curr_skip_next, remove_prev, finish XXX
105 /* remove the backslash */
107 /* skip over the next character */
111 } else if (*cp == '\'') {
112 /* remove the quote */
114 /* now within single quotes */
116 } else if (*cp == '"') {
117 /* remove the quote */
119 /* now within double quotes */
121 } else if (*cp == '\0') {
124 } else if (isspace (*cp)) {
125 /* unescaped whitespace - end of string */
134 /* remove the quote */
138 } else if (*cp == '\0') {
142 /* preserve everything within single quotes */
148 /* remove the quote */
152 } else if (*cp == '\\') {
154 /* if backslash followed by double quote, remove backslash
155 else skip over the backslash and following char */
157 remove_char (cp - 1);
162 eise if (*cp == '\0') {
166 /* preserve everything within double quotes */
172 * XXX - should handle quotes, backslash escapes, etc.
173 * like the shell does.
183 * change to the user's home directory
184 * set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental
188 void setup_env (struct passwd *info)
196 * Change the current working directory to be the home directory
197 * of the user. It is a fatal error for this process to be unable
198 * to change to that directory. There is no "default" home
201 * We no longer do it as root - should work better on NFS-mounted
202 * home directories. Some systems default to HOME=/, so we make
203 * this a configurable option. --marekm
206 if (chdir (info->pw_dir) == -1) {
207 static char temp_pw_dir[] = "/";
209 if (!getdef_bool ("DEFAULT_HOME") || chdir ("/") == -1) {
210 fprintf (stderr, _("Unable to cd to '%s'\n"),
213 "unable to cd to `%s' for user `%s'\n",
214 info->pw_dir, info->pw_name));
218 puts (_("No directory, logging in with HOME=/"));
219 info->pw_dir = temp_pw_dir;
223 * Create the HOME environmental variable and export it.
226 addenv ("HOME", info->pw_dir);
229 * Create the SHELL environmental variable and export it.
232 if ((NULL == info->pw_shell) || ('\0' == *info->pw_shell)) {
233 static char temp_pw_shell[] = "/bin/sh";
235 info->pw_shell = temp_pw_shell;
238 addenv ("SHELL", info->pw_shell);
241 * Export the user name. For BSD derived systems, it's "USER", for
242 * all others it's "LOGNAME". We set both of them.
245 addenv ("USER", info->pw_name);
246 addenv ("LOGNAME", info->pw_name);
249 * Create the PATH environmental variable and export it.
252 cp = getdef_str ((info->pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH");
255 /* not specified, use a minimal default */
256 addenv ("PATH=/bin:/usr/bin", NULL);
257 } else if (strchr (cp, '=')) {
258 /* specified as name=value (PATH=...) */
261 /* only value specified without "PATH=" */
267 * Create the MAIL environmental variable and export it. login.defs
271 if (getdef_bool ("MAIL_CHECK_ENAB")) {
272 if ((cp = getdef_str ("MAIL_DIR")))
273 addenv_path ("MAIL", cp, info->pw_name);
274 else if ((cp = getdef_str ("MAIL_FILE")))
275 addenv_path ("MAIL", info->pw_dir, cp);
277 #if defined(MAIL_SPOOL_FILE)
278 addenv_path ("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
279 #elif defined(MAIL_SPOOL_DIR)
280 addenv_path ("MAIL", MAIL_SPOOL_DIR, info->pw_name);
286 * Read environment from optional config file. --marekm
288 if ((envf = getdef_str ("ENVIRON_FILE")))
289 read_env_file (envf);
290 #endif /* !USE_PAM */