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