From c84d6aa2f63f014a1c08f4adf67c462b98f68028 Mon Sep 17 00:00:00 2001 From: Lukasz Marek Date: Thu, 30 May 2013 15:22:13 +0200 Subject: ftp: move create control connection to function Move common code that opens control connection to function. This code can be reused when reconnecting to FTP server after inactivity. --- libavformat/ftp.c | 116 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 68 insertions(+), 48 deletions(-) (limited to 'libavformat/ftp.c') diff --git a/libavformat/ftp.c b/libavformat/ftp.c index 50c09298a8..da9408a2c3 100644 --- a/libavformat/ftp.c +++ b/libavformat/ftp.c @@ -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; } -- cgit v1.2.3