|
|
|
@ -227,6 +227,48 @@ 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, 500, 501, 0}; /* 500, 501 are incorrect codes */ |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
@ -270,8 +312,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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -439,8 +479,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) { |
|
|
|
|