[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