*** unix/tclUnixChan.c 1998/06/01 17:43:54 1.1 --- unix/tclUnixChan.c 1998/07/20 17:22:51 *************** *** 11,20 **** --- 11,23 ---- * * SCCS: @(#) tclUnixChan.c 1.172 96/06/11 10:14:51 */ + static char rcsid[] = "$Header: /local/src/usr.contrib/tcl7.5/unix/RCS/tclUnixChan.c,v 1.2 1998/07/20 17:22:32 pkern Exp $"; #include "tclInt.h" /* Internal definitions for Tcl. */ #include "tclPort.h" /* Portability features for Tcl. */ + #include + /* * This structure describes per-instance state of a pipe based channel. */ *************** *** 1251,1263 **** * value; initialized by caller. */ { TcpState *statePtr; ! struct sockaddr_in sockname; ! struct sockaddr_in peername; struct hostent *hostEntPtr; int sock; ! int size = sizeof(struct sockaddr_in); size_t len = 0; char buf[128]; statePtr = (TcpState *) instanceData; sock = (int) Tcl_GetFileInfo(statePtr->sock, NULL); --- 1254,1270 ---- * value; initialized by caller. */ { TcpState *statePtr; ! struct sockaddr sockname; ! struct sockaddr peername; struct hostent *hostEntPtr; int sock; ! int size = sizeof(struct sockaddr); size_t len = 0; char buf[128]; + struct sockaddr_in *tcpsock; + struct sockaddr_in *tcppeer; + struct sockaddr_un *localsock; + struct sockaddr_un *localpeer; statePtr = (TcpState *) instanceData; sock = (int) Tcl_GetFileInfo(statePtr->sock, NULL); *************** *** 1268,1288 **** if ((len == 0) || ((len > 1) && (optionName[1] == 'p') && (strncmp(optionName, "-peername", len) == 0))) { ! if (getpeername(sock, (struct sockaddr *) &peername, &size) >= 0) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); } ! Tcl_DStringAppendElement(dsPtr, inet_ntoa(peername.sin_addr)); ! hostEntPtr = gethostbyaddr((char *) &(peername.sin_addr), ! sizeof(peername.sin_addr), AF_INET); ! if (hostEntPtr != (struct hostent *) NULL) { ! Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name); ! } else { ! Tcl_DStringAppendElement(dsPtr, inet_ntoa(peername.sin_addr)); ! } ! sprintf(buf, "%d", ntohs(peername.sin_port)); ! Tcl_DStringAppendElement(dsPtr, buf); if (len == 0) { Tcl_DStringEndSublist(dsPtr); } else { --- 1275,1306 ---- if ((len == 0) || ((len > 1) && (optionName[1] == 'p') && (strncmp(optionName, "-peername", len) == 0))) { ! if (getpeername(sock, &peername, &size) >= 0) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); } ! switch (peername.sa_family) { ! case AF_INET: ! tcppeer = &peername; ! Tcl_DStringAppendElement(dsPtr, inet_ntoa(tcppeer->sin_addr)); ! hostEntPtr = gethostbyaddr((char *) &(tcppeer->sin_addr), ! sizeof(tcppeer->sin_addr), AF_INET); ! if (hostEntPtr != (struct hostent *) NULL) { ! Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name); ! } else { ! Tcl_DStringAppendElement(dsPtr, inet_ntoa(tcppeer->sin_addr)); ! } ! sprintf(buf, "%d", ntohs(tcppeer->sin_port)); ! Tcl_DStringAppendElement(dsPtr, buf); ! break; ! case AF_UNIX: ! localpeer = &peername; ! Tcl_DStringAppendElement(dsPtr, localpeer->sun_path); ! break; ! default: ! break; ! } if (len == 0) { Tcl_DStringEndSublist(dsPtr); } else { *************** *** 1294,1314 **** if ((len == 0) || ((len > 1) && (optionName[1] == 's') && (strncmp(optionName, "-sockname", len) == 0))) { ! if (getsockname(sock, (struct sockaddr *) &sockname, &size) >= 0) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } ! Tcl_DStringAppendElement(dsPtr, inet_ntoa(sockname.sin_addr)); ! hostEntPtr = gethostbyaddr((char *) &(sockname.sin_addr), ! sizeof(peername.sin_addr), AF_INET); ! if (hostEntPtr != (struct hostent *) NULL) { ! Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name); ! } else { ! Tcl_DStringAppendElement(dsPtr, inet_ntoa(sockname.sin_addr)); ! } ! sprintf(buf, "%d", ntohs(sockname.sin_port)); ! Tcl_DStringAppendElement(dsPtr, buf); if (len == 0) { Tcl_DStringEndSublist(dsPtr); } else { --- 1312,1343 ---- if ((len == 0) || ((len > 1) && (optionName[1] == 's') && (strncmp(optionName, "-sockname", len) == 0))) { ! if (getsockname(sock, &sockname, &size) >= 0) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } ! switch (sockname.sa_family) { ! case AF_INET: ! tcpsock = &sockname; ! Tcl_DStringAppendElement(dsPtr, inet_ntoa(tcpsock->sin_addr)); ! hostEntPtr = gethostbyaddr((char *) &(tcpsock->sin_addr), ! sizeof(tcpsock->sin_addr), AF_INET); ! if (hostEntPtr != (struct hostent *) NULL) { ! Tcl_DStringAppendElement(dsPtr, hostEntPtr->h_name); ! } else { ! Tcl_DStringAppendElement(dsPtr, inet_ntoa(tcpsock->sin_addr)); ! } ! sprintf(buf, "%d", ntohs(tcpsock->sin_port)); ! Tcl_DStringAppendElement(dsPtr, buf); ! break; ! case AF_UNIX: ! localsock = &sockname; ! Tcl_DStringAppendElement(dsPtr, localsock->sun_path); ! break; ! default: ! break; ! } if (len == 0) { Tcl_DStringEndSublist(dsPtr); } else { *************** *** 1358,1378 **** * do a synchronous connect or bind. */ { int status, sock, asyncConnect, curState, origState; ! struct sockaddr_in sockaddr; /* socket address */ ! struct sockaddr_in mysockaddr; /* Socket address for client */ TcpState *statePtr; sock = -1; origState = 0; ! if (! CreateSocketAddress(&sockaddr, host, port)) { ! goto addressError; } ! if ((myaddr != NULL || myport != 0) && ! ! CreateSocketAddress(&mysockaddr, myaddr, myport)) { goto addressError; } ! sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { goto addressError; } --- 1387,1449 ---- * do a synchronous connect or bind. */ { int status, sock, asyncConnect, curState, origState; ! struct sockaddr_in tcpaddr; /* socket address */ ! struct sockaddr_in mytcpaddr; /* Socket address for client */ TcpState *statePtr; + int sockOptions; + struct sockaddr_un localaddr; /* socket address */ + struct sockaddr_un mylocaladdr; /* Socket address for client */ + struct sockaddr *sockaddr, *mysockaddr; sock = -1; origState = 0; ! sockOptions = SO_REUSEADDR; ! ! if (port < 0 && host != NULL) { ! /* sockOptions = 0; /* */ ! if (strlen(host) >= sizeof(localaddr.sun_path)) { ! errno = E2BIG; /* XXX */ ! goto addressError; ! } ! strcpy(localaddr.sun_path, host); ! localaddr.sun_family = AF_UNIX; ! localaddr.sun_len = sizeof(localaddr.sun_len) + ! strlen(localaddr.sun_path) + 1; ! sockaddr = (struct sockaddr *)&localaddr; } ! else if (! CreateSocketAddress(&tcpaddr, host, port)) { goto addressError; } + else { + tcpaddr.sin_len = sizeof(tcpaddr); + tcpaddr.sin_family = AF_INET; + sockaddr = (struct sockaddr *)&tcpaddr; + } + + if ((myaddr != NULL || myport != 0)) { + if (myport < 0 && myaddr != NULL) { + /* sockOptions = 0; /* */ + if (strlen(myaddr) >= sizeof(mylocaladdr.sun_path)) { + errno = E2BIG; /* XXX */ + goto addressError; + } + strcpy(mylocaladdr.sun_path, myaddr); + mylocaladdr.sun_family = AF_UNIX; + mylocaladdr.sun_len = sizeof(mylocaladdr.sun_len) + + strlen(mylocaladdr.sun_path) + 1; + mysockaddr = (struct sockaddr *)&mylocaladdr; + } + else if (! CreateSocketAddress(&mytcpaddr, myaddr, myport)) { + goto addressError; + } + else { + mytcpaddr.sin_len = sizeof(mytcpaddr); + mytcpaddr.sin_family = AF_INET; + mysockaddr = (struct sockaddr *)&mytcpaddr; + } + } ! sock = socket(sockaddr->sa_family, SOCK_STREAM, 0); if (sock < 0) { goto addressError; } *************** *** 1393,1412 **** */ status = 1; ! (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &status, sizeof(status)); ! status = bind(sock, (struct sockaddr *) &sockaddr, ! sizeof(struct sockaddr)); if (status != -1) { status = listen(sock, TCL_LISTEN_LIMIT); } } else { if (myaddr != NULL || myport != 0) { status = 1; ! (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &status, sizeof(status)); ! status = bind(sock, (struct sockaddr *) &mysockaddr, ! sizeof(struct sockaddr)); if (status < 0) { goto bindError; } --- 1464,1481 ---- */ status = 1; ! (void) setsockopt(sock, SOL_SOCKET, sockOptions, (char *) &status, sizeof(status)); ! status = bind(sock, sockaddr, sockaddr->sa_len); if (status != -1) { status = listen(sock, TCL_LISTEN_LIMIT); } } else { if (myaddr != NULL || myport != 0) { status = 1; ! (void) setsockopt(sock, SOL_SOCKET, sockOptions, (char *) &status, sizeof(status)); ! status = bind(sock, mysockaddr, mysockaddr->sa_len); if (status < 0) { goto bindError; } *************** *** 1427,1434 **** status = 0; } if (status > -1) { ! status = connect(sock, (struct sockaddr *) &sockaddr, ! sizeof(sockaddr)); if (status < 0) { if (errno == EINPROGRESS) { asyncConnect = 1; --- 1496,1502 ---- status = 0; } if (status > -1) { ! status = connect(sock, sockaddr, sockaddr->sa_len); if (status < 0) { if (errno == EINPROGRESS) { asyncConnect = 1;