220 lines
3.0 KiB
C
220 lines
3.0 KiB
C
#define tabsize 20
|
|
#define all p = &itab[0]; p < &itab[20]; p++
|
|
#define ever ;;
|
|
#define single 0173030
|
|
#define reboot 0173040
|
|
char shell[] "/bin/sh";
|
|
char minus[] "-";
|
|
char runc[] "/etc/rc";
|
|
char init[] "/etc/init";
|
|
char ifile[] "/etc/ttys";
|
|
char utmp[] "/etc/utmp";
|
|
char wtmpf[] "/usr/adm/wtmp";
|
|
char ctty[] "/dev/tty8";
|
|
int fi;
|
|
struct
|
|
{
|
|
int flag;
|
|
int line;
|
|
char coms[2];
|
|
} line;
|
|
struct tab
|
|
{
|
|
int pid;
|
|
int line;
|
|
int comn;
|
|
} itab[tabsize];
|
|
|
|
struct {
|
|
char name[8];
|
|
char tty;
|
|
char fill;
|
|
int time[2];
|
|
int wfill;
|
|
} wtmp;
|
|
|
|
main()
|
|
{
|
|
register i;
|
|
register struct tab *p, *q;
|
|
int reset();
|
|
|
|
/*
|
|
* if not single user,
|
|
* run shell sequence
|
|
*/
|
|
|
|
if(getcsw() != single) {
|
|
i = fork();
|
|
if(i == 0) {
|
|
open("/", 0);
|
|
dup(0);
|
|
dup(0);
|
|
execl(shell, shell, runc, 0);
|
|
exit();
|
|
}
|
|
while(wait() != i);
|
|
close(creat(utmp, 0644));
|
|
if ((i = open(wtmpf, 1)) >= 0) {
|
|
seek(i, 0, 2);
|
|
wtmp.tty = '~';
|
|
time(wtmp.time);
|
|
write(i, &wtmp, 16);
|
|
close(i);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* main loop for hangup signal
|
|
* close all files and
|
|
* check switches for magic values
|
|
*/
|
|
|
|
setexit();
|
|
signal(1, reset);
|
|
for(i=0; i<10; i++)
|
|
close(i);
|
|
switch(getcsw()) {
|
|
|
|
case single:
|
|
error:
|
|
termall();
|
|
i = fork();
|
|
if(i == 0) {
|
|
open(ctty, 2);
|
|
dup(0);
|
|
execl(shell, minus, 0);
|
|
exit();
|
|
}
|
|
while(wait() != i);
|
|
|
|
case reboot:
|
|
termall();
|
|
execl(init, minus, 0);
|
|
reset();
|
|
}
|
|
|
|
/*
|
|
* open and merge in init file
|
|
*/
|
|
|
|
fi = open(ifile, 0);
|
|
q = &itab[0];
|
|
while(rline()) {
|
|
if(line.flag == '0')
|
|
continue;
|
|
for(all)
|
|
if(p->line==line.line || p->line==0) {
|
|
if(p >= q) {
|
|
i = p->pid;
|
|
p->pid = q->pid;
|
|
q->pid = i;
|
|
p->line = q->line;
|
|
p->comn = q->comn;
|
|
q->line = line.line;
|
|
q->coms[0] = line.comn;
|
|
q++;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
close(fi);
|
|
if(q == &itab[0])
|
|
goto error;
|
|
for(; q < &itab[tabsize]; q++)
|
|
term(q);
|
|
for(all)
|
|
if(p->line != 0 && p->pid == 0)
|
|
dfork(p);
|
|
for(ever) {
|
|
i = wait();
|
|
for(all)
|
|
if(p->pid == i) {
|
|
rmut(p);
|
|
dfork(p);
|
|
}
|
|
}
|
|
}
|
|
|
|
termall()
|
|
{
|
|
register struct tab *p;
|
|
|
|
for(all)
|
|
term(p);
|
|
}
|
|
|
|
term(ap)
|
|
struct tab *ap;
|
|
{
|
|
register struct tab *p;
|
|
|
|
p = ap;
|
|
if(p->pid != 0) {
|
|
rmut(p);
|
|
kill(p->pid, 9);
|
|
}
|
|
p->pid = 0;
|
|
p->line = 0;
|
|
}
|
|
|
|
rline()
|
|
{
|
|
static char c[4];
|
|
|
|
if(read(fi, c, 4) != 4 || c[3] != '\n')
|
|
return(0);
|
|
line.flag = c[0];
|
|
line.line = c[1];
|
|
line.comn = c[2];
|
|
return(1);
|
|
}
|
|
|
|
dfork(ap)
|
|
struct tab *ap;
|
|
{
|
|
register i;
|
|
register char *tty;
|
|
register struct tab *p;
|
|
|
|
p = ap;
|
|
i = fork();
|
|
if(i == 0) {
|
|
signal(1, 0);
|
|
tty = "/dev/ttyx";
|
|
tty[8] = p->line;
|
|
chown(tty, 0);
|
|
chmod(tty, 0622);
|
|
open(tty, 2);
|
|
dup(0);
|
|
execl("etc/getty", minus, p->coms, 0);
|
|
exit();
|
|
}
|
|
p->pid = i;
|
|
}
|
|
|
|
rmut(p)
|
|
struct tab *p;
|
|
{
|
|
register i, f;
|
|
static char zero[16];
|
|
|
|
f = open(utmp, 1);
|
|
if(f >= 0) {
|
|
i = p->line;
|
|
if(i >= 'a')
|
|
i =+ '0' + 10 - 'a';
|
|
seek(f, (i-'0')*16, 0);
|
|
write(f, zero, 16);
|
|
close(f);
|
|
}
|
|
f = open(wtmpf, 1);
|
|
if (f >= 0) {
|
|
wtmp.tty = p->line;
|
|
time(wtmp.time);
|
|
seek(f, 0, 2);
|
|
write(f, &wtmp, 16);
|
|
close(f);
|
|
}
|
|
}
|