#!/bin/bash
SOURCE="$0"
source /usr/lib/elive-tools/functions
EL_REPORTS="1"


# NOTE: this was originally an initd (sysvinit) script, to support systemd I moved it to the sbin directly and called from sysvinit, or, in case of systemd, will be run by a service and removed the sysvinit at boot time from live-config-systemd

# Defaults
#PIDDIR=/var/run/drivers-install
#drivers-installPID=$PIDDIR/drivers-install.pid
DESC="Configure Drivers"
SCRIPTNAME=/etc/init.d/drivers-install

# enable translations
# wrapper for fix strange languages
locales_source(){
    if [[ -s "/etc/default/locale" ]] ; then
        source /etc/default/locale
    fi
    # wrapper for fix strange languages
    case "$LANG" in
        am*|ar*|bg*|bn*|el*|fa*|gu*|he*|hy*|hi*|iw*|ja*|ka*|kn*|ko*|ml*|mr*|ne*|pa*|ru*|sr*|ta*|te*|th*|uk*|vi*|zh*)
            export LC_ALL=en_US.UTF-8
            export LANG=en_US.UTF-8
    esac
}
locales_source

# gettext functions
if [[ -x "/usr/bin/gettext.sh" ]] ; then
    . gettext.sh
else
    # make it compatible
    eval_gettext(){
        echo "$@"
    }
fi
TEXTDOMAIN="deliver"
export TEXTDOMAIN

_CMDLINE="$(cat /proc/cmdline)"
for arg in $_CMDLINE
do
    [[ "$arg" = "persistence" ]] && is_persistence=1
    [[ "$arg" = "thanatests" ]] && is_thanatests=1
    [[ "$arg" = "boot=live" ]] && is_live=1
    [[ "$arg" = "debug" ]] && is_debug=1
done

if ((is_persistence)) ; then
    if [[ -s "/etc/default/persistence-elive.sh" ]] ; then
        is_persistence_booted=1

        source "/etc/default/persistence-elive.sh"
        if [[ -n "$counter_times_persistence_booted" ]] && [[ "${counter_times_persistence_booted}" -ge "1" ]] ; then
            is_persistence_booted_already=1
        fi
    else
        unset is_persistence
    fi
fi

LIVE_MOUNT_MAIN_d="/run/live"
# determine the mount version
case "$( cat /etc/debian_version )" in
    12.*|"bookworm"*)  # unused
        is_bookworm=1
        ;;
    11.*|"bullseye"*)  # unused
        is_bullseye=1
        ;;
    10.*|"buster"*)    # unused
        is_buster=1
        ;;
    7.*|"wheezy"*)
        is_wheezy=1
        LIVE_MOUNT_MAIN_d="/lib/live/mount"
        ;;
    *)
        el_error "debian version unknown: $(cat /etc/debian_version)"
        ;;
esac

# extra needed vars
RAM_TOTAL_mb="$( el_ram_usage_show total )"


# Reads config file (will override defaults above)
[ -r /etc/default/drivers-install ] && . /etc/default/drivers-install

. /lib/lsb/init-functions

