|
|
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:
8: #define LINSIZ sizeof(wtmp.ut_line)
9: #define TABSIZ 100
10: #define ALL p = &itab[0]; p < &itab[TABSIZ]; p++
11: #define EVER ;;
12: #define SCPYN(a, b) strncpy(a, b, sizeof(a))
13: #define SCMPN(a, b) strncmp(a, b, sizeof(a))
14:
15: char shell[] = "/bin/sh";
16: char getty[] = "/etc/getty";
17: char minus[] = "-";
18: char runc[] = "/etc/rc";
19: char ifile[] = "/etc/ttys";
20: char utmp[] = "/etc/utmp";
21: char wtmpf[] = "/usr/adm/wtmp";
22: char ctty[] = "/dev/console";
23: char dev[] = "/dev/";
24:
25: struct utmp wtmp;
26: struct
27: {
28: char line[LINSIZ];
29: char comn;
30: char flag;
31: } line;
32: struct tab
33: {
34: char line[LINSIZ];
35: char comn;
36: char xflag;
37: int pid;
38: } itab[TABSIZ];
39:
40: int fi;
41: int mergflag;
42: char tty[20];
43: jmp_buf sjbuf, shutpass;
44:
45: int reset();
46: char *strcpy(), *strcat();
47: long lseek();
48:
49: main()
50: {
51: register int r11; /* passed thru from boot */
52: int howto, oldhowto;
53:
54: howto = r11;
55: setjmp(sjbuf);
56: signal(SIGTERM, reset);
57: signal(SIGSTOP, SIG_IGN);
58: signal(SIGTSTP, SIG_IGN);
59: signal(SIGTTIN, SIG_IGN);
60: signal(SIGTTOU, SIG_IGN);
61: for(EVER) {
62: oldhowto = howto;
63: howto = RB_SINGLE;
64: if (setjmp(shutpass) == 0)
65: shutdown();
66: if (oldhowto & RB_SINGLE)
67: single();
68: if (runcom(oldhowto) == 0)
69: continue;
70: merge();
71: multiple();
72: }
73: }
74:
75: int shutreset();
76:
77: shutdown()
78: {
79: register i;
80: register struct tab *p;
81:
82: close(creat(utmp, 0644));
83: signal(SIGHUP, SIG_IGN);
84: for(ALL) {
85: term(p);
86: p->line[0] = 0;
87: }
88: signal(SIGALRM, shutreset);
89: alarm(30);
90: for(i=0; i<5; i++)
91: kill(-1, SIGKILL);
92: while(wait((int *)0) != -1)
93: ;
94: alarm(0);
95: shutend();
96: }
97:
98: char shutfailm[] = "WARNING: Something is hung (wont die); ps axl advised\n";
99:
100: shutreset()
101: {
102: int status;
103:
104: if (fork() == 0) {
105: int ct = open(ctty, 1);
106: write(ct, shutfailm, sizeof (shutfailm));
107: sleep(5);
108: exit(1);
109: }
110: sleep(5);
111: shutend();
112: longjmp(shutpass, 1);
113: }
114:
115: shutend()
116: {
117: register i;
118:
119: signal(SIGALRM, SIG_DFL);
120: for(i=0; i<10; i++)
121: close(i);
122: }
123:
124: single()
125: {
126: register pid;
127:
128: pid = fork();
129: if(pid == 0) {
130: /*
131: alarm(300);
132: */
133: signal(SIGTERM, SIG_DFL);
134: signal(SIGHUP, SIG_DFL);
135: signal(SIGALRM, SIG_DFL);
136: open(ctty, 2);
137: dup(0);
138: dup(0);
139: execl(shell, minus, (char *)0);
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: open("/", 0);
155: dup(0);
156: dup(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_IGN);
323: strcpy(tty, dev);
324: strncat(tty, p->line, LINSIZ);
325: chown(tty, 0, 0);
326: chmod(tty, 0622);
327: open(tty, 2);
328: vhangup();
329: signal(SIGHUP, SIG_DFL);
330: open(tty, 2);
331: close(0);
332: dup(1);
333: dup(0);
334: tty[0] = p->comn;
335: tty[1] = 0;
336: execl(getty, minus, tty, (char *)0);
337: exit(0);
338: }
339: p->pid = pid;
340: }
341:
342: rmut(p)
343: register struct tab *p;
344: {
345: register f;
346:
347: f = open(utmp, 2);
348: if(f >= 0) {
349: while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
350: if (SCMPN(wtmp.ut_line, p->line))
351: continue;
352: lseek(f, -(long)sizeof(wtmp), 1);
353: SCPYN(wtmp.ut_name, "");
354: time(&wtmp.ut_time);
355: write(f, (char *)&wtmp, sizeof(wtmp));
356: }
357: close(f);
358: }
359: f = open(wtmpf, 1);
360: if (f >= 0) {
361: SCPYN(wtmp.ut_line, p->line);
362: SCPYN(wtmp.ut_name, "");
363: time(&wtmp.ut_time);
364: lseek(f, (long)0, 2);
365: write(f, (char *)&wtmp, sizeof(wtmp));
366: close(f);
367: }
368: }
369:
370: reset()
371: {
372: longjmp(sjbuf, 1);
373: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.