libarchive-static 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }