#!/usr/bin/env bash
#
#   Script name: ubconfig
#   Description: Script for configure UBLinux (ublinux.ini)
#   GitLab: https://gitlab.ublinux.ru/
#   Author: Dmitry Razumov asmeron@ublinux.ru
#   Contributors: asmeron@ublinux.ru
#
#   Copyright (c) 2021-2022 UBLinux Development Team <support@ublinux.ru>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.

VERSION_SCRIPT=1.61

# Exit Immediately if a command fails
#set -o errexit

# Extended pattern matching: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching
#shopt -s extglob

#################################
###   :::   C O L O R S   :::   #
#################################
set_color(){
#http://abload.de/img/bash-color-chartmxjbp.png
    export BBC=$'\e[1;34m'
    export RBC=$'\e[1;31m'
    export WBC=$'\e[1m'
    export EC=$'\e[0m'

    export txtblk='\033[0;30m' # Black - Regular
    export txtred='\033[0;31m' # Red			# prompt: error color
    export txtgrn='\033[0;32m' # Green			# prompt: success color
    export txtylw='\033[0;33m' # Yellow			# prompt: waring color
    export txtblu='\033[0;34m' # Blue			
    export txtpur='\033[0;35m' # Purple
    export txtcyn='\033[0;36m' # Cyan			# prompt: info color
    export txtwht='\033[0;37m' # White
    export bldblk='\033[1;30m' # Black - Bold
    export bldred='\033[1;31m' # Red			# prompt: bold error color
    export bldgrn='\033[1;32m' # Green			# prompt: bold success color
    export bldylw="\033[1;33m" # Yellow                 # prompt: bold warning color
    export bldblu='\033[1;34m' # Blue				
    export bldpur='\033[1;35m' # Purple
    export bldcyn="\033[1;36m" # Cyan                   # prompt: bold info color
    export bldwht="\033[1;37m" # White			# prompt: bold default color

    export undblk='\033[4;30m' # Black - Underline
    export undred='\033[4;31m' # Red

    export bakblk='\033[40m'   # Black - Background
    export bakred='\033[41m'   # Red
    export badgrn='\033[42m'   # Green

    export txtrst='\033[0m'    # Text Reset		# prompt: default color
}


#######################################
###   :::   F U N C T I O N S   :::   #
#######################################

check_root(){
    [[ ${DEBUG} == yes ]] && return 0
    if [[ ${EUID:-$(id -u)} > 0 ]]; then
	case ${1} in
	    -w  | --warning)	  shift; prompt -w "Please run as root! ${@}" && return 1 ;;
	    -wq | --warning-quit) shift; prompt -wq "Please run as root!" ;;
    	    *) 			  prompt -wq "Please run as root!" ;;
        esac
    fi
}

# Check command availability
has_command(){ command -v $1 &> /dev/null; }

# echo like ... with flag type and display message colors
prompt(){
    [[ -n ${QUIET} ]] && return
    case ${1} in
	-s  | --success)	shift; echo -e "${bldgrn}${@}${txtrst}" ;;    			# print success message
	-sq | --success-quit)	shift; echo -e "${bldgrn}${@}${txtrst}"; exit 1 ;;    		# print success message
	-e  | --error)   	shift; echo -e "${bldred}ERROR:${@}${txtrst}" ;;   		# print error message
	-eq | --error-quit)   	shift; echo -e "${bldred}ERROR:${@}${txtrst}"; exit 1 ;;	# print error message
	-w  | --warning) 	shift; echo -e "${bldylw}WARNING:${bldwht}${@}${txtrst}" ;; 	# print warning message
	-wq | --warning-quit) 	shift; echo -e "${bldylw}WARNING:${bldwht}${@}${txtrst}"; exit 1 ;; # print warning message
	-i  | --info)    	shift; echo -e "${bldcyn}INFO:${txtcyn}${@}${txtrst}" ;;    	# print info message
	-iq | --info-quit)    	shift; echo -e "${bldcyn}INFO:${txtcyn}${@}${txtrst}"; exit 1 ;; # print info message
	*)    			echo -e "$@" ;;							# print all message
    esac
}

