chiark / gitweb /
lib/home.c: Introduce functions for building pathmames in home directories.
[disorder] / lib / configuration.c
index b36033b9dab64242e30b2fe18a20b6fa750520f1..17f9ec7b4ed137f4f3b60aed9de3dac574b51233 100644 (file)
@@ -37,9 +37,6 @@
 # include <langinfo.h>
 #endif
 
-#if HAVE_SHLOBJ_H
-# include <Shlobj.h>
-#endif
 #include <signal.h>
 
 #include "rights.h"
@@ -48,6 +45,7 @@
 #include "log.h"
 #include "split.h"
 #include "syscalls.h"
+#include "home.h"
 #include "table.h"
 #include "inputline.h"
 #include "charset.h"
@@ -723,15 +721,14 @@ static int validate_tracklength(const struct config_state *cs,
   return 0;
 }
 
-/** @brief Validate a non-negative (@c long) integer
+/** @brief Common code for validating integer values
  * @param cs Configuration state
  * @param nvec Length of (proposed) new value
  * @param vec Elements of new value
- * @return 0 on success, non-0 on error
+ * @param n_out Where to put the value
  */
-static int validate_non_negative(const struct config_state *cs,
-                                int nvec, char **vec) {
-  long n;
+static int common_validate_integer(const struct config_state *cs,
+                                  int nvec, char **vec, long *n_out) {
   char errbuf[1024];
 
   if(nvec < 1) {
@@ -742,11 +739,24 @@ static int validate_non_negative(const struct config_state *cs,
     disorder_error(0, "%s:%d: too many arguments", cs->path, cs->line);
     return -1;
   }
-  if(xstrtol(&n, vec[0], 0, 0)) {
+  if(xstrtol(n_out, vec[0], 0, 0)) {
     disorder_error(0, "%s:%d: %s", cs->path, cs->line,
                    format_error(ec_errno, errno, errbuf, sizeof errbuf));
     return -1;
   }
+  return 0;
+}
+
+/** @brief Validate a non-negative (@c long) integer
+ * @param cs Configuration state
+ * @param nvec Length of (proposed) new value
+ * @param vec Elements of new value
+ * @return 0 on success, non-0 on error
+ */
+static int validate_non_negative(const struct config_state *cs,
+                                int nvec, char **vec) {
+  long n;
+  if(common_validate_integer(cs, nvec, vec, &n)) return -1;
   if(n < 0) {
     disorder_error(0, "%s:%d: must not be negative", cs->path, cs->line);
     return -1;
@@ -763,21 +773,7 @@ static int validate_non_negative(const struct config_state *cs,
 static int validate_positive(const struct config_state *cs,
                          int nvec, char **vec) {
   long n;
-  char errbuf[1024];
-
-  if(nvec < 1) {
-    disorder_error(0, "%s:%d: missing argument", cs->path, cs->line);
-    return -1;
-  }
-  if(nvec > 1) {
-    disorder_error(0, "%s:%d: too many arguments", cs->path, cs->line);
-    return -1;
-  }
-  if(xstrtol(&n, vec[0], 0, 0)) {
-    disorder_error(0, "%s:%d: %s", cs->path, cs->line,
-                   format_error(ec_errno, errno, errbuf, sizeof errbuf));
-    return -1;
-  }
+  if(common_validate_integer(cs, nvec, vec, &n)) return -1;
   if(n <= 0) {
     disorder_error(0, "%s:%d: must be positive", cs->path, cs->line);
     return -1;
@@ -986,6 +982,24 @@ static int validate_pausemode(const struct config_state attribute((unused)) *cs,
   return -1;
 }
 
+/** @brief Validate an MTU-discovery setting
+ * @param cs Configuration state
+ * @param nvec Length of (proposed) new value
+ * @param vec Elements of new value
+ * @return 0 on success, non-0 on error
+ */
+static int validate_mtu_discovery(const struct config_state attribute((unused)) *cs,
+                                 int nvec,
+                                 char **vec) {
+  if (nvec == 1 &&
+      (!strcmp(vec[0], "default") ||
+       !strcmp(vec[0], "yes") ||
+       !strcmp(vec[0], "no")))
+    return 0;
+  disorder_error(0, "%s:%d: invalid MTU-discovery setting", cs->path, cs->line);
+  return -1;
+}
+
 /** @brief Validate a destination network address
  * @param cs Configuration state
  * @param nvec Length of (proposed) new value
@@ -1012,6 +1026,32 @@ static int validate_destaddr(const struct config_state attribute((unused)) *cs,
   return 0;
 }
 
+/** @brief Validate an internet address
+ * @param cs Configuration state
+ * @param nvec Length of (proposed) new value
+ * @param vec Elements of new value
+ * @return 0 on success, non-0 on error
+ *
+ * By a destination address, it is meant that it must be either IPv4 or IPv6.
+ */
+static int validate_inetaddr(const struct config_state *cs,
+                            int nvec, char **vec) {
+  struct netaddress na[1];
+
+  if(netaddress_parse(na, nvec, vec)) {
+    disorder_error(0, "%s:%d: invalid network address", cs->path, cs->line);
+    return -1;
+  }
+  switch(na->af) {
+    case AF_INET: case AF_INET6: case AF_UNSPEC: break;
+    default:
+      disorder_error(0, "%s:%d: must be an intenet address",
+                    cs->path, cs->line);
+      return -1;
+  }
+  return 0;
+}
+
 /** @brief Item name and and offset */
 #define C(x) #x, offsetof(struct config, x)
 /** @brief Item name and and offset */
@@ -1067,8 +1107,16 @@ static const struct conf conf[] = {
   { C(reminder_interval), &type_integer,         validate_positive },
   { C(remote_userman),   &type_boolean,          validate_any },
   { C(replay_min),       &type_integer,          validate_non_negative },
+  { C(rtp_always_request), &type_boolean,       validate_any },
   { C(rtp_delay_threshold), &type_integer,       validate_positive },
+  { C(rtp_instance_name), &type_string,                 validate_any },
+  { C(rtp_max_payload),         &type_integer,          validate_positive },
+  { C(rtp_maxbuffer),   &type_integer,          validate_non_negative },
+  { C(rtp_minbuffer),   &type_integer,          validate_non_negative },
   { C(rtp_mode),         &type_string,           validate_any },
+  { C(rtp_mtu_discovery), &type_string,                 validate_mtu_discovery },
+  { C(rtp_rcvbuf),      &type_integer,          validate_non_negative },
+  { C(rtp_request_address), &type_netaddress,   validate_inetaddr },
   { C(rtp_verbose),      &type_boolean,          validate_any },
   { C(sample_format),    &type_sample_format,    validate_sample_format },
   { C(scratch),          &type_string_accum,     validate_isreg },
@@ -1380,6 +1428,8 @@ static struct config *config_default(void) {
   c->listen.af = -1;
   c->connect.af = -1;
   c->rtp_mode = xstrdup("auto");
+  c->rtp_max_payload = -1;
+  c->rtp_mtu_discovery = xstrdup("default");
   return c;
 }
 
@@ -1554,7 +1604,7 @@ int config_read(int server,
     xfree(privconf);
 #endif
     /* if we have a password file, read it */
-    if((privconf = config_userconf(0, pw))
+    if((privconf = config_userconf())
        && access(privconf, F_OK) == 0
        && config_include(c, privconf))
       return -1;
@@ -1620,22 +1670,8 @@ char *config_private(void) {
 }
 
 /** @brief Return the path to user's personal configuration file */
-char *config_userconf(const char *home, const struct passwd *pw) {
-  char *s;
-#if _WIN32
-  wchar_t *wpath = 0;
-  char *appdata;
-  if(SHGetKnownFolderPath(&FOLDERID_RoamingAppData, 0, NULL, &wpath) != S_OK)
-    disorder_fatal(0, "error calling SHGetKnownFolderPath");
-  appdata = win_wtomb(wpath);
-  CoTaskMemFree(wpath);
-  byte_xasprintf(&s, "%s\\DisOrder\\passwd", appdata);
-#else
-  if(!home && !pw && !(pw = getpwuid(getuid())))
-    disorder_fatal(0, "cannot determine our username");
-  byte_xasprintf(&s, "%s/.disorder/passwd", home ? home : pw->pw_dir);
-#endif
-  return s;
+char *config_userconf(void) {
+  return profile_filename("passwd");
 }
 
 #if !_WIN32