xref: /csrg-svn/old/init/init.c (revision 1029)
1*1029Sbill static char *sccsid = "@(#)init.c	4.1 (Berkeley) 10/01/80";
2*1029Sbill #include <signal.h>
3*1029Sbill #include <sys/types.h>
4*1029Sbill #include <utmp.h>
5*1029Sbill #include <setjmp.h>
6*1029Sbill 
7*1029Sbill #define	LINSIZ	sizeof(wtmp.ut_line)
8*1029Sbill #define	TABSIZ	100
9*1029Sbill #define	ALL	p = &itab[0]; p < &itab[TABSIZ]; p++
10*1029Sbill #define	EVER	;;
11*1029Sbill #define SCPYN(a, b)	strncpy(a, b, sizeof(a))
12*1029Sbill #define SCMPN(a, b)	strncmp(a, b, sizeof(a))
13*1029Sbill 
14*1029Sbill char	shell[]	= "/bin/sh";
15*1029Sbill char	getty[]	 = "/etc/getty.vm";
16*1029Sbill char	minus[]	= "-";
17*1029Sbill char	runc[]	= "/etc/rc";
18*1029Sbill char	ifile[]	= "/etc/ttys";
19*1029Sbill char	utmp[]	= "/etc/utmp";
20*1029Sbill char	wtmpf[]	= "/usr/adm/wtmp";
21*1029Sbill char	ctty[]	= "/dev/console";
22*1029Sbill char	dev[]	= "/dev/";
23*1029Sbill 
24*1029Sbill struct utmp wtmp;
25*1029Sbill struct
26*1029Sbill {
27*1029Sbill 	char	line[LINSIZ];
28*1029Sbill 	char	comn;
29*1029Sbill 	char	flag;
30*1029Sbill } line;
31*1029Sbill struct	tab
32*1029Sbill {
33*1029Sbill 	char	line[LINSIZ];
34*1029Sbill 	char	comn;
35*1029Sbill 	char	xflag;
36*1029Sbill 	int	pid;
37*1029Sbill } itab[TABSIZ];
38*1029Sbill 
39*1029Sbill int	fi;
40*1029Sbill int	mergflag;
41*1029Sbill char	tty[20];
42*1029Sbill jmp_buf	sjbuf;
43*1029Sbill 
44*1029Sbill int	reset();
45*1029Sbill char	*strcpy(), *strcat();
46*1029Sbill long	lseek();
47*1029Sbill 
48*1029Sbill main()
49*1029Sbill {
50*1029Sbill 	setjmp(sjbuf);
51*1029Sbill 	signal(SIGTERM, reset);
52*1029Sbill 	signal(SIGSTOP, SIG_IGN);
53*1029Sbill 	signal(SIGTSTP, SIG_IGN);
54*1029Sbill 	signal(SIGTTIN, SIG_IGN);
55*1029Sbill 	signal(SIGTTOU, SIG_IGN);
56*1029Sbill 	for(EVER) {
57*1029Sbill 		shutdown();
58*1029Sbill 		single();
59*1029Sbill 		runcom();
60*1029Sbill 		merge();
61*1029Sbill 		multiple();
62*1029Sbill 	}
63*1029Sbill }
64*1029Sbill 
65*1029Sbill shutdown()
66*1029Sbill {
67*1029Sbill 	register i;
68*1029Sbill 	register struct tab *p;
69*1029Sbill 
70*1029Sbill 	close(creat(utmp, 0644));
71*1029Sbill 	signal(SIGHUP, SIG_IGN);
72*1029Sbill 	for(ALL) {
73*1029Sbill 		term(p);
74*1029Sbill 		p->line[0] = 0;
75*1029Sbill 	}
76*1029Sbill 	signal(SIGALRM, reset);
77*1029Sbill 	alarm(60);
78*1029Sbill 	for(i=0; i<5; i++)
79*1029Sbill 		kill(-1, SIGKILL);
80*1029Sbill 	while(wait((int *)0) != -1)
81*1029Sbill 		;
82*1029Sbill 	alarm(0);
83*1029Sbill 	signal(SIGALRM, SIG_DFL);
84*1029Sbill 	for(i=0; i<10; i++)
85*1029Sbill 		close(i);
86*1029Sbill }
87*1029Sbill 
88*1029Sbill single()
89*1029Sbill {
90*1029Sbill 	register pid;
91*1029Sbill 
92*1029Sbill 	pid = fork();
93*1029Sbill 	if(pid == 0) {
94*1029Sbill /*
95*1029Sbill 		alarm(300);
96*1029Sbill */
97*1029Sbill 		signal(SIGTERM, SIG_DFL);
98*1029Sbill 		signal(SIGHUP, SIG_DFL);
99*1029Sbill 		signal(SIGALRM, SIG_DFL);
100*1029Sbill 		open(ctty, 2);
101*1029Sbill 		dup(0);
102*1029Sbill 		dup(0);
103*1029Sbill 		execl(shell, minus, (char *)0);
104*1029Sbill 		exit(0);
105*1029Sbill 	}
106*1029Sbill 	while(wait((int *)0) != pid)
107*1029Sbill 		;
108*1029Sbill }
109*1029Sbill 
110*1029Sbill runcom()
111*1029Sbill {
112*1029Sbill 	register pid, f;
113*1029Sbill 
114*1029Sbill 	pid = fork();
115*1029Sbill 	if(pid == 0) {
116*1029Sbill 		open("/", 0);
117*1029Sbill 		dup(0);
118*1029Sbill 		dup(0);
119*1029Sbill 		execl(shell, shell, runc, (char *)0);
120*1029Sbill 		exit(0);
121*1029Sbill 	}
122*1029Sbill 	while(wait((int *)0) != pid)
123*1029Sbill 		;
124*1029Sbill 	f = open(wtmpf, 1);
125*1029Sbill 	if (f >= 0) {
126*1029Sbill 		lseek(f, 0L, 2);
127*1029Sbill 		SCPYN(wtmp.ut_line, "~");
128*1029Sbill 		SCPYN(wtmp.ut_name, "reboot");
129*1029Sbill 		time(&wtmp.ut_time);
130*1029Sbill 		write(f, (char *)&wtmp, sizeof(wtmp));
131*1029Sbill 		close(f);
132*1029Sbill 	}
133*1029Sbill }
134*1029Sbill 
135*1029Sbill setmerge()
136*1029Sbill {
137*1029Sbill 
138*1029Sbill 	signal(SIGHUP, setmerge);
139*1029Sbill 	mergflag = 1;
140*1029Sbill }
141*1029Sbill 
142*1029Sbill multiple()
143*1029Sbill {
144*1029Sbill 	register struct tab *p;
145*1029Sbill 	register pid;
146*1029Sbill 
147*1029Sbill loop:
148*1029Sbill 	mergflag = 0;
149*1029Sbill 	signal(SIGHUP, setmerge);
150*1029Sbill 	for(EVER) {
151*1029Sbill 		pid = wait((int *)0);
152*1029Sbill 		if(mergflag) {
153*1029Sbill 			merge();
154*1029Sbill 			goto loop;
155*1029Sbill 		}
156*1029Sbill 		if(pid == -1)
157*1029Sbill 			return;
158*1029Sbill 		for(ALL)
159*1029Sbill 			if(p->pid == pid || p->pid == -1) {
160*1029Sbill 				rmut(p);
161*1029Sbill 				dfork(p);
162*1029Sbill 			}
163*1029Sbill 	}
164*1029Sbill }
165*1029Sbill 
166*1029Sbill term(p)
167*1029Sbill register struct tab *p;
168*1029Sbill {
169*1029Sbill 
170*1029Sbill 	if(p->pid != 0) {
171*1029Sbill 		rmut(p);
172*1029Sbill 		kill(p->pid, SIGKILL);
173*1029Sbill 	}
174*1029Sbill 	p->pid = 0;
175*1029Sbill }
176*1029Sbill 
177*1029Sbill rline()
178*1029Sbill {
179*1029Sbill 	register c, i;
180*1029Sbill 
181*1029Sbill loop:
182*1029Sbill 	c = get();
183*1029Sbill 	if(c < 0)
184*1029Sbill 		return(0);
185*1029Sbill 	if(c == 0)
186*1029Sbill 		goto loop;
187*1029Sbill 	line.flag = c;
188*1029Sbill 	c = get();
189*1029Sbill 	if(c <= 0)
190*1029Sbill 		goto loop;
191*1029Sbill 	line.comn = c;
192*1029Sbill 	SCPYN(line.line, "");
193*1029Sbill 	for (i=0; i<LINSIZ; i++) {
194*1029Sbill 		c = get();
195*1029Sbill 		if(c <= 0)
196*1029Sbill 			break;
197*1029Sbill 		line.line[i] = c;
198*1029Sbill 	}
199*1029Sbill 	while(c > 0)
200*1029Sbill 		c = get();
201*1029Sbill 	if(line.line[0] == 0)
202*1029Sbill 		goto loop;
203*1029Sbill 	if(line.flag == '0')
204*1029Sbill 		goto loop;
205*1029Sbill 	strcpy(tty, dev);
206*1029Sbill 	strncat(tty, line.line, LINSIZ);
207*1029Sbill 	if(access(tty, 06) < 0)
208*1029Sbill 		goto loop;
209*1029Sbill 	return(1);
210*1029Sbill }
211*1029Sbill 
212*1029Sbill get()
213*1029Sbill {
214*1029Sbill 	char b;
215*1029Sbill 
216*1029Sbill 	if(read(fi, &b, 1) != 1)
217*1029Sbill 		return(-1);
218*1029Sbill 	if(b == '\n')
219*1029Sbill 		return(0);
220*1029Sbill 	return(b);
221*1029Sbill }
222*1029Sbill 
223*1029Sbill #define	FOUND	1
224*1029Sbill #define	CHANGE	2
225*1029Sbill 
226*1029Sbill merge()
227*1029Sbill {
228*1029Sbill 	register struct tab *p;
229*1029Sbill 
230*1029Sbill 	fi = open(ifile, 0);
231*1029Sbill 	if(fi < 0)
232*1029Sbill 		return;
233*1029Sbill 	for(ALL)
234*1029Sbill 		p->xflag = 0;
235*1029Sbill 	while(rline()) {
236*1029Sbill 		for(ALL) {
237*1029Sbill 			if (SCMPN(p->line, line.line))
238*1029Sbill 				continue;
239*1029Sbill 			p->xflag |= FOUND;
240*1029Sbill 			if(line.comn != p->comn) {
241*1029Sbill 				p->xflag |= CHANGE;
242*1029Sbill 				p->comn = line.comn;
243*1029Sbill 			}
244*1029Sbill 			goto contin1;
245*1029Sbill 		}
246*1029Sbill 		for(ALL) {
247*1029Sbill 			if(p->line[0] != 0)
248*1029Sbill 				continue;
249*1029Sbill 			SCPYN(p->line, line.line);
250*1029Sbill 			p->xflag |= FOUND|CHANGE;
251*1029Sbill 			p->comn = line.comn;
252*1029Sbill 			goto contin1;
253*1029Sbill 		}
254*1029Sbill 	contin1:
255*1029Sbill 		;
256*1029Sbill 	}
257*1029Sbill 	close(fi);
258*1029Sbill 	for(ALL) {
259*1029Sbill 		if((p->xflag&FOUND) == 0) {
260*1029Sbill 			term(p);
261*1029Sbill 			p->line[0] = 0;
262*1029Sbill 		}
263*1029Sbill 		if((p->xflag&CHANGE) != 0) {
264*1029Sbill 			term(p);
265*1029Sbill 			dfork(p);
266*1029Sbill 		}
267*1029Sbill 	}
268*1029Sbill }
269*1029Sbill 
270*1029Sbill dfork(p)
271*1029Sbill struct tab *p;
272*1029Sbill {
273*1029Sbill 	register pid;
274*1029Sbill 
275*1029Sbill 	pid = fork();
276*1029Sbill 	if(pid == 0) {
277*1029Sbill 		signal(SIGTERM, SIG_DFL);
278*1029Sbill 		signal(SIGHUP, SIG_IGN);
279*1029Sbill 		strcpy(tty, dev);
280*1029Sbill 		strncat(tty, p->line, LINSIZ);
281*1029Sbill 		chown(tty, 0, 0);
282*1029Sbill 		chmod(tty, 0622);
283*1029Sbill 		open(tty, 2);
284*1029Sbill 		vhangup();
285*1029Sbill 		signal(SIGHUP, SIG_DFL);
286*1029Sbill 		open(tty, 2);
287*1029Sbill 		close(0);
288*1029Sbill 		dup(1);
289*1029Sbill 		dup(0);
290*1029Sbill 		tty[0] = p->comn;
291*1029Sbill 		tty[1] = 0;
292*1029Sbill 		execl(getty, minus, tty, (char *)0);
293*1029Sbill 		exit(0);
294*1029Sbill 	}
295*1029Sbill 	p->pid = pid;
296*1029Sbill }
297*1029Sbill 
298*1029Sbill rmut(p)
299*1029Sbill register struct tab *p;
300*1029Sbill {
301*1029Sbill 	register f;
302*1029Sbill 
303*1029Sbill 	f = open(utmp, 2);
304*1029Sbill 	if(f >= 0) {
305*1029Sbill 		while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
306*1029Sbill 			if (SCMPN(wtmp.ut_line, p->line))
307*1029Sbill 				continue;
308*1029Sbill 			lseek(f, -(long)sizeof(wtmp), 1);
309*1029Sbill 			SCPYN(wtmp.ut_name, "");
310*1029Sbill 			time(&wtmp.ut_time);
311*1029Sbill 			write(f, (char *)&wtmp, sizeof(wtmp));
312*1029Sbill 		}
313*1029Sbill 		close(f);
314*1029Sbill 	}
315*1029Sbill 	f = open(wtmpf, 1);
316*1029Sbill 	if (f >= 0) {
317*1029Sbill 		SCPYN(wtmp.ut_line, p->line);
318*1029Sbill 		SCPYN(wtmp.ut_name, "");
319*1029Sbill 		time(&wtmp.ut_time);
320*1029Sbill 		lseek(f, (long)0, 2);
321*1029Sbill 		write(f, (char *)&wtmp, sizeof(wtmp));
322*1029Sbill 		close(f);
323*1029Sbill 	}
324*1029Sbill }
325*1029Sbill 
326*1029Sbill reset()
327*1029Sbill {
328*1029Sbill 	longjmp(sjbuf, 1);
329*1029Sbill }
330*1029Sbill 
331*1029Sbill 
332