#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	Makefile
#	error.c
#	getlevel.c
#	main.c
#	process.c
#	startup.c
#	inittab.c
#	spawn.c
#	config.h
#	inittab.h
#	patchlevel.h
# This archive created: Wed Mar 22 08:07:05 1989
# By:	John F. Haugh II (River Parishes Programming, Dallas TX)
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
#
#	%Z%Init - System V compatible init
#
#	%W%	%U%	%G%
#
SHELL = /bin/sh

CFLAGS = -O -M3 -g

SRCS = error.c getlevel.c main.c process.c startup.c inittab.c spawn.c

HDRS = config.h inittab.h patchlevel.h

OBJS = error.o getlevel.o main.o process.o startup.o inittab.o spawn.o

FILES = Makefile $(SRCS) $(HDRS)

init: $(OBJS)
	cc -o init -g $(OBJS)

error.o: config.h

getlevel.o: inittab.h config.h

inittab.o: inittab.h config.h

main.o: inittab.h config.h

process.o: inittab.h config.h

spawn.o: inittab.h

startup.o: inittab.h config.h

shar:	$(FILES)
	shar $(FILES) > init.shar

clean:
	rm -f *.o core

clobber: clean
	rm -f init
SHAR_EOF
fi
if test -f 'error.c'
then
	echo shar: "will not over-write existing file 'error.c'"
else
cat << \SHAR_EOF > 'error.c'
#include <fcntl.h>
#include <stdio.h>
#include "config.h"

#ifndef	lint
static	char	_sccsid[] = "@(#)error.c	1.1	07:58:04	3/22/89";
#endif

extern	int	proc1;
extern	int	consolefd;

error (s)
char	*s;
{
	char	buf[BUFSIZ];
	
	sprintf (buf, "ERROR: %s\r\n", s);
#ifdef	DEBUG
	fputs (buf, stderr);
#else
	if (proc1) {
		if (fork () == 0) {
			proc1 = 0;
			consolefd = open (CONSOLE, O_RDWR|O_NDELAY);
			write (consolefd, buf, strlen (buf));
			_exit (0);
		}
	} else {
		write (consolefd, buf, strlen (buf));
		_exit (0);
	}
#endif
}

msg (s)
char	*s;
{
	char	buf[BUFSIZ];
	
	sprintf (buf, "%s\r\n", s);
#ifdef	DEBUG
	fputs (buf, stderr);
#else
	if (proc1) {
		if (fork () == 0) {
			proc1 = 0;
			consolefd = open (CONSOLE, O_RDWR|O_NDELAY);
			write (consolefd, buf, strlen (buf));
			_exit (0);
		}
	} else {
		write (consolefd, buf, strlen (buf));
		_exit (0);
	}
#endif
}
SHAR_EOF
fi
if test -f 'getlevel.c'
then
	echo shar: "will not over-write existing file 'getlevel.c'"
else
cat << \SHAR_EOF > 'getlevel.c'
#include <stdio.h>
#include <fcntl.h>
#include <termio.h>
#include <signal.h>
#include "inittab.h"
#include "config.h"

#ifndef	lint
static	char	_sccsid[] = "@(#)getlevel.c	1.1	07:58:04	3/22/89";
#endif

extern	int	proc1;
extern	int	consolefd;
extern	int	nproc;
extern	struct	inittab	*proc;

/*
 * getlevel - return new run level
 */

