1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
$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 <sys/socket.h>
+
+#ifdef FTPPASS_HOSTNAMEGEN
#include <netinet/in.h>
@@ -22,3 +23,8 @@
+#ifdef INET6
+#include <netdb.h>
+#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
|