#!/bin/bash
# Name : eaglediag
# Goal : diagnostic script for eagle-usb driver (formerly adiusbadsl)
# Author : Benoit Audouard aka baud123 (baud at magic dot fr)
# Description : identifie les elements permettant un diagnostic
#       type de systeme, verification de l'install
#       verification bon fonctionnement modem
#	verification bon fonctionnement couche reseau
# ce script s'adapte a la version 1.0.4e des drivers et au-dessus
# il doit etre lance sous root
# Availability : see http://baud123.free.fr/eagle/
# Documentation : see http://fast800.tuxfamily.org/faqeagle/
VERSION_DIAG="v1.2 20040111"

# todo
# - obtenir un numero de version du driver eagle-usb (meme celles de dev)
# - obtenir le type de connexion (degroupe ok, Free/9Tel/...)
# - traduire completement les commentaires en anglais
# - verify the user that launches eaglediag : exit with help if not root
# - add some advices based on the option selected to help the newbie analyze the output
# - verify hdd parameters (hdparm)

# done
# 0.5 take into account eagle-cvs and eagle-1.0.4
# 0.6 correction anomaly eagleusb.conf => eagle-usb.conf (ballot)
# 0.7 20031007 do not rely on DEGROUPE=0 (1.0.4e specific...), choose VCI=23(Free) or 24 (Degroupe)
#     replace * with # to avoid unwanted copy/paste and rpm exist for red-hat !
# 0.8 20031013 rename script from diag_eagle_usb.sh to eaglediag, use tee instead of tail -f
#     to avoid a kill in the end...
# 0.9 20031017 module is eagle-usb not adiusbadsl since 1.0.5, deactivate 1.0.4e service check
#     remaining translations...
# 1.0 20031123 add parameters, add functionalities (-uali), a revamped version !
# - ajouter un filtre sur /var/log/messages (mots cle grep -iE: pppd, usb, adi, ...)
# 1.1 20031221 change log directory to /var/log/eagle-usb/, add version mismatch (gcc / kernel)
# 1.2 20040111 compliant with kernel 2.6.0 (eagle_usb module instead of eagle-usb)
# INIT
# global variables
# date format YYYYMMDDHHmmss
TIME_STAMP=`date +"%Y""%m""%d""%H""%M""%S"`

# Paths
LOG_FILE=/var/log/eagle-usb/eagle_diag_${TIME_STAMP}.txt

SYSCONF_FILE=/var/lock/subsys/adiusbadsl # for service in 1.0.4e
#SYSCONF_FILE=/etc/sysconfig/adiusbadsl
#EAGLEDIR=/usr/local/eagleusb
EAGLECONF=/etc/analog/adiusbadsl.conf
EAGLE_VERSION="1.0.4"
EAGLE_TEST_E=0 # verify 1.0.4e version
EAGLE_STAT=showstat
MOD_EAGLE_USB=adiusbadsl

# create log directory if necessary
if [ ! -d /var/log/eagle-usb ] ; then
	mkdir /var/log/eagle-usb
fi

# this is the only criteria I've found to identify 1.0.4e...
# this file does not exist in 1.0.5cvs nor with <=1.0.4
# well never test 1.0.4e
if [ -f /etc/eagleusb.conf ] ; then
	EAGLE_TEST_E=0
fi

# since v1.0.5pre1cvs : directory change
# hence this is my criteria to identify new version with eagle everywhere instead of adi
if [ -f /etc/eagle-usb/eagle-usb.conf ] ; then
	EAGLECONF=/etc/eagle-usb/eagle-usb.conf
	EAGLE_VERSION="1.0.5pre1cvs"
	EAGLE_TEST_E=0 # do not verify 1.0.4e version
	EAGLE_STAT=eaglestat
	MOD_EAGLE_USB="eagle.usb"
fi

# Strings:
OPERSTR="Modem is operational"
EAGLEDIAG_USAGE_MSG="Usage : eaglediag [-ahvmscuil]\n"\
"\twith no parameter, only display status\n"\
"\t-a|--all\t: show everything (not log though !)\n"\
"\t-h|--help\t: this help\n"\
"\t-v|--version\t: display version\n"\
"\t-m|--make\t: for compilation problems\n"\
"\t-s|--synchro\t: when the modem does not synchronize\n"\
"\t-c|--connect\t: for connection problems (ifconfig + route)\n"\
"\t-u|--usb\t: for usb related problems (check for Latency)\n"\
"\t-i|--interrupts : to check if an IRQ is shared\n"\
"\t-l|--log\t: selection of /var/log/messages (sort and select what's relevant !)\n"

IP_FREE="213.228.0.42"
URL_FREE="www.free.fr"

# GET_INFO
# groupe ou degroupe ? unlucky ou lucky ?
# by default NON DEGROUPE (Free)
FREE_DEGROUPE=0
if [ -f ${EAGLECONF} ] ; then
	# look for string VCI=00000024 = Free dgroup
	if [ "X"`cat ${EAGLECONF}|grep -E "^VCI="` = "X""VCI=00000024" ] ; then
		FREE_DEGROUPE=1
	else
		FREE_DEGROUPE=0 # may be other ISP as well... to be improved !!
	fi
fi

# Identify which version the user is running for his/her own good sake
# Mandrake and Red-Hat have rpm
RPM_EXIST=0 ## RPM detection is based on distribution, maybe a better test exists ?
APT_EXIST=0 ## APT detection based on distrib, maybe a better test exists ?
PING_WAIT="-w 5" # option for ping to stop after 5 seconds
DISTRIB="other"
DISTRIB_FILE=""
if [ -f /etc/redhat-release ] ; then
        RPM_EXIST=1
	DISTRIB="rh"
	DISTRIB_FILE=/etc/redhat-release
fi
# on Mandrake, redhat-release exist... must therefore be after red-hat (same for Suse ?)
if [ -f /etc/mandrake-release ] ; then 
	RPM_EXIST=1
	DISTRIB="mdk"
	DISTRIB_FILE=/etc/mandrake-release
fi
if [ -f /etc/gentoo-release ] ; then
	DISTRIB="gentoo"
	DISTRIB_FILE=/etc/gentoo-release
fi
if [ -f /etc/debian_version ] ; then
	APT_EXIST=1 # I do not know how to use it, nevertheless may be useful in the future ?
	DISTRIB="debian"
	DISTRIB_FILE=/etc/debian_version
	PING_WAIT="" # -w 5 option not compatible with debian...
fi
# on Fedora, redhat-release may exist... should therefore be after red-hat
if [ -f /etc/fedora-release ] ; then 
	RPM_EXIST=1
	DISTRIB="fedora"
	DISTRIB_FILE=/etc/fedora-release
fi
if [ -f /etc/slackware-version ] ; then 
	DISTRIB="slackware"
	DISTRIB_FILE=/etc/slackware-version
fi
if [ -f /etc/SuSE-version ] ; then 
	DISTRIB="SuSE"
	DISTRIB_FILE=/etc/SuSE-version
fi

CMDECHO="echo"
CMDECHO_lg="echo -n"
# in /bin/ on Mandrake /usr/bin on Debian 
GAWK_BIN=gawk

# PARAMETERS
PB_COMPIL=0  # by default, do not look at compilation problems (dependancies...)
PB_SYNCHRO=0 # by default, do not look at synchro problems
PB_CONNECT=0 # by default, do not give connection infos
PB_STATUS=1  # by default provide info on status [this test is never used...]
PB_USB=0     # by default no usb info
PB_IRQ=0     # by default no interrupts infos
PB_MESSAGES=0 # by default, do not display any selection of /var/log/messages (even for all)

i=1
PARAMS=""

