Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"mk.h"
2
 
3
char 	*shell =	"/bin/rc";
4
char 	*shellname =	"rc";
5
 
6
static	Word	*encodenulls(char*, int);
7
 
8
void
9
readenv(void)
10
{
11
	char *p;
12
	int envf, f;
13
	Dir *e;
14
	char nam[1024];
15
	int i, n, len;
16
	Word *w;
17
 
18
	rfork(RFENVG);	/*  use copy of the current environment variables */
19
 
20
	envf = open("/env", OREAD);
21
	if(envf < 0)
22
		return;
23
	while((n = dirread(envf, &e)) > 0){
24
		for(i = 0; i < n; i++){
25
			len = e[i].length;
26
				/* don't import funny names, NULL values,
27
				 * or internal mk variables
28
				 */
29
			if(len <= 0 || *shname(e[i].name) != '\0')
30
				continue;
31
			if (symlook(e[i].name, S_INTERNAL, 0))
32
				continue;
33
			snprint(nam, sizeof nam, "/env/%s", e[i].name);
34
			f = open(nam, OREAD);
35
			if(f < 0)
36
				continue;
37
			p = Malloc(len+1);
38
			if(read(f, p, len) != len){
39
				perror(nam);
40
				close(f);
41
				continue;
42
			}
43
			close(f);
44
			if (p[len-1] == 0)
45
				len--;
46
			else
47
				p[len] = 0;
48
			w = encodenulls(p, len);
49
			free(p);
50
			p = strdup(e[i].name);
51
			setvar(p, (void *) w);
52
			symlook(p, S_EXPORTED, (void*)"")->u.ptr = "";
53
		}
54
		free(e);
55
	}
56
	close(envf);
57
}
58
 
59
/* break string of values into words at 01's or nulls*/
60
static Word *
61
encodenulls(char *s, int n)
62
{
63
	Word *w, *head;
64
	char *cp;
65
 
66
	head = w = 0;
67
	while (n-- > 0) {
68
		for (cp = s; *cp && *cp != '\0'; cp++)
69
				n--;
70
		*cp = 0;
71
		if (w) {
72
			w->next = newword(s);
73
			w = w->next;
74
		} else
75
			head = w = newword(s);
76
		s = cp+1;
77
	}
78
	if (!head)
79
		head = newword("");
80
	return head;
81
}
82
 
83
/* as well as 01's, change blanks to nulls, so that rc will
84
 * treat the words as separate arguments
85
 */
86
void
87
exportenv(Envy *e)
88
{
89
	int f, n, hasvalue, first;
90
	Word *w;
91
	Symtab *sy;
92
	char nam[256];
93
 
94
	for(;e->name; e++){
95
		sy = symlook(e->name, S_VAR, 0);
96
		if (e->values == 0 || e->values->s == 0 || e->values->s[0] == 0)
97
			hasvalue = 0;
98
		else
99
			hasvalue = 1;
100
		if(sy == 0 && !hasvalue)	/* non-existant null symbol */
101
			continue;
102
		snprint(nam, sizeof nam, "/env/%s", e->name);
103
		if (sy != 0 && !hasvalue) {	/* Remove from environment */
104
				/* we could remove it from the symbol table
105
				 * too, but we're in the child copy, and it
106
				 * would still remain in the parent's table.
107
				 */
108
			remove(nam);
109
			delword(e->values);
110
			e->values = 0;		/* memory leak */
111
			continue;
112
		}
113
 
114
		f = create(nam, OWRITE, 0666L);
115
		if(f < 0) {
116
			fprint(2, "can't create %s, f=%d\n", nam, f);
117
			perror(nam);
118
			continue;
119
		}
120
		first = 1;
121
		for (w = e->values; w; w = w->next) {
122
			n = strlen(w->s);
123
			if (n) {
124
				if(first)
125
					first = 0;
126
				else{
127
					if (write (f, "\0", 1) != 1)
128
						perror(nam);
129
				}
130
				if (write(f, w->s, n) != n)
131
					perror(nam);
132
			}
133
		}
134
		close(f);
135
	}
136
}
137
 