usage_version(){
    printf "%s  %s\n" "${0##*/}" "version: ${VERSION_SCRIPT}"
}
usage(){
    cat <<EOF
Script for configure UBLinux
Author: Dmitry Razumov asmeron@ublinux.ru

Usage:  ${0##*/} [OPTIONS...] {COMMAND} {SECTION} PARAM1=value PARAM2=value PARAMn=value

Commands:
  get		Get configuration option
  set 		Set configuration option
  remove 	Remove option of a configuration

Meta Commands:
  help          Show this help

Options for get:
  -r, --raw	   Show only values, without name variables
  -s, --source=<SOURCE>
   		   Configuration as source
    *glo | global  Configuration file as source: ublinux.ini
     sys | system  Configuration file as source: /etc/ublinux/*
     def | default Configuration file as source: /usr/lib/ublinux/os-config
     <file>        Configuration file as source, global ublinux.ini format: <FILE.ini>
  -d, --default    Before loading the source, additionally include the default 
		   settings file /usr/lib/ublinux/os-config
  -c, --compare    Compare configuration, system and global configuration files

Options for set:
  -t, --target
    *		   Without the specified option, are used *global *system
    *glo | global  Only configuration file as target: ublinux.ini
    *sys | system  Only configuration file as target: /etc/ublinux/*
     <file>        Configuration file as target, global ublinux.ini format: <FILE.ini>
  -n, --noexecute  Do not execute system configuration commands for option
  You can use the following operators to set parameter values:
     +=		   Add a value to the list of parameters
     -=		   Remove the last specified value from the parameter list
     --=	   Remove all occurrences of the specified value from the parameter list

Options for remove:
  -t, --target
    *		   Without the specified option, are used *global *system
    *glo | global  Only configuration file as target: ublinux.ini
    *sys | system  Only configuration file as target: /etc/ublinux/*
     <file>        Configuration file as target, global ublinux.ini format: <FILE.ini>
  -n, --noexecute  Do not execute system configuration commands for option

Options:
  -h, --help	   Show this help
  -h, --help=<SECTION>
	    	   Show help by section
  -q, --quiet	   Quiet mode
  -V, --version	   Show package version

Known sections:
  config 	/etc/ublinux/config
  boot 		/etc/ublinux/boot
  save 		/etc/ublinux/save
  network 	/etc/ublinux/network
  security 	/etc/ublinux/security
  kiosk		/etc/ublinux/kiosk
  desktop	/etc/ublinux/desktop
  video		/etc/ublinux/video
  theme		/etc/ublinux/theme
  steam		/etc/ublinux/steam
  clock		/etc/ublinux/clock
  locale	/etc/ublinux/locale
  keyboard	/etc/ublinux/keyboard
  ubm		/etc/ublinux/ubm
  nfs-server	/etc/ublinux/nfs-server
  nfs-common	/etc/ublinux/nfs-common
  proxy		/etc/ublinux/proxy

Examples:
${0##*/} get config HOSTNAME
${0##*/} get clock ZONE HWCLOCK_SYNC
${0##*/} get boot GRUB_PASSWORD[*]
${0##*/} get / DOMAIN
${0##*/} --raw get / DOMAIN
${0##*/} get /
${0##*/} --source default get [] ZONE
${0##*/} --source global get /
${0##*/} --source system get /
${0##*/} --compare get config
${0##*/} --default --source system get config DEFAULTPASSWD
${0##*/} set config HOSTNAME=myhost
${0##*/} set boot GRUB_CMDLINE_LINUX+=" nomodeset"
${0##*/} set boot GRUB_CMDLINE_LINUX-="nomodeset"
${0##*/} set network DOMAIN=domain.ru NETWORK[all]="+ipv4.dns 192.168.1.1"
${0##*/} --target system set clock ZONE="Asia/Omsk" HWCLOCK_SYNC=localtime
${0##*/} remove network DOMAIN
${0##*/} remove network DOMAIN[] NETWORK[]
${0##*/} remove network DOMAIN[*]
EOF
}
usage_config(){
    cat <<EOF
Configure UBLinux
Usage:  ${0##*/} {COMMAND} {SECTION} [OPTIONS...] ...

Options section: config
  HOSTNAME=<HOSTNAME>   Host name | Имя машины
EOF
}
usage_network(){
    cat <<EOF
Configure UBLinux
Usage:  ${0##*/} {COMMAND} {SECTION} [OPTIONS...] ...

Options section: network
  DOMAIN=<DOMAIN>	Domain configuration | Подключение к AD серверу

EOF
}
usage_kiosk(){
    cat <<EOF
Configure UBLinux
Usage:  ${0##*/} {COMMAND} {SECTION} [OPTIONS...] ...

Options section: kiosk
    cat <<EOF
EOF
}
help(){
    usage_version
    [[ -n $1 ]] || usage
    [[ $1 == "config" ]] && usage_config
    [[ $1 == "network" ]] && usage_network
    [[ $1 == "kiosk" ]] && usage_kiosk
    exit 0
}
arguments(){
# Pre-process options to:
# - expand -xyz into -x -y -z
# - expand --longopt=arg into --longopt arg
    local ARGV=()
    local END_OF_OPT=
    while [[ $# -gt 0 ]]; do
	arg="$1"; shift
	case "${END_OF_OPT}${arg}" in
	    --) ARGV+=("$arg"); END_OF_OPT=1 ;;
	    --*=*)ARGV+=("${arg%%=*}" "${arg#*=}") ;;
	    --*) ARGV+=("$arg") ;;
	    -*) for i in $(seq 2 ${#arg}); do ARGV+=("-${arg:i-1:1}"); done ;;
	    *) ARGV+=("$arg") ;;
	esac
    done
    # Apply pre-processed options
    set -- "${ARGV[@]}"
    # Parse options
    local END_OF_OPT=
    local POSITIONAL_ARGS=()
    [[ -z $@ ]] && usage && exit 0
    while [[ $# -gt 0 ]]; do
	case "${END_OF_OPT}${1}" in
	    get | GET)		   COMMAND="${1,,}"; END_OF_OPT=1 ;;
	    set | SET)		   COMMAND="${1,,}"; END_OF_OPT=1 ;;
	    remove | REMOVE)	   COMMAND="${1,,}"; END_OF_OPT=1 ;;
	    -r | --raw)    	   RAW=1 ;;	    
	    -c | --compare)    	   COMPARE=1 ;;
	    -s | --source) 	   shift; SOURCE="$1" ;;
	    -d | --default)	   LOAD_DEFAULT=1 ;;
	    -t | --target) 	   shift; TARGET="$1" ;;
	    -n | --noexecute) 	   SET_NOEXECUTE=1 ;;
	    -h | --help | help)	   shift; help $1;;
	    -q | --quiet)     	   QUIET=1; QUIET_SYSTEMCTL="--quiet"; QUIET_ARG="-q" ;;
	    -V | --version)	   usage_version; exit 0 ;;
	    --stdin)        	   READ_STDIN=1 ;;
	    --)             	   END_OF_OPT=1 ;;
	    -*|--*)         	   prompt -w "Unrecognized argument, skiped: $1" >&2  ;;
	    *)              	   POSITIONAL_ARGS+=("$1") ;;
	esac
	shift
    done
    # Restore positional parameters
    set -- "${POSITIONAL_ARGS[@]}"
    REQUEST_ARGS=("${POSITIONAL_ARGS[@]}")
    [[ -n ${SOURCE} ]] && case "${SOURCE}" in
	glob | global)	SOURCE="global" ;;
	sys  | system)	SOURCE="system" ;;
	def  | default)	SOURCE="default" ;;
	*) 		[[ -f ${SOURCE} ]] || prompt -eq " Unrecognized sources !" ;;
    esac
    [[ -n ${TARGET} ]] && case "${TARGET}" in
	glob | global)	TARGET="global" ;;
	sys  | system)	TARGET="system" ;;
	*) 		[[ -f ${TARGET} ]] || prompt -eq " Unrecognized target !" ;;
    esac
    if [[ ${COMMAND} == 'get' ]]; then 
	[[ -z ${SOURCE} ]] && SOURCE="global"
	[[ ${SOURCE} == "global" || -n ${COMPARE} ]] && check_root -wq
    elif [[ ${COMMAND} == 'set' || ${COMMAND} == 'remove' ]]; then
	[[ -n ${TARGET} && -f ${TARGET} && -w ${TARGET} ]] || check_root -wq
    fi 
}

prepare_section(){
    SECTION=$(grep -E '^([A-z0-9.,<>/@#$;%^:&?*=+|_-])+$' <<< ${1%% *}) #'
    ((SKIP_ARGS_SECTION++))
    [[ ${SECTION} == "" ]] && SECTION="unknown"
    ## Если секция вида: [test-1]755
    if [[ ! ${SECTION} =~ / ]]; then
	PRE_SECTION=${SECTION%%]*}
	## Если секция сложная вида: [test-1]a+x
	[[ ${SECTION} =~ ^\[.*\] ]] && POST_SECTION=${SECTION##*]}
	#SECTION="[${PATH_UBLINUX_CURRENT}/${PRE_SECTION/[/}]${POST_SECTION}"
	SECTION="[/etc/ublinux/${PRE_SECTION/[/}]${POST_SECTION}"
    ## Если секция вида: /etc/ublinux/test-1
    elif [[ ${SECTION} =~ ^/ ]]; then
	SECTION="[${SECTION}]"
    fi
    if [[ "$1" =~ " " ]]; then
	SECTION+=" ${1#* }"
    else
	## Если секция сложная, без ковычек, вида: [/etc/ublinux/test-1]a+x [chroot .]
	if [[ $3 == ".]" ]]; then
	    SECTION+=" $2 $3"
	    ((SKIP_ARGS_SECTION+=2))
	## Если секция сложная, без ковычек, вида: [/etc/ublinux/test-1]a+x [/usr/bin/bash]
	elif [[ $2 =~ ^\[([a-zA-Z./]+*)\]$ ]]; then
	    SECTION+=" $2"
	    ((SKIP_ARGS_SECTION++))
	fi
    fi
}

