#!/usr/bin/perl ################################################################################ # # v1.2 # # Updates v1.1: # Updated 04/16/04 to remove readlines and replace with <> # apparently this is the cause of the problem # with older versions of Perl. # # Updates v1.2: # Updated 10/15/04 found a problem where NetView Windows will names # devices differently. Changing the key for everything # to use the symbol id instead # # The object of this script is to accept the output from ovmapdump -v and # to create a location.conf file. We simply feed it the name(and path) of # the file we want to run against. # # This is not a IBM Tivoli NetView supported tool. Please use at your own # risk. Do NOT call IBM for support as they will have no clue what you are # talking about. No warranty is given or implied. # # Here is a quick breakdown of the important variables and what they are # used for: # $submap{} - this hash stores the symbol id of the device as the key # and stores the submapid and parent_submapid in an # array # # $location{} - this hash stores the submapid as the key and stores # the name, symbol type and parent_submapid in an array # # @{$router{}} - this is an array of a hash(the hash is used as the # varible name) is built for each submap. All router # names that are parented by that submap are stored # in this array.(this is also true for @{$network{}}) # # @toplevel - this is an array that stores the submapid of all # locations parented by IP Internet # # @{$parent{}} - this is an array of a hash, the hash key is the submapid # and it stores an array each child submapid # # ################################################################################ if (! defined($ARGV[0])) { print "No target file defined.\n"; print "Usage: $0 \n"; exit 255; } open (MAPDUMP, "$ARGV[0]") || die "Unable to open: $ARGV[0]\n"; $date = `date`; chomp $date; print "# location.conf file was autogenerated on $date.\n\n"; while () { if ( $_ =~ /^Submap ID/ ) { # Here we need to capture the submapid and parent_submapid and # store it in a hash with the Name as the key ($submapid) = /^Submap ID\: (.*)/; # Apparently in perl there is no way to move the file pointer by # line, we will just skip the lines we know we dont care about skip_line(\*MAPDUMP,1); $name = get_var(\*MAPDUMP); # We need to store ip internet and use it as our starting point if ( $name =~ /^IP Internet\b/ ) { $ipmapid = $submapid; } skip_line(\*MAPDUMP,3); $pobjid = get_var(\*MAPDUMP); $psubid = get_var(\*MAPDUMP); $submap{$pobjid} = [($submapid,$psubid)]; skip_line(\*MAPDUMP,16); } elsif ( $_ =~ /^Symbol ID/ ) { # Here we grab the label, Symbol type and store it with its parent id # for each location. Each router and network is stored simply with # its parent id skip_line(\*MAPDUMP,1); $label = get_var(\*MAPDUMP); $objid = get_var(\*MAPDUMP); $symid = get_var(\*MAPDUMP); # used only to store routers and networks # as there are multiple symbols for each # router and subnet skip_line(\*MAPDUMP,1); $symtype = get_var(\*MAPDUMP); skip_line(\*MAPDUMP,14); if ($symtype =~ /Router|Cisco|Connector/ ) { # store hopefully all layer3 capable devices(i guess we should add # bay, lucent whatever) into a hash of an array with the parent submap # id as the key of the hash. The array contains all routers that are # a child of that submap push(@{$router{$symid}},$label); } elsif ($symtype =~ /Location/) { if (! $location{$submap{$objid}[0]}) { # store name, symbol type, submap id(hash key), and submap parent id # also create a new hash array(parent) that stores the parent submap # id along with each of its children in the array. We will walk this # array recursively to create the location.conf file. We also store # all the locations that appear on ip internet (undef,$hold) = split(/\:/, $symtype); $symtype = $hold; @location{$submap{$objid}[0]}=[($label,$symtype,$submap{$objid}[1])]; if ( $submap{$objid}[1] == $ipmapid ) { push (@toplevel, $submap{$objid}[0]); } if ( $submap{$objid}[1] > 0 ) { push (@{$parent{$submap{$objid}[1]}},$submap{$objid}[0]); } } } elsif ($symtype =~ /Network/ ) { # store all networks with their parent id and label # if they do not already exist if ( ! grep { /\b$label\b/ } @{$network{$symid}} ) { push(@{$network{$symid}},$label); } } } } # Close filehandle close(MAPDUMP); # We will start with our toplevel array, this contains the mapid of each of # ip internets locations. We will start there, once this loop completes the # script is complete foreach $submap (@toplevel) { # First we must create our 0 level icon # Name 0 Symboltype create_toplevel_entry($submap); # After we print the toplevel entry, we will add all routers # and then all networks before moving to its children locations walk_routers($submap); walk_networks($submap); # Now we begin the recursive loop through the locations walk_children($submap); # print a blank line at the end print "\n"; } # print ending message $date = `date`; chomp $date; print "# Script completed processing on $date\n"; # FIN script completed # This subroutine will recursively call itself until it reaches the end # of all children of the submap passed. sub walk_children { foreach $child (@{$parent{$_[0]}}) { # First we create the upper level entry for this child, then # print routers and or networks before again calling this # routine for its children. create_zero_entry($child,$location{$_[0]}[0]); walk_routers($child); walk_networks($child); walk_children($child); } } sub create_zero_entry { # We need to check if the name of this object or its parent # name contains spaces, if so we need to quote them. $child_name = check_spaces($location{$_[0]}[0]); $type = check_spaces($location{$_[0]}[1]); $parent_name = check_spaces($_[1]); if ( length($child_name) < 8 ) { printf "%s\t\t255\t%s\t%s\n",$child_name,$type,$parent_name; } else { printf "%s\t255\t%s\t%s\n",$child_name,$type,$parent_name; } } sub create_toplevel_entry { # This routine simply prints the 0 level entry for the toplevel # icons $name = check_spaces($location{$_[0]}[0]); $type = check_spaces($location{$_[0]}[1]); if ( length($name) < 8 ) { printf "%s\t\t255\t%s\n",$name, $type; } else { printf "%s\t255\t%s\n",$name, $type; } } sub walk_routers { # Each router of a parent submap is stored in an array. We walk # the array passed and print the output. foreach $router (sort(@{$router{$_[0]}})) { $name = check_spaces($location{$_[0]}[0]); if (length($name) < 8 ) { printf "%s\t\t%s\n",$name, $router; } else { printf "%s\t%s\n",$name, $router; } } print "\n"; } sub walk_networks { # Each network of a parent submap is stored in an array. We walk # the array passed and print the output. foreach $network (sort(@{$network{$_[0]}})) { $name = check_spaces($location{$_[0]}[0]); $type = check_spaces($location{$_[0]}[1]); if ( length($network) < 8 && length($name) < 8 ) { printf "%s\t\t%s\t\t%s\n",$name, $network, $type; } elsif (length($network) < 8 ) { printf "%s\t%s\t\t%s\n",$name, $network, $type; } elsif (length($name) < 8 ) { printf "%s\t\t%s\t%s\n",$name, $network, $type; } else { printf "%s\t%s\t%s\n",$name, $network, $type; } } print "\n"; } # Stupid readline hack to work around perls inability to move the # file pointer by line. sub skip_line { for ($i=1;$i<=$_[1];$i++) { # $test = readline($_[0]); REMOVED 4/16/04 ; } } # Got tired of writing this over and over so I made it a function # it simply pulls the necessary information(ie after the ":") sub get_var { # $test = readline($_[0]); REMOVED 4/16/04 $hold = ; $hold =~ /^S.*\: (.*)/; return $1; } # In some of the names of locations and some of the Location Symbol # types contain spaces, if need be we will quote them before printing # this checks for and returns a quoted string if necessary sub check_spaces { if ($_[0] =~ / /) { $return = "\"$_[0]\""; } else { $return = $_[0]; } return($return); }