V5/usr/source/s1/init.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);
}
}