diff -ruN netris-0.5/Configure netris-0.5-v6-19991206a/Configure --- netris-0.5/Configure Sun May 16 15:57:48 1999 +++ netris-0.5-v6-19991206a/Configure Mon Dec 6 18:53:27 1999 @@ -57,6 +57,12 @@ --curses-hack) CURSES_HACK=true ;; + --disable-ipv6|--enable-ipv6=no) + ENABLE_IPV6=no + ;; + --enable-ipv6) + ENABLE_IPV6=yes + ;; *) cat << "END" Usage: ./Configure [options...] @@ -67,6 +73,7 @@ --cextra : Set extra C flags --lextra : Set extra linker flags --curses-hack: Disable scroll-optimization for broken curses + --enable-ipv6: Enable IPv6 feature END exit 1 ;; @@ -89,6 +96,7 @@ fi done + echo "Checking for on_exit()" cat << END > test.c void handler(void) {} @@ -135,6 +143,45 @@ HAS_MEMORY_H=false fi +if test X"$ENABLE_IPV6" = X""; then + echo "Checking for whether we enable IPv6 feature" + cat << END >test.c +#include +#include +main(){ + if (socket(AF_INET6, SOCK_STREAM, 0) < 0) return(1); + else return(0); +} +END + if $CC $CFLAGS $LEXTRA test.c > /dev/null 2>&1; then + if ./a.out 2>&1; then + ENABLE_IPV6=yes + else + ENABLE_IPV6=no + fi + fi +fi +if test X"$ENABLE_IPV6" = X"yes"; then + echo "Checking for IPv6 library" + CEXTRA="-DINET6 $CEXTRA" + IPV6_ENV="KAME V6 INET6" + IPV6_KAME_DIR=/usr/local/v6 + IPV6_KAME_LIB=inet6 + IPV6_V6_DIR=/usr/local/v6 + IPV6_V6_DIB=v6 + IPV6_INET6_DIR=/usr/inet6 + IPV6_INET6_LIB=inet6 + for i in $IPV6_ENV; do + eval IPV6_DIR=\$IPV6_${i}_DIR + eval IPV6_LIB=\$IPV6_${i}_LIB + if [ -f $IPV6_DIR/lib/lib${IPV6_LIB}.a ]; then + CEXTRA="-I$IPV6_DIR/include $CEXTRA" + LEXTRA="-L$IPV6_DIR/lib -l${IPV6_LIB} $LEXTRA" + break + fi + done +fi + rm -f test.c test.o a.out ORIG_SOURCES="game- curses- shapes- board- util- inet- robot-" @@ -150,10 +197,14 @@ echo > .depend echo "Creating Makefile" -sed -e "s/-LFLAGS-/$LFLAGS/g" -e "s/-SRCS-/$SRCS/g" \ +_LFLAGS=`echo "$LFLAGS" | sed -e 's#/#\\\\/#g'` +_LEXTRA=`echo "$LEXTRA" | sed -e 's#/#\\\\/#g'` +_COPT=`echo "$COPT" | sed -e 's#/#\\\\/#g'` +_CEXTRA=`echo "$CEXTRA" | sed -e 's#/#\\\\/#g'` +sed -e "s/-LFLAGS-/$_LFLAGS/g" -e "s/-SRCS-/$SRCS/g" \ -e "s/-OBJS-/$OBJS/g" -e "s/-DISTFILES-/$DISTFILES/g" \ - -e "s/-COPT-/$COPT/g" -e "s/-CEXTRA-/$CEXTRA/g" \ - -e "s/-LEXTRA-/$LEXTRA/g" -e "s/-CC-/$CC/g" \ + -e "s/-COPT-/$_COPT/g" -e "s/-CEXTRA-/$_CEXTRA/g" \ + -e "s/-LEXTRA-/$_LEXTRA/g" -e "s/-CC-/$CC/g" \ << "END" > Makefile # # Automatically generated by ./Configure -- DO NOT EDIT! @@ -163,15 +214,19 @@ COPT = -COPT- CEXTRA = -CEXTRA- LEXTRA = -LEXTRA- -LFLAGS = -LEXTRA- -LFLAGS- +LFLAGS = $(LEXTRA) -LFLAGS- CFLAGS = $(CEXTRA) $(COPT) PROG = netris HEADERS = netris.h +PREFIX?=/usr/local SRCS = -SRCS- OBJS = -OBJS- DISTFILES = -DISTFILES- +DESTDIR = $(PREFIX)/bin + +INSTALL = install -c all: Makefile config.h proto.h $(PROG) sr @@ -228,6 +283,10 @@ cleandir: clean rm -f .depend Makefile config.h +install: + $(INSTALL) -o bin -g bin -s -m 755 $(PROG) $(DESTDIR) + $(INSTALL) -o bin -g bin -s -m 755 sr $(DESTDIR) + ##### DO NOT EDIT OR DELETE THIS LINE, it's needed by make depend ##### END @@ -256,6 +315,9 @@ fi if [ "$CURSES_HACK" = "true" ]; then echo "#define CURSES_HACK" >> config.h +fi +if [ "$ENABLE_IPV6" = "yes" ]; then + echo "#define ENABLE_IPV6" >> config.h fi echo "Running 'make depend'" diff -ruN netris-0.5/README.v6 netris-0.5-v6-19991206a/README.v6 --- netris-0.5/README.v6 Thu Jan 1 09:00:00 1970 +++ netris-0.5-v6-19991206a/README.v6 Mon Dec 6 19:23:23 1999 @@ -0,0 +1,36 @@ +IPv6 Patch for netris-0.5 + +IPv6 patch for netris is originally developped by H.YOSHIFUJi + in early December 1999. + +IPv6 support is enabled by defining INET6 macro during the +compilation phase. "Configure" will detect and automatically +enable this feature, but you can enable / disable this feature +explicitly with "--enable-ipv6" / "--disable-ipv6" option to +the "Configure" scirpt. + +Note: INET6 switches netris into the protocol independent world, + so you can enable this feature if you have getaddrinfo() + and getnameinfo() defined in RFC2553. + +Note: Netris cannot bind to multiple sockets without FD_ZERO + macro family. In this case, it will bind to the first + socket it finds. You can specify protocol family with + -4 / -6 option to the executable "netris" file. + +The following IPv6 platforms should be supported: + GNU/Linux with glibc-2.1.2 + FreeBSD {2.2.8,3.3} with KAME package + Solaris 7 with IPv6_Prototype_01 package + +Note: On Solaris 7 + IPv6_Prototype_01 systems, you should + register the port number in /etc/services file. + There is "ad hoc" solution, but I hate it because + it looks "dirty"; it discards the pure protocol + independent socket programming model. + +** History ** +netris-0.5-v6-19991206 H.YOSHIFUJI + - First patch. +netric-0.5-v6-19991206a H.YOSHIFUJI + - fix core dump in strncpy(). diff -ruN netris-0.5/game.c netris-0.5-v6-19991206a/game.c --- netris-0.5/game.c Sun May 16 15:57:48 1999 +++ netris-0.5-v6-19991206a/game.c Mon Dec 6 17:53:12 1999 @@ -25,6 +25,7 @@ #include #include #include +#include #include enum { KT_left, KT_rotate, KT_right, KT_drop, KT_down, @@ -358,12 +359,36 @@ { int initConn = 0, waitConn = 0, ch; char *hostStr = NULL, *portStr = NULL; +#ifdef INET6 + int default_ai_family = PF_UNSPEC; +#endif standoutEnable = colorEnable = 1; stepDownInterval = DEFAULT_INTERVAL; MapKeys(DEFAULT_KEYS); - while ((ch = getopt(argc, argv, "hHRs:r:Fk:c:woDSCp:i:")) != -1) + while ((ch = getopt(argc, argv, "hHRs:r:Fk:c:woDSCp:i:" +#ifdef INET6 +#ifdef PF_INET6 + "6" +#endif +#ifdef PF_INET + "4" +#endif +#endif + )) != -1) switch (ch) { +#ifdef INET6 +#ifdef PF_INET6 + case '6': + default_ai_family = PF_INET6; + break; +#endif +#ifdef PF_INET + case '4': + default_ai_family = PF_INET; + break; +#endif +#endif case 'c': initConn = 1; hostStr = optarg; @@ -424,7 +449,11 @@ InitUtil(); if (robotEnable) InitRobot(robotProg); - InitNet(); +#ifdef INET6 + InitNet(default_ai_family); +#else + InitNet(0); +#endif InitScreens(); if (initConn || waitConn) { MyEvent event; diff -ruN netris-0.5/inet.c netris-0.5-v6-19991206a/inet.c --- netris-0.5/inet.c Sun May 16 15:57:48 1999 +++ netris-0.5-v6-19991206a/inet.c Mon Dec 6 19:19:29 1999 @@ -30,9 +30,16 @@ #include #define HEADER_SIZE sizeof(netint2[2]) +#ifdef INET6 +# define MAX_LISTEN_SOCKS 16 +#endif static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event); +#ifdef INET6 +static int Default_Ai_Family = PF_UNSPEC; +static char str_buff[64 + NI_MAXHOST]; +#endif static int sock = -1; static EventGenRec netGen = { NULL, 0, FT_read, -1, NetGenFunc, EM_net }; @@ -40,25 +47,127 @@ static int netBufSize, netBufGoal = HEADER_SIZE; static int isServer, lostConn, gotEndConn; -ExtFunc void InitNet(void) +ExtFunc void InitNet(int default_ai_family) { +#ifdef INET6 + Default_Ai_Family = default_ai_family; +#endif AtExit(CloseNet); } ExtFunc int WaitForConnection(char *portStr) { +#ifdef INET6 + struct sockaddr_storage addr; + struct addrinfo hints,*res0,*res; + int gai; + char serv_buf[NI_MAXSERV]; +#ifdef FD_ZERO + fd_set fdvar; +#endif + int socklistListen[MAX_LISTEN_SOCKS]; + int countSock, maxSock; + int i, sel; +#else struct sockaddr_in addr; struct hostent *host; +#endif int sockListen; int addrLen; +#ifndef INET6 short port; +#endif int val1; struct linger val2; +#ifdef INET6 + if (portStr) + strncpy(serv_buf, portStr, sizeof(serv_buf)); + else + snprintf(serv_buf, sizeof(serv_buf), "%d", DEFAULT_PORT); +#else if (portStr) port = atoi(portStr); /* XXX Error checking */ else port = DEFAULT_PORT; +#endif +#ifdef INET6 + memset(&hints, 0, sizeof(hints)); + hints.ai_family = Default_Ai_Family; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + gai = getaddrinfo(NULL, serv_buf, &hints, &res0); + if (gai){ + snprintf(str_buff, sizeof(str_buff)-1, + "getaddrinfo(): %s", gai_strerror(gai)); + str_buff[sizeof(str_buff)-1] = '\0'; + fatal(str_buff); + } + countSock = 0; + maxSock = -1; +#ifdef FD_ZERO + FD_ZERO(&fdvar); +#endif + for (res=res0; res && (countSock < MAX_LISTEN_SOCKS); res=res->ai_next){ + sockListen = socket(res->ai_family, res->ai_socktype, 0); + if(sockListen < 0) continue; + val1 = 1; + setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR, + (void *)&val1, sizeof(val1)); + if (bind(sockListen, res->ai_addr, res->ai_addrlen) < 0){ + close(sockListen); + continue; + } + if (listen(sockListen, 1) < 0){ + close(sockListen); + continue; + } +#ifdef FD_ZERO + FD_SET(sockListen, &fdvar); +#endif + socklistListen[countSock++] = sockListen; + if (maxSock < sockListen) maxSock = sockListen; +#ifndef FD_ZERO +#warn You do not have FD_ZERO macro, so netris listens only one socket. This should be ok, but you might want to specify the protocol with -6 or -4 option. + if (countSock){ + break; +#endif + } + if (!countSock){ + die("socket(),bind(),listen()"); + } + freeaddrinfo(res0); +#ifdef FD_ZERO + sockListen = -1; + while(sockListen < 0){ + sel = select(maxSock + 1, &fdvar, NULL, NULL, NULL); + if (sel < 0){ + for (i=0; ih_name) { strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1); - opponentHost[sizeof(opponentHost)-1] = 0; } } +#endif + opponentHost[sizeof(opponentHost)-1] = 0; AddEventGen(&netGen); isServer = 1; return 0; @@ -99,36 +219,96 @@ ExtFunc int InitiateConnection(char *hostStr, char *portStr) { +#ifdef INET6 + struct sockaddr_storage; + struct addrinfo hints, *res0, *res; + char serv_buf[NI_MAXSERV]; + int gai; +#else struct sockaddr_in addr; struct hostent *host; short port; - int mySock; +#endif + int mySock = -1; +#ifdef INET6 + if (portStr) + strncpy(serv_buf, portStr, sizeof(serv_buf)); + else + snprintf(serv_buf, sizeof(serv_buf), "%d", + DEFAULT_PORT); +#else if (portStr) port = atoi(portStr); /* XXX Error checking */ else port = DEFAULT_PORT; +#endif +#ifdef INET6 + while (mySock < 0){ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = Default_Ai_Family; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + gai = getaddrinfo(hostStr, serv_buf, &hints, &res0); + if (gai){ + snprintf(str_buff, sizeof(str_buff)-1, + "getaddrinfo(): %s", gai_strerror(gai)); + str_buff[sizeof(str_buff)-1] = '\0'; + fatal(str_buff); + } + for (res=res0; res; res=res->ai_next){ + mySock = socket(res->ai_family, res->ai_socktype, 0); + if (mySock < 0) + continue; + if (connect(mySock, res->ai_addr, res->ai_addrlen) < 0){ + close(mySock); + mySock = -1; + if(errno != ECONNREFUSED){ + freeaddrinfo(res0); + die("connect"); + } + else{ + continue; + } + } + if (res->ai_canonname) + strncpy(opponentHost, res->ai_canonname, sizeof(opponentHost)-1); + else + strncpy(opponentHost, hostStr, sizeof(opponentHost)-1); + opponentHost[sizeof(opponentHost)-1] = 0; + break; + } + if (mySock < 0){ + freeaddrinfo(res0); + sleep(1); + continue; + } + } +#else host = gethostbyname(hostStr); if (!host) die("gethostbyname"); assert(host->h_addrtype == AF_INET); strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1); opponentHost[sizeof(opponentHost)-1] = 0; - again: - memset(&addr, 0, sizeof(addr)); - addr.sin_family = host->h_addrtype; - memcpy(&addr.sin_addr, host->h_addr, host->h_length); - addr.sin_port = htons(port); - mySock = socket(AF_INET, SOCK_STREAM, 0); - if (mySock < 0) - die("socket"); - if (connect(mySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - if (errno != ECONNREFUSED) - die("connect"); - close(mySock); - sleep(1); - goto again; + while (1){ + memset(&addr, 0, sizeof(addr)); + addr.sin_family = host->h_addrtype; + memcpy(&addr.sin_addr, host->h_addr, host->h_length); + addr.sin_port = htons(port); + mySock = socket(AF_INET, SOCK_STREAM, 0); + if (mySock < 0) + die("socket"); + if (connect(mySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (errno != ECONNREFUSED) + die("connect"); + close(mySock); + sleep(1); + continue; + } + break; } +#endif netGen.fd = sock = mySock; AddEventGen(&netGen); return 0; diff -ruN netris-0.5/util.c netris-0.5-v6-19991206a/util.c --- netris-0.5/util.c Sun May 16 15:57:48 1999 +++ netris-0.5-v6-19991206a/util.c Mon Dec 6 18:33:30 1999 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -71,7 +72,19 @@ " -h Print usage information\n" " -w Wait for connection\n" " -c Initiate connection\n" +#ifdef INET6 + " -p Set port number / service name (default is %d)\n" +#else " -p Set port number (default is %d)\n" +#endif +#ifdef INET6 +#ifdef PF_INET6 + " -6 Use only IPv6 socket\n" +#endif +#ifdef PF_INET + " -4 Use only IPv4 socket\n" +#endif +#endif " -k Remap keys. The argument is a prefix of the string\n" " containing the keys in order: left, rotate, right, drop,\n" " down-faster, toggle-spying, pause, faster, redraw.\n"