size_t dir_buffer_size;
size_t dir_buffer_offset;
int utf8;
+ const char *option_user; /**< User to be used if none given in the URL */
+ const char *option_password; /**< Password to be used if none given in the URL */
} FTPContext;
#define OFFSET(x) offsetof(FTPContext, x)
{"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
{"ftp-write-seekable", "control seekability of connection during encoding", OFFSET(write_seekable), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
{"ftp-anonymous-password", "password for anonymous login. E-mail address should be used.", OFFSET(anonymous_password), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
+ {"ftp-user", "user for FTP login. Overridden by whatever is in the URL.", OFFSET(option_user), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
+ {"ftp-password", "password for FTP login. Overridden by whatever is in the URL.", OFFSET(option_password), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E },
{NULL}
};
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) {
+ if (ftp_send_command(s, command, size_codes, &res) == 213 && res && strlen(res) > 4) {
s->filesize = strtoll(&res[4], NULL, 10);
} else {
s->filesize = -1;
return 0;
}
-static int ftp_has_feature(FTPContext *s, const char *feature_name);
-
static int ftp_list(FTPContext *s)
{
int ret;
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, 0};
+ static const int opts_codes[] = {200, 202, 451, 0};
av_freep(&s->features);
if (ftp_send_command(s, feat_command, feat_codes, &s->features) != 211) {
}
if (ftp_has_feature(s, "UTF8")) {
- if (ftp_send_command(s, enable_utf8_command, opts_codes, NULL) == 200)
+ int ret = ftp_send_command(s, enable_utf8_command, opts_codes, NULL);
+ if (ret == 200 || ret == 202)
s->utf8 = 1;
}
static int ftp_connect(URLContext *h, const char *url)
{
- char proto[10], path[MAX_URL_SIZE], credencials[MAX_URL_SIZE], hostname[MAX_URL_SIZE];
+ char proto[10], path[MAX_URL_SIZE], credentials[MAX_URL_SIZE], hostname[MAX_URL_SIZE];
const char *tok_user = NULL, *tok_pass = NULL;
char *end = NULL, *newpath = NULL;
int err;
s->features = NULL;
av_url_split(proto, sizeof(proto),
- credencials, sizeof(credencials),
+ credentials, sizeof(credentials),
hostname, sizeof(hostname),
&s->server_control_port,
path, sizeof(path),
url);
- tok_user = av_strtok(credencials, ":", &end);
+ tok_user = av_strtok(credentials, ":", &end);
tok_pass = av_strtok(end, ":", &end);
if (!tok_user) {
- tok_user = "anonymous";
- tok_pass = av_x_if_null(s->anonymous_password, "nopassword");
+ if (!s->option_user) {
+ tok_user = "anonymous";
+ tok_pass = av_x_if_null(s->anonymous_password, "nopassword");
+ } else {
+ tok_user = s->option_user;
+ }
+ }
+ if (!tok_pass) {
+ tok_pass = s->option_password;
}
s->user = av_strdup(tok_user);
s->password = av_strdup(tok_pass);
if (s->state == DISCONNECTED) {
/* optimization */
if (s->position >= s->filesize)
- return 0;
+ return AVERROR_EOF;
if ((err = ftp_connect_data_connection(h)) < 0)
return err;
}
if (s->state == READY) {
if (s->position >= s->filesize)
- return 0;
+ return AVERROR_EOF;
if ((err = ftp_retrieve(s)) < 0)
return err;
}