int	getlevel ()
{
	char	buf[16];
	int	fd;
	int	status;
	int	pid;
	int	child;
	int	i;
	struct	termio	termio;

	for (i = 0;i < nproc;i++) {
		if (proc[i].ini_pid > 1) {
			kill (- proc[i].ini_pid, SIGKILL);
			waitfor (&proc[i]);
		}
	}
	kill (0, SIGKILL);
	switch (child = fork ()) {
		default:	/* still proc1 ... */
			while ((pid = wait (&status)) != child
					&& pid != -1)
				;
			if ((status & 0377) != 0) {
				error ("Can't get run-level, using S");
				return ('S');
			}
			break;
		case -1:	/* couldn't fork */
			error ("Can't get run-level, using S");
			return ('S');
		case 0:		/* child process */
			proc1 = 0;
			if ((fd = open (CONSOLE, O_RDWR|O_NDELAY)) < 0)
				_exit (0); /* assume 'S' ... */

#ifndef	DEBUG
			ioctl (fd, TCGETA, &termio);
			termio.c_iflag = (ISTRIP|ICRNL|IXON);
			termio.c_oflag = (OPOST|ONLCR);
			termio.c_cflag &= CBAUD;
			termio.c_cflag |= (CREAD|HUPCL);
			termio.c_lflag = (ISIG|ICANON|ECHO|ECHOE|ECHOK);
			ioctl (fd, TCSETA, &termio);
#endif
			fcntl (fd, F_SETFL,
				fcntl (fd, F_GETFL, 0) & ~O_NDELAY);
			consolefd = fd;
			do {
				write (fd, "Enter run-level [Ss0123456]: ", 29);
				i = read (fd, buf, sizeof buf);
				if (i >= 0)
					buf[i] = '\0';
			} while (! (buf[0] == 's' || buf[0] == 'S'
				|| (buf[0] >= '0' && buf[0] <= '6')));

			if (buf[0] == 'S' || buf[0] == '0')
				_exit (0);
			else if (buf[0] == 's')
				_exit (1);
			else
				_exit (buf[0] - '0' + 1);
	}
	status = (status >> 8) & 07;
	return ("Ss123456"[status]);
}
SHAR_EOF
fi
if test -f 'main.c'
then
	echo shar: "will not over-write existing file 'main.c'"
else
cat << \SHAR_EOF > 'main.c'
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <utmp.h>
#include <string.h>
#include "config.h"
#include "inittab.h"

#ifndef lint
static	char	_sccsid[] = "@(#)main.c	1.1	07:58:07	3/22/89";
#endif

char	intrflag;
int	proc1;
int	runlevel;
int	prevlevel;
int	runcnt[8];
int	consolefd;
int	wtmpfd;
int	nproc;

struct	inittab	*proc;

reinit ()
{
	int	i;

	msg ("Reloading INIT");
#ifndef	DEBUG
	kill (-1, SIGKILL);
#endif
#ifdef	DEBUG
	execl ("./init", "init", "proc1", (char *) 0);
#else
	execl ("/etc/init", "/etc/init", (char *) 0);
#endif
}

main (argc, argv)
int	argc;
char	**argv;
{
	int	newlevel;
	char	buf[BUFSIZ];

#ifdef	DEBUG
	if (proc1 = (argc > 1 && strcmp (argv[1], "proc1") == 0)) {
		argv[1] = argv[0];
		argc--;
		argv++;
	}
#else
 	proc1 = getpid () == 1;
#endif
	if (proc1)
		startup ();

	while (1) {
		process (runlevel);

		newlevel = getlevel ();

		if (newlevel != runlevel)
			sprintf (buf, "INIT: New run-level: %c", newlevel);
		else
			sprintf (buf, "INIT: Run-level: %c", newlevel);

		msg (buf);
		runlevel = newlevel;
	}
}
SHAR_EOF
fi
if test -f 'process.c'
then
	echo shar: "will not over-write existing file 'process.c'"
else
cat << \SHAR_EOF > 'process.c'
#include <signal.h>
#include <sys/types.h>
#include <utmp.h>
#include <fcntl.h>
#include "config.h"
#include "inittab.h"

#ifndef	lint
static	char	_sccsid[] = "@(#)process.c	1.1	07:58:08	3/22/89";
#endif

extern	char	intrflag;
extern	int	nproc;
extern	int	prevlevel;
extern	int	runlevel;
extern	int	runcnt[];
extern	int	wtmpfd;
extern	struct	inittab	*proc;

/* 
 * process - perform entries specified in inittab
 *
 *	perform respawn, wait, and once commands.
 */

