#!/usr/local/bin/perl
#translate-devalias
# if run with ANY arguments, it only prints a list of the boot devices
# otherwise it lists all drives with their physical address (as needed for devalias) and /dev/rdsk name

$debug = 0;
$verbose = 0;
my (%mappings);
if ($#ARGV != -1)
{
    $bootflag = 1;
}

$format = "/tmp/format.output";
read_format($format);

$prtconf = "/tmp/prtconf.output";
system("/usr/sbin/prtconf -vp > $prtconf");

#find relationship between /dev/rdsk/c0t0d0s0  and  ../../devices/pci@1f,4000/scsi@3/sd@0,0:a,raw
find_devices();

foreach $dev (sort keys %mappings)
{
    $flag = 0;
    find_entry($mappings{$dev});
    if ($flag == 0)
    {
        if ($bootflag == 0)
        {
            printf "%18s\t%-65s\t%s\n"," ",$mappings{$dev},$dev;
        }
    }
}

run_get_dev_info2();
find_boot_devices();

################################################################################
sub read_format
################################################################################
{
    my ($formatfile) = @_;

    if (! -f "$formatfile")
    {
        if (! defined($ENV{SUDO_USER}))
        {
            print "USAGE: sudo $0\n";
            exit(1);
        }
        else
        {
            $formatfile = "/tmp/format.output";
            $input = "/tmp/format.input";
            open(OUT,">$input");
            print OUT "0\nq\n";
            close(OUT);
            @res = `/usr/sbin/format < $input > $formatfile`;
        }
    }
    print "using $formatfile as input\n";
    open (FMT,$formatfile);
    {
        while ($line = <FMT>)
        {
            chomp($line);
            if ($line =~ m#^\s+(\d+)\.\s+(.*?)\s+<(.*?)>#)
            {
                if ($debug)
                {
                    print "$1 - $2\n";
                }
                push(@devices,$2);
            }

        }
    }
    close(FMT);
}


################################################################################
sub find_devices
################################################################################
{
    ($dev) = @_;
    my ($slot);

    @parts = split(m#/#,$dev);
    $logical = pop(@parts);
    if ($logical =~ m#s#)
    {
    }
    else
    {
        $logical = $logical."s0";
    }
    
    $dir = "/dev/rdsk";
    
    #
    ## read a directory $dir ( ignoring . and .. )
    #
        opendir(DIR,"$dir") || die "opendir $dir failed";
        @files = grep(m#$logical#,readdir(DIR));
        closedir(DIR);
    
    if ($#files == 0)
    {
        $file = $files[0];
    }
    else
    {
#        print "$#files\n";
    }
    foreach $file (@files)
    {
        $file = $dir."/".$file;
        $link = readlink($file);
        if ($verbose)
        {
            print " $file maps to $link\n";
        }
        ($front,$string) = split(m#devices#,$link);
        ($string2,$j)    = split(m#,[0-9]:#,$string);
# for 3000's we need to leave "sd" as "sd"
# /dev/rdsk/c0t0d0s0 -> ../../devices/sbus@3,0/SUNW,fas@3,8800000/sd@0,0:a,raw
#
# for 3500's we need to change "sdisk" to "ssd"
# /dev/rdsk/c0t0d0s0 -> ../../devices/sbus@2,0/SUNW,socal@d,10000/sf@0,0/ssd@w21000020379cebf9,0:a,raw
#        if (($string2 =~ m#^/sbus#) || ($string2 =~ m#socal#))
#        {
#            $string2 =~ s#sdisk#ssd#;
#        }

# for 450's we need to change "sd" to "disk"
# /dev/rdsk/c0t0d0s0 -> ../../devices/pci@1f,4000/scsi@3/sd@0,0:a,raw
        if ($string2 =~ m#^/pci#)
        {
            $string2 =~ s#sd#disk#;
        }

        if ($verbose)
        {
            print " look for $string2 in prtconf output\n";
        }
        $mappings{$file} = $string2;
    }
}


################################################################################
sub find_entry
################################################################################
{
    ($string2) = @_;

    if ($string2 eq "")
    {
#        print "disk not found\n";
#        exit();
    }

    if ($string2 =~ m#fibre-channel#)
    {
#        print " non-local fibre-channel device $file\n";
    }
    else
    {
    
        open(IN,"$prtconf");
        {
            while ($line = <IN>)
            {
                chomp($line);
                if ($line =~ m#$string2#)
                {
                    if ($debug)
                    {
                        print "$line\n";
                    }
#                    print "$dev -> $mappings{$dev}\n";
                    $line =~ s#^\s+##;
                    ($alias,$device) = split(m#:#,$line);
                    $device =~ s#^\s+##;
                    $device =~ s#'##g;
                    if ($bootflag == 0)
                    {
                        printf "%18s\t%-65s\t%s\n",$alias,$device,$dev;
                    }
                    $flag = 1;
                    $aliases{$alias} = $device."\t".$dev;
                }
                else
                {
#if ($line =~ m#socal#)
#{
#    $line =~ s#^\s+##;
#    ($alias,$device) = split(m#:#,$line);
#    $device =~ s#^\s+##;
#    $device =~ s#'##g;
##    printf "%15s\t%s\t%s\n",$alias,$device,$dev;
#printf "%15s\t%s\n%15s\t%s\n",$alias, $device, "=>", $string2;
#}
                }
            }
        }
        close(IN);
    }
}


################################################################################
sub find_boot_devices
################################################################################
{
    $eeprom = "/tmp/eeprom.output";
    system("/usr/sbin/eeprom > $eeprom");

    open(IN,"$eeprom");
    while ($line = <IN>)
    {
        chomp($line);
        if ($line =~ m#boot-device#)
        {
            print "$line\n";
            ($name,$vals) = split(m#=#,$line);
            @names = split(m#\s+#,$vals);
            foreach $alias (@names)
            {
                if (defined($aliases{$alias}))
                {
                    print "$alias\t$aliases{$alias}\t";
                    ($machine,$human) = split(m#\t#,$aliases{$alias});
                    if (defined($used{$human}))
                    {
                        if (($alias =~ m#pri#) && (!($used{$human} =~ m#\(/\)#)))
                        {
                            print "ERROR: ";
                        }
                        elsif (($alias =~ m#mir#) && (!($used{$human} =~ m#\(/\)#)))
                        {
                            print "ERROR: ";
                        }
                        elsif (($alias =~ m#bck#) && (!($used{$human} =~ m#bck#i)))
                        {
                            print "ERROR: ";
                        }
                        
                        print "$used{$human}\n";
                    }
                    else
                    {
                        print "\n";
                    }
                }
                else
                {
                    print "$alias\tERROR: alias not defined\n";
                }
            }
        }
    }
    close(IN);
}




################################################################################
sub run_get_dev_info2
################################################################################
{
    $devinfo = "/tmp/devinfo.output";
    system("/usr/local/bin/get-dev-info2 > $devinfo");
    open(DINFO,"$devinfo") || die "Cannot open $devinfo";
    while ($line = <DINFO>)
    {
        chomp($line);
        ($dev,$rest) = split(m#\t#,$line,2);
        if ($dev =~ m#^c#)
        {
            $dev = "/dev/rdsk/".$dev;
            $used{$dev} = $rest;
        }
    }
    close(DINFO);
}


