Index: /trunk/Ohana/src/addstar/Makefile
===================================================================
--- /trunk/Ohana/src/addstar/Makefile	(revision 4863)
+++ /trunk/Ohana/src/addstar/Makefile	(revision 4864)
@@ -61,5 +61,5 @@
 $(SRC)/update_coords.$(ARCH).o \
 $(SRC)/wcatalog.$(ARCH).o \
-$(SRC)/wimage.$(ARCH).o \
+$(SRC)/Shutdown.$(ARCH).o \
 $(SRC)/rfits.$(ARCH).o \
 $(SRC)/rtext.$(ARCH).o
Index: /trunk/Ohana/src/addstar/include/addstar.h
===================================================================
--- /trunk/Ohana/src/addstar/include/addstar.h	(revision 4863)
+++ /trunk/Ohana/src/addstar/include/addstar.h	(revision 4864)
@@ -138,5 +138,5 @@
 Stars     *getgsc                 PROTO((GSCRegion *patch, int *NSTARS));
 Stars     *getusno                PROTO((GSCRegion *catstats, int *Nstars));
-Image     *gimages                PROTO((Image *image, int *Npimage));
+Image     *gimages                PROTO((FITS_DB *db, Image *image, int *Npimage));
 Stars     *grefcat                PROTO((char *Refcat, GSCRegion *catstats, int *nstars));
 Stars     *grefstars              PROTO((char *file, int *Nstars));
@@ -152,5 +152,5 @@
 int        load_pt_catalog        PROTO((Catalog *catalog, GSCRegion *region));  /*** choose new name ***/
 void       load_subpix            PROTO(());
-void       lock_image_db          PROTO(());
+void       lock_image_db          PROTO((FITS_DB *db, char *filename));
 int        main                   PROTO((int argc, char **argv));
 void       make_backup            PROTO((char *filename));
@@ -170,8 +170,10 @@
 void       sort_stars             PROTO((Stars *stars, int N));
 int        str_to_radec           PROTO((double *ra, double *dec, char *str1, char *str2));
-void       unlock_image_db        PROTO((Image *image));
+void       unlock_image_db        PROTO((FITS_DB *db));
 void       update_coords          PROTO((Average *average, Measure *measure, int *next));
 void       wcatalog               PROTO((Catalog *catalog));
-void       wimage                 PROTO((Image *image));
+void       wimage                 PROTO((FITS_DB *db, Image *image));
+void       create_image_db        PROTO((FITS_DB *db));
+void       set_db                 PROTO((FITS_DB *in));
 
 void       uppercase              PROTO((char *string));
Index: /trunk/Ohana/src/addstar/src/Shutdown.c
===================================================================
--- /trunk/Ohana/src/addstar/src/Shutdown.c	(revision 4864)
+++ /trunk/Ohana/src/addstar/src/Shutdown.c	(revision 4864)
@@ -0,0 +1,28 @@
+# include "addstar.h"
+
+static FITS_DB *db;
+
+void set_db (FITS_DB *in) {
+  db = in;
+}
+
+/* clean up open / locked ImageCat before shutting down */
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format));
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
+  SetProtect (TRUE);
+  fits_db_close (db);
+  fprintf (stderr, "ERROR: addstar halted\n");
+  exit (1);
+}
+
Index: /trunk/Ohana/src/addstar/src/addstar.c
===================================================================
--- /trunk/Ohana/src/addstar/src/addstar.c	(revision 4863)
+++ /trunk/Ohana/src/addstar/src/addstar.c	(revision 4864)
@@ -8,4 +8,5 @@
   GSCRegion *regions;
   Catalog catalog;
+  FITS_DB db;
 
   double dtime;
@@ -21,9 +22,10 @@
   overlap = NULL;
   regions = NULL;
+  set_db (&db);
 
   if (SKYPROBE) load_subpix ();
 