get_value(){
    # $1 Имя переменной из внешней функции, для заполнения данными
    # $2 Перечень опций для поиска
    # ${FILE_UBLINUX_DATA} как источник данных для анализа
    get_value_config(){
	declare -n VALUE_CONFIG=$1
	shift
	# Из полученных переменных сформировать вывод в зависимости от опции --raw
	get_value_format(){
	    while read -r LINE; do
	        [[ -n ${RAW} ]] && VALUE_CONFIG+="$(sed 's/^"//;s/"$//' <<< ${LINE#*=})\n" || VALUE_CONFIG+="${LINE}\n"
	    done <<< "${1}"
	}
	local FIND_VALUE_CONFIG=${FILE_UBLINUX_DATA}
	# Если секция не указана, то выводим весь файл
	if [[ ${SECTION} == "" || ${SECTION} == "/" || ${SECTION} == "[/]" || ${SECTION} == "[/etc/ublinux/]" || ${SECTION} == "[/etc/ublinux/*]" ]] && [[ $@ == "" ]]; then
	    FIND_VALUE_CONFIG=$(grep -Ev '^declare|^\[' <<< ${FIND_VALUE_CONFIG})
	    get_value_format "${FIND_VALUE_CONFIG}"
	# Секция указан, ищем запрошенные переменные и выводим
	else
	    # Вырезать искомую секцию из файла конфигурации
	    if [[ ${!VALUE_CONFIG} == "VALUE_GLOBAL" ]]; then
		if [[ ${SECTION} != "" && ${SECTION} != "/" && ${SECTION} != "[/]" && ${SECTION} != "[/etc/ublinux/]" && ${SECTION} != "[/etc/ublinux/*]" ]]; then
		    # Экранировать все символы в имени секции
		    ESC_SECTION=$(sed 's/[^a-zA-Z0-9,._@%-]/\\&/g' <<< "${SECTION}")
		    FIND_VALUE_CONFIG=$(sed -En "/${ESC_SECTION}/,/^\[/p" <<< "${FIND_VALUE_CONFIG}" | grep -v '^\[')
		fi
	    elif [[ ${!VALUE_CONFIG} == "VALUE_MANUAL" ]]; then
		if [[ ${SECTION} != "" && ${SECTION} != "/" && ${SECTION} != "[/]" && ${SECTION} != "[/etc/ublinux/]" && ${SECTION} != "[/etc/ublinux/*]" ]]; then
		    # Экранировать все символы в имени секции
		    ESC_SECTION=$(sed 's/[^a-zA-Z0-9,._@%-]/\\&/g' <<< "${SECTION}")
		    FIND_VALUE_CONFIG=$(sed -En "/${ESC_SECTION}/,/^\[/p" <<< "${FIND_VALUE_CONFIG}" | grep -v '^\[')
		else
		    # Скрыть имена блоков в выводе
		    FIND_VALUE_CONFIG=$(grep -v '^\[' <<< "${FIND_VALUE_CONFIG}")
		fi
	    fi
	    # Если указан только секция и нет переменных для фильтра
	    if [[ -n ${SECTION} ]] && [[ $@ == "" || $@ == "/" || $@ == "*" ]]; then
		get_value_format "${FIND_VALUE_CONFIG}"
	    # Указана секция и присутствуют переменные для фильтра
	    else
		for REQUEST_ITEM in "$@"; do
		    if [[ ${REQUEST_ITEM%%=*} =~ "[]"$|"[*]"$ ]]; then
	    		REQUEST_ITEM=$(sed 's/[^a-zA-Z0-9 ]/\\&/g' <<< "${REQUEST_ITEM%%[*}[")
    	    		FIND_VALUE=$(grep -E "^${REQUEST_ITEM}" <<< ${FIND_VALUE_CONFIG})
		    else
	    		REQUEST_ITEM=$(sed 's/[^a-zA-Z0-9 ]/\\&/g' <<< "${REQUEST_ITEM%%=*}=")
    	    		FIND_VALUE=$(grep -E "^${REQUEST_ITEM}" <<< "${FIND_VALUE_CONFIG}" | tail -1)
    	    	    fi
    	    	    [[ ${FIND_VALUE} != "" ]] || FIND_VALUE="(null)"
		    get_value_format "${FIND_VALUE}"
		done
	    fi
	fi
    }
    get_value_compare(){
	while read -r REQUEST_ITEM; do
	    grep -Eq "^$|(null)" <<< ${REQUEST_ITEM} && continue
	    REQUEST_ITEM_ESC=$(sed 's/[^a-zA-Z0-9 ]/\\&/g' <<< ${REQUEST_ITEM})
	    FIND_VALUE=$(grep -E "^${REQUEST_ITEM_ESC}" <<< ${2//\\n/$'\n'})
	    [[ ${FIND_VALUE} == "" ]] && FIND_VALUE="${REQUEST_ITEM}" || continue
	    if [[ -n ${RAW} ]]; then 
		while read -r LINE; do
		    VALUE_COMPARE+="${3}${LINE#*=}\n"
		done <<< ${FIND_VALUE}
	    else
		while read -r LINE; do
		    VALUE_COMPARE+="${3}${LINE}\n"
		done <<< ${FIND_VALUE}
	    fi
	done <<< ${FILE_UBLINUX_DATA//\\n/$'\n'}
    }
    local VALUE_COMPARE=
    local VALUE_GLOBAL=
    local VALUE_SYSTEM=
    local VALUE_DEFAULT=
    local VALUE_MANUAL=
    shift ${SKIP_ARGS_SECTION}
    if [[ -n ${COMPARE} ]]; then
	[[ -f ${FILE_UBLINUX_CONF} ]] || return 1
	FILE_UBLINUX_DATA=$(grep -Ev '^\s*#|^\s*$' ${FILE_UBLINUX_CONF})
        get_value_config "VALUE_GLOBAL" "$@"
    	if [[ ${SECTION} == "[/]" ]]; then
    	    FILE_UBLINUX_DATA="$(cat ${PATH_UBLINUX_CURRENT}/* | grep -Ev '^\s*#|^\s*$')"
    	    get_value_config "VALUE_SYSTEM" "$@"
	elif [[ -f ${PATH_UBLINUX_CURRENT}/$(tr -d '[]' <<< ${SECTION##*/}) ]]; then
    	    FILE_UBLINUX_DATA=$(cat ${PATH_UBLINUX_CURRENT}/$(tr -d '[]' <<< ${SECTION##*/}) | grep -Ev '^\s*#|^\s*$')
    	    get_value_config "VALUE_SYSTEM" "$@"
    	fi
        get_value_compare "${VALUE_GLOBAL}" "${VALUE_SYSTEM}" "Global:"
        get_value_compare "${VALUE_SYSTEM}" "${VALUE_GLOBAL}" "System:"
	echo -en "${VALUE_COMPARE}"
    elif [[ ${SOURCE} == global ]]; then 
	[[ -f ${FILE_UBLINUX_CONF} ]] || return 1
	FILE_UBLINUX_DATA=$(grep -Ev '^\s*#|^\s*$' ${FILE_UBLINUX_CONF})
	if [[ ${SECTION} != "" && ${SECTION} != "[/]" && -n ${LOAD_DEFAULT} ]]; then
	    ESC_SECTION=$(sed 's/[^a-zA-Z0-9,._+@%-]/\\&/g' <<< "${SECTION}")
	    FILE_UBLINUX_DATA=$(sed "/${ESC_SECTION}/r"<(echo "$(grep -Ev '^\s*#|^\s*$' ${FILE_UBLINUX_DEFAULT})") <<< ${FILE_UBLINUX_DATA}) #"
	fi
        get_value_config "VALUE_GLOBAL" "$@"
        echo -en "${VALUE_GLOBAL}"
    elif [[ ${SOURCE} == system ]]; then
	if [[ -f ${PATH_UBLINUX_CURRENT}/$(tr -d '[]' <<< ${SECTION##*/}) ]]; then
	    [[ -n ${LOAD_DEFAULT} ]] && FILE_DEFAULT_DATA="$(grep -Ev '^\s*#|^\s*$' ${FILE_UBLINUX_DEFAULT})\n"
	    FILE_UBLINUX_DATA=${FILE_DEFAULT_DATA/%\\n/$'\n'}$(cat ${PATH_UBLINUX_CURRENT}/$(tr -d '[]' <<< ${SECTION##*/}) | grep -Ev '^\s*#|^\s*$')
	    get_value_config "VALUE_SYSTEM" "$@"
	elif [[ ${SECTION} == "" || ${SECTION} == "[/]" || ${SECTION} == "[/etc/ublinux/]" || ${SECTION} == "[/etc/ublinux/*]" ]]; then
	    FILE_UBLINUX_DATA=$(cat ${PATH_UBLINUX_CURRENT}/* | grep -Ev '^\s*#|^\s*$')
	    get_value_config "VALUE_SYSTEM" "$@"
	fi
        echo -en "${VALUE_SYSTEM}"
    elif [[ ${SOURCE} == default ]]; then
	[[ -f ${FILE_UBLINUX_DEFAULT} ]] || return 1
	FILE_UBLINUX_DATA=$(grep -Ev '^\s*#|^\s*$' ${FILE_UBLINUX_DEFAULT})
	get_value_config "VALUE_DEFAULT" "$@"
	echo -en "${VALUE_DEFAULT}"
    else
	[[ -f ${SOURCE} ]] || return 1
	FILE_UBLINUX_DATA=$(grep -Ev '^\s*#|^\s*$' ${SOURCE})
	get_value_config "VALUE_MANUAL" "$@"
	echo -en "${VALUE_MANUAL}"
    fi
}
remove_value(){
    remove_value_all(){
	remove_value_global(){
		# Поиск секции по полному имени с каталогом [/etc/ublinux/name]
		if ESC_SECTION=$(sed 's/[^a-zA-Z0-9,._@%-]/\\&/g' <<< "${SECTION}") && grep -Eq "^${ESC_SECTION}" "${FILE_UBLINUX_CONF}"; then
		    true
		# Поиск секции по сокращённому имени без каталога [name]
		elif ESC_SECTION="\[$(tr -d '[]' <<< ${SECTION##*/})\]" && grep -Eq "^${ESC_SECTION}" "${FILE_UBLINUX_CONF}"; then
		    true
		else 
		    return 1
		fi
	        # Вырезаем блок по меткам
		FIND_VALUE_CONFIG=$(grep -n "" "${FILE_UBLINUX_CONF}" | sed -E -n "/^[0-9]*:${ESC_SECTION}/,/^[0-9]*:\s*#*\s*\[/p")
		# Если сектор пустой и состоит только из заголовка сектор, то пропуск, иначе последнюю строку следующего сектора вырезаем
		[[ $(head -1 <<< ${FIND_VALUE_CONFIG}) != $(tail -1 <<< ${FIND_VALUE_CONFIG}) ]] || FIND_VALUE_CONFIG=$(sed -E '${/^[0-9]*:\s*#*\s*\[/d;}' <<< ${FIND_VALUE_CONFIG})
		# Нет выбранного блока для анализа
		if [[ ${FIND_VALUE_CONFIG} == "" ]]; then
		    return 1
		# Если после имени указано [] или [*] то удалить все переменные ассациативного массива	
		elif [[ ${NAME_VAR_LOCAL##*\[} =~ ^"]"$|^"*]"$ ]] && SECTION_DATA="$(grep -E "^[0-9]*:${ESC_NAME_VAR_LOCAL%%[*}[" <<< ${FIND_VALUE_CONFIG} | cut -d: -f1)" && [[ ${SECTION_DATA} != "" ]]; then 
		    sed -E "${SECTION_DATA//$'\n'/d;}d" -i "${FILE_UBLINUX_CONF}"
		# Поиск прямое совпадение переменной, номер строки в переменную ^A=
		elif SECTION_DATA="$(grep -E "^[0-9]*:${ESC_NAME_VAR_LOCAL}=" <<< ${FIND_VALUE_CONFIG} | tail -1 | cut -d: -f1)" && [[ ${SECTION_DATA} != "" ]]; then 
		    # Прямое совпадение найдено, удаление по номеру строки
		    sed -E "${SECTION_DATA}d" -i "${FILE_UBLINUX_CONF}"
		else 
		    return 1
		fi
	}
	remove_value_system(){
	    #FILE_CONFIG="${PATH_UBLINUX_CURRENT}/$(tr -d '[]' <<< "${SECTION##*/}")"
	    # Получить только путь из ${SECTION}
	    PATH_CONFIG_SECTION=$(sed -r "s/\[([a-zA-Z0-9,._@%-/]*)\].*/\1/; s/.[^/]*$//" <<< "${SECTION}") #"
	    # Если базовый каталог указанный в секции входит в состав системного каталога ${PATH_UBLINUX_CURRENT}, то продолжить, иначе это другой файл настроек и выйти
	    #[[ ${PATH_CONFIG_SECTION} == ${PATH_UBLINUX_CURRENT} ]] && FILE_CONFIG=$(sed "s/\[\([a-zA-Z0-9,._@%-/]*\)\].*/\1/" <<< "${SECTION}") || return 2 #"
	    [[ ${PATH_UBLINUX_CURRENT} =~ "${PATH_CONFIG_SECTION}"$ ]] && FILE_CONFIG="${PATH_UBLINUX_CURRENT}/$(sed "s/\[\([a-zA-Z0-9,._@%-/]*\)\].*/\1/; s/^.*[/$]//" <<< "${SECTION}")" || return 2 #"
	    if [[ -f ${FILE_CONFIG} ]]; then
	        if [[ ${NAME_VAR_LOCAL##*\[} =~ ^"]"$|^"*]"$ ]]; then
	    	    grep -Eq "^${ESC_NAME_VAR_LOCAL%%[*}[" "${FILE_CONFIG}" || return 1
		    sed -E "/^${ESC_NAME_VAR_LOCAL%%[*}[/d" -i "${FILE_CONFIG}"
		    grep -Eq "^${ESC_NAME_VAR_LOCAL%%[*}[" "${FILE_CONFIG}" &&  return 1
		else
		    grep -Eq "^${ESC_NAME_VAR_LOCAL}=" "${FILE_CONFIG}" || return 1
		    sed -E "/^${ESC_NAME_VAR_LOCAL}=/d" -i "${FILE_CONFIG}"
		    grep -Eq "^${ESC_NAME_VAR_LOCAL}=" "${FILE_CONFIG}" &&  return 1
		fi
		sed "/^declare -A/d" -i "${FILE_CONFIG}"
		DECLARE_A=$(grep -E "^[A-z0-9_]*\[.*\]=.*" "${FILE_CONFIG}" | sed -E "s/\[.*//" | sort -u | tr "\n" " ")
		[[ -z ${DECLARE_A} ]] || sed "1i declare -A ${DECLARE_A}" -i "${FILE_CONFIG}"
	    else
	        return 3
	    fi
	}
	if [[ ${SECTION} == "" || ${SECTION} == "[/]" || ${SECTION} == "[/etc/ublinux/]" || ${SECTION} == "[/etc/ublinux/*]" ]]; then
	    SECTION="[/etc/ublinux/config]"
	fi
	local NAME_VAR_LOCAL=${NAME_VAR}
	ESC_NAME_VAR_LOCAL="$(sed 's/[^a-zA-Z0-9,._@%-]/\\&/g' <<< "${NAME_VAR_LOCAL}")"
	if [[ -z ${TARGET} ]]; then
	    remove_value_global; STATUS_GLOBAL=$?
	    remove_value_system; STATUS_SYSTEM=$?
	elif [[ ${TARGET} == global ]]; then
	    remove_value_global; STATUS_GLOBAL=$?
	elif [[ ${TARGET} == system ]]; then
	    remove_value_system; STATUS_SYSTEM=$?
	elif [[ -f ${TARGET} ]]; then
	    FILE_UBLINUX_CONF=${TARGET}
	    remove_value_global; STATUS_GLOBAL=$?
	fi
	[[ ${STATUS_GLOBAL} == 0 ]] && prompt -s "${NAME_VAR_LOCAL} variable remove from global configuration ${FILE_UBLINUX_CONF}"
	[[ ${STATUS_GLOBAL} == 1 ]] && { prompt -w " ${NAME_VAR_LOCAL} variable not remove from global configuration ${FILE_UBLINUX_CONF}"; local STATUS=1; }
	[[ ${STATUS_SYSTEM} == 0 ]] && prompt -s "${NAME_VAR_LOCAL} variable remove from system configuration ${FILE_CONFIG}"
	[[ ${STATUS_SYSTEM} == 1 ]] && { prompt -w " ${NAME_VAR_LOCAL} variable not remove from system configuration ${FILE_CONFIG}"; local STATUS=1; }
	[[ ${STATUS} == 1 ]] && return 1 || return 0
    }
    local STATUS_SYSTEM STATUS_GLOBAL
    shift ${SKIP_ARGS_SECTION}
    [[ -n "$@" ]] || prompt -eq " not found arguments !"
    for ARG in "$@"; do
	NAME_VAR=${ARG%%=*}; VALUE_VAR=$(ubconfig --raw ${COMMAND_SRC} get ${SECTION} ${NAME_VAR})
	remove_value_all; local STATUS=$?
	[[ ${STATUS_SYSTEM} == 0 && -z ${SET_NOEXECUTE} ]] && select_exec || true
    done
}
set_value(){
    set_value_all(){
	set_value_global(){
		# Поиск секции по полному имени с каталогом [/etc/ublinux/name] или по сокращённому имени без каталога [name]
		if ESC_SECTION=$(sed 's/[^a-zA-Z0-9,._@%-]/\\&/g' <<< "${SECTION}") && grep -Eq "^\s*#*\s*${ESC_SECTION}" "${FILE_UBLINUX_CONF}" || \
		    { ESC_SECTION="\[$(tr -d '[]' <<< ${SECTION##*/})\]" && grep -Eq "^\s*#*\s*${ESC_SECTION}" "${FILE_UBLINUX_CONF}"; }; then
		    # Если секция закомментирована, то открываем
		    sed -E "s/^\s*#*\s*${ESC_SECTION}/${ESC_SECTION}/" -i "${FILE_UBLINUX_CONF}"
		    # Вырезаем блок по меткам; Удаляем пустые строки и строки с одним символом #
		    FIND_VALUE_CONFIG=$(grep -n "" "${FILE_UBLINUX_CONF}" | sed -E -n "/^[0-9]*:\s*#*\s*${ESC_SECTION}/,/^[0-9]*:\s*#*\s*\[/{/^[0-9]*:\s*#*\s*$/d;p;}")
		    # Если сектор пустой и состоит только из заголовка сектор, то пропуск, иначе последнюю строку следующего сектора вырезаем
		    [[ $(wc -l <<< ${FIND_VALUE_CONFIG}) -eq 1 ]] || FIND_VALUE_CONFIG=$(sed -E '${/^[0-9]*:\s*#*\s*\[/d;}' <<< ${FIND_VALUE_CONFIG})
		fi
		local SECTION_DATA=
		# Секция не найдена. Нет выбранного блока для анализа, вставляем новую секцию в конец файла
		if [[ -z ${FIND_VALUE_CONFIG} ]]; then
		    echo -e "\n${SECTION}\n${NAME_VAR_LOCAL}=${VALUE_VAR_LOCAL}" >> "${FILE_UBLINUX_CONF}"
		    #echo -e "${NAME_VAR_LOCAL}=${VALUE_VAR_LOCAL}" >> "${FILE_UBLINUX_CONF}"
		# Поиск прямое совпадение переменной, номер строки в переменную ^A=
		elif SECTION_DATA="$(grep -E "^[0-9]*:${ESC_NAME_VAR_LOCAL}=" <<< ${FIND_VALUE_CONFIG} | tail -1 | cut -d: -f1)" && [[ -n ${SECTION_DATA} ]]; then 
		    # Прямое совпадение найдено, замена по номеру строки
		    sed -E "${SECTION_DATA}s/.*/${ESC_NAME_VAR_LOCAL}=${ESC_VALUE_VAR_LOCAL}/" -i "${FILE_UBLINUX_CONF}"
		# Поиск по косвенному совпадению, после # коментария имя переменной ^ *#* *A=
		elif SECTION_DATA="$(grep -E "^[0-9]*:\s*#*\s*${ESC_NAME_VAR_LOCAL}=" <<< ${FIND_VALUE_CONFIG} | tail -1 | cut -d: -f1)" && [[ -n ${SECTION_DATA} ]]; then
		    # Косвенное сопадение найдено, вставка после номера строки
		    sed -E "${SECTION_DATA}a ${ESC_NAME_VAR_LOCAL}=${ESC_VALUE_VAR_LOCAL}" -i "${FILE_UBLINUX_CONF}"
		# Поиск по косвенному совпадению, после # коментария имя переменной обрезанное до '['  ^ *#* *A[.*]=
		elif SECTION_DATA="$(grep -E  "^[0-9]*:\s*#*\s*${ESC_NAME_VAR_LOCAL%%\\[*}" <<< ${FIND_VALUE_CONFIG} | tail -1 | cut -d: -f1)" && [[ -n ${SECTION_DATA} ]]; then 
		    # Косвенное сопадение найдено, вставка после номера строки
		    sed -E "${SECTION_DATA}a ${ESC_NAME_VAR_LOCAL}=${ESC_VALUE_VAR_LOCAL}" -i "${FILE_UBLINUX_CONF}"
		# Совпадений не найдено, поиск последней строки блока
		else 
		    SECTION_DATA="$(tail -1 <<< $(grep -Ev '^[0-9]*:#*$' <<< ${FIND_VALUE_CONFIG}) | cut -d: -f1)"
		    # Совпадений не найдено, вставляем в конец блока новой строкой
		    [[ -n ${SECTION_DATA} ]] && sed -E "${SECTION_DATA}a ${ESC_NAME_VAR_LOCAL}=${ESC_VALUE_VAR_LOCAL}" -i "${FILE_UBLINUX_CONF}"
		fi
		grep -q "^${ESC_NAME_VAR_LOCAL}=${ESC_VALUE_VAR_LOCAL}$" "${FILE_UBLINUX_CONF}" || return 1
	}
	set_value_system(){
	    #FILE_CONFIG="${PATH_UBLINUX_CURRENT}/$(tr -d '[]' <<< "${SECTION##*/}")"
	    # Получить только путь из ${SECTION}
	    PATH_CONFIG_SECTION=$(sed -r "s/\[([a-zA-Z0-9,._@%-/]*)\].*/\1/; s/.[^/]*$//" <<< "${SECTION}") #"
	    # Если базовый каталог указанный в секции входит в состав системного каталога ${PATH_UBLINUX_CURRENT}, то продолжить, иначе это другой файл настроек и выйти
	    #[[ ${PATH_CONFIG_SECTION} == ${PATH_UBLINUX_CURRENT} ]] && FILE_CONFIG=$(sed "s/\[\([a-zA-Z0-9,._@%-/]*\)\].*/\1/" <<< "${SECTION}") || return 2 #"
	    [[ ${PATH_UBLINUX_CURRENT} =~ "${PATH_CONFIG_SECTION}"$ ]] && FILE_CONFIG="${PATH_UBLINUX_CURRENT}/$(sed "s/\[\([a-zA-Z0-9,._@%-/]*\)\].*/\1/; s/^.*[/$]//" <<< "${SECTION}")" || return 2 #"
	    [[ -f ${FILE_CONFIG} ]] && sed -E "/^${ESC_NAME_VAR_LOCAL}=/d" -i "${FILE_CONFIG}" || touch "${FILE_CONFIG}"
	    echo "${NAME_VAR_LOCAL}=${VALUE_VAR_LOCAL}" >> "${FILE_CONFIG}"
	    grep -q "^${ESC_NAME_VAR_LOCAL}=${ESC_VALUE_VAR_LOCAL}$" "${FILE_CONFIG}" || return 1
	    # Mark associative array
	    sed "/^declare -A/d" -i "${FILE_CONFIG}"
	    DECLARE_A=$(grep -E "^[A-z0-9_]*\[.*\]=.*" "${FILE_CONFIG}" | sed -E "s/\[.*//" | sort -u | tr "\n" " ")
	    [[ -z ${DECLARE_A} ]] || sed "1i declare -A ${DECLARE_A}" -i "${FILE_CONFIG}"
	}
	if [[ ${SECTION} == "" || ${SECTION} == "[/]" || ${SECTION} == "[/etc/ublinux/]" || ${SECTION} == "[/etc/ublinux/*]" ]]; then
	    SECTION="[/etc/ublinux/config]"
	fi
	local MODE_VAR_LOCAL=${MODE_VAR}
	local NAME_VAR_LOCAL=${NAME_VAR}
	local VALUE_VAR_LOCAL=${VALUE_VAR}
	if [[ ${MODE_VAR_LOCAL} == "+=" ]]; then
	    [[ -n ${TARGET} ]] && COMMAND_SRC="--source ${TARGET}"
	    EXIST_VALUE=$(ubconfig --raw ${COMMAND_SRC} get ${SECTION} ${NAME_VAR_LOCAL})
	    [[ ${EXIST_VALUE} != "(null)" ]] && VALUE_VAR_LOCAL="${EXIST_VALUE}${VALUE_VAR_LOCAL}"
	elif [[ ${MODE_VAR_LOCAL} == "-=" || ${MODE_VAR_LOCAL} == "--=" ]]; then
	    [[ -n ${TARGET} ]] && COMMAND_SRC="--source ${TARGET}"
	    EXIST_VALUE=$(ubconfig --raw ${COMMAND_SRC} get ${SECTION} ${NAME_VAR_LOCAL})
	    if [[ ${EXIST_VALUE} != "(null)" ]]; then
		# Удалить только последнее вхождения строки
		[[ ${MODE_VAR_LOCAL} == "-=" ]] && VALUE_VAR_LOCAL="$(sed "s/${VALUE_VAR_LOCAL}//" <<< ${EXIST_VALUE})"
		# Удалить все вхождения строки
		[[ ${MODE_VAR_LOCAL} == "--=" ]] && VALUE_VAR_LOCAL="$(sed "s/${VALUE_VAR_LOCAL}//g" <<< ${EXIST_VALUE})"
		[[ ${EXIST_VALUE} == ${VALUE_VAR_LOCAL} ]] && prompt -wq "Part of the specified value '${VALUE_VAR}' was not found in the variable '${NAME_VAR_LOCAL}' in ${TARGET} configuration"
	    else
		prompt -wq "The empty '${NAME_VAR_LOCAL}' variable in ${TARGET} configuration"
	    fi
	fi
	[[ ${VALUE_VAR_LOCAL} =~ " " ]] && VALUE_VAR_LOCAL="\"${VALUE_VAR_LOCAL}\""
	ESC_NAME_VAR_LOCAL="$(sed 's/[^a-zA-Z0-9,._@%-]/\\&/g' <<< "${NAME_VAR_LOCAL}")"
	ESC_VALUE_VAR_LOCAL="$(sed 's/[^a-zA-Z0-9,._@%-]/\\&/g' <<< "${VALUE_VAR_LOCAL}")"
	if [[ -z ${TARGET} ]]; then
	    set_value_global; STATUS_GLOBAL=$?
	    set_value_system; STATUS_SYSTEM=$?
	elif [[ ${TARGET} == global ]]; then
	    set_value_global; STATUS_GLOBAL=$?
	elif [[ ${TARGET} == system ]]; then
	    set_value_system; STATUS_SYSTEM=$?
	elif [[ -f ${TARGET} ]]; then
	    FILE_UBLINUX_CONF="${TARGET}"
	    set_value_global; STATUS_GLOBAL=$?
	fi
	[[ ${STATUS_GLOBAL} == 0 ]] && prompt -s "${NAME_VAR_LOCAL} variable added to global configuration ${FILE_UBLINUX_CONF}"
	[[ ${STATUS_GLOBAL} == 1 ]] && { prompt -e " ${NAME_VAR_LOCAL} variable not added to global configuration ${FILE_UBLINUX_CONF}"; local STATUS=1; }
	[[ ${STATUS_SYSTEM} == 0 ]] && prompt -s "${NAME_VAR_LOCAL} variable added to system configuration ${FILE_CONFIG}"
	[[ ${STATUS_SYSTEM} == 1 ]] && { prompt -e " ${NAME_VAR_LOCAL} variable not added to system configuration ${FILE_CONFIG}"; local STATUS=1; }
	[[ ${STATUS} == 1 ]] && return 1 || return 0
    }
    local STATUS_SYSTEM STATUS_GLOBAL
    shift ${SKIP_ARGS_SECTION}
    [[ -n "$@" ]] || prompt -eq " not found arguments !"
    for ARG in "$@"; do
	if grep -qE "^(a-z|A-Z|0-9|.|_|-|\/|\[|\])+\+=.*$" <<< ${ARG}; then
	## Режим +=
	    MODE_VAR="+="; NAME_VAR=${ARG%%+=*}; VALUE_VAR=${ARG#*+=}
	elif grep -qE "^(a-z|A-Z|0-9|.|_|-|\/|\[|\])+\-\-=.*$" <<< ${ARG}; then
	## Режим --=
	    MODE_VAR="--="; NAME_VAR=${ARG%%--=*}; VALUE_VAR=${ARG#*--=}
	elif grep -qE "^(a-z|A-Z|0-9|.|_|-|\/|\[|\])+\-=.*$" <<< ${ARG}; then
	## Режим -=
	    MODE_VAR="-="; NAME_VAR=${ARG%%-=*}; VALUE_VAR=${ARG#*-=}
	else
	## Режим =
	    MODE_VAR="="; NAME_VAR=${ARG%%=*}; VALUE_VAR=${ARG#*=}
	fi
	set_value_all; local STATUS=$?
	[[ ${STATUS_SYSTEM} == 0 && -z ${SET_NOEXECUTE} ]] && select_exec || true
    done
}
select_exec(){
    case "${SECTION}" in
	"[/etc/ublinux/boot]"|"[boot]")
    	    case "${NAME_VAR}" in
		'GRUB_TIMEOUT')		exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_timeout ;;
		'GRUB_DEFAULT')		exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_default ;;
		'GRUB_SUPERUSERS')	exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_superusers ;;
		GRUB_PASSWORD\[*\])	exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_password ;;
		'GRUB_BOOT_SILENT')	exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_boot_silent ;;
		'GRUB_TERMINAL_INPUT')	exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_terminal_input ;;
		'GRUB_TERMINAL_OUTPUT')	exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_terminal_output ;;
		'GRUB_PLAY')		exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_play ;;
		'GRUB_CMDLINE_LINUX')	exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.halt.pre/20-grub exec_grub_cmdline_linux ;;
		*)			local NO_FIND_EXCUTE=1 ;;
	    esac
	;;
	"[/etc/ublinux/clock]"|"[clock]")
    	    case "${NAME_VAR}" in
		'ZONE')		exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/10-system exec_timezone ;;
		'HWCLOCK_SYNC') exec_clock_hwclock_sync ;;
		*)		local NO_FIND_EXCUTE=1 ;;
	    esac
	;;
	"[/etc/ublinux/config]"|"[config]")
	    case "${NAME_VAR}" in
	        'HOSTNAME')	${ROOTFS}/usr/lib/ublinux/rc.preinit.d/30-network-hostname ${COMMAND} ${NAME_VAR}=${VALUE_VAR} ;;
	        'SERVICESSTART') exec_config_servicesstart ;;
	        *)		local NO_FIND_EXCUTE=1 ;;
	    esac
	;;
	"[/etc/ublinux/server]"|"[server]")
	    case "${NAME_VAR}" in
	        'STORAGE_CONTAINERS_PATH') ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/80-server-containers-storage ${COMMAND} ;;
	        'STORAGE_LIBVIRT_PATH')	   ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/81-server-libvirt-storage ${COMMAND} ;;
	        *)			   local NO_FIND_EXCUTE=1 ;;
	    esac
	;;
	"[/etc/ublinux/desktop]"|"[desktop]")
	    case "${NAME_VAR}" in
	        'MULTISEAT_SIMPLE')	${ROOTFS}/usr/lib/ublinux/rc.preinit.d/55-multiseat ;;
	        'AUTOEXEC')		${ROOTFS}/usr/lib/ublinux/rc.desktop/all/autoexec ${COMMAND} ${NAME_VAR}=${VALUE_VAR} ;;
	        AUTOEXEC\[*\])		${ROOTFS}/usr/lib/ublinux/rc.desktop/all/autoexec ${COMMAND} ${NAME_VAR}=${VALUE_VAR} ;;
	        *)			local NO_FIND_EXCUTE=1 ;;
	    esac
	;;
	"[/etc/ublinux/network]"|"[network]")
    	    case "${NAME_VAR}" in
		'DOMAIN')		exec_network_domain ;;
		'DOMAIN[server]') 	true ;;
		'NTPSERVERS')		${ROOTFS}/usr/lib/ublinux/rc.preinit.d/21-ntp ${COMMAND} ;;
		PROXY_SYSTEM\[*\])	${ROOTFS}/usr/lib/ublinux/rc.preinit.d/31-network-proxy-system ;;
		*)			local NO_FIND_EXCUTE=1 ;;
	    esac
	;;
	"[/etc/ublinux/security]"|"[security]")
    	    case "${NAME_VAR}" in
		'OPENSSL_ENGINE')		 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/56-openssl-engine ;;
		'ACCESS_DENIED_VTX11')		 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/57-access-denied-vtx11 ;;
		'ACCESS_ALLOWED_LOGIN')		 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/58-access-login exec_access_allowed_login ;;
		'ACCESS_DENIED_LOGIN')		 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/58-access-login exec_access_denied_login ;;
		ACCESS_ALLOWED_SUID\[*\])	 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.post.d/42-access-suid-sgid exec_access_allowed_suid ;;
		ACCESS_ALLOWED_SGID\[*\])	 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.post.d/42-access-suid-sgid exec_access_allowed_sgid ;;
		ACCESS_ALLOWED_INTERPRETER\[*\]) exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.post.d/43-access-interpreter ;;
		MOUNT_ATTR\[*\])		 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.post.d/44-mountattr ;;
		MOUNT_QUOTA\[*\])		 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.post.d/45-disk-quota ;;
		CGROUP_QUOTA\[*\])		 ${ROOTFS}/usr/lib/ublinux/rc.post.d/46-cgroup-quota ${COMMAND} ${NAME_VAR}=${VALUE_VAR} ;;
		POLKIT\[*\])			 exec_simple_set_remove ${ROOTFS}/usr/lib/ublinux/rc.preinit.d/59-polkit ;;
		*)				 local NO_FIND_EXCUTE=1 ;;
	    esac
	;;
	\[*\])
	    case "${NAME_VAR}" in
	        *)		local NO_FIND_EXCUTE=1 ;;
	    esac
	;;
	*) prompt -i " ${SECTION} section not found for execution"; local NO_FIND_EXCUTE=1 ;;
    esac
    [[ ${NO_FIND_EXCUTE} == 1 ]] || prompt -s "Execute system configuration commands for option ${NAME_VAR}"
}

