#!/bin/sh
#
# SliTaz Hardware configuration tool. Auto-detect and configure in a
# simple way all PCI, PCMCIA and USB devices. Some Wireless Adapters 
# need non-free firmware not installed by default. Users must use the
# option --get-firmware to force installation. GUI uses Yad and is
# called by args such as all box functions.
#
# (c) 2009-2014 SliTaz GNU/Linux - GNU GPL v3
#
# Authors: Christophe Lincoln <pankso@slitaz.org>
#          Rohit Joshi <jozee@slitaz.org>
#
. /lib/libtaz.sh
export TEXTDOMAIN='slitaz-tools' # i18n text mode

usage() {
	cat << EOT

$(_n 'SliTaz Hardware configuration')

$(boldify "$(_n 'Usage:')") $(basename $0) [$(_n 'command')] [--$(_n 'option')]

$(boldify "$(_n 'Commands:')")
  usage             $(_n 'Print this short usage.')
  init              $(_n 'Used at boot time to configure devices.')
  setup             $(_n 'Setup hardware devices.')
  detect-pci        $(_n 'Detect all PCI devices.')
  detect-usb        $(_n 'Detect all USB devices.')
  detected-modules  $(_n 'List all detected Kernel modules.')

$(boldify "$(_n 'Options:')")
  --get-firmware    $(_n 'Get and install non-free firmware (PCI and USB).')

EOT
}

check_firmware() {
	if [ -x /usr/bin/get-$mod-firmware ]; then
		if [ ! -d /var/lib/tazpkg/installed/$mod-firmware ]; then
			# We need an active connection to install firmware and we
			# only install firmware if specified from cmdline.
			if ifconfig | grep -q "inet addr"; then
				# Ensure module is not loaded and get files.
				if [ "$firmware" == "get" ]; then
					rmmod $mod 2>/dev/null
					get-$mod-firmware
				else
					_ '* Use --get-firmware option to install missing files.'
				fi
			else
				_ '* No active connection to get and install firmware.'
			fi
		else
			_ '> Firmware in use: $mod-firmware'
		fi
	fi
}

load_module() {
	if ! lsmod | grep -q "^$mod"; then
		# Check if builtin, loaded or missing
		if modprobe $mod 2>/dev/null; then
			if zcat /proc/config.gz | fgrep -i $mod | fgrep -q '=y'; then
				_ '* Builtin module : $mod'
				unset mod
			else
				_ "* Loaded module  : $mod"
			fi
		else
			if zcat /proc/config.gz | fgrep -i $mod | fgrep -q '=y'; then
				_ '* Builtin module : $mod'
				unset mod
			else
				_ '! Missing module : $mod'
			fi
		fi
	else
		_ '> Module in use  : $mod'
	fi
	# Add it to load automatically at next boot.
	if ! echo "$LOAD_MODULES" | grep -q "$mod"; then
		sed -i s/"LOAD_MODULES=\"$LOAD_MODULES\""/"LOAD_MODULES=\"$LOAD_MODULES $mod\""/ \
			/etc/rcS.conf
	fi
	. /etc/rcS.conf
}

# Detect PCI devices and load kernel module only at first boot,
# in LiveCD mode or with the command 'detect-pci'.
detect_pci_devices() {
	if [ ! -s /var/lib/detected-modules ]; then
		. /etc/rcS.conf
		# We need module_name to match output of lsmod.
		list=$(lspci -k | grep "driver" | cut -d ":" -f 2 | sed s/-/_/g)
		echo "$list" > /var/lib/detected-modules
		for mod in $(cat /var/lib/detected-modules | uniq)
		do
			check_firmware
			load_module
		done
	fi
}

# Detect all USB devices.
detect_usb_devices() {
	if [ -e /sys/bus/usb/devices/usb/usb1 ]; then
		for product in /sys/bus/usb/devices/*/product
		do
			path=$(dirname $product)
			product=$(cat $product)
			config=$(cat $path/configuration)
			debug "$path"
			. $path/[0-9]*/uevent
			[ ! "$DRIVER" ] && DRIVER="(none)"
			echo "$product $config $(indent 40 $DRIVER)"
			unset DRIVER
		done
	fi
}

# Get firmware used by check_firmware()
if [ "$2" == "--get-firmware" ]; then
	firmware='get'
fi

# What to do.
case "$1" in
	-i|init)
		check_root
		_ 'Detecting PCI devices Kernel modules...'
		detect_pci_devices
		_ 'Detecting USB devices Kernel modules...'
		detect_usb_devices ;;
	-dp|detect-pci)
		check_root
		newline; _ 'Detected PCI devices Kernel modules'; separator
		rm -f /var/lib/detected-modules
		detect_pci_devices
		separator; newline ;;
	-du|detect-usb)
		check_root
		newline; _ 'Detected USB devices Kernel modules'; separator
		rm -f /var/lib/detected-usb-modules
		detect_usb_devices
		separator; newline ;;
	-s|setup)
		SETUP_OPTIONS=$(echo "$@" | sed 's/setup//')
		check_root
		hwsetup $SETUP_OPTIONS ;;
	-dm|detected-modules)
		newline; _ 'Detected PCI and USB modules'; separator
		cat /var/lib/detected-modules
		cat /var/lib/detected-usb-modules 2>/dev/null
		separator; newline ;;
	*) 
		usage ;;
esac

exit 0
