~darkxst/ubuntu/saucy/gdm/lp1212408

« back to all changes in this revision

Viewing changes to daemon/gdmconfig.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2008-09-02 10:37:20 UTC
  • mfrom: (1.4.27 upstream)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: james.westby@ubuntu.com-20080902103720-p810vv530hqj45wg
Tags: 2.20.7-3
* Install the debian-moreblue-orbit theme, thanks Andre Luiz Rodrigues 
  Ferreira. Closes: #497440.
* 35_gdm.conf.patch: make it the default.
* copyright: fix encoding.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* GDM - The GNOME Display Manager
2
 
 * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
3
 
 * Copyright (C) 2005 Brian Cameron <brian.cameron@sun.com>
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU 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  02111-1307  USA
18
 
 */
19
 
 
20
 
/* 
21
 
 * gdmconfig.c isolates most logic that interacts with vicious-extensions
22
 
 * into a single file and provides a mechanism for interacting with GDM
23
 
 * configuration optins via access functions for getting/setting values.
24
 
 * This logic also ensures that the same configuration validation happens
25
 
 * when loading the values initially or setting them via the
26
 
 * GDM_UPDATE_CONFIG socket command.
27
 
 * 
28
 
 * When adding a new configuration option, simply add the new option to 
29
 
 * gdm.h and to the val_hash and type_hash hashes in the gdm_config_init
30
 
 * function.  Any validation for the configuration option should be
31
 
 * placed in the _gdm_set_value_string, _gdm_set_value_int, or
32
 
 * _gdm_set_value_bool functions.
33
 
 */
34
 
#include "config.h"
35
 
 
36
 
#include <stdlib.h>
37
 
#include <unistd.h>
38
 
#include <ctype.h>
39
 
#include <fcntl.h>
40
 
#include <sys/types.h>
41
 
#include <sys/resource.h>
42
 
#include <sys/stat.h>
43
 
#include <sys/resource.h>
44
 
#include <signal.h>
45
 
#include <pwd.h>
46
 
#include <grp.h>
47
 
 
48
 
#include <glib.h>
49
 
#include <glib/gi18n.h>
50
 
 
51
 
#include "vicious.h"
52
 
 
53
 
#include "gdm.h"
54
 
#include "gdmconfig.h"
55
 
#include "verify.h"
56
 
#include "gdm-net.h"
57
 
#include "misc.h"
58
 
#include "server.h"
59
 
#include "filecheck.h"
60
 
#include "slave.h"
61
 
 
62
 
gchar *config_file                     = NULL;
63
 
gchar *custom_config_file              = NULL;
64
 
static time_t config_file_mtime        = 0;
65
 
static time_t custom_config_file_mtime = 0;
66
 
 
67
 
extern gboolean no_console;
68
 
extern gboolean gdm_emergency_server;
69
 
 
70
 
GSList *displays          = NULL;
71
 
GSList *displays_inactive = NULL;
72
 
GSList *xservers          = NULL;
73
 
 
74
 
gint high_display_num = 0;
75
 
 
76
 
typedef enum {
77
 
        CONFIG_BOOL,
78
 
        CONFIG_INT,
79
 
        CONFIG_STRING
80
 
} GdmConfigType;
81
 
 
82
 
static GHashTable    *type_hash       = NULL;
83
 
static GHashTable    *val_hash        = NULL;
84
 
static GHashTable    *translated_hash = NULL;
85
 
static GHashTable    *realkey_hash    = NULL;
86
 
static GdmConfigType  bool_type       = CONFIG_BOOL;
87
 
static GdmConfigType  int_type        = CONFIG_INT;
88
 
static GdmConfigType  string_type     = CONFIG_STRING;
89
 
 
90
 
static uid_t GdmUserId;   /* Userid  under which gdm should run */
91
 
static gid_t GdmGroupId;  /* Gruopid under which gdm should run */
92
 
 
93
 
/* Config options used by daemon */
94
 
/* ----------------------------- */
95
 
static gchar *GdmUser = NULL;
96
 
static gchar *GdmGroup = NULL;
97
 
static gchar *GdmGtkRC = NULL;
98
 
static gchar *GdmGtkTheme = NULL;
99
 
static gchar *GdmSessDir = NULL;
100
 
static gchar *GdmBaseXsession = NULL;
101
 
static gchar *GdmDefaultSession = NULL;
102
 
static gchar *GdmAutomaticLogin = NULL;
103
 
static gchar *GdmConfigurator = NULL;
104
 
static gchar *GdmGlobalFaceDir = NULL;
105
 
static gchar *GdmGreeter = NULL;
106
 
static gchar *GdmRemoteGreeter = NULL;
107
 
static gchar *GdmGtkModulesList = NULL;
108
 
static gchar *GdmChooser = NULL;
109
 
static gchar *GdmLogDir = NULL;
110
 
static gchar *GdmDisplayInitDir = NULL;
111
 
static gchar *GdmPostLogin = NULL;
112
 
static gchar *GdmPreSession = NULL;
113
 
static gchar *GdmPostSession = NULL;
114
 
static gchar *GdmFailsafeXserver = NULL;
115
 
static gchar *GdmXKeepsCrashing = NULL;
116
 
static gchar *GdmHalt = NULL;
117
 
static gchar *GdmReboot = NULL;
118
 
static gchar *GdmSuspend = NULL;
119
 
static gchar *GdmServAuthDir = NULL;
120
 
static gchar *GdmMulticastAddr;
121
 
static gchar *GdmUserAuthDir = NULL;
122
 
static gchar *GdmUserAuthFile = NULL;
123
 
static gchar *GdmUserAuthFallback = NULL;
124
 
static gchar *GdmPidFile = NULL;
125
 
static gchar *GdmPath = NULL;
126
 
static gchar *GdmRootPath = NULL;
127
 
static gchar *GdmWilling = NULL;
128
 
static gchar *GdmXdmcpProxyXserver = NULL;
129
 
static gchar *GdmXdmcpProxyReconnect = NULL;
130
 
static gchar *GdmTimedLogin = NULL;
131
 
static gchar *GdmStandardXserver = NULL;
132
 
static gchar *GdmXnest = NULL;
133
 
static gchar *GdmSoundProgram = NULL;
134
 
static gchar *GdmSoundOnLoginFile = NULL;
135
 
static gchar *GdmSoundOnLoginSuccessFile = NULL;
136
 
static gchar *GdmSoundOnLoginFailureFile = NULL;
137
 
static gchar *GdmConsoleCannotHandle = NULL;
138
 
static gchar *GdmPamStack = NULL;
139
 
 
140
 
static gint GdmXineramaScreen = 0;
141
 
static gint GdmUserMaxFile = 0;
142
 
static gint GdmDisplaysPerHost = 0;
143
 
static gint GdmMaxPending = 0;
144
 
static gint GdmMaxSessions = 0;
145
 
static gint GdmUdpPort = 0;
146
 
static gint GdmMaxIndirect = 0;
147
 
static gint GdmMaxWaitIndirect = 0;
148
 
static gint GdmPingInterval = 0;
149
 
static gint GdmRelaxPerm = 0;
150
 
static gint GdmRetryDelay = 0;
151
 
static gint GdmTimedLoginDelay = 0;
152
 
static gint GdmFlexibleXservers = 5;
153
 
static gint GdmFirstVt = 7;
154
 
static gint GdmXserverTimeout = 10;
155
 
 
156
 
/* The SDTLOGIN feature is Solaris specific, and causes the Xserver to be
157
 
 * run with user permissionsinstead of as root, which adds security but
158
 
 * disables the AlwaysRestartServer option as highlighted in the gdm
159
 
 * documentation */
160
 
#ifdef sun
161
 
gboolean GdmAlwaysRestartServer = TRUE;
162
 
#else
163
 
gboolean GdmAlwaysRestartServer = FALSE;
164
 
#endif
165
 
static gboolean GdmAutomaticLoginEnable = FALSE;
166
 
static gboolean GdmConfigAvailable = FALSE;
167
 
static gboolean GdmSystemMenu = FALSE;
168
 
static gboolean GdmChooserButton = FALSE;
169
 
static gboolean GdmBrowser = FALSE;
170
 
static gboolean GdmAddGtkModules = FALSE;
171
 
static gboolean GdmDoubleLoginWarning = TRUE;
172
 
static gboolean GdmAlwaysLoginCurrentSession = FALSE;
173
 
static gboolean GdmDisplayLastLogin = TRUE;
174
 
static gboolean GdmMulticast;
175
 
static gboolean GdmNeverPlaceCookiesOnNfs = TRUE;
176
 
static gboolean GdmPasswordRequired = FALSE;
177
 
static gboolean GdmKillInitClients = FALSE;
178
 
static gboolean GdmXdmcp = FALSE;
179
 
static gboolean GdmIndirect = FALSE;
180
 
static gboolean GdmXdmcpProxy = FALSE;
181
 
static gboolean GdmDebug = FALSE;
182
 
static gboolean GdmDebugGestures = FALSE;
183
 
static gboolean GdmAllowRoot = FALSE;
184
 
static gboolean GdmAllowRemoteRoot = FALSE;
185
 
static gboolean GdmAllowRemoteAutoLogin = FALSE;
186
 
static gboolean GdmCheckDirOwner = TRUE;
187
 
static gboolean GdmTimedLoginEnable = FALSE;
188
 
static gboolean GdmDynamicXservers = FALSE;
189
 
static gboolean GdmVTAllocation = TRUE;
190
 
static gboolean GdmDisallowTcp = TRUE;
191
 
static gboolean GdmSoundOnLogin = TRUE;
192
 
static gboolean GdmSoundOnLoginSuccess = FALSE;
193
 
static gboolean GdmSoundOnLoginFailure = FALSE;
194
 
static gboolean GdmConsoleNotify = TRUE;
195
 
 
196
 
/* Config options used by slave */
197
 
/* ---------------------------- */
198
 
static gchar *GdmGtkThemesToAllow = NULL;
199
 
static gchar *GdmInclude = NULL;
200
 
static gchar *GdmExclude = NULL;
201
 
static gchar *GdmDefaultFace = NULL;
202
 
static gchar *GdmLocaleFile = NULL;
203
 
static gchar *GdmLogo = NULL;
204
 
static gchar *GdmChooserButtonLogo = NULL;
205
 
static gchar *GdmWelcome = NULL;
206
 
static gchar *GdmRemoteWelcome = NULL;
207
 
static gchar *GdmBackgroundProgram = NULL;
208
 
static gchar *GdmBackgroundImage = NULL;
209
 
static gchar *GdmBackgroundColor = NULL;
210
 
static gchar *GdmGraphicalTheme = NULL;
211
 
static gchar *GdmInfoMsgFile = NULL;
212
 
static gchar *GdmInfoMsgFont = NULL;
213
 
static gchar *GdmHost = NULL;
214
 
static gchar *GdmHostImageDir = NULL;
215
 
static gchar *GdmHosts = NULL;
216
 
static gchar *GdmGraphicalThemeColor = NULL;
217
 
static gchar *GdmGraphicalThemeDir = NULL;
218
 
static gchar *GdmGraphicalThemes = NULL;
219
 
static gchar *GdmPreFetchProgram = NULL;
220
 
static gchar *GdmUse24Clock = NULL;
221
 
 
222
 
static gint GdmPositionX;
223
 
static gint GdmPositionY;
224
 
static gint GdmMinimalUid;
225
 
static gint GdmMaxIconWidth;
226
 
static gint GdmMaxIconHeight;
227
 
static gint GdmBackgroundType;
228
 
static gint GdmScanTime;
229
 
static gint GdmMaxWait;
230
 
static gint GdmFlexiReapDelayMinutes;
231
 
static gint GdmBackgroundProgramInitialDelay = 30;
232
 
static gint GdmBackgroundProgramRestartDelay = 30;
233
 
 
234
 
static gboolean GdmAllowGtkThemeChange;
235
 
static gboolean GdmTitleBar;
236
 
static gboolean GdmIncludeAll;
237
 
static gboolean GdmDefaultWelcome;
238
 
static gboolean GdmDefaultRemoteWelcome;
239
 
static gboolean GdmLockPosition;
240
 
static gboolean GdmBackgroundScaleToFit;
241
 
static gboolean GdmBackgroundRemoteOnlyColor;
242
 
static gboolean GdmRunBackgroundProgramAlways;
243
 
static gboolean GdmSetPosition;
244
 
static gboolean GdmQuiver;
245
 
static gboolean GdmShowGnomeFailsafe;
246
 
static gboolean GdmShowXtermFailsafe;
247
 
static gboolean GdmShowLastSession;
248
 
static gboolean GdmEntryCircles;
249
 
static gboolean GdmEntryInvisible;
250
 
static gboolean GdmGraphicalThemeRand;
251
 
static gboolean GdmBroadcast;
252
 
static gboolean GdmAllowAdd;
253
 
static gboolean GdmRestartBackgroundProgram;
254
 
 
255
 
/**
256
 
 * gdm_config_add_hash
257
 
 *
258
 
 * Add config value to the val_hash and type_hash.  Strip the key so
259
 
 * it doesn't contain a default value.  This function assumes the
260
 
 * val_hash, type_hash, and realkey_hash have been initialized.
261
 
 */
262
 
static void
263
 
gdm_config_add_hash (gchar *key, gpointer value, GdmConfigType *type)
264
 
{
265
 
   gchar *p;
266
 
   gchar *newkey = g_strdup (key);
267
 
 
268
 
   g_strstrip (newkey);
269
 
   p = strchr (newkey, '=');
270
 
   if (p != NULL)
271
 
      *p = '\0';
272
 
 
273
 
   g_hash_table_insert (val_hash, newkey, value);
274
 
   g_hash_table_insert (type_hash, newkey, type);
275
 
   g_hash_table_insert (realkey_hash, newkey, key);
276
 
}
277
 
 
278
 
/**
279
 
 * gdm_config_hash_lookup
280
 
 *
281
 
 * Accesses hash with key, stripping it so it doesn't contain a default
282
 
 * value.
283
 
 */
284
 
static gpointer
285
 
gdm_config_hash_lookup (GHashTable *hash, gchar *key)
286
 
{
287
 
   gchar *p;
288
 
   gpointer *ret;
289
 
   gchar *newkey = g_strdup (key);
290
 
 
291
 
   g_strstrip (newkey);
292
 
   p = strchr (newkey, '=');
293
 
   if (p != NULL)
294
 
      *p = '\0';
295
 
 
296
 
   ret = g_hash_table_lookup (hash, newkey);
297
 
   g_free (newkey);
298
 
   return (ret);
299
 
}
300
 
 
301
 
/**
302
 
 * is_key
303
 
 *
304
 
 * Since GDM keys sometimes have default values defined in the gdm.h header
305
 
 * file (e.g. key=value), this function strips off the "=value" from both 
306
 
 * keys passed and compares them, returning TRUE if they are the same, 
307
 
 * FALSE otherwise.
308
 
 */
309
 
static gboolean
310
 
is_key (const gchar *key1, const gchar *key2)
311
 
{
312
 
   gchar *key1d, *key2d, *p;
313
 
 
314
 
   key1d = g_strdup (key1);
315
 
   key2d = g_strdup (key2);
316
 
 
317
 
   g_strstrip (key1d);
318
 
   p = strchr (key1d, '=');
319
 
   if (p != NULL)
320
 
      *p = '\0';
321
 
 
322
 
   g_strstrip (key2d);
323
 
   p = strchr (key2d, '=');
324
 
   if (p != NULL)
325
 
      *p = '\0';
326
 
 
327
 
   if (strcmp (ve_sure_string (key1d), ve_sure_string (key2d)) == 0) {
328
 
      g_free (key1d);
329
 
      g_free (key2d);
330
 
      return TRUE;
331
 
   } else {
332
 
      g_free (key1d);
333
 
      g_free (key2d);
334
 
      return FALSE;
335
 
   }
336
 
}
337
 
 
338
 
/**
339
 
 * gdm_config_init
340
 
 * 
341
 
 * Sets up initial hashes used by configuration routines.
342
 
 */ 
343
 
static void 
344
 
gdm_config_init (void)
345
 
