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