198 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
/* 
 | 
						|
 * (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
 | 
						|
 * cinit.c
 | 
						|
 * part of cLinux
 | 
						|
 */
 | 
						|
 | 
						|
#define CINIT_DIR "/etc/cinit"
 | 
						|
 | 
						|
#define C_INIT    "init"
 | 
						|
#define C_SHD     "shutdown"
 | 
						|
#define C_REBOOT  "reboot"
 | 
						|
 | 
						|
#define C_NEEDS   "needs"
 | 
						|
#define C_WANTS   "wants"
 | 
						|
#define C_RUN     "run"
 | 
						|
 | 
						|
/* opendir() */
 | 
						|
#include <sys/types.h>
 | 
						|
#include <dirent.h>
 | 
						|
 | 
						|
/* *stat() */
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <unistd.h>
 | 
						|
 | 
						|
/* wait() */
 | 
						|
#include <sys/wait.h>
 | 
						|
 | 
						|
/* strlen */
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#define EKEL "/etc/cinit/init/wants"
 | 
						|
 | 
						|
void cerr(char *msg)
 | 
						|
{
 | 
						|
   printf("%s\n", msg);
 | 
						|
}
 | 
						|
 | 
						|
/*********************************************************************** 
 | 
						|
 * parallel run forked() run_svc()
 | 
						|
 */
 | 
						|
#define MAX_PAR 32
 | 
						|
 | 
						|
int run_run_svcs(char *rpath)
 | 
						|
{
 | 
						|
   DIR *d_tmp = NULL;
 | 
						|
   struct dirent *tdirent;
 | 
						|
   char *p, pathbuf[1024];
 | 
						|
   pid_t pids[MAX_PAR];
 | 
						|
   int tmp,i=0;
 | 
						|
 | 
						|
   printf("run_run_svcs on: %s\n",rpath);
 | 
						|
  
 | 
						|
   d_tmp = opendir(rpath);
 | 
						|
 | 
						|
   if(d_tmp == NULL) {
 | 
						|
      printf("Failed to open dir: %s", rpath);
 | 
						|
      return 0;
 | 
						|
   }
 | 
						|
 | 
						|
   while( (tdirent = readdir(d_tmp) ) != NULL) {
 | 
						|
      if (strcmp(tdirent->d_name, ".") == 0
 | 
						|
       || strcmp(tdirent->d_name, "..") == 0)
 | 
						|
         continue;
 | 
						|
      
 | 
						|
      if(i < MAX_PAR) {
 | 
						|
         pids[i] = fork();
 | 
						|
         i++;
 | 
						|
      } else {
 | 
						|
         cerr("to many dependencies");
 | 
						|
         return 1;
 | 
						|
      }
 | 
						|
 | 
						|
      if(pids[i-1] == -1) { /* err */
 | 
						|
         cerr("fork failed\n");
 | 
						|
         return 0;
 | 
						|
      } else if(pids[i-1] == 0) { /* child */
 | 
						|
         printf("Service zu starten nun: %s\n", tdirent->d_name);
 | 
						|
         run_svc(tdirent->d_name);
 | 
						|
         _exit(0);
 | 
						|
      } else /* the parent simply goes the loop again */
 | 
						|
         printf("run_svcs_PARENT\n");
 | 
						|
   }
 | 
						|
 | 
						|
   closedir(d_tmp);
 | 
						|
   
 | 
						|
   /* wait for pids */
 | 
						|
   while(i >= 0) {
 | 
						|
//      printf("waiting for %d ... \n",i);
 | 
						|
      waitpid(pids[i], &tmp, 0);
 | 
						|
      i--;
 | 
						|
   }
 | 
						|
}
 | 
						|
 | 
						|
/*********************************************************************** 
 | 
						|
 * run_svc: gets a wants/needs directory
 | 
						|
 * returns whether _one_ service failed or not
 | 
						|
 */
 | 
						|
