X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fthird_party%2Fffmpeg%2Flibavformat%2Fftp.c;h=66c066549e5b282cf73cc42ae71e45ee9b8336ab;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=dae8aa086d2f45ede2cea0b81694c04351cda14b;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/third_party/ffmpeg/libavformat/ftp.c b/src/third_party/ffmpeg/libavformat/ftp.c index dae8aa0..66c0665 100644 --- a/src/third_party/ffmpeg/libavformat/ftp.c +++ b/src/third_party/ffmpeg/libavformat/ftp.c @@ -119,7 +119,7 @@ static int ftp_get_line(FTPContext *s, char *line, int line_size) */ static int ftp_status(FTPContext *s, char **line, const int response_codes[]) { - int err, i, dash = 0, result = 0, code_found = 0; + int err, i, dash = 0, result = 0, code_found = 0, linesize; char buf[CONTROL_BUFFER_SIZE]; AVBPrint line_buffer; @@ -135,25 +135,40 @@ static int ftp_status(FTPContext *s, char **line, const int response_codes[]) av_log(s, AV_LOG_DEBUG, "%s\n", buf); - if (strlen(buf) < 4) - continue; - + linesize = strlen(buf); err = 0; - for (i = 0; i < 3; ++i) { - if (buf[i] < '0' || buf[i] > '9') - continue; - err *= 10; - err += buf[i] - '0'; + if (linesize >= 3) { + for (i = 0; i < 3; ++i) { + if (buf[i] < '0' || buf[i] > '9') { + err = 0; + break; + } + err *= 10; + err += buf[i] - '0'; + } } - dash = !!(buf[3] == '-'); - for (i = 0; response_codes[i]; ++i) { - if (err == response_codes[i]) { - if (line) - av_bprintf(&line_buffer, "%s", buf); + if (!code_found) { + if (err >= 500) { code_found = 1; result = err; - break; + } else + for (i = 0; response_codes[i]; ++i) { + if (err == response_codes[i]) { + code_found = 1; + result = err; + break; + } + } + } + if (code_found) { + if (line) + av_bprintf(&line_buffer, "%s\r\n", buf); + if (linesize >= 4) { + if (!dash && buf[3] == '-') + dash = err; + else if (err == dash && buf[3] == ' ') + dash = 0; } } } @@ -198,8 +213,8 @@ static int ftp_auth(FTPContext *s) const char *user = NULL, *pass = NULL; char *end = NULL, buf[CONTROL_BUFFER_SIZE], credencials[CREDENTIALS_BUFFER_SIZE]; int err; - static const int user_codes[] = {331, 230, 500, 530, 0}; /* 500, 530 are incorrect codes */ - static const int pass_codes[] = {230, 503, 530, 0}; /* 503, 530 are incorrect codes */ + static const int user_codes[] = {331, 230, 0}; + static const int pass_codes[] = {230, 0}; /* Authentication may be repeated, original string has to be saved */ av_strlcpy(credencials, s->credencials, sizeof(credencials)); @@ -227,12 +242,54 @@ static int ftp_auth(FTPContext *s) return 0; } +static int ftp_passive_mode_epsv(FTPContext *s) +{ + char *res = NULL, *start = NULL, *end = NULL; + int i; + static const char d = '|'; + static const char *command = "EPSV\r\n"; + static const int epsv_codes[] = {229, 0}; + + if (ftp_send_command(s, command, epsv_codes, &res) != 229 || !res) + goto fail; + + for (i = 0; res[i]; ++i) { + if (res[i] == '(') { + start = res + i + 1; + } else if (res[i] == ')') { + end = res + i; + break; + } + } + if (!start || !end) + goto fail; + + *end = '\0'; + if (strlen(start) < 5) + goto fail; + if (start[0] != d || start[1] != d || start[2] != d || end[-1] != d) + goto fail; + start += 3; + end[-1] = '\0'; + + s->server_data_port = atoi(start); + av_dlog(s, "Server data port: %d\n", s->server_data_port); + + av_free(res); + return 0; + + fail: + av_free(res); + s->server_data_port = -1; + return AVERROR(ENOSYS); +} + static int ftp_passive_mode(FTPContext *s) { char *res = NULL, *start = NULL, *end = NULL; int i; static const char *command = "PASV\r\n"; - static const int pasv_codes[] = {227, 501, 0}; /* 501 is incorrect code */ + static const int pasv_codes[] = {227, 0}; if (ftp_send_command(s, command, pasv_codes, &res) != 227 || !res) goto fail; @@ -270,8 +327,6 @@ static int ftp_passive_mode(FTPContext *s) fail: av_free(res); s->server_data_port = -1; - av_log(s, AV_LOG_ERROR, "Set passive mode failed\n" - "Your FTP server may use IPv6 which is not supported yet.\n"); return AVERROR(EIO); } @@ -317,7 +372,7 @@ static int ftp_file_size(FTPContext *s) { char command[CONTROL_BUFFER_SIZE]; char *res = NULL; - static const int size_codes[] = {213, 501, 550, 0}; /* 501, 550 are incorrect codes */ + static const int size_codes[] = {213, 0}; snprintf(command, sizeof(command), "SIZE %s\r\n", s->path); if (ftp_send_command(s, command, size_codes, &res) == 213 && res) { @@ -335,7 +390,7 @@ static int ftp_file_size(FTPContext *s) static int ftp_retrieve(FTPContext *s) { char command[CONTROL_BUFFER_SIZE]; - static const int retr_codes[] = {150, 550, 554, 0}; /* 550, 554 are incorrect codes */ + static const int retr_codes[] = {150, 0}; snprintf(command, sizeof(command), "RETR %s\r\n", s->path); if (ftp_send_command(s, command, retr_codes, NULL) != 150) @@ -363,7 +418,7 @@ static int ftp_store(FTPContext *s) static int ftp_type(FTPContext *s) { static const char *command = "TYPE I\r\n"; - static const int type_codes[] = {200, 500, 504, 0}; /* 500, 504 are incorrect codes */ + static const int type_codes[] = {200, 0}; if (ftp_send_command(s, command, type_codes, NULL) != 200) return AVERROR(EIO); @@ -374,7 +429,7 @@ static int ftp_type(FTPContext *s) static int ftp_restart(FTPContext *s, int64_t pos) { char command[CONTROL_BUFFER_SIZE]; - static const int rest_codes[] = {350, 500, 501, 0}; /* 500, 501 are incorrect codes */ + static const int rest_codes[] = {350, 0}; snprintf(command, sizeof(command), "REST %"PRId64"\r\n", pos); if (ftp_send_command(s, command, rest_codes, NULL) != 350) @@ -383,6 +438,21 @@ static int ftp_restart(FTPContext *s, int64_t pos) return 0; } +static int ftp_features(FTPContext *s) +{ + static const char *feat_command = "FEAT\r\n"; + static const char *enable_utf8_command = "OPTS UTF8 ON\r\n"; + static const int feat_codes[] = {211, 0}; + static const int opts_codes[] = {200, 451}; + char *feat; + + if (ftp_send_command(s, feat_command, feat_codes, &feat) == 211) { + if (av_stristr(feat, "UTF8")) + ftp_send_command(s, enable_utf8_command, opts_codes, NULL); + } + return 0; +} + static int ftp_connect_control_connection(URLContext *h) { char buf[CONTROL_BUFFER_SIZE], opts_format[20], *response = NULL; @@ -426,6 +496,8 @@ static int ftp_connect_control_connection(URLContext *h) av_log(h, AV_LOG_ERROR, "Set content type failed\n"); return err; } + + ftp_features(s); } return 0; } @@ -439,8 +511,11 @@ static int ftp_connect_data_connection(URLContext *h) if (!s->conn_data) { /* Enter passive mode */ - if ((err = ftp_passive_mode(s)) < 0) - return err; + if (ftp_passive_mode_epsv(s) < 0) { + /* Use PASV as fallback */ + if ((err = ftp_passive_mode(s)) < 0) + 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) {