1
2
3#include "toys.h"
4
5
6extern char **environ;
7
8
9
10
11long environ_bytes()
12{
13 long bytes = sizeof(char *);
14 char **ev;
15
16 for (ev = environ; *ev; ev++) bytes += sizeof(char *) + strlen(*ev) + 1;
17
18 return bytes;
19}
20
21
22
23void xclearenv(void)
24{
25 toys.envc = 0;
26 *environ = 0;
27}
28
29
30
31
32void xsetenv(char *name, char *val)
33{
34 unsigned i, len, envc;
35 char *new;
36
37
38 if (!toys.envc) {
39
40 while (environ[toys.envc++]);
41 memcpy(new = xmalloc(((toys.envc|0xff)+1)*sizeof(char *)),
42 environ, toys.envc*sizeof(char *));
43 environ = (void *)new;
44 }
45
46 new = strchr(name, '=');
47 if (new) {
48 len = new-name;
49 if (val) error_exit("xsetenv %s to %s", name, val);
50 new = name;
51 } else {
52 len = strlen(name);
53 if (val) new = xmprintf("%s=%s", name, val);
54 }
55
56 envc = toys.envc-1;
57 for (i = 0; environ[i]; i++) {
58
59 if (!memcmp(name, environ[i], len) && environ[i][len]=='=') {
60 if (i>=envc) free(environ[i]);
61 else {
62
63 toys.envc = envc--;
64 for (; new ? i<envc : !!environ[i]; i++) environ[i] = environ[i+1];
65 i = envc;
66 }
67 break;
68 }
69 }
70
71 if (!new) return;
72
73
74 if (!environ[i]) {
75 len = i+1;
76 if (!(len&255)) environ = xrealloc(environ, len*sizeof(char *));
77 environ[len] = 0;
78 }
79 environ[i] = new;
80}
81
82void xunsetenv(char *name)
83{
84 if (strchr(name, '=')) error_exit("xunsetenv %s name has =", name);
85 xsetenv(name, 0);
86}
87
88
89void reset_env(struct passwd *p, int clear)
90{
91 int i;
92
93 if (clear) {
94 char *s, *stuff[] = {"TERM", "DISPLAY", "COLORTERM", "XAUTHORITY"};
95
96 for (i=0; i<ARRAY_LEN(stuff); i++)
97 stuff[i] = (s = getenv(stuff[i])) ? xmprintf("%s=%s", stuff[i], s) : 0;
98 xclearenv();
99 for (i=0; i < ARRAY_LEN(stuff); i++) if (stuff[i]) xsetenv(stuff[i], 0);
100 if (chdir(p->pw_dir)) {
101 perror_msg("chdir %s", p->pw_dir);
102 xchdir("/");
103 }
104 } else {
105 char **ev1, **ev2;
106
107
108 for (ev1 = ev2 = environ;;) {
109 while (*ev2 && (strstart(ev2, "LD_") || strstart(ev2, "IFS=") ||
110 strstart(ev2, "ENV=") || strstart(ev2, "BASH_ENV="))) ev2++;
111 if (!(*ev1++ = *ev2++)) break;
112 }
113 }
114
115 setenv("PATH", _PATH_DEFPATH, 1);
116 setenv("HOME", p->pw_dir, 1);
117 setenv("SHELL", p->pw_shell, 1);
118 setenv("USER", p->pw_name, 1);
119 setenv("LOGNAME", p->pw_name, 1);
120}
121