00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #include <dbus-c++/debug.h>
00029 #include <dbus-c++/server.h>
00030
00031 #include "internalerror.h"
00032 #include "server_p.h"
00033 #include "connection_p.h"
00034 #include "dispatcher_p.h"
00035 #include "systemerror.h"
00036
00037 using namespace DBus;
00038
00039 Server::Private::Private(DBusServer *s)
00040 : server(s), auth_enabled(false), anon_enabled(false)
00041 {
00042 }
00043
00044 Server::Private::~Private()
00045 {
00046 }
00047
00048 void Server::Private::on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data)
00049 {
00050 Server *s = static_cast<Server *>(data);
00051
00052 Connection nc (new Connection::Private(conn, s->_pvt.get()));
00053
00054 s->_pvt->connections.push_back(nc);
00055
00056 s->on_new_connection(nc);
00057
00058 if (s->_pvt->auth_enabled)
00059 dbus_connection_set_unix_user_function (conn, Private::on_unix_auth_cb, s, NULL);
00060
00061 if (s->_pvt->anon_enabled)
00062 dbus_connection_set_allow_anonymous (conn, true);
00063
00064 debug_log("incoming connection 0x%08x", conn);
00065 }
00066
00067 dbus_bool_t Server::Private::on_unix_auth_cb(DBusConnection *c, unsigned long uid, void *data)
00068 {
00069 Server *s = static_cast<Server *>(data);
00070
00071 return s->on_user_auth(uid);
00072 }
00073
00074 Server::Server(const char *address)
00075 {
00076 InternalError e;
00077 DBusServer *server = dbus_server_listen(address, e);
00078
00079 if (e) throw Error(e);
00080
00081 debug_log("server 0x%08x listening on %s", server, address);
00082
00083 _pvt = new Private(server);
00084
00085 dbus_server_set_new_connection_function(_pvt->server, Private::on_new_conn_cb, this, NULL);
00086
00087 setup(default_dispatcher);
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 Server::~Server()
00097 {
00098 dbus_server_unref(_pvt->server);
00099 }
00100
00101 Dispatcher *Server::setup(Dispatcher *dispatcher)
00102 {
00103 debug_log("registering stubs for server %p", _pvt->server);
00104
00105 Dispatcher *prev = _pvt->dispatcher;
00106
00107 dbus_server_set_watch_functions(
00108 _pvt->server,
00109 Dispatcher::Private::on_add_watch,
00110 Dispatcher::Private::on_rem_watch,
00111 Dispatcher::Private::on_toggle_watch,
00112 dispatcher,
00113 0
00114 );
00115
00116 dbus_server_set_timeout_functions(
00117 _pvt->server,
00118 Dispatcher::Private::on_add_timeout,
00119 Dispatcher::Private::on_rem_timeout,
00120 Dispatcher::Private::on_toggle_timeout,
00121 dispatcher,
00122 0
00123 );
00124
00125 _pvt->dispatcher = dispatcher;
00126
00127 return prev;
00128 }
00129
00130 bool Server::operator == (const Server &s) const
00131 {
00132 return _pvt->server == s._pvt->server;
00133 }
00134
00135 bool Server::listening() const
00136 {
00137 return dbus_server_get_is_connected(_pvt->server);
00138 }
00139 void Server::disconnect()
00140 {
00141 dbus_server_disconnect(_pvt->server);
00142 }
00143
00144 bool Server::on_user_auth(unsigned long uid)
00145 {
00146 return true;
00147 }
00148
00149 void Server::enable_auth(bool enable)
00150 {
00151 _pvt->auth_enabled = enable;
00152 }
00153
00154 void Server::detach_connection(Connection &c)
00155 {
00156 _pvt->connections.remove(c);
00157 }
00158
00159 void Server::enable_anon(bool enable)
00160 {
00161 const char *anon_mech[] = {"ANONYMOUS", 0};
00162 const char *default_mech[] = {"EXTERNAL", "DBUS_COOKIE_SHA1", "ANONYMOUS", 0};
00163 const char **used_mech = default_mech;
00164
00165 if (enable)
00166 used_mech = anon_mech;
00167
00168 if (!dbus_server_set_auth_mechanisms(_pvt->server, used_mech))
00169 throw SetAuthMechanismsError();
00170
00171 _pvt->anon_enabled = enable;
00172 }