Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtlogin / resource.c
1 /* $TOG: resource.c /main/7 1997/03/14 13:45:09 barstow $ */
2 /* (c) Copyright 1997 The Open Group */
3 /*                                                                      *
4  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
5  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
6  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
7  * (c) Copyright 1993, 1994 Novell, Inc.                                *
8  */
9 /*
10  * xdm - display manager daemon
11  *
12  * Copyright 1988 Massachusetts Institute of Technology
13  *
14  * Permission to use, copy, modify, and distribute this software and its
15  * documentation for any purpose and without fee is hereby granted, provided
16  * that the above copyright notice appear in all copies and that both that
17  * copyright notice and this permission notice appear in supporting
18  * documentation, and that the name of M.I.T. not be used in advertising or
19  * publicity pertaining to distribution of the software without specific,
20  * written prior permission.  M.I.T. makes no representations about the
21  * suitability of this software for any purpose.  It is provided "as is"
22  * without express or implied warranty.
23  *
24  * Author:  Keith Packard, MIT X Consortium
25  */
26
27 /*
28  * resource.c
29  */
30
31 # include "dm.h"
32 # include "vgmsg.h"
33 # include <X11/Xresource.h>
34 # include <X11/Xmu/CharSet.h>
35 # include <string.h>
36
37
38   void CleanUpName( char *src, char *dst, int len) ;
39   static char * getFullFileName(char *name, int special, char * lang);
40   extern char * qualifyWithFirst(char *, char *);
41
42 /* XtOffset() hack for ibmrt BandAidCompiler */
43
44 int session_set = False;
45 char    *config;
46
47 char    *servers;
48 int     request_port;
49 int     debugLevel;
50 char    *errorLogFile;
51 int     errorLogSize;
52 int     daemonMode;
53 char    *pidFile;
54 int     lockPidFile;
55 char    *authDir;
56 int     autoRescan;
57 int     removeDomainname;
58 char    *keyFile;
59 char    *accessFile;
60 char    **exportList;    /* List of all export env vars */
61 char    *sysParmsFile;
62 char    *timeZone;
63 char    *fpHead = NULL;
64 char    *fpTail = NULL;
65 int     wakeupInterval;
66 int     langListTimeout;
67 #ifdef DEF_NETWORK_DEV
68 char    *networkDev;
69 #endif
70 #if defined(__osf__)
71 char    *ignoreLocales;
72 #endif
73
74 /*
75  * Dtlogin will accept both Dtlogin and XDM resources. The string variable
76  * "AppName" contains the proper application name to use in looking up
77  * resources.
78  */
79
80 # define DISPLAYMANAGER     "DisplayManager"
81 # define DTLOGIN            "Dtlogin"
82
83 static  char    AppName[16] = DTLOGIN;
84
85
86 # define DM_STRING      0
87 # define DM_INT         1
88 # define DM_BOOL        2
89 # define DM_ARGV        3
90
91 #ifdef BLS
92 #  define DEF_XDM_CONFIG CDE_INSTALLATION_TOP "/lib/X11/Dtlogin/Xconfig"
93 #  define DEF_AUTH_DIR   CDE_INSTALLATION_TOP "/lib/X11/Dtlogin"
94 #  define DEF_KEY_FILE   CDE_INSTALLATION_TOP "/lib/X11/Dtlogin/Xkeys"
95 #endif
96
97
98 /*
99  * the following constants are supposed to be set in the makefile from
100  * parameters set util/imake.includes/site.def (or *.macros in that directory
101  * if it is server-specific).  DO NOT CHANGE THESE DEFINITIONS!
102  */
103 #ifndef DEF_SERVER_LINE 
104 #  ifdef sun 
105 #define DEF_SERVER_LINE ":0 local /usr/openwin/bin/X :0"
106 #  else
107 #define DEF_SERVER_LINE ":0 local /usr/bin/X11/X :0"
108 #  endif /* sun */
109 #endif
110 #ifndef XRDB_PROGRAM
111 #  ifdef sun 
112 #define XRDB_PROGRAM "/usr/openwin/bin/xrdb"
113 #  else
114 #define XRDB_PROGRAM "/usr/bin/X11/xrdb"
115 #  endif /* sun */
116 #endif
117 #ifndef DEF_SESSION
118 #define DEF_SESSION CDE_INSTALLATION_TOP "/bin/Xsession"
119 #endif
120
121 #ifndef DEF_USER_PATH
122 #  ifdef sun 
123 #    define DEF_USER_PATH "/usr/openwin/bin:/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin:."
124 #  else
125 #    define DEF_USER_PATH "/usr/bin/X11:/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin"
126 #  endif /* sun */
127 #endif
128
129 #ifndef DEF_SYSTEM_PATH
130 #  ifdef sun 
131 #    define DEF_SYSTEM_PATH "/usr/openwin/bin:/etc:/bin:/usr/bin"
132 #  else
133 #    define DEF_SYSTEM_PATH "/usr/bin/X11:/etc:/bin:/usr/bin"
134 #  endif /* sun */
135 #endif
136
137 #ifndef DEF_SYSTEM_SHELL
138 #define DEF_SYSTEM_SHELL "/bin/sh"
139 #endif
140
141 #ifndef DEF_FAILSAFE_CLIENT
142 #  ifdef sun 
143 #define DEF_FAILSAFE_CLIENT "/usr/openwin/bin/xterm"
144 #  else
145 #define DEF_FAILSAFE_CLIENT "/usr/bin/X11/xterm"
146 #  endif /* sun */
147 #endif
148
149 #ifndef DEF_XDM_CONFIG
150 #define DEF_XDM_CONFIG "Xconfig"
151 #endif
152
153 #ifndef DEF_CHOOSER
154 #define DEF_CHOOSER CDE_INSTALLATION_TOP "/bin/chooser"
155 #endif
156
157 #ifndef CPP_PROGRAM
158 #define CPP_PROGRAM "/lib/cpp"
159 #endif
160 #ifndef DEF_XDM_AUTH_GEN
161 #define DEF_XDM_AUTH_GEN CDE_CONFIGURATION_TOP "/xdmauthgen"
162 #endif
163 #ifndef DEF_AUTH_NAME
164 #define DEF_AUTH_NAME   "MIT-MAGIC-COOKIE-1"
165 #endif
166 #ifndef DEF_AUTH_DIR
167 #define DEF_AUTH_DIR CDE_CONFIGURATION_TOP
168 #endif
169 #ifndef DEF_USER_AUTH_DIR
170 #define DEF_USER_AUTH_DIR       "/tmp"
171 #endif
172 #ifndef DEF_KEY_FILE
173 #define DEF_KEY_FILE    CDE_CONFIGURATION_TOP "/Xkeys"
174 #endif
175 #ifndef DEF_ACCESS_FILE
176 #define DEF_ACCESS_FILE ""
177 #endif
178 #ifndef DEF_TIMEZONE
179 #define DEF_TIMEZONE    "MST7MDT"
180 #endif
181 #ifndef DEF_SYS_PARMS_FILE
182 #  if defined( __hpux )
183 #    define DEF_SYS_PARMS_FILE  "/etc/src.sh"
184 #  else
185 #    define DEF_SYS_PARMS_FILE  "/etc/TIMEZONE"
186 #  endif
187 #endif
188 #define DEF_UDP_PORT    "177"       /* registered XDMCP port, don't change */
189
190 #ifndef DEF_ENV
191 #  ifdef sun    /* need to set the environment for Sun OpenWindows */
192 #    define DEF_ENV     "OPENWINHOME=/usr/openwin"
193 #  else
194 #    define DEF_ENV     ""
195 #  endif
196 #endif
197
198 #ifndef DEF_LANG        /* LANG default settings for various architectures */
199 #  ifdef __apollo
200 #    define DEF_LANG    "C"
201 #  endif
202 #  ifdef __osf__
203 #    define DEF_LANG    "C"
204 #  endif
205 #  ifdef __hp_osf
206 #    define DEF_LANG    "en_US.88591"
207 #  endif
208 #  ifdef sun    /* default language under Solaris */
209 #    define DEF_LANG    "C" 
210 #  endif
211 #endif
212
213 #ifndef DEF_LANG        /* set LANG to NULL if not already defined         */
214 #define DEF_LANG        ""
215 #endif
216
217 struct dmResources {
218         char    *name, *class;
219         int     type;
220         char    **dm_value;
221         char    *default_value;
222 } DmResources[] = {
223 "servers",      "Servers",      DM_STRING,      &servers,
224                                 DEF_SERVER_LINE,
225 "requestPort",  "RequestPort",  DM_INT,         (char **) &request_port,
226                                 DEF_UDP_PORT,
227 "debugLevel",   "DebugLevel",   DM_INT,         (char **) &debugLevel,
228                                 "0",
229 "errorLogFile", "ErrorLogFile", DM_STRING,      &errorLogFile,
230                                 "",
231 "errorLogSize", "ErrorLogSize", DM_INT,         (char **) &errorLogSize,
232                                 "50",
233 "daemonMode",   "DaemonMode",   DM_BOOL,        (char **) &daemonMode,
234                                 "false",
235 "pidFile",      "PidFile",      DM_STRING,      &pidFile,
236                                 "",
237 "lockPidFile",  "LockPidFile",  DM_BOOL,        (char **) &lockPidFile,
238                                 "true",
239 "authDir",      "AuthDir",      DM_STRING,      &authDir,
240                                 DEF_AUTH_DIR,
241 "autoRescan",   "AutoRescan",   DM_BOOL,        (char **) &autoRescan,
242                                 "true",
243 "removeDomainname","RemoveDomainname",DM_BOOL,  (char **) &removeDomainname,
244                                 "true",
245 "keyFile",      "KeyFile",      DM_STRING,      &keyFile,
246                                 DEF_KEY_FILE,
247 "accessFile",   "AccessFile",   DM_STRING,      &accessFile,
248                                 DEF_ACCESS_FILE,
249 /* exportList env var resource    RK   08.17.93  */
250 "exportList",   "ExportList",   DM_ARGV,        (char **) &exportList,
251                                 "",
252 "timeZone",     "TimeZone",     DM_STRING,      &timeZone,
253                                 "",
254 "fontPathHead", "FontPathHead", DM_STRING,      &fpHead,
255                                 "",
256 "fontPathTail", "FontPathTail", DM_STRING,      &fpTail,
257                                 "",
258 "sysParmsFile", "SysParmsFile", DM_STRING,      &sysParmsFile,
259                                 DEF_SYS_PARMS_FILE,
260 "wakeupInterval","WakeupInterval",DM_INT,       (char **) &wakeupInterval,
261                                 "10",
262 "langListTimeout","langListTimeout",DM_INT,     (char **) &langListTimeout,
263                                 "30",
264 #ifdef DEF_NETWORK_DEV
265 "networkDevice","NetworkDevice",DM_STRING,      &networkDev,
266                                 DEF_NETWORK_DEV,
267 #endif
268 #if defined(__osf__)
269 "ignoreLocales", "IgnoreLocales", DM_STRING,    &ignoreLocales,
270                                 "",
271 #endif
272 };
273
274 # define NUM_DM_RESOURCES       (sizeof DmResources / sizeof DmResources[0])
275
276 # define boffset(f)     ((char *) &(((struct display *) 0)->f) - (char *) 0)
277
278 struct displayResources {
279         char    *name, *class;
280         int     type;
281         int     offset;
282         char    *default_value;
283 } DisplayResources[] = {
284
285
286 /* 
287  * resources for managing the server...
288  */
289  
290 "serverAttempts","ServerAttempts", DM_INT,      boffset(serverAttempts),
291                                 "1",
292 "openDelay",    "OpenDelay",    DM_INT,         boffset(openDelay),
293                                 "5",
294 "openRepeat",   "OpenRepeat",   DM_INT,         boffset(openRepeat),
295                                 "5",
296 "openTimeout",  "OpenTimeout",  DM_INT,         boffset(openTimeout),
297                                 "30",
298 "startAttempts","StartAttempts",DM_INT,         boffset(startAttempts),
299                                 "4",
300 "pingInterval", "PingInterval", DM_INT,         boffset(pingInterval),
301                                 "5",
302 "pingTimeout",  "PingTimeout",  DM_INT,         boffset(pingTimeout),
303                                 "5",
304 "terminateServer","TerminateServer",DM_BOOL,    boffset(terminateServer),
305                                 "false",
306 "grabServer",   "GrabServer",   DM_BOOL,        boffset(grabServer),
307                                 "true",
308 "grabTimeout",  "GrabTimeout",  DM_INT,         boffset(grabTimeout),
309                                 "3",
310 "resetSignal",  "Signal",       DM_INT,         boffset(resetSignal),
311                                 "1",    /* SIGHUP */
312 "termSignal",   "Signal",       DM_INT,         boffset(termSignal),
313                                 "15",   /* SIGTERM */
314 "resetForAuth", "ResetForAuth", DM_BOOL,        boffset(resetForAuth),
315                                 "false",
316 "authorize",    "Authorize",    DM_BOOL,        boffset(authorize),
317                                 "true",
318 "authName",     "AuthName",     DM_ARGV,        boffset(authNames),
319                                 DEF_AUTH_NAME,
320 "authFile",     "AuthFile",     DM_STRING,      boffset(authFile),
321                                 "",
322 #if 0
323 "gettyLine",    "GettyLine",    DM_STRING,      boffset(gettyLine),
324                                 "",
325 "gettySpeed",   "GettySpeed",   DM_STRING,      boffset(gettySpeed),
326                                 "9600",
327 #endif
328 /*
329  *  resources which control the session behavior...
330  */
331
332 "resources",    "Resources",    DM_STRING,      boffset(resources),
333                                 "",
334 "xrdb",         "Xrdb",         DM_STRING,      boffset(xrdb),
335                                 XRDB_PROGRAM,
336 "cpp",          "Cpp",          DM_STRING,      boffset(cpp),
337                                 CPP_PROGRAM,
338 "setup",        "Setup",        DM_STRING,      boffset(setup),
339                                 "",
340 "startup",      "Startup",      DM_STRING,      boffset(startup),
341                                 "",
342 "reset",        "Reset",        DM_STRING,      boffset(reset),
343                                 "",
344 "session",      "Session",      DM_STRING,      boffset(session),
345                                 DEF_SESSION,
346 "userPath",     "Path",         DM_STRING,      boffset(userPath),
347                                 DEF_USER_PATH,
348 "systemPath",   "Path",         DM_STRING,      boffset(systemPath),
349                                 DEF_SYSTEM_PATH,
350 "systemShell",  "Shell",        DM_STRING,      boffset(systemShell),
351                                 DEF_SYSTEM_SHELL,
352 "failsafeClient","FailsafeClient",      DM_STRING,      boffset(failsafeClient),
353                                 DEF_FAILSAFE_CLIENT,
354 "userAuthDir",  "UserAuthDir",  DM_STRING,      boffset(userAuthDir),
355                                 DEF_AUTH_DIR,
356 "chooser",      "Chooser",      DM_STRING,      boffset(chooser),
357                                 DEF_CHOOSER,
358 "language",     "Language",     DM_STRING,      boffset(language),
359                                 DEF_LANG,
360 "languageList", "LanguageList", DM_STRING,      boffset(langList),
361                                 "",
362 "environment",  "Environment",  DM_STRING,      boffset(environStr),
363                                 DEF_ENV,
364 "dtlite",       "Dtlite",       DM_BOOL,        boffset(dtlite),
365                                 "false",
366 "xdmMode",      "XdmMode",      DM_BOOL,        boffset(xdmMode),
367                                 "false",
368 "authenticationName","AuthenticationName", DM_STRING,   boffset(verifyName),
369                                 "",
370 "pmSearchPath", "PmSearchPath", DM_STRING,      boffset(pmSearchPath),
371                                 DEF_PM_SEARCH_PATH,
372 "bmSearchPath", "bmSearchPath", DM_STRING,      boffset(bmSearchPath), 
373                                 DEF_BM_SEARCH_PATH,
374 };
375
376 # define NUM_DISPLAY_RESOURCES  (sizeof DisplayResources/sizeof DisplayResources[0])
377
378 XrmDatabase     DmResourceDB;
379
380 int 
381 GetResource( char *name, char *class, int valueType, char **valuep,
382              char *default_value )
383 {
384     char        *type;
385     XrmValue    value;
386     char        *string, *new_string;
387     char        str_buf[50];
388     int len;
389
390
391     if (DmResourceDB && XrmGetResource (DmResourceDB,
392         name, class,
393         &type, &value))
394     {
395         string = value.addr;
396         len = value.size;
397     }
398     else
399     {
400         string = default_value;
401         len = (string == NULL ? 0 : strlen (string));
402     }
403
404     Debug ("%s/%s value %*.*s\n", name, class, len, len, string);
405
406
407     /*
408      *  check if new resource is the same as old...
409      */
410      
411      if (valueType == DM_STRING && *valuep) {
412         if (string != NULL && strlen (*valuep) == len && !strncmp (*valuep, string, len))
413             return;
414         else {
415             free (*valuep);
416             *(valuep) = NULL;
417         }
418      }
419  
420
421     switch (valueType) {
422     case DM_STRING:
423         if ( len > 0 ) {
424             new_string = malloc ((unsigned) (len+1));
425             if (!new_string) {
426                 LogOutOfMem(
427                   ReadCatalog(MC_LOG_SET,MC_LOG_GET_RSC,MC_DEF_LOG_GET_RSC));
428                 return;
429             }
430             strncpy (new_string, string, len);
431             new_string[len] = '\0';
432             *(valuep) = new_string;
433         }
434         break;
435     case DM_INT:
436         strncpy (str_buf, string, sizeof (str_buf));
437         str_buf[sizeof (str_buf)-1] = '\0';
438         *((int *) valuep) = atoi (str_buf);
439         break;
440     case DM_BOOL:
441         strncpy (str_buf, string, sizeof (str_buf));
442         str_buf[sizeof (str_buf)-1] = '\0';
443         XmuCopyISOLatin1Lowered (str_buf, str_buf);
444         if (!strcmp (str_buf, "true") ||
445             !strcmp (str_buf, "on") ||
446             !strcmp (str_buf, "yes"))
447                 *((int *) valuep) = 1;
448         else if (!strcmp (str_buf, "false") ||
449                  !strcmp (str_buf, "off") ||
450                  !strcmp (str_buf, "no"))
451                 *((int *) valuep) = 0;
452         break;
453     case DM_ARGV:
454         *((char ***) valuep) = parseArgs ((char **) 0, string);
455         break;
456
457     }
458 }
459
460 XrmOptionDescRec configTable [] = {
461 {"-server",     NULL,                   XrmoptionSkipArg,       (caddr_t) NULL },
462 {"-udpPort",    NULL,                   XrmoptionSkipArg,       (caddr_t) NULL },
463 {"-error",      NULL,                   XrmoptionSkipArg,       (caddr_t) NULL },
464 {"-resources",  NULL,                   XrmoptionSkipArg,       (caddr_t) NULL },
465 {"-session",    NULL,                   XrmoptionSkipArg,       (caddr_t) NULL },
466 {"-debug",      NULL,                   XrmoptionSkipArg,       (caddr_t) NULL },
467 {"-xrm",        NULL,                   XrmoptionSkipArg,       (caddr_t) NULL },
468 {"-config",     ".configFile",          XrmoptionSepArg,        (caddr_t) NULL }
469 };
470
471 XrmOptionDescRec optionTable [] = {
472 {"-server",     ".servers",             XrmoptionSepArg,        (caddr_t) NULL },
473 {"-udpPort",    ".requestPort",         XrmoptionSepArg,        (caddr_t) NULL },
474 {"-error",      ".errorLogFile",        XrmoptionSepArg,        (caddr_t) NULL },
475 {"-resources",  "*resources",           XrmoptionSepArg,        (caddr_t) NULL },
476 {"-session",    "*session",             XrmoptionSepArg,        (caddr_t) NULL },
477 {"-debug",      "*debugLevel",          XrmoptionSepArg,        (caddr_t) NULL },
478 {"-xrm",        NULL,                   XrmoptionResArg,        (caddr_t) NULL },
479 {"-daemon",     ".daemonMode",          XrmoptionNoArg,         "true"         },
480 {"-nodaemon",   ".daemonMode",          XrmoptionNoArg,         "false"        }
481 };
482
483 static int      originalArgc;
484 static char     **originalArgv;
485
486 void 
487 InitResources( int argc, char **argv )
488 {
489         XrmInitialize ();
490         originalArgc = argc;
491         originalArgv = argv;
492         ReinitResources ();
493 }
494
495 void 
496 ReinitResources( void )
497 {
498     int argc;
499     char        **a;
500     char        **argv;
501     XrmDatabase newDB;
502     char * configFileName;
503     char        *type;
504     XrmValue    value;
505
506     argv = (char **) malloc ((originalArgc + 1) * sizeof (char *));
507     if (!argv)
508         LogOutOfMem(
509                 ReadCatalog(MC_LOG_SET,MC_LOG_NO_SPACE,MC_DEF_LOG_NO_SPACE));
510     for (argc = 0; argc < originalArgc; argc++)
511         argv[argc] = originalArgv[argc];
512     argv[argc] = 0;
513     if (DmResourceDB)
514         XrmDestroyDatabase (DmResourceDB);
515     DmResourceDB = XrmGetStringDatabase ("");
516     /* pre-parse the command line to get the -config option, if any */
517     XrmParseCommand (&DmResourceDB, configTable,
518                      sizeof (configTable) / sizeof (configTable[0]),
519                      "Dtlogin", &argc, argv);
520     
521     configFileName = qualifyWithFirst(DEF_XDM_CONFIG,
522                                       CDE_CONFIGURATION_TOP "/config:"
523                                       CDE_INSTALLATION_TOP "/config");
524
525     GetResource ("Dtlogin.configFile", "Dtlogin.ConfigFile",
526                  DM_STRING, &config, configFileName);
527
528     free(configFileName);
529
530
531     
532     newDB = XrmGetFileDatabase ( config );
533     if (newDB)
534     {
535
536         if (DmResourceDB)
537             XrmDestroyDatabase (DmResourceDB);
538         DmResourceDB = newDB;
539     }
540     else if (argc != originalArgc)
541         LogError(
542                 ReadCatalog(MC_LOG_SET,MC_LOG_NO_OPENCFG,MC_DEF_LOG_NO_OPENCFG),
543                 config );
544
545
546
547     /*
548      *  scan the resource database to set the application name...
549      */
550     SetAppName();       
551      
552     XrmParseCommand (&DmResourceDB, optionTable,
553                      sizeof (optionTable) / sizeof (optionTable[0]),
554                      AppName, &argc, argv);
555
556      /* 
557       * test to see if the session variable is set.
558       * for enabling the toggle in the options menu, if it is set..
559       */
560     if((XrmGetResource (DmResourceDB, "Dtlogin*session", "Dtlogin*Session", &type, &value)) == True)
561         session_set = True;
562
563     if (argc > 1)
564     {
565         LogError(ReadCatalog(MC_LOG_SET,MC_LOG_EXTRA_ARG,MC_DEF_LOG_EXTRA_ARG));
566         for (a = argv + 1; *a; a++)
567                 LogError ((unsigned char *)" \"%s\"", *a);
568         LogError ((unsigned char *)"\n");
569     }
570     free (argv);
571 }
572
573 void 
574 LoadDMResources( void )
575 {
576         int     i;
577         char    name[1024], class[1024];
578         FILE    *fp;
579
580         if (servers) {free(servers); servers=NULL;}
581         if (keyFile) {free(keyFile); keyFile=NULL;}
582         if (accessFile) {free(accessFile); accessFile=NULL;}
583
584         for (i = 0; i < NUM_DM_RESOURCES; i++) {
585                 sprintf (name, "%s.%s", AppName, DmResources[i].name);
586                 sprintf (class, "%s.%s", AppName, DmResources[i].class);
587                 GetResource (name, class, DmResources[i].type,
588                               (char **) DmResources[i].dm_value,
589                               DmResources[i].default_value);
590         }
591
592         servers = getFullFileName(servers, 1, NULL);
593         keyFile = getFullFileName(keyFile, 0, NULL);
594         accessFile = getFullFileName(accessFile, 0, NULL);
595
596 #ifndef __apollo        /* set a TZ default for all OS except Domain */
597         if (timeZone == NULL || strlen(timeZone) == 0)
598         {
599          /*
600           *  dynamically determine the timeZone resource default value...
601           */
602           GetSysParms(&timeZone,0,0);
603         }
604 #endif
605
606 }
607
608 void
609 CleanUpName( char *src, char *dst, int len )
610 {
611     while (*src) {
612         if (--len <= 0)
613                 break;
614         switch (*src)
615         {
616         case ':':
617         case '.':
618             *dst++ = '_';
619             break;
620         default:
621             *dst++ = *src;
622         }
623         ++src;
624     }
625     *dst = '\0';
626 }
627
628 void
629 LoadDisplayResources( struct display *d )
630 {
631         int     i;
632         char    name[1024], class[1024];
633         char    dpyName[512], dpyClass[512];
634         char    *lang;
635
636         Debug("Loading display resources for %s\n", d->name);
637         
638         if (d->resources) {free(d->resources); d->resources=NULL;}
639         if (d->setup)     {free(d->setup); d->setup=NULL;}
640         if (d->startup)   {free(d->startup); d->startup=NULL;}
641         if (d->reset)     {free(d->reset); d->reset=NULL;}
642         if (d->session)   {free(d->session); d->session=NULL;}
643         if (d->failsafeClient) {free(d->failsafeClient); d->failsafeClient=NULL;}
644
645         CleanUpName (d->name, dpyName, sizeof (dpyName));
646         CleanUpName (d->class ? d->class : d->name, dpyClass, sizeof (dpyClass));
647
648         if((lang = getenv("LANG")) != NULL)
649            for (i = NUM_DISPLAY_RESOURCES - 1; i >= 0; i--)  {
650                 if(strcmp(DisplayResources[i].name,"language") == 0){
651                   DisplayResources[i].default_value = lang;
652                   break;
653                 }
654            }
655
656
657         for (i = 0; i < NUM_DISPLAY_RESOURCES; i++) {
658                 sprintf (name, "%s.%s.%s", AppName,
659                         dpyName, DisplayResources[i].name);
660                 sprintf (class, "%s.%s.%s", AppName,
661                         dpyClass, DisplayResources[i].class);
662                 GetResource (name, class, DisplayResources[i].type,
663                               (char **) (((char *) d) + DisplayResources[i].offset), DisplayResources[i].default_value);
664         }
665
666 #ifdef _AIX
667     if(d->language == NULL || strlen(d->language) == 0)
668         SetDefaultLanguage(d);
669 #endif /* _AIX */
670
671         d->resources = getFullFileName(d->resources, 2, d->language);
672         d->setup = getFullFileName(d->setup, 0, NULL);
673         d->startup = getFullFileName(d->startup, 0, NULL);
674         d->reset = getFullFileName(d->reset, 0, NULL);
675         d->session = getFullFileName(d->session, 0, NULL);
676         d->failsafeClient = getFullFileName(d->failsafeClient, 0, NULL);
677
678 }
679
680
681         
682 /***************************************************************************
683  *
684  *  SetAppName
685  *
686  *  Probe the resource database to see whether the config file is using
687  *  "Dtlogin" or "DisplayManager" as the application name.
688  *
689  *  If it cannot be determined, "Dtlogin" is used.
690  ***************************************************************************/
691
692 void
693 SetAppName( void )
694 {
695     int         i;
696     char        name[1024], class[1024];
697     char        *type;
698     XrmValue    value;
699
700     for (i = 0; i < NUM_DM_RESOURCES; i++) {
701
702         /*
703          *  try "Dtlogin" (default) ...
704          */
705
706         sprintf (name, "%s.%s", DTLOGIN, DmResources[i].name);
707         sprintf (class, "%s.%s", DTLOGIN, DmResources[i].class);
708
709         if (DmResourceDB && XrmGetResource (DmResourceDB, name, class,
710             &type, &value)) {
711
712             strcpy(AppName, DTLOGIN);
713             break;
714         }
715
716
717         /*
718          *  try "DisplayManager" ...
719          */
720
721         sprintf (name, "%s.%s", DISPLAYMANAGER, DmResources[i].name);
722         sprintf (class, "%s.%s", DISPLAYMANAGER, DmResources[i].class);
723
724         if (DmResourceDB && XrmGetResource (DmResourceDB, name, class,
725             &type, &value)) {
726
727             strcpy(AppName, DISPLAYMANAGER);
728             break;
729         }
730         
731     }
732 }
733
734
735 /***************************************************************************
736  *
737  *  getFullFileName
738  *
739  * Try to produce a fully qualified file name by prepending
740  * /etc/dt/config or /usr/dt/config to a resource file name.
741  * There are 2 special cases:  servers - which can be a command, and
742  *                             resources - which can an imbeded %L.
743  ***************************************************************************/
744 extern char *_ExpandLang( char *string, char *lang );
745
746 static char *
747 getFullFileName(char *name, int special, char *lang)
748 {
749
750 char * newname;
751
752     if (name == NULL)
753         return(NULL);
754
755     /** if the file already starts with a '/' **/
756     /** then just return a copy of it         **/
757     if (name[0] == '/') {
758         if ((newname = (char *)malloc((strlen(name)+1)*sizeof(char))) == NULL) {
759             return (NULL);
760         } else {
761             strcpy(newname, name);
762             return(newname);
763         }
764     }
765
766     switch (special) {
767                  /*********************/
768         case 0:  /** no special case **/
769                  /*********************/
770             newname = qualifyWithFirst(name,
771                                        CDE_CONFIGURATION_TOP "/config:"
772                                        CDE_INSTALLATION_TOP "/config");
773             return (newname);
774
775                  /***************************************/
776         case 1:  /** special handling for servers file **/
777                  /***************************************/
778             if (strchr(name, ':') != NULL) {
779                 /** This is probably a command and not a file name **/
780                 /** so just return a copy of it.                   **/
781                 if ((newname = (char *)malloc((strlen(name)+1)*sizeof(char)))
782                     == NULL) {
783                     return (NULL);
784                 } else {
785                     strcpy(newname, name);
786                     return(newname);
787                 }
788             } else {
789                 newname = qualifyWithFirst(name,
790                                            CDE_CONFIGURATION_TOP "/config:"
791                                            CDE_INSTALLATION_TOP "/config");
792                 return (newname);
793             }
794
795                  /********************************************/
796         case 2:  /** special handling for d->resources file **/
797                  /********************************************/
798             if (strchr(name, '%') == NULL) {
799                 /** no special processing needed **/
800                 newname = qualifyWithFirst(name,
801                                            CDE_CONFIGURATION_TOP "/config:"
802                                            CDE_INSTALLATION_TOP "/config");
803                 return (newname);
804             } else {
805                 char *langString;
806                 char *tempName;
807                 int tempLen;
808
809                 /** need to remember the %L **/
810                 if (lang == NULL)
811                     lang = "C";
812                 langString = _ExpandLang(name, lang);
813                 if ( (tempName = qualifyWithFirst(langString,
814                                            CDE_CONFIGURATION_TOP "/config:"
815                                            CDE_INSTALLATION_TOP "/config") )
816                     == NULL) {
817                     free(langString);
818                     langString = _ExpandLang(name, "C");
819                     if ( (tempName = qualifyWithFirst(langString,
820                                            CDE_CONFIGURATION_TOP "/config:"
821                                            CDE_INSTALLATION_TOP "/config") )
822                         == NULL) {
823                         free(langString);
824                         return(NULL);
825                     }
826                 }
827                 /** We have a fully qualified and expanded file name **/
828                 /** but we need to return a fully qualified but NOT  **/
829                 /** expanded file name.                              **/
830                 tempLen = strlen(tempName) - strlen(langString)
831                              + strlen(name) + 1;
832                 if ((newname = (char *)malloc(tempLen * sizeof(char))) == NULL){
833                     free(langString);
834                     return(tempName);
835                 } else {
836                     tempLen = strlen(tempName) - strlen(langString);
837                     strncpy(newname, tempName, tempLen);
838                     strcpy(newname+tempLen, name);
839                     free (langString);
840                     return(newname);
841                 }
842             }
843     }
844 }
845