Index: fedkit/splitter.pl
===================================================================
--- fedkit/splitter.pl	(revision 63f7c7e4cd48d49acd4a12961a57cff382e0ecc2)
+++ fedkit/splitter.pl	(revision c23025eb0e715ed884dacce94a85294f82901209)
@@ -33,10 +33,11 @@
 
     # XXX system with a relative pathname is sort of gross
-    if ( $host ne "localhost") {
-	system ("ssh $user\@$host $cmd");
-    }
-    else {
-	system ("$cmd");
-    }
+    # if ( $host ne "localhost") {
+	#system ("ssh $user\@$host $cmd");
+	#}
+    #else {
+	#system ("$cmd");
+	#}
+    system ("ssh $user\@$host $cmd");
     if ($?) {
 	warn "$wname failed $?\n" if $wname;
@@ -66,10 +67,11 @@
 # 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.  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.
+# 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.
 sub start_segment {
     my($tb, $eid) = @_;			    # testbed and experiment ID
-    my($host) = $host{$tb};		    # Host name of remote users
+    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
@@ -81,12 +83,14 @@
 
     # Determine the status of the remote experiment
-    if ( $host ne "localhost") {
-	open(STATUS, "ssh $user\@$host /usr/testbed/bin/expinfo $pid $eid|") || 
-	    die "Can't ssh to $user\@$host:$!\n";
-    }
-    else {
-	open(STATUS, "/usr/testbed/bin/expinfo $pid $eid|") || 
-	    die "Can't call expinfo locally";
-    }
+    #if ( $host ne "localhost") {
+#	open(STATUS, "ssh $user\@$host /usr/testbed/bin/expinfo $pid $eid|") || 
+#	    die "Can't ssh to $user\@$host:$!\n";
+#    }
+#    else {
+#	open(STATUS, "/usr/testbed/bin/expinfo $pid $eid|") || 
+#	    die "Can't call expinfo locally";
+#    }
+    open(STATUS, "ssh $user\@$host /usr/testbed/bin/expinfo $pid $eid|") || 
+	die "Can't ssh to $user\@$host:$!\n";
     # XXX: this is simple now.  Parsing may become more complex
     while (<STATUS>) {
@@ -98,12 +102,18 @@
 
     # Copy the experiment definition data over (unless the host is local)
-    if ( $host ne "localhost") {
-	&scp_file($tclfile, "$user\@$host") || return 0;
-    }
-
+    #if ( $host ne "localhost") {
+#	&scp_file("$tmpdir/$tb/$tclfile", "$user\@$host") || return 0;
+#    }
+#    else {
+#	# XXX this ain't quite right
+#	system("cp $tmpdir/$tb/$tclfile .");
+#    }
+
+    &scp_file("$tmpdir/$tb/$tclfile", "$user\@$host") || return 0;
     # Remote experiment is active.  Modify it.
     if ($state eq "active") {
 	# First copy new scripts and hostinfo into the remote /proj
-	&scp_file("./hostnames", "$user\@$host", $to_hostname) || return 0;
+	&scp_file("$tmpdir/$tb/hostnames", "$user\@$host", $to_hostname) ||
+	    return 0;
 	&ship_scripts($host, $user, $proj_dir) || return 0;
 	&ssh_cmd($user, $host, "/usr/testbed/bin/modexp -r -s -w $pid " . 
@@ -151,5 +161,5 @@
     my($tb, $eid) = @_;
     my($user) = "$user{$tb}";
-    my($host) = "$host{$tb}";
+    my($host) = "$host{$tb}$domain{$tb}";
     my($pid) = $project{$tb};
 
@@ -159,5 +169,7 @@
 }
 
-$tcl_splitter = "/usr/testbed/lib/ns2ir/parse.tcl";	    # tcl program to split experiments
+# tcl program to split experiments
+# $tcl_splitter = "/usr/testbed/lib/ns2ir/parse.tcl";
+$tcl_splitter = "/users/faber/testbed/tbsetup/ns2ir/parse.tcl";
 $tclsh = "/usr/local/bin/otclsh";   # tclsh to call directly
 
@@ -169,5 +181,5 @@
 
 # Argument processing.
-getopts('d:c:m:e:f:n', \%opts);
+getopts('d:c:m:e:f:nt:', \%opts);
 
 $eid = $opts{'e'};		    # Experiment ID
@@ -175,6 +187,14 @@
 $master = $opts{'m'};		    # Master testbed
 $startem = $opts{'n'} ? 0 : 1;	    # If true, start the sub-experiments
+$tmpdir = $opts{'t'} || "/tmp";		    # where to collect tmp files
 $config = $opts{'c'} || "./testbeds";
 $local_script_dir = $opts{'d'};	    # Local scripts
+
+$tmpdir .= "/split$$";
+
+unless (-d "$tmpdir") {
+    mkdir("$tmpdir") || die "Can't create $tmpdir: $!";
+}
+
 
 for $s (@scripts) {
@@ -190,7 +210,8 @@
     next if /^#/;
     chomp;
-    ($tb, $h, $u, $p, $es, $gs, $mes, $mgs, $t, $i) = split(":", $_);
+    ($tb, $h, $d, $u, $p, $es, $gs, $mes, $mgs, $t, $i) = split(":", $_);
     $host{$tb} = $h;
     $user{$tb} = $u;
+    $domain{$tb} = $d;
     $project{$tb} = $p;
     $gwtype{$tb} = $t;
@@ -200,9 +221,12 @@
     $mgwstart{$tb} = $mgs;
     $gwimage{$tb} = $i;
+
+    # Make sure the domain starts with a period
+    $domain{$tb} = ".$domain{$tb}" unless $domain{$tb} =~ /^\./;
 }
 close(CONF);
 
 # Open a pipe to the splitter program and start it parsing the experiments
-open(PIPE, "$tclsh $tcl_splitter -s -p $pid $gid $eid $tcl|") || 
+open(PIPE, "$tclsh $tcl_splitter -s -m $master -p $pid $gid $eid $tcl|") || 
     die "Cannot execute $tclsh $tcl_splitter -s -p $pid $gid $eid $tcl:$!\n";
 
@@ -218,5 +242,9 @@
 	if ($host{$ctb}) {
 	    $allocated{$ctb}++;	# Keep track of the testbeds allocated
-	    $destfile = "./$eid.$ctb.tcl";
+
+	    unless (-d "$tmpdir/$ctb") {
+		mkdir("$tmpdir/$ctb") || die "Can't create $tmpdir/$ctb: $!";
+	    }
+	    $destfile = "$tmpdir/$ctb/$eid.$ctb.tcl";
 
 	    open(FILE, ">$destfile") || die "Cannot open $destfile:$!\n";
@@ -228,4 +256,5 @@
 	next;
     };
+
     # End of that experiment
     /^#\s+End\s+Testbed\s+\((\w+)\)/ && do {
@@ -236,8 +265,35 @@
 	next;
     };
+
+    # Beginning of a gateway set
+    /^#\s+Begin\s+gateways\s+\((\w+)\)/ && do {
+	$gateways = $1;
+	# If we've heard of this tb, create the config lines for it one at a
+	# time.
+	if ($allocated{$gateways}) {
+	    # Just in case.  This directory should already have been created
+	    # above.
+	    unless (-d "$tmpdir/$gateways") {
+		mkdir("$tmpdir/$gateways") || 
+		    die "Can't create $tmpdir/$gateways: $!";
+	    }
+	}
+	else {
+	    warn "Gateways given (and ignored) for testbed not in use: " .
+		"$gateways\n";
+	    $gateways = 0;
+	}
+	next;
+    };
+    /^#\s+End\s+gateways\s+\((\w+)\)/ && do {
+	die "Mismatched gateway markers ($1, $gateways)\n" 
+	    unless !$gateways || $gateways == $1;
+	$gateways = 0;
+	next;
+    };
     # Beginning of the hostnames list.  Collection is always in the hostnames
     # file.
     /^#\s+Begin\s+hostnames/ && do {
-	$destfile = "./hostnames";
+	$destfile = "$tmpdir/hostnames";
 	open(FILE, ">$destfile") || die "Can't open $destfile:$!\n";
 	next;
@@ -249,4 +305,35 @@
 	next;
     };
