1
2
3
4
5
6
7
8
9
10
11
12#include "libbb.h"
13#include "bb_archive.h"
14
15#define XZ_FUNC FAST_FUNC
16#define XZ_EXTERN static
17
18#define XZ_DEC_DYNALLOC
19
20
21#define XZ_DEC_ANY_CHECK 1
22
23
24#define XZ_INTERNAL_CRC32 0
25static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
26{
27 return ~crc32_block_endian0(~crc, buf, size, global_crc32_table);
28}
29
30
31#define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); })
32#define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); })
33#define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val))
34#define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val))
35
36#include "unxz/xz_dec_bcj.c"
37#include "unxz/xz_dec_lzma2.c"
38#include "unxz/xz_dec_stream.c"
39
40IF_DESKTOP(long long) int FAST_FUNC
41unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
42{
43 struct xz_buf iobuf;
44 struct xz_dec *state;
45 unsigned char *membuf;
46 IF_DESKTOP(long long) int total = 0;
47
48 if (!global_crc32_table)
49 global_crc32_table = crc32_filltable(NULL, 0);
50
51 memset(&iobuf, 0, sizeof(iobuf));
52 membuf = xmalloc(2 * BUFSIZ);
53 iobuf.in = membuf;
54 iobuf.out = membuf + BUFSIZ;
55 iobuf.out_size = BUFSIZ;
56
57 if (!aux || aux->check_signature == 0) {
58
59 strcpy((char*)membuf, HEADER_MAGIC);
60 iobuf.in_size = HEADER_MAGIC_SIZE;
61 }
62
63
64 state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024);
65
66 while (1) {
67 enum xz_ret r;
68
69 if (iobuf.in_pos == iobuf.in_size) {
70 int rd = safe_read(src_fd, membuf, BUFSIZ);
71 if (rd < 0) {
72 bb_error_msg(bb_msg_read_error);
73 total = -1;
74 break;
75 }
76 iobuf.in_size = rd;
77 iobuf.in_pos = 0;
78 }
79
80
81 r = xz_dec_run(state, &iobuf);
82
83
84 if (iobuf.out_pos) {
85 xwrite(dst_fd, iobuf.out, iobuf.out_pos);
86 IF_DESKTOP(total += iobuf.out_pos;)
87 iobuf.out_pos = 0;
88 }
89 if (r == XZ_STREAM_END) {
90 break;
91 }
92 if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) {
93 bb_error_msg("corrupted data");
94 total = -1;
95 break;
96 }
97 }
98 xz_dec_end(state);
99 free(membuf);
100
101 return total;
102}
103