server.cpp
Go to the documentation of this file.
00001 /*
00002  *
00003  *  D-Bus++ - C++ bindings for D-Bus
00004  *
00005  *  Copyright (C) 2005-2007  Paolo Durante <shackan@gmail.com>
00006  *
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Lesser General Public
00010  *  License as published by the Free Software Foundation; either
00011  *  version 2.1 of the License, or (at your option) any later version.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public
00019  *  License along with this library; if not, write to the Free Software
00020  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 "error.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 Server::Server(const Server &s)
00091 : _pvt(s._pvt)
00092 {
00093   dbus_server_ref(_pvt->server);
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::enable_anon(bool enable)
00155 {
00156   const char *anon_mech[] = {"ANONYMOUS", 0};
00157   const char *default_mech[] = {"EXTERNAL", "DBUS_COOKIE_SHA1", "ANONYMOUS", 0};
00158   const char **used_mech = default_mech;
00159 
00160   if (enable)
00161     used_mech = anon_mech;
00162 
00163   if (!dbus_server_set_auth_mechanisms(_pvt->server, used_mech))
00164     throw ErrorSetAuthMechanisms();
00165 
00166   _pvt->anon_enabled = enable;
00167 }