From 01ba47bd4fc59c66b98301186cac7bc64c89404a Mon Sep 17 00:00:00 2001 From: Clint Adams Date: Thu, 12 Jul 2007 03:09:12 +0000 Subject: revert that --- Src/Modules/tcp.c | 141 ++++++++++++++++++++++++++++++++++++++------------- Src/Modules/tcp.mdd | 3 +- Src/Modules/zftp.c | 32 +++++++----- Src/Modules/zftp.mdd | 2 +- 4 files changed, 127 insertions(+), 51 deletions(-) (limited to 'Src/Modules') diff --git a/Src/Modules/tcp.c b/Src/Modules/tcp.c index 847bb6fc5..d1d4e5002 100644 --- a/Src/Modules/tcp.c +++ b/Src/Modules/tcp.c @@ -135,6 +135,79 @@ 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 */ @@ -238,23 +311,25 @@ tcp_close(Tcp_session sess) /**/ mod_export int -tcp_connect(Tcp_session sess, struct addrinfo *zai) +tcp_connect(Tcp_session sess, char *addrp, struct hostent *zhost, int d_port) { int salen; #ifdef SUPPORT_IPV6 - if (zai->ai_family==AF_INET6) { - memcpy(&(sess->peer.in6.sin6_addr), zai->ai_addr, zai->ai_addrlen); + if (zhost->h_addrtype==AF_INET6) { + memcpy(&(sess->peer.in6.sin6_addr), addrp, zhost->h_length); + sess->peer.in6.sin6_port = d_port; 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 = zai->ai_family; + sess->peer.in6.sin6_family = zhost->h_addrtype; salen = sizeof(struct sockaddr_in6); } else #endif /* SUPPORT_IPV6 */ { - memcpy(&(sess->peer.in.sin_addr), zai->ai_addr, zai->ai_addrlen); - sess->peer.in.sin_family = zai->ai_family; + 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); } @@ -264,13 +339,12 @@ tcp_connect(Tcp_session sess, struct addrinfo *zai) static int bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) { - int err=1, destport, force=0, verbose=0, test=0, targetfd=0; + int herrno, err=1, destport, force=0, verbose=0, test=0, targetfd=0; ZSOCKLEN_T len; - char *desthost, *localname, *remotename; - char zthostname[1025], ztpeername[1025]; + char **addrp, *desthost, *localname, *remotename; + struct hostent *zthost = NULL, *ztpeer = NULL; struct servent *srv; Tcp_session sess = NULL; - struct addrinfo *zhostlist, *zai; if (OPT_ISSET(ops,'f')) force = 1; @@ -487,16 +561,16 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) if (sess->fd != -1) { - if (getnameinfo((const struct sockaddr *)&(sess->sock.in.sin_addr), sizeof(struct sockaddr_in), zthostname, 1025, NULL, 0, 0)) + 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 - 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) @@ -528,21 +602,20 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) destport = htons(23); } else { - struct addrinfo hints; - - 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); - } + 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; } sess = tcp_socket(PF_INET, SOCK_STREAM, 0, 0); @@ -564,11 +637,11 @@ bin_ztcp(char *nam, char **args, Options ops, UNUSED(int func)) return 1; } - for (zai = zhostlist; err && zai; zai = zai->ai_next) { - if (zai->ai_addrlen != 4) + for (addrp = zthost->h_addr_list; err && *addrp; addrp++) { + if (zthost->h_length != 4) zwarnnam(nam, "address length mismatch"); do { - err = tcp_connect(sess, zai); + err = tcp_connect(sess, *addrp, zthost, destport); } while (err && errno == EINTR && !errflag); } diff --git a/Src/Modules/tcp.mdd b/Src/Modules/tcp.mdd index d2bac21b5..69fd4d6bf 100644 --- a/Src/Modules/tcp.mdd +++ b/Src/Modules/tcp.mdd @@ -1,7 +1,6 @@ name=zsh/net/tcp -link=`if test x$ac_cv_func_getaddrinfo; then echo dynamic; else echo no; fi` +link=dynamic load=no - functions='Functions/TCP/*' objects="tcp.o" diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c index 9f810f922..af48e80aa 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 addrinfo *zai; + struct hostent *zhostp; char **addrp, *fname, *tmpptr, *portnam = "ftp"; char *hostnam, *hostsuffix; int err, tmout, port = -1; ZSOCKLEN_T len; - int af, hlen; + int herrno, af, hlen; if (!*args) { if (zfsess->userparams) @@ -1806,20 +1806,21 @@ zftp_open(char *name, char **args, int flags) #endif { off_t tcp_port; - struct addrinfo hints, *hostlist; - int gai_err; - hints.ai_family = af; - - gai_err = getaddrinfo(hostnam, NULL, &hints, &hostlist); - - if (errflag || 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 + */ FAILED(); - zwarnnam(name, "host lookup failure: %s", gai_strerror(gai_err)); + zwarnnam(name, "host not found: %s", hostnam); alarm(0); return 1; } - zfsetparam("ZFTP_HOST", ztrdup(hostlist->ai_canonname), ZFPM_READONLY); + zfsetparam("ZFTP_HOST", ztrdup(zhostp->h_name), ZFPM_READONLY); /* careful with pointer types */ #if defined(HAVE_NTOHS) && defined(HAVE_HTONS) tcp_port = (off_t)ntohs((unsigned short)zservp->s_port); @@ -1844,6 +1845,7 @@ zftp_open(char *name, char **args, int flags) tcp_close(zfsess->control); zfsess->control = NULL; } + freehostent(zhostp); zfunsetparam("ZFTP_HOST"); zfunsetparam("ZFTP_PORT"); FAILED(); @@ -1862,16 +1864,17 @@ zftp_open(char *name, char **args, int flags) err = 1; /* try all possible IP's */ - for (zai = hostlist; err && zai; zai = zai->ai_next) { - if(hlen != zai->ai_addrlen) + for (addrp = zhostp->h_addr_list; err && *addrp; addrp++) { + if(hlen != zhostp->h_length) zwarnnam(name, "address length mismatch"); do { - err = tcp_connect(zfsess->control, zai); + err = tcp_connect(zfsess->control, *addrp, zhostp, zservp->s_port); } 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); @@ -1892,6 +1895,7 @@ 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 f86056ca5..e96b367f9 100644 --- a/Src/Modules/zftp.mdd +++ b/Src/Modules/zftp.mdd @@ -1,5 +1,5 @@ name=zsh/zftp -link=`if test x$ac_cv_func_getaddrinfo; then echo dynamic; else echo no; fi` +link=dynamic load=no functions='Functions/Zftp/*' -- cgit 1.4.1