jfh@rpp386.Dallas.TX.US (John F. Haugh II) (03/27/89)
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@rpp386.Dallas.TX.US | -- Arnold Swartzenegger UucpNet : <backbone>!killer!rpp386!jfh +--------------------------------------