|
Lines 19-27
Link Here
|
| 19 |
|
19 |
|
| 20 |
/*! |
20 |
/*! |
| 21 |
* \file dbusInterface.cpp |
21 |
* \file dbusInterface.cpp |
| 22 |
* \brief In this file can be found the functionality to connect to |
22 |
* \brief In this file can be found the functionality to connect to |
| 23 |
* the HAL daemon via D-Bus, to handle D-Bus calls/events and to |
23 |
* the D-Bus, to handle D-Bus session management |
| 24 |
* provide wrapper to HAL lib and functions |
|
|
| 25 |
* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> |
24 |
* \author Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de> |
| 26 |
* \date 2006-2007 |
25 |
* \date 2006-2007 |
| 27 |
*/ |
26 |
*/ |
|
Lines 30-56
Link Here
|
| 30 |
#include <tdelocale.h> |
29 |
#include <tdelocale.h> |
| 31 |
|
30 |
|
| 32 |
// DBUS - Header |
31 |
// DBUS - Header |
|
|
32 |
#include "dbus/dbus-shared.h" |
| 33 |
#include "dbusInterface.h" |
33 |
#include "dbusInterface.h" |
|
|
34 |
#include <tqdbusdatalist.h> |
| 35 |
#include <tqdbusdatamap.h> |
| 36 |
#include <tqdbuserror.h> |
| 37 |
#include <tqdbusmessage.h> |
| 38 |
#include <tqdbusvariant.h> |
| 34 |
|
39 |
|
| 35 |
// system headers |
40 |
// system headers |
| 36 |
#include <iostream> |
41 |
#include <unistd.h> |
| 37 |
|
42 |
|
| 38 |
static void* myInstance = 0; |
43 |
static void* myInstance = 0; |
| 39 |
|
44 |
|
| 40 |
/*! The default constructor of the class dbusInterface. */ |
45 |
/*! The default constructor of the class dbusInterface. */ |
| 41 |
dbusInterface::dbusInterface(){ |
46 |
dbusInterface::dbusInterface(): |
|
|
47 |
dBusConn(), |
| 48 |
dBusWatch(0), |
| 49 |
systemdSession(), |
| 50 |
systemdSeat(0), |
| 51 |
systemdInhibit(-1), |
| 52 |
consolekitSession(), |
| 53 |
consolekitSeat(0) |
| 54 |
{ |
| 42 |
kdDebugFuncIn(trace); |
55 |
kdDebugFuncIn(trace); |
| 43 |
|
56 |
|
| 44 |
dbus_is_connected = false; |
|
|
| 45 |
acquiredPolicyPower = false; |
| 46 |
|
| 47 |
// add pointer to this for filter_function() |
57 |
// add pointer to this for filter_function() |
| 48 |
myInstance=this; |
58 |
myInstance=this; |
|
|
59 |
|
| 49 |
// init connection to dbus |
60 |
// init connection to dbus |
| 50 |
if(!initDBUS()) { |
61 |
initDBUS(); |
| 51 |
kdError() << "Can't connect to D-Bus" << endl; |
|
|
| 52 |
m_dBusQtConnection = NULL; |
| 53 |
} |
| 54 |
|
62 |
|
| 55 |
kdDebugFuncOut(trace); |
63 |
kdDebugFuncOut(trace); |
| 56 |
} |
64 |
} |
|
Lines 72-101
dbusInterface::~dbusInterface(){
Link Here
|
| 72 |
* \retval false if disconnected |
80 |
* \retval false if disconnected |
| 73 |
*/ |
81 |
*/ |
| 74 |
bool dbusInterface::isConnectedToDBUS() { |
82 |
bool dbusInterface::isConnectedToDBUS() { |
| 75 |
return dbus_is_connected; |
83 |
return dBusConn.isConnected(); |
| 76 |
} |
|
|
| 77 |
|
| 78 |
/*! |
| 79 |
* This function return information if the org.freedesktop.Policy.Power |
| 80 |
* interface was claimed. |
| 81 |
* \return boolean with the status of claim the interface |
| 82 |
* \retval true if acquired |
| 83 |
* \retval false if not |
| 84 |
*/ |
| 85 |
bool dbusInterface::acquiredPolicyPowerInterface() { |
| 86 |
return acquiredPolicyPower; |
| 87 |
} |
84 |
} |
| 88 |
|
85 |
|
| 89 |
/*! |
86 |
/*! |
| 90 |
* This function try a reconnect to D-Bus and HAL daemon. |
87 |
* This function try a reconnect to D-Bus. |
| 91 |
* \return boolean with the result of the operation |
88 |
* \return boolean with the result of the operation |
| 92 |
* \retval true if successful reconnected to D-Bus and HAL |
89 |
* \retval true if successful reconnected to D-Bus |
| 93 |
* \retval false if unsuccessful |
90 |
* \retval false if unsuccessful |
| 94 |
*/ |
91 |
*/ |
| 95 |
bool dbusInterface::reconnect() { |
92 |
bool dbusInterface::reconnect() { |
| 96 |
// close D-Bus connection |
93 |
// close D-Bus connection |
| 97 |
close(); |
94 |
close(); |
| 98 |
// init D-Bus conntection and HAL context |
95 |
// init D-Bus conntection |
| 99 |
return (initDBUS()); |
96 |
return (initDBUS()); |
| 100 |
} |
97 |
} |
| 101 |
|
98 |
|
|
Lines 106-123
bool dbusInterface::reconnect() {
Link Here
|
| 106 |
* \retval false if any problems |
103 |
* \retval false if any problems |
| 107 |
*/ |
104 |
*/ |
| 108 |
bool dbusInterface::close() { |
105 |
bool dbusInterface::close() { |
| 109 |
if ( m_dBusQtConnection != NULL ) { |
106 |
if( dBusConn.isConnected() ) { |
| 110 |
releasePolicyPowerIface(); |
107 |
if( dBusWatch ) { |
| 111 |
m_dBusQtConnection->close(); |
108 |
delete dBusWatch; |
| 112 |
m_dBusQtConnection = NULL; |
109 |
} |
|
|
110 |
if( systemdSeat ) { |
| 111 |
delete systemdSeat; |
| 112 |
} |
| 113 |
if( consolekitSeat ) { |
| 114 |
delete consolekitSeat; |
| 115 |
} |
| 116 |
dBusConn.closeConnection(); |
| 113 |
} |
117 |
} |
| 114 |
dbus_is_connected = false; |
|
|
| 115 |
|
| 116 |
return true; |
118 |
return true; |
| 117 |
} |
119 |
} |
| 118 |
|
120 |
|
| 119 |
/* ----> D-Bus section :: START <---- */ |
|
|
| 120 |
|
| 121 |
/*! |
121 |
/*! |
| 122 |
* This function initialise the connection to the D-Bus daemon. |
122 |
* This function initialise the connection to the D-Bus daemon. |
| 123 |
* \return boolean with the result of the operation |
123 |
* \return boolean with the result of the operation |
|
Lines 127-654
bool dbusInterface::close() {
Link Here
|
| 127 |
bool dbusInterface::initDBUS(){ |
127 |
bool dbusInterface::initDBUS(){ |
| 128 |
kdDebugFuncIn(trace); |
128 |
kdDebugFuncIn(trace); |
| 129 |
|
129 |
|
| 130 |
dbus_is_connected = false; |
130 |
dBusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); |
| 131 |
|
|
|
| 132 |
DBusError error; |
| 133 |
dbus_error_init(&error); |
| 134 |
|
| 135 |
dbus_connection = dbus_bus_get( DBUS_BUS_SYSTEM, &error ); |
| 136 |
|
| 137 |
if (dbus_connection == NULL){ |
| 138 |
kdError() << "Failed to open connection to system message bus: " << error.message << endl; |
| 139 |
dbus_error_free (&error); |
| 140 |
return false; |
| 141 |
} |
| 142 |
|
131 |
|
| 143 |
if ( dbus_error_is_set( &error ) ) { |
132 |
if( !dBusConn.isConnected() ) { |
| 144 |
kdError() << "Failed to register connection with system message bus: " << error.message << endl; |
133 |
kdError() << "Failed to open connection to system message bus: " << dBusConn.lastError().name().local8Bit() << endl; |
| 145 |
return false; |
134 |
return false; |
| 146 |
} |
135 |
} |
| 147 |
|
136 |
|
| 148 |
acquirePolicyPowerIface(); |
137 |
// watcher for NameOwnerChanged signals |
| 149 |
|
138 |
dBusWatch = new TQT_DBusProxy(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, dBusConn); |
| 150 |
dbus_connection_set_exit_on_disconnect( dbus_connection, false ); |
139 |
TQObject::connect(dBusWatch, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), |
| 151 |
|
140 |
this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); |
| 152 |
/* add the filter function which should be executed on events on the bus */ |
141 |
|
| 153 |
if ( ! dbus_connection_add_filter( dbus_connection, filterFunction, this, NULL) ) { |
142 |
// find already running SystemD |
| 154 |
kdFatal() << "Error: Not enough memory to add filter to dbus connection" << endl; |
143 |
TQT_DBusProxy checkSystemD(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, dBusConn); |
| 155 |
exit(EXIT_FAILURE); |
144 |
if( checkSystemD.canSend() ) { |
| 156 |
} |
145 |
TQValueList<TQT_DBusData> params; |
| 157 |
|
146 |
params << TQT_DBusData::fromString(SYSTEMD_LOGIN1_SERVICE); |
| 158 |
/* add a match rule to catch all signals going through the bus with D-Bus interface */ |
147 |
TQT_DBusMessage reply = checkSystemD.sendWithReply("NameHasOwner", params); |
| 159 |
dbus_bus_add_match( dbus_connection, "type='signal'," |
148 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 && reply[0].toBool() ) { |
| 160 |
"interface='org.freedesktop.DBus'," |
149 |
onServiceRegistered(SYSTEMD_LOGIN1_SERVICE); |
| 161 |
"member='NameOwnerChanged'", NULL); |
150 |
} |
| 162 |
|
|
|
| 163 |
/* add a match rule to catch all signals going through the bus with ConsoleKit Interface */ |
| 164 |
dbus_bus_add_match( dbus_connection, "type='signal'," |
| 165 |
"interface='org.freedesktop.ConsoleKit.Session'," |
| 166 |
"member='ActiveChanged'", NULL); |
| 167 |
|
| 168 |
m_dBusQtConnection = new DBusQt::Connection(this); |
| 169 |
m_dBusQtConnection->dbus_connection_setup_with_qt_main(dbus_connection); |
| 170 |
|
| 171 |
dbus_is_connected = true; |
| 172 |
|
| 173 |
kdDebugFuncOut(trace); |
| 174 |
return true; |
| 175 |
} |
| 176 |
|
| 177 |
/*! |
| 178 |
* This function acquire the org.freedesktop.Policy.Power interface |
| 179 |
* \return boolean with the result of the operation |
| 180 |
* \retval true if successful acquired the interface |
| 181 |
* \retval false if unsuccessful |
| 182 |
*/ |
| 183 |
bool dbusInterface::acquirePolicyPowerIface(){ |
| 184 |
kdDebugFuncIn(trace); |
| 185 |
|
| 186 |
if (dbus_connection == NULL) { |
| 187 |
kdDebugFuncOut(trace); |
| 188 |
return false; |
| 189 |
} |
151 |
} |
| 190 |
|
152 |
|
| 191 |
DBusError err; |
153 |
// find already running ConsoleKit |
| 192 |
dbus_error_init(&err); |
154 |
TQT_DBusProxy checkConsoleKit(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, dBusConn); |
| 193 |
int ret = dbus_bus_request_name(dbus_connection, "org.freedesktop.Policy.Power", |
155 |
if( checkConsoleKit.canSend() ) { |
| 194 |
DBUS_NAME_FLAG_REPLACE_EXISTING, &err); |
156 |
TQValueList<TQT_DBusData> params; |
| 195 |
if (dbus_error_is_set(&err)) { |
157 |
params << TQT_DBusData::fromString(CK_SERVICE); |
| 196 |
kdWarning() << "Acquire org.freedesktop.Policy.Power interface failed with error: " << err.message << endl; |
158 |
TQT_DBusMessage reply = checkConsoleKit.sendWithReply("NameHasOwner", params); |
| 197 |
dbus_error_free(&err); |
159 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 && reply[0].toBool() ) { |
| 198 |
} |
160 |
onServiceRegistered(CK_SERVICE); |
| 199 |
switch (ret) { |
161 |
} |
| 200 |
case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: |
|
|
| 201 |
kdDebug() << "Acquired org.freedesktop.Policy.Power interface" << endl; |
| 202 |
acquiredPolicyPower = true; |
| 203 |
break; |
| 204 |
case DBUS_REQUEST_NAME_REPLY_IN_QUEUE: |
| 205 |
kdWarning() << "Queued to acquire org.freedesktop.Policy.Power interface" << endl; |
| 206 |
acquiredPolicyPower = false; |
| 207 |
break; |
| 208 |
default: |
| 209 |
acquiredPolicyPower = false; |
| 210 |
break; |
| 211 |
} |
162 |
} |
| 212 |
|
163 |
|
| 213 |
kdDebugFuncOut(trace); |
164 |
kdDebugFuncOut(trace); |
| 214 |
return acquiredPolicyPower; |
165 |
return true; |
| 215 |
} |
166 |
} |
| 216 |
|
167 |
|
| 217 |
/*! |
168 |
/*! |
| 218 |
* This function release the org.freedesktop.Policy.Power interface |
169 |
* This function handles signals from the D-Bus daemon. |
| 219 |
* \return boolean with the result of the operation |
|
|
| 220 |
* \retval true if successful acquired the interface |
| 221 |
* \retval false if unsuccessful |
| 222 |
*/ |
170 |
*/ |
| 223 |
bool dbusInterface::releasePolicyPowerIface(){ |
171 |
void dbusInterface::handleDBusSignal(const TQT_DBusMessage& msg) { |
| 224 |
kdDebugFuncIn(trace); |
172 |
// service registered / unregistered |
| 225 |
|
173 |
if( msg.path() == DBUS_PATH_DBUS |
| 226 |
int result; |
174 |
&& msg.interface() == DBUS_INTERFACE_DBUS |
| 227 |
bool retval = false; |
175 |
&& msg.member() == "NameOwnerChanged" ) { |
| 228 |
DBusError error; |
176 |
if( msg[1].toString().isEmpty() ) { |
| 229 |
|
177 |
// old-owner is empty |
| 230 |
if (dbus_connection == NULL) { |
178 |
onServiceRegistered(msg[0].toString()); |
| 231 |
kdDebugFuncOut(trace); |
179 |
} |
| 232 |
return false; |
180 |
if( msg[2].toString().isEmpty() ) { |
| 233 |
} |
181 |
// new-owner is empty |
| 234 |
|
182 |
onServiceUnregistered(msg[0].toString()); |
| 235 |
dbus_error_init(&error); |
|
|
| 236 |
|
| 237 |
result = dbus_bus_release_name(dbus_connection, "org.freedesktop.Policy.Power", &error); |
| 238 |
|
| 239 |
if ( dbus_error_is_set( &error ) ) { |
| 240 |
kdError() << "Failed to release org.freedesktop.Policy.Power: " << error.message << endl; |
| 241 |
dbus_error_free(&error); |
| 242 |
} else { |
| 243 |
switch (result) { |
| 244 |
case DBUS_RELEASE_NAME_REPLY_RELEASED: |
| 245 |
kdDebug() << "Released org.freedesktop.Policy.Power interface" << endl; |
| 246 |
retval = true; |
| 247 |
acquiredPolicyPower = false; |
| 248 |
break; |
| 249 |
case DBUS_RELEASE_NAME_REPLY_NOT_OWNER: |
| 250 |
kdWarning() << "Couldn't release org.freedesktop.Policy.Power, not the owner" << endl; |
| 251 |
break; |
| 252 |
case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT: |
| 253 |
kdWarning() << "Couldn't release org.freedesktop.Policy.Power, Iface not existing" << endl; |
| 254 |
break; |
| 255 |
default: |
| 256 |
kdWarning() << "Couldn't release org.freedesktop.Policy.Power, unknown error" << endl; |
| 257 |
break; |
| 258 |
} |
183 |
} |
|
|
184 |
return; |
| 259 |
} |
185 |
} |
| 260 |
|
|
|
| 261 |
return retval; |
| 262 |
kdDebugFuncOut(trace); |
| 263 |
} |
| 264 |
|
186 |
|
| 265 |
/*! |
187 |
// systemd session changed |
| 266 |
* This function check if the org.freedesktop.Policy.Power |
188 |
if( systemdSeat |
| 267 |
* interface is owned by someone |
189 |
&& msg.path() == systemdSeat->path() |
| 268 |
* \return boolean with the result of the operation |
190 |
&& msg.interface() == DBUS_INTERFACE_PROPERTIES |
| 269 |
* \retval true if the interface is owned by someone |
191 |
&& msg.member() == "PropertiesChanged" |
| 270 |
* \retval false if else |
192 |
&& msg[0].toString() == SYSTEMD_LOGIN1_SEAT_IFACE) { |
| 271 |
*/ |
193 |
bool activeSessionProperty = false; |
| 272 |
bool dbusInterface::isPolicyPowerIfaceOwned(){ |
194 |
TQT_DBusDataMap<TQString> map = msg[1].toStringKeyMap(); |
| 273 |
kdDebugFuncIn(trace); |
195 |
TQT_DBusDataMap<TQString>::const_iterator it = map.begin(); |
| 274 |
|
196 |
for (; !activeSessionProperty && it != map.end(); ++it) { |
| 275 |
bool retval = false; |
197 |
if( it.key() != "ActiveSession" ) { |
| 276 |
DBusError error; |
198 |
activeSessionProperty = true; |
| 277 |
|
199 |
} |
| 278 |
if (dbus_connection == NULL) { |
200 |
} |
| 279 |
kdDebugFuncOut(trace); |
201 |
TQValueList<TQString> list = msg[2].toList().toStringList(); |
| 280 |
return false; |
202 |
TQValueList<TQString>::const_iterator it1 = list.begin(); |
|
|
203 |
for (; !activeSessionProperty && it1 != list.end(); ++it1) { |
| 204 |
if( (*it1) == "ActiveSession" ) { |
| 205 |
activeSessionProperty = true; |
| 206 |
} |
| 207 |
} |
| 208 |
if( activeSessionProperty ) { |
| 209 |
emit activeSessionChanged(checkActiveSession()); |
| 210 |
} |
| 211 |
return; |
| 281 |
} |
212 |
} |
| 282 |
|
213 |
|
| 283 |
dbus_error_init(&error); |
214 |
// consolekit session changed |
| 284 |
|
215 |
if( consolekitSeat |
| 285 |
retval = dbus_bus_name_has_owner(dbus_connection, "org.freedesktop.Policy.Power", &error); |
216 |
&& msg.path() == consolekitSeat->path() |
| 286 |
|
217 |
&& msg.interface() == CK_SEAT_IFACE |
| 287 |
if ( dbus_error_is_set( &error ) ) { |
218 |
&& msg.member() == "ActiveSessionChanged") { |
| 288 |
kdError() << "Failed to check if org.freedesktop.Policy.Power has an owner: " << error.message << endl; |
219 |
emit activeSessionChanged(msg[0].toString() == TQString(consolekitSession)); |
| 289 |
dbus_error_free(&error); |
220 |
return; |
| 290 |
} |
221 |
} |
| 291 |
|
|
|
| 292 |
kdDebugFuncOut(trace); |
| 293 |
return retval; |
| 294 |
} |
| 295 |
|
| 296 |
/* ----> DBUS section :: END <---- */ |
| 297 |
|
| 298 |
/* ----> D-Bus methode calls functions :: START <---- */ |
| 299 |
/*! |
| 300 |
* This function call a D-Bus method |
| 301 |
* \param interface TQString with te dbus interface |
| 302 |
* \param path TQString with the object path |
| 303 |
* \param object TQString with the object name |
| 304 |
* \param method TQString with the name of the methode |
| 305 |
* \param first_arg_type integer with the dbus type of the first argument |
| 306 |
* \param ... more arguments |
| 307 |
* \return If the query was successful or not |
| 308 |
*/ |
| 309 |
bool dbusInterface::dbusSystemMethodCall( TQString interface, TQString path, TQString object, TQString method, |
| 310 |
int first_arg_type, ... ) { |
| 311 |
kdDebugFuncIn(trace); |
| 312 |
|
| 313 |
bool _ret = false; |
| 314 |
va_list var_args; |
| 315 |
|
| 316 |
va_start(var_args, first_arg_type); |
| 317 |
_ret = dbusMethodCall( interface, path, object, method, DBUS_BUS_SYSTEM, |
| 318 |
NULL, -1, first_arg_type, var_args); |
| 319 |
va_end(var_args); |
| 320 |
|
| 321 |
kdDebugFuncOut(trace); |
| 322 |
return _ret; |
| 323 |
} |
222 |
} |
| 324 |
|
223 |
|
| 325 |
|
224 |
/*! |
| 326 |
/*! |
225 |
* This function handles dBus service registering |
| 327 |
* This overloaded function call a D-Bus method on the D-Bus system bus with a return value |
|
|
| 328 |
* \param interface TQString with the dbus interface |
| 329 |
* \param path TQString with the object path |
| 330 |
* \param object TQString with the object name |
| 331 |
* \param method TQString with the name of the method |
| 332 |
* \param retvalue void pointer to arguments, if NULL we make a simple call |
| 333 |
* \param retval_type Integer with the dbus type of the return value, set to -1 if retvalue is NULL |
| 334 |
* \param first_arg_type Integer with the dbus type of the first argument followed by the value |
| 335 |
* \return If the query was successful or not |
| 336 |
*/ |
| 337 |
bool dbusInterface::dbusSystemMethodCall( TQString interface, TQString path, TQString object, TQString method, |
| 338 |
void *retvalue, int retval_type, int first_arg_type, ... ) { |
| 339 |
kdDebugFuncIn(trace); |
| 340 |
|
| 341 |
bool _ret = false; |
| 342 |
va_list var_args; |
| 343 |
|
| 344 |
va_start(var_args, first_arg_type); |
| 345 |
_ret = dbusMethodCall( interface, path, object, method, DBUS_BUS_SYSTEM, |
| 346 |
retvalue, retval_type, first_arg_type, var_args); |
| 347 |
va_end(var_args); |
| 348 |
|
| 349 |
kdDebugFuncOut(trace); |
| 350 |
return _ret; |
| 351 |
} |
| 352 |
|
| 353 |
|
| 354 |
/*! |
| 355 |
* This function call a D-Bus method with a return value |
| 356 |
* \param interface TQString with the dbus interface |
| 357 |
* \param path TQString with the object path |
| 358 |
* \param object TQString with the object name |
| 359 |
* \param method TQString with the name of the method |
| 360 |
* \param dbus_type DBusBusType with the D-Bus BUS Type |
| 361 |
* \param retvalue void pointer to arguments, if NULL we make a simple call |
| 362 |
* \param retval_type Integer with the dbus type of the return value, set to -1 if retvalue is NULL |
| 363 |
* \param first_arg_type Integer with the dbus type of the first argument followed by the value |
| 364 |
* \param var_args va_list with more arguments |
| 365 |
* \return If the query was successful or not |
| 366 |
*/ |
226 |
*/ |
| 367 |
bool dbusInterface::dbusMethodCall( TQString interface, TQString path, TQString object, TQString method, |
227 |
void dbusInterface::onServiceRegistered(const TQString& service) { |
| 368 |
DBusBusType dbus_type, void *retvalue, int retval_type, int first_arg_type, |
228 |
if( service == SYSTEMD_LOGIN1_SERVICE ) { |
| 369 |
va_list var_args ) { |
229 |
// get current session |
| 370 |
kdDebugFuncIn(trace); |
230 |
TQT_DBusProxy managerIface(SYSTEMD_LOGIN1_SERVICE, SYSTEMD_LOGIN1_PATH, SYSTEMD_LOGIN1_MANAGER_IFACE, dBusConn); |
| 371 |
|
231 |
systemdSession = TQT_DBusObjectPath(); |
| 372 |
DBusMessage *message; |
232 |
if( managerIface.canSend() ) { |
| 373 |
DBusMessage *reply; |
233 |
TQValueList<TQT_DBusData> params; |
| 374 |
DBusError error; |
234 |
params << TQT_DBusData::fromUInt32( getpid() ); |
| 375 |
bool ret = false; |
235 |
TQT_DBusMessage reply = managerIface.sendWithReply("GetSessionByPID", params); |
| 376 |
|
236 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 377 |
dbus_error_init(&error); |
237 |
systemdSession = reply[0].toObjectPath(); |
| 378 |
|
238 |
} |
| 379 |
dbus_connection = dbus_bus_get(dbus_type, &error); |
239 |
} |
| 380 |
|
240 |
if( !systemdSession.isValid() ) { |
| 381 |
if (dbus_error_is_set(&error)) { |
241 |
kdWarning() << "The session is not registered with systemd" << endl; |
| 382 |
kdError() << "Could not get dbus connection: " << error.message << endl; |
242 |
return; |
| 383 |
dbus_error_free(&error); |
243 |
} |
| 384 |
goto out; |
|
|
| 385 |
} |
| 386 |
|
| 387 |
message = dbus_message_new_method_call( interface.ascii(), path.ascii(), object.ascii(), method.ascii() ); |
| 388 |
dbus_message_append_args_valist(message, first_arg_type, var_args); |
| 389 |
|
244 |
|
| 390 |
if (retvalue == NULL) { |
245 |
// get session seat |
| 391 |
if (!dbus_connection_send(dbus_connection, message, NULL)) { |
246 |
TQT_DBusProxy sessionProperties(SYSTEMD_LOGIN1_SERVICE, systemdSession, DBUS_INTERFACE_PROPERTIES, dBusConn); |
| 392 |
kdError() << "Could not send method call." << endl; |
247 |
TQT_DBusObjectPath seat; |
| 393 |
dbus_message_unref( message ); |
248 |
if( sessionProperties.canSend() ) { |
| 394 |
goto out; |
249 |
TQValueList<TQT_DBusData> params; |
|
|
250 |
params |
| 251 |
<< TQT_DBusData::fromString( SYSTEMD_LOGIN1_SESSION_IFACE ) |
| 252 |
<< TQT_DBusData::fromString( "Seat" ); |
| 253 |
TQT_DBusMessage reply = sessionProperties.sendWithReply("Get", params); |
| 254 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 255 |
seat = reply[0].toVariant().value.toStruct()[1].toObjectPath(); |
| 256 |
} |
| 395 |
} |
257 |
} |
| 396 |
} else { |
258 |
if( !seat.isValid() ) { |
| 397 |
reply = dbus_connection_send_with_reply_and_block(dbus_connection, message, -1, &error); |
259 |
kdWarning() << "Unable to associate systemd session with a seat" << endl; |
| 398 |
|
260 |
return; |
| 399 |
if (dbus_error_is_set(&error)) { |
|
|
| 400 |
kdError() << "Could not send dbus message: " << error.message << endl; |
| 401 |
dbus_message_unref(message); |
| 402 |
dbus_error_free(&error); |
| 403 |
goto out; |
| 404 |
} |
261 |
} |
| 405 |
|
262 |
|
| 406 |
int type = dbus_message_get_type(reply); |
263 |
// watch session changes |
| 407 |
if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN) { |
264 |
systemdSeat = new TQT_DBusProxy(SYSTEMD_LOGIN1_SERVICE, seat, DBUS_INTERFACE_PROPERTIES, dBusConn); |
| 408 |
if (!dbus_message_get_args(reply, &error, retval_type, retvalue, DBUS_TYPE_INVALID)){ |
265 |
TQObject::connect(systemdSeat, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), |
| 409 |
if (dbus_error_is_set(&error)) { |
266 |
this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); |
| 410 |
kdError() << "Could not get argument from reply: " |
267 |
|
| 411 |
<< error.message << endl; |
268 |
// inhibit systemd handling of power/sleep/hibernate/lid buttons |
| 412 |
dbus_error_free(&error); |
269 |
// http://www.freedesktop.org/wiki/Software/systemd/inhibit |
| 413 |
} |
270 |
if( !systemdInhibit.isValid() && managerIface.canSend() ) { |
| 414 |
dbus_message_unref(reply); |
271 |
TQValueList<TQT_DBusData> params; |
| 415 |
dbus_message_unref(message); |
272 |
params |
| 416 |
goto out; |
273 |
<< TQT_DBusData::fromString("handle-power-key:handle-suspend-key:handle-hibernate-key:handle-lid-switch") // what |
|
|
274 |
<< TQT_DBusData::fromString("TDEPowersave") // who |
| 275 |
<< TQT_DBusData::fromString("TDE handles power events") // why |
| 276 |
<< TQT_DBusData::fromString("block"); // mode |
| 277 |
TQT_DBusMessage reply = managerIface.sendWithReply("Inhibit", params); |
| 278 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 279 |
systemdInhibit = reply[0].toUnixFd(); |
| 417 |
} |
280 |
} |
| 418 |
} else { |
|
|
| 419 |
kdError() << "Revieved invalid DBUS_MESSAGE_TYPE: " << type |
| 420 |
<< "expected: " << DBUS_MESSAGE_TYPE_METHOD_RETURN << endl; |
| 421 |
dbus_message_unref(reply); |
| 422 |
dbus_message_unref(message); |
| 423 |
goto out; |
| 424 |
} |
281 |
} |
|
|
282 |
return; |
| 425 |
} |
283 |
} |
|
|
284 |
if( service == CK_SERVICE ) { |
| 285 |
// get current session |
| 286 |
TQT_DBusProxy managerIface(CK_SERVICE, CK_MANAGER_OBJECT, CK_MANAGER_IFACE, dBusConn); |
| 287 |
consolekitSession = TQT_DBusObjectPath(); |
| 288 |
if( managerIface.canSend() ) { |
| 289 |
TQValueList<TQT_DBusData> params; |
| 290 |
params << TQT_DBusData::fromUInt32( getpid() ); |
| 291 |
TQT_DBusMessage reply = managerIface.sendWithReply("GetSessionForUnixProcess", params); |
| 292 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 293 |
consolekitSession = reply[0].toObjectPath(); |
| 294 |
} |
| 295 |
} |
| 296 |
if( !consolekitSession.isValid() ) { |
| 297 |
kdWarning() << "The session is not registered with consolekit" << endl; |
| 298 |
return; |
| 299 |
} |
| 426 |
|
300 |
|
| 427 |
ret = true; // if we are here, everything should be okay |
301 |
// get session seat |
| 428 |
dbus_message_unref(message); |
302 |
TQT_DBusObjectPath seat; |
| 429 |
dbus_connection_flush(dbus_connection); |
303 |
if( dBusConn.isConnected() ) { |
| 430 |
|
304 |
TQT_DBusMessage msg = TQT_DBusMessage::methodCall(CK_SERVICE, consolekitSession, CK_SESSION_IFACE, "GetSeatId"); |
| 431 |
out: |
305 |
TQT_DBusMessage reply = dBusConn.sendWithReply(msg); |
| 432 |
kdDebugFuncOut(trace); |
306 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 433 |
return ret; |
307 |
seat = reply[0].toObjectPath(); |
| 434 |
} |
308 |
} |
| 435 |
|
309 |
} |
| 436 |
/* ----> D-Bus methode calls functions :: END <---- */ |
310 |
if( !seat.isValid() ) { |
| 437 |
/* ---> PolicyKit method call section :: START <--- */ |
311 |
kdWarning() << "Unable to associate consolekit session with a seat" << endl; |
| 438 |
|
312 |
return; |
| 439 |
/*! |
313 |
} |
| 440 |
* Check if the user is privileged to a special privilege |
|
|
| 441 |
* \param privilege TQString with the name of the requested privilege |
| 442 |
* \param udi TQString with the UDI. |
| 443 |
* \param ressource TQString with the name of the ressource |
| 444 |
* \param user TQString with the name of the user. If empty the current user is used. |
| 445 |
* \return int with info if the user is allowed or not. |
| 446 |
* \retval 0 if not allowed |
| 447 |
* \retval 1 if allowed |
| 448 |
* \retval -1 if a error occurs or we could not query the interface |
| 449 |
*/ |
| 450 |
int dbusInterface::isUserPrivileged(TQString privilege, TQString udi, TQString ressource, TQString user) { |
| 451 |
kdDebugFuncIn(trace); |
| 452 |
|
314 |
|
| 453 |
const char *_unique_name; |
315 |
// watch session changes |
| 454 |
const char *_user; |
316 |
consolekitSeat = new TQT_DBusProxy(CK_SERVICE, seat, CK_SEAT_IFACE, dBusConn); |
| 455 |
const char *_privilege; |
317 |
TQObject::connect(consolekitSeat, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), |
| 456 |
|
318 |
this, TQT_SLOT(handleDBusSignal(const TQT_DBusMessage&))); |
| 457 |
int retval = -1; |
319 |
return; |
| 458 |
|
|
|
| 459 |
if (user.isEmpty() || user.isNull()) |
| 460 |
_user = getenv("USER"); |
| 461 |
else |
| 462 |
_user = user.latin1(); |
| 463 |
|
| 464 |
if (_user == NULL || privilege.isEmpty()) |
| 465 |
goto out; |
| 466 |
|
| 467 |
_unique_name = dbus_bus_get_unique_name(dbus_connection); |
| 468 |
_privilege = privilege.latin1(); |
| 469 |
|
| 470 |
// not sure if we need this, but to avoid problems |
| 471 |
dbus_bool_t _retval; |
| 472 |
const char *_ressource; |
| 473 |
_ressource = ressource.latin1(); |
| 474 |
|
| 475 |
if (!dbusSystemMethodCall( "org.freedesktop.PolicyKit", |
| 476 |
"/org/freedesktop/PolicyKit/Manager", |
| 477 |
"org.freedesktop.PolicyKit.Manager", |
| 478 |
"IsUserPrivileged", |
| 479 |
&_retval, DBUS_TYPE_BOOLEAN, |
| 480 |
DBUS_TYPE_STRING, &_unique_name, |
| 481 |
DBUS_TYPE_STRING, &_user, |
| 482 |
DBUS_TYPE_STRING, &_privilege, |
| 483 |
DBUS_TYPE_STRING, &_ressource, |
| 484 |
DBUS_TYPE_INVALID)) { |
| 485 |
retval = -1; // only to be sure we have no changes trough the call |
| 486 |
} else { |
| 487 |
retval = (int) _retval; |
| 488 |
} |
320 |
} |
| 489 |
|
|
|
| 490 |
out: |
| 491 |
kdDebugFuncOut(trace); |
| 492 |
return retval; |
| 493 |
} |
321 |
} |
| 494 |
/* ---> PolicyKit method call section :: END <--- */ |
|
|
| 495 |
|
322 |
|
| 496 |
/*! |
323 |
/*! |
| 497 |
* Use this TQT_SLOT to emit a reviced messages to the tdepowersave. |
324 |
* This function handles dBus service unregistering |
| 498 |
* NOTE: Because of the filter function this need to be a public function. |
|
|
| 499 |
* Don't use this function in any other place than this class. |
| 500 |
* \param type enum with the type of the message |
| 501 |
* \param message String with the message |
| 502 |
* \param string String with additional info |
| 503 |
*/ |
325 |
*/ |
| 504 |
void dbusInterface::emitMsgReceived( msg_type type, TQString message, TQString string ) { |
326 |
void dbusInterface::onServiceUnregistered(const TQString& service) { |
| 505 |
|
327 |
if( service == SYSTEMD_LOGIN1_SERVICE ) { |
| 506 |
if (message.startsWith("dbus.terminate")) |
328 |
systemdInhibit.setFileDescriptor(-1); |
| 507 |
dbus_is_connected = false; |
329 |
systemdSession = TQT_DBusObjectPath(); |
| 508 |
|
330 |
if( systemdSeat ) { |
| 509 |
if (type == POLICY_POWER_OWNER_CHANGED) { |
331 |
delete systemdSeat; |
| 510 |
if (message.startsWith("NOW_OWNER")) |
332 |
} |
| 511 |
acquiredPolicyPower = true; |
333 |
return; |
| 512 |
else |
334 |
} |
| 513 |
acquiredPolicyPower = false; |
335 |
if( service == CK_SERVICE ) { |
|
|
336 |
consolekitSession = TQT_DBusObjectPath(); |
| 337 |
if( consolekitSeat ) { |
| 338 |
delete consolekitSeat; |
| 339 |
} |
| 340 |
return; |
| 514 |
} |
341 |
} |
| 515 |
|
|
|
| 516 |
emit msgReceived_withStringString( type, message, string ); |
| 517 |
} |
342 |
} |
| 518 |
|
343 |
|
| 519 |
#include "dbusInterface.moc" |
344 |
/*! |
| 520 |
// --> functions which are not member of the class ... |
345 |
* This functions is used to check if session is active |
| 521 |
|
|
|
| 522 |
/*! |
| 523 |
* This function is needed filter function for the D-Bus connection to filter |
| 524 |
* all needed messages from the bus which are needful for TDEPowersave. |
| 525 |
* \param connection existing connection to the D-Bus daemon |
| 526 |
* \param message the recieved message from the D-Bus daemon |
| 527 |
* \param data void pointer (see dbus bindings for more information) |
| 528 |
* \return DBusHandlerResult |
| 529 |
*/ |
346 |
*/ |
| 530 |
DBusHandlerResult |
347 |
bool dbusInterface::checkActiveSession() { |
| 531 |
filterFunction (DBusConnection *connection, DBusMessage *message, void */*data*/) { |
348 |
if( systemdSeat && systemdSeat->canSend() ) { |
| 532 |
kdDebugFuncIn(trace); |
349 |
TQT_DBusObjectPath activeSession; |
| 533 |
|
350 |
TQValueList<TQT_DBusData> params; |
| 534 |
bool reply_wanted; |
351 |
params |
| 535 |
char *value; |
352 |
<< TQT_DBusData::fromString( SYSTEMD_LOGIN1_SEAT_IFACE ) |
| 536 |
TQString ifaceType; |
353 |
<< TQT_DBusData::fromString( "ActiveSession" ); |
| 537 |
|
354 |
TQT_DBusMessage reply = systemdSeat->sendWithReply("Get", params); |
| 538 |
DBusError error; |
355 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 539 |
dbus_error_init( &error ); |
356 |
activeSession = reply[0].toVariant().value.toStruct()[1].toObjectPath(); |
| 540 |
|
357 |
return (activeSession == systemdSession); |
| 541 |
if (dbus_message_is_signal (message, |
|
|
| 542 |
DBUS_INTERFACE_LOCAL, |
| 543 |
"Disconnected")){ |
| 544 |
((dbusInterface*) myInstance)->emitMsgReceived( DBUS_EVENT, "dbus.terminate", 0 ); |
| 545 |
dbus_connection_unref(connection); |
| 546 |
kdDebugFuncOut(trace); |
| 547 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 548 |
} |
| 549 |
|
| 550 |
if ( dbus_message_get_type( message ) != DBUS_MESSAGE_TYPE_SIGNAL ) { |
| 551 |
if (trace) kdDebug() << "recieved message, but wasn't from type DBUS_MESSAGE_TYPE_SIGNAL" << endl; |
| 552 |
kdDebugFuncOut(trace); |
| 553 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 554 |
} |
| 555 |
|
| 556 |
ifaceType = dbus_message_get_interface( message ); |
| 557 |
if (ifaceType == NULL) { |
| 558 |
kdDebug() << "Received message from invalid interface" << endl; |
| 559 |
kdDebugFuncOut(trace); |
| 560 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 561 |
} |
| 562 |
|
| 563 |
reply_wanted = !dbus_message_get_no_reply( message ); |
| 564 |
|
| 565 |
if (ifaceType.startsWith(DBUS_INTERFACE_DBUS)) { |
| 566 |
if(trace) kdDebug() << "Received from DBUS_INTERFACE_DBUS" << endl; |
| 567 |
/* get the name of the signal */ |
| 568 |
const char *signal = dbus_message_get_member( message ); |
| 569 |
|
| 570 |
/* get the first argument. This must be a string at the moment */ |
| 571 |
dbus_message_get_args( message, &error, DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID ); |
| 572 |
|
| 573 |
if ( dbus_error_is_set( &error ) ) { |
| 574 |
kdWarning() << "Received signal " << error.message << " but no string argument" << endl; |
| 575 |
dbus_error_free( &error ); |
| 576 |
kdDebugFuncOut(trace); |
| 577 |
return DBUS_HANDLER_RESULT_HANDLED; |
| 578 |
} |
358 |
} |
| 579 |
|
359 |
} |
| 580 |
if (trace) kdDebug() << "filter_function::SIGNAL=" << signal << " VALUE=" << value << endl; |
360 |
if( consolekitSeat && consolekitSeat->canSend() ) { |
| 581 |
|
361 |
TQT_DBusObjectPath activeSession; |
| 582 |
/* our name is... */ |
362 |
TQValueList<TQT_DBusData> params; |
| 583 |
if ( ! strcmp( signal, "NameAcquired" ) ) { |
363 |
TQT_DBusMessage reply = consolekitSeat->sendWithReply("GetActiveSession", params); |
| 584 |
kdDebugFuncOut(trace); |
364 |
if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1 ) { |
| 585 |
return DBUS_HANDLER_RESULT_HANDLED; |
365 |
activeSession = reply[0].toObjectPath(); |
| 586 |
} |
366 |
return (activeSession == consolekitSession); |
| 587 |
|
|
|
| 588 |
else if ( ! strcmp( signal, "NameOwnerChanged" )) { |
| 589 |
char *service; |
| 590 |
char *old_owner; |
| 591 |
char *new_owner; |
| 592 |
|
| 593 |
if (dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &service, |
| 594 |
DBUS_TYPE_STRING, &old_owner, |
| 595 |
DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID)) { |
| 596 |
if (!strcmp(service, "org.freedesktop.Policy.Power")) { |
| 597 |
const char *own_name; |
| 598 |
|
| 599 |
own_name = dbus_bus_get_unique_name(((dbusInterface*) myInstance)->get_DBUS_connection()); |
| 600 |
|
| 601 |
if (!strcmp(new_owner, own_name)) { |
| 602 |
kdDebug() << "=== now owner of org.freedesktop.Policy.Power ===" << endl; |
| 603 |
// we have now again the ower of the name! |
| 604 |
((dbusInterface*) myInstance)->emitMsgReceived( POLICY_POWER_OWNER_CHANGED, |
| 605 |
"NOW_OWNER", |
| 606 |
NULL ); |
| 607 |
} else { |
| 608 |
// some other has now the interface |
| 609 |
kdDebug() << "=== someone owner of org.freedesktop.Policy.Power ===" << endl; |
| 610 |
((dbusInterface*) myInstance)->emitMsgReceived( POLICY_POWER_OWNER_CHANGED, |
| 611 |
"OTHER_OWNER", |
| 612 |
NULL ); |
| 613 |
} |
| 614 |
} |
| 615 |
} |
| 616 |
} |
| 617 |
kdDebugFuncOut(trace); |
| 618 |
return DBUS_HANDLER_RESULT_HANDLED; |
| 619 |
} else if (ifaceType.startsWith("org.freedesktop.ConsoleKit.Session")) { |
| 620 |
kdDebug() << "Received from org.freedesktop.ConsoleKit.Session" << endl; |
| 621 |
|
| 622 |
const char *session = dbus_message_get_path (message); |
| 623 |
const char *signal = dbus_message_get_member( message ); |
| 624 |
|
| 625 |
if (! strcmp(signal, "ActiveChanged")) { |
| 626 |
dbus_bool_t active; |
| 627 |
|
| 628 |
if (dbus_message_get_args( message, &error, DBUS_TYPE_BOOLEAN, &active, DBUS_TYPE_INVALID )) { |
| 629 |
((dbusInterface*) myInstance)->emitMsgReceived( CONSOLEKIT_SESSION_ACTIVE, |
| 630 |
session, TQString("%1").arg((int)active)); |
| 631 |
} else { |
| 632 |
if (dbus_error_is_set( &error )) dbus_error_free( &error ); |
| 633 |
} |
| 634 |
} else { |
| 635 |
kdDebug() << "Received unknown signal from org.freedesktop.ConsoleKit.Session: " |
| 636 |
<< signal << endl; |
| 637 |
kdDebugFuncOut(trace); |
| 638 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 639 |
} |
367 |
} |
| 640 |
kdDebugFuncOut(trace); |
|
|
| 641 |
return DBUS_HANDLER_RESULT_HANDLED; |
| 642 |
} else { |
| 643 |
kdDebugFuncOut(trace); |
| 644 |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| 645 |
} |
368 |
} |
|
|
369 |
return false; |
| 646 |
} |
370 |
} |
| 647 |
|
371 |
|
| 648 |
// --> some functions to get private members |
372 |
#include "dbusInterface.moc" |
| 649 |
|
|
|
| 650 |
//! to get the current connection to D-Bus |
| 651 |
DBusConnection * dbusInterface::get_DBUS_connection() { |
| 652 |
return dbus_connection; |
| 653 |
} |
| 654 |
|