/* * ssexec_resolve.c * * Copyright (c) 2018-2024 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 <wchar.h> #include <stdint.h> #include <oblibs/log.h> #include <oblibs/sastr.h> #include <oblibs/string.h> #include <oblibs/types.h> #include <skalibs/types.h> #include <skalibs/stralloc.h> #include <skalibs/lolstdio.h> #include <skalibs/buffer.h> #include <skalibs/sgetopt.h> #include <66/resolve.h> #include <66/ssexec.h> #include <66/service.h> #include <66/info.h> #include <66/constants.h> #include <66/config.h> #include <66/state.h> #define MAXOPTS 75 static wchar_t const field_suffix[] = L" :" ; static char fields[INFO_NKEY][INFO_FIELD_MAXLEN] = {{ 0 }} ; static void info_display_string(char const *field, char const *str, uint32_t element, uint8_t check) { info_display_field_name(field) ; if (check && !element) { if (!bprintf(buffer_1,"%s%s", log_color->warning, "None")) log_dieusys(LOG_EXIT_SYS, "write to stdout") ; } else { if (!buffer_puts(buffer_1, str + element)) log_dieusys(LOG_EXIT_SYS, "write to stdout") ; } if (buffer_putsflush(buffer_1, "\n") == -1) log_dieusys(LOG_EXIT_SYS, "write to stdout") ; } static void info_display_int(char const *field, uint32_t element) { info_display_field_name(field) ; char ui[UINT_FMT] ; ui[uint_fmt(ui, element)] = 0 ; if (!buffer_puts(buffer_1, ui)) log_dieusys(LOG_EXIT_SYS, "write to stdout") ; if (buffer_putsflush(buffer_1, "\n") == -1) log_dieusys(LOG_EXIT_SYS, "write to stdout") ; } static void info_display_service_field(resolve_service_t *res) { uint8_t m = 0 ; info_display_string(fields[m++], res->sa.s, res->name, 0) ; info_display_string(fields[m++], res->sa.s, res->description, 1) ; info_display_string(fields[m++], res->sa.s, res->version, 1) ; info_display_int(fields[m++], res->type) ; info_display_int(fields[m++], res->notify) ; info_display_int(fields[m++], res->maxdeath) ; info_display_int(fields[m++], res->earlier) ; info_display_string(fields[m++], res->sa.s, res->hiercopy, 1) ; info_display_string(fields[m++], res->sa.s, res->intree, 1) ; info_display_string(fields[m++], res->sa.s, res->ownerstr, 1) ; info_display_int(fields[m++], res->owner) ; info_display_string(fields[m++], res->sa.s, res->treename, 1) ; info_display_string(fields[m++], res->sa.s, res->user, 1) ; info_display_string(fields[m++], res->sa.s, res->inns, 1) ; info_display_int(fields[m++], res->enabled) ; info_display_string(fields[m++], res->sa.s, res->path.home, 1) ; info_display_string(fields[m++], res->sa.s, res->path.frontend, 1) ; info_display_string(fields[m++], res->sa.s, res->path.servicedir, 1) ; info_display_string(fields[m++], res->sa.s, res->dependencies.depends, 1) ; info_display_string(fields[m++], res->sa.s, res->dependencies.requiredby, 1) ; info_display_string(fields[m++], res->sa.s, res->dependencies.optsdeps, 1) ; info_display_string(fields[m++], res->sa.s, res->dependencies.contents, 1) ; info_display_int(fields[m++], res->dependencies.ndepends) ; info_display_int(fields[m++], res->dependencies.nrequiredby) ; info_display_int(fields[m++], res->dependencies.noptsdeps) ; info_display_int(fields[m++], res->dependencies.ncontents) ; info_display_string(fields[m++], res->sa.s, res->execute.run.run, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.run.run_user, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.run.build, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.run.shebang, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.run.runas, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.finish.run, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.finish.run_user, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.finish.build, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.finish.shebang, 1) ; info_display_string(fields[m++], res->sa.s, res->execute.finish.runas, 1) ; info_display_int(fields[m++], res->execute.timeout.kill) ; info_display_int(fields[m++], res->execute.timeout.finish) ; info_display_int(fields[m++], res->execute.timeout.up) ; info_display_int(fields[m++], res->execute.timeout.down) ; info_display_int(fields[m++], res->execute.down) ; info_display_int(fields[m++], res->execute.downsignal) ; info_display_string(fields[m++], res->sa.s, res->live.livedir, 1) ; info_display_string(fields[m++], res->sa.s, res->live.status, 1) ; info_display_string(fields[m++], res->sa.s, res->live.servicedir, 1) ; info_display_string(fields[m++], res->sa.s, res->live.scandir, 1) ; info_display_string(fields[m++], res->sa.s, res->live.statedir, 1) ; info_display_string(fields[m++], res->sa.s, res->live.eventdir, 1) ; info_display_string(fields[m++], res->sa.s, res->live.notifdir, 1) ; info_display_string(fields[m++], res->sa.s, res->live.supervisedir, 1) ; info_display_string(fields[m++], res->sa.s, res->live.fdholderdir, 1) ; info_display_string(fields[m++], res->sa.s, res->live.oneshotddir, 1) ; info_display_string(fields[m++], res->sa.s, res->logger.name, 1) ; info_display_string(fields[m++], res->sa.s, res->logger.destination, 1) ; info_display_int(fields[m++], res->logger.backup) ; info_display_int(fields[m++], res->logger.maxsize) ; info_display_int(fields[m++], res->logger.timestamp) ; info_display_int(fields[m++], res->logger.want) ; info_display_string(fields[m++], res->sa.s, res->logger.execute.run.run, 1) ; info_display_string(fields[m++], res->sa.s, res->logger.execute.run.run_user, 1) ; info_display_string(fields[m++], res->sa.s, res->logger.execute.run.build, 1) ; info_display_string(fields[m++], res->sa.s, res->logger.execute.run.shebang, 1) ; info_display_string(fields[m++], res->sa.s, res->logger.execute.run.runas, 1) ; info_display_int(fields[m++], res->logger.execute.timeout.kill) ; info_display_int(fields[m++], res->logger.execute.timeout.finish) ; info_display_string(fields[m++], res->sa.s, res->environ.env, 1) ; info_display_string(fields[m++], res->sa.s, res->environ.envdir, 1) ; info_display_int(fields[m++], res->environ.env_overwrite) ; info_display_string(fields[m++], res->sa.s, res->regex.configure, 1) ; info_display_string(fields[m++], res->sa.s, res->regex.directories, 1) ; info_display_string(fields[m++], res->sa.s, res->regex.files, 1) ; info_display_string(fields[m++], res->sa.s, res->regex.infiles, 1) ; info_display_int(fields[m++], res->regex.ndirectories) ; info_display_int(fields[m++], res->regex.nfiles) ; info_display_int(fields[m], res->regex.ninfiles) ; } int ssexec_resolve(int argc, char const *const *argv, ssexec_t *info) { int r = 0 ; char const *svname = 0 ; resolve_service_t res = RESOLVE_SERVICE_ZERO ; resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ; char service_buf[MAXOPTS][INFO_FIELD_MAXLEN] = { "name", "description" , "version", "type", "notify", "maxdeath", "earlier", "hiercopy", "intree", "ownerstr", "owner", "treename", "user" , "inns", "enabled", "home", "frontend", "servicedir", "depends", "requiredby", "optsdeps", "contents", "ndepends", "nrequiredby", "noptsdeps", "ncontents", "run", "run_user", "run_build", "run_shebang", "run_runas", "finish", "finish_user", "finish_build", "finish_shebang", "finish_runas", "timeoutkill", "timeoutfinish", "timeoutup", "timeoutdown", "down", "downsignal", "livedir", "status", "servicedir", "scandir", "statedir", "eventdir", "notifdir", "supervisedir", "fdholderdir", "oneshotddir", "logname" , "logdestination" , "logbackup" , "logmaxsize" , "logtimestamp" , "logwant", "logrun" , "logrun_user" , "logrun_build" , "logrun_shebang" , "logrun_runas" , "logtimeoutkill", "logtimeoutfinish", "env", "envdir", "env_overwrite", "configure", "directories", "files", "infiles", "ndirectories", "nfiles", "ninfiles" } ; { subgetopt l = SUBGETOPT_ZERO ; for (;;) { int opt = subgetopt_r(argc, argv, OPTS_RESOLVE, &l) ; if (opt == -1) break ; switch (opt) { case 'h' : info_help(info->help, info->usage) ; return 0 ; default : log_usage(info->usage, "\n", info->help) ; } } argc -= l.ind ; argv += l.ind ; } if (argc < 1) log_usage(info->usage, "\n", info->help) ; svname = *argv ; r = service_is_g(svname, STATE_FLAGS_ISPARSED) ; if (r == -1) log_dieu(LOG_EXIT_SYS, "get information of service: ", svname, " -- please a bug report") ; else if (!r || r == STATE_FLAGS_FALSE) log_die(LOG_EXIT_USER, "service: ", svname, " is not parsed -- try to parse it first using '66 parse ", svname, "'") ; if (resolve_read_g(wres, info->base.s, svname) <= 0) log_dieusys(LOG_EXIT_SYS, "read resolve file") ; info_field_align(service_buf, fields, field_suffix,MAXOPTS) ; info_display_service_field(&res) ; resolve_free(wres) ; return 0 ; }