for param in $* ; do
	# do not know why there i > 0 ? taken from Tux...
	#echo $param
	if [ $i -gt 0 ] ; then
		param=${param//--help/-h}
		# with a parameter to the argument (for example timeout...)
                # param=${param//--timeout=/-t}
                # param=${param//--timeout/-t}
		param=${param//--make/-m}
		param=${param//--synchro/-s}
		param=${param//--connect/-c}
		param=${param//--usb/-u}
		param=${param//--interrupts/-i}
		param=${param//--log/-l}
		param=${param//--version/-v}
		param=${param//--all/-a}

                PARAMS="$PARAMS $param"
        fi
        let i++
done
evalParams() {
        while getopts "hmscuilav" opt; do # t:
		        # with an argument add ":" after letter and take the argument with :
                        #t  ) TIMEOUT=$OPTARG ;;
                case $opt in
                        h  ) echo -e $EAGLEDIAG_USAGE_MSG ; exit 0 ;;
                        m  ) PB_COMPIL=1 ;;
                        s  ) PB_SYNCHRO=1 ;;
                        c  ) PB_CONNECT=1 ;;
                        u  ) PB_USB=1 ;;
                        i  ) PB_IRQ=1 ;;
                        l  ) PB_MESSAGES=1 ;;
			a  ) PB_COMPIL=1 ; PB_SYNCHRO=1 ; PB_CONNECT=1 ; PB_USB=1 ; PB_IRQ=1 ;;
                        v  ) echo $0 ${VERSION_DIAG} ; exit 1 ;;
                        \? ) echo -e $EAGLEDIAG_USAGE_MSG ; exit 1 ;;
                esac
        done
}
evalParams $PARAMS

#echo $PARAMS
#echo "-mscuil" $PB_COMPIL $PB_SYNCHRO $PB_CONNECT $PB_USB $PB_IRQ $PB_MESSAGES

# START DIAG
${CMDECHO} "Diagnostic (${VERSION_DIAG}) driver eagle-usb ${TIME_STAMP}" | tee -a ${LOG_FILE}

# System Information 
${CMDECHO} "# System Information" | tee -a ${LOG_FILE}
uname -a | tee -a ${LOG_FILE}
if [ ${DISTRIB} != "other" ] ; then
	cat ${DISTRIB_FILE} | tee -a ${LOG_FILE}
else
	echo "other distrib" | tee -a ${LOG_FILE}
fi
cat /proc/version | tee -a ${LOG_FILE}
# gcc version begins by gcc
# verify that -v works with Red Hat, for Mandrake and Debian -v it's ok, 
# --version does not work with Debian
# Red Hat response in French does not begin with gcc (version I think... #?!@#)
gcc -v 2>&1 |grep -iE "gcc " 2>&1 | tee -a ${LOG_FILE}

if [ ${PB_SYNCHRO} -eq 1 -o ${PB_COMPIL} -eq 1 ] ; then
	# Verify dependances of eagle-usb driver on kernel-source and other packages...
	# if a binary RPM were used, there would be no need for this
	${CMDECHO} "# Dependances" | tee -a ${LOG_FILE}
	if [ ${RPM_EXIST} -eq 1 ] ; then
		rpm -q kernel-source 2>&1 | tee -a ${LOG_FILE} 
		rpm -q patch 2>&1 | tee -a ${LOG_FILE} 
		rpm -q slocate 2>&1 | tee -a ${LOG_FILE}
		rpm -q dhcp-client 2>&1 | tee -a ${LOG_FILE}
		rpm -q dhcpcd 2>&1 | tee -a ${LOG_FILE}
	else
		# people without rpm are not going to be happy...
		# give me a simple way to check what you installed ! (Debian deb ? Gentoo ebuild ?)
		#${CMDECHO} "Verifier dependances a la main (kernel-source...)" | tee -a ${LOG_FILE}
		${CMDECHO} "Verify dependances on source by hand (kernel-source...)" | tee -a ${LOG_FILE}
	fi

	# Another verification (which source is used ?)
	# deux verifs valent mieux qu'une (3 en comptant le uname)
	ls -l /usr/src/ | grep -i linux 2>&1 | tee -a ${LOG_FILE}

	# first step towards intelligence for eaglediag : verify that gcc available is the same
	# as the one used to compile the kernel
	GCC_VERSION=`gcc -v 2>&1 | grep -i "gcc "`
	KERNEL_COMPILED_WITH_SAME_GCC=`grep "${GCC_VERSION}" /proc/version`
	if [ "X""${KERNEL_COMPILED_WITH_SAME_GCC}" = "X" ] ; then
		echo "Warning : available gcc and the version used to compile the kernel differ" | tee -a ${LOG_FILE}
		echo "Advice  : that's a standard problem on debian, revert to gcc version used for kernel"  | tee -a ${LOG_FILE}
	fi
fi # synchro / compil

if [ ${PB_SYNCHRO} -eq 1 -o ${PB_USB} -eq 1 -o ${PB_IRQ} -eq 1 ] ; then
	# Verify modules configuration
	# Verifie config des modules
	${CMDECHO} "# Kernel config : usb modules" | tee -a ${LOG_FILE}
	lsmod | grep -E "usb|hci" | tee -a ${LOG_FILE}
fi # synchro / usb

if [ ${PB_USB} -eq 1 ] ; then
	${CMDECHO} "# pci & usb configuration (check for latency, only keep relevant lines about USB)"
	lspci | tee -a ${LOG_FILE} # display a summary
	cat /proc/pci | tee -a ${LOG_FILE} # look for latency
	lsusb | tee -a ${LOG_FILE} # identify devices plugged in
fi # usb

if [ ${PB_IRQ} -eq 1 ] ; then
	${CMDECHO} "# interruptions' affectation"
	cat /proc/interrupts | tee -a ${LOG_FILE} # look for modules on the same IRQ (may conflict, mainly usb with eth)
fi # interrupts

if [ ${EAGLE_TEST_E} -eq 1 ] ; then
	# valid for 1.0.4e
	${CMDECHO_lg} "# service started ? (info for 1.0.4e)  " | tee -a ${LOG_FILE}
	if [ -f $SYSCONF_FILE ] ; then
		${CMDECHO} "[ OK ]" | tee -a ${LOG_FILE}
	else
		${CMDECHO} "[ KO ]" | tee -a ${LOG_FILE}
	fi
fi

$CMDECHO_lg "# module loaded ?        " | tee -a ${LOG_FILE}
if lsmod | grep -qE "${MOD_EAGLE_USB}" ; then
	$CMDECHO "[ OK ]" | tee -a ${LOG_FILE}
else
	$CMDECHO "[ KO ]" | tee -a ${LOG_FILE}
fi
${CMDECHO_lg} "# modem operational ?    " | tee -a ${LOG_FILE}
if ${EAGLE_STAT} | grep -q "Modem is operational" ; then
	$CMDECHO "[ OK ]" | tee -a ${LOG_FILE}
else
	$CMDECHO "[ KO ]" | tee -a ${LOG_FILE}
fi

if [ ${PB_SYNCHRO} -eq 1 ] ; then
	# un petit showstat tout de meme (donne l'attenuation pour les deconnexions)
	# provide showstat result (gives attenuation)
	# identify VPI/VCI in decimal
	${EAGLE_STAT} | tee -a ${LOG_FILE}
fi # synchro

