#define CF_FILE_ERROR (1)
#define CF_FILE_CONFIG (1 << 2)
#define CF_FILE_MODULE (1 << 3)
-int cf_file_changed(CONF_SECTION *cs);
+int cf_file_changed(CONF_SECTION *cs, rb_walker_t callback);
extern CONF_SECTION *root_config;
extern bool cf_new_escape;
}
+typedef struct cf_file_callback_t {
+ int rcode;
+ rb_walker_t callback;
+ CONF_SECTION *modules;
+} cf_file_callback_t;
+
+
/*
* Return 0 for keep going, 1 for stop.
*/
static int file_callback(void *ctx, void *data)
{
- int *rcode = ctx;
- struct stat buf;
+ cf_file_callback_t *cb = ctx;
cf_file_t *file = data;
+ struct stat buf;
/*
* The file doesn't exist or we can no longer read it.
*/
if (stat(file->filename, &buf) < 0) {
- *rcode = CF_FILE_ERROR;
+ cb->rcode = CF_FILE_ERROR;
return 1;
}
*/
if (buf.st_mtime != file->buf.st_mtime) {
if (!file->input) {
- *rcode |= CF_FILE_CONFIG;
+ cb->rcode |= CF_FILE_CONFIG;
} else {
- *rcode |= CF_FILE_MODULE;
+ (void) cb->callback(cb->modules, file->cs);
+ cb->rcode |= CF_FILE_MODULE;
}
}
/*
* See if any of the files have changed.
*/
-int cf_file_changed(CONF_SECTION *cs)
+int cf_file_changed(CONF_SECTION *cs, rb_walker_t callback)
{
- int rcode;
CONF_DATA *cd;
CONF_SECTION *top;
+ cf_file_callback_t cb;
rbtree_t *tree;
top = cf_top_section(cs);
tree = cd->data;
- rcode = CF_FILE_NONE;
- (void) rbtree_walk(tree, RBTREE_IN_ORDER, file_callback, &rcode);
+ cb.rcode = CF_FILE_NONE;
+ cb.callback = callback;
+ cb.modules = cf_section_sub_find(cs, "modules");
- return rcode;
+ (void) rbtree_walk(tree, RBTREE_IN_ORDER, file_callback, &cb);
+
+ return cb.rcode;
}
static int _cf_section_free(CONF_SECTION *cs)
#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modules.h>
+#include <freeradius-devel/modpriv.h>
#include <freeradius-devel/rad_assert.h>
#include <sys/stat.h>
}
}
+static int hup_callback(void *ctx, void *data)
+{
+ CONF_SECTION *modules = ctx;
+ CONF_SECTION *cs = data;
+ CONF_SECTION *parent;
+ char const *name;
+ module_instance_t *mi;
+
+ /*
+ * Files may be defined in sub-sections of a module
+ * config. Walk up the tree until we find the module
+ * definition.
+ */
+ parent = cf_item_parent(cf_section_to_item(cs));
+ while (parent != modules) {
+ cs = parent;
+ parent = cf_item_parent(cf_section_to_item(cs));
+
+ /*
+ * Something went wrong. Oh well...
+ */
+ if (!parent) return 0;
+ }
+
+ name = cf_section_name2(cs);
+ if (!name) name = cf_section_name1(cs);
+
+ mi = module_find(modules, name);
+ if (!mi) return 0;
+
+ if ((mi->entry->module->type & RLM_TYPE_HUP_SAFE) == 0) return 0;
+
+ if (!module_hup_module(mi->cs, mi, time(NULL))) return 0;
+
+ return 0;
+}
+
void main_config_hup(void)
{
int rcode;
}
last_hup = when;
- rcode = cf_file_changed(cs_cache->cs);
+ rcode = cf_file_changed(cs_cache->cs, hup_callback);
if (rcode == CF_FILE_NONE) {
INFO("HUP - No files changed. Ignoring");
return;