process ()
{
	int	i;
	int	utmpfd;
	int	count;
	struct	inittab	*ip;
	struct	utmp	utmp;
	struct	utmp	utent;

	if (runlevel == 'S')
		i = runcnt[0]++;
	else if (runlevel == 's')
		i = runcnt[1]++;
	else
		i = runcnt[runlevel - '0' + 1]++;

#ifdef	DEBUG
	utmpfd = -1;
#else
	utmpfd = open ("/etc/utmp", O_RDWR|O_CREAT, 0644);
#endif
	memset ((char *) &utmp, 0, sizeof utmp);
	sprintf (utmp.ut_line, RUNLVL_MSG, runlevel);
	utmp.ut_type = RUN_LVL;
	utmp.ut_pid = i;
	utmp.ut_exit.e_termination = runlevel;
	utmp.ut_exit.e_exit = prevlevel;
	utmp.ut_time = time ((time_t *) 0);

	prevlevel = runlevel;
	intrflag = 0;

	if (utmpfd >= 0) {
		while (read (utmpfd, &utent, sizeof utent) == sizeof utent)
			if (utent.ut_type == RUN_LVL)
				break;

		if (utent.ut_type == RUN_LVL)
			lseek (utmpfd, (off_t) - sizeof utent, 1);

		write (utmpfd, &utmp, sizeof utmp);
		close (utmpfd);
		utmpfd = -1;
	}
	if (wtmpfd >= 0)
		write (wtmpfd, &utmp, sizeof utmp);
again:
	inittab (runlevel);
#ifdef	DEBUG
	prtab ();
#endif
	for (count = 0, ip = proc;ip != &proc[nproc];ip++) {
		if (ip->ini_pid && kill (ip->ini_pid, 0) != 0)
			waitfor (ip);

		if (! (ip->ini_pid && kill (ip->ini_pid, 0) == 0)) {
			switch (ip->ini_action) {
				case INIT_RESPAWN:
					spawn (ip);
					count++;
					break;
				case INIT_WAIT:
					if (intrflag == 0)
						spawn (ip);
					count++;
					break;
				case INIT_ONCE:
					if (ip->ini_count == 0)
						spawn (ip);
					count++;
					break;
			}
		}
	}
	intrflag = 0;
	if (count)
		waitfor ((struct inittab *) 0);

	if (intrflag && intrflag != SIGUSR1)
		goto again;
}
SHAR_EOF
fi
if test -f 'startup.c'
then
	echo shar: "will not over-write existing file 'startup.c'"
else
cat << \SHAR_EOF > 'startup.c'
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <utmp.h>
#include "config.h"
#include "inittab.h"

extern	void	reread ();
extern	void	reinit ();
extern	char	intrflag;
extern	int	runlevel;
extern	int	prevlevel;
extern	int	nproc;
extern	int	wtmpfd;
extern	struct	inittab	*proc;

#ifndef	lint
static	char	_sccsid[] = "@(#)startup.c	1.1	07:58:09	3/22/89";
#endif

/*
 * startup - set up the initial state
 */

