]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/contrib/xz-embedded/userspace/xzminidec.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / contrib / xz-embedded / userspace / xzminidec.c
1 /*
2  * Simple XZ decoder command line tool
3  *
4  * Author: Lasse Collin <lasse.collin@tukaani.org>
5  *
6  * This file has been put into the public domain.
7  * You can do whatever you want with this file.
8  */
9
10 /*
11  * This is really limited: Not all filters from .xz format are supported,
12  * only CRC32 is supported as the integrity check, and decoding of
13  * concatenated .xz streams is not supported. Thus, you may want to look
14  * at xzdec from XZ Utils if a few KiB bigger tool is not a problem.
15  */
16
17 #include <stdbool.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include "xz.h"
21
22 static uint8_t in[BUFSIZ];
23 static uint8_t out[BUFSIZ];
24
25 int main(int argc, char **argv)
26 {
27         struct xz_buf b;
28         struct xz_dec *s;
29         enum xz_ret ret;
30         const char *msg;
31
32         if (argc >= 2 && strcmp(argv[1], "--help") == 0) {
33                 fputs("Uncompress a .xz file from stdin to stdout.\n"
34                                 "Arguments other than `--help' are ignored.\n",
35                                 stdout);
36                 return 0;
37         }
38
39         xz_crc32_init();
40
41         /*
42          * Support up to 64 MiB dictionary. The actually needed memory
43          * is allocated once the headers have been parsed.
44          */
45         s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
46         if (s == NULL) {
47                 msg = "Memory allocation failed\n";
48                 goto error;
49         }
50
51         b.in = in;
52         b.in_pos = 0;
53         b.in_size = 0;
54         b.out = out;
55         b.out_pos = 0;
56         b.out_size = BUFSIZ;
57
58         while (true) {
59                 if (b.in_pos == b.in_size) {
60                         b.in_size = fread(in, 1, sizeof(in), stdin);
61                         b.in_pos = 0;
62                 }
63
64                 ret = xz_dec_run(s, &b);
65
66                 if (b.out_pos == sizeof(out)) {
67                         if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {
68                                 msg = "Write error\n";
69                                 goto error;
70                         }
71
72                         b.out_pos = 0;
73                 }
74
75                 if (ret == XZ_OK)
76                         continue;
77
78 #ifdef XZ_DEC_ANY_CHECK
79                 if (ret == XZ_UNSUPPORTED_CHECK) {
80                         fputs(argv[0], stderr);
81                         fputs(": ", stderr);
82                         fputs("Unsupported check; not verifying "
83                                         "file integrity\n", stderr);
84                         continue;
85                 }
86 #endif
87
88                 if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos
89                                 || fclose(stdout)) {
90                         msg = "Write error\n";
91                         goto error;
92                 }
93
94                 switch (ret) {
95                 case XZ_STREAM_END:
96                         xz_dec_end(s);
97                         return 0;
98
99                 case XZ_MEM_ERROR:
100                         msg = "Memory allocation failed\n";
101                         goto error;
102
103                 case XZ_MEMLIMIT_ERROR:
104                         msg = "Memory usage limit reached\n";
105                         goto error;
106
107                 case XZ_FORMAT_ERROR:
108                         msg = "Not a .xz file\n";
109                         goto error;
110
111                 case XZ_OPTIONS_ERROR:
112                         msg = "Unsupported options in the .xz headers\n";
113                         goto error;
114
115                 case XZ_DATA_ERROR:
116                 case XZ_BUF_ERROR:
117                         msg = "File is corrupt\n";
118                         goto error;
119
120                 default:
121                         msg = "Bug!\n";
122                         goto error;
123                 }
124         }
125
126 error:
127         xz_dec_end(s);
128         fputs(argv[0], stderr);
129         fputs(": ", stderr);
130         fputs(msg, stderr);
131         return 1;
132 }