Configuration reloader for postlicyd.
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Thu, 18 Sep 2008 20:17:45 +0000 (22:17 +0200)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Thu, 18 Sep 2008 20:17:45 +0000 (22:17 +0200)
Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
postlicyd/config.c
postlicyd/config.h
postlicyd/main-postlicyd.c

index b563ef3..7ea485c 100644 (file)
@@ -75,17 +75,22 @@ config_param_register("verify_filter");
 static inline config_t *config_new(void)
 {
     config_t *config = p_new(config_t, 1);
+    return config;
+}
+
+static void config_close(config_t *config)
+{
     for (int i = 0 ; i < SMTP_count ; ++i) {
         config->entry_points[i] = -1;
     }
-    return config;
+    array_deep_wipe(config->filters, filter_wipe);
+    array_deep_wipe(config->params, filter_params_wipe);
 }
 
 void config_delete(config_t **config)
 {
     if (*config) {
-        array_deep_wipe((*config)->filters, filter_wipe);
-        array_deep_wipe((*config)->params, filter_params_wipe);
+        config_close(*config);
         p_delete(config);
     }
 }
@@ -146,9 +151,8 @@ static bool config_second_pass(config_t *config)
     return ok;
 }
 
-config_t *config_read(const char *file)
+static bool config_load(config_t *config)
 {
-    config_t *config;
     filter_t filter;
     file_map_t map;
     const char *p;
@@ -159,18 +163,18 @@ config_t *config_read(const char *file)
     char value[BUFSIZ];
     ssize_t key_len, value_len;
 
-    if (!file_map_open(&map, file, false)) {
+    if (!file_map_open(&map, config->filename, false)) {
         return false;
     }
 
-    config = config_new();
+    config_close(config);
     filter_init(&filter);
     linep = p = map.map;
 
 #define READ_ERROR(Fmt, ...)                                                   \
     do {                                                                       \
-        syslog(LOG_ERR, "config file %s:%d:%d: " Fmt, file, line + 1,          \
-               p - linep + 1, ##__VA_ARGS__);                                  \
+        syslog(LOG_ERR, "config file %s:%d:%d: " Fmt, config->filename,        \
+               line + 1, p - linep + 1, ##__VA_ARGS__);                        \
         goto error;                                                            \
     } while (0)
 #define ADD_IN_BUFFER(Buffer, Len, Char)                                       \
@@ -355,7 +359,7 @@ ok:
         goto error;
     }
     file_map_close(&map);
-    return config;
+    return true;
 
 badeof:
     syslog(LOG_ERR, "Unexpected end of file");
@@ -364,7 +368,22 @@ error:
     if (filter.name) {
         filter_wipe(&filter);
     }
-    config_delete(&config);
     file_map_close(&map);
-    return NULL;
+    return false;
+}
+
+bool config_reload(config_t *config)
+{
+    return config_load(config);
+}
+
+config_t *config_read(const char *file)
+{
+    config_t *config = config_new();
+    config->filename = file;
+    if (!config_reload(config)) {
+        p_delete(&config);
+        return NULL;
+    }
+    return config;
 }
index 554fe96..6584919 100644 (file)
 typedef struct config_t config_t;
 
 struct config_t {
-    A(filter_t)        filters;
+    /* SOURCE */
+    /* Root configuration file.
+     */
+    const char *filename;
+
+    /* Parameters.
+     */
     A(filter_param_t)  params;
+
+
+    /* INTERPRETED */
+    /* Filters.
+     */
+    A(filter_t) filters;
+
+    /* Entry point of the filters.
+     * (one per smtp state)
+     */
     int entry_points[SMTP_count];
+
+    /* Port on which the program have to bind to.
+     * The parameter from CLI override the parameter from configuration file.
+     */
+    uint16_t port;
 };
 
 __attribute__((nonnull(1)))
 config_t *config_read(const char *file);
 
+__attribute__((nonnull(1)))
+bool config_reload(config_t *config);
+
 void config_delete(config_t **config);
 
 #endif
index 5be638b..5f46e76 100644 (file)
@@ -56,6 +56,11 @@ static void *query_starter(server_t* server)
     return query_new();
 }
 
+static bool config_refresh(void *config)
+{
+    return config_reload(config);
+}
+
 static int postfix_parsejob(query_t *query, char *p)
 {
 #define PARSE_CHECK(expr, error, ...)                                        \
@@ -246,6 +251,7 @@ int main(int argc, char *argv[])
     const char *pidfile = NULL;
     bool daemonize = true;
     int port = DEFAULT_PORT;
+    bool port_from_cli = false;
 
     for (int c = 0; (c = getopt(argc, argv, "hf" "l:p:")) >= 0; ) {
         switch (c) {
@@ -257,6 +263,7 @@ int main(int argc, char *argv[])
             break;
           case 'l':
             port = atoi(optarg);
+            port_from_cli = true;
             break;
           case 'f':
             daemonize = false;
@@ -276,15 +283,19 @@ int main(int argc, char *argv[])
     if (config == NULL) {
         return EXIT_FAILURE;
     }
+    if (port_from_cli || config->port == 0) {
+        config->port = port;
+    }
 
     if (common_setup(pidfile, false, RUNAS_USER, RUNAS_GROUP,
                      daemonize) != EXIT_SUCCESS
-        || start_listener(port) < 0) {
+        || start_listener(config->port) < 0) {
+        config_delete(&config);
         return EXIT_FAILURE;
     }
     {
         int res = server_loop(query_starter, (delete_client_t)query_delete,
-                              policy_run, NULL, config);
+                              policy_run, config_refresh, config);
         config_delete(&config);
         return res;
     }