{
346
 
   type_hash    = g_hash_table_new (g_str_hash, g_str_equal);
347
 
   val_hash     = g_hash_table_new (g_str_hash, g_str_equal);
348
 
   realkey_hash = g_hash_table_new (g_str_hash, g_str_equal);
349
 
 
350
 
   /* boolean values */
351
 
   gdm_config_add_hash (GDM_KEY_ALLOW_REMOTE_ROOT, &GdmAllowRemoteRoot, &bool_type);
352
 
   gdm_config_add_hash (GDM_KEY_ALLOW_ROOT, &GdmAllowRoot, &bool_type);
353
 
   gdm_config_add_hash (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN,
354
 
      &GdmAllowRemoteAutoLogin, &bool_type);
355
 
   gdm_config_add_hash (GDM_KEY_PASSWORD_REQUIRED, &GdmPasswordRequired, &bool_type);
356
 
   gdm_config_add_hash (GDM_KEY_AUTOMATIC_LOGIN_ENABLE,
357
 
      &GdmAutomaticLoginEnable, &bool_type);
358
 
   gdm_config_add_hash (GDM_KEY_ALWAYS_RESTART_SERVER,
359
 
      &GdmAlwaysRestartServer, &bool_type);
360
 
   gdm_config_add_hash (GDM_KEY_ADD_GTK_MODULES, &GdmAddGtkModules, &bool_type);
361
 
   gdm_config_add_hash (GDM_KEY_DOUBLE_LOGIN_WARNING,
362
 
      &GdmDoubleLoginWarning, &bool_type);
363
 
   gdm_config_add_hash (GDM_KEY_ALWAYS_LOGIN_CURRENT_SESSION,
364
 
      &GdmAlwaysLoginCurrentSession, &bool_type);
365
 
   gdm_config_add_hash (GDM_KEY_DISPLAY_LAST_LOGIN, &GdmDisplayLastLogin, &bool_type);
366
 
   gdm_config_add_hash (GDM_KEY_KILL_INIT_CLIENTS, &GdmKillInitClients, &bool_type);
367
 
   gdm_config_add_hash (GDM_KEY_CONFIG_AVAILABLE, &GdmConfigAvailable, &bool_type);
368
 
   gdm_config_add_hash (GDM_KEY_SYSTEM_MENU, &GdmSystemMenu, &bool_type);
369
 
   gdm_config_add_hash (GDM_KEY_CHOOSER_BUTTON, &GdmChooserButton, &bool_type);
370
 
   gdm_config_add_hash (GDM_KEY_BROWSER, &GdmBrowser, &bool_type);
371
 
   gdm_config_add_hash (GDM_KEY_MULTICAST, &GdmMulticast, &bool_type);
372
 
   gdm_config_add_hash (GDM_KEY_NEVER_PLACE_COOKIES_ON_NFS,
373
 
      &GdmNeverPlaceCookiesOnNfs, &bool_type);
374
 
   gdm_config_add_hash (GDM_KEY_CONSOLE_NOTIFY, &GdmConsoleNotify, &bool_type);
375
 
   gdm_config_add_hash (GDM_KEY_TIMED_LOGIN_ENABLE, &GdmTimedLoginEnable, &bool_type);
376
 
   gdm_config_add_hash (GDM_KEY_CHECK_DIR_OWNER, &GdmCheckDirOwner, &bool_type);
377
 
   gdm_config_add_hash (GDM_KEY_XDMCP, &GdmXdmcp, &bool_type);
378
 
   gdm_config_add_hash (GDM_KEY_INDIRECT, &GdmIndirect, &bool_type);
379
 
   gdm_config_add_hash (GDM_KEY_XDMCP_PROXY, &GdmXdmcpProxy, &bool_type);
380
 
   gdm_config_add_hash (GDM_KEY_DYNAMIC_XSERVERS, &GdmDynamicXservers, &bool_type);
381
 
   gdm_config_add_hash (GDM_KEY_VT_ALLOCATION, &GdmVTAllocation, &bool_type);
382
 
   gdm_config_add_hash (GDM_KEY_DISALLOW_TCP, &GdmDisallowTcp, &bool_type);
383
 
   gdm_config_add_hash (GDM_KEY_SOUND_ON_LOGIN_SUCCESS,
384
 
      &GdmSoundOnLoginSuccess, &bool_type);
385
 
   gdm_config_add_hash (GDM_KEY_SOUND_ON_LOGIN_FAILURE,
386
 
      &GdmSoundOnLoginFailure, &bool_type);
387
 
   gdm_config_add_hash (GDM_KEY_DEBUG, &GdmDebug, &bool_type);
388
 
   gdm_config_add_hash (GDM_KEY_DEBUG_GESTURES, &GdmDebugGestures, &bool_type);
389
 
   gdm_config_add_hash (GDM_KEY_ALLOW_GTK_THEME_CHANGE,
390
 
      &GdmAllowGtkThemeChange, &bool_type);
391
 
   gdm_config_add_hash (GDM_KEY_TITLE_BAR, &GdmTitleBar, &bool_type);
392
 
   gdm_config_add_hash (GDM_KEY_INCLUDE_ALL, &GdmIncludeAll, &bool_type);
393
 
   gdm_config_add_hash (GDM_KEY_DEFAULT_WELCOME, &GdmDefaultWelcome, &bool_type);
394
 
   gdm_config_add_hash (GDM_KEY_DEFAULT_REMOTE_WELCOME,
395
 
      &GdmDefaultRemoteWelcome, &bool_type);
396
 
   gdm_config_add_hash (GDM_KEY_LOCK_POSITION, &GdmLockPosition, &bool_type);
397
 
   gdm_config_add_hash (GDM_KEY_BACKGROUND_SCALE_TO_FIT,
398
 
      &GdmBackgroundScaleToFit, &bool_type);
399
 
   gdm_config_add_hash (GDM_KEY_BACKGROUND_REMOTE_ONLY_COLOR,
400
 
      &GdmBackgroundRemoteOnlyColor, &bool_type);
401
 
   gdm_config_add_hash (GDM_KEY_RUN_BACKGROUND_PROGRAM_ALWAYS,
402
 
      &GdmRunBackgroundProgramAlways, &bool_type);
403
 
   gdm_config_add_hash (GDM_KEY_SET_POSITION, &GdmSetPosition, &bool_type);
404
 
   gdm_config_add_hash (GDM_KEY_QUIVER, &GdmQuiver, &bool_type);
405
 
   gdm_config_add_hash (GDM_KEY_SHOW_GNOME_FAILSAFE,
406
 
      &GdmShowGnomeFailsafe, &bool_type);
407
 
   gdm_config_add_hash (GDM_KEY_SHOW_XTERM_FAILSAFE,
408
 
      &GdmShowXtermFailsafe, &bool_type);
409
 
   gdm_config_add_hash (GDM_KEY_SHOW_LAST_SESSION,
410
 
      &GdmShowLastSession, &bool_type);
411
 
   gdm_config_add_hash (GDM_KEY_USE_24_CLOCK, &GdmUse24Clock, &string_type);
412
 
   gdm_config_add_hash (GDM_KEY_ENTRY_CIRCLES, &GdmEntryCircles, &bool_type);
413
 
   gdm_config_add_hash (GDM_KEY_ENTRY_INVISIBLE, &GdmEntryInvisible, &bool_type);
414
 
   gdm_config_add_hash (GDM_KEY_GRAPHICAL_THEME_RAND,
415
 
      &GdmGraphicalThemeRand, &bool_type);
416
 
   gdm_config_add_hash (GDM_KEY_BROADCAST, &GdmBroadcast, &bool_type);
417
 
   gdm_config_add_hash (GDM_KEY_ALLOW_ADD, &GdmAllowAdd, &bool_type);
418
 
   gdm_config_add_hash (GDM_KEY_SOUND_ON_LOGIN, &GdmSoundOnLogin, &bool_type);
419
 
   gdm_config_add_hash (GDM_KEY_RESTART_BACKGROUND_PROGRAM,
420
 
      &GdmRestartBackgroundProgram, &bool_type);
421
 
 
422
 
   /* string values */
423
 
   gdm_config_add_hash (GDM_KEY_PATH, &GdmPath, &string_type);
424
 
   gdm_config_add_hash (GDM_KEY_ROOT_PATH, &GdmRootPath, &string_type);
425
 
   gdm_config_add_hash (GDM_KEY_CONSOLE_CANNOT_HANDLE,
426
 
      &GdmConsoleCannotHandle, &string_type);
427
 
   gdm_config_add_hash (GDM_KEY_CHOOSER, &GdmChooser, &string_type);
428
 
   gdm_config_add_hash (GDM_KEY_GREETER, &GdmGreeter, &string_type);
429
 
   gdm_config_add_hash (GDM_KEY_CONFIGURATOR, &GdmConfigurator, &string_type);
430
 
   gdm_config_add_hash (GDM_KEY_POSTLOGIN, &GdmPostLogin, &string_type);
431
 
   gdm_config_add_hash (GDM_KEY_PRESESSION, &GdmPreSession, &string_type);
432
 
   gdm_config_add_hash (GDM_KEY_POSTSESSION, &GdmPostSession, &string_type);
433
 
   gdm_config_add_hash (GDM_KEY_FAILSAFE_XSERVER, &GdmFailsafeXserver, &string_type);
434
 
   gdm_config_add_hash (GDM_KEY_X_KEEPS_CRASHING, &GdmXKeepsCrashing, &string_type);
435
 
   gdm_config_add_hash (GDM_KEY_BASE_XSESSION, &GdmBaseXsession, &string_type);
436
 
   gdm_config_add_hash (GDM_KEY_REMOTE_GREETER, &GdmRemoteGreeter, &string_type);
437
 
   gdm_config_add_hash (GDM_KEY_DISPLAY_INIT_DIR, &GdmDisplayInitDir, &string_type);
438
 
   gdm_config_add_hash (GDM_KEY_AUTOMATIC_LOGIN, &GdmAutomaticLogin, &string_type);
439
 
   gdm_config_add_hash (GDM_KEY_GTK_MODULES_LIST, &GdmGtkModulesList, &string_type);
440
 
   gdm_config_add_hash (GDM_KEY_REBOOT, &GdmReboot, &string_type);
441
 
   gdm_config_add_hash (GDM_KEY_HALT, &GdmHalt, &string_type);
442
 
   gdm_config_add_hash (GDM_KEY_SUSPEND, &GdmSuspend, &string_type);
443
 
   gdm_config_add_hash (GDM_KEY_LOG_DIR, &GdmLogDir, &string_type);
444
 
   gdm_config_add_hash (GDM_KEY_PID_FILE, &GdmPidFile, &string_type);
445
 
   gdm_config_add_hash (GDM_KEY_GLOBAL_FACE_DIR, &GdmGlobalFaceDir, &string_type);
446
 
   gdm_config_add_hash (GDM_KEY_SERV_AUTHDIR, &GdmServAuthDir, &string_type);
447
 
   gdm_config_add_hash (GDM_KEY_USER_AUTHDIR, &GdmUserAuthDir, &string_type);
448
 
   gdm_config_add_hash (GDM_KEY_USER_AUTHFILE, &GdmUserAuthFile, &string_type);
449
 
   gdm_config_add_hash (GDM_KEY_USER_AUTHDIR_FALLBACK,
450
 
      &GdmUserAuthFallback, &string_type);
451
 
   gdm_config_add_hash (GDM_KEY_SESSION_DESKTOP_DIR, &GdmSessDir, &string_type);
452
 
   gdm_config_add_hash (GDM_KEY_DEFAULT_SESSION, &GdmDefaultSession, &string_type);
453
 
   gdm_config_add_hash (GDM_KEY_MULTICAST_ADDR, &GdmMulticastAddr, &string_type);
454
 
   gdm_config_add_hash (GDM_KEY_USER, &GdmUser, &string_type);
455
 
   gdm_config_add_hash (GDM_KEY_GROUP, &GdmGroup, &string_type);
456
 
   gdm_config_add_hash (GDM_KEY_GTKRC, &GdmGtkRC, &string_type);
457
 
   gdm_config_add_hash (GDM_KEY_GTK_THEME, &GdmGtkTheme, &string_type);
458
 
   gdm_config_add_hash (GDM_KEY_TIMED_LOGIN, &GdmTimedLogin, &string_type);
459
 
   gdm_config_add_hash (GDM_KEY_WILLING, &GdmWilling, &string_type);
460
 
   gdm_config_add_hash (GDM_KEY_XDMCP_PROXY_XSERVER,
461
 
      &GdmXdmcpProxyXserver, &string_type);
462
 
   gdm_config_add_hash (GDM_KEY_XDMCP_PROXY_RECONNECT,
463
 
      &GdmXdmcpProxyReconnect, &string_type);
464
 
   gdm_config_add_hash (GDM_KEY_STANDARD_XSERVER, &GdmStandardXserver, &string_type);
465
 
   gdm_config_add_hash (GDM_KEY_XNEST, &GdmXnest, &string_type);
466
 
   gdm_config_add_hash (GDM_KEY_SOUND_PROGRAM, &GdmSoundProgram, &string_type);
467
 
   gdm_config_add_hash (GDM_KEY_SOUND_ON_LOGIN_FILE,
468
 
      &GdmSoundOnLoginFile, &string_type);
469
 
   gdm_config_add_hash (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE,
470
 
      &GdmSoundOnLoginSuccessFile, &string_type);
471
 
   gdm_config_add_hash (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE,
472
 
      &GdmSoundOnLoginFailureFile, &string_type);
473
 
   gdm_config_add_hash (GDM_KEY_GTK_THEMES_TO_ALLOW,
474
 
      &GdmGtkThemesToAllow, &string_type);
475
 
   gdm_config_add_hash (GDM_KEY_INCLUDE, &GdmInclude, &string_type);
476
 
   gdm_config_add_hash (GDM_KEY_EXCLUDE, &GdmExclude, &string_type);
477
 
   gdm_config_add_hash (GDM_KEY_DEFAULT_FACE, &GdmDefaultFace, &string_type);
478
 
   gdm_config_add_hash (GDM_KEY_LOCALE_FILE, &GdmLocaleFile, &string_type);
479
 
   gdm_config_add_hash (GDM_KEY_LOGO, &GdmLogo, &string_type);
480
 
   gdm_config_add_hash (GDM_KEY_CHOOSER_BUTTON_LOGO,
481
 
      &GdmChooserButtonLogo, &string_type);
482
 
   gdm_config_add_hash (GDM_KEY_WELCOME, &GdmWelcome, &string_type);
483
 
   gdm_config_add_hash (GDM_KEY_REMOTE_WELCOME, &GdmRemoteWelcome, &string_type);
484
 
   gdm_config_add_hash (GDM_KEY_BACKGROUND_PROGRAM,
485
 
      &GdmBackgroundProgram, &string_type);
486
 
   gdm_config_add_hash (GDM_KEY_BACKGROUND_IMAGE,
487
 
      &GdmBackgroundImage, &string_type);
488
 
   gdm_config_add_hash (GDM_KEY_BACKGROUND_COLOR,
489
 
      &GdmBackgroundColor, &string_type);
490
 
   gdm_config_add_hash (GDM_KEY_GRAPHICAL_THEME,
491
 
      &GdmGraphicalTheme, &string_type);
492
 
   gdm_config_add_hash (GDM_KEY_GRAPHICAL_THEME_DIR,
493
 
      &GdmGraphicalThemeDir, &string_type);
494
 
   gdm_config_add_hash (GDM_KEY_GRAPHICAL_THEMES,
495
 
      &GdmGraphicalThemes, &string_type);
496
 
   gdm_config_add_hash (GDM_KEY_GRAPHICAL_THEMED_COLOR,
497
 
      &GdmGraphicalThemeColor, &string_type);
498
 
   gdm_config_add_hash (GDM_KEY_INFO_MSG_FILE, &GdmInfoMsgFile, &string_type);
499
 
   gdm_config_add_hash (GDM_KEY_INFO_MSG_FONT, &GdmInfoMsgFont, &string_type);
500
 
   gdm_config_add_hash (GDM_KEY_DEFAULT_HOST_IMG, &GdmHost, &string_type);
501
 
   gdm_config_add_hash (GDM_KEY_HOST_IMAGE_DIR, &GdmHostImageDir, &string_type);
502
 
   gdm_config_add_hash (GDM_KEY_HOSTS, &GdmHosts, &string_type);
503
 
   gdm_config_add_hash (GDM_KEY_PRE_FETCH_PROGRAM,
504
 
      &GdmPreFetchProgram, &string_type);
505
 
   gdm_config_add_hash (GDM_KEY_PAM_STACK, &GdmPamStack, &string_type);
506
 
 
507
 
   /* int values */
508
 
   gdm_config_add_hash (GDM_KEY_XINERAMA_SCREEN, &GdmXineramaScreen, &int_type);
509
 
   gdm_config_add_hash (GDM_KEY_RETRY_DELAY, &GdmRetryDelay, &int_type);
510
 
   gdm_config_add_hash (GDM_KEY_TIMED_LOGIN_DELAY, &GdmTimedLoginDelay, &int_type);
511
 
   gdm_config_add_hash (GDM_KEY_RELAX_PERM, &GdmRelaxPerm, &int_type);
512
 
   gdm_config_add_hash (GDM_KEY_USER_MAX_FILE, &GdmUserMaxFile, &int_type);
513
 
   gdm_config_add_hash (GDM_KEY_DISPLAYS_PER_HOST, &GdmDisplaysPerHost, &int_type);
514
 
   gdm_config_add_hash (GDM_KEY_MAX_PENDING, &GdmMaxPending, &int_type);
515
 
   gdm_config_add_hash (GDM_KEY_MAX_WAIT, &GdmMaxWait, &int_type);
516
 
   gdm_config_add_hash (GDM_KEY_MAX_SESSIONS, &GdmMaxSessions, &int_type);
517
 
   gdm_config_add_hash (GDM_KEY_UDP_PORT, &GdmUdpPort, &int_type);
518
 
   gdm_config_add_hash (GDM_KEY_MAX_INDIRECT, &GdmMaxIndirect, &int_type);
519
 
   gdm_config_add_hash (GDM_KEY_MAX_WAIT_INDIRECT, &GdmMaxWaitIndirect, &int_type);
520
 
   gdm_config_add_hash (GDM_KEY_PING_INTERVAL, &GdmPingInterval, &int_type);
521
 
   gdm_config_add_hash (GDM_KEY_FLEXIBLE_XSERVERS, &GdmFlexibleXservers, &int_type);
522
 
   gdm_config_add_hash (GDM_KEY_FIRST_VT, &GdmFirstVt, &int_type);
523
 
   gdm_config_add_hash (GDM_KEY_POSITION_X, &GdmPositionX, &int_type);
524
 
   gdm_config_add_hash (GDM_KEY_POSITION_Y, &GdmPositionY, &int_type);
525
 
   gdm_config_add_hash (GDM_KEY_MINIMAL_UID, &GdmMinimalUid, &int_type);
526
 
   gdm_config_add_hash (GDM_KEY_MAX_ICON_WIDTH, &GdmMaxIconWidth, &int_type);
527
 
   gdm_config_add_hash (GDM_KEY_MAX_ICON_HEIGHT, &GdmMaxIconHeight, &int_type);
528
 
   gdm_config_add_hash (GDM_KEY_BACKGROUND_TYPE, &GdmBackgroundType, &int_type);
529
 
   gdm_config_add_hash (GDM_KEY_SCAN_TIME, &GdmScanTime, &int_type);
530
 
   gdm_config_add_hash (GDM_KEY_FLEXI_REAP_DELAY_MINUTES,
531
 
      &GdmFlexiReapDelayMinutes, &int_type);
532
 
   gdm_config_add_hash (GDM_KEY_BACKGROUND_PROGRAM_INITIAL_DELAY,
533
 
      &GdmBackgroundProgramInitialDelay, &int_type);
534
 
   gdm_config_add_hash (GDM_KEY_BACKGROUND_PROGRAM_RESTART_DELAY,
535
 
      &GdmBackgroundProgramRestartDelay, &int_type);
536
 
   gdm_config_add_hash (GDM_KEY_XSERVER_TIMEOUT, &GdmXserverTimeout, &int_type);
537
 
}
538
 
 
539
 