################################################################
pre_optimizations(){
    # remove mandb: it makes apt much slower without reason
    if ! ((is_persistence)) ; then
        # disable mandb
        rm -f /usr/bin/mandb
        ln -s /bin/true /usr/bin/mandb

        cat > "/etc/dpkg/dpkg.cfg.d/01_nodoc" << EOF
path-exclude /usr/share/doc/*
path-exclude /usr/share/man/*
path-exclude /usr/share/groff/*
path-exclude /usr/share/info/*
# lintian stuff is small, but really unnecessary
path-exclude /usr/share/lintian/*
path-exclude /usr/share/linda/*
EOF

    fi
}

splash(){
    case "$1" in
        hide)
            if ((is_wheezy)) ; then
                plymouth --ping 1>/dev/null 2>&1  && plymouth --hide-splash && chvt 1 && chvt 7
            else
                if ((is_bullseye)) ; then
                    plymouth --ping 1>/dev/null 2>&1  && plymouth quit && chvt 1
                else
                    # in bookworm it works back
                    plymouth --ping 1>/dev/null 2>&1  && plymouth --hide-splash && chvt 1
                fi
            fi
            ;;
        show)
            # show back plymouth
            plymouth --ping 1>/dev/null 2>&1  && plymouth show-splash 1>/dev/null 2>&1
            ;;
    esac
}

################################################################
wait_for_internet(){
    ((is_connected)) && return

    local count count_max
    count=1
    if grep -qsE "type=(wifi|.*wireless)" /etc/NetworkManager/system-connections/* 2>/dev/null  ; then
        count_max=30
    else
        count_max=10
    fi

    while true ; do
        log_progress_msg "checking for internet connection... (${count}/${count_max})"
        if timeout 2 ping -c 1 "8.8.8.8"  2>/dev/null 1>&2 ; then
            is_connected=1
            echo
            log_progress_msg "internet available"
            break
        fi

        sleep 1

        count="$(( $count + 1 ))"
        if [[ "$count" -gt "$count_max" ]] ; then
            break
        fi
    done
}

#wait_for_dbus(){
    #if [[ -x "$( which dbus-daemon )" ]] && ! ((is_wheezy)) ; then
        ##echo -e "I: waiting for dbus to be ready" 1>2
        #log_progress_msg "waiting for DBUS connection"
        ##while ! sudo -H -n service dbus status | colors-remove | grep -Fqs "running"
        #while ! pidof dbus-daemon 1>/dev/null 2>&1
        #do
            #LC_ALL=C sleep 0.2
        #done
    #fi
#}

################################################################
check_virtual_machine(){
    # detect virtualmachine
    case "$( dmidecode -s system-product-name )" in
        *"VirtualBox"*)
            MACHINE_VIRTUAL="yes"
            MACHINE_VIRTUAL_TYPE="virtualbox"
            ;;
        *"VMware"*)
            MACHINE_VIRTUAL="yes"
            MACHINE_VIRTUAL_TYPE="vmware"
            ;;
        *"OpenStack Nova"*)
            MACHINE_VIRTUAL="yes"
            MACHINE_VIRTUAL_TYPE="openstacknova"
            ;;
        *"Parallels Virtual"*)
            MACHINE_VIRTUAL="yes"
            MACHINE_VIRTUAL_TYPE="parallels"
            ;;
        "Bochs")
            # qemu
            if grep -Fqs "QEMU" /proc/cpuinfo ; then
                MACHINE_VIRTUAL="yes"
                MACHINE_VIRTUAL_TYPE="qemu"
            fi
            ;;
    esac

    # other virtual machines:
    if [[ -z "$MACHINE_VIRTUAL" ]] ; then
        case "$( dmidecode -s system-manufacturer )" in
            "QEMU")
                # Red hat virtual machine type
                # Product Name: Standard PC (i440FX + PIIX, 1996)
                # 00:02.0 VGA compatible controller: Red Hat, Inc. QXL paravirtual graphic card (rev 04)
                MACHINE_VIRTUAL="yes"
                MACHINE_VIRTUAL_TYPE="qemu"
                ;;
            "Microsoft"*)
                MACHINE_VIRTUAL="yes"
                MACHINE_VIRTUAL_TYPE="other"
                ;;
        esac
    fi

    if [[ -z "$MACHINE_VIRTUAL" ]] ; then
        if dmidecode | grep -qsE "(Family|Product Name): Virtual Machine" \
            || grep -Fqs "hypervisor" /proc/cpuinfo ; then

            MACHINE_VIRTUAL="yes"
            MACHINE_VIRTUAL_TYPE="other"
            report_unknown_machine
        fi
    fi


    # save confs
    if ! [[ -e "/etc/elive/machine-profile" ]] ; then
        mkdir -p "/etc/elive"
        touch "/etc/elive/machine-profile"
        echo "# Configuration file with variables that can be sourced to get variables related to machine profiles and identifiers" >> /etc/elive/machine-profile
    fi


    if [[ "$MACHINE_VIRTUAL" = "yes" ]] ; then
        # save profile
        if ! grep -qs "^MACHINE_VIRTUAL=" /etc/elive/machine-profile ; then
            echo "MACHINE_VIRTUAL=\"$MACHINE_VIRTUAL\"" >> /etc/elive/machine-profile
        fi
        if ! grep -qs "^MACHINE_VIRTUAL_TYPE=" /etc/elive/machine-profile ; then
            echo "MACHINE_VIRTUAL_TYPE=\"$MACHINE_VIRTUAL_TYPE\"" >> /etc/elive/machine-profile
        fi

    else
        # normal-hardware checks
        if ! [[ "$( lspci 2>/dev/null | wc -l )" -ge 2 ]] ; then
            el_error "lspci wrong output:\n$(lspci 2>&1 )"
        fi

        if ! [[ "$( lsusb 2>/dev/null | wc -l )" -ge 1 ]] ; then
            el_error "lsusb wrong output:\n$(lsusb 2>&1 )"
        fi

        # disable virtualbox daemon because we don't need it, to free some memory
        if [[ "$RAM_TOTAL_mb" -lt 5000 ]] ; then
            systemctl mask     virtualbox.service  1>/dev/null 2>&1 || true
            systemctl disable  virtualbox.service  1>/dev/null 2>&1 || true
            systemctl stop     virtualbox.service  1>/dev/null 2>&1 || true
        fi
    fi


    # virtual machine special cases
    if [[ "$MACHINE_VIRTUAL" = "yes" ]] ; then
        # vbox:
        if [[ "$MACHINE_VIRTUAL_TYPE" = "virtualbox" ]] ; then
            # more than one cpu
            if [[ "$( grep "^processor" /proc/cpuinfo | wc -l )" -gt 1 ]] && ! ((is_thanatests)) ; then
                splash hide

                dialog --timeout 30 --clear --colors --title "Virtual Machine" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
                    --msgbox "$( eval_gettext "Warning: Using multiple CPUs in a virtual machine may cause instability. If you experience problems, try using only one CPU. Performance can vary depending on your virtual machine's settings and host computer.\n\nFor best results, consider enabling: APIC (for 2+ CPUs), PAE, KVM virtualization, VT, Nested Paging, and Host I/O Cache for disks and media." )" 0 0 2>/dev/null

                splash show
            fi

        fi

        # tell about possible crash
        # if ((is_bookworm)) ; then
        #     splash hide
        #
        #     dialog --timeout 30 --clear --colors --title "Virtual Machine" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
        #         --msgbox "$( eval_gettext "Warning: You are using a Virtual Machine. We have seen issues where the graphical system restarts, especially when opening the Thunar file manager. If you encounter this issue, try running Elive on real hardware." )" 0 0 2>/dev/null
        #
        #     splash show
        # fi
    fi
}
################################################################
mount_nopersistence_saved_configurations(){
    # XXX important: this function has a same one in /etc/init.d/persistence-elive so both they should be updated similar
    mountpoint_medium="$LIVE_MOUNT_MAIN_d/medium"
    # XXX: this file is only used when USB (img) mode, otherwise we fallback to the EFI partition for this
    persistent_image_confs="$mountpoint_medium/live/elive-live-saved-configurations.img"

    mountpoint_changes="/mnt/persistent_image_confs"
    mountpoint_changes_commit="$mountpoint_changes/persistent"


    # USB mode (.img, not hybrid)
    if LC_ALL=C grep -qs "^/dev/.*$mountpoint_medium vfat " /proc/mounts \
        && [[ -e "$persistent_image_confs" ]] ; then
            #el_debug "Elive running in USB mode (img)"
            mkdir -p "$mountpoint_changes"

            # remount usb partition in RW
            mount -o remount -o rw "$mountpoint_medium"
            # mount persistence image
            mount -o rw "$persistent_image_confs" "$mountpoint_changes"

    # hybrid image mode (iso9660 cdrom/dvd bootable)
    elif LC_ALL=C grep -qs "^/dev/.*$mountpoint_medium iso9660 " /proc/mounts ; then
        #el_debug "Elive running in Hybrid mode (iso)"
        mkdir -p "$mountpoint_changes"

        mountpoint_partition="$( LC_ALL=C grep "^/dev/.*$mountpoint_medium iso9660 " /proc/mounts | awk '{print $1}' | tail -1 )"
        mountpoint_partition="${mountpoint_partition%%[0-9]*}"
        if blkid -o export "${mountpoint_partition}1" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}1"
        elif blkid -o export "${mountpoint_partition}2" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}2"
        elif blkid -o export "${mountpoint_partition}3" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}3"
        elif blkid -o export "${mountpoint_partition}4" | grep -qsi "TYPE=vfat" ; then
            mountpoint_partition="${mountpoint_partition}4"
        fi

        if [[ -b "$mountpoint_partition" ]] ; then
            # this can fail if we are using a cdrom media instead of a USB, but it doesn't matter because we will check if we were able to mount it later
            mount -o rw "$mountpoint_partition" "$mountpoint_changes" 2>/dev/null || true
        fi
    fi
}
################################################################
persistence_soft_restore(){
    # only if we are not in a real persistence mode:
    if ((is_persistence_booted_already)) ; then
        log_progress_msg "Persistence mounted"
    else
        mount_nopersistence_saved_configurations

        if LC_ALL=C grep -qs " $mountpoint_changes " /proc/mounts ; then
            # copy back needed ones:
            cp -a "$mountpoint_changes_commit"/* /
            chmod 600 /etc/NetworkManager/system-connections/*nmconnection 1>/dev/null 2>&1 || true

            umount "$mountpoint_changes" || umount -f "$mountpoint_changes"
            rmdir "$mountpoint_changes"
        fi
    fi
}
################################################################
language_fix(){
    if [[ "$LANG" = bg* ]] || [[ "$LANG" = bn* ]] || [[ "$LANG" = el* ]] || [[ "$LANG" = hi* ]] || [[ "$LANG" = ja* ]] || [[ "$LANG" = ko* ]] || [[ "$LANG" = ru* ]] || [[ "$LANG" = sr* ]] || [[ "$LANG" = te* ]] || [[ "$LANG" = uk* ]] || [[ "$LANG" = vi* ]] || [[ "$LANG" = zh* ]] ; then
        export LANG="en_US.UTF-8"
    fi
}
################################################################
languagedetect(){
    local OnLine country country_lower language cache_location_f part label mountpoint eliveversion
    cache_location_f="/etc/elive-tools/geolocation/livemode-location-fetched.txt"

    # do not run it again in persistence, but only once to get the correct configurations
    if ((is_persistence_booted_already)) ; then
        if [[ -e "/var/lib/live/config/languagedetect" ]] ; then
            el_debug "$(basename $0) already ran (persistence booted more than one time), ignoring..."
            return
        else
            el_info "persitence already booted before but languages not yet preconfigured, trying again..."
        fi
    fi

    #log_daemon_msg "Language preconfigurations"

    # configure locales based on our cmdline parameters {{{
    # simulate/set a country
    if echo "$_CMDLINE" | LC_ALL=C grep -qE "(country|locales)=" ; then
        for _PARAMETER in ${_CMDLINE}
        do
            case "${_PARAMETER}" in
                country=*)
                    country="${_PARAMETER#*country=}"
                    read -r country <<< "$country"

                    if [[ "$country" = *"_"* ]] || [[ "$country" = *"-"* ]] ; then
                        country="$( echo "$country" | tr '[a-z]' '[A-Z]' | sed -e 's|^.*-||g' -e 's|^.*_||g' | tr ',' ' ' | awk '{print $1}' )"

                        language="${_PARAMETER#*country=}"
                        read -r language <<< "$language"
                        language="$( echo "$language" | tr '[A-Z]' '[a-z]' | sed -e 's|-.*$||g' -e 's|_.*$||g' )"
                    else
                        #country="$( echo "$country" | tr '[a-z]' '[A-Z]' | sed -e 's|-.*$||g' -e 's|_.*$||g' )"
                        country="$( echo "$country" | tr '[a-z]' '[A-Z]' | sed -e 's|^.*-||g' -e 's|^.*_||g' | tr ',' ' ' | awk '{print $1}' )"
                    fi
                    is_language_forced=1
                    ;;
                locales=*|locale=*)

                    # XXX Warning: do not use this parameter since its bugged (its from from live-* tools), like if you set "locales=ko_KR", you will have THAT locale instead of "ko_KR.UTF-8 UTF-8"

                    locales="${_PARAMETER#*locales=}"
                    read -r locales <<< "$locales"
                    if [[ -z "$locales" ]] ; then
                        locales="${_PARAMETER#*locale=}"
                        read -r locales <<< "$locales"
                    fi

                    # user didn't used xx_XX.UTF-8 mode, so hack:
                    if ! echo "$locales" | grep -qs "\." && echo "$locales" | grep -qs "[[:alpha:]]" ; then
                        country="$locales"

                        if [[ "$country" = *"_"* ]] || [[ "$country" = *"-"* ]] ; then
                            country="$( echo "$country" | tr '[a-z]' '[A-Z]' | sed -e 's|^.*-||g' -e 's|^.*_||g' | tr ',' ' ' | awk '{print $1}' )"

                            language="${_PARAMETER#*locales=}"
                            read -r language <<< "$language"
                            if [[ -z "$language" ]] ; then
                                language="${_PARAMETER#*locale=}"
                                read -r language <<< "$language"
                            fi
                            language="$( echo "$language" | tr '[A-Z]' '[a-z]' | sed -e 's|-.*$||g' -e 's|_.*$||g' )"
                        else
                            #country="$( echo "$country" | tr '[a-z]' '[A-Z]' | sed -e 's|-.*$||g' -e 's|_.*$||g' )"
                            country="$( echo "$country" | tr '[a-z]' '[A-Z]' | sed -e 's|^.*-||g' -e 's|^.*_||g' | tr ',' ' ' | awk '{print $1}' )"
                        fi
                    fi
                    is_language_forced=1
                    ;;
            esac
        done
    fi

    # }}}
    # wifi unblock {{{
    # do we have rfkill blocked by default? unblock it!
    if laptop-detect ; then
        if ! el_dependencies_check "rfkill" 2>/dev/null ; then
            el_warning "Dependencies missing: rfkill"
        fi

        while read -ru 3 line
        do
            # know the possible id to unblock
            if echo "$line" | LC_ALL=C grep -qsE "^[[:digit:]]+:.*Wireless " ; then
                id="$( echo "$line" | sed -e 's|: .*$||g' )"
                #el_debug "ID is $id"
            fi

            # unblock Soft if we are blocked
            if echo "$line" | LC_ALL=C grep -qsi "Soft blocked: yes" ; then
                rfkill unblock "$id" 2>/dev/null 1>&2

                # we can have multiple devices so this result is not very reliable, don't use it as an important result:
                if rfkill list 2>/dev/null | grep -qsi "Soft blocked: no" ; then
                    is_unblocked=1
                fi
            fi

            # unblock Hard if we are blocked
            if echo "$line" | LC_ALL=C grep -qsi "Hard blocked: yes" ; then
                # try to unblock but it may not work
                rfkill unblock "$id" 2>/dev/null 1>&2

                if rfkill list 2>/dev/null | grep -qsi "Hard blocked: yes" ; then
                    #log_progress_msg "Wifi is blocked by hardware"
                    NOREPORTS=1 el_warning "$( eval_gettext "Wi-Fi is deactivated. Please enable it using the hardware switch or keyboard hotkey." )"
                fi
            fi
        done 3<<< "$( rfkill list 2>/dev/null )"

        # wait to have it initialized if was reactivated
        if ((is_unblocked)) && ! ((is_language_forced)) ; then
            log_progress_msg "Activating Wi-Fi..."
            sleep 2
            #log_progress_msg "Wifi reactivated"
        fi
    fi


    # - wifi unblock }}}
    # reciclate confs {{{
    #
    if el_check_dir_has_files /etc/NetworkManager/system-connections/ 1>/dev/null 2>&1 ; then
        systemctl restart NetworkManager.service
        wait_for_internet
    fi

    if ! ((is_connected)) ; then
        log_progress_msg "Searching configurations..."
        count=0
        while read -ru 3 line
        do
            unset part label mountpoint eliveversion filesystem
            part="$( echo "$line" | awk -v FS="::"  '{print $1}' )"
            label="$( echo "$line" | awk -v FS="::"  '{print $4}' )"
            filesystem="$( echo "$line" | awk -v FS="::"  '{print $3}' )"

            # ignore disks and specially the usb of elive like sdb itself
            if echo "$filesystem" | grep -qsE "(ntfs|iso9660|udf)" ; then
                continue
            fi

            if [[ -b "$part" ]] ; then

                if echo "$label" | grep -qsiE "(Elive_OS|Elive_boot|Absolute|Alt-edu|Bunsen|archbang|buster|debian|chakra|crunchbang|deepin|devuan|element|buntu|fedora|hat|ferenos|gentoo|kali|mint|mageia|makulu|manjaro|mx1|mx2|suse|parrot|pepper|raspbian|sabayon|salix|puppy|siduction|sparky|zorin)" ; then

                    # set a max partitions to scan, we don't want to bottleneck
                    count="$(( $count + 1 ))"
                    log_progress_msg "Searching configurations ($count)"
                    if [[ "${count}" -ge "7" ]] ; then
                        log_progress_msg "Maximum number of attempts reached, continuing..."
                        break
                    fi

                    NOREPORTS=1 timeout 180 mounts-manager --mount "$part" 1>/dev/null
                    mountpoint="$( NOREPORTS=1 timeout 120 mounts-manager --get-mountpoint "$part" 2>/dev/null )"

                    if [[ -d "$mountpoint" ]] ; then
                        #eliveversion="$( cat "$mountpoint/etc/elive-version" | grep "^elive-version: " | sed -e 's|^elive-version: ||g' | tail -1 )"

                        #if [[ -n "$eliveversion" ]] ; then
                            #if LC_ALL="$EL_LC_EN" dpkg --compare-versions "$eliveversion" "ge" "3.0.0" && LC_ALL="$EL_LC_EN" dpkg --compare-versions "$eliveversion" "lt" "4.0.0" ; then
                                # only copy these ones since are the new confs:
                                mkdir -p /tmp/system-connections
                                cp -af "$mountpoint/etc/NetworkManager/system-connections/"*nmconnection  /tmp/system-connections/ 2>/dev/null || true

                                # remember reports
                                if [[ -s "$mountpoint/etc/elive/settings" ]] ; then
                                    source "$mountpoint/etc/elive/settings"
                                    if [[ "$conf_send_debug_reports" = "yes" ]] ; then
                                        if [[ -n "$conf_send_debug_reports_email" ]] ; then
                                            mkdir -p "/etc/elive"
                                            # sed -i "/^conf_send_debug_reports/d" "/etc/elive/settings" 2>/dev/null || true
                                            # echo -e "conf_send_debug_reports=\"$conf_send_debug_reports\"" >> "/etc/elive/settings"
                                            # echo -e "conf_send_debug_reports_email=\"$conf_send_debug_reports_email\"" >> "/etc/elive/settings"
                                            cp "$mountpoint/etc/elive/settings" "/etc/elive/settings"
                                        fi
                                    fi
                                fi

                                for file in "$mountpoint/etc/NetworkManager/system-connections/"*
                                do
                                    [[ -s "$file" ]] || continue

                                    if grep -qsE "type=(wifi|.*wireless|ethernet)" "$file" ; then
                                        if ! echo "$file" | grep -qsE "[[:digit:]]$" ; then
                                            cp -af "$file" /tmp/system-connections/ 2>/dev/null
                                        fi
                                    fi
                                done
                                # fix permissions
                                chmod 600 /tmp/system-connections/* 1>/dev/null 2>&1 || true
                            #fi
                        #fi
                    fi

                    if mounts-manager --check-is-mounted "$part" 1>/dev/null 2>&1 ; then
                        ( umount "$part" 2>/dev/null || umount -f "$part" 2>/dev/null ) &
                    fi
                fi

            fi
        done 3<<< "$( NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-all )"

        # ask user if wants to re-use internet configurations
        if el_check_dir_has_files /tmp/system-connections/ 1>/dev/null 2>&1 ; then

            title="$( eval_gettext "Elive Galactic Magic" )"
            message="$( eval_gettext "Would you like to reuse the internet configurations found on your computer?" )"

            if ((is_thanatests)) ; then
                ret=0
            else
                splash hide

                dialog --timeout 20 --clear --colors --backtitle "Elive Systems: Use Ctrl-L to redraw, TAB to select, Enter to confirm" \
                    --title "$title" \
                    --yesno "$message" \
                    7 50
                ret="$?"

                splash show
            fi


            case "$ret" in
                0|255|123) # yes, timeout, cancel
                    log_progress_msg "Reusing internet configurations"

                    # allow network to be used for any user by default, this solves a small issue where after install there was no network
                    sed -i -e '/^permissions=/d' "/tmp/system-connections/"*  2>/dev/null || true
                    # allow all interfaces (wifi device names can change)
                    sed -i -e '/^interface-name=/d' "/tmp/system-connections/"*  2>/dev/null || true
                    # move them in order to be used
                    mv -f /tmp/system-connections/* /etc/NetworkManager/system-connections/

                    # restart nm
                    systemctl restart NetworkManager.service
                    log_progress_msg "Reactivating network configuration"

                    if grep -qsE "type=(wifi|.*wireless)" /etc/NetworkManager/system-connections/* ; then
                        sleep 2
                    fi

                    ;;
                1) # no
                    log_progress_msg "Not reusing internet configurations"
                    true
                    ;;
            esac
        else
            log_progress_msg ""
        fi
    fi

    # - reciclate confs }}}
    # skip if thanatests (and we didn't forced the country)
    if ((is_thanatests)) ; then
        el_info "ignoring languagedetect because of development tests"
        return
    fi

    # geolocation: know our country {{{
    # fetch and cache our location if we have not yet saved
    if ! ((is_language_forced)) ; then
        if [[ ! -s "$cache_location_f" ]] && [[ -z "$country" ]]  ; then

            # wait some time only if we have wifi connections, otherwise just proceed fast
            if el_check_dir_has_files /etc/NetworkManager/system-connections/ 1>/dev/null 2>&1  ; then

                wait_for_internet

                if ! ((is_connected)) ; then
                    echo
                    log_progress_msg "Internet connection not available"
                    log_end_msg 1
                    return
                fi
            fi

            #if ! el_verify_internet fast ; then
            #if ! el_verify_internet  ; then
                #log_progress_msg "Connection to internet not available"
                #return
            #fi

            mkdir -p "$( dirname "$cache_location_f" )"
            timeout 12 showmylocation 1>"$cache_location_f"  2>/dev/null
        fi
    fi

    # - geolocation: know our country }}}
    # configure a new country {{{
    if [[ -s "$cache_location_f" ]] || [[ -n "$country" ]] ; then

        # generate new of not found
        if ! [[ -s "/etc/locale.gen" ]] ; then
            if [[ -x "$( which locale-gen )" ]] ; then
                cat /usr/share/i18n/SUPPORTED | awk '{print "# "$0}' > /etc/locale.gen
                # enable english utf by default
                sed -i -e 's|# en_US.UTF-8 UTF-8|en_US.UTF-8 UTF-8|g' /etc/locale.gen
            else
                # exit in case we don't have locales installed, so not needed
                return
            fi
        fi

        # get country code
        if [[ -z "$country" ]] && [[ -s "$cache_location_f" ]] ; then
            country="$( cat "$cache_location_f" | awk -v FS="::" '{if ($1 == "country_code" ) print toupper($2) }' | tail -1 )"
            country_name="$( cat "$cache_location_f" | awk -v FS="::" '{if ($1 == "country_name" ) print $2 }' | tail -1 )"

            if [[ -z "$country" ]] ; then
                case "$country_name" in
                    USA|US|"United States")     country="US" ; ;;
                    Russia)                     country="RU" ; ;;
                esac
            fi
            # remove extra leading blank chars
            read -r country <<< "$country"
        fi

        if [[ -n "$country" ]] ; then
            # new code, simpler and more powerful (supports an entire country)
            #cat "/etc/locale.gen" | sed -e  "s|# \([[:alpha:]]*_${country}\.UTF-8 UTF-8\)|\1|g" > "/etc/locale.gen.detected"
            #cat "/etc/locale.gen" | sed -e "s|^# \([[:alpha:]]*_${country}\.[^@]* UTF-8$\)|\1|g" > "/etc/locale.gen.detected"
            if [[ -n "$language" ]] ; then
                cat "/etc/locale.gen" | sed -e "s|^# \([[:alpha:]]*${language}_${country}.* UTF-8$\)|\1|g" > "/etc/locale.gen.detected"
            else
                cat "/etc/locale.gen" | sed -e "s|^# \([[:alpha:]]*_${country}.* UTF-8$\)|\1|g" > "/etc/locale.gen.detected"
            fi

            # check if we have enough memory for other processes
            if [[ "$RAM_TOTAL_mb" -gt 1300 ]]  || ((is_language_forced))  || [[ "$( LC_ALL=C free -m | awk '{if ($1 == "Swap:") print $4}' )" -gt 700 ]] ; then
                is_enough_memory=1
            else
                unset is_enough_memory
            fi

            # generate new languages if needed
            if [[ "$( diff -a "/etc/locale.gen.detected" "/etc/locale.gen" | wc -l )" -gt 2 ]] ; then
                sudo -H mv /etc/locale.gen.detected /etc/locale.gen
                echo

                # add needed locales for our first env startup
                # this basically adds all the extra languages of a detected country, so we can select it from the list
                if ((is_enough_memory)) && ! ((is_thanatests)) ; then
                    if [[ -n "$country_name" ]] ; then
                        log_progress_msg "Adding languages for $country_name"
                    else
                        log_progress_msg "Adding languages for $country"
                    fi
                    sudo -H locale-gen --keep-existing > /dev/null 2>&1
                else
                    log_progress_msg "Not adding extra language configurations for $country due to low RAM."
                fi
                    #sudo -H update-locale

            else
                rm -f /etc/locale.gen.detected 2>/dev/null || true
            fi


            # enable the default language conf so E can show it as default too
            country_lower="$( echo "$country" | tr '[A-Z]' '[a-z]' )"

            # get the default language of the country
            if [[ -z "$language" ]] ; then
                if LC_ALL=C grep -qs "_${country}.* UTF-8$" /usr/share/i18n/SUPPORTED ; then
                    if LC_ALL=C grep -q "^${country_lower}_${country}.* UTF-8$" /usr/share/i18n/SUPPORTED ; then
                        language="$country_lower"
                    else
                        if [[ "$( LC_ALL=C grep "_${country}.* UTF-8$" /usr/share/i18n/SUPPORTED | wc -l | cut -f 1 -d ' ' )" -eq 1 ]] ; then
                            language="$( LC_ALL=C grep "_${country}.* UTF-8$" /usr/share/i18n/SUPPORTED | sed -e 's|\..*$||g' -e 's|_.*$||g' | head -1 )"
                        fi
                    fi
                fi
            fi

            # reconfigure locales
            if [[ -n "$language" ]] && [[ -n "$country" ]] ; then
                # only if we have enough memory for this
                if ((is_enough_memory)) ; then

                    # export needed before to configure
                    LIVE_LOCALES="${language}_${country}"
                    export LIVE_LOCALES

                    # note: these are needed in order to update the default system's language, so E will show it as default
                    rm -f /var/lib/live/config/locales
                    source /lib/live/config/*-locales

                    # reconfigure console locale
                    locales_source

                    # wrapper for fix strange languages
                    case "$LANG" in
                        bg*|bn*|el*|hi*|ja*|ko*|ru*|sr*|te*|uk*|vi*|zh*)
                            export LC_ALL=en_US.UTF-8
                            export LANG=en_US.UTF-8
                    esac

                    # update: we will do that later in a E hook
                    #dpkg-reconfigure -f noninteractive -p critical console-setup
                    #setupcon
                fi

                touch /var/lib/live/config/languagedetect
            fi

            # append the locales to debconf-get-selections
            # UPDATE: we should not need this, locale.gen should be copied in teh installed system and then generating correctly the locales
            # locales_source
            #if ! debconf-get-selections 2>/dev/null | grep -E "locales/locales_to_be_generated\s+multiselect" | grep -qs "$LANG" ; then
                #if echo "$LANG" | grep -qs "\.UTF-8" ; then
                    #echo "$(debconf-get-selections 2>/dev/null | grep -E "locales/locales_to_be_generated\s+multiselect" ), $LANG UTF-8" | debconf-set-selections
                    #echo "$(debconf-get-selections 2>/dev/null | grep -E "locales/locales_to_be_generated\s+multiselect" ), $LANG UTF-8" >> /tmp/preseeds.cfg
                #else
                    #el_error "non-utf8 language, how to add to preseeds?: $LANG"
                #fi
            #fi

        else
            # delete file if not processed correctly
            el_warning "country not get correctly for ip $(showmyip): $(cat "$cache_location_f" )"
            rm -f "$cache_location_f"
        fi
    fi
    # - configure a new country }}}
    log_progress_msg ""

}
################################################################
check_integrity(){
    locales_source

    # integrity verification {{{
    # minimal verification of the integrity of the system
    if ! [[ -s "/usr/bin/tee" ]] || ! [[ -s "/usr/bin/who" ]] || ! [[ -s "/usr/bin/apt-get" ]] || ! [[ -s "/usr/bin/gawk" ]] ; then
        locales_source

        el_c_n="\033[0;39m" # Normal color  (orig: normal)
        el_c_r="\033[1;31m" # Red color  (orig: red)

        splash hide

        clear
        echo -e "\n\n\n${el_c_r}WARNING WARNING WARNING"
        echo -e "\n\n"
        echo "$( eval_gettext "Your Elive system appears to be damaged, possibly due to an interrupted download. If you experience any errors, please download Elive again and write it to a new storage device." )"
        echo -e "\n\n"
        echo -e "\n\n\nWARNING WARNING WARNING${el_c_n}"

        sleep 20

        splash show
    fi

    # - integrity verification }}}
}
################################################################
check_errors_and_reports(){
    if [[ -e "/var/lib/dpkg/info/systemd.list" ]] && [[ -e "/var/lib/dpkg/info/live-config-systemd.list" ]] ; then
        if sudo -H -n systemctl status systemd-journald.service 2>&1 | colors-remove | grep -Fqs loaded ; then
            #logs_error="$( PAGER="" journalctl -p err | colors-remove )"
            logs_error="$( PAGER="" journalctl -p err | grep -vE "(Logs begin at|/dev/xconsole|ACPI.*ERROR|power saving mode for wireless card|ntpd|acer_wmi|acer-aspireone-fand)" )"

            if [[ -n "$logs_error" ]] ; then
                #el_warning "journalctl -p err found errors:\n${logs_error}"
                el_warning "journalctl -p err found errors:\n$( PAGER="" journalctl -p err | grep -vE "(Logs begin at|/dev/xconsole|ACPI.*ERROR|power saving mode for wireless card|ntpd|acer_wmi|acer-aspireone-fand)" )"
            fi
        fi
    fi
}
################################################################
disable_update_initramfs(){
    # UPDATE: should be correctly managed by live-tools
    #log_progress_msg "Disabling update-initramfs for live mode"

    if [[ -x "/bin/live-update-initramfs" ]] ; then
        mv /bin/live-update-initramfs /bin/live-update-initramfs.orig
        ln -s /bin/true /bin/live-update-initramfs
    else
        mv /usr/sbin/update-initramfs /usr/sbin/update-initramfs.orig
        ln -s /bin/true /usr/sbin/update-initramfs
    fi
}

################################################################
check_for_slow_computer(){
    local cpubogomips
    locales_source

    cpubogomips="$( grep -F bogomips /proc/cpuinfo | sed -e 's|^.*: ||g' -e 's|\..*$||g' | tr ' ' '\n' | grep "[[:digit:]]" | head -1 )"

    if echo "${_CMDLINE}" | LC_ALL=C grep -Fqs "simulate=slow-computer" ; then
        RAM_TOTAL_mb="200"
        cpubogomips="400"
    fi

    # disable systemctl journal on low ram:
    if [[ "${RAM_TOTAL_mb}" -lt "800" ]] ; then
        if sudo -H -n systemctl status systemd-journald.service 2>&1 | colors-remove | grep -Fqs loaded ; then
            # note: os-prober will not work if 'journald-dev-log' is disabled
            systemctl disable  systemd-journald.service systemd-journald.socket systemd-journald-audit.socket systemd-journald-dev-log.socket   1>/dev/null 2>&1 || true
            systemctl stop     systemd-journald.service systemd-journald.socket systemd-journald-audit.socket systemd-journald-dev-log.socket   1>/dev/null 2>&1 || true
            rm -rf /var/log/journal/* 1>/dev/null 2>&1 || true
        fi
    fi

    if [[ "${RAM_TOTAL_mb}" -lt "800" ]] || [[ "$cpubogomips" -lt 1500 ]] ; then
        splash hide

        dialog --timeout 50 --clear --colors --title "Low Resources Computer" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
            --msgbox "$( eval_gettext "Your computer appears to be old or has limited resources. If Elive runs very slowly, consider trying an older version, which may perform better on your hardware. All versions are available for download from our website." )" 0 0 2>/dev/null

        splash show
    fi


}
################################################################
check_for_slow_usb(){
    local usb_version

    locales_source

    usb_version="$( LC_ALL=C timeout 20 lsusb | grep -F "root hub" | sed -e 's|root hub.*$||g' -e 's|^.*Foundation ||g' | tr ' ' '\n' | grep "[[:digit:]]" | sort -uV | tail -1 | sed -e 's|\..*$||g' )"
    if echo "${_CMDLINE}" | LC_ALL=C grep -Fqs "simulate=slow-usb" ; then
        usb_version=1
    fi

    if [[ -n "$usb_version" ]] ; then
        if [[ "${usb_version}" = "1" ]] ; then

            if ! [[ -n "$MACHINE_VIRTUAL" ]] ; then
                splash hide

                dialog --timeout 50 --clear --colors --title "USB 1.0" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
                    --msgbox "$( eval_gettext "Warning: Your computer is using USB 1.0, which will result in an extremely slow Live experience. Elive will perform much faster once installed on your hard disk. Alternatively, booting from a DVD will provide better performance." )" 0 0 2>/dev/null

                splash show
            fi
        fi
    fi

}
check_for_secureboot(){
    locales_source

    if el_check_dir_has_files "/sys/firmware/efi/" 1>/dev/null 2>&1 ; then
        if el_check_dir_has_files "/sys/firmware/efi/efivars" 1>/dev/null 2>&1 ; then
            is_efi_booted=1
        fi
    fi

    if ((is_efi_booted)) ; then
        if [[ -x "$(which mokutil)" ]]; then
            if mokutil --sb-state 2>&1 | grep -Fqs "SecureBoot enabled" ; then
                is_secureboot_enabled=1
            fi
        fi
    fi

    if ((is_secureboot_enabled)) ; then
        # add a flag to know about this state
        touch /tmp/.secureboot-enabled

        splash hide

        dialog --timeout 200 --clear --colors --title "SecureBoot Limitation" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
            --msgbox "$( eval_gettext "Warning: SecureBoot is enabled. This may cause issues with Wi-Fi, VirtualBox, or Nvidia drivers. We recommend disabling SecureBoot in your BIOS settings for full functionality. You can find many online guides that explain how to do this." )" 0 0 2>/dev/null

        splash show
    fi
}
################################################################
check_for_security(){
    # a simple check to know if the OS has been modified / altered / hacked, which may include a security risk to the users
    locales_source

    # check if the system is modified more recently than expected
    if [[ -s "$LIVE_MOUNT_MAIN_d/medium/live/filesystem.squashfs" ]] \
        && [[ -s "$LIVE_MOUNT_MAIN_d/medium/live/filesystem.squashfs.sig" ]] \
        && [[ "$LIVE_MOUNT_MAIN_d/medium/live/filesystem.squashfs" -nt "$LIVE_MOUNT_MAIN_d/medium/live/filesystem.squashfs.sig" ]] \
        ; then

        # add a flag to know about this state
        touch /tmp/.system-modified

        splash hide
        # seems like this is made from unetbootin:
        if echo "${_CMDLINE}" | LC_ALL=C grep -qsiE "(initrd=/ubninit|BOOT_IMAGE=/ubnkern)" ; then
            # probably due to unetbootin tool
            dialog --timeout 200 --clear --colors --title "Recording USB" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
                --msgbox "$( eval_gettext "Warning: It appears a non-recommended tool was used to create your bootable USB drive. To ensure compatibility, reliability, and security, please use one of the recommended tools listed on our website." )" 0 0 2>/dev/null
        else
            # modified Elive system
            dialog --timeout 200 --clear --colors --title "Elive Authenticity - MODIFIED" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
                --msgbox "$( eval_gettext "This system has been modified from the original Elive version. Proceed only if you trust the source of these changes." )" 0 0 2>/dev/null
        fi
        splash show
    fi
}
################################################################
swap_partitions_use(){
    local list_swaps want_simulate partition magic

    if echo "${_CMDLINE}" | LC_ALL=C grep -qsiE "simulate=(swapuse|wantswap)" ; then
        want_simulate=1
    fi

    if echo "${_CMDLINE}" | LC_ALL=C grep -qsiE "(noswap|nodosswap)" ; then
        el_debug "We requested to not use swap"
        return 0
    fi

    # with 100 we have enough to get the console, with 200 to install nvidia, with 300 to run E, and with 400 to have terminology and thunar opened
    # machines with 4gb of ram is not so much so enable it for these
    if [[ "$RAM_TOTAL_mb" -lt 4500 ]] || ((want_simulate)) ; then
        log_progress_msg "Checking if we can use an existing swap partition..."
        while read -ru 3 partition
        do
            unset magic
            [[ -b "$partition" ]] || continue

            # detect and enable swaps
            magic=$( dd if="${partition}" bs=4086 skip=1 count=1 2>/dev/null | dd bs=10 count=1 2>/dev/null ) || continue

            if [[ "${magic}" = "SWAPSPACE"* ]] || [[ "${magic}" = "SWAP-SPACE" ]] || [[ "$RAM_TOTAL_mb" -lt 800 ]] ; then
                log_progress_msg "Enabled SWAP from ${partition}"
                swapon "$partition" 2>/dev/null

                # is good to have it marked in any of the cases
                echo "$partition none swap sw 0 0" >> /etc/fstab
            else
                magic="$( dd if="${partition}" bs=4086 skip=1 count=1 2>/dev/null )"
                if echo "$magic" | grep -Eq "(tuxonice|lzflowlevel)" ; then
                    echo "${partition}" >> /hibernation_activated
                fi
            fi
        done 3<<< "$( NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-all | awk -v FS="::" '{if ($2 == "swap") print $1}' )"

        # only create swapfiles if we really need a swap partition (even less ram):
        # at least 1gb of ram to not trigger the creation of swapfiles:
        if [[ "$RAM_TOTAL_mb" -lt 850 ]] || ((want_simulate)) ; then

            list_swaps="$(swapon -s | grep "^/")"

            if [[ -z $list_swaps ]] || ((want_simulate)) ; then
                log_progress_msg "No swap partitions found. A temporary swap file must be created."

                # call the tool!
                #swap-tempfile-create-on-existing-partition
                swap_tempfile_create
            fi
        fi
    #else
        #el_debug "We don't really need a swap partition because we have enough memory for run Elive"
    fi
}
################################################################
reconfigure_slmodem(){
    local title message want_simulate ret
    # check if exists, save time
    if [[ ! -e /etc/init.d/sl-modem-daemon ]] && ! systemctl list-units --full -all | grep -Fq "sl-modem-daemon.service" && [[ ! -b /dev/slamr0 ]]  ; then
        return
    fi
    locales_source

    if echo "${_CMDLINE}" | LC_ALL=C grep -Fqs "simulate=sl-modem" ; then
        want_simulate=1
    fi

    if test -b /dev/slamr0 || ((want_simulate)) || lsmod | grep -qsE "^slamr\s+.*1$" ; then
        log_progress_msg "Configuring sl-modem"

        title="$( eval_gettext "SmartLink Modem Detected" )"
        message="$( eval_gettext "A SmartLink Modem (winmodem) has been detected. The driver for this device may be unstable and is only needed for dial-up internet access. If you use Wi-Fi or an Ethernet cable, you do not need this driver." )""\n\n""$( eval_gettext "Would you like to remove the SmartLink Modem driver?" )"

        splash hide

        dialog --timeout 30 --clear --colors --backtitle "Elive Systems: Use Ctrl-L to redraw, TAB to select, Enter to confirm" \
            --title "$title" \
            --yesno "$message" \
            0 0
        ret="$?"

        splash show


        case "$ret" in
            0|255|123) # yes, timeout, cancel
                log_progress_msg "Removing modem daemon and drivers"
                ( service sl-modem-daemon stop 1>/dev/null 2>&1 & ) || true
                systemctl mask sl-modem-daemon.service 1>/dev/null 2>&1 || true
                systemctl disable sl-modem-daemon.service 1>/dev/null 2>&1 || true
                systemctl stop sl-modem-daemon.service 1>/dev/null 2>&1 || true
                killall slmodemd 2>/dev/null || true
                rm -f /etc/init.d/sl-modem*
                echo "sl-modem-daemon" >> /tmp/.packages-to-remove
                echo "sl-modem-dkms" >> /tmp/.packages-to-remove
                echo "sl-modem-source" >> /tmp/.packages-to-remove
                ;;
            1) # no
                log_progress_msg "Keeping modem daemon and drivers"
                true
                ;;
        esac

    else
        # we don't have it, remove
        ( service sl-modem-daemon stop 1>/dev/null 2>&1 & ) || true
        systemctl mask sl-modem-daemon.service 1>/dev/null 2>&1 || true
        systemctl disable sl-modem-daemon.service 1>/dev/null 2>&1 || true
        systemctl stop sl-modem-daemon.service 1>/dev/null 2>&1 || true
        killall slmodemd 2>/dev/null || true
        rm -f /etc/init.d/sl-modem*

        echo "sl-modem-daemon" >> /tmp/.packages-to-remove
        echo "sl-modem-dkms" >> /tmp/.packages-to-remove
        echo "sl-modem-source" >> /tmp/.packages-to-remove

    fi
}
################################################################
special_hardware_configs(){
    locales_source

    # Apple keyboard {{{
    # note: not tested if these works or not anymore
    if grep -qsi "Apple.*keyboard" /proc/bus/input/devices ; then
        # auto, since can autodetect
        log_progress_msg "Apple Keyboard special configurations"

        # xorg keyboard
        echo "xserver-xorg	xserver-xorg/config/inputdevice/keyboard/options	string	lv3:switch" >> /tmp/debconf.live
        echo "xserver-xorg	xserver-xorg/config/inputdevice/keyboard/model	string	pc106" >> /tmp/debconf.live

        # normal keyboard config
        if laptop-detect ; then
            echo "keyboard-configuration keyboard-configuration/modelcode select apple_laptop" >> /tmp/debconf.live
            sed -i -e "s|^XKBMODEL=.*$|XKBMODEL=\"apple_laptop\"|" /etc/default/keyboard
        else
            echo "keyboard-configuration keyboard-configuration/modelcode select apple" >> /tmp/debconf.live
            sed -i -e "s|^XKBMODEL=.*$|XKBMODEL=\"apple\"|" /etc/default/keyboard
        fi

        echo "keyboard-configuration keyboard-configuration/variantcode string mac" >> /tmp/debconf.live
        sed -i -e "s|^XKBVARIANT=.*$|XKBVARIANT=\"mac\"|" /etc/default/keyboard

        echo "keyboard-configuration keyboard-configuration/optionscode string lv3:switch" >> /tmp/debconf.live
        sed -i -e "s|^XKBOPTIONS=.*$|XKBOPTIONS=\"lv3:switch\"|" /etc/default/keyboard


        if [[ -e /tmp/debconf.live ]] ;  then
            debconf-set-selections < /tmp/debconf.live
            rm -f /tmp/debconf.live
        fi

        # reconfigure xorg
        log_progress_msg "Reconfiguring xorg (Apple keyboard)"
        dpkg-reconfigure -f noninteractive -p critical \
            xserver-xorg 2>&1 \
            | grep -Fv "overwriting possibly-customised configuration" \
            | grep -Fv "file; backup in /etc/X11/xorg.conf" || true

        echo "isight-firmware-tools" >> /tmp/.packages-to-install

        # touch /tmp/.apple-detected
    else
        echo "isight-firmware-tools" >> /tmp/.packages-to-remove
    fi

    # }}}
    # apple macbooks {{{
    # Macbooks detect
    # TODO:  and I have Elivecd installed because the full support of the mac hardware, i.e. WiFi chipset, and elive works pretty fluently.
    if dmidecode -s system-product-name | grep -qsi "macbook" ; then
        #XXX can be migrated to x11 hooks
        chmod +x /etc/init.d/macfanctld
        service macfanctld start 1>/dev/null 2>&1 || true
        systemctl unmask macfanctld.service 1>/dev/null 2>&1 || true
        systemctl enable macfanctld.service 1>/dev/null 2>&1 || true
        touch /tmp/.macbook-detected
    else
        echo "macfanctld" >> /tmp/.packages-to-remove
        #systemctl disable macfanctld.service 1>/dev/null 2>&1 || true
        #( service macfanctld stop 1>/dev/null 2>&1 & ) || true
        killall macfanctld 2>/dev/null || true
        #rm -f /etc/init.d/macfanctld
    fi

    if grep -F macbook /etc/elive-version | grep -Fqs specialmachine ; then
        touch /tmp/.eliveformacbooks
    fi

    # - macbooks }}}
    # laptop {{{
    if laptop-detect && ! [[ "$MACHINE_VIRTUAL" = "yes" ]] ; then
        true
    else
        echo "fancontrol" >> /tmp/.packages-to-remove
        echo "lm-sensors" >> /tmp/.packages-to-remove
    fi
    # - laptop }}}
    # eeepc {{{
    # EeePC detect
    if [[ "$( dmidecode -s system-product-name )" = "701" ]] ; then

        #XXX can be migrated to x11 hooks
            # test detection
        touch /tmp/.eeepc-detected
        if ! ((is_persistence)) ; then
            echo -e "specialmachine: EeePC" >> /etc/elive-version
        fi

        if modprobe p4-clockmod 2>/dev/null ; then
            echo -e "Cpu Frequency module\np4-clockmod" >> /etc/modules
        fi
        if modprobe pciehp 2>/dev/null ; then
            echo -e "pciehp" >> /etc/modules
        fi
        if modprobe eeepc-laptop 2>/dev/null ; then
            echo -e "eeepc-laptop" >> /etc/modules
        fi
    fi
    # check if exists, save time
    if [[ -e /etc/init.d/eeepc-acpi-scripts ]] || systemctl list-units --full -all | grep -Fqs "eeepc-acpi-scripts.service" ; then
        if ! dmidecode -s "system-serial-number" | grep -qsi "eeepc" && ! lsmod | grep -qsi "eeepc" ; then
            ( service eeepc-acpi-scripts stop 2>/dev/null & ) || true
            # remove also a file that shows some annoying error messages in tty1
            systemctl mask eeepc-acpi-scripts.service 1>/dev/null 2>&1 || true
            systemctl disable eeepc-acpi-scripts.service 1>/dev/null 2>&1 || true
            systemctl stop eeepc-acpi-scripts.service 1>/dev/null 2>&1 || true
            rm -f /etc/init.d/eeepc* /usr/share/acpi-support/eeepc-acpi-scripts/lib/shengine.sh /etc/pm/power.d/SHE.sh   2>/dev/null
            echo -e "eeepc-acpi-scripts" >> /tmp/.packages-to-remove
        fi
    fi
    # - eeepc }}}
    # Acer Aspire-ONE {{{
    if [[ "$( dmidecode -s system-product-name )" = "AOA1"* ]] && [[ "$( dmidecode -s system-manufacturer )" = "Acer" ]] ; then
        echo -e "acer-aspireone-fand" >> /tmp/.packages-to-install

        if [[ -f "/var/lib/dpkg/info/acer-aspireone-fand.list" ]] ; then
            systemctl unmask acer-aspireone-fand 1>/dev/null 2>&1 || true
            systemctl enable acer-aspireone-fand 1>/dev/null 2>&1 || true
            systemctl start acer-aspireone-fand 1>/dev/null 2>&1 || true
        fi
    else
        echo -e "acer-aspireone-fand" >> /tmp/.packages-to-remove
    fi


    # - Acer Aspire-ONE }}}
    # virtual machines {{{

    # configure ssh for virtual machines
    if [[ "$MACHINE_VIRTUAL" = "yes" ]] || { ((is_thanatests)) && [[ -d "/etc/ssh" ]] ; } ; then
        if [[ -e /etc/ssh/sshd_config ]] ; then
            # enable ssh with password on vmachines
            sed -i -e 's|\(#\)*\(PermitRootLogin\).*$|\2 yes|' /etc/ssh/sshd_config
            sed -i -e 's|\(#\)*\(PasswordAuthentication\).*$|\2 yes|' /etc/ssh/sshd_config

            if [[ -x "$( which ssh-keygen )" ]] ; then
                rm -f /etc/ssh/ssh_host_rsa_key* || true
                ssh-keygen -q -f /etc/ssh/ssh_host_rsa_key -N "" -t rsa
                # start the daemon
                sudo -H killall -9 sshd 2>/dev/null || true
                systemctl unmask ssh.service 1>/dev/null 2>&1 || true
                systemctl enable ssh.service 1>/dev/null 2>&1 || true
                systemctl start ssh.service 1>/dev/null 2>&1 || true
            fi

        fi
    # else
    #     systemctl stop ssh.service 1>/dev/null 2>&1 || true
    fi

    if [[ "$MACHINE_VIRTUAL_TYPE" = "qemu" ]] ; then
        # load them, just in case (they should be already loaded)
        modprobe -q mousedev >> /var/log/initramfs.debug 2>&1
        modprobe -q psmouse  >> /var/log/initramfs.debug 2>&1

        if ((is_wheezy)) && [[ "$(which enlightenment_start 2>/dev/null)" ]] ; then
            splash hide

            # this seems like to be fixed in newer versions
            dialog --timeout 30 --clear --colors --title "QEMU" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
                --msgbox "$( eval_gettext "Elive does not work correctly in QEMU due to a bug related to the MMX instruction set. For a better experience and a smoother desktop, please use VirtualBox or similar virtualization software. The graphical system may not start, or menus may be buggy due to this MMX issue." )" 0 0 2>/dev/null

            splash show
        fi
    fi

    # - }}}
    # Touchpad / Synaptics confs {{{
    if grep -qsiE '(synap|alps|cyapa|trackpad|etps|elan)' /proc/bus/input/devices ; then
        # cyapa chromebook's (Acer C720) {{{
        if grep -qsi "cyapa" /proc/bus/input/devices ; then
            # google chromebooks crappy touchpads (Acer C720)
# FIXME: finish and betatest to see if works
            mkdir -p /etc/X11/xorg.conf.d
            cat > /etc/X11/xorg.conf.d/50-cyapa-touchpad.conf << EOF
# note: this is a template file, use touchpad-configurator from elive which is a better option
Section "InputClass"
    Identifier      "touchpad peppy cyapa"
    MatchIsTouchpad "on"
    MatchDevicePath "/dev/input/event*"
    MatchProduct    "cyapa"
    Option          "ClickPad"         "1"
    Option          "FingerLow" "6"
    Option          "FingerHigh" "6"
    # disable movements and taps in the bottom zone so that you can click more easly!
    Option          "AreaBottomEdge" "88%"
    #Option          "SoftButtonAreas"  "50% 0 82% 0 0 0 0 0"
    # In the following example right button will occupy 40% of the rightmost part of the button area. We then proceed to setup the middle button to occupy 20% of the touchpad in a small area in the center.
    Option          "SoftButtonAreas"  "60% 0 82% 0 40% 59% 82% 0"
    # double tap and drap locks the draging until you tap again
    Option          "LockedDrags"     "1"
    # enable 2 and 3 buttons of mouse in the top corners?
    #Option          "LTCornerButton" "2"
    #Option          "RTCornerButton" "3"

    # append options here
EndSection
EOF

        else
            # XXX temporal
            if dmesg | grep -qsi cyapa ; then
                el_warning "Cyapa mouse detected wrongly in $0, improve the code:\nhwinfo --mouse:\n$(hwinfo --mouse 2>&1 )\n\n/proc/bus/input/devices/:\n$(cat /proc/bus/input/devices)\n\ndmesg:\n$(dmesg | grep -i cyapa)"
            fi
        fi

        # - cyapa chromebook's (Acer C720) }}}
        # normal touchpad {{{
        mkdir -p /etc/X11/xorg.conf.d
        cat > /etc/X11/xorg.conf.d/80-eliveconfs-touchpad.conf << EOF
# note: this is a template file, use touchpad-configurator from elive which is a better option
Section "InputClass"
    Identifier      "touchpad elive default configuration"
    #Option          "LockedDrags"     "1"
    Option          "LTCornerButton" "2"
    Option          "RTCornerButton" "3"
    # vertical scrolling when dragging along the right edge.
    #Option          "VertEdgeScroll" "1"
    #Option          "HorizEdgeScroll" "1"
    # Enable edge scrolling to continue while the finger stays in an edge corner.
    #Option          "CornerCoasting" "1"
    # Enable horizontal scrolling when dragging with two fingers anywhere on the touchpad.
    Option          "VertTwoFingerScroll" "1"
    Option          "HorizTwoFingerScroll" "1"
    # which mouse button is reported on a non-corner N-finger tap (enables taps as clicks)
    Option          "TapButton1"        "1"
    Option          "TapButton2"        "3"
    Option          "TapButton3"        "2"
    # which mouse button is reported when left-clicking with N fingers
    #Option          "ClickFinger2"  "3"
    #Option          "ClickFinger3"  "2"

    # append options here
EndSection
EOF

        # }}}
        # thinkpad trackpoint's {{{
        # UPDATE: disabled: this crappy feature makes your middle-button of the mouse NOT working, a not desirable thing, for example try to alt + middle-cllick to resize a window and you will see that not works
        #if grep -Fqs "TPPS/2 IBM TrackPoint" /proc/bus/input/devices ; then
            #mkdir -p /etc/X11/xorg.conf.d
            #cat > /etc/X11/xorg.conf.d/50-thinkpad-mousebuttonwheel.conf << EOF
#Section "InputClass"
    #Identifier "Trackpoint Wheel Emulation"
    #MatchProduct "TrackPoint"
    #MatchDevicePath "/dev/input/event*"
    #Driver "evdev"
    #Option "EmulateWheel" "true"
    #Option "EmulateWheelButton" "2"
    #Option "Emulate3Buttons" "false"
    #Option "XAxisMapping" "6 7"
    #Option "YAxisMapping" "4 5"
#EndSection
#EOF
        #fi

        # - thinkpad trackpoint's }}}
    fi
    # - Synaptics Touchpad cons }}}
    # misc {{{
    if ! grep -Fqs "msr" /proc/cpuinfo || ! grep -Fqs "Fan" /sys/class/thermal/cooling_device*/type 2>/dev/null ; then
        echo -e "thermald" >> /tmp/.packages-to-remove
    fi
    # - misc }}}
    # no keyboard found {{{
    # if user-manager creation detects this file entry, it will add onboard to the autolaunching apps
    if dmidecode -s system-product-name | grep -qsi "WeTab" ; then
        touch /tmp/.no-keyboard
    fi

    if ! cat /proc/bus/input/devices | grep -qsi "keyboard" ; then
        if ! lsusb | grep -qsi "keyboard" ; then
            if ! dmesg | grep -qsi "keyboard" ; then
                if ! hwinfo --keyboard | grep -qsi "keyboard" ; then
                    #el_warning "No keyboard found? improve the code:\nhwinfo --keyboard:\n$(hwinfo --keyboard 2>&1 )\n\n/proc/bus/input/devices/:\n$(cat /proc/bus/input/devices)\n\ndmesg:\n$(dmesg | grep -i keyboard)\n\nlsusb:\n$(lsusb 2>&1 | grep -i keyboard)"

                    # mark
                    touch /tmp/.no-keyboard
                fi
            fi
        fi
    fi
    # - no keyboard found }}}
    # bluetooth reactivation {{{

    # sometimes we need to unblock bluetooth this way (ex. Thinkpad L440):
    rfkill unblock bluetooth 1>/dev/null 2>&1 || true

    # - bluetooth reactivation }}}


}
################################################################
replace_xinit_script_from_liveconfig(){
    if ! ((is_wheezy)) ; then
        return 0
    fi
    # put ours there
    if [[ -s "/usr/lib/deliver/scripts/shell-login/zx-live_config_xinit_elive.sh" ]] ; then
        ln -fs /usr/lib/deliver/scripts/shell-login/zx-live_config_xinit_elive.sh /etc/profile.d/
        # zsh should run it externally and not sourced, or it will fail
        echo "/usr/lib/deliver/scripts/shell-login/zx-live_config_xinit_elive.sh" > /etc/zsh/zprofile.d/zx-live_config_xinit_elive.sh
        chmod a+x /etc/zsh/zprofile.d/zx-live_config_xinit_elive.sh

        # remove the ones by live-config
        if [[ -s "/etc/profile.d/zz-live-config_xinit.sh" ]] ; then
            rm -f /etc/profile.d/zz-live-config_xinit.sh 2>/dev/null
        fi
        if [[ -s "/etc/zsh/zprofile.d/zz-live-config_xinit.sh" ]] ; then
            rm -f /etc/zsh/zprofile.d/zz-live-config_xinit.sh 2>/dev/null
        fi
    fi

}

