1 static char *sccsid = "@(#)init.c 4.1 (Berkeley) 10/01/80"; 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 14 char shell[] = "/bin/sh"; 15 char getty[] = "/etc/getty.vm"; 16 char minus[] = "-"; 17 char runc[] = "/etc/rc"; 18 char ifile[] = "/etc/ttys"; 19 char utmp[] = "/etc/utmp"; 20 char wtmpf[] = "/usr/adm/wtmp"; 21 char ctty[] = "/dev/console"; 22 char dev[] = "/dev/"; 23 24 struct utmp wtmp; 25 struct 26 { 27 char line[LINSIZ]; 28 char comn; 29 char flag; 30 } line; 31 struct tab 32 { 33 char line[LINSIZ]; 34 char comn; 35 char xflag; 36 int pid; 37 } itab[TABSIZ]; 38 39 int fi; 40 int mergflag; 41 char tty[20]; 42 jmp_buf sjbuf; 43 44 int reset(); 45 char *strcpy(), *strcat(); 46 long lseek(); 47 48 main() 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 65 shutdown() 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 88 single() 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 110 runcom() 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 135 setmerge() 136 { 137 138 signal(SIGHUP, setmerge); 139 mergflag = 1; 140 } 141 142 multiple() 143 { 144 register struct tab *p; 145 register pid; 146 147 loop: 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 166 term(p) 167 register 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 177 rline() 178 { 179 register c, i; 180 181 loop: 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 212 get() 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 226 merge() 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 270 dfork(p) 271 struct 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 298 rmut(p) 299 register 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 326 reset() 327 { 328 longjmp(sjbuf, 1); 329 } 330 331 332