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