summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Src/Modules/tcp.c141
-rw-r--r--Src/Modules/tcp.mdd3
-rw-r--r--Src/Modules/zftp.c32
-rw-r--r--Src/Modules/zftp.mdd2
-rw-r--r--configure.ac2
6 files changed, 58 insertions, 128 deletions
diff --git a/ChangeLog b/ChangeLog
index eb67ec1cb..3eaab955f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-07-12  Clint Adams  <clint@zsh.org>
+
+	* 23670: Src/Modules/tcp.c, Src/Modules/tcp.mdd,
+	Src/Modules/zftp.c, Src/Modules/zftp.mdd, configure.ac: use
+	getaddrinfo() and getnameinfo() instead of get*by* functions.
+
 2007-07-06  Clint Adams  <clint@zsh.org>
 
 	* 23666: Completion/Debian/Type/_deb_packages:
diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c
index d1d4e5002..847bb6fc5 100644
--- a/Src/Modules/tcp.c
+++ b/Src/Modules/tcp.c
@@ -135,79 +135,6 @@ zsh_inet_pton(int af, char const *src, void *dst)
 /**/
 #endif /* !HAVE_INET_PTON */
 
-/**/
-#ifndef HAVE_GETIPNODEBYNAME
-
-/**/
-# ifndef HAVE_GETHOSTBYNAME2
-
-/**/
-mod_export struct hostent *
-zsh_gethostbyname2(char const *name, int af)
-{
-    if (af != AF_INET) {
-	h_errno = NO_RECOVERY;
-	return NULL;
-    }
-    return gethostbyname(name);
-}
-
-/**/
-#else /* !HAVE_GETHOSTBYNAME2 */
-
-/**/
-# define zsh_gethostbyname2 gethostbyname2
-
-/**/
-# endif /* !HAVE_GETHOSTBYNAME2 */
-
-/* note: this is not a complete implementation.  If ignores the flags,
-   and does not provide the memory allocation of the standard interface.
-   Each returned structure will overwrite the previous one. */
-
-/**/
-mod_export struct hostent *
-zsh_getipnodebyname(char const *name, int af, UNUSED(int flags), int *errorp)
-{
-    static struct hostent ahe;
-    static char nbuf[16];
-    static char *addrlist[] = { nbuf, NULL };
-# ifdef SUPPORT_IPV6
-    static char pbuf[INET6_ADDRSTRLEN];
-# else
-    static char pbuf[INET_ADDRSTRLEN];
-# endif
-    struct hostent *he;
-    if (zsh_inet_pton(af, name, nbuf) == 1) {
-	zsh_inet_ntop(af, nbuf, pbuf, sizeof(pbuf));
-	ahe.h_name = pbuf;
-	ahe.h_aliases = addrlist+1;
-	ahe.h_addrtype = af;
-	ahe.h_length = (af == AF_INET) ? 4 : 16;
-	ahe.h_addr_list = addrlist;
-	return &ahe;
-    }
-    he = zsh_gethostbyname2(name, af);
-    if (!he)
-	*errorp = h_errno;
-    return he;
-}
-
-/**/
-mod_export void
-freehostent(UNUSED(struct hostent *ptr))
-{
-}
-
-/**/
-#else /* !HAVE_GETIPNODEBYNAME */
-
-/**/
-# define zsh_getipnodebyname getipnodebyname
-
-/**/
-#endif /* !HAVE_GETIPNODEBYNAME */
-
 LinkList ztcp_sessions;
 
 /* "allocate" a tcp_session */
@@ -311,25 +238,23 @@ tcp_close(Tcp_session sess)
 
 /**/
 mod_export int
-tcp_connect(Tcp_session sess, char *addrp, struct hostent *zhost, int d_port)
+tcp_connect(Tcp_session sess, struct addrinfo *zai)
 {
     int salen;
 #ifdef SUPPORT_IPV6
-    if (zhost->h_addrtype==AF_INET6) {
-	memcpy(&(sess->peer.in6.sin6_addr), addrp, zhost->h_length);
-	sess->peer.in6.sin6_port = d_port;
+    if (zai->ai_family==AF_INET6) {
+	memcpy(&(sess->peer.in6.sin6_addr), zai->ai_addr, zai->ai_addrlen);
 	sess->peer.in6.sin6_flowinfo = 0;
 # ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
 	sess->peer.in6.sin6_scope_id = 0;
 # endif
-	sess->peer.in6.sin6_family = zhost->h_addrtype;
+	sess->peer.in6.sin6_family = zai->ai_family;
 	salen = sizeof(struct sockaddr_in6);
     } else
 #endif /* SUPPORT_IPV6 */
     {
-	memcpy(&(sess->peer.in.sin_addr), addrp, zhost->h_length);
-	sess->peer.in.sin_port = d_port;
-	sess->peer.in.sin_family = zhost->h_addrtype;
+	memcpy(&(sess->peer.in.sin_addr), zai->ai_addr, zai->ai_addrlen);
+	sess->peer.in.sin_family = zai->ai_family;
 	salen = sizeof(struct sockaddr_in);
     }
 
@@ -339,12 +264,13 @@ tcp_connect(Tcp_session sess, char *addrp, struct hostent *zhost, int d_port)
 static int
 bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 {
-    int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0;
+    int err=1, destport, force=0, verbose=0, test=0, targetfd=0;
     ZSOCKLEN_T  len;
-    char **addrp, *desthost, *localname, *remotename;
-    struct hostent *zthost = NULL, *ztpeer = NULL;
+    char *desthost, *localname, *remotename;
+    char zthostname[1025], ztpeername[1025];
     struct servent *srv;
     Tcp_session sess = NULL;
+    struct addrinfo *zhostlist, *zai;
 
     if (OPT_ISSET(ops,'f'))
 	force = 1;
@@ -561,16 +487,16 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 
 		if (sess->fd != -1)
 		{
-		    zthost = gethostbyaddr((const void *)&(sess->sock.in.sin_addr), sizeof(sess->sock.in.sin_addr), AF_INET);
-		    if (zthost)
-			localname = zthost->h_name;
-		    else
+		    if (getnameinfo((const struct sockaddr *)&(sess->sock.in.sin_addr), sizeof(struct sockaddr_in), zthostname, 1025, NULL, 0, 0))
 			localname = ztrdup(inet_ntoa(sess->sock.in.sin_addr));
-		    ztpeer = gethostbyaddr((const void *)&(sess->peer.in.sin_addr), sizeof(sess->peer.in.sin_addr), AF_INET);
-		    if (ztpeer)
-			remotename = ztpeer->h_name;
 		    else
+			localname = (char *)&zthostname;
+
+		    if (getnameinfo((const struct sockaddr *)&(sess->peer.in.sin_addr), sizeof(struct sockaddr_in), ztpeername, 1025, NULL, 0, 0))
 			remotename = ztrdup(inet_ntoa(sess->peer.in.sin_addr));
+		    else 
+			remotename = (char *)&ztpeername;
+
 		    if (OPT_ISSET(ops,'L')) {
 			int schar;
 			if (sess->flags & ZTCP_ZFTP)
@@ -602,20 +528,21 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    destport = htons(23);
 	}
 	else {
+	    struct addrinfo hints;
 
-	    srv = getservbyname(args[1],"tcp");
-	    if (srv)
-		destport = srv->s_port;
-	    else
-		destport = htons(atoi(args[1]));
-	}
-	
-	desthost = ztrdup(args[0]);
-	
-	zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno);
-	if (!zthost || errflag) {
-	    zwarnnam(nam, "host resolution failure: %s", desthost);
-	    return 1;
+	    hints.ai_family = AF_INET;
+	    hints.ai_socktype = SOCK_STREAM;
+	    hints.ai_protocol = PF_INET;
+
+	    desthost = ztrdup(args[0]);
+
+	    if(getaddrinfo(desthost, args[1], &hints, &zhostlist)) {
+	        zwarnnam(nam, "host resolution failure: %s", desthost);
+	        return 1;
+	    }
+	    else {
+		destport = ntohs(((struct sockaddr_in *)(&zhostlist->ai_addr))->sin_port);
+	    }
 	}
 	
 	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, 0);
@@ -637,11 +564,11 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func))
 	    return 1;
 	}
 	
