1 /* console-kit.h vdagentd ConsoleKit integration code
3 Copyright 2010 Red Hat, Inc.
6 Hans de Goede <hdegoede@redhat.com>
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "console-kit.h"
23 #include <dbus/dbus.h>
30 DBusConnection
*connection
;
36 static char *console_kit_get_first_seat(struct console_kit
*ck
);
37 static char *console_kit_check_active_session_change(struct console_kit
*ck
);
39 struct console_kit
*console_kit_create(FILE *errfile
)
41 struct console_kit
*ck
;
45 ck
= calloc(1, sizeof(*ck
));
49 ck
->errfile
= errfile
;
51 dbus_error_init(&error
);
52 ck
->connection
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
);
53 if (ck
->connection
== NULL
|| dbus_error_is_set(&error
)) {
54 if (dbus_error_is_set(&error
)) {
55 fprintf(ck
->errfile
, "Unable to connect to system bus: %s\n",
57 dbus_error_free(&error
);
59 fprintf(ck
->errfile
, "Unable to connect to system bus\n");
64 if (!console_kit_get_first_seat(ck
)) {
65 console_kit_destroy(ck
);
69 /* Register for active session changes */
70 snprintf(match
, sizeof(match
),
71 "type='signal',interface='org.freedesktop.ConsoleKit.Seat',"
72 "path='%s',member='ActiveSessionChanged'", ck
->seat
);
73 dbus_error_init(&error
);
74 dbus_bus_add_match(ck
->connection
, match
, &error
);
75 if (dbus_error_is_set(&error
)) {
76 fprintf(ck
->errfile
, "Match Error (%s)\n", error
.message
);
77 console_kit_destroy(ck
);
81 if (!console_kit_get_active_session(ck
)) {
82 console_kit_destroy(ck
);
89 void console_kit_destroy(struct console_kit
*ck
)
94 dbus_connection_close(ck
->connection
);
96 free(ck
->active_session
);
100 static char *console_kit_get_first_seat(struct console_kit
*ck
)
103 DBusMessage
*message
= NULL
;
104 DBusMessage
*reply
= NULL
;
105 DBusMessageIter iter
, subiter
;
109 message
= dbus_message_new_method_call("org.freedesktop.ConsoleKit",
110 "/org/freedesktop/ConsoleKit/Manager",
111 "org.freedesktop.ConsoleKit.Manager",
113 if (message
== NULL
) {
114 fprintf(ck
->errfile
, "Unable to create dbus message\n");
118 dbus_error_init(&error
);
119 reply
= dbus_connection_send_with_reply_and_block(ck
->connection
,
123 if (reply
== NULL
|| dbus_error_is_set(&error
)) {
124 if (dbus_error_is_set(&error
)) {
125 fprintf(ck
->errfile
, "GetSeats failed: %s\n",
127 dbus_error_free(&error
);
129 fprintf(ck
->errfile
, "GetSeats failed\n");
133 dbus_message_iter_init(reply
, &iter
);
134 type
= dbus_message_iter_get_arg_type(&iter
);
135 if (type
!= DBUS_TYPE_ARRAY
) {
137 "expected an array return value, got a '%c' instead\n", type
);
141 dbus_message_iter_recurse(&iter
, &subiter
);
142 type
= dbus_message_iter_get_arg_type(&subiter
);
143 if (type
!= DBUS_TYPE_OBJECT_PATH
) {
145 "expected an object path element, got a '%c' instead\n", type
);
149 dbus_message_iter_get_basic(&subiter
, &seat
);
150 ck
->seat
= strdup(seat
);
154 dbus_message_unref(reply
);
157 if (message
!= NULL
) {
158 dbus_message_unref(message
);
164 const char *console_kit_get_active_session(struct console_kit
*ck
)
167 DBusMessage
*message
= NULL
;
168 DBusMessage
*reply
= NULL
;
169 char *session
= NULL
;
174 if (ck
->active_session
)
175 return console_kit_check_active_session_change(ck
);
177 message
= dbus_message_new_method_call("org.freedesktop.ConsoleKit",
179 "org.freedesktop.ConsoleKit.Seat",
181 if (message
== NULL
) {
182 fprintf(ck
->errfile
, "Unable to create dbus message\n");
186 dbus_error_init(&error
);
187 reply
= dbus_connection_send_with_reply_and_block(ck
->connection
,
191 if (reply
== NULL
|| dbus_error_is_set(&error
)) {
192 if (dbus_error_is_set(&error
)) {
193 fprintf(ck
->errfile
, "GetSeats failed: %s\n",
195 dbus_error_free(&error
);
197 fprintf(ck
->errfile
, "GetSeats failed\n");
201 dbus_error_init(&error
);
202 if (!dbus_message_get_args(reply
,
204 DBUS_TYPE_OBJECT_PATH
, &session
,
205 DBUS_TYPE_INVALID
)) {
206 if (dbus_error_is_set(&error
)) {
207 fprintf(ck
->errfile
, "error getting ssid from reply: %s\n",
209 dbus_error_free(&error
);
211 fprintf(ck
->errfile
, "error getting ssid from reply\n");
216 ck
->active_session
= strdup(session
);
220 dbus_message_unref(reply
);
223 if (message
!= NULL
) {
224 dbus_message_unref(message
);
227 return ck
->active_session
;
230 const char *console_kit_session_for_pid(struct console_kit
*ck
, uint32_t pid
)
233 DBusMessage
*message
= NULL
;
234 DBusMessage
*reply
= NULL
;
235 DBusMessageIter args
;
241 message
= dbus_message_new_method_call("org.freedesktop.ConsoleKit",
242 "/org/freedesktop/ConsoleKit/Manager",
243 "org.freedesktop.ConsoleKit.Manager",
244 "GetSessionForUnixProcess");
245 if (message
== NULL
) {
246 fprintf(ck
->errfile
, "Unable to create dbus message\n");
250 dbus_message_iter_init_append(message
, &args
);
251 if (!dbus_message_iter_append_basic(&args
, DBUS_TYPE_UINT32
, &pid
)) {
252 fprintf(ck
->errfile
, "Unable to append dbus message args\n");
256 dbus_error_init(&error
);
257 reply
= dbus_connection_send_with_reply_and_block(ck
->connection
,
261 if (reply
== NULL
|| dbus_error_is_set(&error
)) {
262 if (dbus_error_is_set(&error
)) {
263 fprintf(ck
->errfile
, "GetSessionForUnixProcess failed: %s\n",
265 dbus_error_free(&error
);
267 fprintf(ck
->errfile
, "GetSessionForUnixProces failed\n");
271 dbus_error_init(&error
);
272 if (!dbus_message_get_args(reply
,
274 DBUS_TYPE_OBJECT_PATH
, &ssid
,
275 DBUS_TYPE_INVALID
)) {
276 if (dbus_error_is_set(&error
)) {
277 fprintf(ck
->errfile
, "error getting ssid from reply: %s\n",
279 dbus_error_free(&error
);
281 fprintf(ck
->errfile
, "error getting ssid from reply\n");
290 dbus_message_unref(reply
);
293 if (message
!= NULL
) {
294 dbus_message_unref(message
);
300 static char *console_kit_check_active_session_change(struct console_kit
*ck
)
302 DBusMessage
*message
= NULL
;
303 DBusMessageIter iter
;
307 /* non blocking read of the next available message */
308 dbus_connection_read_write(ck
->connection
, 0);
309 while ((message
= dbus_connection_pop_message(ck
->connection
))) {
310 if (dbus_message_get_type(message
) == DBUS_MESSAGE_TYPE_SIGNAL
) {
311 const char *member
= dbus_message_get_member (message
);
312 if (!strcmp(member
, "NameAcquired")) {
313 dbus_message_unref(message
);
316 if (strcmp(member
, "ActiveSessionChanged")) {
317 fprintf(ck
->errfile
, "unexpected signal member: %s\n", member
);
318 dbus_message_unref(message
);
322 fprintf(ck
->errfile
, "received non signal message!\n");
323 dbus_message_unref(message
);
327 free(ck
->active_session
);
328 ck
->active_session
= NULL
;
330 dbus_message_iter_init(message
, &iter
);
331 type
= dbus_message_iter_get_arg_type(&iter
);
332 /* Session should be an object path, but there is a bug in
333 ConsoleKit where it sends a string rather then an object_path
334 accept object_path too in case the bug ever gets fixed */
335 if (type
!= DBUS_TYPE_STRING
&& type
!= DBUS_TYPE_OBJECT_PATH
) {
337 "ActiveSessionChanged message has unexpected type: '%c'\n",
339 dbus_message_unref(message
);
343 dbus_message_iter_get_basic(&iter
, &session
);
344 ck
->active_session
= strdup(session
);
345 dbus_message_unref(message
);
347 /* non blocking read of the next available message */
348 dbus_connection_read_write(ck
->connection
, 0);
351 return ck
->active_session
;