#!/usr/bin/perl 
#
# Lux_Parse.PL -  Sun A5x00 Information Gathering Tool
#       Version 2.0: Oct 11th, 2002
# (c) Ben Rockwood - benr@cuddletech.com
# cuddletech - use unix or die(c).

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



### Parse Arguments
$ARGS = @ARGV;

if ($ARGS < 1) {
        print("Usage: lux_parse.pl array\n");
        exit(1);
}

### Set photon name and output to confirm to user
$photon = $ARGV[0];
#print("Photon is: $photon\n");

### Collect data for parsing
__clean_up();
`luxadm display $photon \> /tmp/luxadm.$photon.out`;
`vxdisk list  > /tmp/vxdisk.tmp.out`;
`ls -l /dev/dsk > /tmp/devdsk.tmp.out`;


# Determine Array Type
__array_type();
print("Drive Listing for $array_type named $photon:\n");


#Print Header:
#print("LUX_PARSE - cuddletech\n")
print("A5x Slot\tShort WWN\tStatus\n");
print("\t\tSCSI ID\tInstance\tVMDisk\tDG\n");
print("--------\t----------------\t------\t---\n");

# Print info
__disks_report();

print("Done...");
# Clean up
__clean_up();



###########################################################
### Subroutines

### Purpose: Define array type by outputting $array_type
sub __array_type {
	open(LUX, "/tmp/luxadm.$photon.out");

	my $i = 0;
	foreach(<LUX>){
        	chomp($_);
        	if ( $_ =~ m/^\d/ ) {
                	$disk_count[$i++] = $_;
        	}
	}      

	$num_drives = @disk_count;

	if( $num_drives == 11 ) {
                $array_type = "A5200";
          } elsif ( $num_drives == 7 ) {
                $array_type = "A5100";
          } else {
                print("DEBUG: Array has $num_drives num of elements\n");
	}

	close(LUX);
}


### Purpose: Clean up temp files
sub __clean_up {

print("Cleaning up: ");
	if (-e "/tmp/vxdisk.tmp.out") {`rm -f /tmp/vxdisk.tmp.out`; print("vxdisk.tmp.out, "); }
	if (-e "/tmp/luxadm.$photon.out") {`rm -f /tmp/luxadm.$photon.out`; print("luxadm.$photon.out, "); }
	if (-e "/tmp/devdsk.tmp.out") {`rm -f /tmp/devdsk.tmp.out`; print("devdsk.tmp.out"); }
print("... done.\n");
}


### Purpose: Get and print disk information

sub __disks_report {

	open(LUX, "/tmp/luxadm.$photon.out");

	## Parse luxadm for front drives.
	my $i = 0;
	foreach(<LUX>){
          chomp($_);
          if ( $_ =~ m/^\d/ ) {
		my $status_front = $_;
		my $wwn_long = $_;
                $status_front =~ s/^\d+\s+(.+?)\s+(\w{16})?\s+(.+?)\s+(\w{16})?$/$1/;
                $wwn_long =~ s/^\d+\s+(.+?)\s+(\w{16})?\s+(.+?)\s+(\w{16})?$/$2/;
		#print("DEBUG: Long WWN is $wwn_long\n");

		if ( $wwn_long ne "") {
			$wwn_short = $wwn_long;
			$wwn_short =~ s/^\d{6}//;
			#print("DEBUG: Short WWN is $wwn_short\n");

			print("$photon,f$i\t$wwn_short\t$status_front\n");

			__get_disk_details();
		 } else {
			print("$photon,f$i\tERROR\t$status_front\n");
			print("\t\t-\t-\t-\t-\n");
		}

		$i++;
          }
	}      
	close(LUX);	

	open(LUX, "/tmp/luxadm.$photon.out");
	## Parse luxadm for rear drives.
	$i = 0;
	foreach(<LUX>){
          chomp($_);
	  if ( $_ =~ m/^\d/ ) {	
		my $status_rear = $_;
		my $wwn_long = $_;
        	$status_rear =~ s/^\d+\s+(.+?)\s+(\w{16})?\s+(.+?)\s+(\w{16})?$/$3/;
        	$wwn_long =~ s/^\d+\s+(.+?)\s+(\w{16})?\s+(.+?)\s+(\w{16})?$/$4/;

                if ( $wwn_long ne "") {
                        $wwn_short = $wwn_long;
                        $wwn_short =~ s/^\d{6}//;
                        #print("DEBUG: Short WWN is $wwn_short\n");

                        print("$photon,r$i\t$wwn_short\t$status_rear\n");

                        __get_disk_details();
                 } else {
                        print("$photon,r$i\tERROR\t$status_rear\n");
			print("\t\t-\t-\t-\t-\n");
                }       

                $i++;

	  }
	}      

	close(LUX);
}


## Purpose: Get additional disk bits
sub __get_disk_details {

	#print("DEBUG:My WWN is $wwn_short\n");

	 foreach(`cat /tmp/devdsk.tmp.out | grep $wwn_short,0:c`){	
		my @dev_out = split(/\s+/, $_);

		### Debug:
		#foreach(@dev_out){
		#	print("-> $_\n");
		#}	


		$scsi_id = $dev_out[8];
		#print("DEBUG: Got SCSI ID - $scsi_id\n");

		# Tunemeup: I should probly not diffrent dev instances for 20 21 and 22, being node, pathA and pathB to each disk.
		my $path_wwn = $dev_out[10];
		#print("DEBUG: Got Disk Path - $path_wwn\n");
		$path_wwn =~ s/^.*\/.*?\@(.*?),.*$/$1/;
		#print("DEBUG: New Disk Path - $path_wwn\n");

		my $instpath = `grep $path_wwn /etc/path_to_inst`;	
		(my $devpath, my $inst, my $drv) = split(/\s+/, $instpath);
		$drv =~ s/\"//g;
		#print("DEBUG: Got Instance - $drv$inst\n");

		my @vx_out = split(/\s+/, `grep $scsi_id /tmp/vxdisk.tmp.out `);	
		#print("DEBUG: Got VX Info... $vx_out[2] $vx_out[3]\n");
	
		#Return Values: 
                if ($vx_out[2]) { $vmdisk = $vx_out[2]; } else { $vmdisk = "\t"; }
                if ($vx_out[3]) { $dg = $vx_out[3]; } else { $dg = "\t"; }
		$drvinst = "$drv$inst";

		#Print
		print("\t\t$scsi_id\t$drvinst\t$vmdisk\t$dg\n");
		#print("DEBUG: Done in get details\n");
	}
}
		
