Chris@4: /* Chris@4: miniunz.c Chris@4: Version 1.1, February 14h, 2010 Chris@4: sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) Chris@4: Chris@4: Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) Chris@4: Chris@4: Modifications of Unzip for Zip64 Chris@4: Copyright (C) 2007-2008 Even Rouault Chris@4: Chris@4: Modifications for Zip64 support on both zip and unzip Chris@4: Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) Chris@4: */ Chris@4: Chris@4: #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) Chris@4: #ifndef __USE_FILE_OFFSET64 Chris@4: #define __USE_FILE_OFFSET64 Chris@4: #endif Chris@4: #ifndef __USE_LARGEFILE64 Chris@4: #define __USE_LARGEFILE64 Chris@4: #endif Chris@4: #ifndef _LARGEFILE64_SOURCE Chris@4: #define _LARGEFILE64_SOURCE Chris@4: #endif Chris@4: #ifndef _FILE_OFFSET_BIT Chris@4: #define _FILE_OFFSET_BIT 64 Chris@4: #endif Chris@4: #endif Chris@4: Chris@4: #ifdef __APPLE__ Chris@4: // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions Chris@4: #define FOPEN_FUNC(filename, mode) fopen(filename, mode) Chris@4: #define FTELLO_FUNC(stream) ftello(stream) Chris@4: #define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin) Chris@4: #else Chris@4: #define FOPEN_FUNC(filename, mode) fopen64(filename, mode) Chris@4: #define FTELLO_FUNC(stream) ftello64(stream) Chris@4: #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) Chris@4: #endif Chris@4: Chris@4: Chris@4: #include Chris@4: #include Chris@4: #include Chris@4: #include Chris@4: #include Chris@4: #include Chris@4: Chris@4: #ifdef _WIN32 Chris@4: # include Chris@4: # include Chris@4: #else Chris@4: # include Chris@4: # include Chris@4: #endif Chris@4: Chris@4: Chris@4: #include "unzip.h" Chris@4: Chris@4: #define CASESENSITIVITY (0) Chris@4: #define WRITEBUFFERSIZE (8192) Chris@4: #define MAXFILENAME (256) Chris@4: Chris@4: #ifdef _WIN32 Chris@4: #define USEWIN32IOAPI Chris@4: #include "iowin32.h" Chris@4: #endif Chris@4: /* Chris@4: mini unzip, demo of unzip package Chris@4: Chris@4: usage : Chris@4: Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] Chris@4: Chris@4: list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT Chris@4: if it exists Chris@4: */ Chris@4: Chris@4: Chris@4: /* change_file_date : change the date/time of a file Chris@4: filename : the filename of the file where date/time must be modified Chris@4: dosdate : the new date at the MSDos format (4 bytes) Chris@4: tmu_date : the SAME new date at the tm_unz format */ Chris@4: void change_file_date(filename,dosdate,tmu_date) Chris@4: const char *filename; Chris@4: uLong dosdate; Chris@4: tm_unz tmu_date; Chris@4: { Chris@4: #ifdef _WIN32 Chris@4: HANDLE hFile; Chris@4: FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; Chris@4: Chris@4: hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE, Chris@4: 0,NULL,OPEN_EXISTING,0,NULL); Chris@4: GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); Chris@4: DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); Chris@4: LocalFileTimeToFileTime(&ftLocal,&ftm); Chris@4: SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); Chris@4: CloseHandle(hFile); Chris@4: #else Chris@4: #ifdef unix || __APPLE__ Chris@4: struct utimbuf ut; Chris@4: struct tm newdate; Chris@4: newdate.tm_sec = tmu_date.tm_sec; Chris@4: newdate.tm_min=tmu_date.tm_min; Chris@4: newdate.tm_hour=tmu_date.tm_hour; Chris@4: newdate.tm_mday=tmu_date.tm_mday; Chris@4: newdate.tm_mon=tmu_date.tm_mon; Chris@4: if (tmu_date.tm_year > 1900) Chris@4: newdate.tm_year=tmu_date.tm_year - 1900; Chris@4: else Chris@4: newdate.tm_year=tmu_date.tm_year ; Chris@4: newdate.tm_isdst=-1; Chris@4: Chris@4: ut.actime=ut.modtime=mktime(&newdate); Chris@4: utime(filename,&ut); Chris@4: #endif Chris@4: #endif Chris@4: } Chris@4: Chris@4: Chris@4: /* mymkdir and change_file_date are not 100 % portable Chris@4: As I don't know well Unix, I wait feedback for the unix portion */ Chris@4: Chris@4: int mymkdir(dirname) Chris@4: const char* dirname; Chris@4: { Chris@4: int ret=0; Chris@4: #ifdef _WIN32 Chris@4: ret = _mkdir(dirname); Chris@4: #elif unix Chris@4: ret = mkdir (dirname,0775); Chris@4: #elif __APPLE__ Chris@4: ret = mkdir (dirname,0775); Chris@4: #endif Chris@4: return ret; Chris@4: } Chris@4: Chris@4: int makedir (newdir) Chris@4: char *newdir; Chris@4: { Chris@4: char *buffer ; Chris@4: char *p; Chris@4: int len = (int)strlen(newdir); Chris@4: Chris@4: if (len <= 0) Chris@4: return 0; Chris@4: Chris@4: buffer = (char*)malloc(len+1); Chris@4: if (buffer==NULL) Chris@4: { Chris@4: printf("Error allocating memory\n"); Chris@4: return UNZ_INTERNALERROR; Chris@4: } Chris@4: strcpy(buffer,newdir); Chris@4: Chris@4: if (buffer[len-1] == '/') { Chris@4: buffer[len-1] = '\0'; Chris@4: } Chris@4: if (mymkdir(buffer) == 0) Chris@4: { Chris@4: free(buffer); Chris@4: return 1; Chris@4: } Chris@4: Chris@4: p = buffer+1; Chris@4: while (1) Chris@4: { Chris@4: char hold; Chris@4: Chris@4: while(*p && *p != '\\' && *p != '/') Chris@4: p++; Chris@4: hold = *p; Chris@4: *p = 0; Chris@4: if ((mymkdir(buffer) == -1) && (errno == ENOENT)) Chris@4: { Chris@4: printf("couldn't create directory %s\n",buffer); Chris@4: free(buffer); Chris@4: return 0; Chris@4: } Chris@4: if (hold == 0) Chris@4: break; Chris@4: *p++ = hold; Chris@4: } Chris@4: free(buffer); Chris@4: return 1; Chris@4: } Chris@4: Chris@4: void do_banner() Chris@4: { Chris@4: printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n"); Chris@4: printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n"); Chris@4: } Chris@4: Chris@4: void do_help() Chris@4: { Chris@4: printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \ Chris@4: " -e Extract without pathname (junk paths)\n" \ Chris@4: " -x Extract with pathname\n" \ Chris@4: " -v list files\n" \ Chris@4: " -l list files\n" \ Chris@4: " -d directory to extract into\n" \ Chris@4: " -o overwrite files without prompting\n" \ Chris@4: " -p extract crypted file using password\n\n"); Chris@4: } Chris@4: Chris@4: void Display64BitsSize(ZPOS64_T n, int size_char) Chris@4: { Chris@4: /* to avoid compatibility problem , we do here the conversion */ Chris@4: char number[21]; Chris@4: int offset=19; Chris@4: int pos_string = 19; Chris@4: number[20]=0; Chris@4: for (;;) { Chris@4: number[offset]=(char)((n%10)+'0'); Chris@4: if (number[offset] != '0') Chris@4: pos_string=offset; Chris@4: n/=10; Chris@4: if (offset==0) Chris@4: break; Chris@4: offset--; Chris@4: } Chris@4: { Chris@4: int size_display_string = 19-pos_string; Chris@4: while (size_char > size_display_string) Chris@4: { Chris@4: size_char--; Chris@4: printf(" "); Chris@4: } Chris@4: } Chris@4: Chris@4: printf("%s",&number[pos_string]); Chris@4: } Chris@4: Chris@4: int do_list(uf) Chris@4: unzFile uf; Chris@4: { Chris@4: uLong i; Chris@4: unz_global_info64 gi; Chris@4: int err; Chris@4: Chris@4: err = unzGetGlobalInfo64(uf,&gi); Chris@4: if (err!=UNZ_OK) Chris@4: printf("error %d with zipfile in unzGetGlobalInfo \n",err); Chris@4: printf(" Length Method Size Ratio Date Time CRC-32 Name\n"); Chris@4: printf(" ------ ------ ---- ----- ---- ---- ------ ----\n"); Chris@4: for (i=0;i0) Chris@4: ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size); Chris@4: Chris@4: /* display a '*' if the file is crypted */ Chris@4: if ((file_info.flag & 1) != 0) Chris@4: charCrypt='*'; Chris@4: Chris@4: if (file_info.compression_method==0) Chris@4: string_method="Stored"; Chris@4: else Chris@4: if (file_info.compression_method==Z_DEFLATED) Chris@4: { Chris@4: uInt iLevel=(uInt)((file_info.flag & 0x6)/2); Chris@4: if (iLevel==0) Chris@4: string_method="Defl:N"; Chris@4: else if (iLevel==1) Chris@4: string_method="Defl:X"; Chris@4: else if ((iLevel==2) || (iLevel==3)) Chris@4: string_method="Defl:F"; /* 2:fast , 3 : extra fast*/ Chris@4: } Chris@4: else Chris@4: if (file_info.compression_method==Z_BZIP2ED) Chris@4: { Chris@4: string_method="BZip2 "; Chris@4: } Chris@4: else Chris@4: string_method="Unkn. "; Chris@4: Chris@4: Display64BitsSize(file_info.uncompressed_size,7); Chris@4: printf(" %6s%c",string_method,charCrypt); Chris@4: Display64BitsSize(file_info.compressed_size,7); Chris@4: printf(" %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n", Chris@4: ratio, Chris@4: (uLong)file_info.tmu_date.tm_mon + 1, Chris@4: (uLong)file_info.tmu_date.tm_mday, Chris@4: (uLong)file_info.tmu_date.tm_year % 100, Chris@4: (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min, Chris@4: (uLong)file_info.crc,filename_inzip); Chris@4: if ((i+1)='a') && (rep<='z')) Chris@4: rep -= 0x20; Chris@4: } Chris@4: while ((rep!='Y') && (rep!='N') && (rep!='A')); Chris@4: } Chris@4: Chris@4: if (rep == 'N') Chris@4: skip = 1; Chris@4: Chris@4: if (rep == 'A') Chris@4: *popt_overwrite=1; Chris@4: } Chris@4: Chris@4: if ((skip==0) && (err==UNZ_OK)) Chris@4: { Chris@4: fout=FOPEN_FUNC(write_filename,"wb"); Chris@4: /* some zipfile don't contain directory alone before file */ Chris@4: if ((fout==NULL) && ((*popt_extract_without_path)==0) && Chris@4: (filename_withoutpath!=(char*)filename_inzip)) Chris@4: { Chris@4: char c=*(filename_withoutpath-1); Chris@4: *(filename_withoutpath-1)='\0'; Chris@4: makedir(write_filename); Chris@4: *(filename_withoutpath-1)=c; Chris@4: fout=FOPEN_FUNC(write_filename,"wb"); Chris@4: } Chris@4: Chris@4: if (fout==NULL) Chris@4: { Chris@4: printf("error opening %s\n",write_filename); Chris@4: } Chris@4: } Chris@4: Chris@4: if (fout!=NULL) Chris@4: { Chris@4: printf(" extracting: %s\n",write_filename); Chris@4: Chris@4: do Chris@4: { Chris@4: err = unzReadCurrentFile(uf,buf,size_buf); Chris@4: if (err<0) Chris@4: { Chris@4: printf("error %d with zipfile in unzReadCurrentFile\n",err); Chris@4: break; Chris@4: } Chris@4: if (err>0) Chris@4: if (fwrite(buf,err,1,fout)!=1) Chris@4: { Chris@4: printf("error in writing extracted file\n"); Chris@4: err=UNZ_ERRNO; Chris@4: break; Chris@4: } Chris@4: } Chris@4: while (err>0); Chris@4: if (fout) Chris@4: fclose(fout); Chris@4: Chris@4: if (err==0) Chris@4: change_file_date(write_filename,file_info.dosDate, Chris@4: file_info.tmu_date); Chris@4: } Chris@4: Chris@4: if (err==UNZ_OK) Chris@4: { Chris@4: err = unzCloseCurrentFile (uf); Chris@4: if (err!=UNZ_OK) Chris@4: { Chris@4: printf("error %d with zipfile in unzCloseCurrentFile\n",err); Chris@4: } Chris@4: } Chris@4: else Chris@4: unzCloseCurrentFile(uf); /* don't lose the error */ Chris@4: } Chris@4: Chris@4: free(buf); Chris@4: return err; Chris@4: } Chris@4: Chris@4: Chris@4: int do_extract(uf,opt_extract_without_path,opt_overwrite,password) Chris@4: unzFile uf; Chris@4: int opt_extract_without_path; Chris@4: int opt_overwrite; Chris@4: const char* password; Chris@4: { Chris@4: uLong i; Chris@4: unz_global_info64 gi; Chris@4: int err; Chris@4: FILE* fout=NULL; Chris@4: Chris@4: err = unzGetGlobalInfo64(uf,&gi); Chris@4: if (err!=UNZ_OK) Chris@4: printf("error %d with zipfile in unzGetGlobalInfo \n",err); Chris@4: Chris@4: for (i=0;i