-	for (addrp = zthost->h_addr_list; err && *addrp; addrp++) {
-	    if (zthost->h_length != 4)
+	for (zai = zhostlist; err && zai; zai = zai->ai_next) {
+	    if (zai->ai_addrlen != 4)
 		zwarnnam(nam, "address length mismatch");
 	    do {
-		err = tcp_connect(sess, *addrp, zthost, destport);
+		err = tcp_connect(sess, zai);
 	    } while (err && errno == EINTR && !errflag);
 	}
 	
diff --git a/Src/Modules/tcp.mdd b/Src/Modules/tcp.mdd
index 69fd4d6bf..d2bac21b5 100644
--- a/Src/Modules/tcp.mdd
+++ b/Src/Modules/tcp.mdd
@@ -1,6 +1,7 @@
 name=zsh/net/tcp
-link=dynamic
+link=`if test x$ac_cv_func_getaddrinfo; then echo dynamic; else echo no; fi`
 load=no
+
 functions='Functions/TCP/*'
 
 objects="tcp.o"
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index af48e80aa..9f810f922 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -1697,12 +1697,12 @@ zftp_open(char *name, char **args, int flags)
 {
     struct protoent *zprotop;
     struct servent *zservp;
-    struct hostent *zhostp;
+    struct addrinfo *zai;
     char **addrp, *fname, *tmpptr, *portnam = "ftp";
     char *hostnam, *hostsuffix;
     int err, tmout, port = -1;
     ZSOCKLEN_T  len;
-    int herrno, af, hlen;
+    int af, hlen;
 
     if (!*args) {
 	if (zfsess->userparams)
@@ -1806,21 +1806,20 @@ zftp_open(char *name, char **args, int flags)
 #endif
     {
 	off_t tcp_port;
+	struct addrinfo hints, *hostlist;
+	int gai_err;
 
-	zhostp = zsh_getipnodebyname(hostnam, af, 0, &herrno);
-	if (!zhostp || errflag) {
-	    /* should use herror() here if available, but maybe
-	     * needs configure test. on AIX it's present but not
-	     * in headers.
-	     * 
-	     * on the other hand, herror() is obsolete
-	     */
+	hints.ai_family = af;
+
+	gai_err = getaddrinfo(hostnam, NULL, &hints, &hostlist);
+
+	if (errflag || gai_err) {
 	    FAILED();
-	    zwarnnam(name, "host not found: %s", hostnam);
+	    zwarnnam(name, "host lookup failure: %s", gai_strerror(gai_err));
 	    alarm(0);
 	    return 1;
 	}
-	zfsetparam("ZFTP_HOST", ztrdup(zhostp->h_name), ZFPM_READONLY);
+	zfsetparam("ZFTP_HOST", ztrdup(hostlist->ai_canonname), ZFPM_READONLY);
 	/* careful with pointer types */
 #if defined(HAVE_NTOHS) && defined(HAVE_HTONS)
 	tcp_port = (off_t)ntohs((unsigned short)zservp->s_port);
@@ -1845,7 +1844,6 @@ zftp_open(char *name, char **args, int flags)
 		tcp_close(zfsess->control);
 		zfsess->control = NULL;
 	    }
-	    freehostent(zhostp);
 	    zfunsetparam("ZFTP_HOST");
 	    zfunsetparam("ZFTP_PORT");
 	    FAILED();
@@ -1864,17 +1862,16 @@ zftp_open(char *name, char **args, int flags)
 	err = 1;
 
 	/* try all possible IP's */
-	for (addrp = zhostp->h_addr_list; err && *addrp; addrp++) {
-	    if(hlen != zhostp->h_length)
+	for (zai = hostlist; err && zai; zai = zai->ai_next) {
+	    if(hlen != zai->ai_addrlen)
 		zwarnnam(name, "address length mismatch");
 	    do {
-		err = tcp_connect(zfsess->control, *addrp, zhostp, zservp->s_port);
+		err = tcp_connect(zfsess->control, zai);
 	    } while (err && errno == EINTR && !errflag);
 	    /* you can check whether it's worth retrying here */
 	}
 
 	if (err) {
-	    freehostent(zhostp);
 	    zfclose(0);
 	    FAILED();
 	    zwarnnam(name, "connect failed: %e", errno);
@@ -1895,7 +1892,6 @@ zftp_open(char *name, char **args, int flags)
 	zsh_inet_ntop(af, *addrp, pbuf, sizeof(pbuf));
 	zfsetparam("ZFTP_IP", ztrdup(pbuf), ZFPM_READONLY);
     }
-    freehostent(zhostp);
     /* now we can talk to the control connection */
     zcfinish = 0;
 
diff --git a/Src/Modules/zftp.mdd b/Src/Modules/zftp.mdd
index e96b367f9..f86056ca5 100644
--- a/Src/Modules/zftp.mdd
+++ b/Src/Modules/zftp.mdd
@@ -1,5 +1,5 @@
 name=zsh/zftp
-link=dynamic
+link=`if test x$ac_cv_func_getaddrinfo; then echo dynamic; else echo no; fi`
 load=no
 functions='Functions/Zftp/*'
 
diff --git a/configure.ac b/configure.ac
index a3556d103..9a0cfae5d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1116,7 +1116,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
 	       waitpid wait3 \
 	       sigaction sigblock sighold sigrelse sigsetmask sigprocmask \
 	       killpg setpgid setpgrp tcsetpgrp tcgetattr nice \
-	       gethostname gethostbyname2 getipnodebyname \
+	       gethostname getaddrinfo getnameinfo \
 	       inet_aton inet_pton inet_ntop \
 	       getlogin getpwent getpwnam getpwuid getgrgid getgrnam \
 	       initgroups nis_list \