15 void uncompresslzma(void *buf, size_t bufsize, FILE *out) {
16 lzma_stream s = LZMA_STREAM_INIT;
19 uint8_t outbuf[BUFSIZ];
25 ret = lzma_stream_decoder(strm, UINT64_MAX, 0);
26 /* The only reasonable error here is LZMA_MEM_ERROR. */
28 fprintf(stderr, "%s", ret == LZMA_MEM_ERROR ? strerror(ENOMEM)
29 : "Internal error (bug)");
33 strm->avail_in = bufsize;
35 strm->avail_out = BUFSIZ;
36 strm->next_out = outbuf;
38 lzma_action action = LZMA_RUN;
41 ret = lzma_code(strm, action);
43 // Write and check write error before checking decoder error.
44 // This way as much data as possible gets written to output
45 // even if decoder detected an error.
46 if (strm->avail_out == 0 || ret != LZMA_OK) {
47 const size_t write_size = BUFSIZ - strm->avail_out;
49 if (fwrite(outbuf, 1, write_size, out) != write_size) {
50 // Wouldn't be a surprise if writing to stderr
51 // would fail too but at least try to show an
53 fprintf(stderr, "Cannot write to output file stream: "
54 "%s", strerror(errno));
58 strm->next_out = outbuf;
59 strm->avail_out = BUFSIZ;
63 if (ret == LZMA_STREAM_END) {
64 // lzma_stream_decoder() already guarantees
65 // that there's no trailing garbage.
66 assert(strm->avail_in == 0);
67 //assert(action == LZMA_FINISH);
74 msg = strerror(ENOMEM);
77 case LZMA_FORMAT_ERROR:
78 msg = "File format not recognized";
81 case LZMA_OPTIONS_ERROR:
82 // FIXME: Better message?
83 msg = "Unsupported compression options";
87 msg = "File is corrupt";
91 msg = "Unexpected end of input";
95 msg = "Internal error (bug)";
99 fprintf(stderr, "xz: %s\n", msg);