teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone

Blame rpm-4.4.2-rpmio-ipv6.patch

Paul Nasrat 9e992c
--- rpm-4.4.2/configure.ac.ipv6	2006-07-05 10:06:54.000000000 -0400
Paul Nasrat 9e992c
+++ rpm-4.4.2/configure.ac	2006-07-05 10:07:00.000000000 -0400
Paul Nasrat 9e992c
@@ -858,7 +858,8 @@
Paul Nasrat 9e992c
 dnl XXX AC_FUNC_FORK([])
Paul Nasrat 9e992c
 dnl XXX AC_CHECK_FUNCS(gethostname mkdir mkfifo rmdir select uname)
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
-AC_CHECK_FUNCS(basename getcwd getwd inet_aton mtrace putenv realpath setenv)
Paul Nasrat 9e992c
+AC_CHECK_FUNCS(basename getaddrinfo getcwd getnameinfo getwd inet_aton)
Paul Nasrat 9e992c
+AC_CHECK_FUNCS(mtrace putenv realpath setenv)
Paul Nasrat 9e992c
 AC_CHECK_FUNCS(stpcpy stpncpy strcspn)
Paul Nasrat 9e992c
 AC_CHECK_FUNCS(strdup strndup strerror strtol strtoul strspn strstr)
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
--- rpm-4.4.2/rpmio/rpmio.c.ipv6	2005-01-25 22:39:58.000000000 -0500
Paul Nasrat 9e992c
+++ rpm-4.4.2/rpmio/rpmio.c	2006-07-05 10:04:15.000000000 -0400
Paul Nasrat 9e992c
@@ -9,6 +9,10 @@
Paul Nasrat 9e992c
 # include <machine/types.h>
Paul Nasrat 9e992c
 #endif
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
+#if HAVE_SYS_SOCKET_H
Paul Nasrat 9e992c
+# include <sys/socket.h>
Paul Nasrat 9e992c
+#endif
Paul Nasrat 9e992c
+
Paul Nasrat 9e992c
 #include <netinet/in.h>
Paul Nasrat 9e992c
 #include <arpa/inet.h>		/* XXX for inet_aton and HP-UX */
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
@@ -750,6 +754,7 @@
Paul Nasrat 9e992c
     return retstr;
Paul Nasrat 9e992c
 }
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
+#if !defined(HAVE_GETADDRINFO)
Paul Nasrat 9e992c
 #if !defined(USE_ALT_DNS) || !USE_ALT_DNS 
Paul Nasrat 9e992c
 static int mygethostbyname(const char * host,
Paul Nasrat 9e992c
 		/*@out@*/ struct in_addr * address)
Paul Nasrat 9e992c
@@ -800,14 +805,50 @@
Paul Nasrat 9e992c
 }
Paul Nasrat 9e992c
 /*@=compdef@*/
Paul Nasrat 9e992c
 /*@=boundsread@*/
Paul Nasrat 9e992c
+#endif
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
 static int tcpConnect(FD_t ctrl, const char * host, int port)
Paul Nasrat 9e992c
 	/*@globals h_errno, fileSystem, internalState @*/
Paul Nasrat 9e992c
 	/*@modifies ctrl, fileSystem, internalState @*/
