FFmpeg
ftp.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Lukasz Marek <lukasz.m.luki@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <string.h>
22 #include <time.h>
23 
24 #include "libavutil/avstring.h"
25 #include "libavutil/internal.h"
26 #include "libavutil/parseutils.h"
27 #include "avformat.h"
28 #include "internal.h"
29 #include "url.h"
30 #include "urldecode.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/bprint.h"
33 
34 #define CONTROL_BUFFER_SIZE 1024
35 #define DIR_BUFFER_SIZE 4096
36 
37 typedef enum {
45 } FTPState;
46 
47 typedef enum {
52 
53 typedef struct {
54  const AVClass *class;
55  URLContext *conn_control; /**< Control connection */
56  URLContext *conn_data; /**< Data connection, NULL when not connected */
57  uint8_t control_buffer[CONTROL_BUFFER_SIZE]; /**< Control connection buffer */
58  uint8_t *control_buf_ptr, *control_buf_end;
59  int server_data_port; /**< Data connection port opened by server, -1 on error. */
60  int server_control_port; /**< Control connection port, default is 21 */
61  char *hostname; /**< Server address. */
62  char *user; /**< Server user */
63  char *password; /**< Server user's password */
64  char *path; /**< Path to resource on server. */
65  int64_t filesize; /**< Size of file on server, -1 on error. */
66  int64_t position; /**< Current position, calculated. */
67  int rw_timeout; /**< Network timeout. */
68  const char *anonymous_password; /**< Password to be used for anonymous user. An email should be used. */
69  int write_seekable; /**< Control seekability, 0 = disable, 1 = enable. */
70  FTPState state; /**< State of data connection */
71  FTPListingMethod listing_method; /**< Called listing method */
72  char *features; /**< List of server's features represented as raw response */
73  char *dir_buffer;
76  int utf8;
77  const char *option_user; /**< User to be used if none given in the URL */
78  const char *option_password; /**< Password to be used if none given in the URL */
79 } FTPContext;
80 
81 #define OFFSET(x) offsetof(FTPContext, x)
82 #define D AV_OPT_FLAG_DECODING_PARAM
83 #define E AV_OPT_FLAG_ENCODING_PARAM
84 static const AVOption options[] = {
85  {"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
86  {"ftp-write-seekable", "control seekability of connection during encoding", OFFSET(write_seekable), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E },
87  {"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 },
88  {"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 },
89  {"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 },
90  {NULL}
91 };
92 
93 static const AVClass ftp_context_class = {
94  .class_name = "ftp",
95  .item_name = av_default_item_name,
96  .option = options,
97  .version = LIBAVUTIL_VERSION_INT,
98 };
99 
100 static int ftp_close(URLContext *h);
101 
102 static int ftp_getc(FTPContext *s)
103 {
104  int len;
105  if (s->control_buf_ptr >= s->control_buf_end) {
106  len = ffurl_read(s->conn_control, s->control_buffer, CONTROL_BUFFER_SIZE);
107  if (len < 0) {
108  return len;
109  } else if (!len) {
110  return -1;
111  } else {
112  s->control_buf_ptr = s->control_buffer;
113  s->control_buf_end = s->control_buffer + len;
114  }
115  }
116  return *s->control_buf_ptr++;
117 }
118 
119 static int ftp_get_line(FTPContext *s, char *line, int line_size)
120 {
121  int ch;
122  char *q = line;
123 
124  for (;;) {
125  ch = ftp_getc(s);
126  if (ch < 0) {
127  return ch;
128  }
129  if (ch == '\n') {
130  /* process line */
131  if (q > line && q[-1] == '\r')
132  q--;
133  *q = '\0';
134  return 0;
135  } else {
136  if ((q - line) < line_size - 1)
137  *q++ = ch;
138  }
139  }
140 }
141 
142 /*
143  * This routine returns ftp server response code.
144  * Server may send more than one response for a certain command.
145  * First expected code is returned.
146  */
147 static int ftp_status(FTPContext *s, char **line, const int response_codes[])
148 {
149  int err, i, dash = 0, result = 0, code_found = 0, linesize;
150  char buf[CONTROL_BUFFER_SIZE];
151  AVBPrint line_buffer;
152 
153  if (line)
154  av_bprint_init(&line_buffer, 0, AV_BPRINT_SIZE_AUTOMATIC);
155 
156  while (!code_found || dash) {
157  if ((err = ftp_get_line(s, buf, sizeof(buf))) < 0) {
158  if (line)
159  av_bprint_finalize(&line_buffer, NULL);
160  return err;
161  }
162 
163  av_log(s, AV_LOG_DEBUG, "%s\n", buf);
164 
165  linesize = strlen(buf);
166  err = 0;
167  if (linesize >= 3) {
168  for (i = 0; i < 3; ++i) {
169  if (buf[i] < '0' || buf[i] > '9') {
170  err = 0;
171  break;
172  }
173  err *= 10;
174  err += buf[i] - '0';
175  }
176  }
177 
178  if (!code_found) {
179  if (err >= 500) {
180  code_found = 1;
181  result = err;
182  } else
183  for (i = 0; response_codes[i]; ++i) {
184  if (err == response_codes[i]) {
185  code_found = 1;
186  result = err;
187  break;
188  }
189  }
190  }
191  if (code_found) {
192  if (line)
193  av_bprintf(&line_buffer, "%s\r\n", buf);
194  if (linesize >= 4) {
195  if (!dash && buf[3] == '-')
196  dash = err;
197  else if (err == dash && buf[3] == ' ')
198  dash = 0;
199  }
200  }
201  }
202 
203  if (line)
204  av_bprint_finalize(&line_buffer, line);
205  return result;
206 }
207 
208 static int ftp_send_command(FTPContext *s, const char *command,
209  const int response_codes[], char **response)
210 {
211  int err;
212 
213  ff_dlog(s, "%s", command);
214 
215  if (response)
216  *response = NULL;
217 
218  if (!s->conn_control)
219  return AVERROR(EIO);
220 
221  if ((err = ffurl_write(s->conn_control, command, strlen(command))) < 0)
222  return err;
223  if (!err)
224  return -1;
225 
226  /* return status */
227  if (response_codes) {
228  return ftp_status(s, response, response_codes);
229  }
230  return 0;
231 }
232 
234 {
235  ffurl_closep(&s->conn_data);
236  s->state = DISCONNECTED;
237 }
238 
240 {
241  ffurl_closep(&s->conn_control);
243 }
244 
245 static int ftp_auth(FTPContext *s)
246 {
247  char buf[CONTROL_BUFFER_SIZE];
248  int err;
249  static const int user_codes[] = {331, 230, 0};
250  static const int pass_codes[] = {230, 0};
251 
252  if (strpbrk(s->user, "\r\n"))
253  return AVERROR(EINVAL);
254  err = snprintf(buf, sizeof(buf), "USER %s\r\n", s->user);
255  if (err >= sizeof(buf))
256  return AVERROR(ENOSYS);
257 
258  err = ftp_send_command(s, buf, user_codes, NULL);
259  if (err == 331) {
260  if (s->password) {
261  if (strpbrk(s->password, "\r\n"))
262  return AVERROR(EINVAL);
263  err = snprintf(buf, sizeof(buf), "PASS %s\r\n", s->password);
264  if (err >= sizeof(buf))
265  return AVERROR(ENOSYS);
266 
267  err = ftp_send_command(s, buf, pass_codes, NULL);
268  } else
269  return AVERROR(EACCES);
270  }
271  if (err != 230)
272  return AVERROR(EACCES);
273 
274  return 0;
275 }
276 
278 {
279  char *res = NULL, *start = NULL, *end = NULL;
280  int i;
281  static const char d = '|';
282  static const char *command = "EPSV\r\n";
283  static const int epsv_codes[] = {229, 0};
284 
285  if (ftp_send_command(s, command, epsv_codes, &res) != 229 || !res)
286  goto fail;
287 
288  for (i = 0; res[i]; ++i) {
289  if (res[i] == '(') {
290  start = res + i + 1;
291  } else if (res[i] == ')') {
292  end = res + i;
293  break;
294  }
295  }
296  if (!start || !end)
297  goto fail;
298 
299  *end = '\0';
300  if (strlen(start) < 5)
301  goto fail;
302  if (start[0] != d || start[1] != d || start[2] != d || end[-1] != d)
303  goto fail;
304  start += 3;
305  end[-1] = '\0';
306 
307  s->server_data_port = atoi(start);
308  ff_dlog(s, "Server data port: %d\n", s->server_data_port);
309 
310  av_free(res);
311  return 0;
312 
313  fail:
314  av_free(res);
315  s->server_data_port = -1;
316  return AVERROR(ENOSYS);
317 }
318 
320 {
321  char *res = NULL, *start = NULL, *end = NULL;
322  int i;
323  static const char *command = "PASV\r\n";
324  static const int pasv_codes[] = {227, 0};
325 
326  if (ftp_send_command(s, command, pasv_codes, &res) != 227 || !res)
327  goto fail;
328 
329  for (i = 0; res[i]; ++i) {
330  if (res[i] == '(') {
331  start = res + i + 1;
332  } else if (res[i] == ')') {
333  end = res + i;
334  break;
335  }
336  }
337  if (!start || !end)
338  goto fail;
339 
340  *end = '\0';
341  /* skip ip */
342  if (!av_strtok(start, ",", &end)) goto fail;
343  if (!av_strtok(NULL, ",", &end)) goto fail;
344  if (!av_strtok(NULL, ",", &end)) goto fail;
345  if (!av_strtok(NULL, ",", &end)) goto fail;
346 
347  /* parse port number */
348  start = av_strtok(NULL, ",", &end);
349  if (!start) goto fail;
350  s->server_data_port = atoi(start) * 256;
351  start = av_strtok(NULL, ",", &end);
352  if (!start) goto fail;
353  s->server_data_port += atoi(start);
354  ff_dlog(s, "Server data port: %d\n", s->server_data_port);
355 
356  av_free(res);
357  return 0;
358 
359  fail:
360  av_free(res);
361  s->server_data_port = -1;
362  return AVERROR(EIO);
363 }
364 
366 {
367  char *res = NULL, *start = NULL, *end = NULL;
368  int i;
369  static const char *command = "PWD\r\n";
370  static const int pwd_codes[] = {257, 0};
371 
372  if (ftp_send_command(s, command, pwd_codes, &res) != 257 || !res)
373  goto fail;
374 
375  for (i = 0; res[i]; ++i) {
376  if (res[i] == '"') {
377  if (!start) {
378  start = res + i + 1;
379  continue;
380  }
381  end = res + i;
382  break;
383  }
384  }
385 
386  if (!end)
387  goto fail;
388 
389  *end = '\0';
390  s->path = av_strdup(start);
391 
392  av_free(res);
393 
394  if (!s->path)
395  return AVERROR(ENOMEM);
396  return 0;
397 
398  fail:
399  av_free(res);
400  return AVERROR(EIO);
401 }
402 
404 {
405  char command[CONTROL_BUFFER_SIZE];
406  char *res = NULL;
407  int ret;
408  static const int size_codes[] = {213, 0};
409 
410  ret = snprintf(command, sizeof(command), "SIZE %s\r\n", s->path);
411  if (ret >= sizeof(command))
412  return AVERROR(ENOSYS);
413 
414  if (ftp_send_command(s, command, size_codes, &res) == 213 && res && strlen(res) > 4) {
415  s->filesize = strtoll(&res[4], NULL, 10);
416  } else {
417  s->filesize = -1;
418  av_free(res);
419  return AVERROR(EIO);
420  }
421 
422  av_free(res);
423  return 0;
424 }
425 
427 {
428  char command[CONTROL_BUFFER_SIZE];
429  static const int retr_codes[] = {150, 125, 0};
430  int resp_code, ret;
431 
432  ret = snprintf(command, sizeof(command), "RETR %s\r\n", s->path);
433  if (ret >= sizeof(command))
434  return AVERROR(ENOSYS);
435 
436  resp_code = ftp_send_command(s, command, retr_codes, NULL);
437  if (resp_code != 125 && resp_code != 150)
438  return AVERROR(EIO);
439 
440  s->state = DOWNLOADING;
441 
442  return 0;
443 }
444 
445 static int ftp_store(FTPContext *s)
446 {
447  char command[CONTROL_BUFFER_SIZE];
448  static const int stor_codes[] = {150, 125, 0};
449  int resp_code, ret;
450 
451  ret = snprintf(command, sizeof(command), "STOR %s\r\n", s->path);
452  if (ret >= sizeof(command))
453  return AVERROR(ENOSYS);
454 
455  resp_code = ftp_send_command(s, command, stor_codes, NULL);
456  if (resp_code != 125 && resp_code != 150)
457  return AVERROR(EIO);
458 
459  s->state = UPLOADING;
460 
461  return 0;
462 }
463 
464 static int ftp_type(FTPContext *s)
465 {
466  static const char *command = "TYPE I\r\n";
467  static const int type_codes[] = {200, 0};
468 
469  if (ftp_send_command(s, command, type_codes, NULL) != 200)
470  return AVERROR(EIO);
471 
472  return 0;
473 }
474 
475 static int ftp_restart(FTPContext *s, int64_t pos)
476 {
477  char command[CONTROL_BUFFER_SIZE];
478  static const int rest_codes[] = {350, 0};
479 
480  snprintf(command, sizeof(command), "REST %"PRId64"\r\n", pos);
481  if (ftp_send_command(s, command, rest_codes, NULL) != 350)
482  return AVERROR(EIO);
483 
484  return 0;
485 }
486 
488 {
489  static const int cwd_codes[] = {250, 550, 0}; /* 550 is incorrect code */
490  char command[MAX_URL_SIZE];
491  int ret;
492 
493  ret = snprintf(command, sizeof(command), "CWD %s\r\n", s->path);
494  if (ret >= sizeof(command))
495  return AVERROR(ENOSYS);
496 
497  if (ftp_send_command(s, command, cwd_codes, NULL) != 250)
498  return AVERROR(EIO);
499  return 0;
500 }
501 
503 {
504  static const char *command = "MLSD\r\n";
505  static const int mlsd_codes[] = {150, 500, 0}; /* 500 is incorrect code */
506 
507  if (ftp_send_command(s, command, mlsd_codes, NULL) != 150)
508  return AVERROR(ENOSYS);
509  s->listing_method = MLSD;
510  return 0;
511 }
512 
514 {
515  static const char *command = "NLST\r\n";
516  static const int nlst_codes[] = {226, 425, 426, 451, 450, 550, 0};
517 
518  if (ftp_send_command(s, command, nlst_codes, NULL) != 226)
519  return AVERROR(ENOSYS);
520  s->listing_method = NLST;
521  return 0;
522 }
523 
524 static int ftp_list(FTPContext *s)
525 {
526  int ret;
527  s->state = LISTING_DIR;
528 
529  if ((ret = ftp_list_mlsd(s)) < 0)
530  ret = ftp_list_nlst(s);
531 
532  return ret;
533 }
534 
535 static int ftp_has_feature(FTPContext *s, const char *feature_name)
536 {
537  if (!s->features)
538  return 0;
539 
540  return av_stristr(s->features, feature_name) != NULL;
541 }
542 
544 {
545  static const char *feat_command = "FEAT\r\n";
546  static const char *enable_utf8_command = "OPTS UTF8 ON\r\n";
547  static const int feat_codes[] = {211, 0};
548  static const int opts_codes[] = {200, 202, 451, 0};
549 
550  av_freep(&s->features);
551  if (ftp_send_command(s, feat_command, feat_codes, &s->features) != 211) {
552  av_freep(&s->features);
553  }
554 
555  if (ftp_has_feature(s, "UTF8")) {
556  int ret = ftp_send_command(s, enable_utf8_command, opts_codes, NULL);
557  if (ret == 200 || ret == 202)
558  s->utf8 = 1;
559  }
560 
561  return 0;
562 }
563 
565 {
566  char buf[CONTROL_BUFFER_SIZE], *response = NULL;
567  int err;
569  FTPContext *s = h->priv_data;
570  static const int connect_codes[] = {220, 0};
571 
572  if (!s->conn_control) {
573  ff_url_join(buf, sizeof(buf), "tcp", NULL,
574  s->hostname, s->server_control_port, NULL);
575  if (s->rw_timeout != -1) {
576  av_dict_set_int(&opts, "timeout", s->rw_timeout, 0);
577  } /* if option is not given, don't pass it and let tcp use its own default */
578  err = ffurl_open_whitelist(&s->conn_control, buf, AVIO_FLAG_READ_WRITE,
579  &h->interrupt_callback, &opts,
580  h->protocol_whitelist, h->protocol_blacklist, h);
581  av_dict_free(&opts);
582  if (err < 0) {
583  av_log(h, AV_LOG_ERROR, "Cannot open control connection\n");
584  return err;
585  }
586 
587  /* check if server is ready */
588  if (ftp_status(s, ((h->flags & AVIO_FLAG_WRITE) ? &response : NULL), connect_codes) != 220) {
589  av_log(h, AV_LOG_ERROR, "FTP server not ready for new users\n");
590  return AVERROR(EACCES);
591  }
592 
593  if ((h->flags & AVIO_FLAG_WRITE) && av_stristr(response, "pure-ftpd")) {
594  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.");
595  }
596  av_free(response);
597 
598  if ((err = ftp_auth(s)) < 0) {
599  av_log(h, AV_LOG_ERROR, "FTP authentication failed\n");
600  return err;
601  }
602 
603  if ((err = ftp_type(s)) < 0) {
604  av_log(h, AV_LOG_ERROR, "Set content type failed\n");
605  return err;
606  }
607 
608  ftp_features(s);
609  }
610  return 0;
611 }
612 
614 {
615  int err;
616  char buf[CONTROL_BUFFER_SIZE];
618  FTPContext *s = h->priv_data;
619 
620  if (!s->conn_data) {
621  /* Enter passive mode */
622  if (ftp_passive_mode_epsv(s) < 0) {
623  /* Use PASV as fallback */
624  if ((err = ftp_passive_mode(s)) < 0)
625  return err;
626  }
627  /* Open data connection */
628  ff_url_join(buf, sizeof(buf), "tcp", NULL, s->hostname, s->server_data_port, NULL);
629  if (s->rw_timeout != -1) {
630  av_dict_set_int(&opts, "timeout", s->rw_timeout, 0);
631  } /* if option is not given, don't pass it and let tcp use its own default */
632  err = ffurl_open_whitelist(&s->conn_data, buf, h->flags,
633  &h->interrupt_callback, &opts,
634  h->protocol_whitelist, h->protocol_blacklist, h);
635  av_dict_free(&opts);
636  if (err < 0)
637  return err;
638 
639  if (s->position)
640  if ((err = ftp_restart(s, s->position)) < 0)
641  return err;
642  }
643  s->state = READY;
644  return 0;
645 }
646 
647 static int ftp_abort(URLContext *h)
648 {
649  static const char *command = "ABOR\r\n";
650  int err;
651  static const int abor_codes[] = {225, 226, 0};
652  FTPContext *s = h->priv_data;
653 
654  /* According to RCF 959:
655  "ABOR command tells the server to abort the previous FTP
656  service command and any associated transfer of data."
657 
658  There are FTP server implementations that don't response
659  to any commands during data transfer in passive mode (including ABOR).
660 
661  This implementation closes data connection by force.
662  */
663 
664  if (ftp_send_command(s, command, NULL, NULL) < 0) {
666  if ((err = ftp_connect_control_connection(h)) < 0) {
667  av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");
668  return err;
669  }
670  } else {
672  if (ftp_status(s, NULL, abor_codes) < 225) {
673  /* wu-ftpd also closes control connection after data connection closing */
674  ffurl_closep(&s->conn_control);
675  if ((err = ftp_connect_control_connection(h)) < 0) {
676  av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");
677  return err;
678  }
679  }
680  }
681 
682  return 0;
683 }
684 
685 static int ftp_connect(URLContext *h, const char *url)
686 {
687  char proto[10], path[MAX_URL_SIZE], credentials[MAX_URL_SIZE], hostname[MAX_URL_SIZE];
688  const char *tok_user = NULL, *tok_pass = NULL;
689  char *newpath = NULL;
690  int err;
691  FTPContext *s = h->priv_data;
692 
693  s->state = DISCONNECTED;
694  s->listing_method = UNKNOWN_METHOD;
695  s->filesize = -1;
696  s->position = 0;
697  s->features = NULL;
698 
699  av_url_split(proto, sizeof(proto),
700  credentials, sizeof(credentials),
701  hostname, sizeof(hostname),
702  &s->server_control_port,
703  path, sizeof(path),
704  url);
705 
706  if (!*credentials) {
707  if (!s->option_user) {
708  tok_user = "anonymous";
709  tok_pass = av_x_if_null(s->anonymous_password, "nopassword");
710  } else {
711  tok_user = s->option_user;
712  tok_pass = s->option_password;
713  }
714  s->user = av_strdup(tok_user);
715  s->password = av_strdup(tok_pass);
716  } else {
717  char *pass = strchr(credentials, ':');
718  if (pass) {
719  *pass++ = '\0';
720  tok_pass = pass;
721  s->password = ff_urldecode(pass, 0);
722  } else {
723  tok_pass = s->option_password;
724  s->password = av_strdup(tok_pass);
725  }
726  s->user = ff_urldecode(credentials, 0);
727  }
728  s->hostname = av_strdup(hostname);
729  if (!s->hostname || !s->user || (tok_pass && !s->password)) {
730  return AVERROR(ENOMEM);
731  }
732 
733  if (s->server_control_port < 0 || s->server_control_port > 65535)
734  s->server_control_port = 21;
735 
736  if ((err = ftp_connect_control_connection(h)) < 0)
737  return err;
738 
739  if ((err = ftp_current_dir(s)) < 0)
740  return err;
741 
742  newpath = av_append_path_component(s->path, path);
743  if (!newpath)
744  return AVERROR(ENOMEM);
745  av_free(s->path);
746  s->path = newpath;
747 
748  return 0;
749 }
750 
751 static int ftp_open(URLContext *h, const char *url, int flags)
752 {
753  FTPContext *s = h->priv_data;
754  int err;
755 
756  ff_dlog(h, "ftp protocol open\n");
757 
758  if ((err = ftp_connect(h, url)) < 0)
759  goto fail;
760 
761  if (ftp_restart(s, 0) < 0) {
762  h->is_streamed = 1;
763  } else {
764  ftp_file_size(s);
765  if (s->write_seekable != 1 && flags & AVIO_FLAG_WRITE)
766  h->is_streamed = 1;
767  }
768 
769  return 0;
770 
771  fail:
772  av_log(h, AV_LOG_ERROR, "FTP open failed\n");
773  ftp_close(h);
774  return err;
775 }
776 
777 static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
778 {
779  FTPContext *s = h->priv_data;
780  int err;
781  int64_t new_pos;
782 
783  ff_dlog(h, "ftp protocol seek %"PRId64" %d\n", pos, whence);
784 
785  switch(whence) {
786  case AVSEEK_SIZE:
787  return s->filesize;
788  case SEEK_SET:
789  new_pos = pos;
790  break;
791  case SEEK_CUR:
792  new_pos = s->position + pos;
793  break;
794  case SEEK_END:
795  if (s->filesize < 0)
796  return AVERROR(EIO);
797  new_pos = s->filesize + pos;
798  break;
799  default:
800  return AVERROR(EINVAL);
801  }
802 
803  if (h->is_streamed)
804  return AVERROR(EIO);
805 
806  if (new_pos < 0) {
807  av_log(h, AV_LOG_ERROR, "Seeking to nagative position.\n");
808  return AVERROR(EINVAL);
809  }
810 
811  if (new_pos != s->position) {
812  if ((err = ftp_abort(h)) < 0)
813  return err;
814  s->position = new_pos;
815  }
816  return new_pos;
817 }
818 
819 static int ftp_read(URLContext *h, unsigned char *buf, int size)
820 {
821  FTPContext *s = h->priv_data;
822  int read, err, retry_done = 0;
823 
824  ff_dlog(h, "ftp protocol read %d bytes\n", size);
825  retry:
826  if (s->state == ENDOFFILE)
827  return AVERROR_EOF;
828  if (s->state == DISCONNECTED) {
829  if ((err = ftp_connect_data_connection(h)) < 0)
830  return err;
831  }
832  if (s->state == READY) {
833  if ((err = ftp_retrieve(s)) < 0)
834  return err;
835  }
836  if (s->conn_data && s->state == DOWNLOADING) {
837  read = ffurl_read(s->conn_data, buf, size);
838  if (read >= 0) {
839  s->position += read;
840  s->filesize = FFMAX(s->filesize, s->position);
841  }
842  if (read == AVERROR_EOF) {
843  static const int retr_codes[] = {226, 250, 425, 426, 451, 0};
844  char *response = NULL;
845  err = ftp_status(s, &response, retr_codes);
846  if (err == 226) {
848  av_freep(&response);
849  s->state = ENDOFFILE;
850  return AVERROR_EOF;
851  }
852  /* 250 is not allowed, any other status means some kind of error */
853  av_log(h, AV_LOG_ERROR, "FTP transfer failed: %s\n", response ? response : (err < 0 ? av_err2str(err) : "?"));
854  av_freep(&response);
855  read = AVERROR(EIO);
856  }
857  if (read <= 0 && !h->is_streamed) {
858  /* Server closed connection. Probably due to inactivity */
859  av_log(h, AV_LOG_INFO, "Reconnect to FTP server.\n");
860  if ((err = ftp_abort(h)) < 0)
861  return err;
862  if (!retry_done) {
863  retry_done = 1;
864  goto retry;
865  }
866  }
867  return read;
868  }
869 
870  av_log(h, AV_LOG_DEBUG, "FTP read failed\n");
871  return AVERROR(EIO);
872 }
873 
874 static int ftp_write(URLContext *h, const unsigned char *buf, int size)
875 {
876  int err;
877  FTPContext *s = h->priv_data;
878  int written;
879 
880  ff_dlog(h, "ftp protocol write %d bytes\n", size);
881 
882  if (s->state == DISCONNECTED) {
883  if ((err = ftp_connect_data_connection(h)) < 0)
884  return err;
885  }
886  if (s->state == READY) {
887  if ((err = ftp_store(s)) < 0)
888  return err;
889  }
890  if (s->conn_data && s->state == UPLOADING) {
891  written = ffurl_write(s->conn_data, buf, size);
892  if (written > 0) {
893  s->position += written;
894  s->filesize = FFMAX(s->filesize, s->position);
895  }
896  return written;
897  }
898 
899  av_log(h, AV_LOG_ERROR, "FTP write failed\n");
900  return AVERROR(EIO);
901 }
902 
903 static int ftp_close(URLContext *h)
904 {
905  FTPContext *s = h->priv_data;
906 
907  ff_dlog(h, "ftp protocol close\n");
908 
910  av_freep(&s->user);
911  av_freep(&s->password);
912  av_freep(&s->hostname);
913  av_freep(&s->path);
914  av_freep(&s->features);
915 
916  return 0;
917 }
918 
920 {
921  FTPContext *s = h->priv_data;
922 
923  ff_dlog(h, "ftp protocol get_file_handle\n");
924 
925  if (s->conn_data)
926  return ffurl_get_file_handle(s->conn_data);
927 
928  return AVERROR(EIO);
929 }
930 
931 static int ftp_shutdown(URLContext *h, int flags)
932 {
933  FTPContext *s = h->priv_data;
934 
935  ff_dlog(h, "ftp protocol shutdown\n");
936 
937  if (s->conn_data)
938  return ffurl_shutdown(s->conn_data, flags);
939 
940  return AVERROR(EIO);
941 }
942 
944 {
945  FTPContext *s = h->priv_data;
946  int ret;
947 
948  if ((ret = ftp_connect(h, h->filename)) < 0)
949  goto fail;
950  if ((ret = ftp_set_dir(s)) < 0)
951  goto fail;
952  if ((ret = ftp_connect_data_connection(h)) < 0)
953  goto fail;
954  if ((ret = ftp_list(s)) < 0)
955  goto fail;
956  s->dir_buffer = av_malloc(DIR_BUFFER_SIZE);
957  if (!s->dir_buffer) {
958  ret = AVERROR(ENOMEM);
959  goto fail;
960  }
961  s->dir_buffer[0] = 0;
962  if (s->conn_data && s->state == LISTING_DIR)
963  return 0;
964  fail:
965  ffurl_closep(&s->conn_control);
966  ffurl_closep(&s->conn_data);
967  return ret;
968 }
969 
970 static int64_t ftp_parse_date(const char *date)
971 {
972  struct tm tv;
973  memset(&tv, 0, sizeof(struct tm));
974  av_small_strptime(date, "%Y%m%d%H%M%S", &tv);
975  return INT64_C(1000000) * av_timegm(&tv);
976 }
977 
978 static int ftp_parse_entry_nlst(char *line, AVIODirEntry *next)
979 {
980  next->name = av_strdup(line);
981  return 0;
982 }
983 
984 static int ftp_parse_entry_mlsd(char *mlsd, AVIODirEntry *next)
985 {
986  char *fact, *value;
987  char *saveptr = NULL, *p = mlsd;
988  ff_dlog(NULL, "%s\n", mlsd);
989  while(fact = av_strtok(p, ";", &saveptr)) {
990  p = NULL;
991  if (fact[0] == ' ') {
992  next->name = av_strdup(&fact[1]);
993  continue;
994  }
995  fact = av_strtok(fact, "=", &value);
996  if (!fact)
997  continue;
998  if (!av_strcasecmp(fact, "type")) {
999  if (!av_strcasecmp(value, "cdir") || !av_strcasecmp(value, "pdir"))
1000  return 1;
1001  if (!av_strcasecmp(value, "dir"))
1002  next->type = AVIO_ENTRY_DIRECTORY;
1003  else if (!av_strcasecmp(value, "file"))
1004  next->type = AVIO_ENTRY_FILE;
1005  else if (!av_strcasecmp(value, "OS.unix=slink:"))
1007  } else if (!av_strcasecmp(fact, "modify")) {
1009  } else if (!av_strcasecmp(fact, "UNIX.mode")) {
1010  next->filemode = strtoumax(value, NULL, 8);
1011  } else if (!av_strcasecmp(fact, "UNIX.uid") || !av_strcasecmp(fact, "UNIX.owner"))
1012  next->user_id = strtoumax(value, NULL, 10);
1013  else if (!av_strcasecmp(fact, "UNIX.gid") || !av_strcasecmp(fact, "UNIX.group"))
1014  next->group_id = strtoumax(value, NULL, 10);
1015  else if (!av_strcasecmp(fact, "size") || !av_strcasecmp(fact, "sizd"))
1016  next->size = strtoll(value, NULL, 10);
1017  }
1018  return 0;
1019 }
1020 
1021 /**
1022  * @return 0 on success, negative on error, positive on entry to discard.
1023  */
1024 static int ftp_parse_entry(URLContext *h, char *line, AVIODirEntry *next)
1025 {
1026  FTPContext *s = h->priv_data;
1027 
1028  switch (s->listing_method) {
1029  case MLSD:
1030  return ftp_parse_entry_mlsd(line, next);
1031  case NLST:
1032  return ftp_parse_entry_nlst(line, next);
1033  case UNKNOWN_METHOD:
1034  default:
1035  return -1;
1036  }
1037 }
1038 
1040 {
1041  FTPContext *s = h->priv_data;
1042  char *start, *found;
1043  int ret, retried;
1044 
1045  do {
1046  retried = 0;
1047  start = s->dir_buffer + s->dir_buffer_offset;
1048  while (!(found = strstr(start, "\n"))) {
1049  if (retried)
1050  return AVERROR(EIO);
1051  s->dir_buffer_size -= s->dir_buffer_offset;
1052  s->dir_buffer_offset = 0;
1053  if (s->dir_buffer_size)
1054  memmove(s->dir_buffer, start, s->dir_buffer_size);
1055  ret = ffurl_read(s->conn_data, s->dir_buffer + s->dir_buffer_size, DIR_BUFFER_SIZE - (s->dir_buffer_size + 1));
1056  if (ret < 0)
1057  return ret;
1058  if (!ret) {
1059  *next = NULL;
1060  return 0;
1061  }
1062  s->dir_buffer_size += ret;
1063  s->dir_buffer[s->dir_buffer_size] = 0;
1064  start = s->dir_buffer;
1065  retried = 1;
1066  }
1067  s->dir_buffer_offset += (found + 1 - start);
1068  found[0] = 0;
1069  if (found > start && found[-1] == '\r')
1070  found[-1] = 0;
1071 
1072  *next = ff_alloc_dir_entry();
1073  if (!*next)
1074  return AVERROR(ENOMEM);
1075  (*next)->utf8 = s->utf8;
1076  ret = ftp_parse_entry(h, start, *next);
1077  if (ret) {
1079  if (ret < 0)
1080  return ret;
1081  }
1082  } while (ret > 0);
1083  return 0;
1084 }
1085 
1087 {
1088  FTPContext *s = h->priv_data;
1089  av_freep(&s->dir_buffer);
1090  ffurl_closep(&s->conn_control);
1091  ffurl_closep(&s->conn_data);
1092  return 0;
1093 }
1094 
1096 {
1097  FTPContext *s = h->priv_data;
1098  char command[MAX_URL_SIZE];
1099  static const int del_codes[] = {250, 421, 450, 500, 501, 502, 530, 550, 0};
1100  static const int rmd_codes[] = {250, 421, 500, 501, 502, 530, 550, 0};
1101  int ret;
1102 
1103  if ((ret = ftp_connect(h, h->filename)) < 0)
1104  goto cleanup;
1105 
1106  ret = snprintf(command, sizeof(command), "DELE %s\r\n", s->path);
1107  if (ret >= sizeof(command)) {
1108  ret = AVERROR(ENOSYS);
1109  goto cleanup;
1110  }
1111 
1112  if (ftp_send_command(s, command, del_codes, NULL) == 250) {
1113  ret = 0;
1114  goto cleanup;
1115  }
1116 
1117  ret = snprintf(command, sizeof(command), "RMD %s\r\n", s->path);
1118  if (ret >= sizeof(command)) {
1119  ret = AVERROR(ENOSYS);
1120  goto cleanup;
1121  }
1122 
1123  if (ftp_send_command(s, command, rmd_codes, NULL) == 250)
1124  ret = 0;
1125  else
1126  ret = AVERROR(EIO);
1127 
1128 cleanup:
1129  ftp_close(h);
1130  return ret;
1131 }
1132 
1133 static int ftp_move(URLContext *h_src, URLContext *h_dst)
1134 {
1135  FTPContext *s = h_src->priv_data;
1136  char command[MAX_URL_SIZE], path[MAX_URL_SIZE];
1137  static const int rnfr_codes[] = {350, 421, 450, 500, 501, 502, 503, 530, 0};
1138  static const int rnto_codes[] = {250, 421, 500, 501, 502, 503, 530, 532, 553, 0};
1139  int ret;
1140 
1141  if ((ret = ftp_connect(h_src, h_src->filename)) < 0)
1142  goto cleanup;
1143 
1144  ret = snprintf(command, sizeof(command), "RNFR %s\r\n", s->path);
1145  if (ret >= sizeof(command)) {
1146  ret = AVERROR(ENOSYS);
1147  goto cleanup;
1148  }
1149 
1150  if (ftp_send_command(s, command, rnfr_codes, NULL) != 350) {
1151  ret = AVERROR(EIO);
1152  goto cleanup;
1153  }
1154 
1155  av_url_split(0, 0, 0, 0, 0, 0, 0,
1156  path, sizeof(path),
1157  h_dst->filename);
1158  ret = snprintf(command, sizeof(command), "RNTO %s\r\n", path);
1159  if (ret >= sizeof(command)) {
1160  ret = AVERROR(ENOSYS);
1161  goto cleanup;
1162  }
1163 
1164  if (ftp_send_command(s, command, rnto_codes, NULL) == 250)
1165  ret = 0;
1166  else
1167  ret = AVERROR(EIO);
1168 
1169 cleanup:
1170  ftp_close(h_src);
1171  return ret;
1172 }
1173 
1175  .name = "ftp",
1176  .url_open = ftp_open,
1177  .url_read = ftp_read,
1178  .url_write = ftp_write,
1179  .url_seek = ftp_seek,
1180  .url_close = ftp_close,
1181  .url_get_file_handle = ftp_get_file_handle,
1182  .url_shutdown = ftp_shutdown,
1183  .priv_data_size = sizeof(FTPContext),
1184  .priv_data_class = &ftp_context_class,
1185  .url_open_dir = ftp_open_dir,
1186  .url_read_dir = ftp_read_dir,
1187  .url_close_dir = ftp_close_dir,
1188  .url_delete = ftp_delete,
1189  .url_move = ftp_move,
1191  .default_whitelist = "tcp",
1192 };
ftp_seek
static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
Definition: ftp.c:777
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
ftp_get_line
static int ftp_get_line(FTPContext *s, char *line, int line_size)
Definition: ftp.c:119
FTPContext::user
char * user
Server user.
Definition: ftp.c:62
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
URLContext::filename
char * filename
specified URL
Definition: url.h:41
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:33
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
av_stristr
char * av_stristr(const char *s1, const char *s2)
Locate the first case-independent occurrence in the string haystack of the string needle.
Definition: avstring.c:58
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVIO_FLAG_READ_WRITE
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:638
ffurl_write
static int ffurl_write(URLContext *h, const uint8_t *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition: url.h:208
FTPContext::anonymous_password
const char * anonymous_password
Password to be used for anonymous user.
Definition: ftp.c:68
av_strcasecmp
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:207
ftp_abort
static int ftp_abort(URLContext *h)
Definition: ftp.c:647
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
AVIODirEntry::type
int type
Type of the entry.
Definition: avio.h:89
ftp_write
static int ftp_write(URLContext *h, const unsigned char *buf, int size)
Definition: ftp.c:874
FTPContext
Definition: ftp.c:53
AVOption
AVOption.
Definition: opt.h:251
AVSEEK_SIZE
#define AVSEEK_SIZE
ORing this as the "whence" parameter to a seek function causes it to return the filesize without seek...
Definition: avio.h:487
ff_ftp_protocol
const URLProtocol ff_ftp_protocol
Definition: ftp.c:1174
FTPContext::control_buf_ptr
uint8_t * control_buf_ptr
Definition: ftp.c:58
UNKNOWN
@ UNKNOWN
Definition: ftp.c:38
AVDictionary
Definition: dict.c:34
FTPContext::password
char * password
Server user's password.
Definition: ftp.c:63
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
DISCONNECTED
@ DISCONNECTED
Definition: ftp.c:43
URLProtocol
Definition: url.h:53
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
ftp_file_size
static int ftp_file_size(FTPContext *s)
Definition: ftp.c:403
av_append_path_component
char * av_append_path_component(const char *path, const char *component)
Append path component to the existing path.
Definition: avstring.c:296
OFFSET
#define OFFSET(x)
Definition: ftp.c:81
FTPContext::server_data_port
int server_data_port
Data connection port opened by server, -1 on error.
Definition: ftp.c:59
ff_urldecode
char * ff_urldecode(const char *url, int decode_plus_sign)
Decodes an URL from its percent-encoded form back into normal representation.
Definition: urldecode.c:35
AVIO_ENTRY_DIRECTORY
@ AVIO_ENTRY_DIRECTORY
Definition: avio.h:71
ftp_open
static int ftp_open(URLContext *h, const char *url, int flags)
Definition: ftp.c:751
fail
#define fail()
Definition: checkasm.h:138
ftp_close
static int ftp_close(URLContext *h)
Definition: ftp.c:903
ftp_shutdown
static int ftp_shutdown(URLContext *h, int flags)
Definition: ftp.c:931
AV_BPRINT_SIZE_AUTOMATIC
#define AV_BPRINT_SIZE_AUTOMATIC
av_timegm
time_t av_timegm(struct tm *tm)
Convert the decomposed UTC time in tm to a time_t value.
Definition: parseutils.c:570
READY
@ READY
Definition: ftp.c:39
URLContext::priv_data
void * priv_data
Definition: url.h:40
avio_free_directory_entry
void avio_free_directory_entry(AVIODirEntry **entry)
Free entry allocated by avio_read_dir().
Definition: avio.c:604
AVIODirEntry::modification_timestamp
int64_t modification_timestamp
Time of last modification in microseconds since unix epoch, -1 if unknown.
Definition: avio.h:93
ftp_passive_mode_epsv
static int ftp_passive_mode_epsv(FTPContext *s)
Definition: ftp.c:277
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
AVIO_ENTRY_SYMBOLIC_LINK
@ AVIO_ENTRY_SYMBOLIC_LINK
Definition: avio.h:73
ftp_context_class
static const AVClass ftp_context_class
Definition: ftp.c:93
ffurl_open_whitelist
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist, URLContext *parent)
Create an URLContext for accessing to the resource indicated by url, and open it.
Definition: avio.c:300
UNKNOWN_METHOD
@ UNKNOWN_METHOD
Definition: ftp.c:48
FTPContext::write_seekable
int write_seekable
Control seekability, 0 = disable, 1 = enable.
Definition: ftp.c:69
s
#define s(width, name)
Definition: cbs_vp9.c:198
FTPContext::dir_buffer_size
size_t dir_buffer_size
Definition: ftp.c:74
ftp_read_dir
static int ftp_read_dir(URLContext *h, AVIODirEntry **next)
Definition: ftp.c:1039
av_strtok
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition: avstring.c:178
FTPContext::dir_buffer_offset
size_t dir_buffer_offset
Definition: ftp.c:75
UPLOADING
@ UPLOADING
Definition: ftp.c:41
D
#define D
Definition: ftp.c:82
ff_url_join
int ff_url_join(char *str, int size, const char *proto, const char *authorization, const char *hostname, int port, const char *fmt,...)
Definition: url.c:40
ftp_parse_entry_nlst
static int ftp_parse_entry_nlst(char *line, AVIODirEntry *next)
Definition: ftp.c:978
FTPListingMethod
FTPListingMethod
Definition: ftp.c:47
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:637
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ftp_has_feature
static int ftp_has_feature(FTPContext *s, const char *feature_name)
Definition: ftp.c:535
internal.h
opts
AVDictionary * opts
Definition: movenc.c:50
MLSD
@ MLSD
Definition: ftp.c:50
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
NULL
#define NULL
Definition: coverity.c:32
AVIODirEntry::size
int64_t size
File size in bytes, -1 if unknown.
Definition: avio.h:92
FTPContext::listing_method
FTPListingMethod listing_method
Called listing method.
Definition: ftp.c:71
E
#define E
Definition: ftp.c:83
AVIODirEntry::name
char * name
Filename.
Definition: avio.h:88
ftp_auth
static int ftp_auth(FTPContext *s)
Definition: ftp.c:245
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
ffurl_shutdown
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
Definition: avio.c:660
ftp_get_file_handle
static int ftp_get_file_handle(URLContext *h)
Definition: ftp.c:919
parseutils.h
ftp_send_command
static int ftp_send_command(FTPContext *s, const char *command, const int response_codes[], char **response)
Definition: ftp.c:208
ftp_delete
static int ftp_delete(URLContext *h)
Definition: ftp.c:1095
AVIO_ENTRY_FILE
@ AVIO_ENTRY_FILE
Definition: avio.h:75
ftp_list
static int ftp_list(FTPContext *s)
Definition: ftp.c:524
time.h
AVIODirEntry::group_id
int64_t group_id
Group ID of owner, -1 if unknown.
Definition: avio.h:100
AVIODirEntry::filemode
int64_t filemode
Unix file mode, -1 if unknown.
Definition: avio.h:101
options
static const AVOption options[]
Definition: ftp.c:84
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
ftp_parse_date
static int64_t ftp_parse_date(const char *date)
Definition: ftp.c:970
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
CONTROL_BUFFER_SIZE
#define CONTROL_BUFFER_SIZE
Definition: ftp.c:34
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:121
ftp_status
static int ftp_status(FTPContext *s, char **line, const int response_codes[])
Definition: ftp.c:147
size
int size
Definition: twinvq_data.h:10344
AVIODirEntry
Describes single entry of the directory.
Definition: avio.h:87
URLProtocol::name
const char * name
Definition: url.h:54
FTPContext::state
FTPState state
State of data connection.
Definition: ftp.c:70
ftp_parse_entry
static int ftp_parse_entry(URLContext *h, char *line, AVIODirEntry *next)
Definition: ftp.c:1024
FTPContext::conn_control
URLContext * conn_control
Control connection.
Definition: ftp.c:55
ftp_close_dir
static int ftp_close_dir(URLContext *h)
Definition: ftp.c:1086
LISTING_DIR
@ LISTING_DIR
Definition: ftp.c:42
ftp_open_dir
static int ftp_open_dir(URLContext *h)
Definition: ftp.c:943
FTPContext::hostname
char * hostname
Server address.
Definition: ftp.c:61
line
Definition: graph2dot.c:48
FTPContext::position
int64_t position
Current position, calculated.
Definition: ftp.c:66
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:225
fact
static double fact(double i)
Definition: af_aiir.c:943
FTPContext::filesize
int64_t filesize
Size of file on server, -1 on error.
Definition: ftp.c:65
FTPState
FTPState
Definition: ftp.c:37
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
ENDOFFILE
@ ENDOFFILE
Definition: ftp.c:44
AVIODirEntry::user_id
int64_t user_id
User ID of owner, -1 if unknown.
Definition: avio.h:99
ff_alloc_dir_entry
AVIODirEntry * ff_alloc_dir_entry(void)
Allocate directory entry with default values.
Definition: url.c:327
bprint.h
URLContext
Definition: url.h:37
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
ftp_read
static int ftp_read(URLContext *h, unsigned char *buf, int size)
Definition: ftp.c:819
ftp_list_nlst
static int ftp_list_nlst(FTPContext *s)
Definition: ftp.c:513
DIR_BUFFER_SIZE
#define DIR_BUFFER_SIZE
Definition: ftp.c:35
internal.h
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
ftp_retrieve
static int ftp_retrieve(FTPContext *s)
Definition: ftp.c:426
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:358
FTPContext::utf8
int utf8
Definition: ftp.c:76
url.h
len
int len
Definition: vorbis_enc_data.h:426
ftp_close_both_connections
static void ftp_close_both_connections(FTPContext *s)
Definition: ftp.c:239
ffurl_closep
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:439
FTPContext::option_password
const char * option_password
Password to be used if none given in the URL.
Definition: ftp.c:78
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
ftp_connect_control_connection
static int ftp_connect_control_connection(URLContext *h)
Definition: ftp.c:564
FTPContext::path
char * path
Path to resource on server.
Definition: ftp.c:64
FTPContext::option_user
const char * option_user
User to be used if none given in the URL.
Definition: ftp.c:77
pos
unsigned int pos
Definition: spdifenc.c:413
avformat.h
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
av_small_strptime
char * av_small_strptime(const char *p, const char *fmt, struct tm *dt)
Simplified version of strptime.
Definition: parseutils.c:491
FTPContext::conn_data
URLContext * conn_data
Data connection, NULL when not connected.
Definition: ftp.c:56
MAX_URL_SIZE
#define MAX_URL_SIZE
Definition: internal.h:30
ftp_passive_mode
static int ftp_passive_mode(FTPContext *s)
Definition: ftp.c:319
urldecode.h
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
DOWNLOADING
@ DOWNLOADING
Definition: ftp.c:40
ftp_features
static int ftp_features(FTPContext *s)
Definition: ftp.c:543
ftp_current_dir
static int ftp_current_dir(FTPContext *s)
Definition: ftp.c:365
ftp_store
static int ftp_store(FTPContext *s)
Definition: ftp.c:445
ftp_getc
static int ftp_getc(FTPContext *s)
Definition: ftp.c:102
FTPContext::server_control_port
int server_control_port
Control connection port, default is 21.
Definition: ftp.c:60
ftp_connect_data_connection
static int ftp_connect_data_connection(URLContext *h)
Definition: ftp.c:613
av_dict_set_int
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition: dict.c:169
ftp_list_mlsd
static int ftp_list_mlsd(FTPContext *s)
Definition: ftp.c:502
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:270
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
NLST
@ NLST
Definition: ftp.c:49
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
d
d
Definition: ffmpeg_filter.c:368
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
ftp_close_data_connection
static void ftp_close_data_connection(FTPContext *s)
Definition: ftp.c:233
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ftp_type
static int ftp_type(FTPContext *s)
Definition: ftp.c:464
FTPContext::features
char * features
List of server's features represented as raw response.
Definition: ftp.c:72
ftp_parse_entry_mlsd
static int ftp_parse_entry_mlsd(char *mlsd, AVIODirEntry *next)
Definition: ftp.c:984
h
h
Definition: vp9dsp_template.c:2038
ftp_restart
static int ftp_restart(FTPContext *s, int64_t pos)
Definition: ftp.c:475
FTPContext::dir_buffer
char * dir_buffer
Definition: ftp.c:73
FTPContext::rw_timeout
int rw_timeout
Network timeout.
Definition: ftp.c:67
avstring.h
ftp_move
static int ftp_move(URLContext *h_src, URLContext *h_dst)
Definition: ftp.c:1133
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
ftp_set_dir
static int ftp_set_dir(FTPContext *s)
Definition: ftp.c:487
snprintf
#define snprintf
Definition: snprintf.h:34
ffurl_get_file_handle
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:627
ftp_connect
static int ftp_connect(URLContext *h, const char *url)
Definition: ftp.c:685
line
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
Definition: swscale.txt:40
read
static uint32_t BS_FUNC() read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
Definition: bitstream_template.h:231
av_x_if_null
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
Definition: avutil.h:312
ffurl_read
static int ffurl_read(URLContext *h, uint8_t *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf.
Definition: url.h:183