ftp: move create control connection to function
authorLukasz Marek <lukasz.m.luki@gmail.com>
Thu, 30 May 2013 13:22:13 +0000 (15:22 +0200)
committerLukasz Marek <lukasz.m.luki@gmail.com>
Fri, 31 May 2013 13:57:58 +0000 (15:57 +0200)
Move common code that opens control connection to function.
This code can be reused when reconnecting to FTP server
after inactivity.

libavformat/ftp.c

index 50c0929..da9408a 100644 (file)
@@ -48,6 +48,7 @@ typedef struct {
     uint8_t control_buffer[CONTROL_BUFFER_SIZE]; /**< Control connection buffer */
     uint8_t *control_buf_ptr, *control_buf_end;
     int server_data_port;                        /**< Data connection port opened by server, -1 on error. */
+    int server_control_port;                     /**< Control connection port, default is 21 */
     char hostname[512];                          /**< Server address. */
     char credencials[CREDENTIALS_BUFFER_SIZE];   /**< Authentication data */
     char path[MAX_URL_SIZE];                     /**< Path to resource on server. */
@@ -378,7 +379,51 @@ static int ftp_type(FTPContext *s)
     return 0;
 }
 
-static int ftp_reconnect_data_connection(URLContext *h)
+static int ftp_connect_control_connection(URLContext *h)
+{
+    char buf[CONTROL_BUFFER_SIZE], opts_format[20];
+    int err;
+    AVDictionary *opts = NULL;
+    FTPContext *s = h->priv_data;
+
+    s->conn_control_block_flag = 0;
+
+    if (!s->conn_control) {
+        ff_url_join(buf, sizeof(buf), "tcp", NULL,
+                    s->hostname, s->server_control_port, NULL);
+        if (s->rw_timeout != -1) {
+            snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
+            av_dict_set(&opts, "timeout", opts_format, 0);
+        } /* if option is not given, don't pass it and let tcp use its own default */
+        err = ffurl_open(&s->conn_control, buf, AVIO_FLAG_READ_WRITE,
+                         &s->conn_control_interrupt_cb, &opts);
+        av_dict_free(&opts);
+        if (err < 0) {
+            av_dlog(h, "Cannot open control connection, error %d\n", err);
+            return err;
+        }
+
+        /* consume all messages from server */
+        if (ftp_status(s, NULL, NULL, NULL, NULL, 220) != 220) {
+            av_log(h, AV_LOG_ERROR, "FTP server not ready for new users\n");
+            err = AVERROR(EACCES);
+            return err;
+        }
+
+        if ((err = ftp_auth(s)) < 0) {
+            av_log(h, AV_LOG_ERROR, "FTP authentication failed\n");
+            return err;
+        }
+
+        if ((err = ftp_type(s)) < 0) {
+            av_dlog(h, "Set content type failed\n");
+            return err;
+        }
+    }
+    return 0;
+}
+
+static int ftp_connect_data_connection(URLContext *h)
 {
     int err;
     char buf[CONTROL_BUFFER_SIZE], opts_format[20];
@@ -386,6 +431,12 @@ static int ftp_reconnect_data_connection(URLContext *h)
     FTPContext *s = h->priv_data;
 
     if (!s->conn_data) {
+        /* Enter passive mode */
+        if ((err = ftp_passive_mode(s)) < 0) {
+            av_dlog(h, "Set passive mode failed\n");
+            return err;
+        }
+        /* Open data connection */
         ff_url_join(buf, sizeof(buf), "tcp", NULL, s->hostname, s->server_data_port, NULL);
         if (s->rw_timeout != -1) {
             snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
@@ -404,9 +455,8 @@ static int ftp_reconnect_data_connection(URLContext *h)
 
 static int ftp_open(URLContext *h, const char *url, int flags)
 {
-    char proto[10], path[MAX_URL_SIZE], buf[CONTROL_BUFFER_SIZE], opts_format[20];
-    AVDictionary *opts = NULL;
-    int port, err;
+    char proto[10], path[MAX_URL_SIZE];
+    int err;
     FTPContext *s = h->priv_data;
 
     av_dlog(h, "ftp protocol open\n");
@@ -419,52 +469,26 @@ static int ftp_open(URLContext *h, const char *url, int flags)
     av_url_split(proto, sizeof(proto),
                  s->credencials, sizeof(s->credencials),
                  s->hostname, sizeof(s->hostname),
-                 &port,
+                 &s->server_control_port,
                  path, sizeof(path),
                  url);
 
-    if (port < 0)
-        port = 21;
-
-    if (!s->conn_control) {
-        ff_url_join(buf, sizeof(buf), "tcp", NULL, s->hostname, port, NULL);
-        if (s->rw_timeout != -1) {
-            snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
-            av_dict_set(&opts, "timeout", opts_format, 0);
-        } /* if option is not given, don't pass it and let tcp use its own default */
-        err = ffurl_open(&s->conn_control, buf, AVIO_FLAG_READ_WRITE,
-                         &s->conn_control_interrupt_cb, &opts);
-        av_dict_free(&opts);
-        if (err < 0)
-            goto fail;
-
-        /* consume all messages from server */
-        if (ftp_status(s, NULL, NULL, NULL, NULL, 220) != 220) {
-            av_log(h, AV_LOG_ERROR, "Server not ready for new users\n");
-            err = AVERROR(EACCES);
-            goto fail;
-        }
+    if (s->server_control_port < 0 || s->server_control_port > 65535)
+        s->server_control_port = 21;
 
-        if ((err = ftp_auth(s)) < 0)
-            goto fail;
-
-        if ((err = ftp_type(s)) < 0)
-            goto fail;
+    if ((err = ftp_connect_control_connection(h)) < 0)
+        goto fail;
 
-        if ((err = ftp_current_dir(s)) < 0)
-            goto fail;
-        av_strlcat(s->path, path, sizeof(s->path));
+    if ((err = ftp_current_dir(s)) < 0)
+        goto fail;
+    av_strlcat(s->path, path, sizeof(s->path));
 
-        if ((err = ftp_passive_mode(s)) < 0)
-            goto fail;
+    if (ftp_file_size(s) < 0 && flags & AVIO_FLAG_READ)
+        h->is_streamed = 1;
+    if (s->write_seekable != 1 && flags & AVIO_FLAG_WRITE)
+        h->is_streamed = 1;
 
-        if (ftp_file_size(s) < 0 && flags & AVIO_FLAG_READ)
-            h->is_streamed = 1;
-        if (s->write_seekable != 1 && flags & AVIO_FLAG_WRITE)
-            h->is_streamed = 1;
-    }
-
-    if ((err = ftp_reconnect_data_connection(h)) < 0)
+    if ((err = ftp_connect_data_connection(h)) < 0)
         goto fail;
 
     return 0;
@@ -577,12 +601,8 @@ static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
                     return AVERROR(EIO);
             }
 
-            /* set passive */
-            if ((err = ftp_passive_mode(s)) < 0)
-                return err;
-
             /* open new data connection */
-            if ((err = ftp_reconnect_data_connection(h)) < 0)
+            if ((err = ftp_connect_data_connection(h)) < 0)
                 return err;
         }