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

Reply via email to