Change __signed to signed.
[dragonfly.git] / crypto / kerberosIV / appl / bsd / sysv_environ.c
1 /* Author: Wietse Venema <wietse@wzv.win.tue.nl> */
2
3 #include "bsd_locl.h"
4
5 RCSID("$Id: sysv_environ.c,v 1.23 1997/12/14 23:50:44 assar Exp $");
6
7 #ifdef HAVE_ULIMIT_H
8 #include <ulimit.h>
9 #endif
10
11 #ifndef UL_SETFSIZE
12 #define UL_SETFSIZE 2
13 #endif
14
15 #include "sysv_default.h"
16
17 /*
18  * Set 
19  */
20
21 static void
22 read_etc_environment (void)
23 {
24     FILE *f;
25     char buf[BUFSIZ];
26
27     f = fopen(_PATH_ETC_ENVIRONMENT, "r");
28     if (f) {
29         char *val;
30
31         while (fgets (buf, sizeof(buf), f) != NULL) {
32             if (buf[0] == '\n' || buf[0] == '#')
33                 continue;
34             buf[strlen(buf) - 1] = '\0';
35             val = strchr (buf, '=');
36             if (val == NULL)
37                 continue;
38             *val = '\0';
39             setenv(buf, val + 1, 1);
40         }
41         fclose (f);
42     }
43 }
44
45  /*
46   * Environment variables that are preserved (but may still be overruled by
47   * other means). Only TERM and TZ appear to survive (SunOS 5.1). These are
48   * typically inherited from the ttymon process.
49   */
50
51 static struct preserved {
52     char   *name;
53     char   *value;
54 } preserved[] = {
55     {"TZ", 0},
56     {"TERM", 0},
57     {0},
58 };
59
60  /*
61   * Environment variables that are not preserved and that cannot be specified
62   * via commandline or stdin. Except for the LD_xxx (runtime linker) stuff,
63   * the list applies to most SYSV systems. The manpage mentions only that
64   * SHELL and PATH are censored. HOME, LOGNAME and MAIL are always
65   * overwritten; they are in the list to make the censoring explicit.
66   */
67
68 static struct censored {
69     char   *prefix;
70     int     length;
71 } censored[] = {
72   {"SHELL=",    sizeof("SHELL=") - 1},
73      {"HOME=",  sizeof("HOME=") - 1},
74      {"LOGNAME=",       sizeof("LOGNAME=") - 1},
75      {"MAIL=",  sizeof("MAIL=") - 1},
76      {"CDPATH=",        sizeof("CDPATH=") - 1},
77      {"IFS=",   sizeof("IFS=") - 1},
78      {"PATH=",  sizeof("PATH=") - 1},
79     {"LD_",     sizeof("LD_") - 1},
80     {0},
81 };
82
83 /* sysv_newenv - set up final environment after logging in */
84
85 void sysv_newenv(int argc, char **argv, struct passwd *pwd,
86                  char *term, int pflag)
87 {
88     unsigned umask_val;
89     char    buf[BUFSIZ];
90     int     count = 0;
91     struct censored *cp;
92     struct preserved *pp;
93
94     /* Preserve a selection of the environment. */
95
96     for (pp = preserved; pp->name; pp++)
97         pp->value = getenv(pp->name);
98
99     /*
100      * Note: it is a bad idea to assign a static array to the global environ
101      * variable. Reason is that putenv() can run into problems when it tries
102      * to realloc() the environment table. Instead, we just clear environ[0]
103      * and let putenv() work things out.
104      */
105
106     if (!pflag && environ)
107         environ[0] = 0;
108
109     /* Restore preserved environment variables. */
110
111     for (pp = preserved; pp->name; pp++)
112         if (pp->value)
113             setenv(pp->name, pp->value, 1);
114
115     /* The TERM definition from e.g. rlogind can override an existing one. */
116
117     if (term[0])
118         setenv("TERM", term, 1);
119
120     /*
121      * Environment definitions from the command line overrule existing ones,
122      * but can be overruled by definitions from stdin. Some variables are
123      * censored.
124      * 
125      * Omission: we do not support environment definitions from stdin.
126      */
127
128 #define STREQN(x,y,l) (x[0] == y[0] && strncmp(x,y,l) == 0)
129
130     while (argc && *argv) {
131         if (strchr(*argv, '=') == 0) {
132             snprintf(buf, sizeof(buf), "L%d", count++);
133             setenv(buf, *argv, 1);
134         } else {
135             for (cp = censored; cp->prefix; cp++)
136                 if (STREQN(*argv, cp->prefix, cp->length))
137                     break;
138             if (cp->prefix == 0)
139                 putenv(*argv);
140         }
141         argc--, argv++;
142     }
143
144     /* PATH is always reset. */
145
146     setenv("PATH", pwd->pw_uid ? default_path : default_supath, 1);
147
148     /* Undocumented: HOME, MAIL and LOGNAME are always reset (SunOS 5.1). */
149
150     setenv("HOME", pwd->pw_dir, 1);
151     {
152         char *sep = "/";
153         if(KRB4_MAILDIR[strlen(KRB4_MAILDIR) - 1] == '/')
154             sep = "";
155         roken_concat(buf, sizeof(buf), KRB4_MAILDIR, sep, pwd->pw_name, NULL);
156     }
157     setenv("MAIL", buf, 1);
158     setenv("LOGNAME", pwd->pw_name, 1);
159     setenv("USER", pwd->pw_name, 1);
160
161     /*
162      * Variables that may be set according to specifications in the defaults
163      * file. HZ and TZ are set only if they are still uninitialized.
164      * 
165      * Extension: when ALTSHELL=YES, we set the SHELL variable even if it is
166      * /bin/sh.
167      */
168
169     if (strcasecmp(default_altsh, "YES") == 0)
170         setenv("SHELL", pwd->pw_shell, 1);
171     if (default_hz)
172         setenv("HZ", default_hz, 0);
173     if (default_timezone)
174         setenv("TZ", default_timezone, 0);
175
176     /* Non-environment stuff. */
177
178     if (default_umask) {
179         if (sscanf(default_umask, "%o", &umask_val) == 1 && umask_val)
180             umask(umask_val);
181     }
182 #ifdef HAVE_ULIMIT
183     if (default_ulimit) {
184         long    limit_val;
185
186         if (sscanf(default_ulimit, "%ld", &limit_val) == 1 && limit_val)
187             if (ulimit(UL_SETFSIZE, limit_val) < 0)
188                 warn ("ulimit(UL_SETFSIZE, %ld)", limit_val);
189     }
190 #endif
191     read_etc_environment();
192 }
193