#!/bin/bash

###############################################################################
# PackIt v1.14 by SFR'2013-2016                                               #
# GNU GPL v2 applies                                                          #
###############################################################################

APPNAME="PackIt"
VERSION="v1.14"

[ "`which realpath 2>/dev/null`" ] || alias realpath='readlink -f'

MYNAME="$(realpath "$0")"
MYPATH="$(dirname "$MYNAME")"
PATH="${MYPATH}/resources:${PATH}"
LD_LIBRARY_PATH="${MYPATH}/resources:${LD_LIBRARY_PATH}"

export TEXTDOMAINDIR="${MYPATH}/locale"
export TEXTDOMAIN=packit
export OUTPUT_CHARSET=UTF-8

TMPDIR=/tmp/packit_temp_${$}
mkdir -p $TMPDIR

TMPMNT=${TMPDIR}/packit_mntpt_${$}
mkdir -p $TMPMNT

OLDDIR="$(pwd)"

trap 'cd "$OLDDIR"; umount "$TMPMNT" 2>/dev/null; rm -rf $TMPDIR' EXIT

export TMP_INPUT=${TMPDIR}/input			; : > $TMP_INPUT
export TMP_PASS1=${TMPDIR}/pass1			; : > $TMP_PASS1
export TMP_PASS2=${TMPDIR}/pass2			; : > $TMP_PASS2
export TMP_OUTPUT_DIR=${TMPDIR}/outdir		; : > $TMP_OUTPUT_DIR
export TMP_ARCHNAME=${TMPDIR}/archname		; : > $TMP_ARCHNAME
export TMP_EXT=${TMPDIR}/ext				; : > $TMP_EXT
export TMP_MKSQ_LIST=${TMPDIR}/mksqlist		; : > $TMP_MKSQ_LIST

TMP_EXEC=${TMPDIR}/packit_exec

APPICON="${MYPATH}/PackIt.png"

# -----------------------------------------------------------------------------

[ "`which gtkdialog4 2>/dev/null`" ] && GTKDIALOG=gtkdialog4 || GTKDIALOG=gtkdialog

func_vercmp_gt () {
  [ "${1}" != "$(echo -e "${1}\n${2}" | sort -t '.' -k1,1n -k2,2n -k3,3n -k4,4n -k5,5n | head -n1)" ]
}

GTKDLG_VER="`$GTKDIALOG -v 2>/dev/null | grep -Eo 'version.*\.[0-9] ' | cut -f2 -d ' '`"

if func_vercmp_gt "0.8.0" "${GTKDLG_VER}"; then
  export GUI_REQUIREMENTS='
    <window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
      <vbox>
        <pixmap><input file stock="gtk-dialog-warning"></input></pixmap>
        <text><label>""</label></text>
        <text><label>'$(gettext "Please install Gtkdialog >= 0.8.0.")'</label></text>
        <text><label>""</label></text>
        
        <hbox homogeneous="true">
          <button ok></button>
        </hbox>
      </vbox>
    <action signal="delete-event">EXIT:abort</action>
    </window>'
    $GTKDIALOG -cp GUI_REQUIREMENTS
    exit 1
fi

func_vercmp_gt "0.8.3" "${GTKDLG_VER}" && GTKDLG_NEW=0 || GTKDLG_NEW=1	# 1 = gtkdialog >= 0.8.3

# -----------------------------------------------------------------------------

ARCHNAME="$(gettext 'NewArchive')"
OUTPUT_DIR="$HOME"

