X-Git-Url: https://jfr.im/git/irc/gameservirc.git/blobdiff_plain/85ce9d3ecb3e6888dae590b3a8e347e0a2131bd9..d7c069e247c2b2d3073eab722aa0c3afc2a75214:/gameserv/sockhelp.cpp diff --git a/gameserv/sockhelp.cpp b/gameserv/sockhelp.cpp index c68dd8e..e6e25d2 100644 --- a/gameserv/sockhelp.cpp +++ b/gameserv/sockhelp.cpp @@ -13,6 +13,7 @@ */ #include "sockhelp.h" +#include "extern.h" /* Take a service name, and a service type, and return a port number. If the @@ -22,19 +23,14 @@ int atoport(char *service, char *proto) { int port; long int lport; - struct servent *serv; char *errpos; - /* First try to read it from /etc/services */ - serv = getservbyname(service, proto); - if (serv != NULL) - port = serv->s_port; - else { /* Not in services, maybe a number? */ lport = strtol(service,&errpos,0); if ( (errpos[0] != 0) || (lport < 1) || (lport > 65535) ) return -1; /* Invalid port address */ + port = htons(lport); - } + return port; } @@ -43,13 +39,7 @@ int atoport(char *service, char *proto) struct in_addr *atoaddr(char *address) { struct hostent *host; - static struct in_addr saddr; - /* First try it as aaa.bbb.ccc.ddd. */ - saddr.s_addr = inet_addr(address); - if (saddr.s_addr != -1) { - return &saddr; - } host = gethostbyname(address); if (host != NULL) { return (struct in_addr *) *host->h_addr_list; @@ -156,7 +146,119 @@ int get_connection(int socket_type, u_short port, int *listener) else return listening_socket; } +#if !HAVE_GETHOSTBYNAME + +/* Translate an IP dotted-quad address to a 4-byte character string. + * Return NULL if the given string is not in dotted-quad format. + */ + +static char *pack_ip(const char *ipaddr) +{ + static char ipbuf[4]; + int tmp[4], i; + + if (sscanf(ipaddr, "%d.%d.%d.%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3]) + != 4) + return NULL; + for (i = 0; i < 4; i++) { + if (tmp[i] < 0 || tmp[i] > 255) + return NULL; + ipbuf[i] = tmp[i]; + } + return ipbuf; +} + +#endif + +/*************************************************************************/ + +/*************************************************************************/ + +/* lhost/lport specify the local side of the connection. If they are not + * given (lhost==NULL, lport==0), then they are left free to vary. + */ + +int conn(const char *host, int port, const char *lhost, int lport) +{ +#if HAVE_GETHOSTBYNAME + struct hostent *hp; +#else + char *addr; +#endif + struct sockaddr_in sa, lsa; + int sock; + + memset(&lsa, 0, sizeof(lsa)); + if (lhost) + { +#if HAVE_GETHOSTBYNAME + if ((hp = gethostbyname(lhost)) != NULL) + { + memcpy((char *) &lsa.sin_addr, hp->h_addr, hp->h_length); + lsa.sin_family = hp->h_addrtype; +#else + if (addr = pack_ip(lhost)) + { + memcpy((char *) &lsa.sin_addr, addr, 4); + lsa.sin_family = AF_INET; +#endif + } + else + { + lhost = NULL; + } + } + if (lport) + { + lsa.sin_port = htons((unsigned short) lport); + } + + memset(&sa, 0, sizeof(sa)); +#if HAVE_GETHOSTBYNAME + if (!(hp = gethostbyname(host))) + { + return -1; + } + memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length); + sa.sin_family = hp->h_addrtype; +#else + if (!(addr = pack_ip(host))) + { + log("conn(): `%s' is not a valid IP address", host); + errno = EINVAL; + return -1; + } + memcpy((char *) &sa.sin_addr, addr, 4); + sa.sin_family = AF_INET; +#endif + sa.sin_port = htons((unsigned short) port); + + if ((sock = socket(sa.sin_family, SOCK_STREAM, 0)) < 0) + { + return -1; + } + + if ((lhost || lport) + && bind(sock, (struct sockaddr *) &lsa, sizeof(lsa)) < 0) + { + int errno_save = errno; + close(sock); + errno = errno_save; + return -1; + } + + if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0) + { + int errno_save = errno; + close(sock); + errno = errno_save; + return -1; + } + + return sock; +} + /* This is a generic function to make a connection to a given server/port. service is the port name/number, type is either SOCK_STREAM or SOCK_DGRAM, and @@ -191,7 +293,7 @@ int make_connection(char *service, int type, char *netaddress) sock = socket(AF_INET, type, 0); - printf("Connecting to %s on port %d.\n",inet_ntoa(*addr),htons(port)); + log("Connecting to %s on port %d.",inet_ntoa(*addr),htons(port)); if (type == SOCK_STREAM) { connected = connect(sock, (struct sockaddr *) &address, @@ -242,7 +344,7 @@ int sock_read(int sockfd, char *buf, size_t count) int sock_gets(int sockfd, char *str, size_t count) { int bytes_read; - int total_count = 0; + unsigned int total_count = 0; char *current_position; char last_read = 0;