/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* * File: connect.c $TOG: connect.c /main/8 1998/04/09 17:44:33 mgreess $ * Language: C * * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved. * * (c) Copyright 1993, 1994 Hewlett-Packard Company * * (c) Copyright 1993, 1994 International Business Machines Corp. * * (c) Copyright 1993, 1994 Sun Microsystems, Inc. * * (c) Copyright 1993, 1994 Novell, Inc. * */ #include
#include /* NOTE: sbport.h must be the first include. */ #include /**** needed by gethostbyname et al *****/ #define X_INCLUDE_NETDB_H #define XOS_USE_XT_LOCKING #include #include #include #include /* Xe_make_struct, make_str ... */ #include #include /* Xe_shellexp */ #include "DtSvcLock.h" #include /* * local variables */ static XeString context_host = NULL; static XeString FindDomainHost (XeString host_spec); static void UnParseFileString (XeString host, XeString path); static int GetDomainName (XeString buffer, unsigned int bufsize); #define strequal(xxx_str1, xxx_str2) (!strcmp(xxx_str1, xxx_str2)) /*------------------------------------------------------------------------+*/ XeString XeCreateContextString(XeString host, XeString directory, XeString file) /*------------------------------------------------------------------------+*/ { XeString context_string; host = XeFindShortHost(host); if ((strequal(directory, (XeString)"")) || (directory == NULL)){ if ((strequal(file, (XeString)"")) || (file == NULL)){ Xe_release_str(host); return((XeString) NULL); } else { context_string = XeMalloc (strlen(host) + strlen(file) + 2); sprintf (context_string, "%s:%s", host, file); } } else { if ((strequal(file, (XeString)"")) || (file == NULL)){ context_string = XeMalloc(strlen(host) + strlen(directory) + 2); sprintf (context_string, "%s:%s", host, directory); } else { context_string = XeMalloc(strlen(host) + strlen(directory) + strlen(file) + 3); sprintf (context_string, "%s:%s/%s", host, directory, file); } } Xe_release_str(host); return(context_string); } /*------------------------------------------------------------------------+*/ XeString XeFindShortHost(XeString host_spec) /*------------------------------------------------------------------------+*/ { XeString host, ptr, ptr2; XeChar localhost[MAXHOSTNAMELEN]; if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) { _DtSvcProcessLock(); if (!context_host){ context_host = (XeString) XeMalloc (MAXHOSTNAMELEN); Xegetcwd(context_host, MAXHOSTNAMELEN); } _DtSvcProcessUnlock(); host_spec = context_host; } host_spec = Xe_shellexp(host_spec); ptr = strstr(host_spec, (XeString)"."); if (!ptr) /* short name already */ host = strdup(host_spec); else { GetDomainName(localhost, MAXHOSTNAMELEN); ptr2 = strstr(localhost, (XeString)"."); if (ptr2 && strequal(ptr, ptr2)) { /* domains same, can eliminate */ host = Xe_make_ntype(ptr-host_spec+1, XeChar); strncpy(host, host_spec, ptr-host_spec); /* copy only up to "." */ host[ptr-host_spec] = '\0'; /* NULL terminate copy */ } else host = strdup(host_spec); } return host; } /* temporary without domain comparisons */ /*------------------------------------------------------------------------+*/ XeString XeFindHost(XeString host_spec) /*------------------------------------------------------------------------+*/ { if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) { _DtSvcProcessLock(); if (!context_host){ context_host = (XeString) XeMalloc (MAXHOSTNAMELEN); Xegetcwd(context_host, MAXHOSTNAMELEN); } _DtSvcProcessUnlock(); host_spec = context_host; } host_spec = Xe_shellexp(host_spec); return strdup(host_spec); } /* this should be XeFindHost but is called other name for 1.0 operation using only simple names if in short domain. See defect HZNlp05737 */ /*------------------------------------------------------------------------+*/ static XeString FindDomainHost(XeString host_spec) /*------------------------------------------------------------------------+*/ { XeString host; XeString ptr; XeChar localhost[MAXHOSTNAMELEN]; if (!host_spec || !host_spec[0] || strequal(host_spec, (XeString)"-")) { _DtSvcProcessLock(); if (!context_host){ context_host = (XeString) XeMalloc (MAXHOSTNAMELEN); Xegetcwd(context_host, MAXHOSTNAMELEN); } _DtSvcProcessUnlock(); host_spec = context_host; } else if (strequal(host_spec, (XeString)"*")) { host_spec = strdup((XeString)"*"); return host_spec; } host_spec = Xe_shellexp(host_spec); ptr = strstr(host_spec, (XeString)"."); if (ptr) host = strdup(host_spec); else { GetDomainName(localhost, MAXHOSTNAMELEN); ptr = strstr(localhost, (XeString)"."); /* points to domain name if one exists */ if (ptr) { host = Xe_make_ntype(strlen(host_spec)+strlen(ptr)+1, XeChar); strcpy(host, host_spec); strcat(host, ptr); } else host = strdup(host_spec); } return(host); } /****** XeParseFileString and UnParseFileString work together to munge and unmunge a path into a host path pair. UnParseFileString DOES NOT WORK FOR ARBITRARY STRINGS. It is not a general functions (it is a hack). Do not use It as a general function. ******/ /*------------------------------------------------------------------------+*/ static void UnParseFileString(XeString host, XeString path) /*------------------------------------------------------------------------+*/ { if (host) { /* there was a host in the original string */ *--path = (XeChar) ':'; } } /*------------------------------------------------------------------------+*/ int XeParseFileString(XeString line, XeString *host_addr, XeString *path_addr) /*------------------------------------------------------------------------+*/ { XeString current_position = line; if ((XeChar)'/' == *line) { *host_addr = XeString_NULL; *path_addr = line; return(0); } while (*current_position && ((XeChar) ':' != *current_position)) { int len; if ((len = mblen(current_position, MB_CUR_MAX)) > 1) current_position += len; else current_position++; } if (*current_position) { /* host was specified */ *current_position++ = XeChar_NULL; /* ":" goes to NULL */ *host_addr = line; *path_addr = current_position; } else { *host_addr = XeString_NULL; *path_addr = line; } return(0); } /***** Xegethostname is a replacement for gethostname which always returns the canonical (domain) hostname ******/ static XeString domainname = XeString_NULL; /* this should be Xegethostname but is called other name for 1.0 operation using only simple names if in short domain. See defect HZNlp05737 */ /*------------------------------------------------------------------------+*/ static int GetDomainName(XeString buffer, unsigned int bufsize) /*------------------------------------------------------------------------+*/ { XeString tmpbuf = Xe_make_buffer(bufsize); XeString ptr; struct hostent *host_ret; _Xgethostbynameparams host_buf; static Boolean firstPass = TRUE; int status; /* try to get domain name from hostname */ if ((status = gethostname(tmpbuf, bufsize))) { XeFree(tmpbuf); return status; /* failed gethostname */ } ptr = strstr(tmpbuf, (XeString)"."); _DtSvcProcessLock(); if (domainname && ptr && strcmp(domainname, ptr)) /* domains are different */ _DtSimpleError(XeProgName, XeWarning, NULL, (XeString) "><%s not found in hosts database", tmpbuf); _DtSvcProcessUnlock(); return -1; } if ((ptr = strstr(host_ret->h_name, (XeString)"."))) /* if dot in canonical name */ domainname = strdup(ptr); } /* construct full domain name for return */ strncpy(buffer, tmpbuf, bufsize); if (domainname) strncat(buffer, domainname, bufsize - strlen(tmpbuf)); XeFree(tmpbuf); _DtSvcProcessUnlock(); return 0; } /*------------------------------------------------------------------------+*/ int Xegetshorthostname(XeString buffer, unsigned int bufsize) /*------------------------------------------------------------------------+*/ { XeString ptr; int status; if ((status = gethostname(buffer, bufsize))) return status; /* failed gethostname */ if ((ptr = strstr(buffer, (XeString)"."))) *ptr = '\0'; /* delete domain name if there is one */ return 0; } /*------------------------------------------------------------------------+*/ int Xegethostname(XeString buffer, unsigned int bufsize) /*------------------------------------------------------------------------+*/ { return Xegetshorthostname(buffer, bufsize); } /*------------------------------------------------------------------------+*/ Boolean XeIsLocalHostP(XeString hostname) /*------------------------------------------------------------------------+*/ { XeChar localhost[MAXHOSTNAMELEN]; XeString found_host = FindDomainHost(hostname); int status; GetDomainName(localhost, MAXHOSTNAMELEN); status = strcmp(localhost, found_host)==0; XeFree(found_host); return status; } /*------------------------------------------------------------------------+*/ Boolean XeIsSameHostP(XeString host1, XeString host2) /*------------------------------------------------------------------------+*/ { XeString long_host1 = FindDomainHost(host1); XeString long_host2 = FindDomainHost(host2); int status = strcmp(long_host1, long_host2) == 0; if (!host1 || !host1[0] || !strcmp(host1,(XeString)"-") || !host2 || !host2[0] || !strcmp(host2,(XeString)"-")) status = strcmp(host1, host2) == 0; XeFree(long_host1); XeFree(long_host2); return status; } /* note the following functions use char not Xechar because they are plug replacements for the Unix functions */ static char *last_env_string = NULL; /* save env so it can be freed later */ /* Note: only use this function for $PWD as it assumes it can free the env variable when a new one is assigned -- this will only be true if the same variable is used for all calls to copying_putenv */ static void copying_putenv(char *env) { char *env_copy = XeCopyStringM(env); putenv(env_copy); _DtSvcProcessLock(); if (last_env_string) XeFree(last_env_string); last_env_string = env_copy; _DtSvcProcessUnlock(); } /*------------------------------------------------------------------------+*/ char * Xegetcwd(char *buf, int size) /*------------------------------------------------------------------------+*/ { Boolean pwd_ok = FALSE; char *env, *current_dir; if ((current_dir = getenv("PWD"))) { /* use PWD instead of slow call */ int s1, s2; struct stat sb1, sb2; /* The code used to copy size-1 bytes. This is a waste most of */ /* the time. All we need to copy is strlen($PWD) bytes unless */ /* there are more bytes that fit into the array passed in. */ int len=strlen(current_dir); if (len > size-1) len = size-1; strncpy(buf, current_dir, len); buf[len] = '\0'; /* Make sure $PWD is the same as "." before we trust it. */ /* All this is still much faster the getcwd() esp. on UX discless. */ s1 = stat(buf, &sb1); s2 = stat(".", &sb2); /* If device and inode are the same, we have a match */ pwd_ok = ((s1 == 0 && s2 == 0) && (sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino) ); } if (!pwd_ok) { current_dir = getcwd(buf, size); env = XeMalloc(MAXPATHLEN+10); sprintf(env, "PWD=%s", buf); copying_putenv(env); /* set PWD if necessary for later cache use */ XeFree(env); } return current_dir; } /*------------------------------------------------------------------------+*/ int Xechdir (const char *path) /*------------------------------------------------------------------------+*/ { int status; char *simple_path = NULL; char *env; char buf[MAXPATHLEN+10]; if ((status = chdir(path))==0) { env = XeMalloc(MAXPATHLEN+10); if (path[0] != '/') { /* relative path */ path = getcwd(buf, sizeof buf); sprintf(env, "PWD=%s", path); } else { char *canon_path = pathcollapse(path, NULL, FALSE); /* absolute path */ sprintf(env, "PWD=%s", canon_path); /* note XeFree() not appropriate if Xemalloc not used */ free(canon_path); } copying_putenv(env); /* update PWD if directory changed */ XeFree(env); } return status; }