# si le service est lance (faut un minimum d'effort tout de meme)
# commente : n'a plus l'air de fonctionner avec Mandrake 9.2 ?
#if [ -f $SYSCONF_FILE ] ; then
	SERVICE_CONNEXION=0 # le service de connexion est operationnel ?
	# ce serait pas mal d'avoir plus d'info que groupe/degroupe
	# maintenant ya 9telecom, les anglais, ...
	# cryptic gawk to get vpi/vci/encapsulation, lines in config files are
	# {begin of line} {keyword} {=} {value}, this gawk gets the value
	CONF_EAGLE_VPI_VCI_ENCAP=`${GAWK_BIN}  -F "=" 'BEGIN { vpi=0 ; vci=0; encap=0 } /^VPI/ { vpi=$2 ; } /^VCI/ { vci=$2 } /^Encap/ { encap=$2 } END { printf("%d %d %d", vpi,vci,encap); }' ${EAGLECONF}` 
	# why doesn't | read variable_name does not put the displayed result in a variable (worked on Digital Unix)
	#echo ${CONF_EAGLE_VPI_VCI_ENCAP}

	if [ ${FREE_DEGROUPE} -eq 0 ] ; then
		$CMDECHO "# Config eagle : non degroupe Free ${CONF_EAGLE_VPI_VCI_ENCAP}" | tee -a ${LOG_FILE}
		${CMDECHO_lg} "# pppd launched ?        " | tee -a ${LOG_FILE}
		if [ `pidof pppd` ] ; then
			$CMDECHO "[ OK ]" | tee -a ${LOG_FILE}
			SERVICE_CONNEXION=1
		else
			$CMDECHO "[ KO ]" | tee -a ${LOG_FILE}
		fi
		# ajouter tests divers lie au non degroupe
		# add tests related to "non dgroupe"
	else
		$CMDECHO "# Config eagle : degroupe Free ${CONF_EAGLE_VPI_VCI_ENCAP}" | tee -a ${LOG_FILE}
		$CMDECHO "# dhcpclient launched ?  " | tee -a ${LOG_FILE}
		SERVICE_CONNEXION=1
		# how to test that dhcpcd or dhclient were launched ????
		# tests related to "Free degroupe"
		# pppd should not be launched
		if [ `pidof pppd` ] ; then
			$CMDECHO "# pppd should not be launched [KO]" | tee -a ${LOG_FILE}
		fi
	fi
	if [ ${SERVICE_CONNEXION} -eq 1 ] ; then
		$CMDECHO "# Service for connection [ OK ]" | tee -a ${LOG_FILE}
	fi

	if [ ${PB_CONNECT} -eq 1 ] ; then
		# bah on fait quand meme ces tests 
		# (avec IP fixe, il ne devrait pas yavoir besoin de dhcpclient...)
		# ya des infos sur le LAN que l'utilisateur devrait cacher
		$CMDECHO "# /etc/resolv.conf should contain the DNS" | tee -a ${LOG_FILE}
		# debug : verifier que ca marche si c'est un lien
		if [ -f /etc/resolv.conf ] ; then
			cat /etc/resolv.conf | tee -a ${LOG_FILE}
		fi
		ifconfig -a | tee -a ${LOG_FILE}
		route -n | tee -a ${LOG_FILE}
	fi # connect
		
	${CMDECHO_lg} "# ping IP ?              " | tee -a ${LOG_FILE}
	# -n does not use DNS, -q quiet (), -c 1 un seul paquet envoy, 
	# -w 5 attend rponse au plus tard en 5s : non compatible debian
	#/bin/ping -n -q -c 1 -w 5 ${IP_FREE} 1>/dev/null 2>/dev/null
	/bin/ping -n -q -c 1 ${PING_WAIT} ${IP_FREE} 1>/dev/null 2>/dev/null
	if [ $? = 0 ] ; then
		$CMDECHO "[ OK ]" | tee -a ${LOG_FILE}
	else
		$CMDECHO "[ KO ]" | tee -a ${LOG_FILE}
	fi
	${CMDECHO_lg} "# test DNS resolution ?  " | tee -a ${LOG_FILE}
	/bin/ping -n -q -c 1 -w 5 ${URL_FREE} 1>/dev/null 2>/dev/null
	if [ $? = 0 ] ; then
		$CMDECHO "[ OK ]" | tee -a ${LOG_FILE}
	else
		$CMDECHO "[ KO ]" | tee -a ${LOG_FILE}
	fi
#fi

# display a selection of /var/log/messages : beware this can be very long !!!
if [ ${PB_MESSAGES} -eq 1 ] ; then
	# would be cool to restrict to current day ? unless -all is selected ? evol !
	# or restrict from last restart (dmesg is better for this but lacks the timestamp and many messages)
	# adsl : may not be useful (part of adiusbadsl...)
	# apic|acpi : may be added in the future
	${CMDECHO} "# selection of /var/log/messages content (please sort and only keep what's relevant !)"
	grep -iE "usb|adi|eagle|pci|hotplug|insmod|ppp|dhclient|dhcp|respawn" /var/log/messages | tee -a ${LOG_FILE}

fi

$CMDECHO "Complete diagnostic has been saved on ${LOG_FILE}"
$CMDECHO "Please keep only relevant data and remove personal informations."
exit 0
