[alt.sources] Init Clone: patch #1

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  +--------------------------------------