if (($#)); then 
  [ ! -e "$1" ] && { echo "File/dir doesn't exist!"; exit 1; }
  FILEPATH="$(dirname "$1")"
  [ "$FILEPATH" = "." ] && FILEPATH="$(pwd)"
  [ "$FILEPATH" = "" ] && FILEPATH="/"
  OUTPUT_DIR="$FILEPATH"
  [ "$2" = "" ] && ARCHNAME="$(basename "$1")"
fi

echo "$OUTPUT_DIR" > $TMP_OUTPUT_DIR
echo "$ARCHNAME" > $TMP_ARCHNAME

# -----------------------------------------------------------------------------

SEVENZ=7z
for i in 7z 7za 7zr; do
  [ "`which $i 2>/dev/null`" ] && { SEVENZ="$i"; break; }
done

LZ4=lz4
for i in lz4 lz4c; do
  [ "`which $i 2>/dev/null`" ] && { LZ4="$i"; break; }
done

MKSQUASHFS=mksquashfs
for i in mksquashfs mksquashfs4 mksquashfs3; do
  [ "`which $i 2>/dev/null`" ] && { MKSQUASHFS="$i";  break; }
done

export SEVENZ LZ4 MKSQUASHFS

# -----------------------------------------------------------------------------

PASS_1="tar cpio mkisofs mke2fs $MKSQUASHFS"
PASS_2="$SEVENZ bzip2 compress freeze gzip $LZ4 lzip lzma lzop rar xz zip"

# -----------------------------------------------------------------------------
# Check if mksquashfs supports some additional compression methods
# -----------------------------------------------------------------------------
if [ "`which $MKSQUASHFS 2>/dev/null`" ]; then
  MKSQ_LIST=
  for i in gzip lzma lzo lz4 xz; do
    [ "$($MKSQUASHFS 2>&1 | grep -w "$i")" ] && MKSQ_LIST="${MKSQ_LIST}\n$i"
  done
  echo -en "${MKSQ_LIST:2}" > $TMP_MKSQ_LIST
fi

# -----------------------------------------------------------------------------
# Test 7z(a/r) and rar's .sfx/.exe ability
# -----------------------------------------------------------------------------
IS_7Z_SFX=false; IS_7Z_EXE=false; IS_RAR_SFX=false; IS_RAR_EXE=false
SELFEXTTEST=$TMPDIR/selfexttest.sfx

if [ "`which $SEVENZ 2>/dev/null`" ]; then
  echo test | $SEVENZ a -si -sfx7zCon.sfx $SELFEXTTEST >/dev/null
  [ $? -eq 0 ] && IS_7Z_SFX=true
  rm -f $SELFEXTTEST

  echo test | $SEVENZ a -si -sfx7z.sfx $SELFEXTTEST >/dev/null
  [ $? -eq 0 ] && IS_7Z_EXE=true
  rm -f $SELFEXTTEST
fi

if [ "`which rar 2>/dev/null`" ]; then
  [ -e "${MYPATH}/resources/default.sfx" ] && { echo test | rar a -si -sfx${MYPATH}/resources/default.sfx $SELFEXTTEST >/dev/null; } || { echo test | rar a -si -sfxdefault.sfx $SELFEXTTEST >/dev/null 2>&1; }
  [ $? -eq 0 ] && IS_RAR_SFX=true
  rm -f $SELFEXTTEST
  
  [ -e "${MYPATH}/resources/Default.SFX" ] && { echo test | rar a -si -sfx${MYPATH}/resources/Default.SFX $SELFEXTTEST >/dev/null; } || { echo test | rar a -si -sfxDefault.SFX $SELFEXTTEST >/dev/null 2>&1; }
  [ $? -eq 0 ] && IS_RAR_EXE=true
  rm -f $SELFEXTTEST
fi

export IS_7Z_SFX IS_7Z_EXE IS_RAR_SFX IS_RAR_EXE

# -----------------------------------------------------------------------------
# Flags for PASS_2 tools: COMPRESSION_LEVEL | ENCRYPTION | ENCRYPT_FILENAMES | SOLID | MULTIPLE_FILES
# -----------------------------------------------------------------------------
F_7z=11111
F_7za=11111
F_7zr=11111
F_bzip2=10000
F_compress=00000
F_freeze=00000
F_gzip=10000
F_lz4=10000
F_lz4c=10000
F_lzip=10000
F_lzma=10000
F_lzop=10000
F_rar=11111
F_xz=10000
F_zip=11001

# =============================================================================

func_escape () {
  local TMP="${1}"
  TMP="${TMP//\\/\\\\}"			# escape backslashes
  TMP="${TMP//\"/\\\"}"			# escape "
  TMP="${TMP//\$/\\\$}"			# escape $
  TMP="${TMP//\`/\\\`}"			# escape `
  echo -n "$TMP"
}

# -----------------------------------------------------------------------------

func_set_extension () {
  [ $1 -eq 1 ] && echo -n "$2" > $TMP_PASS1 || echo -n "$2" > $TMP_PASS2

  TEMPEXT="$(<$TMP_PASS1)$(<$TMP_PASS2)"
  case "$TEMPEXT" in
    .tar)					TEMPEXT=".tar\n.cbt" ;;
    .cpio)					TEMPEXT=".cpio" ;;
    .mkisofs)				TEMPEXT=".iso" ;;
    .mke2fs)				TEMPEXT=".2fs\n.ext2\n.img" ;;
    .$MKSQUASHFS)			TEMPEXT=".sfs\n.sqfs\n.squashfs" ;;
  # -----------
    .$SEVENZ)				TEMPEXT=".7z\n.cb7"
							[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.sfx"
							[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.exe" ;;
    .bzip2)					TEMPEXT=".bz2" ;;
    .compress)				TEMPEXT=".Z" ;;
    .freeze) 				TEMPEXT=".F" ;;
    .gzip)					TEMPEXT=".gz" ;;
    .$LZ4)					TEMPEXT=".lz4" ;;
    .lzip)                  TEMPEXT=".lz" ;;
    .lzma)					TEMPEXT=".lzma" ;;
    .lzop)					TEMPEXT=".lzo" ;;
    .rar)					TEMPEXT=".rar\n.cbr"
							[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.sfx"
							[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.exe" ;;
    .xz)					TEMPEXT=".xz" ;;
    .zip)					TEMPEXT=".zip\n.cbz"
							[ "`which unzipsfx 2>/dev/null`" ] && TEMPEXT="${TEMPEXT}\n.sfx" ;;
  # -----------
    .tar.$SEVENZ)			TEMPEXT=".tar.7z"
							[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.tar.sfx"
							[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.tar.exe" ;;
    .tar.bzip2)				TEMPEXT=".tar.bz2\n.tb2\n.tbz\n.tbz2" ;;
    .tar.compress)			TEMPEXT=".tar.Z\n.taz\n.tz" ;;
    .tar.freeze)			TEMPEXT=".tar.F" ;;
    .tar.gzip) 				TEMPEXT=".tar.gz\n.tgz" ;;
    .tar.$LZ4)				TEMPEXT=".tar.lz4"	;;
    .tar.lzip)              TEMPEXT=".tar.lz\n.tlz" ;;
    .tar.lzma)				TEMPEXT=".tar.lzma" ;;
    .tar.lzop)				TEMPEXT=".tar.lzo\n.tzo" ;;
    .tar.rar)				TEMPEXT=".tar.rar"
							[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.tar.sfx"
							[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.tar.exe" ;;
    .tar.xz)				TEMPEXT=".tar.xz\n.txz" ;;
    .tar.zip)				TEMPEXT=".tar.zip"
							[ "`which unzipsfx 2>/dev/null`" ] && TEMPEXT="${TEMPEXT}\n.tar.sfx" ;;
  # -----------
    .cpio.$SEVENZ)			TEMPEXT=".cpio.7z"
							[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.cpio.sfx"
							[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.cpio.exe" ;;
    .cpio.bzip2)			TEMPEXT=".cpio.bz2" ;;
    .cpio.compress)			TEMPEXT=".cpio.Z" ;;
    .cpio.freeze)			TEMPEXT=".cpio.F" ;;
    .cpio.gzip)				TEMPEXT=".cpio.gz\n.cgz" ;;
    .cpio.$LZ4)				TEMPEXT=".cpio.lz4"	;;
    .cpio.lzip)             TEMPEXT=".cpio.lz" ;;
    .cpio.lzma)				TEMPEXT=".cpio.lzma" ;;
    .cpio.lzop)				TEMPEXT=".cpio.lzo" ;;
    .cpio.rar)				TEMPEXT=".cpio.rar"
							[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.cpio.sfx"
							[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.cpio.exe" ;;
    .cpio.xz)				TEMPEXT=".cpio.xz" ;;
    .cpio.zip)				TEMPEXT=".cpio.zip"
							[ "`which unzipsfx 2>/dev/null`" ] && TEMPEXT="${TEMPEXT}\n.cpio.sfx" ;;
  # -----------
    .mke2fs.$SEVENZ)		TEMPEXT=".2fs.7z\n.ext2.7z\n.img.7z"
							[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.2fs.sfx\n.ext2.sfx\n.img.sfx"
							[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.2fs.exe\n.ext2.exe\n.img.exe" ;;
    .mke2fs.bzip2)			TEMPEXT=".2fs.bz2\n.ext2.bz2\n.img.bz2" ;;
    .mke2fs.compress)		TEMPEXT=".2fs.Z\n.ext2.Z\n.img.Z" ;;
    .mke2fs.freeze)			TEMPEXT=".2fs.F\n.ext2.F\n.img.F" ;;
    .mke2fs.gzip)			TEMPEXT=".2fs.gz\n.ext2.gz\n.img.gz" ;;
    .mke2fs.$LZ4)			TEMPEXT=".2fs.lz4\next2.lz4\nimg.lz4" ;;
    .mke2fs.lzip)           TEMPEXT=".2fs.lz\next2.lz\nimg.lz" ;;
    .mke2fs.lzma)			TEMPEXT=".2fs.lzma\n.ext2.lzma\n.img.lzma" ;;
    .mke2fs.lzop)			TEMPEXT=".2fs.lzo\n.ext2.lzo\n.img.lzo" ;;
    .mke2fs.rar)			TEMPEXT=".2fs.rar\n.ext2.rar\n.img.rar"
							[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.2fs.sfx\n.ext2.sfx\n.img.sfx"
							[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.2fs.exe\n.ext2.exe\n.img.exe" ;;
    .mke2fs.xz)				TEMPEXT=".2fs.xz\n.ext2.xz\n.img.xz" ;;
    .mke2fs.zip)			TEMPEXT=".2fs.zip\n.ext2.zip\n.img.zip"
							[ "`which unzipsfx 2>/dev/null`" ] && TEMPEXT="${TEMPEXT}\n.2fs.sfx\n.ext2.sfx\n.img.sfx" ;;
  # -----------
    .mkisofs.$SEVENZ)		TEMPEXT=".iso.7z"
							[ "$IS_7Z_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.iso.sfx"
							[ "$IS_7Z_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.iso.exe" ;;
    .mkisofs.bzip2)			TEMPEXT=".iso.bz2" ;;
    .mkisofs.compress)		TEMPEXT=".iso.Z" ;;
    .mkisofs.freeze)		TEMPEXT=".iso.F" ;;
    .mkisofs.gzip)			TEMPEXT=".iso.gz" ;;
    .mkisofs.$LZ4)			TEMPEXT=".iso.lz4" ;;
    .mkisofs.lzip)          TEMPEXT=".iso.lz" ;;
    .mkisofs.lzma)			TEMPEXT=".iso.lzma" ;;
    .mkisofs.lzop)			TEMPEXT=".iso.lzo" ;;
    .mkisofs.rar)			TEMPEXT=".iso.rar"
							[ "$IS_RAR_SFX" = "true" ] && TEMPEXT="${TEMPEXT}\n.iso.sfx"
							[ "$IS_RAR_EXE" = "true" ] && TEMPEXT="${TEMPEXT}\n.iso.exe" ;;
    .mkisofs.xz)			TEMPEXT=".iso.xz" ;;
    .mkisofs.zip)			TEMPEXT=".iso.zip"
							[ "`which unzipsfx 2>/dev/null`" ] && TEMPEXT="${TEMPEXT}\n.iso.sfx" ;;
  # -----------
    .$MKSQUASHFS.*)			TEMPEXT=".sfs\n.sqfs\n.squashfs" ;;
    *)						TEMPEXT="" ;;
  esac
  
  echo -en $TEMPEXT > $TMP_EXT
}
export -f func_set_extension

