support hostName in bind.
authorClaus Gittinger <cg@exept.de>
Tue, 25 Mar 1997 10:20:33 +0100
changeset 510 0d076bd01e91
parent 509 eb5a2d5bab0b
child 511 c071e228cb24
support hostName in bind.
Socket.st
--- a/Socket.st	Tue Mar 25 09:53:21 1997 +0100
+++ b/Socket.st	Tue Mar 25 10:20:33 1997 +0100
@@ -1527,16 +1527,16 @@
      i.e. address must always be nil.
 
      The interpretation of portNrOrName depends on the domain:
-	inet domain uses (4byte) byteArray like internet numbers,
-	unix domain uses pathname strings,
-	others use whatever will come up in the future
+        inet domain uses (4byte) byteArray like internet numbers,
+        unix domain uses pathname strings,
+        others use whatever will come up in the future
 
      The reuse boolean argument controls if the SO_REUSEADDR socket option
      is to be set (to avoid the 'bind: address in use' error).
     "
 
     filePointer isNil ifTrue:[
-	^ self error:'not a valid socket'
+        ^ self error:'not a valid socket'
     ].
 %{
 #ifndef NO_SOCKET
@@ -1544,8 +1544,8 @@
     OBJ myDomain;
     int sock;
     union {
-	struct sockaddr_in in;
-	struct sockaddr_un un;
+        struct sockaddr_in in;
+        struct sockaddr_un un;
     } sa;
     int sockaddr_size;
     int ret;
@@ -1553,77 +1553,102 @@
     int ok;
 
     if (!__isString(__INST(domain)) && !__isSymbol(__INST(domain))) {
-	DBGPRINTF(("SOCKET: invalid domain arg\n"));
-	RETURN (false);
+        DBGPRINTF(("SOCKET: invalid domain arg\n"));
+        RETURN (false);
     }
 
     ok = 0;
     myDomain = __INST(domain);
 # ifdef AF_INET
     if (myDomain == @symbol(inet)) {
-	/*
-	 * INET addresses - port must be a smallinteger or nil
-	 */
-	sa.in.sin_family = AF_INET;
-
-	if (portNrOrName == nil) {
-	    sa.in.sin_port = 0;
-	} else {
-	    if (! __isSmallInteger(portNrOrName)) {
-	        DBGPRINTF(("SOCKET: invalid port arg\n"));
-	        RETURN (false);
-	    }
-	    sa.in.sin_port = htons((u_short) _intVal(portNrOrName));
-	}
-
-	/*
-	 * INET addresses - addr must be nil, integer or byteArray
-	 */
-	if (address == nil) {
-	    sa.in.sin_addr.s_addr = htonl(INADDR_ANY);
-	} else {
-	    if (__isInteger(address)) {
-		sa.in.sin_addr.s_addr = htonl(__longIntVal(address));
-	    } else {
-	        if (__isByteArray(address)) {
-		    unsigned char *cp;
-		    int n;
-
-	            cp = __ByteArrayInstPtr(address)->ba_element;
-	            n = __byteArraySize(address);
-	            if (n > 4) n = 4;
-	    	    bcopy(cp, &sa.in.sin_addr.s_addr, n);
-		} else {
-		    printf("SOCKET: address bind not yet supported\n");
-		    RETURN (false);
-		}
-	    }
-	}
-	DBGPRINTF(("SOCKET: bind addr: %x port: %x\n", sa.in.sin_addr.s_addr, sa.in.sin_port));
-	sockaddr_size = sizeof(struct sockaddr_in);
-	ok = 1;
+        /*
+         * INET addresses - port must be a smallinteger or nil
+         */
+        sa.in.sin_family = AF_INET;
+
+        if (portNrOrName == nil) {
+            sa.in.sin_port = 0;
+        } else {
+            if (! __isSmallInteger(portNrOrName)) {
+                DBGPRINTF(("SOCKET: invalid port arg\n"));
+                RETURN (false);
+            }
+            sa.in.sin_port = htons((u_short) _intVal(portNrOrName));
+        }
+
+        /*
+         * INET addresses - addr must be nil, integer or byteArray
+         */
+        if (address == nil) {
+            sa.in.sin_addr.s_addr = htonl(INADDR_ANY);
+        } else {
+            if (__isInteger(address)) {
+                sa.in.sin_addr.s_addr = htonl(__longIntVal(address));
+            } else {
+                if (__isByteArray(address)) {
+                    unsigned char *cp;
+                    int n;
+
+                    cp = __ByteArrayInstPtr(address)->ba_element;
+                    n = __byteArraySize(address);
+                    if (n > 4) n = 4;
+                    bcopy(cp, &sa.in.sin_addr.s_addr, n);
+                } else {
+                    char *hostName;
+                    unsigned addr;
+                    struct hostent *hp ;
+
+                    if (! __isString(address)) {
+                        DBGPRINTF(("SOCKET: invalid address arg in bind\n"));
+                        RETURN (false);
+                    }
+
+                    hostName = (char *) _stringVal(address);
+
+                    if ((addr = inet_addr(hostName)) != -1) {
+                        /* 
+                         * is Internet addr in octet notation 
+                         */
+                        bcopy(&addr, (char *) &sa.in.sin_addr, sizeof(addr)) ; /* set address */
+                    } else {
+                        /* 
+                         * do we know the host's address? 
+                         */
+                        if ((hp = gethostbyname(hostName)) == NULL) {
+                            DBGPRINTF(("SOCKET: unknown host:%s\n", hostName));
+                            RETURN (false);
+                        }
+                        bcopy(hp->h_addr, (char *) &sa.in.sin_addr, hp->h_length) ;
+                        sa.in.sin_family = hp->h_addrtype;
+                    }
+                }
+            }
+        }
+        DBGPRINTF(("SOCKET: bind addr: %x port: %x\n", sa.in.sin_addr.s_addr, sa.in.sin_port));
+        sockaddr_size = sizeof(struct sockaddr_in);
+        ok = 1;
     }
 # endif
 # ifdef AF_UNIX
     if (myDomain == @symbol(unix)) {
-	char *pathName;
-	int l;
-
-	if (! __isString(portNrOrName)) {
-	    DBGPRINTF(("SOCKET: invalid port (pathname) arg\n"));
-	    RETURN (false);
-	}
-	pathName = __stringVal(portNrOrName);
-	l = strlen(pathName);
-	if ((l + sizeof ( sa.un.sun_family )) > sizeof(struct sockaddr_un)) {
-	    DBGPRINTF(("SOCKET: pathname too long\n"));
-	    RETURN (false);
-	}
-
-	strcpy(sa.un.sun_path, pathName);
-	sa.un.sun_family = AF_UNIX;
-	sockaddr_size = l + sizeof ( sa.un.sun_family );
-	ok = 1;
+        char *pathName;
+        int l;
+
+        if (! __isString(portNrOrName)) {
+            DBGPRINTF(("SOCKET: invalid port (pathname) arg\n"));
+            RETURN (false);
+        }
+        pathName = __stringVal(portNrOrName);
+        l = strlen(pathName);
+        if ((l + sizeof ( sa.un.sun_family )) > sizeof(struct sockaddr_un)) {
+            DBGPRINTF(("SOCKET: pathname too long\n"));
+            RETURN (false);
+        }
+
+        strcpy(sa.un.sun_path, pathName);
+        sa.un.sun_family = AF_UNIX;
+        sockaddr_size = l + sizeof ( sa.un.sun_family );
+        ok = 1;
     }
 # endif
     /*
@@ -1655,30 +1680,30 @@
 # endif
 
     if (! ok) {
-	DBGPRINTF(("SOCKET: unsupported domain\n"));
-	RETURN (false);
+        DBGPRINTF(("SOCKET: unsupported domain\n"));
+        RETURN (false);
     }
 
     sock = fileno(__FILEVal(t));
 
 # ifdef SO_REUSEADDR
     if (reuse == true) {
-	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) {
-	    DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n"));
-	}
+        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) {
+            DBGPRINTF(("SOCKET: setsockopt - SO_REUSEADDR failed\n"));
+        }
     }
 # endif /* SO_REUSEADDR */
 
     __BEGIN_INTERRUPTABLE__
     do {
-	ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size);
+        ret = bind(sock, (struct sockaddr *)&sa, sockaddr_size);
     } while ((ret < 0) && (errno == EINTR));
     __END_INTERRUPTABLE__
 
     if (ret < 0) {
-	DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno));
-	__INST(lastErrorNumber) = __MKSMALLINT(errno);
-	RETURN (false);
+        DBGPRINTF(("SOCKET: bind failed errno=%d\n", errno));
+        __INST(lastErrorNumber) = __MKSMALLINT(errno);
+        RETURN (false);
     }
 
     __INST(port) = portNrOrName; __STORE(self, portNrOrName);
@@ -1696,9 +1721,9 @@
             if (getsockname(sock, (struct sockaddr *)&sa, &sockaddr_size) < 0) {
                 DBGPRINTF(("SOCKET: cannot get peername\n"));
             } else {
-		DBGPRINTF(("SOCKET: anon port=%x\n", sa.in.sin_port));
+                DBGPRINTF(("SOCKET: anon port=%x\n", sa.in.sin_port));
                 p = ntohs(sa.in.sin_port);
-	        __INST(port) = __MKSMALLINT(p);
+                __INST(port) = __MKSMALLINT(p);
             }
         }
     }
@@ -1711,8 +1736,8 @@
 
     "
      (Socket domain:#inet type:#stream)
-	 bindTo:9999
-	 address:nil
+         bindTo:9999
+         address:nil
     "
 !
 
@@ -2722,5 +2747,5 @@
 !Socket class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.80 1997-03-25 08:53:21 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/Socket.st,v 1.81 1997-03-25 09:20:33 cg Exp $'
 ! !