#!/usr/bin/env bash
#
# Author: Dmitry Razumov <asmeron@ublinux.com>
# Copyright (c) 2021-2025 UBLinux <support@ublinux.com>
#
# Initial script for Linux UBLinux
# This script are launching before starting init from initrd script
# Current dir allways must be set to root (/)
# All system path must be relative, except initrd dirs

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

PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin

[[ -d /usr/lib/ublinux ]] && { ROOTFS= ; CMD_CHROOT= ; } || { [[ -d /sysroot ]] && ROOTFS="/sysroot" || ROOTFS="."; CMD_CHROOT="chroot ${ROOTFS}"; }
SOURCE=${ROOTFS}/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
debug_mode "$0" "$@"

SYSCONF="${ROOTFS}${SYSCONF}"
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/system; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null

exec_copy_to_initd(){
# Функция создания симлинка в /etc/init.d на сервисы из /etc/rc.d/init.d
    PATH_INITD="${ROOTFS}/etc/init.d"
    PATH_RCD_INITD="${ROOTFS}/etc/rc.d/init.d"
    while read -u3 SELECT_FILE_SERVICE; do
	[[ -e ${PATH_INITD}/${SELECT_FILE_SERVICE} ]] || ln -s ${PATH_RCD_INITD}/${SELECT_FILE_SERVICE} ${PATH_INITD}
    done 3< <(ls -1 ${PATH_RCD_INITD} 2>/dev/null | grep -vE "README|functions")
}

