00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-server.h"
00025 #include "dbus-server-unix.h"
00026 #ifdef DBUS_BUILD_TESTS
00027 #include "dbus-server-debug-pipe.h"
00028 #endif
00029 #include "dbus-address.h"
00030
00062 dbus_bool_t
00063 _dbus_server_init_base (DBusServer *server,
00064 const DBusServerVTable *vtable,
00065 const DBusString *address)
00066 {
00067 server->vtable = vtable;
00068 server->refcount = 1;
00069
00070 server->address = NULL;
00071 server->watches = NULL;
00072 server->timeouts = NULL;
00073
00074 if (!_dbus_string_copy_data (address, &server->address))
00075 goto failed;
00076
00077 server->watches = _dbus_watch_list_new ();
00078 if (server->watches == NULL)
00079 goto failed;
00080
00081 server->timeouts = _dbus_timeout_list_new ();
00082 if (server->timeouts == NULL)
00083 goto failed;
00084
00085 _dbus_data_slot_list_init (&server->slot_list);
00086
00087 _dbus_verbose ("Initialized server on address %s\n", server->address);
00088
00089 return TRUE;
00090
00091 failed:
00092 if (server->watches)
00093 {
00094 _dbus_watch_list_free (server->watches);
00095 server->watches = NULL;
00096 }
00097 if (server->timeouts)
00098 {
00099 _dbus_timeout_list_free (server->timeouts);
00100 server->timeouts = NULL;
00101 }
00102 if (server->address)
00103 {
00104 dbus_free (server->address);
00105 server->address = NULL;
00106 }
00107
00108 return FALSE;
00109 }
00110
00117 void
00118 _dbus_server_finalize_base (DBusServer *server)
00119 {
00120
00121 _dbus_data_slot_list_free (&server->slot_list);
00122
00123 dbus_server_set_new_connection_function (server, NULL, NULL, NULL);
00124
00125 if (!server->disconnected)
00126 dbus_server_disconnect (server);
00127
00128 _dbus_watch_list_free (server->watches);
00129 _dbus_timeout_list_free (server->timeouts);
00130
00131 dbus_free (server->address);
00132
00133 dbus_free_string_array (server->auth_mechanisms);
00134 }
00135
00143 dbus_bool_t
00144 _dbus_server_add_watch (DBusServer *server,
00145 DBusWatch *watch)
00146 {
00147 return _dbus_watch_list_add_watch (server->watches, watch);
00148 }
00149
00156 void
00157 _dbus_server_remove_watch (DBusServer *server,
00158 DBusWatch *watch)
00159 {
00160 _dbus_watch_list_remove_watch (server->watches, watch);
00161 }
00162
00172 void
00173 _dbus_server_toggle_watch (DBusServer *server,
00174 DBusWatch *watch,
00175 dbus_bool_t enabled)
00176 {
00177 if (server->watches)
00178 _dbus_watch_list_toggle_watch (server->watches,
00179 watch, enabled);
00180 }
00181
00191 dbus_bool_t
00192 _dbus_server_add_timeout (DBusServer *server,
00193 DBusTimeout *timeout)
00194 {
00195 return _dbus_timeout_list_add_timeout (server->timeouts, timeout);
00196 }
00197
00204 void
00205 _dbus_server_remove_timeout (DBusServer *server,
00206 DBusTimeout *timeout)
00207 {
00208 _dbus_timeout_list_remove_timeout (server->timeouts, timeout);
00209 }
00210
00220 void
00221 _dbus_server_toggle_timeout (DBusServer *server,
00222 DBusTimeout *timeout,
00223 dbus_bool_t enabled)
00224 {
00225 if (server->timeouts)
00226 _dbus_timeout_list_toggle_timeout (server->timeouts,
00227 timeout, enabled);
00228 }
00229
00230
00268 DBusServer*
00269 dbus_server_listen (const char *address,
00270 DBusError *error)
00271 {
00272 DBusServer *server;
00273 DBusAddressEntry **entries;
00274 int len, i;
00275 const char *address_problem_type;
00276 const char *address_problem_field;
00277 const char *address_problem_other;
00278
00279 _dbus_return_val_if_fail (address != NULL, NULL);
00280 _dbus_return_val_if_error_is_set (error, NULL);
00281
00282 if (!dbus_parse_address (address, &entries, &len, error))
00283 return NULL;
00284
00285 server = NULL;
00286 address_problem_type = NULL;
00287 address_problem_field = NULL;
00288 address_problem_other = NULL;
00289
00290 for (i = 0; i < len; i++)
00291 {
00292 const char *method = dbus_address_entry_get_method (entries[i]);
00293
00294 if (strcmp (method, "unix") == 0)
00295 {
00296 const char *path = dbus_address_entry_get_value (entries[i], "path");
00297 const char *tmpdir = dbus_address_entry_get_value (entries[i], "tmpdir");
00298 const char *abstract = dbus_address_entry_get_value (entries[i], "abstract");
00299
00300 if (path == NULL && tmpdir == NULL && abstract == NULL)
00301 {
00302 address_problem_type = "unix";
00303 address_problem_field = "path or tmpdir or abstract";
00304 goto bad_address;
00305 }
00306
00307 if ((path && tmpdir) ||
00308 (path && abstract) ||
00309 (tmpdir && abstract))
00310 {
00311 address_problem_other = "cannot specify two of \"path\" and \"tmpdir\" and \"abstract\" at the same time";
00312 goto bad_address;
00313 }
00314
00315 if (tmpdir != NULL)
00316 {
00317 DBusString full_path;
00318 DBusString filename;
00319
00320 if (!_dbus_string_init (&full_path))
00321 {
00322 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00323 goto out;
00324 }
00325
00326 if (!_dbus_string_init (&filename))
00327 {
00328 _dbus_string_free (&full_path);
00329 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00330 goto out;
00331 }
00332
00333 if (!_dbus_string_append (&filename,
00334 "dbus-") ||
00335 !_dbus_generate_random_ascii (&filename, 10) ||
00336 !_dbus_string_append (&full_path, tmpdir) ||
00337 !_dbus_concat_dir_and_file (&full_path, &filename))
00338 {
00339 _dbus_string_free (&full_path);
00340 _dbus_string_free (&filename);
00341 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
00342 goto out;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 server =
00355 _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path),
00356 #ifdef HAVE_ABSTRACT_SOCKETS
00357 TRUE,
00358 #else
00359 FALSE,
00360 #endif
00361 error);
00362
00363 _dbus_string_free (&full_path);
00364 _dbus_string_free (&filename);
00365 }
00366 else
00367 {
00368 if (path)
00369 server = _dbus_server_new_for_domain_socket (path, FALSE, error);
00370 else
00371 server = _dbus_server_new_for_domain_socket (abstract, TRUE, error);
00372 }
00373 }
00374 else if (strcmp (method, "tcp") == 0)
00375 {
00376 const char *host = dbus_address_entry_get_value (entries[i], "host");
00377 const char *port = dbus_address_entry_get_value (entries[i], "port");
00378 DBusString str;
00379 long lport;
00380 dbus_bool_t sresult;
00381
00382 if (port == NULL)
00383 {
00384 address_problem_type = "tcp";
00385 address_problem_field = "port";
00386 goto bad_address;
00387 }
00388
00389 _dbus_string_init_const (&str, port);
00390 sresult = _dbus_string_parse_int (&str, 0, &lport, NULL);
00391 _dbus_string_free (&str);
00392
00393 if (sresult == FALSE || lport <= 0 || lport > 65535)
00394 {
00395 address_problem_other = "Port is not an integer between 0 and 65535";
00396 goto bad_address;
00397 }
00398
00399 server = _dbus_server_new_for_tcp_socket (host, lport, error);
00400
00401 if (server)
00402 break;
00403 }
00404 #ifdef DBUS_BUILD_TESTS
00405 else if (strcmp (method, "debug-pipe") == 0)
00406 {
00407 const char *name = dbus_address_entry_get_value (entries[i], "name");
00408
00409 if (name == NULL)
00410 {
00411 address_problem_type = "debug-pipe";
00412 address_problem_field = "name";
00413 goto bad_address;
00414 }
00415
00416 server = _dbus_server_debug_pipe_new (name, error);
00417 }
00418 #endif
00419 else
00420 {
00421 address_problem_other = "Unknown address type (examples of valid types are \"unix\" and \"tcp\")";
00422 goto bad_address;
00423 }
00424
00425 if (server)
00426 break;
00427 }
00428
00429 out:
00430
00431 dbus_address_entries_free (entries);
00432 return server;
00433
00434 bad_address:
00435 dbus_address_entries_free (entries);
00436 if (address_problem_type != NULL)
00437 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00438 "Server address of type %s was missing argument %s",
00439 address_problem_type, address_problem_field);
00440 else
00441 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00442 "Could not parse server address: %s",
00443 address_problem_other);
00444
00445 return NULL;
00446 }
00447
00453 void
00454 dbus_server_ref (DBusServer *server)
00455 {
00456 _dbus_return_if_fail (server != NULL);
00457
00458 server->refcount += 1;
00459 }
00460
00469 void
00470 dbus_server_unref (DBusServer *server)
00471 {
00472 _dbus_return_if_fail (server != NULL);
00473
00474 _dbus_assert (server->refcount > 0);
00475
00476 server->refcount -= 1;
00477 if (server->refcount == 0)
00478 {
00479 _dbus_assert (server->vtable->finalize != NULL);
00480
00481 (* server->vtable->finalize) (server);
00482 }
00483 }
00484
00493 void
00494 dbus_server_disconnect (DBusServer *server)
00495 {
00496 _dbus_return_if_fail (server != NULL);
00497
00498 _dbus_assert (server->vtable->disconnect != NULL);
00499
00500 if (server->disconnected)
00501 return;
00502
00503 (* server->vtable->disconnect) (server);
00504 server->disconnected = TRUE;
00505 }
00506
00512 dbus_bool_t
00513 dbus_server_get_is_connected (DBusServer *server)
00514 {
00515 _dbus_return_val_if_fail (server != NULL, FALSE);
00516
00517 return !server->disconnected;
00518 }
00519
00527 char*
00528 dbus_server_get_address (DBusServer *server)
00529 {
00530 _dbus_return_val_if_fail (server != NULL, NULL);
00531
00532 return _dbus_strdup (server->address);
00533 }
00534
00547 void
00548 dbus_server_set_new_connection_function (DBusServer *server,
00549 DBusNewConnectionFunction function,
00550 void *data,
00551 DBusFreeFunction free_data_function)
00552 {
00553 _dbus_return_if_fail (server != NULL);
00554
00555 if (server->new_connection_free_data_function != NULL)
00556 (* server->new_connection_free_data_function) (server->new_connection_data);
00557
00558 server->new_connection_function = function;
00559 server->new_connection_data = data;
00560 server->new_connection_free_data_function = free_data_function;
00561 }
00562
00579 dbus_bool_t
00580 dbus_server_set_watch_functions (DBusServer *server,
00581 DBusAddWatchFunction add_function,
00582 DBusRemoveWatchFunction remove_function,
00583 DBusWatchToggledFunction toggled_function,
00584 void *data,
00585 DBusFreeFunction free_data_function)
00586 {
00587 _dbus_return_val_if_fail (server != NULL, FALSE);
00588
00589 return _dbus_watch_list_set_functions (server->watches,
00590 add_function,
00591 remove_function,
00592 toggled_function,
00593 data,
00594 free_data_function);
00595 }
00596
00612 dbus_bool_t
00613 dbus_server_set_timeout_functions (DBusServer *server,
00614 DBusAddTimeoutFunction add_function,
00615 DBusRemoveTimeoutFunction remove_function,
00616 DBusTimeoutToggledFunction toggled_function,
00617 void *data,
00618 DBusFreeFunction free_data_function)
00619 {
00620 _dbus_return_val_if_fail (server != NULL, FALSE);
00621
00622 return _dbus_timeout_list_set_functions (server->timeouts,
00623 add_function, remove_function,
00624 toggled_function,
00625 data, free_data_function);
00626 }
00627
00638 dbus_bool_t
00639 dbus_server_set_auth_mechanisms (DBusServer *server,
00640 const char **mechanisms)
00641 {
00642 char **copy;
00643
00644 _dbus_return_val_if_fail (server != NULL, FALSE);
00645
00646 if (mechanisms != NULL)
00647 {
00648 copy = _dbus_dup_string_array (mechanisms);
00649 if (copy == NULL)
00650 return FALSE;
00651 }
00652 else
00653 copy = NULL;
00654
00655 dbus_free_string_array (server->auth_mechanisms);
00656 server->auth_mechanisms = copy;
00657
00658 return TRUE;
00659 }
00660
00661
00662 static DBusDataSlotAllocator slot_allocator;
00663 _DBUS_DEFINE_GLOBAL_LOCK (server_slots);
00664
00679 dbus_bool_t
00680 dbus_server_allocate_data_slot (dbus_int32_t *slot_p)
00681 {
00682 return _dbus_data_slot_allocator_alloc (&slot_allocator,
00683 _DBUS_LOCK_NAME (server_slots),
00684 slot_p);
00685 }
00686
00698 void
00699 dbus_server_free_data_slot (dbus_int32_t *slot_p)
00700 {
00701 _dbus_return_if_fail (*slot_p >= 0);
00702
00703 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
00704 }
00705
00719 dbus_bool_t
00720 dbus_server_set_data (DBusServer *server,
00721 int slot,
00722 void *data,
00723 DBusFreeFunction free_data_func)
00724 {
00725 DBusFreeFunction old_free_func;
00726 void *old_data;
00727 dbus_bool_t retval;
00728
00729 _dbus_return_val_if_fail (server != NULL, FALSE);
00730
00731 #if 0
00732 dbus_mutex_lock (server->mutex);
00733 #endif
00734
00735 retval = _dbus_data_slot_list_set (&slot_allocator,
00736 &server->slot_list,
00737 slot, data, free_data_func,
00738 &old_free_func, &old_data);
00739
00740 #if 0
00741 dbus_mutex_unlock (server->mutex);
00742 #endif
00743
00744 if (retval)
00745 {
00746
00747 if (old_free_func)
00748 (* old_free_func) (old_data);
00749 }
00750
00751 return retval;
00752 }
00753
00762 void*
00763 dbus_server_get_data (DBusServer *server,
00764 int slot)
00765 {
00766 void *res;
00767
00768 _dbus_return_val_if_fail (server != NULL, NULL);
00769
00770 #if 0
00771 dbus_mutex_lock (server->mutex);
00772 #endif
00773
00774 res = _dbus_data_slot_list_get (&slot_allocator,
00775 &server->slot_list,
00776 slot);
00777
00778 #if 0
00779 dbus_mutex_unlock (server->mutex);
00780 #endif
00781
00782 return res;
00783 }
00784