Path: blob/main/sys/contrib/xz-embedded/userspace/xzminidec.c
48255 views
/*1* Simple XZ decoder command line tool2*3* Author: Lasse Collin <[email protected]>4*5* This file has been put into the public domain.6* You can do whatever you want with this file.7*/89/*10* This is really limited: Not all filters from .xz format are supported,11* only CRC32 is supported as the integrity check, and decoding of12* concatenated .xz streams is not supported. Thus, you may want to look13* at xzdec from XZ Utils if a few KiB bigger tool is not a problem.14*/1516#include <stdbool.h>17#include <stdio.h>18#include <string.h>19#include "xz.h"2021static uint8_t in[BUFSIZ];22static uint8_t out[BUFSIZ];2324int main(int argc, char **argv)25{26struct xz_buf b;27struct xz_dec *s;28enum xz_ret ret;29const char *msg;3031if (argc >= 2 && strcmp(argv[1], "--help") == 0) {32fputs("Uncompress a .xz file from stdin to stdout.\n"33"Arguments other than `--help' are ignored.\n",34stdout);35return 0;36}3738xz_crc32_init();39#ifdef XZ_USE_CRC6440xz_crc64_init();41#endif4243/*44* Support up to 64 MiB dictionary. The actually needed memory45* is allocated once the headers have been parsed.46*/47s = xz_dec_init(XZ_DYNALLOC, 1 << 26);48if (s == NULL) {49msg = "Memory allocation failed\n";50goto error;51}5253b.in = in;54b.in_pos = 0;55b.in_size = 0;56b.out = out;57b.out_pos = 0;58b.out_size = BUFSIZ;5960while (true) {61if (b.in_pos == b.in_size) {62b.in_size = fread(in, 1, sizeof(in), stdin);6364if (ferror(stdin)) {65msg = "Read error\n";66goto error;67}6869b.in_pos = 0;70}7172/*73* There are a few ways to set the "finish" (the third)74* argument. We could use feof(stdin) but testing in_size75* is fine too and may also work in applications that don't76* use FILEs.77*/78ret = xz_dec_catrun(s, &b, b.in_size == 0);7980if (b.out_pos == sizeof(out)) {81if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos) {82msg = "Write error\n";83goto error;84}8586b.out_pos = 0;87}8889if (ret == XZ_OK)90continue;9192#ifdef XZ_DEC_ANY_CHECK93if (ret == XZ_UNSUPPORTED_CHECK) {94fputs(argv[0], stderr);95fputs(": ", stderr);96fputs("Unsupported check; not verifying "97"file integrity\n", stderr);98continue;99}100#endif101102if (fwrite(out, 1, b.out_pos, stdout) != b.out_pos103|| fclose(stdout)) {104msg = "Write error\n";105goto error;106}107108switch (ret) {109case XZ_STREAM_END:110xz_dec_end(s);111return 0;112113case XZ_MEM_ERROR:114msg = "Memory allocation failed\n";115goto error;116117case XZ_MEMLIMIT_ERROR:118msg = "Memory usage limit reached\n";119goto error;120121case XZ_FORMAT_ERROR:122msg = "Not a .xz file\n";123goto error;124125case XZ_OPTIONS_ERROR:126msg = "Unsupported options in the .xz headers\n";127goto error;128129case XZ_DATA_ERROR:130case XZ_BUF_ERROR:131msg = "File is corrupt\n";132goto error;133134default:135msg = "Bug!\n";136goto error;137}138}139140error:141xz_dec_end(s);142fputs(argv[0], stderr);143fputs(": ", stderr);144fputs(msg, stderr);145return 1;146}147148149