diff --git a/src/include/66/service.h b/src/include/66/service.h index 8f098a5426485733745b586af1d7477061baf8b6..b19734561416c0483270adbbf56056b5bc55c241 100644 --- a/src/include/66/service.h +++ b/src/include/66/service.h @@ -25,7 +25,7 @@ #include <66/ssexec.h> #include <66/resolve.h> -#include <66/state.h> +#include <66/utils.h> typedef struct resolve_service_addon_path_s resolve_service_addon_path_t, *resolve_service_addon_path_t_ref ; struct resolve_service_addon_path_s @@ -33,9 +33,10 @@ struct resolve_service_addon_path_s uint32_t home ; // string, /var/lib/66 or /home/user/.66 uint32_t frontend ; // string, /home/<user>/.66/service or /etc/66/service or /usr/lib/66/service uint32_t status ; //string, /var/lib/66/system/service/svc/service_name/state/status + uint32_t servicedir ; //string, /var/lib/66/system/service/svc/service_name or for module /var/lib/66/system/service/svc/module_name/svc/service_name } ; -#define RESOLVE_SERVICE_ADDON_PATH_ZERO { 0,0,0 } +#define RESOLVE_SERVICE_ADDON_PATH_ZERO { 0,0,0,0 } typedef struct resolve_service_addon_dependencies_s resolve_service_addon_dependencies_t, *resolve_service_addon_dependencies_t_ref ; struct resolve_service_addon_dependencies_s @@ -43,13 +44,15 @@ struct resolve_service_addon_dependencies_s uint32_t depends ; // string uint32_t requiredby ; // string, uint32_t optsdeps ; // string, optional dependencies + uint32_t contents ; // string uint32_t ndepends ; // integer uint32_t nrequiredby ; // integer uint32_t noptsdeps ; // integer + uint32_t ncontents ; // integer } ; -#define RESOLVE_SERVICE_ADDON_DEPENDENCIES_ZERO { 0,0,0,0,0,0 } +#define RESOLVE_SERVICE_ADDON_DEPENDENCIES_ZERO { 0,0,0,0,0,0,0,0 } typedef struct resolve_service_addon_timeout_s resolve_service_addon_timeout_t, *resolve_service_addon_timeout_t_ref ; struct resolve_service_addon_timeout_s @@ -148,15 +151,14 @@ struct resolve_service_addon_regex_s uint32_t directories ; // string uint32_t files ; // string uint32_t infiles ; // string - uint32_t contents ; // string uint32_t ndirectories ; // integer uint32_t nfiles ; // integer uint32_t ninfiles ; // integer - uint32_t ncontents ; // integer + } ; -#define RESOLVE_SERVICE_ADDON_REGEX_ZERO { 0,0,0,0,0,0,0,0,0 } +#define RESOLVE_SERVICE_ADDON_REGEX_ZERO { 0,0,0,0,0,0,0 } typedef struct resolve_service_s resolve_service_t, *resolve_service_t_ref ; @@ -225,14 +227,17 @@ enum resolve_service_enum_e E_RESOLVE_SERVICE_HOME, E_RESOLVE_SERVICE_FRONTEND, E_RESOLVE_SERVICE_STATUS, + E_RESOLVE_SERVICE_SERVICEDIR, // dependencies E_RESOLVE_SERVICE_DEPENDS, E_RESOLVE_SERVICE_REQUIREDBY, E_RESOLVE_SERVICE_OPTSDEPS, + E_RESOLVE_SERVICE_CONTENTS, E_RESOLVE_SERVICE_NDEPENDS, E_RESOLVE_SERVICE_NREQUIREDBY, E_RESOLVE_SERVICE_NOPTSDEPS, + E_RESOLVE_SERVICE_NCONTENTS, // execute E_RESOLVE_SERVICE_RUN, @@ -287,11 +292,9 @@ enum resolve_service_enum_e E_RESOLVE_SERVICE_REGEX_DIRECTORIES, E_RESOLVE_SERVICE_REGEX_FILES, E_RESOLVE_SERVICE_REGEX_INFILES, - E_RESOLVE_SERVICE_REGEX_CONTENTS, E_RESOLVE_SERVICE_REGEX_NDIRECTORIES, E_RESOLVE_SERVICE_REGEX_NFILES, E_RESOLVE_SERVICE_REGEX_NINFILES, - E_RESOLVE_SERVICE_REGEX_NCONTENTS, E_RESOLVE_SERVICE_ENDOFKEY } ; @@ -311,20 +314,16 @@ extern int service_resolve_modify_field(resolve_service_t *res, resolve_service_ extern int service_resolve_read_cdb(cdb *c, resolve_service_t *res) ; extern int service_resolve_write(resolve_service_t *res) ; extern int service_resolve_write_cdb(cdbmaker *c, resolve_service_t *sres) ; -extern void service_enable_disable(graph_t *g, char const *base, char const *sv, uint8_t action) ; +extern void service_enable_disable(graph_t *g, resolve_service_t *res, resolve_service_t *ares, unsigned int areslen, uint8_t action, visit_t *visit) ; +/* avoid circular dependencies by prototyping the ss_state_t instead + * of calling the state.h header file*/ +typedef struct ss_state_s ss_state_t, *ss_state_t_ref ; +extern int service_is(ss_state_t *ste, uint32_t flag) ; /** Graph */ extern void service_graph_g(char const *alist, size_t alen, graph_t *graph, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint32_t flag) ; extern void service_graph_collect(graph_t *g, char const *alist, size_t alen, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint32_t flag) ; extern void service_graph_build(graph_t *g, resolve_service_t *ares, unsigned int areslen, uint32_t flag) ; -extern int service_is(ss_state_t *ste, uint32_t flag) ; - - - - - -/** SHOULD BE NOT USED */ -extern int service_resolve_sort_bytype(stralloc *list, char const *src) ; #endif diff --git a/src/lib66/parse/parse_compute_resolve.c b/src/lib66/parse/parse_compute_resolve.c index 7dc54203d1516b39af37b8346b799e193f164732..a7fd6538e7a679719bc2ecd242ef9561ad9873ab 100644 --- a/src/lib66/parse/parse_compute_resolve.c +++ b/src/lib66/parse/parse_compute_resolve.c @@ -17,6 +17,7 @@ #include <oblibs/log.h> #include <oblibs/string.h> +#include <oblibs/directory.h> #include <skalibs/types.h> #include <skalibs/stralloc.h> @@ -26,41 +27,86 @@ #include <66/resolve.h> #include <66/state.h> #include <66/ssexec.h> -#include <66/parser.h> +#include <66/parse.h> #include <66/utils.h> #include <66/service.h> - +#include <66/sanitize.h> #include <s6/config.h> #ifndef FAKELEN #define FAKELEN strlen(run) #endif -static uint32_t compute_scan_dir(resolve_wrapper_t_ref wres, ssexec_t *info, char const *service) +static uint32_t compute_servicedir(resolve_wrapper_t_ref wres, ssexec_t *info) +{ + resolve_service_t_ref res = (resolve_service_t *)wres->obj ; + char *name = res->sa.s + res->name ; + size_t namelen = strlen(name) ; + + char dir[info->base.len + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1] ; + + auto_strings(dir, info->base.s, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name) ; + + return resolve_add_string(wres, dir) ; +} + +static uint32_t compute_status(resolve_wrapper_t_ref wres, ssexec_t *info) +{ + resolve_service_t_ref res = (resolve_service_t *)wres->obj ; + char *name = res->sa.s + res->name ; + size_t namelen = strlen(name) ; + + char dir[info->base.len + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ; + + auto_strings(dir, info->base.s, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name, SS_STATE, "/", SS_STATUS) ; + + return resolve_add_string(wres, dir) ; + +} + +static uint32_t compute_scan_dir(resolve_wrapper_t_ref wres, ssexec_t *info) { log_flow() ; - size_t servicelen = strlen(service) ; + resolve_service_t_ref res = (resolve_service_t *)wres->obj ; + char *name = res->sa.s + res->name ; + size_t namelen = strlen(name) ; - char tmp[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + servicelen + 1 + SS_SCANDIR_LEN + 1 + servicelen + 1] ; - auto_strings(tmp, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", service, "/", SS_SCANDIR, "/", service) ; + char dir[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + namelen + 1 + SS_SCANDIR_LEN + 1 + namelen + 1] ; - return resolve_add_string(wres, tmp) ; + auto_strings(dir, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", name, "/", SS_SCANDIR, "/", name) ; + + return resolve_add_string(wres, dir) ; +} + +static uint32_t compute_state_dir(resolve_wrapper_t_ref wres, ssexec_t *info, char const *folder) +{ + log_flow() ; + + resolve_service_t_ref res = (resolve_service_t *)wres->obj ; + char *name = res->sa.s + res->name ; + size_t namelen = strlen(name) ; + size_t folderlen = strlen(folder) ; + char dir[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + namelen + 1 + folderlen + 1] ; + auto_strings(dir, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", name, "/", folder) ; + + return resolve_add_string(wres, dir) ; } -static uint32_t compute_state_dir(resolve_wrapper_t_ref wres, ssexec_t *info, char const *service, char const *folder) +static uint32_t compute_pipe_service(resolve_wrapper_t_ref wres, ssexec_t *info, char const *service, char const *name) { log_flow() ; size_t servicelen = strlen(service) ; - size_t folderlen = strlen(folder) ; + size_t namelen = strlen(name) ; - char tmp[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + servicelen + 1 + folderlen + 1] ; - auto_strings(tmp, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", service, "/", folder) ; + char tmp[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + servicelen + 1 + SS_SCANDIR_LEN + 1 + namelen + 1] ; + auto_strings(tmp, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", service, "/", SS_SCANDIR, "/", name) ; return resolve_add_string(wres, tmp) ; + } static uint32_t compute_log_dir(resolve_wrapper_t_ref wres, resolve_service_t *res) @@ -68,7 +114,7 @@ static uint32_t compute_log_dir(resolve_wrapper_t_ref wres, resolve_service_t *r log_flow() ; size_t namelen = strlen(res->sa.s + res->name) ; - size_t syslen = res->owner ? strlen(res->sa.s + res->path.home) + strlen(SS_LOGGER_USERDIR) : strlen(SS_LOGGER_SYSDIR) ; + size_t syslen = res->owner ? strlen(res->sa.s + res->path.home) + strlen(SS_LOGGER_USERDIR) + strlen(SS_USER_DIR) : strlen(SS_LOGGER_SYSDIR) ; size_t dstlen = res->logger.destination ? strlen(res->sa.s + res->logger.destination) : strlen(SS_LOGGER_SYSDIR) ; char dstlog[syslen + dstlen + namelen + 1] ; @@ -91,20 +137,6 @@ static uint32_t compute_log_dir(resolve_wrapper_t_ref wres, resolve_service_t *r return resolve_add_string(wres, dstlog) ; } -static uint32_t compute_pipe_service(resolve_wrapper_t_ref wres, ssexec_t *info, char const *service, char const *name) -{ - log_flow() ; - - size_t servicelen = strlen(service) ; - size_t namelen = strlen(name) ; - - char tmp[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + servicelen + 1 + SS_SCANDIR_LEN + 1 + namelen + 1] ; - auto_strings(tmp, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", service, "/", SS_SCANDIR, "/", name) ; - - return resolve_add_string(wres, tmp) ; - -} - /** * @!runorfinish -> finish, @runorfinish -> run * */ @@ -303,7 +335,7 @@ static void compute_log_script(resolve_service_t *res) free(wres) ; } -static void compute_log(resolve_service_t *res, ssexec_t *info) +static void compute_log(resolve_service_t *res, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info) { log_flow() ; @@ -323,7 +355,6 @@ static void compute_log(resolve_service_t *res, ssexec_t *info) auto_strings(description, str + res->name, " logger") ; lres.name = resolve_add_string(wres, name) ; - lres.description = resolve_add_string(wres, description) ; lres.version = resolve_add_string(wres, str + res->version) ; lres.type = res->type ; @@ -337,16 +368,13 @@ static void compute_log(resolve_service_t *res, ssexec_t *info) lres.owner = res->owner ; lres.treename = resolve_add_string(wres, str + res->treename) ; lres.user = resolve_add_string(wres, str + res->user) ; + if (res->inmodule) + lres.inmodule = resolve_add_string(wres, str + res->inmodule) ; lres.path.home = resolve_add_string(wres, str + res->path.home) ; lres.path.frontend = resolve_add_string(wres, str + res->path.frontend) ; - - { - char status[strlen(res->sa.s + res->path.home) + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + strlen(name) + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ; - auto_strings(status, res->sa.s + res->path.home, SS_SYSTEM, SS_SYSTEM, SS_SVC, "/", name, SS_STATE, "/" SS_STATUS) ; - lres.path.status = resolve_add_string(wres, status) ; - - } + lres.path.servicedir = compute_servicedir(wres, info) ; + lres.path.status = compute_status(wres, info) ; lres.dependencies.requiredby = resolve_add_string(wres, str + res->name) ; lres.dependencies.nrequiredby = 1 ; @@ -360,14 +388,20 @@ static void compute_log(resolve_service_t *res, ssexec_t *info) lres.execute.downsignal = res->logger.execute.downsignal ; lres.live.livedir = resolve_add_string(wres, info->live.s) ; - lres.live.scandir = compute_scan_dir(wres, info, name) ; - lres.live.statedir = compute_state_dir(wres, info, name, "state") ; - lres.live.eventdir = compute_state_dir(wres, info, name, "event") ; - lres.live.notifdir = compute_state_dir(wres, info, name, "notif") ; - lres.live.supervisedir = compute_state_dir(wres, info, name, "supervise") ; + lres.live.scandir = compute_scan_dir(wres, info) ; + lres.live.statedir = compute_state_dir(wres, info, "state") ; + lres.live.eventdir = compute_state_dir(wres, info, "event") ; + lres.live.notifdir = compute_state_dir(wres, info, "notif") ; + lres.live.supervisedir = compute_state_dir(wres, info, "supervise") ; lres.live.fdholderdir = compute_pipe_service(wres, info, name, SS_FDHOLDER) ; lres.live.oneshotddir = compute_pipe_service(wres, info, name, SS_ONESHOTD) ; + lres.logger.destination = resolve_add_string(wres, str + res->logger.destination) ; + lres.logger.backup = res->logger.backup ; + lres.logger.maxsize = res->logger.maxsize ; + lres.logger.timestamp = res->logger.timestamp ; + lres.logger.want = 0 ; + // oneshot do not use fdholder daemon if (res->type == TYPE_CLASSIC) { @@ -377,24 +411,28 @@ static void compute_log(resolve_service_t *res, ssexec_t *info) lres.execute.run.runas = resolve_add_string(wres, res->sa.s + res->logger.execute.run.runas) ; } - if (!service_resolve_write(&lres)) - log_dieu(LOG_EXIT_SYS, "write resolve file of service: ", name) ; + if (service_resolve_array_search(ares, *areslen, name) < 0) { + if (*areslen >= SS_MAX_SERVICE) + log_die(LOG_EXIT_SYS, "too many services to parse -- compile again 66 changing the --max-service options") ; + + ares[(*areslen)++] = lres ; + } - resolve_free(wres) ; + free(wres) ; } -void parse_compute_resolve(resolve_service_t *res, ssexec_t *info) +void parse_compute_resolve(unsigned int idx, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info) { log_flow() ; + resolve_service_t_ref res = &ares[idx] ; resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ; char name[strlen(res->sa.s + res->name) + 1] ; - char status[info->base.len + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + strlen(name) + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ; auto_strings(name, res->sa.s + res->name) ; - auto_strings(status, info->base.s, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name, SS_STATE, "/", SS_STATUS) ; - res->path.status = resolve_add_string(wres, status) ; + res->path.status = compute_status(wres, info) ; + res->path.servicedir = compute_servicedir(wres, info) ; res->path.home = resolve_add_string(wres, info->base.s) ; @@ -430,7 +468,7 @@ void parse_compute_resolve(resolve_service_t *res, ssexec_t *info) * * /run/66/scandir/uid/ * */ - res->live.scandir = compute_scan_dir(wres, info, name) ; + res->live.scandir = compute_scan_dir(wres, info) ; /* state */ /** @@ -441,16 +479,16 @@ void parse_compute_resolve(resolve_service_t *res, ssexec_t *info) * /run/66/state/uid/service_name/event * /run/66/state/uid/service_name/supervise * */ - res->live.statedir = compute_state_dir(wres, info, name, "state") ; + res->live.statedir = compute_state_dir(wres, info, "state") ; /* event */ - res->live.eventdir = compute_state_dir(wres, info, name, "event") ; + res->live.eventdir = compute_state_dir(wres, info, "event") ; /* notif */ - res->live.notifdir = compute_state_dir(wres, info, name, "notif") ; + res->live.notifdir = compute_state_dir(wres, info, "notif") ; /* supervise */ - res->live.supervisedir = compute_state_dir(wres, info, name, "supervise") ; + res->live.supervisedir = compute_state_dir(wres, info, "supervise") ; /* fdholder */ res->live.fdholderdir = compute_pipe_service(wres, info, name, SS_FDHOLDER) ; @@ -458,9 +496,10 @@ void parse_compute_resolve(resolve_service_t *res, ssexec_t *info) /* oneshotd */ res->live.oneshotddir = compute_pipe_service(wres, info, name, SS_ONESHOTD) ; - if (res->logger.want && res->type != TYPE_MODULE && res->type != TYPE_BUNDLE) { + if (res->logger.want && (res->type == TYPE_CLASSIC || res->type == TYPE_ONESHOT)) { size_t namelen = strlen(name) ; + char logname[namelen + SS_LOG_SUFFIX_LEN + 1] ; auto_strings(logname, name, SS_LOG_SUFFIX) ; @@ -469,16 +508,24 @@ void parse_compute_resolve(resolve_service_t *res, ssexec_t *info) res->logger.destination = compute_log_dir(wres, res) ; - if (res->type != TYPE_ONESHOT) { + if (res->type == TYPE_CLASSIC) { /** the logger is not a service with oneshot type */ - char buf[strlen(res->sa.s + res->dependencies.depends) + 1 + strlen(res->sa.s + res->logger.name) + 1] ; - auto_strings(buf, res->sa.s + res->dependencies.depends, " ", res->sa.s + res->logger.name) ; + if (res->dependencies.ndepends) { + + char buf[strlen(res->sa.s + res->dependencies.depends) + 1 + strlen(res->sa.s + res->logger.name) + 1] ; + auto_strings(buf, res->sa.s + res->dependencies.depends, " ", res->sa.s + res->logger.name) ; + + res->dependencies.depends = resolve_add_string(wres, buf) ; + + } else { + + res->dependencies.depends = resolve_add_string(wres, res->sa.s + res->logger.name) ; - res->dependencies.depends = resolve_add_string(wres, buf) ; + } res->dependencies.ndepends++ ; - compute_log(res, info) ; + compute_log(res, ares, areslen, info) ; } } @@ -514,8 +561,5 @@ void parse_compute_resolve(resolve_service_t *res, ssexec_t *info) } } - if (!service_resolve_write(res)) - log_dieu(LOG_EXIT_SYS, "write resolve file of service: ", name) ; - free(wres) ; }