/
githubmirror
/
dbus-broker
Обзор
Документация
Войти
/
githubmirror
/
dbus-broker
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v21
src/broker/controller-dbus.c
771 строка
28 KB
David Rheinsberg
dbus-broker: switch to c_assert()
10 апр 2019, 13:15
10 апр 2019, 13:15
31f60af
Код
Авторство
О чём код?
/* * D-Bus Interface of Broker Controller */ #include <c-dvar.h> #include <c-dvar-type.h> #include <c-stdaux.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include "broker/broker.h" #include "broker/controller.h" #include "bus/policy.h" #include "dbus/connection.h" #include "dbus/message.h" #include "dbus/protocol.h" #include "util/error.h" #include "util/fdlist.h" typedef struct ControllerMethod ControllerMethod; typedef int (*ControllerMethodFn) (Controller *controller, const char *path, CDVar *var_in, FDList *fds_in, CDVar *var_out); struct ControllerMethod { const char *name; ControllerMethodFn fn; const CDVarType *in; const CDVarType *out; }; /* * This macro defines a c-dvar type for DBus Messages. It evaluates to: * * ((yyyyuua(yv))X) * * ..where 'X' is provided via @_body. That is, it evaluates to the combination * of DBus Header and DBus Body for a given body-type. */ #define CONTROLLER_T_MESSAGE(_body) \ C_DVAR_T_TUPLE2( \ C_DVAR_T_TUPLE7( \ C_DVAR_T_y, \ C_DVAR_T_y, \ C_DVAR_T_y, \ C_DVAR_T_y, \ C_DVAR_T_u, \ C_DVAR_T_u, \ C_DVAR_T_ARRAY( \ C_DVAR_T_TUPLE2( \ C_DVAR_T_y, \ C_DVAR_T_v \ ) \ ) \ ), \ _body \ ) static const CDVarType controller_type_in_v[] = { C_DVAR_T_INIT( C_DVAR_T_TUPLE1( C_DVAR_T_v ) ) }; static const CDVarType controller_type_in_ohv[] = { C_DVAR_T_INIT( C_DVAR_T_TUPLE3( C_DVAR_T_o, C_DVAR_T_h, C_DVAR_T_v ) ) }; static const CDVarType controller_type_in_osu[] = { C_DVAR_T_INIT( C_DVAR_T_TUPLE3( C_DVAR_T_o, C_DVAR_T_s, C_DVAR_T_u ) ) }; static const CDVarType controller_type_out_unit[] = { C_DVAR_T_INIT( CONTROLLER_T_MESSAGE( C_DVAR_T_TUPLE0 ) ) }; static void controller_dvar_write_signature_out(CDVar *var, const CDVarType *type) { char signature[C_DVAR_TYPE_LENGTH_MAX + 1]; c_assert(type->length < sizeof(signature) + strlen("((yyyyuua(yv))())")); c_assert(type[0].element == '('); c_assert(type[1].element == '('); c_assert(type[2].element == 'y'); c_assert(type[3].element == 'y'); c_assert(type[4].element == 'y'); c_assert(type[5].element == 'y'); c_assert(type[6].element == 'u'); c_assert(type[7].element == 'u'); c_assert(type[8].element == 'a'); c_assert(type[9].element == '('); c_assert(type[10].element == 'y'); c_assert(type[11].element == 'v'); c_assert(type[12].element == ')'); c_assert(type[13].element == ')'); c_assert(type[14].element == '('); c_assert(type[type->length - 2].element == ')'); c_assert(type[type->length - 1].element == ')'); for (unsigned int i = strlen("((yyyyuua(yv))("), j = 0; i < type->length - strlen("))"); i++, j++) signature[j] = type[i].element; signature[type->length - strlen("((yyyyuua(yv))())")] = '\0'; c_dvar_write(var, "g", signature); } static int controller_dvar_verify_signature_in(const CDVarType *type, const char *signature) { if (type->length != strlen(signature) + 2) return CONTROLLER_E_UNEXPECTED_SIGNATURE; c_assert(type[0].element == '('); c_assert(type[type->length - 1].element == ')'); for (unsigned int i = 1; i + 1 < type->length; i++) if (signature[i - 1] != type[i].element) return CONTROLLER_E_UNEXPECTED_SIGNATURE; return 0; } static void controller_write_reply_header(CDVar *var, uint32_t serial, const CDVarType *type) { c_dvar_write(var, "(yyyyuu[(y<u>)(y<", c_dvar_is_big_endian(var) ? 'B' : 'l', DBUS_MESSAGE_TYPE_METHOD_RETURN, DBUS_HEADER_FLAG_NO_REPLY_EXPECTED, 1, 0, (uint32_t)-1, DBUS_MESSAGE_FIELD_REPLY_SERIAL, c_dvar_type_u, serial, DBUS_MESSAGE_FIELD_SIGNATURE, c_dvar_type_g); controller_dvar_write_signature_out(var, type); c_dvar_write(var, ">)])"); } static int controller_send_error(Connection *connection, uint32_t serial, const char *error) { _c_cleanup_(c_dvar_deinit) CDVar var = C_DVAR_INIT; _c_cleanup_(message_unrefp) Message *message = NULL; _c_cleanup_(c_freep) void *data = NULL; size_t n_data; int r; if (!serial) return 0; c_dvar_begin_write(&var, (__BYTE_ORDER == __BIG_ENDIAN), controller_type_out_unit, 1); c_dvar_write(&var, "((yyyyuu[(y<u>)(y<s>)])())", c_dvar_is_big_endian(&var) ? 'B' : 'l', DBUS_MESSAGE_TYPE_ERROR, DBUS_HEADER_FLAG_NO_REPLY_EXPECTED, 1, 0, (uint32_t)-1, DBUS_MESSAGE_FIELD_REPLY_SERIAL, c_dvar_type_u, serial, DBUS_MESSAGE_FIELD_ERROR_NAME, c_dvar_type_s, error); r = c_dvar_end_write(&var, &data, &n_data); if (r) return error_origin(r); r = message_new_outgoing(&message, data, n_data); if (r) return error_fold(r); data = NULL; r = connection_queue(connection, NULL, message); if (r) { if (r == CONNECTION_E_QUOTA || r == CONNECTION_E_UNEXPECTED_FDS) connection_close(connection); else return error_fold(r); } return 0; } static int controller_end_read(CDVar *var) { int r; r = c_dvar_end_read(var); switch (r) { case C_DVAR_E_CORRUPT_DATA: case C_DVAR_E_OUT_OF_BOUNDS: case C_DVAR_E_TYPE_MISMATCH: return CONTROLLER_E_INVALID_MESSAGE; default: return error_origin(r); } } static int controller_method_add_name(Controller *controller, const char *_path, CDVar *in_v, FDList *fds, CDVar *out_v) { const char *path, *name_str; ControllerName *name; uid_t uid; int r; c_dvar_read(in_v, "(osu)", &path, &name_str, &uid); r = controller_end_read(in_v); if (r) return error_trace(r); if (strncmp(path, "/org/bus1/DBus/Name/", strlen("/org/bus1/DBus/Name/")) != 0) return CONTROLLER_E_UNEXPECTED_PATH; if (!dbus_validate_name(name_str, strlen(name_str)) || name_str[0] == ':') return CONTROLLER_E_NAME_INVALID; r = controller_add_name(controller, &name, path, name_str, uid); if (r) return error_trace(r); c_dvar_write(out_v, "()"); return 0; } static int controller_method_add_listener(Controller *controller, const char *_path, CDVar *in_v, FDList *fds, CDVar *out_v) { _c_cleanup_(policy_registry_freep) PolicyRegistry *policy = NULL; const char *path; ControllerListener *listener; int r, listener_fd, v1, v2; uint32_t fd_index; socklen_t n; r = policy_registry_new(&policy, controller->broker->bus.seclabel); if (r) return error_fold(r); c_dvar_read(in_v, "(oh", &path, &fd_index); r = policy_registry_import(policy, in_v); if (r) return (r == POLICY_E_INVALID) ? CONTROLLER_E_LISTENER_INVALID_POLICY : error_fold(r); c_dvar_read(in_v, ")"); r = controller_end_read(in_v); if (r) return error_trace(r); if (strncmp(path, "/org/bus1/DBus/Listener/", strlen("/org/bus1/DBus/Listener/")) != 0) return CONTROLLER_E_UNEXPECTED_PATH; listener_fd = fdlist_get(fds, fd_index); if (listener_fd < 0) return CONTROLLER_E_LISTENER_INVALID_FD; n = sizeof(v1); r = getsockopt(listener_fd, SOL_SOCKET, SO_DOMAIN, &v1, &n); n = sizeof(v2); r = r ?: getsockopt(listener_fd, SOL_SOCKET, SO_TYPE, &v2, &n); if (r < 0) return (errno == EBADF || errno == ENOTSOCK) ? CONTROLLER_E_LISTENER_INVALID_FD : error_origin(-errno); if (v1 != AF_UNIX || v2 != SOCK_STREAM) return CONTROLLER_E_LISTENER_INVALID_FD; r = controller_add_listener(controller, &listener, path, listener_fd, policy); if (r) return error_trace(r); policy = NULL; fdlist_steal(fds, fd_index); c_dvar_write(out_v, "()"); return 0; } static int controller_method_listener_release(Controller *controller, const char *path, CDVar *in_v, FDList *fds, CDVar *out_v) { ControllerListener *listener; int r; c_dvar_read(in_v, "()"); r = controller_end_read(in_v); if (r) return error_trace(r); listener = controller_find_listener(controller, path); if (!listener) return CONTROLLER_E_LISTENER_NOT_FOUND; controller_listener_free(listener); c_dvar_write(out_v, "()"); return 0; } static int controller_method_name_release(Controller *controller, const char *path, CDVar *in_v, FDList *fds, CDVar *out_v) { ControllerName *name; int r; c_dvar_read(in_v, "()"); r = controller_end_read(in_v); if (r) return error_trace(r); name = controller_find_name(controller, path); if (!name) return CONTROLLER_E_NAME_NOT_FOUND; r = controller_name_reset(name); if (r) return error_trace(r); controller_name_free(name); c_dvar_write(out_v, "()"); return 0; } static int controller_method_listener_set_policy(Controller *controller, const char *path, CDVar *in_v, FDList *fds, CDVar *out_v) { _c_cleanup_(policy_registry_freep) PolicyRegistry *policy = NULL; ControllerListener *listener; int r; r = policy_registry_new(&policy, controller->broker->bus.seclabel); if (r) return error_fold(r); c_dvar_read(in_v, "("); r = policy_registry_import(policy, in_v); if (r) return (r == POLICY_E_INVALID) ? CONTROLLER_E_LISTENER_INVALID_POLICY : error_fold(r); c_dvar_read(in_v, ")"); r = controller_end_read(in_v); if (r) return error_trace(r); listener = controller_find_listener(controller, path); if (!listener) return CONTROLLER_E_LISTENER_NOT_FOUND; r = controller_listener_set_policy(listener, policy); if (r) return error_trace(r); policy = NULL; c_dvar_write(out_v, "()"); return 0; } static int controller_method_name_reset(Controller *controller, const char *path, CDVar *in_v, FDList *fds, CDVar *out_v) { ControllerName *name; int r; c_dvar_read(in_v, "()"); r = controller_end_read(in_v); if (r) return error_trace(r); name = controller_find_name(controller, path); if (!name) return CONTROLLER_E_NAME_NOT_FOUND; r = controller_name_reset(name); if (r) return error_trace(r); c_dvar_write(out_v, "()"); return 0; } static int controller_handle_method(const ControllerMethod *method, Controller *controller, const char *path, uint32_t serial, const char *signature_in, Message *message_in) { _c_cleanup_(c_dvar_deinit) CDVar var_in = C_DVAR_INIT, var_out = C_DVAR_INIT; _c_cleanup_(message_unrefp) Message *message_out = NULL; _c_cleanup_(c_freep) void *data = NULL; size_t n_data; int r; /* * Verify the input signature and prepare the input & output variants * for input parsing and output marshaling. */ r = controller_dvar_verify_signature_in(method->in, signature_in); if (r) return error_trace(r); c_dvar_begin_read(&var_in, message_in->big_endian, method->in, 1, message_in->body, message_in->n_body); c_dvar_begin_write(&var_out, (__BYTE_ORDER == __BIG_ENDIAN), method->out, 1); /* * Write the generic reply-header and then call into the method-handler * of the specific controller method. Note that the controller-methods are * responsible to call controller_end_read(var_in), to verify all read data * was correct. */ c_dvar_write(&var_out, "("); controller_write_reply_header(&var_out, serial, method->out); r = method->fn(controller, path, &var_in, message_in->fds, &var_out); if (r) return error_trace(r); c_dvar_write(&var_out, ")"); /* * The message was correctly handled and the reply is serialized in * @var_out. Lets finish it up and queue the reply on the destination. * Note that any failure in doing so must be a fatal error, so there is * no point in reverting the operation on failure. */ r = c_dvar_end_write(&var_out, &data, &n_data); if (r) return error_origin(r); /* No reply expected. */ if (!serial) return 0; r = message_new_outgoing(&message_out, data, n_data); if (r) return error_fold(r); data = NULL; r = connection_queue(&controller->connection, NULL, message_out); if (r) { if (r == CONNECTION_E_QUOTA || r == CONNECTION_E_UNEXPECTED_FDS) connection_close(&controller->connection); else return error_fold(r); } return 0; } static int controller_dispatch_controller(Controller *controller, uint32_t serial, const char *method, const char *path, const char *signature, Message *message) { static const ControllerMethod methods[] = { { "AddName", controller_method_add_name, controller_type_in_osu, controller_type_out_unit }, { "AddListener", controller_method_add_listener, controller_type_in_ohv, controller_type_out_unit }, }; for (size_t i = 0; i < C_ARRAY_SIZE(methods); i++) { if (strcmp(methods[i].name, method) != 0) continue; return controller_handle_method(&methods[i], controller, path, serial, signature, message); } return CONTROLLER_E_UNEXPECTED_METHOD; } static int controller_dispatch_name(Controller *controller, uint32_t serial, const char *method, const char *path, const char *signature, Message *message) { static const ControllerMethod methods[] = { { "Reset", controller_method_name_reset, c_dvar_type_unit, controller_type_out_unit }, { "Release", controller_method_name_release, c_dvar_type_unit, controller_type_out_unit }, }; for (size_t i = 0; i < C_ARRAY_SIZE(methods); i++) { if (strcmp(methods[i].name, method) != 0) continue; return controller_handle_method(&methods[i], controller, path, serial, signature, message); } return CONTROLLER_E_UNEXPECTED_METHOD; } static int controller_dispatch_listener(Controller *controller, uint32_t serial, const char *method, const char *path, const char *signature, Message *message) { static const ControllerMethod methods[] = { { "Release", controller_method_listener_release, c_dvar_type_unit, controller_type_out_unit }, { "SetPolicy", controller_method_listener_set_policy, controller_type_in_v, controller_type_out_unit }, }; for (size_t i = 0; i < C_ARRAY_SIZE(methods); i++) { if (strcmp(methods[i].name, method) != 0) continue; return controller_handle_method(&methods[i], controller, path, serial, signature, message); } return CONTROLLER_E_UNEXPECTED_METHOD; } static int controller_dispatch_object(Controller *controller, uint32_t serial, const char *interface, const char *member, const char *path, const char *signature, Message *message) { if (strcmp(path, "/org/bus1/DBus/Broker") == 0) { if (interface && _c_unlikely_(strcmp(interface, "org.bus1.DBus.Broker") != 0)) return CONTROLLER_E_UNEXPECTED_INTERFACE; return controller_dispatch_controller(controller, serial, member, path, signature, message); } else if (strncmp(path, "/org/bus1/DBus/Name/", strlen("/org/bus1/DBus/Name/")) == 0) { if (interface && _c_unlikely_(strcmp(interface, "org.bus1.DBus.Name") != 0)) return CONTROLLER_E_UNEXPECTED_INTERFACE; return controller_dispatch_name(controller, serial, member, path, signature, message); } else if (strncmp(path, "/org/bus1/DBus/Listener/", strlen("/org/bus1/DBus/Listener/")) == 0) { if (interface && _c_unlikely_(strcmp(interface, "org.bus1.DBus.Listener") != 0)) return CONTROLLER_E_UNEXPECTED_INTERFACE; return controller_dispatch_listener(controller, serial, member, path, signature, message); } return CONTROLLER_E_UNEXPECTED_PATH; } static int controller_dispatch_reply(Controller *controller, uint32_t serial, const char *signature, Message *message) { ControllerReload *reload; int r; reload = controller_find_reload(controller, serial); if (!reload) return CONTROLLER_E_UNEXPECTED_REPLY; if (strcmp(signature, "")) return CONTROLLER_E_UNEXPECTED_SIGNATURE; r = controller_reload_completed(reload); if (r) return error_trace(r); controller_reload_free(reload); return 0; } static int controller_dispatch_error(Controller *controller, uint32_t serial, const char *error_name, Message *message) { ControllerReload *reload; int r; reload = controller_find_reload(controller, serial); if (!reload) return CONTROLLER_E_UNEXPECTED_REPLY; if (strcmp(error_name, "org.bus1.DBus.Controller.Error.InvalidConfig")) return CONTROLLER_E_UNEXPECTED_ERROR; r = controller_reload_invalid(reload); if (r) return error_trace(r); controller_reload_free(reload); return 0; } int controller_dbus_dispatch(Controller *controller, Message *message) { Connection *connection = &controller->connection; int r; r = message_parse_metadata(message); if (r > 0) return CONTROLLER_E_PROTOCOL_VIOLATION; else if (r < 0) return error_fold(r); switch (message->header->type) { case DBUS_MESSAGE_TYPE_METHOD_CALL: r = controller_dispatch_object(controller, message_read_serial(message), message->metadata.fields.interface, message->metadata.fields.member, message->metadata.fields.path, message->metadata.fields.signature, message); break; case DBUS_MESSAGE_TYPE_METHOD_RETURN: r = controller_dispatch_reply(controller, message->metadata.fields.reply_serial, message->metadata.fields.signature, message); break; case DBUS_MESSAGE_TYPE_ERROR: r = controller_dispatch_error(controller, message->metadata.fields.reply_serial, message->metadata.fields.error_name, message); break; default: return CONTROLLER_E_PROTOCOL_VIOLATION; } switch (r) { case CONTROLLER_E_INVALID_MESSAGE: case CONTROLLER_E_UNEXPECTED_REPLY: case CONTROLLER_E_UNEXPECTED_ERROR: return CONTROLLER_E_PROTOCOL_VIOLATION; case CONTROLLER_E_UNEXPECTED_MESSAGE_TYPE: case CONTROLLER_E_UNEXPECTED_PATH: r = controller_send_error(connection, message_read_serial(message), "org.freedesktop.DBus.Error.AccessDenied"); break; case CONTROLLER_E_UNEXPECTED_INTERFACE: r = controller_send_error(connection, message_read_serial(message), "org.freedesktop.DBus.Error.UnknownInterface"); break; case CONTROLLER_E_UNEXPECTED_METHOD: r = controller_send_error(connection, message_read_serial(message), "org.freedesktop.DBus.Error.UnknownMethod"); break; case CONTROLLER_E_UNEXPECTED_SIGNATURE: r = controller_send_error(connection, message_read_serial(message), "org.freedesktop.DBus.Error.InvalidArgs"); break; case CONTROLLER_E_LISTENER_EXISTS: r = controller_send_error(connection, message_read_serial(message), "org.bus1.DBus.Listener.Exists"); break; case CONTROLLER_E_LISTENER_INVALID_FD: r = controller_send_error(connection, message_read_serial(message), "org.bus1.DBus.Listener.InvalidFD"); break; case CONTROLLER_E_LISTENER_INVALID_POLICY: r = controller_send_error(connection, message_read_serial(message), "org.bus1.DBus.Listener.InvalidPolicy"); break; case CONTROLLER_E_NAME_EXISTS: r = controller_send_error(connection, message_read_serial(message), "org.bus1.DBus.Name.Exists"); break; case CONTROLLER_E_NAME_IS_ACTIVATABLE: r = controller_send_error(connection, message_read_serial(message), "org.bus1.DBus.Name.IsActivatable"); break; case CONTROLLER_E_NAME_INVALID: r = controller_send_error(connection, message_read_serial(message), "org.bus1.DBus.Name.Invalid"); break; case CONTROLLER_E_LISTENER_NOT_FOUND: r = controller_send_error(connection, message_read_serial(message), "org.bus1.DBus.Listener.NotFound"); break; case CONTROLLER_E_NAME_NOT_FOUND: r = controller_send_error(connection, message_read_serial(message), "org.bus1.DBus.Name.NotFound"); break; default: break; } return error_trace(r); } /** * controller_dbus_send_activation() - XXX */ int controller_dbus_send_activation(Controller *controller, const char *path) { static const CDVarType type[] = { C_DVAR_T_INIT( CONTROLLER_T_MESSAGE( C_DVAR_T_TUPLE0 ) ) }; _c_cleanup_(c_dvar_deinit) CDVar var = C_DVAR_INIT; _c_cleanup_(message_unrefp) Message *message = NULL; _c_cleanup_(c_freep) void *data = NULL; size_t n_data; int r; c_dvar_begin_write(&var, (__BYTE_ORDER == __BIG_ENDIAN), type, 1); c_dvar_write(&var, "((yyyyuu[(y<o>)(y<s>)(y<s>)])())", c_dvar_is_big_endian(&var) ? 'B' : 'l', DBUS_MESSAGE_TYPE_SIGNAL, DBUS_HEADER_FLAG_NO_REPLY_EXPECTED, 1, 0, (uint32_t)-1, DBUS_MESSAGE_FIELD_PATH, c_dvar_type_o, path, DBUS_MESSAGE_FIELD_INTERFACE, c_dvar_type_s, "org.bus1.DBus.Name", DBUS_MESSAGE_FIELD_MEMBER, c_dvar_type_s, "Activate"); r = c_dvar_end_write(&var, &data, &n_data); if (r) return error_origin(r); r = message_new_outgoing(&message, data, n_data); if (r) return error_fold(r); data = NULL; r = connection_queue(&controller->connection, NULL, message); if (r) return error_fold(r); return 0; } /** * controller_dbus_send_environment() - XXX */ int controller_dbus_send_environment(Controller *controller, const char * const *env, size_t n_env) { static const CDVarType type[] = { C_DVAR_T_INIT( CONTROLLER_T_MESSAGE( C_DVAR_T_TUPLE1( C_DVAR_T_ARRAY( C_DVAR_T_PAIR( C_DVAR_T_s, C_DVAR_T_s ) ) ) ) ) }; _c_cleanup_(c_dvar_deinit) CDVar var = C_DVAR_INIT; _c_cleanup_(message_unrefp) Message *message = NULL; _c_cleanup_(c_freep) void *data = NULL; size_t i, n_data; int r; c_dvar_begin_write(&var, (__BYTE_ORDER == __BIG_ENDIAN), type, 1); c_dvar_write(&var, "((yyyyuu[(y<o>)(y<s>)(y<s>)(y<g>)])([", c_dvar_is_big_endian(&var) ? 'B' : 'l', DBUS_MESSAGE_TYPE_SIGNAL, DBUS_HEADER_FLAG_NO_REPLY_EXPECTED, 1, 0, (uint32_t)-1, DBUS_MESSAGE_FIELD_PATH, c_dvar_type_o, "/org/bus1/DBus/Broker", DBUS_MESSAGE_FIELD_INTERFACE, c_dvar_type_s, "org.bus1.DBus.Broker", DBUS_MESSAGE_FIELD_MEMBER, c_dvar_type_s, "SetActivationEnvironment", DBUS_MESSAGE_FIELD_SIGNATURE, c_dvar_type_g, "a{ss}"); for (i = 0; i < n_env; ++i) c_dvar_write(&var, "{ss}", env[i * 2], env[i * 2 + 1]); c_dvar_write(&var, "]))"); r = c_dvar_end_write(&var, &data, &n_data); if (r) return error_origin(r); r = message_new_outgoing(&message, data, n_data); if (r) return error_fold(r); data = NULL; r = connection_queue(&controller->connection, NULL, message); if (r) return error_fold(r); return 0; } /** * controller_dbus_send_reload() - XXX */ int controller_dbus_send_reload(Controller *controller, User *user, uint32_t serial) { static const CDVarType type[] = { C_DVAR_T_INIT( CONTROLLER_T_MESSAGE( C_DVAR_T_TUPLE0 ) ) }; _c_cleanup_(c_dvar_deinit) CDVar var = C_DVAR_INIT; _c_cleanup_(message_unrefp) Message *message = NULL; _c_cleanup_(c_freep) void *data = NULL; size_t n_data; int r; c_dvar_begin_write(&var, (__BYTE_ORDER == __BIG_ENDIAN), type, 1); c_dvar_write(&var, "((yyyyuu[(y<o>)(y<s>)(y<s>)])())", c_dvar_is_big_endian(&var) ? 'B' : 'l', DBUS_MESSAGE_TYPE_METHOD_CALL, 0, 1, 0, serial, DBUS_MESSAGE_FIELD_PATH, c_dvar_type_o, "/org/bus1/DBus/Controller", DBUS_MESSAGE_FIELD_INTERFACE, c_dvar_type_s, "org.bus1.DBus.Controller", DBUS_MESSAGE_FIELD_MEMBER, c_dvar_type_s, "ReloadConfig"); r = c_dvar_end_write(&var, &data, &n_data); if (r) return error_origin(r); r = message_new_outgoing(&message, data, n_data); if (r) return error_fold(r); data = NULL; r = connection_queue(&controller->connection, user, message); if (r) { if (r == CONNECTION_E_QUOTA) return CONTROLLER_E_QUOTA; return error_fold(r); } return 0; }