/**
540
 
 * gdm_get_config:
541
 
 *
542
 
 * Get config file.  
543
 
 */
544
 
static VeConfig *
545
 
gdm_get_default_config (struct stat *statbuf)
546
 
{
547
 
   int r;
548
 
 
549
 
   /* Not NULL if config_file was set by command-line option. */
550
 
   if (config_file != NULL) {
551
 
      VE_IGNORE_EINTR (r = g_stat (config_file, statbuf));
552
 
      if (r < 0) {
553
 
         gdm_error (_("%s: No GDM configuration file: %s. Using defaults."),
554
 
                      "gdm_config_parse", config_file);
555
 
         return NULL;
556
 
      }
557
 
   } else {
558
 
      VE_IGNORE_EINTR (r = g_stat (GDM_DEFAULTS_CONF, statbuf));
559
 
      if (r < 0) {
560
 
         gdm_error (_("%s: No GDM configuration file: %s. Using defaults."),
561
 
                      "gdm_config_parse", GDM_DEFAULTS_CONF);
562
 
         return NULL;
563
 
      } else {
564
 
              config_file = GDM_DEFAULTS_CONF;
565
 
      }
566
 
   }
567
 
 
568
 
   return ve_config_new (config_file);
569
 
}
570
 
 
571
 
/**
572
 
 * gdm_get_custom_config:
573
 
 *
574
 
 * Get the custom config file where gdmsetup saves its changes and
575
 
 * where users are encouraged to make modifications.
576
 
 */
577
 
static VeConfig *
578
 
gdm_get_custom_config (struct stat *statbuf)
579
 
{
580
 
   int r;
581
 
 
582
 
   /*
583
 
    * First check to see if the old configuration file name is on
584
 
    * the system.  If so, use that as the custom configuration
585
 
    * file.  "make install" will move this file aside, and 
586
 
    * distros probably can also manage moving this file on
587
 
    * upgrade.   
588
 
    *
589
 
    * In case this file is on the system, then use it as
590
 
    * the custom configuration file until the user moves it
591
 
    * aside.  This will likely mean all the defaults in
592
 
    * defaults.conf will not get used since the old gdm.conf
593
 
    * file has all the keys in it (except new ones).  But
594
 
    * that would be what the user wants.
595
 
    */
596
 
 
597
 
    /*
598
 
     * We disable this on Debian, as we already have the non-custom conf
599
 
     * located in /usr/share.  So, we make the old conf the custom config
600
 
     * in /etc, with the same name as before.  Users that upgrade to the new
601
 
     * maintainer conf get just that (and a blank custom.conf to make changes
602
 
     * in), and users that don't upgrade to the new conf, get both configs
603
 
     * with the one they kept getting precedence.
604
 
     */
605
 
#if 0
606
 
   VE_IGNORE_EINTR (r = g_stat (GDM_OLD_CONF, statbuf));
607
 
   if (r >= 0) {
608
 
      custom_config_file = g_strdup (GDM_OLD_CONF);
609
 
      return ve_config_new (custom_config_file);
610
 
   }
611
 
#endif
612
 
 
613
 
   VE_IGNORE_EINTR (r = g_stat (GDM_CUSTOM_CONF, statbuf));
614
 
   if (r >= 0) {
615
 
      custom_config_file = g_strdup (GDM_CUSTOM_CONF);
616
 
      return ve_config_new (custom_config_file);
617
 
   } else {
618
 
      return NULL;
619
 
   }
620
 
}
621
 
 
622
 
/**
623
 
 * gdm_get_per_display_custom_config_file
624
 
 *
625
 
 * Returns the per-display config file for a given display
626
 
 * This is always the custom config file name with the display
627
 
 * appended, and never gdm.conf.
628
 
 */
629
 
static gchar *
630
 
gdm_get_per_display_custom_config_file (gchar *display)
631
 
{
632
 
  return g_strdup_printf ("%s%s", custom_config_file, display);
633
 
}
634
 
 
635
 
/**
636
 
 * gdm_get_custom_config_file
637
 
 *
638
 
 * Returns the custom config file being used.
639
 
 */
640
 
gchar *
641
 
gdm_get_custom_config_file (void)
642
 
{
643
 
   return custom_config_file;
644
 
}
645
 
 
646
 
/**
647
 
 * gdm_get_value_int
648
 
 *
649
 
 * Gets an integer configuration option by key.  The option must
650
 
 * first be loaded, say, by calling gdm_config_parse.
651
 
 */
652
 
gint
653
 
gdm_get_value_int (char *key)
654
 
{
655
 
   GdmConfigType *type = gdm_config_hash_lookup (type_hash, key);
656
 
   gpointer val        = gdm_config_hash_lookup (val_hash, key);
657
 
 
658
 
   if (type == NULL || val == NULL) {
659
 
      gdm_error ("Request for invalid configuration key %s", key);
660
 
   } else if (*type != CONFIG_INT) {
661
 
      gdm_error ("Request for configuration key %s, but not type INT", key);
662
 
   } else {
663
 
      gint *intval = (int *)val;
664
 
      return *intval;
665
 
   }
666
 
 
667
 
   return 0;
668
 
}
669
 
 
670
 
/**
671
 
 * gdm_get_value_string
672
 
 *
673
 
 * Gets a string configuration option by key.  The option must
674
 
 * first be loaded, say, by calling gdm_config_parse.
675
 
 */
676
 
gchar *
677
 
gdm_get_value_string (char *key)
678
 
{
679
 
   GdmConfigType *type;
680
 
   gpointer val;
681
 
 
682
 
   /* First look in translated_hash */
683
 
   if (translated_hash != NULL) {
684
 
      val = gdm_config_hash_lookup (translated_hash, key);
685
 
      if (val) {
686
 
         gchar **charval = (char **)val;
687
 
         return *charval;
688
 
      }
689
 
   }
690
 
 
691
 
   type = gdm_config_hash_lookup (type_hash, key);
692
 
   val  = gdm_config_hash_lookup (val_hash, key);
693
 
 
694
 
   if (type == NULL || val == NULL) {
695
 
      gdm_error ("Request for invalid configuration key %s", key);
696
 
   } else if (*type != CONFIG_STRING) {
697
 
      gdm_error ("Request for configuration key %s, but not type STRING", key);
698
 
   } else {
699
 
      gchar **charval = (char **)val;
700
 
      return *charval;
701
 
   }
702
 
 
703
 
   return NULL;
704
 
}
705
 
 
706
 
/**
707
 
 * gdm_get_value_bool
708
 
 * 
709
 
 * Gets a boolean configuration option by key.  The option must
710
 
 * first be loaded, say, by calling gdm_config_parse.
711
 
 */
712
 
gboolean
713
 
gdm_get_value_bool (char *key)
714
 
{
715
 
   GdmConfigType *type = gdm_config_hash_lookup (type_hash, key);
716
 
   gpointer val        = gdm_config_hash_lookup (val_hash, key);
717
 
 
718
 
   if (type == NULL || val == NULL) {
719
 
      gdm_error ("Request for invalid configuration key %s", key);
720
 
   } else if (*type != CONFIG_BOOL) {
721
 
      gdm_error ("Request for configuration key %s, but not type BOOL", key);
722
 
   } else {
723
 
      gboolean *boolval = (gboolean *)val;
724
 
      return *boolval;
725
 
   }
726
 
 
727
 
   return FALSE;
728
 
}
729
 
 
730
 
/**
731
 
 * Note that some GUI configuration parameters are read by the daemon,
732
 
 * and in order for them to work, it is necessary for the daemon to 
733
 
 * access a few keys in a per-display fashion.  These access functions
734
 
 * allow the daemon to access these keys properly.
735
 
 */
736
 
 
737
 
/**
738
 
 * gdm_get_value_int_per_display
739
 
 *
740
 
 * Gets the per-display version  of the configuration, or the default
741
 
 * value if none exists.
742
 
 */
743
 
gint gdm_get_value_int_per_display (gchar *display, gchar *key)
744
 
{
745
 
   gchar *perdispval;
746
 
 
747
 
   gdm_config_key_to_string_per_display (display, key, &perdispval);
748
 
 
749
 
   if (perdispval != NULL) {
750
 
      gint val = atoi (perdispval);
751
 
      g_free (perdispval);
752
 
      return val;
753
 
   } else {
754
 
      return (gdm_get_value_int (key));
755
 
   }
756
 
}
757
 
 
758
 
/**
759
 
 * gdm_get_value_bool_per_display
760
 
 *
761
 
 * Gets the per-display version  of the configuration, or the default
762
 
 * value if none exists.
763
 
 */
764
 
gboolean gdm_get_value_bool_per_display (gchar *display, gchar *key)
765
 
{
766
 
   gchar *perdispval;
767
 
 
768
 
   gdm_config_key_to_string_per_display (display, key, &perdispval);
769
 
 
770
 
   if (perdispval != NULL) {
771
 
      if (perdispval[0] == 'T' ||
772
 
          perdispval[0] == 't' ||
773
 
          perdispval[0] == 'Y' ||
774
 
          perdispval[0] == 'y' ||
775
 
          atoi (perdispval) != 0) {
776
 
                g_free (perdispval);
777
 
                return TRUE;
778
 
       } else {
779
 
                return FALSE;
780
 
       }
781
 
   } else {
782
 
      return (gdm_get_value_bool (key));
783
 
   }
784
 
}
785
 
 
786
 
/**
787
 
 * gdm_get_value_string_per_display
788
 
 *
789
 
 * Gets the per-display version  of the configuration, or the default
790
 
 * value if none exists.  Note that this value needs to be freed,
791
 
 * unlike the non-per-display version.
792
 
 */
793
 
gchar * gdm_get_value_string_per_display (gchar *display, gchar *key)
794
 
{
795
 
   gchar *perdispval;
796
 
 
797
 
   gdm_config_key_to_string_per_display (display, key, &perdispval);
798
 
 
799
 
   if (perdispval != NULL) {
800
 
      return perdispval;
801
 
   } else {
802
 
      return (g_strdup (gdm_get_value_string (key)));
803
 
   }
804
 
}
805
 
 
806
 
/**
807
 
 * gdm_config_key_to_string_per_display
808
 
 *
809
 
 * If the key makes sense to be per-display, return the value,
810
 
 * otherwise return NULL.  Keys that only apply to the daemon
811
 
 * process do not make sense for per-display configuration  
812
 
 * Valid keys include any key in the greeter or gui categories,
813
 
 * and the GDM_KEY_PAM_STACK key.
814
 
 *
815
 
 * If additional keys make sense for per-display usage, make
816
 
 * sure they are added to the if-test below.
817
 
 */
818
 
void
819
 
gdm_config_key_to_string_per_display (gchar *display, gchar *key, gchar **retval)
820
 
{
821
 
   gchar *file;
822
 
   gchar **splitstr = g_strsplit (key, "/", 2);
823
 
   *retval = NULL;
824
 
 
825
 
   if (display == NULL)
826
 
      return;
827
 
 
828
 
   file = gdm_get_per_display_custom_config_file (display);
829
 
 
830
 
   if (strcmp (ve_sure_string (splitstr[0]), "greeter") == 0 ||
831
 
       strcmp (ve_sure_string (splitstr[0]), "gui") == 0 ||
832
 
       is_key (key, GDM_KEY_PAM_STACK)) {
833
 
      gdm_config_key_to_string (file, key, retval);
834
 
   }
835
 
 
836
 
   g_free (file);
837
 
 
838
 
   return;
839
 
}
840
 
 
841
 
/**
842
 
 * gdm_config_key_to_string
843
 
 *
844
 
 * Returns a specific key from the config file, or NULL if not found.
845
 
 * Note this returns the value in string form, so the caller needs
846
 
 * to parse it properly if it is a bool or int.
847
 
 */
848
 
void
849
 
gdm_config_key_to_string (gchar *file, gchar *key, gchar **retval)
850
 
{
851
 
   VeConfig *cfg = ve_config_get (file);
852
 
   GdmConfigType *type = gdm_config_hash_lookup (type_hash, key);
853
 
   gchar **splitstr = g_strsplit (key, "/", 2);
854
 
   GList *list;
855
 
   *retval = NULL;
856
 
 
857
 
   /* Should not fail, all keys should have a category. */
858
 
   if (splitstr[0] == NULL)
859
 
      return;
860
 
 
861
 
   /* If file doesn't exist, then just return */
862
 
   if (cfg == NULL)
863
 
      return;
864
 
 
865
 
   list = ve_config_get_keys (cfg, splitstr[0]);
866
 
   while (list != NULL) {
867
 
      gchar *display_key     = (char *)list->data;
868
 
      gchar *display_fullkey = g_strdup_printf ("%s/%s", splitstr[0], display_key);
869
 
 
870
 
      if (is_key (key, display_fullkey)) {
871
 
         gdm_debug ("Returning value for key <%s>\n", key);
872
 
         if (*type == CONFIG_BOOL) {
873
 
            gboolean value = ve_config_get_bool (cfg, key);
874
 
            if (value)
875
 
               *retval = g_strdup ("true");
876
 
            else
877
 
               *retval = g_strdup ("false");
878
 
            return;
879
 
         } else if (*type == CONFIG_INT) {
880
 
            gint value = ve_config_get_int (cfg, key);
881
 
            *retval = g_strdup_printf ("%d", value);
882
 
            return;
883
 
         } else if (*type == CONFIG_STRING) {
884
 
            gchar *value = ve_config_get_string (cfg, key);
885
 
            if (value != NULL)
886
 
               *retval = g_strdup (value);
887
 
            return;
888
 
         }
889
 
      }
890
 
      g_free (display_fullkey);
891
 
      list = list->next;
892
 
   }
893
 
   return;
894
 
}
895
 
 
896
 
