1 $NetBSD: patch-aj,v 1.1 2000/01/15 17:44:22 hubertf Exp $
3 diff -x *.orig -urN ./WWW/Library/Implementation/HTFTP.c /usr/pkgsrc/www/lynx/work.unpatched/lynx2-8-2/WWW/Library/Implementation/HTFTP.c
4 --- ./WWW/Library/Implementation/HTFTP.c Tue May 25 19:13:02 1999
5 +++ /usr/pkgsrc/www/lynx/work.unpatched/lynx2-8-2/WWW/Library/Implementation/HTFTP.c Sat Jan 15 07:57:18 2000
6 @@ -1013,10 +1013,11 @@
8 PRIVATE int get_listen_socket NOARGS
10 - struct sockaddr_in soc_address; /* Binary network address */
11 - struct sockaddr_in* soc_in = &soc_address;
12 + struct sockaddr_storage soc_address; /* Binary network address */
13 + struct sockaddr_in* soc_in = (struct sockaddr_in *)&soc_address;
14 int new_socket; /* Will be master_socket */
19 FD_ZERO(&open_sockets); /* Clear our record of open sockets */
21 @@ -1026,9 +1027,18 @@
22 return master_socket; /* Done already */
23 #endif /* !REPEAT_LISTEN */
25 + /* query address family of control connection */
26 + slen = sizeof(soc_address);
27 + if (getsockname(control->socket, (struct sockaddr *)&soc_address,
29 + return HTInetStatus("getsockname failed");
31 + af = soc_address.ss_family;
32 + memset(&soc_address, 0, sizeof(soc_address));
34 /* Create internet socket
36 - new_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
37 + new_socket = socket(af, SOCK_STREAM, IPPROTO_TCP);
40 return HTInetStatus(gettext("socket for master socket"));
41 @@ -1037,8 +1047,24 @@
43 /* Search for a free port.
45 - soc_in->sin_family = AF_INET; /* Family = internet, host order */
46 - soc_in->sin_addr.s_addr = INADDR_ANY; /* Any peer address */
47 + memset(&soc_address, 0, sizeof(soc_address));
48 + soc_address.ss_family = af;
52 + soc_address.ss_len = sizeof(struct sockaddr_in);
58 + soc_address.ss_len = sizeof(struct sockaddr_in6);
67 unsigned short old_port_number = port_number;
68 @@ -1049,15 +1075,19 @@
69 if (port_number == old_port_number) {
70 return HTInetStatus("bind");
72 - soc_address.sin_port = htons(port_number);
73 + soc_in->sin_port = htons(port_number);
76 if ((status=Rbind(new_socket,
77 (struct sockaddr*)&soc_address,
78 /* Cast to generic sockaddr */
83 + SA_LEN((struct sockaddr *)&soc_address),
85 #ifndef SHORTENED_RBIND
86 - ,socks_bind_remoteAddr
87 + socks_bind_remoteAddr
88 #endif /* !SHORTENED_RBIND */
91 @@ -1066,7 +1096,12 @@
92 if ((status=bind(new_socket,
93 (struct sockaddr*)&soc_address,
94 /* Cast to generic sockaddr */
95 - sizeof(soc_address))) == 0)
99 + SA_LEN((struct sockaddr *)&soc_address)
103 CTRACE(tfp, "TCP bind attempt to port %d yields %d, errno=%d\n",
104 port_number, status, SOCKET_ERRNO);
105 @@ -1088,17 +1123,21 @@
106 (void *)&address_length);
107 if (status<0) return HTInetStatus("getsockname");
108 CTRACE(tfp, "HTFTP: This host is %s\n",
109 - HTInetString(soc_in));
110 + HTInetString((SockA *)soc_in));
112 - soc_address.sin_port = 0; /* Unspecified: please allocate */
113 + soc_in->sin_port = 0; /* Unspecified: please allocate */
116 status=Rbind(new_socket,
117 (struct sockaddr*)&soc_address,
118 /* Cast to generic sockaddr */
119 - sizeof(soc_address)
121 + soc_address.ss_len,
123 + SA_LEN((struct sockaddr *)&soc_address),
125 #ifndef SHORTENED_RBIND
126 - ,socks_bind_remoteAddr
127 + socks_bind_remoteAddr
128 #endif /* !SHORTENED_RBIND */
131 @@ -1106,7 +1145,12 @@
132 status=bind(new_socket,
133 (struct sockaddr*)&soc_address,
134 /* Cast to generic sockaddr */
135 - sizeof(soc_address));
139 + SA_LEN((struct sockaddr *)&soc_address)
142 if (status<0) return HTInetStatus("bind");
144 address_length = sizeof(soc_address);
145 @@ -1126,7 +1170,7 @@
147 CTRACE(tfp, "HTFTP: bound to port %d on %s\n",
148 (int)ntohs(soc_in->sin_port),
149 - HTInetString(soc_in));
150 + HTInetString((SockA *)soc_in));
153 if (master_socket >= 0)
154 @@ -1138,7 +1182,9 @@
155 /* Now we must find out who we are to tell the other guy
157 (void)HTHostName(); /* Make address valid - doesn't work*/
158 - sprintf(port_command, "PORT %d,%d,%d,%d,%d,%d%c%c",
159 + switch (soc_address.ss_family) {
161 + sprintf(port_command, "PORT %d,%d,%d,%d,%d,%d%c%c",
162 (int)*((unsigned char *)(&soc_in->sin_addr)+0),
163 (int)*((unsigned char *)(&soc_in->sin_addr)+1),
164 (int)*((unsigned char *)(&soc_in->sin_addr)+2),
165 @@ -1146,7 +1192,29 @@
166 (int)*((unsigned char *)(&soc_in->sin_port)+0),
167 (int)*((unsigned char *)(&soc_in->sin_port)+1),
174 + char hostbuf[MAXHOSTNAMELEN];
175 + char portbuf[MAXHOSTNAMELEN];
176 + getnameinfo((struct sockaddr *)&soc_address,
178 + soc_address.ss_len,
180 + SA_LEN((struct sockaddr *)&soc_address),
182 + hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
183 + NI_NUMERICHOST | NI_NUMERICSERV);
184 + sprintf(port_command, "EPRT |%d|%s|%s|%c%c", 2, hostbuf, portbuf,
190 + sprintf(port_command, "JUNK%c%c", CR, LF);
194 /* Inform TCP that we will accept connections
196 @@ -2594,7 +2662,8 @@
198 NETCLOSE (control->socket);
199 control->socket = -1;
200 - close_master_socket ();
201 + if (master_socket >= 0)
202 + (void)close_master_socket ();
203 /* HT_INTERRUPTED would fall through, if we could interrupt
204 somehow in the middle of it, which we currently can't. */
206 @@ -2631,26 +2700,50 @@
210 - status = send_cmd_1("PASV");
213 - continue; /* retry or Bad return */
214 - return -status; /* bad reply */
215 + status = send_cmd_1("EPSV");
216 + if (status < 0) /* retry or Bad return */
218 + else if (status != 2) {
219 + status = send_cmd_1("PASV");
220 + if (status < 0) /* retry or Bad return */
222 + else if (status != 2) {
223 + return -status; /* bad reply */
226 - for (p = response_text; *p && *p != ','; p++)
229 - while (--p > response_text && '0' <= *p && *p <= '9')
231 + if (strncmp(command, "PASV", 4) == 0) {
232 + for (p = response_text; *p && *p != ','; p++)
235 + while (--p > response_text && '0' <= *p && *p <= '9')
238 - status = sscanf(p+1, "%d,%d,%d,%d,%d,%d",
239 - &h0, &h1, &h2, &h3, &p0, &p1);
241 - fprintf(tfp, "HTFTP: PASV reply has no inet address!\n");
244 - passive_port = (p0<<8) + p1;
245 - CTRACE(tfp, "HTFTP: Server is listening on port %d\n",
246 + status = sscanf(p+1, "%d,%d,%d,%d,%d,%d",
247 + &h0, &h1, &h2, &h3, &p0, &p1);
249 + fprintf(tfp, "HTFTP: PASV reply has no inet address!\n");
252 + passive_port = (p0<<8) + p1;
253 + } else if (strncmp(command, "EPSV", 4) == 0) {
258 + for (p = response_text; *p && !isspace(*p); p++)
260 + for (p = response_text; *p && isspace(*p); p++)
262 + status = sscanf(p+1, "%c%c%c%d%c",
263 + &h0, &h1, &h2, &p0, &h3);
265 + fprintf(tfp, "HTFTP: EPSV reply has invalid format!\n");
270 + CTRACE(tfp, "HTFTP: Server is listening on port %d\n",
274 @@ -3162,7 +3255,7 @@
275 /* Wait for the connection
278 - struct sockaddr_in soc_address;
279 + struct sockaddr_storage soc_address;
280 int soc_addrlen=sizeof(soc_address);