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;
129 while (!code_found || dash) {
142 for (i = 0; i < 3; ++i) {
143 if (buf[i] <
'0' || buf[i] >
'9')
148 dash = !!(buf[3] ==
'-');
150 for (i = 0; response_codes[i]; ++i) {
151 if (err == response_codes[i]) {
167 const int response_codes[],
char **response)
177 if (response_codes) {
178 return ftp_status(s, response, response_codes);
198 const char *user = NULL, *
pass = NULL;
201 static const int user_codes[] = {331, 230, 500, 530, 0};
202 static const int pass_codes[] = {230, 503, 530, 0};
207 user =
av_strtok(credencials,
":", &end);
215 snprintf(buf,
sizeof(buf),
"USER %s\r\n", user);
219 snprintf(buf,
sizeof(buf),
"PASS %s\r\n", pass);
234 static const char *
command =
"PASV\r\n";
235 static const int pasv_codes[] = {227, 501, 0};
240 for (i = 0; res[i]; ++i) {
243 }
else if (res[i] ==
')') {
253 if (!
av_strtok(start,
",", &end))
goto fail;
254 if (!
av_strtok(end,
",", &end))
goto fail;
255 if (!
av_strtok(end,
",", &end))
goto fail;
256 if (!
av_strtok(end,
",", &end))
goto fail;
260 if (!start)
goto fail;
263 if (!start)
goto fail;
274 "Your FTP server may use IPv6 which is not supported yet.\n");
282 static const char *
command =
"PWD\r\n";
283 static const int pwd_codes[] = {257, 0};
288 for (i = 0; res[i]; ++i) {
302 if (end > res && end[-1] ==
'/') {
320 static const int size_codes[] = {213, 501, 550, 0};
322 snprintf(command,
sizeof(command),
"SIZE %s\r\n", s->
path);
324 s->
filesize = strtoll(&res[4], NULL, 10);
338 static const int retr_codes[] = {150, 550, 554, 0};
340 snprintf(command,
sizeof(command),
"RETR %s\r\n", s->
path);
352 static const int stor_codes[] = {150, 0};
354 snprintf(command,
sizeof(command),
"STOR %s\r\n", s->
path);
365 static const char *
command =
"TYPE I\r\n";
366 static const int type_codes[] = {200, 500, 504, 0};
377 static const int rest_codes[] = {350, 500, 501, 0};
379 snprintf(command,
sizeof(command),
"REST %"PRId64
"\r\n", pos);
392 static const int connect_codes[] = {220, 0};
416 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.");
466 static const char *
command =
"ABOR\r\n";
468 static const int abor_codes[] = {225, 226, 0};
508 av_dlog(h,
"ftp protocol open\n");
553 int64_t new_pos, fake_pos;
555 av_dlog(h,
"ftp protocol seek %"PRId64
" %d\n", pos, whence);
595 int read, err, retry_done = 0;
597 av_dlog(h,
"ftp protocol read %d bytes\n", size);
627 if (read <= 0 && s->position < s->filesize && !h->
is_streamed) {
633 if ((err =
ftp_seek(h, pos, SEEK_SET)) < 0) {
655 av_dlog(h,
"ftp protocol write %d bytes\n", size);
680 av_dlog(h,
"ftp protocol close\n");
691 av_dlog(h,
"ftp protocol get_file_handle\n");
703 av_dlog(h,
"ftp protocol shutdown\n");
721 .priv_data_class = &ftp_context_class,