diff options
Diffstat (limited to 'src/vfs/extfs/helpers/u7z')
-rwxr-xr-x | src/vfs/extfs/helpers/u7z | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/src/vfs/extfs/helpers/u7z b/src/vfs/extfs/helpers/u7z new file mode 100755 index 0000000..91301c3 --- /dev/null +++ b/src/vfs/extfs/helpers/u7z @@ -0,0 +1,135 @@ +#! /bin/sh +# +# extfs support for p7zip +# Written by Pavel Roskin <proski@gnu.org> +# Some Bugfixes/workarounds by Sergiy Niskorodov <sgh@mail.zp.ua> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +P7ZIP=`which 7z 2>/dev/null` \ + || P7ZIP=`which 7zz 2>/dev/null` \ + || P7ZIP=`which 7za 2>/dev/null` \ + || P7ZIP=`which 7zr 2>/dev/null` \ + || P7ZIP="" + +# Let the test framework hook in: +P7ZIP=${MC_TEST_EXTFS_LIST_CMD:-$P7ZIP} +STAT=${MC_TEST_EXTFS_U7Z_STAT:-stat} + +mcu7zip_list () +{ + # Symlinks are not shown - no idea how to distinguish them + # Read-only files are not shown as such - it's rarely useful + + ugid="`id -nu` `id -ng`" + + date_re='^\(....\)-\(..\)-\(..\) \(..:..:..\)' # 19 chars. + date_mc='\2-\3-\1 \4' + empty_date_re='^ \{19\}' + + size_re='............' # 12 chars. + empty_size_re=' \{12\}' + zero_size=' 0' + + # archive entries can have no datetime info, 7z will use archive file datetime + date_archive=`$STAT -c %y "$1" 2>/dev/null | sed -n "s/${date_re}.*/${date_mc}/p" 2>/dev/null` + [ "${date_archive}"x = x ] && date_archive=`ls -lan "$1" 2>/dev/null | awk '{print $6, $7, $8}' 2>/dev/null` + [ "${date_archive}"x = x ] && date_archive="01-01-1970 00:00:00" + + $P7ZIP l "$1" | sed -n " + + # If the uncompressed size is missing, we copy the compressed size onto it. + # + # But first, if the compressed size is missing too, set it to zero: + s/^\(.\{19\} [D.]....\) $empty_size_re $empty_size_re/\1 $zero_size $zero_size/ + # Next, do the copy: + s/^\(.\{19\} [D.]....\) $empty_size_re \($size_re\)/\1 \2 \2/ + # + # (We use '.\{19\}' as the date may be missing. It may give false positives + # but we don't mind: the printing commands that follow use strict patterns.). + + # Handle directories. + s/$date_re D.... $size_re $size_re\(.*\)/drwxr-xr-x 1 $ugid 0 $date_mc \5/p + s/$empty_date_re D.... $size_re $size_re\(.*\)/drwxr-xr-x 1 $ugid 0 $date_archive \1/p + + # Handle normal files. + s/$date_re \..... \($size_re\) $size_re\(.*\)/-rw-r--r-- 1 $ugid \5 $date_mc \6/p + s/$empty_date_re \..... \($size_re\) $size_re\(.*\)/-rw-r--r-- 1 $ugid \1 $date_archive \2/p + " +} + +mcu7zip_copyout () +{ + #first we check if we have old p7zip archive with prefix ./ in filename + $P7ZIP l "$1" "$2" | grep -q "0 files, 0 folders" && \ + EXFNAME='*./'"$2" || EXFNAME="$2" + $P7ZIP e -so "$1" "$EXFNAME" > "$3" 2>/dev/null +} + +mcu7zip_copyin () +{ + $P7ZIP a -si"$2" "$1" <"$3" >/dev/null 2>&1 +} + +mcu7zip_mkdir () +{ + dir=`mktemp -d "${MC_TMPDIR:-/tmp}/mctmpdir-u7z.XXXXXX"` || exit 1 + mkdir -p "$dir"/"$2" + $P7ZIP a -w"$dir" "$1" "$dir"/"$2" >/dev/null 2>&1 + rm -rf "$dir" +} + +mcu7zip_rm () +{ + # NOTE: Version 4.20 fails to delete files in subdirectories + #first we check if we have old p7zip archive with prefix ./ in filename + $P7ZIP l "$1" "$2" | grep -q "0 files, 0 folders" && \ + EXFNAME='*./'"$2" || EXFNAME="$2" + $P7ZIP d "$1" "$EXFNAME" 2>&1 | grep -q E_NOTIMPL > /dev/null 2>&1 && \ + { printf "Function not implemented...\n7z cannot delete from solid archive." >&2 ; exit 1 ; } +} + +mcu7zip_rmdir () +{ + #first we check if we have old p7zip archive with prefix ./ in filename + $P7ZIP l "$1" "$2" | grep -q "0 files, 0 folders" && \ + EXFNAME='*./'"$2" || EXFNAME="$2" + $P7ZIP d "$1" "$EXFNAME"/ 2>&1 | grep -q E_NOTIMPL > /dev/null 2>&1 && \ + { printf "Function not implemented...\n7z cannot delete from solid archive." >&2 ; exit 1 ; } +} + +# override any locale for dates +LC_DATE=C +export LC_DATE + +umask 077 + +if [ -z "$P7ZIP" ]; then + echo "Error: could not find p7zip (looked for 7z, 7za and 7zr)" >&2 + exit 1 +fi + +cmd="$1" +shift + +case "$cmd" in + list) mcu7zip_list "$@" | sort -k 8 ;; + copyout) mcu7zip_copyout "$@" ;; + copyin) mcu7zip_copyin "$@" ;; + mkdir) mcu7zip_mkdir "$@" ;; + rm) mcu7zip_rm "$@" ;; + rmdir) mcu7zip_rmdir "$@" ;; + *) exit 1 ;; +esac +exit 0 |