X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgkdbus.c;h=2a68d40fbffeda0252e2f77b18c76b7cf3ebeaf9;hb=2a53b4d0e2c98a14aedf31e38f0ad1fb2e8fe26f;hp=95fe311b9450941b0a32b98c69f0ed750a723676;hpb=3138d12756d158a0550244a94af804714563dd0f;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gkdbus.c b/gio/gkdbus.c index 95fe311..2a68d40 100644 --- a/gio/gkdbus.c +++ b/gio/gkdbus.c @@ -65,6 +65,11 @@ for (item = (head)->first; \ (guint8 *)(item) < (guint8 *)(head) + (head)->size; \ item = KDBUS_ITEM_NEXT(item)) +#define KDBUS_FOREACH(iter, first, _size) \ + for (iter = (first); \ + ((guint8 *)(iter) < (guint8 *)(first) + (_size)) && \ + ((guint8 *)(iter) >= (guint8 *)(first)); \ + iter = (void*)(((guint8 *)iter) + KDBUS_ALIGN8((iter)->size))) #define g_alloca0(x) memset(g_alloca(x), '\0', (x)) @@ -147,6 +152,277 @@ const guint8 hash_keys[8][16] = {0xf2,0x77,0xe9,0x6f,0x93,0xb5,0x4e,0x71,0x9a,0x0c,0x34,0x88,0x39,0x25,0xbf,0x35} }; +enum { + MATCH_ELEMENT_TYPE, + MATCH_ELEMENT_SENDER, + MATCH_ELEMENT_INTERFACE, + MATCH_ELEMENT_MEMBER, + MATCH_ELEMENT_PATH, + MATCH_ELEMENT_PATH_NAMESPACE, + MATCH_ELEMENT_DESTINATION, + MATCH_ELEMENT_ARG0NAMESPACE, + MATCH_ELEMENT_EAVESDROP, + MATCH_ELEMENT_ARGN, + MATCH_ELEMENT_ARGNPATH, +}; + +/* MatchElement struct */ +typedef struct { + guint16 type; + guint16 arg; + char *value; +} MatchElement; + +/* Match struct */ +typedef struct { + int n_elements; + MatchElement *elements; +} Match; + + +/** + * is_key() + * + */ +static gboolean +is_key (const char *key_start, const char *key_end, char *value) +{ + gsize len = strlen (value); + + if (len != key_end - key_start) + return FALSE; + + return strncmp (key_start, value, len) == 0; +} + + +/** + * parse_key() + * + */ +static gboolean +parse_key (MatchElement *element, const char *key_start, const char *key_end) +{ + gboolean res = TRUE; + + if (is_key (key_start, key_end, "type")) + { + element->type = MATCH_ELEMENT_TYPE; + } + else if (is_key (key_start, key_end, "sender")) + { + element->type = MATCH_ELEMENT_SENDER; + } + else if (is_key (key_start, key_end, "interface")) + { + element->type = MATCH_ELEMENT_INTERFACE; + } + else if (is_key (key_start, key_end, "member")) + { + element->type = MATCH_ELEMENT_MEMBER; + } + else if (is_key (key_start, key_end, "path")) + { + element->type = MATCH_ELEMENT_PATH; + } + else if (is_key (key_start, key_end, "path_namespace")) + { + element->type = MATCH_ELEMENT_PATH_NAMESPACE; + } + else if (is_key (key_start, key_end, "destination")) + { + element->type = MATCH_ELEMENT_DESTINATION; + } + else if (is_key (key_start, key_end, "arg0namespace")) + { + element->type = MATCH_ELEMENT_ARG0NAMESPACE; + } + else if (is_key (key_start, key_end, "eavesdrop")) + { + element->type = MATCH_ELEMENT_EAVESDROP; + } + else if (key_end - key_start > 3 && is_key (key_start, key_start + 3, "arg")) + { + const char *digits = key_start + 3; + const char *end_digits = digits; + + while (end_digits < key_end && g_ascii_isdigit (*end_digits)) + end_digits++; + + if (end_digits == key_end) /* argN */ + { + element->type = MATCH_ELEMENT_ARGN; + element->arg = atoi (digits); + } + else if (is_key (end_digits, key_end, "path")) /* argNpath */ + { + element->type = MATCH_ELEMENT_ARGNPATH; + element->arg = atoi (digits); + } + else + res = FALSE; + } + else + res = FALSE; + + return res; +} + + +/** + * parse_value() + * + */ +static const char * +parse_value (MatchElement *element, const char *s) +{ + char quote_char; + GString *value; + + value = g_string_new (""); + + quote_char = 0; + + for (;*s; s++) + { + if (quote_char == 0) + { + switch (*s) + { + case '\'': + quote_char = '\''; + break; + + case ',': + s++; + goto out; + + case '\\': + quote_char = '\\'; + break; + + default: + g_string_append_c (value, *s); + break; + } + } + else if (quote_char == '\\') + { + /* \ only counts as an escape if escaping a quote mark */ + if (*s != '\'') + g_string_append_c (value, '\\'); + + g_string_append_c (value, *s); + quote_char = 0; + } + else /* quote_char == ' */ + { + if (*s == '\'') + quote_char = 0; + else + g_string_append_c (value, *s); + } + } + + out: + if (quote_char == '\\') + g_string_append_c (value, '\\'); + else if (quote_char == '\'') + { + g_string_free (value, TRUE); + return NULL; + } + + element->value = g_string_free (value, FALSE); + return s; +} + + +/** + * match_new() + * + */ +static Match * +match_new (const char *str) +{ + Match *match; + GArray *elements; + const char *p; + const char *key_start; + const char *key_end; + MatchElement element; + int i; + + elements = g_array_new (TRUE, TRUE, sizeof (MatchElement)); + + p = str; + + while (*p != 0) + { + memset (&element, 0, sizeof (element)); + + /* Skip initial whitespace */ + while (*p && g_ascii_isspace (*p)) + p++; + + key_start = p; + + /* Read non-whitespace non-equals chars */ + while (*p && *p != '=' && !g_ascii_isspace (*p)) + p++; + + key_end = p; + + /* Skip any whitespace after key */ + while (*p && g_ascii_isspace (*p)) + p++; + + if (key_start == key_end) + continue; /* Allow trailing whitespace */ + if (*p != '=') + goto error; + + ++p; + + if (!parse_key (&element, key_start, key_end)) + goto error; + + p = parse_value (&element, p); + if (p == NULL) + goto error; + + g_array_append_val (elements, element); + } + + match = g_new0 (Match, 1); + match->n_elements = elements->len; + match->elements = (MatchElement *)g_array_free (elements, FALSE); + + return match; + + error: + for (i = 0; i < elements->len; i++) + g_free (g_array_index (elements, MatchElement, i).value); + g_array_free (elements, TRUE); + return NULL; +} + + +/** + * match_free() + * + */ +static void +match_free (Match *match) +{ + int i; + for (i = 0; i < match->n_elements; i++) + g_free (match->elements[i].value); + g_free (match->elements); + g_free (match); +} + + /** * g_kdbus_finalize: * @@ -230,12 +506,13 @@ static gboolean g_kdbus_free_data (GKDBusWorker *kdbus, guint64 offset) { - struct kdbus_cmd_free cmd; + struct kdbus_cmd_free cmd = { + .size = sizeof(cmd), + .offset = offset, + .flags = 0 + }; int ret; - cmd.offset = offset; - cmd.flags = 0; - ret = ioctl (kdbus->fd, KDBUS_CMD_FREE, &cmd); if (ret < 0) return FALSE; @@ -314,7 +591,7 @@ GVariant * _g_kdbus_Hello (GKDBusWorker *worker, GError **error) { - struct kdbus_cmd_hello *hello; + struct kdbus_cmd_hello *cmd; struct kdbus_item *item; gchar *conn_name; @@ -326,20 +603,20 @@ _g_kdbus_Hello (GKDBusWorker *worker, size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_hello, items)) + KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1); - hello = g_alloca0 (size); - hello->flags = worker->flags; - hello->attach_flags_send = worker->attach_flags_send; - hello->attach_flags_recv = worker->attach_flags_recv; - hello->size = size; - hello->pool_size = KDBUS_POOL_SIZE; + cmd = g_alloca0 (size); + cmd->flags = worker->flags; + cmd->attach_flags_send = worker->attach_flags_send; + cmd->attach_flags_recv = worker->attach_flags_recv; + cmd->size = size; + cmd->pool_size = KDBUS_POOL_SIZE; - item = hello->items; + item = cmd->items; item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + conn_name_size + 1; item->type = KDBUS_ITEM_CONN_DESCRIPTION; memcpy (item->str, conn_name, conn_name_size+1); item = KDBUS_ITEM_NEXT (item); - if (ioctl(worker->fd, KDBUS_CMD_HELLO, hello)) + if (ioctl(worker->fd, KDBUS_CMD_HELLO, cmd)) { g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), @@ -358,7 +635,7 @@ _g_kdbus_Hello (GKDBusWorker *worker, return NULL; } - if (hello->bus_flags > 0xFFFFFFFFULL) + if (cmd->bus_flags > 0xFFFFFFFFULL) { g_set_error_literal (error, G_IO_ERROR, @@ -367,14 +644,14 @@ _g_kdbus_Hello (GKDBusWorker *worker, return NULL; } - memcpy (worker->bus_id, hello->id128, 16); + memcpy (worker->bus_id, cmd->id128, 16); - worker->unique_id = hello->id; - asprintf(&worker->unique_name, ":1.%llu", (unsigned long long) hello->id); + worker->unique_id = cmd->id; + asprintf(&worker->unique_name, ":1.%llu", (unsigned long long) cmd->id); /* read bloom filters parameters */ - //worker->bloom_size = (gsize) hello->bloom.size; - //worker->bloom_n_hash = (guint) hello->bloom.n_hash; + //worker->bloom_size = (gsize) cmd->bloom.size; + //worker->bloom_n_hash = (guint) cmd->bloom.n_hash; return g_variant_new ("(s)", worker->unique_name); } @@ -391,7 +668,7 @@ _g_kdbus_RequestName (GKDBusWorker *worker, GError **error) { GVariant *result; - struct kdbus_cmd_name *kdbus_name; + struct kdbus_cmd *cmd; guint64 kdbus_flags; gssize len, size; gint status, ret; @@ -419,15 +696,15 @@ _g_kdbus_RequestName (GKDBusWorker *worker, g_kdbus_translate_nameowner_flags (flags, &kdbus_flags); len = strlen(name) + 1; - size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len); - kdbus_name = g_alloca0 (size); - kdbus_name->size = size; - kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len; - kdbus_name->items[0].type = KDBUS_ITEM_NAME; - kdbus_name->flags = kdbus_flags; - memcpy (kdbus_name->items[0].str, name, len); - - ret = ioctl(worker->fd, KDBUS_CMD_NAME_ACQUIRE, kdbus_name); + size = G_STRUCT_OFFSET (struct kdbus_cmd, items) + KDBUS_ITEM_SIZE(len); + cmd = g_alloca0 (size); + cmd->size = size; + cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len; + cmd->items[0].type = KDBUS_ITEM_NAME; + cmd->flags = kdbus_flags; + memcpy (cmd->items[0].str, name, len); + + ret = ioctl(worker->fd, KDBUS_CMD_NAME_ACQUIRE, cmd); if (ret < 0) { if (errno == EEXIST) @@ -444,7 +721,7 @@ _g_kdbus_RequestName (GKDBusWorker *worker, } } - if (kdbus_name->flags & KDBUS_NAME_IN_QUEUE) + if (cmd->flags & KDBUS_NAME_IN_QUEUE) status = G_BUS_REQUEST_NAME_FLAGS_IN_QUEUE; result = g_variant_new ("(u)", status); @@ -463,7 +740,7 @@ _g_kdbus_ReleaseName (GKDBusWorker *worker, GError **error) { GVariant *result; - struct kdbus_cmd_name *kdbus_name; + struct kdbus_cmd *cmd; gssize len, size; gint status, ret; @@ -488,14 +765,14 @@ _g_kdbus_ReleaseName (GKDBusWorker *worker, } len = strlen(name) + 1; - size = G_STRUCT_OFFSET (struct kdbus_cmd_name, items) + KDBUS_ITEM_SIZE(len); - kdbus_name = g_alloca0 (size); - kdbus_name->size = size; - kdbus_name->items[0].size = KDBUS_ITEM_HEADER_SIZE + len; - kdbus_name->items[0].type = KDBUS_ITEM_NAME; - memcpy (kdbus_name->items[0].str, name, len); - - ret = ioctl(worker->fd, KDBUS_CMD_NAME_RELEASE, kdbus_name); + size = G_STRUCT_OFFSET (struct kdbus_cmd, items) + KDBUS_ITEM_SIZE(len); + cmd = g_alloca0 (size); + cmd->size = size; + cmd->items[0].size = KDBUS_ITEM_HEADER_SIZE + len; + cmd->items[0].type = KDBUS_ITEM_NAME; + memcpy (cmd->items[0].str, name, len); + + ret = ioctl(worker->fd, KDBUS_CMD_NAME_RELEASE, cmd); if (ret < 0) { if (errno == ESRCH) @@ -553,10 +830,10 @@ _g_kdbus_GetListNames (GKDBusWorker *worker, { GVariant *result; GVariantBuilder *builder; - - struct kdbus_cmd_name_list cmd = {}; - struct kdbus_name_list *name_list; - struct kdbus_name_info *name; + struct kdbus_info *name_list, *name; + struct kdbus_cmd_list cmd = { + .size = sizeof(cmd) + }; guint64 prev_id; gint ret; @@ -564,11 +841,11 @@ _g_kdbus_GetListNames (GKDBusWorker *worker, prev_id = 0; if (list_name_type) - cmd.flags = KDBUS_NAME_LIST_ACTIVATORS; /* ListActivatableNames */ + cmd.flags = KDBUS_LIST_ACTIVATORS; /* ListActivatableNames */ else - cmd.flags = KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES; /* ListNames */ + cmd.flags = KDBUS_LIST_UNIQUE | KDBUS_LIST_NAMES; /* ListNames */ - ret = ioctl(worker->fd, KDBUS_CMD_NAME_LIST, &cmd); + ret = ioctl(worker->fd, KDBUS_CMD_LIST, &cmd); if (ret < 0) { g_set_error (error, @@ -578,23 +855,23 @@ _g_kdbus_GetListNames (GKDBusWorker *worker, return NULL; } - name_list = (struct kdbus_name_list *) ((guint8 *) worker->kdbus_buffer + cmd.offset); + name_list = (struct kdbus_info *) ((guint8 *) worker->kdbus_buffer + cmd.offset); builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); - KDBUS_ITEM_FOREACH(name, name_list, names) + KDBUS_FOREACH(name, name_list, cmd.list_size) { struct kdbus_item *item; const gchar *item_name = ""; - if ((cmd.flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != prev_id) + if ((cmd.flags & KDBUS_LIST_UNIQUE) && name->id != prev_id) { GString *unique_name; unique_name = g_string_new (NULL); - g_string_printf (unique_name, ":1.%llu", name->owner_id); + g_string_printf (unique_name, ":1.%llu", name->id); g_variant_builder_add (builder, "s", unique_name->str); g_string_free (unique_name,TRUE); - prev_id = name->owner_id; + prev_id = name->id; } KDBUS_ITEM_FOREACH(item, name, items) @@ -659,17 +936,19 @@ g_kdbus_NameHasOwner_internal (GKDBusWorker *worker, */ GVariant * _g_kdbus_GetListQueuedOwners (GKDBusWorker *worker, - const gchar *name, - GError **error) + const gchar *name, + GError **error) { GVariant *result; GVariantBuilder *builder; GString *unique_name; gint ret; - struct kdbus_cmd_name_list cmd = {}; - struct kdbus_name_list *name_list; - struct kdbus_name_info *kname; + struct kdbus_info *name_list, *kname; + struct kdbus_cmd_list cmd = { + .size = sizeof(cmd), + .flags = KDBUS_LIST_QUEUED + }; if (!g_dbus_is_name (name)) { @@ -689,8 +968,7 @@ _g_kdbus_GetListQueuedOwners (GKDBusWorker *worker, return NULL; } - cmd.flags = KDBUS_NAME_LIST_QUEUED; - ret = ioctl(worker->fd, KDBUS_CMD_NAME_LIST, &cmd); + ret = ioctl(worker->fd, KDBUS_CMD_LIST, &cmd); if (ret < 0) { g_set_error (error, @@ -700,11 +978,11 @@ _g_kdbus_GetListQueuedOwners (GKDBusWorker *worker, return NULL; } - name_list = (struct kdbus_name_list *) ((guint8 *) worker->kdbus_buffer + cmd.offset); + name_list = (struct kdbus_info *) ((guint8 *) worker->kdbus_buffer + cmd.offset); unique_name = g_string_new (NULL); builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); - KDBUS_ITEM_FOREACH(kname, name_list, names) + KDBUS_FOREACH(kname, name_list, cmd.list_size) { struct kdbus_item *item; const char *item_name = ""; @@ -716,7 +994,7 @@ _g_kdbus_GetListQueuedOwners (GKDBusWorker *worker, if (strcmp(item_name, name)) continue; - g_string_printf (unique_name, ":1.%llu", kname->owner_id); + g_string_printf (unique_name, ":1.%llu", kname->id); g_variant_builder_add (builder, "s", item_name); } @@ -906,22 +1184,260 @@ _g_kdbus_GetConnectionUnixUser (GKDBusWorker *worker, /** - * _g_kdbus_match_remove: + * g_kdbus_bloom_add_data: + * Based on bus-bloom.c from systemd + * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c + */ +static void +g_kdbus_bloom_add_data (GKDBusWorker *worker, + guint64 bloom_data [], + const void *data, + gsize n) +{ + guint8 hash[8]; + guint64 bit_num; + guint bytes_num = 0; + guint cnt_1, cnt_2; + + guint c = 0; + guint64 p = 0; + + bit_num = worker->bloom_size * 8; + + if (bit_num > 1) + bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8; + + for (cnt_1 = 0; cnt_1 < (worker->bloom_n_hash); cnt_1++) + { + for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++) + { + if (c <= 0) + { + g_siphash24(hash, data, n, hash_keys[cnt_1++]); + c += 8; + } + + p = (p << 8ULL) | (guint64) hash[8 - c]; + c--; + } + + p &= bit_num - 1; + bloom_data[p >> 6] |= 1ULL << (p & 63); + } +} + + +/** + * g_kdbus_bloom_add_pair: * */ static void -_g_kdbus_match_remove (GKDBusWorker *worker, - guint cookie) +g_kdbus_bloom_add_pair (GKDBusWorker *worker, + guint64 bloom_data [], + const gchar *parameter, + const gchar *value) { - struct kdbus_cmd_match cmd_match = {}; - gint ret; + gchar buf[1024]; + gsize size; + + size = strlen(parameter) + strlen(value) + 1; + if (size > 1024) + return; + + strcpy(stpcpy(stpcpy(buf, parameter), ":"), value); + g_kdbus_bloom_add_data(worker, bloom_data, buf, size); +} + + +/** + * g_kdbus_bloom_add_prefixes: + * + */ +static void +g_kdbus_bloom_add_prefixes (GKDBusWorker *worker, + guint64 bloom_data [], + const gchar *parameter, + const gchar *value, + gchar separator) +{ + gchar buf[1024]; + gsize size; + + size = strlen(parameter) + strlen(value) + 1; + if (size > 1024) + return; + + strcpy(stpcpy(stpcpy(buf, parameter), ":"), value); + + for (;;) + { + gchar *last_sep; + last_sep = strrchr(buf, separator); + if (!last_sep || last_sep == buf) + break; + + *last_sep = 0; + g_kdbus_bloom_add_data(worker, bloom_data, buf, last_sep-buf); + } +} + + +/** + * _g_kdbus_AddMatch: + * + */ +void +_g_kdbus_AddMatch (GKDBusWorker *worker, + const gchar *match_rule, + guint cookie) +{ + Match *match; + MatchElement *element; + const gchar *sender_name; + gsize sender_len, size; + struct kdbus_cmd_match *cmd; + struct kdbus_item *item; + guint64 *bloom; + guint64 src_id; + gchar *type; + gint cnt, ret; + + if (match_rule[0] == '-') + return; + + match = match_new (match_rule); + if (!match) + { + match_free (match); + return; + } + + sender_name = NULL; + src_id = KDBUS_MATCH_ID_ANY; + + bloom = g_alloca0 (worker->bloom_size); + size = KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_cmd_match, items)); + match = match_new (match_rule); - cmd_match.size = sizeof (cmd_match); - cmd_match.cookie = cookie; + for (cnt = 0; cnt < match->n_elements; cnt++) + { + element = &match->elements[cnt]; + switch (element->type) + { + case MATCH_ELEMENT_SENDER: + if (g_dbus_is_unique_name(element->value)) + { + src_id = g_ascii_strtoull ((element->value)+3, NULL, 10); + size += KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, id) + sizeof(src_id)); + } + else if (g_dbus_is_name (element->value)) + { + sender_name = element->value; + sender_len = strlen(element->value) + 1; + size += KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, str) + sender_len); + } + else + { + g_critical ("Error while adding a match: %d", cookie); + match_free (match); + return; + } + break; + + case MATCH_ELEMENT_TYPE: + g_kdbus_bloom_add_pair (worker, bloom, "message-type", element->value); + break; + + case MATCH_ELEMENT_INTERFACE: + g_kdbus_bloom_add_pair (worker, bloom, "interface", element->value); + break; + + case MATCH_ELEMENT_MEMBER: + g_kdbus_bloom_add_pair (worker, bloom, "member", element->value); + break; + + case MATCH_ELEMENT_PATH: + g_kdbus_bloom_add_pair (worker, bloom, "path", element->value); + break; + + case MATCH_ELEMENT_PATH_NAMESPACE: + if (g_strcmp0 (element->value, "/")) + g_kdbus_bloom_add_pair (worker, bloom, "path-slash-prefix", element->value); + break; + + case MATCH_ELEMENT_ARGN: + asprintf (&type, "arg%u", element->arg); + g_kdbus_bloom_add_pair (worker, bloom, type, element->value); + free (type); + break; + + case MATCH_ELEMENT_ARGNPATH: + asprintf (&type, "arg%u-slash-prefix", element->arg); + g_kdbus_bloom_add_pair (worker, bloom, type, element->value); + free (type); + break; + + case MATCH_ELEMENT_ARG0NAMESPACE: + g_kdbus_bloom_add_pair (worker, bloom, "arg0-dot-prefix", element->value); + break; + + case MATCH_ELEMENT_DESTINATION: + case MATCH_ELEMENT_EAVESDROP: + break; + } + } + + size += KDBUS_ALIGN8 (G_STRUCT_OFFSET (struct kdbus_item, data64) + worker->bloom_size); + cmd = g_alloca0 (size); + cmd->size = size; + cmd->cookie = cookie; - ret = ioctl(worker->fd, KDBUS_CMD_MATCH_REMOVE, &cmd_match); + item = cmd->items; + item->size = G_STRUCT_OFFSET(struct kdbus_item, data64) + worker->bloom_size; + item->type = KDBUS_ITEM_BLOOM_MASK; + memcpy(item->data64, bloom, worker->bloom_size); + item = KDBUS_ITEM_NEXT(item); + + if (src_id != KDBUS_MATCH_ID_ANY) + { + item->size = G_STRUCT_OFFSET (struct kdbus_item, id) + sizeof(src_id); + item->type = KDBUS_ITEM_ID; + item->id = src_id; + item = KDBUS_ITEM_NEXT(item); + } + + if (sender_name) + { + item->size = G_STRUCT_OFFSET (struct kdbus_item, str) + sender_len; + item->type = KDBUS_ITEM_NAME; + memcpy (item->str, sender_name, sender_len); + } + + ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd); if (ret < 0) - g_warning ("ERROR - %d\n", (int) errno); + g_critical ("Error while adding a match: %d", cookie); + + match_free (match); +} + + +/** + * _g_kdbus_RemoveMatch: + * + */ +void +_g_kdbus_RemoveMatch (GKDBusWorker *worker, + guint cookie) +{ + struct kdbus_cmd_match cmd = { + .size = sizeof(cmd), + .cookie = cookie + }; + gint ret; + + ret = ioctl(worker->fd, KDBUS_CMD_MATCH_REMOVE, &cmd); + if (ret < 0) + g_warning ("Error while removing a match: %d\n", (int) errno); } @@ -937,7 +1453,7 @@ _g_kdbus_subscribe_name_owner_changed (GKDBusWorker *worker, guint cookie) { struct kdbus_item *item; - struct kdbus_cmd_match *cmd_match; + struct kdbus_cmd_match *cmd; gssize size, len; gint ret; guint64 old_id = 0; /* XXX why? */ @@ -948,10 +1464,10 @@ _g_kdbus_subscribe_name_owner_changed (GKDBusWorker *worker, G_STRUCT_OFFSET (struct kdbus_item, name_change) + G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len); - cmd_match = g_alloca0 (size); - cmd_match->size = size; - cmd_match->cookie = cookie; - item = cmd_match->items; + cmd = g_alloca0 (size); + cmd->size = size; + cmd->cookie = cookie; + item = cmd->items; if (old_name[0] == 0) { @@ -977,10 +1493,10 @@ _g_kdbus_subscribe_name_owner_changed (GKDBusWorker *worker, return; } - cmd_match = g_alloca0 (size); - cmd_match->size = size; - cmd_match->cookie = cookie; - item = cmd_match->items; + cmd = g_alloca0 (size); + cmd->size = size; + cmd->cookie = cookie; + item = cmd->items; /* KDBUS_ITEM_NAME_CHANGE */ item->type = KDBUS_ITEM_NAME_CHANGE; @@ -991,7 +1507,7 @@ _g_kdbus_subscribe_name_owner_changed (GKDBusWorker *worker, G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len; item = KDBUS_ITEM_NEXT(item); - ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd_match); + ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd); if (ret < 0) g_warning ("ERROR - %d\n", (int) errno); } @@ -1006,7 +1522,7 @@ _g_kdbus_subscribe_name_acquired (GKDBusWorker *worker, const gchar *name) { struct kdbus_item *item; - struct kdbus_cmd_match *cmd_match; + struct kdbus_cmd_match *cmd; gssize size, len; guint64 cookie; gint ret; @@ -1017,10 +1533,10 @@ _g_kdbus_subscribe_name_acquired (GKDBusWorker *worker, G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len); cookie = 0xbeefbeefbeefbeef; - cmd_match = g_alloca0 (size); - cmd_match->size = size; - cmd_match->cookie = cookie; - item = cmd_match->items; + cmd = g_alloca0 (size); + cmd->size = size; + cmd->cookie = cookie; + item = cmd->items; /* KDBUS_ITEM_NAME_ADD */ item->type = KDBUS_ITEM_NAME_ADD; @@ -1031,7 +1547,7 @@ _g_kdbus_subscribe_name_acquired (GKDBusWorker *worker, G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len; item = KDBUS_ITEM_NEXT(item); - ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd_match); + ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd); if (ret < 0) g_warning ("ERROR - %d\n", (int) errno); @@ -1048,7 +1564,7 @@ _g_kdbus_subscribe_name_lost (GKDBusWorker *worker, const gchar *name) { struct kdbus_item *item; - struct kdbus_cmd_match *cmd_match; + struct kdbus_cmd_match *cmd; gssize size, len; guint64 cookie; gint ret; @@ -1059,10 +1575,10 @@ _g_kdbus_subscribe_name_lost (GKDBusWorker *worker, G_STRUCT_OFFSET (struct kdbus_notify_name_change, name) + len); cookie = 0xdeafdeafdeafdeaf; - cmd_match = g_alloca0 (size); - cmd_match->size = size; - cmd_match->cookie = cookie; - item = cmd_match->items; + cmd = g_alloca0 (size); + cmd->size = size; + cmd->cookie = cookie; + item = cmd->items; /* KDBUS_ITEM_NAME_REMOVE */ item->type = KDBUS_ITEM_NAME_REMOVE; @@ -1073,7 +1589,7 @@ _g_kdbus_subscribe_name_lost (GKDBusWorker *worker, G_STRUCT_OFFSET(struct kdbus_notify_name_change, name) + len; item = KDBUS_ITEM_NEXT(item); - ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd_match); + ret = ioctl(worker->fd, KDBUS_CMD_MATCH_ADD, cmd); if (ret < 0) g_warning ("ERROR - %d\n", (int) errno); @@ -1091,7 +1607,7 @@ _g_kdbus_unsubscribe_name_acquired (GKDBusWorker *worker) guint64 cookie; cookie = 0xbeefbeefbeefbeef; - _g_kdbus_match_remove (worker, cookie); + _g_kdbus_RemoveMatch (worker, cookie); } @@ -1105,7 +1621,7 @@ _g_kdbus_unsubscribe_name_lost (GKDBusWorker *worker) guint64 cookie; cookie = 0xdeafdeafdeafdeaf; - _g_kdbus_match_remove (worker, cookie); + _g_kdbus_RemoveMatch (worker, cookie); } @@ -1132,97 +1648,6 @@ g_kdbus_append_bloom (struct kdbus_item **item, /** - * g_kdbus_bloom_add_data: - * Based on bus-bloom.c from systemd - * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c - */ -static void -g_kdbus_bloom_add_data (GKDBusWorker *worker, - guint64 bloom_data [], - const void *data, - gsize n) -{ - guint8 hash[8]; - guint64 bit_num; - guint bytes_num = 0; - guint cnt_1, cnt_2; - - guint c = 0; - guint64 p = 0; - - bit_num = worker->bloom_size * 8; - - if (bit_num > 1) - bytes_num = ((__builtin_clzll(bit_num) ^ 63U) + 7) / 8; - - for (cnt_1 = 0; cnt_1 < (worker->bloom_n_hash); cnt_1++) - { - for (cnt_2 = 0; cnt_2 < bytes_num; cnt_2++) - { - if (c <= 0) - { - g_siphash24(hash, data, n, hash_keys[cnt_1++]); - c += 8; - } - - p = (p << 8ULL) | (guint64) hash[8 - c]; - c--; - } - - p &= bit_num - 1; - bloom_data[p >> 6] |= 1ULL << (p & 63); - } -} - - -/** - * g_kdbus_bloom_add_pair: - * - */ -static void -g_kdbus_bloom_add_pair (GKDBusWorker *worker, - guint64 bloom_data [], - const gchar *parameter, - const gchar *value) -{ - GString *data = g_string_new (NULL); - - g_string_printf (data,"%s:%s",parameter,value); - g_kdbus_bloom_add_data(worker, bloom_data, data->str, data->len); - g_string_free (data, TRUE); -} - - -/** - * g_kdbus_bloom_add_prefixes: - * - */ -static void -g_kdbus_bloom_add_prefixes (GKDBusWorker *worker, - guint64 bloom_data [], - const gchar *parameter, - const gchar *value, - gchar separator) -{ - GString *data = g_string_new (NULL); - - g_string_printf (data,"%s:%s",parameter,value); - - for (;;) - { - gchar *last_sep; - last_sep = strrchr(data->str, separator); - if (!last_sep || last_sep == data->str) - break; - - *last_sep = 0; - g_kdbus_bloom_add_data(worker, bloom_data, data->str, last_sep-(data->str)); - } - g_string_free (data, TRUE); -} - - -/** * g_kdbus_setup_bloom: * Based on bus-bloom.c from systemd * http://cgit.freedesktop.org/systemd/systemd/tree/src/libsystemd/sd-bus/bus-bloom.c @@ -1464,7 +1889,7 @@ g_kdbus_decode_dbus_msg (GKDBusWorker *worker, flavour = body_size & 7; g_assert ((item->vec.offset & 7) == flavour); - vector.gbytes = g_bytes_new (((guchar *) worker->kdbus_buffer) + item->vec.offset - flavour, item->vec.size + flavour); + vector.gbytes = g_bytes_new (((guchar *) msg) + item->vec.offset - flavour, item->vec.size + flavour); vector.data.pointer = g_bytes_get_data (vector.gbytes, NULL); vector.data.pointer += flavour; vector.size = item->vec.size; @@ -1626,7 +2051,7 @@ again: g_print ("but sometimes that's okay\n"); - msg = (struct kdbus_msg *)((guint8 *)kdbus->kdbus_buffer + recv.reply.offset); + msg = (struct kdbus_msg *)((guint8 *)kdbus->kdbus_buffer + recv.msg.offset); if (msg->payload_type == KDBUS_PAYLOAD_DBUS) g_kdbus_decode_dbus_msg (kdbus, msg); @@ -1641,7 +2066,7 @@ again: return -1; } - ioctl(kdbus->fd, KDBUS_CMD_FREE, &recv.reply.offset); + ioctl(kdbus->fd, KDBUS_CMD_FREE, &recv.msg.offset); return 0; }