138
int
139
waitfor(char *msg)
140
{
141
	Waitmsg *w;
142
	int pid;
143
 
144
	if((w=wait()) == nil)
145
		return -1;
146
	strecpy(msg, msg+ERRMAX, w->msg);
147
	pid = w->pid;
148
	free(w);
149
	return pid;
150
}
151
 
152
void
153
expunge(int pid, char *msg)
154
{
155
	postnote(PNPROC, pid, msg);
156
}
157
 
158
int
159
execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
160
{
161
	char *p;
162
	int tot, n, pid, in[2], out[2];
163
 
164
	if(buf && pipe(out) < 0){
165
		perror("pipe");
166
		Exit();
167
	}
168
	pid = rfork(RFPROC|RFFDG|RFENVG);
169
	if(pid < 0){
170
		perror("mk rfork");
171
		Exit();
172
	}
173
	if(pid == 0){
174
		if(buf)
175
			close(out[0]);
176
		if(pipe(in) < 0){
177
			perror("pipe");
178
			Exit();
179
		}
180
		pid = fork();
181
		if(pid < 0){
182
			perror("mk fork");
183
			Exit();
184
		}
185
		if(pid != 0){
186
			dup(in[0], 0);
187
			if(buf){
188
				dup(out[1], 1);
189
				close(out[1]);
190
			}
191
			close(in[0]);
192
			close(in[1]);
193
			if (e)
194
				exportenv(e);
195
			if(shflags)
196
				execl(shell, shellname, shflags, args, nil);
197
			else
198
				execl(shell, shellname, args, nil);
199
			perror(shell);
200
			_exits("exec");
201
		}
202
		close(out[1]);
203
		close(in[0]);
204
		p = cmd+strlen(cmd);
205
		while(cmd < p){
206
			n = write(in[1], cmd, p-cmd);
207
			if(n < 0)
208
				break;
209
			cmd += n;
210
		}
211
		close(in[1]);
212
		_exits(0);
213
	}
214
	if(buf){
215
		close(out[1]);
216
		tot = 0;
217
		for(;;){
218
			if (buf->current >= buf->end)
219
				growbuf(buf);
220
			n = read(out[0], buf->current, buf->end-buf->current);
221
			if(n <= 0)
222
				break;
223
			buf->current += n;
224
			tot += n;
225
		}
226
		if (tot && buf->current[-1] == '\n')
227
			buf->current--;
228
		close(out[0]);
229
	}
230
	return pid;
231
}
232
 
233
int
234
pipecmd(char *cmd, Envy *e, int *fd)
235
{
236
	int pid, pfd[2];
237
 
238
	if(DEBUG(D_EXEC))
239
		fprint(1, "pipecmd='%s'\n", cmd);/**/
240
 
241
	if(fd && pipe(pfd) < 0){
242
		perror("pipe");
243
		Exit();
244
	}
245
	pid = rfork(RFPROC|RFFDG|RFENVG);
246
	if(pid < 0){
247
		perror("mk fork");
248
		Exit();
249
	}
250
	if(pid == 0){
251
		if(fd){
252
			close(pfd[0]);
253
			dup(pfd[1], 1);
254
			close(pfd[1]);
255
		}
256
		if(e)
257
			exportenv(e);
258
		if(shflags)
259
			execl(shell, shellname, shflags, "-c", cmd, nil);
260
		else
261
			execl(shell, shellname, "-c", cmd, nil);
262
		perror(shell);
263
		_exits("exec");
264
	}
265
	if(fd){
266
		close(pfd[1]);
267
		*fd = pfd[0];
268
	}
269
	return pid;
270
}
271
 
272
void
273
Exit(void)
274
{
275
	while(waitpid() >= 0)
276
		;
277
	exits("error");
278
}
279
 
280
int
281
notifyf(void *a, char *msg)
282
{
283
	static int nnote;
284
 
285
	USED(a);
286
	if(++nnote > 100){	/* until andrew fixes his program */
287
		fprint(2, "mk: too many notes\n");
288
		notify(0);
289
		abort();
290
	}
291
	if(strcmp(msg, "interrupt")!=0 && strcmp(msg, "hangup")!=0)
292
		return 0;
293
	killchildren(msg);
294
	return -1;
295
}
296
 
297
void
298
catchnotes()
299
{
300
	atnotify(notifyf, 1);
301
}
302
 
303
char*
304
maketmp(void)
305
{
306
	static char temp[] = "/tmp/mkargXXXXXX";
307
 
308
	mktemp(temp);
309
	return temp;
310
}
311
 
312
int
313
chgtime(char *name)
314
{
315
	Dir sbuf;
316
 
317
	if(access(name, AEXIST) >= 0) {
318
		nulldir(&sbuf);
319
		sbuf.mtime = time((long *)0);
320
		return dirwstat(name, &sbuf);
321
	}
322
	return close(create(name, OWRITE, 0666));
323
}
324
 
325
void
326
rcopy(char **to, Resub *match, int n)
327
{
328
	int c;
329
	char *p;
330
 
331
	*to = match->sp;		/* stem0 matches complete target */
332
	for(to++, match++; --n > 0; to++, match++){
333
		if(match->sp && match->ep){
334
			p = match->ep;
335
			c = *p;
336
			*p = 0;
337
			*to = strdup(match->sp);
338
			*p = c;
339
		}
340
		else
341
			*to = 0;
342
	}
343
}
344
 
345
void
346
dirtime(char *dir, char *path)
347
{
348
	int i, fd, n;
349
	ulong mtime;
350
	Dir *d;
351
	char buf[4096];
352
 
353
	fd = open(dir, OREAD);
354
	if(fd >= 0){
355
		while((n = dirread(fd, &d)) > 0){
356
			for(i=0; i<n; i++){
357
				mtime = d[i].mtime;
358
				/* defensive driving: this does happen */
359
				if(mtime == 0)
360
					mtime = 1;
361
				snprint(buf, sizeof buf, "%s%s", path,
362
					d[i].name);
363
				if(symlook(buf, S_TIME, 0) == nil)
364
					symlook(strdup(buf), S_TIME,
365
						(void*)mtime)->u.value = mtime;
366
			}
367
			free(d);
368
		}
369
		close(fd);
370
	}
371
}
372
 
373
void
374
bulkmtime(char *dir)
375
{
376
	char buf[4096];
377
	char *ss, *s, *sym;
378
 
379
	if(dir){
380
		sym = dir;
381
		s = dir;
382
		if(strcmp(dir, "/") == 0)
383
			strecpy(buf, buf + sizeof buf - 1, dir);
384
		else
385
			snprint(buf, sizeof buf, "%s/", dir);
386
	}else{
387
		s = ".";
388
		sym = "";
389
		buf[0] = 0;
390
	}
391
	if(symlook(sym, S_BULKED, 0))
392
		return;
393
	ss = strdup(sym);
394
	symlook(ss, S_BULKED, (void*)ss);
395
	dirtime(s, buf);
396
}
397
 
398
ulong
399
mkmtime(char *name, int force)
400
{
401
	Dir *d;
402
	char *s, *ss, carry;
403
	ulong t;
404
	Symtab *sym;
405
	char buf[4096];
406
 
407
	strecpy(buf, buf + sizeof buf - 1, name);
408
	cleanname(buf);
409
	name = buf;
410
 
411
	s = utfrrune(name, '/');
412
	if(s == name)
413
		s++;
414
	if(s){
415
		ss = name;
416
		carry = *s;
417
		*s = 0;
418
	}else{
419
		ss = 0;
420
		carry = 0;
421
	}
422
	bulkmtime(ss);
423
	if(carry)
424
		*s = carry;
425
	if(!force){
426
		sym = symlook(name, S_TIME, 0);
427
		if(sym)
428
			return sym->u.value;
429
		return 0;
430
	}
431
	if((d = dirstat(name)) == nil)
432
		return 0;
433
	t = d->mtime;
434
	free(d);
435
	return t;
436
}
437