Files
cdesktop/cde/lib/DtSvc/DtEncap/connect.c
2018-04-28 12:30:20 -06:00

456 lines
14 KiB
C

/*
* 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 <Dt/UserMsg.h>
#include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
#include <sys/socket.h> /**** needed by gethostbyname et al *****/
#define X_INCLUDE_NETDB_H
#define XOS_USE_XT_LOCKING
#include <X11/Xos_r.h>
#include <bms/bms.h>
#include <bms/connect.h>
#include <bms/MemoryMgr.h> /* Xe_make_struct, make_str ... */
#include <bms/XeUserMsg.h>
#include <bms/pathwexp.h> /* Xe_shellexp */
#include "DtSvcLock.h"
#include <codelibs/pathutils.h>
/*
* 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) "><Domain configured in hostname and domain server are different: '%s', '%s'", domainname, ptr);
if (!domainname && ptr)
domainname = strdup(ptr);
if (ptr) { /* "." in hostname */
strncpy(buffer, tmpbuf, bufsize);
XeFree(tmpbuf);
_DtSvcProcessUnlock();
return 0;
}
/* look up domain name in domain server */
if (!domainname && (firstPass)) {
firstPass = FALSE;
host_ret = _XGethostbyname(tmpbuf, host_buf);
if (host_ret == NULL) {
_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;
}