$NetBSD: patch-ae,v 1.3 2000/08/16 00:31:34 itojun Exp $ Index: ftp.c =================================================================== RCS file: /cvsroot/apps/w3m/ftp.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -1 -r1.1 -r1.2 --- ftp.c 2000/08/15 23:53:35 1.1 +++ ftp.c 2000/08/16 00:28:03 1.2 @@ -15,4 +15,5 @@ -#ifdef FTPPASS_HOSTNAMEGEN #include + +#ifdef FTPPASS_HOSTNAMEGEN #include @@ -22,3 +23,8 @@ +#ifdef INET6 +#include +#endif + typedef struct _FTP { + int family; FILE *rcontrol; @@ -105,2 +111,8 @@ Str tmp; +#ifdef INET6 + struct sockaddr_storage ss; +#else + struct sockaddr ss; +#endif + int sslen; FTP ftp = New(struct _FTP); @@ -116,3 +128,7 @@ if (n > 0 && pass[n - 1] == '@') { +#ifdef INET6 + struct sockaddr_storage sockname; +#else struct sockaddr_in sockname; +#endif int socknamelen = sizeof(sockname); @@ -120,5 +136,19 @@ if (!getsockname(fd, (struct sockaddr *) &sockname, &socknamelen)) { +#ifdef INET6 + char hbuf[NI_MAXHOST]; +#else struct hostent *sockent; +#endif Str tmp2 = Strnew_charp(pass); +#ifdef INET6 + if (getnameinfo((struct sockaddr *)&sockname, socknamelen, + hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) == 0) { + Strcat_charp(tmp2, hbuf); + } else if (getnameinfo((struct sockaddr *)&sockname, socknamelen, + hbuf, sizeof(hbuf), NULL, 0, 0) == 0) { + Strcat_m_charp(tmp2, "[", hbuf, "]", NULL); + } else + Strcat_charp(tmp2, "invalid"); +#else if (sockent = gethostbyaddr((char *) &sockname.sin_addr, @@ -129,2 +159,3 @@ Strcat_m_charp(tmp2, "[", inet_ntoa(sockname.sin_addr), "]", NULL); +#endif @@ -135,2 +166,8 @@ #endif + sslen = sizeof(ss); + if (getsockname(fd, (struct sockaddr *)&ss, &sslen) < 0) { + close(fd); + return -1; + } + ftp->family = ((struct sockaddr *)&ss)->sa_family; ftp->rcontrol = fdopen(fd, "rb"); @@ -176,3 +213,46 @@ +#ifdef INET6 int +ftp_epsv(FTP ftp) +{ + int port; + int data_s; + char *p; + Str tmp; + char hbuf[NI_MAXHOST]; + struct sockaddr_storage ss; + int sslen; + + sslen = sizeof(ss); + if (getpeername(fileno(ftp->wcontrol), (struct sockaddr *)&ss, &sslen) < 0) + return -1; + if (getnameinfo((struct sockaddr *)&ss, ((struct sockaddr *)&ss)->sa_len, + hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) { + return -1; + } + + fwrite("EPSV\r\n", 6, sizeof(char), ftp->wcontrol); + fflush(ftp->wcontrol); + tmp = read_response(ftp); + if (atoi(tmp->ptr) != 229) + return -1; + for (p = tmp->ptr + 4; *p && *p != '('; p++); /*)*/ + if (*p == '\0') + return -1; + p++; + /* find "|||port|" */ + if (p[0] && p[0] == p[1] && p[0] == p[2]) + p += 3; + else + return -1; + sscanf(p, "%d", &port); + data_s = openSocket(hbuf, "", port); + if (data_s < 0) + return -1; + ftp->data = fdopen(data_s, "rb"); + return 0; +} +#endif + +int ftp_pasv(FTP ftp) @@ -183,2 +263,9 @@ Str tmp; + +#ifdef INET6 + if (ftp->family == AF_INET6 || ftp->family == AF_INET) { + if (ftp_epsv(ftp) == 0) + return 0; + } +#endif