void	startup ()
{
	int	i;
	int	fd;
	int	utmpfd;
	struct	utmp	utent;
	struct	utmp	utmp;

	wtmpfd = open ("/etc/wtmp", O_RDWR|O_APPEND|O_CREAT, 0644);
#ifdef	DEBUG
	utmpfd = -1;
#else
	utmpfd = open ("/etc/utmp", O_RDWR|O_CREAT|O_TRUNC, 0644);
#endif

	memset (utmp, sizeof utmp, 0);
	strcpy (utmp.ut_line, BOOT_MSG);
	utmp.ut_type = BOOT_TIME;
	utmp.ut_time = time ((time_t *) 0);

	if (utmpfd >= 0) {
		while (read (utmpfd, &utent, sizeof utent) == sizeof utent)
			if (utent.ut_type == BOOT_TIME)
				break;

		if (utent.ut_type == BOOT_TIME)
			lseek (utmpfd, (off_t) - sizeof utent, 1);

		write (utmpfd, &utmp, sizeof utmp);
	}
	if (wtmpfd >= 0)
		write (wtmpfd, &utmp, sizeof utmp);
#ifndef	DEBUG
	for (i = 1;i < NSIG;i++)
		signal (i, SIG_IGN);
#endif
	signal (SIGHUP, reread);
	signal (SIGINT, reread);
	signal (SIGQUIT, reread);
	signal (SIGUSR1, reread);
	signal (SIGUSR2, reinit);
	signal (SIGCLD, SIG_DFL);

	inittab (-1);
#ifdef	DEBUG
	printf ("INIT: BOOT\n");
	prtab ();
#endif
	/*
	 * certain entries must be executed first.  initdefault is
	 * the first one of them.  if there is no initdefault entry,
	 * we assume 'S' for the initial run level.
	 */

	for (i = 0;i < nproc && ! runlevel;i++) /* scan for initdefault */
		if (proc[i].ini_action == INIT_INITDEFAULT)
			runlevel = proc[i].ini_levels[0];

	if (! runlevel)
		runlevel = 'S';

	prevlevel = runlevel;
	memset (utmp, sizeof utmp, 0);
	sprintf (utmp.ut_line, RUNLVL_MSG, runlevel);
	utmp.ut_type = RUN_LVL;
	utmp.ut_pid = 0;
	utmp.ut_exit.e_termination = utmp.ut_exit.e_exit = runlevel;
	utmp.ut_time = time ((time_t *) 0);

	if (utmpfd >= 0) {
		while (read (utmpfd, &utent, sizeof utent) == sizeof utent)
			if (utent.ut_type == RUN_LVL)
				break;

		if (utent.ut_type == RUN_LVL)
			lseek (utmpfd, (off_t) - sizeof utent, 1);

		write (utmpfd, &utmp, sizeof utmp);
	}
	if (wtmpfd >= 0)
		write (wtmpfd, &utmp, sizeof utmp);

	/*
	 * next we must exec all `sysinit' commands ...
	 */

	for (i = 0;i < nproc;i++)	/* scan for sysinit */
		if (proc[i].ini_action == INIT_SYSINIT)
			spawn (&proc[i]);

	/*
	 * now we execute the `boot time only' commands ...
	 */

	for (i = 0;i < nproc;i++)
		if (proc[i].ini_action == INIT_BOOT
				|| proc[i].ini_action == INIT_BOOTWAIT)
			spawn (&proc[i]);

	close (utmpfd);
}
SHAR_EOF
fi
if test -f 'inittab.c'
then
	echo shar: "will not over-write existing file 'inittab.c'"
else
cat << \SHAR_EOF > 'inittab.c'
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include "inittab.h"
#include "config.h"

#ifndef	lint
static	char	_sccsid[] = "@(#)inittab.c	1.1	07:58:06	3/22/89";
#endif

char	*actions[] = {
	"respawn",
	"wait",
	"once",
	"boot",
	"bootwait",
	"powerfail",
	"powerwait",
	"off",
	"ondemand",
	"initdefault",
	"sysinit"
};

struct	inittab	initdefault = {
	"default",
	"Ss123456",
	INIT_ONCE,
	"/etc/sulogin",
	0
};

extern	struct	inittab	*proc;
extern	int	nproc;
extern	char	intrflag;
extern	char	*malloc ();
extern	char	*realloc ();

struct	inittab	*getinit (fp, entry)
FILE	*fp;
struct	inittab	*entry;
{
	char	*cp;
	char	buf[BUFSIZ];
	char	id[16];
	char	levels[16];
	char	actions[16];
	char	command[BUFSIZ];

