summaryrefslogtreecommitdiff
path: root/Src/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Modules')
-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
4 files changed, 127 insertions, 51 deletions
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/*'