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