-  /* we use the image table to lock db access */
-  lock_image_db ();
+  /* we use the image table to lock db access -- perhaps this is not necessary?*/
+  lock_image_db (&db, ImageCat);
 
   switch (MODE) {
@@ -32,5 +34,7 @@
     if ((DUMP != NULL) && !strcmp (DUMP, "rawstars")) dump_rawstars (stars, Nstars);
     regions = gregion_image (&image, &Nregions);
-    overlap = gimages (&image, &Noverlap);
+    /* lock_image_db (&db, ImageCat); */
+    overlap = gimages (&db, &image, &Noverlap);
+    /* unlock_image_db (&db); */
     break;
   case M_REFLIST:
@@ -75,5 +79,20 @@
 
   if (CALIBRATE) { FindCalibration (&image); }
-  unlock_image_db (&image); 
+
+  if (db.dbstate == LCK_EMPTY) {
+    create_image_db (&db);
+  }
+  
+  ohana_memcheck (FALSE);
+
+  /* write out new image */
+  if (MODE == M_IMAGE) {
+    dvo_image_addrows (&db, &image, 1);
+    SetProtect (TRUE);
+    dvo_image_update (&db, VERBOSE);
+    SetProtect (FALSE);
+  }
+  ohana_memcheck (FALSE);
+  /* unlock_image_db (&db); */
 
   gettimeofday (&stop, NULL);
Index: /trunk/Ohana/src/addstar/src/gimages.c
===================================================================
--- /trunk/Ohana/src/addstar/src/gimages.c	(revision 4863)
+++ /trunk/Ohana/src/addstar/src/gimages.c	(revision 4864)
@@ -2,9 +2,8 @@
 
 /* given image, find catalog images which overlap it */
-Image *gimages (Image *image, int *Npimage) {
+Image *gimages (FITS_DB *db, Image *image, int *Npimage) {
   
-  int i, j, k, Nimage, addtolist, size, dbstate;
-  int NTIMAGE, Ntimage, ntimage;
-  int NPIMAGE, npimage;
+  int i, j, k, addtolist;
+  int NPIMAGE, npimage, Ntimage;
   Image *timage, *pimage;
   Coords tcoords;
@@ -12,8 +11,4 @@
   double Xi[5], Yi[5], Xo[5], Yo[5];  /* image and original corners */
   double zeropt;
-  struct stat filestatus;
-  FILE *f;
-
-  FITS_DB *db;
 
   /* if image.db is opened successfully, f will not be NULL.
@@ -21,16 +16,14 @@
      if image.db is not locked & opened successfully, we will not reach here!
   */
-  db = GetDB ();
   if (db[0].dbstate == LCK_EMPTY) {
     *Npimage = 0;
     return (NULL);
   }
-  fseek (f, 0, SEEK_SET);
 
-  if (!dvo_image_load (db, TRUE)) {
-    Shutdown ("can't read image catalog %s", ImageCat);
+  /* read entire db table (use block read eventually?) */
+  if (!dvo_image_load (db, VERBOSE, FORCE_READ)) {
+    Shutdown ("can't read image catalog %s", db[0].filename);
   }
-  timage = fits_table_get_Image (&db.ftable, &Ntimage);
-  /* timage represents the complete image table */
+  timage = fits_table_get_Image (&db[0].ftable, &Ntimage, &db[0].swapped);
 
   fits_scan (&db[0].header, "ZERO_PT", "%lf", 1, &zeropt);
@@ -80,5 +73,7 @@
   BuildChipMatch (timage, Ntimage);
 
-  /* run through image table and search for overlaps */
+  /* run through image table and search for overlaps
+     also define the vtable entries for the images we keep  */
+
   for (i = 0; i < Ntimage; i++) {
 
@@ -116,5 +111,5 @@
 
   BuildChipMatch (pimage, npimage);
-
+  
   if (VERBOSE) fprintf (stderr, "found %d overlapping images\n", npimage);
 
@@ -134,4 +129,3 @@
    we are now loading in the entire image db table into memory.  
 
-   we will need to write out the new image with a vtable.
 */
Index: /trunk/Ohana/src/addstar/src/image-db.c
===================================================================
--- /trunk/Ohana/src/addstar/src/image-db.c	(revision 4863)
+++ /trunk/Ohana/src/addstar/src/image-db.c	(revision 4864)
@@ -1,22 +1,14 @@
 # include "addstar.h"
 
-# define LOCK LCK_XCLD
+void lock_image_db (FITS_DB *db, char *filename) {
 
-/* file-pointer to Image.db table. if image db does not yet exist */
-static FITS_DB db;
+  /* lock the image catalog */
+  check_permissions (filename);
 
-FITS_DB *GetDB () {
-  return (&db);
-}
+  db[0].lockstate = LCK_XCLD;
+  db[0].timeout   = 3600.0;
+  fits_db_init (db);
 
-void lock_image_db () {
-  /* lock the image catalog */
-  check_permissions (ImageCat);
-
-  db.lockstate = LCK_XCLD;
-  db.timeout   = 3600.0;
-  fits_db_init (&db);
-
-  if (!fits_db_lock (&db, ImageCat)) {
+  if (!fits_db_lock (db, filename)) {
     fprintf (stderr, "ERROR: can't lock image catalog\n");
     exit (1);
@@ -24,39 +16,46 @@
 }
 
-void unlock_image_db (Image *image) {
+void unlock_image_db (FITS_DB *db) {
 
   mode_t mode;
 
-  /* protect wimage from interrupt signals */
-  if (MODE == M_IMAGE) {
-    SetProtect (TRUE);
-    wimage (image); 
-    SetProtect (FALSE);
+  fprintf (stderr, "closing file\n");
+  if (db[0].f == NULL) {
+    fprintf (stderr, "re-closing file??\n");
   }
-
-  fits_db_close (&db);
+  fits_db_close (db);
+  db[0].f = NULL;
 
   /* force permissions to 666 */
   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-  chmod (ImageCat, mode);
+  chmod (db[0].filename, mode);
 }
 
-/* clean up open / locked ImageCat before shutting down */
-int Shutdown (char *format, ...) {  
-  va_list argp;
-  char *formatplus;
-  
-  ALLOCATE (formatplus, char, strlen(format));
-  strcpy (formatplus, format);
-  strcat (formatplus, "\n");
+void create_image_db (FITS_DB *db) {
 
-  va_start (argp, format);
-  vfprintf (stderr, formatplus, argp);
-  free (formatplus);
-  va_end (argp);
+  if (VERBOSE) fprintf (stderr, "can't find %s, creating a new one\n", ImageCat);
 
-  SetProtect (TRUE);
-  fits_db_close (&db);
-  fprintf (stderr, "ERROR: addstar halted\n");
-  exit (1);
+  /* create new header */
+  fits_init_header (&db[0].header);
+
+  if (!strcmp (CATMODE, "RAW")) {
+    /* make header a fake image */
+    db[0].header.bitpix   = 16;
+    db[0].header.Naxes    = 2;
+    db[0].header.Naxis[0] = 1;
+    db[0].header.Naxis[1] = 1;
+    fits_create_header (&db[0].header);
+  }
+
+  if (!strcmp (CATMODE, "MEF") || !strcmp (CATMODE, "SPLIT")) {
+    fits_create_header (&db[0].header);
+  }
+
+  fits_create_matrix (&db[0].header, &db[0].matrix);
+  fits_table_set_Image (&db[0].ftable, NULL, 0);
+
+  /* assign Zero Point provided by first image in dB */
+  fits_modify (&db[0].header, "ZERO_PT", "%lf", 1, ZeroPt);
+  fits_modify (&db[0].header, "NIMAGES", "%d", 1, 0);
 }
+
Index: /trunk/Ohana/src/addstar/src/rfits.c
===================================================================
--- /trunk/Ohana/src/addstar/src/rfits.c	(revision 4863)
+++ /trunk/Ohana/src/addstar/src/rfits.c	(revision 4864)
@@ -16,5 +16,5 @@
   if (!fits_fread_ftable (f, &table, "SMPFILE")) goto escape;
 
-  smpdata = fits_table_get_SMPData (&table, &Nstars);
+  smpdata = fits_table_get_SMPData (&table, &Nstars, NULL);
 
   ALLOCATE (stars, Stars, Nstars);
Index: /trunk/Ohana/src/addstar/src/wimage.c
===================================================================
--- /trunk/Ohana/src/addstar/src/wimage.c	(revision 4863)
+++ /trunk/Ohana/src/addstar/src/wimage.c	(revision 4864)
@@ -2,48 +2,33 @@
 
 /* add 1 image to image db */
-void wimage (Image *image) {
+void wimages (FITS_DB *db, Image *image, int Nimage) {
   
-  FILE *f;
-  int Nimages, status, offset, dbstate;
-  Header header;
+  int status, Nimages;
 
-  db = GetDB ();
-  fseek (f, 0, SEEK_SET);
+  /* set permissions somewhere ...
+  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+  fchmod (ImageCat, mode); */
 
-  if (dbstate == LCK_EMPTY) {
-    if (VERBOSE) fprintf (stderr, "can't find %s, creating a new one\n", ImageCat);
-    if (!fits_read_header (ImageTemplate, &header)) {
-      fprintf (stderr, "ERROR: can't find template header %s\n", ImageTemplate);
-      exit (1);
-    }
-    /* assign Zero Point provided by first image in dB */
-    fits_modify (&header, "ZERO_PT", "%lf", 1, ZeroPt);
-    fits_modify (&header, "NIMAGES", "%d", 1, 0);
-  } else {
-    if (!fits_load_header (f, &header)) {
-      fprintf (stderr, "ERROR: can't read image header %s\n", ImageCat);
-      exit (1);
-    }
-  }
-  
+  /* adjust header */
   Nimages = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimages);
+  fits_scan (&db[0].header, "NIMAGES", "%d", 1, &Nimages);
   Nimages ++;
-  fits_modify (&header, "NIMAGES", "%d", 1, Nimages);
+  fits_modify (&db[0].header, "NIMAGES", "%d", 1, Nimages);
 
-  /* position to begining of file to write header */
-  fseek (f, 0, SEEK_SET);
-  status = Fwrite (header.buffer, 1, header.size, f, "char");
-  if (status != header.size) {
-    fprintf (stderr, "ERROR: failed writing data to image header\n");
-    exit (1);
+  fits_table_to_vtable (&db[0].ftable, &db[0].vtable, 0, 0);
+  for (i = 0; i < Nimage; i++) {
+    fits_vadd_rows (&db[0].vtable, (char *) image, 1, sizeof(Image));
   }
 
-  /* position to end of data array */
-  offset = (Nimages - 1)*sizeof(Image) + header.size;
-  fseek (f, offset, SEEK_SET);
+  /* check that primary header and table header agree */
+  if (Nimages != db[0].header.Naxis[1]) {
+    fprintf (stderr, "header / table length mismatch!\n");
+  }
 
-  status = Fwrite (image, sizeof(Image), 1, f, "image");
-  if (status != 1) {
+  SetProtect (TRUE);
+  status = dvo_image_update (db, VERBOSE);
+  SetProtect (FALSE);
+
+  if (!status) {
     fprintf (stderr, "ERROR: failed writing data to image catalog\n");
     exit (1);
@@ -51,7 +36,10 @@
 }
 
-/* the image we add in this routine is always a new image.  
-   We only need to do two things:
-     1) append the data for the image to the end of the file
-     2) update the NIMAGES field in the header (which means, read in header, re-write)
- */
+/* add the new image to the image table:
+   - use the table header (from ftable)
+   - create an empty vtable
+   - add the new image to the end of the vtable
+   
+   - write out the vtable, either as TEXT or FITS
+   * dvo_image_update performs the needed byte-swap on the image data
+*/
Index: /trunk/Ohana/src/delstar/Makefile
===================================================================
--- /trunk/Ohana/src/delstar/Makefile	(revision 4863)
+++ /trunk/Ohana/src/delstar/Makefile	(revision 4864)
@@ -40,5 +40,5 @@
 $(SRC)/sort_lists.$(ARCH).o \
 $(SRC)/check_permissions.$(ARCH).o \
-$(SRC)/dimages.$(ARCH).o          
+$(SRC)/Shutdown.$(ARCH).o          
 
 OBJ = $(DELSTAR)
Index: /trunk/Ohana/src/delstar/include/delstar.h
===================================================================
--- /trunk/Ohana/src/delstar/include/delstar.h	(revision 4863)
+++ /trunk/Ohana/src/delstar/include/delstar.h	(revision 4864)
@@ -50,13 +50,11 @@
 int        args                   PROTO((int *argc, char **argv));
 void       check_permissions      PROTO((char *basefile));
-void       delete_imagefile       PROTO((char *filename));
-void       delete_imagename       PROTO((char *name));
-void       delete_times           PROTO(());
-int        dimages                PROTO((int *imlist, int Nimlist));
+void       delete_imagefile       PROTO((FITS_DB *db, char *filename));
+void       delete_imagename       PROTO((FITS_DB *db, char *name));
+void       delete_times           PROTO((FITS_DB *db));
 int        edge_check             PROTO((double *x1, double *y1, double *x2, double *y2));
-Image     *find_images            PROTO((FILE *f, CatStats *catstats, int *Nimages));
-int       *find_images_data       PROTO((Image *timage, int *nlist));
-int       *find_images_name       PROTO((char *filename, int *nlist));
-int       *find_images_time       PROTO((time_t start, time_t end, PhotCode *code, int *nlist));
+int       *find_images_data       PROTO((FITS_DB *db, Image *timage, int *nlist));
+int       *find_images_name       PROTO((FITS_DB *db, char *filename, int *nlist));
+int       *find_images_time       PROTO((FITS_DB *db, time_t start, time_t end, PhotCode *code, int *nlist));
 void       find_matches           PROTO((Catalog *catalog, int photcode, int start, int end));
 int        gcatalog               PROTO((Catalog *catalog));
@@ -66,6 +64,6 @@
 Image     *gtimes                 PROTO((int *NIMAGE));
 void       help                   PROTO(());
-int        load_image_db          PROTO(());
-void       lock_image_db          PROTO(());
+int        load_image_db          PROTO((FITS_DB *db));
+void       lock_image_db          PROTO((FITS_DB *db, char *filename));
 void       match_images           PROTO((Catalog *catalog, Image *image, int Nimage));
 double     opening_angle          PROTO((double x1, double y1, double x2, double y2, double x3, double y3));
@@ -74,5 +72,7 @@
 void       sort_lists             PROTO((float *X, float *Y, int *S, int N));
 void       sort_regions           PROTO((GSCRegion *region, int N));
-void       unlock_image_db        PROTO(());
+void       unlock_image_db        PROTO((FITS_DB *db));
 void       usage                  PROTO(());
 int        wcatalog               PROTO((Catalog *catalog));
+
+void set_db (FITS_DB *in);
Index: /trunk/Ohana/src/delstar/src/Shutdown.c
===================================================================
--- /trunk/Ohana/src/delstar/src/Shutdown.c	(revision 4864)
+++ /trunk/Ohana/src/delstar/src/Shutdown.c	(revision 4864)
@@ -0,0 +1,28 @@
+# include "delstar.h"
+
+static FITS_DB *db;
+
+void set_db (FITS_DB *in) {
+  db = in;
+}
+
+/* clean up open / locked ImageCat before shutting down */
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format));
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
+  SetProtect (TRUE);
+  fits_db_close (db);
+  fprintf (stderr, "ERROR: delstar halted\n");
+  exit (1);
+}
+
Index: /trunk/Ohana/src/delstar/src/args.c
===================================================================
--- /trunk/Ohana/src/delstar/src/args.c	(revision 4863)
+++ /trunk/Ohana/src/delstar/src/args.c	(revision 4864)
@@ -4,5 +4,6 @@
 
   fprintf (stderr, "USAGE:\n");
-  fprintf (stderr, "  delstar (filename) or (start range) or -orphan (region)\n");
+  fprintf (stderr, "  delstar (filename)\n");
+  fprintf (stderr, "  delstar -name (filename)\n");
   fprintf (stderr, "  delstar -time (start) (stop/range)\n");
   fprintf (stderr, "  delstar -orphan (region)\n");
Index: unk/Ohana/src/delstar/src/delete_image.c
===================================================================
--- /trunk/Ohana/src/delstar/src/delete_image.c	(revision 4863)
+++ 	(revision )
@@ -1,43 +1,0 @@
-
-delete_imagefile (char *filename) {
-
-  int i, Nregions;
-  Image *image;
-  GSCRegion *region;
-  Catalog catalog;
-
-    image = gimages (filename);
-  
-    fprintf (stderr, "deleting %s\n", image[0].name);
-    region = gregions (image, &Nregions);
-
-    for (i = 0; i < Nregions; i++) {
-      fprintf (stderr, "deleting from %s\n", region[i].filename);
-      catalog.filename = region[i].filename;  /* don't free region before catalog! */
-      switch (lock_catalog (&catalog, LCK_SOFT)) {
-      case 0:
-	fprintf (stderr, "ERROR: can't lock file\n");
-	exit (1);
-      case 1:
-	gcatalog (&catalog);
-	break;
-      case 2:
-	fprintf (stderr, "no data in %s, skipping\n", catalog.filename);
-	catalog.Naverage = 0;
-	catalog.Nmeasure = 0;
-	break;
-      default:
-	fprintf (stderr, "weird lock_catalog exit state\n");
-	exit (1);
-      }
-      find_matches (&catalog, image);
-      wcatalog (&catalog);
-    }
-
-    dimages (f, image, 1); 
-
-    /* this probably gets moved inside dimages */
-    unlock_image_db (ImageCat, f, LCK_HARD, &dbstate);
-    fprintf (stderr, "SUCCESS\n");
-    exit (0);
-}
Index: /trunk/Ohana/src/delstar/src/delete_imagefile.c
===================================================================
--- /trunk/Ohana/src/delstar/src/delete_imagefile.c	(revision 4863)
+++ /trunk/Ohana/src/delstar/src/delete_imagefile.c	(revision 4864)
@@ -1,8 +1,7 @@
 # include "delstar.h"
 
-void delete_imagefile (char *filename) {
+void delete_imagefile (FITS_DB *db, char *filename) {
 
-  int i, j;
-  int Nregions, Nimlist;
+  int i, Nregions, Nimlist;
   int *imlist;
   double trange;
@@ -41,5 +40,5 @@
     start = image[0].tzero;
     stop  = image[0].tzero + trange;
-    find_matches (&catalog, image[j].source, start, stop);
+    find_matches (&catalog, image[0].source, start, stop);
     wcatalog (&catalog);
     unlock_catalog (&catalog);
@@ -47,11 +46,11 @@
 
   /* find and delete matching images */
-  imlist = find_images_data (image, &Nimlist);
+  imlist = find_images_data (db, image, &Nimlist);
   if (!Nimlist) Shutdown ("image %s not found in db", filename);
 
-  dimages (imlist, Nimlist); 
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, imlist, Nimlist);
+  dvo_image_update (db, VERBOSE);
+  unlock_image_db (db);
 
-  save_image_db ();
-  unlock_image_db ();
   fprintf (stderr, "SUCCESS\n");
   exit (0);
Index: /trunk/Ohana/src/delstar/src/delete_imagename.c
===================================================================
--- /trunk/Ohana/src/delstar/src/delete_imagename.c	(revision 4863)
+++ /trunk/Ohana/src/delstar/src/delete_imagename.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "delstar.h"
 
-void delete_imagename (char *name) {
+void delete_imagename (FITS_DB *db, char *name) {
 
   int i, j, k;
@@ -12,8 +12,8 @@
   Catalog catalog;
 
-  image = GetImages (&Nimage);
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
 
   /* find image in db by name */
-  imlist = find_images_name (name, &Nimlist);
+  imlist = find_images_name (db, name, &Nimlist);
   if (!Nimlist) Shutdown ("image %s not found in db", name);
   
@@ -55,8 +55,8 @@
 
   /* delete the identified images */
-  dimages (imlist, Nimlist); 
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, imlist, Nimlist);
+  dvo_image_update (db, VERBOSE);
+  unlock_image_db (db);
 
-  save_image_db ();
-  unlock_image_db ();
   fprintf (stderr, "SUCCESS\n");
   exit (0);
Index: /trunk/Ohana/src/delstar/src/delete_times.c
===================================================================
--- /trunk/Ohana/src/delstar/src/delete_times.c	(revision 4863)
+++ /trunk/Ohana/src/delstar/src/delete_times.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "delstar.h"
 
-void delete_times () {
+void delete_times (FITS_DB *db) {
 
   int i, j, k, n;
@@ -17,8 +17,8 @@
   ALLOCATE (region, GSCRegion, NREGIONS);
 
-  image = GetImages (&Nimage);
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
 
   /* find images for time range, delete each image */ 
-  imlist = find_images_time (START, END, PHOTCODE, &Nimlist);
+  imlist = find_images_time (db, START, END, PHOTCODE, &Nimlist);
 
   /* find all overlapping regions */
@@ -75,8 +75,8 @@
 
   /* delete the identified images */
-  dimages (imlist, Nimlist); 
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, imlist, Nimlist);
+  dvo_image_update (db, VERBOSE);
+  unlock_image_db (db);
 
-  save_image_db ();
-  unlock_image_db ();
   fprintf (stderr, "SUCCESS\n");
   exit (0);
Index: /trunk/Ohana/src/delstar/src/delstar.c
===================================================================
--- /trunk/Ohana/src/delstar/src/delstar.c	(revision 4863)
+++ /trunk/Ohana/src/delstar/src/delstar.c	(revision 4864)
@@ -2,4 +2,6 @@
 
 int main (int argc, char **argv) {
+
+  FITS_DB db;
 
   SetSignals ();
@@ -7,17 +9,17 @@
   args (&argc, argv);
 
-  lock_image_db ();
-  load_image_db ();
+  set_db (&db);
+  lock_image_db (&db, ImageCat);
+  load_image_db (&db);
 
-  /* delete orphaned measurements (no image) from catalog */ 
   switch (MODE) {
     case MODE_IMAGEFILE:
-      delete_imagefile (argv[1]);
+      delete_imagefile (&db, argv[1]);
       break;
     case MODE_IMAGENAME:
-      delete_imagename (argv[1]);
+      delete_imagename (&db, argv[1]);
       break;
     case MODE_TIME:
-      delete_times ();
+      delete_times (&db);
       break;
     case MODE_ORPHAN:
Index: unk/Ohana/src/delstar/src/dimages.c
===================================================================
--- /trunk/Ohana/src/delstar/src/dimages.c	(revision 4863)
+++ 	(revision )
@@ -1,32 +1,0 @@
-# include "delstar.h"
-
-/* delete images by sequence number */
-
-int dimages (int *imlist, int Nimlist) {
-  
-  int i, j, Nimage;
-  Image *image;
-
-  image = GetImages (&Nimage);
-
-  /* first, mark the deleted images with a flag (name = 0) */
-  for (i = 0; i < Nimlist; i++) {
-    j = imlist[i];
-    image[j].name[0] = 0;
-    /* this puts a restriction on the DB: image name must not be NULL */
-  }
-
-  /* delete the marked images */
-  for (i = 0, j = 0; j < Nimage; j++) {
-    if (!image[j].name[0]) continue;
-    if (i != j) {
-      image[i] = image[j];
-    }
-    i++;
-  }
-  Nimage = i;
-  REALLOCATE (image, Image, Nimage);
-
-  SetImages (image, Nimage);
-  return (TRUE);
-}
Index: /trunk/Ohana/src/delstar/src/find_image_db.c
===================================================================
--- /trunk/Ohana/src/delstar/src/find_image_db.c	(revision 4863)
+++ /trunk/Ohana/src/delstar/src/find_image_db.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "delstar.h"
 
-int *find_images_name (char *filename, int *nlist) {
+int *find_images_name (FITS_DB *db, char *filename, int *nlist) {
 
   int i, Nimage, Nlist, NLIST;
@@ -16,5 +16,5 @@
   }
 
-  image = GetImages (&Nimage);
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
 
   Nlist = 0;
@@ -34,5 +34,5 @@
 
 /* find images in db by image data (time/photcode) */
-int *find_images_data (Image *timage, int *nlist) {
+int *find_images_data (FITS_DB *db, Image *timage, int *nlist) {
 
   int i, Nimage, Nlist, NLIST; 
@@ -42,9 +42,9 @@
   int code;
 
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+
   start = timage[0].tzero - MAX(0.05*timage[0].trate*timage[0].NY, 1);
   stop  = timage[0].tzero + MAX(1.05*timage[0].trate*timage[0].NY, 1);
   code  = timage[0].source;
-
-  image = GetImages (&Nimage);
 
   Nlist = 0;
@@ -66,5 +66,5 @@
 
 /* find images in db by image data (time/photcode) */
-int *find_images_time (time_t start, time_t end, PhotCode *code, int *nlist) {
+int *find_images_time (FITS_DB *db, time_t start, time_t end, PhotCode *code, int *nlist) {
 
   int i, Nimage, Nlist, NLIST;
@@ -72,5 +72,5 @@
   Image *image;
 
-  image = GetImages (&Nimage);
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
 
   Nlist = 0;
Index: unk/Ohana/src/delstar/src/find_images.c
===================================================================
--- /trunk/Ohana/src/delstar/src/find_images.c	(revision 4863)
+++ 	(revision )
@@ -1,185 +1,0 @@
-# include "delstar.h"
-
-Image *find_images (FILE *f, CatStats *catstats, int *Nimages) {
-  
-  Header header;
-  Image *timage, *image;
-  int i, j, k, found, nimage, Nimage, NIMAGE, NTIMAGE, Nloop, Nlast;
-  int n, Nim, status;
-  double Xc[6], Yc[6], Xi[6], Yi[6], r, d, x, y, dx, dy;
-  Coords *tcoords;
-
-  /* we make positional comparisons in the projection of catalog */
-  tcoords = &catstats[0].coords;
-  /* define catalog corners */
-  Xc[0] = catstats[0].RA[0]; Yc[0] = catstats[0].DEC[0];
-  Xc[1] = catstats[0].RA[1]; Yc[1] = catstats[0].DEC[0];
-  Xc[2] = catstats[0].RA[1]; Yc[2] = catstats[0].DEC[1];
-  Xc[3] = catstats[0].RA[0]; Yc[3] = catstats[0].DEC[1];
-  Xc[4] = catstats[0].RA[0]; Yc[4] = catstats[0].DEC[0];
-  Xc[5] = catstats[0].RA[1]; Yc[5] = catstats[0].DEC[1];
-  for (j = 0; j < 6; j++) {
-    r = Xc[j]; d = Yc[j];
-    RD_to_XY (&Xc[j], &Yc[j], r, d, tcoords);
-  }
-  /* find Y positions of RA center */
-  r = 0.5*(catstats[0].RA[0] + catstats[0].RA[1]);
-  d = catstats[0].DEC[0];
-  RD_to_XY (&x, &y, r, d, tcoords);
-  Yc[0] = MIN (y, Yc[0]);
-  Yc[1] = MIN (y, Yc[1]);
-  Yc[4] = MIN (y, Yc[4]);
-  /* find Y positions of RA center */
-  r = 0.5*(catstats[0].RA[0] + catstats[0].RA[1]);
-  d = catstats[0].DEC[1];
-  RD_to_XY (&x, &y, r, d, tcoords);
-  Yc[2] = MAX (y, Yc[2]);
-  Yc[3] = MAX (y, Yc[3]);
-  Yc[5] = MAX (y, Yc[5]);
-
-  dx = 0.02*(Xc[2] - Xc[0]);
-  dy = 0.02*(Yc[2] - Yc[0]);
-  Xc[0] -= dx; Yc[0] -= dy;
-  Xc[1] += dx; Yc[1] -= dy;
-  Xc[2] += dx; Yc[2] += dy;
-  Xc[3] -= dx; Yc[3] += dy;
-  Xc[4] -= dx; Yc[4] -= dy;
-  Xc[5] -= dx; Yc[5] -= dy;
-
-  /* check if image datafile exists, get header, number of images */
-  if (!fits_fread_header (f, &header)) {
-    fprintf (stderr, "ERROR: error reading image catalog header\n");
-    exit (1);
-  }
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-  if (Nimage == 0) {
-    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
-    Shutdown ();
-  }
-  fseek (f, header.size, SEEK_SET); 
-
-  /* set up buffers for images, temporary storage */
-  NTIMAGE = 100;
-  ALLOCATE (timage, Image, NTIMAGE);
-  NIMAGE = 100;
-  ALLOCATE (image, Image, NIMAGE);
-  nimage = 0;
-  Nloop = Nimage / NTIMAGE + 1;
-  Nlast = Nimage % NTIMAGE;
-  
-  /* read in images in groups of NTIMAGE (100) */
-  for (n = 0; n < Nloop; n++) {
-    Nim = (n == Nloop - 1) ? Nlast : NTIMAGE;
-    status = Fread (timage, sizeof(Image), Nim, f, "image");
-    if (status != Nim) {
-      fprintf (stderr, "ERROR: couldn't read images from image catalog: %s\n", ImageCat);
-      exit (1);
-    }
-    /* test each image in block */
-    for (i = 0; i < Nim; i++) {
-      /* define image corners */
-      Xi[0] = 0;            Yi[0] = 0;
-      Xi[1] = timage[i].NX; Yi[1] = 0;
-      Xi[2] = timage[i].NX; Yi[2] = timage[i].NY;
-      Xi[3] = 0;            Yi[3] = timage[i].NY;
-      Xi[4] = 0;            Yi[4] = 0;
-      Xi[5] = timage[i].NX; Yi[5] = timage[i].NY;
-      found = FALSE;
-      /* transform to tcoords */
-      if (catstats[0].DEC[1] > 86.25) { /* pole */
-	for (j = 0; j < 6; j++) {
-	  XY_to_RD (&r, &d, Xi[j], Yi[j], &timage[i].coords);
-	  if (d > catstats[0].DEC[0] - 0.5) found = TRUE;
-	}
-      } else {
-	for (j = 0; j < 6; j++) {
-	  XY_to_RD (&r, &d, Xi[j], Yi[j], &timage[i].coords);
-	  RD_to_XY (&Xi[j], &Yi[j], r, d, tcoords);
-	}
-	/* check if edges cross */
-	for (j = 0; (j < 5) && !found; j++) {
-	  for (k = 0; (k < 5) && !found; k++) {
-	    found |= edge_check (&Xi[j], &Yi[j], &Xc[k], &Yc[k]);
-	  }
-	}
-      }
-      if (found) {
-	image[nimage] = timage[i]; 
-	image[nimage].code = 0;
-	nimage ++;
-	if (nimage == NIMAGE) {
-	  NIMAGE += 100;
-	  REALLOCATE (image, Image, NIMAGE);
-	}
-      }
-    }
-  }
-      
-  if (VERBOSE) { 
-    for (i = 0; i < nimage; i++) {
-      XY_to_RD (&r, &d, 0.5*image[i].NX, 0.5*image[i].NY, &image[i].coords);
-      fprintf (stderr, "associated images: %d %8.4f %8.4f %10d %6d  %5.3f %6.3f %6.3f\n", 
-	       i, r, d, image[i].tzero, image[i].nstar, 0.001*image[i].secz, 
-	       0.001*image[i].Mcal, 0.001*image[i].dMcal);
-    }
-  }
-
-  REALLOCATE (image, Image, MAX (nimage, 1));
-  free (timage);
-  *Nimages = nimage;
-  return (image);
-}
-
-int edge_check (double *x1, double *y1, double *x2, double *y2) {
-
-  double theta1, theta2;
-  double Theta1, Theta2;
-
-  theta1 = opening_angle (x1[0], y1[0], x2[0], y2[0], x1[1], y1[1]); 
-  theta2 = opening_angle (x1[0], y1[0], x2[0], y2[0], x2[1], y2[1]); 
-
-  if (theta1*theta2 < 0.0) {
-    return (FALSE);
-  }
-
-  if (fabs(theta1) < fabs(theta2)) {
-    return (FALSE);
-  }
-
-  Theta1 = theta1;
-  Theta2 = theta2;
-  theta1 = opening_angle (x2[0], y2[0], x1[1], y1[1], x2[1], y2[1]); 
-  theta2 = opening_angle (x2[0], y2[0], x1[1], y1[1], x1[0], y1[0]); 
-  
- 
-  if (theta1*theta2 < 0.0) {
-    return (FALSE);
-  }
-
-  if (fabs(theta1) < fabs(theta2)) {
-    return (FALSE);
-  }
-
-  return (TRUE);
-
-}
-
-double opening_angle (double x1, double y1, double x2, double y2, double x3, double y3) {
-
-  double dx1, dy1, dx2, dy2, ct, st, theta;
-
-  dx1 = x1 - x2;
-  dy1 = y1 - y2;
-  
-  dx2 = x3 - x2;
-  dy2 = y3 - y2;
-  
-  ct = (dx1*dx2 + dy1*dy2);
-  st = (dx1*dy2 - dx2*dy1);
-
-  theta = atan2 (st, ct);
-
-  return (theta);
-
-}
Index: unk/Ohana/src/delstar/src/gcatstats.c
===================================================================
--- /trunk/Ohana/src/delstar/src/gcatstats.c	(revision 4863)
+++ 	(revision )
@@ -1,57 +1,0 @@
-# include "delstar.h"
-
-gcatstats (catalog, catstats)
-Catalog catalog[];
-CatStats catstats[];
-{
-
-  int i;
-  double RaCenter, DecCenter;
-  double MinRA, MaxRA, MinDEC, MaxDEC;
-  float *X1, *Y1;
-  int *N1;
-  Coords tcoords;
-  
-  fits_scan (&catalog[0].header, "RA0", "%lf", 1, &MinRA);
-  fits_scan (&catalog[0].header, "RA1", "%lf", 1, &MaxRA);
-  fits_scan (&catalog[0].header, "DEC0", "%lf", 1, &MinDEC);
-  fits_scan (&catalog[0].header, "DEC1", "%lf", 1, &MaxDEC);
-
-  /* double check on region RA and DEC ranges */
-  DecCenter = 0.5*(MinDEC + MaxDEC);
-  RaCenter = 0.5*(MinRA + MaxRA);
-  if (MaxDEC > 86.25) {  /* we are on the pole */
-    DecCenter = 90.0;
-    RaCenter = 0.0;
-  }
-
-  catstats[0].RA[0] = MinRA;
-  catstats[0].RA[1] = MaxRA;
-  catstats[0].DEC[0] = MinDEC;
-  catstats[0].DEC[1] = MaxDEC;
-
-  /** allocate local arrays **/
-  ALLOCATE (catstats[0].X, float, catalog[0].Naverage);
-  ALLOCATE (catstats[0].Y, float, catalog[0].Naverage);
-  ALLOCATE (catstats[0].N, int,   catalog[0].Naverage);
-
-  /* project onto rectilinear grid with 1 arcsec pixels, sort by X */
-  /* reference for coords is center of field  */
-  catstats[0].coords.crval1 = RaCenter;
-  catstats[0].coords.crval2 = DecCenter;
-  catstats[0].coords.crpix1 = catstats[0].coords.crpix2 = 0.0;
-  catstats[0].coords.cdelt1 = catstats[0].coords.cdelt2 = 1.0 / 3600.0;
-  catstats[0].coords.pc1_1 = catstats[0].coords.pc2_2 = 1.0;
-  catstats[0].coords.pc1_2 = catstats[0].coords.pc2_1 = 0.0;
-  strcpy (catstats[0].coords.ctype, "RA---TAN");
-
-  X1 = catstats[0].X;
-  Y1 = catstats[0].Y;
-  for (i = 0; i < catalog[0].Naverage; i++, X1++, Y1++) {
-    fRD_to_XY (X1, Y1, catalog[0].average[i].R, catalog[0].average[i].D, &catstats[0].coords);
-    catstats[0].N[i] = i;
-  }
-  if (catalog[0].Naverage > 1) sort_lists (catstats[0].X, catstats[0].Y, catstats[0].N, catalog[0].Naverage);
-  
-}
-
Index: unk/Ohana/src/delstar/src/gregions.c
===================================================================
--- /trunk/Ohana/src/delstar/src/gregions.c	(revision 4863)
+++ 	(revision )
@@ -1,53 +1,0 @@
-# include "delstar.h"
-
-GSCRegion *gregions (Image *image, int *Nregions) {
-  
-  GSCRegion *region;
-  FILE *f;
-  double x, y;
-  double dr, dd, dec, ra;
-  int i, j, done, nregion, NREGION;
-  
-  f = fopen (GSCFILE, "r");
-  if (f == NULL) {
-    fprintf (stderr, "ERROR: can't find GSC region file %s\n", GSCFILE);
-    exit (1);
-  }
-  
-  /* find regions at image corners */
-  NREGION = 10;
-  ALLOCATE (region, GSCRegion, NREGION);
-  nregion = 0;
-
-  /* look for new regions on grid across image */ 
-  for (x = 0; x <= 1; x+=0.25) {
-    for (y = 0; y <= 1; y+=0.25) {
-      XY_to_RD (&ra, &dec, image[0].NX*(1.1*x - 0.05), image[0].NY*(1.1*y - 0.05), &image[0].coords);
-      aregion (&region[nregion], f, ra, dec);
-      done = FALSE;
-      for (j = 0; (j < nregion) && !done; j++) {
-	if (!strcmp (region[nregion].filename, region[j].filename)) {
-	  nregion --;
-	  done = TRUE;
-	}
-      }
-      nregion ++;
-      if (nregion == NREGION) {
-	NREGION += 10;
-	REALLOCATE (region, GSCRegion, NREGION);
-      }
-    }
-  }
-
-  if (VERBOSE) {
-    fprintf (stderr, "found %d region files:\n", nregion);
-    for (i = 0; i < nregion; i++) {
-      fprintf (stderr, "  %d %s\n", i, region[i].filename);
-    }
-  }
-  *Nregions = nregion;
-  
-  fclose (f);
-  return (region);
-  
-}
Index: unk/Ohana/src/delstar/src/gtimes.c
===================================================================
--- /trunk/Ohana/src/delstar/src/gtimes.c	(revision 4863)
+++ 	(revision )
@@ -1,68 +1,0 @@
-# include "delstar.h"
-
-Image *gtimes (int *NIMAGE) {
- 
-  int i, npimage, NPIMAGE, ntimage, Ntimage, NTIMAGE, Nimage;
-  time_t tstart, tend;
-  double range;
-  Image *pimage, *timage;
-  Header header;
-  FILE *f;
-
-  /* globals: START, END, PHOTCODE */
-
-  /* get image db file pointer */
-  f = GetDB (&dbstate);
-  if (dbstate == LCK_EMPTY) {
-    Shutdown ("database is empty");
-  }
-  fseek (f, 0, SEEK_SET);
-
-  /* read header */
-  if (!fits_fread_header (f, &header)) {
-    Shutdown ("can't read image catalog %s", ImageCat);
-  }
-  fseek (f, header.size, SEEK_SET); 
-
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-
-  NTIMAGE = 100;
-  ALLOCATE (timage, Image, NTIMAGE);
-
-  npimage = 0;
-  NPIMAGE = 20;
-  ALLOCATE (pimage, Image, NPIMAGE);
-
-  /* add match on photcode */
-  for (Ntimage = 0; Ntimage < Nimage; Ntimage += ntimage) {
-    ntimage = Fread (timage, sizeof(Image), NTIMAGE, f, "image");
-    for (i = 0; i < ntimage; i++) {
-      tstart = timage[i].tzero;
-      tend = timage[i].tzero + 1e-4*timage[i].trate*timage[i].NY;
-      if ((tstart <= END) && (tend >= START)) {
-	pimage[npimage] = timage[i];
-	npimage ++;
-	if (npimage == NPIMAGE) {
-	  NPIMAGE += 20;
-	  REALLOCATE (pimage, Image, NPIMAGE);
-	}
-      }
-    }
-  }
-  free (timage);
-
-  { 
-    double Ra, Dec;
-    if (VERBOSE) fprintf (stderr, "found the following images:\n");
-    for (i = 0; VERBOSE && (i < npimage); i++) {
-      XY_to_RD (&Ra, &Dec, 0.5*pimage[i].NX, 0.5*pimage[i].NY, &pimage[i].coords);
-      fprintf (stderr, "%3d %s %8.4f %8.4f %d %d\n", i, pimage[i].name, Ra, Dec,
-	       pimage[i].tzero, pimage[i].nstar);
-    }
-  }
-
-  *NIMAGE = npimage;
-  return (pimage);
-
-}
Index: /trunk/Ohana/src/delstar/src/image-db.c
===================================================================
--- /trunk/Ohana/src/delstar/src/image-db.c	(revision 4863)
+++ /trunk/Ohana/src/delstar/src/image-db.c	(revision 4864)
@@ -1,119 +1,35 @@
 # include "delstar.h"
 
-# define LOCK LCK_XCLD
+void lock_image_db (FITS_DB *db, char *filename) {
 
-/* file-pointer to Image.db table. if image db does not yet exist */
-static FILE *f = (FILE *) NULL;
-static int dbstate = LCK_UNLOCK;
+  /* lock the image catalog */
+  check_permissions (filename);
 
-static Header header;
-static Image *image = NULL;
-static int   Nimage;
+  db[0].lockstate = LCK_XCLD;
+  db[0].timeout   = 3600.0;
+  fits_db_init (db);
 
-FILE *GetDB (int *state) {
-  *state = dbstate;
-  return (f);
+  if (!fits_db_lock (db, filename)) {
+    fprintf (stderr, "ERROR: can't lock image catalog\n");
+    exit (1);
+  }
 }
 
-Image *GetImages (int *nimage) {
-  *nimage = Nimage;
-  return (image);
-}
-
-int SetImages (Image *new, int Nnew) {
-  Nimage = Nnew;
-  image  =  new;
-  fits_modify (&header, "NIMAGES", "%d", 1, Nimage);
-  return (TRUE);
-}
-
-/* clean up open / locked ImageCat before shutting down */
-int Shutdown (char *format, ...) {  
-  va_list argp;
-  char *formatplus;
-  
-  ALLOCATE (formatplus, char, strlen(format));
-  strcpy (formatplus, format);
-  strcat (formatplus, "\n");
-
-  va_start (argp, format);
-  vfprintf (stderr, formatplus, argp);
-  va_end (argp);
-
-  SetProtect (TRUE);
-  fclearlockfile (ImageCat, f, LOCK, &dbstate);
-  fprintf (stderr, "ERROR: addstar halted\n");
-  exit (1);
-}
-
-void lock_image_db () {
-  /* lock the image catalog */
-  check_permissions (ImageCat);
-  f = fsetlockfile (ImageCat, 3600.0, LOCK, &dbstate);
-  if (f == NULL) {
-    Shutdown ("ERROR: can't lock image catalog");
-  }
-  if (dbstate == LCK_EMPTY) {
-    Shutdown ("ERROR: database is empty");
-  }
-  fseek (f, 0, SEEK_SET);
-}
-
-int load_image_db () {
-
-  int nimage;
-
-  /* read header */
-  fseek (f, 0, SEEK_SET);
-  if (!fits_fread_header (f, &header)) {
-    Shutdown ("can't read image catalog %s", ImageCat);
-  }
-  fseek (f, header.size, SEEK_SET); 
-
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-  ALLOCATE (image, Image, Nimage);
-
-  nimage = Fread (image, sizeof(Image), Nimage, f, "image");
-  if (nimage != Nimage) {
-    Shutdown ("error reading images from db file");
-  }
-  
-  return (TRUE);
-}
-
-int save_image_db () {
-
-  int status;
-  char line[1024];
-  mode_t mode;
-
-  /* use cp to make backup copy */
-  sprintf (line, "cp %s %s~", ImageCat, ImageCat);
-  status = system (line);
-  if (status) {
-    Shutdown ("ERROR: unable to create %s~, exiting", ImageCat);
-  }
-  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-  sprintf (line, "%s~", ImageCat);
-  chmod (line, mode);
-
-  /* update header */
-  fits_modify (&header, "NIMAGES", "%d", 1, Nimage);
-
-  /* write out data to already opened file */
-  fseek (f, 0, SEEK_SET);
-  Fwrite (header.buffer, 1, header.size, f, "char");
-  Fwrite (image, sizeof(Image), Nimage, f, "image");
-
-  return (TRUE);
-}
-
-void unlock_image_db () {
+void unlock_image_db (FITS_DB *db) {
 
   mode_t mode;
 
-  fclearlockfile (ImageCat, f, LOCK, &dbstate);
+  fits_db_close (db);
+
+  /* force permissions to 666 */
   mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-  chmod (ImageCat, mode);
+  chmod (db[0].filename, mode);
 }
+
+int load_image_db (FITS_DB *db) {
+
+  if (db[0].dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db[0].filename);
+
+  /* read entire db table */
+  if (!dvo_image_load (db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db[0].filename);
+}
Index: /trunk/Ohana/src/gastro2/src/rfits.c
===================================================================
--- /trunk/Ohana/src/gastro2/src/rfits.c	(revision 4863)
+++ /trunk/Ohana/src/gastro2/src/rfits.c	(revision 4864)
@@ -13,5 +13,5 @@
   if (!fits_fread_ftable (f, &table, "SMPFILE")) goto escape;
 
-  stars = fits_table_get_SMPData (&table, &Nstars);
+  stars = fits_table_get_SMPData (&table, &Nstars, NULL);
 
   ALLOCATE (stardata, StarData, Nstars);
Index: /trunk/Ohana/src/getstar/src/gimages.c
===================================================================
--- /trunk/Ohana/src/getstar/src/gimages.c	(revision 4863)
+++ /trunk/Ohana/src/getstar/src/gimages.c	(revision 4864)
@@ -10,15 +10,10 @@
   Header header;
   
-  f = fopen (ImageCat, "r");
-  if (f == (FILE *) NULL) {
-    fprintf (stderr, "error opening image cat %s\n", ImageCat);
-    exit (1);
-  }
-
-  /* read header */
-  if (!fits_load_header (f, &header)) {
-    if (VERBOSE) fprintf (stderr, "ERROR: can't read image catalog %s\n", ImageCat);
-    exit (1);
-  }
+  set_db (&db);
+  lock_image_db (&db, ImageCat);
+  if (db[0].dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db[0].filename);
+  if (!dvo_image_load (db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db[0].filename);
+  timage = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+  unlock_image_db (&db, ImageCat);
 
   fits_scan (&header, "ZERO_PT", "%lf", 1, &zeropt);
@@ -26,27 +21,4 @@
     fprintf (stderr, "ERROR: zero point in image table (%f:%s) inconsistent with zero point in image header (%f:%s)\n",
 	     zeropt, ImageCat, ZeroPt, filename);
-    exit (1);
-  }
-
-  /* advance to data segment */ 
-  fseek (f, header.size, SEEK_SET); 
-
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-  /* check that file size makes sense */
-  if (stat (ImageCat, &filestatus) == -1) {
-    fprintf (stderr, "ERROR: failed to get status of image catalog\n");
-    exit (1);
-  }
-  size = Nimage*sizeof(Image) + header.size;
-  if (size != filestatus.st_size) {
-    fprintf (stderr, "ERROR: image catalog has inconsistent size\n");
-    exit (1);
-  } 
-
-  ALLOCATE (timage, Image, Nimage);
-  nimage = Fread (timage, sizeof(Image), Nimage, f, "image");
-  if (nimage != Nimage) {
-    fprintf (stderr, "error reading images from table\n");
     exit (1);
   }
Index: /trunk/Ohana/src/imregister/Makefile
===================================================================
--- /trunk/Ohana/src/imregister/Makefile	(revision 4863)
+++ /trunk/Ohana/src/imregister/Makefile	(revision 4864)
@@ -179,5 +179,5 @@
 
 install:
-	for i in $(INSTALL); do make $$i.install; done
+	for i in $(INSTALL); do make $$i.install || exit; done
 
 clean:
Index: /trunk/Ohana/src/imregister/detrend/altpath.c
===================================================================
--- /trunk/Ohana/src/imregister/detrend/altpath.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/detrend/altpath.c	(revision 4864)
@@ -8,5 +8,4 @@
   char *dBPath, infile[256], outfile[256], line[1024];
   struct stat statbuf;
-  VTable vtable;
 
   ALLOCATE (current, int, Nimage);
@@ -48,9 +47,9 @@
 
     /** we may later want to pull this out and put it elsewhere **/
-    fits_vtable_from_ftable (&db[0].ftable, &vtable, list, Nlist);
+    fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, list, Nlist);
     for (i = 0; i < Nmatch; i++) {
-      fits_convert_DetReg ((DetReg *) vtable.buffer[i], sizeof (DetReg), 1);
+      fits_convert_DetReg ((DetReg *) db[0].vtable.buffer[i], sizeof (DetReg), 1);
     }
-    fits_db_update (db, &vtable);
+    fits_db_update (db);
     fits_db_close (db);
     fits_db_free (db);
@@ -85,9 +84,9 @@
 
     /** we may later want to pull this out and put it elsewhere **/
-    fits_vtable_from_ftable (&db[0].ftable, &vtable, list, Nlist);
+    fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, list, Nlist);
     for (i = 0; i < Nmatch; i++) {
-      fits_convert_DetReg ((DetReg *) vtable.buffer[i], sizeof (DetReg), 1);
+      fits_convert_DetReg ((DetReg *) db[0].vtable.buffer[i], sizeof (DetReg), 1);
     }
-    fits_db_update (db, &vtable);
+    fits_db_update (db);
     fits_db_close (db);
     fits_db_free (db);
@@ -114,9 +113,9 @@
 
     /** we may later want to pull this out and put it elsewhere **/
-    fits_vtable_from_ftable (&db[0].ftable, &vtable, list, Nlist);
+    fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, list, Nlist);
     for (i = 0; i < Nmatch; i++) {
-      fits_convert_DetReg ((DetReg *) vtable.buffer[i], sizeof (DetReg), 1);
+      fits_convert_DetReg ((DetReg *) db[0].vtable.buffer[i], sizeof (DetReg), 1);
     }
-    fits_db_update (db, &vtable);
+    fits_db_update (db);
     fits_db_close (db);
     fits_db_free (db);
Index: /trunk/Ohana/src/imregister/detrend/modify.c
===================================================================
--- /trunk/Ohana/src/imregister/detrend/modify.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/detrend/modify.c	(revision 4864)
@@ -6,5 +6,4 @@
   int i, j, value;
   int *list;
-  VTable vtable;
   
   value = M_UNDEF;
@@ -45,9 +44,9 @@
 
   /** we may later want to pull this out and put it elsewhere **/
-  fits_vtable_from_ftable (&db[0].ftable, &vtable, list, Nmatch);
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, list, Nmatch);
   for (i = 0; i < Nmatch; i++) {
-    fits_convert_DetReg ((DetReg *) vtable.buffer[i], sizeof (DetReg), 1);
+    fits_convert_DetReg ((DetReg *) db[0].vtable.buffer[i], sizeof (DetReg), 1);
   }
-  fits_db_update (db, &vtable);
+  fits_db_update (db);
   fits_db_close (db);
   fits_db_free (db);
Index: /trunk/Ohana/src/imregister/imphot/modify.c
===================================================================
--- /trunk/Ohana/src/imregister/imphot/modify.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/imphot/modify.c	(revision 4864)
@@ -5,5 +5,4 @@
 
   int i, j;
-  VTable vtable;
 
   /* modify the selected entries */
@@ -29,9 +28,9 @@
 
   /** we may later want to pull this out and put it elsewhere **/
-  fits_vtable_from_ftable (&db[0].ftable, &vtable, match, Nmatch);
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, match, Nmatch);
   for (i = 0; i < Nmatch; i++) {
-    fits_convert_Image ((Image *) vtable.buffer[i], sizeof (Image), 1);
+    fits_convert_Image ((Image *) db[0].vtable.buffer[i], sizeof (Image), 1);
   }
-  fits_db_update (db, &vtable);
+  fits_db_update (db);
   fits_db_close (db);
   fits_db_free (db);
Index: /trunk/Ohana/src/imregister/imreg/imregclient.c
===================================================================
--- /trunk/Ohana/src/imregister/imreg/imregclient.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/imreg/imregclient.c	(revision 4864)
@@ -7,5 +7,4 @@
   FILE *f;
   RegImage *image;
-  VTable vtable;
   FITS_DB db;
 
@@ -83,8 +82,8 @@
 
   fits_convert_RegImage (image, sizeof (RegImage), Nentry);
-  fits_table_to_vtable (&db.ftable, &vtable, 0, 0);
-  fits_vadd_rows (&vtable, (char *) image, Nentry, sizeof(RegImage));
+  fits_table_to_vtable (&db.ftable, &db.vtable, 0, 0);
+  fits_vadd_rows (&db.vtable, (char *) image, Nentry, sizeof(RegImage));
 
-  fits_db_update (&db, &vtable);
+  fits_db_update (&db);
   fits_db_close (&db);
   fits_db_free (&db);
Index: /trunk/Ohana/src/imregister/imreg/modify.c
===================================================================
--- /trunk/Ohana/src/imregister/imreg/modify.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/imreg/modify.c	(revision 4864)
@@ -7,5 +7,4 @@
   char *tmppath;
   char *ext, *root, *path, dist;
-  VTable vtable;
 
   Nold = 0;
@@ -79,9 +78,9 @@
 
   /** we may later want to pull this out and put it elsewhere **/
-  fits_vtable_from_ftable (&db[0].ftable, &vtable, match, Nmatch);
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, match, Nmatch);
   for (i = 0; i < Nmatch; i++) {
-    fits_convert_RegImage ((RegImage *) vtable.buffer[i], sizeof (RegImage), 1);
+    fits_convert_RegImage ((RegImage *) db[0].vtable.buffer[i], sizeof (RegImage), 1);
   }
-  fits_db_update (db, &vtable);
+  fits_db_update (db);
   fits_db_close (db);
   fits_db_free (db);
Index: /trunk/Ohana/src/imregister/spreg/modify.c
===================================================================
--- /trunk/Ohana/src/imregister/spreg/modify.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/spreg/modify.c	(revision 4864)
@@ -6,5 +6,4 @@
   int i, j, Nold;
   char *tmppath;
-  VTable vtable;
 
   Nold = 0;
@@ -39,9 +38,9 @@
 
   /** we may later want to pull this out and put it elsewhere **/
-  fits_vtable_from_ftable (&db[0].ftable, &vtable, match, Nmatch);
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, match, Nmatch);
   for (i = 0; i < Nmatch; i++) {
-    fits_convert_Spectrum ((Spectrum *) vtable.buffer[i], sizeof (Spectrum), 1);
+    fits_convert_Spectrum ((Spectrum *) db[0].vtable.buffer[i], sizeof (Spectrum), 1);
   }
-  fits_db_update (db, &vtable);
+  fits_db_update (db);
   fits_db_close (db);
   fits_db_free (db);
Index: /trunk/Ohana/src/imregister/src/detregister.c
===================================================================
--- /trunk/Ohana/src/imregister/src/detregister.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/detregister.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "detrend.h"
-static char *version = "detregister $Revision: 3.3 $";
+static char *version = "detregister $Revision: 3.4 $";
 
 int main (int argc, char **argv) {
@@ -8,5 +8,4 @@
   DetReg newdata;
   Descriptor descriptor;
-  VTable vtable;
   FITS_DB db;
   
@@ -40,8 +39,8 @@
 
   fits_convert_DetReg (&newdata, sizeof (DetReg), 1);
-  fits_table_to_vtable (&db.ftable, &vtable, 0, 0);
-  fits_vadd_rows (&vtable, (char *) &newdata, 1, sizeof(DetReg));
+  fits_table_to_vtable (&db.ftable, &db.vtable, 0, 0);
+  fits_vadd_rows (&db.vtable, (char *) &newdata, 1, sizeof(DetReg));
 
-  fits_db_update (&db, &vtable);
+  fits_db_update (&db);
   fits_db_close (&db);
   fits_db_free (&db);
Index: /trunk/Ohana/src/imregister/src/detsearch.c
===================================================================
--- /trunk/Ohana/src/imregister/src/detsearch.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/detsearch.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "detrend.h"
-static char *version = "detsearch $Revision: 3.6 $";
+static char *version = "detsearch $Revision: 3.7 $";
 
 int main (int argc, char **argv) {
@@ -35,5 +35,5 @@
 
   if (!output.Modify && !output.Delete && !output.Altpath) fits_db_close (&db);
-  detrend = fits_table_get_DetReg (&db.ftable, &Ndetrend);
+  detrend = fits_table_get_DetReg (&db.ftable, &Ndetrend, &db.swapped);
   
   match = MatchCriteria (detrend, Ndetrend, &Nmatch);          /* match basic criteria */
Index: /trunk/Ohana/src/imregister/src/imphotmerge.c
===================================================================
--- /trunk/Ohana/src/imregister/src/imphotmerge.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/imphotmerge.c	(revision 4864)
@@ -1,6 +1,8 @@
 # include "imregister.h"
 
+/*** this needs to be written using dvo_image functions ***/
+
 Image *LoadImageTable (FILE *f, Header *header, int *nimage);
-static char *version = "imphotcopy $Revision: 1.2 $";
+static char *version = "imphotcopy $Revision: 1.3 $";
 
 int main (int argc, char **argv) {
Index: /trunk/Ohana/src/imregister/src/imphotsearch.c
===================================================================
--- /trunk/Ohana/src/imregister/src/imphotsearch.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/imphotsearch.c	(revision 4864)
@@ -2,5 +2,5 @@
 # include "imphot.h"
 
-static char *version = "imphotsearch $Revision: 1.8 $";
+static char *version = "imphotsearch $Revision: 1.9 $";
 
 int main (int argc, char **argv) {
@@ -25,5 +25,5 @@
   }
   /* we use a varient of fits_db_load since the file may be in text format */
-  if (!dvo_image_load (&db)) {
+  if (!dvo_image_load (&db, VERBOSE, FORCE_READ)) {
     fprintf (stderr, "ERROR: failure to load db\n");
     fits_db_close (&db);
@@ -32,5 +32,5 @@
   if (!options.modify) fits_db_close (&db);
 
-  image = fits_table_get_Image (&db.ftable, &Nimage);
+  image = fits_table_get_Image (&db.ftable, &Nimage, &db.swapped);
 
   match = subset (image, Nimage, &Nmatch);
Index: /trunk/Ohana/src/imregister/src/imregister.c
===================================================================
--- /trunk/Ohana/src/imregister/src/imregister.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/imregister.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "imreg.h"
-static char *version = "imregister $Revision: 3.6 $";
+static char *version = "imregister $Revision: 3.7 $";
 
 int main (int argc, char **argv) {
@@ -7,5 +7,4 @@
   int Nregimage;
   RegImage *image, *regimage;
-  VTable vtable;
   FITS_DB db;
 
@@ -39,8 +38,8 @@
 
   fits_convert_RegImage (regimage, sizeof (RegImage), Nregimage);
-  fits_table_to_vtable (&db.ftable, &vtable, 0, 0);
-  fits_vadd_rows (&vtable, (char *) regimage, Nregimage, sizeof(RegImage));
+  fits_table_to_vtable (&db.ftable, &db.vtable, 0, 0);
+  fits_vadd_rows (&db.vtable, (char *) regimage, Nregimage, sizeof(RegImage));
 
-  fits_db_update (&db, &vtable);
+  fits_db_update (&db);
   fits_db_close (&db);
   fits_db_free (&db);
Index: /trunk/Ohana/src/imregister/src/imregtable.c
===================================================================
--- /trunk/Ohana/src/imregister/src/imregtable.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/imregtable.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "imreg.h"
-static char *version = "imregtable $Revision: 3.6 $";
+static char *version = "imregtable $Revision: 3.7 $";
 
 int main (int argc, char **argv) {
@@ -12,5 +12,4 @@
   Matrix matrix;
   FTable ftable;
-  VTable vtable;
   FITS_DB db;
 
@@ -34,5 +33,5 @@
   fits_read_ftable  (infile, &ftable, "IMAGE_DATABASE");
 
-  image = fits_table_get_RegImage (&ftable, &Nimage);
+  image = fits_table_get_RegImage (&ftable, &Nimage, NULL);
 
   /* load database table */
@@ -58,8 +57,8 @@
 
   fits_convert_RegImage (image, sizeof (RegImage), Nimage);
-  fits_table_to_vtable (&db.ftable, &vtable, 0, 0);
-  fits_vadd_rows (&vtable, (char *) image, Nimage, sizeof(RegImage));
+  fits_table_to_vtable (&db.ftable, &db.vtable, 0, 0);
+  fits_vadd_rows (&db.vtable, (char *) image, Nimage, sizeof(RegImage));
 
-  fits_db_update (&db, &vtable);
+  fits_db_update (&db);
   fits_db_close (&db);
   fits_db_free (&db);
Index: /trunk/Ohana/src/imregister/src/imsearch.c
===================================================================
--- /trunk/Ohana/src/imregister/src/imsearch.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/imsearch.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "imreg.h"
-static char *version = "imsearch $Revision: 3.5 $";
+static char *version = "imsearch $Revision: 3.6 $";
 
 int main (int argc, char **argv) {
@@ -29,5 +29,5 @@
   if (!output.modify && !output.delete) fits_db_close (&db);
 
-  image = fits_table_get_RegImage (&db.ftable, &Nimage);
+  image = fits_table_get_RegImage (&db.ftable, &Nimage, &db.swapped);
   
   match = match_criteria (image, Nimage, &Nmatch);
Index: /trunk/Ohana/src/imregister/src/imstatreg.c
===================================================================
--- /trunk/Ohana/src/imregister/src/imstatreg.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/imstatreg.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "imreg.h"
-static char *version = "imstatreg $Revision: 3.14 $";
+static char *version = "imstatreg $Revision: 3.15 $";
 
 int main (int argc, char **argv) {
@@ -10,5 +10,4 @@
   RegImage *image, *subset;
   FITS_DB image_db, temp_db;
-  VTable vtable;
 
   get_version (argc, argv, version);
@@ -67,5 +66,5 @@
       exit (1);
     }
-    subset = fits_table_get_RegImage (&temp_db.ftable, &Nsubset);
+    subset = fits_table_get_RegImage (&temp_db.ftable, &Nsubset, &temp_db.swapped);
     fprintf (stderr, "temporary database read\n");
 
@@ -90,5 +89,5 @@
 	 we will just drop the temp db data */
     }
-    image = fits_table_get_RegImage (&image_db.ftable, &Nimage);
+    image = fits_table_get_RegImage (&image_db.ftable, &Nimage, &image_db.swapped);
     fprintf (stderr, "main database read\n");
 
@@ -98,14 +97,13 @@
 
     /* update entries in main db */
-    fits_vtable_from_ftable (&image_db.ftable, &vtable, match, Nmatch);
+    fits_vtable_from_ftable (&image_db.ftable, &image_db.vtable, match, Nmatch);
     for (i = 0; i < Nmatch; i++) {
-      fits_convert_RegImage ((RegImage *) vtable.buffer[i], sizeof (RegImage), 1);
+      fits_convert_RegImage ((RegImage *) image_db.vtable.buffer[i], sizeof (RegImage), 1);
     }
-    fits_db_update (&image_db, &vtable);
+    fits_db_update (&image_db);
     fits_db_close (&image_db);
 
     fits_db_free (&image_db);
     fits_db_free (&temp_db);
-    fits_free_vtable (&vtable);
     if (match != NULL) free (match);
     if (image != NULL) free (image);
Index: /trunk/Ohana/src/imregister/src/photreg.c
===================================================================
--- /trunk/Ohana/src/imregister/src/photreg.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/photreg.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "photreg.h"
-static char *version = "photreg $Revision: 1.7 $";
+static char *version = "photreg $Revision: 1.8 $";
 
 int main (int argc, char **argv) {
@@ -7,5 +7,4 @@
   char *filename;
   PhotPars newdata;
-  VTable vtable;
   FITS_DB db;
   
@@ -42,8 +41,8 @@
   /** we may later want to pull this out and put it elsewhere **/
   fits_convert_PhotPars (&newdata, sizeof (PhotPars), 1);
-  fits_table_to_vtable (&db.ftable, &vtable, 0, 0);
-  fits_vadd_rows (&vtable, (char *) &newdata, 1, sizeof(PhotPars));
+  fits_table_to_vtable (&db.ftable, &db.vtable, 0, 0);
+  fits_vadd_rows (&db.vtable, (char *) &newdata, 1, sizeof(PhotPars));
 
-  fits_db_update (&db, &vtable);
+  fits_db_update (&db);
   fits_db_close (&db);
   fits_db_free (&db);
Index: /trunk/Ohana/src/imregister/src/photsearch.c
===================================================================
--- /trunk/Ohana/src/imregister/src/photsearch.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/photsearch.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "photreg.h"
-static char *version = "photsearch $Revision: 1.7 $";
+static char *version = "photsearch $Revision: 1.8 $";
 
 int main (int argc, char **argv) {
@@ -41,8 +41,8 @@
   /* add test to EXTNAME? */
   if (output.convert) {
-    photpars_old = fits_table_get_PhotParsOld (&db.ftable, &Nphotpars);
+    photpars_old = fits_table_get_PhotParsOld (&db.ftable, &Nphotpars, &db.swapped);
     photpars = PhotParsOld_to_PhotPars (photpars_old, Nphotpars);
   } else {
-    photpars = fits_table_get_PhotPars (&db.ftable, &Nphotpars);
+    photpars = fits_table_get_PhotPars (&db.ftable, &Nphotpars, &db.swapped);
   }
 
Index: /trunk/Ohana/src/imregister/src/spregister.c
===================================================================
--- /trunk/Ohana/src/imregister/src/spregister.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/spregister.c	(revision 4864)
@@ -1,10 +1,9 @@
 # include "imregister.h"
 # include "spreg.h"
-static char *version = "spregister $Revision: 1.7 $";
+static char *version = "spregister $Revision: 1.8 $";
 
 int main (int argc, char **argv) {
  
   Spectrum *spectrum;
-  VTable vtable;
   FITS_DB db;
 
@@ -39,8 +38,8 @@
 
   fits_convert_Spectrum (spectrum, sizeof (Spectrum), 1);
-  fits_table_to_vtable (&db.ftable, &vtable, 0, 0);
-  fits_vadd_rows (&vtable, (char *) spectrum, 1, sizeof(Spectrum));
+  fits_table_to_vtable (&db.ftable, &db.vtable, 0, 0);
+  fits_vadd_rows (&db.vtable, (char *) spectrum, 1, sizeof(Spectrum));
 
-  fits_db_update (&db, &vtable);
+  fits_db_update (&db);
   fits_db_close (&db);
   fits_db_free (&db);
Index: /trunk/Ohana/src/imregister/src/spsearch.c
===================================================================
--- /trunk/Ohana/src/imregister/src/spsearch.c	(revision 4863)
+++ /trunk/Ohana/src/imregister/src/spsearch.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "imregister.h"
 # include "spreg.h"
-static char *version = "spsearch $Revision: 1.6 $";
+static char *version = "spsearch $Revision: 1.7 $";
 
 int main (int argc, char **argv) {
@@ -29,5 +29,5 @@
   if (!output.modify && !output.delete) fits_db_close (&db);
 
-  spectrum = fits_table_get_Spectrum (&db.ftable, &Nspectrum);
+  spectrum = fits_table_get_Spectrum (&db.ftable, &Nspectrum, &db.swapped);
   
   match = match_criteria (spectrum, Nspectrum, &Nmatch);
Index: /trunk/Ohana/src/libautocode/def/autocode.c
===================================================================
--- /trunk/Ohana/src/libautocode/def/autocode.c	(revision 4863)
+++ /trunk/Ohana/src/libautocode/def/autocode.c	(revision 4864)
@@ -27,5 +27,6 @@
 
 /*** add test of EXTNAME and header-defined columns? ***/
-$STRUCT *fits_table_get_$STRUCT (FTable *ftable, int *Ndata) {
+/* return internal structure representation */
+$STRUCT *fits_table_get_$STRUCT (FTable *ftable, int *Ndata, int *swapped) {
 
   $STRUCT *data;
@@ -33,6 +34,8 @@
   *Ndata = ftable[0].header[0].Naxis[1];
   data = ($STRUCT *) ftable[0].buffer;
-  fits_convert_$STRUCT (data, sizeof ($STRUCT), *Ndata);
-  
+  if ((swapped == NULL) || (*swapped == FALSE)) {
+    fits_convert_$STRUCT (data, sizeof ($STRUCT), *Ndata);
+    if (swapped != NULL) *swapped = TRUE;
+  }
   return (data);
 }
Index: /trunk/Ohana/src/libautocode/def/autocode.h
===================================================================
--- /trunk/Ohana/src/libautocode/def/autocode.h	(revision 4863)
+++ /trunk/Ohana/src/libautocode/def/autocode.h	(revision 4864)
@@ -2,5 +2,5 @@
 /** STRUCT DEFINITION **/
 
-$STRUCT *fits_table_get_$STRUCT (FTable *table, int *Ndata);
+$STRUCT *fits_table_get_$STRUCT (FTable *table, int *Ndata, int *swapped);
 int      fits_table_set_$STRUCT (FTable *ftable, $STRUCT *data, int Ndata);
 int      fits_table_mkheader_$STRUCT (Header *header);
Index: /trunk/Ohana/src/libfits/include/fitsio.h
===================================================================
--- /trunk/Ohana/src/libfits/include/fitsio.h	(revision 4863)
+++ /trunk/Ohana/src/libfits/include/fitsio.h	(revision 4864)
@@ -82,4 +82,5 @@
 int   fits_fread_Theader          PROTO((FILE *, Header *));
 int   fits_fread_ftable           PROTO((FILE *, FTable *, char *)); 
+int   fits_fread_vtable_range     PROTO((FILE *f, VTable *table, int start, int Nrows));
 int   fits_fread_vtable           PROTO((FILE *f, VTable *table, char *extname, int Nrow, int *row));
 int   fits_fread_ftable_data      PROTO((FILE *f, FTable *table));
@@ -122,4 +123,5 @@
 int   fits_read_Theader           PROTO((char *, Header *));     
 int   fits_read_table             PROTO((char *, FTable *)); 
+int   fits_read_table             PROTO((char *, FTable *)); 
 int   fits_write_Theader          PROTO((char *, Header *header));
 int   fits_write_table            PROTO((char *, FTable *)); 
Index: /trunk/Ohana/src/libohana/Makefile
===================================================================
--- /trunk/Ohana/src/libohana/Makefile	(revision 4863)
+++ /trunk/Ohana/src/libohana/Makefile	(revision 4864)
@@ -47,4 +47,5 @@
 $(SRC)/fits_db.$(ARCH).o	 \
 $(SRC)/photfits.$(ARCH).o        \
+$(SRC)/dvo_image.$(ARCH).o           \
 $(SRC)/phot_catalog.$(ARCH).o    \
 $(SRC)/phot_catalog_mef.$(ARCH).o      \
Index: /trunk/Ohana/src/libohana/include/dvo.h
===================================================================
--- /trunk/Ohana/src/libohana/include/dvo.h	(revision 4863)
+++ /trunk/Ohana/src/libohana/include/dvo.h	(revision 4864)
@@ -90,4 +90,9 @@
   Header theader;
   FTable ftable;
+  VTable vtable;
+  int    mode;          /* what data storage mode is used for disk file? */
+  int    format;        /* what data format is used for disk file? */
+  int    virtual;       /* is table in ftable or vtable? */
+  int    swapped;       /* is table in internal byte-order? */
 } FITS_DB;
 
@@ -141,8 +146,9 @@
 int   fits_db_lock                PROTO((FITS_DB *db, char *filename));
 int   fits_db_load                PROTO((FITS_DB *db));
+int   fits_db_load_segment        PROTO((FITS_DB *db, int start, int Nrows));
+int   fits_db_save                PROTO((FITS_DB *db));
+int   fits_db_update              PROTO((FITS_DB *db));
 int   fits_db_close               PROTO((FITS_DB *db));
 int   fits_db_free                PROTO((FITS_DB *db));
-int   fits_db_save                PROTO((FITS_DB *db));
-int   fits_db_update              PROTO((FITS_DB *db, VTable *vtable));
 
 /* in coords.c, using libautocode/def/coords.d */
@@ -256,3 +262,12 @@
 int save_catalog_mef (Catalog *catalog, char VERBOSE);
 
+/*** DVO image db I/O Functions ***/
+int dvo_image_load (FITS_DB *db, int VERBOSE, int FORCE_READ);
+int dvo_image_save (FITS_DB *db, int VERBOSE);
+int dvo_image_update (FITS_DB *db, int VERBOSE);
+int dvo_image_load_raw (FITS_DB *db, int VERBOSE, int FORCE_READ);
+int dvo_image_update_raw (FITS_DB *db, int VERBOSE);
+int dvo_image_save_raw (FITS_DB *db, int VERBOSE);
+int dvo_image_addrows (FITS_DB *db, Image *new, int Nnew);
+
 # endif
Index: /trunk/Ohana/src/libohana/src/dvo_convert.c
===================================================================
--- /trunk/Ohana/src/libohana/src/dvo_convert.c	(revision 4863)
+++ /trunk/Ohana/src/libohana/src/dvo_convert.c	(revision 4864)
@@ -24,10 +24,10 @@
   }
   if (!strcmp (extname, "DVO_AVERAGE")) {
-    average = fits_table_get_Average (ftable, Naverage);
+    average = fits_table_get_Average (ftable, Naverage, NULL);
     return (average);
   }
   if (!strcmp (extname, "DVO_AVERAGE_ELIXIR")) {
     AverageElixir *tmpaverage;
-    tmpaverage = fits_table_get_AverageElixir (ftable, Naverage);
+    tmpaverage = fits_table_get_AverageElixir (ftable, Naverage, NULL);
     average = AverageElixirToInternal (tmpaverage, *Naverage);
     free (tmpaverage);
@@ -36,5 +36,5 @@
   if (!strcmp (extname, "DVO_AVERAGE_LONEOS")) {
     AverageLoneos *tmpaverage;
-    tmpaverage = fits_table_get_AverageLoneos (ftable, Naverage);
+    tmpaverage = fits_table_get_AverageLoneos (ftable, Naverage, NULL);
     average = AverageLoneosToInternal (tmpaverage, *Naverage);
     free (tmpaverage);
@@ -43,5 +43,5 @@
   if (!strcmp (extname, "DVO_AVERAGE_PANSTARRS")) {
     AveragePanstarrs *tmpaverage;
-    tmpaverage = fits_table_get_AveragePanstarrs (ftable, Naverage);
+    tmpaverage = fits_table_get_AveragePanstarrs (ftable, Naverage, NULL);
     average = AveragePanstarrsToInternal (tmpaverage, *Naverage);
     free (tmpaverage);
@@ -99,10 +99,10 @@
   }
   if (!strcmp (extname, "DVO_MEASURE")) {
-    measure = fits_table_get_Measure (ftable, Nmeasure);
+    measure = fits_table_get_Measure (ftable, Nmeasure, NULL);
     return (measure);
   }
   if (!strcmp (extname, "DVO_MEASURE_ELIXIR")) {
     MeasureElixir *tmpmeasure;
-    tmpmeasure = fits_table_get_MeasureElixir (ftable, Nmeasure);
+    tmpmeasure = fits_table_get_MeasureElixir (ftable, Nmeasure, NULL);
     measure = MeasureElixirToInternal (tmpmeasure, *Nmeasure);
     free (tmpmeasure);
@@ -111,5 +111,5 @@
   if (!strcmp (extname, "DVO_MEASURE_LONEOS")) {
     MeasureLoneos *tmpmeasure;
-    tmpmeasure = fits_table_get_MeasureLoneos (ftable, Nmeasure);
+    tmpmeasure = fits_table_get_MeasureLoneos (ftable, Nmeasure, NULL);
     measure = MeasureLoneosToInternal (tmpmeasure, *Nmeasure);
     free (tmpmeasure);
@@ -118,5 +118,5 @@
   if (!strcmp (extname, "DVO_MEASURE_PANSTARRS")) {
     MeasurePanstarrs *tmpmeasure;
-    tmpmeasure = fits_table_get_MeasurePanstarrs (ftable, Nmeasure);
+    tmpmeasure = fits_table_get_MeasurePanstarrs (ftable, Nmeasure, NULL);
     measure = MeasurePanstarrsToInternal (tmpmeasure, *Nmeasure);
     free (tmpmeasure);
Index: /trunk/Ohana/src/libohana/src/dvo_image.c
===================================================================
--- /trunk/Ohana/src/libohana/src/dvo_image.c	(revision 4863)
+++ /trunk/Ohana/src/libohana/src/dvo_image.c	(revision 4864)
@@ -4,15 +4,135 @@
 enum {FITS, RAW};
 
-/** this is a varient on fits_db_load to handle the RAW mode */
-int dvo_image_load (FITS_DB *db, int VERBOSE) {
-
-  int Nx, Ny, Naxis;
-  int mode, status;
+/* determine db mode (raw/fits) and read the complete table */
+int dvo_image_load (FITS_DB *db, int VERBOSE, int FORCE_READ) {
+
+  int Naxis, Nrow, Nread, mode, status;
+  char buffer[241];
 
   /* database name must be set first */
-  if (db == NULL) {
-    fprintf (stderr, "db handle is not set\n");
+  if (db == NULL) return (FALSE);
+  if (db[0].f == NULL) return (FALSE);
+
+  fseek (db[0].f, 0, SEEK_SET);
+
+  /* test for NAXIS == 2 in line 3 */
+  bzero (buffer, 241);
+  Nread = fread (buffer, 1, 240, db[0].f);
+  if (Nread != 240) {
+    if (VERBOSE) fprintf (stderr, "can't determine image db mode\n");
     return (FALSE);
   }
+  Nread = sscanf (&buffer[160], "NAXIS   = %d", &Naxis);
+  if (Nread != 1) {
+    if (VERBOSE) fprintf (stderr, "can't determine image db mode\n");
+    return (FALSE);
+  }
+  fseek (db[0].f, 0, SEEK_SET);
+
+  mode = FITS;
+  if (Naxis == 2) mode = RAW;
+  if (VERBOSE) {
+    switch (mode) {
+      case FITS:
+	fprintf (stderr, "reading images (mode FITS)\n");
+	break;
+      case RAW:
+	fprintf (stderr, "reading images (mode RAW)\n");
+	break;
+      default:
+	fprintf (stderr, "error getting image mode\n");
+	exit (2);
+    }
+  }
+
+  /* read data in appropriate mode */
+  if (mode == FITS) {
+    status = fits_db_load (db);
+  } else {
+    status = dvo_image_load_raw (db, VERBOSE, FORCE_READ);
+  }
+  /* byteswap table data */
+  Nrow = db[0].theader.Naxis[1];
+  fits_convert_Image ((Image *) db[0].ftable.buffer, sizeof(Image), Nrow);
+  db[0].swapped = TRUE;
+
+  return (TRUE);
+}
+
+/* write the complete image table to disk in the requested mode */
+int dvo_image_save (FITS_DB *db, int VERBOSE) {
+
+  int Nrow, mode, status;
+
+  mode = FITS;
+  if (db[0].header.Naxes == 2) mode = RAW;
+  
+  /* byteswap table data */
+  Nrow = db[0].theader.Naxis[1];
+  if (db[0].swapped) {
+    fits_convert_Image ((Image *) db[0].ftable.buffer, sizeof(Image), Nrow);
+    db[0].swapped = FALSE;
+  }  
+  
+  /* write data in appropriate mode */
+  if (mode == FITS) {
+    status = fits_db_save (db);
+  } else {
+    status = dvo_image_save_raw (db, VERBOSE);
+  }
+  return (TRUE);
+}
+
+int dvo_image_addrows (FITS_DB *db, Image *new, int Nnew) {
+
+  int Nimages;
+
+  /* adjust header */
+  Nimages = 0;
+  fits_scan (&db[0].header, "NIMAGES", "%d", 1, &Nimages);
+  Nimages += Nnew;
+  fits_modify (&db[0].header, "NIMAGES", "%d", 1, Nimages);
+
+  fits_table_to_vtable (&db[0].ftable, &db[0].vtable, 0, 0);
+  fits_vadd_rows (&db[0].vtable, (char *) new, Nnew, sizeof(Image));
+
+  /* check that primary header and table header agree */
+  if (Nimages != db[0].theader.Naxis[1]) {
+    fprintf (stderr, "header / table length mismatch!\n");
+  }
+  return (TRUE);
+}  
+
+/* write the vtable data to disk in the requested mode */
+int dvo_image_update (FITS_DB *db, int VERBOSE) {
+
+  int i, mode, status;
+
+  mode = FITS;
+  if (db[0].header.Naxes == 2) mode = RAW;
+  
+  /* byteswap table data */
+  for (i = 0; i < db[0].vtable.Nrow; i++) {
+    fits_convert_Image ((Image *) db[0].vtable.buffer[i], sizeof(Image), 1);
+  }
+
+  /* write data in appropriate mode */
+  if (mode == FITS) {
+    status = fits_db_update (db);
+  } else {
+    status = dvo_image_update_raw (db, VERBOSE);
+  }
+  return (TRUE);
+}
+
+/* the old Image.dat files used a fake FITS header defining a finite data block
+ * this function reads in the data portion, assuming header already loaded
+ */
+
+int dvo_image_load_raw (FITS_DB *db, int VERBOSE, int FORCE_READ) {
+
+  int Nimage, size, nimage;
+  struct stat filestatus;
+  Image *image;
 
   /* init & load in FITS table data - return FALSE on error */
@@ -21,32 +141,4 @@
     return (FALSE);
   }
-
-  fits_scan (&db[0].header, "NAXIS",  "%d", 1, &Naxis);
-  fits_scan (&db[0].header, "NAXIS1", "%d", 1, &Nx);
-  fits_scan (&db[0].header, "NAXIS2", "%d", 1, &Ny);
-  
-  mode = FITS;
-  if ((Naxis == 2) && (Nx == 1106) && (Ny == 1024)) {
-    mode = TEXT;
-  }
-  
-  /* how do we decide if it is text or fits? must examine header */
-  if (mode == FITS) {
-    status = dvo_image_load_fits (db, VERBOSE);
-  } else {
-    status = dvo_image_load_rtext (db, VERBOSE);
-  }
-  return (TRUE);
-}
-
-/* the old Image.dat files used a fake FITS header defining a finite data block
- * this function reads in the data portion, assuming header already loaded
- */
-
-int dvo_image_load_text (FITS_DB *db, int VERBOSE) {
-
-  int Nimage, size, nimage;
-  struct stat filestatus;
-  Image *image;
 
   /* check that file size makes sense */
@@ -70,5 +162,5 @@
   /* create a dummy set of table information */
   /* (original table has NAXIS = 2, change to 0) */
-  fits_modify (&db[0].header, "NAXIS", "%d", 1, 0);
+  /* fits_modify (&db[0].header, "NAXIS", "%d", 1, 0); */
   fits_create_matrix (&db[0].header, &db[0].matrix);
   fits_table_mkheader_Image (&db[0].theader);
@@ -90,24 +182,63 @@
 }
 
-/* load the rest of the db table into memory (first extension only) */
-int rfits (FITS_DB *db, int VERBOSE) {
-
-  /* database name must be set first */
-  if (db == NULL) {
-    if (VERBOSE) fprintf (stderr, "db handle is not set\n");
-    return (FALSE);
-  }
-  if (!fits_fread_matrix (db[0].f, &db[0].matrix, &db[0].header)) {
-    if (VERBOSE) fprintf (stderr, "can't read primary matrix");
-    return (FALSE);
-  }
-  if (!fits_fread_header (db[0].f, &db[0].theader)) {
-    if (VERBOSE) fprintf (stderr, "can't read table header");
-    return (FALSE);
-  }
-  if (!fits_fread_ftable_data (db[0].f, &db[0].ftable)) {
-    if (VERBOSE) fprintf (stderr, "can't read table data");
-    return (FALSE);
-  }
-  return (TRUE);
-}
+/* write out image db elements from vtable */
+int dvo_image_update_raw (FITS_DB *db, int VERBOSE) {
+
+  int i, Nx, Ny, Nrow, Nbytes;
+  int status, start, offset;
+  int *row;
+
+  if (VERBOSE) fprintf (stderr, "writing out %d images\n", db[0].vtable.Nrow);
+
+  /* position to start of file */
+  Fseek (db[0].f, 0, SEEK_SET);
+  
+  /* write out complete header (no check on disk size?) */
+  status = fwrite (db[0].header.buffer, 1, db[0].header.size, db[0].f);
+  if (status != db[0].header.size) {
+    fprintf (stderr, "ERROR: failed writing data to image header\n");
+    exit (1);
+  }
+
+  /** this code is identical to fits_fwrite_vtable, except without padding */
+  Nrow = db[0].vtable.Nrow;
+  row = db[0].vtable.row;
+  fits_scan (db[0].vtable.header, "NAXIS1", "%d", 1, &Nx);
+  fits_scan (db[0].vtable.header, "NAXIS2", "%d", 1, &Ny);
+
+  /* file pointer is at beginning of desired table data */
+  start = ftell (db[0].f);
+  
+  for (i = 0; i < Nrow; i++) {
+    offset = start + Nx*row[i];
+    fseek (db[0].f, offset, SEEK_SET);
+    Nbytes = fwrite (db[0].vtable.buffer[i], sizeof (char), Nx, db[0].f);
+    if (Nbytes != Nx) { return (FALSE); }
+  }
+  return (TRUE);
+}
+
+/* write out complete image db table from ftable */
+int dvo_image_save_raw (FITS_DB *db, int VERBOSE) {
+
+  int status, Nx, Ny, size, Nbytes;
+
+  if (VERBOSE) fprintf (stderr, "writing out %d images\n", db[0].theader.Naxis[1]);
+
+  /* position to start of file */
+  Fseek (db[0].f, 0, SEEK_SET);
+  
+  /* write out complete header (no check on disk size?) */
+  status = fwrite (db[0].header.buffer, 1, db[0].header.size, db[0].f);
+  if (status != db[0].header.size) {
+    fprintf (stderr, "ERROR: failed writing data to image header\n");
+    exit (1);
+  }
+
+  fits_scan (db[0].ftable.header, "NAXIS1", "%d", 1, &Nx);
+  fits_scan (db[0].ftable.header, "NAXIS2", "%d", 1, &Ny);
+  size = Nx * Ny;
+  Nbytes = fwrite (db[0].ftable.buffer, sizeof(char), size, db[0].f);
+  if (Nbytes != size) return (FALSE);
+  return (TRUE);
+}
Index: /trunk/Ohana/src/libohana/src/fits_db.c
===================================================================
--- /trunk/Ohana/src/libohana/src/fits_db.c	(revision 4863)
+++ /trunk/Ohana/src/libohana/src/fits_db.c	(revision 4864)
@@ -5,9 +5,15 @@
 int fits_db_init (FITS_DB *db) {
 
+  db[0].f             = NULL;
   db[0].filename      = NULL;
   db[0].header.buffer = NULL;
   db[0].matrix.buffer = NULL;
+  db[0].theader.buffer = NULL;
   db[0].ftable.buffer = NULL;
   db[0].ftable.header = &db[0].theader;
+
+  db[0].vtable.header = NULL;
+  db[0].vtable.buffer = NULL;
+  db[0].vtable.row    = NULL;
   return (TRUE);
 }
@@ -79,4 +85,66 @@
     return (FALSE);
   }
+  db[0].swapped = FALSE;  /* is table in internal byte-order? */
+  return (TRUE);
+}
+
+/* load the data from Nrows from table starting at start; load header, etc if needed */
+int fits_db_load_segment (FITS_DB *db, int start, int Nrows) {
+
+  int Nskip;
+
+  /* database name must be set first */
+  if (db == NULL) {
+    fprintf (stderr, "db handle is not set\n");
+    return (FALSE);
+  }
+
+  /* database name must be opened */
+  if (db[0].f == NULL) {
+    fprintf (stderr, "db is not opened\n");
+    return (FALSE);
+  }
+
+  /* position to start of file */
+  Fseek (db[0].f, 0, SEEK_SET);
+
+  /* load or skip header */
+  if (db[0].header.buffer == NULL) {
+    if (!fits_fread_header (db[0].f, &db[0].header)) {
+      fprintf (stderr, "can't read primary header\n"); 
+      return (FALSE);
+    }
+  } else {
+    Nskip = db[0].header.size;
+    Fseek (db[0].f, Nskip, SEEK_CUR);
+  }
+
+  /* load or skip matrix */
+  if (db[0].matrix.buffer == NULL) {
+    if (!fits_fread_matrix (db[0].f, &db[0].matrix, &db[0].header)) {
+      fprintf (stderr, "can't read primary matrix");
+      return (FALSE);
+    }
+  } else {
+    Nskip = fits_matrix_size (&db[0].header);
+    Fseek (db[0].f, Nskip, SEEK_CUR);
+  }
+
+  /* load or skip table header */
+  if (db[0].theader.buffer == NULL) {
+    if (!fits_fread_header (db[0].f, &db[0].theader)) {
+      fprintf (stderr, "can't read table header");
+      return (FALSE);
+    }
+  } else {
+    Nskip = db[0].header.size;
+    Fseek (db[0].f, Nskip, SEEK_CUR);
+  }
+
+  /* read table segment into vtable */
+  if (!fits_fread_vtable_range (db[0].f, &db[0].vtable, start, Nrows)) {
+    fprintf (stderr, "can't read table data");
+    return (FALSE);
+  }
   return (TRUE);
 }
@@ -109,10 +177,10 @@
 
 /* write vtable to db file (also appends rows to the end of the table) */
-int fits_db_update (FITS_DB *db, VTable *vtable) {
+int fits_db_update (FITS_DB *db) {
 
   /* this section is not valid if we have changed the size of header, matrix, theader */
 
   /* write subset to file */
-  make_backup (db[0].filename);
+  make_backup (db[0].filename);  /*** drop this!!?? ***/
   Fseek (db[0].f, 0, SEEK_SET);
 
@@ -130,5 +198,5 @@
     return (FALSE);
   }
-  if (!fits_fwrite_vtable   (db[0].f, vtable))  {
+  if (!fits_fwrite_vtable   (db[0].f, &db[0].vtable))  {
     fprintf (stderr, "can't update table data");
     return (FALSE);
@@ -143,4 +211,5 @@
   fits_free_header (&db[0].theader);
   fits_free_table  (&db[0].ftable);
+  fits_free_vtable (&db[0].vtable);
   if (db[0].filename != NULL) {
     free (db[0].filename);
Index: /trunk/Ohana/src/libohana/src/phot_catalog_mef.c
===================================================================
--- /trunk/Ohana/src/libohana/src/phot_catalog_mef.c	(revision 4863)
+++ /trunk/Ohana/src/libohana/src/phot_catalog_mef.c	(revision 4864)
@@ -87,5 +87,5 @@
     }
     /* no conversions currently defined */
-    catalog[0].missing = fits_table_get_Missing (&ftable, &catalog[0].Nmissing);
+    catalog[0].missing = fits_table_get_Missing (&ftable, &catalog[0].Nmissing, NULL);
     if (Nmissing != catalog[0].Nmissing) {
       fprintf (stderr, "Warning: mismatch between Nmissing in PHU and Table headers (%d vs %d)\n", Nmissing, catalog[0].Nmissing);
@@ -108,5 +108,5 @@
     }
     /* no conversions currently defined */
-    catalog[0].secfilt = fits_table_get_SecFilt (&ftable, &Nitems);
+    catalog[0].secfilt = fits_table_get_SecFilt (&ftable, &Nitems, NULL);
     catalog[0].Nsecfilt = Nitems / catalog[0].Naverage;
     if (Nsecfilt != catalog[0].Nsecfilt) {
Index: /trunk/Ohana/src/markstar/src/find_images.c
===================================================================
--- /trunk/Ohana/src/markstar/src/find_images.c	(revision 4863)
+++ /trunk/Ohana/src/markstar/src/find_images.c	(revision 4864)
@@ -2,8 +2,5 @@
 double opening_angle ();
 
-Image *find_images (catstats, Nimages)
-CatStats catstats[];
-int *Nimages;
-{
+Image *find_images (FITS_DB *db, CatStats *catstats, int *Nimages) {
   
   Header header;
@@ -28,92 +25,61 @@
   }
 
-  /* check if image datafile exists, get header, number of images */
-  if (!fits_read_header (ImageCat, &header)) {
-    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
-    exit (0);
-  }
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-  if (Nimage == 0) {
-    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
-    exit (0);
-  }
-
-  /* get ready to read data on images */ 
-  f = fopen (ImageCat, "r");
-  if (f == (FILE *) NULL) {
-    fprintf (stderr, "ERROR: trouble opening Image catalog: %s (2)\n", ImageCat);
-    exit (0);
-  }
-  fseek (f, header.size, SEEK_SET); 
+  timage = fits_table_get_Image (&db[0].ftable, &Ntimage, &db[0].swapped);
 
   /* set up buffers for images, temporary storage */
-  NTIMAGE = 100;
-  ALLOCATE (timage, Image, NTIMAGE);
+  nimage = 0;
   NIMAGE = 100;
   ALLOCATE (image, Image, NIMAGE);
-  nimage = 0;
-  Nloop = Nimage / NTIMAGE + 1;
-  Nlast = Nimage % NTIMAGE;
-  
-  /* read in images in groups of NTIMAGE (100) */
-  for (n = 0; n < Nloop; n++) {
-    Nim = (n == Nloop - 1) ? Nlast : NTIMAGE;
-    status = Fread (timage, sizeof(Image), Nim, f, "image");
-    if (status != Nim) {
-      fprintf (stderr, "ERROR: couldn't read images from image catalog: %s\n", ImageCat);
-      exit (0);
-    }
-    /* test each image in block */
-    for (i = 0; i < Nim; i++) {
-      /* define image corners */
-      Xi[0] = 0;            Yi[0] = 0;
-      Xi[1] = timage[i].NX; Yi[1] = 0;
-      Xi[2] = timage[i].NX; Yi[2] = timage[i].NY;
-      Xi[3] = 0;            Yi[3] = timage[i].NY;
-      Xi[4] = 0;            Yi[4] = 0;
-      found = FALSE;
-      /* transform to tcoords */
-      if (catstats[0].DEC[1] > 86.25) { /* pole */
-	for (j = 0; j < 5; j++) {
-	  XY_to_RD (&r, &d, Xi[j], Yi[j], &timage[i].coords);
-	  if (d > catstats[0].DEC[0] - 0.5) found = TRUE;
-	}
-      } else {
-	for (j = 0; j < 6; j++) {
-	  XY_to_RD (&r, &d, Xi[j], Yi[j], &timage[i].coords);
-	  InRange = RD_to_XY (&Xi[j], &Yi[j], r, d, tcoords);
-	  if (!InRange) {
-	    /* if RD_to_XY returns false, the coords are ~180 away from
-	       the projection center */ 
-	    goto imskip;
-	  }
-	}
-	/* check if image corner inside catalog */
-	for (j = 0; (j < 4) && !found; j++) {
-	  found |= corner_check (&Xi[j], &Yi[j], &Xc[0], &Yc[0]);
-	}
-	/* check if catalog corner inside image */
-	for (j = 0; (j < 4) && !found; j++) {
-	  found |= corner_check (&Xc[j], &Yc[j], &Xi[0], &Yi[0]);
-	}
-	/* check if edges cross */
-	for (j = 0; (j < 4) && !found; j++) {
-	  for (k = 0; (k < 4) && !found; k++) {
-	    found |= edge_check (&Xi[j], &Yi[j], &Xc[k], &Yc[k]);
-	  }
+
+  /* test each image in block */
+  for (i = 0; i < Ntimage; i++) {
+    /* define image corners */
+    Xi[0] = 0;            Yi[0] = 0;
+    Xi[1] = timage[i].NX; Yi[1] = 0;
+    Xi[2] = timage[i].NX; Yi[2] = timage[i].NY;
+    Xi[3] = 0;            Yi[3] = timage[i].NY;
+    Xi[4] = 0;            Yi[4] = 0;
+    found = FALSE;
+    /* transform to tcoords */
+    if (catstats[0].DEC[1] > 86.25) { /* pole */
+      for (j = 0; j < 5; j++) {
+	XY_to_RD (&r, &d, Xi[j], Yi[j], &timage[i].coords);
+	if (d > catstats[0].DEC[0] - 0.5) found = TRUE;
+      }
+    } else {
+      for (j = 0; j < 6; j++) {
+	XY_to_RD (&r, &d, Xi[j], Yi[j], &timage[i].coords);
+	InRange = RD_to_XY (&Xi[j], &Yi[j], r, d, tcoords);
+	if (!InRange) {
+	  /* if RD_to_XY returns false, the coords are ~180 away from
+	     the projection center */ 
+	  goto imskip;
 	}
       }
-      if (found) {
-	image[nimage] = timage[i]; 
-	image[nimage].code = 0;
-	nimage ++;
-	if (nimage == NIMAGE) {
-	  NIMAGE += 100;
-	  REALLOCATE (image, Image, NIMAGE);
+      /* check if image corner inside catalog */
+      for (j = 0; (j < 4) && !found; j++) {
+	found |= corner_check (&Xi[j], &Yi[j], &Xc[0], &Yc[0]);
+      }
+      /* check if catalog corner inside image */
+      for (j = 0; (j < 4) && !found; j++) {
+	found |= corner_check (&Xc[j], &Yc[j], &Xi[0], &Yi[0]);
+      }
+      /* check if edges cross */
+      for (j = 0; (j < 4) && !found; j++) {
+	for (k = 0; (k < 4) && !found; k++) {
+	  found |= edge_check (&Xi[j], &Yi[j], &Xc[k], &Yc[k]);
 	}
       }
-    imskip:
     }
+    if (found) {
+      image[nimage] = timage[i]; 
+      image[nimage].code = 0;
+      nimage ++;
+      if (nimage == NIMAGE) {
+	NIMAGE += 100;
+	REALLOCATE (image, Image, NIMAGE);
+      }
+    }
+  imskip:
   }
       
@@ -128,7 +94,5 @@
 
   REALLOCATE (image, Image, MAX (nimage, 1));
-  free (timage);
   *Nimages = nimage;
-  fclose (f);
   return (image);
 }
Index: /trunk/Ohana/src/markstar/src/markstar.c
===================================================================
--- /trunk/Ohana/src/markstar/src/markstar.c	(revision 4863)
+++ /trunk/Ohana/src/markstar/src/markstar.c	(revision 4864)
@@ -1,8 +1,7 @@
 # include "markstar.h"
 
-main (argc, argv)
-int argc;
-char **argv;
-{
+/*** this needs to be cleaned to match current db I/O model ***/
+
+int main (int argc, char **argv) {
 
   FILE *f;
@@ -12,4 +11,5 @@
   CatStats catstats;
   struct timeval now, then;  
+  FITS_DB db;
   
   gettimeofday (&then, (void *) NULL);
@@ -36,7 +36,6 @@
   }
 
-  /* if lockfile exists, program will complain and quit */
-  check_lockfile (); 
-  check_permissions (argv[1]);
+  set_db (&db);
+  lock_image_db (&db, ImageCat);
 
   gcatalog (argv[1], &catalog);
Index: /trunk/Ohana/src/mosastro/src/rfits.c
===================================================================
--- /trunk/Ohana/src/mosastro/src/rfits.c	(revision 4863)
+++ /trunk/Ohana/src/mosastro/src/rfits.c	(revision 4864)
@@ -30,5 +30,5 @@
   }
 
-  stars = fits_table_get_SMPData (&table, &mychip[0].Nstars);
+  stars = fits_table_get_SMPData (&table, &mychip[0].Nstars, NULL);
   fits_scan (table.header, "NAXIS1", "%d", 1, &Nx);
 
Index: /trunk/Ohana/src/opihi/dvo/LoadImages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/LoadImages.c	(revision 4863)
+++ /trunk/Ohana/src/opihi/dvo/LoadImages.c	(revision 4864)
@@ -10,13 +10,23 @@
 
   fits_db_init (&db);
+  db.lockstate = LCK_SOFT;
+  db.timeout   = 120.0;
+
   if (!fits_db_lock (&db, filename)) {
-    fprintf (stderr, "No available image catalog %s (1)\n", filename);
+    fprintf (stderr, "error opening image catalog %s (1)\n", filename);
     return (NULL);
   }
 
-  dvo_image_load (&db, TRUE);
+  if (db.dbstate == LCK_EMPTY) {
+    fprintf (stderr, "note: image catalog is empty\n");
+    ALLOCATE (image, Image, 1);
+    *nimage = 1;
+    return (image);
+  }
+
+  dvo_image_load (&db, TRUE, FALSE);
   fits_db_close (&db);
 
-  image = fits_table_get_Image (&db.ftable, nimage);
+  image = fits_table_get_Image (&db.ftable, nimage, &db.swapped);
   return (image);
 }
Index: /trunk/Ohana/src/opihi/dvo/badimages.c
===================================================================
--- /trunk/Ohana/src/opihi/dvo/badimages.c	(revision 4863)
+++ /trunk/Ohana/src/opihi/dvo/badimages.c	(revision 4864)
@@ -8,14 +8,9 @@
 int badimages (int argc, char **argv) {
   
-  FILE *f;
-  int i, Nimage, nimage, entry, First, Cross;
+  int i, Nimage, entry, First, Cross;
   float *ptr;
   double nominal, big, small, value;
-  Header header;
   Image *image;
-  char ImageCat[256];
 
-  VarConfig ("IMAGE_CATALOG", "%s", ImageCat);
-  
   if (argc != 3) {
     fprintf (stderr, "USAGE: badimages entry value\n");
@@ -24,4 +19,6 @@
   }
   
+  image = LoadImages (&Nimage);
+
   Cross = FALSE;
   First = FALSE;
@@ -36,30 +33,4 @@
       Cross = TRUE;
     }
-  }
-  
-  /* check if image datafile exists, get header */
-  if (!fits_read_header (ImageCat, &header)) {
-    fprintf (stderr, "can't open image catalog %s\n", ImageCat);
-    return (FALSE);
-  }
-  
-  /* get ready to read data on images */ 
-  f = fopen (ImageCat, "r");
-  if (f == (FILE *) NULL) {
-    fprintf (stderr, "can't open image catalog %s\n", ImageCat);
-    return (FALSE);
-  }
-  fseek (f, header.size, SEEK_SET); 
-  
-  /* read in image data */
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-  ALLOCATE (image, Image, Nimage);
-  nimage = Fread (image, sizeof(Image), Nimage, f, "image");
-  fclose (f);
-  if (nimage != Nimage) {
-    fprintf (stderr, "error reading all data from image file (%d != %d)\n", nimage, Nimage);
-    free (image);
-    return (FALSE);
   }
   
@@ -101,3 +72,2 @@
 
 }
-  
Index: /trunk/Ohana/src/photdbc/Makefile
===================================================================
--- /trunk/Ohana/src/photdbc/Makefile	(revision 4863)
+++ /trunk/Ohana/src/photdbc/Makefile	(revision 4864)
@@ -20,23 +20,28 @@
 
 SRCLIST = \
-$(SRC)/photdbc.$(ARCH).o	 \
-$(SRC)/initialize.$(ARCH).o	 \
-$(SRC)/ConfigInit.$(ARCH).o	 \
-$(SRC)/args.$(ARCH).o		 \
-$(SRC)/liststats.$(ARCH).o	 \
-$(SRC)/load_images.$(ARCH).o	 \
-$(SRC)/name_region.$(ARCH).o	 \
-$(SRC)/find_images.$(ARCH).o	 \
-$(SRC)/find_regions.$(ARCH).o	 \
-$(SRC)/get_regions.$(ARCH).o	 \
-$(SRC)/load_catalogs.$(ARCH).o	 \
-$(SRC)/gcatalog.$(ARCH).o 	 \
-$(SRC)/misc.$(ARCH).o		 \
-$(SRC)/join_stars.$(ARCH).o      \
-$(SRC)/unique_measures.$(ARCH).o \
-$(SRC)/flag_measures.$(ARCH).o   \
-$(SRC)/get_mags.$(ARCH).o        \
-$(SRC)/check_directory.$(ARCH).o \
-$(SRC)/subcatalog.$(ARCH).o      \
+$(SRC)/photdbc.$(ARCH).o	   \
+$(SRC)/initialize.$(ARCH).o	   \
+$(SRC)/ConfigInit.$(ARCH).o	   \
+$(SRC)/args.$(ARCH).o		   \
+$(SRC)/liststats.$(ARCH).o	   \
+$(SRC)/load_images.$(ARCH).o	   \
+$(SRC)/name_region.$(ARCH).o	   \
+$(SRC)/find_images.$(ARCH).o	   \
+$(SRC)/find_regions.$(ARCH).o	   \
+$(SRC)/get_regions.$(ARCH).o	   \
+$(SRC)/load_catalogs.$(ARCH).o	   \
+$(SRC)/gcatalog.$(ARCH).o 	   \
+$(SRC)/misc.$(ARCH).o		   \
+$(SRC)/join_stars.$(ARCH).o        \
+$(SRC)/unique_measures.$(ARCH).o   \
+$(SRC)/flag_measures.$(ARCH).o     \
+$(SRC)/get_mags.$(ARCH).o          \
+$(SRC)/check_directory.$(ARCH).o   \
+$(SRC)/overlap_funcs.$(ARCH).o     \
+$(SRC)/image-db.$(ARCH).o          \
+$(SRC)/SetSignals.$(ARCH).o        \
+$(SRC)/Shutdown.$(ARCH).o          \
+$(SRC)/check_permissions.$(ARCH).o \
+$(SRC)/subcatalog.$(ARCH).o        \
 $(SRC)/wcatalog.$(ARCH).o
 
Index: /trunk/Ohana/src/photdbc/include/photdbc.h
===================================================================
--- /trunk/Ohana/src/photdbc/include/photdbc.h	(revision 4863)
+++ /trunk/Ohana/src/photdbc/include/photdbc.h	(revision 4864)
@@ -64,10 +64,9 @@
 # define FLAG_DUPMEAS         0x0040
 
-Image        *find_images (GSCRegion *region, int Nregion, int *Nimages, int **LineNum); 
+Image        *find_images (FITS_DB *db, GSCRegion *region, int Nregion, int *Nimage, int **LineNum);
 GSCRegion    *find_regions (Image *image, int Nimage, int *Nregions, GSCRegion *fullregion); 
-Image        *get_images (int *N); 
 GSCRegion    *get_regions (double minRa, double maxRa, double minDec, double maxDec, int *Nregions); 
 Catalog      *load_catalogs (GSCRegion *region, int Nregion); 
-GSCRegion    *load_images (char *seed, int *nregion); 
+GSCRegion    *load_images (FITS_DB *db, char *seed, int *nregion);
 GSCRegion    *name_region (char *name, int *Nregions); 
 void          ConfigInit (int *argc, char **argv); 
@@ -75,5 +74,5 @@
 int           corner_check (double *x1, double *y1, double *x2, double *y2); 
 int           edge_check (double *x1, double *y1, double *x2, double *y2); 
-void          flag_measures (Catalog *catalog); 
+void          flag_measures (FITS_DB *db, Catalog *catalog); 
 int           gcatalog (Catalog *catalog); 
 void          get_mags (Catalog *catalog); 
@@ -93,4 +92,13 @@
 void          unique_measures (Catalog *catalog);
 void          wcatalog (Catalog *catalog);
-Catalog *subcatalog (Catalog *catalog);
-void check_directory (char *basefile);
+Catalog      *subcatalog (Catalog *catalog);
+void          check_directory (char *basefile);
+
+int Shutdown (char *format, ...);
+void set_db (FITS_DB *in);
+void lock_image_db (FITS_DB *db, char *filename);
+void unlock_image_db (FITS_DB *db);
+void check_permissions (char *basefile);
+void TrapSignal (int sig);
+void SetProtect (int mode);
+int SetSignals ();
Index: /trunk/Ohana/src/photdbc/src/SetSignals.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/SetSignals.c	(revision 4864)
+++ /trunk/Ohana/src/photdbc/src/SetSignals.c	(revision 4864)
@@ -0,0 +1,118 @@
+# include "photdbc.h"
+
+static int Protect = FALSE;
+static int Trapped = FALSE;
+
+void TrapSignal (int sig) {
+    fprintf (stderr, "trapped signal %d\n", sig);
+    if (sig == 11) {
+      fprintf (stderr, "seg fault\n");
+      exit (1);
+    }
+    if (Protect) {
+      Trapped = TRUE;
+      fprintf (stderr, "blocking until protected sections are clear\n");
+      return;
+    }
+    Shutdown ("halted by signal (trapped)");
+}    
+
+void SetProtect (int mode) {
+  Protect = mode;
+  if (Trapped && !Protect) Shutdown ("halted by signal (protect)");
+}
+
+int SetSignals () {
+
+  int i;
+
+  /* disable almost all signal interrupts */
+  for (i = 0; i < 36; i++) {
+    switch (i) {
+      /* can't redirect this signals */
+    case SIGKILL:    /* kill -9: cannot be caught or ignored */
+    case SIGSTOP:    /* SIGSTOP: cannot be caught or ignored */
+      /* ignore these signals */
+    case SIGCHLD:    /* child halted: ignore */
+    case SIGPWR:     /* power failure - why ignore this? */
+    case SIGWINCH:   /* window resized */
+    case SIGCONT:    /* continue - maintain this action */
+    case SIGTSTP:    /* stop signal sent from tty - why ignore? */
+    case SIGURG:     /* socket signal, ignore this */
+      break;
+      
+    default:
+      signal (i, TrapSignal);
+    }
+  }
+  return (TRUE);
+}
+/*
+
+       Signal     Value     Action   Comment
+       -------------------------------------------------------------------------
+       SIGHUP        1        A      Hangup detected on controlling terminal
+                                     or death of controlling process
+       SIGINT        2        A      Interrupt from keyboard
+       SIGQUIT       3        A      Quit from keyboard
+       SIGILL        4        A      Illegal Instruction
+       SIGABRT       6        C      Abort signal from abort(3)
+       SIGFPE        8        C      Floating point exception
+       SIGKILL       9       AEF     Kill signal
+       SIGSEGV      11        C      Invalid memory reference
+       SIGPIPE      13        A      Broken pipe: write to pipe with no readers
+       SIGALRM      14        A      Timer signal from alarm(2)
+       SIGTERM      15        A      Termination signal
+       SIGUSR1   30,10,16     A      User-defined signal 1
+       SIGUSR2   31,12,17     A      User-defined signal 2
+       SIGCHLD   20,17,18     B      Child stopped or terminated
+       SIGCONT   19,18,25            Continue if stopped
+       SIGSTOP   17,19,23    DEF     Stop process
+       SIGTSTP   18,20,24     D      Stop typed at tty
+       SIGTTIN   21,21,26     D      tty input for background process
+       SIGTTOU   22,22,27     D      tty output for background process
+
+       Next various other signals.
+
+       Signal       Value     Action   Comment
+       ---------------------------------------------------------------------
+       SIGTRAP        5         CG     Trace/breakpoint trap
+       SIGIOT         6         CG     IOT trap. A synonym for SIGABRT
+       SIGEMT       7,-,7       G
+       SIGBUS      10,7,10      AG     Bus error
+       SIGSYS      12,-,12      G      Bad argument to routine (SVID)
+       SIGSTKFLT    -,16,-      AG     Stack fault on coprocessor
+       SIGURG      16,23,21     BG     Urgent condition on socket (4.2 BSD)
+       SIGIO       23,29,22     AG     I/O now possible (4.2 BSD)
+       SIGPOLL                  AG     A synonym for SIGIO (System V)
+       SIGCLD       -,-,18      G      A synonym for SIGCHLD
+       SIGXCPU     24,24,30     AG     CPU time limit exceeded (4.2 BSD)
+       SIGXFSZ     25,25,31     AG     File size limit exceeded (4.2 BSD)
+       SIGVTALRM   26,26,28     AG     Virtual alarm clock (4.2 BSD)
+       SIGPROF     27,27,29     AG     Profile alarm clock
+       SIGPWR      29,30,19     AG     Power failure (System V)
+       SIGINFO      29,-,-      G      A synonym for SIGPWR
+       SIGLOST      -,-,-       AG     File lock lost
+       SIGWINCH    28,28,20     BG     Window resize signal (4.3 BSD, Sun)
+       SIGUNUSED    -,31,-      AG     Unused signal
+       (Here - denotes that a signal is absent; there where three values are given, the first one is usually  valid  for  alpha  and
+       sparc,  the  middle  one  for i386 and ppc, the last one for mips. Signal 29 is SIGINFO / SIGPWR on an alpha but SIGLOST on a
+       sparc.)
+
+       The letters in the "Action" column have the following meanings:
+
+       A      Default action is to terminate the process.
+
+       B      Default action is to ignore the signal.
+
+       C      Default action is to dump core.
+
+       D      Default action is to stop the process.
+
+       E      Signal cannot be caught.
+
+       F      Signal cannot be ignored.
+
+       G      Not a POSIX.1 conformant signal.
+
+*/
Index: /trunk/Ohana/src/photdbc/src/Shutdown.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/Shutdown.c	(revision 4864)
+++ /trunk/Ohana/src/photdbc/src/Shutdown.c	(revision 4864)
@@ -0,0 +1,28 @@
+# include "photdbc.h"
+
+static FITS_DB *db;
+
+void set_db (FITS_DB *in) {
+  db = in;
+}
+
+/* clean up open / locked ImageCat before shutting down */
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format));
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
+  SetProtect (TRUE);
+  fits_db_close (db);
+  fprintf (stderr, "ERROR: addstar halted\n");
+  exit (1);
+}
+
Index: /trunk/Ohana/src/photdbc/src/check_permissions.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/check_permissions.c	(revision 4864)
+++ /trunk/Ohana/src/photdbc/src/check_permissions.c	(revision 4864)
@@ -0,0 +1,67 @@
+# include "photdbc.h"
+
+void check_permissions (char *basefile) {
+  
+  char *c, dir[256], filename[256];
+  struct stat filestat;
+  uid_t uid;
+  gid_t gid;
+  int status, cmode;
+
+  uid = getuid();
+  gid = getgid();
+
+  /* check permission to write to directory */
+  sprintf (filename, "%s", basefile);
+  c = strrchr (filename, '/');
+  if (c == (char *) NULL) {
+    strcpy (dir, ".");
+  } else {
+    *c = 0;
+    strcpy (dir, filename);
+  }
+  status = stat (dir, &filestat);
+  if (status == -1) {
+    fprintf (stderr, "directory %s does not exist, creating...\n", dir);
+    cmode = S_IRWXU | S_IRWXG | S_IRWXO;
+    status = mkdir (dir, cmode);
+    if (status == -1) {
+      fprintf (stderr, "ERROR: can't create %s\n", dir);
+      exit (1);
+    }
+  } 
+  status = stat (dir, &filestat);
+  if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRWXU)) ||
+      ((gid == filestat.st_gid) && (filestat.st_mode & S_IRWXG)) || 
+      (filestat.st_mode & S_IRWXO)) {
+  } else {
+    fprintf (stderr, "ERROR: can't write to %s\n", dir);
+    exit (1);
+  }
+  
+  /* check permission to write to file */
+  sprintf (filename, "%s", basefile);
+  status = stat (filename, &filestat);
+  if (status == 0) { /* file exists, are permissions OK? */
+    if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR) && (filestat.st_mode & S_IWUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IWGRP)) || 
+	((filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IWOTH))) {
+    } else {
+      fprintf (stderr, "ERROR: can't write to %s\n", filename);
+      exit (1);
+    }
+  }
+  
+  /* check permission to write to backup file */
+  sprintf (filename, "%s~", basefile);
+  status = stat (filename, &filestat);
+  if (status == 0) { /* file exists, are permissions OK? */
+    if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR) && (filestat.st_mode & S_IWUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IWGRP)) || 
+	((filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IWOTH))) {
+    } else {
+      fprintf (stderr, "ERROR: can't write to %s\n", filename);
+      exit (1);
+    }
+  }
+}
Index: /trunk/Ohana/src/photdbc/src/find_images.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/find_images.c	(revision 4863)
+++ /trunk/Ohana/src/photdbc/src/find_images.c	(revision 4864)
@@ -7,11 +7,9 @@
    images */
 
-Image *find_images (GSCRegion *region, int Nregion, int *Nimages, int **LineNum) {
+Image *find_images (FITS_DB *db, GSCRegion *region, int Nregion, int *Nimage, int **LineNum) {
   
-  Header header;
   Image *timage, *image;
-  int i, j, k, m, found, nimage, Nimage, NIMAGE;
-  int status, InRange;
-  FILE *f;
+  int i, j, k, m, found, nimage, Ntimage, NIMAGE;
+  int InRange;
   double Xc[5], Yc[5], Xi[5], Yi[5], r, d, dx, dy;
   int *line_number;
@@ -29,31 +27,5 @@
   strcpy (tcoords.ctype, "RA---TAN");
 
-  /* check if image datafile exists, get header, number of images */
-  if (!fits_read_header (ImageCat, &header)) {
-    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
-    exit (0);
-  }
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-  if (Nimage == 0) {
-    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
-    exit (0);
-  }
-
-  /* get ready to read data on images */ 
-  f = fopen (ImageCat, "r");
-  if (f == (FILE *) NULL) {
-    fprintf (stderr, "ERROR: trouble opening Image catalog: %s (2)\n", ImageCat);
-    exit (0);
-  }
-  fseek (f, header.size, SEEK_SET); 
-
-  /* load all images */
-  ALLOCATE (timage, Image, Nimage);
-  status = Fread (timage, sizeof(Image), Nimage, f, "image");
-  if (status != Nimage) {
-    fprintf (stderr, "ERROR: couldn't read images from image catalog: %s\n", ImageCat);
-    exit (0);
-  }
+  timage = fits_table_get_Image (&db[0].ftable, &Ntimage, &db[0].swapped);
 
   nimage = 0;
@@ -62,12 +34,10 @@
   ALLOCATE (line_number, int, NIMAGE);
   
-  for (i = 0; i < Nimage; i++) {
+  for (i = 0; i < Ntimage; i++) {
       
 # if (0)
     /* select images by photcode */
-    np = timage[i].source;
-    Np = photcodes.hashcode[np];
-    if (Np < 0) continue;
-    if (photcodes.code[Np].equiv != PHOTCODE) continue;
+    ecode = GetPhotcodeEquivCodebyCode (timage[i].source);
+    if (ecode != photcode[0].code) continue;
 
     /* select images by time */
@@ -77,5 +47,5 @@
     }
 # endif
-    
+
     /* define image corners */
     Xi[0] = 0;            Yi[0] = 0;
@@ -153,85 +123,7 @@
   REALLOCATE (image, Image, MAX (nimage + 1, 1));
   REALLOCATE (line_number, int, MAX (nimage + 1, 1));
-  free (timage);
-  *Nimages = nimage;
+  *Nimage = nimage;
   *LineNum = line_number;
-  fclose (f);
   return (image);
 }
 
-/* check if line between points 0 and 1 of x1
-   crosses line between points 0 and 1 of x2 */
-int edge_check (double *x1, double *y1, double *x2, double *y2) {
-
-  double theta1, theta2;
-  double Theta1, Theta2;
-
-  theta1 = opening_angle (x1[0], y1[0], x2[0], y2[0], x1[1], y1[1]); 
-  theta2 = opening_angle (x1[0], y1[0], x2[0], y2[0], x2[1], y2[1]); 
-
-  if (theta1*theta2 < 0.0) {
-    return (FALSE);
-  }
-
-  if (fabs(theta1) < fabs(theta2)) {
-    return (FALSE);
-  }
-
-  Theta1 = theta1;
-  Theta2 = theta2;
-  theta1 = opening_angle (x2[0], y2[0], x1[1], y1[1], x2[1], y2[1]); 
-  theta2 = opening_angle (x2[0], y2[0], x1[1], y1[1], x1[0], y1[0]); 
-  
- 
-  if (theta1*theta2 < 0.0) {
-    return (FALSE);
-  }
-
-  if (fabs(theta1) < fabs(theta2)) {
-    return (FALSE);
-  }
-
-  return (TRUE);
-
-}
-
-/* check if point x1,y1 is in box formed by x2[0-4] */
-int corner_check (double *x1, double *y1, double *x2, double *y2) {
-
-  int i;
-  double theta;
-
-  theta = 0;
-
-  for (i = 0; i < 4; i++) {
-    theta += opening_angle (x2[i], y2[i], x1[0], y1[0], x2[i+1], y2[i+1]); 
-  }
-  if (fabs(theta) > 6) {
-    return (TRUE);
-  } else {
-    return (FALSE);
-  }
-}
-
-/* returns the opening angle between the three points (2 is in middle) 
-   in range -pi to pi */
-
-double opening_angle (double x1, double y1, double x2, double y2, double x3, double y3) {
-
-  double dx1, dy1, dx2, dy2, ct, st, theta;
-
-  dx1 = x1 - x2;
-  dy1 = y1 - y2;
-  
-  dx2 = x3 - x2;
-  dy2 = y3 - y2;
-  
-  ct = (dx1*dx2 + dy1*dy2);
-  st = (dx1*dy2 - dx2*dy1);
-
-  theta = atan2 (st, ct);
-
-  return (theta);
-
-}
-
Index: /trunk/Ohana/src/photdbc/src/flag_measures.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/flag_measures.c	(revision 4863)
+++ /trunk/Ohana/src/photdbc/src/flag_measures.c	(revision 4864)
@@ -1,5 +1,5 @@
 # include "photdbc.h"
 
-void flag_measures (Catalog *catalog) {
+void flag_measures (FITS_DB *db, Catalog *catalog) {
 
   int i, j, k, m, n, N, found;
@@ -15,6 +15,5 @@
   if (VERBOSE) fprintf (stderr, "flagging bad measurements\n");
 
-  /* load images */
-  image = get_images (&Nimage);
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
 
   PhotNsec = GetPhotcodeNsecfilt ();
Index: /trunk/Ohana/src/photdbc/src/image-db.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/image-db.c	(revision 4864)
+++ /trunk/Ohana/src/photdbc/src/image-db.c	(revision 4864)
@@ -0,0 +1,27 @@
+# include "photdbc.h"
+
+void lock_image_db (FITS_DB *db, char *filename) {
+
+  /* lock the image catalog */
+  check_permissions (filename);
+
+  db[0].lockstate = LCK_XCLD;
+  db[0].timeout   = 3600.0;
+  fits_db_init (db);
+
+  if (!fits_db_lock (db, filename)) {
+    fprintf (stderr, "ERROR: can't lock image catalog\n");
+    exit (1);
+  }
+}
+
+void unlock_image_db (FITS_DB *db) {
+
+  mode_t mode;
+
+  fits_db_close (db);
+
+  /* force permissions to 666 */
+  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+  chmod (db[0].filename, mode);
+}
Index: /trunk/Ohana/src/photdbc/src/load_images.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/load_images.c	(revision 4863)
+++ /trunk/Ohana/src/photdbc/src/load_images.c	(revision 4864)
@@ -1,63 +1,25 @@
 # include "photdbc.h"
 
-static int   Nimage;
-static int   *Line;
-static Image *image;
+GSCRegion *load_images (FITS_DB *db, char *seed, int *nregion) {
 
-GSCRegion *load_images (char *seed, int *nregion) {
-
+  int        Nregion;
   GSCRegion *region;
-  int       Nregion;
+  int        Nimage;
+  int       *Line;
+  Image     *image;
 
   region = name_region (seed, &Nregion);
 
+  if (db[0].dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db[0].filename);
+
+  /* read entire db table */
+  if (!dvo_image_load (db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db[0].filename);
+
   /* find images which supplied all measurements */
-  image = find_images (region, Nregion, &Nimage, &Line);
+  image = find_images (db, region, Nregion, &Nimage, &Line);
   *nregion = Nregion;
   
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, Line, Nimage);
+
   return (region);
 }
-
-Image *get_images (int *N) {
-  
-  *N = Nimage;
-  return (image);
-}
-
-/*
-void wimages () {
-  
-  int i, status, mode;
-  FILE *f;
-  Header header;
-
-  setMcalFinal (image, Nimage);
-
-  if (!fits_read_header (ImageCat, &header)) {
-    fprintf (stderr, "ERROR: can't find %s\n", ImageCat);
-    exit (0);
-  }
-  
-  f = fopen (ImageCat, "r+");
-  if (f == NULL) {
-    fprintf (stderr, "ERROR: can't open image catalog file to append: %s\n", ImageCat);
-    exit (0);
-  }
-  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-  chmod (ImageCat, mode);
-
-  if (VERBOSE) fprintf (stderr, "writing out %d images\n", Nimage);
-  for (i = 0; i < Nimage; i++) {
-    if (image[i].code == ID_IMAGE_NOCAL) image[i].code &= ~ID_IMAGE_NOCAL; 
-    
-    fseek (f, header.size + Line[i]*sizeof(Image), SEEK_SET);
-    status = Fwrite (&image[i], sizeof(Image), 1, f, "image");
-    if (status != 1) {
-      fprintf (stderr, "ERROR: failure writing image data to catalog %s\n", ImageCat);
-      exit (0);
-    }
-  }
-
-  fclose (f);
-}
-*/
Index: /trunk/Ohana/src/photdbc/src/overlap_funcs.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/overlap_funcs.c	(revision 4864)
+++ /trunk/Ohana/src/photdbc/src/overlap_funcs.c	(revision 4864)
@@ -0,0 +1,78 @@
+# include "photdbc.h"
+
+/* check if line between points 0 and 1 of x1
+   crosses line between points 0 and 1 of x2 */
+int edge_check (double *x1, double *y1, double *x2, double *y2) {
+
+  double theta1, theta2;
+  double Theta1, Theta2;
+
+  theta1 = opening_angle (x1[0], y1[0], x2[0], y2[0], x1[1], y1[1]); 
+  theta2 = opening_angle (x1[0], y1[0], x2[0], y2[0], x2[1], y2[1]); 
+
+  if (theta1*theta2 < 0.0) {
+    return (FALSE);
+  }
+
+  if (fabs(theta1) < fabs(theta2)) {
+    return (FALSE);
+  }
+
+  Theta1 = theta1;
+  Theta2 = theta2;
+  theta1 = opening_angle (x2[0], y2[0], x1[1], y1[1], x2[1], y2[1]); 
+  theta2 = opening_angle (x2[0], y2[0], x1[1], y1[1], x1[0], y1[0]); 
+  
+ 
+  if (theta1*theta2 < 0.0) {
+    return (FALSE);
+  }
+
+  if (fabs(theta1) < fabs(theta2)) {
+    return (FALSE);
+  }
+
+  return (TRUE);
+
+}
+
+/* check if point x1,y1 is in box formed by x2[0-4] */
+int corner_check (double *x1, double *y1, double *x2, double *y2) {
+
+  int i;
+  double theta;
+
+  theta = 0;
+
+  for (i = 0; i < 4; i++) {
+    theta += opening_angle (x2[i], y2[i], x1[0], y1[0], x2[i+1], y2[i+1]); 
+  }
+  if (fabs(theta) > 6) {
+    return (TRUE);
+  } else {
+    return (FALSE);
+  }
+}
+
+/* returns the opening angle between the three points (2 is in middle) 
+   in range -pi to pi */
+
+double opening_angle (double x1, double y1, double x2, double y2, double x3, double y3) {
+
+  double dx1, dy1, dx2, dy2, ct, st, theta;
+
+  dx1 = x1 - x2;
+  dy1 = y1 - y2;
+  
+  dx2 = x3 - x2;
+  dy2 = y3 - y2;
+  
+  ct = (dx1*dx2 + dy1*dy2);
+  st = (dx1*dy2 - dx2*dy1);
+
+  theta = atan2 (st, ct);
+
+  return (theta);
+
+}
+
Index: /trunk/Ohana/src/photdbc/src/photdbc.c
===================================================================
--- /trunk/Ohana/src/photdbc/src/photdbc.c	(revision 4863)
+++ /trunk/Ohana/src/photdbc/src/photdbc.c	(revision 4864)
@@ -7,10 +7,14 @@
   Catalog *catalog;
   GSCRegion *region;
+  FITS_DB db;
 
   /* get configuration info, args, lockfile */
   initialize (argc, argv);
 
+  set_db (&db);
+  lock_image_db (&db, ImageCat);
+
   /* load region and images overlapping region */
-  region = load_images (argv[1], &Nregion);
+  region = load_images (&db, argv[1], &Nregion);
 
   /* load catalog data corresponding to region file */
@@ -25,5 +29,5 @@
   unique_measures (catalog);
 
-  flag_measures (catalog);
+  flag_measures (&db, catalog);
 
   get_mags (catalog);
Index: /trunk/Ohana/src/relphot/Makefile
===================================================================
--- /trunk/Ohana/src/relphot/Makefile	(revision 4863)
+++ /trunk/Ohana/src/relphot/Makefile	(revision 4864)
@@ -42,8 +42,12 @@
 $(SRC)/misc.$(ARCH).o		 \
 $(SRC)/reload_catalogs.$(ARCH).o \
+$(SRC)/image-db.$(ARCH).o \
 $(SRC)/free_catalogs.$(ARCH).o   \
+$(SRC)/check_permissions.$(ARCH).o   \
 $(SRC)/setMrelFinal.$(ARCH).o 	 \
 $(SRC)/write_coords.$(ARCH).o 	 \
 $(SRC)/setExclusions.$(ARCH).o 	 \
+$(SRC)/Shutdown.$(ARCH).o 	 \
+$(SRC)/SetSignals.$(ARCH).o 	 \
 $(SRC)/wcatalog.$(ARCH).o
 
Index: /trunk/Ohana/src/relphot/include/relphot.h
===================================================================
--- /trunk/Ohana/src/relphot/include/relphot.h	(revision 4863)
+++ /trunk/Ohana/src/relphot/include/relphot.h	(revision 4864)
@@ -1,4 +1,5 @@
 # include <ohana.h>
 # include <dvo.h>
+# include <signal.h>
 
 /* # define GRID_V1 */
@@ -118,5 +119,11 @@
 void          findImages          PROTO((Catalog *catalog, int Ncatalog));
 int           findMosaics         PROTO((Catalog *catalog, int Ncatalog));
-Image        *find_images         PROTO((GSCRegion *region, int Nregion, int *Nimages, int **LineNum));
+Image        *find_images         PROTO((FITS_DB *db, GSCRegion *region, int Nregion, int *Nimage, int **LineNum));
+void set_db (FITS_DB *in);
+int Shutdown (char *format, ...);
+void TrapSignal (int sig);
+void SetProtect (int mode);
+int SetSignals ();
+
 GSCRegion    *find_regions        PROTO((Image *image, int Nimage, int *Nregions, GSCRegion *fullregion));
 void          freeGridBins        PROTO((int Ncatalog));
@@ -147,5 +154,11 @@
 int           liststats           PROTO((double *value, double *dvalue, int N, StatType *stats));
 Catalog      *load_catalogs       PROTO((GSCRegion *region, int Nregion, GSCRegion *fullregion));
-GSCRegion    *load_images         PROTO((char *seed, int *nregion, GSCRegion *fullregion));
+GSCRegion    *load_images         PROTO((FITS_DB *db, char *seed, int *nregion, GSCRegion *fullregion));
+
+void check_permissions (char *basefile);
+void lock_image_db (FITS_DB *db, char *filename);
+void unlock_image_db (FITS_DB *db);
+void create_image_db (FITS_DB *db);
+
 int           main                PROTO((int argc, char **argv));
 void          mark_images         PROTO((Image *image, int Nimage, Image *timage, int Ntimage));
@@ -167,5 +180,5 @@
 int           setExclusions       PROTO((Catalog *catalog, int Ncatalog));
 void          setMcal             PROTO((Catalog *catalog, int Poor));
-void          setMcalFinal        PROTO((Image *image, int Nimage));
+void          setMcalFinal        PROTO(());
 int           setMcalOutput       PROTO((Catalog *catalog, int Ncatalog));
 void          setMgrid            PROTO((Catalog *catalog));
Index: /trunk/Ohana/src/relphot/src/MosaicOps.c
===================================================================
--- /trunk/Ohana/src/relphot/src/MosaicOps.c	(revision 4863)
+++ /trunk/Ohana/src/relphot/src/MosaicOps.c	(revision 4864)
@@ -167,9 +167,12 @@
 }
 
-void setMcalFinal (Image *image, int Nimage) {
-
-  int i, j, im;
+void setMcalFinal () {
+
+  int i, j, im, Nimage;
+  Image *image;
 
   if (!MOSAICNAME[0]) return;
+
+  image = getimages (&Nimage);
 
   for (i = 0; i < Nmosaic; i++) {
Index: /trunk/Ohana/src/relphot/src/SetSignals.c
===================================================================
--- /trunk/Ohana/src/relphot/src/SetSignals.c	(revision 4864)
+++ /trunk/Ohana/src/relphot/src/SetSignals.c	(revision 4864)
@@ -0,0 +1,118 @@
+# include "relphot.h"
+
+static int Protect = FALSE;
+static int Trapped = FALSE;
+
+void TrapSignal (int sig) {
+    fprintf (stderr, "trapped signal %d\n", sig);
+    if (sig == 11) {
+      fprintf (stderr, "seg fault\n");
+      exit (1);
+    }
+    if (Protect) {
+      Trapped = TRUE;
+      fprintf (stderr, "blocking until protected sections are clear\n");
+      return;
+    }
+    Shutdown ("halted by signal (trapped)");
+}    
+
+void SetProtect (int mode) {
+  Protect = mode;
+  if (Trapped && !Protect) Shutdown ("halted by signal (protect)");
+}
+
+int SetSignals () {
+
+  int i;
+
+  /* disable almost all signal interrupts */
+  for (i = 0; i < 36; i++) {
+    switch (i) {
+      /* can't redirect this signals */
+    case SIGKILL:    /* kill -9: cannot be caught or ignored */
+    case SIGSTOP:    /* SIGSTOP: cannot be caught or ignored */
+      /* ignore these signals */
+    case SIGCHLD:    /* child halted: ignore */
+    case SIGPWR:     /* power failure - why ignore this? */
+    case SIGWINCH:   /* window resized */
+    case SIGCONT:    /* continue - maintain this action */
+    case SIGTSTP:    /* stop signal sent from tty - why ignore? */
+    case SIGURG:     /* socket signal, ignore this */
+      break;
+      
+    default:
+      signal (i, TrapSignal);
+    }
+  }
+  return (TRUE);
+}
+/*
+
+       Signal     Value     Action   Comment
+       -------------------------------------------------------------------------
+       SIGHUP        1        A      Hangup detected on controlling terminal
+                                     or death of controlling process
+       SIGINT        2        A      Interrupt from keyboard
+       SIGQUIT       3        A      Quit from keyboard
+       SIGILL        4        A      Illegal Instruction
+       SIGABRT       6        C      Abort signal from abort(3)
+       SIGFPE        8        C      Floating point exception
+       SIGKILL       9       AEF     Kill signal
+       SIGSEGV      11        C      Invalid memory reference
+       SIGPIPE      13        A      Broken pipe: write to pipe with no readers
+       SIGALRM      14        A      Timer signal from alarm(2)
+       SIGTERM      15        A      Termination signal
+       SIGUSR1   30,10,16     A      User-defined signal 1
+       SIGUSR2   31,12,17     A      User-defined signal 2
+       SIGCHLD   20,17,18     B      Child stopped or terminated
+       SIGCONT   19,18,25            Continue if stopped
+       SIGSTOP   17,19,23    DEF     Stop process
+       SIGTSTP   18,20,24     D      Stop typed at tty
+       SIGTTIN   21,21,26     D      tty input for background process
+       SIGTTOU   22,22,27     D      tty output for background process
+
+       Next various other signals.
+
+       Signal       Value     Action   Comment
+       ---------------------------------------------------------------------
+       SIGTRAP        5         CG     Trace/breakpoint trap
+       SIGIOT         6         CG     IOT trap. A synonym for SIGABRT
+       SIGEMT       7,-,7       G
+       SIGBUS      10,7,10      AG     Bus error
+       SIGSYS      12,-,12      G      Bad argument to routine (SVID)
+       SIGSTKFLT    -,16,-      AG     Stack fault on coprocessor
+       SIGURG      16,23,21     BG     Urgent condition on socket (4.2 BSD)
+       SIGIO       23,29,22     AG     I/O now possible (4.2 BSD)
+       SIGPOLL                  AG     A synonym for SIGIO (System V)
+       SIGCLD       -,-,18      G      A synonym for SIGCHLD
+       SIGXCPU     24,24,30     AG     CPU time limit exceeded (4.2 BSD)
+       SIGXFSZ     25,25,31     AG     File size limit exceeded (4.2 BSD)
+       SIGVTALRM   26,26,28     AG     Virtual alarm clock (4.2 BSD)
+       SIGPROF     27,27,29     AG     Profile alarm clock
+       SIGPWR      29,30,19     AG     Power failure (System V)
+       SIGINFO      29,-,-      G      A synonym for SIGPWR
+       SIGLOST      -,-,-       AG     File lock lost
+       SIGWINCH    28,28,20     BG     Window resize signal (4.3 BSD, Sun)
+       SIGUNUSED    -,31,-      AG     Unused signal
+       (Here - denotes that a signal is absent; there where three values are given, the first one is usually  valid  for  alpha  and
+       sparc,  the  middle  one  for i386 and ppc, the last one for mips. Signal 29 is SIGINFO / SIGPWR on an alpha but SIGLOST on a
+       sparc.)
+
+       The letters in the "Action" column have the following meanings:
+
+       A      Default action is to terminate the process.
+
+       B      Default action is to ignore the signal.
+
+       C      Default action is to dump core.
+
+       D      Default action is to stop the process.
+
+       E      Signal cannot be caught.
+
+       F      Signal cannot be ignored.
+
+       G      Not a POSIX.1 conformant signal.
+
+*/
Index: /trunk/Ohana/src/relphot/src/Shutdown.c
===================================================================
--- /trunk/Ohana/src/relphot/src/Shutdown.c	(revision 4864)
+++ /trunk/Ohana/src/relphot/src/Shutdown.c	(revision 4864)
@@ -0,0 +1,28 @@
+# include "relphot.h"
+
+static FITS_DB *db;
+
+void set_db (FITS_DB *in) {
+  db = in;
+}
+
+/* clean up open / locked ImageCat before shutting down */
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format));
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
+  SetProtect (TRUE);
+  fits_db_close (db);
+  fprintf (stderr, "ERROR: addstar halted\n");
+  exit (1);
+}
+
Index: /trunk/Ohana/src/relphot/src/check_permissions.c
===================================================================
--- /trunk/Ohana/src/relphot/src/check_permissions.c	(revision 4864)
+++ /trunk/Ohana/src/relphot/src/check_permissions.c	(revision 4864)
@@ -0,0 +1,67 @@
+# include "relphot.h"
+
+void check_permissions (char *basefile) {
+  
+  char *c, dir[256], filename[256];
+  struct stat filestat;
+  uid_t uid;
+  gid_t gid;
+  int status, cmode;
+
+  uid = getuid();
+  gid = getgid();
+
+  /* check permission to write to directory */
+  sprintf (filename, "%s", basefile);
+  c = strrchr (filename, '/');
+  if (c == (char *) NULL) {
+    strcpy (dir, ".");
+  } else {
+    *c = 0;
+    strcpy (dir, filename);
+  }
+  status = stat (dir, &filestat);
+  if (status == -1) {
+    fprintf (stderr, "directory %s does not exist, creating...\n", dir);
+    cmode = S_IRWXU | S_IRWXG | S_IRWXO;
+    status = mkdir (dir, cmode);
+    if (status == -1) {
+      fprintf (stderr, "ERROR: can't create %s\n", dir);
+      exit (1);
+    }
+  } 
+  status = stat (dir, &filestat);
+  if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRWXU)) ||
+      ((gid == filestat.st_gid) && (filestat.st_mode & S_IRWXG)) || 
+      (filestat.st_mode & S_IRWXO)) {
+  } else {
+    fprintf (stderr, "ERROR: can't write to %s\n", dir);
+    exit (1);
+  }
+  
+  /* check permission to write to file */
+  sprintf (filename, "%s", basefile);
+  status = stat (filename, &filestat);
+  if (status == 0) { /* file exists, are permissions OK? */
+    if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR) && (filestat.st_mode & S_IWUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IWGRP)) || 
+	((filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IWOTH))) {
+    } else {
+      fprintf (stderr, "ERROR: can't write to %s\n", filename);
+      exit (1);
+    }
+  }
+  
+  /* check permission to write to backup file */
+  sprintf (filename, "%s~", basefile);
+  status = stat (filename, &filestat);
+  if (status == 0) { /* file exists, are permissions OK? */
+    if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR) && (filestat.st_mode & S_IWUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IWGRP)) || 
+	((filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IWOTH))) {
+    } else {
+      fprintf (stderr, "ERROR: can't write to %s\n", filename);
+      exit (1);
+    }
+  }
+}
Index: /trunk/Ohana/src/relphot/src/find_images.c
===================================================================
--- /trunk/Ohana/src/relphot/src/find_images.c	(revision 4863)
+++ /trunk/Ohana/src/relphot/src/find_images.c	(revision 4864)
@@ -7,11 +7,9 @@
    images */
 
-Image *find_images (GSCRegion *region, int Nregion, int *Nimages, int **LineNum) {
-  
-  Header header;
+Image *find_images (FITS_DB *db, GSCRegion *region, int Nregion, int *Nimage, int **LineNum) {
+  
   Image *timage, *image;
-  int i, j, k, m, found, nimage, Nimage, NIMAGE;
-  int status, InRange, ecode;
-  FILE *f;
+  int i, j, k, m, found, nimage, Ntimage, NIMAGE;
+  int InRange, ecode;
   double Xc[5], Yc[5], Xi[5], Yi[5], r, d, dx, dy;
   int *line_number;
@@ -29,31 +27,5 @@
   strcpy (tcoords.ctype, "RA---TAN");
 
-  /* check if image datafile exists, get header, number of images */
-  if (!fits_read_header (ImageCat, &header)) {
-    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
-    exit (0);
-  }
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-  if (Nimage == 0) {
-    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
-    exit (0);
-  }
-
-  /* get ready to read data on images */ 
-  f = fopen (ImageCat, "r");
-  if (f == (FILE *) NULL) {
-    fprintf (stderr, "ERROR: trouble opening Image catalog: %s (2)\n", ImageCat);
-    exit (0);
-  }
-  fseek (f, header.size, SEEK_SET); 
-
-  /* load all images */
-  ALLOCATE (timage, Image, Nimage);
-  status = Fread (timage, sizeof(Image), Nimage, f, "image");
-  if (status != Nimage) {
-    fprintf (stderr, "ERROR: couldn't read images from image catalog: %s\n", ImageCat);
-    exit (0);
-  }
+  timage = fits_table_get_Image (&db[0].ftable, &Ntimage, &db[0].swapped);
 
   nimage = 0;
@@ -62,5 +34,5 @@
   ALLOCATE (line_number, int, NIMAGE);
   
-  for (i = 0; i < Nimage; i++) {
+  for (i = 0; i < Ntimage; i++) {
       
     /* select images by photcode */
@@ -153,8 +125,6 @@
   REALLOCATE (line_number, int, MAX (nimage, 1));
 
-  free (timage);
-  *Nimages = nimage;
+  *Nimage  = nimage;
   *LineNum = line_number;
-  fclose (f);
   return (image);
 }
Index: /trunk/Ohana/src/relphot/src/image-db.c
===================================================================
--- /trunk/Ohana/src/relphot/src/image-db.c	(revision 4864)
+++ /trunk/Ohana/src/relphot/src/image-db.c	(revision 4864)
@@ -0,0 +1,27 @@
+# include "relphot.h"
+
+void lock_image_db (FITS_DB *db, char *filename) {
+
+  /* lock the image catalog */
+  check_permissions (filename);
+
+  db[0].lockstate = LCK_XCLD;
+  db[0].timeout   = 3600.0;
+  fits_db_init (db);
+
+  if (!fits_db_lock (db, filename)) {
+    fprintf (stderr, "ERROR: can't lock image catalog\n");
+    exit (1);
+  }
+}
+
+void unlock_image_db (FITS_DB *db) {
+
+  mode_t mode;
+
+  fits_db_close (db);
+
+  /* force permissions to 666 */
+  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+  chmod (db[0].filename, mode);
+}
Index: /trunk/Ohana/src/relphot/src/load_images.c
===================================================================
--- /trunk/Ohana/src/relphot/src/load_images.c	(revision 4863)
+++ /trunk/Ohana/src/relphot/src/load_images.c	(revision 4864)
@@ -1,27 +1,32 @@
 # include "relphot.h"
 
-static int   Nimage;
-static int   *Line;
-static Image *image;
-
-GSCRegion *load_images (char *seed, int *nregion, GSCRegion *fullregion) {
+GSCRegion *load_images (FITS_DB *db, char *seed, int *nregion, GSCRegion *fullregion) {
 
   GSCRegion *region;
-  int       Nregion, Ntimage;
-  Image     *timage;
+  int        Nregion;
+  Image     *image;
+  int       *Line;
+  int        Nimage;
+
+  if (db[0].dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db[0].filename);
+
+  /* read entire db table */
+  if (!dvo_image_load (db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db[0].filename);
 
   region = name_region (seed, &Nregion);
 
   /* find images which supplied all measurements */
-  timage = find_images (region, Nregion, &Ntimage, &Line);
+  image = find_images (db, region, Nregion, &Nimage, &Line);
   free (Line);
 
   /* find all region files which touch images */
-  region = find_regions (timage, Ntimage, &Nregion, fullregion);
-  free (timage);
+  region = find_regions (image, Nimage, &Nregion, fullregion);
+  free (image);
 
   /* find images which supplied all measurements for all regions */
-  image = find_images (region, Nregion, &Nimage, &Line);
+  image = find_images (db, region, Nregion, &Nimage, &Line);
   getfullregion (image, Nimage, fullregion);
+
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, Line, Nimage);
 
   initImages (image, Nimage);
@@ -30,38 +35,3 @@
   *nregion = Nregion;
   return (region);
-
 }
-
-void wimages () {
-  
-  int i, status, mode;
-  FILE *f;
-  Header header;
-
-  setMcalFinal (image, Nimage);
-
-  if (!fits_read_header (ImageCat, &header)) {
-    fprintf (stderr, "ERROR: can't find %s\n", ImageCat);
-    exit (0);
-  }
-  
-  f = fopen (ImageCat, "r+");
-  if (f == NULL) {
-    fprintf (stderr, "ERROR: can't open image catalog file to append: %s\n", ImageCat);
-    exit (0);
-  }
-  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-  chmod (ImageCat, mode);
-
-  if (VERBOSE) fprintf (stderr, "writing out %d images\n", Nimage);
-  for (i = 0; i < Nimage; i++) {
-    fseek (f, header.size + Line[i]*sizeof(Image), SEEK_SET);
-    status = Fwrite (&image[i], sizeof(Image), 1, f, "image");
-    if (status != 1) {
-      fprintf (stderr, "ERROR: failure writing image data to catalog %s\n", ImageCat);
-      exit (0);
-    }
-  }
-
-  fclose (f);
-}
Index: /trunk/Ohana/src/relphot/src/relphot.c
===================================================================
--- /trunk/Ohana/src/relphot/src/relphot.c	(revision 4863)
+++ /trunk/Ohana/src/relphot/src/relphot.c	(revision 4864)
@@ -7,10 +7,14 @@
   Catalog *catalog;
   GSCRegion fullregion, *region;
+  FITS_DB db;
 
   /* get configuration info, args */
   initialize (argc, argv);
 
+  set_db (&db);
+  lock_image_db (&db, ImageCat);
+
   /* load regions and images based on seed region */
-  region = load_images (argv[1], &Ncatalog, &fullregion);
+  region = load_images (&db, argv[1], &Ncatalog, &fullregion);
 
   /* load catalog data from region files */
@@ -79,5 +83,8 @@
   /* load catalog data from region files, update Mrel include all data */
   reload_catalogs (region, Ncatalog, &fullregion);
-  wimages (); 
+  setMcalFinal ();
+  dvo_image_update (&db, VERBOSE);
+  unlock_image_db (&db); 
+
   exit (0);
 }
Index: /trunk/Ohana/src/relphot/src/wimages.c
===================================================================
--- /trunk/Ohana/src/relphot/src/wimages.c	(revision 4864)
+++ /trunk/Ohana/src/relphot/src/wimages.c	(revision 4864)
@@ -0,0 +1,45 @@
+# include "relphot.h"
+
+/* add 1 image to image db */
+void wimages (FITS_DB *db, Image *image, int Nimage) {
+  
+  int status, Nimages;
+
+  /* set permissions somewhere ...
+  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+  fchmod (ImageCat, mode); */
+
+  /* adjust header */
+  Nimages = 0;
+  fits_scan (&db[0].header, "NIMAGES", "%d", 1, &Nimages);
+  Nimages ++;
+  fits_modify (&db[0].header, "NIMAGES", "%d", 1, Nimages);
+
+  fits_table_to_vtable (&db[0].ftable, &db[0].vtable, 0, 0);
+  for (i = 0; i < Nimage; i++) {
+    fits_vadd_rows (&db[0].vtable, (char *) image, 1, sizeof(Image));
+  }
+
+  /* check that primary header and table header agree */
+  if (Nimages != db[0].header.Naxis[1]) {
+    fprintf (stderr, "header / table length mismatch!\n");
+  }
+
+  SetProtect (TRUE);
+  status = dvo_image_update (db, VERBOSE);
+  SetProtect (FALSE);
+
+  if (!status) {
+    fprintf (stderr, "ERROR: failed writing data to image catalog\n");
+    exit (1);
+  }
+}
+
+/* add the new image to the image table:
+   - use the table header (from ftable)
+   - create an empty vtable
+   - add the new image to the end of the vtable
+   
+   - write out the vtable, either as TEXT or FITS
+   * dvo_image_update performs the needed byte-swap on the image data
+*/
Index: /trunk/Ohana/src/uniphot/Makefile
===================================================================
--- /trunk/Ohana/src/uniphot/Makefile	(revision 4863)
+++ /trunk/Ohana/src/uniphot/Makefile	(revision 4864)
@@ -26,4 +26,5 @@
 $(SRC)/liststats.$(ARCH).o	 \
 $(SRC)/load_images.$(ARCH).o	 \
+$(SRC)/subset_images.$(ARCH).o	 \
 $(SRC)/find_image_tgroups.$(ARCH).o	 \
 $(SRC)/find_image_sgroups.$(ARCH).o	 \
@@ -34,4 +35,8 @@
 $(SRC)/wimages.$(ARCH).o		 \
 $(SRC)/gcatalog.$(ARCH).o		 \
+$(SRC)/check_permissions.$(ARCH).o		 \
+$(SRC)/image-db.$(ARCH).o		 \
+$(SRC)/SetSignals.$(ARCH).o		 \
+$(SRC)/Shutdown.$(ARCH).o		 \
 $(SRC)/misc.$(ARCH).o
 
Index: /trunk/Ohana/src/uniphot/include/uniphot.h
===================================================================
--- /trunk/Ohana/src/uniphot/include/uniphot.h	(revision 4863)
+++ /trunk/Ohana/src/uniphot/include/uniphot.h	(revision 4864)
@@ -1,4 +1,5 @@
 # include <ohana.h>
 # include <dvo.h>
+# include <signal.h>
 
 # ifdef ANSI
@@ -75,6 +76,6 @@
 int           args               PROTO((int argc, char **argv));
 void          dumpresult         PROTO(());
-Group        *find_image_sgroups PROTO((Image *image, ImageLink *imlink, int Nimage, int *Nsgroup));
-Group        *find_image_tgroups PROTO((Image *image, ImageLink *imlink, int Nimage, int *Ntgroup));
+Group        *find_image_sgroups PROTO((FITS_DB *db, ImageLink *imlink, int *Nsgroup));
+Group        *find_image_tgroups PROTO((FITS_DB *db, ImageLink *imlink, int *Ntgroup));
 void          fit_sgroup         PROTO((Group *sgroup, int Nsgroup));
 void          fit_tgroup         PROTO((Group *tgroup, int Ntgroup));
@@ -83,5 +84,5 @@
 void          initstats          PROTO((char *mode));
 int           liststats          PROTO((double *value, double *dvalue, int N, StatType *stats));
-Image        *load_images        PROTO((int *nimage));
+int           load_images        PROTO((FITS_DB *db));
 int           main               PROTO((int argc, char **argv));
 int           open_graph         PROTO((int N));
@@ -89,6 +90,16 @@
 void          sortB              PROTO((double *X, double *Y, int N));
 void          sortD              PROTO((double *X, double *Y, double *Z, int N));
-void          update             PROTO((Image *image, int Nimage, Group *sgroup, int Nsgroup));
 void          update_catalog     PROTO((Catalog *catalog, Group *sgroup, int warn));
 void          wcatalog           PROTO((Catalog *catalog));
 void          wimages            PROTO((Image *image, int Nimage));
+void check_permissions (char *basefile);
+void lock_image_db (FITS_DB *db, char *filename);
+void unlock_image_db (FITS_DB *db);
+void create_image_db (FITS_DB *db);
+void set_db (FITS_DB *in);
+int Shutdown (char *format, ...);
+void TrapSignal (int sig);
+void SetProtect (int mode);
+int SetSignals ();
+int subset_images (FITS_DB *db);
+void update (FITS_DB *db, Group *sgroup, int Nsgroup);
Index: /trunk/Ohana/src/uniphot/src/SetSignals.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/SetSignals.c	(revision 4864)
+++ /trunk/Ohana/src/uniphot/src/SetSignals.c	(revision 4864)
@@ -0,0 +1,118 @@
+# include "uniphot.h"
+
+static int Protect = FALSE;
+static int Trapped = FALSE;
+
+void TrapSignal (int sig) {
+    fprintf (stderr, "trapped signal %d\n", sig);
+    if (sig == 11) {
+      fprintf (stderr, "seg fault\n");
+      exit (1);
+    }
+    if (Protect) {
+      Trapped = TRUE;
+      fprintf (stderr, "blocking until protected sections are clear\n");
+      return;
+    }
+    Shutdown ("halted by signal (trapped)");
+}    
+
+void SetProtect (int mode) {
+  Protect = mode;
+  if (Trapped && !Protect) Shutdown ("halted by signal (protect)");
+}
+
+int SetSignals () {
+
+  int i;
+
+  /* disable almost all signal interrupts */
+  for (i = 0; i < 36; i++) {
+    switch (i) {
+      /* can't redirect this signals */
+    case SIGKILL:    /* kill -9: cannot be caught or ignored */
+    case SIGSTOP:    /* SIGSTOP: cannot be caught or ignored */
+      /* ignore these signals */
+    case SIGCHLD:    /* child halted: ignore */
+    case SIGPWR:     /* power failure - why ignore this? */
+    case SIGWINCH:   /* window resized */
+    case SIGCONT:    /* continue - maintain this action */
+    case SIGTSTP:    /* stop signal sent from tty - why ignore? */
+    case SIGURG:     /* socket signal, ignore this */
+      break;
+      
+    default:
+      signal (i, TrapSignal);
+    }
+  }
+  return (TRUE);
+}
+/*
+
+       Signal     Value     Action   Comment
+       -------------------------------------------------------------------------
+       SIGHUP        1        A      Hangup detected on controlling terminal
+                                     or death of controlling process
+       SIGINT        2        A      Interrupt from keyboard
+       SIGQUIT       3        A      Quit from keyboard
+       SIGILL        4        A      Illegal Instruction
+       SIGABRT       6        C      Abort signal from abort(3)
+       SIGFPE        8        C      Floating point exception
+       SIGKILL       9       AEF     Kill signal
+       SIGSEGV      11        C      Invalid memory reference
+       SIGPIPE      13        A      Broken pipe: write to pipe with no readers
+       SIGALRM      14        A      Timer signal from alarm(2)
+       SIGTERM      15        A      Termination signal
+       SIGUSR1   30,10,16     A      User-defined signal 1
+       SIGUSR2   31,12,17     A      User-defined signal 2
+       SIGCHLD   20,17,18     B      Child stopped or terminated
+       SIGCONT   19,18,25            Continue if stopped
+       SIGSTOP   17,19,23    DEF     Stop process
+       SIGTSTP   18,20,24     D      Stop typed at tty
+       SIGTTIN   21,21,26     D      tty input for background process
+       SIGTTOU   22,22,27     D      tty output for background process
+
+       Next various other signals.
+
+       Signal       Value     Action   Comment
+       ---------------------------------------------------------------------
+       SIGTRAP        5         CG     Trace/breakpoint trap
+       SIGIOT         6         CG     IOT trap. A synonym for SIGABRT
+       SIGEMT       7,-,7       G
+       SIGBUS      10,7,10      AG     Bus error
+       SIGSYS      12,-,12      G      Bad argument to routine (SVID)
+       SIGSTKFLT    -,16,-      AG     Stack fault on coprocessor
+       SIGURG      16,23,21     BG     Urgent condition on socket (4.2 BSD)
+       SIGIO       23,29,22     AG     I/O now possible (4.2 BSD)
+       SIGPOLL                  AG     A synonym for SIGIO (System V)
+       SIGCLD       -,-,18      G      A synonym for SIGCHLD
+       SIGXCPU     24,24,30     AG     CPU time limit exceeded (4.2 BSD)
+       SIGXFSZ     25,25,31     AG     File size limit exceeded (4.2 BSD)
+       SIGVTALRM   26,26,28     AG     Virtual alarm clock (4.2 BSD)
+       SIGPROF     27,27,29     AG     Profile alarm clock
+       SIGPWR      29,30,19     AG     Power failure (System V)
+       SIGINFO      29,-,-      G      A synonym for SIGPWR
+       SIGLOST      -,-,-       AG     File lock lost
+       SIGWINCH    28,28,20     BG     Window resize signal (4.3 BSD, Sun)
+       SIGUNUSED    -,31,-      AG     Unused signal
+       (Here - denotes that a signal is absent; there where three values are given, the first one is usually  valid  for  alpha  and
+       sparc,  the  middle  one  for i386 and ppc, the last one for mips. Signal 29 is SIGINFO / SIGPWR on an alpha but SIGLOST on a
+       sparc.)
+
+       The letters in the "Action" column have the following meanings:
+
+       A      Default action is to terminate the process.
+
+       B      Default action is to ignore the signal.
+
+       C      Default action is to dump core.
+
+       D      Default action is to stop the process.
+
+       E      Signal cannot be caught.
+
+       F      Signal cannot be ignored.
+
+       G      Not a POSIX.1 conformant signal.
+
+*/
Index: /trunk/Ohana/src/uniphot/src/Shutdown.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/Shutdown.c	(revision 4864)
+++ /trunk/Ohana/src/uniphot/src/Shutdown.c	(revision 4864)
@@ -0,0 +1,28 @@
+# include "uniphot.h"
+
+static FITS_DB *db;
+
+void set_db (FITS_DB *in) {
+  db = in;
+}
+
+/* clean up open / locked ImageCat before shutting down */
+int Shutdown (char *format, ...) {  
+  va_list argp;
+  char *formatplus;
+  
+  ALLOCATE (formatplus, char, strlen(format));
+  strcpy (formatplus, format);
+  strcat (formatplus, "\n");
+
+  va_start (argp, format);
+  vfprintf (stderr, formatplus, argp);
+  free (formatplus);
+  va_end (argp);
+
+  SetProtect (TRUE);
+  fits_db_close (db);
+  fprintf (stderr, "ERROR: addstar halted\n");
+  exit (1);
+}
+
Index: /trunk/Ohana/src/uniphot/src/check_permissions.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/check_permissions.c	(revision 4864)
+++ /trunk/Ohana/src/uniphot/src/check_permissions.c	(revision 4864)
@@ -0,0 +1,67 @@
+# include "uniphot.h"
+
+void check_permissions (char *basefile) {
+  
+  char *c, dir[256], filename[256];
+  struct stat filestat;
+  uid_t uid;
+  gid_t gid;
+  int status, cmode;
+
+  uid = getuid();
+  gid = getgid();
+
+  /* check permission to write to directory */
+  sprintf (filename, "%s", basefile);
+  c = strrchr (filename, '/');
+  if (c == (char *) NULL) {
+    strcpy (dir, ".");
+  } else {
+    *c = 0;
+    strcpy (dir, filename);
+  }
+  status = stat (dir, &filestat);
+  if (status == -1) {
+    fprintf (stderr, "directory %s does not exist, creating...\n", dir);
+    cmode = S_IRWXU | S_IRWXG | S_IRWXO;
+    status = mkdir (dir, cmode);
+    if (status == -1) {
+      fprintf (stderr, "ERROR: can't create %s\n", dir);
+      exit (1);
+    }
+  } 
+  status = stat (dir, &filestat);
+  if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRWXU)) ||
+      ((gid == filestat.st_gid) && (filestat.st_mode & S_IRWXG)) || 
+      (filestat.st_mode & S_IRWXO)) {
+  } else {
+    fprintf (stderr, "ERROR: can't write to %s\n", dir);
+    exit (1);
+  }
+  
+  /* check permission to write to file */
+  sprintf (filename, "%s", basefile);
+  status = stat (filename, &filestat);
+  if (status == 0) { /* file exists, are permissions OK? */
+    if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR) && (filestat.st_mode & S_IWUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IWGRP)) || 
+	((filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IWOTH))) {
+    } else {
+      fprintf (stderr, "ERROR: can't write to %s\n", filename);
+      exit (1);
+    }
+  }
+  
+  /* check permission to write to backup file */
+  sprintf (filename, "%s~", basefile);
+  status = stat (filename, &filestat);
+  if (status == 0) { /* file exists, are permissions OK? */
+    if (((uid == filestat.st_uid) && (filestat.st_mode & S_IRUSR) && (filestat.st_mode & S_IWUSR)) ||
+	((gid == filestat.st_gid) && (filestat.st_mode & S_IRGRP) && (filestat.st_mode & S_IWGRP)) || 
+	((filestat.st_mode & S_IROTH) && (filestat.st_mode & S_IWOTH))) {
+    } else {
+      fprintf (stderr, "ERROR: can't write to %s\n", filename);
+      exit (1);
+    }
+  }
+}
Index: /trunk/Ohana/src/uniphot/src/find_image_sgroups.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/find_image_sgroups.c	(revision 4863)
+++ /trunk/Ohana/src/uniphot/src/find_image_sgroups.c	(revision 4864)
@@ -1,11 +1,14 @@
 # include "uniphot.h"
 
-Group *find_image_sgroups (Image *image, ImageLink *imlink, int Nimage, int *Nsgroup) {
+Group *find_image_sgroups (FITS_DB *db, ImageLink *imlink, int *Nsgroup) {
 
-  int i, j, Ngroup, Nentry, NENTRY;
+  int i, j, Nimage, Ngroup, Nentry, NENTRY;
   double r, d, x, y, radius;
   Group *group;
   Coords coords;
-  
+  Image *image;
+
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+
   coords.crpix1 = coords.crpix2 = 0.0;
   coords.cdelt1 = coords.cdelt2 = 1.0; /* scale is degrees, radius in degrees */
Index: /trunk/Ohana/src/uniphot/src/find_image_tgroups.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/find_image_tgroups.c	(revision 4863)
+++ /trunk/Ohana/src/uniphot/src/find_image_tgroups.c	(revision 4864)
@@ -1,10 +1,13 @@
 # include "uniphot.h"
 
-Group *find_image_tgroups (Image *image, ImageLink *imlink, int Nimage, int *Ntgroup) {
+Group *find_image_tgroups (FITS_DB *db, ImageLink *imlink, int *Ntgroup) {
 
   char *start, *stop;
-  int i, j, Ngroup, NGROUP, Nentry, NENTRY;
+  int i, j, Nimage, Ngroup, NGROUP, Nentry, NENTRY;
   unsigned int *time, *tmin, *tmax;
   Group *group;
+  Image *image;
+
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
 
   /* sort time list (use only valid images?) */
Index: /trunk/Ohana/src/uniphot/src/image-db.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/image-db.c	(revision 4864)
+++ /trunk/Ohana/src/uniphot/src/image-db.c	(revision 4864)
@@ -0,0 +1,27 @@
+# include "uniphot.h"
+
+void lock_image_db (FITS_DB *db, char *filename) {
+
+  /* lock the image catalog */
+  check_permissions (filename);
+
+  db[0].lockstate = LCK_XCLD;
+  db[0].timeout   = 3600.0;
+  fits_db_init (db);
+
+  if (!fits_db_lock (db, filename)) {
+    fprintf (stderr, "ERROR: can't lock image catalog\n");
+    exit (1);
+  }
+}
+
+void unlock_image_db (FITS_DB *db) {
+
+  mode_t mode;
+
+  fits_db_close (db);
+
+  /* force permissions to 666 */
+  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+  chmod (db[0].filename, mode);
+}
Index: /trunk/Ohana/src/uniphot/src/load_images.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/load_images.c	(revision 4863)
+++ /trunk/Ohana/src/uniphot/src/load_images.c	(revision 4864)
@@ -1,60 +1,13 @@
 # include "uniphot.h"
 
-Image *load_images (int *nimage) {
-
-  int    i, Nimage, status, equiv;
-  FILE  *f;
-  Image *image;
-  Header header;
+int load_images (FITS_DB *db) {
 
   if (VERBOSE) fprintf (stderr, "finding images\n");
 
-  /* open image datafile */
-  if ((f = fopen (ImageCat, "r")) == (FILE *) NULL) {
-    fprintf (stderr, "ERROR: can't open image table %s\n", ImageCat);
-    exit (1);
-  }
+  if (db[0].dbstate == LCK_EMPTY) Shutdown ("ERROR: No images in catalog %s (1)", db[0].filename);
 
-  /* read header */
-  if (!fits_fread_header (f, &header)) {
-    fprintf (stderr, "ERROR: can't read image table header %s\n", ImageCat);
-    exit (1);
-  }
+  /* read entire db table */
+  if (!dvo_image_load (db, VERBOSE, FALSE)) Shutdown ("can't read image catalog %s", db[0].filename);
 
-  /* read number of images */
-  Nimage = 0;
-  fits_scan (&header, "NIMAGES", "%d", 1, &Nimage);
-  if (Nimage == 0) {
-    fprintf (stderr, "ERROR: No images in catalog %s (1)\n", ImageCat);
-    exit (1);
-  }
-
-  /* load all images */
-  ALLOCATE (image, Image, Nimage);
-  status = Fread (image, sizeof(Image), Nimage, f, "image");
-  if (status != Nimage) {
-    fprintf (stderr, "ERROR: couldn't read all images from image catalog: %s\n", ImageCat);
-    exit (1);
-  }
-  fclose (f);
-
-  /* mark images to be calibrated */
-  for (i = 0; i < Nimage; i++) {
-      
-    image[i].code |= ID_IMAGE_NOCAL;
-
-    /* select images by photcode */
-    equiv = GetPhotcodeEquivCodebyCode (image[i].source);
-    if (equiv != photcode[0].code) continue;
-
-    /* select images by time */
-    if (TimeSelect) {
-      if (image[i].tzero < TSTART) continue;
-      if (image[i].tzero > TSTOP) continue;
-    }
-
-    image[i].code &= ~ID_IMAGE_NOCAL;
-  }
-  *nimage = Nimage;
-  return (image);
+  return (TRUE);
 }
Index: /trunk/Ohana/src/uniphot/src/subset_images.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/subset_images.c	(revision 4864)
+++ /trunk/Ohana/src/uniphot/src/subset_images.c	(revision 4864)
@@ -0,0 +1,36 @@
+# include "uniphot.h"
+
+int subset_images (FITS_DB *db) {
+
+  int    i, Nimage, equiv;
+  int    Nkeep, *keep;
+  Image *image;
+
+  /* use a vtable to keep the images to be calibrated */
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
+
+  Nkeep = 0;
+  ALLOCATE (keep, int, Nimage);
+
+  /* mark images to be calibrated */
+  for (i = 0; i < Nimage; i++) {
+      
+    image[i].code |= ID_IMAGE_NOCAL;
+
+    /* select images by photcode */
+    equiv = GetPhotcodeEquivCodebyCode (image[i].source);
+    if (equiv != photcode[0].code) continue;
+
+    /* select images by time */
+    if (TimeSelect) {
+      if (image[i].tzero < TSTART) continue;
+      if (image[i].tzero > TSTOP) continue;
+    }
+    image[i].code &= ~ID_IMAGE_NOCAL;
+    keep[Nkeep] = i;
+    Nkeep ++;
+  }
+
+  fits_vtable_from_ftable (&db[0].ftable, &db[0].vtable, keep, Nkeep);
+  return (TRUE);
+}
Index: /trunk/Ohana/src/uniphot/src/uniphot.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/uniphot.c	(revision 4863)
+++ /trunk/Ohana/src/uniphot/src/uniphot.c	(revision 4864)
@@ -5,21 +5,22 @@
   int i, Nimage, Ntgroup, Nsgroup;
   Group *tgroup, *sgroup;
-  Image *image;
   ImageLink *imlinks;
-
-  /* add a mode to check / force consistency between image.Mcal and
-     measure.Mcal use the method in delstar to match image with measure
-     (gregions (image), etc) 
-  */
+  FITS_DB db;
 
   /* get configuration info, args, lockfile */
   initialize (argc, argv);
 
-  /* load images filtered by selection */
-  image = load_images (&Nimage);
+  set_db (&db);
+  lock_image_db (&db, ImageCat);
+
+  /* load images */
+  load_images (&db);
+  
+  /* filter image list by selection */
+  subset_images (&db);
+
   ALLOCATE (imlinks, ImageLink, Nimage);
-
-  tgroup = find_image_tgroups (image, imlinks, Nimage, &Ntgroup);
-  sgroup = find_image_sgroups (image, imlinks, Nimage, &Nsgroup);
+  tgroup = find_image_tgroups (&db, imlinks, &Ntgroup);
+  sgroup = find_image_sgroups (&db, imlinks, &Nsgroup);
 
   /* determine fit values */
@@ -49,6 +50,13 @@
   if (!UPDATE) exit (0);
 
-  update (image, Nimage, sgroup, Nsgroup);
+  update (&db, sgroup, Nsgroup);
+  unlock_image_db (&db); 
+
   exit (0);
 }
 
+/* add a mode to check / force consistency between image.Mcal and
+   measure.Mcal.
+
+   use the method in delstar to match image with measure (gregions (image), etc)
+*/
Index: /trunk/Ohana/src/uniphot/src/update.c
===================================================================
--- /trunk/Ohana/src/uniphot/src/update.c	(revision 4863)
+++ /trunk/Ohana/src/uniphot/src/update.c	(revision 4864)
@@ -2,12 +2,15 @@
 # include <glob.h>
 
-void update (Image *image, int Nimage, Group *sgroup, int Nsgroup) {
+void update (FITS_DB *db, Group *sgroup, int Nsgroup) {
 
-  int i, j, status, Nmin;
+  int i, j, status, Nmin, Nimage;
   char line[256];
   glob_t pglob;
   double Rmin, Rmax, Dmin, Dmax, x, y, radius;
+  Image *image;
   Catalog catalog;
   Coords coords;
+
+  image = fits_table_get_Image (&db[0].ftable, &Nimage, &db[0].swapped);
 
   /* clear the NOCAL flags */
@@ -15,5 +18,4 @@
     image[i].code &= ~ID_IMAGE_NOCAL;
   }
-
 
   /* apply calculated space-group offset to image Mcal values */
@@ -25,5 +27,5 @@
 
   /** write image table **/
-  wimages (image, Nimage);
+  dvo_image_update (db, VERBOSE);
 
   /** update catalog tables **/
