/* $OpenXM: OpenXM/src/kan96xx/plugin/mytcpio.c,v 1.4.2.3 2000/11/11 07:01:19 maekawa Exp $ */ #include #include #include #include #include #include #include /* -lnsl -lsocket /usr/ucblib/libucb.a */ #include "ox_kan.h" /* MyEnv_oxmisc is used in oxmisc.c. It cannot be put in oxmisc.c for the case of sun. */ #if defined(sun) int MyEnv_oxmisc[2000]; #else jmp_buf MyEnv_oxmisc; /* may cause a trouble in Solaris. */ #endif #define READBUFSIZE 10000 static void errorMsg1s(char *s) { fprintf(stderr,"%s\n",s); } #define SET_TCPIOERROR { if (TcpioError == NULL) TcpioError = stdout; } FILE *TcpioError = NULL; int OpenedSocket = 0; extern int Quiet; socketOpen(char *serverName,int portNumber) { struct addrinfo hints, *res, *ai; struct sockaddr_storage ss; socklen_t len; char pstr[BUFSIZ], *errstr; int s, p, opt, error; SET_TCPIOERROR; fprintf(TcpioError, "Hello from open. serverName is %s and " "portnumber is %d\n", serverName, portNumber); memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; memset(pstr, 0, sizeof(pstr)); snprintf(pstr, sizeof(pstr), "%d", portNumber); error = getaddrinfo(serverName, pstr, &hints, &res); if (error) { errorMsg1s("Bad server name."); return (-1); } s = -1; p = -1; errstr = NULL; for (ai = res ; ai != NULL ; ai = ai->ai_next) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { errstr = "socket"; continue; } opt = 1; setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if (bind(s, ai->ai_addr, ai->ai_addrlen) < 0) { errstr = "bind"; close(s); s = -1; continue; } len = sizeof(ss); if (getsockname(s, (struct sockaddr *)&ss, &len) < 0) { errstr = "getsockname"; close(s); s = -1; continue; } switch (ss.ss_family) { case AF_INET: { struct sockaddr_in *sin; sin = (struct sockaddr_in *)&ss; p = ntohs(sin->sin_port); break; } case AF_INET6: { struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)&ss; p = ntohs(sin6->sin6_port); break; } default: p = -1; } if (p < 0) { errstr = "AF"; close(s); s = -1; continue; } if (listen(s, 1) < 0) { errstr = "listen"; close(s); s = -1; continue; } break; } freeaddrinfo(res); if (s < 0) { fprintf(TcpioError, "Error: %s", errstr); errorMsg1s(errstr); } else { OpenedSocket = p; } return (s); } socketAccept(int snum) { int s, news; SET_TCPIOERROR; s = snum; fprintf(TcpioError,"Trying to accept... "); fflush(TcpioError); if ((news = accept(s,NULL,NULL)) < 0) { errorMsg1s("Error in accept."); return(-1); } fprintf(TcpioError,"Accepted.\n"); fflush(TcpioError); if (close(s) < 0) { errorMsg1s("Error in closing the old socket."); return(-1); } return(news); } socketAcceptLocal(int s) { struct sockaddr_storage ss; socklen_t len; int ps, accepted, error; SET_TCPIOERROR; fprintf(TcpioError,"Trying to accept from localhost... "); fflush(TcpioError); len = sizeof(ss); if ((ps = accept(s, (struct sockaddr *)&ss, &len)) < 0) { errorMsg1s("Error in accept."); close(s); return (-1); } len = sizeof(ss); if (getpeername(ps, (struct sockaddr *)&ss, &len) < 0) { close(s); close(ps); errorMsg1s("Error in getpeername."); return (-1); } accepted = 0; switch (ss.ss_family) { case AF_INET: { #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */ #endif /* INADDR_LOOPBACK */ struct sockaddr_in *sin; sin = (struct sockaddr_in *)&ss; if (sin->sin_addr.s_addr == INADDR_LOOPBACK) accepted = 1; break; } case AF_INET6: { struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)&ss; if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) accepted = 1; break; } default: accepted = 0; } if (accepted) { fprintf(stderr, "Authentication: " "localhost is allowed to be accepted.\n"); } else { errorMsg1s("Authentication: " "The connection is not from the localhost."); close(s); close(ps); fprintf(stderr, "The connection is refused."); return (-1); } fprintf(TcpioError, "Accepted.\n"); fflush(TcpioError); if (close(s) < 0) { errorMsg1s("Error in closing the old socket."); close(ps); return(-1); } return(ps); } int oxSocketSelect0(int fd,int t) { fd_set readfds; struct timeval timeout; int debug = 0; extern int errno; SET_TCPIOERROR; FD_ZERO(&readfds); FD_SET(fd,&readfds); timeout.tv_sec = 0; timeout.tv_usec = (long) t; if (t >= 0) { if (debug) {printf("select t>=0 for fd = %d\n",fd); fflush(NULL);} if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) { /* It must be fd+1 !, Not fd. */ fprintf(TcpioError,"select (non-block) error. Error no is %d. See /usr/include/sys/errno.h (asm/errno.h).\n",errno); errorMsg1s("oxSocketSelect0() : select failed."); return(0); } if(debug){printf("Return from select t>=0 for fd = %d\n",fd);fflush(NULL);} }else{ /* block */ if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) { fprintf(TcpioError,"select (block) error. Error no is %d. See /usr/include/sys/errno.h (asm/errno.h).\n",errno); errorMsg1s("socketSelect0() : select failed."); return(0); } } if (FD_ISSET(fd,&readfds)) return(1); else return(0); } oxSocketMultiSelect(int sid[],int size,int t,int result[]) { int i,fd,p; fd_set readfds; struct timeval timeout; int isdata = 0; extern errno; SET_TCPIOERROR; FD_ZERO(&readfds); timeout.tv_sec = 0; timeout.tv_usec = (long)t; fd = 0; for (i=0; i= 0) { p = sid[i]; if (p > fd) fd = p; FD_SET(p,&readfds); /* printf("p = %d, fd=%d",p,fd); */ } } /* printf("MultiSelect..\n"); fflush(NULL); */ if (t >= 0) { if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,&timeout)<0) { /* It must be fd+1 !, Not fd. */ fprintf(TcpioError,"Select error. Error no is %d. See /usr/include/sys/errno.h (asm/errno.h).\n",errno); errorMsg1s("oxSocketMultiSelect() : select failed."); return(0); } }else{ /* block */ if (select(fd+1,&readfds,(fd_set *)NULL,(fd_set *)NULL,(struct timeval *)NULL)<0) { fprintf(TcpioError,"Select error. Error no is %d. See /usr/include/sys/errno.h (asm/errno.h).\n",errno); errorMsg1s("oxSocketMultiSelect() : (block) select failed."); return(0); } } /* printf("Done. MultiSelect.\n"); fflush(NULL); */ for (i=0; i=0) && FD_ISSET(p,&readfds)) { result[i] = 1; isdata = 1; }else{ result[i] = 0; } } return(isdata); } socketConnect(char *serverName,int portNumber) { struct addrinfo hints, *res, *ai; char pstr[BUFSIZ], *errstr; int s, error; SET_TCPIOERROR; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; memset(pstr, 0, sizeof(pstr)); snprintf(pstr, sizeof(pstr), "%d", portNumber); error = getaddrinfo(serverName, pstr, &hints, &res); if (error) { errorMsg1s("bad server name.\n"); return (-1); } s = -1; errstr = NULL; for (ai = res ; ai != NULL ; ai = ai->ai_next) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s < 0) { errstr = "socket"; continue; } if (!Quiet) { fprintf(TcpioError, "Trying to connect %s, port %d\n", serverName, portNumber); } if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) { errstr = "connect"; close(s); s = -1; continue; } } freeaddrinfo(res); if (s < 0) { fprintf(stderr, "Error %s\n", errstr); return (-1); } if (!Quiet) fprintf(TcpioError,"connected.\n"); return (s); } socketConnectWithPass(char *servername,int port,char *pass) { int fd; int m; SET_TCPIOERROR; fd = socketConnect(servername,port); if (fd >= 0) { m = write(fd,pass,strlen(pass)+1); if (m != strlen(pass)+1) { fprintf(TcpioError,"Fail to send password to fd=%d.\n",fd); return(-1); } return(fd); }else{ return(-1); } }