2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * File: connect.c $TOG: connect.c /main/8 1998/04/09 17:44:33 mgreess $
27 * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
29 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
30 * (c) Copyright 1993, 1994 International Business Machines Corp. *
31 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
32 * (c) Copyright 1993, 1994 Novell, Inc. *
35 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
37 #include <sys/socket.h> /**** needed by gethostbyname et al *****/
38 #define X_INCLUDE_NETDB_H
39 #define XOS_USE_XT_LOCKING
40 #include <X11/Xos_r.h>
43 #include <bms/connect.h>
44 #include <bms/MemoryMgr.h> /* Xe_make_struct, make_str ... */
45 #include <bms/XeUserMsg.h>
46 #include <bms/pathwexp.h> /* Xe_shellexp */
47 #include "DtSvcLock.h"
49 #include <codelibs/pathutils.h>
54 static XeString context_host = NULL;
56 static XeString FindDomainHost (XeString host_spec);
57 static void UnParseFileString (XeString host, XeString path);
58 static int GetDomainName (XeString buffer, unsigned int bufsize);
60 #define strequal(xxx_str1, xxx_str2) (!strcmp(xxx_str1, xxx_str2))
62 /*------------------------------------------------------------------------+*/
64 XeCreateContextString(XeString host,
67 /*------------------------------------------------------------------------+*/
69 XeString context_string;
71 host = XeFindShortHost(host);
73 if ((strequal(directory, (XeString)"")) || (directory == NULL)){
74 if ((strequal(file, (XeString)"")) || (file == NULL)){
75 return((XeString) NULL);
77 context_string = XeMalloc (strlen(host) + strlen(file) + 2);
78 sprintf (context_string, "%s:%s", host, file);
81 if ((strequal(file, (XeString)"")) || (file == NULL)){
82 context_string = XeMalloc(strlen(host) + strlen(directory) + 2);
83 sprintf (context_string, "%s:%s", host, directory);
86 context_string = XeMalloc(strlen(host) + strlen(directory) +
88 sprintf (context_string, "%s:%s/%s", host, directory, file);
92 return(context_string);
95 /*------------------------------------------------------------------------+*/
97 XeFindShortHost(XeString host_spec)
98 /*------------------------------------------------------------------------+*/
100 XeString host, ptr, ptr2;
101 XeChar localhost[MAXHOSTNAMELEN];
103 if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
106 context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
107 Xegetcwd(context_host, MAXHOSTNAMELEN);
109 _DtSvcProcessUnlock();
110 host_spec = context_host;
112 host_spec = Xe_shellexp(host_spec);
113 ptr = strstr(host_spec, (XeString)".");
114 if (!ptr) /* short name already */
115 host = strdup(host_spec);
117 GetDomainName(localhost, MAXHOSTNAMELEN);
118 ptr2 = strstr(localhost, (XeString)".");
119 if (ptr2 && strequal(ptr, ptr2)) { /* domains same, can eliminate */
120 host = Xe_make_ntype(ptr-host_spec+1, XeChar);
121 strncpy(host, host_spec, ptr-host_spec); /* copy only up to "." */
122 host[ptr-host_spec] = NULL; /* NULL terminate copy */
125 host = strdup(host_spec);
130 /* temporary without domain comparisons */
131 /*------------------------------------------------------------------------+*/
133 XeFindHost(XeString host_spec)
134 /*------------------------------------------------------------------------+*/
136 if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
139 context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
140 Xegetcwd(context_host, MAXHOSTNAMELEN);
142 _DtSvcProcessUnlock();
143 host_spec = context_host;
145 host_spec = Xe_shellexp(host_spec);
146 return strdup(host_spec);
150 /* this should be XeFindHost but is called other name for 1.0 operation
151 using only simple names if in short domain. See defect HZNlp05737 */
153 /*------------------------------------------------------------------------+*/
155 FindDomainHost(XeString host_spec)
156 /*------------------------------------------------------------------------+*/
160 XeChar localhost[MAXHOSTNAMELEN];
162 if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
165 context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
166 Xegetcwd(context_host, MAXHOSTNAMELEN);
168 _DtSvcProcessUnlock();
169 host_spec = context_host;
171 else if (strequal(host_spec, (XeString)"*")) {
172 host_spec = strdup((XeString)"*");
175 host_spec = Xe_shellexp(host_spec);
176 ptr = strstr(host_spec, (XeString)".");
178 host = strdup(host_spec);
180 GetDomainName(localhost, MAXHOSTNAMELEN);
181 ptr = strstr(localhost, (XeString)"."); /* points to domain name if one exists */
183 host = Xe_make_ntype(strlen(host_spec)+strlen(ptr)+1, XeChar);
184 strcpy(host, host_spec);
188 host = strdup(host_spec);
193 /****** XeParseFileString and UnParseFileString work together to munge and
194 unmunge a path into a host path pair. UnParseFileString DOES NOT WORK
195 FOR ARBITRARY STRINGS. It is not a general functions (it is a hack).
196 Do not use It as a general function.
199 /*------------------------------------------------------------------------+*/
201 UnParseFileString(XeString host, XeString path)
202 /*------------------------------------------------------------------------+*/
204 if (host) { /* there was a host in the original string */
205 *--path = (XeChar) ':';
210 /*------------------------------------------------------------------------+*/
211 XeParseFileString(XeString line,
214 /*------------------------------------------------------------------------+*/
216 XeString current_position = line;
218 if ((XeChar)'/' == *line) {
219 *host_addr = XeString_NULL;
224 while (*current_position && ((XeChar) ':' != *current_position)) {
226 if ((len = mblen(current_position, MB_CUR_MAX)) > 1)
227 current_position += len;
231 if (*current_position) { /* host was specified */
232 *current_position++ = XeChar_NULL; /* ":" goes to NULL */
234 *path_addr = current_position;
236 *host_addr = XeString_NULL;
242 /***** Xegethostname is a replacement for gethostname which always returns the
243 canonical (domain) hostname
246 static XeString domainname = XeString_NULL;
248 /* this should be Xegethostname but is called other name for 1.0 operation
249 using only simple names if in short domain. See defect HZNlp05737 */
251 /*------------------------------------------------------------------------+*/
253 GetDomainName(XeString buffer, unsigned int bufsize)
254 /*------------------------------------------------------------------------+*/
256 XeString tmpbuf = Xe_make_buffer(bufsize);
258 struct hostent *host_ret;
259 _Xgethostbynameparams host_buf;
260 static Boolean firstPass = TRUE;
263 /* try to get domain name from hostname */
264 if (status = gethostname(tmpbuf, bufsize)) {
266 return status; /* failed gethostname */
268 ptr = strstr(tmpbuf, (XeString)".");
270 if (domainname && ptr && strcmp(domainname, ptr)) /* domains are different */
271 _DtSimpleError(XeProgName, XeWarning, NULL, (XeString) "><Domain configured in hostname and domain server are different: '%s', '%s'", domainname, ptr);
272 if (!domainname && ptr)
273 domainname = strdup(ptr);
274 if (ptr) { /* "." in hostname */
275 strncpy(buffer, tmpbuf, bufsize);
277 _DtSvcProcessUnlock();
281 /* look up domain name in domain server */
282 if (!domainname && (firstPass)) {
284 host_ret = _XGethostbyname(tmpbuf, host_buf);
285 if (host_ret == NULL) {
286 _DtSimpleError(XeProgName, XeWarning, NULL, (XeString) "><%s not found in hosts database", tmpbuf);
287 _DtSvcProcessUnlock();
290 if (ptr = strstr(host_ret->h_name, (XeString)".")) /* if dot in canonical name */
291 domainname = strdup(ptr);
294 /* construct full domain name for return */
295 strncpy(buffer, tmpbuf, bufsize);
297 strncat(buffer, domainname, bufsize - strlen(tmpbuf));
299 _DtSvcProcessUnlock();
303 /*------------------------------------------------------------------------+*/
305 Xegetshorthostname(XeString buffer, unsigned int bufsize)
306 /*------------------------------------------------------------------------+*/
311 if (status = gethostname(buffer, bufsize))
312 return status; /* failed gethostname */
313 if (ptr = strstr(buffer, (XeString)"."))
314 *ptr = NULL; /* delete domain name if there is one */
318 /*------------------------------------------------------------------------+*/
320 Xegethostname(XeString buffer, unsigned int bufsize)
321 /*------------------------------------------------------------------------+*/
323 return Xegetshorthostname(buffer, bufsize);
327 /*------------------------------------------------------------------------+*/
329 XeIsLocalHostP(XeString hostname)
330 /*------------------------------------------------------------------------+*/
332 XeChar localhost[MAXHOSTNAMELEN];
333 XeString found_host = FindDomainHost(hostname);
336 GetDomainName(localhost, MAXHOSTNAMELEN);
337 status = strcmp(localhost, found_host)==0;
342 /*------------------------------------------------------------------------+*/
344 XeIsSameHostP(XeString host1, XeString host2)
345 /*------------------------------------------------------------------------+*/
347 XeString long_host1 = FindDomainHost(host1);
348 XeString long_host2 = FindDomainHost(host2);
349 int status = strcmp(long_host1, long_host2) == 0;
350 if (!host1 || !host1[0] || !strcmp(host1,(XeString)"-")
351 || !host2 || !host2[0] || !strcmp(host2,(XeString)"-"))
352 status = strcmp(host1, host2) == 0;
360 /* note the following functions use char not Xechar because they are
361 plug replacements for the Unix functions */
363 static char *last_env_string = NULL; /* save env so it can be freed later */
365 /* Note: only use this function for $PWD as it assumes it can free the
366 env variable when a new one is assigned -- this will only be true if
367 the same variable is used for all calls to copying_putenv */
369 copying_putenv(char *env)
371 char *env_copy = XeCopyStringM(env);
375 XeFree(last_env_string);
376 last_env_string = env_copy;
377 _DtSvcProcessUnlock();
380 /*------------------------------------------------------------------------+*/
382 Xegetcwd(char *buf, int size)
383 /*------------------------------------------------------------------------+*/
385 Boolean pwd_ok = FALSE;
386 char *env, *current_dir;
388 if (current_dir = getenv("PWD")) { /* use PWD instead of slow call */
390 struct stat sb1, sb2;
392 /* The code used to copy size-1 bytes. This is a waste most of */
393 /* the time. All we need to copy is strlen($PWD) bytes unless */
394 /* there are more bytes that fit into the array passed in. */
396 int len=strlen(current_dir);
400 strncpy(buf, current_dir, len);
403 /* Make sure $PWD is the same as "." before we trust it. */
404 /* All this is still much faster the getcwd() esp. on UX discless. */
405 s1 = stat(buf, &sb1);
406 s2 = stat(".", &sb2);
408 /* If device and inode are the same, we have a match */
409 pwd_ok = ((s1 == 0 && s2 == 0) &&
410 (sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino) );
414 current_dir = getcwd(buf, size);
415 env = XeMalloc(MAXPATHLEN+10);
416 sprintf(env, "PWD=%s", buf);
417 copying_putenv(env); /* set PWD if necessary for later cache use */
418 if (env) XeFree(env);
423 /*------------------------------------------------------------------------+*/
425 Xechdir (const char *path)
426 /*------------------------------------------------------------------------+*/
429 char *simple_path = NULL;
431 char buf[MAXPATHLEN+10];
432 if ((status = chdir(path))==0) {
433 env = XeMalloc(MAXPATHLEN+10);
435 if (path[0] != '/') { /* relative path */
436 path = getcwd(buf, sizeof buf);
437 sprintf(env, "PWD=%s", path);
440 char *canon_path = pathcollapse(path, NULL, FALSE);
442 sprintf(env, "PWD=%s", canon_path);
443 /* note XeFree() not appropriate if Xemalloc not used */
447 copying_putenv(env); /* update PWD if directory changed */
448 if (env) XeFree(env);