add cinit-0.3pre16
Signed-off-by: Nico Schottelius <nico@ikn.schottelius.org>
This commit is contained in:
parent
0a2c96848b
commit
0c13ed6979
1089 changed files with 101811 additions and 0 deletions
185
software/cinit/browse_source/cinit-0.3pre16/src/Makefile
Normal file
185
software/cinit/browse_source/cinit-0.3pre16/src/Makefile
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
#
|
||||
# 2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
#
|
||||
# This file is part of cinit.
|
||||
|
||||
# cinit is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# cinit is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# Don't edit Makefiles, use conf/* for configuration.
|
||||
#
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Build tools / locations
|
||||
#
|
||||
|
||||
CC=../tmpbin/cc
|
||||
CFLAGS=
|
||||
LD=../tmpbin/ld
|
||||
LDFLAGS=
|
||||
STRIP=../tmpbin/strip
|
||||
SBIN=../sbin
|
||||
DESTDIR=
|
||||
#DESTDIR=/home/user/nico/emu/dst
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# All objects / binaries
|
||||
# depend on headers. More or less. FIXME: use gcc -M
|
||||
#
|
||||
BIN=cinit.halt cinit.poweroff cinit.reboot cmd
|
||||
CINIT=cinit
|
||||
ALLBIN=${BIN} ${CINIT}
|
||||
|
||||
# headers
|
||||
CONFIG_H=include/config.h
|
||||
CINIT_HEADERS=${shell cat include/listing}
|
||||
|
||||
# objects
|
||||
CINIT_OBJ=${shell cat object_lists/cinit}
|
||||
HALTKILL_OBJ=${shell cat object_lists/halt.kill}
|
||||
POWEROFFKILL_OBJ=${shell cat object_lists/poweroff.kill}
|
||||
REBOOTKILL_OBJ=${shell cat object_lists/reboot.kill}
|
||||
CMD_OBJ=${shell cat object_lists/cmd}
|
||||
|
||||
#
|
||||
# All objects
|
||||
#
|
||||
OBJ=${CINIT_OBJ} ${HALTKILL_OBJ} ${POWEROFFKILL_OBJ} ${REBOOTKILL_OBJ}
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# End user target
|
||||
#
|
||||
#all: cinit cservice ccontrol sizecheck docs
|
||||
all: ${ALLBIN}
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Generic
|
||||
#
|
||||
${OBJ}: ${CINIT_HEADERS}
|
||||
|
||||
%.o: %.c
|
||||
${CC} -c -o $@ $<
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# First do configuration, so we include the right variables
|
||||
#
|
||||
Makefile: .configured
|
||||
|
||||
.configured: ../conf/*
|
||||
@../scripts/build/cinit.configure.os
|
||||
@../scripts/build/cinit.configure.tools
|
||||
@../scripts/build/cinit.configure.ipc
|
||||
@../scripts/build/cinit.configure.mark
|
||||
|
||||
${CINIT_OBJ}: ${CONFIG_H}
|
||||
|
||||
${CONFIG_H}: ../conf/*
|
||||
../scripts/cinit.mkheader > ${CONFIG_H}
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Install targets
|
||||
#
|
||||
|
||||
#install: install-dir cinit cservice ccontrol
|
||||
install: install-cinit install-utilities
|
||||
|
||||
install-sbin:
|
||||
install -d ${DESTDIR}/sbin
|
||||
|
||||
install-utilities: install-sbin ${BIN}
|
||||
@echo '*** Installing utilities ***'
|
||||
install ${BIN} ${DESTDIR}/sbin
|
||||
|
||||
install-cinit: install-sbin cinit
|
||||
@echo '*** Installing cinit ***'
|
||||
@echo "Need to delete cinit before reinstalling it {text file busy problem}"
|
||||
rm -f ${DESTDIR}/sbin/cinit
|
||||
install cinit ${DESTDIR}/sbin
|
||||
|
||||
# FIXME: target broken
|
||||
install-miniconf:
|
||||
./bin/cinit.install.miniconf
|
||||
|
||||
# FIXME: target broken
|
||||
install-dir:
|
||||
./bin/cinit.install.dir
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Build targets
|
||||
#
|
||||
|
||||
cinit: ${CINIT_OBJ}
|
||||
${LD} $^ -o $@
|
||||
|
||||
cinit.halt: ${HALTKILL_OBJ}
|
||||
${LD} $^ -o $@
|
||||
|
||||
cinit.poweroff: ${POWEROFFKILL_OBJ}
|
||||
${LD} $^ -o $@
|
||||
|
||||
cinit.reboot: ${REBOOTKILL_OBJ}
|
||||
${LD} $^ -o $@
|
||||
|
||||
cmd: ${CMD_OBJ}
|
||||
${LD} $^ -o $@
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Internal test targets
|
||||
#
|
||||
|
||||
uml: cinit cmd
|
||||
../../vm/uml/uml-mount.sh
|
||||
cp cinit cmd ../../vm/uml/root/sbin/
|
||||
../../vm/uml/uml-umount.sh
|
||||
|
||||
umlstart: uml
|
||||
../../vm/uml/uml-start.sh
|
||||
|
||||
SDIR=../size
|
||||
SNOW=$(shell date +%Y-%m-%d-%H%M%S)
|
||||
sizecheck: cinit
|
||||
ls -l cinit > $(SDIR)/$(SNOW)
|
||||
cat $(SDIR)/$(SNOW)
|
||||
git add $(SDIR)/$(SNOW)
|
||||
git commit -m "Size: $$(awk '{ print $$5 }' $(SDIR)/$(SNOW))"
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Clenaup targets
|
||||
#
|
||||
|
||||
.PHONY: clean
|
||||
.PHONY: dist
|
||||
.PHONY: distclean
|
||||
|
||||
dist: distclean
|
||||
|
||||
distclean: clean
|
||||
rm -f os/current ipc/current .configured
|
||||
|
||||
clean:
|
||||
rm -f ../tmpbin/*.configured
|
||||
rm -f ${BIN} ${CINIT_OBJ} ${CINIT}
|
||||
find . -name \*.o -exec rm {} \;
|
||||
|
|
@ -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,4 @@
|
|||
-- OBSOLETED --
|
||||
-> This code is not in use in cinit-0.3 anymore!
|
||||
util/
|
||||
External programs, which work with cinit
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
0. Definition Nachrichten
|
||||
0.1 Definition returncodes und co...
|
||||
|
||||
|
||||
1. execute_sth: finish, so we can use it for panic
|
||||
|
||||
2. MSGQ:
|
||||
beidseitig implemenntieren
|
||||
ipc header integrieren
|
||||
Dokumentieren
|
||||
|
||||
conf/* von msgq saeubern
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* ccontrol: control cinit
|
||||
* part of cLinux/cinit
|
||||
*/
|
||||
|
||||
/* *stat() */
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* open */
|
||||
#include <fcntl.h>
|
||||
|
||||
/* signal */
|
||||
#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 <limits.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* global variable */
|
||||
struct listitem *list;
|
||||
int sock;
|
||||
pid_t cpid;
|
||||
|
||||
/***********************************************************************
|
||||
* cservice - control cinit
|
||||
*/
|
||||
|
||||
#define USAGE_TEXT "ccontrol - control cinit\n\n" \
|
||||
"Usage:\n\nccontrol -[phurs]\n" \
|
||||
"\t-p\t- (power off) Power off the system\n" \
|
||||
"\t-h\t- (halt) Halt the system \n" \
|
||||
"\t-u\t- (update) Reboot (warm) and update cinit\n" \
|
||||
"\t-r\t- (reboot) Reboot the system\n" \
|
||||
"\t-s\t- (single user/rescue) Rescue mode\n\n" \
|
||||
|
||||
#define C_USAGE(error) usage(USAGE_TEXT,error)
|
||||
|
||||
/***********************************************************************
|
||||
* ccontrol: control cinit
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* argv */
|
||||
if(argc != 2) C_USAGE(MSG_ERR_LESS_ARGS);
|
||||
if(argv[1][0] != '-') C_USAGE(MSG_ERR_BAD_ARGS);
|
||||
|
||||
switch(argv[1][1]) {
|
||||
case 'p': /* power off */
|
||||
LOG(MSG_POWER_OFF);
|
||||
msg_reboot(CMD_POWEROFF);
|
||||
break;
|
||||
|
||||
case 'h': /* halt */
|
||||
LOG(MSG_HALT);
|
||||
msg_reboot(CMD_HALT);
|
||||
break;
|
||||
|
||||
case 'r': /* reboot */
|
||||
LOG(MSG_REBOOT);
|
||||
msg_reboot(CMD_REBOOT);
|
||||
break;
|
||||
|
||||
case 's': /* rescue */
|
||||
LOG(MSG_RESCUE);
|
||||
msg_reboot(CMD_RESCUE);
|
||||
break;
|
||||
|
||||
case 'u': /* update */
|
||||
LOG(MSG_UPDATE);
|
||||
msg_reboot(CMD_UPDATE);
|
||||
break;
|
||||
|
||||
default:
|
||||
C_USAGE(MSG_ERR_BAD_ARGS);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* cinit-0.2 return codes implemented - nothing changed*/
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Convert char pointer to uint32_t flag
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h> /* strchr */
|
||||
#include <stdio.h> /* NULL */
|
||||
|
||||
#include "cinit.h" /* cinit */
|
||||
|
||||
uint32_t charp_to_flag(char *str)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
if(str != NULL) {
|
||||
if(strchr(str, CINIT_CMD_SVC_WANTS) != NULL)
|
||||
ret |= CINIT_QSN_SVC_WANTS;
|
||||
if(strchr(str, CINIT_CMD_SVC_NEEDS) != NULL)
|
||||
ret |= CINIT_QSN_SVC_NEEDS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Retrieves status of a service
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h> /* malloc */
|
||||
#include <string.h> /* str* */
|
||||
#include <stdint.h> /* integers */
|
||||
|
||||
#include "cinit.h" /* header for clients */
|
||||
|
||||
/* returns either the status (>0)
|
||||
* or -1 on memory error
|
||||
*/
|
||||
int32_t cinit_get_svc_status(char *name)
|
||||
{
|
||||
/* fixme: s32 int! */
|
||||
int tmp;
|
||||
int32_t res;
|
||||
char *p, *answer;
|
||||
int offset = 0, len = strlen(name);
|
||||
|
||||
p = malloc(len + 2 * sizeof(tmp));
|
||||
if(!p) return -1;
|
||||
|
||||
/* code */
|
||||
tmp = CINIT_MSG_GET_STATUS;
|
||||
strncpy(p,(char *) &tmp, sizeof(tmp));
|
||||
offset += sizeof(tmp);
|
||||
|
||||
/* length */
|
||||
strncpy(&p[offset],(char *) &len, sizeof(len));
|
||||
offset += sizeof(len);
|
||||
|
||||
/* data */
|
||||
strncpy(p, (char *) name, len);
|
||||
|
||||
answer = cinit_send_to(p,len);
|
||||
|
||||
if(answer) {
|
||||
strncpy((char *) &res, answer, sizeof(res));
|
||||
free(answer);
|
||||
} else {
|
||||
res = -1;
|
||||
}
|
||||
|
||||
free(name);
|
||||
return res;
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006-2007 Nico Schottelius (nico-cinit (at) schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Communication defines
|
||||
*/
|
||||
|
||||
#ifndef CINIT_COMM_HEADER
|
||||
#define CINIT_COMM_HEADER
|
||||
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include <sys/types.h> /* pid_t */
|
||||
|
||||
/***********************************************************************
|
||||
* Commands the clients may issue to us
|
||||
* maximum number of commands: 2^8 = 256
|
||||
*/
|
||||
enum commands {
|
||||
CMD_MIN='A', /* minimum command number */
|
||||
CMD_SVC_START, /* the client wants US to start a service */
|
||||
CMD_SVC_START_ONLY, /* start this service without dependencies */
|
||||
CMD_SVC_START_NEEDS, /* start this service, needs, but no wants */
|
||||
CMD_SVC_STOP, /* stop svc and all svcs that need it */
|
||||
CMD_SVC_STOP_ONLY, /* we should stop _only_ this service */
|
||||
CMD_SVC_STOP_WANTS, /* stop svc, all svcs that need or want it */
|
||||
CMD_CHG_STAT, /* the client reports a status change */ /* FIXME: NEEDED? */
|
||||
CMD_RESCUE, /* we should start the rescue mode */ /* UNIMPLEMENTED */
|
||||
CMD_HALT, /* halt the system */
|
||||
CMD_REBOOT, /* reboot the system */
|
||||
CMD_POWEROFF, /* poweroff the system */
|
||||
CMD_WBOOT, /* shutdown and restart everything */ /* UNIMPLEMENTED */
|
||||
CMD_INFO, /* send information about that service */ /* UNIMPLEMENTED */
|
||||
CMD_MAX , /* maximum command number */
|
||||
};
|
||||
|
||||
/* 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 *
|
||||
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* client issues a command: start_command
|
||||
*/
|
||||
struct s_cmd {
|
||||
char cmd;
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
* cservice: control cinit services
|
||||
* part of cLinux/cinit
|
||||
*/
|
||||
|
||||
/* *stat() */
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* open */
|
||||
#include <fcntl.h>
|
||||
|
||||
/* signal */
|
||||
#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 <limits.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* global variable */
|
||||
struct listitem *list;
|
||||
int sock;
|
||||
pid_t cpid;
|
||||
|
||||
/***********************************************************************
|
||||
* cservice - control cinit services
|
||||
*/
|
||||
|
||||
#define USAGE_TEXT "cservice - start and stop cinit services\n\n" \
|
||||
"cservice -[ear] <service>\n" \
|
||||
"\t-e\t- (ein,on ) start a service (respawn if respawning is set)\n" \
|
||||
"\t-a\t- (aus,off) stop a respawing service\n" \
|
||||
"\t-r\t- (restart) stop and start a service\n"
|
||||
|
||||
/***********************************************************************
|
||||
* fuzzy_path: allow other kinds of path specification ..
|
||||
*/
|
||||
char *fuzzy_path(char *rpath)
|
||||
{
|
||||
char pathtmp[PATH_MAX];
|
||||
char *re = NULL;
|
||||
|
||||
/* change to rpath */
|
||||
if(chdir(rpath) == -1) {
|
||||
perror(rpath);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get absolute name of rpath */
|
||||
if(! (int) getcwd(pathtmp,PATH_MAX)) {
|
||||
perror(rpath);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
re = malloc( strlen(pathtmp) + 1);
|
||||
|
||||
if(re != NULL) {
|
||||
strcpy(re,pathtmp);
|
||||
}
|
||||
|
||||
return re;
|
||||
}
|
||||
|
||||
#define C_USAGE(error) usage(USAGE_TEXT,error)
|
||||
|
||||
/***********************************************************************
|
||||
* cservice: the main part for controlling cinit from outside
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *real_name = NULL;
|
||||
|
||||
/* argv */
|
||||
if(argc != 3) C_USAGE(MSG_ERR_LESS_ARGS);
|
||||
if(argv[1][0] != '-') C_USAGE(MSG_ERR_BAD_ARGS);
|
||||
if(strlen(argv[1]) != 2) C_USAGE(MSG_ERR_ARGS_LEN);
|
||||
|
||||
real_name = fuzzy_path(argv[2]);
|
||||
|
||||
/* fuzzy path failed, exit! */
|
||||
if(real_name == NULL) {
|
||||
return 1;
|
||||
}
|
||||
switch(argv[1][1]) {
|
||||
case 'a': /* aus */
|
||||
case 'r': /* restart */
|
||||
switch( msg_svc_on_off(real_name,CMD_STOP_SVC) ) {
|
||||
case ST_FAIL:
|
||||
SERVICE_LOG(real_name,LOG_SVC_FAIL);
|
||||
break;
|
||||
case ST_OFF:
|
||||
SERVICE_LOG(real_name,LOG_SVC_STOPED);
|
||||
break;
|
||||
case RT_ERR_COMM:
|
||||
SERVICE_LOG(real_name,MSG_ERR_COMM);
|
||||
break;
|
||||
/* FIX THIS AFTER cinit-0.2 */
|
||||
case RT_TMPNOW:
|
||||
case RT_ERR:
|
||||
case RT_SVC_FAILED:
|
||||
case RT_UNSPEC:
|
||||
case RT_SUCCESS:
|
||||
case ST_NEED_FAIL:
|
||||
case ST_TMP:
|
||||
case ST_ONCE:
|
||||
case RT_NOTEXIST:
|
||||
case ST_RESPAWN:
|
||||
// SERVICE_LOG(real_name,"Ein bekanntest ding");
|
||||
break;
|
||||
/* default:
|
||||
SERVICE_LOG(real_name,MSG_SHOULD_NOT_HAPPEN);
|
||||
break; */
|
||||
}
|
||||
if( argv[1][1] == 'a') break; /* only continue if restarting */
|
||||
|
||||
case 'e': /* ein */
|
||||
switch (run_svc(real_name)) { /* run_svc fuzzys itself */
|
||||
case RT_NOTEXIST:
|
||||
SERVICE_LOG(real_name,LOG_SVC_NOTEXIST);
|
||||
break;
|
||||
case RT_SVC_FAILED:
|
||||
SERVICE_LOG(real_name,LOG_SVC_FAILED);
|
||||
break;
|
||||
case ST_FAIL:
|
||||
SERVICE_LOG(real_name,LOG_SVC_FAIL);
|
||||
break;
|
||||
case ST_ONCE:
|
||||
SERVICE_LOG(real_name,LOG_SVC_ONCE);
|
||||
break;
|
||||
case RT_ERR_COMM:
|
||||
SERVICE_LOG(real_name,MSG_ERR_COMM);
|
||||
break;
|
||||
case ST_RESPAWN:
|
||||
SERVICE_LOG(real_name,LOG_SVC_RESPAWN);
|
||||
break;
|
||||
case ST_NEED_FAIL:
|
||||
SERVICE_LOG(real_name,LOG_NEED_FAIL);
|
||||
break;
|
||||
default:
|
||||
SERVICE_LOG(real_name,MSG_SHOULD_NOT_HAPPEN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
C_USAGE(MSG_ERR_BAD_ARGS);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* uses cinit-0.2 return code style */
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* change status of a service
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* client:
|
||||
* svc = service name
|
||||
* status = status
|
||||
* pid = pid
|
||||
* sock2 = sock
|
||||
* action = ACT_WRITE
|
||||
* return: error code
|
||||
*
|
||||
* server:
|
||||
* svc = buffer
|
||||
* status = where to save status
|
||||
* svc = bufferTH_MAX
|
||||
* pid = where to save pid
|
||||
* sock2 = nsock
|
||||
* action = ACT_READ
|
||||
* return: read service lenght
|
||||
*/
|
||||
|
||||
int do_change_status(char *svc, char *status, pid_t * pid, int sock2,
|
||||
int action)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
ssize_t(*fpoint) (int, void *, size_t);
|
||||
|
||||
if(action == ACT_SERV) {
|
||||
fpoint = read;
|
||||
} else {
|
||||
fpoint = (ssize_t(*)(int, void *, size_t)) write;
|
||||
tmp = strlen(svc);
|
||||
}
|
||||
|
||||
if(fpoint(sock2, &tmp, sizeof(tmp)) == -1) { /* length */
|
||||
perror(MSG_ERR_IO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(tmp > PATH_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(fpoint(sock2, svc, tmp) == -1) { /* write service name */
|
||||
perror(MSG_ERR_IO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(fpoint(sock2, status, sizeof(*status)) == -1) { /* status */
|
||||
perror(MSG_ERR_IO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(fpoint(sock2, pid, sizeof(*pid)) == -1) { /* PID */
|
||||
perror(MSG_ERR_IO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006 Nico Schottelius (nico-linux-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 "cinit.h"
|
||||
#include "os.h"
|
||||
|
||||
/***********************************************************************
|
||||
* sig_reboot
|
||||
* Shutdown the system
|
||||
*/
|
||||
|
||||
void do_reboot(int signal)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
struct timespec ts;
|
||||
char **cmd;
|
||||
int i;
|
||||
|
||||
/* Let's disappear, we don't care about clients anymore */
|
||||
close(sock);
|
||||
/********* first SIGTERM the respawning processes **********/
|
||||
tmp = list->before;
|
||||
do {
|
||||
/* kill service watcher, which will kill processes itself */
|
||||
if( tmp->status == ST_RESPAWN) {
|
||||
kill(tmp->pid,SIGTERM);
|
||||
}
|
||||
tmp = tmp->before;
|
||||
} while( tmp != list );
|
||||
|
||||
/********* now wait for the respawn watchers to return *****/
|
||||
tmp = list->before;
|
||||
do {
|
||||
if( tmp->status == ST_RESPAWN) {
|
||||
/* wait until the respawn watcher terminated */
|
||||
waitpid(tmp->pid,&i,0);
|
||||
}
|
||||
|
||||
/* execute shutdown service FIXME: parallelize that?*/
|
||||
exec_svc(tmp->abs_path,CMD_STOP_SVC);
|
||||
tmp = tmp->before;
|
||||
} while( tmp != list );
|
||||
|
||||
/* now: all services are down, let's kill all other processes */
|
||||
if( kill(-1,SIGTERM) == -1) {
|
||||
perror(MSG_TERMKILL);
|
||||
}
|
||||
|
||||
ts.tv_sec = SLEEP_KILL; /* defined in conf/sleep_kill */
|
||||
nanosleep(&ts,NULL);
|
||||
|
||||
if( kill(-1,SIGKILL) == -1) {
|
||||
perror(MSG_KILLBILL);
|
||||
}
|
||||
D_PRINTF("SIGKILL GESENDET");
|
||||
|
||||
/* THIS IS FUCKING UNCLEAN AND SHOULD BE CLEANED UP VERY MUCH!!! */
|
||||
#define CMD_CNT 4
|
||||
|
||||
#define UMOUNT_CMD "/bin/umount"
|
||||
#define UMOUNT_ARG1 "-arfd"
|
||||
|
||||
#define MOUNT_CMD "/bin/mount"
|
||||
#define MOUNT_ARG1 "-o"
|
||||
#define MOUNT_ARG2 "remount,ro"
|
||||
#define MOUNT_ARG3 "/"
|
||||
|
||||
#define RESCUE_CMD "/bin/sh"
|
||||
|
||||
/* now: we are completley alone. umount everything, go to bed */
|
||||
cmd = (char **) malloc( (CMD_CNT+1) * ( sizeof (char*) ) );
|
||||
if(cmd) {
|
||||
/* /bin/umount -a */
|
||||
cmd[0] = UMOUNT_CMD;
|
||||
cmd[1] = UMOUNT_ARG1;
|
||||
cmd[2] = NULL;
|
||||
|
||||
i = fork();
|
||||
if(i == 0) {
|
||||
execv(cmd[0],cmd);
|
||||
_exit(1); /* if exec fails in child */
|
||||
}
|
||||
|
||||
/* /bin/mount -o remount,ro / */
|
||||
cmd[0] = MOUNT_CMD;
|
||||
cmd[1] = MOUNT_ARG1;
|
||||
cmd[2] = MOUNT_ARG2;
|
||||
cmd[3] = MOUNT_ARG3;
|
||||
cmd[4] = NULL;
|
||||
|
||||
i = fork();
|
||||
if(i == 0) {
|
||||
execv(cmd[0],cmd);
|
||||
_exit(1); /* if exec fails in child */
|
||||
}
|
||||
} else {
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
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;
|
||||
case SIGUSR2: /* rescue - destroy ourself */
|
||||
LOG(MSG_RESCUE);
|
||||
cmd[0] = RESCUE_CMD;
|
||||
cmd[1] = NULL;
|
||||
execv(cmd[0],cmd);
|
||||
panic();
|
||||
break;
|
||||
case SIGCONT: /* update */
|
||||
LOG(MSG_UPDATE);
|
||||
cmd[0] = CINIT_BIN;
|
||||
cmd[1] = NULL;
|
||||
execv(cmd[0],cmd);
|
||||
panic();
|
||||
break;
|
||||
}
|
||||
|
||||
/* do not exit, Linux does that for us */
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* write result of action
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* one handler for read and write! */
|
||||
char do_result(int nsock, char *value)
|
||||
{
|
||||
ssize_t(*fpoint) (int, void *, size_t);
|
||||
char buf;
|
||||
|
||||
if(value == NULL) { /* client */
|
||||
value = &buf;
|
||||
fpoint = read;
|
||||
} else {
|
||||
fpoint = (ssize_t(*)(int, void *, size_t)) write;
|
||||
}
|
||||
|
||||
if(fpoint(nsock, value, 1) == -1) { /* result */
|
||||
perror(MSG_ERR_IO);
|
||||
return RT_ERR_COMM;
|
||||
}
|
||||
|
||||
return *value;
|
||||
}
|
||||
|
||||
/* returns cinit-0.2-style return codes */
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* try to start a service
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include "cinit.h"
|
||||
|
||||
/* serv:
|
||||
* get buf
|
||||
* return length
|
||||
*
|
||||
* client:
|
||||
* print svc
|
||||
* return errorcode
|
||||
*/
|
||||
int do_svc_name(int sock2, char *svc, int action)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
ssize_t(*fpoint) (int, void *, size_t);
|
||||
|
||||
/*
|
||||
* set pointers
|
||||
*/
|
||||
if(action == ACT_CLIENT) {
|
||||
fpoint = (ssize_t(*)(int, void *, size_t)) write;
|
||||
tmp = strlen(svc);
|
||||
} else {
|
||||
fpoint = read;
|
||||
}
|
||||
|
||||
/*
|
||||
* read / write lenght
|
||||
*/
|
||||
if(fpoint(sock2, &tmp, sizeof(tmp)) == -1) {
|
||||
perror(MSG_ERR_IO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(tmp > PATH_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* write/read service name
|
||||
*/
|
||||
if(fpoint(sock2, svc, tmp) == -1) {
|
||||
perror(MSG_ERR_IO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
|
||||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* run_svc
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/***********************************************************************
|
||||
* exec_svc: exec service abspath C_ON or C_OFF
|
||||
*/
|
||||
|
||||
inline pid_t exec_svc(char *abspath, int action)
|
||||
{
|
||||
int tmp;
|
||||
char *p, pathtmp[PATH_MAX];
|
||||
char *sbuf = NULL, **nargv = NULL, **nenv = NULL;
|
||||
int fd, argc;
|
||||
struct stat buf;
|
||||
|
||||
cpid = fork();
|
||||
if(cpid == -1) {
|
||||
perror(MSG_ERR_FORK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***** PARENT ******/
|
||||
if(cpid > 0) {
|
||||
waitpid(cpid, &tmp, 0);
|
||||
if(WIFEXITED(tmp)) {
|
||||
if(!WEXITSTATUS(tmp)) {
|
||||
return cpid;
|
||||
}
|
||||
}
|
||||
SERVICE_LOG(abspath, LOG_SVC_FAIL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********** CHILD EXECUTION ***********/
|
||||
strcpy(pathtmp, abspath);
|
||||
strcat(pathtmp, SLASH);
|
||||
|
||||
if(action == CMD_START_SVC) {
|
||||
strcat(pathtmp, C_ON);
|
||||
} else {
|
||||
strcat(pathtmp, C_OFF);
|
||||
}
|
||||
|
||||
/*
|
||||
* readlink retrieves real name, if it is a symlink
|
||||
*/
|
||||
if((tmp = readlink(pathtmp, pathtmp, PATH_MAX)) == -1) {
|
||||
|
||||
/*
|
||||
* nothing there? fine, exit
|
||||
*/
|
||||
if(errno == ENOENT) {
|
||||
_exit(0);
|
||||
} else if(errno != EINVAL) {
|
||||
perror(MSG_READLINK);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* restore original name, file is not a link
|
||||
*/
|
||||
strcpy(pathtmp, abspath);
|
||||
strcat(pathtmp, SLASH);
|
||||
|
||||
if(action == CMD_START_SVC) {
|
||||
strcat(pathtmp, C_ON);
|
||||
} else {
|
||||
strcat(pathtmp, C_OFF);
|
||||
}
|
||||
tmp = strlen(pathtmp);
|
||||
} else {
|
||||
/*
|
||||
* add '\0', readlink forgets it
|
||||
*/
|
||||
pathtmp[tmp] = '\0';
|
||||
}
|
||||
++tmp; /* the byte to add to memory for \0; neither
|
||||
* readlink nor strlen count the \0 */
|
||||
|
||||
/********** build argv0 ********/
|
||||
nargv = (char **) malloc(sizeof(char *));
|
||||
if(nargv == NULL)
|
||||
_exit(1);
|
||||
|
||||
*nargv = (char *) malloc(tmp);
|
||||
if(*nargv == NULL)
|
||||
_exit(1);
|
||||
|
||||
strcpy(*nargv, pathtmp);
|
||||
|
||||
/********************** read params *********************/
|
||||
strcpy(pathtmp, abspath);
|
||||
strcat(pathtmp, SLASH);
|
||||
|
||||
if(action == CMD_START_SVC) {
|
||||
strcat(pathtmp, C_ONARG);
|
||||
} else {
|
||||
strcat(pathtmp, C_OFFARG);
|
||||
}
|
||||
|
||||
/*
|
||||
* open params file
|
||||
*/
|
||||
if(!stat(pathtmp, &buf)) {
|
||||
fd = open(pathtmp, O_RDONLY);
|
||||
|
||||
if(fd == -1) {
|
||||
perror(MSG_ERR_OPEN);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
argc = 0;
|
||||
|
||||
/*
|
||||
* fill sbuf with content
|
||||
*/
|
||||
while((tmp = read(fd, pathtmp, PATH_MAX)) != 0) {
|
||||
if(tmp == -1) {
|
||||
perror(MSG_ERR_READ);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
sbuf = realloc(sbuf, argc + tmp + 1);
|
||||
strncpy(&sbuf[argc], pathtmp, tmp);
|
||||
argc += tmp;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if(argc) {
|
||||
sbuf[argc] = '\0'; /* terminate string */
|
||||
}
|
||||
} else {
|
||||
sbuf = NULL;
|
||||
}
|
||||
|
||||
/************** build string **************/
|
||||
/*
|
||||
* The idea is to reuse the allocated memory. We'll simply * replace the \n
|
||||
* with \0 and set a char* to it. * We'll lose the last byte (the initial
|
||||
* \0), but we * don't care, as we die some seconds later with execv() * oh,
|
||||
* we'll only lose it, if the file is terminated by \n
|
||||
*/
|
||||
|
||||
argc = 1; /* argv0 */
|
||||
while(sbuf != NULL) {
|
||||
p = strchr(sbuf, '\n');
|
||||
nargv = realloc(nargv, sizeof(char *) * (argc + 1));
|
||||
|
||||
if(nargv == NULL) {
|
||||
LOG(MSG_ERR_ALLOC);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* set to the beginning
|
||||
*/
|
||||
nargv[argc] = sbuf;
|
||||
|
||||
/*
|
||||
* if we found \n
|
||||
*/
|
||||
if(p != NULL) {
|
||||
*p = '\0';
|
||||
} else {
|
||||
/*
|
||||
* set to the end of sbuf, not to the \0, but one before
|
||||
*/
|
||||
p = sbuf + (strlen(sbuf) - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* if next byte is 0, the end of string is found
|
||||
*/
|
||||
if(*(p + 1) == '\0') {
|
||||
sbuf = NULL;
|
||||
} else {
|
||||
sbuf = p + 1;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
|
||||
/************ close argv list **************/
|
||||
nargv = realloc(nargv, sizeof(char *) * (argc + 1)); /* 1: NULL-pointer */
|
||||
if(nargv == NULL) {
|
||||
LOG(MSG_ERR_ALLOC);
|
||||
_exit(1);
|
||||
}
|
||||
nargv[argc] = NULL; /* terminate argv list */
|
||||
|
||||
/********************** read environment *********************/
|
||||
strcpy(pathtmp, abspath);
|
||||
strcat(pathtmp, SLASH);
|
||||
if(action == CMD_START_SVC) {
|
||||
strcat(pathtmp, C_ONENV);
|
||||
} else {
|
||||
strcat(pathtmp, C_OFFENV);
|
||||
}
|
||||
|
||||
argc = 0;
|
||||
sbuf = NULL;
|
||||
if(!stat(pathtmp, &buf)) {
|
||||
fd = open(pathtmp, O_RDONLY);
|
||||
|
||||
/*
|
||||
* file exists, failing to open it is an error
|
||||
*/
|
||||
if(fd == -1) {
|
||||
perror(MSG_ERR_OPEN);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
while((tmp = read(fd, pathtmp, PATH_MAX)) != 0) {
|
||||
if(tmp == -1) {
|
||||
perror(MSG_ERR_READ);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
sbuf = realloc(sbuf, argc + tmp + 1);
|
||||
strncpy(&sbuf[argc], pathtmp, tmp);
|
||||
argc += tmp;
|
||||
}
|
||||
close(fd);
|
||||
if(argc)
|
||||
sbuf[argc] = '\0'; /* terminate string */
|
||||
}
|
||||
|
||||
/************** build environment string **************/
|
||||
argc = 0;
|
||||
while(sbuf != NULL) {
|
||||
p = strchr(sbuf, '\n');
|
||||
|
||||
nenv = realloc(nenv, sizeof(char *) * (argc + 1));
|
||||
if(nenv == NULL) {
|
||||
LOG(MSG_ERR_ALLOC);
|
||||
_exit(1);
|
||||
}
|
||||
nenv[argc] = sbuf;
|
||||
|
||||
/*
|
||||
* if we found \n
|
||||
*/
|
||||
if(p != NULL) {
|
||||
*p = '\0';
|
||||
} else {
|
||||
/*
|
||||
* set to the end of sbuf, not to the \0, but one before
|
||||
*/
|
||||
p = sbuf + (strlen(sbuf) - 1);
|
||||
}
|
||||
|
||||
if(*(p + 1) == '\0') {
|
||||
sbuf = NULL;
|
||||
} else {
|
||||
sbuf = p + 1;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
|
||||
/************ close env list **************/
|
||||
nenv = realloc(nenv, sizeof(char *) * (argc + 1));
|
||||
if(nenv == NULL) {
|
||||
LOG(MSG_ERR_ALLOC);
|
||||
_exit(1);
|
||||
}
|
||||
nenv[argc] = NULL;
|
||||
|
||||
/****************** EXECUTE ********************/
|
||||
|
||||
execve(nargv[0], nargv, nenv);
|
||||
|
||||
/*
|
||||
* we should never reach this block
|
||||
*/
|
||||
P_EXEC_FAILED(nargv[0]);
|
||||
perror(MSG_ERR_EXECVE);
|
||||
/*
|
||||
* FIXME: remove debug, remove double printing without loosing info
|
||||
*/
|
||||
sleep(3); /* debug */
|
||||
_exit(1);
|
||||
}
|
||||
106
software/cinit/browse_source/cinit-0.3pre16/src/ancient/main.c
Normal file
106
software/cinit/browse_source/cinit-0.3pre16/src/ancient/main.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
/*
|
||||
* (c) 2006 Nico Schottelius (nico-linux-cinit at schottelius.org)
|
||||
* main.c
|
||||
* main part of cinit
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h> /* ftok */
|
||||
#include <sys/msg.h> /* msgget */
|
||||
#include <stdio.h> /* perror */
|
||||
#include <stdlib.h> /* exit */
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* global variables */
|
||||
struct listitem *list;
|
||||
pid_t cpid;
|
||||
|
||||
/***********************************************************************
|
||||
* the main procedure
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *initdir;
|
||||
key_t msg_key;
|
||||
int msq_id;
|
||||
|
||||
initdir = CINIT_INIT; /* default init dir */
|
||||
list = NULL; /* list of services is empty currently */
|
||||
cpid = getpid(); /* no comment */
|
||||
|
||||
if(cpid != 1) {
|
||||
usage(CINIT_VERSION, MSG_USAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* set signal handlers
|
||||
*/
|
||||
set_signals(ACT_SERV);
|
||||
|
||||
/*
|
||||
* read arguments, 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_BOOTING, 1);
|
||||
mini_printf(initdir, 1);
|
||||
mini_printf("\n", 1);
|
||||
|
||||
if(chdir(CINIT_INIT) == -1) {
|
||||
perror(MSG_CHDIR);
|
||||
panic();
|
||||
}
|
||||
|
||||
/*
|
||||
* create message queues
|
||||
*/
|
||||
|
||||
/*
|
||||
* start init or profile
|
||||
*/
|
||||
run_init_svc(initdir);
|
||||
|
||||
/*
|
||||
* free, if we malloc()ed before
|
||||
*/
|
||||
if(initdir != CINIT_INIT) {
|
||||
free(initdir);
|
||||
}
|
||||
|
||||
/*
|
||||
* wait until we recieved the signal to create the socket
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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,30 @@
|
|||
|
||||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* tell cinit that I want change the status of a service
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* FIXME: change return code validation */
|
||||
|
||||
int msg_change_status(char *svc, char status, pid_t pid)
|
||||
{
|
||||
if(!begin_msg(CMD_CHG_STATUS)) {
|
||||
return RT_ERR_COMM;
|
||||
}
|
||||
if(!do_change_status(svc, &status, &pid, sock, ACT_CLIENT)) {
|
||||
return 0;
|
||||
}
|
||||
if(!do_result(sock, NULL)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* reboot/halt/poweroff/rescue
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* we trust the caller */
|
||||
int msg_reboot(char cmd)
|
||||
{
|
||||
if(!begin_msg(cmd)) return 0;
|
||||
close(sock);
|
||||
return 1;
|
||||
}
|
||||
/* clean for cinit-0.2 */
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* tell cinit that I want to start a service
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* **********************************************************************
|
||||
* action: 1=on, 0=off
|
||||
*/
|
||||
int msg_svc_on_off(char *svc, char action)
|
||||
{
|
||||
if(!begin_msg(action))
|
||||
return RT_ERR_COMM;
|
||||
if(!do_svc_name(sock, svc, ACT_CLIENT))
|
||||
return RT_ERR_COMM;
|
||||
return (int) do_result(sock, NULL);
|
||||
}
|
||||
|
||||
/* returns cinit-0.2-style return codes */
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/* create pipes */
|
||||
if(pipe(pfd) == -1) {
|
||||
perror(MSG_ERR_PIPE);
|
||||
panic();
|
||||
}
|
||||
/* 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,114 @@
|
|||
|
||||
/*
|
||||
* (c) 2005,2006 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* respawn_svc
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* run a service, gets (relative or absolute) path */
|
||||
pid_t respawn_svc(char *abspath)
|
||||
{
|
||||
pid_t pid;
|
||||
int tmp;
|
||||
int pipefd[2];
|
||||
struct sigaction sa;
|
||||
char delay[PATH_MAX + 1];
|
||||
|
||||
D_PRINTF(abspath);
|
||||
|
||||
if(pipe(pipefd) == -1) {
|
||||
perror(MSG_ERR_PIPE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if(pid == -1) {
|
||||
perror(MSG_ERR_FORK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************** PARENT ********************/
|
||||
if(pid > 0) {
|
||||
/*
|
||||
* if we read anything, our child succeded
|
||||
*/
|
||||
if(read(pipefd[0], &tmp, sizeof(tmp)) == -1) {
|
||||
perror(MSG_ERR_IO);
|
||||
return 0;
|
||||
}
|
||||
return pid; /* return watchers pid */
|
||||
}
|
||||
|
||||
/****************** CHILD: Service watcher ********************/
|
||||
sa.sa_handler = sig_terminate;
|
||||
sigaction(SIGTERM, &sa, NULL); /* term = kill respawing process */
|
||||
/*
|
||||
* sigterm handler should kill first our watching pid, reset the pid to 0
|
||||
* and then we'll kill ourselves
|
||||
*/
|
||||
|
||||
tmp = 1;
|
||||
if(write(pipefd[1], &tmp, sizeof(tmp)) == -1) {
|
||||
perror(MSG_ERR_IO);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* try to read delay into sock
|
||||
*/
|
||||
strcpy(delay, abspath);
|
||||
strcat(delay, SLASH);
|
||||
strcat(delay, C_DELAY);
|
||||
|
||||
/*
|
||||
* reuse sock to specify delay
|
||||
*/
|
||||
sock = -1;
|
||||
tmp = open(delay, O_RDONLY);
|
||||
if(tmp != -1) {
|
||||
pipefd[0] = read(tmp, &delay[0], PATH_MAX);
|
||||
if(pipefd[0] > 0 && pipefd[0] <= PATH_MAX) {
|
||||
delay[pipefd[0]] = 0;
|
||||
sock = atoi(delay);
|
||||
}
|
||||
close(tmp);
|
||||
}
|
||||
|
||||
do {
|
||||
/*
|
||||
* exec_svc will set cpid accordingly
|
||||
*/
|
||||
if(!exec_svc(abspath, CMD_START_SVC)) {
|
||||
if(cpid != 0) {
|
||||
D_PRINTF("sloefen");
|
||||
sleep(SLEEP_SVC);
|
||||
D_PRINTF("Zuende geschlafen");
|
||||
}
|
||||
}
|
||||
} while(cpid); /* cpid is reset by sig_terminate() */
|
||||
|
||||
/*
|
||||
* FIXME: put most code of sig_terminate here, look for no_kill
|
||||
*/
|
||||
|
||||
/*
|
||||
* start off task
|
||||
*/
|
||||
exec_svc(abspath, CMD_STOP_SVC);
|
||||
|
||||
D_PRINTF("jetzt weg");
|
||||
_exit(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 */
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 */
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
/*
|
||||
* cinit
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* run services parallel
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/***********************************************************************
|
||||
* parallel run forked() run_svc()
|
||||
*/
|
||||
|
||||
int run_run_svcs(char *abspath)
|
||||
{
|
||||
DIR *d_tmp = NULL;
|
||||
struct dirent *tdirent;
|
||||
char pathbuf[PATH_MAX + 1];
|
||||
pid_t pids[MAX_DEPS];
|
||||
int status, i, ret = 1;
|
||||
|
||||
D_PRINTF(abspath);
|
||||
|
||||
d_tmp = opendir(abspath);
|
||||
|
||||
/*
|
||||
* if there is no such dir, we are finished
|
||||
*/
|
||||
if(d_tmp == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while((tdirent = readdir(d_tmp)) != NULL) {
|
||||
/*
|
||||
* ignore . and .. and everything with a . at the beginning
|
||||
*/
|
||||
if(*(tdirent->d_name) == '.')
|
||||
continue;
|
||||
|
||||
if(i < MAX_DEPS) {
|
||||
pids[i] = fork();
|
||||
} else {
|
||||
LOG(MSG_ERR_DEPS);
|
||||
break;
|
||||
}
|
||||
|
||||
if(pids[i] == -1) { /* err */
|
||||
perror(MSG_ERR_FORK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(pids[i] == 0) { /* child */
|
||||
strcpy(pathbuf, abspath);
|
||||
strcat(pathbuf, SLASH);
|
||||
strcat(pathbuf, tdirent->d_name);
|
||||
if(run_svc(pathbuf))
|
||||
_exit(0);
|
||||
else
|
||||
_exit(1);
|
||||
} else { /* parent */
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(d_tmp);
|
||||
|
||||
/*
|
||||
* wait for pids
|
||||
*/
|
||||
--i; /* the index is one too much since last i++ */
|
||||
while(i >= 0) {
|
||||
waitpid(pids[i], &status, 0);
|
||||
|
||||
/*
|
||||
* if anything failed, we failed
|
||||
*/
|
||||
if(!WIFEXITED(status)) {
|
||||
ret = 0;
|
||||
} else {
|
||||
if(WEXITSTATUS(status)) {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
--i;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
|
||||
/*
|
||||
* (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,40 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* cinit.c
|
||||
* part of cLinux/cinit
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include "cinit.h"
|
||||
|
||||
void set_signals(int action)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
D_PRINTF("Signale setzen");
|
||||
|
||||
if(action == ACT_SERV) {
|
||||
sa.sa_handler=SIG_IGN;
|
||||
} else {
|
||||
sa.sa_handler=SIG_DFL;
|
||||
}
|
||||
sigaction(SIGINT,&sa,NULL); /* ignore ctr+c and ctr+alt+del */
|
||||
|
||||
/* what todo when a child exited, cleaning dead processes */
|
||||
if(action == ACT_SERV) {
|
||||
sa.sa_handler=sig_child;
|
||||
// SA_NOCLDSTOP
|
||||
}
|
||||
sigaction(SIGCHLD,&sa,NULL);
|
||||
|
||||
/* signal handlers to do special things with: reboot */
|
||||
if(action == ACT_SERV) {
|
||||
sa.sa_handler=sig_reboot;
|
||||
}
|
||||
sigaction(SIGUSR1,&sa,NULL); /* halt */
|
||||
sigaction(SIGUSR2,&sa,NULL); /* rescue */
|
||||
sigaction(SIGTERM,&sa,NULL); /* poweroff */
|
||||
sigaction(SIGHUP,&sa,NULL); /* reboot */
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* terminate: terminate our watching pid
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "cinit.h"
|
||||
|
||||
/* **********************************************************************
|
||||
* terminate the watching service
|
||||
*/
|
||||
void sig_terminate(int signal)
|
||||
{
|
||||
struct timespec ts;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* FIXME: only send SIGTERM, if not_kill does not exist
|
||||
*/
|
||||
if(kill(cpid, SIGTERM) == -1) {
|
||||
if(errno != ESRCH) {
|
||||
perror(MSG_TERMKILL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* variabel delay
|
||||
*/
|
||||
if(sock > 0) {
|
||||
ts.tv_sec = sock;
|
||||
} else {
|
||||
ts.tv_sec = SLEEP_KILL_SVC; /* defined in conf/sleep_kill_svc */
|
||||
}
|
||||
|
||||
/*
|
||||
* if it still exists...
|
||||
*/
|
||||
if(kill(cpid, 0) != -1) {
|
||||
/*
|
||||
* kill if there is a delay
|
||||
*/
|
||||
if(sock != 0) {
|
||||
nanosleep(&ts, NULL);
|
||||
status = kill(cpid, SIGKILL);
|
||||
if(status == -1) {
|
||||
if(errno != ESRCH) {
|
||||
perror(MSG_TERMKILL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remove zombie if killed, if delay is zero wait for it
|
||||
*/
|
||||
waitpid(cpid, &status, 0);
|
||||
|
||||
/*
|
||||
* reset the watching pid to zero (NOT THE WATCHER's!)
|
||||
*/
|
||||
cpid = 0;
|
||||
|
||||
D_PRINTF("muesste weg sein");
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
/* test case for glibc */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h> /* sigaction, sigemtpyset */
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void sig_child(int tmp)
|
||||
{
|
||||
struct timeval tv;
|
||||
pid_t pid;
|
||||
|
||||
while((pid = waitpid(-1, &tmp, WNOHANG)) > 0) {
|
||||
gettimeofday(&tv, NULL);
|
||||
printf("sighandler: %d\n", tv.tv_sec);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
struct sigaction sa;
|
||||
struct timeval tv;
|
||||
struct timespec ts;
|
||||
pid_t pid;
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
|
||||
sa.sa_handler = sig_child;
|
||||
sa.sa_flags = SA_NOCLDSTOP;
|
||||
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
|
||||
while(1) {
|
||||
pid = fork();
|
||||
|
||||
/*
|
||||
* child
|
||||
*/
|
||||
if(!pid) {
|
||||
ts.tv_sec = 2;
|
||||
nanosleep(&ts, NULL);
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
printf("child: %d\n", tv.tv_sec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ts.tv_nsec = 100000;
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* read data from cinit to the client
|
||||
*/
|
||||
|
||||
|
||||
#include "ipc.h" /* IPC */
|
||||
|
||||
/* gets a bunch of bytes and returns the answer from cinit */
|
||||
int cinit_read_from(char **dest, int len)
|
||||
{
|
||||
if(!cinit_ipc_logon()) return NULL;
|
||||
if(!cinit_ipc_connect()) return NULL;
|
||||
|
||||
/* FIXME: add length to ipc function? */
|
||||
if(!cinit_ipc_csend(data)) return NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
259
software/cinit/browse_source/cinit-0.3pre16/src/client/cmd.c
Normal file
259
software/cinit/browse_source/cinit-0.3pre16/src/client/cmd.c
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2009 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* cmd - the cinit client program - sends commands to cinit
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* getopt */
|
||||
#include <signal.h> /* signals */
|
||||
#include <stdio.h> /* printf() */
|
||||
#include <stdlib.h> /* free() */
|
||||
#include <string.h> /* strncmp */
|
||||
|
||||
#include <stdint.h> /* integers */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
|
||||
#include "cmd.h" /* own header */
|
||||
#include "signals.h" /* which signal */
|
||||
#include "svc.h" /* service related */
|
||||
#include "intern.h" /* print_errno() */
|
||||
|
||||
#include "cinit.h" /* cinit external */
|
||||
|
||||
#define C_USAGE(error) usage(USAGE_TEXT,error)
|
||||
#define MSG_IPC_ERROR "An IPC error occured while connecting to cinit. " \
|
||||
"Is cinit running?\n"
|
||||
#define MSG_UNKNOWN_SVC "Unknown service: %s\n"
|
||||
#define MSG_UNKNOWN_RET "Unknown return code: %d\n"
|
||||
|
||||
enum {
|
||||
NOTHING,
|
||||
ENABLE,
|
||||
DISABLE,
|
||||
PID,
|
||||
STATUS
|
||||
} whattodo;
|
||||
|
||||
/***********************************************************************
|
||||
* cmd: main
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char buf[CINIT_DATA_LEN];
|
||||
char *flag = NULL;
|
||||
int opt;
|
||||
int what = NOTHING;
|
||||
uint32_t ret;
|
||||
uint32_t (*fp)(char *, uint32_t); /* to select enable or disable */
|
||||
|
||||
|
||||
union {
|
||||
uint32_t status;
|
||||
pid_t pid;
|
||||
} u;
|
||||
|
||||
/*
|
||||
* -d w(ants) excluded)
|
||||
* -e n(eeds excluded)
|
||||
* -d i(nclude everything)
|
||||
*/
|
||||
|
||||
/* check for
|
||||
* d|e:
|
||||
* check for flags
|
||||
* p|s:
|
||||
* continue with service
|
||||
* h|v|V: print and exit
|
||||
*/
|
||||
while((opt = getopt(argc, argv, CMD_OPTIONS)) != -1) {
|
||||
switch (opt) {
|
||||
|
||||
/********************************************
|
||||
* Non-continuing parameters
|
||||
*/
|
||||
|
||||
/********************************************
|
||||
* help
|
||||
*/
|
||||
case 'h':
|
||||
printf(CMD_USAGE);
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/********************************************/
|
||||
case 'v': /* get version of cinit */
|
||||
ret = cinit_get_version(buf);
|
||||
switch (ret) {
|
||||
case CINIT_ASW_OK:
|
||||
printf("Version of cinit: %s\n", buf);
|
||||
return 0;
|
||||
break;
|
||||
case CINIT_ASW_IPC_ERROR:
|
||||
fprintf(stderr, MSG_IPC_ERROR);
|
||||
what = 2;
|
||||
break;
|
||||
|
||||
default: /* should not happen */
|
||||
printf(MSG_UNKNOWN_RET, ret);
|
||||
what = 3;
|
||||
break;
|
||||
}
|
||||
return what;
|
||||
break;
|
||||
|
||||
/********************************************/
|
||||
case 'V': /* version */
|
||||
printf("Version of cmd: %s\n", CMD_VERSION);
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/********************************************/
|
||||
/*
|
||||
* Continuing parameters
|
||||
*/
|
||||
|
||||
/********************************************/
|
||||
case 'e': /* enable service */
|
||||
what = ENABLE;
|
||||
flag = optarg;
|
||||
break;
|
||||
|
||||
case 'd': /* disable service */
|
||||
what = DISABLE;
|
||||
flag = optarg;
|
||||
break;
|
||||
|
||||
/********************************************/
|
||||
case 'p': /* get pid */
|
||||
what = PID;
|
||||
break;
|
||||
|
||||
/********************************************/
|
||||
case 's': /* get status */
|
||||
what = STATUS;
|
||||
break;
|
||||
|
||||
/********************************************/
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"Sorry, I did not understand what you want. Try -h, please.\n");
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(what == NOTHING) {
|
||||
fprintf(stderr,
|
||||
"That is not much you request from me. Try -h for help.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(!path_absolute(argv[optind], buf, CINIT_DATA_LEN))
|
||||
return 1;
|
||||
|
||||
fp = NULL;
|
||||
switch (what) {
|
||||
case ENABLE:
|
||||
fp = cinit_svc_enable;
|
||||
case DISABLE:
|
||||
if(!fp) fp = cinit_svc_disable;
|
||||
|
||||
u.status |= cinit_flag_to_uint32_t(flag);
|
||||
|
||||
ret = fp(buf, u.status);
|
||||
|
||||
switch (ret) {
|
||||
case CINIT_ASW_OK:
|
||||
printf("Set status of %s.\n", buf);
|
||||
what = 0;
|
||||
break;
|
||||
|
||||
case CINIT_ASW_SVC_UNKNOWN:
|
||||
printf(MSG_UNKNOWN_SVC, buf);
|
||||
what = 1;
|
||||
break;
|
||||
|
||||
case CINIT_ASW_IPC_ERROR:
|
||||
fprintf(stderr, MSG_IPC_ERROR);
|
||||
what = 2;
|
||||
break;
|
||||
|
||||
default: /* should not happen */
|
||||
printf(MSG_UNKNOWN_RET, ret);
|
||||
what = 3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PID:
|
||||
ret = cinit_svc_get_pid(buf, &(u.pid));
|
||||
switch (ret) {
|
||||
case CINIT_ASW_OK:
|
||||
printf("PID of %s: %d\n", buf, u.pid);
|
||||
what = 0;
|
||||
break;
|
||||
|
||||
case CINIT_ASW_SVC_UNKNOWN:
|
||||
printf(MSG_UNKNOWN_SVC, buf);
|
||||
what = 1;
|
||||
break;
|
||||
|
||||
case CINIT_ASW_IPC_ERROR:
|
||||
fprintf(stderr, MSG_IPC_ERROR);
|
||||
what = 2;
|
||||
break;
|
||||
|
||||
default: /* should not happen */
|
||||
printf(MSG_UNKNOWN_RET, ret);
|
||||
what = 3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATUS:
|
||||
ret = cinit_svc_get_status(buf, &(u.status));
|
||||
switch (ret) {
|
||||
case CINIT_ASW_OK:
|
||||
printf("Status of %s is: %d\n", buf, u.status);
|
||||
what = 0;
|
||||
break;
|
||||
|
||||
case CINIT_ASW_SVC_UNKNOWN:
|
||||
printf("Unknown service: %s\n", buf);
|
||||
what = 1;
|
||||
break;
|
||||
|
||||
case CINIT_ASW_IPC_ERROR:
|
||||
fprintf(stderr, MSG_IPC_ERROR);
|
||||
what = 2;
|
||||
break;
|
||||
|
||||
default: /* should not happen */
|
||||
printf(MSG_UNKNOWN_RET, ret);
|
||||
what = 3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return what;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Halt the system through a kill call
|
||||
*/
|
||||
|
||||
#include <signal.h> /* kill() */
|
||||
|
||||
#include "messages.h" /* MSG_* */
|
||||
#include "intern.h" /* print_errno() */
|
||||
#include "signals.h" /* signals mapping */
|
||||
|
||||
int main()
|
||||
{
|
||||
if(kill(1, SIG_CINIT_HALT) == -1) {
|
||||
print_errno(MSG_HALT_KILL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Reboot the system through a kill call
|
||||
*/
|
||||
|
||||
#include <signal.h> /* kill() */
|
||||
|
||||
#include "messages.h" /* MSG_* */
|
||||
#include "intern.h" /* print_errno() */
|
||||
#include "signals.h" /* signals mapping */
|
||||
|
||||
int main()
|
||||
{
|
||||
if(kill(1, SIG_CINIT_POWEROFF) == -1) {
|
||||
print_errno(MSG_POWEROFF_KILL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Reboot the system through a kill call
|
||||
*/
|
||||
|
||||
#include <signal.h> /* kill() */
|
||||
|
||||
#include "messages.h" /* MSG_* */
|
||||
#include "intern.h" /* print_errno() */
|
||||
#include "signals.h" /* signals mapping */
|
||||
|
||||
int main()
|
||||
{
|
||||
if(kill(1, SIG_CINIT_REBOOT) == -1) {
|
||||
print_errno(MSG_REBOOT_KILL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
22
software/cinit/browse_source/cinit-0.3pre16/src/comm/README
Normal file
22
software/cinit/browse_source/cinit-0.3pre16/src/comm/README
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
This directory contains the server (aka cinit) part of the communication process.
|
||||
|
||||
All the communication functions do not depend on the underlying
|
||||
inter process communication mechanism. Use the following functions:
|
||||
|
||||
- send_command(): client function: sends a command to cinit
|
||||
- send_service(): client function: send the service name to operate on
|
||||
|
||||
- read_command(): server function: reads beginning of a command
|
||||
* Extracts the command
|
||||
* reads client identification (=pid)
|
||||
* calls other functions, depending on the command send => switch()
|
||||
- read_service(): server function: reads service
|
||||
|
||||
- write_answer(): server function: answer?
|
||||
* sends answers to clients => senseful?
|
||||
|
||||
|
||||
TODO:
|
||||
- define information function, that returns various information about
|
||||
a service
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* disables a service
|
||||
*
|
||||
*/
|
||||
|
||||
#include "svc-intern.h" /* list_search */
|
||||
#include "cinit.h" /* structure: cinit_answer */
|
||||
|
||||
|
||||
/**
|
||||
* Returns the answer to the disable request to the client.
|
||||
*/
|
||||
int answer_svc_disable(char *svc, struct cinit_answer *asr)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
tmp = list_search(svc);
|
||||
if(!tmp) {
|
||||
asr->ret = CINIT_ASW_SVC_UNKNOWN;
|
||||
} else {
|
||||
asr->ret = svc_disable(tmp);
|
||||
asr->opt = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* return pid of service
|
||||
*
|
||||
*/
|
||||
|
||||
#include "svc-intern.h" /* VERSION */
|
||||
#include "cinit.h" /* structure: cinit_answer */
|
||||
|
||||
int answer_svc_pid(char *svc, struct cinit_answer *asr)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
tmp = list_search(svc);
|
||||
if(!tmp) {
|
||||
asr->ret = CINIT_ASW_SVC_UNKNOWN;
|
||||
} else {
|
||||
asr->ret = CINIT_ASW_OK;
|
||||
asr->opt = tmp->pid;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* returns status of service
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h> /* strncpy */
|
||||
#include "svc-intern.h" /* VERSION */
|
||||
#include "cinit.h" /* structure: cinit_answer */
|
||||
|
||||
int answer_svc_status(char *svc, struct cinit_answer *asr)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
tmp = list_search(svc);
|
||||
if(!tmp) {
|
||||
asr->ret = CINIT_ASW_SVC_UNKNOWN;
|
||||
} else {
|
||||
asr->ret = CINIT_ASW_OK;
|
||||
asr->opt = tmp->status;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Disable a service (with or without dependencies)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cinit.h" /* structure: cinit_answer */
|
||||
|
||||
int answer_svc_stop(char *svc, struct cinit_answer *asr)
|
||||
{
|
||||
struct listitem *tmp;
|
||||
|
||||
tmp = list_search(svc);
|
||||
if(!tmp) {
|
||||
asr->ret = CINIT_ASW_SVC_UNKNOWN;
|
||||
} else {
|
||||
if(tmp->status & (CINIT_ST_RESPAWNING | CINIT_ST_ONCE_RUN)) {
|
||||
asr->ret = svc_disable(tmp);
|
||||
} else { /* not running, nothing todo */
|
||||
asr->ret = CINIT_ASW_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* return version of cinit
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h" /* VERSION */
|
||||
#include "cinit.h" /* structure: cinit_answer */
|
||||
|
||||
int answer_version(struct cinit_answer *asr)
|
||||
{
|
||||
asr->ret = CINIT_ASW_OK;
|
||||
cinit_cp_data(asr->data, VERSION);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Append data to the existing field
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h> /* strncpy */
|
||||
#include "cinit.h" /* CINIT_DATA_LEN */
|
||||
|
||||
void cinit_append_data(char data[], char *src)
|
||||
{
|
||||
strncat(data, src, CINIT_DATA_LEN);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* fill the data field of qsn and asn
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h> /* strncpy */
|
||||
#include "cinit.h" /* CINIT_DATA_LEN */
|
||||
|
||||
void cinit_cp_data(char data[], char *src)
|
||||
{
|
||||
strncpy(data, src, CINIT_DATA_LEN);
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* cinit reads a command sent by a client, called by ipc listener
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cinit.h" /* structures */
|
||||
#include "intern.h" /* answer_svc_status() */
|
||||
|
||||
int read_command(struct cinit_question qsn, struct cinit_answer *asr)
|
||||
{
|
||||
switch (qsn.cmd) {
|
||||
case CINIT_QSN_GET_VERSION:
|
||||
if(!answer_version(asr))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case CINIT_QSN_GET_STATUS:
|
||||
if(!answer_svc_status(qsn.data, asr))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case CINIT_QSN_GET_PID:
|
||||
if(!answer_svc_pid(qsn.data, asr))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case CINIT_QSN_SVC_DISABLE:
|
||||
if(!answer_svc_disable(qsn.data, asr))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/*
|
||||
* FIXME: stopped here case CINIT_MSG_SVC_ENABLE:
|
||||
* if(!answer_svc_enable(qsn.data, asr)) return 0; break;
|
||||
*/
|
||||
|
||||
/*
|
||||
* Unknown command: should not happen :-)
|
||||
*/
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
* 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 "intern.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;
|
||||
|
||||
/***********************************************************************
|
||||
* 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;
|
||||
}
|
||||
127
software/cinit/browse_source/cinit-0.3pre16/src/core/cinit.c
Normal file
127
software/cinit/browse_source/cinit-0.3pre16/src/core/cinit.c
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2005-2009 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* 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 <signal.h> /* struct sigaction */
|
||||
|
||||
#include "intern.h" /* general things */
|
||||
#include "messages.h" /* messages */
|
||||
#include "ipc.h" /* general ipc methods */
|
||||
#include "svc-intern.h" /* gen_svc_tree */
|
||||
#include "signals.h" /* signals used by cinit */
|
||||
|
||||
struct listitem *svc_list = NULL; /* services in a dependency tree */
|
||||
struct dep *deps_pending = NULL; /* the first services to be started */
|
||||
int svc_exited; /* did some service exit? */
|
||||
|
||||
struct sigaction sigstages[SIGSTAGE_END][SIGCINIT_END];
|
||||
int cinit_global_signals[SIGCINIT_END];
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *initdir = CINIT_INIT; /* default init dir */
|
||||
|
||||
/*
|
||||
* Is this really needed? pid_t cpid;
|
||||
*
|
||||
* if(cpid != 1) { mini_printf(CINIT_VERSION,2); mini_printf(MSG_USAGE,2);
|
||||
* return 0; }
|
||||
*/
|
||||
|
||||
/* Bootup "logo" */
|
||||
mini_printf(MSG_BOOTING, 1); mini_printf(initdir, 1); mini_printf("\n", 1);
|
||||
|
||||
/* Should we start a profile? */
|
||||
while(argc > 1) {
|
||||
if(!strncmp(PROFILE, argv[argc - 1], strlen(PROFILE))) {
|
||||
initdir = 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;
|
||||
}
|
||||
|
||||
/* no configuration? - panic! */
|
||||
if(chdir(initdir) == -1) {
|
||||
print_errno(initdir);
|
||||
panic();
|
||||
}
|
||||
|
||||
/* initialize communication (IPC) */
|
||||
if(!cinit_ipc_init()) panic();
|
||||
|
||||
/* Init signal handler */
|
||||
signal_init_map(sigstages, cinit_global_signals);
|
||||
set_signals(SIGSTAGE_DAEMON);
|
||||
|
||||
/* build service dependency tree */
|
||||
if(!gen_svc_tree(initdir)) panic();
|
||||
|
||||
/* unused now, free if allocated */
|
||||
if(strcmp(initdir, CINIT_INIT)) free(initdir);
|
||||
|
||||
/* FIXME: what todo?
|
||||
* change to /, so applications have that as cwd, too Is that really
|
||||
* seneful? Does that help any application? If not, just for looking nice,
|
||||
* that's not a reason to enable it. if(chdir(SLASH) == -1) {
|
||||
* print_errno(SLASH); panic(); }
|
||||
*/
|
||||
|
||||
/* the main startup routine */
|
||||
if(!tree_exec(deps_pending)) panic();
|
||||
|
||||
/* listen to commands after startup */
|
||||
while(1) {
|
||||
/* react on service changes (=process exited) */
|
||||
if(svc_exited) svc_status_changed(deps_pending);
|
||||
|
||||
/* handle the changes */
|
||||
if(deps_pending) svc_handle_pending(deps_pending);
|
||||
|
||||
/* listen until we get a message or get interrupted */
|
||||
cinit_ipc_listen();
|
||||
|
||||
/*
|
||||
* check dependency list: perhaps we need to restart something
|
||||
*/
|
||||
/*
|
||||
* implement in cinit-0.3pre14/5
|
||||
*/
|
||||
|
||||
// tree_exec(deps_pending);
|
||||
// reuse tree_exec()?
|
||||
// if(dep) { svc_start() .. ?
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Reboot: includes shutdown, reboot and poweroff
|
||||
*/
|
||||
|
||||
#include <signal.h> /* kill() */
|
||||
#include <unistd.h> /* exit */
|
||||
|
||||
#include "signals.h" /* signal handling */
|
||||
#include "reboot.h" /* cinit_poweroff&co */
|
||||
#include "messages.h" /* messages */
|
||||
#include "svc-intern.h" /* shutdown_services */
|
||||
#include "intern.h" /* many functions */
|
||||
#include "ipc.h" /* disable ipc */
|
||||
|
||||
void do_reboot(int signal)
|
||||
{
|
||||
/*
|
||||
* do not listen to client requests anymore
|
||||
* and tell the user what happens
|
||||
*/
|
||||
LOG(MSG_SHUTDOWN_START);
|
||||
cinit_ipc_destroy();
|
||||
set_signals(SIGSTAGE_REBOOT);
|
||||
|
||||
/*
|
||||
* shutdown all services: take care about the dependency tree
|
||||
*/
|
||||
LOG(MSG_SHUTDOWN_SVC);
|
||||
shutdown_services(svc_list);
|
||||
|
||||
/*
|
||||
* now: all services are down, let's kill all other processes
|
||||
*/
|
||||
LOG(MSG_SHUTDOWN_TERM);
|
||||
if(kill(-1, SIGTERM) == -1) {
|
||||
print_errno(MSG_TERMKILL);
|
||||
}
|
||||
|
||||
sleep_before_kill();
|
||||
|
||||
LOG(MSG_SHUTDOWN_KILL);
|
||||
if(kill(-1, SIGKILL) == -1) {
|
||||
print_errno(MSG_KILLBILL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute the last command
|
||||
*/
|
||||
LOG(MSG_SHUTDOWN_LAST);
|
||||
execute_and_wait(CINIT_LAST);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
/*
|
||||
* FIXME: should we exit?
|
||||
*/
|
||||
_exit(0);
|
||||
}
|
||||
50
software/cinit/browse_source/cinit-0.3pre16/src/core/panic.c
Normal file
50
software/cinit/browse_source/cinit-0.3pre16/src/core/panic.c
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2005-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Execute something
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* execv */
|
||||
|
||||
#include "intern.h"
|
||||
#include "messages.h"
|
||||
|
||||
void panic(void)
|
||||
{
|
||||
char *nargv[2];
|
||||
|
||||
if(execute_and_wait(CINIT_PANIC))
|
||||
_exit(0);
|
||||
|
||||
/***********************************************************************
|
||||
* In case nothing helps, try to execute something that is always there.
|
||||
* (conf/c_desaster)
|
||||
*/
|
||||
nargv[0] = C_DESASTER;
|
||||
nargv[1] = NULL;
|
||||
|
||||
if(execv(nargv[0], nargv) == -1) {
|
||||
print_errno(MSG_FATAL_PANIC);
|
||||
}
|
||||
|
||||
/* We tried everything possible, die now. */
|
||||
_exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Set signal handlers
|
||||
*/
|
||||
|
||||
#include <signal.h> /* sigaction, sigemtpyset */
|
||||
#include <stdio.h> /* NULL */
|
||||
|
||||
//#include "intern.h" /* defines */
|
||||
//#include "reboot.h" /* reboot related */
|
||||
#include "signals.h" /* reboot related */
|
||||
|
||||
void set_signals(int stage)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < SIGCINIT_END; i++) {
|
||||
sigaction(cinit_global_signals[i], &sigstages[stage][i], NULL); /* what
|
||||
* todo
|
||||
* when
|
||||
* a
|
||||
* child
|
||||
* exited
|
||||
*/
|
||||
}
|
||||
|
||||
// struct sigaction sa;
|
||||
// sigemptyset(&sa.sa_mask); /* no other signals should be blocked */
|
||||
// sa.sa_flags = 0;
|
||||
// if(action == ACT_SERV) {
|
||||
// sa.sa_handler = sig_child;
|
||||
// sa.sa_flags = SA_NOCLDSTOP;
|
||||
// } else {
|
||||
// sa.sa_handler = SIG_DFL;
|
||||
// }
|
||||
|
||||
// sigaction(SIGCHLD,&sa,NULL); /* what todo when a child exited */
|
||||
|
||||
// sa.sa_flags = 0; /* reset flags */
|
||||
// if(action == ACT_SERV) {
|
||||
// sa.sa_handler = do_reboot;
|
||||
// }
|
||||
// sigaction(SIG_CINIT_HALT, &sa, NULL); /* halt */
|
||||
// sigaction(SIG_CINIT_POWEROFF, &sa, NULL); /* poweroff */
|
||||
// sigaction(SIG_CINIT_REBOOT, &sa, NULL); /* reboot */
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2005-2009 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* The child handler (may *not* exec other functions!)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "svc-intern.h" /* marking */
|
||||
|
||||
/***********************************************************************
|
||||
* sig_child: (c)collect the children
|
||||
*/
|
||||
void sig_child(int tmp)
|
||||
{
|
||||
tmp = 2; /* FIXME: how to tell stupid gcc that tmp is a must? */
|
||||
svc_exited = 1; /* FIXME: catch possible race conditions in svc_status_changed() */
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Define signal handlers / actions for the different internal stages
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include "signals.h"
|
||||
#include "reboot.h"
|
||||
#include "intern.h"
|
||||
|
||||
void signal_init_map(struct sigaction sigstages[SIGSTAGE_END][SIGCINIT_END],
|
||||
int cinit_signals[SIGCINIT_END])
|
||||
{
|
||||
/*
|
||||
* First map signals to index
|
||||
*/
|
||||
cinit_signals[SIGCINIT_HALT] = SIGUSR1;
|
||||
cinit_signals[SIGCINIT_POWEROFF] = SIGTERM;
|
||||
cinit_signals[SIGCINIT_REBOOT] = SIGHUP;
|
||||
cinit_signals[SIGCINIT_CHILD] = SIGCHLD;
|
||||
|
||||
/*
|
||||
* Then add the actions for daemon
|
||||
*/
|
||||
sigstages[SIGSTAGE_DAEMON][SIGCINIT_HALT].sa_handler = do_reboot;
|
||||
sigstages[SIGSTAGE_DAEMON][SIGCINIT_POWEROFF].sa_handler = do_reboot;
|
||||
sigstages[SIGSTAGE_DAEMON][SIGCINIT_REBOOT].sa_handler = do_reboot;
|
||||
|
||||
sigstages[SIGSTAGE_DAEMON][SIGCINIT_CHILD].sa_handler = sig_child;
|
||||
sigstages[SIGSTAGE_DAEMON][SIGCINIT_CHILD].sa_flags = SA_NOCLDSTOP;
|
||||
|
||||
/*
|
||||
* Then add the actions for client (=fork>
|
||||
*/
|
||||
sigstages[SIGSTAGE_CLIENT][SIGCINIT_HALT].sa_handler = SIG_DFL;
|
||||
sigstages[SIGSTAGE_CLIENT][SIGCINIT_POWEROFF].sa_handler = SIG_DFL;
|
||||
sigstages[SIGSTAGE_CLIENT][SIGCINIT_REBOOT].sa_handler = SIG_DFL;
|
||||
sigstages[SIGSTAGE_CLIENT][SIGCINIT_CHILD].sa_handler = SIG_DFL;
|
||||
|
||||
/*
|
||||
* Then add the actions for shutdown
|
||||
*/
|
||||
sigstages[SIGSTAGE_REBOOT][SIGCINIT_HALT].sa_handler = SIG_IGN;
|
||||
sigstages[SIGSTAGE_REBOOT][SIGCINIT_POWEROFF].sa_handler = SIG_IGN;
|
||||
sigstages[SIGSTAGE_REBOOT][SIGCINIT_REBOOT].sa_handler = SIG_IGN;
|
||||
sigstages[SIGSTAGE_REBOOT][SIGCINIT_CHILD].sa_handler = SIG_IGN;
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Execute something, but fork() before
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h> /* pid_t */
|
||||
#include <sys/wait.h> /* waitpid */
|
||||
#include <unistd.h> /* fork */
|
||||
|
||||
#include "messages.h" /* MSG_* */
|
||||
#include "intern.h" /* print_errno, execute_sth */
|
||||
|
||||
int execute_and_wait(char *svc)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* fork
|
||||
*/
|
||||
pid = fork();
|
||||
|
||||
if(pid == -1) {
|
||||
print_errno(MSG_ERR_FORK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* exec / child
|
||||
*/
|
||||
if(pid == 0) {
|
||||
execute_sth(svc); /* exits itself */
|
||||
}
|
||||
|
||||
/*
|
||||
* wait / parent
|
||||
*/
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
if(WIFEXITED(status)) {
|
||||
if(WEXITSTATUS(status) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 2006-2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Executes something: replaces us
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* _exit */
|
||||
|
||||
#include "intern.h"
|
||||
#include "build_argv.h"
|
||||
#include "messages.h" /* D_PRINTF */
|
||||
|
||||
void execute_sth(char *basename)
|
||||
{
|
||||
int tmp;
|
||||
struct ba_argv bav;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* tell the user what we execute
|
||||
*/
|
||||
mini_printf(MSG_INTRO_EXEC, 1);
|
||||
mini_printf((bav.argv)[0], 1);
|
||||
mini_printf("\n", 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,66 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 2006-2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* check whether file exists and is a file
|
||||
*/
|
||||
|
||||
#include <errno.h> /* errno */
|
||||
#include <sys/stat.h> /* stat */
|
||||
#include <stdio.h> /* NULL */
|
||||
|
||||
#include "intern.h" /* print_errno() */
|
||||
#include "svc-intern.h" /* svc_report_status() */
|
||||
#include "messages.h" /* messages.. */
|
||||
|
||||
int file_exists(char *filename)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
/*
|
||||
* check: - is it a link? if so, is it broken? report! - is it non existent?
|
||||
* -> return non-existent - is it existent, but not a regular file? report!
|
||||
*/
|
||||
if(lstat(filename, &buf) == -1) { /* lstat fails? */
|
||||
if(errno == ENOENT) {
|
||||
/*
|
||||
* FIXME: remove later
|
||||
*/
|
||||
printf("%s is not existing! => ok, most likely\n", filename);
|
||||
return FE_NOT;
|
||||
} else {
|
||||
mini_printf("anderer fehler.\n", 1);
|
||||
print_errno(filename);
|
||||
return FE_ERR;
|
||||
}
|
||||
} else {
|
||||
if(S_ISLNK(buf.st_mode)) { /* is a link */
|
||||
/*
|
||||
* check link destination
|
||||
*/
|
||||
if(stat(filename, &buf) == -1) { /* do real stat(): */
|
||||
if(errno == ENOENT) {
|
||||
svc_report_status(filename, MSG_BROKENLINK, NULL);
|
||||
return FE_NOLINK;
|
||||
} else {
|
||||
/*
|
||||
* FIXME: MSG_*, ??
|
||||
*/
|
||||
mini_printf("anderer fehler.\n", 1);
|
||||
print_errno(filename);
|
||||
return FE_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* caught all stat() errors */
|
||||
|
||||
if(!S_ISREG(buf.st_mode)) {
|
||||
svc_report_status(filename, MSG_NONREGULAR, NULL);
|
||||
return FE_OTHER;
|
||||
}
|
||||
|
||||
return FE_FILE;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2005-2009 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Print the world!
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
void mini_printf(char *str, int fd)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if(str == NULL) return;
|
||||
|
||||
p = str;
|
||||
while(*p) p++;
|
||||
|
||||
write(fd, str, (size_t) (p - str));
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 "intern.h" /* ORC_* */
|
||||
|
||||
int openreadclose(char *filename, char **where)
|
||||
{
|
||||
|
||||
int tmp;
|
||||
int cnt;
|
||||
int fd;
|
||||
char buf[512];
|
||||
|
||||
*where = NULL;
|
||||
|
||||
/*
|
||||
* what a wonderful loop
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
while((fd = close(fd)) == -1) {
|
||||
if(errno == EINTR)
|
||||
continue;
|
||||
return ORC_ERR_CLOSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* terminate string!
|
||||
*/
|
||||
(*where)[cnt] = '\0';
|
||||
|
||||
return ORC_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* create an absulte path
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* chdir(),getcwd */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include "intern.h" /* print_errno */
|
||||
#include "messages.h" /* messages */
|
||||
|
||||
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,31 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 "intern.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,25 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 "intern.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,56 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Let's sleep a little bit
|
||||
*
|
||||
*/
|
||||
|
||||
#include <time.h> /* nanosleep */
|
||||
#include <stdlib.h> /* strtol() */
|
||||
#include <errno.h> /* errno */
|
||||
|
||||
#include "intern.h" /* print_errno */
|
||||
#include "messages.h" /* messages */
|
||||
|
||||
void sleep_before_kill()
|
||||
{
|
||||
char *content;
|
||||
int tmp;
|
||||
struct timespec ts;
|
||||
|
||||
if(openreadclose(CINIT_SLEEPFILE, &content) == ORC_OK) {
|
||||
errno = 0;
|
||||
tmp = strtol(content, NULL, 10);
|
||||
if(errno != 0)
|
||||
tmp = SLEEP_KILL;
|
||||
free(content);
|
||||
} else {
|
||||
mini_printf(MSG_BUILTIN_SLEEP, 1);
|
||||
tmp = SLEEP_KILL;
|
||||
}
|
||||
|
||||
ts.tv_sec = tmp;
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
if(nanosleep(&ts, NULL) == -1) {
|
||||
print_errno(MSG_ERR_SLEEP);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 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 */
|
||||
|
||||
char *strip_final_newline(char *str)
|
||||
{
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* don't get fooled by bad pointers
|
||||
*/
|
||||
if(str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = strrchr(str, '\n');
|
||||
if(p) {
|
||||
if(*(p + 1) == '\0') {
|
||||
*p = '\0'; /* DO NOT FORGET TO TERMINATE STRING */
|
||||
str = realloc(str, (p - str));
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
/***********************************************************************
|
||||
*
|
||||
* 2005-2007 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* usage: tell the world what we want - seriously no capitalism
|
||||
* usage: tell the user what's wrong and a help text
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* _exit() */
|
||||
#include "intern.h" /* mini_printf */
|
||||
|
||||
void usage(char *banner, char *text)
|
||||
{
|
||||
/*
|
||||
* print banner + error message
|
||||
*/
|
||||
mini_printf(banner, 1);
|
||||
mini_printf(text, 1);
|
||||
_exit(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* 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
|
||||
112
software/cinit/browse_source/cinit-0.3pre16/src/include/cinit.h
Normal file
112
software/cinit/browse_source/cinit-0.3pre16/src/include/cinit.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Header file for external programs (in theory)
|
||||
*/
|
||||
|
||||
#ifndef __CINIT_EXTERNAL_HEADER
|
||||
#define __CINIT_EXTERNAL_HEADER
|
||||
|
||||
/* includes */
|
||||
#include <stdint.h> /* required for functions */
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#include <sys/types.h> /* pid_t */
|
||||
|
||||
/* limits */
|
||||
#define CINIT_DATA_LEN (PATH_MAX+1)
|
||||
|
||||
/*
|
||||
* structures: independent of the ipc code!
|
||||
*/
|
||||
|
||||
/* messages from the client */
|
||||
struct cinit_question {
|
||||
uint32_t cmd;
|
||||
uint32_t opt;
|
||||
char data[CINIT_DATA_LEN];
|
||||
};
|
||||
|
||||
/* messages from cinit */
|
||||
struct cinit_answer {
|
||||
uint32_t ret;
|
||||
uint32_t opt;
|
||||
char data[CINIT_DATA_LEN];
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* codes for messages
|
||||
*/
|
||||
enum { /* questions */
|
||||
CINIT_QSN_GET_STATUS = 0x01, /* status of a service */
|
||||
CINIT_QSN_GET_PID = 0x02, /* get pid of a service */
|
||||
CINIT_QSN_GET_VERSION = 0x04, /* version of cinit */
|
||||
CINIT_QSN_SVC_DISABLE = 0x08, /* service: stop */
|
||||
CINIT_QSN_SVC_ENABLE = 0x10, /* service: start */
|
||||
CINIT_QSN_SVC_NEEDS = 0x20, /* in/exclude needs */
|
||||
CINIT_QSN_SVC_WANTS = 0x40, /* in/exclude wants */
|
||||
CINIT_QSN_SVC_LIST = 0x80, /* list services */
|
||||
|
||||
CINIT_QSN_QUESTION_END = 0xffff /* last message */
|
||||
};
|
||||
|
||||
enum { /* answers */
|
||||
CINIT_ASW_IPC_ERROR = 0x00, /* bad error */
|
||||
CINIT_ASW_OK = 0x01, /* general ok value */
|
||||
CINIT_ASW_SVC_UNKNOWN = 0x04, /* Services is not known */
|
||||
CINIT_ASW_SVC_DISABLED = 0x08, /* service: stop */
|
||||
CINIT_ASW_SVC_ENABLED = 0x10, /* service: start */
|
||||
CINIT_ASW_SVC_ERR = 0x20, /* in/excluded needs */
|
||||
CINIT_ASW_SVC_WANTS = 0x40, /* in/excluded wants */
|
||||
CINIT_ASW_SVC_NEEDS = 0x80, /* in/excluded needs */
|
||||
CINIT_ASW_ERR_INTERN = 0x100, /* cinit internal error */
|
||||
|
||||
CINIT_ASW_ANSWER_END = 0xffff /* last message */
|
||||
};
|
||||
|
||||
enum cinit_svc_flags {
|
||||
CINIT_CMD_SVC_WANTS = 'w',
|
||||
CINIT_CMD_SVC_NEEDS = 'n'
|
||||
};
|
||||
|
||||
struct cinit_msg_msg {
|
||||
int code;
|
||||
char *msg;
|
||||
};
|
||||
|
||||
//struct cinit_msg_msg cinit_codes2messages[] = {
|
||||
|
||||
//}
|
||||
|
||||
/* functions */
|
||||
int cinit_send_to(struct cinit_question *, struct cinit_answer *);
|
||||
void cinit_cp_data(char data[], char *src);
|
||||
|
||||
void cinit_prepare_comm(struct cinit_question *qsn,
|
||||
struct cinit_answer *asr,
|
||||
uint32_t cmd);
|
||||
|
||||
uint32_t cinit_flag_to_uint32_t(char *);
|
||||
uint32_t cinit_get_version(char *);
|
||||
uint32_t cinit_svc_disable(char *svc, uint32_t flag);
|
||||
uint32_t cinit_svc_enable(char *svc, uint32_t flag);
|
||||
uint32_t cinit_svc_get_pid(char *, pid_t *status);
|
||||
uint32_t cinit_svc_get_status(char *, uint32_t *);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Header file for the cmd (cinit management)
|
||||
*/
|
||||
|
||||
#ifndef CINIT_CMD_HEADER
|
||||
#define CINIT_CMD_HEADER
|
||||
|
||||
#define CMD_USAGE "cmd - cinit management\n\n" \
|
||||
"cmd -[de [nw]] -[ps] [service] -[hvV]\n\n" \
|
||||
" -d: disable service\n" \
|
||||
" n: without needs\n" \
|
||||
" Skip needs when en/disabling\n\n"\
|
||||
" w: without wants\n" \
|
||||
" Skip wants when en/disabling\n" \
|
||||
" -e: enable service\n" \
|
||||
" see above\n" \
|
||||
" -h: get help\n" \
|
||||
" this messages" \
|
||||
" -p: get process id (pid)\n" \
|
||||
" of specified service\n" \
|
||||
" -s: get status\n" \
|
||||
" of specified service\n" \
|
||||
" -v: get version\n" \
|
||||
" of cinit\n" \
|
||||
" -V: get version\n" \
|
||||
" of cmd\n" \
|
||||
""
|
||||
|
||||
#define CMD_OPTIONS "e::d::hpsvV"
|
||||
|
||||
#define MSG_KILL "kill()"
|
||||
#define CMD_VERSION "0.2"
|
||||
|
||||
#endif
|
||||
125
software/cinit/browse_source/cinit-0.3pre16/src/include/intern.h
Normal file
125
software/cinit/browse_source/cinit-0.3pre16/src/include/intern.h
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2005-2009 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* internal stuff only :-)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CINIT_INTERN_H
|
||||
#define _CINIT_INTERN_H
|
||||
|
||||
/* includes */
|
||||
#include <sys/types.h> /* pid_t */
|
||||
#include "config.h" /* paths, socket options, etc. */
|
||||
#include "cinit.h" /* structures: answer / question */
|
||||
|
||||
/***********************************************************************
|
||||
* 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, /* everything went fine */
|
||||
ORC_ERR_NONEXISTENT, /* file does not exist */
|
||||
ORC_ERR_OPEN, /* error opening the file */
|
||||
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_NOLINK, /* file is a broken symbolic link*/
|
||||
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_LAST CINIT_CONFDIR SLASH C_LAST
|
||||
#define CINIT_SLEEPFILE CINIT_CONFDIR SLASH SLEEP_BEFORE_KILL
|
||||
|
||||
/* functions (used by server and client) */
|
||||
void mini_printf(char *str, int fd);
|
||||
//void usage(char *banner, char *stext);
|
||||
|
||||
/* core functions */
|
||||
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);
|
||||
|
||||
/* communication */
|
||||
int read_command(struct cinit_question, struct cinit_answer *);
|
||||
int answer_svc_status(char *, struct cinit_answer *);
|
||||
int answer_svc_pid(char *, struct cinit_answer *);
|
||||
int answer_version(struct cinit_answer *);
|
||||
int answer_svc_disable(char *, struct cinit_answer *);
|
||||
|
||||
/* generic */
|
||||
void execute_sth(char *basename);
|
||||
int execute_and_wait(char *svc);
|
||||
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);
|
||||
void sleep_before_kill();
|
||||
|
||||
/* util */
|
||||
void print_errno(char *text);
|
||||
|
||||
#endif /* INTERN */
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Prototypes for ipc handler
|
||||
*/
|
||||
|
||||
#ifndef CINIT_IPC_HEADER
|
||||
#define CINIT_IPC_HEADER
|
||||
|
||||
/* FIXME: change to cinit/types.h later */
|
||||
#include "cinit.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* 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 */
|
||||
|
||||
int cinit_ipc_connect(void); /* connect to init */
|
||||
|
||||
int cinit_ipc_csend(struct cinit_question *); /* ask the server */
|
||||
int cinit_ipc_cread(struct cinit_answer *); /* read answer */
|
||||
|
||||
int cinit_ipc_logoff(void); /* logoff */
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions: shared
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
include/intern.h
|
||||
include/config.h
|
||||
include/ipc.h
|
||||
include/messages.h
|
||||
include/os.h
|
||||
include/reboot.h
|
||||
include/signals.h
|
||||
include/svc.h
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* All messages
|
||||
*/
|
||||
|
||||
#ifndef _CINIT_MSG_H
|
||||
#define _CINIT_MSG_H
|
||||
|
||||
/* version */
|
||||
#define CINIT_VERSION "cinit-" VERSION
|
||||
#define MSG_BOOTING CINIT_VERSION ": Booting from "
|
||||
|
||||
#define MSG_DP ": "
|
||||
|
||||
#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_EXEC_FAILED "Failed to execute "
|
||||
|
||||
#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
|
||||
# include <stdio.h>
|
||||
# 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 */
|
||||
|
||||
/* services: how they should be printed
|
||||
* /etc/cinit/svc/long/name: started once
|
||||
* /etc/cinit/svc/long/name: is respawning
|
||||
* /etc/cinit/svc/long/name: FAILED (why it happened)
|
||||
*/
|
||||
|
||||
#define MSG_INTRO_CINIT "cinit:"
|
||||
#define MSG_INTRO_SPACE MSG_INTRO_CINIT " "
|
||||
#define MSG_INTRO_SVC MSG_INTRO_CINIT
|
||||
#define MSG_INTRO_STOP MSG_INTRO_CINIT "stop: "
|
||||
#define MSG_INTRO_EXEC MSG_INTRO_CINIT "exec: "
|
||||
|
||||
/* FIXME: remove/append, but no intro! */
|
||||
#define MSG_INTRO_FAIL "FAILED "
|
||||
#define MSG_INTRO_RESPAWN MSG_INTRO_CINIT "respawn: "
|
||||
#define MSG_INTRO_OK MSG_INTRO_CINIT "ok: "
|
||||
|
||||
#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_BUILTIN_SLEEP MSG_INTRO_STOP "Using built-in sleep"
|
||||
|
||||
#define MSG_TREE_EXEC MSG_INTRO_SPACE "Execution of reverse service tree\n"
|
||||
|
||||
/* general errors */
|
||||
#define MSG_GETCWD "Getcwd failed! Your system is most likely broken!"
|
||||
#define MSG_FATAL_PANIC MSG_INTRO_SPACE "I tried everything, but even panic() failed: "
|
||||
#define MSG_ERR_SLEEP MSG_INTRO_SPACE "Sleep did not succeed"
|
||||
#define MSG_GETTIMEOFDAY MSG_INTRO_SPACE "gettimeofday() failed!"
|
||||
|
||||
/* execution */
|
||||
//#define MSG_EXECUTING MSG_INTRO_EXEC
|
||||
|
||||
/* stat() errors */
|
||||
#define MSG_NONREGULAR "Is not a regular file."
|
||||
#define MSG_BROKENLINK "Is a broken link."
|
||||
|
||||
/* Service messages */
|
||||
#define MSG_SVC_START "Starting... "
|
||||
#define MSG_SVC_STOP "Stoping... "
|
||||
#define MSG_SVC_RESTART "Restarted."
|
||||
#define MSG_SVC_SLEEP "Sleeping before restart"
|
||||
#define MSG_SVC_OK_ONCE "Started once."
|
||||
#define MSG_SVC_OK_RESPAWN "Is respawning."
|
||||
|
||||
/* Status messages */
|
||||
#define MSG_SHUTDOWN_START MSG_INTRO_STOP "\nBeginning the shutdown process..."
|
||||
#define MSG_SHUTDOWN_SVC MSG_INTRO_STOP "Shutting down services now..."
|
||||
#define MSG_SHUTDOWN_TERM MSG_INTRO_STOP "Terminating remaining processes..."
|
||||
#define MSG_SHUTDOWN_KILL MSG_INTRO_STOP "Killing remaining processes..."
|
||||
#define MSG_SHUTDOWN_LAST MSG_INTRO_STOP "Executing final service..."
|
||||
#define MSG_POWER_OFF MSG_INTRO_STOP "Powering off..."
|
||||
#define MSG_HALT MSG_INTRO_STOP "Halting system ..."
|
||||
#define MSG_REBOOT MSG_INTRO_STOP "Rebooting ..."
|
||||
|
||||
/* client messages */
|
||||
#define MSG_HALT_KILL "halt.kill"
|
||||
#define MSG_REBOOT_KILL "reboot.kill"
|
||||
#define MSG_POWEROFF_KILL "poweroff.kill"
|
||||
|
||||
|
||||
/* reboot */
|
||||
#define MSG_TERMKILL MSG_INTRO_FAIL "SIGTERM"
|
||||
#define MSG_KILLBILL MSG_INTRO_FAIL "SIGKILL"
|
||||
|
||||
#endif /* _CINIT_MSG_H */
|
||||
34
software/cinit/browse_source/cinit-0.3pre16/src/include/os.h
Normal file
34
software/cinit/browse_source/cinit-0.3pre16/src/include/os.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* reboot specific functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CINIT_REBOOT_HEADER
|
||||
#define CINIT_REBOOT_HEADER
|
||||
|
||||
/*****************************************************************************
|
||||
* the main reboot function
|
||||
*/
|
||||
void do_reboot(int signal);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* os specific functions
|
||||
*/
|
||||
void cinit_reboot(void);
|
||||
void cinit_halt(void);
|
||||
void cinit_poweroff(void);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Functions: abstract do_reboot
|
||||
*/
|
||||
#define cinit_do_reboot() do_reboot(SIGHUP)
|
||||
#define cinit_do_halt() do_reboot(SIGUSR1)
|
||||
#define cinit_do_poweroff() do_reboot(SIGTERM)
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Define signals to use: needs signal.h to be included before.
|
||||
*/
|
||||
|
||||
#ifndef CINIT_SIGNALS_HEADER
|
||||
#define CINIT_SIGNALS_HEADER
|
||||
|
||||
#define SIG_CINIT_HALT SIGUSR1
|
||||
#define SIG_CINIT_POWEROFF SIGTERM
|
||||
#define SIG_CINIT_REBOOT SIGHUP
|
||||
#define SIG_CINIT_CHILD SIGCHLD
|
||||
|
||||
enum {
|
||||
SIGSTAGE_REBOOT,
|
||||
SIGSTAGE_DAEMON,
|
||||
SIGSTAGE_CLIENT,
|
||||
SIGSTAGE_END
|
||||
};
|
||||
|
||||
enum {
|
||||
SIGCINIT_HALT,
|
||||
SIGCINIT_POWEROFF,
|
||||
SIGCINIT_REBOOT,
|
||||
SIGCINIT_CHILD,
|
||||
SIGCINIT_END
|
||||
};
|
||||
|
||||
#include <signal.h>
|
||||
struct cinit_signal_map {
|
||||
int signal;
|
||||
struct sigaction sigstages;
|
||||
};
|
||||
|
||||
|
||||
void signal_init_map(struct sigaction sigstages[SIGSTAGE_END][SIGCINIT_END], int cinit_signals[SIGCINIT_END]);
|
||||
void set_signals(int stage);
|
||||
|
||||
/* global vars */
|
||||
extern int cinit_global_signals[SIGCINIT_END]; /* maps signal codes to index */
|
||||
extern struct sigaction sigstages[SIGSTAGE_END][SIGCINIT_END];
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2009 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Internal service specifics
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CINIT_SVC_INTERN_H
|
||||
#define __CINIT_SVC_INTERN_H
|
||||
|
||||
/* includes */
|
||||
#include <sys/types.h> /* pid_t */
|
||||
#include <stdint.h> /* int types */
|
||||
#include "config.h" /* paths, socket options, etc. */
|
||||
#include "cinit.h" /* LEN */
|
||||
|
||||
/* service tree item */
|
||||
struct listitem {
|
||||
struct listitem *prev; /* previous item */
|
||||
struct listitem *next; /* next item */
|
||||
|
||||
char abs_path[CINIT_DATA_LEN]; /* name of service */
|
||||
uint32_t status; /* current status */
|
||||
int waitpid; /* result of last waitpid call */
|
||||
pid_t pid; /* pid of service / respawn watcher */
|
||||
time_t start; /* time the process was started last time */
|
||||
time_t exited; /* time the process exited */
|
||||
|
||||
|
||||
struct dep *wanted_by; /* list of services that want this service */
|
||||
struct dep *needed_by; /* 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 */
|
||||
|
||||
struct listitem *changed; /* list of changed services */
|
||||
};
|
||||
|
||||
/* list of dependencies */
|
||||
struct dep {
|
||||
struct dep *prev;
|
||||
struct dep *next;
|
||||
struct listitem *svc;
|
||||
};
|
||||
|
||||
/* variables */
|
||||
extern struct dep *deps_pending; /* the services to handle */
|
||||
extern struct listitem *svc_list; /* the list of services */
|
||||
extern int svc_exited; /* mark change */
|
||||
|
||||
/* list functions */
|
||||
struct listitem *list_insert(char *path, uint32_t status);
|
||||
int list_delete_byname(char *path);
|
||||
int list_delete_bypointer(struct listitem *);
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
uint32_t svc_set_status(struct listitem *li, uint32_t 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 shutdown_services(struct listitem *start);
|
||||
|
||||
void svc_start(struct listitem *);
|
||||
void svc_stop_deps(struct listitem *, int);
|
||||
uint32_t svc_disable(struct listitem *);
|
||||
int svc_status_changed();
|
||||
int svc_handle_pending(struct dep *pending);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* to decide whether to operate on needs or wants
|
||||
*/
|
||||
enum dep_types {
|
||||
DEP_WANTS,
|
||||
DEP_NEEDS
|
||||
};
|
||||
|
||||
#endif /* _CINIT_SVC_INTERN_H */
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Service status messages
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CINIT_SVC_MESSAGES_H
|
||||
#define __CINIT_SVC_MESSAGES_H
|
||||
|
||||
#include "svc.h"
|
||||
|
||||
struct cinit_svc_msg {
|
||||
int code;
|
||||
char *msg;
|
||||
};
|
||||
|
||||
struct cinit_svc_msg cinit_svc_msg_codes[] = {
|
||||
{ CINIT_ST_SH_ONCE, "Service should be started once" },
|
||||
{ CINIT_ST_SH_RESPAWN, "Service should respawn" },
|
||||
{ CINIT_ST_ONCE_OK, "Service successfully started once" },
|
||||
{ CINIT_ST_ONCE_FAIL, "Service failed to start once" },
|
||||
{ CINIT_ST_RESPAWNING, "Service is respawning" },
|
||||
{ CINIT_ST_NEED_FAILD, "One ore more needs failed" },
|
||||
{ CINIT_ST_IN_LIST, "Service is in starter list" },
|
||||
{ CINIT_ST_BAD_ERR, "Some strange error happened" },
|
||||
{ CINIT_ST_ONCE_RUN, "Service is currently running once" },
|
||||
{ CINIT_ST_NOT_EXIST, "This service does not exist" }
|
||||
};
|
||||
|
||||
#endif /* _CINIT_SVC_H */
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2009 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Service status (also exposed to the outside)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CINIT_SVC_H
|
||||
#define __CINIT_SVC_H
|
||||
|
||||
/***********************************************************************
|
||||
* The real status types a service may have (ignore above)
|
||||
* We have 32 Bits, we should use them ;-)
|
||||
*/
|
||||
enum cinit_svc_status {
|
||||
/* first define basics */
|
||||
CINIT_ST_SH_ONCE = 0x1, /* service SHould be started once yx*/
|
||||
CINIT_ST_SH_RESPAWN = 0x2, /* service SHould respawn yx*/
|
||||
CINIT_ST_ONCE_OK = 0x4, /* service was successfully started once */
|
||||
CINIT_ST_ONCE_FAIL = 0x8, /* service failed to start */
|
||||
CINIT_ST_RESPAWNING = 0x10, /* service is respawning */
|
||||
CINIT_ST_NEED_FAILD = 0x20, /* this service is not started, need failed x*/
|
||||
CINIT_ST_IN_LIST = 0x40, /* this service is being started (= in list) */
|
||||
CINIT_ST_BAD_ERR = 0x80, /* some kind of error that SHOULD NOT happen */
|
||||
CINIT_ST_ONCE_RUN = 0x100, /* the once process is currently running yx*/
|
||||
CINIT_ST_NOT_EXIST = 0x200, /* there's no such service in our database */
|
||||
CINIT_ST_SH_STOP = 0x400, /* service was running, is being stopped x*/
|
||||
CINIT_ST_STOPPED = 0x800, /* service is stopped x*/
|
||||
CINIT_ST_STOP_FAIL = 0x1000 /* service failed to stop..strange situation */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Possibilities the needs of a service may have
|
||||
*/
|
||||
enum cinit_svc_needs_status {
|
||||
CINIT_SNS_NEEDS_STARTED = 1, /* all needs are started. We may start, too */
|
||||
CINIT_SNS_NEEDS_FAILED, /* one ore more needs failed */
|
||||
CINIT_SNS_NEEDS_UNFINISHED /* one ore more needs are not yet started */
|
||||
};
|
||||
/***********************************************************************
|
||||
* How to start/stop a service
|
||||
*/
|
||||
enum cinit_svc_start_stop_options {
|
||||
CINIT_SSSO_COMPLETE = 0x0, /* with all dependencies */
|
||||
CINIT_SSSO_WO_NEEDS = 0x1, /* without needs */
|
||||
CINIT_SSSO_WO_WANTS = 0x2, /* without wants */
|
||||
CINIT_SSSO_WO_BOTH = 0x4 /* without both */
|
||||
};
|
||||
#endif /* _CINIT_SVC_H */
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
This implementation uses the new realtime inferface of
|
||||
posix instead of the old one functions.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Create new queues: One for recieving, one for sending
|
||||
*
|
||||
*/
|
||||
|
||||
#include <mqueue.h>
|
||||
|
||||
#include "cinit.h"
|
||||
#include "config.h"
|
||||
#include "msgq-rt.h"
|
||||
|
||||
int cinit_ipc_init(void)
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#include <mqueue.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
mqd_t readq = mq_open("/test",O_RDWR|O_CREAT|O_EXCL);
|
||||
//mqd_t readq = mq_open("/bin/ls",O_RDWR|O_CREAT|O_EXCL);
|
||||
|
||||
if(readq == -1) {
|
||||
perror("oh nein");
|
||||
return 1;
|
||||
}
|
||||
mqd_t writeq = mq_open("/bin/cp",O_WRONLY|O_CREAT|O_EXCL);
|
||||
if(readq == -1) {
|
||||
perror("oh oh nein");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Create new queues: One for recieving, one for sending
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CINIT_IPC_HEADER
|
||||
#define CINIT_IPC_HEADER
|
||||
|
||||
#define MSGQ_PATHNAME "/cinit" /* identifier */
|
||||
|
||||
/***********************************************************************
|
||||
* 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_DESTROY "msgq-destroy"
|
||||
|
||||
#endif
|
||||
|
|
@ -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,28 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Client reads messages from cinit
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/msg.h> /* msg* */
|
||||
#include <string.h> /* memcpy() */
|
||||
#include <unistd.h> /* getpid() */
|
||||
#include "intern.h" /* print_errno */
|
||||
#include "msgq.h" /* msq specific */
|
||||
|
||||
int cinit_ipc_cread(struct cinit_answer *buf)
|
||||
{
|
||||
struct cinit_msgq_server asr;
|
||||
|
||||
if(msgrcv(__cinit_mq_in, &asr, sizeof(asr.asr), getpid(), 0) == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_MSGRCV);
|
||||
return 0;
|
||||
}
|
||||
memcpy(buf, &(asr.asr), sizeof(*buf));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Client sends messages to cinit
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/msg.h> /* msgget */
|
||||
#include <string.h> /* memcpy() */
|
||||
#include "intern.h" /* print_errno */
|
||||
#include "msgq.h" /* structure */
|
||||
|
||||
int cinit_ipc_csend(struct cinit_question *qsn)
|
||||
{
|
||||
struct cinit_msgq_client msg;
|
||||
|
||||
msg.mtype = 1; /* cinit = 1 */
|
||||
|
||||
/* copy question structure into the msgq-structure */
|
||||
memcpy(&(msg.qsn), qsn, sizeof(msg.qsn));
|
||||
|
||||
if(msgsnd(__cinit_mq_out, &msg, sizeof(msg.qsn), 0) == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_MSGSEND);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006-2007 Nico Schottelius (nico-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 "intern.h" /* print_errno */
|
||||
|
||||
void cinit_ipc_destroy(void)
|
||||
{
|
||||
if(msgctl(__cinit_mq_in, IPC_RMID, NULL) == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_DESTROY); /* print warning, continue */
|
||||
}
|
||||
if(msgctl(__cinit_mq_out, IPC_RMID, NULL) == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_DESTROY); /* print warning, continue */
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006-2007 Nico Schottelius (nico-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 "intern.h" /* print_errno */
|
||||
#include "msgq.h" /* message queue */
|
||||
|
||||
int cinit_ipc_init(void)
|
||||
{
|
||||
key_t k_tmp;
|
||||
|
||||
/* to_server */
|
||||
k_tmp = ftok(__CINIT_MSGQ_PATHNAME, __CINIT_MSGQ_TO_SERVER);
|
||||
if(k_tmp == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_FTOK);
|
||||
return 0;
|
||||
}
|
||||
__cinit_mq_in = msgget(k_tmp, __CINIT_MSGQ_PERMS | IPC_CREAT);
|
||||
if(__cinit_mq_in == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_MSGGET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
k_tmp = ftok(__CINIT_MSGQ_PATHNAME, __CINIT_MSGQ_TO_CLIENT);
|
||||
if(k_tmp == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_FTOK);
|
||||
return 0;
|
||||
}
|
||||
__cinit_mq_out = msgget(k_tmp, __CINIT_MSGQ_PERMS | IPC_CREAT);
|
||||
if(__cinit_mq_out == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_MSGGET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*******************************************************************************
|
||||
*
|
||||
* 2006-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
* Listen to messages
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* printf() */
|
||||
|
||||
#include <sys/msg.h> /* msg* */
|
||||
#include <errno.h> /* errno */
|
||||
|
||||
#include "intern.h" /* print_errno */
|
||||
#include "msgq.h" /* structs */
|
||||
|
||||
int cinit_ipc_listen(void)
|
||||
{
|
||||
int tmp;
|
||||
struct cinit_msgq_client qsn;
|
||||
struct cinit_msgq_server asr;
|
||||
struct msqid_ds msq;
|
||||
|
||||
tmp = msgrcv(__cinit_mq_in, &qsn, sizeof (qsn.qsn), 0, 0);
|
||||
|
||||
/* message system problem */
|
||||
if(tmp == -1) {
|
||||
if(errno != EINTR) {
|
||||
print_errno(__CINIT_MSG_MSGQ_MSGRCV);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* retrieve pid */
|
||||
if(msgctl(__cinit_mq_in, IPC_STAT, &msq) == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_MSGCTL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!read_command(qsn.qsn, &(asr.asr))) {
|
||||
/* FIXME: mini_print */
|
||||
printf("read command failed\n");
|
||||
|
||||
asr.asr.ret = CINIT_ASW_ERR_INTERN;
|
||||
}
|
||||
|
||||
asr.mtype = msq.msg_lspid;
|
||||
if(msgsnd(__cinit_mq_out, &asr, sizeof(asr.asr), 0) == -1) {
|
||||
/* FIXME: do different things on differen errnos ... */
|
||||
print_errno("msgsend/answer");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2007 Nico Schottelius (nico-cinit schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Disconnect from cinit
|
||||
*
|
||||
*/
|
||||
|
||||
int cinit_ipc_logoff(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006-2007 Nico Schottelius (nico-cinit schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* Listen to messages
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h> /* ftok */
|
||||
#include <sys/msg.h> /* msgget */
|
||||
#include "intern.h" /* print_errno */
|
||||
#include "msgq.h" /* msgq constants */
|
||||
|
||||
int cinit_ipc_logon(void)
|
||||
{
|
||||
key_t k_tmp;
|
||||
|
||||
/* generiere nen schluessel: andersrum als im Server */
|
||||
k_tmp = ftok(__CINIT_MSGQ_PATHNAME, __CINIT_MSGQ_TO_CLIENT);
|
||||
if(k_tmp == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_FTOK);
|
||||
return 0;
|
||||
}
|
||||
__cinit_mq_in = msgget(k_tmp, 0);
|
||||
if(__cinit_mq_in == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_MSGGET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
k_tmp = ftok(__CINIT_MSGQ_PATHNAME, __CINIT_MSGQ_TO_SERVER);
|
||||
if(k_tmp == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_FTOK);
|
||||
return 0;
|
||||
}
|
||||
__cinit_mq_out = msgget(k_tmp, 0);
|
||||
if(__cinit_mq_out == -1) {
|
||||
print_errno(__CINIT_MSG_MSGQ_MSGGET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 2006-2007 Nico Schottelius (nico-cinit //@\\ schottelius.org)
|
||||
*
|
||||
* part of cLinux/cinit
|
||||
*
|
||||
* header of message queuing interface
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CINIT_IPC_HEADER
|
||||
#define __CINIT_IPC_HEADER
|
||||
|
||||
#include <cinit.h> /* structures */
|
||||
|
||||
/***********************************************************************
|
||||
* configuration
|
||||
*/
|
||||
|
||||
#define __CINIT_MSGQ_PATHNAME "/bin/sh" /* should be on every *nix */
|
||||
#define __CINIT_MSGQ_TO_SERVER 'i' /* also for ftok */
|
||||
#define __CINIT_MSGQ_TO_CLIENT 'o' /* also for ftok */
|
||||
#define __CINIT_MSGQ_PERMS 0660 /* queue permissions */
|
||||
|
||||
/***********************************************************************
|
||||
* global variables: FIXME: rename, we're in client namespace!
|
||||
*/
|
||||
int __cinit_mq_in; /* input */
|
||||
int __cinit_mq_out; /* output */
|
||||
|
||||
/***********************************************************************
|
||||
* structures
|
||||
*/
|
||||
|
||||
/* messages _from_ the client _to_ the server */
|
||||
struct cinit_msgq_client {
|
||||
long mtype;
|
||||
struct cinit_question qsn;
|
||||
};
|
||||
|
||||
/* messages _from_ the server _to_ the client */
|
||||
struct cinit_msgq_server {
|
||||
long mtype;
|
||||
struct cinit_answer asr;
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* Messages
|
||||
*/
|
||||
|
||||
#define __CINIT_MSG_MSGQ_FTOK "ftok"
|
||||
#define __CINIT_MSG_MSGQ_MSGGET "msgget"
|
||||
#define __CINIT_MSG_MSGQ_MSGCTL "msgctl"
|
||||
#define __CINIT_MSG_MSGQ_MSGSEND "msgsend"
|
||||
#define __CINIT_MSG_MSGQ_MSGRCV "msgrcv"
|
||||
#define __CINIT_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,24 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* tell cinit that I want to start a service
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "cinit.h"
|
||||
|
||||
int begin_msg(char cmd)
|
||||
{
|
||||
sock = connect_sock(sock);
|
||||
if( sock == -1 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(write(sock,&cmd,sizeof(cmd)) == -1) {
|
||||
perror(MSG_ERR_IO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -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,38 @@
|
|||
/*
|
||||
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
|
||||
* run_svc
|
||||
* part of cinit
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* memset, strcpy */
|
||||
|
||||
#include "cinit.h"
|
||||
|
||||
/* open socket connection to cinit-serv and close original socket */
|
||||
int connect_sock(int socke)
|
||||
{
|
||||
int nsock;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
close(socke);
|
||||
|
||||
nsock = socket(PF_UNIX,SOCK_STREAM,0);
|
||||
if( nsock == -1 ) {
|
||||
perror(MSG_SOCKET);
|
||||
return -1;
|
||||
}
|
||||
socke = sizeof(addr);
|
||||
memset(&addr,0,socke);
|
||||
strcpy(addr.sun_path, CINIT_SOCK);
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
if(connect(nsock,(struct sockaddr *)&addr,socke) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nsock;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
Build a small library that can be used by different applications, that provides:
|
||||
|
||||
Constants / Macros:
|
||||
for cinit_halt:
|
||||
CINIT_HALT
|
||||
CINIT_REBOOT
|
||||
CINIT_POWEROFF
|
||||
|
||||
for cinit_svc_start/stop:
|
||||
CINIT_SVC_NORMAL
|
||||
CINIT_SVC_NEEDS
|
||||
CINIT_SVC_ONLY
|
||||
CINIT_SVC_WANTS
|
||||
|
||||
Functions:
|
||||
void cinit_halt(int how);
|
||||
int cinit_svc_start(char *svc, int how);
|
||||
int cinit_svc_stop(char *svc, int how);
|
||||
int cinit_svc_stop(char *svc, int how);
|
||||
|
||||
This lib must then include:
|
||||
- choosen ipc functions
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Converts cher * to uint32_t for svc operations
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* NULL */
|
||||
#include <string.h> /* strchr */
|
||||
#include <stdint.h> /* integers */
|
||||
|
||||
#include "cinit.h" /* constants */
|
||||
|
||||
uint32_t cinit_flag_to_uint32_t(char *flag)
|
||||
{
|
||||
uint32_t ret = 0; /* no flags */
|
||||
|
||||
if(flag != NULL) {
|
||||
if(strchr(flag, CINIT_CMD_SVC_NEEDS)) {
|
||||
ret |= CINIT_QSN_SVC_NEEDS;
|
||||
}
|
||||
if(strchr(flag, CINIT_CMD_SVC_WANTS)) {
|
||||
ret |= CINIT_QSN_SVC_WANTS;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Retrieves version of cinit
|
||||
*/
|
||||
|
||||
#include "cinit.h" /* header for clients */
|
||||
|
||||
uint32_t cinit_get_version(char *buf)
|
||||
{
|
||||
struct cinit_question qsn;
|
||||
struct cinit_answer asr;
|
||||
|
||||
cinit_prepare_comm(&qsn, &asr, CINIT_QSN_GET_VERSION);
|
||||
if(!cinit_send_to(&qsn, &asr))
|
||||
return CINIT_ASW_IPC_ERROR;
|
||||
cinit_cp_data(buf, asr.data);
|
||||
|
||||
return asr.ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* purpose_of_this_file_is_also_there_behind_the_big_header
|
||||
*
|
||||
*/
|
||||
|
||||
#include "" /* include global header */
|
||||
int cinit_halt(int how)
|
||||
{
|
||||
switch (how) {
|
||||
case 'p': /* power off */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Prepares the communication
|
||||
*/
|
||||
|
||||
#include <string.h> /* str*, memset */
|
||||
#include <stdint.h> /* uint32_t */
|
||||
|
||||
#include "cinit.h" /* header for clients */
|
||||
|
||||
void cinit_prepare_comm(struct cinit_question *qsn, struct cinit_answer *asr,
|
||||
uint32_t cmd)
|
||||
{
|
||||
memset(qsn, '\0', sizeof(struct cinit_question));
|
||||
memset(asr, '\0', sizeof(struct cinit_answer));
|
||||
|
||||
qsn->cmd = cmd;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* sends data from the client to cinit
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ipc.h" /* IPC */
|
||||
#include "cinit.h" /* struct cinit_message */
|
||||
|
||||
int cinit_send_to(struct cinit_question *data, struct cinit_answer *res)
|
||||
{
|
||||
if(!cinit_ipc_logon())
|
||||
return 0;
|
||||
if(!cinit_ipc_csend(data))
|
||||
return 0;
|
||||
if(!cinit_ipc_cread(res))
|
||||
return 0;
|
||||
if(!cinit_ipc_logoff())
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Disables a service
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h> /* integers */
|
||||
|
||||
#include "cinit.h" /* header for clients */
|
||||
|
||||
/*
|
||||
* to cinit:
|
||||
* disable + flags
|
||||
* from cinit:
|
||||
* status
|
||||
* unknown service
|
||||
* disabled the service
|
||||
*
|
||||
* disabled the service and needs
|
||||
* disabled the service and wants
|
||||
* disabled the service and needs and wants
|
||||
*
|
||||
* if it is one of the last three it follows
|
||||
* uint32_t num: how many services stopped
|
||||
* num times
|
||||
*
|
||||
* uint32_t len (excluding \0)
|
||||
* char name[]
|
||||
*/
|
||||
|
||||
uint32_t cinit_svc_disable(char *svc, uint32_t flag)
|
||||
{
|
||||
struct cinit_question qsn;
|
||||
struct cinit_answer asr;
|
||||
|
||||
cinit_prepare_comm(&qsn, &asr, CINIT_QSN_SVC_DISABLE);
|
||||
cinit_cp_data((qsn.data), svc);
|
||||
|
||||
qsn.opt = flag;
|
||||
|
||||
if(!cinit_send_to(&qsn, &asr))
|
||||
return CINIT_ASW_IPC_ERROR;
|
||||
|
||||
/*
|
||||
* FIXME: 0.3pre15: add retrieval of services
|
||||
*/
|
||||
|
||||
return asr.ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Retrieves pid of a service
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h> /* integers */
|
||||
#include "cinit.h" /* header for clients */
|
||||
|
||||
uint32_t cinit_svc_enable(char *svc, uint32_t flag)
|
||||
{
|
||||
struct cinit_question qsn;
|
||||
struct cinit_answer asr;
|
||||
|
||||
cinit_prepare_comm(&qsn, &asr, CINIT_QSN_SVC_ENABLE);
|
||||
cinit_cp_data((qsn.data), svc);
|
||||
|
||||
qsn.opt = flag;
|
||||
|
||||
if(!cinit_send_to(&qsn, &asr))
|
||||
return CINIT_ASW_IPC_ERROR;
|
||||
|
||||
/*
|
||||
* add logic to display started services here or: add logic to start
|
||||
* dependend services in here: want to start a -> cinit returns needs b
|
||||
*/
|
||||
|
||||
return CINIT_ASW_IPC_ERROR;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Retrieves pid of a service
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h> /* pid_t */
|
||||
#include <stdint.h> /* integers */
|
||||
#include "cinit.h" /* header for clients */
|
||||
|
||||
uint32_t cinit_svc_get_pid(char *name, pid_t * status)
|
||||
{
|
||||
struct cinit_question qsn;
|
||||
struct cinit_answer asr;
|
||||
|
||||
cinit_prepare_comm(&qsn, &asr, CINIT_QSN_GET_PID);
|
||||
cinit_cp_data((qsn.data), name);
|
||||
|
||||
if(!cinit_send_to(&qsn, &asr))
|
||||
return CINIT_ASW_IPC_ERROR;
|
||||
|
||||
*status = asr.opt;
|
||||
|
||||
return asr.ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 2007-2008 Nico Schottelius (nico-cinit at schottelius.org)
|
||||
*
|
||||
* This file is part of cinit.
|
||||
|
||||
* cinit is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* cinit is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with cinit. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*
|
||||
* Retrieves status of a service
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h> /* integers */
|
||||
#include "cinit.h" /* header for clients */
|
||||
|
||||
uint32_t cinit_svc_get_status(char *name, uint32_t * status)
|
||||
{
|
||||
struct cinit_question qsn;
|
||||
struct cinit_answer asr;
|
||||
|
||||
cinit_prepare_comm(&qsn, &asr, CINIT_QSN_GET_STATUS);
|
||||
cinit_cp_data((qsn.data), name);
|
||||
|
||||
if(!cinit_send_to(&qsn, &asr))
|
||||
return CINIT_ASW_IPC_ERROR;
|
||||
|
||||
*status = asr.opt;
|
||||
|
||||
return asr.ret;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue