diff --git a/src/lib66/environ/deps-lib/deps b/src/lib66/environ/deps-lib/deps index e8c93124d73f756fe123f0bcf5d1dc2a872f573b..09fe8425a805cd3d706f6f607bb123f80064ee25 100644 --- a/src/lib66/environ/deps-lib/deps +++ b/src/lib66/environ/deps-lib/deps @@ -1,6 +1,15 @@ -environ.o +env_append_version.o +env_check_version.o +env_clean_with_comment.o +env_compute.o +env_find_current_version.o +env_import_version_file.o +env_make_symlink.o +env_prepare_for_write.o +env_resolve_conf.o -ls6rc -ls6 -loblibs -lexecline -lskarnet + diff --git a/src/lib66/environ/env_append_version.c b/src/lib66/environ/env_append_version.c new file mode 100644 index 0000000000000000000000000000000000000000..a548a020cf386b5674416288a00f08c8961f3549 --- /dev/null +++ b/src/lib66/environ/env_append_version.c @@ -0,0 +1,48 @@ +/* + * env_appand_version.c + * + * Copyright (c) 2018-2022 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 <sys/stat.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/types.h> + +#include <skalibs/stralloc.h> + +#include <66/environ.h> + +int env_append_version(stralloc *saversion, char const *svconf, char const *version) +{ + log_flow() ; + + int r ; + + stralloc sa = STRALLOC_ZERO ; + + if (!env_check_version(&sa,version)) + return 0 ; + + saversion->len = 0 ; + + if (!auto_stra(saversion,svconf,"/",sa.s)) + log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; + + r = scan_mode(saversion->s,S_IFDIR) ; + if (r == -1 || !r) + log_warnusys_return(LOG_EXIT_ZERO,"find the versioned directory: ",saversion->s) ; + + stralloc_free(&sa) ; + + return 1 ; +} diff --git a/src/lib66/environ/env_check_version.c b/src/lib66/environ/env_check_version.c new file mode 100644 index 0000000000000000000000000000000000000000..f97286eb90fb057e22213c968166ea40676f70bf --- /dev/null +++ b/src/lib66/environ/env_check_version.c @@ -0,0 +1,38 @@ +/* + * env_check_version.c + * + * Copyright (c) 2018-2022 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 <oblibs/log.h> +#include <oblibs/string.h> + +#include <skalibs/stralloc.h> + +#include <66/environ.h> +#include <66/constants.h> + +int env_check_version(stralloc *sa, char const *version) +{ + log_flow() ; + + int r ; + + r = version_scan(sa,version,SS_CONFIG_VERSION_NDOT) ; + + if (r == -1) + log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; + + if (!r) + log_warn_return(LOG_EXIT_ZERO,"invalid version format: ",version) ; + + return 1 ; +} diff --git a/src/lib66/environ/env_clean_with_comment.c b/src/lib66/environ/env_clean_with_comment.c new file mode 100644 index 0000000000000000000000000000000000000000..02d70351cf3dd4de49c9bfafeb2112da07a19c4f --- /dev/null +++ b/src/lib66/environ/env_clean_with_comment.c @@ -0,0 +1,69 @@ +/* + * env_clean_with_comment.c + * + * Copyright (c) 2018-2022 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 <sys/types.h> + +#include <oblibs/log.h> +#include <oblibs/sastr.h> +#include <oblibs/string.h> +#include <oblibs/environ.h> + +#include <66/environ.h> +#include <skalibs/stralloc.h> + +int env_clean_with_comment(stralloc *sa) +{ + log_flow() ; + + ssize_t pos = 0, r ; + char *end = 0, *start = 0 ; + stralloc final = STRALLOC_ZERO ; + stralloc tmp = STRALLOC_ZERO ; + + if (!sastr_split_string_in_nline(sa)) + log_warnu_return(LOG_EXIT_ZERO,"split environment value") ; + + for (; pos < sa->len ; pos += strlen(sa->s + pos) + 1) + { + tmp.len = 0 ; + if (!sastr_clean_string(&tmp,sa->s + pos)) + log_warnu_return(LOG_EXIT_ZERO,"clean environment string") ; + /** keep a empty line between key=value pair and a comment */ + r = get_len_until(tmp.s,'=') ; + end = r < 0 ? "\n" : "\n\n" ; + start = r < 0 ? "" : "\n" ; + + if (tmp.s[0] == '#') + { + if (!sastr_rebuild_in_oneline(&tmp)) + log_warnu_return(LOG_EXIT_ZERO,"rebuild environment string in one line") ; + } + else + { + if (!environ_rebuild_line(&tmp)) + log_warnu_return(LOG_EXIT_ZERO,"rebuild environment line") ; + } + if (!stralloc_0(&tmp) || + !auto_stra(&final,start,tmp.s,end)) + log_warn_return(LOG_EXIT_ZERO,"stralloc") ; + } + sa->len = 0 ; + if (!auto_stra(sa,final.s)) + log_warnu_return(LOG_EXIT_ZERO,"store environment value") ; + + stralloc_free(&tmp) ; + stralloc_free(&final) ; + + return 1 ; +} diff --git a/src/lib66/environ/env_compute.c b/src/lib66/environ/env_compute.c new file mode 100644 index 0000000000000000000000000000000000000000..fb2399e6e471b766bc4b48f8f9c89eb306a725d2 --- /dev/null +++ b/src/lib66/environ/env_compute.c @@ -0,0 +1,88 @@ +/* + * env_compute.c + * + * Copyright (c) 2018-2022 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 <stdint.h> +#include <string.h> + +#include <oblibs/string.h> +#include <oblibs/log.h> + +#include <skalibs/stralloc.h> + +#include <66/environ.h> +#include <66/parser.h> + + +int env_compute(stralloc *result,sv_alltype *sv, uint8_t conf) +{ + log_flow() ; + + int r ; + char *version = keep.s + sv->cname.version ; + char *svconf = keep.s + sv->srconf ; + char *name = keep.s + sv->cname.name ; + size_t svconf_len = strlen(svconf), version_len = strlen(version) ; + char src[svconf_len + 1 + version_len + 1] ; + + auto_strings(src,svconf,"/",version) ; + + /** previous version, this is the current version before + * the switch with env_make_symlink() */ + stralloc pversion = STRALLOC_ZERO ; + // future version, the one which we want + stralloc fversion = STRALLOC_ZERO ; + + /** store current configure file version before the switch + * of the symlink with the env_make_symlink() function */ + r = env_find_current_version(&pversion,svconf) ; + + if (r == -1) + log_warnu_return(LOG_EXIT_ZERO,"find previous configuration file version") ; + + if(!env_make_symlink(sv)) + return 0 ; + + /** !r means that previous version doesn't exist, no need to import anything */ + if (r && !conf) { + + r = env_find_current_version(&fversion,svconf) ; + /** should never happen, the env_make_symlink() die in case of error */ + if (r <= 0) + log_warnu_return(LOG_EXIT_ZERO,"find current configuration file version") ; + + char pv[pversion.len + 1] ; + char fv[fversion.len + 1] ; + + if (!ob_basename(pv,pversion.s)) + log_warnu_return(LOG_EXIT_ZERO,"get basename of: ",pversion.s) ; + + if (!ob_basename(fv,fversion.s)) + log_warnu_return(LOG_EXIT_ZERO,"get basename of: ",fversion.s) ; + + if (!env_import_version_file(name,svconf,pv,fv,sv->cname.itype)) + return 0 ; + + } + + if (!auto_stra(result, \ + "## [STARTWARN]\n## DO NOT MODIFY THIS FILE, IT OVERWRITTEN AT UPGRADE TIME.\n## Uses \'66-env ", \ + name,"\' command instead.\n## Or make a copy of this file at ",src,"/",name, \ + " and modify it.\n## [ENDWARN]\n",sv->saenv.s)) + log_warnu_return(LOG_EXIT_ZERO,"stralloc") ; + + stralloc_free(&pversion) ; + stralloc_free(&fversion) ; + + return 1 ; +} diff --git a/src/lib66/environ/env_find_current_version.c b/src/lib66/environ/env_find_current_version.c new file mode 100644 index 0000000000000000000000000000000000000000..97ebb8ac66c9f6636da32630a16eabfa495df99d --- /dev/null +++ b/src/lib66/environ/env_find_current_version.c @@ -0,0 +1,48 @@ +/* + * env_find_current_version.c + * + * Copyright (c) 2018-2022 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 <sys/stat.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> + +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +#include <66/environ.h> +#include <66/constants.h> + +int env_find_current_version(stralloc *sa,char const *svconf) +{ + log_flow() ; + + size_t svconflen = strlen(svconf) ; + struct stat st ; + char tmp[svconflen + SS_SYM_VERSION_LEN + 1] ; + + auto_strings(tmp,svconf,SS_SYM_VERSION) ; + + /** symlink may no exist yet e.g first activation of the service */ + if (lstat(tmp,&st) == -1) + return 0 ; + + if (sareadlink(sa,tmp) == -1) + return -1 ; + + if (!stralloc_0(sa)) + log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; + + return 1 ; +} diff --git a/src/lib66/environ/env_import_version_file.c b/src/lib66/environ/env_import_version_file.c new file mode 100644 index 0000000000000000000000000000000000000000..d27f7e9a89cf59c3d0414bb0befc3f959d91f97a --- /dev/null +++ b/src/lib66/environ/env_import_version_file.c @@ -0,0 +1,130 @@ +/* + * env_import_version_file.c + * + * Copyright (c) 2018-2022 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 <sys/stat.h> +#include <string.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/sastr.h> + +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +#include <66/environ.h> +#include <66/constants.h> +#include <66/enum.h> + + +int env_import_version_file(char const *svname, char const *svconf, char const *sversion, char const *dversion, int svtype) +{ + log_flow() ; + + int r ; + struct stat st ; + size_t pos = 0, svname_len= strlen(svname) ; + stralloc salist = STRALLOC_ZERO ; + stralloc src_ver = STRALLOC_ZERO ; + stralloc dst_ver = STRALLOC_ZERO ; + + char svname_dot[svname_len + 1 + 1] ; + + auto_strings(svname_dot,".",svname) ; + + r = version_cmp(sversion,dversion,SS_CONFIG_VERSION_NDOT) ; + + if (!r) { + + log_warn_return(LOG_EXIT_ONE,"same configuration file version for: ",svname," -- nothing to import") ; + goto freed ; + } + + if (r == -2) + log_warn_return(LOG_EXIT_ZERO,"compare ",svname," version: ",sversion," vs: ",dversion) ; + + if (r == 1) { + + log_warn_return(LOG_EXIT_ONE,"configuration file version regression for ",svname," -- ignoring configuration file version importation") ; + goto freed ; + } + + if (!env_append_version(&src_ver,svconf,sversion) || + !env_append_version(&dst_ver,svconf,dversion)) + return 0 ; + + char const *exclude[2] = { svname_dot, 0 } ; + if (!sastr_dir_get(&salist,src_ver.s,exclude,S_IFREG)) + log_warnusys_return(LOG_EXIT_ZERO,"get configuration file from directory: ",src_ver.s) ; + + FOREACH_SASTR(&salist,pos) { + + char *name = salist.s + pos ; + size_t namelen = strlen(name) ; + + char s[src_ver.len + 1 + namelen + 1] ; + auto_strings(s,src_ver.s,"/",name) ; + + char d[dst_ver.len + 1 + namelen + 1] ; + auto_strings(d,dst_ver.s,"/",name) ; + + if (lstat(s, &st) < 0) + log_warnusys_return(LOG_EXIT_ZERO,"stat: ",s) ; + + log_info("imports ",svname," configuration file from: ",s," to: ",d) ; + + if (!filecopy_unsafe(s, d, st.st_mode)) + log_warnusys_return(LOG_EXIT_ZERO,"copy: ", s," to: ",d) ; + } + + /** A module type can have multiple sub-modules. Copy these directories + * to keep trace of previous configuration file for a sub-module. + * If we don't copy these directories, when the sub-module is parsed + * the previous configuration doesn't exist and so this function do not + * import anything */ + + if (svtype == TYPE_MODULE) { + + salist.len = 0 ; + pos = 0 ; + + char const *exclude[1] = { 0 } ; + if (!sastr_dir_get(&salist,src_ver.s,exclude,S_IFDIR)) + log_warnusys_return(LOG_EXIT_ZERO,"get configuration directories from directory: ",src_ver.s) ; + + FOREACH_SASTR(&salist,pos) { + + char *name = salist.s + pos ; + size_t namelen = strlen(name) ; + + char s[src_ver.len + 1 + namelen + 1] ; + auto_strings(s,src_ver.s,"/",name) ; + + char d[dst_ver.len + 1 + namelen + 1] ; + auto_strings(d,dst_ver.s,"/",name) ; + + log_info("imports ",svname," configuration file from: ",s," to: ",d) ; + + if (!hiercopy(s,d)) + log_warnusys_return(LOG_EXIT_ZERO,"copy: ",s," to: ",d) ; + } + + } + + freed: + stralloc_free(&src_ver) ; + stralloc_free(&dst_ver) ; + stralloc_free(&salist) ; + + return 1 ; +} diff --git a/src/lib66/environ/env_make_symlink.c b/src/lib66/environ/env_make_symlink.c new file mode 100644 index 0000000000000000000000000000000000000000..e47a5e4aab3cbe9a57e21931647680fc11588689 --- /dev/null +++ b/src/lib66/environ/env_make_symlink.c @@ -0,0 +1,52 @@ +/* + * env_make_symlink.c + * + * Copyright (c) 2018-2022 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 <oblibs/log.h> +#include <oblibs/string.h> +#include <oblibs/directory.h> + +#include <skalibs/unix-transactional.h>//atomic_symlink + +#include <66/environ.h> +#include <66/parser.h> +#include <66/constants.h> + +int env_make_symlink(sv_alltype *sv) +{ + log_flow() ; + + /** svconf-> /etc/66/conf/<service_name> */ + char *svconf = keep.s + sv->srconf ; + char *version = keep.s + sv->cname.version ; + size_t version_len = strlen(version), svconf_len = strlen(svconf) ; + char sym_version[svconf_len + SS_SYM_VERSION_LEN + 1] ; + + char dst[svconf_len + 1 + version_len + 1] ; + + auto_strings(dst,svconf,"/",version) ; + + auto_strings(sym_version,svconf,SS_SYM_VERSION) ; + + if (!dir_create_parent(dst,0755)) + log_warnsys_return(LOG_EXIT_ZERO,"create directory: ",dst) ; + + /** atomic_symlink check if exist + * if it doesn't exist, it create it*/ + if (!atomic_symlink(dst,sym_version,"env_compute")) + log_warnu_return(LOG_EXIT_ZERO,"symlink: ",sym_version," to: ",dst) ; + + return 1 ; +} diff --git a/src/lib66/environ/env_prepare_for_write.c b/src/lib66/environ/env_prepare_for_write.c new file mode 100644 index 0000000000000000000000000000000000000000..0a5082cb7c1735a7590a4ba5966a8c02c8ca8f64 --- /dev/null +++ b/src/lib66/environ/env_prepare_for_write.c @@ -0,0 +1,52 @@ +/* + * env_prepare_for_write.c + * + * Copyright (c) 2018-2022 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 <stdint.h> +#include <string.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> + +#include <skalibs/stralloc.h> +#include <skalibs/djbunix.h> + +#include <66/environ.h> +#include <66/constants.h> +#include <66/parser.h> + + +int env_prepare_for_write(stralloc *name, stralloc *dst, stralloc *contents, sv_alltype *sv,uint8_t conf) +{ + log_flow() ; + + char *svconf = keep.s + sv->srconf ; + size_t svconf_len = strlen(svconf) ; + char sym[svconf_len + SS_SYM_VERSION_LEN + 1] ; + + auto_strings(sym,svconf,SS_SYM_VERSION) ; + + if (!env_compute(contents,sv,conf)) + log_warnu_return(LOG_EXIT_ZERO,"compute environment") ; + + if (sareadlink(dst, sym) == -1) + log_warnusys_return(LOG_EXIT_ZERO,"read link of: ",sym) ; + + if (!stralloc_0(dst)) + log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; + + if (!auto_stra(name,".",keep.s + sv->cname.name)) + log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; + + return 1 ; +} diff --git a/src/lib66/environ/env_resolve_conf.c b/src/lib66/environ/env_resolve_conf.c new file mode 100644 index 0000000000000000000000000000000000000000..842814b4db575cc19b4cc90b7491df65fd6463e8 --- /dev/null +++ b/src/lib66/environ/env_resolve_conf.c @@ -0,0 +1,42 @@ +/* + * env_resolve_conf.c + * + * Copyright (c) 2018-2022 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 <sys/types.h> +#include <string.h> + +#include <oblibs/log.h> +#include <oblibs/string.h> + +#include <skalibs/stralloc.h> + +#include <66/environ.h> +#include <66/constants.h> +#include <66/utils.h> + +int env_resolve_conf(stralloc *env,char const *svname, uid_t owner) +{ + log_flow() ; + + if (!owner) + { + if (!stralloc_cats(env,SS_SERVICE_ADMCONFDIR)) return 0 ; + } + else + { + if (!set_ownerhome(env,owner)) return 0 ; + if (!stralloc_cats(env,SS_SERVICE_USERCONFDIR)) return 0 ; + } + if (!auto_stra(env,svname)) return 0 ; + return 1 ; +} diff --git a/src/lib66/environ/environ.c b/src/lib66/environ/environ.c deleted file mode 100644 index d30e255836ebf2f55de9a7545c609c2eab46d21f..0000000000000000000000000000000000000000 --- a/src/lib66/environ/environ.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * environ.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 <sys/types.h> -#include <stdint.h> -#include <string.h> -#include <stdio.h>//rename -#include <errno.h> -#include <sys/stat.h> - -#include <oblibs/environ.h> -#include <oblibs/sastr.h> -#include <oblibs/files.h> -#include <oblibs/string.h> -#include <oblibs/types.h> -#include <oblibs/directory.h> - -#include <skalibs/unix-transactional.h>//atomic_symlink -#include <skalibs/stralloc.h> -#include <skalibs/djbunix.h>//rm_rf - -#include <66/constants.h> -#include <66/utils.h> -#include <66/environ.h> -#include <66/enum.h> - -int env_resolve_conf(stralloc *env,char const *svname, uid_t owner) -{ - log_flow() ; - - if (!owner) - { - if (!stralloc_cats(env,SS_SERVICE_ADMCONFDIR)) return 0 ; - } - else - { - if (!set_ownerhome(env,owner)) return 0 ; - if (!stralloc_cats(env,SS_SERVICE_USERCONFDIR)) return 0 ; - } - if (!auto_stra(env,svname)) return 0 ; - return 1 ; -} - -int env_make_symlink(sv_alltype *sv) -{ - log_flow() ; - - /** svconf-> /etc/66/conf/<service_name> */ - char *svconf = keep.s + sv->srconf ; - char *version = keep.s + sv->cname.version ; - size_t version_len = strlen(version), svconf_len = strlen(svconf) ; - char sym_version[svconf_len + SS_SYM_VERSION_LEN + 1] ; - - char dst[svconf_len + 1 + version_len + 1] ; - - auto_strings(dst,svconf,"/",version) ; - - auto_strings(sym_version,svconf,SS_SYM_VERSION) ; - - if (!dir_create_parent(dst,0755)) - log_warnsys_return(LOG_EXIT_ZERO,"create directory: ",dst) ; - - /** atomic_symlink check if exist - * if it doesn't exist, it create it*/ - if (!atomic_symlink(dst,sym_version,"env_compute")) - log_warnu_return(LOG_EXIT_ZERO,"symlink: ",sym_version," to: ",dst) ; - - return 1 ; -} - -int env_compute(stralloc *result,sv_alltype *sv, uint8_t conf) -{ - log_flow() ; - - int r ; - char *version = keep.s + sv->cname.version ; - char *svconf = keep.s + sv->srconf ; - char *name = keep.s + sv->cname.name ; - size_t svconf_len = strlen(svconf), version_len = strlen(version) ; - char src[svconf_len + 1 + version_len + 1] ; - - auto_strings(src,svconf,"/",version) ; - - /** previous version, this is the current version before - * the switch with env_make_symlink() */ - stralloc pversion = STRALLOC_ZERO ; - // future version, the one which we want - stralloc fversion = STRALLOC_ZERO ; - - /** store current configure file version before the switch - * of the symlink with the env_make_symlink() function */ - r = env_find_current_version(&pversion,svconf) ; - - if (r == -1) - log_warnu_return(LOG_EXIT_ZERO,"find previous configuration file version") ; - - if(!env_make_symlink(sv)) - return 0 ; - - /** !r means that previous version doesn't exist, no need to import anything */ - if (r && !conf) { - - r = env_find_current_version(&fversion,svconf) ; - /** should never happen, the env_make_symlink() die in case of error */ - if (r <= 0) - log_warnu_return(LOG_EXIT_ZERO,"find current configuration file version") ; - - char pv[pversion.len + 1] ; - char fv[fversion.len + 1] ; - - if (!ob_basename(pv,pversion.s)) - log_warnu_return(LOG_EXIT_ZERO,"get basename of: ",pversion.s) ; - - if (!ob_basename(fv,fversion.s)) - log_warnu_return(LOG_EXIT_ZERO,"get basename of: ",fversion.s) ; - - if (!env_import_version_file(name,svconf,pv,fv,sv->cname.itype)) - return 0 ; - - } - - if (!auto_stra(result, \ - "## [STARTWARN]\n## DO NOT MODIFY THIS FILE, IT OVERWRITTEN AT UPGRADE TIME.\n## Uses \'66-env ", \ - name,"\' command instead.\n## Or make a copy of this file at ",src,"/",name, \ - " and modify it.\n## [ENDWARN]\n",sv->saenv.s)) - log_warnu_return(LOG_EXIT_ZERO,"stralloc") ; - - stralloc_free(&pversion) ; - stralloc_free(&fversion) ; - - return 1 ; -} - -int env_clean_with_comment(stralloc *sa) -{ - log_flow() ; - - ssize_t pos = 0, r ; - char *end = 0, *start = 0 ; - stralloc final = STRALLOC_ZERO ; - stralloc tmp = STRALLOC_ZERO ; - - if (!sastr_split_string_in_nline(sa)) - log_warnu_return(LOG_EXIT_ZERO,"split environment value") ; - - for (; pos < sa->len ; pos += strlen(sa->s + pos) + 1) - { - tmp.len = 0 ; - if (!sastr_clean_string(&tmp,sa->s + pos)) - log_warnu_return(LOG_EXIT_ZERO,"clean environment string") ; - /** keep a empty line between key=value pair and a comment */ - r = get_len_until(tmp.s,'=') ; - end = r < 0 ? "\n" : "\n\n" ; - start = r < 0 ? "" : "\n" ; - - if (tmp.s[0] == '#') - { - if (!sastr_rebuild_in_oneline(&tmp)) - log_warnu_return(LOG_EXIT_ZERO,"rebuild environment string in one line") ; - } - else - { - if (!environ_rebuild_line(&tmp)) - log_warnu_return(LOG_EXIT_ZERO,"rebuild environment line") ; - } - if (!stralloc_0(&tmp) || - !auto_stra(&final,start,tmp.s,end)) - log_warn_return(LOG_EXIT_ZERO,"stralloc") ; - } - sa->len = 0 ; - if (!auto_stra(sa,final.s)) - log_warnu_return(LOG_EXIT_ZERO,"store environment value") ; - - stralloc_free(&tmp) ; - stralloc_free(&final) ; - - return 1 ; -} - -int env_prepare_for_write(stralloc *name, stralloc *dst, stralloc *contents, sv_alltype *sv,uint8_t conf) -{ - log_flow() ; - - char *svconf = keep.s + sv->srconf ; - size_t svconf_len = strlen(svconf) ; - char sym[svconf_len + SS_SYM_VERSION_LEN + 1] ; - - auto_strings(sym,svconf,SS_SYM_VERSION) ; - - if (!env_compute(contents,sv,conf)) - log_warnu_return(LOG_EXIT_ZERO,"compute environment") ; - - if (sareadlink(dst, sym) == -1) - log_warnusys_return(LOG_EXIT_ZERO,"read link of: ",sym) ; - - if (!stralloc_0(dst)) - log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; - - if (!auto_stra(name,".",keep.s + sv->cname.name)) - log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; - - return 1 ; -} - -int env_find_current_version(stralloc *sa,char const *svconf) -{ - log_flow() ; - - size_t svconflen = strlen(svconf) ; - struct stat st ; - char tmp[svconflen + SS_SYM_VERSION_LEN + 1] ; - - auto_strings(tmp,svconf,SS_SYM_VERSION) ; - - /** symlink may no exist yet e.g first activation of the service */ - if (lstat(tmp,&st) == -1) - return 0 ; - - if (sareadlink(sa,tmp) == -1) - return -1 ; - - if (!stralloc_0(sa)) - log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; - - return 1 ; -} - -int env_check_version(stralloc *sa, char const *version) -{ - log_flow() ; - - int r ; - - r = version_scan(sa,version,SS_CONFIG_VERSION_NDOT) ; - - if (r == -1) - log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; - - if (!r) - log_warn_return(LOG_EXIT_ZERO,"invalid version format: ",version) ; - - return 1 ; -} - -int env_append_version(stralloc *saversion, char const *svconf, char const *version) -{ - log_flow() ; - - int r ; - - stralloc sa = STRALLOC_ZERO ; - - if (!env_check_version(&sa,version)) - return 0 ; - - saversion->len = 0 ; - - if (!auto_stra(saversion,svconf,"/",sa.s)) - log_warnusys_return(LOG_EXIT_ZERO,"stralloc") ; - - r = scan_mode(saversion->s,S_IFDIR) ; - if (r == -1 || !r) - log_warnusys_return(LOG_EXIT_ZERO,"find the versioned directory: ",saversion->s) ; - - stralloc_free(&sa) ; - - return 1 ; -} - -int env_import_version_file(char const *svname, char const *svconf, char const *sversion, char const *dversion, int svtype) -{ - log_flow() ; - - int r ; - struct stat st ; - size_t pos = 0, svname_len= strlen(svname) ; - stralloc salist = STRALLOC_ZERO ; - stralloc src_ver = STRALLOC_ZERO ; - stralloc dst_ver = STRALLOC_ZERO ; - - char svname_dot[svname_len + 1 + 1] ; - - auto_strings(svname_dot,".",svname) ; - - r = version_cmp(sversion,dversion,SS_CONFIG_VERSION_NDOT) ; - - if (!r) { - - log_warn_return(LOG_EXIT_ONE,"same configuration file version for: ",svname," -- nothing to import") ; - goto freed ; - } - - if (r == -2) - log_warn_return(LOG_EXIT_ZERO,"compare ",svname," version: ",sversion," vs: ",dversion) ; - - if (r == 1) { - - log_warn_return(LOG_EXIT_ONE,"configuration file version regression for ",svname," -- ignoring configuration file version importation") ; - goto freed ; - } - - if (!env_append_version(&src_ver,svconf,sversion) || - !env_append_version(&dst_ver,svconf,dversion)) - return 0 ; - - char const *exclude[2] = { svname_dot, 0 } ; - if (!sastr_dir_get(&salist,src_ver.s,exclude,S_IFREG)) - log_warnusys_return(LOG_EXIT_ZERO,"get configuration file from directory: ",src_ver.s) ; - - FOREACH_SASTR(&salist,pos) { - - char *name = salist.s + pos ; - size_t namelen = strlen(name) ; - - char s[src_ver.len + 1 + namelen + 1] ; - auto_strings(s,src_ver.s,"/",name) ; - - char d[dst_ver.len + 1 + namelen + 1] ; - auto_strings(d,dst_ver.s,"/",name) ; - - if (lstat(s, &st) < 0) - log_warnusys_return(LOG_EXIT_ZERO,"stat: ",s) ; - - log_info("imports ",svname," configuration file from: ",s," to: ",d) ; - - if (!filecopy_unsafe(s, d, st.st_mode)) - log_warnusys_return(LOG_EXIT_ZERO,"copy: ", s," to: ",d) ; - } - - /** A module type can have multiple sub-modules. Copy these directories - * to keep trace of previous configuration file for a sub-module. - * If we don't copy these directories, when the sub-module is parsed - * the previous configuration doesn't exist and so this function do not - * import anything */ - - if (svtype == TYPE_MODULE) { - - salist.len = 0 ; - pos = 0 ; - - char const *exclude[1] = { 0 } ; - if (!sastr_dir_get(&salist,src_ver.s,exclude,S_IFDIR)) - log_warnusys_return(LOG_EXIT_ZERO,"get configuration directories from directory: ",src_ver.s) ; - - FOREACH_SASTR(&salist,pos) { - - char *name = salist.s + pos ; - size_t namelen = strlen(name) ; - - char s[src_ver.len + 1 + namelen + 1] ; - auto_strings(s,src_ver.s,"/",name) ; - - char d[dst_ver.len + 1 + namelen + 1] ; - auto_strings(d,dst_ver.s,"/",name) ; - - log_info("imports ",svname," configuration file from: ",s," to: ",d) ; - - if (!hiercopy(s,d)) - log_warnusys_return(LOG_EXIT_ZERO,"copy: ",s," to: ",d) ; - } - - } - - freed: - stralloc_free(&src_ver) ; - stralloc_free(&dst_ver) ; - stralloc_free(&salist) ; - - return 1 ; -}