From: Daniel Wagner <daniel.wag...@bmw-carit.de> Let's move the owner ship to the policy_list. The policy_hash is only used to lookup the policy data structure.
This patch removes the requirement that the 'ident' is key to lookup the policy data. Now we are able to define set of rules how we want associate the file with a session. --- plugins/session_policy_local.c | 63 +++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c index b0317bb..b20084d 100644 --- a/plugins/session_policy_local.c +++ b/plugins/session_policy_local.c @@ -110,22 +110,17 @@ static char *parse_selinux_type(const char *context) return ident; } -static struct policy_data *create_policy(const char *ident) +static struct policy_data *create_policy(void) { struct policy_data *policy; - DBG("ident %s", ident); - policy = g_new0(struct policy_data, 1); policy->refcount = 1; policy->config = connman_session_create_default_config(); - policy->ident = g_strdup(ident); policy_list = g_slist_prepend(policy_list, policy); - g_hash_table_replace(policy_hash, policy->ident, policy); - return policy; } @@ -146,9 +141,6 @@ static void policy_unref(struct policy_data *policy) return; policy_list = g_slist_remove(policy_list, policy); - - g_hash_table_remove(policy_hash, policy->ident); - free_policy(policy); }; @@ -176,11 +168,12 @@ static void selinux_context_reply(const unsigned char *context, void *user_data, } policy = g_hash_table_lookup(policy_hash, ident); - if (policy != NULL) { - policy_ref(policy); - policy->session = data->session; + if (policy == NULL) { + policy = create_policy(); + policy->ident = g_strdup(ident); } else - policy = create_policy(ident); + policy_ref(policy); + policy->session = data->session; g_hash_table_replace(session_hash, data->session, policy); config = policy->config; @@ -364,6 +357,7 @@ static void remove_policy(struct policy_data *policy) if (policy->session != NULL) update = TRUE; + g_hash_table_remove(policy_hash, policy->ident); policy_unref(policy); if (update == FALSE) @@ -373,12 +367,31 @@ static void remove_policy(struct policy_data *policy) update_session(policy->session); } +static struct policy_data *find_policy(const char *ident) +{ + GSList *list; + struct policy_data *policy; + + for (list = policy_list; list != NULL; list = list->next) { + policy = list->data; + + if (g_strcmp0(policy->ident, ident) != 0) + continue; + + return policy; + } + + return NULL; +} + static void notify_handler(struct inotify_event *event, const char *ident) { struct policy_data *policy; int err; + DBG("event %x file %s", event->mask, ident); + if (ident == NULL) return; @@ -387,10 +400,19 @@ static void notify_handler(struct inotify_event *event, if (event->mask & (IN_CREATE | IN_MOVED_TO)) { connman_info("Policy added for '%s'", ident); - if (policy != NULL) - policy_ref(policy); - else - policy = create_policy(ident); + /* policy != NULL can happen if the file is overwritten */ + if (policy == NULL) { + policy = find_policy(ident); + if (policy == NULL) + policy = create_policy(); + else + policy_ref(policy); + + policy->ident = g_strdup(ident); + } + + g_hash_table_replace(policy_hash, + g_strdup(ident), policy); } if (policy == NULL) @@ -433,7 +455,8 @@ static void read_policies(void) while ((file = g_dir_read_name(dir)) != NULL) { struct policy_data *policy; - policy = create_policy(file); + policy = create_policy(); + policy->ident = g_strdup(file); err = load_policy(policy); if (err < 0) { connman_warn("Loading policy file '%s' failed with %s", @@ -442,6 +465,8 @@ static void read_policies(void) continue; } + g_hash_table_replace(policy_hash, g_strdup(file), + policy); } g_dir_close(dir); @@ -467,7 +492,7 @@ static int session_policy_local_init(void) session_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); policy_hash = g_hash_table_new_full(g_str_hash, g_str_equal, - NULL, NULL); + g_free, NULL); err = connman_inotify_register(POLICYDIR, notify_handler); if (err < 0) -- 1.8.1.3.566.gaa39828 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman