diff --git a/src/include/66/module.h b/src/include/66/module.h new file mode 100644 index 0000000000000000000000000000000000000000..591025343b7a16b63c21a23942adf7cd2b4b061c --- /dev/null +++ b/src/include/66/module.h @@ -0,0 +1,45 @@ +/* + * module.h + * + * 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./ + */ + +#ifndef SS_MODULE_H +#define SS_MODULE_H + +#include <sys/types.h> + +#include <skalibs/stralloc.h> + +#include <66/service.h> +#include <66/info.h> + +#define SS_MODULE_CONFIG_DIR "/configure" +#define SS_MODULE_CONFIG_DIR_LEN (sizeof SS_MODULE_CONFIG_DIR - 1) +#define SS_MODULE_CONFIG_SCRIPT "configure" +#define SS_MODULE_CONFIG_SCRIPT_LEN (sizeof SS_MODULE_CONFIG_SCRIPT - 1) +#define SS_MODULE_SERVICE "/service" +#define SS_MODULE_SERVICE_LEN (sizeof SS_MODULE_SERVICE - 1) +#define SS_MODULE_SERVICE_INSTANCE "/service@" +#define SS_MODULE_SERVICE_INSTANCE_LEN (sizeof SS_MODULE_SERVICE_INSTANCE - 1) + +extern void get_list(stralloc *list, char const *src, char const *name, mode_t mode) ; +extern void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint8_t force) ; +extern void parse_module_check_dir(char const *src,char const *dir) ; +extern void parse_module_check_name(char const *src, char const *name) ; +extern void regex_configure(resolve_service_t *res, ssexec_t *info, char const *path, char const *name) ; +extern int regex_get_file_name(char *filename, char const *str) ; +extern void regex_get_regex(char *regex, char const *str) ; +extern void regex_get_replace(char *replace, char const *str) ; +extern void regex_rename(stralloc *list, resolve_service_t *res, uint32_t element) ; +extern void regex_replace(stralloc *list, resolve_service_t *res) ; + +#endif diff --git a/src/lib66/module/deps-lib/deps b/src/lib66/module/deps-lib/deps index aa08a1493330806f8a201d878aa14bb087db05a3..a513575fd778a1593d20164b37fd04393134bbab 100644 --- a/src/lib66/module/deps-lib/deps +++ b/src/lib66/module/deps-lib/deps @@ -1,3 +1,12 @@ +get_list.o +parse_module.o +parse_module_check_dir.o +regex_configure.o +regex_get_file_name.o +regex_get_regex.o +regex_get_replace.o +regex_rename.o +regex_replace.o -loblibs -lskarnet diff --git a/src/lib66/module/get_list.c b/src/lib66/module/get_list.c new file mode 100644 index 0000000000000000000000000000000000000000..930482ad84430b09690b09d452179a48b8f3adcf --- /dev/null +++ b/src/lib66/module/get_list.c @@ -0,0 +1,39 @@ +/* + * regex_get_replace.c + * + * Copyright (c) 2018-2022 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <sys/types.h> +#include <string.h> + +#include <oblibs/log.h> +#include <oblibs/sastr.h> + +#include <skalibs/stralloc.h> + +#include <66/module.h> + +void get_list(stralloc *list, char const *src, char const *name, mode_t mode) +{ + log_flow() ; + + list->len = 0 ; + char const *exclude[2] = { SS_MODULE_CONFIG_DIR + 1, 0 } ; + + char t[strlen(src) + 1] ; + + auto_strings(t, src) ; + + if (!sastr_dir_get_recursive(list, t, exclude, mode, 1)) + log_dieusys(LOG_EXIT_SYS,"get file(s) of module: ", name) ; + +} diff --git a/src/lib66/module/parse_module.c b/src/lib66/module/parse_module.c new file mode 100644 index 0000000000000000000000000000000000000000..26d49e32cdbafbe39e189844861fd35b34b0f10f --- /dev/null +++ b/src/lib66/module/parse_module.c @@ -0,0 +1,226 @@ +/* + * parse_module.c + * + * Copyright (c) 2018-2022 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <sys/types.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> //chdir, unlink + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/types.h> +#include <oblibs/sastr.h> +#include <oblibs/directory.h> + +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> //hiercopy + +#include <66/module.h> +#include <66/resolve.h> +#include <66/info.h> +#include <66/constants.h> +#include <66/instance.h> +#include <66/utils.h> +#include <66/parser.h> + +void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint8_t force) +{ + log_flow() ; + + int r, insta = -1 ; + unsigned int residx = 0 ; + size_t pos = 0, pathlen = 0 ; + char *name = res->sa.s + res->name ; + char *src = res->sa.s + res->path.frontend ; + char dirname[strlen(src) + 1] ; + char path[SS_MAX_PATH_LEN] ; + char ainsta[strlen(name)] ; + stralloc list = STRALLOC_ZERO ; + resolve_wrapper_t_ref wres = 0 ; + + log_trace("parse module: ", name) ; + + if (!ob_dirname(dirname, src)) + log_dieu(LOG_EXIT_SYS, "get directory name of: ", src) ; + + insta = instance_check(name) ; + instance_splitname_to_char(ainsta, name, insta, 0) ; + + size_t prefixlen = strlen(name) ; + + char prefix[prefixlen + 2] ; + + instance_splitname_to_char(prefix, name, insta, 1) ; + + auto_strings(prefix + strlen(prefix), "-") ; + prefixlen = strlen(prefix) ; + + if (!getuid()) { + + auto_strings(path, SS_SERVICE_ADMDIR, name) ; + + } else { + + if (!set_ownerhome_stack(path)) + log_dieusys(LOG_EXIT_SYS, "unable to find the home directory of the user") ; + + pathlen = strlen(path) ; + auto_strings(path + pathlen, SS_SERVICE_USERDIR, name) ; + } + + uint8_t conf = res->environ.env_overwrite ; + + /** check mandatory directories + * res->frontend/module_name/{configure,service,service@} */ + parse_module_check_dir(dirname, SS_MODULE_CONFIG_DIR) ; + parse_module_check_dir(dirname, SS_MODULE_SERVICE) ; + parse_module_check_dir(dirname, SS_MODULE_SERVICE_INSTANCE) ; + + r = scan_mode(path, S_IFDIR) ; + if (r == -1) { + errno = EEXIST ; + log_dieusys(LOG_EXIT_SYS, "conflicting format of: ", path) ; + + } else if (!r) { + + if (!hiercopy(dirname, path)) + log_dieusys(LOG_EXIT_SYS, "copy: ", dirname, " to: ", path) ; + + } else { + + /** Must reconfigure all services of the module */ + if (force < 1) { + + log_warn("skip configuration of the module: ", name, " -- already configured") ; + goto deps ; + } + + if (dir_rm_rf(path) < 0) + log_dieusys (LOG_EXIT_SYS, "remove: ", path) ; + + if (!hiercopy(dirname, path)) + log_dieusys(LOG_EXIT_SYS,"copy: ", dirname, " to: ", path) ; + } + + pathlen = strlen(path) ; + /** remove the original service frontend file inside the copied directory + * to avoid double frontend service file for a same service.*/ + auto_strings(path + pathlen, "/", ainsta) ; + + if (unlink(path) < 0) + log_dieusys(LOG_EXIT_ZERO, "unlink: ", path) ; + + path[pathlen] = 0 ; + + /** contents */ + get_list(&list, path, name, S_IFREG) ; + regex_replace(&list, res) ; + + /** directories */ + get_list(&list, path, name, S_IFDIR) ; + regex_rename(&list, res, res->regex.directories) ; + + /** filename */ + get_list(&list, path, name, S_IFREG) ; + regex_rename(&list, res, res->regex.files) ; + + /** configure script */ + regex_configure(res, info, path, name) ; + + deps: + + list.len = 0 ; + + if (!auto_stra(&list, path)) + log_die_nomem("stralloc") ; + + char t[list.len] ; + + sastr_to_char(t, &list) ; + + list.len = 0 ; + char const *exclude[3] = { SS_MODULE_CONFIG_DIR + 1, SS_MODULE_SERVICE_INSTANCE + 1, 0 } ; + if (!sastr_dir_get_recursive(&list, t, exclude, S_IFREG, 1)) + log_dieusys(LOG_EXIT_SYS, "get file(s) of module: ", name) ; + + char ll[list.len] ; + size_t llen = list.len ; + + sastr_to_char(ll, &list) ; + + list.len = 0 ; + + for (pos = 0 ; pos < llen ; pos += strlen(ll + pos) + 1) { + + char *dname = ll + pos ; + char ainsta[pathlen + SS_MODULE_SERVICE_INSTANCE_LEN + 1 + SS_MAX_SERVICE_NAME + 1] ; + size_t namelen = strlen(dname) ; + char bname[namelen] ; + + if (!ob_basename(bname,dname)) + log_dieu(LOG_EXIT_SYS, "find basename of: ", dname) ; + + if (instance_check(bname) > 0) { + auto_strings(ainsta, path, SS_MODULE_SERVICE_INSTANCE, "/", bname) ; + dname = ainsta ; + } + + if (!sastr_add_string(&list, bname)) + log_die_nomem("stralloc") ; + + if (!strcmp(name, bname)) + log_die(LOG_EXIT_SYS, "cyclic call detected -- ", name, " call ", bname) ; + + /** nothing to do with the exit code*/ + parse_frontend(dname, ares, areslen, info, force, conf, &residx, path, bname) ; + + wres = resolve_set_struct(DATA_SERVICE, &ares[residx]) ; + + ares[residx].inmodule = resolve_add_string(wres, name) ; + } + + char deps[list.len] ; + + sastr_to_char(deps, &list) ; + + llen = list.len ; + + list.len = 0 ; + + /* rebuild the dependencies list incorporating the services defined inside + * the module. + + if (res->dependencies.ndepends) + if (!sastr_clean_string(&list, res->sa.s + res->dependencies.depends)) + log_dieu(LOG_EXIT_SYS, "clean string") ; + + + + res->dependencies.depends = parse_compute_list(wres, &list, &res->dependencies.ndepends, 0) ; + + list.len = 0 ; +*/ + + wres = resolve_set_struct(DATA_SERVICE, res) ; + + for (pos = 0 ; pos < llen ; pos += strlen(deps + pos) + 1) + if (!sastr_add_string(&list, deps + pos)) + log_die_nomem("stralloc") ; + + res->regex.contents = parse_compute_list(wres, &list, &res->regex.ncontents, 0) ; + + free(wres) ; + stralloc_free(&list) ; +} diff --git a/src/lib66/module/parse_module_check_dir.c b/src/lib66/module/parse_module_check_dir.c new file mode 100644 index 0000000000000000000000000000000000000000..28cc2eba6bc754fcdf4803476e857f010128b8a1 --- /dev/null +++ b/src/lib66/module/parse_module_check_dir.c @@ -0,0 +1,43 @@ +/* + * regex_get_replace.c + * + * Copyright (c) 2018-2022 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 <errno.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/types.h> +#include <oblibs/directory.h> + +void parse_module_check_dir(char const *src,char const *dir) +{ + log_flow() ; + + int r ; + size_t srclen = strlen(src) ; + size_t dirlen = strlen(dir) ; + + char t[srclen + dirlen + 1] ; + auto_strings(t, src, dir) ; + + r = scan_mode(t,S_IFDIR) ; + if (r < 0) { + errno = EEXIST ; + log_diesys(LOG_EXIT_ZERO, "conflicting format of: ", t) ; + } + + if (!r) + if (!dir_create_parent(t, 0755)) + log_dieusys(LOG_EXIT_ZERO, "create directory: ", t) ; +} diff --git a/src/lib66/module/regex_configure.c b/src/lib66/module/regex_configure.c new file mode 100644 index 0000000000000000000000000000000000000000..7b6a33b89a5033eeb4fa3a129f12fc3af1bc23fb --- /dev/null +++ b/src/lib66/module/regex_configure.c @@ -0,0 +1,145 @@ +/* + * regex_configure.c + * + * Copyright (c) 2018-2022 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <sys/types.h> +#include <string.h> +#include <pwd.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/types.h> +#include <oblibs/sastr.h> +#include <oblibs/environ.h> + +#include <skalibs/stralloc.h> +#include <skalibs/types.h> +#include <skalibs/env.h> +#include <skalibs/djbunix.h> +#include <skalibs/bytestr.h> + +#include <66/module.h> +#include <66/resolve.h> +#include <66/info.h> +#include <66/environ.h> +#include <66/write.h> + +void regex_configure(resolve_service_t *res, ssexec_t *info, char const *path, char const *name) +{ + log_flow() ; + + int wstat, r ; + pid_t pid ; + size_t clen = res->regex.configure > 0 ? 1 : 0 ; + size_t pathlen = strlen(path), n ; + + stralloc env = STRALLOC_ZERO ; + + char const *newargv[2 + clen] ; + unsigned int m = 0 ; + + char pwd[pathlen + 1 + SS_MODULE_CONFIG_DIR_LEN + 1] ; + auto_strings(pwd, path, "/", SS_MODULE_CONFIG_DIR + 1) ; + + char config_script[pathlen + 1 + SS_MODULE_CONFIG_DIR_LEN + 1 + SS_MODULE_CONFIG_SCRIPT_LEN + 1] ; + auto_strings(config_script, path, "/", SS_MODULE_CONFIG_DIR + 1, "/", SS_MODULE_CONFIG_SCRIPT) ; + + r = scan_mode(config_script, S_IFREG) ; + if (r > 0) + { + /** export ssexec_t info value on the environment */ + { + char verbo[UINT_FMT]; + verbo[uid_fmt(verbo, VERBOSITY)] = 0 ; + if (!auto_stra(&env, \ + "MOD_NAME=", name, "\n", \ + "MOD_BASE=", res->sa.s + res->path.home, "\n", \ + "MOD_LIVE=", info->live.s, "\n", \ + "MOD_SCANDIR=", info->scandir.s, "\n", \ + "MOD_TREENAME=", res->sa.s + res->treename, "\n", \ + "MOD_OWNER=", res->sa.s + res->ownerstr, "\n", \ + "MOD_COLOR=", info->opt_color ? "1" : "0", "\n", \ + "MOD_VERBOSITY=", verbo, "\n", \ + "MOD_MODULE_DIR=", path, "\n", \ + "MOD_SKEL_DIR=", SS_SKEL_DIR, "\n", \ + "MOD_SERVICE_SYSDIR=", SS_SERVICE_SYSDIR, "\n", \ + "MOD_SERVICE_ADMDIR=", SS_SERVICE_ADMDIR, "\n", \ + "MOD_SERVICE_ADMCONFDIR=", SS_SERVICE_ADMCONFDIR, "\n", \ + "MOD_MODULE_SYSDIR=", SS_MODULE_SYSDIR, "\n", \ + "MOD_MODULE_ADMDIR=", SS_MODULE_ADMDIR, "\n", \ + "MOD_SCRIPT_SYSDIR=", SS_SCRIPT_SYSDIR, "\n", \ + "MOD_USER_DIR=", SS_USER_DIR, "\n", \ + "MOD_SERVICE_USERDIR=", SS_SERVICE_USERDIR, "\n", \ + "MOD_SERVICE_USERCONFDIR=", SS_SERVICE_USERCONFDIR, "\n", \ + "MOD_MODULE_USERDIR=", SS_MODULE_USERDIR, "\n", \ + "MOD_SCRIPT_USERDIR=", SS_SCRIPT_USERDIR, "\n")) + log_dieu(LOG_EXIT_SYS, "append environment variables") ; + } + + /** environment is not mandatory */ + if (res->environ.env > 0) + { + stralloc oenv = STRALLOC_ZERO ; + stralloc dst = STRALLOC_ZERO ; + char name[strlen(res->sa.s + res->name) + 2] ; + auto_strings(name, ".", res->sa.s + res->name) ; + + if (!env_prepare_for_write(&dst, &oenv, res)) + log_dieu(LOG_EXIT_SYS, "prepare environment") ; + + write_environ(name, oenv.s, dst.s) ; + + /** Reads all files from the directory */ + if (!environ_clean_envfile(&env, dst.s)) + log_dieu(LOG_EXIT_SYS, "read environment") ; + + if (!environ_remove_unexport(&env, &env)) + log_dieu(LOG_EXIT_SYS, "remove exclamation mark from environment variables") ; + + stralloc_free(&oenv) ; + stralloc_free(&dst) ; + } + + if (!sastr_split_string_in_nline(&env)) + log_dieu(LOG_EXIT_SYS, "rebuild environment") ; + + n = env_len((const char *const *)environ) + 1 + byte_count(env.s,env.len,'\0') ; + char const *newenv[n + 1] ; + + if (!env_merge (newenv, n ,(const char *const *)environ,env_len((const char *const *)environ), env.s, env.len)) + log_dieu(LOG_EXIT_SYS, "build environment") ; + + if (chdir(pwd) < 0) + log_dieu(LOG_EXIT_SYS, "chdir to: ", pwd) ; + + m = 0 ; + newargv[m++] = config_script ; + + if (res->regex.configure > 0) + newargv[m++] = res->sa.s + res->regex.configure ; + + newargv[m++] = 0 ; + + log_info("launch script configure of module: ", name) ; + + pid = child_spawn0(newargv[0], newargv, newenv) ; + + if (waitpid_nointr(pid, &wstat, 0) < 0) + log_dieusys(LOG_EXIT_SYS, "wait for: ", config_script) ; + + if (wstat) + log_dieu(LOG_EXIT_SYS, "run: ", config_script) ; + } + + stralloc_free(&env) ; +} diff --git a/src/lib66/module/regex_get_file_name.c b/src/lib66/module/regex_get_file_name.c new file mode 100644 index 0000000000000000000000000000000000000000..b97fab05dabcf69d9faf5212fab2a7ec42b33553 --- /dev/null +++ b/src/lib66/module/regex_get_file_name.c @@ -0,0 +1,48 @@ +/* + * regex_get_file_name.c + * + * Copyright (c) 2018-2022 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 <stddef.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/mill.h> + +#include <skalibs/stralloc.h> + +/* 0 filename undefine + * -1 system error + * should return at least 2 meaning :: no file define*/ +int regex_get_file_name(char *filename, char const *str) +{ + log_flow() ; + + int r ; + size_t pos = 0 ; + stralloc kp = STRALLOC_ZERO ; + + parse_mill_t MILL_GET_COLON = { + .open = ':', .close = ':', + .skip = " \t\r", .skiplen = 3, + .forceclose = 1, + .inner.debug = "get_colon" } ; + + r = mill_element(&kp, str, &MILL_GET_COLON, &pos) ; + if (r == -1) + log_dieu(LOG_EXIT_SYS, "get filename of line: ", str) ; + + auto_strings(filename, kp.s) ; + + stralloc_free(&kp) ; + return pos ; +} diff --git a/src/lib66/module/regex_get_regex.c b/src/lib66/module/regex_get_regex.c new file mode 100644 index 0000000000000000000000000000000000000000..717d51e408d3065b5fd8f0496c2c244cfe7c60a3 --- /dev/null +++ b/src/lib66/module/regex_get_regex.c @@ -0,0 +1,33 @@ +/* + * regex_get_regex.c + * + * Copyright (c) 2018-2022 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <string.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> + +void regex_get_regex(char *regex, char const *str) +{ + log_flow() ; + + size_t len = strlen(str) ; + int pos = get_len_until(str,'=') ; + if (!pos || pos == -1) + log_dieu(LOG_EXIT_SYS, "get regex string of line: ", str) ; + pos++ ; // remove '=' + char tmp[len + 1] ; + memcpy(tmp,str + pos,len-pos) ; + tmp[len-pos] = 0 ; + auto_strings(regex,tmp) ; +} diff --git a/src/lib66/module/regex_get_replace.c b/src/lib66/module/regex_get_replace.c new file mode 100644 index 0000000000000000000000000000000000000000..61ef2817a63514509a2f049e9931e144fd3f94db --- /dev/null +++ b/src/lib66/module/regex_get_replace.c @@ -0,0 +1,31 @@ +/* + * regex_get_replace.c + * + * Copyright (c) 2018-2022 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <string.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> + +void regex_get_replace(char *replace, char const *str) +{ + log_flow() ; + + int pos = get_len_until(str,'=') ; + if (!pos || pos == -1) + log_dieu(LOG_EXIT_SYS,"replace string of line: ", str) ; + char tmp[pos + 1] ; + memcpy(tmp,str,pos) ; + tmp[pos] = 0 ; + auto_strings(replace, tmp) ; +} diff --git a/src/lib66/module/regex_rename.c b/src/lib66/module/regex_rename.c new file mode 100644 index 0000000000000000000000000000000000000000..0fcce188f9f7c6831a24b3a3dc77128c4b12c78f --- /dev/null +++ b/src/lib66/module/regex_rename.c @@ -0,0 +1,94 @@ +/* + * regex_rename.c + * + * Copyright (c) 2018-2022 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 <unistd.h> +#include <stdio.h> + +#include <oblibs/log.h> +#include <oblibs/sastr.h> + +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +#include <66/module.h> +#include <66/constants.h> + +void regex_rename(stralloc *list, resolve_service_t *res, uint32_t element) +{ + log_flow() ; + + stralloc sa = STRALLOC_ZERO ; + + if (!element) + return ; + + if (!sastr_clean_string(&sa, res->sa.s + element)) + log_dieu(LOG_EXIT_SYS, "clean string") ; + + size_t pos = 0, idx = 0, salen = sa.len ; + char t[sa.len] ; + + sastr_to_char(t, &sa) ; + + for (; pos < salen ; pos += strlen(t + pos) + 1) { + + idx = 0 ; + char *line = t + pos ; + char replace[SS_MAX_PATH] = { 0 } ; + char regex[SS_MAX_PATH] = { 0 } ; + + regex_get_replace(replace,line) ; + + regex_get_regex(regex,line) ; + + FOREACH_SASTR(list, idx) { + + sa.len = 0 ; + char *str = list->s + idx ; + size_t len = strlen(str) ; + char dname[len + 1] ; + + if (!ob_dirname(dname, str)) + log_dieu(LOG_EXIT_SYS, "get dirname of: ", str) ; + + if (!sabasename(&sa, str, len)) + log_dieu(LOG_EXIT_SYS, "get basename of: ", str) ; + + if (!stralloc_0(&sa)) + log_die_nomem("stralloc") ; + + if (!sastr_replace(&sa, replace, regex)) + log_dieu(LOG_EXIT_SYS, "replace: ", replace, " by: ", regex, " in file: ", str) ; + + if (!stralloc_0(&sa)) + log_die_nomem("stralloc") ; + + char new[len + sa.len + 1] ; + auto_strings(new, dname, sa.s) ; + + /** do not try to rename the same directory */ + if (strcmp(str, new)) { + + log_trace("rename: ", str, " to: ", new) ; + if (rename(str, new) == -1) + //log_warnusys( "rename: ", str, " to: ", new) ; + log_dieusys(LOG_EXIT_SYS, "rename: ", str, " to: ", new) ; + + break ; + } + } + } + stralloc_free(&sa) ; +} diff --git a/src/lib66/module/regex_replace.c b/src/lib66/module/regex_replace.c new file mode 100644 index 0000000000000000000000000000000000000000..d6ce2762583999391e634ca75b26fd308b211219 --- /dev/null +++ b/src/lib66/module/regex_replace.c @@ -0,0 +1,111 @@ +/* + * regex_replace.c + * + * Copyright (c) 2018-2022 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <string.h> + +#include <oblibs/log.h> +#include <oblibs/sastr.h> +#include <oblibs/files.h> + +#include <skalibs/stralloc.h> + +#include <66/resolve.h> +#include <66/utils.h> +#include <66/constants.h> +#include <66/module.h> + +void regex_replace(stralloc *list, resolve_service_t *res) +{ + log_flow() ; + + int r ; + size_t pos = 0, idx = 0 ; + + stralloc frontend = STRALLOC_ZERO ; + stralloc sa = STRALLOC_ZERO ; + + if (!res->regex.ninfiles) + return ; + + if (!sastr_clean_string(&sa, res->sa.s + res->regex.infiles)) + log_dieu(LOG_EXIT_SYS, "clean string") ; + + FOREACH_SASTR(list, pos) { + + frontend.len = idx = 0 ; + char *str = list->s + pos ; + size_t len = strlen(str) ; + char bname[len + 1] ; + char dname[len + 1] ; + + if (!ob_basename(bname, str)) + log_dieu(LOG_EXIT_SYS, "get basename of: ", str) ; + + if (!ob_dirname(dname, str)) + log_dieu(LOG_EXIT_SYS, "get dirname of: ", str) ; + + //log_trace("read service file of: ", dname, bname) ; + r = read_svfile(&frontend, bname, dname) ; + if (!r) + log_dieusys(LOG_EXIT_SYS, "read file: ", str) ; + else if (r == -1) + continue ; + + { + FOREACH_SASTR(&sa, idx) { + + int all = 0, fpos = 0 ; + char const *line = sa.s + idx ; + size_t linelen = strlen(line) ; + char filename[SS_MAX_SERVICE_NAME + 1] ; + char replace[linelen + 1] ; + char regex[linelen + 1] ; + + if (linelen >= SS_MAX_PATH_LEN) + log_die(LOG_EXIT_SYS, "limit exceeded in service: ", res->sa.s + res->name) ; + + if ((line[0] != ':') || (get_sep_before(line + 1, ':', '=') < 0)) + log_die(LOG_EXIT_SYS, "bad format in line: ", line, " of key @infiles field") ; + + memset(filename, 0, SS_MAX_SERVICE_NAME + 1) ; + memset(replace, 0, linelen + 1) ; + memset(regex, 0, linelen + 1) ; + + fpos = regex_get_file_name(filename, line) ; + if (fpos < 3) all = 1 ; + + regex_get_replace(replace, line + fpos) ; + + regex_get_regex(regex, line + fpos) ; + + if (!strcmp(bname, filename) || all) { + + if (!sastr_replace_all(&frontend, replace, regex)) + log_dieu(LOG_EXIT_SYS, "replace: ", replace, " by: ", regex, " in file: ", str) ; + + if (!stralloc_0(&frontend)) + log_dieusys(LOG_EXIT_SYS, "stralloc") ; + + frontend.len-- ; + + if (!file_write_unsafe(dname, bname, frontend.s, frontend.len)) + log_dieusys(LOG_EXIT_SYS, "write: ", dname, "/", bname) ; + } + } + } + } + + stralloc_free(&frontend) ; + stralloc_free(&sa) ; +} diff --git a/src/lib66/parse/deps-lib/deps b/src/lib66/parse/deps-lib/deps index 0313af57d79c8f2a9d1c3a112f57a061cabbdfdd..d6d430e87c1b4cef5d4ee1c996d774eec41a245f 100644 --- a/src/lib66/parse/deps-lib/deps +++ b/src/lib66/parse/deps-lib/deps @@ -10,7 +10,6 @@ parse_error.o parse_frontend.o parse_line_g.o parse_mandatory.o -parse_module.o parse_parentheses.o parse_section.o parse_service.o diff --git a/src/lib66/parse/parse_module.c b/src/lib66/parse/parse_module.c deleted file mode 100644 index 9b871e68328b027565f584a3b2defbd44eb87478..0000000000000000000000000000000000000000 --- a/src/lib66/parse/parse_module.c +++ /dev/null @@ -1,638 +0,0 @@ -/* - * parse_module.c - * - * Copyright (c) 2018-2022 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 <errno.h> -#include <pwd.h> -#include <sys/types.h> -#include <unistd.h> //chdir, unlink -#include <stdlib.h> -#include <stdio.h> //rename - -#include <oblibs/string.h> -#include <oblibs/log.h> -#include <oblibs/mill.h> -#include <oblibs/sastr.h> -#include <oblibs/types.h> -#include <oblibs/directory.h> -#include <oblibs/environ.h> -#include <oblibs/files.h> - -#include <skalibs/stralloc.h> -#include <skalibs/djbunix.h> //hiercopy -#include <skalibs/env.h> //hiercopy -#include <skalibs/bytestr.h> - -#include <66/write.h> -#include <66/utils.h> -#include <66/environ.h> -#include <66/resolve.h> -#include <66/service.h> -#include <66/constants.h> -#include <66/utils.h> - -#define SS_MODULE_CONFIG_DIR "/configure" -#define SS_MODULE_CONFIG_DIR_LEN (sizeof SS_MODULE_CONFIG_DIR - 1) -#define SS_MODULE_CONFIG_SCRIPT "configure" -#define SS_MODULE_CONFIG_SCRIPT_LEN (sizeof SS_MODULE_CONFIG_SCRIPT - 1) -#define SS_MODULE_SERVICE "/service" -#define SS_MODULE_SERVICE_LEN (sizeof SS_MODULE_SERVICE - 1) -#define SS_MODULE_SERVICE_INSTANCE "/service@" -#define SS_MODULE_SERVICE_INSTANCE_LEN (sizeof SS_MODULE_SERVICE_INSTANCE - 1) - -static void instance_splitname_to_char(char *store, char const *name, int len, int what) -{ - log_flow() ; - - char const *copy ; - size_t tlen = len + 1, clen = 0 ; - - char template[tlen + 1] ; - memcpy(template,name,tlen) ; - template[tlen] = 0 ; - - copy = name + tlen ; - - if (!what) { - - auto_strings(store, template) ; - - } else { - - clen = strlen(copy) ; - memcpy(store, copy, clen) ; - store[clen] = 0 ; - } - -} - -static void parse_module_check_dir(char const *src,char const *dir) -{ - log_flow() ; - - int r ; - size_t srclen = strlen(src) ; - size_t dirlen = strlen(dir) ; - - char t[srclen + dirlen + 1] ; - auto_strings(t, src, dir) ; - - r = scan_mode(t,S_IFDIR) ; - if (r < 0) { - errno = EEXIST ; - log_diesys(LOG_EXIT_ZERO, "conflicting format of: ", t) ; - } - - if (!r) - if (!dir_create_parent(t, 0755)) - log_dieusys(LOG_EXIT_ZERO, "create directory: ", t) ; -} - -static void parse_module_check_name(char const *src, char const *name) -{ - log_flow() ; - - char basename[strlen(src)] ; - int insta = -1 ; - - if (!ob_basename(basename, src)) - log_dieu(LOG_EXIT_SYS, "get basename of: ", src) ; - - insta = instance_check(name) ; - - if (insta <= 0) - log_die(LOG_EXIT_SYS, "invalid module instance name: ", name) ; - - if (basename[0] != '@') - log_die(LOG_EXIT_USER, "invalid directory name for module: ", name, " -- directory name must start with a '@' character") ; -} - -/* 0 filename undefine - * -1 system error - * should return at least 2 meaning :: no file define*/ -static int regex_get_file_name(char *filename, char const *str) -{ - log_flow() ; - - int r ; - size_t pos = 0 ; - stralloc kp = STRALLOC_ZERO ; - - parse_mill_t MILL_GET_COLON = { - .open = ':', .close = ':', - .skip = " \t\r", .skiplen = 3, - .forceclose = 1, - .inner.debug = "get_colon" } ; - - r = mill_element(&kp, str, &MILL_GET_COLON, &pos) ; - if (r == -1) - log_dieu(LOG_EXIT_SYS, "get filename of line: ", str) ; - - auto_strings(filename, kp.s) ; - - stralloc_free(&kp) ; - return pos ; -} - -static void regex_get_replace(char *replace, char const *str) -{ - log_flow() ; - - int pos = get_len_until(str,'=') ; - if (!pos || pos == -1) - log_dieu(LOG_EXIT_SYS,"replace string of line: ", str) ; - char tmp[pos + 1] ; - memcpy(tmp,str,pos) ; - tmp[pos] = 0 ; - auto_strings(replace, tmp) ; -} - -static void regex_get_regex(char *regex, char const *str) -{ - log_flow() ; - - size_t len = strlen(str) ; - int pos = get_len_until(str,'=') ; - if (!pos || pos == -1) - log_dieu(LOG_EXIT_SYS, "get regex string of line: ", str) ; - pos++ ; // remove '=' - char tmp[len + 1] ; - memcpy(tmp,str + pos,len-pos) ; - tmp[len-pos] = 0 ; - auto_strings(regex,tmp) ; -} - -static void get_list(stralloc *list, char const *src, char const *name, mode_t mode) -{ - log_flow() ; - - list->len = 0 ; - char const *exclude[2] = { SS_MODULE_CONFIG_DIR + 1, 0 } ; - - char t[strlen(src) + 1] ; - - auto_strings(t, src) ; - - if (!sastr_dir_get_recursive(list, t, exclude, mode, 1)) - log_dieusys(LOG_EXIT_SYS,"get file(s) of module: ", name) ; - -} - -static void regex_replace(stralloc *list, resolve_service_t *res) -{ - log_flow() ; - - int r ; - size_t pos = 0, idx = 0 ; - - stralloc frontend = STRALLOC_ZERO ; - stralloc sa = STRALLOC_ZERO ; - - if (!res->regex.ninfiles) - return ; - - if (!sastr_clean_string(&sa, res->sa.s + res->regex.infiles)) - log_dieu(LOG_EXIT_SYS, "clean string") ; - - FOREACH_SASTR(list, pos) { - - frontend.len = idx = 0 ; - char *str = list->s + pos ; - size_t len = strlen(str) ; - char bname[len + 1] ; - char dname[len + 1] ; - - if (!ob_basename(bname, str)) - log_dieu(LOG_EXIT_SYS, "get basename of: ", str) ; - - if (!ob_dirname(dname, str)) - log_dieu(LOG_EXIT_SYS, "get dirname of: ", str) ; - - //log_trace("read service file of: ", dname, bname) ; - r = read_svfile(&frontend, bname, dname) ; - if (!r) - log_dieusys(LOG_EXIT_SYS, "read file: ", str) ; - else if (r == -1) - continue ; - - { - FOREACH_SASTR(&sa, idx) { - - int all = 0, fpos = 0 ; - char const *line = sa.s + idx ; - size_t linelen = strlen(line) ; - char filename[SS_MAX_SERVICE_NAME + 1] ; - char replace[linelen + 1] ; - char regex[linelen + 1] ; - - if (linelen >= SS_MAX_PATH_LEN) - log_die(LOG_EXIT_SYS, "limit exceeded in service: ", res->sa.s + res->name) ; - - if ((line[0] != ':') || (get_sep_before(line + 1, ':', '=') < 0)) - log_die(LOG_EXIT_SYS, "bad format in line: ", line, " of key @infiles field") ; - - memset(filename, 0, SS_MAX_SERVICE_NAME + 1) ; - memset(replace, 0, linelen + 1) ; - memset(regex, 0, linelen + 1) ; - - fpos = regex_get_file_name(filename, line) ; - if (fpos < 3) all = 1 ; - - regex_get_replace(replace, line + fpos) ; - - regex_get_regex(regex, line + fpos) ; - - if (!strcmp(bname, filename) || all) { - - if (!sastr_replace_all(&frontend, replace, regex)) - log_dieu(LOG_EXIT_SYS, "replace: ", replace, " by: ", regex, " in file: ", str) ; - - if (!stralloc_0(&frontend)) - log_dieusys(LOG_EXIT_SYS, "stralloc") ; - - frontend.len-- ; - - if (!file_write_unsafe(dname, bname, frontend.s, frontend.len)) - log_dieusys(LOG_EXIT_SYS, "write: ", dname, "/", bname) ; - } - } - } - } - - stralloc_free(&frontend) ; - stralloc_free(&sa) ; -} - -static void regex_rename(stralloc *list, resolve_service_t *res, uint32_t element) -{ - log_flow() ; - - stralloc sa = STRALLOC_ZERO ; - - if (!element) - return ; - - if (!sastr_clean_string(&sa, res->sa.s + element)) - log_dieu(LOG_EXIT_SYS, "clean string") ; - - size_t pos = 0, idx = 0, salen = sa.len ; - char t[sa.len] ; - - sastr_to_char(t, &sa) ; - - for (; pos < salen ; pos += strlen(t + pos) + 1) { - - idx = 0 ; - char *line = t + pos ; - char replace[SS_MAX_PATH] = { 0 } ; - char regex[SS_MAX_PATH] = { 0 } ; - - regex_get_replace(replace,line) ; - - regex_get_regex(regex,line) ; - - FOREACH_SASTR(list, idx) { - - sa.len = 0 ; - char *str = list->s + idx ; - size_t len = strlen(str) ; - char dname[len + 1] ; - - if (!ob_dirname(dname, str)) - log_dieu(LOG_EXIT_SYS, "get dirname of: ", str) ; - - if (!sabasename(&sa, str, len)) - log_dieu(LOG_EXIT_SYS, "get basename of: ", str) ; - - if (!stralloc_0(&sa)) - log_die_nomem("stralloc") ; - - if (!sastr_replace(&sa, replace, regex)) - log_dieu(LOG_EXIT_SYS, "replace: ", replace, " by: ", regex, " in file: ", str) ; - - if (!stralloc_0(&sa)) - log_die_nomem("stralloc") ; - - char new[len + sa.len + 1] ; - auto_strings(new, dname, sa.s) ; - - /** do not try to rename the same directory */ - if (strcmp(str, new)) { - - log_trace("rename: ", str, " to: ", new) ; - if (rename(str, new) == -1) - //log_warnusys( "rename: ", str, " to: ", new) ; - log_dieusys(LOG_EXIT_SYS, "rename: ", str, " to: ", new) ; - - break ; - } - } - } - stralloc_free(&sa) ; -} - -static void regex_configure(resolve_service_t *res, ssexec_t *info, char const *path, char const *name) -{ - log_flow() ; - - int wstat, r ; - pid_t pid ; - size_t clen = res->regex.configure > 0 ? 1 : 0 ; - size_t pathlen = strlen(path), n ; - - stralloc env = STRALLOC_ZERO ; - - char const *newargv[2 + clen] ; - unsigned int m = 0 ; - - char pwd[pathlen + 1 + SS_MODULE_CONFIG_DIR_LEN + 1] ; - auto_strings(pwd, path, "/", SS_MODULE_CONFIG_DIR + 1) ; - - char config_script[pathlen + 1 + SS_MODULE_CONFIG_DIR_LEN + 1 + SS_MODULE_CONFIG_SCRIPT_LEN + 1] ; - auto_strings(config_script, path, "/", SS_MODULE_CONFIG_DIR + 1, "/", SS_MODULE_CONFIG_SCRIPT) ; - - r = scan_mode(config_script, S_IFREG) ; - if (r > 0) - { - /** export ssexec_t info value on the environment */ - { - char verbo[UINT_FMT]; - verbo[uid_fmt(verbo, VERBOSITY)] = 0 ; - if (!auto_stra(&env, \ - "MOD_NAME=", name, "\n", \ - "MOD_BASE=", res->sa.s + res->path.home, "\n", \ - "MOD_LIVE=", res->sa.s + res->live.livedir, "\n", \ - "MOD_SCANDIR=", res->sa.s + res->live.scandir, "\n", \ - "MOD_TREENAME=", res->sa.s + res->treename, "\n", \ - "MOD_OWNER=", res->sa.s + res->ownerstr, "\n", \ - "MOD_COLOR=", info->opt_color ? "1" : "0", "\n", \ - "MOD_VERBOSITY=", verbo, "\n", \ - "MOD_MODULE_DIR=", path, "\n", \ - "MOD_SKEL_DIR=", SS_SKEL_DIR, "\n", \ - "MOD_SERVICE_SYSDIR=", SS_SERVICE_SYSDIR, "\n", \ - "MOD_SERVICE_ADMDIR=", SS_SERVICE_ADMDIR, "\n", \ - "MOD_SERVICE_ADMCONFDIR=", SS_SERVICE_ADMCONFDIR, "\n", \ - "MOD_MODULE_SYSDIR=", SS_MODULE_SYSDIR, "\n", \ - "MOD_MODULE_ADMDIR=", SS_MODULE_ADMDIR, "\n", \ - "MOD_SCRIPT_SYSDIR=", SS_SCRIPT_SYSDIR, "\n", \ - "MOD_USER_DIR=", SS_USER_DIR, "\n", \ - "MOD_SERVICE_USERDIR=", SS_SERVICE_USERDIR, "\n", \ - "MOD_SERVICE_USERCONFDIR=", SS_SERVICE_USERCONFDIR, "\n", \ - "MOD_MODULE_USERDIR=", SS_MODULE_USERDIR, "\n", \ - "MOD_SCRIPT_USERDIR=", SS_SCRIPT_USERDIR, "\n")) - log_dieu(LOG_EXIT_SYS, "append environment variables") ; - } - - /** environment is not mandatory */ - if (res->environ.env > 0) - { - stralloc oenv = STRALLOC_ZERO ; - stralloc dst = STRALLOC_ZERO ; - char name[strlen(res->sa.s + res->name) + 2] ; - auto_strings(name, ".", res->sa.s + res->name) ; - - if (!env_prepare_for_write(&dst, &oenv, res)) - log_dieu(LOG_EXIT_SYS, "prepare environment") ; - - write_environ(name, oenv.s, dst.s) ; - - /** Reads all files from the directory */ - if (!environ_clean_envfile(&env, dst.s)) - log_dieu(LOG_EXIT_SYS, "read environment") ; - - if (!environ_remove_unexport(&env, &env)) - log_dieu(LOG_EXIT_SYS, "remove exclamation mark from environment variables") ; - - stralloc_free(&oenv) ; - stralloc_free(&dst) ; - } - - if (!sastr_split_string_in_nline(&env)) - log_dieu(LOG_EXIT_SYS, "rebuild environment") ; - - n = env_len((const char *const *)environ) + 1 + byte_count(env.s,env.len,'\0') ; - char const *newenv[n + 1] ; - - if (!env_merge (newenv, n ,(const char *const *)environ,env_len((const char *const *)environ), env.s, env.len)) - log_dieu(LOG_EXIT_SYS, "build environment") ; - - if (chdir(pwd) < 0) - log_dieu(LOG_EXIT_SYS, "chdir to: ", pwd) ; - - m = 0 ; - newargv[m++] = config_script ; - - if (res->regex.configure > 0) - newargv[m++] = res->sa.s + res->regex.configure ; - - newargv[m++] = 0 ; - - log_info("launch script configure of module: ", name) ; - - pid = child_spawn0(newargv[0], newargv, newenv) ; - - if (waitpid_nointr(pid, &wstat, 0) < 0) - log_dieusys(LOG_EXIT_SYS, "wait for: ", config_script) ; - - if (wstat) - log_dieu(LOG_EXIT_SYS, "run: ", config_script) ; - } - - stralloc_free(&env) ; -} - -void parse_module(resolve_service_t *res, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint8_t force) -{ - log_flow() ; - - int r, insta = -1 ; - unsigned int residx = 0 ; - size_t pos = 0, pathlen = 0 ; - char *name = res->sa.s + res->name ; - char *src = res->sa.s + res->path.frontend ; - char path[SS_MAX_PATH_LEN] ; - char ainsta[strlen(name)] ; - stralloc list = STRALLOC_ZERO ; - resolve_wrapper_t_ref wres = 0 ; - - log_trace("parse module: ", name) ; - - insta = instance_check(name) ; - instance_splitname_to_char(ainsta, name, insta, 0) ; - - size_t prefixlen = strlen(ainsta) ; - size_t len = prefixlen + SS_MAX_SERVICE_NAME ; - - char prefix[len + 1] ; - auto_strings(prefix, ainsta) ; - //prefix[insta] = '-' ; - prefix[insta] = 0 ; - - if (!getuid()) { - - auto_strings(path, SS_SERVICE_ADMDIR, name) ; - - } else { - - if (!set_ownerhome_stack(path)) - log_dieusys(LOG_EXIT_SYS, "unable to find the home directory of the user") ; - - pathlen = strlen(path) ; - auto_strings(path + pathlen, SS_SERVICE_USERDIR, name) ; - } - - uint8_t conf = res->environ.env_overwrite ; - - /** Check the validity of the module directory. - * The frontend file of the module must be located in - * a directory with a name in the format @template_name: - * - frontend file -> scandir@ - * - directory name containing the frontend service file -> @scandir */ - parse_module_check_name(src, name) ; - - /** check mandatory directories - * res->frontend/module_name/{configure,service,service@} */ - parse_module_check_dir(src, SS_MODULE_CONFIG_DIR) ; - parse_module_check_dir(src, SS_MODULE_SERVICE) ; - parse_module_check_dir(src, SS_MODULE_SERVICE_INSTANCE) ; - - r = scan_mode(path, S_IFDIR) ; - if (r == -1) { - errno = EEXIST ; - log_dieusys(LOG_EXIT_SYS, "conflicting format of: ", path) ; - - } else if (!r) { - - if (!hiercopy(src, path)) - log_dieusys(LOG_EXIT_SYS, "copy: ", src, " to: ", path) ; - - } else { - - /** Must reconfigure all services of the module */ - if (force < 2) { - - log_warn("skip configuration of the module: ", name, " -- already configured") ; - goto deps ; - } - - if (rm_rf(path) < 0) - log_dieusys (LOG_EXIT_SYS, "remove: ", path) ; - - if (!hiercopy(src, path)) - log_dieusys(LOG_EXIT_SYS,"copy: ", src, " to: ", path) ; - } - - pathlen = strlen(path) ; - /** remove the original service frontend file inside the copied directory - * to avoid double frontend service file for a same service.*/ - auto_strings(path + pathlen, "/", ainsta) ; - - if (unlink(path) < 0) - log_dieusys(LOG_EXIT_ZERO, "unlink: ", path) ; - - path[pathlen] = 0 ; - - /** contents */ - get_list(&list, path, name, S_IFREG) ; - regex_replace(&list, res) ; - - /** directories */ - get_list(&list, path, name, S_IFDIR) ; - regex_rename(&list, res, res->regex.directories) ; - - /** filename */ - get_list(&list, path, name, S_IFREG) ; - regex_rename(&list, res, res->regex.files) ; - - /** configure script */ - regex_configure(res, info, path, name) ; - - deps: - - list.len = 0 ; - - if (!auto_stra(&list, path)) - log_die_nomem("stralloc") ; - - char t[list.len] ; - - sastr_to_char(t, &list) ; - - list.len = 0 ; - char const *exclude[3] = { SS_MODULE_CONFIG_DIR + 1, SS_MODULE_SERVICE_INSTANCE + 1, 0 } ; - if (!sastr_dir_get_recursive(&list, t, exclude, S_IFREG, 1)) - log_dieusys(LOG_EXIT_SYS, "get file(s) of module: ", name) ; - - char l[list.len] ; - size_t llen = list.len ; - - sastr_to_char(l, &list) ; - - list.len = 0 ; - - for (pos = 0 ; pos < llen ; pos += strlen(l + pos) + 1) { - - char *dname = l + pos ; - char ainsta[pathlen + SS_MODULE_SERVICE_INSTANCE_LEN + 1 + SS_MAX_SERVICE_NAME + 1] ; - size_t namelen = strlen(dname) ; - char bname[namelen] ; - - if (!ob_basename(bname,dname)) - log_dieu(LOG_EXIT_SYS, "find basename of: ", dname) ; - - if (instance_check(bname) > 0) { - auto_strings(ainsta, path, SS_MODULE_SERVICE_INSTANCE, "/", bname) ; - dname = ainsta ; - } - - if (!sastr_add_string(&list, bname)) - log_die_nomem("stralloc") ; - - if (!strcmp(name, bname)) - log_die(LOG_EXIT_SYS, "cyclic call detected -- ", name, " call ", bname) ; - - /** nothing to do with the exit code */ - parse_frontend(dname, ares, areslen, info, force, conf, &residx, path, bname) ; - - wres = resolve_set_struct(DATA_SERVICE, &ares[residx]) ; - - ares[residx].inmodule = resolve_add_string(wres, prefix - 1) ; - } - - char deps[list.len] ; - - sastr_to_char(deps, &list) ; - - llen = list.len ; - - list.len = 0 ; - - /* rebuild the dependencies list incorporating the services defined inside - * the module. */ - - if (res->dependencies.ndepends) - if (!sastr_clean_string(&list, res->sa.s + res->dependencies.depends)) - log_dieu(LOG_EXIT_SYS, "clean string") ; - - for (pos = 0 ; pos < llen ; pos += strlen(deps + pos) + 1) - if (!sastr_add_string(&list, deps + pos)) - log_die_nomem("stralloc") ; - - wres = resolve_set_struct(DATA_SERVICE, res) ; - - res->dependencies.depends = parse_compute_list(wres, &list, &res->dependencies.ndepends, 0) ; - - free(wres) ; - stralloc_free(&list) ; -}