#!/bin/bash
#HInventory script for Linux
#Thomas BRETON 
#Contribution Julien SAFAR, David DU SERRE TELMON, Kotty, Raphux, Mark, Alexander, Andraž
#Copyright (C) 2005  Thomas BRETON

#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; either version 2
#of the License, or (at your option) any later version.

#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.

#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

VERSION="1.3.4 pour Linux"

##UNSET des langues
unset LANG LC_ALL LC_MESSAGES

##Global variables
HOSTNAME="`hostname -f`"
DATE="`date +%d/%m/%Y` `date +%H:%M:%S`"

if [ "$outputdir" == "" ] && [ -d "/var/spool/hinventory" ]
	then ReportFile=/var/spool/hinventory/$HOSTNAME-`date +%m-%d-%y-%H%M%s`.xml
else if [ "$outputdir" != "" ] && [ -d "$outputdir" ]
	then ReportFile=$outputdir/$HOSTNAME-`date +%m-%d-%y-%H%M%s`.xml
    else ReportFile=$HOSTNAME-`date +%m-%d-%y-%H%M%s`.xml
    fi
fi 

if [ -f "/var/log/dmesg" ]
	then dmesgvar="cat /var/log/dmesg"
	else dmesgvar="dmesg"
fi

if [ -x '/sbin/ifconfig' ]
	then ifconfig='/sbin/ifconfig'
	else ifconfig='ifconfig'
fi

##################################################################################
#Component writing
#4 functions 
##################################################################################
function writecomment ()
{
echo "<!-- $1 -->" >> $ReportFile
if [ "$debug" = 2 ]
then echo "<!-- $1 -->"
fi
}

# From FreeBSD rc.subr
checkyesno () {
  eval _value=\$${1}
  case $_value in
    #       "yes", "true", "on", or "1"
    [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
      return 0
      ;;
    #       "no", "false", "off", or "0"
    [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
      return 1
      ;;
    *)
      return 1
     ;;
  esac
  }
								
##################################################################################
# Sanity check, replace &, < et > with HTML codes
##################################################################################
correct_var () {
  echo "$1" | sed 's/&/\&amp;/g' | sed 's/</\&lt;/g' | sed 's/>/\&gt;/g'
  }


writecomponent () {
  var1=`correct_var "$1"`
  var2=`correct_var "$2"`
  echo "<component>" >> $ReportFile
  echo "<type>$var1</type>" >> $ReportFile
  echo "<name>$var2</name>" >> $ReportFile
  if [ "$debug" = 2 ]; then
    echo "<component>"
    echo "<type>$var1</type>"
    echo "<name>$var2</name>"
  fi
}

writesubcomponent () {
  var1=`correct_var "$1"`
  var2=`correct_var "$2"`
  echo "<attr><name>$var1</name><value>$var2</value></attr>" >> $ReportFile
  if [ "$debug" = 2 ]; then
    echo "<attr><name>$var1</name><value>$var2</value></attr>"
  fi
  }

writeendcomponent () {
  echo "</component>" >> $ReportFile
  if [ "$debug" = 2 ]; then
    echo "</component>"
  fi
  }

##################################################################################
## Temps d execution du script
##################################################################################

timecmd ()
{
diffsec=`expr $2 - $1`
heures=`expr $diffsec / 3600`
minutes1=`expr $diffsec - $heures \* 3600`
minutes=`expr $minutes1 / 60`
secondes1=`expr $diffsec - $minutes \* 60`
secondes=`expr $secondes1 - $heures \* 3600`
timeres="$heures heures $minutes minutes $secondes secondes"
}

##################################################################################
## Couleur
##################################################################################
black='\E[30;47m'
red='\E[31;47m'
green='\E[32;47m'
yellow='\E[33;47m'
blue='\E[34;47m'
magenta='\E[35;47m'
cyan='\E[36;47m'
white='\E[37;47m'

cecho ()                     # Color-echo.
                             # Argument $1 = message
                             # Argument $2 = color
{
local default_msg="No message passed."
                             # Doesn't really need to be a local variable.

message=${1:-$default_msg}   # Defaults to default message.
color=${2:-$black}           # Defaults to black, if not specified.

  echo -e "$color" "$message" 
  tput sgr0                      # Reset to normal.


}


##################################################################################
## Infos de script
##################################################################################

detect_script ()
{
comment=SCRIPT
type=script
name=inventory
version=$VERSION
time=`expr $2 - $1`
if [ "$debug" = 1 ]; then echo "- detect_script: $name"; fi
             if [ "$debug" = 1 ]; then echo "  * Version $version: [$time Sec] ($method)"; fi

writecomment "$comment"
writecomponent "$type" "$name"
writesubcomponent "version" "$version"
writesubcomponent "time" "$time"
writesubcomponent "method" "$method"
writesubcomponent "location" "$location"
writeendcomponent
}



##################################################################################
#Beginning of XML
##################################################################################
function beginXML ()
{
echo "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?> " > $ReportFile
echo "<!DOCTYPE computer [" >> $ReportFile
echo "<!ELEMENT computer      (hostname, datetime, component*)>" >> $ReportFile
echo "<!ELEMENT component     (type,name,attr*)>" >> $ReportFile
echo "<!ELEMENT hostname      (#PCDATA)>" >> $ReportFile
echo "<!ELEMENT datetime (#PCDATA)>" >> $ReportFile
echo "<!ELEMENT type          (#PCDATA)>" >> $ReportFile
echo "<!ELEMENT name          (#PCDATA)>" >> $ReportFile
echo "<!ELEMENT attr          (name,value)>" >> $ReportFile
echo "<!ELEMENT value         (#PCDATA)>" >> $ReportFile
echo "]>" >> $ReportFile
#echo "<computer xmlns="http://www.h-inventory.com">" >> $ReportFile
echo "<computer>" >> $ReportFile
echo "<hostname>$HOSTNAME</hostname>"  >> $ReportFile
echo "<datetime>$DATE</datetime>" >> $ReportFile
}

##################################################################################
#End of XML
##################################################################################
function endXML ()
{
echo "</computer>" >> $ReportFile
}


##################################################################################
# Check arguments
##################################################################################
check_login () {
  if [ "$debug" = 1 ]; then echo "- Check login information"; fi
  fail=0
  # Check server
  if [ -z "$server" ]; then
    echo "  Server: Fail (empty)"
    fail=1
  fi
  # Check login
  if [ -z "$user" ]; then
    echo "  Username: Fail (empty)"
    fail=1
  fi
  # Check password
  if [ -z "$password" ] && [ "$method" != scp ] ; then
    echo "  Password: Fail (empty)"
    fail=1
  fi
  # Check public_key
  if [ "$method" = scp ]; then
    if [ -z "$public_key" ]; then
      echo "  Pulic key: Fail (empty)"
      fail=1
    else
      if [ ! -f "$public_key" ]; then
        echo "  Pulic key: Fail (file $public_key not found)"
        fail=1
     fi
   fi
  fi
  # Check mountpoint
  if [ "$method" = smb ] || [ "$method" = nfs ]; then
  	if [ -z "$mountpoint" ] ; then
	    echo "  Mountpoint: Fail (empty)"
	    fail=1
	 fi
  fi
  # If failure
  if [ $fail = 1 ]; then
    echo "Error, on or more problem(s) has been found for method $method. Review your configuration."
    exit 1
  fi
  }


##################################################################################
### DIFFER BETWEEN SCRIPTS
##################################################################################


##################################################################################
# OS detection
##################################################################################
function detect_os ()
{

comment=OS
type="Operating System"
name=`uname -s`
version=`uname -r`

if [ "$name" = "Linux" ]
        then if test -f /etc/redhat-release; then
                distribution="RedHat"
                release=`cat /etc/redhat-release`
            elif test -f /etc/redhat-version; then
                distribution="RedHat"
                release=`cat /etc/redhat-version`
            elif test -f /etc/fedora-release; then
                distribution="Fedora"
                release=`cat /etc/fedora-release`
            elif test -f /etc/mandrake-release; then
                distribution="Mandrake"
                release=`cat /etc/mandrake-release`
            elif test -f /etc/SuSE-release; then
                distribution="Novell SuSE"
                release=`cat /etc/SuSE-release`
            elif test -f /etc/debian_version; then
                distribution="Debian"
                release=`cat /etc/debian_version`
            elif test -f /etc/debian-version; then
                distribution="Debian"
                release=`cat /etc/debian-version`
            elif test -f /etc/arch-release; then
                distribution="Arch"
                release=`cat /etc/arch-release`
            elif test -f /etc/gentoo-release; then
                distribution="Gentoo"
                release=`cat /etc/gentoo-release`
            elif test -f /etc/slackware-release; then
                distribution="Slackware"
                release=`cat /etc/slackware-release`
            elif test -f /etc/slackware-version; then
                distribution="Slackware"
                release=`cat /etc/slackware-version`
            elif test -f /etc/yellowdog-release; then
                distribution="Yellow dog"
                release=`cat /etc/yellowdog-release`
			elif test -f /etc/sourcemage-release; then
		 		distribution="Source Mage"
				release=`cat /etc/sourcemage-release`
            elif test -f /etc/smgl.iso; then
                distribution="Source Mage"
                release=`cat /etc/smgl.iso`
	    	else distribution="unknown"
                release="unknown"
        fi

if [ "$debug" = 1 ]; then
    if [ "$color" = 1 ]
    	then cecho "- detect_os: $comment" $green 
	     cecho "  * $type: $name" $red
    	     cecho "  * Version: $version" $blue
	     cecho "  * Distribution: $distribution" $blue
             cecho "  * Release: $release" $blue
	else echo "- detect_os: $comment"
  	     echo "  * $type: $name"
    	     echo "  * Version: $version"
	     echo "  * Distribution: $distribution"
             echo "  * Release: $release"
    fi
fi

writecomment "$comment"
writecomponent "$type" "$name ($distribution)"
writesubcomponent "version" "$version"
writesubcomponent "distribution" "$distribution"
writesubcomponent "release" "$release"
fi
writeendcomponent

}



##################################################################################
# Software detection
##################################################################################
function detect_software ()
{
TmpFileSoft="/tmp/softIM.tmp"
TmpFileSoft2="/tmp/softIM2.tmp"

comment=APPLICATIONS
type=application

writecomment "$comment"
if [ "$debug" = 1 ]; then echo "- detect_software: $comment"; fi

if [ -f  "/etc/debian_version" ]
       then
       dpkg -l |grep ^ii 2> /dev/null | while read f
       do
       soft=`echo $f |awk '{print $2}' 2> /dev/null`;
       versoft=`echo $f |awk '{print $3}' 2> /dev/null`
       description=`echo $f |awk '{print $4,$5,$6,$7,$8,$9}' 2> /dev/null`;
        if [ "$debug" = 1 ]; then echo "   * $soft ($description)"; fi
       writecomponent "$type" "$soft $versoft"
       writesubcomponent "commentaire" "$description"
       writeendcomponent
       done

fi

if [ -f "/etc/arch-release" ]
	then for soft in `pacman -Q 2> /dev/null | awk '{ print $1 }'`; do
		description=`pacman -Qi $soft | grep Description | cut -d: -f2 | cut -c2-`
		version=`pacman -Qi $soft | grep Version | cut -d: -f2 | cut -c2-`
		if [ "$debug" = 1 ]; then echo "   * $soft ($description)"; fi
		writecomponent "$type" "$soft"
		writesubcomponent "commentaire" "$description"
		writesubcomponent "version" "$version"
		writeendcomponent
		done
fi

if [ -f "/etc/redhat-release" -o -f "/etc/SuSE-release" -o -f "/etc/mandrake-release" ]
	then for soft in `rpm -qa 2> /dev/null | awk '{ print $1 }'`; do
		description=`rpm -qi $soft | grep Summary | cut -d: -f2 | cut -c2-`
		if [ "$debug" = 1 ]; then echo "   * $soft ($description)"; fi
		writecomponent "$type" "$soft"
		writesubcomponent "commentaire" "$description"
		writeendcomponent
		done
																	
fi

if [ "${distribution}" == "Gentoo" ]
then
        SOFTWARE_LIST="`mktemp /tmp/hinventory_softwares_list_tmp.XXXXXX`"
        if [ ! `which eix` ]
        then
                echo "eix binary not present, please install app-portage/eix"
                exit 1
        fi
        if [ `eix -I --format "CATEGORY=<category>; NAME=<name>; INSTALLED_VERSIONS=<installedversionsshort>; LICENCE=<licenses>; DESCRIPTION=<description>;" | grep "^CATEGORY" | sort >> ${SOFTWARE_LIST}` ]
        then
                update-eix
        fi
        while read INSTALLED_SOFTWARE
        do
                SOFTWARE_NAME=`echo ${INSTALLED_SOFTWARE} | sed "s/.*NAME=\([^;]*\).*/\1/"` 
                SOFTWARE_DESCRIPTION=`echo ${INSTALLED_SOFTWARE} | sed "s/.*DESCRIPTION=\([^;]*\).*/\1/"`
                SOFTWARE_VERSION=`echo ${INSTALLED_SOFTWARE} | sed "s/.*INSTALLED_VERSIONS=\([^;]*\).*/\1/"`
                # Not implemented yet
                #SOFTWARE_CATEGORY=`echo ${INSTALLED_SOFTWARE} | sed "s/.*CATEGORY=\([^;]*\).*/\1/"`
                #SOFTWARE_LICENCE=`echo ${INSTALLED_SOFTWARE} | sed "s/.*LICENCE=\([^;]*\).*/\1/"`
                
                writecomponent "$type" "${SOFTWARE_NAME}"
                # Gentoo admins may prefer this output :
                #writecomponent "$type" "${SOFTWARE_CATEGORY}/${SOFTWARE_NAME}"
                writesubcomponent "commentaire" "${SOFTWARE_DESCRIPTION}"
                writesubcomponent "version" "${SOFTWARE_VERSION}"
                # Not implemented yet
                #writesubcomponent "license" "${SOFTWARE_LICENCE}"
                writeendcomponent
        done < ${SOFTWARE_LIST}
 
#        rm ${SOFTWARE_LIST}
fi

if [ "${distribution}" == "Source Mage" ]
then
        SOFTWARE_LIST="`mktemp /tmp/hinventory_softwares_list_tmp.XXXXXX`"
        if [ ! `which gaze` ]
        then
                echo "Are you sure you are running sorcery?"
                exit 1
        fi
        gaze installed > $SOFTWARE_LIST
        while read INSTALLED_SOFTWARE
        do
                SOFTWARE_NAME=`echo ${INSTALLED_SOFTWARE} | cut -d":" -f1` 
                SOFTWARE_DESCRIPTION=`gaze -q short ${SOFTWARE_NAME} | cut -d":" -f1 | tr "\n" " "`
                SOFTWARE_VERSION=`echo ${INSTALLED_SOFTWARE} | cut -d":" -f4`
                # Not implemented yet
                SOFTWARE_CATEGORY=`gaze -q where ${SOFTWARE_NAME} | head -n1`
                SOFTWARE_LICENCE=`gaze -q license ${SOFTWARE_NAME} | tail -n2 | head -n1 | cut -d"|" -f2`
                
                writecomponent "$type" "${SOFTWARE_NAME}"
                writesubcomponent "commentaire" "${SOFTWARE_DESCRIPTION}"
                writesubcomponent "version" "${SOFTWARE_VERSION}"
                writesubcomponent "license" "${SOFTWARE_LICENCE}"
                writeendcomponent
        done < ${SOFTWARE_LIST}
 
        rm ${SOFTWARE_LIST}
fi

}

##################################################################################
#Detection PACKAGES UPDATE ON DEBIAZN
##################################################################################

function detect_update ()
{
comment=UPDATES
type=updates

writecomment "$comment"

if [ -f  "/etc/debian_version" ] && [ -x '/usr/bin/apt-show-versions' ]
         then echo "Check softwares updates in progress"
	        for soft in `apt-show-versions -u |awk '{print $1}'| cut -d/ -f1  2>/dev/null`; do
                versions=`apt-show-versions -u | grep $soft | tail -n1 |awk '{print $4,$5,$6}' 2>/dev/null`
		writecomponent "$type" "$soft"
                writesubcomponent "versions" "$versions"
                writeendcomponent
         	done

fi
}
##################################################################################
#CPU detection (a finir) pb si different proc
# Compat: FreeBSD
##################################################################################
function detect_cpu ()
{
if [ -e /proc/cpuinfo ]; then
{
comment=CPU
type=CPU

writecomment "$comment"

#CPU Type
if [ "`grep "Alpha" /proc/cpuinfo | cut -d: -f2 | cut -c2- | uniq`" = "Alpha" ]; then
 cputype=Alpha
else
 cputype=i386
fi

case "$cputype" in
 Alpha )
  cpuname=`grep "cpu model" /proc/cpuinfo | cut -d: -f2 | cut -c2- | uniq`
  cpuname=`echo Alpha $cpuname`
  nbcpu=`grep "cpus detected" /proc/cpuinfo | wc -l`
  if [ -f /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ]; then
    cpufreq=`cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq`
    cpufreq=`expr $cpufreq / 1000`
  else
    cpufreq=`grep "timer frequency" /proc/cpuinfo| cut -d: -f2 | cut -c2- | cut -d. -f1 | uniq`
  fi
 ;;
 * )
  cpuname=`grep "model name" /proc/cpuinfo  | cut -d: -f2 | cut -c2- | uniq`
  nbcpu=`cat /proc/cpuinfo | grep "processor" | wc -l`
  if [ -f /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ]; then
    cpufreq=`cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq`
    cpufreq=`expr $cpufreq / 1000`
  else
    cpufreq=`grep "cpu MHz" /proc/cpuinfo| cut -d: -f2 | cut -c2- | cut -d. -f1 | uniq`
  fi
 ;;
esac

while [ $nbcpu -ne 0  ]
do
NAME=$cpuname
if [ "$debug" = 1 ]; then
    echo "- detect_cpu: $comment"
    echo "  * Name: $cpuname"
    echo "  * Frequency: $cpufreq MHz"
  fi
writecomponent "$type" "$NAME"
nbcpu=`expr $nbcpu - 1`
writesubcomponent "speed" "$cpufreq"
writeendcomponent
done
}
fi
}


##################################################################################
#Mem detection 
##################################################################################
function detect_ram ()
{
if [ -e /proc/meminfo ]; then
{
RAMsizekb=`cat /proc/meminfo | grep MemTotal | tr -d ' ' | cut -d':' -f2 | tr -d 'kB'`
RAMsize=`expr $RAMsizekb / 1024`

comment="Memory"
type="Physical Memory"
NAME="Physical Memory"

if [ "$debug" = 1 ]; then
    echo "- detect_ram: $comment"
    echo "  * Size: $RAMsize MB"
  fi
writecomment "$comment"
writecomponent "$type" "$NAME"
writesubcomponent "size" "$RAMsize"
writeendcomponent
}
fi
}

##################################################################################
# Swap detection
##################################################################################
function detect_swap ()
{
swaptotal=`free -m |grep Swap|awk '{print $2}'`
#swapused=`free -m |grep Swap|awk '{print $3}'`
#swapfree=`free -m |grep Swap|awk '{print $4}'`
#swapused=`swapinfo | tail -n1 |awk '{ print $3 }'`
#swapfree=`swapinfo | tail -n1 |awk '{ print $4 }'`
#swapusage=`swapinfo | tail -n1 |awk '{ print $2 }'`

type="Audit"
name="Virtual Memory"

if [ "$debug" = 1 ]; then
    echo "- detect_swap: $comment"
    echo "  * Size: $swaptotal MB"
fi

writecomment "$comment"
writecomponent "$type" "$name"
writesubcomponent "size" "$swaptotal"
writeendcomponent

}


##################################################################################
# ide
##################################################################################

function detect_ide ()
{
if [ -e /proc/ide ]; then
{
comment=IDE
writecomment "$comment"

interface=IDE
for disk in `ls /proc/ide | grep hd`
do
media=`cat /proc/ide/$disk/media`
if [ $media == disk ]
	then size=`$dmesgvar | grep $disk | grep MB | cut -d"(" -f2 | cut -d")" -f1 |cut -d" " -f1`
	     name=`cat /proc/ide/$disk/model` 
	     type="Hard Disk"
	     if [ "$debug" = 1 ]; then echo "- detect_ide: $comment"; fi
	     if [ "$debug" = 1 ]; then echo "  * $disk: $name [$size MB] ($interface)"; fi
	     writecomponent "$type" "$name"
	     writesubcomponent "size" "$size"
	     writesubcomponent "interface" "$interface"
	     writeendcomponent
fi
if [ $media == cdrom ]
	then name=`cat /proc/ide/$disk/model`
             type="CD/DVD Drive"
	     if [ "$debug" = 1 ]; then echo "- detect_ide: $comment"; fi
	     if [ "$debug" = 1 ]; then echo "  * $disk: $name ($interface)"; fi
             writecomponent "$type" "$name"
	     writesubcomponent "interface" "$interface"
	     writeendcomponent
fi
done
}
fi
}

