Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: tcp cleanup and breakage



The highlights of this patch:

getaddrinfo and getnameinfo are used instead of gethostbyname2,
getipnodebyname, getservbyname, getprotobyname, inet_aton, inet_ntop,
and other fun functions.  This means that zsh/net/tcp and zsh/zftp
would be damn near useless on systems with broken or missing
getaddrinfo() in the absence of compatibility functions/workarounds.

ztcp now takes -4 and -6 on systems with IPv6 support.  These are also
largely useless due to the inconsistent implementation of IPv6 in tcp.

ztcp -l now takes an argument in the form bind.addr:port as well as the
previous syntax of ztcp -l port.

Neither zftp nor ztcp try multiple addresses anymore.  I had originally
moved the address-trying loop to tcp_connect(), where it proceeded to
cause me much anguish, so I removed it.  I imagine that a feature like
this could be desirable if non-blocking connects are implemented as
well.

Some other things may have been fixed or broken, and some inexplicable
changes in whitespace occurred.  I won't commit this.

Index: zshconfig.ac
===================================================================
RCS file: /cvsroot/zsh/zsh/zshconfig.ac,v
retrieving revision 1.28
diff -u -r1.28 zshconfig.ac
--- zshconfig.ac	6 May 2002 14:50:11 -0000	1.28
+++ zshconfig.ac	4 Jul 2002 09:43:14 -0000
@@ -934,7 +934,7 @@
 	       waitpid wait3 \
 	       sigaction sigblock sighold sigrelse sigsetmask sigprocmask \
 	       killpg setpgid setpgrp tcsetpgrp tcgetattr nice \
-	       gethostname gethostbyname2 getipnodebyname \
+	       gethostname getaddrinfo \
 	       inet_aton inet_pton inet_ntop \
 	       getlogin getpwent getpwnam getpwuid getgrgid getgrnam \
 	       initgroups nis_list \
Index: Src/Modules/tcp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.c,v
retrieving revision 1.32
diff -u -r1.32 tcp.c
--- Src/Modules/tcp.c	5 Jun 2002 21:02:37 -0000	1.32
+++ Src/Modules/tcp.c	4 Jul 2002 09:43:16 -0000
@@ -48,10 +48,6 @@
 # undef HAVE_POLL
 #endif
 
-#ifdef USE_LOCAL_H_ERRNO
-int h_errno;
-#endif
-
 /* We use the RFC 2553 interfaces.  If the functions don't exist in the
  * library, simulate them. */
 
@@ -64,148 +60,7 @@
 #endif
 
 /**/
-#ifndef HAVE_INET_NTOP
-
-/**/
-mod_export char const *
-zsh_inet_ntop(int af, void const *cp, char *buf, size_t len)
-{       
-    if (af != AF_INET) {
-	errno = EAFNOSUPPORT;
-	return NULL;
-    } 
-    if (len < INET_ADDRSTRLEN) {
-	errno = ENOSPC;
-	return NULL;
-    }
-    strcpy(buf, inet_ntoa(*(struct in_addr *)cp));
-    return buf;
-}
-
-/**/
-#else /* !HAVE_INET_NTOP */
-
-/**/
-# define zsh_inet_ntop inet_ntop
-
-/**/
-#endif /* !HAVE_INET_NTOP */
-
-/**/
-#ifndef HAVE_INET_ATON
-
-# ifndef INADDR_NONE
-#  define INADDR_NONE 0xffffffffUL
-# endif
-
-/**/
-mod_export int zsh_inet_aton(char const *src, struct in_addr *dst)
-{
-    return (dst->s_addr = inet_addr(src)) != INADDR_NONE;
-}
-
-/**/
-#else /* !HAVE_INET_ATON */
-
-/**/
-# define zsh_inet_aton inet_aton
-
-/**/
-#endif /* !HAVE_INET_ATON */
-
-/**/
-#ifndef HAVE_INET_PTON
-
-/**/
-mod_export int
-zsh_inet_pton(int af, char const *src, void *dst)
-{
-    if (af != AF_INET) {
-	errno = EAFNOSUPPORT;
-	return -1;
-    }
-    return !!zsh_inet_aton(src, dst);
-}
-
-#else /* !HAVE_INET_PTON */
-
-# define zsh_inet_pton inet_pton
-
-/**/
-#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, 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(struct hostent *ptr)
-{
-}
-
-/**/
-#else /* !HAVE_GETIPNODEBYNAME */
-
-/**/
-# define zsh_getipnodebyname getipnodebyname
-
-/**/
-#endif /* !HAVE_GETIPNODEBYNAME */
+#ifdef HAVE_GETADDRINFO
 
 LinkList ztcp_sessions;
 
