miniunz.c
上传用户:zlt_tm
上传日期:2007-01-06
资源大小:214k
文件大小:11k
源码类别:

压缩解压

开发平台:

WINDOWS

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #ifdef unix
  8. # include <unistd.h>
  9. # include <utime.h>
  10. #else
  11. # include <direct.h>
  12. # include <io.h>
  13. #endif
  14. #include "unzip.h"
  15. #define CASESENSITIVITY (0)
  16. #define WRITEBUFFERSIZE (8192)
  17. /*
  18.   mini unzip, demo of unzip package
  19.   usage :
  20.   Usage : miniunz [-exvlo] file.zip [file_to_extract]
  21.   list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
  22.     if it exists
  23. */
  24. /* change_file_date : change the date/time of a file
  25.     filename : the filename of the file where date/time must be modified
  26.     dosdate : the new date at the MSDos format (4 bytes)
  27.     tmu_date : the SAME new date at the tm_unz format */
  28. void change_file_date(filename,dosdate,tmu_date)
  29. const char *filename;
  30. uLong dosdate;
  31. tm_unz tmu_date;
  32. {
  33. #ifdef WIN32
  34.   HANDLE hFile;
  35.   FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
  36.   hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE,
  37.                       0,NULL,OPEN_EXISTING,0,NULL);
  38.   GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
  39.   DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
  40.   LocalFileTimeToFileTime(&ftLocal,&ftm);
  41.   SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
  42.   CloseHandle(hFile);
  43. #else
  44. #ifdef unix
  45.   struct utimbuf ut;
  46.   struct tm newdate;
  47.   newdate.tm_sec = tmu_date.tm_sec;
  48.   newdate.tm_min=tmu_date.tm_min;
  49.   newdate.tm_hour=tmu_date.tm_hour;
  50.   newdate.tm_mday=tmu_date.tm_mday;
  51.   newdate.tm_mon=tmu_date.tm_mon;
  52.   if (tmu_date.tm_year > 1900)
  53.       newdate.tm_year=tmu_date.tm_year - 1900;
  54.   else
  55.       newdate.tm_year=tmu_date.tm_year ;
  56.   newdate.tm_isdst=-1;
  57.   ut.actime=ut.modtime=mktime(&newdate);
  58.   utime(filename,&ut);
  59. #endif
  60. #endif
  61. }
  62. /* mymkdir and change_file_date are not 100 % portable
  63.    As I don't know well Unix, I wait feedback for the unix portion */
  64. int mymkdir(dirname)
  65. const char* dirname;
  66. {
  67.     int ret=0;
  68. #ifdef WIN32
  69. ret = mkdir(dirname);
  70. #else
  71. #ifdef unix
  72. ret = mkdir (dirname,0775);
  73. #endif
  74. #endif
  75. return ret;
  76. }
  77. int makedir (newdir)
  78.     char *newdir;
  79. {
  80.   char *buffer ;
  81.   char *p;
  82.   int  len = strlen(newdir);  
  83.   if (len <= 0) 
  84.     return 0;
  85.   buffer = (char*)malloc(len+1);
  86.   strcpy(buffer,newdir);
  87.   
  88.   if (buffer[len-1] == '/') {
  89.     buffer[len-1] = '';
  90.   }
  91.   if (mymkdir(buffer) == 0)
  92.     {
  93.       free(buffer);
  94.       return 1;
  95.     }
  96.   p = buffer+1;
  97.   while (1)
  98.     {
  99.       char hold;
  100.       while(*p && *p != '\' && *p != '/')
  101.         p++;
  102.       hold = *p;
  103.       *p = 0;
  104.       if ((mymkdir(buffer) == -1) && (errno == ENOENT))
  105.         {
  106.           printf("couldn't create directory %sn",buffer);
  107.           free(buffer);
  108.           return 0;
  109.         }
  110.       if (hold == 0)
  111.         break;
  112.       *p++ = hold;
  113.     }
  114.   free(buffer);
  115.   return 1;
  116. }
  117. void do_banner()
  118. {
  119. printf("MiniUnz 0.15, demo of zLib + Unz package written by Gilles Vollantn");
  120. printf("more info at http://wwww.winimage/zLibDll/unzip.htmnn");
  121. }
  122. void do_help()
  123. {
  124. printf("Usage : miniunz [-exvlo] file.zip [file_to_extract]nn") ;
  125. }
  126. int do_list(uf)
  127. unzFile uf;
  128. {
  129. uLong i;
  130. unz_global_info gi;
  131. int err;
  132. err = unzGetGlobalInfo (uf,&gi);
  133. if (err!=UNZ_OK)
  134. printf("error %d with zipfile in unzGetGlobalInfo n",err);
  135.     printf(" Length  Method   Size  Ratio   Date    Time   CRC-32     Namen");
  136.     printf(" ------  ------   ----  -----   ----    ----   ------     ----n");
  137. for (i=0;i<gi.number_entry;i++)
  138. {
  139. char filename_inzip[256];
  140. unz_file_info file_info;
  141. uLong ratio=0;
  142. const char *string_method;
  143. err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
  144. if (err!=UNZ_OK)
  145. {
  146. printf("error %d with zipfile in unzGetCurrentFileInfon",err);
  147. break;
  148. }
  149. if (file_info.uncompressed_size>0)
  150. ratio = (file_info.compressed_size*100)/file_info.uncompressed_size;
  151. if (file_info.compression_method==0)
  152. string_method="Stored";
  153. else
  154. if (file_info.compression_method==Z_DEFLATED)
  155. {
  156. uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
  157. if (iLevel==0)
  158.   string_method="Defl:N";
  159. else if (iLevel==1)
  160.   string_method="Defl:X";
  161. else if ((iLevel==2) || (iLevel==3))
  162.   string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
  163. }
  164. else
  165. string_method="Unkn. ";
  166. printf("%7lu  %6s %7lu %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %sn",
  167.     file_info.uncompressed_size,string_method,file_info.compressed_size,
  168. ratio,
  169. (uLong)file_info.tmu_date.tm_mon + 1,
  170.                 (uLong)file_info.tmu_date.tm_mday,
  171. (uLong)file_info.tmu_date.tm_year % 100,
  172. (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
  173. (uLong)file_info.crc,filename_inzip);
  174. if ((i+1)<gi.number_entry)
  175. {
  176. err = unzGoToNextFile(uf);
  177. if (err!=UNZ_OK)
  178. {
  179. printf("error %d with zipfile in unzGoToNextFilen",err);
  180. break;
  181. }
  182. }
  183. }
  184. return 0;
  185. }
  186. int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite)
  187. unzFile uf;
  188. const int* popt_extract_without_path;
  189.     int* popt_overwrite;
  190. {
  191. char filename_inzip[256];
  192. char* filename_withoutpath;
  193. char* p;
  194.     int err=UNZ_OK;
  195.     FILE *fout=NULL;
  196.     void* buf;
  197.     uInt size_buf;
  198. unz_file_info file_info;
  199. uLong ratio=0;
  200. err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
  201. if (err!=UNZ_OK)
  202. {
  203. printf("error %d with zipfile in unzGetCurrentFileInfon",err);
  204. return err;
  205. }
  206.     size_buf = WRITEBUFFERSIZE;
  207.     buf = (void*)malloc(size_buf);
  208.     if (buf==NULL)
  209.     {
  210.         printf("Error allocating memoryn");
  211.         return UNZ_INTERNALERROR;
  212.     }
  213. p = filename_withoutpath = filename_inzip;
  214. while ((*p) != '')
  215. {
  216. if (((*p)=='/') || ((*p)=='\'))
  217. filename_withoutpath = p+1;
  218. p++;
  219. }
  220. if ((*filename_withoutpath)=='')
  221. {
  222. if ((*popt_extract_without_path)==0)
  223. {
  224. printf("creating directory: %sn",filename_inzip);
  225. mymkdir(filename_inzip);
  226. }
  227. }
  228. else
  229. {
  230. const char* write_filename;
  231. int skip=0;
  232. if ((*popt_extract_without_path)==0)
  233. write_filename = filename_inzip;
  234. else
  235. write_filename = filename_withoutpath;
  236. err = unzOpenCurrentFile(uf);
  237. if (err!=UNZ_OK)
  238. {
  239. printf("error %d with zipfile in unzOpenCurrentFilen",err);
  240. }
  241. if (((*popt_overwrite)==0) && (err==UNZ_OK))
  242. {
  243. char rep;
  244. FILE* ftestexist;
  245. ftestexist = fopen(write_filename,"rb");
  246. if (ftestexist!=NULL)
  247. {
  248. fclose(ftestexist);
  249. do
  250. {
  251. char answer[128];
  252. printf("The file %s exist. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
  253. scanf("%1s",answer);
  254. rep = answer[0] ;
  255. if ((rep>='a') && (rep<='z'))
  256. rep -= 0x20;
  257. }
  258. while ((rep!='Y') && (rep!='N') && (rep!='A'));
  259. }
  260. if (rep == 'N')
  261. skip = 1;
  262. if (rep == 'A')
  263. *popt_overwrite=1;
  264. }
  265. if ((skip==0) && (err==UNZ_OK))
  266. {
  267. fout=fopen(write_filename,"wb");
  268.             /* some zipfile don't contain directory alone before file */
  269.             if ((fout==NULL) && ((*popt_extract_without_path)==0) && 
  270.                                 (filename_withoutpath!=(char*)filename_inzip))
  271.             {
  272.                 char c=*(filename_withoutpath-1);
  273.                 *(filename_withoutpath-1)='';
  274.                 makedir(write_filename);
  275.                 *(filename_withoutpath-1)=c;
  276.                 fout=fopen(write_filename,"wb");
  277.             }
  278. if (fout==NULL)
  279. {
  280. printf("error opening %sn",write_filename);
  281. }
  282. }
  283. if (fout!=NULL)
  284. {
  285. printf(" extracting: %sn",write_filename);
  286. do
  287. {
  288. err = unzReadCurrentFile(uf,buf,size_buf);
  289. if (err<0)
  290. {
  291. printf("error %d with zipfile in unzReadCurrentFilen",err);
  292. break;
  293. }
  294. if (err>0)
  295. if (fwrite(buf,err,1,fout)!=1)
  296. {
  297. printf("error in writing extracted filen");
  298.                         err=UNZ_ERRNO;
  299. break;
  300. }
  301. }
  302. while (err>0);
  303. fclose(fout);
  304. if (err==0) 
  305. change_file_date(write_filename,file_info.dosDate,
  306.              file_info.tmu_date);
  307. }
  308.         if (err==UNZ_OK)
  309.         {
  310.     err = unzCloseCurrentFile (uf);
  311.     if (err!=UNZ_OK)
  312.     {
  313.     printf("error %d with zipfile in unzCloseCurrentFilen",err);
  314.     }
  315.         }
  316.         else
  317.             unzCloseCurrentFile(uf); /* don't lose the error */       
  318. }
  319.     free(buf);    
  320.     return err;
  321. }
  322. int do_extract(uf,opt_extract_without_path,opt_overwrite)
  323. unzFile uf;
  324. int opt_extract_without_path;
  325.     int opt_overwrite;
  326. {
  327. uLong i;
  328. unz_global_info gi;
  329. int err;
  330. FILE* fout=NULL;
  331. err = unzGetGlobalInfo (uf,&gi);
  332. if (err!=UNZ_OK)
  333. printf("error %d with zipfile in unzGetGlobalInfo n",err);
  334. for (i=0;i<gi.number_entry;i++)
  335. {
  336.         if (do_extract_currentfile(uf,&opt_extract_without_path,
  337.                                       &opt_overwrite) != UNZ_OK)
  338.             break;
  339. if ((i+1)<gi.number_entry)
  340. {
  341. err = unzGoToNextFile(uf);
  342. if (err!=UNZ_OK)
  343. {
  344. printf("error %d with zipfile in unzGoToNextFilen",err);
  345. break;
  346. }
  347. }
  348. }
  349. return 0;
  350. }
  351. int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite)
  352. unzFile uf;
  353. const char* filename;
  354. int opt_extract_without_path;
  355.     int opt_overwrite;
  356. {
  357.     int err = UNZ_OK;
  358.     if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
  359.     {
  360.         printf("file %s not found in the zipfilen",filename);
  361.         return 2;
  362.     }
  363.     if (do_extract_currentfile(uf,&opt_extract_without_path,
  364.                                       &opt_overwrite) == UNZ_OK)
  365.         return 0;
  366.     else
  367.         return 1;
  368. }
  369. int main(argc,argv)
  370. int argc;
  371. char *argv[];
  372. {
  373. const char *zipfilename=NULL;
  374.     const char *filename_to_extract=NULL;
  375. int i;
  376. int opt_do_list=0;
  377. int opt_do_extract=1;
  378. int opt_do_extract_withoutpath=0;
  379. int opt_overwrite=0;
  380. char filename_try[512];
  381. unzFile uf=NULL;
  382. do_banner();
  383. if (argc==1)
  384. {
  385. do_help();
  386. exit(0);
  387. }
  388. else
  389. {
  390. for (i=1;i<argc;i++)
  391. {
  392. if ((*argv[i])=='-')
  393. {
  394. const char *p=argv[i]+1;
  395. while ((*p)!='')
  396. {
  397. char c=*(p++);;
  398. if ((c=='l') || (c=='L'))
  399. opt_do_list = 1;
  400. if ((c=='v') || (c=='V'))
  401. opt_do_list = 1;
  402. if ((c=='x') || (c=='X'))
  403. opt_do_extract = 1;
  404. if ((c=='e') || (c=='E'))
  405. opt_do_extract = opt_do_extract_withoutpath = 1;
  406. if ((c=='o') || (c=='O'))
  407. opt_overwrite=1;
  408. }
  409. }
  410. else
  411.             {
  412. if (zipfilename == NULL)
  413. zipfilename = argv[i];
  414.                 else if (filename_to_extract==NULL)
  415.                         filename_to_extract = argv[i] ;
  416.             }
  417. }
  418. }
  419. if (zipfilename!=NULL)
  420. {
  421. strcpy(filename_try,zipfilename);
  422. uf = unzOpen(zipfilename);
  423. if (uf==NULL)
  424. {
  425. strcat(filename_try,".zip");
  426. uf = unzOpen(filename_try);
  427. }
  428. }
  429. if (uf==NULL)
  430. {
  431. printf("Cannot open %s or %s.zipn",zipfilename,zipfilename);
  432. exit (1);
  433. }
  434.     printf("%s openedn",filename_try);
  435. if (opt_do_list==1)
  436. return do_list(uf);
  437. else if (opt_do_extract==1)
  438.     {
  439.         if (filename_to_extract == NULL)
  440.     return do_extract(uf,opt_do_extract_withoutpath,opt_overwrite);
  441.         else
  442.             return do_extract_onefile(uf,filename_to_extract,
  443.                                       opt_do_extract_withoutpath,opt_overwrite);
  444.     }
  445. unzCloseCurrentFile(uf);
  446. return 0;  /* to avoid warning */
  447. }