# -----------------------------------------------------------------------------

func_show_warning () {
  export GUI_WARNING='
    <window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
      <vbox>
        <pixmap><input file stock="gtk-dialog-warning"></input></pixmap>
        <text><label>""</label></text>
        <text><label>'${1}'</label></text>
        <text><label>""</label></text>
        <hseparator></hseparator>
        <hbox homogeneous="true">
          <button space-fill="true" space-expand="true">
            <input file stock="gtk-refresh"></input>
            <label>'$(gettext "Restart")'</label>
            <action>EXIT:OK</action>
          </button>
          <button space-fill="true" space-expand="true">
            <input file stock="gtk-quit"></input>
            <label>'$(gettext "Exit")'</label>
            <action>EXIT:abort</action>
          </button>
        </hbox>
      </vbox>
    <action signal="delete-event">EXIT:abort</action>
    </window>'
    
  eval $($GTKDIALOG -cp GUI_WARNING)
  [ "$EXIT" = "OK" ] || exit 1
}
export func_show_warning

# -----------------------------------------------------------------------------

func_show_success () {
  export GUI_SUCCESS='
    <window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
      <vbox>
        <pixmap>
        '$( if [ -f /usr/local/lib/X11/pixmaps/ok.xpm ]; then 
              echo '<input file>/usr/local/lib/X11/pixmaps/ok.xpm</input>'
            else
              echo '<input file stock="gtk-apply"></input>'
            fi )'
        </pixmap>
        <text><label>""</label></text>
        <text><label>'$(gettext "The archive")'</label></text>
        <text use-markup="true"><input file>'${TMPDIR}/msg'</input></text>
        <text><label>'$(gettext "has been successfully created!")'</label></text>
        <text><label>""</label></text>
        <hseparator></hseparator>
        <hbox homogeneous="true"><button ok></button></hbox>
      </vbox>
    <action signal="delete-event">EXIT:abort</action>
    </window>'
  
  eval $($GTKDIALOG -cp GUI_SUCCESS)
}
export -f func_show_success

# -----------------------------------------------------------------------------

func_show_fail () { 
  export GUI_FAIL='
    <window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
      <vbox>
        <pixmap>
        '$( if [ -f /usr/local/lib/X11/pixmaps/error.xpm ]; then 
              echo '<input file>/usr/local/lib/X11/pixmaps/error.xpm</input>'
            else
              echo '<input file stock="gtk-dialog-error"></input>'
            fi )'
        </pixmap>
        
        <text><label>""</label></text>
        <text><label>'$(gettext "The archive")'</label></text>
        <text use-markup="true"><input file>'${TMPDIR}/msg'</input></text>
        <text><label>'$(gettext "has not been successfully created!")'</label></text>
        <text><label>""</label></text>
        
        <hseparator></hseparator>
        
        <hbox homogeneous="true">
          <button space-fill="true" space-expand="true">
            <input file stock="gtk-file"></input>
            <label>'$(gettext "View log")'</label>
            <action>EXIT:log</action>
          </button>
          <button space-fill="true" space-expand="true">
            <input file stock="gtk-refresh"></input>
            <label>'$(gettext "Restart")'</label>
            <action>EXIT:restart</action>
          </button>
          <button space-fill="true" space-expand="true">
            <input file stock="gtk-quit"></input>
            <label>'$(gettext "Exit")'</label>
            <action>EXIT:exit</action>
          </button>
        </hbox>
      </vbox>
    <action signal="delete-event">EXIT:abort</action>
    </window>'
  
  eval $($GTKDIALOG -cp GUI_FAIL)
  
  case "$EXIT" in
    log)		return 2 ;;
    restart)	return 1 ;;
    *)			return 0 ;;
  esac
}
export -f func_show_success

# -----------------------------------------------------------------------------

func_show_log () {
  export GUI_LOG='
  <window title="'${APPNAME}' - '$(gettext "Log")'" width-request="600" height-request="400" image-name="'${APPICON}'">
    <vbox>
      <edit editable="false">
        <input file>'${TMPDIR}/packit.log'</input>
      </edit>
      <hbox homogeneous="true">
        <button ok></button>
      </hbox>
    </vbox>
  <action signal="delete-event">EXIT:abort</action>
  </window>'
  
  $GTKDIALOG -cp GUI_LOG
}
export -f func_show_log

# -----------------------------------------------------------------------------

RANGE=7

