1 /*****************************************************************************
2 * directory.c: expands a directory (directory: access_browser plug-in)
3 *****************************************************************************
4 * Copyright (C) 2002-2015 VLC authors and VideoLAN
7 * Authors: Derk-Jan Hartman <hartman at videolan dot org>
9 * Julien 'Lta' BALLET <contact # lta.io>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
37 #include <vlc_common.h>
39 #include <vlc_access.h>
40 #include <vlc_input_item.h>
51 /*****************************************************************************
52 * DirInit: Init the directory access with a directory stream
53 *****************************************************************************/
54 int DirInit (stream_t
*access
, DIR *dir
)
56 access_sys_t
*sys
= vlc_obj_alloc(VLC_OBJECT(access
), 1, sizeof (*sys
));
57 if (unlikely(sys
== NULL
))
60 if (!strcmp(access
->psz_name
, "fd"))
62 if (unlikely(asprintf(&sys
->base_uri
, "fd://%s",
63 access
->psz_location
) == -1))
67 sys
->base_uri
= vlc_path2uri(access
->psz_filepath
, "file");
68 if (unlikely(sys
->base_uri
== NULL
))
74 access
->pf_readdir
= DirRead
;
75 access
->pf_control
= access_vaDirectoryControlHelper
;
83 /*****************************************************************************
84 * DirOpen: Open the directory access
85 *****************************************************************************/
86 int DirOpen (vlc_object_t
*obj
)
88 stream_t
*access
= (stream_t
*)obj
;
90 if (access
->psz_filepath
== NULL
)
93 DIR *dir
= vlc_opendir(access
->psz_filepath
);
97 return DirInit(access
, dir
);
100 /*****************************************************************************
101 * Close: close the target
102 *****************************************************************************/
103 void DirClose(vlc_object_t
*obj
)
105 stream_t
*access
= (stream_t
*)obj
;
106 access_sys_t
*sys
= access
->p_sys
;
112 int DirRead (stream_t
*access
, input_item_node_t
*node
)
114 access_sys_t
*sys
= access
->p_sys
;
116 int ret
= VLC_SUCCESS
;
118 bool special_files
= var_InheritBool(access
, "list-special-files");
120 struct vlc_readdir_helper rdh
;
121 vlc_readdir_helper_init(&rdh
, access
, node
);
123 while (ret
== VLC_SUCCESS
&& (entry
= vlc_readdir(sys
->dir
)) != NULL
)
129 if (fstatat(dirfd(sys
->dir
), entry
, &st
, 0))
134 if (snprintf(path
, PATH_MAX
, "%s"DIR_SEP
"%s", access
->psz_filepath
,
135 entry
) >= PATH_MAX
|| vlc_stat(path
, &st
))
138 switch (st
.st_mode
& S_IFMT
)
143 type
= ITEM_TYPE_DISC
;
148 type
= ITEM_TYPE_CARD
;
153 type
= ITEM_TYPE_STREAM
;
156 type
= ITEM_TYPE_FILE
;
159 type
= ITEM_TYPE_DIRECTORY
;
161 /* S_IFLNK cannot occur while following symbolic links */
162 /* S_IFSOCK cannot be opened with open()/openat() */
164 continue; /* ignore */
167 /* Create an input item for the current entry */
168 char *encoded
= vlc_uri_encode(entry
);
169 if (unlikely(encoded
== NULL
))
176 if (unlikely(asprintf(&uri
, "%s/%s", sys
->base_uri
, encoded
) == -1))
179 if (unlikely(uri
== NULL
))
184 ret
= vlc_readdir_helper_additem(&rdh
, uri
, NULL
, entry
, type
,
189 vlc_readdir_helper_finish(&rdh
, ret
== VLC_SUCCESS
);