Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
affbecb0
Commit
affbecb0
authored
Jun 16, 2015
by
Mariusz Szczepańczyk
Committed by
Michael Niedermayer
Aug 13, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lavf/ftp: implement NLST method
Signed-off-by:
Michael Niedermayer
<
michael@niedermayer.cc
>
parent
5fec7942
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
81 additions
and
14 deletions
+81
-14
ftp.c
libavformat/ftp.c
+81
-14
No files found.
libavformat/ftp.c
View file @
affbecb0
...
...
@@ -38,6 +38,12 @@ typedef enum {
DISCONNECTED
}
FTPState
;
typedef
enum
{
UNKNOWN_METHOD
,
NLST
,
MLSD
}
FTPListingMethod
;
typedef
struct
{
const
AVClass
*
class
;
URLContext
*
conn_control
;
/**< Control connection */
...
...
@@ -56,6 +62,8 @@ typedef struct {
const
char
*
anonymous_password
;
/**< Password to be used for anonymous user. An email should be used. */
int
write_seekable
;
/**< Control seekability, 0 = disable, 1 = enable. */
FTPState
state
;
/**< State of data connection */
FTPListingMethod
listing_method
;
/**< Called listing method */
char
*
features
;
/**< List of server's features represented as raw response */
char
*
dir_buffer
;
size_t
dir_buffer_size
;
size_t
dir_buffer_offset
;
...
...
@@ -192,6 +200,8 @@ static int ftp_send_command(FTPContext *s, const char *command,
{
int
err
;
av_dlog
(
s
,
"%s"
,
command
);
if
(
response
)
*
response
=
NULL
;
...
...
@@ -449,32 +459,65 @@ static int ftp_set_dir(FTPContext *s)
return
0
;
}
static
int
ftp_list
(
FTPContext
*
s
)
static
int
ftp_list
_mlsd
(
FTPContext
*
s
)
{
static
const
char
*
command
=
"MLSD
\r\n
"
;
static
const
int
mlsd_codes
[]
=
{
150
,
500
,
0
};
/* 500 is incorrect code */
if
(
ftp_send_command
(
s
,
command
,
mlsd_codes
,
NULL
)
!=
150
)
return
AVERROR
(
ENOSYS
);
s
->
state
=
LISTING_DIR
;
s
->
listing_method
=
MLSD
;
return
0
;
}
static
int
ftp_list_nlst
(
FTPContext
*
s
)
{
static
const
char
*
command
=
"NLST
\r\n
"
;
static
const
int
nlst_codes
[]
=
{
226
,
425
,
426
,
451
,
450
,
550
,
0
};
if
(
ftp_send_command
(
s
,
command
,
nlst_codes
,
NULL
)
!=
226
)
return
AVERROR
(
ENOSYS
);
s
->
listing_method
=
NLST
;
return
0
;
}
static
int
ftp_has_feature
(
FTPContext
*
s
,
const
char
*
feature_name
);
static
int
ftp_list
(
FTPContext
*
s
)
{
int
ret
;
s
->
state
=
LISTING_DIR
;
if
((
ret
=
ftp_list_mlsd
(
s
))
<
0
)
ret
=
ftp_list_nlst
(
s
);
return
ret
;
}
static
int
ftp_has_feature
(
FTPContext
*
s
,
const
char
*
feature_name
)
{
if
(
!
s
->
features
)
return
0
;
return
av_stristr
(
s
->
features
,
feature_name
)
!=
NULL
;
}
static
int
ftp_features
(
FTPContext
*
s
)
{
static
const
char
*
feat_command
=
"FEAT
\r\n
"
;
static
const
char
*
enable_utf8_command
=
"OPTS UTF8 ON
\r\n
"
;
static
const
int
feat_codes
[]
=
{
211
,
0
};
static
const
int
opts_codes
[]
=
{
200
,
451
,
0
};
char
*
feat
=
NULL
;
if
(
ftp_send_command
(
s
,
feat_command
,
feat_codes
,
&
feat
)
==
211
)
{
if
(
av_stristr
(
feat
,
"UTF8"
))
{
if
(
ftp_send_command
(
s
,
enable_utf8_command
,
opts_codes
,
NULL
)
==
200
)
s
->
utf8
=
1
;
}
av_freep
(
&
s
->
features
);
if
(
ftp_send_command
(
s
,
feat_command
,
feat_codes
,
&
s
->
features
)
!=
211
)
{
av_freep
(
&
s
->
features
);
}
if
(
ftp_has_feature
(
s
,
"UTF8"
))
{
if
(
ftp_send_command
(
s
,
enable_utf8_command
,
opts_codes
,
NULL
)
==
200
)
s
->
utf8
=
1
;
}
av_freep
(
&
feat
);
return
0
;
}
...
...
@@ -607,8 +650,10 @@ static int ftp_connect(URLContext *h, const char *url)
FTPContext
*
s
=
h
->
priv_data
;
s
->
state
=
DISCONNECTED
;
s
->
listing_method
=
UNKNOWN
;
s
->
filesize
=
-
1
;
s
->
position
=
0
;
s
->
features
=
NULL
;
av_url_split
(
proto
,
sizeof
(
proto
),
credencials
,
sizeof
(
credencials
),
...
...
@@ -815,6 +860,7 @@ static int ftp_close(URLContext *h)
av_freep
(
&
s
->
password
);
av_freep
(
&
s
->
hostname
);
av_freep
(
&
s
->
path
);
av_freep
(
&
s
->
features
);
return
0
;
}
...
...
@@ -878,10 +924,13 @@ static int64_t ftp_parse_date(const char *date)
return
INT64_C
(
1000000
)
*
av_timegm
(
&
tv
);
}
/**
* @return 0 on success, negative on error, positive on entry to discard.
*/
static
int
ftp_parse_entry
(
char
*
mlsd
,
AVIODirEntry
*
next
)
static
int
ftp_parse_entry_nlst
(
char
*
line
,
AVIODirEntry
*
next
)
{
next
->
name
=
av_strdup
(
line
);
return
0
;
}
static
int
ftp_parse_entry_mlsd
(
char
*
mlsd
,
AVIODirEntry
*
next
)
{
char
*
fact
,
*
value
;
av_dlog
(
NULL
,
"%s
\n
"
,
mlsd
);
...
...
@@ -914,6 +963,24 @@ static int ftp_parse_entry(char *mlsd, AVIODirEntry *next)
return
0
;
}
/**
* @return 0 on success, negative on error, positive on entry to discard.
*/
static
int
ftp_parse_entry
(
URLContext
*
h
,
char
*
line
,
AVIODirEntry
*
next
)
{
FTPContext
*
s
=
h
->
priv_data
;
switch
(
s
->
listing_method
)
{
case
MLSD
:
return
ftp_parse_entry_mlsd
(
line
,
next
);
case
NLST
:
return
ftp_parse_entry_nlst
(
line
,
next
);
case
UNKNOWN_METHOD
:
default:
return
-
1
;
}
}
static
int
ftp_read_dir
(
URLContext
*
h
,
AVIODirEntry
**
next
)
{
FTPContext
*
s
=
h
->
priv_data
;
...
...
@@ -951,7 +1018,7 @@ static int ftp_read_dir(URLContext *h, AVIODirEntry **next)
if
(
!*
next
)
return
AVERROR
(
ENOMEM
);
(
*
next
)
->
utf8
=
s
->
utf8
;
ret
=
ftp_parse_entry
(
start
,
*
next
);
ret
=
ftp_parse_entry
(
h
,
start
,
*
next
);
if
(
ret
)
{
avio_free_directory_entry
(
next
);
if
(
ret
<
0
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment