replace mkdir with sys call
[unix-history] / usr / src / old / init / init.c
CommitLineData
cce8e495 1static char *sccsid = "@(#)init.c 4.9 (Berkeley) %G%";
7c8ab0e6
BJ
2#include <signal.h>
3#include <sys/types.h>
4#include <utmp.h>
5#include <setjmp.h>
215943cc 6#include <sys/reboot.h>
f570e1ff 7#include <errno.h>
7c8ab0e6
BJ
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
16char shell[] = "/bin/sh";
215943cc 17char getty[] = "/etc/getty";
7c8ab0e6
BJ
18char minus[] = "-";
19char runc[] = "/etc/rc";
20char ifile[] = "/etc/ttys";
21char utmp[] = "/etc/utmp";
22char wtmpf[] = "/usr/adm/wtmp";
23char ctty[] = "/dev/console";
24char dev[] = "/dev/";
25
26struct utmp wtmp;
27struct
28{
29 char line[LINSIZ];
30 char comn;
31 char flag;
32} line;
33struct tab
34{
35 char line[LINSIZ];
36 char comn;
37 char xflag;
38 int pid;
43236707
BJ
39 time_t gettytime;
40 int gettycnt;
7c8ab0e6
BJ
41} itab[TABSIZ];
42
43int fi;
44int mergflag;
45char tty[20];
abf0db3c 46jmp_buf sjbuf, shutpass;
f570e1ff 47time_t time0;
7c8ab0e6
BJ
48
49int reset();
f570e1ff 50int idle();
7c8ab0e6
BJ
51char *strcpy(), *strcat();
52long lseek();
53
54main()
55{
215943cc
BJ
56 register int r11; /* passed thru from boot */
57 int howto, oldhowto;
58
f570e1ff 59 time0 = time(0);
215943cc 60 howto = r11;
7c8ab0e6
BJ
61 setjmp(sjbuf);
62 signal(SIGTERM, reset);
f570e1ff 63 signal(SIGTSTP, idle);
7c8ab0e6 64 signal(SIGSTOP, SIG_IGN);
7c8ab0e6
BJ
65 signal(SIGTTIN, SIG_IGN);
66 signal(SIGTTOU, SIG_IGN);
67 for(EVER) {
215943cc
BJ
68 oldhowto = howto;
69 howto = RB_SINGLE;
abf0db3c
BJ
70 if (setjmp(shutpass) == 0)
71 shutdown();
215943cc
BJ
72 if (oldhowto & RB_SINGLE)
73 single();
74 if (runcom(oldhowto) == 0)
75 continue;
7c8ab0e6
BJ
76 merge();
77 multiple();
78 }
79}
80
abf0db3c
BJ
81int shutreset();
82
7c8ab0e6
BJ
83shutdown()
84{
85 register i;
86 register struct tab *p;
87
88 close(creat(utmp, 0644));
89 signal(SIGHUP, SIG_IGN);
90 for(ALL) {
91 term(p);
92 p->line[0] = 0;
93 }
abf0db3c
BJ
94 signal(SIGALRM, shutreset);
95 alarm(30);
7c8ab0e6
BJ
96 for(i=0; i<5; i++)
97 kill(-1, SIGKILL);
98 while(wait((int *)0) != -1)
99 ;
100 alarm(0);
abf0db3c
BJ
101 shutend();
102}
103
104char shutfailm[] = "WARNING: Something is hung (wont die); ps axl advised\n";
105
106shutreset()
107{
108 int status;
109
110 if (fork() == 0) {
111 int ct = open(ctty, 1);
112 write(ct, shutfailm, sizeof (shutfailm));
113 sleep(5);
114 exit(1);
115 }
116 sleep(5);
117 shutend();
118 longjmp(shutpass, 1);
119}
120
121shutend()
122{
f570e1ff 123 register i, f;
abf0db3c 124
f570e1ff 125 acct(0);
7c8ab0e6
BJ
126 signal(SIGALRM, SIG_DFL);
127 for(i=0; i<10; i++)
128 close(i);
f570e1ff
BJ
129 f = open(wtmpf, 1);
130 if (f >= 0) {
131 lseek(f, 0L, 2);
132 SCPYN(wtmp.ut_line, "~");
133 SCPYN(wtmp.ut_name, "shutdown");
134 time(&wtmp.ut_time);
135 write(f, (char *)&wtmp, sizeof(wtmp));
136 close(f);
137 }
138 return(1);
7c8ab0e6
BJ
139}
140
141single()
142{
143 register pid;
f570e1ff
BJ
144 register xpid;
145 extern errno;
7c8ab0e6 146
f570e1ff 147 do {
7c8ab0e6
BJ
148 pid = fork();
149 if(pid == 0) {
150/*
151 alarm(300);
152*/
153 signal(SIGTERM, SIG_DFL);
154 signal(SIGHUP, SIG_DFL);
155 signal(SIGALRM, SIG_DFL);
156 open(ctty, 2);
157 dup(0);
158 dup(0);
159 execl(shell, minus, (char *)0);
160 exit(0);
161 }
f570e1ff
BJ
162 while((xpid = wait((int *)0)) != pid)
163 if (xpid == -1 && errno == ECHILD)
164 break;
165 } while (xpid == -1);
7c8ab0e6
BJ
166}
167
215943cc
BJ
168runcom(oldhowto)
169 int oldhowto;
7c8ab0e6
BJ
170{
171 register pid, f;
215943cc 172 int status;
7c8ab0e6
BJ
173
174 pid = fork();
175 if(pid == 0) {
176 open("/", 0);
177 dup(0);
178 dup(0);
215943cc
BJ
179 if (oldhowto & RB_SINGLE)
180 execl(shell, shell, runc, (char *)0);
181 else
182 execl(shell, shell, runc, "autoboot", (char *)0);
183 exit(1);
7c8ab0e6 184 }
215943cc 185 while(wait(&status) != pid)
7c8ab0e6 186 ;
215943cc
BJ
187 if(status)
188 return(0);
7c8ab0e6
BJ
189 f = open(wtmpf, 1);
190 if (f >= 0) {
191 lseek(f, 0L, 2);
192 SCPYN(wtmp.ut_line, "~");
193 SCPYN(wtmp.ut_name, "reboot");
f570e1ff
BJ
194 if (time0) {
195 wtmp.ut_time = time0;
196 time0 = 0;
197 } else
198 time(&wtmp.ut_time);
7c8ab0e6
BJ
199 write(f, (char *)&wtmp, sizeof(wtmp));
200 close(f);
201 }
215943cc 202 return(1);
7c8ab0e6
BJ
203}
204
205setmerge()
206{
207
208 signal(SIGHUP, setmerge);
209 mergflag = 1;
210}
211
212multiple()
213{
214 register struct tab *p;
215 register pid;
216
217loop:
218 mergflag = 0;
219 signal(SIGHUP, setmerge);
220 for(EVER) {
221 pid = wait((int *)0);
222 if(mergflag) {
223 merge();
224 goto loop;
225 }
226 if(pid == -1)
227 return;
228 for(ALL)
229 if(p->pid == pid || p->pid == -1) {
230 rmut(p);
231 dfork(p);
232 }
233 }
234}
235
236term(p)
237register struct tab *p;
238{
239
240 if(p->pid != 0) {
241 rmut(p);
242 kill(p->pid, SIGKILL);
243 }
244 p->pid = 0;
245}
246
247rline()
248{
249 register c, i;
250
251loop:
252 c = get();
253 if(c < 0)
254 return(0);
255 if(c == 0)
256 goto loop;
257 line.flag = c;
258 c = get();
259 if(c <= 0)
260 goto loop;
261 line.comn = c;
262 SCPYN(line.line, "");
263 for (i=0; i<LINSIZ; i++) {
264 c = get();
265 if(c <= 0)
266 break;
267 line.line[i] = c;
268 }
269 while(c > 0)
270 c = get();
271 if(line.line[0] == 0)
272 goto loop;
273 if(line.flag == '0')
274 goto loop;
275 strcpy(tty, dev);
276 strncat(tty, line.line, LINSIZ);
277 if(access(tty, 06) < 0)
278 goto loop;
279 return(1);
280}
281
282get()
283{
284 char b;
285
286 if(read(fi, &b, 1) != 1)
287 return(-1);
288 if(b == '\n')
289 return(0);
290 return(b);
291}
292
293#define FOUND 1
294#define CHANGE 2
295
296merge()
297{
298 register struct tab *p;
299
300 fi = open(ifile, 0);
301 if(fi < 0)
302 return;
303 for(ALL)
304 p->xflag = 0;
305 while(rline()) {
306 for(ALL) {
307 if (SCMPN(p->line, line.line))
308 continue;
309 p->xflag |= FOUND;
310 if(line.comn != p->comn) {
311 p->xflag |= CHANGE;
312 p->comn = line.comn;
313 }
314 goto contin1;
315 }
316 for(ALL) {
317 if(p->line[0] != 0)
318 continue;
319 SCPYN(p->line, line.line);
320 p->xflag |= FOUND|CHANGE;
321 p->comn = line.comn;
322 goto contin1;
323 }
324 contin1:
325 ;
326 }
327 close(fi);
328 for(ALL) {
329 if((p->xflag&FOUND) == 0) {
330 term(p);
331 p->line[0] = 0;
332 }
333 if((p->xflag&CHANGE) != 0) {
334 term(p);
335 dfork(p);
336 }
337 }
338}
339
30e1f894
SL
340#include <sys/ioctl.h>
341
7c8ab0e6
BJ
342dfork(p)
343struct tab *p;
344{
345 register pid;
43236707
BJ
346 time_t t;
347 int dowait = 0;
cce8e495 348 extern char *sys_errlist[];
43236707
BJ
349
350 time(&t);
351 p->gettycnt++;
352 if ((t - p->gettytime) >= 60) {
353 p->gettytime = t;
354 p->gettycnt = 1;
355 } else {
356 if (p->gettycnt >= 5) {
357 dowait = 1;
358 p->gettytime = t;
359 p->gettycnt = 1;
360 }
361 }
7c8ab0e6
BJ
362 pid = fork();
363 if(pid == 0) {
30e1f894
SL
364 int oerrno, f;
365 extern int errno;
366
367 signal(SIGTERM, SIG_DFL);
368 signal(SIGHUP, SIG_IGN);
cce8e495
TL
369 strcpy(tty, dev);
370 strncat(tty, p->line, LINSIZ);
43236707 371 if (dowait) {
30e1f894 372 f = open("/dev/console", 1);
43236707
BJ
373 write(f, "init: ", 6);
374 write(f, tty, strlen(tty));
375 write(f, ": getty failing, sleeping\n\r", 27);
376 close(f);
377 sleep(30);
30e1f894
SL
378 if ((f = open("/dev/tty", 2)) >= 0) {
379 ioctl(f, TIOCNOTTY, 0);
380 close(f);
381 }
43236707 382 }
7c8ab0e6
BJ
383 chown(tty, 0, 0);
384 chmod(tty, 0622);
ef9abb5f
BJ
385 if (open(tty, 2) < 0) {
386 int repcnt = 0;
387 do {
30e1f894 388 oerrno = errno;
ef9abb5f 389 if (repcnt % 10 == 0) {
30e1f894 390 f = open("/dev/console", 1);
ef9abb5f 391 write(f, "init: ", 6);
cce8e495
TL
392 write(f, tty, strlen(tty));
393 write(f, ": ", 2);
394 write(f, sys_errlist[oerrno],
395 strlen(sys_errlist[oerrno]));
396 write(f, "\n", 1);
ef9abb5f 397 close(f);
30e1f894
SL
398 if ((f = open("/dev/tty", 2)) >= 0) {
399 ioctl(f, TIOCNOTTY, 0);
400 close(f);
401 }
ef9abb5f
BJ
402 }
403 repcnt++;
404 sleep(60);
405 } while (open(tty, 2) < 0);
406 exit(0); /* have wrong control tty, start over */
407 }
7c8ab0e6
BJ
408 vhangup();
409 signal(SIGHUP, SIG_DFL);
410 open(tty, 2);
411 close(0);
412 dup(1);
413 dup(0);
414 tty[0] = p->comn;
415 tty[1] = 0;
416 execl(getty, minus, tty, (char *)0);
417 exit(0);
418 }
419 p->pid = pid;
420}
421
422rmut(p)
423register struct tab *p;
424{
425 register f;
ef9abb5f 426 int found = 0;
7c8ab0e6
BJ
427
428 f = open(utmp, 2);
429 if(f >= 0) {
430 while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
ef9abb5f 431 if (SCMPN(wtmp.ut_line, p->line) || wtmp.ut_name[0]==0)
7c8ab0e6
BJ
432 continue;
433 lseek(f, -(long)sizeof(wtmp), 1);
434 SCPYN(wtmp.ut_name, "");
435 time(&wtmp.ut_time);
436 write(f, (char *)&wtmp, sizeof(wtmp));
ef9abb5f 437 found++;
7c8ab0e6
BJ
438 }
439 close(f);
440 }
ef9abb5f
BJ
441 if (found) {
442 f = open(wtmpf, 1);
443 if (f >= 0) {
444 SCPYN(wtmp.ut_line, p->line);
445 SCPYN(wtmp.ut_name, "");
446 time(&wtmp.ut_time);
447 lseek(f, (long)0, 2);
448 write(f, (char *)&wtmp, sizeof(wtmp));
449 close(f);
450 }
7c8ab0e6
BJ
451 }
452}
453
454reset()
455{
456 longjmp(sjbuf, 1);
457}
f570e1ff
BJ
458
459idle()
460{
461 register struct tab *p;
462 register pid;
463
464 signal(SIGTSTP, idle);
465 for (;;) {
466 pid = wait((int *) 0);
467 if (mergflag)
468 return;
469 if (pid == -1)
470 pause();
471 else {
472 for (ALL)
473 if (p->pid == pid) {
474 rmut(p);
475 p->pid = -1;
476 }
477 }
478 }
479}