FFmpeg
libssh.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 <fcntl.h>
22 #define LIBSSH_STATIC
23 #include <libssh/sftp.h>
24 #include "libavutil/avstring.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/attributes.h"
27 #include "libavformat/avio.h"
28 #include "avformat.h"
29 #include "internal.h"
30 #include "url.h"
31 
32 typedef struct {
33  const AVClass *class;
34  ssh_session session;
35  sftp_session sftp;
36  sftp_file file;
37  sftp_dir dir;
38  int64_t filesize;
40  int trunc;
41  char *priv_key;
43 
44 static av_cold int libssh_create_ssh_session(LIBSSHContext *libssh, const char* hostname, unsigned int port)
45 {
46  static const int verbosity = SSH_LOG_NOLOG;
47 
48  if (!(libssh->session = ssh_new())) {
49  av_log(libssh, AV_LOG_ERROR, "SSH session creation failed: %s\n", ssh_get_error(libssh->session));
50  return AVERROR(ENOMEM);
51  }
52  ssh_options_set(libssh->session, SSH_OPTIONS_HOST, hostname);
53  ssh_options_set(libssh->session, SSH_OPTIONS_PORT, &port);
54  ssh_options_set(libssh->session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
55  if (libssh->rw_timeout > 0) {
56  long timeout = libssh->rw_timeout * 1000;
57  ssh_options_set(libssh->session, SSH_OPTIONS_TIMEOUT_USEC, &timeout);
58  }
59 
60  if (ssh_options_parse_config(libssh->session, NULL) < 0) {
61  av_log(libssh, AV_LOG_WARNING, "Could not parse the config file.\n");
62  }
63 
64  if (ssh_connect(libssh->session) != SSH_OK) {
65  av_log(libssh, AV_LOG_ERROR, "Connection failed: %s\n", ssh_get_error(libssh->session));
66  return AVERROR(EIO);
67  }
68 
69  return 0;
70 }
71 
72 static av_cold int libssh_authentication(LIBSSHContext *libssh, const char *user, const char *password)
73 {
74  int authorized = 0;
75  int auth_methods;
76 
77  if (user)
78  ssh_options_set(libssh->session, SSH_OPTIONS_USER, user);
79 
80  if (ssh_userauth_none(libssh->session, NULL) == SSH_AUTH_SUCCESS)
81  return 0;
82 
83  auth_methods = ssh_userauth_list(libssh->session, NULL);
84 
85  if (auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
86  if (libssh->priv_key) {
87  ssh_key priv_key;
88  if (ssh_pki_import_privkey_file(libssh->priv_key, password, NULL, NULL, &priv_key) == SSH_OK) {
89  if (ssh_userauth_publickey(libssh->session, NULL, priv_key) == SSH_AUTH_SUCCESS) {
90  av_log(libssh, AV_LOG_DEBUG, "Authentication successful with selected private key.\n");
91  authorized = 1;
92  }
93  } else {
94  av_log(libssh, AV_LOG_DEBUG, "Invalid key is provided.\n");
95  return AVERROR(EACCES);
96  }
97  } else if (ssh_userauth_publickey_auto(libssh->session, NULL, password) == SSH_AUTH_SUCCESS) {
98  av_log(libssh, AV_LOG_DEBUG, "Authentication successful with auto selected key.\n");
99  authorized = 1;
100  }
101  }
102 
103  if (!authorized && password && (auth_methods & SSH_AUTH_METHOD_PASSWORD)) {
104  if (ssh_userauth_password(libssh->session, NULL, password) == SSH_AUTH_SUCCESS) {
105  av_log(libssh, AV_LOG_DEBUG, "Authentication successful with password.\n");
106  authorized = 1;
107  }
108  }
109 
110  if (!authorized) {
111  av_log(libssh, AV_LOG_ERROR, "Authentication failed.\n");
112  return AVERROR(EACCES);
113  }
114 
115  return 0;
116 }
117 
119 {
120  if (!(libssh->sftp = sftp_new(libssh->session))) {
121  av_log(libssh, AV_LOG_ERROR, "SFTP session creation failed: %s\n", ssh_get_error(libssh->session));
122  return AVERROR(ENOMEM);
123  }
124 
125  if (sftp_init(libssh->sftp) != SSH_OK) {
126  av_log(libssh, AV_LOG_ERROR, "Error initializing sftp session: %s\n", ssh_get_error(libssh->session));
127  return AVERROR(EIO);
128  }
129 
130  return 0;
131 }
132 
133 static av_cold int libssh_open_file(LIBSSHContext *libssh, int flags, const char *file)
134 {
135  int access;
136 
137  if ((flags & AVIO_FLAG_WRITE) && (flags & AVIO_FLAG_READ)) {
138  access = O_CREAT | O_RDWR;
139  if (libssh->trunc)
140  access |= O_TRUNC;
141  } else if (flags & AVIO_FLAG_WRITE) {
142  access = O_CREAT | O_WRONLY;
143  if (libssh->trunc)
144  access |= O_TRUNC;
145  } else
146  access = O_RDONLY;
147 
148  /* 0666 = -rw-rw-rw- = read+write for everyone, minus umask */
149  if (!(libssh->file = sftp_open(libssh->sftp, file, access, 0666))) {
150  av_log(libssh, AV_LOG_ERROR, "Error opening sftp file: %s\n", ssh_get_error(libssh->session));
151  return AVERROR(EIO);
152  }
153 
154  return 0;
155 }
156 
158 {
159  sftp_attributes stat;
160 
161  if (!(stat = sftp_fstat(libssh->file))) {
162  av_log(libssh, AV_LOG_WARNING, "Cannot stat remote file.\n");
163  libssh->filesize = -1;
164  } else {
165  libssh->filesize = stat->size;
166  sftp_attributes_free(stat);
167  }
168 }
169 
171 {
172  LIBSSHContext *libssh = h->priv_data;
173  if (libssh->file) {
174  sftp_close(libssh->file);
175  libssh->file = NULL;
176  }
177  if (libssh->sftp) {
178  sftp_free(libssh->sftp);
179  libssh->sftp = NULL;
180  }
181  if (libssh->session) {
182  ssh_disconnect(libssh->session);
183  ssh_free(libssh->session);
184  libssh->session = NULL;
185  }
186  return 0;
187 }
188 
189 static av_cold int libssh_connect(URLContext *h, const char *url, char *path, size_t path_size)
190 {
191  LIBSSHContext *libssh = h->priv_data;
192  char proto[10], hostname[1024], credencials[1024];
193  int port = 22, ret;
194  const char *user = NULL, *pass = NULL;
195  char *end = NULL;
196 
197  av_url_split(proto, sizeof(proto),
198  credencials, sizeof(credencials),
199  hostname, sizeof(hostname),
200  &port,
201  path, path_size,
202  url);
203 
204  if (!(*path))
205  av_strlcpy(path, "/", path_size);
206 
207  // a port of 0 will use a port from ~/.ssh/config or the default value 22
208  if (port < 0 || port > 65535)
209  port = 0;
210 
211  if ((ret = libssh_create_ssh_session(libssh, hostname, port)) < 0)
212  return ret;
213 
214  user = av_strtok(credencials, ":", &end);
215  pass = av_strtok(end, ":", &end);
216 
217  if ((ret = libssh_authentication(libssh, user, pass)) < 0)
218  return ret;
219 
220  if ((ret = libssh_create_sftp_session(libssh)) < 0)
221  return ret;
222 
223  return 0;
224 }
225 
226 static av_cold int libssh_open(URLContext *h, const char *url, int flags)
227 {
228  int ret;
229  LIBSSHContext *libssh = h->priv_data;
230  char path[MAX_URL_SIZE];
231 
232  if ((ret = libssh_connect(h, url, path, sizeof(path))) < 0)
233  goto fail;
234 
235  if ((ret = libssh_open_file(libssh, flags, path)) < 0)
236  goto fail;
237 
238  libssh_stat_file(libssh);
239 
240  return 0;
241 
242  fail:
243  libssh_close(h);
244  return ret;
245 }
246 
247 static int64_t libssh_seek(URLContext *h, int64_t pos, int whence)
248 {
249  LIBSSHContext *libssh = h->priv_data;
250  int64_t newpos;
251 
252  if (libssh->filesize == -1 && (whence == AVSEEK_SIZE || whence == SEEK_END)) {
253  av_log(h, AV_LOG_ERROR, "Error during seeking.\n");
254  return AVERROR(EIO);
255  }
256 
257  switch(whence) {
258  case AVSEEK_SIZE:
259  return libssh->filesize;
260  case SEEK_SET:
261  newpos = pos;
262  break;
263  case SEEK_CUR:
264  newpos = sftp_tell64(libssh->file) + pos;
265  break;
266  case SEEK_END:
267  newpos = libssh->filesize + pos;
268  break;
269  default:
270  return AVERROR(EINVAL);
271  }
272 
273  if (newpos < 0) {
274  av_log(h, AV_LOG_ERROR, "Seeking to nagative position.\n");
275  return AVERROR(EINVAL);
276  }
277 
278  if (sftp_seek64(libssh->file, newpos)) {
279  av_log(h, AV_LOG_ERROR, "Error during seeking.\n");
280  return AVERROR(EIO);
281  }
282 
283  return newpos;
284 }
285 
286 static int libssh_read(URLContext *h, unsigned char *buf, int size)
287 {
288  LIBSSHContext *libssh = h->priv_data;
289  int bytes_read;
290 
291  if ((bytes_read = sftp_read(libssh->file, buf, size)) < 0) {
292  av_log(libssh, AV_LOG_ERROR, "Read error.\n");
293  return AVERROR(EIO);
294  }
295  return bytes_read ? bytes_read : AVERROR_EOF;
296 }
297 
298 static int libssh_write(URLContext *h, const unsigned char *buf, int size)
299 {
300  LIBSSHContext *libssh = h->priv_data;
301  int bytes_written;
302 
303  if ((bytes_written = sftp_write(libssh->file, buf, size)) < 0) {
304  av_log(libssh, AV_LOG_ERROR, "Write error.\n");
305  return AVERROR(EIO);
306  }
307  return bytes_written;
308 }
309 
311 {
312  LIBSSHContext *libssh = h->priv_data;
313  int ret;
314  char path[MAX_URL_SIZE];
315 
316  if ((ret = libssh_connect(h, h->filename, path, sizeof(path))) < 0)
317  goto fail;
318 
319  if (!(libssh->dir = sftp_opendir(libssh->sftp, path))) {
320  av_log(libssh, AV_LOG_ERROR, "Error opening sftp dir: %s\n", ssh_get_error(libssh->session));
321  ret = AVERROR(EIO);
322  goto fail;
323  }
324 
325  return 0;
326 
327  fail:
328  libssh_close(h);
329  return ret;
330 }
331 
333 {
334  LIBSSHContext *libssh = h->priv_data;
335  sftp_attributes attr = NULL;
336  AVIODirEntry *entry;
337 
338  *next = entry = ff_alloc_dir_entry();
339  if (!entry)
340  return AVERROR(ENOMEM);
341 
342  do {
343  if (attr)
344  sftp_attributes_free(attr);
345  attr = sftp_readdir(libssh->sftp, libssh->dir);
346  if (!attr) {
347  av_freep(next);
348  if (sftp_dir_eof(libssh->dir))
349  return 0;
350  return AVERROR(EIO);
351  }
352  } while (!strcmp(attr->name, ".") || !strcmp(attr->name, ".."));
353 
354  entry->name = av_strdup(attr->name);
355  entry->group_id = attr->gid;
356  entry->user_id = attr->uid;
357  entry->size = attr->size;
358  entry->access_timestamp = INT64_C(1000000) * attr->atime;
359  entry->modification_timestamp = INT64_C(1000000) * attr->mtime;
360  entry->filemode = attr->permissions & 0777;
361  switch(attr->type) {
362  case SSH_FILEXFER_TYPE_REGULAR:
363  entry->type = AVIO_ENTRY_FILE;
364  break;
365  case SSH_FILEXFER_TYPE_DIRECTORY:
366  entry->type = AVIO_ENTRY_DIRECTORY;
367  break;
368  case SSH_FILEXFER_TYPE_SYMLINK:
370  break;
371  case SSH_FILEXFER_TYPE_SPECIAL:
372  /* Special type includes: sockets, char devices, block devices and pipes.
373  It is probably better to return unknown type, to not confuse anybody. */
374  case SSH_FILEXFER_TYPE_UNKNOWN:
375  default:
376  entry->type = AVIO_ENTRY_UNKNOWN;
377  }
378  sftp_attributes_free(attr);
379  return 0;
380 }
381 
383 {
384  LIBSSHContext *libssh = h->priv_data;
385  if (libssh->dir)
386  sftp_closedir(libssh->dir);
387  libssh->dir = NULL;
388  libssh_close(h);
389  return 0;
390 }
391 
393 {
394  int ret;
395  LIBSSHContext *libssh = h->priv_data;
396  sftp_attributes attr = NULL;
397  char path[MAX_URL_SIZE];
398 
399  if ((ret = libssh_connect(h, h->filename, path, sizeof(path))) < 0)
400  goto cleanup;
401 
402  if (!(attr = sftp_stat(libssh->sftp, path))) {
403  ret = AVERROR(sftp_get_error(libssh->sftp));
404  goto cleanup;
405  }
406 
407  if (attr->type == SSH_FILEXFER_TYPE_DIRECTORY) {
408  if (sftp_rmdir(libssh->sftp, path) < 0) {
409  ret = AVERROR(sftp_get_error(libssh->sftp));
410  goto cleanup;
411  }
412  } else {
413  if (sftp_unlink(libssh->sftp, path) < 0) {
414  ret = AVERROR(sftp_get_error(libssh->sftp));
415  goto cleanup;
416  }
417  }
418 
419  ret = 0;
420 
421 cleanup:
422  if (attr)
423  sftp_attributes_free(attr);
424  libssh_close(h);
425  return ret;
426 }
427 
428 static int libssh_move(URLContext *h_src, URLContext *h_dst)
429 {
430  int ret;
431  LIBSSHContext *libssh = h_src->priv_data;
432  char path_src[MAX_URL_SIZE], path_dst[MAX_URL_SIZE];
433  char hostname_src[1024], hostname_dst[1024];
434  char credentials_src[1024], credentials_dst[1024];
435  int port_src = 22, port_dst = 22;
436 
437  av_url_split(NULL, 0,
438  credentials_src, sizeof(credentials_src),
439  hostname_src, sizeof(hostname_src),
440  &port_src,
441  path_src, sizeof(path_src),
442  h_src->filename);
443 
444  av_url_split(NULL, 0,
445  credentials_dst, sizeof(credentials_dst),
446  hostname_dst, sizeof(hostname_dst),
447  &port_dst,
448  path_dst, sizeof(path_dst),
449  h_dst->filename);
450 
451  if (strcmp(credentials_src, credentials_dst) ||
452  strcmp(hostname_src, hostname_dst) ||
453  port_src != port_dst) {
454  return AVERROR(EINVAL);
455  }
456 
457  if ((ret = libssh_connect(h_src, h_src->filename, path_src, sizeof(path_src))) < 0)
458  goto cleanup;
459 
460  if (sftp_rename(libssh->sftp, path_src, path_dst) < 0) {
461  ret = AVERROR(sftp_get_error(libssh->sftp));
462  goto cleanup;
463  }
464 
465  ret = 0;
466 
467 cleanup:
468  libssh_close(h_src);
469  return ret;
470 }
471 
472 #define OFFSET(x) offsetof(LIBSSHContext, x)
473 #define D AV_OPT_FLAG_DECODING_PARAM
474 #define E AV_OPT_FLAG_ENCODING_PARAM
475 static const AVOption options[] = {
476  {"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
477  {"truncate", "Truncate existing files on write", OFFSET(trunc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, E },
478  {"private_key", "set path to private key", OFFSET(priv_key), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D|E },
479  {NULL}
480 };
481 
483  .class_name = "libssh",
484  .item_name = av_default_item_name,
485  .option = options,
486  .version = LIBAVUTIL_VERSION_INT,
487 };
488 
490  .name = "sftp",
491  .url_open = libssh_open,
492  .url_read = libssh_read,
493  .url_write = libssh_write,
494  .url_seek = libssh_seek,
495  .url_close = libssh_close,
496  .url_delete = libssh_delete,
497  .url_move = libssh_move,
498  .url_open_dir = libssh_open_dir,
499  .url_read_dir = libssh_read_dir,
500  .url_close_dir = libssh_close_dir,
501  .priv_data_size = sizeof(LIBSSHContext),
502  .priv_data_class = &libssh_context_class,
504 };
OFFSET
#define OFFSET(x)
Definition: libssh.c:472
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
libssh_stat_file
static av_cold void libssh_stat_file(LIBSSHContext *libssh)
Definition: libssh.c:157
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
URLContext::filename
char * filename
specified URL
Definition: url.h:41
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:33
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
libssh_seek
static int64_t libssh_seek(URLContext *h, int64_t pos, int whence)
Definition: libssh.c:247
cleanup
static av_cold void cleanup(FlashSV2Context *s)
Definition: flashsv2enc.c:130
AVIODirEntry::type
int type
Type of the entry.
Definition: avio.h:89
AVOption
AVOption.
Definition: opt.h:251
AVSEEK_SIZE
#define AVSEEK_SIZE
ORing this as the "whence" parameter to a seek function causes it to return the filesize without seek...
Definition: avio.h:487
libssh_open
static av_cold int libssh_open(URLContext *h, const char *url, int flags)
Definition: libssh.c:226
libssh_delete
static int libssh_delete(URLContext *h)
Definition: libssh.c:392
URLProtocol
Definition: url.h:53
LIBSSHContext::file
sftp_file file
Definition: libssh.c:36
libssh_move
static int libssh_move(URLContext *h_src, URLContext *h_dst)
Definition: libssh.c:428
AVIO_ENTRY_UNKNOWN
@ AVIO_ENTRY_UNKNOWN
Definition: avio.h:68
AVIODirEntry::access_timestamp
int64_t access_timestamp
Time of last access in microseconds since unix epoch, -1 if unknown.
Definition: avio.h:95
AVIO_ENTRY_DIRECTORY
@ AVIO_ENTRY_DIRECTORY
Definition: avio.h:71
LIBSSHContext::filesize
int64_t filesize
Definition: libssh.c:38
LIBSSHContext::priv_key
char * priv_key
Definition: libssh.c:41
fail
#define fail()
Definition: checkasm.h:138
trunc
static __device__ float trunc(float a)
Definition: cuda_runtime.h:179
LIBSSHContext::trunc
int trunc
Definition: libssh.c:40
URLContext::priv_data
void * priv_data
Definition: url.h:40
AVIODirEntry::modification_timestamp
int64_t modification_timestamp
Time of last modification in microseconds since unix epoch, -1 if unknown.
Definition: avio.h:93
libssh_open_dir
static int libssh_open_dir(URLContext *h)
Definition: libssh.c:310
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AVIO_ENTRY_SYMBOLIC_LINK
@ AVIO_ENTRY_SYMBOLIC_LINK
Definition: avio.h:73
libssh_open_file
static av_cold int libssh_open_file(LIBSSHContext *libssh, int flags, const char *file)
Definition: libssh.c:133
av_strtok
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
Definition: avstring.c:178
LIBSSHContext
Definition: libssh.c:32
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:637
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
libssh_close_dir
static int libssh_close_dir(URLContext *h)
Definition: libssh.c:382
libssh_close
static av_cold int libssh_close(URLContext *h)
Definition: libssh.c:170
internal.h
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
libssh_read
static int libssh_read(URLContext *h, unsigned char *buf, int size)
Definition: libssh.c:286
libssh_connect
static av_cold int libssh_connect(URLContext *h, const char *url, char *path, size_t path_size)
Definition: libssh.c:189
AVIODirEntry::size
int64_t size
File size in bytes, -1 if unknown.
Definition: avio.h:92
AVIODirEntry::name
char * name
Filename.
Definition: avio.h:88
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AVIO_ENTRY_FILE
@ AVIO_ENTRY_FILE
Definition: avio.h:75
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
libssh_create_sftp_session
static av_cold int libssh_create_sftp_session(LIBSSHContext *libssh)
Definition: libssh.c:118
options
static const AVOption options[]
Definition: libssh.c:475
libssh_read_dir
static int libssh_read_dir(URLContext *h, AVIODirEntry **next)
Definition: libssh.c:332
libssh_create_ssh_session
static av_cold int libssh_create_ssh_session(LIBSSHContext *libssh, const char *hostname, unsigned int port)
Definition: libssh.c:44
size
int size
Definition: twinvq_data.h:10344
AVIODirEntry
Describes single entry of the directory.
Definition: avio.h:87
avio.h
LIBSSHContext::dir
sftp_dir dir
Definition: libssh.c:37
URLProtocol::name
const char * name
Definition: url.h:54
LIBSSHContext::session
ssh_session session
Definition: libssh.c:34
attributes.h
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
URLContext
Definition: url.h:37
LIBSSHContext::rw_timeout
int rw_timeout
Definition: libssh.c:39
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:358
url.h
ff_libssh_protocol
const URLProtocol ff_libssh_protocol
Definition: libssh.c:489
libssh_context_class
static const AVClass libssh_context_class
Definition: libssh.c:482
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
pos
unsigned int pos
Definition: spdifenc.c:413
avformat.h
E
#define E
Definition: libssh.c:474
libssh_authentication
static av_cold int libssh_authentication(LIBSSHContext *libssh, const char *user, const char *password)
Definition: libssh.c:72
MAX_URL_SIZE
#define MAX_URL_SIZE
Definition: internal.h:30
libssh_write
static int libssh_write(URLContext *h, const unsigned char *buf, int size)
Definition: libssh.c:298
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:636
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:270
LIBSSHContext::sftp
sftp_session sftp
Definition: libssh.c:35
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2038
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
D
#define D
Definition: libssh.c:473