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
;
37 static char *console_kit_get_first_seat(struct console_kit
*ck
);
38 static char *console_kit_check_active_session_change(struct console_kit
*ck
);
40 struct console_kit
*console_kit_create(FILE *errfile
)
42 struct console_kit
*ck
;
46 ck
= calloc(1, sizeof(*ck
));
50 ck
->errfile
= errfile
;
52 dbus_error_init(&error
);
53 ck
->connection
= dbus_bus_get_private(DBUS_BUS_SYSTEM
, &error
);
54 if (ck
->connection
== NULL
|| dbus_error_is_set(&error
)) {
55 if (dbus_error_is_set(&error
)) {
56 fprintf(ck
->errfile
, "Unable to connect to system bus: %s\n",
58 dbus_error_free(&error
);
60 fprintf(ck
->errfile
, "Unable to connect to system bus\n");
65 if (!dbus_connection_get_unix_fd(ck
->connection
, &ck
->fd
)) {
66 fprintf(ck
->errfile
, "Unable to get connection fd\n");
67 console_kit_destroy(ck
);
71 if (!console_kit_get_first_seat(ck
)) {
72 console_kit_destroy(ck
);
76 /* Register for active session changes */
77 snprintf(match
, sizeof(match
),
78 "type='signal',interface='org.freedesktop.ConsoleKit.Seat',"
79 "path='%s',member='ActiveSessionChanged'", ck
->seat
);
80 dbus_error_init(&error
);
81 dbus_bus_add_match(ck
->connection
, match
, &error
);
82 if (dbus_error_is_set(&error
)) {
83 fprintf(ck
->errfile
, "Match Error (%s)\n", error
.message
);
84 console_kit_destroy(ck
);
88 if (!console_kit_get_active_session(ck
)) {
89 console_kit_destroy(ck
);
96 void console_kit_destroy(struct console_kit
*ck
)
101 dbus_connection_close(ck
->connection
);
103 free(ck
->active_session
);
107 int console_kit_get_fd(struct console_kit
*ck
)
112 static char *console_kit_get_first_seat(struct console_kit
*ck
)
115 DBusMessage
*message
= NULL
;
116 DBusMessage
*reply
= NULL
;
117 DBusMessageIter iter
, subiter
;
121 message
= dbus_message_new_method_call("org.freedesktop.ConsoleKit",
122 "/org/freedesktop/ConsoleKit/Manager",
123 "org.freedesktop.ConsoleKit.Manager",
125 if (message
== NULL
) {
126 fprintf(ck
->errfile
, "Unable to create dbus message\n");
130 dbus_error_init(&error
);
131 reply
= dbus_connection_send_with_reply_and_block(ck
->connection
,
135 if (reply
== NULL
|| dbus_error_is_set(&error
)) {
136 if (dbus_error_is_set(&error
)) {
137 fprintf(ck
->errfile
, "GetSeats failed: %s\n",
139 dbus_error_free(&error
);
141 fprintf(ck
->errfile
, "GetSeats failed\n");
145 dbus_message_iter_init(reply
, &iter
);
146 type
= dbus_message_iter_get_arg_type(&iter
);
147 if (type
!= DBUS_TYPE_ARRAY
) {
149 "expected an array return value, got a '%c' instead\n", type
);
153 dbus_message_iter_recurse(&iter
, &subiter
);
154 type
= dbus_message_iter_get_arg_type(&subiter
);
155 if (type
!= DBUS_TYPE_OBJECT_PATH
) {
157 "expected an object path element, got a '%c' instead\n", type
);
161 dbus_message_iter_get_basic(&subiter
, &seat
);
162 ck
->seat
= strdup(seat
);
166 dbus_message_unref(reply
);
169 if (message
!= NULL
) {
170 dbus_message_unref(message
);
176 const char *console_kit_get_active_session(struct console_kit
*ck
)
179 DBusMessage
*message
= NULL
;
180 DBusMessage
*reply
= NULL
;
181 char *session
= NULL
;
186 if (ck
->active_session
)
187 return console_kit_check_active_session_change(ck
);
189 message
= dbus_message_new_method_call("org.freedesktop.ConsoleKit",
191 "org.freedesktop.ConsoleKit.Seat",
193 if (message
== NULL
) {
194 fprintf(ck
->errfile
, "Unable to create dbus message\n");
198 dbus_error_init(&error
);
199 reply
= dbus_connection_send_with_reply_and_block(ck
->connection
,
203 if (reply
== NULL
|| dbus_error_is_set(&error
)) {
204 if (dbus_error_is_set(&error
)) {
205 fprintf(ck
->errfile
, "GetSeats failed: %s\n",
207 dbus_error_free(&error
);
209 fprintf(ck
->errfile
, "GetSeats failed\n");
213 dbus_error_init(&error
);
214 if (!dbus_message_get_args(reply
,
216 DBUS_TYPE_OBJECT_PATH
, &session
,
217 DBUS_TYPE_INVALID
)) {
218 if (dbus_error_is_set(&error
)) {
219 fprintf(ck
->errfile
, "error getting ssid from reply: %s\n",
221 dbus_error_free(&error
);
223 fprintf(ck
->errfile
, "error getting ssid from reply\n");
228 ck
->active_session
= strdup(session
);
232 dbus_message_unref(reply
);
235 if (message
!= NULL
) {
236 dbus_message_unref(message
);
239 return ck
->active_session
;
242 char *console_kit_session_for_pid(struct console_kit
*ck
, uint32_t pid
)
245 DBusMessage
*message
= NULL
;
246 DBusMessage
*reply
= NULL
;
247 DBusMessageIter args
;
253 message
= dbus_message_new_method_call("org.freedesktop.ConsoleKit",
254 "/org/freedesktop/ConsoleKit/Manager",
255 "org.freedesktop.ConsoleKit.Manager",
256 "GetSessionForUnixProcess");
257 if (message
== NULL
) {
258 fprintf(ck
->errfile
, "Unable to create dbus message\n");
262 dbus_message_iter_init_append(message
, &args
);
263 if (!dbus_message_iter_append_basic(&args
, DBUS_TYPE_UINT32
, &pid
)) {
264 fprintf(ck
->errfile
, "Unable to append dbus message args\n");
268 dbus_error_init(&error
);
269 reply
= dbus_connection_send_with_reply_and_block(ck
->connection
,
273 if (reply
== NULL
|| dbus_error_is_set(&error
)) {
274 if (dbus_error_is_set(&error
)) {
275 fprintf(ck
->errfile
, "GetSessionForUnixProcess failed: %s\n",
277 dbus_error_free(&error
);
279 fprintf(ck
->errfile
, "GetSessionForUnixProces failed\n");
283 dbus_error_init(&error
);
284 if (!dbus_message_get_args(reply
,
286 DBUS_TYPE_OBJECT_PATH
, &ssid
,
287 DBUS_TYPE_INVALID
)) {
288 if (dbus_error_is_set(&error
)) {
289 fprintf(ck
->errfile
, "error getting ssid from reply: %s\n",
291 dbus_error_free(&error
);
293 fprintf(ck
->errfile
, "error getting ssid from reply\n");
302 dbus_message_unref(reply
);
305 if (message
!= NULL
) {
306 dbus_message_unref(message
);
312 static char *console_kit_check_active_session_change(struct console_kit
*ck
)
314 DBusMessage
*message
= NULL
;
315 DBusMessageIter iter
;
319 /* non blocking read of the next available message */
320 dbus_connection_read_write(ck
->connection
, 0);
321 while ((message
= dbus_connection_pop_message(ck
->connection
))) {
322 if (dbus_message_get_type(message
) == DBUS_MESSAGE_TYPE_SIGNAL
) {
323 const char *member
= dbus_message_get_member (message
);
324 if (!strcmp(member
, "NameAcquired")) {
325 dbus_message_unref(message
);
328 if (strcmp(member
, "ActiveSessionChanged")) {
329 fprintf(ck
->errfile
, "unexpected signal member: %s\n", member
);
330 dbus_message_unref(message
);
334 fprintf(ck
->errfile
, "received non signal message!\n");
335 dbus_message_unref(message
);
339 free(ck
->active_session
);
340 ck
->active_session
= NULL
;
342 dbus_message_iter_init(message
, &iter
);
343 type
= dbus_message_iter_get_arg_type(&iter
);
344 /* Session should be an object path, but there is a bug in
345 ConsoleKit where it sends a string rather then an object_path
346 accept object_path too in case the bug ever gets fixed */
347 if (type
!= DBUS_TYPE_STRING
&& type
!= DBUS_TYPE_OBJECT_PATH
) {
349 "ActiveSessionChanged message has unexpected type: '%c'\n",
351 dbus_message_unref(message
);
355 dbus_message_iter_get_basic(&iter
, &session
);
356 ck
->active_session
= strdup(session
);
357 dbus_message_unref(message
);
359 /* non blocking read of the next available message */
360 dbus_connection_read_write(ck
->connection
, 0);
363 return ck
->active_session
;