/* 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 */ }
static dbus_bool_t return_uuid (DBusGUID *uuid, char **uuid_p, DBusError *error) { if (uuid_p) { DBusString encoded; if (!_dbus_string_init (&encoded)) { _DBUS_SET_OOM (error); return FALSE; } if (!_dbus_uuid_encode (uuid, &encoded) || !_dbus_string_steal_data (&encoded, uuid_p)) { _DBUS_SET_OOM (error); _dbus_string_free (&encoded); return FALSE; } _dbus_string_free (&encoded); } return TRUE; }
/** * Obtains the machine UUID of the machine this process is running on. * * The returned string must be freed with dbus_free(). * * This UUID is guaranteed to remain the same until the next reboot * (unless the sysadmin foolishly changes it and screws themselves). * It will usually remain the same across reboots also, but hardware * configuration changes or rebuilding the machine could break that. * * The idea is that two processes with the same machine ID should be * able to use shared memory, UNIX domain sockets, process IDs, and other * features of the OS that require both processes to be running * on the same OS kernel instance. * * The machine ID can also be used to create unique per-machine * instances. For example, you could use it in bus names or * X selection names. * * The machine ID is preferred over the machine hostname, because * the hostname is frequently set to "localhost.localdomain" and * may also change at runtime. * * You can get the machine ID of a remote application by invoking the * method GetMachineId from interface org.freedesktop.DBus.Peer. * * If the remote application has the same machine ID as the one * returned by this function, then the remote application is on the * same machine as your application. * * The UUID is not a UUID in the sense of RFC4122; the details * are explained in the D-Bus specification. * * @returns a 32-byte-long hex-encoded UUID string, or #NULL if insufficient memory */ char* dbus_get_local_machine_id (void) { DBusString uuid; char *s; s = NULL; if (!_dbus_string_init (&uuid)) return NULL; /* The documentation says dbus_get_local_machine_id() only fails on OOM; * this can actually also fail if the D-Bus installation is faulty * (no UUID) *and* reading a new random UUID fails, but we have no way * to report that */ if (!_dbus_get_local_machine_uuid_encoded (&uuid, NULL) || !_dbus_string_steal_data (&uuid, &s)) { _dbus_string_free (&uuid); return NULL; } else { _dbus_string_free (&uuid); return s; } }
static dbus_bool_t init_session_address (void) { dbus_bool_t retval; retval = FALSE; /* First, look in the environment. This is the normal case on * freedesktop.org/Unix systems. */ get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION], "DBUS_SESSION_BUS_ADDRESS"); if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) { dbus_bool_t supported; DBusString addr; DBusError error = DBUS_ERROR_INIT; if (!_dbus_string_init (&addr)) return FALSE; supported = FALSE; /* So it's not in the environment - let's try a platform-specific method. * On MacOS, this involves asking launchd. On Windows (not specified yet) * we might do a COM lookup. * Ignore errors - if we failed, fall back to autolaunch. */ retval = _dbus_lookup_session_address (&supported, &addr, &error); if (supported && retval) { retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]); } else if (supported && !retval) { if (dbus_error_is_set(&error)) _dbus_warn ("Dynamic session lookup supported but failed: %s\n", error.message); else _dbus_warn ("Dynamic session lookup supported but failed silently\n"); } _dbus_string_free (&addr); } else retval = TRUE; if (!retval) return FALSE; /* The DBUS_SESSION_BUS_DEFAULT_ADDRESS should have really been named * DBUS_SESSION_BUS_FALLBACK_ADDRESS. */ if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) bus_connection_addresses[DBUS_BUS_SESSION] = _dbus_strdup (DBUS_SESSION_BUS_DEFAULT_ADDRESS); if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL) return FALSE; return TRUE; }
/** * Returns the signature of the single complete type starting at the * given iterator. * * For example, if the iterator is pointing at the start of "(ii)ii" * (which is "a struct of two ints, followed by an int, followed by an * int"), then "(ii)" would be returned. If the iterator is pointing at * one of the "i" then just that "i" would be returned. * * @param iter pointer to an iterator * @returns current signature; or #NULL if no memory. Should be freed with dbus_free() */ char * dbus_signature_iter_get_signature (const DBusSignatureIter *iter) { DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; DBusString str; char *ret; int pos; if (!_dbus_string_init (&str)) return NULL; pos = 0; _dbus_type_signature_next (real_iter->pos, &pos); if (!_dbus_string_append_len (&str, real_iter->pos, pos)) return NULL; if (!_dbus_string_steal_data (&str, &ret)) ret = NULL; _dbus_string_free (&str); return ret; }
/** * Obtains the machine UUID of the machine this process is running on. * * The returned string must be freed with dbus_free(). * * This UUID is guaranteed to remain the same until the next reboot * (unless the sysadmin foolishly changes it and screws themselves). * It will usually remain the same across reboots also, but hardware * configuration changes or rebuilding the machine could break that. * * The idea is that two processes with the same machine ID should be * able to use shared memory, UNIX domain sockets, process IDs, and other * features of the OS that require both processes to be running * on the same OS kernel instance. * * The machine ID can also be used to create unique per-machine * instances. For example, you could use it in bus names or * X selection names. * * The machine ID is preferred over the machine hostname, because * the hostname is frequently set to "localhost.localdomain" and * may also change at runtime. * * You can get the machine ID of a remote application by invoking the * method GetMachineId from interface org.freedesktop.DBus.Peer. * * If the remote application has the same machine ID as the one * returned by this function, then the remote application is on the * same machine as your application. * * The UUID is not a UUID in the sense of RFC4122; the details * are explained in the D-Bus specification. * * @returns a 32-byte-long hex-encoded UUID string, or #NULL if insufficient memory */ char* dbus_get_local_machine_id (void) { DBusString uuid; char *s; s = NULL; if (!_dbus_string_init (&uuid)) return NULL; if (!_dbus_get_local_machine_uuid_encoded (&uuid) || !_dbus_string_steal_data (&uuid, &s)) { _dbus_string_free (&uuid); return NULL; } else { _dbus_string_free (&uuid); return s; } }
/* This code only gets executed the first time the * config files are parsed. It is not executed * when config files are reloaded. */ static dbus_bool_t process_config_first_time_only (BusContext *context, BusConfigParser *parser, const DBusString *address, BusContextFlags flags, DBusError *error) { DBusString log_prefix; DBusList *link; DBusList **addresses; const char *user, *pidfile; char **auth_mechanisms; DBusList **auth_mechanisms_list; int len; dbus_bool_t retval; _DBUS_ASSERT_ERROR_IS_CLEAR (error); retval = FALSE; auth_mechanisms = NULL; pidfile = NULL; _dbus_init_system_log (TRUE); if (flags & BUS_CONTEXT_FLAG_SYSTEMD_ACTIVATION) context->systemd_activation = TRUE; else context->systemd_activation = FALSE; /* Check for an existing pid file. Of course this is a race; * we'd have to use fcntl() locks on the pid file to * avoid that. But we want to check for the pid file * before overwriting any existing sockets, etc. */ if (flags & BUS_CONTEXT_FLAG_WRITE_PID_FILE) pidfile = bus_config_parser_get_pidfile (parser); if (pidfile != NULL) { DBusString u; DBusStat stbuf; _dbus_string_init_const (&u, pidfile); if (_dbus_stat (&u, &stbuf, NULL)) { #ifdef DBUS_CYGWIN DBusString p; long /* int */ pid; _dbus_string_init (&p); _dbus_file_get_contents(&p, &u, NULL); _dbus_string_parse_int(&p, 0, &pid, NULL); _dbus_string_free(&p); if ((kill((int)pid, 0))) { dbus_set_error(NULL, DBUS_ERROR_FILE_EXISTS, "pid %ld not running, removing stale pid file\n", pid); _dbus_delete_file(&u, NULL); } else { #endif dbus_set_error (error, DBUS_ERROR_FAILED, "The pid file \"%s\" exists, if the message bus is not running, remove this file", pidfile); goto failed; #ifdef DBUS_CYGWIN } #endif } } /* keep around the pid filename so we can delete it later */ context->pidfile = _dbus_strdup (pidfile); /* note that type may be NULL */ context->type = _dbus_strdup (bus_config_parser_get_type (parser)); if (bus_config_parser_get_type (parser) != NULL && context->type == NULL) goto oom; user = bus_config_parser_get_user (parser); if (user != NULL) { context->user = _dbus_strdup (user); if (context->user == NULL) goto oom; } /* Set up the prefix for syslog messages */ if (!_dbus_string_init (&log_prefix)) goto oom; if (context->type && !strcmp (context->type, "system")) { if (!_dbus_string_append (&log_prefix, "[system] ")) goto oom; } else if (context->type && !strcmp (context->type, "session")) { DBusCredentials *credentials; credentials = _dbus_credentials_new_from_current_process (); if (!credentials) goto oom; if (!_dbus_string_append (&log_prefix, "[session ")) { _dbus_credentials_unref (credentials); goto oom; } if (!_dbus_credentials_to_string_append (credentials, &log_prefix)) { _dbus_credentials_unref (credentials); goto oom; } if (!_dbus_string_append (&log_prefix, "] ")) { _dbus_credentials_unref (credentials); goto oom; } _dbus_credentials_unref (credentials); } if (!_dbus_string_steal_data (&log_prefix, &context->log_prefix)) goto oom; _dbus_string_free (&log_prefix); /* Build an array of auth mechanisms */ auth_mechanisms_list = bus_config_parser_get_mechanisms (parser); len = _dbus_list_get_length (auth_mechanisms_list); if (len > 0) { int i; auth_mechanisms = dbus_new0 (char*, len + 1); if (auth_mechanisms == NULL) goto oom; i = 0; link = _dbus_list_get_first_link (auth_mechanisms_list); while (link != NULL) { auth_mechanisms[i] = _dbus_strdup (link->data); if (auth_mechanisms[i] == NULL) goto oom; link = _dbus_list_get_next_link (auth_mechanisms_list, link); i += 1; } }
static dbus_bool_t parse_key_value (BusDesktopFileParser *parser, DBusError *error) { int line_end; int key_start, key_end; int value_start; int p; char *value, *tmp; DBusString key; BusDesktopFileLine *line; _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end)) line_end = parser->len; p = parser->pos; key_start = p; while (p < line_end && (valid[_dbus_string_get_byte (&parser->data, p)] & VALID_KEY_CHAR)) p++; key_end = p; if (key_start == key_end) { report_error (parser, "Empty key name", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error); parser_free (parser); return FALSE; } /* We ignore locales for now */ if (p < line_end && _dbus_string_get_byte (&parser->data, p) == '[') { if (line_end == parser->len) parser->pos = parser->len; else parser->pos = line_end + 1; parser->line_num += 1; return TRUE; } /* Skip space before '=' */ while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ') p++; if (p < line_end && _dbus_string_get_byte (&parser->data, p) != '=') { report_error (parser, "Invalid characters in key name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error); parser_free (parser); return FALSE; } if (p == line_end) { report_error (parser, "No '=' in key/value pair", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error); parser_free (parser); return FALSE; } /* Skip the '=' */ p++; /* Skip space after '=' */ while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ') p++; value_start = p; value = unescape_string (parser, &parser->data, value_start, line_end, error); if (value == NULL) { parser_free (parser); return FALSE; } line = new_line (parser); if (line == NULL) { parser_free (parser); return FALSE; } if (!_dbus_string_init (&key)) { parser_free (parser); return FALSE; } if (!_dbus_string_copy_len (&parser->data, key_start, key_end - key_start, &key, 0)) { parser_free (parser); return FALSE; } if (!_dbus_string_steal_data (&key, &tmp)) { parser_free (parser); return FALSE; } _dbus_string_free (&key); line->key = tmp; line->value = value; if (line_end == parser->len) parser->pos = parser->len; else parser->pos = line_end + 1; parser->line_num += 1; return TRUE; }
/** * @ingroup DBusStringInternals * Unit test for DBusString. * * @todo Need to write tests for _dbus_string_copy() and * _dbus_string_move() moving to/from each of start/middle/end of a * string. Also need tests for _dbus_string_move_len () * * @returns #TRUE on success. */ dbus_bool_t _dbus_string_test (void) { DBusString str; DBusString other; int i, end; long v; double d; int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 }; char *s; dbus_unichar_t ch; i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); set_max_length (&str, lens[i]); test_max_len (&str, lens[i]); _dbus_string_free (&str); ++i; } /* Test shortening and setting length */ i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { int j; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); set_max_length (&str, lens[i]); if (!_dbus_string_set_length (&str, lens[i])) _dbus_assert_not_reached ("failed to set string length"); j = lens[i]; while (j > 0) { _dbus_assert (_dbus_string_get_length (&str) == j); if (j > 0) { _dbus_string_shorten (&str, 1); _dbus_assert (_dbus_string_get_length (&str) == (j - 1)); } --j; } _dbus_string_free (&str); ++i; } /* Test equality */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("oom"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("oom"); _dbus_string_init_const (&other, "H"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1)); _dbus_string_init_const (&other, "Hello"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5)); _dbus_string_init_const (&other, "World"); _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11)); _dbus_string_free (&str); /* Test appending data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); i = 0; while (i < 10) { if (!_dbus_string_append (&str, "a")) _dbus_assert_not_reached ("failed to append string to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1); if (!_dbus_string_append_byte (&str, 'b')) _dbus_assert_not_reached ("failed to append byte to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2); ++i; } _dbus_string_free (&str); /* Check steal_data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_steal_data (&str, &s)) _dbus_assert_not_reached ("failed to steal data"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (((int)strlen (s)) == i); dbus_free (s); /* Check move */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_move (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 2); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_string_free (&other); /* Check copy */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_copy (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello World")); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello WorldHello World")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check replace */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 0, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not replace"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World")); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 5, 1)) _dbus_assert_not_reached ("could not replace center space"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorld")); if (!_dbus_string_replace_len (&str, 1, 1, &other, _dbus_string_get_length (&other) - 1, 1)) _dbus_assert_not_reached ("could not replace end character"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorle")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check append/get unichar */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); ch = 0; if (!_dbus_string_append_unichar (&str, 0xfffc)) _dbus_assert_not_reached ("failed to append unichar"); _dbus_string_get_unichar (&str, 0, &ch, &i); _dbus_assert (ch == 0xfffc); _dbus_assert (i == _dbus_string_get_length (&str)); _dbus_string_free (&str); /* Check insert/set/get byte */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("failed to append Hello"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o'); _dbus_string_set_byte (&str, 1, 'q'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q'); if (!_dbus_string_insert_bytes (&str, 0, 1, 255)) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z')) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W')) _dbus_assert_not_reached ("can't insert byte"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 255); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q'); _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o'); _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W'); _dbus_string_free (&str); /* Check append/parse int/double */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_int (&str, 27)) _dbus_assert_not_reached ("failed to append int"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_int (&str, 0, &v, &end)) _dbus_assert_not_reached ("failed to parse int"); _dbus_assert (v == 27); _dbus_assert (end == i); _dbus_string_free (&str); if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_double (&str, 50.3)) _dbus_assert_not_reached ("failed to append float"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_double (&str, 0, &d, &end)) _dbus_assert_not_reached ("failed to parse float"); _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6)); _dbus_assert (end == i); _dbus_string_free (&str); /* Test find */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("couldn't append to string"); if (!_dbus_string_find (&str, 0, "He", &i)) _dbus_assert_not_reached ("didn't find 'He'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "Hello", &i)) _dbus_assert_not_reached ("didn't find 'Hello'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "ello", &i)) _dbus_assert_not_reached ("didn't find 'ello'"); _dbus_assert (i == 1); if (!_dbus_string_find (&str, 0, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (!_dbus_string_find (&str, 2, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (_dbus_string_find (&str, 4, "lo", &i)) _dbus_assert_not_reached ("did find 'lo'"); if (!_dbus_string_find (&str, 0, "l", &i)) _dbus_assert_not_reached ("didn't find 'l'"); _dbus_assert (i == 2); if (!_dbus_string_find (&str, 0, "H", &i)) _dbus_assert_not_reached ("didn't find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "", &i)) _dbus_assert_not_reached ("didn't find ''"); _dbus_assert (i == 0); if (_dbus_string_find (&str, 0, "Hello!", NULL)) _dbus_assert_not_reached ("Did find 'Hello!'"); if (_dbus_string_find (&str, 0, "Oh, Hello", NULL)) _dbus_assert_not_reached ("Did find 'Oh, Hello'"); if (_dbus_string_find (&str, 0, "ill", NULL)) _dbus_assert_not_reached ("Did find 'ill'"); if (_dbus_string_find (&str, 0, "q", NULL)) _dbus_assert_not_reached ("Did find 'q'"); if (!_dbus_string_find_to (&str, 0, 2, "He", NULL)) _dbus_assert_not_reached ("Didn't find 'He'"); if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) _dbus_assert_not_reached ("Did find 'Hello'"); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) _dbus_assert_not_reached ("Did not find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) _dbus_assert_not_reached ("Did not find 'o'"); _dbus_assert (i == _dbus_string_get_length (&str) - 1); if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i)) _dbus_assert_not_reached ("Did find 'o'"); _dbus_assert (i == -1); if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) _dbus_assert_not_reached ("Did find 'e'"); _dbus_assert (i == -1); if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) _dbus_assert_not_reached ("Didn't find 'e'"); _dbus_assert (i == 1); _dbus_string_free (&str); /* Hex encoding */ _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0)) _dbus_assert_not_reached ("deccoded bogus hex string with no error"); _dbus_assert (end == 8); _dbus_string_free (&other); test_roundtrips (test_hex_roundtrip); _dbus_string_free (&str); { int found, found_len; _dbus_string_init_const (&str, "012\r\n567\n90"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2) _dbus_assert_not_reached ("Did not find '\\r\\n'"); if (found != 3 || found_len != 2) _dbus_assert_not_reached ("invalid return values"); if (!_dbus_string_find_eol (&str, 5, &found, &found_len)) _dbus_assert_not_reached ("Did not find '\\n'"); if (found != 8 || found_len != 1) _dbus_assert_not_reached ("invalid return values"); if (_dbus_string_find_eol (&str, 9, &found, &found_len)) _dbus_assert_not_reached ("Found not expected '\\n'"); else if (found != 11 || found_len != 0) _dbus_assert_not_reached ("invalid return values '\\n'"); found = -1; found_len = -1; _dbus_string_init_const (&str, ""); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found an eol in an empty string"); _dbus_assert (found == 0); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar"); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found eol in string that lacks one"); _dbus_assert (found == 6); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar\n"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("did not find eol in string that has one at end"); _dbus_assert (found == 6); _dbus_assert (found_len == 1); } { DBusString line; #define FIRST_LINE "this is a line" #define SECOND_LINE "this is a second line" /* third line is empty */ #define THIRD_LINE "" #define FOURTH_LINE "this is a fourth line" if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&line)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop first line"); _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop second line"); _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop third line"); _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop fourth line"); _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE)); _dbus_string_free (&str); _dbus_string_free (&line); } { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); for (i = 0; i < 10000; i++) if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz")) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_set_length (&str, 10)) _dbus_assert_not_reached ("failed to set length"); /* actually compact */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact after set_length"); /* peek inside to make sure it worked */ if (((DBusRealString *)&str)->allocated > 30) _dbus_assert_not_reached ("compacting string didn't do anything"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after compact"); /* compact nothing */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact 2nd time"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after 2nd compact"); /* and make sure it still works...*/ if (!_dbus_string_append (&str, "123456")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content after append"); /* after growing automatically, this should do nothing */ if (!_dbus_string_compact (&str, 20000)) _dbus_assert_not_reached ("failed to compact after grow"); /* but this one will do something */ if (!_dbus_string_compact (&str, 0)) _dbus_assert_not_reached ("failed to compact after grow"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content"); if (!_dbus_string_append (&str, "!@#$%")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%")) _dbus_assert_not_reached ("unexpected content"); _dbus_string_free (&str); } { const char two_strings[] = "one\ttwo"; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, two_strings)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_split_on_byte (&str, '\t', &other)) _dbus_assert_not_reached ("no memory or delimiter not found"); if (strcmp (_dbus_string_get_data (&str), "one") != 0) _dbus_assert_not_reached ("left side after split on tab is wrong"); if (strcmp (_dbus_string_get_data (&other), "two") != 0) _dbus_assert_not_reached ("right side after split on tab is wrong"); _dbus_string_free (&str); _dbus_string_free (&other); } return TRUE; }
void _dbus_set_error_valist (DBusError *error, const char *name, const char *format, va_list args) { DBusRealError *real; DBusString str; _dbus_assert (name != NULL); if (error == NULL) return; _dbus_assert (error->name == NULL); _dbus_assert (error->message == NULL); if (!_dbus_string_init (&str)) goto nomem; if (format == NULL) { if (!_dbus_string_append (&str, message_from_error (name))) { _dbus_string_free (&str); goto nomem; } } else { if (!_dbus_string_append_printf_valist (&str, format, args)) { _dbus_string_free (&str); goto nomem; } } real = (DBusRealError *)error; if (!_dbus_string_steal_data (&str, &real->message)) { _dbus_string_free (&str); goto nomem; } _dbus_string_free (&str); real->name = _dbus_strdup (name); if (real->name == NULL) { dbus_free (real->message); real->message = NULL; goto nomem; } real->const_message = FALSE; return; nomem: _DBUS_SET_OOM (error); }
/** * Assigns an error name and message to a DBusError. * Does nothing if error is #NULL. * * The format may be #NULL, which means a (pretty much useless) * default message will be deduced from the name. This is not a good * idea, just go ahead and provide a useful error message. It won't * hurt you. * * If no memory can be allocated for the error message, * an out-of-memory error message will be set instead. * * @param error the error.or #NULL * @param name the error name * @param format printf-style format string. */ void dbus_set_error (DBusError *error, const char *name, const char *format, ...) { DBusRealError *real; DBusString str; va_list args; if (error == NULL) return; /* it's a bug to pile up errors */ _dbus_return_if_error_is_set (error); _dbus_return_if_fail (name != NULL); _dbus_assert (error->name == NULL); _dbus_assert (error->message == NULL); if (!_dbus_string_init (&str)) goto nomem; if (format == NULL) { if (!_dbus_string_append (&str, message_from_error (name))) { _dbus_string_free (&str); goto nomem; } } else { va_start (args, format); if (!_dbus_string_append_printf_valist (&str, format, args)) { _dbus_string_free (&str); va_end (args); goto nomem; } va_end (args); } real = (DBusRealError *)error; if (!_dbus_string_steal_data (&str, &real->message)) { _dbus_string_free (&str); goto nomem; } _dbus_string_free (&str); real->name = _dbus_strdup (name); if (real->name == NULL) { dbus_free (real->message); real->message = NULL; goto nomem; } real->const_message = FALSE; return; nomem: _DBUS_SET_OOM (error); }
static int run_session (const char *dbus_daemon, const char *config_file, char *bus_address, char **argv, int prog_arg) { char *dbus_daemon_argv[3]; int ret = 127; HANDLE server_handle = NULL; HANDLE app_handle = NULL; DWORD exit_code; DBusString argv_strings[4]; DBusString address; char **env = NULL; DBusHashTable *env_table = NULL; long sec,usec; dbus_bool_t result = TRUE; char *key = NULL; char *value = NULL; if (!_dbus_string_init (&argv_strings[0])) result = FALSE; if (!_dbus_string_init (&argv_strings[1])) result = FALSE; if (!_dbus_string_init (&argv_strings[2])) result = FALSE; if (!_dbus_string_init (&address)) result = FALSE; if (!result) goto out; /* run dbus daemon */ _dbus_get_real_time (&sec, &usec); /* On Windows it's difficult to make use of --print-address to * convert a listenable address into a connectable address, so instead * we tell the temporary dbus-daemon to use the Windows autolaunch * mechanism, with a unique scope that is shared by this dbus-daemon, * the app process that defines its lifetime, and any other child * processes they might have. */ _dbus_string_append_printf (&address, "autolaunch:scope=dbus-tmp-session-%ld%ld-" DBUS_PID_FORMAT, sec, usec, _dbus_getpid ()); _dbus_string_append_printf (&argv_strings[0], "%s", dbus_daemon); if (config_file != NULL) _dbus_string_append_printf (&argv_strings[1], "--config-file=%s", config_file); else _dbus_string_append_printf (&argv_strings[1], "--session"); _dbus_string_append_printf (&argv_strings[2], "--address=%s", _dbus_string_get_const_data (&address)); dbus_daemon_argv[0] = _dbus_string_get_data (&argv_strings[0]); dbus_daemon_argv[1] = _dbus_string_get_data (&argv_strings[1]); dbus_daemon_argv[2] = _dbus_string_get_data (&argv_strings[2]); dbus_daemon_argv[3] = NULL; server_handle = _dbus_spawn_program (dbus_daemon, dbus_daemon_argv, NULL); if (!server_handle) { _dbus_win_stderr_win_error (me, "Could not start dbus daemon", GetLastError ()); goto out; } /* run app */ env = _dbus_get_environment (); env_table = _dbus_hash_table_new (DBUS_HASH_STRING, dbus_free, dbus_free); if (!_dbus_hash_table_from_array (env_table, env, '=')) { goto out; } /* replace DBUS_SESSION_BUS_ADDRESS in environment */ if (!_dbus_string_steal_data (&address, &value)) goto out; key = _dbus_strdup ("DBUS_SESSION_BUS_ADDRESS"); if (key == NULL) goto out; if (_dbus_hash_table_insert_string (env_table, key, value)) { /* env_table took ownership, do not free separately */ key = NULL; value = NULL; } else { /* we still own key and value, the cleanup code will free them */ goto out; } _dbus_hash_table_remove_string (env_table, "DBUS_STARTER_ADDRESS"); _dbus_hash_table_remove_string (env_table, "DBUS_STARTER_BUS_TYPE"); _dbus_hash_table_remove_string (env_table, "DBUS_SESSION_BUS_PID"); _dbus_hash_table_remove_string (env_table, "DBUS_SESSION_BUS_WINDOWID"); dbus_free_string_array (env); env = _dbus_hash_table_to_array (env_table, '='); if (!env) goto out; app_handle = _dbus_spawn_program (argv[prog_arg], argv + prog_arg, env); if (!app_handle) { _dbus_win_stderr_win_error (me, "unable to start child process", GetLastError ()); goto out; } WaitForSingleObject (app_handle, INFINITE); if (!GetExitCodeProcess (app_handle, &exit_code)) { _dbus_win_stderr_win_error (me, "could not fetch exit code", GetLastError ()); goto out; } ret = exit_code; out: TerminateProcess (server_handle, 0); if (server_handle != NULL) CloseHandle (server_handle); if (app_handle != NULL) CloseHandle (app_handle); _dbus_string_free (&argv_strings[0]); _dbus_string_free (&argv_strings[1]); _dbus_string_free (&argv_strings[2]); _dbus_string_free (&address); dbus_free_string_array (env); if (env_table != NULL) _dbus_hash_table_unref (env_table); dbus_free (key); dbus_free (value); return ret; }
/* This code only gets executed the first time the * config files are parsed. It is not executed * when config files are reloaded. */ static dbus_bool_t process_config_first_time_only (BusContext *context, BusConfigParser *parser, DBusError *error) { DBusString log_prefix; DBusList *link; DBusList **addresses; const char *user, *pidfile; char **auth_mechanisms; DBusList **auth_mechanisms_list; int len; dbus_bool_t retval; _DBUS_ASSERT_ERROR_IS_CLEAR (error); retval = FALSE; auth_mechanisms = NULL; /* Check for an existing pid file. Of course this is a race; * we'd have to use fcntl() locks on the pid file to * avoid that. But we want to check for the pid file * before overwriting any existing sockets, etc. */ pidfile = bus_config_parser_get_pidfile (parser); if (pidfile != NULL) { DBusString u; DBusStat stbuf; _dbus_string_init_const (&u, pidfile); if (_dbus_stat (&u, &stbuf, NULL)) { dbus_set_error (error, DBUS_ERROR_FAILED, "The pid file \"%s\" exists, if the message bus is not running, remove this file", pidfile); goto failed; } } /* keep around the pid filename so we can delete it later */ context->pidfile = _dbus_strdup (pidfile); /* note that type may be NULL */ context->type = _dbus_strdup (bus_config_parser_get_type (parser)); if (bus_config_parser_get_type (parser) != NULL && context->type == NULL) goto oom; user = bus_config_parser_get_user (parser); if (user != NULL) { context->user = _dbus_strdup (user); if (context->user == NULL) goto oom; } /* Set up the prefix for syslog messages */ if (!_dbus_string_init (&log_prefix)) goto oom; if (context->type && !strcmp (context->type, "system")) { if (!_dbus_string_append (&log_prefix, "[system] ")) goto oom; } else if (context->type && !strcmp (context->type, "session")) { DBusCredentials *credentials; credentials = _dbus_credentials_new_from_current_process (); if (!credentials) goto oom; if (!_dbus_string_append (&log_prefix, "[session ")) goto oom; if (!_dbus_credentials_to_string_append (credentials, &log_prefix)) goto oom; if (!_dbus_string_append (&log_prefix, "] ")) goto oom; _dbus_credentials_unref (credentials); } if (!_dbus_string_steal_data (&log_prefix, &context->log_prefix)) goto oom; _dbus_string_free (&log_prefix); /* Build an array of auth mechanisms */ auth_mechanisms_list = bus_config_parser_get_mechanisms (parser); len = _dbus_list_get_length (auth_mechanisms_list); if (len > 0) { int i; auth_mechanisms = dbus_new0 (char*, len + 1); if (auth_mechanisms == NULL) goto oom; i = 0; link = _dbus_list_get_first_link (auth_mechanisms_list); while (link != NULL) { auth_mechanisms[i] = _dbus_strdup (link->data); if (auth_mechanisms[i] == NULL) goto oom; link = _dbus_list_get_next_link (auth_mechanisms_list, link); } }