export GUI_WAIT='
<window title="'${APPNAME}'" resizable="false" image-name="'${APPICON}'">
  <vbox>
    
    <pixmap>
      <input file stock="gtk-dialog-info"></input>
    </pixmap>
    
    <text><label>""</label></text>
    <text><label>'$(gettext "The archive")'</label></text>
    <text use-markup="true"><input file>'${TMPDIR}/msg'</input></text>
    <text><label>'$(gettext "is being created, please wait...")'</label></text>

    <text>
      <variable>varOUTPUT_SIZE</variable>
      <input>echo -n "["; [ -f "$DESTARCH" ] && du -bh "$DESTARCH" 2>/dev/null | cut -f1 | tr -d "\n" || echo -n "?"; echo -n "]"</input>
    </text>

    <notebook show-border="false" show-tabs="false" tab-base-index="0">
      
      '$(for i in $(seq 1 ${RANGE}); do
      echo '
        <hscale sensitive="false" draw-value="false" range-min="1" range-max="'${RANGE}'" range-step="1" range-value="'${i}'">
        </hscale>'
      done)'
      
      '$(for i in $(seq $((${RANGE}-1)) -1 1); do
      echo '
        <hscale sensitive="false" draw-value="false" range-min="1" range-max="'${RANGE}'" range-step="1" range-value="'${i}'">
        </hscale>'
      done)'
      
      <variable>varINDEX</variable>
      <input>echo $(( ($varINDEX+1) % (('${RANGE}'-1) * 2) ))</input>
    </notebook>

    <timer visible="false" milliseconds="true" interval="200">
       <action>refresh:varINDEX</action>
    </timer>
    <timer visible="false" milliseconds="false" interval="1">
       <action>refresh:varOUTPUT_SIZE</action>
    </timer>

    <hbox homogeneous="true">
      <button>
        <input file stock="gtk-cancel"></input>
        <label>Abort</label>
        <action>PID=`cat '${TMPDIR}/PID'`; while true; do TMP=`pgrep -P $PID`; [ "$TMP" ] && PID="$TMP" || break; done; kill $PID</action>
        <action>#pkill -TERM -P `cat '${TMPDIR}/PID'`</action>
        <action>EXIT:exit</action>
      </button>
    </hbox>
  </vbox>

<action signal="delete-event">PID=`cat '${TMPDIR}/PID'`; while true; do TMP=`pgrep -P $PID`; [ "$TMP" ] && PID="$TMP" || break; done; kill $PID</action>
<action signal="delete-event">EXIT:abort</action>
</window>'

# =============================================================================

export GUI_CHOOSER='
<window title="'${APPNAME}'" modal="true" resizable="false" image-name="'${APPICON}'">
  <vbox>
  
	<chooser>
	  <variable>INPUT</variable>
	  <default>'${HOME}'</default>
	  <width>600</width>
	  <height>400</height>
    </chooser>
    
    <hbox>
	  <button>
	    <label>'$(gettext 'OK')'</label>
	    <input file stock="gtk-ok"></input>
	    <variable>CLOSE_CHOOSER</variable>
	    <action>echo "$INPUT" > '${TMP_INPUT}'</action>
        <action>refresh:varINPUT</action>
	    <action>closewindow:CLOSE_CHOOSER</action>
	  </button>
	  <button>
	    <label>'$(gettext 'Cancel')'</label>
	    <input file stock="gtk-cancel"></input>
	    <action>closewindow:CLOSE_CHOOSER</action>
	  </button>
	</hbox>
	
  </vbox>
<variable>GUI_CHOOSER</variable>

</window>'

# -----------------------------------------------------------------------------

export GUI_MAIN='
<window title="'${APPNAME}' '${VERSION}'" resizable="false" image-name="'${APPICON}'">
  <vbox>
  
    '$(if ! (($#)); then
    echo '
    <frame '$(gettext 'Select input folder or file:')'>
      <hbox>
        <entry editable="true" activates_default="true">
          <variable>varINPUT</variable>
          <input file>'$TMP_INPUT'</input>
          <action>echo "$varINPUT" > '$TMP_INPUT'</action>
        </entry>
  	    <button>
          <input file stock="gtk-file"></input>
	      <action>launch:GUI_CHOOSER</action>
	    </button>
	  </hbox>
	</frame>'
    fi)'
    
    <hbox>
      <frame '$(gettext 'Pass_1:')'>
        <vbox>
          <radiobutton>
            <variable>varPASS1</variable>
            <label>'$(gettext '(none)')'</label>
            <action>if true func_set_extension 1 ''</action>
            <action>if true enable:varPASS2_STATE</action>
            '$( [ $GTKDLG_NEW -eq 1 ] && echo '<action condition="active_is_true(varPASS2)">disable:varPACKIT</action>')'
            <action>refresh:varEXTENSION</action>
            '$([ "$MKSQ_LIST" != "" ] && echo '<action>disable:varMKSQ_LIST</action>')'
          </radiobutton>

          '$(for i in $PASS_1; do
               [ "`which $i 2>/dev/null`" ] &&
               [ "$i" = "$MKSQUASHFS" ] && echo '<hseparator></hseparator>'
               echo '<radiobutton>
					 <label>'$i'</label>
					 <action>if true func_set_extension 1 '.$i'</action>
					 <action>refresh:varEXTENSION</action>
					 <action>enable:varPACKIT</action>'
			   [ "$i" = "$MKSQUASHFS" ] && echo '<action>if true activate:varPASS2</action><action>disable:varPASS2_STATE</action>'
			   [ "$i" != "$MKSQUASHFS" ] && echo '<action>if true enable:varPASS2_STATE</action>'
			   [ "$i" = "$MKSQUASHFS" ] && [ "$MKSQ_LIST" != "" ] && echo '<action>if true enable:varMKSQ_LIST</action>' 
			   [ "$i" != "$MKSQUASHFS" ] && [ "$MKSQ_LIST" != "" ] && echo '<action>disable:varMKSQ_LIST</action>'
			   echo '</radiobutton>'
			   [ "$i" = "$MKSQUASHFS" ] && [ "$MKSQ_LIST" != "" ] && echo '<hbox>
																	      <comboboxtext>
																             <variable>varMKSQ_LIST</variable>
																               <sensitive>false</sensitive>
																               <input file>'$TMP_MKSQ_LIST'</input>
																             </comboboxtext>
																           </hbox>'
             done)'
             
         </vbox>
      </frame>
      
      <frame '$(gettext 'Pass_2:')'>
        <vbox>
          <radiobutton>
            <variable>varPASS2</variable>
            <label>'$(gettext '(none)')'</label>
            <action>if true func_set_extension 2 ''</action>
            '$( [ $GTKDLG_NEW -eq 1 ] && echo '<action condition="active_is_true(varPASS1)">disable:varPACKIT</action>')'
            <action>refresh:varEXTENSION</action>
            <action>disable:varLEVEL</action>
            <action>disable:varLEVEL_INFO</action>
            <action>disable:varSOLID</action>
            <action>disable:varPASSWORD</action>
            <action>disable:varPASSWORD_INFO</action>
            <action>disable:varENCHEAD</action>
          </radiobutton>
          
          '$(for i in $PASS_2; do
               if [ "`which $i 2>/dev/null`" ]; then
                 FLAGS=F_$i
                 echo '<radiobutton>
				       <label>'$i'</label>
                       <action>if true func_set_extension 2 '.$i'</action>
                       <action>refresh:varEXTENSION</action>
                       <action>enable:varLEVEL</action>
                       <action>enable:varLEVEL_INFO</action>
                       <action>enable:varPACKIT</action>'
			     [ ${!FLAGS:0:1} -eq 0 ] && echo '<action>disable:varLEVEL</action><action>disable:varLEVEL_INFO</action>'
                 [ ${!FLAGS:1:1} -eq 0 ] && echo '<action>disable:varPASSWORD</action><action>disable:varPASSWORD_INFO</action>' || echo '<action>enable:varPASSWORD</action><action>enable:varPASSWORD_INFO</action>'
                 [ ${!FLAGS:2:1} -eq 0 ] && echo '<action>disable:varENCHEAD</action>' || echo '<action>enable:varENCHEAD</action>'
                 [ ${!FLAGS:3:1} -eq 0 ] && echo '<action>disable:varSOLID</action>' || echo '<action>enable:varSOLID</action>'
                 echo '</radiobutton>'
               fi
             done)'
          
          <variable>varPASS2_STATE</variable>
        </vbox>
      </frame>
      
      <frame '$(gettext 'Pass_2 extra options:')'>
        <vbox>
        
          <text>
            <variable>varLEVEL_INFO</variable>
            <sensitive>false</sensitive>
            <label>'$(gettext 'Compression preset:')' </label>
          </text>
          <hscale range-min="1" range-max="5" range-step="1" range-value="3" value-pos="2">
            <variable>varLEVEL</variable>
            <sensitive>false</sensitive>
            <item>1|0|'$(gettext 'Fast')'</item>
            <item>3|0|'$(gettext 'Average')'</item>
            <item>5|0|'$(gettext 'Best')'</item>
          </hscale>
          
          <hseparator></hseparator>
          
          <hbox homogeneous="true">
            <checkbox>
              <variable>varSOLID</variable>
              <label>'$(gettext 'Solid archive')'</label>
              <default>false</default>
              <sensitive>false</sensitive>
            </checkbox>
          </hbox>
          
          <hseparator></hseparator>
          
          <text>
            <variable>varPASSWORD_INFO</variable>
            <sensitive>false</sensitive>
            <label>'$(gettext 'Password:')' </label>
          </text>
          <entry max-length="256" caps-lock-warning="true" visibility="false">
            <variable>varPASSWORD</variable>
            <sensitive>false</sensitive>
            '$( [ $GTKDLG_NEW -eq 1 ] && echo '<action condition="command_is_true( [ \"$varPASSWORD\" ] && echo true )">enable:varENCHEAD_PASS</action>')'
            '$( [ $GTKDLG_NEW -eq 1 ] && echo '<action condition="command_is_true( [ \"$varPASSWORD\" ] || echo true )">disable:varENCHEAD_PASS</action>')'
          </entry>

          <hbox homogeneous="true">
            <checkbox>
              <variable>varENCHEAD</variable>
              <default>false</default>
              <sensitive>false</sensitive>
              <label>'$(gettext 'Encrypt filenames')'</label>
            </checkbox>
            '$( [ $GTKDLG_NEW -eq 1 ] && echo '<sensitive>false</sensitive>')'
            '$( [ $GTKDLG_NEW -eq 1 ] && echo '<variable>varENCHEAD_PASS</variable>')'
          </hbox>
        </vbox>
      </frame>
    </hbox>
    
    <hbox>
      <text xalign="0"><label>'$(gettext 'Output folder:')' </label></text>
	  <entry activates_default="true" fs-title="'$(gettext 'Select an output folder')'" fs-folder="'${HOME}'" fs-action="folder">
	    <variable>varOUTPUT_DIR</variable>
	    <input file>'${TMP_OUTPUT_DIR}'</input>
	  </entry>
	  <button>
	    <input file stock="gtk-directory"></input>
	    <action>fileselect:varOUTPUT_DIR</action>
	  </button>
	</hbox>
	
	<hbox>
	  <text xalign="0"><label>'$(gettext 'Archive name:')' </label></text>
	  <entry activates_default="true">
	    <variable>varARCHNAME</variable>
	    <input file>'${TMP_ARCHNAME}'</input>
	  </entry>
	  
	  <comboboxtext width-request="96">
	    <variable>varEXTENSION</variable>
	    <input file>'${TMP_EXT}'</input>
	  </comboboxtext>
	  
	</hbox>

    <hseparator></hseparator>
    
    <hbox>
      <checkbox>
        <variable>varVERBOSE</variable>
        <default>false</default>
        <label>'$(gettext 'Verbose mode')'</label>
      </checkbox>
      <checkbox>
        <variable>varCHKSUM</variable>
        <default>false</default>
        <label>MD5/SHA1</label>
      </checkbox>
      
      <vseparator></vseparator>
      
      <text space-fill="true" space-expand="true"><label>" "</label></text>
      <button can-default="true" has-default="true">
        <variable>varPACKIT</variable>
        <sensitive>false</sensitive>
        <label>'$(gettext 'Pack it!')'</label>
        <input file stock="gtk-ok"></input>
        <action>EXIT:packit</action>
      </button>
      <button>
        <label>'$(gettext 'Cancel')'</label>
        <input file stock="gtk-cancel"></input>
        <action>EXIT:cancel</action>
      </button>
    </hbox>
    
  </vbox>
  
<action signal="delete-event">EXIT:abort</action>
</window>'

# =============================================================================

I=$IFS; IFS='
'
for STATEMENTS in $($GTKDIALOG -cp GUI_MAIN); do
  if [[ "$STATEMENTS" == "varARCHNAME="* ]]; then
    varARCHNAME="`echo $STATEMENTS | cut -f2- -d '"' | rev | cut -f2- -d '"' | rev`"
  elif [[ "$STATEMENTS" == "varOUTPUT_DIR="* ]]; then
    varOUTPUT_DIR="`echo $STATEMENTS | cut -f2- -d '"' | rev | cut -f2- -d '"' | rev`"
  elif [[ "$STATEMENTS" == "varPASSWORD="* ]]; then
    varPASSWORD="`echo $STATEMENTS | cut -f2- -d '"' | rev | cut -f2- -d '"' | rev`"
    varPASSWORD="$(func_escape "$varPASSWORD")"
  else
    eval $STATEMENTS
  fi
done
IFS=$I

[ "$EXIT" != "packit" ] && exit 0

[ "$(<$TMP_INPUT)" = "" ] && IFILES=( "$@" ) || IFILES=( "$(<$TMP_INPUT)" )

