Blame p7zip

396e10
#!/bin/sh
396e10
# gzip-like CLI wrapper for p7zip
396e10
# version 3.0
396e10
#
396e10
# History
396e10
#  2.0 :
396e10
#    - support for -filename, "file name"
396e10
#    - p7zip file1 file2 ...
396e10
#  3.0 :  (robert@debian.org, March 2016)
396e10
#    - use 7za or 7zr, whichever one is available
396e10
#    - refactor the script for better readability
396e10
#    - remove `"$?" != 0 ' checks that do not work with `set -e'
396e10
#    - use stderr for error reporting
396e10
#    - add support for -c, -f, -k options
396e10
396e10
set -e
396e10
396e10
# detect 7z program to use
396e10
prg7z="`which 7za 2>/dev/null`" || \
396e10
  prg7z="`which 7zr 2>/dev/null`" || \
396e10
    { echo "$0: cannot find neither 7za nor 7zr command" >&2; exit 1; }
396e10
396e10
# global options
396e10
f_compress=true
396e10
f_keep=false
396e10
f_force=false
396e10
f_tostdout=false
396e10
396e10
usage()
396e10
{
396e10
  echo "Usage: $0 [options] [--] [ name ... ]"
396e10
  echo ""
396e10
  echo "Options:"
396e10
  echo "    -c --stdout --to-stdout      output data to stdout"
396e10
  echo "    -d --decompress --uncompress decompress file"
396e10
  echo "    -f --force                   do not ask questions"
396e10
  echo "    -k --keep                    keep original file"
396e10
  echo "    -h --help                    print this help"
396e10
  echo "    --                           treat subsequent arguments as file"
396e10
  echo "                                 names, even if they start with a dash"
396e10
  echo ""
396e10
  exit 0
396e10
}
396e10
396e10
has_7z_suffix()
396e10
{
396e10
  case "$1" in
396e10
    *.7z)
396e10
      return 0
396e10
      ;;
396e10
    *)
396e10
      return 1
396e10
      ;;
396e10
  esac;
