Reflect new and modify *.config to connman config list. with patch any modified or added .config file will be read by connman and add these configuration for new provisioning.
P.S. I will submit another patch to refelect new provisioning on current avialable network. --- src/config.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 162 insertions(+), 3 deletions(-) diff --git a/src/config.c b/src/config.c index d203935..52a602b 100644 --- a/src/config.c +++ b/src/config.c @@ -24,8 +24,13 @@ #endif #include <stdio.h> +#include <unistd.h> +#include <limits.h> #include <string.h> +#include <sys/ioctl.h> #include <sys/vfs.h> +#include <sys/types.h> +#include <sys/inotify.h> #include <glib.h> #include "connman.h" @@ -56,6 +61,10 @@ struct connman_config { static GHashTable *config_table = NULL; +static int inotify_watch = 0; +static GIOChannel *inotify_channel = NULL; +static uint channel_watch = 0; + /* Definition of possible strings in the .config files */ #define CONFIG_KEY_NAME "Name" #define CONFIG_KEY_DESC "Description" @@ -340,7 +349,7 @@ static int load_config(struct connman_config *config) return 0; } -static int create_config(const char *ident) +static int create_config(const char *ident, connman_bool_t load) { struct connman_config *config; @@ -362,7 +371,8 @@ static int create_config(const char *ident) connman_info("Adding configuration %s", config->ident); - load_config(config); + if (load == TRUE) + load_config(config); return 0; } @@ -395,7 +405,7 @@ static int read_configs(void) ident = g_string_free(str, FALSE); if (connman_dbus_validate_ident(ident) == TRUE) - create_config(ident); + create_config(ident, TRUE); g_free(ident); } @@ -406,6 +416,151 @@ static int read_configs(void) return 0; } +static gboolean inotify_data(GIOChannel *channel, GIOCondition cond, + gpointer user_data) +{ + char buffer[4096]; + gsize i, ret; + GIOError err; + + if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) { + channel_watch = 0; + return FALSE; + } + + err = g_io_channel_read(channel, (gchar *) buffer, + sizeof(buffer) - 1, &ret); + + if (err != G_IO_ERROR_NONE) { + if (err == G_IO_ERROR_AGAIN) + return TRUE; + + connman_error("Reading from inotify channel failed"); + channel_watch = 0; + return FALSE; + } + + if (ret <= 0) + return TRUE; + + i = 0; + + while (i < ret) { + struct inotify_event *event; + gchar *file; + GString *str; + gchar *ident; + + event = (struct inotify_event *) &buffer[i]; + if (event->len) + file = &buffer[i] + sizeof(struct inotify_event); + else + file = NULL; + + i += sizeof(struct inotify_event) + event->len; + + if (file == NULL) + continue; + + if (g_str_has_suffix(file, ".config") == FALSE) + continue; + + ident = g_strrstr(file, ".config"); + if (ident == NULL) + continue; + + str = g_string_new_len(file, ident - file); + if (str == NULL) + continue; + + ident = g_string_free(str, FALSE); + + if (connman_dbus_validate_ident(ident) == FALSE) { + g_free(ident); + continue; + } + + if (event->mask & IN_CREATE) + create_config(ident, FALSE); + + if (event->mask & IN_MODIFY) { + struct connman_config *config; + + config = g_hash_table_lookup(config_table, ident); + if (config != NULL) { + g_hash_table_remove_all(config->service_table); + load_config(config); + } + } + + if (event->mask & IN_DELETE) + g_hash_table_remove(config_table, ident); + + g_free(ident); + } + + return TRUE; +} + +static int create_watch(void) +{ + int fd; + + fd = inotify_init(); + + if (fd < 0) + return -EIO; + + inotify_watch = inotify_add_watch(fd, STORAGEDIR, + IN_MODIFY | IN_CREATE | IN_DELETE); + if (inotify_watch < 0) { + connman_error("Creation of STORAGEDIR watch failed"); + close(fd); + return -EIO; + } + + inotify_channel = g_io_channel_unix_new(fd); + if (inotify_channel == NULL) { + connman_error("Creation of inotify channel failed"); + inotify_rm_watch(fd, inotify_watch); + inotify_watch = 0; + + close(fd); + return -EIO; + } + + g_io_channel_set_close_on_unref(inotify_channel, TRUE); + g_io_channel_set_encoding(inotify_channel, NULL, NULL); + + channel_watch = g_io_add_watch(inotify_channel, + G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR, + inotify_data, NULL); + + return 0; +} + +static void remove_watch(void) +{ + int fd; + + if (inotify_channel == NULL) + return; + + if (channel_watch != 0) + g_source_remove(channel_watch); + + channel_watch = 0; + + fd = g_io_channel_unix_get_fd(inotify_channel); + + if (inotify_watch >= 0) { + inotify_rm_watch(fd, inotify_watch); + inotify_watch = 0; + } + + g_io_channel_unref(inotify_channel); +} + int __connman_config_init(void) { DBG(""); @@ -413,6 +568,8 @@ int __connman_config_init(void) config_table = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, unregister_config); + create_watch(); + return read_configs(); } @@ -422,6 +579,8 @@ void __connman_config_cleanup(void) g_hash_table_destroy(config_table); config_table = NULL; + + remove_watch(); } static char *config_pem_fsid(const char *pem_file) -- 1.7.3.3 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman