commit b34d3795965beeb0a0f716b7b4b0a7a4c59e52cb
parent 1a6fd48def3ed490c5435bfdf4d5317a319479bd
Author: Jaromil <jaromil@dyne.org>
Date: Mon, 14 Feb 2011 15:57:37 +0100
backup function using duplicity
working, but hairy since duplicity continues trying to connect
and password handling is not optimal
Diffstat:
2 files changed, 121 insertions(+), 1 deletion(-)
diff --git a/src/tomb b/src/tomb
@@ -840,6 +840,124 @@ exec_post_hooks() {
fi
}
+get_arg_tomb() {
+# set up variables to be used by caller:
+# tombfile - filename without path
+# tombdir - directory where the tomb is
+# tombname - name of the tomb (filename without extension)
+# the full path is made with $tombdir/$tombfile
+ if [ -z $1 ]; then
+ error "internal: get_arg_tomb called without argument"
+ return 1
+ fi
+
+ # make sure there is a .tomb extension
+ arg=${1%%\.*}.tomb
+
+ if ! [ -r ${arg} ]; then
+ error "file not found: $arg"
+ return 1
+ fi
+
+ tombfile=`basename $arg`
+ tombdir=`dirname $arg`
+
+ file ${tombdir}/${tombfile} | grep -i 'luks encrypted file' 2>&1 >/dev/null
+ if [ $? != 0 ]; then
+ error "$arg is not a valid tomb file, operation aborted"
+ tomb-notify "Not a tomb." "$arg doesn't seems a real tomb."
+ return 1
+ fi
+
+ tombname=${tombfile%%\.*}
+ return 0
+}
+
+backup_tomb() { # FIXME - duplicity asks passwords too often
+ # using duplicity
+ which duplicity > /dev/null
+ if [ $? != 0 ]; then
+ error "duplicity not found, can't operate backup"
+ return 1
+ fi
+ if [ -z $CMD3 ]; then
+ error "backup command needs 2 arguments: tomb and destination url"
+ error "please refer to tomb(1) and duplicity(1) manuals for more information"
+ return 1
+ fi
+
+ # is it a tomb?
+ get_arg_tomb ${CMD2}
+ if [ $? != 0 ]; then
+ error "there is no tomb to backup, operation aborted."
+ return 1
+ fi
+
+ # is it a url?
+ echo "${CMD3}" | grep -i -e '^.*:\/\/.*' 2>&1 > /dev/null
+ if ! [ $? = 0 ]; then
+ error "second argument is not a valid duplicity url."
+ error "read the tomb(1) and duplicity(1) manual for more information"
+ return 1
+ fi
+ bckurl=${CMD3}
+
+ # is it ssh?
+ protocol="`expr substr $bckurl 1 3`"
+ act "backup over protocol $protocol"
+ if [ "$protocol" = "ssh" ]; then
+ act "ssh connection requires a password"
+ FTP_PASSWORD="`exec_as_user tomb askpass $bckurl`"
+ dupopts="--ssh-askpass"
+# TODO verify ssh access before duplicity does
+# since it blocks the thing retrying 5 times and such crap
+# i.e. try ssh true to sshurl="`echo $bckurl | sed -e 's/ssh:\/\///'`"
+# --no-print-statistics
+ fi
+
+ # duplicity works only on directories
+ # so we create a directory in tmpfs and bind the tomb inside it
+ # during backup the encrypted tomb will be exposed
+ # TODO: check that the tomb is not mounted and, if mounted
+ # remount it read-only so it doesn't gets modified during bck
+ bckname=${tombname}.bck
+ mkdir -p /dev/shm/${bckname}
+ if [ $? != 0 ]; then
+ error "cannot generate a temporary backup directory in /dev/shm, operation aborted."
+ return 1
+ fi
+ bcktmpdir=/dev/shm/${bckname}
+ # mmm, maybe we should mount our own tmpfs? we need root anyway for mount -o bind
+ # if we reach to eliminate this mount trick and upload only one file with duplicity
+ # then this function doesn't needs to be root to work.
+ touch ${bcktmpdir}/${tombfile}
+ mount -o bind ${tombdir}/${tombfile} ${bcktmpdir}/${tombfile}
+ bcklast=`exec_as_user duplicity \
+ ${(s: :)dupopts} \
+ collection-status ${bckurl} \
+ | awk '/^Last full backup date:/ { print $5 }'`
+ # we detect if backup already exists or not so we can handle
+ # password prompt (choosing a password for full, inserting for incr)
+ if [ "$bcklast" = "none" ]; then
+ notice "Creating a backup of tomb $tombname on url $bckurl"
+ exec_as_user FTP_PASSWORD="$FTP_PASSWORD" duplicity ${(s: :)dupopts} \
+ full ${bcktmpdir} ${bckurl}
+ else
+ notice "Updating a backup of tomb $tombname on url $bckurl"
+ exec_as_user FTP_PASSWORD="$FTP_PASSWORD" duplicity ${(s: :)dupopts} \
+ incr ${bcktmpdir} ${bckurl}
+ fi
+ unset FTP_PASSWORD
+ if [ $? != 0 ]; then
+ error "duplicity reported error, operation aborted"
+ umount ${bcktmpdir}/${tombfile}
+ return 1
+ fi
+ notice "Operation successful."
+ umount ${bcktmpdir}/${tombfile}
+ return 0
+}
+
umount_tomb() {
if ! [ $1 ]; then
@@ -1029,6 +1147,8 @@ case "$CMD" in
bury) encode_key ${CMD2} ${CMD3} ;;
exhume) decode_key ${CMD2} ;;
+ backup) check_priv ; backup_tomb ${CMD2} ${CMD3} ;;
+
install) check_priv ; install_tomb ;;
askpass) ask_password $CMD2 $CMD3 ;;
diff --git a/src/tomb-status.c b/src/tomb-status.c
@@ -89,7 +89,7 @@ int main(int argc, char **argv) {
// gtk_status_icon_set_name(status_tomb, "tomb");
gtk_status_icon_set_title(status_tomb, "Tomb");
- snprintf(tooltip,255,"Tomb in %s",mountpoint);
+ snprintf(tooltip,255,"%s",mountpoint);
gtk_status_icon_set_tooltip_text (status_tomb, tooltip);
// LEFT click menu