From d4cc79bcb907b39722f1431d4881bcfcf8740c49 Mon Sep 17 00:00:00 2001 From: Jesse Smith Date: Wed, 8 Jan 2020 19:42:43 -0400 Subject: [PATCH] Added patch from Didier Gaudin which allows init to load configuration data from files stored in /etc/inittab.d/ --- doc/Changelog | 4 +++ src/Makefile | 1 + src/init.c | 88 +++++++++++++++++++++++++++++++++++++++++++-------- src/paths.h | 1 + 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 112cc73..cfadaeb 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -10,6 +10,10 @@ sysvinit (2.97) unreleased; urgency=low * Added shell script from Trek which converts systemd unit files into init.d style scripts. + * Added patch from Didier Gaudin which allows init to load configuration + data from files stored in /etc/inittab.d/ + + sysvinit (2.96) released; urgency=low [ Jesse Smith ] diff --git a/src/Makefile b/src/Makefile index 4141cb8..1b368dc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -203,6 +203,7 @@ install: all $(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 diff --git a/src/init.c b/src/init.c index 767d1ce..78ae760 100644 --- a/src/init.c +++ b/src/init.c @@ -63,6 +63,11 @@ Version information is not placed in the top-level Makefile by default #include #include #include +/* + * inittab.d + */ +#include +#include #ifdef WITH_SELINUX # include @@ -1431,6 +1436,7 @@ static 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 @@ void read_inittab(void) 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,22 +1473,73 @@ void read_inittab(void) 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; + } + } /* end if( done==-1) */ + else if ( done == 0 ){ + /* parse /etc/inittab.d and read all .tab files */ + 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 only one entry per file + */ + if ((fp_tab = fopen(f_name, "r")) == NULL) + continue; + /* read the file while the line contain comment */ + while( fgets(buf, sizeof(buf), fp_tab) != NULL) { + for(p = buf; *p == ' ' || *p == '\t'; p++); + if (*p != '#' && *p != '\n') + break; + } + fclose(fp_tab); + /* do some checks */ + if( buf == NULL ) + continue; + if( strlen( p ) == 0 ) + continue; + } /* end of readdir, all is done */ + else { + done = 1; + continue; + } + } /* end of if(tabdir!=NULL) */ + else { + done = 1; continue; - } + } + } /* end of if ( done == 0 ) */ lineNo++; /* * Skip comments and empty lines @@ -1630,10 +1690,12 @@ void read_inittab(void) break; } } + /* * We're done. */ if (fp) fclose(fp); + if(tabdir) closedir(tabdir); #ifdef __linux__ check_kernel_console(); diff --git a/src/paths.h b/src/paths.h index 05f9c1b..d97bf1b 100644 --- a/src/paths.h +++ b/src/paths.h @@ -27,6 +27,7 @@ #define SECURETTY "/etc/securetty" /* List of root terminals */ #define SDALLOW "/etc/shutdown.allow" /* Users allowed to shutdown */ #define INITTAB "/etc/inittab" /* Location of inittab */ +#define INITTABD "/etc/inittab.d" /* Location of inittab.d directory */ #define INIT "/sbin/init" /* Location of init itself. */ #define NOLOGIN "/etc/nologin" /* Stop user logging in. */ #define FASTBOOT "/fastboot" /* Enable fast boot. */