Fix more warnings
[lash.git] / dbus / object_path.c
blob9911f5729dd9e2f8b9cce234ee9a357c08bbd5f4
1 /*
2 * LASH
4 * Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
5 * Copyright (C) 2008 Nedko Arnaudov
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
26 #include "dbus/object_path.h"
27 #include "common/safety.h"
28 #include "common/debug.h"
29 #include "dbus/introspection.h" /* g_dbus_interface_dtor_introspectable */
30 #include "dbus/error.h" /* lash_dbus_error() */
32 static DBusHandlerResult
33 object_path_handler(DBusConnection *connection,
34 DBusMessage *message,
35 void *data);
37 static void
38 object_path_handler_unregister(DBusConnection *conn,
39 void *data);
41 object_path_t *
42 object_path_new(const char *name,
43 void *context,
44 int num_ifaces,
45 ...)
47 if (!name || !name[0] || num_ifaces < 1) {
48 lash_debug("Invalid arguments");
49 return NULL;
52 lash_debug("Creating object path");
54 object_path_t *path;
55 va_list argp;
56 const interface_t **iface_pptr;
58 path = lash_malloc(1, sizeof(object_path_t));
59 path->name = lash_strdup(name);
60 path->interfaces = lash_malloc(num_ifaces + 2, sizeof(interface_t *));
62 va_start(argp, num_ifaces);
64 iface_pptr = path->interfaces;
65 *iface_pptr = &g_dbus_interface_dtor_introspectable;
66 for (++iface_pptr;
67 (*iface_pptr = va_arg(argp, const interface_t *));
68 ++iface_pptr);
70 va_end(argp);
72 if ((path->introspection = introspection_new(path))) {
73 path->context = context;
74 return path;
77 lash_error("Failed to create object path");
78 object_path_destroy(path);
80 return NULL;
83 int
84 object_path_register(DBusConnection *conn,
85 object_path_t *path)
87 if (!conn || !path || !path->name || !path->interfaces) {
88 lash_debug("Invalid arguments");
89 return 0;
92 lash_debug("Registering object path");
94 DBusObjectPathVTable vtable =
96 object_path_handler_unregister,
97 object_path_handler,
98 NULL, NULL, NULL, NULL
101 dbus_connection_register_object_path(conn, path->name,
102 &vtable, (void *) path);
104 return 1;
107 void
108 object_path_destroy(object_path_t *path)
110 lash_debug("Destroying object path");
112 if (path) {
113 if (path->name) {
114 free(path->name);
115 path->name = NULL;
117 if (path->interfaces) {
118 free(path->interfaces);
119 path->interfaces = NULL;
121 introspection_destroy(path);
122 free(path);
123 path = NULL;
125 #ifdef LASH_DEBUG
126 else
127 lash_debug("Nothing to destroy");
128 #endif
132 static DBusHandlerResult
133 object_path_handler(DBusConnection *connection,
134 DBusMessage *message,
135 void *data)
137 const char *interface_name;
138 const interface_t **iface_pptr;
139 method_call_t call;
141 /* Check if the message is a method call. If not, ignore it. */
142 if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_METHOD_CALL) {
143 goto handled;
146 /* Get the invoked method's name and make sure it's non-NULL. */
147 if (!(call.method_name = dbus_message_get_member(message))) {
148 lash_dbus_error(&call, LASH_DBUS_ERROR_UNKNOWN_METHOD,
149 "Received method call with empty method name");
150 goto send_return;
153 /* Initialize our data. */
154 call.connection = connection;
155 call.message = message;
156 call.interface = NULL; /* To be set by the default interface handler */
157 call.context = data;
158 call.reply = NULL;
160 /* Check if there's an interface specified for this method call. */
161 if ((interface_name = dbus_message_get_interface(message))) {
162 for (iface_pptr = (const interface_t **) ((object_path_t *) data)->interfaces;
163 iface_pptr && *iface_pptr;
164 ++iface_pptr) {
165 if (strcmp(interface_name, (*iface_pptr)->name) == 0) {
166 if ((*iface_pptr)->handler(*iface_pptr, &call)) {
167 goto send_return;
170 break;
174 else
176 /* No interface was specified so we have to try them all. This is
177 * dictated by the D-Bus specification which states that method calls
178 * omitting the interface must never be rejected.
181 for (iface_pptr = (const interface_t **) ((object_path_t *) data)->interfaces;
182 iface_pptr && *iface_pptr;
183 ++iface_pptr) {
184 if ((*iface_pptr)->handler(*iface_pptr, &call)) {
185 goto send_return;
190 lash_dbus_error(&call, LASH_DBUS_ERROR_UNKNOWN_METHOD,
191 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist",
192 call.method_name, dbus_message_get_signature(message), interface_name);
194 send_return:
195 method_return_send(&call);
197 handled:
198 return DBUS_HANDLER_RESULT_HANDLED;
201 static void
202 object_path_handler_unregister(DBusConnection *conn,
203 void *data)
205 #ifdef LASH_DEBUG
206 object_path_t *path = data;
207 lash_debug("Message handler of object path %s was unregistered",
208 (path && path->name) ? path->name : "<unknown>");
209 #endif /* LASH_DEBUG */
212 /* EOF */