##################################################################################
# SCSI
##################################################################################

function detect_scsi ()
{
if [ -e /proc/scsi ]; then
{
  comment=SCSI
  writecomment "$comment"
  interface=SCSI
  if [ -e /sys/bus/scsi/ ]; then
  {
		for disk in `ls /sys/block/|grep "^sd"`
		do
			type="Hard Disk"
			model=`cat /sys/block/$disk/device/model`
	  	vendor=`cat /sys/block/$disk/device/vendor`
		  size=`$dmesgvar | grep -m 1 "SCSI device $disk"|cut -d "(" -f 2|cut -d " " -f 1`
			
			name="$vendor $model"
			
			if [ "$debug" = 1 ]; then echo "- detect_scsi: $comment"; fi
	    if [ "$debug" = 1 ]; then echo "  * $disk: $name [$size MB] ($interface)"; fi
	    writecomponent "$type" "$name"
	    writesubcomponent "size" "$size"
	    writesubcomponent "interface" "$interface"
	    writeendcomponent

		done
	}
	else
	{
	  nb=1
	  vendor=`sed 1d /proc/scsi/scsi | grep Vendor | cut -d: -f2 | cut -d" " -f2`
	  model=`sed 1d /proc/scsi/scsi |  grep Model | cut -d: -f3 | cut -d" " -f2`
	  for disk in `$dmesgvar | grep scsi | grep sd | cut -d" " -f4`
	  do
	    type="Hard Disk"
	    size=`$dmesgvar | grep -w $disk: | grep MB | cut -d"(" -f2 | cut -d" " -f1 | uniq`
	    vendordisk=`echo $vendor | cut -d" " -f$nb`
	    modeldisk=`echo $model | cut -d" " -f$nb`
	    nb=`expr $nb + 1`
	    name=`echo $vendordisk $modeldisk`

	    if [ "$debug" = 1 ]; then echo "- detect_scsi: $comment"; fi
	    if [ "$debug" = 1 ]; then echo "  * $disk: $name [$size MB] ($interface)"; fi
	    writecomponent "$type" "$name"
	    writesubcomponent "size" "$size"
	    writesubcomponent "interface" "$interface"
	    writeendcomponent
	  done
	}
	fi
#   ORIG_IFS=$IFS
#
#   IFS=$'\t\n';
#
#   for disk in $model
#   do
#     IFS=$ORIG_IFS
#     type="Hard Disk"
#     modeldisk=$disk
#     vendordisk=`grep -m 1 $disk /proc/scsi/scsi|cut -d: -f2|awk '{ print substr($0,2,index($0,"Model")-4) }'`
#     size=`cat /var/log/dmesg | grep -w "$disk:" | grep MB | cut -d"(" -f2 | cut -d" " -f1 | uniq`
#     echo $vendordisk: $modeldisk - $size
#     IFS=$'\t\n';
#   done
  }
fi
}

##################################################################################
#Floppy 
##################################################################################
function detect_floppy ()
{

name=`$dmesgvar | grep Floppy | cut -d: -f2 | cut -c2- | cut -d" " -f1`
if ! [ -z $name ]
then
comment=FLOPPY
writecomment "$comment"
size=`$dmesgvar | grep Floppy | cut -d: -f2 | cut -c2- | cut -d" " -f3 | cut -d"M" -f1`
if [ "$debug" = 1 ]; then echo "- detect_floppy: $comment"; fi
             if [ "$debug" = 1 ]; then echo "  * floppy: generic $name ($size MB)"; fi
             writecomponent "floppy" "generic"
             writesubcomponent "size" "$size"
             writeendcomponent
fi
}
##################################################################################
#local filesystems
##################################################################################
function detect_filesystems()
{

comment=FILESYSTEMS
writecomment "$comment"

IFS=$'\t\n';

if [ "$debug" = 1 ]; then echo "- detect filesystems: $comment"; fi

for fs in `df -h -T -P -l|grep -v "^Filesystem"|awk '{ print $1 " " $2 " " $3 " " $4 " " $5 " " $6 " " $7}'`
do
  type="Filesystem"
  dev=`echo $fs|cut -d " " -f 1`
  writecomponent "$type" "$dev"
	writesubcomponent "dev" "$dev"
  fstype=`echo $fs|cut -d " " -f 2`
	writesubcomponent "fstype" "$fstype"
  size=`echo $fs|cut -d " " -f 3`
	writesubcomponent "size" "$size"
  used=`echo $fs|cut -d " " -f 4`
	writesubcomponent "used" "$used"
  avail=`echo $fs|cut -d " " -f 5`
	writesubcomponent "avail" "$avail"
  use=`echo $fs|cut -d " " -f 6`
	writesubcomponent "use" "$use"
  mpoint=`echo $fs|cut -d " " -f 7`
	writesubcomponent "mpoint" "$mpoint"
	writeendcomponent
	
	if [ "$debug" = 1 ]; then echo "  * found $dev ($fstype) on $mpoint"; fi
	
  # echo $dev " " $type " " $size " " $used " " $avail " " $use " " $mpoint
done

}