################################################################
graphical_drivers_extra_configs(){
    if lspci | grep -qsiE "(VGA|3D|Display).*(Silicon Integrated Systems|SiS).*671.*" ; then
        log_progress_msg "Detected graphics card: SiS 671"

        cat > /etc/X11/xorg.conf << EOF
Section "Device"
    Identifier  "Configured Video Device"
    Driver      "sis671"
EndSection
EOF
    fi
}
################################################################
graphical_drivers_privative_install(){

    #
    # First: remove the drivers, we need to clean the environment in persistence
    #
    # detect and run nvidia installer tool
    if ((is_persistence_booted)) ; then
        # remove unneeded drivers
        if ls /var/lib/dpkg/info/nvidia*list 1>/dev/null 2>&1 ; then
            if nvidia-privative-drivers-install -d 1>/dev/null 2>&1 ; then
                # remove not-working (version?) drivers
                if ! nvidia-privative-drivers-install -t ; then
                    #log_daemon_msg "Nvidia: uninstalling driver: not the correct version for this machine"
                    nvidia-privative-drivers-install -a -f -u
                fi
            else
                # we don't have the hardware at all, uninstall driver
                # note: do not test -t because it also checks for the correctly-working driver, and this can fail, we only want to remove it
                #log_daemon_msg "Nvidia: uninstalling driver: this machine doesn't has it"
                nvidia-privative-drivers-install -a -f -u
            fi
        fi
    fi
    # Same for ATI cards
    #if ((is_wheezy)) ; then
        #if which fglrx-privative-drivers-install 1>/dev/null 2>&1 ; then
            ## remove unneeded drivers
            #if ((is_persistence_booted_already)) ; then
                #if fglrx-privative-drivers-install -d 1>/dev/null 2>&1 ; then
                    ## remove not-working (version?) drivers
                    #if ! fglrx-privative-drivers-install -t ; then
                        ##log_daemon_msg "FGLRX: uninstalling driver: not the correct version for this machine"
                        #fglrx-privative-drivers-install -a -f -u
                    #fi
                #else
                    ## we don't have the hardware at all, uninstall driver
                    ##log_daemon_msg "FGLRX: uninstalling driver: this machine doesn't has it"
                    #fglrx-privative-drivers-install -a -f -u
                #fi
            #fi
        #fi
    #fi


    #
    # Install drivers
    #
    # install if needed
    #if echo "${_CMDLINE}" | LC_ALL=C grep -qsiE "simulate=nvidia" || nvidia-privative-drivers-install -d 1>/dev/null 2>&1 ; then
    if echo "${_CMDLINE}" | LC_ALL=C grep -qsiE "(simulate=nvidia|bootmode=privativedrivers|bootmode=nvidia|blacklist=nouveau)" ; then

        if echo "${_CMDLINE}" | LC_ALL=C grep -Fqs "nox11autologin" ; then
            # only report so we are in console mode only
            el_explain 0 "Nvidia card detected. Run __sudo nvidia-privative-drivers-install__ to manually install the proprietary drivers."
            sleep 2
        fi

        # optimus don't looks like to work, at least in wheezy, only install nvidia if is not optimus
        if ! echo "${_CMDLINE}" | LC_ALL=C grep -qsE "(nonvidia|onlyfree)" ; then
            splash hide

            # OPTIMUS nvidia: if we have nvidia, in laptop, and another card that is not nvidia (optimus?)...
            if [[ "$( lspci | grep -E "\W+(VGA|3D|2D|Display)\W+" | wc -l )" -gt "1" ]] && ! [[ "$( lspci | grep -E "\W+(VGA|3D|2D|Display)\W+" | grep -iE "\W+(VGA|3D|2D|Display)\W+.*\W+nvidia\W+" | wc -l )" -gt "1" ]] ; then
                log_progress_msg "Nvidia OPTIMUS found"
            else
                # remove unneeded packages for optimus if we have nvidia but is not an optimus
                echo -e "bbswitch-dkms" >> /tmp/.packages-to-remove
                echo -e "bbswitch-source" >> /tmp/.packages-to-remove
            fi


            nvidia-privative-drivers-install -l

            splash show
        fi

    else
        # remove optimus if we simply don't have nvidia at all
        echo -e "bbswitch-dkms" >> /tmp/.packages-to-remove
        echo -e "bbswitch-source" >> /tmp/.packages-to-remove

        # if we have nvidia but the user didn't selected it, tell this to the user
        if nvidia-privative-drivers-install -d 1>/dev/null 2>&1 ; then
            log_daemon_msg "Detected Nvidia card"
            log_progress_msg "To install proprietary drivers, please select a different boot option..."
            if ((is_persistence_booted)) ; then
                NOREPORTS=1 el_warning "Not installing Nvidia proprietary drivers. To install them, select the 'Nvidia + Persistence' boot option."
            fi
        fi
    fi

    # Same for ATI cards
    # only supported in wheezy, not anymore in newer versions
    #if ((is_wheezy)) ; then
        #if which fglrx-privative-drivers-install 1>/dev/null 2>&1 ; then
            ## install if needed
            #if echo "${_CMDLINE}" | LC_ALL=C grep -qsiE "simulate=(ati|fglrx)" || fglrx-privative-drivers-install -d 1>/dev/null 2>&1 ; then

                #if echo "${_CMDLINE}" | LC_ALL=C grep -Fqs "nox11autologin" ; then
                    ## only report so we are in console mode only
                    #el_explain 0 "ATI card found, run __sudo fglrx-privative-drivers-install__ to install the nonfree drivers"
                    #sleep 2
                #fi

                #if ! echo "${_CMDLINE}" | LC_ALL=C grep -qsE "(nofglrx|onlyfree)" ; then
                    # splash hide

                    #fglrx-privative-drivers-install -l

                    # splash show
                #fi
            #fi
        #fi
    #fi
}

