diff --git a/src/include/66/resolve.h b/src/include/66/resolve.h index 4e3822e1214790bb5f06bd5c14cce2c380394b88..32f3951cf7e484e46d8fe5583cffb47e7f7e544b 100644 --- a/src/include/66/resolve.h +++ b/src/include/66/resolve.h @@ -27,6 +27,9 @@ #include <66/ssexec.h> #include <66/parser.h> +#include <66/tree.h> +#include <66/service.h> + #define SS_RESOLVE "/.resolve" #define SS_RESOLVE_LEN (sizeof SS_RESOLVE - 1) @@ -38,118 +41,57 @@ #define SS_SIMPLE 0 #define SS_DOUBLE 1 -typedef struct ss_resolve_s ss_resolve_t, *ss_resolve_t_ref ; -struct ss_resolve_s +typedef struct resolve_wrapper_s resolve_wrapper_t, *resolve_wrapper_t_ref ; +struct resolve_wrapper_s { - uint32_t salen ; - stralloc sa ; - - uint32_t name ; - uint32_t description ; - uint32_t version ; - uint32_t logger ; - uint32_t logreal ; - uint32_t logassoc ; - uint32_t dstlog ; - uint32_t deps ; // for module -> list of s6-rc service - uint32_t optsdeps ; //optional dependencies - uint32_t extdeps ; //external dependencies - uint32_t contents ; // module -> list of s6-rc and s6 service - uint32_t src ; //frontend source - uint32_t srconf ; //configuration file source - uint32_t live ; //run/66 - uint32_t runat ; //livetree->longrun,scandir->svc - uint32_t tree ; //var/lib/66/system/tree - uint32_t treename ; - uint32_t state ; //run/66/state/uid/treename/ - uint32_t exec_run ; - uint32_t exec_log_run ; - uint32_t real_exec_run ; - uint32_t real_exec_log_run ; - uint32_t exec_finish ; - uint32_t real_exec_finish ; - - uint32_t type ; - uint32_t ndeps ; - uint32_t noptsdeps ; - uint32_t nextdeps ; - uint32_t ncontents ; - uint32_t down ; - uint32_t disen ;//disable->0,enable->1 + uint8_t type ; + void *obj ; } ; -#define RESOLVE_ZERO { 0,STRALLOC_ZERO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } -typedef enum ss_resolve_enum_e ss_resolve_enum_t, *ss_resolve_enum_t_ref; -enum ss_resolve_enum_e -{ - SS_RESOLVE_ENUM_NAME = 0, - SS_RESOLVE_ENUM_DESCRIPTION, - SS_RESOLVE_ENUM_VERSION, - SS_RESOLVE_ENUM_LOGGER, - SS_RESOLVE_ENUM_LOGREAL, - SS_RESOLVE_ENUM_LOGASSOC, - SS_RESOLVE_ENUM_DSTLOG, - SS_RESOLVE_ENUM_DEPS, - SS_RESOLVE_ENUM_OPTSDEPS, - SS_RESOLVE_ENUM_EXTDEPS, - SS_RESOLVE_ENUM_CONTENTS, - SS_RESOLVE_ENUM_SRC, - SS_RESOLVE_ENUM_SRCONF, - SS_RESOLVE_ENUM_LIVE, - SS_RESOLVE_ENUM_RUNAT, - SS_RESOLVE_ENUM_TREE, - SS_RESOLVE_ENUM_TREENAME, - SS_RESOLVE_ENUM_STATE, - SS_RESOLVE_ENUM_EXEC_RUN, - SS_RESOLVE_ENUM_EXEC_LOG_RUN, - SS_RESOLVE_ENUM_REAL_EXEC_RUN, - SS_RESOLVE_ENUM_REAL_EXEC_LOG_RUN, - SS_RESOLVE_ENUM_EXEC_FINISH, - SS_RESOLVE_ENUM_REAL_EXEC_FINISH, - SS_RESOLVE_ENUM_TYPE, - SS_RESOLVE_ENUM_NDEPS, - SS_RESOLVE_ENUM_NOPTSDEPS, - SS_RESOLVE_ENUM_NEXTDEPS, - SS_RESOLVE_ENUM_NCONTENTS, - SS_RESOLVE_ENUM_DOWN, - SS_RESOLVE_ENUM_DISEN, - SS_RESOLVE_ENUM_ENDOFKEY -} ; - -typedef struct ss_resolve_field_table_s ss_resolve_field_table_t, *ss_resolve_field_table_t_ref ; -struct ss_resolve_field_table_s -{ - char *field ; -} ; +#define RESOLVE_SET_SAWRES(wres) \ + stralloc_ref sawres ; \ + if (wres->type == SERVICE_STRUCT) sawres = (&((resolve_service_t *)wres->obj)->sa) ; \ + else if (wres->type == TREE_STRUCT) sawres = (&((resolve_tree_t *)wres->obj)->sa) ; -extern ss_resolve_field_table_t ss_resolve_field_table[] ; +/** + * + * General API + * + * */ + +extern resolve_wrapper_t *resolve_set_struct(uint8_t type, void *s) ; +extern int resolve_init(resolve_wrapper_t *wres) ; +extern int resolve_read(resolve_wrapper_t *wres, char const *src, char const *name) ; +extern int resolve_write(resolve_wrapper_t *wres, char const *dst, char const *name) ; +extern int resolve_check(char const *src, char const *name) ; +extern int resolve_append(genalloc *ga, resolve_wrapper_t *wres) ; +extern int resolve_search(genalloc *ga, char const *name, uint8_t type) ; +extern int resolve_cmp(genalloc *ga, char const *name, uint8_t type) ; +extern void resolve_rmfile(char const *src,char const *name) ; +extern ssize_t resolve_add_string(resolve_wrapper_t *wres, char const *data) ; + +/** + * + * Freed + * + * */ -/** Graph struct */ -typedef struct ss_resolve_graph_ndeps_s ss_resolve_graph_ndeps_t ; -struct ss_resolve_graph_ndeps_s -{ - uint32_t idx ;//uint32_t - genalloc ndeps ;//uint32_t -} ; -#define RESOLVE_GRAPH_NDEPS_ZERO { 0 , GENALLOC_ZERO } +extern void resolve_free(resolve_wrapper_t *wres) ; +extern void resolve_deep_free(uint8_t type, genalloc *g) ; -typedef struct ss_resolve_graph_s ss_resolve_graph_t, *ss_resolve_graph_t_ref ; -struct ss_resolve_graph_s -{ - genalloc name ;//ss_resolve_t - genalloc cp ; //ss_resolve_graph_ndeps_t - genalloc sorted ;//ss_resolve_t -} ; -#define RESOLVE_GRAPH_ZERO { GENALLOC_ZERO , GENALLOC_ZERO , GENALLOC_ZERO } +/** + * + * CDB + * + * */ -typedef enum visit_e visit ; -enum visit_e -{ - SS_WHITE = 0, - SS_GRAY, - SS_BLACK -} ; +extern int resolve_read_cdb(resolve_wrapper_t *wres, char const *name) ; +extern int resolve_write_cdb(resolve_wrapper_t *wres, char const *dst, char const *name) ; +extern int resolve_add_cdb(cdbmaker *c, char const *key, char const *data) ; +extern int resolve_add_cdb_uint(cdbmaker *c, char const *key, uint32_t data) ; +extern int resolve_find_cdb(stralloc *result, cdb const *c, char const *key) ; +/* extern ss_resolve_t const ss_resolve_zero ; extern void ss_resolve_init(ss_resolve_t *res) ; extern void ss_resolve_free(ss_resolve_t *res) ; @@ -182,21 +124,14 @@ extern int ss_resolve_sort_byfile_first(stralloc *sort, char const *src) ; extern int ss_resolve_svtree(stralloc *svtree,char const *svname,char const *tree) ; extern int ss_resolve_modify_field(ss_resolve_t *res, ss_resolve_enum_t field, char const *data) ; extern int ss_resolve_put_field_to_sa(stralloc *sa,ss_resolve_t *res, ss_resolve_enum_t field) ; +*/ -/** Graph function */ -extern void ss_resolve_graph_ndeps_free(ss_resolve_graph_ndeps_t *graph) ; -extern void ss_resolve_graph_free(ss_resolve_graph_t *graph) ; - -extern int ss_resolve_graph_src(ss_resolve_graph_t *graph, char const *dir, unsigned int reverse, unsigned int what) ; -extern int ss_resolve_graph_build(ss_resolve_graph_t *graph,ss_resolve_t *res,char const *src,unsigned int reverse) ; -extern int ss_resolve_graph_sort(ss_resolve_graph_t *graph) ; -extern int ss_resolve_dfs(ss_resolve_graph_t *graph, unsigned int idx, visit *c,unsigned int *ename,unsigned int *edeps) ; -extern int ss_resolve_graph_publish(ss_resolve_graph_t *graph,unsigned int reverse) ; -/** cdb */ +/** cdb extern int ss_resolve_read_cdb(ss_resolve_t *dres, char const *name) ; extern int ss_resolve_write_cdb(ss_resolve_t *res, char const *dst, char const *name) ; extern int ss_resolve_add_cdb(cdbmaker *c,char const *key,char const *data) ; extern int ss_resolve_add_cdb_uint(cdbmaker *c, char const *key,uint32_t data) ; extern int ss_resolve_find_cdb(stralloc *result, cdb const *c,char const *key) ; +*/ #endif diff --git a/src/include/66/service.h b/src/include/66/service.h index 71f150fdb9fe988c3df4392a920c7229877a6bde..769b15b005be0a103458e00f0566cc0b8a0aee7e 100644 --- a/src/include/66/service.h +++ b/src/include/66/service.h @@ -15,9 +15,176 @@ #ifndef SS_SERVICE_H #define SS_SERVICE_H +#include <stdint.h> + #include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/cdb.h> +#include <skalibs/cdbmake.h> + +#include <66/parser.h> +#include <66/ssexec.h> + + +/** Graph struct */ +typedef struct ss_resolve_graph_ndeps_s ss_resolve_graph_ndeps_t ; +struct ss_resolve_graph_ndeps_s +{ + uint32_t idx ;//uint32_t + genalloc ndeps ;//uint32_t +} ; +#define RESOLVE_GRAPH_NDEPS_ZERO { 0 , GENALLOC_ZERO } + +typedef struct ss_resolve_graph_s ss_resolve_graph_t, *ss_resolve_graph_t_ref ; +struct ss_resolve_graph_s +{ + genalloc name ;//resolve_service_t + genalloc cp ; //ss_resolve_graph_ndeps_t + genalloc sorted ;//resolve_service_t +} ; +#define RESOLVE_GRAPH_ZERO { GENALLOC_ZERO , GENALLOC_ZERO , GENALLOC_ZERO } + +typedef enum visit_e visit ; +enum visit_e +{ + SS_WHITE = 0, + SS_GRAY, + SS_BLACK +} ; + + +#define SERVICE_STRUCT 0 + +typedef struct resolve_service_s resolve_service_t, *resolve_service_t_ref ; +struct resolve_service_s +{ + uint32_t salen ; + stralloc sa ; + + uint32_t name ; + uint32_t description ; + uint32_t version ; + uint32_t logger ; + uint32_t logreal ; + uint32_t logassoc ; + uint32_t dstlog ; + uint32_t deps ; // for module -> list of s6-rc service + uint32_t optsdeps ; //optional dependencies + uint32_t extdeps ; //external dependencies + uint32_t contents ; // module -> list of s6-rc and s6 service + uint32_t src ; //frontend source + uint32_t srconf ; //configuration file source + uint32_t live ; //run/66 + uint32_t runat ; //livetree->longrun,scandir->svc + uint32_t tree ; //var/lib/66/system/tree + uint32_t treename ; + uint32_t state ; //run/66/state/uid/treename/ + uint32_t exec_run ; + uint32_t exec_log_run ; + uint32_t real_exec_run ; + uint32_t real_exec_log_run ; + uint32_t exec_finish ; + uint32_t real_exec_finish ; + + uint32_t type ; + uint32_t ndeps ; + uint32_t noptsdeps ; + uint32_t nextdeps ; + uint32_t ncontents ; + uint32_t down ; + uint32_t disen ;//disable->0,enable->1 +} ; +#define RESOLVE_SERVICE_ZERO { 0,STRALLOC_ZERO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } + +typedef enum resolve_service_enum_e resolve_service_enum_t, *resolve_service_enum_t_ref; +enum resolve_service_enum_e +{ + SERVICE_ENUM_NAME = 0, + SERVICE_ENUM_DESCRIPTION, + SERVICE_ENUM_VERSION, + SERVICE_ENUM_LOGGER, + SERVICE_ENUM_LOGREAL, + SERVICE_ENUM_LOGASSOC, + SERVICE_ENUM_DSTLOG, + SERVICE_ENUM_DEPS, + SERVICE_ENUM_OPTSDEPS, + SERVICE_ENUM_EXTDEPS, + SERVICE_ENUM_CONTENTS, + SERVICE_ENUM_SRC, + SERVICE_ENUM_SRCONF, + SERVICE_ENUM_LIVE, + SERVICE_ENUM_RUNAT, + SERVICE_ENUM_TREE, + SERVICE_ENUM_TREENAME, + SERVICE_ENUM_STATE, + SERVICE_ENUM_EXEC_RUN, + SERVICE_ENUM_EXEC_LOG_RUN, + SERVICE_ENUM_REAL_EXEC_RUN, + SERVICE_ENUM_REAL_EXEC_LOG_RUN, + SERVICE_ENUM_EXEC_FINISH, + SERVICE_ENUM_REAL_EXEC_FINISH, + SERVICE_ENUM_TYPE, + SERVICE_ENUM_NDEPS, + SERVICE_ENUM_NOPTSDEPS, + SERVICE_ENUM_NEXTDEPS, + SERVICE_ENUM_NCONTENTS, + SERVICE_ENUM_DOWN, + SERVICE_ENUM_DISEN, + SERVICE_ENUM_ENDOFKEY +} ; + +typedef struct resolve_service_field_table_s resolve_service_field_table_t, *resolve_service_field_table_t_ref ; +struct resolve_service_field_table_s +{ + char *field ; +} ; + +extern resolve_service_field_table_t resolve_service_field_table[] ; + +extern int service_isenabled(char const *sv) ; +extern int service_isenabledat(stralloc *tree, char const *sv) ; +extern int service_frontend_src(stralloc *sasrc, char const *name, char const *src) ; +extern int service_frontend_path(stralloc *sasrc,char const *sv, uid_t owner,char const *directory_forced) ; +extern int service_endof_dir(char const *dir, char const *name) ; +extern int service_cmp_basedir(char const *dir) ; + +/** + * + * Resolve API + * + * */ + +extern int service_read_cdb(cdb *c, resolve_service_t *res) ; +extern int service_write_cdb(cdbmaker *c, resolve_service_t *sres) ; +extern int service_resolve_copy(resolve_service_t *dst, resolve_service_t *res) ; +extern int service_resolve_sort_bytype(genalloc *gares, stralloc *list, char const *src) ; +extern int service_resolve_svtree(stralloc *svtree, char const *svname, char const *tree) ; +extern int service_resolve_setnwrite(sv_alltype *services, ssexec_t *info, char const *dst) ; +extern int service_resolve_setlognwrite(resolve_service_t *sv, char const *dst) ; +extern int service_resolve_write_master(ssexec_t *info, ss_resolve_graph_t *graph, char const *dir, unsigned int reverse) ; +extern int service_resolve_modify_field(resolve_service_t *res, resolve_service_enum_t field, char const *data) ; +extern int service_resolve_field_to_sa(stralloc *sa, resolve_service_t *res, resolve_service_enum_t field) ; +/** + * + * obsolete function + * + * + * */ +extern int service_resolve_add_deps(genalloc *tokeep, resolve_service_t *res, char const *src) ; +extern int service_resolve_add_rdeps(genalloc *tokeep, resolve_service_t *res, char const *src) ; +extern int service_resolve_add_logger(genalloc *ga,char const *src) ; + + + +/** Graph function */ +extern void ss_resolve_graph_ndeps_free(ss_resolve_graph_ndeps_t *graph) ; +extern void ss_resolve_graph_free(ss_resolve_graph_t *graph) ; + +extern int ss_resolve_graph_src(ss_resolve_graph_t *graph, char const *dir, unsigned int reverse, unsigned int what) ; -int service_isenabled(char const *sv) ; -int service_isenabledat(stralloc *tree, char const *sv) ; +extern int ss_resolve_graph_build(ss_resolve_graph_t *graph,resolve_service_t *res,char const *src,unsigned int reverse) ; +extern int ss_resolve_graph_sort(ss_resolve_graph_t *graph) ; +extern int ss_resolve_dfs(ss_resolve_graph_t *graph, unsigned int idx, visit *c,unsigned int *ename,unsigned int *edeps) ; +extern int ss_resolve_graph_publish(ss_resolve_graph_t *graph,unsigned int reverse) ; #endif diff --git a/src/include/66/utils.h b/src/include/66/utils.h index 0a14b585249ddab3aad9fcdcc05568a141c29e1f..3490e94bdb8a47601d353117f6bbd866c2008a74 100644 --- a/src/include/66/utils.h +++ b/src/include/66/utils.h @@ -24,7 +24,7 @@ #include <skalibs/genalloc.h> #include <66/ssexec.h> -#include <66/resolve.h> +#include <66/service.h> #define MYUID getuid() #define YOURUID(passto,owner) youruid(passto,owner) @@ -44,11 +44,15 @@ extern int set_livestate(stralloc *live,uid_t owner) ; extern int set_ownerhome(stralloc *base,uid_t owner) ; extern int set_ownersysdir(stralloc *base,uid_t owner) ; extern int read_svfile(stralloc *sasv,char const *name,char const *src) ; -extern int module_in_cmdline(genalloc *gares, ss_resolve_t *res, char const *dir) ; +extern int module_in_cmdline(genalloc *gares, resolve_service_t *res, char const *dir) ; extern int module_search_service(char const *src, genalloc *gares, char const *name,uint8_t *found, char module_name[256]) ; /** ss_instance.c file */ extern int instance_check(char const *svname) ; extern int instance_splitname(stralloc *sa,char const *name,int len,int what) ; extern int instance_create(stralloc *sasv,char const *svname, char const *regex, int len) ; +extern int module_path(stralloc *sdir, stralloc *mdir, char const *sv,char const *frontend_src, uid_t owner) ; +extern int sa_pointo(stralloc *sa, ssexec_t *info, int type, unsigned int where) ; +extern int create_live(ssexec_t *info) ; + #endif diff --git a/src/lib66/resolve.c b/src/lib66/resolve.c new file mode 100644 index 0000000000000000000000000000000000000000..177fdb283500156ee994c22ab8e9340b2d290a90 --- /dev/null +++ b/src/lib66/resolve.c @@ -0,0 +1,449 @@ +/* + * resolve.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 <unistd.h>//close, fsync +#include <stdlib.h>//mkstemp, malloc, free +#include <sys/types.h>//ssize_t +#include <stdio.h>//rename + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/types.h> + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/cdb.h> +#include <skalibs/djbunix.h> +#include <skalibs/cdbmake.h> +#include <skalibs/posixplz.h>//unlink +#include <skalibs/types.h>//uint##_pack + +#include <66/resolve.h> +#include <66/service.h> +#include <66/tree.h> + +/** + * + * MAIN API + * + * */ + +resolve_wrapper_t *resolve_set_struct(uint8_t type, void *s) +{ + log_flow() ; + + resolve_wrapper_t *wres = malloc(sizeof(resolve_wrapper_t)) ; + + wres->obj = s ; + wres->type = type ; + return wres ; +} ; + +int resolve_init(resolve_wrapper_t *wres) +{ + log_flow() ; + + RESOLVE_SET_SAWRES(wres) ; + + sawres->len = 0 ; + + return resolve_add_string(wres,"") ; +} + +int resolve_read(resolve_wrapper_t *wres, char const *src, char const *name) +{ + log_flow() ; + + size_t srclen = strlen(src) ; + size_t namelen = strlen(name) ; + + char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen + 1] ; + auto_strings(tmp,src,SS_RESOLVE,"/",name) ; + + if (!resolve_read_cdb(wres,tmp)) + return 0 ; + + return 1 ; +} + +int resolve_write(resolve_wrapper_t *wres, char const *dst, char const *name) +{ + log_flow() ; + + size_t dstlen = strlen(dst) ; + size_t namelen = strlen(name) ; + + char tmp[dstlen + SS_RESOLVE_LEN + 1 + namelen + 1] ; + auto_strings(tmp,dst,SS_RESOLVE,"/") ; + + if (!resolve_write_cdb(wres,tmp,name)) + return 0 ; + + return 1 ; +} + +int resolve_check(char const *src, char const *name) +{ + log_flow() ; + + int r ; + size_t srclen = strlen(src) ; + size_t namelen = strlen(name) ; + + char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen + 1] ; + auto_strings(tmp, src, SS_RESOLVE, "/", name) ; + + r = scan_mode(tmp,S_IFREG) ; + if (r <= 0) + return 0 ; + + return 1 ; +} + +int resolve_append(genalloc *ga, resolve_wrapper_t *wres) +{ + log_flow() ; + + int e = 0 ; + + if (wres->type == SERVICE_STRUCT) { + + resolve_service_t cp = RESOLVE_SERVICE_ZERO ; + if (!service_resolve_copy(&cp, ((resolve_service_t *)wres->obj))) + goto err ; + + if (!genalloc_append(resolve_service_t, ga, &cp)) + goto err ; + + } else if (wres->type == TREE_STRUCT) { + + resolve_tree_t cp = RESOLVE_TREE_ZERO ; + if (!tree_resolve_copy(&cp, ((resolve_tree_t *)wres->obj))) + goto err ; + + if (!genalloc_append(resolve_tree_t, ga, &cp)) + goto err ; + + } + + e = 1 ; + err: + return e ; +} + +int resolve_search(genalloc *ga, char const *name, uint8_t type) +{ + log_flow() ; + + size_t len, pos = 0 ; + + if (type == SERVICE_STRUCT) { + + len = genalloc_len(resolve_service_t, ga) ; + + for (;pos < len ; pos++) { + + char *s = genalloc_s(resolve_service_t,ga)[pos].sa.s + genalloc_s(resolve_service_t,ga)[pos].name ; + if (!strcmp(name,s)) + return pos ; + } + + } else if (type == TREE_STRUCT) { + + len = genalloc_len(resolve_tree_t, ga) ; + + for (;pos < len ; pos++) { + + char *s = genalloc_s(resolve_tree_t,ga)[pos].sa.s + genalloc_s(resolve_tree_t,ga)[pos].name ; + if (!strcmp(name,s)) + return pos ; + } + } + + return -1 ; +} + +int resolve_cmp(genalloc *ga, char const *name, uint8_t type) +{ + log_flow() ; + + size_t len, pos = 0 ; + + if (type == SERVICE_STRUCT) { + + len = genalloc_len(resolve_service_t, ga) ; + + for (;pos < len ; pos++) { + + char *str = genalloc_s(resolve_service_t, ga)[pos].sa.s ; + char *s = str + genalloc_s(resolve_service_t, ga)[pos].name ; + if (!strcmp(name,s)) + return 1 ; + } + + } else if (type == TREE_STRUCT) { + + len = genalloc_len(resolve_tree_t, ga) ; + + for (;pos < len ; pos++) { + + char *str = genalloc_s(resolve_tree_t, ga)[pos].sa.s ; + char *s = str + genalloc_s(resolve_tree_t, ga)[pos].name ; + if (!strcmp(name,s)) + return 1 ; + } + } + + return 0 ; +} + +void resolve_rmfile(char const *src,char const *name) +{ + log_flow() ; + + size_t srclen = strlen(src) ; + size_t namelen = strlen(name) ; + + char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen +1] ; + auto_strings(tmp, src, SS_RESOLVE, "/", name) ; + + unlink_void(tmp) ; +} + +ssize_t resolve_add_string(resolve_wrapper_t *wres, char const *data) +{ + log_flow() ; + + RESOLVE_SET_SAWRES(wres) ; + + ssize_t baselen = sawres->len ; + + if (!data) { + + if (!stralloc_catb(sawres,"",1)) + log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ; + + return baselen ; + } + + size_t datalen = strlen(data) ; + + if (!stralloc_catb(sawres,data,datalen + 1)) + log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ; + + return baselen ; +} + +/** + * + * FREED + * + * */ + +void resolve_free(resolve_wrapper_t *wres) +{ + log_flow() ; + + RESOLVE_SET_SAWRES(wres) ; + + stralloc_free(sawres) ; + + free(wres) ; +} + +void resolve_deep_free(uint8_t type, genalloc *g) +{ + log_flow() ; + + size_t pos = 0 ; + + if (type == SERVICE_STRUCT) { + + for (; pos < genalloc_len(resolve_service_t, g) ; pos++) + stralloc_free(&genalloc_s(resolve_service_t, g)[pos].sa) ; + + genalloc_free(resolve_service_t, g) ; + + } else if (type == TREE_STRUCT) { + + for (; pos < genalloc_len(resolve_tree_t, g) ; pos++) + stralloc_free(&genalloc_s(resolve_tree_t, g)[pos].sa) ; + + genalloc_free(resolve_tree_t, g) ; + } + +} + +/** + * + * CDB + * + * */ + +int resolve_read_cdb(resolve_wrapper_t *wres, char const *name) +{ + log_flow() ; + + int fd, e = 0 ; + cdb c = CDB_ZERO ; + + fd = open_readb(name) ; + if (fd < 0) { + log_warnusys("open: ",name) ; + goto err_fd ; + } + + if (!cdb_init_fromfd(&c, fd)) { + log_warnusys("cdb_init: ", name) ; + goto err ; + } + + if (wres->type == SERVICE_STRUCT) { + + if (!service_read_cdb(&c, ((resolve_service_t *)wres->obj))) + goto err ; + + } else if (wres->type == TREE_STRUCT){ + + if (!tree_read_cdb(&c, ((resolve_tree_t *)wres->obj))) + goto err ; + + } + + e = 1 ; + + err: + close(fd) ; + err_fd: + cdb_free(&c) ; + return e ; +} + +int resolve_write_cdb(resolve_wrapper_t *wres, char const *dst, char const *name) +{ + log_flow() ; + + int fd ; + size_t dstlen = strlen(dst), namelen = strlen(name); + cdbmaker c = CDBMAKER_ZERO ; + char tfile[dstlen + 1 + namelen + namelen + 9] ; + char dfile[dstlen + 1 + namelen + 1] ; + + auto_strings(dfile,dst,"/",name) ; + + auto_strings(tfile,dst,"/",name,":",name,":","XXXXXX") ; + + fd = mkstemp(tfile) ; + if (fd < 0 || ndelay_off(fd)) { + log_warnusys("mkstemp: ", tfile) ; + goto err_fd ; + } + + if (!cdbmake_start(&c, fd)) { + log_warnusys("cdbmake_start") ; + goto err ; + } + + if (wres->type == SERVICE_STRUCT) { + + if (!service_write_cdb(&c, ((resolve_service_t *)wres->obj))) + goto err ; + + } else if (wres->type == TREE_STRUCT) { + + if (!tree_write_cdb(&c, ((resolve_tree_t *)wres->obj))) + goto err ; + + } + + if (!cdbmake_finish(&c) || fsync(fd) < 0) { + log_warnusys("write to: ", tfile) ; + goto err ; + } + + close(fd) ; + + if (rename(tfile, dfile) < 0) { + log_warnusys("rename ", tfile, " to ", dfile) ; + goto err_fd ; + } + + return 1 ; + + err: + close(fd) ; + err_fd: + unlink_void(tfile) ; + return 0 ; +} + +int resolve_add_cdb(cdbmaker *c, char const *key, char const *data) +{ + log_flow() ; + + size_t klen = strlen(key) ; + size_t dlen = strlen(data) ; + + if (!cdbmake_add(c,key,klen,dlen ? data : 0,dlen)) + log_warnsys_return(LOG_EXIT_ZERO,"cdb_make_add: ",key) ; + + return 1 ; +} + +int resolve_add_cdb_uint(cdbmaker *c, char const *key, uint32_t data) +{ + log_flow() ; + + char pack[4] ; + size_t klen = strlen(key) ; + + uint32_pack_big(pack, data) ; + if (!cdbmake_add(c,key,klen,pack,4)) + log_warnsys_return(LOG_EXIT_ZERO,"cdb_make_add: ",key) ; + + return 1 ; +} + +int resolve_find_cdb(stralloc *result, cdb const *c, char const *key) +{ + log_flow() ; + + uint32_t x = 0 ; + size_t klen = strlen(key) ; + cdb_data cdata ; + + result->len = 0 ; + + int r = cdb_find(c, &cdata, key, klen) ; + if (r == -1) + log_warnusys_return(LOG_EXIT_LESSONE,"search on cdb key: ",key) ; + + if (!r) + log_warnusys_return(LOG_EXIT_ZERO,"unknown cdb key: ",key) ; + + char pack[cdata.len + 1] ; + memcpy(pack,cdata.s, cdata.len) ; + pack[cdata.len] = 0 ; + + uint32_unpack_big(pack, &x) ; + + if (!auto_stra(result,pack)) + log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ; + + return x ; +} + + diff --git a/src/lib66/service.c b/src/lib66/service.c new file mode 100644 index 0000000000000000000000000000000000000000..73fe1d2dc93b2b1daf7a6e244964641ee2bcf51e --- /dev/null +++ b/src/lib66/service.c @@ -0,0 +1,1869 @@ +/* + * 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 <unistd.h>//getuid +#include <sys/stat.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/types.h> +#include <oblibs/sastr.h> +#include <oblibs/files.h> + +#include <skalibs/djbunix.h>//openreadnclose +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/cdb.h> +#include <skalibs/cdbmake.h> +#include <skalibs/types.h> + +#include <66/utils.h> +#include <66/parser.h> +#include <66/enum.h> +#include <66/constants.h> +#include <66/resolve.h> +#include <66/ssexec.h> +#include <66/service.h> +#include <66/state.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(SERVICE_STRUCT, &res) ; + size_t newlen = 0, pos = 0 ; + int e = -1 ; + 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) ; + + if (resolve_check(trees, sv)) { + + if (!resolve_read(wres, trees, sv)) { + + log_warnu("read resolve file: ", trees, "/", sv) ; + goto freed ; + } + + if (res.disen) { + + log_trace(sv, " enabled at tree: ", treename) ; + + e = 1 ; + goto freed ; + + } else { + + e = 2 ; + goto freed ; + } + } + } + empty: + e = 0 ; + freed: + stralloc_free(&sa) ; + resolve_free(wres) ; + return e ; +} + +/** @Return 0 if not found + * @Return 1 if found + * @Return 2 if found but marked disabled + * @Return -1 system error */ +int service_isenabledat(stralloc *tree, char const *sv) +{ + + log_flow() ; + + stralloc sa = STRALLOC_ZERO ; + resolve_service_t res = RESOLVE_SERVICE_ZERO ; + resolve_wrapper_t_ref wres = resolve_set_struct(SERVICE_STRUCT, &res) ; + size_t newlen = 0, pos = 0 ; + int e = -1 ; + 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) ; + + if (resolve_check(trees, sv)) { + + if (!resolve_read(wres, trees, sv)) { + + log_warnu("read resolve file: ", trees, "/", sv) ; + goto freed ; + } + + if (res.disen) { + + log_trace(sv, " enabled at tree: ", treename) ; + e = 1 ; + + } else { + + log_trace(sv, " disabled at tree: ", treename) ; + e = 2 ; + } + + if (!auto_stra(tree, treename)) { + e = -1 ; + goto freed ; + } + goto freed ; + } + } + empty: + e = 0 ; + freed: + stralloc_free(&sa) ; + resolve_free(wres) ; + return e ; +} + +int service_frontend_src(stralloc *sasrc, char const *name, char const *src) +{ + log_flow() ; + + int insta, equal = 0, e = -1, r = 0, found = 0 ; + stralloc tmp = STRALLOC_ZERO ; + stralloc sort = STRALLOC_ZERO ; + size_t pos = 0, dpos = 0 ; + + char const *exclude[1] = { 0 } ; + + if (!sastr_dir_get_recursive(&sort, src, exclude, S_IFREG|S_IFDIR, 1)) + goto err ; + + + FOREACH_SASTR(&sort, pos) { + + char *dname = sort.s + pos ; + + struct stat st ; + /** use stat instead of lstat to accept symlink */ + if (stat(dname,&st) == -1) + goto err ; + + size_t dnamelen = strlen(dname) ; + char bname[dnamelen + 1] ; + + if (!ob_basename(bname,dname)) + goto err ; + + equal = strcmp(name, bname) ; + + insta = instance_check(bname) ; + + if (insta > 0) { + + if (!instance_splitname(&tmp, bname, insta, SS_INSTANCE_TEMPLATE)) + goto err ; + + equal = strcmp(tmp.s,bname) ; + } + + if (!equal) { + + found = 1 ; + + if (S_ISREG(st.st_mode)) { + + if (sastr_cmp(sasrc, dname) == -1) + if (!sastr_add_string(sasrc, dname)) + goto err ; + + break ; + + } else if (S_ISDIR(st.st_mode)) { + + if (!insta) { + log_warn("invalid name format for: ", dname," -- directory instance name are case reserved") ; + goto err ; + } + + int rd = service_endof_dir(dname, bname) ; + if (rd == -1) + goto err ; + + if (!rd) { + /** user ask to deal which each frontend file + * inside the directory */ + tmp.len = 0 ; + + if (!sastr_dir_get_recursive(&tmp, dname, exclude, S_IFREG|S_IFDIR, 0)) + goto err ; + + /** directory may be empty. */ + if (!tmp.len) + found = 0 ; + + dpos = 0 ; + FOREACH_SASTR(&tmp, dpos) { + + r = service_frontend_src(sasrc, tmp.s + dpos, dname) ; + if (r < 0) + /** system error */ + goto err ; + if (!r) + /** nothing found on empty sub-directory */ + found = 0 ; + } + + break ; + + } + } + } + } + + e = found ; + + err: + stralloc_free(&tmp) ; + stralloc_free(&sort) ; + return e ; +} + +int service_frontend_path(stralloc *sasrc,char const *sv, uid_t owner,char const *directory_forced) +{ + log_flow() ; + + int r ; + char const *src = 0 ; + int err = -1 ; + stralloc home = STRALLOC_ZERO ; + if (directory_forced) + { + if (!service_cmp_basedir(directory_forced)) { log_warn("invalid base service directory: ",directory_forced) ; goto err ; } + src = directory_forced ; + r = service_frontend_src(sasrc,sv,src) ; + if (r == -1){ log_warnusys("parse source directory: ",src) ; goto err ; } + if (!r) { log_warnu("find service: ",sv) ; err = 0 ; goto err ; } + } + else + { + if (!owner) src = SS_SERVICE_ADMDIR ; + else + { + if (!set_ownerhome(&home,owner)) { log_warnusys("set home directory") ; goto err ; } + if (!stralloc_cats(&home,SS_SERVICE_USERDIR)) { log_warnsys("stralloc") ; goto err ; } + if (!stralloc_0(&home)) { log_warnsys("stralloc") ; goto err ; } + home.len-- ; + src = home.s ; + } + + r = service_frontend_src(sasrc,sv,src) ; + if (r == -1){ log_warnusys("parse source directory: ",src) ; goto err ; } + if (!r) + { + src = SS_SERVICE_ADMDIR ; + r = service_frontend_src(sasrc,sv,src) ; + if (r == -1) { log_warnusys("parse source directory: ",src) ; goto err ; } + if (!r) + { + src = SS_SERVICE_SYSDIR ; + r = service_frontend_src(sasrc,sv,src) ; + if (r == -1) { log_warnusys("parse source directory: ",src) ; goto err ; } + if (!r) { log_warnu("find service: ",sv) ; err = 0 ; goto err ; } + } + } + } + stralloc_free(&home) ; + return 1 ; + err: + stralloc_free(&home) ; + return err ; +} + +int service_endof_dir(char const *dir, char const *name) +{ + log_flow() ; + + size_t dirlen = strlen(dir) ; + size_t namelen = strlen(name) ; + char t[dirlen + 1 + namelen + 1] ; + auto_strings(t, dir, "/", name) ; + + int r = scan_mode(t,S_IFREG) ; + + if (!ob_basename(t,dir)) + return -1 ; + + if (!strcmp(t,name) && (r > 0)) + return 1 ; + + return 0 ; +} + +int service_cmp_basedir(char const *dir) +{ + log_flow() ; + + /** dir can be 0, so nothing to do */ + if (!dir) return 1 ; + size_t len = strlen(dir) ; + uid_t owner = MYUID ; + stralloc home = STRALLOC_ZERO ; + + char system[len + 1] ; + char adm[len + 1] ; + char user[len + 1] ; + + if (owner) + { + if (!set_ownerhome(&home,owner)) { log_warnusys("set home directory") ; goto err ; } + if (!auto_stra(&home,SS_SERVICE_USERDIR)) { log_warnsys("stralloc") ; goto err ; } + auto_strings(user,dir) ; + user[strlen(home.s)] = 0 ; + } + + if (len < strlen(SS_SERVICE_SYSDIR)) + if (len < strlen(SS_SERVICE_ADMDIR)) + if (owner) { + if (len < strlen(home.s)) + goto err ; + } else goto err ; + + auto_strings(system,dir) ; + auto_strings(adm,dir) ; + + system[strlen(SS_SERVICE_SYSDIR)] = 0 ; + adm[strlen(SS_SERVICE_ADMDIR)] = 0 ; + + if (strcmp(SS_SERVICE_SYSDIR,system)) + if (strcmp(SS_SERVICE_ADMDIR,adm)) + if (owner) { + if (strcmp(home.s,user)) + goto err ; + } else goto err ; + + stralloc_free(&home) ; + return 1 ; + err: + stralloc_free(&home) ; + return 0 ; +} + +/** + * + * RESOLVE API + * + * */ + +resolve_service_field_table_t resolve_service_field_table[] = { + + [SERVICE_ENUM_NAME] = { .field = "name" }, + [SERVICE_ENUM_DESCRIPTION] = { .field = "description" }, + [SERVICE_ENUM_VERSION] = { .field = "version" }, + [SERVICE_ENUM_LOGGER] = { .field = "logger" }, + [SERVICE_ENUM_LOGREAL] = { .field = "logreal" }, + [SERVICE_ENUM_LOGASSOC] = { .field = "logassoc" }, + [SERVICE_ENUM_DSTLOG] = { .field = "dstlog" }, + [SERVICE_ENUM_DEPS] = { .field = "deps" }, + [SERVICE_ENUM_OPTSDEPS] = { .field = "optsdeps" }, + [SERVICE_ENUM_EXTDEPS] = { .field = "extdeps" }, + [SERVICE_ENUM_CONTENTS] = { .field = "contents" }, + [SERVICE_ENUM_SRC] = { .field = "src" }, + [SERVICE_ENUM_SRCONF] = { .field = "srconf" }, + [SERVICE_ENUM_LIVE] = { .field = "live" }, + [SERVICE_ENUM_RUNAT] = { .field = "runat" }, + [SERVICE_ENUM_TREE] = { .field = "tree" }, + [SERVICE_ENUM_TREENAME] = { .field = "treename" }, + [SERVICE_ENUM_STATE] = { .field = "state" }, + [SERVICE_ENUM_EXEC_RUN] = { .field = "exec_run" }, + [SERVICE_ENUM_EXEC_LOG_RUN] = { .field = "exec_log_run" }, + [SERVICE_ENUM_REAL_EXEC_RUN] = { .field = "real_exec_run" }, + [SERVICE_ENUM_REAL_EXEC_LOG_RUN] = { .field = "real_exec_log_run" }, + [SERVICE_ENUM_EXEC_FINISH] = { .field = "exec_finish" }, + [SERVICE_ENUM_REAL_EXEC_FINISH] = { .field = "real_exec_finish" }, + [SERVICE_ENUM_TYPE] = { .field = "type" }, + [SERVICE_ENUM_NDEPS] = { .field = "ndeps" }, + [SERVICE_ENUM_NOPTSDEPS] = { .field = "noptsdeps" }, + [SERVICE_ENUM_NEXTDEPS] = { .field = "nextdeps" }, + [SERVICE_ENUM_NCONTENTS] = { .field = "ncontents" }, + [SERVICE_ENUM_DOWN] = { .field = "down" }, + [SERVICE_ENUM_DISEN] = { .field = "disen" }, + [SERVICE_ENUM_ENDOFKEY] = { .field = 0 } +} ; + +int service_read_cdb(cdb *c, resolve_service_t *res) +{ + log_flow() ; + + stralloc tmp = STRALLOC_ZERO ; + resolve_wrapper_t_ref wres ; + uint32_t x ; + + wres = resolve_set_struct(SERVICE_STRUCT, res) ; + + /* name */ + resolve_find_cdb(&tmp,c,"name") ; + res->name = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* description */ + resolve_find_cdb(&tmp,c,"description") ; + res->description = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* version */ + resolve_find_cdb(&tmp,c,"version") ; + res->version = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* logger */ + resolve_find_cdb(&tmp,c,"logger") ; + res->logger = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* logreal */ + resolve_find_cdb(&tmp,c,"logreal") ; + res->logreal = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* logassoc */ + resolve_find_cdb(&tmp,c,"logassoc") ; + res->logassoc = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* dstlog */ + resolve_find_cdb(&tmp,c,"dstlog") ; + res->dstlog = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* deps */ + resolve_find_cdb(&tmp,c,"deps") ; + res->deps = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* optsdeps */ + resolve_find_cdb(&tmp,c,"optsdeps") ; + res->optsdeps = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* extdeps */ + resolve_find_cdb(&tmp,c,"extdeps") ; + res->extdeps = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* contents */ + resolve_find_cdb(&tmp,c,"contents") ; + res->contents = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* src */ + resolve_find_cdb(&tmp,c,"src") ; + res->src = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* srconf */ + resolve_find_cdb(&tmp,c,"srconf") ; + res->srconf = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* live */ + resolve_find_cdb(&tmp,c,"live") ; + res->live = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* runat */ + resolve_find_cdb(&tmp,c,"runat") ; + res->runat = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* tree */ + resolve_find_cdb(&tmp,c,"tree") ; + res->tree = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* treename */ + resolve_find_cdb(&tmp,c,"treename") ; + res->treename = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* state */ + resolve_find_cdb(&tmp,c,"state") ; + res->state = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* exec_run */ + resolve_find_cdb(&tmp,c,"exec_run") ; + res->exec_run = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* exec_log_run */ + resolve_find_cdb(&tmp,c,"exec_log_run") ; + res->exec_log_run = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* real_exec_run */ + resolve_find_cdb(&tmp,c,"real_exec_run") ; + res->real_exec_run = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* real_exec_log_run */ + resolve_find_cdb(&tmp,c,"real_exec_log_run") ; + res->real_exec_log_run = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* exec_finish */ + resolve_find_cdb(&tmp,c,"exec_finish") ; + res->exec_finish = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* real_exec_finish */ + resolve_find_cdb(&tmp,c,"real_exec_finish") ; + res->real_exec_finish = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ; + + /* type */ + x = resolve_find_cdb(&tmp,c,"type") ; + res->type = x ; + + /* ndeps */ + x = resolve_find_cdb(&tmp,c,"ndeps") ; + res->ndeps = x ; + + /* noptsdeps */ + x = resolve_find_cdb(&tmp,c,"noptsdeps") ; + res->noptsdeps = x ; + + /* nextdeps */ + x = resolve_find_cdb(&tmp,c,"nextdeps") ; + res->nextdeps = x ; + + /* ncontents */ + x = resolve_find_cdb(&tmp,c,"ncontents") ; + res->ncontents = x ; + + /* down */ + x = resolve_find_cdb(&tmp,c,"down") ; + res->down = x ; + + /* disen */ + x = resolve_find_cdb(&tmp,c,"disen") ; + res->disen = x ; + + free(wres) ; + stralloc_free(&tmp) ; + + return 1 ; +} + +int service_write_cdb(cdbmaker *c, resolve_service_t *sres) +{ + + log_flow() ; + + char *str = sres->sa.s ; + + /* name */ + if (!resolve_add_cdb(c,"name",str + sres->name) || + + /* description */ + !resolve_add_cdb(c,"description",str + sres->description) || + + /* version */ + !resolve_add_cdb(c,"version",str + sres->version) || + + /* logger */ + !resolve_add_cdb(c,"logger",str + sres->logger) || + + /* logreal */ + !resolve_add_cdb(c,"logreal",str + sres->logreal) || + + /* logassoc */ + !resolve_add_cdb(c,"logassoc",str + sres->logassoc) || + + /* dstlog */ + !resolve_add_cdb(c,"dstlog",str + sres->dstlog) || + + /* deps */ + !resolve_add_cdb(c,"deps",str + sres->deps) || + + /* optsdeps */ + !resolve_add_cdb(c,"optsdeps",str + sres->optsdeps) || + + /* extdeps */ + !resolve_add_cdb(c,"extdeps",str + sres->extdeps) || + + /* contents */ + !resolve_add_cdb(c,"contents",str + sres->contents) || + + /* src */ + !resolve_add_cdb(c,"src",str + sres->src) || + + /* srconf */ + !resolve_add_cdb(c,"srconf",str + sres->srconf) || + + /* live */ + !resolve_add_cdb(c,"live",str + sres->live) || + + /* runat */ + !resolve_add_cdb(c,"runat",str + sres->runat) || + + /* tree */ + !resolve_add_cdb(c,"tree",str + sres->tree) || + + /* treename */ + !resolve_add_cdb(c,"treename",str + sres->treename) || + + /* dstlog */ + !resolve_add_cdb(c,"dstlog",str + sres->dstlog) || + + /* state */ + !resolve_add_cdb(c,"state",str + sres->state) || + + /* exec_run */ + !resolve_add_cdb(c,"exec_run",str + sres->exec_run) || + + /* exec_log_run */ + !resolve_add_cdb(c,"exec_log_run",str + sres->exec_log_run) || + + /* real_exec_run */ + !resolve_add_cdb(c,"real_exec_run",str + sres->real_exec_run) || + + /* real_exec_log_run */ + !resolve_add_cdb(c,"real_exec_log_run",str + sres->real_exec_log_run) || + + /* exec_finish */ + !resolve_add_cdb(c,"exec_finish",str + sres->exec_finish) || + + /* real_exec_finish */ + !resolve_add_cdb(c,"real_exec_finish",str + sres->real_exec_finish) || + + /* type */ + !resolve_add_cdb_uint(c,"type",sres->type) || + + /* ndeps */ + !resolve_add_cdb_uint(c,"ndeps",sres->ndeps) || + + /* noptsdeps */ + !resolve_add_cdb_uint(c,"noptsdeps",sres->noptsdeps) || + + /* nextdeps */ + !resolve_add_cdb_uint(c,"nextdeps",sres->nextdeps) || + + /* ncontents */ + !resolve_add_cdb_uint(c,"ncontents",sres->ncontents) || + + /* down */ + !resolve_add_cdb_uint(c,"down",sres->down) || + + /* disen */ + !resolve_add_cdb_uint(c,"disen",sres->disen)) return 0 ; + + return 1 ; +} + +int service_resolve_copy(resolve_service_t *dst, resolve_service_t *res) +{ + log_flow() ; + + stralloc_free(&dst->sa) ; + + size_t len = res->sa.len - 1 ; + dst->salen = res->salen ; + + if (!stralloc_catb(&dst->sa,res->sa.s,len) || + !stralloc_0(&dst->sa)) + return 0 ; + + dst->name = res->name ; + dst->description = res->description ; + dst->version = res->version ; + dst->logger = res->logger ; + dst->logreal = res->logreal ; + dst->logassoc = res->logassoc ; + dst->dstlog = res->dstlog ; + dst->deps = res->deps ; + dst->optsdeps = res->optsdeps ; + dst->extdeps = res->extdeps ; + dst->contents = res->contents ; + dst->src = res->src ; + dst->srconf = res->srconf ; + dst->live = res->live ; + dst->runat = res->runat ; + dst->tree = res->tree ; + dst->treename = res->treename ; + dst->state = res->state ; + dst->exec_run = res->exec_run ; + dst->exec_log_run = res->exec_log_run ; + dst->real_exec_run = res->real_exec_run ; + dst->real_exec_log_run = res->real_exec_log_run ; + dst->exec_finish = res->exec_finish ; + dst->real_exec_finish = res->real_exec_finish ; + dst->type = res->type ; + dst->ndeps = res->ndeps ; + dst->noptsdeps = res->noptsdeps ; + dst->nextdeps = res->nextdeps ; + dst->ncontents = res->ncontents ; + dst->down = res->down ; + dst->disen = res->disen ; + + return 1 ; +} + +int service_resolve_sort_bytype(genalloc *gares, stralloc *list, char const *src) +{ + log_flow() ; + + size_t pos = 0 ; + int e = 0 ; + + resolve_service_t res = RESOLVE_SERVICE_ZERO ; + + resolve_wrapper_t_ref wres = resolve_set_struct(SERVICE_STRUCT, &res) ; + + size_t classic_list = 0, module_list = 0 ; + + FOREACH_SASTR(list, pos) { + + char *name = list->s + pos ; + + resolve_service_t cp = RESOLVE_SERVICE_ZERO ; + + if (!resolve_read(wres, src, name)) + log_warnu_return(LOG_EXIT_ZERO,"read resolve file of: ", src, name) ; + + if (!service_resolve_copy(&cp, &res)) + goto err ; + + switch (res.type) { + + case TYPE_CLASSIC: + + if (!genalloc_insertb(resolve_service_t, gares, 0, &cp, 1)) + goto err ; + + classic_list++ ; + module_list = classic_list ; + + break ; + + case TYPE_MODULE: + + if (!genalloc_insertb(resolve_service_t, gares, classic_list, &cp, 1)) + goto err ; + + module_list++ ; + + break ; + + case TYPE_BUNDLE: + case TYPE_LONGRUN: + case TYPE_ONESHOT: + + if (!genalloc_insertb(resolve_service_t, gares, module_list, &cp, 1)) + goto err ; + + break ; + + default: log_warn_return(LOG_EXIT_ZERO,"unknown action") ; + } + } + + e = 1 ; + + err: + resolve_free(wres) ; + return e ; +} + +/** @Return -1 system error + * @Return 0 no tree exist yet + * @Return 1 svname doesn't exist + * @Return 2 on success + * @Return > 2, service exist on different tree */ +int service_resolve_svtree(stralloc *svtree, char const *svname, char const *tree) +{ + log_flow() ; + + uint8_t found = 1, copied = 0 ; + uid_t owner = getuid() ; + size_t pos = 0, newlen ; + stralloc satree = STRALLOC_ZERO ; + stralloc tmp = STRALLOC_ZERO ; + char const *exclude[3] = { SS_BACKUP + 1, SS_RESOLVE + 1, 0 } ; + + if (!set_ownersysdir(svtree,owner)) { log_warnusys("set owner directory") ; goto err ; } + if (!auto_stra(svtree,SS_SYSTEM)) goto err ; + + if (!scan_mode(svtree->s,S_IFDIR)) + { + found = 0 ; + goto freed ; + } + + if (!auto_stra(svtree,"/")) goto err ; + newlen = svtree->len ; + + if (!stralloc_copy(&tmp,svtree)) goto err ; + + if (!sastr_dir_get(&satree, svtree->s, exclude, S_IFDIR)) { + log_warnu("get list of trees from directory: ",svtree->s) ; + goto err ; + } + + if (satree.len) + { + + FOREACH_SASTR(&satree, pos) { + + tmp.len = newlen ; + char *name = satree.s + pos ; + + if (!auto_stra(&tmp,name,SS_SVDIRS)) goto err ; + if (resolve_check(tmp.s,svname)) { + + if (!tree || (tree && !strcmp(name,tree))){ + svtree->len = 0 ; + if (!stralloc_copy(svtree,&tmp)) goto err ; + copied = 1 ; + } + found++ ; + } + } + } + else + { + found = 0 ; + goto freed ; + } + + if (found > 2 && tree) found = 2 ; + if (!copied) found = 1 ; + if (!stralloc_0(svtree)) goto err ; + freed: + stralloc_free(&satree) ; + stralloc_free(&tmp) ; + return found ; + err: + stralloc_free(&satree) ; + stralloc_free(&tmp) ; + return -1 ; +} + +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(SERVICE_STRUCT, &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.ndeps = 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.ndeps) + { + id = services->cname.idga, nid = res.ndeps ; + 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.deps = 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.deps = resolve_add_string(wres,ndeps.s) ; + + if (res.type == TYPE_CLASSIC) { + + res.ndeps = 1 ; + + } else if (res.type == TYPE_LONGRUN) { + + res.ndeps += 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 ; +} + +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(SERVICE_STRUCT, &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,descrip) ; + 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 ; +} + +int service_resolve_modify_field(resolve_service_t *res, resolve_service_enum_t field, char const *data) +{ + log_flow() ; + + uint32_t ifield ; + int e = 0 ; + + resolve_wrapper_t_ref wres = resolve_set_struct(SERVICE_STRUCT, res) ; + + switch(field) { + + case SERVICE_ENUM_NAME: + res->name = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_DESCRIPTION: + res->description = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_VERSION: + res->version = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_LOGGER: + res->logger = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_LOGREAL: + res->logreal = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_LOGASSOC: + res->logassoc = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_DSTLOG: + res->dstlog = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_DEPS: + res->deps = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_OPTSDEPS: + res->optsdeps = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_EXTDEPS: + res->extdeps = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_CONTENTS: + res->contents = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_SRC: + res->src = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_SRCONF: + res->srconf = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_LIVE: + res->live = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_RUNAT: + res->runat = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_TREE: + res->tree = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_TREENAME: + res->treename = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_STATE: + res->state = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_EXEC_RUN: + res->exec_run = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_EXEC_LOG_RUN: + res->exec_log_run = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_REAL_EXEC_RUN: + res->real_exec_run = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_REAL_EXEC_LOG_RUN: + res->real_exec_log_run = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_EXEC_FINISH: + res->exec_finish = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_REAL_EXEC_FINISH: + res->real_exec_finish = resolve_add_string(wres,data) ; + break ; + + case SERVICE_ENUM_TYPE: + if (!uint0_scan(data, &ifield)) goto err ; + res->type = ifield ; + break ; + + case SERVICE_ENUM_NDEPS: + if (!uint0_scan(data, &ifield)) goto err ; + res->ndeps = ifield ; + break ; + + case SERVICE_ENUM_NOPTSDEPS: + if (!uint0_scan(data, &ifield)) goto err ; + res->noptsdeps = ifield ; + break ; + + case SERVICE_ENUM_NEXTDEPS: + if (!uint0_scan(data, &ifield)) goto err ; + res->nextdeps = ifield ; + break ; + + case SERVICE_ENUM_NCONTENTS: + if (!uint0_scan(data, &ifield)) goto err ; + res->ncontents = ifield ; + break ; + + case SERVICE_ENUM_DOWN: + if (!uint0_scan(data, &ifield)) goto err ; + res->down = ifield ; + break ; + + case SERVICE_ENUM_DISEN: + if (!uint0_scan(data, &ifield)) goto err ; + res->disen = ifield ; + break ; + + default: + break ; + } + + e = 1 ; + + err: + free(wres) ; + return e ; + +} + +int service_resolve_field_to_sa(stralloc *sa, resolve_service_t *res, resolve_service_enum_t field) +{ + log_flow() ; + + uint32_t ifield ; + + switch(field) { + + case SERVICE_ENUM_NAME: + ifield = res->name ; + break ; + + case SERVICE_ENUM_DESCRIPTION: + ifield = res->description ; + break ; + + case SERVICE_ENUM_VERSION: + ifield = res->version ; + break ; + + case SERVICE_ENUM_LOGGER: + ifield = res->logger ; + break ; + + case SERVICE_ENUM_LOGREAL: + ifield = res->logreal ; + break ; + + case SERVICE_ENUM_LOGASSOC: + ifield = res->logassoc ; + break ; + + case SERVICE_ENUM_DSTLOG: + ifield = res->dstlog ; + break ; + + case SERVICE_ENUM_DEPS: + ifield = res->deps ; + break ; + + case SERVICE_ENUM_OPTSDEPS: + ifield = res->optsdeps ; + break ; + + case SERVICE_ENUM_EXTDEPS: + ifield = res->extdeps ; + break ; + + case SERVICE_ENUM_CONTENTS: + ifield = res->contents ; + break ; + + case SERVICE_ENUM_SRC: + ifield = res->src ; + break ; + + case SERVICE_ENUM_SRCONF: + ifield = res->srconf ; + break ; + + case SERVICE_ENUM_LIVE: + ifield = res->live ; + break ; + + case SERVICE_ENUM_RUNAT: + ifield = res->runat ; + break ; + + case SERVICE_ENUM_TREE: + ifield = res->tree ; + break ; + + case SERVICE_ENUM_TREENAME: + ifield = res->treename ; + break ; + + case SERVICE_ENUM_STATE: + ifield = res->state ; + break ; + + case SERVICE_ENUM_EXEC_RUN: + ifield = res->exec_run ; + break ; + + case SERVICE_ENUM_EXEC_LOG_RUN: + ifield = res->exec_log_run ; + break ; + + case SERVICE_ENUM_REAL_EXEC_RUN: + ifield = res->real_exec_run ; + break ; + + case SERVICE_ENUM_REAL_EXEC_LOG_RUN: + ifield = res->real_exec_log_run ; + break ; + + case SERVICE_ENUM_EXEC_FINISH: + ifield = res->exec_finish ; + break ; + + case SERVICE_ENUM_REAL_EXEC_FINISH: + ifield = res->real_exec_finish ; + break ; + + case SERVICE_ENUM_TYPE: + ifield = res->type ; + break ; + + case SERVICE_ENUM_NDEPS: + ifield = res->ndeps ; + break ; + + case SERVICE_ENUM_NOPTSDEPS: + ifield = res->noptsdeps ; + break ; + + case SERVICE_ENUM_NEXTDEPS: + ifield = res->nextdeps ; + break ; + + case SERVICE_ENUM_NCONTENTS: + ifield = res->ncontents ; + break ; + + case SERVICE_ENUM_DOWN: + ifield = res->down ; + break ; + + case SERVICE_ENUM_DISEN: + ifield = res->disen ; + break ; + + default: + return 0 ; + } + + if (!auto_stra(sa,res->sa.s + ifield)) + return 0 ; + + return 1 ; +} + +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(SERVICE_STRUCT, res) ; + + char *name = res->sa.s + res->name ; + char *deps = res->sa.s + res->deps ; + if (!resolve_cmp(tokeep, name, SERVICE_STRUCT) && (!obstr_equal(name,SS_MASTER+1))) + if (!resolve_append(tokeep,wres)) goto err ; + + if (res->ndeps) + { + 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(SERVICE_STRUCT, &dres) ; + char *dname = tmp.s + pos ; + if (!resolve_check(src,dname)) goto err ; + if (!resolve_read(dwres,src,dname)) goto err ; + if (dres.ndeps && !resolve_cmp(tokeep, dname, SERVICE_STRUCT)) + { + if (!service_resolve_add_deps(tokeep,&dres,src)) goto err ; + } + if (!resolve_cmp(tokeep, dname, SERVICE_STRUCT)) + { + 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(SERVICE_STRUCT, 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, SERVICE_STRUCT) && (!obstr_equal(name,SS_MASTER+1))) + { + if (!resolve_append(tokeep,wres)) goto err ; + } + if ((res->type == TYPE_BUNDLE || res->type == TYPE_MODULE) && res->ndeps) + { + uint32_t deps = res->type == TYPE_MODULE ? res->contents : res->deps ; + 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(SERVICE_STRUCT, &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, SERVICE_STRUCT)) + { + 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(SERVICE_STRUCT, &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.ndeps){ resolve_free(dwres) ; continue ; } + + if (!resolve_cmp(tokeep, dname, SERVICE_STRUCT)) + { + if (dres.ndeps)// || (dres.type == TYPE_BUNDLE && dres.ndeps) || ) + { + if (!sastr_clean_string(&tmp,dres.sa.s + dres.deps)) 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(SERVICE_STRUCT, &res) ; + resolve_service_t dres = RESOLVE_SERVICE_ZERO ; + resolve_wrapper_t_ref dwres = resolve_set_struct(SERVICE_STRUCT, &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, SERVICE_STRUCT)) + { + 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, SERVICE_STRUCT)) + if (!resolve_append(&gatmp,dwres)) goto err ; + } + } + resolve_free(wres) ; + resolve_free(dwres) ; + } + resolve_deep_free(SERVICE_STRUCT, ga) ; + if (!genalloc_copy(resolve_service_t,ga,&gatmp)) goto err ; + + e = 1 ; + + err: + genalloc_free(resolve_service_t,&gatmp) ; + resolve_deep_free(SERVICE_STRUCT, &gatmp) ; + return e ; +} + +int service_resolve_write_master(ssexec_t *info, ss_resolve_graph_t *graph,char const *dir, unsigned int reverse) +{ + log_flow() ; + + int r, e = 0 ; + size_t i = 0 ; + char ownerstr[UID_FMT] ; + size_t ownerlen = uid_fmt(ownerstr,info->owner) ; + ownerstr[ownerlen] = 0 ; + + stralloc in = STRALLOC_ZERO ; + stralloc inres = STRALLOC_ZERO ; + stralloc gain = STRALLOC_ZERO ; + resolve_service_t res = RESOLVE_SERVICE_ZERO ; + resolve_wrapper_t_ref wres = resolve_set_struct(SERVICE_STRUCT, &res) ; + + size_t dirlen = strlen(dir) ; + + resolve_init(wres) ; + + char runat[info->livetree.len + 1 + info->treename.len + SS_SVDIRS_LEN + SS_MASTER_LEN + 1] ; + auto_strings(runat, info->livetree.s, "/", info->treename.s, SS_SVDIRS, SS_MASTER) ; + + char dst[dirlen + SS_DB_LEN + SS_SRC_LEN + SS_MASTER_LEN + 1] ; + auto_strings(dst, dir, SS_DB, SS_SRC, SS_MASTER) ; + + size_t livelen = info->live.len - 1 ; + char state[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1] ; + auto_strings(state, info->live.s, SS_STATE, "/", ownerstr, "/", info->treename.s) ; + + if (reverse) + { + size_t dstlen = strlen(dst) ; + char file[dstlen + 1 + SS_CONTENTS_LEN + 1] ; + auto_strings(file, dst, "/", SS_CONTENTS) ; + + size_t filesize=file_get_size(file) ; + + r = openreadfileclose(file,&gain,filesize) ; + if(!r) goto err ; + /** ensure that we have an empty line at the end of the string*/ + if (!auto_stra(&gain,"\n")) goto err ; + if (!sastr_clean_element(&gain)) goto err ; + } + + for (; i < genalloc_len(resolve_service_t,&graph->sorted); i++) + { + char *string = genalloc_s(resolve_service_t,&graph->sorted)[i].sa.s ; + char *name = string + genalloc_s(resolve_service_t,&graph->sorted)[i].name ; + if (reverse) + if (sastr_cmp(&gain,name) == -1) continue ; + + if (!stralloc_cats(&in,name)) goto err ; + if (!stralloc_cats(&in,"\n")) goto err ; + + if (!stralloc_cats(&inres,name)) goto err ; + if (!stralloc_cats(&inres," ")) goto err ; + } + + if (inres.len) inres.len--; + if (!stralloc_0(&inres)) goto err ; + + r = file_write_unsafe(dst,SS_CONTENTS,in.s,in.len) ; + if (!r) + { + log_warnusys("write: ",dst,"contents") ; + goto err ; + } + + res.name = resolve_add_string(wres,SS_MASTER+1) ; + res.description = resolve_add_string(wres,"inner bundle - do not use it") ; + res.treename = resolve_add_string(wres,info->treename.s) ; + res.tree = resolve_add_string(wres,info->tree.s) ; + res.live = resolve_add_string(wres,info->live.s) ; + res.type = TYPE_BUNDLE ; + res.deps = resolve_add_string(wres,inres.s) ; + res.ndeps = genalloc_len(resolve_service_t,&graph->sorted) ; + res.runat = resolve_add_string(wres,runat) ; + res.state = resolve_add_string(wres,state) ; + + if (!resolve_write(wres,dir,SS_MASTER+1)) goto err ; + + e = 1 ; + + err: + resolve_free(wres) ; + stralloc_free(&in) ; + stralloc_free(&inres) ; + stralloc_free(&gain) ; + return e ; +} + diff --git a/src/lib66/ss_resolve.c b/src/lib66/ss_resolve.c deleted file mode 100644 index 12afd2db895f5755e7b3f95124ad2d0920d198fe..0000000000000000000000000000000000000000 --- a/src/lib66/ss_resolve.c +++ /dev/null @@ -1,2120 +0,0 @@ -/* - * ss_resolve.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 <sys/stat.h> -#include <stdint.h> -#include <stdlib.h>//realpath -#include <sys/types.h> -#include <stdio.h> //rename - -#include <oblibs/types.h> -#include <oblibs/log.h> -#include <oblibs/directory.h> -#include <oblibs/files.h> -#include <oblibs/string.h> -#include <oblibs/sastr.h> - -#include <skalibs/stralloc.h> -#include <skalibs/djbunix.h> -#include <skalibs/direntry.h> -#include <skalibs/unix-transactional.h> -#include <skalibs/diuint32.h> -#include <skalibs/cdbmake.h> -#include <skalibs/cdb.h> -#include <skalibs/posixplz.h>//unlink_void - -#include <66/constants.h> -#include <66/utils.h> -#include <66/enum.h> -#include <66/parser.h>//resolve need to find stralloc keep -#include <66/resolve.h> -#include <66/ssexec.h> -#include <66/state.h> - -#include <s6/supervise.h> - -ss_resolve_field_table_t ss_resolve_field_table[] = { - - [SS_RESOLVE_ENUM_NAME] = { .field = "name" }, - [SS_RESOLVE_ENUM_DESCRIPTION] = { .field = "description" }, - [SS_RESOLVE_ENUM_VERSION] = { .field = "version" }, - [SS_RESOLVE_ENUM_LOGGER] = { .field = "logger" }, - [SS_RESOLVE_ENUM_LOGREAL] = { .field = "logreal" }, - [SS_RESOLVE_ENUM_LOGASSOC] = { .field = "logassoc" }, - [SS_RESOLVE_ENUM_DSTLOG] = { .field = "dstlog" }, - [SS_RESOLVE_ENUM_DEPS] = { .field = "deps" }, - [SS_RESOLVE_ENUM_OPTSDEPS] = { .field = "optsdeps" }, - [SS_RESOLVE_ENUM_EXTDEPS] = { .field = "extdeps" }, - [SS_RESOLVE_ENUM_CONTENTS] = { .field = "contents" }, - [SS_RESOLVE_ENUM_SRC] = { .field = "src" }, - [SS_RESOLVE_ENUM_SRCONF] = { .field = "srconf" }, - [SS_RESOLVE_ENUM_LIVE] = { .field = "live" }, - [SS_RESOLVE_ENUM_RUNAT] = { .field = "runat" }, - [SS_RESOLVE_ENUM_TREE] = { .field = "tree" }, - [SS_RESOLVE_ENUM_TREENAME] = { .field = "treename" }, - [SS_RESOLVE_ENUM_STATE] = { .field = "state" }, - [SS_RESOLVE_ENUM_EXEC_RUN] = { .field = "exec_run" }, - [SS_RESOLVE_ENUM_EXEC_LOG_RUN] = { .field = "exec_log_run" }, - [SS_RESOLVE_ENUM_REAL_EXEC_RUN] = { .field = "real_exec_run" }, - [SS_RESOLVE_ENUM_REAL_EXEC_LOG_RUN] = { .field = "real_exec_log_run" }, - [SS_RESOLVE_ENUM_EXEC_FINISH] = { .field = "exec_finish" }, - [SS_RESOLVE_ENUM_REAL_EXEC_FINISH] = { .field = "real_exec_finish" }, - [SS_RESOLVE_ENUM_TYPE] = { .field = "type" }, - [SS_RESOLVE_ENUM_NDEPS] = { .field = "ndeps" }, - [SS_RESOLVE_ENUM_NOPTSDEPS] = { .field = "noptsdeps" }, - [SS_RESOLVE_ENUM_NEXTDEPS] = { .field = "nextdeps" }, - [SS_RESOLVE_ENUM_NCONTENTS] = { .field = "ncontents" }, - [SS_RESOLVE_ENUM_DOWN] = { .field = "down" }, - [SS_RESOLVE_ENUM_DISEN] = { .field = "disen" }, - [SS_RESOLVE_ENUM_ENDOFKEY] = { .field = 0 } -} ; - -void ss_resolve_free(ss_resolve_t *res) -{ - log_flow() ; - - stralloc_free(&res->sa) ; -} - -void ss_resolve_init(ss_resolve_t *res) -{ - log_flow() ; - - res->sa.len = 0 ; - ss_resolve_add_string(res,"") ; -} - -int ss_resolve_pointo(stralloc *sa,ssexec_t *info,int type, unsigned int where) -{ - log_flow() ; - - sa->len = 0 ; - - char ownerstr[UID_FMT] ; - size_t ownerlen = uid_fmt(ownerstr,info->owner) ; - ownerstr[ownerlen] = 0 ; - - if (where == SS_RESOLVE_STATE) { - - if (!auto_stra(sa, info->live.s, SS_STATE + 1, "/", ownerstr, "/", info->treename.s)) - goto err ; - - } else if (where == SS_RESOLVE_SRC) { - - if (!auto_stra(sa, info->tree.s, SS_SVDIRS)) - goto err ; - - } else if (where == SS_RESOLVE_BACK) { - - if (!auto_stra(sa, info->base.s, SS_SYSTEM, SS_BACKUP, "/", info->treename.s)) - goto err ; - - } else if (where == SS_RESOLVE_LIVE) { - - if (!auto_stra(sa, info->live.s, SS_STATE + 1, "/", ownerstr, "/", info->treename.s, SS_SVDIRS)) - goto err ; - } - - if (type >= 0 && where) { - - if (type == TYPE_CLASSIC) { - - if (!auto_stra(sa, SS_SVC)) - goto err ; - - } else if (!auto_stra(sa, SS_DB)) - goto err ; - } - - return 1 ; - - err: - return 0 ; -} - -/* @sdir -> service dir - * @mdir -> module dir */ -int ss_resolve_module_path(stralloc *sdir, stralloc *mdir, char const *sv,char const *frontend_src, uid_t owner) -{ - log_flow() ; - - int r, insta ; - stralloc sainsta = STRALLOC_ZERO ; - stralloc mhome = STRALLOC_ZERO ; // module user dir - stralloc shome = STRALLOC_ZERO ; // service user dir - char const *src = 0 ; - char const *dest = 0 ; - - insta = instance_check(sv) ; - instance_splitname(&sainsta,sv,insta,SS_INSTANCE_TEMPLATE) ; - - if (!owner) - { - src = SS_MODULE_ADMDIR ; - dest = frontend_src ; - } - else - { - if (!set_ownerhome(&mhome,owner)) log_warnusys_return(LOG_EXIT_ZERO,"set home directory") ; - if (!stralloc_cats(&mhome,SS_MODULE_USERDIR)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_0(&mhome)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - mhome.len-- ; - src = mhome.s ; - - if (!set_ownerhome(&shome,owner)) log_warnusys_return(LOG_EXIT_ZERO,"set home directory") ; - if (!stralloc_cats(&shome,SS_SERVICE_USERDIR)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_0(&shome)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - shome.len-- ; - dest = shome.s ; - - } - if (!auto_stra(mdir,src,sainsta.s)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - r = scan_mode(mdir->s,S_IFDIR) ; - if (!r || r == -1) - { - mdir->len = 0 ; - src = SS_MODULE_ADMDIR ; - if (!auto_stra(mdir,src,sainsta.s)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - r = scan_mode(mdir->s,S_IFDIR) ; - if (!r || r == -1) - { - mdir->len = 0 ; - src = SS_MODULE_SYSDIR ; - if (!auto_stra(mdir,src,sainsta.s)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - r = scan_mode(mdir->s,S_IFDIR) ; - if (!r || r == -1) log_warnu_return(LOG_EXIT_ZERO,"find module: ",sv) ; - } - - } - if (!auto_stra(sdir,dest,sv)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - stralloc_free(&sainsta) ; - stralloc_free(&mhome) ; - stralloc_free(&shome) ; - return 1 ; -} - -int ss_resolve_src_path(stralloc *sasrc,char const *sv, uid_t owner,char const *directory_forced) -{ - log_flow() ; - - int r ; - char const *src = 0 ; - int found = 0, err = -1 ; - stralloc home = STRALLOC_ZERO ; - if (directory_forced) - { - if (!ss_resolve_cmp_service_basedir(directory_forced)) { log_warn("invalid base service directory: ",directory_forced) ; goto err ; } - src = directory_forced ; - r = ss_resolve_src(sasrc,sv,src,&found) ; - if (r == -1){ log_warnusys("parse source directory: ",src) ; goto err ; } - if (!r) { log_warnu("find service: ",sv) ; err = 0 ; goto err ; } - } - else - { - if (!owner) src = SS_SERVICE_ADMDIR ; - else - { - if (!set_ownerhome(&home,owner)) { log_warnusys("set home directory") ; goto err ; } - if (!stralloc_cats(&home,SS_SERVICE_USERDIR)) { log_warnsys("stralloc") ; goto err ; } - if (!stralloc_0(&home)) { log_warnsys("stralloc") ; goto err ; } - home.len-- ; - src = home.s ; - } - - r = ss_resolve_src(sasrc,sv,src,&found) ; - if (r == -1){ log_warnusys("parse source directory: ",src) ; goto err ; } - if (!r) - { - found = 0 ; - src = SS_SERVICE_ADMDIR ; - r = ss_resolve_src(sasrc,sv,src,&found) ; - if (r == -1) { log_warnusys("parse source directory: ",src) ; goto err ; } - if (!r) - { - found = 0 ; - src = SS_SERVICE_SYSDIR ; - r = ss_resolve_src(sasrc,sv,src,&found) ; - if (r == -1) { log_warnusys("parse source directory: ",src) ; goto err ; } - if (!r) { log_warnu("find service: ",sv) ; err = 0 ; goto err ; } - } - } - } - stralloc_free(&home) ; - return 1 ; - err: - stralloc_free(&home) ; - return err ; -} - -int ss_resolve_src(stralloc *sasrc, char const *name, char const *src,int *found) -{ - log_flow() ; - - int r, obr, insta ; - size_t i, len, namelen = strlen(name), srclen = strlen(src), pos = 0 ; - stralloc sainsta = STRALLOC_ZERO ; - stralloc satmp = STRALLOC_ZERO ; - stralloc sort = STRALLOC_ZERO ; - char const *exclude[1] = { 0 } ; - - if (!ss_resolve_sort_byfile_first(&sort,src)) - { - log_warnu("sort directory: ",src) ; - goto err ; - } - - for (; pos < sort.len ; pos += strlen(sort.s + pos) + 1) - { - char *dname = sort.s + pos ; - size_t dnamelen = strlen(dname) ; - char bname[dnamelen + 1] ; - - if (!ob_basename(bname,dname)) goto err ; - - if (scan_mode(dname,S_IFDIR) > 0) - { - *found = ss_resolve_src(sasrc,name,dname,found) ; - if (*found < 0) goto err ; - } - obr = 0 ; - insta = 0 ; - obr = obstr_equal(name,bname) ; - insta = instance_check(name) ; - - if (insta > 0) - { - if (!instance_splitname(&sainsta,name,insta,SS_INSTANCE_TEMPLATE)) goto err ; - obr = obstr_equal(sainsta.s,bname) ; - } - - if (obr) - { - *found = 1 ; - if (scan_mode(dname,S_IFDIR) > 0) - { - int rd = ss_resolve_service_isdir(dname,bname) ; - if (rd == -1) goto err ; - if (!rd) - r = sastr_dir_get(&satmp,dname,exclude,S_IFREG|S_IFDIR) ; - else r = sastr_dir_get(&satmp,dname,exclude,S_IFREG) ; - if (!r) - { - log_warnusys("get services from directory: ",dname) ; - goto err ; - } - i = 0, len = satmp.len ; - - for (;i < len; i += strlen(satmp.s + i) + 1) - { - size_t tlen = strlen(satmp.s+i) ; - char t[dnamelen + 1 + tlen + 2]; - - auto_strings(t,dname,"/",satmp.s + i,"/") ; - - r = scan_mode(t,S_IFDIR) ; - if (r == 1) - { - t[dnamelen + 1] = 0 ; - *found = ss_resolve_src(sasrc,satmp.s+i,t,found) ; - if (*found < 0) goto err ; - } - else - { - char t[dnamelen + tlen + 1] ; - auto_strings(t,dname,satmp.s + i) ; - if (sastr_cmp(sasrc,t) == -1) - { - if (!stralloc_cats(sasrc,dname)) goto err ; - if (!stralloc_catb(sasrc,satmp.s+i,tlen+1)) goto err ; - } - } - } - break ; - } - else if (scan_mode(dname,S_IFREG) > 0) - { - char t[srclen + namelen + 1] ; - auto_strings(t,src,name) ; - if (sastr_cmp(sasrc,t) == -1) - { - if (!stralloc_cats(sasrc,src)) goto err ; - if (!stralloc_catb(sasrc,name,namelen+1)) goto err ; - } - break ; - } - else goto err ; - } - } - - stralloc_free(&sainsta) ; - stralloc_free(&satmp) ; - stralloc_free(&sort) ; - - return (*found) ; - - err: - stralloc_free(&sainsta) ; - stralloc_free(&satmp) ; - stralloc_free(&sort) ; - return -1 ; -} - -void ss_resolve_rmfile(char const *src,char const *name) -{ - log_flow() ; - - size_t srclen = strlen(src) ; - size_t namelen = strlen(name) ; - - char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen +1] ; - memcpy(tmp,src,srclen) ; - memcpy(tmp + srclen, SS_RESOLVE,SS_RESOLVE_LEN) ; - tmp[srclen + SS_RESOLVE_LEN] = '/' ; - memcpy(tmp + srclen + SS_RESOLVE_LEN + 1, name, namelen) ; - tmp[srclen + SS_RESOLVE_LEN + 1 + namelen] = 0 ; - - unlink_void(tmp) ; -} - -ssize_t ss_resolve_add_string(ss_resolve_t *res, char const *data) -{ - log_flow() ; - - ssize_t baselen = res->sa.len ; - if (!data) - { - if (!stralloc_catb(&res->sa,"",1)) log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ; - return baselen ; - } - size_t datalen = strlen(data) ; - if (!stralloc_catb(&res->sa,data,datalen + 1)) log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ; - return baselen ; -} - -int ss_resolve_write(ss_resolve_t *res, char const *dst, char const *name) -{ - log_flow() ; - - size_t dstlen = strlen(dst) ; - size_t namelen = strlen(name) ; - - char tmp[dstlen + SS_RESOLVE_LEN + 1 + namelen + 1] ; - auto_strings(tmp,dst,SS_RESOLVE,"/") ; - - if (!ss_resolve_write_cdb(res,tmp,name)) return 0 ; - - return 1 ; -} - -int ss_resolve_read(ss_resolve_t *res, char const *src, char const *name) -{ - log_flow() ; - - size_t srclen = strlen(src) ; - size_t namelen = strlen(name) ; - - char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen + 1] ; - auto_strings(tmp,src,SS_RESOLVE,"/",name) ; - - if (!ss_resolve_read_cdb(res,tmp)) return 0 ; - - return 1 ; -} - -/** not used - * - * - * - * - * -int ss_resolve_check_insrc(ssexec_t *info, char const *name) -{ - log_flow() ; - - stralloc sares = STRALLOC_ZERO ; - if (!ss_resolve_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_SRC)) goto err ; - if (!ss_resolve_check(sares.s,name)) goto err ; - stralloc_free(&sares) ; - return 1 ; - err: - stralloc_free(&sares) ; - return 0 ; -} -* -* -*/ - -int ss_resolve_check(char const *src, char const *name) -{ - log_flow() ; - - int r ; - size_t srclen = strlen(src) ; - size_t namelen = strlen(name) ; - char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen + 1] ; - memcpy(tmp,src,srclen) ; - memcpy(tmp + srclen, SS_RESOLVE,SS_RESOLVE_LEN) ; - tmp[srclen + SS_RESOLVE_LEN] = '/' ; - memcpy(tmp + srclen + SS_RESOLVE_LEN + 1,name,namelen) ; - tmp[srclen + SS_RESOLVE_LEN + 1 + namelen] = 0 ; - r = scan_mode(tmp,S_IFREG) ; - if (!r || r < 0) return 0 ; - return 1 ; -} - -int ss_resolve_setnwrite(sv_alltype *services, ssexec_t *info, char const *dst) -{ - log_flow() ; - - 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 ; - ss_resolve_t res = RESOLVE_ZERO ; - ss_resolve_init(&res) ; - - 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] ; - memcpy(state,info->live.s,livelen) ; - memcpy(state + livelen, SS_STATE,SS_STATE_LEN) ; - state[livelen+ SS_STATE_LEN] = '/' ; - memcpy(state + livelen + SS_STATE_LEN + 1,ownerstr,ownerlen) ; - state[livelen + SS_STATE_LEN + 1 + ownerlen] = '/' ; - memcpy(state + livelen + SS_STATE_LEN + 1 + ownerlen + 1,info->treename.s,info->treename.len) ; - state[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len] = 0 ; - - res.type = services->cname.itype ; - res.name = ss_resolve_add_string(&res,name) ; - res.description = ss_resolve_add_string(&res,keep.s + services->cname.description) ; - res.version = ss_resolve_add_string(&res,keep.s + services->cname.version) ; - res.tree = ss_resolve_add_string(&res,info->tree.s) ; - res.treename = ss_resolve_add_string(&res,info->treename.s) ; - res.live = ss_resolve_add_string(&res,info->live.s) ; - res.state = ss_resolve_add_string(&res,state) ; - res.src = ss_resolve_add_string(&res,keep.s + services->src) ; - if (services->srconf > 0) - res.srconf = ss_resolve_add_string(&res,keep.s + services->srconf) ; - - if (res.type == TYPE_ONESHOT) - { - if (services->type.oneshot.up.exec >= 0) - { - res.exec_run = ss_resolve_add_string(&res,keep.s + services->type.oneshot.up.exec) ; - res.real_exec_run = ss_resolve_add_string(&res,keep.s + services->type.oneshot.up.real_exec) ; - } - if (services->type.oneshot.down.exec >= 0) - { - res.exec_finish = ss_resolve_add_string(&res,keep.s + services->type.oneshot.down.exec) ; - res.real_exec_finish = ss_resolve_add_string(&res,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 = ss_resolve_add_string(&res,keep.s + services->type.classic_longrun.run.exec) ; - res.real_exec_run = ss_resolve_add_string(&res,keep.s + services->type.classic_longrun.run.real_exec) ; - } - if (services->type.classic_longrun.finish.exec >= 0) - { - res.exec_finish = ss_resolve_add_string(&res,keep.s + services->type.classic_longrun.finish.exec) ; - res.real_exec_finish = ss_resolve_add_string(&res,keep.s + services->type.classic_longrun.finish.real_exec) ; - } - } - - res.ndeps = 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) - { - memcpy(stmp,info->scandir.s,info->scandir.len) ; - stmp[info->scandir.len] = '/' ; - memcpy(stmp + info->scandir.len + 1,name,namelen) ; - stmp[info->scandir.len + 1 + namelen] = 0 ; - res.runat = ss_resolve_add_string(&res,stmp) ; - } - else if (res.type >= TYPE_BUNDLE) - { - memcpy(stmp,info->livetree.s,info->livetree.len) ; - stmp[info->livetree.len] = '/' ; - memcpy(stmp + info->livetree.len + 1,info->treename.s,info->treename.len) ; - memcpy(stmp + info->livetree.len + 1 + info->treename.len, SS_SVDIRS,SS_SVDIRS_LEN) ; - stmp[info->livetree.len + 1 + info->treename.len + SS_SVDIRS_LEN] = '/' ; - memcpy(stmp + info->livetree.len + 1 + info->treename.len + SS_SVDIRS_LEN + 1, name,namelen) ; - stmp[info->livetree.len + 1 + info->treename.len + SS_SVDIRS_LEN + 1 + namelen] = 0 ; - res.runat = ss_resolve_add_string(&res,stmp) ; - } - - if (ss_state_check(state,name)) - { - if (!ss_state_read(&sta,state,name)) { log_warnusys("read state file of: ",name) ; goto err ; } - if (!sta.init) - ss_state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_TRUE) ; - if (sta.init) { - ss_state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_TRUE) ; - } else { - ss_state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_FALSE) ; - } - ss_state_setflag(&sta,SS_FLAGS_UNSUPERVISE,SS_FLAGS_FALSE) ; - if (!ss_state_write(&sta,res.sa.s + res.state,name)){ log_warnusys("write state file of: ",name) ; goto err ; } - } - - if (res.ndeps) - { - id = services->cname.idga, nid = res.ndeps ; - 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_return(LOG_EXIT_ZERO,"stralloc") ; - } - ndeps.len-- ; - if (!stralloc_0(&ndeps)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - res.deps = ss_resolve_add_string(&res,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_return(LOG_EXIT_ZERO,"stralloc") ; - } - other_deps.len-- ; - if (!stralloc_0(&other_deps)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - res.optsdeps = ss_resolve_add_string(&res,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_return(LOG_EXIT_ZERO,"stralloc") ; - } - other_deps.len-- ; - if (!stralloc_0(&other_deps)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - res.extdeps = ss_resolve_add_string(&res,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_return(LOG_EXIT_ZERO,"stralloc") ; - } - other_deps.len-- ; - if (!stralloc_0(&other_deps)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - res.contents = ss_resolve_add_string(&res,other_deps.s) ; - } - - if (services->opts[0]) - { - // destination of the logger - if (services->type.classic_longrun.log.destination < 0) - { - if(info->owner > 0) - { - if (!stralloc_cats(&destlog,get_userhome(info->owner))) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_cats(&destlog,"/")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_cats(&destlog,SS_LOGGER_USERDIR)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_cats(&destlog,name)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - else - { - if (!stralloc_cats(&destlog,SS_LOGGER_SYSDIR)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_cats(&destlog,name)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - } - else - { - if (!stralloc_cats(&destlog,keep.s+services->type.classic_longrun.log.destination)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - if (!stralloc_0(&destlog)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - res.dstlog = ss_resolve_add_string(&res,destlog.s) ; - - if ((res.type == TYPE_CLASSIC) || (res.type == TYPE_LONGRUN)) - { - memcpy(logname,name,namelen) ; - memcpy(logname + namelen,SS_LOG_SUFFIX,SS_LOG_SUFFIX_LEN) ; - logname[namelen + SS_LOG_SUFFIX_LEN] = 0 ; - - memcpy(logreal,name,namelen) ; - if (res.type == TYPE_CLASSIC) - { - memcpy(logreal + namelen,"/log",SS_LOG_SUFFIX_LEN) ; - } - else memcpy(logreal + namelen,"-log",SS_LOG_SUFFIX_LEN) ; - logreal[namelen + SS_LOG_SUFFIX_LEN] = 0 ; - - res.logger = ss_resolve_add_string(&res,logname) ; - res.logreal = ss_resolve_add_string(&res,logreal) ; - if (ndeps.len) ndeps.len--; - if (!stralloc_catb(&ndeps," ",1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_cats(&ndeps,res.sa.s + res.logger)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_0(&ndeps)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - res.deps = ss_resolve_add_string(&res,ndeps.s) ; - if (res.type == TYPE_CLASSIC) res.ndeps = 1 ; - else if (res.type == TYPE_LONGRUN) res.ndeps += 1 ; - - if (services->type.classic_longrun.log.run.exec >= 0) - res.exec_log_run = ss_resolve_add_string(&res,keep.s + services->type.classic_longrun.log.run.exec) ; - - if (services->type.classic_longrun.log.run.real_exec >= 0) - res.real_exec_log_run = ss_resolve_add_string(&res,keep.s + services->type.classic_longrun.log.run.real_exec) ; - - if (!ss_resolve_setlognwrite(&res,dst,info)) goto err ; - } - } - - if (!ss_resolve_write(&res,dst,res.sa.s + res.name)) - { - log_warnusys("write resolve file: ",dst,SS_RESOLVE,"/",res.sa.s + res.name) ; - goto err ; - } - - ss_resolve_free(&res) ; - stralloc_free(&ndeps) ; - stralloc_free(&other_deps) ; - stralloc_free(&destlog) ; - return 1 ; - - err: - ss_resolve_free(&res) ; - stralloc_free(&ndeps) ; - stralloc_free(&other_deps) ; - stralloc_free(&destlog) ; - return 0 ; -} - -int ss_resolve_setlognwrite(ss_resolve_t *sv, char const *dst,ssexec_t *info) -{ - log_flow() ; - - if (!sv->logger) return 1 ; - - ss_state_t sta = STATE_ZERO ; - ss_resolve_t res = RESOLVE_ZERO ; - ss_resolve_init(&res) ; - - char *string = sv->sa.s ; - size_t svlen = strlen(string + sv->name) ; - char descrip[svlen + 7 + 1] ; - memcpy(descrip,string + sv->name,svlen) ; - memcpy(descrip + svlen," logger",7) ; - descrip[svlen + 7] = 0 ; - - size_t runlen = strlen(string + sv->runat) ; - char live[runlen + 4 + 1] ; - memcpy(live,string + 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 = ss_resolve_add_string(&res,string + sv->logger) ; - res.description = ss_resolve_add_string(&res,descrip) ; - /*** temporary check here, version is not mandatory yet */ - if (sv->version > 0) - res.version = ss_resolve_add_string(&res,string + sv->version) ; - res.logreal = ss_resolve_add_string(&res,string + sv->logreal) ; - res.logassoc = ss_resolve_add_string(&res,string + sv->name) ; - res.dstlog = ss_resolve_add_string(&res,string + sv->dstlog) ; - res.live = ss_resolve_add_string(&res,string + sv->live) ; - res.runat = ss_resolve_add_string(&res,live) ; - res.tree = ss_resolve_add_string(&res,string + sv->tree) ; - res.treename = ss_resolve_add_string(&res,string + sv->treename) ; - res.state = ss_resolve_add_string(&res,string + sv->state) ; - res.src = ss_resolve_add_string(&res,string + sv->src) ; - res.down = sv->down ; - res.disen = sv->disen ; - if (sv->exec_log_run >= 0) - res.exec_log_run = ss_resolve_add_string(&res,string + sv->exec_log_run) ; - if (sv->real_exec_log_run >= 0) - res.real_exec_log_run = ss_resolve_add_string(&res,string + sv->real_exec_log_run) ; - - if (ss_state_check(string + sv->state,string + sv->logger)) - { - if (!ss_state_read(&sta,string + sv->state,string + sv->logger)) { log_warnusys("read state file of: ",string + sv->logger) ; goto err ; } - if (!sta.init) - ss_state_setflag(&sta,SS_FLAGS_RELOAD,SS_FLAGS_TRUE) ; - ss_state_setflag(&sta,SS_FLAGS_INIT,SS_FLAGS_FALSE) ; - ss_state_setflag(&sta,SS_FLAGS_UNSUPERVISE,SS_FLAGS_FALSE) ; - if (!ss_state_write(&sta,string + sv->state,string + sv->logger)){ log_warnusys("write state file of: ",string + sv->logger) ; goto err ; } - } - - if (!ss_resolve_write(&res,dst,res.sa.s + res.name)) - { - log_warnusys("write resolve file: ",dst,SS_RESOLVE,"/",res.sa.s + res.name) ; - goto err ; - } - ss_resolve_free(&res) ; - return 1 ; - err: - ss_resolve_free(&res) ; - return 0 ; -} - -int ss_resolve_cmp(genalloc *ga,char const *name) -{ - log_flow() ; - - unsigned int i = 0 ; - for (;i < genalloc_len(ss_resolve_t,ga) ; i++) - { - char *string = genalloc_s(ss_resolve_t,ga)[i].sa.s ; - char *s = string + genalloc_s(ss_resolve_t,ga)[i].name ; - if (!strcmp(name,s)) return 1 ; - } - return 0 ; -} - -int ss_resolve_copy(ss_resolve_t *dst,ss_resolve_t *res) -{ - log_flow() ; - - ss_resolve_free(dst) ; - size_t len = res->sa.len - 1 ; - dst->salen = res->salen ; - if (!stralloc_catb(&dst->sa,res->sa.s,len)) return 0 ; - dst->name = res->name ; - dst->description = res->description ; - dst->version = res->version ; - dst->logger = res->logger ; - dst->logreal = res->logreal ; - dst->logassoc = res->logassoc ; - dst->dstlog = res->dstlog ; - dst->deps = res->deps ; - dst->optsdeps = res->optsdeps ; - dst->extdeps = res->extdeps ; - dst->contents = res->contents ; - dst->src = res->src ; - dst->srconf = res->srconf ; - dst->live = res->live ; - dst->runat = res->runat ; - dst->tree = res->tree ; - dst->treename = res->treename ; - dst->state = res->state ; - dst->exec_run = res->exec_run ; - dst->exec_log_run = res->exec_log_run ; - dst->real_exec_run = res->real_exec_run ; - dst->real_exec_log_run = res->real_exec_log_run ; - dst->exec_finish = res->exec_finish ; - dst->real_exec_finish = res->real_exec_finish ; - dst->type = res->type ; - dst->ndeps = res->ndeps ; - dst->noptsdeps = res->noptsdeps ; - dst->nextdeps = res->nextdeps ; - dst->ncontents = res->ncontents ; - dst->down = res->down ; - dst->disen = res->disen ; - - if (!stralloc_0(&dst->sa)) return 0 ; - return 1 ; -} - -int ss_resolve_append(genalloc *ga,ss_resolve_t *res) -{ - log_flow() ; - - ss_resolve_t cp = RESOLVE_ZERO ; - if (!ss_resolve_copy(&cp,res)) goto err ; - if (!genalloc_append(ss_resolve_t,ga,&cp)) goto err ; - return 1 ; - err: - ss_resolve_free(&cp) ; - return 0 ; -} - -int ss_resolve_add_deps(genalloc *tokeep,ss_resolve_t *res, char const *src) -{ - log_flow() ; - - size_t pos = 0 ; - stralloc tmp = STRALLOC_ZERO ; - - char *name = res->sa.s + res->name ; - char *deps = res->sa.s + res->deps ; - if (!ss_resolve_cmp(tokeep,name) && (!obstr_equal(name,SS_MASTER+1))) - if (!ss_resolve_append(tokeep,res)) goto err ; - - if (res->ndeps) - { - if (!sastr_clean_string(&tmp,deps)) return 0 ; - for (;pos < tmp.len ; pos += strlen(tmp.s + pos) + 1) - { - ss_resolve_t dres = RESOLVE_ZERO ; - char *dname = tmp.s + pos ; - if (!ss_resolve_check(src,dname)) goto err ; - if (!ss_resolve_read(&dres,src,dname)) goto err ; - if (dres.ndeps && !ss_resolve_cmp(tokeep,dname)) - { - if (!ss_resolve_add_deps(tokeep,&dres,src)) goto err ; - } - if (!ss_resolve_cmp(tokeep,dname)) - { - if (!ss_resolve_append(tokeep,&dres)) goto err ; - } - ss_resolve_free(&dres) ; - } - } - stralloc_free(&tmp) ; - return 1 ; - err: - stralloc_free(&tmp) ; - return 0 ; -} - -int ss_resolve_add_rdeps(genalloc *tokeep, ss_resolve_t *res, char const *src) -{ - log_flow() ; - - int type ; - stralloc tmp = STRALLOC_ZERO ; - stralloc nsv = STRALLOC_ZERO ; - ss_state_t sta = STATE_ZERO ; - 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 (!ss_resolve_cmp(tokeep,name) && (!obstr_equal(name,SS_MASTER+1))) - { - if (!ss_resolve_append(tokeep,res)) goto err ; - } - if ((res->type == TYPE_BUNDLE || res->type == TYPE_MODULE) && res->ndeps) - { - uint32_t deps = res->type == TYPE_MODULE ? res->contents : res->deps ; - if (!sastr_clean_string(&tmp,res->sa.s + deps)) goto err ; - ss_resolve_t dres = RESOLVE_ZERO ; - for (; a < tmp.len ; a += strlen(tmp.s + a) + 1) - { - char *name = tmp.s + a ; - if (!ss_resolve_check(src,name)) goto err ; - if (!ss_resolve_read(&dres,src,name)) goto err ; - if (dres.type == TYPE_CLASSIC) continue ; - if (!ss_resolve_cmp(tokeep,name)) - { - if (!ss_resolve_append(tokeep,&dres)) goto err ; - if (!ss_resolve_add_rdeps(tokeep,&dres,src)) goto err ; - } - ss_resolve_free(&dres) ; - } - } - for (; b < nsv.len ; b += strlen(nsv.s + b) +1) - { - int dtype = 0 ; - tmp.len = 0 ; - ss_resolve_t dres = RESOLVE_ZERO ; - char *dname = nsv.s + b ; - if (obstr_equal(name,dname)) { ss_resolve_free(&dres) ; continue ; } - if (!ss_resolve_check(src,dname)) goto err ; - if (!ss_resolve_read(&dres,src,dname)) goto err ; - - if (dres.type == TYPE_CLASSIC) dtype = 0 ; - else dtype = 1 ; - - if (ss_state_check(dres.sa.s + dres.state,dname)) - { - if (!ss_state_read(&sta,dres.sa.s + dres.state,dname)) goto err ; - if (dtype != type || (!dres.disen && !sta.unsupervise)){ ss_resolve_free(&dres) ; continue ; } - } - else if (dtype != type || (!dres.disen)){ ss_resolve_free(&dres) ; continue ; } - if (dres.type == TYPE_BUNDLE && !dres.ndeps){ ss_resolve_free(&dres) ; continue ; } - - if (!ss_resolve_cmp(tokeep,dname)) - { - if (dres.ndeps)// || (dres.type == TYPE_BUNDLE && dres.ndeps) || ) - { - if (!sastr_clean_string(&tmp,dres.sa.s + dres.deps)) 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 (!ss_resolve_append(tokeep,&dres)) goto err ; - if (!ss_resolve_add_rdeps(tokeep,&dres,src)) goto err ; - ss_resolve_free(&dres) ; - break ; - } - } - } - } - skip: - ss_resolve_free(&dres) ; - } - - stralloc_free(&nsv) ; - stralloc_free(&tmp) ; - return 1 ; - err: - stralloc_free(&nsv) ; - stralloc_free(&tmp) ; - return 0 ; -} - -int ss_resolve_add_logger(genalloc *ga,char const *src) -{ - log_flow() ; - - size_t i = 0 ; - genalloc gatmp = GENALLOC_ZERO ; - - for (; i < genalloc_len(ss_resolve_t,ga) ; i++) - { - ss_resolve_t res = RESOLVE_ZERO ; - ss_resolve_t dres = RESOLVE_ZERO ; - if (!ss_resolve_copy(&res,&genalloc_s(ss_resolve_t,ga)[i])) goto err ; - - char *string = res.sa.s ; - char *name = string + res.name ; - if (!ss_resolve_cmp(&gatmp,name)) - { - if (!ss_resolve_append(&gatmp,&res)) - goto err ; - - if (res.logger) - { - if (!ss_resolve_check(src,string + res.logger)) goto err ; - if (!ss_resolve_read(&dres,src,string + res.logger)) - goto err ; - if (!ss_resolve_cmp(&gatmp,string + res.logger)) - if (!ss_resolve_append(&gatmp,&dres)) goto err ; - } - } - ss_resolve_free(&res) ; - ss_resolve_free(&dres) ; - } - genalloc_deepfree(ss_resolve_t,ga,ss_resolve_free) ; - if (!genalloc_copy(ss_resolve_t,ga,&gatmp)) goto err ; - - genalloc_free(ss_resolve_t,&gatmp) ; - return 1 ; - err: - genalloc_deepfree(ss_resolve_t,&gatmp,ss_resolve_free) ; - return 0 ; -} - -int ss_resolve_create_live(ssexec_t *info) -{ - log_flow() ; - - int r ; - gid_t gidowner ; - if (!yourgid(&gidowner,info->owner)) return 0 ; - stralloc sares = STRALLOC_ZERO ; - stralloc ressrc = STRALLOC_ZERO ; - - if (!ss_resolve_pointo(&ressrc,info,SS_NOTYPE,SS_RESOLVE_SRC)) goto err ; - - if (!ss_resolve_pointo(&sares,info,SS_NOTYPE,SS_RESOLVE_STATE)) goto err ; - r = scan_mode(sares.s,S_IFDIR) ; - if (r < 0) goto err ; - if (!r) - { - ssize_t len = get_rlen_until(sares.s,'/',sares.len) ; - sares.len-- ; - char sym[sares.len + SS_SVDIRS_LEN + 1] ; - memcpy(sym,sares.s,sares.len) ; - sym[sares.len] = 0 ; - - r = dir_create_parent(sym,0700) ; - if (!r) goto err ; - sym[len] = 0 ; - if (chown(sym,info->owner,gidowner) < 0) goto err ; - memcpy(sym,sares.s,sares.len) ; - memcpy(sym + sares.len, SS_SVDIRS, SS_SVDIRS_LEN) ; - sym[sares.len + SS_SVDIRS_LEN] = 0 ; - - log_trace("point symlink: ",sym," to ",ressrc.s) ; - if (symlink(ressrc.s,sym) < 0) - { - log_warnusys("symlink: ", sym) ; - goto err ; - } - } - /** live/state/uid/treename/init file */ - if (!file_write_unsafe(sares.s,"init","",0)) goto err ; - - stralloc_free(&ressrc) ; - stralloc_free(&sares) ; - - return 1 ; - err: - stralloc_free(&ressrc) ; - stralloc_free(&sares) ; - return 0 ; -} - -int ss_resolve_search(genalloc *ga,char const *name) -{ - log_flow() ; - - unsigned int i = 0 ; - for (; i < genalloc_len(ss_resolve_t,ga) ; i++) - { - char *s = genalloc_s(ss_resolve_t,ga)[i].sa.s + genalloc_s(ss_resolve_t,ga)[i].name ; - if (obstr_equal(name,s)) return i ; - } - return -1 ; -} - -int ss_resolve_write_master(ssexec_t *info,ss_resolve_graph_t *graph,char const *dir, unsigned int reverse) -{ - log_flow() ; - - int r ; - size_t i = 0 ; - char ownerstr[UID_FMT] ; - size_t ownerlen = uid_fmt(ownerstr,info->owner) ; - ownerstr[ownerlen] = 0 ; - - stralloc in = STRALLOC_ZERO ; - stralloc inres = STRALLOC_ZERO ; - stralloc gain = STRALLOC_ZERO ; - ss_resolve_t res = RESOLVE_ZERO ; - - size_t dirlen = strlen(dir) ; - - char runat[info->livetree.len + 1 + info->treename.len + SS_SVDIRS_LEN + SS_MASTER_LEN + 1] ; - memcpy(runat,info->livetree.s,info->livetree.len) ; - runat[info->livetree.len] = '/' ; - memcpy(runat + info->livetree.len + 1,info->treename.s,info->treename.len) ; - memcpy(runat + info->livetree.len + 1 + info->treename.len, SS_SVDIRS,SS_SVDIRS_LEN) ; - memcpy(runat + info->livetree.len + 1 + info->treename.len + SS_SVDIRS_LEN, SS_MASTER, SS_MASTER_LEN) ; - runat[info->livetree.len + 1 + info->treename.len + SS_SVDIRS_LEN + SS_MASTER_LEN] = 0 ; - - char dst[dirlen + SS_DB_LEN + SS_SRC_LEN + SS_MASTER_LEN + 1] ; - memcpy(dst, dir, dirlen) ; - memcpy(dst + dirlen, SS_DB, SS_DB_LEN) ; - memcpy(dst + dirlen + SS_DB_LEN, SS_SRC, SS_SRC_LEN) ; - memcpy(dst + dirlen + SS_DB_LEN + SS_SRC_LEN, SS_MASTER, SS_MASTER_LEN) ; - dst[dirlen + SS_DB_LEN + SS_SRC_LEN + SS_MASTER_LEN] = 0 ; - - size_t livelen = info->live.len - 1 ; - char state[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len + 1] ; - memcpy(state,info->live.s,livelen) ; - memcpy(state + livelen, SS_STATE,SS_STATE_LEN) ; - state[livelen+ SS_STATE_LEN] = '/' ; - memcpy(state + livelen + SS_STATE_LEN + 1,ownerstr,ownerlen) ; - state[livelen + SS_STATE_LEN + 1 + ownerlen] = '/' ; - memcpy(state + livelen + SS_STATE_LEN + 1 + ownerlen + 1,info->treename.s,info->treename.len) ; - state[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + info->treename.len] = 0 ; - - if (reverse) - { - size_t dstlen = strlen(dst) ; - char file[dstlen + 1 + SS_CONTENTS_LEN + 1] ; - memcpy(file,dst,dstlen) ; - file[dstlen] = '/' ; - memcpy(file + dstlen + 1, SS_CONTENTS,SS_CONTENTS_LEN) ; - file[dstlen + 1 + SS_CONTENTS_LEN] = 0 ; - size_t filesize=file_get_size(file) ; - - r = openreadfileclose(file,&gain,filesize) ; - if(!r) goto err ; - /** ensure that we have an empty line at the end of the string*/ - if (!stralloc_cats(&gain,"\n")) goto err ; - if (!stralloc_0(&gain)) goto err ; - if (!sastr_clean_element(&gain)) goto err ; - } - - for (; i < genalloc_len(ss_resolve_t,&graph->sorted); i++) - { - char *string = genalloc_s(ss_resolve_t,&graph->sorted)[i].sa.s ; - char *name = string + genalloc_s(ss_resolve_t,&graph->sorted)[i].name ; - if (reverse) - if (sastr_cmp(&gain,name) == -1) continue ; - - if (!stralloc_cats(&in,name)) goto err ; - if (!stralloc_cats(&in,"\n")) goto err ; - - if (!stralloc_cats(&inres,name)) goto err ; - if (!stralloc_cats(&inres," ")) goto err ; - } - - if (inres.len) inres.len--; - if (!stralloc_0(&inres)) goto err ; - - r = file_write_unsafe(dst,SS_CONTENTS,in.s,in.len) ; - if (!r) - { - log_warnusys("write: ",dst,"contents") ; - goto err ; - } - - ss_resolve_init(&res) ; - res.name = ss_resolve_add_string(&res,SS_MASTER+1) ; - res.description = ss_resolve_add_string(&res,"inner bundle - do not use it") ; - res.treename = ss_resolve_add_string(&res,info->treename.s) ; - res.tree = ss_resolve_add_string(&res,info->tree.s) ; - res.live = ss_resolve_add_string(&res,info->live.s) ; - res.type = TYPE_BUNDLE ; - res.deps = ss_resolve_add_string(&res,inres.s) ; - res.ndeps = genalloc_len(ss_resolve_t,&graph->sorted) ; - res.runat = ss_resolve_add_string(&res,runat) ; - res.state = ss_resolve_add_string(&res,state) ; - - if (!ss_resolve_write(&res,dir,SS_MASTER+1)) goto err ; - - stralloc_free(&in) ; - stralloc_free(&inres) ; - ss_resolve_free(&res) ; - stralloc_free(&gain) ; - return 1 ; - - err: - ss_resolve_free(&res) ; - stralloc_free(&in) ; - stralloc_free(&inres) ; - stralloc_free(&gain) ; - return 0 ; -} - -int ss_resolve_sort_bytype(genalloc *gares,stralloc *list,char const *src) -{ - log_flow() ; - - size_t pos = 0 ; - ss_resolve_t res = RESOLVE_ZERO ; - - /** search for classic first */ - for (pos = 0 ;pos < list->len; pos += strlen(list->s + pos) + 1) - { - char *name = list->s + pos ; - if (!ss_resolve_read(&res,src,name)) - log_warnu_return(LOG_EXIT_ZERO,"read resolve file of: ",name) ; - if (res.type == TYPE_CLASSIC) - if (ss_resolve_search(gares,name) == -1) - if (!ss_resolve_append(gares,&res)) - log_warnu_return(LOG_EXIT_ZERO,"append genalloc") ; - } - - /** second pass for module */ - for (pos = 0 ;pos < list->len; pos += strlen(list->s + pos) + 1) - { - char *name = list->s + pos ; - if (!ss_resolve_read(&res,src,name)) - log_warnu_return(LOG_EXIT_ZERO,"read resolve file of: ",name) ; - if (res.type == TYPE_MODULE) - if (ss_resolve_search(gares,name) == -1) - if (!ss_resolve_append(gares,&res)) - log_warnu_return(LOG_EXIT_ZERO,"append genalloc") ; - } - - /** finally add s6-rc services */ - for (pos = 0 ;pos < list->len; pos += strlen(list->s + pos) + 1) - { - char *name = list->s + pos ; - if (!ss_resolve_read(&res,src,name)) - log_warnu_return(LOG_EXIT_ZERO,"read resolve file of: ",name) ; - if (res.type != TYPE_CLASSIC && res.type != TYPE_MODULE) - if (ss_resolve_search(gares,name) == -1) - if (!ss_resolve_append(gares,&res)) - log_warnu_return(LOG_EXIT_ZERO,"append genalloc") ; - } - - ss_resolve_free(&res) ; - return 1 ; -} - -int ss_resolve_cmp_service_basedir(char const *dir) -{ - log_flow() ; - - /** dir can be 0, so nothing to do */ - if (!dir) return 1 ; - size_t len = strlen(dir) ; - uid_t owner = MYUID ; - stralloc home = STRALLOC_ZERO ; - - char system[len + 1] ; - char adm[len + 1] ; - char user[len + 1] ; - - if (owner) - { - if (!set_ownerhome(&home,owner)) { log_warnusys("set home directory") ; goto err ; } - if (!auto_stra(&home,SS_SERVICE_USERDIR)) { log_warnsys("stralloc") ; goto err ; } - auto_strings(user,dir) ; - user[strlen(home.s)] = 0 ; - } - - if (len < strlen(SS_SERVICE_SYSDIR)) - if (len < strlen(SS_SERVICE_ADMDIR)) - if (owner) { - if (len < strlen(home.s)) - goto err ; - } else goto err ; - - auto_strings(system,dir) ; - auto_strings(adm,dir) ; - - system[strlen(SS_SERVICE_SYSDIR)] = 0 ; - adm[strlen(SS_SERVICE_ADMDIR)] = 0 ; - - if (strcmp(SS_SERVICE_SYSDIR,system)) - if (strcmp(SS_SERVICE_ADMDIR,adm)) - if (owner) { - if (strcmp(home.s,user)) - goto err ; - } else goto err ; - - stralloc_free(&home) ; - return 1 ; - err: - stralloc_free(&home) ; - return 0 ; -} - -int ss_resolve_service_isdir(char const *dir, char const *name) -{ - log_flow() ; - - size_t dirlen = strlen(dir) ; - size_t namelen = strlen(name) ; - char t[dirlen + 1 + namelen + 1] ; - memcpy(t,dir,dirlen) ; - t[dirlen] = '/' ; - memcpy(t + dirlen + 1, name, namelen) ; - t[dirlen + 1 + namelen] = 0 ; - int r = scan_mode(t,S_IFREG) ; - if (!ob_basename(t,dir)) return -1 ; - if (!strcmp(t,name) && r) return 1 ; - return 0 ; -} - -int ss_resolve_sort_byfile_first(stralloc *sort, char const *src) -{ - log_flow() ; - - int fdsrc ; - stralloc tmp = STRALLOC_ZERO ; - - DIR *dir = opendir(src) ; - if (!dir) - { - log_warnusys("open : ", src) ; - goto errstra ; - } - fdsrc = dir_fd(dir) ; - - for (;;) - { - tmp.len = 0 ; - struct stat st ; - direntry *d ; - d = readdir(dir) ; - if (!d) break ; - if (d->d_name[0] == '.') - if (((d->d_name[1] == '.') && !d->d_name[2]) || !d->d_name[1]) - continue ; - - if (stat_at(fdsrc, d->d_name, &st) < 0) - { - log_warnusys("stat ", src, d->d_name) ; - goto errdir ; - } - - if (S_ISREG(st.st_mode)) - { - if (!auto_stra(&tmp,src,d->d_name)) goto errdir ; - if (!stralloc_insertb(sort,0,tmp.s,strlen(tmp.s) + 1)) goto errdir ; - } - else if(S_ISDIR(st.st_mode)) - { - if (!auto_stra(&tmp,src,d->d_name,"/")) goto errdir ; - if (!stralloc_insertb(sort,sort->len,tmp.s,strlen(tmp.s) + 1)) goto errdir ; - } - } - - dir_close(dir) ; - stralloc_free(&tmp) ; - - return 1 ; - - errdir: - dir_close(dir) ; - errstra: - stralloc_free(&tmp) ; - return 0 ; -} - -/** @Return -1 system error - * @Return 0 no tree exist yet - * @Return 1 svname doesn't exist - * @Return 2 on success - * @Return > 2, service exist on different tree */ -int ss_resolve_svtree(stralloc *svtree,char const *svname,char const *tree) -{ - log_flow() ; - - uint8_t found = 1, copied = 0 ; - uid_t owner = getuid() ; - size_t pos, newlen ; - stralloc satree = STRALLOC_ZERO ; - stralloc tmp = STRALLOC_ZERO ; - char const *exclude[3] = { SS_BACKUP + 1, SS_RESOLVE + 1, 0 } ; - - if (!set_ownersysdir(svtree,owner)) { log_warnusys("set owner directory") ; goto err ; } - if (!auto_stra(svtree,SS_SYSTEM)) goto err ; - - if (!scan_mode(svtree->s,S_IFDIR)) - { - found = 0 ; - goto freed ; - } - - if (!auto_stra(svtree,"/")) goto err ; - newlen = svtree->len ; - - if (!stralloc_copy(&tmp,svtree)) goto err ; - - if (!sastr_dir_get(&satree, svtree->s,exclude, S_IFDIR)) { - log_warnu("get list of trees from directory: ",svtree->s) ; - goto err ; - } - - if (satree.len) - { - for(pos = 0 ; pos < satree.len ; pos += strlen(satree.s + pos) + 1) - { - tmp.len = newlen ; - char *name = satree.s + pos ; - - if (!auto_stra(&tmp,name,SS_SVDIRS)) goto err ; - if (ss_resolve_check(tmp.s,svname)) - { - if (!tree || (tree && !strcmp(name,tree))){ - svtree->len = 0 ; - if (!stralloc_copy(svtree,&tmp)) goto err ; - copied = 1 ; - } - found++ ; - } - } - } - else - { - found = 0 ; - goto freed ; - } - - if (found > 2 && tree) found = 2 ; - if (!copied) found = 1 ; - if (!stralloc_0(svtree)) goto err ; - freed: - stralloc_free(&satree) ; - stralloc_free(&tmp) ; - return found ; - err: - stralloc_free(&satree) ; - stralloc_free(&tmp) ; - return -1 ; -} - -int ss_resolve_add_cdb_uint(cdbmaker *c, char const *key,uint32_t data) -{ - log_flow() ; - - char pack[4] ; - size_t klen = strlen(key) ; - - uint32_pack_big(pack, data) ; - if (!cdbmake_add(c,key,klen,pack,4)) - log_warnsys_return(LOG_EXIT_ZERO,"cdb_make_add: ",key) ; - - return 1 ; -} - -int ss_resolve_add_cdb(cdbmaker *c,char const *key,char const *data) -{ - log_flow() ; - - size_t klen = strlen(key) ; - size_t dlen = strlen(data) ; - - if (!cdbmake_add(c,key,klen,dlen ? data : 0,dlen)) - log_warnsys_return(LOG_EXIT_ZERO,"cdb_make_add: ",key) ; - - return 1 ; -} - -int ss_resolve_write_cdb(ss_resolve_t *res, char const *dst, char const *name) -{ - log_flow() ; - - int fd ; - size_t dstlen = strlen(dst), namelen = strlen(name); - cdbmaker c = CDBMAKER_ZERO ; - char tfile[dstlen + 1 + namelen + namelen + 9] ; - char dfile[dstlen + 1 + namelen + 1] ; - - char *str = res->sa.s ; - - auto_strings(dfile,dst,"/",name) ; - - auto_strings(tfile,dst,"/",name,":",name,":","XXXXXX") ; - - fd = mkstemp(tfile) ; - if (fd < 0 || ndelay_off(fd)) { - log_warnusys("mkstemp: ", tfile) ; - goto err_fd ; - } - - if (!cdbmake_start(&c, fd)) { - log_warnusys("cdbmake_start") ; - goto err ; - } - - /* name */ - if (!ss_resolve_add_cdb(&c,"name",str + res->name) || - - /* description */ - !ss_resolve_add_cdb(&c,"description",str + res->description) || - - /* version */ - !ss_resolve_add_cdb(&c,"version",str + res->version) || - - /* logger */ - !ss_resolve_add_cdb(&c,"logger",str + res->logger) || - - /* logreal */ - !ss_resolve_add_cdb(&c,"logreal",str + res->logreal) || - - /* logassoc */ - !ss_resolve_add_cdb(&c,"logassoc",str + res->logassoc) || - - /* dstlog */ - !ss_resolve_add_cdb(&c,"dstlog",str + res->dstlog) || - - /* deps */ - !ss_resolve_add_cdb(&c,"deps",str + res->deps) || - - /* optsdeps */ - !ss_resolve_add_cdb(&c,"optsdeps",str + res->optsdeps) || - - /* extdeps */ - !ss_resolve_add_cdb(&c,"extdeps",str + res->extdeps) || - - /* contents */ - !ss_resolve_add_cdb(&c,"contents",str + res->contents) || - - /* src */ - !ss_resolve_add_cdb(&c,"src",str + res->src) || - - /* srconf */ - !ss_resolve_add_cdb(&c,"srconf",str + res->srconf) || - - /* live */ - !ss_resolve_add_cdb(&c,"live",str + res->live) || - - /* runat */ - !ss_resolve_add_cdb(&c,"runat",str + res->runat) || - - /* tree */ - !ss_resolve_add_cdb(&c,"tree",str + res->tree) || - - /* treename */ - !ss_resolve_add_cdb(&c,"treename",str + res->treename) || - - /* dstlog */ - !ss_resolve_add_cdb(&c,"dstlog",str + res->dstlog) || - - /* state */ - !ss_resolve_add_cdb(&c,"state",str + res->state) || - - /* exec_run */ - !ss_resolve_add_cdb(&c,"exec_run",str + res->exec_run) || - - /* exec_log_run */ - !ss_resolve_add_cdb(&c,"exec_log_run",str + res->exec_log_run) || - - /* real_exec_run */ - !ss_resolve_add_cdb(&c,"real_exec_run",str + res->real_exec_run) || - - /* real_exec_log_run */ - !ss_resolve_add_cdb(&c,"real_exec_log_run",str + res->real_exec_log_run) || - - /* exec_finish */ - !ss_resolve_add_cdb(&c,"exec_finish",str + res->exec_finish) || - - /* real_exec_finish */ - !ss_resolve_add_cdb(&c,"real_exec_finish",str + res->real_exec_finish) || - - /* type */ - !ss_resolve_add_cdb_uint(&c,"type",res->type) || - - /* ndeps */ - !ss_resolve_add_cdb_uint(&c,"ndeps",res->ndeps) || - - /* noptsdeps */ - !ss_resolve_add_cdb_uint(&c,"noptsdeps",res->noptsdeps) || - - /* nextdeps */ - !ss_resolve_add_cdb_uint(&c,"nextdeps",res->nextdeps) || - - /* ncontents */ - !ss_resolve_add_cdb_uint(&c,"ncontents",res->ncontents) || - - /* down */ - !ss_resolve_add_cdb_uint(&c,"down",res->down) || - - /* disen */ - !ss_resolve_add_cdb_uint(&c,"disen",res->disen)) goto err ; - - if (!cdbmake_finish(&c) || fsync(fd) < 0) { - log_warnusys("write to: ", tfile) ; - goto err ; - } - - close(fd) ; - - if (rename(tfile, dfile) < 0) { - log_warnusys("rename ", tfile, " to ", dfile) ; - goto err_fd ; - } - - return 1 ; - - err: - close(fd) ; - err_fd: - unlink_void(tfile) ; - return 0 ; -} - -int ss_resolve_find_cdb(stralloc *result, cdb const *c,char const *key) -{ - log_flow() ; - - uint32_t x = 0 ; - size_t klen = strlen(key) ; - cdb_data cdata ; - - result->len = 0 ; - - int r = cdb_find(c, &cdata, key, klen) ; - if (r == -1) - log_warnusys_return(LOG_EXIT_LESSONE,"search on cdb key: ",key) ; - - if (!r) - log_warnusys_return(LOG_EXIT_ZERO,"unknown cdb key: ",key) ; - - char pack[cdata.len + 1] ; - memcpy(pack,cdata.s, cdata.len) ; - pack[cdata.len] = 0 ; - - uint32_unpack_big(pack, &x) ; - - if (!auto_stra(result,pack)) - log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ; - - return x ; - -} - -int ss_resolve_read_cdb(ss_resolve_t *dres, char const *name) -{ - log_flow() ; - - int fd ; - uint32_t x ; - - cdb c = CDB_ZERO ; - stralloc tmp = STRALLOC_ZERO ; - ss_resolve_t res = RESOLVE_ZERO ; - - fd = open_readb(name) ; - if (fd < 0) { - log_warnusys("open: ",name) ; - goto err_fd ; - } - if (!cdb_init_fromfd(&c, fd)) { - log_warnusys("cdb_init: ", name) ; - goto err ; - } - - ss_resolve_init(&res) ; - - /* name */ - ss_resolve_find_cdb(&tmp,&c,"name") ; - res.name = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* description */ - ss_resolve_find_cdb(&tmp,&c,"description") ; - res.description = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* version */ - ss_resolve_find_cdb(&tmp,&c,"version") ; - res.version = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* logger */ - ss_resolve_find_cdb(&tmp,&c,"logger") ; - res.logger = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* logreal */ - ss_resolve_find_cdb(&tmp,&c,"logreal") ; - res.logreal = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* logassoc */ - ss_resolve_find_cdb(&tmp,&c,"logassoc") ; - res.logassoc = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* dstlog */ - ss_resolve_find_cdb(&tmp,&c,"dstlog") ; - res.dstlog = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* deps */ - ss_resolve_find_cdb(&tmp,&c,"deps") ; - res.deps = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* optsdeps */ - ss_resolve_find_cdb(&tmp,&c,"optsdeps") ; - res.optsdeps = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* extdeps */ - ss_resolve_find_cdb(&tmp,&c,"extdeps") ; - res.extdeps = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* contents */ - ss_resolve_find_cdb(&tmp,&c,"contents") ; - res.contents = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* src */ - ss_resolve_find_cdb(&tmp,&c,"src") ; - res.src = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* srconf */ - ss_resolve_find_cdb(&tmp,&c,"srconf") ; - res.srconf = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* live */ - ss_resolve_find_cdb(&tmp,&c,"live") ; - res.live = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* runat */ - ss_resolve_find_cdb(&tmp,&c,"runat") ; - res.runat = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* tree */ - ss_resolve_find_cdb(&tmp,&c,"tree") ; - res.tree = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* treename */ - ss_resolve_find_cdb(&tmp,&c,"treename") ; - res.treename = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* state */ - ss_resolve_find_cdb(&tmp,&c,"state") ; - res.state = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* exec_run */ - ss_resolve_find_cdb(&tmp,&c,"exec_run") ; - res.exec_run = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* exec_log_run */ - ss_resolve_find_cdb(&tmp,&c,"exec_log_run") ; - res.exec_log_run = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* real_exec_run */ - ss_resolve_find_cdb(&tmp,&c,"real_exec_run") ; - res.real_exec_run = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* real_exec_log_run */ - ss_resolve_find_cdb(&tmp,&c,"real_exec_log_run") ; - res.real_exec_log_run = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* exec_finish */ - ss_resolve_find_cdb(&tmp,&c,"exec_finish") ; - res.exec_finish = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* real_exec_finish */ - ss_resolve_find_cdb(&tmp,&c,"real_exec_finish") ; - res.real_exec_finish = tmp.len ? ss_resolve_add_string(&res,tmp.s) : 0 ; - - /* type */ - x = ss_resolve_find_cdb(&tmp,&c,"type") ; - res.type = x ; - - /* ndeps */ - x = ss_resolve_find_cdb(&tmp,&c,"ndeps") ; - res.ndeps = x ; - - /* noptsdeps */ - x = ss_resolve_find_cdb(&tmp,&c,"noptsdeps") ; - res.noptsdeps = x ; - - /* nextdeps */ - x = ss_resolve_find_cdb(&tmp,&c,"nextdeps") ; - res.nextdeps = x ; - - /* ncontents */ - x = ss_resolve_find_cdb(&tmp,&c,"ncontents") ; - res.ncontents = x ; - - /* down */ - x = ss_resolve_find_cdb(&tmp,&c,"down") ; - res.down = x ; - - /* disen */ - x = ss_resolve_find_cdb(&tmp,&c,"disen") ; - res.disen = x ; - - if (!ss_resolve_copy(dres,&res)) goto err ; - - close(fd) ; - cdb_free(&c) ; - ss_resolve_free(&res) ; - stralloc_free(&tmp) ; - - return 1 ; - - err: - close(fd) ; - err_fd: - cdb_free(&c) ; - ss_resolve_free(&res) ; - stralloc_free(&tmp) ; - return 0 ; -} - -int ss_resolve_modify_field(ss_resolve_t *res, ss_resolve_enum_t field, char const *data) -{ - log_flow() ; - - uint32_t ifield ; - - switch(field) - { - case SS_RESOLVE_ENUM_NAME: - res->name = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_DESCRIPTION: - res->description = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_VERSION: - res->version = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_LOGGER: - res->logger = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_LOGREAL: - res->logreal = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_LOGASSOC: - res->logassoc = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_DSTLOG: - res->dstlog = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_DEPS: - res->deps = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_OPTSDEPS: - res->optsdeps = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_EXTDEPS: - res->extdeps = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_CONTENTS: - res->contents = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_SRC: - res->src = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_SRCONF: - res->srconf = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_LIVE: - res->live = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_RUNAT: - res->runat = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_TREE: - res->tree = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_TREENAME: - res->treename = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_STATE: - res->state = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_EXEC_RUN: - res->exec_run = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_EXEC_LOG_RUN: - res->exec_log_run = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_REAL_EXEC_RUN: - res->real_exec_run = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_REAL_EXEC_LOG_RUN: - res->real_exec_log_run = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_EXEC_FINISH: - res->exec_finish = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_REAL_EXEC_FINISH: - res->real_exec_finish = ss_resolve_add_string(res,data) ; - break ; - - case SS_RESOLVE_ENUM_TYPE: - if (!uint0_scan(data, &ifield)) return 0 ; - res->type = ifield ; - break ; - - case SS_RESOLVE_ENUM_NDEPS: - if (!uint0_scan(data, &ifield)) return 0 ; - res->ndeps = ifield ; - break ; - - case SS_RESOLVE_ENUM_NOPTSDEPS: - if (!uint0_scan(data, &ifield)) return 0 ; - res->noptsdeps = ifield ; - break ; - - case SS_RESOLVE_ENUM_NEXTDEPS: - if (!uint0_scan(data, &ifield)) return 0 ; - res->nextdeps = ifield ; - break ; - - case SS_RESOLVE_ENUM_NCONTENTS: - if (!uint0_scan(data, &ifield)) return 0 ; - res->ncontents = ifield ; - break ; - - case SS_RESOLVE_ENUM_DOWN: - if (!uint0_scan(data, &ifield)) return 0 ; - res->down = ifield ; - break ; - - case SS_RESOLVE_ENUM_DISEN: - if (!uint0_scan(data, &ifield)) return 0 ; - res->disen = ifield ; - break ; - - default: - break ; - } - return 1 ; -} - -int ss_resolve_put_field_to_sa(stralloc *sa,ss_resolve_t *res, ss_resolve_enum_t field) -{ - log_flow() ; - - uint32_t ifield ; - - switch(field) - { - case SS_RESOLVE_ENUM_NAME: - ifield = res->name ; - break ; - - case SS_RESOLVE_ENUM_DESCRIPTION: - ifield = res->description ; - break ; - - case SS_RESOLVE_ENUM_VERSION: - ifield = res->version ; - break ; - - case SS_RESOLVE_ENUM_LOGGER: - ifield = res->logger ; - break ; - - case SS_RESOLVE_ENUM_LOGREAL: - ifield = res->logreal ; - break ; - - case SS_RESOLVE_ENUM_LOGASSOC: - ifield = res->logassoc ; - break ; - - case SS_RESOLVE_ENUM_DSTLOG: - ifield = res->dstlog ; - break ; - - case SS_RESOLVE_ENUM_DEPS: - ifield = res->deps ; - break ; - - case SS_RESOLVE_ENUM_OPTSDEPS: - ifield = res->optsdeps ; - break ; - - case SS_RESOLVE_ENUM_EXTDEPS: - ifield = res->extdeps ; - break ; - - case SS_RESOLVE_ENUM_CONTENTS: - ifield = res->contents ; - break ; - - case SS_RESOLVE_ENUM_SRC: - ifield = res->src ; - break ; - - case SS_RESOLVE_ENUM_SRCONF: - ifield = res->srconf ; - break ; - - case SS_RESOLVE_ENUM_LIVE: - ifield = res->live ; - break ; - - case SS_RESOLVE_ENUM_RUNAT: - ifield = res->runat ; - break ; - - case SS_RESOLVE_ENUM_TREE: - ifield = res->tree ; - break ; - - case SS_RESOLVE_ENUM_TREENAME: - ifield = res->treename ; - break ; - - case SS_RESOLVE_ENUM_STATE: - ifield = res->state ; - break ; - - case SS_RESOLVE_ENUM_EXEC_RUN: - ifield = res->exec_run ; - break ; - - case SS_RESOLVE_ENUM_EXEC_LOG_RUN: - ifield = res->exec_log_run ; - break ; - - case SS_RESOLVE_ENUM_REAL_EXEC_RUN: - ifield = res->real_exec_run ; - break ; - - case SS_RESOLVE_ENUM_REAL_EXEC_LOG_RUN: - ifield = res->real_exec_log_run ; - break ; - - case SS_RESOLVE_ENUM_EXEC_FINISH: - ifield = res->exec_finish ; - break ; - - case SS_RESOLVE_ENUM_REAL_EXEC_FINISH: - ifield = res->real_exec_finish ; - break ; - - case SS_RESOLVE_ENUM_TYPE: - ifield = res->type ; - break ; - - case SS_RESOLVE_ENUM_NDEPS: - ifield = res->ndeps ; - break ; - - case SS_RESOLVE_ENUM_NOPTSDEPS: - ifield = res->noptsdeps ; - break ; - - case SS_RESOLVE_ENUM_NEXTDEPS: - ifield = res->nextdeps ; - break ; - - case SS_RESOLVE_ENUM_NCONTENTS: - ifield = res->ncontents ; - break ; - - case SS_RESOLVE_ENUM_DOWN: - ifield = res->down ; - break ; - - case SS_RESOLVE_ENUM_DISEN: - ifield = res->disen ; - break ; - - default: - return 0 ; - } - - if (!auto_stra(sa,res->sa.s + ifield)) - return 0 ; - - return 1 ; -} diff --git a/src/lib66/ss_service.c b/src/lib66/ss_service.c deleted file mode 100644 index ab94fc4227d1fa7438c28cfa23668808a0a900b9..0000000000000000000000000000000000000000 --- a/src/lib66/ss_service.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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 <unistd.h> -#include <sys/stat.h> - -#include <oblibs/log.h> -#include <oblibs/string.h> -#include <oblibs/types.h> -#include <oblibs/sastr.h> - -#include <skalibs/stralloc.h> - -#include <66/utils.h> -#include <66/constants.h> -#include <66/resolve.h> -#include <66/ssexec.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 ; - ss_resolve_t res = RESOLVE_ZERO ; - size_t newlen = 0, pos = 0 ; - int e = -1 ; - 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) ; - - if (ss_resolve_check(trees, sv)) { - - if (!ss_resolve_read(&res, trees, sv)) { - - log_warnu("read resolve file: ", trees, "/", sv) ; - goto freed ; - } - - if (res.disen) { - - log_trace(sv, " enabled at tree: ", treename) ; - - e = 1 ; - goto freed ; - - } else { - - e = 2 ; - goto freed ; - } - } - } - empty: - e = 0 ; - freed: - stralloc_free(&sa) ; - ss_resolve_free(&res) ; - return e ; -} - -/** @Return 0 if not found - * @Return 1 if found - * @Return 2 if found but marked disabled - * @Return -1 system error */ -int service_isenabledat(stralloc *tree, char const *sv) -{ - - log_flow() ; - - stralloc sa = STRALLOC_ZERO ; - ss_resolve_t res = RESOLVE_ZERO ; - size_t newlen = 0, pos = 0 ; - int e = -1 ; - 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) ; - - if (ss_resolve_check(trees, sv)) { - - if (!ss_resolve_read(&res, trees, sv)) { - - log_warnu("read resolve file: ", trees, "/", sv) ; - goto freed ; - } - - if (res.disen) { - - log_trace(sv, " enabled at tree: ", treename) ; - e = 1 ; - - } else { - - log_trace(sv, " disabled at tree: ", treename) ; - e = 2 ; - } - - if (!auto_stra(tree, treename)) { - e = -1 ; - goto freed ; - } - goto freed ; - } - } - empty: - e = 0 ; - freed: - stralloc_free(&sa) ; - ss_resolve_free(&res) ; - return e ; -}