/**
897
 
 * gdm_config_to_string
898
 
 *
899
 
 * Returns a configuration option as a string.  Used by GDM's
900
 
 * GET_CONFIG socket command.
901
 
 */ 
902
 
void
903
 
gdm_config_to_string (gchar *key, gchar *display, gchar **retval)
904
 
{
905
 
   GdmConfigType *type = gdm_config_hash_lookup (type_hash, key);
906
 
   *retval = NULL;
907
 
 
908
 
   /*
909
 
    * See if there is a per-display config file, returning that value
910
 
    * if it exists.
911
 
    */
912
 
   if (display) {
913
 
      gdm_config_key_to_string_per_display (display, key, retval);
914
 
      if (*retval != NULL)
915
 
         return;
916
 
   }
917
 
 
918
 
   /* First look in translated_hash */
919
 
   if (translated_hash != NULL) {
920
 
      gpointer val = gdm_config_hash_lookup (translated_hash, key);
921
 
      if (val) {
922
 
         *retval = g_strdup (val);
923
 
         return;
924
 
      }
925
 
   }
926
 
 
927
 
   if (type != NULL) {
928
 
      if (*type == CONFIG_BOOL) {
929
 
         gboolean value = gdm_get_value_bool (key);
930
 
         if (value)
931
 
            *retval = g_strdup ("true");
932
 
         else
933
 
            *retval = g_strdup ("false");
934
 
         return;
935
 
      } else if (*type == CONFIG_INT) {
936
 
         gint value = gdm_get_value_int (key);
937
 
         *retval = g_strdup_printf ("%d", value);
938
 
         return;
939
 
      } else if (*type == CONFIG_STRING) {
940
 
         gchar *value = gdm_get_value_string (key);
941
 
         if (value != NULL)
942
 
            *retval = g_strdup (value);
943
 
         return;
944
 
      }
945
 
   }
946
 
 
947
 
   gdm_debug ("Error returning config key %s\n", key);
948
 
   return;
949
 
}
950
 
 
951
 
/**
952
 
 * gdm_compare_displays
953
 
 * 
954
 
 * Support function for loading displays from the configuration
955
 
 * file
956
 
 */
957
 
int
958
 
gdm_compare_displays (gconstpointer a, gconstpointer b)
959
 
{
960
 
   const GdmDisplay *d1 = a;
961
 
   const GdmDisplay *d2 = b;
962
 
   if (d1->dispnum < d2->dispnum)
963
 
      return -1;
964
 
   else if (d1->dispnum > d2->dispnum)
965
 
      return 1;
966
 
   else
967
 
      return 0;
968
 
}
969
 
 
970
 
/**
971
 
 * notify_displays_int
972
 
 * notify_displays_string
973
 
 *
974
 
 * The following two functions will notify the slave programs
975
 
 * (gdmgreeter, gdmlogin, etc.) that a configuration option has
976
 
 * been changed so the slave can update with the new option
977
 
 * value.  GDM does this notify when it receives a
978
 
 * GDM_CONFIG_UPDATE socket command from gdmsetup or from the
979
 
 * gdmflexiserver --command option.   notify_displays_int
980
 
 * is also used for notifying for boolean values.
981
 
 */
982
 
static void
983
 
notify_displays_int (const gchar *key, int val)
984
 
{
985
 
   GSList *li;
986
 
   for (li = displays; li != NULL; li = li->next) {
987
 
       GdmDisplay *disp = li->data;
988
 
       if (disp->master_notify_fd >= 0) {
989
 
          gdm_fdprintf (disp->master_notify_fd, "%c%s %d\n",
990
 
                        GDM_SLAVE_NOTIFY_KEY, key, val);
991
 
 
992
 
          if (disp != NULL && disp->slavepid > 1)
993
 
             kill (disp->slavepid, SIGUSR2);
994
 
      }
995
 
   }
996
 
}
997
 
 
998
 
static void
999
 
notify_displays_string (const gchar *key, const gchar *val)
1000
 
{
1001
 
   GSList *li;
1002
 
   for (li = displays; li != NULL; li = li->next) {
1003
 
      GdmDisplay *disp = li->data;
1004
 
      if (disp->master_notify_fd >= 0) {
1005
 
         if (val == NULL) {
1006
 
            gdm_fdprintf (disp->master_notify_fd, "%c%s \n",
1007
 
                          GDM_SLAVE_NOTIFY_KEY, key);
1008
 
         } else {
1009
 
            gdm_fdprintf (disp->master_notify_fd, "%c%s %s\n",
1010
 
                          GDM_SLAVE_NOTIFY_KEY, key, val);
1011
 
         }
1012
 
         if (disp != NULL && disp->slavepid > 1)
1013
 
            kill (disp->slavepid, SIGUSR2);
1014
 
      }
1015
 
   }
1016
 
}
1017
 
 
1018
 
/**
1019
 
 * _gdm_set_value_string
1020
 
 * _gdm_set_value_bool
1021
 
 * _gdm_set_value_int
1022
 
 *
1023
 
 * The following interfaces are used to set values.  The "doing_update"
1024
 
 * boolean argument which is only set when GDM_UPDATE_CONFIG is called.
1025
 
 * If doing_update is TRUE, then a notify is sent to slaves.  When
1026
 
 * loading values at other times (such as when first loading
1027
 
 * configuration options) there is no need to notify the slaves.  If
1028
 
 * there is a desire to send a notify to the slaves, the
1029
 
 * gdm_update_config function should be used instead of calling these
1030
 
 * functions directly.
1031
 
 */
1032
 
static void
1033
 
_gdm_set_value_string (gchar *key, gchar *value_in, gboolean doing_update)
1034
 
{
1035
 
   gchar **setting = gdm_config_hash_lookup (val_hash, key);
1036
 
   gchar *setting_copy = NULL;
1037
 
   gchar *temp_string;
1038
 
   gchar *value;
1039
 
 
1040
 
   if (! ve_string_empty (value_in))
1041
 
      value = value_in;
1042
 
   else
1043
 
      value = NULL;
1044
 
 
1045
 
   if (setting == NULL) {
1046
 
      gdm_error ("Failure setting key %s to %s", key, value);
1047
 
      return;
1048
 
   }
1049
 
 
1050
 
   if (*setting != NULL) {
1051
 
      /* Free old value */
1052
 
      setting_copy = g_strdup (*setting);
1053
 
      g_free (*setting);
1054
 
   }
1055
 
 
1056
 
   /* User PATH */
1057
 
   if (is_key (key, GDM_KEY_PATH)) {
1058
 
 
1059
 
      temp_string = gdm_read_default ("PATH=");
1060
 
      if (temp_string != NULL)
1061
 
         *setting = temp_string;                
1062
 
      else if (value != NULL)
1063
 
         *setting = g_strdup (value);
1064
 
      else
1065
 
         *setting = NULL;
1066
 
 
1067
 
   /* Root user PATH */
1068
 
   } else if (is_key (key, GDM_KEY_ROOT_PATH)) {
1069
 
 
1070
 
      temp_string = gdm_read_default ("SUPATH=");
1071
 
      if (temp_string != NULL)
1072
 
         *setting = temp_string;                
1073
 
      else if (value != NULL)
1074
 
         *setting = g_strdup (value);
1075
 
      else
1076
 
         *setting = NULL;
1077
 
 
1078
 
    /* Location of Xsession script */
1079
 
    } else if (is_key (key, GDM_KEY_BASE_XSESSION)) {
1080
 
       if (value != NULL) {
1081
 
          *setting = g_strdup (value);
1082
 
       } else {
1083
 
          gdm_info (_("%s: BaseXsession empty; using %s/gdm/Xsession"),
1084
 
                      "gdm_config_parse",
1085
 
                      GDMCONFDIR);
1086
 
          *setting = g_build_filename (GDMCONFDIR,
1087
 
                                       "gdm", "Xsession", NULL);
1088
 
       }
1089
 
 
1090
 
   /* Halt, Reboot, and Suspend commands */
1091
 
   } else if (is_key (key, GDM_KEY_HALT) ||
1092
 
              is_key (key, GDM_KEY_REBOOT) ||
1093
 
              is_key (key, GDM_KEY_SUSPEND)) {
1094
 
       if (value != NULL)
1095
 
          *setting = ve_get_first_working_command (value, FALSE);
1096
 
       else
1097
 
          *setting = NULL;
1098
 
 
1099
 
   /* Console cannot handle these languages */
1100
 
   } else if (is_key (key, GDM_KEY_CONSOLE_CANNOT_HANDLE)) {
1101
 
       if (value != NULL)
1102
 
          *setting = g_strdup (value);
1103
 
       else
1104
 
          *setting = "";
1105
 
       gdm_ok_console_language ();
1106
 
 
1107
 
   /* Location of Xserver */
1108
 
   } else if (is_key (key, GDM_KEY_STANDARD_XSERVER)) {
1109
 
      gchar *bin = NULL;
1110
 
 
1111
 
      if (value != NULL)
1112
 
         bin = ve_first_word (value);
1113
 
 
1114
 
      if G_UNLIKELY (ve_string_empty (bin) ||
1115
 
                     g_access (bin, X_OK) != 0) {
1116
 
         gdm_info (_("%s: Standard X server not found; trying alternatives"),
1117
 
                     "gdm_config_parse");
1118
 
         if (g_access ("/usr/X11R6/bin/X", X_OK) == 0) {
1119
 
            *setting = g_strdup ("/usr/X11R6/bin/X");
1120
 
         } else if (g_access ("/opt/X11R6/bin/X", X_OK) == 0) {
1121
 
            *setting = g_strdup ("/opt/X11R6/bin/X");
1122
 
         } else if (g_access ("/usr/bin/X11/X", X_OK) == 0) {
1123
 
            *setting = g_strdup ("/usr/bin/X11/X");
1124
 
         } else
1125
 
            *setting = g_strdup (value);
1126
 
      } else {
1127
 
         *setting = g_strdup (value);
1128
 
      }
1129
 
 
1130
 
   /* Graphical Theme Directory */
1131
 
   } else if (is_key (key, GDM_KEY_GRAPHICAL_THEME_DIR)) {
1132
 
      if (value == NULL ||
1133
 
          ! g_file_test (value, G_FILE_TEST_IS_DIR))
1134
 
      {
1135
 
         *setting = g_strdup (GREETERTHEMEDIR);
1136
 
      } else {
1137
 
         *setting = g_strdup (value);
1138
 
      }
1139
 
 
1140
 
   /* Graphical Theme */
1141
 
   } else if (is_key (key, GDM_KEY_GRAPHICAL_THEME)) {
1142
 
     if (value == NULL)
1143
 
        *setting = g_strdup ("circles");
1144
 
     else
1145
 
        *setting = g_strdup (value);
1146
 
 
1147
 
   /*
1148
 
    * Default Welcome Message.  Don't translate here since the
1149
 
    * GDM user may not be running with the same language as the user.
1150
 
    * The slave programs will translate the string.
1151
 
    */
1152
 
   } else if (is_key (key, GDM_KEY_WELCOME)) {
1153
 
      if (value != NULL)
1154
 
         *setting = g_strdup (value);
1155
 
      else
1156
 
         *setting = g_strdup (GDM_DEFAULT_WELCOME_MSG);
1157
 
 
1158
 
   /*
1159
 
    * Default Remote Welcome Message.  Don't translate here since the 
1160
 
    * GDM user may not be running with the same language as the user.
1161
 
    * The slave programs will translate the string.
1162
 
    */
1163
 
   } else if (is_key (key, GDM_KEY_REMOTE_WELCOME)) {
1164
 
      if (value != NULL)
1165
 
         *setting = g_strdup (value);
1166
 
      else
1167
 
         *setting = g_strdup (GDM_DEFAULT_REMOTE_WELCOME_MSG);
1168
 
 
1169
 
   /* All others */
1170
 
   } else {
1171
 
       if (value != NULL)
1172
 
          *setting = g_strdup (value);
1173
 
       else {
1174
 
          if (is_key (key, GDM_KEY_GREETER))
1175
 
             gdm_error (_("%s: No greeter specified."), "gdm_config_parse");
1176
 
          else if (is_key (key, GDM_KEY_REMOTE_GREETER))
1177
 
             gdm_error (_("%s: No remote greeter specified."), "gdm_config_parse");
1178
 
          else if (is_key (key, GDM_KEY_SESSION_DESKTOP_DIR))
1179
 
             gdm_error (_("%s: No sessions directory specified."), "gdm_config_parse");
1180
 
 
1181
 
          *setting = NULL;
1182
 
       }
1183
 
   }
1184
 
 
1185
 
   /* Handle update */
1186
 
   if (doing_update == TRUE && 
1187
 
       strcmp (ve_sure_string (*setting),
1188
 
               ve_sure_string (setting_copy)) != 0) {
1189
 
 
1190
 
      if (is_key (key, GDM_KEY_GREETER))
1191
 
         notify_displays_string (GDM_NOTIFY_GREETER, *setting);
1192
 
      else if (is_key (key, GDM_KEY_REMOTE_GREETER))
1193
 
         notify_displays_string (GDM_NOTIFY_REMOTE_GREETER, *setting);
1194
 
      else if (is_key (key, GDM_KEY_SOUND_ON_LOGIN_FILE))
1195
 
         notify_displays_string (GDM_NOTIFY_SOUND_ON_LOGIN_FILE, *setting);
1196
 
      else if (is_key (key, GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE))
1197
 
         notify_displays_string (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE, *setting);
1198
 
      else if (is_key (key, GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE))
1199
 
         notify_displays_string (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE, *setting);
1200
 
      else if (is_key (key, GDM_KEY_GTK_MODULES_LIST))
1201
 
         notify_displays_string (GDM_NOTIFY_GTK_MODULES_LIST, *setting);
1202
 
      else if (is_key (key, GDM_KEY_TIMED_LOGIN))
1203
 
         notify_displays_string (GDM_NOTIFY_TIMED_LOGIN, *setting);
1204
 
   }
1205
 
 
1206
 
   if (setting_copy != NULL)
1207
 
      g_free (setting_copy);
1208
 
 
1209
 
   if (*setting == NULL)
1210
 
      gdm_debug ("set config key %s to string <NULL>", key);
1211
 
   else
1212
 
      gdm_debug ("set config key %s to string %s", key, *setting);
1213
 
}
1214
 
 
1215
 
void
1216
 
gdm_set_value_string (gchar *key, gchar *value_in)
1217
 
{
1218
 
   _gdm_set_value_string (key, value_in, TRUE);
1219
 
}
1220
 
 
1221
 
static void
1222
 
_gdm_set_value_bool (gchar *key, gboolean value, gboolean doing_update)
1223
 