# -----------------------------------------------------------------------------
# Precautions and stuff
# -----------------------------------------------------------------------------
if [ ${#IFILES[@]} -eq 0 ]; then
  func_show_warning "$(gettext 'You must specify an existing input file/folder!')"
  exec "$MYNAME" "$@"
fi

if [ "$varOUTPUT_DIR" = "" ] || [ "$(realpath "$varOUTPUT_DIR")" = "" ]; then
  func_show_warning "$(gettext 'You must specify an existing output folder!')"
  exec "$MYNAME" "$@"
fi

if [ "$(<$TMP_PASS1)$(<$TMP_PASS2)" = "" ]; then
  func_show_warning "$(gettext 'You must select a tool in "Pass_1" and/or "Pass_2"!')"
  exec "$MYNAME" "$@"
fi

if [ "$(<$TMP_PASS1)" = "" ] && ([ ${#IFILES[@]} -gt 1 ] || [ -d "$(realpath "${IFILES[0]}" 2>/dev/null)" ]); then
  TEMPEXT=$(<$TMP_PASS2)
  FLAGS=F_${TEMPEXT:1}
  if [ ${!FLAGS:4:1} -eq 0 ]; then
    func_show_warning "$(gettext 'The chosen tool can process only single files.')"
    exec "$MYNAME" "$@"
  fi
fi

if [ "$(<$TMP_PASS2)" = ".zip" ] && [[ "$varEXTENSION" == *".sfx" ]] && [ "$varPASSWORD" != "" ]; then
  func_show_warning "$(gettext 'Encrypted, self-extracting ZIP archives are not supported.')"
  exec "$MYNAME" "$@"
fi

# -----------------------------------------------------------------------------
# Separate dirname & basename(s)
# -----------------------------------------------------------------------------
INDIR="$(dirname "${IFILES[0]}")"
for i in `seq 0 $((${#IFILES[@]}-1))`; do
  IFILES[$i]="$(basename "${IFILES[$i]}")"
done

# Don't overwrite existing dir/file
varARCHNAME="${varARCHNAME//\//_}"		# precaution: replace / with _
CNT=1
DESTARCH="${varOUTPUT_DIR}/${varARCHNAME}"
TEMP="$DESTARCH"

while [ -e "${TEMP}${varEXTENSION}" ]; do
  TEMP="$DESTARCH($CNT)"
  ((CNT++))
done

echo -n "<b>$(basename "${TEMP}${varEXTENSION}" | sed -e 's~&~\&amp;~g' -e 's~<~\&lt;~g' -e 's~>~\&gt;~g')</b>" > $TMPDIR/msg

TEMP="$(func_escape "$TEMP")"
DESTARCH="${TEMP}${varEXTENSION}"

#DESTARCH="${varOUTPUT_DIR}/${varARCHNAME}${varEXTENSION}"
#if [ -f "$DESTARCH" ]; then
#  $XMESSAGE -buttons "$(gettext 'Overwrite'):100,$(gettext 'Restart'):101,$(gettext 'Exit'):102" -fg red -bg white -fn bold -center -title "$APPNAME - $(gettext 'Warning')" "$(gettext 'Destination file exists! Overwrite?')"
#  RET=$?
#  [ $RET -eq 102 ] && exit
#  [ $RET -eq 101 ] && exec "$MYNAME" "$@"
#fi

# -----------------------------------------------------------------------------

cd "$INDIR"		# important - must be here, before options!!!

# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Prepare options for tools in PASS2
# -----------------------------------------------------------------------------
case "$(<$TMP_PASS2)" in
  .$SEVENZ)
    OPTS="-mx=$(( $varLEVEL + ($varLEVEL-1) ))"
    [ "$($SEVENZ | grep -Eio 'p7zip.*Version.*[0-9]+\.' | cut -f2- -d ' ' | grep -Eo '[0-9]+')" -ge 15 ] && OPTS="${OPTS} -mqs=on"	# old sorting
	[ "$varENCHEAD" = "true" ]			&& OPTS="${OPTS} -mhe=on"		|| OPTS="${OPTS} -mhe=off"
	[ "$varSOLID" = "true" ]			&& OPTS="${OPTS} -ms=on"		|| OPTS="${OPTS} -ms=off"
	[ "$varPASSWORD" != "" ] 			&& PASSWORD="-p${varPASSWORD}"	|| PASSWORD=
	[[ "$varEXTENSION" == *".sfx" ]] 	&& OPTS="${OPTS} -sfx7zCon.sfx"
	[[ "$varEXTENSION" == *".exe" ]] 	&& OPTS="${OPTS} -sfx7z.sfx"
  ;;
  # -----------
  .bzip2|.gzip|.$LZ4|.lzip|.lzma|.xz)
    OPTS="-$(( $varLEVEL + ($varLEVEL-1) ))"
  ;;
  # -----------
  .lzop)
    OPTS="-${varLEVEL}"
  ;;
  # -----------
  .rar)
    OPTS="-m${varLEVEL}"
	[ "$varSOLID" = "true" ]								&& OPTS="${OPTS} -se" || OPTS="${OPTS} -s-"
	[ "$varPASSWORD" != "" ] && [ "$varENCHEAD" = "false" ]	&& PASSWORD="-p${varPASSWORD}"
	[ "$varPASSWORD" != "" ] && [ "$varENCHEAD" = "true" ]	&& PASSWORD="-hp${varPASSWORD}"
	[[ "$varEXTENSION" == *".sfx" ]] 						&& { [ -e "${MYPATH}/default.sfx" ] && OPTS="${OPTS} -sfx${MYPATH}/default.sfx" || OPTS="${OPTS} -sfxdefault.sfx"; }
	[[ "$varEXTENSION" == *".exe" ]] 						&& { [ -e "${MYPATH}/Default.SFX" ] && OPTS="${OPTS} -sfx${MYPATH}/Default.SFX" || OPTS="${OPTS} -sfxDefault.SFX"; }
  ;;
  # -----------
  .zip)
    OPTS="-$(( $varLEVEL + ($varLEVEL-1) ))"
    PASSWORD="$varPASSWORD"
    [[ "$varEXTENSION" == *".sfx" ]] 	&& ZIPSFX=true || ZIPSFX=false
  ;;
esac

[ "$varMKSQ_LIST" != "" ] && MKOPTS=" -comp $varMKSQ_LIST" || MKOPTS=
[ "$varMKSQ_LIST" = "xz" ] && MKOPTS="${MKOPTS} -b 512K"