################################################################
wifi_last_notify_notfound(){
    locales_source

    # do not show this warning for b43 because is going to be installed later
    if [[ "$( lspci -nn -d "14e4:" | wc -l )" -gt 0 ]] ; then
        return 0
    else
        echo "broadcom-sta-dkms" >> /tmp/.packages-to-remove
        echo "broadcom-sta-source" >> /tmp/.packages-to-remove
        echo "broadcom-sta-common" >> /tmp/.packages-to-remove
    fi

    # TODO: move to X11 hooks

    # is_virtual dependency on special_hardware_configs
    if laptop-detect && ! [[ "$MACHINE_VIRTUAL" = "yes" ]] ; then
        if ! timeout 2 ping -c 1 "8.8.8.8" 1>/dev/null 2>&1 ; then

            # no wifi detect in laptop? inform the user
            if ! iwconfig 2>&1 | grep -qsE "(IEEE|802|ESSID)" ; then
                splash hide

                # wifi's not working
                dialog --timeout 40 --clear --colors --title "Wireless Devices" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
                    --msgbox "$( eval_gettext "No Wi-Fi devices were detected. If your computer has a Wi-Fi card, please report this issue to the Elive team so we can add support for it. Your report helps us ensure it works for you and others with the same hardware." )" 0 0 2>/dev/null

                # suggest to use another kernel
                if [[ "$( ls -1 /boot/vmlinuz-* | wc -l )" -gt 1 ]] ; then
                    dialog --timeout 40 --clear --colors --title "Wireless Devices" --backtitle "Elive Systems: Use Ctrl-L to redraw, Enter to confirm" \
                        --msgbox "$( eval_gettext "Your system has multiple kernel versions available. Rebooting and selecting a different kernel from the boot menu may resolve your Wi-Fi issue, as it could contain the necessary drivers." )" 0 0 2>/dev/null

                fi

                splash show
            fi
        fi
    fi
}
################################################################
report_unknown_machine(){
    rm -f /tmp/.machine-profile

    # version / mode machine, example: ThinkCentre M73
    dmidecode -s system-version >> /tmp/.machine-profile
    # is a laptop?
    if laptop-detect ; then
        echo "Laptop: YES" >> /tmp/.machine-profile
    else
        echo "Laptop: NO" >> /tmp/.machine-profile
    fi
    # graphic card:
    lspci | grep -iE "\W+(VGA|3D|2D|Display)" >> /tmp/.machine-profile
    # product / manufacturer, etc...
    dmidecode | grep -iE '(manufacturer|product|vendor)' | sort -u >> /tmp/.machine-profile
    # other few hardware specs
    lspci >> /tmp/.machine-profile

    # report unknown machine type
    el_warning "Unknown Machine type profile:\n$(cat /tmp/.machine-profile)"
}