###############################
###   :::   E X E C   :::   ###
###############################
exec_simple_set_remove(){
    if [[ ${COMMAND} == 'set' || ${COMMAND} == 'remove' ]]; then
	$@
    fi
}
exec_config_servicesstart(){
    ctl_service(){
	if readlink -fq ${ROOTFS}/usr/bin/init | grep -q "lib/systemd/systemd$"; then
	    while read SERVICE; do
		if [[ -n ${SERVICE} && $1 == "enable" ]]; then
		    ${ROOTFS}/usr/bin/systemctl ${QUIET_SYSTEMCTL} unmask ${SERVICE}
		    ${ROOTFS}/usr/bin/systemctl ${QUIET_SYSTEMCTL} enable --now ${SERVICE}
		elif [[ -n ${SERVICE} && $1 == "disable" ]]; then
		    ${ROOTFS}/usr/bin/systemctl ${QUIET_SYSTEMCTL} disable --now ${SERVICE}
		fi
	    done < <(tr ",;[[:space:]]" \\n <<< ${VALUE_VAR})
	fi 
    }
    if [[ ${COMMAND} == 'set' ]]; then
	if [[ ${MODE_VAR} == @('+='|'=') ]]; then
	    ctl_service "enable"
	elif [[ ${MODE_VAR} == @('--='|'-=') ]]; then
	    ctl_service "disable"
	fi 
    elif [[ ${COMMAND} == 'remove' ]]; then
	ctl_service "disable"
    fi
}
exec_network_domain(){
    export PARENT="${PKGNAME}"
    if [[ ${COMMAND} == 'set' ]]; then
	${ROOTFS}/usr/bin/ubdomain-client -q configure
    elif [[ ${COMMAND} == 'remove' ]]; then
	${ROOTFS}/usr/bin/ubdomain-client -q unconfigure
    fi
}
exec_clock_hwclock_sync(){
    if [[ ${COMMAND} == 'set' || ${COMMAND} == 'remove' ]]; then
	${ROOTFS}/usr/lib/ublinux/rc.halt/20-timesave
	${ROOTFS}/usr/lib/ublinux/rc.post.d/02-hwclock
    fi
}


