31 #define CONTROL_BUFFER_SIZE 1024
32 #define CREDENTIALS_BUFFER_SIZE 128
63 #define OFFSET(x) offsetof(FTPContext, x)
64 #define D AV_OPT_FLAG_DECODING_PARAM
65 #define E AV_OPT_FLAG_ENCODING_PARAM
67 {
"timeout",
"set timeout of socket I/O operations",
OFFSET(rw_timeout),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX,
D|
E },
68 {
"ftp-write-seekable",
"control seekability of connection during encoding",
OFFSET(write_seekable),
AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1,
E },
69 {
"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 },
119 if (q > line && q[-1] ==
'\r')
127 if ((q - line) < line_size - 1)
159 int err, i, result = 0, pref_code_found = 0, wait_count = 100;
167 if (!pref_code_found && wait_count--) {
177 if (!pref_code_found) {
182 for (i = 0; i < 3; ++i) {
183 if (buf[i] <
'0' || buf[i] >
'9')
189 for (i = 0; response_codes[i]; ++i) {
190 if (err == response_codes[i]) {
206 const int response_codes[],
char **response)
222 if (response_codes) {
223 return ftp_status(s, response, response_codes);
243 const char *user = NULL, *
pass = NULL;
246 const int user_codes[] = {331, 230, 500, 530, 0};
247 const int pass_codes[] = {230, 503, 530, 0};
252 user =
av_strtok(credencials,
":", &end);
260 snprintf(buf,
sizeof(buf),
"USER %s\r\n", user);
264 snprintf(buf,
sizeof(buf),
"PASS %s\r\n", pass);
279 const char *
command =
"PASV\r\n";
280 const int pasv_codes[] = {227, 501, 0};
285 for (i = 0; res[i]; ++i) {
288 }
else if (res[i] ==
')') {
298 if (!
av_strtok(start,
",", &end))
goto fail;
299 if (!
av_strtok(end,
",", &end))
goto fail;
300 if (!
av_strtok(end,
",", &end))
goto fail;
301 if (!
av_strtok(end,
",", &end))
goto fail;
305 if (!start)
goto fail;
308 if (!start)
goto fail;
325 const char *
command =
"PWD\r\n";
326 const int pwd_codes[] = {257, 0};
331 for (i = 0; res[i]; ++i) {
345 if (end > res && end[-1] ==
'/') {
363 const int size_codes[] = {213, 501, 550, 0};
365 snprintf(command,
sizeof(command),
"SIZE %s\r\n", s->
path);
367 s->
filesize = strtoll(&res[4], NULL, 10);
381 const int retr_codes[] = {150, 550, 554, 0};
383 snprintf(command,
sizeof(command),
"RETR %s\r\n", s->
path);
395 const int stor_codes[] = {150, 0};
397 snprintf(command,
sizeof(command),
"STOR %s\r\n", s->
path);
408 const char *
command =
"TYPE I\r\n";
409 const int type_codes[] = {200, 500, 504, 0};
420 const int rest_codes[] = {350, 500, 501, 0};
422 snprintf(command,
sizeof(command),
"REST %"PRId64
"\r\n", pos);
435 const int connect_codes[] = {220, 0};
455 if (
ftp_status(s, NULL, connect_codes) != 220) {
466 av_dlog(h,
"Set content type failed\n");
483 av_dlog(h,
"Set passive mode failed\n");
508 const char *
command =
"ABOR\r\n";
510 const int abor_codes[] = {225, 226, 0};
551 av_dlog(h,
"ftp protocol open\n");
598 int64_t new_pos, fake_pos;
600 av_dlog(h,
"ftp protocol seek %"PRId64
" %d\n", pos, whence);
623 new_pos =
FFMAX(0, new_pos);
637 int read, err, retry_done = 0;
639 av_dlog(h,
"ftp protocol read %d bytes\n", size);
667 if (read <= 0 && s->position < s->filesize && !h->
is_streamed) {
673 if ((err =
ftp_seek(h, pos, SEEK_SET)) < 0) {
695 av_dlog(h,
"ftp protocol write %d bytes\n", size);
720 av_dlog(h,
"ftp protocol close\n");
731 av_dlog(h,
"ftp protocol get_file_handle\n");
743 av_dlog(h,
"ftp protocol shutdown\n");
761 .priv_data_class = &ftp_context_class,