/*****************************************************************************
* zipaccess.c: Module (access) to extract different archives, based on zlib
*****************************************************************************
- * Copyright (C) 2007 the VideoLAN team
+ * Copyright (C) 2009 the VideoLAN team
* $Id$
*
* Authors: Jean-Philippe André <jpeg@videolan.org>
*****************************************************************************/
/** @todo:
- * - implement crypto (using url zip://user:password@path-to-archive#ZIP#file
+ * - implement crypto (using url zip://user:password@path-to-archive!/file)
* - read files in zip with long name (use unz_file_info.size_filename)
* - multi-volume archive support ?
*/
# include "config.h"
#endif
-#ifdef HAVE_ZLIB_H
-
#include "zip.h"
#include <vlc_access.h>
static int AccessControl( access_t *p_access, int i_query, va_list args );
static ssize_t AccessRead( access_t *, uint8_t *, size_t );
-static int AccessSeek( access_t *, int64_t );
-static int OpenFileInZip( access_t *p_access, int i_pos );
+static int AccessSeek( access_t *, uint64_t );
+static int OpenFileInZip( access_t *p_access, uint64_t i_pos );
+static char *unescapeXml( const char *psz_text );
+
+/** **************************************************************************
+ * \brief Unescape valid XML string
+ * The exact reverse of escapeToXml (zipstream.c)
+ *****************************************************************************/
+static char *unescapeXml( const char *psz_text )
+{
+ char *psz_ret = malloc( strlen( psz_text ) + 1 );
+ if( !psz_ret ) return NULL;
+
+ char *psz_tmp = psz_ret;
+ for( char *psz_iter = (char*) psz_text; *psz_iter; ++psz_iter, ++psz_tmp )
+ {
+ if( *psz_iter == '?' )
+ {
+ int i_value;
+ if( !sscanf( ++psz_iter, "%02x", &i_value ) )
+ {
+ /* Invalid number: URL incorrectly encoded */
+ free( psz_ret );
+ return NULL;
+ }
+ *psz_tmp = (char) i_value;
+ psz_iter++;
+ }
+ else if( isAllowedChar( *psz_iter ) )
+ {
+ *psz_tmp = *psz_iter;
+ }
+ else
+ {
+ /* Invalid character encoding for the URL */
+ free( psz_ret );
+ return NULL;
+ }
+ }
+ *psz_tmp = '\0';
+
+ return psz_ret;
+}
/** **************************************************************************
* \brief Open access
char *psz_pathToZip = NULL, *psz_path = NULL, *psz_sep = NULL;
+ if( !strstr( p_access->psz_location, ZIP_SEP ) )
+ {
+ msg_Dbg( p_access, "location does not contain separator " ZIP_SEP );
+ return VLC_EGENERIC;
+ }
+
p_access->p_sys = p_sys = (access_sys_t*)
- calloc( sizeof( access_sys_t ), 1 );
+ calloc( 1, sizeof( access_sys_t ) );
if( !p_sys )
return VLC_ENOMEM;
/* Split the MRL */
- psz_path = strdup( p_access->psz_path );
- psz_sep = strchr( psz_path, ZIP_SEP_CHAR );
- if( !psz_sep )
- return VLC_EGENERIC;
+ psz_path = strdup( p_access->psz_location );
+ psz_sep = strstr( psz_path, ZIP_SEP );
*psz_sep = '\0';
- psz_pathToZip = unescape_URI_duplicate( psz_path );
- p_sys->psz_fileInzip = strdup( psz_sep + 1 );
+ psz_pathToZip = unescapeXml( psz_path );
+ if( !psz_pathToZip )
+ {
+ /* Maybe this was not an encoded string */
+ msg_Dbg( p_access, "not an encoded URL Trying file '%s'",
+ psz_path );
+ psz_pathToZip = strdup( psz_path );
+ }
+ p_sys->psz_fileInzip = unescapeXml( psz_sep + ZIP_SEP_LEN );
+ if( !p_sys->psz_fileInzip )
+ {
+ p_sys->psz_fileInzip = strdup( psz_sep + ZIP_SEP_LEN );
+ }
/* Define IO functions */
zlib_filefunc_def *p_func = (zlib_filefunc_def*)
unz_file_info z_info;
unzGetCurrentFileInfo( file, &z_info, NULL, 0, NULL, 0, NULL, 0 );
- /* Set access informations: size is needed for AccessSeek */
+ /* Set access information: size is needed for AccessSeek */
p_access->info.i_size = z_info.uncompressed_size;
p_access->info.i_pos = 0;
p_access->info.b_eof = false;
free( p_sys->fileFunctions );
free( p_sys );
}
- var_Destroy( p_access, "zip-no-xspf" );
}
/** **************************************************************************
static int AccessControl( access_t *p_access, int i_query, va_list args )
{
bool *pb_bool;
- int *pi_int;
int64_t *pi_64;
switch( i_query )
*pb_bool = false;
break;
- /* */
- case ACCESS_GET_MTU:
- pi_int = (int*)va_arg( args, int * );
- *pi_int = 0;
- break;
-
case ACCESS_GET_PTS_DELAY:
pi_64 = (int64_t*)va_arg( args, int64_t * );
*pi_64 = DEFAULT_PTS_DELAY;
/** **************************************************************************
* \brief Seek inside zip file
*****************************************************************************/
-static int AccessSeek( access_t *p_access, int64_t seek_len )
+static int AccessSeek( access_t *p_access, uint64_t seek_len )
{
access_sys_t *p_sys = p_access->p_sys;
assert( p_sys );
}
/* Read seek_len data and drop it */
- int i_seek = 0;
+ unsigned i_seek = 0;
int i_read = 1;
char *p_buffer = ( char* ) calloc( 1, ZIP_BUFFER_LEN );
while( ( i_seek < seek_len ) && ( i_read > 0 ) )
/** **************************************************************************
* \brief Open file in zip
*****************************************************************************/
-static int OpenFileInZip( access_t *p_access, int i_pos )
+static int OpenFileInZip( access_t *p_access, uint64_t i_pos )
{
access_sys_t *p_sys = p_access->p_sys;
unzFile file = p_sys->zipFile;
return VLC_EGENERIC;
}
- i_pos = __MIN( i_pos, 0 );
p_access->info.i_pos = 0;
unzCloseCurrentFile( file ); /* returns UNZ_PARAMERROR if file not opened */
default:
return -1;
}
+ if( pos < 0 )
+ return -1;
//msg_Dbg( p_access, "seek (%d,%d): %" PRIu64, offset, origin, pos );
stream_Seek( (stream_t*) stream, pos );
/* Note: in unzip.c, unzlocal_SearchCentralDir seeks to the end of
//msg_Dbg( p_access, "error" );
return 0;
}
-
-
-
-#else
-# error Can not compile zip demuxer without zlib support
-#endif