int run_svc(char *path)
 | 
						|
{
 | 
						|
   DIR *d_tmp = NULL;
 | 
						|
   struct dirent *tdirent;
 | 
						|
   char *p, pathbuf[1024];
 | 
						|
   struct stat buf;
 | 
						|
   int tmp;
 | 
						|
 | 
						|
   /* check if already running  / ran / currently starting */
 | 
						|
 | 
						|
   /* check for service dir */
 | 
						|
   if( stat(path,&buf) ) {
 | 
						|
      printf("no such service: %s\n", path);
 | 
						|
      return 1;
 | 
						|
   }
 | 
						|
 | 
						|
   /* check for needs  -> forked() */
 | 
						|
   strcpy(pathbuf,path);
 | 
						|
   strcat(pathbuf,"/");
 | 
						|
   strcat(pathbuf,C_NEEDS);
 | 
						|
   if( ! stat(pathbuf,&buf) ) {
 | 
						|
      printf("going for %s\n",pathbuf);
 | 
						|
      tmp = fork();
 | 
						|
      if(tmp == -1) {
 | 
						|
         printf("error ...\n");
 | 
						|
         exit(1);
 | 
						|
      } else if(tmp == 0) { /* child */
 | 
						|
         printf("child for run_run_svcs()\n");
 | 
						|
         run_run_svcs(pathbuf);
 | 
						|
         _exit(0);
 | 
						|
         printf("ZOOOMBIE\n");
 | 
						|
      }
 | 
						|
      else
 | 
						|
         printf("parent\n");
 | 
						|
   }
 | 
						|
 | 
						|
   /* check for wants  -> forked() ? */
 | 
						|
   strcpy(pathbuf,path);
 | 
						|
   strcat(pathbuf,"/");
 | 
						|
   strcat(pathbuf,C_WANTS);
 | 
						|
 | 
						|
   if( ! stat(pathbuf,&buf) ) {
 | 
						|
      printf("dir gibt es auch: %s\n", pathbuf);
 | 
						|
      run_run_svcs(pathbuf);
 | 
						|
   }
 | 
						|
   
 | 
						|
   /* check for service/run */
 | 
						|
   strcpy(pathbuf,path);
 | 
						|
   strcat(pathbuf,"/");
 | 
						|
   strcat(pathbuf,C_RUN);
 | 
						|
 | 
						|
   d_tmp = opendir(pathbuf);
 | 
						|
 | 
						|
   if(d_tmp == NULL) {
 | 
						|
      cerr("failed to open dir...");
 | 
						|
      return 0;
 | 
						|
   }
 | 
						|
 | 
						|
   while( (tdirent = readdir(d_tmp) ) != NULL) {
 | 
						|
      if (strcmp(tdirent->d_name, ".") == 0  || strcmp(tdirent->d_name, "..") == 0)
 | 
						|
         continue;
 | 
						|
 | 
						|
      p=tdirent->d_name;
 | 
						|
      while(*p != '\0') {
 | 
						|
         write(1,p,1);
 | 
						|
         p++;
 | 
						|
      }
 | 
						|
      write(1,"\n",1);
 | 
						|
   }
 | 
						|
 | 
						|
   closedir(d_tmp);
 | 
						|
 | 
						|
   return 1;
 | 
						|
}
 | 
						|
 | 
						|
/***********************************************************************
 | 
						|
 * the main procedure
 | 
						|
 */
 | 
						|
 | 
						|
int main()
 | 
						|
{
 | 
						|
 | 
						|
   char buf[256];
 | 
						|
   int tmp;
 | 
						|
 | 
						|
   strcpy(buf,CINIT_DIR);
 | 
						|
   tmp = strlen(CINIT_DIR);
 | 
						|
   buf[tmp] = '/';
 | 
						|
   strcpy(&buf[tmp+1],C_INIT);
 | 
						|
 | 
						|
   printf("path: %s\n",buf);
 | 
						|
 | 
						|
   run_svc("/etc/cinit/init");
 | 
						|
 | 
						|
   run_svc("/NOT_THERE");
 | 
						|
 | 
						|
   return 0;
 | 
						|
 | 
						|
}
 |