[PATCH] Add inotify monitoring .config file th correct file.

Mohamed Abbas mabbas at linux.intel.com
Mon Jan 3 14:40:39 PST 2011


Please ignore the previous patch, I sent the wrong one please use
this one.

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 |  162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 159 insertions(+), 3 deletions(-)

diff --git a/src/config.c b/src/config.c
index d203935..c4be8b1 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,148 @@ 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)
+			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);
+
+	}
+
+	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 +565,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 +576,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




More information about the connman mailing list