Back to index

im-sdk  12.3.91
Xtranssock.c
Go to the documentation of this file.
00001 /* $XConsortium: Xtranssock.c,v 1.36 95/04/28 15:23:33 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  * NCR DISCLAIMS 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 #include <stdio.h>
00056 #include <stdlib.h>
00057 #include <ctype.h>
00058 #ifndef WIN32
00059 
00060 #if defined(TCPCONN) || defined(UNIXCONN)
00061 #include <netinet/in.h>
00062 #else
00063 #ifdef ESIX
00064 #include <lan/in.h>
00065 #endif
00066 #endif
00067 #if defined(TCPCONN) || defined(UNIXCONN)
00068 #include <netdb.h>
00069 #endif
00070 
00071 #ifdef UNIXCONN
00072 #include <sys/un.h>
00073 #include <sys/stat.h>
00074 #endif
00075 
00076 #ifdef hpux
00077 #define NO_TCP_H
00078 #endif /* hpux */
00079 #ifdef MOTOROLA
00080 #ifdef SYSV
00081 #define NO_TCP_H
00082 #endif /* SYSV */
00083 #endif /* MOTOROLA */
00084 #ifndef NO_TCP_H
00085 #ifdef __osf__
00086 #include <sys/param.h>
00087 #endif /* osf */
00088 #if defined(__NetBSD__) || defined(__FreeBSD__)
00089 #include <machine/endian.h>
00090 #endif /* __NetBSD__ || __FreeBSD__ */
00091 #include <netinet/tcp.h>
00092 #endif /* !NO_TCP_H */
00093 #include <sys/ioctl.h>
00094 #ifdef SVR4
00095 #include <sys/filio.h>
00096 #endif
00097 #if (defined(i386) && defined(SYSV) && !defined(SCO)) || defined(_SEQUENT_)
00098 #if !defined(_SEQUENT_) && !defined(ESIX)
00099 #include <net/errno.h>
00100 #endif /* _SEQUENT_  || ESIX */
00101 #include <sys/stropts.h>
00102 #endif /* i386 && SYSV || _SEQUENT_ */
00103 #endif /* !WIN32 */
00104 
00105 #ifdef WIN32
00106 #define _WILLWINSOCK_
00107 #define BOOL wBOOL
00108 #undef Status
00109 #define Status wStatus
00110 #include <winsock.h>
00111 #undef Status
00112 #define Status int
00113 #undef BOOL
00114 #include <X11/Xw32defs.h>
00115 #undef close
00116 #define close closesocket
00117 #define ECONNREFUSED WSAECONNREFUSED
00118 #define EADDRINUSE WSAEADDRINUSE
00119 #define EPROTOTYPE WSAEPROTOTYPE
00120 #undef EWOULDBLOCK
00121 #define EWOULDBLOCK WSAEWOULDBLOCK
00122 #undef EINTR
00123 #define EINTR WSAEINTR
00124 #endif /* WIN32 */
00125 
00126 #if defined(SO_DONTLINGER) && defined(SO_LINGER)
00127 #undef SO_DONTLINGER
00128 #endif
00129 
00130 
00131 /*
00132  * This is the Socket implementation of the X Transport service layer
00133  *
00134  * This file contains the implementation for both the UNIX and INET domains,
00135  * and can be built for either one, or both.
00136  *
00137  */
00138 
00139 typedef struct _Sockettrans2dev {      
00140     char      *transname;
00141     int              family;
00142     int              devcotsname;
00143     int              devcltsname;
00144     int              protocol;
00145 } Sockettrans2dev;
00146 
00147 static Sockettrans2dev Sockettrans2devtab[] = {
00148 #ifdef TCPCONN
00149     {"inet",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
00150     {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
00151 #endif /* TCPCONN */
00152 #ifdef UNIXCONN
00153     {"unix",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
00154 #if !defined(LOCALCONN)
00155     {"local",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
00156 #endif /* !LOCALCONN */
00157 #endif /* UNIXCONN */
00158 };
00159 
00160 #define NUMSOCKETFAMILIES (sizeof(Sockettrans2devtab)/sizeof(Sockettrans2dev))
00161 
00162 
00163 #ifdef UNIXCONN
00164 
00165 #ifdef hpux
00166 
00167 #if defined(X11_t)
00168 #define UNIX_PATH "/usr/spool/sockets/X11/"
00169 #define UNIX_DIR "/usr/spool/sockets/X11"
00170 #define OLD_UNIX_PATH "/tmp/.X11-unix/X"
00171 #endif /* X11_t */
00172 #if defined(XIM_t)
00173 #define UNIX_PATH "/usr/spool/sockets/XIM/"
00174 #define UNIX_DIR "/usr/spool/sockets/XIM"
00175 #define OLD_UNIX_PATH "/tmp/.XIM-unix/XIM"
00176 #endif /* XIM_t */
00177 #if defined(FS_t) || defined(FONT_t)
00178 #define UNIX_PATH "/usr/spool/sockets/fontserv/"
00179 #define UNIX_DIR "/usr/spool/sockets/fontserv"
00180 #endif /* FS_t || FONT_t */
00181 #if defined(ICE_t)
00182 #define UNIX_PATH "/usr/spool/sockets/ICE/"
00183 #define UNIX_DIR "/usr/spool/sockets/ICE"
00184 #endif /* ICE_t */
00185 #if defined(TEST_t)
00186 #define UNIX_PATH "/usr/spool/sockets/xtrans_test/"
00187 #define UNIX_DIR "/usr/spool/sockets/xtrans_test"
00188 #endif
00189 
00190 #else /* !hpux */
00191 
00192 #if defined(X11_t)
00193 #define UNIX_PATH "/tmp/.X11-unix/X"
00194 #define UNIX_DIR "/tmp/.X11-unix"
00195 #endif /* X11_t */
00196 #if defined(XIM_t)
00197 #define UNIX_PATH "/tmp/.XIM-unix/XIM"
00198 #define UNIX_DIR "/tmp/.XIM-unix"
00199 #endif /* XIM_t */
00200 #if defined(FS_t) || defined(FONT_t)
00201 #define UNIX_PATH "/tmp/.font-unix/fs"
00202 #define UNIX_DIR "/tmp/.font-unix"
00203 #endif /* FS_t || FONT_t */
00204 #if defined(ICE_t)
00205 #define UNIX_PATH "/tmp/.ICE-unix/"
00206 #define UNIX_DIR "/tmp/.ICE-unix"
00207 #endif /* ICE_t */
00208 #if defined(TEST_t)
00209 #define UNIX_PATH "/tmp/.Test-unix/test"
00210 #define UNIX_DIR "/tmp/.Test-unix"
00211 #endif
00212 
00213 #endif /* hpux */
00214 
00215 #endif /* UNIXCONN */
00216 
00217 
00218 /*
00219  * These are some utility function used by the real interface function below.
00220  */
00221 
00222 static int
00223 TRANS(SocketSelectFamily) (family)
00224 
00225 char *family;
00226 
00227 {
00228     int     i;
00229 
00230     PRMSG (3,"TRANS(SocketSelectFamily) (%s)\n", family, 0, 0);
00231 
00232     for (i = 0; i < NUMSOCKETFAMILIES;i++)
00233     {
00234         if (!strcmp (family, Sockettrans2devtab[i].transname))
00235            return i;
00236     }
00237 
00238     return -1;
00239 }
00240 
00241 
00242 /*
00243  * This function gets the local address of the socket and stores it in the
00244  * XtransConnInfo structure for the connection.
00245  */
00246 
00247 static int
00248 TRANS(SocketINETGetAddr) (ciptr)
00249 
00250 XtransConnInfo ciptr;
00251 
00252 {
00253     struct sockaddr_in      sockname;
00254     int                     namelen = sizeof sockname;
00255 
00256     PRMSG (3,"TRANS(SocketINETGetAddr) (%x)\n", ciptr, 0, 0);
00257 
00258     if (getsockname (ciptr->fd,(struct sockaddr *) &sockname, &namelen) < 0)
00259     {
00260        PRMSG (1,"TRANS(SocketINETGetAddr): getsockname() failed: %d\n",
00261            EGET(),0, 0);
00262        return -1;
00263     }
00264 
00265     /*
00266      * Everything looks good: fill in the XtransConnInfo structure.
00267      */
00268 
00269     if ((ciptr->addr = (char *) malloc (namelen)) == NULL)
00270     {
00271         PRMSG (1,
00272            "TRANS(SocketINETGetAddr): Can't allocate space for the addr\n",
00273            0, 0, 0);
00274         return -1;
00275     }
00276 
00277     ciptr->family = sockname.sin_family;
00278     ciptr->addrlen = namelen;
00279     memcpy (ciptr->addr, &sockname, ciptr->addrlen);
00280 
00281     return 0;
00282 }
00283 
00284 
00285 /*
00286  * This function gets the remote address of the socket and stores it in the
00287  * XtransConnInfo structure for the connection.
00288  */
00289 
00290 static int
00291 TRANS(SocketINETGetPeerAddr) (ciptr)
00292 
00293 XtransConnInfo ciptr;
00294 
00295 {
00296     struct sockaddr_in      sockname;
00297     int                     namelen = sizeof(sockname);
00298 
00299     PRMSG (3,"TRANS(SocketINETGetPeerAddr) (%x)\n", ciptr, 0, 0);
00300 
00301     if (getpeername (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
00302     {
00303        PRMSG (1,"TRANS(SocketINETGetPeerAddr): getpeername() failed: %d\n",
00304            EGET(), 0, 0);
00305        return -1;
00306     }
00307 
00308     /*
00309      * Everything looks good: fill in the XtransConnInfo structure.
00310      */
00311 
00312     if ((ciptr->peeraddr = (char *) malloc (namelen)) == NULL)
00313     {
00314         PRMSG (1,
00315           "TRANS(SocketINETGetPeerAddr): Can't allocate space for the addr\n",
00316           0, 0, 0);
00317         return -1;
00318     }
00319 
00320     ciptr->peeraddrlen = namelen;
00321     memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
00322 
00323     return 0;
00324 }
00325 
00326 
00327 static XtransConnInfo
00328 TRANS(SocketOpen) (i, type)
00329 
00330 int i;
00331 int type;
00332 
00333 {
00334     XtransConnInfo   ciptr;
00335 
00336     PRMSG (3,"TRANS(SocketOpen) (%d,%d)\n", i, type, 0);
00337 
00338     if ((ciptr = (XtransConnInfo) calloc (
00339        1, sizeof(struct _XtransConnInfo))) == NULL)
00340     {
00341        PRMSG (1, "TRANS(SocketOpen): malloc failed\n", 0, 0, 0);
00342        return NULL;
00343     }
00344 
00345     if ((ciptr->fd = socket(Sockettrans2devtab[i].family, type,
00346        Sockettrans2devtab[i].protocol)) < 0
00347 #ifndef WIN32
00348 #if (defined(X11_t) && !defined(USE_POLL)) || defined(FS_t) || defined(FONT_t)
00349        || ciptr->fd >= TRANS_OPEN_MAX
00350 #endif
00351 #endif
00352       ) {
00353        PRMSG (1, "TRANS(SocketOpen): socket() failed for %s\n",
00354            Sockettrans2devtab[i].transname, 0, 0);
00355 
00356        free ((char *) ciptr);
00357        return NULL;
00358     }
00359 
00360 #ifdef TCP_NODELAY
00361     if (Sockettrans2devtab[i].family == AF_INET)
00362     {
00363        /*
00364         * turn off TCP coalescence for INET sockets
00365         */
00366 
00367        int tmp = 1;
00368        setsockopt (ciptr->fd, IPPROTO_TCP, TCP_NODELAY,
00369            (char *) &tmp, sizeof (int));
00370     }
00371 #endif
00372 
00373     return ciptr;
00374 }
00375 
00376 
00377 #ifdef TRANS_REOPEN
00378 
00379 static XtransConnInfo
00380 TRANS(SocketReopen) (i, type, fd, port)
00381 
00382 int  i;
00383 int  type;
00384 int  fd;
00385 char *port;
00386 
00387 {
00388     XtransConnInfo   ciptr;
00389 
00390     PRMSG (3,"TRANS(SocketReopen) (%d,%d,%s)\n", type, fd, port);
00391 
00392     if ((ciptr = (XtransConnInfo) calloc (
00393        1, sizeof(struct _XtransConnInfo))) == NULL)
00394     {
00395        PRMSG (1, "TRANS(SocketReopen): malloc failed\n", 0, 0, 0);
00396        return NULL;
00397     }
00398 
00399     ciptr->fd = fd;
00400 
00401     return ciptr;
00402 }
00403 
00404 #endif /* TRANS_REOPEN */
00405 
00406 
00407 /*
00408  * These functions are the interface supplied in the Xtransport structure
00409  */
00410 
00411 #ifdef TRANS_CLIENT
00412 
00413 static XtransConnInfo
00414 TRANS(SocketOpenCOTSClient) (thistrans, protocol, host, port)
00415 
00416 Xtransport *thistrans;
00417 char      *protocol;
00418 char      *host;
00419 char       *port;
00420 
00421 {
00422     XtransConnInfo   ciptr;
00423     int                     i;
00424 
00425     PRMSG (2, "TRANS(SocketOpenCOTSClient) (%s,%s,%s)\n",
00426        protocol, host, port);
00427 
00428     if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
00429     {
00430        PRMSG (1,
00431        "TRANS(SocketOpenCOTSClient): Unable to determine socket type for %s\n",
00432            thistrans->TransName, 0, 0);
00433        return NULL;
00434     }
00435 
00436     if ((ciptr = TRANS(SocketOpen) (
00437        i, Sockettrans2devtab[i].devcotsname)) == NULL)
00438     {
00439        PRMSG (1,"TRANS(SocketOpenCOTSClient): Unable to open socket for %s\n",
00440            thistrans->TransName, 0, 0);
00441        return NULL;
00442     }
00443 
00444     /* Save the index for later use */
00445 
00446     ciptr->index = i;
00447 
00448     return ciptr;
00449 }
00450 
00451 #endif /* TRANS_CLIENT */
00452 
00453 
00454 #ifdef TRANS_SERVER
00455 
00456 static XtransConnInfo
00457 TRANS(SocketOpenCOTSServer) (thistrans, protocol, host, port)
00458 
00459 Xtransport *thistrans;
00460 char      *protocol;
00461 char      *host;
00462 char      *port;
00463 
00464 {
00465     XtransConnInfo   ciptr;
00466     int       i;
00467 
00468     PRMSG (2,"TRANS(SocketOpenCOTSServer) (%s,%s,%s)\n", protocol, host, port);
00469 
00470     if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
00471     {
00472        PRMSG (1,
00473        "TRANS(SocketOpenCOTSServer): Unable to determine socket type for %s\n",
00474            thistrans->TransName, 0, 0);
00475        return NULL;
00476     }
00477 
00478     if ((ciptr = TRANS(SocketOpen) (
00479        i, Sockettrans2devtab[i].devcotsname)) == NULL)
00480     {
00481        PRMSG (1,"TRANS(SocketOpenCOTSServer): Unable to open socket for %s\n",
00482            thistrans->TransName, 0, 0);
00483        return NULL;
00484     }
00485 
00486 #ifdef SO_REUSEADDR
00487 
00488     /*
00489      * SO_REUSEADDR only applied to AF_INET
00490      */
00491 
00492     if (Sockettrans2devtab[i].family == AF_INET)
00493     {
00494        int one = 1;
00495        setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR,
00496                   (char *) &one, sizeof (int));
00497     }
00498 #endif
00499 
00500     /* Save the index for later use */
00501 
00502     ciptr->index = i;
00503 
00504     return ciptr;
00505 }
00506 
00507 #endif /* TRANS_SERVER */
00508 
00509 
00510 #ifdef TRANS_CLIENT
00511 
00512 static XtransConnInfo
00513 TRANS(SocketOpenCLTSClient) (thistrans, protocol, host, port)
00514 
00515 Xtransport *thistrans;
00516 char      *protocol;
00517 char      *host;
00518 char      *port;
00519 
00520 {
00521     XtransConnInfo   ciptr;
00522     int                     i;
00523 
00524     PRMSG (2,"TRANS(SocketOpenCLTSClient) (%s,%s,%s)\n", protocol, host, port);
00525 
00526     if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
00527     {
00528        PRMSG (1,
00529        "TRANS(SocketOpenCLTSClient): Unable to determine socket type for %s\n",
00530            thistrans->TransName, 0, 0);
00531        return NULL;
00532     }
00533 
00534     if ((ciptr = TRANS(SocketOpen) (
00535        i, Sockettrans2devtab[i].devcotsname)) == NULL)
00536     {
00537        PRMSG (1,"TRANS(SocketOpenCLTSClient): Unable to open socket for %s\n",
00538              thistrans->TransName, 0, 0);
00539        return NULL;
00540     }
00541 
00542     /* Save the index for later use */
00543 
00544     ciptr->index = i;
00545 
00546     return ciptr;
00547 }
00548 
00549 #endif /* TRANS_CLIENT */
00550 
00551 
00552 #ifdef TRANS_SERVER
00553 
00554 static XtransConnInfo
00555 TRANS(SocketOpenCLTSServer) (thistrans, protocol, host, port)
00556 
00557 Xtransport *thistrans;
00558 char      *protocol;
00559 char      *host;
00560 char      *port;
00561 
00562 {
00563     XtransConnInfo   ciptr;
00564     int       i;
00565 
00566     PRMSG (2,"TRANS(SocketOpenCLTSServer) (%s,%s,%s)\n", protocol, host, port);
00567 
00568     if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
00569     {
00570        PRMSG (1,
00571        "TRANS(SocketOpenCLTSServer): Unable to determine socket type for %s\n",
00572              thistrans->TransName, 0, 0);
00573        return NULL;
00574     }
00575 
00576     if ((ciptr = TRANS(SocketOpen) (
00577        i, Sockettrans2devtab[i].devcotsname)) == NULL)
00578     {
00579        PRMSG (1,"TRANS(SocketOpenCLTSServer): Unable to open socket for %s\n",
00580              thistrans->TransName, 0, 0);
00581        return NULL;
00582     }
00583 
00584     /* Save the index for later use */
00585 
00586     ciptr->index = i;
00587 
00588     return ciptr;
00589 }
00590 
00591 #endif /* TRANS_SERVER */
00592 
00593 
00594 #ifdef TRANS_REOPEN
00595 
00596 static XtransConnInfo
00597 TRANS(SocketReopenCOTSServer) (thistrans, fd, port)
00598 
00599 Xtransport *thistrans;
00600 int       fd;
00601 char      *port;
00602 
00603 {
00604     XtransConnInfo   ciptr;
00605     int                     i;
00606 
00607     PRMSG (2,
00608        "TRANS(SocketReopenCOTSServer) (%d, %s)\n", fd, port, 0);
00609 
00610     if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
00611     {
00612        PRMSG (1,
00613        "TRANS(SocketReopenCOTSServer): Unable to determine socket type for %s\n",
00614            thistrans->TransName, 0, 0);
00615        return NULL;
00616     }
00617 
00618     if ((ciptr = TRANS(SocketReopen) (
00619        i, Sockettrans2devtab[i].devcotsname, fd, port)) == NULL)
00620     {
00621        PRMSG (1,
00622            "TRANS(SocketReopenCOTSServer): Unable to reopen socket for %s\n",
00623            thistrans->TransName, 0, 0);
00624        return NULL;
00625     }
00626 
00627     /* Save the index for later use */
00628 
00629     ciptr->index = i;
00630 
00631     return ciptr;
00632 }
00633 
00634 static XtransConnInfo
00635 TRANS(SocketReopenCLTSServer) (thistrans, fd, port)
00636 
00637 Xtransport *thistrans;
00638 int       fd;
00639 char      *port;
00640 
00641 {
00642     XtransConnInfo   ciptr;
00643     int                     i;
00644 
00645 
00646     PRMSG (2,
00647        "TRANS(SocketReopenCLTSServer) (%d, %s)\n", fd, port, 0);
00648 
00649     if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
00650     {
00651        PRMSG (1,
00652        "TRANS(SocketReopenCLTSServer): Unable to determine socket type for %s\n",
00653              thistrans->TransName, 0, 0);
00654        return NULL;
00655     }
00656 
00657     if ((ciptr = TRANS(SocketReopen) (
00658        i, Sockettrans2devtab[i].devcotsname, fd, port)) == NULL)
00659     {
00660        PRMSG (1,
00661             "TRANS(SocketReopenCLTSServer): Unable to reopen socket for %s\n",
00662             thistrans->TransName, 0, 0);
00663        return NULL;
00664     }
00665 
00666     /* Save the index for later use */
00667 
00668     ciptr->index = i;
00669 
00670     return ciptr;
00671 }
00672 
00673 #endif /* TRANS_REOPEN */
00674 
00675 
00676 static int
00677 TRANS(SocketSetOption) (ciptr, option, arg)
00678 
00679 XtransConnInfo       ciptr;
00680 int           option;
00681 int           arg;
00682 
00683 {
00684     PRMSG (2,"TRANS(SocketSetOption) (%d,%d,%d)\n", ciptr->fd, option, arg);
00685 
00686     return -1;
00687 }
00688 
00689 
00690 #ifdef TRANS_SERVER
00691 
00692 static int
00693 TRANS(SocketCreateListener) (ciptr, sockname, socknamelen)
00694 
00695 XtransConnInfo       ciptr;
00696 struct sockaddr      *sockname;
00697 int           socknamelen;
00698 
00699 {
00700     int       namelen = socknamelen;
00701     int       fd = ciptr->fd;
00702     int       retry;
00703 
00704     PRMSG (3, "TRANS(SocketCreateListener) (%x,%d)\n", ciptr, fd, 0);
00705 
00706     if (Sockettrans2devtab[ciptr->index].family == AF_INET)
00707        retry = 20;
00708     else
00709        retry = 0;
00710 
00711     while (bind (fd, (struct sockaddr *) sockname, namelen) < 0)
00712     {
00713        if (errno == EADDRINUSE)
00714            return TRANS_ADDR_IN_USE;
00715 
00716        if (retry-- == 0) {
00717            PRMSG (1, "TRANS(SocketCreateListener): failed to bind listener\n",
00718               0, 0, 0);
00719            close (fd);
00720            return TRANS_CREATE_LISTENER_FAILED;
00721        }
00722 #ifdef SO_REUSEADDR
00723        sleep (1);
00724 #else
00725        sleep (10);
00726 #endif /* SO_REUSEDADDR */
00727     }
00728 
00729     if (Sockettrans2devtab[ciptr->index].family == AF_INET) {
00730 #ifdef SO_DONTLINGER
00731        setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);
00732 #else
00733 #ifdef SO_LINGER
00734     {
00735        static int linger[2] = { 0, 0 };
00736        setsockopt (fd, SOL_SOCKET, SO_LINGER,
00737               (char *) linger, sizeof (linger));
00738     }
00739 #endif
00740 #endif
00741 }
00742 
00743     if (listen (fd, 5) < 0)
00744     {
00745        PRMSG (1, "TRANS(SocketCreateListener): listen() failed\n", 0, 0, 0);
00746        close (fd);
00747        return TRANS_CREATE_LISTENER_FAILED;
00748     }
00749        
00750     /* Set a flag to indicate that this connection is a listener */
00751 
00752     ciptr->flags = 1;
00753 
00754     return 0;
00755 }
00756 
00757 
00758 #ifdef TCPCONN
00759 static int
00760 TRANS(SocketINETCreateListener) (ciptr, port)
00761 
00762 XtransConnInfo       ciptr;
00763 char          *port;
00764 
00765 {
00766     struct sockaddr_in      sockname;
00767     int              namelen = sizeof(sockname);
00768     int              status;
00769     short     tmpport;
00770     struct    servent       *servp;
00771 
00772 #if 0
00773 #define PORTBUFSIZE  64     /* what is a real size for this? */
00774 
00775     char      portbuf[PORTBUFSIZE];
00776 #endif
00777     
00778     PRMSG (2, "TRANS(SocketINETCreateListener) (%s)\n", port, 0, 0);
00779 
00780 #ifdef X11_t
00781     /*
00782      * X has a well known port, that is transport dependent. It is easier
00783      * to handle it here, than try and come up with a transport independent
00784      * representation that can be passed in and resolved the usual way.
00785      *
00786      * The port that is passed here is really a string containing the idisplay
00787      * from ConnectDisplay().
00788      */
00789 
00790     if (is_numeric (port))
00791     {
00792        tmpport = (short) atoi (port);
00793 
00794        sprintf (portbuf,"%d", X_TCP_PORT+tmpport);
00795     }
00796     else
00797        strncpy (portbuf, port, PORTBUFSIZE);
00798 
00799     port = portbuf;
00800 #endif
00801 
00802     if (port && *port)
00803     {
00804        /* Check to see if the port string is just a number (handles X11) */
00805 
00806        if (!is_numeric (port))
00807        {
00808            if ((servp = getservbyname (port, "tcp")) == NULL)
00809            {
00810               PRMSG (1,
00811             "TRANS(SocketINETCreateListener): Unable to get service for %s\n",
00812                     port, 0, 0);
00813               return TRANS_CREATE_LISTENER_FAILED;
00814            }
00815            
00816            sockname.sin_port = servp->s_port;
00817        }
00818        else
00819        {
00820            tmpport = (short) atoi (port);
00821            sockname.sin_port = htons (tmpport);
00822        }
00823     }
00824     else
00825        sockname.sin_port = htons (0);
00826 
00827 #ifdef BSD44SOCKETS
00828     sockname.sin_len = sizeof (sockname);
00829 #endif
00830     sockname.sin_family = AF_INET;
00831     sockname.sin_addr.s_addr = htonl (INADDR_ANY);
00832 
00833     if ((status = TRANS(SocketCreateListener) (ciptr,
00834        (struct sockaddr *) &sockname, namelen)) < 0)
00835     {
00836        PRMSG (1,
00837     "TRANS(SocketINETCreateListener): TRANS(SocketCreateListener) () failed\n",
00838            0, 0, 0);
00839        return status;
00840     }
00841 
00842     if (TRANS(SocketINETGetAddr) (ciptr) < 0)
00843     {
00844        PRMSG (1,
00845        "TRANS(SocketINETCreateListener): TRANS(SocketINETGetAddr) () failed\n",
00846            0, 0, 0);
00847        return TRANS_CREATE_LISTENER_FAILED;
00848     }
00849 
00850     return 0;
00851 }
00852 
00853 #endif /* SOCKCONN */
00854 
00855 
00856 #ifdef UNIXCONN
00857 
00858 static int
00859 TRANS(SocketUNIXCreateListener) (ciptr, port)
00860 
00861 XtransConnInfo ciptr;
00862 char *port;
00863 
00864 {
00865     struct sockaddr_un      sockname;
00866     int                     namelen;
00867     int                     oldUmask;
00868     int                     status;
00869 
00870     PRMSG (2, "TRANS(SocketUNIXCreateListener) (%s)\n",
00871        port ? port : "NULL", 0, 0);
00872 
00873     /* Make sure the directory is created */
00874 
00875     oldUmask = umask (0);
00876 
00877 #ifdef UNIX_DIR
00878     if (!mkdir (UNIX_DIR, 0777))
00879         chmod (UNIX_DIR, 0777);
00880 #endif
00881 
00882     sockname.sun_family = AF_UNIX;
00883 
00884     if (port && *port) {
00885        if (*port == '/') { /* a full pathname */
00886            sprintf (sockname.sun_path, "%s", port);
00887        } else {
00888            sprintf (sockname.sun_path, "%s%s", UNIX_PATH, port);
00889        }
00890     } else {
00891        sprintf (sockname.sun_path, "%s%d", UNIX_PATH, getpid());
00892     }
00893 
00894 #ifdef BSD44SOCKETS
00895     sockname.sun_len = strlen(sockname.sun_path);
00896     namelen = SUN_LEN(&sockname);
00897 #else
00898     namelen = strlen(sockname.sun_path) + sizeof(sockname.sun_family);
00899 #endif
00900 
00901     unlink (sockname.sun_path);
00902 
00903     if ((status = TRANS(SocketCreateListener) (ciptr,
00904        (struct sockaddr *) &sockname, namelen)) < 0)
00905     {
00906        PRMSG (1,
00907     "TRANS(SocketUNIXCreateListener): TRANS(SocketCreateListener) () failed\n",
00908            0, 0, 0);
00909        return status;
00910     }
00911 
00912     /*
00913      * Now that the listener is esablished, create the addr info for
00914      * this connection. getpeername() doesn't work for UNIX Domain Sockets
00915      * on some systems (hpux at least), so we will just do it manually, instead
00916      * of calling something like TRANS(SocketUNIXGetAddr).
00917      */
00918 
00919     namelen = sizeof (sockname); /* this will always make it the same size */
00920 
00921     if ((ciptr->addr = (char *) malloc (namelen)) == NULL)
00922     {
00923         PRMSG (1,
00924         "TRANS(SocketUNIXCreateListener): Can't allocate space for the addr\n",
00925            0, 0, 0);
00926         return TRANS_CREATE_LISTENER_FAILED;
00927     }
00928 
00929     ciptr->family = sockname.sun_family;
00930     ciptr->addrlen = namelen;
00931     memcpy (ciptr->addr, &sockname, ciptr->addrlen);
00932 
00933     (void) umask (oldUmask);
00934 
00935     return 0;
00936 }
00937 
00938 
00939 static int
00940 TRANS(SocketUNIXResetListener) (ciptr)
00941 
00942 XtransConnInfo ciptr;
00943 
00944 {
00945     /*
00946      * See if the unix domain socket has disappeared.  If it has, recreate it.
00947      */
00948 
00949     struct sockaddr_un      *unsock = (struct sockaddr_un *) ciptr->addr;
00950     struct stat             statb;
00951     int              status = TRANS_RESET_NOOP;
00952     void             TRANS(FreeConnInfo) ();
00953 
00954     PRMSG (3, "TRANS(SocketUNIXResetListener) (%x,%d)\n", ciptr, ciptr->fd, 0);
00955 
00956     if (stat (unsock->sun_path, &statb) == -1 ||
00957         ((statb.st_mode & S_IFMT) !=
00958 #if (defined (sun) && defined(SVR4)) || defined(NCR)
00959                      S_IFIFO))
00960 #else
00961                      S_IFSOCK))
00962 #endif
00963     {
00964        int oldUmask = umask (0);
00965 
00966 #ifdef UNIX_DIR
00967        if (!mkdir (UNIX_DIR, 0777))
00968            chmod (UNIX_DIR, 0777);
00969 #endif
00970 
00971        close (ciptr->fd);
00972        unlink (unsock->sun_path);
00973 
00974        if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
00975        {
00976            TRANS(FreeConnInfo) (ciptr);
00977            return TRANS_RESET_FAILURE;
00978        }
00979 
00980        if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0)
00981        {
00982            close (ciptr->fd);
00983            TRANS(FreeConnInfo) (ciptr);
00984            return TRANS_RESET_FAILURE;
00985        }
00986 
00987        if (listen (ciptr->fd, 5) < 0)
00988        {
00989            close (ciptr->fd);
00990            TRANS(FreeConnInfo) (ciptr);
00991            return TRANS_RESET_FAILURE;
00992        }
00993 
00994        umask (oldUmask);
00995 
00996        status = TRANS_RESET_NEW_FD;
00997     }
00998 
00999     return status;
01000 }
01001 
01002 #endif /* UNIXCONN */
01003 
01004 
01005 #ifdef TCPCONN
01006 
01007 static XtransConnInfo
01008 TRANS(SocketINETAccept) (ciptr, status)
01009 
01010 XtransConnInfo ciptr;
01011 int           *status;
01012 
01013 {
01014     XtransConnInfo   newciptr;
01015     struct sockaddr_in      sockname;
01016     int                     namelen = sizeof(sockname);
01017 
01018     PRMSG (2, "TRANS(SocketINETAccept) (%x,%d)\n", ciptr, ciptr->fd, 0);
01019 
01020     if ((newciptr = (XtransConnInfo) calloc (
01021        1, sizeof(struct _XtransConnInfo))) == NULL)
01022     {
01023        PRMSG (1, "TRANS(SocketINETAccept): malloc failed\n", 0, 0, 0);
01024        *status = TRANS_ACCEPT_BAD_MALLOC;
01025        return NULL;
01026     }
01027 
01028     if ((newciptr->fd = accept (ciptr->fd,
01029        (struct sockaddr *) &sockname, &namelen)) < 0)
01030     {
01031        PRMSG (1, "TRANS(SocketINETAccept): accept() failed\n", 0, 0, 0);
01032        free (newciptr);
01033        *status = TRANS_ACCEPT_FAILED;
01034        return NULL;
01035     }
01036 
01037 #ifdef TCP_NODELAY
01038     {
01039        /*
01040         * turn off TCP coalescence for INET sockets
01041         */
01042 
01043        int tmp = 1;
01044        setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY,
01045            (char *) &tmp, sizeof (int));
01046     }
01047 #endif
01048 
01049     /*
01050      * Get this address again because the transport may give a more 
01051      * specific address now that a connection is established.
01052      */
01053 
01054     if (TRANS(SocketINETGetAddr) (newciptr) < 0)
01055     {
01056        PRMSG (1,
01057            "TRANS(SocketINETAccept): TRANS(SocketINETGetAddr) () failed:\n",
01058            0, 0, 0);
01059        close (newciptr->fd);
01060        free (newciptr);
01061        *status = TRANS_ACCEPT_MISC_ERROR;
01062         return NULL;
01063     }
01064 
01065     if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0)
01066     {
01067        PRMSG (1,
01068          "TRANS(SocketINETAccept): TRANS(SocketINETGetPeerAddr) () failed:\n",
01069               0, 0, 0);
01070        close (newciptr->fd);
01071        if (newciptr->addr) free (newciptr->addr);
01072        free (newciptr);
01073        *status = TRANS_ACCEPT_MISC_ERROR;
01074         return NULL;
01075     }
01076 
01077     *status = 0;
01078 
01079     return newciptr;
01080 }
01081 
01082 #endif /* TCPCONN */
01083 
01084 
01085 #ifdef UNIXCONN
01086 static XtransConnInfo
01087 TRANS(SocketUNIXAccept) (ciptr, status)
01088 
01089 XtransConnInfo ciptr;
01090 int           *status;
01091 
01092 {
01093     XtransConnInfo   newciptr;
01094     struct sockaddr_un      sockname;
01095     int                     namelen = sizeof(sockname);
01096 
01097     PRMSG (2, "TRANS(SocketUNIXAccept) (%x,%d)\n", ciptr, ciptr->fd, 0);
01098 
01099     if ((newciptr = (XtransConnInfo) calloc (
01100        1, sizeof(struct _XtransConnInfo))) == NULL)
01101     {
01102        PRMSG (1, "TRANS(SocketUNIXAccept): malloc failed\n", 0, 0, 0);
01103        *status = TRANS_ACCEPT_BAD_MALLOC;
01104        return NULL;
01105     }
01106 
01107     if ((newciptr->fd = accept (ciptr->fd,
01108        (struct sockaddr *) &sockname, &namelen)) < 0)
01109     {
01110        PRMSG (1, "TRANS(SocketUNIXAccept): accept() failed\n", 0, 0, 0);
01111        free (newciptr);
01112        *status = TRANS_ACCEPT_FAILED;
01113        return NULL;
01114     }
01115 
01116     /*
01117      * Get the socket name and the peer name from the listener socket,
01118      * since this is unix domain.
01119      */
01120 
01121     if ((newciptr->addr = (char *) malloc (ciptr->addrlen)) == NULL)
01122     {
01123         PRMSG (1,
01124         "TRANS(SocketUNIXAccept): Can't allocate space for the addr\n",
01125              0, 0, 0);
01126        close (newciptr->fd);
01127        free (newciptr);
01128        *status = TRANS_ACCEPT_BAD_MALLOC;
01129         return NULL;
01130     }
01131 
01132 
01133     newciptr->addrlen = ciptr->addrlen;
01134     memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen);
01135 
01136     if ((newciptr->peeraddr = (char *) malloc (ciptr->addrlen)) == NULL)
01137     {
01138         PRMSG (1,
01139              "TRANS(SocketUNIXAccept): Can't allocate space for the addr\n",
01140              0, 0, 0);
01141        close (newciptr->fd);
01142        if (newciptr->addr) free (newciptr->addr);
01143        free (newciptr);
01144        *status = TRANS_ACCEPT_BAD_MALLOC;
01145         return NULL;
01146     }
01147     
01148     newciptr->peeraddrlen = ciptr->addrlen;
01149     memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen);
01150 
01151     *status = 0;
01152 
01153     return newciptr;
01154 }
01155 
01156 #endif /* UNIXCONN */
01157 
01158 #endif /* TRANS_SERVER */
01159 
01160 
01161 #ifdef TRANS_CLIENT
01162 
01163 #ifdef TCPCONN
01164 static int
01165 TRANS(SocketINETConnect) (ciptr, host, port)
01166 
01167 XtransConnInfo       ciptr;
01168 char          *host;
01169 char          *port;
01170 
01171 {
01172     struct sockaddr_in      sockname;
01173     int                     namelen = sizeof(sockname);
01174     struct hostent   *hostp;
01175     struct servent   *servp;
01176 
01177 #define PORTBUFSIZE  64     /* what is a real size for this? */
01178     char      portbuf[PORTBUFSIZE];
01179 
01180     int                     ret;
01181     short            tmpport;
01182     unsigned long    tmpaddr;
01183     char             hostnamebuf[256];           /* tmp space */
01184 
01185     PRMSG (2,"TRANS(SocketINETConnect) (%d,%s,%s)\n", ciptr->fd, host, port);
01186 
01187     if (!host)
01188     {
01189        hostnamebuf[0] = '\0';
01190        (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
01191        host = hostnamebuf;
01192     }
01193 
01194 #ifdef X11_t
01195     /*
01196      * X has a well known port, that is transport dependent. It is easier
01197      * to handle it here, than try and come up with a transport independent
01198      * representation that can be passed in and resolved the usual way.
01199      *
01200      * The port that is passed here is really a string containing the idisplay
01201      * from ConnectDisplay().
01202      */
01203 
01204     if (is_numeric (port))
01205     {
01206        tmpport = (short) atoi (port);
01207 
01208        sprintf (portbuf, "%d", X_TCP_PORT + tmpport);
01209     }
01210     else
01211 #endif
01212        strncpy (portbuf, port, PORTBUFSIZE);
01213 
01214     /*
01215      * Build the socket name.
01216      */
01217 
01218 #ifdef BSD44SOCKETS
01219     sockname.sin_len = sizeof (struct sockaddr_in);
01220 #endif
01221     sockname.sin_family = AF_INET;
01222 
01223     /*
01224      * fill in sin_addr
01225      */
01226 
01227     /* check for ww.xx.yy.zz host string */
01228 
01229     if (isascii (host[0]) && isdigit (host[0])) {
01230        tmpaddr = inet_addr (host); /* returns network byte order */
01231     } else {
01232        tmpaddr = -1;
01233     }
01234 
01235     PRMSG (4,"TRANS(SocketINETConnect) inet_addr(%s) = %x\n",
01236        host, tmpaddr, 0);
01237 
01238     if (tmpaddr == -1)
01239     {
01240        if ((hostp = gethostbyname(host)) == NULL)
01241        {
01242            PRMSG (1,"TRANS(SocketINETConnect) () can't get address for %s\n",
01243                 host, 0, 0);
01244            ESET(EINVAL);
01245            return TRANS_CONNECT_FAILED;
01246        }
01247        if (hostp->h_addrtype != AF_INET)  /* is IP host? */
01248        {
01249            PRMSG (1,"TRANS(SocketINETConnect) () not INET host%s\n",
01250                 host, 0, 0);
01251            ESET(EPROTOTYPE);
01252            return TRANS_CONNECT_FAILED;
01253        }
01254        
01255 #if defined(CRAY) && defined(OLDTCP)
01256         /* Only Cray UNICOS3 and UNICOS4 will define this */
01257         {
01258        long t;
01259        memcpy ((char *)&t, (char *) hostp->h_addr, sizeof (t));
01260        sockname.sin_addr = t;
01261         }
01262 #else
01263         memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr,
01264               sizeof (sockname.sin_addr));
01265 #endif /* CRAY and OLDTCP */
01266        
01267     }
01268 else
01269     {
01270 #if defined(CRAY) && defined(OLDTCP)
01271        /* Only Cray UNICOS3 and UNICOS4 will define this */
01272        sockname.sin_addr = tmpaddr;
01273 #else
01274        sockname.sin_addr.s_addr = tmpaddr;
01275 #endif /* CRAY and OLDTCP */
01276     }
01277 
01278     /*
01279      * fill in sin_port
01280      */
01281     
01282     /* Check for number in the port string */
01283 
01284     if (!is_numeric (portbuf))
01285     {
01286        if ((servp = getservbyname (portbuf,"tcp")) == NULL)
01287        {
01288            PRMSG (1,"TRANS(SocketINETConnect) () can't get service for %s\n",
01289                 portbuf, 0, 0);
01290            return TRANS_CONNECT_FAILED;
01291        }
01292        sockname.sin_port = servp->s_port;
01293     }
01294     else
01295     {
01296        tmpport = (short) atoi (portbuf);
01297        sockname.sin_port = htons (tmpport);
01298     }
01299     
01300     PRMSG (4,"TRANS(SocketINETConnect) sockname.sin_port = %d\n",
01301          ntohs(sockname.sin_port), 0, 0);
01302 
01303     /*
01304      * Do the connect()
01305      */
01306 
01307     if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0)
01308     {
01309 #ifdef WIN32
01310        int olderrno = WSAGetLastError();
01311 #else
01312        int olderrno = errno;
01313 #endif
01314 
01315        PRMSG (1,"TRANS(SocketINETConnect) () can't connect: errno = %d\n",
01316          EGET(),0, 0);
01317 
01318        /*
01319         * If the error was ECONNREFUSED, the server may be overloaded
01320         * and we should try again.
01321         *
01322         * If the error was EINTR, the connect was interrupted and we
01323         * should try again.
01324         */
01325 
01326        if (olderrno == ECONNREFUSED || olderrno == EINTR)
01327            return TRANS_TRY_CONNECT_AGAIN;
01328        else
01329            return TRANS_CONNECT_FAILED;   
01330     }
01331     
01332 
01333     /*
01334      * Sync up the address fields of ciptr.
01335      */
01336     
01337     if (TRANS(SocketINETGetAddr) (ciptr) < 0)
01338     {
01339        PRMSG (1,
01340           "TRANS(SocketINETConnect): TRANS(SocketINETGetAddr) () failed:\n",
01341           0, 0, 0);
01342        return TRANS_CONNECT_FAILED;
01343     }
01344 
01345     if (TRANS(SocketINETGetPeerAddr) (ciptr) < 0)
01346     {
01347        PRMSG (1,
01348         "TRANS(SocketINETConnect): TRANS(SocketINETGetPeerAddr) () failed:\n",
01349              0, 0, 0);
01350        return TRANS_CONNECT_FAILED;
01351     }
01352 
01353     return 0;
01354 }
01355 
01356 #endif /* TCPCONN */
01357 
01358 
01359 
01360 #ifdef UNIXCONN
01361 
01362 /*
01363  * Make sure 'host' is really local.
01364  */
01365 
01366 static int
01367 UnixHostReallyLocal (host)
01368 
01369 char *host;
01370 
01371 {
01372     char hostnamebuf[256];
01373 
01374     TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
01375 
01376     if (strcmp (hostnamebuf, host) == 0)
01377     {
01378        return (1);
01379     }
01380     else
01381     {
01382        /*
01383         * A host may have more than one network address.  If any of the
01384         * network addresses of 'host' (specified to the connect call)
01385         * match any of the network addresses of 'hostname' (determined
01386         * by TRANS(GetHostname)), then the two hostnames are equivalent,
01387         * and we know that 'host' is really a local host.
01388         */
01389 
01390        struct hostent *specified_local_host;
01391        struct hostent *actual_local_host;
01392        char specified_local_addr_list[10][4];
01393        int scount, equiv, i, j;
01394 
01395        if ((specified_local_host = gethostbyname (host)) == NULL)
01396            return (0);
01397 
01398        scount = 0;
01399        while (specified_local_host->h_addr_list[scount] && scount <= 8)
01400        {
01401            /*
01402             * The 2nd call to gethostname() overrides the data
01403             * from the 1st call, so we must save the address list.
01404             */
01405 
01406            specified_local_addr_list[scount][0] =
01407               specified_local_host->h_addr_list[scount][0];
01408            specified_local_addr_list[scount][1] =
01409               specified_local_host->h_addr_list[scount][1];
01410            specified_local_addr_list[scount][2] =
01411               specified_local_host->h_addr_list[scount][2];
01412            specified_local_addr_list[scount][3] =
01413               specified_local_host->h_addr_list[scount][3];
01414            scount++;
01415        }
01416 
01417        if ((actual_local_host = gethostbyname (hostnamebuf)) == NULL)
01418            return (0);
01419 
01420        equiv = 0;
01421        i = 0;
01422 
01423        while (i < scount && !equiv)
01424        {
01425            j = 0;
01426 
01427            while (actual_local_host->h_addr_list[j])
01428            {
01429               if ((specified_local_addr_list[i][0] ==
01430                    actual_local_host->h_addr_list[j][0]) &&
01431                   (specified_local_addr_list[i][1] ==
01432                    actual_local_host->h_addr_list[j][1]) &&
01433                   (specified_local_addr_list[i][2] ==
01434                    actual_local_host->h_addr_list[j][2]) &&
01435                   (specified_local_addr_list[i][3] ==
01436                    actual_local_host->h_addr_list[j][3]))
01437               {
01438                   /* They're equal, so we're done */
01439                   
01440                   equiv = 1;
01441                   break;
01442               }
01443 
01444               j++;
01445            }
01446 
01447            i++;
01448        }
01449        
01450     return (equiv);
01451     }
01452 }
01453 
01454 static int
01455 TRANS(SocketUNIXConnect) (ciptr, host, port)
01456 
01457 XtransConnInfo ciptr;
01458 char *host;
01459 char *port;
01460 
01461 {
01462     struct sockaddr_un      sockname;
01463     int                     namelen;
01464 
01465 #if defined(hpux) && defined(X11_t)
01466     struct sockaddr_un      old_sockname;
01467     int                     old_namelen;
01468 #endif
01469 
01470 
01471     PRMSG (2,"TRANS(SocketUNIXConnect) (%d,%s,%s)\n", ciptr->fd, host, port);
01472     
01473     /*
01474      * Make sure 'host' is really local.  If not, we return failure.
01475      * The reason we make this check is because a process may advertise
01476      * a "local" network ID for which it can accept connections, but if
01477      * a process on a remote machine tries to connect to this network ID,
01478      * we know for sure it will fail.
01479      */
01480 
01481     if (strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host))
01482     {
01483        PRMSG (1,
01484           "TRANS(SocketUNIXConnect): Cannot connect to non-local host %s\n",
01485               host, 0, 0);
01486        return TRANS_CONNECT_FAILED;
01487     }
01488 
01489 
01490     /*
01491      * Check the port.
01492      */
01493 
01494     if (!port || !*port)
01495     {
01496        PRMSG (1,"TRANS(SocketUNIXConnect): Missing port specification\n",
01497              0, 0, 0);
01498        return TRANS_CONNECT_FAILED;
01499     }
01500 
01501     /*
01502      * Build the socket name.
01503      */
01504     
01505     sockname.sun_family = AF_UNIX;
01506 
01507     if (*port == '/') { /* a full pathname */
01508        sprintf (sockname.sun_path, "%s", port);
01509     } else {
01510        sprintf (sockname.sun_path, "%s%s", UNIX_PATH, port);
01511     }
01512 
01513 #ifdef BSD44SOCKETS
01514     sockname.sun_len = strlen (sockname.sun_path);
01515     namelen = SUN_LEN (&sockname);
01516 #else
01517     namelen = strlen (sockname.sun_path) + sizeof (sockname.sun_family);
01518 #endif
01519 
01520 
01521 #if defined(hpux) && defined(X11_t)
01522     /*
01523      * This is gross, but it was in Xlib
01524      */
01525     old_sockname.sun_family = AF_UNIX;
01526     if (*port == '/') { /* a full pathname */
01527        sprintf (old_sockname.sun_path, "%s", port);
01528     } else {
01529        sprintf (old_sockname.sun_path, "%s%s", OLD_UNIX_PATH, port);
01530     }
01531     old_namelen = strlen (old_sockname.sun_path) +
01532        sizeof (old_sockname.sun_family);
01533 #endif
01534 
01535 
01536     /*
01537      * Do the connect()
01538      */
01539 
01540     if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0)
01541     {
01542        int olderrno = errno;
01543        int connected = 0;
01544        
01545 #if defined(hpux) && defined(X11_t)
01546        if (olderrno == ENOENT)
01547        {
01548            if (connect (ciptr->fd,
01549               (struct sockaddr *) &old_sockname, old_namelen) >= 0)
01550            {
01551               connected = 1;
01552            }
01553            else
01554               olderrno = errno;
01555        }
01556 #endif
01557        if (!connected)
01558        {
01559            errno = olderrno;
01560            
01561            PRMSG (1,"TRANS(SocketUNIXConnect) () can't connect: errno = %d\n",
01562                 EGET(),0, 0);
01563 
01564            if (olderrno == ENOENT || olderrno == EINTR)
01565               return TRANS_TRY_CONNECT_AGAIN;
01566            else
01567               return TRANS_CONNECT_FAILED;
01568        }
01569     }
01570 
01571     /*
01572      * Get the socket name and the peer name from the connect socket,
01573      * since this is unix domain.
01574      */
01575 
01576     if ((ciptr->addr = (char *) malloc(namelen)) == NULL ||
01577        (ciptr->peeraddr = (char *) malloc(namelen)) == NULL)
01578     {
01579         PRMSG (1,
01580        "TRANS(SocketUNIXCreateListener): Can't allocate space for the addr\n",
01581              0, 0, 0);
01582         return TRANS_CONNECT_FAILED;
01583     }
01584 
01585     ciptr->family = AF_UNIX;
01586     ciptr->addrlen = namelen;
01587     ciptr->peeraddrlen = namelen;
01588     memcpy (ciptr->addr, &sockname, ciptr->addrlen);
01589     memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
01590     
01591     return 0;
01592 }
01593 
01594 #endif /* UNIXCONN */
01595 
01596 #endif /* TRANS_CLIENT */
01597 
01598 
01599 static int
01600 TRANS(SocketBytesReadable) (ciptr, pend)
01601 
01602 XtransConnInfo ciptr;
01603 BytesReadable_t *pend;
01604 
01605 {
01606     PRMSG (2,"TRANS(SocketBytesReadable) (%x,%d,%x)\n",
01607        ciptr, ciptr->fd, pend);
01608 
01609 #ifdef WIN32
01610     return ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
01611 #else
01612 #if (defined(i386) && defined(SYSV) && !defined(SCO)) || defined(_SEQUENT_)
01613     return ioctl (ciptr->fd, I_NREAD, (char *) pend);
01614 #else
01615     return ioctl (ciptr->fd, FIONREAD, (char *) pend);
01616 #endif /* i386 && SYSV || _SEQUENT_ */
01617 #endif /* WIN32 */
01618 }
01619 
01620 
01621 static int
01622 TRANS(SocketRead) (ciptr, buf, size)
01623 
01624 XtransConnInfo       ciptr;
01625 char          *buf;
01626 int           size;
01627 
01628 {
01629     PRMSG (2,"TRANS(SocketRead) (%d,%x,%d)\n", ciptr->fd, buf, size);
01630 
01631 #ifdef WIN32
01632     return recv ((SOCKET)ciptr->fd, buf, size, 0);
01633 #else
01634     return read (ciptr->fd, buf, size);
01635 #endif /* WIN32 */
01636 }
01637 
01638 
01639 static int
01640 TRANS(SocketWrite) (ciptr, buf, size)
01641 
01642 XtransConnInfo ciptr;
01643 char          *buf;
01644 int           size;
01645 
01646 {
01647     PRMSG (2,"TRANS(SocketWrite) (%d,%x,%d)\n", ciptr->fd, buf, size);
01648 
01649 #ifdef WIN32
01650     return send ((SOCKET)ciptr->fd, buf, size, 0);
01651 #else
01652     return write (ciptr->fd, buf, size);
01653 #endif /* WIN32 */
01654 }
01655 
01656 
01657 static int
01658 TRANS(SocketReadv) (ciptr, buf, size)
01659 
01660 XtransConnInfo       ciptr;
01661 struct iovec  *buf;
01662 int           size;
01663 
01664 {
01665     PRMSG (2,"TRANS(SocketReadv) (%d,%x,%d)\n", ciptr->fd, buf, size);
01666 
01667     return READV (ciptr, buf, size);
01668 }
01669 
01670 
01671 static int
01672 TRANS(SocketWritev) (ciptr, buf, size)
01673 
01674 XtransConnInfo       ciptr;
01675 struct iovec  *buf;
01676 int           size;
01677 
01678 {
01679     PRMSG (2,"TRANS(SocketWritev) (%d,%x,%d)\n", ciptr->fd, buf, size);
01680 
01681     return WRITEV (ciptr, buf, size);
01682 }
01683 
01684 
01685 static int
01686 TRANS(SocketDisconnect) (ciptr)
01687 
01688 XtransConnInfo ciptr;
01689 
01690 {
01691     PRMSG (2,"TRANS(SocketDisconnect) (%x,%d)\n", ciptr, ciptr->fd, 0);
01692 
01693     return shutdown (ciptr->fd, 2); /* disallow further sends and receives */
01694 }
01695 
01696 
01697 #ifdef TCPCONN
01698 static int
01699 TRANS(SocketINETClose) (ciptr)
01700 
01701 XtransConnInfo ciptr;
01702 
01703 {
01704     PRMSG (2,"TRANS(SocketINETClose) (%x,%d)\n", ciptr, ciptr->fd, 0);
01705 
01706     return close (ciptr->fd);
01707 }
01708 
01709 #endif /* TCPCONN */
01710 
01711 
01712 #ifdef UNIXCONN
01713 static int
01714 TRANS(SocketUNIXClose) (ciptr)
01715 
01716 XtransConnInfo ciptr;
01717 
01718 {
01719     /*
01720      * If this is the server side, then once the socket is closed,
01721      * it must be unlinked to completely close it
01722      */
01723 
01724     struct sockaddr_un      *sockname = (struct sockaddr_un *) ciptr->addr;
01725     char      path[200]; /* > sizeof sun_path +1 */
01726     int ret;
01727 
01728     PRMSG (2,"TRANS(SocketUNIXClose) (%x,%d)\n", ciptr, ciptr->fd, 0);
01729 
01730     ret = close(ciptr->fd);
01731 
01732     if (ciptr->flags
01733        && sockname
01734        && sockname->sun_family == AF_UNIX
01735        && sockname->sun_path[0])
01736     {
01737        strncpy (path, sockname->sun_path,
01738               ciptr->addrlen - sizeof (sockname->sun_family));
01739        unlink (path);
01740     }
01741 
01742     return ret;
01743 }
01744 
01745 static int
01746 TRANS(SocketUNIXCloseForCloning) (ciptr)
01747 
01748 XtransConnInfo ciptr;
01749 
01750 {
01751     /*
01752      * Don't unlink path.
01753      */
01754 
01755     int ret;
01756 
01757     PRMSG (2,"TRANS(SocketUNIXCloseForCloning) (%x,%d)\n",
01758        ciptr, ciptr->fd, 0);
01759 
01760     ret = close(ciptr->fd);
01761 
01762     return ret;
01763 }
01764 
01765 #endif /* UNIXCONN */
01766 
01767 
01768 #ifdef TCPCONN
01769 Xtransport    TRANS(SocketTCPFuncs) = {
01770        /* Socket Interface */
01771        "tcp",
01772         0,
01773 #ifdef TRANS_CLIENT
01774        TRANS(SocketOpenCOTSClient),
01775 #endif /* TRANS_CLIENT */
01776 #ifdef TRANS_SERVER
01777        TRANS(SocketOpenCOTSServer),
01778 #endif /* TRANS_SERVER */
01779 #ifdef TRANS_CLIENT
01780        TRANS(SocketOpenCLTSClient),
01781 #endif /* TRANS_CLIENT */
01782 #ifdef TRANS_SERVER
01783        TRANS(SocketOpenCLTSServer),
01784 #endif /* TRANS_SERVER */
01785 #ifdef TRANS_REOPEN
01786        TRANS(SocketReopenCOTSServer),
01787        TRANS(SocketReopenCLTSServer),
01788 #endif
01789        TRANS(SocketSetOption),
01790 #ifdef TRANS_SERVER
01791        TRANS(SocketINETCreateListener),
01792        NULL,                                     /* ResetListener */
01793        TRANS(SocketINETAccept),
01794 #endif /* TRANS_SERVER */
01795 #ifdef TRANS_CLIENT
01796        TRANS(SocketINETConnect),
01797 #endif /* TRANS_CLIENT */
01798        TRANS(SocketBytesReadable),
01799        TRANS(SocketRead),
01800        TRANS(SocketWrite),
01801        TRANS(SocketReadv),
01802        TRANS(SocketWritev),
01803        TRANS(SocketDisconnect),
01804        TRANS(SocketINETClose),
01805        TRANS(SocketINETClose),
01806        };
01807 
01808 Xtransport    TRANS(SocketINETFuncs) = {
01809        /* Socket Interface */
01810        "inet",
01811        TRANS_ALIAS,
01812 #ifdef TRANS_CLIENT
01813        TRANS(SocketOpenCOTSClient),
01814 #endif /* TRANS_CLIENT */
01815 #ifdef TRANS_SERVER
01816        TRANS(SocketOpenCOTSServer),
01817 #endif /* TRANS_SERVER */
01818 #ifdef TRANS_CLIENT
01819        TRANS(SocketOpenCLTSClient),
01820 #endif /* TRANS_CLIENT */
01821 #ifdef TRANS_SERVER
01822        TRANS(SocketOpenCLTSServer),
01823 #endif /* TRANS_SERVER */
01824 #ifdef TRANS_REOPEN
01825        TRANS(SocketReopenCOTSServer),
01826        TRANS(SocketReopenCLTSServer),
01827 #endif
01828        TRANS(SocketSetOption),
01829 #ifdef TRANS_SERVER
01830        TRANS(SocketINETCreateListener),
01831        NULL,                                     /* ResetListener */
01832        TRANS(SocketINETAccept),
01833 #endif /* TRANS_SERVER */
01834 #ifdef TRANS_CLIENT
01835        TRANS(SocketINETConnect),
01836 #endif /* TRANS_CLIENT */
01837        TRANS(SocketBytesReadable),
01838        TRANS(SocketRead),
01839        TRANS(SocketWrite),
01840        TRANS(SocketReadv),
01841        TRANS(SocketWritev),
01842        TRANS(SocketDisconnect),
01843        TRANS(SocketINETClose),
01844        TRANS(SocketINETClose),
01845        };
01846 
01847 #endif /* TCPCONN */
01848 
01849 #ifdef UNIXCONN
01850 #if !defined(LOCALCONN)
01851 Xtransport    TRANS(SocketLocalFuncs) = {
01852        /* Socket Interface */
01853        "local",
01854        0,
01855 #ifdef TRANS_CLIENT
01856        TRANS(SocketOpenCOTSClient),
01857 #endif /* TRANS_CLIENT */
01858 #ifdef TRANS_SERVER
01859        TRANS(SocketOpenCOTSServer),
01860 #endif /* TRANS_SERVER */
01861 #ifdef TRANS_CLIENT
01862        TRANS(SocketOpenCLTSClient),
01863 #endif /* TRANS_CLIENT */
01864 #ifdef TRANS_SERVER
01865        TRANS(SocketOpenCLTSServer),
01866 #endif /* TRANS_SERVER */
01867 #ifdef TRANS_REOPEN
01868        TRANS(SocketReopenCOTSServer),
01869        TRANS(SocketReopenCLTSServer),
01870 #endif
01871        TRANS(SocketSetOption),
01872 #ifdef TRANS_SERVER
01873        TRANS(SocketUNIXCreateListener),
01874        TRANS(SocketUNIXResetListener),
01875        TRANS(SocketUNIXAccept),
01876 #endif /* TRANS_SERVER */
01877 #ifdef TRANS_CLIENT
01878        TRANS(SocketUNIXConnect),
01879 #endif /* TRANS_CLIENT */
01880        TRANS(SocketBytesReadable),
01881        TRANS(SocketRead),
01882        TRANS(SocketWrite),
01883        TRANS(SocketReadv),
01884        TRANS(SocketWritev),
01885        TRANS(SocketDisconnect),
01886        TRANS(SocketUNIXClose),
01887        TRANS(SocketUNIXCloseForCloning),
01888        };
01889 #endif /* !LOCALCONN */
01890 
01891 Xtransport    TRANS(SocketUNIXFuncs) = {
01892        /* Socket Interface */
01893        "unix",
01894 #if !defined(LOCALCONN)
01895         TRANS_ALIAS,
01896 #else
01897        0,
01898 #endif
01899 #ifdef TRANS_CLIENT
01900        TRANS(SocketOpenCOTSClient),
01901 #endif /* TRANS_CLIENT */
01902 #ifdef TRANS_SERVER
01903        TRANS(SocketOpenCOTSServer),
01904 #endif /* TRANS_SERVER */
01905 #ifdef TRANS_CLIENT
01906        TRANS(SocketOpenCLTSClient),
01907 #endif /* TRANS_CLIENT */
01908 #ifdef TRANS_SERVER
01909        TRANS(SocketOpenCLTSServer),
01910 #endif /* TRANS_SERVER */
01911 #ifdef TRANS_REOPEN
01912        TRANS(SocketReopenCOTSServer),
01913        TRANS(SocketReopenCLTSServer),
01914 #endif
01915        TRANS(SocketSetOption),
01916 #ifdef TRANS_SERVER
01917        TRANS(SocketUNIXCreateListener),
01918        TRANS(SocketUNIXResetListener),
01919        TRANS(SocketUNIXAccept),
01920 #endif /* TRANS_SERVER */
01921 #ifdef TRANS_CLIENT
01922        TRANS(SocketUNIXConnect),
01923 #endif /* TRANS_CLIENT */
01924        TRANS(SocketBytesReadable),
01925        TRANS(SocketRead),
01926        TRANS(SocketWrite),
01927        TRANS(SocketReadv),
01928        TRANS(SocketWritev),
01929        TRANS(SocketDisconnect),
01930        TRANS(SocketUNIXClose),
01931        TRANS(SocketUNIXCloseForCloning),
01932        };
01933 
01934 #endif /* UNIXCONN */