libarchive-static 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. data/ext/Makefile +6 -0
  2. data/ext/extconf.rb +61 -0
  3. data/ext/libarchive-0.1.1/COPYING.libarchive +60 -0
  4. data/ext/libarchive-0.1.1/LICENSE.libbzip2 +42 -0
  5. data/ext/libarchive-0.1.1/README.txt +143 -0
  6. data/ext/libarchive-0.1.1/ext/Makefile.in +0 -0
  7. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +31 -0
  8. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.h +6 -0
  9. data/ext/libarchive-0.1.1/ext/archive_read_support_format.c +32 -0
  10. data/ext/libarchive-0.1.1/ext/archive_read_support_format.h +6 -0
  11. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +29 -0
  12. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.h +6 -0
  13. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +32 -0
  14. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.h +6 -0
  15. data/ext/libarchive-0.1.1/ext/config.h.in +22 -0
  16. data/ext/libarchive-0.1.1/ext/configure +3904 -0
  17. data/ext/libarchive-0.1.1/ext/configure.in +11 -0
  18. data/ext/libarchive-0.1.1/ext/depend +19 -0
  19. data/ext/libarchive-0.1.1/ext/extconf.rb +6 -0
  20. data/ext/libarchive-0.1.1/ext/install-sh +250 -0
  21. data/ext/libarchive-0.1.1/ext/libarchive.c +89 -0
  22. data/ext/libarchive-0.1.1/ext/libarchive_archive.c +84 -0
  23. data/ext/libarchive-0.1.1/ext/libarchive_entry.c +1015 -0
  24. data/ext/libarchive-0.1.1/ext/libarchive_internal.h +155 -0
  25. data/ext/libarchive-0.1.1/ext/libarchive_reader.c +328 -0
  26. data/ext/libarchive-0.1.1/ext/libarchive_win32.h +52 -0
  27. data/ext/libarchive-0.1.1/ext/libarchive_writer.c +246 -0
  28. data/ext/libarchive-0.1.1/libarchive.c +1762 -0
  29. data/ext/libarchive-2.8.4/Makefile.in +7076 -0
  30. data/ext/libarchive-2.8.4/build/autoconf/check_stdcall_func.m4 +51 -0
  31. data/ext/libarchive-2.8.4/build/autoconf/compile +143 -0
  32. data/ext/libarchive-2.8.4/build/autoconf/config.guess +1502 -0
  33. data/ext/libarchive-2.8.4/build/autoconf/config.sub +1708 -0
  34. data/ext/libarchive-2.8.4/build/autoconf/depcomp +630 -0
  35. data/ext/libarchive-2.8.4/build/autoconf/install-sh +291 -0
  36. data/ext/libarchive-2.8.4/build/autoconf/la_uid_t.m4 +20 -0
  37. data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +8406 -0
  38. data/ext/libarchive-2.8.4/build/autoconf/missing +376 -0
  39. data/ext/libarchive-2.8.4/build/pkgconfig/libarchive.pc.in +10 -0
  40. data/ext/libarchive-2.8.4/config.h.in +772 -0
  41. data/ext/libarchive-2.8.4/configure +17916 -0
  42. data/ext/libarchive-2.8.4/libarchive/archive.h +741 -0
  43. data/ext/libarchive-2.8.4/libarchive/archive_check_magic.c +134 -0
  44. data/ext/libarchive-2.8.4/libarchive/archive_crc32.h +66 -0
  45. data/ext/libarchive-2.8.4/libarchive/archive_endian.h +162 -0
  46. data/ext/libarchive-2.8.4/libarchive/archive_entry.c +2202 -0
  47. data/ext/libarchive-2.8.4/libarchive/archive_entry.h +524 -0
  48. data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_bhfi.c +74 -0
  49. data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_stat.c +77 -0
  50. data/ext/libarchive-2.8.4/libarchive/archive_entry_link_resolver.c +405 -0
  51. data/ext/libarchive-2.8.4/libarchive/archive_entry_private.h +184 -0
  52. data/ext/libarchive-2.8.4/libarchive/archive_entry_stat.c +118 -0
  53. data/ext/libarchive-2.8.4/libarchive/archive_entry_strmode.c +87 -0
  54. data/ext/libarchive-2.8.4/libarchive/archive_entry_xattr.c +158 -0
  55. data/ext/libarchive-2.8.4/libarchive/archive_hash.h +281 -0
  56. data/ext/libarchive-2.8.4/libarchive/archive_platform.h +165 -0
  57. data/ext/libarchive-2.8.4/libarchive/archive_private.h +124 -0
  58. data/ext/libarchive-2.8.4/libarchive/archive_read.c +1249 -0
  59. data/ext/libarchive-2.8.4/libarchive/archive_read_data_into_fd.c +93 -0
  60. data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +198 -0
  61. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +570 -0
  62. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_private.h +62 -0
  63. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_set_standard_lookup.c +303 -0
  64. data/ext/libarchive-2.8.4/libarchive/archive_read_extract.c +182 -0
  65. data/ext/libarchive-2.8.4/libarchive/archive_read_open_fd.c +190 -0
  66. data/ext/libarchive-2.8.4/libarchive/archive_read_open_file.c +165 -0
  67. data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +272 -0
  68. data/ext/libarchive-2.8.4/libarchive/archive_read_open_memory.c +156 -0
  69. data/ext/libarchive-2.8.4/libarchive/archive_read_private.h +199 -0
  70. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_all.c +60 -0
  71. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c +353 -0
  72. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c +444 -0
  73. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c +465 -0
  74. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_none.c +40 -0
  75. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_program.c +459 -0
  76. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c +287 -0
  77. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c +627 -0
  78. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c +708 -0
  79. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_all.c +43 -0
  80. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_ar.c +584 -0
  81. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +777 -0
  82. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_empty.c +93 -0
  83. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_iso9660.c +2830 -0
  84. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +1304 -0
  85. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_raw.c +185 -0
  86. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_tar.c +2418 -0
  87. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_xar.c +3151 -0
  88. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +903 -0
  89. data/ext/libarchive-2.8.4/libarchive/archive_string.c +453 -0
  90. data/ext/libarchive-2.8.4/libarchive/archive_string.h +148 -0
  91. data/ext/libarchive-2.8.4/libarchive/archive_string_sprintf.c +164 -0
  92. data/ext/libarchive-2.8.4/libarchive/archive_util.c +391 -0
  93. data/ext/libarchive-2.8.4/libarchive/archive_virtual.c +94 -0
  94. data/ext/libarchive-2.8.4/libarchive/archive_windows.c +1236 -0
  95. data/ext/libarchive-2.8.4/libarchive/archive_windows.h +347 -0
  96. data/ext/libarchive-2.8.4/libarchive/archive_write.c +466 -0
  97. data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +2628 -0
  98. data/ext/libarchive-2.8.4/libarchive/archive_write_disk_private.h +38 -0
  99. data/ext/libarchive-2.8.4/libarchive/archive_write_disk_set_standard_lookup.c +262 -0
  100. data/ext/libarchive-2.8.4/libarchive/archive_write_open_fd.c +141 -0
  101. data/ext/libarchive-2.8.4/libarchive/archive_write_open_file.c +105 -0
  102. data/ext/libarchive-2.8.4/libarchive/archive_write_open_filename.c +162 -0
  103. data/ext/libarchive-2.8.4/libarchive/archive_write_open_memory.c +126 -0
  104. data/ext/libarchive-2.8.4/libarchive/archive_write_private.h +122 -0
  105. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +408 -0
  106. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c +492 -0
  107. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +477 -0
  108. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +257 -0
  109. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +347 -0
  110. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +438 -0
  111. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format.c +72 -0
  112. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ar.c +550 -0
  113. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_by_name.c +76 -0
  114. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +344 -0
  115. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +295 -0
  116. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +1050 -0
  117. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_pax.c +1386 -0
  118. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_shar.c +626 -0
  119. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ustar.c +587 -0
  120. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +667 -0
  121. data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +154 -0
  122. data/ext/libarchive-2.8.4/libarchive/filter_fork.c +161 -0
  123. data/ext/libarchive-2.8.4/libarchive/filter_fork.h +41 -0
  124. data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +113 -0
  125. data/ext/libarchive-static-makefile +80 -0
  126. data/ext/libarchive-static-wrapper-makefile +22 -0
  127. data/ext/zlib-1.2.5/Makefile.in +257 -0
  128. data/ext/zlib-1.2.5/adler32.c +169 -0
  129. data/ext/zlib-1.2.5/compress.c +80 -0
  130. data/ext/zlib-1.2.5/configure +596 -0
  131. data/ext/zlib-1.2.5/crc32.c +442 -0
  132. data/ext/zlib-1.2.5/crc32.h +441 -0
  133. data/ext/zlib-1.2.5/deflate.c +1834 -0
  134. data/ext/zlib-1.2.5/deflate.h +342 -0
  135. data/ext/zlib-1.2.5/example.c +565 -0
  136. data/ext/zlib-1.2.5/gzclose.c +25 -0
  137. data/ext/zlib-1.2.5/gzguts.h +132 -0
  138. data/ext/zlib-1.2.5/gzlib.c +537 -0
  139. data/ext/zlib-1.2.5/gzread.c +653 -0
  140. data/ext/zlib-1.2.5/gzwrite.c +531 -0
  141. data/ext/zlib-1.2.5/infback.c +632 -0
  142. data/ext/zlib-1.2.5/inffast.c +340 -0
  143. data/ext/zlib-1.2.5/inffast.h +11 -0
  144. data/ext/zlib-1.2.5/inffixed.h +94 -0
  145. data/ext/zlib-1.2.5/inflate.c +1480 -0
  146. data/ext/zlib-1.2.5/inflate.h +122 -0
  147. data/ext/zlib-1.2.5/inftrees.c +330 -0
  148. data/ext/zlib-1.2.5/inftrees.h +62 -0
  149. data/ext/zlib-1.2.5/minigzip.c +440 -0
  150. data/ext/zlib-1.2.5/trees.c +1244 -0
  151. data/ext/zlib-1.2.5/trees.h +128 -0
  152. data/ext/zlib-1.2.5/uncompr.c +59 -0
  153. data/ext/zlib-1.2.5/zconf.h +428 -0
  154. data/ext/zlib-1.2.5/zlib.h +1613 -0
  155. data/ext/zlib-1.2.5/zutil.c +318 -0
  156. data/ext/zlib-1.2.5/zutil.h +274 -0
  157. metadata +211 -0
