Hello community,

here is the log from the commit of package duply for openSUSE:Factory checked 
in at 2015-10-02 09:23:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/duply (Old)
 and      /work/SRC/openSUSE:Factory/.duply.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "duply"

Changes:
--------
--- /work/SRC/openSUSE:Factory/duply/duply.changes      2014-07-12 
17:14:50.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.duply.new/duply.changes 2015-10-02 
09:23:37.000000000 +0200
@@ -1,0 +2,47 @@
+Wed Sep 23 16:20:59 UTC 2015 - malcolmle...@opensuse.org
+
+- Update to version 1.10.1:
+  + Bugfix 86: Duply+Swift outputs warning.
+  + Bugfix 87: Swift fails without BACKEND_URL.
+- Changes from 1.10:
+  + Featreq 36: busybox issues - fix awk, grep version detection,
+    fix grep failure because --color=never switch is unsupported.
+  + Bugfix 81: --exclude-globbing-filelist is deprecated since
+    0.7.03.
+  + Implemented base-/dirname as bash functions.
+  + Featreq 31 " Support for duplicity Azure backend " - ignored a
+    contributed patch by Scott McKenzie and instead opted for
+    removing almost all code that deals with special env vars
+    required by backends. Adding and modifying these results in too
+    much overhead so I dropped this feature. The future alternative
+    for users is to consult the duplicity manpage and add the
+    needed export definitions to the conf file. Appended a
+    commented example to the template conf below the auth section.
+- Changes from 1.9.2:
+  + Bugfix: exporting keys with gpg2.1 works now.
+  + Documented GPG_OPTS needed for gpg2.1 to conf template.
+  + Bugfix 82: GREP_OPTIONS=--color=always disrupted time
+    calculation.
+  + Added GPG conf var (see conf template for details).
+  + Added grep version output as it is an integral needed binary.
+  + Added PYTHONPATH printout in version output.
+- Changes from 1.9.1:
+  + Export CMD_ERR now for scripts to detect if CMD_PREV
+    failed/succeeded.
+  + Bugfix: CMD_PREV contained command even if it was skipped.
+- Changes from 1.9.0:
+  + Bugfix: env vars were not exported when external script was
+    executable.
+  + Rework GPG_KEY handling, allow virtually anything now (uid,
+    keyid etc.) see gpg manpage, section "How to specify a user ID"
+    let gpg complain when the delivered values are invalid for
+    whatever reason.
+  + Started to rework tmp space checking, exposed folder & writable
+    check. TODO: reimplement enough file space available checking.
+- Changes from 1.8.0:
+  + Add command verifyPath to expose 'verify --file-to-restore'
+    action.
+  + Add time parameter support to verify command.
+  + Add section time formats to usage output.
+
+-------------------------------------------------------------------

Old:
----
  duply_1.7.4.tgz

New:
----
  duply_1.10.1.tgz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ duply.spec ++++++
--- /var/tmp/diff_new_pack.Ip8e7u/_old  2015-10-02 09:23:37.000000000 +0200
+++ /var/tmp/diff_new_pack.Ip8e7u/_new  2015-10-02 09:23:37.000000000 +0200
@@ -1,8 +1,8 @@
 #
 # spec file for package duply
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
-# Copyright (c) 2011-2013 Malcolm J Lewis <malcolmle...@opensuse.org>
+# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2011-2015 Malcolm J Lewis <malcolmle...@opensuse.org>
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,14 +18,16 @@
 
 
 Name:           duply
-Version:        1.7.4
+Version:        1.10.1
 Release:        0
 Summary:        A frontend for the mighty duplicity magic
 License:        GPL-2.0
 Group:          Productivity/Archiving/Compression
 Url:            http://duply.net/
-Source0:        
http://downloads.sourceforge.net/ftplicity/duply%20%28simple%20duplicity%29/1.7.x/%{name}_%{version}.tgz
+Source0:        
http://downloads.sourceforge.net/ftplicity/duply%20%28simple%20duplicity%29/1.10.x/%{name}_%{version}.tgz
+# MANUAL BEGIN
 Requires:       duplicity
+# MANUAL END
 BuildArch:      noarch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 

++++++ duply_1.7.4.tgz -> duply_1.10.1.tgz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/duply_1.7.4/INSTALL.txt new/duply_1.10.1/INSTALL.txt
--- old/duply_1.7.4/INSTALL.txt 2014-06-24 20:55:59.000000000 +0200
+++ new/duply_1.10.1/INSTALL.txt        2015-08-19 16:57:44.000000000 +0200
@@ -38,12 +38,12 @@
 # install into PREFIX
 PREFIX=~/_apps/duplicity-0.6.07
 python setup.py install --prefix="$PREFIX" --install-lib="$PREFIX"
-# OBSOLETE: since 0.6.17 the next step is not required anymore
+# NOTE: 0.6.17 to 25 do not need the next step, 0.6.25 and newer do again 
 # patch executable to find libs in PREFIX
-cat $PREFIX/bin/duplicity | \
-awk '1;/import getpass, gzip, os, sys, time, types/{print 
"sys.path.insert(1,sys.path[0] + \47/../\47)"}' > \
-$PREFIX/bin/duplicity_mod && chmod 755 $PREFIX/bin/duplicity_mod && \
-mv $PREFIX/bin/duplicity_mod $PREFIX/bin/duplicity
+awk '1;/import.*[ ,]+sys/{print "sys.path.insert(1,sys.path[0] + 
\47/../\47)"}' \
+"$PREFIX/bin/duplicity" > "$PREFIX/bin/duplicity_mod" && \
+chmod 755 "$PREFIX/bin/duplicity_mod" && \
+mv "$PREFIX/bin/duplicity_mod" "$PREFIX/bin/duplicity"
 
 If this works flawlessly than you will find the duplicity executable under
 $PREFIX/bin/duplicity
@@ -78,4 +78,4 @@
 UNINSTALL DUPLICITY
 
 python setup.py install --record files.txt
-cat files.txt | xargs rm -rf
\ No newline at end of file
+cat files.txt | xargs rm -rf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/duply_1.7.4/duply new/duply_1.10.1/duply
--- old/duply_1.7.4/duply       2014-06-24 20:55:59.000000000 +0200
+++ new/duply_1.10.1/duply      2015-08-19 16:57:44.000000000 +0200
@@ -9,7 +9,7 @@
 #  changed from ftplicity to duply.                                           #
 #  See http://duply.net or http://ftplicity.sourceforge.net/ for more info.   #
 #  (c) 2006 Christiane Ruetten, Heise Zeitschriften Verlag, Germany           #
-#  (c) 2008-2014 Edgar Soldin (changes since version 1.3)                     #
+#  (c) 2008-2015 Edgar Soldin (changes since version 1.3)                     #
 ###############################################################################
 #  LICENSE:                                                                   #
 #  This program is licensed under GPLv2.                                      #
@@ -34,6 +34,50 @@
 #
 #
 #  CHANGELOG:
+#  1.10.1 (19.8.2015)
+#  - bugfix 86: Duply+Swift outputs warning
+#  - bugfix 87: Swift fails without BACKEND_URL
+#
+#  1.10 (31.7.2015)
+#  - featreq 36: busybox issues - fix awk, grep version detection,
+#    fix grep failure because --color=never switch is unsupported
+#    (thx Thomas Harning Jr. for reporting and helping to debug/fix it)
+#  - bugfix 81: --exclude-globbing-filelist is deprecated since 0.7.03
+#    (thx Joachim Wiedorn, also for maintaining the debian package)
+#  - implemented base-/dirname as bash functions
+#  - featreq 31 " Support for duplicity Azure backend " - ignored a 
+#    contributed patch by Scott McKenzie and instead opted for removing almost
+#    all code that deals with special env vars required by backends.
+#    adding and modifying these results in too much overhead so i dropped this
+#    feature. the future alternative for users is to consult the duplicity 
+#    manpage and add the needed export definitions to the conf file.
+#    appended a commented example to the template conf below the auth section.
+#
+#  1.9.2 (21.6.2015)
+#  - bugfix: exporting keys with gpg2.1 works now (thx Philip Jocks)
+#  - documented GPG_OPTS needed for gpg2.1 to conf template (thx Troy Engel)
+#  - bugfix 82: GREP_OPTIONS=--color=always disrupted time calculation
+#  - added GPG conf var (see conf template for details)
+#  - added grep version output as it is an integral needed binary
+#  - added PYTHONPATH printout in version output
+#
+#  1.9.1 (13.10.2014)
+#  - export CMD_ERR now for scripts to detect if CMD_PREV failed/succeeded
+#  - bugfix: CMD_PREV contained command even if it was skipped
+#
+#  1.9.0 (24.8.2014)
+#  - bugfix: env vars were not exported when external script was executable
+#  - rework GPG_KEY handling, allow virtually anything now (uid, keyid etc.) 
+#    see gpg manpage, section "How to specify a user ID"
+#    let gpg complain when the delivered values are invalid for whatever reason
+#  - started to rework tmp space checking, exposed folder & writable check
+#    TODO: reimplement enough file space available checking
+#
+#  1.8.0 (13.7.2014)
+#  - add command verifyPath to expose 'verify --file-to-restore' action
+#  - add time parameter support to verify command
+#  - add section time formats to usage output 
+#
 #  1.7.4 (24.6.2014)
 #  - remove ubuntu one support, service is discontinued
 #  - featreq 31: add authenticated swift (contributed by Justus Seifert)
@@ -343,13 +387,35 @@
 #    1.0   - first release
 ###############################################################################
 
+# utility functions overriding binaries
+
+# wrap grep to override possible env set GREP_OPTIONS=--color=always
+function grep {
+  command env -u GREP_OPTIONS grep "$@"
+}
+
+# implement basename in plain bash
+function basename {
+  echo "${1##*/}"
+}
+
+# implement dirname in plain bash
+function dirname {
+  echo ${1%/*}
+}
+
+# a lookup function for executables working with names or file paths
+function lookup {
+  local bin="$1"
+  ( [ "${bin##*/}" == "$bin" ] && hash "$bin" 2>/dev/null ) || [ -x "$bin" ]
+}
 
 # important definitions #######################################################
 
 ME_LONG="$0"
 ME="$(basename $0)"
 ME_NAME="${ME%%.*}"
