~ilidrissi.amine/ubuntu/maverick/gdm/gdm.fix-617044

« back to all changes in this revision

Viewing changes to utils/gdm-set-default-session.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2010-06-22 13:26:45 UTC
  • Revision ID: james.westby@ubuntu.com-20100622132645-c530n4nbftv40mm4
Tags: 2.30.2-0ubuntu4
* debian/control:
  - Build-depend on gnome-common for autotools
* debian/rules:
  - Run autotools on build
* debian/source:
  - Use source format 3.0
* debian/patches/*:
  - Use quilt and fix patch headers
* debian/patches/09_gdmsetup.patch:
  - Add checkbutton for enabling face browser (LP: #445123)
* debian/patches/99_autoreconf.patch:
  - Removed, autotools now run from debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifdef HAVE_CONFIG_H
 
2
#include "config.h"
 
3
#endif
 
4
 
 
5
#include <stdlib.h>
 
6
#include <unistd.h>
 
7
 
 
8
#include <glib.h>
 
9
#include <glib/gi18n.h>
 
10
#include <dbus/dbus-glib-bindings.h>
 
11
 
 
12
#define GDM_SETTINGS_DBUS_NAME "org.gnome.DisplayManager"
 
13
#define GDM_SETTINGS_DBUS_PATH "/org/gnome/DisplayManager/Settings"
 
14
#define GDM_SETTINGS_DBUS_INTERFACE "org.gnome.DisplayManager.Settings"
 
15
 
 
16
#define SESSION_KEY_GROUP "daemon"
 
17
#define SESSION_KEY_NAME  "DefaultSession"
 
18
 
 
19
typedef enum {
 
20
    CONNEXIONSUCCEED,
 
21
    CONNEXIONFAILED,
 
22
    ALREADYHASVALUE,
 
23
    HASNOVALUE,
 
24
    VALUEFOUND
 
25
} DBusState;
 
26
 
 
27
static gboolean debug = FALSE;
 
28
static gboolean keepold = FALSE;
 
29
static gboolean remove = FALSE;
 
30
 
 
31
static GOptionEntry entries[] =
 
32
{
 
33
  { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Enable debugging", NULL },
 
34
  { "keep-old", 'k', 0, G_OPTION_ARG_NONE, &keepold, "Only update if no default already set", NULL },
 
35
  { "remove", 'r', 0, G_OPTION_ARG_NONE, &remove, "Remove default session if it's this one", NULL },
 
36
  { NULL }
 
37
};
 
38
 
 
39
void
 
40
show_nothing(const gchar   *log_domain,
 
41
             GLogLevelFlags log_level,
 
42
             const gchar   *message,
 
43
             gpointer       unused_data) {};
 
44
 
 
45
int
 
46
init_dbus_connection(DBusGProxy **proxy) {
 
47
    DBusGConnection *connection;
 
48
    GError          *error = NULL;
 
49
 
 
50
    connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
 
51
    if (connection == NULL) {
 
52
         g_debug ("Can't connect to system bus: %s", error->message);
 
53
         g_error_free (error);
 
54
         return(CONNEXIONFAILED);
 
55
    }
 
56
 
 
57
    *proxy = dbus_g_proxy_new_for_name_owner (connection,
 
58
                                              GDM_SETTINGS_DBUS_NAME,
 
59
                                              GDM_SETTINGS_DBUS_PATH,
 
60
                                              GDM_SETTINGS_DBUS_INTERFACE,
 
61
                                              &error);
 
62
    if(!*proxy) {
 
63
         g_debug ("No object on the bus: %s", error->message);
 
64
         g_error_free (error);
 
65
         return(CONNEXIONFAILED);
 
66
    }
 
67
 
 
68
    return(CONNEXIONSUCCEED);
 
69
}
 
70
 
 
71
int
 
72
get_default_session_name_with_dbus(DBusGProxy *proxy, gchar **name)
 
73
{
 
74
    GError *error = NULL;
 
75
 
 
76
    if (!dbus_g_proxy_call (proxy, "GetValue", &error,
 
77
                            G_TYPE_STRING, SESSION_KEY_GROUP "/" SESSION_KEY_NAME, G_TYPE_INVALID,
 
78
                            G_TYPE_STRING, name, G_TYPE_INVALID)) {
 
79
        // This probably (_owner used previously) means that the value doesn't exist in config file
 
80
        if(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_REMOTE_EXCEPTION) {
 
81
            g_debug ("Probably no value registered: %s. %s", dbus_g_error_get_name (error), error->message);
 
82
            g_error_free (error);
 
83
            return(HASNOVALUE);
 
84
        }
 
85
        // possible if GDM_SETTINGS_DBUS_PATH or GDM_SETTINGS_DBUS_INTERFACE aren't exposed by the
 
86
        // existing GDM_SETTINGS_DBUS_NAME (shouldn't happen)
 
87
        else {
 
88
            g_debug ("No GDM_SETTINGS_DBUS_PATH or GDM_SETTINGS_DBUS_INTERFACE on the bus: %s", error->message);
 
89
            g_error_free (error);
 
90
            return(CONNEXIONFAILED);
 
91
        }
 
92
    }
 
93
    return(VALUEFOUND);
 
94
 
 
95
}
 
96
 
 
97
int
 
98
set_default_session_name_with_dbus(DBusGProxy *proxy, gchar *sessionname)
 
99
{
 
100
    GError *error = NULL;
 
101
    
 
102
    dbus_g_proxy_call (proxy, "SetValue", &error,
 
103
                       G_TYPE_STRING, SESSION_KEY_GROUP "/" SESSION_KEY_NAME,
 
104
                       G_TYPE_STRING, sessionname, G_TYPE_INVALID, G_TYPE_INVALID);
 
105
    if (error) {
 
106
        g_debug ("Error changing default session value to '%s': %s\nNo update will be done", sessionname, error->message);
 
107
        g_error_free (error);
 
108
        return FALSE;
 
109
    }
 
110
    
 
111
    return TRUE;
 
112
}
 
113
 
 
114
int
 
115
update_session_if_needed(gchar *default_session, gchar *proposed_session, gboolean dbusupdate, gpointer *parameter)
 
116
{
 
117
    DBusGProxy      *proxy = NULL;
 
118
    GKeyFile        *keyfile = NULL;
 
119
    gboolean         success = FALSE;
 
120
 
 
121
    if (dbusupdate)
 
122
        proxy = (DBusGProxy *) parameter;
 
123
    else {
 
124
        keyfile = (GKeyFile *) parameter;
 
125
        success = TRUE; // by default, the function succeed (return void)
 
126
    }
 
127
        
 
128
    if (!(default_session)) {
 
129
        g_debug("No value previously set. Update to %s", proposed_session);
 
130
        if (dbusupdate)
 
131
            success = set_default_session_name_with_dbus(proxy, proposed_session);
 
132
        else
 
133
            g_key_file_set_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, proposed_session);
 
134
    }
 
135
    else {
 
136
        if (remove) {
 
137
            if (g_strcmp0(proposed_session, default_session) == 0) {
 
138
                g_debug("Remove %s as default session", proposed_session);
 
139
                if (dbusupdate)
 
140
                    success = set_default_session_name_with_dbus(proxy, "");
 
141
                else
 
142
                    g_key_file_set_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, "");
 
143
                if (!success)
 
144
                    return(2);
 
145
                return(0);
 
146
            }
 
147
            g_debug("Don't remove: %s not default session", proposed_session);
 
148
            return(4);
 
149
        }
 
150
        if (strlen(default_session) < 1) {
 
151
            g_debug("Empty value set as gdm default session. Set to %s", proposed_session);
 
152
            if (dbusupdate)
 
153
                success = set_default_session_name_with_dbus(proxy, proposed_session);
 
154
            else
 
155
                g_key_file_set_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, proposed_session);
 
156
        }
 
157
        else {
 
158
            g_debug("Found existing default session: %s", default_session);
 
159
            if(keepold)
 
160
                g_debug("keep-old mode: keep previous default session");
 
161
            else {
 
162
                g_debug("Update to %s", proposed_session);
 
163
                if (dbusupdate)
 
164
                    success = set_default_session_name_with_dbus(proxy, proposed_session);
 
165
                else
 
166
                    g_key_file_set_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, proposed_session);
 
167
            }
 
168
        }
 
169
    }
 
170
    if (!success)
 
171
        return(2);
 
172
    return(0);
 
173
}
 
174
 
 
175
int 
 
176
main (int argc, char *argv[])
 
177
{
 
178
    GOptionContext *context = NULL;
 
179
    GError         *error = NULL;
 
180
 
 
181
    DBusGProxy     *proxy = NULL;
 
182
    DBusState       return_dbus_code = CONNEXIONFAILED;
 
183
    gboolean        dbus_connexion_ok = FALSE;
 
184
 
 
185
    GKeyFile       *keyfile;
 
186
    GKeyFileFlags   flags;
 
187
    gchar          *s_data;
 
188
    gsize           size;
 
189
    const gchar    *gdm_conf_file = GDMCONFDIR "/custom.conf";
 
190
 
 
191
    gchar          *default_session = NULL;
 
192
    gchar          *proposed_session = NULL;
 
193
    gint            return_code;
 
194
 
 
195
    g_type_init ();
 
196
 
 
197
    context = g_option_context_new (_("- set gdm default session"));
 
198
    g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
 
199
    if (!g_option_context_parse (context, &argc, &argv, &error)) {
 
200
        g_printerr (_("option parsing failed: %s\n"), error->message);
 
201
        g_option_context_free(context);
 
202
        g_error_free (error);
 
203
        exit (1);
 
204
    }
 
205
    if (argc!=2) {
 
206
        g_printerr(_("Wrong usage of the command\n%s"), g_option_context_get_help (context, FALSE, NULL));
 
207
        g_option_context_free(context); 
 
208
        exit(1);
 
209
    }
 
210
    if (context)
 
211
        g_option_context_free(context); 
 
212
    if (!debug)
 
213
        g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, show_nothing, NULL);
 
214
    proposed_session = argv[1];
 
215
 
 
216
 
 
217
    if (init_dbus_connection(&proxy) == CONNEXIONSUCCEED) {
 
218
        return_dbus_code = get_default_session_name_with_dbus(proxy, &default_session);
 
219
        if (return_dbus_code == CONNEXIONFAILED)
 
220
            dbus_connexion_ok = FALSE; // dbus and service connexion ok, but can't access proxy
 
221
        else {
 
222
            dbus_connexion_ok = TRUE;
 
223
            if (return_dbus_code == HASNOVALUE)
 
224
                default_session = NULL;
 
225
            return_code = update_session_if_needed (default_session, proposed_session, TRUE, (gpointer *) proxy);
 
226
        }
 
227
    }
 
228
    if (proxy)
 
229
       g_object_unref (proxy);
 
230
 
 
231
    if (!dbus_connexion_ok) {
 
232
        g_debug ("Can't change value by dbus, failback in %s direct modification", gdm_conf_file);
 
233
        if (geteuid() != 0) {
 
234
            g_printerr ("Updating directly %s requires root permission\n", gdm_conf_file);
 
235
            exit(1);
 
236
        }
 
237
        keyfile = g_key_file_new ();
 
238
        flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
 
239
        if (!(g_key_file_load_from_file (keyfile, gdm_conf_file, flags, &error))) {
 
240
            g_debug ("File doesn't seem to exist or can't be read: create one (%s)", error->message);
 
241
            g_error_free (error);
 
242
            error = NULL;
 
243
        }
 
244
        // try to get the right key
 
245
        default_session = g_key_file_get_string (keyfile, SESSION_KEY_GROUP, SESSION_KEY_NAME, NULL);
 
246
        return_code = update_session_if_needed (default_session, proposed_session, FALSE, (gpointer *) keyfile);
 
247
        if(return_code == 0) {
 
248
            s_data = g_key_file_to_data (keyfile, &size, &error);
 
249
            if (!s_data) {
 
250
                g_debug ("Can't convert data to string: %s", error->message);
 
251
                g_error_free (error);
 
252
                return_code = 1;
 
253
            }
 
254
            else {
 
255
                if(!g_file_set_contents (gdm_conf_file, s_data, size, &error)) {
 
256
                    g_printerr ("Can't update: %s\n", error->message);
 
257
                    g_error_free (error);
 
258
                    return_code = 1;
 
259
                }
 
260
                g_free(s_data);
 
261
             }
 
262
        }
 
263
        g_key_file_free(keyfile);
 
264
    }
 
265
 
 
266
    if(default_session)
 
267
        g_free(default_session);
 
268
 
 
269
    exit(return_code);
 
270
 
 
271
}