###############################
###   :::   M A I N   :::   ###
###############################

    PKGNAME=${0##*/}
    PATH_WORK=${PWD}
    set_color
    unset ROOTFS; [[ -d /usr/lib/ublinux ]] || ROOTFS=.
    eval $(grep -i "^SYSCONF=" ${ROOTFS}/usr/lib/ublinux/os-config)

    PATH_UBLINUX_CURRENT="${ROOTFS}${SYSCONF}"
    FILE_UBLINUX_CONF=$(ls ${ROOTFS}/memory/layer-base/*/ublinux.ini 2>/dev/null | tail -1)
    FILE_UBLINUX_DEFAULT="${ROOTFS}/usr/lib/ublinux/os-config"

## DEBUG PATH:
#DEBUG=yes
#PATH_UBLINUX_CURRENT="./etc/ublinux"; [[ -d ${PATH_UBLINUX_CURRENT} ]] && PATH_UBLINUX_CURRENT=$(realpath "${PATH_UBLINUX_CURRENT}") || exit 1
#FILE_UBLINUX_CONF="ublinux.ini"; [[ -f ${FILE_UBLINUX_CONF} ]] && FILE_UBLINUX_CONF=$(realpath "${FILE_UBLINUX_CONF}") || exit 1
#FILE_UBLINUX_DEFAULT="os-config"; [[ -f ${FILE_UBLINUX_CONF} ]] && FILE_UBLINUX_DEFAULT=$(realpath "${FILE_UBLINUX_DEFAULT}") ||  exit 1

    REQUEST_ARGS=()
    arguments "$@"
    set -- "${REQUEST_ARGS[@]}"

    SKIP_ARGS_SECTION=0
    [[ -z $1 ]] || prepare_section "$@"
    if [[ ${COMMAND} == 'get' ]]; then
        get_value "$@"
    elif [[ ${COMMAND} == 'set' ]]; then
	[[ -z $1 ]] && help || set_value "$@"
    elif [[ ${COMMAND} == 'remove' ]]; then
	[[ -z $1 ]] && help || remove_value "$@"
    fi






#_init_(){
#    export BIN_MKMOD="mkubm"
#    export mnctlPath="/etc/NetworkManager"
#    export tmpUblinuxChng="/tmp/ublinux/connections"
#
#    export excludeFiles=$(mktemp -p /dev/shm)
#    export arg_modules_path=$(realpath /memory/layer-base/*/modules | tail -n1)
#    export path_tmp="$tmpUblinuxChng/$(date '+%Y.%m.%d')-connections"
#}
#_init_
#mkdir -p $path_tmp || exit 1
#[[ -n $arg_modules_path ]] && rsync -aAXruR --exclude-from="$excludeFiles" "$mnctlPath" "$path_tmp" && cd $arg_modules_path || exit 1
#eval ${BIN_MKMOD} -l $(find $tmpUblinuxChng -maxdepth 1 -mindepth 1 -iname '*connections') -o "$(date '+%Y.%m.%d')-connections.ubm" || exit 1
#rm -rf $path_tmp || exit 1
