Skip to content
Snippets Groups Projects
Commit 9fe81661 authored by Eric Vidal's avatar Eric Vidal :speech_balloon:
Browse files

split 66-scandir, add 66-scanctl, works on scandir begins

parent 2a8450cd
No related branches found
No related tags found
No related merge requests found
......@@ -23,6 +23,7 @@ src/66/66-hpr.o src/66/66-hpr.lo: src/66/66-hpr.c src/include/66/config.h src/in
src/66/66-info.o src/66/66-info.lo: src/66/66-info.c src/include/66/constants.h src/include/66/enum.h src/include/66/resolve.h src/include/66/tree.h src/include/66/utils.h
src/66/66-init.o src/66/66-init.lo: src/66/66-init.c src/include/66/ssexec.h
src/66/66-parser.o src/66/66-parser.lo: src/66/66-parser.c src/include/66/parser.h src/include/66/utils.h
src/66/66-scanctl.o src/66/66-scanctl.lo: src/66/66-scanctl.c src/include/66/utils.h
src/66/66-scandir.o src/66/66-scandir.lo: src/66/66-scandir.c src/include/66/config.h src/include/66/constants.h src/include/66/environ.h src/include/66/utils.h
src/66/66-shutdown.o src/66/66-shutdown.lo: src/66/66-shutdown.c src/include/66/config.h src/include/66/hpr.h
src/66/66-shutdownd.o src/66/66-shutdownd.lo: src/66/66-shutdownd.c src/include/66/config.h src/include/66/constants.h
......@@ -120,6 +121,8 @@ src/lib66/tree_switch_current.o src/lib66/tree_switch_current.lo: src/lib66/tree
66-init: src/66/66-init.o ${LIB66} -loblibs -ls6 -lskarnet
66-parser: EXTRA_LIBS :=
66-parser: src/66/66-parser.o ${LIB66} -loblibs -lskarnet
66-scanctl: EXTRA_LIBS :=
66-scanctl: src/66/66-scanctl.o ${LIB66} -loblibs -ls6 -lskarnet
66-scandir: EXTRA_LIBS :=
66-scandir: src/66/66-scandir.o ${LIB66} -loblibs -ls6 -lskarnet
66-shutdown: EXTRA_LIBS := ${TAINNOW_LIB} ${SOCKET_LIB}
......
66-scandir 0755
66-scanctl 0755
66-init 0755
66-tree 0755
66-dbctl 0755
......
BIN_TARGETS := \
66-scandir \
66-scanctl \
66-init \
66-tree \
66-dbctl \
......
/*
* 66-scanctl.c
*
* Copyright (c) 2018-2019 Eric Vidal <eric@obarun.org>
*
* All rights reserved.
*
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <string.h>
#include <oblibs/error2.h>
#include <oblibs/obgetopt.h>
#include <skalibs/buffer.h>
#include <skalibs/stralloc.h>
#include <skalibs/types.h>
#include <66/utils.h>
#define SIGSIZE 64
#define USAGE "66-scanctl [ -h ] [ -v verbosity ] [ -l live ] [ -o owner ] signal"
unsigned int VERBOSITY = 1 ;
static inline void info_help (void)
{
static char const *help =
"66-scandir <options> signal\n"
"\n"
"options :\n"
" -h: print this help\n"
" -v: increase/decrease verbosity\n"
" -l: live directory\n"
" -o: handle scandir of owner\n"
;
if (buffer_putsflush(buffer_1, help) < 0)
strerr_diefu1sys(111, "write to stdout") ;
}
static inline unsigned int lookup (char const *const *table, char const *signal)
{
unsigned int i = 0 ;
for (; table[i] ; i++) if (!strcmp(signal, table[i])) break ;
return i ;
}
static inline unsigned int parse_signal (char const *signal)
{
static char const *const signal_table[] =
{
"reload",
"interrupt",
"quit",
"halt",
"reboot",
"poweroff",
0
} ;
unsigned int i = lookup(signal_table, signal) ;
if (!signal_table[i]) strerr_dief2x(111,"unknown signal: ",signal) ;
return i ;
}
int send_signal(char const *scandir, char const *signal)
{
unsigned int sig = 5 ;
size_t siglen = strlen(signal) ;
char csig[SIGSIZE + 1] ;
sig = parse_signal(signal) ;
if (sig < 6)
{
csig[0] = '-' ;
switch(sig)
{
case 0: csig[1] = 'a' ;
csig[2] = 'n' ;
csig[3] = 0 ;
break ;
case 1: csig[1] = 'i' ;
csig[2] = 0 ;
break ;
case 2: csig[1] = 'q' ;
csig[2] = 0 ;
break ;
case 3: csig[1] = '0' ;
csig[2] = 0 ;
break ;
case 4: csig[1] = '6' ;
csig[2] = 0 ;
break ;
case 5: csig[1] = '7' ;
csig[2] = 0 ;
break ;
default: break ;
}
}
else
{
csig[0] = '-' ;
memcpy(csig + 1,signal,siglen) ;
csig[siglen + 1] = 0 ;
}
VERBO1 strerr_warni5x("Sending ",csig," signal to scandir: ",scandir," ...") ;
return scandir_send_signal(scandir,csig) ;
}
int main(int argc, char const *const *argv)
{
int r ;
uid_t owner = MYUID ;
char const *signal ;
stralloc scandir = STRALLOC_ZERO ;
PROG = "66-scandir" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
int opt = getopt_args(argc,argv, ">hv:l:o:", &l) ;
if (opt == -1) break ;
if (opt == -2) strerr_dief1x(110,"options must be set first") ;
switch (opt)
{
case 'h' : info_help(); return 0 ;
case 'v' : if (!uint0_scan(l.arg, &VERBOSITY)) exitusage(USAGE) ; break ;
case 'l' : if (!stralloc_cats(&scandir,l.arg)) retstralloc(111,"main") ;
if (!stralloc_0(&scandir)) retstralloc(111,"main") ;
break ;
case 'o' :
if (MYUID) strerr_dief1x(110, "only root can use -o options") ;
else if (!youruid(&owner,l.arg)) strerr_diefu2sys(111,"get uid of: ",l.arg) ;
break ;
default : exitusage(USAGE) ;
}
}
argc -= l.ind ; argv += l.ind ;
}
if (argc < 1) exitusage(USAGE) ;
signal = argv[0] ;
r = set_livedir(&scandir) ;
if (r < 0) strerr_dief3x(110,"live: ",scandir.s," must be an absolute path") ;
if (!r) strerr_diefu1sys(111,"set live directory") ;
r = set_livescan(&scandir,owner) ;
if (r < 0) strerr_dief3x(110,"scandir: ", scandir.s, " must be an absolute path") ;
if (!r) strerr_diefu1sys(111,"set scandir directory") ;
r = scandir_ok(scandir.s) ;
if (!r) strerr_dief3sys(111,"scandir: ",scandir.s," is not running") ;
else if (r < 0) strerr_diefu2sys(111, "check: ", scandir.s) ;
if (send_signal(scandir.s,signal) <= 0) goto err ;
stralloc_free(&scandir) ;
return 0 ;
err:
stralloc_free(&scandir) ;
return 111 ;
}
......@@ -65,7 +65,7 @@ static char const *stage3 = "/etc/66/stage3 $@" ;
static char TMPENV[MAXENV+1] ;
#define USAGE "66-scandir [ -h ] [ -v verbosity ] [ -b ] [ -l live ] [ -t rescan ] [ -2 stage2.tini ] [ -3 stage3 ] [ -e environment ] [ -c | u | r ] [ -s signal ] owner"
#define USAGE "66-scandir [ -h ] [ -v verbosity ] [ -b ] [ -l live ] [ -t rescan ] [ -2 stage2.tini ] [ -3 stage3 ] [ -e environment ] [ -c | u | r ] owner"
unsigned int VERBOSITY = 1 ;
static unsigned int BOOT = 0 ;
......@@ -87,97 +87,11 @@ static inline void info_help (void)
" -c: create scandir\n"
" -r: remove scandir\n"
" -u: bring up scandir\n"
" -s: send a signal to the scandir\n"
;
if (buffer_putsflush(buffer_1, help) < 0)
strerr_diefu1sys(111, "write to stdout") ;
}
static inline unsigned int lookup (char const *const *table, char const *signal)
{
unsigned int i = 0 ;
for (; table[i] ; i++) if (!strcmp(signal, table[i])) break ;
return i ;
}
static inline unsigned int parse_signal (char const *signal)
{
static char const *const signal_table[] =
{
"reload",
"interrupt",
"quit",
"halt",
"reboot",
"poweroff",
0
} ;
unsigned int i = lookup(signal_table, signal) ;
if (!signal_table[i]) strerr_dief2x(111,"unknown signal: ",signal) ;
return i ;
}
int scandir_down(char const *scandir, char const *signal, char const *const *envp)
{
int r ;
unsigned int sig = 5 ;
size_t siglen = strlen(signal) ;
char csig[SIGSIZE + 1] ;
if (siglen > SIGSIZE) strerr_diefu2x(111,"too many command to send to: ",scandir) ;
r = scandir_ok(scandir) ;
if (r < 0) strerr_diefu2sys(111, "check ", scandir) ;
if (!r)
{
VERBO2 strerr_warni3x("scandir ",scandir," not running") ;
return 0 ;
}
sig = parse_signal(signal) ;
if (sig < 6)
{
csig[0] = '-' ;
switch(sig)
{
case 0: csig[1] = 'a' ;
csig[2] = 'n' ;
csig[3] = 0 ;
break ;
case 1: csig[1] = 'i' ;
csig[2] = 0 ;
break ;
case 2: csig[1] = 'q' ;
csig[2] = 0 ;
break ;
case 3: csig[1] = '0' ;
csig[2] = 0 ;
break ;
case 4: csig[1] = '6' ;
csig[2] = 0 ;
break ;
case 5: csig[1] = '7' ;
csig[2] = 0 ;
break ;
default: break ;
}
}
else
{
csig[0] = '-' ;
memcpy(csig + 1,signal,siglen) ;
csig[siglen + 1] = 0 ;
}
char const *newdown[5] ;
unsigned int m = 0 ;
newdown[m++] = S6_BINPREFIX "s6-svscanctl" ;
newdown[m++] = csig ;
newdown[m++] = "--" ;
newdown[m++] = scandir ;
newdown[m++] = 0 ;
VERBO2 strerr_warni5x("Sending ",csig," signal to scandir: ",scandir," ...") ;
xpathexec_run (newdown[0], newdown, envp) ;
}
int scandir_up(char const *scandir, unsigned int timeout, char const *const *envp)
{
......@@ -391,7 +305,6 @@ int write_bootlog(char const *live, char const *scandir, char const *scanname)
memcpy(logdir + logdirless, "/fifo", 5) ;
logdir[logdirless + 5] = 0 ;
r = scan_mode(logdir,S_IFIFO) ;
if (r < 0) { errno = EEXIST ; return 0 ; }
if (!r)
......@@ -437,7 +350,7 @@ int write_bootlog(char const *live, char const *scandir, char const *scanname)
EXECLINE_BINPREFIX "redirfd -w 2 /dev/console\n" \
EXECLINE_BINPREFIX "redirfd -w 1 /dev/null\n" \
EXECLINE_BINPREFIX "redirfd -rnb 0 fifo\n" \
S6_BINPREFIX "s6-log -bp -- t ")) retstralloc(0, "write_bootlog") ;
S6_BINPREFIX "s6-log -bpd3 -- 1 t ")) retstralloc(0, "write_bootlog") ;
if (!stralloc_cats(&run,path)) retstralloc(0, "write_bootlog") ;
if (!stralloc_cats(&run,"\n")) retstralloc(0, "write_bootlog") ;
......@@ -450,6 +363,13 @@ int write_bootlog(char const *live, char const *scandir, char const *scanname)
return 0 ;
}
VERBO3 strerr_warnt3x("write file: ",logdir,"/notification-fd") ;
if (!file_write_unsafe(logdir,"notification-fd","3\n",2))
{
VERBO3 strerr_warnwu3sys("write file: ",logdir,"/run") ;
return 0 ;
}
memcpy(logdir + logdirless,"/run",4) ;
logdir[logdirless + 4] = 0 ;
......@@ -835,104 +755,20 @@ int sanitize_live(char const *live, char const *scandir, char const *scanname, u
return 1 ;
}
size_t make_env(char const *src,char const *const *envp,char const **newenv)
{
stralloc sa = STRALLOC_ZERO ;
stralloc modifs = STRALLOC_ZERO ;
genalloc toparse = GENALLOC_ZERO ;
int r, i ;
size_t filesize, envlen = env_len(envp) ;
r = scan_mode(src,S_IFDIR) ;
if (r < 0)
{
r = scan_mode(src,S_IFREG) ;
if (!r || r < 0)
{
VERBO3 strerr_warnw2sys("invalid environment: ",src) ;
goto err ;
}
filesize=file_get_size(src) ;
if (filesize > MAXENV)
{
VERBO3 strerr_warnw2x("environment too long: ",src) ;
goto err ;
}
if (!openreadfileclose(src,&sa,filesize))
{
VERBO3 strerr_warnwu2sys("open: ",src ) ;
goto err ;
}
if (!env_parsenclean(&modifs,&sa))
{
VERBO3 strerr_warnwu2x("parse and clean environment of: ",sa.s) ;
goto err ;
}
}
else if (!r)
{
VERBO3 strerr_warnw2sys("invalid environment: ",src) ;
goto err ;
}
/** we parse all file of the directory*/
else
{
r = dir_get(&toparse,src,"",S_IFREG) ;
if (!r)
{
VERBO3 strerr_warnwu2sys("get file from: ",src) ;
goto err ;
}
for (i = 0 ; i < genalloc_len(stralist,&toparse) ; i++)
{
sa.len = 0 ;
if (i > MAXFILE) strerr_dief2x(111,"to many file to parse in: ",src) ;
if (!file_readputsa(&sa,src,gaistr(&toparse,i))) strerr_diefu4sys(111,"read file: ",src,"/",gaistr(&toparse,i)) ;
if (!env_parsenclean(&modifs,&sa)) strerr_diefu4x(111,"parse and clean environment of: ",src,"/",gaistr(&toparse,i)) ;
}
}
size_t n = env_len(envp) + 1 + byte_count(modifs.s,modifs.len,'\0') ;
size_t mlen = modifs.len ;
if (mlen > MAXENV)
{
VERBO3 strerr_warnw2x("environment too long: ",src) ;
goto err ;
}
memcpy(TMPENV,modifs.s,mlen) ;
TMPENV[mlen] = 0 ;
if (!env_merge(newenv, n, envp, envlen, TMPENV, mlen))
{
VERBO3 strerr_warnwu2x("merge environment from: ",src) ;
goto err ;
}
genalloc_deepfree(stralist,&toparse,stra_free) ;
stralloc_free(&sa) ;
stralloc_free(&modifs) ;
return 1 ;
err:
genalloc_deepfree(stralist,&toparse,stra_free) ;
stralloc_free(&sa) ;
stralloc_free(&modifs) ;
return 0 ;
}
int main(int argc, char const *const *argv, char const *const *envp)
{
int r ;
unsigned int up, down, rescan, create, remove ;
unsigned int up, rescan, create, remove ;
stralloc live = STRALLOC_ZERO ;
stralloc livetree = STRALLOC_ZERO ;
stralloc scandir = STRALLOC_ZERO ;
stralloc envdir = STRALLOC_ZERO ;
stralloc signal = STRALLOC_ZERO ;
char const *newenv[MAXENV+1] ;
char const *const *genv = NULL ;
char const *const *genv = 0 ;
up = down = rescan = create = remove = 0 ;
up = rescan = create = remove = 0 ;
PROG = "66-scandir" ;
{
......@@ -940,7 +776,7 @@ int main(int argc, char const *const *argv, char const *const *envp)
for (;;)
{
int opt = getopt_args(argc,argv, ">hv:bl:t:3:2:e:crus:", &l) ;
int opt = getopt_args(argc,argv, ">hv:bl:t:2:e:cru", &l) ;
if (opt == -1) break ;
if (opt == -2) strerr_dief1x(110,"options must be set first") ;
switch (opt)
......@@ -952,26 +788,21 @@ int main(int argc, char const *const *argv, char const *const *envp)
if(!stralloc_0(&live)) retstralloc(111,"main") ;
break ;
case 't' : if (uint0_scan(l.arg, &rescan)) break ;
case 't' : if (!uint0_scan(l.arg, &rescan)) break ;
case '2' : stage2tini = l.arg ; break ;
case '3' : stage3 = l.arg ; break ;
case 'e' : if(!stralloc_cats(&envdir,l.arg)) retstralloc(111,"main") ;
if(!stralloc_0(&envdir)) retstralloc(111,"main") ;
break ;
case 'c' : create = 1 ; if (remove) exitusage(USAGE) ; break ;
case 'r' : remove = 1 ; if (create) exitusage(USAGE) ; break ;
case 'u' : up = 1 ; if (down) exitusage(USAGE) ; break ;
case 's' : down = 1 ; if (up) exitusage(USAGE) ;
if(!stralloc_cats(&signal,l.arg)) retstralloc(111,"main") ;
if(!stralloc_0(&signal)) retstralloc(111,"main") ;
break ;
case 'u' : up = 1 ; break ;
default : exitusage(USAGE) ;
}
}
argc -= l.ind ; argv += l.ind ;
}
if (argc > 1 || (!create && !remove && !up && !down)) exitusage(USAGE) ;
if (argc > 1 || (!create && !remove && !up)) exitusage(USAGE) ;
if (!argc) OWNER = MYUID ;
else
......@@ -1016,7 +847,7 @@ int main(int argc, char const *const *argv, char const *const *envp)
if (r < 0)
strerr_dief3x(110,"environment: ",envdir.s," must be an absolute path") ;
if (!make_env(envdir.s,envp,newenv)) strerr_diefu2x(111,"parse environment directory; ",envdir.s) ;
if (!build_env(envdir.s,envp,newenv,TMPENV)) strerr_diefu2x(111,"build environment with: ",envdir.s) ;
genv = newenv ;
}
else
......@@ -1056,10 +887,6 @@ int main(int argc, char const *const *argv, char const *const *envp)
}
stralloc_free(&live) ;
if (down)
{
scandir_down(rlive,signal.s,genv) ;
}
if (up)
{
scandir_up(rlive,rescan,genv) ;
......@@ -1090,7 +917,6 @@ int main(int argc, char const *const *argv, char const *const *envp)
stralloc_free(&livetree) ;
stralloc_free(&scandir) ;
stralloc_free(&envdir) ;
stralloc_free(&signal) ;
return 0 ;
}
......
${LIB66}
-loblibs
-ls6
-lskarnet
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment