/* * ssexec_inresolve.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 <wchar.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 <66/resolve.h> #include <66/ssexec.h> #include <66/tree.h> #include <66/service.h> #include <66/info.h> #include <66/utils.h> #include <66/constants.h> #include <66/config.h> #include <66/state.h> #define MAXOPTS 84 static wchar_t const field_suffix[] = L" :" ; static char fields[INFO_NKEY][INFO_FIELD_MAXLEN] = {{ 0 }} ; static inline unsigned int lookup (char const *const *table, char const *data) { log_flow() ; unsigned int i = 0 ; for (; table[i] ; i++) if (!strcmp(data, table[i])) break ; return i ; } static inline unsigned int parse_what (char const *str) { log_flow() ; static char const *const table[] = { "service", "tree", 0 } ; unsigned int i = lookup(table, str) ; if (!table[i]) i = 2 ; return i ; } 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) { info_display_string(fields[0], res->sa.s, res->name, 0) ; info_display_string(fields[1], res->sa.s, res->description, 1) ; info_display_string(fields[2], res->sa.s, res->version, 1) ; info_display_int(fields[3], res->type) ; info_display_int(fields[4], res->notify) ; info_display_int(fields[5], res->maxdeath) ; info_display_int(fields[6], res->earlier) ; info_display_string(fields[7], res->sa.s, res->hiercopy, 1) ; info_display_string(fields[8], res->sa.s, res->intree, 1) ; info_display_string(fields[9], res->sa.s, res->ownerstr, 1) ; info_display_int(fields[10], res->owner) ; info_display_string(fields[11], res->sa.s, res->treename, 1) ; info_display_string(fields[12], res->sa.s, res->user, 1) ; info_display_string(fields[13], res->sa.s, res->inmodule, 1) ; info_display_string(fields[14], res->sa.s, res->path.home, 1) ; info_display_string(fields[15], res->sa.s, res->path.frontend, 1) ; info_display_string(fields[16], res->sa.s, res->path.tree, 1) ; info_display_string(fields[17], res->sa.s, res->path.status, 1) ; info_display_string(fields[18], res->sa.s, res->dependencies.depends, 1) ; info_display_string(fields[19], res->sa.s, res->dependencies.requiredby, 1) ; info_display_string(fields[20], res->sa.s, res->dependencies.optsdeps, 1) ; info_display_int(fields[21], res->dependencies.ndepends) ; info_display_int(fields[22], res->dependencies.nrequiredby) ; info_display_int(fields[23], res->dependencies.noptsdeps) ; info_display_string(fields[24], res->sa.s, res->execute.run.run, 1) ; info_display_string(fields[25], res->sa.s, res->execute.run.run_user, 1) ; info_display_string(fields[26], res->sa.s, res->execute.run.build, 1) ; info_display_string(fields[27], res->sa.s, res->execute.run.shebang, 1) ; info_display_string(fields[28], res->sa.s, res->execute.run.runas, 1) ; info_display_string(fields[29], res->sa.s, res->execute.finish.run, 1) ; info_display_string(fields[30], res->sa.s, res->execute.finish.run_user, 1) ; info_display_string(fields[31], res->sa.s, res->execute.finish.build, 1) ; info_display_string(fields[32], res->sa.s, res->execute.finish.shebang, 1) ; info_display_string(fields[33], res->sa.s, res->execute.finish.runas, 1) ; info_display_int(fields[34], res->execute.timeout.kill) ; info_display_int(fields[35], res->execute.timeout.finish) ; info_display_int(fields[36], res->execute.timeout.up) ; info_display_int(fields[37], res->execute.timeout.down) ; info_display_int(fields[38], res->execute.down) ; info_display_int(fields[39], res->execute.downsignal) ; info_display_string(fields[40], res->sa.s, res->live.livedir, 1) ; info_display_string(fields[41], res->sa.s, res->live.scandir, 1) ; info_display_string(fields[42], res->sa.s, res->live.statedir, 1) ; info_display_string(fields[43], res->sa.s, res->live.eventdir, 1) ; info_display_string(fields[44], res->sa.s, res->live.notifdir, 1) ; info_display_string(fields[45], res->sa.s, res->live.supervisedir, 1) ; info_display_string(fields[46], res->sa.s, res->live.fdholderdir, 1) ; info_display_string(fields[47], res->sa.s, res->live.oneshotddir, 1) ; info_display_string(fields[48], res->sa.s, res->logger.name, 1) ; info_display_string(fields[49], res->sa.s, res->logger.destination, 1) ; info_display_int(fields[50], res->logger.backup) ; info_display_int(fields[51], res->logger.maxsize) ; info_display_int(fields[52], res->logger.timestamp) ; info_display_string(fields[53], res->sa.s, res->logger.execute.run.run, 1) ; info_display_string(fields[54], res->sa.s, res->logger.execute.run.run_user, 1) ; info_display_string(fields[55], res->sa.s, res->logger.execute.run.build, 1) ; info_display_string(fields[56], res->sa.s, res->logger.execute.run.shebang, 1) ; info_display_string(fields[57], res->sa.s, res->logger.execute.run.runas, 1) ; info_display_int(fields[58], res->logger.execute.timeout.kill) ; info_display_int(fields[59], res->logger.execute.timeout.finish) ; info_display_string(fields[60], res->sa.s, res->environ.env, 1) ; info_display_string(fields[61], res->sa.s, res->environ.envdir, 1) ; info_display_int(fields[62], res->environ.env_overwrite) ; info_display_string(fields[63], res->sa.s, res->regex.configure, 1) ; info_display_string(fields[64], res->sa.s, res->regex.directories, 1) ; info_display_string(fields[65], res->sa.s, res->regex.files, 1) ; info_display_string(fields[66], res->sa.s, res->regex.infiles, 1) ; info_display_int(fields[67], res->regex.ndirectories) ; info_display_int(fields[68], res->regex.nfiles) ; info_display_int(fields[69], res->regex.ninfiles) ; } int ssexec_inresolve(int argc, char const *const *argv, ssexec_t *info) { int found = 0, what = 0 ; uint8_t master = 0 ; stralloc sa = STRALLOC_ZERO ; char const *svname = 0 ; char const *treename = info->treename.s ; char atree[SS_MAX_TREENAME + 1] ; argc-- ; argv++ ; if (argc < 2) log_usage(usage_inresolve) ; what = parse_what(*argv) ; if (what == 2) log_usage(usage_inresolve) ; argv++; argc--; svname = *argv ; if (!set_ownersysdir(&sa, getuid())) log_dieu(LOG_EXIT_SYS, "set owner directory") ; if (!what) { char service_buf[MAXOPTS][INFO_FIELD_MAXLEN] = { "name", "description" , "version", "type", "notify", "maxdeath", "earlier", "hiercopy", "intree", "ownerstr", "owner", "treename", "user" , "inmodule", // 14 "home", "frontend", "tree", "status", //18 "depends", "requiredby", "optsdeps", "ndepends", "nrequiredby", "noptsdeps", // 24 "run", "run_user", "run_build", "run_shebang", "run_runas", "finish", "finish_user", "finish_build", "finish_shebang", "finish_runas", "timeoutkill", "timeoutfinish", "timeoutup", "timeoutdown", "down", "downsignal", // 40 "livedir", "scandir", "statedir", "eventdir", "notifdir", "supervisedir", "fdholderdir", "oneshotddir", //48 "logname" , "logdestination" , "logbackup" , "logmaxsize" , "logtimestamp" , "logrun" , "logrun_user" , "logrun_build" , "logrun_shebang" , "logrun_runas" , "logtimeoutkill", "logtimeoutfinish", // 60 "env", "envdir", "env_overwrite", // 63 "configure", "directories", "files", "infiles", "ndirectories", "nfiles", "ninfiles", // 70 "classic", "bundle", "oneshot", "module", "enabled", "disabled", "contents", "nclassic", "nbundle", "noneshot", "nmodule", "nenabled", "ndisabled", "ncontents" // 84 } ; resolve_wrapper_t_ref wres = 0 ; resolve_service_t res = RESOLVE_SERVICE_ZERO ; resolve_service_master_t mres = RESOLVE_SERVICE_MASTER_ZERO ; if (!strcmp(svname, SS_MASTER + 1)) { master = 1 ; wres = resolve_set_struct(DATA_SERVICE_MASTER, &mres) ; } else { wres = resolve_set_struct(DATA_SERVICE, &res) ; } if (!master) { found = service_is_g(atree, svname, STATE_FLAGS_ISPARSED) ; if (found == -1) log_dieu(LOG_EXIT_SYS, "get information of service: ", svname, " -- please a bug report") ; else if (!found) log_die(LOG_EXIT_USER, "unknown service: ", svname) ; if (!resolve_read_g(wres, sa.s, svname)) log_dieusys(LOG_EXIT_SYS,"read resolve file") ; } else { char solve[sa.len + SS_SYSTEM_LEN + 1 + strlen(treename) + SS_SVDIRS_LEN + 1] ; auto_strings(solve, sa.s, SS_SYSTEM, "/", treename, SS_SVDIRS) ; if (!resolve_read(wres, solve, SS_MASTER + 1)) log_dieusys(LOG_EXIT_SYS,"read resolve file") ; } info_field_align(service_buf, fields, field_suffix,MAXOPTS) ; if (!master) { info_display_service_field(&res) ; } else { info_display_string(fields[0], mres.sa.s, mres.name, 0) ; info_display_string(fields[70], mres.sa.s, mres.classic, 1) ; info_display_string(fields[71], mres.sa.s, mres.bundle, 1) ; info_display_string(fields[72], mres.sa.s, mres.oneshot, 1) ; info_display_string(fields[73], mres.sa.s, mres.module, 1) ; info_display_string(fields[74], mres.sa.s, mres.enabled, 1) ; info_display_string(fields[75], mres.sa.s, mres.disabled, 1) ; info_display_string(fields[76], mres.sa.s, mres.contents, 1) ; info_display_int(fields[77], mres.nclassic) ; info_display_int(fields[78], mres.nbundle) ; info_display_int(fields[79], mres.noneshot) ; info_display_int(fields[80], mres.nmodule) ; info_display_int(fields[81], mres.nenabled) ; info_display_int(fields[82], mres.ndisabled) ; info_display_int(fields[83], mres.ncontents) ; } resolve_free(wres) ; } else { char tree_buf[MAXOPTS][INFO_FIELD_MAXLEN] = { "name", "depends" , "requiredby", "allow", "groups", "contents", "ndepends", "nrequiredby", "nallow", "ngroups", "ncontents", "init" , "disen", // 13 // Master "enabled", "current", "contents", "nenabled", "ncontents" // 18 } ; resolve_wrapper_t_ref wres = 0 ; resolve_tree_t tres = RESOLVE_TREE_ZERO ; resolve_tree_master_t mres = RESOLVE_TREE_MASTER_ZERO ; if (!strcmp(argv[0], SS_MASTER + 1)) { master = 1 ; wres = resolve_set_struct(DATA_TREE_MASTER, &mres) ; } else { wres = resolve_set_struct(DATA_TREE, &tres) ; } found = tree_isvalid(sa.s, svname) ; if (found < 0) log_diesys(LOG_EXIT_SYS, "invalid tree directory") ; if (!found) log_dieusys(LOG_EXIT_SYS, "find tree: ", svname) ; if (!resolve_read_g(wres, sa.s, svname)) log_dieusys(LOG_EXIT_SYS, "read resolve file") ; info_field_align(tree_buf, fields, field_suffix,MAXOPTS) ; if (!master) { info_display_string(fields[0], tres.sa.s, tres.name, 0) ; info_display_string(fields[1], tres.sa.s, tres.depends, 1) ; info_display_string(fields[2], tres.sa.s, tres.requiredby, 1) ; info_display_string(fields[3], tres.sa.s, tres.allow, 1) ; info_display_string(fields[4], tres.sa.s, tres.groups, 1) ; info_display_string(fields[5], tres.sa.s, tres.contents, 1) ; info_display_int(fields[6], tres.ndepends) ; info_display_int(fields[7], tres.nrequiredby) ; info_display_int(fields[8], tres.nallow) ; info_display_int(fields[9], tres.ngroups) ; info_display_int(fields[10], tres.ncontents) ; info_display_int(fields[11], tres.init) ; info_display_int(fields[12], tres.disen) ; } else { info_display_string(fields[0], mres.sa.s, mres.name, 1) ; info_display_string(fields[3], mres.sa.s, mres.allow, 1) ; info_display_string(fields[13], mres.sa.s, mres.enabled, 1) ; info_display_string(fields[14], mres.sa.s, mres.current, 1) ; info_display_string(fields[15], mres.sa.s, mres.contents, 1) ; info_display_int(fields[16], mres.nenabled) ; info_display_int(fields[17], mres.ncontents) ; } resolve_free(wres) ; } stralloc_free(&sa) ; return 0 ; }