+ return FTPLOGINC;
+ }
+ xfree (respline);
+ /* All OK. */
+ return FTPOK;
+}
+
+static void
+ip_address_to_port_repr (const ip_address *addr, int port, char *buf,
+ size_t buflen)
+{
+ unsigned char *ptr;
+
+ assert (addr->family == AF_INET);
+ /* buf must contain the argument of PORT (of the form a,b,c,d,e,f). */
+ assert (buflen >= 6 * 4);
+
+ ptr = IP_INADDR_DATA (addr);
+ snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d", ptr[0], ptr[1],
+ ptr[2], ptr[3], (port & 0xff00) >> 8, port & 0xff);
+ buf[buflen - 1] = '\0';
+}
+
+/* Bind a port and send the appropriate PORT command to the FTP
+ server. Use acceptport after RETR, to get the socket of data
+ connection. */
+uerr_t
+ftp_port (int csock, int *local_sock)
+{
+ uerr_t err;
+ char *request, *respline;
+ ip_address addr;
+ int nwritten;
+ int port;
+ /* Must contain the argument of PORT (of the form a,b,c,d,e,f). */
+ char bytes[6 * 4 + 1];
+
+ /* Get the address of this side of the connection. */
+ if (!socket_ip_address (csock, &addr, ENDPOINT_LOCAL))
+ return FTPSYSERR;
+
+ assert (addr.family == AF_INET);
+
+ /* Setting port to 0 lets the system choose a free port. */
+ port = 0;
+
+ /* Bind the port. */
+ *local_sock = bind_local (&addr, &port);
+ if (*local_sock < 0)
+ return FTPSYSERR;
+
+ /* Construct the argument of PORT (of the form a,b,c,d,e,f). */
+ ip_address_to_port_repr (&addr, port, bytes, sizeof (bytes));
+
+ /* Send PORT request. */
+ request = ftp_request ("PORT", bytes);
+ nwritten = fd_write (csock, request, strlen (request), -1);
+ if (nwritten < 0)
+ {
+ xfree (request);
+ fd_close (*local_sock);
+ return WRITEFAILED;
+ }
+ xfree (request);
+
+ /* Get appropriate response. */
+ err = ftp_response (csock, &respline);
+ if (err != FTPOK)
+ {
+ fd_close (*local_sock);