Commit 5d020c46 authored by Filip Roséen's avatar Filip Roséen Committed by Jean-Baptiste Kempf
Browse files

gui/skins2: remove legacy archive dependencies



This is now handled by ThemeLoader::unarchive, and is therefore no
longer needed.
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent d70ed82c
......@@ -854,19 +854,15 @@ AC_CHECK_HEADERS(zlib.h, [ have_zlib=yes ], [ have_zlib=no ])
AM_CONDITIONAL(HAVE_ZLIB, [ test "${have_zlib}" = "yes" ])
if test "${have_zlib}" = "yes"
then
VLC_ADD_LIBS([skins2 sap unzip zip],[-lz])
VLC_ADD_LIBS([sap],[-lz])
PKG_CHECK_MODULES([MINIZIP], [minizip] , [ have_minizip=yes ], [
AC_CHECK_HEADERS([unzip.h], [
have_minizip=yes
MINIZIP_LIBS="-lminizip -lz"
], [
VLC_ADD_CPPFLAGS([skins2], [-I\\\$(top_srcdir)/modules/access/zip/unzip])
VLC_ADD_LIBS([skins2], [\\\$(top_builddir)/modules/libunzip.la])
have_minizip=no
])
])
VLC_ADD_CPPFLAGS([skins2],[$MINIZIP_CFLAGS])
VLC_ADD_LIBS([skins2],[$MINIZIP_LIBS])
fi
AM_CONDITIONAL(HAVE_MINIZIP, [ test "${have_minizip}" = "yes" ])
......
......@@ -45,253 +45,86 @@
#include "../src/vlcproc.hpp"
#include "../src/window_manager.hpp"
#if defined( HAVE_ZLIB_H )
# include <zlib.h>
# include <errno.h>
int gzopen_frontend ( const char *pathname, int oflags, int mode );
int gzclose_frontend( int );
int gzread_frontend ( int, void *, size_t );
int gzwrite_frontend( int, const void *, size_t );
#if defined( HAVE_LIBTAR_H )
# include <libtar.h>
#else
typedef gzFile TAR;
int tar_open ( TAR **t, char *pathname, int oflags );
int tar_extract_all ( TAR *t, char *prefix );
int tar_close ( TAR *t );
int getoct( char *p, int width );
#endif
int makedir( const char *newdir );
#endif
#define DEFAULT_XML_FILE "theme.xml"
#define WINAMP2_XML_FILE "winamp2.xml"
#define ZIP_BUFFER_SIZE 4096
#ifndef O_BINARY
# define O_BINARY 0
#endif
bool ThemeLoader::load( const std::string &fileName )
/* Recursive make directory
* Abort if you get an ENOENT errno somewhere in the middle
* e.g. ignore error "mkdir on existing directory"
*
* return 1 if OK, 0 on error
*/
static int makedir( const char *newdir )
{
std::string path = getFilePath( fileName );
//Before all, let's see if the file is present
struct stat p_stat;
if( vlc_stat( fileName.c_str(), &p_stat ) )
return false;
// First, we try to un-targz the file, and if it fails we hope it's a XML
// file...
#if defined( HAVE_ZLIB_H )
if( ! extract( fileName ) && ! parse( path, fileName ) )
return false;
#else
if( ! parse( path, fileName ) )
return false;
#endif
Theme *pNewTheme = getIntf()->p_sys->p_theme;
if( !pNewTheme )
return false;
// Restore the theme configuration
getIntf()->p_sys->p_theme->loadConfig();
// Retain new loaded skins in config
config_PutPsz( getIntf(), "skins2-last", fileName.c_str() );
return true;
}
char *p, *buffer = strdup( newdir );
int len = strlen( buffer );
#if defined( HAVE_ZLIB_H )
bool ThemeLoader::extractTarGz( const std::string &tarFile, const std::string &rootDir )
{
TAR *t;
#if defined( HAVE_LIBTAR_H )
tartype_t gztype = { (openfunc_t) gzopen_frontend,
(closefunc_t) gzclose_frontend,
(readfunc_t) gzread_frontend,
(writefunc_t) gzwrite_frontend };
if( tar_open( &t, (char *)tarFile.c_str(), &gztype, O_RDONLY, 0,
TAR_GNU ) == -1 )
#else
if( tar_open( &t, (char *)tarFile.c_str(), O_RDONLY ) == -1 )
#endif
if( len <= 0 )
{
msg_Dbg( getIntf(), "failed to open %s as a gzip tar file",
tarFile.c_str() );
return false;
free( buffer );
return 0;
}
if( tar_extract_all( t, (char *)rootDir.c_str() ) != 0 )
if( buffer[len-1] == '/' )
{
tar_close( t );
return false;
buffer[len-1] = '\0';
}
if( tar_close( t ) != 0 )
if( vlc_mkdir( buffer, 0775 ) == 0 )
{
return false;
free( buffer );
return 1;
}
return true;
}
static voidpf ZCALLBACK open_vlc( voidpf opaque, const char *filename, int mode)
{
(void)mode;
intf_thread_t *pIntf = (intf_thread_t *)opaque;
FILE *stream = vlc_fopen( filename, "rb" );
if( stream == NULL )
msg_Dbg( pIntf, "vlc_fopen failed for %s", filename );
return stream;
}
bool ThemeLoader::extractZip( const std::string &zipFile, const std::string &rootDir )
{
bool b_isWsz = strstr( zipFile.c_str(), ".wsz" );
// Try to open the ZIP file
zlib_filefunc_def descr;
fill_fopen_filefunc( &descr );
descr.zopen_file = open_vlc;
descr.opaque = getIntf();
unzFile file = unzOpen2( zipFile.c_str(), &descr );
if( file == 0 )
{
msg_Dbg( getIntf(), "failed to open %s as a zip file",
zipFile.c_str() );
return false;
}
unz_global_info info;
if( unzGetGlobalInfo( file, &info ) != UNZ_OK )
{
msg_Dbg( getIntf(), "failed to read zip info from %s",
zipFile.c_str() );
unzClose( file );
return false;
}
// Extract all the files in the archive
for( unsigned long i = 0; i < info.number_entry; i++ )
p = buffer + 1;
while( 1 )
{
if( !extractFileInZip( file, rootDir, b_isWsz ) )
{
msg_Warn( getIntf(), "error while unzipping %s",
zipFile.c_str() );
unzClose( file );
return false;
}
char hold;
if( i < info.number_entry - 1 )
while( *p && *p != '\\' && *p != '/' ) p++;
hold = *p;
*p = 0;
if( ( vlc_mkdir( buffer, 0775 ) == -1 ) && ( errno == ENOENT ) )
{
// Go the next file in the archive
if( unzGoToNextFile( file ) != UNZ_OK )
{
msg_Warn( getIntf(), "error while unzipping %s",
zipFile.c_str() );
unzClose( file );
return false;
}
fprintf( stderr, "couldn't create directory %s\n", buffer );
free( buffer );
return 0;
}
if( hold == 0 ) break;
*p++ = hold;
}
unzClose( file );
return true;
free( buffer );
return 1;
}
bool ThemeLoader::extractFileInZip( unzFile file, const std::string &rootDir,
bool isWsz )
bool ThemeLoader::load( const std::string &fileName )
{
// Read info for the current file
char filenameInZip[256];
unz_file_info fileInfo;
if( unzGetCurrentFileInfo( file, &fileInfo, filenameInZip,
sizeof( filenameInZip), NULL, 0, NULL, 0 )
!= UNZ_OK )
{
return false;
}
// Convert the file name to lower case, because some winamp skins
// use the wrong case...
if( isWsz )
for( size_t i = 0; i < strlen( filenameInZip ); i++ )
filenameInZip[i] = tolower( (unsigned char)filenameInZip[i] );
std::string path = getFilePath( fileName );
// Allocate the buffer
void *pBuffer = malloc( ZIP_BUFFER_SIZE );
if( !pBuffer )
//Before all, let's see if the file is present
struct stat p_stat;
if( vlc_stat( fileName.c_str(), &p_stat ) )
return false;
// Get the path of the file
OSFactory *pOsFactory = OSFactory::instance( getIntf() );
std::string fullPath = rootDir
+ pOsFactory->getDirSeparator()
+ fixDirSeparators( filenameInZip );
std::string basePath = getFilePath( fullPath );
// First, we try to un-targz the file, and if it fails we hope it's a XML
// file...
// Extract the file if is not a directory
if( basePath != fullPath )
{
if( unzOpenCurrentFile( file ) )
{
free( pBuffer );
return false;
}
makedir( basePath.c_str() );
FILE *fout = vlc_fopen( fullPath.c_str(), "wb" );
if( fout == NULL )
{
msg_Err( getIntf(), "error opening %s", fullPath.c_str() );
free( pBuffer );
return false;
}
if( ! extract( fileName ) && ! parse( path, fileName ) )
return false;
// Extract the current file
int n;
do
{
n = unzReadCurrentFile( file, pBuffer, ZIP_BUFFER_SIZE );
if( n < 0 )
{
msg_Err( getIntf(), "error while reading zip file" );
fclose(fout);
free( pBuffer );
return false;
}
else if( n > 0 )
{
if( fwrite( pBuffer, n , 1, fout) != 1 )
{
msg_Err( getIntf(), "error while writing %s",
fullPath.c_str() );
fclose(fout);
free( pBuffer );
return false;
}
}
} while( n > 0 );
Theme *pNewTheme = getIntf()->p_sys->p_theme;
if( !pNewTheme )
return false;
fclose(fout);
// Restore the theme configuration
getIntf()->p_sys->p_theme->loadConfig();
if( unzCloseCurrentFile( file ) != UNZ_OK )
{
free( pBuffer );
return false;
}
}
// Retain new loaded skins in config
config_PutPsz( getIntf(), "skins2-last", fileName.c_str() );
free( pBuffer );
return true;
}
bool ThemeLoader::extract( const std::string &fileName )
{
bool result = true;
......@@ -472,8 +305,6 @@ void ThemeLoader::deleteTempFiles( const std::string &path )
{
OSFactory::instance( getIntf() )->rmDir( path );
}
#endif // HAVE_ZLIB_H
bool ThemeLoader::parse( const std::string &path, const std::string &xmlFile )
{
......@@ -514,22 +345,6 @@ std::string ThemeLoader::getFilePath( const std::string &rFullPath )
return basePath;
}
std::string ThemeLoader::fixDirSeparators( const std::string &rPath )
{
OSFactory *pOsFactory = OSFactory::instance( getIntf() );
const std::string &sep = pOsFactory->getDirSeparator();
std::string::size_type p = rPath.find( "/", 0 );
std::string newPath = rPath;
while( p != std::string::npos )
{
newPath = newPath.replace( p, 1, sep );
p = newPath.find( "/", p + 1 );
}
return newPath;
}
bool ThemeLoader::findFile( const std::string &rootDir, const std::string &rFileName,
std::string &themeFilePath )
{
......@@ -592,351 +407,6 @@ bool ThemeLoader::findFile( const std::string &rootDir, const std::string &rFile
return false;
}
#if !defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H )
/* Values used in typeflag field */
#define REGTYPE '0' /* regular file */
#define AREGTYPE '\0' /* regular file */
#define DIRTYPE '5' /* directory */
#define BLOCKSIZE 512
struct tar_header
{ /* byte offset */
char name[100]; /* 0 */
char mode[8]; /* 100 */
char uid[8]; /* 108 */
char gid[8]; /* 116 */
char size[12]; /* 124 */
char mtime[12]; /* 136 */
char chksum[8]; /* 148 */
char typeflag; /* 156 */
char linkname[100]; /* 157 */
char magic[6]; /* 257 */
char version[2]; /* 263 */
char uname[32]; /* 265 */
char gname[32]; /* 297 */
char devmajor[8]; /* 329 */
char devminor[8]; /* 337 */
char prefix[155]; /* 345 */
/* 500 */
};
union tar_buffer {
char buffer[BLOCKSIZE];
struct tar_header header;
};
int tar_open( TAR **t, char *pathname, int oflags )
{
(void)oflags;
int fd = vlc_open( pathname, O_BINARY | O_RDONLY );
if( fd == -1 )
{
fprintf( stderr, "Couldn't open %s\n", pathname );
return -1;
}
gzFile f = gzdopen( fd, "rb" );
if( f == NULL )
{
fprintf( stderr, "Couldn't gzopen %s\n", pathname );
vlc_close( fd );
return -1;
}
*t = (gzFile *)malloc( sizeof(gzFile) );
if( *t == NULL )
{
gzclose( f );
return -1;
}
**t = f;
return 0;
}
int tar_extract_all( TAR *t, char *prefix )
{
union tar_buffer buffer;
int len, err, getheader = 1, remaining = 0;
FILE *outfile = NULL;
#if defined( _WIN32 )
long path_max = PATH_MAX;
#else
long path_max = pathconf (".", _PC_PATH_MAX);
#endif
size_t maxsize = (path_max == -1 || path_max > 4096) ? 4096 : path_max;
char fname[BLOCKSIZE + maxsize];
while( 1 )
{
len = gzread( *t, &buffer, BLOCKSIZE );
if( len < 0 )
{
fprintf( stderr, "%s\n", gzerror(*t, &err) );
}
/*
* Always expect complete blocks to process
* the tar information.
*/
if( len != 0 && len != BLOCKSIZE )
{
fprintf( stderr, "gzread: incomplete block read\n" );
return -1;
}
/*
* If we have to get a tar header
*/
if( getheader == 1 )
{
/*
* If we met the end of the tar
* or the end-of-tar block, we are done
*/
if( (len == 0) || (buffer.header.name[0] == 0) )
{
break;
}
snprintf( fname, sizeof(fname), "%s/%s", prefix, buffer.header.name );
/* Check magic value in header */
if( strncmp( buffer.header.magic, "GNUtar", 6 ) &&
strncmp( buffer.header.magic, "ustar", 5 ) )
{
//fprintf(stderr, "not a tar file\n");
return -1;
}
switch( buffer.header.typeflag )
{
case DIRTYPE:
makedir( fname );
break;
case REGTYPE:
case AREGTYPE:
remaining = getoct( buffer.header.size, 12 );
if( !remaining ) outfile = NULL; else
{
outfile = vlc_fopen( fname, "wb" );
if( outfile == NULL )
{
/* try creating directory */
char *p = strrchr( fname, '/' );
if( p != NULL )
{
*p = '\0';
makedir( fname );
*p = '/';
outfile = vlc_fopen( fname, "wb" );
if( !outfile )
{
fprintf( stderr, "tar couldn't create %s\n",
fname );
}
}
}
}
/*
* could have no contents
*/
getheader = (remaining) ? 0 : 1;
break;
default:
break;
}
}
else
{
unsigned int bytes = (remaining > BLOCKSIZE)?BLOCKSIZE:remaining;
if( outfile != NULL )
{
if( fwrite( &buffer, sizeof(char), bytes, outfile ) != bytes )
{
fprintf( stderr, "error writing %s skipping...\n", fname );
fclose( outfile );
outfile = NULL;
vlc_unlink( fname );
}
}
remaining -= bytes;
if( remaining == 0 )
{
getheader = 1;
if( outfile != NULL )
{
fclose(outfile);
outfile = NULL;
}
}
}
}
return 0;
}
int tar_close( TAR *t )
{
if( gzclose( *t ) != Z_OK ) fprintf( stderr, "failed gzclose\n" );
free( t );
return 0;
}
/* helper functions */
int getoct( char *p, int width )
{
int result = 0;
char c;
while( width-- )
{
c = *p++;
if( c == ' ' )
continue;
if( c == 0 )
break;
result = result * 8 + (c - '0');
}
return result;
}
#endif
/* Recursive make directory
* Abort if you get an ENOENT errno somewhere in the middle
* e.g. ignore error "mkdir on existing directory"
*
* return 1 if OK, 0 on error
*/
int makedir( const char *newdir )
{
char *p, *buffer = strdup( newdir );
int len = strlen( buffer );
if( len <= 0 )
{
free( buffer );
return 0;
}
if( buffer[len-1] == '/' )
{
buffer[len-1] = '\0';
}
if( vlc_mkdir( buffer, 0775 ) == 0 )
{
free( buffer );
return 1;
}