#line 20 "connectsock.c-nw"
#include <config.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif /* INADDR_NONE */

#ifndef BSD
#define bzero(s, n) memset(s, '\0', n)
#define bcopy(s1, s2, n) memmove(s2, s1, n)
#endif /* BSD */

EXPORT int connectsock(char *host, char *service, char *protocol,
                       Bool nonblock)
{
    struct hostent *phe;                /* host information entry */
    struct servent *pse;                /* service information entry */
    struct protoent *ppe;               /* protocol information entry */
    struct sockaddr_in sin;             /* Internet endpoint address */
    int s, type;                        /* socket descriptor and type */
    int flags;                          /* fcntl() flags */

    bzero((char *)&sin, sizeof(sin));
    sin.sin_family = AF_INET;

    /* Map service name to port number */

    if ((pse = getservbyname(service, protocol)))
        sin.sin_port = pse->s_port;
    else if ((sin.sin_port = htons((u_short)atoi(service))) == 0)
        return -1; /* errexit("can't get \"%s\" service entry\n", service); */

    /* Map host name to IP address, allowing for dotted decimal */

    if ((phe = gethostbyname(host)))
        bcopy(phe->h_addr, (char *)&sin.sin_addr, phe->h_length);
    else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
        return -1; /* errexit("can't get \"%s\" host entry\n", host); */

    /* Map protocol name to protocol number */

    if ((ppe = getprotobyname(protocol)) == 0)
        return -1; /* errexit("can't get \"%s\" protocol entry\n",protocol); */

    /* Use protocol to choose a socket type */

    if (strcmp(protocol, "udp") == 0)
        type = SOCK_DGRAM;
    else
        type = SOCK_STREAM;

    /* Allocate a socket */

    if ((s = socket(PF_INET, type, ppe->p_proto)) < 0)
        return -1; /*errexit("can't create socket: %s\n",sys_errlist[errno]);*/

    /* Optionally set non-blocking I/O */
    if (nonblock) {
        if ((flags = fcntl(s, F_GETFL, 0)) == -1) return -1;
        if (fcntl(s, F_SETFL, flags|O_NONBLOCK) == -1) return -1;
    }

    /* Connect the socket */
    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
        return -1; /* errexit("can't connect to %s.%s: %s\n", host, service,
                      sys_errlist[errno]); */

    return s;
}