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 libraries 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 <Dt/UserMsg.h>
37 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
39 #include <sys/socket.h> /**** needed by gethostbyname et al *****/
40 #define X_INCLUDE_NETDB_H
41 #define XOS_USE_XT_LOCKING
42 #include <X11/Xos_r.h>
45 #include <bms/connect.h>
46 #include <bms/MemoryMgr.h> /* Xe_make_struct, make_str ... */
47 #include <bms/XeUserMsg.h>
48 #include <bms/pathwexp.h> /* Xe_shellexp */
49 #include "DtSvcLock.h"
51 #include <codelibs/pathutils.h>
56 static XeString context_host = NULL;
58 static XeString FindDomainHost (XeString host_spec);
59 static void UnParseFileString (XeString host, XeString path);
60 static int GetDomainName (XeString buffer, unsigned int bufsize);
62 #define strequal(xxx_str1, xxx_str2) (!strcmp(xxx_str1, xxx_str2))
64 /*------------------------------------------------------------------------+*/
66 XeCreateContextString(XeString host,
69 /*------------------------------------------------------------------------+*/
71 XeString context_string;
73 host = XeFindShortHost(host);
75 if ((strequal(directory, (XeString)"")) || (directory == NULL)){
76 if ((strequal(file, (XeString)"")) || (file == NULL)){
78 return((XeString) NULL);
80 context_string = XeMalloc (strlen(host) + strlen(file) + 2);
81 sprintf (context_string, "%s:%s", host, file);
84 if ((strequal(file, (XeString)"")) || (file == NULL)){
85 context_string = XeMalloc(strlen(host) + strlen(directory) + 2);
86 sprintf (context_string, "%s:%s", host, directory);
89 context_string = XeMalloc(strlen(host) + strlen(directory) +
91 sprintf (context_string, "%s:%s/%s", host, directory, file);
95 return(context_string);
98 /*------------------------------------------------------------------------+*/
100 XeFindShortHost(XeString host_spec)
101 /*------------------------------------------------------------------------+*/
103 XeString host, ptr, ptr2;
104 XeChar localhost[MAXHOSTNAMELEN];
106 if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
109 context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
110 Xegetcwd(context_host, MAXHOSTNAMELEN);
112 _DtSvcProcessUnlock();
113 host_spec = context_host;
115 host_spec = Xe_shellexp(host_spec);
116 ptr = strstr(host_spec, (XeString)".");
117 if (!ptr) /* short name already */
118 host = strdup(host_spec);
120 GetDomainName(localhost, MAXHOSTNAMELEN);
121 ptr2 = strstr(localhost, (XeString)".");
122 if (ptr2 && strequal(ptr, ptr2)) { /* domains same, can eliminate */
123 host = Xe_make_ntype(ptr-host_spec+1, XeChar);
124 strncpy(host, host_spec, ptr-host_spec); /* copy only up to "." */
125 host[ptr-host_spec] = '\0'; /* NULL terminate copy */
128 host = strdup(host_spec);
133 /* temporary without domain comparisons */
134 /*------------------------------------------------------------------------+*/
136 XeFindHost(XeString host_spec)
137 /*------------------------------------------------------------------------+*/
139 if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
142 context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
143 Xegetcwd(context_host, MAXHOSTNAMELEN);
145 _DtSvcProcessUnlock();
146 host_spec = context_host;
148 host_spec = Xe_shellexp(host_spec);
149 return strdup(host_spec);
153 /* this should be XeFindHost but is called other name for 1.0 operation
154 using only simple names if in short domain. See defect HZNlp05737 */
156 /*------------------------------------------------------------------------+*/
158 FindDomainHost(XeString host_spec)
159 /*------------------------------------------------------------------------+*/
163 XeChar localhost[MAXHOSTNAMELEN];
165 if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) {
168 context_host = (XeString) XeMalloc (MAXHOSTNAMELEN);
169 Xegetcwd(context_host, MAXHOSTNAMELEN);
171 _DtSvcProcessUnlock();
172 host_spec = context_host;
174 else if (strequal(host_spec, (XeString)"*")) {
175 host_spec = strdup((XeString)"*");
178 host_spec = Xe_shellexp(host_spec);
179 ptr = strstr(host_spec, (XeString)".");
181 host = strdup(host_spec);
183 GetDomainName(localhost, MAXHOSTNAMELEN);
184 ptr = strstr(localhost, (XeString)"."); /* points to domain name if one exists */
186 host = Xe_make_ntype(strlen(host_spec)+strlen(ptr)+1, XeChar);
187 strcpy(host, host_spec);
191 host = strdup(host_spec);
196 /****** XeParseFileString and UnParseFileString work together to munge and
197 unmunge a path into a host path pair. UnParseFileString DOES NOT WORK
198 FOR ARBITRARY STRINGS. It is not a general functions (it is a hack).
199 Do not use It as a general function.
202 /*------------------------------------------------------------------------+*/
204 UnParseFileString(XeString host, XeString path)
205 /*------------------------------------------------------------------------+*/
207 if (host) { /* there was a host in the original string */
208 *--path = (XeChar) ':';
213 /*------------------------------------------------------------------------+*/
215 XeParseFileString(XeString line,
218 /*------------------------------------------------------------------------+*/
220 XeString current_position = line;
222 if ((XeChar)'/' == *line) {
223 *host_addr = XeString_NULL;
228 while (*current_position && ((XeChar) ':' != *current_position)) {
230 if ((len = mblen(current_position, MB_CUR_MAX)) > 1)
231 current_position += len;
235 if (*current_position) { /* host was specified */
236 *current_position++ = XeChar_NULL; /* ":" goes to NULL */
238 *path_addr = current_position;
240 *host_addr = XeString_NULL;
246 /***** Xegethostname is a replacement for gethostname which always returns the
247 canonical (domain) hostname
250 static XeString domainname = XeString_NULL;
252 /* this should be Xegethostname but is called other name for 1.0 operation
253 using only simple names if in short domain. See defect HZNlp05737 */
255 /*------------------------------------------------------------------------+*/
257 GetDomainName(XeString buffer, unsigned int bufsize)
258 /*------------------------------------------------------------------------+*/
260 XeString tmpbuf = Xe_make_buffer(bufsize);
262 struct hostent *host_ret;
263 _Xgethostbynameparams host_buf;
264 static Boolean firstPass = TRUE;
267 /* try to get domain name from hostname */
268 if ((status = gethostname(tmpbuf, bufsize))) {
270 return status; /* failed gethostname */
272 ptr = strstr(tmpbuf, (XeString)".");
274 if (domainname && ptr && strcmp(domainname, ptr)) /* domains are different */
275 _DtSimpleError(XeProgName, XeWarning, NULL, (XeString) "><Domain configured in hostname and domain server are different: '%s', '%s'", domainname, ptr);
276 if (!domainname && ptr)
277 domainname = strdup(ptr);
278 if (ptr) { /* "." in hostname */
279 strncpy(buffer, tmpbuf, bufsize);
281 _DtSvcProcessUnlock();
285 /* look up domain name in domain server */
286 if (!domainname && (firstPass)) {
288 host_ret = _XGethostbyname(tmpbuf, host_buf);
289 if (host_ret == NULL) {
290 _DtSimpleError(XeProgName, XeWarning, NULL, (XeString) "><%s not found in hosts database", tmpbuf);
291 _DtSvcProcessUnlock();
294 if ((ptr = strstr(host_ret->h_name, (XeString)"."))) /* if dot in canonical name */
295 domainname = strdup(ptr);
298 /* construct full domain name for return */
299 strncpy(buffer, tmpbuf, bufsize);
301 strncat(buffer, domainname, bufsize - strlen(tmpbuf));
303 _DtSvcProcessUnlock();
307 /*------------------------------------------------------------------------+*/
309 Xegetshorthostname(XeString buffer, unsigned int bufsize)
310 /*------------------------------------------------------------------------+*/
315 if ((status = gethostname(buffer, bufsize)))
316 return status; /* failed gethostname */
317 if ((ptr = strstr(buffer, (XeString)".")))
318 *ptr = '\0'; /* delete domain name if there is one */
322 /*------------------------------------------------------------------------+*/
324 Xegethostname(XeString buffer, unsigned int bufsize)
325 /*------------------------------------------------------------------------+*/
327 return Xegetshorthostname(buffer, bufsize);
331 /*------------------------------------------------------------------------+*/
333 XeIsLocalHostP(XeString hostname)
334 /*------------------------------------------------------------------------+*/
336 XeChar localhost[MAXHOSTNAMELEN];
337 XeString found_host = FindDomainHost(hostname);
340 GetDomainName(localhost, MAXHOSTNAMELEN);
341 status = strcmp(localhost, found_host)==0;
346 /*------------------------------------------------------------------------+*/
348 XeIsSameHostP(XeString host1, XeString host2)
349 /*------------------------------------------------------------------------+*/
351 XeString long_host1 = FindDomainHost(host1);
352 XeString long_host2 = FindDomainHost(host2);
353 int status = strcmp(long_host1, long_host2) == 0;
354 if (!host1 || !host1[0] || !strcmp(host1,(XeString)"-")
355 || !host2 || !host2[0] || !strcmp(host2,(XeString)"-"))
356 status = strcmp(host1, host2) == 0;
364 /* note the following functions use char not Xechar because they are
365 plug replacements for the Unix functions */
367 static char *last_env_string = NULL; /* save env so it can be freed later */
369 /* Note: only use this function for $PWD as it assumes it can free the
370 env variable when a new one is assigned -- this will only be true if
371 the same variable is used for all calls to copying_putenv */
373 copying_putenv(char *env)
375 char *env_copy = XeCopyStringM(env);
379 XeFree(last_env_string);
380 last_env_string = env_copy;
381 _DtSvcProcessUnlock();
384 /*------------------------------------------------------------------------+*/
386 Xegetcwd(char *buf, int size)
387 /*------------------------------------------------------------------------+*/
389 Boolean pwd_ok = FALSE;
390 char *env, *current_dir;
392 if ((current_dir = getenv("PWD"))) { /* use PWD instead of slow call */
394 struct stat sb1, sb2;
396 /* The code used to copy size-1 bytes. This is a waste most of */
397 /* the time. All we need to copy is strlen($PWD) bytes unless */
398 /* there are more bytes that fit into the array passed in. */
400 int len=strlen(current_dir);
404 strncpy(buf, current_dir, len);
407 /* Make sure $PWD is the same as "." before we trust it. */
408 /* All this is still much faster the getcwd() esp. on UX discless. */
409 s1 = stat(buf, &sb1);
410 s2 = stat(".", &sb2);
412 /* If device and inode are the same, we have a match */
413 pwd_ok = ((s1 == 0 && s2 == 0) &&
414 (sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino) );
418 current_dir = getcwd(buf, size);
419 env = XeMalloc(MAXPATHLEN+10);
420 sprintf(env, "PWD=%s", buf);
421 copying_putenv(env); /* set PWD if necessary for later cache use */
427 /*------------------------------------------------------------------------+*/
429 Xechdir (const char *path)
430 /*------------------------------------------------------------------------+*/
433 char *simple_path = NULL;
435 char buf[MAXPATHLEN+10];
436 if ((status = chdir(path))==0) {
437 env = XeMalloc(MAXPATHLEN+10);
439 if (path[0] != '/') { /* relative path */
440 path = getcwd(buf, sizeof buf);
441 sprintf(env, "PWD=%s", path);
444 char *canon_path = pathcollapse(path, NULL, FALSE);
446 sprintf(env, "PWD=%s", canon_path);
447 /* note XeFree() not appropriate if Xemalloc not used */
451 copying_putenv(env); /* update PWD if directory changed */