#!/usr/bin/perl
$ID = q$Id: tpd_hostinfo,v 1.19.2.5 2011/06/09 21:28:36 pambati Exp $;
#
# Description : script to define the tokens for hostexplorer 
# Copyright: 2008 3PARdata , Inc.
#

use strict;
use warnings;
use POSIX;

use File::Copy;
use File::Path;
use Sys::Hostname;

my $version = "1.1.1-6";
my $os;
my $osver;
my $mpsw;
my $mpswver;
my $mppstamp;
my $is_net;
my $clus;
my $clusver;
my $clusid;
my $clusname;
my $ip;

# LOGGING for TOKEN VALUE
my $LOGPATH = "/var/log/3par/hostexplorer/";
my $LOGFILE = "hagent-token.log";

# to move the logs and save old logs
sub log_move {
	my $OLD;
    my $OLDLEV1;
    my $OLDLEV2;
    my $OLDLEV3;
    my $OLDLEV4;
    my $LOG = $LOGPATH . $LOGFILE;
    my $LOGSIZE = `du -k $LOG`;
    $LOGSIZE =~ (m/^(\d+)\s+\S+/);
    $LOGSIZE = $1;

	$OLD = $LOG . ".0";
	$OLDLEV1 = $LOG . ".1";
	$OLDLEV2 = $LOG . ".2";
	$OLDLEV3 = $LOG . ".3";
	$OLDLEV4 = $LOG . ".4";

	if ($LOGSIZE > 5000) {
		(-e $OLDLEV3 ) and move($OLDLEV3, $OLDLEV4);
		(-e $OLDLEV2 ) and move($OLDLEV2, $OLDLEV3);
		(-e $OLDLEV1 ) and move($OLDLEV1, $OLDLEV2);
		(-e $OLD ) and move($OLD, $OLDLEV1);
		(-e $LOG ) and move($LOG, $OLD);
	}
} # end of log_move

# logging function to add the TOKEN VALUE
sub log_data {

	my $LOG = $LOGPATH . $LOGFILE;
	my $TIMESTAMP = POSIX::strftime("%b %d %H:%M:%S %Y", localtime());
	my $TEXT = $TIMESTAMP . "  " . $_[0];
		my $RETCODE;
		my $DATAFILE;

	unless(-d "$LOGPATH"){
        mkpath $LOGPATH ;
	}
	$RETCODE = open($DATAFILE, ">>$LOG");
	if (defined $RETCODE) {
			print $DATAFILE "$TEXT";
	}

	close($DATAFILE);
	# check for the size of the logfile
	log_move;
} #end of log_data

# Read a file and return the contents; if we can't open the file we return undef
sub readfile($) {
    my $file = shift;
    my $value;

    if (open(FILE, $file)) {
        $value = <FILE>;
        chomp $value;
        close(FILE);
    }

    return $value;
}

sub dir_is_empty($) {
    my ($path) = shift;
    return 1 if (! -d $path);
    opendir DIR, $path;
    while(my $entry = readdir DIR) {
        next if($entry =~ /^\.\.?$/);
        closedir DIR;
        return 0;
    }
    closedir DIR;
    return 1;
}

#
# get the iscsi physical disk name for soalris
#
sub get_dname($) {
	my $iname = shift;
	my $pname;
	my $val;
	
    if ($iname =~ /^(c[\d]*)(t[\d]*)(iqn.[\d]*\-[\d]*\.Com.[\w]*\%[\w]{22})(d[\d]*)(.*)/)
	{
		(my $val1, my $val2, my $val3, my $val4, my $val5) = ($1, $2, $3, $4, $5);
		# get the hex value for dxxx
		$val4 =~ s/d//;
		my $decval = sprintf("%x", $val4);
		$val = $val3 . "," . $decval;
		if (defined($val5) && ($val5 =~ /^(s[\d]*)/)) {
			$val = $val . ":c,raw";
		} else {
			$val = $val . ":wd,raw";
		}
		$pname = `ls -l /dev/rdsk | grep -i $val | awk '{print \$9}'`;
	} else {
		$pname="nodev";
	}
	return $pname;
}

#
# Get the IP address of a host
#
sub getipaddr {
	my @ipout = `ifconfig -a 2>/dev/null`;
	my $ipval;
	foreach my $line (@ipout) {
		chomp $line;
		if ($line =~ m/^\s*inet (?:addr:)?([\d.]+).*?cast/ ) {
			$ipval = $1;
			return $ipval;
		}
	}
}

#
# Get the CPU information
#
sub getlinuxcpuinfo  {
	my @cpus;
	my @cpufile = glob('/proc/cpuinfo');
}
	
#
# get the error information 
#
sub getlinuxerrorinfo {

}

#
# get the FPM policy and FPM interval
#
sub getfpmforlinux($) {
	my $fpmvar = shift;
	my $fpmfile  = "/etc/multipath.conf";
	open(FILE, $fpmfile) || return "unknown";
		my @data = <FILE>;
	close(FILE);

foreach my $line (@data)
{
	if ($line =~ /$fpmvar/) {
		(my $val, my $fpmval) = split(' ',$line);
		return $fpmval;
	}
}
}

# function to get the remote port address
sub find_target_port(@) {

	my $hbaval = shift;
	my $lunval = shift;
	my $gotlun;
	my @twwns;
	my $rwwn;
	my @fcval = `fcinfo remote-port -s -p $hbaval`;

	foreach my $line (@fcval) {
		chomp $line;
		if ($line =~ /Remote Port WWN: (.*)/) {
			my $twwn=$1;
			push @twwns, $twwn;
		} elsif ($line =~ /OS Device Name: (.*)/) {
			$gotlun = $1;
			if ($lunval eq $gotlun) {
			$rwwn = pop(@twwns);
			return $rwwn;
			}
		}

	}
}

#
# get the cpu type for solaris
sub getsolcpuinfo {
	my @cpuinfo = `psrinfo -v`;
	my $cputype;

	foreach my $line (@cpuinfo) {
		if ($line =~ /The (.*)(processor)(.*) /) {
			$cputype = $1;
			return $cputype;
		}
	}
}