	while (fgets (buf, BUFSIZ, fp) != (char *) 0) {
		if (buf[0] == '#')
			continue;

		if (cp = strtok (buf, ":"))
			strcpy (id, cp);
		else
			continue;

		if (cp = strtok ((char *) 0, ":"))
			strcpy (levels, cp);
		else
			continue;

		if (cp = strtok ((char *) 0, ":"))
			strcpy (actions, cp);
		else
			continue;

		if (cp = strtok ((char *) 0, ":"))
			strcpy (command, cp);
		else
			continue;

		if (cp = strchr (command, '\n'))
			*cp = '\0';

		if (strcmp (actions, "respawn") == 0)
			entry->ini_action = INIT_RESPAWN;
		else if (strcmp (actions, "wait") == 0)
			entry->ini_action = INIT_WAIT;
		else if (strcmp (actions, "once") == 0)
			entry->ini_action = INIT_ONCE;
		else if (strcmp (actions, "boot") == 0)
			entry->ini_action = INIT_BOOT;
		else if (strcmp (actions, "bootwait") == 0)
			entry->ini_action = INIT_BOOTWAIT;
		else if (strcmp (actions, "off") == 0)
			entry->ini_action = INIT_OFF;
		else if (strcmp (actions, "ondemand") == 0)
			entry->ini_action = INIT_ONDEMAND;
		else if (strcmp (actions, "initdefault") == 0)
			entry->ini_action = INIT_INITDEFAULT;
		else if (strcmp (actions, "sysinit") == 0)
			entry->ini_action = INIT_SYSINIT;
		else
			continue;

		entry->ini_id = strdup (id);
		entry->ini_levels = strdup (levels);
		entry->ini_command = strdup (command);

		return (entry);
	}
	return ((struct inittab *) 0);
}

freeinit (entry)
struct	inittab	*entry;
{
	free (entry->ini_id);
	free (entry->ini_levels);
	free (entry->ini_command);
}

struct	inittab	*findinit (id, table, entries)
char	*id;
struct	inittab	*table;
int	entries;
{
	while (--entries >= 0) {
		if (strcmp (id, table->ini_id) == 0)
			return (table);
		else
			table++;
	}
	return ((struct inittab *) 0);
}

/*
 * inittab - read the inittab
 */

inittab (runlevel)
int	runlevel;
{
	FILE	*fp;
	int	i, j;
	struct	inittab	it;
	struct	inittab	*ip;
	struct	inittab	*newproc;
	int	newprocs;
	int	kills;

	if ((fp = fopen (INITTAB, "r")) == (FILE *) 0) {
		nproc = 1;
		proc = (struct inittab *) malloc (sizeof it);
		proc[0] = initdefault;
		return;
	}
	newprocs = 0;

	if (runlevel != -1) {
		for (kills = i = 0;i < nproc;i++) {
			if (proc[i].ini_pid == 0)
				continue;

			if (strchr (proc[i].ini_levels, runlevel))
				continue;

			kill (proc[i].ini_pid, SIGTERM);
			kills++;
		}
		if (kills)
			sleep (10);

		for (i = 0;i < nproc;i++) {
			if (proc[i].ini_pid == 0)
				continue;

			if (strchr (proc[i].ini_levels, runlevel))
				continue;

			kill (proc[i].ini_pid, SIGKILL);
			waitfor (&proc[i]);
		}
	}
	while (getinit (fp, &it)) {
		if (runlevel != -1
			&& (it.ini_action == INIT_BOOT
				|| it.ini_action == INIT_BOOTWAIT
				|| it.ini_action == INIT_INITDEFAULT
				|| it.ini_action == INIT_SYSINIT
				|| ! strchr (it.ini_levels, runlevel))) {
			freeinit (&it);
			continue;
		}
		if (newprocs == 0)
			newproc = (struct inittab *) malloc (sizeof it);
		else
			newproc = (struct inittab *) realloc (newproc, sizeof it * (newprocs + 1));

		newproc[newprocs++] = it;
	}
	fclose (fp);

	for (kills = i = 0;i < newprocs;i++) {
		if (ip = findinit (newproc[i].ini_id, proc, nproc)) {
			newproc[i].ini_pid = ip->ini_pid;
			newproc[i].ini_count = ip->ini_count;
			newproc[i].ini_status = ip->ini_status;
			if (newproc[i].ini_action == ip->ini_action
				&& strcmp (newproc[i].ini_levels, ip->ini_levels) == 0
				&& strcmp (newproc[i].ini_command, ip->ini_command) == 0)
				continue;
		} else {
			newproc[i].ini_pid = 0;
			newproc[i].ini_count = 0;
			newproc[i].ini_status = 0;
		}
		if (newproc[i].ini_pid == 0)
			continue;

		if (newproc[i].ini_action == INIT_OFF) {
			kill (newproc[i].ini_pid, SIGTERM);
			kills++;
		}
	}
	if (kills)
		sleep (10);

	for (i = 0;i < newprocs;i++) {
		if (ip = findinit (newproc[i].ini_id, proc, nproc)) {
			if (newproc[i].ini_action == ip->ini_action
				&& strcmp (newproc[i].ini_levels, ip->ini_levels) == 0
				&& strcmp (newproc[i].ini_command, ip->ini_command) == 0)
				continue;
		}
		if (newproc[i].ini_pid == 0)
			continue;

		if (newproc[i].ini_action == INIT_OFF) {
			kill (newproc[i].ini_pid, SIGKILL);
			waitfor (&newproc[i]);
		}
	}
	for (i = 0;i < nproc;i++)
		freeinit (&proc[i]);

	proc = newproc;
	nproc = newprocs;
}

