# $Header: Ptdpm2.pm 17-nov-2004.12:05:37 mgoodric Exp $
#
# Package : Ptdpm2.pm
#
# Copyright (c) 2002, 2004, Oracle. All rights reserved.  
#
#   NAME
#       Ptdpm2.pm
#
#   DESCRIPTION
#       Collects hardware and software data
#
#   NOTES
#
#   MODIFIED     (MM/DD/YY)
#      mgoodric   04/28/05 - fix for no OS components found
#      mgoodric   11/17/04 - add MGMT_HC_xxx tablenames 
#      mgoodric   09/27/04 - code cleanup 
#      mgoodric   05/27/04 - Add constants for trunc() function
#      mgoodric   03/21/04 - Linux cleanup
#      mgoodric   07/14/03 - fix for converting to UTF8 data
#      mgoodric   07/08/03 - fix output when on VENDOR_SOFTWARE available
#      mgoodric   05/11/03 - added -debug tracing
#      mgoodric   04/08/03 - fix finding MAC address
#      rlal       02/25/03 - EM 4.0 changed for Linux
#      goramamo   10/23/02 - removed mount time
#      goramamo   08/15/02 - 904 Changes
#      goramamo   07/12/02 - To handle nic_log_intf
#      xxu        06/25/02 - remove /usr/local/bin/perl
#      goramamo   06/01/02 - GIT5 Changes
#      mgoodric   02/14/02 - Make scripts more portable
#      jmansur    01/24/02 - add appendosparamXML
#      goramamo   10/15/01 - Creation
#
##*************************************************************

use strict;

package Ptdpm2;

use Carp;
require 5.005;

#require 5.6.1;
require Exporter;

use Ptdpm3;
use Ptdpm4;

#******************************************
#   Export Subroutines
#******************************************

@Ptdpm2::ISA    = ('Exporter');
@Ptdpm2::EXPORT = qw(
  &appendsysXML
  &appendhwXML

  &appendossumXML
  &appendOSConfHashXML
  &appendOSHashXML
  &appendfsXML

  &appendVendorHashXML

  &typeBegin
  &typeValue
  &typeEnd
  &typeEndSubComponent
  &typeEndOSSubComponent
  &typeEndVendorSubComponent
  &typeOScompXML
  );

#******************************************
#     Global Variables
#******************************************

use constant NOT_FOUND => -1;
use constant NIL => '';

# Hardware details

$Ptdpm2::MGMT_HC_SYSTEM_SUMMARY     = 'MGMT_HC_SYSTEM_SYMMARY';
$Ptdpm2::HARDWARE_TAG               = 'HARDWARE';
$Ptdpm2::SUBCOMPONENT_TAG           = 'SUBCOMPONENT';
$Ptdpm2::SYSTEM_SUMMARY_TAG         = 'SYSTEM_SUMMARY';
$Ptdpm2::HOSTNAME_TAG               = 'HOSTNAME';
$Ptdpm2::DOMAIN_TAG                 = 'DOMAIN';
$Ptdpm2::CC_PARTNER_INFO_TAG        = 'CC_PARTNER_INFO';
$Ptdpm2::CC_SOFTWARE_VERSION_TAG    = 'CC_SOFTWARE_VERSION';
$Ptdpm2::CC_SOFTWARE_BUILD_DATE_TAG = 'CC_SOFTWARE_BUILD_DATE';

