#!/bin/sh
#---------------------------------------------------------------
# Project         : hardware4linux.info
# File            : hwreport
# Author          : Frederic Lepied
# Created On      : Fri Feb 17 22:48:06 2006
# Purpose         : gather hardware and os info and the store them
#                   in an archive file.
#---------------------------------------------------------------

if [ `whoami` != root ]; then
    echo "you need to be root to launch this program" 1>&2
    exit 1
fi

if [ $# != 1 ]; then
    prog=`basename $0`
    cat <<EOF
$prog creates a file with detailed reports of this computer's hardware
in a way which is suitable for uploading to http://hardware4linux.info/upload/.

Usage: $prog <report-file-progname>
Example: "$prog /tmp/myreport" to create /tmp/myreport.tar.bz2
EOF
    exit 1
fi

set -e

BASE="$1"
DEST=`mktemp -d`

if [ ! -d "$DEST" ]; then
    echo "Unable to create temporary directory" 1>&2
    exit 1
fi

clean() {
    [ -d "$DEST" ] && rm -rf "$DEST"
}

trap clean 0

# step 0: verify integrity
PATH=`dirname $0`/../lib:/usr/lib/hwreport:$PATH:.
export PATH

for e in dmidecode scan-printers reportusb lspci lsmod; do
    if ! type $e > /dev/null 2>&1; then
	echo "$e not found. Aborting" 1>&2
	exit 1
    fi
done

# step 1: gather info

echo "version=0.11.0" > "$DEST/hwreport.info"
echo "date=`date +'%F,%T'`" >> "$DEST/hwreport.info"

mounted=
if [ ! -r /proc/bus/usb/devices ]; then
    mount -t usbfs none /proc/bus/usb && mounted=1 || :
fi

for d in /proc/bus/*; do
    f=`basename $d`
    if [ -r "$d/devices" ]; then
	cat $d/devices > "$DEST/$f.devices"
    fi
done

if [ -n "$mounted" ]; then
    umount /proc/bus/usb
fi

reportusb > "$DEST/reportusb.out"
lspci -vn > "$DEST/lspci.out"

if [ -d /sys/bus/pci/devices/ -a -r /proc/modules ] ; then
    (
    cd /sys/bus/pci/devices/
    for address in * ; do
	if [ -d "$address/driver/module" ] ; then
	    module=`cd $address/driver/module ; pwd -P | xargs basename`
	    if grep -q "^$module " /proc/modules ; then
		address=$(echo $address |sed s/0000://)
		echo "`lspci -n -s $address | tail -n 1 | awk '{print $3}'` $module" >> "$DEST/pci.modules"
	    fi
	fi
    done
    )
fi

if [ -d /sys/bus/usb/devices/ -a -r /proc/modules ] ; then
    (
    cd /sys/bus/usb/devices/
    for address in * ; do
	if [ -r "$address/uevent" ] ; then
	    cp "$address/uevent" "$DEST/usb-$address.uevent"
	fi
    done
    )
fi
    
# report module related info only if the kernel
# has been compiled with module support...
if [ -f /proc/modules ]; then
    lsmod > "$DEST/lsmod.out"
    
    cp -p /lib/modules/`uname -r`/*map /lib/modules/`uname -r`/modules.alias "$DEST/" || :
fi

scan-printers > "$DEST/printers.out"

for f in /proc/parport/[0-9]*/autoprobe /proc/sys/dev/parport/parport[0-9]*/autoprobe; do
    if [ -r $f ]; then
	echo -n "$f: " >> "$DEST/printers.out"
	while read l; do echo -n "$l"; done < $f >> "$DEST/printers.out"
	echo >> "$DEST/printers.out"
    fi
done

if [ -f /proc/cmdline ]; then
    cat /proc/cmdline > "$DEST/cmdline"
fi

dmidecode | egrep -v '(Serial Number|UUID|Asset Tag):' > "$DEST/dmidecode.out"

cat /proc/cpuinfo > "$DEST/cpuinfo"

if [ -r /proc/asound/cards ]; then
    cat /proc/asound/cards > "$DEST/asound.cards"
    for c in `ls /proc/asound/card*/codec*/* /proc/asound/card*/codec* 2> /dev/null`; do
	if [ -r "$c" ]; then
	    b=`basename $c`
	    d=`dirname $c`
	    dd=`dirname $d`
	    d=`basename $d`
	    dd=`basename $dd`
	    cat "$c" > "$DEST/$dd:$d:$b"
	fi
    done
fi

if type locale > /dev/null 2>&1; then
    locale > "$DEST/locale.out"
fi

if [ -r /etc/sysconfig/hw-uuid ]; then
    cp /etc/sysconfig/hw-uuid "$DEST/hw-uuid"
fi

osinfo -x > "$DEST/osinfo.xml" || rm -f "$DEST/osinfo.xml"

# copy the file needed by osinfo

mkdir "$DEST/etc"

set +e

uname -i 2> /dev/null > "$DEST/etc/unamei.osinfo"
uname -r 2> /dev/null > "$DEST/etc/unamer.osinfo"
uname -m 2> /dev/null > "$DEST/etc/unamem.osinfo"

cp -p /etc/*version "$DEST/etc/" > /dev/null 2>&1
r=$?
cp -p /etc/*release "$DEST/etc/" > /dev/null 2>&1

if [ $? != 0 -a $r != 0 ] || [ -f /etc/arch-release ]; then
    cp -p /etc/issue "$DEST/etc/" > /dev/null 2>&1
fi

if type pacman > /dev/null 2>&1; then
    pacman -Qi pacman > "$DEST/etc/pacman.osinfo" 2> /dev/null
fi

set -e

# step 2: archive info

# try to guess which kind of archiver is available
if type tar > /dev/null 2>&1; then
    case "$BASE" in
	/*) FILE="$BASE".tar;;
	*) FILE="$PWD/$BASE".tar;;
    esac
    (cd $DEST; tar cf "$FILE" *)
    if type bzip2 > /dev/null 2>&1; then
	bzip2 -9f "$FILE"
	FILE="$FILE.bz2"
    elif type gzip > /dev/null 2>&1; then
	gzip -9f "$FILE"
	FILE="$FILE.gz"
    fi
elif type zip > /dev/null 2>&1; then
    FILE="$BASE".zip
    rm -f "$FILE"
    zip "$FILE" -9 -q -j -r "$DEST"
else
    echo "no way to store the files. Given up." 1>&2
    exit 1
fi

rm -f $FILES

echo "$FILE created successfully"

# hwreport ends here