@@ -0,0 +1,903 @@
1
+ /*-
2
+ * Copyright (c) 2004 Tim Kientzle
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+ */
25
+
26
+ #include "archive_platform.h"
27
+ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102 2009-12-28 03:11:36Z kientzle $");
28
+
29
+ #ifdef HAVE_ERRNO_H
30
+ #include <errno.h>
31
+ #endif
32
+ #include <stdio.h>
33
+ #ifdef HAVE_STDLIB_H
34
+ #include <stdlib.h>
35
+ #endif
36
+ #include <time.h>
37
+ #ifdef HAVE_ZLIB_H
38
+ #include <zlib.h>
39
+ #endif
40
+
41
+ #include "archive.h"
42
+ #include "archive_entry.h"
43
+ #include "archive_private.h"
44
+ #include "archive_read_private.h"
45
+ #include "archive_endian.h"
46
+
47
+ #ifndef HAVE_ZLIB_H
48
+ #include "archive_crc32.h"
49
+ #endif
50
+
51
+ struct zip {
52
+ /* entry_bytes_remaining is the number of bytes we expect. */
53
+ int64_t entry_bytes_remaining;
54
+ int64_t entry_offset;
55
+
56
+ /* These count the number of bytes actually read for the entry. */
57
+ int64_t entry_compressed_bytes_read;
58
+ int64_t entry_uncompressed_bytes_read;
59
+
60
+ /* Running CRC32 of the decompressed data */
61
+ unsigned long entry_crc32;
62
+
63
+ unsigned version;
64
+ unsigned system;
65
+ unsigned flags;
66
+ unsigned compression;
67
+ const char * compression_name;
68
+ time_t mtime;
69
+ time_t ctime;
70
+ time_t atime;
71
+ mode_t mode;
72
+ uid_t uid;
73
+ gid_t gid;
74
+
75
+ /* Flags to mark progress of decompression. */
76
+ char decompress_init;
77
+ char end_of_entry;
78
+
79
+ unsigned long crc32;
80
+ ssize_t filename_length;
81
+ ssize_t extra_length;
82
+ int64_t uncompressed_size;
83
+ int64_t compressed_size;
84
+
85
+ unsigned char *uncompressed_buffer;
86
+ size_t uncompressed_buffer_size;
87
+ #ifdef HAVE_ZLIB_H
88
+ z_stream stream;
89
+ char stream_valid;
90
+ #endif
91
+
92
+ struct archive_string pathname;
93
+ struct archive_string extra;
94
+ char format_name[64];
95
+ };
96
+
97
+ #define ZIP_LENGTH_AT_END 8
98
+
99
+ struct zip_file_header {
100
+ char signature[4];
101
+ char version[2];
102
+ char flags[2];
103
+ char compression[2];
104
+ char timedate[4];
105
+ char crc32[4];
106
+ char compressed_size[4];
107
+ char uncompressed_size[4];
108
+ char filename_length[2];
109
+ char extra_length[2];
110
+ };
111
+
112
+ static const char *compression_names[] = {
113
+ "uncompressed",
114
+ "shrinking",
115
+ "reduced-1",
116
+ "reduced-2",
117
+ "reduced-3",
118
+ "reduced-4",
119
+ "imploded",
120
+ "reserved",
121
+ "deflation"
122
+ };
123
+
124
+ static int archive_read_format_zip_bid(struct archive_read *);
125
+ static int archive_read_format_zip_cleanup(struct archive_read *);
126
+ static int archive_read_format_zip_read_data(struct archive_read *,
127
+ const void **, size_t *, off_t *);
128
+ static int archive_read_format_zip_read_data_skip(struct archive_read *a);
129
+ static int archive_read_format_zip_read_header(struct archive_read *,
130
+ struct archive_entry *);
131
+ static int zip_read_data_deflate(struct archive_read *a, const void **buff,
132
+ size_t *size, off_t *offset);
133
+ static int zip_read_data_none(struct archive_read *a, const void **buff,
134
+ size_t *size, off_t *offset);
135
+ static int zip_read_file_header(struct archive_read *a,
136
+ struct archive_entry *entry, struct zip *zip);
137
+ static time_t zip_time(const char *);
138
+ static void process_extra(const void* extra, struct zip* zip);
139
+
140
+ int
141
+ archive_read_support_format_zip(struct archive *_a)
142
+ {
143
+ struct archive_read *a = (struct archive_read *)_a;
144
+ struct zip *zip;
145
+ int r;
146
+
147
+ zip = (struct zip *)malloc(sizeof(*zip));
148
+ if (zip == NULL) {
149
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data");
150
+ return (ARCHIVE_FATAL);
151
+ }
152
+ memset(zip, 0, sizeof(*zip));
153
+
154
+ r = __archive_read_register_format(a,
155
+ zip,
156
+ "zip",
157
+ archive_read_format_zip_bid,
158
+ NULL,
159
+ archive_read_format_zip_read_header,
160
+ archive_read_format_zip_read_data,
161
+ archive_read_format_zip_read_data_skip,
162
+ archive_read_format_zip_cleanup);
163
+
164
+ if (r != ARCHIVE_OK)
165
+ free(zip);
166
+ return (ARCHIVE_OK);
167
+ }
168
+
169
+
170
+ static int
171
+ archive_read_format_zip_bid(struct archive_read *a)
172
+ {
173
+ const char *p;
174
+ const void *buff;
175
+ ssize_t bytes_avail, offset;
176
+
177
+ if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
178
+ return (-1);
179
+
180
+ /*
181
+ * Bid of 30 here is: 16 bits for "PK",
182
+ * next 16-bit field has four options (-2 bits).
183
+ * 16 + 16-2 = 30.
184
+ */
185
+ if (p[0] == 'P' && p[1] == 'K') {
186
+ if ((p[2] == '\001' && p[3] == '\002')
187
+ || (p[2] == '\003' && p[3] == '\004')
188
+ || (p[2] == '\005' && p[3] == '\006')
189
+ || (p[2] == '\007' && p[3] == '\010')
190
+ || (p[2] == '0' && p[3] == '0'))
191
+ return (30);
192
+ }
193
+
194
+ /*
195
+ * Attempt to handle self-extracting archives
196
+ * by noting a PE header and searching forward
197
+ * up to 128k for a 'PK\003\004' marker.
198
+ */
199
+ if (p[0] == 'M' && p[1] == 'Z') {
200
+ /*
201
+ * TODO: Optimize by initializing 'offset' to an
202
+ * estimate of the likely start of the archive data
203
+ * based on values in the PE header. Note that we
204
+ * don't need to be exact, but we mustn't skip too
205
+ * far. The search below will compensate if we
206
+ * undershoot.
207
+ */
208
+ offset = 0;
209
+ while (offset < 124000) {
210
+ /* Get 4k of data beyond where we stopped. */
211
+ buff = __archive_read_ahead(a, offset + 4096,
212
+ &bytes_avail);
213
+ if (buff == NULL)
214
+ break;
215
+ p = (const char *)buff + offset;
216
+ while (p + 9 < (const char *)buff + bytes_avail) {
217
+ if (p[0] == 'P' && p[1] == 'K' /* signature */
218
+ && p[2] == 3 && p[3] == 4 /* File entry */
219
+ && p[8] == 8 /* compression == deflate */
220
+ && p[9] == 0 /* High byte of compression */
221
+ )
222
+ {
223
+ return (30);
224
+ }
225
+ ++p;
226
+ }
227
+ offset = p - (const char *)buff;
228
+ }
229
+ }
230
+
231
+ return (0);
232
+ }
233
+
234
+ /*
235
+ * Search forward for a "PK\003\004" file header. This handles the
236
+ * case of self-extracting archives, where there is an executable
237
+ * prepended to the ZIP archive.
238
+ */
239
+ static int
240
+ skip_sfx(struct archive_read *a)
241
+ {
242
+ const void *h;
243
+ const char *p, *q;
244
+ size_t skip;
245
+ ssize_t bytes;
246
+
247
+ /*
248
+ * TODO: We should be able to skip forward by a bunch
249
+ * by lifting some values from the PE header. We don't
250
+ * need to be exact (we're still going to search forward
251
+ * to find the header), but it will speed things up and
252
+ * reduce the chance of a false positive.
253
+ */
254
+ for (;;) {
255
+ h = __archive_read_ahead(a, 4, &bytes);
256
+ if (bytes < 4)
257
+ return (ARCHIVE_FATAL);
258
+ p = h;
259
+ q = p + bytes;
260
+
261
+ /*
262
+ * Scan ahead until we find something that looks
263
+ * like the zip header.
264
+ */
265
+ while (p + 4 < q) {
266
+ switch (p[3]) {
267
+ case '\004':
268
+ /* TODO: Additional verification here. */
269
+ if (memcmp("PK\003\004", p, 4) == 0) {
270
+ skip = p - (const char *)h;
271
+ __archive_read_consume(a, skip);
272
+ return (ARCHIVE_OK);
273
+ }
274
+ p += 4;
275
+ break;
276
+ case '\003': p += 1; break;
277
+ case 'K': p += 2; break;
278
+ case 'P': p += 3; break;
279
+ default: p += 4; break;
280
+ }
281
+ }
282
+ skip = p - (const char *)h;
283
+ __archive_read_consume(a, skip);
284
+ }
285
+ }
286
+
287
+ static int
288
+ archive_read_format_zip_read_header(struct archive_read *a,
289
+ struct archive_entry *entry)
290
+ {
291
+ const void *h;
292
+ const char *signature;
293
+ struct zip *zip;
294
+ int r = ARCHIVE_OK, r1;
295
+
296
+ a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
297
+ if (a->archive.archive_format_name == NULL)
298
+ a->archive.archive_format_name = "ZIP";
299
+
300
+ zip = (struct zip *)(a->format->data);
301
+ zip->decompress_init = 0;
302
+ zip->end_of_entry = 0;
303
+ zip->entry_uncompressed_bytes_read = 0;
304
+ zip->entry_compressed_bytes_read = 0;
305
+ zip->entry_crc32 = crc32(0, NULL, 0);
306
+ if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
307
+ return (ARCHIVE_FATAL);
308
+
309
+ signature = (const char *)h;
310
+ if (signature[0] == 'M' && signature[1] == 'Z') {
311
+ /* This is an executable? Must be self-extracting... */
312
+ r = skip_sfx(a);
313
+ if (r < ARCHIVE_WARN)
314
+ return (r);
315
+ if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
316
+ return (ARCHIVE_FATAL);
317
+ signature = (const char *)h;
318
+ }
319
+
320
+ if (signature[0] != 'P' || signature[1] != 'K') {
321
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
322
+ "Bad ZIP file");
323
+ return (ARCHIVE_FATAL);
324
+ }
325
+
326
+ /*
327
+ * "PK00" signature is used for "split" archives that
328
+ * only have a single segment. This means we can just
329
+ * skip the PK00; the first real file header should follow.
330
+ */
331
+ if (signature[2] == '0' && signature[3] == '0') {
332
+ __archive_read_consume(a, 4);
333
+ if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
334
+ return (ARCHIVE_FATAL);
335
+ signature = (const char *)h;
336
+ if (signature[0] != 'P' || signature[1] != 'K') {
337
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
338
+ "Bad ZIP file");
339
+ return (ARCHIVE_FATAL);
340
+ }
341
+ }
342
+
343
+ if (signature[2] == '\001' && signature[3] == '\002') {
344
+ /* Beginning of central directory. */
345
+ return (ARCHIVE_EOF);
346
+ }
347
+
348
+ if (signature[2] == '\003' && signature[3] == '\004') {
349
+ /* Regular file entry. */
350
+ r1 = zip_read_file_header(a, entry, zip);
351
+ if (r1 != ARCHIVE_OK)
352
+ return (r1);
353
+ return (r);
354
+ }
355
+
356
+ if (signature[2] == '\005' && signature[3] == '\006') {
357
+ /* End-of-archive record. */
358
+ return (ARCHIVE_EOF);
359
+ }
360
+
361
+ if (signature[2] == '\007' && signature[3] == '\010') {
362
+ /*
363
+ * We should never encounter this record here;
364
+ * see ZIP_LENGTH_AT_END handling below for details.
365
+ */
366
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
367
+ "Bad ZIP file: Unexpected end-of-entry record");
368
+ return (ARCHIVE_FATAL);
369
+ }
370
+
371
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
372
+ "Damaged ZIP file or unsupported format variant (%d,%d)",
373
+ signature[2], signature[3]);
374
+ return (ARCHIVE_FATAL);
375
+ }
376
+
377
+ static int
378
+ zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
379
+ struct zip *zip)
380
+ {
381
+ const struct zip_file_header *p;
382
+ const void *h;
383
+
384
+ if ((p = __archive_read_ahead(a, sizeof *p, NULL)) == NULL) {
385
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
386
+ "Truncated ZIP file header");
387
+ return (ARCHIVE_FATAL);
388
+ }
389
+
390
+ zip->version = p->version[0];
391
+ zip->system = p->version[1];
392
+ zip->flags = archive_le16dec(p->flags);
393
+ zip->compression = archive_le16dec(p->compression);
394
+ if (zip->compression <
395
+ sizeof(compression_names)/sizeof(compression_names[0]))
396
+ zip->compression_name = compression_names[zip->compression];
397
+ else
398
+ zip->compression_name = "??";
399
+ zip->mtime = zip_time(p->timedate);
400
+ zip->ctime = 0;
401
+ zip->atime = 0;
402
+ zip->mode = 0;
403
+ zip->uid = 0;
404
+ zip->gid = 0;
405
+ zip->crc32 = archive_le32dec(p->crc32);
406
+ zip->filename_length = archive_le16dec(p->filename_length);
407
+ zip->extra_length = archive_le16dec(p->extra_length);
408
+ zip->uncompressed_size = archive_le32dec(p->uncompressed_size);
409
+ zip->compressed_size = archive_le32dec(p->compressed_size);
410
+
411
+ __archive_read_consume(a, sizeof(struct zip_file_header));
412
+
413
+
414
+ /* Read the filename. */
415
+ if ((h = __archive_read_ahead(a, zip->filename_length, NULL)) == NULL) {
416
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
417
+ "Truncated ZIP file header");
418
+ return (ARCHIVE_FATAL);
419
+ }
420
+ if (archive_string_ensure(&zip->pathname, zip->filename_length) == NULL)
421
+ __archive_errx(1, "Out of memory");
422
+ archive_strncpy(&zip->pathname, h, zip->filename_length);
423
+ __archive_read_consume(a, zip->filename_length);
424
+ archive_entry_set_pathname(entry, zip->pathname.s);
425
+
426
+ if (zip->pathname.s[archive_strlen(&zip->pathname) - 1] == '/')
427
+ zip->mode = AE_IFDIR | 0777;
428
+ else
429
+ zip->mode = AE_IFREG | 0777;
430
+
431
+ /* Read the extra data. */
432
+ if ((h = __archive_read_ahead(a, zip->extra_length, NULL)) == NULL) {
433
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
434
+ "Truncated ZIP file header");
435
+ return (ARCHIVE_FATAL);
436
+ }
437
+ process_extra(h, zip);
438
+ __archive_read_consume(a, zip->extra_length);
439
+
440
+ /* Populate some additional entry fields: */
441
+ archive_entry_set_mode(entry, zip->mode);
442
+ archive_entry_set_uid(entry, zip->uid);
443
+ archive_entry_set_gid(entry, zip->gid);
444
+ archive_entry_set_mtime(entry, zip->mtime, 0);
445
+ archive_entry_set_ctime(entry, zip->ctime, 0);
446
+ archive_entry_set_atime(entry, zip->atime, 0);
447
+ /* Set the size only if it's meaningful. */
448
+ if (0 == (zip->flags & ZIP_LENGTH_AT_END))
449
+ archive_entry_set_size(entry, zip->uncompressed_size);
450
+
451
+ zip->entry_bytes_remaining = zip->compressed_size;
452
+ zip->entry_offset = 0;
453
+
454
+ /* If there's no body, force read_data() to return EOF immediately. */
455
+ if (0 == (zip->flags & ZIP_LENGTH_AT_END)
456
+ && zip->entry_bytes_remaining < 1)
457
+ zip->end_of_entry = 1;
458
+
459
+ /* Set up a more descriptive format name. */
460
+ sprintf(zip->format_name, "ZIP %d.%d (%s)",
461
+ zip->version / 10, zip->version % 10,
462
+ zip->compression_name);
463
+ a->archive.archive_format_name = zip->format_name;
464
+
465
+ return (ARCHIVE_OK);
466
+ }
467
+
468
+ /* Convert an MSDOS-style date/time into Unix-style time. */
469
+ static time_t
470
+ zip_time(const char *p)
471
+ {
472
+ int msTime, msDate;
473
+ struct tm ts;
474
+
475
+ msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]);
476
+ msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]);
477
+
478
+ memset(&ts, 0, sizeof(ts));
479
+ ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
480
+ ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
481
+ ts.tm_mday = msDate & 0x1f; /* Day of month. */
482
+ ts.tm_hour = (msTime >> 11) & 0x1f;
483
+ ts.tm_min = (msTime >> 5) & 0x3f;
484
+ ts.tm_sec = (msTime << 1) & 0x3e;
485
+ ts.tm_isdst = -1;
486
+ return mktime(&ts);
487
+ }
488
+
489
+ static int
490
+ archive_read_format_zip_read_data(struct archive_read *a,
491
+ const void **buff, size_t *size, off_t *offset)
492
+ {
493
+ int r;
494
+ struct zip *zip;
495
+
496
+ zip = (struct zip *)(a->format->data);
497
+
498
+ /*
499
+ * If we hit end-of-entry last time, clean up and return
500
+ * ARCHIVE_EOF this time.
501
+ */
502
+ if (zip->end_of_entry) {
503
+ *offset = zip->entry_uncompressed_bytes_read;
504
+ *size = 0;
505
+ *buff = NULL;
506
+ return (ARCHIVE_EOF);
507
+ }
508
+
509
+ switch(zip->compression) {
510
+ case 0: /* No compression. */
511
+ r = zip_read_data_none(a, buff, size, offset);
512
+ break;
513
+ case 8: /* Deflate compression. */
514
+ r = zip_read_data_deflate(a, buff, size, offset);
515
+ break;
516
+ default: /* Unsupported compression. */
517
+ *buff = NULL;
518
+ *size = 0;
519
+ *offset = 0;
520
+ /* Return a warning. */
521
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
522
+ "Unsupported ZIP compression method (%s)",
523
+ zip->compression_name);
524
+ if (zip->flags & ZIP_LENGTH_AT_END) {
525
+ /*
526
+ * ZIP_LENGTH_AT_END requires us to
527
+ * decompress the entry in order to
528
+ * skip it, but we don't know this
529
+ * compression method, so we give up.
530
+ */
531
+ r = ARCHIVE_FATAL;
532
+ } else {
533
+ /* We can't decompress this entry, but we will
534
+ * be able to skip() it and try the next entry. */
535
+ r = ARCHIVE_WARN;
536
+ }
537
+ break;
538
+ }
539
+ if (r != ARCHIVE_OK)
540
+ return (r);
541
+ /* Update checksum */
542
+ if (*size)
543
+ zip->entry_crc32 = crc32(zip->entry_crc32, *buff, *size);
544
+ /* If we hit the end, swallow any end-of-data marker. */
545
+ if (zip->end_of_entry) {
546
+ if (zip->flags & ZIP_LENGTH_AT_END) {
547
+ const char *p;
548
+
549
+ if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) {
550
+ archive_set_error(&a->archive,
551
+ ARCHIVE_ERRNO_FILE_FORMAT,
552
+ "Truncated ZIP end-of-file record");
553
+ return (ARCHIVE_FATAL);
554
+ }
555
+ zip->crc32 = archive_le32dec(p + 4);
556
+ zip->compressed_size = archive_le32dec(p + 8);
557
+ zip->uncompressed_size = archive_le32dec(p + 12);
558
+ __archive_read_consume(a, 16);
559
+ }
560
+ /* Check file size, CRC against these values. */
561
+ if (zip->compressed_size != zip->entry_compressed_bytes_read) {
562
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
563
+ "ZIP compressed data is wrong size");
564
+ return (ARCHIVE_WARN);
565
+ }
566
+ /* Size field only stores the lower 32 bits of the actual size. */
567
+ if ((zip->uncompressed_size & UINT32_MAX)
568
+ != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
569
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
570
+ "ZIP uncompressed data is wrong size");
571
+ return (ARCHIVE_WARN);
572
+ }
573
+ /* Check computed CRC against header */
574
+ if (zip->crc32 != zip->entry_crc32) {
575
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
576
+ "ZIP bad CRC: 0x%lx should be 0x%lx",
577
+ zip->entry_crc32, zip->crc32);
578
+ return (ARCHIVE_WARN);
579
+ }
580
+ }
581
+
582
+ /* Return EOF immediately if this is a non-regular file. */
583
+ if (AE_IFREG != (zip->mode & AE_IFMT))
584
+ return (ARCHIVE_EOF);
585
+ return (ARCHIVE_OK);
586
+ }
587
+
588
+ /*
589
+ * Read "uncompressed" data. According to the current specification,
590
+ * if ZIP_LENGTH_AT_END is specified, then the size fields in the
591
+ * initial file header are supposed to be set to zero. This would, of
592
+ * course, make it impossible for us to read the archive, since we
593
+ * couldn't determine the end of the file data. Info-ZIP seems to
594
+ * include the real size fields both before and after the data in this
595
+ * case (the CRC only appears afterwards), so this works as you would
596
+ * expect.
597
+ *
598
+ * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
599
+ * zip->end_of_entry if it consumes all of the data.
600
+ */
601
+ static int
602
+ zip_read_data_none(struct archive_read *a, const void **buff,
603
+ size_t *size, off_t *offset)
604
+ {
605
+ struct zip *zip;
606
+ ssize_t bytes_avail;
607
+
608
+ zip = (struct zip *)(a->format->data);
609
+
610
+ if (zip->entry_bytes_remaining == 0) {
611
+ *buff = NULL;
612
+ *size = 0;
613
+ *offset = zip->entry_offset;
614
+ zip->end_of_entry = 1;
615
+ return (ARCHIVE_OK);
616
+ }
617
+ /*
618
+ * Note: '1' here is a performance optimization.
619
+ * Recall that the decompression layer returns a count of
620
+ * available bytes; asking for more than that forces the
621
+ * decompressor to combine reads by copying data.
622
+ */
623
+ *buff = __archive_read_ahead(a, 1, &bytes_avail);
624
+ if (bytes_avail <= 0) {
625
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
626
+ "Truncated ZIP file data");
627
+ return (ARCHIVE_FATAL);
628
+ }
629
+ if (bytes_avail > zip->entry_bytes_remaining)
630
+ bytes_avail = zip->entry_bytes_remaining;
631
+ __archive_read_consume(a, bytes_avail);
632
+ *size = bytes_avail;
633
+ *offset = zip->entry_offset;
634
+ zip->entry_offset += *size;
635
+ zip->entry_bytes_remaining -= *size;
636
+ zip->entry_uncompressed_bytes_read += *size;
637
+ zip->entry_compressed_bytes_read += *size;
638
+ return (ARCHIVE_OK);
639
+ }
640
+
641
+ #ifdef HAVE_ZLIB_H
642
+ static int
643
+ zip_read_data_deflate(struct archive_read *a, const void **buff,
644
+ size_t *size, off_t *offset)
645
+ {
646
+ struct zip *zip;
647
+ ssize_t bytes_avail;
648
+ const void *compressed_buff;
649
+ int r;
650
+
651
+ zip = (struct zip *)(a->format->data);
652
+
653
+ /* If the buffer hasn't been allocated, allocate it now. */
654
+ if (zip->uncompressed_buffer == NULL) {
655
+ zip->uncompressed_buffer_size = 32 * 1024;
656
+ zip->uncompressed_buffer
657
+ = (unsigned char *)malloc(zip->uncompressed_buffer_size);
658
+ if (zip->uncompressed_buffer == NULL) {
659
+ archive_set_error(&a->archive, ENOMEM,
660
+ "No memory for ZIP decompression");
661
+ return (ARCHIVE_FATAL);
662
+ }
663
+ }
664
+
665
+ /* If we haven't yet read any data, initialize the decompressor. */
666
+ if (!zip->decompress_init) {
667
+ if (zip->stream_valid)
668
+ r = inflateReset(&zip->stream);
669
+ else
670
+ r = inflateInit2(&zip->stream,
671
+ -15 /* Don't check for zlib header */);
672
+ if (r != Z_OK) {
673
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
674
+ "Can't initialize ZIP decompression.");
675
+ return (ARCHIVE_FATAL);
676
+ }
677
+ /* Stream structure has been set up. */
678
+ zip->stream_valid = 1;
679
+ /* We've initialized decompression for this stream. */
680
+ zip->decompress_init = 1;
681
+ }
682
+
683
+ /*
684
+ * Note: '1' here is a performance optimization.
685
+ * Recall that the decompression layer returns a count of
686
+ * available bytes; asking for more than that forces the
687
+ * decompressor to combine reads by copying data.
688
+ */
689
+ compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
690
+ if (bytes_avail <= 0) {
691
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
692
+ "Truncated ZIP file body");
693
+ return (ARCHIVE_FATAL);
694
+ }
695
+
696
+ /*
697
+ * A bug in zlib.h: stream.next_in should be marked 'const'
698
+ * but isn't (the library never alters data through the
699
+ * next_in pointer, only reads it). The result: this ugly
700
+ * cast to remove 'const'.
701
+ */
702
+ zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff;
703
+ zip->stream.avail_in = bytes_avail;
704
+ zip->stream.total_in = 0;
705
+ zip->stream.next_out = zip->uncompressed_buffer;
706
+ zip->stream.avail_out = zip->uncompressed_buffer_size;
707
+ zip->stream.total_out = 0;
708
+
709
+ r = inflate(&zip->stream, 0);
710
+ switch (r) {
711
+ case Z_OK:
712
+ break;
713
+ case Z_STREAM_END:
714
+ zip->end_of_entry = 1;
715
+ break;
716
+ case Z_MEM_ERROR:
717
+ archive_set_error(&a->archive, ENOMEM,
718
+ "Out of memory for ZIP decompression");
719
+ return (ARCHIVE_FATAL);
720
+ default:
721
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
722
+ "ZIP decompression failed (%d)", r);
723
+ return (ARCHIVE_FATAL);
724
+ }
725
+
726
+ /* Consume as much as the compressor actually used. */
727
+ bytes_avail = zip->stream.total_in;
728
+ __archive_read_consume(a, bytes_avail);
729
+ zip->entry_bytes_remaining -= bytes_avail;
730
+ zip->entry_compressed_bytes_read += bytes_avail;
731
+
732
+ *offset = zip->entry_offset;
733
+ *size = zip->stream.total_out;
734
+ zip->entry_uncompressed_bytes_read += *size;
735
+ *buff = zip->uncompressed_buffer;
736
+ zip->entry_offset += *size;
737
+ return (ARCHIVE_OK);
738
+ }
739
+ #else
740
+ static int
741
+ zip_read_data_deflate(struct archive_read *a, const void **buff,
742
+ size_t *size, off_t *offset)
743
+ {
744
+ *buff = NULL;
745
+ *size = 0;
746
+ *offset = 0;
747
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
748
+ "libarchive compiled without deflate support (no libz)");
749
+ return (ARCHIVE_FATAL);
750
+ }
751
+ #endif
752
+
753
+ static int
754
+ archive_read_format_zip_read_data_skip(struct archive_read *a)
755
+ {
756
+ struct zip *zip;
757
+ const void *buff = NULL;
758
+ off_t bytes_skipped;
759
+
760
+ zip = (struct zip *)(a->format->data);
761
+
762
+ /* If we've already read to end of data, we're done. */
763
+ if (zip->end_of_entry)
764
+ return (ARCHIVE_OK);
765
+
766
+ /*
767
+ * If the length is at the end, we have no choice but
768
+ * to decompress all the data to find the end marker.
769
+ */
770
+ if (zip->flags & ZIP_LENGTH_AT_END) {
771
+ size_t size;
772
+ off_t offset;
773
+ int r;
774
+ do {
775
+ r = archive_read_format_zip_read_data(a, &buff,
776
+ &size, &offset);
777
+ } while (r == ARCHIVE_OK);
778
+ return (r);
779
+ }
780
+
781
+ /*
782
+ * If the length is at the beginning, we can skip the
783
+ * compressed data much more quickly.
784
+ */
785
+ bytes_skipped = __archive_read_skip(a, zip->entry_bytes_remaining);
786
+ if (bytes_skipped < 0)
787
+ return (ARCHIVE_FATAL);
788
+
789
+ /* This entry is finished and done. */
790
+ zip->end_of_entry = 1;
791
+ return (ARCHIVE_OK);
792
+ }
793
+
794
+ static int
795
+ archive_read_format_zip_cleanup(struct archive_read *a)
796
+ {
797
+ struct zip *zip;
798
+
799
+ zip = (struct zip *)(a->format->data);
800
+ #ifdef HAVE_ZLIB_H
801
+ if (zip->stream_valid)
802
+ inflateEnd(&zip->stream);
803
+ #endif
804
+ free(zip->uncompressed_buffer);
805
+ archive_string_free(&(zip->pathname));
806
+ archive_string_free(&(zip->extra));
807
+ free(zip);
808
+ (a->format->data) = NULL;
809
+ return (ARCHIVE_OK);
810
+ }
811
+
812
+ /*
813
+ * The extra data is stored as a list of
814
+ * id1+size1+data1 + id2+size2+data2 ...
815
+ * triplets. id and size are 2 bytes each.
816
+ */
817
+ static void
818
+ process_extra(const void* extra, struct zip* zip)
819
+ {
820
+ int offset = 0;
821
+ const char *p = (const char *)extra;
822
+ while (offset < zip->extra_length - 4)
823
+ {
824
+ unsigned short headerid = archive_le16dec(p + offset);
825
+ unsigned short datasize = archive_le16dec(p + offset + 2);
826
+ offset += 4;
827
+ if (offset + datasize > zip->extra_length)
828
+ break;
829
+ #ifdef DEBUG
830
+ fprintf(stderr, "Header id 0x%04x, length %d\n",
831
+ headerid, datasize);
832
+ #endif
833
+ switch (headerid) {
834
+ case 0x0001:
835
+ /* Zip64 extended information extra field. */
836
+ if (datasize >= 8)
837
+ zip->uncompressed_size = archive_le64dec(p + offset);
838
+ if (datasize >= 16)
839
+ zip->compressed_size = archive_le64dec(p + offset + 8);
840
+ break;
841
+ case 0x5455:
842
+ {
843
+ /* Extended time field "UT". */
844
+ int flags = p[offset];
845
+ offset++;
846
+ datasize--;
847
+ /* Flag bits indicate which dates are present. */
848
+ if (flags & 0x01)
849
+ {
850
+ #ifdef DEBUG
851
+ fprintf(stderr, "mtime: %lld -> %d\n",
852
+ (long long)zip->mtime,
853
+ archive_le32dec(p + offset));
854
+ #endif
855
+ if (datasize < 4)
856
+ break;
857
+ zip->mtime = archive_le32dec(p + offset);
858
+ offset += 4;
859
+ datasize -= 4;
860
+ }
861
+ if (flags & 0x02)
862
+ {
863
+ if (datasize < 4)
864
+ break;
865
+ zip->atime = archive_le32dec(p + offset);
866
+ offset += 4;
867
+ datasize -= 4;
868
+ }
869
+ if (flags & 0x04)
870
+ {
871
+ if (datasize < 4)
872
+ break;
873
+ zip->ctime = archive_le32dec(p + offset);
874
+ offset += 4;
875
+ datasize -= 4;
876
+ }
877
+ break;
878
+ }
879
+ case 0x7855:
880
+ /* Info-ZIP Unix Extra Field (type 2) "Ux". */
881
+ #ifdef DEBUG
882
+ fprintf(stderr, "uid %d gid %d\n",
883
+ archive_le16dec(p + offset),
884
+ archive_le16dec(p + offset + 2));
885
+ #endif
886
+ if (datasize >= 2)
887
+ zip->uid = archive_le16dec(p + offset);
888
+ if (datasize >= 4)
889
+ zip->gid = archive_le16dec(p + offset + 2);
890
+ break;
891
+ default:
892
+ break;
893
+ }
894
+ offset += datasize;
895
+ }
896
+ #ifdef DEBUG
897
+ if (offset != zip->extra_length)
898
+ {
899
+ fprintf(stderr,
900
+ "Extra data field contents do not match reported size!");
901
+ }
902
+ #endif
903
+ }