#!/bin/bash

# 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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.



function parsecmd(){
# parse given command line ordering arguments in arg[]
# if an argument requires a parameter it's stored in val[]

while [ $OPTIND -le $# ]; do
        getopts :maF:birhvs opt
        case $opt in
                m) arg[0]=m ;;
                a) arg[1]=a ;;
                F) arg[2]=F
                   val[0]=$OPTARG ;;
                b) arg[3]=b ;;
                i) arg[4]=i ;;
                r) arg[5]=r ;;
                h) arg[6]=h ;;
                v) arg[7]=v ;;
		s) arg[8]=s ;;
		*) printhelp
		   exit 1 ;;
        esac
        i=`expr $i + 1`
done
}

printhelp(){
# print the help on line
	
	versioninfo
	cat << ENDOFHELP
usage: procinfo [-smaihv] [-Ffile]

        -s      display memory, disk, IRQ & DMA info (default)
        -m      display module and device info
        -a      display all info

        -i      show all IRQ channels, not just those used
        -r      show memory usage -/+ buffers/cache
        -Ffile  print output to file -- normally a tty
        -v      print version info
        -h      print this help

ENDOFHELP
}

function versioninfo(){
# print version

	echo "This is procinfo version 0.1alpha-pre :)"
}

function hostversion(){
# print os version, num of cpu and fqdn
	
	VERSION=`cat /proc/version`
	TOTCPU=`grep -c processor /proc/cpuinfo`
	HOSTNAME=`cat /proc/sys/kernel/hostname`
	DOMAIN=`cat /proc/sys/kernel/domainname`

	echo -e "$VERSION ${TOTCPU}CPU  [$HOSTNAME.$DOMAIN]\n"
}

function meminfo(){
# print info related to memory (total, used, free, shared, buffers ecc)
# here we check also if "-r" is set

	MEMINFO=`cat /proc/meminfo`

	MEMTOTAL=`echo -e "$MEMINFO" | grep MemTotal | awk '{print $2}'`
	MEMFREE=`echo -e "$MEMINFO" | grep MemFree | awk '{print $2}'`
	MEMBUF=`echo -e "$MEMINFO" | grep Buffers | awk '{print $2}'`
	MEMUSED=`expr $MEMTOTAL - $MEMFREE`
	MEMCACHED=`echo -e "$MEMINFO" | grep ^Cached: | awk '{print $2}'`
	SWAPTOTAL=`echo -e "$MEMINFO" | grep SwapTotal | awk '{print $2}'`
	SWAPFREE=`echo -e "$MEMINFO" | grep SwapFree | awk '{print $2}'`
	SWAPUSED=`expr $SWAPTOTAL - $SWAPFREE`
	BUFFCACHEUSED=`expr $MEMUSED - $MEMBUF - $MEMCACHED`
	BUFFCACHEFREE=`expr $MEMFREE + $MEMBUF + $MEMCACHED`    

	# according to man 1 free shared is obsolete, we don't look further and we simply
	# print zero
	echo -e "Memory:\t\tTotal\t\tUsed\t\tFree\t\tShared\t\tBuffers"
	echo -e "Mem:\t\t$MEMTOTAL\t\t$MEMUSED\t\t$MEMFREE\t\t0\t\t$MEMBUF"
	if [[ ${arg[5]} = r ]] ; then
		echo -e "-/+ buffers:\t\t\t$BUFFCACHEUSED\t\t$BUFFCACHEFREE"
	fi
	echo -e "Swap:\t\t$SWAPTOTAL\t\t$SWAPUSED\t\t$SWAPFREE\n"
}

function bootloadavg() {
# print boot time (in UTC) and load average

	BOOTTIME=`date -ud "1970-01-01 $(grep btime /proc/stat | awk '{print $2}') seconds"`
	LOADAVG=`cat /proc/loadavg`

	echo -e  "Bootup: $BOOTTIME\tLoad average:\t$LOADAVG\n"
}


