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

remove unused or renamed file

parent e4f2e59b
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 2143 deletions
/*
* parse_service.c
*
* Copyright (c) 2018-2021 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 <66/parser.h>
#include <stdint.h>
#include <string.h>
#include <oblibs/log.h>
#include <oblibs/sastr.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <skalibs/stralloc.h>
#include <skalibs/genalloc.h>
#include <66/utils.h>
#include <66/constants.h>
#include <66/ssexec.h>
#include <66/service.h>
#include <66/tree.h>
static void parse_service_instance(stralloc *frontend, char const *svsrc, char const *sv, int insta)
{
log_flow() ;
stralloc sa = STRALLOC_ZERO ;
if (!instance_splitname(&sa, sv, insta, SS_INSTANCE_TEMPLATE))
log_die(LOG_EXIT_SYS, "split instance service: ", sv) ;
log_trace("read frontend service of: ", svsrc, sa.s) ;
if (read_svfile(frontend, sa.s, svsrc) <= 0)
log_dieusys(LOG_EXIT_SYS, "read frontend service of: ", svsrc, sa.s) ;
stralloc_free(&sa) ;
if (!instance_create(frontend, sv, SS_INSTANCE_REGEX, insta))
log_die(LOG_EXIT_SYS, "create instance service: ", sv) ;
/** ensure that we have an empty line at the end of the string*/
if (!auto_stra(frontend, "\n"))
log_die_nomem("stralloc") ;
}
static int parse_add_service(stralloc *parsed_list, sv_alltype *alltype, char const *service, uint8_t conf)
{
log_flow() ;
log_trace("add service: ", service) ;
// keep overwrite_conf
alltype->overwrite_conf = conf ;
// keep source of the frontend file
alltype->src = keep.len ;
if (!sastr_add_string(&keep, service))
return 0 ;
// keep service on current list
if (!sastr_add_string(parsed_list, service))
return 0 ;
if (!genalloc_append(sv_alltype, &gasv, alltype))
return 0 ;
return 1 ;
}
static void set_info(ssexec_t *info)
{
log_flow() ;
info->tree.len = 0 ;
int r = ssexec_set_treeinfo(info) ;
if (r == -4) log_die(LOG_EXIT_USER,"You're not allowed to use the tree: ",info->tree.s) ;
if (r == -3) log_dieu(LOG_EXIT_USER,"find the current tree. You must use the -t options") ;
if (r == -2) log_dieu(LOG_EXIT_USER,"set the tree name") ;
if (r == -1) log_dieu(LOG_EXIT_USER,"parse seed file") ;
if (!r) log_dieusys(LOG_EXIT_SYS,"find tree: ", info->treename.s) ;
}
#include <stdio.h>
/* @sv -> name of the service to parse with
* the path of the frontend file source
* @Return 0 on fail
* @Return 1 on success
* @Return 2 -> already parsed */
int parse_service(char const *sv, stralloc *parsed_list, ssexec_t *info, uint8_t force, uint8_t conf)
{
log_flow() ;
if (sastr_cmp(parsed_list, sv) >= 0) {
log_warn("ignoring: ", sv, " service -- already parsed") ;
return 2 ;
}
log_trace("parse service: ", sv) ;
int insta, r ;
size_t svlen = strlen(sv) ;
char svname[svlen + 1], svsrc[svlen + 1] ;
sv_alltype alltype = SV_ALLTYPE_ZERO ;
stralloc frontend = STRALLOC_ZERO ;
stralloc satree = STRALLOC_ZERO ;
if (!ob_basename(svname, sv))
log_dieu(LOG_EXIT_SYS, "get basename of: ", sv) ;
if (!ob_dirname(svsrc, sv))
log_dieu(LOG_EXIT_SYS, "get dirname of: ", sv) ;
insta = instance_check(svname) ;
if (!insta) {
log_die(LOG_EXIT_SYS, "invalid instance name: ", svname) ;
} else if (insta > 0) {
parse_service_instance(&frontend, svsrc, svname, insta) ;
} else {
log_trace("read frontend service of: ", sv) ;
if (read_svfile(&frontend, svname, svsrc) <= 0)
log_dieusys(LOG_EXIT_SYS, "read frontend service of: ", sv) ;
}
r = service_isenabledat(&satree, svname) ;
if (r < -1)
log_dieu(LOG_EXIT_SYS, "check already enabled services") ;
if (r > 0) {
if (force) {
/* -t option was used */
if (!info->skip_opt_tree) {
if (strcmp(info->treename.s, satree.s))
log_die(LOG_EXIT_SYS,"you can not force to enable again a service on different tree -- current: ", satree.s, " asked: ", info->treename.s, ". Try first to disable it") ;
} else {
if (!auto_stra(&info->treename, satree.s))
log_die_nomem("stralloc") ;
}
goto set ;
} else {
log_info("ignoring service: ", sv, " -- already enabled at tree: ", satree.s) ;
/** we don't care about the use of the -t option. The define of the
* info->tree and info->treename is just made to avoid segmentation fault
* at the rest of the process. The service is not parsed or enable again anyway. */
info->treename.len = 0 ;
if (!auto_stra(&info->treename, satree.s))
log_die_nomem("stralloc") ;
set_info(info) ;
sv_alltype_free(&alltype) ;
stralloc_free(&frontend) ;
stralloc_free(&satree) ;
return 2 ;
}
}
if (info->skip_opt_tree) {
/** first try to find the @intree key at the frontend file*/
if (!get_svintree(&alltype,frontend.s))
log_die(LOG_EXIT_USER, "invalid value for key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,KEY_MAIN_INTREE)," in service file: ", sv) ;
if (alltype.cname.intree >= 0) {
info->treename.len = 0 ;
if (!auto_stra(&info->treename, keep.s + alltype.cname.intree))
log_die_nomem("stralloc") ;
}
}
set:
set_info(info) ;
if (!get_svtype(&alltype, frontend.s))
log_die(LOG_EXIT_USER, "invalid value for key: ", get_key_by_enum(ENUM_KEY_SECTION_MAIN, KEY_MAIN_TYPE), " at frontend service: ", sv) ;
/** contents of directory should be listed by service_frontend_path
* except for module type */
if (scan_mode(sv,S_IFDIR) == 1 && alltype.cname.itype != TYPE_MODULE)
goto freed ;
alltype.cname.name = keep.len ;
if (!sastr_add_string(&keep, svname))
log_die_nomem("stralloc") ;
if (!parser(&alltype, &frontend, svname, alltype.cname.itype))
log_dieu(LOG_EXIT_SYS, "parse service: ", sv) ;
if (!parse_add_service(parsed_list, &alltype, sv, conf))
log_dieu(LOG_EXIT_SYS, "add service: ", sv) ;
freed:
stralloc_free(&frontend) ;
stralloc_free(&satree) ;
return 1 ;
}
int parse_service_deps(sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, char const *directory_forced)
{
log_flow() ;
int r, e = 0 ;
stralloc sa = STRALLOC_ZERO ;
if (alltype->cname.nga) {
size_t id = alltype->cname.idga, nid = alltype->cname.nga ;
for (; nid ; id += strlen(deps.s + id) + 1, nid--) {
sa.len = 0 ;
if (alltype->cname.itype != TYPE_BUNDLE) {
log_trace("service: ", keep.s + alltype->cname.name, " depends on: ", deps.s + id) ;
} else log_trace("bundle: ", keep.s + alltype->cname.name, " contents: ", deps.s + id," as service") ;
r = service_frontend_path(&sa, deps.s + id, info->owner, directory_forced) ;
if (r < 1) goto err ;//don't warn here, the ss_revolve_src_path do it
if (!parse_service(sa.s, parsed_list, info, force, alltype->overwrite_conf))
goto err ;
}
} else log_trace(keep.s + alltype->cname.name,": haven't dependencies") ;
e = 1 ;
err:
stralloc_free(&sa) ;
return e ;
}
int parse_service_optsdeps(stralloc *rebuild, sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, uint8_t field, char const *directory_forced)
{
log_flow() ;
int r, e = 0 ;
stralloc sa = STRALLOC_ZERO ;
size_t id, nid ;
uint8_t ext = field == KEY_MAIN_EXTDEPS ? 1 : 0 ;
int idref = alltype->cname.idopts ;
unsigned int nref = alltype->cname.nopts ;
if (ext) {
idref = alltype->cname.idext ;
nref = alltype->cname.next ;
}
if (nref) {
id = (size_t)idref, nid = (size_t)nref ;
for (; nid ; id += strlen(deps.s + id) + 1, nid--) {
sa.len = 0 ;
// 0 -> not found, 1 -> found, -1 -> system error
r = service_isenabled(deps.s + id) ;
if (r == -1)
log_dieu(LOG_EXIT_SYS, "check already enabled services") ;
if (r > 0) {
if (!ext)
break ;
else
continue ;
}
r = service_frontend_path(&sa, deps.s + id, info->owner, directory_forced) ;
if (r == -1)
goto err ;
if (!r) {
log_trace("unable to find", ext ? " external " : " optional ", "dependency: ", deps.s + id, " for service: ", keep.s + alltype->cname.name) ;
// external deps must exist
if (ext)
goto err ;
continue ;
}
if (!parse_service(sa.s, parsed_list, info, force, alltype->overwrite_conf))
goto err ;
if (!sastr_add_string(rebuild, deps.s + id))
log_die_nomem("stralloc") ;
// we only keep the first optsdepends found
if (!ext) break ;
}
} else log_trace(keep.s + alltype->cname.name,": haven't", ext ? " external " : " optional ", "dependencies") ;
e = 1 ;
err:
stralloc_free(&sa) ;
return e ;
}
int parse_service_alldeps(sv_alltype *alltype, ssexec_t *info, stralloc *parsed_list, uint8_t force, char const *directory_forced)
{
log_flow() ;
int e = 0 ;
size_t id, nid, pos ;
char *name = keep.s + alltype->cname.name ;
stralloc sa = STRALLOC_ZERO ;
stralloc rebuild = STRALLOC_ZERO ;
if (!parse_service_deps(alltype, info, parsed_list, force, directory_forced)) {
log_warnu("parse dependencies of: ", name) ;
goto err ;
}
if (!parse_service_optsdeps(&rebuild, alltype, info, parsed_list, force, KEY_MAIN_EXTDEPS, directory_forced)) {
log_warnu("parse external dependencies of: ", name) ;
goto err ;
}
if (!parse_service_optsdeps(&rebuild, alltype, info, parsed_list, force, KEY_MAIN_OPTSDEPS, directory_forced)) {
log_warnu("parse optional dependencies of: ", name) ;
goto err ;
}
// rebuild the dependencies list of the service to add the new dependencies.
if (rebuild.len) {
pos = 0 ;
sa.len = 0 ;
id = alltype->cname.idga ;
nid = alltype->cname.nga ;
{
for (; nid ; id += strlen(deps.s + id) + 1, nid--) {
if (!sastr_add_string(&sa, deps.s + id)) {
log_warn("stralloc") ;
goto err ;
}
}
FOREACH_SASTR(&rebuild, pos) {
if (!sastr_add_string(&sa, rebuild.s + pos)) {
log_warn("stralloc") ;
goto err ;
}
}
}
alltype->cname.idga = deps.len ;
alltype->cname.nga = 0 ;
pos = 0 ;
FOREACH_SASTR(&sa, pos) {
log_info("rebuil list", sa.s + pos) ;
if (!sastr_add_string(&deps,sa.s + pos)) {
log_warn("stralloc") ;
goto err ;
}
alltype->cname.nga++ ;
}
}
e = 1 ;
err:
stralloc_free(&rebuild) ;
stralloc_free(&sa) ;
return e ;
}
/*
* service.c
*
* Copyright (c) 2018-2021 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 <stdint.h>
#include <stdlib.h>//free
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/sastr.h>
#include <skalibs/genalloc.h>
#include <skalibs/stralloc.h>
#include <skalibs/types.h>
#include <66/constants.h>
#include <66/resolve.h>
#include <66/service.h>
#include <66/state.h>
int service_resolve_add_deps(genalloc *tokeep, resolve_service_t *res, char const *src)
{
log_flow() ;
int e = 0 ;
size_t pos = 0 ;
stralloc tmp = STRALLOC_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
char *name = res->sa.s + res->name ;
char *deps = res->sa.s + res->depends ;
if (!resolve_cmp(tokeep, name, DATA_SERVICE) && (!obstr_equal(name,SS_MASTER+1)))
if (!resolve_append(tokeep,wres)) goto err ;
if (res->ndepends)
{
if (!sastr_clean_string(&tmp,deps)) return 0 ;
for (;pos < tmp.len ; pos += strlen(tmp.s + pos) + 1)
{
resolve_service_t dres = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref dwres = resolve_set_struct(DATA_SERVICE, &dres) ;
char *dname = tmp.s + pos ;
if (!resolve_check(src,dname)) goto err ;
if (!resolve_read(dwres,src,dname)) goto err ;
if (dres.ndepends && !resolve_cmp(tokeep, dname, DATA_SERVICE))
{
if (!service_resolve_add_deps(tokeep,&dres,src)) goto err ;
}
if (!resolve_cmp(tokeep, dname, DATA_SERVICE))
{
if (!resolve_append(tokeep,dwres)) goto err ;
}
resolve_free(dwres) ;
}
}
e = 1 ;
err:
stralloc_free(&tmp) ;
free(wres) ;
return e ;
}
int service_resolve_add_rdeps(genalloc *tokeep, resolve_service_t *res, char const *src)
{
log_flow() ;
int type, e = 0 ;
stralloc tmp = STRALLOC_ZERO ;
stralloc nsv = STRALLOC_ZERO ;
ss_state_t sta = STATE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
char const *exclude[2] = { SS_MASTER + 1, 0 } ;
char *name = res->sa.s + res->name ;
size_t srclen = strlen(src), a = 0, b = 0, c = 0 ;
char s[srclen + SS_RESOLVE_LEN + 1] ;
memcpy(s,src,srclen) ;
memcpy(s + srclen,SS_RESOLVE,SS_RESOLVE_LEN) ;
s[srclen + SS_RESOLVE_LEN] = 0 ;
if (res->type == TYPE_CLASSIC) type = 0 ;
else type = 1 ;
if (!sastr_dir_get(&nsv,s,exclude,S_IFREG)) goto err ;
if (!resolve_cmp(tokeep, name, DATA_SERVICE) && (!obstr_equal(name,SS_MASTER+1)))
{
if (!resolve_append(tokeep,wres)) goto err ;
}
if ((res->type == TYPE_BUNDLE || res->type == TYPE_MODULE) && res->ndepends)
{
uint32_t deps = res->type == TYPE_MODULE ? res->contents : res->depends ;
if (!sastr_clean_string(&tmp,res->sa.s + deps)) goto err ;
resolve_service_t dres = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref dwres = resolve_set_struct(DATA_SERVICE, &dres) ;
for (; a < tmp.len ; a += strlen(tmp.s + a) + 1)
{
char *name = tmp.s + a ;
if (!resolve_check(src,name)) goto err ;
if (!resolve_read(dwres,src,name)) goto err ;
if (dres.type == TYPE_CLASSIC) continue ;
if (!resolve_cmp(tokeep, name, DATA_SERVICE))
{
if (!resolve_append(tokeep,dwres)) goto err ;
if (!service_resolve_add_rdeps(tokeep,&dres,src)) goto err ;
}
resolve_free(dwres) ;
}
}
for (; b < nsv.len ; b += strlen(nsv.s + b) +1)
{
int dtype = 0 ;
tmp.len = 0 ;
resolve_service_t dres = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref dwres = resolve_set_struct(DATA_SERVICE, &dres) ;
char *dname = nsv.s + b ;
if (obstr_equal(name,dname)) { resolve_free(wres) ; continue ; }
if (!resolve_check(src,dname)) goto err ;
if (!resolve_read(dwres,src,dname)) goto err ;
if (dres.type == TYPE_CLASSIC) dtype = 0 ;
else dtype = 1 ;
if (state_check(dres.sa.s + dres.state,dname))
{
if (!state_read(&sta,dres.sa.s + dres.state,dname)) goto err ;
if (dtype != type || (!dres.disen && !sta.unsupervise)){ resolve_free(dwres) ; continue ; }
}
else if (dtype != type || (!dres.disen)){ resolve_free(dwres) ; continue ; }
if (dres.type == TYPE_BUNDLE && !dres.ndepends){ resolve_free(dwres) ; continue ; }
if (!resolve_cmp(tokeep, dname, DATA_SERVICE))
{
if (dres.ndepends)// || (dres.type == TYPE_BUNDLE && dres.ndepends) || )
{
if (!sastr_clean_string(&tmp,dres.sa.s + dres.depends)) goto err ;
/** we must check every service inside the module to not add as
* rdeps a service declared inside the module.
* eg.
* module boot@system declare tty-rc@tty1
* we don't want boot@system as rdeps of tty-rc@tty1 but only
* service inside the module as rdeps of tty-rc@tty1 */
if (dres.type == TYPE_MODULE)
for (c = 0 ; c < tmp.len ; c += strlen(tmp.s + c) + 1)
if (obstr_equal(name,tmp.s + c)) goto skip ;
for (c = 0 ; c < tmp.len ; c += strlen(tmp.s + c) + 1)
{
if (obstr_equal(name,tmp.s + c))
{
if (!resolve_append(tokeep,dwres)) goto err ;
if (!service_resolve_add_rdeps(tokeep,&dres,src)) goto err ;
resolve_free(dwres) ;
break ;
}
}
}
}
skip:
resolve_free(dwres) ;
}
e = 1 ;
err:
free(wres) ;
stralloc_free(&nsv) ;
stralloc_free(&tmp) ;
return e ;
}
int service_resolve_add_logger(genalloc *ga,char const *src)
{
log_flow() ;
int e = 0 ;
size_t i = 0 ;
genalloc gatmp = GENALLOC_ZERO ;
for (; i < genalloc_len(resolve_service_t,ga) ; i++)
{
resolve_service_t res = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
resolve_service_t dres = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref dwres = resolve_set_struct(DATA_SERVICE, &dres) ;
if (!service_resolve_copy(&res,&genalloc_s(resolve_service_t,ga)[i])) goto err ;
char *string = res.sa.s ;
char *name = string + res.name ;
if (!resolve_cmp(&gatmp, name, DATA_SERVICE))
{
if (!resolve_append(&gatmp,wres))
goto err ;
if (res.logger)
{
if (!resolve_check(src,string + res.logger)) goto err ;
if (!resolve_read(dwres,src,string + res.logger))
goto err ;
if (!resolve_cmp(&gatmp, string + res.logger, DATA_SERVICE))
if (!resolve_append(&gatmp,dwres)) goto err ;
}
}
resolve_free(wres) ;
resolve_free(dwres) ;
}
resolve_deep_free(DATA_SERVICE, ga) ;
if (!genalloc_copy(resolve_service_t,ga,&gatmp)) goto err ;
e = 1 ;
err:
genalloc_free(resolve_service_t,&gatmp) ;
resolve_deep_free(DATA_SERVICE, &gatmp) ;
return e ;
}
/*
* service_isenabled.c
*
* Copyright (c) 2018-2021 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 <unistd.h>//getuid
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/sastr.h>
#include <skalibs/stralloc.h>
#include <66/constants.h>
#include <66/resolve.h>
#include <66/service.h>
#include <66/utils.h>
/** @Return 0 if not found
* @Return 1 if found
* @Return 2 if found but marked disabled
* @Return -1 system error */
int service_isenabled(char const *sv)
{
log_flow() ;
stralloc sa = STRALLOC_ZERO ;
resolve_service_t res = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
size_t newlen = 0, pos = 0 ;
int e = -1, r ;
char const *exclude[3] = { SS_BACKUP + 1, SS_RESOLVE + 1, 0 } ;
if (!set_ownersysdir(&sa, getuid())) {
log_warnusys("set owner directory") ;
stralloc_free(&sa) ;
return 0 ;
}
char tmp[sa.len + SS_SYSTEM_LEN + 2] ;
auto_strings(tmp, sa.s, SS_SYSTEM) ;
// no tree exist yet
if (!scan_mode(tmp, S_IFDIR))
goto empty ;
auto_strings(tmp, sa.s, SS_SYSTEM, "/") ;
newlen = sa.len + SS_SYSTEM_LEN + 1 ;
sa.len = 0 ;
if (!sastr_dir_get(&sa, tmp, exclude, S_IFDIR)) {
log_warnu("get list of trees from: ", tmp) ;
goto freed ;
}
FOREACH_SASTR(&sa, pos) {
char *treename = sa.s + pos ;
char trees[newlen + strlen(treename) + SS_SVDIRS_LEN + 1] ;
auto_strings(trees, tmp, treename, SS_SVDIRS) ;
r = resolve_read_g(wres, trees, sv) ;
if (r < 0) {
log_warnu("read resolve file: ", trees, "/", sv) ;
e = -1 ;
goto freed ;
} else if (r) {
if (res.disen) {
log_trace(sv, " enabled at tree: ", treename) ;
e = 1 ;
goto freed ;
} else {
log_trace(sv, " disabled at tree: ", treename) ;
e = 2 ;
goto freed ;
}
}
}
empty:
e = 0 ;
freed:
stralloc_free(&sa) ;
resolve_free(wres) ;
return e ;
}
/*
* service_resolve_setlognwrite.c
*
* Copyright (c) 2018-2021 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/log.h>
#include <oblibs/string.h>
#include <66/enum.h>
#include <66/state.h>
#include <66/resolve.h>
#include <66/service.h>
int service_resolve_setlognwrite(resolve_service_t *sv, char const *dst)
{
log_flow() ;
if (!sv->logger) return 1 ;
int e = 0 ;
ss_state_t sta = STATE_ZERO ;
resolve_service_t res = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
resolve_init(wres) ;
char *str = sv->sa.s ;
size_t svlen = strlen(str + sv->name) ;
char descrip[svlen + 7 + 1] ;
auto_strings(descrip, str + sv->name, " logger") ;
size_t runlen = strlen(str + sv->runat) ;
char live[runlen + 4 + 1] ;
memcpy(live,str + sv->runat,runlen) ;
if (sv->type >= TYPE_BUNDLE) {
memcpy(live + runlen,"-log",4) ;
} else memcpy(live + runlen,"/log",4) ;
live[runlen + 4] = 0 ;
res.type = sv->type ;
res.name = resolve_add_string(wres,str + sv->logger) ;
res.description = resolve_add_string(wres,str + sv->description) ;
res.version = resolve_add_string(wres,str + sv->version) ;
res.logreal = resolve_add_string(wres,str + sv->logreal) ;
res.logassoc = resolve_add_string(wres,str + sv->name) ;
res.dstlog = resolve_add_string(wres,str + sv->dstlog) ;
res.live = resolve_add_string(wres,str + sv->live) ;
res.runat = resolve_add_string(wres,live) ;
res.tree = resolve_add_string(wres,str + sv->tree) ;
res.treename = resolve_add_string(wres,str + sv->treename) ;
res.state = resolve_add_string(wres,str + sv->state) ;
res.src = resolve_add_string(wres,str + sv->src) ;
res.down = sv->down ;
res.disen = sv->disen ;
if (sv->exec_log_run > 0)
res.exec_log_run = resolve_add_string(wres,str + sv->exec_log_run) ;
if (sv->real_exec_log_run > 0)
res.real_exec_log_run = resolve_add_string(wres,str + sv->real_exec_log_run) ;
if (state_check(str + sv->state,str + sv->logger)) {
if (!state_read(&sta,str + sv->state,str + sv->logger)) {
log_warnusys("read state file of: ",str + sv->logger) ;
goto err ;
}
if (!sta.init)
state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_TRUE) ;
state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_FALSE) ;
state_setflag(&sta,SS_FLAGS_UNSUPERVISE,SS_FLAGS_FALSE) ;
if (!state_write(&sta,str + sv->state,str + sv->logger)) {
log_warnusys("write state file of: ",str + sv->logger) ;
goto err ;
}
}
if (!resolve_write(wres,dst,res.sa.s + res.name)) {
log_warnusys("write resolve file: ",dst,SS_RESOLVE,"/",res.sa.s + res.name) ;
goto err ;
}
e = 1 ;
err:
resolve_free(wres) ;
return e ;
}
/*
* service_resolve_setnwrite.c
*
* Copyright (c) 2018-2021 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/log.h>
#include <oblibs/string.h>
#include <skalibs/types.h>
#include <skalibs/stralloc.h>
#include <66/enum.h>
#include <66/constants.h>
#include <66/resolve.h>
#include <66/state.h>
#include <66/ssexec.h>
#include <66/parser.h>
#include <66/utils.h>
#include <66/service.h>
int service_resolve_setnwrite(sv_alltype *services, ssexec_t *info, char const *dst)
{
log_flow() ;
int e = 0 ;
char ownerstr[UID_FMT] ;
size_t ownerlen = uid_fmt(ownerstr,info->owner), id, nid ;
ownerstr[ownerlen] = 0 ;
stralloc destlog = STRALLOC_ZERO ;
stralloc ndeps = STRALLOC_ZERO ;
stralloc other_deps = STRALLOC_ZERO ;
ss_state_t sta = STATE_ZERO ;
resolve_service_t res = RESOLVE_SERVICE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
resolve_init(wres) ;
char *name = keep.s + services->cname.name ;
size_t namelen = strlen(name) ;
char logname[namelen + SS_LOG_SUFFIX_LEN + 1] ;
char logreal[namelen + SS_LOG_SUFFIX_LEN + 1] ;
char stmp[info->livetree.len + 1 + info->treename.len + SS_SVDIRS_LEN + 1 + namelen + SS_LOG_SUFFIX_LEN + 1] ;
size_t livelen = info->live.len - 1 ;
char state[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1 + namelen + 1] ;
auto_strings(state, info->live.s, SS_STATE, "/", ownerstr, "/", info->treename.s) ;
res.type = services->cname.itype ;
res.name = resolve_add_string(wres,name) ;
res.description = resolve_add_string(wres,keep.s + services->cname.description) ;
res.version = resolve_add_string(wres,keep.s + services->cname.version) ;
res.tree = resolve_add_string(wres,info->tree.s) ;
res.treename = resolve_add_string(wres,info->treename.s) ;
res.live = resolve_add_string(wres,info->live.s) ;
res.state = resolve_add_string(wres,state) ;
res.src = resolve_add_string(wres,keep.s + services->src) ;
if (services->srconf > 0)
res.srconf = resolve_add_string(wres,keep.s + services->srconf) ;
if (res.type == TYPE_ONESHOT) {
if (services->type.oneshot.up.exec >= 0) {
res.exec_run = resolve_add_string(wres,keep.s + services->type.oneshot.up.exec) ;
res.real_exec_run = resolve_add_string(wres,keep.s + services->type.oneshot.up.real_exec) ;
}
if (services->type.oneshot.down.exec >= 0) {
res.exec_finish = resolve_add_string(wres,keep.s + services->type.oneshot.down.exec) ;
res.real_exec_finish = resolve_add_string(wres,keep.s + services->type.oneshot.down.real_exec) ;
}
}
if (res.type == TYPE_CLASSIC || res.type == TYPE_LONGRUN) {
if (services->type.classic_longrun.run.exec >= 0) {
res.exec_run = resolve_add_string(wres,keep.s + services->type.classic_longrun.run.exec) ;
res.real_exec_run = resolve_add_string(wres,keep.s + services->type.classic_longrun.run.real_exec) ;
}
if (services->type.classic_longrun.finish.exec >= 0) {
res.exec_finish = resolve_add_string(wres,keep.s + services->type.classic_longrun.finish.exec) ;
res.real_exec_finish = resolve_add_string(wres,keep.s + services->type.classic_longrun.finish.real_exec) ;
}
}
res.ndepends = services->cname.nga ;
res.noptsdeps = services->cname.nopts ;
res.nextdeps = services->cname.next ;
res.ncontents = services->cname.ncontents ;
if (services->flags[0])
res.down = 1 ;
res.disen = 1 ;
if (res.type == TYPE_CLASSIC) {
auto_strings(stmp, info->scandir.s, "/", name) ;
res.runat = resolve_add_string(wres,stmp) ;
} else if (res.type >= TYPE_BUNDLE) {
auto_strings(stmp, info->livetree.s, "/", info->treename.s, SS_SVDIRS, "/", name) ;
res.runat = resolve_add_string(wres,stmp) ;
}
if (state_check(state,name)) {
if (!state_read(&sta,state,name)) {
log_warnusys("read state file of: ",name) ;
goto err ;
}
if (!sta.init)
state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_TRUE) ;
if (sta.init) {
state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_TRUE) ;
} else {
state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_FALSE) ;
}
state_setflag(&sta,SS_FLAGS_UNSUPERVISE,SS_FLAGS_FALSE) ;
if (!state_write(&sta,res.sa.s + res.state,name)) {
log_warnusys("write state file of: ",name) ;
goto err ;
}
}
if (res.ndepends)
{
id = services->cname.idga, nid = res.ndepends ;
for (;nid; id += strlen(deps.s + id) + 1, nid--) {
if (!stralloc_catb(&ndeps,deps.s + id,strlen(deps.s + id)) ||
!stralloc_catb(&ndeps," ",1)) {
log_warnsys("stralloc") ;
goto err ;
}
}
ndeps.len-- ;
if (!stralloc_0(&ndeps)) {
log_warnsys("stralloc") ;
goto err ;
}
res.depends = resolve_add_string(wres,ndeps.s) ;
}
if (res.noptsdeps)
{
id = services->cname.idopts, nid = res.noptsdeps ;
for (;nid; id += strlen(deps.s + id) + 1, nid--) {
if (!stralloc_catb(&other_deps,deps.s + id,strlen(deps.s + id)) ||
!stralloc_catb(&other_deps," ",1)) {
log_warnsys("stralloc") ;
goto err ;
}
}
other_deps.len-- ;
if (!stralloc_0(&other_deps)) {
log_warnsys("stralloc") ;
goto err ;
}
res.optsdeps = resolve_add_string(wres,other_deps.s) ;
}
if (res.nextdeps)
{
other_deps.len = 0 ;
id = services->cname.idext, nid = res.nextdeps ;
for (;nid; id += strlen(deps.s + id) + 1, nid--) {
if (!stralloc_catb(&other_deps,deps.s + id,strlen(deps.s + id)) ||
!stralloc_catb(&other_deps," ",1)){
log_warnsys("stralloc") ;
goto err ;
}
}
other_deps.len-- ;
if (!stralloc_0(&other_deps)){
log_warnsys("stralloc") ;
goto err ;
}
res.extdeps = resolve_add_string(wres,other_deps.s) ;
}
if (res.ncontents) {
other_deps.len = 0 ;
id = services->cname.idcontents, nid = res.ncontents ;
for (;nid; id += strlen(deps.s + id) + 1, nid--) {
if (!stralloc_catb(&other_deps,deps.s + id,strlen(deps.s + id)) ||
!stralloc_catb(&other_deps," ",1)) {
log_warnsys("stralloc") ;
goto err ;
}
}
other_deps.len-- ;
if (!stralloc_0(&other_deps)) {
log_warnsys("stralloc") ;
goto err ;
}
res.contents = resolve_add_string(wres,other_deps.s) ;
}
if (services->opts[0]) {
// destination of the logger
if (services->type.classic_longrun.log.destination < 0) {
if(info->owner > 0) {
if (!auto_stra(&destlog, get_userhome(info->owner), "/", SS_LOGGER_USERDIR, name)) {
log_warnsys("stralloc") ;
goto err ;
}
} else {
if (!auto_stra(&destlog, SS_LOGGER_SYSDIR, name)) {
log_warnsys("stralloc") ;
goto err ;
}
}
} else {
if (!auto_stra(&destlog,keep.s + services->type.classic_longrun.log.destination)) {
log_warnsys("stralloc") ;
goto err ;
}
}
res.dstlog = resolve_add_string(wres,destlog.s) ;
if ((res.type == TYPE_CLASSIC) || (res.type == TYPE_LONGRUN)) {
auto_strings(logname, name, SS_LOG_SUFFIX) ;
auto_strings(logreal, name) ;
if (res.type == TYPE_CLASSIC) {
auto_strings(logreal + namelen, "/log") ;
} else {
auto_strings(logreal + namelen,"-log") ;
}
res.logger = resolve_add_string(wres,logname) ;
res.logreal = resolve_add_string(wres,logreal) ;
if (ndeps.len)
ndeps.len--;
if (!stralloc_catb(&ndeps," ",1) ||
!stralloc_cats(&ndeps,res.sa.s + res.logger) ||
!stralloc_0(&ndeps)) {
log_warnsys("stralloc") ;
goto err ;
}
res.depends = resolve_add_string(wres,ndeps.s) ;
if (res.type == TYPE_CLASSIC) {
res.ndepends = 1 ;
} else if (res.type == TYPE_LONGRUN) {
res.ndepends += 1 ;
}
if (services->type.classic_longrun.log.run.exec >= 0)
res.exec_log_run = resolve_add_string(wres,keep.s + services->type.classic_longrun.log.run.exec) ;
if (services->type.classic_longrun.log.run.real_exec >= 0)
res.real_exec_log_run = resolve_add_string(wres,keep.s + services->type.classic_longrun.log.run.real_exec) ;
if (!service_resolve_setlognwrite(&res,dst))
goto err ;
}
}
if (!resolve_write(wres,dst,res.sa.s + res.name)) {
log_warnusys("write resolve file: ",dst,SS_RESOLVE,"/",res.sa.s + res.name) ;
goto err ;
}
e = 1 ;
err:
resolve_free(wres) ;
stralloc_free(&ndeps) ;
stralloc_free(&other_deps) ;
stralloc_free(&destlog) ;
return e ;
}
/*
* state_check_flags.c
*
* Copyright (c) 2018-2021 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 <oblibs/log.h>
#include <66/state.h>
int state_check_flags(char const *src, char const *name,int flags)
{
log_flow() ;
/** unitialized at all, all flags == 0.
* Return -1 to make a distinction between
* file absent and flag == 0. */
if (!state_check(src,name))
return -1 ;
ss_state_t sta = STATE_ZERO ;
if (!state_read(&sta,src,name))
// should not happen
return -1 ;
switch (flags)
{
case SS_FLAGS_RELOAD: return sta.reload ;
case SS_FLAGS_INIT: return sta.init ;
case SS_FLAGS_UNSUPERVISE: return sta.unsupervise ;
case SS_FLAGS_STATE: return sta.state ;
case SS_FLAGS_PID: return sta.pid ;
default:
// should never happen
return -1 ;
}
}
/*
* state_setflag.c
*
* Copyright (c) 2018-2021 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 <stdint.h>
#include <oblibs/log.h>
#include <66/state.h>
void state_setflag(ss_state_t *sta,int flags,int flags_val)
{
log_flow() ;
switch (flags)
{
case SS_FLAGS_RELOAD: sta->reload = flags_val ; break ;
case SS_FLAGS_INIT: sta->init = flags_val ; break ;
case SS_FLAGS_UNSUPERVISE: sta->unsupervise = flags_val ; break ;
case SS_FLAGS_STATE: sta->state = flags_val ; break ;
case SS_FLAGS_PID: sta->pid = (uint32_t)flags_val ; break ;
default: return ;
}
}
/*
* svc_init.c
*
* Copyright (c) 2018-2021 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 <66/svc.h>
#include <string.h>
#include <stdlib.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/sastr.h>
#include <skalibs/genalloc.h>
#include <skalibs/types.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#include <skalibs/posixplz.h>//touch
#include <s6/supervise.h>
#include <s6/ftrigr.h>
#include <s6/ftrigw.h>
#include <66/utils.h>
#include <66/resolve.h>
#include <66/constants.h>
#include <66/ssexec.h>
#include <66/state.h>
#define FLAGS_INIT_EARLIER 1
#define FLAGS_INIT_DOWN (1 << 1)
/**
* @init: array of resolve files of services
* @len: length of the @init array
* @flags: FLAGS_INIT_DOWN -> remove down file, FLAGS_INIT_EARLIER -> earlier services
* */
int svc_init(ssexec_t *info, resolve_service_t *init, unsigned int len, uint8_t flags)
{
log_flow() ;
uint8_t earlier = FLAGS_ISSET(flags, FLAGS_INIT_EARLIER) ;
uint8_t down = FLAGS_ISSET(flags, FLAGS_INIT_DOWN) ;
gid_t gid = getgid() ;
int r, e = 0 ;
unsigned int pos = 0, nsv = 0 ;
unsigned int real[len] ;
unsigned int down[len] ;
ss_state_t sta = STATE_ZERO ;
for (; pos < len ; pos++)
down[pos] = 0 ;
for (pos = 0 ; pos < len ; pos++) {
char *string = init[pos].sa.s ;
char *name = string + init[pos].name ;
size_t namelen = strlen(name) ;
size_t treenamelen = strlen(init[pos].treename) ;
if (!create_live_state(info, init[pos].treename))
log_warnusys_return(LOG_EXIT_ZERO, "create the live directory of states") ;
if (!earlier && s6_svc_ok(string + init[pos].runat)) {
log_info("Skipping: ", name," -- already initialized") ;
continue ;
}
char svsrc[info->base.len + SS_SYSTEM_LEN + 1 + treenamelen + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
auto_strings(svsrc, info->base.s, SS_SYSTEM_LEN, "/", treenamelen, SS_SVDIRS, SS_SVC, "/", name) ;
size_t runatlen = string + init[pos].runat ;
char scandir[runatlen + 6 + 1] ; // +6 event directory name
auto_strings(scandir, string + init[pos].runat) ;
r = scan_mode(scandir, S_IFDIR) ;
if (r < 0)
log_warnsys_return(LOG_EXIT_ZERO, "conflicting format for: ", scandir) ;
if (!r) {
log_trace("copy: ",svsrc, " to ", scandir) ;
if (!hiercopy(svsrc, scandir))
log_warnusys_return(LOG_EXIT_ZERO, "copy: ",svsrc," to: ",scandir) ;
}
auto_strings(scandir + runatlen, "/down") ;
fd = open_trunc(scandir) ;
if (fd < 0)
log_warnusys_return(LOG_EXIT_ZERO, "create down file: ", scandir) ;
fd_close(fd) ;
if (!init[pos].down)
down[nsv] = 1 ;
if (!earlier) {
auto_strings(scandir + runatlen, "/event") ;
log_trace("create fifo: ",scandir) ;
if (!ftrigw_fifodir_make(scandir, gid, 0))
log_warnusys_return(LOG_EXIT_ZERO, "create fifo: ",scandir) ;
}
real[nsv++] = init[pos] ;
}
if (!earlier) {
ftrigr_t fifo = FTRIGR_ZERO ;
uint16_t ids[len] ;
unsigned int nids = 0 ;
tain deadline ;
tain_now_set_stopwatch_g() ;
tain_addsec(&deadline, &STAMP, 2) ;
if (!ftrigr_startf_g(&fifo, &deadline))
goto err ;
for (pos = 0 ; pos < nsv ; pos++) {
char *string = init[real[pos]].sa.s ;
size_t runatlen = string + init[real[pos]].runat ;
char scandir[runatlen + 6 + 1] ; // +6 event directory name
auto_strings(scandir, string + init[real[pos]].runat) ;
log_trace("subcribe to fifo: ", scandir) ;
/** unsubscribe automatically, options is 0 */
ids[nids] = ftrigr_subscribe_g(&fifo, scandir, "s", 0, &deadline) ;
if (!ids[nids++]) {
log_warnusys("subcribe to fifo: ", scandir) ;
goto err ;
}
}
if (nids) {
log_trace("reload scandir: ", info->scandir.s) ;
if (scandir_send_signal(info->scandir.s, "h") <= 0) {
log_warnusys("reload scandir: ", info->scandir.s) ;
goto err ;
}
log_trace("waiting for events on fifo") ;
if (ftrigr_wait_and_g(&fifo, ids, nids, &deadline) < 0)
goto err ;
}
}
for (pos = 0 ; pos < nsv ; pos++) {
char const *string = init[real[pos]].sa.s ;
char const *name = string + init[real[pos]].name ;
char const *state = string + init[real[pos]].state ;
log_trace("Write state file of: ", name) ;
state_setflag(&sta, SS_FLAGS_RELOAD, SS_FLAGS_FALSE) ;
state_setflag(&sta, SS_FLAGS_INIT, SS_FLAGS_FALSE) ;
state_setflag(&sta, SS_FLAGS_STATE, SS_FLAGS_UNKNOWN) ;
state_setflag(&sta, SS_FLAGS_PID, SS_FLAGS_UNKNOWN) ;
if (!state_write(&sta,state,name)) {
log_warnusys("write state file of: ",name) ;
goto err ;
}
if (down[pos] && down) {
size_t runatlen = string + init[down[pos]].runat ;
char file[runatlen + 5 + 1] ;
auto_strings(file, string + init[down[pos]].runat, "/down") ;
log_trace("delete down file: ", file) ;
if (unlink(file) < 0 && errno != ENOENT) {
log_warnusys("delete down file: ", file)
}
}
log_info("Initialized successfully: ",name) ;
}
e = 1 ;
err:
ftrigr_end(&fifo) ;
return e ;
}
/*
* svc_switch_to.c
*
* Copyright (c) 2018-2021 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 <oblibs/log.h>
#include <string.h>
#include <skalibs/types.h>
#include <66/backup.h>
#include <66/utils.h>
#include <66/enum.h>
#include <66/ssexec.h>
/** 1-> backup
* 0-> ori */
int svc_switch_to(ssexec_t *info,unsigned int where)
{
log_flow() ;
int r ;
char type[UINT_FMT] ;
size_t typelen = uint_fmt(type, TYPE_CLASSIC) ;
type[typelen] = 0 ;
size_t cmdlen ;
char cmd[typelen + 6 + 1] ;
memcpy(cmd,"-t",2) ;
memcpy(cmd + 2,type,typelen) ;
cmdlen = 2 + typelen ;
memcpy(cmd + cmdlen," -b",3) ;
cmd[cmdlen + 3] = 0 ;
r = backup_cmd_switcher(VERBOSITY,cmd,info) ;
if (r < 0)
log_warnusys_return(LOG_EXIT_ZERO,"find origin of svc service for: ",info->treename.s) ;
// point to origin
if (!r && where)
{
log_trace("make a backup of svc service for: ",info->treename.s) ;
if (!backup_make_new(info,TYPE_CLASSIC))
log_warnusys_return(LOG_EXIT_ZERO,"make a backup of svc service for: ",info->treename.s) ;
log_trace("switch svc symlink of tree: ",info->treename.s," to backup") ;
memcpy(cmd + cmdlen," -s1",4) ;
cmd[cmdlen + 4] = 0 ;
r = backup_cmd_switcher(VERBOSITY,cmd,info) ;
if (r < 0)
{
log_warnusys("switch svc symlink of tree: ",info->treename.s," to backup") ;
}
}
else if (r > 0 && !where)
{
log_trace("switch svc symlink of tree: ",info->treename.s," to source") ;
memcpy(cmd + cmdlen," -s0",4) ;
cmd[cmdlen + 4] = 0 ;
r = backup_cmd_switcher(VERBOSITY,cmd,info) ;
if (r < 0)
{
log_warnusys("switch svc symlink of tree: ",info->treename.s," to source") ;
}
log_trace("make a backup of svc service for: ",info->treename.s) ;
if (!backup_make_new(info,TYPE_CLASSIC))
log_warnusys_return(LOG_EXIT_ZERO,"make a backup of svc service for: ",info->treename.s) ;
}
return 1 ;
}
/*
* tree_cmd_state.c
*
* Copyright (c) 2018-2021 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 <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <oblibs/obgetopt.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/files.h>
#include <oblibs/sastr.h>
#include <skalibs/stralloc.h>
#include <skalibs/types.h>
#include <skalibs/djbunix.h>
#include <66/utils.h>
#include <66/constants.h>
//USAGE "tree_state [ -v verbosity ] [ -a add ] [ -d delete ] [ -s search ] tree"
int tree_state(int argc, char const *const *argv)
{
log_flow() ;
int r, fd,skip = -1 ;
unsigned int add, del, sch, verbosity, err ;
size_t statesize = 0, treelen, statelen, pos = 0 ;
uid_t owner = MYUID ;
char const *tree = 0 ;
verbosity = 1 ;
add = del = sch = err = 0 ;
{
subgetopt l = SUBGETOPT_ZERO ;
for (;;)
{
int opt = getopt_args(argc,argv, "v:sad", &l) ;
if (opt == -1) break ;
if (opt == -2) log_warn_return(LOG_EXIT_ZERO,"options must be set first") ;
switch (opt)
{
case 'v' : if (!uint0_scan(l.arg, &verbosity)) return 0 ; break ;
case 'a' : add = 1 ; if (del) return 0 ; break ;
case 'd' : del = 1 ; if (add) return 0 ; break ;
case 's' : sch = 1 ; break ;
default : return 0 ;
}
}
argc -= l.ind ; argv += l.ind ;
}
if (argc < 1) return 0 ;
stralloc base = STRALLOC_ZERO ;
stralloc contents = STRALLOC_ZERO ;
tree = *argv ;
treelen = strlen(tree) ;
if (!set_ownersysdir(&base,owner))
{
log_warnusys("set owner directory") ;
stralloc_free(&base) ;
stralloc_free(&contents) ;
return 0 ;
}
/** /system/state */
char state[base.len + SS_SYSTEM_LEN + SS_STATE_LEN + 1] ;
memcpy(state,base.s,base.len) ;
memcpy(state + base.len,SS_SYSTEM,SS_SYSTEM_LEN) ;
memcpy(state + base.len + SS_SYSTEM_LEN, SS_STATE ,SS_STATE_LEN) ;
statelen = base.len + SS_SYSTEM_LEN + SS_STATE_LEN ;
state[statelen] = 0 ;
r = scan_mode(state,S_IFREG) ;
if (r == -1) { errno = EEXIST ; goto out ; }
if (!r)
{
log_warnusys("find: ",state) ;
goto out ;
}
statesize = file_get_size(state) ;
r = openreadfileclose(state,&contents,statesize) ;
if(!r)
{
log_warnusys("open: ", state) ;
goto out ;
}
if (contents.len)
{
if (!sastr_split_string_in_nline(&contents)) goto out ;
}
if (add)
{
if (sastr_cmp(&contents,tree) == -1)
{
fd = open_append(state) ;
if (fd < 0)
{
log_warnusys("open: ",state) ;
goto out ;
}
r = write(fd, tree,treelen);
r = write(fd, "\n",1);
if (r < 0)
{
log_warnusys("write: ",state," with ", tree," as content") ;
fd_close(fd) ;
goto out ;
}
fd_close(fd) ;
}
else
{
err = 2 ;
goto out ;
}
}
if (del)
{
skip = sastr_cmp(&contents,tree) ;
if (skip >= 0)
{
fd = open_trunc(state) ;
if (fd < 0)
{
log_warnusys("open_trunc ", state) ;
goto out ;
}
/*** replace it by write_file_unsafe*/
for (;pos < contents.len ; pos += strlen(contents.s + pos) + 1)
{
if (pos == (size_t)skip) continue ;
char *name = contents.s + pos ;
size_t namelen = strlen(contents.s + pos) ;
r = write(fd, name,namelen);
if (r < 0)
{
log_warnusys("write: ",state," with ", name," as content") ;
fd_close(fd) ;
goto out ;
}
r = write(fd, "\n",1);
if (r < 0)
{
log_warnusys("write: ",state," with ", name," as content") ;
fd_close(fd) ;
goto out ;
}
}
fd_close(fd) ;
}
else
{
err = 2 ;
goto out ;
}
}
if (sch)
{
if (sastr_cmp(&contents,tree) >= 0)
{
err = 1 ;
goto out ;
}
else
{
err = 2 ;
goto out ;
}
}
err = 1 ;
out:
stralloc_free(&base) ;
stralloc_free(&contents) ;
return err ;
}
int tree_cmd_state(unsigned int verbosity,char const *cmd, char const *tree)
{
log_flow() ;
int r ;
size_t pos = 0 ;
stralloc opts = STRALLOC_ZERO ;
if (!sastr_clean_string(&opts,cmd))
{
log_warnu("clean: ",cmd) ;
stralloc_free(&opts) ;
return 0 ;
}
int newopts = 5 + sastr_len(&opts) ;
char const *newargv[newopts] ;
unsigned int m = 0 ;
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, verbosity)] = 0 ;
newargv[m++] = "tree_state" ;
newargv[m++] = "-v" ;
newargv[m++] = fmt ;
for (;pos < opts.len; pos += strlen(opts.s + pos) + 1)
newargv[m++] = opts.s + pos ;
newargv[m++] = tree ;
newargv[m++] = 0 ;
r = tree_state(newopts,newargv) ;
stralloc_free(&opts) ;
return r ;
}
/*
* tree_copy.c
*
* Copyright (c) 2018-2021 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 <66/tree.h>
#include <string.h>
#include <oblibs/string.h>
#include <oblibs/directory.h>
#include <oblibs/log.h>
#include <skalibs/djbunix.h>
#include <66/constants.h>
int tree_copy(stralloc *dir, char const *tree,char const *treename)
{
log_flow() ;
char *fdir = 0 ;
size_t treelen = strlen(tree) ;
char tmp[treelen + SS_SVDIRS_LEN + 1] ;
auto_strings(tmp, tree, SS_SVDIRS) ;
fdir = dir_create_tmp(dir,"/tmp",treename) ;
if (!fdir) return 0 ;
if (!hiercopy(tmp,fdir)) return 0 ;
return 1 ;
}
/*
* tree_copy_tmp.c
*
* Copyright (c) 2018-2021 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 <66/tree.h>
#include <string.h>
#include <oblibs/string.h>
#include <oblibs/log.h>
#include <oblibs/directory.h>
#include <oblibs/types.h>
#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
#include <66/constants.h>
#include <66/enum.h>
#include <66/utils.h>
#include <66/ssexec.h>
#include <66/resolve.h>
void err(unsigned int *e, unsigned int msg,char const *resolve,char const *swap, char const *svdir)
{
switch (msg)
{
case 0: log_warnu("set revolve pointer to source") ;
break ;
case 1: log_warnu("set revolve pointer to backup") ;
break ;
case 2: log_warnu("copy : ",svdir," to ", resolve) ;
break ;
case 3: log_warnu("remove directory: ", svdir) ;
break ;
case 4: log_warnu("set revolve pointer to live") ;
break ;
default: break ;
}
*e = 0 ;
}
int tree_copy_tmp(char const *workdir, ssexec_t *info)
{
log_flow() ;
stralloc saresolve = STRALLOC_ZERO ;
stralloc swap = STRALLOC_ZERO ;
unsigned int e = 1 ;
size_t svdirlen ;
char svdir[info->tree.len + SS_SVDIRS_LEN + SS_RESOLVE_LEN + 1] ;
memcpy(svdir,info->tree.s,info->tree.len) ;
memcpy(svdir + info->tree.len,SS_SVDIRS,SS_SVDIRS_LEN) ;
svdirlen = info->tree.len + SS_SVDIRS_LEN ;
memcpy(svdir + svdirlen,SS_SVC, SS_SVC_LEN) ;
svdir[svdirlen + SS_SVC_LEN] = 0 ;
/** svc */
if (rm_rf(svdir) < 0)
{
if (!sa_pointo(&saresolve,info,TYPE_CLASSIC,SS_RESOLVE_SRC))
{
err(&e,0,saresolve.s,swap.s,svdir) ;
goto err ;
}
if (!sa_pointo(&swap,info,TYPE_CLASSIC,SS_RESOLVE_BACK))
{
err(&e,1,saresolve.s,swap.s,svdir) ;
goto err ;
}
if (!hiercopy(swap.s,saresolve.s))
{
err(&e,2,saresolve.s,swap.s,svdir) ;
goto err ;
}
err(&e,3,saresolve.s,swap.s,svdir) ;
goto err ;
}
/** db */
memcpy(svdir + svdirlen,SS_DB, SS_DB_LEN) ;
svdir[svdirlen + SS_DB_LEN] = 0 ;
if (rm_rf(svdir) < 0)
{
if (!sa_pointo(&saresolve,info,TYPE_LONGRUN,SS_RESOLVE_SRC))
{
err(&e,0,saresolve.s,swap.s,svdir) ;
goto err ;
}
if (!sa_pointo(&swap,info,TYPE_LONGRUN,SS_RESOLVE_BACK))
{
err(&e,1,saresolve.s,swap.s,svdir) ;
goto err ;
}
if (!hiercopy(swap.s,saresolve.s))
{
err(&e,2,saresolve.s,swap.s,svdir) ;
goto err ;
}
err(&e,3,saresolve.s,swap.s,svdir) ;
goto err ;
}
/** resolve */
memcpy(svdir + svdirlen,SS_RESOLVE,SS_RESOLVE_LEN) ;
svdir[svdirlen + SS_RESOLVE_LEN] = 0 ;
if (rm_rf(svdir) < 0)
{
if (!sa_pointo(&saresolve,info,SS_NOTYPE,SS_RESOLVE_SRC))
{
err(&e,0,saresolve.s,swap.s,svdir) ;
goto err ;
}
saresolve.len--;
if (!stralloc_cats(&saresolve,SS_RESOLVE)) log_warnsys_return(LOG_EXIT_ZERO,"tree_copy_tmp") ;
if (!stralloc_0(&saresolve)) log_warnsys_return(LOG_EXIT_ZERO,"tree_copy_tmp") ;
if (!sa_pointo(&swap,info,SS_NOTYPE,SS_RESOLVE_BACK))
{
err(&e,1,saresolve.s,swap.s,svdir) ;
goto err ;
}
swap.len--;
if (!stralloc_cats(&swap,SS_RESOLVE)) log_warnsys_return(LOG_EXIT_ZERO,"tree_copy_tmp") ;
if (!stralloc_0(&swap)) log_warnsys_return(LOG_EXIT_ZERO,"tree_copy_tmp") ;
if (!hiercopy(swap.s,saresolve.s))
{
err(&e,2,saresolve.s,swap.s,svdir) ;
goto err ;
}
err(&e,3,saresolve.s,swap.s,svdir) ;
goto err ;
}
svdir[svdirlen] = 0 ;
if (!hiercopy(workdir,svdir))
{
if (!sa_pointo(&saresolve,info,SS_NOTYPE,SS_RESOLVE_SRC))
{
err(&e,0,saresolve.s,swap.s,svdir) ;
goto err ;
}
if (!sa_pointo(&swap,info,SS_NOTYPE,SS_RESOLVE_BACK))
{
err(&e,1,saresolve.s,swap.s,svdir) ;
goto err ;
}
if (!hiercopy(swap.s,saresolve.s))
{
err(&e,2,saresolve.s,swap.s,svdir) ;
goto err ;
}
err(&e,2,saresolve.s,swap.s,svdir) ;
goto err ;
}
err:
stralloc_free(&saresolve) ;
stralloc_free(&swap) ;
return e ;
}
/*
* create_live_state.c
*
* Copyright (c) 2018-2021 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 <sys/types.h>
#include <unistd.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/directory.h>
#include <66/ssexec.h>
#include <66/utils.h>
#include <66/constants.h>
int create_live_state(ssexec_t *info, char const *treename)
{
log_flow() ;
int r ;
gid_t gidowner ;
size_t treenamelen = strlen(treename) ;
char ste[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + treenamelen + 1] ;
if (!yourgid(&gidowner, info->owner))
log_warnusys_return(LOG_EXIT_ZERO, "get gid of: ", info->ownerstr) ;
auto_strings(ste, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", treename) ;
r = scan_mode(ste, S_IFDIR) ;
if (r < 0)
log_warnsys_return(LOG_EXIT_ZERO, "conflicting format for: ", ste) ;
if (!r) {
r = dir_create_parent(ste, 0700) ;
if (!r)
log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", ste) ;
ste[info->live.len + SS_STATE_LEN + info->ownerlen + 1] = 0 ;
if (chown(ste, info->owner, gidowner) < 0)
log_warnusys_return(LOG_EXIT_ZERO, "chown: ", ste) ;
}
return 1 ;
}
/*
* create_live_tree.c
*
* Copyright (c) 2018-2021 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 <sys/types.h>
#include <unistd.h>
#include <oblibs/log.h>
#include <oblibs/string.h>
#include <oblibs/types.h>
#include <oblibs/directory.h>
#include <66/ssexec.h>
#include <66/utils.h>
#include <66/constants.h>
int create_live_tree(ssexec_t *info)
{
log_flow() ;
int r = scan_mode(info->livetree.s, S_IFDIR) ;
if (r < 0)
log_warn_return(LOG_EXIT_ZERO, "conflicting format for: ", info->livetree.s) ;
if (!r) {
log_trace("create directory: ", info->livetree.s) ;
if (!dir_create(info->livetree.s, 0700))
log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", info->livetree.s) ;
log_trace("chown directory: ", info->livetree.s) ;
if (chown(info->livetree.s,info->owner,gidowner) < 0)
log_warnusys_return(LOG_EXIT_SYS, "chown directory: ", info->livetree.s) ;
}
return 1 ;
}
/*
* set_livetree.c
*
* Copyright (c) 2018-2021 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 <oblibs/log.h>
#include <skalibs/types.h>
#include <skalibs/stralloc.h>
#include <66/utils.h>
#include <66/constants.h>
int set_livetree(stralloc *livetree,uid_t owner)
{
log_flow() ;
int r ;
char ownerpack[UID_FMT] ;
r = set_livedir(livetree) ;
if (r < 0) return -1 ;
if (!r) return 0 ;
size_t ownerlen = uid_fmt(ownerpack,owner) ;
ownerpack[ownerlen] = 0 ;
if (!stralloc_cats(livetree,SS_TREE "/")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
if (!stralloc_cats(livetree,ownerpack)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
if (!stralloc_0(livetree)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
livetree->len--;
return 1 ;
}
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