server/: Make initialization errors be non-fatal and restartable.
[tripe] / server / keymgmt.c
index 48e4de6..84d7010 100644 (file)
@@ -291,19 +291,21 @@ static int kh_reopen(keyhalf *kh)
  * Arguments:  @keyhalf *kh@ = pointer to keyhalf structure to set up
  *             @const char *kr@ = name of the keyring file
  *
- * Returns:    ---
+ * Returns:    Zero on success, @-1@ on error.
  *
  * Use:                Initialize a keyhalf structure, maintaining the private or
  *             public keys.  Intended to be called during initialization:
  *             exits if there's some kind of problem.
  */
 
-static void kh_init(keyhalf *kh, const char *kr)
+static int kh_init(keyhalf *kh, const char *kr)
 {
+  if (kh->kf) return (0);
   kh->kr = xstrdup(kr);
+  if (kh_reopen(kh)) return (-1);
   fwatch_init(&kh->w, kr);
   sym_create(&kh->tab);
-  if (kh_reopen(kh)) exit(EXIT_FAILURE);
+  return (0);
 }
 
 /* --- @kh_load@ --- *
@@ -554,7 +556,7 @@ static void kh_clear(keyhalf *kh)
 /*----- Main code ---------------------------------------------------------*/
 
 char *tag_priv = 0;
-kdata *master;
+kdata *master = 0;
 
 /* --- @km_init@ --- *
  *
@@ -562,15 +564,16 @@ kdata *master;
  *             @const char *pubkr@ = public keyring file
  *             @const char *ptag@ = default private-key tag
  *
- * Returns:    ---
+ * Returns:    Zero on success, @-1@ on failure.
  *
  * Use:                Initializes the key-management machinery, loading the
  *             keyrings and so on.
  */
 
-void km_init(const char *privkr, const char *pubkr, const char *ptag)
+int km_init(const char *privkr, const char *pubkr, const char *ptag)
 {
   const gchash *const *hh;
+  kdata *kd;
 
   for (hh = ghashtab; *hh; hh++) {
     if ((*hh)->hashsz > MAXHASHSZ) {
@@ -581,11 +584,17 @@ void km_init(const char *privkr, const char *pubkr, const char *ptag)
     }
   }
 
-  kh_init(&priv, privkr);
-  kh_init(&pub, pubkr);
+  if (kh_init(&priv, privkr) || kh_init(&pub, pubkr))
+    return (-1);
 
   tag_priv = ptag ? xstrdup(ptag) : 0;
-  if ((master = km_findpriv(ptag)) == 0) exit(EXIT_FAILURE);
+  kh_refresh(&priv);
+
+  if ((kd = km_findpriv(tag_priv)) == 0) return (-1);
+  if (master) km_unref(master);
+  master = kd;
+
+  return (0);
 }
 
 /* --- @km_reload@ --- *