# -----------------------------------------------------------------------------
# Prepare PASS1
# -----------------------------------------------------------------------------
case "$(<$TMP_PASS1)" in
  .tar)
    [ "$(realpath "`which tar 2>/dev/null`" | grep "busybox")" ] && TAR_OPT='' || TAR_OPT='--no-unquote'
	[ ! "$(<$TMP_PASS2)" ] &&
	PASS1='tar '${TAR_OPT}' -cvf "$DESTARCH" -- "${IFILES[@]}"' ||
	PASS1='tar '${TAR_OPT}' -cvf - -- "${IFILES[@]}" | '
  ;;
  # -----------
  .cpio)
    [ ! "$(<$TMP_PASS2)" ] &&
	PASS1='find "./${IFILES[@]}" | cpio -ov -H newc > "$DESTARCH"' ||
	PASS1='find "./${IFILES[@]}" | cpio -ov -H newc | '
  ;;
  # -----------
  .mkisofs)
    VOLID="$(func_escape "${ARCHNAME:0:31}")"
	# If only one dir selected, search for bootloader in there
	if [ ${#IFILES[@]} -eq 1 ] && [ -d "${IFILES[0]}" ]; then
	  BOOTLOADER=''
	  BOOTPARM=''
	  JOLIET_OPT='-J'

	  # Bootloader search "borrowed" from shinobar's "dir2iso"
	  for B in grldr isolinux.bin; do
	    [ -s "${IFILES[0]}/${B}" ] && BOOTLOADER="${B}" && break
	  done

	  # EFI (Fatdog64)
	  EFI="$(find "${IFILES[0]}" -type f -name "efiboot.img" -printf '%P\n' 2>/dev/null)"

	  [ "$BOOTLOADER" ] && BOOTPARM="-b "${BOOTLOADER}" -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table"
	  [ "$EFI" ] && BOOTPARM="${BOOTPARM} -eltorito-alt-boot -eltorito-platform efi -b "${EFI}" -no-emul-boot"

	  # Disable Joliet when creating Puppy ISO
	  [ "$BOOTLOADER" ] && [ -e "${IFILES[0]}/vmlinuz" -a -e "${IFILES[0]}/initrd"* ] && JOLIET_OPT=''

	  # TO_DO: isohybrid!!!

	  [ ! "$(<$TMP_PASS2)" ] && 
	    PASS1='mkisofs -iso-level 4 $JOLIET_OPT -D -R -V "$VOLID" -o "$DESTARCH" $BOOTPARM -- "${IFILES[@]}"' ||
	    PASS1='mkisofs -iso-level 4 $JOLIET_OPT -D -R -V "$VOLID" $BOOTPARM -- "${IFILES[@]}" | '
	else
	  # Create graft-points, in order to have all dirs separately
	  # (bug? filename can't end with '\' backslash)
	  for i in $(seq 0 $((${#IFILES[@]}-1)) ); do
	    #IFILES[$i]="$(basename "${IFILES[$i]}")=${IFILES[$i]}"
	    IFILES[$i]="${IFILES[$i]//=/\\=}=${IFILES[$i]//=/\\=}"	# also, escape =
	  done
	  [ ! "$(<$TMP_PASS2)" ] && 
	    PASS1='mkisofs -graft-points -J -D -R -V "$VOLID" -o "$DESTARCH" -- "${IFILES[@]}"' ||
	    PASS1='mkisofs -graft-points -J -D -R -V "$VOLID" -- "${IFILES[@]}" | '
	fi
  ;;
  # -----------
  .mke2fs)
    PASS1='DEST_TMP="${DESTARCH}_${$}.tmp"
	   DATASIZE=$( du -c -s -B 1 -- "${IFILES[@]}" | tail -n 1 | cut -f1); RET=$?;
	   [ $RET -eq 0 ] && [ $DATASIZE -lt $((256*1024)) ] && DATASIZE=$((256*1024))
	   [ $RET -eq 0 ] && dd if=/dev/zero of="${DEST_TMP}" bs=$(( ($DATASIZE+($DATASIZE/10)+(10*1024*1024))/10 )) count=10; RET=$?;
	   [ $RET -eq 0 ] && mke2fs -F -m 0 -- "${DEST_TMP}"; RET=$?;
	   [ $RET -eq 0 ] && mount -t ext2 -o rw,sync,loop -- "${DEST_TMP}" $TMPMNT; RET=$?;
	   [ $RET -eq 0 ] && cp -ravi -t $TMPMNT -- "${IFILES[@]}"; RET=$?;
	   umount $TMPMNT 2>/dev/null
	   # bug (?) in resize2fs - if filename contains ? it will be truncated
	   [ $RET -eq 0 ] && resize2fs -M -- "${DEST_TMP}"; RET=$?
	   [ $RET -eq 0 ] || { rm -f -- "${DEST_TMP}"; NoNeXiStAnTcOmMaNd 2>/dev/null; }' # make error
       [ "$(<$TMP_PASS2)" ] && PASS1=''${PASS1}' && cat "${DEST_TMP}" | '
  ;;
  # -----------
  .$MKSQUASHFS)
    PASS1='$MKSQUASHFS "${IFILES[@]}" "$DESTARCH" -info $MKOPTS'
	: > $TMP_PASS2	# disable Pass 2
  ;;
  # -----------
  *) PASS1= ;;
esac

# -----------------------------------------------------------------------------
# Prepare PASS2
# -----------------------------------------------------------------------------
case "$(<$TMP_PASS2)" in
  .$SEVENZ)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='$SEVENZ a $OPTS "$PASSWORD" -- "$DESTARCH" "${IFILES[@]}"' ||
	PASS2='$SEVENZ a -si $OPTS "$PASSWORD" -- "$DESTARCH"'
  ;;
  # -----------
  .bzip2)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='bzip2 -vv -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='bzip2 -vv -c $OPTS > "$DESTARCH"'
  ;;
  # -----------
  .compress)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='compress -v -c -f "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='compress -v -c -f > "$DESTARCH"'
  ;;
  # -----------
  .freeze)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='freeze -vv -c -f "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='freeze -vv -c -f > "$DESTARCH"'
  ;;
  # -----------
  .gzip)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='gzip -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='gzip -v -c $OPTS > "$DESTARCH"'
  ;;
  # -----------
  .$LZ4)	# can't use -- yet, as for build 131
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='$LZ4 -v $OPTS "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='$LZ4 -v $OPTS > "$DESTARCH"'
  ;;
  # -----------
  .lzip)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='lzip -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='lzip -v -c $OPTS > "$DESTARCH"'
  ;;
  # -----------
  .lzma)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='lzma -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='lzma -v -c $OPTS > "$DESTARCH"'
  ;;
  # -----------
  .lzop)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='lzop -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='lzop -v -c $OPTS > "$DESTARCH"'
  ;;
  # -----------
  .rar)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='rar a -ol $OPTS "$PASSWORD" -- "$DESTARCH" "${IFILES[@]}"' ||
	PASS2='rar a -si"$(basename "${DESTARCH%.*}")" -ol $OPTS "$PASSWORD" -- "$DESTARCH" "${IFILES[@]}"'
  ;;
  # -----------
  .xz)
    [ ! "$(<$TMP_PASS1)" ] &&
	PASS2='xz -v -c $OPTS -- "${IFILES[@]}" > "$DESTARCH"' ||
	PASS2='xz -v -c $OPTS > "$DESTARCH"'
  ;;
  # -----------
  .zip)
    [ ! "$(<$TMP_PASS1)" ] &&
	{ [ "$PASSWORD" != "" ] && PASS2='zip -v -r -y $OPTS -P"${PASSWORD}" - "${IFILES[@]}" > "$DESTARCH"' || PASS2='zip -v -r -y $OPTS - "${IFILES[@]}" > "$DESTARCH"'; } ||
    { mkdir -p ${TMPDIR}/FIFO_tmp
	FIFO="${TMPDIR}/FIFO_tmp/$(basename "${DESTARCH%.*}")"
	PASS1='mkfifo "$FIFO"; '${PASS1}' cat - > "$FIFO" | ' 
	[ "$PASSWORD" != "" ] && PASS2='zip -j -v -y $OPTS -P"${PASSWORD}" - -FI "$FIFO" > "$DESTARCH"' || PASS2='zip -j -v -y $OPTS - -FI "$FIFO" > "$DESTARCH"'; }
    
    # Some gymnastics needed for .sfx
    PASS2=''${PASS2}'; RET=$?
    if [ $RET -eq 0 ] && [ "$ZIPSFX" = "true" ]; then
      cat "$(which unzipsfx)" "${DESTARCH}" > "${DESTARCH}_${$}.tmp"
      mv -f -- "${DESTARCH}_${$}.tmp" "${DESTARCH}"
      chmod +x "${DESTARCH}"
      zip -A "${DESTARCH}"
    elif [ $RET -ne 0 ]; then
      NoNeXiStAnTcOmMaNd 2>/dev/null	# make error
    fi'
  ;;
  # -----------
  *) PASS2= ;;
