From: Ralph Boehme Date: Fri, 1 Aug 2014 14:09:03 +0000 (+0200) Subject: afpd: check for modified included config file, FR #95 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=d7e5521f69859b3df89da09bf50621945f119d97 afpd: check for modified included config file, FR #95 Signed-off-by: Ralph Boehme --- diff --git a/NEWS b/NEWS index 0ff59489..2f29a534 100644 --- 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 ================ diff --git a/include/atalk/globals.h b/include/atalk/globals.h index ed450520..dfb356a8 100644 --- a/include/atalk/globals.h +++ b/include/atalk/globals.h @@ -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; }; diff --git a/libatalk/iniparser/iniparser.c b/libatalk/iniparser/iniparser.c index 53f6a108..343a6d06 100644 --- a/libatalk/iniparser/iniparser.c +++ b/libatalk/iniparser/iniparser.c @@ -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; diff --git a/libatalk/util/netatalk_conf.c b/libatalk/util/netatalk_conf.c index a1d27311..b5652608 100644 --- a/libatalk/util/netatalk_conf.c +++ b/libatalk/util/netatalk_conf.c @@ -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 */