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