esac

if [ "$(<$TMP_PASS1)" = ".mke2fs" ]; then
  if [ ! "$PASS2" ]; then
    PASS1=''${PASS1}' && mv -n -- "${DEST_TMP}" "${DESTARCH}"'
  else
    PASS2=''${PASS2}' && rm -f -- "${DEST_TMP}"'
  fi
fi

# -----------------------------------------------------------------------------
# Escape \ " and ` also in input filenames
# -----------------------------------------------------------------------------

for i in `seq 0 $((${#IFILES[@]}-1))`; do
  IFILES[$i]="$(func_escape "${IFILES[$i]}")"
done

# -----------------------------------------------------------------------------
# Prepare exec script
# -----------------------------------------------------------------------------

REDCOL="\e[31;107m"
BLUECOL="\e[34;107m"
GREENCOL="\e[32;107m"
OFFCOL="\e[30;107m"

echo '#! /bin/bash
set -o pipefail' > $TMP_EXEC

for i in $(seq 0 $((${#IFILES[@]}-1))); do
  echo "IFILES[$i]=\"${IFILES[$i]}\"" >> $TMP_EXEC					
done

cat << EOF >> $TMP_EXEC

trap '[ -f $TMPDIR/retval ] || rm -f "\$DESTARCH"' EXIT
trap '[ -f "\$DEST_TMP" ] && rm -f -- "\$DEST_TMP"' EXIT

echo \${$} > '${TMPDIR}/PID'

TMPMNT="$TMPMNT"	
DESTARCH="$DESTARCH"
MKSQUASHFS="$MKSQUASHFS"
SEVENZ="$SEVENZ"
LZ4="$LZ4"
OPTS="$OPTS"	
MKOPTS="$MKOPTS"	
VOLID="$VOLID"
BOOTPARM="$BOOTPARM"
JOLIET_OPT="$JOLIET_OPT"
PASSWORD="$PASSWORD"
ZIPSFX="$ZIPSFX"
FIFO="$FIFO"
varCHKSUM="$varCHKSUM"
PASS1='${PASS1}'
PASS2='${PASS2}'

echo -e "${OFFCOL}"
clear
printf -- "${BLUECOL}=%.0s${OFFCOL}" {0..77}; echo
echo -ne "${BLUECOL}$(gettext "Creating:")${OFFCOL} "; echo "\${DESTARCH}"
printf -- "${BLUECOL}=%.0s${OFFCOL}" {0..77}; echo

eval "\${PASS1}\${PASS2}"; RET=\$?

if [ \$RET -eq 0 ] && [ "\$varCHKSUM" = "true" ]; then
  CURDIR="\$(pwd)"
  cd "\$(dirname "\${DESTARCH}")"
  md5sum -- "\$(basename "\${DESTARCH}")" > "\$(basename "\${DESTARCH}").md5"
  sha1sum -- "\$(basename "\${DESTARCH}")" > "\$(basename "\${DESTARCH}").sha1"
  cd "\${CURDIR}"
fi

echo; printf -- "${BLUECOL}*%.0s${OFFCOL}" {0..77}; echo
echo -e "${OFFCOL}"
#sync

if [ \$RET -ne 0 ]; then
  echo -ne "${REDCOL}$(gettext "Creation of") ${BLUECOL}"
  echo -n "\$(basename "\${DESTARCH}") "
  echo -e "${REDCOL}$(gettext "has failed!")"
  rm -f "\$DESTARCH"
else
  echo -ne "${BLUECOL}"
  echo -n "\$(basename "\${DESTARCH}") "
  echo -e "${GREENCOL}$(gettext "has been successfully created!")"
fi

echo -e "${OFFCOL}"
echo \$RET > '$TMPDIR/retval'

EOF

chmod +x $TMP_EXEC

# -----------------------------------------------------------------------------
# Ok, pack it!
# -----------------------------------------------------------------------------

#INPUT_SIZE=$(du -hcs "${IFILES[@]}" | tail -n -1 | cut -f1)
#export INPUT_SIZE DESTARCH
export DESTARCH

if [ "$varVERBOSE" = "false" ]; then
  
  #echo 'gtk-theme-name="default"' > $TMPDIR/gtkrc_custom
  #export GTK2_RC_FILES="${HOME}/.gtkrc-2.0:$TMPDIR/gtkrc_custom" 
  $GTKDIALOG -cp GUI_WAIT & GTKPID=$!
  
  $TMP_EXEC 2>&1 | sed -r "s/\x1B\[([0-9]{1,3}((;[0-9]{1,3})*)?)?[m|K|H|J]//g" | tr -s '\b' '\n' > $TMPDIR/packit.log
  RET=$(<$TMPDIR/retval)
  cd "$OLDDIR"

  kill -s 0 $GTKPID 2>/dev/null && [ "$(ps $GTKPID | grep "$GTKDIALOG")" ] && kill $GTKPID
  
  if [ $RET -eq 0 ]; then
    func_show_success
    exit 0
  else
    func_show_fail
    case "$?" in
      2) func_show_log; exit 1 ;;
      1) exec "$MYNAME" "$@" ;;
      *) exit 1 ;;
    esac
  fi

else

  if [ ! "`$GTKDIALOG --version | grep -w 'VTE'`" ]; then
    echo '/bin/bash' >> $TMP_EXEC
    for i in $TERM urxvt xterm rxvt lxterminal sakura; do
      [ `which $i 2>/dev/null` ] && { EXEC_TERMINAL=$i; break; }
    done
    $EXEC_TERMINAL -T "$APPNAME" -e $TMP_EXEC
    
  else
  
    export GUI_VTE='
    <window title="'$APPNAME'" image-name="'${APPICON}'">
      <vbox>
        <terminal argv0="/bin/sh"
	  			  scrollback-lines="100000"
  	    	  	  has-focus="true"
  			      text-background-color="#fff"
			      text-foreground-color="#000">
	      <variable>vte0</variable>
	      <width>82</width>
          <input>echo "HISTFILE=; '${TMP_EXEC}'"</input>
          <action signal="child-exited">exit:EXIT</action>
        </terminal>
      </vbox>
    <action signal="delete-event">EXIT:abort</action>
    </window>'
      
    $GTKDIALOG -cp GUI_VTE
    
  fi
fi

############################### |* @ ( |< 1 7  ################################