* always use getaddrinfo() and getnameinfo() instead of maintaining two code

paths. (lukemftp will provide replacements for these on older systems)
* rename __USE_SELECT to USE_SELECT
* rename BSD4_4 to HAVE_SIN_LEN
* replace union sockunion {} with struct sockinet {}, and modify the code
  accordingly. this is possibly more portable, as it doesn't rely upon the
  structure alignment within the union for our own stuff.
  (XXX: haven't tested the ipv6 stuff)
This commit is contained in:
lukem 2000-07-30 06:10:43 +00:00
parent 32ef6bb0e7
commit fad4243147
2 changed files with 46 additions and 200 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: fetch.c,v 1.119 2000/07/30 04:42:37 lukem Exp $ */
/* $NetBSD: fetch.c,v 1.120 2000/07/30 06:10:43 lukem Exp $ */
/*-
* Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
@ -41,7 +41,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fetch.c,v 1.119 2000/07/30 04:42:37 lukem Exp $");
__RCSID("$NetBSD: fetch.c,v 1.120 2000/07/30 06:10:43 lukem Exp $");
#endif /* not lint */
/*
@ -435,14 +435,9 @@ sigjmp_buf httpabort;
static int
fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
{
#if defined(NI_NUMERICHOST) && defined(INET6)
struct addrinfo hints, *res, *res0 = NULL;
int error;
char hbuf[NI_MAXHOST];
#else
struct sockaddr_in sin;
struct hostent *hp = NULL;
#endif
volatile sigfunc oldintr, oldintp;
volatile int s;
struct stat sb;
@ -656,66 +651,6 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
}
} /* ! EMPTYSTRING(proxyenv) */
#if !defined(NI_NUMERICHOST) || !defined(INET6)
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if (isdigit((unsigned char)host[0])) {
if (inet_aton(host, &sin.sin_addr) == 0) {
warnx("Invalid IP address `%s'", host);
goto cleanup_fetch_url;
}
} else {
hp = gethostbyname(host);
if (hp == NULL) {
warnx("%s: %s", host, hstrerror(h_errno));
goto cleanup_fetch_url;
}
if (hp->h_addrtype != AF_INET) {
warnx("`%s': not an Internet address?", host);
goto cleanup_fetch_url;
}
if (hp->h_length > sizeof(sin.sin_addr))
hp->h_length = sizeof(sin.sin_addr);
memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
}
sin.sin_port = htons(portnum);
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) {
warn("Can't create socket");
goto cleanup_fetch_url;
}
while (xconnect(s, (struct sockaddr *)&sin,
sizeof(sin)) == -1) {
if (errno == EINTR)
continue;
if (hp && hp->h_addr_list[1]) {
int oerrno = errno;
char *ia;
ia = inet_ntoa(sin.sin_addr);
errno = oerrno;
warn("Connect to address `%s'", ia);
hp->h_addr_list++;
memcpy(&sin.sin_addr, hp->h_addr_list[0],
(size_t)hp->h_length);
if (verbose)
fprintf(ttyout, "Trying %s...\n",
inet_ntoa(sin.sin_addr));
(void)close(s);
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
warn("Can't create socket");
goto cleanup_fetch_url;
}
continue;
}
warn("Can't connect to `%s'", host);
goto cleanup_fetch_url;
}
#else
memset(&hints, 0, sizeof(hints));
hints.ai_flags = 0;
hints.ai_family = AF_UNSPEC;
@ -766,7 +701,6 @@ fetch_url(const char *url, const char *proxyenv, char *proxyauth, char *wwwauth)
warn("Can't connect to %s", host);
goto cleanup_fetch_url;
}
#endif
fin = fdopen(s, "r+");
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: ftp.c,v 1.103 2000/07/30 04:42:37 lukem Exp $ */
/* $NetBSD: ftp.c,v 1.104 2000/07/30 06:10:44 lukem Exp $ */
/*-
* Copyright (c) 1996-2000 The NetBSD Foundation, Inc.
@ -103,7 +103,7 @@
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
#else
__RCSID("$NetBSD: ftp.c,v 1.103 2000/07/30 04:42:37 lukem Exp $");
__RCSID("$NetBSD: ftp.c,v 1.104 2000/07/30 06:10:44 lukem Exp $");
#endif
#endif /* not lint */
@ -129,7 +129,7 @@ __RCSID("$NetBSD: ftp.c,v 1.103 2000/07/30 04:42:37 lukem Exp $");
#include <time.h>
#include <unistd.h>
#include <stdarg.h>
#ifndef __USE_SELECT
#ifndef USE_SELECT
#include <poll.h>
#endif
@ -144,56 +144,37 @@ char pasv[BUFSIZ]; /* passive port for proxy data connection */
static int empty(FILE *, FILE *, int);
union sockunion {
struct sockinet {
#ifdef BSD4_4
u_char si_len;
u_char si_family;
#else
u_short si_family;
#endif
u_short si_port;
#ifndef BSD4_4
u_char si_pad[
struct sockinet {
union sockunion {
struct sockaddr_in su_sin;
#ifdef INET6
sizeof(struct sockaddr_in6)
#else
sizeof(struct sockaddr_in)
struct sockaddr_in6 su_sin6;
#endif
- sizeof(u_int)];
u_char si_len;
#endif
} su_si;
struct sockaddr_in su_sin;
#ifdef INET6
struct sockaddr_in6 su_sin6;
} si_su;
#ifndef HAVE_SIN_LEN
int si_len;
#endif
};
#define su_len su_si.si_len
#define su_family su_si.si_family
#define su_port su_si.si_port
#ifndef HAVE_SIN_LEN
# define su_len si_len
#else
# define su_len si_su.su_sin.sin_len
#endif
#define su_family si_su.su_sin.sin_family
#define su_port si_su.su_sin.sin_port
union sockunion myctladdr, hisctladdr, data_addr;
struct sockinet myctladdr, hisctladdr, data_addr;
char *
hookup(char *host, char *port)
{
int s = -1, len, error;
#if defined(NI_NUMERICHOST) && defined(INET6)
struct addrinfo hints, *res, *res0;
char hbuf[MAXHOSTNAMELEN];
#else
struct hostent *hp = NULL;
char **ptr, *ep;
struct sockaddr_in sin;
long nport;
#endif
static char hostnamebuf[MAXHOSTNAMELEN];
char *cause = "unknown";
int family;
#if defined(NI_NUMERICHOST) && defined(INET6)
memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
@ -276,84 +257,14 @@ hookup(char *host, char *port)
freeaddrinfo(res0);
return 0;
}
memcpy(&hisctladdr, res->ai_addr, res->ai_addrlen);
len = res->ai_addrlen;
memcpy(&hisctladdr.si_su, res->ai_addr, res->ai_addrlen);
hisctladdr.su_len = res->ai_addrlen;
len = hisctladdr.su_len;
freeaddrinfo(res0);
res0 = res = NULL;
family = hisctladdr.su_family;
#else
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if ((hp = gethostbyname(host)) == NULL) {
warnx("%s: %s", host, hstrerror(h_errno));
code = -1;
return 0;
}
nport = strtol(port, &ep, 10);
if (*ep != '\0' && ep == port) {
struct servent *svp;
svp = getservbyname(port, "tcp");
if (svp == NULL) {
warnx("hookup: unknown port `%s'", port);
sin.sin_port = htons(FTP_PORT);
} else
sin.sin_port = svp->s_port;
} else if (nport < 1 || nport > MAX_IN_PORT_T || *ep != '\0') {
warnx("hookup: invalid port `%s'", port);
sin.sin_port = htons(FTP_PORT);
} else
sin.sin_port = htons(nport);
(void)strlcpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
hostname = hostnamebuf;
if (hp->h_length > sizeof(sin.sin_addr))
hp->h_length = sizeof(sin.sin_addr);
for (ptr = hp->h_addr_list; *ptr; ptr++) {
memcpy(&sin.sin_addr, *ptr, (size_t)hp->h_length);
if (hp->h_addr_list[1])
fprintf(ttyout, "Trying %s...\n",
inet_ntoa(sin.sin_addr));
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
cause = "socket";
continue;
}
while ((error = xconnect(s, (struct sockaddr *)&sin,
sizeof(sin))) < 0 && errno == EINTR) {
;
}
if (error) {
/* this "if" clause is to prevent print warning twice */
if (hp->h_addr_list[1]) {
warn("connect to address %s",
inet_ntoa(sin.sin_addr));
}
cause = "connect";
close(s);
s = -1;
continue;
}
/* finally we got one */
break;
}
if (s < 0) {
warn("%s", cause);
code = -1;
return 0;
}
memcpy(&hisctladdr, &sin, sizeof(sin));
len = sizeof(sin);
if (hisctladdr.su_len == 0)
hisctladdr.su_len = len;
family = AF_INET;
#endif
if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
memset((char *)&myctladdr, 0, sizeof (myctladdr));
if (getsockname(s, (struct sockaddr *)&myctladdr.si_su, &len) < 0) {
warn("getsockname");
code = -1;
goto bad;
@ -362,7 +273,7 @@ hookup(char *host, char *port)
myctladdr.su_len = len;
#ifdef IPTOS_LOWDELAY
if (family == AF_INET) {
if (hisctladdr.su_family == AF_INET) {
int tos = IPTOS_LOWDELAY;
if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos,
sizeof(int)) < 0)
@ -631,7 +542,7 @@ empty(FILE *cin, FILE *din, int sec)
int nr;
int nfd = 0;
#ifdef __USE_SELECT
#ifdef USE_SELECT
struct timeval t;
fd_set rmask;
@ -1398,8 +1309,8 @@ initconn(void)
#ifdef INET6
if (myctladdr.su_family == AF_INET6 && debug &&
(IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr) ||
IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) {
(IN6_IS_ADDR_LINKLOCAL(&myctladdr.si_su.su_sin6.sin6_addr) ||
IN6_IS_ADDR_SITELOCAL(&myctladdr.si_su.su_sin6.sin6_addr))) {
warnx("use of scoped address can be troublesome");
}
#endif
@ -1519,8 +1430,8 @@ initconn(void)
memset(&data_addr, 0, sizeof(data_addr));
data_addr.su_family = AF_INET;
data_addr.su_len = sizeof(struct sockaddr_in);
data_addr.su_sin.sin_addr.s_addr =
htonl(pack4(addr, 0));
data_addr.si_su.su_sin.sin_addr.s_addr =
htonl(pack4(addr, 0));
data_addr.su_port = htons(pack2(port, 0));
} else if (strcmp(pasvcmd, "LPSV") == 0) {
if (code / 10 == 22 && code != 228) {
@ -1553,8 +1464,8 @@ initconn(void)
memset(&data_addr, 0, sizeof(data_addr));
data_addr.su_family = AF_INET;
data_addr.su_len = sizeof(struct sockaddr_in);
data_addr.su_sin.sin_addr.s_addr =
htonl(pack4(addr, 0));
data_addr.si_su.su_sin.sin_addr.s_addr =
htonl(pack4(addr, 0));
data_addr.su_port = htons(pack2(port, 0));
break;
#ifdef INET6
@ -1588,7 +1499,7 @@ initconn(void)
{
int i;
for (i = 0; i < sizeof(struct in6_addr); i++) {
data_addr.su_sin6.sin6_addr.s6_addr[i] =
data_addr.si_su.su_sin6.sin6_addr.s6_addr[i] =
UC(addr[i]);
}
}
@ -1626,7 +1537,7 @@ initconn(void)
} else
goto bad;
while (xconnect(data, (struct sockaddr *)&data_addr,
while (xconnect(data, (struct sockaddr *)&data_addr.si_su,
data_addr.su_len) < 0) {
if (errno == EINTR)
continue;
@ -1672,7 +1583,8 @@ initconn(void)
warn("setsockopt (reuse address)");
goto bad;
}
if (bind(data, (struct sockaddr *)&data_addr, data_addr.su_len) < 0) {
if (bind(data, (struct sockaddr *)&data_addr.si_su,
data_addr.su_len) < 0) {
warn("bind");
goto bad;
}
@ -1680,8 +1592,8 @@ initconn(void)
setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
sizeof(on)) < 0)
warn("setsockopt (ignored)");
len = sizeof(data_addr);
if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
len = sizeof(data_addr.si_su); /* XXXLUKEM */
if (getsockname(data, (struct sockaddr *)&data_addr.si_su, &len) < 0) {
warn("getsockname");
goto bad;
}
@ -1704,7 +1616,7 @@ initconn(void)
#ifdef INET6
case AF_INET6:
af = (data_addr.su_family == AF_INET) ? 1 : 2;
if (getnameinfo((struct sockaddr *)&data_addr,
if (getnameinfo((struct sockaddr *)&data_addr.si_su,
data_addr.su_len, hname, sizeof(hname),
NULL, 0, NI_NUMERICHOST)) {
result = ERROR;
@ -1732,7 +1644,7 @@ initconn(void)
switch (data_addr.su_family) {
case AF_INET:
a = (char *)&data_addr.su_sin.sin_addr;
a = (char *)&data_addr.si_su.su_sin.sin_addr;
p = (char *)&data_addr.su_port;
result = command("PORT %d,%d,%d,%d,%d,%d",
UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
@ -1740,7 +1652,7 @@ initconn(void)
break;
#ifdef INET6
case AF_INET6:
a = (char *)&data_addr.su_sin6.sin6_addr;
a = (char *)&data_addr.si_su.su_sin6.sin6_addr;
p = (char *)&data_addr.su_port;
result = command(
"LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
@ -1787,7 +1699,7 @@ initconn(void)
FILE *
dataconn(const char *lmode)
{
union sockunion from;
struct sockinet from;
int s, fromlen = myctladdr.su_len;
if (passivemode)
@ -1830,8 +1742,8 @@ pswitch(int flag)
static struct comvars {
int connect;
char name[MAXHOSTNAMELEN];
union sockunion mctl;
union sockunion hctl;
struct sockinet mctl;
struct sockinet hctl;
FILE *in;
FILE *out;
int tpe;
@ -2207,7 +2119,7 @@ ai_unmapped(struct addrinfo *ai)
sin.sin_port = sin6->sin6_port;
ai->ai_family = AF_INET;
#ifdef BSD4_4
#ifdef HAVE_SIN_LEN
sin.sin_len = len;
#endif
memcpy(ai->ai_addr, &sin, len);