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