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