import cinit from unix.schottelius.org
Signed-off-by: Nico Schottelius <nico@ikn.schottelius.org>
This commit is contained in:
parent
3729fc68eb
commit
423ba10303
13396 changed files with 269468 additions and 0 deletions
130
software/cinit/browse_source/cinit-0.3pre6/src/Makefile
Normal file
130
software/cinit/browse_source/cinit-0.3pre6/src/Makefile
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#
|
||||
# cinit
|
||||
#
|
||||
# Nico Schottelius
|
||||
#
|
||||
# Don't edit Makefiles, use conf/* for configuration.
|
||||
#
|
||||
|
||||
include Makefile.tests
|
||||
|
||||
# Build tools / locations
|
||||
CC=../tmpbin/cc
|
||||
CFLAGS=
|
||||
LD=../tmpbin/ld
|
||||
LDFLAGS=
|
||||
STRIP=../tmpbin/strip
|
||||
SBIN=../sbin
|
||||
|
||||
# directories and files
|
||||
CONFIG_H=include/config.h
|
||||
|
||||
BIN=cinit
|
||||
|
||||
#
|
||||
# All objects depend on headers. More or less. FIXME: use gcc -M
|
||||
#
|
||||
CINIT_HEADERS=$(shell cat include/listing)
|
||||
|
||||
# NEW
|
||||
CINIT_OBJ=$(shell cat object_lists/cinit)
|
||||
|
||||
#
|
||||
# Dependencies
|
||||
#
|
||||
$(CINIT_OBJ): $(CINIT_HEADERS)
|
||||
|
||||
#
|
||||
# Client modules
|
||||
#
|
||||
CLIENT=client/msg_svc_on_off.o client/msg_change_status.o client/run_svc.o \
|
||||
client/exec_svc.o client/respawn_svc.o client/run_run_svcs.o \
|
||||
client/connect_sock.o client/begin_msg.o client/sig_terminate.o
|
||||
|
||||
COMMUNICATION=comm/do_change_status.o comm/do_result.o comm/do_svc_name.o
|
||||
|
||||
BOTH=generic/set_signals.o generic/mini_printf.o generic/usage.o
|
||||
|
||||
OBJ=$(SERV) $(SERV_OS) $(CLIENT) $(BOTH) $(COMMUNICATION)
|
||||
|
||||
CSVC_OBJ=util/cservice.o generic/mini_printf.o util/msg_reboot.o \
|
||||
generic/usage.o \
|
||||
$(CLIENT) $(COMMUNICATION)
|
||||
|
||||
CCO_OBJ=util/ccontrol.o generic/mini_printf.o util/msg_reboot.o \
|
||||
generic/usage.o \
|
||||
$(CLIENT) $(COMMUNICATION)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -o $@ $<
|
||||
|
||||
#
|
||||
# End user target
|
||||
#
|
||||
#all: cinit cservice ccontrol sizecheck docs
|
||||
#all: $(BIN)
|
||||
all: cinit
|
||||
|
||||
#
|
||||
# First do configuration, so we include the right variables
|
||||
#
|
||||
Makefile: .configured
|
||||
|
||||
.configured: ../conf/*
|
||||
@../bin/cinit.configure.os
|
||||
@../bin/cinit.configure.tools
|
||||
@../bin/cinit.configure.ipc
|
||||
@../bin/cinit.configure.mark
|
||||
|
||||
$(CINIT_OBJ): $(CONFIG_H)
|
||||
|
||||
|
||||
$(CONFIG_H): ../conf/*
|
||||
../scripts/cinit.mkheader > $(CONFIG_H)
|
||||
|
||||
cservice: $(SBIN)/cservice
|
||||
|
||||
$(SBIN)/cservice util/cservice: $(SBIN) $(CSVC_OBJ)
|
||||
$(LD) $(LDFLAGS) $(CSVC_OBJ) -o $@
|
||||
$(STRIP) $@
|
||||
|
||||
ccontrol: $(SBIN)/ccontrol
|
||||
|
||||
$(SBIN)/ccontrol util/ccontrol: config.h $(SBIN) $(CCO_OBJ)
|
||||
$(LD) $(LDFLAGS) $(CCO_OBJ) -o $@
|
||||
$(STRIP) $@
|
||||
|
||||
install: install-dir cinit cservice ccontrol
|
||||
@echo '*** Installing cinit ***'
|
||||
./bin/cinit.install.binary
|
||||
|
||||
install-miniconf:
|
||||
./bin/cinit.install.miniconf
|
||||
|
||||
install-dir:
|
||||
./bin/cinit.install.dir
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Build targets
|
||||
#
|
||||
cinit: $(CINIT_OBJ)
|
||||
$(LD) $^ -o $@
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Generic targets
|
||||
#
|
||||
|
||||
.PHONY: dist
|
||||
dist: distclean
|
||||
|
||||
.PHONY: distclean
|
||||
distclean: clean
|
||||
rm -f os/current ipc/current
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f ../tmpbin/*.configured
|
||||
rm -f $(BIN)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# Makefile for cinit tests
|
||||
#
|
||||
# Nico Schottelius
|
||||
#
|
||||
# Don't edit Makefiles, use conf/* for configuration.
|
||||
#
|
||||
|
||||
TEST_BUILD_ARGV=test/test_build_argv.o core/build_argv.o
|
||||
|
||||
PROGS=test_build_argv test_build_argv_link
|
||||
|
||||
tests: $(PROGS)
|
||||
|
||||
test_build_argv: test/test_build_argv.o core/build_argv.o
|
||||
test_build_argv_link: test/test_build_argv+link.o core/build_argv.o
|
||||
|
||||
test_gen_svc_tree: test/test_gen_svc_tree.o svc/list_display_all.o \
|
||||
svc/list_display_all.o \
|
||||
svc/list_display_all.o \
|
||||
svc/list_display_all.o \
|
||||
svc/list_display_all.o \
|
||||
svc/gen_svc_tree.o \
|
||||
generic/mini_printf.o \
|
||||
svc/list_display_all.o
|
||||
|
||||
test_openreadclose: test/test_openreadclose.o generic/openreadclose.o
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* run initial service(s)
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/***********************************************************************
|
||||
* start the first service
|
||||
*/
|
||||
|
||||
int run_init_svc(char *cinit_svc)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
/* leave cinit alone */
|
||||
pid = fork();
|
||||
|
||||
if(pid == -1) { /* err */
|
||||
print_errno(MSG_ERR_FORK);
|
||||
return 0;
|
||||
} else if(pid == 0) { /* child */
|
||||
cinit_ipc_sclose();
|
||||
set_signals(ACT_CLIENT);
|
||||
|
||||
/* FIXME: open stderr, stdin, stdout to files / syslog / logable ?
|
||||
* IMPLEMENT PER SERVICE!
|
||||
*/
|
||||
|
||||
run_svc(cinit_svc);
|
||||
|
||||
_exit(0); /* nobody cares about us, so exit successfully anyway */
|
||||
}
|
||||
/* parent exits, we don't care about our children */
|
||||
return 1;
|
||||
}
|
||||
/* ready for cinit-0.2 */
|
||||
170
software/cinit/browse_source/cinit-0.3pre6/src/core/build_argv.c
Normal file
170
software/cinit/browse_source/cinit-0.3pre6/src/core/build_argv.c
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Build **argv for execution in cinit way:
|
||||
* 1. check whether cmd is a valid executable
|
||||
* 2. try to read cmd.params and write parameters
|
||||
* 3. try to read cmd.env and setup environment
|
||||
*
|
||||
* Returns:
|
||||
* BA_OK: Everything went well, you can use the struct
|
||||
* BA_NOTFOUND: Binary executable is not available
|
||||
* BA_PARAMS: Reading the parameters failed (ignoring non-existence!)
|
||||
* BA_ENV: Reading the environment failed (same as above)
|
||||
* BA_OTHER: Other error
|
||||
*/
|
||||
|
||||
#include <fcntl.h> /* open() */
|
||||
#include <stdlib.h> /* *alloc() */
|
||||
#include <unistd.h> /* readlink */
|
||||
#include <errno.h> /* errno */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <string.h> /* strchr */
|
||||
#include <sys/stat.h> /* stat() */
|
||||
|
||||
#include "cinit.h"
|
||||
#include "build_argv.h"
|
||||
|
||||
/*
|
||||
* char *basename: something we should execute
|
||||
* (*basename) + ".params" will be added as parameters
|
||||
* (*basename) + ".env" will be added as environment
|
||||
*/
|
||||
|
||||
int cinit_build_argv(char *basename, struct ba_argv *bav)
|
||||
{
|
||||
int tmp;
|
||||
int argc;
|
||||
char pathtmp[PATH_MAX+1];
|
||||
char *sbuf = NULL;
|
||||
char *p;
|
||||
|
||||
/* sane values */
|
||||
bav->argv = NULL;
|
||||
bav->envp = NULL;
|
||||
|
||||
mini_printf("CBA::",1);
|
||||
mini_printf(basename,1);
|
||||
mini_printf("\n",1);
|
||||
|
||||
/***********************************************************************
|
||||
* Try to get realname (for links)
|
||||
*/
|
||||
if((tmp = readlink(basename,pathtmp,PATH_MAX)) == -1) {
|
||||
/* nothing there? */
|
||||
if(errno == ENOENT) {
|
||||
return BA_E_NOTFOUND;
|
||||
}
|
||||
if (errno != EINVAL) {
|
||||
return BA_E_OTHER;
|
||||
}
|
||||
tmp=strlen(basename);
|
||||
strncpy(pathtmp,basename,tmp);
|
||||
}
|
||||
pathtmp[tmp] = '\0';
|
||||
++tmp; /* the byte to add to memory for \0;
|
||||
neither readlink nor strlen count the \0 */
|
||||
|
||||
/***********************************************************************
|
||||
* prepare argv0
|
||||
*/
|
||||
bav->argv = malloc(sizeof(char *));
|
||||
if(bav->argv == NULL) return BA_E_MEM;
|
||||
|
||||
*bav->argv = malloc(tmp);
|
||||
if(*(bav->argv) == NULL) return BA_E_MEM;
|
||||
|
||||
strncpy(*(bav->argv),pathtmp,tmp);
|
||||
|
||||
/********************** read params *********************/
|
||||
/* FIXME check bounds! */
|
||||
strcpy(pathtmp,basename);
|
||||
strcat(pathtmp,C_PARAMS);
|
||||
/* ORC_ERR_NONEXISTENT: Ok, have sbuf set to NULL
|
||||
* ORC_OK: Ok, have a filled buffer (perhaps NULL, too)
|
||||
* other: Error, print errno
|
||||
*/
|
||||
tmp = openreadclose(pathtmp,&sbuf);
|
||||
|
||||
if(tmp != ORC_ERR_NONEXISTENT && tmp != ORC_OK) {
|
||||
print_errno(pathtmp);
|
||||
return BA_E_PARAMS;
|
||||
}
|
||||
|
||||
sbuf = strip_final_newline(sbuf);
|
||||
|
||||
/***********************************************************************
|
||||
* Now split the string, converting \n to \0
|
||||
*/
|
||||
argc = 1; /* argv0 */
|
||||
while(sbuf != NULL) {
|
||||
p = strchr(sbuf,'\n');
|
||||
bav->argv = realloc(bav->argv, sizeof(char *) * (argc + 1));
|
||||
|
||||
if(bav->argv == NULL) return BA_E_MEM;
|
||||
bav->argv[argc] = sbuf; /* here begins the current argument */
|
||||
|
||||
if(p != NULL) { /* found another \n */
|
||||
*p = '\0';
|
||||
sbuf = p+1;
|
||||
} else { /* end of string */
|
||||
sbuf = NULL;
|
||||
}
|
||||
|
||||
++argc;
|
||||
}
|
||||
|
||||
/************ close argv list **************/
|
||||
bav->argv = realloc(bav->argv, sizeof(char *) * (argc + 1));
|
||||
if(bav->argv == NULL) return BA_E_MEM;
|
||||
bav->argv[argc] = NULL; /* terminate argv list */
|
||||
|
||||
/********************** read environment *********************/
|
||||
strcpy(pathtmp,basename);
|
||||
strcat(pathtmp,C_ENV);
|
||||
|
||||
tmp = argc = 0;
|
||||
sbuf = NULL;
|
||||
|
||||
tmp = openreadclose(pathtmp,&sbuf);
|
||||
|
||||
if(tmp != ORC_ERR_NONEXISTENT && tmp != ORC_OK) {
|
||||
print_errno(pathtmp);
|
||||
return BA_E_PARAMS;
|
||||
}
|
||||
|
||||
sbuf = strip_final_newline(sbuf);
|
||||
|
||||
/************** build environment string **************/
|
||||
argc = 0;
|
||||
while(sbuf != NULL) {
|
||||
p = strchr(sbuf,'\n');
|
||||
|
||||
bav->envp = realloc(bav->envp, sizeof(char *) * (argc + 1));
|
||||
if(bav->envp == NULL) return BA_E_MEM;
|
||||
|
||||
bav->envp[argc] = sbuf;
|
||||
|
||||
/* if we found \n */
|
||||
if(p != NULL) {
|
||||
*p = '\0';
|
||||
sbuf = p+1;
|
||||
} else {
|
||||
sbuf = NULL;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
|
||||
/************ close env list **************/
|
||||
bav->envp = realloc(bav->envp, sizeof(char *) * (argc + 1));
|
||||
if(bav->envp == NULL) {
|
||||
return BA_E_MEM;
|
||||
}
|
||||
bav->envp[argc] = NULL;
|
||||
|
||||
return BA_OK;
|
||||
}
|
||||
90
software/cinit/browse_source/cinit-0.3pre6/src/core/cinit.c
Normal file
90
software/cinit/browse_source/cinit-0.3pre6/src/core/cinit.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* The main file
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* getpid,chdir */
|
||||
#include <string.h> /* str(ncmp,len,cpy,cat) */
|
||||
#include <stdio.h> /* perror */
|
||||
#include <stdlib.h> /* malloc */
|
||||
|
||||
#include "cinit.h" /* general things */
|
||||
#include "messages.h" /* messages */
|
||||
#include "ipc.h" /* general ipc methods */
|
||||
#include "svc.h" /* gen_svc_tree */
|
||||
|
||||
struct listitem *svc_list = NULL;
|
||||
struct dep *svc_init = NULL;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *initdir;
|
||||
// pid_t cpid;
|
||||
|
||||
initdir = CINIT_INIT; /* default init dir */
|
||||
|
||||
/* FIXME: RE-ENABLE as SOON AS PRODUCTIVE cpid = getpid();
|
||||
* Is this really needed or should we lock() ourselves?
|
||||
if(cpid != 1) {
|
||||
mini_printf(CINIT_VERSION,2);
|
||||
mini_printf(MSG_USAGE,2);
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
set_signals(ACT_SERV);
|
||||
|
||||
/* Look whether we should start a profile */
|
||||
while(argc > 1) {
|
||||
if( !strncmp(PROFILE, argv[argc-1], strlen(PROFILE)) ) {
|
||||
initdir = (char *) malloc(
|
||||
strlen(CINIT_SVCDIR) +
|
||||
strlen(&argv[argc-1][strlen(PROFILE)]) + 2
|
||||
);
|
||||
if(initdir == NULL) {
|
||||
panic();
|
||||
}
|
||||
strcpy(initdir,CINIT_SVCDIR);
|
||||
strcat(initdir,SLASH);
|
||||
strcat(initdir,&argv[argc-1][strlen(PROFILE)]);
|
||||
break;
|
||||
}
|
||||
argc--;
|
||||
}
|
||||
|
||||
/* FIXME: do we really need three calls? */
|
||||
mini_printf(MSG_BOOTING,1); mini_printf(initdir,1); mini_printf("\n",1);
|
||||
|
||||
if(chdir(initdir) == -1) {
|
||||
print_errno(initdir);
|
||||
panic();
|
||||
}
|
||||
|
||||
/* initialize ipc method */
|
||||
if(!cinit_ipc_init()) {
|
||||
panic();
|
||||
}
|
||||
|
||||
/* pre-calculate service tree */
|
||||
gen_svc_tree(initdir);
|
||||
|
||||
/* free, if we malloc()ed before */
|
||||
if(initdir != CINIT_INIT) {
|
||||
free(initdir);
|
||||
}
|
||||
|
||||
/* start tree from the bottom */
|
||||
if(!tree_exec(svc_init)) return 1;
|
||||
|
||||
mini_printf("=> cinit started.\n",1);
|
||||
|
||||
/* listen for incomming messages: should never return */
|
||||
if(!cinit_ipc_listen()) {
|
||||
panic();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Communication defines
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ipc.h"
|
||||
#include "cinit.h"
|
||||
#include "os.h"
|
||||
#include "messages.h"
|
||||
|
||||
/***********************************************************************
|
||||
* sig_reboot
|
||||
* Shutdown the system
|
||||
*/
|
||||
|
||||
void do_reboot(int signal)
|
||||
{
|
||||
//struct listitem *tmp;
|
||||
struct timespec ts;
|
||||
//char **cmd;
|
||||
//int i;
|
||||
|
||||
/* shutdown all services: take care about the dependency tree */
|
||||
|
||||
/* do not listen to client requests anymore
|
||||
* FIXME: perhaps before shutdown? */
|
||||
cinit_ipc_destroy();
|
||||
|
||||
/* now: all services are down, let's kill all other processes */
|
||||
if( kill(-1,SIGTERM) == -1) {
|
||||
print_errno(MSG_TERMKILL);
|
||||
}
|
||||
|
||||
/* FIXME make SLEEP_KILL an optional configuration statement */
|
||||
ts.tv_sec = SLEEP_KILL; /* defined in conf/sleep_kill */
|
||||
ts.tv_nsec = 0;
|
||||
nanosleep(&ts,NULL);
|
||||
|
||||
if( kill(-1,SIGKILL) == -1) {
|
||||
print_errno(MSG_KILLBILL);
|
||||
}
|
||||
|
||||
/* execute umount, as defined in conf/umount */
|
||||
|
||||
/* execute_sth(CINIT_UMOUNT); */
|
||||
|
||||
/* do what we really wanted to do */
|
||||
switch(signal) {
|
||||
case SIGTERM: /* power off */
|
||||
LOG(MSG_POWER_OFF);
|
||||
cinit_poweroff();
|
||||
break;
|
||||
case SIGHUP: /* reboot */
|
||||
LOG(MSG_REBOOT);
|
||||
cinit_reboot();
|
||||
break;
|
||||
case SIGUSR1: /* halt */
|
||||
LOG(MSG_HALT);
|
||||
cinit_halt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
core/build_argv.o
|
||||
core/cinit.o
|
||||
core/panic.o
|
||||
core/run_init_svc.o
|
||||
core/set_signals.o
|
||||
core/do_reboot.o
|
||||
core/sig_child.o
|
||||
30
software/cinit/browse_source/cinit-0.3pre6/src/core/panic.c
Normal file
30
software/cinit/browse_source/cinit-0.3pre6/src/core/panic.c
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Execute something
|
||||
*/
|
||||
|
||||
#include "cinit.h"
|
||||
#include <unistd.h>
|
||||
|
||||
void panic(void)
|
||||
{
|
||||
char *nargv[2];
|
||||
|
||||
execute_sth(CINIT_PANIC);
|
||||
|
||||
/***********************************************************************
|
||||
* THIS SHOULD NOT HAPPEN, fallback to hardcoded sulogin
|
||||
* (conf/sulogin)
|
||||
*/
|
||||
nargv[0] = SULOGIN;
|
||||
nargv[1] = NULL;
|
||||
|
||||
execv(SULOGIN,nargv);
|
||||
|
||||
/* there's nothing todo, if everything fails */
|
||||
_exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* run initial service(s)
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* _exit, fork */
|
||||
|
||||
#include "cinit.h"
|
||||
#include "messages.h"
|
||||
#include "ipc.h"
|
||||
|
||||
int run_svc(char *rpath) { rpath = "test"; return 0; } /* a hack to compile cinit for now */
|
||||
|
||||
int run_init_svc(char *cinit_svc)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
/* leave cinit alone */
|
||||
pid = fork();
|
||||
|
||||
if(pid == -1) { /* err */
|
||||
print_errno(MSG_ERR_FORK);
|
||||
return 0;
|
||||
} else if(pid == 0) { /* child */
|
||||
cinit_ipc_sclose();
|
||||
set_signals(ACT_CLIENT);
|
||||
|
||||
if(!cinit_ipc_logon()) _exit(1);
|
||||
|
||||
/* FIXME: open stderr, stdin, stdout to files / syslog / logable ?
|
||||
* IMPLEMENT PER SERVICE!
|
||||
*/
|
||||
|
||||
run_svc(cinit_svc);
|
||||
|
||||
_exit(0); /* nobody cares about us, so exit successfully anyway */
|
||||
}
|
||||
/* parent exits, we don't care about our children */
|
||||
return 1;
|
||||
}
|
||||
/* ready for cinit-0.2 */
|
||||
131
software/cinit/browse_source/cinit-0.3pre6/src/core/run_svc.c
Normal file
131
software/cinit/browse_source/cinit-0.3pre6/src/core/run_svc.c
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
* run_svc
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
/* headers are clean */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
#error "needs to be cleaned up"
|
||||
|
||||
/***********************************************************************
|
||||
* run_svc: run a service and before all dependencies
|
||||
*/
|
||||
int run_svc(char *rpath)
|
||||
{
|
||||
int tmp;
|
||||
pid_t pid;
|
||||
char abspath[PATH_MAX], pathtmp[PATH_MAX]; /* pathtmp will be misused */
|
||||
struct stat buf;
|
||||
struct timespec ts;
|
||||
|
||||
/******************* absolute PATH ***************/
|
||||
/* save current working dir */
|
||||
if(! (int) getcwd(pathtmp,PATH_MAX)) {
|
||||
print_errno(pathtmp);
|
||||
return RT_UNSPEC;
|
||||
}
|
||||
|
||||
/* change to rpath */
|
||||
if(chdir(rpath) == -1) {
|
||||
print_errno(rpath);
|
||||
return RT_NOTEXIST;
|
||||
}
|
||||
|
||||
/* get absolute name of rpath */
|
||||
if(! (int) getcwd(abspath,PATH_MAX)) {
|
||||
perror(abspath);
|
||||
return RT_UNSPEC;
|
||||
}
|
||||
|
||||
/* change back */
|
||||
if(chdir(pathtmp) == -1) {
|
||||
perror(pathtmp);
|
||||
return RT_UNSPEC;
|
||||
}
|
||||
D_PRINTF(abspath);
|
||||
|
||||
/******************* REGISTER SERVICE ***************/
|
||||
do {
|
||||
tmp = msg_svc_on_off(abspath,CMD_START_SVC); /* check status */
|
||||
|
||||
switch(tmp) {
|
||||
case ST_FAIL: /* somebody failed before, we won't retry */
|
||||
return RT_SVC_FAILED;
|
||||
break;
|
||||
case ST_TMP: /* someone is working on it */
|
||||
ts.tv_sec = SLEEP_RERUN;
|
||||
nanosleep(&ts,NULL);
|
||||
break;
|
||||
case ST_ONCE: /* somebody did our work */
|
||||
case RT_ERR_COMM: /* communication failed */
|
||||
case ST_RESPAWN: /* somebody does our work */
|
||||
case ST_NEED_FAIL: /* the needs failed before */
|
||||
return tmp;
|
||||
break;
|
||||
case RT_TMPNOW: /* do not go to default: */
|
||||
break;
|
||||
default:
|
||||
mini_printf(MSG_SHOULD_NOT_HAPPEN,1);
|
||||
return RT_UNSPEC;
|
||||
break;
|
||||
}
|
||||
} while(tmp != RT_TMPNOW);
|
||||
|
||||
/******************* BEGIN DEPENDENCIES ***************/
|
||||
strcpy(pathtmp,abspath);
|
||||
strcat(pathtmp,SLASH);
|
||||
strcat(pathtmp,C_NEEDS);
|
||||
|
||||
/* check for needs */
|
||||
if( stat(pathtmp,&buf) == 0 ) {
|
||||
if( ! run_run_svcs(pathtmp) ) {
|
||||
SERVICE_LOG(abspath,LOG_NEED_FAIL);
|
||||
msg_change_status(abspath, ST_NEED_FAIL, 0);
|
||||
return ST_NEED_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/********** WANTS ************/
|
||||
strcpy(pathtmp,abspath);
|
||||
strcat(pathtmp,SLASH);
|
||||
strcat(pathtmp,C_WANTS);
|
||||
|
||||
if( stat(pathtmp,&buf) == 0 ) {
|
||||
run_run_svcs(pathtmp); /* don't care about what happens with the want svc */
|
||||
}
|
||||
|
||||
/******************* execute services ***************/
|
||||
strcpy(pathtmp,abspath);
|
||||
strcat(pathtmp,SLASH);
|
||||
strcat(pathtmp,C_RESPAWN);
|
||||
|
||||
if( stat(pathtmp,&buf) == 0) {
|
||||
pid = respawn_svc(abspath);
|
||||
tmp = ST_RESPAWN;
|
||||
} else {
|
||||
pid = exec_svc(abspath, CMD_START_SVC);
|
||||
tmp = ST_ONCE;
|
||||
}
|
||||
|
||||
if(!pid) {
|
||||
msg_change_status(abspath, ST_FAIL, pid);
|
||||
return ST_FAIL;
|
||||
}
|
||||
|
||||
if(!msg_change_status(abspath, tmp, pid) ) {
|
||||
return RT_ERR_COMM;
|
||||
}
|
||||
|
||||
return tmp; /* ST_ONCE || ST_RESPAWN */
|
||||
}
|
||||
/* cinit-0.2 return codes implemented */
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006-2006 Nico Schottelius (nico-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Define signal handlers
|
||||
*/
|
||||
|
||||
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <stdio.h> /* NULL */
|
||||
#include "cinit.h" /* defines */
|
||||
|
||||
void set_signals(int action)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
if(action == ACT_SERV) {
|
||||
sa.sa_handler=sig_child;
|
||||
} else {
|
||||
sa.sa_handler=SIG_DFL;
|
||||
}
|
||||
sigaction(SIGCHLD,&sa,NULL); /* what todo when a child exited */
|
||||
|
||||
if(action == ACT_SERV) {
|
||||
sa.sa_handler=do_reboot;
|
||||
}
|
||||
sigaction(SIGHUP,&sa,NULL); /* reboot */
|
||||
sigaction(SIGTERM,&sa,NULL); /* poweroff */
|
||||
sigaction(SIGUSR1,&sa,NULL); /* halt */
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* The child handler
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h> /* FIXME: check headers (->Posix!) */
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h> /* NULL */
|
||||
|
||||
#include <signal.h> /* sigaction */
|
||||
#include "cinit.h" /* */
|
||||
#include "svc.h" /* list_search_pid */
|
||||
#include "messages.h" /* messages */
|
||||
|
||||
/***********************************************************************
|
||||
* sig_child: (c)collect the children
|
||||
*/
|
||||
void sig_child(int tmp)
|
||||
{
|
||||
/* New code:
|
||||
* - search for pid in service list
|
||||
* * if (respawn) -> start new
|
||||
* - insert delay? if exit code is non-zero? if uptime too less?
|
||||
* * if (once) -> update service status
|
||||
* * else ignore, but reap away
|
||||
*/
|
||||
struct listitem *svc;
|
||||
struct sigaction sa;
|
||||
|
||||
/* do not interrupt us or anything we might call */
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigaction(SIGCHLD,&sa,NULL);
|
||||
|
||||
while((tmp = waitpid(-1, &tmp, WNOHANG)) > 0) {
|
||||
/* check if it's a watched child */
|
||||
svc = list_search_pid((pid_t) tmp);
|
||||
|
||||
if(svc != NULL) {
|
||||
/* Check, that we are operating on it =. that it is no normal child */
|
||||
if(svc->status & ST_ONCE_RUN
|
||||
|| svc->status & ST_SH_RESPAWN
|
||||
|| svc->status & ST_RESPAWNING) {
|
||||
if(WIFEXITED(tmp) && !WEXITSTATUS(tmp)) {
|
||||
svc_success(svc);
|
||||
svc_report_status(svc->abs_path,MSG_SVC_OK,NULL);
|
||||
} else {
|
||||
svc_fail(svc);
|
||||
svc_report_status(svc->abs_path,MSG_SVC_FAIL,NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* respawn: restart */
|
||||
if(svc->status == ST_RESPAWNING) {
|
||||
svc_report_status(svc->abs_path,MSG_SVC_RESTART,NULL);
|
||||
svc_start(svc);
|
||||
}
|
||||
} else {
|
||||
/* FIXME remove in production version */
|
||||
mini_printf("Cleanup: reparenting\n",1);
|
||||
}
|
||||
}
|
||||
|
||||
sa.sa_handler = sig_child;
|
||||
sigaction(SIGCHLD,&sa,NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Executes something: replaces us
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* _exit */
|
||||
#include "cinit.h"
|
||||
#include "build_argv.h"
|
||||
|
||||
void execute_sth(char *basename)
|
||||
{
|
||||
int tmp;
|
||||
struct ba_argv bav;
|
||||
|
||||
mini_printf("ES::",1);
|
||||
mini_printf(basename,1);
|
||||
mini_printf("\n",1);
|
||||
|
||||
tmp = cinit_build_argv(basename,&bav);
|
||||
if((tmp = cinit_build_argv(basename,&bav)) != BA_OK) {
|
||||
if(tmp != BA_E_MEM) { /* do not print something on memory errors */
|
||||
print_errno(basename);
|
||||
}
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
execve((bav.argv)[0],bav.argv,bav.envp);
|
||||
print_errno(basename);
|
||||
_exit(1); /* simply exit non-zero. That's enough for cinit to recognize
|
||||
it as faulty */
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* check whether file exists and is a file
|
||||
*/
|
||||
|
||||
#include <sys/types.h> /* FIXME: check headers against posix */
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h> /* errno */
|
||||
#include "cinit.h"
|
||||
|
||||
int file_exists(char *filename)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if(stat(filename,&buf) == -1) {
|
||||
if(errno == ENOENT) {
|
||||
return FE_NOT;
|
||||
} else {
|
||||
print_errno(filename);
|
||||
return FE_ERR;
|
||||
}
|
||||
} else {
|
||||
if(!S_ISREG(buf.st_mode)) {
|
||||
return FE_OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
return FE_FILE;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Print the world!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
void mini_printf(char *str,int fd)
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* don't get fooled by bad pointers */
|
||||
if(str == NULL) return;
|
||||
|
||||
p = str;
|
||||
while ( *p ) p++;
|
||||
|
||||
write(fd,str,(size_t) (p - str) );
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
generic/execute_sth.o
|
||||
generic/mini_printf.o
|
||||
generic/path_absolute.o
|
||||
generic/path_append.o
|
||||
generic/print_errno.o
|
||||
generic/openreadclose.o
|
||||
generic/strip_final_newline.o
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* read a file
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* open, read, close */
|
||||
#include <string.h> /* strncpy */
|
||||
#include <stdlib.h> /* realloc */
|
||||
#include <errno.h> /* errno */
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <fcntl.h> /* open */
|
||||
#include "cinit.h"
|
||||
|
||||
int openreadclose(char *filename, char **where)
|
||||
{
|
||||
|
||||
int tmp;
|
||||
int cnt;
|
||||
int fd;
|
||||
char buf[512];
|
||||
|
||||
mini_printf("ORC:",1);
|
||||
mini_printf(filename,1);
|
||||
mini_printf("\n",1);
|
||||
*where = NULL;
|
||||
|
||||
while((fd = open(filename,O_RDONLY)) == -1) {
|
||||
if(errno == ENOENT) return ORC_ERR_NONEXISTENT;
|
||||
if(errno != EINTR) return ORC_ERR_OPEN;
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
while (1) {
|
||||
tmp = read(fd,buf,512);
|
||||
|
||||
if(tmp == -1) {
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return ORC_ERR_READ;
|
||||
} else if(tmp == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
cnt += tmp;
|
||||
*where = realloc(*where,cnt + 1);
|
||||
if(*where == NULL) return ORC_ERR_MEM;
|
||||
|
||||
/* FIXME check correctness of copied buffer...
|
||||
* and get some sleep..soon, very soon! */
|
||||
strncpy(&(*where)[cnt-tmp],buf,tmp);
|
||||
mini_printf("ORC: ",1);
|
||||
mini_printf(buf,1);
|
||||
mini_printf("\n",1);
|
||||
}
|
||||
|
||||
while((fd = close(fd)) == -1) {
|
||||
if(errno == EINTR) continue;
|
||||
return ORC_ERR_CLOSE;
|
||||
}
|
||||
|
||||
/* terminate string! */
|
||||
(*where)[cnt] = '\0';
|
||||
|
||||
return ORC_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* create an absulte path
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* chdir(),getcwd */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include "cinit.h" /* print_errno */
|
||||
#include "messages.h" /* print_errno */
|
||||
|
||||
int path_absolute(char *relpath, char *newpath, size_t size)
|
||||
{
|
||||
char oldpath[PATH_MAX+1];
|
||||
|
||||
if(!getcwd(oldpath,PATH_MAX+1)) {
|
||||
print_errno(MSG_GETCWD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(chdir(relpath) == -1) {
|
||||
print_errno(relpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!getcwd(newpath,size)) {
|
||||
print_errno(relpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(chdir(oldpath) == -1) {
|
||||
print_errno(oldpath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* create path to needs
|
||||
*/
|
||||
|
||||
#include <string.h> /* strlen */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
|
||||
#include "cinit.h" /* mini_printf, PD_ERR */
|
||||
|
||||
int path_append(char *path, char *append)
|
||||
{
|
||||
size_t end = strlen(path);
|
||||
|
||||
if(strcmp(&path[end-1],SLASH)) {
|
||||
if((end + strlen(SLASH) + strlen(append)) > PATH_MAX) return 0;
|
||||
strcat(path,SLASH);
|
||||
} else {
|
||||
if((end + strlen(append)) > PATH_MAX) return 0;
|
||||
}
|
||||
strcat(path,append);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* stolen from tcpserver_blocker
|
||||
*
|
||||
* Author: Nico Schottelius
|
||||
* Date: 2006-08-24
|
||||
*
|
||||
* Print the error found in errno
|
||||
*/
|
||||
|
||||
#include <string.h> /* strerror */
|
||||
#include <errno.h> /* errno */
|
||||
|
||||
#include "cinit.h" /* mini_printf, PD_ERR */
|
||||
|
||||
void print_errno(char *msg)
|
||||
{
|
||||
if(msg) {
|
||||
mini_printf(msg, FD_ERR);
|
||||
mini_printf(": ", FD_ERR);
|
||||
}
|
||||
mini_printf(strerror(errno), FD_ERR);
|
||||
mini_printf("\n", FD_ERR);
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* If the last character is \n, shrink the memory and remove it
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <string.h> /* strchr */
|
||||
#include <stdlib.h> /* alloc */
|
||||
#include "cinit.h" /* FIXME debug */
|
||||
|
||||
char *strip_final_newline(char *str)
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* don't get fooled by bad pointers */
|
||||
if(str == NULL) {
|
||||
mini_printf("SFN: NULL\n",1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = strrchr(str,'\n');
|
||||
if(p) {
|
||||
if(*(p+1) == '\0') {
|
||||
str = realloc(str,(p-str));
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* usage: tell the world what we want - seriously no capitalism
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include "cinit.h"
|
||||
|
||||
/***********************************************************************
|
||||
* usage: tell the user what's wrong and a help text
|
||||
*/
|
||||
void usage(char *banner, char *text)
|
||||
{
|
||||
/* print banner + error message */
|
||||
mini_printf(banner,1);
|
||||
mini_printf(text,1);
|
||||
_exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* build **argv
|
||||
*/
|
||||
|
||||
#ifndef CINIT_BA_HEADER
|
||||
#define CINIT_BA_HEADER
|
||||
|
||||
/*****************************************************************************
|
||||
* Defines: return values
|
||||
*/
|
||||
enum {
|
||||
BA_OK,
|
||||
BA_E_NOTFOUND,
|
||||
BA_E_PARAMS,
|
||||
BA_E_ENV,
|
||||
BA_E_MEM,
|
||||
BA_E_OTHER
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Structures
|
||||
*/
|
||||
struct ba_argv {
|
||||
char **argv;
|
||||
char **envp;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions
|
||||
*/
|
||||
int cinit_build_argv(char *basename, struct ba_argv *bav);
|
||||
|
||||
#endif
|
||||
109
software/cinit/browse_source/cinit-0.3pre6/src/include/cinit.h
Normal file
109
software/cinit/browse_source/cinit-0.3pre6/src/include/cinit.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
*/
|
||||
|
||||
#ifndef _CINIT_H
|
||||
#define _CINIT_H
|
||||
|
||||
/* includes */
|
||||
#include <sys/types.h> /* pid_t */
|
||||
#include "config.h" /* paths, socket options, etc. */
|
||||
|
||||
/***********************************************************************
|
||||
* Defines
|
||||
*/
|
||||
#define SLASH "/"
|
||||
#define CINIT_CONFDIR CINIT_DIR SLASH C_CONFDIR
|
||||
#define CINIT_PANIC CINIT_CONFDIR SLASH C_PANIC
|
||||
|
||||
enum { /* FIXME: there are some default defines somewhere for that */
|
||||
FD_IN=0,
|
||||
FD_OUT=1,
|
||||
FD_ERR=2
|
||||
};
|
||||
|
||||
enum { /* returns of openreadclose */
|
||||
ORC_OK,
|
||||
ORC_ERR_NONEXISTENT,
|
||||
ORC_ERR_OPEN,
|
||||
ORC_ERR_READ,
|
||||
ORC_ERR_CLOSE,
|
||||
ORC_ERR_MEM
|
||||
};
|
||||
|
||||
/* values for execute_sth:
|
||||
* STRICT: print and error, if .../on does not exist
|
||||
* NOSTRICT: no .../on is fine
|
||||
*/
|
||||
enum {
|
||||
EXEC_STRICT,
|
||||
EXEC_NOSTRICT
|
||||
};
|
||||
|
||||
enum {
|
||||
FE_FILE, /* file exists and is a file */
|
||||
FE_OTHER, /* file exists, but is no file */
|
||||
FE_NOT, /* file does not exist */
|
||||
FE_ERR /* some error occured */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Paths
|
||||
*/
|
||||
#define CINIT_SVCDIR CINIT_DIR SLASH SVCDIR
|
||||
#define CINIT_INIT CINIT_SVCDIR SLASH C_INIT
|
||||
#define CINIT_TMNT CINIT_DIR SLASH C_TMP
|
||||
#define CINIT_SOCK CINIT_TMNT SLASH C_SOCK
|
||||
#define CINIT_BIN PREFIX SLASH "sbin" SLASH "cinit"
|
||||
|
||||
#define CINIT_CONFDIR CINIT_DIR SLASH C_CONFDIR
|
||||
#define CINIT_PANIC CINIT_CONFDIR SLASH C_PANIC
|
||||
#define CINIT_UMOUNT CINIT_CONFDIR SLASH C_UMOUNT
|
||||
|
||||
/* actions for i/o handlers (see comm/do_*) */
|
||||
#define ACT_SERV 0
|
||||
#define ACT_CLIENT 1
|
||||
|
||||
/* functions (used by server and client) */
|
||||
int run_svc(char *rpath);
|
||||
void mini_printf(char *str, int fd);
|
||||
void set_signals(int action);
|
||||
void usage(char *banner, char *stext);
|
||||
|
||||
int do_svc_name(int sock2, char *svc, int action);
|
||||
int do_change_status(char *svc, char *status, pid_t *pid, int sock2, int action);
|
||||
char do_result(int sock2, char *value);
|
||||
|
||||
/* core functions */
|
||||
void do_reboot(int signal);
|
||||
void panic(void);
|
||||
void sig_child(int signal);
|
||||
|
||||
/* client / message functions */
|
||||
int msg_svc_on_off(char *svc, char action);
|
||||
int msg_change_status(char *svc, char status, pid_t pid);
|
||||
int begin_msg(char cmd);
|
||||
|
||||
/* client functions */
|
||||
pid_t respawn_svc(char *abspath);
|
||||
char **read_file(char *file);
|
||||
void sig_terminate(int signal);
|
||||
|
||||
/* generic */
|
||||
void execute_sth(char *basename);
|
||||
int path_append(char *path, char *append);
|
||||
int path_absolute(char *relpath, char *buf, size_t size);
|
||||
int openreadclose(char *filename, char **where);
|
||||
char *strip_final_newline(char *str);
|
||||
int file_exists(char *filename);
|
||||
|
||||
/* util */
|
||||
int msg_reboot(char cmd);
|
||||
void print_errno(char *text);
|
||||
|
||||
/* os-functions */
|
||||
void cinit_reboot(void);
|
||||
void cinit_halt(void);
|
||||
void cinit_poweroff(void);
|
||||
|
||||
#endif /* _CINIT_H */
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Communication defines
|
||||
*/
|
||||
|
||||
#ifndef CINIT_COMM_HEADER
|
||||
#define CINIT_COMM_HEADER
|
||||
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
|
||||
/***********************************************************************
|
||||
* Commands the clients may issue to us
|
||||
* maximum number of commands: 2^8 = 256
|
||||
*/
|
||||
enum commands {
|
||||
CMD_START_SVC=1, /* the client wants US to start a service */
|
||||
CMD_START_SVC_ONLY, /* start this service without dependencies */
|
||||
CMD_STOP_SVC, /* stop svc and all svcs that need it */
|
||||
CMD_STOP_SVC_ONLY, /* we should stop _only_ this service */
|
||||
CMD_STOP_SVC_WANTS, /* stop svc, all svcs that need or want it */
|
||||
CMD_CHG_STAT, /* the client reports a status change */
|
||||
CMD_RESCUE, /* we should start the rescue mode */
|
||||
CMD_HALT, /* halt the system */
|
||||
CMD_REBOOT, /* reboot the system */
|
||||
CMD_POWEROFF, /* poweroff the system */
|
||||
CMD_WBOOT, /* shutdown and restart everything */
|
||||
CMD_INFO /* send information about that service */
|
||||
};
|
||||
|
||||
/* old
|
||||
RT_ERR_COMM, * communication failed *
|
||||
RT_ERR, * service starting failed *
|
||||
RT_UNSPEC, * some kind of error, unspecified *
|
||||
RT_SUCCESS, * successfully started: respawning or once *
|
||||
RT_SVC_FAILED, * tried earlier, service failed, won't retry *
|
||||
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* messages from the client
|
||||
* Prefix: qst_ (question)
|
||||
*/
|
||||
struct msg_client {
|
||||
pid_t pid; /* pid of the telling client */
|
||||
char cmd; /* which cmd is issued to us */
|
||||
char status; /* status of the service */
|
||||
char svc[PATH_MAX]; /* name of the service */
|
||||
char svc_orig[PATH_MAX]; /* the service, which wants to start us */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* messages from the server
|
||||
* Prefix: asw_ (answer)
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* return short status
|
||||
*/
|
||||
struct asw_sstatus {
|
||||
long mtype;
|
||||
char status;
|
||||
char msg[PATH_MAX];
|
||||
};
|
||||
|
||||
#endif
|
||||
33
software/cinit/browse_source/cinit-0.3pre6/src/include/ipc.h
Normal file
33
software/cinit/browse_source/cinit-0.3pre6/src/include/ipc.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Prototypes for ipc handler
|
||||
*/
|
||||
|
||||
#ifndef CINIT_IPC_HEADER
|
||||
#define CINIT_IPC_HEADER
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions: in server
|
||||
*/
|
||||
int cinit_ipc_init(void); /* init in init */
|
||||
int cinit_ipc_listen(void); /* listen in init */
|
||||
int cinit_ipc_sclose(void); /* fork of cinit come from outside! */
|
||||
int cinit_ipc_ssend(void *data); /* send to a client from the server */
|
||||
void cinit_ipc_destroy(void); /* destroy ipc handler in cinit */
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions: in clients
|
||||
*/
|
||||
int cinit_ipc_logon(void); /* logon to init (client init) */
|
||||
int cinit_ipc_connect(void); /* connect to init */
|
||||
int cinit_ipc_csend(void *data); /* send to the server from a client */
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions: shared
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
include/cinit.h
|
||||
include/config.h
|
||||
include/ipc.h
|
||||
include/messages.h
|
||||
include/os.h
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
*/
|
||||
|
||||
#ifndef _CINIT_MSG_H
|
||||
#define _CINIT_MSG_H
|
||||
|
||||
/* version */
|
||||
#define CINIT_VERSION "cinit-" VERSION
|
||||
#define MSG_BOOTING CINIT_VERSION ": Booting from "
|
||||
|
||||
#define MSG_DP ": "
|
||||
|
||||
/* Messages to the outside */
|
||||
#define MSG_BIND "bind"
|
||||
#define MSG_CONNECT "connect"
|
||||
#define MSG_FCNTL "fcntl"
|
||||
#define MSG_KILLBILL "sigkill"
|
||||
#define MSG_LISTEN "listen"
|
||||
#define MSG_SOCKET "socket"
|
||||
#define MSG_TERMKILL "sigterm"
|
||||
#define MSG_USAGE_1 ": fast executing, small and simple init "
|
||||
#define MSG_USAGE_2 "with support for profiles\n"
|
||||
#define MSG_USAGE_3 "\nError: cinit must be started as PID 1.\n"
|
||||
#define MSG_USAGE MSG_USAGE_1 MSG_USAGE_2 MSG_USAGE_3
|
||||
#define MSG_ERR_FORK "fork"
|
||||
#define MSG_ERR_IO "i/o"
|
||||
#define MSG_ERR_OPEN "open"
|
||||
#define MSG_ERR_PIPE "pipe"
|
||||
#define MSG_ERR_READ "read"
|
||||
#define MSG_ERR_EXECVE "execve"
|
||||
#define MSG_ERR_ALLOC "memory allocation"
|
||||
#define MSG_ERR_UMOUNT "umount"
|
||||
#define MSG_ERR_MOUNT "mount"
|
||||
#define MSG_NOT_DIR "not a directory"
|
||||
#define MSG_CHDIR "chdir"
|
||||
#define MSG_READLINK "readlink"
|
||||
#define MSG_ERR_ADD_SVC "Adding service failed"
|
||||
#define MSG_CMD_UNKNOWN "Unknown command"
|
||||
|
||||
#define MSG_ERR_DEPS "Too many dependencies"
|
||||
#define MSG_ERR_ACCEPT "accept"
|
||||
#define MSG_ERR_WAITPID "waitpid"
|
||||
#define MSG_ERR_POLL "poll"
|
||||
#define MSG_ERR_MODIFY "modify list failed"
|
||||
#define MSG_ERR_COMM "Communication failed"
|
||||
|
||||
#define MSG_ERR_LESS_ARGS "Too less arguments!"
|
||||
#define MSG_ERR_BAD_ARGS "Wrong arguments / parameter"
|
||||
#define MSG_ERR_ARGS_LEN "Wrong parameter length"
|
||||
|
||||
#define LOG_SVC_STOPED "Service stoped"
|
||||
#define LOG_SVC_ONCE "Started once"
|
||||
#define LOG_SVC_RESPAWN "Respawns now"
|
||||
#define LOG_NEED_FAIL "One or more need failed"
|
||||
#define LOG_SVC_FAILED "Service already failed, not starting."
|
||||
#define LOG_SVC_NOTEXIST "Service does not exist"
|
||||
|
||||
#define MSG_START_SVC "Starting "
|
||||
#define MSG_STOP_SVC "Stoping "
|
||||
#define MSG_EXEC_FAILED "Failed to execute "
|
||||
|
||||
#define MSG_POWER_OFF "Powering off..."
|
||||
#define MSG_HALT "Halting system ..."
|
||||
#define MSG_REBOOT "Rebooting ..."
|
||||
#define MSG_RESCUE "Switching to rescue mode ..."
|
||||
#define MSG_UPDATE "Updating cinit ..."
|
||||
#define MSG_HOT_REBOOT "Hot reboot in progress ..."
|
||||
|
||||
#define MSG_SHOULD_NOT_HAPPEN "This should not happen, I do not know what todo!"
|
||||
|
||||
/* DEBUG */
|
||||
#ifdef DEBUG
|
||||
# define D_PRINTF(x) ( printf("[%s:%d]: %s\n",__FILE__,__LINE__,x) )
|
||||
#else
|
||||
# define D_PRINTF(x) if(0)
|
||||
#endif
|
||||
|
||||
/* macros */
|
||||
#define SERVICE_LOG(svc,message) { \
|
||||
mini_printf(svc,1); \
|
||||
mini_printf(MSG_DP,1); \
|
||||
mini_printf(message,1); \
|
||||
mini_printf("\n",1); \
|
||||
}
|
||||
#define LOG(s) { \
|
||||
mini_printf(s,1); \
|
||||
mini_printf("\n",1); \
|
||||
}
|
||||
#define P_START_SERVICE(name) { mini_printf(MSG_START_SVC,1); mini_printf(name,1); mini_printf("\n",1); }
|
||||
#define P_EXEC_FAILED(name) { mini_printf(MSG_EXEC_FAILED,1); mini_printf(name,1); mini_printf("\n",1); }
|
||||
|
||||
/* NEW (clean) Service status: Messages to the outside */
|
||||
#define MSG_INTRO_OK "[SUCCESS] "
|
||||
#define MSG_INTRO_FAIL "[FAILED] "
|
||||
#define MSG_INTRO_CINIT "[CINIT] "
|
||||
#define MSG_INTRO_RESPAWN "[RESPAWN] "
|
||||
#define MSG_INTRO_SVC "[SERVICE] "
|
||||
|
||||
#define MSG_SVC_FORK "fork() failed"
|
||||
#define MSG_SVC_NEED_FAIL MSG_INTRO_FAIL "Needs failed for service"
|
||||
#define MSG_SVC_FAIL MSG_INTRO_FAIL "Service failed!"
|
||||
#define MSG_SVC_OK MSG_INTRO_OK "Service successfully executed."
|
||||
#define MSG_SVC_RESTART MSG_INTRO_RESPAWN "Restarting service."
|
||||
#define MSG_SVC_START "Starting service."
|
||||
|
||||
#define MSG_TREE_EXEC MSG_INTRO_CINIT "Execution of reverse service tree\n"
|
||||
//#define MSG_GEN_TREE MSG_INTRO_CINIT "Generating service tree...\n"
|
||||
|
||||
/* general errors */
|
||||
#define MSG_GETCWD "Getcwd failed! Your system is most likely broken!"
|
||||
|
||||
#endif /* _CINIT_MSG_H */
|
||||
20
software/cinit/browse_source/cinit-0.3pre6/src/include/os.h
Normal file
20
software/cinit/browse_source/cinit-0.3pre6/src/include/os.h
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* os specific functions
|
||||
*/
|
||||
|
||||
#ifndef CINIT_OS_HEADER
|
||||
#define CINIT_OS_HEADER
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions
|
||||
*/
|
||||
void cinit_halt(void);
|
||||
void cinit_poweroff(void);
|
||||
void cinit_reboot(void);
|
||||
|
||||
#endif
|
||||
128
software/cinit/browse_source/cinit-0.3pre6/src/include/svc.h
Normal file
128
software/cinit/browse_source/cinit-0.3pre6/src/include/svc.h
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006,2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Start the service tree we created
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CINIT_SVC_H
|
||||
#define _CINIT_SVC_H
|
||||
|
||||
/* includes */
|
||||
#include <sys/types.h> /* pid_t */
|
||||
#include "config.h" /* paths, socket options, etc. */
|
||||
|
||||
/* service list */
|
||||
struct listitem {
|
||||
struct listitem *prev; /* previous item */
|
||||
struct listitem *next; /* next item */
|
||||
|
||||
char *abs_path; /* name of service */
|
||||
long int status; /* current status */
|
||||
pid_t pid; /* pid of service / respawn watcher */
|
||||
|
||||
|
||||
struct dep *wanted; /* list of services that want this service */
|
||||
struct dep *needed; /* list of services that need this service */
|
||||
|
||||
struct dep *wants; /* list of services that this service wants */
|
||||
struct dep *needs; /* list of services that this service needs */
|
||||
};
|
||||
|
||||
/* list of dependencies */
|
||||
struct dep {
|
||||
struct dep *prev;
|
||||
struct dep *next;
|
||||
struct listitem *svc;
|
||||
};
|
||||
|
||||
/* variables */
|
||||
extern struct dep *svc_init; /* the services to start */
|
||||
extern struct listitem *svc_list; /* the list of services */
|
||||
|
||||
/* list functions */
|
||||
struct listitem *list_insert(char *path, int status);
|
||||
int list_delete(char *path);
|
||||
int list_modify(char *path, int new_status, pid_t new_pid);
|
||||
struct listitem *list_search(char *path);
|
||||
struct listitem *list_search_pid(pid_t pid);
|
||||
int list_display_all();
|
||||
|
||||
|
||||
/* service */
|
||||
struct listitem *svc_create(char *svc);
|
||||
struct listitem *gen_svc_tree(char *svc);
|
||||
int check_add_deps(struct listitem *svc, int type);
|
||||
void dep_entry_add(struct dep **list, struct dep *new);
|
||||
struct dep *dep_entry_del(struct dep *del);
|
||||
int tree_exec(struct dep *start);
|
||||
int svc_set_status(struct listitem *li, int status);
|
||||
int svc_should_respawn(struct listitem *li);
|
||||
int svc_needs_status(struct listitem *li);
|
||||
int dep_needs_wants_add(struct dep **list, struct listitem *svc, int type);
|
||||
struct dep *dep_create(struct listitem *svc);
|
||||
void svc_success(struct listitem *li);
|
||||
void svc_fail(struct listitem *li);
|
||||
void svc_report_status(char *svc, char *msg, char *err);
|
||||
void svc_start(struct listitem *li);
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* to decide whether to operate on needs or wants
|
||||
*/
|
||||
enum dep_types {
|
||||
DEP_WANTS,
|
||||
DEP_NEEDS
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* status of a service and return codes - errors and success
|
||||
*/
|
||||
enum svc_status_old {
|
||||
ST_TMPNOW=1, /* the client is now starting the service NEEDED??? */
|
||||
ST_NOTEXIST, /* service does not exist */
|
||||
|
||||
ST_NEED_FAIL, /* failed to start a need for this service */
|
||||
ST_FAIL, /* failed to start service */
|
||||
|
||||
ST_OFF, /* service is off */
|
||||
ST_OFF_ALL, /* service and those that need it are off */
|
||||
ST_OFF_ALL_F, /* same, but something failed */
|
||||
ST_OFF_WANTS, /* service + those that need or want it are off */
|
||||
ST_OFF_WANTS_F, /* same, but something failed */
|
||||
|
||||
ST_TMP, /* currently working on it */
|
||||
ST_ONCE, /* executed once */
|
||||
ST_RESPAWN /* running and respawning */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* The real status types a service may have (ignore above)
|
||||
* We have 32 Bits, we should use them ;-)
|
||||
*/
|
||||
enum svc_status {
|
||||
/* first define basics */
|
||||
ST_SH_ONCE = 0x1, /* service SHould be started once */
|
||||
ST_SH_RESPAWN = 0x2, /* service SHould respawn */
|
||||
ST_ONCE_OK = 0x4, /* service was successfully started once */
|
||||
ST_ONCE_FAIL = 0x8, /* service failed to start */
|
||||
ST_RESPAWNING = 0x10, /* service is respawning */
|
||||
ST_NEED_FAILD = 0x20, /* this service is not started, need failed */
|
||||
ST_IN_LIST = 0x40, /* this service is being started (= in list) */
|
||||
ST_BAD_ERR = 0x80, /* some kind of error that SHOULD NOT happen */
|
||||
ST_ONCE_RUN = 0x100 /* the once process is currently running */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Possibilities the needs of a service may have
|
||||
*/
|
||||
enum svc_needs_status {
|
||||
SNS_NEEDS_STARTED = 1, /* all needs are started. We may start, too */
|
||||
SNS_NEEDS_FAILED, /* one ore more needs failed */
|
||||
SNS_NEEDS_UNFINISHED /* one ore more needs are not yet started */
|
||||
};
|
||||
#endif /* _CINIT_SVC_H */
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
cinit/src/ipc/msgq: About this msqg implementation
|
||||
===================================================
|
||||
Nico Schottelius <nico-linux-cinit__@__schottelius.org>
|
||||
0.1, Initial Version from 2006-08-04
|
||||
:Author Initials: NS
|
||||
|
||||
Intro here
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
cinit opens a
|
||||
|
||||
Files
|
||||
-----
|
||||
- README.text: This file
|
||||
- cinit_init_ipc.c: Init
|
||||
msgq.h
|
||||
objects
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Listen to messages
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h> /* ftok */
|
||||
#include <sys/msg.h> /* msgget */
|
||||
|
||||
#include "config.h"
|
||||
#include "msgq.h"
|
||||
|
||||
int cinit_ipc_listen(void)
|
||||
{
|
||||
int tmp;
|
||||
key_t k_in, k_out;
|
||||
int mq_in = 0, mq_out = 0;
|
||||
int tmp = 0;
|
||||
|
||||
struct msg_client m_client;
|
||||
struct msg_server m_serv;
|
||||
|
||||
/* generiere nen schluessel */
|
||||
k_in = ftok(IPC_KEY,IPC_IN);
|
||||
k_out = ftok(IPC_KEY,IPC_OUT);
|
||||
|
||||
if(k_in == -1 || k_out == -1) {
|
||||
perror("ftok");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* neue queue */
|
||||
mq_in = msgget(k_in,0666 | IPC_CREAT);
|
||||
mq_out = msgget(k_out,0666 | IPC_CREAT);
|
||||
|
||||
if(mq_in == -1 || mq_out == -1) {
|
||||
perror("msgget");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* wrong tabsto ;-) */
|
||||
while (1) {
|
||||
tmp = msgrcv(mq_in,&m_client,(sizeof m_client),0,0);
|
||||
|
||||
if(tmp == -1) {
|
||||
perror("msgrcv");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("pid: %d, m_client: %s\n",m_client.pid,m_client.text);
|
||||
|
||||
/* use pid as the message type */
|
||||
m_serv.mtype = (long) m_client.pid;
|
||||
strcpy(m_serv.text,"Alles ok\n");
|
||||
|
||||
tmp = msgsnd(mq_out, &m_serv, sizeof(m_serv), 0);
|
||||
|
||||
if(tmp == -1) {
|
||||
perror("msgsnd");
|
||||
exit(1);
|
||||
}
|
||||
} /* while */
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Listen to messages
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h> /* ftok */
|
||||
#include <sys/msg.h> /* msgget */
|
||||
|
||||
#include "config.h"
|
||||
#include "msgq.h"
|
||||
|
||||
int cinit_ipc_logon(void)
|
||||
{
|
||||
int tmp;
|
||||
key_t k_in, k_out;
|
||||
int mq_in = 0, mq_out = 0;
|
||||
int tmp = 0;
|
||||
|
||||
struct msg_client m_client;
|
||||
struct msg_server m_serv;
|
||||
|
||||
/* generiere nen schluessel: andersrum als im Server */
|
||||
k_in = ftok(IPC_KEY,IPC_OUT);
|
||||
k_out = ftok(IPC_KEY,IPC_IN);
|
||||
|
||||
if(k_in == -1 || k_out == -1) {
|
||||
print_errno(MSG_MSGQ_FTOK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* neue queue */
|
||||
mq_in = msgget(k_in,0666 | IPC_CREAT);
|
||||
mq_out = msgget(k_out,0666 | IPC_CREAT);
|
||||
|
||||
if(mq_in == -1 || mq_out == -1) {
|
||||
print_errno(MSG_MSGQ_MSGGET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
printf("pid: %d, m_client: %s\n",m_client.pid,m_client.text);
|
||||
|
||||
/* use pid as the message type */
|
||||
m_serv.mtype = (long) m_client.pid;
|
||||
strcpy(m_serv.text,"Alles ok\n");
|
||||
|
||||
tmp = msgsnd(mq_out, &m_serv, sizeof(m_serv), 0);
|
||||
|
||||
if(tmp == -1) {
|
||||
perror("msgsnd");
|
||||
exit(1);
|
||||
}
|
||||
} /* while */
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Destory ipc mechanism, cinit is gonna die soon.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/msg.h> /* msgget */
|
||||
#include <stdio.h> /* NULL */
|
||||
|
||||
#include "msgq.h" /* mq_in, mq_out */
|
||||
#include "cinit.h" /* print_errno */
|
||||
|
||||
void cinit_ipc_destroy(void)
|
||||
{
|
||||
if(msgctl(mq_in,IPC_RMID,NULL) == -1) {
|
||||
print_errno(MSG_MSGQ_DESTROY); /* print warning, continue */
|
||||
}
|
||||
if(msgctl(mq_out,IPC_RMID,NULL) == -1) {
|
||||
print_errno(MSG_MSGQ_DESTROY); /* print warning, continue */
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Create new queues: One for recieving, one for sending
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h> /* ftok */
|
||||
#include <sys/msg.h> /* msgget */
|
||||
#include <stdio.h> /* msgget */
|
||||
|
||||
#include "cinit.h"
|
||||
#include "config.h"
|
||||
#include "msgq.h"
|
||||
|
||||
int cinit_ipc_init(void)
|
||||
{
|
||||
key_t k_tmp;
|
||||
|
||||
/* to_server */
|
||||
k_tmp = ftok(MSGQ_PATHNAME,MSGQ_TO_SERVER);
|
||||
if(k_tmp == -1) {
|
||||
print_errno(MSG_MSGQ_FTOK);
|
||||
return 0;
|
||||
}
|
||||
mq_in = msgget(k_tmp,MSGQ_PERMS | IPC_CREAT);
|
||||
if(mq_in == -1) {
|
||||
print_errno(MSG_MSGQ_MSGGET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* to_client */
|
||||
k_tmp = ftok(MSGQ_PATHNAME,MSGQ_TO_CLIENT);
|
||||
if(k_tmp == -1) {
|
||||
perror(MSG_MSGQ_FTOK);
|
||||
return 0;
|
||||
}
|
||||
mq_out = msgget(k_tmp,MSGQ_PERMS | IPC_CREAT);
|
||||
if(mq_out == -1) {
|
||||
perror(MSG_MSGQ_MSGGET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Listen to messages
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h> /* ftok */
|
||||
#include <sys/msg.h> /* msgget */
|
||||
#include <stdio.h> /* perror */
|
||||
|
||||
#include "config.h"
|
||||
#include "msgq.h"
|
||||
|
||||
int cinit_ipc_listen(void)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
struct msg_client m_client;
|
||||
|
||||
while (1) {
|
||||
/* FIXME: change msg structure */
|
||||
tmp = msgrcv(mq_in,&m_client,(sizeof m_client),0,0);
|
||||
|
||||
if(tmp == -1) {
|
||||
perror(MSG_MSGQ_MSGRCV);
|
||||
}
|
||||
|
||||
printf("pid: %d, m_client\n",m_client.pid);
|
||||
|
||||
/* use pid as the message type
|
||||
m_serv.mtype = (long) m_client.pid;
|
||||
strcpy(m_serv.text,"Alles ok\n");
|
||||
|
||||
tmp = msgsnd(mq_out, &m_serv, sizeof(m_serv), 0);
|
||||
|
||||
if(tmp == -1) {
|
||||
perror("msgsnd");
|
||||
return 0;
|
||||
} */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Listen to messages
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h> /* ftok */
|
||||
#include <sys/msg.h> /* msgget */
|
||||
|
||||
#include "config.h"
|
||||
#include "msgq.h"
|
||||
|
||||
int cinit_ipc_listen(void)
|
||||
{
|
||||
int tmp;
|
||||
key_t k_in, k_out;
|
||||
int mq_in = 0, mq_out = 0;
|
||||
int tmp = 0;
|
||||
|
||||
struct msg_client m_client;
|
||||
struct msg_server m_serv;
|
||||
|
||||
/* generiere nen schluessel */
|
||||
k_in = ftok(IPC_KEY,IPC_IN);
|
||||
k_out = ftok(IPC_KEY,IPC_OUT);
|
||||
|
||||
if(k_in == -1 || k_out == -1) {
|
||||
perror("ftok");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* neue queue */
|
||||
mq_in = msgget(k_in,0666 | IPC_CREAT);
|
||||
mq_out = msgget(k_out,0666 | IPC_CREAT);
|
||||
|
||||
if(mq_in == -1 || mq_out == -1) {
|
||||
perror("msgget");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* wrong tabsto ;-) */
|
||||
while (1) {
|
||||
tmp = msgrcv(mq_in,&m_client,(sizeof m_client),0,0);
|
||||
|
||||
if(tmp == -1) {
|
||||
perror("msgrcv");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("pid: %d, m_client: %s\n",m_client.pid,m_client.text);
|
||||
|
||||
/* use pid as the message type */
|
||||
m_serv.mtype = (long) m_client.pid;
|
||||
strcpy(m_serv.text,"Alles ok\n");
|
||||
|
||||
tmp = msgsnd(mq_out, &m_serv, sizeof(m_serv), 0);
|
||||
|
||||
if(tmp == -1) {
|
||||
perror("msgsnd");
|
||||
exit(1);
|
||||
}
|
||||
} /* while */
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Listen to messages
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h> /* ftok */
|
||||
#include <sys/msg.h> /* msgget */
|
||||
|
||||
#include "config.h"
|
||||
#include "cinit.h" /* print_errno */
|
||||
#include "msgq.h"
|
||||
|
||||
int cinit_ipc_logon(void)
|
||||
{
|
||||
key_t k_in, k_out; /* FIXME: remove one variable */
|
||||
|
||||
/* generiere nen schluessel: andersrum als im Server */
|
||||
k_in = ftok(MSGQ_PATHNAME,MSGQ_TO_CLIENT);
|
||||
k_out = ftok(MSGQ_PATHNAME,MSGQ_TO_SERVER);
|
||||
|
||||
if(k_in == -1 || k_out == -1) {
|
||||
print_errno(MSG_MSGQ_FTOK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* neue queue */
|
||||
mq_in = msgget(k_in,0666 | IPC_CREAT);
|
||||
mq_out = msgget(k_out,0666 | IPC_CREAT);
|
||||
|
||||
if(mq_in == -1 || mq_out == -1) {
|
||||
print_errno(MSG_MSGQ_MSGGET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Close the ressources from the server, clean state for forks.
|
||||
*
|
||||
*/
|
||||
|
||||
int cinit_ipc_sclose(void)
|
||||
{
|
||||
return 1; /* nothing to do when using message queues */
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* (c) 2006 Nico Schottelius (nico-linux-cinit //@\\ schottelius.org)
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#ifndef CINIT_IPC_HEADER
|
||||
#define CINIT_IPC_HEADER
|
||||
|
||||
#include <comm.h> /* structures */
|
||||
|
||||
/***********************************************************************
|
||||
* configuration
|
||||
*/
|
||||
|
||||
#define MSGQ_PATHNAME "/bin/sh" /* should be on every *nix */
|
||||
#define MSGQ_TO_SERVER 'i' /* also for ftok */
|
||||
#define MSGQ_TO_CLIENT 'o' /* also for ftok */
|
||||
#define MSGQ_PERMS 0660 /* queue permissions */
|
||||
|
||||
/***********************************************************************
|
||||
* global variables
|
||||
*/
|
||||
int mq_in; /* input */
|
||||
int mq_out; /* output */
|
||||
|
||||
/***********************************************************************
|
||||
* structures
|
||||
*/
|
||||
|
||||
/* messages _from_ the client _to_ the server */
|
||||
struct msgq_client {
|
||||
long mtype;
|
||||
pid_t pid;
|
||||
struct msg_client msg;
|
||||
};
|
||||
|
||||
/* messages _from_ the server _to_ the client */
|
||||
struct msgq_server_short {
|
||||
long mtype;
|
||||
struct asw_sstatus answer;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Messages
|
||||
*/
|
||||
|
||||
#define MSG_MSGQ_FTOK "ftok"
|
||||
#define MSG_MSGQ_MSGGET "msgget"
|
||||
#define MSG_MSGQ_MSGRCV "msgrcv"
|
||||
#define MSG_MSGQ_DESTROY "msgq-destroy"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
ipc/current/cinit_ipc_init.o
|
||||
ipc/current/cinit_ipc_listen.o
|
||||
ipc/current/cinit_ipc_sclose.o
|
||||
ipc/current/cinit_ipc_destroy.o
|
||||
ipc/current/cinit_ipc_logon.o
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* (c) 2005, 2006 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* cinit.c
|
||||
* part of cLinux/cinit
|
||||
*/
|
||||
|
||||
/* *stat() */
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* open */
|
||||
#include <fcntl.h>
|
||||
|
||||
/* siggnal */
|
||||
#include <signal.h>
|
||||
|
||||
/* PATH_MAX */
|
||||
#include <limits.h>
|
||||
|
||||
/* str* */
|
||||
#include <string.h>
|
||||
|
||||
/* sockets */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/***********************************************************************
|
||||
* create a socket, when we recieved a signal
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
struct pollfd plist;
|
||||
char *initdir;
|
||||
|
||||
list = NULL; /* list of services is empty currently */
|
||||
initdir = CINIT_INIT; /* default init dir */
|
||||
|
||||
cpid = getpid();
|
||||
if(cpid != 1) {
|
||||
usage(MSG_USAGE,MSG_NOT_ONE);
|
||||
}
|
||||
|
||||
set_signals(ACT_SERV); /* set signal handlers */
|
||||
|
||||
/* read args, profile support */
|
||||
while(argc > 1) {
|
||||
if( !strncmp(PROFILE, argv[argc-1], strlen(PROFILE)) ) {
|
||||
initdir = (char *) malloc(
|
||||
strlen(CINIT_DIR) +
|
||||
strlen(&argv[argc-1][strlen(PROFILE)]) + 2
|
||||
);
|
||||
if(initdir == NULL) {
|
||||
panic();
|
||||
}
|
||||
strcpy(initdir,CINIT_DIR);
|
||||
strcat(initdir,SLASH);
|
||||
strcat(initdir,&argv[argc-1][strlen(PROFILE)]);
|
||||
break;
|
||||
}
|
||||
argc--;
|
||||
}
|
||||
|
||||
/* tell the world we are there FIXME: do we really need three calls? */
|
||||
mini_printf(MSG_CINIT,1); mini_printf(initdir,1); mini_printf("\n",1);
|
||||
|
||||
if( chdir(CINIT_INIT) == -1) {
|
||||
perror(MSG_CHDIR);
|
||||
panic();
|
||||
}
|
||||
|
||||
/******************** TMPDIR **********************/
|
||||
if( mount(C_TMPMOUNT,CINIT_TMNT,C_TMPFS,0,NULL) == -1 ) {
|
||||
perror(MSG_ERR_MOUNT);
|
||||
panic();
|
||||
}
|
||||
|
||||
/******************** begin socket **********************/
|
||||
sock = socket(AF_UNIX,SOCK_STREAM,0); /* create socket */
|
||||
if( sock == -1 ) {
|
||||
perror(MSG_SOCKET);
|
||||
panic();
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr) ); /* clear addr */
|
||||
strcpy(addr.sun_path, CINIT_SOCK);
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
if(bind(sock,(struct sockaddr *)&addr,sizeof(addr)) == -1) {
|
||||
perror(MSG_BIND);
|
||||
panic();
|
||||
}
|
||||
|
||||
/* start listening */
|
||||
if(listen(sock,SOCK_QUEUE) == -1) {
|
||||
perror(MSG_LISTEN);
|
||||
panic();
|
||||
}
|
||||
|
||||
/* start init or profile */
|
||||
run_init_svc(initdir);
|
||||
|
||||
/* free, if we malloc()ed before */
|
||||
if(initdir != CINIT_INIT) {
|
||||
free(initdir);
|
||||
}
|
||||
|
||||
/* our life is polling a socket */
|
||||
plist.fd = sock;
|
||||
plist.events = POLLIN | POLLPRI;
|
||||
while(1) {
|
||||
if(poll(&plist, 1, -1) != -1) {
|
||||
if( (plist.revents & POLLIN) == POLLIN ||
|
||||
(plist.revents & POLLPRI) == POLLPRI) {
|
||||
sigio(sock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* cinit
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* handle client requests
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/***********************************************************************
|
||||
* sigio: client handling
|
||||
*/
|
||||
|
||||
/* we are called, if one or _more_ connections are waiting */
|
||||
void sigio(int socket)
|
||||
{
|
||||
int tmp, nsock;
|
||||
char buf[PATH_MAX+1], status;
|
||||
struct listitem *list_tmp;
|
||||
pid_t pid;
|
||||
|
||||
while ( (nsock = accept(socket,(struct sockaddr *) NULL,
|
||||
(socklen_t *) NULL)) != -1) {
|
||||
|
||||
if( read(nsock,&buf[0],1) == -1) {
|
||||
perror(MSG_ERR_READ);
|
||||
close(nsock);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(buf[0]) {
|
||||
|
||||
/********************** START SERVICE *******************/
|
||||
case CMD_START_SVC:
|
||||
tmp = do_svc_name(nsock,buf,ACT_SERV);
|
||||
if(!tmp) break;
|
||||
|
||||
buf[tmp] = 0;
|
||||
list_tmp = list_search(buf);
|
||||
|
||||
if(list_tmp != NULL) { /* service already exists, return status */
|
||||
status = list_tmp->status;
|
||||
do_result(nsock,&status);
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = list_insert(buf,ST_TMP); /* add service */
|
||||
if(!tmp) { /* failed */
|
||||
LOG(MSG_ERR_ADD_SVC);
|
||||
status = ST_FAIL;
|
||||
} else {
|
||||
status = RT_TMPNOW;
|
||||
}
|
||||
do_result(nsock,&status);
|
||||
break;
|
||||
|
||||
/********************** STOP (RESPAWNING) *******************/
|
||||
case CMD_STOP_SVC:
|
||||
tmp = do_svc_name(nsock,buf,ACT_SERV);
|
||||
if(!tmp) break;
|
||||
buf[tmp] = 0;
|
||||
list_tmp = list_search(buf);
|
||||
|
||||
/* FIXME:
|
||||
- handle off
|
||||
- handle switching off once services
|
||||
- perhaps remove old cinit code, which has respawing childs
|
||||
*/
|
||||
|
||||
if(list_tmp != NULL) { /* service exists */
|
||||
if(list_tmp->status == ST_RESPAWN) {
|
||||
/* kill cinit watcher, which kills the real process */
|
||||
kill(list_tmp->pid,SIGTERM);
|
||||
|
||||
/* wait for watcher to terminate */
|
||||
waitpid(list_tmp->pid,&tmp,0);
|
||||
}
|
||||
|
||||
status = ST_OFF;
|
||||
if(!list_modify(buf,status,list_tmp->pid)) {
|
||||
status = ST_FAIL;
|
||||
} else { /* return status */
|
||||
status = list_tmp->status;
|
||||
}
|
||||
} else { /* no service there */
|
||||
status = RT_NOTEXIST;
|
||||
}
|
||||
do_result(nsock,&status);
|
||||
break;
|
||||
|
||||
/********************** CHANGE SERVICE STATUS *******************/
|
||||
case CMD_CHG_STATUS:
|
||||
tmp = do_change_status(buf,&status,&pid,nsock,ACT_SERV);
|
||||
if(!tmp) break;
|
||||
buf[tmp] = 0; /* terminate buf */
|
||||
|
||||
if(!list_modify(buf,status,pid)) {
|
||||
SERVICE_LOG(buf,MSG_ERR_MODIFY);
|
||||
status = 0;
|
||||
}
|
||||
do_result(nsock,&status);
|
||||
break;
|
||||
|
||||
/********************** SPECIAL ACTIONS *******************/
|
||||
case CMD_REBOOT:
|
||||
sig_reboot(SIGHUP);
|
||||
break;
|
||||
case CMD_POWEROFF:
|
||||
sig_reboot(SIGTERM);
|
||||
break;
|
||||
case CMD_HALT:
|
||||
sig_reboot(SIGUSR1);
|
||||
break;
|
||||
case CMD_RESCUE:
|
||||
sig_reboot(SIGUSR2);
|
||||
break;
|
||||
case CMD_UPDATE:
|
||||
sig_reboot(SIGCONT);
|
||||
break;
|
||||
default:
|
||||
LOG(MSG_CMD_UNKNOWN);
|
||||
break;
|
||||
}
|
||||
close(nsock);
|
||||
}
|
||||
|
||||
/* hier kommt man haeufiger herein, interrupted system call */
|
||||
if( errno != EAGAIN && errno != EINTR) { /* report, but don't panic */
|
||||
perror(MSG_ERR_ACCEPT);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
core/build_argv.o
|
||||
core/cinit.o
|
||||
core/panic.o
|
||||
core/run_init_svc.o
|
||||
core/set_signals.o
|
||||
core/do_reboot.o
|
||||
core/sig_child.o
|
||||
generic/execute_sth.o
|
||||
generic/file_exists.o
|
||||
generic/mini_printf.o
|
||||
generic/path_absolute.o
|
||||
generic/path_append.o
|
||||
generic/print_errno.o
|
||||
generic/openreadclose.o
|
||||
generic/strip_final_newline.o
|
||||
ipc/current/cinit_ipc_init.o
|
||||
ipc/current/cinit_ipc_listen.o
|
||||
ipc/current/cinit_ipc_sclose.o
|
||||
ipc/current/cinit_ipc_destroy.o
|
||||
ipc/current/cinit_ipc_logon.o
|
||||
os/current/halt.o
|
||||
os/current/poweroff.o
|
||||
os/current/reboot.o
|
||||
os/current/halt.o
|
||||
os/current/poweroff.o
|
||||
os/current/reboot.o
|
||||
os/current/halt.o
|
||||
os/current/poweroff.o
|
||||
os/current/reboot.o
|
||||
svc/gen_svc_tree.o
|
||||
svc/list_delete.o
|
||||
svc/list_display_all.o
|
||||
svc/list_insert.o
|
||||
svc/list_modify.o
|
||||
svc/list_search.o
|
||||
svc/list_search_pid.o
|
||||
svc/svc_create.o
|
||||
svc/check_add_deps.o
|
||||
svc/dep_entry_add.o
|
||||
svc/dep_entry_del.o
|
||||
svc/tree_exec.o
|
||||
svc/svc_set_status.o
|
||||
svc/svc_should_respawn.o
|
||||
svc/svc_needs_status.o
|
||||
svc/dep_needs_wants_add.o
|
||||
svc/dep_create.o
|
||||
svc/svc_success.o
|
||||
svc/svc_report_status.o
|
||||
svc/svc_start.o
|
||||
svc/svc_fail.o
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* halt the system
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_halt(void)
|
||||
{
|
||||
reboot(RB_HALT);
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
os/current/halt.o
|
||||
os/current/poweroff.o
|
||||
os/current/reboot.o
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* poweroff
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_poweroff(void)
|
||||
{
|
||||
reboot(RB_POWEROFF);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* reboot the system
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_reboot(void)
|
||||
{
|
||||
reboot(RB_AUTOBOOT);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* How to halt the system
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_halt(void)
|
||||
{
|
||||
reboot(RB_HALT_SYSTEM);
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
os/current/halt.o
|
||||
os/current/poweroff.o
|
||||
os/current/reboot.o
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* poweroff the system
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_poweroff(void)
|
||||
{
|
||||
reboot(RB_POWER_OFF);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* reboot the system
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_reboot(void)
|
||||
{
|
||||
reboot(RB_AUTOBOOT);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* halt the system
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_halt(void)
|
||||
{
|
||||
reboot(RB_HALT);
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
os/current/halt.o
|
||||
os/current/poweroff.o
|
||||
os/current/reboot.o
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* poweroff
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_poweroff(void)
|
||||
{
|
||||
reboot(RB_HALT | RB_POWERDOWN);
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* reboot the system
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/reboot.h>
|
||||
|
||||
void cinit_reboot(void)
|
||||
{
|
||||
reboot(RB_AUTOBOOT);
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Pre calculate the service tree
|
||||
*/
|
||||
|
||||
/* FIXME: clean headers, check:
|
||||
* getcwd */
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include <stdlib.h> /* malloc */
|
||||
#include <string.h> /* strcpy */
|
||||
|
||||
#include "cinit.h" /* mini_printf */
|
||||
#include "messages.h"
|
||||
#include "svc.h"
|
||||
|
||||
int check_add_deps(struct listitem *svc, int type)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
char oldpath[PATH_MAX+1];
|
||||
struct dirent *tdirent;
|
||||
struct dep *deps = NULL;
|
||||
struct listitem *new_svc;
|
||||
DIR *d_tmp;
|
||||
|
||||
/* remember where we started */
|
||||
if(!getcwd(oldpath,PATH_MAX+1)) {
|
||||
print_errno(MSG_GETCWD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mini_printf("CAD::",1);
|
||||
mini_printf(svc->abs_path,1);
|
||||
mini_printf("\n",1);
|
||||
|
||||
/* Create path */
|
||||
strcpy(buf,svc->abs_path);
|
||||
if(type == DEP_NEEDS) {
|
||||
if(!path_append(buf,C_NEEDS)) return 0;
|
||||
} else {
|
||||
if(!path_append(buf,C_WANTS)) return 0;
|
||||
}
|
||||
|
||||
d_tmp = opendir(buf);
|
||||
if(d_tmp == NULL) {
|
||||
if(errno != ENOENT) {
|
||||
print_errno(buf);
|
||||
return 0;
|
||||
}
|
||||
return 1; /* it's fine when there's no dependencies */
|
||||
}
|
||||
|
||||
if(chdir(buf) == -1) { /* change to needs or wants */
|
||||
print_errno(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while((tdirent=readdir(d_tmp))!=NULL) {
|
||||
if(*(tdirent->d_name) == '.') continue; /* ignore .* */
|
||||
|
||||
/* skip non-working directories / broken links
|
||||
* path_absolute reports errors on failure */
|
||||
if(!path_absolute(tdirent->d_name,buf,PATH_MAX+1)) continue;
|
||||
|
||||
/* 1. create the service we depend on
|
||||
* 2. initialize its dependencies
|
||||
*/
|
||||
if(!(new_svc = gen_svc_tree(buf))) return 0;
|
||||
|
||||
/* We need ALL dependencies, as we are called only once
|
||||
* per service; no need to test that first!
|
||||
*
|
||||
* And the other service CANNOT know anything about us yet,
|
||||
* so we always add us to its list.
|
||||
*/
|
||||
|
||||
/* Dependencies:
|
||||
* - a.needs b; add b to the list of dependencies.
|
||||
* - a.needs b; add a to the list of needed by b.
|
||||
*
|
||||
* 1. check whether the dependency already exists
|
||||
* 2. otherwise add it
|
||||
* 3. do it once for needs, once for needed_by
|
||||
*/
|
||||
|
||||
/* create a dependency entry containing us */
|
||||
deps = dep_create(svc);
|
||||
if(!deps) return 0;
|
||||
|
||||
if(type == DEP_NEEDS) {
|
||||
dep_entry_add(&(new_svc->needed),deps);
|
||||
|
||||
/* second link */
|
||||
deps = dep_create(new_svc);
|
||||
if(!deps) return 0;
|
||||
dep_entry_add(&(svc->needs),deps);
|
||||
} else {
|
||||
dep_entry_add(&(new_svc->wanted),deps);
|
||||
|
||||
/* second link */
|
||||
deps = dep_create(new_svc);
|
||||
if(!deps) return 0;
|
||||
dep_entry_add(&(svc->wants),deps);
|
||||
}
|
||||
}
|
||||
if(chdir(oldpath) == -1) {
|
||||
print_errno(buf);
|
||||
return 0;
|
||||
}
|
||||
closedir(d_tmp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Create dependency
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <stdlib.h> /* malloc() */
|
||||
#include "svc.h" /* structs */
|
||||
|
||||
/* search for an entry by path, reverse: from end to the beginning */
|
||||
struct dep *dep_create(struct listitem *svc)
|
||||
{
|
||||
struct dep *entry;
|
||||
|
||||
entry = malloc(sizeof(struct dep));
|
||||
if(!entry) return NULL;
|
||||
entry->svc = svc;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* List handling: Add a new item to a (non-)empty list
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include "svc.h" /* types */
|
||||
|
||||
/*
|
||||
* list: pointer to the list
|
||||
* new: pointer to data to insert (already filled up)
|
||||
*
|
||||
* We add the new element BEFORE the existing element!
|
||||
*/
|
||||
void dep_entry_add(struct dep **deplist, struct dep *new)
|
||||
{
|
||||
if(*deplist == NULL) { /* new list */
|
||||
*deplist = new;
|
||||
(*deplist)->prev = *deplist;
|
||||
(*deplist)->next = *deplist;
|
||||
} else { /* already existing */
|
||||
new->next = *deplist; /* new-> first */
|
||||
new->prev = (*deplist)->prev; /* last <- new */
|
||||
(*deplist)->prev->next = new; /* last -> new */
|
||||
(*deplist)->prev = new; /* new <- first */
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* List handling: Add a new item to a (non-)empty list
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <stdlib.h> /* free() */
|
||||
#include "svc.h"
|
||||
|
||||
/*
|
||||
* tmp: pointer to data to remove (must not be NULL)
|
||||
*
|
||||
* Returns either the next object or NULL if there's no next object
|
||||
*/
|
||||
struct dep *dep_entry_del(struct dep *del)
|
||||
{
|
||||
struct dep *tmp;
|
||||
|
||||
/* last service in the list */
|
||||
if(del->next == del && del->prev == del) {
|
||||
tmp=NULL;
|
||||
} else {
|
||||
/* remove from list */
|
||||
del->prev->next = del->next;
|
||||
del->next->prev = del->prev;
|
||||
tmp = del->next;
|
||||
}
|
||||
|
||||
free(del);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Add all wants or needs from a specific service to dep list
|
||||
* -> this builds the needs and needed_by and
|
||||
* -> or this builds the wants and wanted_by and
|
||||
*
|
||||
* This function is used to fillup the starting list with dependencies
|
||||
* after a service has sucessfully been executed.
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include "svc.h"
|
||||
|
||||
/*
|
||||
* list: pointer to the list
|
||||
* svc: pointer to data to the service
|
||||
*/
|
||||
|
||||
int dep_needs_wants_add(struct dep **list, struct listitem *svc, int type)
|
||||
{
|
||||
struct dep *tmp, *new, *end;
|
||||
|
||||
if(type == DEP_NEEDS) {
|
||||
end = svc->needed;
|
||||
} else {
|
||||
end = svc->wanted;
|
||||
}
|
||||
|
||||
/* Place to the first dependency of this service */
|
||||
tmp = end;
|
||||
if(tmp != NULL) {
|
||||
do {
|
||||
/* Add service to the starter list, which
|
||||
* - should be started once
|
||||
* - should be respawned (both VIRGIN services!)
|
||||
* - and which are not already in the list!
|
||||
*/
|
||||
if(((tmp->svc->status & ST_SH_ONCE) ||
|
||||
(tmp->svc->status & ST_SH_RESPAWN)) &&
|
||||
!(tmp->svc->status & ST_IN_LIST)) {
|
||||
new = dep_create(tmp->svc);
|
||||
if(!new) return 0;
|
||||
tmp->svc->status |= ST_IN_LIST;
|
||||
dep_entry_add(list,new);
|
||||
}
|
||||
/* FIXME: Clearify if we should go forward or backwards?
|
||||
* this decision will influence starting order
|
||||
* and may thereby add a minimal mount of speed enhancement
|
||||
*
|
||||
* As far as I can see it is not predictable, which way is
|
||||
* better, because it heavily depends on the other services.
|
||||
*
|
||||
* If you know better, provide me with a patch ;-)
|
||||
*/
|
||||
tmp = tmp->next;
|
||||
} while(tmp != end);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Pre calculate the service tree
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "cinit.h"
|
||||
#include "svc.h"
|
||||
|
||||
struct listitem *gen_svc_tree(char *svc)
|
||||
{
|
||||
struct listitem *li;
|
||||
struct dep *deps;
|
||||
|
||||
/* only do something if the service is not already known */
|
||||
if((li=list_search(svc))) return li;
|
||||
|
||||
/* create a template, so other instances won't try to recreate us */
|
||||
if(!(li=svc_create(svc))) return NULL;
|
||||
|
||||
if(!check_add_deps(li,DEP_NEEDS)) return NULL;
|
||||
if(!check_add_deps(li,DEP_WANTS)) return NULL;
|
||||
|
||||
/* no dependencies? then you are a start service */
|
||||
if(!li->wants && !li->needs) {
|
||||
deps = dep_create(li);
|
||||
if(!deps) return NULL;
|
||||
dep_entry_add(&svc_init,deps);
|
||||
|
||||
/* Mark it as being in the startup list, so it does not
|
||||
* get added again in a dep_needs_wants_add call */
|
||||
li->status |= ST_IN_LIST;
|
||||
}
|
||||
|
||||
return li;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* (c) 2005 Marcus Przyklink (downhill-clinux (at) burningchaos.org)
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* List handling
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cinit.h"
|
||||
#include "svc.h"
|
||||
|
||||
/* ... */
|
||||
int list_delete(char *path)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
tmp = list_search(path);
|
||||
|
||||
if( tmp == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp->next->prev = tmp->prev;
|
||||
tmp->prev->next = tmp->next;
|
||||
free(tmp->abs_path);
|
||||
free(tmp);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Show all list elements - mainly for debugging
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include "cinit.h"
|
||||
#include "svc.h"
|
||||
|
||||
int list_display_all()
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
if( svc_list == NULL ) {
|
||||
return 0;
|
||||
} else {
|
||||
tmp = svc_list;
|
||||
}
|
||||
|
||||
do {
|
||||
mini_printf("Service: ",1);
|
||||
mini_printf(tmp->abs_path,1);
|
||||
mini_printf("\n",1);
|
||||
tmp = tmp->prev;
|
||||
} while(tmp != svc_list);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* (c) 2005 Marcus Przyklink (downhill-clinux (at) burningchaos.org)
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* List handling
|
||||
*/
|
||||
|
||||
#include <stdlib.h> /* malloc */
|
||||
#include <string.h> /* bzero / memset */
|
||||
#include "svc.h" /* the list pointer */
|
||||
|
||||
struct listitem *list_insert(char *path, int status)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
tmp = malloc(sizeof(struct listitem));
|
||||
if(tmp == NULL) return NULL;
|
||||
memset( tmp, '\0', sizeof(struct listitem));
|
||||
|
||||
if(svc_list == NULL) { /* list is empty, we have to init it */
|
||||
svc_list = tmp;
|
||||
svc_list->next = svc_list;
|
||||
svc_list->prev = svc_list;
|
||||
} else { /* list has members,add this one */
|
||||
tmp->next = svc_list; /* begin after the new element */
|
||||
tmp->prev = svc_list->prev; /* change to the ex-last */
|
||||
svc_list->prev->next = tmp; /* change last element */
|
||||
svc_list->prev = tmp; /* first refers to previous now */
|
||||
}
|
||||
|
||||
tmp->abs_path = malloc(strlen(path) + 1);
|
||||
if(tmp->abs_path == NULL) return NULL;
|
||||
|
||||
strcpy(tmp->abs_path,path);
|
||||
tmp->status = status;
|
||||
tmp->pid = 0;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* (c) 2005 Marcus Przyklink (downhill-clinux (at) burningchaos.org)
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* List handling
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "cinit.h"
|
||||
#include "comm.h" /* for ST_OFF */
|
||||
#include "svc.h" /* for ST_OFF */
|
||||
|
||||
/* change pid and status of a process */
|
||||
int list_modify(char *path, int new_status, pid_t new_pid)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
// D_PRINTF(path);
|
||||
|
||||
tmp = list_search(path);
|
||||
if( tmp == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* delete objects, which are killed */
|
||||
if(new_status == ST_OFF) {
|
||||
return list_delete(path);
|
||||
} else {
|
||||
tmp->status = new_status;
|
||||
tmp->pid = new_pid;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* (c) 2005 Marcus Przyklink (downhill-clinux (at) burningchaos.org)
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* List handling
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <string.h> /* strcmp */
|
||||
#include "cinit.h"
|
||||
#include "svc.h"
|
||||
|
||||
/* search for an entry by path, reverse: from end to the beginning */
|
||||
struct listitem *list_search(char *path)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
if(svc_list == NULL) { /* think positive */
|
||||
return NULL;
|
||||
} else {
|
||||
tmp = svc_list;
|
||||
}
|
||||
|
||||
do {
|
||||
if(!strcmp(path, tmp->abs_path)) {
|
||||
return tmp;
|
||||
}
|
||||
tmp = tmp->prev;
|
||||
} while(tmp != svc_list);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* (c) 2005 Marcus Przyklink (downhill-clinux (at) burningchaos.org)
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* List handling: Search by pid
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <sys/types.h> /* pid_t */
|
||||
#include "svc.h" /* struct listitem */
|
||||
|
||||
struct listitem *list_search_pid(pid_t pid)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
if(svc_list == NULL) {
|
||||
return NULL;
|
||||
} else {
|
||||
tmp = svc_list;
|
||||
}
|
||||
|
||||
do {
|
||||
if(pid == tmp->pid) {
|
||||
return tmp;
|
||||
}
|
||||
tmp = tmp->prev;
|
||||
} while(tmp != svc_list);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
21
software/cinit/browse_source/cinit-0.3pre6/src/svc/objects
Normal file
21
software/cinit/browse_source/cinit-0.3pre6/src/svc/objects
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
svc/gen_svc_tree.o
|
||||
svc/list_delete.o
|
||||
svc/list_display_all.o
|
||||
svc/list_insert.o
|
||||
svc/list_modify.o
|
||||
svc/list_search.o
|
||||
svc/list_search_pid.o
|
||||
svc/svc_create.o
|
||||
svc/check_add_deps.o
|
||||
svc/dep_entry_add.o
|
||||
svc/dep_entry_del.o
|
||||
svc/tree_exec.o
|
||||
svc/svc_set_status.o
|
||||
svc/svc_should_respawn.o
|
||||
svc/svc_needs_status.o
|
||||
svc/dep_needs_wants_add.o
|
||||
svc/dep_create.o
|
||||
svc/svc_success.o
|
||||
svc/svc_report_status.o
|
||||
svc/svc_start.o
|
||||
svc/svc_fail.o
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* List handling
|
||||
*/
|
||||
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
#include "cinit.h"
|
||||
#include "messages.h"
|
||||
|
||||
int svc_add_needs(char *needs, char *is_needed)
|
||||
{
|
||||
struct listitem *svc_needs, *svc_is_needed;
|
||||
|
||||
|
||||
/* retrieve service entries in global service list */
|
||||
svc_needs = svc_is_needed = NULL;
|
||||
svc_needs = list_search(needs);
|
||||
svc_is_needed = list_search(is_needed);
|
||||
|
||||
/* and exit if one is missing */
|
||||
if( !svc_needs || !svc_is_needed ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* first add needs */
|
||||
|
||||
/* now add needed_by */
|
||||
|
||||
malloc... /* for adding */
|
||||
|
||||
if(svc->needs == NULL) {
|
||||
svc->needs = neu;
|
||||
} else {
|
||||
svc->next = neu;
|
||||
}
|
||||
|
||||
/* write generic function for dependencies or even all lists */
|
||||
dep_entry_add(list_pointer,new_entry);
|
||||
|
||||
if( list == NULL ) { /* list is empty, we have to init it */
|
||||
list = tmp;
|
||||
list->after = list;
|
||||
list->before = list;
|
||||
} else { /* list has members,add this one */
|
||||
tmp->after = list; /* begin after the new element */
|
||||
tmp->before = list->before; /* change to the ex-last */
|
||||
list->before->after = tmp; /* change last element */
|
||||
list->before = tmp; /* first refers to previous now */
|
||||
}
|
||||
|
||||
tmp->abs_path = malloc( strlen(path) + 1);
|
||||
if( tmp->abs_path == NULL ) {
|
||||
LOG(MSG_ERR_ALLOC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(tmp->abs_path,path);
|
||||
tmp->status = status;
|
||||
tmp->pid = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Check whether service is existent
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <string.h> /* strcpy */
|
||||
#include <unistd.h> /* stat */
|
||||
#include <sys/stat.h> /* stat */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include <errno.h> /* errno */
|
||||
#include "svc.h" /* listitem */
|
||||
#include "cinit.h" /* path_append */
|
||||
|
||||
/* checking for existence is done before! */
|
||||
/* FIXME: check heedars for conformance with POSIX */
|
||||
struct listitem *svc_create(char *svc)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
struct stat statbuf;
|
||||
struct listitem *li;
|
||||
|
||||
li = list_insert(svc,-1);
|
||||
if(!li) return NULL;
|
||||
|
||||
/* FIXME: add two path length checks? svc and svc+strlen(C_RESPAWN)? */
|
||||
strcpy(buf,svc);
|
||||
if(!path_append(buf,C_RESPAWN)) return NULL;
|
||||
|
||||
if(stat(buf,&statbuf) == -1) {
|
||||
if(errno == ENOENT) {
|
||||
svc_set_status(li,ST_SH_ONCE);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
mini_printf("respawn: ",1);
|
||||
mini_printf(li->abs_path,1);
|
||||
mini_printf("\n",1);
|
||||
svc_set_status(li,ST_SH_RESPAWN);
|
||||
}
|
||||
|
||||
return li;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Mark the service as being failed
|
||||
*/
|
||||
|
||||
#include "svc.h"
|
||||
|
||||
void svc_fail(struct listitem *li)
|
||||
{
|
||||
if(li->status & ST_ONCE_RUN)
|
||||
li->status = ST_ONCE_FAIL;
|
||||
else {
|
||||
/* FIXME: do something senseful, record time of dead? */
|
||||
li->status = ST_RESPAWNING;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Return status of the needs of this service
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include "svc.h" /* service information */
|
||||
|
||||
// DEBUG #include "cinit.h" /* service information */
|
||||
|
||||
int svc_needs_status(struct listitem *svc)
|
||||
{
|
||||
int retval = SNS_NEEDS_STARTED;
|
||||
struct dep *deps = svc->needs;
|
||||
|
||||
/* DEBUG mini_printf("sns: ",1);
|
||||
mini_printf(svc->abs_path,1);
|
||||
mini_printf("\n",1); */
|
||||
|
||||
if(deps == NULL) return SNS_NEEDS_STARTED; /* no needs, everything fine */
|
||||
|
||||
do {
|
||||
/* worst case: need failed */
|
||||
if((deps->svc->status & ST_NEED_FAILD) ||
|
||||
(deps->svc->status & ST_ONCE_FAIL)) {
|
||||
retval = SNS_NEEDS_FAILED;
|
||||
break;
|
||||
}
|
||||
/* services are being started */
|
||||
if((deps->svc->status & ST_SH_ONCE) ||
|
||||
(deps->svc->status & ST_SH_RESPAWN)) {
|
||||
retval = SNS_NEEDS_UNFINISHED;
|
||||
}
|
||||
deps = deps->next;
|
||||
} while(deps != svc->needs);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Tell the world what happened to the service
|
||||
*/
|
||||
|
||||
#include "cinit.h" /* mini_printf */
|
||||
#include "messages.h" /* MSG_INTRO_SVC */
|
||||
|
||||
void svc_report_status(char *svc, char *msg, char *err)
|
||||
{
|
||||
mini_printf(MSG_INTRO_SVC,1);
|
||||
mini_printf(svc,1);
|
||||
mini_printf(": ",1);
|
||||
mini_printf(msg,1);
|
||||
if(err) {
|
||||
mini_printf(" (",1);
|
||||
mini_printf(err,1);
|
||||
mini_printf(")",1);
|
||||
}
|
||||
mini_printf("\n",1);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Check whether service is existent
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include "svc.h"
|
||||
|
||||
/* checking for existence is done before! */
|
||||
int svc_respawn_check(struct listitem *svc)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
|
||||
strcpy(buf,svc->abs_path);
|
||||
if(!path_append(buf,C_RESPAWN)) return 0
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2005-2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Set the status of a service
|
||||
*/
|
||||
|
||||
#include "svc.h"
|
||||
|
||||
/* checking for existence is done before! */
|
||||
int svc_set_status(struct listitem *li, int status)
|
||||
{
|
||||
return (li->status = status);
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Return whether should respawn or not
|
||||
*/
|
||||
|
||||
#include "svc.h"
|
||||
|
||||
/* checking for existence is done before! */
|
||||
int svc_should_respawn(struct listitem *li)
|
||||
{
|
||||
return (li->status & ST_SH_RESPAWN);
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Start a service
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <unistd.h> /* fork */
|
||||
#include <string.h> /* strerror */
|
||||
#include <errno.h> /* errno */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include "svc.h" /* struct * */
|
||||
#include "messages.h" /* MSG_* */
|
||||
#include "cinit.h" /* execute_sth */
|
||||
|
||||
//void svc_start(struct listitem *li, int strict)
|
||||
void svc_start(struct listitem *li)
|
||||
{
|
||||
char buf[PATH_MAX+1];
|
||||
|
||||
/* FIXME: All cleanup must go here
|
||||
* close(fds);
|
||||
* reset signals
|
||||
* reset env?
|
||||
*
|
||||
* FIXME: Add logging possibility to here
|
||||
* open (0,1,2) to other processes, if specified */
|
||||
li->pid = fork();
|
||||
|
||||
if(li->pid < 0) {
|
||||
svc_report_status(li->abs_path,MSG_SVC_FORK,strerror(errno));
|
||||
svc_set_status(li,ST_BAD_ERR);
|
||||
return;
|
||||
}
|
||||
if(li->pid > 0) {
|
||||
if(li->status & ST_SH_ONCE)
|
||||
li->status = ST_ONCE_RUN;
|
||||
else
|
||||
li->status = ST_RESPAWNING;
|
||||
return;
|
||||
}
|
||||
|
||||
/********************** Client / fork() ************************/
|
||||
svc_report_status(li->abs_path,MSG_SVC_START,NULL);
|
||||
|
||||
/* length check is done by path_append */
|
||||
strcpy(buf,li->abs_path);
|
||||
if(!path_append(buf,C_ON)) return;
|
||||
|
||||
/* Check for existence */
|
||||
li->status = file_exists(buf);
|
||||
|
||||
if(li->status == FE_NOT) _exit(0); /* nothing there? fine! */
|
||||
|
||||
if(li->status == FE_FILE) {
|
||||
/* FIXME: reset signals: Is this necessary? Or does fork clean it anyway? */
|
||||
set_signals(ACT_CLIENT);
|
||||
|
||||
/* and now, fire it up */
|
||||
execute_sth(buf);
|
||||
} else {
|
||||
/* either no file or an error */
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Set the status of a service
|
||||
*/
|
||||
|
||||
#include "svc.h"
|
||||
|
||||
void svc_success(struct listitem *li)
|
||||
{
|
||||
if(li->status & ST_ONCE_RUN)
|
||||
li->status = ST_ONCE_OK;
|
||||
else
|
||||
li->status = ST_RESPAWNING;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Start the service tree we created
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include "cinit.h" /* mini_printf */
|
||||
#include "svc.h" /* svc_init */
|
||||
#include "messages.h" /* messages */
|
||||
|
||||
/* some thoughts...
|
||||
*
|
||||
* - we already generated the tree, we now need to start it from
|
||||
* the ends
|
||||
*
|
||||
* - after starting the first service we have to care about SIG_CHILD
|
||||
* to record changes
|
||||
*
|
||||
* - we execute all services in parallel without problems, because of
|
||||
* SIG_CHILD notification
|
||||
*
|
||||
* - After successfully starting the service we start the services that
|
||||
* need or want that service
|
||||
*/
|
||||
int tree_exec(struct dep *start)
|
||||
{
|
||||
struct dep *tmp = start;
|
||||
|
||||
mini_printf(MSG_TREE_EXEC,1);
|
||||
|
||||
/* the main starting loop: All services in this list should be
|
||||
* started, but it is possible that dependent services are in the
|
||||
* list. In this case simply skip the current service
|
||||
*/
|
||||
do {
|
||||
switch(svc_needs_status(tmp->svc)) {
|
||||
case SNS_NEEDS_STARTED:
|
||||
/* execute service, add dependencies, remowe from list */
|
||||
svc_start(tmp->svc);
|
||||
if(!dep_needs_wants_add(&tmp,tmp->svc,DEP_NEEDS)) return 0;
|
||||
if(!dep_needs_wants_add(&tmp,tmp->svc,DEP_WANTS)) return 0;
|
||||
tmp = dep_entry_del(tmp);
|
||||
break;
|
||||
|
||||
case SNS_NEEDS_FAILED:
|
||||
/* mark service as NEED_FAILD and delete from list */
|
||||
svc_report_status(tmp->svc->abs_path,MSG_SVC_NEED_FAIL,NULL);
|
||||
svc_set_status(tmp->svc,ST_NEED_FAILD);
|
||||
tmp = dep_entry_del(tmp);
|
||||
break;
|
||||
|
||||
case SNS_NEEDS_UNFINISHED:
|
||||
/* continue with the next item */
|
||||
tmp = tmp->next;
|
||||
break;
|
||||
}
|
||||
|
||||
} while(tmp != NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* test build_argv
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "build_argv.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
char *file = "./test_exec_link";
|
||||
struct ba_argv cargv;
|
||||
int tmp;
|
||||
|
||||
if( ( tmp = cinit_build_argv(file,&cargv) ) != BA_OK) {
|
||||
if(tmp != BA_E_MEM) {
|
||||
perror("fehler:");
|
||||
exit(24);
|
||||
} else exit(23);
|
||||
}
|
||||
|
||||
printf("code: %s\n", cargv.argv[0]);
|
||||
execve((cargv.argv)[0],cargv.argv,cargv.envp);
|
||||
|
||||
perror("execve");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* test build_argv
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "build_argv.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
char *file = "./test_exec";
|
||||
struct ba_argv cargv;
|
||||
int tmp;
|
||||
|
||||
if( ( tmp = cinit_build_argv(file,&cargv) ) != BA_OK) {
|
||||
if(tmp != BA_E_MEM) {
|
||||
perror("fehler:");
|
||||
exit(24);
|
||||
} else exit(23);
|
||||
}
|
||||
|
||||
printf("code: %s\n", cargv.argv[0]);
|
||||
execve((cargv.argv)[0],cargv.argv,cargv.envp);
|
||||
|
||||
perror("execve");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
# Nico Schottelius
|
||||
# Test-skript for cinit
|
||||
|
||||
echo '$0': "$0"
|
||||
echo '$@': "$@"
|
||||
echo 'cinit_is_great:' $cinit_is_great
|
||||
|
|
@ -0,0 +1 @@
|
|||
cinit_is_great=yes
|
||||
|
|
@ -0,0 +1 @@
|
|||
Let's see if we read the arguments....YES!
|
||||
|
|
@ -0,0 +1 @@
|
|||
test_exec
|
||||
|
|
@ -0,0 +1 @@
|
|||
test_exec.env
|
||||
|
|
@ -0,0 +1 @@
|
|||
test_exec.params
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* test gen_svc_tree
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "build_argv.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
gen_svc_tree("/etc/cinit/svc/init");
|
||||
list_display_all();
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int openreadclose(char *filename, char **where);
|
||||
|
||||
int main()
|
||||
{
|
||||
char *data;
|
||||
char *file = "test_openreadclose.c";
|
||||
|
||||
openreadclose(file,&data);
|
||||
|
||||
printf("%s\n",data);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue