|
|
1.1 root 1: static char *sccsid = "@(#)init.c 4.3 (Berkeley) 10/13/80";
2: #include <signal.h>
3: #include <sys/types.h>
4: #include <utmp.h>
5: #include <setjmp.h>
6: #include <sys/reboot.h>
7: #include <sys/ioctl.h>
1.1.1.2 ! root 8: #include <sun/fbio.h>
1.1 root 9:
10: #define LINSIZ sizeof(wtmp.ut_line)
11: #define TABSIZ 100
12: #define ALL p = &itab[0]; p < &itab[TABSIZ]; p++
13: #define EVER ;;
14: #define SCPYN(a, b) strncpy(a, b, sizeof(a))
15: #define SCMPN(a, b) strncmp(a, b, sizeof(a))
16:
17: char shell[] = "/bin/sh";
18: char getty[] = "/etc/getty";
19: char minus[] = "-";
20: char runc[] = "/etc/rc";
21: char ifile[] = "/etc/ttys";
22: char utmp[] = "/etc/utmp";
23: char wtmpf[] = "/usr/adm/wtmp";
24: char ctty[] = "/dev/console";
25: char dev[] = "/dev/";
26: extern int tty_ld;
27: extern int ntty_ld;
1.1.1.2 ! root 28: extern int kbd_ld;
1.1 root 29:
30: struct utmp wtmp;
31: struct
32: {
33: char line[LINSIZ];
34: char comn;
35: char flag;
36: } line;
37: struct tab
38: {
39: char line[LINSIZ];
40: char comn;
41: char xflag;
42: int pid;
43: } itab[TABSIZ];
44:
45: int fi;
46: int mergflag;
47: char tty[20];
48: jmp_buf sjbuf, shutpass;
49:
50: int reset();
51: char *strcpy(), *strcat();
52: long lseek();
53:
54: main(argc, argv)
55: int argc;
56: char *argv[];
57: {
58: register int r11; /* passed thru from boot */
59: int howto, oldhowto;
60: char *cp;
61:
62: #if vax
63: howto = r11;
64: #endif
65: #if sun
66: howto = 0;
67: cp = &argv[1][1];
68: while(*cp)
69: if(*cp++ == 's')
70: howto = RB_SINGLE;
71: #endif
72: setjmp(sjbuf);
73: signal(SIGTERM, reset);
74: signal(SIGSTOP, SIG_IGN);
75: signal(SIGTSTP, SIG_IGN);
76: signal(SIGTTIN, SIG_IGN);
77: signal(SIGTTOU, SIG_IGN);
78: for(EVER) {
79: oldhowto = howto;
80: howto = RB_SINGLE;
81: if (setjmp(shutpass) == 0)
82: shutdown();
83: if (oldhowto & RB_SINGLE)
84: single();
85: if (runcom(oldhowto) == 0)
86: continue;
87: merge();
88: multiple();
89: }
90: }
91:
92: int shutreset();
93:
94: shutdown()
95: {
96: register i;
97: register struct tab *p;
98:
99: close(creat(utmp, 0644));
100: signal(SIGHUP, SIG_IGN);
101: for(ALL) {
102: term(p);
103: p->line[0] = 0;
104: }
105: signal(SIGALRM, shutreset);
106: alarm(30);
107: for(i=0; i<5; i++)
108: kill(-1, SIGKILL);
109: while(wait((int *)0) != -1)
110: ;
111: alarm(0);
112: shutend();
113: }
114:
115: char shutfailm[] = "WARNING: Something is hung (wont die); ps axl advised\n";
116:
117: shutreset()
118: {
119: int status;
120:
121: if (fork() == 0) {
122: int ct = open(ctty, 1);
123: write(ct, shutfailm, sizeof (shutfailm));
124: sleep(5);
125: exit(1);
126: }
127: sleep(5);
128: shutend();
129: longjmp(shutpass, 1);
130: }
131:
132: shutend()
133: {
134: register i;
135:
136: signal(SIGALRM, SIG_DFL);
137: for(i=0; i<10; i++)
138: close(i);
139: }
140:
141: single()
142: {
143: register pid;
144:
145: pid = fork();
146: if(pid == 0) {
147: signal(SIGTERM, SIG_DFL);
148: signal(SIGHUP, SIG_DFL);
149: signal(SIGALRM, SIG_DFL);
150: setupio(ctty);
151: execl(shell, minus, (char *)0);
152: write(1, "exec failed\n", 12);
153: exit(0);
154: }
155: while(wait((int *)0) != pid)
156: ;
157: }
158:
159: runcom(oldhowto)
160: int oldhowto;
161: {
162: register pid, f;
163: int status;
164:
165: pid = fork();
166: if(pid == 0) {
167: setupio(ctty);
168: close(0);
169: open("/dev/null", 0);
170: if (oldhowto & RB_SINGLE)
171: execl(shell, shell, runc, (char *)0);
172: else
173: execl(shell, shell, runc, "autoboot", (char *)0);
174: exit(1);
175: }
176: while(wait(&status) != pid)
177: ;
178: if(status)
179: return(0);
180: f = open(wtmpf, 1);
181: if (f >= 0) {
182: lseek(f, 0L, 2);
183: SCPYN(wtmp.ut_line, "~");
184: SCPYN(wtmp.ut_name, "reboot");
185: time(&wtmp.ut_time);
186: write(f, (char *)&wtmp, sizeof(wtmp));
187: close(f);
188: }
189: return(1);
190: }
191:
192: setmerge()
193: {
194:
195: signal(SIGHUP, setmerge);
196: mergflag = 1;
197: }
198:
199: multiple()
200: {
201: register struct tab *p;
202: register pid;
203:
204: loop:
205: mergflag = 0;
206: signal(SIGHUP, setmerge);
207: for(EVER) {
208: pid = wait((int *)0);
209: if(mergflag) {
210: merge();
211: goto loop;
212: }
213: if(pid == -1)
214: return;
215: for(ALL)
216: if(p->pid == pid || p->pid == -1) {
217: rmut(p);
218: dfork(p);
219: }
220: }
221: }
222:
223: term(p)
224: register struct tab *p;
225: {
226:
227: if(p->pid != 0) {
228: rmut(p);
229: kill(p->pid, SIGKILL);
230: }
231: p->pid = 0;
232: }
233:
234: rline()
235: {
236: register c, i;
237:
238: loop:
239: c = get();
240: if(c < 0)
241: return(0);
242: if(c == 0)
243: goto loop;
244: line.flag = c;
245: c = get();
246: if(c <= 0)
247: goto loop;
248: line.comn = c;
249: SCPYN(line.line, "");
250: for (i=0; i<LINSIZ; i++) {
251: c = get();
252: if(c <= 0)
253: break;
254: line.line[i] = c;
255: }
256: while(c > 0)
257: c = get();
258: if(line.line[0] == 0)
259: goto loop;
260: if(line.flag == '0')
261: goto loop;
262: strcpy(tty, dev);
263: strncat(tty, line.line, LINSIZ);
264: if(access(tty, 06) < 0)
265: goto loop;
266: return(1);
267: }
268:
269: get()
270: {
271: char b;
272:
273: if(read(fi, &b, 1) != 1)
274: return(-1);
275: if(b == '\n')
276: return(0);
277: return(b);
278: }
279:
280: #define FOUND 1
281: #define CHANGE 2
282:
283: merge()
284: {
285: register struct tab *p;
286:
287: fi = open(ifile, 0);
288: if(fi < 0)
289: return;
290: for(ALL)
291: p->xflag = 0;
292: while(rline()) {
293: for(ALL) {
294: if (SCMPN(p->line, line.line))
295: continue;
296: p->xflag |= FOUND;
297: if(line.comn != p->comn) {
298: p->xflag |= CHANGE;
299: p->comn = line.comn;
300: }
301: goto contin1;
302: }
303: for(ALL) {
304: if(p->line[0] != 0)
305: continue;
306: SCPYN(p->line, line.line);
307: p->xflag |= FOUND|CHANGE;
308: p->comn = line.comn;
309: goto contin1;
310: }
311: contin1:
312: ;
313: }
314: close(fi);
315: for(ALL) {
316: if((p->xflag&FOUND) == 0) {
317: term(p);
318: p->line[0] = 0;
319: }
320: if((p->xflag&CHANGE) != 0) {
321: term(p);
322: dfork(p);
323: }
324: }
325: }
326:
327: dfork(p)
328: struct tab *p;
329: {
330: register pid;
331:
332: pid = fork();
333: if(pid == 0) {
334: signal(SIGTERM, SIG_DFL);
335: signal(SIGHUP, SIG_DFL);
336: strcpy(tty, dev);
337: strncat(tty, p->line, LINSIZ);
338: chown(tty, 0, 0);
339: chmod(tty, 0622);
340: setupio(tty);
341: tty[0] = p->comn;
342: tty[1] = 0;
343: execl(getty, minus, tty, (char *)0);
344: exit(0);
345: }
346: p->pid = pid;
347: }
348:
349: rmut(p)
350: register struct tab *p;
351: {
352: register f;
353:
354: f = open(utmp, 2);
355: if(f >= 0) {
356: while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
357: if (SCMPN(wtmp.ut_line, p->line))
358: continue;
359: lseek(f, -(long)sizeof(wtmp), 1);
360: SCPYN(wtmp.ut_name, "");
361: time(&wtmp.ut_time);
362: write(f, (char *)&wtmp, sizeof(wtmp));
363: }
364: close(f);
365: }
366: f = open(wtmpf, 1);
367: if (f >= 0) {
368: SCPYN(wtmp.ut_line, p->line);
369: SCPYN(wtmp.ut_name, "");
370: time(&wtmp.ut_time);
371: lseek(f, (long)0, 2);
372: write(f, (char *)&wtmp, sizeof(wtmp));
373: close(f);
374: }
375: }
376:
377: reset()
378: {
379: longjmp(sjbuf, 1);
380: }
381:
382: setupio(tty)
383: char *tty;
384: {
385: int f;
386:
387: while (open(tty, 2) != 0)
388: sleep(10);
389: ioctl(0, TIOCSPGRP, (char *)0);
1.1.1.2 ! root 390: while (ioctl(0, FIOPOPLD, (char *)0) >= 0)
! 391: ;
! 392: if (ioctl(0, KBIOISKBD, (char *)0) >= 0)
! 393: ioctl(0, FIOPUSHLD, &kbd_ld);
1.1 root 394: ioctl(0, FIOPUSHLD, &tty_ld);
395: dup(0);
396: dup(0);
397: dup(0);
398: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.