396e10
}
396e10
396e10
make_tmp_file()
396e10
{
396e10
  P7ZIPTMP="${TMP:-/tmp}"
396e10
  mktemp "${P7ZIPTMP}/p7zip.XXXXXXXX"
396e10
}
396e10
396e10
check_not_a_tty()
396e10
{
396e10
  if ! ${f_force} && ${f_compress} && tty <&1 >/dev/null ; then
396e10
    echo "$0: compressed data not written to a terminal." >&2
396e10
    echo "For help, type: $0 -h" >&2
396e10
    exit 1
396e10
  fi
396e10
}
396e10
396e10
compress_file()
396e10
{
396e10
  file="$1"
396e10
396e10
  if ! ${f_force} && has_7z_suffix "${file}"; then
396e10
    echo "$0: $file already has the 7z suffix" >&2
396e10
    exit 1
396e10
  fi
396e10
396e10
  # compress to stdout via temporary file
396e10
  if ${f_tostdout}; then
396e10
    check_not_a_tty
396e10
    tmp="`make_tmp_file`"
396e10
    trap "rm -f -- ${tmp}" 0
396e10
    rm -f -- "${tmp}"
396e10
    "${prg7z}" a -si -- "${tmp}" < "${file}" >/dev/null && cat "${tmp}" || \
396e10
      { echo "$0: failed to compress data to temporary file" >&2;  exit 1; }
396e10
    rm -f -- "${tmp}"
396e10
    return 0
396e10
  fi
396e10
396e10
  # compress to a file
396e10
  if ! ${f_force} && [ -e "${file}.7z" ]; then
396e10
    echo "$0: destination file ${file}.7z already exists" >&2
396e10
    exit 1
396e10
  fi
396e10
396e10
  rm -f -- "${file}.7z"
396e10
  flags=""
396e10
  ${f_keep} || flags="$flags -sdel"
396e10
  ! ${f_force} || flags="$flags -y"
396e10
  "${prg7z}" a $flags -- "${file}.7z" "${file}" || {  rm -f -- "${file}.7z"; exit 1; }
396e10
}
396e10
396e10
396e10
decompress_file()
396e10
{
396e10
  file="$1"
396e10
396e10
  has_7z_suffix "${file}" || { echo "$0: ${file}: unknown suffix" >&2; exit 1; }
396e10
396e10
  # decompress to stdout
396e10
  if ${f_tostdout}; then
396e10
    # The following `| cat' pipe shouldn't be needed, however it is here to
396e10
    # trick 7z not to complain about writing data to terminal.
396e10
    "${prg7z}" x -so -- "${file}" | cat || exit 1
396e10
    return 0;
396e10
  fi
396e10
396e10
  flags=""
396e10
  ! ${f_force} || flags="$flags -y"
396e10
  "${prg7z}" x $flags -- "${file}" || exit 1
396e10
396e10
  # remove original file unless the archive contains more than one file
396e10
  if ! ${f_keep} && "${prg7z}" l --  "${file}" 2>/dev/null | grep -q '^1 file,' 2>/dev/null; then
396e10
    rm -f -- "${file}"
396e10
  fi
396e10
}
396e10
396e10
process_file()
396e10
{
396e10
  file="$1"
396e10
396e10
  # check if file exists and is readable
396e10
  [ -r "${file}" ] || { echo "$0: cannot read ${file}" >&2; exit 1; }
396e10
396e10
  if ${f_compress}; then
396e10
    compress_file "${file}"
396e10
  else
396e10
    decompress_file "${file}"
396e10
  fi
396e10
}
396e10
396e10
process_stdin()
396e10
{
396e10
  check_not_a_tty
396e10
396e10
  tmp="`make_tmp_file`"
396e10
  trap "rm -f -- ${tmp}" 0
396e10
396e10
  if ${f_compress}; then
396e10
396e10
    rm -f -- "${tmp}"
396e10
    "${prg7z}" a -si -- "${tmp}" >/dev/null && cat -- "${tmp}" || exit 1
396e10
396e10
  else # decompress
396e10
396e10
    cat > "${tmp}"
396e10
    # The following `| cat' pipe shouldn't be needed, however it is here to
396e10
    # trick 7z not to complain about writing data to terminal.
396e10
    "${prg7z}" x -so -- "${tmp}" | cat || exit 1
396e10
  fi
396e10
396e10
  rm -f -- "${tmp}"
396e10
}
396e10
396e10
396e10
## MAIN
396e10
396e10
396e10
# files and flags
396e10
while [ "$#" != "0" ] ; do
396e10
  case "$1" in
396e10
    -c|--stdout|--to-stdout)
396e10
      f_tostdout=true
396e10
      ;;
396e10
    -d|--decompress|--uncompress)
396e10
      f_compress=false # decompressing
396e10
      ;;
396e10
    -f|--force)
396e10
      f_force=true
396e10
      ;;
396e10
    -h|--help)
396e10
      usage
396e10
      ;;
396e10
    -k|--keep)
396e10
      f_keep=true
396e10
      ;;
396e10
    --)
396e10
      shift
396e10
      break
396e10
      ;;
396e10
    -*)
396e10
      echo "$0: ignoring unknown option $1" >&2
396e10
      ;;
396e10
    *)
396e10
      break
396e10
      ;;
396e10
  esac
396e10
  shift
396e10
done
396e10
396e10
396e10
# make sure they're present, before we screw up
396e10
for i in mktemp rm cat tty grep; do
396e10
  if ! which $i >/dev/null ; then
396e10
    echo "$0: $i: command not found" >&2
396e10
    exit 1
396e10
  fi
396e10
done
396e10
396e10
if [ "$#" = 0 ]; then
396e10
  # compressing/decompressing using standard I/O
396e10
  process_stdin
396e10
  exit 0
396e10
fi
396e10
396e10
# only files now
396e10
while [ "$#" != "0" ] ; do
396e10
  process_file  "$1"
396e10
  shift
396e10
done
396e10
396e10
exit 0