Index: trunk/gsdl/src/recpt/collectoraction.cpp
===================================================================
--- trunk/gsdl/src/recpt/collectoraction.cpp	(revision 1422)
+++ trunk/gsdl/src/recpt/collectoraction.cpp	(revision 1425)
@@ -24,7 +24,14 @@
  *********************************************************************/
 
+// note that the collectoraction relies on having direct access to a
+// collections configuration file. this breaks the separation between
+// receptionist and collection server and so is not suitable (at least
+// in its current form) for use when collection servers are separate 
+// from the receptionist (e.g. when using the CORBA protocol).
+
 #include "collectoraction.h"
 #include "OIDtools.h"
 #include "fileutil.h"
+#include "cfgread.h"
 
 #if !defined (__WIN32__)
@@ -55,92 +62,96 @@
   argsinfo.addarginfo (NULL, arg_ainfo);
 
-  arg_ainfo.shortname = "pcp";
-  arg_ainfo.longname = "previous collector page";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
+  arg_ainfo.shortname = "bc1fullname";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1dirname";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1contactemail";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1aboutdesc";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1clone";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1clonecol";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1inputdir1";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1inputdir2";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1inputdir3";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  arg_ainfo.shortname = "bc1inputdir4";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = true;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "";
+  arg_ainfo.savedarginfo = cgiarginfo::must;
+  argsinfo.addarginfo (NULL, arg_ainfo);
+
+  // only set when one of the fields was changed in
+  // the "collection info" page
+  arg_ainfo.shortname = "bc1infochanged";
+  arg_ainfo.longname = "collector specific";
+  arg_ainfo.multiplechar = false;
+  arg_ainfo.defaultstatus = cgiarginfo::weak;
+  arg_ainfo.argdefault = "0";
   arg_ainfo.savedarginfo = cgiarginfo::mustnot;
   argsinfo.addarginfo (NULL, arg_ainfo);
 
-  arg_ainfo.shortname = "bc1fullname";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1dirname";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1contactemail";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1aboutdesc";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1clone";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = false;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "0";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1clonecol";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1inputdir1";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1inputdir2";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1inputdir3";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
-  arg_ainfo.shortname = "bc1inputdir4";
-  arg_ainfo.longname = "collector specific";
-  arg_ainfo.multiplechar = true;
-  arg_ainfo.defaultstatus = cgiarginfo::weak;
-  arg_ainfo.argdefault = "";
-  arg_ainfo.savedarginfo = cgiarginfo::must;
-  argsinfo.addarginfo (NULL, arg_ainfo);
-
+  // only set when cfg file is altered from within
+  // "configure collection" page
   arg_ainfo.shortname = "bc1cfgchanged";
   arg_ainfo.longname = "collector specific";
@@ -186,5 +197,5 @@
 
 bool collectoraction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args, 
-				     ostream &/*logout*/) {
+				     ostream &logout) {
 
   if (args["cp"] != "intro") {
@@ -194,12 +205,20 @@
   }
 
-  if ((args["pcp"] == "info") && args["bc1dirname"].empty()) {
-    // we've just come from the "collection information" page for the 
-    // first time so we'll need to create the collection with mkcol.pl
-    // and set up bc1dirname - we do this part here instead of in do_action
-    // because the bc1dirname argument must be set to its new value before
-    // the compressedoptions macros are set.
-    args["bc1dirname"] = get_directory_name (args["bc1fullname"]);
-    do_mkcol = true;
+  if (args["bc1infochanged"] == "1") {
+
+    if (args["bc1dirname"].empty()) {
+      // we've just come from the "collection information" page for the 
+      // first time so we'll need to create the collection with mkcol.pl
+      // and set up bc1dirname - we do this part here instead of in do_action
+      // because the bc1dirname argument must be set to its new value before
+      // the compressedoptions macros are set.
+      args["bc1dirname"] = get_directory_name (args["bc1fullname"]);
+      do_mkcol = true;
+
+    } else {
+      // "collection information" has been changed after collection was made
+      // so we'll need to update the cfg file.
+      update_cfgfile_partial (args, logout);
+    }
   }
 
@@ -208,9 +227,126 @@
     // page. we need to update the file on disk and catch bc1 arguments up
     // with changes.
-
-
-  }
-
+    update_cfgfile_complete (args, logout);
+  }
+  
   return true;
