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,667 @@
1
+ /*-
2
+ * Copyright (c) 2008 Anselm Strauss
3
+ * Copyright (c) 2009 Joerg Sonnenberger
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ */
26
+
27
+ /*
28
+ * Development supported by Google Summer of Code 2008.
29
+ */
30
+
31
+ /*
32
+ * The current implementation is very limited:
33
+ *
34
+ * - No encryption support.
35
+ * - No ZIP64 support.
36
+ * - No support for splitting and spanning.
37
+ * - Only supports regular file and folder entries.
38
+ *
39
+ * Note that generally data in ZIP files is little-endian encoded,
40
+ * with some exceptions.
41
+ *
42
+ * TODO: Since Libarchive is generally 64bit oriented, but this implementation
43
+ * does not yet support sizes exceeding 32bit, it is highly fragile for
44
+ * big archives. This should change when ZIP64 is finally implemented, otherwise
45
+ * some serious checking has to be done.
46
+ *
47
+ */
48
+
49
+ #include "archive_platform.h"
50
+ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_zip.c 201168 2009-12-29 06:15:32Z kientzle $");
51
+
52
+ #ifdef HAVE_ERRNO_H
53
+ #include <errno.h>
54
+ #endif
55
+ #include <stdio.h>
56
+ #ifdef HAVE_STDLIB_H
57
+ #include <stdlib.h>
58
+ #endif
59
+ #ifdef HAVE_STRING_H
60
+ #include <string.h>
61
+ #endif
62
+ #ifdef HAVE_ZLIB_H
63
+ #include <zlib.h>
64
+ #endif
65
+
66
+ #include "archive.h"
67
+ #include "archive_endian.h"
68
+ #include "archive_entry.h"
69
+ #include "archive_private.h"
70
+ #include "archive_write_private.h"
71
+
72
+ #ifndef HAVE_ZLIB_H
73
+ #include "archive_crc32.h"
74
+ #endif
75
+
76
+ #define ZIP_SIGNATURE_LOCAL_FILE_HEADER 0x04034b50
77
+ #define ZIP_SIGNATURE_DATA_DESCRIPTOR 0x08074b50
78
+ #define ZIP_SIGNATURE_FILE_HEADER 0x02014b50
79
+ #define ZIP_SIGNATURE_CENTRAL_DIRECTORY_END 0x06054b50
80
+ #define ZIP_SIGNATURE_EXTRA_TIMESTAMP 0x5455
81
+ #define ZIP_SIGNATURE_EXTRA_UNIX 0x7855
82
+ #define ZIP_VERSION_EXTRACT 0x0014 /* ZIP version 2.0 is needed. */
83
+ #define ZIP_VERSION_BY 0x0314 /* Made by UNIX, using ZIP version 2.0. */
84
+ #define ZIP_FLAGS 0x08 /* Flagging bit 3 (count from 0) for using data descriptor. */
85
+
86
+ enum compression {
87
+ COMPRESSION_STORE = 0
88
+ #ifdef HAVE_ZLIB_H
89
+ ,
90
+ COMPRESSION_DEFLATE = 8
91
+ #endif
92
+ };
93
+
94
+ static ssize_t archive_write_zip_data(struct archive_write *, const void *buff, size_t s);
95
+ static int archive_write_zip_finish(struct archive_write *);
96
+ static int archive_write_zip_destroy(struct archive_write *);
97
+ static int archive_write_zip_finish_entry(struct archive_write *);
98
+ static int archive_write_zip_header(struct archive_write *, struct archive_entry *);
99
+ static unsigned int dos_time(const time_t);
100
+ static size_t path_length(struct archive_entry *);
101
+ static int write_path(struct archive_entry *, struct archive_write *);
102
+
103
+ struct zip_local_file_header {
104
+ char signature[4];
105
+ char version[2];
106
+ char flags[2];
107
+ char compression[2];
108
+ char timedate[4];
109
+ char crc32[4];
110
+ char compressed_size[4];
111
+ char uncompressed_size[4];
112
+ char filename_length[2];
113
+ char extra_length[2];
114
+ };
115
+
116
+ struct zip_file_header {
117
+ char signature[4];
118
+ char version_by[2];
119
+ char version_extract[2];
120
+ char flags[2];
121
+ char compression[2];
122
+ char timedate[4];
123
+ char crc32[4];
124
+ char compressed_size[4];
125
+ char uncompressed_size[4];
126
+ char filename_length[2];
127
+ char extra_length[2];
128
+ char comment_length[2];
129
+ char disk_number[2];
130
+ char attributes_internal[2];
131
+ char attributes_external[4];
132
+ char offset[4];
133
+ };
134
+
135
+ struct zip_data_descriptor {
136
+ char signature[4]; /* Not mandatory, but recommended by specification. */
137
+ char crc32[4];
138
+ char compressed_size[4];
139
+ char uncompressed_size[4];
140
+ };
141
+
142
+ struct zip_extra_data_local {
143
+ char time_id[2];
144
+ char time_size[2];
145
+ char time_flag[1];
146
+ char mtime[4];
147
+ char atime[4];
148
+ char ctime[4];
149
+ char unix_id[2];
150
+ char unix_size[2];
151
+ char unix_uid[2];
152
+ char unix_gid[2];
153
+ };
154
+
155
+ struct zip_extra_data_central {
156
+ char time_id[2];
157
+ char time_size[2];
158
+ char time_flag[1];
159
+ char mtime[4];
160
+ char unix_id[2];
161
+ char unix_size[2];
162
+ };
163
+
164
+ struct zip_file_header_link {
165
+ struct zip_file_header_link *next;
166
+ struct archive_entry *entry;
167
+ off_t offset;
168
+ unsigned long crc32;
169
+ off_t compressed_size;
170
+ enum compression compression;
171
+ };
172
+
173
+ struct zip {
174
+ struct zip_data_descriptor data_descriptor;
175
+ struct zip_file_header_link *central_directory;
176
+ struct zip_file_header_link *central_directory_end;
177
+ int64_t offset;
178
+ int64_t written_bytes;
179
+ int64_t remaining_data_bytes;
180
+ enum compression compression;
181
+
182
+ #ifdef HAVE_ZLIB_H
183
+ z_stream stream;
184
+ size_t len_buf;
185
+ unsigned char *buf;
186
+ #endif
187
+ };
188
+
189
+ struct zip_central_directory_end {
190
+ char signature[4];
191
+ char disk[2];
192
+ char start_disk[2];
193
+ char entries_disk[2];
194
+ char entries[2];
195
+ char size[4];
196
+ char offset[4];
197
+ char comment_length[2];
198
+ };
199
+
200
+ static int
201
+ archive_write_zip_options(struct archive_write *a, const char *key,
202
+ const char *value)
203
+ {
204
+ struct zip *zip = a->format_data;
205
+
206
+ if (strcmp(key, "compression") == 0) {
207
+ if (strcmp(value, "deflate") == 0) {
208
+ #ifdef HAVE_ZLIB_H
209
+ zip->compression = COMPRESSION_DEFLATE;
210
+ #else
211
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
212
+ "deflate compression not supported");
213
+ return ARCHIVE_WARN;
214
+ #endif
215
+ } else if (strcmp(value, "store") == 0)
216
+ zip->compression = COMPRESSION_STORE;
217
+ else
218
+ return (ARCHIVE_WARN);
219
+ return (ARCHIVE_OK);
220
+ }
221
+ return (ARCHIVE_WARN);
222
+ }
223
+
224
+ int
225
+ archive_write_set_format_zip(struct archive *_a)
226
+ {
227
+ struct archive_write *a = (struct archive_write *)_a;
228
+ struct zip *zip;
229
+
230
+ /* If another format was already registered, unregister it. */
231
+ if (a->format_destroy != NULL)
232
+ (a->format_destroy)(a);
233
+
234
+ zip = (struct zip *) calloc(1, sizeof(*zip));
235
+ if (zip == NULL) {
236
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data");
237
+ return (ARCHIVE_FATAL);
238
+ }
239
+ zip->central_directory = NULL;
240
+ zip->central_directory_end = NULL;
241
+ zip->offset = 0;
242
+ zip->written_bytes = 0;
243
+ zip->remaining_data_bytes = 0;
244
+
245
+ #ifdef HAVE_ZLIB_H
246
+ zip->compression = COMPRESSION_DEFLATE;
247
+ zip->len_buf = 65536;
248
+ zip->buf = malloc(zip->len_buf);
249
+ if (zip->buf == NULL) {
250
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate compression buffer");
251
+ return (ARCHIVE_FATAL);
252
+ }
253
+ #else
254
+ zip->compression = COMPRESSION_STORE;
255
+ #endif
256
+
257
+ a->format_data = zip;
258
+
259
+ a->pad_uncompressed = 0; /* Actually not needed for now, since no compression support yet. */
260
+ a->format_name = "zip";
261
+ a->format_options = archive_write_zip_options;
262
+ a->format_write_header = archive_write_zip_header;
263
+ a->format_write_data = archive_write_zip_data;
264
+ a->format_finish_entry = archive_write_zip_finish_entry;
265
+ a->format_finish = archive_write_zip_finish;
266
+ a->format_destroy = archive_write_zip_destroy;
267
+ a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
268
+ a->archive.archive_format_name = "ZIP";
269
+
270
+ archive_le32enc(&zip->data_descriptor.signature,
271
+ ZIP_SIGNATURE_DATA_DESCRIPTOR);
272
+
273
+ return (ARCHIVE_OK);
274
+ }
275
+
276
+ static int
277
+ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
278
+ {
279
+ struct zip *zip;
280
+ struct zip_local_file_header h;
281
+ struct zip_extra_data_local e;
282
+ struct zip_data_descriptor *d;
283
+ struct zip_file_header_link *l;
284
+ int ret;
285
+ int64_t size;
286
+ mode_t type;
287
+
288
+ /* Entries other than a regular file or a folder are skipped. */
289
+ type = archive_entry_filetype(entry);
290
+ if ((type != AE_IFREG) & (type != AE_IFDIR)) {
291
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Filetype not supported");
292
+ return ARCHIVE_FAILED;
293
+ };
294
+
295
+ /* Directory entries should have a size of 0. */
296
+ if (type == AE_IFDIR)
297
+ archive_entry_set_size(entry, 0);
298
+
299
+ zip = a->format_data;
300
+ d = &zip->data_descriptor;
301
+ size = archive_entry_size(entry);
302
+ zip->remaining_data_bytes = size;
303
+
304
+ /* Append archive entry to the central directory data. */
305
+ l = (struct zip_file_header_link *) malloc(sizeof(*l));
306
+ if (l == NULL) {
307
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate zip header data");
308
+ return (ARCHIVE_FATAL);
309
+ }
310
+ l->entry = archive_entry_clone(entry);
311
+ /* Initialize the CRC variable and potentially the local crc32(). */
312
+ l->crc32 = crc32(0, NULL, 0);
313
+ l->compression = zip->compression;
314
+ l->compressed_size = 0;
315
+ l->next = NULL;
316
+ if (zip->central_directory == NULL) {
317
+ zip->central_directory = l;
318
+ } else {
319
+ zip->central_directory_end->next = l;
320
+ }
321
+ zip->central_directory_end = l;
322
+
323
+ /* Store the offset of this header for later use in central directory. */
324
+ l->offset = zip->written_bytes;
325
+
326
+ memset(&h, 0, sizeof(h));
327
+ archive_le32enc(&h.signature, ZIP_SIGNATURE_LOCAL_FILE_HEADER);
328
+ archive_le16enc(&h.version, ZIP_VERSION_EXTRACT);
329
+ archive_le16enc(&h.flags, ZIP_FLAGS);
330
+ archive_le16enc(&h.compression, zip->compression);
331
+ archive_le32enc(&h.timedate, dos_time(archive_entry_mtime(entry)));
332
+ archive_le16enc(&h.filename_length, (uint16_t)path_length(entry));
333
+
334
+ switch (zip->compression) {
335
+ case COMPRESSION_STORE:
336
+ /* Setting compressed and uncompressed sizes even when specification says
337
+ * to set to zero when using data descriptors. Otherwise the end of the
338
+ * data for an entry is rather difficult to find. */
339
+ archive_le32enc(&h.compressed_size, size);
340
+ archive_le32enc(&h.uncompressed_size, size);
341
+ break;
342
+ #ifdef HAVE_ZLIB_H
343
+ case COMPRESSION_DEFLATE:
344
+ archive_le32enc(&h.uncompressed_size, size);
345
+
346
+ zip->stream.zalloc = Z_NULL;
347
+ zip->stream.zfree = Z_NULL;
348
+ zip->stream.opaque = Z_NULL;
349
+ zip->stream.next_out = zip->buf;
350
+ zip->stream.avail_out = zip->len_buf;
351
+ if (deflateInit2(&zip->stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
352
+ -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) {
353
+ archive_set_error(&a->archive, ENOMEM, "Can't init deflate compressor");
354
+ return (ARCHIVE_FATAL);
355
+ }
356
+ break;
357
+ #endif
358
+ }
359
+
360
+ /* Formatting extra data. */
361
+ archive_le16enc(&h.extra_length, sizeof(e));
362
+ archive_le16enc(&e.time_id, ZIP_SIGNATURE_EXTRA_TIMESTAMP);
363
+ archive_le16enc(&e.time_size, sizeof(e.time_flag) +
364
+ sizeof(e.mtime) + sizeof(e.atime) + sizeof(e.ctime));
365
+ e.time_flag[0] = 0x07;
366
+ archive_le32enc(&e.mtime, archive_entry_mtime(entry));
367
+ archive_le32enc(&e.atime, archive_entry_atime(entry));
368
+ archive_le32enc(&e.ctime, archive_entry_ctime(entry));
369
+
370
+ archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_UNIX);
371
+ archive_le16enc(&e.unix_size, sizeof(e.unix_uid) + sizeof(e.unix_gid));
372
+ archive_le16enc(&e.unix_uid, archive_entry_uid(entry));
373
+ archive_le16enc(&e.unix_gid, archive_entry_gid(entry));
374
+
375
+ archive_le32enc(&d->uncompressed_size, size);
376
+
377
+ ret = (a->compressor.write)(a, &h, sizeof(h));
378
+ if (ret != ARCHIVE_OK)
379
+ return (ARCHIVE_FATAL);
380
+ zip->written_bytes += sizeof(h);
381
+
382
+ ret = write_path(entry, a);
383
+ if (ret <= ARCHIVE_OK)
384
+ return (ARCHIVE_FATAL);
385
+ zip->written_bytes += ret;
386
+
387
+ ret = (a->compressor.write)(a, &e, sizeof(e));
388
+ if (ret != ARCHIVE_OK)
389
+ return (ARCHIVE_FATAL);
390
+ zip->written_bytes += sizeof(e);
391
+
392
+ return (ARCHIVE_OK);
393
+ }
394
+
395
+ static ssize_t
396
+ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
397
+ {
398
+ int ret;
399
+ struct zip *zip = a->format_data;
400
+ struct zip_file_header_link *l = zip->central_directory_end;
401
+
402
+ if ((int64_t)s > zip->remaining_data_bytes)
403
+ s = (size_t)zip->remaining_data_bytes;
404
+
405
+ if (s == 0) return 0;
406
+
407
+ switch (zip->compression) {
408
+ case COMPRESSION_STORE:
409
+ ret = (a->compressor.write)(a, buff, s);
410
+ if (ret != ARCHIVE_OK) return (ret);
411
+ zip->written_bytes += s;
412
+ zip->remaining_data_bytes -= s;
413
+ l->compressed_size += s;
414
+ l->crc32 = crc32(l->crc32, buff, s);
415
+ return (s);
416
+ #if HAVE_ZLIB_H
417
+ case COMPRESSION_DEFLATE:
418
+ zip->stream.next_in = (unsigned char*)(uintptr_t)buff;
419
+ zip->stream.avail_in = s;
420
+ do {
421
+ ret = deflate(&zip->stream, Z_NO_FLUSH);
422
+ if (ret == Z_STREAM_ERROR)
423
+ return (ARCHIVE_FATAL);
424
+ if (zip->stream.avail_out == 0) {
425
+ ret = (a->compressor.write)(a, zip->buf, zip->len_buf);
426
+ if (ret != ARCHIVE_OK)
427
+ return (ret);
428
+ l->compressed_size += zip->len_buf;
429
+ zip->written_bytes += zip->len_buf;
430
+ zip->stream.next_out = zip->buf;
431
+ zip->stream.avail_out = zip->len_buf;
432
+ }
433
+ } while (zip->stream.avail_in != 0);
434
+ zip->remaining_data_bytes -= s;
435
+ /* If we have it, use zlib's fast crc32() */
436
+ l->crc32 = crc32(l->crc32, buff, s);
437
+ return (s);
438
+ #endif
439
+
440
+ default:
441
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
442
+ "Invalid ZIP compression type");
443
+ return ARCHIVE_FATAL;
444
+ }
445
+ }
446
+
447
+ static int
448
+ archive_write_zip_finish_entry(struct archive_write *a)
449
+ {
450
+ /* Write the data descripter after file data has been written. */
451
+ int ret;
452
+ struct zip *zip = a->format_data;
453
+ struct zip_data_descriptor *d = &zip->data_descriptor;
454
+ struct zip_file_header_link *l = zip->central_directory_end;
455
+ #if HAVE_ZLIB_H
456
+ size_t reminder;
457
+ #endif
458
+
459
+ switch(zip->compression) {
460
+ case COMPRESSION_STORE:
461
+ break;
462
+ #if HAVE_ZLIB_H
463
+ case COMPRESSION_DEFLATE:
464
+ for (;;) {
465
+ ret = deflate(&zip->stream, Z_FINISH);
466
+ if (ret == Z_STREAM_ERROR)
467
+ return (ARCHIVE_FATAL);
468
+ reminder = zip->len_buf - zip->stream.avail_out;
469
+ ret = (a->compressor.write)(a, zip->buf, reminder);
470
+ if (ret != ARCHIVE_OK)
471
+ return (ret);
472
+ l->compressed_size += reminder;
473
+ zip->written_bytes += reminder;
474
+ zip->stream.next_out = zip->buf;
475
+ if (zip->stream.avail_out != 0)
476
+ break;
477
+ zip->stream.avail_out = zip->len_buf;
478
+ }
479
+ deflateEnd(&zip->stream);
480
+ break;
481
+ #endif
482
+ }
483
+
484
+ archive_le32enc(&d->crc32, l->crc32);
485
+ archive_le32enc(&d->compressed_size, l->compressed_size);
486
+ ret = (a->compressor.write)(a, d, sizeof(*d));
487
+ if (ret != ARCHIVE_OK)
488
+ return (ARCHIVE_FATAL);
489
+ zip->written_bytes += sizeof(*d);
490
+ return (ARCHIVE_OK);
491
+ }
492
+
493
+ static int
494
+ archive_write_zip_finish(struct archive_write *a)
495
+ {
496
+ struct zip *zip;
497
+ struct zip_file_header_link *l;
498
+ struct zip_file_header h;
499
+ struct zip_central_directory_end end;
500
+ struct zip_extra_data_central e;
501
+ off_t offset_start, offset_end;
502
+ int entries;
503
+ int ret;
504
+
505
+ zip = a->format_data;
506
+ l = zip->central_directory;
507
+
508
+ /*
509
+ * Formatting central directory file header fields that are fixed for all entries.
510
+ * Fields not used (and therefor 0) are:
511
+ *
512
+ * - comment_length
513
+ * - disk_number
514
+ * - attributes_internal
515
+ */
516
+ memset(&h, 0, sizeof(h));
517
+ archive_le32enc(&h.signature, ZIP_SIGNATURE_FILE_HEADER);
518
+ archive_le16enc(&h.version_by, ZIP_VERSION_BY);
519
+ archive_le16enc(&h.version_extract, ZIP_VERSION_EXTRACT);
520
+ archive_le16enc(&h.flags, ZIP_FLAGS);
521
+
522
+ entries = 0;
523
+ offset_start = zip->written_bytes;
524
+
525
+ /* Formatting individual header fields per entry and
526
+ * writing each entry. */
527
+ while (l != NULL) {
528
+ archive_le16enc(&h.compression, l->compression);
529
+ archive_le32enc(&h.timedate, dos_time(archive_entry_mtime(l->entry)));
530
+ archive_le32enc(&h.crc32, l->crc32);
531
+ archive_le32enc(&h.compressed_size, l->compressed_size);
532
+ archive_le32enc(&h.uncompressed_size, archive_entry_size(l->entry));
533
+ archive_le16enc(&h.filename_length, (uint16_t)path_length(l->entry));
534
+ archive_le16enc(&h.extra_length, sizeof(e));
535
+ archive_le16enc(&h.attributes_external[2], archive_entry_mode(l->entry));
536
+ archive_le32enc(&h.offset, l->offset);
537
+
538
+ /* Formatting extra data. */
539
+ archive_le16enc(&e.time_id, ZIP_SIGNATURE_EXTRA_TIMESTAMP);
540
+ archive_le16enc(&e.time_size, sizeof(e.mtime) + sizeof(e.time_flag));
541
+ e.time_flag[0] = 0x07;
542
+ archive_le32enc(&e.mtime, archive_entry_mtime(l->entry));
543
+ archive_le16enc(&e.unix_id, ZIP_SIGNATURE_EXTRA_UNIX);
544
+ archive_le16enc(&e.unix_size, 0x0000);
545
+
546
+ ret = (a->compressor.write)(a, &h, sizeof(h));
547
+ if (ret != ARCHIVE_OK)
548
+ return (ARCHIVE_FATAL);
549
+ zip->written_bytes += sizeof(h);
550
+
551
+ ret = write_path(l->entry, a);
552
+ if (ret <= ARCHIVE_OK)
553
+ return (ARCHIVE_FATAL);
554
+ zip->written_bytes += ret;
555
+
556
+ ret = (a->compressor.write)(a, &e, sizeof(e));
557
+ if (ret != ARCHIVE_OK)
558
+ return (ARCHIVE_FATAL);
559
+ zip->written_bytes += sizeof(e);
560
+
561
+ l = l->next;
562
+ entries++;
563
+ }
564
+ offset_end = zip->written_bytes;
565
+
566
+ /* Formatting end of central directory. */
567
+ memset(&end, 0, sizeof(end));
568
+ archive_le32enc(&end.signature, ZIP_SIGNATURE_CENTRAL_DIRECTORY_END);
569
+ archive_le16enc(&end.entries_disk, entries);
570
+ archive_le16enc(&end.entries, entries);
571
+ archive_le32enc(&end.size, offset_end - offset_start);
572
+ archive_le32enc(&end.offset, offset_start);
573
+
574
+ /* Writing end of central directory. */
575
+ ret = (a->compressor.write)(a, &end, sizeof(end));
576
+ if (ret != ARCHIVE_OK)
577
+ return (ARCHIVE_FATAL);
578
+ zip->written_bytes += sizeof(end);
579
+ return (ARCHIVE_OK);
580
+ }
581
+
582
+ static int
583
+ archive_write_zip_destroy(struct archive_write *a)
584
+ {
585
+ struct zip *zip;
586
+ struct zip_file_header_link *l;
587
+
588
+ zip = a->format_data;
589
+ while (zip->central_directory != NULL) {
590
+ l = zip->central_directory;
591
+ zip->central_directory = l->next;
592
+ archive_entry_free(l->entry);
593
+ free(l);
594
+ }
595
+ #ifdef HAVE_ZLIB_H
596
+ free(zip->buf);
597
+ #endif
598
+ free(zip);
599
+ a->format_data = NULL;
600
+ return (ARCHIVE_OK);
601
+ }
602
+
603
+ /* Convert into MSDOS-style date/time. */
604
+ static unsigned int
605
+ dos_time(const time_t unix_time)
606
+ {
607
+ struct tm *t;
608
+ unsigned int dt;
609
+
610
+ /* This will not preserve time when creating/extracting the archive
611
+ * on two systems with different time zones. */
612
+ t = localtime(&unix_time);
613
+
614
+ dt = 0;
615
+ dt += ((t->tm_year - 80) & 0x7f) << 9;
616
+ dt += ((t->tm_mon + 1) & 0x0f) << 5;
617
+ dt += (t->tm_mday & 0x1f);
618
+ dt <<= 16;
619
+ dt += (t->tm_hour & 0x1f) << 11;
620
+ dt += (t->tm_min & 0x3f) << 5;
621
+ dt += (t->tm_sec & 0x3e) >> 1; /* Only counting every 2 seconds. */
622
+ return dt;
623
+ }
624
+
625
+ static size_t
626
+ path_length(struct archive_entry *entry)
627
+ {
628
+ mode_t type;
629
+ const char *path;
630
+
631
+ type = archive_entry_filetype(entry);
632
+ path = archive_entry_pathname(entry);
633
+
634
+ if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
635
+ return strlen(path) + 1;
636
+ } else {
637
+ return strlen(path);
638
+ }
639
+ }
640
+
641
+ static int
642
+ write_path(struct archive_entry *entry, struct archive_write *archive)
643
+ {
644
+ int ret;
645
+ const char *path;
646
+ mode_t type;
647
+ size_t written_bytes;
648
+
649
+ path = archive_entry_pathname(entry);
650
+ type = archive_entry_filetype(entry);
651
+ written_bytes = 0;
652
+
653
+ ret = (archive->compressor.write)(archive, path, strlen(path));
654
+ if (ret != ARCHIVE_OK)
655
+ return (ARCHIVE_FATAL);
656
+ written_bytes += strlen(path);
657
+
658
+ /* Folders are recognized by a traling slash. */
659
+ if ((type == AE_IFDIR) & (path[strlen(path) - 1] != '/')) {
660
+ ret = (archive->compressor.write)(archive, "/", 1);
661
+ if (ret != ARCHIVE_OK)
662
+ return (ARCHIVE_FATAL);
663
+ written_bytes += 1;
664
+ }
665
+
666
+ return ((int)written_bytes);
667
+ }