$Ptdpm2::MGMT_HC_HARDWARE_MASTER          = 'MGMT_HC_HARDWARE_MASTER';
$Ptdpm2::HARDWARE_DETAILS_TAG             = 'HARDWARE_DETAILS';
$Ptdpm2::HARDWARE_PROVIDER_TAG            = 'HARDWARE_PROVIDER';
$Ptdpm2::SYSTEM_CONFIGURATION_TAG         = 'SYSTEM_CONFIGURATION';
$Ptdpm2::MACHINE_ARCHITECTURE_TAG         = 'MACHINE_ARCHITECTURE';
$Ptdpm2::CLOCK_FREQUENCY_IN_MHZ_TAG       = 'CLOCK_FREQUENCY_IN_MHZ';
$Ptdpm2::MEMORY_SIZE_IN_MB_TAG            = 'MEMORY_SIZE_IN_MB';
$Ptdpm2::TOTAL_LOCAL_DISK_SPACE_IN_GB_TAG = 'TOTAL_LOCAL_DISK_SPACE_IN_GB';
$Ptdpm2::NUMBER_OF_CPUS_TAG               = 'NUMBER_OF_CPUS';
$Ptdpm2::NUMBER_OF_CPU_BOARDS_TAG         = 'NUMBER_OF_CPU_BOARDS';
$Ptdpm2::NUMBER_OF_IO_DEVICES_TAG         = 'NUMBER_OF_IO_DEVICES';
$Ptdpm2::NUMBER_OF_FANS_TAG               = 'NUMBER_OF_FANS';
$Ptdpm2::NUMBER_OF_POWER_SUPPLIES_TAG     = 'NUMBER_OF_POWER_SUPPLIES';

$Ptdpm2::MGMT_HC_CPU_DETAILS    = 'MGMT_HC_CPU_DETAILS';
$Ptdpm2::CPU_TAG                = 'CPU';
$Ptdpm2::CPU_VENDOR_TAG         = 'CPU_VENDOR';
$Ptdpm2::VENDOR_TAG             = 'VENDOR';
$Ptdpm2::CPU_SPEED_IN_MHZ_TAG   = 'CPU_SPEED_IN_MHZ';
$Ptdpm2::ECACHE_IN_MB_TAG       = 'ECACHE_IN_MB';
$Ptdpm2::CPU_IMPLEMENTATION_TAG = 'CPU_IMPLEMENTATION';
$Ptdpm2::REVISION_TAG           = 'REVISION';
$Ptdpm2::MASK_TAG               = 'MASK';

$Ptdpm2::MGMT_HC_IOCARD_DETAILS = 'MGMT_HC_IOCARD_DETAILS';
$Ptdpm2::IO_DEVICES_TAG         = 'IO_DEVICES';
#$Ptdpm2::VENDOR_TAG            = 'VENDOR';
$Ptdpm2::NAME_TAG               = 'NAME';
$Ptdpm2::FREQUENCY_IN_MHZ_TAG   = 'FREQUENCY_IN_MHZ';
$Ptdpm2::BUS_TYPE_TAG           = 'BUS_TYPE';
#$Ptdpm2::REVISION_TAG          = 'REVISION';

$Ptdpm2::MGMT_HC_NIC_DETAILS        = 'MGMT_HC_NIC_DETAILS';
$Ptdpm2::NETWORK_INTERFACE_CARD_TAG = 'NETWORK_INTERFACE_CARD';
#$Ptdpm2::NAME_TAG                  = 'NAME';
$Ptdpm2::NIC_NAME_TAG               = 'NIC_NAME';
$Ptdpm2::FLAGS_TAG                  = 'FLAGS';
$Ptdpm2::MAX_TRANSFER_UNIT_TAG      = 'MAX_TRANSFER_UNIT';
$Ptdpm2::INET_ADDRESS_TAG           = 'INET_ADDRESS';
#$Ptdpm2::MASK_TAG                  = 'MASK';
$Ptdpm2::BROADCAST_ADDRESS_TAG      = 'BROADCAST_ADDRESS';
$Ptdpm2::MAC_ADDRESS_TAG            = 'MAC_ADDRESS';
$Ptdpm2::HOSTNAME_ALIASES_TAG       = 'HOSTNAME_ALIASES';

# Operating System Details

$Ptdpm2::MGMT_HC_OS_SUMMARY            = 'MGMT_HC_OS_SUMMARY';
$Ptdpm2::OS_SOFTWARE_TAG               = 'OS_SOFTWARE';
$Ptdpm2::OS_SUMMARY_TAG                = 'OS_SUMMARY';
$Ptdpm2::OS_TAG                        = 'OS';
$Ptdpm2::OS_VENDOR_TAG                 = 'OS_VENDOR';
$Ptdpm2::OS_BASE_VERSION_TAG           = 'OS_BASE_VERSION';
$Ptdpm2::OS_UPDATE_LEVEL_TAG           = 'OS_UPDATE_LEVEL';
$Ptdpm2::OS_DISTRIBUTOR_VERSION_TAG    = 'OS_DISTRIBUTOR_VERSION';
$Ptdpm2::OS_MAX_SWAP_SPACE_IN_MB_TAG   = 'OS_MAX_SWAP_SPACE_IN_MB';
$Ptdpm2::OS_ADDRESS_LENGTH_IN_BITS_TAG = 'OS_ADDRESS_LENGTH_IN_BITS';

$Ptdpm2::MGMT_HC_OS_PROPERTIES = 'MGMT_HC_OS_PROPERTIES';
$Ptdpm2::OS_PROPERTY_TAG       = 'OS_PROPERTY';
$Ptdpm2::TYPE_TAG              = 'TYPE';
#$Ptdpm2::NAME_TAG             = 'NAME';
$Ptdpm2::VALUE_TAG             = 'VALUE';

$Ptdpm2::MGMT_HC_FS_MOUNT_DETAILS = 'MGMT_HC_FS_MOUNT_DETAILS';
$Ptdpm2::FILE_SYSTEM_TAG          = 'FILE_SYSTEM';
$Ptdpm2::RESOURCE_NAME_TAG        = 'RESOURCE_NAME';
$Ptdpm2::MOUNT_LOCATION_TAG       = 'MOUNT_LOCATION';
#$Ptdpm2::TYPE_TAG                = 'TYPE';
$Ptdpm2::MOUNT_OPTIONS_TAG        = 'MOUNT_OPTIONS';

$Ptdpm2::MGMT_HC_OS_COMPONENTS = 'MGMT_HC_OS_COMPONENTS';
$Ptdpm2::OS_COMPONENT_TAG      = 'OS_COMPONENT';
#$Ptdpm2::NAME_TAG             = 'NAME';
#$Ptdpm2::TYPE_TAG             = 'TYPE';
$Ptdpm2::VERSION_TAG           = 'VERSION';
$Ptdpm2::DESCRIPTION_TAG       = 'DESCRIPTION';
$Ptdpm2::INSTALLATION_DATE_TAG = 'INSTALLATION_DATE';

# Vendor Software Details

$Ptdpm2::MGMT_HC_VENDOR_SUMMARY                = 'MGMT_HC_VENDOR_SUMMARY';
$Ptdpm2::VENDOR_SOFTWARE_TAG                   = 'VENDOR_SOFTWARE';
$Ptdpm2::VENDOR_SOFTWARE_SUMMARY_TAG           = 'VENDOR_SOFTWARE_SUMMARY';
$Ptdpm2::VENDOR_SOFTWARE_NAME_TAG              = 'VENDOR_SOFTWARE_NAME';
$Ptdpm2::VENDOR_NAME_TAG                       = 'VENDOR_NAME';
$Ptdpm2::VENDOR_SOFTWARE_VERSION_TAG           = 'VENDOR_SOFTWARE_VERSION';
$Ptdpm2::VENDOR_SOFTWARE_INSTALLATION_DATE_TAG =
  'VENDOR_SOFTWARE_INSTALLATION_DATE';
$Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG          = 'VENDOR_SOFTWARE_LOCATION';
$Ptdpm2::VENDOR_SOFTWARE_DESCRIPTION_TAG       = 'VENDOR_SOFTWARE_DESCRIPTION';
$Ptdpm2::VENDOR_SOFTWARE_SPECIFIC_INFORMATION_TAG =
  'VENDOR_SOFTWARE_SPECIFIC_INFORMATION';

$Ptdpm2::MGMT_HC_VENDOR_SW_COMPONENTS = 'MGMT_HC_VENDOR_SW_COMPONENTS';
$Ptdpm2::VENDOR_COMPONENT_TAG         = 'VENDOR_COMPONENT';
#$Ptdpm2::NAME_TAG                    = 'NAME';
#$Ptdpm2::TYPE_TAG                    = 'TYPE';
#$Ptdpm2::VERSION_TAG                 = 'VERSION';
#$Ptdpm2::DESCRIPTION_TAG             = 'DESCRIPTION';
#$Ptdpm2::INSTALLATION_DATE_TAG       = 'INSTALLATION_DATE';

$Ptdpm2::INVENTORY      = 'INVENTORY';
$Ptdpm2::NOT_APPLICABLE = 'N/A';
$Ptdpm2::UNKNOWN        = 'UNKNOWN';
$Ptdpm2::SEP            = ':';

%Ptdpm2::CONSTRAINTS = 
(
    $Ptdpm2::HOSTNAME_TAG                    => 128,
    $Ptdpm2::DOMAIN_TAG                      => 500,
    $Ptdpm2::HARDWARE_PROVIDER_TAG           => 128,
    $Ptdpm2::SYSTEM_CONFIGURATION_TAG        => 4000,
    $Ptdpm2::MACHINE_ARCHITECTURE_TAG        => 500,

    $Ptdpm2::CPU_VENDOR_TAG                  => 128,
    $Ptdpm2::CPU_IMPLEMENTATION_TAG          => 500,
    $Ptdpm2::REVISION_TAG                    => 2000,
    $Ptdpm2::MASK_TAG                        => 500,

    $Ptdpm2::VENDOR_TAG                      => 128,
    $Ptdpm2::NAME_TAG                        => 128,
    $Ptdpm2::BUS_TYPE_TAG                    => 500,
#   $Ptdpm2::REVISION_TAG                    => 2000,

    $Ptdpm2::NIC_NAME_TAG                    => 128,
    $Ptdpm2::FLAGS_TAG                       => 1024,
    $Ptdpm2::INET_ADDRESS_TAG                => 20,
#   $Ptdpm2::MASK_TAG                        => 20,
    $Ptdpm2::BROADCAST_ADDRESS_TAG           => 20,
    $Ptdpm2::MAC_ADDRESS_TAG                 => 20,
    $Ptdpm2::HOSTNAME_ALIASES_TAG            => 4000,

    $Ptdpm2::OS_TAG                          => 128,
    $Ptdpm2::OS_VENDOR_TAG                   => 128,
    $Ptdpm2::OS_BASE_VERSION_TAG             => 100,
    $Ptdpm2::OS_UPDATE_LEVEL_TAG             => 100,
    $Ptdpm2::OS_DISTRIBUTOR_VERSION_TAG      => 128,
    $Ptdpm2::OS_ADDRESS_LENGTH_IN_BITS_TAG   => 20,

#   $Ptdpm2::NAME_TAG                        => 128,
#   $Ptdpm2::TYPE_TAG                        => 128,
    $Ptdpm2::VALUE_TAG                       => 2000,

#   $Ptdpm2::NAME_TAG                        => 128,
    $Ptdpm2::TYPE_TAG                        => 100,
    $Ptdpm2::VERSION_TAG                     => 100,
    $Ptdpm2::DESCRIPTION_TAG                 => 2000,

    $Ptdpm2::RESOURCE_NAME_TAG               => 128,
#   $Ptdpm2::TYPE_TAG                        => 100,
    $Ptdpm2::MOUNT_LOCATION_TAG              => 1024,
    $Ptdpm2::MOUNT_OPTIONS_TAG               => 1024,

    $Ptdpm2::VENDOR_SOFTWARE_NAME_TAG        => 128,
    $Ptdpm2::VENDOR_NAME_TAG                 => 128,
    $Ptdpm2::VENDOR_SOFTWARE_VERSION_TAG     => 100,
    $Ptdpm2::VENDOR_SOFTWARE_LOCATION_TAG    => 1024,
    $Ptdpm2::VENDOR_SOFTWARE_DESCRIPTION_TAG => 2000,
    $Ptdpm2::VENDOR_SOFTWARE_SPECIFIC_INFORMATION_TAG => 4000
);

