GetDflt.c revision 61b2299d
1/* $Xorg: GetDflt.c,v 1.6 2001/02/09 02:03:33 xorgcvs Exp $ */
2
3/***********************************************************
4
5Copyright 1987, 1988, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included in
14all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall not be
24used in advertising or otherwise to promote the sale, use or other dealings
25in this Software without prior written authorization from The Open Group.
26
27
28Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
29
30                        All Rights Reserved
31
32Permission to use, copy, modify, and distribute this software and its
33documentation for any purpose and without fee is hereby granted,
34provided that the above copyright notice appear in all copies and that
35both that copyright notice and this permission notice appear in
36supporting documentation, and that the name of Digital not be
37used in advertising or publicity pertaining to distribution of the
38software without specific, written prior permission.
39
40DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
41ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
42DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
43ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
44WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46SOFTWARE.
47
48******************************************************************/
49/* $XFree86: xc/lib/X11/GetDflt.c,v 3.22 2003/04/13 19:22:16 dawes Exp $ */
50
51#ifdef HAVE_CONFIG_H
52#include <config.h>
53#endif
54#include "Xlibint.h"
55#include <X11/Xos.h>
56#include <X11/Xresource.h>
57
58#ifndef X_NOT_POSIX
59#ifdef _POSIX_SOURCE
60#include <limits.h>
61#else
62#define _POSIX_SOURCE
63#include <limits.h>
64#undef _POSIX_SOURCE
65#endif
66#endif
67#ifndef PATH_MAX
68#ifdef WIN32
69#define PATH_MAX 512
70#else
71#include <sys/param.h>
72#endif
73#ifndef PATH_MAX
74#ifdef MAXPATHLEN
75#define PATH_MAX MAXPATHLEN
76#else
77#define PATH_MAX 1024
78#endif
79#endif
80#endif
81
82#ifdef XTHREADS
83#include <X11/Xthreads.h>
84#endif
85#ifndef WIN32
86#define X_INCLUDE_PWD_H
87#define XOS_USE_XLIB_LOCKING
88#include <X11/Xos_r.h>
89#endif
90#include <stdio.h>
91#include <ctype.h>
92
93
94/*ARGSUSED*/
95static char *
96GetHomeDir(
97    char *dest,
98    int len)
99{
100#ifdef WIN32
101    register char *ptr1 = NULL;
102    register char *ptr2 = NULL;
103    int len1 = 0, len2 = 0;
104
105    if ((ptr1 = getenv("HOME"))) {	/* old, deprecated */
106	len1 = strlen (ptr1);
107    } else if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) {
108	len1 = strlen (ptr1);
109	len2 = strlen (ptr2);
110    } else if ((ptr2 = getenv("USERNAME"))) {
111	len1 = strlen (ptr1 = "/users/");
112	len2 = strlen (ptr2);
113    }
114    if ((len1 + len2 + 1) < len)
115	sprintf (dest, "%s%s", ptr1, (ptr2) ? ptr2 : "");
116    else
117	*dest = '\0';
118#else
119#ifdef X_NEEDS_PWPARAMS
120    _Xgetpwparams pwparams;
121#endif
122    struct passwd *pw;
123    register char *ptr;
124
125    if (len <= 0 || dest == NULL)
126	return NULL;
127
128    if ((ptr = getenv("HOME"))) {
129	(void) strncpy(dest, ptr, len-1);
130	dest[len-1] = '\0';
131    } else {
132	if ((ptr = getenv("USER")))
133	    pw = _XGetpwnam(ptr,pwparams);
134	else
135	    pw = _XGetpwuid(getuid(),pwparams);
136	if (pw != NULL) {
137	    (void) strncpy(dest, pw->pw_dir, len-1);
138	    dest[len-1] = '\0';
139	} else
140	    *dest = '\0';
141    }
142#endif
143    return dest;
144}
145
146
147static XrmDatabase
148InitDefaults(
149    Display *dpy)			/* display for defaults.... */
150{
151    XrmDatabase userdb;
152    XrmDatabase xdb;
153    char fname[PATH_MAX];               /* longer than any conceivable size */
154    char *xenv;
155
156    XrmInitialize();
157
158    /*
159     * See lib/Xt/Initialize.c
160     *
161     * First, get the defaults from the server; if none, then load from
162     * ~/.Xdefaults.  Next, if there is an XENVIRONMENT environment variable,
163     * then load that file.
164     */
165
166    if (dpy->xdefaults == NULL) {
167	const char *slashDotXdefaults = "/.Xdefaults";
168
169	(void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaults) - 1);
170	(void) strcat (fname, slashDotXdefaults);
171	xdb = XrmGetFileDatabase (fname);
172    } else {
173	xdb = XrmGetStringDatabase(dpy->xdefaults);
174    }
175
176    if (!(xenv = getenv ("XENVIRONMENT"))) {
177	const char *slashDotXdefaultsDash = "/.Xdefaults-";
178	int len;
179
180	(void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaultsDash) - 1);
181	(void) strcat (fname, slashDotXdefaultsDash);
182	len = strlen (fname);
183	(void) _XGetHostname (fname+len, PATH_MAX-len);
184	xenv = fname;
185    }
186    userdb = XrmGetFileDatabase (xenv);
187    XrmMergeDatabases (userdb, &xdb);
188    return (xdb);
189
190#ifdef old
191    if (fname[0] != '\0') userdb =  XrmGetFileDatabase(fname);
192    xdb = XrmGetStringDatabase(dpy->xdefaults);
193    XrmMergeDatabases(userdb, &xdb);
194    return xdb;
195#endif
196}
197
198char *
199XGetDefault(
200	Display *dpy,			/* display for defaults.... */
201	char _Xconst *prog,		/* name of program for option	*/
202	register _Xconst char *name)	/* name of option program wants */
203{					/* to get, for example, "font"  */
204	XrmName names[3];
205	XrmClass classes[3];
206	XrmRepresentation fromType;
207	XrmValue result;
208	char *progname;
209#ifdef WIN32
210	char *progname2;
211#endif
212#ifdef __UNIXOS2__
213	char *progname2;
214	char *dotpos;
215#endif
216
217	/*
218	 * strip path off of program name (XXX - this is OS specific)
219	 */
220	progname = strrchr (prog, '/');
221#ifdef WIN32
222	progname2 = strrchr (prog, '\\');
223	if (progname2 && (!progname || progname < progname2))
224	    progname = progname2;
225#endif
226#ifdef __UNIXOS2__  /* Very similar to WIN32 */
227	progname2 = strrchr (prog, '\\');
228	if (progname2 && (!progname || progname < progname2))
229	    progname = progname2;
230	dotpos = strrchr (prog, '.');
231	if (dotpos && (dotpos>progname2)) *dotpos='\0';
232#endif  /* We take out the .exe suffix  */
233
234	if (progname)
235	    progname++;
236	else
237	    progname = (char *)prog;
238
239	/*
240	 * see if database has ever been initialized.  Lookups can be done
241	 * without locks held.
242	 */
243	LockDisplay(dpy);
244	if (dpy->db == NULL) {
245	    dpy->db = InitDefaults(dpy);
246	    dpy->flags |= XlibDisplayDfltRMDB;
247	}
248	UnlockDisplay(dpy);
249
250	names[0] = XrmStringToName(progname);
251	names[1] = XrmStringToName(name);
252	names[2] = NULLQUARK;
253	classes[0] = XrmStringToClass("Program");
254	classes[1] = XrmStringToClass("Name");
255	classes[2] = NULLQUARK;
256	(void)XrmQGetResource(dpy->db, names, classes, &fromType, &result);
257	return (result.addr);
258}
259
260