aboutsummaryrefslogtreecommitdiff
path: root/src/lzma/list.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2008-11-19 23:52:24 +0200
committerLasse Collin <lasse.collin@tukaani.org>2008-11-19 23:52:24 +0200
commit1880a3927b23f265f63b2adb86fbdb81ea09eb06 (patch)
tree2fe1b65d21f81b28f46eb707378d97f553e99ee1 /src/lzma/list.c
parentOh well, big messy commit again. Some highlights: (diff)
downloadxz-1880a3927b23f265f63b2adb86fbdb81ea09eb06.tar.xz
Renamed lzma to xz and lzmadec to xzdec. We create symlinks
lzma, unlzma, and lzcat in "make install" for backwards compatibility with LZMA Utils 4.32.x; I'm not sure if this should be the default though.
Diffstat (limited to 'src/lzma/list.c')
-rw-r--r--src/lzma/list.c477
1 files changed, 0 insertions, 477 deletions
diff --git a/src/lzma/list.c b/src/lzma/list.c
deleted file mode 100644
index 8728d47b..00000000
--- a/src/lzma/list.c
+++ /dev/null
@@ -1,477 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//
-/// \file list.c
-/// \brief Listing information about .lzma files
-//
-// Copyright (C) 2007 Lasse Collin
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#include "private.h"
-
-
-/*
-
-1. Check the file type: native, alone, unknown
-
-Alone:
-1. Show info about header. Don't look for concatenated parts.
-
-Native:
-1. Check that Stream Header is valid.
-2. Seek to the end of the file.
-3. Skip padding.
-4. Reverse decode Stream Footer.
-5. Seek Backward Size bytes.
-6.
-
-*/
-
-
-static void
-unsupported_file(file_handle *handle)
-{
- errmsg(V_ERROR, "%s: Unsupported file type", handle->name);
- set_exit_status(ERROR);
- (void)io_close(handle);
- return;
-}
-
-
-/// Primitive escaping function, that escapes only ASCII control characters.
-static void
-print_escaped(const uint8_t *str)
-{
- while (*str != '\0') {
- if (*str <= 0x1F || *str == 0x7F)
- printf("\\x%02X", *str);
- else
- putchar(*str);
-
- ++str;
- }
-
- return;
-}
-
-
-static void
-list_native(file_handle *handle)
-{
- lzma_stream strm = LZMA_STREAM_INIT;
- lzma_stream_flags flags;
- lzma_ret ret = lzma_stream_header_decoder(&strm, &flags);
-
-}
-
-
-static void
-list_alone(const listing_handle *handle)
-{
- if (handle->buffer[0] > (4 * 5 + 4) * 9 + 8) {
- unsupported_file(handle);
- return;
- }
-
- const unsigned int pb = handle->buffer[0] / (9 * 5);
- handle->buffer[0] -= pb * 9 * 5;
- const unsigned int lp = handle->buffer[0] / 9;
- const unsigned int lc = handle->buffer[0] - lp * 9;
-
- uint32_t dict = 0;
- for (size_t i = 1; i < 5; ++i) {
- dict <<= 8;
- dict |= header[i];
- }
-
- if (dict > LZMA_DICTIONARY_SIZE_MAX) {
- unsupported_file(handle);
- return;
- }
-
- uint64_t uncompressed_size = 0;
- for (size_t i = 5; i < 13; ++i) {
- uncompressed_size <<= 8;
- uncompressed_size |= header[i];
- }
-
- // Reject files with uncompressed size of 256 GiB or more. It's
- // an arbitrary limit trying to avoid at least some false positives.
- if (uncompressed_size != UINT64_MAX
- && uncompressed_size >= (UINT64_C(1) << 38)) {
- unsupported_file(handle);
- return;
- }
-
- if (verbosity < V_WARNING) {
- printf("name=");
- print_escaped(handle->name);
- printf("\nformat=alone\n");
-
- if (uncompressed_size == UINT64_MAX)
- printf("uncompressed_size=unknown\n");
- else
- printf("uncompressed_size=%" PRIu64 "\n",
- uncompressed_size);
-
- printf("dict=%" PRIu32 "\n", dict);
-
- printf("lc=%u\nlp=%u\npb=%u\n\n", lc, lp, pb);
-
- } else {
- printf("File name: ");
- print_escaped(handle->name);
- printf("\nFile format: LZMA_Alone\n")
-
- printf("Uncompressed size: ");
- if (uncompressed_size == UINT64_MAX)
- printf("unknown\n");
- else
- printf("%," PRIu64 " bytes (%" PRIu64 " MiB)\n",
- uncompressed_size,
- (uncompressed_size + 1024 * 512)
- / (1024 * 1024));
-
- printf("Dictionary size: %," PRIu32 " bytes "
- "(%" PRIu32 " MiB)\n",
- dict, (dict + 1024 * 512) / (1024 * 1024));
-
- printf("Literal context bits (lc): %u\n", lc);
- printf("Literal position bits (lc): %u\n", lp);
- printf("Position bits (pb): %u\n", pb);
- }
-
- return;
-}
-
-
-
-
-typedef struct {
- const char *filename;
- struct stat st;
- int fd;
-
- lzma_stream strm;
- lzma_stream_flags stream_flags;
- lzma_info *info;
-
- lzma_vli backward_size;
- lzma_vli uncompressed_size;
-
- size_t buffer_size;
- uint8_t buffer[IO_BUFFER_SIZE];
-} listing_handle;
-
-
-static bool
-listing_pread(listing_handle *handle, uint64_t offset)
-{
- if (offset >= (uint64_t)(handle->st.st_size)) {
- errmsg(V_ERROR, "%s: Trying to read past the end of "
- "the file.", handle->filename);
- return true;
- }
-
-#ifdef HAVE_PREAD
- const ssize_t ret = pread(handle->fd, handle->buffer, IO_BUFFER_SIZE,
- (off_t)(offset));
-#else
- // Use lseek() + read() since we don't have pread(). We don't care
- // to which offset the reading position is left.
- if (lseek(handle->fd, (off_t)(offset), SEEK_SET) == -1) {
- errmsg(V_ERROR, "%s: %s", handle->filename, strerror(errno));
- return true;
- }
-
- const ssize_t ret = read(handle->fd, handle->buffer, IO_BUFFER_SIZE);
-#endif
-
- if (ret == -1) {
- errmsg(V_ERROR, "%s: %s", handle->filename, strerror(errno));
- return true;
- }
-
- if (ret == 0) {
- errmsg(V_ERROR, "%s: Trying to read past the end of "
- "the file.", handle->filename);
- return true;
- }
-
- handle->buffer_size = (size_t)(ret);
- return false;
-}
-
-
-
-static bool
-parse_stream_header(listing_handle *handle)
-{
- if (listing_pread(handle, 0))
- return true;
-
- // TODO Got enough input?
-
- lzma_ret ret = lzma_stream_header_decoder(
- &handle->strm, &handle->stream_flags);
- if (ret != LZMA_OK) {
- errmsg(V_ERROR, "%s: %s", handle->name, str_strm_error(ret));
- return true;
- }
-
- handle->strm.next_in = handle->buffer;
- handle->strm.avail_in = handle->buffer_size;
- ret = lzma_code(&handle->strm, LZMA_RUN);
- if (ret != LZMA_STREAM_END) {
- assert(ret != LZMA_OK);
- errmsg(V_ERROR, "%s: %s", handle->name, str_strm_error(ret));
- return true;
- }
-
- return false;
-}
-
-
-static bool
-parse_stream_tail(listing_handle *handle)
-{
- uint64_t offset = (uint64_t)(handle->st.st_size);
-
- // Skip padding
- do {
- if (offset == 0) {
- errmsg(V_ERROR, "%s: %s", handle->name,
- str_strm_error(LZMA_DATA_ERROR));
- return true;
- }
-
- if (offset < IO_BUFFER_SIZE)
- offset = 0;
- else
- offset -= IO_BUFFER_SIZE;
-
- if (listing_pread(handle, offset))
- return true;
-
- while (handle->buffer_size > 0
- && handle->buffer[handle->buffer_size - 1]
- == '\0')
- --handle->buffer_size;
-
- } while (handle->buffer_size == 0);
-
- if (handle->buffer_size < LZMA_STREAM_TAIL_SIZE) {
- // TODO
- }
-
- lzma_stream_flags stream_flags;
- lzma_ret ret = lzma_stream_tail_decoder(&handle->strm, &stream_flags);
- if (ret != LZMA_OK) {
- errmsg(V_ERROR, "%s: %s", handle->name, str_strm_error(ret));
- return true;
- }
-
- handle->strm.next_in = handle->buffer + handle->buffer_size
- - LZMA_STREAM_TAIL_SIZE;
- handle->strm.avail_in = LZMA_STREAM_TAIL_SIZE;
- handle->buffer_size -= LZMA_STREAM_TAIL_SIZE;
- ret = lzma_code(&handle->strm, LZMA_RUN);
- if (ret != LZMA_OK) {
- assert(ret != LZMA_OK);
- errmsg(V_ERROR, "%s: %s", handle->name, str_strm_error(ret));
- return true;
- }
-
- if (!lzma_stream_flags_is_equal(handle->stream_flags, stream_flags)) {
- // TODO
- // Possibly corrupt, possibly concatenated file.
- }
-
- handle->backward_size = 0;
- ret = lzma_vli_reverse_decode(&handle->backward_size, handle->buffer,
- &handle->buffer_size);
- if (ret != LZMA_OK) {
- // It may be LZMA_BUF_ERROR too, but it doesn't make sense
- // as an error message displayed to the user.
- errmsg(V_ERROR, "%s: %s", handle->name,
- str_strm_error(LZMA_DATA_ERROR));
- return true;
- }
-
- if (!stream_flags.is_multi) {
- handle->uncompressed_size = 0;
- size_t tmp = handle->buffer_size;
- ret = lzma_vli_reverse_decode(&handle->uncompressed_size,
- handle->buffer, &tmp);
- if (ret != LZMA_OK)
- handle->uncompressed_size = LZMA_VLI_UNKNOWN;
- }
-
- // Calculate the Header Metadata Block start offset.
-
-
- return false;
-}
-
-
-
-static void
-list_native(listing_handle *handle)
-{
- lzma_memory_limiter *limiter
- = lzma_memory_limiter_create(opt_memory);
- if (limiter == NULL) {
- errmsg(V_ERROR,
- }
- lzma_info *info =
-
-
- // Parse Stream Header
- //
- // Single-Block Stream:
- // - Parse Block Header
- // - Parse Stream Footer
- // - If Backward Size doesn't match, error out
- //
- // Multi-Block Stream:
- // - Parse Header Metadata Block, if any
- // - Parse Footer Metadata Block
- // - Parse Stream Footer
- // - If Footer Metadata Block doesn't match the Stream, error out
- //
- // In other words, we don't support concatened files.
- if (parse_stream_header(handle))
- return;
-
- if (parse_block_header(handle))
- return;
-
- if (handle->stream_flags.is_multi) {
- if (handle->block_options.is_metadata) {
- if (parse_metadata(handle)
- return;
- }
-
- if (my_seek(handle,
-
- } else {
- if (handle->block_options.is_metadata) {
- FILE_IS_CORRUPT();
- return;
- }
-
- if (parse_stream_footer(handle))
- return;
-
- // If Uncompressed Size isn't present in Block Header,
- // it must be present in Stream Footer.
- if (handle->block_options.uncompressed_size
- == LZMA_VLI_UNKNOWN
- && handle->stream_flags.uncompressed_size
- == LZMA_VLI_UNKNOWN) {
- FILE_IS_CORRUPT();
- return;
- }
-
- // Construct a single-Record Index.
- lzma_index *index = malloc(sizeof(lzma_index));
- if (index == NULL) {
- out_of_memory();
- return;
- }
-
- // Pohdintaa:
- // Jos Block coder hoitaisi Uncompressed ja Backward Sizet,
- // voisi index->total_sizeksi laittaa suoraan Backward Sizen.
- index->total_size =
-
- if () {
-
- }
- }
-
-
- if (handle->block_options.is_metadata) {
- if (!handle->stream_flags.is_multi) {
- FILE_IS_CORRUPT();
- return;
- }
-
- if (parse_metadata(handle))
- return;
-
- }
-}
-
-
-
-extern void
-list(const char *filename)
-{
- if (strcmp(filename, "-") == 0) {
- errmsg(V_ERROR, "%s: --list does not support reading from "
- "standard input", filename);
- return;
- }
-
- if (is_empty_filename(filename))
- return;
-
- listing_handle handle;
- handle.filename = filename;
-
- handle.fd = open(filename, O_RDONLY | O_NOCTTY);
- if (handle.fd == -1) {
- errmsg(V_ERROR, "%s: %s", filename, strerror(errno));
- return;
- }
-
- if (fstat(handle.fd, &handle.st)) {
- errmsg(V_ERROR, "%s: %s", filename, strerror(errno));
- goto out;
- }
-
- if (!S_ISREG(handle.st.st_mode)) {
- errmsg(V_WARNING, _("%s: Not a regular file, skipping"),
- filename);
- goto out;
- }
-
- if (handle.st.st_size <= 0) {
- errmsg(V_ERROR, _("%s: File is empty"), filename);
- goto out;
- }
-
- if (listing_pread(&handle, 0))
- goto out;
-
- if (handle.buffer[0] == 0xFF) {
- if (opt_header == HEADER_ALONE) {
- errmsg(V_ERROR, "%s: FIXME", filename); // FIXME
- goto out;
- }
-
- list_native(&handle);
- } else {
- if (opt_header != HEADER_AUTO && opt_header != HEADER_ALONE) {
- errmsg(V_ERROR, "%s: FIXME", filename); // FIXME
- goto out;
- }
-
- list_alone(&handle);
- }
-
-out:
- (void)close(fd);
- return;
-}