Index: curl-7.19.7/lib/select.c
===================================================================
--- curl-7.19.7.orig/lib/select.c	2009-10-28 21:21:58.000000000 +0100
+++ curl-7.19.7/lib/select.c	2015-09-18 16:59:18.951708649 +0200
@@ -142,11 +142,11 @@ static int wait_ms(int timeout_ms)
 }
 
 /*
- * This is an internal function used for waiting for read or write
- * events on a pair of file descriptors.  It uses poll() when a fine
- * poll() is available, in order to avoid limits with FD_SETSIZE,
- * otherwise select() is used.  An error is returned if select() is
- * being used and a file descriptor is too large for FD_SETSIZE.
+ * Wait for read or write events on a set of file descriptors. It uses poll()
+ * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
+ * otherwise select() is used.  An error is returned if select() is being used
+ * and a file descriptor is too large for FD_SETSIZE.
+ *
  * A negative timeout value makes this function wait indefinitely,
  * unles no valid file descriptor is given, when this happens the
  * negative timeout is ignored and the function times out immediately.
@@ -157,10 +157,17 @@ static int wait_ms(int timeout_ms)
  * Return values:
  *   -1 = system call error or fd >= FD_SETSIZE
  *    0 = timeout
- *    CURL_CSELECT_IN | CURL_CSELECT_OUT | CURL_CSELECT_ERR
+ *    [bitmask] = action as described below
+ *
+ * CURL_CSELECT_IN - first socket is readable
+ * CURL_CSELECT_IN2 - second socket is readable
+ * CURL_CSELECT_OUT - write socket is writable
+ * CURL_CSELECT_ERR - an error condition occurred
  */
