From a27767daa48eaafab5623cb046e1a367910c161f Mon Sep 17 00:00:00 2001 From: obarun <eric@obarun.org> Date: Thu, 29 Sep 2022 20:42:56 +1100 Subject: [PATCH] revamp of the write process --- src/include/66/write.h | 31 +++ src/lib66/write/deps-lib/deps | 14 ++ src/lib66/write/write_classic.c | 57 +++++ src/lib66/write/write_common.c | 136 ++++++++++++ src/lib66/write/write_environ.c | 36 +++ src/lib66/write/write_execute_scripts.c | 104 +++++++++ src/lib66/write/write_execute_scripts_user.c | 60 +++++ src/lib66/write/write_logger.c | 217 +++++++++++++++++++ src/lib66/write/write_oneshot.c | 41 ++++ src/lib66/write/write_service.c | 102 +++++++++ src/lib66/write/write_uint.c | 30 +++ 11 files changed, 828 insertions(+) create mode 100644 src/include/66/write.h create mode 100644 src/lib66/write/deps-lib/deps create mode 100644 src/lib66/write/write_classic.c create mode 100644 src/lib66/write/write_common.c create mode 100644 src/lib66/write/write_environ.c create mode 100644 src/lib66/write/write_execute_scripts.c create mode 100644 src/lib66/write/write_execute_scripts_user.c create mode 100644 src/lib66/write/write_logger.c create mode 100644 src/lib66/write/write_oneshot.c create mode 100644 src/lib66/write/write_service.c create mode 100644 src/lib66/write/write_uint.c diff --git a/src/include/66/write.h b/src/include/66/write.h new file mode 100644 index 00000000..b4b24dc5 --- /dev/null +++ b/src/include/66/write.h @@ -0,0 +1,31 @@ +/* + * write.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_WRITE_H +#define SS_WRITE_H + +#include <stdint.h> +#include <66/service.h> + +extern int write_services(resolve_service_t *res, char const *workdir, uint8_t force) ; +extern void write_classic(resolve_service_t *res, char const *dst, uint8_t force) ; +extern void write_common(resolve_service_t *res, char const *dst) ; +extern void write_environ(char const *name, char const *contents, char const *dst) ; +extern void write_execute_scripts(resolve_service_t *res, resolve_service_addon_scripts_t *scripts, char const *file, char const *dst) ; +extern void write_execute_scripts_user(resolve_service_t *res, resolve_service_addon_scripts_t *scripts, char const *file, char const *dst) ; +extern void write_logger(resolve_service_t *res, char const *destination, uint8_t force) ; +extern void write_oneshot(resolve_service_t *res, char const *dst) ; +extern void write_uint(char const *dst, char const *name, uint32_t ui) ; + +#endif diff --git a/src/lib66/write/deps-lib/deps b/src/lib66/write/deps-lib/deps new file mode 100644 index 00000000..bd387c82 --- /dev/null +++ b/src/lib66/write/deps-lib/deps @@ -0,0 +1,14 @@ +write_classic.o +write_common.o +write_environ.o +write_execute_scripts.o +write_execute_scripts_user.o +write_logger.o +write_oneshot.o +write_service.o +write_uint.o +-ls6 +-loblibs +-lexecline +-lskarnet + diff --git a/src/lib66/write/write_classic.c b/src/lib66/write/write_classic.c new file mode 100644 index 00000000..e582c0a7 --- /dev/null +++ b/src/lib66/write/write_classic.c @@ -0,0 +1,57 @@ +/* + * write_classic.c + * + * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <stdint.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> + +#include <66/service.h> +#include <66/write.h> + +/* dst e.g. /var/lib/66/system/<tree>/servicedirs/svc/<name> */ + +void write_classic(resolve_service_t *res, char const *dst, uint8_t force) +{ + log_flow() ; + + /**notification,timeout, ... */ + write_common(res, dst) ; + + /** run file */ + write_execute_scripts(res, &res->execute.run, "run", dst) ; + + /** finish file */ + if (res->execute.finish.run_user) + write_execute_scripts(res, &res->execute.finish, "finish", dst) ; + + /** run.user file */ + write_execute_scripts_user(res, &res->execute.run, "run.user", dst) ; + + /** finish.user file */ + if (res->execute.finish.run_user) + write_execute_scripts_user(res, &res->execute.finish, "finish.user", dst) ; + + /** logger */ + if (res->logger.name) { + + char destination[strlen(dst)] ; + + if (!ob_dirname(destination, dst)) + log_dieu(LOG_EXIT_SYS, "get dirname of: ", dst) ; + + write_logger(res, destination, force) ; + } + +} diff --git a/src/lib66/write/write_common.c b/src/lib66/write/write_common.c new file mode 100644 index 00000000..e0d35104 --- /dev/null +++ b/src/lib66/write/write_common.c @@ -0,0 +1,136 @@ +/* + * write_common.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 <errno.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/files.h> +#include <oblibs/sastr.h> +#include <oblibs/directory.h> +#include <oblibs/types.h> + +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +#include <66/service.h> +#include <66/write.h> +#include <66/constants.h> +#include <66/environ.h> +#include <66/enum.h> + +void write_common(resolve_service_t *res, char const *dst) +{ + log_flow() ; + + char *time = 0 ; + size_t dstlen = strlen(dst) ; + + /** down file */ + if (res->execute.down) + if (!file_create_empty(dst, "down", 0644)) + log_dieusys(LOG_EXIT_SYS, "create down file") ; + + /** notification-fd */ + if (res->notify) + write_uint(dst, SS_NOTIFICATION, res->notify) ; + + /** timeout family + * + * Only write timeout file for classic service. + * All others services are read directly through + * the resolve file at start process. */ + if (res->execute.timeout.kill) + write_uint(dst, "timeout-kill", res->execute.timeout.kill) ; + + if (res->execute.timeout.finish) + write_uint(dst, "timeout-finish", res->execute.timeout.finish) ; + + /** max-death-tally */ + if (res->maxdeath) + write_uint(dst, SS_MAXDEATHTALLY, res->maxdeath) ; + + /** down-signal */ + if (res->execute.downsignal) + write_uint(dst, "down-signal", res->execute.downsignal) ; + + /** environment + * environment for module is already written by the parse_module() function */ + if (res->environ.env && res->type != TYPE_MODULE) { + + stralloc dst = STRALLOC_ZERO ; + stralloc contents = 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, &contents, res)) + log_dieu(LOG_EXIT_SYS, "prepare environment for: ", res->sa.s + res->name) ; + + write_environ(name, contents.s, dst.s) ; + + stralloc_free(&dst) ; + stralloc_free(&contents) ; + } + + /** hierarchy copy */ + if (res->hiercopy) { + + int r ; + size_t pos = 0 ; + stralloc sa = STRALLOC_ZERO ; + char *src = res->sa.s + res->path.frontend ; + size_t srclen = strlen(src) ; + + if (!sastr_clean_string(&sa, res->sa.s + res->hiercopy)) + log_dieu(LOG_EXIT_SYS, "clean string") ; + + FOREACH_SASTR(&sa, pos) { + + char *what = sa.s + pos ; + size_t whatlen = strlen(what) ; + char tmp[SS_MAX_PATH_LEN + 1] ; + char basedir[srclen + 1] ; + + if (!ob_dirname(basedir, src)) + log_dieu(LOG_EXIT_SYS, "get dirname of: ", src) ; + + if (what[0] == '.') { + + if (!dir_beabsolute(tmp, src)) + log_dieusys(LOG_EXIT_SYS, "find absolute path of: ", what) ; + + } else { + + auto_strings(tmp, what) ; + } + + r = scan_mode(tmp, S_IFDIR) ; + if (r <= 0) { + + r = scan_mode(tmp, S_IFREG) ; + if (!r) + log_dieusys(LOG_EXIT_SYS, "find: ", tmp) ; + if (r < 0) { + errno = ENOTSUP ; + log_diesys(LOG_EXIT_SYS, "invalid format of: ", tmp) ; + } + } + + if (!hiercopy(tmp, dst)) + log_dieusys(LOG_EXIT_SYS, "copy: ", tmp, " to: ", dst) ; + } + } +} diff --git a/src/lib66/write/write_environ.c b/src/lib66/write/write_environ.c new file mode 100644 index 00000000..46482ef3 --- /dev/null +++ b/src/lib66/write/write_environ.c @@ -0,0 +1,36 @@ +/* + * write_environ.c + * + * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <string.h> + +#include <oblibs/log.h> +#include <oblibs/files.h> +#include <oblibs/types.h> + +void write_environ(char const *name, char const *contents, char const *dst) +{ + log_flow() ; + + int r ; + size_t len = strlen(contents) ; + + r = scan_mode(dst,S_IFDIR) ; + if (r < 0) + log_die(LOG_EXIT_SYS, "conflicting format of the environment directory: ", dst) ; + else if (!r) + log_dieusys(LOG_EXIT_SYS, "find environment directory: ", dst) ; + + if (!file_write_unsafe(dst, name, contents, len)) + log_dieusys(LOG_EXIT_SYS, "create file: ", dst, "/", name) ; +} diff --git a/src/lib66/write/write_execute_scripts.c b/src/lib66/write/write_execute_scripts.c new file mode 100644 index 00000000..4bab4205 --- /dev/null +++ b/src/lib66/write/write_execute_scripts.c @@ -0,0 +1,104 @@ +/* + * write_execute_scripts.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 <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/files.h> + +#include <66/service.h> +#include <66/config.h> +#include <66/constants.h> +#include <66/enum.h> + +#include <s6/config.h> + +#ifndef FAKELEN +#define FAKELEN strlen(run) +#endif + +void write_execute_scripts(resolve_service_t *res, resolve_service_addon_scripts_t *scripts, char const *file, char const *dst) +{ + log_flow() ; + + char write[strlen(dst) + 1 + strlen(file) + 1] ; + char *shebang = "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ; + size_t shebanglen = strlen(shebang) ; + char run[shebanglen + strlen(res->sa.s + res->live.fdholderdir) + SS_FDHOLDER_PIPENAME_LEN + strlen(res->sa.s + res->name) + SS_LOG_SUFFIX_LEN + strlen(S6_BINPREFIX) + strlen(res->sa.s + scripts->runas) + strlen(res->sa.s + res->environ.envdir) + SS_SYM_VERSION_LEN + (SS_MAX_PATH*2) + SS_MAX_PATH + strlen(file) + 117 + 1] ; + + auto_strings(write, dst, "/", file) ; + + /** shebang */ + auto_strings(run, shebang) ; + + if (res->logger.name && res->type != TYPE_ONESHOT) + auto_strings(run + FAKELEN, \ + "fdmove 1 0\n", \ + "s6-fdholder-retrieve ", \ + res->sa.s + res->live.fdholderdir, "/s ", \ + "\"" SS_FDHOLDER_PIPENAME "w-", \ + res->sa.s + res->name, SS_LOG_SUFFIX "\"\n", \ + "fdswap 0 1\n") ; + + + /** environ */ + if (res->environ.env) + auto_strings(run + FAKELEN, res->sa.s + res->environ.envdir, SS_SYM_VERSION "\n") ; + + /** log redirection for oneshot service */ + if (res->logger.name && res->type == TYPE_ONESHOT) { + + char verbo[UINT_FMT] ; + verbo[uint_fmt(verbo, VERBOSITY)] = 0 ; + + size_t namelen = strlen(res->sa.s + res->name) ; + size_t syslen = res->owner ? strlen(res->sa.s + res->path.home) + 1 + strlen(SS_LOGGER_USERDIR) : 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] ; + + if (!res->logger.destination) { + + if (res->owner) + + auto_strings(dstlog, res->sa.s + res->path.home, "/", SS_LOGGER_USERDIR, res->sa.s + res->name) ; + + else + + auto_strings(dstlog, SS_LOGGER_SYSDIR, res->sa.s + res->name) ; + + } else { + + auto_strings(dstlog, res->sa.s + res->logger.destination) ; + } + + auto_strings(run + FAKELEN, "execl-toc -v", verbo, " -d ", dstlog, " -m 0755\n") ; + auto_strings(run + FAKELEN, "redirfd -a 1 ", dstlog, "/current\n") ; + } + + /** runas */ + if (!res->owner && scripts->runas) + auto_strings(run + FAKELEN, S6_BINPREFIX "s6-setuidgid ", res->sa.s + scripts->runas, "\n") ; + + auto_strings(run + FAKELEN, "./", file, ".user") ; + + if (!file_write_unsafe(dst, file, run, FAKELEN)) + log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/", file) ; + + if (chmod(write, 0755) < 0) + log_dieusys(LOG_EXIT_SYS, "chmod", write) ; + +} diff --git a/src/lib66/write/write_execute_scripts_user.c b/src/lib66/write/write_execute_scripts_user.c new file mode 100644 index 00000000..65ee0fff --- /dev/null +++ b/src/lib66/write/write_execute_scripts_user.c @@ -0,0 +1,60 @@ +/* + * write_execute_scripts_user.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 <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/files.h> + +#include <66/service.h> +#include <66/config.h> +#include <66/enum.h> + +#ifndef FAKELEN +#define FAKELEN strlen(run) +#endif + +void write_execute_scripts_user(resolve_service_t *res, resolve_service_addon_scripts_t *scripts, char const *file, char const *dst) +{ + log_flow() ; + + char *shebang = scripts->shebang ? res->sa.s + scripts->shebang : SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ; + size_t shebanglen = strlen(shebang) ; + size_t scriptlen = strlen(res->sa.s + scripts->run_user) ; + char run[2 + shebanglen + 15 + scriptlen + 1] ; + int build = !strcmp(res->sa.s + scripts->build, "custom") ? 1 : 0 ; + char write[strlen(dst) + 1 + strlen(file) + 1] ; + + auto_strings(write, dst, "/", file) ; + + auto_strings(run, "#!") ; + + if (build && scripts->shebang) + auto_strings(run + FAKELEN, res->sa.s + scripts->shebang, "\n") ; + else + auto_strings(run + FAKELEN, \ + SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n", + "fdmove -c 2 1\n") ; + + auto_strings(run + FAKELEN, res->sa.s + scripts->run_user) ; + + if (!file_write_unsafe(dst, file, run, FAKELEN)) + log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/", file) ; + + if (chmod(write, 0755) < 0) + log_dieusys(LOG_EXIT_SYS, "chmod", write) ; + +} diff --git a/src/lib66/write/write_logger.c b/src/lib66/write/write_logger.c new file mode 100644 index 00000000..46bcd69b --- /dev/null +++ b/src/lib66/write/write_logger.c @@ -0,0 +1,217 @@ +/* + * write_logger.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 <sys/types.h> +#include <sys/stat.h> + +#include <oblibs/string.h> +#include <oblibs/log.h> +#include <oblibs/types.h> +#include <oblibs/directory.h> +#include <oblibs/files.h> + +#include <skalibs/types.h> + +#include <66/config.h> +#include <66/write.h> +#include <66/enum.h> +#include <66/utils.h> +#include <s6/config.h> +#include <66/constants.h> + +#include <s6/config.h> + +#ifndef FAKELEN +#define FAKELEN strlen(run) +#endif + +/** @destination -> /var/lib/66/system/<tree>/servicedirs/svc/ */ + +void write_logger(resolve_service_t *res, char const *destination, uint8_t force) +{ + log_flow() ; + + int r ; + uid_t log_uid ; + gid_t log_gid ; + uint8_t owner = res->owner ; + + int build = !strcmp(res->sa.s + res->logger.execute.run.build, "custom") ? 1 : 0 ; + + char *pmax = 0 ; + char *pback = 0 ; + char max[UINT32_FMT] ; + char back[UINT32_FMT] ; + char *timestamp = 0 ; + int itimestamp = SS_LOGGER_TIMESTAMP ; + char *logrunner = res->logger.execute.run.runas ? res->sa.s + res->logger.execute.run.runas : SS_LOGGER_RUNNER ; + + char dst[strlen(destination) + 1 + strlen(res->sa.s + res->logger.name) + 1] ; + auto_strings(dst, destination, "/", res->sa.s + res->logger.name) ; + + r = scan_mode(dst, S_IFDIR) ; + if (r && force) { + + if (!dir_rm_rf(dst)) + log_dieusys(LOG_EXIT_SYS, "delete: ", dst) ; + + } else if (r) { + + log_warn("ignoring ", dst, " -- already exist") ; + return ; + } + + if (!dir_create_parent(dst, 0755)) + log_dieusys(LOG_EXIT_SYS, "create directory: ", dst) ; + + if (res->logger.execute.timeout.kill) + write_uint(dst, "timeout-kill", res->logger.execute.timeout.kill) ; + + if (res->logger.execute.timeout.finish) + write_uint(dst, "timeout-finish", res->logger.execute.timeout.finish) ; + + /** timestamp */ + if (res->logger.timestamp != 3) + timestamp = res->logger.timestamp == TIME_NONE ? "" : res->logger.timestamp == TIME_ISO ? "T" : "t" ; + else + timestamp = itimestamp == TIME_NONE ? "" : itimestamp == TIME_ISO ? "T" : "t" ; + + /** backup */ + if (res->logger.backup) { + + back[uint32_fmt(back,res->logger.backup)] = 0 ; + pback = back ; + + } else + pback = "3" ; + + /** file size */ + if (res->logger.maxsize) { + + max[uint32_fmt(max,res->logger.maxsize)] = 0 ; + pmax = max ; + + } else + pmax = "1000000" ; + + /** log destination */ + size_t namelen = strlen(res->sa.s + res->name) ; + size_t syslen = res->owner ? strlen(res->sa.s + res->path.home) + 1 + strlen(SS_LOGGER_USERDIR) : 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] ; + + if (!res->logger.destination) { + + if (res->owner) + + auto_strings(dstlog, res->sa.s + res->path.home, "/", SS_LOGGER_USERDIR, res->sa.s + res->name) ; + + else + + auto_strings(dstlog, SS_LOGGER_SYSDIR, res->sa.s + res->name) ; + + } else { + + auto_strings(dstlog, res->sa.s + res->logger.destination) ; + } + + if (!dir_create_parent(dstlog, 0755)) + log_dieusys(LOG_EXIT_SYS, "create directory: ", dstlog) ; + + if (!owner && ((res->logger.execute.run.build == BUILD_AUTO) || (!res->logger.execute.run.build))) { + + if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) + log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ; + + if (chown(dstlog, log_uid, log_gid) == -1) + log_dieusys(LOG_EXIT_SYS, "chown: ", dstlog) ; + } + + { + /** dst/run file */ + char *shebang = res->logger.execute.run.shebang ? res->sa.s + res->logger.execute.run.shebang : "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ; + + char run[strlen(shebang) + strlen(res->sa.s + res->live.fdholderdir) + SS_FDHOLDER_PIPENAME_LEN + strlen(res->sa.s + res->logger.name) + strlen(S6_BINPREFIX) + strlen(res->sa.s + res->logger.execute.run.runas) + 53 + 1] ; + + auto_strings(run, \ + shebang, \ + "s6-fdholder-retrieve ", \ + res->sa.s + res->live.fdholderdir, "/s ", \ + "\"" SS_FDHOLDER_PIPENAME "r-", \ + res->sa.s + res->logger.name, "\"\n") ; + + /** runas */ + if (!res->owner && res->logger.execute.run.runas) + auto_strings(run + FAKELEN, S6_BINPREFIX "s6-setuidgid ", res->sa.s + res->logger.execute.run.runas, "\n") ; + + auto_strings(run + FAKELEN, "./run.user\n") ; + + if (!file_write_unsafe(dst, "run", run, FAKELEN)) + log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/run.user") ; + + char write[strlen(dst) + 5] ; + auto_strings(write, dst, "/run") ; + + if (chmod(write, 0755) < 0) + log_dieusys(LOG_EXIT_SYS, "chmod", write) ; + } + + if (!build) { + + char *shebang = "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ; + size_t shebanglen = strlen(shebang) ; + + char run[shebanglen + strlen(S6_BINPREFIX) + strlen(logrunner) + strlen(pback) + strlen(timestamp) + strlen(pmax) + strlen(dstlog) + 45 + 1] ; + + auto_strings(run, \ + shebang, \ + "fdmove -c 2 1\n") ; + + if (!owner) + auto_strings(run + FAKELEN, S6_BINPREFIX "s6-setuidgid ", logrunner, "\n") ; + + auto_strings(run + FAKELEN, "s6-log ") ; + + if (SS_LOGGER_NOTIFY) + auto_strings(run + FAKELEN, "-d3 ") ; + + auto_strings(run + FAKELEN, "n", pback, " ") ; + + if (res->logger.timestamp < TIME_NONE) + auto_strings(run + FAKELEN, timestamp, " ") ; + + auto_strings(run + FAKELEN, "s", pmax, " ", dstlog, "\n") ; + + if (!file_write_unsafe(dst, "run.user", run, FAKELEN)) + log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/run.user") ; + + /** notification fd */ + if (SS_LOGGER_NOTIFY) + write_uint(dst, SS_NOTIFICATION, 3) ; + + } else { + + if (!file_write_unsafe(dst, "run.user", res->sa.s + res->logger.execute.run.run_user, strlen(res->sa.s + res->logger.execute.run.run_user))) + log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/run.user") ; + } + + char write[strlen(dst) + 10] ; + auto_strings(write, dst, "/run.user") ; + + if (chmod(write, 0755) < 0) + log_dieusys(LOG_EXIT_SYS, "chmod", write) ; +} diff --git a/src/lib66/write/write_oneshot.c b/src/lib66/write/write_oneshot.c new file mode 100644 index 00000000..673f975e --- /dev/null +++ b/src/lib66/write/write_oneshot.c @@ -0,0 +1,41 @@ +/* + * write_oneshot.c + * + * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <oblibs/log.h> + +#include <66/service.h> +#include <66/write.h> + +void write_oneshot(resolve_service_t *res, char const *dst) +{ + log_flow() ; + + /**notification,timeout, ... */ + write_common(res, dst) ; + + /** run file */ + write_execute_scripts(res, &res->execute.run, "up", dst) ; + + /** finish file */ + if (res->execute.finish.run_user) + write_execute_scripts(res, &res->execute.finish, "down", dst) ; + + /** run.user file */ + write_execute_scripts_user(res, &res->execute.run, "up.user", dst) ; + + /** finish.user file */ + if (res->execute.finish.run_user) + write_execute_scripts_user(res, &res->execute.finish, "down.user", dst) ; + +} diff --git a/src/lib66/write/write_service.c b/src/lib66/write/write_service.c new file mode 100644 index 00000000..d9d4c8da --- /dev/null +++ b/src/lib66/write/write_service.c @@ -0,0 +1,102 @@ +/* + * write_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 <oblibs/string.h> +#include <oblibs/log.h> +#include <oblibs/types.h> +#include <oblibs/directory.h> + +#include <66/service.h> +#include <66/resolve.h> +#include <66/enum.h> +#include <66/write.h> +#include <66/constants.h> + +/** @Return 0 on fail + * @Return 1 on success + * @Return 2 if the service is ignored + * + * @workdir -> /var/lib/66/system/<tree>/servicedirs/ + * */ +int write_services(resolve_service_t *res, char const *workdir, uint8_t force) +{ + log_flow() ; + + int r ; + size_t workdirlen = strlen(workdir) ; + char *name = res->sa.s + res->name ; + size_t namelen = strlen(name) ; + int type = res->type ; + + { + resolve_service_t fres = RESOLVE_SERVICE_ZERO ; + resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &fres) ; + + if (resolve_read_g(wres, workdir, name)) + if (fres.type != type && fres.live.disen) + log_die(LOG_EXIT_SYS, "Detection of incompatible type format for: ", name, " -- current: ", get_key_by_enum(ENUM_TYPE, type), " previous: ", get_key_by_enum(ENUM_TYPE, fres.type)) ; + + resolve_free(wres) ; + } + + char wname[workdirlen + SS_SVC_LEN + 1 + namelen + 1] ; + auto_strings(wname, workdir, SS_SVC, "/", name) ; + + r = scan_mode(wname, S_IFDIR) ; + if (r < 0) + log_die(LOG_EXIT_SYS, "unvalide source: ", wname) ; + + if ((r && force) || !r) { + + if (dir_rm_rf(wname) < 0) + log_dieusys(LOG_EXIT_SYS, "remove: ", wname) ; + + if (!dir_create_parent(wname, 0755)) + log_dieusys(LOG_EXIT_SYS, "create ", wname) ; + + } else if (r && !force) { + + log_info("Ignoring: ", name, " service: already written") ; + return 2 ; + } + + log_trace("Write service ", name, " ...") ; + + switch(type) { + + case TYPE_CLASSIC: + + write_classic(res, wname, force) ; + break ; + + case TYPE_ONESHOT: + + write_oneshot(res, wname) ; + break ; + + default: + log_die(LOG_EXIT_SYS, "unkown type: ", get_key_by_enum(ENUM_TYPE, type)) ; + } + + return 1 ; +} + + + + diff --git a/src/lib66/write/write_uint.c b/src/lib66/write/write_uint.c new file mode 100644 index 00000000..6ec3e99a --- /dev/null +++ b/src/lib66/write/write_uint.c @@ -0,0 +1,30 @@ +/* + * write_uint.c + * + * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org> + * + * All rights reserved. + * + * This file is part of Obarun. It is subject to the license terms in + * the LICENSE file found in the top-level directory of this + * distribution. + * This file may not be copied, modified, propagated, or distributed + * except according to the terms contained in the LICENSE file./ + */ + +#include <stdint.h> + +#include <oblibs/log.h> +#include <oblibs/files.h> + +#include <skalibs/types.h> + +void write_uint(char const *dst, char const *name, uint32_t ui) +{ + log_flow() ; + + char number[UINT32_FMT] ; + + if (!file_write_unsafe(dst, name, number, uint32_fmt(number,ui))) + log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/", name) ; +} -- GitLab