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