#!/usr/bin/perl
use strict ;
use warnings ;
my %scsi_devices ;

my @devs ;
opendir(my $devsd, "/dev") or warn("could not open /dev");
for (readdir $devsd) {
	push (@devs, $_) if ($_ =~ m/^sd/);
}
closedir($devsd) ;

sub head {
    my ($fname) = @_ ;
    open(FH, "<", "$fname") or warn("could not open $fname !\n") ;
    my @lines = <FH>;
    close(FH);
    chomp($lines[0]) ;
    return($lines[0]) ;
}

for my $dev (@devs) {
    chomp($dev) ;
	next if ($dev =~ m/[0-9]/);
    my $scsi_id = `/sbin/scsi_id --whitelist --device=/dev/$dev`;
	chomp($scsi_id);
    ${scsi_devices}{$scsi_id}{devs}{$dev} = {};
    unless (defined ${scsi_devices}{$scsi_id}{size}) {
        ${scsi_devices}{$scsi_id}{size} = head("/sys/class/block/$dev/size");
        chomp(${scsi_devices}{$scsi_id}{size}) ;

        ${scsi_devices}{$scsi_id}{vendor} = head("/sys/class/block/$dev/device/vendor");
        chomp(${scsi_devices}{$scsi_id}{vendor}); 

        ${scsi_devices}{$scsi_id}{model} = head("/sys/class/block/$dev/device/model");
        chomp(${scsi_devices}{$scsi_id}{model}); 
    }

	opendir(my $devdir, "/sys/class/block/$dev/device/scsi_device") or warn("could not open /sys/class/block/$dev/device/scsi_device");
	for my $devdirent (readdir $devdir) {
		next if ($devdirent =~ m/^\./);
		chomp($devdirent);
		my @scsi_dev = split(':', $devdirent) ;
		${scsi_devices}{$scsi_id}{devs}{$dev}{host} = $scsi_dev[0];
		${scsi_devices}{$scsi_id}{devs}{$dev}{channel} = $scsi_dev[1];
		${scsi_devices}{$scsi_id}{devs}{$dev}{id} = $scsi_dev[2];
		${scsi_devices}{$scsi_id}{devs}{$dev}{lun} = $scsi_dev[3];
	}
	closedir($devdir);
}

for my $scsi_id (sort keys %scsi_devices) {
    print ${scsi_devices}{$scsi_id}{vendor} . " ";
    print ${scsi_devices}{$scsi_id}{model} . " ";
    if (${scsi_devices}{$scsi_id}{size} >= ((2**21) * 10)) {
        printf("%iGB\n", int(${scsi_devices}{$scsi_id}{size} / (2**21))) ;
    } elsif (${scsi_devices}{$scsi_id}{size} >= (2**21)) {
        printf("%.1fGB\n", (${scsi_devices}{$scsi_id}{size} / (2**21))) ;
    } elsif (${scsi_devices}{$scsi_id}{size} >= ((2**11) * 10)) {
        printf("%iMB\n,", int(${scsi_devices}{$scsi_id}{size} / (2**11)));
    } else {
        printf("%.1fMB\n", (${scsi_devices}{$scsi_id}{size} / (2**11))) ;
    }

    for my $sd (sort {$a cmp $b} keys %{$scsi_devices{$scsi_id}{devs}}) {
		printf("  \\_ %-4s host%i channel %02i id %02i lun %02i\n", 
			$sd,
			${scsi_devices}{$scsi_id}{devs}{$sd}{host},
			${scsi_devices}{$scsi_id}{devs}{$sd}{channel},
			${scsi_devices}{$scsi_id}{devs}{$sd}{id},
			${scsi_devices}{$scsi_id}{devs}{$sd}{lun}
		);
    }
    print "\n";
}
