Statistics
| Revision:

root / trunk / base / auto_shutdown_linux.c @ 1834

History | View | Annotate | Download (7 KB)

1
/* 
2
    Copyright (C) 2005-2010  Erik van Pienbroek
3

                
4
    This program is free software; you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation; either version 2 of the License, or
7
    (at your option) any later version.
8

                
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13

                
14
    You should have received a copy of the GNU General Public License
15
    along with this program; if not, write to the Free Software
16
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
*/
18

                
19
#ifdef HAVE_CONFIG_H
20
#include "config.h"
21
#endif
22

                
23
#include "nntpgrab_utils.h"
24
#if defined(HAVE_POLKIT_OLD) || defined(HAVE_POLKIT1)
25
#include 
26
#include 
27
#include 
28

                
29
#ifdef HAVE_POLKIT_OLD
30
#include 
31
#endif
32

                
33
static gboolean obtain_privileges(gpointer data);
34

                
35
static ngboolean
36
perform_shutdown_kde(void)
37
{
38
    guint retval = 0;
39
    gboolean ret;
40
    DBusGConnection *connection;
41
    DBusGProxy *proxy;
42
    GError *error = NULL;
43

                
44
    const char *service = "org.kde.ksmserver";
45
    const char *path = "/KSMServer";
46
    const char *interface = "org.kde.KSMServerInterface";
47
    const char *method = "logout";
48

                
49
    connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
50
    if (!connection) {
51
        g_print("connection = NULL: %s\n", error->message);
52
        g_error_free(error);
53
        return FALSE;
54
    }
55

                
56
    proxy = dbus_g_proxy_new_for_name_owner (connection,
57
        service,
58
        path,
59
        interface,
60
        &error);
61

                
62
    if (!proxy) {
63
        g_warning ("proxy = NULL: %s\n", error->message);
64
        g_error_free(error);
65
        dbus_g_connection_unref(connection);
66
        return FALSE;
67
    }
68
    if (DBUS_IS_G_PROXY (proxy) == FALSE) {
69
        g_warning ("not connected\n");
70
        g_object_unref (proxy);
71
        dbus_g_connection_unref(connection);
72
        return FALSE;
73
    }
74

                
75
    /* Documentation about this DBus call can be found at: 
76
     * https://api.kde.org/4.x-api/kdebase-workspace-apidocs/libs/kworkspace/html/namespaceKWorkSpace.html#a77570b74f371dd029a8baa248209bf9ba5f369481270db64e8e9716b82a4e4b02
77
     * https://majewsky.wordpress.com/category/geek-stuff/the-command-line-and-i/
78
     */
79
    ret = dbus_g_proxy_call (proxy, "logout", &error,
80
        G_TYPE_INT, 1,  /* Show confirmation dialog */
81
        G_TYPE_INT, 2,  /* Shut down the system */
82
        G_TYPE_INT, 1,  /* Shut down if no sessions are active */
83
        G_TYPE_INVALID,
84
        G_TYPE_INVALID);
85

                
86
    g_object_unref (proxy);
87
    dbus_g_connection_unref(connection);
88

                
89
    if (retval != 0) {
90
        g_warning ("%s failed in a horrible way!: %s\n", method, error->message);
91
        g_error_free(error);
92
        return FALSE;
93
    }
94

                
95
    if (error) {
96
        g_print(__FILE__ ":%i %s\n", __LINE__, error->message);
97
        g_error_free(error);
98
        return FALSE;
99
    }
100

                
101
    return TRUE;
102
}
103

                
104
static ngboolean
105
perform_shutdown_gnome(void)
106
{
107
    time_t start;
108
    time_t end;
109
    guint retval = 0;
110
    gboolean ret;
111
    DBusGConnection *connection;
112
    DBusGProxy *proxy;
113
    GError *error = NULL;
114
    //const char *service = "org.freedesktop.Hal";
115
    //const char *path = "/org/freedesktop/Hal/devices/computer";
116
    //const char *interface = "org.freedesktop.Hal.Device.SystemPowerManagement";
117

                
118
    const char *service = "org.freedesktop.PowerManagement";
119
    const char *path = "/org/freedesktop/PowerManagement";
120
    const char *interface = "org.freedesktop.PowerManagement";
121
    const char *method = "Shutdown";
122

                
123
    connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
124
    if (!connection) {
125
        g_print("connection = NULL: %s\n", error->message);
126
        g_error_free(error);
127
        return FALSE;
128
    }
129

                
130
    proxy = dbus_g_proxy_new_for_name_owner (connection,
131
        service,
132
        path,
133
        interface,
134
        &error);
135

                
136
    if (!proxy) {
137
        g_warning ("proxy = NULL: %s\n", error->message);
138
        g_error_free(error);
139
        dbus_g_connection_unref(connection);
140
        return FALSE;
141
    }
142
    if (DBUS_IS_G_PROXY (proxy) == FALSE) {
143
        g_warning ("not connected\n");
144
        g_object_unref (proxy);
145
        dbus_g_connection_unref(connection);
146
        return FALSE;
147
    }
148

                
149
    time (&start);
150
    ret = dbus_g_proxy_call (proxy, method, &error,
151
        G_TYPE_INVALID,
152
        G_TYPE_INT, &retval,
153
        G_TYPE_INVALID);
154

                
155
    g_object_unref (proxy);
156
    dbus_g_connection_unref(connection);
157

                
158
    if (retval != 0) {
159
        g_warning ("%s failed in a horrible way!: %s\n", method, error->message);
160
        g_error_free(error);
161
        return FALSE;
162
    }
163

                
164
    if (!ret) {
165
        static gboolean beenhere = FALSE;
166
#ifdef HAVE_POLKIT_OLD
167
        PolKitResult result = POLKIT_RESULT_UNKNOWN;
168

                
169
        if (!polkit_result_from_string_representation(error->message, &result)) {
170
            g_print("Failure: %s\n", error->message);
171
            g_error_free(error);
172
        }
173

                
174
        g_print("result = %i\n", result);
175
#endif
176

                
177
        g_print(__FILE__ ":%i %s\n", __LINE__, error->message);
178

                
179
        if (!beenhere) {
180
            beenhere = TRUE;
181
            obtain_privileges(error->message);
182
            nntpgrab_utils_perform_shutdown();
183
        }
184

                
185
        return FALSE;
186
    }
187

                
188
    /* compare the amount of time that has passed - if it's more than 6 hours 
189
     * then the dbus call timed out (dbus-pending-call.c) */
190
    time (&end);
191
    if (difftime (start,end) >= 6*60*60*1000) {
192
        g_print("DBUS call timed out\n");
193
        return FALSE;
194
    }
195

                
196
    g_print("Success\n");
197

                
198
    return ret;
199
}
200
#endif
201

                
202
#ifdef HAVE_POLKIT_OLD
203
static void
204
auth_cb(PolKitAction *action, gboolean gained_privilege, GError *error, gpointer data)
205
{
206
    polkit_action_debug(action);
207

                
208
    g_print("gained_privilege = %i\n", gained_privilege);
209
    if (error) {
210
        g_print("Error: %s\n", error->message);
211
    }
212

                
213
    if (!gained_privilege) {
214
        g_print("Unable to gain privilege\n");
215
        g_print("error = %#x\n", error);
216
    } else {
217
        g_print("Privilege gained, now shutting down\n");
218
        nntpgrab_utils_perform_shutdown();
219
    }
220

                
221
    gtk_main_quit();
222
}
223

                
224
static gboolean
225
obtain_privileges(gpointer data)
226
{
227
    PolKitAction *polkit_action;
228
    GError *error = NULL;
229

                
230
    g_print("obtain privileges\n");
231

                
232
    polkit_action = polkit_action_new();
233
    polkit_action_set_action_id (polkit_action, (const char*) data);
234

                
235
    if (!polkit_gnome_auth_obtain(polkit_action, 0, getpid(), auth_cb, NULL, &error)) {
236
        g_print("Error occured: %s\n", error->message);
237
        g_error_free(error);
238
        return FALSE;
239
    }
240

                
241
    g_print("Success\n");
242

                
243
    return FALSE;
244
}
245
#endif
246

                
247
#ifdef HAVE_POLKIT1
248
static gboolean
249
obtain_privileges(gpointer data)
250
{
251
    return FALSE;
252
}
253
#endif
254

                
255
ngboolean
256
nntpgrab_utils_perform_shutdown(void)
257
{
258
#if defined(HAVE_POLKIT_OLD) || defined(HAVE_POLKIT1)
259
    if (!perform_shutdown_gnome() && !perform_shutdown_kde()) {
260
        return FALSE;
261
    }
262
#else
263
    return FALSE;
264
#endif
265
}