]> git.sesse.net Git - vlc/blob - modules/access/dsm/browser.c
Add pf_readdir support to libdsm access module
[vlc] / modules / access / dsm / browser.c
1 /*****************************************************************************
2  * bdsm/access.c: liBDSM based SMB/CIFS access module
3  *****************************************************************************
4  * Copyright (C) 2001-2014 VLC authors and VideoLAN
5  *
6  * Authors: Julien 'Lta' BALLET <contact # lta 'dot' io>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include "common.h"
31
32 static int Control (access_t *p_access, int i_query, va_list args);
33 static int BrowseShare( access_t *p_access, input_item_node_t *p_node );
34 static int BrowseDirectory( access_t *p_access, input_item_node_t *p_node );
35 static bool AddToNode( access_t *p_access, input_item_node_t *p_node,
36                        const char *psz_name );
37
38 int BrowserInit( access_t *p_access )
39 {
40     access_sys_t *p_sys = p_access->p_sys;
41
42     if( p_sys->psz_share == NULL )
43         p_access->pf_readdir = BrowseShare;
44     else
45         p_access->pf_readdir = BrowseDirectory;
46     p_access->pf_control = Control;
47
48     return VLC_SUCCESS;
49 }
50
51 static int BrowseShare( access_t *p_access, input_item_node_t *p_node )
52 {
53     smb_share_list  shares;
54     const char     *psz_name;
55     size_t          share_count;
56
57     share_count = smb_share_get_list( p_access->p_sys->p_session, &shares );
58     if( !share_count )
59         return VLC_ENOITEM;
60
61     for( size_t i = 0; i < share_count; i++ )
62     {
63         psz_name = smb_share_list_at( shares, i );
64
65         if( psz_name[strlen( psz_name ) - 1] == '$')
66             continue;
67
68         AddToNode( p_access, p_node, psz_name );
69     }
70
71     smb_share_list_destroy( shares );
72     return VLC_SUCCESS;
73 }
74
75 static int BrowseDirectory( access_t *p_access, input_item_node_t *p_node )
76 {
77     access_sys_t   *p_sys = p_access->p_sys;
78     smb_stat_list   files;
79     smb_stat        st;
80     char           *psz_query;
81     const char     *psz_name;
82     size_t          files_count;
83     int             i_ret;
84
85     if( p_sys->psz_path != NULL )
86     {
87         i_ret = asprintf( &psz_query, "%s\\*", p_sys->psz_path );
88         if( i_ret == -1 )
89             return VLC_ENOMEM;
90         files = smb_find( p_sys->p_session, p_sys->i_tid, psz_query );
91         free( psz_query );
92     }
93     else
94         files = smb_find( p_sys->p_session, p_sys->i_tid, "\\*" );
95
96     if( files == NULL )
97         return VLC_ENOITEM;
98
99     files_count = smb_stat_list_count( files );
100     for( size_t i = 0; i < files_count; i++ )
101     {
102         st = smb_stat_list_at( files, i );
103
104         if( st == NULL )
105             goto error;
106
107         psz_name = smb_stat_name( st );
108
109         /* Avoid infinite loop */
110         if( !strcmp( psz_name, ".") || !strcmp( psz_name, "..") )
111             continue;
112
113         AddToNode( p_access, p_node, psz_name );
114     }
115
116     smb_stat_list_destroy( files );
117     return VLC_SUCCESS;
118
119     error:
120         smb_stat_list_destroy( files );
121         return VLC_ENOITEM;
122 }
123
124 /*****************************************************************************
125  * Control:
126  *****************************************************************************/
127 static int Control( access_t *p_access, int i_query, va_list args )
128 {
129     VLC_UNUSED( p_access );
130
131     switch( i_query )
132     {
133         case ACCESS_CAN_SEEK:
134         case ACCESS_CAN_FASTSEEK:
135             *va_arg( args, bool* ) = false;
136             break;
137
138         case ACCESS_CAN_PAUSE:
139         case ACCESS_CAN_CONTROL_PACE:
140             *va_arg( args, bool* ) = true;
141             break;
142
143         case ACCESS_GET_PTS_DELAY:
144             *va_arg( args, int64_t * ) = DEFAULT_PTS_DELAY * 1000;
145             break;
146
147         default:
148             return VLC_EGENERIC;
149      }
150      return VLC_SUCCESS;
151  }
152
153 static bool AddToNode( access_t *p_access, input_item_node_t *p_node,
154                        const char *psz_name )
155 {
156     access_sys_t *p_sys = p_access->p_sys;
157     input_item_t *p_item;
158     char         *psz_uri, *psz_option;
159     int           i_ret;
160
161     i_ret = asprintf( &psz_uri, "%s/%s", p_node->p_item->psz_uri, psz_name );
162     /* XXX Handle ENOMEM by enabling retry */
163     if( i_ret == -1 )
164         return false;
165
166     p_item = input_item_New( psz_uri, psz_name );
167     free( psz_uri );
168     if( p_item == NULL )
169         return false;
170
171     input_item_CopyOptions( p_node->p_item, p_item );
172     input_item_node_AppendItem( p_node, p_item );
173
174     /* Here we save on the node the credentials that allowed us to login.
175      * That way the user isn't prompted more than once for credentials */
176     i_ret = asprintf( &psz_option, "smb-user=%s", p_sys->creds.login );
177     if( i_ret != -1 )
178         input_item_AddOption( p_item, psz_option, VLC_INPUT_OPTION_TRUSTED );
179     free( psz_option );
180     i_ret = asprintf( &psz_option, "smb-pwd=%s", p_sys->creds.password );
181     if( i_ret != -1 )
182         input_item_AddOption( p_item, psz_option, VLC_INPUT_OPTION_TRUSTED );
183     free( psz_option );
184     asprintf( &psz_option, "smb-domain=%s", p_sys->creds.domain );
185     if( i_ret != -1 )
186         input_item_AddOption( p_item, psz_option, VLC_INPUT_OPTION_TRUSTED );
187     free( psz_option );
188
189     input_item_Release( p_item );
190     return true;
191 }