#!/usr/bin/env bash
#
# Description[en]: Helper functions for .umb module utility manager
# Description[ru]: Функции для утилит управления модулями .umb
# Author: Dmitry Razumov <asmeron@ublinux.com>
#
# Выражаю благодность разработчикам проекта pfs-utils, за идею и вдохновение
# Форк проекта pfs-utils (https://github.com/pfs-utils)
# Fork from pfs-utils (https://github.com/pfs-utils)
#

VERSION_SCRIPT=2.17

HELP_UBM() {
    echo -e "$(basename $0) is a library for ubm script utils\n"
    echo    "Usage:"
    echo    "	$(basename $0) <function> <pars>"
    echo    "		OR"
    echo -e "	. $(realpath $0) ;  <function> <pars> \n"
    echo    "Available functions list:"
    echo    "$(cat $0 |grep '^.*\ *().*{\ *$' |sed 's/().*{//')"
#   cat $0 |grep \(\).*{$
    exit 0
}

COL(){
    color_red='\033[0;31m'
    color_green='\033[0;32m'
    color_yellow='\033[0;33m'
    color_blue='\033[0;34m'
    color_default='\033[0m'
}

# Сообщение $1 в цвете, код ошибки $2
#	$2=0 	 - простое сообщение оранжевое
#	$2=иное  - сообщение об ошибке красное
#	$3=отсутствует/любое - не выходим / выход с кодом $2
msg(){
    [[ $2 == 0 ]] && echo -ne "$color_yellow" || echo -ne "$color_red"
    echo -ne "$1"; echo -ne "$color_default\n"
    [[ -z $3 ]] || exit $2
}

exitmsg() {
    if [[ $2 -ne 0 ]]; then
	echo -ne "$color_red" ; echo "$1" ; echo -ne "$color_default\n"
	[ $3 ] || exit $2
    fi
} 

allow_only_root() {
    if [ "0$UID" -ne 0 ]; then
        exitmsg "Only root can run $0" -1
    fi
}

