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