{
1224
 
   gboolean *setting     = gdm_config_hash_lookup (val_hash, key);
1225
 
   gboolean setting_copy = *setting;
1226
 
   gchar *temp_string;
1227
 
 
1228
 
   if (setting == NULL) {
1229
 
      if (value)
1230
 
         gdm_error ("Failure setting key %s to true", key);
1231
 
      else
1232
 
         gdm_error ("Failure setting key %s to false", key);
1233
 
      return;
1234
 
   }
1235
 
 
1236
 
   /* Password Required */
1237
 
   if (is_key (key, GDM_KEY_PASSWORD_REQUIRED)) {
1238
 
      temp_string = gdm_read_default ("PASSREQ=");
1239
 
      if (temp_string == NULL)
1240
 
         *setting = value;
1241
 
      else if (g_ascii_strcasecmp (temp_string, "YES") == 0)
1242
 
         *setting = TRUE;
1243
 
      else
1244
 
         *setting = FALSE;
1245
 
      g_free (temp_string);
1246
 
 
1247
 
   /* Allow root login */
1248
 
   } else if (is_key (key, GDM_KEY_ALLOW_REMOTE_ROOT)) {
1249
 
      temp_string = gdm_read_default ("CONSOLE=");
1250
 
 
1251
 
      if (temp_string == NULL)
1252
 
         *setting = value;
1253
 
      else if (g_ascii_strcasecmp (temp_string, "/dev/console") != 0)
1254
 
         *setting = TRUE;
1255
 
      else
1256
 
         *setting = FALSE;
1257
 
      g_free (temp_string);
1258
 
 
1259
 
   /* XDMCP */
1260
 
#ifndef HAVE_LIBXDMCP
1261
 
   } else if (is_key (key, GDM_KEY_XDMCP)) {
1262
 
      if (value) {
1263
 
         gdm_info (_("%s: XDMCP was enabled while there is no XDMCP support; turning it off"), "gdm_config_parse");
1264
 
      }
1265
 
      *setting = FALSE;
1266
 
#endif
1267
 
   } else {
1268
 
      *setting = value;
1269
 
   }
1270
 
 
1271
 
   /* Handle update */
1272
 
   if (doing_update == TRUE && *setting != setting_copy) {
1273
 
     if (is_key (key, GDM_KEY_ALLOW_ROOT))
1274
 
        notify_displays_int (GDM_NOTIFY_ALLOW_ROOT, *setting);
1275
 
     else if (is_key (key, GDM_KEY_ALLOW_REMOTE_ROOT))
1276
 
        notify_displays_int (GDM_NOTIFY_ALLOW_REMOTE_ROOT, *setting);
1277
 
     else if (is_key (key, GDM_KEY_ALLOW_REMOTE_AUTOLOGIN))
1278
 
        notify_displays_int (GDM_NOTIFY_ALLOW_REMOTE_AUTOLOGIN, *setting);
1279
 
     else if (is_key (key, GDM_KEY_SYSTEM_MENU))
1280
 
        notify_displays_int (GDM_NOTIFY_SYSTEM_MENU, *setting);
1281
 
     else if (is_key (key, GDM_KEY_CONFIG_AVAILABLE))
1282
 
        notify_displays_int (GDM_NOTIFY_CONFIG_AVAILABLE, *setting);
1283
 
     else if (is_key (key, GDM_KEY_CHOOSER_BUTTON))
1284
 
        notify_displays_int (GDM_NOTIFY_CHOOSER_BUTTON, *setting); 
1285
 
     else if (is_key (key, GDM_KEY_DISALLOW_TCP))
1286
 
        notify_displays_int (GDM_NOTIFY_DISALLOW_TCP, *setting);
1287
 
     else if (is_key (key, GDM_KEY_ADD_GTK_MODULES))
1288
 
        notify_displays_int (GDM_NOTIFY_ADD_GTK_MODULES, *setting);
1289
 
     else if (is_key (key, GDM_KEY_TIMED_LOGIN_ENABLE))
1290
 
        notify_displays_int (GDM_NOTIFY_TIMED_LOGIN_ENABLE, *setting);
1291
 
   }
1292
 
 
1293
 
   if (*setting)
1294
 
      gdm_debug ("set config key %s to boolean true", key);
1295
 
   else
1296
 
      gdm_debug ("set config key %s to boolean false", key);
1297
 
}
1298
 
 
1299
 
void
1300
 
gdm_set_value_bool (gchar *key, gboolean value)
1301
 
{
1302
 
   _gdm_set_value_bool (key, value, TRUE);
1303
 
}
1304
 
 
1305
 
static void
1306
 
_gdm_set_value_int (gchar *key, gint value, gboolean doing_update)
1307
 
{
1308
 
   gint *setting     = gdm_config_hash_lookup (val_hash, key);
1309
 
   gint setting_copy = *setting;
1310
 
 
1311
 
   if (setting == NULL) {
1312
 
      gdm_error ("Failure setting key %s to %d", key, value);
1313
 
      return;
1314
 
   }
1315
 
 
1316
 
   if (is_key (key, GDM_KEY_MAX_INDIRECT) ||
1317
 
       is_key (key, GDM_KEY_XINERAMA_SCREEN)) {
1318
 
      if (value < 0)
1319
 
         *setting = 0;
1320
 
      else
1321
 
         *setting = value;
1322
 
   } else if (is_key (key, GDM_KEY_TIMED_LOGIN_DELAY)) {
1323
 
      if (value < 5) {
1324
 
         gdm_info (_("%s: TimedLoginDelay is less than 5, defaulting to 5."), "gdm_config_parse");
1325
 
         *setting = 5;
1326
 
      } else
1327
 
         *setting = value;
1328
 
   } else if (is_key (key, GDM_KEY_MAX_ICON_WIDTH) ||
1329
 
              is_key (key, GDM_KEY_MAX_ICON_HEIGHT)) {
1330
 
      if (value < 0)
1331
 
         *setting = 128;
1332
 
      else
1333
 
         *setting = value;
1334
 
   } else if (is_key (key, GDM_KEY_SCAN_TIME)) {
1335
 
      if (value < 1)
1336
 
         *setting = 1;
1337
 
      else
1338
 
         *setting = value;
1339
 
   }
1340
 
 else {
1341
 
      *setting = value;
1342
 
   }
1343
 
 
1344
 
   /* Handle update */
1345
 
   if (doing_update == TRUE && *setting != setting_copy) {
1346
 
      if (is_key (key, GDM_KEY_RETRY_DELAY))
1347
 
         notify_displays_int (GDM_NOTIFY_RETRY_DELAY, *setting);
1348
 
      else if (is_key (key, GDM_KEY_TIMED_LOGIN_DELAY))
1349
 
         notify_displays_int (GDM_NOTIFY_TIMED_LOGIN_DELAY, *setting);
1350
 
   }
1351
 
 
1352
 
   gdm_debug ("set config key %s to integer %d", key, *setting);
1353
 
}
1354
 
 
1355
 
void
1356
 
gdm_set_value_int (gchar *key, gint value)
1357
 
{
1358
 
   _gdm_set_value_int (key, value, TRUE);
1359
 
}
1360
 
 
1361
 
/**
1362
 
 * gdm_set_value
1363
 
 *
1364
 
 * This functon is used to set the config values in the hash.  This is called
1365
 
 * at initial config load time or when gdm_update_config is called to reload
1366
 
 * them.   It adds translated strings to the hash with their proper keys
1367
 
 * (greeter/Welcome[cs] for example).
1368
 
 */
1369
 
static gboolean
1370
 
gdm_set_value (VeConfig *cfg, GdmConfigType *type, gchar *key, gboolean doing_update) 
1371
 
{
1372
 
   gchar * realkey = gdm_config_hash_lookup (realkey_hash, key);
1373
 
   gchar *value;
1374
 
 
1375
 
   if (realkey == NULL) {
1376
 
      return FALSE;
1377
 
   }
1378
 
 
1379
 
   if (*type == CONFIG_BOOL) {
1380
 
       gboolean value = ve_config_get_bool (cfg, realkey);
1381
 
       _gdm_set_value_bool (key, value, doing_update);
1382
 
       return TRUE;
1383
 
   } else if (*type == CONFIG_INT) {
1384
 
       gint value = ve_config_get_int (cfg, realkey);
1385
 
       _gdm_set_value_int (key, value, doing_update);
1386
 
       return TRUE;
1387
 
   } else if (*type == CONFIG_STRING) {
1388
 
 
1389
 
       /* Process translated strings */
1390
 
       if (is_key (key, GDM_KEY_WELCOME) ||
1391
 
           is_key (key, GDM_KEY_REMOTE_WELCOME)) {
1392
 
 
1393
 
          GList *list = ve_config_get_keys (cfg, "greeter");
1394
 
          gchar *prefix, *basekey;
1395
 
 
1396
 
          if (is_key (key, GDM_KEY_WELCOME)) {
1397
 
             basekey = g_strdup ("Welcome");
1398
 
             prefix  = g_strdup ("Welcome[");
1399
 
          } else {
1400
 
             basekey = g_strdup ("RemoteWelcome");
1401
 
             prefix  = g_strdup ("RemoteWelcome[");
1402
 
          }
1403
 
 
1404
 
          /*
1405
 
           * Loop over translated keys and put all values into the hash
1406
 
           * Probably should loop through the hashs and delete any old values,
1407
 
           * but this just means that if a translation is deleted from the
1408
 
           * config, GDM won't forget about it until restart.  I don't think
1409
 
           * this will happen, or be a real problem if it does.
1410
 
           */
1411
 
          while (list != NULL) {
1412
 
             if (g_str_has_prefix ((char *)list->data, prefix) &&
1413
 
                 g_str_has_suffix ((char *)list->data, "]")) {
1414
 
                gchar *transkey, *transvalue;
1415
 
 
1416
 
                if (translated_hash == NULL)
1417
 
                   translated_hash = g_hash_table_new (g_str_hash, g_str_equal);
1418
 
 
1419
 
                transkey   = g_strdup_printf ("greeter/%s", (char *)list->data);
1420
 
                transvalue = ve_config_get_string (cfg, transkey);
1421
 
 
1422
 
                g_hash_table_remove (translated_hash, transkey);
1423
 
 
1424
 
               /*
1425
 
                * Store translated values in a separate hash.  Note that we load
1426
 
                * the initial values via a g_hash_table_foreach function, so if
1427
 
                * we add these to the same hash, we would end up loading these
1428
 
                * values in again a second time.
1429
 
                */
1430
 
                g_hash_table_insert (translated_hash, transkey, transvalue);
1431
 
             }
1432
 
             list = list->next;
1433
 
          }
1434
 
          g_free (basekey);
1435
 
          g_free (prefix);
1436
 
       }
1437
 
 
1438
 
       /* Handle non-translated strings as normal */
1439
 
       value = ve_config_get_string (cfg, realkey);
1440
 
       _gdm_set_value_string (key, value, doing_update);
1441
 
       return TRUE;
1442
 
   }
1443
 
   
1444
 
   return FALSE;
1445
 
}
1446
 
 
1447
 
/**
1448
 
 * gdm_find_xserver
1449
 
 *
1450
 
 * Return an xserver with a given ID, or NULL if not found.
1451
 
 */
1452
 
GdmXserver *
1453
 
gdm_find_xserver (const gchar *id)
1454
 
{
1455
 
   GSList *li;
1456
 
 
1457
 
   if (xservers == NULL)
1458
 
      return NULL;
1459
 
 
1460
 
   if (id == NULL)
1461
 
      return xservers->data;
1462
 
 
1463
 
   for (li = xservers; li != NULL; li = li->next) {
1464
 
      GdmXserver *svr = li->data;
1465
 
      if (strcmp (ve_sure_string (svr->id), ve_sure_string (id)) == 0)
1466
 
         return svr;
1467
 
   }
1468
 
   return NULL;
1469
 
}
1470
 
 
1471
 
/**
1472
 
 * gdm_get_xservers
1473
 
 *
1474
 
 * Prepare a string to be returned for the GET_SERVER_LIST
1475
 
 * sockets command.
1476
 
 */
1477
 
gchar *
1478
 
gdm_get_xservers (void)
1479
 
{
1480
 
   GSList *li;
1481
 
   gchar *retval = NULL;
1482
 
 
1483
 
   if (xservers == NULL)
1484
 
      return NULL;
1485
 
 
1486
 
   for (li = xservers; li != NULL; li = li->next) {
1487
 
      GdmXserver *svr = li->data;
1488
 
      if (retval != NULL)
1489
 
         retval = g_strconcat (retval, ";", svr->id, NULL);
1490
 
      else
1491
 
         retval = g_strdup (svr->id);
1492
 
   }
1493
 
 
1494
 
   return retval;
1495
 
}
1496
 
 
1497
 
/* PRIO_MIN and PRIO_MAX are not defined on Solaris, but are -20 and 20 */
1498
 
#if sun
1499
 
#ifndef PRIO_MIN
1500
 
#define PRIO_MIN -20
1501
 
#endif
1502
 
#ifndef PRIO_MAX
1503
 
#define PRIO_MAX 20
1504
 
#endif
1505
 
#endif
1506
 
 
1507
 
/**
1508
 
 * gdm_load_xservers
1509
 
 *
1510
 
 * Load [server-foo] sections from a configuration file.
1511
 
 */
1512
 
static void
1513
 
gdm_load_xservers (VeConfig *cfg)
1514
 
{
1515
 
   GList *list, *li;
1516
 
 
1517
 
   /* Find server definitions */
1518
 
   list = ve_config_get_sections (cfg);
1519
 
   for (li = list; li != NULL; li = li->next) {
1520
 
      const gchar *sec = li->data;
1521
 
 
1522
 
      if (strncmp (sec, "server-", strlen ("server-")) == 0) {
1523
 
         gchar *id;
1524
 
 
1525
 
         id = g_strdup (sec + strlen ("server-"));
1526
 
 
1527
 
         /*
1528
 
          * See if we already loaded a server with this id, skip if
1529
 
          * one already exists.
1530
 
          */
1531
 
         if (gdm_find_xserver (id) != NULL) {
1532
 
            g_free (id);
1533
 
         } else {
1534
 
            GdmXserver *svr = g_new0 (GdmXserver, 1);
1535
 
            gchar buf[256];
1536
 
            int n;
1537
 
 
1538
 
            svr->id = id;
1539
 
 
1540
 
            g_snprintf (buf, sizeof (buf), "%s/" GDM_KEY_SERVER_NAME, sec);
1541
 
            svr->name = ve_config_get_string (cfg, buf);
1542
 
            g_snprintf (buf, sizeof (buf), "%s/" GDM_KEY_SERVER_COMMAND, sec);
1543
 
            svr->command = ve_config_get_string (cfg, buf);
1544
 
            g_snprintf (buf, sizeof (buf), "%s/" GDM_KEY_SERVER_FLEXIBLE, sec);
1545
 
            svr->flexible = ve_config_get_bool (cfg, buf);
1546
 
            g_snprintf (buf, sizeof (buf), "%s/" GDM_KEY_SERVER_CHOOSABLE, sec);
1547
 
            svr->choosable = ve_config_get_bool (cfg, buf);
1548
 
            g_snprintf (buf, sizeof (buf), "%s/" GDM_KEY_SERVER_HANDLED, sec);
1549
 
            svr->handled = ve_config_get_bool (cfg, buf);
1550
 
            g_snprintf (buf, sizeof (buf), "%s/" GDM_KEY_SERVER_CHOOSER, sec);
1551
 
            svr->chooser = ve_config_get_bool (cfg, buf);
1552
 
            g_snprintf (buf, sizeof (buf), "%s/" GDM_KEY_SERVER_PRIORITY, sec);
1553
 
            svr->priority = ve_config_get_int (cfg, buf);
1554
 
 
1555
 
            /* do some bounds checking */
1556
 
             n = svr->priority;
1557
 
             if (n < PRIO_MIN)
1558
 
                n = PRIO_MIN;
1559
 
             else if (n > PRIO_MAX)
1560
 
                n = PRIO_MAX;
1561
 
             if (n != svr->priority) {
1562
 
                gdm_error (_("%s: Priority out of bounds; changed to %d"),
1563
 
                             "gdm_config_parse", n);
1564
 
                svr->priority = n;
1565
 
             }
1566
 
 
1567
 
            if (ve_string_empty (svr->command)) {
1568
 
               gdm_error (_("%s: Empty server command; "
1569
 
                            "using standard command."), "gdm_config_parse");
1570
 
               g_free (svr->command);
1571
 
               svr->command = g_strdup (GdmStandardXserver);
1572
 
            }
1573
 
 
1574
 
            xservers = g_slist_append (xservers, svr);
1575
 
         }
1576
 
      }
1577
 
   }
1578
 
  ve_config_free_list_of_strings (list);
1579
 
}
1580
 
 
1581
 
/**
1582
 
 * gdm_update_xservers
1583
 
 *
1584
 
 * Reload [server-foo] sections from the configuration files.
1585
 
 */
1586
 
static void
1587
 
gdm_update_xservers (VeConfig *cfg, VeConfig *custom_cfg)
1588
 
