Index: fedkit/splitter.pl
===================================================================
--- fedkit/splitter.pl	(revision b81452934b7a71c1d40db947149d64b2411318f1)
+++ fedkit/splitter.pl	(revision 527321c85cd2df8650f17c5c3980ede0dbb60320)
@@ -9,42 +9,35 @@
 use File::Copy;
 
-my(@scripts) = ("federate.sh", "smbmount.pl", "make_hosts", "fed-tun.pl");
-my($local_script_dir) = ".";
+my @scripts = ("federate.sh", "smbmount.pl", "make_hosts", "fed-tun.pl");
+my $local_script_dir = ".";
 my($pid, $gid);			# Process and group IDs for calling parse.tcl
-my($splitter_config);		# Configuration file
-my($debug);			# True if thecalled in debug mode
-my($verbose);			# True for extra progress reports
-my($startem);			# If true, start the sub-experiments
-my($eid);			# Experiment ID
-my($tcl);			# The experiment description (topology file)
-my($master);			# Master testbed
-my($tmpdir);			# tmp files
-my($tb_config);			# testbed configurations
-my($smb_share);			# Share to mount from the master
-my($project_user);		# User to mount project dirs as
+my $splitter_config;		# Configuration file
+my $debug;			# True if thecalled in debug mode
+my $verbose;			# True for extra progress reports
+my $startem;			# If true, start the sub-experiments
+my $eid;			# Experiment ID
+my $tcl;			# The experiment description (topology file)
+my $master;			# Master testbed
+my $tmpdir;			# tmp files
+my $tb_config;			# testbed configurations
+my $smb_share;			# Share to mount from the master
+my $project_user;		# User to mount project dirs as
 my($gw_pubkey, $gw_pubkey_base);# Connector pubkey (full path & basename)
 my($gw_secretkey, $gw_secretkey_base);# Connector secret key (full path & 
 				# basename)
-my($tcl_splitter);		# tcl program to split experiments
+my $tcl_splitter;		# tcl program to split experiments
 				# (changed during devel)
-my($tclsh);			# tclsh to call directly (changed during devel)
-my(@tarfiles);			# Tarfiles in use by this experiment
-my(%opts);			# Parsed options
-
-# Per testbed parameters parsed from testbeds file
-my(%host);			# ops node of the testbed
-my(%user);			# User to operate as 
-my(%domain);			# testbed DNS domain
-my(%project);			# Remote project to instantiate undere
-my(%gwtype);			# Node type for connector
-my(%expstart);			# startcmd for experimental nodes (slave)
-my(%gwstart);			# startcmd for connector nodes (slave)
-my(%mexpstart);			# startcmd for experimental nodes (master)
-my(%mgwstart);			# startcmd for connector nodes (master)
-my(%gwimage);			# connector image name
-my(%fs);			# testbed fs node
-my(%boss);			# testbed boss node
-my(%tun);			# XXX: should disappear configure tunnel?
-
+my $tclsh;			# tclsh to call directly (changed during devel)
+my @tarfiles;			# Tarfiles in use by this experiment
+my %opts;			# Parsed options
+
+my $tbparams = {};		# Map of the per-testbed parameters from the
+				# testbeds file.  It is a reference to a hash
+				# of hashes (because it's passed around a bunch
+				# and it's nicer to have one access pattern
+				# throughout the script, in the main loop and
+				# the subroutines).  That access is exemplified
+				# by  $tbparams->{'deter'}->{'domain'} which is
+				# the domain parameter of the DETER testbed.  
 
 # Parse the config file.  The format is a colon-separated parameter name