void	reread (sig)
int	sig;
{
	char	buf[BUFSIZ];

	signal (sig, reread);
	intrflag = sig;
}

prtab ()
{
	int	i;
	char	buf[BUFSIZ];

	for (i = 0;i < nproc;i++) {
		sprintf (buf, "%s:%s:%s:%s",
			proc[i].ini_id, proc[i].ini_levels,
			actions[proc[i].ini_action], proc[i].ini_command);
		msg (buf);
	}
}
SHAR_EOF
fi
if test -f 'spawn.c'
then
	echo shar: "will not over-write existing file 'spawn.c'"
else
cat << \SHAR_EOF > 'spawn.c'
#include <stdio.h>
#include <sys/types.h>
#include <utmp.h>
#include <signal.h>
#include "inittab.h"

#ifndef	lint
static	char	_sccsid[] = "@(#)spawn.c	1.1	07:58:09	3/22/89";
#endif

extern	int	proc1;
extern	int	errno;
extern	int	nproc;
extern	int	wtmpfd;
extern	struct	inittab	*proc;

struct	utmp	*getutent ();
extern	void	waitfor ();
time_t	time ();

/*
 * spawn - execute an entry
 */

spawn (entry)
struct	inittab	*entry;
{
	int	mustwait = 0;
	int	child;
	int	type;
	int	fd;
	int	sig;
	char	buf[BUFSIZ];

	mustwait = (entry->ini_action == INIT_WAIT ||
			entry->ini_action == INIT_BOOTWAIT ||
			entry->ini_action == INIT_SYSINIT);

	switch (child = fork ()) {
		case 0:
			proc1 = 0;
			strcat (strcpy (buf, "exec "), entry->ini_command);
			for (fd = 0;fd < _NFILE;fd++)
				close (fd);
			setpgrp ();

			if (execl ("/bin/sh", "sh", "-c", buf, (char *) 0)) {
				sprintf (buf, "INIT: Can't exec %s", buf);
				error (buf);
				_exit (errno);
			}
			break;
		case -1:
			return;
		default:
			entry->ini_count++;
			entry->ini_pid = child;
			birth (entry);

			if (mustwait)
				waitfor (entry);

			break;
	}
}

void	waitfor (entry)
struct	inittab	*entry;
{
	struct	inittab	*ip;
	int	pid;
	int	status;
	int	i;
	int	children;

	if (entry && entry->ini_pid == 0)
		return;

	if (! entry) {		/* count the children to wait for */
		for (children = 0, ip = proc;ip != &proc[nproc];ip++)
			if (ip->ini_pid)
				children++;
	} else {		/* only have one to worry about */
		children = 1;
	}
	while (children && (pid = wait (&status)) != -1) {
		if (entry && pid == entry->ini_pid) {
			entry->ini_status = status;
			bury (entry);
			entry->ini_pid = 0;
			return;
		}

		/*
		 * find process in table and lay to rest.  may require
		 * being restarted if action is respawn.  entries not
		 * in the table are silently buried.
		 */

		for (ip = proc;ip != &proc[nproc];ip++) {
			if (ip->ini_pid != pid)
				continue;

			ip->ini_status = status;
			bury (ip);
			children--;
			ip->ini_pid = 0;
			if (ip->ini_action == INIT_RESPAWN) {
				spawn (ip);
				children++;
			}
			break;
		}
	}
}