-ME_VERSION="1.7.4"
+ME_VERSION="1.10.1"
 ME_WEBSITE="http://duply.net";
 
 # default config values
@@ -357,11 +423,13 @@
 DEFAULT_TARGET='scheme://user[:password]@host[:port]/[/]path'
 DEFAULT_TARGET_USER='_backend_username_'
 DEFAULT_TARGET_PASS='_backend_password_'
+DEFAULT_GPG='gpg'
 DEFAULT_GPG_KEY='_KEY_ID_'
 DEFAULT_GPG_PW='_GPG_PASSWORD_'
 
 # function definitions ##########################
-function set_config { # sets config vars
+
+function set_config { # sets global config vars
   local CONFHOME_COMPAT="$HOME/.ftplicity"
   local CONFHOME="$HOME/.duply"
   local CONFHOME_ETC_COMPAT="/etc/ftplicity"
@@ -405,7 +473,7 @@
 
 function version_info { # print version information
   cat <<END
-  $ME version $ME_VERSION
+  $ME_NAME version $ME_VERSION
   ($ME_WEBSITE)
 END
 }
@@ -419,14 +487,18 @@
 }
 
 function using_info {
-  duplicity_version_get
+  lookup duplicity && duplicity_version_get
+  local NOTFOUND="MISSING"
   # freebsd awk (--version only), debian mawk (-W version only), deliver '' so 
awk does not wait for input
-  AWK_VERSION=$((awk --version '' 2>/dev/null || awk -W version '' 
2>/dev/null) | awk '/.+/{sub(/^[Aa][Ww][Kk][ \t]*/,"",$0);print $0;exit}')
-  PYTHON_VERSION=$(python -V 2>&1| awk '{print tolower($0);exit}')
-  GPG_INFO=`gpg --version 2>/dev/null| awk '/^gpg/{v=$1" "$3};/^Home/{print v" 
("$0")"}'`
-  BASH_VERSION=$(bash --version | awk '/^GNU bash, version/{sub(/GNU bash, 
version[ ]+/,"",$0);print $0}')
-  echo -e "Using installed duplicity version ${DUPL_VERSION:-(not 
found)}${PYTHON_VERSION+, $PYTHON_VERSION}\
-${GPG_INFO:+, $GPG_INFO}${AWK_VERSION:+, awk 
'${AWK_VERSION}'}${BASH_VERSION:+, bash '${BASH_VERSION}'}."
+  local AWK_VERSION=$( lookup awk && (awk --version 2>/dev/null || awk -W 
version 2>&1) | awk 'NR<=2&&tolower($0)~/(busybox|awk)/{success=1;print;exit} 
END{if(success<1) print "unknown"}' || echo "$NOTFOUND" )
+  local GREP_VERSION=$( lookup grep && grep --version 2>&1 | awk 
'NR<=2&&tolower($0)~/(busybox|grep.*[0-9]+\.[0-9]+)/{success=1;print;exit} 
END{if(success<1) print "unknown"}' || echo "$NOTFOUND" )
+  local PYTHON_VERSION=$(lookup python && python -V 2>&1| awk '{print 
tolower($0);exit}' || echo "python $NOTFOUND" )
+  local GPG_INFO=$(gpg_avail && gpg --version 2>&1| awk 'NR==1{v=$1" 
"$3};/^Home:/{print v" ("$0")"}' || echo "gpg $NOTFOUND")
+  local BASH_VERSION=$(bash --version | awk 'NR==1{IGNORECASE=1;sub(/GNU bash, 
version[ ]+/,"",$0);print $0}')
+  echo -e "Using installed duplicity version ${DUPL_VERSION:-$NOTFOUND}\
+${PYTHON_VERSION+, $PYTHON_VERSION${PYTHONPATH:+ 'PYTHONPATH=$PYTHONPATH'}}\
+${GPG_INFO:+, $GPG_INFO}${AWK_VERSION:+, awk 
'${AWK_VERSION}'}${GREP_VERSION:+, grep '${GREP_VERSION}'}\
+${BASH_VERSION:+, bash '${BASH_VERSION}'}."
 }
 
 function usage_info { # print usage information
@@ -469,10 +541,10 @@
   to '~/.${ME_NAME}/<profile>' (~ expands to environment variable \$HOME).
 
   Superuser root can place profiles under '/etc/${ME_NAME}'. Simply create
-  the folder manually before running $ME as superuser.
+  the folder manually before running $ME_NAME as superuser.
   Note:  
-    Already existing profiles in root's profile folder will cease to work
-    unless there are moved to the new location manually.
+    Already existing profiles in root's home folder will cease to work
+    unless they are moved to the new location manually.
 
   example 1:   $ME humbug backup
 
@@ -495,7 +567,7 @@
              the next command will only be executed if the previous failed
 
    example:  
-    'pre_and_bkp_or_verify_post' translates to 'pre+bkp-verify_post
+    'pre+bkp-verify_post' translates to 'pre_and_bkp_or_verify_post'
 
 COMMANDS:
   usage      get usage help text
@@ -512,7 +584,11 @@
   list [<age>]  
              list all files in backup (as it was at <age>, default: now)
   status     prints backup sets and chains currently in repository
-  verify     list files changed since latest backup
+  verify [<age>] [--compare-data]  
+             list files changed, since age if given
+  verifyPath <rel_path_in_bkp> <local_path> [<age>] [--compare-data]  
+             list changes of a file or folder path in backup compared to a
+             local path, since age if given
   restore <target_path> [<age>]  
              restore the complete backup to <target_path> [as it was at <age>]
   fetch <src_path> <target_path> [<age>]  
@@ -538,7 +614,7 @@
   txt2man    feature for package maintainers - create a manpage based on the 
              usage output. download txt2man from http://mvertes.free.fr/, put 
              it in the PATH and run '$ME txt2man' to create a man page.
-  version    show version information of $ME and needed programs
+  version    show version information of $ME_NAME and needed programs
 
 OPTIONS:
   --force    passed to duplicity (see commands: purge, purge-full, cleanup)
@@ -546,26 +622,35 @@
   --disable-encryption  
              disable encryption, overrides profile settings
 
+TIME FORMATS:
+  For all time related parameters like age, max_age etc.
+  Refer to the duplicity manpage for all available formats. Here some examples:
+    2002-01-25T07:00:00+02:00 (full date time format string)
+    2002/3/5 (date string YYYY/MM/DD)
+    12D (interval, 12 days ago)
+    1h78m (interval, 1 hour 78 minutes ago)
+
 PRE/POST SCRIPTS:
-  All internal duply variables will be readable in the scripts.
-  Some of interest might be
+  Useful internal duply variables will be readable in the scripts.
+  Some of interest may be
 
     CONFDIR, SOURCE, TARGET_URL_<PROT|HOSTPATH|USER|PASS>, 
-    GPG_<KEYS_ENC|KEY_SIGN|PW>, CMD_<PREV|NEXT>
+    GPG_<KEYS_ENC|KEY_SIGN|PW>, CMD_<PREV|NEXT>, CMD_ERR
 
   The CMD_* variables were introduced to allow different actions according to 
   the command the scripts were attached to e.g. 'pre_bkp_post_pre_verify_post' 
   will call the pre script two times, with CMD_NEXT variable set to 'bkp' 
   on the first and to 'verify' on the second run.
+  CMD_ERR holds the exit code of the CMD_PREV .
 
 EXAMPLES:
   create profile 'humbug':  
-    $ME humbug create (now edit the resulting conf file)
+    $ME humbug create (don't forget to edit this new conf file)
   backup 'humbug' now:  
     $ME humbug backup
   list available backup sets of profile 'humbug':  
     $ME humbug status
-  list and delete obsolete backup archives of 'humbug':  
+  list and delete outdated backups of 'humbug':  
     $ME humbug purge --force
   restore latest backup of 'humbug' to /mnt/restore:  
     $ME humbug restore /mnt/restore
@@ -574,6 +659,8 @@
     (see "duplicity manpage", section TIME FORMATS)
   a one line batch job on 'humbug' for cron execution:  
     $ME humbug backup_verify_purge --force
+  batch job to run a full backup with pre/post scripts:  
+    $ME humbug pre_full_post
 
 FILES:
   in profile folder '~/.${ME_NAME}/<profile>' or '/etc/${ME_NAME}'
@@ -609,20 +696,24 @@
     cat <<EOF >"$CONF"
 # gpg encryption settings, simple settings:
 #  GPG_KEY='disabled' - disables encryption alltogether
-#  GPG_KEY='<key1>[,<key2>]'; GPG_PW='pass' - encrypt with keys, sign 
-#    with key1 if secret key available and use GPG_PW for sign & decrypt
+#  GPG_KEY='<key1>[,<key2>]'; GPG_PW='pass' - encrypt with keys,
+#   sign if secret key of key1 is available use GPG_PW for sign & decrypt
+#  Note: you can specify keys via all methods described in gpg manpage,
+#        section "How to specify a user ID", escape commas (,) via backslash 
(\)
+#        e.g. 'Mueller, Horst', 'Bernd' -> 'Mueller\, Horst, Bernd'
+#        as they are used to separate the entries
 #  GPG_PW='passphrase' - symmetric encryption using passphrase only
 GPG_KEY='${DEFAULT_GPG_KEY}'
 GPG_PW='${DEFAULT_GPG_PW}'
 # gpg encryption settings in detail (extended settings)
 #  the above settings translate to the following more specific settings
-#  GPG_KEYS_ENC='<keyid1>,[<keyid2>,...]' - list of pubkeys to encrypt to
+#  GPG_KEYS_ENC='<keyid1>[,<keyid2>,...]' - list of pubkeys to encrypt to
 #  GPG_KEY_SIGN='<keyid1>|disabled' - a secret key for signing
 #  GPG_PW='<passphrase>' - needed for signing, decryption and symmetric
 #   encryption. If you want to deliver different passphrases for e.g. 
 #   several keys or symmetric encryption plus key signing you can use
-#   gpg-agent. Add '--use-agent' to the duplicity parameters below.
-#   also see "A NOTE ON SYMMETRIC ENCRYPTION AND SIGNING" in duplicity manpage
+#   gpg-agent. Simply make sure that GPG_AGENT_INFO is set in environment.
+#   also see "A NOTE ON SYMMETRIC ENCRYPTION AND SIGNING" in duplicity manpage 
 # notes on en/decryption
 #  private key and passphrase will only be needed for decryption or signing.
 #  decryption happens on restore and incrementals (compare archdir contents).
@@ -634,60 +725,50 @@
 # NOTE: available since duplicity 0.6.14, translates to SIGN_PASSPHRASE
 #GPG_PW_SIGN='<signpass>'
 
+# uncomment and set a file path or name force duply to use this gpg executable
+# available in duplicity 0.7.04 and above (currently unreleased 06/2015)
+#GPG='/usr/local/gpg-2.1/bin/gpg'
+
 # gpg options passed from duplicity to gpg process (default='')
 # e.g. "--trust-model pgp|classic|direct|always" 
 #   or "--compress-algo=bzip2 --bzip2-compress-level=9"
 #   or "--personal-cipher-preferences AES256,AES192,AES..."
 #   or "--homedir ~/.duply" - keep keyring and gpg settings duply specific
+#   or "--pinentry-mode loopback" - needed for GPG 2.1+ _and_
+#      also enable allow-loopback-pinentry in your .gnupg/gpg-agent.conf
 #GPG_OPTS=''
 
 # disable preliminary tests with the following setting
 #GPG_TEST='disabled'
 
-# credentials & server address of the backup target (URL-Format)
-# syntax is
-#   scheme://[user:password@]host[:port]/[/]path
-# for details see duplicity manpage, section URL Format
-#   http://duplicity.nongnu.org/duplicity.1.html#sect8
-# probably one out of
-#   # for cloudfiles backend user id is CLOUDFILES_USERNAME, password is 
-#   # CLOUDFILES_APIKEY, you might need to set CLOUDFILES_AUTHURL manually
-#   cf+http://[user:password@]container_name
-#   dpbx:///some_dir
-#   file://[relative|/absolute]/local/path
-#   ftp[s]://user[:password]@other.host[:port]/some_dir
-#   gdocs://user[:password]@other.host/some_dir
-#   # for the google cloud storage (since duplicity 0.6.22)
-#   # user/password are GS_ACCESS_KEY_ID/GS_SECRET_ACCESS_KEY
-#   gs://bucket[/prefix] 
-#   hsi://user[:password]@other.host/some_dir
-#   imap[s]://user[:password]@host.com[/from_address_prefix]
-#   mega://user[:password]@mega.co.nz/some_dir
-#   rsync://user[:password]@host.com[:port]::[/]module/some_dir
-#   # rsync over ssh (only keyauth)
-#   rsync://u...@host.com[:port]/[relative|/absolute]_path
-#   # for the s3 user/password are AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY
-#   s3://[user:password@]host/bucket_name[/prefix]
-#   s3+http://[user:password@]bucket_name[/prefix]
-#   # scp and sftp are aliases for the ssh backend
-#   ssh://user[:password]@other.host[:port]/[/]some_dir
-#   # for authenticated swift define TARGET_USER or SWIFT_USERNAME,
-#   # TARGET_PASS or SWIFT_PASSWORD, SWIFT_AUTHURL (mandatory, the path to 
-#   # your identity service, omitting leads to an error with swift),
-#   # optionally SWIFT_AUTHVERSION (which defaults to "1")
-#   swift://container_name
-#   tahoe://alias/directory
-#   webdav[s]://user[:password]@other.host/some_dir
-# ATTENTION: characters other than A-Za-z0-9.-_.~ in the URL have 
-#            to be replaced by their url encoded pendants, see
-#            http://en.wikipedia.org/wiki/Url_encoding 
-#            if you define the credentials as TARGET_USER, TARGET_PASS below 
-#            duply will try to url_encode them for you if the need arises
+# backend, credentials & location of the backup target (URL-Format)
+# generic syntax is
+#   scheme://[user[:password]@]host[:port]/[/]path
+# eg.
+#   sftp://bob:sec...@backupserver.com//home/bob/dupbkp
+# for details and available backends see duplicity manpage, section URL Format
+#   http://duplicity.nongnu.org/duplicity.1.html#sect7
+# NOTE:
+#   some backends (eg. cloudfiles) need additional env vars to be set to
+#   work properly, when in doubt consult the man page mentioned above.
+# ATTENTION:
+#   characters other than A-Za-z0-9.-_.~ in the URL have to be
+#   replaced by their url encoded pendants, see
+#     http://en.wikipedia.org/wiki/Url_encoding
+#   if you define the credentials as TARGET_USER, TARGET_PASS below $ME
+#   will try to url_encode them for you if the need arises.
 TARGET='${DEFAULT_TARGET}'
 # optionally the username/password can be defined as extra variables
 # setting them here _and_ in TARGET results in an error
 #TARGET_USER='${DEFAULT_TARGET_USER}'
 #TARGET_PASS='${DEFAULT_TARGET_PASS}'
+# alternatively you might export the auth env vars for your backend here
+# when in doubt consult (if existing) the NOTE section of your backend on
+#  http://duplicity.nongnu.org/duplicity.1.html for details
+# eg. for cloud files backend it might look like this (uncomment for use!)
+#export CLOUDFILES_USERNAME='someuser'
+#export CLOUDFILES_APIKEY='somekey'
+#export CLOUDFILES_AUTHURL ='someurl'
 
 # base directory to backup
 SOURCE='${DEFAULT_SOURCE}'
@@ -865,15 +946,14 @@
 "
 }
 
-# TODO
 function error_gpg_key {
-  local KEY_ID=$1
-  local KIND=$2
+  local KEY_ID="$1"
+  local KIND="$2"
   error_gpg "${KIND} gpg key '${KEY_ID}' cannot be found." \
 "Doublecheck if the above key is listed by 'gpg --list-keys' or available 
-  as gpg key file '$(basename "$(gpg_keyfile ${KEY_ID})")' in the profile 
folder.
-  If not you can put it there and $ME will autoimport it on the next run.
-  Alternatively import it manually as the user you plan to run $ME with."
+  as gpg key file '$(basename "$(gpg_keyfile "${KEY_ID}")")' in the profile 
folder.
+  If not you can put it there and $ME_NAME will autoimport it on the next run.
+  Alternatively import it manually as the user you plan to run $ME_NAME with."
 }
 
 function error_gpg_test {
@@ -884,10 +964,10 @@
 Hint${hint:+s}:
   ${hint}This error means that gpg is probably misconfigured or not working 
   correctly. The error message above should help to solve the problem.
-  However, if for some reason $ME should misinterpret the situation you 
+  However, if for some reason $ME_NAME should misinterpret the situation you 
   can define GPG_TEST='disabled' in the conf file to bypass the test.
   Please do not forget to report the bug in order to resolve the problem
-  in future versions of $ME.
+  in future versions of $ME_NAME.
 "
 }
 
@@ -904,7 +984,7 @@
 function duplicity_version_get {
        var_isset DUPL_VERSION && return
        DUPL_VERSION=`duplicity --version 2>&1 | awk '/^duplicity /{print $2; 
exit;}'`
-       #DUPL_VERSION='0.6.08b' #,0.4.4.RC4,0.6.08b
+       #DUPL_VERSION='0.7.03' #'0.6.08b' #,0.4.4.RC4,0.6.08b
        DUPL_VERSION_VALUE=0
        DUPL_VERSION_AWK=$(awk -v v="$DUPL_VERSION" 'BEGIN{
        if (match(v,/[^\.0-9]+[0-9]*$/)){
@@ -924,7 +1004,7 @@
        if [ $DUPL_VERSION_VALUE -eq 0 ]; then
                inform "duplicity version check failed (please report, this is 
a bug)" 
        elif [ $DUPL_VERSION_VALUE -le 404 ] && [ ${DUPL_VERSION_RC:-4} -lt 4 
]; then
-               error "The installed version $DUPL_VERSION is incompatible with 
$ME v$ME_VERSION.
+               error "The installed version $DUPL_VERSION is incompatible with 
$ME_NAME v$ME_VERSION.
 You should upgrade your version of duplicity to at least v0.4.4RC4 or
 use the older ftplicity version 1.1.1 from $ME_WEBSITE."
        fi
@@ -962,14 +1042,14 @@
 
 function run_cmd {
   # run or print escaped cmd string
-  CMD_ERR=0
+  local CMD_ERR=0
   if [ -n "$PREVIEW" ]; then
     CMD_OUT=$( echo "$@ 2>&1" )
-    CMD_MSG="-- Run cmd '$CMD_MSG' --\n$CMD_OUT"
+    CMD_MSG="-- Run cmd -- $CMD_MSG --\n$CMD_OUT"
   elif [ -n "$CMD_DISABLED" ]; then
     CMD_MSG="$CMD_MSG (DISABLED) - $CMD_DISABLED"
   else
-    CMD_OUT=` eval $@ 2>&1 `
+    CMD_OUT=` eval "$@" 2>&1 `
     CMD_ERR=$?
     if [ "$CMD_ERR" = "0" ]; then
       CMD_MSG="$CMD_MSG (OK)"
@@ -1007,8 +1087,8 @@
   if gpg_disabled; then
     local DUPL_PARAM_ENC='--no-encryption'
   else
-    local DUPL_PARAM_ENC=$(gpg_prefix_keyset ' --encrypt-key ' 'GPG_KEYS_ENC')
-    gpg_signing && local DUPL_PARAM_SIGN=$(gpg_prefix_keyset ' --sign-key ' 
'GPG_KEY_SIGN')
+    local DUPL_PARAM_ENC=$(gpg_prefix_keyset '--encrypt-key' 
"${GPG_KEYS_ENC_ARRAY[@]}")
+    gpg_signing && local DUPL_PARAM_SIGN=$(gpg_prefix_keyset '--sign-key' 
"$GPG_KEY_SIGN")
     # interpret password settings
     var_isset 'GPG_PW' && DUPL_ARG_ENC="PASSPHRASE=$(qw "${GPG_PW}")"
     var_isset 'GPG_PW_SIGN' && DUPL_ARG_ENC="${DUPL_ARG_ENC} 
SIGN_PASSPHRASE=$(qw "${GPG_PW_SIGN}")"
@@ -1033,17 +1113,18 @@
  ${DUPL_ARG_ENC}"
 }
 
-# filter the DUPL_PARAMS var from conf
+
+# function to filter the DUPL_PARAMS var from user conf
 function duplicity_params_conf {
-       # reuse cmd var from main loop
-       ## in/exclude parameters are currently not supported on restores
-       if [ "$cmd" = "fetch" ] || [ "$cmd" = "restore" ]; then
-               # filter exclude params from fetch/restore
-               echo "$DUPL_PARAMS" | awk '{gsub(/--(ex|in)clude[a-z-]*(([ 
\t]+|=)[^-][^ \t]+)?/,"");print}'
-               return
-       fi
-       
-       echo "$DUPL_PARAMS"
+  # reuse cmd var from main loop
+  ## in/exclude parameters are currently not supported on restores
+  if [ "$cmd" = "fetch" ] || [ "$cmd" = "restore" ] || [ "$cmd" = "status" ]; 
then
+    # filter exclude params from fetch/restore
+    echo "$DUPL_PARAMS" | awk '{gsub(/--(ex|in)clude[a-z-]*(([ \t]+|=)[^-][^ 
\t]+)?/,"");print}'
+    return
+  fi
+  
+  echo "$DUPL_PARAMS"
 }
 
 function duplify { # the actual wrapper function
@@ -1069,7 +1150,7 @@
   var_isset 'PREVIEW' && local RUN=echo || local RUN=eval
 $RUN ${DUPL_VARS_GLOBAL} ${BACKEND_PARAMS} \
  ${DUPL_PRECMD} duplicity $DUPL_CMD $DUPL_PARAMS_GLOBAL 
$(duplicity_params_conf)\
- $GPG_USEAGENT $DUPL_CMD_PARAMS ${PREVIEW:+}
+ $GPG_USEAGENT $(gpg_custom_binary) $DUPL_CMD_PARAMS ${PREVIEW:+}
 
   local ERR=$?
   return $ERR
@@ -1136,12 +1217,12 @@
 }
 
 function var_isset {
-       if [ -z "$1" ]; then
-               echo "ERROR: function var_isset needs a string as parameter"
-       elif eval "[ \"\${$1}\" == 'not_set' ]" || eval "[ \"\${$1-not_set}\" 
!= 'not_set' ]"; then
-               return 0
-       fi
-       return 1
+  if [ -z "$1" ]; then
+    echo "ERROR: function var_isset needs a string as parameter"
+  elif eval "[ \"\${$1}\" == 'not_set' ]" || eval "[ \"\${$1-not_set}\" != 
'not_set' ]"; then
+    return 0
+  fi
+  return 1
 }
 
 function url_encode {
@@ -1167,17 +1248,53 @@
   echo "$@"|awk '$0=tolower($0)'
 }
 
+function isnumber {
+  case "$*" in
+    ''|*[!0-9]*) return 1;;
+    *) return 0;;
+  esac
+}
+
+#function tmp_space {
+#  
+#  if ! isnumber $VOLSIZE; then
+#    inform "failed to determine free space (please report, this is a bug)"
+#    return
+#  fi
+#  
+# get free temp space
+#  TEMP_FREE="$(df -P -k "$TEMP_DIR" 2>/dev/null | awk 
'END{pos=(NF-2);if(pos>0) print $pos;}')"
+#  # check for free space or FAIL
+#  if [ $((${TEMP_FREE:-0}-${VOLSIZE:-0}*1024)) -lt 0-lt 0 ]; then
+#    error "Temporary file space '$TEMP_DIR' free space is smaller 
($((TEMP_FREE/1024))MB)
+#than one duplicity volume (${VOLSIZE}MB).
+#    
+#  Hint: Free space or change TEMP_DIR setting."
+#fi
+#
+#}
+
 function gpg_disabled {
-  echo "${GPG_KEY}${GPG_KEYS_ENC}" | grep -iq 'disabled'
+  echo "${GPG_KEY}" | grep -iq -e '^disabled$'
+}
+
+# usage: join SEPARATOR "entry1" "entry2"
+function join {
+  local SEP="$1" ENTRY OUT; shift;
+  for ENTRY in "$@"; do
+    ENTRY=${ENTRY//$SEP/\\$SEP}
+    [ -z "$OUT" ] && OUT=$ENTRY || OUT="$OUT$SEP$ENTRY"
+  done
+  echo $OUT
 }
 
 function gpg_signing {
-  return $(echo ${GPG_KEY_SIGN} | grep -ic 'disabled')
+  echo ${GPG_KEY_SIGN} | grep -v -q -e '^disabled$'
 }
 
 # parameter key id, key_type
 function gpg_keyfile {
-  local GPG_KEY="$1" TYPE="$2"
+  local GPG_KEY=$(gpg_key_legalize $1) TYPE="$2"
   local KEYFILE="${KEYFILE//.asc/${GPG_KEY:+.$GPG_KEY}.asc}"
   echo "${KEYFILE//.asc/${TYPE:+.$(tolower $TYPE)}.asc}"
 }
@@ -1187,8 +1304,8 @@
   local i FILE FOUND=0 KEY_ID="$1" KEY_TYPE="$2" KEY_FP="" ERR=0
   # create a list of legacy key file names and current naming scheme
   # we always import pub and sec if they are avail in conf folder
-  local KEYFILES=( "$CONFDIR/gpgkey" "$(gpg_keyfile $KEY_ID)" \
-                   "$(gpg_keyfile $KEY_ID PUB)" "$(gpg_keyfile $KEY_ID SEC)")
+  local KEYFILES=( "$CONFDIR/gpgkey" $(gpg_keyfile "$KEY_ID") \
+                   $(gpg_keyfile "$KEY_ID" PUB) $(gpg_keyfile "$KEY_ID" SEC))
 
   # Try autoimport from existing old gpgkey files 
   # and new gpgkey.XXX.asc files (since v1.4.2)
@@ -1199,8 +1316,8 @@
       FOUND=1
       
       CMD_MSG="Import keyfile '$FILE' to keyring"
-      run_cmd "$GPG" $GPG_OPTS --batch --import "$FILE"
-      if [ "$CMD_ERR" != "0" ]; then 
+      run_cmd gpg $GPG_OPTS --batch --import "$FILE"
+      if [ "$?" != "0" ]; then 
         warning "Import failed.${CMD_OUT:+\n$CMD_OUT}"
         ERR=1
         # continue with next
@@ -1214,43 +1331,44 @@
   fi
 
   # try to set trust automagically
-  CMD_MSG="Autoset trust of key '$KEY_ID'to ultimate"
-  run_cmd echo $(gpg_fingerprint $KEY_ID):6: \| "$GPG" $GPG_OPTS 
--import-ownertrust --batch --logger-fd 1
-  if [ "$CMD_ERR" = "0" ] && [ -z "$PREVIEW" ]; then 
+  CMD_MSG="Autoset trust of key '$KEY_ID' to ultimate"
+  run_cmd echo $(gpg_fingerprint "$KEY_ID"):6: \| gpg $GPG_OPTS 
--import-ownertrust --batch --logger-fd 1
+  if [ "$?" = "0" ] && [ -z "$PREVIEW" ]; then 
    # success on all levels, we're done
    return $ERR
   fi
 
   # failover: user has to set trust manually
-  echo -e "For $ME to work you have to set the trust level 
+  echo -e "For $ME_NAME to work you have to set the trust level 
 with the command \"trust\" to \"ultimate\" (5) now.
 Exit the edit mode of gpg with \"quit\"."
   CMD_MSG="Running gpg to manually edit key '$KEY_ID'"
-  run_cmd sleep 5\; "$GPG" $GPG_OPTS --edit-key $KEY_ID
+  run_cmd sleep 5\; gpg $GPG_OPTS --edit-key "$KEY_ID"
 
   return $ERR
 }
 
-# check for 8 digits and using 0x00.. here because gpg uses substring matching 
by default
 # see 'How to specify a user ID' on gpg manpage
 function gpg_fingerprint {
-  [ ${#1} -eq 8 ] \
-    && local PRINT=$("$GPG" $GPG_OPTS --fingerprint 0x"$1" 2>&1|awk -F= 
'NR==2{gsub(/ /,"",$2);$2=toupper($2); if ( $2 ~ /^[A-F0-9]+$/ && length($2) == 
40 ) print $2; else exit 1}') \
+  local PRINT=$(gpg $GPG_OPTS --fingerprint "$1" 2>&1|awk -F= 'NR==2{gsub(/ 
/,"",$2);$2=toupper($2); if ( $2 ~ /^[A-F0-9]+$/ && length($2) == 40 ) print 
$2; else exit 1}') \
     && [ -n "$PRINT" ] && echo $PRINT && return 0
   return 1
 }
 
 function gpg_export_if_needed {
-  local SUCCESS FILE KEY_TYPE KEY_LIST=$1
+  local SUCCESS FILE KEY_TYPE
   local TMPFILE="$TEMP_DIR/${ME_NAME}.$$.$(date_fix %s).gpgexp"
-  for KEY_ID in $KEY_LIST; do
+  for KEY_ID in "$@"; do
     # check if already exported, do it if not
     for KEY_TYPE in PUB SEC; do
-      FILE="$(gpg_keyfile $KEY_ID $KEY_TYPE)"
-      if [ ! -f "$FILE" ] && eval gpg_$(tolower $KEY_TYPE)_avail $KEY_ID; then
+      FILE="$(gpg_keyfile "$KEY_ID" $KEY_TYPE)"
+      if [ ! -f "$FILE" ] && eval gpg_$(tolower $KEY_TYPE)_avail \"$KEY_ID\"; 
then
         # exporting
-        CMD_MSG="Export $KEY_TYPE key $KEY_ID"
-        run_cmd $GPG $GPG_OPTS --armor --export"$(test "SEC" = "$KEY_TYPE" && 
echo -secret-keys)"" $KEY_ID >> \"$TMPFILE\""
+        CMD_MSG="Export $KEY_TYPE key '$KEY_ID'"
+        # gpg2.1 insists on passphrase here, gpg2.0- happily exports w/o it
+        # we pipe an empty string when GPG_PW is not set to avoid gpg silently 
waiting for input
+        run_cmd echo $(qw $GPG_PW) \| gpg $GPG_OPTS --passphrase-fd 0 --armor 
--export"$(test "SEC" = "$KEY_TYPE" && echo -secret-keys)"" $(qw $KEY_ID) >> 
\"$TMPFILE\""
+        CMD_ERR=$?
 
         if [ "$CMD_ERR" = "0" ]; then
           CMD_MSG="Write file '"$(basename "$FILE")"'"
@@ -1269,22 +1387,31 @@
     done
   done
   
-  [ -n "$SUCCESS" ] && inform "$ME exported new keys to your profile.
+  [ -n "$SUCCESS" ] && inform "$ME_NAME exported new keys to your profile.
 You should backup your changed profile folder now and store it in a safe 
place."
 }
 
