From 806ebe56411159c5253ac9fbacfa92c2855e8f52 Mon Sep 17 00:00:00 2001 From: obarun <eric@obarun.org> Date: Sun, 19 May 2024 00:05:50 +1100 Subject: [PATCH] respect -s options at edition time. make exclusive -s and -c options. use new environment function from oblibs. less HEAP memory usage. --- src/lib66/exec/ssexec_env.c | 238 ++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 136 deletions(-) diff --git a/src/lib66/exec/ssexec_env.c b/src/lib66/exec/ssexec_env.c index 86eed569..2443e526 100644 --- a/src/lib66/exec/ssexec_env.c +++ b/src/lib66/exec/ssexec_env.c @@ -61,11 +61,11 @@ static uint8_t check_current_version(char const *svconf,char const *version) { log_flow() ; - stralloc sa = STRALLOC_ZERO ; + _alloc_sa_(sa) ; if (!env_find_current_version(&sa,svconf)) log_dieu(LOG_EXIT_SYS,"find current version") ; char bname[sa.len + 1] ; if (!ob_basename(bname,sa.s)) log_dieu(LOG_EXIT_SYS,"get basename of: ",sa.s) ; - stralloc_free(&sa) ; + return !version_cmp(bname,version,SS_CONFIG_VERSION_NDOT) ? 1 : 0 ; } @@ -114,48 +114,6 @@ static void do_import(char const *svname, char const *svconf, char const *versio log_dieu(LOG_EXIT_SYS,"import configuration file from version: ",src_version," to version: ",dst_version) ; } -static void replace_value_of_key(stralloc *srclist,char const *key) -{ - log_flow() ; - - _alloc_sa_(sakey) ; - _alloc_stk_(line, strlen(key) + 1) ; - - int start = -1 ,end = -1 ; - - if (!environ_get_key(&line,key)) - log_dieusys(LOG_EXIT_SYS,"get key: ",key, " from environments") ; - - if (!stack_add(&line, "=", 1)) - log_die_nomem("stack") ; - - start = sastr_find(srclist,line.s) ; - if (start == -1) { - log_1_warnu("find key: ",line.s) ; - return ; - } - - end = get_len_until(srclist->s + start,'\n') ; - - if (end == -1) - log_dieu(LOG_EXIT_SYS,"find end of line") ; - - if (!stralloc_catb(&sakey,srclist->s + start,end ) || - !stralloc_0(&sakey)) - log_die_nomem("stralloc") ; - - if (!strcmp(sakey.s,key)) - return ; - - if (!sastr_replace(srclist,sakey.s,key)) - log_dieu(LOG_EXIT_SYS,"replace: ",sakey.s," by: ",key) ; - - if (!stralloc_0(srclist)) - log_die_nomem("stralloc") ; - - srclist->len-- ; -} - static void write_user_env_file(char const *src, char const *sv) { size_t srclen = strlen(src), svlen = strlen(sv) ; @@ -197,18 +155,15 @@ int ssexec_env(int argc, char const *const *argv, ssexec_t *info) int r ; size_t pos = 0 ; - stralloc satmp = STRALLOC_ZERO ; - stralloc sasrc = STRALLOC_ZERO ; - stralloc saversion = STRALLOC_ZERO ; - stralloc eversion = STRALLOC_ZERO ; - stralloc savar = STRALLOC_ZERO ; - stralloc salist = STRALLOC_ZERO ; + _alloc_sa_(satmp) ; + _alloc_sa_(src) ; + _alloc_sa_(savar) ; resolve_service_t res = RESOLVE_SERVICE_ZERO ; resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ; - uint8_t todo = T_UNSET ; + uint8_t todo = T_UNSET, current = 0 ; - char const *sv = 0, *svconf = 0, *src = 0, *import = 0 ; + char const *sv = 0, *svconf = 0, *import = 0 ; { subgetopt l = SUBGETOPT_ZERO ; @@ -227,15 +182,23 @@ int ssexec_env(int argc, char const *const *argv, ssexec_t *info) case 'c' : - if (env_check_version(&saversion,l.arg) <= 0) - log_dieu(LOG_EXIT_SYS,"check version format") ; + if (satmp.len) + log_die(LOG_EXIT_USER, "-c and -s options are mutually exclusive") ; + + if (!auto_stra(&satmp, l.arg)) + log_die_nomem("stralloc") ; + + current++ ; break ; case 's' : - if (env_check_version(&eversion,l.arg) <= 0) - log_dieu(LOG_EXIT_SYS,"check version format") ; + if (satmp.len) + log_die(LOG_EXIT_USER, "-c and -s options are mutually exclusive") ; + + if (!auto_stra(&satmp, l.arg)) + log_die_nomem("stralloc") ; break ; @@ -284,7 +247,7 @@ int ssexec_env(int argc, char const *const *argv, ssexec_t *info) if (argc < 1) log_usage(info->usage, "\n", info->help) ; sv = argv[0] ; - if (todo == T_UNSET && !import && !saversion.len && !eversion.len) todo = T_EDIT ; + if (todo == T_UNSET && !import && !current) todo = T_EDIT ; r = service_is_g(sv, STATE_FLAGS_ISPARSED) ; if (r == -1) @@ -298,130 +261,133 @@ int ssexec_env(int argc, char const *const *argv, ssexec_t *info) if (!res.environ.envdir) { log_1_warn(sv," do not have configuration file") ; - goto freed ; + resolve_free(wres) ; + return 0 ; } + if (!env_get_destination(&src, &res)) + log_dieusys(LOG_EXIT_SYS, "get current environment version") ; + svconf = res.sa.s + res.environ.envdir ; - if (saversion.len) - { - size_t conflen = strlen(svconf) ; - char sym[conflen + SS_SYM_VERSION_LEN + 1] ; - auto_strings(sym,svconf,SS_SYM_VERSION) ; + if (import) { + do_import(sv,svconf,import,res.type) ; + resolve_free(wres) ; + return 0 ; + } - if (!env_append_version(&saversion,svconf,saversion.s)) - log_dieu(LOG_EXIT_ZERO,"append version") ; + if (satmp.len) { - r = scan_mode(saversion.s,S_IFDIR) ; - if (r == -1 || !r) log_dieusys(LOG_EXIT_USER,"find the versioned directory: ",saversion.s) ; + src.len = 0 ; + if (!env_append_version(&src, svconf, satmp.s)) + log_dieu(LOG_EXIT_ZERO, "append version") ; - if (!atomic_symlink(saversion.s,sym,"ssexec_env")) - log_warnu_return(LOG_EXIT_ZERO,"symlink: ",sym," to: ",saversion.s) ; + if (current) { - log_info("symlink switched successfully to version: ",saversion.s) ; - } + size_t conflen = strlen(svconf) ; + char sym[conflen + SS_SYM_VERSION_LEN + 1] ; + auto_strings(sym, svconf, SS_SYM_VERSION) ; - if (import) - do_import(sv,svconf,import,res.type) ; + if (!atomic_symlink(src.s, sym, "ssexec_env")) + log_warnu_return(LOG_EXIT_ZERO, "symlink: ", sym, " to: ", src.s) ; - if (eversion.len) - { - if (!env_append_version(&sasrc,svconf,eversion.s)) - log_dieu(LOG_EXIT_SYS,"append version") ; + log_info("symlink switched successfully to version: ", src.s) ; - src = sasrc.s ; - } - else - { - if (!auto_stra(&sasrc,svconf,SS_SYM_VERSION)) log_die_nomem("stralloc") ; - if (sareadlink(&satmp,sasrc.s) == -1) log_dieusys(LOG_EXIT_SYS,"readlink: ",sasrc.s) ; - if (!stralloc_0(&satmp) || - !stralloc_copy(&sasrc,&satmp)) log_die_nomem("stralloc") ; - src = sasrc.s ; + resolve_free(wres) ; + return 0 ; + } + + satmp.len = 0 ; } - satmp.len = 0 ; + resolve_free(wres) ; switch(todo) { case T_VLIST: { char const *exclude[2] = { SS_SYM_VERSION + 1, 0 } ; - if (!sastr_dir_get(&satmp,svconf,exclude,S_IFDIR)) - log_dieu(LOG_EXIT_SYS,"get versioned directory of: ",svconf) ; - } - for (pos = 0 ; pos < satmp.len; pos += strlen(satmp.s + pos) + 1) - { - if (buffer_puts(buffer_1, svconf) < 0) - log_dieusys(LOG_EXIT_SYS, "write to stdout") ; - if (buffer_puts(buffer_1, "/") < 0) - log_dieusys(LOG_EXIT_SYS, "write to stdout") ; - if (buffer_puts(buffer_1, satmp.s + pos) < 0) - log_dieusys(LOG_EXIT_SYS, "write to stdout") ; - if (check_current_version(svconf,satmp.s + pos)) - if (buffer_putsflush(buffer_1, " current") < 0) + if (!sastr_dir_get(&satmp, svconf, exclude, S_IFDIR)) + log_dieu(LOG_EXIT_SYS, "get versioned directory of: ", svconf) ; + + pos = 0 ; + FOREACH_SASTR(&satmp, pos) { + + if (buffer_puts(buffer_1, svconf) < 0 || + buffer_puts(buffer_1, "/") < 0 || + buffer_puts(buffer_1, satmp.s + pos) < 0) + log_dieusys(LOG_EXIT_SYS, "write to stdout") ; + if (check_current_version(svconf, satmp.s + pos)) { + if (buffer_putsflush(buffer_1, " current") < 0) + log_dieusys(LOG_EXIT_SYS, "write to stdout") ; + } + if (buffer_putsflush(buffer_1, "\n") < 0) log_dieusys(LOG_EXIT_SYS, "write to stdout") ; - if (buffer_putsflush(buffer_1, "\n") < 0) - log_dieusys(LOG_EXIT_SYS, "write to stdout") ; + } } break ; case T_LIST: { char const *exclude[2] = { SS_SYM_VERSION + 1, 0 } ; - if (!sastr_dir_get(&satmp,src,exclude,S_IFREG)) - log_dieu(LOG_EXIT_SYS,"get versioned directory at: ",src) ; - } - for (pos = 0 ; pos < satmp.len; pos += strlen(satmp.s + pos) + 1) - { - salist.len = 0 ; - char *name = satmp.s + pos ; - if (!file_readputsa(&salist,src,name)) log_dieusys(LOG_EXIT_SYS,"read: ",src,"/",name) ; - if (!stralloc_0(&salist)) log_die_nomem("stralloc") ; - log_info("contents of file: ",src,"/",name,"\n",salist.s) ; + if (!sastr_dir_get(&satmp, src.s, exclude, S_IFREG)) + log_dieu(LOG_EXIT_SYS, "get versioned directory at: ", src.s) ; + + pos = 0 ; + FOREACH_SASTR(&satmp, pos) { + + char *name = satmp.s + pos ; + _alloc_stk_(file, src.len + strlen(name) + 2) ; + auto_strings(file.s, src.s, "/", name) ; + size_t filen = file_get_size(file.s) ; + _alloc_stk_(list, filen + 1) ; + + if (!stack_read_file(&list, file.s)) + log_dieusys(LOG_EXIT_SYS,"read: ", file.s) ; + + log_info("contents of file: ", file.s, "\n", list.s) ; + } } break ; case T_REPLACE: - /** the user configuration file may not exist yet - * We read the upstream file if it's the case and write - * the change to the user file */ - write_user_env_file(src,sv) ; + { + /** the user configuration file may not exist yet + * We read the upstream file if it's the case and write + * the change to the user file */ + write_user_env_file(src.s, sv) ; + + _alloc_stk_(file, strlen(src.s) + strlen(sv) + 2) ; + _alloc_sa_(env) ; - if (!file_readputsa(&salist,src,sv)) - log_dieusys(LOG_EXIT_SYS,"read: ",src,"/",sv) ; + auto_strings(file.s, src.s, "/", sv) ; - FOREACH_SASTR(&savar,pos) { + if (!environ_merge_file(&env, file.s)) + log_dieusys(LOG_EXIT_SYS, "merge environment file: ", file.s) ; - char *key = savar.s + pos ; + if (!environ_merge_environ(&env, &savar)) + log_dieusys(LOG_EXIT_SYS, "merge environment from command line") ; - replace_value_of_key(&salist,key) ; - } - if (!auto_stra(&satmp,src,"/",sv)) log_die_nomem("stralloc") ; + if (!environ_rebuild(&env)) + log_dieusys(LOG_EXIT_SYS, "rebuild environment") ; - if (!openwritenclose_unsafe(satmp.s,salist.s,salist.len)) - log_dieusys(LOG_EXIT_SYS,"write file: ",satmp.s) ; + if (!openwritenclose_unsafe(file.s, env.s, env.len)) + log_dieusys(LOG_EXIT_SYS,"write file: ", file.s) ; + } break ; case T_EDIT: - write_user_env_file(src,sv) ; + write_user_env_file(src.s,sv) ; - run_editor(src, sv) ; + run_editor(src.s, sv) ; + + break ; /** Can't happens */ default: break ; } - freed: - stralloc_free(&satmp) ; - stralloc_free(&sasrc) ; - stralloc_free(&saversion) ; - stralloc_free(&eversion) ; - stralloc_free(&savar) ; - stralloc_free(&salist) ; - resolve_free(wres) ; - return 0 ; } -- GitLab