{
1589
 
   GSList *xli;
1590
 
 
1591
 
   /* Free list if already loaded */
1592
 
   if (xservers != NULL) {
1593
 
      for (xli = xservers; xli != NULL; xli = xli->next) {
1594
 
         GdmXserver *xsvr = xli->data;
1595
 
 
1596
 
         g_free (xsvr->id);
1597
 
         g_free (xsvr->name);
1598
 
         g_free (xsvr->command);
1599
 
      }
1600
 
      g_slist_free (xservers);
1601
 
      xservers = NULL;
1602
 
   }
1603
 
 
1604
 
   /* Reload first from custom_cfg then from cfg. */
1605
 
   if (custom_cfg != NULL)
1606
 
      gdm_load_xservers (custom_cfg);
1607
 
 
1608
 
   if (cfg != NULL)
1609
 
      gdm_load_xservers (cfg);
1610
 
 
1611
 
   /* If no "Standard" server was created, then add it */
1612
 
   if (xservers == NULL || gdm_find_xserver (GDM_STANDARD) == NULL) {
1613
 
      GdmXserver *svr = g_new0 (GdmXserver, 1);
1614
 
 
1615
 
      svr->id        = g_strdup (GDM_STANDARD);
1616
 
      svr->name      = g_strdup ("Standard server");
1617
 
      svr->command   = g_strdup (GdmStandardXserver);
1618
 
      svr->flexible  = TRUE;
1619
 
      svr->choosable = TRUE;
1620
 
      svr->handled   = TRUE;
1621
 
      svr->priority  = 0;
1622
 
      xservers       = g_slist_append (xservers, svr);
1623
 
   }
1624
 
}
1625
 
 
1626
 
/**
1627
 
 * gdm_update_config
1628
 
 * 
1629
 
 * Will cause a the GDM daemon to re-read the key from the configuration
1630
 
 * file and cause notify signal to be sent to the slaves for the 
1631
 
 * specified key, if appropriate.  Only specific keys defined in the
1632
 
 * gdm_set_value functions above are associated with such notification.
1633
 
 * Obviously notification is not needed for configuration options only
1634
 
 * used by the daemon.  This function is called when the UPDDATE_CONFIG
1635
 
 * sockets command is called.
1636
 
 *
1637
 
 * To add a new notification, a GDM_NOTIFY_* argument will need to be
1638
 
 * defined in gdm.h, supporting logic placed in the gdm_set_value
1639
 
 * functions and in the gdm_slave_handle_notify function in slave.c.
1640
 
 */
1641
 
gboolean
1642
 
gdm_update_config (gchar* key)
1643
 
{
1644
 
   GdmConfigType *type;
1645
 
   struct stat statbuf, custom_statbuf;
1646
 
   VeConfig *cfg;
1647
 
   VeConfig *custom_cfg = NULL;
1648
 
   gboolean rc = FALSE;
1649
 
 
1650
 
   /*
1651
 
    * Do not allow these keys to be updated, since GDM would need
1652
 
    * additional work, or at least heavy testing, to make these keys
1653
 
    * flexible enough to be changed at runtime.
1654
 
    */ 
1655
 
   if (is_key (key, GDM_KEY_PID_FILE) ||
1656
 
       is_key (key, GDM_KEY_CONSOLE_NOTIFY) ||
1657
 
       is_key (key, GDM_KEY_USER) ||
1658
 
       is_key (key, GDM_KEY_GROUP) ||
1659
 
       is_key (key, GDM_KEY_LOG_DIR) ||
1660
 
       is_key (key, GDM_KEY_SERV_AUTHDIR) ||
1661
 
       is_key (key, GDM_KEY_USER_AUTHDIR) ||
1662
 
       is_key (key, GDM_KEY_USER_AUTHFILE) ||
1663
 
       is_key (key, GDM_KEY_USER_AUTHDIR_FALLBACK)) {
1664
 
      return FALSE;
1665
 
   }
1666
 
 
1667
 
   /* See if custom file is now there */
1668
 
   if (custom_config_file == NULL) {
1669
 
      custom_cfg = gdm_get_custom_config (&statbuf);
1670
 
   }
1671
 
 
1672
 
   /* Don't bother re-reading configuration if files have not changed */
1673
 
   VE_IGNORE_EINTR (g_stat (config_file, &statbuf));
1674
 
   VE_IGNORE_EINTR (g_stat (custom_config_file, &custom_statbuf));
1675
 
 
1676
 
  /*
1677
 
   * Do not reset mtime to the latest values since there is no
1678
 
   * guarantee that only one key was modified since last write.
1679
 
   * This check simply avoids re-reading the files if neither
1680
 
   * has changed since GDM was started.
1681
 
   */
1682
 
   if (config_file_mtime        == statbuf.st_mtime &&
1683
 
       custom_config_file_mtime == custom_statbuf.st_mtime)
1684
 
      return TRUE;
1685
 
 
1686
 
   /* Shortcut for updating all XDMCP parameters */
1687
 
   if (is_key (key, "xdmcp/PARAMETERS")) {
1688
 
      gdm_update_config (GDM_KEY_DISPLAYS_PER_HOST);
1689
 
      gdm_update_config (GDM_KEY_MAX_PENDING);
1690
 
      gdm_update_config (GDM_KEY_MAX_WAIT);
1691
 
      gdm_update_config (GDM_KEY_MAX_SESSIONS);
1692
 
      gdm_update_config (GDM_KEY_INDIRECT);
1693
 
      gdm_update_config (GDM_KEY_MAX_INDIRECT);
1694
 
      gdm_update_config (GDM_KEY_MAX_WAIT_INDIRECT);
1695
 
      gdm_update_config (GDM_KEY_PING_INTERVAL);
1696
 
      return TRUE;
1697
 
   }
1698
 
 
1699
 
   if (custom_config_file != NULL)
1700
 
      custom_cfg = ve_config_new (custom_config_file);
1701
 
 
1702
 
   if (is_key (key, "xservers/PARAMETERS")) {
1703
 
      cfg = ve_config_new (config_file);
1704
 
      gdm_update_xservers (cfg, custom_cfg);
1705
 
      ve_config_destroy (cfg);
1706
 
      if (custom_cfg != NULL)
1707
 
         ve_config_destroy (custom_cfg);
1708
 
      return TRUE;
1709
 
   }
1710
 
 
1711
 
   type = gdm_config_hash_lookup (type_hash, key);
1712
 
   if (type == NULL)
1713
 
      return FALSE;
1714
 
 
1715
 
   /* First check the custom file */
1716
 
   if (custom_cfg != NULL) {
1717
 
       gchar **splitstr = g_strsplit (key, "/", 2);
1718
 
 
1719
 
       if (splitstr[0] != NULL) {
1720
 
          GList *list = ve_config_get_keys (custom_cfg, splitstr[0]);
1721
 
 
1722
 
          while (list != NULL) {
1723
 
             gchar *custom_key     = (char *)list->data;
1724
 
             gchar *custom_fullkey = g_strdup_printf ("%s/%s", splitstr[0], custom_key);
1725
 
 
1726
 
             if (is_key (key, custom_fullkey)) {
1727
 
                rc = gdm_set_value (custom_cfg, type, key, TRUE);
1728
 
                
1729
 
                g_free (custom_fullkey);
1730
 
                g_strfreev (splitstr);
1731
 
                ve_config_destroy (custom_cfg);
1732
 
                return (rc);
1733
 
             }
1734
 
 
1735
 
             g_free (custom_fullkey);
1736
 
             list = list->next;
1737
 
          }
1738
 
       }
1739
 
       g_strfreev (splitstr);
1740
 
   }
1741
 
 
1742
 
   /* If not in the custom file, check main config file */
1743
 
   cfg = ve_config_new (config_file);
1744
 
   rc  = gdm_set_value (cfg, type, key, TRUE);
1745
 
 
1746
 
   ve_config_destroy (cfg);
1747
 
   if (custom_cfg != NULL)
1748
 
      ve_config_destroy (custom_cfg);
1749
 
   return rc;
1750
 
}
1751
 
 
1752
 
/**
1753
 
 * check_logdir
1754
 
 * check_servauthdir
1755
 
 *
1756
 
 * Support functions for gdm_config_parse.
1757
 
 */
1758
 
static void
1759
 
check_logdir (void)
1760
 
{
1761
 
        struct stat statbuf;
1762
 
        int r;
1763
 
 
1764
 
        VE_IGNORE_EINTR (r = g_stat (GdmLogDir, &statbuf));
1765
 
        if (r < 0 ||
1766
 
            ! S_ISDIR (statbuf.st_mode))  {
1767
 
                gdm_error (_("%s: Logdir %s does not exist or isn't a directory.  Using ServAuthDir %s."), "gdm_config_parse",
1768
 
                           GdmLogDir, GdmServAuthDir);
1769
 
                g_free (GdmLogDir);
1770
 
                GdmLogDir = g_strdup (GdmServAuthDir);
1771
 
        }
1772
 
}
1773
 
 
1774
 
static void
1775
 
check_servauthdir (struct stat *statbuf)
1776
 
{
1777
 
    int r;
1778
 
 
1779
 
    /* Enter paranoia mode */
1780
 
    VE_IGNORE_EINTR (r = g_stat (GdmServAuthDir, statbuf));
1781
 
    if G_UNLIKELY (r < 0) {
1782
 
            if (GdmConsoleNotify) {
1783
 
               gchar *s = g_strdup_printf
1784
 
                       (C_(N_("Server Authorization directory "
1785
 
                              "(daemon/ServAuthDir) is set to %s "
1786
 
                              "but this does not exist. Please "
1787
 
                              "correct GDM configuration and "
1788
 
                              "restart GDM.")), GdmServAuthDir);
1789
 
 
1790
 
               gdm_text_message_dialog (s);
1791
 
               g_free (s);
1792
 
            }
1793
 
 
1794
 
            GdmPidFile = NULL;
1795
 
            gdm_fail (_("%s: Authdir %s does not exist. Aborting."), "gdm_config_parse", GdmServAuthDir);
1796
 
    }
1797
 
 
1798
 
    if G_UNLIKELY (! S_ISDIR (statbuf->st_mode)) {
1799
 
            if (GdmConsoleNotify) {
1800
 
               gchar *s = g_strdup_printf
1801
 
                       (C_(N_("Server Authorization directory "
1802
 
                              "(daemon/ServAuthDir) is set to %s "
1803
 
                              "but this is not a directory. Please "
1804
 
                              "correct GDM configuration and "
1805
 
                              "restart GDM.")), GdmServAuthDir);
1806
 
 
1807
 
                gdm_text_message_dialog (s);
1808
 
                g_free (s);
1809
 
            }
1810
 
 
1811
 
            GdmPidFile = NULL;
1812
 
            gdm_fail (_("%s: Authdir %s is not a directory. Aborting."), "gdm_config_parse", GdmServAuthDir);
1813
 
    }
1814
 
}
1815
 
 
1816
 
typedef struct _GdmConfigFiles {
1817
 
   VeConfig *cfg;
1818
 
   VeConfig *custom_cfg;
1819
 
} GdmConfigFiles;
1820
 
 
1821
 
/**
1822
 
 * gdm_load_displays
1823
 
 *
1824
 
 * Load the displays section of the config file
1825
 
 */
1826
 
static void
1827
 
gdm_load_displays (VeConfig *cfg, GList *list )
1828
 
{
1829
 
   GList *li;
1830
 
   GSList *li2;
1831
 
 
1832
 
   for (li = list; li != NULL; li = li->next) {
1833
 
      const gchar *key = li->data;
1834
 
 
1835
 
      if (isdigit (*key)) {
1836
 
         gchar *fullkey;
1837
 
         gchar *dispval;
1838
 
         int keynum = atoi (key);
1839
 
         gboolean skip_entry = FALSE;
1840
 
 
1841
 
         fullkey  = g_strdup_printf ("%s/%s", GDM_KEY_SECTION_SERVERS, key);
1842
 
         dispval  = ve_config_get_string (cfg, fullkey);
1843
 
         g_free (fullkey);
1844
 
 
1845
 
         /* Do not add if already in the list */
1846
 
         for (li2 = displays; li2 != NULL; li2 = li2->next) {
1847
 
            GdmDisplay *disp = li2->data;
1848
 
            if (disp->dispnum == keynum) {
1849
 
               skip_entry = TRUE;
1850
 
               break;
1851
 
            }
1852
 
         }
1853
 
 
1854
 
         /* Do not add if this display was marked as inactive already */
1855
 
         for (li2 = displays_inactive; li2 != NULL; li2 = li2->next) {
1856
 
            gchar *disp = li2->data;
1857
 
            if (atoi (disp) == keynum) {
1858
 
               skip_entry = TRUE;
1859
 
               break;
1860
 
            }
1861
 
         }
1862
 
 
1863
 
         if (skip_entry == TRUE) {
1864
 
            g_free (dispval);
1865
 
            continue;
1866
 
         }
1867
 
 
1868
 
         if (g_ascii_strcasecmp (ve_sure_string (dispval), "inactive") == 0) {
1869
 
            gdm_debug ("display %s is inactive", key);
1870
 
            displays_inactive = g_slist_append (displays_inactive, g_strdup (key));
1871
 
         } else {
1872
 
            GdmDisplay *disp = gdm_server_alloc (keynum, dispval);
1873
 
 
1874
 
            if (disp == NULL)
1875
 
               continue;
1876
 
 
1877
 
            displays = g_slist_insert_sorted (displays, disp, gdm_compare_displays);
1878
 
            if (keynum > high_display_num)
1879
 
               high_display_num = keynum;
1880
 
         }
1881
 
 
1882
 
         g_free (dispval);
1883
 
 
1884
 
      } else {
1885
 
        gdm_info (_("%s: Invalid server line in config file. Ignoring!"), "gdm_config_parse");
1886
 
      }
1887
 
   }
1888
 
}
1889
 
 
1890
 
/**
1891
 
 * gdm_load_config_option
1892
 
 *
1893
 
 * Called by gdm_config_parse in a loop to set each key.
1894
 
 */
1895
 
static void
1896
 
gdm_load_config_option (gpointer key_in, gpointer value_in, gpointer data)
1897
 
{
1898
 
   gchar *key               = (gchar *)key_in;
1899
 
   GdmConfigType *type      = (GdmConfigType *)value_in;
1900
 
   GdmConfigFiles *cfgfiles = (GdmConfigFiles *)data;
1901
 
   gboolean custom_retval;
1902
 
 
1903
 
   if (type != NULL) {
1904
 
      /* First check the custom file */
1905
 
      if (cfgfiles->custom_cfg != NULL) {
1906
 
          gchar **splitstr = g_strsplit (key_in, "/", 2);
1907
 
          if (splitstr[0] != NULL) {
1908
 
             GList *list = ve_config_get_keys (cfgfiles->custom_cfg, splitstr[0]);
1909
 
 
1910
 
             while (list != NULL) {
1911
 
                gchar *custom_key     = (char *)list->data;
1912
 
                gchar *custom_fullkey = g_strdup_printf ("%s/%s", splitstr[0], custom_key);
1913
 
 
1914
 
                if (is_key (key_in, custom_fullkey)) {
1915
 
                   custom_retval = gdm_set_value (cfgfiles->custom_cfg, type, key, FALSE);
1916
 
                   g_free (custom_fullkey);
1917
 
                   g_strfreev (splitstr);
1918
 
                   return;
1919
 
                }
1920
 
 
1921
 
                g_free (custom_fullkey);
1922
 
                list = list->next;
1923
 
             }
1924
 
          }
1925
 
          g_strfreev (splitstr);
1926
 
      }
1927
 
 
1928
 
      /* If not in the custom file, check main config file */
1929
 
      if (gdm_set_value (cfgfiles->cfg, type, key, FALSE))
1930
 
         return;
1931
 
   }
1932
 
 
1933
 
   gdm_error ("Cannot set config option %s", key); 
1934
 
}
1935
 
 
1936
 
/**
1937
 
 * gdm_config_parse
1938
 
 *
1939
 
 * Loads initial configuration settings.
1940
 
 */
1941
 
void
1942
 
gdm_config_parse (void)
1943
 
