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