|
|
1.1 root 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:
13: char shell[] = "/bin/sh";
14: char getty[] = "/etc/getty.vm";
15: char minus[] = "-";
16: char runc[] = "/etc/rc";
17: char ifile[] = "/etc/ttys";
18: char utmp[] = "/etc/utmp";
19: char wtmpf[] = "/usr/adm/wtmp";
20: char ctty[] = "/dev/console";
21: char dev[] = "/dev/";
22:
23: struct utmp wtmp;
24: struct
25: {
26: char line[LINSIZ];
27: char comn;
28: char flag;
29: } line;
30: struct tab
31: {
32: char line[LINSIZ];
33: char comn;
34: char xflag;
35: int pid;
36: } itab[TABSIZ];
37:
38: int fi;
39: int mergflag;
40: char tty[20];
41: jmp_buf sjbuf;
42:
43: int reset();
44: char *strcpy(), *strcat();
45: long lseek();
46:
47: main()
48: {
49: setjmp(sjbuf);
50: signal(SIGTERM, reset);
51: for(EVER) {
52: shutdown();
53: single();
54: runcom();
55: merge();
56: multiple();
57: }
58: }
59:
60: shutdown()
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:
83: single()
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:
105: runcom()
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:
130: setmerge()
131: {
132:
133: mergflag = 1;
134: }
135:
136: multiple()
137: {
138: register struct tab *p;
139: register pid;
140:
141: loop:
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:
160: term(p)
161: register 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:
171: rline()
172: {
173: register c, i;
174:
175: loop:
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:
206: get()
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:
220: merge()
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:
264: dfork(p)
265: struct 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:
288: rmut(p)
289: register 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:
316: reset()
317: {
318: longjmp(sjbuf, 1);
319: }
320:
321:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.