+
+    # Generate gateway configuration info, one file per line
+    $gateways && do {
+	chomp;
+	my($dtb, $myname, $desthost, $type) = split(" ", $_);
+	my($sdomain) = $domain{$gateways};	# domain for the source
+	my($ddomain) = $domain{$dtb};		# domain for the destination
+
+	# If either end of this link is in the master side of the testbed, that
+	# side is the active end. Otherwise the first testbed encountered in
+	# the file will be the active end.  The $active_end variable keeps
+	# track of those decisions
+	if ( $dtb eq $master ) { $active = "false"; }
+	elsif ($gateways eq $master ) { $active = "true"; }
+	elsif ( $active_end{"$dtb-$gateways"} ) { $active="false"; }
+	else { $active_end{"$gateways-$dtb"}++; $active = "true"; }
+
+	# Write out the file
+	open(GWCONFIG, ">$tmpdir/$gateways/$myname$sdomain.gw.conf") || 
+	    die "can't open $tmpdir/%gateways/$myname$sdomain.gw.conf: $!\n";
+	print GWCONFIG "Active: $active\n";
+	print GWCONFIG "Type: $type\n";
+	print GWCONFIG "Peer: $desthost$ddomain\n";
+	print GWCONFIG "Pubkeys: /placeholder\n";
+	print GWCONFIG "Privkeys: /placeholder\n";
+	close(GWCONFIG);
+
+	#done processing gateway entry, ready for next line
+	next; 
+    };
+
 
     next unless $destfile;  # Unidentified testbed, ignore config
@@ -352,4 +439,13 @@
 testbed.
 
+=item host
+
+The host name of the testbed's ops node.  The user calling B<splitter.pl> must
+be able to execute commands on this host via L<ssh(1)>.
+
+=item domain
+
+The domain of nodes in this testbed (including the ops host).
+
 =item project
 
