Commit f37089c8 authored by Gildas Bazin's avatar Gildas Bazin

* modules/gui/skins/src/themeloader.*: dropped the dependancy on libtar
   for the .vlt skins support. libtar is still used if present, otherwise
   we use our small implementation of untar.
parent 1d7d6338
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* themeloader.cpp: ThemeLoader class * themeloader.cpp: ThemeLoader class
***************************************************************************** *****************************************************************************
* Copyright (C) 2003 VideoLAN * Copyright (C) 2003 VideoLAN
* $Id: themeloader.cpp,v 1.7 2003/04/20 19:03:15 jlj Exp $ * $Id: themeloader.cpp,v 1.8 2003/04/24 15:57:50 gbazin Exp $
* *
* Authors: Olivier Teulire <ipkiss@via.ecp.fr> * Authors: Olivier Teulire <ipkiss@via.ecp.fr>
* Emmanuel Puig <karibu@via.ecp.fr> * Emmanuel Puig <karibu@via.ecp.fr>
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#include <fcntl.h> #include <fcntl.h>
#if !defined WIN32 #if !defined WIN32
# include <unistd.h> # include <unistd.h>
# ifndef PATH_MAX
# define MAX_PATH PATH_MAX;
# endif
#else #else
# include <direct.h> # include <direct.h>
#endif #endif
...@@ -37,12 +40,20 @@ ...@@ -37,12 +40,20 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/intf.h> #include <vlc/intf.h>
#if defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H ) #if defined( HAVE_ZLIB_H )
# include <zlib.h> # include <zlib.h>
# include <libtar.h>
# include <errno.h> # include <errno.h>
#endif #endif
#if defined( HAVE_ZLIB_H ) && defined( HAVE_LIBTAR_H )
# include <libtar.h>
#elif defined( HAVE_ZLIB_H )
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 );
#endif
//--- SKIN ------------------------------------------------------------------ //--- SKIN ------------------------------------------------------------------
#include "../os_api.h" #include "../os_api.h"
#include "theme.h" #include "theme.h"
...@@ -72,12 +83,11 @@ ThemeLoader::~ThemeLoader() ...@@ -72,12 +83,11 @@ ThemeLoader::~ThemeLoader()
{ {
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#if defined( HAVE_ZLIB_H )
int gzopen_frontend( char *pathname, int oflags, int mode ) int gzopen_frontend( char *pathname, int oflags, int mode )
{ {
#if defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H )
char *gzflags; char *gzflags;
gzFile gzf; gzFile gzf;
int fd;
switch( oflags & O_ACCMODE ) switch( oflags & O_ACCMODE )
{ {
...@@ -93,14 +103,7 @@ int gzopen_frontend( char *pathname, int oflags, int mode ) ...@@ -93,14 +103,7 @@ int gzopen_frontend( char *pathname, int oflags, int mode )
return -1; return -1;
} }
fd = open( pathname, oflags, mode ); gzf = gzopen( pathname, gzflags );
if( fd == -1 )
return -1;
// if( ( oflags & O_CREAT ) && fchmod( fd, mode ) )
// return -1;
gzf = gzdopen( fd, gzflags );
if( !gzf ) if( !gzf )
{ {
errno = ENOMEM; errno = ENOMEM;
...@@ -108,20 +111,23 @@ int gzopen_frontend( char *pathname, int oflags, int mode ) ...@@ -108,20 +111,23 @@ int gzopen_frontend( char *pathname, int oflags, int mode )
} }
return (int)gzf; return (int)gzf;
#else
return 0;
#endif
} }
#endif
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#if defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H ) #if defined( HAVE_ZLIB_H )
bool ThemeLoader::ExtractTarGz( const string tarfile, const string rootdir ) bool ThemeLoader::ExtractTarGz( const string tarfile, const string rootdir )
{ {
TAR *t; TAR *t;
#if defined( HAVE_LIBTAR_H )
tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose, tartype_t gztype = { (openfunc_t) gzopen_frontend, (closefunc_t) gzclose,
(readfunc_t) gzread, (writefunc_t) gzwrite }; (readfunc_t) gzread, (writefunc_t) gzwrite };
if( tar_open( &t, (char *)tarfile.c_str(), &gztype, O_RDONLY, 0, if( tar_open( &t, (char *)tarfile.c_str(), &gztype, O_RDONLY, 0,
TAR_GNU ) == -1 ) TAR_GNU ) == -1 )
#else
if( tar_open( &t, (char *)tarfile.c_str(), O_RDONLY ) == -1 )
#endif
{ {
return false; return false;
} }
...@@ -189,13 +195,8 @@ bool ThemeLoader::Parse( const string XmlFile ) ...@@ -189,13 +195,8 @@ bool ThemeLoader::Parse( const string XmlFile )
msg_Dbg( p_intf, "Using skin file: %s", XmlFile.c_str() ); msg_Dbg( p_intf, "Using skin file: %s", XmlFile.c_str() );
// Save current working directory // Save current working directory
#ifdef WIN32
char *cwd = new char[MAX_PATH];
getcwd( cwd, MAX_PATH );
#else
char *cwd = new char[PATH_MAX]; char *cwd = new char[PATH_MAX];
getcwd( cwd, PATH_MAX ); getcwd( cwd, PATH_MAX );
#endif
// Directory separator is different in each OS ! // Directory separator is different in each OS !
int p = XmlFile.rfind( DIRECTORY_SEPARATOR, XmlFile.size() ); int p = XmlFile.rfind( DIRECTORY_SEPARATOR, XmlFile.size() );
...@@ -234,7 +235,7 @@ bool ThemeLoader::Load( const string FileName ) ...@@ -234,7 +235,7 @@ bool ThemeLoader::Load( const string FileName )
{ {
// First, we try to un-targz the file, and if it fails we hope it's a XML // First, we try to un-targz the file, and if it fails we hope it's a XML
// file... // file...
#if defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H ) #if defined( HAVE_ZLIB_H )
if( ! Extract( FileName ) && ! Parse( FileName ) ) if( ! Extract( FileName ) && ! Parse( FileName ) )
return false; return false;
#else #else
...@@ -257,3 +258,222 @@ bool ThemeLoader::Load( const string FileName ) ...@@ -257,3 +258,222 @@ bool ThemeLoader::Load( const string FileName )
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#if !defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H )
#ifdef WIN32
# define mkdir(dirname,mode) _mkdir(dirname)
#endif
/* 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;
};
/* helper functions */
int getoct( char *p, int width );
int makedir( char *newdir );
int tar_open( TAR **t, char *pathname, int oflags )
{
gzFile f = gzopen( pathname, "rb" );
if( f == NULL )
{
fprintf( stderr, "Couldn't gzopen %s\n", pathname );
return -1;
}
*t = (gzFile *)malloc( sizeof(gzFile) );
**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;
char fname[BLOCKSIZE + PATH_MAX];
while( 1 )
{
len = gzread( *t, &buffer, BLOCKSIZE );
if(len < 0) fprintf(stderr, "%s", gzerror(*t, &err) );
/*
* Always expect complete blocks to process
* the tar information.
*/
if(len != BLOCKSIZE) fprintf(stderr, "gzread: incomplete block read");
/*
* 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;
sprintf( fname, "%s/%s", prefix, buffer.header.name );
switch (buffer.header.typeflag)
{
case DIRTYPE:
makedir( fname );
break;
case REGTYPE:
case AREGTYPE:
remaining = getoct( buffer.header.size, 12 );
if( remaining )
{
outfile = fopen( fname, "wb" );
if( outfile == NULL )
{
/* try creating directory */
char *p = strrchr( fname, '/' );
if( p != NULL )
{
*p = '\0';
makedir( fname );
*p = '/';
outfile = fopen( fname, "wb" );
if( !outfile )
fprintf( stderr, "tar couldn't create %s",
fname );
}
}
}
else outfile = NULL;
/*
* 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 );
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" );
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;
}
/* 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( 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( mkdir( buffer, 0775 ) == 0 ) { free(buffer); return 1; }
p = buffer+1;
while( 1 )
{
char hold;
while( *p && *p != '\\' && *p != '/' ) p++;
hold = *p;
*p = 0;
if( ( mkdir( buffer, 0775 ) == -1 ) && ( errno == ENOENT ) )
{
fprintf(stderr,"couldn't create directory %s\n", buffer);
free(buffer);
return 0;
}
if( hold == 0 ) break;
*p++ = hold;
}
free(buffer);
return 1;
}
#endif
//---------------------------------------------------------------------------
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* themeloader.h: ThemeLoader class * themeloader.h: ThemeLoader class
***************************************************************************** *****************************************************************************
* Copyright (C) 2003 VideoLAN * Copyright (C) 2003 VideoLAN
* $Id: themeloader.h,v 1.2 2003/03/18 04:56:58 ipkiss Exp $ * $Id: themeloader.h,v 1.3 2003/04/24 15:57:50 gbazin Exp $
* *
* Authors: Olivier Teulière <ipkiss@via.ecp.fr> * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
* Emmanuel Puig <karibu@via.ecp.fr> * Emmanuel Puig <karibu@via.ecp.fr>
...@@ -33,14 +33,14 @@ using namespace std; ...@@ -33,14 +33,14 @@ using namespace std;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
struct intf_thread_t; struct intf_thread_t;
int gzopen_frontend( char *pathname, int oFlags, int mode );
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
class ThemeLoader class ThemeLoader
{ {
private: private:
intf_thread_t *p_intf; intf_thread_t *p_intf;
#if defined( HAVE_LIBTAR_H ) && defined( HAVE_ZLIB_H ) #if defined( HAVE_ZLIB_H )
bool ExtractTarGz( const string tarfile, const string rootdir ); bool ExtractTarGz( const string tarfile, const string rootdir );
bool Extract( const string FileName ); bool Extract( const string FileName );
void DeleteTempFiles( const string Path ); void DeleteTempFiles( const string Path );
...@@ -55,4 +55,3 @@ class ThemeLoader ...@@ -55,4 +55,3 @@ class ThemeLoader
}; };
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment