#!/bin/ksh
# Display disk attributes
# @(#) W. S., 25.09.2001
# src: ~wolfgang/WS_ASP/devattr.ksh
# Information is collected from following sources:
# a) ls -l /dev/dsk: soft links logical disk names -> physical disk names
# b) ls -l /dev/diskette?*: soft links logical floppy names -> physical
#    floppy names
# c) /etc/path_to_inst: paths of installed devices
# d) modinfo command: major device no's, comments concerning drivers


# 1. Construct list paths ./. disks / CD-ROM's & floppies:
#    Device paths and names are extracted from soft links in /dev/dsk
#    and /dev/diskette?*. Slice ID's are stripped.
#    Results are e. g. 
#    /pci@0,0/pci-ide@7,1/ide@0/cmdk@0,0 c0d0
#    -------------- path --------------- disk/CR-ROM
#    /isa/fdc@1,3f0/fd@0,0 diskette0
#    ------- path --------  floppy

#    Disks / CD-ROM's:

ls -l /dev/dsk |
 nawk 'BEGIN {FS="(devices|[ \t]+|:[a-z]+)"}
       NR>2  {slice=match($9,/[ps]/)		# slice pos.
              print $12,substr($9,1,slice-1)	# path, disk
             }' > /tmp/dev_list  		# w/o slice ID

#    Floppies:

ls -l /dev/diskette?* |
 nawk 'BEGIN {FS="(devices|[ \t]+|:[a-z]+)"}
             {print $12, substr($9,6)		# path, floppy
             }' >> /tmp/dev_list

#    Get rid of multiple entries:

sort -u /tmp/dev_list -o /tmp/dev_list

# 2. Construct list path ./. controller:
#    Controller paths and names are extracted from device paths
#    and names; driver names and LUN's are stripped. For floppies,
#    controller names are constructed as f<floppy no.> (e. g. f0).
#    Results are e. g.
#    /pci@0,0/pci-ide@7,1/ide@0 c0
#    --------- path ----------- ctrl (disk, CD)
#    /isa/fdc@1,3f0 f0
#    ---- path ---- floppy

rm /tmp/ctrl_list 2>/dev/null
while read path contrl
do
   path=$(dirname $path)			# strip driver
   if [[ $contrl = c* ]]			# disk / CD?
   then
     typeset -L2 ctrl=$contrl			# yes - c0 etc.
   else
     typeset -R1 tmp=$contrl			# no - floppy-no.
     typeset -L2 ctrl="f"$tmp			# f<floppy-no.>	
   fi
   print $path $ctrl >> /tmp/ctrl_list
done < /tmp/dev_list 

#    Get rid of multiple entries:

sort -u /tmp/ctrl_list -o /tmp/ctrl_list

# 3. Get paths ./. instance-no's for installed controllers & devices:
#    Excerpt from /etc/path_to_inst

rm /tmp/inst_list 2>/dev/null
for inst in "/tmp/dev_list" "/tmp/ctrl_list"
do
   while read path garbage			# get path
   do
      grep \"$path\" /etc/path_to_inst |
      tr -d '"' >> /tmp/inst_list		# strip '"'
   done < $inst 
done

# 4. Get major-no's ./. driver names from modinfo-command:
#    Result e. g. 
#    102 cmdk (Common Direct Access Disk Drive)
#    no. drv. ------------ comment ------------
#    (The major no. could as well be extracted from /devices;
#    modinfo is preferable as it gives a comment concerning
#    the drivers as well.)

rm /tmp/maj_nos 2>/dev/null
while read path instance driver
do
   modinfo |
    nawk '$6 == '\"$driver\"' {
                               print $4, substr($0,30) >> "/tmp/maj_nos"
                              }' 
done < /tmp/inst_list

#    Get rid of multiple entries:

sort -u /tmp/maj_nos -o /tmp/maj_nos

# 5. Display results:

print "\nConnected disks / CD-ROMS / floppies   $(date +'%d.%m.%Y')"
print "=================================================\n"
while read c_path ctrl				# read controller info
do

   while read inst_path inst_no driver		# read device info
   do

     [[ $c_path = $inst_path ]] && break	# device in controller?	
   done < /tmp/inst_list

   while read maj_no driver_name comment	# yes - read maj. no. info
   do
     [[ $driver = $driver_name ]] && break	# got curr. driver name?
   done < /tmp/maj_nos

   printf "\nController : %2s  Path   : %s\n"\
          "$ctrl" "$c_path" 			# yes
   printf "Instance   : %2s  Driver : %3s - %s\n"\
          "$inst_no" "$maj_no" "$driver $comment"

   while read d_path dev
   do
     chk_path=$(dirname $d_path)		# get ctrl. path of device
     if [[ $c_path = $chk_path ]]		# device in curr. ctrl.?
     then
       conn="yes"				# yes - presume connected
       if [[ $ctrl = c* ]]			# device = disk/CD?
       then
         log_name="/dev/dsk/${dev}s2"		# yes	
       else
	 log_name="/dev/"$dev			# no: floppy
       fi

#	Now test if disk / CD /floppy is connected. Could as well be done by
#	using prtconf, but prtvtoc is easier ...

       (prtvtoc $logname 2>&1 |
	 grep "No") 1>/dev/null	  		# dev. exists?
       (( $? == 0 )) && conn="no"		# no, if grep finds "No"

       drv=$(basename $d_path)			# driver name

       while read inst_path inst_no driver	# get instance-info
       do
         [[ $d_path = $inst_path ]] && break	# found curr. device
       done < /tmp/inst_list			# in instance list?

       while read maj_no driver_name comment	# yes: get maj. no's
       do					# & driver names
         [[ $driver = $driver_name ]] && break	# found curr. driver name?
       done < /tmp/maj_nos

       printf "\n  Device   : %-10s %-10s Connected : %s\n"\
              "$dev" "$drv" "$conn"		# yes
       printf "  Instance : %2s  Driver : %3s - %s\n"\
              "$inst_no" "$maj_no" "$driver_name $comment"
     fi

   done < /tmp/dev_list

done < /tmp/ctrl_list

print " "
exit 0
