Exemple #1
0
static int raw_import_process(RawImport *i) {
        ssize_t l;
        int r;

        assert(i);
        assert(i->buffer_size < sizeof(i->buffer));

        l = read(i->input_fd, i->buffer + i->buffer_size, sizeof(i->buffer) - i->buffer_size);
        if (l < 0) {
                if (errno == EAGAIN)
                        return 0;

                r = log_error_errno(errno, "Failed to read input file: %m");
                goto finish;
        }
        if (l == 0) {
                if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
                        log_error("Premature end of file.");
                        r = -EIO;
                        goto finish;
                }

                r = raw_import_finish(i);
                goto finish;
        }

        i->buffer_size += l;

        if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
                r = import_uncompress_detect(&i->compress, i->buffer, i->buffer_size);
                if (r < 0) {
                        log_error_errno(r, "Failed to detect file compression: %m");
                        goto finish;
                }
                if (r == 0) /* Need more data */
                        return 0;

                r = raw_import_open_disk(i);
                if (r < 0)
                        goto finish;

                r = raw_import_try_reflink(i);
                if (r < 0)
                        goto finish;
                if (r > 0) {
                        r = raw_import_finish(i);
                        goto finish;
                }
        }

        r = import_uncompress(&i->compress, i->buffer, i->buffer_size, raw_import_write, i);
        if (r < 0) {
                log_error_errno(r, "Failed to decode and write: %m");
                goto finish;
        }

        i->written_compressed += i->buffer_size;
        i->buffer_size = 0;

        raw_import_report_progress(i);

        return 0;

finish:
        if (i->on_finished)
                i->on_finished(i, r, i->userdata);
        else
                sd_event_exit(i->event, r);

        return 0;
}
Exemple #2
0
int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCompressCallback callback, void *userdata) {
        int r;

        assert(c);
        assert(callback);

        r = import_uncompress_detect(c, data, size);
        if (r <= 0)
                return r;

        if (c->encoding)
                return -EINVAL;

        if (size <= 0)
                return 1;

        assert(data);

        switch (c->type) {

        case IMPORT_COMPRESS_UNCOMPRESSED:
                r = callback(data, size, userdata);
                if (r < 0)
                        return r;

                break;

        case IMPORT_COMPRESS_XZ:
                c->xz.next_in = data;
                c->xz.avail_in = size;

                while (c->xz.avail_in > 0) {
                        uint8_t buffer[16 * 1024];
                        lzma_ret lzr;

                        c->xz.next_out = buffer;
                        c->xz.avail_out = sizeof(buffer);

                        lzr = lzma_code(&c->xz, LZMA_RUN);
                        if (lzr != LZMA_OK && lzr != LZMA_STREAM_END)
                                return -EIO;

                        r = callback(buffer, sizeof(buffer) - c->xz.avail_out, userdata);
                        if (r < 0)
                                return r;
                }

                break;

        case IMPORT_COMPRESS_GZIP:
                c->gzip.next_in = (void*) data;
                c->gzip.avail_in = size;

                while (c->gzip.avail_in > 0) {
                        uint8_t buffer[16 * 1024];

                        c->gzip.next_out = buffer;
                        c->gzip.avail_out = sizeof(buffer);

                        r = inflate(&c->gzip, Z_NO_FLUSH);
                        if (r != Z_OK && r != Z_STREAM_END)
                                return -EIO;

                        r = callback(buffer, sizeof(buffer) - c->gzip.avail_out, userdata);
                        if (r < 0)
                                return r;
                }

                break;

        case IMPORT_COMPRESS_BZIP2:
                c->bzip2.next_in = (void*) data;
                c->bzip2.avail_in = size;

                while (c->bzip2.avail_in > 0) {
                        uint8_t buffer[16 * 1024];

                        c->bzip2.next_out = (char*) buffer;
                        c->bzip2.avail_out = sizeof(buffer);

                        r = BZ2_bzDecompress(&c->bzip2);
                        if (r != BZ_OK && r != BZ_STREAM_END)
                                return -EIO;

                        r = callback(buffer, sizeof(buffer) - c->bzip2.avail_out, userdata);
                        if (r < 0)
                                return r;
                }

                break;

        default:
                assert_not_reached("Unknown compression");
        }

        return 1;
}