www.nico.schottelius.org/software/cinit/browse_source/cinit-0.0.8/old/cservice.c01
Nico Schottelius 423ba10303 import cinit from unix.schottelius.org
Signed-off-by: Nico Schottelius <nico@ikn.schottelius.org>
2009-09-16 12:53:45 +02:00

185 lines
3.8 KiB
Text

/*
* (c) 2005 Nico Schottelius (nico-linux at schottelius.org)
* cservice: control cinit
* 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>
/* mount */
#include <sys/mount.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h> /* nanosleep */
#include "cinit.h"
/* global variable */
struct listitem *list;
int sock, logfd;
/***********************************************************************
* cservice - control cinit
*/
#define CSERVICE_BANNER "cservice - control cinit\n\n"
#define USAGE_TEXT "\n\nUsage:\n\ncservice -[fund] <service>\n" \
"\t-u\t- (up) start a service (including all needed depedencies)\n" \
"\t-d\t- (down) kill a respawing service\n\n" \
"\t-f\t- (force) force starting service and all dependencies\n" \
"\t-n\t- (no dependency) start a service, don't care about dependencies\n\n"
void usage(char *stext)
{
write(1,CSERVICE_BANNER,strlen(CSERVICE_BANNER));
write(1,stext,strlen(stext));
write(1,USAGE_TEXT,strlen(USAGE_TEXT));
_exit(1);
}
int main(int argc, char **argv)
{
struct stat sbuf;
pid_t pid;
struct sockaddr_un addr;
char svc_dir[PATH_MAX+1];
int tmp;
/* argv */
if(argc != 3) usage("Too less arguments!");
if(argv[1][0] != '-') usage("Wrong arguments");
if(strlen(argv[1]) != 2) usage("Wrong parameter length");
switch(argv[1][1]) {
case 'o': /* on */
// run_-vc(argv[2]);
break;
case 'k': /* kill */
// msg_kill_svc(argv[2]);
break;
case 'p': /* power off */
msg_reboot(CMD_POWEROFF);
break;
case 'r': /* reboot */
msg_reboot(CMD_REBOOT);
break;
case 'h': /* halt */
msg_reboot(CMD_HALT);
break;
default:
usage("Unknown parameter");
break;
}
/* absolute the service */
if( argv[2][0] == '/') {
if(strlen(argv[2]) > PATH_MAX) usage("Servicename too long");
strcpy(svc_dir,argv[2]);
} else {
if( ( strlen(CINIT_DIR)+strlen(argv[2]) ) > PATH_MAX)
usage("Servicename too long");
strcpy(svc_dir,CINIT_DIR);
strcat(svc_dir,argv[2]);
}
tmp = readlink(svc_dir,svc_dir,PATH_MAX);
if(tmp == -1) {
if(errno != EINVAL) {
perror(MSG_READLINK);
_exit(1);
}
}
/* stat, checkdir */
if( stat(svc_dir,&sbuf) ) {
perror(MSG_INIT_MISS);
_exit(1);
}
if( ! S_ISDIR(sbuf.st_mode) ) {
mini_printf(MSG_NOT_DIR);
_exit(1);
}
if( chdir(svc_dir) == -1) {
perror(MSG_CHDIR);
_exit(1);
}
switch(argv[1][1]) {
case 't':
break;
case 'h':
/* recursive find dependencies, this will take long time :( */
find_deps(svc_dir)
break;
case 'i':
run_svc(svc_dir);
break;
case 'l':
break;
case 'o':
break;
default: usage("Unknown Parameter");
}
/******************** begin socket **********************/
sock = socket(AF_UNIX,SOCK_STREAM,0); /* create socket */
if( sock == -1 ) {
perror(MSG_SOCKET);
}
/* tell the socket, _we_ want to get SIGIO! */
pid = getpid();
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);
}
/* start listening */
if(listen(sock,SOCK_QUEUE) == -1) {
perror(MSG_LISTEN);
}
return 0;
}