+# replace all non-alnum chars with underscore (for file operations)
+function gpg_key_legalize {
+  echo $* | awk '{gsub(/[^a-zA-Z0-9]/,"_",$0); print}'
+}
+
 function gpg_key_cache {
   local RES
+  local MODE=$1
+  shift
   local PREFIX="GPG_KEY"
-  local CACHE="PREFIX_$1_$2"
-  if [ "$1" = "RESET" ]; then
-    eval unset PREFIX_PUB_$2 PREFIX_SEC_$2
+  local SUFFIX=$(gpg_key_legalize "$@")
+  local KEYID="$*"
+  local CACHE="${PREFIX}_${MODE}_${SUFFIX}"
+  if [ "$MODE" = "RESET" ]; then
+    eval unset ${PREFIX}_PUB_$SUFFIX ${PREFIX}_SEC_$SUFFIX
     return 255
   elif ! var_isset "$CACHE"; then
-    if [ "$1" = "PUB" ]; then
-      RES=$("$GPG" $GPG_OPTS --list-key "$2" > /dev/null 2>&1; echo -n $?)
-    elif [ "$1" = "SEC" ]; then
-      RES=$("$GPG" $GPG_OPTS --list-secret-key "$2" > /dev/null 2>&1; echo -n 
$?)
+    if [ "$MODE" = "PUB" ]; then
+      RES=$(gpg $GPG_OPTS --list-key "$KEYID" > /dev/null 2>&1; echo -n $?)
+    elif [ "$MODE" = "SEC" ]; then
+      RES=$(gpg $GPG_OPTS --list-secret-key "$KEYID" > /dev/null 2>&1; echo -n 
$?)
     else
       return 255
     fi
@@ -1294,34 +1421,34 @@
 }
 
 function gpg_pub_avail {
-  gpg_key_cache PUB $1
+  gpg_key_cache PUB "$@"
 }
 
 function gpg_sec_avail {
-  gpg_key_cache SEC $1
+  gpg_key_cache SEC "$@"
 }
 
 function gpg_key_format {
   echo $1 | grep -q '^[0-9a-fA-F]\{8\}$'
 }
 
-function gpg_split_keyset {
-  awk "BEGIN{ keys=toupper(\"$@\"); gsub(/[^A-Z0-9]/,\" \",keys); print keys }"
-}
-
-function gpg_join_keyset {
-  local KEY_ID OUT
-  for KEY_ID in $@; do
-    [ -z "$OUT" ] && OUT=$KEY_ID || OUT=${OUT},${KEY_ID}
-  done
-  echo $OUT
+#function gpg_split_keyset {
+#  return
+#  awk "BEGIN{ keys=toupper(\"$@\"); gsub(/[^A-Z0-9]/,\" \",keys); print keys 
}"
+#}
+
+# splits a comma separated line into lines, respects escaped commas
+function gpg_split_keyset2 {
+  local LIST
+  LIST=$(echo "$@" | awk '{ gsub(/,/,"\n",$0); gsub(/\\\n/,",",$0); print $0 
}')
+  echo -e "$LIST"
 }
 
 function gpg_prefix_keyset {
-  local KEY_ID OUT KEYSET
-  [ -n "$2" ] && eval "local KEYSET=\"\${$2[@]}\""
-  for KEY_ID in $KEYSET; do
-    OUT=${OUT}${1}${KEY_ID}
+  local PREFIX="$1" OUT=""
+  shift
+  for KEY_ID in "$@"; do
+    OUT="${OUT} $PREFIX $(qw ${KEY_ID})"
   done
   echo $OUT
 }
@@ -1335,18 +1462,17 @@
         print $0; exit}' "$CONF"
 }
 
+# return success if at least one secret key is available
 function gpg_key_decryptable {
-  # decryption needs pass, might be empty, but must be set
-  #var_isset 'GPG_PW' || return 1
   local KEY_ID
-  for KEY_ID in ${GPG_KEYS_ENC[@]}; do
-    gpg_sec_avail $KEY_ID && return 0
+  for KEY_ID in "${GPG_KEYS_ENC_ARRAY[@]}"; do
+    gpg_sec_avail "$KEY_ID" && return 0
   done
   return 1
 }
 
 function gpg_symmetric {
-  [ -z "${GPG_KEY}${GPG_KEYS_ENC}" ]
+  [ -z "${GPG_KEY}${GPG_KEYS_ENC_ARRAY}" ]
 }
 
 # checks for max two params if they are set, typically GPG_PW & GPG_PW_SIGN
@@ -1387,6 +1513,27 @@
   return $ERR
 }
 
+function gpg_custom_binary {
+  var_isset GPG && [ "$GPG" != "$DEFAULT_GPG" ] &&\
+    echo "--gpg-binary $(qw "$GPG")"
+}
+
+function gpg_binary {
+  local BIN
+  var_isset GPG && BIN="$GPG" || BIN="$DEFAULT_GPG"
+  echo "$BIN"
+}
+
+function gpg_avail {
+  lookup $(gpg_binary)
+}
+
+# enforce the use our selected gpg binary
+function gpg {
+  command $(gpg_binary) "$@"
+}
+export -f gpg
+
 # start of script 
#######################################################################
 
 # confidentiality first, all we create is only readable by us
@@ -1396,9 +1543,9 @@
 [ -n "$ME_LONG" ] && [ -x "$ME_LONG" ] || error "$ME missing. Executable & 
available in path? ($ME_LONG)"
 
 if [ ${#@} -eq 1 ]; then
-       cmd="${1}"
+  cmd="${1}"
 else
-       FTPLCFG="${1}" ; cmd="${2}"
+  FTPLCFG="${1}" ; cmd="${2}"
 fi
 
 # deal with command before profile validation calls
@@ -1438,6 +1585,11 @@
     exit 0
     ;;
   version|-version|--version|-v|-V)
+    # profile can override GPG, so import it if it was given
+    var_isset FTPLCFG && {
+      set_config
+      [ -r "$CONF" ] && . "$CONF" || warning "Cannot import config '$CONF'."
+    }
     version_info_using
     exit 0
     ;;
@@ -1461,13 +1613,18 @@
 echo "Start $ME v$ME_VERSION, time is $(date_fix '%F %T')."
 
 # check system environment
-DUPLICITY="$(which duplicity 2>/dev/null)"
-[ -z "$DUPLICITY" ] && error_path "duplicity missing. installed und available 
in path?"
+
+# is duplicity avail
+lookup duplicity || error_path "duplicity missing. installed und available in 
path?"
 # init, exec duplicity version check info
 duplicity_version_get
 duplicity_version_check
 
-[ -z "$(which awk 2>/dev/null)" ] && error_path "awk missing. installed und 
available in path?"
+# check for certain important helper programs
+for f in awk grep; do
+  lookup "$f" || \
+    error_path "$f missing. installed und available in path?"
+done
 
 ### read configuration
 set_config
@@ -1534,12 +1691,6 @@
   }')
 eval ${TARGET_SPLIT_URL}
 
-# check if backend specific software is in path
-[ -n "$(echo ${TARGET_URL_PROT} | grep -i -e '^ftp://$')" ] && \
-  [ -z "$(which ncftp 2>/dev/null)" ] && error_path "Protocol 'ftp' needs 
ncftp. Installed und available in path?" 
-[ -n "$(echo ${TARGET_URL_PROT} | grep -i -e '^ftps://$')" ] && \
-  [ -z "$(which lftp 2>/dev/null)" ] && error_path "Protocol 'ftps' needs 
lftp. Installed und available in path?"
-
 # fetch commmand from parameters 
########################################################
 # Hint: cmds is also used to check if authentification info sufficient in the 
next step 
 cmds="$2"; shift 2
@@ -1609,54 +1760,25 @@
  Hint: Remove conflicting setting."
 fi
 
-# check if authentication information sufficient
-if ( ( ! var_isset 'TARGET_USER' && ! var_isset 'TARGET_URL_USER' ) && \
-       ( ! var_isset 'TARGET_PASS' && ! var_isset 'TARGET_URL_PASS' ) ); then
-  # ok here some exceptions:
-  #   protocols that do not need passwords
-  #   s3[+http] only needs password for write operations
-  if [ -n "$( tolower "${TARGET_URL_PROT}" | grep -e 
'^\(dpbx\|file\|tahoe\|ssh\|scp\|sftp\|swift\)://$' )" ]; then
-    : # all is well file/tahoe do not need passwords, ssh might use key auth
-  elif [ -n "$(tolower "${TARGET_URL_PROT}" | grep -e '^s3\(\+http\)\?://$')" 
] && \
-     [ -z "$(echo ${cmds} | grep -e '\(bkp\|incr\|full\|purge\|cleanup\)')" ]; 
then
-    : # still fine, it's possible to read only access configured buckets 
anonymously
-  else
-    error " Backup target credentials needed but not set in conf file 
- '$CONF'.
- Setting TARGET_USER or TARGET_PASS or the corresponding values in TARGET url 
- are missing. Some protocols only might need it for write access to the backup 
- repository (commands: bkp,backup,full,incr,purge) but not for read only access
- (e.g. verify,list,restore,fetch). 
- 
- Hints:
-   Add the credentials (user,password) to the conf file.
-   To force an empty password set TARGET_PASS='' or 
TARGET='prot://user:@host..'.
-"
-  fi
-fi
-
 # GPG config plausibility check1 (disabled check) #############################
 if gpg_disabled; then