{
1944
 
   GdmConfigFiles cfgfiles;
1945
 
   VeConfig *cfg, *custom_cfg;
1946
 
   struct passwd *pwent;
1947
 
   struct group *grent;
1948
 
   struct stat statbuf;
1949
 
   gchar *bin;
1950
 
 
1951
 
   /* Init structures for configuration data */
1952
 
   gdm_config_init ();
1953
 
 
1954
 
   displays          = NULL;
1955
 
   high_display_num  = 0;
1956
 
 
1957
 
   /*
1958
 
    * It is okay if the custom_cfg file is missing, then just use
1959
 
    * main configuration file.  If cfg is missing, then GDM will 
1960
 
    * use the built-in defaults found in gdm.h.
1961
 
    */
1962
 
   cfg                      = gdm_get_default_config (&statbuf);
1963
 
   config_file_mtime        = statbuf.st_mtime;
1964
 
   custom_cfg               = gdm_get_custom_config (&statbuf);
1965
 
   custom_config_file_mtime = statbuf.st_mtime;
1966
 
   cfgfiles.cfg             = cfg;
1967
 
   cfgfiles.custom_cfg      = custom_cfg;
1968
 
 
1969
 
   /* Loop over all configuration options and load them */
1970
 
   g_hash_table_foreach (type_hash, gdm_load_config_option, &cfgfiles);
1971
 
 
1972
 
   /* Load server-foo sections */
1973
 
   gdm_update_xservers (cfg, custom_cfg);
1974
 
 
1975
 
   /* Only read the list if no_console is FALSE at this stage */
1976
 
   if ( !no_console) {
1977
 
      GList *list;
1978
 
      GSList *li2;
1979
 
 
1980
 
      /* Find static X server definitions */
1981
 
      if (custom_cfg) {
1982
 
         list = ve_config_get_keys (custom_cfg, GDM_KEY_SECTION_SERVERS);
1983
 
         gdm_load_displays (custom_cfg, list);
1984
 
         ve_config_free_list_of_strings (list);
1985
 
      }
1986
 
 
1987
 
      list = ve_config_get_keys (cfg, GDM_KEY_SECTION_SERVERS);
1988
 
      gdm_load_displays (cfg, list);
1989
 
      ve_config_free_list_of_strings (list);
1990
 
 
1991
 
      /* Free list of inactive, not needed anymore */
1992
 
      for (li2 = displays_inactive; li2 != NULL; li2 = li2->next) {
1993
 
         gchar *disp = li2->data;
1994
 
         g_free (disp);
1995
 
      }
1996
 
      g_slist_free (displays_inactive);
1997
 
   }
1998
 
 
1999
 
   if G_UNLIKELY ((displays == NULL) && (! GdmXdmcp) && (!GdmDynamicXservers)) {
2000
 
      gchar *server = NULL;
2001
 
 
2002
 
      /*
2003
 
       * If we requested no static servers (there is no console),
2004
 
       * then don't display errors in console messages
2005
 
       */
2006
 
      if (no_console) {
2007
 
         gdm_fail (_("%s: XDMCP disabled and no static servers defined. Aborting!"), "gdm_config_parse");
2008
 
      }
2009
 
 
2010
 
      bin = ve_first_word (GdmStandardXserver);
2011
 
      if G_LIKELY (g_access (bin, X_OK) == 0) {
2012
 
         server = GdmStandardXserver;
2013
 
      } else if (g_access ("/usr/bin/X11/X", X_OK) == 0) {
2014
 
         server = "/usr/bin/X11/X";
2015
 
      } else if (g_access ("/usr/X11R6/bin/X", X_OK) == 0) {
2016
 
         server = "/usr/X11R6/bin/X";
2017
 
      } else if (g_access ("/opt/X11R6/bin/X", X_OK) == 0) {
2018
 
         server = "/opt/X11R6/bin/X";
2019
 
      }
2020
 
      g_free (bin);
2021
 
 
2022
 
      /* yay, we can add a backup emergency server */
2023
 
      if (server != NULL) {
2024
 
         int num = gdm_get_free_display (0 /* start */, 0 /* server uid */);
2025
 
         gdm_error (_("%s: XDMCP disabled and no static servers defined. Adding %s on :%d to allow configuration!"),
2026
 
                      "gdm_config_parse", server, num);
2027
 
 
2028
 
         gdm_emergency_server = TRUE;
2029
 
         displays = g_slist_append (displays, gdm_server_alloc (num, server));
2030
 
         /* ALWAYS run the greeter and don't log anyone in,
2031
 
          * this is just an emergency session */
2032
 
         g_free (GdmAutomaticLogin);
2033
 
         g_free (GdmTimedLogin);
2034
 
         GdmAutomaticLogin = NULL;
2035
 
         GdmTimedLogin     = NULL;
2036
 
      } else {
2037
 
         if (GdmConsoleNotify) {
2038
 
            gchar *s = g_strdup_printf (C_(N_("XDMCP is disabled and GDM "
2039
 
                                      "cannot find any static server "
2040
 
                                      "to start.  Aborting!  Please "
2041
 
                                      "correct the configuration "
2042
 
                                      "and restart GDM.")));
2043
 
            gdm_text_message_dialog (s);
2044
 
            g_free (s);
2045
 
         }
2046
 
 
2047
 
         GdmPidFile = NULL;
2048
 
         gdm_fail (_("%s: XDMCP disabled and no static servers defined. Aborting!"), "gdm_config_parse");
2049
 
      }
2050
 
   }
2051
 
 
2052
 
   /* If no displays were found, then obviously
2053
 
      we're in a no console mode */
2054
 
   if (displays == NULL)
2055
 
      no_console = TRUE;
2056
 
 
2057
 
   if (no_console)
2058
 
      GdmConsoleNotify = FALSE;
2059
 
 
2060
 
   /* Lookup user and groupid for the GDM user */
2061
 
   pwent = getpwnam (GdmUser);
2062
 
 
2063
 
   /* Set GdmUserId and GdmGroupId */
2064
 
   if G_UNLIKELY (pwent == NULL) {
2065
 
 
2066
 
      if (GdmConsoleNotify) {
2067
 
         gchar *s = g_strdup_printf (C_(N_("The GDM user '%s' does not exist. "
2068
 
                                           "Please correct GDM configuration "
2069
 
                                           "and restart GDM.")), GdmUser);
2070
 
         gdm_text_message_dialog (s);
2071
 
         g_free (s);
2072
 
      }
2073
 
 
2074
 
      GdmPidFile = NULL;
2075
 
      gdm_fail (_("%s: Can't find the GDM user '%s'. Aborting!"), "gdm_config_parse", GdmUser);
2076
 
   } else {
2077
 
      GdmUserId = pwent->pw_uid;
2078
 
   }
2079
 
 
2080
 
   if G_UNLIKELY (GdmUserId == 0) {
2081
 
      if (GdmConsoleNotify) {
2082
 
         gchar *s = g_strdup_printf (C_(N_("The GDM user is set to be root, but "
2083
 
                                           "this is not allowed since it can "
2084
 
                                           "pose a security risk.  Please "
2085
 
                                           "correct GDM configuration and "
2086
 
                                           "restart GDM.")));
2087
 
 
2088
 
         gdm_text_message_dialog (s);
2089
 
         g_free (s);
2090
 
      }
2091
 
 
2092
 
      GdmPidFile = NULL;
2093
 
      gdm_fail (_("%s: The GDM user should not be root. Aborting!"), "gdm_config_parse");
2094
 
   }
2095
 
 
2096
 
   grent = getgrnam (GdmGroup);
2097
 
 
2098
 
   if G_UNLIKELY (grent == NULL) {
2099
 
      if (GdmConsoleNotify) {
2100
 
         gchar *s = g_strdup_printf (C_(N_("The GDM group '%s' does not exist. "
2101
 
                                           "Please correct GDM configuration "
2102
 
                                           "and restart GDM.")), GdmGroup);
2103
 
         gdm_text_message_dialog (s);
2104
 
         g_free (s);
2105
 
      }
2106
 
 
2107
 
      GdmPidFile = NULL;
2108
 
      gdm_fail (_("%s: Can't find the GDM group '%s'. Aborting!"), "gdm_config_parse", GdmGroup);
2109
 
   } else  {
2110
 
      GdmGroupId = grent->gr_gid;   
2111
 
   }
2112
 
 
2113
 
   if G_UNLIKELY (GdmGroupId == 0) {
2114
 
      if (GdmConsoleNotify) {
2115
 
         gchar *s = g_strdup_printf (C_(N_("The GDM group is set to be root, but "
2116
 
                                           "this is not allowed since it can "
2117
 
                                           "pose a security risk. Please "
2118
 
                                           "correct GDM configuration and "
2119
 
                                           "restart GDM.")));
2120
 
         gdm_text_message_dialog (s);
2121
 
         g_free (s);
2122
 
      }
2123
 
 
2124
 
      GdmPidFile = NULL;
2125
 
      gdm_fail (_("%s: The GDM group should not be root. Aborting!"), "gdm_config_parse");
2126
 
   }
2127
 
 
2128
 
   /* gid remains `gdm' */
2129
 
   NEVER_FAILS_root_set_euid_egid (GdmUserId, GdmGroupId);
2130
 
 
2131
 
   /* Check that the greeter can be executed */
2132
 
   bin = ve_first_word (GdmGreeter);
2133
 
   if G_UNLIKELY (ve_string_empty (bin) || g_access (bin, X_OK) != 0) {
2134
 
      gdm_error (_("%s: Greeter not found or can't be executed by the GDM user"), "gdm_config_parse");
2135
 
   }
2136
 
   g_free (bin);
2137
 
 
2138
 
   bin = ve_first_word (GdmRemoteGreeter);
2139
 
   if G_UNLIKELY (ve_string_empty (bin) || g_access (bin, X_OK) != 0) {
2140
 
      gdm_error (_("%s: Remote greeter not found or can't be executed by the GDM user"), "gdm_config_parse");
2141
 
   }
2142
 
   g_free (bin);
2143
 
 
2144
 
   /* Check that chooser can be executed */
2145
 
   bin = ve_first_word (GdmChooser);
2146
 
 
2147
 
   if G_UNLIKELY (GdmIndirect && (ve_string_empty (bin) || g_access (bin, X_OK) != 0)) {
2148
 
      gdm_error (_("%s: Chooser not found or it can't be executed by the GDM user"), "gdm_config_parse");
2149
 
   }
2150
 
    
2151
 
   g_free (bin);
2152
 
 
2153
 
   /* Check the serv auth and log dirs */
2154
 
   if G_UNLIKELY (ve_string_empty (GdmServAuthDir)) {
2155
 
       if (GdmConsoleNotify) {
2156
 
          gdm_text_message_dialog
2157
 
             (C_(N_("No daemon/ServAuthDir specified in the GDM configuration file")));
2158
 
       }
2159
 
       GdmPidFile = NULL;
2160
 
       gdm_fail (_("%s: No daemon/ServAuthDir specified."), "gdm_config_parse");
2161
 
   }
2162
 
 
2163
 
   if (ve_string_empty (GdmLogDir)) {
2164
 
      g_free (GdmLogDir);
2165
 
      GdmLogDir = g_strdup (GdmServAuthDir);
2166
 
   }
2167
 
 
2168
 
   /* Enter paranoia mode */
2169
 
   check_servauthdir (&statbuf);
2170
 
 
2171
 
   NEVER_FAILS_root_set_euid_egid (0, 0);
2172
 
 
2173
 
   /* Now set things up for us as  */
2174
 
   chown (GdmServAuthDir, 0, GdmGroupId);
2175
 
   g_chmod (GdmServAuthDir, (S_IRWXU|S_IRWXG|S_ISVTX));
2176
 
 
2177
 
   NEVER_FAILS_root_set_euid_egid (GdmUserId, GdmGroupId);
2178
 
 
2179
 
   /* Again paranoid */
2180
 
   check_servauthdir (&statbuf);
2181
 
 
2182
 
   if G_UNLIKELY (statbuf.st_uid != 0 || statbuf.st_gid != GdmGroupId)  {
2183
 
      if (GdmConsoleNotify) {
2184
 
         gchar *s = g_strdup_printf (C_(N_("Server Authorization directory "
2185
 
                                           "(daemon/ServAuthDir) is set to %s "
2186
 
                                           "but is not owned by user %s and group "
2187
 
                                           "%s. Please correct the ownership or "
2188
 
                                           "GDM configuration and restart "
2189
 
                                           "GDM.")), GdmServAuthDir,
2190
 
                                        gdm_root_user (), GdmGroup);
2191
 
         gdm_text_message_dialog (s);
2192
 
         g_free (s);
2193
 
      }
2194
 
 
2195
 
      GdmPidFile = NULL;
2196
 
      gdm_fail (_("%s: Authdir %s is not owned by user %s, group %s. Aborting."),
2197
 
                     "gdm_config_parse", GdmServAuthDir, gdm_root_user (), GdmGroup);
2198
 
   }
2199
 
 
2200
 
   if G_UNLIKELY (statbuf.st_mode != (S_IFDIR|S_IRWXU|S_IRWXG|S_ISVTX))  {
2201
 
      if (GdmConsoleNotify) {
2202
 
         gchar *s = g_strdup_printf (C_(N_("Server Authorization directory "
2203
 
                                    "(daemon/ServAuthDir) is set to %s "
2204
 
                                    "but has the wrong permissions: it "
2205
 
                                    "should have permissions of %o. "
2206
 
                                    "Please correct the permissions or "
2207
 
                                    "the GDM configuration and "
2208
 
                                    "restart GDM.")), GdmServAuthDir,
2209
 
                                    (S_IRWXU|S_IRWXG|S_ISVTX));
2210
 
         gdm_text_message_dialog (s);
2211
 
         g_free (s);
2212
 
      }
2213
 
 
2214
 
      GdmPidFile = NULL;
2215
 
      gdm_fail (_("%s: Authdir %s has wrong permissions %o. Should be %o. Aborting."), "gdm_config_parse", 
2216
 
                  GdmServAuthDir, statbuf.st_mode, (S_IRWXU|S_IRWXG|S_ISVTX));
2217
 
   }
2218
 
 
2219
 
   NEVER_FAILS_root_set_euid_egid (0, 0);
2220
 
 
2221
 
   check_logdir ();
2222
 
 
2223
 
   /* Check that user authentication is properly configured */
2224
 
   gdm_verify_check ();
2225
 
 
2226
 
   if (custom_cfg)
2227
 
      ve_config_destroy (custom_cfg);
2228
 
   ve_config_destroy (cfg);
2229
 
}
2230
 
 
2231
 
/** 
2232
 
 * gdm_get_gdmuid
2233
 
 * gdm_get_gdmgid
2234
 
 *
2235
 
 * Access functions for getting the GDM user ID and group ID.
2236
 
 */
2237
 
uid_t
2238
 
gdm_get_gdmuid (void)
2239
 
{
2240
 
   return GdmUserId;
2241
 
}
2242
 
 
2243
 
gid_t
2244
 
gdm_get_gdmgid (void)
2245
 
{
2246
 
   return GdmGroupId;
2247
 
}
2248
 
 
2249
 
/** 
2250
 
 * gdm_get_high_display_num
2251
 
 * gdm_get_high_display_num
2252
 
 *
2253
 
 * Access functions for getting the high display number.
2254
 
 */
2255
 
gint
2256
 
gdm_get_high_display_num (void)
2257
 
{
2258
 
   return high_display_num;
2259
 
}
2260
 
 
2261
 
void
2262
 
gdm_set_high_display_num (gint val)
2263
 
{
2264
 
   high_display_num = val;
2265
 
}
2266
 
 
2267
 
/**
2268
 
 * gdm_is_valid_key
2269
 
 *
2270
 
 * Returns TRUE if the key is a valid key, FALSE otherwise.
2271
 
 */
2272
 
gboolean
2273
 
gdm_is_valid_key (gchar *key)
2274
 
{
2275
 
   GdmConfigType *type = gdm_config_hash_lookup (type_hash, key);
2276
 
   if (type == NULL)
2277
 
      return FALSE;
2278
 
 
2279
 
   return TRUE;
2280
 
}
2281
 
 
2282
 
/**
2283
 
 * gdm_signal_terminthup_was_notified
2284
 
 *
2285
 
 * returns TRUE if signal SIGTERM, SIGINT, or SIGHUP was received.
2286
 
 * This just hides these vicious-extensions functions from the
2287
 
 * other files
2288
 
 */
2289
 
gboolean
2290
 
gdm_signal_terminthup_was_notified (void)
2291
 
{
2292
 
   if (ve_signal_was_notified (SIGTERM) ||
2293
 
       ve_signal_was_notified (SIGINT) ||
2294
 
       ve_signal_was_notified (SIGHUP)) {
2295
 
      return TRUE;
2296
 
   } else {
2297
 
      return FALSE;
2298
 
   }
2299
 
}
2300
 
 
2301
 
/**
2302
 
 * check_user_file
2303
 
 * check_global_file
2304
 
 * is_in_trusted_pic_dir
2305
 
 * get_facefile_from_gnome2_dir_config 
2306
 
 * path_is_local
2307
 
 * gdm_get_facefile_from_home
2308
 
 * gdm_get_facefile_from_global
2309
 
 *
2310
 
 * These functions are used for accessing the user's face image from their
2311
 
 * home directory via vicious-extensions.
2312
 
 */
2313
 
static gboolean
2314
 
check_user_file (const char *path,
2315
 
                 guint       uid)
2316
 
