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,3151 @@
1
+ /*-
2
+ * Copyright (c) 2009 Michihiro NAKAJIMA
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
+ #include "archive_platform.h"
26
+ __FBSDID("$FreeBSD$");
27
+
28
+ #ifdef HAVE_ERRNO_H
29
+ #include <errno.h>
30
+ #endif
31
+ #include <stdio.h>
32
+ #ifdef HAVE_STDLIB_H
33
+ #include <stdlib.h>
34
+ #endif
35
+ #if HAVE_LIBXML_XMLREADER_H
36
+ #include <libxml/xmlreader.h>
37
+ #elif HAVE_BSDXML_H
38
+ #include <bsdxml.h>
39
+ #elif HAVE_EXPAT_H
40
+ #include <expat.h>
41
+ #endif
42
+ #ifdef HAVE_BZLIB_H
43
+ #include <bzlib.h>
44
+ #endif
45
+ #if HAVE_LZMA_H
46
+ #include <lzma.h>
47
+ #elif HAVE_LZMADEC_H
48
+ #include <lzmadec.h>
49
+ #endif
50
+ #ifdef HAVE_ZLIB_H
51
+ #include <zlib.h>
52
+ #endif
53
+
54
+ #include "archive.h"
55
+ #include "archive_endian.h"
56
+ #include "archive_entry.h"
57
+ #include "archive_hash.h"
58
+ #include "archive_private.h"
59
+ #include "archive_read_private.h"
60
+
61
+ #if (!defined(HAVE_LIBXML_XMLREADER_H) && \
62
+ !defined(HAVE_BSDXML_H) && !defined(HAVE_EXPAT_H)) ||\
63
+ !defined(HAVE_ZLIB_H) || \
64
+ !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
65
+ /*
66
+ * xar needs several external libraries.
67
+ * o libxml2 or expat --- XML parser
68
+ * o openssl or MD5/SHA1 hash function
69
+ * o zlib
70
+ * o bzlib2 (option)
71
+ * o liblzma (option)
72
+ */
73
+ int
74
+ archive_read_support_format_xar(struct archive *_a)
75
+ {
76
+ struct archive_read *a = (struct archive_read *)_a;
77
+
78
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
79
+ "Xar not supported on this platform");
80
+ return (ARCHIVE_WARN);
81
+ }
82
+
83
+ #else /* Support xar format */
84
+
85
+ //#define DEBUG 1
86
+ //#define DEBUG_PRINT_TOC 1
87
+ #if DEBUG_PRINT_TOC
88
+ #define PRINT_TOC(d, outbytes) do { \
89
+ unsigned char *x = (unsigned char *)(uintptr_t)d; \
90
+ unsigned char c = x[outbytes-1]; \
91
+ x[outbytes - 1] = 0; \
92
+ fprintf(stderr, "%s", x); \
93
+ fprintf(stderr, "%c", c); \
94
+ x[outbytes - 1] = c; \
95
+ } while (0)
96
+ #else
97
+ #define PRINT_TOC(d, outbytes)
98
+ #endif
99
+
100
+ #define HEADER_MAGIC 0x78617221
101
+ #define HEADER_SIZE 28
102
+ #define HEADER_VERSION 1
103
+ #define CKSUM_NONE 0
104
+ #define CKSUM_SHA1 1
105
+ #define CKSUM_MD5 2
106
+
107
+ #define MD5_SIZE 16
108
+ #define SHA1_SIZE 20
109
+ #define MAX_SUM_SIZE 20
110
+
111
+ enum enctype {
112
+ NONE,
113
+ GZIP,
114
+ BZIP2,
115
+ LZMA,
116
+ XZ,
117
+ };
118
+
119
+ struct chksumval {
120
+ int alg;
121
+ size_t len;
122
+ unsigned char val[MAX_SUM_SIZE];
123
+ };
124
+
125
+ struct chksumwork {
126
+ int alg;
127
+ #ifdef ARCHIVE_HAS_MD5
128
+ archive_md5_ctx md5ctx;
129
+ #endif
130
+ #ifdef ARCHIVE_HAS_SHA1
131
+ archive_sha1_ctx sha1ctx;
132
+ #endif
133
+ };
134
+
135
+ struct xattr {
136
+ struct xattr *next;
137
+ struct archive_string name;
138
+ uint64_t id;
139
+ uint64_t length;
140
+ uint64_t offset;
141
+ uint64_t size;
142
+ enum enctype encoding;
143
+ struct chksumval a_sum;
144
+ struct chksumval e_sum;
145
+ struct archive_string fstype;
146
+ };
147
+
148
+ struct xar_file {
149
+ struct xar_file *next;
150
+ struct xar_file *hdnext;
151
+ struct xar_file *parent;
152
+ int subdirs;
153
+
154
+ unsigned int has;
155
+ #define HAS_DATA 0x00001
156
+ #define HAS_PATHNAME 0x00002
157
+ #define HAS_SYMLINK 0x00004
158
+ #define HAS_TIME 0x00008
159
+ #define HAS_UID 0x00010
160
+ #define HAS_GID 0x00020
161
+ #define HAS_MODE 0x00040
162
+ #define HAS_TYPE 0x00080
163
+ #define HAS_DEV 0x00100
164
+ #define HAS_DEVMAJOR 0x00200
165
+ #define HAS_DEVMINOR 0x00400
166
+ #define HAS_INO 0x00800
167
+ #define HAS_FFLAGS 0x01000
168
+ #define HAS_XATTR 0x02000
169
+ #define HAS_ACL 0x04000
170
+
171
+ uint64_t id;
172
+ uint64_t length;
173
+ uint64_t offset;
174
+ uint64_t size;
175
+ enum enctype encoding;
176
+ struct chksumval a_sum;
177
+ struct chksumval e_sum;
178
+ struct archive_string pathname;
179
+ struct archive_string symlink;
180
+ time_t ctime;
181
+ time_t mtime;
182
+ time_t atime;
183
+ struct archive_string uname;
184
+ uid_t uid;
185
+ struct archive_string gname;
186
+ gid_t gid;
187
+ mode_t mode;
188
+ dev_t dev;
189
+ dev_t devmajor;
190
+ dev_t devminor;
191
+ int64_t ino64;
192
+ struct archive_string fflags_text;
193
+ unsigned int link;
194
+ unsigned int nlink;
195
+ struct archive_string hardlink;
196
+ struct xattr *xattr_list;
197
+ };
198
+
199
+ struct hdlink {
200
+ struct hdlink *next;
201
+
202
+ unsigned int id;
203
+ int cnt;
204
+ struct xar_file *files;
205
+ };
206
+
207
+ struct heap_queue {
208
+ struct xar_file **files;
209
+ int allocated;
210
+ int used;
211
+ };
212
+
213
+ enum xmlstatus {
214
+ INIT,
215
+ XAR,
216
+ TOC,
217
+ TOC_CREATION_TIME,
218
+ TOC_CHECKSUM,
219
+ TOC_CHECKSUM_OFFSET,
220
+ TOC_CHECKSUM_SIZE,
221
+ TOC_FILE,
222
+ FILE_DATA,
223
+ FILE_DATA_LENGTH,
224
+ FILE_DATA_OFFSET,
225
+ FILE_DATA_SIZE,
226
+ FILE_DATA_ENCODING,
227
+ FILE_DATA_A_CHECKSUM,
228
+ FILE_DATA_E_CHECKSUM,
229
+ FILE_DATA_CONTENT,
230
+ FILE_EA,
231
+ FILE_EA_LENGTH,
232
+ FILE_EA_OFFSET,
233
+ FILE_EA_SIZE,
234
+ FILE_EA_ENCODING,
235
+ FILE_EA_A_CHECKSUM,
236
+ FILE_EA_E_CHECKSUM,
237
+ FILE_EA_NAME,
238
+ FILE_EA_FSTYPE,
239
+ FILE_CTIME,
240
+ FILE_MTIME,
241
+ FILE_ATIME,
242
+ FILE_GROUP,
243
+ FILE_GID,
244
+ FILE_USER,
245
+ FILE_UID,
246
+ FILE_MODE,
247
+ FILE_DEVICE,
248
+ FILE_DEVICE_MAJOR,
249
+ FILE_DEVICE_MINOR,
250
+ FILE_DEVICENO,
251
+ FILE_INODE,
252
+ FILE_LINK,
253
+ FILE_TYPE,
254
+ FILE_NAME,
255
+ FILE_ACL,
256
+ FILE_ACL_DEFAULT,
257
+ FILE_ACL_ACCESS,
258
+ FILE_ACL_APPLEEXTENDED,
259
+ /* BSD file flags. */
260
+ FILE_FLAGS,
261
+ FILE_FLAGS_USER_NODUMP,
262
+ FILE_FLAGS_USER_IMMUTABLE,
263
+ FILE_FLAGS_USER_APPEND,
264
+ FILE_FLAGS_USER_OPAQUE,
265
+ FILE_FLAGS_USER_NOUNLINK,
266
+ FILE_FLAGS_SYS_ARCHIVED,
267
+ FILE_FLAGS_SYS_IMMUTABLE,
268
+ FILE_FLAGS_SYS_APPEND,
269
+ FILE_FLAGS_SYS_NOUNLINK,
270
+ FILE_FLAGS_SYS_SNAPSHOT,
271
+ /* Linux file flags. */
272
+ FILE_EXT2,
273
+ FILE_EXT2_SecureDeletion,
274
+ FILE_EXT2_Undelete,
275
+ FILE_EXT2_Compress,
276
+ FILE_EXT2_Synchronous,
277
+ FILE_EXT2_Immutable,
278
+ FILE_EXT2_AppendOnly,
279
+ FILE_EXT2_NoDump,
280
+ FILE_EXT2_NoAtime,
281
+ FILE_EXT2_CompDirty,
282
+ FILE_EXT2_CompBlock,
283
+ FILE_EXT2_NoCompBlock,
284
+ FILE_EXT2_CompError,
285
+ FILE_EXT2_BTree,
286
+ FILE_EXT2_HashIndexed,
287
+ FILE_EXT2_iMagic,
288
+ FILE_EXT2_Journaled,
289
+ FILE_EXT2_NoTail,
290
+ FILE_EXT2_DirSync,
291
+ FILE_EXT2_TopDir,
292
+ FILE_EXT2_Reserved,
293
+ UNKNOWN,
294
+ };
295
+
296
+ struct unknown_tag {
297
+ struct unknown_tag *next;
298
+ struct archive_string name;
299
+ };
300
+
301
+ struct xar {
302
+ uint64_t offset; /* Current position in the file. */
303
+ int64_t total;
304
+ uint64_t h_base;
305
+ int end_of_file;
306
+ unsigned char buff[1024*32];
307
+
308
+ enum xmlstatus xmlsts;
309
+ enum xmlstatus xmlsts_unknown;
310
+ struct unknown_tag *unknowntags;
311
+ int base64text;
312
+
313
+ /*
314
+ * TOC
315
+ */
316
+ uint64_t toc_remaining;
317
+ uint64_t toc_total;
318
+ uint64_t toc_chksum_offset;
319
+ uint64_t toc_chksum_size;
320
+
321
+ /*
322
+ * For Decoding data.
323
+ */
324
+ enum enctype rd_encoding;
325
+ z_stream stream;
326
+ int stream_valid;
327
+ #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
328
+ bz_stream bzstream;
329
+ int bzstream_valid;
330
+ #endif
331
+ #if HAVE_LZMA_H && HAVE_LIBLZMA
332
+ lzma_stream lzstream;
333
+ int lzstream_valid;
334
+ #elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
335
+ lzmadec_stream lzstream;
336
+ int lzstream_valid;
337
+ #endif
338
+ /*
339
+ * For Checksum data.
340
+ */
341
+ struct chksumwork a_sumwrk;
342
+ struct chksumwork e_sumwrk;
343
+
344
+ struct xar_file *file; /* current reading file. */
345
+ struct xattr *xattr; /* current reading extended attribute. */
346
+ struct heap_queue file_queue;
347
+ struct xar_file *hdlink_orgs;
348
+ struct hdlink *hdlink_list;
349
+
350
+ int entry_init;
351
+ uint64_t entry_total;
352
+ uint64_t entry_remaining;
353
+ uint64_t entry_size;
354
+ enum enctype entry_encoding;
355
+ struct chksumval entry_a_sum;
356
+ struct chksumval entry_e_sum;
357
+ };
358
+
359
+ struct xmlattr {
360
+ struct xmlattr *next;
361
+ char *name;
362
+ char *value;
363
+ };
364
+
365
+ struct xmlattr_list {
366
+ struct xmlattr *first;
367
+ struct xmlattr **last;
368
+ };
369
+
370
+ static int xar_bid(struct archive_read *);
371
+ static int xar_read_header(struct archive_read *,
372
+ struct archive_entry *);
373
+ static int xar_read_data(struct archive_read *,
374
+ const void **, size_t *, off_t *);
375
+ static int xar_read_data_skip(struct archive_read *);
376
+ static int xar_cleanup(struct archive_read *);
377
+ static int move_reading_point(struct archive_read *, uint64_t);
378
+ static int rd_contents_init(struct archive_read *,
379
+ enum enctype, int, int);
380
+ static int rd_contents(struct archive_read *, const void **,
381
+ size_t *, size_t *, uint64_t);
382
+ static uint64_t atol10(const char *, size_t);
383
+ static int64_t atol8(const char *, size_t);
384
+ static size_t atohex(unsigned char *, size_t, const char *, size_t);
385
+ static time_t parse_time(const char *p, size_t n);
386
+ static void heap_add_entry(struct heap_queue *, struct xar_file *);
387
+ static struct xar_file *heap_get_entry(struct heap_queue *);
388
+ static void add_link(struct xar *, struct xar_file *);
389
+ static void checksum_init(struct archive_read *, int, int);
390
+ static void checksum_update(struct archive_read *, const void *,
391
+ size_t, const void *, size_t);
392
+ static int checksum_final(struct archive_read *, const void *,
393
+ size_t, const void *, size_t);
394
+ static int decompression_init(struct archive_read *, enum enctype);
395
+ static int decompress(struct archive_read *, const void **,
396
+ size_t *, const void *, size_t *);
397
+ static int decompression_cleanup(struct archive_read *);
398
+ static void xmlattr_cleanup(struct xmlattr_list *);
399
+ static void file_new(struct xar *, struct xmlattr_list *);
400
+ static void file_free(struct xar_file *);
401
+ static void xattr_new(struct xar *, struct xmlattr_list *);
402
+ static void xattr_free(struct xattr *);
403
+ static int getencoding(struct xmlattr_list *);
404
+ static int getsumalgorithm(struct xmlattr_list *);
405
+ static void unknowntag_start(struct xar *, const char *);
406
+ static void unknowntag_end(struct xar *, const char *);
407
+ static void xml_start(void *, const char *, struct xmlattr_list *);
408
+ static void xml_end(void *, const char *);
409
+ static void xml_data(void *, const char *, int);
410
+ static int xml_parse_file_flags(struct xar *, const char *);
411
+ static int xml_parse_file_ext2(struct xar *, const char *);
412
+ #if defined(HAVE_LIBXML_XMLREADER_H)
413
+ static int xml2_xmlattr_setup(struct xmlattr_list *, xmlTextReaderPtr);
414
+ static int xml2_read_cb(void *, char *, int);
415
+ static int xml2_close_cb(void *);
416
+ static void xml2_error_hdr(void *, const char *, xmlParserSeverities,
417
+ xmlTextReaderLocatorPtr);
418
+ static int xml2_read_toc(struct archive_read *);
419
+ #elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
420
+ static void expat_xmlattr_setup(struct xmlattr_list *, const XML_Char **);
421
+ static void expat_start_cb(void *, const XML_Char *, const XML_Char **);
422
+ static void expat_end_cb(void *, const XML_Char *);
423
+ static void expat_data_cb(void *, const XML_Char *, int);
424
+ static int expat_read_toc(struct archive_read *);
425
+ #endif
426
+
427
+ int
428
+ archive_read_support_format_xar(struct archive *_a)
429
+ {
430
+ struct xar *xar;
431
+ struct archive_read *a = (struct archive_read *)_a;
432
+ int r;
433
+
434
+ xar = (struct xar *)calloc(1, sizeof(*xar));
435
+ if (xar == NULL) {
436
+ archive_set_error(&a->archive, ENOMEM,
437
+ "Can't allocate xar data");
438
+ return (ARCHIVE_FATAL);
439
+ }
440
+
441
+ r = __archive_read_register_format(a,
442
+ xar,
443
+ "xar",
444
+ xar_bid,
445
+ NULL,
446
+ xar_read_header,
447
+ xar_read_data,
448
+ xar_read_data_skip,
449
+ xar_cleanup);
450
+ if (r != ARCHIVE_OK)
451
+ free(xar);
452
+ return (r);
453
+ }
454
+
455
+ static int
456
+ xar_bid(struct archive_read *a)
457
+ {
458
+ const unsigned char *b;
459
+ int bid;
460
+
461
+ b = __archive_read_ahead(a, HEADER_SIZE, NULL);
462
+ if (b == NULL)
463
+ return (-1);
464
+
465
+ bid = 0;
466
+ /*
467
+ * Verify magic code
468
+ */
469
+ if (archive_be32dec(b) != HEADER_MAGIC)
470
+ return (0);
471
+ bid += 32;
472
+ /*
473
+ * Verify header size
474
+ */
475
+ if (archive_be16dec(b+4) != HEADER_SIZE)
476
+ return (0);
477
+ bid += 16;
478
+ /*
479
+ * Verify header version
480
+ */
481
+ if (archive_be16dec(b+6) != HEADER_VERSION)
482
+ return (0);
483
+ bid += 16;
484
+ /*
485
+ * Verify type of checksum
486
+ */
487
+ switch (archive_be32dec(b+24)) {
488
+ case CKSUM_NONE:
489
+ case CKSUM_SHA1:
490
+ case CKSUM_MD5:
491
+ bid += 32;
492
+ break;
493
+ default:
494
+ return (0);
495
+ }
496
+
497
+ return (bid);
498
+ }
499
+
500
+ static int
501
+ read_toc(struct archive_read *a)
502
+ {
503
+ struct xar *xar;
504
+ struct xar_file *file;
505
+ const unsigned char *b;
506
+ uint64_t toc_compressed_size;
507
+ uint64_t toc_uncompressed_size;
508
+ uint32_t toc_chksum_alg;
509
+ ssize_t bytes;
510
+ int r;
511
+
512
+ xar = (struct xar *)(a->format->data);
513
+
514
+ /*
515
+ * Read xar header.
516
+ */
517
+ b = __archive_read_ahead(a, HEADER_SIZE, &bytes);
518
+ if (bytes < 0)
519
+ return ((int)bytes);
520
+ if (bytes < HEADER_SIZE) {
521
+ archive_set_error(&a->archive,
522
+ ARCHIVE_ERRNO_FILE_FORMAT,
523
+ "Truncated archive header");
524
+ return (ARCHIVE_FATAL);
525
+ }
526
+
527
+ if (archive_be32dec(b) != HEADER_MAGIC) {
528
+ archive_set_error(&a->archive,
529
+ ARCHIVE_ERRNO_FILE_FORMAT,
530
+ "Invalid header magic");
531
+ return (ARCHIVE_FATAL);
532
+ }
533
+ if (archive_be16dec(b+6) != HEADER_VERSION) {
534
+ archive_set_error(&a->archive,
535
+ ARCHIVE_ERRNO_FILE_FORMAT,
536
+ "Unsupported header version(%d)",
537
+ archive_be16dec(b+6));
538
+ return (ARCHIVE_FATAL);
539
+ }
540
+ toc_compressed_size = archive_be64dec(b+8);
541
+ xar->toc_remaining = toc_compressed_size;
542
+ toc_uncompressed_size = archive_be64dec(b+16);
543
+ toc_chksum_alg = archive_be32dec(b+24);
544
+ __archive_read_consume(a, HEADER_SIZE);
545
+ xar->offset += HEADER_SIZE;
546
+ xar->toc_total = 0;
547
+
548
+ /*
549
+ * Read TOC(Table of Contents).
550
+ */
551
+ /* Initialize reading contents. */
552
+ r = move_reading_point(a, HEADER_SIZE);
553
+ if (r != ARCHIVE_OK)
554
+ return (r);
555
+ r = rd_contents_init(a, GZIP, toc_chksum_alg, CKSUM_NONE);
556
+ if (r != ARCHIVE_OK)
557
+ return (r);
558
+
559
+ #ifdef HAVE_LIBXML_XMLREADER_H
560
+ r = xml2_read_toc(a);
561
+ #elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
562
+ r = expat_read_toc(a);
563
+ #endif
564
+ if (r != ARCHIVE_OK)
565
+ return (r);
566
+
567
+ /* Set 'The HEAP' base. */
568
+ xar->h_base = xar->offset;
569
+ if (xar->toc_total != toc_uncompressed_size) {
570
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
571
+ "TOC uncompressed size error");
572
+ return (ARCHIVE_FATAL);
573
+ }
574
+
575
+ /*
576
+ * Checksum TOC
577
+ */
578
+ if (toc_chksum_alg != CKSUM_NONE) {
579
+ r = move_reading_point(a, xar->toc_chksum_offset);
580
+ if (r != ARCHIVE_OK)
581
+ return (r);
582
+ b = __archive_read_ahead(a, xar->toc_chksum_size, &bytes);
583
+ if (bytes < 0)
584
+ return ((int)bytes);
585
+ if ((uint64_t)bytes < xar->toc_chksum_size) {
586
+ archive_set_error(&a->archive,
587
+ ARCHIVE_ERRNO_FILE_FORMAT,
588
+ "Truncated archive file");
589
+ return (ARCHIVE_FATAL);
590
+ }
591
+ r = checksum_final(a, b, xar->toc_chksum_size, NULL, 0);
592
+ __archive_read_consume(a, xar->toc_chksum_size);
593
+ xar->offset += xar->toc_chksum_size;
594
+ if (r != ARCHIVE_OK)
595
+ return (ARCHIVE_FATAL);
596
+ }
597
+
598
+ /*
599
+ * Connect hardlinked files.
600
+ */
601
+ for (file = xar->hdlink_orgs; file != NULL; file = file->hdnext) {
602
+ struct hdlink **hdlink;
603
+
604
+ for (hdlink = &(xar->hdlink_list); *hdlink != NULL;
605
+ hdlink = &((*hdlink)->next)) {
606
+ if ((*hdlink)->id == file->id) {
607
+ struct hdlink *hltmp;
608
+ struct xar_file *f2;
609
+ int nlink = (*hdlink)->cnt + 1;
610
+
611
+ file->nlink = nlink;
612
+ for (f2 = (*hdlink)->files; f2 != NULL;
613
+ f2 = f2->hdnext) {
614
+ f2->nlink = nlink;
615
+ archive_string_copy(
616
+ &(f2->hardlink), &(file->pathname));
617
+ }
618
+ /* Remove resolved files from hdlist_list. */
619
+ hltmp = *hdlink;
620
+ *hdlink = hltmp->next;
621
+ free(hltmp);
622
+ break;
623
+ }
624
+ }
625
+ }
626
+ a->archive.archive_format = ARCHIVE_FORMAT_XAR;
627
+ a->archive.archive_format_name = "xar";
628
+
629
+ return (ARCHIVE_OK);
630
+ }
631
+
632
+ static int
633
+ xar_read_header(struct archive_read *a, struct archive_entry *entry)
634
+ {
635
+ struct xar *xar;
636
+ struct xar_file *file;
637
+ struct xattr *xattr;
638
+ int r;
639
+
640
+ xar = (struct xar *)(a->format->data);
641
+
642
+ if (xar->offset == 0) {
643
+ /* Read TOC. */
644
+ r = read_toc(a);
645
+ if (r != ARCHIVE_OK)
646
+ return (r);
647
+ }
648
+
649
+ for (;;) {
650
+ file = xar->file = heap_get_entry(&(xar->file_queue));
651
+ if (file == NULL) {
652
+ xar->end_of_file = 1;
653
+ return (ARCHIVE_EOF);
654
+ }
655
+ if ((file->mode & AE_IFMT) != AE_IFDIR)
656
+ break;
657
+ if (file->has != (HAS_PATHNAME | HAS_TYPE))
658
+ break;
659
+ /*
660
+ * If a file type is a directory and it does not have
661
+ * any metadata, do not export.
662
+ */
663
+ file_free(file);
664
+ }
665
+ archive_entry_set_atime(entry, file->atime, 0);
666
+ archive_entry_set_ctime(entry, file->ctime, 0);
667
+ archive_entry_set_mtime(entry, file->mtime, 0);
668
+ archive_entry_set_gid(entry, file->gid);
669
+ if (file->gname.length > 0)
670
+ archive_entry_update_gname_utf8(entry, file->gname.s);
671
+ archive_entry_set_uid(entry, file->uid);
672
+ if (file->uname.length > 0)
673
+ archive_entry_update_uname_utf8(entry, file->uname.s);
674
+ archive_entry_set_mode(entry, file->mode);
675
+ archive_entry_update_pathname_utf8(entry, file->pathname.s);
676
+ if (file->symlink.length > 0)
677
+ archive_entry_update_symlink_utf8(entry, file->symlink.s);
678
+ /* Set proper nlink. */
679
+ if ((file->mode & AE_IFMT) == AE_IFDIR)
680
+ archive_entry_set_nlink(entry, file->subdirs + 2);
681
+ else
682
+ archive_entry_set_nlink(entry, file->nlink);
683
+ archive_entry_set_size(entry, file->size);
684
+ if (archive_strlen(&(file->hardlink)) > 0)
685
+ archive_entry_update_hardlink_utf8(entry,
686
+ file->hardlink.s);
687
+ archive_entry_set_ino64(entry, file->ino64);
688
+ if (file->has & HAS_DEV)
689
+ archive_entry_set_dev(entry, file->dev);
690
+ if (file->has & HAS_DEVMAJOR)
691
+ archive_entry_set_devmajor(entry, file->devmajor);
692
+ if (file->has & HAS_DEVMINOR)
693
+ archive_entry_set_devminor(entry, file->devminor);
694
+ if (archive_strlen(&(file->fflags_text)) > 0)
695
+ archive_entry_copy_fflags_text(entry, file->fflags_text.s);
696
+
697
+ xar->entry_init = 1;
698
+ xar->entry_total = 0;
699
+ xar->entry_remaining = file->length;
700
+ xar->entry_size = file->size;
701
+ xar->entry_encoding = file->encoding;
702
+ xar->entry_a_sum = file->a_sum;
703
+ xar->entry_e_sum = file->e_sum;
704
+ /*
705
+ * Read extended attributes.
706
+ */
707
+ r = ARCHIVE_OK;
708
+ xattr = file->xattr_list;
709
+ while (xattr != NULL) {
710
+ const void *d;
711
+ size_t outbytes, used;
712
+
713
+ r = move_reading_point(a, xattr->offset);
714
+ if (r != ARCHIVE_OK)
715
+ break;
716
+ r = rd_contents_init(a, xattr->encoding,
717
+ xattr->a_sum.alg, xattr->e_sum.alg);
718
+ if (r != ARCHIVE_OK)
719
+ break;
720
+ d = NULL;
721
+ r = rd_contents(a, &d, &outbytes, &used, xattr->length);
722
+ if (r != ARCHIVE_OK)
723
+ break;
724
+ if (outbytes != xattr->size) {
725
+ archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
726
+ "Decompressed size error");
727
+ r = ARCHIVE_FATAL;
728
+ break;
729
+ }
730
+ r = checksum_final(a,
731
+ xattr->a_sum.val, xattr->a_sum.len,
732
+ xattr->e_sum.val, xattr->e_sum.len);
733
+ if (r != ARCHIVE_OK)
734
+ break;
735
+ archive_entry_xattr_add_entry(entry,
736
+ xattr->name.s, d, outbytes);
737
+ xattr = xattr->next;
738
+ }
739
+ if (r != ARCHIVE_OK) {
740
+ file_free(file);
741
+ return (r);
742
+ }
743
+
744
+ if (xar->entry_remaining > 0)
745
+ /* Move reading point to the beginning of current
746
+ * file contents. */
747
+ r = move_reading_point(a, file->offset);
748
+ else
749
+ r = ARCHIVE_OK;
750
+
751
+ file_free(file);
752
+ return (r);
753
+ }
754
+
755
+ static int
756
+ xar_read_data(struct archive_read *a,
757
+ const void **buff, size_t *size, off_t *offset)
758
+ {
759
+ struct xar *xar;
760
+ size_t used;
761
+ int r;
762
+
763
+ xar = (struct xar *)(a->format->data);
764
+ if (xar->end_of_file || xar->entry_remaining <= 0) {
765
+ r = ARCHIVE_EOF;
766
+ goto abort_read_data;
767
+ }
768
+
769
+ if (xar->entry_init) {
770
+ r = rd_contents_init(a, xar->entry_encoding,
771
+ xar->entry_a_sum.alg, xar->entry_e_sum.alg);
772
+ if (r != ARCHIVE_OK) {
773
+ xar->entry_remaining = 0;
774
+ return (r);
775
+ }
776
+ xar->entry_init = 0;
777
+ }
778
+
779
+ *buff = NULL;
780
+ r = rd_contents(a, buff, size, &used, xar->entry_remaining);
781
+ if (r != ARCHIVE_OK)
782
+ goto abort_read_data;
783
+
784
+ *offset = xar->entry_total;
785
+ xar->entry_total += *size;
786
+ xar->total += *size;
787
+ xar->offset += used;
788
+ xar->entry_remaining -= used;
789
+ __archive_read_consume(a, used);
790
+
791
+ if (xar->entry_remaining == 0) {
792
+ if (xar->entry_total != xar->entry_size) {
793
+ archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
794
+ "Decompressed size error");
795
+ r = ARCHIVE_FATAL;
796
+ goto abort_read_data;
797
+ }
798
+ r = checksum_final(a,
799
+ xar->entry_a_sum.val, xar->entry_a_sum.len,
800
+ xar->entry_e_sum.val, xar->entry_e_sum.len);
801
+ if (r != ARCHIVE_OK)
802
+ goto abort_read_data;
803
+ }
804
+
805
+ return (ARCHIVE_OK);
806
+ abort_read_data:
807
+ *buff = NULL;
808
+ *size = 0;
809
+ *offset = xar->total;
810
+ return (r);
811
+ }
812
+
813
+ static int
814
+ xar_read_data_skip(struct archive_read *a)
815
+ {
816
+ struct xar *xar;
817
+ int64_t bytes_skipped;
818
+
819
+ xar = (struct xar *)(a->format->data);
820
+ if (xar->end_of_file)
821
+ return (ARCHIVE_EOF);
822
+ bytes_skipped = __archive_read_skip(a, xar->entry_remaining);
823
+ if (bytes_skipped < 0)
824
+ return (ARCHIVE_FATAL);
825
+ xar->offset += bytes_skipped;
826
+ return (ARCHIVE_OK);
827
+ }
828
+
829
+ static int
830
+ xar_cleanup(struct archive_read *a)
831
+ {
832
+ struct xar *xar;
833
+ struct hdlink *hdlink;
834
+ int i;
835
+ int r;
836
+
837
+ xar = (struct xar *)(a->format->data);
838
+ r = decompression_cleanup(a);
839
+ hdlink = xar->hdlink_list;
840
+ while (hdlink != NULL) {
841
+ struct hdlink *next = hdlink->next;
842
+
843
+ free(hdlink);
844
+ hdlink = next;
845
+ }
846
+ for (i = 0; i < xar->file_queue.used; i++)
847
+ file_free(xar->file_queue.files[i]);
848
+ while (xar->unknowntags != NULL) {
849
+ struct unknown_tag *tag;
850
+
851
+ tag = xar->unknowntags;
852
+ xar->unknowntags = tag->next;
853
+ archive_string_free(&(tag->name));
854
+ free(tag);
855
+ }
856
+ free(xar);
857
+ a->format->data = NULL;
858
+ return (r);
859
+ }
860
+
861
+ static int
862
+ move_reading_point(struct archive_read *a, uint64_t offset)
863
+ {
864
+ struct xar *xar;
865
+
866
+ xar = (struct xar *)(a->format->data);
867
+ if (xar->offset - xar->h_base != offset) {
868
+ /* Seek forward to the start of file contents. */
869
+ int64_t step;
870
+
871
+ step = offset - (xar->offset - xar->h_base);
872
+ if (step > 0) {
873
+ step = __archive_read_skip(a, step);
874
+ if (step < 0)
875
+ return ((int)step);
876
+ xar->offset += step;
877
+ } else {
878
+ archive_set_error(&(a->archive),
879
+ ARCHIVE_ERRNO_MISC,
880
+ "Cannot seek.");
881
+ return (ARCHIVE_FAILED);
882
+ }
883
+ }
884
+ return (ARCHIVE_OK);
885
+ }
886
+
887
+ static int
888
+ rd_contents_init(struct archive_read *a, enum enctype encoding,
889
+ int a_sum_alg, int e_sum_alg)
890
+ {
891
+ int r;
892
+
893
+ /* Init decompress library. */
894
+ if ((r = decompression_init(a, encoding)) != ARCHIVE_OK)
895
+ return (r);
896
+ /* Init checksum library. */
897
+ checksum_init(a, a_sum_alg, e_sum_alg);
898
+ return (ARCHIVE_OK);
899
+ }
900
+
901
+ static int
902
+ rd_contents(struct archive_read *a, const void **buff, size_t *size,
903
+ size_t *used, uint64_t remaining)
904
+ {
905
+ const unsigned char *b;
906
+ ssize_t bytes;
907
+
908
+ /* Get whatever bytes are immediately available. */
909
+ b = __archive_read_ahead(a, 1, &bytes);
910
+ if (bytes < 0)
911
+ return ((int)bytes);
912
+ if (bytes == 0) {
913
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
914
+ "Truncated archive file");
915
+ return (ARCHIVE_FATAL);
916
+ }
917
+ if ((uint64_t)bytes > remaining)
918
+ bytes = (ssize_t)remaining;
919
+
920
+ /*
921
+ * Decompress contents of file.
922
+ */
923
+ *used = bytes;
924
+ if (decompress(a, buff, size, b, used) != ARCHIVE_OK)
925
+ return (ARCHIVE_FATAL);
926
+
927
+ /*
928
+ * Update checksum of a compressed data and a extracted data.
929
+ */
930
+ checksum_update(a, b, *used, *buff, *size);
931
+
932
+ return (ARCHIVE_OK);
933
+ }
934
+
935
+ /*
936
+ * Note that this implementation does not (and should not!) obey
937
+ * locale settings; you cannot simply substitute strtol here, since
938
+ * it does obey locale.
939
+ */
940
+
941
+ static uint64_t
942
+ atol10(const char *p, size_t char_cnt)
943
+ {
944
+ uint64_t l;
945
+ int digit;
946
+
947
+ l = 0;
948
+ digit = *p - '0';
949
+ while (digit >= 0 && digit < 10 && char_cnt-- > 0) {
950
+ l = (l * 10) + digit;
951
+ digit = *++p - '0';
952
+ }
953
+ return (l);
954
+ }
955
+
956
+ static int64_t
957
+ atol8(const char *p, size_t char_cnt)
958
+ {
959
+ int64_t l;
960
+ int digit;
961
+
962
+ l = 0;
963
+ while (char_cnt-- > 0) {
964
+ if (*p >= '0' && *p <= '7')
965
+ digit = *p - '0';
966
+ else
967
+ break;
968
+ p++;
969
+ l <<= 3;
970
+ l |= digit;
971
+ }
972
+ return (l);
973
+ }
974
+
975
+ static size_t
976
+ atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
977
+ {
978
+ size_t fbsize = bsize;
979
+
980
+ while (bsize && psize > 1) {
981
+ unsigned char x;
982
+
983
+ if (p[0] >= 'a' && p[0] <= 'z')
984
+ x = (p[0] - 'a' + 0x0a) << 4;
985
+ else if (p[0] >= 'A' && p[0] <= 'Z')
986
+ x = (p[0] - 'A' + 0x0a) << 4;
987
+ else if (p[0] >= '0' && p[0] <= '9')
988
+ x = (p[0] - '0') << 4;
989
+ else
990
+ return (-1);
991
+ if (p[1] >= 'a' && p[1] <= 'z')
992
+ x |= p[1] - 'a' + 0x0a;
993
+ else if (p[1] >= 'A' && p[1] <= 'Z')
994
+ x |= p[1] - 'A' + 0x0a;
995
+ else if (p[1] >= '0' && p[1] <= '9')
996
+ x |= p[1] - '0';
997
+ else
998
+ return (-1);
999
+
1000
+ *b++ = x;
1001
+ bsize--;
1002
+ p += 2;
1003
+ psize -= 2;
1004
+ }
1005
+ return (fbsize - bsize);
1006
+ }
1007
+
1008
+ static time_t
1009
+ time_from_tm(struct tm *t)
1010
+ {
1011
+ #if HAVE_TIMEGM
1012
+ /* Use platform timegm() if available. */
1013
+ return (timegm(t));
1014
+ #else
1015
+ /* Else use direct calculation using POSIX assumptions. */
1016
+ /* First, fix up tm_yday based on the year/month/day. */
1017
+ mktime(t);
1018
+ /* Then we can compute timegm() from first principles. */
1019
+ return (t->tm_sec + t->tm_min * 60 + t->tm_hour * 3600
1020
+ + t->tm_yday * 86400 + (t->tm_year - 70) * 31536000
1021
+ + ((t->tm_year - 69) / 4) * 86400 -
1022
+ ((t->tm_year - 1) / 100) * 86400
1023
+ + ((t->tm_year + 299) / 400) * 86400);
1024
+ #endif
1025
+ }
1026
+
1027
+ static time_t
1028
+ parse_time(const char *p, size_t n)
1029
+ {
1030
+ struct tm tm;
1031
+ time_t t = 0;
1032
+ int64_t data;
1033
+
1034
+ memset(&tm, 0, sizeof(tm));
1035
+ if (n != 20)
1036
+ return (t);
1037
+ data = atol10(p, 4);
1038
+ if (data < 1900)
1039
+ return (t);
1040
+ tm.tm_year = (int)data - 1900;
1041
+ p += 4;
1042
+ if (*p++ != '-')
1043
+ return (t);
1044
+ data = atol10(p, 2);
1045
+ if (data < 1 || data > 12)
1046
+ return (t);
1047
+ tm.tm_mon = (int)data -1;
1048
+ p += 2;
1049
+ if (*p++ != '-')
1050
+ return (t);
1051
+ data = atol10(p, 2);
1052
+ if (data < 1 || data > 31)
1053
+ return (t);
1054
+ tm.tm_mday = (int)data;
1055
+ p += 2;
1056
+ if (*p++ != 'T')
1057
+ return (t);
1058
+ data = atol10(p, 2);
1059
+ if (data < 0 || data > 23)
1060
+ return (t);
1061
+ tm.tm_hour = (int)data;
1062
+ p += 2;
1063
+ if (*p++ != ':')
1064
+ return (t);
1065
+ data = atol10(p, 2);
1066
+ if (data < 0 || data > 59)
1067
+ return (t);
1068
+ tm.tm_min = (int)data;
1069
+ p += 2;
1070
+ if (*p++ != ':')
1071
+ return (t);
1072
+ data = atol10(p, 2);
1073
+ if (data < 0 || data > 60)
1074
+ return (t);
1075
+ tm.tm_sec = (int)data;
1076
+ #if 0
1077
+ p += 2;
1078
+ if (*p != 'Z')
1079
+ return (t);
1080
+ #endif
1081
+
1082
+ t = time_from_tm(&tm);
1083
+
1084
+ return (t);
1085
+ }
1086
+
1087
+ static void
1088
+ heap_add_entry(struct heap_queue *heap, struct xar_file *file)
1089
+ {
1090
+ uint64_t file_id, parent_id;
1091
+ int hole, parent;
1092
+
1093
+ /* Expand our pending files list as necessary. */
1094
+ if (heap->used >= heap->allocated) {
1095
+ struct xar_file **new_pending_files;
1096
+ int new_size = heap->allocated * 2;
1097
+
1098
+ if (heap->allocated < 1024)
1099
+ new_size = 1024;
1100
+ /* Overflow might keep us from growing the list. */
1101
+ if (new_size <= heap->allocated)
1102
+ __archive_errx(1, "Out of memory");
1103
+ new_pending_files = (struct xar_file **)
1104
+ malloc(new_size * sizeof(new_pending_files[0]));
1105
+ if (new_pending_files == NULL)
1106
+ __archive_errx(1, "Out of memory");
1107
+ memcpy(new_pending_files, heap->files,
1108
+ heap->allocated * sizeof(new_pending_files[0]));
1109
+ if (heap->files != NULL)
1110
+ free(heap->files);
1111
+ heap->files = new_pending_files;
1112
+ heap->allocated = new_size;
1113
+ }
1114
+
1115
+ file_id = file->id;
1116
+
1117
+ /*
1118
+ * Start with hole at end, walk it up tree to find insertion point.
1119
+ */
1120
+ hole = heap->used++;
1121
+ while (hole > 0) {
1122
+ parent = (hole - 1)/2;
1123
+ parent_id = heap->files[parent]->id;
1124
+ if (file_id >= parent_id) {
1125
+ heap->files[hole] = file;
1126
+ return;
1127
+ }
1128
+ // Move parent into hole <==> move hole up tree.
1129
+ heap->files[hole] = heap->files[parent];
1130
+ hole = parent;
1131
+ }
1132
+ heap->files[0] = file;
1133
+ }
1134
+
1135
+ static struct xar_file *
1136
+ heap_get_entry(struct heap_queue *heap)
1137
+ {
1138
+ uint64_t a_id, b_id, c_id;
1139
+ int a, b, c;
1140
+ struct xar_file *r, *tmp;
1141
+
1142
+ if (heap->used < 1)
1143
+ return (NULL);
1144
+
1145
+ /*
1146
+ * The first file in the list is the earliest; we'll return this.
1147
+ */
1148
+ r = heap->files[0];
1149
+
1150
+ /*
1151
+ * Move the last item in the heap to the root of the tree
1152
+ */
1153
+ heap->files[0] = heap->files[--(heap->used)];
1154
+
1155
+ /*
1156
+ * Rebalance the heap.
1157
+ */
1158
+ a = 0; // Starting element and its heap key
1159
+ a_id = heap->files[a]->id;
1160
+ for (;;) {
1161
+ b = a + a + 1; // First child
1162
+ if (b >= heap->used)
1163
+ return (r);
1164
+ b_id = heap->files[b]->id;
1165
+ c = b + 1; // Use second child if it is smaller.
1166
+ if (c < heap->used) {
1167
+ c_id = heap->files[c]->id;
1168
+ if (c_id < b_id) {
1169
+ b = c;
1170
+ b_id = c_id;
1171
+ }
1172
+ }
1173
+ if (a_id <= b_id)
1174
+ return (r);
1175
+ tmp = heap->files[a];
1176
+ heap->files[a] = heap->files[b];
1177
+ heap->files[b] = tmp;
1178
+ a = b;
1179
+ }
1180
+ }
1181
+
1182
+ static void
1183
+ add_link(struct xar *xar, struct xar_file *file)
1184
+ {
1185
+ struct hdlink *hdlink;
1186
+
1187
+ for (hdlink = xar->hdlink_list; hdlink != NULL; hdlink = hdlink->next) {
1188
+ if (hdlink->id == file->link) {
1189
+ file->hdnext = hdlink->files;
1190
+ hdlink->cnt++;
1191
+ hdlink->files = file;
1192
+ return;
1193
+ }
1194
+ }
1195
+ hdlink = malloc(sizeof(*hdlink));
1196
+ if (hdlink == NULL)
1197
+ __archive_errx(1, "No memory for add_link()");
1198
+ file->hdnext = NULL;
1199
+ hdlink->id = file->link;
1200
+ hdlink->cnt = 1;
1201
+ hdlink->files = file;
1202
+ hdlink->next = xar->hdlink_list;
1203
+ xar->hdlink_list = hdlink;
1204
+ }
1205
+
1206
+ static void
1207
+ _checksum_init(struct chksumwork *sumwrk, int sum_alg)
1208
+ {
1209
+ sumwrk->alg = sum_alg;
1210
+ switch (sum_alg) {
1211
+ case CKSUM_NONE:
1212
+ break;
1213
+ case CKSUM_SHA1:
1214
+ archive_sha1_init(&(sumwrk->sha1ctx));
1215
+ break;
1216
+ case CKSUM_MD5:
1217
+ archive_md5_init(&(sumwrk->md5ctx));
1218
+ break;
1219
+ }
1220
+ }
1221
+
1222
+ static void
1223
+ _checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
1224
+ {
1225
+
1226
+ switch (sumwrk->alg) {
1227
+ case CKSUM_NONE:
1228
+ break;
1229
+ case CKSUM_SHA1:
1230
+ archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
1231
+ break;
1232
+ case CKSUM_MD5:
1233
+ archive_md5_update(&(sumwrk->md5ctx), buff, size);
1234
+ break;
1235
+ }
1236
+ }
1237
+
1238
+ static int
1239
+ _checksum_final(struct chksumwork *sumwrk, const void *val, size_t len)
1240
+ {
1241
+ unsigned char sum[MAX_SUM_SIZE];
1242
+ int r = ARCHIVE_OK;
1243
+
1244
+ switch (sumwrk->alg) {
1245
+ case CKSUM_NONE:
1246
+ break;
1247
+ case CKSUM_SHA1:
1248
+ archive_sha1_final(&(sumwrk->sha1ctx), sum);
1249
+ if (len != SHA1_SIZE ||
1250
+ memcmp(val, sum, SHA1_SIZE) != 0)
1251
+ r = ARCHIVE_FAILED;
1252
+ break;
1253
+ case CKSUM_MD5:
1254
+ archive_md5_final(&(sumwrk->md5ctx), sum);
1255
+ if (len != MD5_SIZE ||
1256
+ memcmp(val, sum, MD5_SIZE) != 0)
1257
+ r = ARCHIVE_FAILED;
1258
+ break;
1259
+ }
1260
+ return (r);
1261
+ }
1262
+
1263
+ static void
1264
+ checksum_init(struct archive_read *a, int a_sum_alg, int e_sum_alg)
1265
+ {
1266
+ struct xar *xar;
1267
+
1268
+ xar = (struct xar *)(a->format->data);
1269
+ _checksum_init(&(xar->a_sumwrk), a_sum_alg);
1270
+ _checksum_init(&(xar->e_sumwrk), e_sum_alg);
1271
+ }
1272
+
1273
+ static void
1274
+ checksum_update(struct archive_read *a, const void *abuff, size_t asize,
1275
+ const void *ebuff, size_t esize)
1276
+ {
1277
+ struct xar *xar;
1278
+
1279
+ xar = (struct xar *)(a->format->data);
1280
+ _checksum_update(&(xar->a_sumwrk), abuff, asize);
1281
+ _checksum_update(&(xar->e_sumwrk), ebuff, esize);
1282
+ }
1283
+
1284
+ static int
1285
+ checksum_final(struct archive_read *a, const void *a_sum_val,
1286
+ size_t a_sum_len, const void *e_sum_val, size_t e_sum_len)
1287
+ {
1288
+ struct xar *xar;
1289
+ int r;
1290
+
1291
+ xar = (struct xar *)(a->format->data);
1292
+ r = _checksum_final(&(xar->a_sumwrk), a_sum_val, a_sum_len);
1293
+ if (r == ARCHIVE_OK)
1294
+ r = _checksum_final(&(xar->e_sumwrk), e_sum_val, e_sum_len);
1295
+ if (r != ARCHIVE_OK)
1296
+ archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
1297
+ "Sumcheck error");
1298
+ return (r);
1299
+ }
1300
+
1301
+ static int
1302
+ decompression_init(struct archive_read *a, enum enctype encoding)
1303
+ {
1304
+ struct xar *xar;
1305
+ const char *detail;
1306
+ int r;
1307
+
1308
+ xar = (struct xar *)(a->format->data);
1309
+ xar->rd_encoding = encoding;
1310
+ switch (encoding) {
1311
+ case NONE:
1312
+ break;
1313
+ case GZIP:
1314
+ if (xar->stream_valid)
1315
+ r = inflateReset(&(xar->stream));
1316
+ else
1317
+ r = inflateInit(&(xar->stream));
1318
+ if (r != Z_OK) {
1319
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1320
+ "Couldn't initialize zlib stream.");
1321
+ return (ARCHIVE_FATAL);
1322
+ }
1323
+ xar->stream_valid = 1;
1324
+ xar->stream.total_in = 0;
1325
+ xar->stream.total_out = 0;
1326
+ break;
1327
+ #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1328
+ case BZIP2:
1329
+ if (xar->bzstream_valid) {
1330
+ BZ2_bzDecompressEnd(&(xar->bzstream));
1331
+ xar->bzstream_valid = 0;
1332
+ }
1333
+ r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 0);
1334
+ if (r == BZ_MEM_ERROR)
1335
+ r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 1);
1336
+ if (r != BZ_OK) {
1337
+ int err = ARCHIVE_ERRNO_MISC;
1338
+ detail = NULL;
1339
+ switch (r) {
1340
+ case BZ_PARAM_ERROR:
1341
+ detail = "invalid setup parameter";
1342
+ break;
1343
+ case BZ_MEM_ERROR:
1344
+ err = ENOMEM;
1345
+ detail = "out of memory";
1346
+ break;
1347
+ case BZ_CONFIG_ERROR:
1348
+ detail = "mis-compiled library";
1349
+ break;
1350
+ }
1351
+ archive_set_error(&a->archive, err,
1352
+ "Internal error initializing decompressor: %s",
1353
+ detail == NULL ? "??" : detail);
1354
+ xar->bzstream_valid = 0;
1355
+ return (ARCHIVE_FATAL);
1356
+ }
1357
+ xar->bzstream_valid = 1;
1358
+ xar->bzstream.total_in_lo32 = 0;
1359
+ xar->bzstream.total_in_hi32 = 0;
1360
+ xar->bzstream.total_out_lo32 = 0;
1361
+ xar->bzstream.total_out_hi32 = 0;
1362
+ break;
1363
+ #endif
1364
+ #if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1365
+ case XZ:
1366
+ case LZMA:
1367
+ if (xar->lzstream_valid) {
1368
+ lzma_end(&(xar->lzstream));
1369
+ xar->lzstream_valid = 0;
1370
+ }
1371
+ if (xar->entry_encoding == XZ)
1372
+ r = lzma_stream_decoder(&(xar->lzstream),
1373
+ (1U << 30),/* memlimit */
1374
+ LZMA_CONCATENATED);
1375
+ else
1376
+ r = lzma_alone_decoder(&(xar->lzstream),
1377
+ (1U << 30));/* memlimit */
1378
+ if (r != LZMA_OK) {
1379
+ switch (r) {
1380
+ case LZMA_MEM_ERROR:
1381
+ archive_set_error(&a->archive,
1382
+ ENOMEM,
1383
+ "Internal error initializing "
1384
+ "compression library: "
1385
+ "Cannot allocate memory");
1386
+ break;
1387
+ case LZMA_OPTIONS_ERROR:
1388
+ archive_set_error(&a->archive,
1389
+ ARCHIVE_ERRNO_MISC,
1390
+ "Internal error initializing "
1391
+ "compression library: "
1392
+ "Invalid or unsupported options");
1393
+ break;
1394
+ default:
1395
+ archive_set_error(&a->archive,
1396
+ ARCHIVE_ERRNO_MISC,
1397
+ "Internal error initializing "
1398
+ "lzma library");
1399
+ break;
1400
+ }
1401
+ return (ARCHIVE_FATAL);
1402
+ }
1403
+ xar->lzstream_valid = 1;
1404
+ xar->lzstream.total_in = 0;
1405
+ xar->lzstream.total_out = 0;
1406
+ break;
1407
+ #elif defined(HAVE_LZMADEC_H) && defined(HAVE_LIBLZMADEC)
1408
+ case LZMA:
1409
+ if (xar->lzstream_valid)
1410
+ lzmadec_end(&(xar->lzstream));
1411
+ r = lzmadec_init(&(xar->lzstream));
1412
+ if (r != LZMADEC_OK) {
1413
+ switch (r) {
1414
+ case LZMADEC_HEADER_ERROR:
1415
+ archive_set_error(&a->archive,
1416
+ ARCHIVE_ERRNO_MISC,
1417
+ "Internal error initializing "
1418
+ "compression library: "
1419
+ "invalid header");
1420
+ break;
1421
+ case LZMADEC_MEM_ERROR:
1422
+ archive_set_error(&a->archive,
1423
+ ENOMEM,
1424
+ "Internal error initializing "
1425
+ "compression library: "
1426
+ "out of memory");
1427
+ break;
1428
+ }
1429
+ return (ARCHIVE_FATAL);
1430
+ }
1431
+ xar->lzstream_valid = 1;
1432
+ xar->lzstream.total_in = 0;
1433
+ xar->lzstream.total_out = 0;
1434
+ break;
1435
+ #endif
1436
+ /*
1437
+ * Unsupported compression.
1438
+ */
1439
+ default:
1440
+ #if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
1441
+ case BZIP2:
1442
+ #endif
1443
+ #if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
1444
+ #if !defined(HAVE_LZMADEC_H) || !defined(HAVE_LIBLZMADEC)
1445
+ case LZMA:
1446
+ #endif
1447
+ case XZ:
1448
+ #endif
1449
+ switch (xar->entry_encoding) {
1450
+ case BZIP2: detail = "bzip2"; break;
1451
+ case LZMA: detail = "lzma"; break;
1452
+ case XZ: detail = "xz"; break;
1453
+ default: detail = "??"; break;
1454
+ }
1455
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1456
+ "%s compression not supported on this platform",
1457
+ detail);
1458
+ return (ARCHIVE_FAILED);
1459
+ }
1460
+ return (ARCHIVE_OK);
1461
+ }
1462
+
1463
+ static int
1464
+ decompress(struct archive_read *a, const void **buff, size_t *outbytes,
1465
+ const void *b, size_t *used)
1466
+ {
1467
+ struct xar *xar;
1468
+ void *outbuff;
1469
+ size_t avail_in, avail_out;
1470
+ int r;
1471
+
1472
+ xar = (struct xar *)(a->format->data);
1473
+ avail_in = *used;
1474
+ outbuff = (void *)(uintptr_t)*buff;
1475
+ if (outbuff == NULL) {
1476
+ outbuff = xar->buff;
1477
+ *buff = outbuff;
1478
+ avail_out = sizeof(xar->buff);
1479
+ } else
1480
+ avail_out = *outbytes;
1481
+ switch (xar->rd_encoding) {
1482
+ case GZIP:
1483
+ xar->stream.next_in = (Bytef *)(uintptr_t)b;
1484
+ xar->stream.avail_in = avail_in;
1485
+ xar->stream.next_out = (unsigned char *)outbuff;
1486
+ xar->stream.avail_out = avail_out;
1487
+ r = inflate(&(xar->stream), 0);
1488
+ switch (r) {
1489
+ case Z_OK: /* Decompressor made some progress.*/
1490
+ case Z_STREAM_END: /* Found end of stream. */
1491
+ break;
1492
+ default:
1493
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1494
+ "File decompression failed (%d)", r);
1495
+ return (ARCHIVE_FATAL);
1496
+ }
1497
+ *used = avail_in - xar->stream.avail_in;
1498
+ *outbytes = avail_out - xar->stream.avail_out;
1499
+ break;
1500
+ #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1501
+ case BZIP2:
1502
+ xar->bzstream.next_in = (char *)(uintptr_t)b;
1503
+ xar->bzstream.avail_in = avail_in;
1504
+ xar->bzstream.next_out = (char *)outbuff;
1505
+ xar->bzstream.avail_out = avail_out;
1506
+ r = BZ2_bzDecompress(&(xar->bzstream));
1507
+ switch (r) {
1508
+ case BZ_STREAM_END: /* Found end of stream. */
1509
+ switch (BZ2_bzDecompressEnd(&(xar->bzstream))) {
1510
+ case BZ_OK:
1511
+ break;
1512
+ default:
1513
+ archive_set_error(&(a->archive),
1514
+ ARCHIVE_ERRNO_MISC,
1515
+ "Failed to clean up decompressor");
1516
+ return (ARCHIVE_FATAL);
1517
+ }
1518
+ xar->bzstream_valid = 0;
1519
+ /* FALLTHROUGH */
1520
+ case BZ_OK: /* Decompressor made some progress. */
1521
+ break;
1522
+ default:
1523
+ archive_set_error(&(a->archive),
1524
+ ARCHIVE_ERRNO_MISC,
1525
+ "bzip decompression failed");
1526
+ return (ARCHIVE_FATAL);
1527
+ }
1528
+ *used = avail_in - xar->bzstream.avail_in;
1529
+ *outbytes = avail_out - xar->bzstream.avail_out;
1530
+ break;
1531
+ #endif
1532
+ #if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1533
+ case LZMA:
1534
+ case XZ:
1535
+ xar->lzstream.next_in = b;
1536
+ xar->lzstream.avail_in = avail_in;
1537
+ xar->lzstream.next_out = (unsigned char *)outbuff;
1538
+ xar->lzstream.avail_out = avail_out;
1539
+ r = lzma_code(&(xar->lzstream), LZMA_RUN);
1540
+ switch (r) {
1541
+ case LZMA_STREAM_END: /* Found end of stream. */
1542
+ lzma_end(&(xar->lzstream));
1543
+ xar->lzstream_valid = 0;
1544
+ /* FALLTHROUGH */
1545
+ case LZMA_OK: /* Decompressor made some progress. */
1546
+ break;
1547
+ default:
1548
+ archive_set_error(&(a->archive),
1549
+ ARCHIVE_ERRNO_MISC,
1550
+ "%s decompression failed(%d)",
1551
+ (xar->entry_encoding == XZ)?"xz":"lzma",
1552
+ r);
1553
+ return (ARCHIVE_FATAL);
1554
+ }
1555
+ *used = avail_in - xar->lzstream.avail_in;
1556
+ *outbytes = avail_out - xar->lzstream.avail_out;
1557
+ break;
1558
+ #elif defined(HAVE_LZMADEC_H) && defined(HAVE_LIBLZMADEC)
1559
+ case LZMA:
1560
+ xar->lzstream.next_in = (unsigned char *)(uintptr_t)b;
1561
+ xar->lzstream.avail_in = avail_in;
1562
+ xar->lzstream.next_out = (unsigned char *)outbuff;
1563
+ xar->lzstream.avail_out = avail_out;
1564
+ r = lzmadec_decode(&(xar->lzstream), 0);
1565
+ switch (r) {
1566
+ case LZMADEC_STREAM_END: /* Found end of stream. */
1567
+ switch (lzmadec_end(&(xar->lzstream))) {
1568
+ case LZMADEC_OK:
1569
+ break;
1570
+ default:
1571
+ archive_set_error(&(a->archive),
1572
+ ARCHIVE_ERRNO_MISC,
1573
+ "Failed to clean up lzmadec decompressor");
1574
+ return (ARCHIVE_FATAL);
1575
+ }
1576
+ xar->lzstream_valid = 0;
1577
+ /* FALLTHROUGH */
1578
+ case LZMADEC_OK: /* Decompressor made some progress. */
1579
+ break;
1580
+ default:
1581
+ archive_set_error(&(a->archive),
1582
+ ARCHIVE_ERRNO_MISC,
1583
+ "lzmadec decompression failed(%d)",
1584
+ r);
1585
+ return (ARCHIVE_FATAL);
1586
+ }
1587
+ *used = avail_in - xar->lzstream.avail_in;
1588
+ *outbytes = avail_out - xar->lzstream.avail_out;
1589
+ break;
1590
+ #endif
1591
+ #if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
1592
+ case BZIP2:
1593
+ #endif
1594
+ #if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
1595
+ #if !defined(HAVE_LZMADEC_H) || !defined(HAVE_LIBLZMADEC)
1596
+ case LZMA:
1597
+ #endif
1598
+ case XZ:
1599
+ #endif
1600
+ case NONE:
1601
+ default:
1602
+ if (outbuff == xar->buff) {
1603
+ *buff = b;
1604
+ *used = avail_in;
1605
+ *outbytes = avail_in;
1606
+ } else {
1607
+ if (avail_out > avail_in)
1608
+ avail_out = avail_in;
1609
+ memcpy(outbuff, b, avail_out);
1610
+ *used = avail_out;
1611
+ *outbytes = avail_out;
1612
+ }
1613
+ break;
1614
+ }
1615
+ return (ARCHIVE_OK);
1616
+ }
1617
+
1618
+ static int
1619
+ decompression_cleanup(struct archive_read *a)
1620
+ {
1621
+ struct xar *xar;
1622
+ int r;
1623
+
1624
+ xar = (struct xar *)(a->format->data);
1625
+ r = ARCHIVE_OK;
1626
+ if (xar->stream_valid) {
1627
+ if (inflateEnd(&(xar->stream)) != Z_OK) {
1628
+ archive_set_error(&a->archive,
1629
+ ARCHIVE_ERRNO_MISC,
1630
+ "Failed to clean up zlib decompressor");
1631
+ r = ARCHIVE_FATAL;
1632
+ }
1633
+ }
1634
+ #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1635
+ if (xar->bzstream_valid) {
1636
+ if (BZ2_bzDecompressEnd(&(xar->bzstream)) != BZ_OK) {
1637
+ archive_set_error(&a->archive,
1638
+ ARCHIVE_ERRNO_MISC,
1639
+ "Failed to clean up bzip2 decompressor");
1640
+ r = ARCHIVE_FATAL;
1641
+ }
1642
+ }
1643
+ #endif
1644
+ #if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1645
+ if (xar->lzstream_valid)
1646
+ lzma_end(&(xar->lzstream));
1647
+ #elif defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1648
+ if (xar->lzstream_valid) {
1649
+ if (lzmadec_end(&(xar->lzstream)) != LZMADEC_OK) {
1650
+ archive_set_error(&a->archive,
1651
+ ARCHIVE_ERRNO_MISC,
1652
+ "Failed to clean up lzmadec decompressor");
1653
+ r = ARCHIVE_FATAL;
1654
+ }
1655
+ }
1656
+ #endif
1657
+ return (r);
1658
+ }
1659
+
1660
+ static void
1661
+ xmlattr_cleanup(struct xmlattr_list *list)
1662
+ {
1663
+ struct xmlattr *attr, *next;
1664
+
1665
+ attr = list->first;
1666
+ while (attr != NULL) {
1667
+ next = attr->next;
1668
+ free(attr->name);
1669
+ free(attr->value);
1670
+ free(attr);
1671
+ attr = next;
1672
+ }
1673
+ list->first = NULL;
1674
+ list->last = &(list->first);
1675
+ }
1676
+
1677
+ static void
1678
+ file_new(struct xar *xar, struct xmlattr_list *list)
1679
+ {
1680
+ struct xar_file *file;
1681
+ struct xmlattr *attr;
1682
+
1683
+ file = calloc(1, sizeof(*file));
1684
+ if (file == NULL)
1685
+ __archive_errx(1, "Out of memory");
1686
+ file->parent = xar->file;
1687
+ file->mode = 0777 | AE_IFREG;
1688
+ file->atime = time(NULL);
1689
+ file->mtime = time(NULL);
1690
+ xar->file = file;
1691
+ xar->xattr = NULL;
1692
+ for (attr = list->first; attr != NULL; attr = attr->next) {
1693
+ if (strcmp(attr->name, "id") == 0)
1694
+ file->id = atol10(attr->value, strlen(attr->value));
1695
+ }
1696
+ file->nlink = 1;
1697
+ heap_add_entry(&(xar->file_queue), file);
1698
+ }
1699
+
1700
+ static void
1701
+ file_free(struct xar_file *file)
1702
+ {
1703
+ struct xattr *xattr;
1704
+
1705
+ archive_string_free(&(file->pathname));
1706
+ archive_string_free(&(file->symlink));
1707
+ archive_string_free(&(file->uname));
1708
+ archive_string_free(&(file->gname));
1709
+ archive_string_free(&(file->hardlink));
1710
+ xattr = file->xattr_list;
1711
+ while (xattr != NULL) {
1712
+ struct xattr *next;
1713
+
1714
+ next = xattr->next;
1715
+ xattr_free(xattr);
1716
+ xattr = next;
1717
+ }
1718
+
1719
+ free(file);
1720
+ }
1721
+
1722
+ static void
1723
+ xattr_new(struct xar *xar, struct xmlattr_list *list)
1724
+ {
1725
+ struct xattr *xattr, **nx;
1726
+ struct xmlattr *attr;
1727
+
1728
+ xattr = calloc(1, sizeof(*xattr));
1729
+ if (xattr == NULL)
1730
+ __archive_errx(1, "Out of memory");
1731
+ xar->xattr = xattr;
1732
+ for (attr = list->first; attr != NULL; attr = attr->next) {
1733
+ if (strcmp(attr->name, "id") == 0)
1734
+ xattr->id = atol10(attr->value, strlen(attr->value));
1735
+ }
1736
+ /* Chain to xattr list. */
1737
+ for (nx = &(xar->file->xattr_list);
1738
+ *nx != NULL; nx = &((*nx)->next)) {
1739
+ if (xattr->id < (*nx)->id)
1740
+ break;
1741
+ }
1742
+ xattr->next = *nx;
1743
+ *nx = xattr;
1744
+ }
1745
+
1746
+ static void
1747
+ xattr_free(struct xattr *xattr)
1748
+ {
1749
+ archive_string_free(&(xattr->name));
1750
+ free(xattr);
1751
+ }
1752
+
1753
+ static int
1754
+ getencoding(struct xmlattr_list *list)
1755
+ {
1756
+ struct xmlattr *attr;
1757
+ enum enctype encoding = NONE;
1758
+
1759
+ for (attr = list->first; attr != NULL; attr = attr->next) {
1760
+ if (strcmp(attr->name, "style") == 0) {
1761
+ if (strcmp(attr->value, "application/octet-stream") == 0)
1762
+ encoding = NONE;
1763
+ else if (strcmp(attr->value, "application/x-gzip") == 0)
1764
+ encoding = GZIP;
1765
+ else if (strcmp(attr->value, "application/x-bzip2") == 0)
1766
+ encoding = BZIP2;
1767
+ else if (strcmp(attr->value, "application/x-lzma") == 0)
1768
+ encoding = LZMA;
1769
+ else if (strcmp(attr->value, "application/x-xz") == 0)
1770
+ encoding = XZ;
1771
+ }
1772
+ }
1773
+ return (encoding);
1774
+ }
1775
+
1776
+ static int
1777
+ getsumalgorithm(struct xmlattr_list *list)
1778
+ {
1779
+ struct xmlattr *attr;
1780
+ int alg = CKSUM_NONE;
1781
+
1782
+ for (attr = list->first; attr != NULL; attr = attr->next) {
1783
+ if (strcmp(attr->name, "style") == 0) {
1784
+ const char *v = attr->value;
1785
+ if ((v[0] == 'S' || v[0] == 's') &&
1786
+ (v[1] == 'H' || v[1] == 'h') &&
1787
+ (v[2] == 'A' || v[2] == 'a') &&
1788
+ v[3] == '1' && v[4] == '\0')
1789
+ alg = CKSUM_SHA1;
1790
+ if ((v[0] == 'M' || v[0] == 'm') &&
1791
+ (v[1] == 'D' || v[1] == 'd') &&
1792
+ v[2] == '5' && v[3] == '\0')
1793
+ alg = CKSUM_MD5;
1794
+ }
1795
+ }
1796
+ return (alg);
1797
+ }
1798
+
1799
+ static void
1800
+ unknowntag_start(struct xar *xar, const char *name)
1801
+ {
1802
+ struct unknown_tag *tag;
1803
+
1804
+ #if DEBUG
1805
+ fprintf(stderr, "unknowntag_start:%s\n", name);
1806
+ #endif
1807
+ tag = malloc(sizeof(*tag));
1808
+ if (tag == NULL)
1809
+ __archive_errx(1, "Out of memory");
1810
+ tag->next = xar->unknowntags;
1811
+ archive_string_init(&(tag->name));
1812
+ archive_strcpy(&(tag->name), name);
1813
+ if (xar->unknowntags == NULL) {
1814
+ xar->xmlsts_unknown = xar->xmlsts;
1815
+ xar->xmlsts = UNKNOWN;
1816
+ }
1817
+ xar->unknowntags = tag;
1818
+ }
1819
+
1820
+ static void
1821
+ unknowntag_end(struct xar *xar, const char *name)
1822
+ {
1823
+ struct unknown_tag *tag;
1824
+
1825
+ #if DEBUG
1826
+ fprintf(stderr, "unknowntag_end:%s\n", name);
1827
+ #endif
1828
+ tag = xar->unknowntags;
1829
+ if (tag == NULL || name == NULL)
1830
+ return;
1831
+ if (strcmp(tag->name.s, name) == 0) {
1832
+ xar->unknowntags = tag->next;
1833
+ archive_string_free(&(tag->name));
1834
+ free(tag);
1835
+ if (xar->unknowntags == NULL)
1836
+ xar->xmlsts = xar->xmlsts_unknown;
1837
+ }
1838
+ }
1839
+
1840
+ static void
1841
+ xml_start(void *userData, const char *name, struct xmlattr_list *list)
1842
+ {
1843
+ struct archive_read *a;
1844
+ struct xar *xar;
1845
+ struct xmlattr *attr;
1846
+
1847
+ a = (struct archive_read *)userData;
1848
+ xar = (struct xar *)(a->format->data);
1849
+
1850
+ #if DEBUG
1851
+ fprintf(stderr, "xml_sta:[%s]\n", name);
1852
+ for (attr = list->first; attr != NULL; attr = attr->next)
1853
+ fprintf(stderr, " attr:\"%s\"=\"%s\"\n",
1854
+ attr->name, attr->value);
1855
+ #endif
1856
+ xar->base64text = 0;
1857
+ switch (xar->xmlsts) {
1858
+ case INIT:
1859
+ if (strcmp(name, "xar") == 0)
1860
+ xar->xmlsts = XAR;
1861
+ else
1862
+ unknowntag_start(xar, name);
1863
+ break;
1864
+ case XAR:
1865
+ if (strcmp(name, "toc") == 0)
1866
+ xar->xmlsts = TOC;
1867
+ else
1868
+ unknowntag_start(xar, name);
1869
+ break;
1870
+ case TOC:
1871
+ if (strcmp(name, "creation-time") == 0)
1872
+ xar->xmlsts = TOC_CREATION_TIME;
1873
+ else if (strcmp(name, "checksum") == 0)
1874
+ xar->xmlsts = TOC_CHECKSUM;
1875
+ else if (strcmp(name, "file") == 0) {
1876
+ file_new(xar, list);
1877
+ xar->xmlsts = TOC_FILE;
1878
+ }
1879
+ else
1880
+ unknowntag_start(xar, name);
1881
+ break;
1882
+ case TOC_CHECKSUM:
1883
+ if (strcmp(name, "offset") == 0)
1884
+ xar->xmlsts = TOC_CHECKSUM_OFFSET;
1885
+ else if (strcmp(name, "size") == 0)
1886
+ xar->xmlsts = TOC_CHECKSUM_SIZE;
1887
+ else
1888
+ unknowntag_start(xar, name);
1889
+ break;
1890
+ case TOC_FILE:
1891
+ if (strcmp(name, "file") == 0) {
1892
+ file_new(xar, list);
1893
+ }
1894
+ else if (strcmp(name, "data") == 0)
1895
+ xar->xmlsts = FILE_DATA;
1896
+ else if (strcmp(name, "ea") == 0) {
1897
+ xattr_new(xar, list);
1898
+ xar->xmlsts = FILE_EA;
1899
+ }
1900
+ else if (strcmp(name, "ctime") == 0)
1901
+ xar->xmlsts = FILE_CTIME;
1902
+ else if (strcmp(name, "mtime") == 0)
1903
+ xar->xmlsts = FILE_MTIME;
1904
+ else if (strcmp(name, "atime") == 0)
1905
+ xar->xmlsts = FILE_ATIME;
1906
+ else if (strcmp(name, "group") == 0)
1907
+ xar->xmlsts = FILE_GROUP;
1908
+ else if (strcmp(name, "gid") == 0)
1909
+ xar->xmlsts = FILE_GID;
1910
+ else if (strcmp(name, "user") == 0)
1911
+ xar->xmlsts = FILE_USER;
1912
+ else if (strcmp(name, "uid") == 0)
1913
+ xar->xmlsts = FILE_UID;
1914
+ else if (strcmp(name, "mode") == 0)
1915
+ xar->xmlsts = FILE_MODE;
1916
+ else if (strcmp(name, "device") == 0)
1917
+ xar->xmlsts = FILE_DEVICE;
1918
+ else if (strcmp(name, "deviceno") == 0)
1919
+ xar->xmlsts = FILE_DEVICENO;
1920
+ else if (strcmp(name, "inode") == 0)
1921
+ xar->xmlsts = FILE_INODE;
1922
+ else if (strcmp(name, "link") == 0)
1923
+ xar->xmlsts = FILE_LINK;
1924
+ else if (strcmp(name, "type") == 0) {
1925
+ xar->xmlsts = FILE_TYPE;
1926
+ for (attr = list->first; attr != NULL;
1927
+ attr = attr->next) {
1928
+ if (strcmp(attr->name, "link") != 0)
1929
+ continue;
1930
+ if (strcmp(attr->value, "original") == 0) {
1931
+ xar->file->hdnext = xar->hdlink_orgs;
1932
+ xar->hdlink_orgs = xar->file;
1933
+ } else {
1934
+ xar->file->link = atol10(attr->value,
1935
+ strlen(attr->value));
1936
+ if (xar->file->link > 0)
1937
+ add_link(xar, xar->file);
1938
+ }
1939
+ }
1940
+ }
1941
+ else if (strcmp(name, "name") == 0) {
1942
+ xar->xmlsts = FILE_NAME;
1943
+ for (attr = list->first; attr != NULL;
1944
+ attr = attr->next) {
1945
+ if (strcmp(attr->name, "enctype") == 0 &&
1946
+ strcmp(attr->value, "base64") == 0)
1947
+ xar->base64text = 1;
1948
+ }
1949
+ }
1950
+ else if (strcmp(name, "acl") == 0)
1951
+ xar->xmlsts = FILE_ACL;
1952
+ else if (strcmp(name, "flags") == 0)
1953
+ xar->xmlsts = FILE_FLAGS;
1954
+ else if (strcmp(name, "ext2") == 0)
1955
+ xar->xmlsts = FILE_EXT2;
1956
+ else
1957
+ unknowntag_start(xar, name);
1958
+ break;
1959
+ case FILE_DATA:
1960
+ if (strcmp(name, "length") == 0)
1961
+ xar->xmlsts = FILE_DATA_LENGTH;
1962
+ else if (strcmp(name, "offset") == 0)
1963
+ xar->xmlsts = FILE_DATA_OFFSET;
1964
+ else if (strcmp(name, "size") == 0)
1965
+ xar->xmlsts = FILE_DATA_SIZE;
1966
+ else if (strcmp(name, "encoding") == 0) {
1967
+ xar->xmlsts = FILE_DATA_ENCODING;
1968
+ xar->file->encoding = getencoding(list);
1969
+ }
1970
+ else if (strcmp(name, "archived-checksum") == 0) {
1971
+ xar->xmlsts = FILE_DATA_A_CHECKSUM;
1972
+ xar->file->a_sum.alg = getsumalgorithm(list);
1973
+ }
1974
+ else if (strcmp(name, "extracted-checksum") == 0) {
1975
+ xar->xmlsts = FILE_DATA_E_CHECKSUM;
1976
+ xar->file->e_sum.alg = getsumalgorithm(list);
1977
+ }
1978
+ else if (strcmp(name, "content") == 0)
1979
+ xar->xmlsts = FILE_DATA_CONTENT;
1980
+ else
1981
+ unknowntag_start(xar, name);
1982
+ break;
1983
+ case FILE_DEVICE:
1984
+ if (strcmp(name, "major") == 0)
1985
+ xar->xmlsts = FILE_DEVICE_MAJOR;
1986
+ else if (strcmp(name, "minor") == 0)
1987
+ xar->xmlsts = FILE_DEVICE_MINOR;
1988
+ else
1989
+ unknowntag_start(xar, name);
1990
+ break;
1991
+ case FILE_DATA_CONTENT:
1992
+ unknowntag_start(xar, name);
1993
+ break;
1994
+ case FILE_EA:
1995
+ if (strcmp(name, "length") == 0)
1996
+ xar->xmlsts = FILE_EA_LENGTH;
1997
+ else if (strcmp(name, "offset") == 0)
1998
+ xar->xmlsts = FILE_EA_OFFSET;
1999
+ else if (strcmp(name, "size") == 0)
2000
+ xar->xmlsts = FILE_EA_SIZE;
2001
+ else if (strcmp(name, "encoding") == 0) {
2002
+ xar->xmlsts = FILE_EA_ENCODING;
2003
+ xar->xattr->encoding = getencoding(list);
2004
+ } else if (strcmp(name, "archived-checksum") == 0)
2005
+ xar->xmlsts = FILE_EA_A_CHECKSUM;
2006
+ else if (strcmp(name, "extracted-checksum") == 0)
2007
+ xar->xmlsts = FILE_EA_E_CHECKSUM;
2008
+ else if (strcmp(name, "name") == 0)
2009
+ xar->xmlsts = FILE_EA_NAME;
2010
+ else if (strcmp(name, "fstype") == 0)
2011
+ xar->xmlsts = FILE_EA_FSTYPE;
2012
+ else
2013
+ unknowntag_start(xar, name);
2014
+ break;
2015
+ case FILE_ACL:
2016
+ if (strcmp(name, "appleextended") == 0)
2017
+ xar->xmlsts = FILE_ACL_APPLEEXTENDED;
2018
+ if (strcmp(name, "default") == 0)
2019
+ xar->xmlsts = FILE_ACL_DEFAULT;
2020
+ else if (strcmp(name, "access") == 0)
2021
+ xar->xmlsts = FILE_ACL_ACCESS;
2022
+ else
2023
+ unknowntag_start(xar, name);
2024
+ break;
2025
+ case FILE_FLAGS:
2026
+ if (!xml_parse_file_flags(xar, name))
2027
+ unknowntag_start(xar, name);
2028
+ break;
2029
+ case FILE_EXT2:
2030
+ if (!xml_parse_file_ext2(xar, name))
2031
+ unknowntag_start(xar, name);
2032
+ break;
2033
+ case TOC_CREATION_TIME:
2034
+ case TOC_CHECKSUM_OFFSET:
2035
+ case TOC_CHECKSUM_SIZE:
2036
+ case FILE_DATA_LENGTH:
2037
+ case FILE_DATA_OFFSET:
2038
+ case FILE_DATA_SIZE:
2039
+ case FILE_DATA_ENCODING:
2040
+ case FILE_DATA_A_CHECKSUM:
2041
+ case FILE_DATA_E_CHECKSUM:
2042
+ case FILE_EA_LENGTH:
2043
+ case FILE_EA_OFFSET:
2044
+ case FILE_EA_SIZE:
2045
+ case FILE_EA_ENCODING:
2046
+ case FILE_EA_A_CHECKSUM:
2047
+ case FILE_EA_E_CHECKSUM:
2048
+ case FILE_EA_NAME:
2049
+ case FILE_EA_FSTYPE:
2050
+ case FILE_CTIME:
2051
+ case FILE_MTIME:
2052
+ case FILE_ATIME:
2053
+ case FILE_GROUP:
2054
+ case FILE_GID:
2055
+ case FILE_USER:
2056
+ case FILE_UID:
2057
+ case FILE_INODE:
2058
+ case FILE_DEVICE_MAJOR:
2059
+ case FILE_DEVICE_MINOR:
2060
+ case FILE_DEVICENO:
2061
+ case FILE_MODE:
2062
+ case FILE_TYPE:
2063
+ case FILE_LINK:
2064
+ case FILE_NAME:
2065
+ case FILE_ACL_DEFAULT:
2066
+ case FILE_ACL_ACCESS:
2067
+ case FILE_ACL_APPLEEXTENDED:
2068
+ case FILE_FLAGS_USER_NODUMP:
2069
+ case FILE_FLAGS_USER_IMMUTABLE:
2070
+ case FILE_FLAGS_USER_APPEND:
2071
+ case FILE_FLAGS_USER_OPAQUE:
2072
+ case FILE_FLAGS_USER_NOUNLINK:
2073
+ case FILE_FLAGS_SYS_ARCHIVED:
2074
+ case FILE_FLAGS_SYS_IMMUTABLE:
2075
+ case FILE_FLAGS_SYS_APPEND:
2076
+ case FILE_FLAGS_SYS_NOUNLINK:
2077
+ case FILE_FLAGS_SYS_SNAPSHOT:
2078
+ case FILE_EXT2_SecureDeletion:
2079
+ case FILE_EXT2_Undelete:
2080
+ case FILE_EXT2_Compress:
2081
+ case FILE_EXT2_Synchronous:
2082
+ case FILE_EXT2_Immutable:
2083
+ case FILE_EXT2_AppendOnly:
2084
+ case FILE_EXT2_NoDump:
2085
+ case FILE_EXT2_NoAtime:
2086
+ case FILE_EXT2_CompDirty:
2087
+ case FILE_EXT2_CompBlock:
2088
+ case FILE_EXT2_NoCompBlock:
2089
+ case FILE_EXT2_CompError:
2090
+ case FILE_EXT2_BTree:
2091
+ case FILE_EXT2_HashIndexed:
2092
+ case FILE_EXT2_iMagic:
2093
+ case FILE_EXT2_Journaled:
2094
+ case FILE_EXT2_NoTail:
2095
+ case FILE_EXT2_DirSync:
2096
+ case FILE_EXT2_TopDir:
2097
+ case FILE_EXT2_Reserved:
2098
+ case UNKNOWN:
2099
+ unknowntag_start(xar, name);
2100
+ break;
2101
+ }
2102
+ }
2103
+
2104
+ static void
2105
+ xml_end(void *userData, const char *name)
2106
+ {
2107
+ struct archive_read *a;
2108
+ struct xar *xar;
2109
+
2110
+ a = (struct archive_read *)userData;
2111
+ xar = (struct xar *)(a->format->data);
2112
+
2113
+ #if DEBUG
2114
+ fprintf(stderr, "xml_end:[%s]\n", name);
2115
+ #endif
2116
+ switch (xar->xmlsts) {
2117
+ case INIT:
2118
+ break;
2119
+ case XAR:
2120
+ if (strcmp(name, "xar") == 0)
2121
+ xar->xmlsts = INIT;
2122
+ break;
2123
+ case TOC:
2124
+ if (strcmp(name, "toc") == 0)
2125
+ xar->xmlsts = XAR;
2126
+ break;
2127
+ case TOC_CREATION_TIME:
2128
+ if (strcmp(name, "creation-time") == 0)
2129
+ xar->xmlsts = TOC;
2130
+ break;
2131
+ case TOC_CHECKSUM:
2132
+ if (strcmp(name, "checksum") == 0)
2133
+ xar->xmlsts = TOC;
2134
+ break;
2135
+ case TOC_CHECKSUM_OFFSET:
2136
+ if (strcmp(name, "offset") == 0)
2137
+ xar->xmlsts = TOC_CHECKSUM;
2138
+ break;
2139
+ case TOC_CHECKSUM_SIZE:
2140
+ if (strcmp(name, "size") == 0)
2141
+ xar->xmlsts = TOC_CHECKSUM;
2142
+ break;
2143
+ case TOC_FILE:
2144
+ if (strcmp(name, "file") == 0) {
2145
+ if (xar->file->parent != NULL &&
2146
+ ((xar->file->mode & AE_IFMT) == AE_IFDIR))
2147
+ xar->file->parent->subdirs++;
2148
+ xar->file = xar->file->parent;
2149
+ if (xar->file == NULL)
2150
+ xar->xmlsts = TOC;
2151
+ }
2152
+ break;
2153
+ case FILE_DATA:
2154
+ if (strcmp(name, "data") == 0)
2155
+ xar->xmlsts = TOC_FILE;
2156
+ break;
2157
+ case FILE_DATA_LENGTH:
2158
+ if (strcmp(name, "length") == 0)
2159
+ xar->xmlsts = FILE_DATA;
2160
+ break;
2161
+ case FILE_DATA_OFFSET:
2162
+ if (strcmp(name, "offset") == 0)
2163
+ xar->xmlsts = FILE_DATA;
2164
+ break;
2165
+ case FILE_DATA_SIZE:
2166
+ if (strcmp(name, "size") == 0)
2167
+ xar->xmlsts = FILE_DATA;
2168
+ break;
2169
+ case FILE_DATA_ENCODING:
2170
+ if (strcmp(name, "encoding") == 0)
2171
+ xar->xmlsts = FILE_DATA;
2172
+ break;
2173
+ case FILE_DATA_A_CHECKSUM:
2174
+ if (strcmp(name, "archived-checksum") == 0)
2175
+ xar->xmlsts = FILE_DATA;
2176
+ break;
2177
+ case FILE_DATA_E_CHECKSUM:
2178
+ if (strcmp(name, "extracted-checksum") == 0)
2179
+ xar->xmlsts = FILE_DATA;
2180
+ break;
2181
+ case FILE_DATA_CONTENT:
2182
+ if (strcmp(name, "content") == 0)
2183
+ xar->xmlsts = FILE_DATA;
2184
+ break;
2185
+ case FILE_EA:
2186
+ if (strcmp(name, "ea") == 0) {
2187
+ xar->xmlsts = TOC_FILE;
2188
+ xar->xattr = NULL;
2189
+ }
2190
+ break;
2191
+ case FILE_EA_LENGTH:
2192
+ if (strcmp(name, "length") == 0)
2193
+ xar->xmlsts = FILE_EA;
2194
+ break;
2195
+ case FILE_EA_OFFSET:
2196
+ if (strcmp(name, "offset") == 0)
2197
+ xar->xmlsts = FILE_EA;
2198
+ break;
2199
+ case FILE_EA_SIZE:
2200
+ if (strcmp(name, "size") == 0)
2201
+ xar->xmlsts = FILE_EA;
2202
+ break;
2203
+ case FILE_EA_ENCODING:
2204
+ if (strcmp(name, "encoding") == 0)
2205
+ xar->xmlsts = FILE_EA;
2206
+ break;
2207
+ case FILE_EA_A_CHECKSUM:
2208
+ if (strcmp(name, "archived-checksum") == 0)
2209
+ xar->xmlsts = FILE_EA;
2210
+ break;
2211
+ case FILE_EA_E_CHECKSUM:
2212
+ if (strcmp(name, "extracted-checksum") == 0)
2213
+ xar->xmlsts = FILE_EA;
2214
+ break;
2215
+ case FILE_EA_NAME:
2216
+ if (strcmp(name, "name") == 0)
2217
+ xar->xmlsts = FILE_EA;
2218
+ break;
2219
+ case FILE_EA_FSTYPE:
2220
+ if (strcmp(name, "fstype") == 0)
2221
+ xar->xmlsts = FILE_EA;
2222
+ break;
2223
+ case FILE_CTIME:
2224
+ if (strcmp(name, "ctime") == 0)
2225
+ xar->xmlsts = TOC_FILE;
2226
+ break;
2227
+ case FILE_MTIME:
2228
+ if (strcmp(name, "mtime") == 0)
2229
+ xar->xmlsts = TOC_FILE;
2230
+ break;
2231
+ case FILE_ATIME:
2232
+ if (strcmp(name, "atime") == 0)
2233
+ xar->xmlsts = TOC_FILE;
2234
+ break;
2235
+ case FILE_GROUP:
2236
+ if (strcmp(name, "group") == 0)
2237
+ xar->xmlsts = TOC_FILE;
2238
+ break;
2239
+ case FILE_GID:
2240
+ if (strcmp(name, "gid") == 0)
2241
+ xar->xmlsts = TOC_FILE;
2242
+ break;
2243
+ case FILE_USER:
2244
+ if (strcmp(name, "user") == 0)
2245
+ xar->xmlsts = TOC_FILE;
2246
+ break;
2247
+ case FILE_UID:
2248
+ if (strcmp(name, "uid") == 0)
2249
+ xar->xmlsts = TOC_FILE;
2250
+ break;
2251
+ case FILE_MODE:
2252
+ if (strcmp(name, "mode") == 0)
2253
+ xar->xmlsts = TOC_FILE;
2254
+ break;
2255
+ case FILE_DEVICE:
2256
+ if (strcmp(name, "device") == 0)
2257
+ xar->xmlsts = TOC_FILE;
2258
+ break;
2259
+ case FILE_DEVICE_MAJOR:
2260
+ if (strcmp(name, "major") == 0)
2261
+ xar->xmlsts = FILE_DEVICE;
2262
+ break;
2263
+ case FILE_DEVICE_MINOR:
2264
+ if (strcmp(name, "minor") == 0)
2265
+ xar->xmlsts = FILE_DEVICE;
2266
+ break;
2267
+ case FILE_DEVICENO:
2268
+ if (strcmp(name, "deviceno") == 0)
2269
+ xar->xmlsts = TOC_FILE;
2270
+ break;
2271
+ case FILE_INODE:
2272
+ if (strcmp(name, "inode") == 0)
2273
+ xar->xmlsts = TOC_FILE;
2274
+ break;
2275
+ case FILE_LINK:
2276
+ if (strcmp(name, "link") == 0)
2277
+ xar->xmlsts = TOC_FILE;
2278
+ break;
2279
+ case FILE_TYPE:
2280
+ if (strcmp(name, "type") == 0)
2281
+ xar->xmlsts = TOC_FILE;
2282
+ break;
2283
+ case FILE_NAME:
2284
+ if (strcmp(name, "name") == 0)
2285
+ xar->xmlsts = TOC_FILE;
2286
+ break;
2287
+ case FILE_ACL:
2288
+ if (strcmp(name, "acl") == 0)
2289
+ xar->xmlsts = TOC_FILE;
2290
+ break;
2291
+ case FILE_ACL_DEFAULT:
2292
+ if (strcmp(name, "default") == 0)
2293
+ xar->xmlsts = FILE_ACL;
2294
+ break;
2295
+ case FILE_ACL_ACCESS:
2296
+ if (strcmp(name, "access") == 0)
2297
+ xar->xmlsts = FILE_ACL;
2298
+ break;
2299
+ case FILE_ACL_APPLEEXTENDED:
2300
+ if (strcmp(name, "appleextended") == 0)
2301
+ xar->xmlsts = FILE_ACL;
2302
+ break;
2303
+ case FILE_FLAGS:
2304
+ if (strcmp(name, "flags") == 0)
2305
+ xar->xmlsts = TOC_FILE;
2306
+ break;
2307
+ case FILE_FLAGS_USER_NODUMP:
2308
+ if (strcmp(name, "UserNoDump") == 0)
2309
+ xar->xmlsts = FILE_FLAGS;
2310
+ break;
2311
+ case FILE_FLAGS_USER_IMMUTABLE:
2312
+ if (strcmp(name, "UserImmutable") == 0)
2313
+ xar->xmlsts = FILE_FLAGS;
2314
+ break;
2315
+ case FILE_FLAGS_USER_APPEND:
2316
+ if (strcmp(name, "UserAppend") == 0)
2317
+ xar->xmlsts = FILE_FLAGS;
2318
+ break;
2319
+ case FILE_FLAGS_USER_OPAQUE:
2320
+ if (strcmp(name, "UserOpaque") == 0)
2321
+ xar->xmlsts = FILE_FLAGS;
2322
+ break;
2323
+ case FILE_FLAGS_USER_NOUNLINK:
2324
+ if (strcmp(name, "UserNoUnlink") == 0)
2325
+ xar->xmlsts = FILE_FLAGS;
2326
+ break;
2327
+ case FILE_FLAGS_SYS_ARCHIVED:
2328
+ if (strcmp(name, "SystemArchived") == 0)
2329
+ xar->xmlsts = FILE_FLAGS;
2330
+ break;
2331
+ case FILE_FLAGS_SYS_IMMUTABLE:
2332
+ if (strcmp(name, "SystemImmutable") == 0)
2333
+ xar->xmlsts = FILE_FLAGS;
2334
+ break;
2335
+ case FILE_FLAGS_SYS_APPEND:
2336
+ if (strcmp(name, "SystemAppend") == 0)
2337
+ xar->xmlsts = FILE_FLAGS;
2338
+ break;
2339
+ case FILE_FLAGS_SYS_NOUNLINK:
2340
+ if (strcmp(name, "SystemNoUnlink") == 0)
2341
+ xar->xmlsts = FILE_FLAGS;
2342
+ break;
2343
+ case FILE_FLAGS_SYS_SNAPSHOT:
2344
+ if (strcmp(name, "SystemSnapshot") == 0)
2345
+ xar->xmlsts = FILE_FLAGS;
2346
+ break;
2347
+ case FILE_EXT2:
2348
+ if (strcmp(name, "ext2") == 0)
2349
+ xar->xmlsts = TOC_FILE;
2350
+ break;
2351
+ case FILE_EXT2_SecureDeletion:
2352
+ if (strcmp(name, "SecureDeletion") == 0)
2353
+ xar->xmlsts = FILE_EXT2;
2354
+ break;
2355
+ case FILE_EXT2_Undelete:
2356
+ if (strcmp(name, "Undelete") == 0)
2357
+ xar->xmlsts = FILE_EXT2;
2358
+ break;
2359
+ case FILE_EXT2_Compress:
2360
+ if (strcmp(name, "Compress") == 0)
2361
+ xar->xmlsts = FILE_EXT2;
2362
+ break;
2363
+ case FILE_EXT2_Synchronous:
2364
+ if (strcmp(name, "Synchronous") == 0)
2365
+ xar->xmlsts = FILE_EXT2;
2366
+ break;
2367
+ case FILE_EXT2_Immutable:
2368
+ if (strcmp(name, "Immutable") == 0)
2369
+ xar->xmlsts = FILE_EXT2;
2370
+ break;
2371
+ case FILE_EXT2_AppendOnly:
2372
+ if (strcmp(name, "AppendOnly") == 0)
2373
+ xar->xmlsts = FILE_EXT2;
2374
+ break;
2375
+ case FILE_EXT2_NoDump:
2376
+ if (strcmp(name, "NoDump") == 0)
2377
+ xar->xmlsts = FILE_EXT2;
2378
+ break;
2379
+ case FILE_EXT2_NoAtime:
2380
+ if (strcmp(name, "NoAtime") == 0)
2381
+ xar->xmlsts = FILE_EXT2;
2382
+ break;
2383
+ case FILE_EXT2_CompDirty:
2384
+ if (strcmp(name, "CompDirty") == 0)
2385
+ xar->xmlsts = FILE_EXT2;
2386
+ break;
2387
+ case FILE_EXT2_CompBlock:
2388
+ if (strcmp(name, "CompBlock") == 0)
2389
+ xar->xmlsts = FILE_EXT2;
2390
+ break;
2391
+ case FILE_EXT2_NoCompBlock:
2392
+ if (strcmp(name, "NoCompBlock") == 0)
2393
+ xar->xmlsts = FILE_EXT2;
2394
+ break;
2395
+ case FILE_EXT2_CompError:
2396
+ if (strcmp(name, "CompError") == 0)
2397
+ xar->xmlsts = FILE_EXT2;
2398
+ break;
2399
+ case FILE_EXT2_BTree:
2400
+ if (strcmp(name, "BTree") == 0)
2401
+ xar->xmlsts = FILE_EXT2;
2402
+ break;
2403
+ case FILE_EXT2_HashIndexed:
2404
+ if (strcmp(name, "HashIndexed") == 0)
2405
+ xar->xmlsts = FILE_EXT2;
2406
+ break;
2407
+ case FILE_EXT2_iMagic:
2408
+ if (strcmp(name, "iMagic") == 0)
2409
+ xar->xmlsts = FILE_EXT2;
2410
+ break;
2411
+ case FILE_EXT2_Journaled:
2412
+ if (strcmp(name, "Journaled") == 0)
2413
+ xar->xmlsts = FILE_EXT2;
2414
+ break;
2415
+ case FILE_EXT2_NoTail:
2416
+ if (strcmp(name, "NoTail") == 0)
2417
+ xar->xmlsts = FILE_EXT2;
2418
+ break;
2419
+ case FILE_EXT2_DirSync:
2420
+ if (strcmp(name, "DirSync") == 0)
2421
+ xar->xmlsts = FILE_EXT2;
2422
+ break;
2423
+ case FILE_EXT2_TopDir:
2424
+ if (strcmp(name, "TopDir") == 0)
2425
+ xar->xmlsts = FILE_EXT2;
2426
+ break;
2427
+ case FILE_EXT2_Reserved:
2428
+ if (strcmp(name, "Reserved") == 0)
2429
+ xar->xmlsts = FILE_EXT2;
2430
+ break;
2431
+ case UNKNOWN:
2432
+ unknowntag_end(xar, name);
2433
+ break;
2434
+ }
2435
+ }
2436
+
2437
+ static const int base64[256] = {
2438
+ -1, -1, -1, -1, -1, -1, -1, -1,
2439
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 00 - 0F */
2440
+ -1, -1, -1, -1, -1, -1, -1, -1,
2441
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 10 - 1F */
2442
+ -1, -1, -1, -1, -1, -1, -1, -1,
2443
+ -1, -1, -1, 62, -1, -1, -1, 63, /* 20 - 2F */
2444
+ 52, 53, 54, 55, 56, 57, 58, 59,
2445
+ 60, 61, -1, -1, -1, -1, -1, -1, /* 30 - 3F */
2446
+ -1, 0, 1, 2, 3, 4, 5, 6,
2447
+ 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */
2448
+ 15, 16, 17, 18, 19, 20, 21, 22,
2449
+ 23, 24, 25, -1, -1, -1, -1, -1, /* 50 - 5F */
2450
+ -1, 26, 27, 28, 29, 30, 31, 32,
2451
+ 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */
2452
+ 41, 42, 43, 44, 45, 46, 47, 48,
2453
+ 49, 50, 51, -1, -1, -1, -1, -1, /* 70 - 7F */
2454
+ -1, -1, -1, -1, -1, -1, -1, -1,
2455
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 8F */
2456
+ -1, -1, -1, -1, -1, -1, -1, -1,
2457
+ -1, -1, -1, -1, -1, -1, -1, -1, /* 90 - 9F */
2458
+ -1, -1, -1, -1, -1, -1, -1, -1,
2459
+ -1, -1, -1, -1, -1, -1, -1, -1, /* A0 - AF */
2460
+ -1, -1, -1, -1, -1, -1, -1, -1,
2461
+ -1, -1, -1, -1, -1, -1, -1, -1, /* B0 - BF */
2462
+ -1, -1, -1, -1, -1, -1, -1, -1,
2463
+ -1, -1, -1, -1, -1, -1, -1, -1, /* C0 - CF */
2464
+ -1, -1, -1, -1, -1, -1, -1, -1,
2465
+ -1, -1, -1, -1, -1, -1, -1, -1, /* D0 - DF */
2466
+ -1, -1, -1, -1, -1, -1, -1, -1,
2467
+ -1, -1, -1, -1, -1, -1, -1, -1, /* E0 - EF */
2468
+ -1, -1, -1, -1, -1, -1, -1, -1,
2469
+ -1, -1, -1, -1, -1, -1, -1, -1, /* F0 - FF */
2470
+ };
2471
+
2472
+ static void
2473
+ strappend_base64(struct archive_string *as, const char *s, size_t l)
2474
+ {
2475
+ unsigned char buff[256];
2476
+ unsigned char *out;
2477
+ const unsigned char *b;
2478
+ size_t len;
2479
+
2480
+ len = 0;
2481
+ out = buff;
2482
+ b = (const unsigned char *)s;
2483
+ while (l > 0) {
2484
+ int n = 0;
2485
+
2486
+ if (l > 0) {
2487
+ if (base64[b[0]] < 0 || base64[b[1]] < 0)
2488
+ break;
2489
+ n = base64[*b++] << 18;
2490
+ n |= base64[*b++] << 12;
2491
+ *out++ = n >> 16;
2492
+ len++;
2493
+ l -= 2;
2494
+ }
2495
+ if (l > 0) {
2496
+ if (base64[*b] < 0)
2497
+ break;
2498
+ n |= base64[*b++] << 6;
2499
+ *out++ = (n >> 8) & 0xFF;
2500
+ len++;
2501
+ --l;
2502
+ }
2503
+ if (l > 0) {
2504
+ if (base64[*b] < 0)
2505
+ break;
2506
+ n |= base64[*b++];
2507
+ *out++ = n & 0xFF;
2508
+ len++;
2509
+ --l;
2510
+ }
2511
+ if (len+3 >= sizeof(buff)) {
2512
+ archive_strncat(as, (const char *)buff, len);
2513
+ len = 0;
2514
+ out = buff;
2515
+ }
2516
+ }
2517
+ if (len > 0)
2518
+ archive_strncat(as, (const char *)buff, len);
2519
+ }
2520
+
2521
+ static void
2522
+ xml_data(void *userData, const char *s, int len)
2523
+ {
2524
+ struct archive_read *a;
2525
+ struct xar *xar;
2526
+
2527
+ a = (struct archive_read *)userData;
2528
+ xar = (struct xar *)(a->format->data);
2529
+
2530
+ #if DEBUG
2531
+ {
2532
+ char buff[1024];
2533
+ if (len > sizeof(buff)-1)
2534
+ len = sizeof(buff)-1;
2535
+ memcpy(buff, s, len);
2536
+ buff[len] = 0;
2537
+ fprintf(stderr, "\tlen=%d:\"%s\"\n", len, buff);
2538
+ }
2539
+ #endif
2540
+ switch (xar->xmlsts) {
2541
+ case TOC_CHECKSUM_OFFSET:
2542
+ xar->toc_chksum_offset = atol10(s, len);
2543
+ break;
2544
+ case TOC_CHECKSUM_SIZE:
2545
+ xar->toc_chksum_size = atol10(s, len);
2546
+ break;
2547
+ default:
2548
+ break;
2549
+ }
2550
+ if (xar->file == NULL)
2551
+ return;
2552
+
2553
+ switch (xar->xmlsts) {
2554
+ case FILE_NAME:
2555
+ if (xar->file->parent != NULL) {
2556
+ archive_string_concat(&(xar->file->pathname),
2557
+ &(xar->file->parent->pathname));
2558
+ archive_strappend_char(&(xar->file->pathname), '/');
2559
+ }
2560
+ xar->file->has |= HAS_PATHNAME;
2561
+ if (xar->base64text)
2562
+ strappend_base64(&(xar->file->pathname), s, len);
2563
+ else
2564
+ archive_strncat(&(xar->file->pathname), s, len);
2565
+ break;
2566
+ case FILE_LINK:
2567
+ xar->file->has |= HAS_SYMLINK;
2568
+ archive_strncpy(&(xar->file->symlink), s, len);
2569
+ break;
2570
+ case FILE_TYPE:
2571
+ if (strncmp("file", s, len) == 0 ||
2572
+ strncmp("hardlink", s, len) == 0)
2573
+ xar->file->mode =
2574
+ (xar->file->mode & ~AE_IFMT) | AE_IFREG;
2575
+ if (strncmp("directory", s, len) == 0)
2576
+ xar->file->mode =
2577
+ (xar->file->mode & ~AE_IFMT) | AE_IFDIR;
2578
+ if (strncmp("symlink", s, len) == 0)
2579
+ xar->file->mode =
2580
+ (xar->file->mode & ~AE_IFMT) | AE_IFLNK;
2581
+ if (strncmp("character special", s, len) == 0)
2582
+ xar->file->mode =
2583
+ (xar->file->mode & ~AE_IFMT) | AE_IFCHR;
2584
+ if (strncmp("block special", s, len) == 0)
2585
+ xar->file->mode =
2586
+ (xar->file->mode & ~AE_IFMT) | AE_IFBLK;
2587
+ if (strncmp("socket", s, len) == 0)
2588
+ xar->file->mode =
2589
+ (xar->file->mode & ~AE_IFMT) | AE_IFSOCK;
2590
+ if (strncmp("fifo", s, len) == 0)
2591
+ xar->file->mode =
2592
+ (xar->file->mode & ~AE_IFMT) | AE_IFIFO;
2593
+ xar->file->has |= HAS_TYPE;
2594
+ break;
2595
+ case FILE_INODE:
2596
+ xar->file->has |= HAS_INO;
2597
+ xar->file->ino64 = atol10(s, len);
2598
+ break;
2599
+ case FILE_DEVICE_MAJOR:
2600
+ xar->file->has |= HAS_DEVMAJOR;
2601
+ xar->file->devmajor = (dev_t)atol10(s, len);
2602
+ break;
2603
+ case FILE_DEVICE_MINOR:
2604
+ xar->file->has |= HAS_DEVMINOR;
2605
+ xar->file->devminor = (dev_t)atol10(s, len);
2606
+ break;
2607
+ case FILE_DEVICENO:
2608
+ xar->file->has |= HAS_DEV;
2609
+ xar->file->dev = (dev_t)atol10(s, len);
2610
+ break;
2611
+ case FILE_MODE:
2612
+ xar->file->has |= HAS_MODE;
2613
+ xar->file->mode =
2614
+ (xar->file->mode & AE_IFMT) |
2615
+ (atol8(s, len) & ~AE_IFMT);
2616
+ break;
2617
+ case FILE_GROUP:
2618
+ xar->file->has |= HAS_GID;
2619
+ archive_strncpy(&(xar->file->gname), s, len);
2620
+ break;
2621
+ case FILE_GID:
2622
+ xar->file->has |= HAS_GID;
2623
+ xar->file->gid = atol10(s, len);
2624
+ break;
2625
+ case FILE_USER:
2626
+ xar->file->has |= HAS_UID;
2627
+ archive_strncpy(&(xar->file->uname), s, len);
2628
+ break;
2629
+ case FILE_UID:
2630
+ xar->file->has |= HAS_UID;
2631
+ xar->file->uid = atol10(s, len);
2632
+ break;
2633
+ case FILE_CTIME:
2634
+ xar->file->has |= HAS_TIME;
2635
+ xar->file->ctime = parse_time(s, len);
2636
+ break;
2637
+ case FILE_MTIME:
2638
+ xar->file->has |= HAS_TIME;
2639
+ xar->file->mtime = parse_time(s, len);
2640
+ break;
2641
+ case FILE_ATIME:
2642
+ xar->file->has |= HAS_TIME;
2643
+ xar->file->atime = parse_time(s, len);
2644
+ break;
2645
+ case FILE_DATA_LENGTH:
2646
+ xar->file->has |= HAS_DATA;
2647
+ xar->file->length = atol10(s, len);
2648
+ break;
2649
+ case FILE_DATA_OFFSET:
2650
+ xar->file->has |= HAS_DATA;
2651
+ xar->file->offset = atol10(s, len);
2652
+ break;
2653
+ case FILE_DATA_SIZE:
2654
+ xar->file->has |= HAS_DATA;
2655
+ xar->file->size = atol10(s, len);
2656
+ break;
2657
+ case FILE_DATA_A_CHECKSUM:
2658
+ xar->file->a_sum.len = atohex(xar->file->a_sum.val,
2659
+ sizeof(xar->file->a_sum.val), s, len);
2660
+ break;
2661
+ case FILE_DATA_E_CHECKSUM:
2662
+ xar->file->e_sum.len = atohex(xar->file->e_sum.val,
2663
+ sizeof(xar->file->e_sum.val), s, len);
2664
+ break;
2665
+ case FILE_EA_LENGTH:
2666
+ xar->file->has |= HAS_XATTR;
2667
+ xar->xattr->length = atol10(s, len);
2668
+ break;
2669
+ case FILE_EA_OFFSET:
2670
+ xar->file->has |= HAS_XATTR;
2671
+ xar->xattr->offset = atol10(s, len);
2672
+ break;
2673
+ case FILE_EA_SIZE:
2674
+ xar->file->has |= HAS_XATTR;
2675
+ xar->xattr->size = atol10(s, len);
2676
+ break;
2677
+ case FILE_EA_A_CHECKSUM:
2678
+ xar->file->has |= HAS_XATTR;
2679
+ xar->xattr->a_sum.len = atohex(xar->xattr->a_sum.val,
2680
+ sizeof(xar->xattr->a_sum.val), s, len);
2681
+ break;
2682
+ case FILE_EA_E_CHECKSUM:
2683
+ xar->file->has |= HAS_XATTR;
2684
+ xar->xattr->e_sum.len = atohex(xar->xattr->e_sum.val,
2685
+ sizeof(xar->xattr->e_sum.val), s, len);
2686
+ break;
2687
+ case FILE_EA_NAME:
2688
+ xar->file->has |= HAS_XATTR;
2689
+ archive_strncpy(&(xar->xattr->name), s, len);
2690
+ break;
2691
+ case FILE_EA_FSTYPE:
2692
+ xar->file->has |= HAS_XATTR;
2693
+ archive_strncpy(&(xar->xattr->fstype), s, len);
2694
+ break;
2695
+ break;
2696
+ case FILE_ACL_DEFAULT:
2697
+ case FILE_ACL_ACCESS:
2698
+ case FILE_ACL_APPLEEXTENDED:
2699
+ xar->file->has |= HAS_ACL;
2700
+ /* TODO */
2701
+ break;
2702
+ case INIT:
2703
+ case XAR:
2704
+ case TOC:
2705
+ case TOC_CREATION_TIME:
2706
+ case TOC_CHECKSUM:
2707
+ case TOC_CHECKSUM_OFFSET:
2708
+ case TOC_CHECKSUM_SIZE:
2709
+ case TOC_FILE:
2710
+ case FILE_DATA:
2711
+ case FILE_DATA_ENCODING:
2712
+ case FILE_DATA_CONTENT:
2713
+ case FILE_DEVICE:
2714
+ case FILE_EA:
2715
+ case FILE_EA_ENCODING:
2716
+ case FILE_ACL:
2717
+ case FILE_FLAGS:
2718
+ case FILE_FLAGS_USER_NODUMP:
2719
+ case FILE_FLAGS_USER_IMMUTABLE:
2720
+ case FILE_FLAGS_USER_APPEND:
2721
+ case FILE_FLAGS_USER_OPAQUE:
2722
+ case FILE_FLAGS_USER_NOUNLINK:
2723
+ case FILE_FLAGS_SYS_ARCHIVED:
2724
+ case FILE_FLAGS_SYS_IMMUTABLE:
2725
+ case FILE_FLAGS_SYS_APPEND:
2726
+ case FILE_FLAGS_SYS_NOUNLINK:
2727
+ case FILE_FLAGS_SYS_SNAPSHOT:
2728
+ case FILE_EXT2:
2729
+ case FILE_EXT2_SecureDeletion:
2730
+ case FILE_EXT2_Undelete:
2731
+ case FILE_EXT2_Compress:
2732
+ case FILE_EXT2_Synchronous:
2733
+ case FILE_EXT2_Immutable:
2734
+ case FILE_EXT2_AppendOnly:
2735
+ case FILE_EXT2_NoDump:
2736
+ case FILE_EXT2_NoAtime:
2737
+ case FILE_EXT2_CompDirty:
2738
+ case FILE_EXT2_CompBlock:
2739
+ case FILE_EXT2_NoCompBlock:
2740
+ case FILE_EXT2_CompError:
2741
+ case FILE_EXT2_BTree:
2742
+ case FILE_EXT2_HashIndexed:
2743
+ case FILE_EXT2_iMagic:
2744
+ case FILE_EXT2_Journaled:
2745
+ case FILE_EXT2_NoTail:
2746
+ case FILE_EXT2_DirSync:
2747
+ case FILE_EXT2_TopDir:
2748
+ case FILE_EXT2_Reserved:
2749
+ case UNKNOWN:
2750
+ break;
2751
+ }
2752
+ }
2753
+
2754
+ /*
2755
+ * BSD file flags.
2756
+ */
2757
+ static int
2758
+ xml_parse_file_flags(struct xar *xar, const char *name)
2759
+ {
2760
+ const char *flag = NULL;
2761
+
2762
+ if (strcmp(name, "UserNoDump") == 0) {
2763
+ xar->xmlsts = FILE_FLAGS_USER_NODUMP;
2764
+ flag = "nodump";
2765
+ }
2766
+ else if (strcmp(name, "UserImmutable") == 0) {
2767
+ xar->xmlsts = FILE_FLAGS_USER_IMMUTABLE;
2768
+ flag = "uimmutable";
2769
+ }
2770
+ else if (strcmp(name, "UserAppend") == 0) {
2771
+ xar->xmlsts = FILE_FLAGS_USER_APPEND;
2772
+ flag = "uappend";
2773
+ }
2774
+ else if (strcmp(name, "UserOpaque") == 0) {
2775
+ xar->xmlsts = FILE_FLAGS_USER_OPAQUE;
2776
+ flag = "opaque";
2777
+ }
2778
+ else if (strcmp(name, "UserNoUnlink") == 0) {
2779
+ xar->xmlsts = FILE_FLAGS_USER_NOUNLINK;
2780
+ flag = "nouunlink";
2781
+ }
2782
+ else if (strcmp(name, "SystemArchived") == 0) {
2783
+ xar->xmlsts = FILE_FLAGS_SYS_ARCHIVED;
2784
+ flag = "archived";
2785
+ }
2786
+ else if (strcmp(name, "SystemImmutable") == 0) {
2787
+ xar->xmlsts = FILE_FLAGS_SYS_IMMUTABLE;
2788
+ flag = "simmutable";
2789
+ }
2790
+ else if (strcmp(name, "SystemAppend") == 0) {
2791
+ xar->xmlsts = FILE_FLAGS_SYS_APPEND;
2792
+ flag = "sappend";
2793
+ }
2794
+ else if (strcmp(name, "SystemNoUnlink") == 0) {
2795
+ xar->xmlsts = FILE_FLAGS_SYS_NOUNLINK;
2796
+ flag = "nosunlink";
2797
+ }
2798
+ else if (strcmp(name, "SystemSnapshot") == 0) {
2799
+ xar->xmlsts = FILE_FLAGS_SYS_SNAPSHOT;
2800
+ flag = "snapshot";
2801
+ }
2802
+
2803
+ if (flag == NULL)
2804
+ return (0);
2805
+ xar->file->has |= HAS_FFLAGS;
2806
+ if (archive_strlen(&(xar->file->fflags_text)) > 0)
2807
+ archive_strappend_char(&(xar->file->fflags_text), ',');
2808
+ archive_strcat(&(xar->file->fflags_text), flag);
2809
+ return (1);
2810
+ }
2811
+
2812
+ /*
2813
+ * Linux file flags.
2814
+ */
2815
+ static int
2816
+ xml_parse_file_ext2(struct xar *xar, const char *name)
2817
+ {
2818
+ const char *flag = NULL;
2819
+
2820
+ if (strcmp(name, "SecureDeletion") == 0) {
2821
+ xar->xmlsts = FILE_EXT2_SecureDeletion;
2822
+ flag = "securedeletion";
2823
+ }
2824
+ else if (strcmp(name, "Undelete") == 0) {
2825
+ xar->xmlsts = FILE_EXT2_Undelete;
2826
+ flag = "nouunlink";
2827
+ }
2828
+ else if (strcmp(name, "Compress") == 0) {
2829
+ xar->xmlsts = FILE_EXT2_Compress;
2830
+ flag = "compress";
2831
+ }
2832
+ else if (strcmp(name, "Synchronous") == 0) {
2833
+ xar->xmlsts = FILE_EXT2_Synchronous;
2834
+ flag = "sync";
2835
+ }
2836
+ else if (strcmp(name, "Immutable") == 0) {
2837
+ xar->xmlsts = FILE_EXT2_Immutable;
2838
+ flag = "simmutable";
2839
+ }
2840
+ else if (strcmp(name, "AppendOnly") == 0) {
2841
+ xar->xmlsts = FILE_EXT2_AppendOnly;
2842
+ flag = "sappend";
2843
+ }
2844
+ else if (strcmp(name, "NoDump") == 0) {
2845
+ xar->xmlsts = FILE_EXT2_NoDump;
2846
+ flag = "nodump";
2847
+ }
2848
+ else if (strcmp(name, "NoAtime") == 0) {
2849
+ xar->xmlsts = FILE_EXT2_NoAtime;
2850
+ flag = "noatime";
2851
+ }
2852
+ else if (strcmp(name, "CompDirty") == 0) {
2853
+ xar->xmlsts = FILE_EXT2_CompDirty;
2854
+ flag = "compdirty";
2855
+ }
2856
+ else if (strcmp(name, "CompBlock") == 0) {
2857
+ xar->xmlsts = FILE_EXT2_CompBlock;
2858
+ flag = "comprblk";
2859
+ }
2860
+ else if (strcmp(name, "NoCompBlock") == 0) {
2861
+ xar->xmlsts = FILE_EXT2_NoCompBlock;
2862
+ flag = "nocomprblk";
2863
+ }
2864
+ else if (strcmp(name, "CompError") == 0) {
2865
+ xar->xmlsts = FILE_EXT2_CompError;
2866
+ flag = "comperr";
2867
+ }
2868
+ else if (strcmp(name, "BTree") == 0) {
2869
+ xar->xmlsts = FILE_EXT2_BTree;
2870
+ flag = "btree";
2871
+ }
2872
+ else if (strcmp(name, "HashIndexed") == 0) {
2873
+ xar->xmlsts = FILE_EXT2_HashIndexed;
2874
+ flag = "hashidx";
2875
+ }
2876
+ else if (strcmp(name, "iMagic") == 0) {
2877
+ xar->xmlsts = FILE_EXT2_iMagic;
2878
+ flag = "imagic";
2879
+ }
2880
+ else if (strcmp(name, "Journaled") == 0) {
2881
+ xar->xmlsts = FILE_EXT2_Journaled;
2882
+ flag = "journal";
2883
+ }
2884
+ else if (strcmp(name, "NoTail") == 0) {
2885
+ xar->xmlsts = FILE_EXT2_NoTail;
2886
+ flag = "notail";
2887
+ }
2888
+ else if (strcmp(name, "DirSync") == 0) {
2889
+ xar->xmlsts = FILE_EXT2_DirSync;
2890
+ flag = "dirsync";
2891
+ }
2892
+ else if (strcmp(name, "TopDir") == 0) {
2893
+ xar->xmlsts = FILE_EXT2_TopDir;
2894
+ flag = "topdir";
2895
+ }
2896
+ else if (strcmp(name, "Reserved") == 0) {
2897
+ xar->xmlsts = FILE_EXT2_Reserved;
2898
+ flag = "reserved";
2899
+ }
2900
+
2901
+ if (flag == NULL)
2902
+ return (0);
2903
+ if (archive_strlen(&(xar->file->fflags_text)) > 0)
2904
+ archive_strappend_char(&(xar->file->fflags_text), ',');
2905
+ archive_strcat(&(xar->file->fflags_text), flag);
2906
+ return (1);
2907
+ }
2908
+
2909
+ #ifdef HAVE_LIBXML_XMLREADER_H
2910
+
2911
+ static int
2912
+ xml2_xmlattr_setup(struct xmlattr_list *list, xmlTextReaderPtr reader)
2913
+ {
2914
+ struct xmlattr *attr;
2915
+ int r;
2916
+
2917
+ list->first = NULL;
2918
+ list->last = &(list->first);
2919
+ r = xmlTextReaderMoveToFirstAttribute(reader);
2920
+ while (r == 1) {
2921
+ attr = malloc(sizeof*(attr));
2922
+ if (attr == NULL)
2923
+ __archive_errx(1, "Out of memory");
2924
+ attr->name = strdup(
2925
+ (const char *)xmlTextReaderConstLocalName(reader));
2926
+ if (attr->name == NULL)
2927
+ __archive_errx(1, "Out of memory");
2928
+ attr->value = strdup(
2929
+ (const char *)xmlTextReaderConstValue(reader));
2930
+ if (attr->value == NULL)
2931
+ __archive_errx(1, "Out of memory");
2932
+ attr->next = NULL;
2933
+ *list->last = attr;
2934
+ list->last = &(attr->next);
2935
+ r = xmlTextReaderMoveToNextAttribute(reader);
2936
+ }
2937
+ return (r);
2938
+ }
2939
+
2940
+ static int
2941
+ xml2_read_cb(void *context, char *buffer, int len)
2942
+ {
2943
+ struct archive_read *a;
2944
+ struct xar *xar;
2945
+ const void *d;
2946
+ size_t outbytes;
2947
+ size_t used;
2948
+ int r;
2949
+
2950
+ a = (struct archive_read *)context;
2951
+ xar = (struct xar *)(a->format->data);
2952
+
2953
+ if (xar->toc_remaining <= 0)
2954
+ return (0);
2955
+ d = buffer;
2956
+ outbytes = len;
2957
+ r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
2958
+ if (r != ARCHIVE_OK)
2959
+ return (r);
2960
+ __archive_read_consume(a, used);
2961
+ xar->toc_remaining -= used;
2962
+ xar->offset += used;
2963
+ xar->toc_total += outbytes;
2964
+ PRINT_TOC(buffer, len);
2965
+
2966
+ return ((int)outbytes);
2967
+ }
2968
+
2969
+ static int
2970
+ xml2_close_cb(void *context)
2971
+ {
2972
+
2973
+ (void)context; /* UNUSED */
2974
+ return (0);
2975
+ }
2976
+
2977
+ static void
2978
+ xml2_error_hdr(void *arg, const char *msg, xmlParserSeverities severity,
2979
+ xmlTextReaderLocatorPtr locator)
2980
+ {
2981
+ struct archive_read *a;
2982
+
2983
+ (void)locator; /* UNUSED */
2984
+ a = (struct archive_read *)arg;
2985
+ switch (severity) {
2986
+ case XML_PARSER_SEVERITY_VALIDITY_WARNING:
2987
+ case XML_PARSER_SEVERITY_WARNING:
2988
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2989
+ "XML Parsing error: %s", msg);
2990
+ break;
2991
+ case XML_PARSER_SEVERITY_VALIDITY_ERROR:
2992
+ case XML_PARSER_SEVERITY_ERROR:
2993
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2994
+ "XML Parsing error: %s", msg);
2995
+ break;
2996
+ }
2997
+ }
2998
+
2999
+ static int
3000
+ xml2_read_toc(struct archive_read *a)
3001
+ {
3002
+ xmlTextReaderPtr reader;
3003
+ struct xmlattr_list list;
3004
+ int r;
3005
+
3006
+ reader = xmlReaderForIO(xml2_read_cb, xml2_close_cb, a, NULL, NULL, 0);
3007
+ if (reader == NULL) {
3008
+ archive_set_error(&a->archive, ENOMEM,
3009
+ "Couldn't allocate memory for xml parser");
3010
+ return (ARCHIVE_FATAL);
3011
+ }
3012
+ xmlTextReaderSetErrorHandler(reader, xml2_error_hdr, a);
3013
+
3014
+ while ((r = xmlTextReaderRead(reader)) == 1) {
3015
+ const char *name, *value;
3016
+ int type, empty;
3017
+
3018
+ type = xmlTextReaderNodeType(reader);
3019
+ name = (const char *)xmlTextReaderConstLocalName(reader);
3020
+ switch (type) {
3021
+ case XML_READER_TYPE_ELEMENT:
3022
+ empty = xmlTextReaderIsEmptyElement(reader);
3023
+ r = xml2_xmlattr_setup(&list, reader);
3024
+ if (r == 0) {
3025
+ xml_start(a, name, &list);
3026
+ xmlattr_cleanup(&list);
3027
+ if (empty)
3028
+ xml_end(a, name);
3029
+ }
3030
+ break;
3031
+ case XML_READER_TYPE_END_ELEMENT:
3032
+ xml_end(a, name);
3033
+ break;
3034
+ case XML_READER_TYPE_TEXT:
3035
+ value = (const char *)xmlTextReaderConstValue(reader);
3036
+ xml_data(a, value, strlen(value));
3037
+ break;
3038
+ case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
3039
+ default:
3040
+ break;
3041
+ }
3042
+ if (r < 0)
3043
+ break;
3044
+ }
3045
+ xmlFreeTextReader(reader);
3046
+ xmlCleanupParser();
3047
+
3048
+ return ((r == 0)?ARCHIVE_OK:ARCHIVE_FATAL);
3049
+ }
3050
+
3051
+ #elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
3052
+
3053
+ static void
3054
+ expat_xmlattr_setup(struct xmlattr_list *list, const XML_Char **atts)
3055
+ {
3056
+ struct xmlattr *attr;
3057
+
3058
+ list->first = NULL;
3059
+ list->last = &(list->first);
3060
+ if (atts == NULL)
3061
+ return;
3062
+ while (atts[0] != NULL && atts[1] != NULL) {
3063
+ attr = malloc(sizeof*(attr));
3064
+ if (attr == NULL)
3065
+ __archive_errx(1, "Out of memory");
3066
+ attr->name = strdup(atts[0]);
3067
+ if (attr->name == NULL)
3068
+ __archive_errx(1, "Out of memory");
3069
+ attr->value = strdup(atts[1]);
3070
+ if (attr->value == NULL)
3071
+ __archive_errx(1, "Out of memory");
3072
+ attr->next = NULL;
3073
+ *list->last = attr;
3074
+ list->last = &(attr->next);
3075
+ atts += 2;
3076
+ }
3077
+ }
3078
+
3079
+ static void
3080
+ expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts)
3081
+ {
3082
+ struct xmlattr_list list;
3083
+
3084
+ expat_xmlattr_setup(&list, atts);
3085
+ xml_start(userData, (const char *)name, &list);
3086
+ xmlattr_cleanup(&list);
3087
+ }
3088
+
3089
+ static void
3090
+ expat_end_cb(void *userData, const XML_Char *name)
3091
+ {
3092
+ xml_end(userData, (const char *)name);
3093
+ }
3094
+
3095
+ static void
3096
+ expat_data_cb(void *userData, const XML_Char *s, int len)
3097
+ {
3098
+ xml_data(userData, s, len);
3099
+ }
3100
+
3101
+ static int
3102
+ expat_read_toc(struct archive_read *a)
3103
+ {
3104
+ struct xar *xar;
3105
+ XML_Parser parser;
3106
+
3107
+ xar = (struct xar *)(a->format->data);
3108
+
3109
+ /* Initialize XML Parser library. */
3110
+ parser = XML_ParserCreate(NULL);
3111
+ if (parser == NULL) {
3112
+ archive_set_error(&a->archive, ENOMEM,
3113
+ "Couldn't allocate memory for xml parser");
3114
+ return (ARCHIVE_FATAL);
3115
+ }
3116
+ XML_SetUserData(parser, a);
3117
+ XML_SetElementHandler(parser, expat_start_cb, expat_end_cb);
3118
+ XML_SetCharacterDataHandler(parser, expat_data_cb);
3119
+ xar->xmlsts = INIT;
3120
+
3121
+ while (xar->toc_remaining) {
3122
+ enum XML_Status xr;
3123
+ const void *d;
3124
+ size_t outbytes;
3125
+ size_t used;
3126
+ int r;
3127
+
3128
+ d = NULL;
3129
+ r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
3130
+ if (r != ARCHIVE_OK)
3131
+ return (r);
3132
+ __archive_read_consume(a, used);
3133
+ xar->toc_remaining -= used;
3134
+ xar->offset += used;
3135
+ xar->toc_total += outbytes;
3136
+ PRINT_TOC(d, outbytes);
3137
+
3138
+ xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0);
3139
+ if (xr == XML_STATUS_ERROR) {
3140
+ XML_ParserFree(parser);
3141
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3142
+ "XML Parsing failed");
3143
+ return (ARCHIVE_FATAL);
3144
+ }
3145
+ }
3146
+ XML_ParserFree(parser);
3147
+ return (ARCHIVE_OK);
3148
+ }
3149
+ #endif /* defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) */
3150
+
3151
+ #endif /* Support xar format */