my $indent = NIL;

#******************************************
#     Exported Subroutines
#******************************************

sub appendsysXML
{
    my (@sys) = @_;
    my $size = scalar(@sys);
    my @ossumXML = ();
    my $tag   = NIL;
    my $value = NIL;

    my $i = 0;
    my $j = 0;

    $ossumXML[$j++] = typeBegin($Ptdpm2::HARDWARE_TAG);
 
    if ($size > 0)
    {
    	$ossumXML[$j++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
    	$ossumXML[$j++] = typeBegin($Ptdpm2::SYSTEM_SUMMARY_TAG);



    	for ($i = 0 ; $i < $size ; $i++)
    	{
     	    ($tag, $value) = split ($Ptdpm2::SEP, $sys[$i]);
            chomp($tag);
            if ($tag ne NIL)
            {
            	$ossumXML[$j++] = typeValue($tag, $value);
            }
        }

    	$ossumXML[$j++] = typeEnd($Ptdpm2::SYSTEM_SUMMARY_TAG);
    	$ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    }
    return @ossumXML;
}

sub appendossumXML
{
    my (@sys) = @_;
    my $size = scalar(@sys);
    my @ossumXML = ();
    my $tag   = NIL;
    my $value = NIL;

    my $i = 0;
    my $j = 0;

    $ossumXML[$j++] = typeBegin($Ptdpm2::OS_SOFTWARE_TAG);
    if ($size > 0)
    {
    	$ossumXML[$j++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
    	$ossumXML[$j++] = typeBegin($Ptdpm2::OS_SUMMARY_TAG);

    	for ($i = 0 ; $i < $size ; $i++)
    	{
       	    ($tag, $value) = split ($Ptdpm2::SEP, $sys[$i]);
            chomp($tag);
            if ($tag ne NIL)
            {
            	$ossumXML[$j++] = typeValue($tag, $value);
            }
    	}

    	$ossumXML[$j++] = typeEnd($Ptdpm2::OS_SUMMARY_TAG);
    	$ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    }

    return @ossumXML;
}

sub appendhwXML
{
    my (@hw) = @_;
    my $size = scalar(@hw);
    my @ossumXML = ();
    my $tag   = NIL;
    my $value = NIL;

    my $i   = 0;
    my $j   = 0;
    my $k   = 0;
    my $cpu = 0;
    my $iod = 0;
    my $nic = 0;

    if ($size > 0)
    {
        $ossumXML[$j++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
        $ossumXML[$j++] = typeBegin($Ptdpm2::HARDWARE_DETAILS_TAG);
    }

    for ($i = 0 ; $i < $size ; $i++)
    {

        #print STDERR "$hw[$i]\n"; #debug
        ($tag, $value) = split ($Ptdpm2::SEP, $hw[$i], 2);
        chomp($tag);

        if (index($hw[$i], $Ptdpm2::CPU_VENDOR_TAG) > NOT_FOUND)
        {
            if ($cpu == 0)
            {
                $cpu = 1;
                $ossumXML[$j++] = typeEnd($Ptdpm2::HARDWARE_DETAILS_TAG);
                $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);

                #$cpudone = 1;
                $ossumXML[$j++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
                $ossumXML[$j++] = typeBegin($Ptdpm2::CPU_TAG);
            }
            elsif ($cpu == 1)
            {
                $ossumXML[$j++] = typeEnd($Ptdpm2::CPU_TAG);
                $ossumXML[$j++] = typeBegin($Ptdpm2::CPU_TAG);
            }

        }

        if (index($hw[$i], $Ptdpm2::VENDOR_TAG) > NOT_FOUND
            && index($hw[$i], $Ptdpm2::CPU_VENDOR_TAG) < 0)
        {
            if ($iod == 0)
            {
                $iod = 1;
                if ($cpu == 0)
                {
                    $ossumXML[$j++] = typeEnd($Ptdpm2::HARDWARE_DETAILS_TAG);
                    $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
                }
                if ($cpu == 1)
                {
                    $ossumXML[$j++] = typeEnd($Ptdpm2::CPU_TAG);
                    $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
                }
                $cpu = 2;
                $ossumXML[$j++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
                $ossumXML[$j++] = typeBegin($Ptdpm2::IO_DEVICES_TAG);
            }
            elsif ($iod == 1)
            {
                $ossumXML[$j++] = typeEnd($Ptdpm2::IO_DEVICES_TAG);
                $ossumXML[$j++] = typeBegin($Ptdpm2::IO_DEVICES_TAG);
            }

        }
        if (index($hw[$i], $Ptdpm2::NIC_NAME_TAG) > NOT_FOUND)
        {
            if ($nic == 0)
            {
                $nic = 1;
                if (($cpu == 0) && ($iod == 0))
                {
                    $ossumXML[$j++] = typeEnd($Ptdpm2::HARDWARE_DETAILS_TAG);
                    $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
                }
                if ($cpu == 1)
                {
                    $ossumXML[$j++] = typeEnd($Ptdpm2::CPU_TAG);
                    $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
                }
                if ($iod == 1)
                {
                    $ossumXML[$j++] = typeEnd($Ptdpm2::IO_DEVICES_TAG);
                    $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
                }
                $cpu = 2;
                $iod = 2;
                $nic = 1;
                $ossumXML[$j++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
                $ossumXML[$j++] = typeBegin($Ptdpm2::NETWORK_INTERFACE_CARD_TAG);
            }
            elsif ($nic == 1)
            {
                $ossumXML[$j++] = typeEnd($Ptdpm2::NETWORK_INTERFACE_CARD_TAG);
                $ossumXML[$j++] = typeBegin($Ptdpm2::NETWORK_INTERFACE_CARD_TAG);
            }

        }

        if ($tag eq $Ptdpm2::NIC_NAME_TAG)
        {
            $ossumXML[$j++] = typeValue($Ptdpm2::NAME_TAG, $value);
        }
        elsif ($tag eq $Ptdpm2::CPU_VENDOR_TAG)
        {
            $ossumXML[$j++] = typeValue($Ptdpm2::VENDOR_TAG, $value);
        }
        elsif ($tag ne NIL)
        {
            $ossumXML[$j++] = typeValue($tag, $value);
        }
    }

    if ($cpu == 1)
    {
        $ossumXML[$j++] = typeEnd($Ptdpm2::CPU_TAG);
    }
    if ($iod == 1)
    {
        $ossumXML[$j++] = typeEnd($Ptdpm2::IO_DEVICES_TAG);
    }
    if ($nic == 1)
    {
        $ossumXML[$j++] = typeEnd($Ptdpm2::NETWORK_INTERFACE_CARD_TAG);
    }
    if ($size > 0)
    {
        $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    }

    $ossumXML[$j++] = typeEnd($Ptdpm2::HARDWARE_TAG);

    return @ossumXML;
}

sub typeBegin($)
{
    my ($tag) = @_;
    my $value = $indent.'<'.$tag.'>';
    $indent .= ' ' if ($main::INDENT);

    return $value."\n";
}

sub typeValue($$;$)
{
    my ($tag, $value, $maxlen) = @_;
    if (!defined $tag) { return NIL; }
    chomp($tag);
    $tag = Ptdpm3::trim($tag);
    if ($tag eq NIL) { return NIL; }
    if (!defined $value) { $value = NIL; }
    chomp($value);
    $value = Ptdpm3::trim($value);
    if ($value eq NIL)
    {
        $value = $indent.'<'.$tag.'/>';
    }
    else
    {
        #$maxlen = $Ptdpm2::CONSTRAINTS{$tag} if (!defined $maxlen);
        #$value  = Ptdpm3::trunc($value, $maxlen) if (defined $maxlen);
        $value  = $indent.'<'.$tag.'>'.checkXMLInternalEntitiesInString($value).'</'.$tag.'>';
    }

    return $value."\n";
}

sub typeEnd($)
{
    my ($tag) = @_;
    $indent =~ s/ // if ($main::INDENT);
    my $value = $indent.'</'.$tag.'>';

    return $value."\n";
}

sub typeEndSubComponent($)
{
    my ($tag) = @_;
    my @endXML = ();
    my $j = 0;

    $endXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    $endXML[$j++] = typeEnd($tag);

    return @endXML;
}

sub typeEndVendorSubComponent
{
    my @ossumXML = ();
    my $j = 0;

    $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    $ossumXML[$j++] = typeEnd($Ptdpm2::VENDOR_SOFTWARE_TAG);

    return @ossumXML;
}

sub typeEndOSSubComponent
{
    my @ossumXML = ();
    my $j = 0;

    $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    $ossumXML[$j++] = typeEnd($Ptdpm2::OS_SOFTWARE_TAG);

    return @ossumXML;
}

sub typeOScompXML
{
    my @ossumXML = ();
    my $j = 0;

    $ossumXML[$j++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
    $ossumXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    $ossumXML[$j++] = typeEnd($Ptdpm2::OS_SOFTWARE_TAG);

    return @ossumXML;
}

sub appendOSHashXML
{
    my (%prods)    = @_;
    my $size     = scalar(%prods);
    my @prodsXML = ();

    my $i       = NIL;
    my $j       = NIL;
    my $k       = NIL;
    my $l       = NIL;
    my $m       = 0;
    my $rest    = NIL;
    my $newprod = 0;

    # Level 0
    if ($size)
    {
    	$prodsXML[$m++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);

    	for $i (sort keys %prods)
    	{

            #print STDERR "$i\n"; #debug

            # Level 1
            for $j (sort keys %{$prods{$i}})
            {

            	# Level 2
            	for $k (sort keys %{$prods{$i}{$j}})
            	{
                    $prodsXML[$m++] = typeBegin($Ptdpm2::OS_COMPONENT_TAG);

                    # Level 3
                    for $l (sort keys %{$prods{$i}{$j}{$k}})
                    {
                    	$rest = $prods{$i}{$j}{$k}{$l};
                    	$prodsXML[$m++] = typeValue($l, $rest);

                    	#print STDERR "$i $j $k $l $prods{$i}{$j}{$k}{$l}\n"; # debug
                    }
                    $prodsXML[$m++] = typeEnd($Ptdpm2::OS_COMPONENT_TAG);
                }    # Level 2
            }    # Level 1
         }    # Level 0

         $prodsXML[$m++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    }
    $prodsXML[$m++] = typeEnd($Ptdpm2::OS_SOFTWARE_TAG);

    return @prodsXML;
}

sub appendOSConfHashXML
{
    my (%prods)    = @_;
    my $size     = scalar(%prods);
    my @prodsXML = ();

    my $i       = NIL;
    my $j       = NIL;
    my $k       = NIL;
    my $m       = 0;
    my $rest    = NIL;
    my $newprod = 0;

    # Level 0
    if ($size)
    {
    	$prodsXML[$m++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);

    	for $i (sort keys %prods)
    	{

            #print STDERR "$i\n"; #debug

            # Level 1
            for $j (sort keys %{$prods{$i}})
            {
            	$prodsXML[$m++] = typeBegin($Ptdpm2::OS_PROPERTY_TAG);

            	# Level 2
            	for $k (sort keys %{$prods{$i}{$j}})
            	{
               	    $rest = $prods{$i}{$j}{$k};
                    $prodsXML[$m++] = typeValue($k, $rest);
            	}    # Level 2
            	$prodsXML[$m++] = typeEnd($Ptdpm2::OS_PROPERTY_TAG);
            }    # Level 1
    	}    # Level 0

    	$prodsXML[$m++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    }
    return @prodsXML;
}

sub appendVendorHashXML
{
    my (%prods)    = @_;
    my $size     = scalar(%prods);
    my @prodsXML = ();

    my $i = NIL;
    my $j = NIL;
    my $k = NIL;
    my $l = NIL;
    my $m = 0;

    my $rest   = NIL;
    my $oldtag = NIL;

    # Level 0
    for $i (sort keys %prods)
    {

        # To Print the list of all products by version and location
        #print STDERR "$i\n"; # debug

        # Level 1
        for $j (sort keys %{$prods{$i}})
        {

            # Level 2
            for $k (sort keys %{$prods{$i}{$j}})
            {

                # Level 3
                for $l (sort keys %{$prods{$i}{$j}{$k}})
                {

                    if ($l eq $Ptdpm2::VENDOR_NAME_TAG)
                    {
                        if ($oldtag eq $Ptdpm2::VERSION_TAG)
                        {
                            $prodsXML[$m++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
                            $prodsXML[$m++] = typeEnd($Ptdpm2::VENDOR_SOFTWARE_TAG);
                        }
                        $prodsXML[$m++] = typeBegin($Ptdpm2::VENDOR_SOFTWARE_TAG);
                        $prodsXML[$m++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
                        $prodsXML[$m++] = typeBegin($Ptdpm2::VENDOR_SOFTWARE_SUMMARY_TAG);
                    }
                    elsif ($l eq $Ptdpm2::DESCRIPTION_TAG)
                    {
                        $prodsXML[$m++] = typeBegin($Ptdpm2::VENDOR_COMPONENT_TAG);
                    }

                    $rest = $prods{$i}{$j}{$k}{$l};
                    $prodsXML[$m++] = typeValue($l, $rest);

                    if ($l eq $Ptdpm2::VENDOR_SOFTWARE_VERSION_TAG)
                    {
                        $prodsXML[$m++] = typeEnd($Ptdpm2::VENDOR_SOFTWARE_SUMMARY_TAG);
                        $prodsXML[$m++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
                        $prodsXML[$m++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);
                    }
                    elsif ($l eq $Ptdpm2::VERSION_TAG)
                    {
                        $prodsXML[$m++] = typeEnd($Ptdpm2::VENDOR_COMPONENT_TAG);
                    }
                    $oldtag = $l;
                }    # Level 3
            }    # Level 2
        }    # Level 1
    }    # Level 0

    if ($m > 0)
    {
        $prodsXML[$m++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
        $prodsXML[$m++] = typeEnd($Ptdpm2::VENDOR_SOFTWARE_TAG);
    }

    return @prodsXML;
}

sub appendfsXML
{
    my (@sys) = @_;
    my $size = scalar(@sys);
    my @oskernXML = ();
    my $tag   = NIL;
    my $value = NIL;

    my $m = 0;
    my $n = 0;
    my $j = 0;

    if ($size > 0)
    {
    	$oskernXML[$j++] = typeBegin($Ptdpm2::SUBCOMPONENT_TAG);

    	for ($n = 0 ; $n < $size ; $n++)
    	{
            for ($m = 0 ; $m < 5 ; $m++)
            {
            	$tag = substr($sys[$n][$m], 0, index($sys[$n][$m], $Ptdpm2::SEP));
            	$value = substr($sys[$n][$m], index($sys[$n][$m], $Ptdpm2::SEP) + 1);
            	chomp($tag);

            	if (index($tag, $Ptdpm2::RESOURCE_NAME_TAG) > NOT_FOUND)
            	{
                   $oskernXML[$j++] = typeBegin($Ptdpm2::FILE_SYSTEM_TAG);
                   $oskernXML[$j++] = typeValue($tag, $value);
            	}
            	elsif (index($tag, $Ptdpm2::MOUNT_OPTIONS_TAG) > NOT_FOUND)
            	{
                    $oskernXML[$j++] = typeValue($tag, $value);
                    $oskernXML[$j++] = typeEnd($Ptdpm2::FILE_SYSTEM_TAG);
                    $m = 5;
            	}
            	elsif ($tag ne NIL)
            	{
                    $oskernXML[$j++] = typeValue($tag, $value);
            	}
            }
    	}

    	$oskernXML[$j++] = typeEnd($Ptdpm2::SUBCOMPONENT_TAG);
    }
    return @oskernXML;
}

1;

# End of the Program
