#!/usr/bin/env bash

ENABLED=yes
[[ ${ENABLED} == "yes" ]] || exit 0
DEBUGMODE=no

SOURCE=/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null  || exit 0
SOURCE=/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null  || exit 0
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/update; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null

debug_mode "$0" "$@"

## Настройка подключения репозиториев
## REPOSITORY=disable|enable|only
##  *disable            # Отключить управление списком репозиториев, по умолчанию
##                      # Используются репозитории из пакета pacman, по умолчанию: core,extra,community,multilib,modules
##   enable             # Включить управление списком репозиториев
##                      # Используются системные репозитории core,extra,community,multilib,modules и указанные в параметре REPOSITORY[*]
##			# Если не указаны дополнитеьные репозитории в параметре REPOSITORY[*] и включен любой режим песочницы, то активен только репозиторий 'modules'
##   only               # Включить управление списком репозиториев
##                      # Используются только репозитории указанные в параметре REPOSITORY[*]
## Порядок указания репозиториев важен
## По умолчанию включены системные репозитории, имена: core,extra,community,multilib,modules 
## REPOSITORY[<name_repo>]=<server_path_1>,<server_path_2>,...,<server_path_n>;<siglevel>;<usage>;disable
##   <name_repo>        # Произвольное имя репозитория. Обязательный
##                      # Имена системных репозиториев: core,extra,community,multilib,modules
##   <server_path_n>    # Полный URL-адрес места, где можно найти базу данных, пакеты и подписи (если доступны) для этого репозитория. Обязательный
##                      # Возможно указать несколько, через запятую (,)
##                      # Символ $ обязательно экранировать \$
##     <file>           # Если указан доступный файл, то подключить как дополнительный файл расширения конфигурации (Include = <file>)
##     file://          # URL префикс для репозитория в каталоге
##     ftp://           # URL префикс для репозитория FTP
##     http://          # URL префикс для репозитория HTTP
##     https://         # URL префикс для репозитория HTTPS
##   <siglevel>           # Уровень проверки подписи репозитория, можно выбрать одну из основных и вторую из дополнительных, разделитель запятая. Не обязательный
##                        # Последовательность имеет значение, т.к. накладываются правила каскадно. По умолчанию: Required,DatabaseOptional
##     Never              # Проверка подписи выполняться не будет. Основная
##       PackageNever     # Только для пакетов. Дополнительная
##       DatabaseNever    # Только для базы данных. Дополнительная
##     Optional           # Подписи будут проверяться при их наличии, но неподписанные базы данных и пакеты также будут приниматься. Основная
##       PackageOptional  # Только для пакетов. Дополнительная
##      *DatabaseOptional # Только для базы данных. Дополнительная
##    *Required           # Подписи будут необходимы для всех пакетов и баз данных. Основная
##       PackageRequired  # Только для пакетов. Дополнительная
##       DatabaseRequired # Только для базы данных. Дополнительная
##     TrustedOnly        # Если подпись проверяется для пакетов и базы, она должна находиться в связке ключей и быть полностью доверенной; маргинальное доверие не применимо
##       PackageTrustedOnly  # Если подпись проверяется только для пакетов
##       DatabaseTrustedOnly # Если подпись проверяется только для базы данных
##     TrustAll           # Если подпись проверена, она должна находиться в связке ключей, но ей не требуется назначать уровень доверия (например, неизвестное или предельное доверие)
##       PackageTrustAll  # Если подпись проверена только для пакетов
##       DatabaseTrustAll # Если подпись проверена только для базы данных
##   <usage>            # Уровень использования этого репозитория. Не обязательный
##    *All              # Включать все перечисленные функции для репозитория, по умолчанию
##     Sync             # Включать обновления для этого репозитория
##     Search           # Включать поиск этого репозитория
##     Install          # Включать установку пакетов из этого репозитория во время операции --sync
##     Upgrade          # Позволить этому репозиторию быть действительным источником пакетов при выполнении --sysupgrade
##   disable            # Временно отключить управление репозиторием, либо после = указать - пример: REPOSITORY[modules]=-/etc/pacman.d/mirrorlist
## Если требуется создать файл зеркала в пакетном режиме, то пример: ubconfig set [/etc/pacman.d/ub-mirrorlist] "|SERVER=http://repo.ublinux.ru/2405/\$repo/\$arch" "|SERVER=https://repo.ublinux.ru/2405/\$repo/\$arch"
## 
## REPOSITORY[core]=/etc/pacman.d/mirrorlist;;;disable
## REPOSITORY[modules]="https://repo.ublinux.ru/2405/\$repo/\$arch"
## REPOSITORY[modules]='https://repo.ublinux.ru/2405/$repo/$arch'
## REPOSITORY[mymodules]=http://192.168.0.1:8080/repo/2204;;;disable
## REPOSITORY[webmyrepo]=http://myweb.org/myrepo;Never
## REPOSITORY[localmyrepo]=file:///home/myrepo;Never;All
## REPOSITORY[myrepo]=/home/myrepo/mirrorlist
exec_01_repository(){
    repository_enable(){
	local FILE_SOURCE_DEFAULT="/usr/lib/ublinux/default"
	local FILE_SOURCE_UPDATE="${SYSCONF}/update"
	local FILE_PACMAN_CONF="${ROOTFS}/etc/pacman.conf"
	local PACMAN_CONF_DATA=
	local ARG_UBCONFIG=
    	# Удалим все действующие репозитории
	awk -i inplace -v b=2 '/^\[.*\]$/{f=1; c++} !(f && c>=b); /^\s*$/{f=0}' ${FILE_PACMAN_CONF}
	# Удалить в конце файла все пустые строки
	sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' -i ${FILE_PACMAN_CONF}
	local REPOSITORY_LIST= REPOSITORY_LIST_DEFAULT= REPOSITORY_LIST_SOURCE=
	REPOSITORY_LIST_SOURCE=$(grep -oE "^[[:blank:]]*REPOSITORY\[.*\]" ${FILE_SOURCE_UPDATE} 2>/dev/null)
	if [[ ${REPOSITORY[0]} == "enable" ]]; then
	    # Если включено управление репозиториями 'enable' + не заданы пользовательские репозитории + режим песочницы, то включить только модули
	    if [[ ${SYSTEMBOOT_STATEMODE,,} == @("sandbox"|"sandbox_ram_home"|"sandbox_hdd"|"sandbox_hdd_home") && ${REPOSITORY_LIST_SOURCE} == "" ]]; then
		REPOSITORY_LIST_DEFAULT=$(grep -oE "^[[:blank:]]*REPOSITORY\[modules\]" ${FILE_SOURCE_DEFAULT} 2>/dev/null)$'\n'
	    else
		REPOSITORY_LIST_DEFAULT=$(grep -oE "^[[:blank:]]*REPOSITORY\[.*\]" ${FILE_SOURCE_DEFAULT} 2>/dev/null)$'\n'
	    fi
	    ARG_UBCONFIG="--default"
	fi	
	REPOSITORY_LIST="${REPOSITORY_LIST_DEFAULT}${REPOSITORY_LIST_SOURCE}"
	local REPOSITORY_NAME= REPOSITORY_VAR=
	while IFS='' read -u3 REPOSITORY_NAME; do
    	    [[ ${REPOSITORY_NAME} =~ ^.*'['(.*)']' ]] && REPOSITORY_NAME=${BASH_REMATCH[1]} || continue
    	    REPOSITORY_VAR=$(ubconfig --quiet --raw ${ARG_UBCONFIG} --source system get [update] REPOSITORY[${REPOSITORY_NAME}] 2>/dev/null)
            [[ -n ${REPOSITORY_VAR} ]] \
            &&  while IFS=';' read -r -u4 REPOSITORY_SERVER_PATHS REPOSITORY_SIGLEVEL REPOSITORY_USAGE REPOSITORY_DISABLE NULL; do
    		[[ ${REPOSITORY_SERVER_PATHS} =~ ^("disable"|"-") ]] && continue
        	[[ ${REPOSITORY_DISABLE} = @("disable"|"off"|"no") ]] && continue
        	PACMAN_CONF_DATA+=$'\n'
        	PACMAN_CONF_DATA+="[${REPOSITORY_NAME}]"$'\n'
        	[[ -n ${REPOSITORY_SIGLEVEL} ]] && PACMAN_CONF_DATA+="SigLevel = ${REPOSITORY_SIGLEVEL//,/ }"$'\n'
        	[[ -n ${REPOSITORY_USAGE} ]] && PACMAN_CONF_DATA+="Usage = ${REPOSITORY_USAGE}"$'\n'
        	[[ -n ${REPOSITORY_SERVER_PATHS} ]] \
        	&& while IFS= read -r -u5 REPOSITORY_SERVER_PATH; do
        	    if [[ ${REPOSITORY_SERVER_PATH} =~ ^"/" ]]; then
        		PACMAN_CONF_DATA+="Include = ${REPOSITORY_SERVER_PATH}"$'\n'
        	    elif [[ ${REPOSITORY_SERVER_PATH} =~ ^("file:"|"ftp:"|"http:"|"https:") ]]; then
        		PACMAN_CONF_DATA+="Server = ${REPOSITORY_SERVER_PATH}"$'\n'
        	    fi
        	done 5<<< "${REPOSITORY_SERVER_PATHS//,/$'\n'}"
        	#echo "${REPOSITORY_NAME} == ${REPOSITORY_SERVER_PATHS} :: ${REPOSITORY_SIGLEVEL} :: ${REPOSITORY_USAGE} :: ${REPOSITORY_DISABLE} :: ${NULL}"
            done 4<<< "${REPOSITORY_VAR}"
        # awk - Из списка удалить вторые дубликаты, не меняя порядок
    	done 3< <(awk -v RS="[\n]+" '!n[$0]++' <<< "${REPOSITORY_LIST}")
        echo "${PACMAN_CONF_DATA}" >> ${FILE_PACMAN_CONF}
    }
    repository_disable(){
    # Отключить управление репозиториями, восстановить из пакета pacman.conf
	find /memory/bundles -maxdepth 3 -path "*/etc/*" -type f -name "pacman.conf" -exec cp -af {} "/etc/" \; -quit
    }
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local PARAM="$@"
    if [[ -n ${PARAM} ]]; then
        REPOSITORY_NAME=${PARAM%%=*}
        REPOSITORY_VAR=${PARAM#*=}
    fi
    
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#REPOSITORY[@]} != 0 ]]; then
	if [[ ${REPOSITORY[0]} == @("enable"|"only") ]]; then
	    repository_enable
        elif [[ ${REPOSITORY[0]} == "disable" ]]; then
	    repository_disable
	    ubconfig --quiet --nocolor --noexecute remove [update] REPOSITORY
        fi
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
        if [[ ${REPOSITORY[0]} == @("enable"|"only") ]]; then
    	    repository_enable
        elif [[ ${REPOSITORY_NAME} == "REPOSITORY" ]]; then
    	# Удаление параметра REPOSITORY= . Отключить управление репозиториями
    	    repository_disable
        fi
    fi
}

## pacredir (https://github.com/eworm-de/pacredir)
## Опубликовать локальный репозиторий в локальной сети и подключиться к сети распределённых репозиториев
## При установке, пакет ищется в распределённой сети репозиториев и устанавливается самой последней доступной версией
## REPOPUBLIC_NET=disable|no|none|enable|yes,db,<name_repos_1>,...,<name_repos_n>
##   disable|no|none 	# Отключить все репозитории от сети распределённых репозиториев
##   enable|yes		# Подключить репозитории к сети распределённых репозиториев. Если не указаны конкретные имена, то будут подключены все
##   db         	# Получать БД пакетов pacman от сети распределённых репозиториев
##   <name_repo>  	# Подключить только выбранные имена репозиториев, например: core,extra,community,multilib,modules
## REPOPUBLIC_NET=enable,db
## REPOPUBLIC_NET=enable,db,community,modules
exec_02_repopublic_net(){
    disable_pacredir(){
	systemctl --quiet disable pacserve.service pacredir.service
	systemctl --quiet stop pacserve.service pacredir.service
	sed -E "/Include = \/etc\/pacman.d\/pacredir/d" -i ${FILE_PACMAN_CONF}
	sed -E "s/^(Server = )/#\1/" -i ${FILE_PACREDIR_CONF}
    }
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local FILE_PACMAN_CONF="${ROOTFS}/etc/pacman.conf"
    local FILE_PACREDIR_CONF="${ROOTFS}/etc/pacman.d/pacredir"
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#REPOPUBLIC_NET[@]} != 0 ]]; then
	local DB_CACHE=
	local REPOPUBLIC_NET_ENABLE=
	local REPOPUBLIC_NET_ENABLE_MANUAL=
	local DATA_PACMAN_CONF=$(cat ${FILE_PACMAN_CONF})
	#sed -E "/Include = \/etc\/pacman.d\/pacredir/d" <<< ${DATA_PACMAN_CONF}
	local DATA_PACMAN_CONF=${DATA_PACMAN_CONF//$'\n'Include = \/etc\/pacman.d\/pacredir/}
    	while IFS= read -u3 REPOPUBLIC_NET_REPOSITORY; do
	    if [[ ${REPOPUBLIC_NET_REPOSITORY,,} == @("disable"|"no"|"none") ]]; then
	    # Отключить управление 
		REPOPUBLIC_NET_ENABLE=
		break
	    elif [[ ${REPOPUBLIC_NET_REPOSITORY,,} == @("enable"|"yes") ]]; then
    	    # Включить управление
		REPOPUBLIC_NET_ENABLE=yes
	    elif [[ ${REPOPUBLIC_NET_REPOSITORY,,} == "db" ]]; then
	    # Включить запрос БД pacman из кеш сервера
	        DB_CACHE=yes
    	    else
    		REPOPUBLIC_NET_ENABLE="manual"
    	    # Добавить к указанному репозиторию, работать через кеш сервер
    	        DATA_PACMAN_CONF=$(sed -E "/\[${REPOPUBLIC_NET_REPOSITORY}\]/a Include = \/etc\/pacman.d\/pacredir" <<< ${DATA_PACMAN_CONF})
    	    fi
    	done 3<<< "${REPOPUBLIC_NET//,/$'\n'}"
    	if [[ -z ${REPOPUBLIC_NET_ENABLE} ]]; then
	    disable_pacredir
	else
    	    # Если не укзаны репозитории, то добавить ко всем репозиториям в pacman.conf: Include = /etc/pacman.d/pacredir
    	    [[ ${REPOPUBLIC_NET_ENABLE} == "manual" ]] || DATA_PACMAN_CONF=$(sed -E "0,/^\[.*\]$/! s/(^\[.*\]$)/\1\nInclude = \/etc\/pacman.d\/pacredir/" <<< ${DATA_PACMAN_CONF}) #"
    	    [[ -n ${DB_CACHE} ]] && sed -E "s/^#(Server = )/\1/" -i ${FILE_PACREDIR_CONF} || sed -E "s/^(Server = )/#\1/" -i ${FILE_PACREDIR_CONF}
    	    echo "${DATA_PACMAN_CONF}" > ${FILE_PACMAN_CONF}
	    systemctl --quiet restart pacserve.service pacredir.service
	fi
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	disable_pacredir
    fi
}

## darkhttpd or miniserve
## Опубликовать хранилище или репозиторий в виде локального WEB ресурса
## Если необходимо опубликовать выборочные репозитории, то создать новый каталог хранилища в который переместить симлинки выбранных репозиториев. Опубликовать новый каталог хранилища.
## REPOPUBLIC_WEB[<path>[:<repo1,repo2,...>]]=enable|yes|disable|no|none:listing:<port>:<auth_name>:<auth_pass>:<auth_hash>
##   <path>		# Путь до каталога хранилища, который будет опубликован
##   <path>:repo1,repo2	# Путь до каталога хранилища и выбранные репозитории из хранилища которые будут опубликованы
##   enable|yes		# Включить публикацию
##   disable|no|none	# Выключить публикацию
##   listing		# Включить WEB обозреватель файлов. Не обязятельный
##   <port>		# Порт по которому доступен репозиторий. По умолчанию: 80. Не обязательный
##   <auth_name> 	# Параметры авторизации, имя пользователя. Не обязательный
##   <auth_pass> 	# Параметры авторизации, открытый пароль или тип хеша. Не обязательный
##     <password>  	# Не зашифрованный пароль
##     sha256	 	# Использовать зашифрованный пароль SHA256, применять только совместно с <auth_hash>
##     sha512	 	# Использовать зашифрованный пароль SHA512, применять только совместно с <auth_hash>
##   <auth_hash> 	# Параметры авторизации, не зашифрованный или зашифрованный пароль SHA256 или SHA512. Не обязательный
##			# Получить SHA шифр из пароля: echo -n "PASSWORD" | sha512sum | cut -f 1 -d ' '
## REPOPUBLIC_WEB[/home/storage]=enable:listing
## REPOPUBLIC_WEB[/home/storage:repo-1,repo-2]=enable:listing::ublinux:123
## REPOPUBLIC_WEB[/home/storage:repo-1,repo-2]=enable:listing::ublinux:sha512:123
## REPOPUBLIC_WEB[/home/storage:repo-1,repo-2]=enable:listing::ublinux:sha256:a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
exec_03_repopublic_web(){
    kill_web_service(){
	local REPOPUBLIC_WEB_PATH=$1
	if [[ -n ${REPOPUBLIC_WEB_PATH} ]]; then
	# Убить процесс с указанным каталогом
	    pkill -f "darkhttpd ${REPOPUBLIC_WEB_PATH}"
	    pkill -f "miniserve .* ${REPOPUBLIC_WEB_PATH}"
	else
	# Убить все процессы
	    pkill -f "darkhttpd .* ${PATH_LOG_REPOPUBLIC_WEB}"
	    pkill -f "miniserve .* --title UBLinux Repository:"
	fi
    }
    mount_bind_storage(){
	umount "${PATH_NEW_REPOPUBLIC_WEB_PATH}"/* 2>/dev/null
	install -dm755 "${PATH_NEW_REPOPUBLIC_WEB_PATH}/pool"
	mount --bind -o ro "${SRC_REPOPUBLIC_WEB_PATH_POOL}" "${PATH_NEW_REPOPUBLIC_WEB_PATH}/pool"
	while IFS= read -u4 SELECT_SRC_REPOPUBLIC_WEB_PATH_REPO; do
	    if [[ -d ${SRC_REPOPUBLIC_WEB_PATH_POOL%/*}/${SELECT_SRC_REPOPUBLIC_WEB_PATH_REPO} ]]; then
	        install -dm755 "${PATH_NEW_REPOPUBLIC_WEB_PATH}/${SELECT_SRC_REPOPUBLIC_WEB_PATH_REPO}"
	        mount --bind -o ro "${SRC_REPOPUBLIC_WEB_PATH_POOL%/*}/${SELECT_SRC_REPOPUBLIC_WEB_PATH_REPO}" "${PATH_NEW_REPOPUBLIC_WEB_PATH}/${SELECT_SRC_REPOPUBLIC_WEB_PATH_REPO}"
	    else
	        echo "WARNING: repository '${SRC_REPOPUBLIC_WEB_PATH_POOL%/*}/${SELECT_SRC_REPOPUBLIC_WEB_PATH_REPO}' not found!"
	    fi
	done 4<<< ${SRC_REPOPUBLIC_WEB_PATH_REPOLIST//,/$'\n'}
    }
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local PATH_NEW_REPOPUBLIC_WEB_PATH="${ROOTFS}/srv/http/repopublic_web"
    local PATH_LOG_REPOPUBLIC_WEB="${ROOTFS}/var/log/repopublic_web"
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#REPOPUBLIC_WEB[@]} != 0 ]]; then
	local ARGS_DRAKHTTPD=" --daemon --chroot --no-server-id --uid http --gid http --mimetypes /etc/conf.d/mimetypes --log ${PATH_LOG_REPOPUBLIC_WEB}/darkhttpd.log"
	local ARGS_MINISERV=" --color-scheme archlinux --color-scheme-dark archlinux --hide-theme-selector --hide-version-footer --dirs-first --title 'UBLinux Repository: '"
	[[ -d ${PATH_LOG_REPOPUBLIC_WEB} ]] || install -dm755 "${PATH_LOG_REPOPUBLIC_WEB}"
	while IFS= read -u3 REPOPUBLIC_WEB_PATHS; do
	    local CREATE_BIND_STORAGE=
	    if [[ ${REPOPUBLIC_WEB_PATHS} =~ ":" ]]; then
	    # Указано хранилище и репозитории для публикации
		SRC_REPOPUBLIC_WEB_PATH_POOL="${REPOPUBLIC_WEB_PATHS%:*}/pool"
		SRC_REPOPUBLIC_WEB_PATH_REPOLIST=${REPOPUBLIC_WEB_PATHS#*:}
		if [[ -d ${SRC_REPOPUBLIC_WEB_PATH_POOL} ]]; then
		    REPOPUBLIC_WEB_PATH=${PATH_NEW_REPOPUBLIC_WEB_PATH}
		    CREATE_BIND_STORAGE=yes
		else
		# Публикуемый каталог не содержит pool всех пакетов, публикуем каталог храниища
		    REPOPUBLIC_WEB_PATH=${REPOPUBLIC_WEB_PATHS}
		fi
	    else
	    # Указано только хранилище
		REPOPUBLIC_WEB_PATH=${REPOPUBLIC_WEB_PATHS}
	    fi
	    IFS=: read -r SELECT_STATUS SELECT_LISTING SELECT_PORT SELECT_AUTH_NAME SELECT_AUTH_PASS SELECT_AUTH_HASH NULL <<< "${REPOPUBLIC_WEB[${REPOPUBLIC_WEB_PATHS}]}"
	    if [[ ${SELECT_STATUS} == @("enable"|"yes") ]]; then
		[[ -n ${CREATE_BIND_STORAGE} ]] && mount_bind_storage
		[[ ${SELECT_LISTING} == "listing" ]] || { ARGS_DRAKHTTPD+=" --no-listing"; ARGS_MINISERV+=" --disable-indexing"; }
		[[ -n ${SELECT_PORT} ]] && ARGS_DRAKHTTPD+=" --port ${SELECT_PORT}" && ARGS_MINISERV+=" --port ${SELECT_PORT}" || { ARGS_DRAKHTTPD+=" --port 80"; ARGS_MINISERV+=" --port 80"; }
		if [[ -n ${SELECT_AUTH_NAME} && -n ${SELECT_AUTH_PASS} ]]; then
		    if [[ -z ${SELECT_AUTH_HASH} ]]; then
			ARGS_DRAKHTTPD+=" --auth ${SELECT_AUTH_NAME}:${SELECT_AUTH_PASS}"; ARGS_MINISERV+=" --auth ${SELECT_AUTH_NAME}:${SELECT_AUTH_PASS}"
		    else
			ARGS_DRAKHTTPD=
			[[ ${SELECT_AUTH_PASS,,} == "sha256" && ${#SELECT_AUTH_HASH} -ne 64 ]] && SELECT_AUTH_HASH=$(echo -n "${SELECT_AUTH_HASH}" | sha256sum | cut -f 1 -d ' ')
			[[ ${SELECT_AUTH_PASS,,} == "sha512" && ${#SELECT_AUTH_HASH} -ne 128 ]] && SELECT_AUTH_HASH=$(echo -n "${SELECT_AUTH_HASH}" | sha512sum | cut -f 1 -d ' ')
			ARGS_MINISERV+=" --auth ${SELECT_AUTH_NAME}:${SELECT_AUTH_PASS}:${SELECT_AUTH_HASH}"
		    fi
		fi
		if [[ -n ${ARGS_DRAKHTTPD} ]]; then
		# Без шифрованного пароля, используем darkhttpd
		    kill_web_service "${REPOPUBLIC_WEB_PATH}"
		    darkhttpd "${REPOPUBLIC_WEB_PATH}" ${ARGS_DRAKHTTPD}
		else
		# C шифрованным паролем, используем miniserve
		    kill_web_service "${REPOPUBLIC_WEB_PATH}"
		    eval setsid miniserve ${ARGS_MINISERV} -- "${REPOPUBLIC_WEB_PATH}" 1>"${PATH_LOG_REPOPUBLIC_WEB}"/miniserve.log 2>&1 &
		fi
	    elif [[ ${SELECT_STATUS} == @("disable"|"no"|"none") ]]; then
		kill_web_service "${REPOPUBLIC_WEB_PATH}"
		umount "${PATH_NEW_REPOPUBLIC_WEB_PATH}"/* 2>/dev/null
		rm -rdf "${PATH_NEW_REPOPUBLIC_WEB_PATH}"
	    fi
    	done 3< <(printf "%s\n" "${!REPOPUBLIC_WEB[@]}")
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	kill_web_service
	umount "${PATH_NEW_REPOPUBLIC_WEB_PATH}"/* 2>/dev/null
	rm -rdf "${PATH_NEW_REPOPUBLIC_WEB_PATH}"
    fi
}

## pacoloco (https://github.com/anatol/pacoloco)
## Опубликовать ленивое зеркало подключенных репозиториев в виде локального WEB ресурса. 
## Получая запрос от пользователя, загружает с удалённого репозитория пакет и сохраняет в кеше передавая его пользователю.
## REPOPUBLIC_CACHE=enable|yes|disable|no|none
##   enable|yes		# Включить ленивое зеркало
##   disable|no|none	# Выключить ленивое зеркало
##
## Если задано только "REPOPUBLIC_CACHE=enable" без указания рпозиториев пользователем, то создаётся зеркало по умолчанию, где "2204" версия текущего дистрибутива:
##   : REPOPUBLIC_CACHE[ublinux_2405]=url@http://repo.ublinux.ru/2405,url@https://repo.ublinux.ru/2405
## На клиенте необходимо указать: 
##   либо в файле "/etc/pacman.conf" у каждого репозитория: Server=http://ipadress:8080/repo/ublinux_2204/$repo/$arch 
##   либо в файле "/etc/pacman.d/mirrorlist" для всех репозиториев: Server=http://ipadress:8080/repo/ublinux_2204/$repo/$arch 
##   либо параметры в конфигурации REPOSITORY[core]='http://ipadress:8080/repo/ublinux_2204/$repo/$arch'
##
## REPOPUBLIC_CACHE[<var>]=<value>
##   <var>:			# Параметр управления, возможные варианты:
##     port			# Порт сервиса, по умолчанию: 80
##     cache_dir		# Каталог кэша, по умолчанию: /memory/layer-base/1/repopublic_cache
##     purge_files_after	# Продолжительность бездействия (в секундах), по истечении которой файл должен быть удален из кэша, по умолчанию: 360000
##				# =360000 секунд или 100 часов, =0 никогда не выполнять
##     download_timeout		# Таймаут (в секундах) для загрузки интернет-кэша, по умолчанию: 3600
##     http_proxy		# Работать через прокси. Пример: http://foo.company.com:8989
##     user_agent		# Пользовательский агент, используемый для извлечения файлов из репозиториев, по умолчанию: repopublic/1.0
##     prefetch.cron		# Cтандартное выражение cron, пример: 0 0 3 * * * *
##				# (https://en.wikipedia.org/wiki/Cron#CRON_expression) (https://github.com/gorhill/cronexpr#implementation )
##     prefetch.ttl_unaccessed_in_days	# Количество дней подряд, в течение которых не обновляются системы в сети, по умолчанию: 30
##					# Удалять и останавливать пакеты предварительной выборки (и ссылки на базы данных), если они не загружены после ttl_unaccessed_in_days дней, после обновления
##     prefetch.ttl_unupdated_in_days	# Количество дней подряд, в течение которых не было запрошено обновление, по умолчанию: 300
##					# Удалять и останавливать пакеты предварительной выборки, которые не были обновлены в исходной версии или запрошены в течение ttl_unupdated_in_days
## REPOPUBLIC_CACHE[<repository>]=<type>@<url>
##   <repository>		# Имя репозитория, для подключения клиентов
##   <type>:			# Тип подключаемого репозитория
##     url			# Вэб ссылка на репозиторий
##     http_proxy		# Прокси-сервер, может быть включен для каждого репозитория, затеняя глобальный 'http_proxy'
##     mirrorlist		# Файл зеркал. Будьте осторожны! Убедитесь, что URL текущего сервера НЕ включен в этот файл!
##  <url>			# Ресурс, можно указать несколько черз зпятую (,)
## REPOPUBLIC_CACHE[ublinux_2405]="url@http://repo.ublinux.ru/2405,url@https://repo.ublinux.ru/2405"
## REPOPUBLIC_CACHE[myrepo_x86_64]="url@http://my.repo.ru/myrepo/x86_64"
## REPOPUBLIC_CACHE[newrepo]="http_proxy@http://proxy.localnet.ru:8080,url@http://192.168.1.1/newrepo/x86_64"
## REPOPUBLIC_CACHE[ublinux-reflector]="mirrorlist@/etc/pacman.d/reflector_mirrorlist"
exec_04_repopublic_cache(){
    enable_pacoloco(){
	local FILE_PACOLOCO_CONF="${ROOTFS}/etc/pacoloco.yaml"
	local REPOPUBLIC_CACHE_REPO_MANUAL=
        [[ -d ${REPOPUBLIC_CACHE[cache_dir]} ]] || install -dm755 ${REPOPUBLIC_CACHE[cache_dir]}
        chown -R pacoloco:pacoloco ${REPOPUBLIC_CACHE[cache_dir]}
        true > ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[port]} ]] && yq '.port = '${REPOPUBLIC_CACHE[port]}'' --inplace ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[cache_dir]} ]] && yq '.cache_dir = "'${REPOPUBLIC_CACHE[cache_dir]}'"' --inplace ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[purge_files_after]} ]] && yq '.purge_files_after = '${REPOPUBLIC_CACHE[purge_files_after]}'' --inplace ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[download_timeout]} ]] && yq '.download_timeout = '${REPOPUBLIC_CACHE[download_timeout]}'' --inplace ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[user_agent]} ]] && yq '.user_agent = "'${REPOPUBLIC_CACHE[user_agent]}'"' --inplace ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[http_proxy]} ]] && yq '.http_proxy = "'${REPOPUBLIC_CACHE[http_proxy]}'"' --inplace ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[prefetch.cron]} ]] && yq '.prefetch.cron = "'${REPOPUBLIC_CACHE[prefetch.cron]}'"' --inplace ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[prefetch.ttl_unaccessed_in_days]} ]] && yq '.prefetch.ttl_unaccessed_in_days = '${REPOPUBLIC_CACHE[prefetch.ttl_unaccessed_in_days]}'' --inplace ${FILE_PACOLOCO_CONF}
        [[ ${REPOPUBLIC_CACHE[prefetch.ttl_unupdated_in_days]} ]] && yq '.prefetch.ttl_unupdated_in_days = '${REPOPUBLIC_CACHE[prefetch.ttl_unupdated_in_days]}'' --inplace ${FILE_PACOLOCO_CONF}
        while IFS= read -u3 SELECT_REPOPUBLIC_CACHE; do
	    if [[ ${SELECT_REPOPUBLIC_CACHE,,} == @(0|"port"|"cache_dir"|"purge_files_after"|"download_timeout"|"user_agent"|"http_proxy"|"prefetch.cron"|"prefetch.ttl_unaccessed_in_days"|"prefetch.ttl_unupdated_in_days") ]]; then
	    # Название параметра, не репозиторий
	        true
	    else
	    # Имя репозитория
	        REPOPUBLIC_CACHE_REPO_MANUAL=yes
	        REPOPUBLIC_CACHE_URL_LIST=()
	        while IFS= read -u4 SELECT_REPOPUBLIC_CACHE_URL; do
		    if [[ ${SELECT_REPOPUBLIC_CACHE_URL} =~ (.*)"@"(.*) ]]; then
			REPOPUBLIC_CACHE_TYPE=${BASH_REMATCH[1]}
			REPOPUBLIC_CACHE_URL=${BASH_REMATCH[2]}
			if [[ ${REPOPUBLIC_CACHE_TYPE} == @("url"|"urls") ]]; then
			    REPOPUBLIC_CACHE_URL_LIST+=(${REPOPUBLIC_CACHE_URL})
			else
			    yq -p yaml -o yaml '.repos.'${SELECT_REPOPUBLIC_CACHE}'.'${REPOPUBLIC_CACHE_TYPE}' = "'${REPOPUBLIC_CACHE_URL}'"' --inplace ${FILE_PACOLOCO_CONF}
			fi
		    fi
		done 4<<< "${REPOPUBLIC_CACHE[${SELECT_REPOPUBLIC_CACHE}]//,/$'\n'}"
		if [[ ${#REPOPUBLIC_CACHE_URL_LIST[@]} -ge 2 ]]; then
		    REPOPUBLIC_CACHE_TYPE="urls"
		    for SELECT_REPOPUBLIC_CACHE_URL in ${REPOPUBLIC_CACHE_URL_LIST[@]}; do
		        yq -p yaml -o yaml '.repos.'${SELECT_REPOPUBLIC_CACHE}'.'${REPOPUBLIC_CACHE_TYPE}' += ["'${SELECT_REPOPUBLIC_CACHE_URL}'"]' --inplace ${FILE_PACOLOCO_CONF}
		    done
		else
		    REPOPUBLIC_CACHE_TYPE="url"
		    yq -p yaml -o yaml '.repos.'${SELECT_REPOPUBLIC_CACHE}'.'${REPOPUBLIC_CACHE_TYPE}' = "'${REPOPUBLIC_CACHE_URL}'"' --inplace ${FILE_PACOLOCO_CONF}
		fi
    	    fi
    	done 3< <(printf "%s\n" "${!REPOPUBLIC_CACHE[@]}")
    	if [[ ${REPOPUBLIC_CACHE_REPO_MANUAL} == "" ]]; then
    	    VERSION_ID=$(grep "VERSION_ID" ${ROOTFS}/etc/os-release | cut -d= -f2)
    	    yq -p yaml -o yaml \
    	        '.repos.ublinux_'${VERSION_ID}'.urls += ["http://repo.ublinux.ru/'${VERSION_ID}'"] |
    	        .repos.ublinux_'${VERSION_ID}'.urls += ["https://repo.ublinux.ru/'${VERSION_ID}'"]' --inplace ${FILE_PACOLOCO_CONF}
    	fi
    	systemctl --quiet restart pacoloco.service
    }
    disable_pacoloco(){
	systemctl --quiet disable pacoloco.service
	systemctl --quiet stop pacoloco.service
	find /memory/bundles -maxdepth 3 -path "*/etc/*" -type f -name "pacoloco.yaml" -exec cp -af {} "/etc/" \; -quit
    }
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local PARAM="$@"
    if [[ -n ${PARAM} ]]; then
        REPOPUBLIC_CACHE_NAME=${PARAM%%=*}
        REPOPUBLIC_CACHE_VAR=${PARAM#*=}
    fi
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#REPOPUBLIC_CACHE[@]} != 0 ]]; then
	if [[ ${REPOPUBLIC_CACHE[0]} == @("enable"|"yes") ]]; then
    	# Включить управление
	    enable_pacoloco
	elif [[ ${REPOPUBLIC_CACHE[0]} == @("disable"|"no"|"none") ]]; then
	# Отключить управление 
	    disable_pacoloco
	fi
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	if [[ ${REPOPUBLIC_CACHE[0]} == @("enable"|"yes") ]]; then
    	# Включить управление
	    enable_pacoloco
	elif [[ ${REPOPUBLIC_CACHE_NAME} == "REPOPUBLIC_CACHE" ]]; then
	# Отключить управление 
	    disable_pacoloco
	fi
    fi
}

## Настройка автообновления системы
## AUTOUPDATE=enable
##   enable	# Включает автообновление. Параметрами по умолчанию: modsys boot core,extra,community,multilib,modules
## Настройка режимов обновления
## AUTOUPDATE[mode]=*modsys|modules|system	
##  *modsys	# Вначале обновлять все модули и после систему. Использует [update] REPOSITORY[modules]=
##   modules	# Обновлять только модули. Использует [update] REPOSITORY[modules]=
##   system	# Обновлять всё в порядке указанных репозиториев
## Настройка интервала обновления
## AUTOUPDATE[interval]=*boot,30min|12h|*7d|1M
##    *boot     # Каждую загрузку
##     30min	# Каждые 30 минут, возможно указать любую цифру
##     12h	# Каждые 12 часов, возможно указать любую цифру
##    *7d	# Каждые 7 дней, возможно указать любую цифру
##     1M	# Один раз в месяц, возможно указать любую цифру
## TODO: Настройка репозиториев обновления
## AUTOUPDATE[repos]=<repository_1>,<repository_2>,<repository_n>
##   <repository_n>     # Имена репозиториев с которых будет происходить обновление. Если не указано, то по умолчанию все системные
## AUTOUPDATE=enable
exec_autoupdate(){
    enable_autoupdate(){
	ONBOOTSEC=
	ONACTIVESEC=
	AUTOUPDATE_INTERVAL_SEC=
	while read -u3 AUTOUPDATE_INTERVAL; do
	    [[ ${AUTOUPDATE_INTERVAL} == "boot" ]] && ONBOOTSEC="OnBootSec=" || ONACTIVESEC="OnActiveSec="
	    if [[ ${AUTOUPDATE_INTERVAL} =~ ^([[:digit:]])"min"$ ]]; then
		AUTOUPDATE_INTERVAL_SEC="${BASH_REMATCH[1]}min"
	    elif [[ ${AUTOUPDATE_INTERVAL} =~ ^([[:digit:]])"h"$ ]]; then
		AUTOUPDATE_INTERVAL_SEC="${BASH_REMATCH[1]}h"
	    elif [[ ${AUTOUPDATE_INTERVAL} =~ ^([[:digit:]])"d"$ ]]; then
		AUTOUPDATE_INTERVAL_SEC="$((${BASH_REMATCH[1]}*24))h"
	    elif [[ ${AUTOUPDATE_INTERVAL} =~ ^([[:digit:]])"M"$ ]]; then
		AUTOUPDATE_INTERVAL_SEC="$((${BASH_REMATCH[1]}*24*30))h"
	    fi
	done 3<<< ${AUTOUPDATE[interval]//,/$'\n'}
	ONUNITACTIVESEC="OnUnitActiveSec=${AUTOUPDATE_INTERVAL_SEC}"
	[[ -n ${ONBOOTSEC} ]] & ONBOOTSEC+="${AUTOUPDATE_INTERVAL_SEC}"
	[[ -n ${ONACTIVESEC} ]] & ONACTIVESEC+="${AUTOUPDATE_INTERVAL_SEC}"
		
	cat <<-EOF > "${PATH_AUTOUPDATE_SERVICE}"
[Unit]
Description=Automatic Update UBLinux
After=network-online.target

[Service]
Type=simple
SyslogIdentifier=autoupdate
ExecStart=${FILE_LIVE_AUTOUPDATE}
TimeoutStopSec=300
KillMode=process
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target
EOF
	cat <<-EOF > "${PATH_AUTOUPDATE_TIMER}"
[Unit]
Description=Automatic Update UBLinux

[Timer]
${ONBOOTSEC}
${ONACTIVESEC}
${ONUNITACTIVESEC}
Unit=${AUTOUPDATE_SERVICE}

[Install]
WantedBy=multi-user.target
EOF
	systemctl --quiet daemon-reload    
	systemctl --quiet restart ${AUTOUPDATE_TIMER}
    }
    disable_autoupdate(){
	systemctl --quiet disable ${AUTOUPDATE_TIMER} ${AUTOUPDATE_SERVICE} 2>/dev/null
	systemctl --quiet stop ${AUTOUPDATE_TIMER} ${AUTOUPDATE_SERVICE} 2>/dev/null
	rm -f "${PATH_AUTOUPDATE_SERVICE}" "${PATH_AUTOUPDATE_TIMER}"
	systemctl --quiet daemon-reload    
    }
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local PARAM="$@"
    if [[ -n ${PARAM} ]]; then
        AUTOUPDATE_NAME=${PARAM%%=*}
        AUTOUPDATE_VAR=${PARAM#*=}
    fi
    FILE_LIVE_AUTOUPDATE="/usr/lib/ublinux/rc.local.d/43-repository live_autoupdate"
    AUTOUPDATE_SERVICE="ubconfig-autoupdate.service"
    PATH_AUTOUPDATE_SERVICE="/usr/lib/systemd/system/${AUTOUPDATE_SERVICE}"
    AUTOUPDATE_TIMER="ubconfig-autoupdate.timer"
    PATH_AUTOUPDATE_TIMER="/usr/lib/systemd/system/${AUTOUPDATE_TIMER}"
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then
	if [[ ${AUTOUPDATE[0]} == @("enable"|"yes") ]]; then
	    enable_autoupdate
	elif [[ ${AUTOUPDATE[0]} == @("disable"|"no") ]]; then
	    disable_autoupdate
	fi
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	if [[ ${AUTOUPDATE[0]} == @("enable"|"yes") ]]; then
	    enable_autoupdate
	elif [[ ${AUTOUPDATE_NAME} == "AUTOUPDATE" ]]; then
	    disable_autoupdate
	fi
    fi
}

# Обновление системы, выполняемое сервисом "ubconfig-autoupdate.service" по таймеру "ubconfig-autoupdate.timer"
live_autoupdate(){
    autoupdate_only_modules(){
    # Обновить систему только из репозитория [modules]
        # Соханить параметры до обновления
        SAVE_REPOSITORY=$(ubconfig --nocolor --source system get [update] REPOSITORY)
        SAVE_REPOSITORY_ARRAY=$(ubconfig --nocolor --source system get [update] REPOSITORY[*])
        REPOSITORY_MODULES=$(ubconfig --nocolor --source system get [update] REPOSITORY[modules])
        [[ ${REPOSITORY_MODULES} == @(""|"(null)") ]] && REPOSITORY_MODULES="REPOSITORY[modules]=/etc/pacman.d/mirrorlist"
	ubconfig --quiet --nocolor --target system set [update] REPOSITORY=disable
	ubconfig --quiet --nocolor --target system remove [update] "REPOSITORY[*]"
	ubconfig --quiet --nocolor --target system set [update] ${REPOSITORY_MODULES}
	ubconfig --quiet --nocolor --target system set [update] REPOSITORY=only
	/usr/bin/nice -n 19 /usr/bin/pacman -Syuwq --noconfirm
	/usr/bin/nice -n 19 /usr/bin/pacman -Suu --noconfirm
	ubconfig --quiet --nocolor --target system set [update] REPOSITORY=disable
	ubconfig --quiet --nocolor --target system remove [update] "REPOSITORY[*]"
	# Восстановить параметры после обновления
	[[ ${SAVE_REPOSITORY} == @(""|"(null)") ]] || ubconfig --quiet --nocolor --target system set [update] ${SAVE_REPOSITORY}
	[[ ${SAVE_REPOSITORY_ARRAY} == @(""|"(null)") ]] || ubconfig --quiet --nocolor --target system set [update] ${SAVE_REPOSITORY_ARRAY}
    }
    if [[ ${AUTOUPDATE[0]} == @("enable"|"yes") ]]; then
	FILE_LOG_AUTOUPDATE="/var/log/ubconfig-autoupdate.log"
	exec &> >(tee -a "${FILE_LOG_AUTOUPDATE}")
	echo
	date
	if [[ ${AUTOUPDATE[mode]} == "modsys" ]]; then
	    # Обновить систему из репозитория [modules]
	    autoupdate_only_modules
	    # Обновить систему из всех подключеных репозиториев
	    /usr/bin/nice -n 19 /usr/bin/pacman -Syuwq --noconfirm
	    /usr/bin/nice -n 19 /usr/bin/pacman -Suu --noconfirm
	elif [[ ${AUTOUPDATE[mode]} == "modules" ]]; then
	    # Обновить систему из репозитория [modules]
	    autoupdate_only_modules
	elif [[ ${AUTOUPDATE[mode]} == "system" ]]; then
	    # Обновить систему из всех подключеных репозиториев
	    /usr/bin/nice -n 19 /usr/bin/pacman -Syuwq --noconfirm
	    /usr/bin/nice -n 19 /usr/bin/pacman -Suu --noconfirm
	fi
	UPDATE_TIMESTAMP=$(date +'%Y-%m-%d %H:%M')
	ubconfig --quiet --nocolor set [update] AUTOUPDATE[timestamp]="${UPDATE_TIMESTAMP}"
	#notify_send "Update ${UPDATE_TIMESTAMP}" -i dialog-warning
	#notify-send --action 'STOPUPDATE=Остановить обновление' test
    fi
}

## Удалить версии дубликатов пакетов в базе pacman
exec_remove_duplicated_pacman(){
    ## Если в полном сохранении пользователь обновиляет систему и в очередное обновление обновил только модули, то изменения останутся старыми, т.к. /changes/ имеет приориетный низкий слой
    ##  т.е. по факту приложения останутся старыми. В БД пакетов будут новые имена из модуля видны, и далее могут не дать обновить на новые пакеты.
    ##  т.е. в базе pacman будут новые пакеты, а по факту файлы/бинарники старые
        local PATH_PACMAN_DB="/var/lib/pacman/local/"
        local PKG_PACMAN_DB_OLD=()
        local PKG_PACMAN_DB_NEW=()
        # Из всех дубликатов приложений в базе pacman удалить старые версии
        #cd ${PATH_PACMAN_DB}; rm -rdf $(ls -1vr ${PATH_PACMAN_DB} | sed -En 's/((.*)-([^-]+)-([^-]+))/\2|\1/p' | awk -F '|' 'prefixes[$1]++ {print $2}') #'
        readarray -t PKG_PACMAN_DB_OLD < <(ls -1vr ${PATH_PACMAN_DB} | sed -En 's/((.*)-([^-]+)-([^-]+))/\2|\1/p' | awk -F '|' 'prefixes[$1]++ {print $2}') #'
        readarray -t PKG_PACMAN_DB_NEW < <(ls -1v ${PATH_PACMAN_DB} | sed -En 's/((.*)-([^-]+)-([^-]+))/\2|\1/p' | awk -F '|' 'prefixes[$1]++ {print $2}') #'
        # Индексы позиций имени пакетов в массиве одинаковые, только разные версии
        for PKG_PACMAN_DB in ${!PKG_PACMAN_DB_OLD[@]}; do
            # Старые пакеты ${PKG_PACMAN_DB_OLD[${PKG_PACMAN_DB}]}
            # Новые пакеты  ${PKG_PACMAN_DB_NEW[${PKG_PACMAN_DB}]}
            if [[ -d "/memory/changes/${PATH_PACMAN_DB}/${PKG_PACMAN_DB_NEW[${PKG_PACMAN_DB}]}" ]]; then
                # Если новые пакет находится в самом низком слое /changes/, то значит и файлы данных пакеты будут новые
                # Следует удалить старое имя пакета из корня
                rm -rdf "${PATH_PACMAN_DB}/${PKG_PACMAN_DB_OLD[${PKG_PACMAN_DB}]}"
            elif [[ -d "/memory/changes/${PATH_PACMAN_DB}/${PKG_PACMAN_DB_OLD[${PKG_PACMAN_DB}]}" ]]; then
                # Если старый пакет находится в самом низком слое /changes/, то значит и файлы данных пакеты будут старые, не смотря на новизну модуля
                # Следует удалить новое имя пакета из корня
                rm -rdf "${PATH_PACMAN_DB}/${PKG_PACMAN_DB_NEW[${PKG_PACMAN_DB}]}"
            else
                # В нижнем слое /changes/ нет пакета, значит оба пакета и старый и новый находятся в модулях
                # Сравниваем номера слоёв старого и нового пакета и удяляем имя пакета в более высоком слое, который перекрывается более низким слоем
                local AUFS_BUNDLE=$(aufs-n --raw '$n $bname_bundle')
                AUFS_BUNDLE_PKG_NEW=$(find /memory/bundles/*/var/lib/pacman/local/ -maxdepth 1 -type d -name "${PKG_PACMAN_DB_NEW[${PKG_PACMAN_DB}]}" | cut -d/ -f4 | head -1)
                AUFS_BUNDLE_PKG_OLD=$(find /memory/bundles/*/var/lib/pacman/local/ -maxdepth 1 -type d -name "${PKG_PACMAN_DB_OLD[${PKG_PACMAN_DB}]}" | cut -d/ -f4 | head -1)
                local AUFS_BUNDLE_PKG_NEW_NUM=
                local AUFS_BUNDLE_PKG_OLD_NUM=
                [[ ${AUFS_BUNDLE} =~ (^|$'\n')([[:digit:]]+)' '${AUFS_BUNDLE_PKG_NEW}($'\n'|$) ]] && AUFS_BUNDLE_PKG_NEW_NUM="${BASH_REMATCH[2]}"
                [[ ${AUFS_BUNDLE} =~ (^|$'\n')([[:digit:]]+)' '${AUFS_BUNDLE_PKG_OLD}($'\n'|$) ]] && AUFS_BUNDLE_PKG_OLD_NUM="${BASH_REMATCH[2]}"
                if [[ -n ${AUFS_BUNDLE_PKG_NEW_NUM} && -n ${AUFS_BUNDLE_PKG_OLD_NUM} ]]; then
		    # Принудительно указываем, что числа в десятичной системе исчисления $((10#${}))
		    if [[ $((10#${AUFS_BUNDLE_PKG_NEW_NUM})) -lt $((10#${AUFS_BUNDLE_PKG_OLD_NUM})) ]]; then
                        rm -rdf "${PATH_PACMAN_DB}/${PKG_PACMAN_DB_OLD[${PKG_PACMAN_DB}]}"
                    else
                        rm -rdf "${PATH_PACMAN_DB}/${PKG_PACMAN_DB_NEW[${PKG_PACMAN_DB}]}"
                    fi
                fi
            fi
        done
        # Ситуация для которой не нужно обработки, т.к. манипулировать данными не нужно
        # Одно из решений - после установки модулей проверять какие пакеты в базе дублируются и эти файлы этих приложений из модуля переписать в корень
        #sudo rsync -hrlptgoDHAXEU --existing --update --exclude ".wh.*" --progress /memory/bundles/010-core-2204-2-x86_64.ubm/ /
}

################
##### MAIN #####
################

    # Если файл подключен как ресурс с функциями, то выйти
    return 0 2>/dev/null && return 0
    if [[ -z $@ ]]; then
        while read -ru3 FUNCTION; do
            $"${FUNCTION##* }"
        done 3< <(declare -F | grep "declare -f exec_")
    else
	FUNCTION=
	while [[ $# -gt 0 ]]; do
	    [[ -z ${1} ]] || { declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1//\'/}'"; }
	    shift
	done
	eval ${FUNCTION#*; }
    fi
