IPv6 support

This commit is contained in:
kzak 2006-07-18 07:21:33 +00:00
parent 27331ff5ec
commit 964b5b0f0d
2 changed files with 306 additions and 1 deletions

299
gawk-3.1.5-ipv6.patch Normal file
View File

@ -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 */

View File

@ -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 <kzak@redhat.com> 3.1.5-10
- add IPv6 support (patch be Jan Pazdziora)
* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 3.1.5-9.1
- rebuild