{
2317
 
        char    *dir;
2318
 
        char    *file;
2319
 
        gboolean is_ok;
2320
 
 
2321
 
        if (path == NULL)
2322
 
                return FALSE;
2323
 
 
2324
 
        if (g_access (path, R_OK) != 0)
2325
 
                return FALSE;
2326
 
 
2327
 
        dir = g_path_get_dirname (path);
2328
 
        file = g_path_get_basename (path);
2329
 
 
2330
 
        is_ok = gdm_file_check ("run_pictures",
2331
 
                                uid,
2332
 
                                dir,
2333
 
                                file,
2334
 
                                TRUE, TRUE,
2335
 
                                gdm_get_value_int (GDM_KEY_USER_MAX_FILE),
2336
 
                                gdm_get_value_int (GDM_KEY_RELAX_PERM));
2337
 
        g_free (dir);
2338
 
        g_free (file);
2339
 
 
2340
 
        return is_ok;
2341
 
}
2342
 
 
2343
 
static gboolean
2344
 
check_global_file (const char *path,
2345
 
                   guint       uid)
2346
 
{
2347
 
        if (path == NULL)
2348
 
                return FALSE;
2349
 
 
2350
 
        if (g_access (path, R_OK) != 0)
2351
 
                return FALSE;
2352
 
 
2353
 
        return TRUE;
2354
 
}
2355
 
 
2356
 
/* If path starts with a "trusted" directory, don't sanity check things */
2357
 
/* This is really somewhat "outdated" as we now really want things in
2358
 
 * the picture dir or in ~/.gnome2/photo */
2359
 
static gboolean
2360
 
is_in_trusted_pic_dir (const char *path)
2361
 
{
2362
 
        /* our own pixmap dir is trusted */
2363
 
        if (strncmp (path, PIXMAPDIR, sizeof (PIXMAPDIR)) == 0)
2364
 
                return TRUE;
2365
 
 
2366
 
        return FALSE;
2367
 
}
2368
 
 
2369
 
static gchar *
2370
 
get_facefile_from_gnome2_dir_config (const char *homedir,
2371
 
                                     guint       uid)
2372
 
{
2373
 
   char *picfile = NULL;
2374
 
   char *cfgdir;
2375
 
 
2376
 
   /* Sanity check on ~user/.gnome2/gdm */
2377
 
   cfgdir = g_build_filename (homedir, ".gnome2", "gdm", NULL);
2378
 
   if (G_LIKELY (check_user_file (cfgdir, uid))) {
2379
 
      VeConfig *cfg;
2380
 
      char *cfgfile;
2381
 
 
2382
 
      cfgfile = g_build_filename (homedir, ".gnome2", "gdm", NULL);
2383
 
      cfg = ve_config_new (cfgfile);
2384
 
      g_free (cfgfile);
2385
 
 
2386
 
      picfile = ve_config_get_string (cfg, "face/picture=");
2387
 
      ve_config_destroy (cfg);
2388
 
 
2389
 
      /* must exist and be absolute (note that this check
2390
 
       * catches empty strings)*/
2391
 
      /* Note that these days we just set ~/.face */
2392
 
      if G_UNLIKELY (picfile != NULL &&
2393
 
                     (picfile[0] != '/' ||
2394
 
                      /* this catches readability by user */
2395
 
                      g_access (picfile, R_OK) != 0)) {
2396
 
         g_free (picfile);
2397
 
         picfile = NULL;
2398
 
      }
2399
 
 
2400
 
      if (picfile != NULL) {
2401
 
         char buf[PATH_MAX];
2402
 
         if (realpath (picfile, buf) == NULL) {
2403
 
            g_free (picfile);
2404
 
            picfile = NULL;
2405
 
         } else {
2406
 
            g_free (picfile);
2407
 
            picfile = g_strdup (buf);
2408
 
         }
2409
 
      }
2410
 
 
2411
 
      if G_UNLIKELY (picfile != NULL) {
2412
 
         if (! is_in_trusted_pic_dir (picfile)) {
2413
 
            /* if not in trusted dir, check it out */
2414
 
 
2415
 
            /* Note that strict permissions checking is done
2416
 
             * on this file.  Even if it may not even be owned by the
2417
 
             * user.  This setting should ONLY point to pics in trusted
2418
 
             * dirs. */
2419
 
            if (! check_user_file (picfile, uid)) {
2420
 
               g_free (picfile);
2421
 
               picfile = NULL;
2422
 
            }
2423
 
         }
2424
 
      }
2425
 
   }
2426
 
   g_free (cfgdir);
2427
 
 
2428
 
   return picfile;
2429
 
}
2430
 
 
2431
 
static GHashTable *fstype_hash = NULL;
2432
 
extern char *filesystem_type (char *path, char *relpath, struct stat *statp);
2433
 
 
2434
 
static gboolean
2435
 
path_is_local (const char *path)
2436
 
{
2437
 
        gpointer local = NULL;
2438
 
 
2439
 
        if (path == NULL)
2440
 
                return FALSE;
2441
 
 
2442
 
        if (fstype_hash == NULL)
2443
 
                fstype_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
2444
 
        else
2445
 
                local = g_hash_table_lookup (fstype_hash, path);
2446
 
 
2447
 
        if (local == NULL) {
2448
 
                struct stat statbuf;
2449
 
 
2450
 
                if (g_stat (path, &statbuf) == 0) {
2451
 
                        char *type = filesystem_type ((char *)path, (char *)path, &statbuf);
2452
 
                        gboolean is_local = ((strcmp (ve_sure_string (type), "nfs") != 0) &&
2453
 
                                             (strcmp (ve_sure_string (type), "afs") != 0) &&
2454
 
                                             (strcmp (ve_sure_string (type), "autofs") != 0) &&
2455
 
                                             (strcmp (ve_sure_string (type), "unknown") != 0) &&
2456
 
                                             (strcmp (ve_sure_string (type), "ncpfs") != 0));
2457
 
                        local = GINT_TO_POINTER (is_local ? 1 : -1);
2458
 
                        g_hash_table_insert (fstype_hash, g_strdup (path), local);
2459
 
                }
2460
 
        }
2461
 
 
2462
 
        return GPOINTER_TO_INT (local) > 0;
2463
 
}
2464
 
 
2465
 
gchar *
2466
 
gdm_get_facefile_from_home (const char *homedir,
2467
 
                            guint       uid)
2468
 
{
2469
 
   char    *picfile = NULL;
2470
 
   char    *path;
2471
 
   gboolean is_local;
2472
 
 
2473
 
   /* special case: look at parent of home to detect autofs
2474
 
      this is so we don't try to trigger an automount */
2475
 
   path = g_path_get_dirname (homedir);
2476
 
   is_local = path_is_local (path);
2477
 
   g_free (path);
2478
 
 
2479
 
   /* now check that home dir itself is local */
2480
 
   if (is_local) {
2481
 
      is_local = path_is_local (homedir);
2482
 
   }
2483
 
 
2484
 
   /* Only look at local home directories so we don't try to
2485
 
      read from remote (e.g. NFS) volumes */
2486
 
   if (! is_local)
2487
 
      return NULL;
2488
 
 
2489
 
   picfile = g_build_filename (homedir, ".face", NULL);
2490
 
 
2491
 
   if (check_user_file (picfile, uid))
2492
 
      return picfile;
2493
 
   else {
2494
 
      g_free (picfile);
2495
 
      picfile = NULL;
2496
 
   }
2497
 
 
2498
 
   picfile = g_build_filename (homedir, ".face.icon", NULL);
2499
 
 
2500
 
   if (check_user_file (picfile, uid))
2501
 
           return picfile;
2502
 
   else {
2503
 
      g_free (picfile);
2504
 
      picfile = NULL;
2505
 
   }
2506
 
 
2507
 
   picfile = get_facefile_from_gnome2_dir_config (homedir, uid);
2508
 
   if (check_user_file (picfile, uid))
2509
 
      return picfile;
2510
 
   else {
2511
 
      g_free (picfile);
2512
 
      picfile = NULL;
2513
 
   }
2514
 
 
2515
 
   /* Nothing found yet, try the old locations */
2516
 
 
2517
 
   picfile = g_build_filename (homedir, ".gnome2", "photo", NULL);
2518
 
   if (check_user_file (picfile, uid))
2519
 
      return picfile;
2520
 
   else {
2521
 
      g_free (picfile);
2522
 
      picfile = NULL;
2523
 
   }
2524
 
 
2525
 
   picfile = g_build_filename (homedir, ".gnome", "photo", NULL);
2526
 
   if (check_user_file (picfile, uid))
2527
 
      return picfile;
2528
 
   else {
2529
 
      g_free (picfile);
2530
 
      picfile = NULL;
2531
 
   }
2532
 
 
2533
 
   return NULL;
2534
 
}
2535
 
 
2536
 
gchar *
2537
 
gdm_get_facefile_from_global (const char *username,
2538
 
                              guint       uid)
2539
 
{
2540
 
   char *picfile = NULL;
2541
 
   char *facedir = gdm_get_value_string (GDM_KEY_GLOBAL_FACE_DIR);
2542
 
 
2543
 
   /* Try the global face directory */
2544
 
 
2545
 
   picfile = g_build_filename (facedir, username, NULL);
2546
 
 
2547
 
   if (check_global_file (picfile, uid))
2548
 
      return picfile;
2549
 
 
2550
 
   g_free (picfile);
2551
 
   picfile = gdm_make_filename (facedir, username, ".png");
2552
 
 
2553
 
   if (check_global_file (picfile, uid))
2554
 
      return picfile;
2555
 
 
2556
 
   g_free (picfile);
2557
 
   return NULL;
2558
 
}
2559
 
 
2560
 
/**
2561
 
 * gdm_get_session_exec
2562
 
 *
2563
 
 * This function accesses the GDM session desktop file, via vicious
2564
 
 * extensions and returns the execution command for starting the
2565
 
 * session.
2566
 
 */
2567
 
char *
2568
 
gdm_get_session_exec (const char *session_name, gboolean check_try_exec)
2569
 
{
2570
 
   char *file;
2571
 
   char *full = NULL;
2572
 
   VeConfig *cfg;
2573
 
   static char *exec;
2574
 
   static char *cached = NULL;
2575
 
   char *tryexec;
2576
 
 
2577
 
   /* clear cache */
2578
 
   if (session_name == NULL) {
2579
 
      g_free (exec);
2580
 
      exec = NULL;
2581
 
      g_free (cached);
2582
 
      cached = NULL;
2583
 
      return NULL;
2584
 
   }
2585
 
 
2586
 
   if (cached != NULL && strcmp (ve_sure_string (session_name), ve_sure_string (cached)) == 0)
2587
 
      return g_strdup (exec);
2588
 
 
2589
 
   g_free (exec);
2590
 
   exec = NULL;
2591
 
   g_free (cached);
2592
 
   cached = g_strdup (session_name);
2593
 
 
2594
 
   /* Some ugly special casing for legacy "Default.desktop", oh well,
2595
 
    * we changed to "default.desktop" */
2596
 
   if (g_ascii_strcasecmp (session_name, "default") == 0 ||
2597
 
       g_ascii_strcasecmp (session_name, "default.desktop") == 0) {
2598
 
      full = ve_find_prog_in_path ("default.desktop",
2599
 
         gdm_get_value_string (GDM_KEY_SESSION_DESKTOP_DIR));
2600
 
   }
2601
 
 
2602
 
   if (full == NULL) {
2603
 
      file = gdm_ensure_extension (session_name, ".desktop");
2604
 
      full = ve_find_prog_in_path (file,
2605
 
         gdm_get_value_string (GDM_KEY_SESSION_DESKTOP_DIR));
2606
 
      g_free (file);
2607
 
   }
2608
 
 
2609
 
   if (ve_string_empty (full) || g_access (full, R_OK) != 0) {
2610
 
      g_free (full);
2611
 
      if (gdm_is_session_magic (session_name)) {
2612
 
         exec = g_strdup (session_name);
2613
 
         return g_strdup (exec);
2614
 
      } else {
2615
 
         return NULL;
2616
 
      }
2617
 
   }
2618
 
 
2619
 
   cfg = ve_config_get (full);
2620
 
   g_free (full);
2621
 
   if (ve_config_get_bool (cfg, "Desktop Entry/Hidden=false"))
2622
 
      return NULL;
2623
 
 
2624
 
   if (check_try_exec) {
2625
 
      tryexec = ve_config_get_string (cfg, "Desktop Entry/TryExec");
2626
 
      if ( ! ve_string_empty (tryexec) &&
2627
 
           ! ve_is_prog_in_path (tryexec, gdm_get_value_string (GDM_KEY_PATH)) &&
2628
 
           ! ve_is_prog_in_path (tryexec, gdm_saved_getenv ("PATH"))) {
2629
 
         g_free (tryexec);
2630
 
         return NULL;
2631
 
      }
2632
 
      g_free (tryexec);
2633
 
   }
2634
 
 
2635
 
   exec = ve_config_get_string (cfg, "Desktop Entry/Exec");
2636
 
   return g_strdup (exec);
2637
 
}
2638
 
 
2639
 
/**
2640
 
 * gdm_set_user_session_lang
2641
 
 * gdm_get_user_session_lang
2642
 
 *
2643
 
 * These functions get and set the user's language and setting in their
2644
 
 * $HOME/.dmrc file via vicious-extensions.
2645
 
 */
2646
 
void
2647
 
gdm_set_user_session_lang (gboolean savesess, gboolean savelang,
2648
 
    const char *home_dir, const char *save_session, const char *save_language)
2649
 
{
2650
 
   VeConfig *dmrc = NULL;
2651
 
   gchar *cfgstr = g_build_filename (home_dir, ".dmrc", NULL);
2652
 
 
2653
 
   if (savesess) {
2654
 
      dmrc = ve_config_new (cfgstr);
2655
 
      ve_config_set_string (dmrc, "Desktop/Session",
2656
 
         ve_sure_string (save_session));
2657
 
   }
2658
 
 
2659
 
   if (savelang) {
2660
 
      if (dmrc == NULL)
2661
 
         dmrc = ve_config_new (cfgstr);
2662
 
      if (ve_string_empty (save_language))
2663
 
         /* we chose the system default language so wipe the
2664
 
          * lang key */
2665
 
         ve_config_delete_key (dmrc, "Desktop/Language");
2666
 
      else
2667
 
         ve_config_set_string (dmrc, "Desktop/Language", save_language);
2668
 
   }
2669
 
 
2670
 
   g_free (cfgstr);
2671
 
 
2672
 
   if (dmrc != NULL) {
2673
 
      mode_t oldmode;
2674
 
      oldmode = umask (077);
2675
 
      ve_config_save (dmrc, FALSE);
2676
 
      ve_config_destroy (dmrc);
2677
 
      dmrc = NULL;
2678
 
      umask (oldmode);
2679
 
   }
2680
 
}
2681
 
 
2682
 
void
2683
 
gdm_get_user_session_lang (char **usrsess, char **usrlang,
2684
 
   const char *home_dir, gboolean *savesess)
2685
 
{
2686
 
   char *p;
2687
 
   char *cfgfile = g_build_filename (home_dir, ".dmrc", NULL);
2688
 
   VeConfig *cfg = ve_config_new (cfgfile);
2689
 
   g_free (cfgfile);
2690
 
 
2691
 
   *usrsess = ve_config_get_string (cfg, "Desktop/Session");
2692
 
   if (*usrsess == NULL)
2693
 
      *usrsess = g_strdup ("");
2694
 
 
2695
 
   /* this is just being truly anal about what users give us, and in case
2696
 
    * it looks like they may have included a path whack it. */
2697
 
   p = strrchr (*usrsess, '/');
2698
 
   if (p != NULL) {
2699
 
      char *tmp = g_strdup (p+1);
2700
 
      g_free (*usrsess);
2701
 
      *usrsess = tmp;
2702
 
   }
2703
 
 
2704
 
   /* ugly workaround for migration */
2705
 
   if ((strcmp (ve_sure_string (*usrsess), "Default.desktop") == 0 ||
2706
 
        strcmp (ve_sure_string (*usrsess), "Default") == 0) &&
2707
 
       ! ve_is_prog_in_path ("Default.desktop",
2708
 
            gdm_get_value_string (GDM_KEY_SESSION_DESKTOP_DIR))) {
2709
 
           g_free (*usrsess);
2710
 
           *usrsess = g_strdup ("default");
2711
 
           *savesess = TRUE;
2712
 
   }
2713
 
 
2714
 
   *usrlang = ve_config_get_string (cfg, "Desktop/Language");
2715
 
   if (*usrlang == NULL)
2716
 
           *usrlang = g_strdup ("");
2717
 
 
2718
 
   ve_config_destroy (cfg);
2719
 
}
2720