Index: xz/extra/7z2lzma/7z2lzma.bash |
=================================================================== |
--- xz/extra/7z2lzma/7z2lzma.bash (revision 0) |
+++ xz/extra/7z2lzma/7z2lzma.bash (revision 0) |
@@ -0,0 +1,115 @@ |
+#!/bin/bash |
+# |
+############################################################################# |
+# |
+# 7z2lzma.bash is very primitive .7z to .lzma converter. The input file must |
+# have exactly one LZMA compressed stream, which has been created with the |
+# default lc, lp, and pb values. The CRC32 in the .7z archive is not checked, |
+# and the script may seem to succeed while it actually created a corrupt .lzma |
+# file. You should always try uncompressing both the original .7z and the |
+# created .lzma and compare that the output is identical. |
+# |
+# This script requires basic GNU tools and 7z or 7za tool from p7zip. |
+# |
+# Last modified: 2009-01-15 14:25+0200 |
+# |
+############################################################################# |
+# |
+# Author: Lasse Collin <lasse.collin@tukaani.org> |
+# |
+# This file has been put into the public domain. |
+# You can do whatever you want with this file. |
+# |
+############################################################################# |
+ |
+# You can use 7z or 7za, both will work. |
+SEVENZIP=7za |
+ |
+if [ $# != 2 -o -z "$1" -o -z "$2" ]; then |
+ echo "Usage: $0 input.7z output.lzma" |
+ exit 1 |
+fi |
+ |
+# Converts an integer variable to little endian binary integer. |
+int2bin() |
+{ |
+ local LEN=$1 |
+ local NUM=$2 |
+ local HEX=(0 1 2 3 4 5 6 7 8 9 A B C D E F) |
+ local I |
+ for ((I=0; I < "$LEN"; ++I)); do |
+ printf "\\x${HEX[(NUM >> 4) & 0x0F]}${HEX[NUM & 0x0F]}" |
+ NUM=$((NUM >> 8)) |
+ done |
+} |
+ |
+# Make sure we get possible errors from pipes. |
+set -o pipefail |
+ |
+# Get information about the input file. At least older 7z and 7za versions |
+# may return with zero exit status even when an error occurred, so check |
+# if the output has any lines beginning with "Error". |
+INFO=$("$SEVENZIP" l -slt "$1") |
+if [ $? != 0 ] || printf '%s\n' "$INFO" | grep -q ^Error; then |
+ printf '%s\n' "$INFO" |
+ exit 1 |
+fi |
+ |
+# Check if the input file has more than one compressed block. |
+if printf '%s\n' "$INFO" | grep -q '^Block = 1'; then |
+ echo "Cannot convert, because the input file has more than" |
+ echo "one compressed block." |
+ exit 1 |
+fi |
+ |
+# Get compressed, uncompressed, and dictionary size. |
+CSIZE=$(printf '%s\n' "$INFO" | sed -rn 's|^Packed Size = ([0-9]+$)|\1|p') |
+USIZE=$(printf '%s\n' "$INFO" | sed -rn 's|^Size = ([0-9]+$)|\1|p') |
+DICT=$(printf '%s\n' "$INFO" | sed -rn 's|^Method = LZMA:([0-9]+[bkm]?)$|\1|p') |
+ |
+if [ -z "$CSIZE" -o -z "$USIZE" -o -z "$DICT" ]; then |
+ echo "Parsing output of $SEVENZIP failed. Maybe the file uses some" |
+ echo "other compression method than plain LZMA." |
+ exit 1 |
+fi |
+ |
+# The following assumes that the default lc, lp, and pb settings were used. |
+# Otherwise the output will be corrupt. |
+printf '\x5D' > "$2" |
+ |
+# Dictionary size can be either was power of two, bytes, kibibytes, or |
+# mebibytes. We need to convert it to bytes. |
+case $DICT in |
+ *b) |
+ DICT=${DICT%b} |
+ ;; |
+ *k) |
+ DICT=${DICT%k} |
+ DICT=$((DICT << 10)) |
+ ;; |
+ *m) |
+ DICT=${DICT%m} |
+ DICT=$((DICT << 20)) |
+ ;; |
+ *) |
+ DICT=$((1 << DICT)) |
+ ;; |
+esac |
+int2bin 4 "$DICT" >> "$2" |
+ |
+# Uncompressed size |
+int2bin 8 "$USIZE" >> "$2" |
+ |
+# Copy the actual compressed data. Using multiple dd commands to avoid |
+# copying large amount of data with one-byte block size, which would be |
+# annoyingly slow. |
+BS=8192 |
+BIGSIZE=$((CSIZE / BS)) |
+CSIZE=$((CSIZE % BS)) |
+{ |
+ dd of=/dev/null bs=32 count=1 \ |
+ && dd bs="$BS" count="$BIGSIZE" \ |
+ && dd bs=1 count="$CSIZE" |
+} < "$1" >> "$2" |
+ |
+exit $? |
Property changes on: xz/extra/7z2lzma/7z2lzma.bash |
___________________________________________________________________ |
Added: svn:executable |
+ * |
Added: svn:eol-style |
+ LF |