##################################################################################
#SOFTWARE RAID detection
##################################################################################
function detect_raid ()
{
	if [ "$debug" = 1 ]; then echo "- detect_raid: Software Raid"; fi 
	if [ -e "/sys" ]; then
	{
		type="SoftwareRaid"
		for md in `ls /sys/block/|grep "^md[0-9]$"`; do
			writecomment $type
			writecomponent $type $md
			if [ -e "/sys/block/$md/md" ]; then
			{
		  	level=`cat /sys/block/$md/md/level`
				writesubcomponent "level" $level
		    state=`cat /sys/block/$md/md/sync_action`
				writesubcomponent "state" $state
		    disks=''
		    for disk in `ls /sys/block/$md/md/|grep "^dev-[s|h]d[a-z][0-9]$"|cut -d "-" -f 2`; do
		    	disks=$disks",$disk"
		    done
				writesubcomponent "devices" $disks
			}
      else {
        line=`grep "$md" /proc/mdstat|cut -d ":" -f 2`
        level=`echo $line|awk '{ print $2 }'`
        writesubcomponent "level" $level
        writesubcomponent "state" "unknown" 
        line=`echo $line|awk '{ for(i=3;i<=NF;i++) { print $i }  }'` 
        disks=''
        for disk in $line; do
          disks="$disks,"`echo $disk|cut -d "[" -f 1`
        done
        writesubcomponent "devices" $disks
      }
			fi
	    if [ "$debug" = 1 ]; then echo "  * RAID Device $md found"; fi
			writeendcomponent
		done;
	}
  else
  {
    ORIG_IFS=$IFS

    IFS=$'\t\n';

		type="SoftwareRaid"
		
    for md in `grep "^md[0-9]" /proc/mdstat`; do
        line=`echo $md|cut -d ":" -f 2`

        md=`echo $md|cut -d ":" -f 1`
				
				writecomponent $type $md

				level=`echo $line|awk '{ print $2 }'`

        writesubcomponent "level" $level
        writesubcomponent "state" "unknown"

        line=`echo $line|awk '{ for(i=3;i<=NF;i++) { print $i }  }'`

        disks=''
        for disk in $line; do
          disks="$disks,"`echo $disk|cut -d "[" -f 1`
        done

        writesubcomponent "devices" $disks
				writeendcomponent
    done

    IFS=$ORIG_IFS
  }
	fi
}


##################################################################################
#PCI detection
##################################################################################
function detect_pci ()
{
pcilist=`lspci -vm`

comment="Cards"
writecomment "$comment" 

if [ "$debug" = 1 ]; then echo "- detect_pci: $comment"; fi

perif=`lspci -vm | grep "[[:digit:]]:[[:digit:]]" | cut -f2`

for i in $perif; do

type=`echo "$pcilist" | grep -w $i -A 4 | grep -w "Class:" | cut -d":" -f2 | cut -f2`
name=`echo "$pcilist" | grep -w $i -A 4 | grep -v "[[:digit:]]:[[:digit:]]" | grep -w "Device:" | cut -d":" -f2 | cut -f2`
mark=`echo "$pcilist" | grep -w $i -A 4 | grep -w "Vendor:" | cut -d":" -f2 | cut -f2`

if [ "$type" != "Ethernet controller" ] && [ "$type" != "Network controller" ]
then 
	if [ "$type" == "SCSI storage controller" ]; then type="SCSI Controller"; fi
	if [ "$type" = "IDE interface" ]; then type="IDE Controller";fi
	if [ "$type" = "VGA compatible controller" ]; then type="Graphic Card"; fi
	
	if [ "$debug" = 1 ]; then echo "  * $i: $name - $mark ($type)"; fi
	
	writecomponent "$type" "$name"
	writesubcomponent "manufacturer" "$mark"
	writeendcomponent	
fi

done
}