@@ -85,10 +78,10 @@
 
 sub parse_testbeds {
-    my($file) = @_;		    # Testbeds file
-    my($fh) = new IO::File($file);  # Testbeds filehandle
-    my($tb);			    # Current testbed
+    my($file, $tbparams) = @_;	    # Testbeds file and parameter hash
+    my $fh = new IO::File($file);  # Testbeds filehandle
+    my $tb;			    # Current testbed
     # Convert attribute in the file to global variable name.  XXX: Again, this
     # needs to be a 2-level hash
-    my(%attr_to_hash) = (
+    my %attr_to_hash = (
 	"opsnode" => "host",
 	"user" => "user",
@@ -117,4 +110,5 @@
 	/^\s*\[(.*)\]/ && do {
 	    $tb = $1;
+	    $tbparams->{$tb} = {} unless $tbparams->{$tb};
 	    next;
 	};
@@ -126,10 +120,9 @@
 		next;
 	    }
-	    my($key) = $1; 
+	    my $key = $1; 
 	    $key =~ tr/A-Z/a-z/;
-	    my($var) = $attr_to_hash{$key};
-
-	    # XXX: The eval is scary.  This will become a 2-level hash.
-	    if ($var) { eval "\$$var\{$tb\} = \"$2\";"; }
+	    my $var = $attr_to_hash{$key};
+
+	    if ($var) { $tbparams->{$tb}->{$var} = $2; }
 	    else { warn "Unknown keyword $key in $file\n"; }
 
@@ -218,28 +211,28 @@
 }
 
-
-
-
 # Start a sub section of the experiment on a given testbed.  The testbed and
 # the user to start the experiment as are pulled from the global per-testbed
-# hash, as is the project name on the remote testbed.  Parameters are the
-# testbed and the experiment id.  Configuration files are scp-ed over to the
-# target testbed from the global $tmpdir/$tb directory.  Then the current state
-# of the experiment determined using expinfo.  From that state, the experiment
-# is either created, modified or spapped in.  If everything succeeds, true is
-# returned.  If the global verbose is set progress messages are printed.
+# hash, passed in as $tbparams, as is the project name on the remote testbed.
+# Parameters are the testbed and the experiment id.  Configuration files are
+# scp-ed over to the target testbed from the global $tmpdir/$tb directory.
+# Then the current state of the experiment determined using expinfo.  From that
+# state, the experiment is either created, modified or spapped in.  If
+# everything succeeds, true is returned.  If the global verbose is set progress
+# messages are printed.
 sub start_segment {
-    my($tb, $eid) = @_;			    # testbed and experiment ID
-    my($host) = "$host{$tb}$domain{$tb}";   # Host name of remote ops (FQDN)
-    my($user) = $user{$tb};		    # user to pass to ssh
-    my($pid) = $project{$tb};		    # remote project to start the
+    my($tb, $eid, $tbparams) = @_;	    # testbed, experiment ID, and 
+					    # per-testbed parameters
+    my $host =				    # Host name of remote ops (FQDN)
+	$tbparams->{$tb}->{'host'} . $tbparams->{$tb}->{'domain'};
+    my $user = $tbparams->{$tb}->{'user'};  # user to pass to ssh
+    my $pid = $tbparams->{$tb}->{'project'};# remote project to start the
 					    # experiment under
-    my($tclfile) = "./$eid.$tb.tcl";	    # Local tcl file with the
+    my $tclfile = "./$eid.$tb.tcl";	    # Local tcl file with the
 					    # sub-experiment
-    my($proj_dir) = "/proj/$pid/exp/$eid/tmp";  # Where to stash federation stuff
-    my($tarfiles_dir) = "/proj/$pid/tarfiles/$eid";  # Where to stash tarfiles
-    my($to_hostname) = "$proj_dir/hosts";   # remote hostnames file
-    my($state);				    # State of remote experiment
-    my($status) = new IO::Pipe;		    # The pipe to get status
+    my $proj_dir = "/proj/$pid/exp/$eid/tmp";  # Where to stash federation stuff
+    my $tarfiles_dir = "/proj/$pid/tarfiles/$eid";  # Where to stash tarfiles
+    my $to_hostname = "$proj_dir/hosts";    # remote hostnames file
+    my $state;				    # State of remote experiment
+    my $status = new IO::Pipe;		    # The pipe to get status
 
     # Determine the status of the remote experiment
@@ -352,8 +345,10 @@
 # start_segment, though much simpler.
 sub stop_segment {
-    my($tb, $eid) = @_;
-    my($user) = "$user{$tb}";
-    my($host) = "$host{$tb}$domain{$tb}";
-    my($pid) = $project{$tb};
+    my($tb, $eid, $tbparams) = @_;	    # testbed, experiment ID and 
+					    # per-testbed parameters
+    my $user = $tbparams->{$tb}->{'user'};  # testbed user
+    my $host =				    # Ops node
+	$tbparams->{$tb}->{'host'} . $tbparams->{$tb}->{'domain'};
+    my $pid = $tbparams->{$tb}->{'project'};# testbed project
 
     print "Stopping $eid on $tb\n" if $verbose;
@@ -421,5 +416,5 @@
 
 if ($opts{'N'} ) {
-    &parse_testbeds($tb_config) ||
+    &parse_testbeds($tb_config, $tbparams) ||
 	die "Cannot testbed congfigurations from $tb_config: $!\n";
 }
@@ -433,20 +428,21 @@
 	my($tb, $h, $d, $u, $p, $es, $gs, $mes, $mgs, $t, $i, $fs, $boss,
 	    $tun) = split(":", $_);
-	$host{$tb} = $h;
-	$user{$tb} = $u;
-	$domain{$tb} = $d;
-	$project{$tb} = $p;
-	$gwtype{$tb} = $t;
-	$expstart{$tb} = $es;
-	$gwstart{$tb} = $gs;
-	$mexpstart{$tb} = $mes;
-	$mgwstart{$tb} = $mgs;
-	$gwimage{$tb} = $i;
-	$fs{$tb} = $fs;
-	$boss{$tb} = $boss;
-	$tun{$tb} = $tun;
+	$tbparams->{$tb}->{'host'} = $h;
+	$tbparams->{$tb}->{'user'} = $u;
+	$tbparams->{$tb}->{'domain'} = $d;
+	$tbparams->{$tb}->{'project'} = $p;
+	$tbparams->{$tb}->{'gwtype'} = $t;
+	$tbparams->{$tb}->{'expstart'} = $es;
+	$tbparams->{$tb}->{'gwstart'} = $gs;
+	$tbparams->{$tb}->{'mexpstart'} = $mes;
+	$tbparams->{$tb}->{'mgwstart'} = $mgs;
+	$tbparams->{$tb}->{'gwimage'} = $i;
+	$tbparams->{$tb}->{'fs'} = $fs;
+	$tbparams->{$tb}->{'boss'} = $boss;
+	$tbparams->{$tb}->{'tun'} = $tun;
 
 	# Make sure the domain starts with a period
-	$domain{$tb} = ".$domain{$tb}" unless $domain{$tb} =~ /^\./;
+	$tbparams->{$tb}->{'domain'} = "." . $tbparams->{$tb}->{'domain'}
+	    unless $tbparams->{$tb}->{'domain'} =~ /^\./;
     }
     $conf->close();
@@ -460,14 +456,14 @@
 
 # Parsing variables
-my($ctb);			# Current testbed
-my(%allocated);			# If allocated{$tb} > 0, $tb is in use
-my($destfile);			# File that the sub-experiment tcl file is
+my $ctb;			# Current testbed
+my %allocated;			# If allocated{$tb} > 0, $tb is in use
+my $destfile;			# File that the sub-experiment tcl file is
 				# being written to, or "" if none.  Also used
 				# for hostnames file.
-my($gateways);			# when gateway lists are being processed this
+my $gateways;			# when gateway lists are being processed this
 				# is the testbed whose gateways are being
 				# gathered.
-my($control_gateway);		# Control net gateway for the current testbed
-my(%active_end);		# If active_end{"a-b"} > 0 then a is the active
+my $control_gateway;		# Control net gateway for the current testbed
+my %active_end;			# If active_end{"a-b"} > 0 then a is the active
 				# end of the a <-> b connector pair.
 
@@ -482,5 +478,5 @@
 	# description.  If not, warn the caller and ignore the configuration of
 	# this testbed.
-	if ($host{$ctb}) {
+	if ($tbparams->{$ctb}) {
 	    $allocated{$ctb}++;	# Keep track of the testbeds allocated
 
@@ -535,5 +531,5 @@
 	if ($control_gateway ) {
 	    # Client config
-	    my($cc) = new IO::File(">$tmpdir/$gateways/client.conf");
+	    my $cc = new IO::File(">$tmpdir/$gateways/client.conf");
 	    die "Can't open $tmpdir/$gateways/client.conf: $!\n" unless $cc;
 	    print $cc "ControlGateway: $control_gateway\n";
@@ -565,14 +561,25 @@
 	chomp;
 	my($dtb, $myname, $desthost, $type) = split(" ", $_);
-	my($sdomain) = $domain{$gateways};	# domain for the source
-	my($ddomain) = $domain{$dtb};		# domain for the destination
-	my($sproject) = $project{$gateways};	# Project of the destination
-	my($active);				# Is this the active side of
+
+	# Many of these are to simplify print statements
+	my $sdomain =				# domain for the source
+	    $tbparams->{$gateways}->{'domain'};
+	my $ddomain =				# domain for the destination
+	    $tbparams->{$dtb}->{'domain'};
+	my $sproject =				# Project of the destination
+	    $tbparams->{$gateways}->{'project'};
+	my $fs =				# Master fs node (FQDN)
+	    $tbparams->{$master}->{'fs'} .  $tbparams->{$master}->{'domain'};
+	my $boss =				# Master boss node (FQDN)
+	    $tbparams->{$master}->{'boss'} .  $tbparams->{$master}->{'domain'};
+	my $remote_script_dir =			# Remote fed script location
+	    "/proj/" . $tbparams->{$dtb}->{'project'} . "/exp/$eid/tmp";
+	my $active;				# Is this the active side of
 						# the connector?
 
-	$sdomain = ".$eid.$project{$gateways}$sdomain";
-	$ddomain = ".$eid.$project{$dtb}$ddomain";
-
-	my($conf_file) = "$myname$sdomain.gw.conf";
+	$sdomain = ".$eid." . $tbparams->{$gateways}->{'project'} . "$sdomain";
+	$ddomain = ".$eid." . $tbparams->{$dtb}->{'project'} . "$ddomain";
+
+	my $conf_file = "$myname$sdomain.gw.conf";
 	# translate to lower case so the `hostname` hack for specifying
 	# configuration files works.
@@ -597,9 +604,9 @@
 
 	print $gwconfig "Active: $active\n";
-	print $gwconfig "TunnelCfg: $tun{$gateways}\n";
-	print $gwconfig "BossName: $boss{$master}$domain{$master}\n";
-	print $gwconfig "FsName: $fs{$master}$domain{$master}\n";
+	print $gwconfig "TunnelCfg: " . $tbparams->{$gateways}->{'tun'} . "\n";
+	print $gwconfig "BossName: $boss\n";
+	print $gwconfig "FsName: $fs\n";
 	print $gwconfig "Type: $type\n";
-	print $gwconfig "RemoteScriptDir: /proj/$project{$dtb}/exp/$eid/tmp\n";
+	print $gwconfig "RemoteScriptDir: $remote_script_dir\n";
 	print $gwconfig "Peer: $desthost$ddomain\n";
 	print $gwconfig "Pubkeys: " . 
@@ -636,21 +643,29 @@
 
     next unless $destfile;  # Unidentified testbed, ignore config
+    # local copies that can be used in the substitutions below
+    my $gwtype = $tbparams->{$ctb}->{'gwtype'};
+    my $gwimage = $tbparams->{$ctb}->{'gwimage'};
+    my $mgwstart = $tbparams->{$ctb}->{'mgwstart'};
+    my $mexpstart = $tbparams->{$ctb}->{'mexpstart'};
+    my $gwstart = $tbparams->{$ctb}->{'gwstart'};
+    my $expstart = $tbparams->{$ctb}->{'expstart'};
+    my $project = $tbparams->{$ctb}->{'project'};
 
     # Substitute variables
-    s/GWTYPE/$gwtype{$ctb}/g;
-    s/GWIMAGE/$gwimage{$ctb}/g;
+    s/GWTYPE/$gwtype/g;
+    s/GWIMAGE/$gwimage/g;
     if ($ctb eq $master ) {
-	s/GWSTART/$mgwstart{$ctb}/g;
-	s/EXPSTART/$mexpstart{$ctb}/g;
+	s/GWSTART/$mgwstart/g;
+	s/EXPSTART/$mexpstart/g;
     }
     else {
-	s/GWSTART/$gwstart{$ctb}/g;
-	s/EXPSTART/$expstart{$ctb}/g;
+	s/GWSTART/$gwstart/g;
+	s/EXPSTART/$expstart/g;
     }
     # XXX: oh is this bad
     s#GWCONF#FEDDIR\`hostname\`.gw.conf#g;
-    s#PROJDIR#/proj/$project{$ctb}/#g;
+    s#PROJDIR#/proj/$project/#g;
     s#EID#$eid#g;
-    s#FEDDIR#/proj/$project{$ctb}/exp/$eid/tmp/#g;
+    s#FEDDIR#/proj/$project/exp/$eid/tmp/#g;
     print FILE;
 }
@@ -670,5 +685,5 @@
 exit(0) unless $startem;
 
-my(%started);		    # If $started{$tb} then $tb successfully started
+my %started;		    # If $started{$tb} then $tb successfully started
 
 # Start up the slave sub-experiments first
@@ -676,5 +691,5 @@
 for my $tb  (keys %allocated) {
     if ($tb ne $master) {
-	if (&start_segment($tb, $eid)) { $started{$tb}++; }
+	if (&start_segment($tb, $eid, $tbparams)) { $started{$tb}++; }
 	else { last TESTBED; }
     }
@@ -682,5 +697,5 @@
 
 # Now the master
-if (&start_segment($master, $eid)) { 
+if (&start_segment($master, $eid, $tbparams)) { 
     $started{$master}++;
 }
@@ -688,5 +703,5 @@
 # If any testbed failed, swap the rest out.
 if ( scalar(keys %started) != scalar(keys %allocated)) {
-    for my $tb (keys %started) { &stop_segment($tb, $eid); }
+    for my $tb (keys %started) { &stop_segment($tb, $eid, $tbparams); }
     print "Error starting experiment\n";
     exit(1);