################################################################
efreet_cache_fixes(){
    # rename "s|HOSTNAME|$(hostname)|g" /home/*/.cache/efreet/* 2>/dev/null || true
    local file
    for file in /home/*/.cache/efreet/* ; do
        if [[ -s "$file" ]] ; then
            ln -fs "$file" "${file/HOSTNAME/$(hostname)}" 2>/dev/null || true
        fi
    done
}

################################################################
audio_detect_and_configure(){
    # NOTE: this feature is duplicated in the startup of the desktop, but we want to have to preconfigure a default one in early stage, maybe E doesn't starts or something similar
    #el_explain 0 "Configuring audio card..."
    el_warning "disabled $FUNCNAME"

    # TODO: remove por pulseaudio ? we may not need this anymore with it

    if ! which pulseaudio 1>/dev/null 2>&1 ; then
        if ! [[ -s "/root/.asoundrc" ]] ; then
            audio-configurator --quiet --smart --auto
            # we need to create the PCM channel! it doesn't exist until we do it
            timeout 5 aplay /dev/null 2>/dev/null

            # do not set volumes from here (audio glitches), also user needs to set it because some apps needs to be configured too
            if ! [[ -s "/home/eliveuser/.asoundrc" ]] ; then
                cp -a /root/.asoundrc /home/eliveuser/ 2>/dev/null
                chown eliveuser:eliveuser /home/eliveuser/.asoundrc 2>/dev/null
            fi
        fi
    fi


    # we will do that later
    #el_explain 0 "Set default volumes..."
    #rm -f "/root/.config/setvolume" 2>/dev/null 1>&2
    #setvolume defaults
    #setvolume 75% # not needed

    # now store the PCM (and volumes) channel so that we can have it among reloads
    #el_explain 0 "Store volume configurations..."
    #alsactl store

    #el_explain 0 "Copy root volume configuration to $USER..."
    #cp -a /root/.asoundrc /home/eliveuser/ 2>/dev/null
    #chown eliveuser:eliveuser /home/eliveuser/.asoundrc 2>/dev/null
}
################################################################
swap_tempfile_create(){
    # pre {{{
    local file dir line partition filesystem name mountpoint

    # }}}

    # Ask if we want to create swap or exit {{{
    local title message_1 message_2 message_3

    title="$( eval_gettext "Swap File Creation Tool" )"
    message_1="$( eval_gettext "Your computer has low RAM. To prevent it from running out of memory, would you like to create a temporary swap file on one of your partitions?" )"
    message_3="$( eval_gettext "Important: You cannot partition a hard disk to install Elive while one of its partitions is in use as swap. To install on that disk, first disable swap by running the command:" ) 'swapoff'"


    splash hide

    dialog --timeout 90 --clear --colors --backtitle "Elive Systems: Use Ctrl-L to redraw, TAB to select, Enter to confirm" \
        --title "$title" \
        --yesno "$message_1\n\n${message_3}" \
        0 0
    ret="$?"

    splash show


    case "$ret" in
        0|255|123) # yes, timeout, cancel
            true

            ;;
        1) # no
            return
            ;;
    esac

    # }}}

    while read -ru 3 line
    do
        partition="${line%%::*}"

        if [[ -b "$partition" ]] ; then
            unset filesystem name

            filesystem="$( echo "$line" | awk -v FS="::" '{print $3}' )"
            name="$( echo "$line" | awk -v FS="::" '{print $3}' )"

            if mounts-manager --mount "$partition" 1>/dev/null ; then
                mountpoint="$( mounts-manager --get-mountpoint "$partition" 2>/dev/null )"

                # skip invalid ones
                if echo "$mountpoint" | grep -qsE "(^/run/)" ; then
                    ( umount "$partition" 2>/dev/null || umount -f "$partition" 2>/dev/null ) &
                    continue
                fi
                #size_free_mb="$( df -m --output=avail "$mountpoint" | grep "[[:digit:]]" | tail -1 )"

                if el_check_dir_has_files "$mountpoint" ; then
                    # recyclate old swap files?
                    if [[ -s "$mountpoint/swapfile-tmp-deleteme.swp" ]] ; then

                        if file -s "$mountpoint/swapfile-tmp-deleteme.swp" | grep -Fqs "swap file" ; then
                            # ask if use existing swapfile {{{
                            local message_swapfile_found_use_or_not
                            message_swapfile_found_use_or_not="$( printf "$( eval_gettext "A swap file was found on one of your partitions. Would you like to use it?" )" "" )"
                            splash hide

                            dialog --timeout 90 --clear --colors --backtitle "Elive Systems: Use Ctrl-L to redraw, TAB to select, Enter to confirm" \
                                --title "$title" \
                                --yesno "${message_swapfile_found_use_or_not}\n\nPartition '${partition}', filesystem '${filesystem}', label '${name}', mounted in '$mountpoint'" \
                                0 0
                            ret="$?"

                            splash show

                            # - ask if use existing swapfile }}}
                            case "$ret" in
                                0) # yes
                                    chmod 0600 "$mountpoint/swapfile-tmp-deleteme.swp" 1>/dev/null 2>&1 || true
                                    if ! swapon "$mountpoint/swapfile-tmp-deleteme.swp" 1>/dev/null 2>&1  ; then
                                        mkswap -q "$mountpoint/swapfile-tmp-deleteme.swp"
                                        swapon "$mountpoint/swapfile-tmp-deleteme.swp" 1>/dev/null 2>&1
                                    fi

                                    echo "$mountpoint/swapfile-tmp-deleteme.swp none swap sw 0 0" >> /etc/fstab
                                    is_swapfile_created=1

                                    ;;
                                1|255|123) # no, timeout, cancel
                                    rm -f "$mountpoint/swapfile-tmp-deleteme.swp"
                                    continue
                                    ;;
                            esac

                        fi
                    else
                        # min 200 free mb
                        # update: not needed, we have already a human selector (asking loop)
                        #if [[ "$size_free_mb" -gt "200" ]] ; then
                            create_swapfile_mountpoint "$partition" "$mountpoint" "$filesystem" "$name" "swapfile-tmp-deleteme.swp"
                        #else
                            #echo "Less than 200 MB free, trying with next partition"
                        #fi
                    fi


                    # finish if was created
                    if ((is_swapfile_created)) ; then
                        el_explain 0 "Swap file successfully created in $mountpoint"
                        return 0
                    fi
                fi
            fi

            # umount if anything was mounted (but not if we have added a swap!)
            if mounts-manager --check-is-mounted "$partition" 1>/dev/null 2>&1 ; then
                ( umount "$partition" 2>/dev/null || umount -f "$partition" 2>/dev/null ) &
            fi
        fi
    #done 3<<< "$( partitions-list --show-all-mountable | psort -- -p "::reiserfs::" -p "::ext" -p "fat" | psort -- -p "^/dev/sd" -p "^/dev/hd" )"
    done 3<<< "$( NOREPORTS=1 EL_DEBUG=0 timeout 120 partitions-list --show-all-mountable | grep -v "^/dev/sr" | psort -- -p "fat" -p "::ext" | psort -- -p "^/dev/sd" -p "^/dev/hd" )"

}
################################################################
create_swapfile_mountpoint(){
    local mountpoint file spaceleft size message_1 name filesystem partition size target ret
    local title message_1 message_2

    partition="$1"
    mountpoint="$2"
    filesystem="$3"
    name="$4"
    file="$5"

    if ! el_check_variables "mountpoint|file" ; then
        return 1
    fi

    spaceleft="$( LC_ALL=C df -m --output=avail "$mountpoint" | grep "[[:digit:]]" | tail -1 )"

    # we should never need more than 500 mb and also this takes space
    if [[ "${spaceleft}" -gt "600" ]] ; then
        size="500"
    else
        if [[ "${spaceleft}" -gt "500" ]] ; then
            size="400"
        else
            if [[ "${spaceleft}" -gt "400" ]] ; then
                size="300"
            else
                if [[ "${spaceleft}" -gt "300" ]] ; then
                    size="200"
                else
                    if [[ "${spaceleft}" -gt "120" ]] ; then
                        size="100"
                    else
                        el_warning "Not enough free space in '$mountpoint' to create a swap file"
                        return 1
                    fi
                fi
            fi
        fi
    fi


    title="$( eval_gettext "Swap File Creation Tool" )"
    message_1="$( printf "$( eval_gettext "A suitable partition was found for a temporary swap file:\n\nPartition: %s\nLabel: %s\nFilesystem: %s\nMount Point: %s\n\nThis partition has %s MB of free space, so a %s MB swap file can be created. This file will be deleted on shutdown." )" "${partition}" "${name}" "${filesystem}" "${mountpoint}" "${spaceleft}" "${size}"   )"

    message_2="$( eval_gettext "Would you like to use this partition to create a temporary swap file?" )"

    splash hide

    dialog --timeout 240 --clear --colors --backtitle "Elive Systems: Use Ctrl-L to redraw, TAB to select, Enter to confirm" \
        --title "$title" \
        --yesno "${message_1}\n\n${message_2}" \
        0 0
    ret="$?"

    splash show

    case "$ret" in
        0|255|123) # yes, timeout, cancel
            if [[ -d "$mountpoint/tmp" ]] ; then
                target="$mountpoint/tmp/$file"
            else
                target="$mountpoint/$file"
            fi

            el_explain 0 "Creating a ${size}MB swap file. This may take a while."

            # RO filesystem?
            if ! touch "$target" 2>/dev/null ; then
                el_explain 0 "Unable to write to this filesystem. Skipping..."
                sleep 2

                return 1
            fi

            if ! [[ -s "$target" ]] && ! file -s "$target" | grep -qsi "swap file" ; then
                #if ! fallocate -l ${size}M "$target" ; then  ## important: fallocate only works in ext4 and new FS's
                if ! dd if=/dev/zero of="$target" bs="1M" count="$size" ; then
                    el_warning "Unable to create swap file. Skipping..."
                    sleep 2

                    return 1
                fi
            fi

            mkswap -q "$target"
            chmod 0600 "$target" 1>/dev/null 2>&1 || true
            swapon "$target" 2>/dev/null

            # is good to have it marked in any of the cases
            echo "$target none swap sw 0 0" >>/etc/fstab

            is_swapfile_created=1
            ;;
        1) # no
            return 1
            ;;
    esac

}
################################################################
################################################################


do_start(){
    if ! ((is_live)) ; then
        exit 0
    fi
    # if this script fails on bootup, a probably better way to debug, edit this file with "set -e ; set -x" and run it manually
    if ((is_debug)) ; then
        set -x
    fi

    if grep -Fqs "$(basename $0)" /tmp/.live-processes-finished 2>/dev/null ; then
        el_info "$(basename $0) already ran, ignoring..."
        exit
    fi

    # make sure that the working console reads and outputs things correctly (otherwise tab not works on dialog's unless we do a "login" or "getty")
    #exec 0</dev/console 1>/dev/console 2>/var/log/$(basename $0).log
    exec 0</dev/console 1>/dev/console 2>&1


    # checks, important because all other profile machine detection depends on this
    if [[ -x "$(which dmidecode 2>/dev/null )" ]] ; then
        if ! [[ "$( dmidecode | grep -Ei '(manufacturer|product)' | wc -l )" -ge 2 ]] ; then
            el_error "unable to get dmidecode information at $SOURCE"
        fi
    else
        el_error "dmidecode not found"
    fi


    #
    # each type of drivers
    #
    #disable_update_initramfs

    pre_optimizations

    persistence_soft_restore

    check_for_secureboot
    swap_partitions_use

    languagedetect
    language_fix

    check_integrity
    check_virtual_machine
    check_for_slow_usb
    check_for_slow_computer
    check_for_security


    reconfigure_slmodem
    special_hardware_configs

    replace_xinit_script_from_liveconfig

    graphical_drivers_privative_install
    graphical_drivers_extra_configs


    wifi_last_notify_notfound

    # audio_detect_and_configure

    # update: this doesnt works, the only way is by using a static hostname in the live mode like HOSTNAME (on live-config randomizer of hostnames), otherwise they will be always regenerated, and even like that i think it keeps a 4.6mb usage
    # efreet_cache_fixes

    # wait for dbus to be correctly run
    # update: not needed anymore if we have it in our .service file
    #wait_for_dbus

    # disabled: useless reports most of the time (very hardware specifics)
    #check_errors_and_reports

    # mark done for systemd
    echo "$(basename $0)" >> /tmp/.live-processes-finished


    # turn off debugging if we have finished
    if ((is_debug)) ; then
        set +x
    fi

    # return back to the main console, just in case
    if ((is_wheezy)) ; then
        chvt 1
    fi

    wait
    true

    exit 0
}

do_stop(){
    true
}

case "$1" in
    "")
        echo "Error: drivers-install should be called with the 'start' argument." >&2
        ;;
    start)
        do_start
        ;;
    stop)
        do_stop
        ;;
    restart|reload|force-reload)
        "$0" stop
        "$0" start
        ;;
    *)
        echo "Usage: drivers-install [start|stop]" >&2
        exit 3
        ;;
esac


# vim: set filetype=sh foldmethod=marker :
