15 ssize_t uncompresslzma(void *buf, size_t bufsize, int out) {
16 lzma_stream s = LZMA_STREAM_INIT;
20 uint8_t outbuf[BUFSIZ];
26 ret = lzma_stream_decoder(strm, UINT64_MAX, 0);
27 /* The only reasonable error here is LZMA_MEM_ERROR. */
29 fprintf(stderr, "%s", ret == LZMA_MEM_ERROR ? strerror(ENOMEM)
30 : "Internal error (bug)");
34 strm->avail_in = bufsize;
36 strm->avail_out = BUFSIZ;
37 strm->next_out = outbuf;
39 lzma_action action = LZMA_RUN;
42 ret = lzma_code(strm, action);
44 // Write and check write error before checking decoder error.
45 // This way as much data as possible gets written to output
46 // even if decoder detected an error.
47 if (strm->avail_out == 0 || ret != LZMA_OK) {
48 size_t avail = BUFSIZ - strm->avail_out;
55 written = write(out, outbuf, avail);
57 /* Wouldn't be a surprise if writing to
58 * stderr would fail too but at least
59 * try to show an error message.
61 fprintf(stderr, "Cannot write to output"
71 strm->next_out = outbuf;
72 strm->avail_out = BUFSIZ;
76 if (ret == LZMA_STREAM_END) {
77 // lzma_stream_decoder() already guarantees
78 // that there's no trailing garbage.
79 assert(strm->avail_in == 0);
80 //assert(action == LZMA_FINISH);
87 msg = strerror(ENOMEM);
90 case LZMA_FORMAT_ERROR:
91 msg = "File format not recognized";
94 case LZMA_OPTIONS_ERROR:
95 // FIXME: Better message?
96 msg = "Unsupported compression options";
100 msg = "File is corrupt";
104 msg = "Unexpected end of input";
108 msg = "Internal error (bug)";
112 fprintf(stderr, "zpmuncompress: %s\n", msg);