Init Clone: patch #1
John F. Haugh II
jfh at rpp386.Dallas.TX.US
Mon Mar 27 14:59:33 AEST 1989
This patch corrects a number of minor problems with init and
adds rudimentary support for a telinit. If you were concerned
about how reliable this init is, I have been using this
particular version for about a week with nice results.
If someone is playing with this on a 16 bit [ 286 or so ]
machine, I would appreciate hearing about it.
There is less debugging left to be done, so if you are less
frightened, feel free to toss that boring old init of yours
and start using this wonderful, exciting, flakey version you
now have the source code for ...
- John.
--
*** orig/getlevel.c
--- getlevel.c
**************
*** 1,3
#include <stdio.h>
#include <fcntl.h>
#include <termio.h>
--- 1,4 -----
+ #include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <termio.h>
**************
*** 2,7
#include <fcntl.h>
#include <termio.h>
#include <signal.h>
#include "inittab.h"
#include "config.h"
--- 3,9 -----
#include <fcntl.h>
#include <termio.h>
#include <signal.h>
+ #include <utmp.h>
#include "inittab.h"
#include "config.h"
**************
*** 6,12
#include "config.h"
#ifndef lint
! static char _sccsid[] = "@(#)getlevel.c 1.1 07:58:04 3/22/89";
#endif
extern int proc1;
--- 8,14 -----
#include "config.h"
#ifndef lint
! static char _sccsid[] = "@(#)getlevel.c 1.2 22:36:38 3/26/89";
#endif
extern int proc1;
**************
*** 13,18
extern int consolefd;
extern int nproc;
extern struct inittab *proc;
/*
* getlevel - return new run level
--- 15,22 -----
extern int consolefd;
extern int nproc;
extern struct inittab *proc;
+ extern struct utmp runlvl;
+ extern struct utmp *getutid ();
/*
* getlevel - return new run level
**************
*** 21,27
int getlevel ()
{
char buf[16];
- int fd;
int status;
int pid;
int child;
--- 25,30 -----
int getlevel ()
{
char buf[16];
int status;
int pid;
int child;
**************
*** 27,32
int child;
int i;
struct termio termio;
for (i = 0;i < nproc;i++) {
if (proc[i].ini_pid > 1) {
--- 30,37 -----
int child;
int i;
struct termio termio;
+ struct utmp utent;
+ struct utmp *up;
for (i = 0;i < nproc;i++) {
if (proc[i].ini_pid > 1) {
**************
*** 35,40
}
}
kill (0, SIGKILL);
switch (child = fork ()) {
default: /* still proc1 ... */
while ((pid = wait (&status)) != child
--- 40,55 -----
}
}
kill (0, SIGKILL);
+
+ utent.ut_type = RUN_LVL;
+ setutent ();
+ if (up = getutid (&utent))
+ utent = *up;
+ endutent ();
+
+ if (up && runlvl.ut_time > 0 && utent.ut_time > runlvl.ut_time)
+ return (utent.ut_exit.e_termination);
+
switch (child = fork ()) {
default: /* still proc1 ... */
while ((pid = wait (&status)) != child
**************
*** 46,52
}
break;
case -1: /* couldn't fork */
- error ("Can't get run-level, using S");
return ('S');
case 0: /* child process */
proc1 = 0;
--- 61,66 -----
}
break;
case -1: /* couldn't fork */
return ('S');
case 0: /* child process */
proc1 = 0;
**************
*** 50,56
return ('S');
case 0: /* child process */
proc1 = 0;
! if ((fd = open (CONSOLE, O_RDWR|O_NDELAY)) < 0)
_exit (0); /* assume 'S' ... */
#ifndef DEBUG
--- 64,70 -----
return ('S');
case 0: /* child process */
proc1 = 0;
! if ((consolefd = open (CONSOLE, O_RDWR|O_NDELAY)) < 0)
_exit (0); /* assume 'S' ... */
#ifndef DEBUG
**************
*** 54,60
_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;
--- 68,74 -----
_exit (0); /* assume 'S' ... */
#ifndef DEBUG
! ioctl (consolefd, TCGETA, &termio);
termio.c_iflag = (ISTRIP|ICRNL|IXON);
termio.c_oflag = (OPOST|ONLCR);
termio.c_cflag &= CBAUD;
**************
*** 60,66
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);
--- 74,80 -----
termio.c_cflag &= CBAUD;
termio.c_cflag |= (CREAD|HUPCL);
termio.c_lflag = (ISIG|ICANON|ECHO|ECHOE|ECHOK);
! ioctl (consolefd, TCSETA, &termio);
#endif
fcntl (consolefd, F_SETFL,
fcntl (consolefd, F_GETFL, 0) & ~O_NDELAY);
**************
*** 62,70
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);
--- 76,83 -----
termio.c_lflag = (ISIG|ICANON|ECHO|ECHOE|ECHOK);
ioctl (consolefd, TCSETA, &termio);
#endif
! fcntl (consolefd, F_SETFL,
! fcntl (consolefd, F_GETFL, 0) & ~O_NDELAY);
do {
write (consolefd,
"Enter run-level [Ss0123456]: ", 29);
**************
*** 66,73
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'
--- 79,87 -----
fcntl (consolefd, F_SETFL,
fcntl (consolefd, F_GETFL, 0) & ~O_NDELAY);
do {
! write (consolefd,
! "Enter run-level [Ss0123456]: ", 29);
! i = read (consolefd, buf, sizeof buf);
if (i >= 0)
buf[i] = '\0';
} while (! (buf[0] == 's' || buf[0] == 'S'
*** orig/main.c
--- main.c
**************
*** 8,14
#include "inittab.h"
#ifndef lint
! static char _sccsid[] = "@(#)main.c 1.1 07:58:07 3/22/89";
#endif
char intrflag;
--- 8,14 -----
#include "inittab.h"
#ifndef lint
! static char _sccsid[] = "@(#)main.c 1.2 22:36:41 3/26/89";
#endif
char intrflag;
**************
*** 21,26
int nproc;
struct inittab *proc;
reinit ()
{
--- 21,27 -----
int nproc;
struct inittab *proc;
+ struct utmp runlvl;
void reinit ()
{
**************
*** 22,28
struct inittab *proc;
! reinit ()
{
int i;
--- 23,29 -----
struct inittab *proc;
struct utmp runlvl;
! void reinit ()
{
int i;
**************
*** 30,35
#ifndef DEBUG
kill (-1, SIGKILL);
#endif
#ifdef DEBUG
execl ("./init", "init", "proc1", (char *) 0);
#else
--- 31,38 -----
#ifndef DEBUG
kill (-1, SIGKILL);
#endif
+ for (i = 0;i < _NFILE;i++)
+ close (i);
#ifdef DEBUG
execl ("./init", "init", "proc1", (char *) 0);
#else
*** orig/process.c
--- process.c
**************
*** 6,12
#include "inittab.h"
#ifndef lint
! static char _sccsid[] = "@(#)process.c 1.1 07:58:08 3/22/89";
#endif
extern char intrflag;
--- 6,12 -----
#include "inittab.h"
#ifndef lint
! static char _sccsid[] = "@(#)process.c 1.2 22:36:42 3/26/89";
#endif
extern char intrflag;
**************
*** 16,21
extern int runcnt[];
extern int wtmpfd;
extern struct inittab *proc;
/*
* process - perform entries specified in inittab
--- 16,22 -----
extern int runcnt[];
extern int wtmpfd;
extern struct inittab *proc;
+ extern struct utmp runlvl;
/*
* process - perform entries specified in inittab
**************
*** 29,35
int utmpfd;
int count;
struct inittab *ip;
- struct utmp utmp;
struct utmp utent;
if (runlevel == 'S')
--- 30,35 -----
int utmpfd;
int count;
struct inittab *ip;
struct utmp utent;
char buf[BUFSIZ];
**************
*** 31,36
struct inittab *ip;
struct utmp utmp;
struct utmp utent;
if (runlevel == 'S')
i = runcnt[0]++;
--- 31,37 -----
int count;
struct inittab *ip;
struct utmp utent;
+ char buf[BUFSIZ];
if (runlevel == 'S')
i = runcnt[0]++;
**************
*** 44,56
#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;
--- 45,56 -----
#else
utmpfd = open ("/etc/utmp", O_RDWR|O_CREAT, 0644);
#endif
! sprintf (runlvl.ut_line, RUNLVL_MSG, runlevel);
! runlvl.ut_type = RUN_LVL;
! runlvl.ut_pid = i;
! runlvl.ut_exit.e_termination = runlevel;
! runlvl.ut_exit.e_exit = prevlevel;
! runlvl.ut_time = time ((time_t *) 0);
prevlevel = runlevel;
intrflag = 0;
**************
*** 63,69
if (utent.ut_type == RUN_LVL)
lseek (utmpfd, (off_t) - sizeof utent, 1);
! write (utmpfd, &utmp, sizeof utmp);
close (utmpfd);
utmpfd = -1;
}
--- 63,69 -----
if (utent.ut_type == RUN_LVL)
lseek (utmpfd, (off_t) - sizeof utent, 1);
! write (utmpfd, &runlvl, sizeof runlvl);
close (utmpfd);
utmpfd = -1;
}
**************
*** 68,74
utmpfd = -1;
}
if (wtmpfd >= 0)
! write (wtmpfd, &utmp, sizeof utmp);
again:
inittab (runlevel);
#ifdef DEBUG
--- 68,74 -----
utmpfd = -1;
}
if (wtmpfd >= 0)
! write (wtmpfd, &runlvl, sizeof runlvl);
again:
inittab (runlevel);
#ifdef DEBUG
*** orig/spawn.c
--- spawn.c
**************
*** 1,6
#include <stdio.h>
#include <sys/types.h>
#include <utmp.h>
#include <signal.h>
#include "inittab.h"
--- 1,7 -----
#include <stdio.h>
#include <sys/types.h>
#include <utmp.h>
+ #include <string.h>
#include <signal.h>
#include "inittab.h"
**************
*** 5,11
#include "inittab.h"
#ifndef lint
! static char _sccsid[] = "@(#)spawn.c 1.1 07:58:09 3/22/89";
#endif
extern int proc1;
--- 6,12 -----
#include "inittab.h"
#ifndef lint
! static char _sccsid[] = "@(#)spawn.c 1.2 22:36:44 3/26/89";
#endif
extern int proc1;
**************
*** 141,146
{
struct utmp *utmp;
struct utmp new;
setutent ();
--- 142,148 -----
{
struct utmp *utmp;
struct utmp new;
+ char buf[BUFSIZ];
setutent ();
**************
*** 153,159
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);
--- 155,161 -----
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);
**************
*** 155,161
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;
--- 157,163 -----
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);
strcpy (buf, entry->ini_command);
if (buf[0] == '/') {
**************
*** 157,162
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;
--- 159,172 -----
strcpy (utmp->ut_user, "GETTY");
} else {
memset (utmp->ut_user, '\0', sizeof utmp->ut_user);
+ strcpy (buf, entry->ini_command);
+ if (buf[0] == '/') {
+ strtok (buf, " \t\r\n;");
+ strncpy (utmp->ut_user,
+ strrchr (buf, '/') + 1, sizeof utmp->ut_user);
+ utmp->ut_user[sizeof utmp->ut_user - 1] = '\0';
+ }
+ }
utmp->ut_pid = entry->ini_pid;
utmp->ut_type = INIT_PROCESS;
utmp->ut_exit.e_termination = 0;
*** orig/Makefile
--- Makefile
**************
*** 1,7
#
# @(#)Init - System V compatible init
#
! # @(#)Makefile 1.1 22:39:53 3/26/89
#
SHELL = /bin/sh
--- 1,7 -----
#
# @(#)Init - System V compatible init
#
! # @(#)Makefile 1.2 22:42:37 3/26/89
#
SHELL = /bin/sh
**************
*** 7,13
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
--- 7,13 -----
CFLAGS = -O -M3 -g
! CC = cc
ISRCS = error.c getlevel.c main.c process.c startup.c inittab.c spawn.c
**************
*** 9,15
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
--- 9,15 -----
CC = cc
! ISRCS = error.c getlevel.c main.c process.c startup.c inittab.c spawn.c
TSRCS = telinit.c
**************
*** 11,17
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)
--- 11,17 -----
ISRCS = error.c getlevel.c main.c process.c startup.c inittab.c spawn.c
! TSRCS = telinit.c
HDRS = config.h inittab.h patchlevel.h
**************
*** 13,19
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)
--- 13,19 -----
TSRCS = telinit.c
! HDRS = config.h inittab.h patchlevel.h
IOBJS = error.o getlevel.o main.o process.o startup.o inittab.o spawn.o
**************
*** 15,22
FILES = Makefile $(SRCS) $(HDRS)
! init: $(OBJS)
! cc -o init -g $(OBJS)
error.o: config.h
--- 15,21 -----
HDRS = config.h inittab.h patchlevel.h
! IOBJS = error.o getlevel.o main.o process.o startup.o inittab.o spawn.o
FILES = Makefile $(SRCS) $(TSRCS) $(HDRS)
**************
*** 18,24
init: $(OBJS)
cc -o init -g $(OBJS)
! error.o: config.h
getlevel.o: inittab.h config.h
--- 17,23 -----
IOBJS = error.o getlevel.o main.o process.o startup.o inittab.o spawn.o
! FILES = Makefile $(SRCS) $(TSRCS) $(HDRS)
all: init telinit
**************
*** 20,25
error.o: config.h
getlevel.o: inittab.h config.h
inittab.o: inittab.h config.h
--- 19,34 -----
FILES = Makefile $(SRCS) $(TSRCS) $(HDRS)
+ all: init telinit
+
+ init: $(IOBJS)
+ $(CC) -o init -g $(IOBJS)
+
+ telinit: telinit.o
+ $(CC) -o telinit telinit.o
+
+ error.o: config.h
+
getlevel.o: inittab.h config.h
inittab.o: inittab.h config.h
**************
*** 31,36
spawn.o: inittab.h
startup.o: inittab.h config.h
shar: $(FILES)
shar $(FILES) > init.shar
--- 40,47 -----
spawn.o: inittab.h
startup.o: inittab.h config.h
+
+ telinit.o: config.h
shar: $(FILES)
shar $(FILES) > init.shar
*** orig/telinit.c
--- telinit.c
**************
*** 0,1
--- 1,70 -----
+ #include <sys/types.h>
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <signal.h>
+ #include <string.h>
+ #include <utmp.h>
+ #include "config.h"
+
+ #ifndef lint
+ static char _sccsid[] = "@(#)telinit.c 1.1 22:45:38 3/26/89";
+ #endif
+
+ /*
+ * telinit - set new run level
+ */
+
+ usage ()
+ {
+ fprintf ("usage: telinit [Ss123456qabc]\n");
+ exit (2);
+ }
+
+ main (argc, argv)
+ int argc;
+ char **argv;
+ {
+ struct utmp utent;
+ int fd;
+
+ if (argc != 2)
+ usage ();
+
+ if (strlen (argv[1]) != 1)
+ usage ();
+
+ if (strchr ("qSs123456", argv[1][0]) == (char *) 0)
+ usage ();
+
+ if (argv[1][0] == 'q') {
+ if (kill (1, SIGINT)) {
+ perror ("Can't signal INIT");
+ exit (1);
+ }
+ exit (0);
+ }
+ if ((fd = open (UTMP_FILE, O_RDWR)) < 0) {
+ perror (UTMP_FILE);
+ exit (1);
+ }
+ while (read (fd, &utent, sizeof utent) == sizeof utent)
+ if (utent.ut_type == RUN_LVL)
+ break;
+
+ if (utent.ut_type != RUN_LVL) {
+ fprintf (stderr, "Can't find run-level\n");
+ exit (1);
+ }
+ utent.ut_exit.e_termination = argv[1][0];
+ utent.ut_time = time ((time_t *) 0);
+
+ lseek (fd, - sizeof utent, 1);
+ write (fd, &utent, sizeof utent);
+ close (fd);
+
+ if (kill (1, SIGUSR1)) {
+ perror ("Can't signal INIT");
+ exit (1);
+ }
+ exit (0);
+ }
--
John F. Haugh II +-Quote of the Week:-------------------
VoiceNet: (214) 250-3311 Data: -6272 | "Do not drink and bake"
InterNet: jfh at rpp386.Dallas.TX.US | -- Arnold Swartzenegger
UucpNet : <backbone>!killer!rpp386!jfh +--------------------------------------
More information about the Alt.sources
mailing list