Back to index

im-sdk  12.3.91
Xtransutil.c
Go to the documentation of this file.
00001 /* $XConsortium: Xtransutil.c,v 1.19 95/02/10 17:54:09 mor Exp $ */
00002 /*
00003 
00004 Copyright (c) 1993, 1994  X Consortium
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining
00007 a copy of this software and associated documentation files (the
00008 "Software"), to deal in the Software without restriction, including
00009 without limitation the rights to use, copy, modify, merge, publish,
00010 distribute, sublicense, and/or sell copies of the Software, and to
00011 permit persons to whom the Software is furnished to do so, subject to
00012 the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included
00015 in all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00018 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00019 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00020 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
00021 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00022 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00023 OTHER DEALINGS IN THE SOFTWARE.
00024 
00025 Except as contained in this notice, the name of the X Consortium shall
00026 not be used in advertising or otherwise to promote the sale, use or
00027 other dealings in this Software without prior written authorization
00028 from the X Consortium.
00029 
00030 */
00031 
00032 /* Copyright (c) 1993, 1994 NCR Corporation - Dayton, Ohio, USA
00033  *
00034  * All Rights Reserved
00035  *
00036  * Permission to use, copy, modify, and distribute this software and its
00037  * documentation for any purpose and without fee is hereby granted, provided
00038  * that the above copyright notice appear in all copies and that both that
00039  * copyright notice and this permission notice appear in supporting
00040  * documentation, and that the name NCR not be used in advertising
00041  * or publicity pertaining to distribution of the software without specific,
00042  * written prior permission.  NCR makes no representations about the
00043  * suitability of this software for any purpose.  It is provided "as is"
00044  * without express or implied warranty.
00045  *
00046  * NCRS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
00047  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
00048  * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
00049  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
00050  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
00051  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
00052  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00053  */
00054 
00055 /*
00056  * These are some utility functions created for convenience or to provide
00057  * an interface that is similar to an existing interface. These are built
00058  * only using the Transport Independant API, and have no knowledge of
00059  * the internal implementation.
00060  */
00061 
00062 #ifdef X11_t
00063 
00064 /*
00065  * These values come from X.h and Xauth.h, and MUST match them. Some
00066  * of these values are also defined by the ChangeHost protocol message.
00067  */
00068 
00069 #define FamilyInternet             0
00070 #define FamilyDECnet        1
00071 #define FamilyChaos         2
00072 #define FamilyAmoeba        33
00073 #define FamilyLocalHost            252
00074 #define FamilyKrb5Principal 253
00075 #define FamilyNetname              254
00076 #define FamilyLocal         256
00077 #define FamilyWild          65535
00078 
00079 /*
00080  * TRANS(ConvertAddress) converts a sockaddr based address to an
00081  * X authorization based address. Some of this is defined as part of
00082  * the ChangeHost protocol. The rest is just doen in a consistent manner.
00083  */
00084 
00085 int
00086 TRANS(ConvertAddress)(familyp,addrlenp,addrp)
00087 int    *familyp;
00088 int    *addrlenp;
00089 Xtransaddr    **addrp;
00090 {
00091 
00092     PRMSG(2,"TRANS(ConvertAddress)(%d,%d,%x)\n",*familyp,*addrlenp,*addrp);
00093 
00094     switch( *familyp )
00095     {
00096 #if defined(TCPCONN) || defined(STREAMSCONN)
00097     case AF_INET:
00098     {
00099        /*
00100         * Check for the BSD hack localhost address 127.0.0.1.
00101         * In this case, we are really FamilyLocal.
00102         */
00103 
00104        struct sockaddr_in saddr;
00105 #ifdef CRAY
00106 #ifdef OLDTCP
00107        int len = sizeof(saddr.sin_addr);
00108 #else
00109        int len = SIZEOF_in_addr;
00110 #endif /* OLDTCP */
00111        char *cp = (char *) &saddr.sin_addr;
00112 #else /* else not CRAY */
00113        int len = sizeof(saddr.sin_addr.s_addr);
00114        char *cp = (char *) &saddr.sin_addr.s_addr;
00115 #endif /* CRAY */
00116 
00117        memcpy (&saddr, *addrp, sizeof (struct sockaddr_in));
00118 
00119        if ((len == 4) && (cp[0] == 127) && (cp[1] == 0) &&
00120            (cp[2] == 0) && (cp[3] == 1))
00121        {
00122            *familyp=FamilyLocal;
00123        }
00124        else
00125        {
00126            *familyp=FamilyInternet;
00127            *addrlenp=len;
00128            memcpy(*addrp,&saddr.sin_addr,len);
00129        }
00130        break;
00131     }
00132 #endif /* defined(TCPCONN) || defined(STREAMSCONN) */
00133 
00134 #if defined(DNETCONN)
00135     case AF_DECnet:
00136     {
00137        struct sockaddr_dn saddr;
00138 
00139        memcpy (&saddr, *addrp, sizeof (struct sockaddr_dn));
00140 
00141        *familyp=FamilyDECnet;
00142        *addrlenp=sizeof(struct dn_naddr);
00143        memcpy(*addrp,&saddr.sdn_add,*addrlenp);
00144 
00145        break;
00146     }
00147 #endif /* defined(DNETCONN) */
00148 
00149 #if defined(UNIXCONN) || defined(LOCALCONN)
00150     case AF_UNIX:
00151     {
00152        *familyp=FamilyLocal;
00153        break;
00154     }
00155 #endif /* defined(UNIXCONN) || defined(LOCALCONN) */
00156 
00157 #if defined(AMRPCCONN)
00158     case AF_AMOEBA:
00159     {
00160        *familyp=FamilyAmoeba;
00161        break;
00162     }
00163 #endif
00164 #if defined(AMTCPCONN) && !(defined(TCPCONN) || defined(STREAMSCONN))
00165     case AF_INET:
00166     {
00167        *familyp=FamilyInternet;
00168        break;
00169     }
00170 #endif
00171 
00172     default:
00173        PRMSG(1,"TRANS(ConvertFamily) Unknown family type %d\n",
00174              *familyp, 0,0 );
00175        return -1;
00176     }
00177 
00178 
00179     if (*familyp == FamilyLocal)
00180     {
00181        /*
00182         * In the case of a local connection, we need to get the
00183         * host name for authentication.
00184         */
00185        
00186        char hostnamebuf[256];
00187        int len = TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
00188 
00189        if (len > 0) {
00190            if (*addrp && *addrlenp < (len + 1))
00191            {
00192               free ((char *) *addrp);
00193               *addrp = NULL;
00194            }
00195            if (!*addrp)
00196               *addrp = (Xtransaddr *) malloc (len + 1);
00197            if (*addrp) {
00198               strcpy ((char *) *addrp, hostnamebuf);
00199               *addrlenp = len;
00200            } else {
00201               *addrlenp = 0;
00202            }
00203        }
00204        else
00205        {
00206            if (*addrp)
00207               free ((char *) *addrp);
00208            *addrp = NULL;
00209            *addrlenp = 0;
00210        }
00211     }
00212 
00213     return 0;
00214 }
00215 
00216 #endif /* X11_t */
00217 
00218 #ifdef ICE_t
00219 
00220 #include <signal.h>
00221 
00222 char *
00223 TRANS(GetMyNetworkId) (ciptr)
00224 
00225 XtransConnInfo  ciptr;
00226 
00227 {
00228     int              family = ciptr->family;
00229     int              addrlen = ciptr->addrlen;
00230     char      *addr = ciptr->addr;
00231     char      hostnamebuf[256];
00232     char      *networkId = NULL;
00233     char      *transName = ciptr->transptr->TransName;
00234 
00235     if (gethostname (hostnamebuf, sizeof (hostnamebuf)) < 0)
00236     {
00237        return (NULL);
00238     }
00239 
00240     switch (family)
00241     {
00242 #if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN)
00243     case AF_UNIX:
00244     {
00245        struct sockaddr_un *saddr = (struct sockaddr_un *) addr;
00246        networkId = (char *) malloc (3 + strlen (transName) +
00247            strlen (hostnamebuf) + strlen (saddr->sun_path));
00248        sprintf (networkId, "%s/%s:%s", transName,
00249            hostnamebuf, saddr->sun_path);
00250        break;
00251     }
00252 #endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) */
00253 
00254 #if defined(TCPCONN) || defined(STREAMSCONN)
00255     case AF_INET:
00256     {
00257        struct sockaddr_in *saddr = (struct sockaddr_in *) addr;
00258        char portnumbuf[10];
00259 
00260        sprintf (portnumbuf, "%d", ntohs (saddr->sin_port));
00261        networkId = (char *) malloc (3 + strlen (transName) +
00262            strlen (hostnamebuf) + strlen (portnumbuf));
00263        sprintf (networkId, "%s/%s:%s", transName, hostnamebuf, portnumbuf);
00264        break;
00265     }
00266 #endif /* defined(TCPCONN) || defined(STREAMSCONN) */
00267 
00268 #if defined(DNETCONN)
00269     case AF_DECnet:
00270     {
00271        struct sockaddr_dn *saddr = (struct sockaddr_dn *) addr;
00272 
00273        networkId = (char *) malloc (
00274            13 + strlen (hostnamebuf) + saddr->sdn_objnamel);
00275        sprintf (networkId, "dnet/%s::%s",
00276            hostnamebuf, saddr->sdn_objname);
00277        break;
00278     }
00279 #endif /* defined(DNETCONN) */
00280 
00281     default:
00282        break;
00283     }
00284 
00285     return (networkId);
00286 }
00287 
00288 #include <setjmp.h>
00289 static jmp_buf env;
00290 
00291 #ifdef SIGALRM
00292 static int nameserver_timedout = 0;
00293 
00294 static 
00295 #ifdef SIGNALRETURNSINT
00296 int
00297 #else
00298 void
00299 #endif
00300 nameserver_lost(sig)
00301 {
00302   nameserver_timedout = 1;
00303   longjmp (env, -1);
00304   /* NOTREACHED */
00305 #ifdef SIGNALRETURNSINT
00306   return -1;                       /* for picky compilers */
00307 #endif
00308 }
00309 #endif /* SIGALARM */
00310 
00311 
00312 char *
00313 TRANS(GetPeerNetworkId) (ciptr)
00314 
00315 XtransConnInfo  ciptr;
00316 
00317 {
00318     int              family = ciptr->family;
00319     int              peer_addrlen = ciptr->peeraddrlen;
00320     char      *peer_addr = ciptr->peeraddr;
00321     char      *hostname;
00322     char      *networkId = NULL;
00323     char      addrbuf[256];
00324     char      *addr = NULL;
00325 
00326     switch (family)
00327     {
00328     case AF_UNSPEC:
00329 #if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN)
00330     case AF_UNIX:
00331     {
00332        if (gethostname (addrbuf, sizeof (addrbuf)) == 0)
00333            addr = addrbuf;
00334        break;
00335     }
00336 #endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) */
00337 
00338 #if defined(TCPCONN) || defined(STREAMSCONN)
00339     case AF_INET:
00340     {
00341        struct sockaddr_in *saddr = (struct sockaddr_in *) peer_addr;
00342        struct hostent *hp = NULL;
00343 #ifndef WIN32
00344        char *inet_ntoa();
00345 #endif
00346 
00347 #ifdef SIGALRM
00348        /*
00349         * gethostbyaddr can take a LONG time if the host does not exist.
00350         * Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
00351         * that something is wrong and do not make the user wait.
00352         * gethostbyaddr will continue after a signal, so we have to
00353         * jump out of it. 
00354         */
00355 
00356        nameserver_timedout = 0;
00357        signal (SIGALRM, nameserver_lost);
00358        alarm (4);
00359        if (setjmp(env) == 0) {
00360 #endif
00361            hp = gethostbyaddr ((char *) &saddr->sin_addr,
00362               sizeof (saddr->sin_addr), AF_INET);
00363 #ifdef SIGALRM
00364        }
00365        alarm (0);
00366 #endif
00367        if (hp)
00368          addr = hp->h_name;
00369        else
00370          addr = inet_ntoa (saddr->sin_addr);
00371        break;
00372     }
00373 
00374 #endif /* defined(TCPCONN) || defined(STREAMSCONN) */
00375 
00376 #if defined(DNETCONN)
00377     case AF_DECnet:
00378     {
00379        struct sockaddr_dn *saddr = (struct sockaddr_dn *) peer_addr;
00380        struct nodeent *np;
00381 
00382        if (np = getnodebyaddr(saddr->sdn_add.a_addr,
00383            saddr->sdn_add.a_len, AF_DECnet)) {
00384            sprintf(addrbuf, "%s:", np->n_name);
00385        } else {
00386            sprintf(addrbuf, "%s:", dnet_htoa(&saddr->sdn_add));
00387        }
00388        addr = addrbuf;
00389        break;
00390     }
00391 #endif /* defined(DNETCONN) */
00392 
00393 #if defined(AMRPCCONN)
00394     case AF_AMOEBA:
00395     {
00396        addr = "Amoeba"; /* not really used */
00397        break;
00398     }
00399 #endif
00400 #if defined(AMTCPCONN) && !(defined(TCPCONN) || defined(STREAMSCONN))
00401     case AF_INET:
00402     {
00403        if (gethostname (addrbuf, sizeof (addrbuf)) == 0) {
00404            addr = addrbuf;
00405        } else {
00406            addr = "";
00407        }
00408        break;
00409     }
00410 #endif
00411 
00412     default:
00413        return (NULL);
00414     }
00415 
00416 
00417     hostname = (char *) malloc (
00418        strlen (ciptr->transptr->TransName) + strlen (addr) + 2);
00419     strcpy (hostname, ciptr->transptr->TransName);
00420     strcat (hostname, "/");
00421     if (addr)
00422        strcat (hostname, addr);
00423 
00424     return (hostname);
00425 }
00426 
00427 #endif /* ICE_t */
00428 
00429 
00430 #if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
00431 int
00432 TRANS(WSAStartup) ()
00433 {
00434     static WSADATA wsadata;
00435 
00436     PRMSG (2,"TRANS(WSAStartup)()\n", 0, 0, 0);
00437 
00438     if (!wsadata.wVersion && WSAStartup(MAKEWORD(1,1), &wsadata))
00439         return 1;
00440     return 0;
00441 }
00442 #endif
00443 
00444 
00445 static int
00446 is_numeric (str)
00447 
00448 char *str;
00449 
00450 {
00451     int i;
00452 
00453     for (i = 0; i < (int) strlen (str); i++)
00454        if (!isdigit (str[i]))
00455            return (0);
00456 
00457     return (1);
00458 }