function modetime() {
# print info on user/nice/idle/system time and some disk stats

	STAT=`cat /proc/stat`

	STAT_CPU=`echo -e "$STAT" | grep '\<cpu\>'`
	USER=`echo $STAT_CPU | cut -d ' ' -f 2`
	NICE=`echo $STAT_CPU | cut -d ' ' -f 3`
	SYST=`echo $STAT_CPU | cut -d ' ' -f 4`
	IDLE=`echo $STAT_CPU | cut -d ' ' -f 5`
	UPTIME=`expr $USER + $NICE + $SYST + $IDLE`
	USR_PRC=`expr  $USER \* 100 \/ $UPTIME`.`expr $(expr $USER \* 100 \% $UPTIME) \* 10 \/ $UPTIME`
	NCE_PRC=`expr  $NICE \* 100 \/ $UPTIME`.`expr $(expr $NICE \* 100 \% $UPTIME) \* 10 \/ $UPTIME`
	SYS_PRC=`expr  $SYST \* 100 \/ $UPTIME`.`expr $(expr $SYST \* 100 \% $UPTIME) \* 10 \/ $UPTIME`
	IDL_PRC=`expr  $IDLE \* 100 \/ $UPTIME`.`expr $(expr $IDLE \* 100 \% $UPTIME) \* 10 \/ $UPTIME`
	STAT_CTXT=`echo "$STAT" | grep ctxt | cut -d ' ' -f 2`

	# in 2.6 kernel page and swap info are in /proc/diskstat
	# procinfo doesn't look in that file, so we print a default value "0"
	# for the same reason we ignore "-b" :)
	echo -e "user:\t\t$USER\t$USR_PRC%\t\tpage in:\t0"
	echo -e "nice:\t\t$NICE\t$NCE_PRC%\t\tpage out:\t0"
	echo -e "system:\t\t$SYST\t$SYS_PRC%\t\tswap in:\t0"
	echo -e "idle:\t\t$IDLE\t$IDL_PRC%\t\tswap out:\t0"
	echo -e "uptime:\t\t$UPTIME\t\t\tcontext:\t$STAT_CTXT\n"
}

function irqs() {
# print irq info, here we check also if "-i" option has been called

	STAT=`cat /proc/stat`

        IRQ_VALS=`echo -e "$STAT" | grep intr | sed -e 's/^intr [0-9]* //'`
        NUM_IRQ=`echo -e "$IRQ_VALS" | wc -w`
        INTERRUPTS=`cat /proc/interrupts`

        if [ "${arg[4]}" == 'i' ]; then
                i=0
                for irqval in $IRQ_VALS
                do
                        IRQ_DESC=`echo "$INTERRUPTS" | grep "\<$i\>:" | sed -e 's/^ *[0-9]*: *[0-9]* *[A-Za-z]* *//'`
                        echo -e "irq $i: $irqval\t$IRQ_DESC"
                        i=`expr $i + 1`
                done
        else
                i=0
                for irqval in $IRQ_VALS
                do
                        IRQ_DESC=`echo "$INTERRUPTS" | grep "\<$i\>:" | sed -e 's/^ *[0-9]*: *[0-9]* *[A-Za-z]* *//'`
                        if [ "$IRQ_DESC" != "" ]; then
                                echo -e "irq $i: $irqval\t$IRQ_DESC"
                        fi
                        i=`expr $i + 1`
                done
        fi

        echo -e "\n"
}       

function kcmd() {
# print command line given to kernel @ boot time

	KCMDLINE=`cat /proc/cmdline`
	
	echo -e "Kernel Command Line:\n\t$KCMDLINE\n"
}

function modulesinfo() {
# print size / used / name for each module loaded

	MODULES=`cat /proc/modules`

	echo "Modules:"
	MODNUM=`echo "$MODULES" |wc -l`
	COUNT=1
	while [ $COUNT -le $MODNUM ]; do
		MODCURR=`echo "$MODULES" | sed -ne "${COUNT}p"`
		MODNAME=`echo "$MODCURR" | cut -d ' ' -f1`
		MODSIZE=`expr $(echo "$MODCURR" | cut -d ' ' -f2) / 1024`
		MODUSED=`echo "$MODCURR" | cut -d ' ' -f3`
		echo -n "$MODSIZE "
		if [ $MODUSED != 0 ]; then
			echo -n "*"
		  else
			echo -n " "
		fi
		echo -ne "$MODNAME\t"
		COUNT=`expr $COUNT + 1`
	done
	echo
}	

function devlist() {
# print devices list

	DEVICES=`cat /proc/devices`

	echo -e "$DEVICES\n"
}

function filesys() {
# print the list of supported filesystem

	FILESYSTEMS=`cat /proc/filesystems`

	echo "File Systems:"
	NODEV=`echo "$FILESYSTEMS" | grep nodev | cut -f2`
	for fs in $NODEV
	do
		echo -n "[$fs] "
	done
	echo
	DEV=`echo "$FILESYSTEMS" | grep -v nodev | cut -f2`
	echo $DEV
	echo
}
