afpd: check for modified included config file, FR #95
authorRalph Boehme <rb@sernet.de>
Fri, 1 Aug 2014 14:09:03 +0000 (16:09 +0200)
committerRalph Boehme <rb@sernet.de>
Fri, 1 Aug 2014 15:45:25 +0000 (17:45 +0200)
Signed-off-by: Ralph Boehme <rb@sernet.de>
NEWS
include/atalk/globals.h
libatalk/iniparser/iniparser.c
libatalk/util/netatalk_conf.c

diff --git a/NEWS b/NEWS
index 0ff5948..2f29a53 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Changes in 3.1.4
        (default: no), FR #94
 * UPD: afpd: FCE version 2 with new event types and new config options
        "fce ignore names" and "fce notify script"
+* UPD: afpd: check for modified included config file, FR #95.
 
 Changes in 3.1.3
 ================
index ed45052..dfb356a 100644 (file)
@@ -131,6 +131,7 @@ struct afp_options {
     char *cnid_mysql_pw;
     char *cnid_mysql_db;
     struct afp_volume_name volfile;
+    struct afp_volume_name includefile;
     uint64_t sparql_limit;
 };
 
index 53f6a10..343a6d0 100644 (file)
@@ -598,6 +598,10 @@ dictionary * atalk_iniparser_load(const char * ininame)
             break ;
         case LINE_VALUE:
             if (strcmp(key, "include") == 0) {
+                errs = atalkdict_set(dict, section, key, val);
+                if (errs < 0) {
+                    LOG(log_error, logtype_default, "iniparser: memory allocation failure");
+                }
                 if ((include = fopen(val, "r")) == NULL) {
                     LOG(log_error, logtype_default, "iniparser: cannot open \"%s\"", val);
                     continue;
index a1d2731..b565260 100644 (file)
@@ -1047,14 +1047,45 @@ EC_CLEANUP:
 
 /* ----------------------
  */
-static int volfile_changed(struct afp_options *p)
+static int volfile_changed(AFPObj *obj)
 {
     struct stat st;
+    struct afp_options *p = &obj->options;
+    int result;
+    const char *includefile;
+
+    result = stat(p->configfile, &st);
+    if (result != 0) {
+        LOG(log_debug, logtype_afpd, "where is the config file %s ?",
+            p->configfile);
+        /*
+         * We return 1 which means "config file changed". The caller
+         * will re-read config and fail too which is what we want.
+         */
+        return 1;
+    }
 
-    if (!stat(p->configfile, &st) && st.st_mtime > p->volfile.mtime) {
+    if (st.st_mtime > p->volfile.mtime) {
         p->volfile.mtime = st.st_mtime;
         return 1;
     }
+
+    includefile = atalk_iniparser_getstring(obj->iniconfig, INISEC_GLOBAL,
+                                            "include", NULL);
+    if (includefile) {
+        result = stat(includefile, &st);
+        if (result != 0) {
+            LOG(log_debug, logtype_afpd, "where is the include file %s ?",
+                includefile);
+            return 1;
+        }
+
+        if (st.st_mtime > p->includefile.mtime) {
+            p->includefile.mtime = st.st_mtime;
+            return 1;
+        }
+    }
+
     return 0;
 }
 
@@ -1430,6 +1461,7 @@ int load_volumes(AFPObj *obj, lv_flags_t flags)
     struct stat         st;
     int                 retries = 0;
     struct vol         *vol;
+    char               *includefile;
 
     LOG(log_debug, logtype_afpd, "load_volumes: BEGIN");
 
@@ -1450,7 +1482,7 @@ int load_volumes(AFPObj *obj, lv_flags_t flags)
     }
 
     if (Volumes) {
-        if (!volfile_changed(&obj->options))
+        if (!volfile_changed(obj))
             goto EC_CLEANUP;
         have_uservol = 0;
         for (vol = Volumes; vol; vol = vol->v_next) {
@@ -1469,6 +1501,13 @@ int load_volumes(AFPObj *obj, lv_flags_t flags)
         LOG(log_debug, logtype_afpd, "load_volumes: no volumes yet");
         EC_ZERO_LOG( lstat(obj->options.configfile, &st) );
         obj->options.volfile.mtime = st.st_mtime;
+
+        includefile = atalk_iniparser_getstring(obj->iniconfig, INISEC_GLOBAL,
+                                                "include", NULL);
+        if (includefile) {
+            EC_ZERO_LOG( stat(includefile, &st) );
+            obj->options.includefile.mtime = st.st_mtime;
+        }
     }
 
     /* try putting a read lock on the volume file twice, sleep 1 second if first attempt fails */