Browse Source

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.
tags/n2.0
Lukasz Marek 12 years ago
parent
commit
c84d6aa2f6
1 changed files with 68 additions and 48 deletions
  1. +68
    -48
      libavformat/ftp.c

+ 68
- 48
libavformat/ftp.c View 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;
}



Loading…
Cancel
Save