=================================================================== RCS file: /home/cvs/OpenXM/src/kan96xx/plugin/mytcpio.c,v retrieving revision 1.2 retrieving revision 1.4.2.1 diff -u -p -r1.2 -r1.4.2.1 --- OpenXM/src/kan96xx/plugin/mytcpio.c 1999/10/30 02:22:16 1.2 +++ OpenXM/src/kan96xx/plugin/mytcpio.c 2000/11/10 20:12:08 1.4.2.1 @@ -1,4 +1,4 @@ -/* $OpenXM$ */ +/* $OpenXM: OpenXM/src/kan96xx/plugin/mytcpio.c,v 1.4 2000/09/08 16:08:42 takayama Exp $ */ #include #include #include @@ -23,64 +23,116 @@ static void errorMsg1s(char *s) { fprintf(stderr,"%s\n",s); } -FILE *TcpioError = stdout; +#define SET_TCPIOERROR { if (TcpioError == NULL) TcpioError = stdout; } +FILE *TcpioError = NULL; int OpenedSocket = 0; extern int Quiet; socketOpen(char *serverName,int portNumber) { - static struct hostent *myhost; - static struct sockaddr_in me; - static int s_waiting; - static int on; - extern int errno; - int tt; + 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); - fprintf(TcpioError,"Hello from open. serverName is %s and portnumber is %d\n", - serverName,portNumber); - if ((myhost = gethostbyname(serverName)) == NULL) { - errorMsg1s("Bad server name."); - return(-1); - } - bzero((char *)&me,sizeof(me)); - me.sin_family = AF_INET; - me.sin_port = htons(portNumber); - bcopy(myhost->h_addr, - &me.sin_addr,myhost->h_length); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - if ((s_waiting = socket(AF_INET,SOCK_STREAM,0)) < 0) { - errorMsg1s("Socket allocation is failed."); - return(-1); - } + memset(pstr, 0, sizeof(pstr)); + snprintf(pstr, sizeof(pstr), "%u", portNumber); - on=1; setsockopt(s_waiting,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); - /* important */ - if ((tt = bind(s_waiting,(struct sockaddr *) &me,sizeof(me))) == -1) { - fprintf(TcpioError,"Bind error. Error no is %d. See /usr/include/sys/errno.h. (asm/errno.h)\n",errno); - errorMsg1s("cannot bind"); - return(-1); - } - /* printf("bind returns %d\n",tt); */ - tt = sizeof(me); - if (getsockname(s_waiting,(struct sockaddr *)&me,&tt) < 0) { - fprintf(TcpioError,"getsockname error. Error no is %d. See /usr/include/sys/errno.h (asm/errno.h).\n",errno); - errorMsg1s("cannot getsockname"); - return(-1); - } + error = getaddrinfo(serverName, pstr, &hints, &res); + if (error) { + errorMsg1s("Bad server name."); + return (-1); + } - if (listen(s_waiting,1) < 0) { - errorMsg1s("Listen failed"); - return(-1); - } - fprintf(TcpioError,"Done the initialization. port =%d\n",ntohs(me.sin_port)); - OpenedSocket = ntohs(me.sin_port); - return(s_waiting); + 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) { @@ -97,34 +149,37 @@ socketAccept(int snum) { socketAcceptLocal(int snum) { int s, news; - struct sockaddr peer; + struct sockaddr_storage ss; int len; int i; - + + SET_TCPIOERROR; s = snum; fprintf(TcpioError,"Trying to accept from localhost... "); fflush(TcpioError); - len = sizeof(struct sockaddr); - if ((news = accept(s,&peer,&len)) < 0) { + len = sizeof(ss); + if ((news = accept(s, (struct sockaddr *)&ss,&len)) < 0) { errorMsg1s("Error in accept."); return(-1); } - len = sizeof(struct sockaddr); - getpeername(news,&peer,&len); + len = sizeof(ss); + getpeername(news, (struct sockaddr *)&ss,&len); +#if 0 printf("len= %d\n",len); for (i=0; i= 0) { m = write(fd,pass,strlen(pass)+1);