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