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