beta-0.89.2
[luatex.git] / source / libs / zziplib / zziplib-0.13.62 / bins / unzip-mem.c
blob3f7d7f0631ec2a317f2637b13c42154a7a871183
1 /*
2 * Copyright (c) 2003 Guido Draheim <guidod@gmx.de>
3 * Use freely under the restrictions of the ZLIB license.
5 * This file is used as an example to clarify zzipmmap api usage.
6 */
8 #include <zlib.h> /* crc32 */
10 #include <zzip/memdisk.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
15 #ifdef ZZIP_HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
18 #ifdef ZZIP_HAVE_IO_H
19 #include <io.h>
20 #endif
22 #include <time.h>
24 #ifdef ZZIP_HAVE_FNMATCH_H
25 #include <fnmatch.h>
26 #else
27 #define fnmatch(x,y,z) strcmp(x,y)
28 #endif
30 #ifndef O_BINARY
31 #define O_BINARY 0
32 #endif
34 #define ___ {
35 #define ____ }
37 #define EXIT_SUCCESS 0
38 #define EXIT_WARNINGS 1
39 #define EXIT_ERRORS 2
40 #define EXIT_EFORMAT 3
41 #define EXIT_ENOMEM 4
42 #define EXIT_ENOTTY 5
43 #define EXIT_EINFLATE 6
44 #define EXIT_ENOARCH 9
45 #define EXIT_EOPTION 10
46 #define EXIT_ENOFILE 11
47 #define EXIT_EDISKFULL 50
48 #define EXIT_EPREMATURE 51
49 #define EXIT_USERABORT 80
50 #define EXIT_BADCOMPRESSION 81
51 #define EXIT_BADPASSWORD 82
53 static int status = EXIT_SUCCESS;
54 static int option_list = 0; /* "-l" */
55 static int option_pipe = 0; /* "-p" */
56 static int option_verbose = 0; /* "-v" */
57 static int option_testcrc = 0; /* "-t" */
58 static int option_binary = 0; /* "-b" */
59 static int option_nocase = 0; /* "-C" */
60 static int option_junkpaths = 0; /* "-j" */
61 static int option_dosfiles = 0; /* "-L" */
62 static int option_keepold = 0; /* "-n" */
63 static int option_overwrite = 0; /* "-o" */
64 static int option_quiet = 0; /* "-q" */
65 static int option_permbits = 0; /* "-X" */
67 static const char usage[] =
69 "unzzip-mem <zip> [names].. \n"
70 " - unzzip a zip archive.\n"
71 "options:\n"
72 " -l list archive files (name, usize, mtime, comments)\n" /* +totals */
73 " -p extract archive files to pipe, i.e. stdout (binary mode)\n"
74 " -t test archive files (check the crc values)\n"
75 " -v verbose list of archive files\n"
76 " -b accept and ignore (force binary extract)\n"
77 " -C match filenames case-insensitively\n"
78 " -j junk paths (do not recreate directory structure)\n"
79 " -L convert dos filenames to lowercase upon extract\n"
80 " -n never overwrite existing files\n"
81 " -o always overwrite existing files\n"
82 " -q quite operation\n"
83 " -X restore user/owner attributes of files\n"
86 static void zzip_mem_entry_pipe(ZZIP_MEM_DISK* disk,
87 ZZIP_MEM_ENTRY* entry, FILE* out)
89 ZZIP_DISK_FILE* file = zzip_mem_entry_fopen (disk, entry);
90 if (file)
92 char buffer[1024]; int len;
93 while ((len = zzip_mem_disk_fread (buffer, 1024, 1, file)))
94 fwrite (buffer, len, 1, out);
96 zzip_mem_disk_fclose (file);
100 static void zzip_mem_entry_make(ZZIP_MEM_DISK* disk,
101 ZZIP_MEM_ENTRY* entry)
103 FILE* file = fopen (entry->zz_name, "w");
104 if (file) { zzip_mem_entry_pipe (disk, entry, file); fclose (file); }
105 perror (entry->zz_name);
106 if (status < EXIT_WARNINGS) status = EXIT_WARNINGS;
109 /* ------------------------- test ------------------------------------ */
111 static char* archive = 0;
112 static int test_errors = 0;
114 static void zzip_mem_entry_test(ZZIP_MEM_DISK* disk,
115 ZZIP_MEM_ENTRY* entry)
117 ZZIP_DISK_FILE* file = zzip_mem_entry_fopen (disk, entry);
118 printf (" testing: %s ", entry->zz_name);
119 if (strlen (entry->zz_name) < 24) {
120 printf ("%.*s", 24 - (int) strlen (entry->zz_name),
121 " ");
123 if (file)
125 unsigned long crc = crc32 (0L, NULL, 0);
126 unsigned char buffer[1024]; int len;
127 while ((len = zzip_mem_disk_fread (buffer, 1024, 1, file))) {
128 crc = crc32 (crc, buffer, len);
131 zzip_mem_disk_fclose (file);
132 if (crc == (unsigned long) entry->zz_crc32) {
133 printf ("OK\n");
134 } else {
135 printf ("BAD %lx (should be %lx)\n", crc, entry->zz_crc32);
136 test_errors ++;
138 } else {
139 printf ("ERROR (no such file)\n");
140 test_errors ++;
144 static void zzip_mem_entry_test_start(void)
146 test_errors = 0;
147 printf ("Archive: %s\n", archive);
150 static void zzip_mem_entry_test_done(void)
152 if (test_errors == 0) {
153 printf ("No errors detected in compressed data of %s\n", archive);
154 } else {
155 printf ("%i errors detected in compressed data of %s\n",
156 test_errors, archive);
160 /* ------------------------- list ------------------------------------ */
162 static char _zzip_time_[30];
163 static char* _zzip_ctime (const time_t* timeval)
165 struct tm* date = localtime (timeval);
166 sprintf (_zzip_time_, "%02i-%02i-%02i %02i:%02i",
167 date->tm_mon, date->tm_mday, date->tm_year%100,
168 date->tm_hour, date->tm_min);
169 return _zzip_time_;
172 static const char* comprlevel[] = {
173 "stored", "shrunk", "redu:1", "redu:2", "redu:3", "redu:4",
174 "impl:N", "toknze", "defl:N", "defl:B", "impl:B" };
176 zzip_off_t sum_usize = 0;
177 zzip_off_t sum_csize = 0;
178 zzip_off_t sum_files = 0;
179 #define L (long)
181 static void zzip_mem_entry_direntry_start (void)
183 sum_usize = 0;
184 sum_csize = 0;
185 sum_files = 0;
186 if (option_verbose) goto verbose;
187 printf(" Length Date & Time Name\n");
188 printf(" -------- ---- ---- ----\n");
189 return;
190 verbose:
191 printf(" Length Method Size Ratio Date Time CRC-32 Name\n");
192 printf("-------- ------ ------- ----- ---- ---- ------ ----\n");
195 static void zzip_mem_entry_direntry_done (void)
197 char exp = ' ';
198 if (sum_usize / 1024 > 1024*1024*1024) { exp = 'G';
199 sum_usize /= 1024*1024*1024; sum_usize /= 1024*1024*1024; }
200 if (sum_usize > 1024*1024*1024) { exp = 'M';
201 sum_usize /= 1024*1024; sum_csize /= 1024*1024; }
202 if (sum_usize > 1024*1024) { exp = 'K';
203 sum_usize /= 1024; sum_csize /= 1024; }
204 if (option_verbose) goto verbose;
205 printf(" -------- ----\n");
206 printf(" %8li%c %8li %s\n", L sum_usize, exp, L sum_files,
207 sum_files == 1 ? "file" : "files");
208 return;
209 verbose:
210 printf("-------- ------ ------- ----- ----\n");
211 printf("%8li%c %8li%c %3li%% %8li %s\n",
212 L sum_usize, exp, L sum_csize, exp,
213 L (100 - (sum_csize*100/sum_usize)), L sum_files,
214 sum_files == 1 ? "file" : "files");
217 static void zzip_mem_entry_direntry(ZZIP_MEM_ENTRY* entry)
219 char* name = zzip_mem_entry_to_name (entry);
220 zzip_off_t usize = zzip_mem_entry_usize (entry);
221 zzip_off_t csize = zzip_mem_entry_csize (entry);
222 int compr = zzip_mem_entry_data_comprlevel (entry);
223 time_t mtime = entry->zz_mktime;
224 long crc32 = entry->zz_crc32;
225 const char* comment = zzip_mem_entry_to_comment (entry);
226 char exp = ' ';
228 sum_usize += usize;
229 sum_csize += csize;
230 sum_files += 1;
232 if (usize / 1024 > 1024*1024*1024) { exp = 'G';
233 usize /= 1024*1024*1024; usize /= 1024*1024*1024; }
234 if (usize > 1024*1024*1024) { exp = 'M';
235 usize /= 1024*1024; csize /= 1024*1024; }
236 if (usize > 1024*1024) { exp = 'K';
237 usize /= 1024; csize /= 1024; }
239 if (! comment) comment = "";
240 if (*name == '\n') name++;
242 if (option_verbose) {
243 printf("%8li%c %s %8li%c%3li%% %s %8lx %s %s\n",
244 L usize, exp, comprlevel[compr], L csize, exp,
245 L (100 - (csize*100/usize)),
246 _zzip_ctime(&mtime), crc32, name, comment);
247 } else {
248 printf(" %8li%c %s %s %s\n",
249 L usize, exp, _zzip_ctime(&mtime), name, comment);
253 static void zzip_mem_entry_listfiles(ZZIP_MEM_DISK* disk, char* filespec)
255 zzip_mem_entry_direntry_start ();
256 ___ ZZIP_MEM_ENTRY* entry = 0;
257 while ((entry = zzip_mem_disk_findmatch(disk, filespec, entry, 0, 0)))
258 zzip_mem_entry_direntry (entry); ____;
259 zzip_mem_entry_direntry_done ();
262 static void zzip_mem_entry_listall(ZZIP_MEM_DISK* disk)
264 zzip_mem_entry_direntry_start ();
265 ___ ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
266 for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
267 zzip_mem_entry_direntry (entry); ____;
268 zzip_mem_entry_direntry_done ();
271 static void zzip_mem_entry_testfiles(ZZIP_MEM_DISK* disk, char* filespec)
273 zzip_mem_entry_test_start ();
274 ___ ZZIP_MEM_ENTRY* entry = 0;
275 while ((entry = zzip_mem_disk_findmatch(disk, filespec, entry, 0, 0)))
276 zzip_mem_entry_test (disk, entry); ____;
277 zzip_mem_entry_test_done ();
280 static void zzip_mem_entry_testall(ZZIP_MEM_DISK* disk)
282 zzip_mem_entry_test_start ();
283 ___ ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
284 for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
285 zzip_mem_entry_test (disk, entry); ____;
286 zzip_mem_entry_test_done ();
289 static void zzip_mem_entry_pipefiles(ZZIP_MEM_DISK* disk, char* filespec)
291 ZZIP_MEM_ENTRY* entry = 0;
292 while ((entry = zzip_mem_disk_findmatch(disk, filespec, entry, 0, 0)))
293 zzip_mem_entry_pipe (disk, entry, stdout);
296 static void zzip_mem_entry_pipeall(ZZIP_MEM_DISK* disk)
298 ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
299 for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
300 zzip_mem_entry_pipe (disk, entry, stdout);
303 static void zzip_mem_entry_makefiles(ZZIP_MEM_DISK* disk, char* filespec)
305 ZZIP_MEM_ENTRY* entry = 0;
306 while ((entry = zzip_mem_disk_findmatch(disk, filespec, entry, 0, 0)))
307 zzip_mem_entry_make (disk, entry);
310 static void zzip_mem_entry_makeall(ZZIP_MEM_DISK* disk)
312 ZZIP_MEM_ENTRY* entry = zzip_mem_disk_findfirst(disk);
313 for (; entry ; entry = zzip_mem_disk_findnext(disk, entry))
314 zzip_mem_entry_make (disk, entry);
317 int
318 main (int argc, char ** argv)
320 int argn; int archname = 0; int filespec = 0;
321 ZZIP_MEM_DISK* disk;
322 if (argc <= 1 || ! strcmp (argv[1], "--help"))
324 printf (usage);
325 return 0;
327 if (! strcmp (argv[1], "--version"))
329 printf (__FILE__" version "ZZIP_PACKAGE" "ZZIP_VERSION"\n");
330 return 0;
333 for (argn=1; argn < argc; argn++) {
334 if ((argv[argn])[0] == '-') {
335 int x = 1;
336 while ((argv[argn])[x]) {
337 switch (argv[argn][x]) {
338 case 'l': option_list++; break;
339 case 'p': option_pipe++; break;
340 case 't': option_testcrc++; break;
341 case 'v': option_verbose++; break;
342 case 'b': option_binary++; break;
343 case 'C': option_nocase++; break;
344 case 'j': option_junkpaths++; break;
345 case 'L': option_dosfiles++; break;
346 case 'n': option_keepold++; break;
347 case 'o': option_overwrite++; break;
348 case 'q': option_quiet++; break;
349 case 'X': option_permbits++; break;
351 x++;
353 (argv[argn])[0] = 0;
354 } else {
355 if (! archname) { archname = argn; continue; }
356 if (! filespec) { filespec = argn; continue; }
360 if (! archname) {
361 printf (usage);
362 return 0;
363 } else archive = argv[archname];
365 disk = zzip_mem_disk_open (argv[archname]);
366 if (! disk) {
367 perror(argv[archname]);
368 return -1;
371 if (option_list || option_verbose) {
372 if (! filespec) {
373 zzip_mem_entry_listall (disk);
374 } else {
375 for (argn=filespec; argn < argc; argn++) {
376 if (argv[argn][0]) {
377 zzip_mem_entry_listfiles (disk, argv[argn]);
381 } else if (option_pipe) {
382 if (! filespec) {
383 zzip_mem_entry_pipeall (disk);
384 } else {
385 for (argn=filespec; argn < argc; argn++) {
386 if (argv[argn][0]) {
387 zzip_mem_entry_pipefiles (disk, argv[argn]);
391 } else if (option_testcrc) {
392 if (! filespec) {
393 zzip_mem_entry_testall (disk);
394 } else {
395 for (argn=filespec; argn < argc; argn++) {
396 if (argv[argn][0]) {
397 zzip_mem_entry_testfiles (disk, argv[argn]);
401 } else {
402 if (! filespec) {
403 zzip_mem_entry_makeall (disk);
404 } else {
405 for (argn=filespec; argn < argc; argn++) {
406 if (argv[argn][0]) {
407 zzip_mem_entry_makefiles (disk, argv[argn]);
413 return status;
417 * Local variables:
418 * c-file-style: "stroustrup"
419 * End: