From 8abab7887bb2cb8910ed92b0ce4f67f6fd9cef3b Mon Sep 17 00:00:00 2001 From: obarun <eric@obarun.org> Date: Sat, 15 Oct 2022 20:39:57 +1100 Subject: [PATCH] bye bye old parser --- src/lib66/parse/parser.c | 94 --- src/lib66/parse/parser_utils.c | 1364 -------------------------------- src/lib66/parse/parser_write.c | 914 --------------------- 3 files changed, 2372 deletions(-) delete mode 100644 src/lib66/parse/parser.c delete mode 100644 src/lib66/parse/parser_utils.c delete mode 100644 src/lib66/parse/parser_write.c diff --git a/src/lib66/parse/parser.c b/src/lib66/parse/parser.c deleted file mode 100644 index ce560754..00000000 --- a/src/lib66/parse/parser.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * parser.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 <stdint.h> -//#include <stdio.h> - -#include <stddef.h> - -#include <oblibs/log.h> - -#include <skalibs/genalloc.h> - -#include <66/enum.h> -#include <66/parser.h> - -sv_alltype const sv_alltype_zero = SV_ALLTYPE_ZERO ; -sv_name_t const sv_name_zero = SV_NAME_ZERO ; -keynocheck const keynocheck_zero = KEYNOCHECK_ZERO ; - -int parser(sv_alltype *service,stralloc *src,char const *svname,int svtype) -{ - log_flow() ; - - int r ; - size_t i = 0 ; - section_t sasection = SECTION_ZERO ; - genalloc ganocheck = GENALLOC_ZERO ; - sasection.file = svname ; - - r = section_get_range(&sasection,src) ; - if (r <= 0){ - log_warnu("parse section of service file: ",svname) ; - goto err ; - } - if (!sasection.idx[SECTION_MAIN]) - { - log_warn("missing section [main] in service file: ", svname) ; - goto err ; - } - - if ((svtype != TYPE_BUNDLE && svtype != TYPE_MODULE) && !sasection.idx[SECTION_START]) - { - log_warn("missing section [start] in service file: ", svname) ; - goto err ; - } - if (!key_get_range(&ganocheck,&sasection)) goto err ; - if (!genalloc_len(keynocheck,&ganocheck)){ - log_warn("empty service file: ",svname) ; - goto err ; - } - - for (i = 0;i < genalloc_len(keynocheck,&ganocheck);i++) - { - if (!nocheck_toservice(&(genalloc_s(keynocheck,&ganocheck)[i]),svtype,service)) - { - log_warnu("keep information of service file: ",svname) ; - goto err ; - } - } - - if (!check_mandatory(service,&sasection)) goto err ; - - if ((service->opts[1]) && (svtype == TYPE_LONGRUN)) - { - if (!add_pipe(service, &deps)) - { - log_warnu("add pipe: ", keep.s+service->cname.name) ; - goto err ; - } - } - - section_free(&sasection) ; - genalloc_deepfree(keynocheck,&ganocheck,keynocheck_free) ; - return 1 ; - err: - section_free(&sasection) ; - genalloc_deepfree(keynocheck,&ganocheck,keynocheck_free) ; - return 0 ; -} - - diff --git a/src/lib66/parse/parser_utils.c b/src/lib66/parse/parser_utils.c deleted file mode 100644 index 6d6377e9..00000000 --- a/src/lib66/parse/parser_utils.c +++ /dev/null @@ -1,1364 +0,0 @@ -/* - * parser_utils.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 <66/parser.h> - -#include <string.h> -#include <unistd.h>//getuid -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> -#include <pwd.h> -#include <errno.h> - -#include <oblibs/string.h> -#include <oblibs/files.h> -#include <oblibs/log.h> -#include <oblibs/types.h> -#include <oblibs/mill.h> -#include <oblibs/environ.h> -#include <oblibs/sastr.h> - -#include <skalibs/sig.h> -#include <skalibs/genalloc.h> -#include <skalibs/stralloc.h> -#include <skalibs/bytestr.h> -#include <skalibs/diuint32.h> -#include <skalibs/djbunix.h> - -#include <66/config.h> -#include <66/constants.h> -#include <66/enum.h> -#include <66/environ.h> //env_clean_with_comment -#include <66/utils.h>//MYUID - -stralloc keep = STRALLOC_ZERO ;//sv_alltype data -stralloc deps = STRALLOC_ZERO ;//sv_name depends -genalloc gasv = GENALLOC_ZERO ;//sv_alltype general - -/********************************** - * function helper declaration - * *******************************/ - -void section_setsa(int id, stralloc_ref *p,section_t *sa) ; -int section_get_skip(char const *s,size_t pos,int nline) ; -int section_get_id(stralloc *secname, char const *string,size_t *pos,int *id) ; -int key_get_next_id(stralloc *sa, char const *string,size_t *pos) ; -int get_clean_val(keynocheck *ch) ; -int get_enum(char const *string, keynocheck *ch) ; -int get_timeout(keynocheck *ch,uint32_t *ui) ; -int get_uint(keynocheck *ch,uint32_t *ui) ; -int check_valid_runas(keynocheck *check) ; -void parse_err(int ierr,keynocheck *check) ; -int parse_line(stralloc *sa, size_t *pos) ; -int parse_bracket(stralloc *sa,size_t *pos) ; - -/********************************** - * freed function - * *******************************/ - -void sv_alltype_free(sv_alltype *sv) -{ - log_flow() ; - - stralloc_free(&sv->saenv) ; - *&sv->saenv = stralloc_zero ; -} - -void keynocheck_free(keynocheck *nocheck) -{ - log_flow() ; - - stralloc_free(&nocheck->val) ; - *nocheck = keynocheck_zero ; -} - -void section_free(section_t *sec) -{ - log_flow() ; - - stralloc_free(&sec->main) ; - stralloc_free(&sec->start) ; - stralloc_free(&sec->stop) ; - stralloc_free(&sec->logger) ; - stralloc_free(&sec->environment) ; -} - -void freed_parser(void) -{ - log_flow() ; - - stralloc_free(&keep) ; - stralloc_free(&deps) ; - for (unsigned int i = 0 ; i < genalloc_len(sv_alltype,&gasv) ; i++) - sv_alltype_free(&genalloc_s(sv_alltype,&gasv)[i]) ; - genalloc_free(sv_alltype,&gasv) ; -} - -/********************************** - * Mill utilities - * *******************************/ - -parse_mill_t MILL_FIRST_BRACKET = \ -{ \ - .search = "(", .searchlen = 1, \ - .end = ")", .endlen = 1, \ - .inner.debug = "first_bracket" } ; - -parse_mill_t MILL_GET_AROBASE_KEY = \ -{ \ - .open = '@', .close = '=', .keepopen = 1, \ - .flush = 1, \ - .forceclose = 1, .skip = " \t\r", .skiplen = 3, \ - .forceskip = 1, .inner.debug = "get_arobase_key" } ; - -parse_mill_t MILL_GET_COMMENTED_KEY = \ -{ \ - .search = "#", .searchlen = 1, \ - .end = "@", .endlen = 1, - .inner.debug = "get_commented_key" } ; - -parse_mill_t MILL_GET_SECTION_NAME = \ -{ \ - .open = '[', .close = ']', \ - .forceclose = 1, .forceskip = 1, \ - .skip = " \t\r", .skiplen = 3, \ - .inner.debug = "get_section_name" } ; - -/********************************** - * parser split function - * *******************************/ - -int section_get_range(section_t *sasection,stralloc *src) -{ - log_flow() ; - - if (!src->len) return 0 ; - size_t pos = 0, start = 0 ; - int r, n = 0, id = -1, skip = 0 ; - stralloc secname = STRALLOC_ZERO ; - stralloc_ref psasection = 0 ; - stralloc cp = STRALLOC_ZERO ; - /** be clean */ - wild_zero_all(&MILL_GET_LINE) ; - wild_zero_all(&MILL_GET_SECTION_NAME) ; - r = mill_string(&cp,src,&MILL_GET_LINE) ; - if (r == -1 || !r) goto err ; - if (!sastr_rebuild_in_nline(&cp) || - !stralloc_0(&cp)) goto err ; - - while (pos < cp.len) - { - if(secname.len && n) - { - skip = section_get_skip(cp.s,pos,MILL_GET_SECTION_NAME.inner.nline) ; - id = get_enum_by_key(secname.s) ; - section_setsa(id,&psasection,sasection) ; - if (skip) sasection->idx[id] = 1 ; - } - if (!section_get_id(&secname,cp.s,&pos,&id)) goto err ; - if (!secname.len && !n) goto err ; - if (!n) - { - skip = section_get_skip(cp.s,pos,MILL_GET_SECTION_NAME.inner.nline) ; - section_setsa(id,&psasection,sasection) ; - if (skip) sasection->idx[id] = 1 ; - start = pos ; - - if (!section_get_id(&secname,cp.s,&pos,&id)) goto err ; - if(skip) - { - r = get_rlen_until(cp.s,'\n',pos-1) ;//-1 to retrieve the end of previous line - if (r == -1) goto err ; - if (!stralloc_catb(psasection,cp.s+start,(r-start))) goto err ; - if (!stralloc_0(psasection)) goto err ; - } - n++ ; - start = pos ; - } - else - { - if (skip) - { - /** end of file do not contain section, avoid to remove the len of it if in the case*/ - if (secname.len) - { - r = get_rlen_until(cp.s,'\n',pos-1) ;//-1 to retrieve the end of previous line - if (r == -1) goto err ; - if (!stralloc_catb(psasection,cp.s+start,(r - start))) goto err ; - - } - else if (!stralloc_catb(psasection,cp.s+start,cp.len - start)) goto err ; - if (!stralloc_0(psasection)) goto err ; - } - start = pos ; - } - } - stralloc_free(&secname) ; - stralloc_free(&cp) ; - return 1 ; - err: - stralloc_free(&secname) ; - stralloc_free(&cp) ; - return 0 ; -} - -int key_get_range(genalloc *ga, section_t *sasection) -{ - log_flow() ; - - int r ; - size_t pos = 0, fakepos = 0 ; - uint8_t found = 0 ; - stralloc sakey = STRALLOC_ZERO ; - stralloc_ref psasection ; - key_all_t const *list = total_list ; - - for (int i = 0 ; i < SECTION_ENDOFKEY ; i++) - { - if (sasection->idx[i]) - { - if (i == SECTION_ENV) - { - pos = 0 ; - keynocheck nocheck = KEYNOCHECK_ZERO ; - nocheck.idsec = i ; - nocheck.idkey = KEY_ENVIRON_ENVAL ; - nocheck.expected = EXPECT_KEYVAL ; - section_setsa(i,&psasection,sasection) ; - if (!stralloc_cats(&nocheck.val,psasection->s+1)) goto err ;//+1 remove the first '\n' - if (!stralloc_cats(&nocheck.val,"\n") || - !stralloc_0(&nocheck.val)) goto err ; - nocheck.val.len-- ; - - if (!genalloc_append(keynocheck,ga,&nocheck)) goto err ; - } - else - { - section_setsa(i,&psasection,sasection) ; - pos = 0 ; - size_t blen = psasection->len ; - while (pos < blen) - { - keynocheck nocheck = KEYNOCHECK_ZERO ; - sakey.len = 0 ; - r = mill_element(&sakey,psasection->s,&MILL_GET_AROBASE_KEY,&pos) ; - if (r == -1) goto err ; - if (!r) break ; //end of string - fakepos = get_rlen_until(psasection->s,'\n',pos) ; - r = mill_element(&sakey,psasection->s,&MILL_GET_COMMENTED_KEY,&fakepos) ; - if (r == -1) goto err ; - if (r) continue ; - if (!stralloc_cats(&nocheck.val,psasection->s+pos)) goto err ; - if (!stralloc_0(&nocheck.val)) goto err ; - for (int j = 0 ; j < total_list_el[i]; j++) - { - found = 0 ; - if (*list[i].list[j].name && obstr_equal(sakey.s,*list[i].list[j].name)) - { - nocheck.idsec = i ; - nocheck.idkey = list[i].list[j].id ; - nocheck.expected = list[i].list[j].expected ; - found = 1 ; - switch(list[i].list[j].expected) - { - case EXPECT_QUOTE: - if (!sastr_get_double_quote(&nocheck.val)) - { - parse_err(6,&nocheck) ; - goto err ; - } - if (!stralloc_0(&nocheck.val)) goto err ; - break ; - case EXPECT_BRACKET: - if (!parse_bracket(&nocheck.val,&pos)) - { - parse_err(6,&nocheck) ; - goto err ; - } - if (nocheck.val.len == 1) - { - parse_err(9,&nocheck) ; - goto err ; - } - break ; - case EXPECT_LINE: - case EXPECT_UINT: - case EXPECT_SLASH: - if (!parse_line(&nocheck.val,&pos)) - { - parse_err(7,&nocheck) ; - goto err ; - } - if (nocheck.val.len == 1) - { - parse_err(9,&nocheck) ; - goto err ; - } - break ; - default: - return 0 ; - } - if (!genalloc_append(keynocheck,ga,&nocheck)) goto err ; - break ; - } - } - if (!found && r >=0) - { - log_warn("unknown key: ",sakey.s," : in section: ",get_key_by_enum(ENUM_SECTION,i)) ; - keynocheck_free(&nocheck) ; - goto err ; - } - } - } - } - } - - stralloc_free(&sakey) ; - return 1 ; - err: - stralloc_free(&sakey) ; - return 0 ; -} - -int check_mandatory(sv_alltype *service, section_t *sasection) -{ - log_flow() ; - - if (service->cname.description < 0) - log_warn_return(LOG_EXIT_ZERO,"key @description at section [start] must be set") ; - - if (!service->user[0]) - log_warn_return(LOG_EXIT_ZERO,"key @user at section [start] must be set") ; - - if (service->cname.version < 0) - log_warn_return(LOG_EXIT_ZERO,"key @version at section [main] must be set") ; - - if (service->opts[2] && !sasection->idx[SECTION_ENV]) - log_warn_return(LOG_EXIT_ZERO,"options env was asked -- section environment must be set") ; - - switch (service->cname.itype) - { - case TYPE_BUNDLE: - if (service->cname.idga < 0) - log_warn_return(LOG_EXIT_ZERO,"bundle type detected -- key @contents must be set") ; - break ; - case TYPE_ONESHOT: - if ((service->type.oneshot.up.build == BUILD_CUSTOM) && (service->type.oneshot.up.shebang < 0)) - log_warn_return(LOG_EXIT_ZERO,"custom build asked on section [start] -- key @shebang must be set") ; - - if (service->type.oneshot.up.exec < 0) - log_warn_return(LOG_EXIT_ZERO,"key @execute at section [start] must be set") ; - - if (sasection->idx[SECTION_STOP]) - { - if ((service->type.oneshot.down.build == BUILD_CUSTOM) && (service->type.oneshot.down.shebang < 0)) - log_warn_return(LOG_EXIT_ZERO,"custom build asked on section [stop] -- key @shebang must be set") ; - if (service->type.oneshot.down.exec < 0) - log_warn_return(LOG_EXIT_ZERO,"key @execute at section [stop] must be set") ; - } - break ; - case TYPE_CLASSIC: - case TYPE_LONGRUN: - if ((service->type.classic_longrun.run.build == BUILD_CUSTOM) && (service->type.classic_longrun.run.shebang < 0)) - log_warn_return(LOG_EXIT_ZERO,"custom build asked on section [start] -- key @shebang must be set") ; - - if (service->type.classic_longrun.run.exec < 0) - log_warn_return(LOG_EXIT_ZERO,"key @execute at section [start] must be set") ; - - if (sasection->idx[SECTION_STOP]) - { - if ((service->type.classic_longrun.finish.build == BUILD_CUSTOM) && (service->type.classic_longrun.finish.shebang < 0)) - log_warn_return(LOG_EXIT_ZERO,"custom build asked on section [stop] -- key @shebang must be set") ; - if (service->type.classic_longrun.finish.exec < 0) - log_warn_return(LOG_EXIT_ZERO,"key @execute at section [stop] must be set") ; - } - if (sasection->idx[SECTION_LOG]) - { - if (service->type.classic_longrun.log.run.build == BUILD_CUSTOM) - { - if (service->type.classic_longrun.log.run.shebang < 0) - log_warn_return(LOG_EXIT_ZERO,"custom build asked on section [logger] -- key @shebang must be set") ; - if (service->type.classic_longrun.log.run.exec < 0) - log_warn_return(LOG_EXIT_ZERO,"custom build asked on section [logger] -- key @execute must be set") ; - } - } - break ; - case TYPE_MODULE: - /*if (!sasection->idx[SECTION_REGEX]) - log_warn_return(LOG_EXIT_ZERO,"section [regex] must be set") ; - if (service->type.module.iddir < 0) - log_warn_return(LOG_EXIT_ZERO,"key @directories at section [regex] must be set") ; - if (service->type.module.idfiles < 0) - log_warn_return(LOG_EXIT_ZERO,"key @files at section [regex] must be set") ; - if (service->type.module.start_infiles < 0) - log_warn_return(LOG_EXIT_ZERO,"key @infiles at section [regex] must be set") ;*/ - break ; - /** really nothing to do here */ - default: break ; - } - return 1 ; -} - -int nocheck_toservice(keynocheck *nocheck,int svtype, sv_alltype *service) -{ - log_flow() ; - - int p = svtype ; - int ste = 0 ; - - unsigned char const actions[SECTION_ENDOFKEY][TYPE_ENDOFKEY] = { - // CLASSIC, BUNDLE, LONGRUN, ONESHOT MODULES - { ACTION_COMMON, ACTION_COMMON, ACTION_COMMON, ACTION_COMMON, ACTION_COMMON }, // main - { ACTION_EXECRUN, ACTION_SKIP, ACTION_EXECRUN, ACTION_EXECUP, ACTION_SKIP }, // start - { ACTION_EXECFINISH, ACTION_SKIP, ACTION_EXECFINISH, ACTION_EXECDOWN, ACTION_SKIP }, // stop - { ACTION_EXECLOG, ACTION_SKIP, ACTION_EXECLOG, ACTION_SKIP, ACTION_SKIP }, // log - { ACTION_ENVIRON, ACTION_SKIP, ACTION_ENVIRON, ACTION_ENVIRON, ACTION_ENVIRON }, // env - { ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, ACTION_REGEX } // regex - } ; - - unsigned char const states[ACTION_SKIP + 1][TYPE_ENDOFKEY] = { - // CLASSIC, BUNDLE, LONGRUN, ONESHOT MODULES - { SECTION_START, ACTION_SKIP, SECTION_START, SECTION_START, SECTION_REGEX }, // action_common - { SECTION_STOP, ACTION_SKIP, SECTION_STOP, ACTION_SKIP, ACTION_SKIP }, // action_execrun - { SECTION_LOG, ACTION_SKIP, SECTION_LOG, ACTION_SKIP, ACTION_SKIP }, // action_execfinish - { SECTION_ENV, ACTION_SKIP, SECTION_ENV, ACTION_SKIP, ACTION_SKIP }, // action_log - { ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, SECTION_STOP, ACTION_SKIP }, // action_execup - { ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, SECTION_ENV, ACTION_SKIP }, // action_execdown - { ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, ACTION_SKIP }, // action_environ - { ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, SECTION_ENV }, // action_regex - { ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, ACTION_SKIP, ACTION_SKIP } // action_skip - } ; - - while (ste < 8) - { - unsigned int action = actions[ste][p] ; - ste = states[action][p] ; - - switch (action) { - case ACTION_COMMON: - if (nocheck->idsec == SECTION_MAIN) - if (!keep_common(service,nocheck,svtype)) - return 0 ; - break ; - case ACTION_EXECRUN: - if (nocheck->idsec == SECTION_START) - if (!keep_runfinish(&service->type.classic_longrun.run,nocheck)) - return 0 ; - break ; - case ACTION_EXECFINISH: - if (nocheck->idsec == SECTION_STOP) - if (!keep_runfinish(&service->type.classic_longrun.finish,nocheck)) - return 0 ; - break ; - case ACTION_EXECLOG: - if (nocheck->idsec == SECTION_LOG) - if (!keep_logger(&service->type.classic_longrun.log,nocheck)) - return 0 ; - break ; - case ACTION_EXECUP: - if (nocheck->idsec == SECTION_START) - if (!keep_runfinish(&service->type.oneshot.up,nocheck)) - return 0 ; - break ; - case ACTION_EXECDOWN: - if (nocheck->idsec == SECTION_STOP) - if (!keep_runfinish(&service->type.oneshot.down,nocheck)) - return 0 ; - break ; - case ACTION_ENVIRON: - if (nocheck->idsec == SECTION_ENV) - if (!keep_environ(service,nocheck)) - return 0 ; - break ; - case ACTION_REGEX: - if (nocheck->idsec == SECTION_REGEX) - if (!keep_regex(&service->type.module,nocheck)) - return 0 ; - break ; - case ACTION_SKIP: - break ; - default: log_warn_return(LOG_EXIT_ZERO,"unknown action") ; - } - } - - return 1 ; -} - -/********************************** - * store - * *******************************/ -int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype) -{ - log_flow() ; - - int r = 0 ; - size_t pos = 0, *chlen = &nocheck->val.len ; - char *chval = nocheck->val.s ; - - switch(nocheck->idkey){ - case KEY_MAIN_TYPE: - r = get_enum(chval,nocheck) ; - if (r == -1) return 0 ; - service->cname.itype = r ; - break ; - case KEY_MAIN_DESCRIPTION: - service->cname.description = keep.len ; - if (!stralloc_catb(&keep,chval,*chlen + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break ; - case KEY_MAIN_VERSION: - service->cname.version = keep.len ; - r = version_scan(&nocheck->val,chval,SS_CONFIG_VERSION_NDOT) ; - if (r == -1) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!r) { parse_err(0,nocheck) ; return 0 ; } - if (!stralloc_catb(&keep,chval,*chlen + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break ; - case KEY_MAIN_OPTIONS: - if (service->cname.itype == TYPE_BUNDLE) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!get_clean_val(nocheck)) return 0 ; - for (;pos < *chlen; pos += strlen(chval + pos)+1) - { - uint8_t reverse = chval[pos] == '!' ? 1 : 0 ; - - r = get_enum(chval + pos + reverse,nocheck) ; - if (r == -1) return 0 ; - if (svtype != TYPE_BUNDLE || svtype != TYPE_MODULE) - { - /** set a logger by default */ - if (reverse) - service->opts[0] = 0 ;/**0 means not enabled, 1 by default*/ - - if (svtype == TYPE_LONGRUN && r == OPTS_PIPELINE) - service->opts[1] = 1 ; - } - if (r == OPTS_ENVIR) - { - stralloc saconf = STRALLOC_ZERO ; - if (!env_resolve_conf(&saconf,keep.s + service->cname.name,MYUID)) { - stralloc_free(&saconf) ; - return 0 ; - } - service->srconf = keep.len ; - if (!stralloc_catb(&keep,saconf.s,saconf.len + 1)) { - stralloc_free(&saconf) ; - return 0 ; - } - service->opts[2] = 1 ; - stralloc_free(&saconf) ; - } - } - break ; - case KEY_MAIN_FLAGS: - if (service->cname.itype == TYPE_BUNDLE || service->cname.itype == TYPE_MODULE) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!get_clean_val(nocheck)) return 0 ; - for (;pos < *chlen; pos += strlen(chval + pos)+1) - { - r = get_enum(chval + pos,nocheck) ; - if (r == -1) return 0 ; - if (r == FLAGS_DOWN) - service->flags[0] = 1 ;/**0 means not enabled*/ - } - break ; - case KEY_MAIN_USER: - if (!get_clean_val(nocheck)) return 0 ; - { - uid_t owner = MYUID ; - if (!owner) - { - if (sastr_find(&nocheck->val,"root") == -1) - log_warnu_return(LOG_EXIT_ZERO,"use the service -- permission denied") ; - } - /** special case, we don't know which user want to use - * the service, we need a general name to allow all user - * the term "user" is took here to allow the current user*/ - ssize_t p = sastr_cmp(&nocheck->val,"user") ; - for (;pos < *chlen; pos += strlen(chval + pos)+1) - { - if (pos == (size_t)p) - { - struct passwd *pw = getpwuid(owner); - if (!pw) - { - if (!errno) errno = ESRCH ; - log_warnu_return(LOG_EXIT_ZERO,"get user name") ; - } - if (!scan_uidlist(pw->pw_name,(uid_t *)service->user)) { - - parse_err(0,nocheck) ; - return 0 ; - } - continue ; - } - if (!scan_uidlist(chval + pos,(uid_t *)service->user)) - { - parse_err(0,nocheck) ; - return 0 ; - } - } - uid_t nb = service->user[0] ; - if (p == -1 && owner) - { - int e = 0 ; - for (int i = 1; i < nb+1; i++) { - if (service->user[i] == owner) { - e = 1 ; - break ; - } - } - if (!e) - log_warnu_return(LOG_EXIT_ZERO,"use the service -- permission denied") ; - } - } - break ; - case KEY_MAIN_HIERCOPY: - if (service->cname.itype == TYPE_BUNDLE) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!get_clean_val(nocheck)) return 0 ; - { - unsigned int idx = 0 ; - for (;pos < *chlen; pos += strlen(chval + pos)+1) - { - char *name = chval + pos ; - size_t namelen = strlen(chval + pos) ; - service->hiercopy[idx+1] = keep.len ; - if (!stralloc_catb(&keep,name,namelen + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - service->hiercopy[0] = ++idx ; - } - } - break ; - case KEY_MAIN_DEPENDS: - if ((service->cname.itype == TYPE_CLASSIC) || (service->cname.itype == TYPE_BUNDLE)) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!get_clean_val(nocheck)) return 0 ; - service->cname.idga = deps.len ; - for (;pos < *chlen; pos += strlen(chval + pos)+1) - { - /* allow to comment a service */ - if (chval[pos] == '#') continue ; - if (!stralloc_catb(&deps,chval + pos,strlen(chval + pos) + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - service->cname.nga++ ; - } - break ; - case KEY_MAIN_OPTSDEPS: - if ((service->cname.itype == TYPE_CLASSIC) || (service->cname.itype == TYPE_BUNDLE)) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - if (!get_clean_val(nocheck)) return 0 ; - service->cname.idopts = deps.len ; - for (;pos < *chlen; pos += strlen(chval + pos)+1) - { - /* allow to comment a service */ - if (chval[pos] == '#') continue ; - if (!stralloc_catb(&deps,chval + pos,strlen(chval + pos) + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - service->cname.nopts++ ; - } - break ; - case KEY_MAIN_EXTDEPS: - if ((service->cname.itype == TYPE_CLASSIC) || (service->cname.itype == TYPE_BUNDLE)) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - if (!get_clean_val(nocheck)) return 0 ; - service->cname.idext = deps.len ; - for (;pos < *chlen; pos += strlen(chval + pos)+1) - { - /* allow to comment a service */ - if (chval[pos] == '#') continue ; - if (!stralloc_catb(&deps,chval + pos,strlen(chval + pos) + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - service->cname.next++ ; - } - break ; - case KEY_MAIN_CONTENTS: - if (service->cname.itype != TYPE_BUNDLE) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!get_clean_val(nocheck)) return 0 ; - service->cname.idga = deps.len ; - for (;pos < *chlen; pos += strlen(chval + pos) + 1) - { - /* allow to comment a service */ - if (chval[pos] == '#') continue ; - if (!stralloc_catb(&deps,chval + pos,strlen(chval + pos) + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - service->cname.nga++ ; - } - break ; - case KEY_MAIN_T_KILL: - case KEY_MAIN_T_FINISH: - case KEY_MAIN_T_UP: - case KEY_MAIN_T_DOWN: - if (service->cname.itype == TYPE_BUNDLE || service->cname.itype == TYPE_MODULE) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!get_timeout(nocheck,(uint32_t *)service->timeout)) return 0 ; - break ; - case KEY_MAIN_DEATH: - if (service->cname.itype == TYPE_BUNDLE || service->cname.itype == TYPE_MODULE) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!get_uint(nocheck,&service->death)) return 0 ; - break ; - case KEY_MAIN_NOTIFY: - if (service->cname.itype == TYPE_BUNDLE || service->cname.itype == TYPE_MODULE) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!get_uint(nocheck,&service->notification)) return 0 ; - break ; - case KEY_MAIN_SIGNAL: - if (service->cname.itype == TYPE_BUNDLE || service->cname.itype == TYPE_MODULE) - log_warn_return(LOG_EXIT_ZERO,"key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey),": is not valid for type ",get_key_by_enum(ENUM_TYPE,service->cname.itype)) ; - - if (!sig0_scan(chval,&service->signal)) - { - parse_err(3,nocheck) ; - return 0 ; - } - break ; - case KEY_MAIN_INTREE: - service->cname.intree = keep.len ; - if (!stralloc_catb(&keep,chval,*chlen + 1)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break ; - default: log_warn_return(LOG_EXIT_ZERO,"unknown key: ",get_key_by_enum(ENUM_KEY_SECTION_MAIN,nocheck->idkey)) ; - - } - - return 1 ; -} - -int keep_runfinish(sv_exec *exec,keynocheck *nocheck) -{ - log_flow() ; - - int r = 0 ; - size_t *chlen = &nocheck->val.len ; - char *chval = nocheck->val.s ; - - switch(nocheck->idkey) - { - case KEY_STARTSTOP_BUILD: - r = get_enum(chval,nocheck) ; - if (r == -1) return 0 ; - exec->build = r ; - break ; - case KEY_STARTSTOP_RUNAS: - if (!check_valid_runas(nocheck)) return 0 ; - exec->runas = keep.len ; - if (!stralloc_catb(&keep,chval,*chlen + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break ; - case KEY_STARTSTOP_SHEBANG: - if (chval[0] != '/') - { - parse_err(4,nocheck) ; - return 0 ; - } - exec->shebang = keep.len ; - if (!stralloc_catb(&keep,chval,*chlen + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break ; - case KEY_STARTSTOP_EXEC: - exec->exec = keep.len ; - if (!stralloc_catb(&keep,chval,*chlen + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break ; - default: log_warn_return(LOG_EXIT_ZERO,"unknown key: ",get_key_by_enum(ENUM_KEY_SECTION_STARTSTOP,nocheck->idkey)) ; - } - return 1 ; -} - -int keep_logger(sv_execlog *log,keynocheck *nocheck) -{ - log_flow() ; - - int r ; - size_t pos = 0, *chlen = &nocheck->val.len ; - char *chval = nocheck->val.s ; - - switch(nocheck->idkey){ - case KEY_LOGGER_BUILD: - if (!keep_runfinish(&log->run,nocheck)) return 0 ; - break ; - case KEY_LOGGER_RUNAS: - if (!keep_runfinish(&log->run,nocheck)) return 0 ; - break ; - case KEY_LOGGER_DEPENDS: - if (!get_clean_val(nocheck)) return 0 ; - log->idga = deps.len ; - for (;pos < *chlen; pos += strlen(chval + pos) + 1) - { - if (!stralloc_catb(&deps,chval + pos,strlen(chval + pos) + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - log->nga++ ; - } - break ; - case KEY_LOGGER_SHEBANG: - if (!keep_runfinish(&log->run,nocheck)) return 0 ; - break ; - case KEY_LOGGER_EXEC: - if (!keep_runfinish(&log->run,nocheck)) return 0 ; - break ; - case KEY_LOGGER_T_KILL: - case KEY_LOGGER_T_FINISH: - if (!get_timeout(nocheck,(uint32_t *)log->timeout)) return 0 ; - break ; - case KEY_LOGGER_DESTINATION: - if (chval[0] != '/') - { - parse_err(4,nocheck) ; - return 0 ; - } - log->destination = keep.len ; - if (!stralloc_catb(&keep,chval,*chlen + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break ; - case KEY_LOGGER_BACKUP: - if (!get_uint(nocheck,&log->backup)) return 0 ; - break ; - case KEY_LOGGER_MAXSIZE: - if (!get_uint(nocheck,&log->maxsize)) return 0 ; - break ; - case KEY_LOGGER_TIMESTP: - r = get_enum(chval,nocheck) ; - if (r == -1) return 0 ; - log->timestamp = r ; - break ; - default: log_warn_return(LOG_EXIT_ZERO,"unknown key: ",get_key_by_enum(ENUM_KEY_SECTION_LOGGER,nocheck->idkey)) ; - } - return 1 ; -} - -int keep_environ(sv_alltype *service,keynocheck *nocheck) -{ - log_flow() ; - - stralloc tmp = STRALLOC_ZERO ; - switch(nocheck->idkey){ - case KEY_ENVIRON_ENVAL: - if (!env_clean_with_comment(&nocheck->val)) - log_warnu_return(LOG_EXIT_ZERO,"clean environment value") ; - if (!auto_stra(&service->saenv,nocheck->val.s)) - log_warnu_return(LOG_EXIT_ZERO,"store environment value") ; - { - /** The declaration of the [environment] automatically add - * the @options=(env) */ - if (!service->opts[2]) { - - stralloc saconf = STRALLOC_ZERO ; - if (!env_resolve_conf(&saconf,keep.s + service->cname.name,MYUID)) { - stralloc_free(&saconf) ; - return 0 ; - } - service->srconf = keep.len ; - if (!stralloc_catb(&keep,saconf.s,saconf.len + 1)) { - stralloc_free(&saconf) ; - return 0 ; - } - service->opts[2] = 1 ; - stralloc_free(&saconf) ; - } - } - ; - break ; - default: log_warn_return(LOG_EXIT_ZERO,"unknown key: ",get_key_by_enum(ENUM_KEY_SECTION_ENVIRON,nocheck->idkey)) ; - } - stralloc_free(&tmp) ; - return 1 ; -} - -int keep_regex(sv_module *module,keynocheck *nocheck) -{ - log_flow() ; - - size_t pos = 0, *chlen = &nocheck->val.len ; - char *chval = nocheck->val.s ; - - switch(nocheck->idkey){ - case KEY_REGEX_CONFIGURE: - module->configure = keep.len ; - if (!stralloc_catb(&keep,chval,*chlen + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break ; - case KEY_REGEX_DIRECTORIES: - if (!get_clean_val(nocheck)) return 0 ; - module->iddir = keep.len ; - for (;pos < *chlen; pos += strlen(chval + pos) + 1) - { - /* allow to comment a service */ - if (chval[pos] == '#') continue ; - if (!stralloc_catb(&keep,chval + pos,strlen(chval + pos) + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - module->ndir++ ; - } - break ; - case KEY_REGEX_FILES: - if (!get_clean_val(nocheck)) return 0 ; - module->idfiles = keep.len ; - for (;pos < *chlen; pos += strlen(chval + pos) + 1) - { - /* allow to comment a service */ - if (chval[pos] == '#') continue ; - if (!stralloc_catb(&keep,chval + pos,strlen(chval + pos) + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - module->nfiles++ ; - } - break ; - case KEY_REGEX_INFILES: - if (!environ_get_clean_env(&nocheck->val)) - log_warnu_return(LOG_EXIT_ZERO,"clean key ",get_key_by_enum(ENUM_KEY_SECTION_REGEX,nocheck->idkey)," field") ; - if (!environ_clean_nline(&nocheck->val)) - log_warnu_return(LOG_EXIT_ZERO,"clean lines of key ",get_key_by_enum(ENUM_KEY_SECTION_REGEX,nocheck->idkey)," field") ; - if (!stralloc_0(&nocheck->val)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - if (!sastr_split_string_in_nline(&nocheck->val)) - log_warnu_return(LOG_EXIT_SYS,"split lines of key ",get_key_by_enum(ENUM_KEY_SECTION_REGEX,nocheck->idkey)," field") ; - - module->start_infiles = keep.len ; - for (;pos < *chlen; pos += strlen(chval + pos) + 1) - if (!stralloc_catb(&keep,chval + pos,strlen(chval + pos) + 1)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - module->end_infiles = keep.len ; - break ; - case KEY_REGEX_ADDSERVICES: - if (!get_clean_val(nocheck)) return 0 ; - module->idaddservices = keep.len ; - for (;pos < *chlen; pos += strlen(chval + pos) + 1) - { - /* allow to comment a service */ - if (chval[pos] == '#') continue ; - if (!stralloc_catb(&keep,chval + pos,strlen(chval + pos) + 1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - module->naddservices++ ; - } - break ; - default: log_warn_return(LOG_EXIT_ZERO,"unknown key: ",get_key_by_enum(ENUM_KEY_SECTION_REGEX,nocheck->idkey)) ; - } - return 1 ; -} - -/********************************** - * helper function - * *******************************/ -int add_pipe(sv_alltype *sv, stralloc *sa) -{ - log_flow() ; - - char *prodname = keep.s+sv->cname.name ; - - stralloc tmp = STRALLOC_ZERO ; - - sv->pipeline = sa->len ; - if (!stralloc_cats(&tmp,SS_PIPE_NAME)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_cats(&tmp,prodname)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_0(&tmp)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - if (!stralloc_catb(sa,tmp.s,tmp.len+1)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - stralloc_free(&tmp) ; - - return 1 ; -} - -int parse_line(stralloc *sa, size_t *pos) -{ - log_flow() ; - - if (!sa->len) return 0 ; - int r = 0 ; - size_t newpos = 0 ; - stralloc kp = STRALLOC_ZERO ; - wild_zero_all(&MILL_CLEAN_LINE) ; - r = mill_element(&kp,sa->s,&MILL_CLEAN_LINE,&newpos) ; - if (r == -1 || !r) goto err ; - if (!stralloc_0(&kp)) goto err ; - if (!stralloc_copy(sa,&kp)) goto err ; - *pos += newpos - 1 ; - stralloc_free(&kp) ; - return 1 ; - err: - stralloc_free(&kp) ; - return 0 ; -} - -int parse_bracket(stralloc *sa,size_t *pos) -{ - log_flow() ; - - if (!sa->len) return 0 ; - size_t newpos = 0 ; - stralloc kp = STRALLOC_ZERO ; - if (!key_get_next_id(&kp,sa->s,&newpos)) goto err ; - if (!stralloc_0(&kp)) goto err ; - if (!stralloc_copy(sa,&kp)) goto err ; - *pos += newpos ; - stralloc_free(&kp) ; - return 1 ; - err: - stralloc_free(&kp) ; - return 0 ; -} - -void section_setsa(int id, stralloc_ref *p,section_t *sa) -{ - log_flow() ; - - switch(id) - { - case SECTION_MAIN: *p = &sa->main ; break ; - case SECTION_START: *p = &sa->start ; break ; - case SECTION_STOP: *p = &sa->stop ; break ; - case SECTION_LOG: *p = &sa->logger ; break ; - case SECTION_ENV: *p = &sa->environment ; break ; - case SECTION_REGEX: *p = &sa->regex ; break ; - default: break ; - } -} - -int section_get_skip(char const *s,size_t pos,int nline) -{ - log_flow() ; - - ssize_t r = -1 ; - if (nline == 1) - { - r = get_sep_before(s,'#','[') ; - if (r >= 0) return 0 ; - } - r = get_rlen_until(s,'\n',pos) ; - if (r >= 0) - { - r = get_sep_before(s+r+1,'#','[') ; - if (r >= 0) return 0 ; - } - return 1 ; -} - -int section_get_id(stralloc *secname, char const *str,size_t *pos,int *id) -{ - log_flow() ; - - size_t len = strlen(str) ; - size_t newpos = 0 ; - (*id) = -1 ; - - while ((*id) < 0 && (*pos) < len) - { - secname->len = 0 ; - newpos = 0 ; - if (mill_element(secname,str+(*pos),&MILL_GET_SECTION_NAME,&newpos) == -1) return 0 ; - if (secname->len) - { - if (!stralloc_0(secname)) return 0 ; - (*id) = get_enum_by_key(secname->s) ; - } - (*pos) += newpos ; - } - return 1 ; -} - -int key_get_next_id(stralloc *sa, char const *str,size_t *pos) -{ - log_flow() ; - - if (!str) return 0 ; - int r = 0 ; - size_t newpos = 0, len = strlen(str) ; - stralloc kp = STRALLOC_ZERO ; - wild_zero_all(&MILL_GET_AROBASE_KEY) ; - wild_zero_all(&MILL_FIRST_BRACKET) ; - int id = -1 ; - r = mill_element(&kp,str,&MILL_FIRST_BRACKET,&newpos) ; - if (r == -1 || !r) goto err ; - *pos = newpos ; - while (id == -1 && newpos < len) - { - kp.len = 0 ; - r = mill_element(&kp,str,&MILL_GET_AROBASE_KEY,&newpos) ; - if (r == -1) goto err ; - if (!stralloc_0(&kp)) goto err ; - id = get_enum_by_key(kp.s) ; - //May confusing in case of instantiated service - //if (id == -1 && kp.len > 1) log_warn("unknown key: ",kp.s,": at parenthesis parse") ; - } - newpos = get_rlen_until(str,')',newpos) ; - if (newpos == -1) goto err ; - if (!stralloc_catb(sa,str+*pos,newpos - *pos)) goto err ; - *pos = newpos + 1 ; //+1 remove the last ')' - stralloc_free(&kp) ; - return 1 ; - err: - stralloc_free(&kp) ; - return 0 ; -} - -int get_clean_val(keynocheck *ch) -{ - log_flow() ; - - if (!sastr_clean_element(&ch->val)) - { - parse_err(8,ch) ; - return 0 ; - } - return 1 ; -} - -int get_enum(char const *str, keynocheck *ch) -{ - log_flow() ; - - int r = get_enum_by_key(str) ; - if (r == -1) - { - parse_err(0,ch) ; - return -1 ; - } - return r ; -} - -int get_timeout(keynocheck *ch,uint32_t *ui) -{ - log_flow() ; - - int time = 0 ; - if ((ch->idkey == KEY_MAIN_T_KILL) || (ch->idkey == KEY_LOGGER_T_KILL)) time = 0 ; - else if ((ch->idkey == KEY_MAIN_T_FINISH) || (ch->idkey == KEY_LOGGER_T_FINISH)) time = 1 ; - else if (ch->idkey == KEY_MAIN_T_UP) time = 2 ; - else if (ch->idkey == KEY_MAIN_T_DOWN) time = 3 ; - if (scan_timeout(ch->val.s,ui,time) == -1) - { - parse_err(3,ch) ; - return 0 ; - } - return 1 ; -} - -int get_uint(keynocheck *ch,uint32_t *ui) -{ - log_flow() ; - - if (!uint32_scan(ch->val.s,ui)) - { - parse_err(3,ch) ; - return 0 ; - } - return 1 ; -} - -int check_valid_runas(keynocheck *ch) -{ - log_flow() ; - - size_t len = strlen(ch->val.s) ; - char file[len + 1] ; - auto_strings(file,ch->val.s) ; - - char *colon ; - colon = strchr(file,':') ; - - if (colon) { - - *colon = 0 ; - - uid_t uid ; - gid_t gid ; - size_t uid_strlen ; - size_t gid_strlen ; - static char uid_str[UID_FMT] ; - static char gid_str[GID_FMT] ; - - /** on format :gid, get the uid of - * the owner of the process */ - if (!*file) { - - uid = getuid() ; - - } - else { - - if (get_uidbyname(file,&uid) == -1) { - parse_err(0,ch) ; - return 0 ; - } - - } - uid_strlen = uid_fmt(uid_str,uid) ; - uid_str[uid_strlen] = 0 ; - - /** on format uid:, get the gid of - * the owner of the process */ - if (!*(colon + 1)) { - - if (!yourgid(&gid,uid)) { - parse_err(0,ch) ; - return 0 ; - } - - } - else { - - if (get_gidbygroup(colon + 1,&gid) == -1) { - parse_err(0,ch) ; - return 0 ; - } - - } - gid_strlen = gid_fmt(gid_str,gid) ; - gid_str[gid_strlen] = 0 ; - - ch->val.len = 0 ; - if (!auto_stra(&ch->val,uid_str,":",gid_str)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - } - else { - - int e = errno ; - errno = 0 ; - - struct passwd *pw = getpwnam(ch->val.s); - - if (!pw) { - - if (!errno) errno = ESRCH ; - parse_err(0,ch) ; - return 0 ; - } - - errno = e ; - - } - - return 1 ; -} - -void parse_err(int ierr,keynocheck *check) -{ - log_flow() ; - - int idsec = check->idsec ; - int idkey = check->idkey ; - char const *section = get_key_by_enum(ENUM_SECTION,idsec) ; - /* start stop enum are the same, enum_all must increase by one to match - * the correct list */ - char const *key = get_key_by_enum(idsec < 2 ? idsec + 1 : idsec,idkey) ; - - switch(ierr) - { - case 0: - log_warn("invalid value for key: ",key,": in section: ",section) ; - break ; - case 1: - log_warn("multiple definition of key: ",key,": in section: ",section) ; - break ; - case 2: - log_warn("same value for key: ",key,": in section: ",section) ; - break ; - case 3: - log_warn("key: ",key,": must be an integrer value in section: ",section) ; - break ; - case 4: - log_warn("key: ",key,": must be an absolute path in section: ",section) ; - break ; - case 5: - log_warn("key: ",key,": must be set in section: ",section) ; - break ; - case 6: - log_warn("invalid format of key: ",key,": in section: ",section) ; - break ; - case 7: - log_warnu("parse key: ",key,": in section: ",section) ; - break ; - case 8: - log_warnu("clean value of key: ",key,": in section: ",section) ; - break ; - case 9: - log_warn("empty value of key: ",key,": in section: ",section) ; - break ; - default: - log_warn("unknown parse_err number") ; - break ; - } -} - -int get_svtype(sv_alltype *sv_before, char const *contents) -{ - log_flow() ; - - stralloc sa = STRALLOC_ZERO ; - - if (!auto_stra(&sa,contents)) goto err ; - - if (!environ_get_val_of_key(&sa,get_key_by_enum(ENUM_KEY_SECTION_MAIN,KEY_MAIN_TYPE))) goto err ; - - if (!sastr_clean_element(&sa)) goto err ; - sv_before->cname.itype = get_enum_by_key(sa.s) ; - - if (sv_before->cname.itype == -1) goto err ; - - stralloc_free(&sa) ; - return 1 ; - err: - stralloc_free(&sa) ; - return 0 ; -} - -int get_svtype_from_file(char const *file) -{ - log_flow() ; - - stralloc tmp = STRALLOC_ZERO ; - int svtype = -1 ; - size_t len = strlen(file) ; - char bname[len + 1] ; - char dname[len + 1] ; - if (!ob_basename(bname,file)) goto err ; - if (!ob_dirname(dname,file)) goto err ; - - log_trace("read service file of: ",dname,bname) ; - if (read_svfile(&tmp,bname,dname) <= 0) goto err ; - - if (!environ_get_val_of_key(&tmp,get_key_by_enum(ENUM_KEY_SECTION_MAIN,KEY_MAIN_TYPE))) goto err ; - - if (!sastr_clean_element(&tmp)) goto err ; - svtype = get_enum_by_key(tmp.s) ; - - err: - stralloc_free(&tmp) ; - return svtype ; -} - -int get_svintree(sv_alltype *sv_before, char const *contents) -{ - log_flow() ; - - int r ; - stralloc sa = STRALLOC_ZERO ; - - if (!auto_stra(&sa,contents)) goto err ; - - /** @intree may not exist */ - r = sastr_find(&sa,get_key_by_enum(ENUM_KEY_SECTION_MAIN,KEY_MAIN_INTREE)) ; - if (r == -1) { sv_before->cname.intree == -1 ; goto freed ; } - - if (!environ_get_val_of_key(&sa,get_key_by_enum(ENUM_KEY_SECTION_MAIN,KEY_MAIN_INTREE))) goto err ; - - if (!sastr_clean_element(&sa)) goto err ; - - sv_before->cname.intree = keep.len ; - if (!sastr_add_string(&keep, sa.s)) - goto err ; - - freed: - stralloc_free(&sa) ; - return 1 ; - err: - stralloc_free(&sa) ; - return 0 ; -} diff --git a/src/lib66/parse/parser_write.c b/src/lib66/parse/parser_write.c deleted file mode 100644 index 9fe60566..00000000 --- a/src/lib66/parse/parser_write.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * parser_write.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 <66/parser.h> - -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <stdint.h> - -#include <oblibs/string.h> -#include <oblibs/files.h> -#include <oblibs/log.h> -#include <oblibs/types.h> -#include <oblibs/directory.h> - -#include <skalibs/types.h> -#include <skalibs/bytestr.h> -#include <skalibs/djbunix.h> -#include <skalibs/diuint32.h> - -#include <66/constants.h> -#include <66/enum.h> -#include <66/utils.h> -#include <66/enum.h> -#include <66/resolve.h> -#include <66/ssexec.h> -#include <66/environ.h> - -#include <s6/config.h>//S6_BINPREFIX -#include <execline/config.h>//EXECLINE_BINPREFIX - -/** @Return 0 on fail - * @Return 1 on success - * @Return 2 if the service is ignored */ -int write_services(sv_alltype *sv, char const *workdir, uint8_t force, uint8_t conf) -{ - log_flow() ; - - int r ; - - size_t workdirlen = strlen(workdir) ; - char *name = keep.s+sv->cname.name ; - size_t namelen = strlen(name) ; - int type = sv->cname.itype ; - - { - resolve_service_t res = RESOLVE_SERVICE_ZERO ; - resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ; - if (resolve_check(workdir,name)) - { - if (!resolve_read(wres,workdir,name)) log_dieusys(LOG_EXIT_SYS,"read resolve file of: ",name) ; - if (res.type != type && res.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,res.type)) ; - } - resolve_free(wres) ; - } - - size_t wnamelen ; - char wname[workdirlen + SS_SVC_LEN + SS_SRC_LEN + namelen + 1 + 1] ; - memcpy(wname,workdir,workdirlen) ; - wnamelen = workdirlen ; - - if (type == TYPE_CLASSIC) - { - memcpy(wname + wnamelen, SS_SVC, SS_SVC_LEN) ; - memcpy(wname + wnamelen + SS_SVC_LEN, "/", 1) ; - memcpy(wname + wnamelen + SS_SVC_LEN + 1, name, namelen) ; - wnamelen = wnamelen + SS_SVC_LEN + 1 + namelen ; - wname[wnamelen] = 0 ; - - } - else - { - memcpy(wname + wnamelen, SS_DB, SS_DB_LEN) ; - memcpy(wname + wnamelen + SS_DB_LEN, SS_SRC,SS_SRC_LEN) ; - memcpy(wname + wnamelen + SS_DB_LEN + SS_SRC_LEN, "/", 1) ; - memcpy(wname + wnamelen + SS_DB_LEN + SS_SRC_LEN + 1, name, namelen) ; - wnamelen = wnamelen + SS_DB_LEN + SS_SRC_LEN + 1 + namelen ; - wname[wnamelen] = 0 ; - } - - r = scan_mode(wname,S_IFDIR) ; - if (r < 0) - log_warn_return(LOG_EXIT_ZERO,"unvalide source: ",wname) ; - - if ((r && force) || !r) - { - if (rm_rf(wname) < 0) - log_warnusys_return(LOG_EXIT_ZERO,"remove: ",wname) ; - r = dir_create(wname, 0755) ; - if (!r) - log_warnusys_return(LOG_EXIT_ZERO,"create ",wname) ; - } - else if (r && !force) - { - log_info("Ignoring: ",name," service: already enabled") ; - return 2 ; - } - - log_trace("Write service ", name," ...") ; - - switch(type) - { - case TYPE_CLASSIC: - if (!write_classic(sv, wname, force, conf)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",wname) ; - - break ; - case TYPE_LONGRUN: - if (!write_longrun(sv, wname, force, conf)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",wname) ; - - break ; - case TYPE_ONESHOT: - if (!write_oneshot(sv, wname, conf)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",wname) ; - - break ; - case TYPE_MODULE: - if (!write_common(sv,wname,conf)) - log_warnu_return(LOG_EXIT_ZERO,"write common files") ; - case TYPE_BUNDLE: - if (!write_bundle(sv, wname)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",wname) ; - - break ; - default: log_warn_return(LOG_EXIT_ZERO,"unkown type: ", get_key_by_enum(ENUM_TYPE,sv->cname.itype)) ; - } - - return 1 ; -} - -int write_classic(sv_alltype *sv, char const *dst, uint8_t force,uint8_t conf) -{ - log_flow() ; - - /**notification,timeout, ...*/ - if (!write_common(sv, dst, conf)) - log_warnu_return(LOG_EXIT_ZERO,"write common files") ; - - /** run file*/ - if (!write_exec(sv, &sv->type.classic_longrun.run,"run",dst,0755)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/run") ; - - /** finish file*/ - if (sv->type.classic_longrun.finish.exec >= 0) - { - if (!write_exec(sv, &sv->type.classic_longrun.finish,"finish",dst,0755)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/finish") ; - } - /**logger */ - if (sv->opts[0]) - { - if (!write_logger(sv, &sv->type.classic_longrun.log,"log",dst,0755, force)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/log") ; - } - - return 1 ; -} - -int write_longrun(sv_alltype *sv,char const *dst, uint8_t force, uint8_t conf) -{ - log_flow() ; - - /**notification,timeout ...*/ - if (!write_common(sv, dst,conf)) - log_warnu_return(LOG_EXIT_ZERO,"write common files") ; - - /**run file*/ - if (!write_exec(sv, &sv->type.classic_longrun.run,"run",dst,0644)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/run") ; - - /**finish file*/ - if (sv->type.classic_longrun.finish.exec >= 0) - { - - if (!write_exec(sv, &sv->type.classic_longrun.finish,"finish",dst,0644)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/finish") ; - } - - /**logger*/ - if (sv->opts[0]) - { - char *name = keep.s+sv->cname.name ; - size_t r, namelen = strlen(name), dstlen = strlen(dst) ; - char logname[namelen + SS_LOG_SUFFIX_LEN + 1] ; - char dstlog[dstlen + 1] ; - - memcpy(logname,name,namelen) ; - memcpy(logname + namelen,SS_LOG_SUFFIX,SS_LOG_SUFFIX_LEN) ; - logname[namelen + SS_LOG_SUFFIX_LEN] = 0 ; - - r = get_rstrlen_until(dst,name) ; - r--;//remove the last slash - memcpy(dstlog,dst,r) ; - dstlog[r] = 0 ; - - if (!write_logger(sv, &sv->type.classic_longrun.log,logname,dstlog,0644,force)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dstlog,"/",logname) ; - - /** write_logger change the sv_alltype appending the real_exec log element */ - name = keep.s+sv->cname.name ; - - if (!write_consprod(sv,name,logname,dst,dstlog)) - log_warnu_return(LOG_EXIT_ZERO,"write consumer/producer files") ; - } - /** dependencies */ - if (!write_dependencies(sv->cname.nga,sv->cname.idga, dst, "dependencies")) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/dependencies") ; - - return 1 ; -} - -int write_oneshot(sv_alltype *sv,char const *dst,uint8_t conf) -{ - log_flow() ; - - if (!write_common(sv, dst,conf)) - log_warnu_return(LOG_EXIT_ZERO,"write common files") ; - - /** up file*/ - if (!write_exec(sv, &sv->type.oneshot.up,"up",dst,0644)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/up") ; - - /** down file*/ - if (sv->type.oneshot.down.exec >= 0) - { - if (!write_exec(sv, &sv->type.oneshot.down,"down",dst,0644)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/down") ; - } - - /** dependencies */ - if (!write_dependencies(sv->cname.nga,sv->cname.idga, dst, "dependencies")) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/dependencies") ; - - return 1 ; -} - -int write_bundle(sv_alltype *sv, char const *dst) -{ - log_flow() ; - - /** type file*/ - if (!file_write_unsafe(dst,"type","bundle",6)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/type") ; - - /** contents file*/ - if (!write_dependencies(sv->cname.nga,sv->cname.idga, dst, "contents")) - log_warnu_return(LOG_EXIT_ZERO,"write: ",dst,"/contents") ; - - return 1 ; -} - -int write_logger(sv_alltype *sv, sv_execlog *log,char const *name, char const *dst, mode_t mode, uint8_t force) -{ - log_flow() ; - - int r ; - int logbuild = log->run.build < 0 ? BUILD_AUTO : log->run.build ; - - uid_t log_uid ; - gid_t log_gid ; - uid_t owner = MYUID ; - char *time = 0 ; - char *pmax = 0 ; - char *pback = 0 ; - char *timestamp = 0 ; - int itimestamp = SS_LOGGER_TIMESTAMP ; - char *logrunner = log->run.runas >=0 ? keep.s + log->run.runas : SS_LOGGER_RUNNER ; - char max[UINT32_FMT] ; - char back[UINT32_FMT] ; - char const *userhome ; - char *svname = keep.s + sv->cname.name ; - - stralloc ddst = STRALLOC_ZERO ; - stralloc shebang = STRALLOC_ZERO ; - stralloc ui = STRALLOC_ZERO ; - stralloc exec = STRALLOC_ZERO ; - stralloc destlog = STRALLOC_ZERO ; - - /** destination of the temporary directory e.g - * /tmp/test:mrNoe5/db/source/service-log */ - if(!stralloc_cats(&ddst,dst) || - !stralloc_cats(&ddst,"/") || - !stralloc_cats(&ddst,name) || - !stralloc_0(&ddst)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - r = scan_mode(ddst.s,S_IFDIR) ; - if (r && force) - { - if (rm_rf(ddst.s) < 0) - log_warnusys_return(LOG_EXIT_ZERO,"remove: ",ddst.s) ; - - r = dir_create(ddst.s, 0755) ; - if (!r) - log_warnusys_return(LOG_EXIT_ZERO,"create ",ddst.s," directory") ; - } - else if (r) - { - log_warnu_return(LOG_EXIT_ZERO,"ignoring ",name,": already enabled") ; - } - else - { - r = dir_create(ddst.s, 0755) ; - if (!r) - log_warnusys_return(LOG_EXIT_ZERO,"create ",ddst.s," directory") ; - } - - userhome = get_userhome(owner) ; - - /**timeout family*/ - for (uint32_t i = 0; i < 2;i++) - { - if (log->timeout[i][0]) - { - - if (!i) - time = "timeout-kill" ; - if (i) - time = "timeout-finish" ; - if (!write_uint(ddst.s,time,log->timeout[i][0])) return 0 ; - - } - - } - /** dependencies*/ - if (log->nga > 0) - { - if (!write_dependencies(log->nga,log->idga,ddst.s,"dependencies")) - log_warnu_return(LOG_EXIT_ZERO,"write: ",ddst.s,"/dependencies") ; - } - - if (sv->cname.itype > TYPE_CLASSIC) - { - if (!file_write_unsafe(ddst.s,"type","longrun",7)) - log_warnusys_return(LOG_EXIT_ZERO,"write: ",ddst.s,"/type") ; - } - - switch(logbuild) - { - case BUILD_AUTO: - /** uid */ - if (!stralloc_cats(&shebang, "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n") || - !stralloc_0(&shebang)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!owner) - { - if (!stralloc_cats(&ui,S6_BINPREFIX "s6-setuidgid ") || - !stralloc_cats(&ui,logrunner)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - if (!stralloc_cats(&ui,"\n") || - !stralloc_0(&ui)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - /** destination */ - if (log->destination < 0) - { - if(owner > 0) - { - - if (!stralloc_cats(&destlog,userhome) || - !stralloc_cats(&destlog,"/") || - !stralloc_cats(&destlog,SS_LOGGER_USERDIR) || - !stralloc_cats(&destlog,svname)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - else - { - if (!stralloc_cats(&destlog,SS_LOGGER_SYSDIR) || - !stralloc_cats(&destlog,svname)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - } - else - { - if (!stralloc_cats(&destlog,keep.s+log->destination)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - if (!stralloc_0(&destlog)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - if (log->timestamp >= 0) timestamp = log->timestamp == TIME_NONE ? "" : log->timestamp == TIME_ISO ? "T" : "t" ; - else timestamp = itimestamp == TIME_NONE ? "" : itimestamp == TIME_ISO ? "T" : "t" ; - - if (log->backup > 0) - { - back[uint32_fmt(back,log->backup)] = 0 ; - pback = back ; - } - else pback = "3" ; - - if (log->maxsize > 0) - { - max[uint32_fmt(max,log->maxsize)] = 0 ; - pmax = max ; - } - else pmax = "1000000" ; - - if (!stralloc_cats(&exec,shebang.s) || - !stralloc_cats(&exec,EXECLINE_BINPREFIX "fdmove -c 2 1\n") || - !stralloc_cats(&exec,ui.s) || - !stralloc_cats(&exec,S6_BINPREFIX "s6-log ")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (SS_LOGGER_NOTIFY) - if (!stralloc_cats(&exec,"-d3 ")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - if (!stralloc_cats(&exec,"n") || - !stralloc_cats(&exec,pback) || - !stralloc_cats(&exec," ")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (log->timestamp < TIME_NONE) - { - if (!stralloc_cats(&exec,timestamp) || - !stralloc_cats(&exec," ")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - if (!stralloc_cats(&exec,"s") || - !stralloc_cats(&exec,pmax) || - !stralloc_cats(&exec," ") || - !stralloc_cats(&exec,destlog.s) || - !stralloc_cats(&exec,"\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - /**write it*/ - if (!file_write_unsafe(ddst.s,"run",exec.s,exec.len)) - log_warnusys_return(LOG_EXIT_ZERO,"write: ",ddst.s,"/run") ; - - /** notification fd */ - if (SS_LOGGER_NOTIFY) - if (!file_write_unsafe(ddst.s,SS_NOTIFICATION,"3\n",2)) - log_warnusys_return(LOG_EXIT_ZERO,"write: ",ddst.s,"/" SS_NOTIFICATION) ; - - if (sv->cname.itype == TYPE_CLASSIC) - { - ddst.len-- ; - if (!stralloc_cats(&ddst,"/run") || - !stralloc_0(&ddst)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - if (chmod(ddst.s, mode) < 0) - log_warnusys_return(LOG_EXIT_ZERO,"chmod ", ddst.s) ; - } - break; - case BUILD_CUSTOM: - if (!write_exec(sv, &log->run,"run",ddst.s,mode)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",ddst.s,"/run") ; - if (log->destination >= 0) - if (!stralloc_cats(&destlog,keep.s+log->destination) || - !stralloc_0(&destlog)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - break; - default: log_warn_return(LOG_EXIT_ZERO,"unknown build value: ",get_key_by_enum(ENUM_BUILD,logbuild)) ; - } - if (destlog.len) - { - r = scan_mode(destlog.s,S_IFDIR) ; - if (r == -1) - log_warn_return(LOG_EXIT_ZERO,"log directory: ", destlog.s,": already exist with a different mode") ; - - if (!dir_create_parent(destlog.s,0755)) - log_warnusys_return(LOG_EXIT_ZERO,"create log directory: ",destlog.s) ; - } - /** redefine the logrunner, write_exec change the sv_alltype struct*/ - logrunner = log->run.runas >=0 ? keep.s + log->run.runas : SS_LOGGER_RUNNER ; - - if (!owner && ((log->run.build == BUILD_AUTO) || (log->run.build < 0))) // log->run.build may not set - { - if (!youruid(&log_uid,logrunner) || - !yourgid(&log_gid,log_uid)) - log_warnusys_return(LOG_EXIT_ZERO,"get uid and gid of: ",logrunner) ; - - if (chown(destlog.s,log_uid,log_gid) == -1) - log_warnusys_return(LOG_EXIT_ZERO,"chown: ",destlog.s) ; - } - - /** keep the exec file */ - if (!stralloc_insertb(&exec,0,"\n",1)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_0(&exec)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - log->run.real_exec = keep.len ; - if (!stralloc_catb(&keep,exec.s,strlen(exec.s) + 1)) - log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; - - stralloc_free(&shebang) ; - stralloc_free(&ui) ; - stralloc_free(&exec) ; - stralloc_free(&destlog) ; - stralloc_free(&ddst) ; - - return 1 ; -} - -int write_consprod(sv_alltype *sv,char const *prodname,char const *consname,char const *proddst,char const *consdst) -{ - log_flow() ; - - size_t consdstlen = strlen(consdst) ; - size_t consnamelen = strlen(consname) ; - size_t proddstlen = strlen(proddst) ; - - char consfile[consdstlen + 1 + consnamelen + 1] ; - memcpy(consfile,consdst,consdstlen) ; - consfile[consdstlen] = '/' ; - memcpy(consfile + consdstlen + 1, consname,consnamelen) ; - consfile[consdstlen + 1 + consnamelen] = 0 ; - - char prodfile[proddstlen + 1] ; - memcpy(prodfile,proddst,proddstlen) ; - prodfile[proddstlen] = 0 ; - - char pipefile[consdstlen + 1 + consnamelen + 1 + 1] ; - - /**producer-for*/ - if (!file_write_unsafe(consfile,get_key_by_enum(ENUM_LOGOPTS,LOGOPTS_CONSUMER),prodname,strlen(prodname))) - log_warnu_return(LOG_EXIT_ZERO,"write: ",consfile,get_key_by_enum(ENUM_LOGOPTS,LOGOPTS_CONSUMER)) ; - - /**consumer-for*/ - if (!file_write_unsafe(prodfile,get_key_by_enum(ENUM_LOGOPTS,LOGOPTS_PRODUCER),consname,strlen(consname))) - log_warnu_return(LOG_EXIT_ZERO,"write: ",prodfile,get_key_by_enum(ENUM_LOGOPTS,LOGOPTS_PRODUCER)) ; - - /**pipeline**/ - if (sv->opts[1] > 0) - { - size_t len = strlen(deps.s+sv->pipeline) ; - char pipename[len + 1] ; - memcpy(pipefile,consdst,consdstlen) ; - pipefile[consdstlen] = '/' ; - memcpy(pipefile + consdstlen + 1, consname,consnamelen) ; - pipefile[consdstlen + 1 + consnamelen] = '/' ; - pipefile[consdstlen + 1 + consnamelen + 1] = 0 ; - - memcpy(pipename,deps.s+sv->pipeline,len) ; - pipename[len] = 0 ; - if (!file_write_unsafe(pipefile,get_key_by_enum(ENUM_LOGOPTS,LOGOPTS_PIPE),pipename,len)) - log_warnu_return(LOG_EXIT_ZERO,"write: ",pipefile,get_key_by_enum(ENUM_LOGOPTS,LOGOPTS_PIPE)) ; - } - - return 1 ; -} - -int write_common(sv_alltype *sv, char const *dst,uint8_t conf) -{ - log_flow() ; - - char *time = NULL ; - char *src = keep.s + sv->src ; - size_t dstlen = strlen(dst) ; - size_t srclen = strlen(src) ; - /**down file*/ - if (sv->flags[0] > 0) - { - if (!file_create_empty(dst,"down",0644)) - log_warnusys_return(LOG_EXIT_ZERO,"create down file") ; - } - - /**notification-fd*/ - if (sv->notification > 0) - { - if (!write_uint(dst,"notification-fd", sv->notification)) - log_warnu_return(LOG_EXIT_ZERO,"write notification file") ; - } - /**timeout family*/ - for (uint32_t i = 0; i < 4;i++) - { - if (sv->timeout[i][0] > 0) - { - - if (!i) - time = "timeout-kill" ; - if (i) - time = "timeout-finish" ; - if (i > 1) - time = "timeout-up" ; - if (i > 2) - time = "timeout-down" ; - - if (!write_uint(dst, time, sv->timeout[i][0])) - log_warnu_return(LOG_EXIT_ZERO,"write file: ",time) ; - } - - } - /** type file*/ - if (sv->cname.itype > TYPE_CLASSIC) - { - if (!file_write_unsafe(dst,"type",get_key_by_enum(ENUM_TYPE,sv->cname.itype),strlen(get_key_by_enum(ENUM_TYPE,sv->cname.itype)))) - log_warnusys_return(LOG_EXIT_ZERO,"write type file") ; - } - /** max-death-tally */ - if (sv->death > 0) - { - if (!write_uint(dst, "max-death-tally", sv->death)) - log_warnu_return(LOG_EXIT_ZERO,"write max-death-tally file") ; - } - /**down-signal*/ - if (sv->signal > 0) - { - if (!write_uint(dst,"down-signal", sv->signal)) - log_warnu_return(LOG_EXIT_ZERO,"write down-signal file") ; - } - /** environment */ - /** do not pass through here if the service is a module type. - * the environment file was already written */ - if (sv->opts[2] > 0 && sv->cname.itype != TYPE_MODULE) - { - stralloc dst = STRALLOC_ZERO ; - stralloc contents = STRALLOC_ZERO ; - stralloc name = STRALLOC_ZERO ; - - if (!env_prepare_for_write(&name,&dst,&contents,sv,conf)) - return 0 ; - - if (!write_env(name.s,contents.s,dst.s)) - log_warnu_return(LOG_EXIT_ZERO,"write environment") ; - - stralloc_free(&dst) ; - stralloc_free(&contents) ; - stralloc_free(&name) ; - } - /** hierarchy copy */ - if (sv->hiercopy[0]) - { - int r ; - for (uint32_t i = 0 ; i < sv->hiercopy[0] ; i++) - { - char *what = keep.s + sv->hiercopy[i+1] ; - size_t whatlen = strlen(what) ; - char tmp[4095 + 1] ; - char basedir[srclen + 1] ; - if (!ob_dirname(basedir,src)) - log_warnu_return(LOG_EXIT_ZERO,"get dirname of: ",src) ; - - if (what[0] == '/' || what[0] == '.') - { - if (!dir_beabsolute(tmp,what)) - log_warnusys_return(LOG_EXIT_ZERO,"find absolute path of: ",what) ; - } - else - { - auto_strings(tmp,basedir,what) ; - } - - char dtmp[dstlen + 1 + whatlen] ; - auto_strings(dtmp,dst,"/",what) ; - - r = scan_mode(tmp,S_IFDIR) ; - if (r <= 0) - { - r = scan_mode(tmp,S_IFREG) ; - if (!r) log_warnusys_return(LOG_EXIT_ZERO,"find: ",tmp) ; - if (r < 0) { errno = ENOTSUP ; log_warnsys_return(LOG_EXIT_ZERO,"invalid format of: ",tmp) ; } - } - if (!hiercopy(tmp,dtmp)) - log_warnusys_return(LOG_EXIT_ZERO,"copy: ",tmp," to: ",dtmp) ; - } - } - return 1 ; -} - -int write_exec(sv_alltype *sv, sv_exec *exec,char const *file,char const *dst,mode_t mode) -{ - log_flow() ; - - unsigned int type = sv->cname.itype ; - int build = exec->build < 0 ? BUILD_AUTO : exec->build ; - uid_t owner = MYUID ; - size_t filelen = strlen(file) ; - size_t dstlen = strlen(dst) ; - char write[dstlen + 1 + filelen + 1] ; - - stralloc home = STRALLOC_ZERO ; - stralloc shebang = STRALLOC_ZERO ; - stralloc ui = STRALLOC_ZERO ; - stralloc env = STRALLOC_ZERO ; - stralloc runuser = STRALLOC_ZERO ; - stralloc execute = STRALLOC_ZERO ; - stralloc destlog_oneshot = STRALLOC_ZERO ; - - if (type == TYPE_ONESHOT) - { - if (!stralloc_cats(&shebang,EXECLINE_BINPREFIX "fdmove -c 2 1\n")) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - if (sv->opts[0]) - { - /** prepare oneshot logger */ - if (!write_oneshot_logger(&destlog_oneshot,sv)) return 0 ; - - if (!stralloc_cats(&shebang,"redirfd -a 1 ") || - !stralloc_cats(&shebang,destlog_oneshot.s) || - !stralloc_cats(&shebang,"\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - } - switch (build) - { - case BUILD_AUTO: - /** uid */ - if (!owner && (exec->runas >= 0)) - { - if (!stralloc_cats(&ui,S6_BINPREFIX "s6-setuidgid ") || - !stralloc_cats(&ui,keep.s + exec->runas) || - !stralloc_cats(&ui,"\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - /** environment */ - if (sv->opts[2] && (build == BUILD_AUTO)) - { - if (!stralloc_cats(&env,SS_BINPREFIX "execl-envfile ") || - !stralloc_cats(&env,keep.s + sv->srconf) || - !stralloc_cats(&env,SS_SYM_VERSION) || - !stralloc_cats(&env,"\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - /** shebang */ - if (type != TYPE_ONESHOT) - { - if (!stralloc_cats(&shebang, "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - break ; - case BUILD_CUSTOM: - if (type != TYPE_ONESHOT) - { - if (!stralloc_cats(&shebang, "#!") || - !stralloc_cats(&shebang, keep.s+exec->shebang) || - !stralloc_cats(&shebang,"\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - else - { - if (!stralloc_cats(&shebang, keep.s+exec->shebang) || - !stralloc_cats(&shebang," \"")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - break ; - default: log_warn(LOG_EXIT_ZERO,"unknown ", get_key_by_enum(ENUM_BUILD,build)," build type") ; - break ; - } - /** close uid */ - if (!stralloc_0(&ui)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - /** close env*/ - if (!stralloc_0(&env)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - /** close shebang */ - if (!stralloc_0(&shebang)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - /** close command */ - if (!stralloc_cats(&runuser, keep.s+exec->exec)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if ((type == TYPE_ONESHOT) && (build == BUILD_CUSTOM)) - { - if (!stralloc_cats(&runuser," \"")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - if (!stralloc_cats(&runuser,"\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_0(&runuser)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - /** build the file*/ - if (!stralloc_cats(&execute,shebang.s)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if ((build == BUILD_AUTO) && (sv->cname.itype != TYPE_ONESHOT)) - { - if (!stralloc_cats(&execute,EXECLINE_BINPREFIX "fdmove -c 2 1\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - - if (!stralloc_cats(&execute,env.s) || - !stralloc_cats(&execute,ui.s) || - !stralloc_cats(&execute,runuser.s)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - memcpy(write,dst,dstlen) ; - write[dstlen] = '/' ; - memcpy(write + dstlen + 1, file, filelen) ; - write[dstlen + 1 + filelen] = 0 ; - - if (!file_write_unsafe(dst,file,execute.s,execute.len)) - log_warnusys_return(LOG_EXIT_ZERO,"write: ",dst,"/",file) ; - - if (chmod(write, mode) < 0) - log_warnusys_return(LOG_EXIT_ZERO,"chmod ", write) ; - - /** keep the exec file */ - if (!stralloc_insertb(&execute,0,"\n",1)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - if (!stralloc_0(&execute)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - exec->real_exec = keep.len ; - if (!stralloc_catb(&keep,execute.s,strlen(execute.s) + 1)) - log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; - - stralloc_free(&home) ; - stralloc_free(&shebang) ; - stralloc_free(&ui) ; - stralloc_free(&execute) ; - stralloc_free(&env) ; - stralloc_free(&runuser) ; - stralloc_free(&execute) ; - stralloc_free(&destlog_oneshot) ; - return 1 ; -} - -int write_dependencies(unsigned int nga,unsigned int idga,char const *dst,char const *filename) -{ - log_flow() ; - - stralloc contents = STRALLOC_ZERO ; - size_t id = idga, nid = nga ; - for (;nid; id += strlen(deps.s + id) + 1, nid--) - { - if (!stralloc_cats(&contents,deps.s + id) || - !stralloc_cats(&contents,"\n")) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - /** file contents for a bundle must be present even if it's an empty one */ - if (contents.len || obstr_equal(filename,SS_CONTENTS)) - { - if (!file_write_unsafe(dst,filename,contents.s,contents.len)) - { - log_warnusys("create file: ",dst,filename) ; - goto err ; - } - } - - stralloc_free(&contents) ; - return 1 ; - err: - stralloc_free(&contents) ; - return 0 ; -} - -int 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_warnusys_return(LOG_EXIT_ZERO,"write: ",dst,"/",name) ; - - return 1 ; -} - -int write_env(char const *name, char const *contents,char const *dst) -{ - log_flow() ; - - log_flow() ; - - int r ; - size_t contents_len = strlen(contents) ; - - r = scan_mode(dst,S_IFDIR) ; - if (r < 0) - log_warn_return(LOG_EXIT_ZERO," conflicting format of the environment directory: ",dst) ; - else if (!r) - log_warnusys_return(LOG_EXIT_ZERO,"find environment directory: ",dst) ; - - if (!file_write_unsafe(dst,name,contents,contents_len)) - log_warnusys_return(LOG_EXIT_ZERO,"create file: ",dst,"/",name) ; - - return 1 ; -} - -int write_oneshot_logger(stralloc *destlog, sv_alltype *sv) -{ - log_flow() ; - - if (sv->opts[0]) - { - int r ; - uid_t owner = MYUID ; - size_t len ; - char const *userhome ; - char *svname = keep.s + sv->cname.name ; - - userhome = get_userhome(owner) ; - - //if (sv->type.oneshot.log.destination < 0) - { - if(owner > 0) - { - if (!auto_stra(destlog,userhome,"/",SS_LOGGER_USERDIR,svname)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - else - { - if (!auto_stra(destlog,SS_LOGGER_SYSDIR,svname)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - } - /** Section logger has no effect with oneshot - * this implementation is for the future - * - else - { - if (!auto_stra(&destlog,keep.s+log->destination)) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - */ - r = scan_mode(destlog->s,S_IFDIR) ; - if (r == -1) - log_warn_return(LOG_EXIT_ZERO,"log directory: ", destlog->s,": already exist with a different mode") ; - - if (!dir_create_parent(destlog->s,0755)) - log_warnusys_return(LOG_EXIT_ZERO,"create log directory: ",destlog->s) ; - - len = destlog->len ; - if (!auto_stra(destlog,"/current")) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - - r = scan_mode(destlog->s,S_IFREG) ; - if (!r) - { - destlog->s[len] = 0 ; - destlog->len = len ; - if (!file_write_unsafe(destlog->s,"current","",0)) - log_warnusys_return(LOG_EXIT_ZERO,"write: ",destlog->s,"/current") ; - - if (!auto_stra(destlog,"/current")) - log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ; - } - } - - return 1 ; -} -- GitLab