live555: remove trailing whitespace
[vlc.git] / modules / access / directory.c
blob1cc93791cf07437c7919cab3bb8d98dd728cb5a2
1 /*****************************************************************************
2 * directory.c: expands a directory (directory: access_browser plug-in)
3 *****************************************************************************
4 * Copyright (C) 2002-2015 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Derk-Jan Hartman <hartman at videolan dot org>
8 * RĂ©mi Denis-Courmont
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 /*****************************************************************************
27 * Preamble
28 *****************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
34 #include <limits.h>
35 #include <sys/stat.h>
37 #include <vlc_common.h>
38 #include "fs.h"
39 #include <vlc_access.h>
40 #include <vlc_input_item.h>
42 #include <vlc_fs.h>
43 #include <vlc_url.h>
45 typedef struct
47 char *base_uri;
48 DIR *dir;
49 } access_sys_t;
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_malloc(VLC_OBJECT(access), sizeof (*sys));
57 if (unlikely(sys == NULL))
58 goto error;
60 if (!strcmp(access->psz_name, "fd"))
62 if (unlikely(asprintf(&sys->base_uri, "fd://%s",
63 access->psz_location) == -1))
64 sys->base_uri = NULL;
66 else
67 sys->base_uri = vlc_path2uri(access->psz_filepath, "file");
68 if (unlikely(sys->base_uri == NULL))
69 goto error;
71 sys->dir = dir;
73 access->p_sys = sys;
74 access->pf_readdir = DirRead;
75 access->pf_control = access_vaDirectoryControlHelper;
76 return VLC_SUCCESS;
78 error:
79 closedir(dir);
80 return VLC_ENOMEM;
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)
91 return VLC_EGENERIC;
93 DIR *dir = vlc_opendir(access->psz_filepath);
94 if (dir == NULL)
95 return VLC_EGENERIC;
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;
108 free(sys->base_uri);
109 closedir(sys->dir);
112 int DirRead (stream_t *access, input_item_node_t *node)
114 access_sys_t *sys = access->p_sys;
115 const char *entry;
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)
125 struct stat st;
126 int type;
128 #ifdef HAVE_OPENAT
129 if (fstatat(dirfd(sys->dir), entry, &st, 0))
130 continue;
131 #else
132 char path[PATH_MAX];
134 if (snprintf(path, PATH_MAX, "%s"DIR_SEP"%s", access->psz_filepath,
135 entry) >= PATH_MAX || vlc_stat(path, &st))
136 continue;
137 #endif
138 switch (st.st_mode & S_IFMT)
140 case S_IFBLK:
141 if (!special_files)
142 continue;
143 type = ITEM_TYPE_DISC;
144 break;
145 case S_IFCHR:
146 if (!special_files)
147 continue;
148 type = ITEM_TYPE_CARD;
149 break;
150 case S_IFIFO:
151 if (!special_files)
152 continue;
153 type = ITEM_TYPE_STREAM;
154 break;
155 case S_IFREG:
156 type = ITEM_TYPE_FILE;
157 break;
158 case S_IFDIR:
159 type = ITEM_TYPE_DIRECTORY;
160 break;
161 /* S_IFLNK cannot occur while following symbolic links */
162 /* S_IFSOCK cannot be opened with open()/openat() */
163 default:
164 continue; /* ignore */
167 /* Create an input item for the current entry */
168 char *encoded = vlc_uri_encode(entry);
169 if (unlikely(encoded == NULL))
171 ret = VLC_ENOMEM;
172 break;
175 char *uri;
176 if (unlikely(asprintf(&uri, "%s/%s", sys->base_uri, encoded) == -1))
177 uri = NULL;
178 free(encoded);
179 if (unlikely(uri == NULL))
181 ret = VLC_ENOMEM;
182 break;
184 ret = vlc_readdir_helper_additem(&rdh, uri, NULL, entry, type,
185 ITEM_NET_UNKNOWN);
186 free(uri);
189 vlc_readdir_helper_finish(&rdh, ret == VLC_SUCCESS);
191 return ret;