[vlc-devel] Re: [0.8.6-bugfix] Backport Win32 UTF8 Directory access
xxcv
xxcv07 at gmail.com
Thu Jan 18 15:35:48 CET 2007
Please read added comments below thanks:
>
> ------------------------------------------------------------------------
>
> --- /home/slack/VLC_0.8.6b_SVN/include/charset.h 2006-10-13
> 16:03:36.000000000 +1000
> +++ include/charset.h 2007-01-15 11:35:41.000000000 +1100
> @@ -37,11 +37,16 @@
> VLC_EXPORT( char *, ToLocale, ( const char * ) );
>
> VLC_EXPORT( FILE *, utf8_fopen, ( const char *filename, const char
> *mode ) );
> -VLC_EXPORT( void *, utf8_opendir, ( const char *dirname ) );
> -VLC_EXPORT( const char *, utf8_readdir, ( void *dir ) );
> +VLC_EXPORT( DIR *, utf8_opendir, ( const char *dirname ) );
> +VLC_EXPORT( const char *, utf8_readdir, ( DIR *dir ) );
> +VLC_EXPORT( int, utf8_loaddir, ( DIR *dir, char ***namelist, int
> (*select)( const char * ), int (*compar)( const char **, const char **
> ) ) );
> VLC_EXPORT( int, utf8_scandir, ( const char *dirname, char
> ***namelist, int (*select)( const char * ), int (*compar)( const char
> **, const char ** ) ) );
> -VLC_EXPORT( int, utf8_stat, ( const char *filename, void *buf ) );
> -VLC_EXPORT( int, utf8_lstat, ( const char *filename, void *buf ) );
> +
> +#ifdef WIN32
> +# define stat _stati64
> +#endif
> +VLC_EXPORT( int, utf8_stat, ( const char *filename, struct stat *buf
> ) );
> +VLC_EXPORT( int, utf8_lstat, ( const char *filename, struct stat *buf
> ) );
> VLC_EXPORT( int, utf8_mkdir, ( const char *filename ) );
>
> VLC_EXPORT( int, utf8_vfprintf, ( FILE *stream, const char *fmt,
> va_list ap ) );
>
FromWide() from trunk
> @@ -53,13 +58,17 @@
> VLC_EXPORT( char *, FromUTF32, ( const uint32_t * ) );
> VLC_EXPORT( char *, FromUTF16, ( const uint16_t * ) );
>
> -static inline char *FromWide( const wchar_t *in )
> +static inline char *FromWide (const wchar_t *wide)
> {
> - return (sizeof( wchar_t ) == 2)
> - ? FromUTF16( (const uint16_t *)in )
> - : FromUTF32( (const uint32_t *)in );
> -}
> + size_t len = WideCharToMultiByte (CP_UTF8, 0, wide, -1, NULL, 0,
> NULL, NULL);
> + if (len == 0)
> + return NULL;
>
> + char *out = (char *)malloc (len);
> +
> + WideCharToMultiByte (CP_UTF8, 0, wide, -1, out, len, NULL, NULL);
> + return out;
> +}
>
> VLC_EXPORT( char *, __vlc_fix_readdir_charset, ( vlc_object_t *,
> const char * ) );
> #define vlc_fix_readdir_charset(a,b)
> __vlc_fix_readdir_charset(VLC_OBJECT(a),b)
>
Adding / updating required header
> --- /home/slack/VLC_0.8.6b_SVN/include/vlc_common.h 2006-11-17
> 17:14:57.000000000 +1100
> +++ include/vlc_common.h 2007-01-15 12:51:31.000000000 +1100
> @@ -428,6 +428,17 @@
> typedef struct update_t update_t;
> typedef struct update_iterator_t update_iterator_t;
>
> +/* stat/lstat/fstat */
> +#ifdef WIN32
> +#include <sys/stat.h>
> +struct _stati64;
> +#define stat _stati64
> +#define fstat _fstati64
> +/* You should otherwise use utf8_stat and utf8_lstat. */
> +#else
> +struct stat;
> +#endif
> +
> /*****************************************************************************
>
> * Variable callbacks
>
> *****************************************************************************/
>
> @@ -979,9 +990,24 @@
> # endif
> #endif
>
> - VLC_EXPORT( void *, vlc_opendir_wrapper, ( const char * ) );
> - VLC_EXPORT( struct dirent *, vlc_readdir_wrapper, ( void * ) );
> - VLC_EXPORT( int, vlc_closedir_wrapper, ( void * ) );
> +#if defined (WIN32)
> +# include <dirent.h>
> + VLC_EXPORT( void *, vlc_wopendir, ( const wchar_t * ) );
> + VLC_EXPORT( struct _wdirent *, vlc_wreaddir, ( void * ) );
> + VLC_EXPORT( int, vlc_wclosedir, ( void * ) );
> + VLC_EXPORT( void, vlc_rewinddir, ( void * ) );
> + VLC_EXPORT( void, vlc_seekdir, ( void *, long ) );
> + VLC_EXPORT( long, vlc_telldir, ( void * ) );
> +# define opendir Use_utf8_opendir_or_vlc_wopendir_instead!
> +# define readdir Use_utf8_readdir_or_vlc_wreaddir_instead!
> +# define closedir vlc_wclosedir
> +# define _wopendir vlc_wopendir
> +# define _wreaddir vlc_wreaddir
> +# define _wclosedir vlc_wclosedir
> +# define rewinddir vlc_rewinddir
> +# define seekdir vlc_seekdir
> +# define telldir vlc_telldir
> +#endif
>
> /* Format type specifiers for 64 bits numbers */
> #if defined(__CYGWIN32__) || (!defined(WIN32) && !defined(UNDER_CE))
> --- /home/slack/VLC_0.8.6b_SVN/include/vlc_symbols.h 2006-10-13
> 16:03:36.000000000 +1000
> +++ include/vlc_symbols.h 2007-01-15 12:51:34.000000000 +1100
> @@ -414,9 +414,6 @@
> const char * (*VLC_CompileHost_inner) (void);
> const char * (*VLC_Version_inner) (void);
> int (*playlist_PreparseEnqueueItem_inner) (playlist_t *,
> playlist_item_t *);
> - struct dirent * (*vlc_readdir_wrapper_inner) (void *);
> - int (*vlc_closedir_wrapper_inner) (void *);
> - void * (*vlc_opendir_wrapper_inner) (const char *);
> void (*httpd_HandlerDelete_inner) (httpd_handler_t *);
> int (*__vlc_execve_inner) (vlc_object_t *p_object, int i_argc,
> char **pp_argv, char **pp_env, char *psz_cwd, char *p_in, int i_in,
> char **pp_data, int *pi_data);
> httpd_handler_t * (*httpd_HandlerNew_inner) (httpd_host_t *,
> const char *psz_url, const char *psz_user, const char *psz_password,
> const vlc_acl_t *p_acl, httpd_handler_callback_t pf_fill,
> httpd_handler_sys_t *);
> @@ -467,11 +464,11 @@
> void (*vlc_HashInsert_inner) (hashtable_entry_t **, int *, int,
> const char *, void *);
> int (*vlc_HashLookup_inner) (hashtable_entry_t *, int, int, const
> char *);
> void* (*vlc_HashRetrieve_inner) (hashtable_entry_t*, int, int,
> const char *);
> - void * (*utf8_opendir_inner) (const char *dirname);
> + DIR * (*utf8_opendir_inner) (const char *dirname);
> FILE * (*utf8_fopen_inner) (const char *filename, const char *mode);
> - const char * (*utf8_readdir_inner) (void *dir);
> - int (*utf8_stat_inner) (const char *filename, void *buf);
> - int (*utf8_lstat_inner) (const char *filename, void *buf);
> + const char * (*utf8_readdir_inner) (DIR *dir);
> + int (*utf8_stat_inner) (const char *filename, struct stat *buf);
> + int (*utf8_lstat_inner) (const char *filename, struct stat *buf);
> char * (*FromLocaleDup_inner) (const char *);
> int (*utf8_mkdir_inner) (const char *filename);
> vlm_media_t* (*vlm_MediaSearch_inner) (vlm_t *, const char *);
> @@ -497,6 +494,13 @@
> int (*utf8_vfprintf_inner) (FILE *stream, const char *fmt,
> va_list ap);
> void *utf8_fprintf_deprecated;
> void *utf8_vfprintf_deprecated;
> + int (*vlc_wclosedir_inner) (void *);
> + struct _wdirent * (*vlc_wreaddir_inner) (void *);
> + void * (*vlc_wopendir_inner) (const wchar_t *);
> + int (*utf8_loaddir_inner) (DIR *dir, char ***namelist, int
> (*select)( const char * ), int (*compar)( const char **, const char **
> ));
> + void (*vlc_seekdir_inner) (void *, long);
> + void (*vlc_rewinddir_inner) (void *);
> + long (*vlc_telldir_inner) (void *);
> };
> # if defined (__PLUGIN__)
> # define aout_FiltersCreatePipeline
> (p_symbols)->aout_FiltersCreatePipeline_inner
> @@ -893,9 +897,6 @@
> # define VLC_CompileHost (p_symbols)->VLC_CompileHost_inner
> # define VLC_Version (p_symbols)->VLC_Version_inner
> # define playlist_PreparseEnqueueItem
> (p_symbols)->playlist_PreparseEnqueueItem_inner
> -# define vlc_readdir_wrapper (p_symbols)->vlc_readdir_wrapper_inner
> -# define vlc_closedir_wrapper (p_symbols)->vlc_closedir_wrapper_inner
> -# define vlc_opendir_wrapper (p_symbols)->vlc_opendir_wrapper_inner
> # define httpd_HandlerDelete (p_symbols)->httpd_HandlerDelete_inner
> # define __vlc_execve (p_symbols)->__vlc_execve_inner
> # define httpd_HandlerNew (p_symbols)->httpd_HandlerNew_inner
> @@ -972,6 +973,13 @@
> # define input_AddSubtitles (p_symbols)->input_AddSubtitles_inner
> # define utf8_fprintf (p_symbols)->utf8_fprintf_inner
> # define utf8_vfprintf (p_symbols)->utf8_vfprintf_inner
> +# define vlc_wclosedir (p_symbols)->vlc_wclosedir_inner
> +# define vlc_wreaddir (p_symbols)->vlc_wreaddir_inner
> +# define vlc_wopendir (p_symbols)->vlc_wopendir_inner
> +# define utf8_loaddir (p_symbols)->utf8_loaddir_inner
> +# define vlc_seekdir (p_symbols)->vlc_seekdir_inner
> +# define vlc_rewinddir (p_symbols)->vlc_rewinddir_inner
> +# define vlc_telldir (p_symbols)->vlc_telldir_inner
> # elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)
> /******************************************************************
> * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.
> @@ -1371,9 +1379,6 @@
> ((p_symbols)->VLC_CompileHost_inner) = VLC_CompileHost; \
> ((p_symbols)->VLC_Version_inner) = VLC_Version; \
> ((p_symbols)->playlist_PreparseEnqueueItem_inner) =
> playlist_PreparseEnqueueItem; \
> - ((p_symbols)->vlc_readdir_wrapper_inner) = vlc_readdir_wrapper; \
> - ((p_symbols)->vlc_closedir_wrapper_inner) = vlc_closedir_wrapper; \
> - ((p_symbols)->vlc_opendir_wrapper_inner) = vlc_opendir_wrapper; \
> ((p_symbols)->httpd_HandlerDelete_inner) = httpd_HandlerDelete; \
> ((p_symbols)->__vlc_execve_inner) = __vlc_execve; \
> ((p_symbols)->httpd_HandlerNew_inner) = httpd_HandlerNew; \
> @@ -1450,6 +1455,13 @@
> ((p_symbols)->input_AddSubtitles_inner) = input_AddSubtitles; \
> ((p_symbols)->utf8_fprintf_inner) = utf8_fprintf; \
> ((p_symbols)->utf8_vfprintf_inner) = utf8_vfprintf; \
> + ((p_symbols)->vlc_wclosedir_inner) = vlc_wclosedir; \
> + ((p_symbols)->vlc_wreaddir_inner) = vlc_wreaddir; \
> + ((p_symbols)->vlc_wopendir_inner) = vlc_wopendir; \
> + ((p_symbols)->utf8_loaddir_inner) = utf8_loaddir; \
> + ((p_symbols)->vlc_seekdir_inner) = vlc_seekdir; \
> + ((p_symbols)->vlc_rewinddir_inner) = vlc_rewinddir; \
> + ((p_symbols)->vlc_telldir_inner) = vlc_telldir; \
> (p_symbols)->net_ConvertIPv4_deprecated = NULL; \
> (p_symbols)->__stats_CounterGet_deprecated = NULL; \
> (p_symbols)->__stats_TimerDumpAll_deprecated = NULL; \
> --- /home/slack/VLC_0.8.6b_SVN/src/extras/libc.c 2006-11-17
> 17:14:44.000000000 +1100
> +++ src/extras/libc.c 2007-01-15 12:59:50.000000000 +1100
> @@ -52,6 +52,12 @@
> #endif
>
> #if defined(WIN32) || defined(UNDER_CE)
> +# undef _wopendir
> +# undef _wreaddir
> +# undef _wclosedir
> +# undef rewinddir
> +# undef seekdir
> +# undef telldir
> # define WIN32_LEAN_AND_MEAN
> # include <windows.h>
> #endif
>
Update vlc_wopendir, wclose
> @@ -389,25 +395,27 @@
> #endif
>
> /*****************************************************************************
>
> - * vlc_*dir_wrapper: wrapper under Windows to return the list of
> drive letters
> + * vlc_w*dir: wrapper under Windows to return the list of drive letters
> * when called with an empty argument or just '\'
>
> *****************************************************************************/
>
> #if defined(WIN32) && !defined(UNDER_CE)
> +# include <assert.h>
> +
> typedef struct vlc_DIR
> {
> - DIR *p_real_dir;
> + _WDIR *p_real_dir;
> int i_drives;
> - struct dirent dd_dir;
> + struct _wdirent dd_dir;
> vlc_bool_t b_insert_back;
> } vlc_DIR;
>
> -void *vlc_opendir_wrapper( const char *psz_path )
> +void *vlc_wopendir( const wchar_t *wpath )
> {
> vlc_DIR *p_dir;
> - DIR *p_real_dir;
> + _WDIR *p_real_dir;
>
> - if ( psz_path == NULL || psz_path[0] == '\0'
> - || (psz_path[0] == '\\' && psz_path[1] == '\0') )
> + if ( wpath == NULL || wpath[0] == '\0'
> + || (wcscmp (wpath, L"\\") == 0) )
> {
> /* Special mode to list drive letters */
> p_dir = malloc( sizeof(vlc_DIR) );
> @@ -416,18 +424,19 @@
> return (void *)p_dir;
> }
>
> - p_real_dir = opendir( psz_path );
> + p_real_dir = _wopendir( wpath );
> if ( p_real_dir == NULL )
> return NULL;
>
> p_dir = malloc( sizeof(vlc_DIR) );
> p_dir->p_real_dir = p_real_dir;
> - p_dir->b_insert_back = ( psz_path[1] == ':' && psz_path[2] == '\\'
> - && psz_path[3] =='\0' );
> +
> + assert (wpath[0]); // wpath[1] is defined
> + p_dir->b_insert_back = !wcscmp (wpath + 1, L":\\");
> return (void *)p_dir;
> }
>
> -struct dirent *vlc_readdir_wrapper( void *_p_dir )
> +struct _wdirent *vlc_wreaddir( void *_p_dir )
> {
> vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
> unsigned int i;
> @@ -437,15 +446,16 @@
> {
> if ( p_dir->b_insert_back )
> {
> + /* Adds "..", gruik! */
> p_dir->dd_dir.d_ino = 0;
> p_dir->dd_dir.d_reclen = 0;
> p_dir->dd_dir.d_namlen = 2;
> - strcpy( p_dir->dd_dir.d_name, ".." );
> + wcscpy( p_dir->dd_dir.d_name, L".." );
> p_dir->b_insert_back = VLC_FALSE;
> return &p_dir->dd_dir;
> }
>
> - return readdir( p_dir->p_real_dir );
> + return _wreaddir( p_dir->p_real_dir );
> }
>
> /* Drive letters mode */
> @@ -459,38 +469,47 @@
> if ( i >= 26 )
> return NULL; /* this should not happen */
>
> - sprintf( p_dir->dd_dir.d_name, "%c:\\", 'A' + i );
> - p_dir->dd_dir.d_namlen = strlen(p_dir->dd_dir.d_name);
> + swprintf( p_dir->dd_dir.d_name, L"%c:\\", 'A' + i );
> + p_dir->dd_dir.d_namlen = wcslen(p_dir->dd_dir.d_name);
> p_dir->i_drives &= ~(1UL << i);
> return &p_dir->dd_dir;
> }
>
> -int vlc_closedir_wrapper( void *_p_dir )
> +int vlc_wclosedir( void *_p_dir )
> {
> vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
> + int i_ret = 0;
>
> if ( p_dir->p_real_dir != NULL )
> - {
> - int i_ret = closedir( p_dir->p_real_dir );
> - free( p_dir );
> - return i_ret;
> - }
> + i_ret = _wclosedir( p_dir->p_real_dir );
>
> free( p_dir );
> - return 0;
> + return i_ret;
> }
> -#else
> -void *vlc_opendir_wrapper( const char *psz_path )
> +
>
add new functions from trunk
> +void vlc_rewinddir( void *_p_dir )
> {
> - return (void *)opendir( psz_path );
> + vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
> +
> + if ( p_dir->p_real_dir != NULL )
> + _wrewinddir( p_dir->p_real_dir );
> }
> -struct dirent *vlc_readdir_wrapper( void *_p_dir )
> +
> +void vlc_seekdir( void *_p_dir, long loc)
> {
> - return readdir( (DIR *)_p_dir );
> + vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
> +
> + if ( p_dir->p_real_dir != NULL )
> + _wseekdir( p_dir->p_real_dir, loc );
> }
> -int vlc_closedir_wrapper( void *_p_dir )
> +
> +long vlc_telldir( void *_p_dir )
> {
> - return closedir( (DIR *)_p_dir );
> + vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
> +
> + if ( p_dir->p_real_dir != NULL )
> + return _wtelldir( p_dir->p_real_dir );
> + return 0;
> }
> #endif
>
> @@ -498,6 +517,12 @@
> * scandir: scan a directory alpha-sorted
>
> *****************************************************************************/
>
> #if !defined( HAVE_SCANDIR )
> +/* FIXME: I suspect this is dead code -> utf8_scandir */
> +#ifdef WIN32
> +# undef opendir
> +# undef readdir
> +# undef closedir
> +#endif
> int vlc_alphasort( const struct dirent **a, const struct dirent **b )
> {
> return strcoll( (*a)->d_name, (*b)->d_name );
>
no more using wrappers...
> @@ -513,11 +538,11 @@
> struct dirent ** pp_list;
> int ret, size;
>
> - if( !namelist || !( p_dir = vlc_opendir_wrapper( name ) ) )
> return -1;
> + if( !namelist || !( p_dir = opendir( name ) ) ) return -1;
>
> ret = 0;
> pp_list = NULL;
> - while( ( p_content = vlc_readdir_wrapper( p_dir ) ) )
> + while( ( p_content = readdir( p_dir ) ) )
> {
> if( filter && !filter( p_content ) )
> {
> @@ -530,7 +555,7 @@
> ret++;
> }
>
> - vlc_closedir_wrapper( p_dir );
> + closedir( p_dir );
>
> if( compar )
> {
> --- /home/slack/VLC_0.8.6b_SVN/src/misc/modules.c 2006-11-23
> 15:19:29.000000000 +1100
> +++ src/misc/modules.c 2007-01-15 10:40:31.000000000 +1100
> @@ -819,6 +819,12 @@
> static void AllocatePluginDir( vlc_object_t *p_this, const char
> *psz_dir,
> int i_maxdepth )
> {
> +/* FIXME: Needs to be ported to wide char on ALL Windows builds */
> +#ifdef WIN32
> +# undef opendir
> +# undef closedir
> +# undef readdir
> +#endif
> #if defined( UNDER_CE ) || defined( _MSC_VER )
> #ifdef UNDER_CE
> wchar_t psz_wpath[MAX_PATH + 256];
>
updating utf8_opendir, readdir, scandir, loaddir functions
> --- /home/slack/VLC_0.8.6b_SVN/src/misc/unicode.c 2006-10-22
> 14:40:13.000000000 +1000
> +++ src/misc/unicode.c 2007-01-15 13:17:12.000000000 +1100
> @@ -401,31 +401,49 @@
> }
>
>
> -void *utf8_opendir( const char *dirname )
> +DIR *utf8_opendir( const char *dirname )
> {
> - /* TODO: support for WinNT non-ACP filenames */
> +#ifdef WIN32
> + wchar_t wname[MAX_PATH + 1];
> +
> + if (MultiByteToWideChar (CP_UTF8, 0, dirname, -1, wname, MAX_PATH))
> + {
> + wname[MAX_PATH] = L'\0';
> + return (DIR *)vlc_wopendir (wname);
> + }
> +#else
> const char *local_name = ToLocale( dirname );
>
> if( local_name != NULL )
> {
> - DIR *dir = vlc_opendir_wrapper( local_name );
> + DIR *dir = opendir( local_name );
> LocaleFree( local_name );
> return dir;
> }
> else
> errno = ENOENT;
> +#endif
> +
> return NULL;
> }
>
> -const char *utf8_readdir( void *dir )
> +const char *utf8_readdir( DIR *dir )
> {
> +#ifdef WIN32
> + struct _wdirent *ent = vlc_wreaddir( dir );
> + if( ent == NULL )
> + return NULL;
> +
> + return FromWide( ent->d_name );
> +#else
> struct dirent *ent;
>
> - ent = vlc_readdir_wrapper( (DIR *)dir );
> + ent = readdir( dir );
> if( ent == NULL )
> return NULL;
>
> return FromLocale( ent->d_name );
> +#endif
> }
>
> static int dummy_select( const char *str )
> @@ -434,12 +452,10 @@
> return 1;
> }
>
> -int utf8_scandir( const char *dirname, char ***namelist,
> +int utf8_loaddir( DIR *dir, char ***namelist,
> int (*select)( const char * ),
> int (*compar)( const char **, const char ** ) )
> {
> - DIR *dir = utf8_opendir( dirname );
> -
> if( select == NULL )
> select = dummy_select;
>
> @@ -448,33 +464,30 @@
> else
> {
> char **tab = NULL;
> - const char *entry;
> + char *entry;
> unsigned num = 0;
>
> + rewinddir( dir );
> +
> while( ( entry = utf8_readdir( dir ) ) != NULL )
> {
> char **newtab;
> - char *utf_entry = strdup( entry );
> - LocaleFree( entry );
> - if( utf_entry == NULL )
> - goto error;
>
> - if( !select( utf_entry ) )
> + if( !select( entry ) )
> {
> - free( utf_entry );
> + free( entry );
> continue;
> }
>
> newtab = realloc( tab, sizeof( char * ) * (num + 1) );
> if( newtab == NULL )
> {
> - free( utf_entry );
> + free( entry );
> goto error;
> }
> tab = newtab;
> - tab[num++] = utf_entry;
> + tab[num++] = entry;
> }
> - vlc_closedir_wrapper( dir );
>
> if( compar != NULL )
> qsort( tab, num, sizeof( tab[0] ),
> @@ -490,12 +503,27 @@
> free( tab[i] );
> if( tab != NULL )
> free( tab );
> - return -1;}
> + }
> }
> + return -1;
> }
>
> +int utf8_scandir( const char *dirname, char ***namelist,
> + int (*select)( const char * ),
> + int (*compar)( const char **, const char ** ) )
> +{
> + DIR *dir = utf8_opendir (dirname);
> + int val = -1;
> +
> + if (dir != NULL)
> + {
> + val = utf8_loaddir (dir, namelist, select, compar);
> + closedir (dir);
> + }
> + return val;
> +}
>
> -static int utf8_statEx( const char *filename, void *buf,
> +static int utf8_statEx( const char *filename, struct stat *buf,
> vlc_bool_t deref )
> {
> #if defined (WIN32) || defined (UNDER_CE)
> @@ -512,7 +540,7 @@
> }
> wpath[MAX_PATH] = L'\0';
>
> - return _wstati64( wpath, (struct _stati64 *)buf );
> + return _wstati64( wpath, buf );
> }
> #endif
> #ifdef HAVE_SYS_STAT_H
>
> @@ -520,8 +548,8 @@
>
> if( local_name != NULL )
> {
> - int res = deref ? stat( local_name, (struct stat *)buf )
> - : lstat( local_name, (struct stat *)buf );
> + int res = deref ? stat( local_name, buf )
> + : lstat( local_name, buf );
> LocaleFree( local_name );
> return res;
> }
>
Add proper type for buf
> @@ -531,12 +559,12 @@
> }
>
>
> -int utf8_stat( const char *filename, void *buf)
> +int utf8_stat( const char *filename, struct stat *buf)
> {
> return utf8_statEx( filename, buf, VLC_TRUE );
> }
>
> -int utf8_lstat( const char *filename, void *buf)
> +int utf8_lstat( const char *filename, struct stat *buf)
> {
> return utf8_statEx( filename, buf, VLC_FALSE );
> }
> --- /home/slack/VLC_0.8.6b_SVN/src/video_output/vout_intf.c
> 2006-12-09 14:33:45.000000000 +1100
> +++ src/video_output/vout_intf.c 2007-01-15 10:40:31.000000000 +1100
> @@ -641,7 +641,7 @@
> char *psz_prefix = var_GetString( p_vout, "snapshot-prefix" );
> if( !psz_prefix ) psz_prefix = strdup( "vlcsnap-" );
>
> - vlc_closedir_wrapper( path );
> + closedir( path );
> if( var_GetBool( p_vout, "snapshot-sequential" ) == VLC_TRUE )
> {
> int i_num = var_GetInteger( p_vout, "snapshot-num" );
> --- /home/slack/VLC_0.8.6b_SVN/modules/access/directory.c
> 2007-01-15 10:38:00.000000000 +1100
> +++ modules/access/directory.c 2007-01-15 13:09:37.000000000 +1100
> @@ -125,7 +125,9 @@
>
>
> static int ReadDir( playlist_t *, const char *psz_name, int i_mode,
> - playlist_item_t * );
> + playlist_item_t *, DIR *handle );
> +
> +static DIR *OpenDir (vlc_object_t *obj, const char *psz_name);
>
>
Update Open function handled by OpenDir(), same as trunk.
> /*****************************************************************************
>
> * Open: open the directory
> @@ -134,36 +136,12 @@
> {
> access_t *p_access = (access_t*)p_this;
>
> -#ifdef HAVE_SYS_STAT_H
> - struct stat stat_info;
> - char *psz_path = ToLocale( p_access->psz_path );
> -
> - if( ( stat( psz_path, &stat_info ) == -1 ) ||
> - !S_ISDIR( stat_info.st_mode ) )
> -#elif defined(WIN32)
> - int i_ret;
> -
> -# ifdef UNICODE
> - wchar_t psz_path[MAX_PATH];
> - mbstowcs( psz_path, p_access->psz_path, MAX_PATH );
> - psz_path[MAX_PATH-1] = 0;
> -# else
> - char *psz_path = p_access->psz_path;
> -# endif /* UNICODE */
> -
> - i_ret = GetFileAttributes( psz_path );
> - if( i_ret == -1 || !(i_ret & FILE_ATTRIBUTE_DIRECTORY) )
> -
> -#else
> - if( strcmp( p_access->psz_access, "dir") &&
> - strcmp( p_access->psz_access, "directory") )
> -#endif
> - {
> - LocaleFree( psz_path );
> + DIR *handle = OpenDir (p_this, p_access->psz_path);
> + if (handle == NULL)
> return VLC_EGENERIC;
> - }
>
> - LocaleFree( psz_path );
> + p_access->p_sys = (access_sys_t *)handle;
> +
> p_access->pf_read = Read;
> p_access->pf_block = NULL;
> p_access->pf_seek = NULL;
>
>
>
> @@ -283,7 +255,7 @@
> }
>
> p_item->input.i_type = ITEM_TYPE_DIRECTORY;
> - if( ReadDir( p_playlist, psz_name , i_mode, p_item ) !=
> VLC_SUCCESS )
> + if( ReadDir( p_playlist, psz_name , i_mode, p_item, (DIR
> *)p_access->p_sys ) != VLC_SUCCESS )
> {
> }
> end:
> @@ -380,27 +352,27 @@
> return demux2_vaControlHelper( p_demux->s, 0, 0, 0, 1, i_query,
> args );
> }
>
>
Replacing filter by sort as it is used by new function utf8_loaddir() ...
Add extra parameter for ReadDir() with DIR *handle, for handling new
code function in trunk
> -static int Filter( const struct dirent *foo )
> +static int Sort (const char **a, const char **b)
> {
> - return VLC_TRUE;
> + return strcoll (*a, *b);
> }
>
> /*****************************************************************************
>
> * ReadDir: read a directory and add its content to the list
>
> *****************************************************************************/
>
> static int ReadDir( playlist_t *p_playlist, const char *psz_name,
> - int i_mode, playlist_item_t *p_parent )
> + int i_mode, playlist_item_t *p_parent, DIR *handle )
> {
> - struct dirent **pp_dir_content = 0;
> + char **pp_dir_content = NULL;
> int i_dir_content, i, i_return = VLC_SUCCESS;
> playlist_item_t *p_node;
>
> - char **ppsz_extensions = 0;
> + char **ppsz_extensions = NULL;
> int i_extensions = 0;
> char *psz_ignore;
>
> /* Get the first directory entry */
> - i_dir_content = scandir( psz_name, &pp_dir_content, Filter,
> alphasort );
> + i_dir_content = utf8_loaddir (handle, &pp_dir_content, NULL, Sort);
> if( i_dir_content == -1 )
> {
> msg_Warn( p_playlist, "failed to read directory" );
>
Update variables so its used correctly
> @@ -451,87 +423,54 @@
> /* While we still have entries in the directory */
> for( i = 0; i < i_dir_content; i++ )
> {
> - struct dirent *p_dir_content = pp_dir_content[i];
> + const char *p_dir_content = pp_dir_content[i];
> int i_size_entry = strlen( psz_name ) +
> - strlen( p_dir_content->d_name ) + 2;
> + strlen( p_dir_content ) + 2 + 7 /*
> strlen("file://") */;
> char *psz_uri = (char *)malloc( sizeof(char) * i_size_entry );
>
> - sprintf( psz_uri, "%s/%s", psz_name, p_dir_content->d_name );
> + sprintf( psz_uri, "%s/%s", psz_name, p_dir_content );
>
> /* if it starts with '.' then forget it */
> - if( p_dir_content->d_name[0] != '.' )
> + if( p_dir_content[0] != '.' )
> {
>
Removed stat code same as trunk changeset by courmisch, I am not sure if
it will impact other platforms.
> -#if defined( S_ISDIR )
> - struct stat stat_data;
> + DIR *subdir = (i_mode != MODE_COLLAPSE)
> + ? OpenDir (VLC_OBJECT (p_playlist), psz_uri) : NULL;
>
> - if( !stat( psz_uri, &stat_data )
> - && S_ISDIR(stat_data.st_mode) && i_mode != MODE_COLLAPSE )
> -#elif defined( DT_DIR )
> - if( ( p_dir_content->d_type & DT_DIR ) && i_mode !=
> MODE_COLLAPSE )
> -#else
> - if( 0 )
> -#endif
> + if (subdir != NULL) /* Recurse into subdirectory */
> {
> -#if defined( S_ISLNK )
> -/*
> - * FIXME: there is a ToCToU race condition here; but it is rather tricky
> - * impossible to fix while keeping some kind of portable code, and
> maybe even
> - * in a non-portable way.
> - */
> - if( lstat( psz_uri, &stat_data )
> - || S_ISLNK(stat_data.st_mode) )
> - {
> - msg_Dbg( p_playlist, "skipping directory symlink
> %s",
> - psz_uri );
> - free( psz_uri );
> - continue;
> - }
> -#endif
>
If none is set in preference subdirectory are ignored.
> if( i_mode == MODE_NONE )
> {
> msg_Dbg( p_playlist, "skipping subdirectory %s",
> psz_uri );
> + closedir (subdir);
> free( psz_uri );
> continue;
> }
> - else if( i_mode == MODE_EXPAND )
> - {
> - char *psz_newname, *psz_tmp;
> - msg_Dbg(p_playlist, "reading subdirectory %s",
> psz_uri );
> -
> - psz_tmp = FromLocale( p_dir_content->d_name );
> - psz_newname = vlc_fix_readdir_charset(
> - p_playlist, psz_tmp );
> - LocaleFree( psz_tmp );
> -
> - p_node = playlist_NodeCreate( p_playlist,
> - p_parent->pp_parents[0]->i_view,
> - psz_newname, p_parent );
> -
> - playlist_CopyParents( p_parent, p_node );
>
> - p_node->input.i_type = ITEM_TYPE_DIRECTORY;
> + msg_Dbg(p_playlist, "reading subdirectory %s",
> psz_uri );
>
> - /* an strdup() just because of Mac OS X */
> - free( psz_newname );
> -
> - /* If we had the parent in category, the it is
> now node.
> - * Else, we still don't have */
> - if( ReadDir( p_playlist, psz_uri , MODE_EXPAND,
> - p_node ) != VLC_SUCCESS )
> - {
> - i_return = VLC_EGENERIC;
> - break;
> - }
> - }
>
Expanding directory
> + p_node = playlist_NodeCreate( p_playlist,
> + p_parent->pp_parents[0]->i_view,
> + (char *)p_dir_content, p_parent );
> +
> + playlist_CopyParents( p_parent, p_node );
> +
> + p_node->input.i_type = ITEM_TYPE_DIRECTORY;
> +
> + /* If we had the parent in category, the it is now node.
> + * Else, we still don't have */
> + i_return = ReadDir( p_playlist, psz_uri , MODE_EXPAND,
> + p_node, subdir );
> + closedir (subdir);
> + if (i_return)
> + break; // error :-(
> }
> else
> {
> playlist_item_t *p_item;
> - char *psz_tmp1, *psz_tmp2, *psz_loc;
>
> if( i_extensions > 0 )
> {
> - char *psz_dot = strrchr( p_dir_content->d_name,
> '.' );
> + char *psz_dot = strrchr( p_dir_content, '.' );
> if( psz_dot++ && *psz_dot )
> {
> int a;
>
Removing vlc_fix_readdir_charset() but i am not sure what impact will
this have on Apple, is it okay to remove these thedj ?
> @@ -549,18 +488,8 @@
> }
> }
>
> - psz_loc = FromLocale( psz_uri );
> - psz_tmp1 = vlc_fix_readdir_charset(
> VLC_OBJECT(p_playlist),
> - psz_loc );
> - LocaleFree( psz_loc );
> -
> - psz_loc = FromLocale( p_dir_content->d_name );
> - psz_tmp2 = vlc_fix_readdir_charset(
> VLC_OBJECT(p_playlist),
> - psz_loc );
> - LocaleFree( psz_loc );
> -
>
Change to use correct variable.
> p_item = playlist_ItemNewWithType(
> VLC_OBJECT(p_playlist),
> - psz_tmp1, psz_tmp2, ITEM_TYPE_VFILE );
> + psz_uri, p_dir_content, ITEM_TYPE_VFILE );
> playlist_NodeAddItem( p_playlist,p_item,
> p_parent->pp_parents[0]->i_view,
> p_parent,
>
>
Add OpenDir() from trunk
> +
> +static DIR *OpenDir (vlc_object_t *obj, const char *path)
> +{
> + msg_Dbg (obj, "opening directory `%s'", path);
> + DIR *handle = utf8_opendir (path);
> + if (handle == NULL)
> + {
> + int err = errno;
> + if (err != ENOTDIR)
> + msg_Err (obj, "%s: %s", path, strerror (err));
> + else
> + msg_Dbg (obj, "skipping non-directory `%s'", path);
> + errno = err;
> +
> + return NULL;
> + }
> + return handle;
> +}
> +
>
vlc_closedir_wrapper() is no longer used.
> --- /home/slack/VLC_0.8.6b_SVN/modules/control/http/util.c
> 2006-12-09 14:33:46.000000000 +1100
> +++ modules/control/http/util.c 2007-01-15 10:40:31.000000000 +1100
> @@ -253,7 +253,7 @@
> if( !f->name )
> {
> msg_Err( p_intf , "unable to parse directory" );
> - vlc_closedir_wrapper( p_dir );
> + closedir( p_dir );
> free( f );
> return( VLC_ENOMEM );
> }
> @@ -336,7 +336,7 @@
> }
>
> ACL_Destroy( p_acl );
> - vlc_closedir_wrapper( p_dir );
> + closedir( p_dir );
>
> return VLC_SUCCESS;
> }
>
--
This is the vlc-devel mailing-list, see http://www.videolan.org/vlc/
To unsubscribe, please read http://developers.videolan.org/lists.html
More information about the vlc-devel
mailing list