Merge from vendor branch TNF:
[pkgsrcv2.git] / www / lynx / patches.v6 / patch-aj
1 $NetBSD: patch-aj,v 1.1 2000/01/15 17:44:22 hubertf Exp $
2
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 @@
7  */
8  PRIVATE int get_listen_socket NOARGS
9  {
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 */
15 -
16 +    int af;
17 +    int slen;
18  
19      FD_ZERO(&open_sockets);    /* Clear our record of open sockets */
20      num_sockets = 0;
21 @@ -1026,9 +1027,18 @@
22         return master_socket;  /* Done already */
23  #endif /* !REPEAT_LISTEN */
24  
25 +    /* query address family of control connection */
26 +    slen = sizeof(soc_address);
27 +    if (getsockname(control->socket, (struct sockaddr *)&soc_address,
28 +               &slen) < 0) {
29 +       return HTInetStatus("getsockname failed");
30 +    }
31 +    af = soc_address.ss_family;
32 +    memset(&soc_address, 0, sizeof(soc_address));
33 +
34  /*  Create internet socket
35  */
36 -    new_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
37 +    new_socket = socket(af, SOCK_STREAM, IPPROTO_TCP);
38  
39      if (new_socket < 0)
40         return HTInetStatus(gettext("socket for master socket"));
41 @@ -1037,8 +1047,24 @@
42  
43  /*  Search for a free port.
44  */
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;
49 +    switch (af) {
50 +    case AF_INET:
51 +#ifdef SIN6_LEN
52 +       soc_address.ss_len = sizeof(struct sockaddr_in);
53 +#endif
54 +       break;
55 +#ifdef INET6
56 +    case AF_INET6:
57 +#ifdef SIN6_LEN
58 +       soc_address.ss_len = sizeof(struct sockaddr_in6);
59 +#endif
60 +       break;
61 +#endif
62 +    default:
63 +       HTInetStatus("AF");
64 +    }
65  #ifdef POLL_PORTS
66      {
67         unsigned short old_port_number = port_number;
68 @@ -1049,15 +1075,19 @@
69             if (port_number == old_port_number) {
70                 return HTInetStatus("bind");
71             }
72 -           soc_address.sin_port = htons(port_number);
73 +           soc_in->sin_port = htons(port_number);
74  #ifdef SOCKS
75             if (socks_flag)
76                 if ((status=Rbind(new_socket,
77                         (struct sockaddr*)&soc_address,
78                             /* Cast to generic sockaddr */
79 -                       sizeof(soc_address)
80 +#ifdef SIN6_LEN
81 +                       soc_address.ss_len,
82 +#else
83 +                       SA_LEN((struct sockaddr *)&soc_address),
84 +#endif
85  #ifndef SHORTENED_RBIND
86 -                       ,socks_bind_remoteAddr
87 +                       socks_bind_remoteAddr
88  #endif /* !SHORTENED_RBIND */
89                                                 )) == 0)
90                     break;
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)
96 +#ifdef SIN6_LEN
97 +                   soc_address.ss_len
98 +#else
99 +                   SA_LEN((struct sockaddr *)&soc_address)
100 +#endif
101 +                   )) == 0)
102                 break;
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));
111  
112 -       soc_address.sin_port = 0;       /* Unspecified: please allocate */
113 +       soc_in->sin_port = 0;   /* Unspecified: please allocate */
114  #ifdef SOCKS
115         if (socks_flag)
116             status=Rbind(new_socket,
117                          (struct sockaddr*)&soc_address,
118                          /* Cast to generic sockaddr */
119 -                        sizeof(soc_address)
120 +#ifdef SIN6_LEN
121 +                        soc_address.ss_len,
122 +#else
123 +                        SA_LEN((struct sockaddr *)&soc_address),
124 +#endif
125  #ifndef SHORTENED_RBIND
126 -                       ,socks_bind_remoteAddr
127 +                       socks_bind_remoteAddr
128  #endif /* !SHORTENED_RBIND */
129                                                 );
130         else
131 @@ -1106,7 +1145,12 @@
132         status=bind(new_socket,
133                     (struct sockaddr*)&soc_address,
134                     /* Cast to generic sockaddr */
135 -                   sizeof(soc_address));
136 +#ifdef SIN6_LEN
137 +                   soc_address.ss_len
138 +#else
139 +                   SA_LEN((struct sockaddr *)&soc_address)
140 +#endif
141 +                   );
142         if (status<0) return HTInetStatus("bind");
143  
144         address_length = sizeof(soc_address);
145 @@ -1126,7 +1170,7 @@
146  
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));
151  
152  #ifdef REPEAT_LISTEN
153      if (master_socket >= 0)
154 @@ -1138,7 +1182,9 @@
155  /*     Now we must find out who we are to tell the other guy
156  */
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) {
160 +    case AF_INET:
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),
168                     CR, LF);
169 -
170 +       break;
171 +#ifdef INET6
172 +    case AF_INET6:
173 +      {
174 +       char hostbuf[MAXHOSTNAMELEN];
175 +       char portbuf[MAXHOSTNAMELEN];
176 +       getnameinfo((struct sockaddr *)&soc_address,
177 +#ifdef SIN6_LEN
178 +           soc_address.ss_len,
179 +#else
180 +           SA_LEN((struct sockaddr *)&soc_address),
181 +#endif
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,
185 +               CR, LF);
186 +       break;
187 +      }
188 +#endif
189 +    default:
190 +       sprintf(port_command, "JUNK%c%c", CR, LF);
191 +       break;
192 +    }
193  
194  /*     Inform TCP that we will accept connections
195  */
196 @@ -2594,7 +2662,8 @@
197         if (status < 0) {
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. */
205             return status;
206 @@ -2631,26 +2700,50 @@
207             int status;
208             data_soc = status;
209  
210 -           status = send_cmd_1("PASV");
211 -           if (status != 2) {
212 -               if (status < 0)
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 */
217 +               continue;
218 +           else if (status != 2) {
219 +               status = send_cmd_1("PASV");
220 +               if (status < 0) /* retry or Bad return */
221 +                   continue;
222 +               else if (status != 2) {
223 +                   return -status;     /* bad reply */
224 +               }
225             }
226 -           for (p = response_text; *p && *p != ','; p++)
227 -               ; /* null body */
228  
229 -           while (--p > response_text && '0' <= *p && *p <= '9')
230 -               ; /* null body */
231 +           if (strncmp(command, "PASV", 4) == 0) {
232 +               for (p = response_text; *p && *p != ','; p++)
233 +                   ; /* null body */
234 +
235 +               while (--p > response_text && '0' <= *p && *p <= '9')
236 +                   ; /* null body */
237  
238 -          status = sscanf(p+1, "%d,%d,%d,%d,%d,%d",
239 -                  &h0, &h1, &h2, &h3, &p0, &p1);
240 -          if (status < 4) {
241 -              fprintf(tfp, "HTFTP: PASV reply has no inet address!\n");
242 -              return -99;
243 -          }
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);
248 +              if (status < 4) {
249 +                  fprintf(tfp, "HTFTP: PASV reply has no inet address!\n");
250 +                  return -99;
251 +              }
252 +              passive_port = (p0<<8) + p1;
253 +           } else if (strncmp(command, "EPSV", 4) == 0) {
254 +               char ch;
255 +               /*
256 +                * EPSV |||port|
257 +                */
258 +               for (p = response_text; *p && !isspace(*p); p++)
259 +                   ; /* null body */
260 +               for (p = response_text; *p && isspace(*p); p++)
261 +                   ; /* null body */
262 +               status = sscanf(p+1, "%c%c%c%d%c",
263 +                      &h0, &h1, &h2, &p0, &h3);
264 +               if (status != 5) {
265 +                   fprintf(tfp, "HTFTP: EPSV reply has invalid format!\n");
266 +                   return -99;
267 +               }
268 +               passive_port = p0;
269 +           }
270 +           CTRACE(tfp, "HTFTP: Server is listening on port %d\n",
271                         passive_port);
272  
273  
274 @@ -3162,7 +3255,7 @@
275  /*     Wait for the connection
276  */
277      {
278 -       struct sockaddr_in soc_address;
279 +       struct sockaddr_storage soc_address;
280         int     soc_addrlen=sizeof(soc_address);
281  #ifdef SOCKS
282         if (socks_flag)