GetDflt.c revision b4ee4795
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
56#ifndef X_NOT_POSIX
57#ifdef _POSIX_SOURCE
58#include <limits.h>
59#else
60#define _POSIX_SOURCE
61#include <limits.h>
62#undef _POSIX_SOURCE
63#endif
64#endif
65#ifndef PATH_MAX
66#ifdef WIN32
67#define PATH_MAX 512
68#else
69#include <sys/param.h>
70#endif
71#ifndef PATH_MAX
72#ifdef MAXPATHLEN
73#define PATH_MAX MAXPATHLEN
74#else
75#define PATH_MAX 1024
76#endif
77#endif
78#endif
79
80#ifdef XTHREADS
81#include <X11/Xthreads.h>
82#endif
83#ifndef WIN32
84#define X_INCLUDE_PWD_H
85#define XOS_USE_XLIB_LOCKING
86#include <X11/Xos_r.h>
87#endif
88#include <stdio.h>
89#include <ctype.h>
90
91
92/*ARGSUSED*/
93static char *
94GetHomeDir(
95    char *dest,
96    int len)
97{
98#ifdef WIN32
99    register char *ptr1 = NULL;
100    register char *ptr2 = NULL;
101    int len1 = 0, len2 = 0;
102
103    if ((ptr1 = getenv("HOME"))) {	/* old, deprecated */
104	len1 = strlen (ptr1);
105    } else if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) {
106	len1 = strlen (ptr1);
107	len2 = strlen (ptr2);
108    } else if ((ptr2 = getenv("USERNAME"))) {
109	len1 = strlen (ptr1 = "/users/");
110	len2 = strlen (ptr2);
111    }
112    if ((len1 + len2 + 1) < len)
113	sprintf (dest, "%s%s", ptr1, (ptr2) ? ptr2 : "");
114    else
115	*dest = '\0';
116#else
117#ifdef X_NEEDS_PWPARAMS
118    _Xgetpwparams pwparams;
119#endif
120    struct passwd *pw;
121    register char *ptr;
122
123    if (len <= 0 || dest == NULL)
124	return NULL;
125
126    if ((ptr = getenv("HOME"))) {
127	(void) strncpy(dest, ptr, len-1);
128	dest[len-1] = '\0';
129    } else {
130	if ((ptr = getenv("USER")))
131	    pw = _XGetpwnam(ptr,pwparams);
132	else
133	    pw = _XGetpwuid(getuid(),pwparams);
134	if (pw != NULL) {
135	    (void) strncpy(dest, pw->pw_dir, len-1);
136	    dest[len-1] = '\0';
137	} else
138	    *dest = '\0';
139    }
140#endif
141    return dest;
142}
143
144
145static XrmDatabase
146InitDefaults(
147    Display *dpy)			/* display for defaults.... */
148{
149    XrmDatabase userdb;
150    XrmDatabase xdb;
151    char fname[PATH_MAX];               /* longer than any conceivable size */
152    char *xenv;
153
154    XrmInitialize();
155
156    /*
157     * See lib/Xt/Initialize.c
158     *
159     * First, get the defaults from the server; if none, then load from
160     * ~/.Xdefaults.  Next, if there is an XENVIRONMENT environment variable,
161     * then load that file.
162     */
163
164    if (dpy->xdefaults == NULL) {
165	const char *slashDotXdefaults = "/.Xdefaults";
166
167	(void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaults) - 1);
168	(void) strcat (fname, slashDotXdefaults);
169	xdb = XrmGetFileDatabase (fname);
170    } else {
171	xdb = XrmGetStringDatabase(dpy->xdefaults);
172    }
173
174    if (!(xenv = getenv ("XENVIRONMENT"))) {
175	const char *slashDotXdefaultsDash = "/.Xdefaults-";
176	int len;
177
178	(void) GetHomeDir (fname, PATH_MAX - strlen (slashDotXdefaultsDash) - 1);
179	(void) strcat (fname, slashDotXdefaultsDash);
180	len = strlen (fname);
181	(void) _XGetHostname (fname+len, PATH_MAX-len);
182	xenv = fname;
183    }
184    userdb = XrmGetFileDatabase (xenv);
185    XrmMergeDatabases (userdb, &xdb);
186    return (xdb);
187
188#ifdef old
189    if (fname[0] != '\0') userdb =  XrmGetFileDatabase(fname);
190    xdb = XrmGetStringDatabase(dpy->xdefaults);
191    XrmMergeDatabases(userdb, &xdb);
192    return xdb;
193#endif
194}
195
196char *
197XGetDefault(
198	Display *dpy,			/* display for defaults.... */
199	char _Xconst *prog,		/* name of program for option	*/
200	register _Xconst char *name)	/* name of option program wants */
201{					/* to get, for example, "font"  */
202	XrmName names[3];
203	XrmClass classes[3];
204	XrmRepresentation fromType;
205	XrmValue result;
206	char *progname;
207#ifdef WIN32
208	char *progname2;
209#endif
210#ifdef __UNIXOS2__
211	char *progname2;
212	char *dotpos;
213#endif
214
215	/*
216	 * strip path off of program name (XXX - this is OS specific)
217	 */
218	progname = strrchr (prog, '/');
219#ifdef WIN32
220	progname2 = strrchr (prog, '\\');
221	if (progname2 && (!progname || progname < progname2))
222	    progname = progname2;
223#endif
224#ifdef __UNIXOS2__  /* Very similar to WIN32 */
225	progname2 = strrchr (prog, '\\');
226	if (progname2 && (!progname || progname < progname2))
227	    progname = progname2;
228	dotpos = strrchr (prog, '.');
229	if (dotpos && (dotpos>progname2)) *dotpos='\0';
230#endif  /* We take out the .exe suffix  */
231
232	if (progname)
233	    progname++;
234	else
235	    progname = (char *)prog;
236
237	/*
238	 * see if database has ever been initialized.  Lookups can be done
239	 * without locks held.
240	 */
241	LockDisplay(dpy);
242	if (dpy->db == NULL) {
243	    dpy->db = InitDefaults(dpy);
244	    dpy->flags |= XlibDisplayDfltRMDB;
245	}
246	UnlockDisplay(dpy);
247
248	names[0] = XrmStringToName(progname);
249	names[1] = XrmStringToName(name);
250	names[2] = NULLQUARK;
251	classes[0] = XrmStringToClass("Program");
252	classes[1] = XrmStringToClass("Name");
253	classes[2] = NULLQUARK;
254	(void)XrmQGetResource(dpy->db, names, classes, &fromType, &result);
255	return (result.addr);
256}
257
258