From 964b5b0f0d67e118e406fbf6973445829a1e14cc Mon Sep 17 00:00:00 2001 From: kzak Date: Tue, 18 Jul 2006 07:21:33 +0000 Subject: [PATCH] IPv6 support --- gawk-3.1.5-ipv6.patch | 299 ++++++++++++++++++++++++++++++++++++++++++ gawk.spec | 8 +- 2 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 gawk-3.1.5-ipv6.patch diff --git a/gawk-3.1.5-ipv6.patch b/gawk-3.1.5-ipv6.patch new file mode 100644 index 0000000..82d8a33 --- /dev/null +++ b/gawk-3.1.5-ipv6.patch @@ -0,0 +1,299 @@ +diff -bru gawk-3.1.5.orig/io.c gawk-3.1.5/io.c +--- gawk-3.1.5.orig/io.c 2006-07-07 16:13:08.000000000 +0200 ++++ gawk-3.1.5/io.c 2006-07-10 13:18:13.000000000 +0200 +@@ -71,7 +71,6 @@ + extern int MRL; + + #ifdef HAVE_SOCKETS +-enum inet_prot { INET_NONE, INET_TCP, INET_UDP, INET_RAW }; + + #ifndef SHUT_RD + #define SHUT_RD 0 +@@ -1133,24 +1132,60 @@ + /* socketopen --- open a socket and set it into connected state */ + + static int +-socketopen(enum inet_prot type, int localport, int remoteport, const char *remotehostname) ++socketopen(int type, const char *localpname, const char *remotepname, ++ const char *remotehostname) + { +- struct hostent *hp = gethostbyname(remotehostname); +- struct sockaddr_in local_addr, remote_addr; ++ struct addrinfo *lres, *lres0; ++ struct addrinfo lhints; ++ struct addrinfo *rres, *rres0; ++ struct addrinfo rhints; ++ ++ int lerror; ++ int rerror; ++ + int socket_fd; + int any_remote_host = strcmp(remotehostname, "0"); + ++ memset (&lhints, '\0', sizeof (lhints)); ++ lhints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; ++ lhints.ai_socktype = type; ++ ++ lerror = getaddrinfo (NULL, localpname, &lhints, &lres); ++ if (lerror) { ++ if (strcmp(localpname, "0")) ++ fatal(_("local port invalid in `/inet'")); ++ lres0 = NULL; ++ lres = &lhints; ++ } else ++ lres0 = lres; ++ ++ while (lres) { ++ memset (&rhints, '\0', sizeof (rhints)); ++ rhints.ai_flags = lhints.ai_flags; ++ rhints.ai_socktype = lhints.ai_socktype; ++ rhints.ai_family = lhints.ai_family; ++ rhints.ai_protocol = lhints.ai_protocol; ++ ++ rerror = getaddrinfo (remotehostname, remotepname, &rhints, &rres); ++ if (rerror) { ++ if (lres0) ++ freeaddrinfo(lres0); ++ fatal(_("remote host and port information invalid")); ++ } ++ rres0 = rres; + socket_fd = INVALID_HANDLE; +- switch (type) { +- case INET_TCP: +- if (localport != 0 || remoteport != 0) { ++ while (rres) { ++ socket_fd = socket (rres->ai_family, ++ rres->ai_socktype, rres->ai_protocol); ++ if (socket_fd < 0 || socket_fd == INVALID_HANDLE) ++ goto nextrres; ++ ++ if (type == SOCK_STREAM) { + int on = 1; + #ifdef SO_LINGER + struct linger linger; +- + memset(& linger, '\0', sizeof(linger)); + #endif +- socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, + (char *) & on, sizeof(on)); + #ifdef SO_LINGER +@@ -1160,57 +1195,27 @@ + (char *) & linger, sizeof(linger)); + #endif + } +- break; +- case INET_UDP: +- if (localport != 0 || remoteport != 0) +- socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); +- break; +- case INET_RAW: +-#ifdef SOCK_RAW +- if (localport == 0 && remoteport == 0) +- socket_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); +-#endif +- break; +- case INET_NONE: +- /* fall through */ +- default: +- cant_happen(); +- break; +- } ++ if (bind(socket_fd, lres->ai_addr, lres->ai_addrlen) != 0) ++ goto nextrres; + +- if (socket_fd < 0 || socket_fd == INVALID_HANDLE +- || (hp == NULL && any_remote_host != 0)) +- return INVALID_HANDLE; +- +- local_addr.sin_family = remote_addr.sin_family = AF_INET; +- local_addr.sin_addr.s_addr = htonl(INADDR_ANY); +- remote_addr.sin_addr.s_addr = htonl(INADDR_ANY); +- local_addr.sin_port = htons(localport); +- remote_addr.sin_port = htons(remoteport); +- if (bind(socket_fd, (struct sockaddr *) &local_addr, sizeof(local_addr)) == 0) { + if (any_remote_host != 0) { /* not ANY => create a client */ +- if (type == INET_TCP || type == INET_UDP) { +- memcpy(&remote_addr.sin_addr, hp->h_addr, +- sizeof(remote_addr.sin_addr)); +- if (connect(socket_fd, +- (struct sockaddr *) &remote_addr, +- sizeof(remote_addr)) != 0) { +- close(socket_fd); +- if (localport == 0) +- socket_fd = INVALID_HANDLE; +- else +- socket_fd = socketopen(type, localport, 0, "0"); +- } ++ if (type != SOCK_RAW) { ++ if (connect(socket_fd, rres->ai_addr, ++ rres->ai_addrlen) == 0) ++ break; + } else { + /* /inet/raw client not ready yet */ + fatal(_("/inet/raw client not ready yet, sorry")); + if (geteuid() != 0) ++ /* FIXME: is this second fatal ever reached? */ + fatal(_("only root may use `/inet/raw'.")); + } + } else { /* remote host is ANY => create a server */ +- if (type == INET_TCP) { ++ if (type == SOCK_STREAM) { + int clientsocket_fd = INVALID_HANDLE; +- socklen_t namelen = sizeof(remote_addr); ++ ++ struct sockaddr_storage remote_addr; ++ socklen_t namelen = sizeof (remote_addr); + + if (listen(socket_fd, 1) >= 0 + && (clientsocket_fd = accept(socket_fd, +@@ -1218,25 +1223,22 @@ + &namelen)) >= 0) { + close(socket_fd); + socket_fd = clientsocket_fd; +- } else { +- close(socket_fd); +- socket_fd = INVALID_HANDLE; ++ break; + } +- } else if (type == INET_UDP) { ++ } else if (type == SOCK_DGRAM) { + #ifdef MSG_PEEK + char buf[10]; ++ struct sockaddr_storage remote_addr; + socklen_t readle; + + if (recvfrom(socket_fd, buf, 1, MSG_PEEK, + (struct sockaddr *) & remote_addr, +- & readle) < 1 +- || readle != sizeof(remote_addr) +- || connect(socket_fd, ++ & readle) >= 0 ++ && readle ++ && connect(socket_fd, + (struct sockaddr *)& remote_addr, +- readle) != 0) { +- close(socket_fd); +- socket_fd = INVALID_HANDLE; +- } ++ readle) == 0) ++ break; + #endif + } else { + /* /inet/raw server not ready yet */ +@@ -1245,10 +1247,20 @@ + fatal(_("only root may use `/inet/raw'.")); + } + } +- } else { ++ ++nextrres: ++ if (socket_fd != INVALID_HANDLE) + close(socket_fd); + socket_fd = INVALID_HANDLE; ++ rres = rres->ai_next; ++ } ++ freeaddrinfo(rres0); ++ if (socket_fd != INVALID_HANDLE) ++ break; ++ lres = lres->ai_next; + } ++ if (lres0) ++ freeaddrinfo(lres0); + + return socket_fd; + } +@@ -1313,30 +1325,24 @@ + } else if (STREQN(name, "/inet/", 6)) { + #ifdef HAVE_SOCKETS + /* /inet/protocol/localport/hostname/remoteport */ +- enum inet_prot protocol = INET_NONE; +- int localport, remoteport; ++ int protocol; + char *hostname; + char *hostnameslastcharp; + char *localpname; +- char proto[4]; +- struct servent *service; ++ char *localpnamelastcharp; + + cp = (char *) name + 6; + /* which protocol? */ + if (STREQN(cp, "tcp/", 4)) +- protocol = INET_TCP; ++ protocol = SOCK_STREAM; + else if (STREQN(cp, "udp/", 4)) +- protocol = INET_UDP; ++ protocol = SOCK_DGRAM; + else if (STREQN(cp, "raw/", 4)) +- protocol = INET_RAW; ++ protocol = SOCK_RAW; + else + fatal(_("no (known) protocol supplied in special filename `%s'"), + name); + +- proto[0] = cp[0]; +- proto[1] = cp[1]; +- proto[2] = cp[2]; +- proto[3] = '\0'; + cp += 4; + + /* which localport? */ +@@ -1354,25 +1360,17 @@ + * By using atoi() the use of decimal numbers is enforced. + */ + *cp = '\0'; +- +- localport = atoi(localpname); +- if (strcmp(localpname, "0") != 0 +- && (localport <= 0 || localport > 65535)) { +- service = getservbyname(localpname, proto); +- if (service == NULL) +- fatal(_("local port invalid in `%s'"), name); +- else +- localport = ntohs(service->s_port); +- } +- *cp = '/'; ++ localpnamelastcharp = cp; + + /* which hostname? */ + cp++; + hostname = cp; + while (*cp != '/' && *cp != '\0') + cp++; +- if (*cp != '/' || cp == hostname) ++ if (*cp != '/' || cp == hostname) { ++ *localpnamelastcharp = '/'; + fatal(_("must supply a remote hostname to `/inet'")); ++ } + *cp = '\0'; + hostnameslastcharp = cp; + +@@ -1386,22 +1384,15 @@ + * Here too, require a port, let them explicitly put 0 if + * they don't care. + */ +- if (*cp == '\0') ++ if (*cp == '\0') { ++ *localpnamelastcharp = '/'; ++ *hostnameslastcharp = '/'; + fatal(_("must supply a remote port to `/inet'")); +- remoteport = atoi(cp); +- if (strcmp(cp, "0") != 0 +- && (remoteport <= 0 || remoteport > 65535)) { +- service = getservbyname(cp, proto); +- if (service == NULL) +- fatal(_("remote port invalid in `%s'"), name); +- else +- remoteport = ntohs(service->s_port); + } + +- /* Open Sesame! */ +- openfd = socketopen(protocol, localport, remoteport, hostname); ++ openfd = socketopen(protocol, localpname, cp, hostname); ++ *localpnamelastcharp = '/'; + *hostnameslastcharp = '/'; +- + #else /* ! HAVE_SOCKETS */ + fatal(_("TCP/IP communications are not supported")); + #endif /* HAVE_SOCKETS */ diff --git a/gawk.spec b/gawk.spec index f56311f..caa5282 100644 --- a/gawk.spec +++ b/gawk.spec @@ -1,7 +1,7 @@ Summary: The GNU version of the awk text processing utility. Name: gawk Version: 3.1.5 -Release: 9.1 +Release: 10 License: GPL Group: Applications/Text Source0: ftp://ftp.gnu.org/gnu/gawk/gawk-%{version}.tar.bz2 @@ -25,6 +25,8 @@ Patch7: gawk-3.1.5-internal.patch Patch8: gawk-3.1.5-syntaxerror.patch # http://lists.gnu.org/archive/html/bug-gnu-utils/2006-07/msg00004.html Patch9: gawk-3.1.5-numflags.patch +# IPv6 support +Patch10: gawk-3.1.5-ipv6.patch %description The gawk packages contains the GNU version of awk, a text processing @@ -45,6 +47,7 @@ considered to be a standard Linux tool for processing text. %patch7 -p1 -b .internal %patch8 -p1 -b .syntaxerror %patch9 -p1 -b .numflag +%patch10 -p1 -b .ipv6 %build %configure @@ -93,6 +96,9 @@ fi %{_datadir}/awk %changelog +* Tue Jul 18 2006 Karel Zak 3.1.5-10 +- add IPv6 support (patch be Jan Pazdziora) + * Wed Jul 12 2006 Jesse Keating - 3.1.5-9.1 - rebuild