static void randomly_set_extreme_ints (const DBusString *orig_data, DBusString *mutated) { int i; int byte_order; const char *d; dbus_uint32_t orig; static int which = 0; unsigned int extreme_ints[] = { _DBUS_INT_MAX, _DBUS_UINT_MAX, _DBUS_INT_MAX - 1, _DBUS_UINT_MAX - 1, _DBUS_INT_MAX - 2, _DBUS_UINT_MAX - 2, _DBUS_INT_MAX - 17, _DBUS_UINT_MAX - 17, _DBUS_INT_MAX / 2, _DBUS_INT_MAX / 3, _DBUS_UINT_MAX / 2, _DBUS_UINT_MAX / 3, 0, 1, 2, 3, (unsigned int) -1, (unsigned int) -2, (unsigned int) -3 }; if (orig_data != mutated) { _dbus_string_set_length (mutated, 0); if (!_dbus_string_copy (orig_data, 0, mutated, 0)) _dbus_assert_not_reached ("out of mem"); } if (_dbus_string_get_length (mutated) < 12) return; d = _dbus_string_get_const_data (mutated); if (!(*d == DBUS_LITTLE_ENDIAN || *d == DBUS_BIG_ENDIAN)) return; byte_order = *d; i = random_int_in_range (4, _dbus_string_get_length (mutated) - 8); i = _DBUS_ALIGN_VALUE (i, 4); orig = _dbus_demarshal_uint32 (mutated, byte_order, i, NULL); which = random_int_in_range (0, _DBUS_N_ELEMENTS (extreme_ints)); _dbus_assert (which >= 0); _dbus_assert (which < _DBUS_N_ELEMENTS (extreme_ints)); _dbus_marshal_set_uint32 (mutated, byte_order, i, extreme_ints[which]); }
/* this is a little fragile since it assumes the address doesn't * already have a guid, but it shouldn't */ static char* copy_address_with_guid_appended (const DBusString *address, const DBusString *guid_hex) { DBusString with_guid; char *retval; if (!_dbus_string_init (&with_guid)) return NULL; if (!_dbus_string_copy (address, 0, &with_guid, _dbus_string_get_length (&with_guid)) || !_dbus_string_append (&with_guid, ",guid=") || !_dbus_string_copy (guid_hex, 0, &with_guid, _dbus_string_get_length (&with_guid))) { _dbus_string_free (&with_guid); return NULL; } retval = NULL; _dbus_string_steal_data (&with_guid, &retval); _dbus_string_free (&with_guid); return retval; /* may be NULL if steal_data failed */ }
/** * Tries loading the message in the given message file * and verifies that DBusMessageLoader can handle it. * * @param filename filename to load * @param expected_validity what the message has to be like to return #TRUE * @returns #TRUE if the message has the expected validity */ dbus_bool_t dbus_internal_do_not_use_try_message_file (const DBusString *filename, DBusValidity expected_validity) { DBusString data; dbus_bool_t retval; retval = FALSE; if (!_dbus_string_init (&data)) _dbus_assert_not_reached ("could not allocate string\n"); if (!dbus_internal_do_not_use_load_message_file (filename, &data)) goto failed; retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity); failed: if (!retval) { if (_dbus_string_get_length (&data) > 0) _dbus_verbose_bytes_of_string (&data, 0, _dbus_string_get_length (&data)); _dbus_warn ("Failed message loader test on %s\n", _dbus_string_get_const_data (filename)); } _dbus_string_free (&data); return retval; }
static dbus_bool_t find_next_typecode (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity) { int body_seq; int byte_seq; int base_depth; base_depth = iter->depth; restart: _dbus_assert (iter->depth == (base_depth + 0)); _dbus_string_set_length (data, 0); body_seq = iter_get_sequence (iter); if (!generate_many_bodies (iter, data, expected_validity)) return FALSE; /* Undo the "next" in generate_many_bodies */ iter_set_sequence (iter, body_seq); iter_recurse (iter); while (TRUE) { _dbus_assert (iter->depth == (base_depth + 1)); byte_seq = iter_get_sequence (iter); _dbus_assert (byte_seq <= _dbus_string_get_length (data)); if (byte_seq == _dbus_string_get_length (data)) { /* reset byte count */ iter_set_sequence (iter, 0); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 0)); iter_next (iter); /* go to the next body */ goto restart; } _dbus_assert (byte_seq < _dbus_string_get_length (data)); if (dbus_type_is_valid (_dbus_string_get_byte (data, byte_seq))) break; else iter_next (iter); } _dbus_assert (byte_seq == iter_get_sequence (iter)); _dbus_assert (byte_seq < _dbus_string_get_length (data)); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 0)); return TRUE; }
/** * Writes a struct of { byte, variant } with the given basic type. * * @param writer the writer (should be ready to write a struct) * @param type the type of the value * @param value the value as for _dbus_marshal_set_basic() * @returns #FALSE if no memory */ static dbus_bool_t write_basic_field (DBusTypeWriter *writer, int field, int type, const void *value) { DBusTypeWriter sub; DBusTypeWriter variant; int start; int padding; unsigned char field_byte; DBusString contained_type; char buf[2]; start = writer->value_pos; padding = _dbus_string_get_length (writer->value_str) - start; if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT, NULL, 0, &sub)) goto append_failed; field_byte = field; if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE, &field_byte)) goto append_failed; buf[0] = type; buf[1] = '\0'; _dbus_string_init_const_len (&contained_type, buf, 1); if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT, &contained_type, 0, &variant)) goto append_failed; if (!_dbus_type_writer_write_basic (&variant, type, value)) goto append_failed; if (!_dbus_type_writer_unrecurse (&sub, &variant)) goto append_failed; if (!_dbus_type_writer_unrecurse (writer, &sub)) goto append_failed; return TRUE; append_failed: _dbus_string_delete (writer->value_str, start, _dbus_string_get_length (writer->value_str) - start - padding); return FALSE; }
/** * Checks that the given range of the string is a valid object path * name in the D-Bus protocol. Part of the validation ensures that * the object path contains only ASCII. * * @todo this is inconsistent with most of DBusString in that * it allows a start,len range that extends past the string end. * * @todo change spec to disallow more things, such as spaces in the * path name * * @param str the string * @param start first byte index to check * @param len number of bytes to check * @returns #TRUE if the byte range exists and is a valid name */ dbus_bool_t _dbus_validate_path (const DBusString *str, int start, int len) { const unsigned char *s; const unsigned char *end; const unsigned char *last_slash; _dbus_assert (start >= 0); _dbus_assert (len >= 0); _dbus_assert (start <= _dbus_string_get_length (str)); if (len > _dbus_string_get_length (str) - start) return FALSE; if (len == 0) return FALSE; s = _dbus_string_get_const_data (str) + start; end = s + len; if (*s != '/') return FALSE; last_slash = s; ++s; while (s != end) { if (*s == '/') { if ((s - last_slash) < 2) return FALSE; /* no empty path components allowed */ last_slash = s; } else { if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s))) return FALSE; } ++s; } if ((end - last_slash) < 2 && len > 1) return FALSE; /* trailing slash not allowed unless the string is "/" */ return TRUE; }
/** * Checks that the given range of the string is a valid message type * signature in the D-Bus protocol. * * @todo this is inconsistent with most of DBusString in that * it allows a start,len range that extends past the string end. * * @param str the string * @param start first byte index to check * @param len number of bytes to check * @returns #TRUE if the byte range exists and is a valid signature */ dbus_bool_t _dbus_validate_signature (const DBusString *str, int start, int len) { _dbus_assert (start >= 0); _dbus_assert (start <= _dbus_string_get_length (str)); _dbus_assert (len >= 0); if (len > _dbus_string_get_length (str) - start) return FALSE; return _dbus_validate_signature_with_reason (str, start, len) == DBUS_VALID; }
static void test_hex_roundtrip (const unsigned char *data, int len) { DBusString orig; DBusString encoded; DBusString decoded; int end; if (len < 0) len = strlen (data); if (!_dbus_string_init (&orig)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_init (&encoded)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_init (&decoded)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_append_len (&orig, data, len)) _dbus_assert_not_reached ("couldn't append orig data"); if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0)) _dbus_assert_not_reached ("could not encode"); if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0)) _dbus_assert_not_reached ("could not decode"); _dbus_assert (_dbus_string_get_length (&encoded) == end); if (!_dbus_string_equal (&orig, &decoded)) { const char *s; printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n", _dbus_string_get_length (&orig), _dbus_string_get_length (&encoded), _dbus_string_get_length (&decoded)); printf ("Original: %s\n", data); s = _dbus_string_get_const_data (&decoded); printf ("Decoded: %s\n", s); _dbus_assert_not_reached ("original string not the same as string decoded from hex"); } _dbus_string_free (&orig); _dbus_string_free (&encoded); _dbus_string_free (&decoded); }
static void correct_header_padding (DBusHeader *header) { int unpadded_len; _dbus_assert (header->padding == 7); _dbus_string_shorten (&header->data, header->padding); unpadded_len = _dbus_string_get_length (&header->data); if (!_dbus_string_align_length (&header->data, 8)) _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated"); header->padding = _dbus_string_get_length (&header->data) - unpadded_len; }
static void run_validity_tests (const ValidityTest *tests, int n_tests, DBusValidity (* func) (const DBusString*,int,int)) { int i; for (i = 0; i < n_tests; i++) { DBusString str; DBusValidity v; _dbus_string_init_const (&str, tests[i].data); v = (*func) (&str, 0, _dbus_string_get_length (&str)); if (v != tests[i].expected) { _dbus_warn ("Improper validation result %d for '%s'\n", v, tests[i].data); _dbus_assert_not_reached ("test failed"); } ++i; } }
EXPORT_C #endif void _dbus_marshal_byteswap (const DBusString *signature, int signature_start, int old_byte_order, int new_byte_order, DBusString *value_str, int value_pos) { DBusTypeReader reader; _dbus_assert (value_pos >= 0); _dbus_assert (value_pos <= _dbus_string_get_length (value_str)); if (old_byte_order == new_byte_order) return; _dbus_type_reader_init_types_only (&reader, signature, signature_start); #ifndef __SYMBIAN32__ byteswap_body_helper (&reader, TRUE, old_byte_order, new_byte_order, _dbus_string_get_data_len (value_str, value_pos, 0), NULL); #else byteswap_body_helper (&reader, TRUE, old_byte_order, new_byte_order, (unsigned char *)_dbus_string_get_data_len (value_str, value_pos, 0), NULL); #endif }
/** * Appends a double to a DBusString. * * @param str the string * @param value the floating point value * @returns #FALSE if not enough memory or other failure. */ dbus_bool_t _dbus_string_append_double (DBusString *str, double value) { #define MAX_DOUBLE_LEN 64 /* this is completely made up :-/ */ int orig_len; char *buf; int i; orig_len = _dbus_string_get_length (str); if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN)) return FALSE; buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN); snprintf (buf, MAX_LONG_LEN, "%g", value); i = 0; while (*buf) { ++buf; ++i; } _dbus_string_shorten (str, MAX_DOUBLE_LEN - i); return TRUE; }
/** * Generates the given number of random bytes, where the bytes are * chosen from the alphanumeric ASCII subset. * * @param str the string * @param n_bytes the number of random ASCII bytes to append to string * @param error location to store reason for failure * @returns #TRUE on success, #FALSE if no memory or other failure */ dbus_bool_t _dbus_generate_random_ascii (DBusString *str, int n_bytes, DBusError *error) { static const char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; int i; int len; if (!_dbus_generate_random_bytes (str, n_bytes, error)) return FALSE; len = _dbus_string_get_length (str); i = len - n_bytes; while (i < len) { _dbus_string_set_byte (str, i, letters[_dbus_string_get_byte (str, i) % (sizeof (letters) - 1)]); ++i; } _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes, n_bytes)); return TRUE; }
/** * Appends an unsigned integer to a DBusString. * * @param str the string * @param value the integer value * @returns #FALSE if not enough memory or other failure. */ dbus_bool_t _dbus_string_append_uint (DBusString *str, unsigned long value) { /* this is wrong, but definitely on the high side. */ #define MAX_ULONG_LEN (MAX_LONG_LEN * 2) int orig_len; int i; char *buf; orig_len = _dbus_string_get_length (str); if (!_dbus_string_lengthen (str, MAX_ULONG_LEN)) return FALSE; buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN); snprintf (buf, MAX_ULONG_LEN, "%lu", value); i = 0; while (*buf) { ++buf; ++i; } _dbus_string_shorten (str, MAX_ULONG_LEN - i); return TRUE; }
/** * Parses an unsigned integer contained in a DBusString. Either return * parameter may be #NULL if you aren't interested in it. The integer * is parsed and stored in value_return. Return parameters are not * initialized if the function returns #FALSE. * * @param str the string * @param start the byte index of the start of the integer * @param value_return return location of the integer value or #NULL * @param end_return return location of the end of the integer, or #NULL * @returns #TRUE on success */ dbus_bool_t _dbus_string_parse_uint (const DBusString *str, int start, unsigned long *value_return, int *end_return) { unsigned long v; const char *p; char *end; p = _dbus_string_get_const_data_len (str, start, _dbus_string_get_length (str) - start); end = NULL; _dbus_set_errno_to_zero (); v = strtoul (p, &end, 0); if (end == NULL || end == p || errno != 0) return FALSE; if (value_return) *value_return = v; if (end_return) *end_return = start + (end - p); return TRUE; }
/** * Parses a floating point number contained in a DBusString. Either * return parameter may be #NULL if you aren't interested in it. The * integer is parsed and stored in value_return. Return parameters are * not initialized if the function returns #FALSE. * * @param str the string * @param start the byte index of the start of the float * @param value_return return location of the float value or #NULL * @param end_return return location of the end of the float, or #NULL * @returns #TRUE on success */ dbus_bool_t _dbus_string_parse_double (const DBusString *str, int start, double *value_return, int *end_return) { double v; const char *p; char *end; p = _dbus_string_get_const_data_len (str, start, _dbus_string_get_length (str) - start); /* parsing hex works on linux but isn't portable, so intercept it * here to get uniform behavior. */ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) return FALSE; end = NULL; errno = 0; v = ascii_strtod (p, &end); if (end == NULL || end == p || errno != 0) return FALSE; if (value_return) *value_return = v; if (end_return) *end_return = start + (end - p); return TRUE; }
/** * Appends an integer to a DBusString. * * @param str the string * @param value the integer value * @returns #FALSE if not enough memory or other failure. */ dbus_bool_t _dbus_string_append_int (DBusString *str, long value) { /* this calculation is from comp.lang.c faq */ #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1) /* +1 for '-' */ int orig_len; int i; char *buf; orig_len = _dbus_string_get_length (str); if (!_dbus_string_lengthen (str, MAX_LONG_LEN)) return FALSE; buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN); snprintf (buf, MAX_LONG_LEN, "%ld", value); i = 0; while (*buf) { ++buf; ++i; } _dbus_string_shorten (str, MAX_LONG_LEN - i); return TRUE; }
static dbus_bool_t print_install_root() { DBusString runtime_prefix; if (!_dbus_string_init (&runtime_prefix)) { _dbus_assert_not_reached ("out of memory"); return FALSE; } if (!_dbus_get_install_root (&runtime_prefix)) { _dbus_assert_not_reached ("out of memory"); _dbus_string_free (&runtime_prefix); return FALSE; } if (_dbus_string_get_length (&runtime_prefix) == 0) { fprintf (stderr, "_dbus_get_install_root() failed\n"); _dbus_string_free (&runtime_prefix); return FALSE; } fprintf (stdout, "_dbus_get_install_root() returned '%s'\n", _dbus_string_get_const_data (&runtime_prefix)); _dbus_string_free (&runtime_prefix); return TRUE; }
/** * Checks that the given range of the string is a valid member name * in the D-Bus protocol. This includes a length restriction, etc., * see the specification. * * @todo this is inconsistent with most of DBusString in that * it allows a start,len range that extends past the string end. * * @param str the string * @param start first byte index to check * @param len number of bytes to check * @returns #TRUE if the byte range exists and is a valid name */ dbus_bool_t _dbus_validate_member (const DBusString *str, int start, int len) { const unsigned char *s; const unsigned char *end; const unsigned char *member; _dbus_assert (start >= 0); _dbus_assert (len >= 0); _dbus_assert (start <= _dbus_string_get_length (str)); if (len > _dbus_string_get_length (str) - start) return FALSE; if (len > DBUS_MAXIMUM_NAME_LENGTH) return FALSE; if (len == 0) return FALSE; member = _dbus_string_get_const_data (str) + start; end = member + len; s = member; /* check special cases of first char so it doesn't have to be done * in the loop. Note we know len > 0 */ if (_DBUS_UNLIKELY (!VALID_INITIAL_NAME_CHARACTER (*s))) return FALSE; else ++s; while (s != end) { if (_DBUS_UNLIKELY (!VALID_NAME_CHARACTER (*s))) { return FALSE; } ++s; } return TRUE; }
static dbus_bool_t create_unique_client_name (BusRegistry *registry, DBusString *str) { /* We never want to use the same unique client name twice, because * we want to guarantee that if you send a message to a given unique * name, you always get the same application. So we use two numbers * for INT_MAX * INT_MAX combinations, should be pretty safe against * wraparound. */ /* FIXME these should be in BusRegistry rather than static vars */ static int next_major_number = 0; static int next_minor_number = 0; int len; len = _dbus_string_get_length (str); while (TRUE) { /* start out with 1-0, go to 1-1, 1-2, 1-3, * up to 1-MAXINT, then 2-0, 2-1, etc. */ if (next_minor_number <= 0) { next_major_number += 1; next_minor_number = 0; if (next_major_number <= 0) _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added"); } _dbus_assert (next_major_number > 0); _dbus_assert (next_minor_number >= 0); /* appname:MAJOR-MINOR */ if (!_dbus_string_append (str, ":")) return FALSE; if (!_dbus_string_append_int (str, next_major_number)) return FALSE; if (!_dbus_string_append (str, ".")) return FALSE; if (!_dbus_string_append_int (str, next_minor_number)) return FALSE; next_minor_number += 1; /* Check if a client with the name exists */ if (bus_registry_lookup (registry, str) == NULL) break; /* drop the number again, try the next one. */ _dbus_string_set_length (str, len); } return TRUE; }
/** * Hex-encode a UUID. * * @param uuid the uuid * @param encoded string to append hex uuid to * @returns #FALSE if no memory */ dbus_bool_t _dbus_uuid_encode (const DBusGUID *uuid, DBusString *encoded) { DBusString binary; _dbus_string_init_const_len (&binary, uuid->as_bytes, DBUS_UUID_LENGTH_BYTES); return _dbus_string_hex_encode (&binary, 0, encoded, _dbus_string_get_length (encoded)); }
dbus_bool_t _dbus_path_is_absolute (const DBusString *filename) { if (_dbus_string_get_length (filename) > 0) return _dbus_string_get_byte (filename, 0) == '/'; else return FALSE; }
static dbus_bool_t generate_byte_changed (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity) { int byte_seq; int v_BYTE; /* This is a little convoluted to make the bodies the * outer loop and each byte of each body the inner * loop */ restart: if (!generate_many_bodies (iter, data, expected_validity)) return FALSE; iter_recurse (iter); byte_seq = iter_get_sequence (iter); iter_next (iter); iter_unrecurse (iter); if (byte_seq == _dbus_string_get_length (data)) { _dbus_string_set_length (data, 0); /* reset byte count */ iter_recurse (iter); iter_set_sequence (iter, 0); iter_unrecurse (iter); goto restart; } else { /* Undo the "next" in generate_many_bodies */ iter_set_sequence (iter, iter_get_sequence (iter) - 1); } _dbus_assert (byte_seq < _dbus_string_get_length (data)); v_BYTE = _dbus_string_get_byte (data, byte_seq); v_BYTE += byte_seq; /* arbitrary but deterministic change to the byte */ _dbus_string_set_byte (data, byte_seq, v_BYTE); *expected_validity = DBUS_VALIDITY_UNKNOWN; return TRUE; }
/** * sends the nonce over a given socket. Blocks while doing so. * * @param fd the file descriptor to write the nonce data to (usually a socket) * @param noncefile the noncefile location to read the nonce from * @param error contains error details if FALSE is returned * @return TRUE iff the nonce was successfully sent. Note that this does not * indicate whether the server accepted the nonce. */ dbus_bool_t _dbus_send_nonce (DBusSocket fd, const DBusString *noncefile, DBusError *error) { dbus_bool_t read_result; int send_result; DBusString nonce; _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (_dbus_string_get_length (noncefile) == 0) return FALSE; if (!_dbus_string_init (&nonce)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return FALSE; } read_result = _dbus_read_nonce (noncefile, &nonce, error); if (!read_result) { _DBUS_ASSERT_ERROR_IS_SET (error); _dbus_string_free (&nonce); return FALSE; } _DBUS_ASSERT_ERROR_IS_CLEAR (error); send_result = _dbus_write_socket (fd, &nonce, 0, _dbus_string_get_length (&nonce)); _dbus_string_free (&nonce); if (send_result == -1) { dbus_set_error (error, _dbus_error_from_system_errno (), "Failed to send nonce (fd=%" DBUS_SOCKET_FORMAT "): %s", _dbus_socket_printable (fd), _dbus_strerror_from_errno ()); return FALSE; } return TRUE; }
static dbus_bool_t generate_many_bodies_inner (DBusMessageDataIter *iter, DBusMessage **message_p) { DBusMessage *message; DBusString signature; DBusString body; char byte_order; /* Keeping this small makes things go faster */ message = dbus_message_new_method_call ("o.z.F", "/", "o.z.B", "Nah"); if (message == NULL) _dbus_assert_not_reached ("oom"); byte_order = _dbus_header_get_byte_order (&message->header); set_reply_serial (message); if (!_dbus_string_init (&signature) || !_dbus_string_init (&body)) _dbus_assert_not_reached ("oom"); if (dbus_internal_do_not_use_generate_bodies (iter_get_sequence (iter), byte_order, &signature, &body)) { const char *v_SIGNATURE; v_SIGNATURE = _dbus_string_get_const_data (&signature); if (!_dbus_header_set_field_basic (&message->header, DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE, &v_SIGNATURE)) _dbus_assert_not_reached ("oom"); if (!_dbus_string_move (&body, 0, &message->body, 0)) _dbus_assert_not_reached ("oom"); _dbus_marshal_set_uint32 (&message->header.data, BODY_LENGTH_OFFSET, _dbus_string_get_length (&message->body), byte_order); *message_p = message; } else { dbus_message_unref (message); *message_p = NULL; } _dbus_string_free (&signature); _dbus_string_free (&body); return *message_p != NULL; }
static dbus_bool_t generate_typecode_changed (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity) { int byte_seq; int typecode_seq; int base_depth; base_depth = iter->depth; restart: _dbus_assert (iter->depth == (base_depth + 0)); _dbus_string_set_length (data, 0); if (!find_next_typecode (iter, data, expected_validity)) return FALSE; iter_recurse (iter); byte_seq = iter_get_sequence (iter); _dbus_assert (byte_seq < _dbus_string_get_length (data)); iter_recurse (iter); typecode_seq = iter_get_sequence (iter); iter_next (iter); _dbus_assert (typecode_seq <= _DBUS_N_ELEMENTS (typecodes)); if (typecode_seq == _DBUS_N_ELEMENTS (typecodes)) { _dbus_assert (iter->depth == (base_depth + 2)); iter_set_sequence (iter, 0); /* reset typecode sequence */ iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 1)); iter_next (iter); /* go to the next byte_seq */ iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 0)); goto restart; } _dbus_assert (iter->depth == (base_depth + 2)); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 1)); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 0)); #if 0 printf ("Changing byte %d in message %d to %c\n", byte_seq, iter_get_sequence (iter), typecodes[typecode_seq]); #endif _dbus_string_set_byte (data, byte_seq, typecodes[typecode_seq]); *expected_validity = DBUS_VALIDITY_UNKNOWN; return TRUE; }
static void check_two_pid_descriptors (const DBusString *pid_fd, const char *extra_arg) { if (_dbus_string_get_length (pid_fd) > 0) { fprintf (stderr, "--%s specified but printing pid to %s already requested\n", extra_arg, _dbus_string_get_const_data (pid_fd)); exit (1); } }
static void check_two_config_files (const DBusString *config_file, const char *extra_arg) { if (_dbus_string_get_length (config_file) > 0) { fprintf (stderr, "--%s specified but configuration file %s already requested\n", extra_arg, _dbus_string_get_const_data (config_file)); exit (1); } }
static void check_two_addresses (const DBusString *address, const char *extra_arg) { if (_dbus_string_get_length (address) > 0) { fprintf (stderr, "--%s specified but address %s already requested\n", extra_arg, _dbus_string_get_const_data (address)); exit (1); } }
dbus_bool_t _dbus_string_get_dirname (const DBusString *filename, DBusString *dirname) { int sep; _dbus_assert (filename != dirname); _dbus_assert (filename != NULL); _dbus_assert (dirname != NULL); /* Ignore any separators on the end */ sep = _dbus_string_get_length (filename); if (sep == 0) return _dbus_string_append (dirname, "."); /* empty string passed in */ while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/') --sep; _dbus_assert (sep >= 0); if (sep == 0) return _dbus_string_append (dirname, "/"); /* Now find the previous separator */ _dbus_string_find_byte_backward (filename, sep, '/', &sep); if (sep < 0) return _dbus_string_append (dirname, "."); /* skip multiple separators */ while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/') --sep; _dbus_assert (sep >= 0); if (sep == 0 && _dbus_string_get_byte (filename, 0) == '/') return _dbus_string_append (dirname, "/"); else return _dbus_string_copy_len (filename, 0, sep - 0, dirname, _dbus_string_get_length (dirname)); }