-       : # encryption disabled, all is well
-
+  : # encryption disabled, all is well
 elif [ -z "${GPG_KEY}${GPG_KEYS_ENC}${GPG_KEY_SIGN}" ] && ! var_isset 
'GPG_PW'; then
-       warning "GPG_KEY and GPG_PW are empty or not set in conf file 
+  warning "GPG_KEY, GPG_KEYS_ENC, GPG_KEY_SIGN and GPG_PW are empty/not set in 
conf file 
 '$CONF'.
 Will disable encryption for duplicity now.
 
 Hint: 
  If you really want to use _no_ encryption you can disable this warning by 
  setting GPG_KEY='disabled' in conf file."
- GPG_KEY='disabled'
+  GPG_KEY='disabled'
 fi
 
 # GPG availability check (now we know if gpg is really needed)#################
 if ! gpg_disabled; then 
-       GPG="$(which gpg 2>/dev/null)"
-       [ -z "$GPG" ] && error_path "gpg missing. installed und available in 
path?"
+  gpg_avail || error_path "gpg '$(gpg_binary)' missing. installed und 
available in path?"
 fi
 
-
 # Output versions info ########################################################
 using_info
 
@@ -1671,29 +1793,20 @@
 '$CONF'."
 fi
 
-# disabled as keys can really be given in too many forms e.g. short/long id, 
fingerprint, email, name ...
-## check gpg keys format
-#for KEY_SET_NAME in GPG_KEY GPG_KEYS_ENC $(gpg_signing && echo -n 
GPG_KEY_SIGN); do
-#  eval KEY_SET="\${${KEY_SET_NAME}}"
-#  for KEY_ID in $(gpg_split_keyset "$KEY_SET"); do
-#    # test format [ ! $(echo $GPG_KEY | grep '^[0-9a-fA-F]\{8\}$') ] not set 
correct (8 digit ID) or
-#    gpg_key_format ${KEY_ID} || \
-#      error_gpg "GPG key '${KEY_ID}' set in '${KEY_SET_NAME}' is not \na 
valid 8 character hex digit string e.g. '012345AB'."
-#  done
-#done
-
-# create enc gpg keys array, for further processing
-GPG_KEYS_ENC=( $(gpg_split_keyset ${GPG_KEY}) $(gpg_split_keyset 
${GPG_KEYS_ENC}) )
+# create array of gpg encr keys, for further processing
+OIFS="$IFS" IFS=$'\n'
+GPG_KEYS_ENC_ARRAY=( $( gpg_split_keyset2 ${GPG_KEY},${GPG_KEYS_ENC} ) )
+IFS="$OIFS"
 
 # check gpg encr public keys availability
-for (( i = 0 ; i < ${#GPG_KEYS_ENC[@]} ; i++ )); do
-  KEY_ID=${GPG_KEYS_ENC[$i]}
+for (( i = 0 ; i < ${#GPG_KEYS_ENC_ARRAY[@]} ; i++ )); do
+  KEY_ID="${GPG_KEYS_ENC_ARRAY[$i]}"
   # test availability, try to import, retest
-  if ! gpg_pub_avail ${KEY_ID}; then
+  if ! gpg_pub_avail "${KEY_ID}"; then
     echo "Encryption public key '${KEY_ID}' not found."
     gpg_import "${KEY_ID}" PUB
-    gpg_key_cache RESET ${KEY_ID}
-    gpg_pub_avail ${KEY_ID} || error_gpg_key "${KEY_ID}" "Public"
+    gpg_key_cache RESET "${KEY_ID}"
+    gpg_pub_avail "${KEY_ID}" || error_gpg_key "${KEY_ID}" "Public"
   fi
 done
 
@@ -1703,19 +1816,19 @@
   echo "Signing disabled per configuration."
 # try first key, if one set
 elif ! var_isset 'GPG_KEY_SIGN'; then
-  KEY_ID=${GPG_KEYS_ENC[0]}
+  KEY_ID="${GPG_KEYS_ENC_ARRAY[0]}"
   if [ -z "${KEY_ID}" ]; then
     echo "Signing disabled. Not GPG_KEY entries in config."
     GPG_KEY_SIGN='disabled'
   else  
     # use avail OR try import OR fail
     if gpg_sec_avail "${KEY_ID}"; then
-      GPG_KEY_SIGN=${KEY_ID}
+      GPG_KEY_SIGN="${KEY_ID}"
     else
       gpg_import "${KEY_ID}" SEC
-      gpg_key_cache RESET ${KEY_ID}
+      gpg_key_cache RESET "${KEY_ID}"
       if gpg_sec_avail "${KEY_ID}"; then
-        GPG_KEY_SIGN=${KEY_ID}
+        GPG_KEY_SIGN="${KEY_ID}"
       fi
     fi
 
@@ -1728,14 +1841,12 @@
     fi
   fi
 else
-  KEY_ID=${GPG_KEY_SIGN}
-  if ! gpg_sec_avail ${KEY_ID}; then
+  KEY_ID="${GPG_KEY_SIGN}"
+  if ! gpg_sec_avail "${KEY_ID}"; then
     inform "Secret signing key defined in setting GPG_KEY_SIGN='${KEY_ID}' not 
found.\nTry to import."
     gpg_import "${KEY_ID}" SEC
-    gpg_key_cache RESET ${KEY_ID}
-    gpg_sec_avail ${KEY_ID} || error_gpg_key "${KEY_ID}" "Private"
-  else
-    echo "Use configured key '${KEY_ID}' as signing key."
+    gpg_key_cache RESET "${KEY_ID}"
+    gpg_sec_avail "${KEY_ID}" || error_gpg_key "${KEY_ID}" "Private"
   fi
 fi
 
@@ -1756,14 +1867,15 @@
 This is unfortunately impossible. For details see duplicity manpage, 
 section 'A Note On Symmetric Encryption And Signing'.
 
-Tip: Separate signing keys may have empty passwords e.g. GPG_PW_SIGN=''."
+Tip: Separate signing keys may have empty passwords e.g. GPG_PW_SIGN=''.
+Tip2: Use gpg-agent."
 fi
 # key enc can deal without, but might profit from gpg-agent
 # if GPG_PW is not set alltogether
 # if signing key is different from first (main) enc key (we can only pipe one 
pass into gpg)
 if ! gpg_symmetric && \
    ( ! var_isset GPG_PW || \
-     ( gpg_signing && ! var_isset GPG_PW_SIGN && [ "$GPG_KEY_SIGN" != 
"${GPG_KEYS_ENC[0]}" ] ) ); then
+     ( gpg_signing && ! var_isset GPG_PW_SIGN && [ "$GPG_KEY_SIGN" != 
"${GPG_KEYS_ENC_ARRAY[0]}" ] ) ); then
 
   GPG_AGENT_ERR=$(gpg_agent_avail ; echo $?)
   if [ "$GPG_AGENT_ERR" -eq 1 ]; then
@@ -1780,34 +1892,30 @@
 fi
 
 # config plausibility check - SPACE ###########################################
-# is tmp writeable
-# is tmp big enough
-if [ ! -d "$TEMP_DIR" ]; then
+
+# is tmp is a folder
+CMD_MSG="Checking TEMP_DIR '${TEMP_DIR}' is a folder"
+run_cmd test -d "$TEMP_DIR"
+if [ "$?" != "0" ]; then
     error "Temporary file space '$TEMP_DIR' is not a directory."
-elif [ ! -w "$TEMP_DIR" ]; then
+fi    
+# is tmp writeable
+CMD_MSG="Checking TEMP_DIR '${TEMP_DIR}' is writable"
+run_cmd test -w "$TEMP_DIR"
+if [ "$?" != "0" ]; then
     error "Temporary file space '$TEMP_DIR' not writable."
 fi
 
+
 # get volsize, default duplicity volume size is 25MB since v0.5.07
 VOLSIZE=${VOLSIZE:-25}
-# get free temp space
-TEMP_FREE="$(df $TEMP_DIR 2>/dev/null | awk 'END{pos=(NF-2);if(pos>0) print 
$pos;}')"
-# check for free space or FAIL
-if [ "$((${TEMP_FREE:-0}-${VOLSIZE:-0}*1024))" -lt 0 ]; then
-    error "Temporary file space '$TEMP_DIR' free space is smaller 
($((TEMP_FREE/1024))MB)
-than one duplicity volume (${VOLSIZE}MB).
-    
-  Hint: Free space or change TEMP_DIR setting."
-fi
+# double if asynch is on
+echo $@ $DUPL_PARAMS | grep -q -e '--asynchronous-upload' && FACTOR=2 || 
FACTOR=1
+
+# TODO: check for enough (async= upload space and WARN only
+#       use function tmp_space 
+#echo TODO: reimplent tmp space check
 
-# check for enough async upload space and WARN only
-if [ $((${TEMP_FREE:-0}-2*${VOLSIZE:-0}*1024)) -lt 0 ]; then
-    warning "Temporary file space '$TEMP_DIR' free space is smaller 
($((TEMP_FREE/1024))MB)
-than two duplicity volumes (2x${VOLSIZE}MB). This can lead to problems when 
-using the --asynchronous-upload option.
-    
-  Hint: Free space or change TEMP_DIR setting."
-fi
 
 # test - GPG SANITY 
#####################################################################
 # if encryption is disabled, skip this whole section
@@ -1825,32 +1933,34 @@
 
 # signing enabled?
 if gpg_signing; then
-  CMD_PARAM_SIGN="--sign --default-key ${GPG_KEY_SIGN}"
-  CMD_MSG_SIGN="Sign with ${GPG_KEY_SIGN}"
+  CMD_PARAM_SIGN="--sign --default-key $(qw ${GPG_KEY_SIGN})"
+  CMD_MSG_SIGN="Sign with '${GPG_KEY_SIGN}'"
 fi
 
 # using keys
-if [ ${#GPG_KEYS_ENC[@]} -gt 0 ]; then
+if [ ${#GPG_KEYS_ENC_ARRAY[@]} -gt 0 ]; then
 
-  for KEY_ID in ${GPG_KEYS_ENC[@]}; do
-    CMD_PARAMS="$CMD_PARAMS -r ${KEY_ID}"
+  for KEY_ID in "${GPG_KEYS_ENC_ARRAY[@]}"; do
+    CMD_PARAMS="$CMD_PARAMS -r $(qw ${KEY_ID})"
   done
   # check encrypting
-  CMD_MSG="Test - Encrypt to $(gpg_join_keyset 
${GPG_KEYS_ENC[@]})${CMD_MSG_SIGN:+ & $CMD_MSG_SIGN}"
-  run_cmd $(gpg_pass_pipein GPG_PW_SIGN GPG_PW) $GPG $CMD_PARAM_SIGN 
$(gpg_param_passwd GPG_PW_SIGN GPG_PW) $CMD_PARAMS $GPG_USEAGENT --status-fd 1 
$GPG_OPTS -o "${GPG_TEST}_ENC" -e "$ME_LONG"
+  CMD_MSG="Test - Encrypt to '$(join "','" 
"${GPG_KEYS_ENC_ARRAY[@]}")'${CMD_MSG_SIGN:+ & $CMD_MSG_SIGN}"
+  run_cmd $(gpg_pass_pipein GPG_PW_SIGN GPG_PW) gpg $CMD_PARAM_SIGN 
$(gpg_param_passwd GPG_PW_SIGN GPG_PW) $CMD_PARAMS $GPG_USEAGENT --status-fd 1 
$GPG_OPTS -o "${GPG_TEST}_ENC" -e "$ME_LONG"
+  CMD_ERR=$?
 
   if [ "$CMD_ERR" != "0" ]; then 
     KEY_NOTRUST=$(echo "$CMD_OUT"|awk '/^\[GNUPG:\] INV_RECP 10/ { print $4 }')
     [ -n "$KEY_NOTRUST" ] && HINT="Key '${KEY_NOTRUST}' seems to be untrusted. 
If you really trust this key try to
-  'gpg --edit-key $KEY_NOTRUST' and raise the trust level to ultimate. If you
+  'gpg --edit-key "$KEY_NOTRUST"' and raise the trust level to ultimate. If you
   can trust all of your keys set GPG_OPTS='--trust-model always' in conf file."
     error_gpg_test "Encryption failed (Code $CMD_ERR).${CMD_OUT:+\n$CMD_OUT}" 
"$HINT"
   fi
 
   # check decrypting
   CMD_MSG="Test - Decrypt"
-  gpg_key_decryptable || CMD_DISABLED="No matching secret key or GPG_PW not 
set."
-  run_cmd $(gpg_pass_pipein GPG_PW) "$GPG" $(gpg_param_passwd GPG_PW) 
$GPG_OPTS -o "${GPG_TEST}_DEC" $GPG_USEAGENT -d "${GPG_TEST}_ENC"
+  gpg_key_decryptable || CMD_DISABLED="No matching secret key available."
+  run_cmd $(gpg_pass_pipein GPG_PW) gpg $(gpg_param_passwd GPG_PW) $GPG_OPTS 
-o "${GPG_TEST}_DEC" $GPG_USEAGENT -d "${GPG_TEST}_ENC"
+  CMD_ERR=$?
 
   if [ "$CMD_ERR" != "0" ]; then 
     error_gpg_test "Decryption failed.${CMD_OUT:+\n$CMD_OUT}"
@@ -1860,14 +1970,16 @@
 else
   # check encrypting
   CMD_MSG="Test - Encryption with passphrase${CMD_MSG_SIGN:+ & $CMD_MSG_SIGN}"
-  run_cmd $(gpg_pass_pipein GPG_PW) "$GPG" $GPG_OPTS $CMD_PARAM_SIGN 
--passphrase-fd 0 -o "${GPG_TEST}_ENC" --batch -c "$ME_LONG"
+  run_cmd $(gpg_pass_pipein GPG_PW) gpg $GPG_OPTS $CMD_PARAM_SIGN 
--passphrase-fd 0 -o "${GPG_TEST}_ENC" --batch -c "$ME_LONG"
+  CMD_ERR=$?
   if [ "$CMD_ERR" != "0" ]; then 
     error_gpg_test "Encryption failed.${CMD_OUT:+\n$CMD_OUT}"
   fi
 
   # check decrypting
   CMD_MSG="Test - Decryption with passphrase"
-  run_cmd $(gpg_pass_pipein GPG_PW) "$GPG" $GPG_OPTS --passphrase-fd 0 -o 
"${GPG_TEST}_DEC" --batch -d "${GPG_TEST}_ENC"
+  run_cmd $(gpg_pass_pipein GPG_PW) gpg $GPG_OPTS --passphrase-fd 0 -o 
"${GPG_TEST}_DEC" --batch -d "${GPG_TEST}_ENC"
+  CMD_ERR=$?
   if [ "$CMD_ERR" != "0" ]; then 
     error_gpg_test "Decryption failed.${CMD_OUT:+\n$CMD_OUT}"
   fi
@@ -1877,7 +1989,7 @@
 CMD_MSG="Test - Compare"
 [ -r "${GPG_TEST}_DEC" ] || CMD_DISABLED="File not found. Nothing to compare."
 run_cmd "test \"\$(cat '$ME_LONG')\" = \"\$(cat '${GPG_TEST}_DEC')\""
-
+CMD_ERR=$?
 if [ "$CMD_ERR" = "0" ]; then 
   cleanup_gpgtest
 else
@@ -1893,7 +2005,7 @@
 [ -f "$EXCLUDE" ] || touch "$EXCLUDE"
 
 # export only used keys, if bkp not already exists 
######################################
-gpg_export_if_needed "${GPG_KEYS_ENC[@]} $(gpg_signing && echo $GPG_KEY_SIGN)"
+gpg_export_if_needed "${GPG_KEYS_ENC_ARRAY[@]}" "$(gpg_signing && echo 
$GPG_KEY_SIGN)"
 
 
 # command execution 
#####################################################################
@@ -1907,102 +2019,71 @@
 var_isset 'TARGET_USER' && TARGET_URL_USER="$TARGET_USER"
 var_isset 'TARGET_PASS' && TARGET_URL_PASS="$TARGET_PASS"
 
-# build target backend data depending on protocol
+# issue some warnings
 case "$(tolower "${TARGET_URL_PROT%%:*}")" in
-  's3'|'s3+http')
-    BACKEND_PARAMS="AWS_ACCESS_KEY_ID='${TARGET_URL_USER}' 
AWS_SECRET_ACCESS_KEY='${TARGET_URL_PASS}'"
-    BACKEND_URL="${TARGET_URL_PROT}${TARGET_URL_HOSTPATH}"
-    ;;
-  'gs')
-    BACKEND_PARAMS="GS_ACCESS_KEY_ID='${TARGET_URL_USER}' 
GS_SECRET_ACCESS_KEY='${TARGET_URL_PASS}'"
-    BACKEND_URL="${TARGET_URL_PROT}${TARGET_URL_HOSTPATH}"
-    ;;
   'cf+http')
-    # respect potentially set cloudfile env vars
-    var_isset 'CLOUDFILES_USERNAME' && TARGET_URL_USER="$CLOUDFILES_USERNAME"
-    var_isset 'CLOUDFILES_APIKEY' && TARGET_URL_PASS="$CLOUDFILES_APIKEY"
-    # add them to duplicity params
-    var_isset 'TARGET_URL_USER' && \
-      BACKEND_PARAMS="CLOUDFILES_USERNAME=$(qw "${TARGET_URL_USER}")"
-    var_isset 'TARGET_URL_PASS' && \
-      BACKEND_PARAMS="$BACKEND_PARAMS CLOUDFILES_APIKEY=$(qw 
"${TARGET_URL_PASS}")"
-    BACKEND_URL="${TARGET_URL_PROT}${TARGET_URL_HOSTPATH}"
     # info on missing AUTH_URL
     if ! var_isset 'CLOUDFILES_AUTHURL'; then
