Index: /branches/eam_branches/ipp-20111122/Ohana/src/libohana/src/string.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/libohana/src/string.c	(revision 33202)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/libohana/src/string.c	(revision 33203)
@@ -143,4 +143,24 @@
 }
 
+int scan_line_maxlen (FILE *f, char *line, int maxlen) {
+
+  int i, status;
+  char c;
+  
+  status = EOF + 1;
+  
+  for (i = 0, c = 0; (c != '\n') && (status != EOF) && (i < maxlen); i++) {
+    status = fscanf (f, "%c", &c);
+    line[i] = c;
+  }
+  line[i - 1] = 0;  /* this could make things crash! */
+
+  if (i > 1) {
+    status = EOF + 1;
+  }
+
+  return (status);
+}
+
 char *_parse_nextword (char *string) {
 
Index: /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/HostTableLoad.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/HostTableLoad.c	(revision 33203)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/HostTableLoad.c	(revision 33203)
@@ -0,0 +1,110 @@
+# include "photdbc.h"
+
+typedef struct {
+  char *hostname;
+  char *pathname;
+  int hostID;
+} HostInfo
+
+typedef struct {
+    int Nhosts;
+  HostInfo *hosts;
+} HostTable
+
+void InitHosts (HostInfo *hosts, int Nhosts, int NHOSTS) {
+
+  int i;
+  for (i = Nhosts; i < NHOSTS; i++) {
+    hosts[i].hostname = NULL;
+    hosts[i].pathname = NULL;
+  }
+  return;
+}
+
+void FreeHosts (HostInfo *hosts, int Nhosts) {
+
+  int i;
+  for (i = 0; i < Nhosts; i++) {
+    free (hosts[i].hostname);
+    free (hosts[i].pathname);
+  }
+  free (hosts);
+  return;
+}
+
+HostTable *HostTableLoad () {
+
+  FILE *f = fopen (filename, "r");
+  if (!f) {
+    fprintf (stderr, "failed to open host table %s\n", filename);
+    return NULL;
+  }
+
+  // simple format: ID hostname pathname
+  
+  int NHOSTS = 16;
+  int Nhosts = 0;
+  ALLOCATE (hosts, HostInfo, NHOSTS);
+  InitHosts (hosts, Nhosts, NHOSTS);
+
+  int Nline;
+  for (Nline = 0; TRUE; Nline ++) {
+    int ID;
+    char tmphost[1024];
+    char tmppath[1024];
+    char line[1024];
+
+    int status = scan_line_maxlen (f, line, 1024);
+    if (status = EOF) break;
+
+    // find first non-whitespace char & skip commented lines
+    for (i = 0; OHANA_WHITESPACE (line[i]); i++);
+    if (line[i] == '#') continue;
+
+    status = sscanf (line, "%d %1023s %1023s", &ID, tmphost, tmppath);
+    if (status != 3) {
+      fprintf (stderr, "error reading line %d of host table %s\n", Nline, filename);
+      FreeHost (hosts, Nhosts);
+      return NULL;
+    }
+
+    hosts[Nhosts].hostID = ID;
+    hosts[Nhosts].hostname = strcreate(tmphost);
+    hosts[Nhosts].pathname = strcreate(tmppath);
+    
+    Nhosts ++;
+    if (Nhosts >= NHOSTS) {
+      NHOSTS += 16;
+      REALLOCATE (hosts, HostInfo, NHOSTS);
+      InitHosts (hosts, Nhosts, NHOSTS);
+    }
+  }    
+
+  ALLOCATE (table, HostTable, 1);
+  table->Nhosts = Nhosts;
+  table->hosts = hosts;
+
+  return table;
+}
+
+int CheckHostsAndPaths (HostTable *table) {
+
+  char command[64];
+  char shell[64];
+
+  strcpy (command, "ssh");
+  strcpy (shell, "pclient");
+
+  for (i = 0; i < table->Nhosts; i++) {
+
+    // verify that I can ssh to this machine
+    if (DEBUG) fprintf (stderr, "starting host within thread\n");
+
+    pid = rconnect (command, host[0].hostname, shell, stdio);
+    if (!pid) {     
+      /** failure to start: extend retry period **/
+      if (DEBUG) fprintf (stderr, "failure to start %s\n", table->hosts[i].hostname);
+    }
+  }
+
+}
Index: /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/dvodist.c
===================================================================
--- /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/dvodist.c	(revision 33203)
+++ /branches/eam_branches/ipp-20111122/Ohana/src/photdbc/src/dvodist.c	(revision 33203)
@@ -0,0 +1,100 @@
+# include "photdbc.h"
+
+int main (int argc, char **argv) {
+
+  int i;
+  char *skyfile;
+  Catalog incatalog;
+  Catalog outcatalog;
+  SkyTable *sky;
+  SkyList *skylist;
+
+  /* get configuration info, args, lockfile */
+  initialize (argc, argv);
+
+  // dvodist (-out | -in)
+  // dvodist -out : host table represents new target locations
+  
+  hosts = HostTableLoad ();
+
+  // the output catalog needs to inherit the SKY_DEPTH of the input catalog
+  sky = SkyTableLoadOptimal (CATDIR, NULL, GSCFILE, TRUE, SKY_DEPTH_HST, VERBOSE);
+  SkyTableSetFilenames (sky, CATDIR, "cpt");
+  skylist = SkyListByPatch (sky, -1, &REGION);
+
+  AssignSkyToHost (skylist, hosts);
+
+  CopyToHostLocation ();
+
+  SkyTableSave (sky, skyfile);
+
+}
+
+void stuff () {
+
+  for (i = 0; i < skylist[0].Nregions; i++) {
+    if (VERBOSE) fprintf (stderr, "%s\n", skylist[0].regions[i][0].name);
+
+    // set the parameters which guide catalog open/load/create
+    incatalog.filename = skylist[0].filename[i];
+    incatalog.Nsecfilt = GetPhotcodeNsecfilt ();
+    incatalog.catflags = LOAD_AVES | LOAD_MEAS | LOAD_SECF;
+
+    // an error exit status here is a significant error
+    if (!dvo_catalog_open (&incatalog, skylist[0].regions[i], VERBOSE, "r")) {
+      fprintf (stderr, "ERROR: failure to open/create catalog file %s\n", incatalog.filename);
+      exit (2);
+    }
+    // skip empty input catalogs
+    if (!incatalog.Naves_disk) {
+      dvo_catalog_unlock (&incatalog);
+      dvo_catalog_free (&incatalog);
+      continue;
+    }
+
+    // create output catalog filename
+    outcatalog.filename = strsubs (incatalog.filename, CATDIR, argv[1]);
+    if (outcatalog.filename == NULL) Shutdown ("error with input catalog name");
+
+    // define outcatalog open parameters
+    outcatalog.catformat = dvo_catalog_catformat (CATFORMAT);  // set the default catformat from config data
+    outcatalog.catmode   = dvo_catalog_catmode (CATMODE);      // set the default catmode from config data
+    outcatalog.Nsecfilt  = incatalog.Nsecfilt;                 // inherit from the incatalog
+    outcatalog.catflags  = LOAD_AVES | LOAD_MEAS | LOAD_MISS | LOAD_SECF;
+
+    // output catalogs always represent the same skyregions as the input catalogs
+    if (!dvo_catalog_open (&outcatalog, skylist[0].regions[i], VERBOSE, "w")) {
+      fprintf (stderr, "ERROR: failure to open/create catalog file %s\n", outcatalog.filename);
+      exit (2);
+    }
+
+    // the output catalog needs to have the same values for 'objID' and 'sorted' as the input
+    outcatalog.objID = incatalog.objID;
+    outcatalog.sorted = incatalog.sorted;
+    if (!incatalog.sorted) {
+      fprintf (stderr, "ERROR: input db must be sorted: %s\n", incatalog.filename);
+      exit (2);
+    }
+
+    /* limit number of measures based on selections */
+    make_subcatalog (&outcatalog, &incatalog, skylist[0].regions[i]);
+	
+    // XXX add other filters here:
+    // join_stars (&outcatalog);
+    // unique_measures (catalog);
+    // flag_measures (&db, catalog);
+    // get_mags (catalog);
+
+    dvo_catalog_save (&outcatalog, VERBOSE);
+    dvo_catalog_unlock (&outcatalog);
+    dvo_catalog_free (&outcatalog);
+
+    dvo_catalog_unlock (&incatalog);
+    dvo_catalog_free (&incatalog);
+  }
+
+  ALLOCATE (skyfile, char, strlen(argv[1]) + strlen("/SkyTable.fits") + 1);
+  sprintf (skyfile, "%s/SkyTable.fits", argv[1]);
+  SkyTableSave (sky, skyfile);
+  exit (0);
+}
