Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
353f77fc
Commit
353f77fc
authored
May 07, 2015
by
Thomas Guillem
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
access/directory: remove recursive code
Recursive parsing is not handled anymore by accesses.
parent
b62156ba
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
85 additions
and
229 deletions
+85
-229
modules/access/directory.c
modules/access/directory.c
+83
-224
modules/access/file.c
modules/access/file.c
+2
-4
modules/access/fs.h
modules/access/fs.h
+0
-1
No files found.
modules/access/directory.c
View file @
353f77fc
/*****************************************************************************
* directory.c: expands a directory (directory: access_browser plug-in)
*****************************************************************************
* Copyright (C) 2002-20
08
VLC authors and VideoLAN
* Copyright (C) 2002-20
15
VLC authors and VideoLAN
* $Id$
*
* Authors: Derk-Jan Hartman <hartman at videolan dot org>
...
...
@@ -47,225 +47,54 @@
#include <vlc_strings.h>
#include <vlc_charset.h>
enum
{
ENTRY_DIR
=
0
,
ENTRY_ENOTDIR
=
-
1
,
ENTRY_EACCESS
=
-
2
,
};
enum
{
MODE_NONE
,
MODE_COLLAPSE
,
MODE_EXPAND
,
};
typedef
struct
directory
directory
;
struct
directory
{
directory
*
parent
;
DIR
*
handle
;
char
*
uri
;
char
**
filev
;
int
filec
,
i
;
#ifdef HAVE_OPENAT
dev_t
device
;
ino_t
inode
;
#else
char
*
path
;
#endif
};
struct
access_sys_t
{
directory
*
current
;
char
mode
;
char
*
psz_base_uri
;
DIR
*
p_dir
;
};
/* Select non-hidden files only */
static
int
visible
(
const
char
*
name
)
{
return
name
[
0
]
!=
'.'
;
}
#ifdef HAVE_OPENAT
/* Detect directories that recurse into themselves. */
static
bool
has_inode_loop
(
const
directory
*
dir
,
dev_t
dev
,
ino_t
inode
)
{
while
(
dir
!=
NULL
)
{
if
((
dir
->
device
==
dev
)
&&
(
dir
->
inode
==
inode
))
return
true
;
dir
=
dir
->
parent
;
}
return
false
;
}
#endif
/* success -> returns ENTRY_DIR and the handle parameter is set to the handle,
* error -> return ENTRY_ENOTDIR or ENTRY_EACCESS */
static
int
directory_open
(
directory
*
p_dir
,
char
*
psz_entry
,
DIR
**
handle
)
{
*
handle
=
NULL
;
#ifdef HAVE_OPENAT
int
fd
=
vlc_openat
(
dirfd
(
p_dir
->
handle
),
psz_entry
,
O_RDONLY
|
O_DIRECTORY
);
if
(
fd
==
-
1
)
{
if
(
errno
==
ENOTDIR
)
return
ENTRY_ENOTDIR
;
else
return
ENTRY_EACCESS
;
}
struct
stat
st
;
if
(
fstat
(
fd
,
&
st
)
||
has_inode_loop
(
p_dir
,
st
.
st_dev
,
st
.
st_ino
)
||
(
*
handle
=
fdopendir
(
fd
))
==
NULL
)
{
close
(
fd
);
return
ENTRY_EACCESS
;
}
#else
char
*
path
;
if
(
asprintf
(
&
path
,
"%s/%s"
,
p_dir
->
path
,
psz_entry
)
==
-
1
)
return
ENTRY_EACCESS
;
*
handle
=
vlc_opendir
(
path
);
free
(
path
);
if
(
*
handle
==
NULL
)
{
return
ENTRY_ENOTDIR
;
}
#endif
return
ENTRY_DIR
;
}
static
bool
directory_push
(
access_sys_t
*
p_sys
,
DIR
*
handle
,
char
*
psz_uri
)
{
directory
*
p_dir
=
malloc
(
sizeof
(
*
p_dir
));
psz_uri
=
strdup
(
psz_uri
);
if
(
unlikely
(
p_dir
==
NULL
||
psz_uri
==
NULL
))
goto
error
;
p_dir
->
parent
=
p_sys
->
current
;
p_dir
->
handle
=
handle
;
p_dir
->
uri
=
psz_uri
;
p_dir
->
filec
=
vlc_loaddir
(
handle
,
&
p_dir
->
filev
,
visible
,
NULL
);
if
(
p_dir
->
filec
<
0
)
p_dir
->
filev
=
NULL
;
p_dir
->
i
=
0
;
#ifdef HAVE_OPENAT
struct
stat
st
;
if
(
fstat
(
dirfd
(
handle
),
&
st
))
goto
error_filev
;
p_dir
->
device
=
st
.
st_dev
;
p_dir
->
inode
=
st
.
st_ino
;
#else
p_dir
->
path
=
make_path
(
psz_uri
);
if
(
p_dir
->
path
==
NULL
)
goto
error_filev
;
#endif
p_sys
->
current
=
p_dir
;
return
true
;
error_filev:
for
(
int
i
=
0
;
i
<
p_dir
->
filec
;
i
++
)
free
(
p_dir
->
filev
[
i
]);
free
(
p_dir
->
filev
);
error:
closedir
(
handle
);
free
(
p_dir
);
free
(
psz_uri
);
return
false
;
}
static
bool
directory_pop
(
access_sys_t
*
p_sys
)
{
directory
*
p_old
=
p_sys
->
current
;
if
(
p_old
==
NULL
)
return
false
;
p_sys
->
current
=
p_old
->
parent
;
closedir
(
p_old
->
handle
);
free
(
p_old
->
uri
);
for
(
int
i
=
0
;
i
<
p_old
->
filec
;
i
++
)
free
(
p_old
->
filev
[
i
]);
free
(
p_old
->
filev
);
#ifndef HAVE_OPENAT
free
(
p_old
->
path
);
#endif
free
(
p_old
);
return
p_sys
->
current
!=
NULL
;
}
/*****************************************************************************
* Open: open the directory
*****************************************************************************/
int
DirOpen
(
vlc_object_t
*
p_this
)
{
access_t
*
p_access
=
(
access_t
*
)
p_this
;
DIR
*
p_dir
;
char
*
psz_base_uri
;
if
(
!
p_access
->
psz_filepath
)
return
VLC_EGENERIC
;
DIR
*
handle
=
vlc_opendir
(
p_access
->
psz_filepath
);
if
(
handle
==
NULL
)
p_dir
=
vlc_opendir
(
p_access
->
psz_filepath
);
if
(
p_dir
==
NULL
)
return
VLC_EGENERIC
;
return
DirInit
(
p_access
,
handle
);
}
int
DirInit
(
access_t
*
p_access
,
DIR
*
handle
)
{
access_sys_t
*
p_sys
=
malloc
(
sizeof
(
*
p_sys
));
if
(
unlikely
(
p_sys
==
NULL
))
goto
error
;
char
*
uri
;
if
(
!
strcmp
(
p_access
->
psz_access
,
"fd"
))
{
if
(
asprintf
(
&
uri
,
"fd://%s"
,
p_access
->
psz_location
)
==
-
1
)
uri
=
NULL
;
if
(
asprintf
(
&
psz_base_
uri
,
"fd://%s"
,
p_access
->
psz_location
)
==
-
1
)
psz_base_
uri
=
NULL
;
}
else
uri
=
vlc_path2uri
(
p_access
->
psz_filepath
,
"file"
);
if
(
unlikely
(
uri
==
NULL
))
psz_base_
uri
=
vlc_path2uri
(
p_access
->
psz_filepath
,
"file"
);
if
(
unlikely
(
psz_base_
uri
==
NULL
))
{
closedir
(
handle
);
goto
error
;
closedir
(
p_dir
);
return
VLC_ENOMEM
;
}
/* "Open" the base directory */
p_
sys
->
current
=
NULL
;
if
(
!
directory_push
(
p_sys
,
handle
,
uri
)
)
p_
access
->
p_sys
=
calloc
(
1
,
sizeof
(
access_sys_t
))
;
if
(
!
p_access
->
p_sys
)
{
free
(
uri
);
goto
error
;
closedir
(
p_dir
);
free
(
psz_base_uri
);
return
VLC_ENOMEM
;
}
free
(
uri
);
p_access
->
p_sys
=
p_sys
;
p_access
->
p_sys
->
p_dir
=
p_dir
;
p_access
->
p_sys
->
psz_base_uri
=
psz_base_uri
;
p_access
->
pf_readdir
=
DirRead
;
return
VLC_SUCCESS
;
error:
free
(
p_sys
);
return
VLC_EGENERIC
;
}
/*****************************************************************************
...
...
@@ -276,57 +105,87 @@ void DirClose( vlc_object_t * p_this )
access_t
*
p_access
=
(
access_t
*
)
p_this
;
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
while
(
directory_pop
(
p_sys
))
;
free
(
p_sys
->
psz_base_uri
);
closedir
(
p_sys
->
p_dir
)
;
free
(
p_sys
);
}
/* This function is a little bit too complex for what it seems to do, but the
* point is to de-recursify directory recusion to avoid overruning the stack
* in case there's a high directory depth */
static
bool
is_looping
(
access_t
*
p_access
,
const
char
*
psz_uri
)
{
#ifdef S_ISLNK
struct
stat
st
;
bool
b_looping
=
false
;
if
(
vlc_lstat
(
psz_uri
,
&
st
)
!=
0
)
return
false
;
if
(
S_ISLNK
(
st
.
st_mode
))
{
char
*
psz_link
=
malloc
(
st
.
st_size
+
1
);
ssize_t
i_ret
;
if
(
psz_link
)
{
i_ret
=
readlink
(
psz_uri
,
psz_link
,
st
.
st_size
+
1
);
if
(
i_ret
>
0
&&
i_ret
<=
st
.
st_size
)
{
psz_link
[
i_ret
]
=
'\0'
;
if
(
strstr
(
p_access
->
psz_filepath
,
psz_link
))
b_looping
=
true
;
}
free
(
psz_link
);
}
}
return
b_looping
;
#else
return
false
;
#endif
}
input_item_t
*
DirRead
(
access_t
*
p_access
)
{
access_sys_t
*
p_sys
=
p_access
->
p_sys
;
DIR
*
p_dir
=
p_sys
->
p_dir
;
input_item_t
*
p_item
=
NULL
;
const
char
*
psz_entry
;
while
(
!
p_item
&&
p_sys
->
current
!=
NULL
&&
p_sys
->
current
->
i
<=
p_sys
->
current
->
filec
)
while
(
!
p_item
&&
(
psz_entry
=
vlc_readdir
(
p_dir
)))
{
directory
*
p_current
=
p_sys
->
current
;
char
*
psz_entry
=
p_current
->
filev
[
p_current
->
i
++
];
char
*
psz_full_uri
,
*
psz_uri
;
DIR
*
handle
;
int
i_res
;
char
*
psz_uri
,
*
psz_encoded_entry
;
struct
stat
st
;
int
i_type
;
/* Check if it is a directory or even readable */
i_res
=
directory_open
(
p_current
,
psz_entry
,
&
handle
);
/* Create an input item for the current entry */
psz_uri
=
encode_URI_component
(
psz_entry
);
if
(
psz_uri
==
NULL
||
asprintf
(
&
psz_full_uri
,
"%s/%s"
,
p_current
->
uri
,
psz_uri
)
==
-
1
)
psz_full_uri
=
NULL
;
free
(
psz_uri
);
if
(
psz_full_uri
==
NULL
)
if
(
asprintf
(
&
psz_uri
,
"%s/%s"
,
p_access
->
psz_filepath
,
psz_entry
)
==
-
1
)
return
NULL
;
if
(
vlc_stat
(
psz_uri
,
&
st
)
!=
0
)
{
closedir
(
handle
);
free
(
psz_uri
);
continue
;
}
int
i_type
=
i_res
==
ENTRY_DIR
?
ITEM_TYPE_DIRECTORY
:
ITEM_TYPE_FILE
;
p_item
=
input_item_NewWithType
(
psz_full_uri
,
psz_entry
,
0
,
NULL
,
0
,
0
,
i_type
);
if
(
p_item
==
NULL
)
i_type
=
S_ISDIR
(
st
.
st_mode
)
?
ITEM_TYPE_DIRECTORY
:
ITEM_TYPE_FILE
;
if
(
i_type
==
ITEM_TYPE_DIRECTORY
&&
is_looping
(
p_access
,
psz_uri
))
{
free
(
psz_full_uri
);
closedir
(
handle
);
free
(
psz_uri
);
continue
;
}
free
(
psz_uri
);
/* Create an input item for the current entry */
psz_encoded_entry
=
encode_URI_component
(
psz_entry
);
if
(
psz_encoded_entry
==
NULL
)
continue
;
if
(
asprintf
(
&
psz_uri
,
"%s/%s"
,
p_sys
->
psz_base_uri
,
psz_encoded_entry
)
==
-
1
)
return
NULL
;
free
(
psz_encoded_entry
);
free
(
psz_full_uri
);
p_item
=
input_item_NewWithType
(
psz_uri
,
psz_entry
,
0
,
NULL
,
0
,
0
,
i_type
);
free
(
psz_uri
);
if
(
!
p_item
)
return
NULL
;
}
return
p_item
;
}
modules/access/file.c
View file @
353f77fc
...
...
@@ -205,10 +205,8 @@ int FileOpen( vlc_object_t *p_this )
if
(
S_ISDIR
(
st
.
st_mode
))
{
#ifdef HAVE_FDOPENDIR
DIR
*
handle
=
fdopendir
(
fd
);
if
(
handle
==
NULL
)
goto
error
;
/* Uh? */
return
DirInit
(
p_access
,
handle
);
msg_Err
(
p_access
,
"DirOpen from FileOpen"
);
return
DirOpen
(
VLC_OBJECT
(
p_access
));
#else
msg_Dbg
(
p_access
,
"ignoring directory"
);
goto
error
;
...
...
modules/access/fs.h
View file @
353f77fc
...
...
@@ -26,5 +26,4 @@ void FileClose (vlc_object_t *);
int
DirOpen
(
vlc_object_t
*
);
int
DirInit
(
access_t
*
p_access
,
DIR
*
handle
);
input_item_t
*
DirRead
(
access_t
*
);
int
DirControl
(
access_t
*
,
int
,
va_list
);
void
DirClose
(
vlc_object_t
*
);
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