28 #define CONTROL_BUFFER_SIZE 1024
29 #define CREDENTIALS_BUFFER_SIZE 128
58 #define OFFSET(x) offsetof(FTPContext, x)
59 #define D AV_OPT_FLAG_DECODING_PARAM
60 #define E AV_OPT_FLAG_ENCODING_PARAM
62 {
"timeout",
"set timeout of socket I/O operations",
OFFSET(rw_timeout),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
D|
E },
63 {
"ftp-write-seekable",
"control seekability of connection during encoding",
OFFSET(write_seekable),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1,
E },
64 {
"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 },
104 if (q > line && q[-1] ==
'\r')
109 if ((q - line) < line_size - 1)
122 int err, i, dash = 0, result = 0, code_found = 0, linesize;
124 AVBPrint line_buffer;
129 while (!code_found || dash) {
138 linesize = strlen(buf);
141 for (i = 0; i < 3; ++i) {
142 if (buf[i] <
'0' || buf[i] >
'9') {
156 for (i = 0; response_codes[i]; ++i) {
157 if (err == response_codes[i]) {
168 if (!dash && buf[3] ==
'-')
170 else if (err == dash && buf[3] ==
' ')
182 const int response_codes[],
char **response)
195 if (response_codes) {
196 return ftp_status(s, response, response_codes);
219 static const int user_codes[] = {331, 230, 0};
220 static const int pass_codes[] = {230, 0};
225 user =
av_strtok(credencials,
":", &end);
233 snprintf(buf,
sizeof(buf),
"USER %s\r\n", user);
237 snprintf(buf,
sizeof(buf),
"PASS %s\r\n", pass);
252 static const char d =
'|';
253 static const char *
command =
"EPSV\r\n";
254 static const int epsv_codes[] = {229, 0};
259 for (i = 0; res[i]; ++i) {
262 }
else if (res[i] ==
')') {
271 if (strlen(start) < 5)
273 if (start[0] != d || start[1] != d || start[2] != d || end[-1] != d)
294 static const char *
command =
"PASV\r\n";
295 static const int pasv_codes[] = {227, 0};
300 for (i = 0; res[i]; ++i) {
303 }
else if (res[i] ==
')') {
313 if (!
av_strtok(start,
",", &end))
goto fail;
314 if (!
av_strtok(end,
",", &end))
goto fail;
315 if (!
av_strtok(end,
",", &end))
goto fail;
316 if (!
av_strtok(end,
",", &end))
goto fail;
320 if (!start)
goto fail;
323 if (!start)
goto fail;
340 static const char *
command =
"PWD\r\n";
341 static const int pwd_codes[] = {257, 0};
346 for (i = 0; res[i]; ++i) {
360 if (end > res && end[-1] ==
'/') {
378 static const int size_codes[] = {213, 0};
380 snprintf(command,
sizeof(command),
"SIZE %s\r\n", s->
path);
396 static const int retr_codes[] = {150, 0};
398 snprintf(command,
sizeof(command),
"RETR %s\r\n", s->
path);
410 static const int stor_codes[] = {150, 0};
412 snprintf(command,
sizeof(command),
"STOR %s\r\n", s->
path);
423 static const char *
command =
"TYPE I\r\n";
424 static const int type_codes[] = {200, 0};
435 static const int rest_codes[] = {350, 0};
437 snprintf(command,
sizeof(command),
"REST %"PRId64
"\r\n", pos);
446 static const char *feat_command =
"FEAT\r\n";
447 static const char *enable_utf8_command =
"OPTS UTF8 ON\r\n";
448 static const int feat_codes[] = {211, 0};
449 static const int opts_codes[] = {200, 451};
467 static const int connect_codes[] = {220, 0};
490 av_log(h,
AV_LOG_WARNING,
"Pure-FTPd server is used as an output protocol. It is known issue this implementation may produce incorrect content and it cannot be fixed at this moment.");
544 static const char *
command =
"ABOR\r\n";
546 static const int abor_codes[] = {225, 226, 0};
586 av_dlog(h,
"ftp protocol open\n");
631 int64_t new_pos, fake_pos;
633 av_dlog(h,
"ftp protocol seek %"PRId64
" %d\n", pos, whence);
673 int read, err, retry_done = 0;
675 av_dlog(h,
"ftp protocol read %d bytes\n", size);
705 if (read <= 0 && s->position < s->filesize && !h->
is_streamed) {
711 if ((err =
ftp_seek(h, pos, SEEK_SET)) < 0) {
733 av_dlog(h,
"ftp protocol write %d bytes\n", size);
758 av_dlog(h,
"ftp protocol close\n");
769 av_dlog(h,
"ftp protocol get_file_handle\n");
781 av_dlog(h,
"ftp protocol shutdown\n");
799 .priv_data_class = &ftp_context_class,