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