-int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
-                      int timeout_ms)
+int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
+                      curl_socket_t readfd1,
+                      curl_socket_t writefd, /* socket to write to */
+                      long timeout_ms)       /* milliseconds to wait */
 {
 #ifdef HAVE_POLL_FINE
   struct pollfd pfd[2];
@@ -179,7 +186,9 @@ int Curl_socket_ready(curl_socket_t read
   int r;
   int ret;
 
-  if((readfd == CURL_SOCKET_BAD) && (writefd == CURL_SOCKET_BAD)) {
+  if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
+     (writefd == CURL_SOCKET_BAD)) {
+    /* no sockets, just wait */
     r = wait_ms(timeout_ms);
     return r;
   }
@@ -197,8 +206,14 @@ int Curl_socket_ready(curl_socket_t read
 #ifdef HAVE_POLL_FINE
 
   num = 0;
-  if(readfd != CURL_SOCKET_BAD) {
-    pfd[num].fd = readfd;
+  if(readfd0 != CURL_SOCKET_BAD) {
+    pfd[num].fd = readfd0;
+    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
+    pfd[num].revents = 0;
+    num++;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    pfd[num].fd = readfd1;
     pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
     pfd[num].revents = 0;
     num++;
@@ -235,13 +250,20 @@ int Curl_socket_ready(curl_socket_t read
 
   ret = 0;
   num = 0;
-  if(readfd != CURL_SOCKET_BAD) {
+  if(readfd0 != CURL_SOCKET_BAD) {
     if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
       ret |= CURL_CSELECT_IN;
     if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
       ret |= CURL_CSELECT_ERR;
     num++;
   }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
+      ret |= CURL_CSELECT_IN2;
+    if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
+      ret |= CURL_CSELECT_ERR;
+    num++;
+  }
   if(writefd != CURL_SOCKET_BAD) {
     if(pfd[num].revents & (POLLWRNORM|POLLOUT))
       ret |= CURL_CSELECT_OUT;
@@ -257,11 +279,18 @@ int Curl_socket_ready(curl_socket_t read
   maxfd = (curl_socket_t)-1;
 
   FD_ZERO(&fds_read);
-  if(readfd != CURL_SOCKET_BAD) {
-    VERIFY_SOCK(readfd);
-    FD_SET(readfd, &fds_read);
-    FD_SET(readfd, &fds_err);
-    maxfd = readfd;
+  if(readfd0 != CURL_SOCKET_BAD) {
+    VERIFY_SOCK(readfd0);
+    FD_SET(readfd0, &fds_read);
+    FD_SET(readfd0, &fds_err);
+    maxfd = readfd0;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    VERIFY_SOCK(readfd1);
+    FD_SET(readfd1, &fds_read);
+    FD_SET(readfd1, &fds_err);
+    if(readfd1 > maxfd)
+      maxfd = readfd1;
   }
 
   FD_ZERO(&fds_write);
@@ -303,10 +332,16 @@ int Curl_socket_ready(curl_socket_t read
     return 0;
 
   ret = 0;
-  if(readfd != CURL_SOCKET_BAD) {
-    if(FD_ISSET(readfd, &fds_read))
+  if(readfd0 != CURL_SOCKET_BAD) {
+    if(FD_ISSET(readfd0, &fds_read))
       ret |= CURL_CSELECT_IN;
-    if(FD_ISSET(readfd, &fds_err))
+    if(FD_ISSET(readfd0, &fds_err))
+      ret |= CURL_CSELECT_ERR;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    if(FD_ISSET(readfd1, &fds_read))
+      ret |= CURL_CSELECT_IN2;
+    if(FD_ISSET(readfd1, &fds_err))
       ret |= CURL_CSELECT_ERR;
   }
   if(writefd != CURL_SOCKET_BAD) {
Index: curl-7.19.7/lib/select.h
===================================================================
--- curl-7.19.7.orig/lib/select.h	2008-07-10 22:57:44.000000000 +0200
+++ curl-7.19.7/lib/select.h	2015-09-18 16:59:18.951708649 +0200
@@ -85,8 +85,18 @@ struct pollfd
 #define POLLRDBAND POLLPRI
 #endif
 
-int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
-                      int timeout_ms);
+/* there are three CSELECT defines that are defined in the public header that
+   are exposed to users, but this *IN2 bit is only ever used internally and
+   therefore defined here */
+#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
+
+int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
+                      curl_socket_t writefd,
+                       long timeout_ms);
+
+/* provide the former API internally */
+#define Curl_socket_ready(x,y,z) \
+  Curl_socket_check(x, CURL_SOCKET_BAD, y, z)
 
 int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
 
Index: curl-7.19.7/lib/ftp.c
===================================================================
--- curl-7.19.7.orig/lib/ftp.c	2009-09-20 13:52:15.000000000 +0200
+++ curl-7.19.7/lib/ftp.c	2015-09-18 16:59:18.951708649 +0200
@@ -307,16 +307,31 @@ static bool isBadFtpString(const char *s
 static CURLcode AllowServerConnect(struct connectdata *conn)
 {
   struct SessionHandle *data = conn->data;
-  curl_socket_t sock = conn->sock[SECONDARYSOCKET];
-  long timeout_ms = Curl_timeleft(conn, NULL, TRUE);
+  curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
+  curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
+  long timeout_ms;
+  int result;
+  ssize_t nread;
+  int ftpcode;
 
+  timeout_ms = Curl_timeleft(conn, NULL, TRUE);
   if(timeout_ms < 0) {
     /* if a timeout was already reached, bail out */
     failf(data, "Timed out before server could connect to us");
     return CURLE_OPERATION_TIMEDOUT;
   }
 
-  switch (Curl_socket_ready(sock, CURL_SOCKET_BAD, (int)timeout_ms)) {
+  /* First check whether there is a cached response from server */
+  if(conn->proto.ftpc.cache_size && conn->proto.ftpc.cache && conn->proto.ftpc.cache[0] > '3') {
+    /* Data connection could not be established, let's return */
+    infof(data, "There is negative response in cache while serv connect\n");
+    Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, (int)timeout_ms);
+
+  switch (result) {
   case -1: /* error */
     /* let's die here */
     failf(data, "Error while waiting for server connect");
@@ -336,12 +351,21 @@ static CURLcode AllowServerConnect(struc
 #endif
       curl_socklen_t size = (curl_socklen_t) sizeof(add);
 
-      if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
+      /* check data on ctrl connection */
+      if(result & CURL_CSELECT_IN) {
+        infof(data, "Ctrl conn has data while waiting for data conn\n");
+        Curl_GetFTPResponse(&nread, conn, &ftpcode);
+
+        if(ftpcode/100 > 3)
+          return CURLE_FTP_PORT_FAILED;
+      }
+
+      if(0 == getsockname(data_sock, (struct sockaddr *) &add, &size)) {
         size = sizeof(add);
 
-        s=accept(sock, (struct sockaddr *) &add, &size);
+        s=accept(data_sock, (struct sockaddr *) &add, &size);
       }
-      sclose(sock); /* close the first socket */
+      sclose(data_sock); /* close the first socket */
 
       if(CURL_SOCKET_BAD == s) {
         /* DIE! */