bury (entry)
struct	inittab	*entry;
{
	struct	utmp	*utmp;

	setutent ();

	while (utmp = getutent ()) {
		if (strcmp (utmp->ut_id, entry->ini_id) == 0)
			break;
	}
	if (utmp) {
		utmp->ut_pid = entry->ini_pid;
		utmp->ut_type = DEAD_PROCESS;
		utmp->ut_exit.e_termination = entry->ini_status & 0377;
		utmp->ut_exit.e_exit = (entry->ini_status >> 8) & 0377;
		pututline (utmp);
		write (wtmpfd, (char *) utmp, sizeof *utmp);
	}
	endutent ();
}

birth (entry)
struct	inittab	*entry;
{
	struct	utmp	*utmp;
	struct	utmp	new;

	setutent ();

	while (utmp = getutent ()) {
		if (strcmp (utmp->ut_id, entry->ini_id) == 0)
			break;
	}
	if (! utmp) {
		utmp = &new;
		memset ((char *) utmp, 0, sizeof *utmp);
	}
	strncpy (utmp->ut_id, entry->ini_id, sizeof (utmp->ut_id));
	if (entry->ini_action == INIT_RESPAWN)
		strcpy (utmp->ut_user, "GETTY");
	else
		memset (utmp->ut_user, '\0', sizeof utmp->ut_user);
	utmp->ut_pid = entry->ini_pid;
	utmp->ut_type = INIT_PROCESS;
	utmp->ut_exit.e_termination = 0;
	utmp->ut_exit.e_exit = 0;
	utmp->ut_time = time ((time_t *) 0);

	pututline (utmp);
	write (wtmpfd, (char *) utmp, sizeof *utmp);

	endutent ();
}
SHAR_EOF
fi
if test -f 'config.h'
then
	echo shar: "will not over-write existing file 'config.h'"
else
cat << \SHAR_EOF > 'config.h'
/*
 * config.h - init configuration file
 *
 *	@(#)config.h	1.1	07:58:03	3/22/89
 */

#ifndef	DEBUG
#define	CONSOLE	"/dev/console"
#define	NPROC	100
#define	INITTAB	"/etc/inittab"
#else
#define	CONSOLE	"/dev/tty"
#define	NPROC	20
#define	INITTAB	"inittab"
#endif
SHAR_EOF
fi
if test -f 'inittab.h'
then
	echo shar: "will not over-write existing file 'inittab.h'"
else
cat << \SHAR_EOF > 'inittab.h'
#include <stdio.h>
#include "config.h"

/*
 * inittab - structure of the inittab file
 *
 *	@(#)inittab.h	1.1	07:58:06	3/22/89
 */

struct	inittab	{
	char	*ini_id;
	char	*ini_levels;
	int	ini_action;
	char	*ini_command;
	long	ini_count;
	int	ini_pid;
	int	ini_status;
};

#define	INIT_RESPAWN	0
#define	INIT_WAIT	1
#define	INIT_ONCE	2
#define	INIT_BOOT	3
#define	INIT_BOOTWAIT	4
#define	INIT_POWERFAIL	5
#define	INIT_POWERWAIT	6
#define	INIT_OFF	7
#define	INIT_ONDEMAND	8
#define	INIT_INITDEFAULT 9
#define	INIT_SYSINIT	10
SHAR_EOF
fi
if test -f 'patchlevel.h'
then
	echo shar: "will not over-write existing file 'patchlevel.h'"
else
cat << \SHAR_EOF > 'patchlevel.h'
/*
 * patchlevel.h - current patch level
 *
 *	@(#)patchlevel.h	1.1	07:58:07	3/22/89
 */

#define	PATCHLEVEL	1
SHAR_EOF
fi
exit 0
#	End of shell archive