+}
+
+// update configuration file on disk to match bc1 arguments
+void collectoraction::update_cfgfile_partial (cgiargsclass &args, ostream &logout) {
+
+  text_t cfgfile = filename_cat(gsdlhome, "collect", args["bc1dirname"], "etc", "collect.cfg");
+  char *cfgfilec = cfgfile.getcstr();
+
+  vector<text_tarray> cfgarray;
+
+  // read in cfg file
+  ifstream cfg_in (cfgfilec);
+  if (cfg_in) {
+    text_tarray cfgline;
+    while (read_cfg_line(cfg_in, cfgline) >= 0) {
+      if (cfgline.size () >= 2) {
+	if (cfgline[0] == "creator") {
+	  cfgline[1] = args["bc1contactemail"];
+	} else if (cfgline[0] == "collectionmeta") {
+	  if (cfgline[1] == "collectionname") {
+	    cfgline[2] = args["bc1fullname"];
+	  } else if (cfgline[1] == "collectionextra") {
+	    cfgline[2] = carriage_replace (args["bc1aboutdesc"], 0);
+	  }
+	}
+      }
+      cfgarray.push_back (cfgline);
+    }
+    cfg_in.close();
+
+    // now write cfg file back out
+    ofstream cfg_out (cfgfilec);
+    if (cfg_out) {
+      // lock the file
+      int fd = GSDL_GET_FILEDESC(cfg_out);
+      int lock_val = 1;
+      GSDL_LOCK_FILE (fd);
+      if (lock_val != 0) {
+	logout << "Error: Couldn't lock file " << cfgfilec << "\n";
+	cfg_out.close();
+	
+      } else {
+
+	vector<text_tarray>::const_iterator this_line = cfgarray.begin();
+	vector<text_tarray>::const_iterator end_line = cfgarray.end();
+	while (this_line != end_line) {
+	  write_cfg_line (cfg_out, *this_line);
+	  this_line ++;
+	}
+	GSDL_UNLOCK_FILE (fd);
+	cfg_out.close();
+      }
+
+    } else {
+      logout << "collectoraction::update_cfgfile_partial: unable to open " 
+	     << cfgfilec << " for output\n";
+    }
+
+  } else {
+    logout << "collectoraction::update_cfgfile_partial: unable to open " 
+	   << cfgfilec << " for input\n";
+  }
+  delete cfgfilec;
+}
+
+// replace configuration file on disk with that in the bc1cfgfile argument and 
+// catch other bc1 arguments up with those the new cfgfile contains
+void collectoraction::update_cfgfile_complete (cgiargsclass &args, ostream &logout) {
+
+  text_t cfgfile = filename_cat(gsdlhome, "collect", args["bc1dirname"], "etc", "collect.cfg");
+  char *cfgfilec = cfgfile.getcstr();
+  ofstream cfg_out (cfgfilec);
+  
+  if (cfg_out) {
+    // lock the file
+    int fd = GSDL_GET_FILEDESC(cfg_out);
+    int lock_val = 1;
+    GSDL_LOCK_FILE (fd);
+    if (lock_val != 0) {
+      logout << "Error: Couldn't lock file " << cfgfilec << "\n";
+      cfg_out.close();
+      
+    } else {
+      
+      outconvertclass text_t2ascii;
+      cfg_out << text_t2ascii << args["bc1cfgfile"];
+      GSDL_UNLOCK_FILE (fd);
+      cfg_out.close();
+      
+      // now that we've written the file we'll read it back again and
+      // update our bc1 arguments
+      ifstream cfg_in (cfgfilec);
+      if (cfg_in) {
+	text_tarray cfgline;
+	while (read_cfg_line(cfg_in, cfgline) >= 0) {
+	  if (cfgline.size () >= 2) {
+	    if (cfgline[0] == "creator") {
+	      args["bc1contactemail"] = cfgline[1];
+	    } else if (cfgline[0] == "collectionmeta") {
+	      if (cfgline[1] == "collectionname") {
+		args["bc1fullname"] = cfgline[2];
+	      } else if (cfgline[1] == "collectionextra") {
+		args["bc1aboutdesc"] = carriage_replace (cfgline[2], 1);
+	      }
+	    }
+	  }
+	}
+	cfg_in.close();
+      } else {
+	logout << "collectoraction::update_cfgfile_complete: unable to open " 
+	       << cfgfilec << " for input\n";
+      }
+    }
+  } else {
+    logout << "collectoraction::update_cfgfile_complete: unable to open " 
+	   << cfgfilec << " for output\n";
+  }
+  delete cfgfilec;
 }
 
