chiark / gitweb /
Do some basic compatibility checking when installing a new server
[disorder] / lib / configuration.c
index 5691e8ae24e518fa1d79ab3fe53d1a317281ae0a..dd089491ce423b9b31eacfb4d997de14e760c515 100644 (file)
@@ -510,6 +510,7 @@ static void free_none(struct config attribute((unused)) *c,
 static void free_string(struct config *c,
                        const struct conf *whoami) {
   xfree(VALUE(c, char *));
+  VALUE(c, char *) = 0;
 }
 
 static void free_stringlist(struct config *c,
@@ -833,27 +834,6 @@ static int validate_alias(const struct config_state *cs,
   return 0;
 }
 
-static int validate_addrport(const struct config_state attribute((unused)) *cs,
-                            int nvec,
-                            char attribute((unused)) **vec) {
-  switch(nvec) {
-  case 0:
-    error(0, "%s:%d: missing address",
-         cs->path, cs->line);
-    return -1;
-  case 1:
-    error(0, "%s:%d: missing port name/number",
-         cs->path, cs->line);
-    return -1;
-  case 2:
-    return 0;
-  default:
-    error(0, "%s:%d: expected ADDRESS PORT",
-         cs->path, cs->line);
-    return -1;
-  }
-}
-
 static int validate_algo(const struct config_state attribute((unused)) *cs,
                         int nvec,
                         char **vec) {
@@ -933,7 +913,7 @@ static const struct conf conf[] = {
   { C(checkpoint_kbyte), &type_integer,          validate_non_negative },
   { C(checkpoint_min),   &type_integer,          validate_non_negative },
   { C(collection),       &type_collections,      validate_any },
-  { C(connect),          &type_stringlist,       validate_addrport },
+  { C(connect),          &type_netaddress,       validate_destaddr },
   { C(cookie_login_lifetime),  &type_integer,    validate_positive },
   { C(cookie_key_lifetime),  &type_integer,      validate_positive },
   { C(dbversion),        &type_integer,          validate_positive },
@@ -1176,7 +1156,7 @@ static struct config *config_default(void) {
   logname = pw->pw_name;
   c->username = xstrdup(logname);
   c->refresh = 15;
-  c->prefsync = 3600;
+  c->prefsync = 0;
   c->signal = SIGKILL;
   c->alias = xstrdup("{/artist}{/album}{/title}{ext}");
   c->lock = 1;
@@ -1223,6 +1203,7 @@ static struct config *config_default(void) {
   c->broadcast.af = -1;
   c->broadcast_from.af = -1;
   c->listen.af = -1;
+  c->connect.af = -1;
   return c;
 }
 
@@ -1345,8 +1326,14 @@ static void config_postdefaults(struct config *c,
 
 /** @brief (Re-)read the config file
  * @param server If set, do extra checking
+ * @param oldconfig Old configuration for compatibility check
+ * @return 0 on success, non-0 on error
+ *
+ * If @p oldconfig is set, then certain compatibility checks are done between
+ * the old and new configurations.
  */
-int config_read(int server) {
+int config_read(int server,
+                const struct config *oldconfig) {
   struct config *c;
   char *privconf;
   struct passwd *pw;
@@ -1381,6 +1368,31 @@ int config_read(int server) {
   }
   /* install default namepart and transform settings */
   config_postdefaults(c, server);
+  if(oldconfig)  {
+    int failed = 0;
+    if(strcmp(c->home, oldconfig->home)) {
+      error(0, "'home' cannot be changed without a restart");
+      failed = 1;
+    }
+    if(strcmp(c->alias, oldconfig->alias)) {
+      error(0, "'alias' cannot be changed without a restart");
+      failed = 1;
+    }
+    if(strcmp(c->user, oldconfig->user)) {
+      error(0, "'user' cannot be changed without a restart");
+      failed = 1;
+    }
+    if(c->nice_speaker != oldconfig->nice_speaker) {
+      error(0, "'nice_speaker' cannot be changed without a restart");
+      /* ...but we accept the new config anyway */
+    }
+    /* TODO namepart */
+    /* TODO stopword */
+    if(failed) {
+      error(0, "not installing incompatible new configuration");
+      return -1;
+    }
+  }
   /* everything is good so we shall use the new config */
   config_free(config);
   /* warn about obsolete directives */
@@ -1390,6 +1402,12 @@ int config_read(int server) {
     error(0, "'allow' will be removed in a future version");
   if(c->trust.n)
     error(0, "'trust' will be removed in a future version");
+  if(!c->lock)
+    error(0, "'lock' will be removed in a future version");
+  if(c->gap)
+    error(0, "'gap' will be removed in a future version");
+  if(c->prefsync)
+    error(0, "'prefsync' will be removed in a future version");
   config = c;
   return 0;
 }