# Чистим мусор в директории $1
trim() {
    [[ $1 ]] && REMOVE_PATH="$1" || return 1
    [[ -d ${REMOVE_PATH} && ${a//./} != "/" ]] || return 2
    cat <<EOF | while read FILE_RM; do rm -f "${FILE_RM}"; done
${REMOVE_PATH}/etc/machine-id
${REMOVE_PATH}/etc/udev/hwdb.bin
${REMOVE_PATH}/etc/ld.so.cache
${REMOVE_PATH}/var/cache/ldconfig/aux-cache
${REMOVE_PATH}/usr/local/share/applications/mimeinfo.cache
${REMOVE_PATH}/usr/share/applications/mimeinfo.cache
EOF
    cat <<EOF | while read PATH_RM; do rm -rdf "${PATH_RM}"; done
${REMOVE_PATH}/tmp
${REMOVE_PATH}/run
${REMOVE_PATH}/var/tmp
${REMOVE_PATH}/var/cache/pkgfile
${REMOVE_PATH}/var/cache/ldconfig
${REMOVE_PATH}/var/cache/fontconfig
${REMOVE_PATH}/var/cache/pacman
${REMOVE_PATH}/var/lib/pacman/sync
${REMOVE_PATH}/etc/pacman.d/gnupg
EOF
    find "${REMOVE_PATH}/usr/share/icons" -type f -name icon-theme.cache 2>/dev/null | xargs rm -f
#   ${REMOVE_PATH}/var/lib/ubcontainer
#   ${REMOVE_PATH}/var/log
    
}

# Сформитровать в указанной папке $1
#		ubm.files - список файлов модуля,
#		ubm.dirs.empty - список пустых директорий,
# отключил	ubm.depends - список зависимостей
#mklist(){
#    local source_root dest_root pack_name spec_file depends
#    while [ $1 ]; do eval $1; shift; done
#    [ "$source_root" ] || return 1
#    source_root=$(realpath $source_root)
#    if [ "$dest_root" ] ; then
#    	dest_root="$(realpath "$dest_root")"
#    else
#	dest_root="$source_root"
#    fi
#    [ $pack_name ] || pack_name="$(basename "${source_root%.$EXT}")"
#    dest_dir="${dest_root}${UBMDIR}/mount/${pack_name}/"
#    mkdir -p $dest_dir
#    if [ -d "${source_root}${UBMDIR}/mount" -a $(ls -1 "${source_root}${UBMDIR}/mount" 2>/dev/null |wc -l) -gt 1 ] ; then
#	mkdir -p "${dest_dir}submod"
#	cp  -fax "${source_root}${UBMDIR}/mount"   /tmp/
#	mv  -f /tmp/mount "${dest_dir}submod/" &&  rm -rf /tmp/mount
#	for submod in $(ls -1 ${source_root}${UBMDIR}/mount/ 2>/dev/null); do
#	    rm -rf ${dest_root}${UBMDIR}/mount/$submod
#	done
#    fi
#    [ ! -z $spec_file -a -f $spec_file ] && cp "$spec_file" ${dest_dir}/
#    find "${source_root}" ! -type d        | sed 's#'"$source_root"'##' | grep -Ev '^/.wh..wh.|^'$UBMDIR'' > "${dest_dir}/ubm.files"
#    find "${source_root}"   -type d -empty | sed 's#'"$source_root"'##' | grep -Ev '^/.wh..wh.|^'$UBMDIR'' > "${dest_dir}/ubm.dirs.empty"
#    #[ "$depends" ] && echo "$depends" > "${dest_dir}/ubm.depends"
#    #return 0 #иначе без $depends не нулевое завершение
#}

# Получить свободное место на $copyramdir
checkramfreeb(){
    local freedf
    freedf=$(df $copyramdir -B 1024 |tail -n1 |awk '{print $4}' 2>/dev/null)
#    freeram="$(free | grep 'Mem:' | tr -s ' ' | cut -f 4 -d ' ')"
    echo $freedf
}

# Проверка на поддержку системой squashfs/aufs
check_ubm(){
    [ "$aufsroot" ] || return 1
    grep squashfs /proc/filesystems || return 1
    grep aufs /proc/filesystems     || return 1
    return 0
}

# Получить строку информации о фале, в зависимости от типа файла, и блокировки
disktypeb(){
    ftest=$(file "$1")
    if $(echo "$ftest" | grep -Eqi cannot.*open); then
	echo "$ftest" && return 1
    elif $(echo "$ftest" | grep -Eqi block.*special); then
	echo $(blkid -s TYPE "$1") && return 0
    else
        echo "$ftest" && return 0
    fi
}

# Определим тип файла с которыми можем работать
fs_type(){
    diskinfo="$(disktypeb "$1" 2>/dev/null)"
    if echo "${diskinfo}" | grep -qi -F "Ext2"; then
	echo 'ext2'
    elif echo "${diskinfo}" | grep -qi -F "Ext3"; then
	echo 'ext3'
    elif echo "${diskinfo}" | grep -qi -F "Ext4"; then
	echo 'ext4'
    elif echo "${diskinfo}" | grep -qi -F "squashfs"; then
	echo 'squashfs'
    elif echo "${diskinfo}" | grep  -qi "ISO.*9660"; then
	echo 'iso9660'
    fi
}

# Если в busybox работаем
losetupb() { losetup "$@" || busybox losetup "$@" ; }
mountb()   { mount "$@" || busybox mount "$@" ; }
umountb()  { umount "$@" || busybox umount "$@" ; }

# Отмонтировать CHROOT в $1
umount_all_chroot(){
    [ "$1" ] || return 2
    for CHROOT_ROOT in {sys,proc,dev}; do
	while grep -q ${SYSMNT}/aufs-$1/${CHROOT_ROOT} /proc/mounts; do
    	    umount ${SYSMNT}/aufs-$1/${CHROOT_ROOT}
	done
    done
}

# Создать AUFS
make_aufs(){
    [[ -f ${SYSMNT}/aufs-$1.lock ]] &&  return 1
    echo "${SYSMNT}/aufs-$1" > ${SYSMNT}/aufs-$1.lock
    mkdir ${SYSMNT}/changes-$1
    [[ -d $2 ]] && mount --bind $2 /${SYSMNT}/changes-$1 || mount -t tmpfs tmpfs /${SYSMNT}/changes-$1
    mkdir ${SYSMNT}/aufs-$1
    mount -t aufs -o dirs=/${SYSMNT}/changes-$1/=rw aufs /${SYSMNT}/aufs-$1 && echo "${SYSMNT}/aufs-$1" || return 2
}

# Удалить AUFS
delete_aufs(){
# remove aufs from $1
    [ "$1" ] || return 1
    umount_all_chroot $1
    if [ -d ${SYSMNT}/aufs-$1 ]; then
	for i in {1..10}; do
	    umount ${SYSMNT}/aufs-$1 && rmdir ${SYSMNT}/aufs-$1 && break || sleep $i
	done #2>/dev/null
    fi
    if [ "$(grep changes-$1 /proc/mounts)" ]; then
	for i in {1..10}; do
    	    umount -d ${SYSMNT}/changes-$1 && rm -rdf ${SYSMNT}/changes-$1 && break || sleep $i
	done
    else
        rm -rdf ${SYSMNT}/changes-$1
    fi #2>/dev/null
    if [ -d ${SYSMNT}/bundles-$1 ]; then
	for i in {1..10}; do
	    ls -1A ${SYSMNT}/bundles-$1 | while read D; do
        	umount -d ${SYSMNT}/bundles-$1/"$D" && rmdir ${SYSMNT}/bundles-$1/"$D"
    	    done
	    rmdir ${SYSMNT}/bundles-$1 && break || sleep $i
	done
    fi #2>/dev/null
    if [ "$(grep tmpfs-$1 /proc/mounts)" ]; then
	for i in {1..5}; do
    	    umount ${SYSMNT}/tmpfs-$1 && rmdir ${SYSMNT}/tmpfs-$1 && break || sleep $i
	done
    else
        rm -rdf  ${SYSMNT}/tmpfs-$1
    fi #2>/dev/null
    ls -1 ${SYSMNT} | grep -E "aufs-${1}$|changes-${1}$|bundles-${1}$" && delete_aufs_error="error"
    [[ -z ${delete_aufs_error} ]] && rm -f ${SYSMNT}/aufs-${1}.lock
    [[ -n ${delete_aufs_error} ]] && return 2
    return 0
}

# Смонтировать слой в AUFS
add_layer() {
# Add new aufs layer, $1 - aufs container name, $2 - layer source
    AUFSMNT=${SYSMNT}/aufs-$1
    NEWLAYER=$(realpath "$2") || return 1
    [[ -e "$NEWLAYER"  ]] || return 2
    grep -q aufs-$1 /proc/mounts || return 3
    MODNAME="$(basename "$NEWLAYER" | sed -e 's/,/_comma_/g' -e 's/=/_equal_/g' -e 's/\*/_asterisk_/g' -e 's/\#/_hash_/g')"
# Если подключаемый слой смонтированная AUFS, то копируем её в tmpfs
#   if df --output=fstype $NEWLAYER | grep -q ^aufs$; then
    if [ "$(cat /proc/mounts | grep -E '^'`df "$NEWLAYER" | tail -1 | cut -f1 -d " "`' ' | cut -f3 -d " " | uniq)" = aufs ]; then
        grep -q ${SYSMNT}/tmpfs-$1 /proc/mounts || ( mkdir ${SYSMNT}/tmpfs-$1 && mount -t tmpfs tmpfs ${SYSMNT}/tmpfs-$1 )
        cp -auPR "$NEWLAYER" "${SYSMNT}/tmpfs-$1/"
        NEWLAYER="${SYSMNT}/tmpfs-$1/$(basename "$NEWLAYER")"
    fi
    if [[ "${NEWLAYER##*/}" == "rootcopy" ]]; then
	rsync -arq ${NEWLAYER}/* ${AUFSMNT}/
	msg "Info: copy ${NEWLAYER}/ to AUFS ${AUFSMNT}/" 0
    else
	case $(file -b "$NEWLAYER") in
    	    *directory)
        	mkdir -p "${SYSMNT}/bundles-$1/$MODNAME"
        	mount --bind "$NEWLAYER" "/${SYSMNT}/bundles-$1/$MODNAME" &>/dev/null
        	NEWLAYER="${SYSMNT}/bundles-$1/$MODNAME"
    	    ;;
    	    Squashfs*4.*|Linux*ext*)
        	mkdir -p "${SYSMNT}/bundles-$1/$MODNAME"
        	mount -o loop "$NEWLAYER" "/${SYSMNT}/bundles-$1/$MODNAME" &>/dev/null
        	NEWLAYER="${SYSMNT}/bundles-$1/$MODNAME"
    	    ;;
	    *) return 4 ;;
        esac
	mount -o remount,add=1:"$NEWLAYER"=ro+wh "$AUFSMNT" &>/dev/null || return 5
	msg "Info: mount ${MODNAME} to ${NEWLAYER} add to AUFS ${AUFSMNT}" 0
    fi
}

# Собрать модуль
# Make module
mksqmod(){
    excludes=""
    [ -f /tmp/mkubm_excludes ] && excludes="-ef /tmp/mkubm_excludes"
    eval mksquashfs "${1}" "${2}" "${compression}" "${excludes}" -noappend "${noprogress}" "${useproc}" -wildcards "${wh}" $devnull
    exitmsg "Error create squashfs module!" $? $3
#    mksquashfs "$@" -noappend "${excludes}"
    rm /tmp/mkubm_excludes 2>/dev/null
    return 0
}

#
ubmramfree() {
#rm unmounted modules and empty dirs from $copyramdir
if [ "$1" ]; then
    [ -f "$1" ] && fsname="`basename $(realpath "$1")`" || fsname="$(basename "$1")"
    fullname=$(echo "${copyramdir}/${fsname}" |sed 's://:/:')
    [ -f "$fullname" ] &&  rm -f "$fullname" || return 1
else
    if [ -d "${copyramdir}" ]; then
	find "${copyramdir}" -mindepth 1 -type f 2>/dev/null | while read ramubm ; do
	    losetupb -a | grep -q "${ramubm}" || rm -f "$ramubm"
	done
	find "${copyramdir}" -mindepth 1 -type d -empty 2>/dev/null | while read empdir ; do
	    rmdir --parents $empdir 2>/dev/null
	done
    fi
fi
}

# Обновить основные кеши системы

# Показать модули, которые заблокированны от отключения открытыми файлами
lsblocked() {
    LSOF=$(lsof -w | awk '{print $9}' |grep "/..*" | grep -Ev "/proc|/sys|/run|/tmp|/dev|/home" | sort -u)
    for a in $LSOF; do
	[ -f $a ] || continue
	[ -f $changesDir/$a ] && continue
	blockFiles="$blockFiles\n$a"
    done
    for bundle in $(aufs-n --raw '$bundle') ; do
	if [[ -n $(echo -e "${blockFiles}\n$(find $bundle | sed "s:$bundle::")" |sort |uniq -d) ]] ; then 		#"
	    echo "$bundle"
	fi
    done
}

#ubm_update_caches() {
#    [ "$(find "$1"{,/usr{,/local,/X11R6}}/lib -type f -name "*.so" 2>/dev/null)" ] && ldconfig #&
#    [ -d "$1/usr/share/mime/" ] && update-mime-database /usr/share/mime &
#    [ -d "$1/usr/lib/gdk-pixbuf-2.0/" ]  && gdk-pixbuf-query-loaders --update-cache &
#    [ -d "$1/usr/share/icons/hicolor/" ] && gtk-update-icon-cache -f -i -q /usr/share/icons/hicolor &
#    [ -d "$1/usr/share/glib-2.0/schemas/" ]  && glib-compile-schemas /usr/share/glib-2.0/schemas/ &
#    if [ -d "$1/usr/share/applications/" -o -d "$1/usr/local/share/applications/" ] ; then
#	update-desktop-database -q &
#	touch /usr/share/applications/screensavers &
#    fi
#    for font_dir in /usr/share/fonts{,/default}/TTF  /usr/X11R6/lib/X11/fonts/TTF ; do
#	if [ -d "$1/${font_dir}" ]; then
#	    fcneed=on
#	    mkfontscale ${font_dir}
#	    mkfontdir ${font_dir} &
#	fi
#    done
#    [ $fcneed ] && fc-cache -f -s &
#}

# Upgrade caches, icons, menus, etc after load/unload/upgrade modules
# Доделать по хукам /usr/share/libalpm/
ubm_update_caches() {
    if [[ -n $@ ]]; then
	for ITEM_MODULES in $@; do
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/modules/*.*.*-* >/dev/null && UPG_DEPMOD=1
	    find /memory/bundles/${ITEM_MODULES##*/}*/{,/usr{,/local,/X11R6}}/lib -type f -name "*.so" &>/dev/null 2>&1 && UPG_LDCONFIG=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/systemd/system >/dev/null && UPG_SYSD_DRS=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/systemd/user >/dev/null && UPG_SYSD_DRU=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/binfmt.d/*.conf >/dev/null && UPG_SYSD_BF=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/systemd/catalog >/dev/null && UPG_SYSD_CAT=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/udev/hwdb.d >/dev/null && UPG_SYSD_HWDB=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/sysctl.d/*.conf >/dev/null && UPG_SYSD_SYSCTL=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/udev/rules.d >/dev/null && UPG_SYSD_RULESD=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr >/dev/null && UPG_SYSD_USR=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/etc/dbus-1/system.d/*.conf >/dev/null && UPG_SYSD_DBUS=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/dbus-1/system.d/*.conf >/dev/null && UPG_SYSD_DBUS=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/dbus-1/system-services/*.service >/dev/null && UPG_SYSD_DBUS=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/polkit-1 >/dev/null && UPG_POLKIT=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/perl5 >/dev/null && UPG_PERL=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/bin/mktexlsr >/dev/null && UPG_TEXLIVE=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/etc/texmf >/dev/null && UPG_TEXLIVE=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/texmf >/dev/null && UPG_TEXLIVE=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/texmf-dist >/dev/null && UPG_TEXLIVE=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/var/lib/texmf >/dev/null && UPG_TEXLIVE=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/gdk-pixbuf-2.0 >/dev/null && UPG_PIXBUF=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/glib-2.0/schemas >/dev/null && UPG_GLIB=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/mime/packages/*.xml >/dev/null && UPG_MIME=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/gtk-2.0/2.10.0/immodules/*.so >/dev/null && UPG_GTK_IMM2=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib/gtk-3.0/3.0.0/immodules/*.so >/dev/null && UPG_GTK_IMM3=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/lib32/gtk-3.0/3.0.0/immodules/*.so >/dev/null && UPG_GTK_IMM3_32=1
	    UPG_ICONS+=$(find /memory/bundles/${ITEM_MODULES##*/}*/usr/share/icons/* -maxdepth 0 -type d 2>/dev/null | sed "s|^/memory/bundles/[^/]*/|/| ; s|$|/|")
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/applications >/dev/null && UPG_APPLICATION=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/local/share/applications >/dev/null && UPG_APPLICATION=1
	    compgen -G /memory/bundles/${ITEM_MODULES##*/}*/usr/share/ca-certificates/trust-source >/dev/null && UPG_CA_CERT=1
	    UPG_DCONF+=$(find /memory/bundles/${ITEM_MODULES##*/}*/etc/dconf/db/* -maxdepth 0 -type d -name "*.d" 2>/dev/null | sed "s|^/memory/bundles/[^/]*/|/| ; s|$|/|")
	    UPG_FONTS+=$(find /memory/bundles/${ITEM_MODULES##*/}*/usr/share/fonts/* -maxdepth 0 -type d 2>/dev/null | sed "s|^/memory/bundles/[^/]*/|/| ; s|$|/|")
	done
    else
        UPG_DEPMOD=1
        UPG_LDCONFIG=1
        UPG_SYSD_DRS=1
        UPG_SYSD_DRU=1
        UPG_SYSD_BF=1
        UPG_SYSD_CAT=1
        UPG_SYSD_HWDB=1
        UPG_SYSD_SYSCTL=1
        UPG_SYSD_RULESD=1
        UPG_SYSD_USR=1
        UPG_SYSD_DBUS=1
        UPG_SYSD_DBUS=1
        UPG_SYSD_DBUS=1
        UPG_POLKIT=1
        UPG_PERL=1
        UPG_TEXLIVE=1
        UPG_TEXLIVE=1
        UPG_TEXLIVE=1
        UPG_TEXLIVE=1
        UPG_TEXLIVE=1
        UPG_PIXBUF=1
        UPG_GLIB=1
        UPG_MIME=1
        UPG_GTK_IMM2=1
        UPG_GTK_IMM3=1
        UPG_GTK_IMM3_32=1
        UPG_ICONS+=$(find /usr/share/icons/* -maxdepth 0 -type d 2>/dev/null)
        UPG_APPLICATION=1
        UPG_APPLICATION=1
        UPG_CA_CERT=1
        UPG_DCONF+=$(find /etc/dconf/db/* -maxdepth 0 -type d -name "*.d" 2>/dev/null)
        UPG_FONTS+=$(find /usr/share/fonts/* -maxdepth 0 -type d 2>/dev/null)

    fi
    [[ -n ${UPG_DEPMOD} ]] && depmod -a
    [[ -n ${UPG_LDCONFIG} ]] && ldconfig 2>/dev/null
    /usr/share/libalpm/scripts/ublinux-sysusers
    /usr/share/libalpm/scripts/ublinux-tmpfiles
    /usr/share/libalpm/scripts/systemd-hook sysusers
    /usr/share/libalpm/scripts/systemd-hook tmpfiles
    /usr/bin/systemctl --quiet try-restart atd.service &>/dev/null
    /usr/bin/systemctl --quiet try-restart cronie.service &>/dev/null
    [[ -n ${UPG_SYSD_DRS} ]] && /usr/bin/systemctl daemon-reexec
    [[ -n ${UPG_SYSD_DRS} ]] && /usr/share/libalpm/scripts/systemd-hook daemon-reload-system
    [[ -n ${UPG_SYSD_DRU} ]] && /usr/share/libalpm/scripts/systemd-hook daemon-reload-user
    [[ -n ${UPG_SYSD_BF} ]] && /usr/share/libalpm/scripts/systemd-hook binfmt
    [[ -n ${UPG_SYSD_CAT} ]] && /usr/share/libalpm/scripts/systemd-hook catalog
    [[ -n ${UPG_SYSD_HWDB} ]] && /usr/share/libalpm/scripts/systemd-hook hwdb
    [[ -n ${UPG_SYSD_SYSCTL} ]] && /usr/share/libalpm/scripts/systemd-hook sysctl
    [[ -n ${UPG_SYSD_RULESD} ]] && /usr/share/libalpm/scripts/systemd-hook udev-reload
    [[ -n ${UPG_SYSD_USR} ]] && /usr/share/libalpm/scripts/systemd-hook update
    [[ -n ${UPG_SYSD_DBUS} ]] && /usr/share/libalpm/scripts/systemd-hook reload dbus
    [[ -n ${UPG_POLKIT} ]] && /usr/bin/systemctl --quiet try-restart polkit.service &>/dev/null
    [[ -n ${UPG_PERL} ]] && /usr/share/libalpm/scripts/detect-old-perl-modules.sh 2>/dev/null
    [[ -n ${UPG_TEXLIVE} ]] && /usr/share/libalpm/scripts/mktexlsr 2>/dev/null
    [[ -n ${UPG_PIXBUF} ]] && /usr/bin/gdk-pixbuf-query-loaders-32 --update-cache 2>/dev/null
    [[ -n ${UPG_PIXBUF} ]] && /usr/bin/gdk-pixbuf-query-loaders --update-cache 2>/dev/null
    [[ -n ${UPG_GLIB} ]] && /usr/bin/glib-compile-schemas /usr/share/glib-2.0/schemas 2>/dev/null
    [[ -n ${UPG_GTK_IMM2} ]] && /usr/bin/gtk-query-immodules-2.0 --update-cache 2>/dev/null
    [[ -n ${UPG_GTK_IMM3} ]] && /usr/bin/gtk-query-immodules-3.0 --update-cache 2>/dev/null
    [[ -n ${UPG_GTK_IMM3_32} ]] && /usr/bin/gtk-query-immodules-3.0-32 --update-cache 2>/dev/null
    [[ -n ${UPG_MIME} ]] && /usr/bin/env PKGSYSTEM_ENABLE_FSYNC=0 /usr/bin/update-mime-database /usr/share/mime
    [[ -n ${UPG_ICONS} ]] && /usr/bin/gtk-update-icon-cache -fiq /usr/share/icons/hicolor/ 2>/dev/null
    [[ -n ${UPG_ICONS} ]] && /usr/share/libalpm/scripts/gtk-update-icon-cache <<< "${UPG_ICONS}" 2>/dev/null
    [[ -n ${UPG_APPLICATION} ]] && /usr/bin/update-desktop-database --quiet 2>/dev/null && touch /usr/share/applications
    [[ -n ${UPG_CA_CERT} ]] && /usr/bin/update-ca-trust
    [[ -n ${UPG_DCONF} ]] && /usr/share/libalpm/scripts/dconf-update <<< "${UPG_DCONF}" 2>/dev/null
    [[ -n ${UPG_FONTS} ]] && /usr/share/libalpm/scripts/xorg-mkfontscale <<< "${UPG_FONTS}" 2>/dev/null 
    [[ -n ${UPG_FONTS} ]] && /usr/bin/fc-cache-32 -fr 2>/dev/null
    [[ -n ${UPG_FONTS} ]] && /usr/bin/fc-cache -fr 2>/dev/null

    # Finish writing any outstanding writes to disk.
    sync
    # Drop all filesystem caches to free up more memory.
    echo 3 > /proc/sys/vm/drop_caches
    # Do another run of writing any possible new outstanding writes.
    sync
    # Tell the kernel to "defragment" memory where possible.
    echo 1 > /proc/sys/vm/compact_memory
}

###################
###	Main	###
###################
    COL
    for arg in $@; do
	case "${arg}" in
	    "-h" | "--help") [ "`basename $0`" = "ubm" ] && HELP_UBM && exit 0
	    ;;
	esac
    done

    EXT="ubm"
    UBMDIR=/var/lib/ubmodules
    copyramdir="/tmp/.mountRAM"
    prefixmp="/mnt/."
    changesDir="/mnt/live/memory/changes/"

    aufsroot="$(`which busybox 2>/dev/null` mount | grep -E ' on / type aufs ')"
    [[ "$aufsroot" ]] && SYSMNT=/$(cut -f2 -d/ /sys/fs/aufs/si_$(grep ' / aufs' /proc/mounts | cut -f2 -d= | tr ',' ' ' | cut -f1 -d' ')/br0)
    if [ -f /etc/initvars ] ; then
        . /etc/initvars
        copyramdir=${SYSMNT}/copy2ram/
        prefixmp=${SYSMNT}/bundles/
        changesDir=${SYSMNT}/changes/
    fi
    wh="-e '... /.wh.*'"
#    compression="-b 512K -comp xz"
    compression="-b 32K -comp gzip"
    compression_fast="-comp lz4"
    if echo $compression |grep -q xz; then
        uname -m | grep -q -e "86" -e "32" -e "64" && compression="$compression -Xbcj x86" || compression="$compression -Xbcj x86,arm"
    fi

# user config file
    [ -f /etc/ublinux/ubm ] && . /etc/ublinux/ubm


    if [[ $(basename $0) == "ubm" ]]; then
	[[ -n $1 ]] || HELP_UBM
	command="$1"
	shift
	$command "$@" || msg "ERROR: excute $command " "$?"
    fi