##################################################################################
#Network detection
##################################################################################
function detect_network ()
{
comment=NETWORK
pcieth=`lspci -vm | grep -A2 "Ethernet controller"; lspci -vm | grep -A2 "Network controller"`


if [ "$debug" = 1 ]; then echo "- detect_network: $comment"; fi

for i in `$ifconfig -a | grep [Ee]th | cut -d" " -f1`
do 
name=`echo "$pcieth" | grep -w "Device:" | cut -d: -f2 | cut -c2- |head -n1`
manuf=`echo "$pcieth" | grep -w "Vendor:" | cut -d: -f2 | cut -c2- |head -n1`
ip=`$ifconfig $i | grep -w inet | cut -d":" -f2 | cut -d" " -f1`
if [ "$i" == "bond" ]
then mac=`$ifconfig $i | grep -w Ethernet | cut -d" " -f10`
else mac=`$ifconfig $i | grep -w Ethernet | cut -d" " -f11`
fi
subnetmask=`$ifconfig $i |grep inet |awk '{print $4}' |cut -f2 -d ":" |head -n1`
type="Network Adapter"

pcieth=`echo "$pcieth" | sed 1,4d`


writecomponent "$type" "$name"

if [ -z "$ip" ]; then ip="0.0.0.0"; fi
if [ -z "$subnetmask" ]; then subnetmask="0.0.0.0"; fi
if [ "$debug" = 1 ]; then echo "  * $i: $name - $manuf - MAC: $mac IP: $ip"; fi

writesubcomponent "manufacturer" "$manuf"
writesubcomponent "mac" "$mac"
writesubcomponent "ip" "$ip"
writesubcomponent "subnetmask" "$subnetmask"
writeendcomponent
done
}


##################################################################################
#Disk Audit
##################################################################################
function disk_audit ()
{
comment=DISK
if [ "$debug" = 1 ]; then echo "- disk_audit: $comment"; fi

nb=`df -lPThm | wc -l`
nbdisk=`expr $nb - 1`

type="Audit"

for part in `df -lPThm | tail -n $nbdisk | awk '{ printf "%s;%s;%s;%s;%s;%s;%s\n", $1, $2, $3, $4, $5, $6, $7 }'`; do
  name=`echo $part | cut -d";" -f1`
  filesystem=`echo $part | cut -d";" -f2`
  size=`echo $part | cut -d";" -f3`
  used=`echo $part | cut -d";" -f4`
  available=`echo $part | cut -d";" -f5`
  percent=`echo $part | cut -d";" -f6`
  mount=`echo $part | cut -d";" -f7`

writecomponent "$type" "Partition $name"

writesubcomponent "filesystem" "$filesystem"
writesubcomponent "size" "$size"
writesubcomponent "freespace" "$available"
writesubcomponent "used" "$used"
writesubcomponent "percent" "$percent"
writesubcomponent "mountpoint" "$mount"

writeendcomponent 
done

if [ -e "/sbin/vgdisplay" ]; then
{
  if [ "$debug" = 1 ]; then echo "- disk_audit: LVM detected"; fi

  for VG in `/sbin/vgs --noheading --separator : --units g 2>/dev/null|cut -d " " -f 3`
  do
    type="Audit"
	writecomponent "$type" "Volume Group"
    vg_name=`echo $VG|cut -d ":" -f 1`
		writesubcomponent "name" "$vg_name"
    lv_num=`echo $VG|cut -d ":" -f 3`
		writesubcomponent "lvnumber" "$lv_num"
    vg_size=`echo $VG|cut -d ":" -f 6`
		writesubcomponent "size" "$vg_size"
    vg_free=`echo $VG|cut -d ":" -f 7`
		writesubcomponent "free" "$vg_free"
		writeendcomponent
    if [ "$debug" = 1 ]; then echo "  * VG $vg_name found"; fi
  done

  for LV in `/sbin/lvs --noheading --separator : --units g 2>/dev/null|cut -d " " -f 3`
  do
    type="Audit"
	writecomponent "$type" "Logical Volume"
    lv_name=`echo $LV|cut -d ":" -f 1`
		writesubcomponent "name" "$lv_name"
    lv_vg=`echo $LV|cut -d ":" -f 2`
		writesubcomponent "vg" "$lv_vg"
    lv_size=`echo $LV|cut -d ":" -f 4`
		writesubcomponent "size" "$lv_size"
		writeendcomponent
    if [ "$debug" = 1 ]; then echo "  * LV $lv_name found"; fi
  done
} 
fi

}

##################################################################################
#UPTIME
##################################################################################
function detect_uptime ()
{
comment=UPTIME
type="Audit"
uptime=`uptime | cut -d, -f1 | awk '{print $3}'`
writecomponent "$type" "uptime"
writesubcomponent "uptime" "$uptime"
writeendcomponent
}

##################################################################################
#USERS
##################################################################################
function detect_users ()
{
	comment=USERS
	type="Audit"
	users=`users`
	writecomponent "$type" "users"
	writesubcomponent "users connected" "$users"
	writeendcomponent
}

##################################################################################
#Upload XML file
##################################################################################
uploadXML () {
  case $method in
    local) exit 0 ;;
    ### Upload SCP
    scp)
      if [ "$debug" = 1 ]; then echo "- Starting upload on scp://${user}@${server}/${remote_path}"; fi
      scp -i $public_key $ReportFile $user@$server:$remote_path
      if [ $? = 0 ]; then
        echo "  * Report succesfully uploaded on $server."
      else
        echo "  * Unable to upload report file on $server."
      fi
    ;;
   ### Upload SOAP
   soap)
