~ubuntu-branches/ubuntu/dapper/gnome-screensaver/dapper

« back to all changes in this revision

Viewing changes to src/gnome-screensaver-dialog.c

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Grawert
  • Date: 2005-10-10 00:18:18 UTC
  • Revision ID: james.westby@ubuntu.com-20051010001818-3mujs05r8rht7xi1
Tags: upstream-0.0.15
ImportĀ upstreamĀ versionĀ 0.0.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2004-2005 William Jon McCann <mccann@jhu.edu>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU General Public License as
 
7
 * published by the Free Software Foundation; either version 2 of the
 
8
 * License, or (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful, but
 
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
18
 * 02111-1307, USA.
 
19
 *
 
20
 * Authors: William Jon McCann <mccann@jhu.edu>
 
21
 *
 
22
 */
 
23
 
 
24
#include "config.h"
 
25
 
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
#include <sys/time.h>
 
29
#include <sys/types.h>
 
30
#include <sys/wait.h>
 
31
 
 
32
#include <glib/gi18n.h>
 
33
#include <gdk/gdkx.h>
 
34
#include <gtk/gtk.h>
 
35
 
 
36
#include "gs-lock-plug.h"
 
37
 
 
38
#include "passwd.h"
 
39
#include "setuid.h"
 
40
 
 
41
 
 
42
/* Profiling stuff adapted from gtkfilechooserdefault */
 
43
 
 
44
#undef PROFILE_LOCK_DIALOG
 
45
#ifdef PROFILE_LOCK_DIALOG
 
46
 
 
47
#define PROFILE_INDENT 4
 
48
static int profile_indent;
 
49
 
 
50
static void
 
51
profile_add_indent (int indent)
 
52
{
 
53
        profile_indent += indent;
 
54
        if (profile_indent < 0)
 
55
                g_error ("You screwed up your indentation");
 
56
}
 
57
 
 
58
static void
 
59
_gs_lock_plug_profile_log (const char *func,
 
60
                           int         indent,
 
61
                           const char *msg1,
 
62
                           const char *msg2)
 
63
{
 
64
        char    *str;
 
65
        GTimeVal now;
 
66
 
 
67
        if (indent < 0)
 
68
                profile_add_indent (indent);
 
69
 
 
70
        g_get_current_time (&now);
 
71
 
 
72
        if (profile_indent == 0)
 
73
                str = g_strdup_printf ("MARK %ld.%6.6ld: %s: %s %s %s", now.tv_sec, now.tv_usec, G_STRLOC, func, msg1 ? msg1 : "", msg2 ? msg2 : "");
 
74
        else
 
75
                str = g_strdup_printf ("MARK %ld.%6.6ld: %s: %*c %s %s %s", now.tv_sec, now.tv_usec, G_STRLOC, profile_indent - 1, ' ', func, msg1 ? msg1 : "", msg2 ? msg2 : "");
 
76
 
 
77
        fprintf (stderr, "%s\n", str);
 
78
        g_free (str);
 
79
 
 
80
        if (indent > 0)
 
81
                profile_add_indent (indent);
 
82
}
 
83
 
 
84
#define profile_start(x, y) _gs_lock_plug_profile_log (G_STRFUNC, PROFILE_INDENT, x, y)
 
85
#define profile_end(x, y)   _gs_lock_plug_profile_log (G_STRFUNC, -PROFILE_INDENT, x, y)
 
86
#define profile_msg(x, y)   _gs_lock_plug_profile_log (NULL, 0, x, y)
 
87
#else
 
88
#define profile_start(x, y)
 
89
#define profile_end(x, y)
 
90
#define profile_msg(x, y)
 
91
#endif
 
92
 
 
93
 
 
94
static gboolean verbose       = FALSE;
 
95
static gboolean show_version  = FALSE;
 
96
static gboolean enable_logout = FALSE;
 
97
static gboolean enable_switch = FALSE;
 
98
 
 
99
static GOptionEntry entries [] = {
 
100
        { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose,
 
101
          N_("Show debugging output"), NULL },
 
102
        { "version", 0, 0, G_OPTION_ARG_NONE, &show_version,
 
103
          N_("Version of this application"), NULL },
 
104
        { "enable-logout", 0, 0, G_OPTION_ARG_NONE, &enable_logout,
 
105
          N_("Show the logout button"), NULL },
 
106
        { "enable-switch", 0, 0, G_OPTION_ARG_NONE, &enable_switch,
 
107
          N_("Show the switch user button"), NULL },
 
108
        { NULL }
 
109
};
 
110
 
 
111
static char *
 
112
get_id_string (GtkWidget *widget)
 
113
{
 
114
        char *id = NULL;
 
115
 
 
116
        g_return_val_if_fail (widget != NULL, NULL);
 
117
        g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
118
 
 
119
        id = g_strdup_printf ("0x%X",
 
120
                              (guint32) GDK_WINDOW_XID (widget->window));
 
121
        return id;
 
122
}
 
123
 
 
124
static gboolean
 
125
print_id (GtkWidget *widget)
 
126
{
 
127
        profile_start ("start", NULL);
 
128
 
 
129
        printf ("WINDOW ID=%s\n", get_id_string (widget));
 
130
        fflush (stdout);
 
131
 
 
132
        profile_end ("end", NULL);
 
133
 
 
134
        return FALSE;
 
135
}
 
136
 
 
137
static void
 
138
response_cancel (void)
 
139
{
 
140
        printf ("RESPONSE=CANCEL\n");
 
141
        fflush (stdout);
 
142
}
 
143
 
 
144
static void
 
145
response_ok (void)
 
146
{
 
147
        printf ("RESPONSE=OK\n");
 
148
        fflush (stdout);
 
149
}
 
150
 
 
151
static void
 
152
response_lock_init_failed (void)
 
153
{
 
154
        /* if we fail to lock then we should drop the dialog */
 
155
        response_ok ();
 
156
}
 
157
 
 
158
static void
 
159
response_cb (GSLockPlug *plug,
 
160
             gint        response_id)
 
161
{
 
162
        switch (response_id) {
 
163
        case (GS_LOCK_PLUG_RESPONSE_OK):
 
164
                response_ok ();
 
165
                break;
 
166
        case (GS_LOCK_PLUG_RESPONSE_CANCEL):
 
167
        default:
 
168
                response_cancel ();
 
169
                break;
 
170
        }
 
171
 
 
172
        gtk_main_quit ();
 
173
}
 
174
 
 
175
static gboolean
 
176
popup_dialog_idle (void)
 
177
{
 
178
        GtkWidget *widget;
 
179
 
 
180
        profile_start ("start", NULL);
 
181
 
 
182
        widget = gs_lock_plug_new ();
 
183
 
 
184
        if (enable_logout) {
 
185
                g_object_set (widget, "logout-enabled", TRUE, NULL);
 
186
        }
 
187
 
 
188
        if (enable_switch) {
 
189
                g_object_set (widget, "switch-enabled", TRUE, NULL);
 
190
        }
 
191
 
 
192
        g_signal_connect (GS_LOCK_PLUG (widget), "response", G_CALLBACK (response_cb), NULL);
 
193
 
 
194
        gtk_widget_show (widget);
 
195
 
 
196
        print_id (widget);
 
197
 
 
198
        profile_end ("end", NULL);
 
199
 
 
200
        return FALSE;
 
201
}
 
202
 
 
203
 
 
204
/*
 
205
 * Copyright (c) 1991-2004 Jamie Zawinski <jwz@jwz.org>
 
206
 * Copyright (c) 2005 William Jon McCann <mccann@jhu.edu>
 
207
 *
 
208
 * Initializations that potentially take place as a priveleged user:
 
209
   If the xscreensaver executable is setuid root, then these initializations
 
210
   are run as root, before discarding privileges.
 
211
*/
 
212
static gboolean
 
213
privileged_initialization (int     *argc,
 
214
                           char   **argv,
 
215
                           gboolean verbose)
 
216
{
 
217
        gboolean ret;
 
218
        char    *nolock_reason;
 
219
        char    *orig_uid;
 
220
        char    *uid_message;
 
221
 
 
222
        profile_start ("start", NULL);
 
223
 
 
224
#ifndef NO_LOCKING
 
225
        /* before hack_uid () for proper permissions */
 
226
        lock_priv_init (*argc, argv, verbose);
 
227
#endif /* NO_LOCKING */
 
228
 
 
229
        ret = hack_uid (&nolock_reason,
 
230
                        &orig_uid,
 
231
                        &uid_message);
 
232
        if (nolock_reason)
 
233
                g_warning ("Locking disabled: %s", nolock_reason);
 
234
        if (uid_message && verbose)
 
235
                g_print ("Modified UID: %s", uid_message);
 
236
 
 
237
        g_free (nolock_reason);
 
238
        g_free (orig_uid);
 
239
        g_free (uid_message);
 
240
 
 
241
        profile_end ("end", NULL);
 
242
 
 
243
        return ret;
 
244
}
 
245
 
 
246
 
 
247
/*
 
248
 * Copyright (c) 1991-2004 Jamie Zawinski <jwz@jwz.org>
 
249
 * Copyright (c) 2005 William Jon McCann <mccann@jhu.edu>
 
250
 *
 
251
 * Figure out what locking mechanisms are supported.
 
252
 */
 
253
static gboolean
 
254
lock_initialization (int     *argc,
 
255
                     char   **argv,
 
256
                     char   **nolock_reason,
 
257
                     gboolean verbose)
 
258
{
 
259
        profile_start ("start", NULL);
 
260
 
 
261
        if (nolock_reason)
 
262
                *nolock_reason = NULL;
 
263
 
 
264
#ifdef NO_LOCKING
 
265
        if (nolock_reason)
 
266
                *nolock_reason = g_strdup ("not compiled with locking support");
 
267
        return FALSE;
 
268
#else /* !NO_LOCKING */
 
269
 
 
270
        /* Finish initializing locking, now that we're out of privileged code. */
 
271
        if (! lock_init (*argc, argv, verbose)) {
 
272
                if (nolock_reason)
 
273
                        *nolock_reason = g_strdup ("error getting password");
 
274
                return FALSE;
 
275
        }
 
276
 
 
277
        /* If locking is currently enabled, but the environment indicates that
 
278
           we have been launched as GDM's "Background" program, then disable
 
279
           locking just in case.
 
280
        */
 
281
        if (getenv ("RUNNING_UNDER_GDM")) {
 
282
                if (nolock_reason)
 
283
                        *nolock_reason = g_strdup ("running under GDM");
 
284
                return FALSE;
 
285
        }
 
286
 
 
287
        /* If the server is XDarwin (MacOS X) then disable locking.
 
288
           (X grabs only affect X programs, so you can use Command-Tab
 
289
           to bring any other Mac program to the front, e.g., Terminal.)
 
290
        */
 
291
        {
 
292
                gboolean macos = FALSE;
 
293
 
 
294
#ifdef __APPLE__
 
295
                /* Disable locking if *running* on Apple hardware, since we have no
 
296
                   reliable way to determine whether the server is running on MacOS.
 
297
                   Hopefully __APPLE__ means "MacOS" and not "Linux on Mac hardware"
 
298
                   but I'm not really sure about that.
 
299
                */
 
300
                macos = TRUE;
 
301
#endif
 
302
 
 
303
                if (macos) {
 
304
                        if (nolock_reason)
 
305
                                *nolock_reason = g_strdup ("Cannot lock securely on MacOS X");
 
306
                        return FALSE;
 
307
                }
 
308
        }
 
309
 
 
310
#endif /* NO_LOCKING */
 
311
 
 
312
        profile_end ("end", NULL);
 
313
 
 
314
        return TRUE;
 
315
}
 
316
 
 
317
int
 
318
main (int    argc,
 
319
      char **argv)
 
320
{
 
321
        GError         *error = NULL;
 
322
        char           *nolock_reason = NULL;
 
323
 
 
324
#ifdef ENABLE_NLS
 
325
        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
 
326
# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
 
327
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
328
# endif 
 
329
        textdomain (GETTEXT_PACKAGE);
 
330
#endif 
 
331
 
 
332
        g_type_init ();
 
333
 
 
334
        if (error) {
 
335
                fprintf (stderr, "%s\n", error->message);
 
336
                response_lock_init_failed ();
 
337
                exit (1);
 
338
        }
 
339
 
 
340
        profile_start ("start", NULL);
 
341
 
 
342
        if (! privileged_initialization (&argc, argv, verbose)) {
 
343
                response_lock_init_failed ();
 
344
                exit (1);
 
345
        }
 
346
 
 
347
        if (! gtk_init_with_args (&argc, &argv, NULL, entries, NULL, &error)) {
 
348
                fprintf (stderr, "%s", error->message);
 
349
                g_error_free (error);
 
350
                exit (1);
 
351
        }
 
352
 
 
353
        if (show_version) {
 
354
                g_print ("%s %s\n", argv [0], VERSION);
 
355
                exit (1);
 
356
        }
 
357
 
 
358
        if (! lock_initialization (&argc, argv, &nolock_reason, verbose)) {
 
359
                if (nolock_reason) {
 
360
                        g_warning ("Screen locking disabled: %s", nolock_reason);
 
361
                        g_free (nolock_reason);
 
362
                }
 
363
                response_lock_init_failed ();
 
364
                exit (1);
 
365
        }
 
366
 
 
367
        g_idle_add ((GSourceFunc)popup_dialog_idle, NULL);
 
368
 
 
369
        gtk_main ();
 
370
 
 
371
        profile_end ("end", NULL);
 
372
 
 
373
        return 0;
 
374
}