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