@@ -310,39 +165,32 @@
 
 /**/
 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;
+    memcpy(&(sess->peer), zai->ai_addr, zai->ai_addrlen);
 #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 == PF_INET6) {
+	sess->peer.in6.sin6_family = zai->ai_family;
 	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;
-	salen = sizeof(struct sockaddr_in6);
-    } else
+    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;
-	salen = sizeof(struct sockaddr_in);
-    }
+	sess->peer.in.sin_family = zai->ai_family;
 
-    return connect(sess->fd, (struct sockaddr *)&(sess->peer), salen);
+    return connect(sess->fd, (struct sockaddr *)&(sess->peer), zai->ai_addrlen);
 }
 
 static int
 bin_ztcp(char *nam, char **args, char *ops, int func)
 {
-    int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0;
+    int gai_errno, err=1, force=0, verbose=0, test=0, targetfd=0,
+    	pf = PF_INET;
     SOCKLEN_T  len;
-    char **addrp, *desthost, *localname, *remotename, **dargs;
-    struct hostent *zthost = NULL, *ztpeer = NULL;
-    struct servent *srv;
+    char *desthost, *destservice, *localname, *remotename, **dargs;
+    struct addrinfo *zthost = NULL, zthints;
     Tcp_session sess = NULL;
 
     if (ops['f'])
@@ -354,6 +202,14 @@
     if (ops['t'])
         test = 1;
 
+#ifdef SUPPORT_IPV6
+    if (ops['4'])
+	pf = PF_INET;
+
+    if (ops['6'])
+	pf = PF_INET6;
+#endif /* SUPPORT_IPV6 */
+
     if (ops['d']) {
 	targetfd = atoi(args[0]);
 	dargs = args + 1;
@@ -396,44 +252,52 @@
 	}
     }
     else if (ops['l']) {
-	int lport = 0;
+	char *localhost, *localport;
 
 	if (!dargs[0]) {
 	    zwarnnam(nam, "-l requires an argument", NULL, 0);
 	    return 1;
 	}
 
-	srv = getservbyname(dargs[0], "tcp");
-	if (srv)
-	    lport = srv->s_port;
-	else
-	    lport = htons(atoi(dargs[0]));
-	if (!lport) { zwarnnam(nam, "bad service name or port number", NULL, 0);
-	return 1;
+	if ((localport = memchr(localhost = dargs[0], (int)':', strlen(dargs[0]))) == NULL) {
+	    localhost = dupstring("0.0.0.0");
+	    localport = dargs[0];
+	}
+	else {
+	    *localport++ = '\0';
+	}
+
+	memset(&zthints, 0, sizeof(zthints));
+	zthints.ai_protocol = IPPROTO_TCP;
+	zthints.ai_flags = AI_CANONNAME;
+	zthints.ai_socktype = SOCK_STREAM;
+
+	if ((gai_errno = zsh_getaddrinfo(localhost, localport, &zthints, &zthost))) {
+	    zwarnnam(nam, "bad service name, port number, or hostname: %s: %d", dargs[0], gai_errno);
+	    return 1;
 	}
-	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, ZTCP_LISTEN);
+	sess = tcp_socket(pf, SOCK_STREAM, IPPROTO_IP, ZTCP_LISTEN);
 
 	if (!sess) {
 	    zwarnnam(nam, "unable to allocate a TCP session slot", NULL, 0);
 	    return 1;
 	}
+	if ((sess->fd) == -1) {
+	    zwarnnam(nam, "socket error: %e", NULL, errno);
+	    return 1;
+	}
 #ifdef SO_OOBINLINE
 	len = 1;
 	setsockopt(sess->fd, SOL_SOCKET, SO_OOBINLINE, (char *)&len, sizeof(len));
 #endif
-	if (!zsh_inet_aton("0.0.0.0", &(sess->sock.in.sin_addr)))
-	{
-	    zwarnnam(nam, "bad address: %s", "0.0.0.0", 0);
-	    return 1;
-	}
 
-	sess->sock.in.sin_family = AF_INET;
-	sess->sock.in.sin_port = lport;
+	memcpy(&(sess->sock.a), zthost->ai_addr, sizeof(struct sockaddr));
 
+	freeaddrinfo(zthost);
 
 	if (bind(sess->fd, (struct sockaddr *)&sess->sock.in, sizeof(struct sockaddr_in)))
 	{
-	    zwarnnam(nam, "could not bind to %s: %e", "0.0.0.0", errno);
+	    zwarnnam(nam, "could not bind to %s: %e", dargs[0], errno);
 	    tcp_close(sess);
 	    return 1;
 	}
@@ -561,16 +425,21 @@
 
 		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
-			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
-			remotename = ztrdup(inet_ntoa(sess->peer.in.sin_addr));
+		    char *hostname;
+		    hostname = malloc(255);
+
+		    if (!zsh_getnameinfo((struct sockaddr *)&(sess->sock.a), sizeof(sess->sock.a), hostname, 255, NULL, 0, 0))
+			localname = hostname;
+		    else {
+			localname = ztrdup("ERR");
+		    }
+
+		    if (!zsh_getnameinfo((struct sockaddr *)&(sess->peer.a), sizeof(sess->peer.a), hostname, 255, NULL, 0, 0))
+			remotename = hostname;
+		    else {
+			remotename = ztrdup("ERR");
+		    }
+
 		    if (ops['L']) {
 			int schar;
 			if (sess->flags & ZTCP_ZFTP)
@@ -599,26 +468,30 @@
 	    return 0;
 	}
 	else if (!dargs[1]) {
-	    destport = htons(23);
+	    destservice = ztrdup("telnet");
 	}
 	else {
-
-	    srv = getservbyname(dargs[1],"tcp");
-	    if (srv)
-		destport = srv->s_port;
-	    else
-		destport = htons(atoi(dargs[1]));
+	    destservice = ztrdup(dargs[1]);
 	}
-	
+
+	memset(&zthints, 0, sizeof(zthints));
+	zthints.ai_protocol = IPPROTO_TCP;
+	zthints.ai_flags = AI_CANONNAME;
+
 	desthost = ztrdup(dargs[0]);
-	
-	zthost = zsh_getipnodebyname(desthost, AF_INET, 0, &herrno);
-	if (!zthost || errflag) {
-	    zwarnnam(nam, "host resolution failure: %s", desthost, 0);
+
+	gai_errno = zsh_getaddrinfo(desthost, destservice, &zthints, &zthost);
+
+	zsfree(desthost);
+	zsfree(destservice);
+
+	if (gai_errno) {
+	    /* gai_strerror could be more useful here */
+	    zwarnnam(nam, "host/service resolution failure: %s: %d", desthost, gai_errno);
 	    return 1;
 	}
 	
-	sess = tcp_socket(PF_INET, SOCK_STREAM, 0, 0);
+	sess = tcp_socket(pf, SOCK_STREAM, IPPROTO_IP, 0);
 
 	if (!sess) {
 	    zwarnnam(nam, "unable to allocate a TCP session slot", NULL, 0);
@@ -632,23 +505,13 @@
 
 	if (sess->fd < 0) {
 	    zwarnnam(nam, "socket creation failed: %e", NULL, errno);
-	    zsfree(desthost);
 	    zts_delete(sess);
 	    return 1;
 	}
 	
-	for (addrp = zthost->h_addr_list; err && *addrp; addrp++) {
-	    if (zthost->h_length != 4)
-		zwarnnam(nam, "address length mismatch", NULL, 0);
-	    do {
-		err = tcp_connect(sess, *addrp, zthost, destport);
-	    } while (err && errno == EINTR && !errflag);
-	}
-	
-	if (err) {
+	if ((err = tcp_connect(sess, zthost))) {
 	    zwarnnam(nam, "connection failed: %e", NULL, errno);
 	    tcp_close(sess);
-	    zsfree(desthost);
 	    return 1;
 	}
 	else
@@ -662,7 +525,7 @@
 
 	    if (verbose)
 		printf("%s:%d is now on fd %d\n",
-			desthost, destport, sess->fd);
+		       zthost->ai_canonname, ntohs(((struct sockaddr_in *)(zthost->ai_addr))->sin_port), sess->fd);
 	}
 	
 	zsfree(desthost);
@@ -672,9 +535,16 @@
 }
 
 static struct builtin bintab[] = {
+#ifdef SUPPORT_IPV6
+    BUILTIN("ztcp", 0, bin_ztcp, 0, 3, 0, "acdflLtv46", NULL),
+#else
     BUILTIN("ztcp", 0, bin_ztcp, 0, 3, 0, "acdflLtv", NULL),
+#endif /* SUPPORT_IPV6 */
 };
 
+/**/
+#endif /* HAVE_GETADDRINFO */
+
 /* The load/unload routines required by the zsh library interface */
 
 /**/
@@ -688,8 +558,12 @@
 int
 boot_(Module m)
 {
+#ifdef HAVE_GETADDRINFO
     ztcp_sessions = znewlinklist();
     return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+#else
+    return 1;
+#endif /* HAVE_GETADDRINFO */
 }
 
 
@@ -697,9 +571,11 @@
 int
 cleanup_(Module m)
 {
+#ifdef HAVE_GETADDRINFO
     tcp_cleanup();
     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
     freelinklist(ztcp_sessions, (FreeFunc) ztcp_free_session);
+#endif /* HAVE_GETADDRINFO */
     return 0;
 }
 
Index: Src/Modules/tcp.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/tcp.h,v
retrieving revision 1.6
diff -u -r1.6 tcp.h
--- Src/Modules/tcp.h	2 Oct 2001 02:35:01 -0000	1.6
+++ Src/Modules/tcp.h	4 Jul 2002 09:43:16 -0000
@@ -93,3 +93,6 @@
 #ifndef INET6_ADDRSTRLEN
 # define INET6_ADDRSTRLEN 46
 #endif
+
+#define zsh_getnameinfo getnameinfo
+#define zsh_getaddrinfo getaddrinfo
Index: Src/Modules/zftp.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/zftp.c,v
retrieving revision 1.27
diff -u -r1.27 zftp.c
--- Src/Modules/zftp.c	15 May 2002 20:38:18 -0000	1.27
+++ Src/Modules/zftp.c	4 Jul 2002 09:43:22 -0000
@@ -639,7 +639,7 @@
 	    case WILL:
 	    case WONT:
 		ch = fgetc(zfsess->cin);
-		/* whatever it wants to do, stop it. */
+				/* whatever it wants to do, stop it. */
 		cmdbuf[0] = (char)IAC;
 		cmdbuf[1] = (char)DONT;
 		cmdbuf[2] = ch;
@@ -649,7 +649,7 @@
 	    case DO:
 	    case DONT:
 		ch = fgetc(zfsess->cin);
-		/* well, tough, we're not going to. */
+				/* well, tough, we're not going to. */
 		cmdbuf[0] = (char)IAC;
 		cmdbuf[1] = (char)WONT;
 		cmdbuf[2] = ch;
@@ -657,7 +657,7 @@
 		continue;
 
 	    case EOF:
-		/* strange machine. */
+				/* strange machine. */
 		zcfinish = 2;
 		break;
 
@@ -828,7 +828,7 @@
      * We use the fd directly; there's no point even using
      * stdio with line buffering, since we always send the
      * complete line in one string anyway.
-     */
+	 */
     int ret, tmout;
 
     if (!zfsess->control)
@@ -1014,8 +1014,11 @@
 	if(zdsockp->a.sa_family == AF_INET6) {
 	    /* see RFC 2428 for explanation */
 	    strcpy(portcmd, "EPRT |2|");
-	    zsh_inet_ntop(AF_INET6, &zdsockp->in6.sin6_addr,
-			  portcmd+8, INET6_ADDRSTRLEN);
+
+	    zsh_getnameinfo(&(zdsockp->a), sizeof(struct sockaddr),
+			    (char *)portcmd+8, INET6_ADDRSTRLEN,
+			    NULL, 0, NI_NUMERICHOST);
+
 	    sprintf(strchr(portcmd, 0), "|%u|\r\n",
 		    (unsigned)ntohs(zdsockp->in6.sin6_port));
 	} else
@@ -1514,7 +1517,7 @@
 	if (n > 0) {
 	    char *iptr;
 	    if (toasc) {
-		/* \n -> \r\n it shouldn't happen to a dog. */
+				/* \n -> \r\n it shouldn't happen to a dog. */
 		char *iptr = ascbuf, *optr = lsbuf;
 		int cnt = n;
 		while (cnt--) {
@@ -1526,7 +1529,7 @@
 		}
 	    }
 	    if (fromasc && (iptr = memchr(lsbuf, '\r', n))) {
-		/* \r\n -> \n */
+				/* \r\n -> \n */
 		char *optr = iptr;
 		int cnt = n - (iptr - lsbuf);
 		while (cnt--) {
@@ -1542,13 +1545,13 @@
 	    sofar += n;
 
 	    for (;;) {
-		/*
-		 * in principle, write can be interrupted after
-		 * safely writing some bytes, and will return the
-		 * number already written, which may not be the
-		 * complete buffer.  so make this robust.  they call me
-		 * `robustness stephenson'.  in my dreams.
-		 */
+				/*
+				 * in principle, write can be interrupted after
+				 * safely writing some bytes, and will return the
+				 * number already written, which may not be the
+				 * complete buffer.  so make this robust.  they call me
+				 * `robustness stephenson'.  in my dreams.
+				 */
 		int newn = write_ptr(fdout, optr, n, wtmout);
 		if (newn == n)
 		    break;
@@ -1696,13 +1699,11 @@
 static int
 zftp_open(char *name, char **args, int flags)
 {
-    struct protoent *zprotop;
-    struct servent *zservp;
-    struct hostent *zhostp = NULL;
-    char **addrp, *fname;
+    struct addrinfo *zhostp = NULL, zthints;
+    char *fname;
     int err, tmout;
     SOCKLEN_T  len;
-    int herrno, af, hlen;
+    int gai_errno, af, hlen;
 
     if (!*args) {
 	if (zfsess->userparams)
@@ -1721,15 +1722,6 @@
     if (zfsess->control)
 	zfclose(0);
 
-    /* this is going to give 0.  why bother? */
-    zprotop = getprotobyname("tcp");
-    zservp = getservbyname("ftp", "tcp");
-
-    if (!zprotop || !zservp) {
-	zwarnnam(name, "Somebody stole FTP!", NULL, 0);
-	return 1;
-    }
-
     /* don't try talking to server yet */
     zcfinish = 2;
 
@@ -1762,20 +1754,20 @@
 # define FAILED() do { } while(0)
 #endif
     {
-	zhostp = zsh_getipnodebyname(args[0], 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
-	     */
+
+	memset(&zthints, 0, sizeof(zthints));
+	zthints.ai_protocol = IPPROTO_TCP;
+	zthints.ai_flags = AI_CANONNAME;
+
+
+	if ((gai_errno = zsh_getaddrinfo(args[0], "ftp", &zthints, &zhostp))) {
+	    /* could use gai_strerror() */
 	    FAILED();
-	    zwarnnam(name, "host not found: %s", args[0], 0);
+	    zwarnnam(name, "host not found: %s: %d", args[0], gai_errno);
 	    alarm(0);
 	    return 1;
 	}
-	zfsetparam("ZFTP_HOST", ztrdup(zhostp->h_name), ZFPM_READONLY);
+	zfsetparam("ZFTP_HOST", ztrdup(zhostp->ai_canonname), ZFPM_READONLY);
 
 #ifdef SUPPORT_IPV6
 	if(af == AF_INET6) {
@@ -1793,7 +1785,7 @@
 		tcp_close(zfsess->control);
 		zfsess->control = NULL;
 	    }
-	    freehostent(zhostp);
+	    freeaddrinfo(zhostp);
 	    zfunsetparam("ZFTP_HOST");
 	    FAILED();
 	    zwarnnam(name, "socket failed: %e", NULL, errno);
@@ -1810,18 +1802,10 @@
 
 	err = 1;
 
-	/* try all possible IP's */
-	for (addrp = zhostp->h_addr_list; err && *addrp; addrp++) {
-	    if(hlen != zhostp->h_length)
-		zwarnnam(name, "address length mismatch", NULL, 0);
-	    do {
-		err = tcp_connect(zfsess->control, *addrp, zhostp, zservp->s_port);
-	    } while (err && errno == EINTR && !errflag);
-	    /* you can check whether it's worth retrying here */
-	}
+	err = tcp_connect(zfsess->control, zhostp);
 
 	if (err) {
-	    freehostent(zhostp);
+	    freeaddrinfo(zhostp);
 	    zfclose(0);
 	    FAILED();
 	    zwarnnam(name, "connect failed: %e", NULL, errno);
@@ -1838,11 +1822,12 @@
 #else
 	char pbuf[INET_ADDRSTRLEN];
 #endif
-	addrp--;
-	zsh_inet_ntop(af, *addrp, pbuf, sizeof(pbuf));
+	zsh_getnameinfo(&(zfsess->control->peer.a), sizeof(struct sockaddr),
+			pbuf, sizeof(pbuf), NULL, 0, NI_NUMERICHOST);
+
 	zfsetparam("ZFTP_IP", ztrdup(pbuf), ZFPM_READONLY);
     }
-    freehostent(zhostp);
+    freeaddrinfo(zhostp);
     /* now we can talk to the control connection */
     zcfinish = 0;
 
@@ -2163,13 +2148,13 @@
 		;
 	    systype = ztrduppfx(ptr, eptr-ptr);
 	    if (!strncmp(systype, "UNIX Type: L8", 13)) {
-		/*
-		 * Use binary for transfers.  This simple test saves much
-		 * hassle for all concerned, particularly me.
-		 *
-		 * We could set this based just on the UNIX part,
-		 * but I don't really know the consequences of that.
-		 */
+				/*
+				 * Use binary for transfers.  This simple test saves much
+				 * hassle for all concerned, particularly me.
+				 *
+				 * We could set this based just on the UNIX part,
+				 * but I don't really know the consequences of that.
+				 */
 		zfstatusp[zfsessno] |= ZFST_IMAG;
 	    }
 	    zfsetparam("ZFTP_SYSTEM", systype, ZFPM_READONLY);
@@ -2262,10 +2247,10 @@
     int ret;
 
     /*
-     * RFC959 says this must be ASCII or EBCDIC, not image format.
-     * I rather suspect on a UNIX server we get away handsomely
-     * with doing everything, including this, as image.
-     */
+	 * RFC959 says this must be ASCII or EBCDIC, not image format.
+	 * I rather suspect on a UNIX server we get away handsomely
+	 * with doing everything, including this, as image.
+	 */
     zfsettype(ZFST_ASCI);
 
     cmd = zfargstring((flags & ZFTP_NLST) ? "NLST" : "LIST", args);
@@ -2528,9 +2513,9 @@
 	    if ((!(zfprefs & ZFPF_DUMB) &&
 		 (zfstatusp[zfsessno] & (ZFST_NOSZ|ZFST_TRSZ)) != ZFST_TRSZ)
 		|| !recv) {
-		/* the final 0 is a local fd to fstat if recv is zero */
+				/* the final 0 is a local fd to fstat if recv is zero */
 		zfstats(*args, recv, &sz, NULL, 0);
-		/* even if it doesn't support SIZE, it may tell us */
+				/* even if it doesn't support SIZE, it may tell us */
 		if (recv && sz == -1)
 		    getsize = 1;
 	    } else
@@ -3029,22 +3014,22 @@
 	for (ptr = prefs; *ptr; ptr++) {
 	    switch (toupper(STOUC(*ptr))) {
 	    case 'S':
-		/* sendport */
+				/* sendport */
 		zfprefs |= ZFPF_SNDP;
 		break;
 
 	    case 'P':
-		/*
-		 * passive
-		 * If we have already been told to use sendport mode,
-		 * we're never going to use passive mode.
-		 */
+				/*
+				 * passive
+				 * If we have already been told to use sendport mode,
+				 * we're never going to use passive mode.
+				 */
 		if (!(zfprefs & ZFPF_SNDP))
 		    zfprefs |= ZFPF_PASV;
 		break;
 
 	    case 'D':
-		/* dumb */
+				/* dumb */
 		zfprefs |= ZFPF_DUMB;
 		break;
 
@@ -3082,7 +3067,7 @@
     /*
      * There are various parameters hanging around, but they're
      * all non-special so are entirely non-life-threatening.
-     */
+	 */
     LinkNode nptr;
     Zftp_session cursess = zfsess;
     for (zfsessno = 0, nptr = firstnode(zfsessions); nptr;
@@ -3090,9 +3075,9 @@
 	zfsess = (Zftp_session)nptr->dat;
 	zfclosedata();
 	/*
-	 * When closing the current session, do the usual unsetting,
-	 * otherwise don't.
-	 */
+		 * When closing the current session, do the usual unsetting,
+		 * otherwise don't.
+		 */
 	zfclose(zfsess != cursess);
     }
     zsfree(lastmsg);



Messages sorted by: Reverse Date, Date, Thread, Author