Paul Nasrat 9e992c
 {
Paul Nasrat 9e992c
-    struct sockaddr_in sin;
Paul Nasrat 9e992c
     int fdno = -1;
Paul Nasrat 9e992c
     int rc;
Paul Nasrat 9e992c
+#ifdef	HAVE_GETADDRINFO
Paul Nasrat 9e992c
+    struct addrinfo hints, *res, *res0;
Paul Nasrat 9e992c
+    char pbuf[NI_MAXSERV];
Paul Nasrat 9e992c
+
Paul Nasrat 9e992c
+    memset(&hints, 0, sizeof(hints));
Paul Nasrat 9e992c
+    hints.ai_family = AF_UNSPEC;
Paul Nasrat 9e992c
+    hints.ai_socktype = SOCK_STREAM;
Paul Nasrat 9e992c
+    sprintf(pbuf, "%d", port);
Paul Nasrat 9e992c
+    pbuf[sizeof(pbuf)-1] = '\0';
Paul Nasrat 9e992c
+    rc = FTPERR_FAILED_CONNECT;
Paul Nasrat 9e992c
+    if (getaddrinfo(host, pbuf, &hints, &res0) == 0) {
Paul Nasrat 9e992c
+	for (res = res0; res != NULL; res= res->ai_next) {
Paul Nasrat 9e992c
+	    if ((fdno = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
Paul Nasrat 9e992c
+		continue;
Paul Nasrat 9e992c
+	    if (connect(fdno, res->ai_addr, res->ai_addrlen) < 0) {
Paul Nasrat 9e992c
+		close(fdno);
Paul Nasrat 9e992c
+		continue;
Paul Nasrat 9e992c
+	    }
Paul Nasrat 9e992c
+	    /* success */
Paul Nasrat 9e992c
+	    rc = 0;
Paul Nasrat 9e992c
+	    if (_ftp_debug) {
Paul Nasrat 9e992c
+		char hbuf[NI_MAXHOST];
Paul Nasrat 9e992c
+		getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
Paul Nasrat 9e992c
+				NULL, 0, NI_NUMERICHOST);
Paul Nasrat 9e992c
+		fprintf(stderr,"++ connect [%s]:%d on fdno %d\n",
Paul Nasrat 9e992c
+				/*@-unrecog@*/ hbuf /*@=unrecog@*/, port, fdno);
Paul Nasrat 9e992c
+	    }
Paul Nasrat 9e992c
+	    break;
Paul Nasrat 9e992c
+	}
Paul Nasrat 9e992c
+	freeaddrinfo(res0);
Paul Nasrat 9e992c
+    }
Paul Nasrat 9e992c
+    if (rc < 0)
Paul Nasrat 9e992c
+	goto errxit;
Paul Nasrat 9e992c
+
Paul Nasrat 9e992c
+#else	/* HAVE_GETADDRINFO */			    
Paul Nasrat 9e992c
+    struct sockaddr_in sin;
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
 /*@-boundswrite@*/
Paul Nasrat 9e992c
     memset(&sin, 0, sizeof(sin));
Paul Nasrat 9e992c
@@ -842,6 +883,7 @@
Paul Nasrat 9e992c
 inet_ntoa(sin.sin_addr)
Paul Nasrat 9e992c
 /*@=unrecog =moduncon =evalorderuncon @*/ ,
Paul Nasrat 9e992c
 (int)ntohs(sin.sin_port), fdno);
Paul Nasrat 9e992c
+#endif	/* HAVE_GETADDRINFO */
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
     fdSetFdno(ctrl, (fdno >= 0 ? fdno : -1));
Paul Nasrat 9e992c
     return 0;
Paul Nasrat 9e992c
@@ -1174,12 +1216,17 @@
Paul Nasrat 9e992c
 int ftpReq(FD_t data, const char * ftpCmd, const char * ftpArg)
Paul Nasrat 9e992c
 {
Paul Nasrat 9e992c
     urlinfo u = data->url;
Paul Nasrat 9e992c
+#if !defined(HAVE_GETADDRINFO)
Paul Nasrat 9e992c
     struct sockaddr_in dataAddress;
Paul Nasrat 9e992c
+#endif	/* HAVE_GETADDRINFO */
Paul Nasrat 9e992c
+    char remoteIP[NI_MAXHOST];
Paul Nasrat 9e992c
     char * cmd;
Paul Nasrat 9e992c
     int cmdlen;
Paul Nasrat 9e992c
     char * passReply;
Paul Nasrat 9e992c
     char * chptr;
Paul Nasrat 9e992c
     int rc;
Paul Nasrat 9e992c
+    int epsv;
Paul Nasrat 9e992c
+    int port;
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
 /*@-boundswrite@*/
Paul Nasrat 9e992c
     URLSANE(u);
Paul Nasrat 9e992c
@@ -1214,8 +1261,35 @@
Paul Nasrat 9e992c
 	data->contentLength = cl;
Paul Nasrat 9e992c
     }
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
+    epsv = 0;
Paul Nasrat 9e992c
     passReply = NULL;
Paul Nasrat 9e992c
-    rc = ftpCommand(u, &passReply, "PASV", NULL);
Paul Nasrat 9e992c
+#ifdef HAVE_GETNAMEINFO
Paul Nasrat 9e992c
+    rc = ftpCommand(u, &passReply, "EPSV", NULL);
Paul Nasrat 9e992c
+    if (rc==0) {
Paul Nasrat 9e992c
+#ifdef HAVE_GETADDRINFO
Paul Nasrat 9e992c
+	struct sockaddr_storage ss;
Paul Nasrat 9e992c
+#else /* HAVE_GETADDRINFO */
Paul Nasrat 9e992c
+	struct sockaddr_in ss;
Paul Nasrat 9e992c
+#endif /* HAVE_GETADDRINFO */
Paul Nasrat 9e992c
+	int size;
Paul Nasrat 9e992c
+	/* we need to know IP of remote host */
Paul Nasrat 9e992c
+	size=sizeof(ss);
Paul Nasrat 9e992c
+	if ((getpeername(fdFileno(c2f(u->ctrl)), (struct sockaddr *)&ss, &size) == 0) &&
Paul Nasrat 9e992c
+			(getnameinfo((struct sockaddr *)&ss, size, remoteIP, sizeof(remoteIP),
Paul Nasrat 9e992c
+				NULL, 0, NI_NUMERICHOST) == 0))
Paul Nasrat 9e992c
+		epsv++;
Paul Nasrat 9e992c
+	else {
Paul Nasrat 9e992c
+		/* abort EPSV and fall back to PASV */
Paul Nasrat 9e992c
+		rc = ftpCommand(u, &passReply, "ABOR", NULL);
Paul Nasrat 9e992c
+		if (rc) {
Paul Nasrat 9e992c
+		    rc = FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
+		    goto errxit;
Paul Nasrat 9e992c
+		}
Paul Nasrat 9e992c
+	}
Paul Nasrat 9e992c
+    }
Paul Nasrat 9e992c
+    if (epsv==0)
Paul Nasrat 9e992c
+#endif /* HAVE_GETNAMEINFO */
Paul Nasrat 9e992c
+        rc = ftpCommand(u, &passReply, "PASV", NULL);
Paul Nasrat 9e992c
     if (rc) {
Paul Nasrat 9e992c
 	rc = FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
 	goto errxit;
Paul Nasrat 9e992c
@@ -1230,6 +1304,15 @@
Paul Nasrat 9e992c
     if (*chptr != ')') return FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
     *chptr-- = '\0';
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
+    if (epsv) {
Paul Nasrat 9e992c
+	int i;
Paul Nasrat 9e992c
+        if(sscanf(passReply,"%*c%*c%*c%d%*c",&i) != 1) {
Paul Nasrat 9e992c
+	   rc = FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
+	   goto errxit;
Paul Nasrat 9e992c
+	}
Paul Nasrat 9e992c
+	port = i;
Paul Nasrat 9e992c
+    } else {
Paul Nasrat 9e992c
+ 
Paul Nasrat 9e992c
     while (*chptr && *chptr != ',') chptr--;
Paul Nasrat 9e992c
     if (*chptr != ',') return FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
     chptr--;
Paul Nasrat 9e992c
@@ -1241,13 +1324,11 @@
Paul Nasrat 9e992c
        port number portion */
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
     {	int i, j;
Paul Nasrat 9e992c
-	memset(&dataAddress, 0, sizeof(dataAddress));
Paul Nasrat 9e992c
-	dataAddress.sin_family = AF_INET;
Paul Nasrat 9e992c
 	if (sscanf(chptr, "%d,%d", &i, &j) != 2) {
Paul Nasrat 9e992c
 	    rc = FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
 	    goto errxit;
Paul Nasrat 9e992c
 	}
Paul Nasrat 9e992c
-	dataAddress.sin_port = htons((((unsigned)i) << 8) + j);
Paul Nasrat 9e992c
+	port = (((unsigned)i) << 8) + j;
Paul Nasrat 9e992c
     }
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
     chptr = passReply;
Paul Nasrat 9e992c
@@ -1255,9 +1336,75 @@
Paul Nasrat 9e992c
 	if (*chptr == ',') *chptr = '.';
Paul Nasrat 9e992c
     }
Paul Nasrat 9e992c
 /*@=boundswrite@*/
Paul Nasrat 9e992c
+    sprintf(remoteIP, "%s", passReply);
Paul Nasrat 9e992c
+    } /* if (epsv) */
Paul Nasrat 9e992c
+
Paul Nasrat 9e992c
+#ifdef HAVE_GETADDRINFO
Paul Nasrat 9e992c
+    {
Paul Nasrat 9e992c
+        struct addrinfo hints, *res, *res0;
Paul Nasrat 9e992c
+	char pbuf[NI_MAXSERV];
Paul Nasrat 9e992c
+
Paul Nasrat 9e992c
+	memset(&hints, 0, sizeof(hints));
Paul Nasrat 9e992c
+	hints.ai_family = AF_UNSPEC;
Paul Nasrat 9e992c
+	hints.ai_socktype = SOCK_STREAM;
Paul Nasrat 9e992c
+	hints.ai_flags = AI_NUMERICHOST;
Paul Nasrat 9e992c
+	sprintf(pbuf, "%d", port);
Paul Nasrat 9e992c
+	pbuf[sizeof(pbuf)-1] = '\0';
Paul Nasrat 9e992c
+	if (getaddrinfo(remoteIP, pbuf, &hints, &res0)) {
Paul Nasrat 9e992c
+	    rc = FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
+	    goto errxit;
Paul Nasrat 9e992c
+	}
Paul Nasrat 9e992c
+
Paul Nasrat 9e992c
+	for (res = res0; res != NULL; res = res->ai_next) {
Paul Nasrat 9e992c
+	    rc = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
Paul Nasrat 9e992c
+	    fdSetFdno(data, (rc >= 0 ? rc : -1));
Paul Nasrat 9e992c
+	    if (rc < 0) {
Paul Nasrat 9e992c
+	        if (res->ai_next)
Paul Nasrat 9e992c
+		    continue;
Paul Nasrat 9e992c
+		else {
Paul Nasrat 9e992c
+		    rc = FTPERR_FAILED_CONNECT;
Paul Nasrat 9e992c
+		    freeaddrinfo(res0);
Paul Nasrat 9e992c
+		    goto errxit;
Paul Nasrat 9e992c
+		}
Paul Nasrat 9e992c
+	    }
Paul Nasrat 9e992c
+	    data = fdLink(data, "open data (ftpReq)");
Paul Nasrat 9e992c
+
Paul Nasrat 9e992c
+	    /* XXX setsockopt SO_LINGER */
Paul Nasrat 9e992c
+	    /* XXX setsockopt SO_KEEPALIVE */
Paul Nasrat 9e992c
+	    /* XXX setsockopt SO_TOS IPTOS_THROUGHPUT */
Paul Nasrat 9e992c
+	    
Paul Nasrat 9e992c
+	    {
Paul Nasrat 9e992c
+		int criterr = 0;
Paul Nasrat 9e992c
+	        while (connect(fdFileno(data), res->ai_addr, res->ai_addrlen) < 0) {
Paul Nasrat 9e992c
+	            if (errno == EINTR)
Paul Nasrat 9e992c
+		        continue;
Paul Nasrat 9e992c
+		    criterr++;
Paul Nasrat 9e992c
+		}
Paul Nasrat 9e992c
+		if (criterr) {
Paul Nasrat 9e992c
+		    if (res->ai_addr) {
Paul Nasrat 9e992c
+		        fdClose(data);
Paul Nasrat 9e992c
+		        continue;
Paul Nasrat 9e992c
+		    } else {
Paul Nasrat 9e992c
+		        rc = FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
+		        freeaddrinfo(res0);
Paul Nasrat 9e992c
+		        goto errxit;
Paul Nasrat 9e992c
+		    }
Paul Nasrat 9e992c
+		}
Paul Nasrat 9e992c
+	    }
Paul Nasrat 9e992c
+	    /* success */
Paul Nasrat 9e992c
+	    rc = 0;
Paul Nasrat 9e992c
+	    break;
Paul Nasrat 9e992c
+	}
Paul Nasrat 9e992c
+	freeaddrinfo(res0);
Paul Nasrat 9e992c
+    }
Paul Nasrat 9e992c
+	    
Paul Nasrat 9e992c
+#else /* HAVE_GETADDRINFO */
Paul Nasrat 9e992c
+    memset(&dataAddress, 0, sizeof(dataAddress));
Paul Nasrat 9e992c
+    dataAddress.sin_family = AF_INET;
Paul Nasrat 9e992c
+    dataAddress.sin_port = htons(port);
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
     /*@-moduncon@*/
Paul Nasrat 9e992c
-    if (!inet_aton(passReply, &dataAddress.sin_addr)) {
Paul Nasrat 9e992c
+    if (!inet_aton(remoteIP, &dataAddress.sin_addr)) {
Paul Nasrat 9e992c
 	rc = FTPERR_PASSIVE_ERROR;
Paul Nasrat 9e992c
 	goto errxit;
Paul Nasrat 9e992c
     }
Paul Nasrat 9e992c
@@ -1285,6 +1432,7 @@
Paul Nasrat 9e992c
 	goto errxit;
Paul Nasrat 9e992c
     }
Paul Nasrat 9e992c
     /*@=internalglobs@*/
Paul Nasrat 9e992c
+#endif /* HAVE_GETADDRINFO */
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
 if (_ftp_debug)
Paul Nasrat 9e992c
 fprintf(stderr, "-> %s", cmd);
Paul Nasrat 9e992c
@@ -1598,6 +1746,7 @@
Paul Nasrat 9e992c
     urlinfo u;
Paul Nasrat 9e992c
     const char * host;
Paul Nasrat 9e992c
     const char * path;
Paul Nasrat 9e992c
+    char hthost[NI_MAXHOST];
Paul Nasrat 9e992c
     int port;
Paul Nasrat 9e992c
     int rc;
Paul Nasrat 9e992c
     char * req;
Paul Nasrat 9e992c
@@ -1610,6 +1759,10 @@
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
     if (((host = (u->proxyh ? u->proxyh : u->host)) == NULL))
Paul Nasrat 9e992c
 	return FTPERR_BAD_HOSTNAME;
Paul Nasrat 9e992c
+    if (strchr(host, ':'))
Paul Nasrat 9e992c
+	sprintf(hthost, "[%s]", host);
Paul Nasrat 9e992c
+    else
Paul Nasrat 9e992c
+	strcpy(hthost, host);
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
     if ((port = (u->proxyp > 0 ? u->proxyp : u->port)) < 0) port = 80;
Paul Nasrat 9e992c
     path = (u->proxyh || u->proxyp > 0) ? u->url : httpArg;
Paul Nasrat 9e992c
@@ -1639,7 +1792,7 @@
Paul Nasrat 9e992c
 Accept: text/plain\r\n\
Paul Nasrat 9e992c
 Transfer-Encoding: chunked\r\n\
Paul Nasrat 9e992c
 \r\n\
Paul Nasrat 9e992c
-") + strlen(httpCmd) + strlen(path) + sizeof(VERSION) + strlen(host) + 20;
Paul Nasrat 9e992c
+") + strlen(httpCmd) + strlen(path) + sizeof(VERSION) + strlen(hthost) + 20;
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
 /*@-boundswrite@*/
Paul Nasrat 9e992c
     req = alloca(len);
Paul Nasrat 9e992c
@@ -1653,7 +1806,7 @@
Paul Nasrat 9e992c
 Accept: text/plain\r\n\
Paul Nasrat 9e992c
 Transfer-Encoding: chunked\r\n\
Paul Nasrat 9e992c
 \r\n\
Paul Nasrat 9e992c
-",	httpCmd, path, (u->httpVersion ? 1 : 0), VERSION, host, port);
Paul Nasrat 9e992c
+",	httpCmd, path, (u->httpVersion ? 1 : 0), VERSION, hthost, port);
Paul Nasrat 9e992c
 } else {
Paul Nasrat 9e992c
     sprintf(req, "\
Paul Nasrat 9e992c
 %s %s HTTP/1.%d\r\n\
Paul Nasrat 9e992c
@@ -1661,7 +1814,7 @@
Paul Nasrat 9e992c
 Host: %s:%d\r\n\
Paul Nasrat 9e992c
 Accept: text/plain\r\n\
Paul Nasrat 9e992c
 \r\n\
Paul Nasrat 9e992c
-",	httpCmd, path, (u->httpVersion ? 1 : 0), VERSION, host, port);
Paul Nasrat 9e992c
+",	httpCmd, path, (u->httpVersion ? 1 : 0), VERSION, hthost, port);
Paul Nasrat 9e992c
 }
Paul Nasrat 9e992c
 /*@=boundswrite@*/
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
--- rpm-4.4.2/rpmio/url.c.ipv6	2004-11-28 15:41:31.000000000 -0500
Paul Nasrat 9e992c
+++ rpm-4.4.2/rpmio/url.c	2006-07-05 10:04:15.000000000 -0400
Paul Nasrat 9e992c
@@ -431,6 +431,8 @@
Paul Nasrat 9e992c
 /*
Paul Nasrat 9e992c
  * Split URL into components. The URL can look like
Paul Nasrat 9e992c
  *	scheme://user:password@host:port/path
Paul Nasrat 9e992c
+  * or as in RFC2732 for IPv6 address
Paul Nasrat 9e992c
+  *    service://user:password@[ip:v6:ad:dr:es:s]:port/path
Paul Nasrat 9e992c
  */
Paul Nasrat 9e992c
 /*@-bounds@*/
Paul Nasrat 9e992c
 /*@-modfilesys@*/
Paul Nasrat 9e992c
@@ -487,8 +489,14 @@
Paul Nasrat 9e992c
     }
Paul Nasrat 9e992c
     /*@=branchstate@*/
Paul Nasrat 9e992c
 
Paul Nasrat 9e992c
-    /* Look for ...host:port */
Paul Nasrat 9e992c
+    /* Look for ...host:port or [v6addr]:port*/
Paul Nasrat 9e992c
     fe = f = s;
Paul Nasrat 9e992c
+    if (strchr(fe, '[') && strchr(fe, ']'))
Paul Nasrat 9e992c
+    {
Paul Nasrat 9e992c
+	    fe = strchr(f, ']');
Paul Nasrat 9e992c
+	    *f++ = '\0';
Paul Nasrat 9e992c
+	    *fe++ = '\0';
Paul Nasrat 9e992c
+    }
Paul Nasrat 9e992c
     while (*fe && *fe != ':') fe++;
Paul Nasrat 9e992c
     if (*fe == ':') {
Paul Nasrat 9e992c
 	*fe++ = '\0';