-      echo -e "INFO: No CLOUDFILES_AUTHURL defined (in conf).\n      Will use 
default from python-cloudfiles (probably rackspace)."
-    else
-      BACKEND_PARAMS="$BACKEND_PARAMS CLOUDFILES_AUTHURL=$(qw 
"${CLOUDFILES_AUTHURL}")"
+      inform "No CLOUDFILES_AUTHURL exported (in conf).
+Will use default which is probably rackspace."
     fi
     ;;
-   'file'|'tahoe'|'dpbx')
-     BACKEND_URL="${TARGET_URL_PROT}${TARGET_URL_HOSTPATH}"
-     ;;
    'swift')
-     BACKEND_URL="${TARGET_URL_PROT}${TARGET_URL_HOSTPATH}"
-     # respect possibly set swift env vars
-     var_isset 'SWIFT_USERNAME' && TARGET_URL_USER="$SWIFT_USERNAME"
-     var_isset 'SWIFT_PASSWORD' && TARGET_URL_PASS="$SWIFT_PASSWORD"
-     # add them to duplicity params like with cloudfile to make it look 
standardized
-     var_isset 'TARGET_URL_USER' && \
-       BACKEND_PARAMS="$BACKEND_PARAMS SWIFT_USERNAME=$(qw 
"${TARGET_URL_USER}")"
-     var_isset 'SWIFT_AUTHURL' && \
-       BACKEND_PARAMS="$BACKEND_PARAMS SWIFT_AUTHURL=$(qw "${SWIFT_AUTHURL}")"
-     ( var_isset 'TARGET_URL_USER' && ! var_isset 'SWIFT_AUTHURL' ) &&\
+    # info on possibly missing AUTH_URL
+       var_isset 'SWIFT_AUTHURL' ||\
        warning "\
-Swift will probably fail because the conf var SWIFT_AUTHURL was not defined!"
-     var_isset 'SWIFT_AUTHVERSION' && \
-       BACKEND_PARAMS="$BACKEND_PARAMS SWIFT_AUTHVERSION=$(qw 
"${SWIFT_AUTHVERSION}")"
-     var_isset 'TARGET_URL_PASS' && \
-       BACKEND_PARAMS="$BACKEND_PARAMS SWIFT_PASSWORD=$(qw 
"${TARGET_URL_PASS}")"
-     ;;
+Swift will probably fail because the conf var SWIFT_AUTHURL was not exported!"
+    ;;
   'rsync')
     # everything in url (this backend does not support pass in env var)
     # this is obsolete from version 0.6.10 (buggy), hopefully fixed in 0.6.11
     # print warning older version is detected
