#!/bin/sh

# OPTIONS
export OPT_SHOWALL=0

while [ "$1" != "" ]; do
	[ "$1" = "-a" -o "$1" = "--all" ] && OPT_SHOWALL=1
	shift
done


# Controlla presenza libhardware
if [ -d /usr/share/libhardware/ ]; then
	HWDIR=/usr/share/libhardware/
elif [ -d /usr/local/share/libhardware/ ]; then
	HWDIR=/usr/local/share/libhardware/
else
	echo ">>>>> libhardware non  installata <<<<<"
	exit 1
fi


# ===== PCI =====

# Cerca driver per le periferiche
chkhw_pci() {
	# $1 = BUS
	# $2 = VENDOR
	# $3 = MODEL
	# $4 = DB libhardware

	# Controlla se il file esiste
	RFILE=$HWDIR/$4
	if [ ! -e $RFILE ]; then
		echo ">>>>> libhardware: $RFILE non  presente <<<<<"
		return 1
	fi

	# Device name
	DNAME=`lspci -s $1`

	# Cerca il driver particolare
	DRV=`grep "^$2|$3|" "$RFILE" | cut -f 3 -d '|' | tail -1`
	# Se non lo trova cerca un driver generico
	[ "$DRV" = "" ] && DRV=`grep "^$2|XXXX|" "$RFILE" | cut -f 3 -d '|' | tail -1`
	if [ "$DRV" = "" ]; then
		echoc YELLOW "driver non trovato ($4, $2.$3): $DNAME"
		return 1
	fi

	# Non carica i moduli gi presenti in memoria o nel file di configurazione
	if grep -q "^$DRV" /proc/modules /etc/badpenguin/config/modules /etc/badpenguin/config/modules.noload 2>/dev/null ; then
		[ "$OPT_SHOWALL" = "1" ] && echo "hardware presente $DRV: $DNAME"
		return 1
	fi

	# carica il modulo
	echo "rilevato $DRV: $DNAME"

	modprobe $DRV ; R1=$?
	if [ $R1 -ne 0 ]; then
		insmod $DRV ; R2=$?
		if [ $R2 -ne 0 ]; then
			# c' qualcosa che non va... mettiamo il modulo in black-list
			echo -e "\n# $DNAME\n$DRV" >>/etc/badpenguin/config/modules.noload
			return 1
		fi
	fi

	# tutto ok, mettiamolo nella white list
	echo -e "\n# $DNAME\n$DRV" >>/etc/badpenguin/config/modules
	return 0
}


# Analizza il bus pci
lspci -n -m | sed -e 's/Class //' | while read BUS CLASS VENDOR MODEL ALTRO ; do

	# Classi che possiamo omettere

	[ "$CLASS" = "" ] && continue
	RCLASS=`echo $CLASS | sed -e 's/"//g'`
	[ "$RCLASS" = "" ] && continue

	case $RCLASS in
		06*)
			# 0600 Host Bridge
			# 0601 ISA Bridge
			# 0604 PCI Bridge
			# 0680 Bridge
			continue
			;;
		0101)
			# 0101 IDE Interface
			continue
			;;
		0300)
			# Video card
			continue
			;;
	esac

	# Classi supportate

	RBUS=`echo $BUS | sed -e 's/"//g'`
	RVENDOR=`echo $VENDOR | sed -e 's/"//g'`
	RMODEL=`echo $MODEL | sed -e 's/"//g'`

	case $RCLASS in
		0c03)
			# USB Controller
			chkhw_pci "$RBUS" "$RVENDOR" "$RMODEL" usb.db
			;;
		0401)
			# Soundcard
			chkhw_pci "$RBUS" "$RVENDOR" "$RMODEL" soundcard.db
			;;
		0200)
			# Ethernet
			chkhw_pci "$RBUS" "$RVENDOR" "$RMODEL" ethernet.db
			;;
		*)
			echoc YELLOW "hardware sconosciuto ($RCLASS): `lspci -s $RBUS`"
			;;
	esac
done
[ "$OPT_SHOWALL" = "1" ] && echo "scansione bus PCI ultimata"



# ===== USB =====


# Cerca driver per le periferiche
chkhw_usb() {
	# $1 = VENDOR
	# $2 = MODEL
	# $3 = NOME
	# $4 = DB libhardware

	# Controlla se il file esiste
	RFILE=$HWDIR/$4
	if [ ! -e $RFILE ]; then
		echo ">>>>> libhardware: $RFILE non  presente <<<<<"
		return 1
	fi

	# Cerca il driver particolare
	DRV=`grep "^$1|$2|" "$RFILE" | cut -f 3 -d '|' | tail -1`
	# Se non lo trova cerca un driver generico
	[ "$DRV" = "" ] && DRV=`grep "^$1|XXXX|" "$RFILE" | cut -f 3 -d '|' | tail -1`
	if [ "$DRV" = "" ]; then
		echoc YELLOW "driver non trovato ($1.$2): $3"
		return 1
	fi

	# Non carica i moduli gi presenti in memoria o nel file di configurazione
	if grep -q "^$DRV" /proc/modules /etc/badpenguin/config/modules /etc/badpenguin/config/modules.noload 2>/dev/null ; then
		[ "$OPT_SHOWALL" = "1" ] && echo "hardware presente $DRV: $3"
		return 1
	fi

	# carica il modulo
	echo "rilevato $DRV: $3"

	modprobe $DRV ; R1=$?
	if [ $R1 -ne 0 ]; then
		insmod $DRV ; R2=$?
		if [ $R2 -ne 0 ]; then
			# c' qualcosa che non va... mettiamo il modulo in black-list
			echo -e "\n# $3\n$DRV" >>/etc/badpenguin/config/modules.noload
			return 1
		fi
	fi

	# tutto ok, mettiamolo nella white list
	echo -e "\n# $3\n$DRV" >>/etc/badpenguin/config/modules
	return 0
}


mount /proc/bus/usb/ 2>/dev/null

if [ ! -f /proc/bus/usb/devices ]; then
	echo "ATTENZIONE: bus USB non montato"
	exit 1
fi

# parsing del file dei device
cat /proc/bus/usb/devices | while read ULINE ; do
	case $ULINE in
		C:*)
			# controlla che il driver sia valido
			if [ "$VENDOR" = "0000" -a "$MODEL" = "0000" ]; then
				# USB UHCI ROOT
				VENDOR=
				MODEL=
				NAME=
				NAME1=
				NAME2=
				continue
			fi
			# Attiva il driver
			chkhw_usb "$VENDOR" "$MODEL" "$NAME1 $NAME2" usb-bus.db
			;;
		*Vendor=*)
			VENDOR=`echo $ULINE | sed -e 's/.*Vendor=//' -e 's/ .*//'`
			MODEL=`echo $ULINE | sed -e 's/.*ProdID=//' -e 's/ .*//'`
			;;
		*Manufacturer=*)
			NAME1=`echo $ULINE | sed -e 's/.*Manufacturer=//'`
			;;
		*Product=*)
			NAME2=`echo $ULINE | sed -e 's/.*Product=//'`
			;;
	esac
done
[ "$OPT_SHOWALL" = "1" ] && echo "scansione bus USB ultimata"

exit 0
