]> jfr.im git - irc/gameservirc.git/blobdiff - gameserv/sockhelp.cpp
fixed some bugs
[irc/gameservirc.git] / gameserv / sockhelp.cpp
index 25cfcb5a21ea279334cd1c9864aa67fc42519377..e6e25d270702c5579af3e4b1ecef4f2693e588fb 100644 (file)
@@ -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 != 0) {
-    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,