#
# Get a list of HBAs for Linux 2.4 by parsing files under /proc
#
sub getlinux24hba {
    my @hbas;
    my  @hbasysdirs;

    my @scsifiles = glob('/proc/scsi/qla2*/?');

    foreach my $scsifile (@scsifiles) {
	my $hba;

        open(FILE, $scsifile);
        while (<FILE>) {
            $hba->{'vendor'} = 'QLogic';
            if (/\S*adapter-port=([0-9a-fA-F]{16})/) {
                $hba->{'port_name'} = $1;
            } elsif (/\s+Firmware version:?\s+(.*), Driver version (.*)$/) {
                $hba->{'fw_version'} = $1;
                $hba->{'driver_version'} = $2;
			} elsif ((/^HBA: (.*) ,/) or (/\S*Fibre Channel Host Adapter for (.*):/)) {
                $hba->{'model_name'} = $1;
            }
        }
        close(FILE);
        push @hbas, $hba;
    }

    # TODO: LSI Logic (/proc/mpt?), Emulex (/proc/scsi/lpfc?)
    # Emulex information
	if ( -e "/proc/scsi/lpfc/") {
          opendir(DIR, "/sys/class/scsi_host/");
          @hbasysdirs = sort grep { /^host/ && -d "/sys/class/scsi_host/$_" }
          readdir(DIR);
          @hbasysdirs = map { $_ = "/sys/class/scsi_host/$_/"; } @hbasysdirs;
          closedir DIR;

          foreach my $hbadir (@hbasysdirs) {
                my $hba;
                if ( -e $hbadir."modeldesc") {
                $hba->{'vendor'} = 'Emulex';
                $hba->{'port_name'} = readfile($hbadir."port_name");
                $hba->{'port_name'} =~ s/^0x//;
                $hba->{'speed'} = readfile($hbadir."speed");
                $hba->{'driver'} = readfile($hbadir."proc_name");
                $hba->{'model_name'} = readfile($hbadir."modelname");
                $hba->{'fw_version'} = readfile($hbadir."fwrev");
                $hba->{'driver_version'} = readfile($hbadir."lpfc_drvr_version");
                $hba->{'driver_version'} =~ s/Emulex LightPulse Fibre Channel SCSI driver //g;
        		push @hbas, $hba;
                }
          }
    }

	# iscsi information
	my $found;
	if (system("ps -C iscsid -o pid= > /dev/null") == 0) {
		$found = 0;
	}
	$found = (dir_is_empty("/sys/class/iscsi_host/"));
	if ($found == 0) {
		my $iscsidir = "/etc/iscsi/";
		if ( -e $iscsidir."initiatorname.iscsi") {
			my $hba;
			$hba->{'vendor'} = "ISCSI";
			$hba->{'port_name'} = readfile($iscsidir."initiatorname.iscsi");
			$hba->{'port_name'} =~ s/InitiatorName=//g;
			$hba->{'driver_version'} = `uname -r`;
			chomp $hba->{'driver_version'};
			# model_name and fw_version are null
			push @hbas, $hba;
		} elsif ( -e "/etc/initiatorname.iscsi") {
			my $hba;
			$hba->{'port_name'} = `grep "InitiatorName=" /etc/initiatorname.iscsi`;
			chomp  $hba->{'port_name'};
			$hba->{'port_name'} =~ s/InitiatorName=//g;
			$hba->{'vendor'} = "CISCO";
			my $iscsi_ver = `iscsi-ls |  grep "SCSI Driver Version" | awk '{print \$5}'`;
			$hba->{'driver_version'} = substr($iscsi_ver, 3);
			chomp $hba->{'driver_version'};
			push @hbas, $hba;
		}
	}

    return @hbas;
}

#
# Get the path wwn information for 2.6 kernel with old style
#
sub get_wwn24($) {
	 my $portval = shift;
    my @lunid = split(/:/, $portval);
    my $fileno = $lunid[0];

    # check for the filename in /proc/scsi/qla*/$fileno);
    my @qlfiles = glob("/proc/scsi/qla*/$fileno");

    my @owwns;
    my $sno = $lunid[2];
    my $tno = $lunid[3];

	foreach my $sfile (@qlfiles) {
        my $owwn;
        open(FILE, $sfile) or die $!;
        while (<FILE>) {
            chomp;
            if (/\S*adapter-port=([0-9a-fA-F]{16})/) {
                 $owwn->{'host_wwn'} = $1;
                 $owwn->{'host_wwn'} =~ s/0x//;
            # add regex for scsi-qla0-target-0= or scsi-qla0-target-1, etc
            } elsif (/\S*target-${sno}=([0-9a-fA-F]{16})/) {
                $owwn->{'tgt_wwn'} = $1;
                $owwn->{'tgt_wwn'} =~ s/0x//;
            } elsif ((/^(\( (${sno}:${tno}\):)) +(.*)/) or
                            (/^(\( (${sno}: ${tno}\):)) +(.*)/)) {
                # match the Id:lun value here, if matches quit and get the wwn
                last;
            }
        }
        close(FILE);
		push @owwns, $owwn;
	}
	return @owwns;
}

#
# Get a list of HBAs for Linux 2.6 by parsing files under /sys
#
sub getlinux26hba {
    my @hbas;
    my @hbasysfsdirs;

    if (! -e "/sys/class/fc_host/") {
		# We're 2.6, but too early to have any useful info in /sys. Fallback to 2.4 style.
		return getlinux24hba();
	}	

    opendir(DIR, "/sys/class/fc_host/");
    @hbasysfsdirs = sort grep { /^host/ && -d "/sys/class/fc_host/$_" }
	readdir(DIR);
    @hbasysfsdirs = map { $_ = "/sys/class/fc_host/$_/"; } @hbasysfsdirs;
    closedir DIR;

    foreach my $hbadir (@hbasysfsdirs) {
        my $hba;
        $hba->{'port_name'} = readfile($hbadir."port_name");

		if (! defined($hba->{'port_name'})) {
			# Give up; this seems to be early enough 2.6 that the fibre channel
			# sysfs information isn't there. Fall back to 2.4 style
			return getlinux24hba();
		}
        $hba->{'port_name'} =~ s/^0x//;
        $hba->{'speed'} = readfile($hbadir."speed");
        $hba->{'driver'} = readlink "$hbadir/device/../driver";
        $hba->{'driver'} =~ s/.*\///;

        # Get the PCI vendor ID and convert to a string if we know it.
        my $vendor = readfile("$hbadir/device/../vendor");
        if ($vendor eq '0x1000') {
            $hba->{'vendor'} = 'LSI Logic';
        } elsif ($vendor eq '0x1077') {
            $hba->{'vendor'} = 'QLogic';
        } elsif ($vendor eq '0x10df') {
            $hba->{'vendor'} = 'Emulex';
        }
        
        my @scsidir = glob $hbadir."device/scsi_host:host*";
        if (! @scsidir) {
            # Later 2.6 kernels have a different layout
            @scsidir = glob $hbadir."device/scsi_host/host*";
        }
		if (($hba->{'speed'} eq "unknown") || (!defined($hba->{'speed'}))) {
			my $chkspeed;
			if ( -e $scsidir[0]."/modeldesc") {
		    	$chkspeed = readfile($scsidir[0]."/modeldesc");
				chomp($chkspeed);
			} elsif ( -e $scsidir[0]."/model_desc") {
		    	$chkspeed = readfile($scsidir[0]."/model_desc");
				chomp($chkspeed);
			}
			my @cvals = split(' ', $chkspeed);
			foreach my $cval (@cvals) {
				if (($cval  =~ m/Gb/) || ($cval  =~ m/GbE/)) {
				  $hba->{'speed'} = $cval;
				}
			}
		}

        $hba->{'model_name'} = readfile($scsidir[0]."/model_name");
        if (!defined($hba->{'model_name'})) {
            $hba->{'model_name'} = readfile($scsidir[0]."/modelname");
        }
        $hba->{'fw_version'} = readfile($scsidir[0]."/fw_version");
        if (!defined($hba->{'fw_version'})) {
            $hba->{'fw_version'} = readfile($scsidir[0]."/fwrev");
        }
        if (!defined($hba->{'fw_version'})) {
            $hba->{'fw_version'} = readfile($scsidir[0]."/version_fw");
        }
        $hba->{'driver_version'} = readfile($scsidir[0]."/driver_version");
		if (!defined($hba->{'driver_version'})) {
			 $hba->{'driver_version'} = readfile($scsidir[0]."/lpfc_drvr_version");
             $hba->{'driver_version'} =~ s/Emulex LightPulse Fibre Channel SCSI driver //g;
		}

        push @hbas, $hba;
    }

	my $found = (dir_is_empty("/sys/class/iscsi_host/"));
	if ($found == 0) {
		my $iscsidir = "/etc/iscsi/";
		if ( -e $iscsidir."initiatorname.iscsi") {
			my $hba;
			$hba->{'vendor'} = "ISCSI";
			$hba->{'port_name'} = readfile($iscsidir."initiatorname.iscsi");
			$hba->{'port_name'} =~ s/InitiatorName=//g;
			$hba->{'driver_version'} = `uname -r`;
			chomp $hba->{'driver_version'};
			# model_name and fw_version are null
			push @hbas, $hba;
		} elsif ( -e "/etc/initiatorname.iscsi" ) {
			my $hba;
			$hba->{'port_name'} = `grep "InitiatorName=" /etc/initiatorname.iscsi`;
			chomp  $hba->{'port_name'};
			$hba->{'port_name'} =~ s/InitiatorName=//g;
			$hba->{'vendor'} = "CISCO";
			my $iscsi_ver = `iscsi-ls |  grep "SCSI Driver Version" | awk '{print \$5}'`;
			$hba->{'driver_version'} = substr($iscsi_ver, 3);
			chomp $hba->{'driver_version'};
			push @hbas, $hba;
		}
	}

    return @hbas;
}

