]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/util/netatalk_conf.c
config: add utility function vdgoption_bool()
[netatalk.git] / libatalk / util / netatalk_conf.c
index 2e1812ddcc0e3cc38aa3f09ec42dbe916421147b..1a4f9fa64de8b6feec41932bb7a5c9dd39a0a5f6 100644 (file)
@@ -547,6 +547,36 @@ static int getoption_bool(const dictionary *conf, const char *vol, const char *o
     return result;
 }
 
+/*!
+ * Get boolean option from volume, default section or global - use default value if not set
+ *
+ * Order of precedence: volume -> default section -> global -> default value
+ *
+ * "vdg" means volume, default section or global
+ *
+ * @param conf    (r) config handle
+ * @param vol     (r) volume name (must be section name ie wo vars expanded)
+ * @param opt     (r) option
+ * @param defsec  (r) if "option" is not found in "vol", try to find it in section "defsec"
+ * @param defval  (r) if neither "vol" nor "defsec" contain "opt" return "defval"
+ *
+ * @returns       const option string from "vol" or "defsec", or "defval" if not found
+ */
+static int vdgoption_bool(const dictionary *conf, const char *vol, const char *opt, const char *defsec, int defval)
+{
+    int result;
+
+    result = atalk_iniparser_getboolean(conf, vol, opt, -1);
+
+    if ((result == -1) && (defsec != NULL))
+        result = atalk_iniparser_getboolean(conf, defsec, opt, -1);
+
+    if (result == -1)
+        result = atalk_iniparser_getboolean(conf, INISEC_GLOBAL, opt, defval);
+
+    return result;
+}
+
 /*!
  * Create volume struct
  *
@@ -827,6 +857,19 @@ static struct vol *creatvol(AFPObj *obj,
         }
     }
 
+    val = getoption(obj->iniconfig, section, "chmod request", preset, NULL);
+    if (val == NULL) {
+        val = atalk_iniparser_getstring(obj->iniconfig, INISEC_GLOBAL, "chmod request", "preserve");
+    }
+    if (strcasecmp(val, "ignore") == 0) {
+        volume->v_flags |= AFPVOL_CHMOD_IGNORE;
+    } else if (strcasecmp(val, "preserve") == 0) {
+        volume->v_flags |= AFPVOL_CHMOD_PRESERVE_ACL;
+    } else if (strcasecmp(val, "simple") != 0) {
+        LOG(log_warning, logtype_afpd, "unknown 'chmod request' setting: '%s', using default", val);
+        volume->v_flags |= AFPVOL_CHMOD_PRESERVE_ACL;
+    }
+
     /*
      * Handle read-only behaviour. semantics:
      * 1) neither the rolist nor the rwlist exist -> rw
@@ -1600,36 +1643,18 @@ struct vol *getvolbypath(AFPObj *obj, const char *path)
     struct vol *tmp;
     const struct passwd *pw;
     char        volname[AFPVOL_U8MNAMELEN + 1];
-    char        abspath[MAXPATHLEN + 1];
+    char        *realabspath = NULL;
     char        volpath[MAXPATHLEN + 1], *realvolpath = NULL;
     char        tmpbuf[MAXPATHLEN + 1];
     const char *secname, *basedir, *p = NULL, *subpath = NULL, *subpathconfig;
     char *user = NULL, *prw;
     regmatch_t match[1];
-    size_t abspath_len;
 
     LOG(log_debug, logtype_afpd, "getvolbypath(\"%s\")", path);
 
-    if (path[0] != '/') {
-        /* relative path, build absolute path */
-        EC_NULL_LOG( getcwd(abspath, MAXPATHLEN) );
-        strlcat(abspath, "/", MAXPATHLEN);
-        strlcat(abspath, path, MAXPATHLEN);
-        path = abspath;
-    } else {
-        strlcpy(abspath, path, MAXPATHLEN);
-        path = abspath;
-    }
-    /* path now points to a copy of path in the abspath buffer */
-
-    /*
-     * Strip trailing slashes
-     */
-    abspath_len = strlen(abspath);
-    while (abspath[abspath_len - 1] == '/') {
-        abspath[abspath_len - 1] = 0;
-        abspath_len--;
-    }
+    /*  build absolute path */
+    EC_NULL( realabspath = realpath_safe(path) );
+    path = realabspath;
 
     for (tmp = Volumes; tmp; tmp = tmp->v_next) { /* (1) */
         size_t v_path_len = strlen(tmp->v_path);
@@ -1751,6 +1776,8 @@ EC_CLEANUP:
         free(user);
     if (realvolpath)
         free(realvolpath);
+    if (realabspath)
+        free(realabspath);
     if (ret != 0)
         vol = NULL;
     return vol;