-    var_isset 'TARGET_URL_USER' && BACKEND_CREDS="$(url_encode 
"${TARGET_URL_USER}")"
-    if duplicity_version_lt 610; then
+    duplicity_version_lt 610 &&
       warning "\
 Duplicity version '$DUPL_VERSION' does not support providing the password as 
 env var for rsync backend. For security reasons you should consider to 
 update to a version greater than '0.6.10' of duplicity."
-      var_isset 'TARGET_URL_PASS' && 
BACKEND_CREDS="${BACKEND_CREDS}:$(url_encode "${TARGET_URL_PASS}")"
-    else
-      var_isset 'TARGET_URL_PASS' && BACKEND_PARAMS="FTP_PASSWORD=$(qw 
"${TARGET_URL_PASS}")"
-    fi
-    var_isset 'BACKEND_CREDS' && BACKEND_CREDS="${BACKEND_CREDS}@"
-    BACKEND_URL="${TARGET_URL_PROT}${BACKEND_CREDS}${TARGET_URL_HOSTPATH}"
+    ;;
+esac
+
+
+# for all protocols we put username in url and pass into env var 
+# for sec�rity reasons, we url_encode username to protect special chars
+# first sortout backends with special ways to handle password
+case "$(tolower "${TARGET_URL_PROT%%:*}")" in
+  'imap'|'imaps')
+    var_isset 'TARGET_URL_PASS' && BACKEND_PARAMS="IMAP_PASSWORD=$(qw 
"${TARGET_URL_PASS}")"
     ;;
   *)
-    # for all other protocols we put username in url and pass into env var 
-    # for sec�rity reasons, we url_encode username to protect special chars
-    var_isset 'TARGET_URL_USER' && 
-      BACKEND_CREDS="$(url_encode "${TARGET_URL_USER}")@"
-    # sortout backends with special ways to handle password
+    # add needed param for ssh backend
     case "$(tolower "${TARGET_URL_PROT%%:*}")" in
-      'imap'|'imaps')
-        var_isset 'TARGET_URL_PASS' && BACKEND_PARAMS="IMAP_PASSWORD=$(qw 
"${TARGET_URL_PASS}")"
-      ;;
       'ssh'|'sftp'|'scp')
-        # ssh backend wants to be told that theres a pass to use
+        # ssh backend wants to be told that there is a pass to use
         var_isset 'TARGET_URL_PASS' && \
           DUPL_PARAMS="$DUPL_PARAMS --ssh-askpass" && \
           BACKEND_PARAMS="FTP_PASSWORD=$(qw "${TARGET_URL_PASS}")"
-      ;;
-      *)
-        # rest uses FTP_PASS var
-        var_isset 'TARGET_URL_PASS' && \
-          BACKEND_PARAMS="FTP_PASSWORD=$(qw "${TARGET_URL_PASS}")"
-      ;;
+        ;;
     esac
-    BACKEND_URL="${TARGET_URL_PROT}${BACKEND_CREDS}${TARGET_URL_HOSTPATH}"
+    # rest uses FTP_PASS var
+    var_isset 'TARGET_URL_PASS' && \
+      BACKEND_PARAMS="FTP_PASSWORD=$(qw "${TARGET_URL_PASS}")"
     ;;
 esac
+# insert url encoded username into target url if needed
+if var_isset 'TARGET_URL_USER'; then
+  BACKEND_URL="${TARGET_URL_PROT}$(url_encode 
"${TARGET_URL_USER}")@${TARGET_URL_HOSTPATH}"
+else
+  BACKEND_URL="$TARGET"
+fi
+
 
 # protect eval from special chars in url (e.g. open ')' in password, 
 # spaces in path, quotes) happens above in duplify() via quotewrap()
 SOURCE="$SOURCE"
 BACKEND_URL="$BACKEND_URL"
 EXCLUDE="$EXCLUDE"
+# since 0.7.03 --exclude-globbing-filelist is deprecated
+EXCLUDE_PARAM="--exclude$(duplicity_version_lt 703 && echo 
-globbing)-filelist" 
 
 # replace magic separators to condition command equivalents (+=and,-=or)
 cmds=$(awk -v cmds="$cmds" "BEGIN{ gsub(/\+/,\"_and_\",cmds); 
gsub(/\-/,\"_or_\",cmds); print cmds}")
@@ -2017,28 +2098,42 @@
 # raise index in cmd array for pre/post param
 var_isset 'CMD_NO' && CMD_NO=$((++CMD_NO)) || CMD_NO=0
 
-# get prev/nextcmd vars
-nextno=$(($CMD_NO+1))
-[ "$nextno" -lt "${#CMDS[@]}" ] && CMD_NEXT=${CMDS[$nextno]} || CMD_NEXT='END'
-prevno=$(($CMD_NO-1))
-[ "$prevno" -ge 0 ] && CMD_PREV=${CMDS[$prevno]} || CMD_PREV='START'
-
 # deal with condition "commands"
+unset SKIP_NOW
 if var_isset 'CMD_SKIP' && [ $CMD_SKIP -gt 0 ]; then
   echo -e "\n--- Skipping command $(toupper $cmd) ! ---"
   CMD_SKIP=$(($CMD_SKIP - 1))
-  continue
+  SKIP_NOW="yes"
 elif [ "$cmd" == 'and' ] && [ "$CMD_ERR" -ne "0" ]; then
   CMD_SKIP=1
-  continue
+  SKIP_NOW="yes"
 elif [ "$cmd" == 'or' ] && [ "$CMD_ERR" -eq "0" ]; then
   CMD_SKIP=1
-  continue
+  SKIP_NOW="yes"
 elif [ "$cmd" == 'and' ] || [ "$cmd" == 'or' ]; then
   unset 'CMD_SKIP';
+  SKIP_NOW="yes"
+fi
+
+# sum up how many commands we skip and actually skip
+if [ -n "$SKIP_NOW" ]; then
+  CMD_SKIPPED=$((${CMD_SKIPPED-0} + 1))
   continue
 fi
 
+# get prev/nextcmd vars
+nextno=$(($CMD_NO+1))
+[ "$nextno" -lt "${#CMDS[@]}" ] && CMD_NEXT=${CMDS[$nextno]} || CMD_NEXT='END'
+# get previous command minus skipped commands
+prevno=$(( $CMD_NO - ${CMD_SKIPPED-0} - 1 )); unset CMD_SKIPPED
+[ "$prevno" -ge 0 ] && CMD_PREV=${CMDS[$prevno]} || CMD_PREV='START'
+
+# export some useful env vars for external scripts/programs to use
+export CONFDIR SOURCE TARGET_URL_PROT TARGET_URL_HOSTPATH \
+       TARGET_URL_USER TARGET_URL_PASS \
+       GPG_KEYS_ENC=$(join "\n" "${GPG_KEYS_ENC_ARRAY[@]}") GPG_KEY_SIGN \
+       GPG_PW CMD_PREV CMD_NEXT CMD_ERR
+
 # save start time
 RUN_START=$(date_fix %s)$(nsecs)
 # user info
@@ -2055,25 +2150,37 @@
     ( run_script "$script" )
     ;;
   'bkp')
-    duplify -- "${dupl_opts[@]}" --exclude-globbing-filelist "$EXCLUDE" \
+    duplify -- "${dupl_opts[@]}" $EXCLUDE_PARAM "$EXCLUDE" \
           "$SOURCE" "$BACKEND_URL"
     ;;
   'incr')
-    duplify incr -- "${dupl_opts[@]}" --exclude-globbing-filelist "$EXCLUDE" \
+    duplify incr -- "${dupl_opts[@]}" $EXCLUDE_PARAM "$EXCLUDE" \
           "$SOURCE" "$BACKEND_URL"
     ;;
   'full')
-    duplify full -- "${dupl_opts[@]}" --exclude-globbing-filelist "$EXCLUDE" \
+    duplify full -- "${dupl_opts[@]}" $EXCLUDE_PARAM "$EXCLUDE" \
           "$SOURCE" "$BACKEND_URL"
     ;;
   'verify')
-    duplify verify -- "${dupl_opts[@]}" --exclude-globbing-filelist "$EXCLUDE" 
\
+    TIME="${ftpl_pars[0]:+"-t ${ftpl_pars[0]}"}"
+    duplify verify -- $TIME "${dupl_opts[@]}" $EXCLUDE_PARAM "$EXCLUDE" \
           "$BACKEND_URL" "$SOURCE"
     ;;
+  'verifypath')
+    TIME="${ftpl_pars[2]:+"-t ${ftpl_pars[2]}"}"
+    IN_PATH="${ftpl_pars[0]}"; OUT_PATH="${ftpl_pars[1]}"; 
+    ( [ -z "$IN_PATH" ] || [ -z "$OUT_PATH" ] ) && error "  Missing parameter 
<rel_bkp_path> or <local_path> for verifyPath.
+  
+  Hint: 
+    Syntax is -> $ME <profile> verifyPath <rel_bkp_path> <local_path> [<age>]"
+
+    duplify verify -- $TIME "${dupl_opts[@]}" $EXCLUDE_PARAM "$EXCLUDE" \
+          --file-to-restore "$IN_PATH" "$BACKEND_URL" "$OUT_PATH"
+    ;;
   'list')
     # time param exists since 0.5.10+
-    TIME="${ftpl_pars[0]:-now}"
-    duplify list-current-files -- -t "$TIME" "${dupl_opts[@]}" "$BACKEND_URL"
+    TIME="${ftpl_pars[0]:+"-t ${ftpl_pars[0]}"}"
+    duplify list-current-files -- $TIME "${dupl_opts[@]}" "$BACKEND_URL"
     ;;
   'cleanup')
     duplify cleanup -- "${dupl_opts[@]}" "$BACKEND_URL"
@@ -2129,7 +2236,8 @@
 esac
 
 CMD_ERR=$?
-RUN_END=$(date_fix %s)$(nsecs) ; RUNTIME=$(( $RUN_END - $RUN_START ))
+RUN_END=$(date_fix %s)$(nsecs)
+RUNTIME=$(( $RUN_END - $RUN_START ))
 
 # print message on error; set error code
 if [ "$CMD_ERR" -ne 0 ]; then


Reply via email to