|
|
@ -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[]) |
|
|
|
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]; |
|
|
|
char buf[CONTROL_BUFFER_SIZE]; |
|
|
|
AVBPrint line_buffer; |
|
|
|
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); |
|
|
|
av_log(s, AV_LOG_DEBUG, "%s\n", buf); |
|
|
|
|
|
|
|
|
|
|
|
if (strlen(buf) < 4) |
|
|
|
linesize = strlen(buf); |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = 0; |
|
|
|
err = 0; |
|
|
|
for (i = 0; i < 3; ++i) { |
|
|
|
if (linesize >= 3) { |
|
|
|
if (buf[i] < '0' || buf[i] > '9') |
|
|
|
for (i = 0; i < 3; ++i) { |
|
|
|
continue; |
|
|
|
if (buf[i] < '0' || buf[i] > '9') { |
|
|
|
err *= 10; |
|
|
|
err = 0; |
|
|
|
err += buf[i] - '0'; |
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
err *= 10; |
|
|
|
|
|
|
|
err += buf[i] - '0'; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
dash = !!(buf[3] == '-'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; response_codes[i]; ++i) { |
|
|
|
if (!code_found) { |
|
|
|
if (err == response_codes[i]) { |
|
|
|
if (err >= 500) { |
|
|
|
if (line) |
|
|
|
|
|
|
|
av_bprintf(&line_buffer, "%s", buf); |
|
|
|
|
|
|
|
code_found = 1; |
|
|
|
code_found = 1; |
|
|
|
result = err; |
|
|
|
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; |
|
|
|
const char *user = NULL, *pass = NULL; |
|
|
|
char *end = NULL, buf[CONTROL_BUFFER_SIZE], credencials[CREDENTIALS_BUFFER_SIZE]; |
|
|
|
char *end = NULL, buf[CONTROL_BUFFER_SIZE], credencials[CREDENTIALS_BUFFER_SIZE]; |
|
|
|
int err; |
|
|
|
int err; |
|
|
|
static const int user_codes[] = {331, 230, 500, 530, 0}; /* 500, 530 are incorrect codes */ |
|
|
|
static const int user_codes[] = {331, 230, 0}; |
|
|
|
static const int pass_codes[] = {230, 503, 530, 0}; /* 503, 530 are incorrect codes */ |
|
|
|
static const int pass_codes[] = {230, 0}; |
|
|
|
|
|
|
|
|
|
|
|
/* Authentication may be repeated, original string has to be saved */ |
|
|
|
/* Authentication may be repeated, original string has to be saved */ |
|
|
|
av_strlcpy(credencials, s->credencials, sizeof(credencials)); |
|
|
|
av_strlcpy(credencials, s->credencials, sizeof(credencials)); |
|
|
@ -233,7 +248,7 @@ static int ftp_passive_mode_epsv(FTPContext *s) |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
static const char d = '|'; |
|
|
|
static const char d = '|'; |
|
|
|
static const char *command = "EPSV\r\n"; |
|
|
|
static const char *command = "EPSV\r\n"; |
|
|
|
static const int epsv_codes[] = {229, 500, 501, 0}; /* 500, 501 are incorrect codes */ |
|
|
|
static const int epsv_codes[] = {229, 0}; |
|
|
|
|
|
|
|
|
|
|
|
if (ftp_send_command(s, command, epsv_codes, &res) != 229 || !res) |
|
|
|
if (ftp_send_command(s, command, epsv_codes, &res) != 229 || !res) |
|
|
|
goto fail; |
|
|
|
goto fail; |
|
|
@ -274,7 +289,7 @@ static int ftp_passive_mode(FTPContext *s) |
|
|
|
char *res = NULL, *start = NULL, *end = NULL; |
|
|
|
char *res = NULL, *start = NULL, *end = NULL; |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
static const char *command = "PASV\r\n"; |
|
|
|
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) |
|
|
|
if (ftp_send_command(s, command, pasv_codes, &res) != 227 || !res) |
|
|
|
goto fail; |
|
|
|
goto fail; |
|
|
@ -357,7 +372,7 @@ static int ftp_file_size(FTPContext *s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char command[CONTROL_BUFFER_SIZE]; |
|
|
|
char command[CONTROL_BUFFER_SIZE]; |
|
|
|
char *res = NULL; |
|
|
|
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); |
|
|
|
snprintf(command, sizeof(command), "SIZE %s\r\n", s->path); |
|
|
|
if (ftp_send_command(s, command, size_codes, &res) == 213 && res) { |
|
|
|
if (ftp_send_command(s, command, size_codes, &res) == 213 && res) { |
|
|
@ -375,7 +390,7 @@ static int ftp_file_size(FTPContext *s) |
|
|
|
static int ftp_retrieve(FTPContext *s) |
|
|
|
static int ftp_retrieve(FTPContext *s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char command[CONTROL_BUFFER_SIZE]; |
|
|
|
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); |
|
|
|
snprintf(command, sizeof(command), "RETR %s\r\n", s->path); |
|
|
|
if (ftp_send_command(s, command, retr_codes, NULL) != 150) |
|
|
|
if (ftp_send_command(s, command, retr_codes, NULL) != 150) |
|
|
@ -403,7 +418,7 @@ static int ftp_store(FTPContext *s) |
|
|
|
static int ftp_type(FTPContext *s) |
|
|
|
static int ftp_type(FTPContext *s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
static const char *command = "TYPE I\r\n"; |
|
|
|
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) |
|
|
|
if (ftp_send_command(s, command, type_codes, NULL) != 200) |
|
|
|
return AVERROR(EIO); |
|
|
|
return AVERROR(EIO); |
|
|
@ -414,7 +429,7 @@ static int ftp_type(FTPContext *s) |
|
|
|
static int ftp_restart(FTPContext *s, int64_t pos) |
|
|
|
static int ftp_restart(FTPContext *s, int64_t pos) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char command[CONTROL_BUFFER_SIZE]; |
|
|
|
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); |
|
|
|
snprintf(command, sizeof(command), "REST %"PRId64"\r\n", pos); |
|
|
|
if (ftp_send_command(s, command, rest_codes, NULL) != 350) |
|
|
|
if (ftp_send_command(s, command, rest_codes, NULL) != 350) |
|
|
@ -423,6 +438,21 @@ static int ftp_restart(FTPContext *s, int64_t pos) |
|
|
|
return 0; |
|
|
|
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) |
|
|
|
static int ftp_connect_control_connection(URLContext *h) |
|
|
|
{ |
|
|
|
{ |
|
|
|
char buf[CONTROL_BUFFER_SIZE], opts_format[20], *response = NULL; |
|
|
|
char buf[CONTROL_BUFFER_SIZE], opts_format[20], *response = NULL; |
|
|
@ -466,6 +496,8 @@ static int ftp_connect_control_connection(URLContext *h) |
|
|
|
av_log(h, AV_LOG_ERROR, "Set content type failed\n"); |
|
|
|
av_log(h, AV_LOG_ERROR, "Set content type failed\n"); |
|
|
|
return err; |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ftp_features(s); |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|