Export better list of errors.
[u/mdw/catacomb] / key-io.c
index 7ab32f3..7ed0c2c 100644 (file)
--- a/key-io.c
+++ b/key-io.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: key-io.c,v 1.1 1999/12/22 15:47:48 mdw Exp $
+ * $Id$
  *
  * Adding new keys to a key file
  *
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: key-io.c,v $
- * Revision 1.1  1999/12/22 15:47:48  mdw
- * Major key-management revision.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include <ctype.h>
@@ -44,7 +36,6 @@
 #include <string.h>
 #include <time.h>
 
-#include <mLib/alloc.h>
 #include <mLib/bits.h>
 #include <mLib/crc32.h>
 #include <mLib/dstr.h>
@@ -58,7 +49,7 @@
 
 /*----- Tweakable macros --------------------------------------------------*/
 
-#define KEY_LOAD(n) ((n) * 2)
+#define KEY_INITSZ 16
 
 /*----- Low-level functions -----------------------------------------------*/
 
@@ -118,7 +109,7 @@ static int insert(key_file *f, key *k)
   if (f->idload > 0)
     f->idload--;
   else if (hash_extend(&f->byid))
-    f->idload = KEY_LOAD(f->byid.mask / 2);
+    f->idload = SYM_LIMIT(f->byid.mask / 2);
 
   /* --- Insert into the type table --- */
 
@@ -286,7 +277,7 @@ int key_merge(key_file *f, const char *file, FILE *fp,
        if (err == KERR_DUPTAG) {
          if (rep)
            rep(file, line, "duplicate key tag stripped", arg);
-         free(k->tag);
+         xfree(k->tag);
          k->tag = 0;
          goto again;
        }
@@ -319,8 +310,8 @@ int key_merge(key_file *f, const char *file, FILE *fp,
 
   skip_3:
     if (k->tag)
-      free(k->tag);
-    free(k->type);
+      xfree(k->tag);
+    xfree(k->type);
   skip_2:
     key_destroy(&k->k);
   skip_1:
@@ -415,7 +406,7 @@ int key_extract(key_file *f, key *k, FILE *fp, const key_filter *kf)
  *
  * Arguments:  @key_file *f@ = pointer to file structure to initialize
  *             @const char *file@ = pointer to the file name
- *             @int how@ = opening options (@KOPEN_*@).
+ *             @unsigned how@ = opening options (@KOPEN_*@).
  *             @key_reporter *rep@ = error reporting function
  *             @void *arg@ = argument for function
  *
@@ -429,33 +420,27 @@ int key_extract(key_file *f, key *k, FILE *fp, const key_filter *kf)
  *             owner only.
  */
 
-int key_open(key_file *f, const char *file, int how,
+int key_open(key_file *f, const char *file, unsigned how,
             key_reporter *rep, void *arg)
 {
-  if (key_lockfile(f, file, how))
+  if (key_lockfile(f, file, how)) {
+    rep(file, 0, strerror(errno), arg);
     return (-1);
-
-  /* --- Trivial bits of initialization --- */
-
+  }
   f->f = 0;
   f->name = xstrdup(file);
 
-  /* --- Read the file of keys into the table --- */
-
-  hash_create(&f->byid, 16);
-  f->idload = KEY_LOAD(16);
+  hash_create(&f->byid, KEY_INITSZ);
+  f->idload = SYM_LIMIT(KEY_INITSZ);
   sym_create(&f->bytype);
   sym_create(&f->bytag);
   f->f |= KF_WRITE;
-  key_merge(f, file, f->fp, rep, arg);
-  if (how == KOPEN_READ)
-    f->f &= ~(KF_WRITE | KF_MODIFIED);
-  else
-    f->f &= ~KF_MODIFIED;
-
-  /* --- Close the file if only needed for reading --- */
+  if (f->fp)
+    key_merge(f, file, f->fp, rep, arg);
+  f->f &= ~KF_MODIFIED;
 
-  if (how == KOPEN_READ) {
+  if ((how & KOPEN_MASK) == KOPEN_READ) {
+    f->f &= ~KF_WRITE;
     fclose(f->fp);
     f->fp = 0;
   }
@@ -463,25 +448,20 @@ int key_open(key_file *f, const char *file, int how,
   return (0);
 }
 
-/* --- @key_close@ --- *
+/* --- @key_discard@ --- *
  *
  * Arguments:  @key_file *f@ = pointer to key file block
  *
- * Returns:    A @KWRITE_@ code indicating how it went.
+ * Returns:    ---
  *
- * Use:                Frees all the key data, writes any changes.  Make sure that
- *             all hell breaks loose if this returns @KWRITE_BROKEN@.
+ * Use:                Frees all the key data, without writing changes.
  */
 
-int key_close(key_file *f)
+void key_discard(key_file *f)
 {
-  int e;
   hash_base *b;
   hash_iter i;
 
-  if ((e = key_save(f)) != KWRITE_OK)
-    return (e);
-
   /* --- Free all the individual keys --- */
 
   for (hash_mkiter(&i, &f->byid); (b = hash_next(&i)) != 0; ) {
@@ -490,12 +470,12 @@ int key_close(key_file *f)
     key *k = (key *)b;
 
     key_destroy(&k->k);
-    free(k->type);
-    free(k->tag);
+    xfree(k->type);
+    xfree(k->tag);
     if (k->c)
-      free(k->c);
+      xfree(k->c);
     for (sym_mkiter(&j, &k->a); (a = sym_next(&j)) != 0; )
-      free(a->p);
+      xfree(a->p);
     sym_destroy(&k->a);
     DESTROY(k);
   }
@@ -505,7 +485,26 @@ int key_close(key_file *f)
 
   if (f->fp)
     fclose(f->fp);
-  free(f->name);
+  xfree(f->name);
+}
+
+/* --- @key_close@ --- *
+ *
+ * Arguments:  @key_file *f@ = pointer to key file block
+ *
+ * Returns:    A @KWRITE_@ code indicating how it went.
+ *
+ * Use:                Frees all the key data, writes any changes.  Make sure that
+ *             all hell breaks loose if this returns @KWRITE_BROKEN@.
+ */
+
+int key_close(key_file *f)
+{
+  int e;
+
+  if (f->fp && (e = key_save(f)) != KWRITE_OK)
+    return (e);
+  key_discard(f);
   return (KWRITE_OK);
 }
 
@@ -563,11 +562,12 @@ key *key_new(key_file *f, uint32 id, const char *type, time_t exp, int *err)
     if ((e = insert(f, k)) == 0)
       f->f |= KF_MODIFIED;
     else {
-      free(k->type);
+      xfree(k->type);
       DESTROY(k);
       k = 0;
     }
   }
+  *err = e;
   return (k);
 }