1 #if 0
2 static const char sccsid[] = "@(#)resource.c	4.08 98/08/04 xlockmore";
3 
4 #endif
5 
6 /*-
7  * resource.c - resource management for xlock, the X Window System lockscreen.
8  *
9  * Copyright (c) 1991 by Patrick J. Naughton.
10  *
11  * See xlock.c for copying information.
12  *
13  * Revision History:
14  *
15  * Changes maintained by David Bagley <bagleyd AT verizon.net>
16  * 02-Dec-03: Jouk Jansen <joukj AT hrem.nano.tudelft.nl>
17  *            On OpenVMS when TCPIP is switched off gethostname does not
18  *            work, in that case LIB$GETSYI to get the DECNET nodename.
19  * 19-Jun-98: batchcount deprecated.  Use count instead.  batchcount still
20  *            works for commandline.
21  * 01-May-97: Matthew Rench <mdrench@mtu.edu>
22  *            Added DPMS options.
23  * 01-Apr-97: Tom Schmidt <tschmidt AT micron.com>
24  *            Fixed memory leak.  Made -visual option a hacker mode for now.
25  * 20-Mar-97: Tom Schmidt <tschmidt AT micron.com>
26  *            Added -visual option.
27  *  3-Apr-96: Jouk Jansen <joukj AT hrem.nano.tudelft.nl>
28  *            Supply for wildcards for filenames for random selection
29  * 18-Mar-96: Ron Hitchens <ron AT idiom.com>
30  *            Setup chosen mode with set_default_mode() for new hook scheme.
31  *  6-Mar-96: Jouk Jansen <joukj AT hrem.nano.tudelft.nl>
32  *            Remote node checking for VMS fixed
33  * 20-Dec-95: Ron Hitchens <ron AT idiom.com>
34  *            Resource parsing fixed for "nolock".
35  * 02-Aug-95: Patch to use default delay, etc., from mode.h thanks to
36  *            Roland Bock <exp120@physik.uni-kiel.d400.de>
37  * 17-Jun-95: Split out mode.h from resource.c .
38  * 29-Mar-95: Added -cycles for more control over a lockscreen similar to
39  *            -delay, -batchcount, and -saturation.
40  * 21-Feb-95: MANY patches from Heath A. Kehoe <hakehoe AT icaen.uiowa.edu>.
41  * 21-Dec-94: patch for -delay, -batchcount and -saturation for X11R5+
42  *            from Patrick D Sullivan <pds@bss.com>.
43  * 18-Dec-94: -inroot option added from Bill Woodward <wpwood@pencom.com>.
44  * 20-Sep-94: added bat mode from Lorenzo Patocchi <patol@info.isbiel.ch>.
45  * 11-Jul-94: added grav mode, and inwindow option from Greg Bowering
46  *            <greg@cs.adelaide.edu.au>
47  * 22-Jun-94: Modified for VMS
48  *            <Anthony.D.Clarke@Support.Hatfield.Raytheon.bae.eurokom.ie>
49  * 17-Jun-94: default changed from life to blank
50  * 21-Mar-94: patch fix for AIXV3 from <R.K.Lloyd@csc.liv.ac.uk>
51  * 01-Dec-93: added patch for AIXV3 from Tom McConnell
52  *            <tmcconne@sedona.intel.com>
53  * 29-Jun-93: added spline, maze, sphere, hyper, helix, rock, and blot mode.
54  *
55  * Changes of Patrick J. Naughton
56  * 25-Sep-91: added worm mode.
57  * 24-Jun-91: changed name to username.
58  * 06-Jun-91: Added flame mode.
59  * 24-May-91: Added -name and -usefirst and -resources.
60  * 16-May-91: Added random mode and pyro mode.
61  * 26-Mar-91: checkResources: delay must be >= 0.
62  * 29-Oct-90: Added #include <ctype.h> for missing isupper() on some OS revs.
63  *	      moved -mode option, reordered Xrm database evaluation.
64  * 28-Oct-90: Added text strings.
65  * 26-Oct-90: Fix bug in mode specific options.
66  * 31-Jul-90: Fix ':' handling in parsefilepath
67  * 07-Jul-90: Created from resource work in xlock.c
68  *
69  */
70 
71 #include "xlock.h"
72 #include "vis.h"
73 #include "iostuff.h"
74 #include "version.h"
75 #if VMS
76 # if ( __VMS_VER < 70000000 )
77 #  ifdef __DECC
78 #   define gethostname decc$gethostname
79 #   define gethostbyname decc$gethostbyname
80 #  endif
81 # else
82 #  include <socket.h>
83 # endif
84 # include <descrip>
85 # include <ssdef>
86 # include <syidef>
87 # include <lib$routines>
88 #endif
89 
90 #ifdef __sgi
91 #undef offsetof
92 #endif
93 
94 #ifndef offsetof
95 # define offsetof(s,m) ((char*)(&((s *)0)->m)-(char*)0)
96 #endif
97 
98 #ifdef USE_MODULES
99 # ifndef DEF_MODULEPATH
100 #if 1
101 #  define DEF_MODULEPATH "/usr/lib/X11/xlock/modules"
102 #else
103 #  define DEF_MODULEPATH "@PREFIX@/lib/X11/xlock/modules"
104 #endif
105 # endif
106 #endif
107 
108 #ifndef DEF_FILESEARCHPATH
109 # ifdef VMS
110 #  include <iodef>
111 #  include <stsdef>
112 #  include <types.h>
113 #  include <starlet.h>
114 
115 #  define DEF_FILESEARCHPATH "DECW$SYSTEM_DEFAULTS:DECW$%N.DAT%S"
116 #  define BUFSIZE 132
117 #  define DECW$C_WS_DSP_TRANSPORT 2	/*  taken from wsdriver.lis */
118 #  define IO$M_WS_DISPLAY 0x00000040	/* taken from wsdriver */
119 
120 struct descriptor_t {		/* descriptor structure         */
121 	unsigned short len;
122 	unsigned char type;
123 	unsigned char c_class;
124 	char       *ptr;
125 };
126 typedef struct descriptor_t dsc;
127 
128 /* $dsc creates a descriptor for a predefined string */
129 
130 #  define $dsc(name,string) dsc name = { sizeof(string)-1,14,1,string}
131 
132 /* $dscp creates a descriptor pointing to a buffer allocated elsewhere */
133 
134 #  define $dscp(name,size,addr) dsc name = { size,14,1,addr }
135 
136 static int  descr();
137 
138 # else
139 #  define DEF_FILESEARCHPATH "/usr/lib/X11/%T/%N%C%S:/usr/lib/X11/%T/%N%S"
140 # endif
141 #endif
142 #ifndef DEF_MODE
143 # if 0
144 #  define DEF_MODE	"blank"	/* May be safer */
145 # else
146 #  define DEF_MODE	"random"	/* May be more interesting */
147 # endif
148 #endif
149 #define DEF_DELAY	"200000"	/* microseconds between batches */
150 #define DEF_COUNT	"100"	/* vectors (or whatever) per batch */
151 #define DEF_CYCLES	"1000"	/* timeout in cycles for a batch */
152 #define DEF_SIZE	"0"	/* size, default if 0 */
153 #define DEF_NCOLORS	"64"	/* maximum number of colors */
154 #define DEF_SATURATION	"1.0"	/* color ramp saturation 0->1 */
155 #define DEF_NICE	"10"	/* xlock process nicelevel */
156 #define DEF_ERASEDELAY	"400"	/* Speed for screen erase modes */
157 #define DEF_ERASETIME	"2"	/* Maximum number of seconds for erase */
158 #define DEF_LOCKDELAY	"0"	/* secs until lock */
159 #define DEF_UNLOCKDELAY	"0"	/* secs until unlock */
160 #define DEF_TIMEOUT	"30"	/* secs until password entry times out */
161 #ifndef DEF_FONT
162 # ifdef AIXV3
163 #  define DEF_FONT	"fixed"
164 # else /* !AIXV3 */
165 #  define DEF_FONT	"-*-helvetica-medium-r-*-*-24-*-*-*-*-*-*"
166 # endif /* !AIXV3 */
167 #endif
168 #define DEF_PLANFONT     "-*-fixed-medium-r-*-*-14-*-*-*-*-*-*"
169 #ifdef USE_MB
170 # define DEF_FONTSET	DEF_FONT ",-*-*-medium-r-normal--24-*"
171 # define DEF_PLANFONTSET DEF_PLANFONT ",-*-*-medium-r-normal--14-*"
172 #endif /* USE_MB */
173 #define DEF_BG		"White"
174 #define DEF_FG		"Black"
175 
176 /* language dependent resources */
177 #if defined FR
178 #include "resource-msg-fr.h"
179 #elif defined NL
180 #include "resource-msg-nl.h"
181 #elif defined JA
182 #include "resource-msg-ja.h"
183 #elif defined ZH
184 #include "resource-msg-zh_TW.h"
185 #else
186 #include "resource-msg-en.h"
187 #endif
188 
189 #ifdef GLOBAL_UNLOCK
190 # define DEF_GUSER "Username: "
191 #endif
192 #ifdef SAFEWORD
193 # define DEF_DPASS "Dynamic password: "
194 # define DEF_FPASS "Fixed Password: "
195 # define DEF_CHALL "Challenge: "
196 #endif
197 #define DEF_GEOMETRY	""
198 #define DEF_ICONGEOMETRY	""
199 #ifdef FX
200 # define DEF_GLGEOMETRY ""
201 #endif
202 #define DEF_DELTA3D	"1.5"	/* space between things in 3d mode relative to their size */
203 #ifndef DEF_MESSAGESFILE
204 # define DEF_MESSAGESFILE	""
205 #endif
206 #ifndef DEF_MESSAGEFILE
207 # define DEF_MESSAGEFILE ""
208 #endif
209 #ifndef DEF_MESSAGE
210 /* #define DEF_MESSAGE "I am out running around." */
211 # define DEF_MESSAGE ""
212 #endif
213 #ifndef DEF_BITMAP
214 # define DEF_BITMAP ""
215 #endif
216 #ifndef DEF_MAILAPP
217 # define DEF_MAILAPP ""
218 #endif
219 #ifdef USE_VTLOCK
220 # define VTLOCKMODE_OFF     	"off"
221 # define VTLOCKMODE_NOSWITCH     "noswitch"
222 # define VTLOCKMODE_SWITCH       "switch"
223 # define VTLOCKMODE_RESTORE      "restore"
224 # define DEF_VTLOCK              VTLOCKMODE_OFF
225 #endif
226 #define DEF_CLASSNAME	"XLock"
227 #if 0
228 /*-
229   Grid     Number of Neighbors
230   ----     ------------------
231   Square   4 or 8
232   Hexagon  6
233   Triangle 3, 9 or 12     <- 9 is not too mathematically sound...
234 */
235 # define DEF_NEIGHBORS  "0"	/* automata mode will choose best or random value */
236 # define DEF_MOUSE   "False"
237 #endif
238 
239 #ifdef USE_RPLAY
240 # define DEF_LOCKSOUND		"thank-you"
241 # define DEF_INFOSOUND		"identify-please"
242 # define DEF_VALIDSOUND		"complete"
243 # define DEF_INVALIDSOUND	"not-programmed"
244 #else /* !USE_RPLAY */
245 # if defined ( DEF_PLAY ) || defined ( USE_NAS ) || defined ( USE_ESOUND )
246 #  define DEF_LOCKSOUND		"thank-you.au"
247 #  define DEF_INFOSOUND		"identify-please.au"
248 #  define DEF_VALIDSOUND	"complete.au"
249 #  define DEF_INVALIDSOUND	"not-programmed.au"
250 # else /* !DEF_PLAY && !USE_NAS && !USE_ESOUND */
251 #  ifdef USE_VMSPLAY
252 #   define DEF_LOCKSOUND	"[]thank-you.au"
253 #   define DEF_INFOSOUND	"[]identify-please.au"
254 #   define DEF_VALIDSOUND	"[]complete.au"
255 #   define DEF_INVALIDSOUND	"[]not-programmed.au"
256 #  endif /* !USE_VMSPLAY */
257 # endif /* !DEF_PLAY && !USE_NAS && !USE_ESOUND */
258 #endif /* !USE_RPLAY */
259 
260 #if defined( USE_AUTO_LOGOUT ) && !defined( DEF_AUTO_LOGOUT )
261 # if ( USE_AUTO_LOGOUT <= 0 )
262 #  define DEF_AUTO_LOGOUT "120"	/* User Default, can be overridden */
263 # else
264 #  define DEF_AUTO_LOGOUT "0"	/* User Default, can be overridden */
265 # endif
266 #endif
267 
268 #ifdef USE_DPMS
269 # define DEF_DPMSSTANDBY "-1"
270 # define DEF_DPMSSUSPEND "-1"
271 # define DEF_DPMSOFF     "-1"
272 #endif
273 
274 #if defined( USE_BUTTON_LOGOUT )
275 # if !defined( DEF_BUTTON_LOGOUT )
276 #  if ( USE_BUTTON_LOGOUT <= 0 )
277 #   define DEF_BUTTON_LOGOUT "5"	/* User Default, can be overridden */
278 #  else
279 #   define DEF_BUTTON_LOGOUT "0"	/* User Default, can be overridden */
280 #  endif
281 # endif
282 #endif
283 
284 /* For modes with text, marquee & nose */
285 extern char *program;
286 extern char *messagesfile;
287 extern char *messagefile;
288 extern char *message;		/* flag as well here */
289 extern char *messagefontname;
290 
291 #if 0
292 /* For automata modes */
293 extern int  neighbors;
294 
295 /* For eyes, julia, & swarm modes */
296 Bool        mouse;
297 #endif
298 
299 char        hostname[MAXHOSTNAMELEN];
300 static char *mode = (char *) NULL;
301 char       *displayname = (char *) NULL;
302 static char *classname;
303 static char *modename;
304 static char *modeclassname;
305 extern Window parent;
306 static char *parentname;
307 extern Bool parentSet;
308 extern char error_buf[ERROR_BUF];
309 
310 #if HAVE_DIRENT_H
311 static struct dirent ***images_list = (struct dirent ***) NULL;
312 int         num_list = 0;
313 struct dirent **image_list = (struct dirent **) NULL;
314 char        filename_r[MAXNAMLEN];
315 char        directory_r[DIRBUF];
316 
317 #endif
318 
319 static XrmOptionDescRec genTable[] =
320 {
321 	{(char *) "-mode", (char *) ".mode", XrmoptionSepArg, (caddr_t) NULL},
322 	{(char *) "-erasemode", (char *) ".erasemode", XrmoptionSepArg, (caddr_t) NULL},
323 	{(char *) "-erasedelay", (char *) ".erasedelay", XrmoptionSepArg, (caddr_t) NULL},
324 	{(char *) "-erasetime", (char *) ".erasetime", XrmoptionSepArg, (caddr_t) NULL},
325 	{(char *) "-nolock", (char *) ".nolock", XrmoptionNoArg, (caddr_t) "on"},
326 	{(char *) "+nolock", (char *) ".nolock", XrmoptionNoArg, (caddr_t) "off"},
327 #ifdef USE_VTLOCK
328 	{(char *) "-vtlock", (char *) ".vtlock", XrmoptionSepArg, (caddr_t) NULL},
329 #endif
330 	{(char *) "-inwindow", (char *) ".inwindow", XrmoptionNoArg, (caddr_t) "on"},
331 	{(char *) "+inwindow", (char *) ".inwindow", XrmoptionNoArg, (caddr_t) "off"},
332 	{(char *) "-inroot", (char *) ".inroot", XrmoptionNoArg, (caddr_t) "on"},
333 	{(char *) "+inroot", (char *) ".inroot", XrmoptionNoArg, (caddr_t) "off"},
334 	{(char *) "-remote", (char *) ".remote", XrmoptionNoArg, (caddr_t) "on"},
335 	{(char *) "+remote", (char *) ".remote", XrmoptionNoArg, (caddr_t) "off"},
336 	{(char *) "-mono", (char *) ".mono", XrmoptionNoArg, (caddr_t) "on"},
337 	{(char *) "+mono", (char *) ".mono", XrmoptionNoArg, (caddr_t) "off"},
338 	{(char *) "-allowaccess", (char *) ".allowaccess", XrmoptionNoArg, (caddr_t) "on"},
339 	{(char *) "+allowaccess", (char *) ".allowaccess", XrmoptionNoArg, (caddr_t) "off"},
340 	{(char *) "-allowroot", (char *) ".allowroot", XrmoptionNoArg, (caddr_t) "on"},
341 	{(char *) "+allowroot", (char *) ".allowroot", XrmoptionNoArg, (caddr_t) "off"},
342 	{(char *) "-debug", (char *) ".debug", XrmoptionNoArg, (caddr_t) "on"},
343 	{(char *) "+debug", (char *) ".debug", XrmoptionNoArg, (caddr_t) "off"},
344 	{(char *) "-description", (char *) ".description", XrmoptionNoArg, (caddr_t) "on"},
345 	{(char *) "+description", (char *) ".description", XrmoptionNoArg, (caddr_t) "off"},
346 	{(char *) "-echokeys", (char *) ".echokeys", XrmoptionNoArg, (caddr_t) "on"},
347 	{(char *) "+echokeys", (char *) ".echokeys", XrmoptionNoArg, (caddr_t) "off"},
348 	{(char *) "-echokey", (char *) ".echokey", XrmoptionSepArg, (caddr_t) NULL},
349 	{(char *) "-enablesaver", (char *) ".enablesaver", XrmoptionNoArg, (caddr_t) "on"},
350 	{(char *) "+enablesaver", (char *) ".enablesaver", XrmoptionNoArg, (caddr_t) "off"},
351 	{(char *) "-resetsaver", (char *) ".resetsaver", XrmoptionNoArg, (caddr_t) "on"},
352 	{(char *) "+resetsaver", (char *) ".resetsaver", XrmoptionNoArg, (caddr_t) "off"},
353 	{(char *) "-grabmouse", (char *) ".grabmouse", XrmoptionNoArg, (caddr_t) "on"},
354 	{(char *) "+grabmouse", (char *) ".grabmouse", XrmoptionNoArg, (caddr_t) "off"},
355 	{(char *) "-grabserver", (char *) ".grabserver", XrmoptionNoArg, (caddr_t) "on"},
356 	{(char *) "+grabserver", (char *) ".grabserver", XrmoptionNoArg, (caddr_t) "off"},
357 	{(char *) "-hide", (char *) ".hide", XrmoptionNoArg, (caddr_t) "on"},
358 	{(char *) "+hide", (char *) ".hide", XrmoptionNoArg, (caddr_t) "off"},
359 	{(char *) "-install", (char *) ".install", XrmoptionNoArg, (caddr_t) "on"},
360 	{(char *) "+install", (char *) ".install", XrmoptionNoArg, (caddr_t) "off"},
361 	{(char *) "-mousemotion", (char *) ".mousemotion", XrmoptionNoArg, (caddr_t) "on"},
362 	{(char *) "+mousemotion", (char *) ".mousemotion", XrmoptionNoArg, (caddr_t) "off"},
363 	{(char *) "-sound", (char *) ".sound", XrmoptionNoArg, (caddr_t) "on"},
364 	{(char *) "+sound", (char *) ".sound", XrmoptionNoArg, (caddr_t) "off"},
365 	{(char *) "-showdate", (char *) ".showdate", XrmoptionNoArg, (caddr_t) "on"},
366 	{(char *) "+showdate", (char *) ".showdate", XrmoptionNoArg, (caddr_t) "off"},
367 	{(char *) "-timeelapsed", (char *) ".timeelapsed", XrmoptionNoArg, (caddr_t) "on"},
368 	{(char *) "+timeelapsed", (char *) ".timeelapsed", XrmoptionNoArg, (caddr_t) "off"},
369 	{(char *) "-usefirst", (char *) ".usefirst", XrmoptionNoArg, (caddr_t) "on"},
370 	{(char *) "+usefirst", (char *) ".usefirst", XrmoptionNoArg, (caddr_t) "off"},
371 	{(char *) "-verbose", (char *) ".verbose", XrmoptionNoArg, (caddr_t) "on"},
372 	{(char *) "+verbose", (char *) ".verbose", XrmoptionNoArg, (caddr_t) "off"},
373 	{(char *) "-nice", (char *) ".nice", XrmoptionSepArg, (caddr_t) NULL},
374 	{(char *) "-lockdelay", (char *) ".lockdelay", XrmoptionSepArg, (caddr_t) NULL},
375 	{(char *) "-unlockdelay", (char *) ".unlockdelay", XrmoptionSepArg, (caddr_t) NULL},
376 	{(char *) "-timeout", (char *) ".timeout", XrmoptionSepArg, (caddr_t) NULL},
377 	{(char *) "-font", (char *) ".font", XrmoptionSepArg, (caddr_t) NULL},
378 	{(char *) "-planfont", (char *) ".planfont", XrmoptionSepArg, (caddr_t) NULL},
379 #ifdef USE_MB
380 	{(char *) "-fontset", (char *) ".fontset", XrmoptionSepArg, (caddr_t) NULL},
381 	{(char *) "-planfontset", (char *) ".planfontset", XrmoptionSepArg, (caddr_t) NULL},
382 #endif
383 	{(char *) "-bg", (char *) ".background", XrmoptionSepArg, (caddr_t) NULL},
384 	{(char *) "-fg", (char *) ".foreground", XrmoptionSepArg, (caddr_t) NULL},
385 	{(char *) "-background", (char *) ".background", XrmoptionSepArg, (caddr_t) NULL},
386 	{(char *) "-foreground", (char *) ".foreground", XrmoptionSepArg, (caddr_t) NULL},
387 	{(char *) "-username", (char *) ".username", XrmoptionSepArg, (caddr_t) NULL},
388 	{(char *) "-password", (char *) ".password", XrmoptionSepArg, (caddr_t) NULL},
389 	{(char *) "-info", (char *) ".info", XrmoptionSepArg, (caddr_t) NULL},
390 	{(char *) "-validate", (char *) ".validate", XrmoptionSepArg, (caddr_t) NULL},
391 	{(char *) "-invalid", (char *) ".invalid", XrmoptionSepArg, (caddr_t) NULL},
392 	{(char *) "-invalidCapsLock", (char *) ".invalidCapsLock", XrmoptionSepArg, (caddr_t) NULL},
393 	{(char *) "-geometry", (char *) ".geometry", XrmoptionSepArg, (caddr_t) NULL},
394 	{(char *) "-icongeometry", (char *) ".icongeometry", XrmoptionSepArg, (caddr_t) NULL},
395 #ifdef FX
396 	{(char *) "-glgeometry", (char *) ".glgeometry", XrmoptionSepArg, (caddr_t) NULL},
397 #endif
398 
399 	{(char *) "-wireframe", (char *) ".wireframe", XrmoptionNoArg, (caddr_t) "on"},
400 	{(char *) "+wireframe", (char *) ".wireframe", XrmoptionNoArg, (caddr_t) "off"},
401 
402 #ifdef USE_GL
403 	{(char *) "-showfps", (char *) ".showfps", XrmoptionNoArg, (caddr_t) "on"},
404 	{(char *) "+showfps", (char *) ".showfps", XrmoptionNoArg, (caddr_t) "off"},
405 	{(char *) "-fpstop", (char *) ".fpstop", XrmoptionNoArg, (caddr_t) "on"},
406 	{(char *) "+fpstop", (char *) ".fpstop", XrmoptionNoArg, (caddr_t) "off"},
407 	{(char *) "-fpsfont", (char *) ".fpsfont", XrmoptionSepArg, (caddr_t) NULL},
408 #endif
409 
410 	{(char *) "-use3d", (char *) ".use3d", XrmoptionNoArg, (caddr_t) "on"},
411 	{(char *) "+use3d", (char *) ".use3d", XrmoptionNoArg, (caddr_t) "off"},
412 	{(char *) "-delta3d", (char *) ".delta3d", XrmoptionSepArg, (caddr_t) NULL},
413 	{(char *) "-none3d", (char *) ".none3d", XrmoptionSepArg, (caddr_t) NULL},
414 	{(char *) "-right3d", (char *) ".right3d", XrmoptionSepArg, (caddr_t) NULL},
415 	{(char *) "-left3d", (char *) ".left3d", XrmoptionSepArg, (caddr_t) NULL},
416 	{(char *) "-both3d", (char *) ".both3d", XrmoptionSepArg, (caddr_t) NULL},
417 
418     /* For modes with text, marquee & nose */
419 	{(char *) "-program", (char *) ".program", XrmoptionSepArg, (caddr_t) NULL},
420 	{(char *) "-messagesfile", (char *) ".messagesfile", XrmoptionSepArg, (caddr_t) NULL},
421 	{(char *) "-messagefile", (char *) ".messagefile", XrmoptionSepArg, (caddr_t) NULL},
422 	{(char *) "-message", (char *) ".message", XrmoptionSepArg, (caddr_t) NULL},
423 	{(char *) "-messagefont", (char *) ".messagefont", XrmoptionSepArg, (caddr_t) NULL},
424 #if 0
425     /* For automata modes */
426 	{(char *) "-neighbors", (char *) ".neighbors", XrmoptionSepArg, (caddr_t) NULL},
427     /* For eyes, julia, and swarm modes */
428 	{(char *) "-mouse", (char *) ".mouse", XrmoptionNoArg, (caddr_t) "on"},
429 	{(char *) "+mouse", (char *) ".mouse", XrmoptionNoArg, (caddr_t) "off"},
430 #endif
431 
432 #if defined( USE_XLOCKRC ) || defined( FALLBACK_XLOCKRC )
433 	{(char *) "-cpasswd", (char *) ".cpasswd", XrmoptionSepArg, (caddr_t) NULL},
434 #endif
435 #ifdef USE_AUTO_LOGOUT
436 	{(char *) "-logoutAuto", (char *) ".logoutAuto", XrmoptionSepArg, (caddr_t) NULL},
437 #endif
438 #ifdef USE_BUTTON_LOGOUT
439 	{(char *) "-logoutButton", (char *) ".logoutButton", XrmoptionSepArg, (caddr_t) NULL},
440 	{(char *) "-logoutButtonLabel", (char *) ".logoutButtonLabel", XrmoptionSepArg, (caddr_t) NULL},
441 	{(char *) "-logoutButtonHelp", (char *) ".logoutButtonHelp", XrmoptionSepArg, (caddr_t) NULL},
442 	{(char *) "-logoutFailedString", (char *) ".logoutFailedString", XrmoptionSepArg, (caddr_t) NULL},
443 #endif
444 #ifdef USE_DTSAVER
445 	{(char *) "-dtsaver", (char *) ".dtsaver", XrmoptionNoArg, (caddr_t) "on"},
446 	{(char *) "+dtsaver", (char *) ".dtsaver", XrmoptionNoArg, (caddr_t) "off"},
447 #endif
448 #ifdef USE_XINERAMA
449 	{(char *) "-xinerama", (char *) ".xinerama", XrmoptionNoArg, (caddr_t) "on"},
450 	{(char *) "+xinerama", (char *) ".xinerama", XrmoptionNoArg, (caddr_t) "off"},
451 #endif
452 #ifdef USE_SOUND
453 	{(char *) "-locksound", (char *) ".locksound", XrmoptionSepArg, (caddr_t) NULL},
454 	{(char *) "-infosound", (char *) ".infosound", XrmoptionSepArg, (caddr_t) NULL},
455 	{(char *) "-validsound", (char *) ".validsound", XrmoptionSepArg, (caddr_t) NULL},
456 	{(char *) "-invalidsound", (char *) ".invalidsound", XrmoptionSepArg, (caddr_t) NULL},
457 #endif
458 	{(char *) "-startCmd", (char *) ".startCmd", XrmoptionSepArg, (caddr_t) NULL},
459 	{(char *) "-endCmd", (char *) ".endCmd", XrmoptionSepArg, (caddr_t) NULL},
460 #ifndef VMS
461 	{(char *) "-pipepassCmd", (char *) ".pipepassCmd", XrmoptionSepArg, (caddr_t) NULL},
462 #endif
463 	{(char *) "-logoutCmd", (char *) ".logoutCmd", XrmoptionSepArg, (caddr_t) NULL},
464 
465 	{(char *) "-mailCmd", (char *) ".mailCmd", XrmoptionSepArg, (caddr_t) ""},
466 	{(char *) "-mailIcon", (char *) ".mailIcon", XrmoptionSepArg, (caddr_t) ""},
467 	{(char *) "-nomailIcon", (char *) ".nomailIcon", XrmoptionSepArg, (caddr_t) ""},
468 #ifdef USE_DPMS
469 	{(char *) "-dpmsstandby", (char *) ".dpmsstandby", XrmoptionSepArg, (caddr_t) NULL},
470 	{(char *) "-dpmssuspend", (char *) ".dpmssuspend", XrmoptionSepArg, (caddr_t) NULL},
471 	{(char *) "-dpmsoff", (char *) ".dpmsoff", XrmoptionSepArg, (caddr_t) NULL},
472 #endif
473 };
474 
475 #define genEntries (sizeof genTable / sizeof genTable[0])
476 
477 static XrmOptionDescRec modeTable[] =
478 {
479 	{(char *) "-delay", (char *) "*delay", XrmoptionSepArg, (caddr_t) NULL},
480 	{(char *) "-batchcount", (char *) "*count", XrmoptionSepArg, (caddr_t) NULL},
481 	{(char *) "-count", (char *) "*count", XrmoptionSepArg, (caddr_t) NULL},
482 	{(char *) "-cycles", (char *) "*cycles", XrmoptionSepArg, (caddr_t) NULL},
483 	{(char *) "-size", (char *) "*size", XrmoptionSepArg, (caddr_t) NULL},
484 	{(char *) "-ncolors", (char *) "*ncolors", XrmoptionSepArg, (caddr_t) NULL},
485 	{(char *) "-saturation", (char *) "*saturation", XrmoptionSepArg, (caddr_t) NULL},
486     /* For modes with images, xbm, xpm, & ras */
487 	{(char *) "-bitmap", (char *) "*bitmap", XrmoptionSepArg, (caddr_t) NULL},
488 };
489 
490 #define modeEntries (sizeof modeTable / sizeof modeTable[0])
491 
492 /*-
493    Chicken/egg problem here.
494    Customization strings will only work with
495 #define CUSTOMIZATION
496    I prefer not to use it because "xlock -display whatever:0" does not work.
497    If I get any complaints about this I will change it the default.
498  */
499 
500 static XrmOptionDescRec cmdlineTable[] =
501 {
502 #ifndef CUSTOMIZATION
503 	{(char *) "-display", (char *) ".display", XrmoptionSepArg, (caddr_t) NULL},
504 #endif
505 	{(char *) "-visual", (char *) ".visual", XrmoptionSepArg, (caddr_t) NULL},
506 	{(char *) "-parent", (char *) ".parent", XrmoptionSepArg, (caddr_t) NULL},
507 	{(char *) "-nolock", (char *) ".nolock", XrmoptionNoArg, (caddr_t) "on"},
508 	{(char *) "+nolock", (char *) ".nolock", XrmoptionNoArg, (caddr_t) "off"},
509 	{(char *) "-remote", (char *) ".remote", XrmoptionNoArg, (caddr_t) "on"},
510 	{(char *) "+remote", (char *) ".remote", XrmoptionNoArg, (caddr_t) "off"},
511 	{(char *) "-inwindow", (char *) ".inwindow", XrmoptionNoArg, (caddr_t) "on"},
512 	{(char *) "+inwindow", (char *) ".inwindow", XrmoptionNoArg, (caddr_t) "off"},
513 	{(char *) "-inroot", (char *) ".inroot", XrmoptionNoArg, (caddr_t) "on"},
514 	{(char *) "+inroot", (char *) ".inroot", XrmoptionNoArg, (caddr_t) "off"},
515 #ifdef USE_DTSAVER
516 	{(char *) "-dtsaver", (char *) ".dtsaver", XrmoptionNoArg, (caddr_t) "on"},
517 	{(char *) "+dtsaver", (char *) ".dtsaver", XrmoptionNoArg, (caddr_t) "off"},
518 #endif
519 #ifdef USE_XINERAMA
520 	{(char *) "-xinerama", (char *) ".xinerama", XrmoptionNoArg, (caddr_t) "on"},
521 	{(char *) "+xinerama", (char *) ".xinerama", XrmoptionNoArg, (caddr_t) "off"},
522 #endif
523 	{(char *) "-xrm", (char *) NULL, XrmoptionResArg, (caddr_t) NULL}
524 };
525 
526 #define cmdlineEntries (sizeof cmdlineTable / sizeof cmdlineTable[0])
527 
528 static XrmOptionDescRec earlyCmdlineTable[] =
529 {
530 	{(char *) "-name", (char *) ".name", XrmoptionSepArg, (caddr_t) NULL},
531 #ifdef CUSTOMIZATION
532 	{(char *) "-display", (char *) ".display", XrmoptionSepArg, (caddr_t) NULL},
533 #endif
534 };
535 
536 #define earlyCmdlineEntries (sizeof earlyCmdlineTable / sizeof earlyCmdlineTable[0])
537 
538 #ifdef USE_MODULES
539 static XrmOptionDescRec modulepathTable[] =
540 {
541 	{(char *) "-modulepath", (char *) ".modulepath", XrmoptionSepArg, (caddr_t) NULL},
542 };
543 
544 #endif
545 
546 static OptionStruct opDesc[] =
547 {
548 	{(char *) "-help", (char *) "print out this message to standard output"},
549 	{(char *) "-version", (char *) "print version number (if >= 4.00) to standard output"},
550 	{(char *) "-resources", (char *) "print default resource file to standard output"},
551 	{(char *) "-display displayname", (char *) "X server to contact"},
552 #ifdef USE_MODULES
553 	{(char *) "-modulepath", (char *) "directory where screensaver modules are stored"},
554 #endif
555 	{(char *) "-visual visualname", (char *) "X visual to use"},
556 	{(char *) "-parent", (char *) "parent window id (for inwindow)"},
557 {(char *) "-name resourcename", (char *) "class name to use for resources (default is XLock)"},
558 	{(char *) "-delay usecs", (char *) "microsecond delay between screen updates"},
559 	{(char *) "-batchcount num", (char *) "number of things per batch (deprecated)"},
560 	{(char *) "-count num", (char *) "number of things per batch"},
561 	{(char *) "-cycles num", (char *) "number of cycles per batch"},
562 	{(char *) "-size num", (char *) "size of a unit in a mode, default is 0"},
563 	{(char *) "-ncolors num", (char *) "maximum number of colors, default is 64"},
564 	{(char *) "-saturation value", (char *) "saturation of color ramp"},
565   /* For modes with images, xbm, xpm, & ras */
566 #ifdef HAVE_XPM
567 	{(char *) "-bitmap filename", (char *) "bitmap file (sometimes xpm and ras too)"},
568 #else
569 	{(char *) "-bitmap filename", (char *) "bitmap file (sometimes ras too)"},
570 #endif
571 	{(char *) "-erasemode erase-modename", (char *) "Erase mode to use (to ddisable set to no_fade)"},
572 	{(char *) "-erasedelay num", (char *) "Erase delay for clear screen modes"},
573 	{(char *) "-erasetime num", (char *) "Maximum time (sec) to be used by erase"},
574 	{(char *) "-/+nolock", (char *) "turn on/off no password required"},
575 	{(char *) "-/+inwindow", (char *) "turn on/off making xlock run in a window"},
576 	{(char *) "-/+inroot", (char *) "turn on/off making xlock run in the root window"},
577 	{(char *) "-/+remote", (char *) "turn on/off remote host access"},
578 	{(char *) "-/+mono", (char *) "turn on/off monochrome override"},
579 	{(char *) "-/+allowaccess", (char *) "turn on/off allow new clients to connect"},
580 #ifdef USE_VTLOCK
581 	{(char *) "-vtlock lock-modename", (char *) "turn on vt switching in [" VTLOCKMODE_SWITCH "|" VTLOCKMODE_NOSWITCH "|" VTLOCKMODE_RESTORE "] lock-mode"},
582 
583 #endif
584 #ifndef ALWAYS_ALLOW_ROOT
585 	{(char *) "-/+allowroot", (char *) "turn on/off allow root password to unlock"},
586 #else
587  {(char *) "-/+allowroot", (char *) "turn on/off allow root password to unlock (off ignored)"},
588 #endif
589 	{(char *) "-/+debug", (char *) "whether to use debug xlock (yes/no)"},
590 	{(char *) "-/+description", (char *) "whether to show mode description (yes/no)"},
591 	{(char *) "-/+echokeys", (char *) "turn on/off echo '?' for each password key"},
592 	{(char *) "-echokey char", (char *) "text character to use for echo key, default is '?'"},
593 	{(char *) "-/+enablesaver", (char *) "turn on/off enable X server screen saver"},
594 	{(char *) "-/+resetsaver", (char *) "turn on/off resetting of X server screen saver"},
595 	{(char *) "-/+grabmouse", (char *) "turn on/off grabbing of mouse and keyboard"},
596 	{(char *) "-/+grabserver", (char *) "turn on/off grabbing of server"},
597 	{(char *) "-/+install", (char *) "whether to use private colormap if needed (yes/no)"},
598 	{(char *) "-/+hide", (char *) "turn on/off user background manipulation"},
599 	{(char *) "-/+mousemotion", (char *) "turn on/off sensitivity to mouse"},
600 	{(char *) "-/+sound", (char *) "whether to use sound if configured for it (yes/no)"},
601 	{(char *) "-/+showdate", (char *) "turn on/off date in password window"},
602 	{(char *) "-/+timeelapsed", (char *) "turn on/off clock"},
603 	{(char *) "-/+usefirst", (char *) "turn on/off using the first char typed in password"},
604 	{(char *) "-/+verbose", (char *) "turn on/off verbosity"},
605 	{(char *) "-nice level", (char *) "nice level for xlock process"},
606 	{(char *) "-lockdelay seconds", (char *) "number of seconds until lock"},
607 	{(char *) "-unlockdelay seconds", (char *) "number of seconds until unlock"},
608 	{(char *) "-timeout seconds", (char *) "number of seconds before password times out"},
609 	{(char *) "-font fontname", (char *) "font to use for password prompt"},
610 	{(char *) "-planfont fontname", (char *) "font to use for plan message"},
611 #ifdef USE_GL
612 	{(char *) "-/+showfps", (char *) "turn on/off display of FPS"},
613 	{(char *) "-/+fpstop", (char *) "turn on/off FPS display on top of window"},
614 	{(char *) "-fpsfont fontname", (char *) "font to use for FPS display"},
615 #endif
616 #ifdef USE_MB
617 	{(char *) "-fontset fontsetname", (char *) "fontset to use for Xmb"},
618 	{(char *) "-planfontset fontsetname", (char *) "fontset to use for Xmb"},
619 #endif
620 	{(char *) "-bg color", (char *) "background color to use for password prompt"},
621 	{(char *) "-fg color", (char *) "foreground color to use for password prompt"},
622 	{(char *) "-background color", (char *) "background color to use for password prompt"},
623 	{(char *) "-foreground color", (char *) "foreground color to use for password prompt"},
624 	{(char *) "-username string", (char *) "text string to use for Name prompt"},
625 	{(char *) "-password string", (char *) "text string to use for Password prompt"},
626 	{(char *) "-info string", (char *) "text string to use for instructions"},
627 	{(char *) "-validate string", (char *) "text string to use for validating password message"},
628 	{(char *) "-invalid string", (char *) "text string to use for invalid password message"},
629 	{(char *) "-invalidCapsLock string", (char *) "text string to use for invalid password message with Caps Lock on"},
630 	{(char *) "-geometry geom", (char *) "geometry for non-full screen lock"},
631 	{(char *) "-icongeometry geom", (char *) "geometry for password window (location ignored)"},
632 #ifdef FX
633 	{(char *) "-glgeometry geom", (char *) "geometry for gl modes (location ignored)"},
634 #endif
635 	{(char *) "-/+wireframe", (char *) "turn on/off wireframe"},
636 
637 	{(char *) "-/+use3d", (char *) "turn on/off 3d view"},
638         {(char *) "-delta3d value", (char *) "space between the center of your 2 eyes for 3d mode"},
639 	{(char *) "-none3d color", (char *) "color to be used for null in 3d mode"},
640 	{(char *) "-right3d color", (char *) "color to be used for the right eye in 3d mode"},
641 	{(char *) "-left3d color", (char *) "color to be used for the left eye in 3d mode"},
642 	{(char *) "-both3d color", (char *) "color to be used overlap in 3d mode"},
643 
644     /* For modes with text, marquee & nose */
645    {(char *) "-program programname", (char *) "program to get messages from, usually fortune"},
646 	{(char *) "-messagesfile formatted-filename", (char *) "formatted file of fortunes"},
647 	{(char *) "-messagefile filename", (char *) "text file for mode"},
648 	{(char *) "-message string", (char *) "text for mode"},
649 	{(char *) "-messagefont fontname", (char *) "font for a specific mode"},
650 #if 0
651     /* For automata modes */
652       {(char *) "-neighbors num", (char *) "squares 4 or 8, hexagons 6, triangles 3, 9 or 12"},
653     /* For eyes, julia, and swarm modes */
654 	{(char *) "-/+mouse", (char *) "turn on/off the grabbing the mouse"},
655 #endif
656 
657 #if defined( USE_XLOCKRC ) || defined( FALLBACK_XLOCKRC )
658 	{(char *) "-cpasswd crypted-password", (char *) "text string of encrypted password"},
659 #endif
660 #ifdef USE_AUTO_LOGOUT
661 	{(char *) "-logoutAuto minutes", (char *) "number of minutes until auto logout (not more than forced auto logout time)"},
662 #endif
663 #ifdef USE_BUTTON_LOGOUT
664 	{(char *) "-logoutButton minutes", (char *) "number of minutes until logout button appears (not more than forced button time)"},
665 	{(char *) "-logoutButtonLabel string", (char *) "text string to use inside logout button"},
666 	{(char *) "-logoutButtonHelp string", (char *) "text string to use for logout button help"},
667 	{(char *) "-logoutFailedString string", (char *) "text string to use for failed logout attempts"},
668 #endif
669 #ifdef USE_DTSAVER
670 	{(char *) "-/+dtsaver", (char *) "turn on/off CDE Saver Mode"},
671 #endif
672 #ifdef XINERAMA
673 	{(char *) "-/+xinerama", (char *) "turn on/off Xinerama"},
674 #endif
675 #ifdef USE_SOUND
676 	{(char *) "-locksound string", (char *) "sound to use at locktime"},
677 	{(char *) "-infosound string", (char *) "sound to use for information"},
678 	{(char *) "-validsound string", (char *) "sound to use when password is valid"},
679 	{(char *) "-invalidsound string", (char *) "sound to use when password is invalid"},
680 #endif
681 	{(char *) "-startCmd string", (char *) "command to run at locktime"},
682 	{(char *) "-endCmd string", (char *) "command to run when unlocking"},
683 #ifndef VMS
684 	{(char *) "-pipepassCmd string", (char *) "command into which to pipe the password when unlocking"},
685 #endif
686       {(char *) "-logoutCmd string", (char *) "command to run when automatically logging out"},
687 	{(char *) "-mailCmd string", (char *) "command to run to check for mail"},
688 	{(char *) "-mailIcon string", (char *) "Icon to display when there is mail"},
689 	{(char *) "-nomailIcon string", (char *) "Icon to display when there is no mail"},
690 #ifdef USE_DPMS
691     {(char *) "-dpmsstandby seconds", (char *) "seconds to wait before engaging DPMS standby"},
692     {(char *) "-dpmssuspend seconds", (char *) "seconds to wait before engaging DPMS suspend"},
693 	{(char *) "-dpmsoff seconds", (char *) "seconds to wait before engaging DPMS off"},
694 #endif
695 };
696 
697 #define opDescEntries (sizeof opDesc / sizeof opDesc[0])
698 
699 int         delay;
700 int         count;
701 int         cycles;
702 int         size;
703 int         ncolors;
704 float       saturation;
705 
706 /* For modes with images, xbm, xpm, & ras */
707 char       *bitmap;
708 
709 #ifdef USE_MODULES
710 char       *modulepath;
711 
712 #endif
713 
714 static char *erasemodename;
715 int         erasedelay, erasetime;
716 Bool        nolock;
717 Bool        inwindow;
718 Bool        inroot;
719 Bool        mono;
720 
721 Bool        allowaccess;
722 
723 #ifdef ALWAYS_ALLOW_ROOT
724 Bool        allowroot = 1;
725 
726 #else
727 Bool        allowroot;
728 
729 #endif
730 Bool        debug;
731 Bool        description;
732 Bool        echokeys;
733 char*       echokey;
734 Bool        enablesaver;
735 Bool        resetsaver;
736 Bool        fullrandom = False;
737 Bool        grabmouse;
738 Bool        grabserver;
739 Bool        hide;
740 Bool        install;
741 Bool        mousemotion;
742 Bool        sound;
743 Bool        showdate;
744 Bool        timeelapsed;
745 Bool        usefirst;
746 Bool        verbose;
747 Bool        remote;
748 
749 #ifdef USE_GL
750 Bool        fpsTop;
751 Bool        showfps;
752 char       *fpsfontname;
753 #endif
754 static char *visualname;
755 int         VisualClassWanted;
756 
757 int         nicelevel;
758 int         lockdelay;
759 int         unlockdelay;
760 int         timeout;
761 
762 char       *fontname;
763 char       *planfontname;
764 
765 #ifdef USE_DPMS
766 int         dpmsstandby;
767 int         dpmssuspend;
768 int         dpmsoff;
769 
770 #endif
771 
772 #ifdef USE_MB
773 char       *fontsetname;
774 char       *planfontsetname;
775 
776 #endif
777 char       *background;
778 char       *foreground;
779 char       *text_user;
780 char       *text_pass;
781 
782 #ifdef GLOBAL_UNLOCK
783 char       *text_guser;
784 #endif
785 
786 #ifdef SAFEWORD
787 char       *text_dpass;
788 char       *text_fpass;
789 char       *text_chall;
790 
791 #endif
792 char       *text_info;
793 #ifdef HAVE_KRB5
794 char	   *text_krbinfo;
795 #endif /* HAVE_KRB5 */
796 char       *text_valid;
797 char       *text_invalid;
798 char       *text_invalidCapsLock;
799 char	   *failed_attempt;
800 char	   *failed_attempts;
801 char       *geometry;
802 char       *icongeometry;
803 #ifdef FX
804 char       *glgeometry;
805 
806 #endif
807 
808 Bool        wireframe;
809 
810 Bool        use3d;
811 float       delta3d;
812 char       *none3d;
813 char       *right3d;
814 char       *left3d;
815 char       *both3d;
816 
817 #if defined( USE_XLOCKRC ) || defined( FALLBACK_XLOCKRC )
818 char       *cpasswd;
819 
820 #endif
821 #ifdef USE_AUTO_LOGOUT
822 int         logoutAuto;
823 
824 #endif
825 #ifdef USE_BUTTON_LOGOUT
826 int         enable_button = 1;
827 
828 int         logoutButton;
829 char       *logoutButtonLabel;
830 char       *logoutButtonHelp;
831 char       *logoutFailedString;
832 
833 #endif
834 #ifdef USE_DTSAVER
835 Bool        dtsaver;
836 
837 #endif
838 #ifdef USE_XINERAMA
839 Bool        xinerama;
840 
841 #endif
842 #ifdef USE_SOUND
843 char       *locksound;
844 char       *infosound;
845 char       *validsound;
846 char       *invalidsound;
847 
848 #endif
849 
850 char       *startCmd;
851 char       *endCmd;
852 #ifndef VMS
853 char       *pipepassCmd;
854 #endif
855 char       *logoutCmd;
856 
857 char       *mailCmd;
858 char       *mailIcon;
859 char       *nomailIcon;
860 
861 #ifdef USE_VTLOCK
862 char       *vtlockres;
863 Bool        vtlock;
864 Bool        vtlock_set_active;
865 Bool        vtlock_restore;
866 
867 #endif
868 
869 static argtype genvars[] =
870 {
871 	{(void *) & erasemodename, (char *) "erasemode", (char *) "EraseMode", (char *) "", t_String},
872 	{(void *) & erasedelay, (char *) "erasedelay", (char *) "EraseDelay", (char *) DEF_ERASEDELAY, t_Int},
873 	{(void *) & erasetime, (char *) "erasetime", (char *) "EraseTime", (char *) DEF_ERASETIME, t_Int},
874 	{(void *) & allowaccess, (char *) "allowaccess", (char *) "AllowAccess", (char *) "off", t_Bool},
875 #ifndef ALWAYS_ALLOW_ROOT
876 	{(void *) & allowroot, (char *) "allowroot", (char *) "AllowRoot", (char *) "off", t_Bool},
877 #endif
878 	{(void *) & debug, (char *) "debug", (char *) "Debug", (char *) "off", t_Bool},
879 	{(void *) & description, (char *) "description", (char *) "Description", (char *) "on", t_Bool},
880 	{(void *) & echokeys, (char *) "echokeys", (char *) "EchoKeys", (char *) "off", t_Bool},
881 	{(void *) & echokey, (char *) "echokey", (char *) "EchoKey", (char *) "?", t_String},
882 	{(void *) & enablesaver, (char *) "enablesaver", (char *) "EnableSaver", (char *) "off", t_Bool},
883 	{(void *) & resetsaver, (char *) "resetsaver", (char *) "ResetSaver", (char *) "on", t_Bool},
884 	{(void *) & grabmouse, (char *) "grabmouse", (char *) "GrabMouse", (char *) "on", t_Bool},
885 	{(void *) & grabserver, (char *) "grabserver", (char *) "GrabServer", (char *) "off", t_Bool},
886 	{(void *) & hide, (char *) "hide", (char *) "Hide", (char *) "on", t_Bool},
887 	{(void *) & install, (char *) "install", (char *) "Install", (char *) "on", t_Bool},
888 	{(void *) & mousemotion, (char *) "mousemotion", (char *) "MouseMotion", (char *) "off", t_Bool},
889 	{(void *) & mono, (char *) "mono", (char *) "Mono", (char *) "off", t_Bool},
890 	{(void *) & sound, (char *) "sound", (char *) "Sound", (char *) "off", t_Bool},
891 #ifdef USE_GL
892 	{(void *) & showfps, (char *) "showfps", (char *) "ShowFps", (char *) "off", t_Bool},
893 	{(void *) & fpsTop, (char *) "fpstop", (char *) "FpsTop", (char *) "on", t_Bool},
894 	{(void *) & fpsfontname, (char *) "fpsfont", (char *) "FpsFont", (char *) DEF_FONT, t_String},
895 #endif
896 	{(void *) & showdate, (char *) "showdate", (char *) "ShowDate", (char *) "on", t_Bool},
897 	{(void *) & timeelapsed, (char *) "timeelapsed", (char *) "TimeElapsed", (char *) "off", t_Bool},
898 	{(void *) & usefirst, (char *) "usefirst", (char *) "UseFirst", (char *) "on", t_Bool},
899 	{(void *) & verbose, (char *) "verbose", (char *) "Verbose", (char *) "off", t_Bool},
900 	{(void *) & visualname, (char *) "visual", (char *) "Visual", (char *) "", t_String},
901 	{(void *) & nicelevel, (char *) "nice", (char *) "Nice", (char *) DEF_NICE, t_Int},
902 	{(void *) & lockdelay, (char *) "lockdelay", (char *) "LockDelay", (char *) DEF_LOCKDELAY, t_Int},
903 	{(void *) & unlockdelay, (char *) "unlockdelay", (char *) "UnLockDelay", (char *) DEF_UNLOCKDELAY, t_Int},
904 	{(void *) & timeout, (char *) "timeout", (char *) "Timeout", (char *) DEF_TIMEOUT, t_Int},
905 	{(void *) & fontname, (char *) "font", (char *) "Font", (char *) DEF_FONT, t_String},
906 	{(void *) & planfontname, (char *) "planfont", (char *) "PlanFont", (char *) DEF_PLANFONT, t_String},
907 #ifdef USE_MB
908 	{(void *) & fontsetname, (char *) "fontset", (char *) "FontSet", (char *) DEF_FONTSET, t_String},
909 	{(void *) & planfontsetname, (char *) "planfontset", (char *) "PlanFontSet", (char *) DEF_PLANFONTSET, t_String},
910 #endif
911 	{(void *) & background, (char *) "background", (char *) "Background", (char *) DEF_BG, t_String},
912 	{(void *) & foreground, (char *) "foreground", (char *) "Foreground", (char *) DEF_FG, t_String},
913 	{(void *) & text_user, (char *) "username", (char *) "Username", (char *) DEF_NAME, t_String},
914 	{(void *) & text_pass, (char *) "password", (char *) "Password", (char *) DEF_PASS, t_String},
915 #ifdef GLOBAL_UNLOCK
916 	{(void *) & text_guser, (char *) "globaluser", (char *) "GlobalUser", (char *) DEF_GUSER, t_String},
917 #endif
918 
919 #ifdef SAFEWORD
920 	{(void *) & text_dpass, (char *) "dynpass", (char *) "Dynpass", (char *) DEF_DPASS, t_String},
921 	{(void *) & text_fpass, (char *) "fixpass", (char *) "Fixpass", (char *) DEF_FPASS, t_String},
922 	{(void *) & text_chall, (char *) "challenge", (char *) "Challenge", (char *) DEF_CHALL, t_String},
923 #endif
924 	{(void *) & text_info, (char *) "info", (char *) "Info", (char *) DEF_INFO, t_String},
925 #ifdef HAVE_KRB5
926 	{(void *) & text_krbinfo, (char *) "kerberosinfo", (char *) "KerberosInfo", (char *) DEF_KRBINFO, t_String},
927 #endif /* HAVE_KRB5 */
928 	{(void *) & text_valid, (char *) "validate", (char *) "Validate", (char *) DEF_VALID, t_String},
929 	{(void *) & text_invalid, (char *) "invalid", (char *) "Invalid", (char *) DEF_INVALID, t_String},
930 	{(void *) & text_invalidCapsLock, (char *) "invalidCapsLock", (char *) "InvalidCapsLock", (char *) DEF_INVALIDCAPSLOCK, t_String},
931 	{(void *) & failed_attempt, (char *) "attempt", (char *) "Attempt", (char *) DEF_COUNT_FAILED, t_String},
932 	{(void *) & failed_attempts, (char *) "attempts", (char *) "Attempts", (char *) DEF_COUNTS_FAILED, t_String},
933 	{(void *) & geometry, (char *) "geometry", (char *) "Geometry", (char *) DEF_GEOMETRY, t_String},
934 	{(void *) & icongeometry, (char *) "icongeometry", (char *) "IconGeometry", (char *) DEF_ICONGEOMETRY, t_String},
935 #ifdef FX
936 	{(void *) & glgeometry, (char *) "glgeometry", (char *) "GLGeometry", (char *) DEF_GLGEOMETRY, t_String},
937 #endif
938 	{(void *) & wireframe, (char *) "wireframe", (char *) "WireFrame", (char *) "off", t_Bool},
939 
940 	{(void *) & use3d, (char *) "use3d", (char *) "Use3D", (char *) "off", t_Bool},
941 	{(void *) & delta3d, (char *) "delta3d", (char *) "Delta3D", (char *) DEF_DELTA3D, t_Float},
942 	{(void *) & none3d, (char *) "none3d", (char *) "None3D", (char *) DEF_NONE3D, t_String},
943 	{(void *) & right3d, (char *) "right3d", (char *) "Right3D", (char *) DEF_RIGHT3D, t_String},
944 	{(void *) & left3d, (char *) "left3d", (char *) "Left3D", (char *) DEF_LEFT3D, t_String},
945 	{(void *) & both3d, (char *) "both3d", (char *) "Both3D", (char *) DEF_BOTH3D, t_String},
946 
947 	{(void *) & program, (char *) "program", (char *) "Program", (char *) DEF_PROGRAM, t_String},
948 	{(void *) & messagesfile, (char *) "messagesfile", (char *) "Messagesfile", (char *) DEF_MESSAGESFILE, t_String},
949 	{(void *) & messagefile, (char *) "messagefile", (char *) "Messagefile", (char *) DEF_MESSAGEFILE, t_String},
950 	{(void *) & message, (char *) "message", (char *) "Message", (char *) DEF_MESSAGE, t_String},
951 	{(void *) & messagefontname, (char *) "messagefont", (char *) "MessageFont", (char *) DEF_MESSAGEFONT, t_String},
952 #if 0
953 	{(void *) & neighbors, (char *) "neighbors", (char *) "Neighbors", (char *) DEF_NEIGHBORS, t_Int},
954 	{(void *) & mouse, (char *) "mouse", (char *) "Mouse", (char *) DEF_MOUSE, t_Bool},
955 #endif
956 
957 #if defined( USE_XLOCKRC ) || defined( FALLBACK_XLOCKRC )
958 	{(void *) & cpasswd, (char *) "cpasswd", (char *) "cpasswd", (char *) "", t_String},
959 #endif
960 #ifdef USE_AUTO_LOGOUT
961 	{(void *) & logoutAuto, (char *) "logoutAuto", (char *) "LogoutAuto", (char *) DEF_AUTO_LOGOUT, t_Int},
962 #endif
963 #ifdef USE_BUTTON_LOGOUT
964 	{(void *) & logoutButton, (char *) "logoutButton", (char *) "LogoutButton", (char *) DEF_BUTTON_LOGOUT, t_Int},
965 	{(void *) & logoutButtonLabel, (char *) "logoutButtonLabel",
966 	 "LogoutButtonLabel", (char *) DEF_BTN_LABEL, t_String},
967 	{(void *) & logoutButtonHelp, (char *) "logoutButtonHelp",
968 	 "LogoutButtonHelp", (char *) DEF_BTN_HELP, t_String},
969 	{(void *) & logoutFailedString, (char *) "logoutFailedString",
970 	 "LogoutFailedString", (char *) DEF_FAIL, t_String},
971 #endif
972 #ifdef USE_SOUND
973 	{(void *) & locksound, (char *) "locksound", (char *) "LockSound", (char *) DEF_LOCKSOUND, t_String},
974 	{(void *) & infosound, (char *) "infosound", (char *) "InfoSound", (char *) DEF_INFOSOUND, t_String},
975 	{(void *) & validsound, (char *) "validsound", (char *) "ValidSound", (char *) DEF_VALIDSOUND, t_String},
976 	{(void *) & invalidsound, (char *) "invalidsound", (char *) "InvalidSound", (char *) DEF_INVALIDSOUND, t_String},
977 #endif
978 	{(void *) & startCmd, (char *) "startCmd", (char *) "StartCmd", (char *) "", t_String},
979 	{(void *) & endCmd, (char *) "endCmd", (char *) "EndCmd", (char *) "", t_String},
980 #ifndef VMS
981 	{(void *) & pipepassCmd, (char *) "pipepassCmd", (char *) "PipePassCmd", (char *) "", t_String},
982 #endif
983 	{(void *) & logoutCmd, (char *) "logoutCmd", (char *) "LogoutCmd", (char *) "", t_String},
984 #ifdef USE_DPMS
985 	{(void *) & dpmsstandby, (char *) "dpmsstandby", (char *) "DPMSStandby", (char *) DEF_DPMSSTANDBY, t_Int},
986 	{(void *) & dpmssuspend, (char *) "dpmssuspend", (char *) "DPMSSuspend", (char *) DEF_DPMSSUSPEND, t_Int},
987 	{(void *) & dpmsoff, (char *) "dpmsoff", (char *) "DPMSOff", (char *) DEF_DPMSOFF, t_Int},
988 #endif
989 
990 	{(void *) & mailCmd, (char *) "mailCmd", (char *) "MailCmd", (char *) DEF_MAILAPP, t_String},
991      	{(void *) & mailIcon, (char *) "mailIcon", (char *) "MailIcon", (char *) DEF_MAILAPP, t_String},
992 	{(void *) & nomailIcon, (char *) "nomailIcon", (char *) "NomailIcon", (char *) DEF_MAILAPP, t_String},
993 #ifdef USE_VTLOCK
994 	{(void *) & vtlockres, (char *) "vtlock", (char *) "VtLock", DEF_VTLOCK, t_String},
995 #endif
996 #if 0
997     /* These resources require special handling.  They must be examined
998      * before the display is opened.  They are evaluated by individual
999      * calls to GetResource(), so they should not be evaluated again here.
1000      * For example, X-terminals need this special treatment.
1001      */
1002 	{(void *) & nolock, (char *) "nolock", (char *) "NoLock", (char *) "off", t_Bool},
1003 	{(void *) & inwindow, (char *) "inwindow", (char *) "InWindow", (char *) "off", t_Bool},
1004 	{(void *) & inroot, (char *) "inroot", (char *) "InRoot", (char *) "off", t_Bool},
1005 	{(void *) & remote, (char *) "remote", (char *) "Remote", (char *) "off", t_Bool},
1006 #endif
1007 };
1008 
1009 #define NGENARGS (sizeof genvars / sizeof genvars[0])
1010 
1011 static argtype modevars[] =
1012 {
1013 	{(void *) & delay, (char *) "delay", (char *) "Delay", (char *) DEF_DELAY, t_Int},
1014 	{(void *) & count, (char *) "count", (char *) "Count", (char *) DEF_COUNT, t_Int},
1015 	{(void *) & cycles, (char *) "cycles", (char *) "Cycles", (char *) DEF_CYCLES, t_Int},
1016 	{(void *) & size, (char *) "size", (char *) "Size", (char *) DEF_SIZE, t_Int},
1017 	{(void *) & ncolors, (char *) "ncolors", (char *) "NColors", (char *) DEF_NCOLORS, t_Int},
1018 	{(void *) & saturation, (char *) "saturation", (char *) "Saturation", (char *) DEF_SATURATION, t_Float},
1019 	{(void *) & bitmap, (char *) "bitmap", (char *) "Bitmap", (char *) DEF_BITMAP, t_String}
1020 };
1021 
1022 #define NMODEARGS (sizeof modevars / sizeof modevars[0])
1023 
1024 extern void checkResources(void);
1025 
1026 static int  modevaroffs[NMODEARGS] =
1027 {
1028 	offsetof(LockStruct, def_delay),
1029 	offsetof(LockStruct, def_count),
1030 	offsetof(LockStruct, def_cycles),
1031 	offsetof(LockStruct, def_size),
1032 	offsetof(LockStruct, def_ncolors),
1033 	offsetof(LockStruct, def_saturation),
1034 	offsetof(LockStruct, def_bitmap)
1035 };
1036 
1037 #ifdef VMS
1038 static char *
stripname(char * string)1039 stripname(char *string)
1040 {
1041 	char       *characters;
1042 
1043 	while (string && *string++ != ']');
1044 	characters = string;
1045 	while (characters)
1046 		if (*characters == '.') {
1047 			*characters = '\0';
1048 			return string;
1049 		} else
1050 			characters++;
1051 	return string;
1052 }
1053 #endif
1054 
1055 static void
Syntax(const char * badOption)1056 Syntax(const char *badOption)
1057 {
1058 	int         col, len, i;
1059 
1060 	(void) fprintf(stderr, "%s:  bad command line option \"%s\"\n\n",
1061 		       ProgramName, badOption);
1062 
1063 	(void) fprintf(stderr, "usage:  %s", ProgramName);
1064 	col = 8 + strlen(ProgramName);
1065 	for (i = 0; i < (int) opDescEntries; i++) {
1066 		len = 3 + strlen(opDesc[i].opt);	/* space [ string ] */
1067 		if (col + len > 79) {
1068 			(void) fprintf(stderr, "\n   ");	/* 3 spaces */
1069 			col = 3;
1070 		}
1071 		(void) fprintf(stderr, " [%s]", opDesc[i].opt);
1072 		col += len;
1073 	}
1074 
1075 	len = 8 + strlen(LockProcs[0].cmdline_arg);
1076 	if (col + len > 79) {
1077 		(void) fprintf(stderr, "\n   ");	/* 3 spaces */
1078 		col = 3;
1079 	}
1080 	(void) fprintf(stderr, " [-mode %s", LockProcs[0].cmdline_arg);
1081 	col += len;
1082 	for (i = 1; i < numprocs; i++) {
1083 		len = 3 + strlen(LockProcs[i].cmdline_arg);
1084 		if (col + len > 79) {
1085 			(void) fprintf(stderr, "\n   ");	/* 3 spaces */
1086 			col = 3;
1087 		}
1088 		(void) fprintf(stderr, " | %s", LockProcs[i].cmdline_arg);
1089 		col += len;
1090 	}
1091 	(void) fprintf(stderr, "]\n");
1092 
1093 	(void) fprintf(stderr, "\nType %s -help for a full description.\n\n",
1094 		       ProgramName);
1095 	exit(1);
1096 }
1097 
1098 static void
Help(void)1099 Help(void)
1100 {
1101 	int         i;
1102 
1103 	(void) printf("usage:\n        %s [-options ...]\n\n", ProgramName);
1104 	(void) printf("where options include:\n");
1105 	for (i = 0; i < (int) opDescEntries; i++) {
1106 		(void) printf("    %-28s %s\n", opDesc[i].opt, opDesc[i].desc);
1107 	}
1108 
1109 	(void) printf("    %-28s %s\n", "-mode mode", "animation mode");
1110 	(void) printf("    where mode is one of:\n");
1111 	for (i = 0; i < numprocs; i++) {
1112 		int         j;
1113 
1114 		(void) printf("          %-23s %s\n",
1115 			      LockProcs[i].cmdline_arg, LockProcs[i].desc);
1116 		for (j = 0; j < LockProcs[i].msopt->numvarsdesc; j++) {
1117 			if (LockProcs[i].msopt->desc == NULL)
1118 				continue;
1119 			(void) printf("              %-23s %s\n",
1120 				LockProcs[i].msopt->desc[j].opt,
1121 				LockProcs[i].msopt->desc[j].desc);
1122 		}
1123 	}
1124 	(void) printf("\n");
1125 
1126 	exit(0);
1127 }
1128 
1129 static void
Version(void)1130 Version(void)
1131 {
1132 	(void) printf("XLock version xlockmore-%s\n", VERSION);
1133 	exit(0);
1134 }
1135 
1136 static void
checkSpecialArgs(int argc,char ** argv)1137 checkSpecialArgs(int argc, char **argv)
1138 {
1139 	int         i;
1140 
1141 	for (i = 0; i < argc; i++) {
1142 		if (!strcmp(argv[i], "-help"))
1143 			Help();
1144 		if (!strcmp(argv[i], "-version"))
1145 			Version();
1146 #ifdef CHECK_OLD_ARGS
1147 		{
1148 			static char *deprecated_args[] =
1149 	{(char *) "-v", (char *) "-imagefile", (char *) "-mfont",
1150 	 (char *) "-rule3d", (char *) "-life3dfile",
1151 	 (char *) "-mouse", (char *) "-shift", (char *) "-tshift"};
1152 			static char *current_args[] =
1153 	{(char *) "-verbose", (char *) "-bitmap", (char *) "-messagefont",
1154 	 (char *) "-rule", (char *) "-lifefile",
1155 	 (char *) "-trackmouse", (char *) "-cycle", (char *) "-cycle"};
1156 			int         j;
1157 
1158 			for (j = 0; j < (int) ((sizeof current_args) / sizeof (*current_args)); j++)
1159 				if (!strcmp(argv[i], deprecated_args[j])) {
1160 					(void) printf("%s deprecated, use %s\n",
1161 					deprecated_args[j], current_args[j]);
1162 					exit(0);
1163 				}
1164 		}
1165 #endif
1166 	}
1167 }
1168 
1169 static void
DumpResources(void)1170 DumpResources(void)
1171 {
1172 	int         i, j;
1173 
1174 	(void) printf("%s.mode: %s\n", classname, DEF_MODE);
1175 
1176 	for (i = 0; i < (int) NGENARGS; i++)
1177 		(void) printf("%s.%s: %s\n",
1178 			      classname, genvars[i].name, genvars[i].def);
1179 
1180 	for (i = 0; i < numprocs; i++) {
1181 		(void) printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
1182 			      "delay", LockProcs[i].def_delay);
1183 		(void) printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
1184 			      "count", LockProcs[i].def_count);
1185 		(void) printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
1186 			      "cycles", LockProcs[i].def_cycles);
1187 		(void) printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
1188 			      "size", LockProcs[i].def_size);
1189 		(void) printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
1190 			      "ncolors", LockProcs[i].def_ncolors);
1191 		(void) printf("%s.%s.%s: %g\n", classname, LockProcs[i].cmdline_arg,
1192 			      "saturation", LockProcs[i].def_saturation);
1193 		(void) printf("%s.%s.%s: %s\n", classname, LockProcs[i].cmdline_arg,
1194 			      "bitmap",
1195 		   (LockProcs[i].def_bitmap) ? LockProcs[i].def_bitmap : "");
1196 		for (j = 0; j < LockProcs[i].msopt->numvarsdesc; j++)
1197 			(void) printf("%s.%s.%s: %s\n", classname, LockProcs[i].cmdline_arg,
1198 				      LockProcs[i].msopt->vars[j].name,
1199 				      LockProcs[i].msopt->vars[j].def);
1200 	}
1201 	exit(0);
1202 }
1203 
1204 static void
LowerString(char * s)1205 LowerString(char *s)
1206 {
1207 
1208 	while (*s) {
1209 		if (isupper((int) *s))
1210 			*s += ('a' - 'A');
1211 		s++;
1212 	}
1213 }
1214 
1215 static void
GetResource(XrmDatabase database,const char * parentName,const char * parentClassName,const char * name,const char * className,int valueType,char * def,void * valuep)1216 GetResource(XrmDatabase database,
1217 	   const char *parentName, const char *parentClassName,
1218      const char *name, const char *className, int valueType, char *def,
1219      void* valuep)
1220 {
1221 	char       *type;
1222 	XrmValue    value;
1223 	char       *string;
1224 	char       *buffer;
1225 	char       *fullName;
1226 	char       *fullClassName;
1227 	int         len, temp;
1228 
1229 	fullName = (char *) malloc(strlen(parentName) + strlen(name) + 2);
1230 	fullClassName = (char *) malloc(strlen(parentClassName) +
1231 					strlen(className) + 2);
1232 
1233 	(void) sprintf(fullName, "%s.%s", parentName, name);
1234 	(void) sprintf(fullClassName, "%s.%s", parentClassName, className);
1235 	temp = XrmGetResource(database, fullName, fullClassName, &type, &value);
1236 	free(fullName);
1237 	free(fullClassName);
1238 
1239 	if (temp) {
1240 		string = value.addr;
1241 		len = value.size - 1;
1242 	} else {
1243 		string = def;
1244 		if (!string || !*string) {
1245 			*((caddr_t *) valuep) = NULL;
1246 			return;
1247 		}
1248 		len = strlen(string);
1249 	}
1250 
1251 	buffer = (char *) malloc(strlen(string) + 1);
1252 	(void) strcpy(buffer, string);
1253 
1254 	switch (valueType) {
1255 		case t_String:
1256 			{
1257 /*-
1258  * PURIFY 4.2 on Solaris 2 and on SunOS4 reports a memory leak on the following
1259  * line. It leaks as many bytes as there are characters in the string + 1. */
1260 				char       *s = (char *) malloc(len + 1);
1261 
1262 				if (s == (char *) NULL) {
1263 					(void) sprintf(error_buf,
1264 						"%s: GetResource - could not allocate memory",
1265 						(strlen(ProgramName) < ERROR_BUF - ERROR_LINE) ?
1266 						ProgramName : DEFAULT_NAME);
1267 					error(error_buf);
1268 				}
1269 				(void) strncpy(s, string, len);
1270 				s[len] = '\0';
1271 				*((char **) valuep) = s;
1272 			}
1273 			break;
1274 		case t_Float:
1275 			*((float *) valuep) = (float) atof(buffer);
1276 			break;
1277 		case t_Int:
1278 			*((int *) valuep) = atoi(buffer);
1279 			break;
1280 		case t_Bool:
1281 			LowerString(buffer);
1282 			*((int *) valuep) = (!strcmp(buffer, "true") ||
1283 					     !strcmp(buffer, "on") ||
1284 					     !strcmp(buffer, "enabled") ||
1285 				      !strcmp(buffer, "yes")) ? True : False;
1286 			break;
1287 	}
1288 	free(buffer);
1289 }
1290 
1291 static      XrmDatabase
parsefilepath(char * xfilesearchpath,const char * typeName,char * className,char * customName)1292 parsefilepath(char *xfilesearchpath, const char *typeName,
1293         char *className, char *customName)
1294 {
1295 	XrmDatabase database = (XrmDatabase) NULL;
1296 	char       *appdefaults;
1297 	char       *src;
1298 	char       *dst;
1299 	int         i, maxlen;
1300 
1301 	if (!customName)
1302 		customName = (char *) "";
1303 	i = maxlen = 0;
1304 	for (src = xfilesearchpath; *src != '\0'; src++) {
1305 		if (*src == '%') {
1306 			src++;
1307 			switch (*src) {
1308 				case '%':
1309 				case ':':
1310 					i++;
1311 					break;
1312 				case 'T':
1313 					i += strlen(typeName);
1314 					break;
1315 				case 'N':
1316 					i += strlen(className);
1317 					break;
1318 				case 'C':
1319 					i += strlen(customName);
1320 					break;
1321 				default:
1322 					break;
1323 			}
1324 #ifdef VMS
1325 		} else if (*src == '#') {	/* Colons required in VMS use # */
1326 #else
1327 		} else if (*src == ':') {
1328 #endif
1329 			if (i > maxlen)
1330 				maxlen = i;
1331 			i = 0;
1332 		} else
1333 			i++;
1334 	}
1335 	if (i > maxlen)
1336 		maxlen = i;
1337 
1338 	/* appdefaults will be at most this long */
1339 	appdefaults = (char *) malloc(maxlen + 1);
1340 
1341 	src = xfilesearchpath;
1342 	dst = appdefaults;
1343 	*dst = '\0';
1344 	for (;;) {
1345 		if (*src == '%') {
1346 			src++;
1347 			switch (*src) {
1348 				case '%':
1349 				case ':':
1350 					*dst++ = *src++;
1351 					*dst = '\0';
1352 					break;
1353 				case 'T':
1354 					(void) strcat(dst, typeName);
1355 					src++;
1356 					dst += strlen(typeName);
1357 					break;
1358 				case 'N':
1359 					(void) strcat(dst, className);
1360 					src++;
1361 					dst += strlen(className);
1362 					break;
1363 				case 'C':
1364 					(void) strcat(dst, customName);
1365 					src++;
1366 					dst += strlen(customName);
1367 					break;
1368 				case 'S':
1369 					src++;
1370 					break;
1371 				default:
1372 					src++;
1373 					break;
1374 			}
1375 #ifdef VMS
1376 		} else if (*src == '#') {	/* Colons required in VMS use # */
1377 #else
1378 		} else if (*src == ':') {
1379 #endif
1380 			database = XrmGetFileDatabase(appdefaults);
1381 			if (database == NULL) {
1382 				dst = appdefaults;
1383 				src++;
1384 			} else
1385 				break;
1386 		} else if (*src == '\0') {
1387 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
1388    * line.  PURIFY 4.0.1 on SunOS4 reports this also when using X11R5, but not
1389    * with OpenWindow 3.0 (X11R4 based). */
1390 			database = XrmGetFileDatabase(appdefaults);
1391 			break;
1392 		} else {
1393 			*dst++ = *src++;
1394 			*dst = '\0';
1395 		}
1396 	}
1397 	free(appdefaults);
1398 	return database;
1399 }
1400 
1401 #ifdef VMS
1402 /*-
1403  * FUNCTIONAL DESCRIPTION:
1404  * int get_info (chan, item, ret_str, ret_len)
1405  * Fetch a single characteristics from the pseudo-workstation
1406  * device and return the information.
1407  * (Taken and modified from the v5.4 fiche. PPL/SG 2/10/91
1408  * FORMAL PARAMETERS:
1409  *      chan:   the device channel
1410  *      item:   the characteristic to show
1411  *      ret_str: str pointer to information
1412  * ret_len: length of above string
1413  *  IMPLICIT INPUTS:
1414  *      none
1415  *  IMPLICIT OUTPUTS:
1416  *      none
1417  *  COMPLETION CODES:
1418  * errors returned by SYS$QIO
1419  *  SIDE EFFECTS:
1420  *      none
1421  * Hacked from Steve Garrett's xservername (as posted to INFO-VAX)
1422  */
1423 
1424 int
get_info(unsigned long chan,unsigned long item,char * ret_str,unsigned long * ret_len)1425 get_info(unsigned long chan, unsigned long item,
1426 	 char *ret_str, unsigned long *ret_len)
1427 {
1428 	unsigned long iosb[2];
1429 	int         status;
1430 	char        itembuf[BUFSIZE];
1431 	struct dsc$descriptor itemval;
1432 
1433 	itemval.dsc$w_length = BUFSIZE;
1434 	itemval.dsc$b_dtype = 0;
1435 	itemval.dsc$b_class = 0;
1436 	itemval.dsc$a_pointer = &itembuf[0];
1437 
1438 	status = sys$qiow(0, chan, IO$_SENSEMODE | IO$M_WS_DISPLAY, &iosb, 0, 0,
1439 			  itemval.dsc$a_pointer,
1440 			  itemval.dsc$w_length,
1441 			  item, 0, 0, 0);
1442 	if (status != SS$_NORMAL)
1443 		return (status);
1444 	if (iosb[0] != SS$_NORMAL)
1445 		return (iosb[0]);
1446 
1447 	itemval.dsc$w_length = iosb[1];
1448 	*ret_len = iosb[1];
1449 	itembuf[*ret_len] = 0;
1450 	(void) strcpy(ret_str, &itembuf[0]);
1451 
1452 	return (status);
1453 }
1454 
1455 
1456 /* routine that will return descripter of asciz string */
1457 
1458 static int
descr(char * name)1459 descr(char *name)
1460 {
1461 	static      $dscp(d1, 0, 0);
1462 	static      $dscp(d2, 0, 0);
1463 	static      $dscp(d3, 0, 0);
1464 	static      $dscp(d4, 0, 0);
1465 	static      $dscp(d5, 0, 0);
1466 	static      $dscp(d6, 0, 0);
1467 	static dsc *tbl[] =
1468 	{&d1, &d2, &d3, &d4, &d5, &d6};
1469 	static int  didx = 0;
1470 
1471 	if (didx == 6)
1472 		didx = 0;
1473 
1474 	tbl[didx]->len = strlen(name);
1475 	tbl[didx]->ptr = name;
1476 
1477 	return (int) tbl[didx++];
1478 }
1479 
1480 #endif
1481 
1482 static void
openDisplay(Display ** displayp)1483 openDisplay(Display ** displayp)
1484 {
1485 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
1486  * the following line. */
1487 	if (!(*displayp = XOpenDisplay((displayname) ? displayname : ""))) {
1488 		int pnl = strlen(ProgramName);
1489 		int dnl = (displayname) ? strlen(displayname) : 0;
1490 
1491 		pnl = (pnl < ERROR_BUF - ERROR_LINE) ? pnl :
1492 			strlen(DEFAULT_NAME);
1493 		(void) sprintf(error_buf,
1494 			"%s: unable to open display %s.\n",
1495 			((strlen(ProgramName) < ERROR_BUF - ERROR_LINE) ?
1496 			ProgramName : DEFAULT_NAME),
1497 			(dnl + pnl < ERROR_BUF - ERROR_LINE) ?
1498 			((displayname) ? displayname : "") : "");
1499 		error(error_buf);
1500 	}
1501 	displayname = DisplayString(*displayp);
1502 }
1503 
1504 #ifdef SOLARIS2
1505 extern struct hostent *gethostbyname(const char *);
1506 #else
1507 #if defined(__cplusplus) || defined(c_plusplus)		/* !__bsdi__ */
1508 /* #include <netdb.h> */
1509 #if !HAVE_GETHOSTNAME
1510 #if 0
1511 	extern int  gethostname(char *, size_t);
1512 	extern struct hostent *gethostbyname(const char *);
1513 
1514 #endif
1515 #else
1516 #if 1
1517 extern int  gethostname(char *, size_t);
1518 #else
1519 #define gethostname(name,namelen) sysinfo(SI_HOSTNAME,name,namelen)
1520 #endif
1521 #endif
1522 #endif
1523 #endif
1524 static void
checkDisplay(void)1525 checkDisplay(void)
1526 {
1527 #ifndef WIN32
1528 	struct hostent *host;
1529 
1530 	/*
1531 	 * only restrict access to other displays if we are locking and if the
1532 	 * Remote resource is not set.
1533 	 */
1534 	if (nolock || inwindow || inroot)
1535 		remote = True;
1536 
1537 	if (gethostname(hostname, MAXHOSTNAMELEN)) {
1538 #ifdef VMS
1539 	    int val;
1540 	    struct dsc$descriptor itemval;
1541 
1542 	    itemval.dsc$w_length = MAXHOSTNAMELEN;
1543 	    itemval.dsc$b_dtype = 0;
1544 	    itemval.dsc$b_class = 0;
1545 	    itemval.dsc$a_pointer = hostname;
1546 
1547 	    val = SYI$_NODENAME;
1548 
1549 	    if ( LIB$GETSYI( &val , 0 , &itemval , 0 , 0 , 0 ) != SS$_NORMAL )
1550 	    {
1551 #endif
1552 
1553 		(void) sprintf(error_buf,
1554 			"%s: Can not get local hostname.\n",
1555 			(strlen(ProgramName) < ERROR_BUF - ERROR_LINE) ?
1556 			ProgramName : DEFAULT_NAME);
1557 		error(error_buf);
1558 	}
1559 #ifdef VMS
1560 	}
1561 	if (!remote && ((displayname[0] == '_') |
1562 			((displayname[0] == 'W') &
1563 			 (displayname[1] == 'S') &
1564 			 (displayname[2] == 'A')))) {	/* this implies a v5.4 system. The return
1565 							   value is a device name, which must be
1566 							   interrogated to find the real information */
1567 		unsigned long chan;
1568 		unsigned int status;
1569 		unsigned long len;
1570 		char        server_transport[100];
1571 
1572 		status = sys$assign(descr(displayname), &chan, 0, 0);
1573 		if (!(status & 1))
1574 			displayname = " ";
1575 		else {
1576 			status = get_info(chan, DECW$C_WS_DSP_TRANSPORT,
1577 					  server_transport, &len);
1578 			if (!(status & 1))
1579 				exit(status);
1580 
1581 			if (strcmp(server_transport, "LOCAL")) {
1582 				int pnl = strlen(ProgramName);
1583 				int dnl = (displayname) ?
1584 					strlen(displayname) : 0;
1585 
1586 				(void) strcat(displayname, "'s display via ");
1587 				(void) strncat(displayname, server_transport, len);
1588 				pnl = (pnl < ERROR_BUF - ERROR_LINE) ?
1589 					pnl : strlen(DEFAULT_NAME);
1590 				(void) sprintf(error_buf,
1591 					"%s: can not lock %s\n",
1592 					(strlen(ProgramName) < ERROR_BUF - ERROR_LINE) ?
1593 					ProgramName : DEFAULT_NAME,
1594 					(dnl + pnl < ERROR_BUF - ERROR_LINE) ?
1595 					((displayname) ? displayname : "") : "");
1596 				error(error_buf);
1597 			}
1598 		}
1599 	} else {
1600 #endif /* VMS */
1601 
1602 		if (displayname != NULL) {
1603 			char       *colon = (char *) strchr(displayname, ':');
1604 			int         n = colon - displayname;
1605 
1606 			if (colon == NULL) {
1607 				int pnl = strlen(ProgramName);
1608 				int dnl = (displayname) ?
1609 					strlen(displayname) : 0;
1610 
1611 				pnl = (pnl < ERROR_BUF - ERROR_LINE) ?
1612 					pnl : strlen(DEFAULT_NAME);
1613 				(void) sprintf(error_buf,
1614 					"%s: Malformed -display argument, \"%s\"\n",
1615 					(strlen(ProgramName) < ERROR_BUF - ERROR_LINE) ?
1616 					ProgramName : DEFAULT_NAME,
1617 					(dnl + pnl < ERROR_BUF - ERROR_LINE) ?
1618 					((displayname) ? displayname : "") : "");
1619 				error(error_buf);
1620 			}
1621 			if (!remote && n
1622 			    && strncmp(displayname, "unix", n)
1623 			    && strncmp(displayname, "localhost", n)) {
1624 				int         badhost = 1;
1625 				char      **hp;
1626 
1627 				if (!(host = (struct hostent *) gethostbyname(hostname))) {
1628 					if (debug || verbose) {
1629 						(void) fprintf(stderr, "%s: Can not get hostbyname.\n",
1630 							       ProgramName);
1631 						(void) fprintf(stderr,
1632 							       "Contact your administrator to fix /etc/hosts.\n");
1633 					}
1634 				} else if (strncmp(displayname, host->h_name, n)) {
1635 					for (hp = host->h_aliases; *hp; hp++) {
1636 						if (!strncmp(displayname, *hp, n)) {
1637 							badhost = 0;
1638 							break;
1639 						}
1640 					}
1641 					if (badhost) {
1642 						int pnl = strlen(ProgramName);
1643 						int dnl = (displayname) ?
1644 							strlen(displayname) : 0;
1645 
1646 						*colon = (char) 0;
1647 						error(error_buf);
1648 
1649 						pnl = (pnl < ERROR_BUF - ERROR_LINE) ?
1650 							pnl : strlen(DEFAULT_NAME);
1651 						(void) sprintf(error_buf,
1652 							"%s: can not lock %s's display\n",
1653 							(strlen(ProgramName) < ERROR_BUF - ERROR_LINE) ?
1654 							ProgramName : DEFAULT_NAME,
1655 							(dnl + pnl <
1656 							ERROR_BUF - ERROR_LINE) ?
1657 							((displayname) ? displayname : "") : "");
1658 						error(error_buf);
1659 					}
1660 				}
1661 			}
1662 		}
1663 #ifdef VMS
1664 	}
1665 #endif
1666 #endif /* !WIN32 */
1667 }
1668 
1669 static void
printvar(char * className,argtype var)1670 printvar(char *className, argtype var)
1671 {
1672 	switch (var.type) {
1673 		case t_String:
1674 			(void) fprintf(stderr, "%s.%s: %s\n",
1675 				       className, var.name,
1676 			 (*((char **) var.var)) ? *((char **) var.var) : "");
1677 			break;
1678 		case t_Float:
1679 			(void) fprintf(stderr, "%s.%s: %g\n",
1680 				  className, var.name, *((float *) var.var));
1681 			break;
1682 		case t_Int:
1683 			(void) fprintf(stderr, "%s.%s: %d\n",
1684 				    className, var.name, *((int *) var.var));
1685 			break;
1686 		case t_Bool:
1687 			(void) fprintf(stderr, "%s.%s: %s\n",
1688 				       className, var.name, *((int *) var.var) ? "True" : "False");
1689 			break;
1690 	}
1691 }
1692 
1693 static void
getServerResources(Display * display,char * homeenv,char ** custom,XrmDatabase * RDB,XrmDatabase * serverDB)1694 getServerResources(Display * display, char *homeenv,
1695 #ifdef CUSTOMIZATION
1696   char **custom,
1697 #endif
1698   XrmDatabase * RDB, XrmDatabase * serverDB)
1699 {
1700 	char       *serverString;
1701 
1702 	serverString = XResourceManagerString(display);
1703 	if (serverString) {
1704 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
1705    * line.  PURIFY 4.0.1 on SunOS4 reports this also when using X11R5, but not
1706    * with OpenWindow 3.0 (X11R4 based). */
1707 		*serverDB = XrmGetStringDatabase(serverString);
1708 #ifndef CUSTOMIZATION
1709 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
1710    * line.  PURIFY 4.0.1 on SunOS4 does not report this error. */
1711 		(void) XrmMergeDatabases(*serverDB, RDB);
1712 #endif
1713 	} else {
1714 		char       *buf = (char *) malloc(strlen(homeenv) + 12);
1715 
1716 		(void) sprintf(buf, "%s/.Xdefaults", homeenv);
1717 #ifdef CUSTOMIZATION
1718 		*serverDB = XrmGetFileDatabase(buf);
1719 #else
1720 		(void) XrmMergeDatabases(XrmGetFileDatabase(buf), RDB);
1721 #endif
1722 		free(buf);
1723 	}
1724 #ifdef CUSTOMIZATION
1725 	if (*serverDB)
1726 		GetResource(*serverDB, ProgramName, classname, "customization",
1727 			    "Customization", t_String, "", custom);
1728 	else
1729 		*custom = "";
1730 #endif
1731 }
1732 
1733 static void
getAppResources(char * homeenv,char ** custom,XrmDatabase * RDB,XrmDatabase * serverDB,int * argc,char ** argv)1734 getAppResources(char *homeenv, char **custom, XrmDatabase * RDB,
1735 #ifdef CUSTOMIZATION
1736 	   XrmDatabase * serverDB,
1737 #endif
1738 	   int *argc, char **argv)
1739 {
1740 	char       *env;
1741 	char       *userpath;
1742 	char       *userfile = (char *) NULL;
1743 	XrmDatabase cmdlineDB = (XrmDatabase) NULL;
1744 	XrmDatabase userDB = (XrmDatabase) NULL;
1745 	XrmDatabase applicationDB = (XrmDatabase) NULL;
1746 
1747 	env = getenv("XFILESEARCHPATH");
1748 	applicationDB = parsefilepath(
1749 		((env == NULL) ? (char *) DEF_FILESEARCHPATH : env),
1750 		"app-defaults", classname, *custom);
1751 
1752 	XrmParseCommand(&cmdlineDB, cmdlineTable, cmdlineEntries, ProgramName,
1753 		argc, argv);
1754 
1755 	userpath = getenv("XUSERFILESEARCHPATH");
1756 	if (!userpath) {
1757 		env = getenv("XAPPLRESDIR");
1758 		if (env) {
1759 			userfile = (char *) malloc(strlen(env) + strlen(homeenv) + 8);
1760 			(void) strcpy(userfile, env);
1761 			(void) strcat(userfile, "/%N:");
1762 			(void) strcat(userfile, homeenv);
1763 			(void) strcat(userfile, "/%N");
1764 		} else {
1765 #ifdef VMS
1766 			userfile = (char *) malloc(2 * strlen(homeenv) + 31);
1767 			(void) strcpy(userfile, homeenv);
1768 			(void) strcat(userfile, "DECW$%N.DAT#");
1769 			(void) strcat(userfile, homeenv);
1770 			(void) strcat(userfile, "DECW$XDEFAULTS.DAT");
1771 #else
1772 			userfile = (char *) malloc(strlen(homeenv) + 4);
1773 			(void) strcpy(userfile, homeenv);
1774 			(void) strcat(userfile, "/%N");
1775 #endif
1776 		}
1777 		userpath = userfile;
1778 	}
1779 	userDB = parsefilepath(userpath, "app-defaults", classname, *custom);
1780 
1781 	if (userfile)
1782 		free(userfile);
1783 
1784 	(void) XrmMergeDatabases(applicationDB, RDB);
1785 	(void) XrmMergeDatabases(userDB, RDB);
1786 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
1787    * line.  PURIFY 4.0.1 on SunOS4 does not report this error. */
1788 	(void) XrmMergeDatabases(cmdlineDB, RDB);
1789 #ifdef CUSTOMIZATION
1790 	if (*serverDB)
1791 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
1792    * line.  PURIFY 4.0.1 on SunOS4 does not report this error. */
1793 		(void) XrmMergeDatabases(*serverDB, RDB);
1794 #else
1795 	GetResource(*RDB, ProgramName, classname, "display", "Display", t_String,
1796 		    (char *) "", &displayname);
1797 #endif
1798 	GetResource(*RDB, ProgramName, classname, "parent", "Parent", t_String,
1799 		    (char *) "", &parentname);
1800 	if (parentname && *parentname) {
1801 		if (sscanf(parentname, "%ld", &parent))
1802 			parentSet = True;
1803 	}
1804 	GetResource(*RDB, ProgramName, classname, "nolock", "NoLock", t_Bool,
1805 		    (char *) "off", (void *) & nolock);
1806 	GetResource(*RDB, ProgramName, classname, "inwindow", "InWindow", t_Bool,
1807 		    (char *) "off", (void *) & inwindow);
1808 	GetResource(*RDB, ProgramName, classname, "inroot", "InRoot", t_Bool,
1809 		    (char *) "off", (void *) & inroot);
1810 	GetResource(*RDB, ProgramName, classname, "remote", "Remote", t_Bool,
1811 		    (char *) "off", (void *) & remote);
1812 #ifdef USE_DTSAVER
1813 	GetResource(*RDB, ProgramName, classname, "dtsaver", "DtSaver", t_Bool,
1814 		    (char *) "off", (void *) & dtsaver);
1815 	if (dtsaver) {
1816 		inroot = False;
1817 		inwindow = True;
1818 		nolock = True;
1819 	}
1820 #endif
1821 #ifdef USE_XINERAMA
1822 	GetResource(*RDB, ProgramName, classname, "xinerama", "Xinerama", t_Bool,
1823 		    (char *) "off", (void *) & xinerama);
1824 #endif
1825 }
1826 
1827 extern void XlockrmParseCommand(
1828     XrmDatabase		*pdb,		/* data base */
1829     register XrmOptionDescList options, /* pointer to table of valid options */
1830     int                 num_options,	/* number of options		     */
1831     char               *prefix,		/* name to prefix resources with     */
1832     int                *arg_c,		/* address of argument count 	     */
1833     char              **arg_v);		/* argument list (command line)	     */
1834 
1835 #if defined( USE_AUTO_LOGOUT ) || defined( USE_BUTTON_LOGOUT )
1836 extern int  fullLock();
1837 
1838 #endif
1839 extern void erasemodefromname(char *name, Bool verbose);
1840 
1841 
1842 void
getResources(Display ** displayp,int argc,char ** argv)1843 getResources(Display ** displayp, int argc, char **argv)
1844 {
1845 	XrmDatabase RDB = (XrmDatabase) NULL;
1846 
1847 #ifdef USE_MODULES
1848 	XrmDatabase modulepathDB = (XrmDatabase) NULL;
1849 
1850 #endif
1851 	XrmDatabase serverDB = (XrmDatabase) NULL;
1852 	XrmDatabase earlyCmdlineDB = (XrmDatabase) NULL;
1853 	XrmDatabase modeDB = (XrmDatabase) NULL;
1854 	XrmDatabase generalDB = (XrmDatabase) NULL;
1855 	char       *custom = (char *) NULL;
1856 	char       *homeenv = (char *) NULL;
1857 	int         i, j;
1858 	int         max_length;
1859 
1860 	XrmInitialize();
1861 
1862 #ifndef USE_MODULES
1863 	/*
1864 	 * Moved back because its annoying if you need -remote and
1865 	 * you do not know it.
1866 	 */
1867 	checkSpecialArgs(argc, argv);
1868 #endif
1869 
1870 	/* Application Class is fixed */
1871 	classname = (char*) DEF_CLASSNAME;
1872 	/*
1873 	 * Application Name may be modified by -name arg from command
1874 	 * line so you can have different resource files for different
1875 	 * configurations/machines etc...
1876 	 */
1877 #ifdef VMS
1878 	/*Strip off directory and .exe; parts */
1879 	ProgramName = stripname(ProgramName);
1880 #endif
1881 	XrmParseCommand(&earlyCmdlineDB, earlyCmdlineTable,
1882 			earlyCmdlineEntries, DEFAULT_NAME, &argc, argv);
1883 	GetResource(earlyCmdlineDB, DEFAULT_NAME, classname, "name", "Name",
1884 		    t_String, ProgramName, &ProgramName);
1885 #ifdef CUSTOMIZATION
1886 	GetResource(earlyCmdlineDB, ProgramName, classname, "display",
1887 		    "Display", t_String, "", &displayname);
1888 #endif
1889 	homeenv = getenv("HOME");
1890 	if (!homeenv)
1891 		homeenv = (char *) "";
1892 
1893 #ifdef CUSTOMIZATION
1894 	openDisplay(displayp);
1895 	getServerResources(*displayp, homeenv, &custom, &RDB, &serverDB);
1896 	getAppResources(homeenv, &custom, &RDB, &serverDB, &argc, argv);
1897 	checkDisplay();
1898 #else
1899 	custom = (char *) "";
1900 	getAppResources(homeenv, &custom, &RDB, &argc, argv);
1901 	openDisplay(displayp);
1902 	checkDisplay();
1903 	getServerResources(*displayp, homeenv, &RDB, &serverDB);
1904 #endif
1905 
1906 #ifdef USE_MODULES
1907 	/*
1908 	 * Now that all the resource files have been loaded, check for the
1909 	 * modules directory, so we'll know what modes are available.
1910 	 */
1911 	XrmParseCommand(&modulepathDB, modulepathTable, 1, ProgramName,
1912 			&argc, argv);
1913 	(void) XrmMergeDatabases(modulepathDB, &RDB);
1914 	GetResource(RDB, ProgramName, classname, "modulepath", "Modulepath",
1915 		    t_String, (char *) DEF_MODULEPATH, &modulepath);
1916 
1917 	/* read modules from modules directory */
1918 	atexit(UnloadModules);	/* make sure modules get unloaded */
1919 	LoadModules(modulepath);
1920 
1921 	/*
1922 	 * Moved the search for help to here because now the modules
1923 	 * have been loaded so they can be listed by help.
1924 	 */
1925 	checkSpecialArgs(argc, argv);
1926 #endif
1927 	XrmParseCommand(&generalDB, genTable, genEntries, ProgramName, &argc, argv);
1928 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
1929    * line.  PURIFY 4.0.1 on SunOS4 does not report this error. */
1930 	(void) XrmMergeDatabases(generalDB, &RDB);
1931 
1932 	GetResource(RDB, ProgramName, classname, "mode", "Mode", t_String,
1933 		    (char *) DEF_MODE, (void *) & mode);
1934 
1935 	XrmParseCommand(&modeDB, modeTable, modeEntries, ProgramName, &argc, argv);
1936 	(void) XrmMergeDatabases(modeDB, &RDB);
1937 
1938 
1939 
1940 	for (i = 0; i < numprocs; i++) {
1941 		/* if (!strcmp(mode, LockProcs[i].cmdline_arg)) */
1942 		XrmDatabase optDB = (XrmDatabase) NULL;
1943 		ModeSpecOpt *ms = LockProcs[i].msopt;
1944 
1945 		if (!ms->numopts)
1946 			continue;
1947 		/* The problem was with XrmParseCommand is that it does not
1948                    work for multiple use options.  Running it first with a
1949                    corrupted version (that makes sure argc and argv do
1950                    not change) to setup optDB then run the real
1951                    XrmParseCommand on a nullDB to set argv and argc.
1952                  */
1953 		XlockrmParseCommand(&optDB, ms->opts, ms->numopts,
1954 				ProgramName, &argc, argv);
1955 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
1956    * line.  PURIFY 4.0.1 on SunOS4 does not report this error. */
1957 		(void) XrmMergeDatabases(optDB, &RDB);
1958 	}
1959 	for (i = 0; i < numprocs; i++) {
1960 		/* if (!strcmp(mode, LockProcs[i].cmdline_arg)) */
1961 		XrmDatabase nullDB = (XrmDatabase) NULL;
1962 		ModeSpecOpt *ms = LockProcs[i].msopt;
1963 
1964 		if (!ms->numopts)
1965 			continue;
1966                  /*     Running real XrmParseCommand on a nullDB to set argv
1967                         and argc.
1968                  */
1969 		XrmParseCommand(&nullDB, ms->opts, ms->numopts,
1970 				ProgramName, &argc, argv);
1971 	}
1972 
1973 	/* the RDB is set, now query load the variables from the database */
1974 
1975 	for (i = 0; i < (int) NGENARGS; i++) {
1976 		GetResource(RDB, ProgramName, classname,
1977 			genvars[i].name, genvars[i].classname,
1978 			genvars[i].type, genvars[i].def,
1979 			(void *) genvars[i].var);
1980 	}
1981 
1982 #ifdef USE_VTLOCK
1983         /* Process the vtlock resource */
1984         if ( !vtlockres || !*vtlockres )
1985         	vtlock = False;
1986         else {
1987 	    if (debug)
1988 		(void) fprintf(stderr,"vtlock: %s\n",vtlockres);
1989             if ( !strcmp( VTLOCKMODE_SWITCH, vtlockres ) )
1990             {
1991                 vtlock = True;
1992                 vtlock_set_active = True;
1993                 vtlock_restore = False;
1994             }
1995             else if ( !strcmp( VTLOCKMODE_RESTORE, vtlockres ) )
1996             {
1997                 vtlock = True;
1998                 vtlock_set_active = True;
1999                 vtlock_restore = True;
2000             }
2001             else if ( !strcmp( VTLOCKMODE_OFF, vtlockres ) )
2002             {
2003                 vtlock = False;
2004 	    }
2005             else
2006             {
2007                 vtlock = True;
2008                 vtlock_set_active = False;
2009                 vtlock_restore = False;
2010             }
2011         }
2012 #endif
2013 
2014 	max_length = 0;
2015 	for (i = 0; i < numprocs; i++) {
2016 		j = strlen(LockProcs[i].cmdline_arg);
2017 		if (j > max_length)
2018 			max_length = j;
2019 	}
2020 
2021 	modename = (char *) malloc(strlen(ProgramName) + max_length + 2);
2022 	modeclassname = (char *) malloc(strlen(classname) + max_length + 2);
2023 
2024 	for (i = 0; i < numprocs; i++) {
2025 		argtype    *v;
2026 		ModeSpecOpt *ms = LockProcs[i].msopt;
2027 
2028 		(void) sprintf(modename, "%s.%s", ProgramName, LockProcs[i].cmdline_arg);
2029 		(void) sprintf(modeclassname, "%s.%s", classname, LockProcs[i].cmdline_arg);
2030 		for (j = 0; j < (int) NMODEARGS; j++) {
2031 			char       *buf = (char *) NULL;
2032 			void       *p = (void *) ((char *) (&LockProcs[i]) + modevaroffs[j]);
2033 
2034 			switch (modevars[j].type) {
2035 				case t_String:
2036 					buf = (char *) malloc(strlen(*((char **) p)) + 1);
2037 					(void) sprintf(buf, "%s",
2038 						*((char **) p));
2039 					break;
2040 				case t_Float:
2041 					buf = (char *) malloc(16);
2042 					(void) sprintf(buf, "%g",
2043 						*((float *) p));
2044 					break;
2045 				case t_Int:
2046 					buf = (char *) malloc(16);
2047 					(void) sprintf(buf,
2048 						"%d", *((int *) p));
2049 					break;
2050 				case t_Bool:
2051 					buf = (char *) malloc(6);
2052 					(void) sprintf(buf, "%s",
2053 						*((int *) p) ? "True" : "False");
2054 					break;
2055 			}
2056 			GetResource(RDB, modename, modeclassname,
2057 				modevars[j].name, modevars[j].classname,
2058 				modevars[j].type, buf, (void *) p);
2059 			if (!strcmp(mode, LockProcs[i].cmdline_arg)) {
2060 				GetResource(RDB, modename, modeclassname,
2061 				     modevars[j].name, modevars[j].classname,
2062 				     modevars[j].type, buf,
2063 				     (void *) modevars[j].var);
2064 			}
2065 			if (buf) {
2066 				free(buf);
2067 				buf = (char *) NULL;
2068 			}
2069 		}
2070 		if (!ms->numvarsdesc)
2071 			continue;
2072 		v = ms->vars;
2073 		for (j = 0; j < ms->numvarsdesc; j++) {
2074 			GetResource(RDB, modename, modeclassname,
2075 				v[j].name, v[j].classname,
2076 				v[j].type, v[j].def, (void *) v[j].var);
2077 		}
2078 	}
2079 
2080 	/*XrmPutFileDatabase(RDB, "/tmp/xlock.rsrc.out"); */
2081 /* PURIFY 4.0.1 on Solaris 2 reports an uninitialized memory read on the next
2082    * line.  PURIFY 4.0.1 on SunOS4 reports this also when using X11R5, but not
2083    * with OpenWindow 3.0 (X11R4 based). */
2084 	(void) XrmDestroyDatabase(RDB);
2085 	if (!strcmp(mode, "run")) {
2086 		geometry = (char *) malloc(4);
2087 		(void) strcpy(geometry, "1x1");
2088 	}
2089 
2090 	/* Parse the rest of the command line */
2091 	for (argc--, argv++; argc > 0; argc--, argv++) {
2092 		if (**argv != '-')
2093 			Syntax(*argv);
2094 		switch (argv[0][1]) {
2095 			case 'r':
2096 				DumpResources();
2097 				/* NOTREACHED */
2098 			default:
2099 				Syntax(*argv);
2100 				/* NOTREACHED */
2101 		}
2102 	}
2103 
2104 #if defined( USE_AUTO_LOGOUT ) || defined( USE_BUTTON_LOGOUT )
2105 	if (fullLock()) {
2106 #ifdef USE_AUTO_LOGOUT
2107 		logoutAuto = 0;
2108 #endif
2109 #ifdef USE_BUTTON_LOGOUT
2110 		enable_button = 0;
2111 #endif
2112 	} else {
2113 #ifdef USE_AUTO_LOGOUT
2114 #if ( USE_AUTO_LOGOUT > 0 )	/* Could be USER defined if 0 */
2115 		if (logoutAuto > USE_AUTO_LOGOUT)
2116 			logoutAuto = USE_AUTO_LOGOUT;
2117 		else if (logoutAuto <= 0)	/* Handle 0 as a special case */
2118 			logoutAuto = USE_AUTO_LOGOUT;
2119 #else
2120 		if (logoutAuto <= 0)	/* Handle 0 as a special case */
2121 			(void) sscanf(DEF_AUTO_LOGOUT, "%d", &logoutAuto);
2122 #endif
2123 #endif
2124 #ifdef USE_BUTTON_LOGOUT
2125 #if ( USE_BUTTON_LOGOUT > 0 )	/* Could be USER defined if <= 0 */
2126 		if (logoutButton > USE_BUTTON_LOGOUT)
2127 			logoutButton = USE_BUTTON_LOGOUT;
2128 		else if (logoutButton <= 0)	/* Handle 0 as a special case */
2129 			logoutButton = USE_BUTTON_LOGOUT;
2130 #endif
2131 #if ( USE_BUTTON_LOGOUT == 0 )
2132 		if (logoutButton <= 0)	/* Handle 0 as a special case */
2133 			(void) sscanf(DEF_BUTTON_LOGOUT, "%d", &logoutButton);
2134 #endif
2135 #endif
2136 	}
2137 #endif
2138 #ifdef USE_DTSAVER
2139 	if (dtsaver) {
2140 		inroot = False;
2141 		inwindow = True;
2142 		nolock = True;
2143 		enablesaver = True;
2144 		grabmouse = False;
2145 		grabserver = False;
2146 		unlockdelay = 0;
2147 		install = False;
2148 		lockdelay = 0;
2149 		geometry = (char *) DEF_GEOMETRY;
2150 	}
2151 #endif
2152 
2153 	if (verbose) {
2154 		for (i = 0; i < (int) NGENARGS; i++)
2155 			printvar(classname, genvars[i]);
2156 		for (i = 0; i < (int) NMODEARGS; i++)
2157 			printvar(modename, modevars[i]);
2158 	}
2159 	if (!visualname || !*visualname || !strcmp(visualname, "default")) {
2160 		VisualClassWanted = -1;
2161 		if (verbose)
2162 			(void) fprintf(stderr, "Using default visual class\n");
2163 	} else {
2164 		VisualClassWanted = visualClassFromName(visualname);
2165 		if (verbose)
2166 			(void) fprintf(stderr, "Using visual class %s\n",
2167 				       nameOfVisualClass(VisualClassWanted));
2168 	}
2169 	erasemodefromname(erasemodename, verbose);
2170 	/* if (!erasemodename || !*erasemodename || !strcmp(erasemodename,
2171 							 "default")) {
2172 		erasemode = -1;
2173 		if (verbose)
2174 			(void) fprintf(stderr, "Using random erase mode\n");
2175 	} else {
2176 	}*/
2177 #if HAVE_DIRENT_H
2178 	/* Evaluate bitmap */
2179 	if (bitmap && strcmp(bitmap, DEF_BITMAP)) {
2180 		get_dir(bitmap, directory_r, filename_r);
2181 		if (image_list != NULL) {
2182 			int         num;
2183 
2184 			for (num = 0; num < num_list; num++) {
2185 				if  (image_list[num])
2186 					free(image_list[num]);
2187 			}
2188 			free(image_list);
2189 			image_list = (struct dirent **) NULL;
2190 		}
2191 		images_list = (struct dirent ***) malloc(sizeof (struct dirent **));
2192 
2193 		if (images_list) {
2194 			num_list = scan_dir(directory_r, images_list, sel_image, NULL);
2195 			image_list = *images_list;
2196 			free(images_list);
2197 			images_list = (struct dirent ***) NULL;
2198 		}
2199 		if (debug)
2200 			for (i = 0; i < num_list; i++)
2201 				(void) printf("File number %d: %s\n", i, image_list[i]->d_name);
2202 		if (num_list < 0) {
2203 			image_list = (struct dirent **) NULL;
2204 			num_list = 0;
2205 		}
2206 	} else {
2207 		num_list = 0;
2208 	}
2209 #endif
2210 	free(modename);
2211 	free(modeclassname);
2212 }
2213 
2214 extern char * old_default_mode;
2215 
2216 void
checkResources(void)2217 checkResources(void)
2218 {
2219 	int         i;
2220 
2221 	/* in case they have a 'xlock*mode: ' empty resource */
2222 	if (!mode || !*mode)
2223 		mode = (char *) DEF_MODE;
2224 
2225 	if (!old_default_mode || !*old_default_mode) {
2226 		 old_default_mode = (char *) malloc(strlen(mode) + 1);
2227 		(void) strcpy(old_default_mode, mode);
2228 	}
2229 	for (i = 0; i < numprocs; i++) {
2230 		if (!strcmp(LockProcs[i].cmdline_arg, mode)) {
2231 			set_default_mode(&LockProcs[i]);
2232 			break;
2233 		}
2234 	}
2235 	if (i == numprocs) {
2236 		(void) fprintf(stderr,
2237 			"unrecognized mode \"%s\", using backup mode \"%s\"\n",
2238 			mode, (char *) DEF_MODE);
2239 		for (i = 0; i < numprocs; i++) {
2240 			if (!strcmp(LockProcs[i].cmdline_arg, (char *) DEF_MODE)) {
2241 				set_default_mode(&LockProcs[i]);
2242 				break;
2243 			}
2244 		}
2245 		if (i != numprocs) {
2246 			delay = LockProcs[i].def_delay;
2247 			count = LockProcs[i].def_count;
2248 			cycles = LockProcs[i].def_cycles;
2249 			size = LockProcs[i].def_size;
2250 			ncolors = LockProcs[i].def_ncolors;
2251 			saturation = LockProcs[i].def_saturation;
2252 			bitmap = LockProcs[i].def_bitmap;
2253 		}
2254 	}
2255 	if (i == numprocs) {
2256 			/* Should not get here, but you never know. */
2257 		  (void) fprintf(stderr, "unrecognized mode and backup mode \"%s\"\n",
2258 				(char *) DEF_MODE);
2259 			Syntax(mode);
2260 	} else {
2261 
2262 		/* count and size we allow negative to mean randomize up to that number */
2263 		if (delay < 0)
2264 			Syntax("-delay argument must not be negative.");
2265 		if (ncolors < 2 || ncolors > 200)
2266 			Syntax("-ncolors argument must be between 2 and 200.");
2267 		if (saturation < 0.0 || saturation > 1.0)
2268 			Syntax("-saturation argument must be between 0.0 and 1.0.");
2269 		if (delta3d < 0.0 || delta3d > 20.0)
2270 			Syntax("-delta3d argument must be between 0.0 and 20.0.");
2271 	}
2272 }
2273