OSDN Git Service

Delete unused source files for 1.98d.
[ffftp/ffftp.git] / putty / UNIX / UXNET.C
diff --git a/putty/UNIX/UXNET.C b/putty/UNIX/UXNET.C
deleted file mode 100644 (file)
index 0882638..0000000
+++ /dev/null
@@ -1,1435 +0,0 @@
-/*\r
- * Unix networking abstraction.\r
- */\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <assert.h>\r
-#include <errno.h>\r
-#include <fcntl.h>\r
-#include <unistd.h>\r
-#include <sys/types.h>\r
-#include <sys/socket.h>\r
-#include <sys/ioctl.h>\r
-#include <arpa/inet.h>\r
-#include <netinet/in.h>\r
-#include <netinet/tcp.h>\r
-#include <netdb.h>\r
-#include <sys/un.h>\r
-\r
-#define DEFINE_PLUG_METHOD_MACROS\r
-#include "putty.h"\r
-#include "network.h"\r
-#include "tree234.h"\r
-\r
-/* Solaris needs <sys/sockio.h> for SIOCATMARK. */\r
-#ifndef SIOCATMARK\r
-#include <sys/sockio.h>\r
-#endif\r
-\r
-#ifndef X11_UNIX_PATH\r
-# define X11_UNIX_PATH "/tmp/.X11-unix/X"\r
-#endif\r
-\r
-/* \r
- * Access to sockaddr types without breaking C strict aliasing rules.\r
- */\r
-union sockaddr_union {\r
-#ifdef NO_IPV6\r
-    struct sockaddr_in storage;\r
-#else\r
-    struct sockaddr_storage storage;\r
-    struct sockaddr_in6 sin6;\r
-#endif\r
-    struct sockaddr sa;\r
-    struct sockaddr_in sin;\r
-    struct sockaddr_un su;\r
-};\r
-\r
-/*\r
- * We used to typedef struct Socket_tag *Socket.\r
- *\r
- * Since we have made the networking abstraction slightly more\r
- * abstract, Socket no longer means a tcp socket (it could mean\r
- * an ssl socket).  So now we must use Actual_Socket when we know\r
- * we are talking about a tcp socket.\r
- */\r
-typedef struct Socket_tag *Actual_Socket;\r
-\r
-/*\r
- * Mutable state that goes with a SockAddr: stores information\r
- * about where in the list of candidate IP(v*) addresses we've\r
- * currently got to.\r
- */\r
-typedef struct SockAddrStep_tag SockAddrStep;\r
-struct SockAddrStep_tag {\r
-#ifndef NO_IPV6\r
-    struct addrinfo *ai;              /* steps along addr->ais */\r
-#endif\r
-    int curraddr;\r
-};\r
-\r
-struct Socket_tag {\r
-    struct socket_function_table *fn;\r
-    /* the above variable absolutely *must* be the first in this structure */\r
-    const char *error;\r
-    int s;\r
-    Plug plug;\r
-    void *private_ptr;\r
-    bufchain output_data;\r
-    int connected;                    /* irrelevant for listening sockets */\r
-    int writable;\r
-    int frozen; /* this causes readability notifications to be ignored */\r
-    int frozen_readable; /* this means we missed at least one readability\r
-                         * notification while we were frozen */\r
-    int localhost_only;                       /* for listening sockets */\r
-    char oobdata[1];\r
-    int sending_oob;\r
-    int oobpending;                   /* is there OOB data available to read? */\r
-    int oobinline;\r
-    int pending_error;                /* in case send() returns error */\r
-    int listener;\r
-    int nodelay, keepalive;            /* for connect()-type sockets */\r
-    int privport, port;                /* and again */\r
-    SockAddr addr;\r
-    SockAddrStep step;\r
-    /*\r
-     * We sometimes need pairs of Socket structures to be linked:\r
-     * if we are listening on the same IPv6 and v4 port, for\r
-     * example. So here we define `parent' and `child' pointers to\r
-     * track this link.\r
-     */\r
-    Actual_Socket parent, child;\r
-};\r
-\r
-struct SockAddr_tag {\r
-    int refcount;\r
-    const char *error;\r
-    enum { UNRESOLVED, UNIX, IP } superfamily;\r
-#ifndef NO_IPV6\r
-    struct addrinfo *ais;             /* Addresses IPv6 style. */\r
-#else\r
-    unsigned long *addresses;         /* Addresses IPv4 style. */\r
-    int naddresses;\r
-#endif\r
-    char hostname[512];                       /* Store an unresolved host name. */\r
-};\r
-\r
-/*\r
- * Which address family this address belongs to. AF_INET for IPv4;\r
- * AF_INET6 for IPv6; AF_UNSPEC indicates that name resolution has\r
- * not been done and a simple host name is held in this SockAddr\r
- * structure.\r
- */\r
-#ifndef NO_IPV6\r
-#define SOCKADDR_FAMILY(addr, step) \\r
-    ((addr)->superfamily == UNRESOLVED ? AF_UNSPEC : \\r
-     (addr)->superfamily == UNIX ? AF_UNIX : \\r
-     (step).ai ? (step).ai->ai_family : AF_INET)\r
-#else\r
-#define SOCKADDR_FAMILY(addr, step) \\r
-    ((addr)->superfamily == UNRESOLVED ? AF_UNSPEC : \\r
-     (addr)->superfamily == UNIX ? AF_UNIX : AF_INET)\r
-#endif\r
-\r
-/*\r
- * Start a SockAddrStep structure to step through multiple\r
- * addresses.\r
- */\r
-#ifndef NO_IPV6\r
-#define START_STEP(addr, step) \\r
-    ((step).ai = (addr)->ais, (step).curraddr = 0)\r
-#else\r
-#define START_STEP(addr, step) \\r
-    ((step).curraddr = 0)\r
-#endif\r
-\r
-static tree234 *sktree;\r
-\r
-static void uxsel_tell(Actual_Socket s);\r
-\r
-static int cmpfortree(void *av, void *bv)\r
-{\r
-    Actual_Socket a = (Actual_Socket) av, b = (Actual_Socket) bv;\r
-    int as = a->s, bs = b->s;\r
-    if (as < bs)\r
-       return -1;\r
-    if (as > bs)\r
-       return +1;\r
-    if (a < b)\r
-       return -1;\r
-    if (a > b)\r
-       return +1;\r
-    return 0;\r
-}\r
-\r
-static int cmpforsearch(void *av, void *bv)\r
-{\r
-    Actual_Socket b = (Actual_Socket) bv;\r
-    int as = *(int *)av, bs = b->s;\r
-    if (as < bs)\r
-       return -1;\r
-    if (as > bs)\r
-       return +1;\r
-    return 0;\r
-}\r
-\r
-void sk_init(void)\r
-{\r
-    sktree = newtree234(cmpfortree);\r
-}\r
-\r
-void sk_cleanup(void)\r
-{\r
-    Actual_Socket s;\r
-    int i;\r
-\r
-    if (sktree) {\r
-       for (i = 0; (s = index234(sktree, i)) != NULL; i++) {\r
-           close(s->s);\r
-       }\r
-    }\r
-}\r
-\r
-SockAddr sk_namelookup(const char *host, char **canonicalname, int address_family)\r
-{\r
-    SockAddr ret = snew(struct SockAddr_tag);\r
-#ifndef NO_IPV6\r
-    struct addrinfo hints;\r
-    int err;\r
-#else\r
-    unsigned long a;\r
-    struct hostent *h = NULL;\r
-    int n;\r
-#endif\r
-    char realhost[8192];\r
-\r
-    /* Clear the structure and default to IPv4. */\r
-    memset(ret, 0, sizeof(struct SockAddr_tag));\r
-    ret->superfamily = UNRESOLVED;\r
-    *realhost = '\0';\r
-    ret->error = NULL;\r
-    ret->refcount = 1;\r
-\r
-#ifndef NO_IPV6\r
-    hints.ai_flags = AI_CANONNAME;\r
-    hints.ai_family = (address_family == ADDRTYPE_IPV4 ? AF_INET :\r
-                      address_family == ADDRTYPE_IPV6 ? AF_INET6 :\r
-                      AF_UNSPEC);\r
-    hints.ai_socktype = SOCK_STREAM;\r
-    hints.ai_protocol = 0;\r
-    hints.ai_addrlen = 0;\r
-    hints.ai_addr = NULL;\r
-    hints.ai_canonname = NULL;\r
-    hints.ai_next = NULL;\r
-    err = getaddrinfo(host, NULL, &hints, &ret->ais);\r
-    if (err != 0) {\r
-       ret->error = gai_strerror(err);\r
-       return ret;\r
-    }\r
-    ret->superfamily = IP;\r
-    *realhost = '\0';\r
-    if (ret->ais->ai_canonname != NULL)\r
-       strncat(realhost, ret->ais->ai_canonname, sizeof(realhost) - 1);\r
-    else\r
-       strncat(realhost, host, sizeof(realhost) - 1);\r
-#else\r
-    if ((a = inet_addr(host)) == (unsigned long)(in_addr_t)(-1)) {\r
-       /*\r
-        * Otherwise use the IPv4-only gethostbyname... (NOTE:\r
-        * we don't use gethostbyname as a fallback!)\r
-        */\r
-       if (ret->superfamily == UNRESOLVED) {\r
-           /*debug(("Resolving \"%s\" with gethostbyname() (IPv4 only)...\n", host)); */\r
-           if ( (h = gethostbyname(host)) )\r
-               ret->superfamily = IP;\r
-       }\r
-       if (ret->superfamily == UNRESOLVED) {\r
-           ret->error = (h_errno == HOST_NOT_FOUND ||\r
-                         h_errno == NO_DATA ||\r
-                         h_errno == NO_ADDRESS ? "Host does not exist" :\r
-                         h_errno == TRY_AGAIN ?\r
-                         "Temporary name service failure" :\r
-                         "gethostbyname: unknown error");\r
-           return ret;\r
-       }\r
-       /* This way we are always sure the h->h_name is valid :) */\r
-       strncpy(realhost, h->h_name, sizeof(realhost));\r
-       for (n = 0; h->h_addr_list[n]; n++);\r
-       ret->addresses = snewn(n, unsigned long);\r
-       ret->naddresses = n;\r
-       for (n = 0; n < ret->naddresses; n++) {\r
-           memcpy(&a, h->h_addr_list[n], sizeof(a));\r
-           ret->addresses[n] = ntohl(a);\r
-       }\r
-    } else {\r
-       /*\r
-        * This must be a numeric IPv4 address because it caused a\r
-        * success return from inet_addr.\r
-        */\r
-       ret->superfamily = IP;\r
-       strncpy(realhost, host, sizeof(realhost));\r
-       ret->addresses = snew(unsigned long);\r
-       ret->naddresses = 1;\r
-       ret->addresses[0] = ntohl(a);\r
-    }\r
-#endif\r
-    realhost[lenof(realhost)-1] = '\0';\r
-    *canonicalname = snewn(1+strlen(realhost), char);\r
-    strcpy(*canonicalname, realhost);\r
-    return ret;\r
-}\r
-\r
-SockAddr sk_nonamelookup(const char *host)\r
-{\r
-    SockAddr ret = snew(struct SockAddr_tag);\r
-    ret->error = NULL;\r
-    ret->superfamily = UNRESOLVED;\r
-    strncpy(ret->hostname, host, lenof(ret->hostname));\r
-    ret->hostname[lenof(ret->hostname)-1] = '\0';\r
-#ifndef NO_IPV6\r
-    ret->ais = NULL;\r
-#else\r
-    ret->addresses = NULL;\r
-#endif\r
-    ret->refcount = 1;\r
-    return ret;\r
-}\r
-\r
-static int sk_nextaddr(SockAddr addr, SockAddrStep *step)\r
-{\r
-#ifndef NO_IPV6\r
-    if (step->ai && step->ai->ai_next) {\r
-       step->ai = step->ai->ai_next;\r
-       return TRUE;\r
-    } else\r
-       return FALSE;\r
-#else\r
-    if (step->curraddr+1 < addr->naddresses) {\r
-       step->curraddr++;\r
-       return TRUE;\r
-    } else {\r
-       return FALSE;\r
-    }\r
-#endif    \r
-}\r
-\r
-void sk_getaddr(SockAddr addr, char *buf, int buflen)\r
-{\r
-    /* XXX not clear what we should return for Unix-domain sockets; let's\r
-     * hope the question never arises */\r
-    assert(addr->superfamily != UNIX);\r
-    if (addr->superfamily == UNRESOLVED) {\r
-       strncpy(buf, addr->hostname, buflen);\r
-       buf[buflen-1] = '\0';\r
-    } else {\r
-#ifndef NO_IPV6\r
-       if (getnameinfo(addr->ais->ai_addr, addr->ais->ai_addrlen, buf, buflen,\r
-                       NULL, 0, NI_NUMERICHOST) != 0) {\r
-           buf[0] = '\0';\r
-           strncat(buf, "<unknown>", buflen - 1);\r
-       }\r
-#else\r
-       struct in_addr a;\r
-       SockAddrStep step;\r
-       START_STEP(addr, step);\r
-       assert(SOCKADDR_FAMILY(addr, step) == AF_INET);\r
-       a.s_addr = htonl(addr->addresses[0]);\r
-       strncpy(buf, inet_ntoa(a), buflen);\r
-       buf[buflen-1] = '\0';\r
-#endif\r
-    }\r
-}\r
-\r
-int sk_hostname_is_local(char *name)\r
-{\r
-    return !strcmp(name, "localhost") ||\r
-          !strcmp(name, "::1") ||\r
-          !strncmp(name, "127.", 4);\r
-}\r
-\r
-#define ipv4_is_loopback(addr) \\r
-    (((addr).s_addr & htonl(0xff000000)) == htonl(0x7f000000))\r
-\r
-static int sockaddr_is_loopback(struct sockaddr *sa)\r
-{\r
-    union sockaddr_union *u = (union sockaddr_union *)sa;\r
-    switch (u->sa.sa_family) {\r
-      case AF_INET:\r
-       return ipv4_is_loopback(u->sin.sin_addr);\r
-#ifndef NO_IPV6\r
-      case AF_INET6:\r
-       return IN6_IS_ADDR_LOOPBACK(&u->sin6.sin6_addr);\r
-#endif\r
-      case AF_UNIX:\r
-       return TRUE;\r
-      default:\r
-       return FALSE;\r
-    }\r
-}\r
-\r
-int sk_address_is_local(SockAddr addr)\r
-{\r
-    if (addr->superfamily == UNRESOLVED)\r
-       return 0;                      /* we don't know; assume not */\r
-    else if (addr->superfamily == UNIX)\r
-       return 1;\r
-    else {\r
-#ifndef NO_IPV6\r
-       return sockaddr_is_loopback(addr->ais->ai_addr);\r
-#else\r
-       struct in_addr a;\r
-       SockAddrStep step;\r
-       START_STEP(addr, step);\r
-       assert(SOCKADDR_FAMILY(addr, step) == AF_INET);\r
-       a.s_addr = htonl(addr->addresses[0]);\r
-       return ipv4_is_loopback(a);\r
-#endif\r
-    }\r
-}\r
-\r
-int sk_addrtype(SockAddr addr)\r
-{\r
-    SockAddrStep step;\r
-    int family;\r
-    START_STEP(addr, step);\r
-    family = SOCKADDR_FAMILY(addr, step);\r
-\r
-    return (family == AF_INET ? ADDRTYPE_IPV4 :\r
-#ifndef NO_IPV6\r
-           family == AF_INET6 ? ADDRTYPE_IPV6 :\r
-#endif\r
-           ADDRTYPE_NAME);\r
-}\r
-\r
-void sk_addrcopy(SockAddr addr, char *buf)\r
-{\r
-    SockAddrStep step;\r
-    int family;\r
-    START_STEP(addr, step);\r
-    family = SOCKADDR_FAMILY(addr, step);\r
-\r
-#ifndef NO_IPV6\r
-    if (family == AF_INET)\r
-       memcpy(buf, &((struct sockaddr_in *)step.ai->ai_addr)->sin_addr,\r
-              sizeof(struct in_addr));\r
-    else if (family == AF_INET6)\r
-       memcpy(buf, &((struct sockaddr_in6 *)step.ai->ai_addr)->sin6_addr,\r
-              sizeof(struct in6_addr));\r
-    else\r
-       assert(FALSE);\r
-#else\r
-    struct in_addr a;\r
-\r
-    assert(family == AF_INET);\r
-    a.s_addr = htonl(addr->addresses[step.curraddr]);\r
-    memcpy(buf, (char*) &a.s_addr, 4);\r
-#endif\r
-}\r
-\r
-void sk_addr_free(SockAddr addr)\r
-{\r
-    if (--addr->refcount > 0)\r
-       return;\r
-#ifndef NO_IPV6\r
-    if (addr->ais != NULL)\r
-       freeaddrinfo(addr->ais);\r
-#else\r
-    sfree(addr->addresses);\r
-#endif\r
-    sfree(addr);\r
-}\r
-\r
-SockAddr sk_addr_dup(SockAddr addr)\r
-{\r
-    addr->refcount++;\r
-    return addr;\r
-}\r
-\r
-static Plug sk_tcp_plug(Socket sock, Plug p)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-    Plug ret = s->plug;\r
-    if (p)\r
-       s->plug = p;\r
-    return ret;\r
-}\r
-\r
-static void sk_tcp_flush(Socket s)\r
-{\r
-    /*\r
-     * We send data to the socket as soon as we can anyway,\r
-     * so we don't need to do anything here.  :-)\r
-     */\r
-}\r
-\r
-static void sk_tcp_close(Socket s);\r
-static int sk_tcp_write(Socket s, const char *data, int len);\r
-static int sk_tcp_write_oob(Socket s, const char *data, int len);\r
-static void sk_tcp_set_private_ptr(Socket s, void *ptr);\r
-static void *sk_tcp_get_private_ptr(Socket s);\r
-static void sk_tcp_set_frozen(Socket s, int is_frozen);\r
-static const char *sk_tcp_socket_error(Socket s);\r
-\r
-static struct socket_function_table tcp_fn_table = {\r
-    sk_tcp_plug,\r
-    sk_tcp_close,\r
-    sk_tcp_write,\r
-    sk_tcp_write_oob,\r
-    sk_tcp_flush,\r
-    sk_tcp_set_private_ptr,\r
-    sk_tcp_get_private_ptr,\r
-    sk_tcp_set_frozen,\r
-    sk_tcp_socket_error\r
-};\r
-\r
-Socket sk_register(OSSocket sockfd, Plug plug)\r
-{\r
-    Actual_Socket ret;\r
-\r
-    /*\r
-     * Create Socket structure.\r
-     */\r
-    ret = snew(struct Socket_tag);\r
-    ret->fn = &tcp_fn_table;\r
-    ret->error = NULL;\r
-    ret->plug = plug;\r
-    bufchain_init(&ret->output_data);\r
-    ret->writable = 1;                /* to start with */\r
-    ret->sending_oob = 0;\r
-    ret->frozen = 1;\r
-    ret->frozen_readable = 0;\r
-    ret->localhost_only = 0;          /* unused, but best init anyway */\r
-    ret->pending_error = 0;\r
-    ret->oobpending = FALSE;\r
-    ret->listener = 0;\r
-    ret->parent = ret->child = NULL;\r
-    ret->addr = NULL;\r
-    ret->connected = 1;\r
-\r
-    ret->s = sockfd;\r
-\r
-    if (ret->s < 0) {\r
-       ret->error = strerror(errno);\r
-       return (Socket) ret;\r
-    }\r
-\r
-    ret->oobinline = 0;\r
-\r
-    uxsel_tell(ret);\r
-    add234(sktree, ret);\r
-\r
-    return (Socket) ret;\r
-}\r
-\r
-static int try_connect(Actual_Socket sock)\r
-{\r
-    int s;\r
-    union sockaddr_union u;\r
-    const union sockaddr_union *sa;\r
-    int err = 0;\r
-    short localport;\r
-    int fl, salen, family;\r
-\r
-    /*\r
-     * Remove the socket from the tree before we overwrite its\r
-     * internal socket id, because that forms part of the tree's\r
-     * sorting criterion. We'll add it back before exiting this\r
-     * function, whether we changed anything or not.\r
-     */\r
-    del234(sktree, sock);\r
-\r
-    if (sock->s >= 0)\r
-        close(sock->s);\r
-\r
-    plug_log(sock->plug, 0, sock->addr, sock->port, NULL, 0);\r
-\r
-    /*\r
-     * Open socket.\r
-     */\r
-    family = SOCKADDR_FAMILY(sock->addr, sock->step);\r
-    assert(family != AF_UNSPEC);\r
-    s = socket(family, SOCK_STREAM, 0);\r
-    sock->s = s;\r
-\r
-    if (s < 0) {\r
-       err = errno;\r
-       goto ret;\r
-    }\r
-\r
-    cloexec(s);\r
-\r
-    if (sock->oobinline) {\r
-       int b = TRUE;\r
-       setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (void *) &b, sizeof(b));\r
-    }\r
-\r
-    if (sock->nodelay) {\r
-       int b = TRUE;\r
-       setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *) &b, sizeof(b));\r
-    }\r
-\r
-    if (sock->keepalive) {\r
-       int b = TRUE;\r
-       setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &b, sizeof(b));\r
-    }\r
-\r
-    /*\r
-     * Bind to local address.\r
-     */\r
-    if (sock->privport)\r
-       localport = 1023;              /* count from 1023 downwards */\r
-    else\r
-       localport = 0;                 /* just use port 0 (ie kernel picks) */\r
-\r
-    /* BSD IP stacks need sockaddr_in zeroed before filling in */\r
-    memset(&u,'\0',sizeof(u));\r
-\r
-    /* We don't try to bind to a local address for UNIX domain sockets.  (Why\r
-     * do we bother doing the bind when localport == 0 anyway?) */\r
-    if (family != AF_UNIX) {\r
-       /* Loop round trying to bind */\r
-       while (1) {\r
-           int retcode;\r
-\r
-#ifndef NO_IPV6\r
-           if (family == AF_INET6) {\r
-               /* XXX use getaddrinfo to get a local address? */\r
-               u.sin6.sin6_family = AF_INET6;\r
-               u.sin6.sin6_addr = in6addr_any;\r
-               u.sin6.sin6_port = htons(localport);\r
-               retcode = bind(s, &u.sa, sizeof(u.sin6));\r
-           } else\r
-#endif\r
-           {\r
-               assert(family == AF_INET);\r
-               u.sin.sin_family = AF_INET;\r
-               u.sin.sin_addr.s_addr = htonl(INADDR_ANY);\r
-               u.sin.sin_port = htons(localport);\r
-               retcode = bind(s, &u.sa, sizeof(u.sin));\r
-           }\r
-           if (retcode >= 0) {\r
-               err = 0;\r
-               break;                 /* done */\r
-           } else {\r
-               err = errno;\r
-               if (err != EADDRINUSE) /* failed, for a bad reason */\r
-                 break;\r
-           }\r
-           \r
-           if (localport == 0)\r
-             break;                   /* we're only looping once */\r
-           localport--;\r
-           if (localport == 0)\r
-             break;                   /* we might have got to the end */\r
-       }\r
-       \r
-       if (err)\r
-           goto ret;\r
-    }\r
-\r
-    /*\r
-     * Connect to remote address.\r
-     */\r
-    switch(family) {\r
-#ifndef NO_IPV6\r
-      case AF_INET:\r
-       /* XXX would be better to have got getaddrinfo() to fill in the port. */\r
-       ((struct sockaddr_in *)sock->step.ai->ai_addr)->sin_port =\r
-           htons(sock->port);\r
-       sa = (const union sockaddr_union *)sock->step.ai->ai_addr;\r
-       salen = sock->step.ai->ai_addrlen;\r
-       break;\r
-      case AF_INET6:\r
-       ((struct sockaddr_in *)sock->step.ai->ai_addr)->sin_port =\r
-           htons(sock->port);\r
-       sa = (const union sockaddr_union *)sock->step.ai->ai_addr;\r
-       salen = sock->step.ai->ai_addrlen;\r
-       break;\r
-#else\r
-      case AF_INET:\r
-       u.sin.sin_family = AF_INET;\r
-       u.sin.sin_addr.s_addr = htonl(sock->addr->addresses[sock->step.curraddr]);\r
-       u.sin.sin_port = htons((short) sock->port);\r
-       sa = &u;\r
-       salen = sizeof u.sin;\r
-       break;\r
-#endif\r
-      case AF_UNIX:\r
-       assert(sock->port == 0);       /* to catch confused people */\r
-       assert(strlen(sock->addr->hostname) < sizeof u.su.sun_path);\r
-       u.su.sun_family = AF_UNIX;\r
-       strcpy(u.su.sun_path, sock->addr->hostname);\r
-       sa = &u;\r
-       salen = sizeof u.su;\r
-       break;\r
-\r
-      default:\r
-       assert(0 && "unknown address family");\r
-       exit(1); /* XXX: GCC doesn't understand assert() on some systems. */\r
-    }\r
-\r
-    fl = fcntl(s, F_GETFL);\r
-    if (fl != -1)\r
-       fcntl(s, F_SETFL, fl | O_NONBLOCK);\r
-\r
-    if ((connect(s, &(sa->sa), salen)) < 0) {\r
-       if ( errno != EINPROGRESS ) {\r
-           err = errno;\r
-           goto ret;\r
-       }\r
-    } else {\r
-       /*\r
-        * If we _don't_ get EWOULDBLOCK, the connect has completed\r
-        * and we should set the socket as connected and writable.\r
-        */\r
-       sock->connected = 1;\r
-       sock->writable = 1;\r
-    }\r
-\r
-    uxsel_tell(sock);\r
-\r
-    ret:\r
-\r
-    /*\r
-     * No matter what happened, put the socket back in the tree.\r
-     */\r
-    add234(sktree, sock);\r
-\r
-    if (err)\r
-       plug_log(sock->plug, 1, sock->addr, sock->port, strerror(err), err);\r
-    return err;\r
-}\r
-\r
-Socket sk_new(SockAddr addr, int port, int privport, int oobinline,\r
-             int nodelay, int keepalive, Plug plug)\r
-{\r
-    Actual_Socket ret;\r
-    int err;\r
-\r
-    /*\r
-     * Create Socket structure.\r
-     */\r
-    ret = snew(struct Socket_tag);\r
-    ret->fn = &tcp_fn_table;\r
-    ret->error = NULL;\r
-    ret->plug = plug;\r
-    bufchain_init(&ret->output_data);\r
-    ret->connected = 0;                       /* to start with */\r
-    ret->writable = 0;                /* to start with */\r
-    ret->sending_oob = 0;\r
-    ret->frozen = 0;\r
-    ret->frozen_readable = 0;\r
-    ret->localhost_only = 0;          /* unused, but best init anyway */\r
-    ret->pending_error = 0;\r
-    ret->parent = ret->child = NULL;\r
-    ret->oobpending = FALSE;\r
-    ret->listener = 0;\r
-    ret->addr = addr;\r
-    START_STEP(ret->addr, ret->step);\r
-    ret->s = -1;\r
-    ret->oobinline = oobinline;\r
-    ret->nodelay = nodelay;\r
-    ret->keepalive = keepalive;\r
-    ret->privport = privport;\r
-    ret->port = port;\r
-\r
-    err = 0;\r
-    do {\r
-        err = try_connect(ret);\r
-    } while (err && sk_nextaddr(ret->addr, &ret->step));\r
-\r
-    if (err)\r
-        ret->error = strerror(err);\r
-\r
-    return (Socket) ret;\r
-}\r
-\r
-Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, int orig_address_family)\r
-{\r
-    int s;\r
-#ifndef NO_IPV6\r
-    struct addrinfo hints, *ai;\r
-    char portstr[6];\r
-#endif\r
-    union sockaddr_union u;\r
-    union sockaddr_union *addr;\r
-    int addrlen;\r
-    Actual_Socket ret;\r
-    int retcode;\r
-    int address_family;\r
-    int on = 1;\r
-\r
-    /*\r
-     * Create Socket structure.\r
-     */\r
-    ret = snew(struct Socket_tag);\r
-    ret->fn = &tcp_fn_table;\r
-    ret->error = NULL;\r
-    ret->plug = plug;\r
-    bufchain_init(&ret->output_data);\r
-    ret->writable = 0;                /* to start with */\r
-    ret->sending_oob = 0;\r
-    ret->frozen = 0;\r
-    ret->frozen_readable = 0;\r
-    ret->localhost_only = local_host_only;\r
-    ret->pending_error = 0;\r
-    ret->parent = ret->child = NULL;\r
-    ret->oobpending = FALSE;\r
-    ret->listener = 1;\r
-    ret->addr = NULL;\r
-\r
-    /*\r
-     * Translate address_family from platform-independent constants\r
-     * into local reality.\r
-     */\r
-    address_family = (orig_address_family == ADDRTYPE_IPV4 ? AF_INET :\r
-#ifndef NO_IPV6\r
-                     orig_address_family == ADDRTYPE_IPV6 ? AF_INET6 :\r
-#endif\r
-                     AF_UNSPEC);\r
-\r
-#ifndef NO_IPV6\r
-    /* Let's default to IPv6.\r
-     * If the stack doesn't support IPv6, we will fall back to IPv4. */\r
-    if (address_family == AF_UNSPEC) address_family = AF_INET6;\r
-#else\r
-    /* No other choice, default to IPv4 */\r
-    if (address_family == AF_UNSPEC)  address_family = AF_INET;\r
-#endif\r
-\r
-    /*\r
-     * Open socket.\r
-     */\r
-    s = socket(address_family, SOCK_STREAM, 0);\r
-\r
-#ifndef NO_IPV6\r
-    /* If the host doesn't support IPv6 try fallback to IPv4. */\r
-    if (s < 0 && address_family == AF_INET6) {\r
-       address_family = AF_INET;\r
-       s = socket(address_family, SOCK_STREAM, 0);\r
-    }\r
-#endif\r
-\r
-    if (s < 0) {\r
-       ret->error = strerror(errno);\r
-       return (Socket) ret;\r
-    }\r
-\r
-    cloexec(s);\r
-\r
-    ret->oobinline = 0;\r
-\r
-    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on));\r
-\r
-    retcode = -1;\r
-    addr = NULL; addrlen = -1;         /* placate optimiser */\r
-\r
-    if (srcaddr != NULL) {\r
-#ifndef NO_IPV6\r
-        hints.ai_flags = AI_NUMERICHOST;\r
-        hints.ai_family = address_family;\r
-        hints.ai_socktype = SOCK_STREAM;\r
-        hints.ai_protocol = 0;\r
-        hints.ai_addrlen = 0;\r
-        hints.ai_addr = NULL;\r
-        hints.ai_canonname = NULL;\r
-        hints.ai_next = NULL;\r
-       assert(port >= 0 && port <= 99999);\r
-        sprintf(portstr, "%d", port);\r
-        retcode = getaddrinfo(srcaddr, portstr, &hints, &ai);\r
-       if (retcode == 0) {\r
-           addr = (union sockaddr_union *)ai->ai_addr;\r
-           addrlen = ai->ai_addrlen;\r
-       }\r
-#else\r
-        memset(&u,'\0',sizeof u);\r
-        u.sin.sin_family = AF_INET;\r
-        u.sin.sin_port = htons(port);\r
-        u.sin.sin_addr.s_addr = inet_addr(srcaddr);\r
-        if (u.sin.sin_addr.s_addr != (in_addr_t)(-1)) {\r
-            /* Override localhost_only with specified listen addr. */\r
-            ret->localhost_only = ipv4_is_loopback(u.sin.sin_addr);\r
-        }\r
-        addr = &u;\r
-        addrlen = sizeof(u.sin);\r
-        retcode = 0;\r
-#endif\r
-    }\r
-\r
-    if (retcode != 0) {\r
-        memset(&u,'\0',sizeof u);\r
-#ifndef NO_IPV6\r
-        if (address_family == AF_INET6) {\r
-            u.sin6.sin6_family = AF_INET6;\r
-            u.sin6.sin6_port = htons(port);\r
-            if (local_host_only)\r
-                u.sin6.sin6_addr = in6addr_loopback;\r
-            else\r
-                u.sin6.sin6_addr = in6addr_any;\r
-            addr = &u;\r
-            addrlen = sizeof(u.sin6);\r
-        } else\r
-#endif\r
-        {\r
-            u.sin.sin_family = AF_INET;\r
-            u.sin.sin_port = htons(port);\r
-           if (local_host_only)\r
-               u.sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\r
-           else\r
-               u.sin.sin_addr.s_addr = htonl(INADDR_ANY);\r
-            addr = &u;\r
-            addrlen = sizeof(u.sin);\r
-        }\r
-    }\r
-\r
-    retcode = bind(s, &addr->sa, addrlen);\r
-    if (retcode < 0) {\r
-        close(s);\r
-       ret->error = strerror(errno);\r
-       return (Socket) ret;\r
-    }\r
-\r
-    if (listen(s, SOMAXCONN) < 0) {\r
-        close(s);\r
-       ret->error = strerror(errno);\r
-       return (Socket) ret;\r
-    }\r
-\r
-#ifndef NO_IPV6\r
-    /*\r
-     * If we were given ADDRTYPE_UNSPEC, we must also create an\r
-     * IPv4 listening socket and link it to this one.\r
-     */\r
-    if (address_family == AF_INET6 && orig_address_family == ADDRTYPE_UNSPEC) {\r
-        Actual_Socket other;\r
-\r
-        other = (Actual_Socket) sk_newlistener(srcaddr, port, plug,\r
-                                               local_host_only, ADDRTYPE_IPV4);\r
-\r
-        if (other) {\r
-            if (!other->error) {\r
-                other->parent = ret;\r
-                ret->child = other;\r
-            } else {\r
-                /* If we couldn't create a listening socket on IPv4 as well\r
-                 * as IPv6, we must return an error overall. */\r
-                close(s);\r
-                sfree(ret);\r
-                return (Socket) other;\r
-            }\r
-        }\r
-    }\r
-#endif\r
-\r
-    ret->s = s;\r
-\r
-    uxsel_tell(ret);\r
-    add234(sktree, ret);\r
-\r
-    return (Socket) ret;\r
-}\r
-\r
-static void sk_tcp_close(Socket sock)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-\r
-    if (s->child)\r
-        sk_tcp_close((Socket)s->child);\r
-\r
-    uxsel_del(s->s);\r
-    del234(sktree, s);\r
-    close(s->s);\r
-    if (s->addr)\r
-        sk_addr_free(s->addr);\r
-    sfree(s);\r
-}\r
-\r
-void *sk_getxdmdata(void *sock, int *lenp)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-    union sockaddr_union u;\r
-    socklen_t addrlen;\r
-    char *buf;\r
-    static unsigned int unix_addr = 0xFFFFFFFF;\r
-\r
-    /*\r
-     * We must check that this socket really _is_ an Actual_Socket.\r
-     */\r
-    if (s->fn != &tcp_fn_table)\r
-       return NULL;                   /* failure */\r
-\r
-    addrlen = sizeof(u);\r
-    if (getsockname(s->s, &u.sa, &addrlen) < 0)\r
-       return NULL;\r
-    switch(u.sa.sa_family) {\r
-      case AF_INET:\r
-       *lenp = 6;\r
-       buf = snewn(*lenp, char);\r
-       PUT_32BIT_MSB_FIRST(buf, ntohl(u.sin.sin_addr.s_addr));\r
-       PUT_16BIT_MSB_FIRST(buf+4, ntohs(u.sin.sin_port));\r
-       break;\r
-#ifndef NO_IPV6\r
-    case AF_INET6:\r
-       *lenp = 6;\r
-       buf = snewn(*lenp, char);\r
-       if (IN6_IS_ADDR_V4MAPPED(&u.sin6.sin6_addr)) {\r
-           memcpy(buf, u.sin6.sin6_addr.s6_addr + 12, 4);\r
-           PUT_16BIT_MSB_FIRST(buf+4, ntohs(u.sin6.sin6_port));\r
-       } else\r
-           /* This is stupid, but it's what XLib does. */\r
-           memset(buf, 0, 6);\r
-       break;\r
-#endif\r
-      case AF_UNIX:\r
-       *lenp = 6;\r
-       buf = snewn(*lenp, char);\r
-       PUT_32BIT_MSB_FIRST(buf, unix_addr--);\r
-        PUT_16BIT_MSB_FIRST(buf+4, getpid());\r
-       break;\r
-\r
-       /* XXX IPV6 */\r
-\r
-      default:\r
-       return NULL;\r
-    }\r
-\r
-    return buf;\r
-}\r
-\r
-/*\r
- * The function which tries to send on a socket once it's deemed\r
- * writable.\r
- */\r
-void try_send(Actual_Socket s)\r
-{\r
-    while (s->sending_oob || bufchain_size(&s->output_data) > 0) {\r
-       int nsent;\r
-       int err;\r
-       void *data;\r
-       int len, urgentflag;\r
-\r
-       if (s->sending_oob) {\r
-           urgentflag = MSG_OOB;\r
-           len = s->sending_oob;\r
-           data = &s->oobdata;\r
-       } else {\r
-           urgentflag = 0;\r
-           bufchain_prefix(&s->output_data, &data, &len);\r
-       }\r
-       nsent = send(s->s, data, len, urgentflag);\r
-       noise_ultralight(nsent);\r
-       if (nsent <= 0) {\r
-           err = (nsent < 0 ? errno : 0);\r
-           if (err == EWOULDBLOCK) {\r
-               /*\r
-                * Perfectly normal: we've sent all we can for the moment.\r
-                */\r
-               s->writable = FALSE;\r
-               return;\r
-           } else {\r
-               /*\r
-                * We unfortunately can't just call plug_closing(),\r
-                * because it's quite likely that we're currently\r
-                * _in_ a call from the code we'd be calling back\r
-                * to, so we'd have to make half the SSH code\r
-                * reentrant. Instead we flag a pending error on\r
-                * the socket, to be dealt with (by calling\r
-                * plug_closing()) at some suitable future moment.\r
-                */\r
-               s->pending_error = err;\r
-               return;\r
-           }\r
-       } else {\r
-           if (s->sending_oob) {\r
-               if (nsent < len) {\r
-                   memmove(s->oobdata, s->oobdata+nsent, len-nsent);\r
-                   s->sending_oob = len - nsent;\r
-               } else {\r
-                   s->sending_oob = 0;\r
-               }\r
-           } else {\r
-               bufchain_consume(&s->output_data, nsent);\r
-           }\r
-       }\r
-    }\r
-    uxsel_tell(s);\r
-}\r
-\r
-static int sk_tcp_write(Socket sock, const char *buf, int len)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-\r
-    /*\r
-     * Add the data to the buffer list on the socket.\r
-     */\r
-    bufchain_add(&s->output_data, buf, len);\r
-\r
-    /*\r
-     * Now try sending from the start of the buffer list.\r
-     */\r
-    if (s->writable)\r
-       try_send(s);\r
-\r
-    /*\r
-     * Update the select() status to correctly reflect whether or\r
-     * not we should be selecting for write.\r
-     */\r
-    uxsel_tell(s);\r
-\r
-    return bufchain_size(&s->output_data);\r
-}\r
-\r
-static int sk_tcp_write_oob(Socket sock, const char *buf, int len)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-\r
-    /*\r
-     * Replace the buffer list on the socket with the data.\r
-     */\r
-    bufchain_clear(&s->output_data);\r
-    assert(len <= sizeof(s->oobdata));\r
-    memcpy(s->oobdata, buf, len);\r
-    s->sending_oob = len;\r
-\r
-    /*\r
-     * Now try sending from the start of the buffer list.\r
-     */\r
-    if (s->writable)\r
-       try_send(s);\r
-\r
-    /*\r
-     * Update the select() status to correctly reflect whether or\r
-     * not we should be selecting for write.\r
-     */\r
-    uxsel_tell(s);\r
-\r
-    return s->sending_oob;\r
-}\r
-\r
-static int net_select_result(int fd, int event)\r
-{\r
-    int ret;\r
-    char buf[20480];                  /* nice big buffer for plenty of speed */\r
-    Actual_Socket s;\r
-    u_long atmark;\r
-\r
-    /* Find the Socket structure */\r
-    s = find234(sktree, &fd, cmpforsearch);\r
-    if (!s)\r
-       return 1;                      /* boggle */\r
-\r
-    noise_ultralight(event);\r
-\r
-    switch (event) {\r
-      case 4:                         /* exceptional */\r
-       if (!s->oobinline) {\r
-           /*\r
-            * On a non-oobinline socket, this indicates that we\r
-            * can immediately perform an OOB read and get back OOB\r
-            * data, which we will send to the back end with\r
-            * type==2 (urgent data).\r
-            */\r
-           ret = recv(s->s, buf, sizeof(buf), MSG_OOB);\r
-           noise_ultralight(ret);\r
-           if (ret <= 0) {\r
-                return plug_closing(s->plug,\r
-                                   ret == 0 ? "Internal networking trouble" :\r
-                                   strerror(errno), errno, 0);\r
-           } else {\r
-                /*\r
-                 * Receiving actual data on a socket means we can\r
-                 * stop falling back through the candidate\r
-                 * addresses to connect to.\r
-                 */\r
-                if (s->addr) {\r
-                    sk_addr_free(s->addr);\r
-                    s->addr = NULL;\r
-                }\r
-               return plug_receive(s->plug, 2, buf, ret);\r
-           }\r
-           break;\r
-       }\r
-\r
-       /*\r
-        * If we reach here, this is an oobinline socket, which\r
-        * means we should set s->oobpending and then deal with it\r
-        * when we get called for the readability event (which\r
-        * should also occur).\r
-        */\r
-       s->oobpending = TRUE;\r
-        break;\r
-      case 1:                         /* readable; also acceptance */\r
-       if (s->listener) {\r
-           /*\r
-            * On a listening socket, the readability event means a\r
-            * connection is ready to be accepted.\r
-            */\r
-           union sockaddr_union su;\r
-           socklen_t addrlen = sizeof(su);\r
-           int t;  /* socket of connection */\r
-            int fl;\r
-\r
-           memset(&su, 0, addrlen);\r
-           t = accept(s->s, &su.sa, &addrlen);\r
-           if (t < 0) {\r
-               break;\r
-           }\r
-\r
-            fl = fcntl(t, F_GETFL);\r
-            if (fl != -1)\r
-                fcntl(t, F_SETFL, fl | O_NONBLOCK);\r
-\r
-           if (s->localhost_only &&\r
-               !sockaddr_is_loopback(&su.sa)) {\r
-               close(t);              /* someone let nonlocal through?! */\r
-           } else if (plug_accepting(s->plug, t)) {\r
-               close(t);              /* denied or error */\r
-           }\r
-           break;\r
-       }\r
-\r
-       /*\r
-        * If we reach here, this is not a listening socket, so\r
-        * readability really means readability.\r
-        */\r
-\r
-       /* In the case the socket is still frozen, we don't even bother */\r
-       if (s->frozen) {\r
-           s->frozen_readable = 1;\r
-           break;\r
-       }\r
-\r
-       /*\r
-        * We have received data on the socket. For an oobinline\r
-        * socket, this might be data _before_ an urgent pointer,\r
-        * in which case we send it to the back end with type==1\r
-        * (data prior to urgent).\r
-        */\r
-       if (s->oobinline && s->oobpending) {\r
-           atmark = 1;\r
-           if (ioctl(s->s, SIOCATMARK, &atmark) == 0 && atmark)\r
-               s->oobpending = FALSE; /* clear this indicator */\r
-       } else\r
-           atmark = 1;\r
-\r
-       ret = recv(s->s, buf, s->oobpending ? 1 : sizeof(buf), 0);\r
-       noise_ultralight(ret);\r
-       if (ret < 0) {\r
-           if (errno == EWOULDBLOCK) {\r
-               break;\r
-           }\r
-       }\r
-       if (ret < 0) {\r
-            /*\r
-             * An error at this point _might_ be an error reported\r
-             * by a non-blocking connect(). So before we return a\r
-             * panic status to the user, let's just see whether\r
-             * that's the case.\r
-             */\r
-            int err = errno;\r
-           if (s->addr) {\r
-               plug_log(s->plug, 1, s->addr, s->port, strerror(err), err);\r
-               while (s->addr && sk_nextaddr(s->addr, &s->step)) {\r
-                   err = try_connect(s);\r
-               }\r
-           }\r
-            if (err != 0)\r
-                return plug_closing(s->plug, strerror(err), err, 0);\r
-       } else if (0 == ret) {\r
-           return plug_closing(s->plug, NULL, 0, 0);\r
-       } else {\r
-            /*\r
-             * Receiving actual data on a socket means we can\r
-             * stop falling back through the candidate\r
-             * addresses to connect to.\r
-             */\r
-            if (s->addr) {\r
-                sk_addr_free(s->addr);\r
-                s->addr = NULL;\r
-            }\r
-           return plug_receive(s->plug, atmark ? 0 : 1, buf, ret);\r
-       }\r
-       break;\r
-      case 2:                         /* writable */\r
-       if (!s->connected) {\r
-           /*\r
-            * select() reports a socket as _writable_ when an\r
-            * asynchronous connection is completed.\r
-            */\r
-           s->connected = s->writable = 1;\r
-           uxsel_tell(s);\r
-           break;\r
-       } else {\r
-           int bufsize_before, bufsize_after;\r
-           s->writable = 1;\r
-           bufsize_before = s->sending_oob + bufchain_size(&s->output_data);\r
-           try_send(s);\r
-           bufsize_after = s->sending_oob + bufchain_size(&s->output_data);\r
-           if (bufsize_after < bufsize_before)\r
-               plug_sent(s->plug, bufsize_after);\r
-       }\r
-       break;\r
-    }\r
-\r
-    return 1;\r
-}\r
-\r
-/*\r
- * Deal with socket errors detected in try_send().\r
- */\r
-void net_pending_errors(void)\r
-{\r
-    int i;\r
-    Actual_Socket s;\r
-\r
-    /*\r
-     * This might be a fiddly business, because it's just possible\r
-     * that handling a pending error on one socket might cause\r
-     * others to be closed. (I can't think of any reason this might\r
-     * happen in current SSH implementation, but to maintain\r
-     * generality of this network layer I'll assume the worst.)\r
-     * \r
-     * So what we'll do is search the socket list for _one_ socket\r
-     * with a pending error, and then handle it, and then search\r
-     * the list again _from the beginning_. Repeat until we make a\r
-     * pass with no socket errors present. That way we are\r
-     * protected against the socket list changing under our feet.\r
-     */\r
-\r
-    do {\r
-       for (i = 0; (s = index234(sktree, i)) != NULL; i++) {\r
-           if (s->pending_error) {\r
-               /*\r
-                * An error has occurred on this socket. Pass it to the\r
-                * plug.\r
-                */\r
-               plug_closing(s->plug, strerror(s->pending_error),\r
-                            s->pending_error, 0);\r
-               break;\r
-           }\r
-       }\r
-    } while (s);\r
-}\r
-\r
-/*\r
- * Each socket abstraction contains a `void *' private field in\r
- * which the client can keep state.\r
- */\r
-static void sk_tcp_set_private_ptr(Socket sock, void *ptr)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-    s->private_ptr = ptr;\r
-}\r
-\r
-static void *sk_tcp_get_private_ptr(Socket sock)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-    return s->private_ptr;\r
-}\r
-\r
-/*\r
- * Special error values are returned from sk_namelookup and sk_new\r
- * if there's a problem. These functions extract an error message,\r
- * or return NULL if there's no problem.\r
- */\r
-const char *sk_addr_error(SockAddr addr)\r
-{\r
-    return addr->error;\r
-}\r
-static const char *sk_tcp_socket_error(Socket sock)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-    return s->error;\r
-}\r
-\r
-static void sk_tcp_set_frozen(Socket sock, int is_frozen)\r
-{\r
-    Actual_Socket s = (Actual_Socket) sock;\r
-    if (s->frozen == is_frozen)\r
-       return;\r
-    s->frozen = is_frozen;\r
-    if (!is_frozen && s->frozen_readable) {\r
-       char c;\r
-       recv(s->s, &c, 1, MSG_PEEK);\r
-    }\r
-    s->frozen_readable = 0;\r
-    uxsel_tell(s);\r
-}\r
-\r
-static void uxsel_tell(Actual_Socket s)\r
-{\r
-    int rwx = 0;\r
-    if (s->listener) {\r
-       rwx |= 1;                       /* read == accept */\r
-    } else {\r
-       if (!s->connected)\r
-           rwx |= 2;                   /* write == connect */\r
-       if (s->connected && !s->frozen)\r
-           rwx |= 1 | 4;               /* read, except */\r
-       if (bufchain_size(&s->output_data))\r
-           rwx |= 2;                   /* write */\r
-    }\r
-    uxsel_set(s->s, rwx, net_select_result);\r
-}\r
-\r
-int net_service_lookup(char *service)\r
-{\r
-    struct servent *se;\r
-    se = getservbyname(service, NULL);\r
-    if (se != NULL)\r
-       return ntohs(se->s_port);\r
-    else\r
-       return 0;\r
-}\r
-\r
-char *get_hostname(void)\r
-{\r
-    int len = 128;\r
-    char *hostname = NULL;\r
-    do {\r
-       len *= 2;\r
-       hostname = sresize(hostname, len, char);\r
-       if ((gethostname(hostname, len) < 0) &&\r
-           (errno != ENAMETOOLONG)) {\r
-           sfree(hostname);\r
-           hostname = NULL;\r
-           break;\r
-       }\r
-    } while (strlen(hostname) >= len-1);\r
-    return hostname;\r
-}\r
-\r
-SockAddr platform_get_x11_unix_address(const char *sockpath, int displaynum)\r
-{\r
-    SockAddr ret = snew(struct SockAddr_tag);\r
-    int n;\r
-\r
-    memset(ret, 0, sizeof *ret);\r
-    ret->superfamily = UNIX;\r
-    /*\r
-     * In special circumstances (notably Mac OS X Leopard), we'll\r
-     * have been passed an explicit Unix socket path.\r
-     */\r
-    if (sockpath) {\r
-       n = snprintf(ret->hostname, sizeof ret->hostname,\r
-                    "%s", sockpath);\r
-    } else {\r
-       n = snprintf(ret->hostname, sizeof ret->hostname,\r
-                    "%s%d", X11_UNIX_PATH, displaynum);\r
-    }\r
-\r
-    if (n < 0)\r
-       ret->error = "snprintf failed";\r
-    else if (n >= sizeof ret->hostname)\r
-       ret->error = "X11 UNIX name too long";\r
-\r
-#ifndef NO_IPV6\r
-    ret->ais = NULL;\r
-#else\r
-    ret->addresses = NULL;\r
-    ret->naddresses = 0;\r
-#endif\r
-    ret->refcount = 1;\r
-    return ret;\r
-}\r