Files
vbagx/source/unzip/miniunz.cpp
dborth 2d9b7ef1f9 [1.0.8 - April 4, 2009]
* "Match Wii Game" controls option! Games that have a Wii equivalent can be
  played using the controls for that Wii game. For example all Zelda games
  can be played with Twilight Princess controls. See the Instructions section
  below for important details.
* Rotation/Tilt sensor games all work
* Solar sensors (Boktai 1/2/3)
* Rumble (except for games that rely on Gameboy Player)
* Keyboard
* PAL support, finally!
* New scaling options, choose how much stretching you want
* Colourised games now partially work but still have distortion
* "Corvette" no longer has a screwed up palette (but still crashes)
* Triggers net reconnection on SMB failure
* Source code refactored, and project file added
* Instructions section added to this readme file
2009-04-10 03:16:28 +00:00

325 lines
7.9 KiB
C++

/*
miniunz.c
Version 1.01e, February 12th, 2005
Copyright (C) 1998-2005 Gilles Vollant
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <utime.h>
#include "unzip.h"
#include "menudraw.h"
#define CASESENSITIVITY (0)
#define WRITEBUFFERSIZE (1024*256)
#define MAXFILENAME (256)
// used to display unzip progress
static uLong total_size;
static uLong total_unzipped;
static int mymkdir(const char* dirname)
{
int ret=0;
ret = mkdir (dirname,0775);
return ret;
}
int makedir (char *newdir)
{
char *buffer ;
char *p;
int len = (int)strlen(newdir);
if (len <= 0)
return 0;
buffer = (char*)malloc(len+1);
strcpy(buffer,newdir);
if (buffer[len-1] == '/') {
buffer[len-1] = '\0';
}
if (mymkdir(buffer) == 0)
{
free(buffer);
return 1;
}
p = buffer+1;
while (1)
{
char hold;
while(*p && *p != '\\' && *p != '/')
p++;
hold = *p;
*p = 0;
if ((mymkdir(buffer) == -1) && (errno == ENOENT))
{
//printf("couldn't create directory %s\n",buffer);
free(buffer);
return 0;
}
if (hold == 0)
break;
*p++ = hold;
}
free(buffer);
return 1;
}
static int do_extract_currentfile(unzFile uf,const int* popt_extract_without_path,int* popt_overwrite,const char* password)
{
char filename_inzip[256];
char* filename_withoutpath;
char* p;
int err=UNZ_OK;
FILE *fout=NULL;
void* buf;
uInt size_buf;
unz_file_info file_info;
err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
if (err!=UNZ_OK)
{
//printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
return err;
}
size_buf = WRITEBUFFERSIZE;
buf = (void*)malloc(size_buf);
if (buf==NULL)
{
//printf("Error allocating memory\n");
return UNZ_INTERNALERROR;
}
p = filename_withoutpath = filename_inzip;
while ((*p) != '\0')
{
if (((*p)=='/') || ((*p)=='\\'))
filename_withoutpath = p+1;
p++;
}
if ((*filename_withoutpath)=='\0')
{
if ((*popt_extract_without_path)==0)
{
//printf("creating directory: %s\n",filename_inzip);
mymkdir(filename_inzip);
}
}
else
{
char* write_filename;
int skip=0;
if ((*popt_extract_without_path)==0)
write_filename = filename_inzip;
else
write_filename = filename_withoutpath;
err = unzOpenCurrentFilePassword(uf,password);
if (err!=UNZ_OK)
{
//printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
}
if (((*popt_overwrite)==0) && (err==UNZ_OK))
{
char rep=0;
FILE* ftestexist;
ftestexist = fopen(write_filename,"rb");
if (ftestexist!=NULL)
{
fclose(ftestexist);
do
{
char answer[128];
int ret;
printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
ret = scanf("%1s",answer);
if (ret != 1)
{
exit(EXIT_FAILURE);
}
rep = answer[0] ;
if ((rep>='a') && (rep<='z'))
rep -= 0x20;
}
while ((rep!='Y') && (rep!='N') && (rep!='A'));
}
if (rep == 'N')
skip = 1;
if (rep == 'A')
*popt_overwrite=1;
}
if ((skip==0) && (err==UNZ_OK))
{
fout=fopen(write_filename,"wb");
/* some zipfile don't contain directory alone before file */
if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
(filename_withoutpath!=(char*)filename_inzip))
{
char c=*(filename_withoutpath-1);
*(filename_withoutpath-1)='\0';
makedir(write_filename);
*(filename_withoutpath-1)=c;
fout=fopen(write_filename,"wb");
}
if (fout==NULL)
{
//printf("error opening %s\n",write_filename);
}
}
if (fout!=NULL)
{
//printf(" extracting: %s\n",write_filename);
do
{
err = unzReadCurrentFile(uf,buf,size_buf);
if (err<0)
{
//printf("error %d with zipfile in unzReadCurrentFile\n",err);
break;
}
if (err>0)
if (fwrite(buf,err,1,fout)!=1)
{
//printf("error in writing extracted file\n");
err=UNZ_ERRNO;
break;
}
total_unzipped += size_buf;
// show progress
ShowProgress("Unzipping...", total_unzipped, total_size);
}
while (err>0);
if (fout)
fclose(fout);
}
if (err==UNZ_OK)
{
err = unzCloseCurrentFile (uf);
if (err!=UNZ_OK)
{
//printf("error %d with zipfile in unzCloseCurrentFile\n",err);
}
}
else
unzCloseCurrentFile(uf); /* don't lose the error */
}
free(buf);
return err;
}
static uLong zipSize(unzFile uf)
{
uLong i;
unz_global_info gi;
int err;
uLong total = 0;
unz_file_info file_info;
char filename_inzip[256];
err = unzGetGlobalInfo (uf,&gi);
for (i=0;i<gi.number_entry;i++)
{
err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
if (err!=UNZ_OK)
return err;
total += file_info.uncompressed_size;
if ((i+1)<gi.number_entry)
{
err = unzGoToNextFile(uf);
if (err!=UNZ_OK)
return err;
}
}
err = unzGoToFirstFile(uf);
if (err!=UNZ_OK)
return err;
return total;
}
int extractZip(unzFile uf,int opt_extract_without_path,int opt_overwrite,const char* password)
{
uLong i;
unz_global_info gi;
int err;
total_size = zipSize(uf);
total_unzipped = 0;
ShowProgress("Unzipping...", total_unzipped, total_size);
err = unzGetGlobalInfo (uf,&gi);
//if (err!=UNZ_OK)
// printf("error %d with zipfile in unzGetGlobalInfo \n",err);
for (i=0;i<gi.number_entry;i++)
{
if (do_extract_currentfile(uf,&opt_extract_without_path,
&opt_overwrite,
password) != UNZ_OK)
break;
if ((i+1)<gi.number_entry)
{
err = unzGoToNextFile(uf);
if (err!=UNZ_OK)
{
//printf("error %d with zipfile in unzGoToNextFile\n",err);
break;
}
}
}
return 0;
}
int extractZipOnefile(unzFile uf,const char* filename,int opt_extract_without_path,int opt_overwrite,const char* password)
{
if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
{
//printf("file %s not found in the zipfile\n",filename);
return 2;
}
if (do_extract_currentfile(uf,&opt_extract_without_path,
&opt_overwrite,
password) == UNZ_OK)
return 0;
else
return 1;
}