FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 "libavutil/avstring.h"
22 #include "avformat.h"
23 #include "internal.h"
24 #include "url.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/bprint.h"
27 
28 #define CONTROL_BUFFER_SIZE 1024
29 
30 typedef enum {
36 } FTPState;
37 
38 typedef struct {
39  const AVClass *class;
40  URLContext *conn_control; /**< Control connection */
41  URLContext *conn_data; /**< Data connection, NULL when not connected */
42  uint8_t control_buffer[CONTROL_BUFFER_SIZE]; /**< Control connection buffer */
43  uint8_t *control_buf_ptr, *control_buf_end;
44  int server_data_port; /**< Data connection port opened by server, -1 on error. */
45  int server_control_port; /**< Control connection port, default is 21 */
46  char *hostname; /**< Server address. */
47  char *user; /**< Server user */
48  char *password; /**< Server user's password */
49  char *path; /**< Path to resource on server. */
50  int64_t filesize; /**< Size of file on server, -1 on error. */
51  int64_t position; /**< Current position, calculated. */
52  int rw_timeout; /**< Network timeout. */
53  const char *anonymous_password; /**< Password to be used for anonymous user. An email should be used. */
54  int write_seekable; /**< Control seekability, 0 = disable, 1 = enable. */
55  FTPState state; /**< State of data connection */
56 } FTPContext;
57 
58 #define OFFSET(x) offsetof(FTPContext, x)
59 #define D AV_OPT_FLAG_DECODING_PARAM
60 #define E AV_OPT_FLAG_ENCODING_PARAM
61 static const AVOption options[] = {
62  {"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
63  {"ftp-write-seekable", "control seekability of connection during encoding", OFFSET(write_seekable), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E },
64  {"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 },
65  {NULL}
66 };
67 
68 static const AVClass ftp_context_class = {
69  .class_name = "ftp",
70  .item_name = av_default_item_name,
71  .option = options,
72  .version = LIBAVUTIL_VERSION_INT,
73 };
74 
75 static int ftp_close(URLContext *h);
76 
77 static int ftp_getc(FTPContext *s)
78 {
79  int len;
80  if (s->control_buf_ptr >= s->control_buf_end) {
82  if (len < 0) {
83  return len;
84  } else if (!len) {
85  return -1;
86  } else {
89  }
90  }
91  return *s->control_buf_ptr++;
92 }
93 
94 static int ftp_get_line(FTPContext *s, char *line, int line_size)
95 {
96  int ch;
97  char *q = line;
98 
99  for (;;) {
100  ch = ftp_getc(s);
101  if (ch < 0) {
102  return ch;
103  }
104  if (ch == '\n') {
105  /* process line */
106  if (q > line && q[-1] == '\r')
107  q--;
108  *q = '\0';
109  return 0;
110  } else {
111  if ((q - line) < line_size - 1)
112  *q++ = ch;
113  }
114  }
115 }
116 
117 /*
118  * This routine returns ftp server response code.
119  * Server may send more than one response for a certain command.
120  * First expected code is returned.
121  */
122 static int ftp_status(FTPContext *s, char **line, const int response_codes[])
123 {
124  int err, i, dash = 0, result = 0, code_found = 0, linesize;
125  char buf[CONTROL_BUFFER_SIZE];
126  AVBPrint line_buffer;
127 
128  if (line)
129  av_bprint_init(&line_buffer, 0, AV_BPRINT_SIZE_AUTOMATIC);
130 
131  while (!code_found || dash) {
132  if ((err = ftp_get_line(s, buf, sizeof(buf))) < 0) {
133  if (line)
134  av_bprint_finalize(&line_buffer, NULL);
135  return err;
136  }
137 
138  av_log(s, AV_LOG_DEBUG, "%s\n", buf);
139 
140  linesize = strlen(buf);
141  err = 0;
142  if (linesize >= 3) {
143  for (i = 0; i < 3; ++i) {
144  if (buf[i] < '0' || buf[i] > '9') {
145  err = 0;
146  break;
147  }
148  err *= 10;
149  err += buf[i] - '0';
150  }
151  }
152 
153  if (!code_found) {
154  if (err >= 500) {
155  code_found = 1;
156  result = err;
157  } else
158  for (i = 0; response_codes[i]; ++i) {
159  if (err == response_codes[i]) {
160  code_found = 1;
161  result = err;
162  break;
163  }
164  }
165  }
166  if (code_found) {
167  if (line)
168  av_bprintf(&line_buffer, "%s\r\n", buf);
169  if (linesize >= 4) {
170  if (!dash && buf[3] == '-')
171  dash = err;
172  else if (err == dash && buf[3] == ' ')
173  dash = 0;
174  }
175  }
176  }
177 
178  if (line)
179  av_bprint_finalize(&line_buffer, line);
180  return result;
181 }
182 
183 static int ftp_send_command(FTPContext *s, const char *command,
184  const int response_codes[], char **response)
185 {
186  int err;
187 
188  if (response)
189  *response = NULL;
190 
191  if ((err = ffurl_write(s->conn_control, command, strlen(command))) < 0)
192  return err;
193  if (!err)
194  return -1;
195 
196  /* return status */
197  if (response_codes) {
198  return ftp_status(s, response, response_codes);
199  }
200  return 0;
201 }
202 
204 {
205  ffurl_closep(&s->conn_data);
206  s->position = 0;
207  s->state = DISCONNECTED;
208 }
209 
211 {
214 }
215 
216 static int ftp_auth(FTPContext *s)
217 {
218  char buf[CONTROL_BUFFER_SIZE];
219  int err;
220  static const int user_codes[] = {331, 230, 0};
221  static const int pass_codes[] = {230, 0};
222 
223  snprintf(buf, sizeof(buf), "USER %s\r\n", s->user);
224  err = ftp_send_command(s, buf, user_codes, NULL);
225  if (err == 331) {
226  if (s->password) {
227  snprintf(buf, sizeof(buf), "PASS %s\r\n", s->password);
228  err = ftp_send_command(s, buf, pass_codes, NULL);
229  } else
230  return AVERROR(EACCES);
231  }
232  if (err != 230)
233  return AVERROR(EACCES);
234 
235  return 0;
236 }
237 
239 {
240  char *res = NULL, *start = NULL, *end = NULL;
241  int i;
242  static const char d = '|';
243  static const char *command = "EPSV\r\n";
244  static const int epsv_codes[] = {229, 0};
245 
246  if (ftp_send_command(s, command, epsv_codes, &res) != 229 || !res)
247  goto fail;
248 
249  for (i = 0; res[i]; ++i) {
250  if (res[i] == '(') {
251  start = res + i + 1;
252  } else if (res[i] == ')') {
253  end = res + i;
254  break;
255  }
256  }
257  if (!start || !end)
258  goto fail;
259 
260  *end = '\0';
261  if (strlen(start) < 5)
262  goto fail;
263  if (start[0] != d || start[1] != d || start[2] != d || end[-1] != d)
264  goto fail;
265  start += 3;
266  end[-1] = '\0';
267 
268  s->server_data_port = atoi(start);
269  av_dlog(s, "Server data port: %d\n", s->server_data_port);
270 
271  av_free(res);
272  return 0;
273 
274  fail:
275  av_free(res);
276  s->server_data_port = -1;
277  return AVERROR(ENOSYS);
278 }
279 
281 {
282  char *res = NULL, *start = NULL, *end = NULL;
283  int i;
284  static const char *command = "PASV\r\n";
285  static const int pasv_codes[] = {227, 0};
286 
287  if (ftp_send_command(s, command, pasv_codes, &res) != 227 || !res)
288  goto fail;
289 
290  for (i = 0; res[i]; ++i) {
291  if (res[i] == '(') {
292  start = res + i + 1;
293  } else if (res[i] == ')') {
294  end = res + i;
295  break;
296  }
297  }
298  if (!start || !end)
299  goto fail;
300 
301  *end = '\0';
302  /* skip ip */
303  if (!av_strtok(start, ",", &end)) goto fail;
304  if (!av_strtok(end, ",", &end)) goto fail;
305  if (!av_strtok(end, ",", &end)) goto fail;
306  if (!av_strtok(end, ",", &end)) goto fail;
307 
308  /* parse port number */
309  start = av_strtok(end, ",", &end);
310  if (!start) goto fail;
311  s->server_data_port = atoi(start) * 256;
312  start = av_strtok(end, ",", &end);
313  if (!start) goto fail;
314  s->server_data_port += atoi(start);
315  av_dlog(s, "Server data port: %d\n", s->server_data_port);
316 
317  av_free(res);
318  return 0;
319 
320  fail:
321  av_free(res);
322  s->server_data_port = -1;
323  return AVERROR(EIO);
324 }
325 
327 {
328  char *res = NULL, *start = NULL, *end = NULL;
329  int i;
330  static const char *command = "PWD\r\n";
331  static const int pwd_codes[] = {257, 0};
332 
333  if (ftp_send_command(s, command, pwd_codes, &res) != 257 || !res)
334  goto fail;
335 
336  for (i = 0; res[i]; ++i) {
337  if (res[i] == '"') {
338  if (!start) {
339  start = res + i + 1;
340  continue;
341  }
342  end = res + i;
343  break;
344  }
345  }
346 
347  if (!end)
348  goto fail;
349 
350  if (end > res && end[-1] == '/') {
351  end[-1] = '\0';
352  } else
353  *end = '\0';
354  s->path = av_strdup(start);
355 
356  av_free(res);
357 
358  if (!s->path)
359  return AVERROR(ENOMEM);
360  return 0;
361 
362  fail:
363  av_free(res);
364  return AVERROR(EIO);
365 }
366 
368 {
370  char *res = NULL;
371  static const int size_codes[] = {213, 0};
372 
373  snprintf(command, sizeof(command), "SIZE %s\r\n", s->path);
374  if (ftp_send_command(s, command, size_codes, &res) == 213 && res) {
375  s->filesize = strtoll(&res[4], NULL, 10);
376  } else {
377  s->filesize = -1;
378  av_free(res);
379  return AVERROR(EIO);
380  }
381 
382  av_free(res);
383  return 0;
384 }
385 
387 {
389  static const int retr_codes[] = {150, 0};
390 
391  snprintf(command, sizeof(command), "RETR %s\r\n", s->path);
392  if (ftp_send_command(s, command, retr_codes, NULL) != 150)
393  return AVERROR(EIO);
394 
395  s->state = DOWNLOADING;
396 
397  return 0;
398 }
399 
400 static int ftp_store(FTPContext *s)
401 {
403  static const int stor_codes[] = {150, 0};
404 
405  snprintf(command, sizeof(command), "STOR %s\r\n", s->path);
406  if (ftp_send_command(s, command, stor_codes, NULL) != 150)
407  return AVERROR(EIO);
408 
409  s->state = UPLOADING;
410 
411  return 0;
412 }
413 
414 static int ftp_type(FTPContext *s)
415 {
416  static const char *command = "TYPE I\r\n";
417  static const int type_codes[] = {200, 0};
418 
419  if (ftp_send_command(s, command, type_codes, NULL) != 200)
420  return AVERROR(EIO);
421 
422  return 0;
423 }
424 
425 static int ftp_restart(FTPContext *s, int64_t pos)
426 {
428  static const int rest_codes[] = {350, 0};
429 
430  snprintf(command, sizeof(command), "REST %"PRId64"\r\n", pos);
431  if (ftp_send_command(s, command, rest_codes, NULL) != 350)
432  return AVERROR(EIO);
433 
434  return 0;
435 }
436 
438 {
439  static const char *feat_command = "FEAT\r\n";
440  static const char *enable_utf8_command = "OPTS UTF8 ON\r\n";
441  static const int feat_codes[] = {211, 0};
442  static const int opts_codes[] = {200, 451};
443  char *feat = NULL;
444 
445  if (ftp_send_command(s, feat_command, feat_codes, &feat) == 211) {
446  if (av_stristr(feat, "UTF8"))
447  ftp_send_command(s, enable_utf8_command, opts_codes, NULL);
448  }
449  av_freep(&feat);
450 
451  return 0;
452 }
453 
455 {
456  char buf[CONTROL_BUFFER_SIZE], *response = NULL;
457  int err;
458  AVDictionary *opts = NULL;
459  FTPContext *s = h->priv_data;
460  static const int connect_codes[] = {220, 0};
461 
462  if (!s->conn_control) {
463  ff_url_join(buf, sizeof(buf), "tcp", NULL,
465  if (s->rw_timeout != -1) {
466  av_dict_set_int(&opts, "timeout", s->rw_timeout, 0);
467  } /* if option is not given, don't pass it and let tcp use its own default */
469  &h->interrupt_callback, &opts);
470  av_dict_free(&opts);
471  if (err < 0) {
472  av_log(h, AV_LOG_ERROR, "Cannot open control connection\n");
473  return err;
474  }
475 
476  /* check if server is ready */
477  if (ftp_status(s, ((h->flags & AVIO_FLAG_WRITE) ? &response : NULL), connect_codes) != 220) {
478  av_log(h, AV_LOG_ERROR, "FTP server not ready for new users\n");
479  return AVERROR(EACCES);
480  }
481 
482  if ((h->flags & AVIO_FLAG_WRITE) && av_stristr(response, "pure-ftpd")) {
483  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.");
484  }
485  av_free(response);
486 
487  if ((err = ftp_auth(s)) < 0) {
488  av_log(h, AV_LOG_ERROR, "FTP authentication failed\n");
489  return err;
490  }
491 
492  if ((err = ftp_type(s)) < 0) {
493  av_log(h, AV_LOG_ERROR, "Set content type failed\n");
494  return err;
495  }
496 
497  ftp_features(s);
498  }
499  return 0;
500 }
501 
503 {
504  int err;
505  char buf[CONTROL_BUFFER_SIZE];
506  AVDictionary *opts = NULL;
507  FTPContext *s = h->priv_data;
508 
509  if (!s->conn_data) {
510  /* Enter passive mode */
511  if (ftp_passive_mode_epsv(s) < 0) {
512  /* Use PASV as fallback */
513  if ((err = ftp_passive_mode(s)) < 0)
514  return err;
515  }
516  /* Open data connection */
517  ff_url_join(buf, sizeof(buf), "tcp", NULL, s->hostname, s->server_data_port, NULL);
518  if (s->rw_timeout != -1) {
519  av_dict_set_int(&opts, "timeout", s->rw_timeout, 0);
520  } /* if option is not given, don't pass it and let tcp use its own default */
521  err = ffurl_open(&s->conn_data, buf, h->flags,
522  &h->interrupt_callback, &opts);
523  av_dict_free(&opts);
524  if (err < 0)
525  return err;
526 
527  if (s->position)
528  if ((err = ftp_restart(s, s->position)) < 0)
529  return err;
530  }
531  s->state = READY;
532  return 0;
533 }
534 
535 static int ftp_abort(URLContext *h)
536 {
537  static const char *command = "ABOR\r\n";
538  int err;
539  static const int abor_codes[] = {225, 226, 0};
540  FTPContext *s = h->priv_data;
541 
542  /* According to RCF 959:
543  "ABOR command tells the server to abort the previous FTP
544  service command and any associated transfer of data."
545 
546  There are FTP server implementations that don't response
547  to any commands during data transfer in passive mode (including ABOR).
548 
549  This implementation closes data connection by force.
550  */
551 
552  if (ftp_send_command(s, command, NULL, NULL) < 0) {
554  if ((err = ftp_connect_control_connection(h)) < 0) {
555  av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");
556  return err;
557  }
558  } else {
560  if (ftp_status(s, NULL, abor_codes) < 225) {
561  /* wu-ftpd also closes control connection after data connection closing */
563  if ((err = ftp_connect_control_connection(h)) < 0) {
564  av_log(h, AV_LOG_ERROR, "Reconnect failed.\n");
565  return err;
566  }
567  }
568  }
569 
570  return 0;
571 }
572 
573 static int ftp_open(URLContext *h, const char *url, int flags)
574 {
575  char proto[10], path[MAX_URL_SIZE], credencials[MAX_URL_SIZE], hostname[MAX_URL_SIZE];
576  const char *tok_user = NULL, *tok_pass = NULL;
577  char *end = NULL;
578  int err;
579  size_t pathlen;
580  FTPContext *s = h->priv_data;
581 
582  av_dlog(h, "ftp protocol open\n");
583 
584  s->state = DISCONNECTED;
585  s->filesize = -1;
586  s->position = 0;
587 
588  av_url_split(proto, sizeof(proto),
589  credencials, sizeof(credencials),
590  hostname, sizeof(hostname),
592  path, sizeof(path),
593  url);
594 
595  tok_user = av_strtok(credencials, ":", &end);
596  tok_pass = av_strtok(end, ":", &end);
597  if (!tok_user) {
598  tok_user = "anonymous";
599  tok_pass = av_x_if_null(s->anonymous_password, "nopassword");
600  }
601  s->user = av_strdup(tok_user);
602  s->password = av_strdup(tok_pass);
603  s->hostname = av_strdup(hostname);
604  if (!s->hostname || !s->user || (tok_pass && !s->password)) {
605  err = AVERROR(ENOMEM);
606  goto fail;
607  }
608 
609  if (s->server_control_port < 0 || s->server_control_port > 65535)
610  s->server_control_port = 21;
611 
612  if ((err = ftp_connect_control_connection(h)) < 0)
613  goto fail;
614 
615  if ((err = ftp_current_dir(s)) < 0)
616  goto fail;
617  pathlen = strlen(s->path) + strlen(path) + 1;
618  if ((err = av_reallocp(&s->path, pathlen)) < 0)
619  goto fail;
620  av_strlcat(s->path + strlen(s->path), path, pathlen);
621 
622  if (ftp_restart(s, 0) < 0) {
623  h->is_streamed = 1;
624  } else {
625  if (ftp_file_size(s) < 0 && flags & AVIO_FLAG_READ)
626  h->is_streamed = 1;
627  if (s->write_seekable != 1 && flags & AVIO_FLAG_WRITE)
628  h->is_streamed = 1;
629  }
630 
631  return 0;
632 
633  fail:
634  av_log(h, AV_LOG_ERROR, "FTP open failed\n");
635  ftp_close(h);
636  return err;
637 }
638 
639 static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
640 {
641  FTPContext *s = h->priv_data;
642  int err;
643  int64_t new_pos, fake_pos;
644 
645  av_dlog(h, "ftp protocol seek %"PRId64" %d\n", pos, whence);
646 
647  switch(whence) {
648  case AVSEEK_SIZE:
649  return s->filesize;
650  case SEEK_SET:
651  new_pos = pos;
652  break;
653  case SEEK_CUR:
654  new_pos = s->position + pos;
655  break;
656  case SEEK_END:
657  if (s->filesize < 0)
658  return AVERROR(EIO);
659  new_pos = s->filesize + pos;
660  break;
661  default:
662  return AVERROR(EINVAL);
663  }
664 
665  if (h->is_streamed)
666  return AVERROR(EIO);
667 
668  if (new_pos < 0) {
669  av_log(h, AV_LOG_ERROR, "Seeking to nagative position.\n");
670  return AVERROR(EINVAL);
671  }
672 
673  fake_pos = s->filesize != -1 ? FFMIN(new_pos, s->filesize) : new_pos;
674  if (fake_pos != s->position) {
675  if ((err = ftp_abort(h)) < 0)
676  return err;
677  s->position = fake_pos;
678  }
679  return new_pos;
680 }
681 
682 static int ftp_read(URLContext *h, unsigned char *buf, int size)
683 {
684  FTPContext *s = h->priv_data;
685  int read, err, retry_done = 0;
686 
687  av_dlog(h, "ftp protocol read %d bytes\n", size);
688  retry:
689  if (s->state == DISCONNECTED) {
690  /* optimization */
691  if (s->position >= s->filesize)
692  return 0;
693  if ((err = ftp_connect_data_connection(h)) < 0)
694  return err;
695  }
696  if (s->state == READY) {
697  if (s->position >= s->filesize)
698  return 0;
699  if ((err = ftp_retrieve(s)) < 0)
700  return err;
701  }
702  if (s->conn_data && s->state == DOWNLOADING) {
703  read = ffurl_read(s->conn_data, buf, size);
704  if (read >= 0) {
705  s->position += read;
706  if (s->position >= s->filesize) {
707  /* server will terminate, but keep current position to avoid madness */
708  /* save position to restart from it */
709  int64_t pos = s->position;
710  if (ftp_abort(h) < 0) {
711  s->position = pos;
712  return AVERROR(EIO);
713  }
714  s->position = pos;
715  }
716  }
717  if (read <= 0 && s->position < s->filesize && !h->is_streamed) {
718  /* Server closed connection. Probably due to inactivity */
719  int64_t pos = s->position;
720  av_log(h, AV_LOG_INFO, "Reconnect to FTP server.\n");
721  if ((err = ftp_abort(h)) < 0)
722  return err;
723  if ((err = ftp_seek(h, pos, SEEK_SET)) < 0) {
724  av_log(h, AV_LOG_ERROR, "Position cannot be restored.\n");
725  return err;
726  }
727  if (!retry_done) {
728  retry_done = 1;
729  goto retry;
730  }
731  }
732  return read;
733  }
734 
735  av_log(h, AV_LOG_DEBUG, "FTP read failed\n");
736  return AVERROR(EIO);
737 }
738 
739 static int ftp_write(URLContext *h, const unsigned char *buf, int size)
740 {
741  int err;
742  FTPContext *s = h->priv_data;
743  int written;
744 
745  av_dlog(h, "ftp protocol write %d bytes\n", size);
746 
747  if (s->state == DISCONNECTED) {
748  if ((err = ftp_connect_data_connection(h)) < 0)
749  return err;
750  }
751  if (s->state == READY) {
752  if ((err = ftp_store(s)) < 0)
753  return err;
754  }
755  if (s->conn_data && s->state == UPLOADING) {
756  written = ffurl_write(s->conn_data, buf, size);
757  if (written > 0) {
758  s->position += written;
759  s->filesize = FFMAX(s->filesize, s->position);
760  }
761  return written;
762  }
763 
764  av_log(h, AV_LOG_ERROR, "FTP write failed\n");
765  return AVERROR(EIO);
766 }
767 
768 static int ftp_close(URLContext *h)
769 {
770  FTPContext *s = h->priv_data;
771 
772  av_dlog(h, "ftp protocol close\n");
773 
775  av_freep(&s->user);
776  av_freep(&s->password);
777  av_freep(&s->hostname);
778  av_freep(&s->path);
779 
780  return 0;
781 }
782 
784 {
785  FTPContext *s = h->priv_data;
786 
787  av_dlog(h, "ftp protocol get_file_handle\n");
788 
789  if (s->conn_data)
790  return ffurl_get_file_handle(s->conn_data);
791 
792  return AVERROR(EIO);
793 }
794 
795 static int ftp_shutdown(URLContext *h, int flags)
796 {
797  FTPContext *s = h->priv_data;
798 
799  av_dlog(h, "ftp protocol shutdown\n");
800 
801  if (s->conn_data)
802  return ffurl_shutdown(s->conn_data, flags);
803 
804  return AVERROR(EIO);
805 }
806 
808  .name = "ftp",
809  .url_open = ftp_open,
810  .url_read = ftp_read,
811  .url_write = ftp_write,
812  .url_seek = ftp_seek,
813  .url_close = ftp_close,
814  .url_get_file_handle = ftp_get_file_handle,
815  .url_shutdown = ftp_shutdown,
816  .priv_data_size = sizeof(FTPContext),
817  .priv_data_class = &ftp_context_class,
819 };
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:3886
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:35
static int ftp_get_line(FTPContext *s, char *line, int line_size)
Definition: ftp.c:94
char * password
Server user's password.
Definition: ftp.c:48
AVOption.
Definition: opt.h:255
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:62
static int ftp_file_size(FTPContext *s)
Definition: ftp.c:367
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:347
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
int is_streamed
true if streamed (no seek possible), default = false
Definition: url.h:46
AVIOInterruptCB interrupt_callback
Definition: url.h:48
#define AVIO_FLAG_READ
read-only
Definition: avio.h:460
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:461
static int ftp_open(URLContext *h, const char *url, int flags)
Definition: ftp.c:573
uint8_t * control_buf_end
Definition: ftp.c:43
int flags
Definition: url.h:44
static int ftp_status(FTPContext *s, char **line, const int response_codes[])
Definition: ftp.c:122
int write_seekable
Control seekability, 0 = disable, 1 = enable.
Definition: ftp.c:54
static int ftp_retrieve(FTPContext *s)
Definition: ftp.c:386
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
int ffurl_shutdown(URLContext *h, int flags)
Signal the URLContext that we are done reading or writing the stream.
Definition: avio.c:534
Definition: ftp.c:31
Definition: ftp.c:34
#define MAX_URL_SIZE
Definition: internal.h:28
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:72
URLContext * conn_control
Control connection.
Definition: ftp.c:40
static int ftp_connect_data_connection(URLContext *h)
Definition: ftp.c:502
uint8_t
static int ftp_shutdown(URLContext *h, int flags)
Definition: ftp.c:795
AVOptions.
FTPState
Definition: ftp.c:30
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:67
#define E
Definition: ftp.c:60
int64_t filesize
Size of file on server, -1 on error.
Definition: ftp.c:50
int av_reallocp(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:185
static int ftp_connect_control_connection(URLContext *h)
Definition: ftp.c:454
uint8_t control_buffer[CONTROL_BUFFER_SIZE]
Control connection buffer.
Definition: ftp.c:42
ptrdiff_t size
Definition: opengl_enc.c:101
static int ftp_current_dir(FTPContext *s)
Definition: ftp.c:326
uint8_t * control_buf_ptr
Definition: ftp.c:43
#define av_log(a,...)
static int ftp_passive_mode(FTPContext *s)
Definition: ftp.c:280
int server_data_port
Data connection port opened by server, -1 on error.
Definition: ftp.c:44
static void * av_x_if_null(const void *p, const void *x)
Return x default pointer in case p is NULL.
Definition: avutil.h:301
static int ftp_getc(FTPContext *s)
Definition: ftp.c:77
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
const char * anonymous_password
Password to be used for anonymous user.
Definition: ftp.c:53
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
static int ftp_abort(URLContext *h)
Definition: ftp.c:535
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:199
Definition: graph2dot.c:48
Definition: ftp.c:32
static int ftp_send_command(FTPContext *s, const char *command, const int response_codes[], char **response)
Definition: ftp.c:183
static void ftp_close_both_connections(FTPContext *s)
Definition: ftp.c:210
static int ftp_passive_mode_epsv(FTPContext *s)
Definition: ftp.c:238
#define FFMAX(a, b)
Definition: common.h:64
int rw_timeout
Network timeout.
Definition: ftp.c:52
static int ftp_read(URLContext *h, unsigned char *buf, int size)
Definition: ftp.c:682
static int ftp_close(URLContext *h)
Definition: ftp.c:768
URLContext * conn_data
Data connection, NULL when not connected.
Definition: ftp.c:41
#define FFMIN(a, b)
Definition: common.h:66
char * user
Server user.
Definition: ftp.c:47
static int ftp_auth(FTPContext *s)
Definition: ftp.c:216
int64_t position
Current position, calculated.
Definition: ftp.c:51
static int ftp_restart(FTPContext *s, int64_t pos)
Definition: ftp.c:425
char * path
Path to resource on server.
Definition: ftp.c:49
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:512
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:370
#define av_dlog(pctx,...)
av_dlog macros
Definition: log.h:330
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:36
static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)
Definition: ftp.c:639
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
#define AV_BPRINT_SIZE_AUTOMATIC
char * av_strdup(const char *s)
Duplicate the string s.
Definition: mem.c:265
static int ftp_get_file_handle(URLContext *h)
Definition: ftp.c:783
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Definition: vf_drawtext.c:765
static const AVOption options[]
Definition: ftp.c:61
void * buf
Definition: avisynth_c.h:553
Definition: url.h:39
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:462
FTPState state
State of data connection.
Definition: ftp.c:55
Describe the class of an AVClass context structure.
Definition: log.h:67
static void ftp_close_data_connection(FTPContext *s)
Definition: ftp.c:203
static int ftp_features(FTPContext *s)
Definition: ftp.c:437
void * priv_data
Definition: url.h:42
#define snprintf
Definition: snprintf.h:34
#define CONTROL_BUFFER_SIZE
Definition: ftp.c:28
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes...
Definition: avstring.c:93
const char * name
Definition: url.h:53
static int flags
Definition: cpu.c:47
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:184
Main libavformat public API header.
static int ftp_write(URLContext *h, const unsigned char *buf, int size)
Definition: ftp.c:739
#define OFFSET(x)
Definition: ftp.c:58
int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create an URLContext for accessing to the resource indicated by url, and open it. ...
Definition: avio.c:272
URLProtocol ff_ftp_protocol
Definition: ftp.c:807
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:143
#define AVSEEK_SIZE
Passing this as the "whence" parameter to a seek function causes it to return the filesize without se...
Definition: avio.h:339
char * hostname
Server address.
Definition: ftp.c:46
static int ftp_store(FTPContext *s)
Definition: ftp.c:400
static int ftp_type(FTPContext *s)
Definition: ftp.c:414
#define D
Definition: ftp.c:59
#define av_free(p)
int len
int server_control_port
Control connection port, default is 21.
Definition: ftp.c:45
static const AVClass ftp_context_class
Definition: ftp.c:68
#define av_freep(p)
void INT64 start
Definition: avisynth_c.h:553
unbuffered private I/O API
Definition: ftp.c:38
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:333