169 Commits

Author SHA1 Message Date
Lasse Collin
2267f5b0d2 Bump the version number to 5.3.1alpha. 2018-04-29 18:58:19 +03:00
Lasse Collin
cee3021d30 extra/scanlzma: Fix compiler warnings. 2018-04-29 18:48:00 +03:00
Lasse Collin
c5c7ceb08a DOS: Add file_info.c to the list of files to build. 2018-04-29 18:44:47 +03:00
Lasse Collin
114cab97af Update NEWS for 5.3.1alpha. 2018-04-29 18:33:10 +03:00
Lasse Collin
b8139e11c5 Add NEWS for 5.2.4. 2018-04-29 18:30:48 +03:00
Lasse Collin
47b59d47cf Update THANKS. 2018-02-06 19:36:30 +02:00
Ben Boeckel
bc19799169 nothrow: use noexcept for C++11 and newer
In C++11, the `throw()` specifier is deprecated and `noexcept` is
preffered instead.
2018-02-06 18:41:45 +02:00
Lasse Collin
fb6d4f83cb liblzma: Remove incorrect #ifdef from range_common.h.
In most cases it was harmless but it could affect some
custom build systems.

Thanks to Pippijn van Steenhoven.
2018-02-06 18:02:48 +02:00
Lasse Collin
bc577d35c2 Update THANKS. 2018-01-10 22:10:39 +02:00
Lasse Collin
713bbc1a80 tuklib_integer: New Intel C compiler needs immintrin.h.
Thanks to Melanie Blower (Intel) for the patch.
2018-01-10 21:54:27 +02:00
Lasse Collin
a0ee1afbd9 Update THANKS. 2017-09-24 20:04:24 +03:00
Lasse Collin
a1e2c568de Windows: Fix paths in VS project files.
Some paths use slashes instead of backslashes as directory
separators... now it should work (I tested VS2013 version).
2017-09-16 20:36:20 +03:00
Lasse Collin
cea5cf8d26 Windows: Update VS2017 project files to include file info decoder. 2017-09-16 12:56:20 +03:00
Lasse Collin
95d563db3e Windows: Add project files for VS2017.
These files match the v5.2 branch (no file info decoder).
2017-09-16 12:56:05 +03:00
Lasse Collin
ab72416d62 Windows: Update VS2013 project files to include file info decoder. 2017-09-16 12:45:50 +03:00
Lasse Collin
8238898018 Windows: Move VS2013 files into windows/vs2013 directory. 2017-09-16 12:44:06 +03:00
Lasse Collin
94e3f986aa Fix or hide warnings from GCC 7's -Wimplicit-fallthrough. 2017-08-14 20:08:33 +03:00
Alexey Tourbin
0b0e1e6803 Docs: Fix a typo in a comment in doc/examples/02_decompress.c. 2017-05-23 18:46:49 +03:00
Lasse Collin
a015cd1f90 xz: Fix "xz --list --robot missing_or_bad_file.xz".
It ended up printing an uninitialized char-array when trying to
print the check names (column 7) on the "totals" line.

This also changes the column 12 (minimum xz version) to
50000002 (xz 5.0.0) instead of 0 when there are no valid
input files.

Thanks to kidmin for the bug report.
2017-05-23 18:34:43 +03:00
Lasse Collin
c2e29f06a7 Docs: Add doc/examples/11_file_info.c. 2017-04-24 20:20:11 +03:00
Lasse Collin
1520f6ec80 Build: Omit pre-5.0.0 entries from the generated ChangeLog.
It makes ChangeLog significantly smaller.
2017-04-24 19:48:47 +03:00
Lasse Collin
8269782283 xz: Use lzma_file_info_decoder() for --list. 2017-04-24 19:48:23 +03:00
Lasse Collin
e353d0b1cc liblzma: Add lzma_file_info_decoder(). 2017-04-24 19:48:04 +03:00
Lasse Collin
144ef9e19e Update the Git repository URL to HTTPS in ChangeLog. 2017-04-24 19:30:22 +03:00
Lasse Collin
8c9842c265 liblzma: Rename LZMA_SEEK to LZMA_SEEK_NEEDED and seek_in to seek_pos. 2017-04-21 15:05:16 +03:00
Lasse Collin
662b27c417 Update the home page URLs to HTTPS. 2017-04-19 22:17:35 +03:00
Lasse Collin
c28f0b3d00 xz: Add io_seek_src(). 2017-04-05 18:47:22 +03:00
Lasse Collin
bba477257d xz: Use POSIX_FADV_RANDOM for in "xz --list" mode.
xz --list is random access so POSIX_FADV_SEQUENTIAL was clearly
wrong.
2017-03-30 22:01:54 +03:00
Lasse Collin
310d19816d liblzma: Make lzma_index_decoder_init() visible to other liblzma funcs.
This is to allow other functions to use it without going
via the public API (lzma_index_decoder()).
2017-03-30 20:03:05 +03:00
Lasse Collin
a27920002d liblzma: Add generic support for input seeking (LZMA_SEEK).
Also mention LZMA_SEEK in xz/message.c to silence a warning.
2017-03-30 20:00:09 +03:00
Lasse Collin
a0b1dda409 liblzma: Fix lzma_memlimit_set(strm, 0).
The 0 got treated specially in a buggy way and as a result
the function did nothing. The API doc said that 0 was supposed
to return LZMA_PROG_ERROR but it didn't.

Now 0 is treated as if 1 had been specified. This is done because
0 is already used to indicate an error from lzma_memlimit_get()
and lzma_memusage().

In addition, lzma_memlimit_set() no longer checks that the new
limit is at least LZMA_MEMUSAGE_BASE. It's counter-productive
for the Index decoder and was actually needed only by the
auto decoder. Auto decoder has now been modified to check for
LZMA_MEMUSAGE_BASE.
2017-03-30 19:51:14 +03:00
Lasse Collin
84462afaad liblzma: Similar memlimit fix for stream_, alone_, and auto_decoder. 2017-03-30 19:16:55 +03:00
Lasse Collin
cbc7401793 liblzma: Fix handling of memlimit == 0 in lzma_index_decoder().
It returned LZMA_PROG_ERROR, which was done to avoid zero as
the limit (because it's a special value elsewhere), but using
LZMA_PROG_ERROR is simply inconvenient and can cause bugs.

The fix/workaround is to treat 0 as if it were 1 byte. It's
effectively the same thing. The only weird consequence is
that then lzma_memlimit_get() will return 1 even when 0 was
specified as the limit.

This fixes a very rare corner case in xz --list where a specific
memory usage limit and a multi-stream file could print the
error message "Internal error (bug)" instead of saying that
the memory usage limit is too low.
2017-03-30 19:10:55 +03:00
Lasse Collin
78ae13bced Update NEWS for 5.2.3. 2016-12-30 13:33:16 +02:00
Lasse Collin
0297863fdb Document --enable-sandbox configure option in INSTALL. 2016-12-26 20:55:52 +02:00
Lasse Collin
d4a0462abe liblzma: Avoid multiple definitions of lzma_coder structures.
Only one definition was visible in a translation unit.
It avoided a few casts and temp variables but seems that
this hack doesn't work with link-time optimizations in compilers
as it's not C99/C11 compliant.

Fixes:
http://www.mail-archive.com/xz-devel@tukaani.org/msg00279.html
2016-11-21 20:24:50 +02:00
Lasse Collin
a01794c52a Update THANKS. 2016-10-24 18:53:25 +03:00
Lasse Collin
df8f446e3a tuklib_cpucores: Add support for sched_getaffinity().
It's available in glibc (GNU/Linux, GNU/kFreeBSD). It's better
than sysconf(_SC_NPROCESSORS_ONLN) because sched_getaffinity()
gives the number of cores available to the process instead of
the total number of cores online.

As a side effect, this commit fixes a bug on GNU/kFreeBSD where
configure would detect the FreeBSD-specific cpuset_getaffinity()
but it wouldn't actually work because on GNU/kFreeBSD it requires
using -lfreebsd-glue when linking. Now the glibc-specific function
will be used instead.

Thanks to Sebastian Andrzej Siewior for the original patch
and testing.
2016-10-24 18:51:36 +03:00
Lasse Collin
446e4318fa xz: Fix copying of timestamps on Windows.
xz used to call utime() on Windows, but its result gets lost
on close(). Using _futime() seems to work.

Thanks to Martok for reporting the bug:
http://www.mail-archive.com/xz-devel@tukaani.org/msg00261.html
2016-06-30 20:27:36 +03:00
Lasse Collin
1b0ac0c53c xz: Silence warnings from -Wlogical-op.
Thanks to Evan Nemerson.
2016-06-16 22:46:02 +03:00
Lasse Collin
c83b7a0334 Build: Fix = to += for xz_SOURCES in src/xz/Makefile.am.
Thanks to Christian Kujau.
2016-04-10 20:55:49 +03:00
Lasse Collin
ade31a2bfb Build: Bump GNU Gettext version requirement to 0.19.
It silences a few warnings and most people probably have
0.19 even on stable distributions.

Thanks to Christian Kujau.
2016-04-10 20:54:17 +03:00
Lasse Collin
ac398c3baf liblzma: Disable external SHA-256 by default.
This is the sane thing to do. The conflict with OpenSSL
on some OSes and especially that the OS-provided versions
can be significantly slower makes it clear that it was
a mistake to have the external SHA-256 support enabled by
default.

Those who want it can now pass --enable-external-sha256 to
configure. INSTALL was updated with notes about OSes where
this can be a bad idea.

The SHA-256 detection code in configure.ac had some bugs that
could lead to a build failure in some situations. These were
fixed, although it doesn't matter that much now that the
external SHA-256 is disabled by default.

MINIX >= 3.2.0 uses NetBSD's libc and thus has SHA256_Init
in libc instead of libutil. Support for the libutil version
was removed.
2016-03-13 20:21:49 +02:00
Lasse Collin
6fd5ecb589 Update THANKS. 2016-03-10 20:27:05 +02:00
Lasse Collin
473ef0dc69 Build: Avoid SHA256_Init on FreeBSD and MINIX 3.
On FreeBSD 10 and older, SHA256_Init from libmd conflicts
with libcrypto from OpenSSL. The OpenSSL version has
different sizeof(SHA256_CTX) and it can cause weird
problems if wrong SHA256_Init gets used.

Looking at the source, MINIX 3 seems to have a similar issue but
I'm not sure. To be safe, I disabled SHA256_Init on MINIX 3 too.

NetBSD has SHA256_Init in libc and they had a similar problem,
but they already fixed it in 2009.

Thanks to Jim Wilcoxson for the bug report that helped
in finding the problem.
2016-03-10 20:26:49 +02:00
Lasse Collin
faf302137e tuklib_physmem: Hopefully silence a warning on Windows. 2015-11-08 20:16:10 +02:00
Lasse Collin
e52e9151cf Update THANKS. 2015-11-04 23:17:43 +02:00
Lasse Collin
14115f84a3 liblzma: Make Valgrind happier with optimized (gcc -O2) liblzma.
When optimizing, GCC can reorder code so that an uninitialized
value gets used in a comparison, which makes Valgrind unhappy.
It doesn't happen when compiled with -O0, which I tend to use
when running Valgrind.

Thanks to Rich Prohaska. I remember this being mentioned long
ago by someone else but nothing was done back then.
2015-11-04 23:14:00 +02:00
Lasse Collin
f4c95ba94b liblzma: Rename lzma_presets.c back to lzma_encoder_presets.c.
It would be too annoying to update other build systems
just because of this.
2015-11-03 20:55:45 +02:00
Lasse Collin
c7bc20a6f3 Build: Disable xzdec, lzmadec, and lzmainfo when they cannot be built.
They all need decoder support and if that isn't available,
there's no point trying to build them.
2015-11-03 20:47:07 +02:00
Lasse Collin
5cbca1205d Build: Simplify $enable_{encoders,decoders} usage a bit. 2015-11-03 20:35:19 +02:00
Lasse Collin
af13781886 Windows/MSVC: Update config.h. 2015-11-03 20:31:31 +02:00
Lasse Collin
9fa5949330 DOS: Update config.h. 2015-11-03 20:29:58 +02:00
Lasse Collin
cb3111e3ed xz: Make xz buildable even when encoders or decoders are disabled.
The patch is quite long but it's mostly about adding new #ifdefs
to omit code when encoders or decoders have been disabled.

This adds two new #defines to config.h: HAVE_ENCODERS and
HAVE_DECODERS.
2015-11-03 20:29:33 +02:00
Lasse Collin
4cc584985c Build: Build LZMA1/2 presets also when only decoder is wanted.
People shouldn't rely on the presets when decoding raw streams,
but xz uses the presets as the starting point for raw decoder
options anyway.

lzma_encocder_presets.c was renamed to lzma_presets.c to
make it clear it's not used solely by the encoder code.
2015-11-03 18:06:40 +02:00
Lasse Collin
23ed1d4148 Build: Fix configure to handle LZMA1 dependency with LZMA2.
Now it gives an error if LZMA1 encoder/decoder is missing
when LZMA2 encoder/decoder was requested. Even better would
be LZMA2 implicitly enabling LZMA1 but it would need more code.
2015-11-03 17:54:48 +02:00
Lasse Collin
b0bc3e0385 Build: Don't omit lzma_cputhreads() unless using --disable-threads.
Previously it was omitted if encoders were disabled
with --disable-encoders. It didn't make sense and
it also broke the build.
2015-11-03 17:41:54 +02:00
Lasse Collin
c6bf438ab3 liblzma: Fix a build failure related to external SHA-256 support.
If an appropriate header and structure were found by configure,
but a library with a usable SHA-256 functions wasn't, the build
failed.
2015-11-02 18:16:51 +02:00
Lasse Collin
e18adc56f2 xz: Always close the file before trying to delete it.
unlink() can return EBUSY in errno for open files on some
operating systems and file systems.
2015-11-02 15:19:10 +02:00
Lasse Collin
282e768a14 Update THANKS. 2015-10-12 21:08:42 +03:00
Lasse Collin
372e402713 Tests: Add tests for the two bugs fixed in index.c. 2015-10-12 21:07:41 +03:00
Lasse Collin
21515d79d7 liblzma: Fix lzma_index_dup() for empty Streams.
Stream Flags and Stream Padding weren't copied from
empty Streams.
2015-10-12 20:45:15 +03:00
Lasse Collin
09f395b6b3 liblzma: Add a note to index.c for those using static analyzers. 2015-10-12 20:31:44 +03:00
Lasse Collin
3bf857edfe liblzma: Fix a memory leak in error path of lzma_index_dup().
lzma_index_dup() calls index_dup_stream() which, in case of
an error, calls index_stream_end() to free memory allocated
by index_stream_init(). However, it illogically didn't
actually free the memory. To make it logical, the tree
handling code was modified a bit in addition to changing
index_stream_end().

Thanks to Evan Nemerson for the bug report.
2015-10-12 20:29:09 +03:00
Lasse Collin
7f05803979 Update NEWS for 5.2.2. 2015-09-29 13:57:28 +03:00
Hauke Henningsen
397fcc0946 Update German translation, mostly wrt orthography
Provide an update of the German translation.
* A lot of compound words were previously written with spaces, while
  German orthography is relatively clear in that the components
  should not be separated.
* When referring to the actual process of (de)compression rather than the
  concept, replace “(De-)Kompression” with “(De-)Komprimierung”.
  Previously, both forms were used in this context and are now used in a
  manner consistent with “Komprimierung” being more likely to refer to
  a process.
* Consistently translate “standard input”/“output”
* Use “Zeichen” instead of false friend “Charakter” for “character”
* Insert commas around relative clauses (as required in German)
* Some other minor corrections
* Capitalize “ß” as “ẞ”
* Consistently start option descriptions in --help with capital letters

Acked-By: Andre Noll <maan@tuebingen.mpg.de>

* Update after msgmerge
2015-08-27 21:28:37 +03:00
Lasse Collin
cbc9e39bae Build: Minor Cygwin cleanup.
Some tests used "cygwin*" and some used "cygwin". I changed
them all to use "cygwin". Shouldn't affect anything in practice.
2015-08-11 13:23:04 +03:00
Lasse Collin
bcacd8ce7a Build: Support building of MSYS2 binaries. 2015-08-11 13:21:52 +03:00
Lasse Collin
0275a5398c Windows: Define DLL_EXPORT when building liblzma.dll with MSVC.
src/liblzma/common/common.h uses it to set __declspec(dllexport)
for the API symbols.

Thanks to Adam Walling.
2015-08-09 21:06:26 +03:00
Lasse Collin
a74525cf9b Windows: Omit unneeded header files from MSVC project files. 2015-08-09 21:02:20 +03:00
Lasse Collin
fbbb295a91 liblzma: A MSVC-specific hack isn't needed with MSVC 2013 and newer. 2015-07-12 20:48:19 +03:00
Lasse Collin
713dbe5c23 Update THANKS. 2015-06-19 20:38:55 +03:00
Lasse Collin
3a5d755d05 Windows: Update the docs. 2015-06-19 20:21:30 +03:00
Lasse Collin
b0798c6aa6 Windows: Add MSVC project files for building liblzma.
Thanks to Adam Walling for creating these files.
2015-06-19 17:25:31 +03:00
Andre Noll
9b02a4ffda Fix typo in German translation.
As pointed out by Robert Pollak, there's a typo in the German
translation of the compression preset option (-0 ... -9) help text.
"The compressor" translates to "der Komprimierer", and the genitive
form is "des Komprimierers". The old word makes no sense at all.
2015-06-10 21:01:09 +03:00
Lasse Collin
c7f4041f6b Tests: Fix a memory leak in test_bcj_exact_size.
Thanks to Cristian Rodríguez.
2015-05-13 20:57:55 +03:00
Lasse Collin
17b29d4f0a Fix NEWS about threading in 5.2.0.
Thanks to Andy Hochhaus.
2015-05-12 18:08:24 +03:00
Lasse Collin
49c26920d6 xz: Document that threaded decompression hasn't been implemented yet. 2015-05-11 21:26:16 +03:00
Lasse Collin
5b2458cb24 Update THANKS. 2015-04-20 20:20:38 +03:00
Lasse Collin
6bd0349c58 Revert "xz: Use pipe2() if available."
This reverts commit 7a11c4a8e5.
It is a problem when libc has pipe2() but the kernel is too
old to have pipe2() and thus pipe2() fails. In xz it's pointless
to have a fallback for non-functioning pipe2(); it's better to
avoid pipe2() completely.

Thanks to Michael Fox for the bug report.
2015-04-20 20:17:48 +03:00
Lasse Collin
fc0df0f8db xz: Fix the Capsicum rights on user_abort_pipe. 2015-04-01 14:45:25 +03:00
Lasse Collin
57393615b3 Update THANKS. 2015-03-31 22:20:11 +03:00
Lasse Collin
1238381143 xz: Add support for sandboxing with Capsicum.
The sandboxing is used conditionally as described in main.c.
This isn't optimal but it was much easier to implement than
a full sandboxing solution and it still covers the most common
use cases where xz is writing to standard output. This should
have practically no effect on performance even with small files
as fork() isn't needed.

C and locale libraries can open files as needed. This has been
fine in the past, but it's a problem with things like Capsicum.
io_sandbox_enter() tries to ensure that various locale-related
files have been loaded before cap_enter() is called, but it's
possible that there are other similar problems which haven't
been seen yet.

Currently Capsicum is available on FreeBSD 10 and later
and there is a port to Linux too.

Thanks to Loganaden Velvindron for help.
2015-03-31 22:19:34 +03:00
Lasse Collin
29a087fb5a Fix bugs and otherwise improve ax_check_capsicum.m4.
AU_ALIAS was removed because the new version is incompatible
with the old version.

It no longer checks for <sys/capability.h> separately.
It's enough to test for it as part of AC_CHECK_DECL.
The defines HAVE_CAPSICUM_SYS_CAPSICUM_H and
HAVE_CAPSICUM_SYS_CAPABILITY_H were removed as unneeded.
HAVE_SYS_CAPSICUM_H from AC_CHECK_HEADERS is enough.

It no longer does a useless search for the Capsicum library
if the header wasn't found.

Fixed a bug in ACTION-IF-FOUND (the first argument). Specifying
the argument omitted the default action but the given action
wasn't used instead.

AC_DEFINE([HAVE_CAPSICUM]) is now always called when Capsicum
support is found. Previously it was part of the default
ACTION-IF-FOUND which a custom action would override. Now
the default action only prepends ${CAPSICUM_LIB} to LIBS.

The documentation was updated.

Since there as no serial number, "#serial 2" was added.
2015-03-31 21:12:30 +03:00
Lasse Collin
6e845c6a3e Add m4/ax_check_capsicum.m4 for detecting Capsicum support.
The file was loaded from this web page:
https://github.com/google/capsicum-test/blob/dev/autoconf/m4/ax_check_capsicum.m4

Thanks to Loganaden Velvindron for pointing it out for me.
2015-03-31 19:20:24 +03:00
Lasse Collin
3717885f9e Bump version to 5.3.0alpha and soname to 5.3.99.
The idea of 99 is that it looks a bit weird in this context.
For new features there's no API/ABI stability in devel versions.
2015-03-30 22:44:02 +03:00
Lasse Collin
eccd8155e1 Update THANKS. 2015-03-29 22:14:47 +03:00
Lasse Collin
25263fd9e7 Fix the detection of installed RAM on QNX.
The earlier version compiled but didn't actually work
since sysconf(_SC_PHYS_PAGES) always fails (or so I was told).

Thanks to Ole André Vadla Ravnås for the patch and testing.
2015-03-29 22:13:48 +03:00
Lasse Collin
4c544d2410 Fix CPU core count detection on QNX.
It tried to use sysctl() on QNX but
  - it broke the build because sysctl() needs -lsocket on QNX;
  - sysctl() doesn't work for detecting the core count on QNX
    even if it compiled.

sysconf() works. An alternative would have been to use
QNX-specific SYSPAGE_ENTRY(num_cpu) from <sys/syspage.h>.

Thanks to Ole André Vadla Ravnås.
2015-03-27 22:39:07 +02:00
Lasse Collin
e0ea6737b0 xz: size_t/uint32_t cleanup in options.c. 2015-03-07 22:05:57 +02:00
Lasse Collin
8bcca29a65 xz: Fix a comment and silence a warning in message.c. 2015-03-07 22:04:23 +02:00
Lasse Collin
f243f5f44c liblzma: Silence more uint32_t vs. size_t warnings. 2015-03-07 22:01:00 +02:00
Lasse Collin
7f0a4c50f4 xz: Make arg_count an unsigned int to silence a warning.
Actually the value of arg_count cannot exceed INT_MAX
but it's nicer as an unsigned int.
2015-03-07 19:54:00 +02:00
Lasse Collin
f6ec468015 liblzma: Fix a warning in index.c. 2015-03-07 19:33:17 +02:00
Lasse Collin
a24518971c Build: Fix a CR+LF problem when running autoreconf -fi on OS/2. 2015-02-26 20:46:14 +02:00
Lasse Collin
dec11497a7 Bump version and soname for 5.2.1. 2015-02-26 16:53:44 +02:00
Lasse Collin
29e39c7997 Update NEWS for 5.2.1. 2015-02-26 13:01:09 +02:00
Lasse Collin
7a11c4a8e5 xz: Use pipe2() if available. 2015-02-22 19:38:48 +02:00
Lasse Collin
117d962685 liblzma: Fix a compression-ratio regression in LZMA1/2 in fast mode.
The bug was added in the commit
f48fce093b and thus
affected 5.1.4beta and 5.2.0. Luckily the bug cannot
cause data corruption or other nasty things.
2015-02-21 23:40:26 +02:00
Lasse Collin
ae984e31c1 xz: Fix the fcntl() usage when creating a pipe for the self-pipe trick.
Now it reads the old flags instead of blindly setting O_NONBLOCK.
The old code may have worked correctly, but this is better.
2015-02-21 23:00:19 +02:00
Lasse Collin
2205bb5853 Update THANKS. 2015-02-10 15:29:34 +02:00
Lasse Collin
d935b0cdf3 tuklib_cpucores: Use cpuset_getaffinity() on FreeBSD if available.
In FreeBSD, cpuset_getaffinity() is the preferred way to get
the number of available cores.

Thanks to Rui Paulo for the patch. I edited it slightly, but
hopefully I didn't break anything.
2015-02-10 15:28:30 +02:00
Lasse Collin
eb61bc58c2 xzdiff: Make the mktemp usage compatible with FreeBSD's mktemp.
Thanks to Rui Paulo for the fix.
2015-02-09 22:08:37 +02:00
Lasse Collin
b9a5b6b7a2 Add a few casts to tuklib_integer.h to silence possible warnings.
I heard that Visual Studio 2013 gave warnings without the casts.

Thanks to Gabi Davar.
2015-02-03 21:45:53 +02:00
Lasse Collin
c45757135f liblzma: Set LZMA_MEMCMPLEN_EXTRA depending on the compare method. 2015-01-26 21:24:39 +02:00
Lasse Collin
3c500174ed Update THANKS. 2015-01-26 20:40:16 +02:00
Lasse Collin
fec88d41e6 liblzma: Silence harmless Valgrind errors.
Thanks to Torsten Rupp for reporting this. I had
forgotten to run Valgrind before the 5.2.0 release.
2015-01-26 20:39:28 +02:00
Lasse Collin
a9b45badfe xz: Fix comments. 2015-01-09 21:50:19 +02:00
Lasse Collin
541aee6dd4 Update THANKS. 2015-01-09 21:35:06 +02:00
Lasse Collin
4170edc914 xz: Don't fail if stdout doesn't support O_NONBLOCK.
This is similar to the case with stdin.

Thanks to Brad Smith for the bug report and testing
on OpenBSD.
2015-01-09 21:34:06 +02:00
Lasse Collin
04bbc0c284 xz: Fix a memory leak in DOS-specific code. 2015-01-07 19:18:20 +02:00
Lasse Collin
f0f1f6c723 xz: Don't fail if stdin doesn't support O_NONBLOCK.
It's a problem at least on OpenBSD which doesn't support
O_NONBLOCK on e.g. /dev/null. I'm not surprised if it's
a problem on other OSes too since this behavior is allowed
in POSIX-1.2008.

The code relying on this behavior was committed in June 2013
and included in 5.1.3alpha released on 2013-10-26. Clearly
the development releases only get limited testing.
2015-01-07 19:08:06 +02:00
Lasse Collin
d2d484647d Tests: Don't hide unexpected error messages in test_files.sh.
Hiding them makes no sense since normally there's no error
when testing the "good" files. With "bad" files errors are
expected and then it makes sense to keep the messages hidden.
2015-01-06 20:30:15 +02:00
Lasse Collin
aae6a6aeda Update Solaris notes in INSTALL.
Mention the possible "make check" failure on Solaris in the
Solaris-specific section of INSTALL. It was already in
section 4.5 but it is better mention it in the OS-specific
section too.
2014-12-30 11:17:16 +02:00
Lasse Collin
7815112153 Build: POSIX shell isn't required if scripts are disabled. 2014-12-26 12:00:05 +02:00
Lasse Collin
a0cd05ee71 DOS: Update Makefile. 2014-12-21 20:48:37 +02:00
Lasse Collin
b85ee0905e Windows: Fix bin_i486 to bin_i686 in build.bash. 2014-12-21 19:50:38 +02:00
Lasse Collin
cbafa71091 Docs: Use lzma_cputhreads() in 04_compress_easy_mt.c. 2014-12-21 18:58:44 +02:00
Lasse Collin
8dbb57238d Docs: Update docs/examples/00_README.txt. 2014-12-21 18:56:44 +02:00
Lasse Collin
6060f7dc76 Bump version and soname for 5.2.0.
I know that soname != app version, but I skip AGE=1
in -version-info to make the soname match the liblzma
version anyway. It doesn't hurt anything as long as
it doesn't conflict with library versioning rules.
2014-12-21 18:11:17 +02:00
Lasse Collin
3e8bd1d15e Avoid variable-length arrays in the debug programs. 2014-12-21 18:05:03 +02:00
Lasse Collin
72f7307cfd Build: Include 04_compress_easy_mt.c in the tarball. 2014-12-21 18:01:45 +02:00
Lasse Collin
2cb82ff21c Fix build when --disable-threads is used. 2014-12-21 18:00:38 +02:00
Adrien Nader
9b9e3536e4 po/fr: improve wording for help for --lzma1/--lzma2. 2014-12-21 18:00:09 +02:00
Adrien Nader
a8b6b569e7 po/fr: missing line in translation of --extreme. 2014-12-21 18:00:09 +02:00
Lasse Collin
f168a6fd1a Update NEWS for 5.2.0. 2014-12-21 14:32:33 +02:00
Lasse Collin
cec2ee863b Update NEWS for 5.0.8. 2014-12-21 14:32:22 +02:00
Lasse Collin
42e97a3264 xz: Fix a comment. 2014-12-21 14:07:54 +02:00
Lasse Collin
29b95d5d66 Update INSTALL about the dependencies of the scripts. 2014-12-20 20:43:14 +02:00
Lasse Collin
3af91040bb Windows: Update build instructions. 2014-12-20 20:42:33 +02:00
Lasse Collin
0152f72bf6 Windows: Update the build script and README-Windows.txt.
The 32-bit build is now for i686 or newer because the
prebuilt MinGW-w64 toolchains include i686 code in the
executables even if one uses -march=i486.

The build script builds 32-bit SSE2 enabled version too.
Run-time detection of SSE2 support would be nice (on any OS)
but it's not implemented in XZ Utils yet.
2014-12-20 20:41:48 +02:00
Lasse Collin
4a1f6133ee Windows: Define TUKLIB_SYMBOL_PREFIX in config.h.
It is to keep all symbols in the lzma_ namespace.
2014-12-19 15:51:50 +02:00
Lasse Collin
7f7d093de7 xz: Update the man page about --threads. 2014-12-16 21:00:09 +02:00
Lasse Collin
009823448b xz: Update the man page about --block-size. 2014-12-16 20:57:43 +02:00
Adrien Nader
7dddfbeb49 po/fr: several more translation updates: reword and handle --ignore-check. 2014-12-12 19:16:10 +02:00
Adrien Nader
6eca5be40e po/fr: yet another place where my email address had to be updated. 2014-12-12 19:16:10 +02:00
Adrien Nader
d1003673e9 po/fr: fix several typos that have been around since the beginning. 2014-12-12 19:16:10 +02:00
Adrien Nader
4c5aa911a0 po/fr: last batch of new translations for now.
Four new error messages.
2014-12-12 19:16:10 +02:00
Adrien Nader
3e3099e36d po/fr: translations for --threads, --block-size and --block-list. 2014-12-12 19:16:10 +02:00
Adrien Nader
e7d96a5933 po/fr: remove fuzzy marker for error messages that will be kept in English.
The following is a copy of a comment inside fr.po:

Note from translator on "file status flags".
The following entry is kept un-translated on purpose. It is difficult to
translate and should only happen in exceptional circumstances which means
that translating would:
- lose some of the meaning
- make it more difficult to look up in search engines; it might happen one
in
a million times, if we dilute the error message in 20 languages, it will be
almost impossible to find an explanation and support for the error.
2014-12-12 19:16:10 +02:00
Adrien Nader
46cbb9033a po/fr: several minor updates and better wording.
Meaning doesn't change at all: it's only for better wording and/or
formatting of a few strings.
2014-12-12 19:16:10 +02:00
Adrien Nader
7ce49d444f po/fr: update my email address and copyright years. 2014-12-12 19:16:09 +02:00
Adrien Nader
214c553ebc fr.po: commit file after only "update-po" so actual is readable. 2014-12-12 19:16:09 +02:00
Lasse Collin
1190c641af liblzma: Document how lzma_mt.block_size affects memory usage. 2014-12-02 20:04:07 +02:00
Lasse Collin
e4fc1d2f95 Update INSTALL about a "make check" failure in test_scripts.sh. 2014-11-28 20:07:18 +02:00
Lasse Collin
34f9e40a0a Remove LZMA_UNSTABLE macro. 2014-11-26 20:12:27 +02:00
Lasse Collin
6d9c0ce9f2 liblzma: Update lzma_stream_encoder_mt() API docs. 2014-11-26 20:10:33 +02:00
Lasse Collin
2301f3f05d liblzma: Verify the filter chain in threaded encoder initialization.
This way an invalid filter chain is detected at the Stream
encoder initialization instead of delaying it to the first
call to lzma_code() which triggers the initialization of
the actual filter encoder(s).
2014-11-25 12:32:05 +02:00
Lasse Collin
107a263d5b Build: Update m4/ax_pthread.m4 from Autoconf Archive. 2014-11-17 19:11:49 +02:00
Lasse Collin
b13a781833 Build: Replace obsolete AC_HELP_STRING with AS_HELP_STRING. 2014-11-17 18:52:21 +02:00
Lasse Collin
542cac122e Build: Fix Autoconf warnings about escaped backquotes.
Thanks to Daniel Richard G. for pointing out that it's
good to sometimes run autoreconf -fi with -Wall.
2014-11-17 18:43:19 +02:00
Lasse Collin
7b03a15cea xzdiff: Use mkdir if mktemp isn't available. 2014-11-10 18:54:40 +02:00
Lasse Collin
f8c13e5e36 xzdiff: Create a temporary directory to hold a temporary file.
This avoids the possibility of "File name too long" when
creating a temp file when the input file name is very long.

This also means that other users on the system can no longer
see the input file names in /tmp (or whatever $TMPDIR is)
since the temporary directory will have a generic name. This
usually doesn't matter since on many systems one can see
the arguments given to all processes anyway.

The number X chars to mktemp where increased from 6 to 10.

Note that with some shells temp files or dirs won't be used at all.
2014-11-10 18:45:01 +02:00
Lasse Collin
7716dcf9df liblzma: Fix lzma_mt.preset in lzma_stream_encoder_mt_memusage().
It read the filter chain from a wrong variable. This is a similar
bug that was fixed in 9494fb6d0f.
2014-11-10 15:38:47 +02:00
Lasse Collin
230fa4a605 Update THANKS. 2014-11-10 14:49:55 +02:00
Lasse Collin
4e4ae08bc7 Update .gitignore files. 2014-10-29 21:28:25 +02:00
Lasse Collin
c923b140b2 Build: Prepare to support Automake's subdir-objects.
Due to a bug in Automake, subdir-objects won't be enabled
for now.

http://debbugs.gnu.org/cgi/bugreport.cgi?bug=17354

Thanks to Daniel Richard G. for the original patches.
2014-10-29 21:15:35 +02:00
Lasse Collin
08c2aa16be Translations: Update the Italian translation.
Thanks to Milo Casagrande.
2014-10-24 20:09:29 +03:00
Lasse Collin
2f9f61aa83 Translations: Update the Polish translation.
Thanks to Jakub Bogusz.
2014-10-18 18:51:45 +03:00
Andre Noll
4f9d233f67 l10n: de.po: Change translator email address.
Although the old address is still working, the new one should
be preferred. So this commit changes all three places in de.po
accordingly.

Signed-off-by: Andre Noll <maan@tuebingen.mpg.de>
2014-10-14 22:06:10 +03:00
Andre Noll
00502b2bed l10n: de.po: Update German translation
Signed-off-by: Andre Noll <maan@systemlinux.org>
2014-10-14 22:06:10 +03:00
Andre Noll
706b049675 l10n: de.po: Fix typo: Schießen -> Schließen.
That's a funny one since "schießen" means to shoot :)

Signed-off-by: Andre Noll <maan@systemlinux.org>
2014-10-14 22:06:09 +03:00
Lasse Collin
7c32e6a935 Update THANKS. 2014-10-09 19:42:26 +03:00
Lasse Collin
076258cc45 Add support for AmigaOS/AROS to tuklib_physmem().
Thanks to Fredrik Wikstrom.
2014-10-09 19:41:51 +03:00
Lasse Collin
efa7b0a210 xzgrep: Avoid passing both -q and -l to grep.
The behavior of grep -ql varies:
  - GNU grep behaves like grep -q.
  - OpenBSD grep behaves like grep -l.

POSIX doesn't make it 100 % clear what behavior is expected.
Anyway, using both -q and -l at the same time makes no sense
so both options simply should never be used at the same time.

Thanks to Christian Weisgerber.
2014-10-09 18:42:14 +03:00
Trần Ngọc Quân
9c5f76098c l10n: vi.po: Update Vietnamese translation
Signed-off-by: Trần Ngọc Quân <vnwildman@gmail.com>
2014-10-04 08:33:39 +07:00
Lasse Collin
c4911f2db3 Build: Detect supported compiler warning flags better.
Clang and nowadays also GCC accept any -Wfoobar option
but then may give a warning that an unknown warning option
was specified. To avoid adding unsupported warning options,
the options are now tested with -Werror.

Thanks to Charles Diza.
2014-09-25 18:38:48 +03:00
Lasse Collin
76e75522ed Update NEWS for 5.0.7. 2014-09-20 21:01:21 +03:00
Lasse Collin
d62028b4c1 liblzma: Fix a portability problem in Makefile.am.
POSIX supports $< only in inference rules (suffix rules).
Using it elsewhere is a GNU make extension and doesn't
work e.g. with OpenBSD make.

Thanks to Christian Weisgerber for the patch.
2014-09-20 19:42:56 +03:00
122 changed files with 6237 additions and 1889 deletions

2
.gitignore vendored
View File

@@ -1,6 +1,7 @@
*~
*.bak
*.bak[0-9]
.gdb_history
.deps
.libs
@@ -29,6 +30,7 @@ build-aux/depcomp
build-aux/install-sh
build-aux/ltmain.sh
build-aux/missing
build-aux/test-driver
/src/liblzma/liblzma.pc
/src/lzmainfo/lzmainfo

View File

@@ -47,7 +47,7 @@ XZ Utils Licensing
naturally it is not legally required. Here is an example of a good
notice to put into "about box" or into documentation:
This software includes code from XZ Utils <http://tukaani.org/xz/>.
This software includes code from XZ Utils <https://tukaani.org/xz/>.
The following license texts are included in the following files:
- COPYING.LGPLv2.1: GNU Lesser General Public License version 2.1

View File

@@ -1,6 +1,6 @@
See the commit log in the git repository:
git clone http://git.tukaani.org/xz.git
git clone https://git.tukaani.org/xz.git
Note that "make dist" doesn't put this tiny file into the package.
Instead, the git commit log is used as ChangeLog. See dist-hook in

137
INSTALL
View File

@@ -122,6 +122,10 @@ XZ Utils Installation
This can be worked around by passing gl_cv_cc_visibility=no
as an argument to the configure script.
test_scripts.sh in "make check" may fail if good enough tools are
missing from PATH (/usr/xpg4/bin or /usr/xpg6/bin). See sections
4.5 and 3.2 for more information.
1.2.6. Tru64
@@ -132,21 +136,33 @@ XZ Utils Installation
1.2.7. Windows
Building XZ Utils on Windows is supported under MinGW + MSYS,
MinGW-w64 + MSYS, and Cygwin. There is windows/build.bash to
ease packaging XZ Utils with MinGW(-w64) + MSYS into a
redistributable .zip or .7z file. See windows/INSTALL-Windows.txt
for more information.
Building XZ Utils on Windows is supported under the following
environments:
It might be possible to build liblzma with a non-GNU toolchain too,
but that will probably require writing a separate makefile. Building
- MinGW-w64 + MSYS (32-bit and 64-bit x86): This is used
for building the official binary packages for Windows.
There is windows/build.bash to ease packaging XZ Utils with
MinGW(-w64) + MSYS into a redistributable .zip or .7z file.
See windows/INSTALL-MinGW.txt for more information.
- MinGW + MSYS (32-bit x86): I haven't recently tested this.
- Cygwin 1.7.35 and later: NOTE that using XZ Utils >= 5.2.0
under Cygwin older than 1.7.35 can lead to DATA LOSS! If
you must use an old Cygwin version, stick to XZ Utils 5.0.x
which is safe under older Cygwin versions. You can check
the Cygwin version with the command "cygcheck -V".
- Microsoft Visual Studio 2013 update 2 or later (MSVC for short):
See windows/INSTALL-MSVC.txt for more information.
It may be possible to build liblzma with other toolchains too, but
that will probably require writing a separate makefile. Building
the command line tools with non-GNU toolchains will be harder than
building only liblzma.
Even if liblzma is built with MinGW, the resulting DLL or static
library can be used by other compilers and linkers, including MSVC.
Thus, it shouldn't be a problem to use MinGW to build liblzma even
if you cannot use MinGW to build the rest of your project. See
Even if liblzma is built with MinGW(-w64), the resulting DLL can
be used by other compilers and linkers, including MSVC. See
windows/README-Windows.txt for details.
@@ -230,6 +246,42 @@ XZ Utils Installation
the liblzma ABI, so this option should be used only when
it is known to not cause problems.
--enable-external-sha256
Try to use SHA-256 code from the operating system libc
or similar base system libraries. This doesn't try to
use OpenSSL or libgcrypt or such libraries.
The reasons to use this option:
- It makes liblzma slightly smaller.
- It might improve SHA-256 speed if the implementation
in the operating is very good (but see below).
External SHA-256 is disabled by default for two reasons:
- On some operating systems the symbol names of the
SHA-256 functions conflict with OpenSSL's libcrypto.
This causes weird problems such as decompression
errors if an application is linked against both
liblzma and libcrypto. This problem affects at least
FreeBSD 10 and older and MINIX 3.3.0 and older, but
other OSes that provide a function "SHA256_Init" might
also be affected. FreeBSD 11 has the problem fixed.
NetBSD had the problem but it was fixed it in 2009
already. OpenBSD uses "SHA256Init" and thus never had
a conflict with libcrypto.
- The SHA-256 code in liblzma is faster than the SHA-256
code provided by some operating systems. If you are
curious, build two copies of xz (internal and external
SHA-256) and compare the decompression (xz --test)
times:
dd if=/dev/zero bs=1024k count=1024 \
| xz -v -0 -Csha256 > foo.xz
time xz --test foo.xz
--disable-xz
--disable-xzdec
--disable-lzmadec
@@ -347,6 +399,29 @@ XZ Utils Installation
calls any liblzma functions from more than
one thread, something bad may happen.
--enable-sandbox=METHOD
There is limited sandboxing support in the xz tool. If
built with sandbox support, it's used automatically when
(de)compressing exactly one file to standard output and
the options --files or --files0 weren't used. This is a
common use case, for example, (de)compressing .tar.xz
files via GNU tar. The sandbox is also used for
single-file `xz --test' or `xz --list'.
Supported METHODs:
auto Look for a supported sandboxing method
and use it if found. If no method is
found, then sandboxing isn't used.
This is the default.
no Disable sandboxing support.
capsicum
Use Capsicum (FreeBSD >= 10) for
sandboxing. If no Capsicum support
is found, configure will give an error.
--enable-symbol-versions
Use symbol versioning for liblzma. This is enabled by
default on GNU/Linux, other GNU-based systems, and
@@ -421,11 +496,16 @@ XZ Utils Installation
gl_cv_posix_shell=/path/to/posix-sh as an argument to the configure
script.
Some of the scripts require also mktemp. The original mktemp can be
found from <http://www.mktemp.org/>. On GNU, most will use the mktemp
program from GNU coreutils instead of the original implementation.
Both mktemp versions are fine for XZ Utils (and practically for
everything else too).
xzdiff (xzcmp/lzdiff/lzcmp) may use mktemp if it is available. As
a fallback xzdiff will use mkdir to securely create a temporary
directory. Having mktemp available is still recommended since the
mkdir fallback method isn't as robust as mktemp is. The original
mktemp can be found from <http://www.mktemp.org/>. On GNU, most will
use the mktemp program from GNU coreutils instead of the original
implementation. Both mktemp versions are fine.
In addition to using xz to decompress .xz files, xzgrep and xzdiff
use gzip, bzip2, and lzop to support .gz, bz2, and .lzo files.
3.2. PATH
@@ -466,7 +546,8 @@ XZ Utils Installation
to POSIX. The configure script tries to find such a shell. If
it fails, you can force the shell to be used by passing
gl_cv_posix_shell=/path/to/posix-sh as an argument to the configure
script.
script. Alternatively you can omit the installation of scripts and
this error by passing --disable-scripts to configure.
4.3. configure works but build fails at crc32_x86.S
@@ -500,13 +581,23 @@ XZ Utils Installation
4.5. "make check" fails
A likely reason is that libtool links the test programs against
an installed version of liblzma instead of the version that was
just built. This is obviously a bug which seems to happen on
some platforms. A workaround is to uninstall the old liblzma
versions first.
If the other tests pass but test_scripts.sh fails, then the problem
is in the scripts in src/scripts. Comparing the contents of
tests/xzgrep_test_output to tests/xzgrep_expected_output might
give a good idea about problems in xzgrep. One possibility is that
some tools are missing from the current PATH or the tools lack
support for some POSIX features. This can happen at least on
Solaris where the tools in /bin may be ancient but good enough
tools are available in /usr/xpg4/bin or /usr/xpg6/bin. One fix
for this problem is described in section 3.2 of this file.
If the problem isn't the one described above, then it's likely
If tests other than test_scripts.sh fail, a likely reason is that
libtool links the test programs against an installed version of
liblzma instead of the version that was just built. This is
obviously a bug which seems to happen on some platforms.
A workaround is to uninstall the old liblzma versions first.
If the problem isn't any of those described above, then it's likely
a bug in XZ Utils or in the compiler. See the platform-specific
notes in this file for possible known problems. Please report
a bug if you cannot solve the problem. See README for contact

View File

@@ -37,6 +37,7 @@ dist_examples_DATA = \
doc/examples/01_compress_easy.c \
doc/examples/02_decompress.c \
doc/examples/03_compress_custom.c \
doc/examples/04_compress_easy_mt.c \
doc/examples/Makefile
examplesolddir = $(docdir)/examples_old
@@ -76,7 +77,8 @@ manfiles = \
# Convert the man pages to PDF and plain text (ASCII only) formats.
dist-hook:
if test -d "$(srcdir)/.git" && type git > /dev/null 2>&1; then \
( cd "$(srcdir)" && git log --date=iso --stat ) \
( cd "$(srcdir)" && git log --date=iso --stat \
b667a3ef6338a2c1db7b7706b1f6c99ea392221c^..HEAD ) \
> "$(distdir)/ChangeLog"; \
fi
if type groff > /dev/null 2>&1 && type ps2pdf > /dev/null 2>&1; then \

198
NEWS
View File

@@ -2,6 +2,181 @@
XZ Utils Release Notes
======================
5.3.1alpha (2018-04-29)
* All fixes from 5.2.4.
* Add lzma_file_info_decoder() into liblzma and use it in xz to
implement the --list feature.
* Capsicum sandbox support is enabled by default where available
(FreeBSD >= 10).
5.2.4 (2018-04-29)
* liblzma:
- Allow 0 as memory usage limit instead of returning
LZMA_PROG_ERROR. Now 0 is treated as if 1 byte was specified,
which effectively is the same as 0.
- Use "noexcept" keyword instead of "throw()" in the public
headers when a C++11 (or newer standard) compiler is used.
- Added a portability fix for recent Intel C Compilers.
- Microsoft Visual Studio build files have been moved under
windows/vs2013 and windows/vs2017.
* xz:
- Fix "xz --list --robot missing_or_bad_file.xz" which would
try to print an unitialized string and thus produce garbage
output. Since the exit status is non-zero, most uses of such
a command won't try to interpret the garbage output.
- "xz --list foo.xz" could print "Internal error (bug)" in a
corner case where a specific memory usage limit had been set.
5.2.3 (2016-12-30)
* xz:
- Always close a file before trying to delete it to avoid
problems on some operating system and file system combinations.
- Fixed copying of file timestamps on Windows.
- Added experimental (disabled by default) sandbox support using
Capsicum (FreeBSD >= 10). See --enable-sandbox in INSTALL.
* C99/C11 conformance fixes to liblzma. The issues affected at least
some builds using link-time optimizations.
* Fixed bugs in the rarely-used function lzma_index_dup().
* Use of external SHA-256 code is now disabled by default.
It can still be enabled by passing --enable-external-sha256
to configure. The reasons to disable it by default (see INSTALL
for more details):
- Some OS-specific SHA-256 implementations conflict with
OpenSSL and cause problems in programs that link against both
liblzma and libcrypto. At least FreeBSD 10 and MINIX 3.3.0
are affected.
- The internal SHA-256 is faster than the SHA-256 code in
some operating systems.
* Changed CPU core count detection to use sched_getaffinity() on
GNU/Linux and GNU/kFreeBSD.
* Fixes to the build-system and xz to make xz buildable even when
encoders, decoders, or threading have been disabled from libilzma
using configure options. These fixes added two new #defines to
config.h: HAVE_ENCODERS and HAVE_DECODERS.
5.2.2 (2015-09-29)
* Fixed bugs in QNX-specific code.
* Omitted the use of pipe2() even if it is available to avoid
portability issues with some old Linux and glibc combinations.
* Updated German translation.
* Added project files to build static and shared liblzma (not the
whole XZ Utils) with Visual Studio 2013 update 2 or later.
* Documented that threaded decompression hasn't been implemented
yet. A 5.2.0 NEWS entry describing multi-threading support had
incorrectly said "decompression" when it should have said
"compression".
5.2.1 (2015-02-26)
* Fixed a compression-ratio regression in fast mode of LZMA1 and
LZMA2. The bug is present in 5.1.4beta and 5.2.0 releases.
* Fixed a portability problem in xz that affected at least OpenBSD.
* Fixed xzdiff to be compatible with FreeBSD's mktemp which differs
from most other mktemp implementations.
* Changed CPU core count detection to use cpuset_getaffinity() on
FreeBSD.
5.2.0 (2014-12-21)
Since 5.1.4beta:
* All fixes from 5.0.8
* liblzma: Fixed lzma_stream_encoder_mt_memusage() when a preset
was used.
* xzdiff: If mktemp isn't installed, mkdir will be used as
a fallback to create a temporary directory. Installing mktemp
is still recommended.
* Updated French, German, Italian, Polish, and Vietnamese
translations.
Summary of fixes and new features added in the 5.1.x development
releases:
* liblzma:
- Added support for multi-threaded compression. See the
lzma_mt structure, lzma_stream_encoder_mt(), and
lzma_stream_encoder_mt_memusage() in <lzma/container.h>,
lzma_get_progress() in <lzma/base.h>, and lzma_cputhreads()
in <lzma/hardware.h> for details.
- Made the uses of lzma_allocator const correct.
- Added lzma_block_uncomp_encode() to create uncompressed
.xz Blocks using LZMA2 uncompressed chunks.
- Added support for LZMA_IGNORE_CHECK.
- A few speed optimizations were made.
- Added support for symbol versioning. It is enabled by default
on GNU/Linux, other GNU-based systems, and FreeBSD.
- liblzma (not the whole XZ Utils) should now be buildable
with MSVC 2013 update 2 or later using windows/config.h.
* xz:
- Fixed a race condition in the signal handling. It was
possible that e.g. the first SIGINT didn't make xz exit
if reading or writing blocked and one had bad luck. The fix
is non-trivial, so as of writing it is unknown if it will be
backported to the v5.0 branch.
- Multi-threaded compression can be enabled with the
--threads (-T) option.
[Fixed: This originally said "decompression".]
- New command line options in xz: --single-stream,
--block-size=SIZE, --block-list=SIZES,
--flush-timeout=TIMEOUT, and --ignore-check.
- xz -lvv now shows the minimum xz version that is required to
decompress the file. Currently it is 5.0.0 for all supported
.xz files except files with empty LZMA2 streams require 5.0.2.
* xzdiff and xzgrep now support .lzo files if lzop is installed.
The .tzo suffix is also recognized as a shorthand for .tar.lzo.
5.1.4beta (2014-09-14)
* All fixes from 5.0.6
@@ -164,6 +339,29 @@ XZ Utils Release Notes
experimental and may change before it gets into a stable release.
5.0.8 (2014-12-21)
* Fixed an old bug in xzgrep that affected OpenBSD and probably
a few other operating systems too.
* Updated French and German translations.
* Added support for detecting the amount of RAM on AmigaOS/AROS.
* Minor build system updates.
5.0.7 (2014-09-20)
* Fix regressions introduced in 5.0.6:
- Fix building with non-GNU make.
- Fix invalid Libs.private value in liblzma.pc which broke
static linking against liblzma if the linker flags were
taken from pkg-config.
5.0.6 (2014-09-14)
* xzgrep now exits with status 0 if at least one file matched.

2
README
View File

@@ -291,7 +291,7 @@ XZ Utils
XZ Embedded is a limited implementation written for use in the Linux
kernel, but it is also suitable for other embedded use.
http://tukaani.org/xz/embedded.html
https://tukaani.org/xz/embedded.html
6. Contact information

18
THANKS
View File

@@ -11,7 +11,9 @@ has been important. :-) In alphabetical order:
- Karl Berry
- Anders F. Björklund
- Emmanuel Blot
- Melanie Blower
- Martin Blumenstingl
- Ben Boeckel
- Jakub Bogusz
- Maarten Bosmans
- Trent W. Buck
@@ -21,6 +23,7 @@ has been important. :-) In alphabetical order:
- Milo Casagrande
- Marek Černocký
- Tomer Chachamu
- Gabi Davar
- Chris Donawa
- Andrew Dudman
- Markus Duft
@@ -29,7 +32,9 @@ has been important. :-) In alphabetical order:
- Gilles Espinasse
- Denis Excoffier
- Michael Felt
- Michael Fox
- Mike Frysinger
- Daniel Richard G.
- Bill Glessner
- Jason Gorski
- Juan Manuel Guerrero
@@ -53,6 +58,7 @@ has been important. :-) In alphabetical order:
- Andraž 'ruskie' Levstik
- Cary Lewis
- Wim Lewis
- Eric Lindblad
- Lorenzo De Liso
- Bela Lubkin
- Gregory Margo
@@ -61,38 +67,50 @@ has been important. :-) In alphabetical order:
- Conley Moorhous
- Rafał Mużyło
- Adrien Nader
- Evan Nemerson
- Hongbo Ni
- Jonathan Nieder
- Andre Noll
- Peter O'Gorman
- Peter Pallinger
- Rui Paulo
- Igor Pavlov
- Diego Elio Pettenò
- Elbert Pol
- Mikko Pouru
- Rich Prohaska
- Trần Ngọc Quân
- Pavel Raiskup
- Ole André Vadla Ravnås
- Robert Readman
- Bernhard Reutner-Fischer
- Eric S. Raymond
- Cristian Rodríguez
- Christian von Roques
- Torsten Rupp
- Jukka Salmi
- Alexandre Sauvé
- Benno Schulenberg
- Andreas Schwab
- Dan Shechter
- Stuart Shelton
- Sebastian Andrzej Siewior
- Brad Smith
- Pippijn van Steenhoven
- Jonathan Stott
- Dan Stromberg
- Vincent Torri
- Paul Townsend
- Mohammed Adnène Trojette
- Alexey Tourbin
- Loganaden Velvindron
- Patrick J. Volkerding
- Martin Väth
- Adam Walling
- Christian Weisgerber
- Bert Wesarg
- Fredrik Wikstrom
- Jim Wilcoxson
- Ralf Wildenhues
- Charles Wilson
- Lars Wirzenius

View File

@@ -21,4 +21,4 @@ sed -n 's/LZMA_VERSION_STABILITY_ALPHA/alpha/
src/liblzma/api/lzma/version.h \
| tr '\n' '|' \
| sed 's/|/./; s/|/./; s/|//g' \
| tr -d '\n'
| tr -d '\r\n'

View File

@@ -18,7 +18,7 @@
AC_PREREQ([2.64])
AC_INIT([XZ Utils], m4_esyscmd([/bin/sh build-aux/version.sh]),
[lasse.collin@tukaani.org], [xz], [http://tukaani.org/xz/])
[lasse.collin@tukaani.org], [xz], [https://tukaani.org/xz/])
AC_CONFIG_SRCDIR([src/liblzma/common/common.h])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
@@ -34,8 +34,8 @@ AC_CANONICAL_HOST
# We do some special things on Windows (32-bit or 64-bit) builds.
case $host_os in
mingw* | cygwin*) is_w32=yes ;;
*) is_w32=no ;;
mingw* | cygwin | msys) is_w32=yes ;;
*) is_w32=no ;;
esac
AM_CONDITIONAL([COND_W32], [test "$is_w32" = yes])
@@ -43,9 +43,15 @@ AM_CONDITIONAL([COND_W32], [test "$is_w32" = yes])
# executables. Cygwin is an exception to this, since it is recommended
# that symlinks don't have the .exe suffix. To make this work, we
# define LN_EXEEXT.
#
# MSYS2 is treated the same way as Cygwin. It uses plain "msys" like
# the original MSYS when building MSYS/MSYS2-binaries. Hopefully this
# doesn't break things for the original MSYS developers. Note that this
# doesn't affect normal MSYS/MSYS2 users building non-MSYS/MSYS2 binaries
# since in that case the $host_os is usually mingw32.
case $host_os in
cygwin) LN_EXEEXT= ;;
*) LN_EXEEXT='$(EXEEXT)' ;;
cygwin | msys) LN_EXEEXT= ;;
*) LN_EXEEXT='$(EXEEXT)' ;;
esac
AC_SUBST([LN_EXEEXT])
@@ -59,7 +65,7 @@ AM_CFLAGS=
#############
AC_MSG_CHECKING([if debugging code should be compiled])
AC_ARG_ENABLE([debug], AC_HELP_STRING([--enable-debug], [Enable debugging code.]),
AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [Enable debugging code.]),
[], enable_debug=no)
if test "x$enable_debug" = xyes; then
AC_MSG_RESULT([yes])
@@ -84,13 +90,14 @@ enable_decoder_[]NAME=no
])dnl
AC_MSG_CHECKING([which encoders to build])
AC_ARG_ENABLE([encoders], AC_HELP_STRING([--enable-encoders=LIST],
AC_ARG_ENABLE([encoders], AS_HELP_STRING([--enable-encoders=LIST],
[Comma-separated list of encoders to build. Default=all.
Available encoders:]
m4_translit(m4_defn([SUPPORTED_FILTERS]), [,], [ ])),
[], [enable_encoders=SUPPORTED_FILTERS])
enable_encoders=`echo "$enable_encoders" | sed 's/,/ /g'`
if test "x$enable_encoders" = xno || test "x$enable_encoders" = x; then
enable_encoders=no
AC_MSG_RESULT([(none)])
else
for arg in $enable_encoders
@@ -108,16 +115,19 @@ else
;;
esac
done
AC_DEFINE([HAVE_ENCODERS], [1],
[Define to 1 if any of HAVE_ENCODER_foo have been defined.])
AC_MSG_RESULT([$enable_encoders])
fi
AC_MSG_CHECKING([which decoders to build])
AC_ARG_ENABLE([decoders], AC_HELP_STRING([--enable-decoders=LIST],
AC_ARG_ENABLE([decoders], AS_HELP_STRING([--enable-decoders=LIST],
[Comma-separated list of decoders to build. Default=all.
Available decoders are the same as available encoders.]),
[], [enable_decoders=SUPPORTED_FILTERS])
enable_decoders=`echo "$enable_decoders" | sed 's/,/ /g'`
if test "x$enable_decoders" = xno || test "x$enable_decoders" = x; then
enable_decoders=no
AC_MSG_RESULT([(none)])
else
for arg in $enable_decoders
@@ -135,11 +145,8 @@ else
;;
esac
done
# LZMA2 requires that LZMA1 is enabled.
test "x$enable_encoder_lzma2" = xyes && enable_encoder_lzma1=yes
test "x$enable_decoder_lzma2" = xyes && enable_decoder_lzma1=yes
AC_DEFINE([HAVE_DECODERS], [1],
[Define to 1 if any of HAVE_DECODER_foo have been defined.])
AC_MSG_RESULT([$enable_decoders])
fi
@@ -148,8 +155,8 @@ if test "x$enable_encoder_lzma2$enable_encoder_lzma1" = xyesno \
AC_MSG_ERROR([LZMA2 requires that LZMA1 is also enabled.])
fi
AM_CONDITIONAL(COND_MAIN_ENCODER, test "x$enable_encoders" != xno && test "x$enable_encoders" != x)
AM_CONDITIONAL(COND_MAIN_DECODER, test "x$enable_decoders" != xno && test "x$enable_decoders" != x)
AM_CONDITIONAL(COND_MAIN_ENCODER, test "x$enable_encoders" != xno)
AM_CONDITIONAL(COND_MAIN_DECODER, test "x$enable_decoders" != xno)
m4_foreach([NAME], [SUPPORTED_FILTERS],
[AM_CONDITIONAL(COND_FILTER_[]m4_toupper(NAME), test "x$enable_filter_[]NAME" = xyes)
@@ -195,7 +202,7 @@ m4_foreach([NAME], [SUPPORTED_MATCH_FINDERS],
])
AC_MSG_CHECKING([which match finders to build])
AC_ARG_ENABLE([match-finders], AC_HELP_STRING([--enable-match-finders=LIST],
AC_ARG_ENABLE([match-finders], AS_HELP_STRING([--enable-match-finders=LIST],
[Comma-separated list of match finders to build. Default=all.
At least one match finder is required for encoding with
the LZMA1 and LZMA2 filters. Available match finders:]
@@ -234,7 +241,7 @@ m4_foreach([NAME], [SUPPORTED_CHECKS],
])dnl
AC_MSG_CHECKING([which integrity checks to build])
AC_ARG_ENABLE([checks], AC_HELP_STRING([--enable-checks=LIST],
AC_ARG_ENABLE([checks], AS_HELP_STRING([--enable-checks=LIST],
[Comma-separated list of integrity checks to build.
Default=all. Available integrity checks:]
m4_translit(m4_defn([SUPPORTED_CHECKS]), [,], [ ])),
@@ -268,13 +275,27 @@ m4_foreach([NAME], [SUPPORTED_CHECKS],
[AM_CONDITIONAL(COND_CHECK_[]m4_toupper(NAME), test "x$enable_check_[]NAME" = xyes)
])dnl
AC_MSG_CHECKING([if external SHA-256 should be used])
AC_ARG_ENABLE([external-sha256], AS_HELP_STRING([--enable-external-sha256],
[Use SHA-256 code from the operating system.
See INSTALL for possible subtle problems.]),
[], [enable_external_sha256=no])
if test "x$enable_check_sha256" != "xyes"; then
enable_external_sha256=no
fi
if test "x$enable_external_sha256" = xyes; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
###########################
# Assembler optimizations #
###########################
AC_MSG_CHECKING([if assembler optimizations should be used])
AC_ARG_ENABLE([assembler], AC_HELP_STRING([--disable-assembler],
AC_ARG_ENABLE([assembler], AS_HELP_STRING([--disable-assembler],
[Do not use assembler optimizations even if such exist
for the architecture.]),
[], [enable_assembler=yes])
@@ -283,7 +304,7 @@ if test "x$enable_assembler" = xyes; then
case $host_os in
# Darwin should work too but only if not creating universal
# binaries. Solaris x86 could work too but I cannot test.
linux* | *bsd* | mingw* | cygwin* | *djgpp*)
linux* | *bsd* | mingw* | cygwin | msys | *djgpp*)
case $host_cpu in
i?86) enable_assembler=x86 ;;
x86_64) enable_assembler=x86_64 ;;
@@ -297,7 +318,7 @@ case $enable_assembler in
;;
*)
AC_MSG_RESULT([])
AC_MSG_ERROR([--enable-assembler accepts only \`yes', \`no', \`x86', or \`x86_64'.])
AC_MSG_ERROR([--enable-assembler accepts only `yes', `no', `x86', or `x86_64'.])
;;
esac
AM_CONDITIONAL(COND_ASM_X86, test "x$enable_assembler" = xx86)
@@ -309,7 +330,7 @@ AM_CONDITIONAL(COND_ASM_X86_64, test "x$enable_assembler" = xx86_64)
#####################
AC_MSG_CHECKING([if small size is preferred over speed])
AC_ARG_ENABLE([small], AC_HELP_STRING([--enable-small],
AC_ARG_ENABLE([small], AS_HELP_STRING([--enable-small],
[Make liblzma smaller and a little slower.
This is disabled by default to optimize for speed.]),
[], [enable_small=no])
@@ -317,7 +338,7 @@ if test "x$enable_small" = xyes; then
AC_DEFINE([HAVE_SMALL], [1], [Define to 1 if optimizing for size.])
elif test "x$enable_small" != xno; then
AC_MSG_RESULT([])
AC_MSG_ERROR([--enable-small accepts only \`yes' or \`no'])
AC_MSG_ERROR([--enable-small accepts only `yes' or `no'])
fi
AC_MSG_RESULT([$enable_small])
AM_CONDITIONAL(COND_SMALL, test "x$enable_small" = xyes)
@@ -328,7 +349,7 @@ AM_CONDITIONAL(COND_SMALL, test "x$enable_small" = xyes)
#############
AC_MSG_CHECKING([if threading support is wanted])
AC_ARG_ENABLE([threads], AC_HELP_STRING([--enable-threads=METHOD],
AC_ARG_ENABLE([threads], AS_HELP_STRING([--enable-threads=METHOD],
[Supported METHODS are `yes', `no', `posix', `win95', and
`vista'. The default is `yes'. Using `no' together with
--enable-small makes liblzma thread unsafe.]),
@@ -357,8 +378,7 @@ case $enable_threads in
;;
*)
AC_MSG_RESULT([])
AC_MSG_ERROR([--enable-threads only accepts
\`yes', \`no', \`posix', \`win95', or \`vista'])
AC_MSG_ERROR([--enable-threads only accepts `yes', `no', `posix', `win95', or `vista'])
;;
esac
@@ -382,7 +402,7 @@ fi
# but most systems, on which we don't have any way to determine the amount
# of RAM, will probably have at least 128 MiB of RAM.
AC_MSG_CHECKING([how much RAM to assume if the real amount is unknown])
AC_ARG_ENABLE([assume-ram], AC_HELP_STRING([--enable-assume-ram=SIZE],
AC_ARG_ENABLE([assume-ram], AS_HELP_STRING([--enable-assume-ram=SIZE],
[If and only if the real amount of RAM cannot be determined,
assume SIZE MiB. The default is 128 MiB. This affects the
default memory usage limit.]),
@@ -402,40 +422,43 @@ AC_DEFINE_UNQUOTED([ASSUME_RAM], [$enable_assume_ram],
# Components to install #
#########################
AC_ARG_ENABLE([xz], [AC_HELP_STRING([--disable-xz],
AC_ARG_ENABLE([xz], [AS_HELP_STRING([--disable-xz],
[do not build the xz tool])],
[], [enable_xz=yes])
AM_CONDITIONAL([COND_XZ], [test x$enable_xz != xno])
AC_ARG_ENABLE([xzdec], [AC_HELP_STRING([--disable-xzdec],
AC_ARG_ENABLE([xzdec], [AS_HELP_STRING([--disable-xzdec],
[do not build xzdec])],
[], [enable_xzdec=yes])
test "x$enable_decoders" = xno && enable_xzdec=no
AM_CONDITIONAL([COND_XZDEC], [test x$enable_xzdec != xno])
AC_ARG_ENABLE([lzmadec], [AC_HELP_STRING([--disable-lzmadec],
AC_ARG_ENABLE([lzmadec], [AS_HELP_STRING([--disable-lzmadec],
[do not build lzmadec
(it exists primarily for LZMA Utils compatibility)])],
[], [enable_lzmadec=yes])
test "x$enable_decoder_lzma1" = xno && enable_lzmadec=no
AM_CONDITIONAL([COND_LZMADEC], [test x$enable_lzmadec != xno])
AC_ARG_ENABLE([lzmainfo], [AC_HELP_STRING([--disable-lzmainfo],
AC_ARG_ENABLE([lzmainfo], [AS_HELP_STRING([--disable-lzmainfo],
[do not build lzmainfo
(it exists primarily for LZMA Utils compatibility)])],
[], [enable_lzmainfo=yes])
test "x$enable_decoder_lzma1" = xno && enable_lzmainfo=no
AM_CONDITIONAL([COND_LZMAINFO], [test x$enable_lzmainfo != xno])
AC_ARG_ENABLE([lzma-links], [AC_HELP_STRING([--disable-lzma-links],
AC_ARG_ENABLE([lzma-links], [AS_HELP_STRING([--disable-lzma-links],
[do not create symlinks for LZMA Utils compatibility])],
[], [enable_lzma_links=yes])
AM_CONDITIONAL([COND_LZMALINKS], [test x$enable_lzma_links != xno])
AC_ARG_ENABLE([scripts], [AC_HELP_STRING([--disable-scripts],
AC_ARG_ENABLE([scripts], [AS_HELP_STRING([--disable-scripts],
[do not install the scripts xzdiff, xzgrep, xzless, xzmore,
and their symlinks])],
[], [enable_scripts=yes])
AM_CONDITIONAL([COND_SCRIPTS], [test x$enable_scripts != xno])
AC_ARG_ENABLE([doc], [AC_HELP_STRING([--disable-doc],
AC_ARG_ENABLE([doc], [AS_HELP_STRING([--disable-doc],
[do not install documentation files to docdir
(man pages will still be installed)])],
[], [enable_doc=yes])
@@ -447,7 +470,7 @@ AM_CONDITIONAL([COND_DOC], [test x$enable_doc != xno])
#####################
AC_MSG_CHECKING([if library symbol versioning should be used])
AC_ARG_ENABLE([symbol-versions], [AC_HELP_STRING([--enable-symbol-versions],
AC_ARG_ENABLE([symbol-versions], [AS_HELP_STRING([--enable-symbol-versions],
[Use symbol versioning for liblzma. Enabled by default on
GNU/Linux, other GNU-based systems, and FreeBSD.])],
[], [enable_symbol_versions=auto])
@@ -469,20 +492,49 @@ AC_MSG_RESULT([$enable_symbol_versions])
AM_CONDITIONAL([COND_SYMVERS], [test "x$enable_symbol_versions" = xyes])
##############
# Sandboxing #
##############
AC_MSG_CHECKING([if sandboxing should be used])
AC_ARG_ENABLE([sandbox], [AS_HELP_STRING([--enable-sandbox=METHOD],
[Sandboxing METHOD can be `auto', `no', or `capsicum'.
The default is `auto' which enables sandboxing if
a supported sandboxing method is found.])],
[], [enable_sandbox=auto])
case $enable_sandbox in
auto)
AC_MSG_RESULT([maybe (autodetect)])
;;
no | capsicum)
AC_MSG_RESULT([$enable_sandbox])
;;
*)
AC_MSG_RESULT([])
AC_MSG_ERROR([--enable-sandbox only accepts `auto', `no', or `capsicum'.])
;;
esac
###############################################################################
# Checks for programs.
###############################################################################
echo
gl_POSIX_SHELL
if test -z "$POSIX_SHELL" ; then
if test -z "$POSIX_SHELL" && test "x$enable_scripts" = xyes ; then
AC_MSG_ERROR([No POSIX conforming shell (sh) was found.])
fi
echo
echo "Initializing Automake:"
AM_INIT_AUTOMAKE([1.12 foreign tar-v7 filename-length-max=99 serial-tests])
# We don't use "subdir-objects" yet because it breaks "make distclean" when
# dependencies are enabled (as of Automake 1.14.1) due to this bug:
# http://debbugs.gnu.org/cgi/bugreport.cgi?bug=17354
# The -Wno-unsupported is used to silence warnings about missing
# "subdir-objects".
AM_INIT_AUTOMAKE([1.12 foreign tar-v7 filename-length-max=99 serial-tests -Wno-unsupported])
AC_PROG_LN_S
AC_PROG_CC_C99
@@ -557,7 +609,7 @@ AM_CONDITIONAL([COND_SHARED], [test "x$enable_shared" != xno])
echo
echo "Initializing gettext:"
AM_GNU_GETTEXT_VERSION([0.18])
AM_GNU_GETTEXT_VERSION([0.19])
AM_GNU_GETTEXT([external])
@@ -620,7 +672,7 @@ AC_C_BIGENDIAN
gl_GETOPT
# Find the best function to set timestamps.
AC_CHECK_FUNCS([futimens futimes futimesat utimes utime], [break])
AC_CHECK_FUNCS([futimens futimes futimesat utimes _futime utime], [break])
# This is nice to have but not mandatory.
AC_CHECK_FUNCS([posix_fadvise])
@@ -631,34 +683,34 @@ TUKLIB_PHYSMEM
TUKLIB_CPUCORES
TUKLIB_MBSTR
# Check for system-provided SHA-256. At least the following is supported:
# If requsted, check for system-provided SHA-256. At least the following
# implementations are supported:
#
# OS Headers Library Type Function
# FreeBSD sys/types.h + sha256.h libmd SHA256_CTX SHA256_Init
# NetBSD sys/types.h + sha2.h SHA256_CTX SHA256_Init
# OpenBSD sys/types.h + sha2.h SHA2_CTX SHA256Init
# Solaris sys/types.h + sha2.h libmd SHA256_CTX SHA256Init
# MINIX 3 sys/types.h + minix/sha2.h libutil SHA256_CTX SHA256_Init
# MINIX 3 sys/types.h + sha2.h SHA256_CTX SHA256_Init
# Darwin CommonCrypto/CommonDigest.h CC_SHA256_CTX CC_SHA256_Init
#
# Note that Darwin's CC_SHA256_Update takes buffer size as uint32_t instead
# of size_t.
#
# We don't check for e.g. OpenSSL or libgcrypt because we don't want
# to introduce dependencies to other packages by default. Maybe such
# libraries could be supported via additional configure options though.
#
if test "x$enable_check_sha256" = "xyes"; then
sha256_header_found=no
sha256_type_found=no
sha256_func_found=no
if test "x$enable_external_sha256" = "xyes"; then
# Test for Common Crypto before others, because Darwin has sha256.h
# too and we don't want to use that, because on older versions it
# uses OpenSSL functions, whose SHA256_Init is not guaranteed to
# succeed.
sha256_header_found=no
AC_CHECK_HEADERS(
[CommonCrypto/CommonDigest.h sha256.h sha2.h minix/sha2.h],
[CommonCrypto/CommonDigest.h sha256.h sha2.h],
[sha256_header_found=yes ; break])
if test "x$sha256_header_found" = xyes; then
AC_CHECK_TYPES([CC_SHA256_CTX, SHA256_CTX, SHA2_CTX], [], [],
AC_CHECK_TYPES([CC_SHA256_CTX, SHA256_CTX, SHA2_CTX],
[sha256_type_found=yes], [],
[[#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
@@ -670,20 +722,19 @@ if test "x$enable_check_sha256" = "xyes"; then
#endif
#ifdef HAVE_SHA2_H
# include <sha2.h>
#endif
#ifdef HAVE_MINIX_SHA2_H
# include <minix/sha2.h>
#endif]])
AC_SEARCH_LIBS([SHA256_Init], [md util])
AC_SEARCH_LIBS([SHA256Init], [md])
AC_CHECK_FUNCS([CC_SHA256_Init SHA256_Init SHA256Init],
[break])
if test "x$sha256_type_found" = xyes ; then
AC_SEARCH_LIBS([SHA256Init], [md])
AC_SEARCH_LIBS([SHA256_Init], [md])
AC_CHECK_FUNCS([CC_SHA256_Init SHA256Init SHA256_Init],
[sha256_func_found=yes ; break])
fi
fi
fi
AM_CONDITIONAL([COND_INTERNAL_SHA256],
[test "x$ac_cv_func_SHA256_Init" != xyes \
&& test "x$ac_cv_func_SHA256Init" != xyes \
&& test "x$ac_cv_func_CC_SHA256_Init" != xyes])
AM_CONDITIONAL([COND_INTERNAL_SHA256], [test "x$sha256_func_found" = xno])
if test "x$enable_external_sha256$sha256_func_found" = xyesno; then
AC_MSG_ERROR([--enable-external-sha256 was specified but no supported external SHA-256 implementation was found])
fi
# Check for SSE2 intrinsics.
AC_CHECK_DECL([_mm_movemask_epi8],
@@ -694,6 +745,23 @@ AC_CHECK_DECL([_mm_movemask_epi8],
#include <immintrin.h>
#endif])
# Check for sandbox support. If one is found, set enable_sandbox=found.
case $enable_sandbox in
auto | capsicum)
AX_CHECK_CAPSICUM([enable_sandbox=found], [:])
;;
esac
# If a specific sandboxing method was explicitly requested and it wasn't
# found, give an error.
case $enable_sandbox in
auto | no | found)
;;
*)
AC_MSG_ERROR([$enable_sandbox support not found])
;;
esac
###############################################################################
# If using GCC, set some additional AM_CFLAGS:
@@ -749,8 +817,9 @@ if test "$GCC" = yes ; then
do
AC_MSG_CHECKING([if $CC accepts $NEW_FLAG])
OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $NEW_FLAG"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([void foo(void) { }])], [
CFLAGS="$CFLAGS $NEW_FLAG -Werror"
AC_COMPILE_IFELSE([AC_LANG_SOURCE(
[void foo(void); void foo(void) { }])], [
AM_CFLAGS="$AM_CFLAGS $NEW_FLAG"
AC_MSG_RESULT([yes])
], [
@@ -760,7 +829,7 @@ if test "$GCC" = yes ; then
done
AC_ARG_ENABLE([werror],
AC_HELP_STRING([--enable-werror], [Enable -Werror to abort
AS_HELP_STRING([--enable-werror], [Enable -Werror to abort
compilation on all compiler warnings.]),
[], [enable_werror=no])
if test "x$enable_werror" = "xyes"; then

View File

@@ -14,6 +14,8 @@
#include "lzma.h"
#include <stdio.h>
#define CHUNK 64
static lzma_stream strm = LZMA_STREAM_INIT;
static FILE *file_in;
@@ -22,7 +24,6 @@ static FILE *file_in;
static void
encode(size_t size, lzma_action action)
{
static const size_t CHUNK = 64;
uint8_t in[CHUNK];
uint8_t out[CHUNK];
lzma_ret ret;

View File

@@ -14,6 +14,8 @@
#include "lzma.h"
#include <stdio.h>
#define CHUNK 64
static lzma_stream strm = LZMA_STREAM_INIT;
static FILE *file_in;
@@ -22,7 +24,6 @@ static FILE *file_in;
static void
encode(size_t size, lzma_action action)
{
static const size_t CHUNK = 64;
uint8_t in[CHUNK];
uint8_t out[CHUNK];
lzma_ret ret;

View File

@@ -25,3 +25,7 @@ List of examples
a custom filter chain
(x86 BCJ + LZMA2)
04_compress_easy_mt.c Multi-threaded multi-call
compression using a compression
preset

View File

@@ -138,7 +138,7 @@ decompress(lzma_stream *strm, const char *inname, FILE *infile, FILE *outfile)
// Once the end of the input file has been reached,
// we need to tell lzma_code() that no more input
// will be coming. As said before, this isn't required
// if the LZMA_CONATENATED flag isn't used when
// if the LZMA_CONCATENATED flag isn't used when
// initializing the decoder.
if (feof(infile))
action = LZMA_FINISH;

View File

@@ -31,10 +31,6 @@ init_encoder(lzma_stream *strm)
// No flags are needed.
.flags = 0,
// Set the number of threads to use.
// FIXME: Add how to autodetect a reasonable number.
.threads = 4,
// Let liblzma determine a sane block size.
.block_size = 0,
@@ -57,6 +53,32 @@ init_encoder(lzma_stream *strm)
.check = LZMA_CHECK_CRC64,
};
// Detect how many threads the CPU supports.
mt.threads = lzma_cputhreads();
// If the number of CPU cores/threads cannot be detected,
// use one thread. Note that this isn't the same as the normal
// single-threaded mode as this will still split the data into
// blocks and use more RAM than the normal single-threaded mode.
// You may want to consider using lzma_easy_encoder() or
// lzma_stream_encoder() instead of lzma_stream_encoder_mt() if
// lzma_cputhreads() returns 0 or 1.
if (mt.threads == 0)
mt.threads = 1;
// If the number of CPU cores/threads exceeds threads_max,
// limit the number of threads to keep memory usage lower.
// The number 8 is arbitrarily chosen and may be too low or
// high depending on the compression preset and the computer
// being used.
//
// FIXME: A better way could be to check the amount of RAM
// (or available RAM) and use lzma_stream_encoder_mt_memusage()
// to determine if the number of threads should be reduced.
const uint32_t threads_max = 8;
if (mt.threads > threads_max)
mt.threads = threads_max;
// Initialize the threaded encoder.
lzma_ret ret = lzma_stream_encoder_mt(strm, &mt);

206
doc/examples/11_file_info.c Normal file
View File

@@ -0,0 +1,206 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file 11_file_info.c
/// \brief Get uncmopressed size of .xz file(s)
///
/// Usage: ./11_file_info INFILE1.xz [INFILEn.xz]...
///
/// Example: ./11_file_info foo.xz
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include <stdbool.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <lzma.h>
static bool
print_file_size(lzma_stream *strm, FILE *infile, const char *filename)
{
// Get the file size. In standard C it can be done by seeking to
// the end of the file and then getting the file position.
// In POSIX one can use fstat() and then st_size from struct stat.
// Also note that fseek() and ftell() use long and thus don't support
// large files on 32-bit systems (POSIX versions fseeko() and
// ftello() can support large files).
if (fseek(infile, 0, SEEK_END)) {
fprintf(stderr, "Error seeking the file `%s': %s\n",
filename, strerror(errno));
return false;
}
const long file_size = ftell(infile);
// The decoder wants to start from the beginning of the .xz file.
rewind(infile);
// Initialize the decoder.
lzma_index *i;
lzma_ret ret = lzma_file_info_decoder(strm, &i, UINT64_MAX,
(uint64_t)file_size);
switch (ret) {
case LZMA_OK:
// Initialization succeeded.
break;
case LZMA_MEM_ERROR:
fprintf(stderr, "Out of memory when initializing "
"the .xz file info decoder\n");
return false;
case LZMA_PROG_ERROR:
default:
fprintf(stderr, "Unknown error, possibly a bug\n");
return false;
}
// This example program reuses the same lzma_stream structure
// for multiple files, so we need to reset this when starting
// a new file.
strm->avail_in = 0;
// Buffer for input data.
uint8_t inbuf[BUFSIZ];
// Pass data to the decoder and seek when needed.
while (true) {
if (strm->avail_in == 0) {
strm->next_in = inbuf;
strm->avail_in = fread(inbuf, 1, sizeof(inbuf),
infile);
if (ferror(infile)) {
fprintf(stderr,
"Error reading from `%s': %s\n",
filename, strerror(errno));
return false;
}
// We don't need to care about hitting the end of
// the file so no need to check for feof().
}
ret = lzma_code(strm, LZMA_RUN);
switch (ret) {
case LZMA_OK:
break;
case LZMA_SEEK_NEEDED:
// The cast is safe because liblzma won't ask us to
// seek past the known size of the input file which
// did fit into a long.
//
// NOTE: Remember to change these to off_t if you
// switch fseeko() or lseek().
if (fseek(infile, (long)(strm->seek_pos), SEEK_SET)) {
fprintf(stderr, "Error seeking the "
"file `%s': %s\n",
filename, strerror(errno));
return false;
}
// The old data in the inbuf is useless now. Set
// avail_in to zero so that we will read new input
// from the new file position on the next iteration
// of this loop.
strm->avail_in = 0;
break;
case LZMA_STREAM_END:
// File information was successfully decoded.
// See <lzma/index.h> for functions that can be
// used on it. In this example we just print
// the uncompressed size (in bytes) of
// the .xz file followed by its file name.
printf("%10" PRIu64 " %s\n",
lzma_index_uncompressed_size(i),
filename);
// Free the memory of the lzma_index structure.
lzma_index_end(i, NULL);
return true;
case LZMA_FORMAT_ERROR:
// .xz magic bytes weren't found.
fprintf(stderr, "The file `%s' is not "
"in the .xz format\n", filename);
return false;
case LZMA_OPTIONS_ERROR:
fprintf(stderr, "The file `%s' has .xz headers that "
"are not supported by this liblzma "
"version\n", filename);
return false;
case LZMA_DATA_ERROR:
fprintf(stderr, "The file `%s' is corrupt\n",
filename);
return false;
case LZMA_MEM_ERROR:
fprintf(stderr, "Memory allocation failed when "
"decoding the file `%s'\n", filename);
return false;
// LZMA_MEMLIMIT_ERROR shouldn't happen because we used
// UINT64_MAX as the limit.
//
// LZMA_BUF_ERROR shouldn't happen because we always provide
// new input when the input buffer is empty. The decoder
// knows the input file size and thus won't try to read past
// the end of the file.
case LZMA_MEMLIMIT_ERROR:
case LZMA_BUF_ERROR:
case LZMA_PROG_ERROR:
default:
fprintf(stderr, "Unknown error, possibly a bug\n");
return false;
}
}
// This line is never reached.
}
extern int
main(int argc, char **argv)
{
bool success = true;
lzma_stream strm = LZMA_STREAM_INIT;
for (int i = 1; i < argc; ++i) {
FILE *infile = fopen(argv[i], "rb");
if (infile == NULL) {
fprintf(stderr, "Cannot open the file `%s': %s\n",
argv[i], strerror(errno));
success = false;
}
success &= print_file_size(&strm, infile, argv[i]);
(void)fclose(infile);
}
lzma_end(&strm);
// Close stdout to catch possible write errors that can occur
// when pending data is flushed from the stdio buffers.
if (fclose(stdout)) {
fprintf(stderr, "Write error: %s\n", strerror(errno));
success = false;
}
return success ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -13,7 +13,8 @@ PROGS = \
01_compress_easy \
02_decompress \
03_compress_custom \
04_compress_easy_mt
04_compress_easy_mt \
11_file_info
all: $(PROGS)

View File

@@ -206,7 +206,7 @@ Q: How do I build a program that needs liblzmadec (lzmadec.h)?
A: liblzmadec is part of LZMA Utils. XZ Utils has liblzma, but no
liblzmadec. The code using liblzmadec should be ported to use
liblzma instead. If you cannot or don't want to do that, download
LZMA Utils from <http://tukaani.org/lzma/>.
LZMA Utils from <https://tukaani.org/lzma/>.
Q: The default build of liblzma is too big. How can I make it smaller?
@@ -220,5 +220,5 @@ A: Give --enable-small to the configure script. Use also appropriate
If the result is still too big, take a look at XZ Embedded. It is
a separate project, which provides a limited but significantly
smaller XZ decoder implementation than XZ Utils. You can find it
at <http://tukaani.org/xz/embedded.html>.
at <https://tukaani.org/xz/embedded.html>.

View File

@@ -64,6 +64,7 @@ SRCS_C = \
../src/liblzma/common/block_header_encoder.c \
../src/liblzma/common/block_util.c \
../src/liblzma/common/common.c \
../src/liblzma/common/file_info.c \
../src/liblzma/common/filter_common.c \
../src/liblzma/common/filter_decoder.c \
../src/liblzma/common/filter_encoder.c \
@@ -113,6 +114,7 @@ SRCS_C = \
../src/xz/list.c \
../src/xz/main.c \
../src/xz/message.c \
../src/xz/mytime.c \
../src/xz/options.c \
../src/xz/signals.c \
../src/xz/suffix.c \

View File

@@ -10,6 +10,9 @@
/* Define to 1 if sha256 integrity check is enabled. */
#define HAVE_CHECK_SHA256 1
/* Define to 1 if any of HAVE_DECODER_foo have been defined. */
#define HAVE_DECODERS 1
/* Define to 1 if arm decoder is enabled. */
#define HAVE_DECODER_ARM 1
@@ -37,6 +40,9 @@
/* Define to 1 if x86 decoder is enabled. */
#define HAVE_DECODER_X86 1
/* Define to 1 if any of HAVE_ENCODER_foo have been defined. */
#define HAVE_ENCODERS 1
/* Define to 1 if arm encoder is enabled. */
#define HAVE_ENCODER_ARM 1
@@ -120,7 +126,7 @@
#define PACKAGE_NAME "XZ Utils"
/* Define to the home page for this package. */
#define PACKAGE_URL "http://tukaani.org/xz/"
#define PACKAGE_URL "https://tukaani.org/xz/"
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4

View File

@@ -37,6 +37,10 @@
/* 5 8 Uncompressed size (little endian). -1 means unknown size */
/* 13 Compressed data */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUFSIZE 4096
int find_lzma_header(unsigned char *buf) {
@@ -48,7 +52,7 @@ int find_lzma_header(unsigned char *buf) {
}
int main(int argc, char *argv[]) {
char buf[BUFSIZE];
unsigned char buf[BUFSIZE];
int ret, i, numlzma, blocks=0;
if (argc != 2) {

3
m4/.gitignore vendored
View File

@@ -1,4 +1,5 @@
codeset.m4
fcntl-o.m4
gettext.m4
glibc2.m4
glibc21.m4
@@ -6,6 +7,7 @@ iconv.m4
intdiv0.m4
intl.m4
intldir.m4
intlmacosx.m4
intmax.m4
inttypes-pri.m4
inttypes_h.m4
@@ -27,6 +29,7 @@ printf-posix.m4
progtest.m4
size_max.m4
stdint_h.m4
threadlib.m4
uintmax_t.m4
ulonglong.m4
visibility.m4

85
m4/ax_check_capsicum.m4 Normal file
View File

@@ -0,0 +1,85 @@
# -*- Autoconf -*-
# SYNOPSIS
#
# AX_CHECK_CAPSICUM([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro searches for an installed Capsicum header and library,
# and if found:
# - AC_DEFINE([HAVE_CAPSICUM]) is called.
# - AC_DEFINE([HAVE_SYS_CAPSICUM_H]) is called if <sys/capsicum.h>
# is present (otherwise <sys/capability.h> must be used).
# - CAPSICUM_LIB is set to the -l option needed to link Capsicum support,
# and AC_SUBST([CAPSICUM_LIB]) is called.
# - The shell commands in ACTION-IF-FOUND are run. The default
# ACTION-IF-FOUND prepends ${CAPSICUM_LIB} into LIBS. If you don't
# want to modify LIBS and don't need to run any other commands either,
# use a colon as ACTION-IF-FOUND.
#
# If Capsicum support isn't found:
# - The shell commands in ACTION-IF-NOT-FOUND are run. The default
# ACTION-IF-NOT-FOUND calls AC_MSG_WARN to print a warning that
# Capsicum support wasn't found.
#
# You should use autoheader to include a definition for the symbols above
# in a config.h file.
#
# Sample usage in a C/C++ source is as follows:
#
# #ifdef HAVE_CAPSICUM
# # ifdef HAVE_SYS_CAPSICUM_H
# # include <sys/capsicum.h>
# # else
# # include <sys/capability.h>
# # endif
# #endif /* HAVE_CAPSICUM */
#
# LICENSE
#
# Copyright (c) 2014 Google Inc.
# Copyright (c) 2015 Lasse Collin <lasse.collin@tukaani.org>
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved. This file is offered as-is,
# without any warranty.
#serial 2
AC_DEFUN([AX_CHECK_CAPSICUM], [
# On FreeBSD >= 11.x and Linux, Capsicum is uses <sys/capsicum.h>.
# If this header is found, it is assumed to be the right one.
capsicum_header_found=no
AC_CHECK_HEADERS([sys/capsicum.h], [capsicum_header_found=yes])
if test "$capsicum_header_found" = no ; then
# On FreeBSD 10.x Capsicum uses <sys/capability.h>. Such a header exists
# on Linux too but it describes POSIX.1e capabilities. Look for the
# declaration of cap_rights_limit to check if <sys/capability.h> is
# a Capsicum header.
AC_CHECK_DECL([cap_rights_limit], [capsicum_header_found=yes], [],
[#include <sys/capability.h>])
fi
capsicum_lib_found=no
CAPSICUM_LIB=
if test "$capsicum_header_found" = yes ; then
AC_LANG_PUSH([C])
# FreeBSD >= 10.x has Capsicum functions in libc.
AC_LINK_IFELSE([AC_LANG_CALL([], [cap_rights_limit])],
[capsicum_lib_found=yes], [])
# Linux has Capsicum functions in libcaprights.
AC_CHECK_LIB([caprights], [cap_rights_limit],
[CAPSICUM_LIB=-lcaprights
capsicum_lib_found=yes], [])
AC_LANG_POP([C])
fi
AC_SUBST([CAPSICUM_LIB])
if test "$capsicum_lib_found" = yes ; then
AC_DEFINE([HAVE_CAPSICUM], [1], [Define to 1 if Capsicum is available.])
m4_default([$1], [LIBS="${CAPSICUM_LIB} $LIBS"])
else
m4_default([$2], [AC_MSG_WARN([Capsicum support not found])])
fi])

View File

@@ -82,7 +82,7 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 18
#serial 21
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
@@ -103,8 +103,8 @@ if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
AC_MSG_RESULT($ax_pthread_ok)
AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
AC_MSG_RESULT([$ax_pthread_ok])
if test x"$ax_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
@@ -164,6 +164,20 @@ case ${host_os} in
;;
esac
# Clang doesn't consider unrecognized options an error unless we specify
# -Werror. We throw in some extra Clang-specific options to ensure that
# this doesn't happen for GCC, which also accepts -Werror.
AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
save_CFLAGS="$CFLAGS"
ax_pthread_extra_flags="-Werror"
CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
[AC_MSG_RESULT([yes])],
[ax_pthread_extra_flags=
AC_MSG_RESULT([no])])
CFLAGS="$save_CFLAGS"
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
@@ -178,7 +192,7 @@ for flag in $ax_pthread_flags; do
;;
pthread-config)
AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
if test x"$ax_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
@@ -193,7 +207,7 @@ for flag in $ax_pthread_flags; do
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
@@ -219,7 +233,7 @@ for flag in $ax_pthread_flags; do
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($ax_pthread_ok)
AC_MSG_RESULT([$ax_pthread_ok])
if test "x$ax_pthread_ok" = xyes; then
break;
fi
@@ -245,9 +259,9 @@ if test "x$ax_pthread_ok" = xyes; then
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT($attr_name)
AC_MSG_RESULT([$attr_name])
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
@@ -261,45 +275,54 @@ if test "x$ax_pthread_ok" = xyes; then
if test "$GCC" = "yes"; then
flag="-D_REENTRANT"
else
# TODO: What about Clang on Solaris?
flag="-mt -D_REENTRANT"
fi
;;
esac
AC_MSG_RESULT(${flag})
AC_MSG_RESULT([$flag])
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
ax_cv_PTHREAD_PRIO_INHERIT, [
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
# More AIX lossage: compile with *_r variant
if test "x$GCC" != xyes; then
case $host_os in
aix*)
AS_CASE(["x/$CC"],
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
;;
esac
fi
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
AC_SUBST([PTHREAD_LIBS])
AC_SUBST([PTHREAD_CFLAGS])
AC_SUBST([PTHREAD_CC])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$ax_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
:
else
ax_pthread_ok=no

View File

@@ -10,8 +10,10 @@
#
# Supported methods:
# - GetSystemInfo(): Windows (including Cygwin)
# - sched_getaffinity(): glibc (GNU/Linux, GNU/kFreeBSD)
# - cpuset_getaffinity(): FreeBSD
# - sysctl(): BSDs, OS/2
# - sysconf(): GNU/Linux, Solaris, Tru64, IRIX, AIX, Cygwin (but
# - sysconf(): GNU/Linux, Solaris, Tru64, IRIX, AIX, QNX, Cygwin (but
# GetSystemInfo() is used on Cygwin)
# - pstat_getdynamic(): HP-UX
#
@@ -45,10 +47,54 @@ compile error
#endif
]])], [tuklib_cv_cpucores_method=special], [
# Look for sysctl() solution first, because on OS/2, both sysconf()
# and sysctl() pass the tests in this file, but only sysctl()
# actually works.
# glibc-based systems (GNU/Linux and GNU/kFreeBSD) have sched_getaffinity().
# The CPU_COUNT() macro was added in glibc 2.9 so we try to link the
# test program instead of merely compiling it. glibc 2.9 is old enough that
# if someone uses the code on older glibc, the fallback to sysconf() should
# be good enough.
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <sched.h>
int
main(void)
{
cpu_set_t cpu_mask;
sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask);
return CPU_COUNT(&cpu_mask);
}
]])], [tuklib_cv_cpucores_method=sched_getaffinity], [
# FreeBSD has both cpuset and sysctl. Look for cpuset first because
# it's a better approach.
#
# This test would match on GNU/kFreeBSD too but it would require
# -lfreebsd-glue when linking and thus in the current form this would
# fail on GNU/kFreeBSD. The above test for sched_getaffinity() matches
# on GNU/kFreeBSD so the test below should never run on that OS.
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <sys/param.h>
#include <sys/cpuset.h>
int
main(void)
{
cpuset_t set;
cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
sizeof(set), &set);
return 0;
}
]])], [tuklib_cv_cpucores_method=cpuset], [
# On OS/2, both sysconf() and sysctl() pass the tests in this file,
# but only sysctl() works. On QNX it's the opposite: only sysconf() works
# (although it assumes that _POSIX_SOURCE, _XOPEN_SOURCE, and _POSIX_C_SOURCE
# are undefined or alternatively _QNX_SOURCE is defined).
#
# We test sysctl() first and intentionally break the sysctl() test on QNX
# so that sysctl() is never used on QNX.
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#ifdef __QNX__
compile error
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
@@ -97,9 +143,19 @@ main(void)
]])], [tuklib_cv_cpucores_method=pstat_getdynamic], [
tuklib_cv_cpucores_method=unknown
])])])])])
])])])])])])])
case $tuklib_cv_cpucores_method in
sched_getaffinity)
AC_DEFINE([TUKLIB_CPUCORES_SCHED_GETAFFINITY], [1],
[Define to 1 if the number of available CPU cores
can be detected with sched_getaffinity()])
;;
cpuset)
AC_DEFINE([TUKLIB_CPUCORES_CPUSET], [1],
[Define to 1 if the number of available CPU cores
can be detected with cpuset(2).])
;;
sysctl)
AC_DEFINE([TUKLIB_CPUCORES_SYSCTL], [1],
[Define to 1 if the number of available CPU cores

View File

@@ -46,7 +46,7 @@ main(void)
fi
AC_MSG_CHECKING([if unaligned memory access should be used])
AC_ARG_ENABLE([unaligned-access], AC_HELP_STRING([--enable-unaligned-access],
AC_ARG_ENABLE([unaligned-access], AS_HELP_STRING([--enable-unaligned-access],
[Enable if the system supports *fast* unaligned memory access
with 16-bit and 32-bit integers. By default, this is enabled
only on x86, x86_64, and big endian PowerPC.]),

View File

@@ -10,8 +10,8 @@
#
# Supported methods:
#
# - Windows (including Cygwin), OS/2, DJGPP (DOS), and OpenVMS have
# operating-system specific functions.
# - Windows (including Cygwin), OS/2, DJGPP (DOS), OpenVMS, AROS,
# and QNX have operating-system specific functions.
#
# - AIX has _system_configuration.physmem.
#
@@ -53,7 +53,8 @@ AC_CACHE_CHECK([how to detect the amount of physical memory],
# a non-compilable text instead of #error to generate an error.
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__OS2__) \
|| defined(__DJGPP__) || defined(__VMS)
|| defined(__DJGPP__) || defined(__VMS) \
|| defined(AMIGA) || defined(__AROS__) || defined(__QNX__)
int main(void) { return 0; }
#else
compile error

694
po/de.po

File diff suppressed because it is too large Load Diff

414
po/fr.po
View File

@@ -1,14 +1,14 @@
# XZ Utils French Translation
# This file is put in the public domain.
# Adrien Nader <camaradetux@gmail.com>, 2011.
# Adrien Nader <adrien@notk.org>, 2011-2014.
#
msgid ""
msgstr ""
"Project-Id-Version: xz-utils\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
"POT-Creation-Date: 2012-05-30 20:40+0200\n"
"POT-Creation-Date: 2014-11-25 20:23+0100\n"
"PO-Revision-Date: 2010-09-24 21;12+0200\n"
"Last-Translator: Adrien Nader <camaradetux@gmail.com>\n"
"Last-Translator: Adrien Nader <adrien@notk.org>\n"
"Language-Team: None\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
@@ -16,73 +16,105 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n==1) ? 0 : 1;\n"
#: src/xz/args.c:338
#: src/xz/args.c:63
#, c-format
msgid "%s: Invalid argument to --block-list"
msgstr ""
#: src/xz/args.c:73
#, c-format
msgid "%s: Too many arguments to --block-list"
msgstr ""
#: src/xz/args.c:102
msgid "0 can only be used as the last element in --block-list"
msgstr ""
#: src/xz/args.c:406
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s : Format de fichier inconnu"
#: src/xz/args.c:361 src/xz/args.c:369
#: src/xz/args.c:429 src/xz/args.c:437
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s : Type de vérification d'intégrité inconnu"
#: src/xz/args.c:396
#: src/xz/args.c:473
msgid "Only one file can be specified with `--files' or `--files0'."
msgstr "Un seul fichier peut être spécifié avec `--files' ou `--files0'."
#: src/xz/args.c:459
#: src/xz/args.c:541
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "La variable d'environnement %s contient trop d'arguments"
#: src/xz/coder.c:105
#: src/xz/coder.c:110
msgid "Maximum number of filters is four"
msgstr "Le nombre maximal de filtres est quatre"
#: src/xz/coder.c:118
#: src/xz/coder.c:129
msgid "Memory usage limit is too low for the given filter setup."
msgstr "La limite d'utilisation mémoire est trop basse pour la configuration de filtres donnée."
#: src/xz/coder.c:148
#: src/xz/coder.c:159
msgid "Using a preset in raw mode is discouraged."
msgstr "Utiliser un préréglage en mode `raw' est déconseillé."
#: src/xz/coder.c:150
#: src/xz/coder.c:161
msgid "The exact options of the presets may vary between software versions."
msgstr "Le détail des préréglages peut varier entre différentes versions du logiciel."
#: src/xz/coder.c:176
#: src/xz/coder.c:184
msgid "The .lzma format supports only the LZMA1 filter"
msgstr "Le format .lzma ne prend en charge que le filtre LZMA1"
#: src/xz/coder.c:184
#: src/xz/coder.c:192
msgid "LZMA1 cannot be used with the .xz format"
msgstr "Le filtre LZMA1 ne peut être utilisé avec le format .xz"
#: src/xz/coder.c:203
#: src/xz/coder.c:209
msgid "The filter chain is incompatible with --flush-timeout"
msgstr ""
#: src/xz/coder.c:215
msgid "Switching to single-threaded mode due to --flush-timeout"
msgstr ""
#: src/xz/coder.c:234
#, c-format
msgid "Using up to %<PRIu32> threads."
msgstr "Jusqu'à %<PRIu32> threads seront utilisés."
#: src/xz/coder.c:216
#: src/xz/coder.c:247
msgid "Unsupported filter chain or filter options"
msgstr "Enchaînement ou options de filtres non pris en charge"
#: src/xz/coder.c:224
#: src/xz/coder.c:255
#, c-format
msgid "Decompression will need %s MiB of memory."
msgstr "La décompression nécessitera %s MiB de mémoire."
#: src/xz/coder.c:259
#: src/xz/coder.c:290
#, c-format
msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB"
msgstr "Nombre de threads réduit de %s à %s pour ne pas dépasser la limite d'utilisation mémoire de %s MiB"
#: src/xz/coder.c:313
#: src/xz/coder.c:344
#, c-format
msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB"
msgstr "Taille du dictionnaire LZMA%c réduite de %s MiB à %s MiB pour ne pas dépasser la limite d'utilisation mémoire de %s MiB"
#: src/xz/file_io.c:90
#, c-format
msgid "Error creating a pipe: %s"
msgstr "Impossible de créer un tube anonyme (pipe) : %s"
#: src/xz/file_io.c:166
#, c-format
msgid "%s: poll() failed: %s"
msgstr "%s : L'appel à la fonction poll() a échoué : %s"
#. TRANSLATORS: When compression or decompression finishes,
#. and xz is going to remove the source file, xz first checks
#. if the source file still exists, and if it does, does its
@@ -93,111 +125,146 @@ msgstr "Taille du dictionnaire LZMA%c réduite de %s MiB à %s MiB pour ne pas d
#. it is possible that the user has put a new file in place
#. of the original file, and in that case it obviously
#. shouldn't be removed.
#: src/xz/file_io.c:136
#: src/xz/file_io.c:236
#, c-format
msgid "%s: File seems to have been moved, not removing"
msgstr "%s : Le fichier a apparemment été déplacé, suppression annulée"
#: src/xz/file_io.c:143 src/xz/file_io.c:635
#: src/xz/file_io.c:243 src/xz/file_io.c:761
#, c-format
msgid "%s: Cannot remove: %s"
msgstr "%s : Impossible de supprimer : %s"
#: src/xz/file_io.c:168
#: src/xz/file_io.c:268
#, c-format
msgid "%s: Cannot set the file owner: %s"
msgstr "%s : Impossible de modifier le propriétaire du fichier : %s"
#: src/xz/file_io.c:174
#: src/xz/file_io.c:274
#, c-format
msgid "%s: Cannot set the file group: %s"
msgstr "%s : Impossible de modifier le groupe propriétaire du fichier : %s"
#: src/xz/file_io.c:193
#: src/xz/file_io.c:293
#, c-format
msgid "%s: Cannot set the file permissions: %s"
msgstr "%s : Impossible de modifier les permissions du fichier : %s"
#: src/xz/file_io.c:340 src/xz/file_io.c:423
# Note from translator on "file status flags".
# The following entry is kept un-translated on purpose. It is difficult to
# translate and should only happen in exceptional circumstances which means
# that translating would:
# - lose some of the meaning
# - make it more difficult to look up in search engines; it might happen one in
# a million times, if we dilute the error message in 20 languages, it will be
# almost impossible to find an explanation and support for the error.
#: src/xz/file_io.c:399
#, c-format
msgid "Error getting the file status flags from standard input: %s"
msgstr ""
#: src/xz/file_io.c:408
#, c-format
msgid "Error setting O_NONBLOCK on standard input: %s"
msgstr "Impossible d'établir le drapeau O_NONBLOCK sur la sortie standard : %s"
#: src/xz/file_io.c:460 src/xz/file_io.c:522
#, c-format
msgid "%s: Is a symbolic link, skipping"
msgstr "%s est un lien symbolique : ignoré"
#: src/xz/file_io.c:468
#: src/xz/file_io.c:551
#, c-format
msgid "%s: Is a directory, skipping"
msgstr "%s est un répertoire : ignoré"
#: src/xz/file_io.c:474
#: src/xz/file_io.c:557
#, c-format
msgid "%s: Not a regular file, skipping"
msgstr "%s n'est pas un fichier régulier : ignoré"
#: src/xz/file_io.c:491
#: src/xz/file_io.c:574
#, c-format
msgid "%s: File has setuid or setgid bit set, skipping"
msgstr "%s : Le fichier possède les bits `setuid' ou `setgid' : ignoré"
#: src/xz/file_io.c:498
#: src/xz/file_io.c:581
#, c-format
msgid "%s: File has sticky bit set, skipping"
msgstr "%s : Le fichier possède le bit `sticky' : ignoré"
#: src/xz/file_io.c:505
#: src/xz/file_io.c:588
#, c-format
msgid "%s: Input file has more than one hard link, skipping"
msgstr "%s : Le fichier d'entrée a plus d'un lien matériel : ignoré"
#: src/xz/file_io.c:761
# See note from translator above titled "file status flags".
#: src/xz/file_io.c:668
#, c-format
msgid "Error restoring the status flags to standard input: %s"
msgstr ""
# See note from translator above titled "file status flags".
#: src/xz/file_io.c:714
#, c-format
msgid "Error getting the file status flags from standard output: %s"
msgstr ""
#: src/xz/file_io.c:723
#, c-format
msgid "Error setting O_NONBLOCK on standard output: %s"
msgstr "Impossible d'activer le drapeau O_NONBLOCK sur la sortie standard : %s"
#: src/xz/file_io.c:896
#, c-format
msgid "Error restoring the O_APPEND flag to standard output: %s"
msgstr "Impossible de rétablir le drapeau O_APPEND sur la sortie standard : %s"
#: src/xz/file_io.c:773
#: src/xz/file_io.c:908
#, c-format
msgid "%s: Closing the file failed: %s"
msgstr "%s : Impossible de fermer le fichier : %s"
#: src/xz/file_io.c:809 src/xz/file_io.c:1008
#: src/xz/file_io.c:944 src/xz/file_io.c:1170
#, c-format
msgid "%s: Seeking failed when trying to create a sparse file: %s"
msgstr "%s : Impossible de se déplacer dans le fichier pour créer un 'sparse file' : %s"
#: src/xz/file_io.c:883
#: src/xz/file_io.c:1039
#, c-format
msgid "%s: Read error: %s"
msgstr "%s : Erreur d'écriture : %s"
#: src/xz/file_io.c:906
#: src/xz/file_io.c:1059
#, c-format
msgid "%s: Error seeking the file: %s"
msgstr "%s : Impossible de se déplacer dans le fichier : %s"
#: src/xz/file_io.c:916
#: src/xz/file_io.c:1069
#, c-format
msgid "%s: Unexpected end of file"
msgstr "%s : Fin de fichier inattendue"
#: src/xz/file_io.c:966
#: src/xz/file_io.c:1128
#, c-format
msgid "%s: Write error: %s"
msgstr "%s : Erreur d'écriture : %s"
#: src/xz/hardware.c:101
#: src/xz/hardware.c:107
msgid "Disabled"
msgstr "Désactivé"
#. TRANSLATORS: Test with "xz --info-memory" to see if
#. the alignment looks nice.
#: src/xz/hardware.c:120
#: src/xz/hardware.c:126
msgid "Total amount of physical memory (RAM): "
msgstr "Quantité totale de mémoire physique (RAM) : "
#: src/xz/hardware.c:122
#: src/xz/hardware.c:128
msgid "Memory usage limit for compression: "
msgstr "Limite d'utilisation pour la compression : "
#: src/xz/hardware.c:124
#: src/xz/hardware.c:130
msgid "Memory usage limit for decompression: "
msgstr "Limite d'utilisation pour la décompression : "
@@ -275,41 +342,41 @@ msgstr "%s : Trop petit pour être un fichier xz valide."
#. to Ratio, the columns are right aligned. Check and Filename
#. are left aligned. If you need longer words, it's OK to
#. use two lines here. Test with "xz -l foo.xz".
#: src/xz/list.c:645
#: src/xz/list.c:671
msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename"
msgstr "Flux Blocs Compressé Décompressé Ratio Vérif Nom de fichier"
msgstr "Flux Blocs Compressé Décompressé Ratio Vérif. Nom de fichier"
#: src/xz/list.c:685
#: src/xz/list.c:711
#, c-format
msgid " Streams: %s\n"
msgstr " Flux : %s\n"
#: src/xz/list.c:687
#: src/xz/list.c:713
#, c-format
msgid " Blocks: %s\n"
msgstr " Blocs : %s\n"
#: src/xz/list.c:689
#: src/xz/list.c:715
#, c-format
msgid " Compressed size: %s\n"
msgstr " Taille compressé : %s\n"
msgstr " Taille données avec compression : %s\n"
#: src/xz/list.c:692
#: src/xz/list.c:718
#, c-format
msgid " Uncompressed size: %s\n"
msgstr " Taille décompressé : %s\n"
msgstr " Taille données sans compression : %s\n"
#: src/xz/list.c:695
#: src/xz/list.c:721
#, c-format
msgid " Ratio: %s\n"
msgstr " Ratio : %s\n"
#: src/xz/list.c:697
#: src/xz/list.c:723
#, c-format
msgid " Check: %s\n"
msgstr " Vérification : %s\n"
#: src/xz/list.c:698
#: src/xz/list.c:724
#, c-format
msgid " Stream padding: %s\n"
msgstr " Octets de rembourrage du flux : %s\n"
@@ -317,7 +384,7 @@ msgstr " Octets de rembourrage du flux : %s\n"
#. TRANSLATORS: The second line is column headings. All except
#. Check are right aligned; Check is left aligned. Test with
#. "xz -lv foo.xz".
#: src/xz/list.c:726
#: src/xz/list.c:752
msgid ""
" Streams:\n"
" Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding"
@@ -327,7 +394,7 @@ msgstr ""
#. TRANSLATORS: The second line is column headings. All
#. except Check are right aligned; Check is left aligned.
#: src/xz/list.c:781
#: src/xz/list.c:807
#, c-format
msgid ""
" Blocks:\n"
@@ -343,57 +410,57 @@ msgstr ""
#. are right aligned. %*s is replaced with 0-120
#. spaces to make the CheckVal column wide enough.
#. Test with "xz -lvv foo.xz".
#: src/xz/list.c:793
#: src/xz/list.c:819
#, c-format
msgid " CheckVal %*s Header Flags CompSize MemUsage Filters"
msgstr " ValVérif %*sEn-tête Drapeaux TailleComp UtilMém Filtres"
#: src/xz/list.c:871 src/xz/list.c:1046
#: src/xz/list.c:897 src/xz/list.c:1072
#, c-format
msgid " Memory needed: %s MiB\n"
msgstr " Mémoire nécessaire : %s MiB\n"
#: src/xz/list.c:873 src/xz/list.c:1048
#: src/xz/list.c:899 src/xz/list.c:1074
#, c-format
msgid " Sizes in headers: %s\n"
msgstr " Tailles stockées dans l'en-tête : %s\n"
#: src/xz/list.c:874 src/xz/list.c:1049
#: src/xz/list.c:900 src/xz/list.c:1075
msgid "Yes"
msgstr "Oui"
#: src/xz/list.c:874 src/xz/list.c:1049
#: src/xz/list.c:900 src/xz/list.c:1075
msgid "No"
msgstr "Non"
#: src/xz/list.c:875 src/xz/list.c:1050
#: src/xz/list.c:901 src/xz/list.c:1076
#, c-format
msgid " Minimum XZ Utils version: %s\n"
msgstr " Version minimale de XZ Utils : %s\n"
#. TRANSLATORS: %s is an integer. Only the plural form of this
#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz".
#: src/xz/list.c:1025
#: src/xz/list.c:1051
#, c-format
msgid "%s file\n"
msgid_plural "%s files\n"
msgstr[0] "%s fichier\n"
msgstr[1] "%s fichiers\n"
#: src/xz/list.c:1038
#: src/xz/list.c:1064
msgid "Totals:"
msgstr "Totaux :"
#: src/xz/list.c:1039
#: src/xz/list.c:1065
#, c-format
msgid " Number of files: %s\n"
msgstr " Nombre de fichiers : %s\n"
#: src/xz/list.c:1114
#: src/xz/list.c:1140
msgid "--list works only on .xz files (--format=xz or --format=auto)"
msgstr "--list ne marche que sur les fichiers .xz (--format=xz ou --format=auto)"
#: src/xz/list.c:1120
#: src/xz/list.c:1146
msgid "--list does not support reading from standard input"
msgstr "--list est incompatible avec la lecture sur l'entrée standard"
@@ -424,68 +491,68 @@ msgstr "Impossible de lire à la fois les données et les noms de fichiers depui
#. of the line in messages. Usually it becomes "xz: ".
#. This is a translatable string because French needs
#. a space before a colon.
#: src/xz/message.c:733
#: src/xz/message.c:713
#, c-format
msgid "%s: "
msgstr "%s : "
#: src/xz/message.c:796 src/xz/message.c:846
#: src/xz/message.c:776 src/xz/message.c:826
msgid "Internal error (bug)"
msgstr "Erreur interne (bug)"
#: src/xz/message.c:803
#: src/xz/message.c:783
msgid "Cannot establish signal handlers"
msgstr "Impossible d'installer le gestionnaire de signaux"
#: src/xz/message.c:812
#: src/xz/message.c:792
msgid "No integrity check; not verifying file integrity"
msgstr "Pas de données de vérification d'intégrité ; vérification non effectuée"
#: src/xz/message.c:815
#: src/xz/message.c:795
msgid "Unsupported type of integrity check; not verifying file integrity"
msgstr "Méthode de vérification d'intégrité non prise en charge ; vérification non effectuée"
#: src/xz/message.c:822
#: src/xz/message.c:802
msgid "Memory usage limit reached"
msgstr "Limite d'utilisation mémoire atteinte"
#: src/xz/message.c:825
#: src/xz/message.c:805
msgid "File format not recognized"
msgstr "Format de fichier inconnu"
#: src/xz/message.c:828
#: src/xz/message.c:808
msgid "Unsupported options"
msgstr "Options non prises en charge"
#: src/xz/message.c:831
#: src/xz/message.c:811
msgid "Compressed data is corrupt"
msgstr "Les données compressées sont corrompues"
#: src/xz/message.c:834
#: src/xz/message.c:814
msgid "Unexpected end of input"
msgstr "Fin des données inattendue "
#: src/xz/message.c:867
#: src/xz/message.c:847
#, c-format
msgid "%s MiB of memory is required. The limiter is disabled."
msgstr "%s MiB de mémoire sont nécessaires. La limite est désactivée."
#: src/xz/message.c:895
#: src/xz/message.c:875
#, c-format
msgid "%s MiB of memory is required. The limit is %s."
msgstr "%s MiB de mémoire sont nécessaires, la limite étant %s."
#: src/xz/message.c:1062
#: src/xz/message.c:1042
#, c-format
msgid "%s: Filter chain: %s\n"
msgstr "%s : Enchaînement de filtres : %s\n"
#: src/xz/message.c:1072
#: src/xz/message.c:1052
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Utilisez `%s --help' pour plus d'informations."
msgstr "Éxécutez `%s --help' pour obtenir davantage d'informations."
#: src/xz/message.c:1098
#: src/xz/message.c:1078
#, c-format
msgid ""
"Usage: %s [OPTION]... [FILE]...\n"
@@ -496,57 +563,57 @@ msgstr ""
"Compresse ou decompresse FICHIER(s) au format .xz.\n"
"\n"
#: src/xz/message.c:1105
#: src/xz/message.c:1085
msgid "Mandatory arguments to long options are mandatory for short options too.\n"
msgstr ""
"Les arguments obligatoires pour les options longues le sont aussi pour les\n"
"options courtes.\n"
#: src/xz/message.c:1109
#: src/xz/message.c:1089
msgid " Operation mode:\n"
msgstr " Mode d'opération :\n"
#: src/xz/message.c:1112
#: src/xz/message.c:1092
msgid ""
" -z, --compress force compression\n"
" -d, --decompress force decompression\n"
" -t, --test test compressed file integrity\n"
" -l, --list list information about .xz files"
msgstr ""
" -z, --compress forcer la compression\n"
" -d, --decompress forcer la décompression\n"
" -z, --compress forcer le mode compression\n"
" -d, --decompress forcer le mode décompression\n"
" -t, --test tester l'intégrité du fichier compressé\n"
" -l, --list lister les informations à propos des fichiers .xz"
" -l, --list lister les informations sur les fichiers .xz"
#: src/xz/message.c:1118
#: src/xz/message.c:1098
msgid ""
"\n"
" Operation modifiers:\n"
msgstr ""
"\n"
" Modifictauers :\n"
" Modificateurs :\n"
#: src/xz/message.c:1121
#: src/xz/message.c:1101
msgid ""
" -k, --keep keep (don't delete) input files\n"
" -f, --force force overwrite of output file and (de)compress links\n"
" -c, --stdout write to standard output and don't delete input files"
msgstr ""
" -k, --keep ne pas supprimer les fichiers d'entrée (\"keep\")\n"
" -f, --force forcer l'écrasement du fichier de sortie et\n"
" (dé)compresser les liens\n"
" -k, --keep ne pas supprimer les fichiers d'entrée\n"
" -f, --force forcer l'écrasement éventuel du fichier de sortie et\n"
" (dé)compresser les liens symboliques\n"
" -c, --stdout écrire sur la sortie standard et ne pas supprimer les\n"
" fichiers d'entrée"
#: src/xz/message.c:1127
#: src/xz/message.c:1107
msgid ""
" --single-stream decompress only the first stream, and silently\n"
" ignore possible remaining input data"
msgstr ""
" --single-stream décompresser uniquement le premier flux et ignorer\n"
" silenciseusement les données éventuellement restantes"
" silencieusement les données éventuellement restantes"
#: src/xz/message.c:1130
#: src/xz/message.c:1110
msgid ""
" --no-sparse do not create sparse files when decompressing\n"
" -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n"
@@ -559,10 +626,10 @@ msgstr ""
" -S, --suffix=.SUF utiliser le suffixe `.SUF' pour les fichiers compressés\n"
" --files[=FILE] lire les fichiers sur lesquels opérer depuis FILE ; si\n"
" FILE est omis, ceux-ci sont lus depuis l'entrée standard\n"
" et doivent être suivis d'un caractère de retour à la ligne\n"
" et doivent être suivis d'un caractère retour à la ligne\n"
" --files0[=FILE] comme --files mais avec un caractère null comme séparateur"
#: src/xz/message.c:1139
#: src/xz/message.c:1119
msgid ""
"\n"
" Basic file format and compression options:\n"
@@ -570,47 +637,80 @@ msgstr ""
"\n"
" Options basiques de format de fichier et de compression :\n"
#: src/xz/message.c:1141
#: src/xz/message.c:1121
msgid ""
" -F, --format=FMT file format to encode or decode; possible values are\n"
" `auto' (default), `xz', `lzma', and `raw'\n"
" -C, --check=CHECK integrity check type: `none' (use with caution),\n"
" `crc32', `crc64' (default), or `sha256'"
msgstr ""
" -F, --format=FMT format de fichier à encoder ou décoder ; les possibilités\n"
" sont : `auto' (par défaut), `xz', `lzma' et `raw'\n"
" -F, --format=FMT format du fichier à encoder ou décoder ; sont acceptés :\n"
" `auto' (par défaut), `xz', `lzma' et `raw'\n"
" -C, --check=CHECK type de vérification d'intégrité : `none' (à utiliser avec\n"
" précaution), `crc32', `crc64' (par défaut) ou `sha256'"
#: src/xz/message.c:1148
#: src/xz/message.c:1126
msgid " --ignore-check don't verify the integrity check when decompressing"
msgstr ""
" --ignore-check ne pas vérifier l'intégrité des données lors de\n"
" la décompression"
#: src/xz/message.c:1130
msgid ""
" -0 ... -9 compression preset; default is 6; take compressor *and*\n"
" decompressor memory usage into account before using 7-9!"
msgstr ""
" -0 ... -9 préréglage de compression ; 6 par défaut ; pensez à\n"
" -0 ... -9 préréglage de compression : 6 par défaut ; pensez à\n"
" l'utilisation mémoire du compresseur *et* du décompresseur\n"
" avant d'utiliser 7, 8 ou 9 !"
#: src/xz/message.c:1152
#: src/xz/message.c:1134
msgid ""
" -e, --extreme try to improve compression ratio by using more CPU time;\n"
" does not affect decompressor memory requirements"
msgstr ""
" -e, --extreme essayer d'améliorer la compression en utilisant davantage\n"
" de temps processeur sans affecter les besoins mémoire du\n"
" décompresseur"
" de temps processeur ;\n"
" n'affecte pas les besoins mémoire du décompresseur"
#: src/xz/message.c:1157
#: src/xz/message.c:1138
msgid ""
" -T, --threads=NUM use at most NUM threads; the default is 1; set to 0\n"
" to use as many threads as there are processor cores"
msgstr ""
" -T, --threads=NB créer au plus NB fils de compression (1 par défault) ; la\n"
" valeur 0 est spéciale et équivaut au nombre de processeurs\n"
" de la machine"
#: src/xz/message.c:1143
msgid ""
" --block-size=SIZE\n"
" when compressing to the .xz format, start a new block\n"
" after every SIZE bytes of input; 0=disabled (default)"
" start a new .xz block after every SIZE bytes of input;\n"
" use this to set the block size for threaded compression"
msgstr ""
" --block-size=SIZE\n"
" pour une compression au format .xz, entamer un nouveau\n"
" bloc après SIZE octets d'entrée ; 0=désactivé (par défaut)"
" --block-size=TAILLE\n"
" débuter un bloc XZ après chaque TAILLE octets de données\n"
" d'entrée ; ce réglage sert pour la compression paralléle"
#: src/xz/message.c:1161
#: src/xz/message.c:1147
msgid ""
" --block-list=SIZES\n"
" start a new .xz block after the given comma-separated\n"
" intervals of uncompressed data"
msgstr ""
" --block-list=TAILLES\n"
" débuter des blocs XZ après les TAILLES octets de données\n"
" spécifiées avec des virgules pour séparateur"
#: src/xz/message.c:1151
msgid ""
" --flush-timeout=TIMEOUT\n"
" when compressing, if more than TIMEOUT milliseconds has\n"
" passed since the previous flush and reading more input\n"
" would block, all pending data is flushed out"
msgstr ""
#: src/xz/message.c:1157
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
@@ -623,10 +723,10 @@ msgstr ""
" --memlimit-decompress=LIMIT\n"
" -M, --memlimit=LIMIT\n"
" règle la limite d'utilisation mémoire pour la compression,\n"
" décompression ou les deux ; LIMIT est en octets, % de\n"
" RAM, ou 0 pour les valeurs par défaut"
" décompression ou les deux ; LIMIT est en octets,\n"
" pourcentage de RAM, ou 0 pour la valeur par défaut"
#: src/xz/message.c:1168
#: src/xz/message.c:1164
msgid ""
" --no-adjust if compression settings exceed the memory usage limit,\n"
" give an error instead of adjusting the settings downwards"
@@ -635,15 +735,15 @@ msgstr ""
" d'utilisation mémoire, renvoyer une erreur plutôt que de\n"
" diminuer les réglages"
#: src/xz/message.c:1174
#: src/xz/message.c:1170
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
msgstr ""
"\n"
" Enchaînement de filtres de compression personnalisé (au lieu des préréglages) :"
" Chaîne de filtres de compression personnalisée (en lieu des préréglages) :"
#: src/xz/message.c:1183
#: src/xz/message.c:1179
msgid ""
"\n"
" --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
@@ -659,8 +759,8 @@ msgid ""
" depth=NUM maximum search depth; 0=automatic (default)"
msgstr ""
"\n"
" --lzma1[=OPTS] LZMA1 ou LZMA2 ; OPTS est une liste de zéro ou plusieurs\n"
" --lzma2[=OPTS] options parmi les suivantes (vals. valides ; par défaut) :\n"
" --lzma1[=OPTS] LZMA1/2 ; OPTS est une liste d'options parmi les suivantes\n"
" --lzma2[=OPTS] (entre parenthèses : valeurs valides et par défaut) :\n"
" preset=PRE remettre les options à un préréglage (0-9[e])\n"
" dict=NUM taille dictionnaire (4KiB - 1536MiB ; 8MiB)\n"
" lc=NUM nombre de 'literal context bits' (0-4 ; 3)\n"
@@ -672,7 +772,7 @@ msgstr ""
" depth=NUM profondeur de recherche maximale ;\n"
" 0=automatique (par défaut)"
#: src/xz/message.c:1198
#: src/xz/message.c:1194
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
@@ -692,9 +792,9 @@ msgstr ""
" --armthumb[=OPTS] filtre BCJ ARM-Thumb ('little endian' uniquement)\n"
" --sparc[=OPTS] filtre BCJ SPARC\n"
" OPTS valides pour tous les filtres BCJ :\n"
" start=NUM start offset for conversions (default=0)"
" start=NUM position de début de la conversion (défaut=0)"
#: src/xz/message.c:1210
#: src/xz/message.c:1206
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
@@ -703,10 +803,10 @@ msgid ""
msgstr ""
"\n"
" --delta[=OPTS] Filtre delta ; OPTS valides (vals. valides ; par défaut) :\n"
" dist=NUM distance entre les octets soustraits\n"
" les uns aux autres (1-256 ; 1)"
" dist=NUM distance entre les octets soustraits les\n"
" uns aux autres (1-256 ; 1)"
#: src/xz/message.c:1218
#: src/xz/message.c:1214
msgid ""
"\n"
" Other options:\n"
@@ -714,54 +814,54 @@ msgstr ""
"\n"
" Autres options :\n"
#: src/xz/message.c:1221
#: src/xz/message.c:1217
msgid ""
" -q, --quiet suppress warnings; specify twice to suppress errors too\n"
" -v, --verbose be verbose; specify twice for even more verbose"
msgstr ""
" -q, --quiet supprimer les avertissemnts ; spécifier deux fois pour\n"
" aussi supprimer les erreur\n"
" -q, --quiet masquer les avertissements ; spécifier deux fois pour\n"
" aussi masquer les erreurs\n"
" -v, --verbose être bavard ; spécifier deux fois pour l'être davantage"
#: src/xz/message.c:1226
#: src/xz/message.c:1222
msgid " -Q, --no-warn make warnings not affect the exit status"
msgstr " -Q, --no-warn les avertissements ne modifient pas le code de sortie"
#: src/xz/message.c:1228
#: src/xz/message.c:1224
msgid " --robot use machine-parsable messages (useful for scripts)"
msgstr ""
" --robot utiliser des messages lisibles par un programme\n"
" (utile pour les scripts)"
#: src/xz/message.c:1231
#: src/xz/message.c:1227
msgid ""
" --info-memory display the total amount of RAM and the currently active\n"
" memory usage limits, and exit"
msgstr ""
" --info-memory affiche la quantité totale de RAM et la limite actuelle\n"
" en mémoire puis quitte"
" --info-memory afficher la quantité totale de RAM ainsi que la limite\n"
" actuelle d'utilisation mémoire puis quitter"
#: src/xz/message.c:1234
#: src/xz/message.c:1230
msgid ""
" -h, --help display the short help (lists only the basic options)\n"
" -H, --long-help display this long help and exit"
msgstr ""
" -h, --help affiche l'aide courte (ne liste que les options de base)\n"
" -H, --long-help affiche l'aide longue (ceci) puis quitte"
" -h, --help afficher l'aide courte (ne liste que les options de base)\n"
" -H, --long-help afficher l'aide longue (ceci) puis quitter"
#: src/xz/message.c:1238
#: src/xz/message.c:1234
msgid ""
" -h, --help display this short help and exit\n"
" -H, --long-help display the long help (lists also the advanced options)"
msgstr ""
" -h, --help affiche l'aide courte (ceci) puis quitte\n"
" -H, --long-help affiche l'aide longue (liste aussi les options avancées)"
" -h, --help afficher l'aide courte (ceci) puis quitter\n"
" -H, --long-help afficher l'aide longue (liste aussi les options avancées)"
#: src/xz/message.c:1243
#: src/xz/message.c:1239
msgid " -V, --version display the version number and exit"
msgstr " -V, --version affiche le numéro de version puis quitte"
msgstr " -V, --version afficher le numéro de version puis quitter"
#: src/xz/message.c:1245
#: src/xz/message.c:1241
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
@@ -773,17 +873,21 @@ msgstr ""
#. for this package. Please add _another line_ saying
#. "Report translation bugs to <...>\n" with the email or WWW
#. address for translation bugs. Thanks.
#: src/xz/message.c:1251
#: src/xz/message.c:1247
#, c-format
msgid "Report bugs to <%s> (in English or Finnish).\n"
msgstr ""
"Signaler les bogues à <%s> (en anglais ou en finlandais).\n"
"Signaler les bogues de traduction à <camaradetux@gmail.com>.\n"
"Signaler les bogues de traduction à <adrien@notk.org>.\n"
#: src/xz/message.c:1253
#: src/xz/message.c:1249
#, c-format
msgid "%s home page: <%s>\n"
msgstr "%s page du projet : <%s>\n"
msgstr "Page du projet %s : <%s>\n"
#: src/xz/message.c:1253
msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."
msgstr ""
#: src/xz/options.c:86
#, c-format
@@ -803,7 +907,7 @@ msgstr "%s : Valeur d'option invalide"
#: src/xz/options.c:247
#, c-format
msgid "Unsupported LZMA1/LZMA2 preset: %s"
msgstr "Préréglage LZMA1/LZMA2 non pris en charge : %s"
msgstr "Préréglage LZMA1/LZMA2 non reconnu : %s"
#: src/xz/options.c:355
msgid "The sum of lc and lp must not exceed 4"
@@ -834,34 +938,34 @@ msgstr "%s : Le fichier a déjà le suffixe '%s', ignoré"
msgid "%s: Invalid filename suffix"
msgstr "%s: Suffixe de nom de fichier invalide"
#: src/xz/util.c:61
#: src/xz/util.c:71
#, c-format
msgid "%s: Value is not a non-negative decimal integer"
msgstr "%s : La valeur n'est pas un entier décimal non négatif"
#: src/xz/util.c:103
#: src/xz/util.c:113
#, c-format
msgid "%s: Invalid multiplier suffix"
msgstr "%s : Suffixe multiplicateur invalide"
#: src/xz/util.c:105
#: src/xz/util.c:115
msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)."
msgstr "Les suffixes valides sont 'KiB' (2^10), 'MiB' (2^20) et 'GiB' (2^30)."
#: src/xz/util.c:122
#: src/xz/util.c:132
#, c-format
msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
msgstr "La valeur de l'option '%s' doit être inclue entre %<PRIu64> et %<PRIu64>"
#: src/xz/util.c:247
#: src/xz/util.c:257
msgid "Empty filename, skipping"
msgstr "Nom de fichier vide, ignoré"
#: src/xz/util.c:261
#: src/xz/util.c:271
msgid "Compressed data cannot be read from a terminal"
msgstr "Les données compressées ne peuvent pas être lues depuis un terminal"
#: src/xz/util.c:274
#: src/xz/util.c:284
msgid "Compressed data cannot be written to a terminal"
msgstr "Les données compressées ne peuvent pas être écrites dans un terminal"

452
po/it.po

File diff suppressed because it is too large Load Diff

332
po/pl.po
View File

@@ -1,13 +1,13 @@
# Polish translation for xz.
# This file is in the public domain.
# Jakub Bogusz <qboosh@pld-linux.org>, 2011-2012.
# Jakub Bogusz <qboosh@pld-linux.org>, 2011-2014.
#
msgid ""
msgstr ""
"Project-Id-Version: xz 5.1.1\n"
"Project-Id-Version: xz 5.1.4\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
"POT-Creation-Date: 2012-05-29 13:59+0300\n"
"PO-Revision-Date: 2012-05-29 18:15+0200\n"
"POT-Creation-Date: 2014-09-14 21:56+0300\n"
"PO-Revision-Date: 2014-10-15 20:53+0200\n"
"Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
"Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
"Language: pl\n"
@@ -16,73 +16,105 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
#: src/xz/args.c:338
#: src/xz/args.c:63
#, c-format
msgid "%s: Invalid argument to --block-list"
msgstr "%s: Błędny argument dla --block-list"
#: src/xz/args.c:73
#, c-format
msgid "%s: Too many arguments to --block-list"
msgstr "%s: Zbyt dużo argumentów dla --block-list"
#: src/xz/args.c:102
msgid "0 can only be used as the last element in --block-list"
msgstr "0 w --block-list może być użyte wyłącznie jako ostatni element"
#: src/xz/args.c:406
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s: Nieznany typ formatu pliku"
#: src/xz/args.c:361 src/xz/args.c:369
#: src/xz/args.c:429 src/xz/args.c:437
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s: Nieobsługiwany typ kontroli spójności"
#: src/xz/args.c:396
#: src/xz/args.c:473
msgid "Only one file can be specified with `--files' or `--files0'."
msgstr "Wraz z opcją `--files' lub `--files0' można podać tylko jeden plik."
#: src/xz/args.c:459
#: src/xz/args.c:541
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "Zmienna środowiskowa %s zawiera zbyt dużo argumentów"
#: src/xz/coder.c:105
#: src/xz/coder.c:110
msgid "Maximum number of filters is four"
msgstr "Maksymalna liczba filtrów to cztery"
#: src/xz/coder.c:118
#: src/xz/coder.c:129
msgid "Memory usage limit is too low for the given filter setup."
msgstr "Limit użycia pamięci jest zbyt mały dla podanej konfiguracji filtra."
#: src/xz/coder.c:148
#: src/xz/coder.c:159
msgid "Using a preset in raw mode is discouraged."
msgstr "Użycie ustawień predefiniowanych w trybie surowym jest odradzane."
#: src/xz/coder.c:150
#: src/xz/coder.c:161
msgid "The exact options of the presets may vary between software versions."
msgstr "Dokładne opcje ustawień predefiniowanych mogą różnić się między wersjami oprogramowania."
#: src/xz/coder.c:176
#: src/xz/coder.c:184
msgid "The .lzma format supports only the LZMA1 filter"
msgstr "Format .lzma obsługuje tylko filtr LZMA1"
#: src/xz/coder.c:184
#: src/xz/coder.c:192
msgid "LZMA1 cannot be used with the .xz format"
msgstr "LZMA1 nie może być używany z formatem .xz"
#: src/xz/coder.c:203
#: src/xz/coder.c:209
msgid "The filter chain is incompatible with --flush-timeout"
msgstr "Łańcuch filtrów jest niezgodny z --flush-timeout"
#: src/xz/coder.c:215
msgid "Switching to single-threaded mode due to --flush-timeout"
msgstr "Przełączanie w tryb jednowątkowy z powodu --flush-timeout"
#: src/xz/coder.c:234
#, c-format
msgid "Using up to %<PRIu32> threads."
msgstr "Maksymalna liczba używanych wątków: %<PRIu32>."
#: src/xz/coder.c:216
#: src/xz/coder.c:247
msgid "Unsupported filter chain or filter options"
msgstr "Nieobsługiwany łańcuch filtrów lub opcje filtra"
#: src/xz/coder.c:224
#: src/xz/coder.c:255
#, c-format
msgid "Decompression will need %s MiB of memory."
msgstr "Dekompresja będzie wymagała %s MiB pamięci."
#: src/xz/coder.c:259
#: src/xz/coder.c:290
#, c-format
msgid "Adjusted the number of threads from %s to %s to not exceed the memory usage limit of %s MiB"
msgstr "Skorygowano liczbę wątków z %s do %s, aby nie przekroczyć limitu użycia pamięci %s MiB"
#: src/xz/coder.c:313
#: src/xz/coder.c:344
#, c-format
msgid "Adjusted LZMA%c dictionary size from %s MiB to %s MiB to not exceed the memory usage limit of %s MiB"
msgstr "Skorygowano rozmiar słownika LZMA%c z %s MiB do %s MiB aby nie przekroczyć limitu użycia pamięci %s MiB"
#: src/xz/file_io.c:90
#, c-format
msgid "Error creating a pipe: %s"
msgstr "Błąd tworzenia potoku: %s"
#: src/xz/file_io.c:166
#, c-format
msgid "%s: poll() failed: %s"
msgstr "%s: poll() nie powiodło się: %s"
#. TRANSLATORS: When compression or decompression finishes,
#. and xz is going to remove the source file, xz first checks
#. if the source file still exists, and if it does, does its
@@ -93,111 +125,136 @@ msgstr "Skorygowano rozmiar słownika LZMA%c z %s MiB do %s MiB aby nie przekroc
#. it is possible that the user has put a new file in place
#. of the original file, and in that case it obviously
#. shouldn't be removed.
#: src/xz/file_io.c:136
#: src/xz/file_io.c:236
#, c-format
msgid "%s: File seems to have been moved, not removing"
msgstr "%s: Plik wygląda na przeniesiony, nie zostanie usunięty"
#: src/xz/file_io.c:143 src/xz/file_io.c:635
#: src/xz/file_io.c:243 src/xz/file_io.c:761
#, c-format
msgid "%s: Cannot remove: %s"
msgstr "%s: Nie można usunąć: %s"
#: src/xz/file_io.c:168
#: src/xz/file_io.c:268
#, c-format
msgid "%s: Cannot set the file owner: %s"
msgstr "%s: Nie można ustawić właściciela pliku: %s"
#: src/xz/file_io.c:174
#: src/xz/file_io.c:274
#, c-format
msgid "%s: Cannot set the file group: %s"
msgstr "%s: Nie można ustawić grupy pliku: %s"
#: src/xz/file_io.c:193
#: src/xz/file_io.c:293
#, c-format
msgid "%s: Cannot set the file permissions: %s"
msgstr "%s: Nie można ustawić uprawnień pliku: %s"
#: src/xz/file_io.c:340 src/xz/file_io.c:423
#: src/xz/file_io.c:399
#, c-format
msgid "Error getting the file status flags from standard input: %s"
msgstr "Błąd podczas pobierania flag stanu pliku ze standardowego wejścia: %s"
#: src/xz/file_io.c:408
#, c-format
msgid "Error setting O_NONBLOCK on standard input: %s"
msgstr "Błąd podczas ustawiania O_NONBLOCK dla standardowego wejścia: %s"
#: src/xz/file_io.c:460 src/xz/file_io.c:522
#, c-format
msgid "%s: Is a symbolic link, skipping"
msgstr "%s: Jest dowiązaniem symbolicznym, pominięto"
#: src/xz/file_io.c:468
#: src/xz/file_io.c:551
#, c-format
msgid "%s: Is a directory, skipping"
msgstr "%s: Jest katalogiem, pominięto"
#: src/xz/file_io.c:474
#: src/xz/file_io.c:557
#, c-format
msgid "%s: Not a regular file, skipping"
msgstr "%s: Nie jest zwykłym plikiem, pominięto"
#: src/xz/file_io.c:491
#: src/xz/file_io.c:574
#, c-format
msgid "%s: File has setuid or setgid bit set, skipping"
msgstr "%s: Plik ma ustawiony bit setuid lub setgid, pominięto"
#: src/xz/file_io.c:498
#: src/xz/file_io.c:581
#, c-format
msgid "%s: File has sticky bit set, skipping"
msgstr "%s: Plik ma ustawiony bit sticky, pominięto"
#: src/xz/file_io.c:505
#: src/xz/file_io.c:588
#, c-format
msgid "%s: Input file has more than one hard link, skipping"
msgstr "%s: Plik wejściowy ma więcej niż jedno dowiązanie zwykłe, pominięto"
#: src/xz/file_io.c:761
#: src/xz/file_io.c:668
#, c-format
msgid "Error restoring the status flags to standard input: %s"
msgstr "Błąd podczas odtwarzania flag stanu dla standardowego wejścia: %s"
#: src/xz/file_io.c:714
#, c-format
msgid "Error getting the file status flags from standard output: %s"
msgstr "Błąd podczas pobierania flag stanu pliku ze standardowego wyjścia: %s"
#: src/xz/file_io.c:723
#, c-format
msgid "Error setting O_NONBLOCK on standard output: %s"
msgstr "Błąd podczas ustawiania O_NONBLOCK dla standardowego wyjścia: %s"
#: src/xz/file_io.c:896
#, c-format
msgid "Error restoring the O_APPEND flag to standard output: %s"
msgstr "Błąd podczas odtwarzania flagi O_APPEND dla standardowego wyjścia: %s"
#: src/xz/file_io.c:773
#: src/xz/file_io.c:908
#, c-format
msgid "%s: Closing the file failed: %s"
msgstr "%s: Zamknięcie pliku nie powiodło się: %s"
#: src/xz/file_io.c:809 src/xz/file_io.c:1008
#: src/xz/file_io.c:944 src/xz/file_io.c:1170
#, c-format
msgid "%s: Seeking failed when trying to create a sparse file: %s"
msgstr "%s: Zmiana pozycji nie powiodła się podczas próby utworzenia pliku rzadkiego: %s"
#: src/xz/file_io.c:883
#: src/xz/file_io.c:1039
#, c-format
msgid "%s: Read error: %s"
msgstr "%s: Błąd odczytu: %s"
#: src/xz/file_io.c:906
#: src/xz/file_io.c:1059
#, c-format
msgid "%s: Error seeking the file: %s"
msgstr "%s: Błąd podczas zmiany pozycji w pliku: %s"
#: src/xz/file_io.c:916
#: src/xz/file_io.c:1069
#, c-format
msgid "%s: Unexpected end of file"
msgstr "%s: Nieoczekiwany koniec pliku"
#: src/xz/file_io.c:966
#: src/xz/file_io.c:1128
#, c-format
msgid "%s: Write error: %s"
msgstr "%s: Błąd zapisu: %s"
#: src/xz/hardware.c:101
#: src/xz/hardware.c:107
msgid "Disabled"
msgstr "Wyłączony"
#. TRANSLATORS: Test with "xz --info-memory" to see if
#. the alignment looks nice.
#: src/xz/hardware.c:120
#: src/xz/hardware.c:126
msgid "Total amount of physical memory (RAM): "
msgstr "Całkowita ilość pamięci fizycznej (RAM): "
#: src/xz/hardware.c:122
#: src/xz/hardware.c:128
msgid "Memory usage limit for compression: "
msgstr "Limit użycia pamięci dla kompresji: "
#: src/xz/hardware.c:124
#: src/xz/hardware.c:130
msgid "Memory usage limit for decompression: "
msgstr "Limit użycia pamięci dla dekompresji: "
@@ -275,41 +332,41 @@ msgstr "%s: Za mały na poprawny plik .xz"
#. to Ratio, the columns are right aligned. Check and Filename
#. are left aligned. If you need longer words, it's OK to
#. use two lines here. Test with "xz -l foo.xz".
#: src/xz/list.c:645
#: src/xz/list.c:671
msgid "Strms Blocks Compressed Uncompressed Ratio Check Filename"
msgstr "Strum. Bloki Spakowany Rozpakowany Wsp. Kontrola Nazwa pliku"
#: src/xz/list.c:685
#: src/xz/list.c:711
#, c-format
msgid " Streams: %s\n"
msgstr " Strumienie: %s\n"
#: src/xz/list.c:687
#: src/xz/list.c:713
#, c-format
msgid " Blocks: %s\n"
msgstr " Bloki: %s\n"
#: src/xz/list.c:689
#: src/xz/list.c:715
#, c-format
msgid " Compressed size: %s\n"
msgstr " Rozmiar spakowany: %s\n"
#: src/xz/list.c:692
#: src/xz/list.c:718
#, c-format
msgid " Uncompressed size: %s\n"
msgstr " Rozmiar rozpakowany: %s\n"
#: src/xz/list.c:695
#: src/xz/list.c:721
#, c-format
msgid " Ratio: %s\n"
msgstr " Współczynnik: %s\n"
#: src/xz/list.c:697
#: src/xz/list.c:723
#, c-format
msgid " Check: %s\n"
msgstr " Kontrola spójności: %s\n"
#: src/xz/list.c:698
#: src/xz/list.c:724
#, c-format
msgid " Stream padding: %s\n"
msgstr " Wyrównanie strumienia: %s\n"
@@ -317,7 +374,7 @@ msgstr " Wyrównanie strumienia: %s\n"
#. TRANSLATORS: The second line is column headings. All except
#. Check are right aligned; Check is left aligned. Test with
#. "xz -lv foo.xz".
#: src/xz/list.c:726
#: src/xz/list.c:752
msgid ""
" Streams:\n"
" Stream Blocks CompOffset UncompOffset CompSize UncompSize Ratio Check Padding"
@@ -327,7 +384,7 @@ msgstr ""
#. TRANSLATORS: The second line is column headings. All
#. except Check are right aligned; Check is left aligned.
#: src/xz/list.c:781
#: src/xz/list.c:807
#, c-format
msgid ""
" Blocks:\n"
@@ -343,37 +400,37 @@ msgstr ""
#. are right aligned. %*s is replaced with 0-120
#. spaces to make the CheckVal column wide enough.
#. Test with "xz -lvv foo.xz".
#: src/xz/list.c:793
#: src/xz/list.c:819
#, c-format
msgid " CheckVal %*s Header Flags CompSize MemUsage Filters"
msgstr " S.kontr. %*sNagłówek Flagi Rozm. spak. Uż.pamięci Filtry"
#: src/xz/list.c:871 src/xz/list.c:1046
#: src/xz/list.c:897 src/xz/list.c:1072
#, c-format
msgid " Memory needed: %s MiB\n"
msgstr " Wymagana pamięć: %s MiB\n"
#: src/xz/list.c:873 src/xz/list.c:1048
#: src/xz/list.c:899 src/xz/list.c:1074
#, c-format
msgid " Sizes in headers: %s\n"
msgstr " Rozmiar w nagłówkach: %s\n"
#: src/xz/list.c:874 src/xz/list.c:1049
#: src/xz/list.c:900 src/xz/list.c:1075
msgid "Yes"
msgstr "Tak"
#: src/xz/list.c:874 src/xz/list.c:1049
#: src/xz/list.c:900 src/xz/list.c:1075
msgid "No"
msgstr "Nie"
#: src/xz/list.c:875 src/xz/list.c:1050
#: src/xz/list.c:901 src/xz/list.c:1076
#, c-format
msgid " Minimum XZ Utils version: %s\n"
msgstr " Minimalna wersja XZ Utils: %s\n"
#. TRANSLATORS: %s is an integer. Only the plural form of this
#. message is used (e.g. "2 files"). Test with "xz -l foo.xz bar.xz".
#: src/xz/list.c:1025
#: src/xz/list.c:1051
#, c-format
msgid "%s file\n"
msgid_plural "%s files\n"
@@ -381,20 +438,20 @@ msgstr[0] "%s plik\n"
msgstr[1] "%s pliki\n"
msgstr[2] "%s plików\n"
#: src/xz/list.c:1038
#: src/xz/list.c:1064
msgid "Totals:"
msgstr "Sumarycznie:"
#: src/xz/list.c:1039
#: src/xz/list.c:1065
#, c-format
msgid " Number of files: %s\n"
msgstr " Liczba plików: %s\n"
#: src/xz/list.c:1114
#: src/xz/list.c:1140
msgid "--list works only on .xz files (--format=xz or --format=auto)"
msgstr "--list działa tylko z plikami .xz (--format=xz lub --format=auto)"
#: src/xz/list.c:1120
#: src/xz/list.c:1146
msgid "--list does not support reading from standard input"
msgstr "--list nie obsługuje odczytu ze standardowego wejścia"
@@ -425,68 +482,68 @@ msgstr "Nie można odczytać danych ze standardowego wejścia przy czytaniu nazw
#. of the line in messages. Usually it becomes "xz: ".
#. This is a translatable string because French needs
#. a space before a colon.
#: src/xz/message.c:733
#: src/xz/message.c:713
#, c-format
msgid "%s: "
msgstr "%s: "
#: src/xz/message.c:796 src/xz/message.c:846
#: src/xz/message.c:776 src/xz/message.c:826
msgid "Internal error (bug)"
msgstr "Błąd wewnętrzny"
#: src/xz/message.c:803
#: src/xz/message.c:783
msgid "Cannot establish signal handlers"
msgstr "Nie można ustawić obsługi sygnałów"
#: src/xz/message.c:812
#: src/xz/message.c:792
msgid "No integrity check; not verifying file integrity"
msgstr "Brak kontroli spójności; poprawność plików nie będzie weryfikowana"
#: src/xz/message.c:815
#: src/xz/message.c:795
msgid "Unsupported type of integrity check; not verifying file integrity"
msgstr "Nieobsługiwany typ kontroli spójności; poprawność plików nie będzie weryfikowana"
#: src/xz/message.c:822
#: src/xz/message.c:802
msgid "Memory usage limit reached"
msgstr "Osiągnięto limit użycia pamięci"
#: src/xz/message.c:825
#: src/xz/message.c:805
msgid "File format not recognized"
msgstr "Nie rozpoznany format pliku"
#: src/xz/message.c:828
#: src/xz/message.c:808
msgid "Unsupported options"
msgstr "Nieobsługiwane opcje"
#: src/xz/message.c:831
#: src/xz/message.c:811
msgid "Compressed data is corrupt"
msgstr "Dane skompresowane są uszkodzone"
#: src/xz/message.c:834
#: src/xz/message.c:814
msgid "Unexpected end of input"
msgstr "Nieoczekiwany koniec wejścia"
#: src/xz/message.c:867
#: src/xz/message.c:847
#, c-format
msgid "%s MiB of memory is required. The limiter is disabled."
msgstr "Wymagane jest %s MiB pamięci. Limit jest wyłączony."
#: src/xz/message.c:895
#: src/xz/message.c:875
#, c-format
msgid "%s MiB of memory is required. The limit is %s."
msgstr "Wymagane jest %s MiB pamięci. Limit to %s."
#: src/xz/message.c:1062
#: src/xz/message.c:1042
#, c-format
msgid "%s: Filter chain: %s\n"
msgstr "%s: Łańcuch filtrów: %s\n"
#: src/xz/message.c:1072
#: src/xz/message.c:1052
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Polecenie `%s --help' pokaże więcej informacji."
#: src/xz/message.c:1098
#: src/xz/message.c:1078
#, c-format
msgid ""
"Usage: %s [OPTION]... [FILE]...\n"
@@ -497,17 +554,17 @@ msgstr ""
"Kompresja lub dekompresja PLIKÓW w formacie .xz.\n"
"\n"
#: src/xz/message.c:1105
#: src/xz/message.c:1085
msgid "Mandatory arguments to long options are mandatory for short options too.\n"
msgstr ""
"Argumenty obowiązkowe dla opcji długich są obowiązkowe również dla opcji\n"
"krótkich.\n"
#: src/xz/message.c:1109
#: src/xz/message.c:1089
msgid " Operation mode:\n"
msgstr " Tryb pracy:\n"
#: src/xz/message.c:1112
#: src/xz/message.c:1092
msgid ""
" -z, --compress force compression\n"
" -d, --decompress force decompression\n"
@@ -519,7 +576,7 @@ msgstr ""
" -t, --test sprawdzenie spójności plików skompresowanych\n"
" -l, --list wypisanie informacji o plikach .xz"
#: src/xz/message.c:1118
#: src/xz/message.c:1098
msgid ""
"\n"
" Operation modifiers:\n"
@@ -527,7 +584,7 @@ msgstr ""
"\n"
" Modyfikatory operacji:\n"
#: src/xz/message.c:1121
#: src/xz/message.c:1101
msgid ""
" -k, --keep keep (don't delete) input files\n"
" -f, --force force overwrite of output file and (de)compress links\n"
@@ -537,7 +594,7 @@ msgstr ""
" -f, --force nadpisywanie plików wyjściowych i (de)kompresja dowiązań\n"
" -c, --stdout zapis na standardowe wyjście, nieusuwanie plików wej."
#: src/xz/message.c:1127
#: src/xz/message.c:1107
msgid ""
" --single-stream decompress only the first stream, and silently\n"
" ignore possible remaining input data"
@@ -545,7 +602,7 @@ msgstr ""
" --single-stream dekompresja tylko pierwszego strumienia, ciche\n"
" zignorowanie pozostałych danych wejściowych"
#: src/xz/message.c:1130
#: src/xz/message.c:1110
msgid ""
" --no-sparse do not create sparse files when decompressing\n"
" -S, --suffix=.SUF use the suffix `.SUF' on compressed files\n"
@@ -561,7 +618,7 @@ msgstr ""
" wejścia; muszą być zakończone znakiem nowej linii\n"
" --files0[=PLIK] podobnie do --files, ale znakiem kończącym musi być NUL"
#: src/xz/message.c:1139
#: src/xz/message.c:1119
msgid ""
"\n"
" Basic file format and compression options:\n"
@@ -569,7 +626,7 @@ msgstr ""
"\n"
" Podstawowe opcje formatu pliku i kompresji:\n"
#: src/xz/message.c:1141
#: src/xz/message.c:1121
msgid ""
" -F, --format=FMT file format to encode or decode; possible values are\n"
" `auto' (default), `xz', `lzma', and `raw'\n"
@@ -581,7 +638,11 @@ msgstr ""
" -C, --check=TEST typ kontroli spójności: `none' (ostrożnie!),\n"
" `crc32', `crc64' (domyślny) lub `sha256'"
#: src/xz/message.c:1148
#: src/xz/message.c:1126
msgid " --ignore-check don't verify the integrity check when decompressing"
msgstr " --ignore-check bez kontroli sprawdzania integralności przy dekompresji"
#: src/xz/message.c:1130
msgid ""
" -0 ... -9 compression preset; default is 6; take compressor *and*\n"
" decompressor memory usage into account before using 7-9!"
@@ -590,7 +651,7 @@ msgstr ""
" użyciem wartości 7-9 należy wziąć pod uwagę wykorzystanie\n"
" pamięci przy kompresji *oraz* dekompresji!"
#: src/xz/message.c:1152
#: src/xz/message.c:1134
msgid ""
" -e, --extreme try to improve compression ratio by using more CPU time;\n"
" does not affect decompressor memory requirements"
@@ -599,17 +660,48 @@ msgstr ""
" ilości czasu procesora; nie wpływa na wymagania\n"
" pamięciowe dekompresora"
#: src/xz/message.c:1157
#: src/xz/message.c:1138
msgid ""
" -T, --threads=NUM use at most NUM threads; the default is 1; set to 0\n"
" to use as many threads as there are processor cores"
msgstr ""
" -T, --threads=ILE użycie maksymalnie ILU wątków; domyślnie 1; 0 oznacza\n"
" tyle, ile jest rdzeni procesorów"
#: src/xz/message.c:1143
msgid ""
" --block-size=SIZE\n"
" when compressing to the .xz format, start a new block\n"
" after every SIZE bytes of input; 0=disabled (default)"
" start a new .xz block after every SIZE bytes of input;\n"
" use this to set the block size for threaded compression"
msgstr ""
" --block-size=LICZBA\n"
" przy kompresji do formatu .xz: rozpoczynanie nowego bloku\n"
" po każdej LICZBIE bajtów wejścia; 0=wyłączone (domyślne)"
" --block-size=ROZMIAR\n"
" rozpoczęcie nowego bloku .xz co ROZMIAR bajtów wejścia;\n"
" opcja służy do ustawienia rozmiaru bloku dla kompresji\n"
" wielowątkowej"
#: src/xz/message.c:1161
#: src/xz/message.c:1147
msgid ""
" --block-list=SIZES\n"
" start a new .xz block after the given comma-separated\n"
" intervals of uncompressed data"
msgstr ""
" --block-list=ROZMIARY\n"
" rozpoczęcie nowego bloku .xz po rozdzielonych przecinkiem\n"
" przedziałach danych nieskompresowanych"
#: src/xz/message.c:1151
msgid ""
" --flush-timeout=TIMEOUT\n"
" when compressing, if more than TIMEOUT milliseconds has\n"
" passed since the previous flush and reading more input\n"
" would block, all pending data is flushed out"
msgstr ""
" --flush-timeout=CZAS\n"
" przy kompresji, jeśli minęło więcej niż CZAS milisekund\n"
" ostatniegu zapisu bloku, a odczyt kolejnych danych byłby\n"
" blokujący, wszystkie gotowe dane są zapisywane"
#: src/xz/message.c:1157
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
@@ -625,7 +717,7 @@ msgstr ""
" dekompresji lub obu; LIMIT jest w bajtach, % RAM lub 0\n"
" dla limitów domyślnych"
#: src/xz/message.c:1168
#: src/xz/message.c:1164
msgid ""
" --no-adjust if compression settings exceed the memory usage limit,\n"
" give an error instead of adjusting the settings downwards"
@@ -634,7 +726,7 @@ msgstr ""
" pamięci, zostanie zgłoszony błąd zamiast zmniejszania\n"
" ustawień"
#: src/xz/message.c:1174
#: src/xz/message.c:1170
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
@@ -642,7 +734,7 @@ msgstr ""
"\n"
" Łańcuch własnych filtrów do kompresji (alternatywa do używania -0 .. -9):"
#: src/xz/message.c:1183
#: src/xz/message.c:1179
msgid ""
"\n"
" --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero or\n"
@@ -671,7 +763,7 @@ msgstr ""
" mf=NAZWA dopasowywacz (hc3, hc4, bt2, bt3, bt4; bt4)\n"
" depth=ILE maks. głębokość szukania; 0=auto (domyślne)"
#: src/xz/message.c:1198
#: src/xz/message.c:1194
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
@@ -693,7 +785,7 @@ msgstr ""
" Poprawne OPCJE dla wszystkich filtrów BCJ:\n"
" start=ILE offset początku konwersji (domyślnie=0)"
#: src/xz/message.c:1210
#: src/xz/message.c:1206
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
@@ -705,7 +797,7 @@ msgstr ""
" dist=ILE odległość między bajtami odejmowanymi od\n"
" siebie (1-256; 1)"
#: src/xz/message.c:1218
#: src/xz/message.c:1214
msgid ""
"\n"
" Other options:\n"
@@ -713,7 +805,7 @@ msgstr ""
"\n"
" Inne opcje:\n"
#: src/xz/message.c:1221
#: src/xz/message.c:1217
msgid ""
" -q, --quiet suppress warnings; specify twice to suppress errors too\n"
" -v, --verbose be verbose; specify twice for even more verbose"
@@ -721,15 +813,15 @@ msgstr ""
" -q, --quiet pominięcie ostrzeżeń; dwukrotne podanie pomija też błędy\n"
" -v, --verbose więcej informacji; dwukrotne podanie to jeszcze więcej"
#: src/xz/message.c:1226
#: src/xz/message.c:1222
msgid " -Q, --no-warn make warnings not affect the exit status"
msgstr " -Q, --no-warn ostrzeżenia nie mają wpływu na status zakończenia"
#: src/xz/message.c:1228
#: src/xz/message.c:1224
msgid " --robot use machine-parsable messages (useful for scripts)"
msgstr " --robot komunikaty w formacie dla maszyny (do skryptów)"
#: src/xz/message.c:1231
#: src/xz/message.c:1227
msgid ""
" --info-memory display the total amount of RAM and the currently active\n"
" memory usage limits, and exit"
@@ -737,7 +829,7 @@ msgstr ""
" --info-memory wyświetlenie całkowitej ilości pamięci RAM oraz aktualnie\n"
" aktywnych limitów pamięci i zakończenie pracy"
#: src/xz/message.c:1234
#: src/xz/message.c:1230
msgid ""
" -h, --help display the short help (lists only the basic options)\n"
" -H, --long-help display this long help and exit"
@@ -745,7 +837,7 @@ msgstr ""
" -h, --help wyświetlenie krótkiego opisu (tylko podstawowe opcje)\n"
" -H, --long-help wyświetlenie tego długiego opisu i zakończenie"
#: src/xz/message.c:1238
#: src/xz/message.c:1234
msgid ""
" -h, --help display this short help and exit\n"
" -H, --long-help display the long help (lists also the advanced options)"
@@ -753,11 +845,11 @@ msgstr ""
" -h, --help wyświetlenie tego krótkiego opisu i zakończenie\n"
" -H, --long-help wyświetlenie długiego opisu (także opcje zaawansowane)"
#: src/xz/message.c:1243
#: src/xz/message.c:1239
msgid " -V, --version display the version number and exit"
msgstr " -V, --version wyświetlenie informacji o wersji i zakończenie"
#: src/xz/message.c:1245
#: src/xz/message.c:1241
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
@@ -769,7 +861,7 @@ msgstr ""
#. for this package. Please add _another line_ saying
#. "Report translation bugs to <...>\n" with the email or WWW
#. address for translation bugs. Thanks.
#: src/xz/message.c:1251
#: src/xz/message.c:1247
#, c-format
msgid "Report bugs to <%s> (in English or Finnish).\n"
msgstr ""
@@ -778,11 +870,15 @@ msgstr ""
"Błędy w tłumaczeniu prosimy zgłaszać na adres\n"
"<translation-team-pl@lists.sourceforge.net>.\n"
#: src/xz/message.c:1253
#: src/xz/message.c:1249
#, c-format
msgid "%s home page: <%s>\n"
msgstr "Strona domowa %s: <%s>\n"
#: src/xz/message.c:1253
msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."
msgstr "TA WERSJA JEST ROZWOJOWA, NIE PRZEZNACZONA DO UŻYTKU PRODUKCYJNEGO."
#: src/xz/options.c:86
#, c-format
msgid "%s: Options must be `name=value' pairs separated with commas"
@@ -832,34 +928,34 @@ msgstr "%s: Plik już ma rozszerzenie `%s', pominięto"
msgid "%s: Invalid filename suffix"
msgstr "%s: Błędne rozszerzenie nazwy pliku"
#: src/xz/util.c:61
#: src/xz/util.c:71
#, c-format
msgid "%s: Value is not a non-negative decimal integer"
msgstr "%s: Wartość nie jest nieujemną liczbą całkowitą"
#: src/xz/util.c:103
#: src/xz/util.c:113
#, c-format
msgid "%s: Invalid multiplier suffix"
msgstr "%s: Błędny przyrostek mnożnika"
#: src/xz/util.c:105
#: src/xz/util.c:115
msgid "Valid suffixes are `KiB' (2^10), `MiB' (2^20), and `GiB' (2^30)."
msgstr "Poprawne przyrostki to `KiB' (2^10), `MiB' (2^20) i `GiB' (2^30)."
#: src/xz/util.c:122
#: src/xz/util.c:132
#, c-format
msgid "Value of the option `%s' must be in the range [%<PRIu64>, %<PRIu64>]"
msgstr "Wartość opcji `%s' musi być w przedziale [%<PRIu64>, %<PRIu64>]"
#: src/xz/util.c:247
#: src/xz/util.c:257
msgid "Empty filename, skipping"
msgstr "Pusta nazwa pliku, pominięto"
#: src/xz/util.c:261
#: src/xz/util.c:271
msgid "Compressed data cannot be read from a terminal"
msgstr "Dane skompresowane nie mogą być czytane z terminala"
#: src/xz/util.c:274
#: src/xz/util.c:284
msgid "Compressed data cannot be written to a terminal"
msgstr "Dane skompresowane nie mogą być zapisywane na terminal"

136
po/vi.po
View File

@@ -5,10 +5,10 @@
#
msgid ""
msgstr ""
"Project-Id-Version: xz 5.1.3alpha\n"
"Project-Id-Version: xz 5.1.4beta\n"
"Report-Msgid-Bugs-To: lasse.collin@tukaani.org\n"
"POT-Creation-Date: 2014-06-23 14:48+0700\n"
"PO-Revision-Date: 2014-06-30 08:31+0700\n"
"POT-Creation-Date: 2014-09-25 08:57+0700\n"
"PO-Revision-Date: 2014-09-25 09:06+0700\n"
"Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
"Language: vi\n"
@@ -18,35 +18,35 @@ msgstr ""
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Poedit-Basepath: ../\n"
#: src/xz/args.c:62
#: src/xz/args.c:63
#, c-format
msgid "%s: Invalid argument to --block-list"
msgstr "%s: Đối số cho --block-list không hợp lệ"
#: src/xz/args.c:72
#: src/xz/args.c:73
#, c-format
msgid "%s: Too many arguments to --block-list"
msgstr "%s: Quá nhiều đối số cho --block-list"
#: src/xz/args.c:101
#: src/xz/args.c:102
msgid "0 can only be used as the last element in --block-list"
msgstr "0 chỉ có thể dùng như là phần tử cuối trong --block-list"
#: src/xz/args.c:403
#: src/xz/args.c:406
#, c-format
msgid "%s: Unknown file format type"
msgstr "%s: Không hiểu kiểu định dạng tập tin"
#: src/xz/args.c:426 src/xz/args.c:434
#: src/xz/args.c:429 src/xz/args.c:437
#, c-format
msgid "%s: Unsupported integrity check type"
msgstr "%s: Không hỗ trợ kiểu kiểm tra toàn vẹn"
#: src/xz/args.c:466
#: src/xz/args.c:473
msgid "Only one file can be specified with `--files' or `--files0'."
msgstr "Chỉ được đưa ra một tập tin cho “--files” hay “--files0”."
#: src/xz/args.c:534
#: src/xz/args.c:541
#, c-format
msgid "The environment variable %s contains too many arguments"
msgstr "Biến môi trường %s chứa quá nhiều đối số"
@@ -61,7 +61,7 @@ msgstr "Mức giới hạn dùng bộ nhớ là quá thấp cho việc cài đ
#: src/xz/coder.c:159
msgid "Using a preset in raw mode is discouraged."
msgstr "Dùng mức nén là trong chế độ raw là ngớ ngẩn."
msgstr "Dùng hiện tại trong chế độ thô là ngớ ngẩn."
#: src/xz/coder.c:161
msgid "The exact options of the presets may vary between software versions."
@@ -195,7 +195,7 @@ msgstr "%s: Tập tin có đặt bít setuid hoặc setgid nên bỏ qua"
#: src/xz/file_io.c:581
#, c-format
msgid "%s: File has sticky bit set, skipping"
msgstr "%s: Tập tin có đặt bít sticky nên bỏ qua"
msgstr "%s: Tập tin có bít sticky nên bỏ qua"
#: src/xz/file_io.c:588
#, c-format
@@ -394,8 +394,8 @@ msgid ""
"UncompSize Ratio Check Padding"
msgstr ""
" Luồng dữ liệu:\n"
" Luồng Khối BùNén BùGiảiNén CỡNén "
" CỡGiảiNén TỷLệ Ktra Đệm"
" Luồng Khối BùNén BùGiảiNén CỡNén "
"CỡGiảiNén TỷLệ Ktra Đệm"
#. TRANSLATORS: The second line is column headings. All
#. except Check are right aligned; Check is left aligned.
@@ -407,8 +407,8 @@ msgid ""
"UncompSize Ratio Check"
msgstr ""
" Khối:\n"
" Luồng Khối BùNén BùGiảiNén CỡTổng "
" CỡGiảiNén TỷLệ Ktra"
" Luồng Khối BùNén BùGiảiNén CỡTổng "
"CỡGiảiNén TỷLệ Ktra"
#. TRANSLATORS: These are additional column headings
#. for the most verbose listing mode. CheckVal
@@ -568,7 +568,7 @@ msgstr "%s: Móc xích lọc: %s\n"
#: src/xz/message.c:1052
#, c-format
msgid "Try `%s --help' for more information."
msgstr "Hãy thử lệnh “%s --help” để xem thông tin thêm."
msgstr "Hãy chạy lệnh “%s --help” để xem thông tin thêm."
#: src/xz/message.c:1078
#, c-format
@@ -578,7 +578,7 @@ msgid ""
"\n"
msgstr ""
"Cách dùng: %s [TÙY CHỌN]... [TẬP TIN]...\n"
"Nén hoặc giải nén các TẬP-TIN có định dạng .xz.\n"
"Nén hoặc giải nén các TẬP TIN có định dạng .xz.\n"
"\n"
#: src/xz/message.c:1085
@@ -668,7 +668,12 @@ msgstr ""
" -C, --check=KIỂM kiểu kiểm tra toàn vẹn: “none” (thận trọng khi dùng),\n"
" “crc32”, “crc64” (mặc định), hay “sha256”"
#: src/xz/message.c:1128
#: src/xz/message.c:1126
msgid ""
" --ignore-check don't verify the integrity check when decompressing"
msgstr " --ignore-check không thẩm tra tính toàn vẹn khi giải nén"
#: src/xz/message.c:1130
msgid ""
" -0 ... -9 compression preset; default is 6; take compressor "
"*and*\n"
@@ -679,7 +684,7 @@ msgstr ""
"nén\n"
" và giải nén, nên tính toán trước khi dùng 7-9!"
#: src/xz/message.c:1132
#: src/xz/message.c:1134
msgid ""
" -e, --extreme try to improve compression ratio by using more CPU "
"time;\n"
@@ -689,36 +694,52 @@ msgstr ""
"hơn;\n"
" nhưng không yêu cần nhiều bộ nhớ khi giải nén"
#: src/xz/message.c:1136
#: src/xz/message.c:1138
msgid ""
" -T, --threads=NUM use at most NUM threads; the default is 1; set to 0\n"
" to use the number of processor cores"
" to use as many threads as there are processor cores"
msgstr ""
" -T, --threads=SỐ dùng tối đa là SỐ tuyến trình; mặc định là 1; đặt "
"thành 0\n"
" để dùng số lượng bằng số lõi vi xử lý"
" -T, --threads=SỐ dùng tối đa là SỐ tuyến trình; mặc định là 1; đặt\n"
" thành 0 để dùng số lượng bằng số lõi vi xử lý"
#: src/xz/message.c:1142
#: src/xz/message.c:1143
msgid ""
" --block-size=SIZE\n"
" when compressing to the .xz format, start a new block\n"
" after every SIZE bytes of input; 0=disabled (default)"
" start a new .xz block after every SIZE bytes of "
"input;\n"
" use this to set the block size for threaded compression"
msgstr ""
" --block-size=CỠ\n"
" khi nén thành định dạng .xz, bắt đầu khối mới\n"
" sau mỗi SỐ byte đầu vào; 0=tắt (mặc định)"
" bắt đầu một khối .xz mới sau mỗi CỠ byte của đầu vào;\n"
" dùng tùy chọn này để đặt cỡ khối cho nén tuyến trình"
#: src/xz/message.c:1147
msgid ""
" --block-list=SIZES\n"
" when compressing to the .xz format, start a new block\n"
" after the given intervals of uncompressed data"
" start a new .xz block after the given comma-separated\n"
" intervals of uncompressed data"
msgstr ""
" --block-list=CỠ\n"
" khi nén thành định dạng .xz, bắt đầu khối mới\n"
" sau các nhịp dữ liệu chưa nén đưa ra"
" bắt đầu một khối .xz mới sau một danh sách ngăn\n"
" cách bằng dấu phẩy nhịp dữ của dữ liệu chưa nén"
#: src/xz/message.c:1151
msgid ""
" --flush-timeout=TIMEOUT\n"
" when compressing, if more than TIMEOUT milliseconds "
"has\n"
" passed since the previous flush and reading more "
"input\n"
" would block, all pending data is flushed out"
msgstr ""
" --flush-timeout=THỜI_GIAN_CHỜ\n"
" khi đang nén, nếu đã trải qua hơn THỜI_GIAN_CHỜ milli-"
"giây\n"
" kể từ lần đẩy dữ liệu lên đĩa trước đó và đang đọc "
"thêm\n"
" khối nữa, mọi dữ liệu đang chờ sẽ được ghi lên đĩa"
#: src/xz/message.c:1157
#, no-c-format
msgid ""
" --memlimit-compress=LIMIT\n"
@@ -735,7 +756,7 @@ msgstr ""
" hoặc cả hai; GIỚI_HẠN có đơn vị là byte, % của RAM,\n"
" hay 0 cho mặc định"
#: src/xz/message.c:1158
#: src/xz/message.c:1164
msgid ""
" --no-adjust if compression settings exceed the memory usage "
"limit,\n"
@@ -745,7 +766,7 @@ msgstr ""
" --no-adjust nếu các cài đặt nén vượt quá giới hạn dùng bộ nhớ,\n"
" đưa ra một lỗi thay vì sửa đổi các cài đặt xuống"
#: src/xz/message.c:1164
#: src/xz/message.c:1170
msgid ""
"\n"
" Custom filter chain for compression (alternative for using presets):"
@@ -753,7 +774,7 @@ msgstr ""
"\n"
" Móc xích lọc tùy chỉnh cho nén (thay cho việc dùng chỉnh trước):"
#: src/xz/message.c:1173
#: src/xz/message.c:1179
msgid ""
"\n"
" --lzma1[=OPTS] LZMA1 or LZMA2; OPTS is a comma-separated list of zero "
@@ -788,7 +809,7 @@ msgstr ""
" depth=SỐ mức sâu tìm kiếm tối đa; 0=tự động (mặc "
"định)"
#: src/xz/message.c:1188
#: src/xz/message.c:1194
msgid ""
"\n"
" --x86[=OPTS] x86 BCJ filter (32-bit and 64-bit)\n"
@@ -811,7 +832,7 @@ msgstr ""
" start=SỐ khoảng bù khởi đầu cho chuyển đổi (mặc "
"định=0)"
#: src/xz/message.c:1200
#: src/xz/message.c:1206
msgid ""
"\n"
" --delta[=OPTS] Delta filter; valid OPTS (valid values; default):\n"
@@ -824,7 +845,7 @@ msgstr ""
" dist=SỐ khoảng cách giữa các byte được trừ từ\n"
" những cái khác (1-256; 1)"
#: src/xz/message.c:1208
#: src/xz/message.c:1214
msgid ""
"\n"
" Other options:\n"
@@ -832,7 +853,7 @@ msgstr ""
"\n"
" Tùy chọn khác:\n"
#: src/xz/message.c:1211
#: src/xz/message.c:1217
msgid ""
" -q, --quiet suppress warnings; specify twice to suppress errors "
"too\n"
@@ -842,20 +863,20 @@ msgstr ""
" chỉ định hai lần nến bạn muốn chặn cả báo lỗi\n"
" -v, --verbose thông báo chi tiết; dùng hai lần nếu muốn chi tiết hơn"
#: src/xz/message.c:1216
#: src/xz/message.c:1222
msgid " -Q, --no-warn make warnings not affect the exit status"
msgstr ""
" -Q, --no-warn làm cho các cảnh báo không ảnh hưởng đến trạng thái "
"thoát"
#: src/xz/message.c:1218
#: src/xz/message.c:1224
msgid ""
" --robot use machine-parsable messages (useful for scripts)"
msgstr ""
" --robot dùng các thông điệp máy có thể phân tích\n"
" (hữu dụng với scripts)"
#: src/xz/message.c:1221
#: src/xz/message.c:1227
msgid ""
" --info-memory display the total amount of RAM and the currently "
"active\n"
@@ -864,7 +885,7 @@ msgstr ""
" --info-memory hiển thị tổng lượng RAM và mức giới hạn tiêu dùng\n"
" bộ nhớ hiện tại, rồi thoát"
#: src/xz/message.c:1224
#: src/xz/message.c:1230
msgid ""
" -h, --help display the short help (lists only the basic options)\n"
" -H, --long-help display this long help and exit"
@@ -873,7 +894,7 @@ msgstr ""
" (chỉ liệt kê các tùy chọn cơ bản)\n"
" -H, --long-help hiển thị trợ giúp đầy đủ rồi thoát"
#: src/xz/message.c:1228
#: src/xz/message.c:1234
msgid ""
" -h, --help display this short help and exit\n"
" -H, --long-help display the long help (lists also the advanced options)"
@@ -882,11 +903,11 @@ msgstr ""
" -H, --long-help hiển thị trợ giúp đầy đủ\n"
" (liệt kê cả những tùy chọn cấp cao)"
#: src/xz/message.c:1233
#: src/xz/message.c:1239
msgid " -V, --version display the version number and exit"
msgstr " -V, --version hiển thị số phiên bản và thoát"
#: src/xz/message.c:1235
#: src/xz/message.c:1241
msgid ""
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
@@ -898,19 +919,19 @@ msgstr ""
#. for this package. Please add _another line_ saying
#. "Report translation bugs to <...>\n" with the email or WWW
#. address for translation bugs. Thanks.
#: src/xz/message.c:1241
#: src/xz/message.c:1247
#, c-format
msgid "Report bugs to <%s> (in English or Finnish).\n"
msgstr ""
"Hãy báo cáo lỗi cho <%s> (bằng tiếng Anh hoặc Phần Lan).\n"
"Thông báo lỗi dịch cho: <http://translationproject.org/team/vi.html>.\n"
#: src/xz/message.c:1243
#: src/xz/message.c:1249
#, c-format
msgid "%s home page: <%s>\n"
msgstr "Trang chủ %s: <%s>.\n"
#: src/xz/message.c:1247
#: src/xz/message.c:1253
msgid "THIS IS A DEVELOPMENT VERSION NOT INTENDED FOR PRODUCTION USE."
msgstr "ĐÂY LÀ PHIÊN BẢN PHÁT TRIỂN VÀ NÓ KHÔNG PHÙ HỢP VỚI MỤC ĐÍCH SẢN XUẤT."
@@ -1004,4 +1025,15 @@ msgstr "Gặp lỗi khi ghi dữ liệu vào đầu ra tiêu chuẩn"
#: src/common/tuklib_exit.c:42
msgid "Unknown error"
msgstr "Lỗi không rõ"
msgstr "Lỗi chưa biết"
#~ msgid ""
#~ " --block-size=SIZE\n"
#~ " when compressing to the .xz format, start a new "
#~ "block\n"
#~ " after every SIZE bytes of input; 0=disabled "
#~ "(default)"
#~ msgstr ""
#~ " --block-size=CỠ\n"
#~ " khi nén thành định dạng .xz, bắt đầu khối mới\n"
#~ " sau mỗi SỐ byte đầu vào; 0=tắt (mặc định)"

View File

@@ -19,4 +19,24 @@ if COND_SCRIPTS
SUBDIRS += scripts
endif
EXTRA_DIST = common
EXTRA_DIST = \
common/common_w32res.rc \
common/mythread.h \
common/sysdefs.h \
common/tuklib_common.h \
common/tuklib_config.h \
common/tuklib_cpucores.c \
common/tuklib_cpucores.h \
common/tuklib_exit.c \
common/tuklib_exit.h \
common/tuklib_gettext.h \
common/tuklib_integer.h \
common/tuklib_mbstr_fw.c \
common/tuklib_mbstr.h \
common/tuklib_mbstr_width.c \
common/tuklib_open_stdxxx.c \
common/tuklib_open_stdxxx.h \
common/tuklib_physmem.c \
common/tuklib_physmem.h \
common/tuklib_progname.c \
common/tuklib_progname.h

View File

@@ -17,7 +17,7 @@
#define MY_VERSION LZMA_VERSION_MAJOR,LZMA_VERSION_MINOR,LZMA_VERSION_PATCH,MY_BUILD
#define MY_FILENAME MY_NAME MY_SUFFIX
#define MY_COMPANY "The Tukaani Project <http://tukaani.org/>"
#define MY_COMPANY "The Tukaani Project <https://tukaani.org/>"
#define MY_PRODUCT PACKAGE_NAME " <" PACKAGE_URL ">"
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

View File

@@ -81,6 +81,8 @@ do { \
#if !(defined(_WIN32) && !defined(__CYGWIN__))
// Use sigprocmask() to set the signal mask in single-threaded programs.
#include <signal.h>
static inline void
mythread_sigmask(int how, const sigset_t *restrict set,
sigset_t *restrict oset)

View File

@@ -18,6 +18,15 @@
# endif
# include <windows.h>
// glibc >= 2.9
#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
# include <sched.h>
// FreeBSD
#elif defined(TUKLIB_CPUCORES_CPUSET)
# include <sys/param.h>
# include <sys/cpuset.h>
#elif defined(TUKLIB_CPUCORES_SYSCTL)
# ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
@@ -44,6 +53,24 @@ tuklib_cpucores(void)
GetSystemInfo(&sysinfo);
ret = sysinfo.dwNumberOfProcessors;
#elif defined(TUKLIB_CPUCORES_SCHED_GETAFFINITY)
cpu_set_t cpu_mask;
if (sched_getaffinity(0, sizeof(cpu_mask), &cpu_mask) == 0)
ret = CPU_COUNT(&cpu_mask);
#elif defined(TUKLIB_CPUCORES_CPUSET)
cpuset_t set;
if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
sizeof(set), &set) == 0) {
# ifdef CPU_COUNT
ret = CPU_COUNT(&set);
# else
for (unsigned i = 0; i < CPU_SETSIZE; ++i)
if (CPU_ISSET(i, &set))
++ret;
# endif
}
#elif defined(TUKLIB_CPUCORES_SYSCTL)
int name[2] = { CTL_HW, HW_NCPU };
int cpus;

View File

@@ -98,6 +98,17 @@
#endif
////////////////////////////////
// Compiler-specific features //
////////////////////////////////
// Newer Intel C compilers require immintrin.h for _bit_scan_reverse()
// and such functions.
#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
# include <immintrin.h>
#endif
///////////////////
// Byte swapping //
///////////////////
@@ -321,8 +332,8 @@ unaligned_read32le(const uint8_t *buf)
static inline void
unaligned_write16be(uint8_t *buf, uint16_t num)
{
buf[0] = num >> 8;
buf[1] = num;
buf[0] = (uint8_t)(num >> 8);
buf[1] = (uint8_t)num;
return;
}
@@ -330,8 +341,8 @@ unaligned_write16be(uint8_t *buf, uint16_t num)
static inline void
unaligned_write16le(uint8_t *buf, uint16_t num)
{
buf[0] = num;
buf[1] = num >> 8;
buf[0] = (uint8_t)num;
buf[1] = (uint8_t)(num >> 8);
return;
}
@@ -339,10 +350,10 @@ unaligned_write16le(uint8_t *buf, uint16_t num)
static inline void
unaligned_write32be(uint8_t *buf, uint32_t num)
{
buf[0] = num >> 24;
buf[1] = num >> 16;
buf[2] = num >> 8;
buf[3] = num;
buf[0] = (uint8_t)(num >> 24);
buf[1] = (uint8_t)(num >> 16);
buf[2] = (uint8_t)(num >> 8);
buf[3] = (uint8_t)num;
return;
}
@@ -350,10 +361,10 @@ unaligned_write32be(uint8_t *buf, uint32_t num)
static inline void
unaligned_write32le(uint8_t *buf, uint32_t num)
{
buf[0] = num;
buf[1] = num >> 8;
buf[2] = num >> 16;
buf[3] = num >> 24;
buf[0] = (uint8_t)num;
buf[1] = (uint8_t)(num >> 8);
buf[2] = (uint8_t)(num >> 16);
buf[3] = (uint8_t)(num >> 24);
return;
}

View File

@@ -33,7 +33,14 @@
# include <syidef.h>
# include <ssdef.h>
// AIX
#elif defined(AMIGA) || defined(__AROS__)
# define __USE_INLINE__
# include <proto/exec.h>
#elif defined(__QNX__)
# include <sys/syspage.h>
# include <string.h>
#elif defined(TUKLIB_PHYSMEM_AIX)
# include <sys/systemcfg.h>
@@ -79,7 +86,8 @@ tuklib_physmem(void)
// GlobalMemoryStatusEx() conditionally.
HMODULE kernel32 = GetModuleHandle("kernel32.dll");
if (kernel32 != NULL) {
BOOL (WINAPI *gmse)(LPMEMORYSTATUSEX) = GetProcAddress(
typedef BOOL (WINAPI *gmse_type)(LPMEMORYSTATUSEX);
gmse_type gmse = (gmse_type)GetProcAddress(
kernel32, "GlobalMemoryStatusEx");
if (gmse != NULL) {
MEMORYSTATUSEX meminfo;
@@ -119,6 +127,18 @@ tuklib_physmem(void)
if (LIB$GETSYI(&val, &vms_mem, 0, 0, 0, 0) == SS$_NORMAL)
ret = (uint64_t)vms_mem * 8192;
#elif defined(AMIGA) || defined(__AROS__)
ret = AvailMem(MEMF_TOTAL);
#elif defined(__QNX__)
const struct asinfo_entry *entries = SYSPAGE_ENTRY(asinfo);
size_t count = SYSPAGE_ENTRY_SIZE(asinfo) / sizeof(struct asinfo_entry);
const char *strings = SYSPAGE_ENTRY(strings)->data;
for (size_t i = 0; i < count; ++i)
if (strcmp(strings + entries[i].name, "ram") == 0)
ret += entries[i].end - entries[i].start + 1;
#elif defined(TUKLIB_PHYSMEM_AIX)
ret = _system_configuration.physmem;

View File

@@ -24,7 +24,7 @@ liblzma_la_CPPFLAGS = \
-I$(top_srcdir)/src/liblzma/simple \
-I$(top_srcdir)/src/common \
-DTUKLIB_SYMBOL_PREFIX=lzma_
liblzma_la_LDFLAGS = -no-undefined -version-info 5:99:0
liblzma_la_LDFLAGS = -no-undefined -version-info 8:99:3
EXTRA_DIST += liblzma.map validate_map.sh
if COND_SYMVERS
@@ -32,10 +32,10 @@ liblzma_la_LDFLAGS += \
-Wl,--version-script=$(top_srcdir)/src/liblzma/liblzma.map
endif
liblzma_la_SOURCES += $(top_srcdir)/src/common/tuklib_physmem.c
liblzma_la_SOURCES += ../common/tuklib_physmem.c
if COND_THREADS
liblzma_la_SOURCES += $(top_srcdir)/src/common/tuklib_cpucores.c
liblzma_la_SOURCES += ../common/tuklib_cpucores.c
endif
include $(srcdir)/common/Makefile.inc
@@ -116,7 +116,7 @@ liblzma.pc: $(srcdir)/liblzma.pc.in
-e 's,@PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
-e 's,@PTHREAD_CFLAGS[@],$(PTHREAD_CFLAGS),g' \
-e 's,@LIBS[@],$(LIBS),g' \
< $< > $@ || { rm -f $@; exit 1; }
< $(srcdir)/liblzma.pc.in > $@ || { rm -f $@; exit 1; }
clean-local:
rm -f liblzma.pc

View File

@@ -82,12 +82,20 @@
# if !defined(UINT32_C) || !defined(UINT64_C) \
|| !defined(UINT32_MAX) || !defined(UINT64_MAX)
/*
* MSVC has no C99 support, and thus it cannot be used to
* compile liblzma. The liblzma API has to still be usable
* from MSVC, so we need to define the required standard
* integer types here.
* MSVC versions older than 2013 have no C99 support, and
* thus they cannot be used to compile liblzma. Using an
* existing liblzma.dll with old MSVC can work though(*),
* but we need to define the required standard integer
* types here in a MSVC-specific way.
*
* (*) If you do this, the existing liblzma.dll probably uses
* a different runtime library than your MSVC-built
* application. Mixing runtimes is generally bad, but
* in this case it should work as long as you avoid
* the few rarely-needed liblzma functions that allocate
* memory and expect the caller to free it using free().
*/
# if defined(_WIN32) && defined(_MSC_VER)
# if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1800
typedef unsigned __int8 uint8_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
@@ -211,7 +219,11 @@
*/
#ifndef lzma_nothrow
# if defined(__cplusplus)
# define lzma_nothrow throw()
# if __cplusplus >= 201103L
# define lzma_nothrow noexcept
# else
# define lzma_nothrow throw()
# endif
# elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
# define lzma_nothrow __attribute__((__nothrow__))
# else

View File

@@ -234,6 +234,23 @@ typedef enum {
* can be a sign of a bug in liblzma. See the documentation
* how to report bugs.
*/
LZMA_SEEK_NEEDED = 12
/**<
* \brief Request to change the input file position
*
* Some coders can do random access in the input file. The
* initialization functions of these coders take the file size
* as an argument. No other coders can return LZMA_SEEK_NEEDED.
*
* When this value is returned, the application must seek to
* the file position given in lzma_stream.seek_pos. This value
* is guaranteed to never exceed the file size that was
* specified at the coder initialization.
*
* After seeking the application should read new input and
* pass it normally via lzma_stream.next_in and .avail_in.
*/
} lzma_ret;
@@ -514,7 +531,19 @@ typedef struct {
void *reserved_ptr2;
void *reserved_ptr3;
void *reserved_ptr4;
uint64_t reserved_int1;
/**
* \brief New seek input position for LZMA_SEEK_NEEDED
*
* When lzma_code() returns LZMA_SEEK_NEEDED, the new input position
* needed by liblzma will be available seek_pos. The value is
* guaranteed to not exceed the file size that was specified when
* this lzma_stream was initialized.
*
* In all other situations the value of this variable is undefined.
*/
uint64_t seek_pos;
uint64_t reserved_int2;
size_t reserved_int3;
size_t reserved_int4;
@@ -644,11 +673,16 @@ extern LZMA_API(uint64_t) lzma_memlimit_get(const lzma_stream *strm)
* This function is supported only when *strm has been initialized with
* a function that takes a memlimit argument.
*
* liblzma 5.2.3 and earlier has a bug where memlimit value of 0 causes
* this function to do nothing (leaving the limit unchanged) and still
* return LZMA_OK. Later versions treat 0 as if 1 had been specified (so
* lzma_memlimit_get() will return 1 even if you specify 0 here).
*
* \return - LZMA_OK: New memory usage limit successfully set.
* - LZMA_MEMLIMIT_ERROR: The new limit is too small.
* The limit was not changed.
* - LZMA_PROG_ERROR: Invalid arguments, e.g. *strm doesn't
* support memory usage limit or memlimit was zero.
* support memory usage limit.
*/
extern LZMA_API(lzma_ret) lzma_memlimit_set(
lzma_stream *strm, uint64_t memlimit) lzma_nothrow;

View File

@@ -60,7 +60,6 @@
#define LZMA_PRESET_EXTREME (UINT32_C(1) << 31)
#ifdef LZMA_UNSTABLE /* Unstable API that may change. Use only for testing. */
/**
* \brief Multithreading options
*/
@@ -97,6 +96,10 @@ typedef struct {
* Set this to 0 to let liblzma choose the block size depending
* on the compression options. For LZMA2 it will be 3*dict_size
* or 1 MiB, whichever is more.
*
* For each thread, about 3 * block_size bytes of memory will be
* allocated. This may change in later liblzma versions. If so,
* the memory usage will probably be reduced, not increased.
*/
uint64_t block_size;
@@ -180,7 +183,6 @@ typedef struct {
void *reserved_ptr4;
} lzma_mt;
#endif
/**
@@ -314,7 +316,6 @@ extern LZMA_API(lzma_ret) lzma_stream_encoder(lzma_stream *strm,
lzma_nothrow lzma_attr_warn_unused_result;
#ifdef LZMA_UNSTABLE /* Unstable API that may change. Use only for testing. */
/**
* \brief Calculate approximate memory usage of multithreaded .xz encoder
*
@@ -340,8 +341,9 @@ extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage(
* This provides the functionality of lzma_easy_encoder() and
* lzma_stream_encoder() as a single function for multithreaded use.
*
* TODO: For lzma_code(), only LZMA_RUN and LZMA_FINISH are currently
* supported. Support for other actions has been planned.
* The supported actions for lzma_code() are LZMA_RUN, LZMA_FULL_FLUSH,
* LZMA_FULL_BARRIER, and LZMA_FINISH. Support for LZMA_SYNC_FLUSH might be
* added in the future.
*
* \param strm Pointer to properly prepared lzma_stream
* \param options Pointer to multithreaded compression options
@@ -355,7 +357,6 @@ extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage(
extern LZMA_API(lzma_ret) lzma_stream_encoder_mt(
lzma_stream *strm, const lzma_mt *options)
lzma_nothrow lzma_attr_warn_unused_result;
#endif
/**
@@ -519,7 +520,10 @@ extern LZMA_API(lzma_ret) lzma_stream_buffer_encode(
*
* \param strm Pointer to properly prepared lzma_stream
* \param memlimit Memory usage limit as bytes. Use UINT64_MAX
* to effectively disable the limiter.
* to effectively disable the limiter. liblzma
* 5.2.3 and earlier don't allow 0 here and return
* LZMA_PROG_ERROR; later versions treat 0 as if 1
* had been specified.
* \param flags Bitwise-or of zero or more of the decoder flags:
* LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,
* LZMA_TELL_ANY_CHECK, LZMA_CONCATENATED
@@ -543,7 +547,10 @@ extern LZMA_API(lzma_ret) lzma_stream_decoder(
*
* \param strm Pointer to properly prepared lzma_stream
* \param memlimit Memory usage limit as bytes. Use UINT64_MAX
* to effectively disable the limiter.
* to effectively disable the limiter. liblzma
* 5.2.3 and earlier don't allow 0 here and return
* LZMA_PROG_ERROR; later versions treat 0 as if 1
* had been specified.
* \param flags Bitwise-or of flags, or zero for no flags.
*
* \return - LZMA_OK: Initialization was successful.
@@ -559,9 +566,16 @@ extern LZMA_API(lzma_ret) lzma_auto_decoder(
/**
* \brief Initialize .lzma decoder (legacy file format)
*
* \param strm Pointer to properly prepared lzma_stream
* \param memlimit Memory usage limit as bytes. Use UINT64_MAX
* to effectively disable the limiter. liblzma
* 5.2.3 and earlier don't allow 0 here and return
* LZMA_PROG_ERROR; later versions treat 0 as if 1
* had been specified.
*
* Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.
* There is no need to use LZMA_FINISH, but allowing it may simplify
* certain types of applications.
* There is no need to use LZMA_FINISH, but it's allowed because it may
* simplify certain types of applications.
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR

View File

@@ -586,8 +586,7 @@ extern LZMA_API(lzma_index *) lzma_index_dup(
* \param i Pointer to lzma_index which should be encoded.
*
* The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
* It is enough to use only one of them (you can choose freely; use LZMA_RUN
* to support liblzma versions older than 5.0.0).
* It is enough to use only one of them (you can choose freely).
*
* \return - LZMA_OK: Initialization succeeded, continue with lzma_code().
* - LZMA_MEM_ERROR
@@ -610,16 +609,21 @@ extern LZMA_API(lzma_ret) lzma_index_encoder(
* to a new lzma_index, which the application
* has to later free with lzma_index_end().
* \param memlimit How much memory the resulting lzma_index is
* allowed to require.
* allowed to require. liblzma 5.2.3 and earlier
* don't allow 0 here and return LZMA_PROG_ERROR;
* later versions treat 0 as if 1 had been specified.
*
* The valid `action' values for lzma_code() are LZMA_RUN and LZMA_FINISH.
* It is enough to use only one of them (you can choose freely; use LZMA_RUN
* to support liblzma versions older than 5.0.0).
* Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.
* There is no need to use LZMA_FINISH, but it's allowed because it may
* simplify certain types of applications.
*
* \return - LZMA_OK: Initialization succeeded, continue with lzma_code().
* - LZMA_MEM_ERROR
* - LZMA_MEMLIMIT_ERROR
* - LZMA_PROG_ERROR
*
* liblzma 5.2.3 and older list also LZMA_MEMLIMIT_ERROR here
* but that error code has never been possible from this
* initialization function.
*/
extern LZMA_API(lzma_ret) lzma_index_decoder(
lzma_stream *strm, lzma_index **i, uint64_t memlimit)
@@ -680,3 +684,69 @@ extern LZMA_API(lzma_ret) lzma_index_buffer_decode(lzma_index **i,
uint64_t *memlimit, const lzma_allocator *allocator,
const uint8_t *in, size_t *in_pos, size_t in_size)
lzma_nothrow;
/**
* \brief Initialize a .xz file information decoder
*
* \param strm Pointer to a properly prepared lzma_stream
* \param dest_index Pointer to a pointer where the decoder will put
* the decoded lzma_index. The old value
* of *dest_index is ignored (not freed).
* \param memlimit How much memory the resulting lzma_index is
* allowed to require. Use UINT64_MAX to
* effectively disable the limiter.
* \param file_size Size of the input .xz file
*
* This decoder decodes the Stream Header, Stream Footer, Index, and
* Stream Padding field(s) from the input .xz file and stores the resulting
* combined index in *dest_index. This information can be used to get the
* uncompressed file size with lzma_index_uncompressed_size(*dest_index) or,
* for example, to implement random access reading by locating the Blocks
* in the Streams.
*
* To get the required information from the .xz file, lzma_code() may ask
* the application to seek in the input file by returning LZMA_SEEK_NEEDED
* and having the target file position specified in lzma_stream.seek_pos.
* The number of seeks required depends on the input file and how big buffers
* the application provides. When possible, the decoder will seek backward
* and forward in the given buffer to avoid useless seek requests. Thus, if
* the application provides the whole file at once, no external seeking will
* be required (that is, lzma_code() won't return LZMA_SEEK_NEEDED).
*
* The value in lzma_stream.total_in can be used to estimate how much data
* liblzma had to read to get the file information. However, due to seeking
* and the way total_in is updated, the value of total_in will be somewhat
* inaccurate (a little too big). Thus, total_in is a good estimate but don't
* expect to see the same exact value for the same file if you change the
* input buffer size or switch to a different liblzma version.
*
* Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.
* You only need to use LZMA_RUN; LZMA_FINISH is only supported because it
* might be convenient for some applications. If you use LZMA_FINISH and if
* lzma_code() asks the application to seek, remember to reset `action' back
* to LZMA_RUN unless you hit the end of the file again.
*
* Possible return values from lzma_code():
* - LZMA_OK: All OK so far, more input needed
* - LZMA_SEEK_NEEDED: Provide more input starting from the absolute
* file position strm->seek_pos
* - LZMA_STREAM_END: Decoding was successful, *dest_index has been set
* - LZMA_FORMAT_ERROR: The input file is not in the .xz format (the
* expected magic bytes were not found from the beginning of the file)
* - LZMA_OPTIONS_ERROR: File looks valid but contains headers that aren't
* supported by this version of liblzma
* - LZMA_DATA_ERROR: File is corrupt
* - LZMA_BUF_ERROR
* - LZMA_MEM_ERROR
* - LZMA_MEMLIMIT_ERROR
* - LZMA_PROG_ERROR
*
* \return - LZMA_OK
* - LZMA_MEM_ERROR
* - LZMA_PROG_ERROR
*/
extern LZMA_API(lzma_ret) lzma_file_info_decoder(
lzma_stream *strm, lzma_index **dest_index,
uint64_t memlimit, uint64_t file_size)
lzma_nothrow;

View File

@@ -21,9 +21,9 @@
* Version number split into components
*/
#define LZMA_VERSION_MAJOR 5
#define LZMA_VERSION_MINOR 1
#define LZMA_VERSION_PATCH 4
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_BETA
#define LZMA_VERSION_MINOR 3
#define LZMA_VERSION_PATCH 1
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_ALPHA
#ifndef LZMA_VERSION_COMMIT
# define LZMA_VERSION_COMMIT ""

View File

@@ -15,7 +15,18 @@
#include "common.h"
#if defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
// If the function for external SHA-256 is missing, use the internal SHA-256
// code. Due to how configure works, these defines can only get defined when
// both a usable header and a type have already been found.
#if !(defined(HAVE_CC_SHA256_INIT) \
|| defined(HAVE_SHA256_INIT) \
|| defined(HAVE_SHA256INIT))
# define HAVE_INTERNAL_SHA256 1
#endif
#if defined(HAVE_INTERNAL_SHA256)
// Nothing
#elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
# include <CommonCrypto/CommonDigest.h>
#elif defined(HAVE_SHA256_H)
# include <sys/types.h>
@@ -23,18 +34,9 @@
#elif defined(HAVE_SHA2_H)
# include <sys/types.h>
# include <sha2.h>
#elif defined(HAVE_MINIX_SHA2_H)
# include <sys/types.h>
# include <minix/sha2.h>
#endif
#if defined(HAVE_CC_SHA256_CTX)
typedef CC_SHA256_CTX lzma_sha256_state;
#elif defined(HAVE_SHA256_CTX)
typedef SHA256_CTX lzma_sha256_state;
#elif defined(HAVE_SHA2_CTX)
typedef SHA2_CTX lzma_sha256_state;
#else
#if defined(HAVE_INTERNAL_SHA256)
/// State for the internal SHA-256 implementation
typedef struct {
/// Internal state
@@ -43,9 +45,17 @@ typedef struct {
/// Size of the message excluding padding
uint64_t size;
} lzma_sha256_state;
#elif defined(HAVE_CC_SHA256_CTX)
typedef CC_SHA256_CTX lzma_sha256_state;
#elif defined(HAVE_SHA256_CTX)
typedef SHA256_CTX lzma_sha256_state;
#elif defined(HAVE_SHA2_CTX)
typedef SHA2_CTX lzma_sha256_state;
#endif
#if defined(HAVE_CC_SHA256_INIT)
#if defined(HAVE_INTERNAL_SHA256)
// Nothing
#elif defined(HAVE_CC_SHA256_INIT)
# define LZMA_SHA256FUNC(x) CC_SHA256_ ## x
#elif defined(HAVE_SHA256_INIT)
# define LZMA_SHA256FUNC(x) SHA256_ ## x

View File

@@ -21,6 +21,10 @@ liblzma_la_SOURCES += \
common/stream_flags_common.h \
common/vli_size.c
if COND_THREADS
liblzma_la_SOURCES += common/hardware_cputhreads.c
endif
if COND_MAIN_ENCODER
liblzma_la_SOURCES += \
common/alone_encoder.c \
@@ -45,7 +49,6 @@ liblzma_la_SOURCES += \
if COND_THREADS
liblzma_la_SOURCES += \
common/hardware_cputhreads.c \
common/outqueue.c \
common/outqueue.h \
common/stream_encoder_mt.c
@@ -62,11 +65,13 @@ liblzma_la_SOURCES += \
common/block_decoder.h \
common/block_header_decoder.c \
common/easy_decoder_memusage.c \
common/file_info.c \
common/filter_buffer_decoder.c \
common/filter_decoder.c \
common/filter_decoder.h \
common/filter_flags_decoder.c \
common/index_decoder.c \
common/index_decoder.h \
common/index_hash.c \
common/stream_buffer_decoder.c \
common/stream_decoder.c \

View File

@@ -15,7 +15,7 @@
#include "lz_decoder.h"
struct lzma_coder_s {
typedef struct {
lzma_next_coder next;
enum {
@@ -46,17 +46,19 @@ struct lzma_coder_s {
/// Options decoded from the header needed to initialize
/// the LZMA decoder
lzma_options_lzma options;
};
} lzma_alone_coder;
static lzma_ret
alone_decode(lzma_coder *coder,
alone_decode(void *coder_ptr,
const lzma_allocator *allocator lzma_attribute((__unused__)),
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
lzma_action action)
{
lzma_alone_coder *coder = coder_ptr;
while (*out_pos < out_size
&& (coder->sequence == SEQ_CODE || *in_pos < in_size))
switch (coder->sequence) {
@@ -166,8 +168,9 @@ alone_decode(lzma_coder *coder,
static void
alone_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
alone_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_alone_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
@@ -175,9 +178,11 @@ alone_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
alone_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
alone_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
uint64_t *old_memlimit, uint64_t new_memlimit)
{
lzma_alone_coder *coder = coder_ptr;
*memusage = coder->memusage;
*old_memlimit = coder->memlimit;
@@ -198,29 +203,29 @@ lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
{
lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);
if (memlimit == 0)
return LZMA_PROG_ERROR;
lzma_alone_coder *coder = next->coder;
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &alone_decode;
next->end = &alone_decoder_end;
next->memconfig = &alone_decoder_memconfig;
next->coder->next = LZMA_NEXT_CODER_INIT;
coder->next = LZMA_NEXT_CODER_INIT;
}
next->coder->sequence = SEQ_PROPERTIES;
next->coder->picky = picky;
next->coder->pos = 0;
next->coder->options.dict_size = 0;
next->coder->options.preset_dict = NULL;
next->coder->options.preset_dict_size = 0;
next->coder->uncompressed_size = 0;
next->coder->memlimit = memlimit;
next->coder->memusage = LZMA_MEMUSAGE_BASE;
coder->sequence = SEQ_PROPERTIES;
coder->picky = picky;
coder->pos = 0;
coder->options.dict_size = 0;
coder->options.preset_dict = NULL;
coder->options.preset_dict_size = 0;
coder->uncompressed_size = 0;
coder->memlimit = my_max(1, memlimit);
coder->memusage = LZMA_MEMUSAGE_BASE;
return LZMA_OK;
}

View File

@@ -17,7 +17,7 @@
#define ALONE_HEADER_SIZE (1 + 4 + 8)
struct lzma_coder_s {
typedef struct {
lzma_next_coder next;
enum {
@@ -27,17 +27,19 @@ struct lzma_coder_s {
size_t header_pos;
uint8_t header[ALONE_HEADER_SIZE];
};
} lzma_alone_coder;
static lzma_ret
alone_encode(lzma_coder *coder,
alone_encode(void *coder_ptr,
const lzma_allocator *allocator lzma_attribute((__unused__)),
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
lzma_action action)
{
lzma_alone_coder *coder = coder_ptr;
while (*out_pos < out_size)
switch (coder->sequence) {
case SEQ_HEADER:
@@ -65,8 +67,9 @@ alone_encode(lzma_coder *coder,
static void
alone_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
alone_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_alone_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
@@ -80,23 +83,26 @@ alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
{
lzma_next_coder_init(&alone_encoder_init, next, allocator);
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_alone_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &alone_encode;
next->end = &alone_encoder_end;
next->coder->next = LZMA_NEXT_CODER_INIT;
coder->next = LZMA_NEXT_CODER_INIT;
}
// Basic initializations
next->coder->sequence = SEQ_HEADER;
next->coder->header_pos = 0;
coder->sequence = SEQ_HEADER;
coder->header_pos = 0;
// Encode the header:
// - Properties (1 byte)
if (lzma_lzma_lclppb_encode(options, next->coder->header))
if (lzma_lzma_lclppb_encode(options, coder->header))
return LZMA_OPTIONS_ERROR;
// - Dictionary size (4 bytes)
@@ -116,10 +122,10 @@ alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
if (d != UINT32_MAX)
++d;
unaligned_write32le(next->coder->header + 1, d);
unaligned_write32le(coder->header + 1, d);
// - Uncompressed size (always unknown and using EOPM)
memset(next->coder->header + 1 + 4, 0xFF, 8);
memset(coder->header + 1 + 4, 0xFF, 8);
// Initialize the LZMA encoder.
const lzma_filter_info filters[2] = {
@@ -131,7 +137,7 @@ alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
}
};
return lzma_next_filter_init(&next->coder->next, allocator, filters);
return lzma_next_filter_init(&coder->next, allocator, filters);
}

View File

@@ -14,7 +14,7 @@
#include "alone_decoder.h"
struct lzma_coder_s {
typedef struct {
/// Stream decoder or LZMA_Alone decoder
lzma_next_coder next;
@@ -26,15 +26,17 @@ struct lzma_coder_s {
SEQ_CODE,
SEQ_FINISH,
} sequence;
};
} lzma_auto_coder;
static lzma_ret
auto_decode(lzma_coder *coder, const lzma_allocator *allocator,
auto_decode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_auto_coder *coder = coder_ptr;
switch (coder->sequence) {
case SEQ_INIT:
if (*in_pos >= in_size)
@@ -100,8 +102,9 @@ auto_decode(lzma_coder *coder, const lzma_allocator *allocator,
static void
auto_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
auto_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_auto_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
@@ -109,8 +112,10 @@ auto_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_check
auto_decoder_get_check(const lzma_coder *coder)
auto_decoder_get_check(const void *coder_ptr)
{
const lzma_auto_coder *coder = coder_ptr;
// It is LZMA_Alone if get_check is NULL.
return coder->next.get_check == NULL ? LZMA_CHECK_NONE
: coder->next.get_check(coder->next.coder);
@@ -118,9 +123,11 @@ auto_decoder_get_check(const lzma_coder *coder)
static lzma_ret
auto_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
auto_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
uint64_t *old_memlimit, uint64_t new_memlimit)
{
lzma_auto_coder *coder = coder_ptr;
lzma_ret ret;
if (coder->next.memconfig != NULL) {
@@ -132,7 +139,10 @@ auto_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
// the current memory usage.
*memusage = LZMA_MEMUSAGE_BASE;
*old_memlimit = coder->memlimit;
ret = LZMA_OK;
if (new_memlimit != 0 && new_memlimit < *memusage)
ret = LZMA_MEMLIMIT_ERROR;
}
if (ret == LZMA_OK && new_memlimit != 0)
@@ -148,27 +158,26 @@ auto_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
{
lzma_next_coder_init(&auto_decoder_init, next, allocator);
if (memlimit == 0)
return LZMA_PROG_ERROR;
if (flags & ~LZMA_SUPPORTED_FLAGS)
return LZMA_OPTIONS_ERROR;
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_auto_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_auto_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &auto_decode;
next->end = &auto_decoder_end;
next->get_check = &auto_decoder_get_check;
next->memconfig = &auto_decoder_memconfig;
next->coder->next = LZMA_NEXT_CODER_INIT;
coder->next = LZMA_NEXT_CODER_INIT;
}
next->coder->memlimit = memlimit;
next->coder->flags = flags;
next->coder->sequence = SEQ_INIT;
coder->memlimit = my_max(1, memlimit);
coder->flags = flags;
coder->sequence = SEQ_INIT;
return LZMA_OK;
}

View File

@@ -15,7 +15,7 @@
#include "check.h"
struct lzma_coder_s {
typedef struct {
enum {
SEQ_CODE,
SEQ_PADDING,
@@ -48,7 +48,7 @@ struct lzma_coder_s {
/// True if the integrity check won't be calculated and verified.
bool ignore_check;
};
} lzma_block_coder;
static inline bool
@@ -74,11 +74,13 @@ is_size_valid(lzma_vli size, lzma_vli reference)
static lzma_ret
block_decode(lzma_coder *coder, const lzma_allocator *allocator,
block_decode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_block_coder *coder = coder_ptr;
switch (coder->sequence) {
case SEQ_CODE: {
const size_t in_start = *in_pos;
@@ -177,8 +179,9 @@ block_decode(lzma_coder *coder, const lzma_allocator *allocator,
static void
block_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
block_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_block_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
@@ -198,27 +201,29 @@ lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|| !lzma_vli_is_valid(block->uncompressed_size))
return LZMA_PROG_ERROR;
// Allocate and initialize *next->coder if needed.
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
// Allocate *next->coder if needed.
lzma_block_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_block_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &block_decode;
next->end = &block_decoder_end;
next->coder->next = LZMA_NEXT_CODER_INIT;
coder->next = LZMA_NEXT_CODER_INIT;
}
// Basic initializations
next->coder->sequence = SEQ_CODE;
next->coder->block = block;
next->coder->compressed_size = 0;
next->coder->uncompressed_size = 0;
coder->sequence = SEQ_CODE;
coder->block = block;
coder->compressed_size = 0;
coder->uncompressed_size = 0;
// If Compressed Size is not known, we calculate the maximum allowed
// value so that encoded size of the Block (including Block Padding)
// is still a valid VLI and a multiple of four.
next->coder->compressed_limit
coder->compressed_limit
= block->compressed_size == LZMA_VLI_UNKNOWN
? (LZMA_VLI_MAX & ~LZMA_VLI_C(3))
- block->header_size
@@ -228,14 +233,14 @@ lzma_block_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
// Initialize the check. It's caller's problem if the Check ID is not
// supported, and the Block decoder cannot verify the Check field.
// Caller can test lzma_check_is_supported(block->check).
next->coder->check_pos = 0;
lzma_check_init(&next->coder->check, block->check);
coder->check_pos = 0;
lzma_check_init(&coder->check, block->check);
next->coder->ignore_check = block->version >= 1
coder->ignore_check = block->version >= 1
? block->ignore_check : false;
// Initialize the filter chain.
return lzma_raw_decoder_init(&next->coder->next, allocator,
return lzma_raw_decoder_init(&coder->next, allocator,
block->filters);
}

View File

@@ -15,7 +15,7 @@
#include "check.h"
struct lzma_coder_s {
typedef struct {
/// The filters in the chain; initialized with lzma_raw_decoder_init().
lzma_next_coder next;
@@ -41,15 +41,17 @@ struct lzma_coder_s {
/// Check of the uncompressed data
lzma_check_state check;
};
} lzma_block_coder;
static lzma_ret
block_encode(lzma_coder *coder, const lzma_allocator *allocator,
block_encode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_block_coder *coder = coder_ptr;
// Check that our amount of input stays in proper limits.
if (LZMA_VLI_MAX - coder->uncompressed_size < in_size - *in_pos)
return LZMA_DATA_ERROR;
@@ -134,8 +136,9 @@ block_encode(lzma_coder *coder, const lzma_allocator *allocator,
static void
block_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
block_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_block_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
@@ -143,10 +146,12 @@ block_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
block_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
block_encoder_update(void *coder_ptr, const lzma_allocator *allocator,
const lzma_filter *filters lzma_attribute((__unused__)),
const lzma_filter *reversed_filters)
{
lzma_block_coder *coder = coder_ptr;
if (coder->sequence != SEQ_CODE)
return LZMA_PROG_ERROR;
@@ -178,30 +183,31 @@ lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
return LZMA_UNSUPPORTED_CHECK;
// Allocate and initialize *next->coder if needed.
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_block_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_block_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &block_encode;
next->end = &block_encoder_end;
next->update = &block_encoder_update;
next->coder->next = LZMA_NEXT_CODER_INIT;
coder->next = LZMA_NEXT_CODER_INIT;
}
// Basic initializations
next->coder->sequence = SEQ_CODE;
next->coder->block = block;
next->coder->compressed_size = 0;
next->coder->uncompressed_size = 0;
next->coder->pos = 0;
coder->sequence = SEQ_CODE;
coder->block = block;
coder->compressed_size = 0;
coder->uncompressed_size = 0;
coder->pos = 0;
// Initialize the check
lzma_check_init(&next->coder->check, block->check);
lzma_check_init(&coder->check, block->check);
// Initialize the requested filters.
return lzma_raw_encoder_init(&next->coder->next, allocator,
block->filters);
return lzma_raw_encoder_init(&coder->next, allocator, block->filters);
}

View File

@@ -207,7 +207,6 @@ lzma_code(lzma_stream *strm, lzma_action action)
|| strm->reserved_ptr2 != NULL
|| strm->reserved_ptr3 != NULL
|| strm->reserved_ptr4 != NULL
|| strm->reserved_int1 != 0
|| strm->reserved_int2 != 0
|| strm->reserved_int3 != 0
|| strm->reserved_int4 != 0
@@ -318,6 +317,17 @@ lzma_code(lzma_stream *strm, lzma_action action)
ret = LZMA_OK;
break;
case LZMA_SEEK_NEEDED:
strm->internal->allow_buf_error = false;
// If LZMA_FINISH was used, reset it back to the
// LZMA_RUN-based state so that new input can be supplied
// by the application.
if (strm->internal->sequence == ISEQ_FINISH)
strm->internal->sequence = ISEQ_RUN;
break;
case LZMA_STREAM_END:
if (strm->internal->sequence == ISEQ_SYNC_FLUSH
|| strm->internal->sequence == ISEQ_FULL_FLUSH
@@ -435,8 +445,10 @@ lzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit)
|| strm->internal->next.memconfig == NULL)
return LZMA_PROG_ERROR;
if (new_memlimit != 0 && new_memlimit < LZMA_MEMUSAGE_BASE)
return LZMA_MEMLIMIT_ERROR;
// Zero is a special value that cannot be used as an actual limit.
// If 0 was specified, use 1 instead.
if (new_memlimit == 0)
new_memlimit = 1;
return strm->internal->next.memconfig(strm->internal->next.coder,
&memusage, &old_memlimit, new_memlimit);

View File

@@ -32,8 +32,6 @@
#define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
#define LZMA_UNSTABLE
#include "lzma.h"
// These allow helping the compiler in some often-executed branches, whose
@@ -90,10 +88,6 @@
#define LZMA_TIMED_OUT 32
/// Type of encoder/decoder specific data; the actual structure is defined
/// differently in different coders.
typedef struct lzma_coder_s lzma_coder;
typedef struct lzma_next_coder_s lzma_next_coder;
typedef struct lzma_filter_info_s lzma_filter_info;
@@ -109,7 +103,7 @@ typedef lzma_ret (*lzma_init_function)(
/// input and output buffers, but for simplicity they still use this same
/// function prototype.
typedef lzma_ret (*lzma_code_function)(
lzma_coder *coder, const lzma_allocator *allocator,
void *coder, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
@@ -117,7 +111,7 @@ typedef lzma_ret (*lzma_code_function)(
/// Type of a function to free the memory allocated for the coder
typedef void (*lzma_end_function)(
lzma_coder *coder, const lzma_allocator *allocator);
void *coder, const lzma_allocator *allocator);
/// Raw coder validates and converts an array of lzma_filter structures to
@@ -140,7 +134,7 @@ struct lzma_filter_info_s {
/// Hold data and function pointers of the next filter in the chain.
struct lzma_next_coder_s {
/// Pointer to coder-specific data
lzma_coder *coder;
void *coder;
/// Filter ID. This is LZMA_VLI_UNKNOWN when this structure doesn't
/// point to a filter coder.
@@ -162,21 +156,21 @@ struct lzma_next_coder_s {
/// Pointer to a function to get progress information. If this is NULL,
/// lzma_stream.total_in and .total_out are used instead.
void (*get_progress)(lzma_coder *coder,
void (*get_progress)(void *coder,
uint64_t *progress_in, uint64_t *progress_out);
/// Pointer to function to return the type of the integrity check.
/// Most coders won't support this.
lzma_check (*get_check)(const lzma_coder *coder);
lzma_check (*get_check)(const void *coder);
/// Pointer to function to get and/or change the memory usage limit.
/// If new_memlimit == 0, the limit is not changed.
lzma_ret (*memconfig)(lzma_coder *coder, uint64_t *memusage,
lzma_ret (*memconfig)(void *coder, uint64_t *memusage,
uint64_t *old_memlimit, uint64_t new_memlimit);
/// Update the filter-specific options or the whole filter chain
/// in the encoder.
lzma_ret (*update)(lzma_coder *coder, const lzma_allocator *allocator,
lzma_ret (*update)(void *coder, const lzma_allocator *allocator,
const lzma_filter *filters,
const lzma_filter *reversed_filters);
};

View File

@@ -0,0 +1,855 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file file_info.c
/// \brief Decode .xz file information into a lzma_index structure
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#include "index_decoder.h"
typedef struct {
enum {
SEQ_MAGIC_BYTES,
SEQ_PADDING_SEEK,
SEQ_PADDING_DECODE,
SEQ_FOOTER,
SEQ_INDEX_INIT,
SEQ_INDEX_DECODE,
SEQ_HEADER_DECODE,
SEQ_HEADER_COMPARE,
} sequence;
/// Absolute position of in[*in_pos] in the file. All code that
/// modifies *in_pos also updates this. seek_to_pos() needs this
/// to determine if we need to request the application to seek for
/// us or if we can do the seeking internally by adjusting *in_pos.
uint64_t file_cur_pos;
/// This refers to absolute positions of interesting parts of the
/// input file. Sometimes it points to the *beginning* of a specific
/// field and sometimes to the *end* of a field. The current target
/// position at each moment is explained in the comments.
uint64_t file_target_pos;
/// Size of the .xz file (from the application).
uint64_t file_size;
/// Index decoder
lzma_next_coder index_decoder;
/// Number of bytes remaining in the Index field that is currently
/// being decoded.
lzma_vli index_remaining;
/// The Index decoder will store the decoded Index in this pointer.
lzma_index *this_index;
/// Amount of Stream Padding in the current Stream.
lzma_vli stream_padding;
/// The final combined index is collected here.
lzma_index *combined_index;
/// Pointer from the application where to store the index information
/// after successful decoding.
lzma_index **dest_index;
/// Pointer to lzma_stream.seek_pos to be used when returning
/// LZMA_SEEK_NEEDED. This is set by seek_to_pos() when needed.
uint64_t *external_seek_pos;
/// Memory usage limit
uint64_t memlimit;
/// Stream Flags from the very beginning of the file.
lzma_stream_flags first_header_flags;
/// Stream Flags from Stream Header of the current Stream.
lzma_stream_flags header_flags;
/// Stream Flags from Stream Footer of the current Stream.
lzma_stream_flags footer_flags;
size_t temp_pos;
size_t temp_size;
uint8_t temp[8192];
} lzma_file_info_coder;
/// Copies data from in[*in_pos] into coder->temp until
/// coder->temp_pos == coder->temp_size. This also keeps coder->file_cur_pos
/// in sync with *in_pos. Returns true if more input is needed.
static bool
fill_temp(lzma_file_info_coder *coder, const uint8_t *restrict in,
size_t *restrict in_pos, size_t in_size)
{
coder->file_cur_pos += lzma_bufcpy(in, in_pos, in_size,
coder->temp, &coder->temp_pos, coder->temp_size);
return coder->temp_pos < coder->temp_size;
}
/// Seeks to the absolute file position specified by target_pos.
/// This tries to do the seeking by only modifying *in_pos, if possible.
/// The main benefit of this is that if one passes the whole file at once
/// to lzma_code(), the decoder will never need to return LZMA_SEEK_NEEDED
/// as all the seeking can be done by adjusting *in_pos in this function.
///
/// Returns true if an external seek is needed and the caller must return
/// LZMA_SEEK_NEEDED.
static bool
seek_to_pos(lzma_file_info_coder *coder, uint64_t target_pos,
size_t in_start, size_t *in_pos, size_t in_size)
{
// The input buffer doesn't extend beyond the end of the file.
// This has been checked by file_info_decode() already.
assert(coder->file_size - coder->file_cur_pos >= in_size - *in_pos);
const uint64_t pos_min = coder->file_cur_pos - (*in_pos - in_start);
const uint64_t pos_max = coder->file_cur_pos + (in_size - *in_pos);
bool external_seek_needed;
if (target_pos >= pos_min && target_pos <= pos_max) {
// The requested position is available in the current input
// buffer or right after it. That is, in a corner case we
// end up setting *in_pos == in_size and thus will immediately
// need new input bytes from the application.
*in_pos += (size_t)(target_pos - coder->file_cur_pos);
external_seek_needed = false;
} else {
// Ask the application to seek the input file.
*coder->external_seek_pos = target_pos;
external_seek_needed = true;
// Mark the whole input buffer as used. This way
// lzma_stream.total_in will have a better estimate
// of the amount of data read. It still won't be perfect
// as the value will depend on the input buffer size that
// the application uses, but it should be good enough for
// those few who want an estimate.
*in_pos = in_size;
}
// After seeking (internal or external) the current position
// will match the requested target position.
coder->file_cur_pos = target_pos;
return external_seek_needed;
}
/// The caller sets coder->file_target_pos so that it points to the *end*
/// of the desired file position. This function then determines how far
/// backwards from that position we can seek. After seeking fill_temp()
/// can be used to read data into coder->temp. When fill_temp() has finished,
/// coder->temp[coder->temp_size] will match coder->file_target_pos.
///
/// This also validates that coder->target_file_pos is sane in sense that
/// we aren't trying to seek too far backwards (too close or beyond the
/// beginning of the file).
static lzma_ret
reverse_seek(lzma_file_info_coder *coder,
size_t in_start, size_t *in_pos, size_t in_size)
{
// Check that there is enough data before the target position
// to contain at least Stream Header and Stream Footer. If there
// isn't, the file cannot be valid.
if (coder->file_target_pos < 2 * LZMA_STREAM_HEADER_SIZE)
return LZMA_DATA_ERROR;
coder->temp_pos = 0;
// The Stream Header at the very beginning of the file gets handled
// specially in SEQ_MAGIC_BYTES and thus we will never need to seek
// there. By not seeking to the first LZMA_STREAM_HEADER_SIZE bytes
// we avoid a useless external seek after SEQ_MAGIC_BYTES if the
// application uses an extremely small input buffer and the input
// file is very small.
if (coder->file_target_pos - LZMA_STREAM_HEADER_SIZE
< sizeof(coder->temp))
coder->temp_size = (size_t)(coder->file_target_pos
- LZMA_STREAM_HEADER_SIZE);
else
coder->temp_size = sizeof(coder->temp);
// The above if-statements guarantee this. This is important because
// the Stream Header/Footer decoders assume that there's at least
// LZMA_STREAM_HEADER_SIZE bytes in coder->temp.
assert(coder->temp_size >= LZMA_STREAM_HEADER_SIZE);
if (seek_to_pos(coder, coder->file_target_pos - coder->temp_size,
in_start, in_pos, in_size))
return LZMA_SEEK_NEEDED;
return LZMA_OK;
}
/// Gets the number of zero-bytes at the end of the buffer.
static size_t
get_padding_size(const uint8_t *buf, size_t buf_size)
{
size_t padding = 0;
while (buf_size > 0 && buf[--buf_size] == 0x00)
++padding;
return padding;
}
/// With the Stream Header at the very beginning of the file, LZMA_FORMAT_ERROR
/// is used to tell the application that Magic Bytes didn't match. In other
/// Stream Header/Footer fields (in the middle/end of the file) it could be
/// a bit confusing to return LZMA_FORMAT_ERROR as we already know that there
/// is a valid Stream Header at the beginning of the file. For those cases
/// this function is used to convert LZMA_FORMAT_ERROR to LZMA_DATA_ERROR.
static lzma_ret
hide_format_error(lzma_ret ret)
{
if (ret == LZMA_FORMAT_ERROR)
ret = LZMA_DATA_ERROR;
return ret;
}
/// Calls the Index decoder and updates coder->index_remaining.
/// This is a separate function because the input can be either directly
/// from the application or from coder->temp.
static lzma_ret
decode_index(lzma_file_info_coder *coder, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, bool update_file_cur_pos)
{
const size_t in_start = *in_pos;
const lzma_ret ret = coder->index_decoder.code(
coder->index_decoder.coder,
allocator, in, in_pos, in_size,
NULL, NULL, 0, LZMA_RUN);
coder->index_remaining -= *in_pos - in_start;
if (update_file_cur_pos)
coder->file_cur_pos += *in_pos - in_start;
return ret;
}
static lzma_ret
file_info_decode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size,
uint8_t *restrict out lzma_attribute((__unused__)),
size_t *restrict out_pos lzma_attribute((__unused__)),
size_t out_size lzma_attribute((__unused__)),
lzma_action action lzma_attribute((__unused__)))
{
lzma_file_info_coder *coder = coder_ptr;
const size_t in_start = *in_pos;
// If the caller provides input past the end of the file, trim
// the extra bytes from the buffer so that we won't read too far.
assert(coder->file_size >= coder->file_cur_pos);
if (coder->file_size - coder->file_cur_pos < in_size - in_start)
in_size = in_start
+ (size_t)(coder->file_size - coder->file_cur_pos);
while (true)
switch (coder->sequence) {
case SEQ_MAGIC_BYTES:
// Decode the Stream Header at the beginning of the file
// first to check if the Magic Bytes match. The flags
// are stored in coder->first_header_flags so that we
// don't need to seek to it again.
//
// Check that the file is big enough to contain at least
// Stream Header.
if (coder->file_size < LZMA_STREAM_HEADER_SIZE)
return LZMA_FORMAT_ERROR;
// Read the Stream Header field into coder->temp.
if (fill_temp(coder, in, in_pos, in_size))
return LZMA_OK;
// This is the only Stream Header/Footer decoding where we
// want to return LZMA_FORMAT_ERROR if the Magic Bytes don't
// match. Elsewehere it will be converted to LZMA_DATA_ERROR.
return_if_error(lzma_stream_header_decode(
&coder->first_header_flags, coder->temp));
// Now that we know that the Magic Bytes match, check the
// file size. It's better to do this here after checking the
// Magic Bytes since this way we can give LZMA_FORMAT_ERROR
// instead of LZMA_DATA_ERROR when the Magic Bytes don't
// match in a file that is too big or isn't a multiple of
// four bytes.
if (coder->file_size > LZMA_VLI_MAX || (coder->file_size & 3))
return LZMA_DATA_ERROR;
// Start looking for Stream Padding and Stream Footer
// at the end of the file.
coder->file_target_pos = coder->file_size;
// Fall through
case SEQ_PADDING_SEEK:
coder->sequence = SEQ_PADDING_DECODE;
return_if_error(reverse_seek(
coder, in_start, in_pos, in_size));
// Fall through
case SEQ_PADDING_DECODE: {
// Copy to coder->temp first. This keeps the code simpler if
// the application only provides input a few bytes at a time.
if (fill_temp(coder, in, in_pos, in_size))
return LZMA_OK;
// Scan the buffer backwards to get the size of the
// Stream Padding field (if any).
const size_t new_padding = get_padding_size(
coder->temp, coder->temp_size);
coder->stream_padding += new_padding;
// Set the target position to the beginning of Stream Padding
// that has been observed so far. If all Stream Padding has
// been seen, then the target position will be at the end
// of the Stream Footer field.
coder->file_target_pos -= new_padding;
if (new_padding == coder->temp_size) {
// The whole buffer was padding. Seek backwards in
// the file to get more input.
coder->sequence = SEQ_PADDING_SEEK;
break;
}
// Size of Stream Padding must be a multiple of 4 bytes.
if (coder->stream_padding & 3)
return LZMA_DATA_ERROR;
coder->sequence = SEQ_FOOTER;
// Calculate the amount of non-padding data in coder->temp.
coder->temp_size -= new_padding;
coder->temp_pos = coder->temp_size;
// We can avoid an external seek if the whole Stream Footer
// is already in coder->temp. In that case SEQ_FOOTER won't
// read more input and will find the Stream Footer from
// coder->temp[coder->temp_size - LZMA_STREAM_HEADER_SIZE].
//
// Otherwise we will need to seek. The seeking is done so
// that Stream Footer wil be at the end of coder->temp.
// This way it's likely that we also get a complete Index
// field into coder->temp without needing a separate seek
// for that (unless the Index field is big).
if (coder->temp_size < LZMA_STREAM_HEADER_SIZE)
return_if_error(reverse_seek(
coder, in_start, in_pos, in_size));
}
// Fall through
case SEQ_FOOTER:
// Copy the Stream Footer field into coder->temp.
// If Stream Footer was already available in coder->temp
// in SEQ_PADDING_DECODE, then this does nothing.
if (fill_temp(coder, in, in_pos, in_size))
return LZMA_OK;
// Make coder->file_target_pos and coder->temp_size point
// to the beginning of Stream Footer and thus to the end
// of the Index field. coder->temp_pos will be updated
// a bit later.
coder->file_target_pos -= LZMA_STREAM_HEADER_SIZE;
coder->temp_size -= LZMA_STREAM_HEADER_SIZE;
// Decode Stream Footer.
return_if_error(hide_format_error(lzma_stream_footer_decode(
&coder->footer_flags,
coder->temp + coder->temp_size)));
// Check that we won't seek past the beginning of the file.
//
// LZMA_STREAM_HEADER_SIZE is added because there must be
// space for Stream Header too even though we won't seek
// there before decoding the Index field.
//
// There's no risk of integer overflow here because
// Backward Size cannot be greater than 2^34.
if (coder->file_target_pos < coder->footer_flags.backward_size
+ LZMA_STREAM_HEADER_SIZE)
return LZMA_DATA_ERROR;
// Set the target position to the beginning of the Index field.
coder->file_target_pos -= coder->footer_flags.backward_size;
coder->sequence = SEQ_INDEX_INIT;
// We can avoid an external seek if the whole Index field is
// already available in coder->temp.
if (coder->temp_size >= coder->footer_flags.backward_size) {
// Set coder->temp_pos to point to the beginning
// of the Index.
coder->temp_pos = coder->temp_size
- coder->footer_flags.backward_size;
} else {
// These are set to zero to indicate that there's no
// useful data (Index or anything else) in coder->temp.
coder->temp_pos = 0;
coder->temp_size = 0;
// Seek to the beginning of the Index field.
if (seek_to_pos(coder, coder->file_target_pos,
in_start, in_pos, in_size))
return LZMA_SEEK_NEEDED;
}
// Fall through
case SEQ_INDEX_INIT: {
// Calculate the amount of memory already used by the earlier
// Indexes so that we know how big memory limit to pass to
// the Index decoder.
//
// NOTE: When there are multiple Streams, the separate
// lzma_index structures can use more RAM (as measured by
// lzma_index_memused()) than the final combined lzma_index.
// Thus memlimit may need to be slightly higher than the final
// calculated memory usage will be. This is perhaps a bit
// confusing to the application, but I think it shouldn't
// cause problems in practice.
uint64_t memused = 0;
if (coder->combined_index != NULL) {
memused = lzma_index_memused(coder->combined_index);
assert(memused <= coder->memlimit);
if (memused > coder->memlimit) // Extra sanity check
return LZMA_PROG_ERROR;
}
// Initialize the Index decoder.
return_if_error(lzma_index_decoder_init(
&coder->index_decoder, allocator,
&coder->this_index,
coder->memlimit - memused));
coder->index_remaining = coder->footer_flags.backward_size;
coder->sequence = SEQ_INDEX_DECODE;
}
// Fall through
case SEQ_INDEX_DECODE: {
// Decode (a part of) the Index. If the whole Index is already
// in coder->temp, read it from there. Otherwise read from
// in[*in_pos] onwards. Note that index_decode() updates
// coder->index_remaining and optionally coder->file_cur_pos.
lzma_ret ret;
if (coder->temp_size != 0) {
assert(coder->temp_size - coder->temp_pos
== coder->index_remaining);
ret = decode_index(coder, allocator, coder->temp,
&coder->temp_pos, coder->temp_size,
false);
} else {
// Don't give the decoder more input than the known
// remaining size of the Index field.
size_t in_stop = in_size;
if (in_size - *in_pos > coder->index_remaining)
in_stop = *in_pos
+ (size_t)(coder->index_remaining);
ret = decode_index(coder, allocator,
in, in_pos, in_stop, true);
}
switch (ret) {
case LZMA_OK:
// If the Index docoder asks for more input when we
// have already given it as much input as Backward Size
// indicated, the file is invalid.
if (coder->index_remaining == 0)
return LZMA_DATA_ERROR;
// We cannot get here if we were reading Index from
// coder->temp because when reading from coder->temp
// we give the Index decoder exactly
// coder->index_remaining bytes of input.
assert(coder->temp_size == 0);
return LZMA_OK;
case LZMA_STREAM_END:
// If the decoding seems to be successful, check also
// that the Index decoder consumed as much input as
// indicated by the Backward Size field.
if (coder->index_remaining != 0)
return LZMA_DATA_ERROR;
break;
default:
return ret;
}
// Calculate how much the Index tells us to seek backwards
// (relative to the beginning of the Index): Total size of
// all Blocks plus the size of the Stream Header field.
// No integer overflow here because lzma_index_total_size()
// cannot return a value greater than LZMA_VLI_MAX.
const uint64_t seek_amount
= lzma_index_total_size(coder->this_index)
+ LZMA_STREAM_HEADER_SIZE;
// Check that Index is sane in sense that seek_amount won't
// make us seek past the beginning of the file when locating
// the Stream Header.
//
// coder->file_target_pos still points to the beginning of
// the Index field.
if (coder->file_target_pos < seek_amount)
return LZMA_DATA_ERROR;
// Set the target to the beginning of Stream Header.
coder->file_target_pos -= seek_amount;
if (coder->file_target_pos == 0) {
// We would seek to the beginning of the file, but
// since we already decoded that Stream Header in
// SEQ_MAGIC_BYTES, we can use the cached value from
// coder->first_header_flags to avoid the seek.
coder->header_flags = coder->first_header_flags;
coder->sequence = SEQ_HEADER_COMPARE;
break;
}
coder->sequence = SEQ_HEADER_DECODE;
// Make coder->file_target_pos point to the end of
// the Stream Header field.
coder->file_target_pos += LZMA_STREAM_HEADER_SIZE;
// If coder->temp_size is non-zero, it points to the end
// of the Index field. Then the beginning of the Index
// field is at coder->temp[coder->temp_size
// - coder->footer_flags.backward_size].
assert(coder->temp_size == 0 || coder->temp_size
>= coder->footer_flags.backward_size);
// If coder->temp contained the whole Index, see if it has
// enough data to contain also the Stream Header. If so,
// we avoid an external seek.
//
// NOTE: This can happen only with small .xz files and only
// for the non-first Stream as the Stream Flags of the first
// Stream are cached and already handled a few lines above.
// So this isn't as useful as the other seek-avoidance cases.
if (coder->temp_size != 0 && coder->temp_size
- coder->footer_flags.backward_size
>= seek_amount) {
// Make temp_pos and temp_size point to the *end* of
// Stream Header so that SEQ_HEADER_DECODE will find
// the start of Stream Header from coder->temp[
// coder->temp_size - LZMA_STREAM_HEADER_SIZE].
coder->temp_pos = coder->temp_size
- coder->footer_flags.backward_size
- seek_amount
+ LZMA_STREAM_HEADER_SIZE;
coder->temp_size = coder->temp_pos;
} else {
// Seek so that Stream Header will be at the end of
// coder->temp. With typical multi-Stream files we
// will usually also get the Stream Footer and Index
// of the *previous* Stream in coder->temp and thus
// won't need a separate seek for them.
return_if_error(reverse_seek(coder,
in_start, in_pos, in_size));
}
}
// Fall through
case SEQ_HEADER_DECODE:
// Copy the Stream Header field into coder->temp.
// If Stream Header was already available in coder->temp
// in SEQ_INDEX_DECODE, then this does nothing.
if (fill_temp(coder, in, in_pos, in_size))
return LZMA_OK;
// Make all these point to the beginning of Stream Header.
coder->file_target_pos -= LZMA_STREAM_HEADER_SIZE;
coder->temp_size -= LZMA_STREAM_HEADER_SIZE;
coder->temp_pos = coder->temp_size;
// Decode the Stream Header.
return_if_error(hide_format_error(lzma_stream_header_decode(
&coder->header_flags,
coder->temp + coder->temp_size)));
coder->sequence = SEQ_HEADER_COMPARE;
// Fall through
case SEQ_HEADER_COMPARE:
// Compare Stream Header against Stream Footer. They must
// match.
return_if_error(lzma_stream_flags_compare(
&coder->header_flags, &coder->footer_flags));
// Store the decoded Stream Flags into the Index. Use the
// Footer Flags because it contains Backward Size, although
// it shouldn't matter in practice.
if (lzma_index_stream_flags(coder->this_index,
&coder->footer_flags) != LZMA_OK)
return LZMA_PROG_ERROR;
// Store also the size of the Stream Padding field. It is
// needed to calculate the offsets of the Streams correctly.
if (lzma_index_stream_padding(coder->this_index,
coder->stream_padding) != LZMA_OK)
return LZMA_PROG_ERROR;
// Reset it so that it's ready for the next Stream.
coder->stream_padding = 0;
// Append the earlier decoded Indexes after this_index.
if (coder->combined_index != NULL)
return_if_error(lzma_index_cat(coder->this_index,
coder->combined_index, allocator));
coder->combined_index = coder->this_index;
coder->this_index = NULL;
// If the whole file was decoded, tell the caller that we
// are finished.
if (coder->file_target_pos == 0) {
// The combined index must indicate the same file
// size as was told to us at initialization.
assert(lzma_index_file_size(coder->combined_index)
== coder->file_size);
// Make the combined index available to
// the application.
*coder->dest_index = coder->combined_index;
coder->combined_index = NULL;
// Mark the input buffer as used since we may have
// done internal seeking and thus don't know how
// many input bytes were actually used. This way
// lzma_stream.total_in gets a slightly better
// estimate of the amount of input used.
*in_pos = in_size;
return LZMA_STREAM_END;
}
// We didn't hit the beginning of the file yet, so continue
// reading backwards in the file. If we have unprocessed
// data in coder->temp, use it before requesting more data
// from the application.
//
// coder->file_target_pos, coder->temp_size, and
// coder->temp_pos all point to the beginning of Stream Header
// and thus the end of the previous Stream in the file.
coder->sequence = coder->temp_size > 0
? SEQ_PADDING_DECODE : SEQ_PADDING_SEEK;
break;
default:
assert(0);
return LZMA_PROG_ERROR;
}
}
static lzma_ret
file_info_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
uint64_t *old_memlimit, uint64_t new_memlimit)
{
lzma_file_info_coder *coder = coder_ptr;
// The memory usage calculation comes from three things:
//
// (1) The Indexes that have already been decoded and processed into
// coder->combined_index.
//
// (2) The latest Index in coder->this_index that has been decoded but
// not yet put into coder->combined_index.
//
// (3) The latest Index that we have started decoding but haven't
// finished and thus isn't available in coder->this_index yet.
// Memory usage and limit information needs to be communicated
// from/to coder->index_decoder.
//
// Care has to be taken to not do both (2) and (3) when calculating
// the memory usage.
uint64_t combined_index_memusage = 0;
uint64_t this_index_memusage = 0;
// (1) If we have already successfully decoded one or more Indexes,
// get their memory usage.
if (coder->combined_index != NULL)
combined_index_memusage = lzma_index_memused(
coder->combined_index);
// Choose between (2), (3), or neither.
if (coder->this_index != NULL) {
// (2) The latest Index is available. Use its memory usage.
this_index_memusage = lzma_index_memused(coder->this_index);
} else if (coder->sequence == SEQ_INDEX_DECODE) {
// (3) The Index decoder is activate and hasn't yet stored
// the new index in coder->this_index. Get the memory usage
// information from the Index decoder.
//
// NOTE: If the Index decoder doesn't yet know how much memory
// it will eventually need, it will return a tiny value here.
uint64_t dummy;
if (coder->index_decoder.memconfig(coder->index_decoder.coder,
&this_index_memusage, &dummy, 0)
!= LZMA_OK) {
assert(0);
return LZMA_PROG_ERROR;
}
}
// Now we know the total memory usage/requirement. If we had neither
// old Indexes nor a new Index, this will be zero which isn't
// acceptable as lzma_memusage() has to return non-zero on success
// and even with an empty .xz file we will end up with a lzma_index
// that takes some memory.
*memusage = combined_index_memusage + this_index_memusage;
if (*memusage == 0)
*memusage = lzma_index_memusage(1, 0);
*old_memlimit = coder->memlimit;
// If requested, set a new memory usage limit.
if (new_memlimit != 0) {
if (new_memlimit < *memusage)
return LZMA_MEMLIMIT_ERROR;
// In the condition (3) we need to tell the Index decoder
// its new memory usage limit.
if (coder->this_index == NULL
&& coder->sequence == SEQ_INDEX_DECODE) {
const uint64_t idec_new_memlimit = new_memlimit
- combined_index_memusage;
assert(this_index_memusage > 0);
assert(idec_new_memlimit > 0);
uint64_t dummy1;
uint64_t dummy2;
if (coder->index_decoder.memconfig(
coder->index_decoder.coder,
&dummy1, &dummy2, idec_new_memlimit)
!= LZMA_OK) {
assert(0);
return LZMA_PROG_ERROR;
}
}
coder->memlimit = new_memlimit;
}
return LZMA_OK;
}
static void
file_info_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_file_info_coder *coder = coder_ptr;
lzma_next_end(&coder->index_decoder, allocator);
lzma_index_end(coder->this_index, allocator);
lzma_index_end(coder->combined_index, allocator);
lzma_free(coder, allocator);
return;
}
static lzma_ret
lzma_file_info_decoder_init(lzma_next_coder *next,
const lzma_allocator *allocator, uint64_t *seek_pos,
lzma_index **dest_index,
uint64_t memlimit, uint64_t file_size)
{
lzma_next_coder_init(&lzma_file_info_decoder_init, next, allocator);
if (dest_index == NULL)
return LZMA_PROG_ERROR;
lzma_file_info_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_file_info_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &file_info_decode;
next->end = &file_info_decoder_end;
next->memconfig = &file_info_decoder_memconfig;
coder->index_decoder = LZMA_NEXT_CODER_INIT;
coder->this_index = NULL;
coder->combined_index = NULL;
}
coder->sequence = SEQ_MAGIC_BYTES;
coder->file_cur_pos = 0;
coder->file_target_pos = 0;
coder->file_size = file_size;
lzma_index_end(coder->this_index, allocator);
coder->this_index = NULL;
lzma_index_end(coder->combined_index, allocator);
coder->combined_index = NULL;
coder->stream_padding = 0;
coder->dest_index = dest_index;
coder->external_seek_pos = seek_pos;
// If memlimit is 0, make it 1 to ensure that lzma_memlimit_get()
// won't return 0 (which would indicate an error).
coder->memlimit = my_max(1, memlimit);
// Preprare thse for reading the first Stream Header into coder->temp.
coder->temp_pos = 0;
coder->temp_size = LZMA_STREAM_HEADER_SIZE;
return LZMA_OK;
}
extern LZMA_API(lzma_ret)
lzma_file_info_decoder(lzma_stream *strm, lzma_index **dest_index,
uint64_t memlimit, uint64_t file_size)
{
lzma_next_strm_init(lzma_file_info_decoder_init, strm, &strm->seek_pos,
dest_index, memlimit, file_size);
// We allow LZMA_FINISH in addition to LZMA_RUN for convenience.
// lzma_code() is able to handle the LZMA_FINISH + LZMA_SEEK_NEEDED
// combination in a sane way. Applications still need to be careful
// if they use LZMA_FINISH so that they remember to reset it back
// to LZMA_RUN after seeking if needed.
strm->internal->supported_actions[LZMA_RUN] = true;
strm->internal->supported_actions[LZMA_FINISH] = true;
return LZMA_OK;
}

View File

@@ -202,22 +202,21 @@ index_tree_node_end(index_tree_node *node, const lzma_allocator *allocator,
if (node->right != NULL)
index_tree_node_end(node->right, allocator, free_func);
if (free_func != NULL)
free_func(node, allocator);
lzma_free(node, allocator);
free_func(node, allocator);
return;
}
/// Free the meory allocated for a tree. If free_func is not NULL,
/// it is called on each node before freeing the node. This is used
/// to free the Record groups from each index_stream before freeing
/// the index_stream itself.
/// Free the memory allocated for a tree. Each node is freed using the
/// given free_func which is either &lzma_free or &index_stream_end.
/// The latter is used to free the Record groups from each index_stream
/// before freeing the index_stream itself.
static void
index_tree_end(index_tree *tree, const lzma_allocator *allocator,
void (*free_func)(void *node, const lzma_allocator *allocator))
{
assert(free_func != NULL);
if (tree->root != NULL)
index_tree_node_end(tree->root, allocator, free_func);
@@ -339,7 +338,7 @@ index_tree_locate(const index_tree *tree, lzma_vli target)
/// Allocate and initialize a new Stream using the given base offsets.
static index_stream *
index_stream_init(lzma_vli compressed_base, lzma_vli uncompressed_base,
lzma_vli stream_number, lzma_vli block_number_base,
uint32_t stream_number, lzma_vli block_number_base,
const lzma_allocator *allocator)
{
index_stream *s = lzma_alloc(sizeof(index_stream), allocator);
@@ -371,7 +370,8 @@ static void
index_stream_end(void *node, const lzma_allocator *allocator)
{
index_stream *s = node;
index_tree_end(&s->groups, allocator, NULL);
index_tree_end(&s->groups, allocator, &lzma_free);
lzma_free(s, allocator);
return;
}
@@ -829,6 +829,9 @@ lzma_index_cat(lzma_index *restrict dest, lzma_index *restrict src,
s->groups.rightmost = &newg->node;
lzma_free(g, allocator);
// NOTE: newg isn't leaked here because
// newg == (void *)&newg->node.
}
}
@@ -869,11 +872,8 @@ index_dup_stream(const index_stream *src, const lzma_allocator *allocator)
index_stream *dest = index_stream_init(src->node.compressed_base,
src->node.uncompressed_base, src->number,
src->block_number_base, allocator);
// Return immediately if allocation failed or if there are
// no groups to duplicate.
if (dest == NULL || src->groups.leftmost == NULL)
return dest;
if (dest == NULL)
return NULL;
// Copy the overall information.
dest->record_count = src->record_count;
@@ -881,6 +881,10 @@ index_dup_stream(const index_stream *src, const lzma_allocator *allocator)
dest->stream_flags = src->stream_flags;
dest->stream_padding = src->stream_padding;
// Return if there are no groups to duplicate.
if (src->groups.leftmost == NULL)
return dest;
// Allocate memory for the Records. We put all the Records into
// a single group. It's simplest and also tends to make
// lzma_index_locate() a little bit faster with very big Indexes.
@@ -1008,6 +1012,8 @@ iter_set_info(lzma_index_iter *iter)
iter->internal[ITER_GROUP].p = NULL;
}
// NOTE: lzma_index_iter.stream.number is lzma_vli but we use uint32_t
// internally.
iter->stream.number = stream->number;
iter->stream.block_count = stream->record_count;
iter->stream.compressed_offset = stream->node.compressed_base;

View File

@@ -10,11 +10,11 @@
//
///////////////////////////////////////////////////////////////////////////////
#include "index.h"
#include "index_decoder.h"
#include "check.h"
struct lzma_coder_s {
typedef struct {
enum {
SEQ_INDICATOR,
SEQ_COUNT,
@@ -50,11 +50,11 @@ struct lzma_coder_s {
/// CRC32 of the List of Records field
uint32_t crc32;
};
} lzma_index_coder;
static lzma_ret
index_decode(lzma_coder *coder, const lzma_allocator *allocator,
index_decode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size,
uint8_t *restrict out lzma_attribute((__unused__)),
@@ -62,6 +62,8 @@ index_decode(lzma_coder *coder, const lzma_allocator *allocator,
size_t out_size lzma_attribute((__unused__)),
lzma_action action lzma_attribute((__unused__)))
{
lzma_index_coder *coder = coder_ptr;
// Similar optimization as in index_encoder.c
const size_t in_start = *in_pos;
lzma_ret ret = LZMA_OK;
@@ -207,8 +209,9 @@ out:
static void
index_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
index_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_index_coder *coder = coder_ptr;
lzma_index_end(coder->index, allocator);
lzma_free(coder, allocator);
return;
@@ -216,9 +219,11 @@ index_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
index_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
index_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
uint64_t *old_memlimit, uint64_t new_memlimit)
{
lzma_index_coder *coder = coder_ptr;
*memusage = lzma_index_memusage(1, coder->count);
*old_memlimit = coder->memlimit;
@@ -234,7 +239,7 @@ index_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
static lzma_ret
index_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator,
index_decoder_reset(lzma_index_coder *coder, const lzma_allocator *allocator,
lzma_index **i, uint64_t memlimit)
{
// Remember the pointer given by the application. We will set it
@@ -251,7 +256,7 @@ index_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator,
// Initialize the rest.
coder->sequence = SEQ_INDICATOR;
coder->memlimit = memlimit;
coder->memlimit = my_max(1, memlimit);
coder->count = 0; // Needs to be initialized due to _memconfig().
coder->pos = 0;
coder->crc32 = 0;
@@ -260,36 +265,38 @@ index_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator,
}
static lzma_ret
index_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
extern lzma_ret
lzma_index_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
lzma_index **i, uint64_t memlimit)
{
lzma_next_coder_init(&index_decoder_init, next, allocator);
lzma_next_coder_init(&lzma_index_decoder_init, next, allocator);
if (i == NULL || memlimit == 0)
if (i == NULL)
return LZMA_PROG_ERROR;
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_index_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_index_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &index_decode;
next->end = &index_decoder_end;
next->memconfig = &index_decoder_memconfig;
next->coder->index = NULL;
coder->index = NULL;
} else {
lzma_index_end(next->coder->index, allocator);
lzma_index_end(coder->index, allocator);
}
return index_decoder_reset(next->coder, allocator, i, memlimit);
return index_decoder_reset(coder, allocator, i, memlimit);
}
extern LZMA_API(lzma_ret)
lzma_index_decoder(lzma_stream *strm, lzma_index **i, uint64_t memlimit)
{
lzma_next_strm_init(index_decoder_init, strm, i, memlimit);
lzma_next_strm_init(lzma_index_decoder_init, strm, i, memlimit);
strm->internal->supported_actions[LZMA_RUN] = true;
strm->internal->supported_actions[LZMA_FINISH] = true;
@@ -309,7 +316,7 @@ lzma_index_buffer_decode(lzma_index **i, uint64_t *memlimit,
return LZMA_PROG_ERROR;
// Initialize the decoder.
lzma_coder coder;
lzma_index_coder coder;
return_if_error(index_decoder_reset(&coder, allocator, i, *memlimit));
// Store the input start position so that we can restore it in case

View File

@@ -0,0 +1,24 @@
///////////////////////////////////////////////////////////////////////////////
//
/// \file index_decoder.h
/// \brief Decodes the Index field
//
// Author: Lasse Collin
//
// This file has been put into the public domain.
// You can do whatever you want with this file.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef LZMA_INDEX_DECODER_H
#define LZMA_INDEX_DECODER_H
#include "index.h"
extern lzma_ret lzma_index_decoder_init(lzma_next_coder *next,
const lzma_allocator *allocator,
lzma_index **i, uint64_t memlimit);
#endif

View File

@@ -15,7 +15,7 @@
#include "check.h"
struct lzma_coder_s {
typedef struct {
enum {
SEQ_INDICATOR,
SEQ_COUNT,
@@ -37,11 +37,11 @@ struct lzma_coder_s {
/// CRC32 of the List of Records field
uint32_t crc32;
};
} lzma_index_coder;
static lzma_ret
index_encode(lzma_coder *coder,
index_encode(void *coder_ptr,
const lzma_allocator *allocator lzma_attribute((__unused__)),
const uint8_t *restrict in lzma_attribute((__unused__)),
size_t *restrict in_pos lzma_attribute((__unused__)),
@@ -50,6 +50,8 @@ index_encode(lzma_coder *coder,
size_t out_size,
lzma_action action lzma_attribute((__unused__)))
{
lzma_index_coder *coder = coder_ptr;
// Position where to start calculating CRC32. The idea is that we
// need to call lzma_crc32() only once per call to index_encode().
const size_t out_start = *out_pos;
@@ -159,7 +161,7 @@ out:
static void
index_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
index_encoder_end(void *coder, const lzma_allocator *allocator)
{
lzma_free(coder, allocator);
return;
@@ -167,7 +169,7 @@ index_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static void
index_encoder_reset(lzma_coder *coder, const lzma_index *i)
index_encoder_reset(lzma_index_coder *coder, const lzma_index *i)
{
lzma_index_iter_init(&coder->iter, i);
@@ -190,7 +192,7 @@ lzma_index_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
return LZMA_PROG_ERROR;
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
next->coder = lzma_alloc(sizeof(lzma_index_coder), allocator);
if (next->coder == NULL)
return LZMA_MEM_ERROR;
@@ -230,7 +232,7 @@ lzma_index_buffer_encode(const lzma_index *i,
// The Index encoder needs just one small data structure so we can
// allocate it on stack.
lzma_coder coder;
lzma_index_coder coder;
index_encoder_reset(&coder, i);
// Do the actual encoding. This should never fail, but store

View File

@@ -19,11 +19,6 @@
# include <immintrin.h>
#endif
/// How many extra bytes lzma_memcmplen() may read. This depends on
/// the method but since it is just a few bytes the biggest possible
/// value is used here.
#define LZMA_MEMCMPLEN_EXTRA 16
/// Find out how many equal bytes the two buffers have.
///
@@ -39,6 +34,11 @@
///
/// \return Number of equal bytes in the buffers is returned.
/// This is always at least len and at most limit.
///
/// \note LZMA_MEMCMPLEN_EXTRA defines how many extra bytes may be read.
/// It's rounded up to 2^n. This extra amount needs to be
/// allocated in the buffers being used. It needs to be
/// initialized too to keep Valgrind quiet.
static inline uint32_t lzma_attribute((__always_inline__))
lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
uint32_t len, uint32_t limit)
@@ -59,6 +59,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
// to be a good method. This may be fine on other 64-bit CPUs too.
// On big endian one should use xor instead of subtraction and switch
// to __builtin_clzll().
#define LZMA_MEMCMPLEN_EXTRA 8
while (len < limit) {
const uint64_t x = *(const uint64_t *)(buf1 + len)
- *(const uint64_t *)(buf2 + len);
@@ -91,6 +92,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
// version is sometimes significantly faster and sometimes
// slightly slower than this SSE2 version, so this SSE2
// version isn't used on x86-64.
# define LZMA_MEMCMPLEN_EXTRA 16
while (len < limit) {
const uint32_t x = 0xFFFF ^ _mm_movemask_epi8(_mm_cmpeq_epi8(
_mm_loadu_si128((const __m128i *)(buf1 + len)),
@@ -116,6 +118,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && !defined(WORDS_BIGENDIAN)
// Generic 32-bit little endian method
# define LZMA_MEMCMPLEN_EXTRA 4
while (len < limit) {
uint32_t x = *(const uint32_t *)(buf1 + len)
- *(const uint32_t *)(buf2 + len);
@@ -138,6 +141,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && defined(WORDS_BIGENDIAN)
// Generic 32-bit big endian method
# define LZMA_MEMCMPLEN_EXTRA 4
while (len < limit) {
uint32_t x = *(const uint32_t *)(buf1 + len)
^ *(const uint32_t *)(buf2 + len);
@@ -160,6 +164,7 @@ lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
#else
// Simple portable version that doesn't use unaligned access.
# define LZMA_MEMCMPLEN_EXTRA 0
while (len < limit && buf1[len] == buf2[len])
++len;

View File

@@ -14,7 +14,7 @@
#include "block_decoder.h"
struct lzma_coder_s {
typedef struct {
enum {
SEQ_STREAM_HEADER,
SEQ_BLOCK_HEADER,
@@ -80,11 +80,11 @@ struct lzma_coder_s {
/// Buffer to hold Stream Header, Block Header, and Stream Footer.
/// Block Header has biggest maximum size.
uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX];
};
} lzma_stream_coder;
static lzma_ret
stream_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator)
stream_decoder_reset(lzma_stream_coder *coder, const lzma_allocator *allocator)
{
// Initialize the Index hash used to verify the Index.
coder->index_hash = lzma_index_hash_init(coder->index_hash, allocator);
@@ -100,11 +100,13 @@ stream_decoder_reset(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
stream_decode(lzma_coder *coder, const lzma_allocator *allocator,
stream_decode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_stream_coder *coder = coder_ptr;
// When decoding the actual Block, it may be able to produce more
// output even if we don't give it any new input.
while (true)
@@ -375,8 +377,9 @@ stream_decode(lzma_coder *coder, const lzma_allocator *allocator,
static void
stream_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
stream_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_stream_coder *coder = coder_ptr;
lzma_next_end(&coder->block_decoder, allocator);
lzma_index_hash_end(coder->index_hash, allocator);
lzma_free(coder, allocator);
@@ -385,16 +388,19 @@ stream_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_check
stream_decoder_get_check(const lzma_coder *coder)
stream_decoder_get_check(const void *coder_ptr)
{
const lzma_stream_coder *coder = coder_ptr;
return coder->stream_flags.check;
}
static lzma_ret
stream_decoder_memconfig(lzma_coder *coder, uint64_t *memusage,
stream_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
uint64_t *old_memlimit, uint64_t new_memlimit)
{
lzma_stream_coder *coder = coder_ptr;
*memusage = coder->memusage;
*old_memlimit = coder->memlimit;
@@ -416,37 +422,36 @@ lzma_stream_decoder_init(
{
lzma_next_coder_init(&lzma_stream_decoder_init, next, allocator);
if (memlimit == 0)
return LZMA_PROG_ERROR;
if (flags & ~LZMA_SUPPORTED_FLAGS)
return LZMA_OPTIONS_ERROR;
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_stream_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_stream_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &stream_decode;
next->end = &stream_decoder_end;
next->get_check = &stream_decoder_get_check;
next->memconfig = &stream_decoder_memconfig;
next->coder->block_decoder = LZMA_NEXT_CODER_INIT;
next->coder->index_hash = NULL;
coder->block_decoder = LZMA_NEXT_CODER_INIT;
coder->index_hash = NULL;
}
next->coder->memlimit = memlimit;
next->coder->memusage = LZMA_MEMUSAGE_BASE;
next->coder->tell_no_check = (flags & LZMA_TELL_NO_CHECK) != 0;
next->coder->tell_unsupported_check
coder->memlimit = my_max(1, memlimit);
coder->memusage = LZMA_MEMUSAGE_BASE;
coder->tell_no_check = (flags & LZMA_TELL_NO_CHECK) != 0;
coder->tell_unsupported_check
= (flags & LZMA_TELL_UNSUPPORTED_CHECK) != 0;
next->coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0;
next->coder->ignore_check = (flags & LZMA_IGNORE_CHECK) != 0;
next->coder->concatenated = (flags & LZMA_CONCATENATED) != 0;
next->coder->first_stream = true;
coder->tell_any_check = (flags & LZMA_TELL_ANY_CHECK) != 0;
coder->ignore_check = (flags & LZMA_IGNORE_CHECK) != 0;
coder->concatenated = (flags & LZMA_CONCATENATED) != 0;
coder->first_stream = true;
return stream_decoder_reset(next->coder, allocator);
return stream_decoder_reset(coder, allocator);
}

View File

@@ -14,7 +14,7 @@
#include "index_encoder.h"
struct lzma_coder_s {
typedef struct {
enum {
SEQ_STREAM_HEADER,
SEQ_BLOCK_INIT,
@@ -55,11 +55,11 @@ struct lzma_coder_s {
/// Buffer to hold Stream Header, Block Header, and Stream Footer.
/// Block Header has biggest maximum size.
uint8_t buffer[LZMA_BLOCK_HEADER_SIZE_MAX];
};
} lzma_stream_coder;
static lzma_ret
block_encoder_init(lzma_coder *coder, const lzma_allocator *allocator)
block_encoder_init(lzma_stream_coder *coder, const lzma_allocator *allocator)
{
// Prepare the Block options. Even though Block encoder doesn't need
// compressed_size, uncompressed_size, and header_size to be
@@ -78,11 +78,13 @@ block_encoder_init(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
stream_encode(lzma_coder *coder, const lzma_allocator *allocator,
stream_encode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_stream_coder *coder = coder_ptr;
// Main loop
while (*out_pos < out_size)
switch (coder->sequence) {
@@ -209,8 +211,10 @@ stream_encode(lzma_coder *coder, const lzma_allocator *allocator,
static void
stream_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
stream_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_stream_coder *coder = coder_ptr;
lzma_next_end(&coder->block_encoder, allocator);
lzma_next_end(&coder->index_encoder, allocator);
lzma_index_end(coder->index, allocator);
@@ -224,10 +228,12 @@ stream_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
stream_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
stream_encoder_update(void *coder_ptr, const lzma_allocator *allocator,
const lzma_filter *filters,
const lzma_filter *reversed_filters)
{
lzma_stream_coder *coder = coder_ptr;
if (coder->sequence <= SEQ_BLOCK_INIT) {
// There is no incomplete Block waiting to be finished,
// thus we can change the whole filter chain. Start by
@@ -271,30 +277,33 @@ stream_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
if (filters == NULL)
return LZMA_PROG_ERROR;
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_stream_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_stream_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &stream_encode;
next->end = &stream_encoder_end;
next->update = &stream_encoder_update;
next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
next->coder->block_encoder = LZMA_NEXT_CODER_INIT;
next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
next->coder->index = NULL;
coder->filters[0].id = LZMA_VLI_UNKNOWN;
coder->block_encoder = LZMA_NEXT_CODER_INIT;
coder->index_encoder = LZMA_NEXT_CODER_INIT;
coder->index = NULL;
}
// Basic initializations
next->coder->sequence = SEQ_STREAM_HEADER;
next->coder->block_options.version = 0;
next->coder->block_options.check = check;
coder->sequence = SEQ_STREAM_HEADER;
coder->block_options.version = 0;
coder->block_options.check = check;
// Initialize the Index
lzma_index_end(next->coder->index, allocator);
next->coder->index = lzma_index_init(allocator);
if (next->coder->index == NULL)
lzma_index_end(coder->index, allocator);
coder->index = lzma_index_init(allocator);
if (coder->index == NULL)
return LZMA_MEM_ERROR;
// Encode the Stream Header
@@ -303,16 +312,15 @@ stream_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
.check = check,
};
return_if_error(lzma_stream_header_encode(
&stream_flags, next->coder->buffer));
&stream_flags, coder->buffer));
next->coder->buffer_pos = 0;
next->coder->buffer_size = LZMA_STREAM_HEADER_SIZE;
coder->buffer_pos = 0;
coder->buffer_size = LZMA_STREAM_HEADER_SIZE;
// Initialize the Block encoder. This way we detect unsupported
// filter chains when initializing the Stream encoder instead of
// giving an error after Stream Header has already written out.
return stream_encoder_update(
next->coder, allocator, filters, NULL);
return stream_encoder_update(coder, allocator, filters, NULL);
}

View File

@@ -44,6 +44,7 @@ typedef enum {
} worker_state;
typedef struct lzma_stream_coder_s lzma_stream_coder;
typedef struct worker_thread_s worker_thread;
struct worker_thread_s {
@@ -65,7 +66,7 @@ struct worker_thread_s {
/// Pointer to the main structure is needed when putting this
/// thread back to the stack of free threads.
lzma_coder *coder;
lzma_stream_coder *coder;
/// The allocator is set by the main thread. Since a copy of the
/// pointer is kept here, the application must not change the
@@ -96,7 +97,7 @@ struct worker_thread_s {
};
struct lzma_coder_s {
struct lzma_stream_coder_s {
enum {
SEQ_STREAM_HEADER,
SEQ_BLOCK,
@@ -417,7 +418,7 @@ worker_start(void *thr_ptr)
/// Make the threads stop but not exit. Optionally wait for them to stop.
static void
threads_stop(lzma_coder *coder, bool wait_for_threads)
threads_stop(lzma_stream_coder *coder, bool wait_for_threads)
{
// Tell the threads to stop.
for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
@@ -446,7 +447,7 @@ threads_stop(lzma_coder *coder, bool wait_for_threads)
/// Stop the threads and free the resources associated with them.
/// Wait until the threads have exited.
static void
threads_end(lzma_coder *coder, const lzma_allocator *allocator)
threads_end(lzma_stream_coder *coder, const lzma_allocator *allocator)
{
for (uint32_t i = 0; i < coder->threads_initialized; ++i) {
mythread_sync(coder->threads[i].mutex) {
@@ -468,7 +469,8 @@ threads_end(lzma_coder *coder, const lzma_allocator *allocator)
/// Initialize a new worker_thread structure and create a new thread.
static lzma_ret
initialize_new_thread(lzma_coder *coder, const lzma_allocator *allocator)
initialize_new_thread(lzma_stream_coder *coder,
const lzma_allocator *allocator)
{
worker_thread *thr = &coder->threads[coder->threads_initialized];
@@ -510,7 +512,7 @@ error_mutex:
static lzma_ret
get_thread(lzma_coder *coder, const lzma_allocator *allocator)
get_thread(lzma_stream_coder *coder, const lzma_allocator *allocator)
{
// If there are no free output subqueues, there is no
// point to try getting a thread.
@@ -548,7 +550,7 @@ get_thread(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
stream_encode_in(lzma_coder *coder, const lzma_allocator *allocator,
stream_encode_in(lzma_stream_coder *coder, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, lzma_action action)
{
@@ -616,7 +618,7 @@ stream_encode_in(lzma_coder *coder, const lzma_allocator *allocator,
/// Wait until more input can be consumed, more output can be read, or
/// an optional timeout is reached.
static bool
wait_for_work(lzma_coder *coder, mythread_condtime *wait_abs,
wait_for_work(lzma_stream_coder *coder, mythread_condtime *wait_abs,
bool *has_blocked, bool has_input)
{
if (coder->timeout != 0 && !*has_blocked) {
@@ -662,11 +664,13 @@ wait_for_work(lzma_coder *coder, mythread_condtime *wait_abs,
static lzma_ret
stream_encode_mt(lzma_coder *coder, const lzma_allocator *allocator,
stream_encode_mt(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_stream_coder *coder = coder_ptr;
switch (coder->sequence) {
case SEQ_STREAM_HEADER:
lzma_bufcpy(coder->header, &coder->header_pos,
@@ -834,8 +838,10 @@ stream_encode_mt(lzma_coder *coder, const lzma_allocator *allocator,
static void
stream_encoder_mt_end(lzma_coder *coder, const lzma_allocator *allocator)
stream_encoder_mt_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_stream_coder *coder = coder_ptr;
// Threads must be killed before the output queue can be freed.
threads_end(coder, allocator);
lzma_outq_end(&coder->outq, allocator);
@@ -907,10 +913,12 @@ get_options(const lzma_mt *options, lzma_options_easy *opt_easy,
static void
get_progress(lzma_coder *coder, uint64_t *progress_in, uint64_t *progress_out)
get_progress(void *coder_ptr, uint64_t *progress_in, uint64_t *progress_out)
{
lzma_stream_coder *coder = coder_ptr;
// Lock coder->mutex to prevent finishing threads from moving their
// progress info from the worker_thread structure to lzma_coder.
// progress info from the worker_thread structure to lzma_stream_coder.
mythread_sync(coder->mutex) {
*progress_in = coder->progress_in;
*progress_out = coder->progress_out;
@@ -947,9 +955,12 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
return LZMA_MEM_ERROR;
#endif
// FIXME TODO: Validate the filter chain so that we can give
// an error in this function instead of delaying it to the first
// call to lzma_code().
// Validate the filter chain so that we can give an error in this
// function instead of delaying it to the first call to lzma_code().
// The memory usage calculation verifies the filter chain as
// a side effect so we take advatange of that.
if (lzma_raw_encoder_memusage(filters) == UINT64_MAX)
return LZMA_OPTIONS_ERROR;
// Validate the Check ID.
if ((unsigned int)(options->check) > LZMA_CHECK_ID_MAX)
@@ -959,24 +970,27 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
return LZMA_UNSUPPORTED_CHECK;
// Allocate and initialize the base structure if needed.
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_stream_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_stream_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
// For the mutex and condition variable initializations
// the error handling has to be done here because
// stream_encoder_mt_end() doesn't know if they have
// already been initialized or not.
if (mythread_mutex_init(&next->coder->mutex)) {
lzma_free(next->coder, allocator);
if (mythread_mutex_init(&coder->mutex)) {
lzma_free(coder, allocator);
next->coder = NULL;
return LZMA_MEM_ERROR;
}
if (mythread_cond_init(&next->coder->cond)) {
mythread_mutex_destroy(&next->coder->mutex);
lzma_free(next->coder, allocator);
if (mythread_cond_init(&coder->cond)) {
mythread_mutex_destroy(&coder->mutex);
lzma_free(coder, allocator);
next->coder = NULL;
return LZMA_MEM_ERROR;
}
@@ -986,76 +1000,76 @@ stream_encoder_mt_init(lzma_next_coder *next, const lzma_allocator *allocator,
next->get_progress = &get_progress;
// next->update = &stream_encoder_mt_update;
next->coder->filters[0].id = LZMA_VLI_UNKNOWN;
next->coder->index_encoder = LZMA_NEXT_CODER_INIT;
next->coder->index = NULL;
memzero(&next->coder->outq, sizeof(next->coder->outq));
next->coder->threads = NULL;
next->coder->threads_max = 0;
next->coder->threads_initialized = 0;
coder->filters[0].id = LZMA_VLI_UNKNOWN;
coder->index_encoder = LZMA_NEXT_CODER_INIT;
coder->index = NULL;
memzero(&coder->outq, sizeof(coder->outq));
coder->threads = NULL;
coder->threads_max = 0;
coder->threads_initialized = 0;
}
// Basic initializations
next->coder->sequence = SEQ_STREAM_HEADER;
next->coder->block_size = (size_t)(block_size);
next->coder->thread_error = LZMA_OK;
next->coder->thr = NULL;
coder->sequence = SEQ_STREAM_HEADER;
coder->block_size = (size_t)(block_size);
coder->thread_error = LZMA_OK;
coder->thr = NULL;
// Allocate the thread-specific base structures.
assert(options->threads > 0);
if (next->coder->threads_max != options->threads) {
threads_end(next->coder, allocator);
if (coder->threads_max != options->threads) {
threads_end(coder, allocator);
next->coder->threads = NULL;
next->coder->threads_max = 0;
coder->threads = NULL;
coder->threads_max = 0;
next->coder->threads_initialized = 0;
next->coder->threads_free = NULL;
coder->threads_initialized = 0;
coder->threads_free = NULL;
next->coder->threads = lzma_alloc(
coder->threads = lzma_alloc(
options->threads * sizeof(worker_thread),
allocator);
if (next->coder->threads == NULL)
if (coder->threads == NULL)
return LZMA_MEM_ERROR;
next->coder->threads_max = options->threads;
coder->threads_max = options->threads;
} else {
// Reuse the old structures and threads. Tell the running
// threads to stop and wait until they have stopped.
threads_stop(next->coder, true);
threads_stop(coder, true);
}
// Output queue
return_if_error(lzma_outq_init(&next->coder->outq, allocator,
return_if_error(lzma_outq_init(&coder->outq, allocator,
outbuf_size_max, options->threads));
// Timeout
next->coder->timeout = options->timeout;
coder->timeout = options->timeout;
// Free the old filter chain and copy the new one.
for (size_t i = 0; next->coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
lzma_free(next->coder->filters[i].options, allocator);
for (size_t i = 0; coder->filters[i].id != LZMA_VLI_UNKNOWN; ++i)
lzma_free(coder->filters[i].options, allocator);
return_if_error(lzma_filters_copy(
filters, next->coder->filters, allocator));
filters, coder->filters, allocator));
// Index
lzma_index_end(next->coder->index, allocator);
next->coder->index = lzma_index_init(allocator);
if (next->coder->index == NULL)
lzma_index_end(coder->index, allocator);
coder->index = lzma_index_init(allocator);
if (coder->index == NULL)
return LZMA_MEM_ERROR;
// Stream Header
next->coder->stream_flags.version = 0;
next->coder->stream_flags.check = options->check;
coder->stream_flags.version = 0;
coder->stream_flags.check = options->check;
return_if_error(lzma_stream_header_encode(
&next->coder->stream_flags, next->coder->header));
&coder->stream_flags, coder->header));
next->coder->header_pos = 0;
coder->header_pos = 0;
// Progress info
next->coder->progress_in = 0;
next->coder->progress_out = LZMA_STREAM_HEADER_SIZE;
coder->progress_in = 0;
coder->progress_out = LZMA_STREAM_HEADER_SIZE;
return LZMA_OK;
}
@@ -1095,8 +1109,7 @@ lzma_stream_encoder_mt_memusage(const lzma_mt *options)
const uint64_t inbuf_memusage = options->threads * block_size;
// Memory usage of the filter encoders
uint64_t filters_memusage
= lzma_raw_encoder_memusage(options->filters);
uint64_t filters_memusage = lzma_raw_encoder_memusage(filters);
if (filters_memusage == UINT64_MAX)
return UINT64_MAX;
@@ -1109,7 +1122,8 @@ lzma_stream_encoder_mt_memusage(const lzma_mt *options)
return UINT64_MAX;
// Sum them with overflow checking.
uint64_t total_memusage = LZMA_MEMUSAGE_BASE + sizeof(lzma_coder)
uint64_t total_memusage = LZMA_MEMUSAGE_BASE
+ sizeof(lzma_stream_coder)
+ options->threads * sizeof(worker_thread);
if (UINT64_MAX - total_memusage < inbuf_memusage)

View File

@@ -15,8 +15,9 @@
static void
delta_coder_end(lzma_coder *coder, const lzma_allocator *allocator)
delta_coder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_delta_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
@@ -28,14 +29,17 @@ lzma_delta_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
const lzma_filter_info *filters)
{
// Allocate memory for the decoder if needed.
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_delta_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_delta_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
// End function is the same for encoder and decoder.
next->end = &delta_coder_end;
next->coder->next = LZMA_NEXT_CODER_INIT;
coder->next = LZMA_NEXT_CODER_INIT;
}
// Validate the options.
@@ -44,15 +48,14 @@ lzma_delta_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
// Set the delta distance.
const lzma_options_delta *opt = filters[0].options;
next->coder->distance = opt->dist;
coder->distance = opt->dist;
// Initialize the rest of the variables.
next->coder->pos = 0;
memzero(next->coder->history, LZMA_DELTA_DIST_MAX);
coder->pos = 0;
memzero(coder->history, LZMA_DELTA_DIST_MAX);
// Initialize the next decoder in the chain, if any.
return lzma_next_filter_init(&next->coder->next,
allocator, filters + 1);
return lzma_next_filter_init(&coder->next, allocator, filters + 1);
}
@@ -66,5 +69,5 @@ lzma_delta_coder_memusage(const void *options)
|| opt->dist > LZMA_DELTA_DIST_MAX)
return UINT64_MAX;
return sizeof(lzma_coder);
return sizeof(lzma_delta_coder);
}

View File

@@ -15,7 +15,7 @@
static void
decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size)
decode_buffer(lzma_delta_coder *coder, uint8_t *buffer, size_t size)
{
const size_t distance = coder->distance;
@@ -27,11 +27,13 @@ decode_buffer(lzma_coder *coder, uint8_t *buffer, size_t size)
static lzma_ret
delta_decode(lzma_coder *coder, const lzma_allocator *allocator,
delta_decode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_delta_coder *coder = coder_ptr;
assert(coder->next.code != NULL);
const size_t out_start = *out_pos;

View File

@@ -18,7 +18,7 @@
/// is the first filter in the chain (and thus the last filter in the
/// encoder's filter stack).
static void
copy_and_encode(lzma_coder *coder,
copy_and_encode(lzma_delta_coder *coder,
const uint8_t *restrict in, uint8_t *restrict out, size_t size)
{
const size_t distance = coder->distance;
@@ -35,7 +35,7 @@ copy_and_encode(lzma_coder *coder,
/// Encodes the data in place. This is used when we are the last filter
/// in the chain (and thus non-last filter in the encoder's filter stack).
static void
encode_in_place(lzma_coder *coder, uint8_t *buffer, size_t size)
encode_in_place(lzma_delta_coder *coder, uint8_t *buffer, size_t size)
{
const size_t distance = coder->distance;
@@ -49,11 +49,13 @@ encode_in_place(lzma_coder *coder, uint8_t *buffer, size_t size)
static lzma_ret
delta_encode(lzma_coder *coder, const lzma_allocator *allocator,
delta_encode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_delta_coder *coder = coder_ptr;
lzma_ret ret;
if (coder->next.code == NULL) {
@@ -84,10 +86,12 @@ delta_encode(lzma_coder *coder, const lzma_allocator *allocator,
static lzma_ret
delta_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
delta_encoder_update(void *coder_ptr, const lzma_allocator *allocator,
const lzma_filter *filters_null lzma_attribute((__unused__)),
const lzma_filter *reversed_filters)
{
lzma_delta_coder *coder = coder_ptr;
// Delta doesn't and will never support changing the options in
// the middle of encoding. If the app tries to change them, we
// simply ignore them.

View File

@@ -15,7 +15,7 @@
#include "delta_common.h"
struct lzma_coder_s {
typedef struct {
/// Next coder in the chain
lzma_next_coder next;
@@ -27,7 +27,7 @@ struct lzma_coder_s {
/// Buffer to hold history of the original data
uint8_t history[LZMA_DELTA_DIST_MAX];
};
} lzma_delta_coder;
extern lzma_ret lzma_delta_coder_init(

View File

@@ -95,14 +95,19 @@ global:
lzma_vli_size;
};
XZ_5.1.4beta {
XZ_5.2 {
global:
lzma_block_uncomp_encode;
lzma_cputhreads;
lzma_get_progress;
lzma_stream_encoder_mt;
lzma_stream_encoder_mt_memusage;
} XZ_5.0;
XZ_5.3.1alpha {
global:
lzma_file_info_decoder;
local:
*;
} XZ_5.0;
} XZ_5.2;

View File

@@ -20,7 +20,7 @@
#include "lz_decoder.h"
struct lzma_coder_s {
typedef struct {
/// Dictionary (history buffer)
lzma_dict dict;
@@ -48,7 +48,7 @@ struct lzma_coder_s {
size_t size;
uint8_t buffer[LZMA_BUFFER_SIZE];
} temp;
};
} lzma_coder;
static void
@@ -125,13 +125,15 @@ decode_buffer(lzma_coder *coder,
static lzma_ret
lz_decode(lzma_coder *coder,
lz_decode(void *coder_ptr,
const lzma_allocator *allocator lzma_attribute((__unused__)),
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
lzma_action action)
{
lzma_coder *coder = coder_ptr;
if (coder->next.code == NULL)
return decode_buffer(coder, in, in_pos, in_size,
out, out_pos, out_size);
@@ -184,8 +186,10 @@ lz_decode(lzma_coder *coder,
static void
lz_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
lz_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder->dict.buf, allocator);
@@ -207,24 +211,26 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
lzma_lz_options *lz_options))
{
// Allocate the base structure if it isn't already allocated.
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &lz_decode;
next->end = &lz_decoder_end;
next->coder->dict.buf = NULL;
next->coder->dict.size = 0;
next->coder->lz = LZMA_LZ_DECODER_INIT;
next->coder->next = LZMA_NEXT_CODER_INIT;
coder->dict.buf = NULL;
coder->dict.size = 0;
coder->lz = LZMA_LZ_DECODER_INIT;
coder->next = LZMA_NEXT_CODER_INIT;
}
// Allocate and initialize the LZ-based decoder. It will also give
// us the dictionary size.
lzma_lz_options lz_options;
return_if_error(lz_init(&next->coder->lz, allocator,
return_if_error(lz_init(&coder->lz, allocator,
filters[0].options, &lz_options));
// If the dictionary size is very small, increase it to 4096 bytes.
@@ -248,14 +254,14 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
lz_options.dict_size = (lz_options.dict_size + 15) & ~((size_t)(15));
// Allocate and initialize the dictionary.
if (next->coder->dict.size != lz_options.dict_size) {
lzma_free(next->coder->dict.buf, allocator);
next->coder->dict.buf
if (coder->dict.size != lz_options.dict_size) {
lzma_free(coder->dict.buf, allocator);
coder->dict.buf
= lzma_alloc(lz_options.dict_size, allocator);
if (next->coder->dict.buf == NULL)
if (coder->dict.buf == NULL)
return LZMA_MEM_ERROR;
next->coder->dict.size = lz_options.dict_size;
coder->dict.size = lz_options.dict_size;
}
lz_decoder_reset(next->coder);
@@ -268,21 +274,20 @@ lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
const size_t copy_size = my_min(lz_options.preset_dict_size,
lz_options.dict_size);
const size_t offset = lz_options.preset_dict_size - copy_size;
memcpy(next->coder->dict.buf, lz_options.preset_dict + offset,
memcpy(coder->dict.buf, lz_options.preset_dict + offset,
copy_size);
next->coder->dict.pos = copy_size;
next->coder->dict.full = copy_size;
coder->dict.pos = copy_size;
coder->dict.full = copy_size;
}
// Miscellaneous initializations
next->coder->next_finished = false;
next->coder->this_finished = false;
next->coder->temp.pos = 0;
next->coder->temp.size = 0;
coder->next_finished = false;
coder->this_finished = false;
coder->temp.pos = 0;
coder->temp.size = 0;
// Initialize the next filter in the chain, if any.
return lzma_next_filter_init(&next->coder->next, allocator,
filters + 1);
return lzma_next_filter_init(&coder->next, allocator, filters + 1);
}
@@ -294,7 +299,8 @@ lzma_lz_decoder_memusage(size_t dictionary_size)
extern void
lzma_lz_decoder_uncompressed(lzma_coder *coder, lzma_vli uncompressed_size)
lzma_lz_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)
{
lzma_coder *coder = coder_ptr;
coder->lz.set_uncompressed(coder->lz.coder, uncompressed_size);
}

View File

@@ -53,21 +53,20 @@ typedef struct {
typedef struct {
/// Data specific to the LZ-based decoder
lzma_coder *coder;
void *coder;
/// Function to decode from in[] to *dict
lzma_ret (*code)(lzma_coder *restrict coder,
lzma_ret (*code)(void *coder,
lzma_dict *restrict dict, const uint8_t *restrict in,
size_t *restrict in_pos, size_t in_size);
void (*reset)(lzma_coder *coder, const void *options);
void (*reset)(void *coder, const void *options);
/// Set the uncompressed size
void (*set_uncompressed)(lzma_coder *coder,
lzma_vli uncompressed_size);
void (*set_uncompressed)(void *coder, lzma_vli uncompressed_size);
/// Free allocated resources
void (*end)(lzma_coder *coder, const lzma_allocator *allocator);
void (*end)(void *coder, const lzma_allocator *allocator);
} lzma_lz_decoder;
@@ -92,7 +91,7 @@ extern lzma_ret lzma_lz_decoder_init(lzma_next_coder *next,
extern uint64_t lzma_lz_decoder_memusage(size_t dictionary_size);
extern void lzma_lz_decoder_uncompressed(
lzma_coder *coder, lzma_vli uncompressed_size);
void *coder, lzma_vli uncompressed_size);
//////////////////////

View File

@@ -23,7 +23,7 @@
#include "memcmplen.h"
struct lzma_coder_s {
typedef struct {
/// LZ-based encoder e.g. LZMA
lzma_lz_encoder lz;
@@ -32,7 +32,7 @@ struct lzma_coder_s {
/// Next coder in the chain
lzma_next_coder next;
};
} lzma_coder;
/// \brief Moves the data in the input window to free space for new data
@@ -110,6 +110,12 @@ fill_window(lzma_coder *coder, const lzma_allocator *allocator,
coder->mf.write_pos = write_pos;
// Silence Valgrind. lzma_memcmplen() can read extra bytes
// and Valgrind will give warnings if those bytes are uninitialized
// because Valgrind cannot see that the values of the uninitialized
// bytes are eventually ignored.
memzero(coder->mf.buffer + write_pos, LZMA_MEMCMPLEN_EXTRA);
// If end of stream has been reached or flushing completed, we allow
// the encoder to process all the input (that is, read_pos is allowed
// to reach write_pos). Otherwise we keep keep_size_after bytes
@@ -133,7 +139,7 @@ fill_window(lzma_coder *coder, const lzma_allocator *allocator,
&& coder->mf.read_pos < coder->mf.read_limit) {
// Match finder may update coder->pending and expects it to
// start from zero, so use a temporary variable.
const size_t pending = coder->mf.pending;
const uint32_t pending = coder->mf.pending;
coder->mf.pending = 0;
// Rewind read_pos so that the match finder can hash
@@ -151,12 +157,14 @@ fill_window(lzma_coder *coder, const lzma_allocator *allocator,
static lzma_ret
lz_encode(lzma_coder *coder, const lzma_allocator *allocator,
lz_encode(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size,
uint8_t *restrict out, size_t *restrict out_pos,
size_t out_size, lzma_action action)
{
lzma_coder *coder = coder_ptr;
while (*out_pos < out_size
&& (*in_pos < in_size || action != LZMA_RUN)) {
// Read more data to coder->mf.buffer if needed.
@@ -475,8 +483,10 @@ lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)
static void
lz_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
lz_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder->mf.son, allocator);
@@ -494,10 +504,12 @@ lz_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
lz_encoder_update(lzma_coder *coder, const lzma_allocator *allocator,
lz_encoder_update(void *coder_ptr, const lzma_allocator *allocator,
const lzma_filter *filters_null lzma_attribute((__unused__)),
const lzma_filter *reversed_filters)
{
lzma_coder *coder = coder_ptr;
if (coder->lz.options_update == NULL)
return LZMA_PROG_ERROR;
@@ -522,46 +534,51 @@ lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
#endif
// Allocate and initialize the base data structure.
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
lzma_coder *coder = next->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &lz_encode;
next->end = &lz_encoder_end;
next->update = &lz_encoder_update;
next->coder->lz.coder = NULL;
next->coder->lz.code = NULL;
next->coder->lz.end = NULL;
coder->lz.coder = NULL;
coder->lz.code = NULL;
coder->lz.end = NULL;
next->coder->mf.buffer = NULL;
next->coder->mf.hash = NULL;
next->coder->mf.son = NULL;
next->coder->mf.hash_count = 0;
next->coder->mf.sons_count = 0;
// mf.size is initialized to silence Valgrind
// when used on optimized binaries (GCC may reorder
// code in a way that Valgrind gets unhappy).
coder->mf.buffer = NULL;
coder->mf.size = 0;
coder->mf.hash = NULL;
coder->mf.son = NULL;
coder->mf.hash_count = 0;
coder->mf.sons_count = 0;
next->coder->next = LZMA_NEXT_CODER_INIT;
coder->next = LZMA_NEXT_CODER_INIT;
}
// Initialize the LZ-based encoder.
lzma_lz_options lz_options;
return_if_error(lz_init(&next->coder->lz, allocator,
return_if_error(lz_init(&coder->lz, allocator,
filters[0].options, &lz_options));
// Setup the size information into next->coder->mf and deallocate
// Setup the size information into coder->mf and deallocate
// old buffers if they have wrong size.
if (lz_encoder_prepare(&next->coder->mf, allocator, &lz_options))
if (lz_encoder_prepare(&coder->mf, allocator, &lz_options))
return LZMA_OPTIONS_ERROR;
// Allocate new buffers if needed, and do the rest of
// the initialization.
if (lz_encoder_init(&next->coder->mf, allocator, &lz_options))
if (lz_encoder_init(&coder->mf, allocator, &lz_options))
return LZMA_MEM_ERROR;
// Initialize the next filter in the chain, if any.
return lzma_next_filter_init(&next->coder->next, allocator,
filters + 1);
return lzma_next_filter_init(&coder->next, allocator, filters + 1);
}

View File

@@ -191,19 +191,18 @@ typedef struct {
typedef struct {
/// Data specific to the LZ-based encoder
lzma_coder *coder;
void *coder;
/// Function to encode from *dict to out[]
lzma_ret (*code)(lzma_coder *restrict coder,
lzma_ret (*code)(void *coder,
lzma_mf *restrict mf, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size);
/// Free allocated resources
void (*end)(lzma_coder *coder, const lzma_allocator *allocator);
void (*end)(void *coder, const lzma_allocator *allocator);
/// Update the options in the middle of the encoding.
lzma_ret (*options_update)(lzma_coder *coder,
const lzma_filter *filter);
lzma_ret (*options_update)(void *coder, const lzma_filter *filter);
} lzma_lz_encoder;

View File

@@ -9,12 +9,16 @@ EXTRA_DIST += lzma/fastpos_tablegen.c
liblzma_la_SOURCES += lzma/lzma_common.h
if COND_FILTER_LZMA1
liblzma_la_SOURCES += \
lzma/lzma_encoder_presets.c
endif
if COND_ENCODER_LZMA1
liblzma_la_SOURCES += \
lzma/fastpos.h \
lzma/lzma_encoder.h \
lzma/lzma_encoder.c \
lzma/lzma_encoder_presets.c \
lzma/lzma_encoder_private.h \
lzma/lzma_encoder_optimum_fast.c \
lzma/lzma_encoder_optimum_normal.c

View File

@@ -16,7 +16,7 @@
#include "lzma_decoder.h"
struct lzma_coder_s {
typedef struct {
enum sequence {
SEQ_CONTROL,
SEQ_UNCOMPRESSED_1,
@@ -50,14 +50,16 @@ struct lzma_coder_s {
bool need_dictionary_reset;
lzma_options_lzma options;
};
} lzma_lzma2_coder;
static lzma_ret
lzma2_decode(lzma_coder *restrict coder, lzma_dict *restrict dict,
lzma2_decode(void *coder_ptr, lzma_dict *restrict dict,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size)
{
lzma_lzma2_coder *restrict coder = coder_ptr;
// With SEQ_LZMA it is possible that no new input is needed to do
// some progress. The rest of the sequences assume that there is
// at least one byte of input.
@@ -209,8 +211,10 @@ lzma2_decode(lzma_coder *restrict coder, lzma_dict *restrict dict,
static void
lzma2_decoder_end(lzma_coder *coder, const lzma_allocator *allocator)
lzma2_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_lzma2_coder *coder = coder_ptr;
assert(coder->lzma.end == NULL);
lzma_free(coder->lzma.coder, allocator);
@@ -224,25 +228,27 @@ static lzma_ret
lzma2_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator,
const void *opt, lzma_lz_options *lz_options)
{
if (lz->coder == NULL) {
lz->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (lz->coder == NULL)
lzma_lzma2_coder *coder = lz->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_lzma2_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
lz->coder = coder;
lz->code = &lzma2_decode;
lz->end = &lzma2_decoder_end;
lz->coder->lzma = LZMA_LZ_DECODER_INIT;
coder->lzma = LZMA_LZ_DECODER_INIT;
}
const lzma_options_lzma *options = opt;
lz->coder->sequence = SEQ_CONTROL;
lz->coder->need_properties = true;
lz->coder->need_dictionary_reset = options->preset_dict == NULL
coder->sequence = SEQ_CONTROL;
coder->need_properties = true;
coder->need_dictionary_reset = options->preset_dict == NULL
|| options->preset_dict_size == 0;
return lzma_lzma_decoder_create(&lz->coder->lzma,
return lzma_lzma_decoder_create(&coder->lzma,
allocator, options, lz_options);
}
@@ -263,7 +269,7 @@ lzma_lzma2_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
extern uint64_t
lzma_lzma2_decoder_memusage(const void *options)
{
return sizeof(lzma_coder)
return sizeof(lzma_lzma2_coder)
+ lzma_lzma_decoder_memusage_nocheck(options);
}

View File

@@ -17,7 +17,7 @@
#include "lzma2_encoder.h"
struct lzma_coder_s {
typedef struct {
enum {
SEQ_INIT,
SEQ_LZMA_ENCODE,
@@ -27,7 +27,7 @@ struct lzma_coder_s {
} sequence;
/// LZMA encoder
lzma_coder *lzma;
void *lzma;
/// LZMA options currently in use.
lzma_options_lzma opt_cur;
@@ -48,11 +48,11 @@ struct lzma_coder_s {
/// Buffer to hold the chunk header and LZMA compressed data
uint8_t buf[LZMA2_HEADER_MAX + LZMA2_CHUNK_MAX];
};
} lzma_lzma2_coder;
static void
lzma2_header_lzma(lzma_coder *coder)
lzma2_header_lzma(lzma_lzma2_coder *coder)
{
assert(coder->uncompressed_size > 0);
assert(coder->uncompressed_size <= LZMA2_UNCOMPRESSED_MAX);
@@ -108,7 +108,7 @@ lzma2_header_lzma(lzma_coder *coder)
static void
lzma2_header_uncompressed(lzma_coder *coder)
lzma2_header_uncompressed(lzma_lzma2_coder *coder)
{
assert(coder->uncompressed_size > 0);
assert(coder->uncompressed_size <= LZMA2_CHUNK_MAX);
@@ -133,10 +133,12 @@ lzma2_header_uncompressed(lzma_coder *coder)
static lzma_ret
lzma2_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
lzma2_encode(void *coder_ptr, lzma_mf *restrict mf,
uint8_t *restrict out, size_t *restrict out_pos,
size_t out_size)
{
lzma_lzma2_coder *restrict coder = coder_ptr;
while (*out_pos < out_size)
switch (coder->sequence) {
case SEQ_INIT:
@@ -262,8 +264,9 @@ lzma2_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
static void
lzma2_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
lzma2_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_lzma2_coder *coder = coder_ptr;
lzma_free(coder->lzma, allocator);
lzma_free(coder, allocator);
return;
@@ -271,8 +274,10 @@ lzma2_encoder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
lzma2_encoder_options_update(lzma_coder *coder, const lzma_filter *filter)
lzma2_encoder_options_update(void *coder_ptr, const lzma_filter *filter)
{
lzma_lzma2_coder *coder = coder_ptr;
// New options can be set only when there is no incomplete chunk.
// This is the case at the beginning of the raw stream and right
// after LZMA_SYNC_FLUSH.
@@ -310,30 +315,32 @@ lzma2_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,
if (options == NULL)
return LZMA_PROG_ERROR;
if (lz->coder == NULL) {
lz->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (lz->coder == NULL)
lzma_lzma2_coder *coder = lz->coder;
if (coder == NULL) {
coder = lzma_alloc(sizeof(lzma_lzma2_coder), allocator);
if (coder == NULL)
return LZMA_MEM_ERROR;
lz->coder = coder;
lz->code = &lzma2_encode;
lz->end = &lzma2_encoder_end;
lz->options_update = &lzma2_encoder_options_update;
lz->coder->lzma = NULL;
coder->lzma = NULL;
}
lz->coder->opt_cur = *(const lzma_options_lzma *)(options);
coder->opt_cur = *(const lzma_options_lzma *)(options);
lz->coder->sequence = SEQ_INIT;
lz->coder->need_properties = true;
lz->coder->need_state_reset = false;
lz->coder->need_dictionary_reset
= lz->coder->opt_cur.preset_dict == NULL
|| lz->coder->opt_cur.preset_dict_size == 0;
coder->sequence = SEQ_INIT;
coder->need_properties = true;
coder->need_state_reset = false;
coder->need_dictionary_reset
= coder->opt_cur.preset_dict == NULL
|| coder->opt_cur.preset_dict_size == 0;
// Initialize LZMA encoder
return_if_error(lzma_lzma_encoder_create(&lz->coder->lzma, allocator,
&lz->coder->opt_cur, lz_options));
return_if_error(lzma_lzma_encoder_create(&coder->lzma, allocator,
&coder->opt_cur, lz_options));
// Make sure that we will always have enough history available in
// case we need to use uncompressed chunks. They are used when the
@@ -364,7 +371,7 @@ lzma_lzma2_encoder_memusage(const void *options)
if (lzma_mem == UINT64_MAX)
return UINT64_MAX;
return sizeof(lzma_coder) + lzma_mem;
return sizeof(lzma_lzma2_coder) + lzma_mem;
}

View File

@@ -16,6 +16,12 @@
#include "lzma_decoder.h"
#include "range_decoder.h"
// The macros unroll loops with switch statements.
// Silence warnings about missing fall-through comments.
#if TUKLIB_GNUC_REQ(7, 0)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
#ifdef HAVE_SMALL
@@ -161,7 +167,7 @@ typedef struct {
} lzma_length_decoder;
struct lzma_coder_s {
typedef struct {
///////////////////
// Probabilities //
///////////////////
@@ -277,14 +283,16 @@ struct lzma_coder_s {
/// If decoding a literal: match byte.
/// If decoding a match: length of the match.
uint32_t len;
};
} lzma_lzma1_decoder;
static lzma_ret
lzma_decode(lzma_coder *restrict coder, lzma_dict *restrict dictptr,
lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr,
const uint8_t *restrict in,
size_t *restrict in_pos, size_t in_size)
{
lzma_lzma1_decoder *restrict coder = coder_ptr;
////////////////////
// Initialization //
////////////////////
@@ -840,23 +848,17 @@ out:
static void
lzma_decoder_uncompressed(lzma_coder *coder, lzma_vli uncompressed_size)
lzma_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)
{
lzma_lzma1_decoder *coder = coder_ptr;
coder->uncompressed_size = uncompressed_size;
}
/*
extern void
lzma_lzma_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)
{
// This is hack.
(*(lzma_coder **)(coder))->uncompressed_size = uncompressed_size;
}
*/
static void
lzma_decoder_reset(lzma_coder *coder, const void *opt)
lzma_decoder_reset(void *coder_ptr, const void *opt)
{
lzma_lzma1_decoder *coder = coder_ptr;
const lzma_options_lzma *options = opt;
// NOTE: We assume that lc/lp/pb are valid since they were
@@ -941,7 +943,7 @@ lzma_lzma_decoder_create(lzma_lz_decoder *lz, const lzma_allocator *allocator,
const void *opt, lzma_lz_options *lz_options)
{
if (lz->coder == NULL) {
lz->coder = lzma_alloc(sizeof(lzma_coder), allocator);
lz->coder = lzma_alloc(sizeof(lzma_lzma1_decoder), allocator);
if (lz->coder == NULL)
return LZMA_MEM_ERROR;
@@ -1014,7 +1016,8 @@ extern uint64_t
lzma_lzma_decoder_memusage_nocheck(const void *options)
{
const lzma_options_lzma *const opt = options;
return sizeof(lzma_coder) + lzma_lz_decoder_memusage(opt->dict_size);
return sizeof(lzma_lzma1_decoder)
+ lzma_lz_decoder_memusage(opt->dict_size);
}

View File

@@ -43,7 +43,7 @@ literal_matched(lzma_range_encoder *rc, probability *subcoder,
static inline void
literal(lzma_coder *coder, lzma_mf *mf, uint32_t position)
literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position)
{
// Locate the literal byte to be encoded and the subcoder.
const uint8_t cur_byte = mf->buffer[
@@ -140,7 +140,7 @@ length(lzma_range_encoder *rc, lzma_length_encoder *lc,
///////////
static inline void
match(lzma_coder *coder, const uint32_t pos_state,
match(lzma_lzma1_encoder *coder, const uint32_t pos_state,
const uint32_t distance, const uint32_t len)
{
update_match(coder->state);
@@ -187,7 +187,7 @@ match(lzma_coder *coder, const uint32_t pos_state,
////////////////////
static inline void
rep_match(lzma_coder *coder, const uint32_t pos_state,
rep_match(lzma_lzma1_encoder *coder, const uint32_t pos_state,
const uint32_t rep, const uint32_t len)
{
if (rep == 0) {
@@ -231,7 +231,7 @@ rep_match(lzma_coder *coder, const uint32_t pos_state,
//////////
static void
encode_symbol(lzma_coder *coder, lzma_mf *mf,
encode_symbol(lzma_lzma1_encoder *coder, lzma_mf *mf,
uint32_t back, uint32_t len, uint32_t position)
{
const uint32_t pos_state = position & coder->pos_mask;
@@ -265,7 +265,7 @@ encode_symbol(lzma_coder *coder, lzma_mf *mf,
static bool
encode_init(lzma_coder *coder, lzma_mf *mf)
encode_init(lzma_lzma1_encoder *coder, lzma_mf *mf)
{
assert(mf_position(mf) == 0);
@@ -293,7 +293,7 @@ encode_init(lzma_coder *coder, lzma_mf *mf)
static void
encode_eopm(lzma_coder *coder, uint32_t position)
encode_eopm(lzma_lzma1_encoder *coder, uint32_t position)
{
const uint32_t pos_state = position & coder->pos_mask;
rc_bit(&coder->rc, &coder->is_match[coder->state][pos_state], 1);
@@ -309,7 +309,7 @@ encode_eopm(lzma_coder *coder, uint32_t position)
extern lzma_ret
lzma_lzma_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,
uint8_t *restrict out, size_t *restrict out_pos,
size_t out_size, uint32_t limit)
{
@@ -402,7 +402,7 @@ lzma_lzma_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
static lzma_ret
lzma_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
lzma_encode(void *coder, lzma_mf *restrict mf,
uint8_t *restrict out, size_t *restrict out_pos,
size_t out_size)
{
@@ -464,7 +464,7 @@ length_encoder_reset(lzma_length_encoder *lencoder,
bittree_reset(lencoder->high, LEN_HIGH_BITS);
if (!fast_mode)
for (size_t pos_state = 0; pos_state < num_pos_states;
for (uint32_t pos_state = 0; pos_state < num_pos_states;
++pos_state)
length_update_prices(lencoder, pos_state);
@@ -473,7 +473,8 @@ length_encoder_reset(lzma_length_encoder *lencoder,
extern lzma_ret
lzma_lzma_encoder_reset(lzma_coder *coder, const lzma_options_lzma *options)
lzma_lzma_encoder_reset(lzma_lzma1_encoder *coder,
const lzma_options_lzma *options)
{
if (!is_options_valid(options))
return LZMA_OPTIONS_ERROR;
@@ -545,18 +546,18 @@ lzma_lzma_encoder_reset(lzma_coder *coder, const lzma_options_lzma *options)
extern lzma_ret
lzma_lzma_encoder_create(lzma_coder **coder_ptr,
lzma_lzma_encoder_create(void **coder_ptr,
const lzma_allocator *allocator,
const lzma_options_lzma *options, lzma_lz_options *lz_options)
{
// Allocate lzma_coder if it wasn't already allocated.
// Allocate lzma_lzma1_encoder if it wasn't already allocated.
if (*coder_ptr == NULL) {
*coder_ptr = lzma_alloc(sizeof(lzma_coder), allocator);
*coder_ptr = lzma_alloc(sizeof(lzma_lzma1_encoder), allocator);
if (*coder_ptr == NULL)
return LZMA_MEM_ERROR;
}
lzma_coder *coder = *coder_ptr;
lzma_lzma1_encoder *coder = *coder_ptr;
// Set compression mode. We haven't validates the options yet,
// but it's OK here, since nothing bad happens with invalid
@@ -636,7 +637,7 @@ lzma_lzma_encoder_memusage(const void *options)
if (lz_memusage == UINT64_MAX)
return UINT64_MAX;
return (uint64_t)(sizeof(lzma_coder)) + lz_memusage;
return (uint64_t)(sizeof(lzma_lzma1_encoder)) + lz_memusage;
}

View File

@@ -17,6 +17,9 @@
#include "common.h"
typedef struct lzma_lzma1_encoder_s lzma_lzma1_encoder;
extern lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next,
const lzma_allocator *allocator,
const lzma_filter_info *filters);
@@ -36,16 +39,16 @@ extern bool lzma_lzma_lclppb_encode(
/// Initializes raw LZMA encoder; this is used by LZMA2.
extern lzma_ret lzma_lzma_encoder_create(
lzma_coder **coder_ptr, const lzma_allocator *allocator,
void **coder_ptr, const lzma_allocator *allocator,
const lzma_options_lzma *options, lzma_lz_options *lz_options);
/// Resets an already initialized LZMA encoder; this is used by LZMA2.
extern lzma_ret lzma_lzma_encoder_reset(
lzma_coder *coder, const lzma_options_lzma *options);
lzma_lzma1_encoder *coder, const lzma_options_lzma *options);
extern lzma_ret lzma_lzma_encode(lzma_coder *restrict coder,
extern lzma_ret lzma_lzma_encode(lzma_lzma1_encoder *restrict coder,
lzma_mf *restrict mf, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size,
uint32_t read_limit);

View File

@@ -18,7 +18,8 @@
extern void
lzma_lzma_optimum_fast(lzma_coder *restrict coder, lzma_mf *restrict mf,
lzma_lzma_optimum_fast(lzma_lzma1_encoder *restrict coder,
lzma_mf *restrict mf,
uint32_t *restrict back_res, uint32_t *restrict len_res)
{
const uint32_t nice_len = mf->nice_len;
@@ -152,7 +153,7 @@ lzma_lzma_optimum_fast(lzma_coder *restrict coder, lzma_mf *restrict mf,
// the old buf pointer instead of recalculating it with mf_ptr().
++buf;
const uint32_t limit = len_main - 1;
const uint32_t limit = my_max(2, len_main - 1);
for (uint32_t i = 0; i < REPS; ++i) {
if (memcmp(buf, buf - coder->reps[i] - 1, limit) == 0) {

View File

@@ -19,7 +19,7 @@
////////////
static uint32_t
get_literal_price(const lzma_coder *const coder, const uint32_t pos,
get_literal_price(const lzma_lzma1_encoder *const coder, const uint32_t pos,
const uint32_t prev_byte, const bool match_mode,
uint32_t match_byte, uint32_t symbol)
{
@@ -65,7 +65,7 @@ get_len_price(const lzma_length_encoder *const lencoder,
static inline uint32_t
get_short_rep_price(const lzma_coder *const coder,
get_short_rep_price(const lzma_lzma1_encoder *const coder,
const lzma_lzma_state state, const uint32_t pos_state)
{
return rc_bit_0_price(coder->is_rep0[state])
@@ -74,7 +74,7 @@ get_short_rep_price(const lzma_coder *const coder,
static inline uint32_t
get_pure_rep_price(const lzma_coder *const coder, const uint32_t rep_index,
get_pure_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index,
const lzma_lzma_state state, uint32_t pos_state)
{
uint32_t price;
@@ -99,7 +99,7 @@ get_pure_rep_price(const lzma_coder *const coder, const uint32_t rep_index,
static inline uint32_t
get_rep_price(const lzma_coder *const coder, const uint32_t rep_index,
get_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index,
const uint32_t len, const lzma_lzma_state state,
const uint32_t pos_state)
{
@@ -109,7 +109,7 @@ get_rep_price(const lzma_coder *const coder, const uint32_t rep_index,
static inline uint32_t
get_dist_len_price(const lzma_coder *const coder, const uint32_t dist,
get_dist_len_price(const lzma_lzma1_encoder *const coder, const uint32_t dist,
const uint32_t len, const uint32_t pos_state)
{
const uint32_t dist_state = get_dist_state(len);
@@ -130,7 +130,7 @@ get_dist_len_price(const lzma_coder *const coder, const uint32_t dist,
static void
fill_dist_prices(lzma_coder *coder)
fill_dist_prices(lzma_lzma1_encoder *coder)
{
for (uint32_t dist_state = 0; dist_state < DIST_STATES; ++dist_state) {
@@ -185,7 +185,7 @@ fill_dist_prices(lzma_coder *coder)
static void
fill_align_prices(lzma_coder *coder)
fill_align_prices(lzma_lzma1_encoder *coder)
{
for (uint32_t i = 0; i < ALIGN_SIZE; ++i)
coder->align_prices[i] = rc_bittree_reverse_price(
@@ -221,7 +221,7 @@ make_short_rep(lzma_optimal *optimal)
static void
backward(lzma_coder *restrict coder, uint32_t *restrict len_res,
backward(lzma_lzma1_encoder *restrict coder, uint32_t *restrict len_res,
uint32_t *restrict back_res, uint32_t cur)
{
coder->opts_end_index = cur;
@@ -269,7 +269,7 @@ backward(lzma_coder *restrict coder, uint32_t *restrict len_res,
//////////
static inline uint32_t
helper1(lzma_coder *restrict coder, lzma_mf *restrict mf,
helper1(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,
uint32_t *restrict back_res, uint32_t *restrict len_res,
uint32_t position)
{
@@ -441,7 +441,7 @@ helper1(lzma_coder *restrict coder, lzma_mf *restrict mf,
static inline uint32_t
helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
helper2(lzma_lzma1_encoder *coder, uint32_t *reps, const uint8_t *buf,
uint32_t len_end, uint32_t position, const uint32_t cur,
const uint32_t nice_len, const uint32_t buf_avail_full)
{
@@ -797,7 +797,8 @@ helper2(lzma_coder *coder, uint32_t *reps, const uint8_t *buf,
extern void
lzma_lzma_optimum_normal(lzma_coder *restrict coder, lzma_mf *restrict mf,
lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder,
lzma_mf *restrict mf,
uint32_t *restrict back_res, uint32_t *restrict len_res,
uint32_t position)
{

View File

@@ -2,6 +2,7 @@
//
/// \file lzma_encoder_presets.c
/// \brief Encoder presets
/// \note xz needs this even when only decoding is enabled.
//
// Author: Lasse Collin
//

View File

@@ -69,7 +69,7 @@ typedef struct {
} lzma_optimal;
struct lzma_coder_s {
struct lzma_lzma1_encoder_s {
/// Range encoder
lzma_range_encoder rc;
@@ -138,10 +138,10 @@ struct lzma_coder_s {
extern void lzma_lzma_optimum_fast(
lzma_coder *restrict coder, lzma_mf *restrict mf,
lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,
uint32_t *restrict back_res, uint32_t *restrict len_res);
extern void lzma_lzma_optimum_normal(lzma_coder *restrict coder,
extern void lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder,
lzma_mf *restrict mf, uint32_t *restrict back_res,
uint32_t *restrict len_res, uint32_t position);

View File

@@ -14,9 +14,7 @@
#ifndef LZMA_RANGE_COMMON_H
#define LZMA_RANGE_COMMON_H
#ifdef HAVE_CONFIG_H
# include "common.h"
#endif
#include "common.h"
///////////////

View File

@@ -15,7 +15,7 @@
static size_t
arm_code(lzma_simple *simple lzma_attribute((__unused__)),
arm_code(void *simple lzma_attribute((__unused__)),
uint32_t now_pos, bool is_encoder,
uint8_t *buffer, size_t size)
{

View File

@@ -15,7 +15,7 @@
static size_t
armthumb_code(lzma_simple *simple lzma_attribute((__unused__)),
armthumb_code(void *simple lzma_attribute((__unused__)),
uint32_t now_pos, bool is_encoder,
uint8_t *buffer, size_t size)
{

View File

@@ -15,7 +15,7 @@
static size_t
ia64_code(lzma_simple *simple lzma_attribute((__unused__)),
ia64_code(void *simple lzma_attribute((__unused__)),
uint32_t now_pos, bool is_encoder,
uint8_t *buffer, size_t size)
{

View File

@@ -15,7 +15,7 @@
static size_t
powerpc_code(lzma_simple *simple lzma_attribute((__unused__)),
powerpc_code(void *simple lzma_attribute((__unused__)),
uint32_t now_pos, bool is_encoder,
uint8_t *buffer, size_t size)
{

View File

@@ -18,7 +18,7 @@
/// Copied or encodes/decodes more data to out[].
static lzma_ret
copy_or_code(lzma_coder *coder, const lzma_allocator *allocator,
copy_or_code(lzma_simple_coder *coder, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
@@ -55,7 +55,7 @@ copy_or_code(lzma_coder *coder, const lzma_allocator *allocator,
static size_t
call_filter(lzma_coder *coder, uint8_t *buffer, size_t size)
call_filter(lzma_simple_coder *coder, uint8_t *buffer, size_t size)
{
const size_t filtered = coder->filter(coder->simple,
coder->now_pos, coder->is_encoder,
@@ -66,11 +66,13 @@ call_filter(lzma_coder *coder, uint8_t *buffer, size_t size)
static lzma_ret
simple_code(lzma_coder *coder, const lzma_allocator *allocator,
simple_code(void *coder_ptr, const lzma_allocator *allocator,
const uint8_t *restrict in, size_t *restrict in_pos,
size_t in_size, uint8_t *restrict out,
size_t *restrict out_pos, size_t out_size, lzma_action action)
{
lzma_simple_coder *coder = coder_ptr;
// TODO: Add partial support for LZMA_SYNC_FLUSH. We can support it
// in cases when the filter is able to filter everything. With most
// simple filters it can be done at offset that is a multiple of 2,
@@ -198,8 +200,9 @@ simple_code(lzma_coder *coder, const lzma_allocator *allocator,
static void
simple_coder_end(lzma_coder *coder, const lzma_allocator *allocator)
simple_coder_end(void *coder_ptr, const lzma_allocator *allocator)
{
lzma_simple_coder *coder = coder_ptr;
lzma_next_end(&coder->next, allocator);
lzma_free(coder->simple, allocator);
lzma_free(coder, allocator);
@@ -208,10 +211,12 @@ simple_coder_end(lzma_coder *coder, const lzma_allocator *allocator)
static lzma_ret
simple_coder_update(lzma_coder *coder, const lzma_allocator *allocator,
simple_coder_update(void *coder_ptr, const lzma_allocator *allocator,
const lzma_filter *filters_null lzma_attribute((__unused__)),
const lzma_filter *reversed_filters)
{
lzma_simple_coder *coder = coder_ptr;
// No update support, just call the next filter in the chain.
return lzma_next_filter_update(
&coder->next, allocator, reversed_filters + 1);
@@ -221,57 +226,57 @@ simple_coder_update(lzma_coder *coder, const lzma_allocator *allocator,
extern lzma_ret
lzma_simple_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
const lzma_filter_info *filters,
size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
size_t (*filter)(void *simple, uint32_t now_pos,
bool is_encoder, uint8_t *buffer, size_t size),
size_t simple_size, size_t unfiltered_max,
uint32_t alignment, bool is_encoder)
{
// Allocate memory for the lzma_coder structure if needed.
if (next->coder == NULL) {
// Allocate memory for the lzma_simple_coder structure if needed.
lzma_simple_coder *coder = next->coder;
if (coder == NULL) {
// Here we allocate space also for the temporary buffer. We
// need twice the size of unfiltered_max, because then it
// is always possible to filter at least unfiltered_max bytes
// more data in coder->buffer[] if it can be filled completely.
next->coder = lzma_alloc(sizeof(lzma_coder)
coder = lzma_alloc(sizeof(lzma_simple_coder)
+ 2 * unfiltered_max, allocator);
if (next->coder == NULL)
if (coder == NULL)
return LZMA_MEM_ERROR;
next->coder = coder;
next->code = &simple_code;
next->end = &simple_coder_end;
next->update = &simple_coder_update;
next->coder->next = LZMA_NEXT_CODER_INIT;
next->coder->filter = filter;
next->coder->allocated = 2 * unfiltered_max;
coder->next = LZMA_NEXT_CODER_INIT;
coder->filter = filter;
coder->allocated = 2 * unfiltered_max;
// Allocate memory for filter-specific data structure.
if (simple_size > 0) {
next->coder->simple = lzma_alloc(
simple_size, allocator);
if (next->coder->simple == NULL)
coder->simple = lzma_alloc(simple_size, allocator);
if (coder->simple == NULL)
return LZMA_MEM_ERROR;
} else {
next->coder->simple = NULL;
coder->simple = NULL;
}
}
if (filters[0].options != NULL) {
const lzma_options_bcj *simple = filters[0].options;
next->coder->now_pos = simple->start_offset;
if (next->coder->now_pos & (alignment - 1))
coder->now_pos = simple->start_offset;
if (coder->now_pos & (alignment - 1))
return LZMA_OPTIONS_ERROR;
} else {
next->coder->now_pos = 0;
coder->now_pos = 0;
}
// Reset variables.
next->coder->is_encoder = is_encoder;
next->coder->end_was_reached = false;
next->coder->pos = 0;
next->coder->filtered = 0;
next->coder->size = 0;
coder->is_encoder = is_encoder;
coder->end_was_reached = false;
coder->pos = 0;
coder->filtered = 0;
coder->size = 0;
return lzma_next_filter_init(
&next->coder->next, allocator, filters + 1);
return lzma_next_filter_init(&coder->next, allocator, filters + 1);
}

View File

@@ -16,9 +16,7 @@
#include "simple_coder.h"
typedef struct lzma_simple_s lzma_simple;
struct lzma_coder_s {
typedef struct {
/// Next filter in the chain
lzma_next_coder next;
@@ -33,12 +31,12 @@ struct lzma_coder_s {
/// Pointer to filter-specific function, which does
/// the actual filtering.
size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
size_t (*filter)(void *simple, uint32_t now_pos,
bool is_encoder, uint8_t *buffer, size_t size);
/// Pointer to filter-specific data, or NULL if filter doesn't need
/// any extra data.
lzma_simple *simple;
void *simple;
/// The lowest 32 bits of the current position in the data. Most
/// filters need this to do conversions between absolute and relative
@@ -62,13 +60,13 @@ struct lzma_coder_s {
/// Temporary buffer
uint8_t buffer[];
};
} lzma_simple_coder;
extern lzma_ret lzma_simple_coder_init(lzma_next_coder *next,
const lzma_allocator *allocator,
const lzma_filter_info *filters,
size_t (*filter)(lzma_simple *simple, uint32_t now_pos,
size_t (*filter)(void *simple, uint32_t now_pos,
bool is_encoder, uint8_t *buffer, size_t size),
size_t simple_size, size_t unfiltered_max,
uint32_t alignment, bool is_encoder);

View File

@@ -15,7 +15,7 @@
static size_t
sparc_code(lzma_simple *simple lzma_attribute((__unused__)),
sparc_code(void *simple lzma_attribute((__unused__)),
uint32_t now_pos, bool is_encoder,
uint8_t *buffer, size_t size)
{

View File

@@ -17,14 +17,14 @@
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
struct lzma_simple_s {
typedef struct {
uint32_t prev_mask;
uint32_t prev_pos;
};
} lzma_simple_x86;
static size_t
x86_code(lzma_simple *simple, uint32_t now_pos, bool is_encoder,
x86_code(void *simple_ptr, uint32_t now_pos, bool is_encoder,
uint8_t *buffer, size_t size)
{
static const bool MASK_TO_ALLOWED_STATUS[8]
@@ -33,6 +33,7 @@ x86_code(lzma_simple *simple, uint32_t now_pos, bool is_encoder,
static const uint32_t MASK_TO_BIT_NUMBER[8]
= { 0, 1, 2, 2, 3, 3, 3, 3 };
lzma_simple_x86 *simple = simple_ptr;
uint32_t prev_mask = simple->prev_mask;
uint32_t prev_pos = simple->prev_pos;
@@ -127,11 +128,13 @@ x86_coder_init(lzma_next_coder *next, const lzma_allocator *allocator,
const lzma_filter_info *filters, bool is_encoder)
{
const lzma_ret ret = lzma_simple_coder_init(next, allocator, filters,
&x86_code, sizeof(lzma_simple), 5, 1, is_encoder);
&x86_code, sizeof(lzma_simple_x86), 5, 1, is_encoder);
if (ret == LZMA_OK) {
next->coder->simple->prev_mask = 0;
next->coder->simple->prev_pos = (uint32_t)(-5);
lzma_simple_coder *coder = next->coder;
lzma_simple_x86 *simple = coder->simple;
simple->prev_mask = 0;
simple->prev_pos = (uint32_t)(-5);
}
return ret;

View File

@@ -9,8 +9,8 @@ bin_PROGRAMS = lzmainfo
lzmainfo_SOURCES = \
lzmainfo.c \
$(top_srcdir)/src/common/tuklib_progname.c \
$(top_srcdir)/src/common/tuklib_exit.c
../common/tuklib_progname.c \
../common/tuklib_exit.c
if COND_W32
lzmainfo_SOURCES += lzmainfo_w32res.rc

View File

@@ -136,18 +136,38 @@ elif test $# -eq 2; then
F=`expr "/$2" : '.*/\(.*\)[-.][ablmotxz2]*$'` || F=$prog
tmp=
trap '
test -n "$tmp" && rm -f "$tmp"
test -n "$tmp" && rm -rf "$tmp"
(exit 2); exit 2
' HUP INT PIPE TERM 0
tmp=`mktemp -t -- "$F.XXXXXX"` || exit 2
$xz2 -cdfq -- "$2" > "$tmp" || exit 2
if type mktemp >/dev/null 2>&1; then
# Note that FreeBSD's mktemp isn't fully compatible with
# the implementations from mktemp.org and GNU coreutils.
# It is important that the -t argument is the last argument
# and that no "--" is used between -t and the template argument.
# This way this command works on all implementations.
tmp=`mktemp -d -t "$prog.XXXXXXXXXX"` || exit 2
else
# Fallback code if mktemp is missing. This isn't as
# robust as using mktemp since this doesn't try with
# different file names in case of a file name conflict.
#
# There's no need to save the original umask since
# we don't create any non-temp files. Note that using
# mkdir -m 0077 isn't secure since some mkdir implementations
# create the dir with the default umask and chmod the
# the dir afterwards.
umask 0077
mkdir -- "${TMPDIR-/tmp}/$prog.$$" || exit 2
tmp="${TMPDIR-/tmp}/$prog.$$"
fi
$xz2 -cdfq -- "$2" > "$tmp/$F" || exit 2
xz_status=$(
exec 4>&1
($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
eval "$cmp" - '"$tmp"' >&3
eval "$cmp" - '"$tmp/$F"' >&3
)
cmp_status=$?
rm -f "$tmp" || xz_status=$?
rm -rf "$tmp" || xz_status=$?
trap - HUP INT PIPE TERM 0
(exit $cmp_status)
fi;;

View File

@@ -106,9 +106,11 @@ while test $# -ne 0; do
with_filename=1
continue;;
(-l | --files-with-*)
files_with_matches=1;;
files_with_matches=1
continue;;
(-L | --files-witho*)
files_without_matches=1;;
files_without_matches=1
continue;;
(-h | --no-f*)
no_filename=1;;
(-V | --v | --ve | --ver | --vers | --versi | --versio | --version)

View File

@@ -16,8 +16,6 @@ xz_SOURCES = \
file_io.h \
hardware.c \
hardware.h \
list.c \
list.h \
main.c \
main.h \
message.c \
@@ -33,11 +31,17 @@ xz_SOURCES = \
suffix.h \
util.c \
util.h \
$(top_srcdir)/src/common/tuklib_open_stdxxx.c \
$(top_srcdir)/src/common/tuklib_progname.c \
$(top_srcdir)/src/common/tuklib_exit.c \
$(top_srcdir)/src/common/tuklib_mbstr_width.c \
$(top_srcdir)/src/common/tuklib_mbstr_fw.c
../common/tuklib_open_stdxxx.c \
../common/tuklib_progname.c \
../common/tuklib_exit.c \
../common/tuklib_mbstr_width.c \
../common/tuklib_mbstr_fw.c
if COND_MAIN_DECODER
xz_SOURCES += \
list.c \
list.h
endif
if COND_W32
xz_SOURCES += xz_w32res.rc
@@ -49,7 +53,7 @@ xz_CPPFLAGS = \
-I$(top_srcdir)/src/liblzma/api \
-I$(top_builddir)/lib
xz_LDADD = $(top_builddir)/src/liblzma/liblzma.la
xz_LDADD = $(top_builddir)/src/liblzma/liblzma.la $(CAPSICUM_LIB)
if COND_GNULIB
xz_LDADD += $(top_builddir)/lib/libgnu.a

View File

@@ -635,6 +635,22 @@ args_parse(args_info *args, int argc, char **argv)
// Then from the command line
parse_real(args, argc, argv);
// If encoder or decoder support was omitted at build time,
// show an error now so that the rest of the code can rely on
// that whatever is in opt_mode is also supported.
#ifndef HAVE_ENCODERS
if (opt_mode == MODE_COMPRESS)
message_fatal(_("Compression support was disabled "
"at build time"));
#endif
#ifndef HAVE_DECODERS
// Even MODE_LIST cannot work without decoder support so MODE_COMPRESS
// is the only valid choice.
if (opt_mode != MODE_COMPRESS)
message_fatal(_("Decompression support was disabled "
"at build time"));
#endif
// Never remove the source file when the destination is not on disk.
// In test mode the data is written nowhere, but setting opt_stdout
// will make the rest of the code behave well.

View File

@@ -15,7 +15,7 @@ typedef struct {
char **arg_names;
/// Number of filenames from command line
size_t arg_count;
unsigned int arg_count;
/// Name of the file from which to read filenames. This is NULL
/// if --files or --files0 was not used.

View File

@@ -51,7 +51,7 @@ static lzma_check check;
/// This becomes false if the --check=CHECK option is used.
static bool check_default = true;
#ifdef MYTHREAD_ENABLED
#if defined(HAVE_ENCODERS) && defined(MYTHREAD_ENABLED)
static lzma_mt mt_options = {
.flags = 0,
.timeout = 300,
@@ -221,9 +221,10 @@ coder_set_compression_settings(void)
// Get the memory usage. Note that if --format=raw was used,
// we can be decompressing.
const uint64_t memory_limit = hardware_memlimit_get(opt_mode);
uint64_t memory_usage;
uint64_t memory_usage = UINT64_MAX;
if (opt_mode == MODE_COMPRESS) {
#ifdef MYTHREAD_ENABLED
#ifdef HAVE_ENCODERS
# ifdef MYTHREAD_ENABLED
if (opt_format == FORMAT_XZ && hardware_threads_get() > 1) {
mt_options.threads = hardware_threads_get();
mt_options.block_size = opt_block_size;
@@ -235,12 +236,15 @@ coder_set_compression_settings(void)
" threads."),
mt_options.threads);
} else
#endif
# endif
{
memory_usage = lzma_raw_encoder_memusage(filters);
}
#endif
} else {
#ifdef HAVE_DECODERS
memory_usage = lzma_raw_decoder_memusage(filters);
#endif
}
if (memory_usage == UINT64_MAX)
@@ -248,7 +252,11 @@ coder_set_compression_settings(void)
// Print memory usage info before possible dictionary
// size auto-adjusting.
//
// NOTE: If only encoder support was built, we cannot show the
// what the decoder memory usage will be.
message_mem_needed(V_DEBUG, memory_usage);
#ifdef HAVE_DECODERS
if (opt_mode == MODE_COMPRESS) {
const uint64_t decmem = lzma_raw_decoder_memusage(filters);
if (decmem != UINT64_MAX)
@@ -256,6 +264,7 @@ coder_set_compression_settings(void)
"%s MiB of memory."), uint64_to_str(
round_up_to_mib(decmem), 0));
}
#endif
if (memory_usage <= memory_limit)
return;
@@ -268,7 +277,8 @@ coder_set_compression_settings(void)
assert(opt_mode == MODE_COMPRESS);
#ifdef MYTHREAD_ENABLED
#ifdef HAVE_ENCODERS
# ifdef MYTHREAD_ENABLED
if (opt_format == FORMAT_XZ && mt_options.threads > 1) {
// Try to reduce the number of threads before
// adjusting the compression settings down.
@@ -295,7 +305,7 @@ coder_set_compression_settings(void)
uint64_to_str(round_up_to_mib(
memory_limit), 2));
}
#endif
# endif
if (memory_usage <= memory_limit)
return;
@@ -349,11 +359,13 @@ coder_set_compression_settings(void)
uint64_to_str(orig_dict_size >> 20, 0),
uint64_to_str(opt->dict_size >> 20, 1),
uint64_to_str(round_up_to_mib(memory_limit), 2));
#endif
return;
}
#ifdef HAVE_DECODERS
/// Return true if the data in in_buf seems to be in the .xz format.
static bool
is_format_xz(void)
@@ -411,6 +423,7 @@ is_format_lzma(void)
return true;
}
#endif
/// Detect the input file type (for now, this done only when decompressing),
@@ -424,6 +437,7 @@ coder_init(file_pair *pair)
lzma_ret ret = LZMA_PROG_ERROR;
if (opt_mode == MODE_COMPRESS) {
#ifdef HAVE_ENCODERS
switch (opt_format) {
case FORMAT_AUTO:
// args.c ensures this.
@@ -431,12 +445,12 @@ coder_init(file_pair *pair)
break;
case FORMAT_XZ:
#ifdef MYTHREAD_ENABLED
# ifdef MYTHREAD_ENABLED
if (hardware_threads_get() > 1)
ret = lzma_stream_encoder_mt(
&strm, &mt_options);
else
#endif
# endif
ret = lzma_stream_encoder(
&strm, filters, check);
break;
@@ -449,7 +463,9 @@ coder_init(file_pair *pair)
ret = lzma_raw_encoder(&strm, filters);
break;
}
#endif
} else {
#ifdef HAVE_DECODERS
uint32_t flags = 0;
// It seems silly to warn about unsupported check if the
@@ -531,6 +547,7 @@ coder_init(file_pair *pair)
strm.avail_out = 0;
ret = lzma_code(&strm, LZMA_RUN);
}
#endif
}
if (ret != LZMA_OK) {

View File

@@ -23,10 +23,20 @@ static bool warn_fchown;
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
# include <sys/time.h>
#elif defined(HAVE__FUTIME)
# include <sys/utime.h>
#elif defined(HAVE_UTIME)
# include <utime.h>
#endif
#ifdef HAVE_CAPSICUM
# ifdef HAVE_SYS_CAPSICUM_H
# include <sys/capsicum.h>
# else
# include <sys/capability.h>
# endif
#endif
#include "tuklib_open_stdxxx.h"
#ifndef O_BINARY
@@ -37,6 +47,14 @@ static bool warn_fchown;
# define O_NOCTTY 0
#endif
// Using this macro to silence a warning from gcc -Wlogical-op.
#if EAGAIN == EWOULDBLOCK
# define IS_EAGAIN_OR_EWOULDBLOCK(e) ((e) == EAGAIN)
#else
# define IS_EAGAIN_OR_EWOULDBLOCK(e) \
((e) == EAGAIN || (e) == EWOULDBLOCK)
#endif
typedef enum {
IO_WAIT_MORE, // Reading or writing is possible.
@@ -48,6 +66,11 @@ typedef enum {
/// If true, try to create sparse files when decompressing.
static bool try_sparse = true;
#ifdef ENABLE_SANDBOX
/// True if the conditions for sandboxing (described in main()) have been met.
static bool sandbox_allowed = false;
#endif
#ifndef TUKLIB_DOSLIKE
/// File status flags of standard input. This is used by io_open_src()
/// and io_close_src().
@@ -82,13 +105,19 @@ io_init(void)
// we are root.
warn_fchown = geteuid() == 0;
if (pipe(user_abort_pipe)
|| fcntl(user_abort_pipe[0], F_SETFL, O_NONBLOCK)
== -1
|| fcntl(user_abort_pipe[1], F_SETFL, O_NONBLOCK)
== -1)
// Create a pipe for the self-pipe trick.
if (pipe(user_abort_pipe))
message_fatal(_("Error creating a pipe: %s"),
strerror(errno));
// Make both ends of the pipe non-blocking.
for (unsigned i = 0; i < 2; ++i) {
int flags = fcntl(user_abort_pipe[i], F_GETFL);
if (flags == -1 || fcntl(user_abort_pipe[i], F_SETFL,
flags | O_NONBLOCK) == -1)
message_fatal(_("Error creating a pipe: %s"),
strerror(errno));
}
#endif
#ifdef __DJGPP__
@@ -126,6 +155,73 @@ io_no_sparse(void)
}
#ifdef ENABLE_SANDBOX
extern void
io_allow_sandbox(void)
{
sandbox_allowed = true;
return;
}
/// Enables operating-system-specific sandbox if it is possible.
/// src_fd is the file descriptor of the input file.
static void
io_sandbox_enter(int src_fd)
{
if (!sandbox_allowed) {
message(V_DEBUG, _("Sandbox is disabled due "
"to incompatible command line arguments"));
return;
}
const char dummy_str[] = "x";
// Try to ensure that both libc and xz locale files have been
// loaded when NLS is enabled.
snprintf(NULL, 0, "%s%s", _(dummy_str), strerror(EINVAL));
// Try to ensure that iconv data files needed for handling multibyte
// characters have been loaded. This is needed at least with glibc.
tuklib_mbstr_width(dummy_str, NULL);
#ifdef HAVE_CAPSICUM
// Capsicum needs FreeBSD 10.0 or later.
cap_rights_t rights;
if (cap_rights_limit(src_fd, cap_rights_init(&rights,
CAP_EVENT, CAP_FCNTL, CAP_LOOKUP, CAP_READ, CAP_SEEK)))
goto error;
if (cap_rights_limit(STDOUT_FILENO, cap_rights_init(&rights,
CAP_EVENT, CAP_FCNTL, CAP_FSTAT, CAP_LOOKUP,
CAP_WRITE, CAP_SEEK)))
goto error;
if (cap_rights_limit(user_abort_pipe[0], cap_rights_init(&rights,
CAP_EVENT)))
goto error;
if (cap_rights_limit(user_abort_pipe[1], cap_rights_init(&rights,
CAP_WRITE)))
goto error;
if (cap_enter())
goto error;
#else
# error ENABLE_SANDBOX is defined but no sandboxing method was found.
#endif
message(V_DEBUG, _("Sandbox was successfully enabled"));
return;
error:
message(V_DEBUG, _("Failed to enable the sandbox"));
}
#endif // ENABLE_SANDBOX
#ifndef TUKLIB_DOSLIKE
/// \brief Waits for input or output to become available or for a signal
///
@@ -363,6 +459,22 @@ io_copy_attrs(const file_pair *pair)
(void)utimes(pair->dest_name, tv);
# endif
#elif defined(HAVE__FUTIME)
// Use one-second precision with Windows-specific _futime().
// We could use utime() too except that for some reason the
// timestamp will get reset at close(). With _futime() it works.
// This struct cannot be const as _futime() takes a non-const pointer.
struct _utimbuf buf = {
.actime = pair->src_st.st_atime,
.modtime = pair->src_st.st_mtime,
};
// Avoid warnings.
(void)atime_nsec;
(void)mtime_nsec;
(void)_futime(pair->dest_fd, &buf);
#elif defined(HAVE_UTIME)
// Use one-second precision. utime() doesn't support using file
// descriptor either. Some systems have broken utime() prototype
@@ -393,7 +505,11 @@ io_open_src_real(file_pair *pair)
#ifdef TUKLIB_DOSLIKE
setmode(STDIN_FILENO, O_BINARY);
#else
// Enable O_NONBLOCK for stdin.
// Try to set stdin to non-blocking mode. It won't work
// e.g. on OpenBSD if stdout is e.g. /dev/null. In such
// case we proceed as if stdin were non-blocking anyway
// (in case of /dev/null it will be in practice). The
// same applies to stdout in io_open_dest_real().
stdin_flags = fcntl(STDIN_FILENO, F_GETFL);
if (stdin_flags == -1) {
message_error(_("Error getting the file status flags "
@@ -402,21 +518,17 @@ io_open_src_real(file_pair *pair)
return true;
}
if ((stdin_flags & O_NONBLOCK) == 0) {
if (fcntl(STDIN_FILENO, F_SETFL,
stdin_flags | O_NONBLOCK) == -1) {
message_error(_("Error setting O_NONBLOCK "
"on standard input: %s"),
strerror(errno));
return true;
}
if ((stdin_flags & O_NONBLOCK) == 0
&& fcntl(STDIN_FILENO, F_SETFL,
stdin_flags | O_NONBLOCK) != -1)
restore_stdin_flags = true;
}
#endif
#ifdef HAVE_POSIX_FADVISE
// It will fail if stdin is a pipe and that's fine.
(void)posix_fadvise(STDIN_FILENO, 0, 0, POSIX_FADV_SEQUENTIAL);
(void)posix_fadvise(STDIN_FILENO, 0, 0,
opt_mode == MODE_LIST
? POSIX_FADV_RANDOM
: POSIX_FADV_SEQUENTIAL);
#endif
return false;
}
@@ -607,7 +719,10 @@ io_open_src_real(file_pair *pair)
#ifdef HAVE_POSIX_FADVISE
// It will fail with some special files like FIFOs but that is fine.
(void)posix_fadvise(pair->src_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
(void)posix_fadvise(pair->src_fd, 0, 0,
opt_mode == MODE_LIST
? POSIX_FADV_RANDOM
: POSIX_FADV_SEQUENTIAL);
#endif
return false;
@@ -646,6 +761,11 @@ io_open_src(const char *src_name)
const bool error = io_open_src_real(&pair);
signals_unblock();
#ifdef ENABLE_SANDBOX
if (!error)
io_sandbox_enter(pair.src_fd);
#endif
return error ? NULL : &pair;
}
@@ -672,23 +792,22 @@ io_close_src(file_pair *pair, bool success)
#endif
if (pair->src_fd != STDIN_FILENO && pair->src_fd != -1) {
#ifdef TUKLIB_DOSLIKE
(void)close(pair->src_fd);
#endif
// If we are going to unlink(), do it before closing the file.
// This way there's no risk that someone replaces the file and
// happens to get same inode number, which would make us
// unlink() wrong file.
// Close the file before possibly unlinking it. On DOS-like
// systems this is always required since unlinking will fail
// if the file is open. On POSIX systems it usually works
// to unlink open files, but in some cases it doesn't and
// one gets EBUSY in errno.
//
// NOTE: DOS-like systems are an exception to this, because
// they don't allow unlinking files that are open. *sigh*
// xz 5.2.2 and older unlinked the file before closing it
// (except on DOS-like systems). The old code didn't handle
// EBUSY and could fail e.g. on some CIFS shares. The
// advantage of unlinking before closing is negligible
// (avoids a race between close() and stat()/lstat() and
// unlink()), so let's keep this simple.
(void)close(pair->src_fd);
if (success && !opt_keep_original)
io_unlink(pair->src_name, &pair->src_st);
#ifndef TUKLIB_DOSLIKE
(void)close(pair->src_fd);
#endif
}
return;
@@ -705,7 +824,10 @@ io_open_dest_real(file_pair *pair)
#ifdef TUKLIB_DOSLIKE
setmode(STDOUT_FILENO, O_BINARY);
#else
// Set O_NONBLOCK if it isn't already set.
// Try to set O_NONBLOCK if it isn't already set.
// If it fails, we assume that stdout is non-blocking
// in practice. See the comments in io_open_src_real()
// for similar situation with stdin.
//
// NOTE: O_APPEND may be unset later in this function
// and it relies on stdout_flags being set here.
@@ -717,17 +839,10 @@ io_open_dest_real(file_pair *pair)
return true;
}
if ((stdout_flags & O_NONBLOCK) == 0) {
if (fcntl(STDOUT_FILENO, F_SETFL,
stdout_flags | O_NONBLOCK) == -1) {
message_error(_("Error setting O_NONBLOCK "
"on standard output: %s"),
strerror(errno));
return true;
}
restore_stdout_flags = true;
}
if ((stdout_flags & O_NONBLOCK) == 0
&& fcntl(STDOUT_FILENO, F_SETFL,
stdout_flags | O_NONBLOCK) != -1)
restore_stdout_flags = true;
#endif
} else {
pair->dest_name = suffix_get_dest_name(pair->src_name);
@@ -742,6 +857,7 @@ io_open_dest_real(file_pair *pair)
message_error("%s: Refusing to write to "
"a DOS special file",
pair->dest_name);
free(pair->dest_name);
return true;
}
@@ -751,6 +867,7 @@ io_open_dest_real(file_pair *pair)
message_error("%s: Output file is the same "
"as the input file",
pair->dest_name);
free(pair->dest_name);
return true;
}
}
@@ -829,23 +946,24 @@ io_open_dest_real(file_pair *pair)
if (lseek(STDOUT_FILENO, 0, SEEK_END) == -1)
return false;
// O_NONBLOCK was set earlier in this function
// so it must be kept here too. If this
// fcntl() call fails, we continue but won't
// Construct the new file status flags.
// If O_NONBLOCK was set earlier in this
// function, it must be kept here too.
int flags = stdout_flags & ~O_APPEND;
if (restore_stdout_flags)
flags |= O_NONBLOCK;
// If this fcntl() fails, we continue but won't
// try to create sparse output. The original
// flags will still be restored if needed (to
// unset O_NONBLOCK) when the file is finished.
if (fcntl(STDOUT_FILENO, F_SETFL,
(stdout_flags | O_NONBLOCK)
& ~O_APPEND) == -1)
if (fcntl(STDOUT_FILENO, F_SETFL, flags) == -1)
return false;
// Disabling O_APPEND succeeded. Mark
// that the flags should be restored
// in io_close_dest(). This quite likely was
// already set when enabling O_NONBLOCK but
// just in case O_NONBLOCK was already set,
// set this again here.
// in io_close_dest(). (This may have already
// been set when enabling O_NONBLOCK.)
restore_stdout_flags = true;
} else if (lseek(STDOUT_FILENO, 0, SEEK_CUR)
@@ -1016,7 +1134,7 @@ io_read(file_pair *pair, io_buf *buf_union, size_t size)
}
#ifndef TUKLIB_DOSLIKE
if (errno == EAGAIN || errno == EWOULDBLOCK) {
if (IS_EAGAIN_OR_EWOULDBLOCK(errno)) {
const io_wait_ret ret = io_wait(pair,
mytime_get_flush_timeout(),
true);
@@ -1051,16 +1169,30 @@ io_read(file_pair *pair, io_buf *buf_union, size_t size)
extern bool
io_pread(file_pair *pair, io_buf *buf, size_t size, off_t pos)
io_seek_src(file_pair *pair, off_t pos)
{
// Using lseek() and read() is more portable than pread() and
// for us it is as good as real pread().
assert(pos >= 0);
if (lseek(pair->src_fd, pos, SEEK_SET) != pos) {
message_error(_("%s: Error seeking the file: %s"),
pair->src_name, strerror(errno));
return true;
}
pair->src_eof = false;
return false;
}
extern bool
io_pread(file_pair *pair, io_buf *buf, size_t size, off_t pos)
{
// Using lseek() and read() is more portable than pread() and
// for us it is as good as real pread().
if (io_seek_src(pair, pos))
return true;
const size_t amount = io_read(pair, buf, size);
if (amount == SIZE_MAX)
return true;
@@ -1104,7 +1236,7 @@ io_write_buf(file_pair *pair, const uint8_t *buf, size_t size)
}
#ifndef TUKLIB_DOSLIKE
if (errno == EAGAIN || errno == EWOULDBLOCK) {
if (IS_EAGAIN_OR_EWOULDBLOCK(errno)) {
if (io_wait(pair, -1, false) == IO_WAIT_MORE)
continue;

View File

@@ -80,6 +80,12 @@ extern void io_write_to_user_abort_pipe(void);
extern void io_no_sparse(void);
#ifdef ENABLE_SANDBOX
/// \brief main() calls this if conditions for sandboxing have been met.
extern void io_allow_sandbox(void);
#endif
/// \brief Open the source file
extern file_pair *io_open_src(const char *src_name);
@@ -123,6 +129,19 @@ extern size_t io_read(file_pair *pair, io_buf *buf, size_t size);
extern void io_fix_src_pos(file_pair *pair, size_t rewind_size);
/// \brief Seek to the given absolute position in the source file
///
/// This calls lseek() and also clears pair->src_eof.
///
/// \param pair Seekable source file
/// \param pos Offset relative to the beginning of the file,
/// from which the data should be read.
///
/// \return On success, false is returned. On error, error message
/// is printed and true is returned.
extern bool io_seek_src(file_pair *pair, off_t pos);
/// \brief Read from source file from given offset to a buffer
///
/// This is remotely similar to standard pread(). This uses lseek() though,

View File

@@ -109,7 +109,7 @@ static struct {
uint32_t checks;
uint32_t min_version;
bool all_have_sizes;
} totals = { 0, 0, 0, 0, 0, 0, 0, 0, 0, true };
} totals = { 0, 0, 0, 0, 0, 0, 0, 0, 50000002, true };
/// Convert XZ Utils version number to a string.
@@ -143,9 +143,6 @@ xz_ver_to_str(uint32_t ver)
///
/// \return On success, false is returned. On error, true is returned.
///
// TODO: This function is pretty big. liblzma should have a function that
// takes a callback function to parse the Index(es) from a .xz file to make
// it easy for applications.
static bool
parse_indexes(xz_file_info *xfi, file_pair *pair)
{
@@ -161,238 +158,75 @@ parse_indexes(xz_file_info *xfi, file_pair *pair)
}
io_buf buf;
lzma_stream_flags header_flags;
lzma_stream_flags footer_flags;
lzma_ret ret;
// lzma_stream for the Index decoder
lzma_stream strm = LZMA_STREAM_INIT;
lzma_index *idx = NULL;
// All Indexes decoded so far
lzma_index *combined_index = NULL;
// The Index currently being decoded
lzma_index *this_index = NULL;
// Current position in the file. We parse the file backwards so
// initialize it to point to the end of the file.
off_t pos = pair->src_st.st_size;
// Each loop iteration decodes one Index.
do {
// Check that there is enough data left to contain at least
// the Stream Header and Stream Footer. This check cannot
// fail in the first pass of this loop.
if (pos < 2 * LZMA_STREAM_HEADER_SIZE) {
message_error("%s: %s", pair->src_name,
message_strm(LZMA_DATA_ERROR));
goto error;
}
pos -= LZMA_STREAM_HEADER_SIZE;
lzma_vli stream_padding = 0;
// Locate the Stream Footer. There may be Stream Padding which
// we must skip when reading backwards.
while (true) {
if (pos < LZMA_STREAM_HEADER_SIZE) {
message_error("%s: %s", pair->src_name,
message_strm(
LZMA_DATA_ERROR));
goto error;
}
if (io_pread(pair, &buf,
LZMA_STREAM_HEADER_SIZE, pos))
goto error;
// Stream Padding is always a multiple of four bytes.
int i = 2;
if (buf.u32[i] != 0)
break;
// To avoid calling io_pread() for every four bytes
// of Stream Padding, take advantage that we read
// 12 bytes (LZMA_STREAM_HEADER_SIZE) already and
// check them too before calling io_pread() again.
do {
stream_padding += 4;
pos -= 4;
--i;
} while (i >= 0 && buf.u32[i] == 0);
}
// Decode the Stream Footer.
ret = lzma_stream_footer_decode(&footer_flags, buf.u8);
if (ret != LZMA_OK) {
message_error("%s: %s", pair->src_name,
message_strm(ret));
goto error;
}
// Check that the Stream Footer doesn't specify something
// that we don't support. This can only happen if the xz
// version is older than liblzma and liblzma supports
// something new.
//
// It is enough to check Stream Footer. Stream Header must
// match when it is compared against Stream Footer with
// lzma_stream_flags_compare().
if (footer_flags.version != 0) {
message_error("%s: %s", pair->src_name,
message_strm(LZMA_OPTIONS_ERROR));
goto error;
}
// Check that the size of the Index field looks sane.
lzma_vli index_size = footer_flags.backward_size;
if ((lzma_vli)(pos) < index_size + LZMA_STREAM_HEADER_SIZE) {
message_error("%s: %s", pair->src_name,
message_strm(LZMA_DATA_ERROR));
goto error;
}
// Set pos to the beginning of the Index.
pos -= index_size;
// See how much memory we can use for decoding this Index.
uint64_t memlimit = hardware_memlimit_get(MODE_LIST);
uint64_t memused = 0;
if (combined_index != NULL) {
memused = lzma_index_memused(combined_index);
if (memused > memlimit)
message_bug();
memlimit -= memused;
}
// Decode the Index.
ret = lzma_index_decoder(&strm, &this_index, memlimit);
if (ret != LZMA_OK) {
message_error("%s: %s", pair->src_name,
message_strm(ret));
goto error;
}
do {
// Don't give the decoder more input than the
// Index size.
strm.avail_in = my_min(IO_BUFFER_SIZE, index_size);
if (io_pread(pair, &buf, strm.avail_in, pos))
goto error;
pos += strm.avail_in;
index_size -= strm.avail_in;
lzma_ret ret = lzma_file_info_decoder(&strm, &idx,
hardware_memlimit_get(MODE_LIST),
(uint64_t)(pair->src_st.st_size));
if (ret != LZMA_OK) {
message_error("%s: %s", pair->src_name, message_strm(ret));
return true;
}
while (true) {
if (strm.avail_in == 0) {
strm.next_in = buf.u8;
ret = lzma_code(&strm, LZMA_RUN);
strm.avail_in = io_read(pair, &buf, IO_BUFFER_SIZE);
if (strm.avail_in == SIZE_MAX)
goto error;
}
} while (ret == LZMA_OK);
ret = lzma_code(&strm, LZMA_RUN);
// If the decoding seems to be successful, check also that
// the Index decoder consumed as much input as indicated
// by the Backward Size field.
if (ret == LZMA_STREAM_END)
if (index_size != 0 || strm.avail_in != 0)
ret = LZMA_DATA_ERROR;
switch (ret) {
case LZMA_OK:
break;
if (ret != LZMA_STREAM_END) {
// LZMA_BUFFER_ERROR means that the Index decoder
// would have liked more input than what the Index
// size should be according to Stream Footer.
// The message for LZMA_DATA_ERROR makes more
// sense in that case.
if (ret == LZMA_BUF_ERROR)
ret = LZMA_DATA_ERROR;
case LZMA_SEEK_NEEDED:
// The cast is safe because liblzma won't ask us to
// seek past the known size of the input file which
// did fit into off_t.
assert(strm.seek_pos
<= (uint64_t)(pair->src_st.st_size));
if (io_seek_src(pair, (off_t)(strm.seek_pos)))
goto error;
// avail_in must be zero so that we will read new
// input.
strm.avail_in = 0;
break;
case LZMA_STREAM_END: {
lzma_end(&strm);
xfi->idx = idx;
// Calculate xfi->stream_padding.
lzma_index_iter iter;
lzma_index_iter_init(&iter, xfi->idx);
while (!lzma_index_iter_next(&iter,
LZMA_INDEX_ITER_STREAM))
xfi->stream_padding += iter.stream.padding;
return false;
}
default:
message_error("%s: %s", pair->src_name,
message_strm(ret));
// If the error was too low memory usage limit,
// show also how much memory would have been needed.
if (ret == LZMA_MEMLIMIT_ERROR) {
uint64_t needed = lzma_memusage(&strm);
if (UINT64_MAX - needed < memused)
needed = UINT64_MAX;
else
needed += memused;
message_mem_needed(V_ERROR, needed);
}
if (ret == LZMA_MEMLIMIT_ERROR)
message_mem_needed(V_ERROR,
lzma_memusage(&strm));
goto error;
}
// Decode the Stream Header and check that its Stream Flags
// match the Stream Footer.
pos -= footer_flags.backward_size + LZMA_STREAM_HEADER_SIZE;
if ((lzma_vli)(pos) < lzma_index_total_size(this_index)) {
message_error("%s: %s", pair->src_name,
message_strm(LZMA_DATA_ERROR));
goto error;
}
pos -= lzma_index_total_size(this_index);
if (io_pread(pair, &buf, LZMA_STREAM_HEADER_SIZE, pos))
goto error;
ret = lzma_stream_header_decode(&header_flags, buf.u8);
if (ret != LZMA_OK) {
message_error("%s: %s", pair->src_name,
message_strm(ret));
goto error;
}
ret = lzma_stream_flags_compare(&header_flags, &footer_flags);
if (ret != LZMA_OK) {
message_error("%s: %s", pair->src_name,
message_strm(ret));
goto error;
}
// Store the decoded Stream Flags into this_index. This is
// needed so that we can print which Check is used in each
// Stream.
ret = lzma_index_stream_flags(this_index, &footer_flags);
if (ret != LZMA_OK)
message_bug();
// Store also the size of the Stream Padding field. It is
// needed to show the offsets of the Streams correctly.
ret = lzma_index_stream_padding(this_index, stream_padding);
if (ret != LZMA_OK)
message_bug();
if (combined_index != NULL) {
// Append the earlier decoded Indexes
// after this_index.
ret = lzma_index_cat(
this_index, combined_index, NULL);
if (ret != LZMA_OK) {
message_error("%s: %s", pair->src_name,
message_strm(ret));
goto error;
}
}
combined_index = this_index;
this_index = NULL;
xfi->stream_padding += stream_padding;
} while (pos > 0);
lzma_end(&strm);
// All OK. Make combined_index available to the caller.
xfi->idx = combined_index;
return false;
}
error:
// Something went wrong, free the allocated memory.
lzma_end(&strm);
lzma_index_end(combined_index, NULL);
lzma_index_end(this_index, NULL);
return true;
}
@@ -484,6 +318,8 @@ parse_block_header(file_pair *pair, const lzma_index_iter *iter,
// If the above fails, the file is corrupt so
// LZMA_DATA_ERROR is a good error code.
// Fall through
case LZMA_DATA_ERROR:
// Free the memory allocated by lzma_block_header_decode().
for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i)
@@ -636,7 +472,11 @@ static void
get_check_names(char buf[CHECKS_STR_SIZE],
uint32_t checks, bool space_after_comma)
{
assert(checks != 0);
// If we get called when there are no Checks to print, set checks
// to 1 so that we print "None". This can happen in the robot mode
// when printing the totals line if there are no valid input files.
if (checks == 0)
checks = 1;
char *pos = buf;
size_t left = CHECKS_STR_SIZE;

Some files were not shown because too many files have changed in this diff Show More