if [ -f "hisoap_client.pl" ]
        then ./hisoap_client.pl $ReportFile
else if [ -f "/bin/hisoap_client.pl" ]
        then /bin/hisoap_client.pl $ReportFile   
fi
fi
;;
  ### Upload HTTP
  http)
  if [ "$debug" = 1 ]; then echo "- Starting upload on http://${user}@${server}${remote_path}"; fi
  
curl -F file1=@$ReportFile -u ${user}:${password} -F SubBtn=OK ${server}${remote_path};
  #  ./http_upload.pl 
    ;;
  ### Upload FTP
  ftp)
    if [ "$use_ssl" ]  && [ -x /usr/bin/ftp-ssl ];
        then ftp=ftp-ssl
        else ftp=ftp
    fi
    if [ "$debug" = 1 ]; then echo "- Starting upload on $ftp://${user}@${server}/${remote_path}"; fi
      $ftp -ipn $server $port << EOF
user ${user} ${password}
binary
cd $remote_path
put $ReportFile
quit
EOF
    if [ $? = 0 ]; then
      echo "  * Report succesfully uploaded on $server."
    else
      echo "  * Unable to upload report file on $server."
    fi
  ;;
### Upload SMB
  smb)
    if [ "$debug" = 1 ]; then echo "- Starting upload on smb://${user}@${server}/${remote_path}"; fi
    if [ -e $mountpoint ]
       then
       echo
       else
       mkdir $mountpoint
       fi
       mount -t smbfs -o username=$user,password=$password //$server/$remote_path $mountpoint
       cp $ReportFile $mountpoint
    if [ $? = 0 ]; then
      echo "  * Report succesfully uploaded on $server."
    else
      echo "  * Unable to upload report file on $server."
    fi
       umount $mountpoint

    ;;
### Upload NFS
  nfs)
	if [ "$debug" = 1 ]; then echo "- Starting upload on nfs://${user}@${server}:${remote_path}"; fi
	if [ -e $mountpoint ]
       then
       echo
       else
       mkdir $mountpoint
       fi
       mount -t nfs $server:$remote_path $mountpoint
       cp $ReportFile $mountpoint
      if [ $? = 0 ]; then
        echo "  * Report succesfully uploaded on $server."
      else
        echo "  * Unable to upload report file on $server."
      fi
       umount $mountpoint
	;;
  esac
  rm -f $ReportFile
  }

#############HTTP####################
# user pass
#--http-user=USAGER      utiliser le nom de l'USAGER http.
#--http-passwd=MOT_DE_PASSE
# get --post-file


##################################################################################
##################################################################################
# MAIN
##################################################################################
##################################################################################
blnConfFile="false"
if [ -f "/etc/hinventory.conf" ]
then ConfFile="/etc/hinventory.conf"
     blnConfFile="true"
else if [ -f "/etc/hinventory_Linux.conf" ]
	then ConfFile="/etc/hinventory.conf"
	     blnConfFile="true"
     	else if [ -f "`dirname $0`/hinventory.conf" ]
		then ConfFile=`dirname $0`/hinventory.conf
	             blnConfFile="true"
		else if [ -f "`dirname $0`/hinventory_Linux.conf" ]
			then ConfFile="`dirname $0`/hinventory_Linux.conf"
			     blnConfFile="true"
		     fi
		fi	
	fi
fi

if [ $blnConfFile == false ]; then
	echo "Fatal error, configuration file is missing."
  exit 1
else

  # Checking conf
  . $ConfFile

  case $debug in
    0) ;;
    1)
      echo "- Parsing configuration file: $ConfFile" 
      echo "  * debug=$debug"
      ;;
    xml) ;;
    *) echo "Fatal error, debug mode not supported, choose : debug=[0][1][2]"; exit 1;;
  esac

  if [ -z "$remote_path" ]; then
    remote_path=.
  fi

  if [ "$debug" = 1 ]; then
    echo "  * method=$method"
    echo "  * server=$server"
    echo "  * remote_path=$remote_path"
    echo "  * mountpoint=$mountpoint"
    echo "  * user=$user"
    echo "  * password=[XXX]"
    echo
  fi

case $method in
    ftp)
      check_login
      ;;
    http)
      check_login
      ;;
    soap)
      ;;
    local)
      ;;
    smb)
      check_login
      ;;
    nfs)
      check_login
      ;;
    scp)
      check_login
      ;;
    *)
       echo "Fatal error, method not supported, choose : ftp, http, local, smb, nfs or scp"
       exit 1
       ;;
  esac
fi

timedeb=`date "+%s"`
beginXML

detect_cpu
detect_ram
detect_ide
detect_scsi
detect_floppy
detect_network
detect_pci
detect_os
###audit###
if checkyesno test_software; then detect_software; fi
if checkyesno test_audit; then disk_audit; detect_swap; detect_uptime; detect_users; fi
if checkyesno test_update; then detect_update; fi

timefin=`date "+%s"`
detect_script $timedeb $timefin
endXML
timecmd $timedeb $timefin
if [ "$debug" = 1 ]; then
	echo "- Temps d execution:"
	echo $timeres
fi
uploadXML
