www.nico.schottelius.org/software/cinit/browse_source/cinit-0.0.4/old/cinit.c02

199 lines
3.9 KiB
Plaintext

/*
* (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;
}