00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <unistd.h>
00042
00043 #include "easydbus-core.h"
00044 #include "debug.h"
00045 #include "utils.h"
00046 #include "acquire_internal.h"
00047 #include "monitor_internal.h"
00048 #include "message_internal.h"
00049
00050
00065 int
00066 easydbus_conn_get_address (EasyDbus_conn * conn,
00067 char *serviceName,
00068 enum easydbus_bus bus, int flags)
00069 {
00070 if (serviceName == NULL || conn == NULL)
00071 return -1;
00072
00073 conn->flags = flags;
00074 conn->bus = bus;
00075 switch (bus) {
00076 case EASYDBUS_SESSION:
00077 return
00078 easydbus_get_address_onsession (conn, serviceName);
00079 break;
00080 case EASYDBUS_SYSTEM:
00081 return
00082 easydbus_get_address_onsystem (conn, serviceName);
00083 break;
00084 case EASYDBUS_SESSION_SERVER:
00085 return
00086 easydbus_get_address_serverSession (conn, serviceName);
00087 break;
00088 default:
00089 break;
00090 }
00091
00092 return -1;
00093 }
00094
00111 int
00112 easydbus_conn_reconnect (EasyDbus_conn *conn, int sleep_time)
00113 {
00114 DBusError err;
00115 int result = -1;
00116 struct EasyDbus_object_box *object;
00117 struct EasyDbus_core *core =
00118 (struct EasyDbus_core *)conn;
00119 char *new_service_name = NULL;
00120
00121 if (!conn || !core->service_name)
00122 return -1;
00123
00124 if (core->conn)
00125 dbus_connection_unref(core->conn);
00126 core->conn = NULL;
00127 conn->registered_ondbus = 0;
00128
00129 dbus_error_init (&err);
00130
00131 sleep (sleep_time);
00132
00133
00134 switch (conn->bus) {
00135 case EASYDBUS_SESSION:
00136 case EASYDBUS_SESSION_SERVER:
00137 if (easydbus_connect_to_bus (core, &err, DBUS_BUS_SESSION))
00138 goto error;
00139 break;
00140 case EASYDBUS_SYSTEM:
00141 case EASYDBUS_SYSTEM_SERVER:
00142 if (easydbus_connect_to_bus (core, &err, DBUS_BUS_SYSTEM))
00143 goto error;
00144 break;
00145 default:
00146 goto error;
00147 break;
00148 }
00149
00150 result = easydbus_acquire_name (core, core->service_name,
00151 conn->flags, &err);
00152
00153 if (result == EASYDBUS_CONN_NAME_SERVICE_EXISTS &&
00154
00155
00156 (conn->flags & EASYDBUS_CONN_DO_NOT_QUEUE)) {
00157 if (conn->flags & EASYDBUS_CONN_NAME_SERVICE_RENAMED) {
00158 new_service_name = easydbus_found_new_name
00159 (core, core->service_name, conn->flags, &err);
00160 if (new_service_name == NULL)
00161 goto error;
00162 result = EASYDBUS_CONN_NAME_SERVICE_RENAMED;
00163 }
00164 else
00165 goto error;
00166 }
00167
00168 conn->registered_ondbus = 1;
00169 if (new_service_name) {
00170 if (core->service_name)
00171 free (core->service_name);
00172 core->service_name = new_service_name;
00173 }
00174
00175 if (core->objects) {
00176 for (object = core->objects; object;
00177 object = object->next) {
00178 if (!dbus_connection_register_object_path (core->conn,
00179 (const char *) object->core.path,
00180 &object->vtable,
00181 core)) {
00182 EasyDbusDebug ("Error on register object %s", object->core.path);
00183 goto error;
00184 }
00185 }
00186 easydbus_conn_enable_filters (conn);
00187 }
00188
00189
00190 if (conn->watcher_add_cb && conn->watcher_remove_cb) {
00191 if (easydbus_watcher_enable (conn, conn->watcher_add_cb,
00192 conn->watcher_remove_cb,
00193 conn->watcher_closure))
00194 goto error;
00195 }
00196
00197 dbus_error_free (&err);
00198
00199 return result;
00200 error:
00201 if (conn->registered_ondbus)
00202 dbus_bus_release_name (core->conn, core->service_name, &err);
00203
00204 if (core->conn != NULL)
00205 dbus_connection_unref (core->conn);
00206
00207 dbus_error_free (&err);
00208 return -1;
00209 }
00210
00217 int
00218 easydbus_conn_set_error_cb (EasyDbus_conn *conn,
00219 easydbus_error_cb_f cb,
00220 void *user_closure)
00221 {
00222 if (!conn || !cb)
00223 return -1;
00224
00225 conn->error_cb = cb;
00226 conn->error_closure = user_closure;
00227
00228 return 0;
00229 }
00230
00237 inline int
00238 easydbus_conn_get_n_object (EasyDbus_conn *conn)
00239 {
00240 return (conn ?
00241 ((struct EasyDbus_core *) conn)->n_objs : -1);
00242 }
00243
00254 EasyDbus_object *
00255 easydbus_conn_get_object (EasyDbus_conn *conn,
00256 unsigned int n)
00257 {
00258 int i;
00259 struct EasyDbus_core *core =
00260 (struct EasyDbus_core *) conn;
00261 struct EasyDbus_object_box *ans = NULL;
00262
00263 if (conn && (((int) n) <= core->n_objs))
00264 for (i = 0, ans = core->objects;
00265 i < core->n_objs;
00266 i++, ans = ans->next);
00267
00268 return (EasyDbus_object *) ans;
00269 }
00270
00278 int
00279 easydbus_conn_set_reply_async_cb (EasyDbus_conn *conn,
00280 easydbus_reply_async_cb_f r_cb,
00281 void *user_closure)
00282 {
00283 if (!conn || !r_cb)
00284 return -1;
00285 conn->reply_async_cb = r_cb;
00286 conn->reply_async_closure = user_closure;
00287
00288 return 0;
00289 }
00290
00297 int
00298 easydbus_conn_set_error_message_cb (EasyDbus_conn *conn,
00299 easydbus_error_message_cb_f e_cb,
00300 void *user_closure)
00301 {
00302 if (!conn || !e_cb)
00303 return -1;
00304 conn->error_message_cb = e_cb;
00305 conn->error_message_closure = user_closure;
00306
00307 return 0;
00308 }
00309
00316 int
00317 easydbus_conn_set_reply_message_cb (EasyDbus_conn *conn,
00318 easydbus_reply_message_cb_f r_cb)
00319 {
00320 if (!conn || !r_cb)
00321 return -1;
00322 conn->reply_message_cb = r_cb;
00323
00324 return 0;
00325 }
00326
00334 EasyDbus_conn *
00335 easydbus_conn_create (void)
00336 {
00337 struct EasyDbus_core *conn =
00338 (struct EasyDbus_core *)
00339 malloc (sizeof (struct EasyDbus_core));
00340
00341 if (!conn)
00342 return NULL;
00343
00344 memset (conn, 0, sizeof (struct EasyDbus_core));
00345
00346 conn->objects = NULL;
00347 conn->conn = NULL;
00348 conn->service_name = NULL;
00349 conn->watcher = NULL;
00350 conn->handled_ext_signals = NULL;
00351 conn->user_data.error_cb = NULL;
00352 conn->user_data.error_closure = NULL;
00353 conn->user_data.flags = 0;
00354 conn->user_data.bus = EASYDBUS_INVALID;
00355 conn->pending_msgs = NULL;
00356 conn->user_data.reply_async_cb = NULL;
00357 conn->user_data.error_message_cb = NULL;
00358 conn->user_data.error_message_closure = NULL;
00359 conn->user_data.reply_message_cb = NULL;
00360
00361 return (EasyDbus_conn *) conn;
00362 }
00363
00368 void
00369 easydbus_conn_set_closure (EasyDbus_conn *c,
00370 void *closure)
00371 {
00372 c->closure = closure;
00373 }
00374
00379 void *
00380 easydbus_conn_get_closure (EasyDbus_conn *c)
00381 {
00382 return (c ? c->closure : NULL);
00383 }
00384
00402 int
00403 easydbus_conn_destroy (EasyDbus_conn * conn)
00404 {
00405 struct EasyDbus_core *core =
00406 (struct EasyDbus_core *) conn;
00407 struct EasyDbus_object_box *object = NULL;
00408 struct EasyDbus_watcher *watch = NULL;
00409 struct EasyDbus_Pending *p = NULL;
00410 struct EasyDbus_ext_signal *signal = NULL;
00411 DBusError err;
00412 int ret_val = 0;
00413 int i;
00414
00415 EasyDbusDebug ("Destroy service %s...",
00416 core->service_name ? core->
00417 service_name : ".");
00418
00419 dbus_error_init (&err);
00420
00421
00422 if (core->n_objs) {
00423 for (i = 0; i < core->n_objs; i++) {
00424 object = core->objects;
00425 core->objects = object->next;
00426 easydbus_object_unregister (conn, &object->core);
00427 easydbus_object_free_skeleton (&object->core);
00428 }
00429 }
00430
00431
00432 while (core->handled_ext_signals) {
00433 signal = core->handled_ext_signals;
00434 core->handled_ext_signals = signal->next;
00435 easydbus_ext_signal_free_skeleton (signal);
00436 }
00437
00438 if (core->conn != NULL) {
00439 if (core->service_name != NULL) {
00440 if (conn->registered_ondbus)
00441
00442
00443 free (core->service_name);
00444 conn->registered_ondbus = 0;
00445 }
00446
00447 for (p = core->pending_msgs; core->pending_msgs;
00448 p = core->pending_msgs) {
00449 core->pending_msgs = p->next;
00450 easydbus_pending_destroy(p);
00451 }
00452
00453 while (core->watcher != NULL) {
00454 watch = core->watcher;
00455 if (conn->watcher_remove_cb &&
00456 dbus_watch_get_enabled (core->watcher->watch))
00457 conn->watcher_remove_cb(core->watcher,
00458 conn->watcher_closure);
00459 core->watcher = core->watcher->next;
00460 free (watch);
00461 }
00462
00463
00464 if (conn->watcher_remove_cb) {
00465 conn->watcher_remove_cb = NULL;
00466 conn->watcher_add_cb = NULL;
00467
00468
00469
00470 dbus_connection_set_watch_functions (core->conn,
00471 NULL, NULL, NULL,
00472 NULL, NULL);
00473 }
00474
00475
00476
00477 dbus_connection_unref (core->conn);
00478 }
00479
00480 free (core);
00481 dbus_error_free (&err);
00482
00483 return ret_val;
00484 }
00485
00498 inline int
00499 easydbus_conn_get_system_service_address (EasyDbus_conn * data,
00500 char *serviceName)
00501 {
00502 struct EasyDbus_core *core = (struct EasyDbus_core *) data;
00503 char *dbus_starter_address = NULL;
00504 DBusError err;
00505
00506 dbus_error_init (&err);
00507
00508
00509 dbus_starter_address = getenv ("DBUS_STARTER_ADDRESS");
00510
00511 if (dbus_starter_address == NULL) {
00512 EasyDbusDebug ("Error on recover dbus_starter_address");
00513 return -1;
00514 }
00515
00516 core->conn = dbus_connection_open (dbus_starter_address, &err);
00517
00518 if (!core->conn) {
00519 EasyDbusDebug ("Error %s from "
00520 "dbus_connection_open: %s",
00521 err.name, err.message);
00522 return -1;
00523 }
00524
00525
00526
00527 dbus_connection_set_exit_on_disconnect (core->conn, FALSE);
00528
00529 dbus_bus_register (core->conn, &err);
00530
00531 if (dbus_error_is_set (&err)) {
00532 EasyDbusDebug ("Error %s from "
00533 "dbus_bus_register: %s", err.name, err.message);
00534 goto error_acquire;
00535 }
00536
00537
00538
00539 dbus_bus_request_name (core->conn, serviceName, 0, &err);
00540
00541
00542 if (dbus_error_is_set (&err)) {
00543 EasyDbusDebug ("Error %s from "
00544 "dbus_bus_request_name: %s",
00545 err.name, err.message);
00546 goto error_acquire;
00547 }
00548
00549
00550
00551
00552
00553
00554
00555 data->registered_ondbus = 1;
00556
00557 if (easydbus_save_serviceName (core, serviceName)) {
00558 EasyDbusDebug ("Error on set unique nameID");
00559 goto error_acquire;
00560 }
00561
00562 dbus_error_free (&err);
00563
00564 return 0;
00565
00566 error_acquire:
00567 if (data->registered_ondbus)
00568 dbus_bus_release_name (core->conn, serviceName, &err);
00569
00570 if (core->conn != NULL)
00571 dbus_connection_unref (core->conn);
00572
00573 dbus_error_free (&err);
00574
00575 return -1;
00576 }
00577
00583 const char *
00584 easydbus_conn_get_service_name (const EasyDbus_conn * conn)
00585 {
00586 return conn ? (const char *)
00587 ((struct EasyDbus_core *)conn)->service_name : NULL;
00588 }
00589
00599 int
00600 easydbus_conn_get_fd (EasyDbus_conn * data)
00601 {
00602 struct EasyDbus_core *core = (struct EasyDbus_core *) data;
00603 int fd;
00604
00605 if (data)
00606
00607 if (dbus_connection_get_unix_fd (core->conn, &fd))
00608 return fd;
00609
00610 return -1;
00611 }
00612
00613