Index: fedd/federation/emulab_access.py
===================================================================
--- fedd/federation/emulab_access.py	(revision 35aa3ae74d9953faf6d76c4d7f5e24359a260a0e)
+++ fedd/federation/emulab_access.py	(revision e02cd14c76fe2382e62f5e57ea53b1c682bf200c)
@@ -100,4 +100,7 @@
         set_log_level(config, "access", self.log)
         self.state_lock = Lock()
+	# XXX: Configurable
+	self.exports = set(('SMB', 'seer', 'tmcd'))
+	self.imports = set(('SMB', 'seer', 'tmcd'))
 
         if auth: self.auth = auth
@@ -485,5 +488,30 @@
                 owners
 
-    def build_response(self, alloc_id, ap):
+    def export_services(self, sreq, project, user):
+	exp = [ ]
+	# XXX: Filthy shortcut here using http so urlparse will give the right
+	# answers.
+	for s in sreq:
+	    sname = s.get('name', '')
+	    svis = s.get('visibility', '')
+	    if svis == 'export':
+		if sname in self.exports:
+		    outs = s.copy()
+		    if sname == 'SMB':
+			outs = s.copy()
+			outs['server'] = "http://fs:139" 
+			outs['fedAttr'] = [
+				{ 'attribute': 'SMBSHARE', 'value': 'USERS' },
+				{ 'attribute': 'SMBUSER', 'value': user },
+				{ 'attribute': 'SMBPROJ', 'value': project },
+			    ]
+		    elif sname == 'seer':
+			outs['server'] = "http://control:16606"
+		    elif sname == 'tmcd':
+			outs['server'] = "http://boss:7777"
+		    exp.append(outs)
+	return exp
+
+    def build_response(self, alloc_id, ap, services):
         """
         Create the SOAP response.
@@ -508,4 +536,7 @@
                 [ { 'attribute': x, 'value' : y } \
                         for x,y in self.attrs.iteritems()])
+
+	if services:
+	    msg['service'] = services
         return msg
 
@@ -676,5 +707,4 @@
                         "Misformed allocation response?")
 
-
             self.allocation[aid]['owners'] = owners
             self.write_state()
@@ -689,5 +719,6 @@
 		raise service_error(service_error.internal, 
 			"Can't open %s/%s : %s" % (self.certdir, aid, e))
-            resp = self.build_response({ 'fedid': allocID } , ap)
+	    services = self.export_services(req.get('service',[]), pname, uname)
+            resp = self.build_response({ 'fedid': allocID } , ap, services)
             return resp
         else:
@@ -819,5 +850,57 @@
 
     def generate_portal_configs(self, topo, pubkey_base, secretkey_base, 
-	    tmpdir, master):
+	    tmpdir, master, lproj, leid, connInfo, services):
+
+	def conninfo_to_dict(key, info):
+	    """
+	    Make a cpoy of the connection information about key, and flatten it
+	    into a single dict by parsing out any feddAttrs.
+	    """
+
+	    rv = None
+	    for i in info:
+		if i.get('portal', "") == key:
+		    rv = i.copy()
+		    break
+	    else:
+		return rv
+
+	    if 'fedAttr' in rv:
+		for a in rv['fedAttr']:
+		    attr = a.get('attribute', "")
+		    val = a.get('value', "")
+		    if attr and attr not in rv:
+			rv[attr] = val
+		del rv['fedAttr']
+	    return rv
+
+	# XXX: un hardcode this
+	def client_null(f, s): pass
+
+	def client_smb(f, s):
+	    smbshare = None
+	    smbuser = None
+	    smbproj = None
+	    for a in s.get('fedAttr', []):
+		if a.get('attribute', '') == 'SMBSHARE':
+		    smbshare = a.get('value', None)
+		elif a.get('attribute', '') == 'SMBUSER':
+		    smbuser = a.get('value', None)
+		elif a.get('attribute', '') == 'SMBPROJ':
+		    smbproj = a.get('value', None)
+
+	    if all((smbshare, smbuser, smbproj)):
+		print >>f, "SMBshare: %s" % smbshare
+		print >>f, "ProjectUser: %s" % smbuser
+		print >>f, "ProjectName: %s" % smbproj
+
+	client_service_out = {
+		'SMB': client_smb,
+		'tmcd': client_null,
+		'seer': client_null,
+		'userconfig': client_null,
+	    }
+	# XXX: end un hardcode this
+
 
 	seer_out = False
@@ -826,30 +909,24 @@
 		if isinstance(e, topdl.Computer) and e.get_attribute('portal')]:
 	    myname = e.name[0]
-	    peer = e.get_attribute('peer')
-	    lexp = e.get_attribute('experiment')
-	    lproj, leid = lexp.split('/', 1)
-	    ldomain = e.get_attribute('domain')
-	    mexp = e.get_attribute('masterexperiment')
+	    type = e.get_attribute('portal_type')
+
+	    info = conninfo_to_dict(myname, connInfo)
+
+	    if not info:
+		raise service_error(service_error.req,
+			"No connectivity info for %s" % myname)
+
+	    peer = info.get('peer', "")
+	    ldomain = self.domain;
+
+	    mexp = info.get('masterexperiment',"")
 	    mproj, meid = mexp.split("/", 1)
-	    mdomain = e.get_attribute('masterdomain')
-	    muser = e.get_attribute('masteruser') or 'root'
-	    smbshare = e.get_attribute('smbshare') or 'USERS'
-	    scriptdir = e.get_attribute('scriptdir')
-	    active = e.get_attribute('active')
-	    type = e.get_attribute('portal_type')
-	    segid = fedid(hexstr=e.get_attribute('peer_segment'))
-	    for e in topo.elements:
-		if isinstance(e, topdl.Segment) and e.id.fedid == segid:
-		    seg = e
-		    break
-	    else:
-		raise service_error(service_error.req, 
-			"Can't find segment for portal %s" % myname)
-
-	    is_ip = re.match('\d+\.\d+\.\d+\.\d+', peer)
-
-	    rexp = seg.get_attribute('experiment')
-	    rproj, reid = rexp.split("/", 1)
-	    rdomain = seg.get_attribute('domain')
+	    mdomain = info.get('masterdomain',"")
+	    muser = info.get('masteruser','root')
+	    smbshare = info.get('smbshare', 'USERS')
+
+	    active = info.get('active', 'False')
+
+
 	    cfn = "%s/%s.gw.conf" % (tmpdir, myname.lower())
 	    tunnelconfig = self.attrs.has_key('TunnelCfg')
@@ -857,20 +934,17 @@
 		f = open(cfn, "w")
 		if active == 'True':
-		    print >>f, "active: %s" % active
 		    if type in ('control', 'both'):
-			print >>f, 'port: remote:139:fs:139'
-			print >>f, 'port: remote:7777:boss:7777'
-			print >>f, 'port: remote:16606:control:16606'
+			for s in [s for s in services \
+				if s.get('name', "") in self.imports]:
+			    p = urlparse(s.get('server', 'http://localhost'))
+			    print >>f, 'port: remote:%s:%s:%s' % \
+				    (p.port, p.hostname, p.port)
 
 		if tunnelconfig:
 		    print >>f, "tunnelip: %s" % tunnelconfig
-		print >>f, "seercontrol: control.%s.%s%s" % \
-			(meid.lower(), mproj.lower(), mdomain)
-		if is_ip:
-		    print >>f, "peer: %s" % peer
-		else:
-		    print >>f, "peer: %s.%s.%s%s" % \
-			    (peer.lower(), reid.lower(), 
-				    rproj.lower(), rdomain)
+		# XXX: send this an fedattr
+		#print >>f, "seercontrol: control.%s.%s%s" % \
+			#(meid.lower(), mproj.lower(), mdomain)
+		print >>f, "peer: %s" % peer.lower()
 		print >>f, "ssh_pubkey: /proj/%s/exp/%s/tmp/%s" % \
 			(lproj, leid, pubkey_base)
@@ -903,8 +977,9 @@
 			(myname.lower(), leid.lower(), lproj.lower(),
 				ldomain.lower())
-		    print >>f, "SMBshare: %s" % smbshare
-		    print >>f, "ProjectUser: %s" % muser
-		    print >>f, "ProjectName: %s" % mproj
-		    print >>f, "ExperimentID: %s/%s" % (mproj, meid)
+		    for s in services:
+			if s.get('name',"") in self.imports:
+			    client_service_out[s['name']](f, s)
+		    # Does seer need this?
+		    # print >>f, "ExperimentID: %s/%s" % (mproj, meid)
 		    f.close()
 		except IOError, e:
@@ -1051,4 +1126,6 @@
 	    raise service_error(server_error.req, "Badly formed request")
 
+	connInfo = req.get('connection', [])
+	services = req.get('service', [])
 	auth_attr = req['allocID']['fedid']
 	aid = "%s" % auth_attr
@@ -1083,5 +1160,5 @@
 		os.mkdir(softdir)
 	    for s in sw:
-		print "%s %s %s" % ( s, certfile, softdir)
+		self.log.debug("Retrieving %s" % s)
 		get_url(s, certfile, softdir)
 
@@ -1131,5 +1208,6 @@
 
 	    self.generate_portal_configs(topo, pubkey_base, 
-		    secretkey_base, tmpdir, master)
+		    secretkey_base, tmpdir, master, proj, ename, connInfo, 
+		    services)
 	    self.generate_ns2(topo, expfile, 
 		    "/proj/%s/software/%s/" % (proj, ename), master)
@@ -1140,4 +1218,6 @@
 	except service_error, e:
 	    err = e
+	except e:
+	    err = service_error(service_error.internal, str(e))
 
         # Walk up tmpdir, deleting as we go
