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