#
# Get a list of HBAs for Solaris by calling fcinfo and parsing the output
#
sub getsolarisfchba {
    my @fcinfo = `fcinfo hba-port`;
    my @hbas;

    my $inhba = 0;
    my $hba;
    foreach my $line (@fcinfo) {
        if ($line =~ /^HBA Port WWN: (.*)/) {
            if ($inhba) {
                push @hbas, $hba;
                undef $hba;
            }
            $inhba = 1;
            $hba->{'port_name'} = $1;
        } elsif ($line =~ /Current Speed: (.*)/) {
            $hba->{'speed'} = $1;
        } elsif ($line =~ /Firmware Version: (.*)/) {
            $hba->{'fw_version'} = $1;
        } elsif ($line =~ /Manufacturer: (.*)/) {
            $hba->{'vendor'} = $1;
        } elsif ($line =~ /Model: (.*)/) {
            $hba->{'model_name'} = $1;
		} elsif ($line =~ /Driver Name: (.*)/) {
			$hba->{'driver'} = $1;
		} elsif ($line =~ /Driver Version: (.*)/) {
			$hba->{'driver_version'} = $1;
        }
    }
    if ($inhba) {
        push @hbas, $hba;
		undef $hba;
    }

    # check for iscsi information here for initiator 
    my $iscsi_yes=`modinfo | egrep iscsi | awk '{print \$1}'`;
    if (($iscsi_yes ne " ") && ($iscsi_yes gt 0)) {
        my @ininode = `iscsiadm list initiator-node`;
        foreach my $iline (@ininode) {
          chomp $iline;
          if ($iline =~ /Initiator node name: (.*)/) {
             $hba->{'port_name'} = $1;
             $hba->{'vendor'} = "Sun";
             $hba->{'model_name'} = "ISCSI";
	    	 push @hbas, $hba;
          }
        }
     }
    return @hbas;
}

#
# Get a list of HBAs for Windows by calling fcinfo and parsing the output
#
sub getwindowshba {
    my @fcinfo = `fcinfo /details`;
    my @hbas;

    my $inhba = 0;
    my $hba;
    foreach my $line (@fcinfo) {
        if ($line =~ /^\s+adapter: (.*)/) {
            if ($inhba) {
                push @hbas, $hba;
                undef $hba;
            }
            $inhba = 1;
        } elsif ($line =~ /\s+port_wwn: (.*)/) {
            $hba->{'port_name'} = $1;
			$hba->{'port_name'} =~ s/://g;
        } elsif ($line =~ /\s+fwver: (.*)/) {
            $hba->{'fw_version'} = $1;
        } elsif ($line =~ /\s+drvname: (.*)/) {
            $hba->{'driver'} = $1;
        } elsif ($line =~ /\s+model: (.*)/) {
            $hba->{'model_name'} = $1;
        }
    }
    if ($inhba) {
        push @hbas, $hba;
    }

    return @hbas;
}

#
# Get a list of HBAs for Solaris by calling luxadm and parsing the output
#
sub getsolarisluxhba {
    my @luxadm = `luxadm -e port`;
    my @hbas;

    my $inhba = 0;
    my $hba;
    foreach my $line (@luxadm) {
		if ($line =~ /^(\/.*:devctl)\s+(.*)$/) {
			next if $2 eq 'NOT CONNECTED';
			my @wwnmap = `luxadm -e dump_map $1`;
			foreach $line (@wwnmap) {
				if ($line =~ /^\d+\s+[0-9a-fA-F]+\s+[0-9a-fA-F]+\s+[0-9a-fA-F]+\s+([0-9a-fA-F]{16}).*Host Bus Adapter/) {
					undef $hba;
					$hba->{'port_name'} = $1;
					push @hbas, $hba;
				}
			}
		}
	}	

    return @hbas;
}

#
# Get a list of HBAs for AIX by calling lscfg
#
sub getaixhba {
	my @lscfg = `lscfg -v`;
	my @hbas;

	my $inhba = 0;
	my $hba;
	foreach my $line (@lscfg) {
		if ($line =~ /^\s\s.*FC Adapter$/) {
			if ($inhba) {
				push @hbas, $hba;
				undef $hba;
			}
			$inhba = 1;
		} elsif ($line =~ /^\s\s\S/) {
			if ($inhba) {
				push @hbas, $hba;
				undef $hba;
			}
			$inhba = 0;
		} elsif ($inhba and $line =~ /Device.*\.([0-9a-fA-F]{16})$/) {
			$hba->{'port_name'} = $1;
		}
	}
	if ($inhba) {
		push @hbas, $hba;
	}

	return @hbas;
}

#
# Get LUN information for iscsi and fc devices using dm 
#
sub getlinuxiscsidmlun {
    my @multipath = `multipath -l 2> /dev/null`;

	my @owwns;
    my @luns;
    my $lun; 
	my @twwns;
	my $tpwwn;
	my $rh4;

	my $rflg = 0;
	my @iscsilun;

    my $fpmpol = getfpmforlinux("path_checker");
    my $fpmint = getfpmforlinux("no_path_retry");

	my $hpn = readfile("/etc/iscsi/initiatorname.iscsi");
	if (defined($hpn)) {
    	$hpn =~ s/InitiatorName=//g;
		$rh4 = 1;
	} else {
		if ( -e "/etc/initiatorname.iscsi" ) {
		$hpn = `grep "InitiatorName=" /etc/initiatorname.iscsi`;
		$hpn =~ s/InitiatorName=//g;
		chomp $hpn;
		}
		$rh4 = 0;
	}

	# if hpn is not defined try to read from /etc/ directory
    foreach my $line (@multipath) {
        chomp $line;
        if ($line =~ /^(.)([0-9a-fA-F]{16}).*3PARdata,VV/ or
				$line =~ /^(.)(50002ac[0-9a-fA-F]{9})/ or
				$line =~ /^(.*) (\(.[0-9a-fA-F]{16})/ or
				$line =~ /^(.*)(\(.[0-9a-fA-F]{16}).*3PARdata,VV/) {
            if (defined($lun)) {
                push @luns, $lun;
                undef $lun;
            }
			my $len = length($2);
			if ($len==18) {
			  $lun->{'wwn'} = substr($2, 2);
			} else {
              $lun->{'wwn'} = $2;
			}
			my $dlen = length($1);
			if ($dlen > 1) {
			  $lun->{'devname'} = $1;
			  $lun->{'devname'} =~ s/\s+$//;
			} else {
			  $lun->{'devname'} = $1.$2;
			}
			$lun->{'fpmpolicy'} = $fpmpol;
			$lun->{'fpminterval'} = $fpmint;
		} elsif (defined($lun)) {
			if ($line =~ /^\\\_ ([^ ]+) +(.*)/ or
					$line =~ /^\\` ([^ ]+) +(.*)/ or
					$line =~ /^\`\-\+\- (policy[^ ]+) +(.*)/) {
						if ($1 =~ /^(policy\=\'[^ ]+)/) {
							(my $gb, my $iop) = split('\'', $1);
							$lun->{'iopolicy'} = $iop;
						} else {
	            $lun->{'iopolicy'} = $1;
						}
			} elsif ($line =~ /^ \\\_ ([^ ]+) +([^ ]+) +[^ ]+ +(.*)/ or
							$line =~ /^  \\\_ ([^ ]+) +([a-z]+) +(.*)/ or
							$line =~ /^  \\|_ ([^ ]+) +([a-z]+) +(.*)/ or
							$line =~ /^  \`\- ([^ ]+) +([a-z]+) +(.*)/ or
							$line =~ /^  \|\- ([^ ]+) +([a-z]+) +(.*)/) {
				my ($hwwn, $twwn);
	            $lun->{'totpathcnt'}++;
				my $tlun = $2;
				my @pstate = split(' ', $3);
				# add code to get iscsi info using /sbin/iscsi-ls 
				if ($rh4 == 1) {
				my @iscsilun = `iscsiadm -m session  -i 2>/dev/null`;
				foreach my $iline (@iscsilun) {
					chomp $iline;
					if ($iline =~ /^TargetName: (.*)/ or
						$iline =~ /^Target: (.*)/) {
						my $tpwwn = $1;
						push @twwns, $tpwwn;
					} elsif ($iline =~ /Attached scsi disk $tlun/) {
						$hwwn = $hpn;
						$twwn = pop(@twwns);
					}
				}
				} else {
					if ($rflg == 0) {
						@iscsilun = `/sbin/iscsi-ls -l 2>/dev/null`;
						$rflg = 1;
					} 
				foreach my $iline (@iscsilun) {
					chomp $iline;
					if ($iline =~ /^TARGET NAME (.*) (.*)/) {
						my $tpwwn = $2;
						push @twwns, $tpwwn;
					} elsif ($iline =~ /Device: \/dev\/$tlun/) {
						$hwwn = $hpn;
						$twwn = pop(@twwns);
					}
				}
				}
				if ((!defined($hwwn)) && (!defined($twwn))) {
				#  add fc part here, there is a common up from multipath cmd
					my @file = glob "/sys/block/$2/device/../../../fc_host*/port_name";
					if (defined($file[0])) {
					} else {
						@file = glob "/sys/block/$2/device/../../../fc_host*/host*/port_name";
					}
					if (defined($file[0])) {
						$hwwn = readfile($file[0]);
						$hwwn =~ s/0x//;
					}
					@file = glob "/sys/block/$2/device/../fc_transport*/port_name";
					if (defined($file[0])) {
					} else {
						@file = glob "/sys/block/$2/device/../fc_transport*/target*/port_name";
					}
					if (defined($file[0])) {
						$twwn = readfile($file[0]);
					} else {
						# for 2.4 kernel dir for qlogic
						@owwns = get_wwn24($1);
						foreach my $owwn (@owwns) {
							if (defined($owwn->{'host_wwn'})) {
								# get the port and add the path no here
								$hwwn = $owwn->{'host_wwn'};
							}
							if (defined($owwn->{'tgt_wwn'})) {
								$twwn = $owwn->{'tgt_wwn'};
							}
						}
					}
				}
				# finally got wwn information
				if (defined($hwwn) && defined($twwn)) {
				if (($3 =~ /\[active\]/) || ((defined $pstate[1]) && (($pstate[1] eq 'active') || ($pstate[1] eq '[active]')))) {
		        $lun->{'gdpathcnt'}++;
						$hwwn =~ s/0x//;
						$twwn =~ s/0x//;
						$lun->{'paths'}->{$hwwn}->{$twwn} = "OK";
		       } else {
						$hwwn =~ s/0x//;
						$twwn =~ s/0x//;
						$lun->{'paths'}->{$hwwn}->{$twwn} = "unavailable";
					}
				}
			}
        }
    }
    if (defined($lun)) {
        push @luns, $lun;
    }
    return @luns;
}


#
# Get LUN multipath info for a Linux host using device-mapper
#
sub getlinuxdmlun {
    my @multipath = `multipath -l 2> /dev/null`;
  
    my $fpmpol = getfpmforlinux("path_checker");
    my $fpmint = getfpmforlinux("no_path_retry");

	my @owwns;
    my @luns;
    my $lun;
		my $rh6;
    foreach my $line (@multipath) {
        chomp $line;
        if ($line =~ /^(.)([0-9a-fA-F]{16}).*3PARdata,VV/ or
				$line =~ /^(.)(50002ac[0-9a-fA-F]{9})/ or
				$line =~ /^(.*) (\(.[0-9a-fA-F]{16})/ or
				$line =~ /^(.*)(\(.[0-9a-fA-F]{16}).*3PARdata,VV/) {
            if (defined($lun)) {
                push @luns, $lun;
                undef $lun;
            }
			my $len = length($2);
			if ($len==18) {
			  $lun->{'wwn'} = substr($2, 2);
			} else {
              $lun->{'wwn'} = $2;
			}
			my $dlen = length($1);
			if ($dlen > 1) {
			  $lun->{'devname'} = $1;
			  $lun->{'devname'} =~ s/\s+$//;	
			} else {
			  $lun->{'devname'} = $1.$2;
			}
			$lun->{'fpmpolicy'} = $fpmpol;
			$lun->{'fpminterval'} = $fpmint;
		} elsif (defined($lun)) {
			if ($line =~ /^\\\_ ([^ ]+) +(.*)/ or
					$line =~ /^\\` ([^ ]+) +(.*)/ or
					$line =~ /^\`\-\+\- (policy[^ ]+) +(.*)/) {
							if ($1 =~ /^(policy\=\'[^ ]+)/) {
								(my $gb, my $iop) = split('\'', $1);
								$lun->{'iopolicy'} = $iop;
							} else {
	           		$lun->{'iopolicy'} = $1;
							}
			} elsif ($line =~ /^ \\\_ ([^ ]+) +([^ ]+) +[^ ]+ +(.*)/ or
							$line =~ /^  \\\_ ([^ ]+) +([a-z]+) +(.*)/ or
							$line =~ /^  \\|_ ([^ ]+) +([a-z]+) +(.*)/ or
							$line =~ /^  \`\- ([^ ]+) +([a-z]+) +(.*)/ or
							$line =~ /^  \|\- ([^ ]+) +([a-z]+) +(.*)/) {
								my ($hwwn, $twwn);
	            	$lun->{'totpathcnt'}++;
								my @pstate = split(' ', $3);
				my @file = glob "/sys/block/$2/device/../../../fc_host*/port_name";
				if (defined($file[0])) {
				} else {
					@file = glob "/sys/block/$2/device/../../../fc_host*/host*/port_name";
				}
				if (defined($file[0])) {
					$hwwn = readfile($file[0]);
					$hwwn =~ s/0x//;
				}
		
				@file = glob "/sys/block/$2/device/../fc_transport*/target*/port_name";
				if (defined($file[0])) {
					$rh6 = 1;
				} else {
					@file = glob "/sys/block/$2/device/../fc_transport*/port_name";
				}
				if (defined($file[0])) {
					$twwn = readfile($file[0]);
				} else {
					#print("falls for old 2.4 kernel.\n");
					@owwns = get_wwn24($1);
					foreach my $owwn (@owwns) {
						if (defined($owwn->{'host_wwn'})) {
							# get the port and add the path no here
							$hwwn = $owwn->{'host_wwn'};
						}
						if (defined($owwn->{'tgt_wwn'})) {
							$twwn = $owwn->{'tgt_wwn'};
						}
					}
				}

				if (defined($hwwn) && defined($twwn)) {
				if (($3 =~ /\[active\]/) || ((defined $pstate[1]) && (($pstate[1] eq 'active') || ($pstate[1] eq '[active]')))) {
		        $lun->{'gdpathcnt'}++;
						$hwwn =~ s/0x//;
						$twwn =~ s/0x//;
						$lun->{'paths'}->{$hwwn}->{$twwn} = "OK";
		       } else {
						$hwwn =~ s/0x//;
						$twwn =~ s/0x//;
						$lun->{'paths'}->{$hwwn}->{$twwn} = "unavailable";
					}
				}
				
			}
        }
    }
    if (defined($lun)) {
        push @luns, $lun;
    }

    return @luns;
}

#
# Get vxdmp node info for Linux using vxdmpadm command
#
# get the enclosure for 3PARADATA
# find the dmpnodename wrt to the enclosure name
sub getlinuxvxlun() {
  my @luns;
  my $lun;
  my $gb;
  my $encln;
  my $fpmval=0;
  my $fpmtok;
  my $tmpfpmval=0;
  my $tmpfpmtok;

  my @encl_list = `vxdmpadm listenclosure all | grep 3PARDATA` ;

  foreach my $line (@encl_list) {
    chomp $line;
		if ($line =~ /^3PARDATA. (.*)(.*)(.*) / or
			$line =~ /^3pardata. (.*)(.*)(.*) /) {
			($encln, $gb, $gb, my $state) = split(' ', $line);
			next if ($state eq 'DISCONNECTED');
		}
    my @dmplun = `vxdmpadm getdmpnode enclosure=$encln | tail -n +3`;
    my $iopolicy = `vxdmpadm getattr enclosure $encln iopolicy | tail -n +3 | awk '{print \$3}'`;

		# fpm policy and fpm interval
		my @dmpfpm=`vxdmpadm getattr enclosure $encln recoveryoption | tail -n +3`;
		foreach my $rline (@dmpfpm) {
			($gb, $tmpfpmtok, $gb, $tmpfpmval) = split(' ', $rline);
			($gb, $tmpfpmval) = split(/(\d+)/, $tmpfpmval);
			if (defined $fpmtok) {
				$fpmtok = $tmpfpmtok . " and " . $fpmtok;
			} else {
				$fpmtok = $tmpfpmtok;
			}
			$fpmval = $tmpfpmval+$fpmval;
		}

    foreach my $dline (@dmplun) {
      chomp $dline;
      if (defined($lun)) {
	  push @luns, $lun;
	  undef $lun;
      }
     ($lun->{'devname'}, $gb, $gb, $lun->{'gdpathcnt'}, $lun->{'totpathcnt'}, $gb, $gb) = split(' ', $dline);
      $lun->{'iopolicy'} = $iopolicy;
      $lun->{'iopolicy'} =~ s/\s$//;
	  $lun->{'fpmpolicy'} = $fpmtok;
	  $lun->{'fpminterval'} = $fpmval;
	
      my $vxdmpinq = "/etc/vx/diag.d/vxscsiinq"; # use vxscsiinq for vxvm 51
      $vxdmpinq = "/etc/vx/diag.d/vxdmpinq" if (! -e $vxdmpinq);
      my $lunid = `$vxdmpinq  /dev/vx/rdmp/$lun->{'devname'} |  grep Serial | awk -F: '{ print \$2}'` ;
      $lunid =~ s/^\s+//;
      if ($lunid) {
        $lun->{'wwn'} = join "", "5000", $lunid;
        $lun->{'wwn'} =~ s/\s+$//;
      }

      my @dmpinfo = `vxdmpadm getsubpaths dmpnodename=$lun->{'devname'} | tail -n +3 | awk '{print \$1 , \$2 }'`;
      my ($hwwn, $twwn);
      foreach $line (@dmpinfo) {
	  chomp $line;
	  my $path; 
	  my $state;
      	 ($path, $state) = split(' ', $line);
	  my @file = glob "/sys/block/$path/device/../../../fc_host*/port_name";

	  if (defined($file[0])) {
		$hwwn = readfile($file[0]);
		$hwwn =~ s/0x//;
	  }

	  @file = glob "/sys/block/$path/device/../fc_transport*/port_name";
	  if (defined($file[0])) {
		$twwn = readfile($file[0]);
	  }
	  if (defined($hwwn) && defined($twwn)) {
		if ($state eq 'ENABLED(A)') {
		  $hwwn =~ s/0x//;
		  $twwn =~ s/0x//;
		  $lun->{'paths'}->{$hwwn}->{$twwn} = "OK";
		} else {
		  $hwwn =~ s/0x//;
		  $twwn =~ s/0x//;
		  $lun->{'paths'}->{$hwwn}->{$twwn} = "unavailable";
		}
	  }
	}
    }
    if (defined($lun)) {
	push @luns, $lun;
     }
  }
  return @luns;
}

#
# Get LUN multipath info for a Solaris host using mpathadm
#
sub getsolarislun {
    my @multipath = `mpathadm list lu 2>/dev/null`;
    
    my @luns;
    my $lun;
    foreach my $line (@multipath) {
        chomp $line;
        if ($line =~ /^\s+(\/dev\/rdsk\/[^ ]+)/) {
            if (defined($lun)) {
                push @luns, $lun;
                undef $lun;
            }
            my @luninfo = `mpathadm show lu $1 2>/dev/null`;
			$lun->{'devname'} = $1;
			$lun->{'devname'} =~ s/^\/dev\/rdsk\///;
			$lun->{'devname'} =~ s/s\d+$//;
			my ($hwwn, $twwn);
            foreach $line (@luninfo) {
                chomp $line;
                if ($line =~ /^\sName:\s+([^ ]+)/) {
                    $lun->{'wwn'} = $1;
                } elsif ($line =~ /^\s+Current Load Balance:\s+([^ ]+)/) {
                    $lun->{'iopolicy'} = $1;
                } elsif ($line =~ /^\s+Initiator Port Name:\s+([^ ,]+)/) {
					$hwwn = $1;
                } elsif ($line =~ /^\s+Target Port Name:\s+([^ ]+)/) {
					$twwn = $1;
					$twwn =~ s/,[^,]*$//;
					$twwn =~ s/^[^,]*,//;
                } elsif ($line =~ /^\s+Path State:\s+([^ ]+)/) {
					$lun->{'paths'}->{$hwwn}->{$twwn} = $1;
                }
            }
        } elsif ($line =~ /^\s+Total Path Count: (\d+)/) {
			if (defined($lun)){
              $lun->{'totpathcnt'} = $1;
			}
        } elsif ($line =~ /^\s+Operational Path Count: (\d+)/) {
			if (defined($lun)){
              $lun->{'gdpathcnt'} = $1;
			}
        }
    }
    if (defined($lun)) {
        push @luns, $lun;
    }

    return @luns;
}

#
# to get iscsi luns information for solaris
#
sub getsoliscsilun() {

my @luns;
my $lun;
my $tpwwn;
my $gb;
my $lundsk;
my @iluns;
my @twwns;

my $pflg = 0;
my @iscsiinfo;

my $ihwwn = `iscsiadm list initiator-node | grep "Initiator node name:"| awk '{print \$4}'`;
$ihwwn =~ s/\s$//;

my @iscsiluns = `iscsiadm list target -S | grep "OS Device Name:" | sort -u`;
foreach my $iline (@iscsiluns) {
  chomp $iline;
  if ($iline =~ /(OS Device Name:)(.\/dev\/rdsk\/[\w]*)/) {
    my $lunname = $2; 
    $lunname =~ s/^\s+//;
  	$lunname =~ s/s\d+$//;
  	($gb, $gb, $gb, $lundsk) = split(/\//, $lunname);
  }
  if (defined($lundsk)) {
	push @iluns, $lundsk;
	undef $lundsk;
  }
}

# all the luns are in the array iluns
# now process the luns to get the wwn information.

foreach my $i (@iluns) {
  chomp $i;
  if (defined($lun)) {
	push @luns, $lun;
	undef $lun;
  }
  my $tmplun = $i;
  $lun->{'devname'} = $tmplun;
  $lun->{'wwn'} = substr($tmplun, 3, 16);

	if ($pflg == 0) {
  	@iscsiinfo = `iscsiadm list target -S`;
		$pflg = 1;
	}
  foreach my $line (@iscsiinfo) {
    chomp $line;
    if ($line =~ /Target: (.*)/) {
        my $tpwwn=$1;
		push(@twwns, $tpwwn);
    } elsif ($line =~ /(OS Device Name:)(.\/dev\/rdsk\/$i)(.*)/) {

		$lun->{'totpathcnt'}++;
		my ($hwwn, $twwn);
        $twwn = pop(@twwns);
	    $hwwn = $ihwwn;
        
        # call a function to determine another path
        if (defined($hwwn) && defined($twwn)) {
		    $lun->{'paths'}->{$hwwn}->{$twwn} = "OK";
        }
    }
  }
}
  if (defined($lun)) {
	push @luns, $lun;
  }
  return @luns;
}

#
# if there is no mpathadm command 
#
sub getsolarisnomplun() {

my @luns;
my $lun;
my $disk;
my $line;

#my @disklist = `format < /dev/null`;
my @disklist = `luxadm probe 2>/dev/null`;
foreach $line (@disklist) {
	chomp $line;
        if ($line =~ /Logical Path:(.*)/) {
		if (defined($lun)) {
			push @luns, $lun;
			undef $lun;
		}

		# display disk information
		my @diskinfo = `luxadm display $1 2>/dev/null`;
		my $tmplun = $1;
		$lun->{'devname'} = $1;
		$lun->{'devname'} =~ s/^\/dev\/rdsk\///;
		$lun->{'devname'} =~ s/s\d+$//;
		my ($hwwn, $twwn);

		foreach $line (@diskinfo) {
			chomp $line;
			if ($line =~ /Serial Num:(.*)/) {
				$lun->{'wwn'} = $1;
				$lun->{'wwn'} =~ s/^\s+//;
				$lun->{'wwn'} = "50002AC0".$lun->{'wwn'};
				# get iopolicy globally  for now add
				$lun->{'iopolicy'} = "round-robin";
			} elsif ($line =~ /Host controller port WWN:(.*)/ or
				 	  $line =~ /Host controller port WWN(.*)/) {
				$hwwn = $1;
				$hwwn =~ s/^\s+//;
				$hwwn =~ s/\s+$//;
				# get the target port here
			} elsif ($line =~ /Device Address(.*)/ or
										$line =~ /LUN path port WWN:(.*)/) {
				$twwn = $1;
				$twwn =~ s/^\s+//;
				($twwn, my $gb) = split(',', $twwn);
				if (!defined($twwn)) {
					$twwn = find_target_port($hwwn, $tmplun);
				}
			} elsif ($line =~ /Path status:(.*)/ or
					  $line =~ /State(.*)/) {
				$lun->{'paths'}->{$hwwn}->{$twwn} = $1;
				$lun->{'paths'}->{$hwwn}->{$twwn} =~ s/^\s+//;
			}
		}

	}
}
if (defined($lun)) {
	push @luns, $lun;
}
	return @luns;
}

#
# get the details of dmp node information for solaris
#
sub getvxdmpsollun() {
	my @luns;
	my $lun;
	my $gb;
	my $encln; 
	my $found=0;
	my $tmpfpmval=0;
	my $tmpfpmtok;
	my $fpmtok;
	my @twwns;

	my @encl_list = `vxdmpadm listenclosure all | grep 3PARDATA` ;
	# check for disconected enclosures here.

	foreach my $line (@encl_list) {
		chomp $line;
		if (defined($lun)) {
			undef $lun;
		}
		
		if ($line =~ /^3PARDATA. (.*)(.*)(.*) / or
				$line =~ /^3pardata. (.*)(.*)(.*) /) {
			($encln, $gb, $gb, my $state) = split(' ', $line);
			next if ($state eq 'DISCONNECTED');
		}
		my @dmplun = `vxdmpadm getdmpnode enclosure=$encln | tail +3`;
		my $iopolicy = `vxdmpadm getattr enclosure $encln iopolicy | tail +3 | awk '{print \$3}'`;
		undef $fpmtok;
		my $fpmval=0;
		# fpm policy and fpm interval
		my @dmpfpm=`vxdmpadm getattr enclosure $encln recoveryoption | tail +3`;
		foreach my $rline (@dmpfpm) {
			($gb, $tmpfpmtok, $gb, $tmpfpmval) = split(' ', $rline);
			($gb, $tmpfpmval) = split(/(\d+)/, $tmpfpmval);
			if (defined $fpmtok) {
				$fpmtok = $tmpfpmtok . " and " . $fpmtok;
			} else {
				$fpmtok = $tmpfpmtok;
			}
			$fpmval = $tmpfpmval+$fpmval;
		}

		foreach my $dline (@dmplun) {
			chomp $dline;
			if (defined($lun)) {
				push @luns, $lun;
				undef $lun;
			}
			($lun->{'devname'}, $gb, $gb, $lun->{'gdpathcnt'}, $lun->{'totpathcnt'}, $gb, $gb) = split(' ', $dline);
			$lun->{'iopolicy'} = $iopolicy;
			$lun->{'iopolicy'} =~ s/\s$//;
            my $vxdmpinq = "/etc/vx/diag.d/vxscsiinq"; # use vxscsiinq for vxvm 51
            $vxdmpinq = "/etc/vx/diag.d/vxdmpinq" if (! -e $vxdmpinq);
            my $lunid = `$vxdmpinq  /dev/vx/rdmp/$lun->{'devname'} |  grep Serial | awk -F: '{ print \$2}'` ;

            $lunid =~ s/^\s+//;
            if ($lunid) {
		$lun->{'wwn'} = join "", "5000", $lunid;
		$lun->{'wwn'} =~ s/\s+$//;
            }

			$lun->{'fpmpolicy'} = $fpmtok;
			$lun->{'fpminterval'} = $fpmval;

			my @dmpinfo = `vxdmpadm getsubpaths dmpnodename=$lun->{'devname'} | tail +3 | awk '{print \$1 , \$2 }'`;
			
			foreach $line (@dmpinfo) {
				chomp $line;
				my $path;
				my $state;
				($path, $state) = split(' ', $line);
				my ($hwwn, $twwn);

			# check if the dmp path is iscsi here
				my $nfound_iscsi = 0;
				if ($path =~ /^(c[\d]*)(t[\d]*)(d[\d]*)(.*)/ or
						$path =~ /^(c[\d]*)(t[0-9a-fA-F]*)(d[\d]*)(.*)/) {
					$nfound_iscsi = 1;
				}
	
				if ($nfound_iscsi) { # wwn info for fc devices
				my @wwninfo = `luxadm display /dev/rdsk/$path 2>/dev/null`;
				foreach my $wline (@wwninfo) {
					chomp $wline;
					if ($wline =~/^\s+(\/dev\/rdsk\/$path)/) {
						$found=1;
					} elsif ($wline =~ /^\s+LUN path port WWN:\s+([^ ]+)/) {
						if ($found eq 1) {
						$twwn=$1;
						}
					} elsif ($wline =~ /^\s+Host controller port WWN:\s+([^ ]+)/) {
						if ($found eq 1) {
						$hwwn=$1;
						$found=0;
						}
					}
				}
				} else {
					my $diskname = get_dname($path);
					$diskname =~ s/\s+$//;

					my $ihwwn = `iscsiadm list initiator-node | grep "Initiator node name:"| awk '{print \$4}'`;
					$ihwwn =~ s/\s$//;
					my @iscsiwwn = `iscsiadm list target -S 2>/dev/null`;
					foreach  my $iline (@iscsiwwn) {
						chomp $iline;
						if ($iline =~ /Target: (.*)/) {
							my $tpwwn=$1;
							push @twwns, $tpwwn;
						} elsif ($iline =~ /(OS Device Name:)(.\/dev\/rdsk\/$diskname)/) {
							$hwwn = $ihwwn;
							$twwn = pop(@twwns);
						}
					}
				} # iscsi

				# get the port details of a path here
				if (defined($hwwn) && defined($twwn)) {
					if ($state eq 'ENABLED(A)') {
						$lun->{'paths'}->{$hwwn}->{$twwn} = "OK";
					} else {
						$lun->{'paths'}->{$hwwn}->{$twwn} = "unavailable";
					}
				}
			}
		}
		if (defined($lun)) {
			push @luns, $lun;
		}
	}
	return @luns;
}

##
## Main entry here
##

	log_data("Collecting TOKEN information: START\n");
	log_data("------------------------------------\n");
print "TPDAGENTVER=${version}\n";
	log_data("TPDAGENTVER=${version}\n");

my $hname = `hostname`;
chomp $hname;
print "HNAME=${hname}\n";
	log_data("HNAME=${hname}\n");		

# uniq host id 
my $uniqid = `hostid`;
print "HOSTID=${uniqid}";
	log_data("HOSTID=${uniqid}");

my $ncpu = `uname -m`;
chomp $ncpu;

$ip = getipaddr;

if ($^O eq 'MSWin32') {
	$os = 'Windows';
} else {
	$os=`uname`;
	chomp $os;
}

print "OS=${os}\n";
	log_data("OS=${os}\n");	

if ($os eq 'Linux') {
    my $linuxver = `uname -r`;
    chomp $linuxver;
    $linuxver =~ /^([^.]*.[^.]*)\.(.*)/;
    $osver = $1;
    print "OSVER=${osver}\n";
	log_data("OSVER=${osver}\n");	
    print "OSPATCH=$2\n";
	log_data("OSPATCH=$2\n");

	# uname -p will give cpu type
	# my $ncpu = `cat /proc/cpuinfo | grep "model name" | sort -u | awk '{print \$4 \$5}'`;
	print "ARCH=${ncpu}\n";
	log_data("ARCH=${ncpu}\n");
	print "IP=${ip}\n";
	log_data("IP=${ip}\n");

	# check iscsi configured
	if (system("ps -C iscsid -o pid= > /dev/null") ==0) {
	    $is_net = 0;
    } else {
	    $is_net = 1;
    }
	if ($is_net == 0) {
		$is_net = (dir_is_empty("/sys/class/iscsi_host/"));
	}

	if ((system("ps -C multipathd -o pid= > /dev/null") == 0) || (system("lsmod | grep dm_multipath >/dev/null") ==0)) {
		$mpsw = 'device-mapper';
		if (-e '/usr/bin/dpkg-query') {
			$mpswver = `dpkg-query -f '\${version}' --show multipath-tools`;
		} else {
			$mpswver = `rpm -qa device-mapper-multipath | sort -u | awk -F- '{print \$4"-"\$5}'`;
		}
		chomp $mpswver;
	}

	if (system("ps -C vxconfigd -o pid= > /dev/null") == 0) {
		$mpsw = 'vxdmp';
		$mpswver = `rpm -qa | grep VRTSvxvm-platform | awk -F- '{print \$3"-"\$4}'`;
		if (!$mpswver) {
			$mpswver = `rpm -qa | grep VRTSvxvm | awk -F- '{print \$2"-"\$3}'`;
		}
		chomp $mpswver;
	}
	if (defined($mpsw) && ($mpsw eq 'vxdmp')) {
		if (-x '/opt/VRTS/bin/haclus') {
			my $clustate = `/opt/VRTSvcs/bin/haclus -value ClusState`;
			chomp $clustate;

			# display cluster token if the cluster is running
			$clus= 'Veritas Cluster Services';
			#$clusver = `rpm -qa | grep VRTSvcs- | awk -F- '{print \$3"-"\$4}'`;
			$clusver = `/opt/VRTSvcs/bin/haclus  -value EngineVersion 2>/dev/null`;
			chomp $clusver;
			if ( -e "/etc/llttab/") {
				$clusid = `grep "set-cluster" /etc/llttab | awk '{print \$2}'`;
				chomp $clusid;
			}
			$clusname = `/opt/VRTSvcs/bin/haclus -value ClusterName 2>/dev/null`;
			chomp $clusname;
		}
	}
} elsif ($os eq 'SunOS') {
    $osver=`uname -r`;
    chomp $osver;
    print "OSVER=${osver}\n";
	log_data("OSVER=${osver}\n");
	
	my $ospat=`uname -v`;
	chomp $ospat;
	print "OSPATCH=${ospat}\n";
	log_data("OSPATCH=${ospat}\n");

	# cpu type
	# my $cputype = `psrinfo -v | grep "operates at" | head -1 | awk '{print \$2}'`;
	print "ARCH=${ncpu}\n";
	log_data("ARCH=${ncpu}\n");
	print "IP=${ip}\n";
	log_data("IP=${ip}\n");

	# patch information
 	my $solpatchinfo = `showrev -p | nawk '{ print \$1 ":" \$2}'`;
	print "PATCHINFO=${solpatchinfo}";

	my $is_vxvm = 0;
    my $is_val=`modinfo | egrep iscsi | awk '{print \$1}'`;
    if (($is_val ne " ") && ($is_val gt 0)) {
		$is_net = 1;
	} else {
		$is_net = 0;
	}

	if (-x '/usr/sbin/vxdmpadm') {
		# check for vxconfigd running
		my $vxpid = `pgrep vxconfigd`;
		if ($vxpid gt 0) {
			$mpsw = 'VXDMP';
			$mpswver = `pkginfo -l VRTSvxvm | grep "VERSION:" | awk '{ print \$2}'`;
			chomp $mpswver;
			$mppstamp = `pkginfo -l VRTSvxvm | grep "PSTAMP:" | awk '{ print \$2}'`;
			chomp $mppstamp;
			$mpswver = join "", $mpswver,":", $mppstamp;
			$is_vxvm = 1;
		}
	} elsif (-x '/usr/sbin/mpathadm') {
		$mpsw = 'MPXIO';
		$mpswver = `uname -r`;
		chomp $mpswver;
	}

	if ($is_vxvm eq 0) {
		$mpsw = 'MPXIO';
		$mpswver = `uname -r`;
		chomp $mpswver;
	}

	# CHECK FOR CLUSTER TYPE
	if (defined($mpsw)) {
		if (-x '/opt/VRTS/bin/haclus') {
			$clus = 'VERITAS CLuster Services';
		#	$clusver = `pkginfo -l VRTSvcs |  grep "VERSION:" | awk '{ print \$2}'`;
			$clusver = `/opt/VRTSvcs/bin/haclus  -value EngineVersion 2>/dev/null`;
			chomp $clusver;
			if ( -e "/etc/llttab/") {
				$clusid = `grep "set-cluster" /etc/llttab | awk '{print \$2}'`;
				chomp $clusid;
			}
			$clusname = `/opt/VRTSvcs/bin/haclus -value ClusterName`;
			chomp $clusname;	
		} elsif (-x '/usr/cluster/bin/scinstall') {
			$clus = 'Sun Cluster';
			chomp $clus;
			# check for usr/cluster/bin/scversions cmd
			$clusver = `/usr/cluster/bin/scinstall -p`;
			chomp $clusver;
			$clusid = `/usr/cluster/bin/scconf -p -v | grep "Cluster ID" | awk -F: '{print \$2}'`;
			$clusid =~ s/^\s+//;	
			$clusid =~ s/^\s+//;	
			chomp $clusid;
			$clusname = `/usr/cluster/bin/scconf -p -v | grep "Cluster name" | awk -F: '{print \$2}'`;
			$clusname =~ s/^\s+//;	
			$clusname =~ s/^\s+//;	
			chomp $clusname;
		}
	}

} elsif ($os eq 'Windows') {
	eval 'use Win32; $osver = Win32::GetOSName();';
    print "OSVER=${osver}\n";
} elsif ($os eq 'AIX') {
    $osver=`oslevel`;
    chomp $osver;
    $osver =~ s/\.\d+.\d+$//;
    print "OSVER=${osver}\n";
}
if (defined($mpsw)) {
	print "MPSW=${mpsw}\n";
	log_data("MPSW=${mpsw}\n");
}

if (defined($mpswver)) {
	print "MPSWVER=${mpswver}\n";
	log_data("MPSWVER=${mpswver}\n");
}

if (defined($clus)) {
	print "CLUSTERSW=${clus}\n";
	log_data("CLUSTERSW=${clus}\n");
}

if (defined($clusver)) {
	print "CLUSTERSWVER=${clusver}\n";
	log_data("CLUSTERSWVER=${clusver}\n");
}

if (defined($clusid)) {
	print "CLUSTERID=${clusid}\n";
	log_data("CLUSTERID=${clusid}\n");
}

if (defined($clusname)) {
	print "CLUSTERNAME=${clusname}\n";
	log_data("CLUSTERNAME=${clusname}\n");
}

my @hbas;
if ($os eq 'SunOS') {
	if (-x '/usr/sbin/fcinfo') {
    	@hbas = getsolarisfchba();
	} elsif (-x '/usr/sbin/luxadm') {
    	@hbas = getsolarisluxhba();
	}
} elsif ($os eq 'Linux' && $osver eq '2.4') {
    @hbas = getlinux24hba();
} elsif ($os eq 'Linux' && $osver eq '2.6') {
    @hbas = getlinux26hba();
} elsif ($os eq 'Windows') {
    @hbas = getwindowshba();
} elsif ($os eq 'AIX') {
    @hbas = getaixhba();
}

my $curhba = 0;
foreach my $hba (@hbas) {
    #
    # We may not be able to get every piece of information for each HBA, so
    # only output what we have.
    #
    if (defined($hba->{'port_name'})) {
        print "HBA${curhba}WWN=", $hba->{'port_name'}, "\n";
        log_data("HBA${curhba}WWN=$hba->{'port_name'}\n");
    }
    if (defined($hba->{'vendor'})) {
        print "HBA${curhba}VEN=", $hba->{'vendor'}, "\n";
		log_data("HBA${curhba}VEN=$hba->{'vendor'}\n");
    }
    if (defined($hba->{'model_name'})) {
        print "HBA${curhba}MODEL=", $hba->{'model_name'}, "\n";
        log_data("HBA${curhba}MODEL=$hba->{'model_name'}\n");
    }
    if (defined($hba->{'driver'})) {
        print "HBA${curhba}DRVR=", $hba->{'driver'}, "\n";
        log_data("HBA${curhba}DRVR=$hba->{'driver'}\n");
    }
    if (defined($hba->{'driver_version'})) {
        print "HBA${curhba}DRVRVER=", $hba->{'driver_version'}, "\n";
        log_data("HBA${curhba}DRVRVER=$hba->{'driver_version'}\n");
    }
    if (defined($hba->{'fw_version'})) {
        print "HBA${curhba}FIRMWARE=", $hba->{'fw_version'}, "\n";
        log_data("HBA${curhba}FIRMWARE=$hba->{'fw_version'}\n");
    }
    if (defined($hba->{'speed'})) {
        print "HBA${curhba}SPEEDCURRENT=", $hba->{'speed'}, "\n";
        log_data("HBA${curhba}SPEEDCURRENT=$hba->{'speed'}\n");
    }
    $curhba++;
}

my @luns;
my @luns1;
my $mp=1;
if ($os eq 'SunOS' && defined($mpsw)) {
	if ($mpsw eq 'MPXIO') {
		if  (-x '/usr/sbin/mpathadm') {
			@luns = getsolarislun();
			my $mp=0;
		} else {
			@luns = getsolarisnomplun();
		}
		if (($is_net == 1) && ($mp == 1)){
			@luns1 = getsoliscsilun();
			@luns = (@luns, @luns1);
		#	@luns = getsoliscsilun();		
		}
	} elsif ($mpsw eq 'VXDMP') {
		@luns = getvxdmpsollun();
	}
} elsif ($os eq 'Linux' && defined($mpsw)) {
	if ($mpsw eq 'device-mapper') {
	  if ($is_net == 0) {
	      @luns = getlinuxiscsidmlun();
   	  } else {
   	      @luns = getlinuxdmlun();
	  }
	} elsif ($mpsw eq 'vxdmp') {
   	    @luns = getlinuxvxlun();
	}
}
my $curlun = 0;
foreach my $lun (@luns) {
	if (defined($lun->{'wwn'})) {
	print "DEVICE${curlun}WWN=", $lun->{'wwn'}, "\n";
	}
	if (defined($lun->{'devname'})){
        print "DEVICE${curlun}NAME=", $lun->{'devname'}, "\n";
        log_data("DEVICE${curlun}NAME=$lun->{'devname'}\n");
	}
	if (defined($lun->{'iopolicy'})){
        print "DEVICE${curlun}IOPOLICY=", $lun->{'iopolicy'}, "\n";
        log_data("DEVICE${curlun}IOPOLICY=$lun->{'iopolicy'}\n");
	}
	if (defined($lun->{'fpmpolicy'})){
        print "DEVICE${curlun}FPMPOLICY=", $lun->{'fpmpolicy'}, "\n";
        log_data("DEVICE${curlun}FPMPOLICY=$lun->{'fpmpolicy'}\n");
	}
	if (defined($lun->{'fpminterval'})){
        print "DEVICE${curlun}FPMINTERVAL=", $lun->{'fpminterval'}, "\n";
        log_data("DEVICE${curlun}FPMINTERVAL=$lun->{'fpminterval'}\n");
	}
	if (defined($lun->{'totpathcnt'})){
        print "DEVICE${curlun}TOTPATHCNT=", $lun->{'totpathcnt'}, "\n";
        log_data("DEVICE${curlun}TOTPATHCNT=$lun->{'totpathcnt'}\n");
	}
	if (defined($lun->{'gdpathcnt'})){
        print "DEVICE${curlun}GDPATHCNT=", $lun->{'gdpathcnt'}, "\n";
        log_data("DEVICE${curlun}GDPATHCNT=$lun->{'gdpathcnt'}\n");
	}
	#
	# If we have details of the paths, output them.
	#
	if (defined($lun->{'paths'})) {
		my $curpath = 0;
		foreach my $hwwn (keys %{$lun->{'paths'}}) {
			print "DEVICE${curlun}PATH${curpath}HWWN=", $hwwn, "\n";
			log_data("DEVICE${curlun}PATH${curpath}HWWN=$hwwn\n");
			my $curtwwn = 0;
			foreach my $twwn (keys %{$lun->{'paths'}->{$hwwn}}) {
				print "DEVICE${curlun}PATH${curpath}TWWN${curtwwn}=", 
						$twwn, "\n";
				log_data("DEVICE${curlun}PATH${curpath}TWWN${curtwwn}=$twwn\n");
				print "DEVICE${curlun}PATH${curpath}TWWN${curtwwn}STATE=", 
						$lun->{'paths'}->{$hwwn}->{$twwn}, "\n";
				log_data("DEVICE${curlun}PATH${curpath}TWWN${curtwwn}STATE=$lun->{'paths'}->{$hwwn}->{$twwn}\n");
				$curtwwn++;
			}
			$curpath++;
		}
	}
    $curlun++;
}

log_data("TOKEN Collection: END \n");

exit;