exec_services_enabledisable(){
# Функция включения/отключения сервисов в предзагрузке SERVICES_ENABLE=
# $1 	Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
# $2 	Параметр со значением, пример: SERVICES_ENABLE=pcscd.service,nmb,smb
# null	Если отсутствует $@, то применяем из системной конфигурации SERVICESSTART SERVICESNOSTART SERVICESMASK SERVICESUNMASK
    ISSYSTEMD=$(readlink -fq ${ROOTFS}/usr/bin/init | grep "lib/systemd/systemd$")
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local PARAM="$@"
    if [[ -n ${PARAM} ]]; then
	local SERVICESSTART= SERVICESNOSTART= SERVICESMASK= SERVICESUNMASK=
	local SERVICES_ENABLE= SERVICES_DISABLE= SERVICES_MASK= SERVICES_UNMASK=
	[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
    else
	SERVICESSTART_KERNEL=$(cmdline_value servicesstart)
	SERVICES_ENABLE_KERNEL=$(cmdline_value services_enable)
	[[ -z ${SERVICESSTART_KERNEL} ]] || SERVICESSTART=${SERVICESSTART_KERNEL}
	[[ -z ${SERVICES_ENABLE_KERNEL} ]] || SERVICES_ENABLE=${SERVICES_ENABLE_KERNEL}
	SERVICESNOSTART_KERNEL=$(cmdline_value servicesnostart)
	SERVICES_DISABLE_KERNEL=$(cmdline_value services_disable)
	[[ -z ${SERVICESNOSTART_KERNEL} ]] || SERVICESNOSTART=${SERVICESNOSTART_KERNEL}
	[[ -z ${SERVICES_DISABLE_KERNEL} ]] || SERVICES_DISABLE=${SERVICES_DISABLE_KERNEL}
    fi
    if [[ -n "${SERVICESSTART}${SERVICESNOSTART}${SERVICESMASK}${SERVICESUNMASK}${SERVICES_ENABLE}${SERVICES_DISABLE}${SERVICES_MASK}${SERVICES_UNMASK}" ]]; then
	if [[ -n ${ROOTFS} ]]; then
	    mkdir -p proc
	    mount -o rbind /proc proc
	fi
	if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then
	    while IFS= read -ru3 SELECT_SERVICE; do
		[[ -n ${SELECT_SERVICE} ]] || continue
		if [[ -n ${ISSYSTEMD} ]]; then
		    ${CMD_CHROOT} /usr/bin/systemctl --quiet unmask ${SELECT_SERVICE}
		fi
	    done 3< <(tr ',; ' '\n' <<< "${SERVICESUNMASK},${SERVICESSTART},${SERVICES_UNMASK},${SERVICES_ENABLE}" | tr -s '\n')
	    while IFS= read -ru3 SELECT_SERVICE; do
		[[ -n ${SELECT_SERVICE} ]] || continue
		if [[ -n ${ISSYSTEMD} ]]; then
		    ${CMD_CHROOT} /usr/bin/systemctl --quiet enable ${SELECT_SERVICE}
		fi
	    done 3< <(tr ',; ' '\n' <<< "${SERVICESSTART},${SERVICES_ENABLE}" | tr -s '\n')
	    while IFS= read -ru3 SELECT_SERVICE; do
		[[ -n ${SELECT_SERVICE} ]] || continue
		if [[ -n ${ISSYSTEMD} ]]; then
		    ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
		fi
	    done 3< <(tr ',; ' '\n' <<< "${SERVICESNOSTART},${SERVICES_DISABLE}" | tr -s '\n')
	    while IFS= read -ru3 SELECT_SERVICE; do
		[[ -n ${SELECT_SERVICE} ]] || continue
		if [[ -n ${ISSYSTEMD} ]]; then
		    ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
		    ${CMD_CHROOT} /usr/bin/systemctl --quiet mask ${SELECT_SERVICE}
		fi
	    done 3< <(tr ',; ' '\n' <<< "${SERVICESMASK},${SERVICES_MASK}" | tr -s '\n')
	elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	    while IFS= read -ru3 SELECT_SERVICE; do
		[[ -n ${SELECT_SERVICE} ]] || continue
		if [[ -n ${ISSYSTEMD} ]]; then
		    true
		fi
	    done 3< <(tr ',; ' '\n' <<< "${SERVICESUNMASK},${SERVICESSTART},${SERVICES_UNMASK},${SERVICES_ENABLE}" | tr -s '\n')
	    while IFS= read -ru3 SELECT_SERVICE; do
		[[ -n ${SELECT_SERVICE} ]] || continue
		if [[ -n ${ISSYSTEMD} ]]; then
		    ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
		fi
	    done 3< <(tr ',; ' '\n' <<< "${SERVICESSTART},${SERVICES_ENABLE}" | tr -s '\n')
	    while IFS= read -ru3 SELECT_SERVICE; do
		[[ -n ${SELECT_SERVICE} ]] || continue
		if [[ -n ${ISSYSTEMD} ]]; then
		    true
		fi
	    done 3< <(tr ',; ' '\n' <<< "${SERVICESNOSTART},${SERVICES_DISABLE}" | tr -s '\n')
	    while IFS= read -ru3 SELECT_SERVICE; do
		[[ -n ${SELECT_SERVICE} ]] || continue
		if [[ -n ${ISSYSTEMD} ]]; then
		    ${CMD_CHROOT} /usr/bin/systemctl --quiet unmask ${SELECT_SERVICE}
		fi
	    done 3< <(tr ',; ' '\n' <<< "${SERVICESMASK},${SERVICES_MASK}" | tr -s '\n')
	fi
	[[ -z ${ROOTFS} ]] || umount proc
    fi
}

exec_services_startstop_live(){
# Функция запуска/остановка сервисов в загруженной системе SERVICES_ENABLE=
# $1 	Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
# $2 	Параметр со значением. Пример: SERVICES_ENABLE=pcscd.service,nmb,smb
# null	Если отсутствует $@, то применяем из системной конфигурации SERVICESSTART SERVICESNOSTART SERVICESMASK SERVICESUNMASK SERVICES_ENABLE SERVICES_DISABLE SERVICES_MASK SERVICES_UNMASK
# Если выполнение в initrd, то выход
    [[ -z ${ROOTFS} ]] || return 0
    ISSYSTEMD=$(readlink -fq ${ROOTFS}/usr/bin/init | grep "lib/systemd/systemd$")
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || COMMAND="set="
    local PARAM="$@"
    if [[ -n ${PARAM} ]]; then
	local SERVICESSTART= SERVICESNOSTART= SERVICESMASK= SERVICESUNMASK=
	local SERVICES_ENABLE= SERVICES_DISABLE= SERVICES_MASK= SERVICES_UNMASK=
	[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
    fi
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then
	while IFS= read -ru3 SELECT_SERVICE; do
	    [[ -n ${SELECT_SERVICE} ]] || continue
	    if [[ -n ${ISSYSTEMD} ]]; then
	        systemctl --quiet start ${SELECT_SERVICE}
	    fi
	done 3< <(tr ',; ' '\n' <<< "${SERVICESSTART},${SERVICES_ENABLE}" | tr -s '\n')
	while IFS= read -ru3 SELECT_SERVICE; do
	    [[ -n ${SELECT_SERVICE} ]] || continue
	    if [[ -n ${ISSYSTEMD} ]]; then
	        systemctl --quiet stop ${SELECT_SERVICE}
	    fi
	done 3< <(tr ',; ' '\n' <<< "${SERVICESNOSTART},${SERVICES_DISABLE}" | tr -s '\n')
	while IFS= read -ru3 SELECT_SERVICE; do
	    [[ -n ${SELECT_SERVICE} ]] || continue
	    if [[ -n ${ISSYSTEMD} ]]; then
	        systemctl --quiet stop ${SELECT_SERVICE}
	    fi
	done 3< <(tr ',; ' '\n' <<< "${SERVICESMASK},${SERVICES_MASK}" | tr -s '\n')
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	while IFS= read -ru3 SELECT_SERVICE; do
	    [[ -n ${SELECT_SERVICE} ]] || continue
	    if [[ -n ${ISSYSTEMD} ]]; then
	        systemctl --quiet stop ${SELECT_SERVICE}
	    fi
	done 3< <(tr ',; ' '\n' <<< "${SERVICESSTART},${SERVICES_ENABLE}" | tr -s '\n')
	while IFS= read -ru3 SELECT_SERVICE; do
	    [[ -n ${SELECT_SERVICE} ]] || continue
	    if [[ -n ${ISSYSTEMD} ]]; then
		true
	    fi
	done 3< <(tr ',; ' '\n' <<< "${SERVICESNOSTART},${SERVICES_DISABLE}" | tr -s '\n')
	while IFS= read -ru3 SELECT_SERVICE; do
	    [[ -n ${SELECT_SERVICE} ]] || continue
	    if [[ -n ${ISSYSTEMD} ]]; then
	        systemctl --quiet unmask ${SELECT_SERVICE}
	    fi
	done 3< <(tr ',; ' '\n' <<< "${SERVICESMASK},${SERVICES_MASK}" | tr -s '\n')
    fi
}

#Выключил, т.к. не перезапишет параметры по умолчанию
# т.к. проблематично проигнорировать все SERVICE[*] из /usr/lib/default, если заданы SERVICE[*] в глобальном конфиге
#exec_services_enabledisable_new(){
## Функция включения/отключения сервисов в предзагрузке SERVICE[*]=
## $1 	Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
## $2 	Параметр со значением, пример: SERVICE[smb]=enable
## null	Если отсутствует $@, то применяем из системной конфигурации SERVICE[<name>]=start|enable|on|stop|disable|off|mask|unmask
#    ISSYSTEMD=$(readlink -fq ${ROOTFS}/usr/bin/init | grep "lib/systemd/systemd$")
#    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && shift
#    local PARAM="$@"
#    if [[ -n ${PARAM} ]]; then
#	local SERVICE=
#	declare -A SERVICE=()
#	[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
#    else
#	SERVICES_ENABLE_KERNEL=$(cmdline_value services_enable)
#	[[ -z ${SERVICES_ENABLE_KERNEL} ]] || while read -u3 SELECT_SERVICE; do
#	    [[ -n ${SELECT_SERVICE} ]] || continue
#	    SERVICE[${SELECT_SERVICE}]=enable
#	done 3< <(tr ',; ' '\n' <<< "${SERVICES_ENABLE_KERNEL}" | tr -s '\n')
#
#	SERVICES_DISABLE_KERNEL=$(cmdline_value services_disable)
#	[[ -z ${SERVICES_DISABLE_KERNEL} ]] || while read -u3 SELECT_SERVICE; do
#	    [[ -n ${SELECT_SERVICE} ]] || continue
#	    SERVICE[${SELECT_SERVICE}]=disable
#	done 3< <(tr ',; ' '\n' <<< "${SERVICES_DISABLE_KERNEL}" | tr -s '\n')
#    fi
#    if [[ -n "${SERVICE[@]}" ]]; then
#	if [[ -n ${ROOTFS} ]]; then
#	    mkdir -p proc
#	    mount -o rbind /proc proc
#	fi
#	while read -u3 SELECT_SERVICE; do
#	    [[ -n ${SELECT_SERVICE} ]] || continue
#	    if [[ ${SERVICE[${SELECT_SERVICE}]} == @(start|enable|on) ]]; then
#		if [[ -n ${ISSYSTEMD} ]]; then
#		    ${CMD_CHROOT} /usr/bin/systemctl --quiet unmask ${SELECT_SERVICE}
#		    ${CMD_CHROOT} /usr/bin/systemctl --quiet enable ${SELECT_SERVICE}
#		fi
#	    elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(stop|disable|off) ]]; then
#		if [[ -n ${ISSYSTEMD} ]]; then
#		    ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
#		fi
#	    elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(mask) ]]; then
#		if [[ -n ${ISSYSTEMD} ]]; then
#		    ${CMD_CHROOT} /usr/bin/systemctl --quiet disable ${SELECT_SERVICE}
#		    ${CMD_CHROOT} /usr/bin/systemctl --quiet mask ${SELECT_SERVICE}
#		fi
#	    elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(unmask) ]]; then
#		if [[ -n ${ISSYSTEMD} ]]; then
#		    ${CMD_CHROOT} /usr/bin/systemctl --quiet unmask ${SELECT_SERVICE}
#		fi
#	    fi
#	done 3< <(printf "%s\n" "${!SERVICE[@]}")
#	[[ -n ${ROOTFS} ]] && umount proc
#    fi
#}

#Выключил, т.к. не перезапишет параметры по умолчанию
# т.к. проблематично проигнорировать все SERVICE[*] из /usr/lib/default, если заданы SERVICE[*] в глобальном конфиге
#exec_services_startstop_live_new(){
## Функция запуска/остановка сервисов в загруженной системе SERVICE[*]=
## $1 	Команды set или remove с режимом, варианты: set=|set+=|set++=|set-=|set--=|remove
## $2 	Параметр со значением, пример: SERVICE[smb]=enable
## null	Если отсутствует $@, то применяем из системной конфигурации SERVICE[*]=start|enable|on|stop|disable|off|mask|unmask
## Если выполнение в initrd, то выход
#    [[ -z ${ROOTFS} ]] || return 0
#    ISSYSTEMD=$(readlink -fq ${ROOTFS}/usr/bin/init | grep "lib/systemd/systemd$")
#    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && shift
#    local PARAM="$@"
#    if [[ -n ${PARAM} ]]; then
#	local SERVICE=
#	declare -A SERVICE=()
#	[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
#    fi
#    while read -u3 SELECT_SERVICE; do
#        if [[ ${SERVICE[${SELECT_SERVICE}]} == @(start|enable|on) ]]; then
#	    if [[ -n ${ISSYSTEMD} ]]; then
#	        ${CMD_CHROOT} /usr/bin/systemctl --quiet start ${SELECT_SERVICE}
#	    fi
#	elif [[ ${SERVICE[${SELECT_SERVICE}]} == @(stop|disable|off) ]]; then
#	    if [[ -n ${ISSYSTEMD} ]]; then
#	        ${CMD_CHROOT} /usr/bin/systemctl --quiet stop ${SELECT_SERVICE}
#	    fi
#	fi
#    done 3< <(printf "%s\n" "${!SERVICE[@]}")
#}

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

    # Если файл подключен как ресурс с функциями, то выйти
    return 0 2>/dev/null && return 0
    if [[ -z $@ ]]; then
        while read -r FUNCTION; do
            $"${FUNCTION##* }"
        done < <(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
