Hello,
Happy new year!
I send you my patch to add /etc/inttab.d support.

The patch scan the /etc/inittab.d/ and read only the first line of *.tab files.
Can you give me your feed-back about this patch.

Didier.


Le mer. 25 déc. 2019 à 09:50, Petter Reinholdtsen <p...@hungry.com> a écrit :
>
>
> Hello, and Merry Christmas. :)
>
> [Didier.Gaudin]
> > do you think it is possible, to have a directory /etc/inittab.d in
> > addition to the /etc/inittab to add service : 1 custom service per file
> > ?
>
> I believe it is both possible and an advantage. :)  Perhaps you can
> create a patch to do so?
>
> --
> Happy hacking
> Petter REinholdtsen
--- sysvinit.orig/src/init.c	2019-12-31 19:09:12.687989710 +0100
+++ sysvinit/src/init.c	2020-01-02 10:14:11.761191795 +0100
@@ -63,6 +63,11 @@
 #include <sys/ttydefaults.h>
 #include <sys/syslog.h>
 #include <sys/time.h>
+/*
+ * inittab.d
+ */
+#include <sys/types.h>
+#include <dirent.h>
 
 #ifdef WITH_SELINUX
 #  include <selinux/selinux.h>
@@ -1431,6 +1436,7 @@
 void read_inittab(void)
 {
   FILE		*fp;			/* The INITTAB file */
+  FILE		*fp_tab;		/* The INITTABD files */
   CHILD		*ch, *old, *i;		/* Pointers to CHILD structure */
   CHILD		*head = NULL;		/* Head of linked list */
 #ifdef INITLVL
@@ -1448,7 +1454,10 @@
   int		round;			/* round 0 for SIGTERM, 1 for SIGKILL */
   int		foundOne = 0;		/* No killing no sleep */
   int		talk;			/* Talk to the user */
-  int		done = 0;		/* Ready yet? */
+  int		done = -1;		/* Ready yet? , 2 level : -1 nothing done, 0 inittab done, 1 inittab and inittab.d done */
+  DIR 		*tabdir=NULL;		/* the INITTAB.D dir */
+  struct dirent *file_entry;		/* inittab.d entry */
+  char 		f_name[272];		/* size d_name + strlen /etc/inittad.d/ */
 
 #if DEBUG
   if (newFamily != NULL) {
@@ -1464,21 +1473,66 @@
   if ((fp = fopen(INITTAB, "r")) == NULL)
 	initlog(L_VB, "No inittab file found");
 
-  while(!done) {
+  /*
+   *  Open INITTAB.D directory 
+   */
+  if( (tabdir = opendir(INITTABD))==NULL)
+	  initlog(L_VB, "No inittab.d directory found");
+
+  while(done!=1) {
 	/*
 	 *	Add single user shell entry at the end.
 	 */
-	if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
-		done = 1;
-		/*
-		 *	See if we have a single user entry.
-		 */
-		for(old = newFamily; old; old = old->next)
-			if (strpbrk(old->rlevel, "S")) break;
-		if (old == NULL)
-			snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN);
-		else
+	if(done == -1) {
+		if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
+			done = 0;
+			/*
+			 *	See if we have a single user entry.
+			 */
+			for(old = newFamily; old; old = old->next)
+				if (strpbrk(old->rlevel, "S"))  break;
+			if (old == NULL)
+				snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN);
+			else
+				continue;
+		}
+	}
+	else if ( done == 0 ){
+		/* parse /etc/inittab.d and read all .tab file */
+		if(tabdir!=NULL){
+			if( (file_entry = readdir(tabdir))!=NULL){
+				/* ignore files not like *.tab */
+				if (!strcmp(file_entry->d_name, ".") || !strcmp(file_entry->d_name, ".."))
+					continue;
+				if (strlen(file_entry->d_name) < 5 || strcmp(file_entry->d_name + strlen(file_entry->d_name) - 4, ".tab"))
+					continue;
+				/*
+				 * initialize filename
+				 */
+				memset(f_name,0,sizeof(char)*272);
+				snprintf(f_name,272,"/etc/inittab.d/%s",file_entry->d_name);
+				initlog(L_VB, "Reading: %s",f_name);
+				/*
+				 * read file in inittab.d
+				 */
+				if ((fp_tab = fopen(f_name, "r")) == NULL)
+					continue;
+				if( fgets(buf, sizeof(buf), fp_tab) == NULL) {
+					fclose(fp_tab);
+					continue;
+				}
+				else
+					fclose(fp_tab);
+			}
+			else {
+				done = 1;
+				continue;
+			}
+		}
+		else {
+			done = 1;
 			continue;
+		}
 	}
 	lineNo++;
 	/*
@@ -1630,10 +1684,12 @@
 			break;
 		}
   }
+
   /*
    *	We're done.
    */
   if (fp) fclose(fp);
+  if(tabdir) closedir(tabdir);
 
 #ifdef __linux__
   check_kernel_console();
--- sysvinit.orig/src/init.c	2019-12-31 19:09:12.687989710 +0100
+++ sysvinit/src/init.c	2019-12-31 18:18:52.397004779 +0100
@@ -63,6 +63,11 @@
 #include <sys/ttydefaults.h>
 #include <sys/syslog.h>
 #include <sys/time.h>
+/*
+ * inittab.d
+ */
+#include <sys/types.h>
+#include <dirent.h>
 
 #ifdef WITH_SELINUX
 #  include <selinux/selinux.h>
@@ -1431,6 +1436,7 @@
 void read_inittab(void)
 {
   FILE		*fp;			/* The INITTAB file */
+  FILE		*fp_tab;		/* The INITTABD files */
   CHILD		*ch, *old, *i;		/* Pointers to CHILD structure */
   CHILD		*head = NULL;		/* Head of linked list */
 #ifdef INITLVL
@@ -1448,7 +1454,10 @@
   int		round;			/* round 0 for SIGTERM, 1 for SIGKILL */
   int		foundOne = 0;		/* No killing no sleep */
   int		talk;			/* Talk to the user */
-  int		done = 0;		/* Ready yet? */
+  int		done = -1;		/* Ready yet? , 2 level : -1 nothing done, 0 inittab done, 1 inittab and inittab.d done */
+  DIR 		*tabdir=NULL;		/* the INITTAB.D dir */
+  struct dirent *file_entry;		/* inittab.d entry */
+  char 		f_name[272];		/* size d_name + strlen /etc/inittad.d/ */
 
 #if DEBUG
   if (newFamily != NULL) {
@@ -1464,21 +1473,65 @@
   if ((fp = fopen(INITTAB, "r")) == NULL)
 	initlog(L_VB, "No inittab file found");
 
-  while(!done) {
+  /*
+   *  Open INITTAB.D directory 
+   */
+  if( (tabdir = opendir(INITTABD))==NULL)
+	  initlog(L_VB, "No inittab.d directory found");
+
+  while(done!=1) {
 	/*
 	 *	Add single user shell entry at the end.
 	 */
-	if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
-		done = 1;
-		/*
-		 *	See if we have a single user entry.
-		 */
-		for(old = newFamily; old; old = old->next)
-			if (strpbrk(old->rlevel, "S")) break;
-		if (old == NULL)
-			snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN);
-		else
+	if(done == -1) {
+		if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
+			done = 0;
+			/*
+			 *	See if we have a single user entry.
+			 */
+			for(old = newFamily; old; old = old->next)
+				if (strpbrk(old->rlevel, "S"))  break;
+			if (old == NULL)
+				snprintf(buf, sizeof(buf), "~~:S:wait:%s\n", SULOGIN);
+			else
+				continue;
+		}
+	}
+	else if ( done == 0 ){
+		/* parse /etc/inittab.d and read all .tab file */
+		if(tabdir!=NULL){
+			if( (file_entry = readdir(tabdir))!=NULL){
+				if (!strcmp(file_entry->d_name, ".") || !strcmp(file_entry->d_name, ".."))
+					continue;
+				if (strlen(file_entry->d_name) < 5 || strcmp(file_entry->d_name + strlen(file_entry->d_name) - 4, ".tab"))
+					continue;
+				/*
+				 * initialize filename
+				 */
+				memset(f_name,0,sizeof(char)*272);
+				snprintf(f_name,272,"/etc/inittab.d/%s",file_entry->d_name);
+				initlog(L_VB, "Reading: %s",f_name);
+				/*
+				 * read file in inittab.d
+				 */
+				if ((fp_tab = fopen(f_name, "r")) == NULL)
+					continue;
+				if( fgets(buf, sizeof(buf), fp_tab) == NULL) {
+					fclose(fp_tab);
+					continue;
+				}
+				else
+					fclose(fp_tab);
+			}
+			else {
+				done = 1;
+				continue;
+			}
+		}
+		else {
+			done = 1;
 			continue;
+		}
 	}
 	lineNo++;
 	/*
@@ -1630,10 +1683,12 @@
 			break;
 		}
   }
+
   /*
    *	We're done.
    */
   if (fp) fclose(fp);
+  if(tabdir) closedir(tabdir);
 
 #ifdef __linux__
   check_kernel_console();
--- sysvinit.orig/src/Makefile	2019-12-31 19:09:12.729989709 +0100
+++ sysvinit/src/Makefile	2019-12-31 18:16:03.577003297 +0100
@@ -202,6 +202,7 @@
 			$(INSTALL_EXEC) $$i $(ROOT)/usr/bin/ ; \
 		done
 		# $(INSTALL_DIR) $(ROOT)/etc/
+		$(INSTALL_DIR) $(ROOT)/etc/inittab.d
 		# $(INSTALL_EXEC) ../doc/initscript.sample $(ROOT)/etc/
 		ln -sf halt $(ROOT)/sbin/reboot
 		ln -sf halt $(ROOT)/sbin/poweroff

Reply via email to