jfh@rpp386.Dallas.TX.US (John F. Haugh II) (03/22/89)
This is the beta test release of the init I've been munging on. It is currently being used on this site with some results. It is not complete and does not contain a telinit. You have to send it various signals to get things to happen ... So far it seems to work. Caveats - - no telinit yet - still flaky as a pie crust - only tested on Xenix/386 2.2.1 - syscon and systty aren't implemented yet Debugging an init is EXTREMELY troublesome. If you are unable to reboot frequently and from a floppy, I would not suggest getting involved just yet. This init is easier to debug in a production setting than the real McCoy as this version can be restarted without rebooting the system. Nice trick. How to use this beasty - Create your /etc/inittab just like normal. You need to have some experience with inittabs. Here is mine as a starter: -- id:S:initdefault: rc:Ss2:wait:/etc/rc < /dev/console > /dev/console 2>&1 co:Ss:wait:/bin/su - root < /dev/console > /dev/console 2>&1 01:2:respawn:/etc/getty tty01 m # Screen 1 02:2:respawn:/etc/getty tty02 m # Screen 2 03:2:respawn:/etc/getty tty03 m # Screen 3 d1:2:respawn:/etc/getty tty1A v # Anchor Automation Modem d2:2:respawn:/etc/getty tty2A v # Everex Modem -- Create a new /etc/rc file. The old one is probably kinda useless if you are running SCO Xenix. It doesn't know about being called in single user mode. Save your old init someplace handy and make and install this version. Reboot. You will now be in single user mode. To change run levels, signal init with SIGUSR1 [ signal 16 ] and you will be prompted on the console for a new run level. Enter the new runlevel at the prompt. To restart init, signal init with SIGUSR2 [ signal 17 ] and init will kill all active processes and re-exec itself. This is very useful for replacing init without rebooting. To re-read the inittab, send init a signal 1, 2, or 3. You might want to read the config.h file. There are only a few options at this stage of the game. If you aren't completely frightened, or REALLY DESPARATELY need a real init, complete with source code, unwrap this sucker and get on with the show ... WARNING - SCREWING WITH INIT CAN GET YOUR MACHINE REAL UNUSABLE REAL FAST. ALWAYS ALWAYS ALWAYS make plenty of backups and sacrifice virgins to the computer gods before screwing with this. Don't say I didn't warn you. THIS POSTING COPYRIGHT, 1989, JOHN F. HAUGH II ALL RIGHTS RESERVED. Use and redistribution in a USENET-like manner permitted, all other uses prohibited. -- #! /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 -- John F. Haugh II +-Quote of the Week:------------------- VoiceNet: (214) 250-3311 Data: -6272 | "Do not drink and bake" InterNet: jfh@rpp386.Dallas.TX.US | -- Arnold Swartzenegger UucpNet : <backbone>!killer!rpp386!jfh +--------------------------------------
jfh@rpp386.Dallas.TX.US (John F. Haugh II) (03/23/89)
In article <13858@rpp386.Dallas.TX.US> jfh@rpp386.Dallas.TX.US (John F. Haugh II) writes: >This is the beta test release of the init I've been munging on. >It is currently being used on this site with some results. It >is not complete and does not contain a telinit. You have to >send it various signals to get things to happen ... That paragraph should have been a clue. Judging from the mail I've received, some people don't associate `not done yet' with `isn't from AT&T'. This code IS NOT derived from AT&T source code. I DO NOT have a source code license and have not used AT&T code to write this. It is 100 PERCENT free of licensing hassles. On the other hand, the init being distributed by Sandy Zelkovitz IS derived from AT&T source code and is being distributed in binary form ONLY. If you need more info, you may contact him at sandy@alphacm.UUCP. DO NOT confuse my init with the init Sandy is handing out. PLEASE. I don't need any more AT&T hate mail. I had my share of that last year with that damned yacc ... -- John F. Haugh II +-Quote of the Week:------------------- VoiceNet: (214) 250-3311 Data: -6272 | "Do not drink and bake" InterNet: jfh@rpp386.Dallas.TX.US | -- Arnold Swartzenegger UucpNet : <backbone>!killer!rpp386!jfh +--------------------------------------