@@ -330,5 +466,5 @@
 
 // set the _cfgfile_ macro
-void collectoraction::set_cfgfile (displayclass &disp, const text_t &dirname) {
+void collectoraction::set_cfgfile (displayclass &disp, const text_t &dirname, ostream &logout) {
 
   // read in collect.cfg      
@@ -342,6 +478,4 @@
 #endif
   
-  delete cfgfilec;
-
   if (cfg_ifs) {  
     // read in collect.cfg      
@@ -350,4 +484,5 @@
     cfg_ifs.get(c);
     while (!cfg_ifs.eof ()) {
+      if (c=='\\') cfgtext.push_back('\\');
       cfgtext.push_back(c);
       cfg_ifs.get(c);
@@ -357,5 +492,10 @@
     // define it as a macro
     disp.setmacro("cfgfile","collector",cfgtext);
-  } 
+
+  } else {
+    logout << "collectoraction::set_cfgfile: couldn't open configuration file (" 
+	   << cfgfilec << ") for reading\n";
+  }    
+  delete cfgfilec;
 }
 
@@ -423,4 +563,8 @@
     collectorbar += get_button (collector_page, "grey", "view", false);
     collectorbar += "</tr><tr><td colspan=4></td><td align=center>_icongreyuparrow_</td><td colspan=4></td>\n";
+
+  } else if (collector_page == "bild") {
+
+
   }
 
@@ -429,5 +573,5 @@
 
   if (collector_page == "srce") set_fullnamemenu (disp, args, protos, logout);
-  if (collector_page == "conf") set_cfgfile (disp, args["bc1dirname"]);
+  if (collector_page == "conf") set_cfgfile (disp, args["bc1dirname"], logout);
 }
 
@@ -458,4 +602,34 @@
   }
 
+  if (collector_page == "bild") {
+    // do the work (download, import, build)
+    text_t build_cmd = "perl " + filename_cat (gsdlhome, "bin", "script", "build");
+    if (!args["bc1inputdir1"].empty()) {
+      build_cmd += " -download \"" + args["bc1inputdir1"] + "\"";
+    }
+    if (!args["bc1inputdir2"].empty()) {
+      build_cmd += " -download \"" + args["bc1inputdir2"] + "\"";
+    }
+    if (!args["bc1inputdir3"].empty()) {
+      build_cmd += " -download \"" + args["bc1inputdir3"] + "\"";
+    }
+    if (!args["bc1inputdir4"].empty()) {
+      build_cmd += " -download \"" + args["bc1inputdir4"] + "\"";
+    }
+    build_cmd.push_back (' ');
+    build_cmd += args["bc1dirname"];
+
+#if !defined (__WIN32__)
+    // run in background on unix systems
+    build_cmd += " &";
+#endif
+    char *build_cmdc = build_cmd.getcstr();
+#if defined (__WIN32__)
+    gsdl_system (build_cmdc, logout);
+#else
+    system (build_cmdc);
+#endif
+    delete build_cmdc;
+  }
 
   if (error.empty()) {
Index: trunk/gsdl/src/recpt/collectoraction.h
===================================================================
--- trunk/gsdl/src/recpt/collectoraction.h	(revision 1422)
+++ trunk/gsdl/src/recpt/collectoraction.h	(revision 1425)
@@ -47,5 +47,9 @@
 			 recptprotolistclass *protos, ostream &logout);
 
-  void set_cfgfile (displayclass &disp, const text_t &dirname);
+  void set_cfgfile (displayclass &disp, const text_t &dirname, ostream &logout);
+
+  void update_cfgfile_partial (cgiargsclass &args, ostream &logout);
+
+  void update_cfgfile_complete (cgiargsclass &args, ostream &logout);
 
   text_t carriage_replace (const text_t &intext, int sw);
