/* * (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 #include /* *stat() */ #include #include /* wait() */ #include /* strlen */ #include #include #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; }