void _dbus_platform_condvar_free (DBusCondVar *cond) { DeleteCriticalSection (&cond->lock); _dbus_list_clear (&cond->list); dbus_free (cond); }
dbus_bool_t bus_service_list_queued_owners (BusService *service, DBusList **return_list, DBusError *error) { DBusList *link; _dbus_assert (*return_list == NULL); link = _dbus_list_get_first_link (&service->owners); _dbus_assert (link != NULL); while (link != NULL) { BusOwner *owner; const char *uname; owner = (BusOwner *) link->data; uname = bus_connection_get_name (owner->conn); if (!_dbus_list_append (return_list, (char *)uname)) goto oom; link = _dbus_list_get_next_link (&service->owners, link); } return TRUE; oom: _dbus_list_clear (return_list); BUS_SET_OOM (error); return FALSE; }
/** * Copies a list. This is a linear-time operation. If there isn't * enough memory to copy the entire list, the destination list will be * set to #NULL. * * @param list address of the head of the list to copy. * @param dest address where the copied list should be placed. * @returns #TRUE on success, #FALSE if not enough memory. */ dbus_bool_t _dbus_list_copy (DBusList **list, DBusList **dest) { DBusList *link; _dbus_assert (list != dest); *dest = NULL; link = *list; while (link != NULL) { if (!_dbus_list_append (dest, link->data)) { /* free what we have so far */ _dbus_list_clear (dest); return FALSE; } link = _dbus_list_get_next_link (list, link); } return TRUE; }
static void _dbus_windows_condvar_free (DBusCondVar *cond) { DeleteCriticalSection (&cond->lock); _dbus_list_clear (&cond->list); dbus_free (cond); }
/** * Frees a DBusWatchList. * * @param watch_list the watch list. */ void _dbus_watch_list_free (DBusWatchList *watch_list) { /* free watch_data and removes watches as a side effect */ _dbus_watch_list_set_functions (watch_list, NULL, NULL, NULL, NULL, NULL); _dbus_list_foreach (&watch_list->watches, (DBusForeachFunction) _dbus_watch_unref, NULL); _dbus_list_clear (&watch_list->watches); dbus_free (watch_list); }
static void free_rule_list_func (void *data) { DBusList **list = data; if (list == NULL) /* DBusHashTable is on crack */ return; _dbus_list_foreach (list, free_rule_func, NULL); _dbus_list_clear (list); dbus_free (list); }
/** * Frees a DBusTimeoutList. * * @param timeout_list the timeout list. */ void _dbus_timeout_list_free (DBusTimeoutList *timeout_list) { /* free timeout_data and remove timeouts as a side effect */ _dbus_timeout_list_set_functions (timeout_list, NULL, NULL, NULL, NULL, NULL); _dbus_list_foreach (&timeout_list->timeouts, (DBusForeachFunction) _dbus_timeout_unref, NULL); _dbus_list_clear (&timeout_list->timeouts); dbus_free (timeout_list); }
void bus_policy_unref (BusPolicy *policy) { _dbus_assert (policy->refcount > 0); policy->refcount -= 1; if (policy->refcount == 0) { _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL); _dbus_list_clear (&policy->default_rules); _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL); _dbus_list_clear (&policy->mandatory_rules); _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL); _dbus_list_clear (&policy->at_console_true_rules); _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL); _dbus_list_clear (&policy->at_console_false_rules); if (policy->rules_by_uid) { _dbus_hash_table_unref (policy->rules_by_uid); policy->rules_by_uid = NULL; } if (policy->rules_by_gid) { _dbus_hash_table_unref (policy->rules_by_gid); policy->rules_by_gid = NULL; } dbus_free (policy); } }
void bus_config_parser_unref (BusConfigParser *parser) { _dbus_string_free (&parser->user); _dbus_string_free (&parser->service_helper); _dbus_string_free (&parser->bus_type); _dbus_list_foreach (&parser->service_dirs, (DBusForeachFunction) dbus_free, NULL); _dbus_list_clear (&parser->service_dirs); dbus_free (parser); }
/** * Sets the reply of a pending call with the given message, * or if the message is #NULL, by timing out the pending call. * * @param pending the pending call * @param message the message to complete the call with, or #NULL * to time out the call */ void _dbus_pending_call_set_reply_unlocked (DBusPendingCall *pending, DBusMessage *message) { if (message == NULL) { message = pending->timeout_link->data; _dbus_list_clear (&pending->timeout_link); } else dbus_message_ref (message); _dbus_verbose (" handing message %p (%s) to pending call serial %u\n", message, dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ? "method return" : dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ? "error" : "other type", pending->reply_serial); _dbus_assert (pending->reply == NULL); _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message)); pending->reply = message; }
static DBusList* tokenize_command_line (const char *command_line, DBusError *error) { char current_quote; const char *p; DBusString current_token; DBusList *retval = NULL; dbus_bool_t quoted;; current_quote = '\0'; quoted = FALSE; p = command_line; if (!_dbus_string_init (¤t_token)) { _DBUS_SET_OOM (error); return NULL; } while (*p) { if (current_quote == '\\') { if (*p == '\n') { /* we append nothing; backslash-newline become nothing */ } else { if (!_dbus_string_append_byte (¤t_token, '\\') || !_dbus_string_append_byte (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } } current_quote = '\0'; } else if (current_quote == '#') { /* Discard up to and including next newline */ while (*p && *p != '\n') ++p; current_quote = '\0'; if (*p == '\0') break; } else if (current_quote) { if (*p == current_quote && /* check that it isn't an escaped double quote */ !(current_quote == '"' && quoted)) { /* close the quote */ current_quote = '\0'; } /* Everything inside quotes, and the close quote, * gets appended literally. */ if (!_dbus_string_append_byte (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } } else { switch (*p) { case '\n': if (!delimit_token (¤t_token, &retval, error)) goto error; _dbus_string_free (¤t_token); if (!_dbus_string_init (¤t_token)) { _DBUS_SET_OOM (error); goto init_error; } break; case ' ': case '\t': /* If the current token contains the previous char, delimit * the current token. A nonzero length * token should always contain the previous char. */ if (_dbus_string_get_length (¤t_token) > 0) { if (!delimit_token (¤t_token, &retval, error)) goto error; _dbus_string_free (¤t_token); if (!_dbus_string_init (¤t_token)) { _DBUS_SET_OOM (error); goto init_error; } } /* discard all unquoted blanks (don't add them to a token) */ break; /* single/double quotes are appended to the token, * escapes are maybe appended next time through the loop, * comment chars are never appended. */ case '\'': case '"': if (!_dbus_string_append_byte (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } /* FALL THRU */ case '#': case '\\': current_quote = *p; break; default: /* Combines rules 4) and 6) - if we have a token, append to it, * otherwise create a new token. */ if (!_dbus_string_append_byte (¤t_token, *p)) { _DBUS_SET_OOM (error); goto error; } break; } } /* We need to count consecutive backslashes mod 2, * to detect escaped doublequotes. */ if (*p != '\\') quoted = FALSE; else quoted = !quoted; ++p; } if (!delimit_token (¤t_token, &retval, error)) goto error; if (current_quote) { dbus_set_error_const (error, DBUS_ERROR_INVALID_ARGS, "Unclosed quotes in command line"); goto error; } if (retval == NULL) { dbus_set_error_const (error, DBUS_ERROR_INVALID_ARGS, "No tokens found in command line"); goto error; } _dbus_string_free (¤t_token); return retval; error: _dbus_string_free (¤t_token); init_error: if (retval) { _dbus_list_foreach (&retval, (DBusForeachFunction) dbus_free, NULL); _dbus_list_clear (&retval); } return NULL; }
/** * @ingroup DBusListInternals * Unit test for DBusList * @returns #TRUE on success. */ dbus_bool_t _dbus_list_test (void) { DBusList *list1; DBusList *list2; DBusList *link1; DBusList *link2; DBusList *copy1; DBusList *copy2; int i; list1 = NULL; list2 = NULL; /* Test append and prepend */ i = 0; while (i < 10) { if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("could not allocate for append"); if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("count not allocate for prepend"); ++i; verify_list (&list1); verify_list (&list2); _dbus_assert (_dbus_list_get_length (&list1) == i); _dbus_assert (_dbus_list_get_length (&list2) == i); } _dbus_assert (is_ascending_sequence (&list1)); _dbus_assert (is_descending_sequence (&list2)); /* Test list clear */ _dbus_list_clear (&list1); _dbus_list_clear (&list2); verify_list (&list1); verify_list (&list2); /* Test get_first, get_last, pop_first, pop_last */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; while (i >= 0) { void *got_data1; void *got_data2; void *data1; void *data2; got_data1 = _dbus_list_get_last (&list1); got_data2 = _dbus_list_get_first (&list2); data1 = _dbus_list_pop_last (&list1); data2 = _dbus_list_pop_first (&list2); _dbus_assert (got_data1 == data1); _dbus_assert (got_data2 == data2); _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); verify_list (&list1); verify_list (&list2); _dbus_assert (is_ascending_sequence (&list1)); _dbus_assert (is_descending_sequence (&list2)); --i; } _dbus_assert (list1 == NULL); _dbus_assert (list2 == NULL); /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; while (i >= 0) { DBusList *got_link1; DBusList *got_link2; DBusList *link1; DBusList *link2; void *data1; void *data2; got_link1 = _dbus_list_get_last_link (&list1); got_link2 = _dbus_list_get_first_link (&list2); link1 = _dbus_list_pop_last_link (&list1); link2 = _dbus_list_pop_first_link (&list2); _dbus_assert (got_link1 == link1); _dbus_assert (got_link2 == link2); data1 = link1->data; data2 = link2->data; _dbus_list_free_link (link1); _dbus_list_free_link (link2); _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); verify_list (&list1); verify_list (&list2); _dbus_assert (is_ascending_sequence (&list1)); _dbus_assert (is_descending_sequence (&list2)); --i; } _dbus_assert (list1 == NULL); _dbus_assert (list2 == NULL); /* Test iteration */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; verify_list (&list1); verify_list (&list2); _dbus_assert (_dbus_list_get_length (&list1) == i); _dbus_assert (_dbus_list_get_length (&list2) == i); } _dbus_assert (is_ascending_sequence (&list1)); _dbus_assert (is_descending_sequence (&list2)); --i; link2 = _dbus_list_get_first_link (&list2); while (link2 != NULL) { verify_list (&link2); /* pretend this link is the head */ _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); link2 = _dbus_list_get_next_link (&list2, link2); --i; } i = 0; link1 = _dbus_list_get_first_link (&list1); while (link1 != NULL) { verify_list (&link1); /* pretend this link is the head */ _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); link1 = _dbus_list_get_next_link (&list1, link1); ++i; } --i; link1 = _dbus_list_get_last_link (&list1); while (link1 != NULL) { verify_list (&link1); /* pretend this link is the head */ _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); link1 = _dbus_list_get_prev_link (&list1, link1); --i; } _dbus_list_clear (&list1); _dbus_list_clear (&list2); /* Test remove */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; while (i >= 0) { if ((i % 2) == 0) { if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("element should have been in list"); if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("element should have been in list"); verify_list (&list1); verify_list (&list2); } --i; } _dbus_assert (all_odd_values (&list1)); _dbus_assert (all_odd_values (&list2)); _dbus_list_clear (&list1); _dbus_list_clear (&list2); /* test removing the other half of the elements */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; while (i >= 0) { if ((i % 2) != 0) { if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("element should have been in list"); if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("element should have been in list"); verify_list (&list1); verify_list (&list2); } --i; } _dbus_assert (all_even_values (&list1)); _dbus_assert (all_even_values (&list2)); /* clear list using remove_link */ while (list1 != NULL) { _dbus_list_remove_link (&list1, list1); verify_list (&list1); } while (list2 != NULL) { _dbus_list_remove_link (&list2, list2); verify_list (&list2); } /* Test remove link more generally */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; link2 = _dbus_list_get_first_link (&list2); while (link2 != NULL) { DBusList *next = _dbus_list_get_next_link (&list2, link2); _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); if ((i % 2) == 0) _dbus_list_remove_link (&list2, link2); verify_list (&list2); link2 = next; --i; } _dbus_assert (all_odd_values (&list2)); _dbus_list_clear (&list2); i = 0; link1 = _dbus_list_get_first_link (&list1); while (link1 != NULL) { DBusList *next = _dbus_list_get_next_link (&list1, link1); _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); if ((i % 2) != 0) _dbus_list_remove_link (&list1, link1); verify_list (&list1); link1 = next; ++i; } _dbus_assert (all_even_values (&list1)); _dbus_list_clear (&list1); /* Test copying a list */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } /* bad pointers, because they are allowed in the copy dest */ copy1 = _DBUS_INT_TO_POINTER (0x342234); copy2 = _DBUS_INT_TO_POINTER (23); _dbus_list_copy (&list1, ©1); verify_list (&list1); verify_list (©1); _dbus_assert (lists_equal (&list1, ©1)); _dbus_list_copy (&list2, ©2); verify_list (&list2); verify_list (©2); _dbus_assert (lists_equal (&list2, ©2)); /* Now test copying empty lists */ _dbus_list_clear (&list1); _dbus_list_clear (&list2); _dbus_list_clear (©1); _dbus_list_clear (©2); /* bad pointers, because they are allowed in the copy dest */ copy1 = _DBUS_INT_TO_POINTER (0x342234); copy2 = _DBUS_INT_TO_POINTER (23); _dbus_list_copy (&list1, ©1); verify_list (&list1); verify_list (©1); _dbus_assert (lists_equal (&list1, ©1)); _dbus_list_copy (&list2, ©2); verify_list (&list2); verify_list (©2); _dbus_assert (lists_equal (&list2, ©2)); _dbus_list_clear (&list1); _dbus_list_clear (&list2); /* insert_before on empty list */ _dbus_list_insert_before (&list1, NULL, _DBUS_INT_TO_POINTER (0)); verify_list (&list1); /* inserting before first element */ _dbus_list_insert_before (&list1, list1, _DBUS_INT_TO_POINTER (2)); verify_list (&list1); _dbus_assert (is_descending_sequence (&list1)); /* inserting in the middle */ _dbus_list_insert_before (&list1, list1->next, _DBUS_INT_TO_POINTER (1)); verify_list (&list1); _dbus_assert (is_descending_sequence (&list1)); /* using insert_before to append */ _dbus_list_insert_before (&list1, NULL, _DBUS_INT_TO_POINTER (-1)); verify_list (&list1); _dbus_assert (is_descending_sequence (&list1)); _dbus_list_clear (&list1); /* insert_after on empty list */ _dbus_list_insert_after (&list1, NULL, _DBUS_INT_TO_POINTER (0)); verify_list (&list1); /* inserting after first element */ _dbus_list_insert_after (&list1, list1, _DBUS_INT_TO_POINTER (1)); verify_list (&list1); _dbus_assert (is_ascending_sequence (&list1)); /* inserting at the end */ _dbus_list_insert_after (&list1, list1->next, _DBUS_INT_TO_POINTER (2)); verify_list (&list1); _dbus_assert (is_ascending_sequence (&list1)); /* using insert_after to prepend */ _dbus_list_insert_after (&list1, NULL, _DBUS_INT_TO_POINTER (-1)); verify_list (&list1); _dbus_assert (is_ascending_sequence (&list1)); _dbus_list_clear (&list1); /* using remove_last */ _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (2)); _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (1)); _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (3)); _dbus_list_remove_last (&list1, _DBUS_INT_TO_POINTER (2)); verify_list (&list1); _dbus_assert (is_ascending_sequence (&list1)); _dbus_list_clear (&list1); return TRUE; }
dbus_bool_t bus_expire_list_test (const DBusString *test_data_dir) { DBusLoop *loop; BusExpireList *list; long tv_sec, tv_usec; long tv_sec_not_expired, tv_usec_not_expired; long tv_sec_expired, tv_usec_expired; long tv_sec_past, tv_usec_past; TestExpireItem *item; int next_interval; dbus_bool_t result = FALSE; loop = _dbus_loop_new (); _dbus_assert (loop != NULL); #define EXPIRE_AFTER 100 list = bus_expire_list_new (loop, EXPIRE_AFTER, test_expire_func, NULL); _dbus_assert (list != NULL); _dbus_get_current_time (&tv_sec, &tv_usec); tv_sec_not_expired = tv_sec; tv_usec_not_expired = tv_usec; time_add_milliseconds (&tv_sec_not_expired, &tv_usec_not_expired, EXPIRE_AFTER - 1); tv_sec_expired = tv_sec; tv_usec_expired = tv_usec; time_add_milliseconds (&tv_sec_expired, &tv_usec_expired, EXPIRE_AFTER); tv_sec_past = tv_sec - 1; tv_usec_past = tv_usec; item = dbus_new0 (TestExpireItem, 1); if (item == NULL) goto oom; item->item.added_tv_sec = tv_sec; item->item.added_tv_usec = tv_usec; if (!_dbus_list_append (&list->items, item)) _dbus_assert_not_reached ("out of memory"); next_interval = do_expiration_with_current_time (list, tv_sec_not_expired, tv_usec_not_expired); _dbus_assert (item->expire_count == 0); _dbus_verbose ("next_interval = %d\n", next_interval); _dbus_assert (next_interval == 1); next_interval = do_expiration_with_current_time (list, tv_sec_expired, tv_usec_expired); _dbus_assert (item->expire_count == 1); _dbus_verbose ("next_interval = %d\n", next_interval); _dbus_assert (next_interval == -1); next_interval = do_expiration_with_current_time (list, tv_sec_past, tv_usec_past); _dbus_assert (item->expire_count == 1); _dbus_verbose ("next_interval = %d\n", next_interval); _dbus_assert (next_interval == 1000 + EXPIRE_AFTER); _dbus_list_clear (&list->items); dbus_free (item); bus_expire_list_free (list); _dbus_loop_unref (loop); result = TRUE; oom: return result; }
/** * Verifies that the range of type_str from type_pos to type_end is a * valid signature. If this function returns #TRUE, it will be safe * to iterate over the signature with a types-only #DBusTypeReader. * The range passed in should NOT include the terminating * nul/DBUS_TYPE_INVALID. * * @param type_str the string * @param type_pos where the typecodes start * @param len length of typecodes * @returns #DBUS_VALID if valid, reason why invalid otherwise */ DBusValidity _dbus_validate_signature_with_reason (const DBusString *type_str, int type_pos, int len) { const unsigned char *p; const unsigned char *end; int last; int struct_depth; int array_depth; int dict_entry_depth; DBusValidity result; int element_count; DBusList *element_count_stack; result = DBUS_VALID; element_count_stack = NULL; if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0))) { result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; goto out; } _dbus_assert (type_str != NULL); _dbus_assert (type_pos < _DBUS_INT32_MAX - len); _dbus_assert (len >= 0); _dbus_assert (type_pos >= 0); if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH) { result = DBUS_INVALID_SIGNATURE_TOO_LONG; goto out; } p = _dbus_string_get_const_data_len (type_str, type_pos, 0); end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0); struct_depth = 0; array_depth = 0; dict_entry_depth = 0; last = DBUS_TYPE_INVALID; while (p != end) { switch (*p) { case DBUS_TYPE_BYTE: case DBUS_TYPE_BOOLEAN: case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: case DBUS_TYPE_DOUBLE: case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_SIGNATURE: case DBUS_TYPE_VARIANT: break; case DBUS_TYPE_ARRAY: array_depth += 1; if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) { result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION; goto out; } break; case DBUS_STRUCT_BEGIN_CHAR: struct_depth += 1; if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) { result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION; goto out; } if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0))) { result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; goto out; } break; case DBUS_STRUCT_END_CHAR: if (struct_depth == 0) { result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED; goto out; } if (last == DBUS_STRUCT_BEGIN_CHAR) { result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS; goto out; } _dbus_list_pop_last (&element_count_stack); struct_depth -= 1; break; case DBUS_DICT_ENTRY_BEGIN_CHAR: if (last != DBUS_TYPE_ARRAY) { result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY; goto out; } dict_entry_depth += 1; if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) { result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION; goto out; } if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0))) { result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; goto out; } break; case DBUS_DICT_ENTRY_END_CHAR: if (dict_entry_depth == 0) { result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED; goto out; } dict_entry_depth -= 1; element_count = _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack)); if (element_count != 2) { if (element_count == 0) result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS; else if (element_count == 1) result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD; else result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS; goto out; } break; case DBUS_TYPE_STRUCT: /* doesn't appear in signatures */ case DBUS_TYPE_DICT_ENTRY: /* ditto */ default: result = DBUS_INVALID_UNKNOWN_TYPECODE; goto out; } if (*p != DBUS_TYPE_ARRAY && *p != DBUS_DICT_ENTRY_BEGIN_CHAR && *p != DBUS_STRUCT_BEGIN_CHAR) { element_count = _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack)); ++element_count; if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (element_count))) { result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; goto out; } } if (array_depth > 0) { if (*p == DBUS_TYPE_ARRAY && p != end) { const char *p1; p1 = p + 1; if (*p1 == DBUS_STRUCT_END_CHAR || *p1 == DBUS_DICT_ENTRY_END_CHAR) { result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE; goto out; } } else { array_depth = 0; } } if (last == DBUS_DICT_ENTRY_BEGIN_CHAR && !dbus_type_is_basic (*p)) { result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; goto out; } last = *p; ++p; } if (array_depth > 0) { result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE; goto out; } if (struct_depth > 0) { result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED; goto out; } if (dict_entry_depth > 0) { result = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED; goto out; } _dbus_assert (last != DBUS_TYPE_ARRAY); _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR); _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR); result = DBUS_VALID; out: _dbus_list_clear (&element_count_stack); return result; }
/** * Split paths into a list of char strings * * @param dirs string with pathes * @param suffix string concated to each path in dirs * @param dir_list contains a list of splitted pathes * return #TRUE is pathes could be splittes,#FALSE in oom case */ dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs, const char *suffix, DBusList **dir_list) { int start; int i; int len; char *cpath; DBusString file_suffix; start = 0; i = 0; _dbus_string_init_const (&file_suffix, suffix); len = _dbus_string_get_length (dirs); while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i)) { DBusString path; if (!_dbus_string_init (&path)) goto oom; if (!_dbus_string_copy_len (dirs, start, i - start, &path, 0)) { _dbus_string_free (&path); goto oom; } _dbus_string_chop_white (&path); /* check for an empty path */ if (_dbus_string_get_length (&path) == 0) goto next; if (!_dbus_concat_dir_and_file (&path, &file_suffix)) { _dbus_string_free (&path); goto oom; } if (!_dbus_string_copy_data(&path, &cpath)) { _dbus_string_free (&path); goto oom; } if (!_dbus_list_append (dir_list, cpath)) { _dbus_string_free (&path); dbus_free (cpath); goto oom; } next: _dbus_string_free (&path); start = i + 1; } if (start != len) { DBusString path; if (!_dbus_string_init (&path)) goto oom; if (!_dbus_string_copy_len (dirs, start, len - start, &path, 0)) { _dbus_string_free (&path); goto oom; } if (!_dbus_concat_dir_and_file (&path, &file_suffix)) { _dbus_string_free (&path); goto oom; } if (!_dbus_string_copy_data(&path, &cpath)) { _dbus_string_free (&path); goto oom; } if (!_dbus_list_append (dir_list, cpath)) { _dbus_string_free (&path); dbus_free (cpath); goto oom; } _dbus_string_free (&path); } return TRUE; oom: _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); _dbus_list_clear (dir_list); return FALSE; }
static dbus_bool_t bus_driver_handle_list_queued_owners (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, DBusError *error) { const char *text; DBusList *base_names; DBusList *link; DBusString str; BusRegistry *registry; BusService *service; DBusMessage *reply; DBusMessageIter iter, array_iter; char *dbus_service_name = DBUS_SERVICE_DBUS; _DBUS_ASSERT_ERROR_IS_CLEAR (error); registry = bus_connection_get_registry (connection); base_names = NULL; text = NULL; reply = NULL; if (! dbus_message_get_args (message, error, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID)) goto failed; _dbus_string_init_const (&str, text); service = bus_registry_lookup (registry, &str); if (service == NULL && _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS)) { /* ORG_FREEDESKTOP_DBUS owns itself */ if (! _dbus_list_append (&base_names, dbus_service_name)) goto oom; } else if (service == NULL) { dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get owners of name '%s': no such name", text); goto failed; } else { if (!bus_service_list_queued_owners (service, &base_names, error)) goto failed; } _dbus_assert (base_names != NULL); reply = dbus_message_new_method_return (message); if (reply == NULL) goto oom; dbus_message_iter_init_append (reply, &iter); if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter)) goto oom; link = _dbus_list_get_first_link (&base_names); while (link != NULL) { char *uname; _dbus_assert (link->data != NULL); uname = (char *)link->data; if (!dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &uname)) goto oom; link = _dbus_list_get_next_link (&base_names, link); } if (! dbus_message_iter_close_container (&iter, &array_iter)) goto oom; if (! bus_transaction_send_from_driver (transaction, connection, reply)) goto oom; dbus_message_unref (reply); return TRUE; oom: BUS_SET_OOM (error); failed: _DBUS_ASSERT_ERROR_IS_SET (error); if (reply) dbus_message_unref (reply); if (base_names) _dbus_list_clear (&base_names); return FALSE; }
static dbus_bool_t test_command_line (const char *arg1, ...) { int i, original_argc, shell_argc; char **shell_argv; char **original_argv; char *command_line, *tmp; DBusString str; DBusList *list = NULL, *node; va_list var_args; DBusError error; va_start (var_args, arg1); _dbus_list_append (&list, (char *)arg1); do { tmp = va_arg (var_args, char *); if (!tmp) break; _dbus_list_append (&list, tmp); } while (tmp); va_end (var_args); original_argc = _dbus_list_get_length (&list); original_argv = dbus_new (char *, original_argc); _dbus_string_init (&str); for (i = 0, node = _dbus_list_get_first_link (&list); i < original_argc && node; i++, node = _dbus_list_get_next_link (&list, node)) { original_argv[i] = node->data; if (i > 0) _dbus_string_append_byte (&str, ' '); _dbus_string_append (&str, original_argv[i]); } _dbus_list_clear (&list); command_line = _dbus_string_get_data (&str); printf ("\n\nTesting command line '%s'\n", command_line); dbus_error_init (&error); if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error)) { fprintf (stderr, "Error parsing command line: %s\n", error.message ? error.message : ""); return FALSE; } else { if (shell_argc != original_argc) { printf ("Number of arguments returned (%d) don't match original (%d)\n", shell_argc, original_argc); return FALSE; } printf ("Number of arguments: %d\n", shell_argc); for (i = 0; i < shell_argc; i++) { char *unquoted; unquoted = _dbus_shell_unquote (original_argv[i]); if (strcmp (unquoted ? unquoted : "", shell_argv[i] ? shell_argv[i] : "")) { printf ("Position %d, returned argument (%s) does not match original (%s)\n", i, shell_argv[i], unquoted); dbus_free (unquoted); return FALSE; } dbus_free (unquoted); if (shell_argv[i]) printf ("Argument %d = %s\n", i, shell_argv[i]); } dbus_free_string_array (shell_argv); } _dbus_string_free (&str); return TRUE; }
/** * _dbus_shell_parse_argv: * * Parses a command line into an argument vector, in much the same way * the shell would, but without many of the expansions the shell would * perform (variable expansion, globs, operators, filename expansion, * etc. are not supported). The results are defined to be the same as * those you would get from a UNIX98 /bin/sh, as long as the input * contains none of the unsupported shell expansions. If the input * does contain such expansions, they are passed through * literally. Free the returned vector with dbus_free_string_array(). * * @command_line: command line to parse * @argcp: return location for number of args * @argvp: return location for array of args * @error: error information **/ dbus_bool_t _dbus_shell_parse_argv (const char *command_line, int *argcp, char ***argvp, DBusError *error) { /* Code based on poptParseArgvString() from libpopt */ int argc = 0; char **argv = NULL; DBusList *tokens = NULL; int i; DBusList *tmp_list; if (!command_line) { _dbus_verbose ("Command line is NULL\n"); return FALSE; } tokens = tokenize_command_line (command_line, error); if (tokens == NULL) { _dbus_verbose ("No tokens for command line '%s'\n", command_line); return FALSE; } /* Because we can't have introduced any new blank space into the * tokens (we didn't do any new expansions), we don't need to * perform field splitting. If we were going to honor IFS or do any * expansions, we would have to do field splitting on each word * here. Also, if we were going to do any expansion we would need to * remove any zero-length words that didn't contain quotes * originally; but since there's no expansion we know all words have * nonzero length, unless they contain quotes. * * So, we simply remove quotes, and don't do any field splitting or * empty word removal, since we know there was no way to introduce * such things. */ argc = _dbus_list_get_length (&tokens); argv = dbus_new (char *, argc + 1); if (!argv) { _DBUS_SET_OOM (error); goto error; } i = 0; tmp_list = tokens; while (tmp_list) { argv[i] = _dbus_shell_unquote (tmp_list->data); if (!argv[i]) { int j; for (j = 0; j < i; j++) dbus_free(argv[j]); dbus_free (argv); _DBUS_SET_OOM (error); goto error; } tmp_list = _dbus_list_get_next_link (&tokens, tmp_list); ++i; } argv[argc] = NULL; _dbus_list_foreach (&tokens, (DBusForeachFunction) dbus_free, NULL); _dbus_list_clear (&tokens); if (argcp) *argcp = argc; if (argvp) *argvp = argv; else dbus_free_string_array (argv); return TRUE; error: _dbus_list_foreach (&tokens, (DBusForeachFunction) dbus_free, NULL); _dbus_list_clear (&tokens); return FALSE; }
static void shutdown_uninitialized_locks (void *data) { _dbus_list_clear (&uninitialized_mutex_list); _dbus_list_clear (&uninitialized_condvar_list); }
static dbus_bool_t init_uninitialized_locks (void) { DBusList *link; _dbus_assert (thread_init_generation != _dbus_current_generation); link = uninitialized_mutex_list; while (link != NULL) { DBusMutex **mp; mp = (DBusMutex **)link->data; _dbus_assert (*mp == _DBUS_DUMMY_MUTEX); *mp = _dbus_mutex_new (); if (*mp == NULL) goto fail_mutex; link = _dbus_list_get_next_link (&uninitialized_mutex_list, link); } link = uninitialized_condvar_list; while (link != NULL) { DBusCondVar **cp; cp = (DBusCondVar **)link->data; _dbus_assert (*cp == _DBUS_DUMMY_CONDVAR); *cp = _dbus_condvar_new (); if (*cp == NULL) goto fail_condvar; link = _dbus_list_get_next_link (&uninitialized_condvar_list, link); } _dbus_list_clear (&uninitialized_mutex_list); _dbus_list_clear (&uninitialized_condvar_list); if (!_dbus_register_shutdown_func (shutdown_uninitialized_locks, NULL)) goto fail_condvar; return TRUE; fail_condvar: link = uninitialized_condvar_list; while (link != NULL) { DBusCondVar **cp; cp = (DBusCondVar **)link->data; if (*cp != _DBUS_DUMMY_CONDVAR) _dbus_condvar_free (*cp); else break; *cp = _DBUS_DUMMY_CONDVAR; link = _dbus_list_get_next_link (&uninitialized_condvar_list, link); } fail_mutex: link = uninitialized_mutex_list; while (link != NULL) { DBusMutex **mp; mp = (DBusMutex **)link->data; if (*mp != _DBUS_DUMMY_MUTEX) _dbus_mutex_free (*mp); else break; *mp = _DBUS_DUMMY_MUTEX; link = _dbus_list_get_next_link (&uninitialized_mutex_list, link); } return FALSE; }