194 lines
4.7 KiB
C
194 lines
4.7 KiB
C
/* Author: Wietse Venema <wietse@wzv.win.tue.nl> */
|
|
|
|
#include "bsd_locl.h"
|
|
|
|
RCSID("$Id: sysv_environ.c,v 1.23 1997/12/14 23:50:44 assar Exp $");
|
|
|
|
#ifdef HAVE_ULIMIT_H
|
|
#include <ulimit.h>
|
|
#endif
|
|
|
|
#ifndef UL_SETFSIZE
|
|
#define UL_SETFSIZE 2
|
|
#endif
|
|
|
|
#include "sysv_default.h"
|
|
|
|
/*
|
|
* Set
|
|
*/
|
|
|
|
static void
|
|
read_etc_environment (void)
|
|
{
|
|
FILE *f;
|
|
char buf[BUFSIZ];
|
|
|
|
f = fopen(_PATH_ETC_ENVIRONMENT, "r");
|
|
if (f) {
|
|
char *val;
|
|
|
|
while (fgets (buf, sizeof(buf), f) != NULL) {
|
|
if (buf[0] == '\n' || buf[0] == '#')
|
|
continue;
|
|
buf[strlen(buf) - 1] = '\0';
|
|
val = strchr (buf, '=');
|
|
if (val == NULL)
|
|
continue;
|
|
*val = '\0';
|
|
setenv(buf, val + 1, 1);
|
|
}
|
|
fclose (f);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Environment variables that are preserved (but may still be overruled by
|
|
* other means). Only TERM and TZ appear to survive (SunOS 5.1). These are
|
|
* typically inherited from the ttymon process.
|
|
*/
|
|
|
|
static struct preserved {
|
|
char *name;
|
|
char *value;
|
|
} preserved[] = {
|
|
{"TZ", 0},
|
|
{"TERM", 0},
|
|
{0},
|
|
};
|
|
|
|
/*
|
|
* Environment variables that are not preserved and that cannot be specified
|
|
* via commandline or stdin. Except for the LD_xxx (runtime linker) stuff,
|
|
* the list applies to most SYSV systems. The manpage mentions only that
|
|
* SHELL and PATH are censored. HOME, LOGNAME and MAIL are always
|
|
* overwritten; they are in the list to make the censoring explicit.
|
|
*/
|
|
|
|
static struct censored {
|
|
char *prefix;
|
|
int length;
|
|
} censored[] = {
|
|
{"SHELL=", sizeof("SHELL=") - 1},
|
|
{"HOME=", sizeof("HOME=") - 1},
|
|
{"LOGNAME=", sizeof("LOGNAME=") - 1},
|
|
{"MAIL=", sizeof("MAIL=") - 1},
|
|
{"CDPATH=", sizeof("CDPATH=") - 1},
|
|
{"IFS=", sizeof("IFS=") - 1},
|
|
{"PATH=", sizeof("PATH=") - 1},
|
|
{"LD_", sizeof("LD_") - 1},
|
|
{0},
|
|
};
|
|
|
|
/* sysv_newenv - set up final environment after logging in */
|
|
|
|
void sysv_newenv(int argc, char **argv, struct passwd *pwd,
|
|
char *term, int pflag)
|
|
{
|
|
unsigned umask_val;
|
|
char buf[BUFSIZ];
|
|
int count = 0;
|
|
struct censored *cp;
|
|
struct preserved *pp;
|
|
|
|
/* Preserve a selection of the environment. */
|
|
|
|
for (pp = preserved; pp->name; pp++)
|
|
pp->value = getenv(pp->name);
|
|
|
|
/*
|
|
* Note: it is a bad idea to assign a static array to the global environ
|
|
* variable. Reason is that putenv() can run into problems when it tries
|
|
* to realloc() the environment table. Instead, we just clear environ[0]
|
|
* and let putenv() work things out.
|
|
*/
|
|
|
|
if (!pflag && environ)
|
|
environ[0] = 0;
|
|
|
|
/* Restore preserved environment variables. */
|
|
|
|
for (pp = preserved; pp->name; pp++)
|
|
if (pp->value)
|
|
setenv(pp->name, pp->value, 1);
|
|
|
|
/* The TERM definition from e.g. rlogind can override an existing one. */
|
|
|
|
if (term[0])
|
|
setenv("TERM", term, 1);
|
|
|
|
/*
|
|
* Environment definitions from the command line overrule existing ones,
|
|
* but can be overruled by definitions from stdin. Some variables are
|
|
* censored.
|
|
*
|
|
* Omission: we do not support environment definitions from stdin.
|
|
*/
|
|
|
|
#define STREQN(x,y,l) (x[0] == y[0] && strncmp(x,y,l) == 0)
|
|
|
|
while (argc && *argv) {
|
|
if (strchr(*argv, '=') == 0) {
|
|
snprintf(buf, sizeof(buf), "L%d", count++);
|
|
setenv(buf, *argv, 1);
|
|
} else {
|
|
for (cp = censored; cp->prefix; cp++)
|
|
if (STREQN(*argv, cp->prefix, cp->length))
|
|
break;
|
|
if (cp->prefix == 0)
|
|
putenv(*argv);
|
|
}
|
|
argc--, argv++;
|
|
}
|
|
|
|
/* PATH is always reset. */
|
|
|
|
setenv("PATH", pwd->pw_uid ? default_path : default_supath, 1);
|
|
|
|
/* Undocumented: HOME, MAIL and LOGNAME are always reset (SunOS 5.1). */
|
|
|
|
setenv("HOME", pwd->pw_dir, 1);
|
|
{
|
|
char *sep = "/";
|
|
if(KRB4_MAILDIR[strlen(KRB4_MAILDIR) - 1] == '/')
|
|
sep = "";
|
|
roken_concat(buf, sizeof(buf), KRB4_MAILDIR, sep, pwd->pw_name, NULL);
|
|
}
|
|
setenv("MAIL", buf, 1);
|
|
setenv("LOGNAME", pwd->pw_name, 1);
|
|
setenv("USER", pwd->pw_name, 1);
|
|
|
|
/*
|
|
* Variables that may be set according to specifications in the defaults
|
|
* file. HZ and TZ are set only if they are still uninitialized.
|
|
*
|
|
* Extension: when ALTSHELL=YES, we set the SHELL variable even if it is
|
|
* /bin/sh.
|
|
*/
|
|
|
|
if (strcasecmp(default_altsh, "YES") == 0)
|
|
setenv("SHELL", pwd->pw_shell, 1);
|
|
if (default_hz)
|
|
setenv("HZ", default_hz, 0);
|
|
if (default_timezone)
|
|
setenv("TZ", default_timezone, 0);
|
|
|
|
/* Non-environment stuff. */
|
|
|
|
if (default_umask) {
|
|
if (sscanf(default_umask, "%o", &umask_val) == 1 && umask_val)
|
|
umask(umask_val);
|
|
}
|
|
#ifdef HAVE_ULIMIT
|
|
if (default_ulimit) {
|
|
long limit_val;
|
|
|
|
if (sscanf(default_ulimit, "%ld", &limit_val) == 1 && limit_val)
|
|
if (ulimit(UL_SETFSIZE, limit_val) < 0)
|
|
warn ("ulimit(UL_SETFSIZE, %ld)", limit_val);
|
|
}
|
|
#endif
|
|
read_etc_environment();
|
|
}
|
|
|