/** * Returns the unique ID of the server, as a newly-allocated * string which must be freed by the caller. This ID is * normally used by clients to tell when two #DBusConnection * would be equivalent (because the server address passed * to dbus_connection_open() will have the same guid in the * two cases). dbus_connection_open() can re-use an existing * connection with the same ID instead of opening a new * connection. * * This is an ID unique to each #DBusServer. Remember that * a #DBusServer represents only one mode of connecting, * so e.g. a bus daemon can listen on multiple addresses * which will mean it has multiple #DBusServer each with * their own ID. * * The ID is not a UUID in the sense of RFC4122; the details * are explained in the D-Bus specification. * * @param server the server * @returns the id of the server or #NULL if no memory */ char* dbus_server_get_id (DBusServer *server) { char *retval; _dbus_return_val_if_fail (server != NULL, NULL); SERVER_LOCK (server); retval = NULL; _dbus_string_copy_data (&server->guid_hex, &retval); SERVER_UNLOCK (server); return retval; }
BusService* bus_registry_ensure (BusRegistry *registry, const DBusString *service_name, DBusConnection *owner_connection_if_created, dbus_uint32_t flags, BusTransaction *transaction, DBusError *error) { BusService *service; _DBUS_ASSERT_ERROR_IS_CLEAR (error); _dbus_assert (owner_connection_if_created != NULL); _dbus_assert (transaction != NULL); service = _dbus_hash_table_lookup_string (registry->service_hash, _dbus_string_get_const_data (service_name)); if (service != NULL) return service; service = _dbus_mem_pool_alloc (registry->service_pool); if (service == NULL) { BUS_SET_OOM (error); return NULL; } service->registry = registry; service->refcount = 1; _dbus_verbose ("copying string %p '%s' to service->name\n", service_name, _dbus_string_get_const_data (service_name)); if (!_dbus_string_copy_data (service_name, &service->name)) { _dbus_mem_pool_dealloc (registry->service_pool, service); BUS_SET_OOM (error); return NULL; } _dbus_verbose ("copied string %p '%s' to '%s'\n", service_name, _dbus_string_get_const_data (service_name), service->name); if (!bus_driver_send_service_owner_changed (service->name, NULL, bus_connection_get_name (owner_connection_if_created), transaction, error)) { bus_service_unref (service); return NULL; } if (!bus_activation_service_created (bus_context_get_activation (registry->context), service->name, transaction, error)) { bus_service_unref (service); return NULL; } if (!bus_service_add_owner (service, owner_connection_if_created, flags, transaction, error)) { bus_service_unref (service); return NULL; } if (!_dbus_hash_table_insert_string (registry->service_hash, service->name, service)) { /* The add_owner gets reverted on transaction cancel */ BUS_SET_OOM (error); return NULL; } return service; }
/** * 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; }
/** * Initializes the base class members of DBusTransport. Chained up to * by subclasses in their constructor. The server GUID is the * globally unique ID for the server creating this connection * and will be #NULL for the client side of a connection. The GUID * is in hex format. * * @param transport the transport being created. * @param vtable the subclass vtable. * @param server_guid non-#NULL if this transport is on the server side of a connection * @param address the address of the transport * @returns #TRUE on success. */ dbus_bool_t _dbus_transport_init_base (DBusTransport *transport, const DBusTransportVTable *vtable, const DBusString *server_guid, const DBusString *address) { DBusMessageLoader *loader; DBusAuth *auth; DBusCounter *counter; char *address_copy; DBusCredentials *creds; loader = _dbus_message_loader_new (); if (loader == NULL) return FALSE; if (server_guid) auth = _dbus_auth_server_new (server_guid); else auth = _dbus_auth_client_new (); if (auth == NULL) { _dbus_message_loader_unref (loader); return FALSE; } counter = _dbus_counter_new (); if (counter == NULL) { _dbus_auth_unref (auth); _dbus_message_loader_unref (loader); return FALSE; } creds = _dbus_credentials_new (); if (creds == NULL) { _dbus_counter_unref (counter); _dbus_auth_unref (auth); _dbus_message_loader_unref (loader); return FALSE; } if (server_guid) { _dbus_assert (address == NULL); address_copy = NULL; } else { _dbus_assert (address != NULL); if (!_dbus_string_copy_data (address, &address_copy)) { _dbus_credentials_unref (creds); _dbus_counter_unref (counter); _dbus_auth_unref (auth); _dbus_message_loader_unref (loader); return FALSE; } } transport->refcount = 1; transport->vtable = vtable; transport->loader = loader; transport->auth = auth; transport->live_messages_size = counter; transport->authenticated = FALSE; transport->disconnected = FALSE; transport->is_server = (server_guid != NULL); transport->send_credentials_pending = !transport->is_server; transport->receive_credentials_pending = transport->is_server; transport->address = address_copy; transport->unix_user_function = NULL; transport->unix_user_data = NULL; transport->free_unix_user_data = NULL; transport->windows_user_function = NULL; transport->windows_user_data = NULL; transport->free_windows_user_data = NULL; transport->expected_guid = NULL; /* Try to default to something that won't totally hose the system, * but doesn't impose too much of a limitation. */ transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63; /* credentials read from socket if any */ transport->credentials = creds; _dbus_counter_set_notify (transport->live_messages_size, transport->max_live_messages_size, live_messages_size_notify, transport); if (transport->address) _dbus_verbose ("Initialized transport on address %s\n", transport->address); return TRUE; }
dbus_bool_t bus_config_parser_content (BusConfigParser *parser, const DBusString *content, DBusError *error) { DBusString content_sane; dbus_bool_t retval; retval = FALSE; if (!_dbus_string_init (&content_sane)) { BUS_SET_OOM (error); goto out; } if (!_dbus_string_copy (content, 0, &content_sane, 0)) { BUS_SET_OOM (error); goto out_content; } /* rip out white space */ _dbus_string_chop_white (&content_sane); if (_dbus_string_get_length (&content_sane) == 0) { /* optimise, there is no content */ retval = TRUE; goto out_content; } switch (parser->type) { case ELEMENT_SERVICEDIR: { char *cpath; /* copy the sane data into a char array */ if (!_dbus_string_copy_data(&content_sane, &cpath)) { BUS_SET_OOM (error); goto out_content; } /* append the dynamic char string to service dirs */ if (!_dbus_list_append (&parser->service_dirs, cpath)) { dbus_free (cpath); BUS_SET_OOM (error); goto out_content; } } break; case ELEMENT_SERVICEHELPER: { if (!_dbus_string_copy (&content_sane, 0, &parser->service_helper, 0)) { BUS_SET_OOM (error); goto out_content; } } break; case ELEMENT_USER: { if (!_dbus_string_copy (&content_sane, 0, &parser->user, 0)) { BUS_SET_OOM (error); goto out_content; } } break; case ELEMENT_TYPE: { if (!_dbus_string_copy (&content_sane, 0, &parser->bus_type, 0)) { BUS_SET_OOM (error); goto out_content; } } break; default: { /* we don't care about the others... really */ _dbus_verbose (" CONTENTS We dont care '%s' type '%i'\n", _dbus_string_get_const_data (&content_sane), parser->type); break; } } /* woot! */ retval = TRUE; out_content: _dbus_string_free (&content_sane); out: return retval; }