#!/bin/sh # Copyright (C) 2006-2008 David Mandelberg # use ssh-agent test x"$USING_SSH_AGENT" = x"yes" || USING_SSH_AGENT=yes exec ssh-agent "$0" "$@" BASE="`dirname "$0"`" METARELDIR="metadata" METADIR="$BASE/$METARELDIR" RS="rsync -a" SSH="ssh" QUIET=0 VERBOSE=0 SIMULATE=0 REMOTE=0 NAME="`basename "$0"`" print_help () { printf "$NAME [OPTION...] RESTORE_POINT...\n" printf "\tOPTIONS:\n" printf "\t\t-h | --help: print a help message\n" printf "\t\t-u | --usage: print a usage message\n" printf "\t\t-q | --quiet: print less\n" printf "\t\t-v | --verbose: print more\n" printf "\t\t-s | --simulate: don't actually restore anything\n" printf "\t\t-f | --force: force restore, even if destination files are newer\n" printf "\tRESTORE_POINT:\n" printf "\t\tTYPE:NAME:LOCATION e.g. local:desktop:/home or remote:foo.bar.com:newfoo.bar.com:/srv\n" } print_usage () { printf "$NAME [-h|-u]\n" printf "$NAME [-q|-v|-s] TYPE:NAME:LOCATION [TYPE:NAME:LOCATION...]\n" } msg () { test x"$QUIET" = x0 && echo " * $*" >&2 return 0 } verbose () { test x"$VERBOSE" = x1 && msg "$@" return 0 } error () { echo " * $*" >&2 exit 1 } # echo and run a command run () { msg "$*" test x"$SIMULATE" = x0 && "$@" } run_verbose () { verbose "$*" test x"$SIMULATE" = x0 && "$@" } stop_remote () { test x"$REMOTE" = x1 || return run_verbose ssh-add -D REMOTE=0 } forced_quit () { msg "Quitting..." test $REMOTE = 1 && stop_remote exit 1 } trap forced_quit 1 2 3 6 15 setup_remote () { test x"$REMOTE" = x0 || return REMOTE=1 run_verbose ssh-add } restore () { NAME="$1"; shift FROM="$1"; shift TO="$1"; shift if test -d "$FROM"; then FROM="$FROM/" TO="$TO/" fi msg "Restoring $NAME..." run $RS "$FROM" "$TO" msg "Done restoring $NAME." } get_col () { IN="$1"; shift COLNUM="$1"; shift COLTOT="$1"; shift REGEXP='\(.*\)' for i in `seq 2 $COLTOT`; do REGEXP='\([^:]*\):'"$REGEXP" done printf "%s" "$IN" | sed "s/$REGEXP/"'\'"$COLNUM/" } # parse options TMP="`getopt -o huqvsf -l help,usage,quiet,verbose,simulate,force -n "$NAME" -- "$@"`" eval set -- "$TMP" FORCE=0 while true; do case "$1" in -h|--help) print_help exit ;; -u|--usage) print_usage exit ;; -q|--quiet) QUIET=1 SSH="$SSH -q" RS="$RS -q" shift ;; -v|--verbose) VERBOSE=1 RS="$RS -v --progress" shift ;; -s|--simulate) SIMULATE=1 shift ;; -f|--force) FORCE=1 shift ;; --) shift break ;; *) error "Error parsing options." esac done test x"$FORCE" = x1 || RS="$RS -u" for RSTRPT in "$@"; do case "$RSTRPT" in local:*) restore "`get_col "$RSTRPT" 2 3`" "$BASE/`get_col "$RSTRPT" 2 3``get_col "$RSTRPT" 3 3`" "`get_col "$RSTRPT" 3 3`" ;; remote:*) setup_remote restore "`get_col "$RSTRPT" 2 4`" "$BASE/`get_col "$RSTRPT" 2 4``get_col "$RSTRPT" 4 4`" "`get_col "$RSTRPT" 3 4`:`get_col "$RSTRPT" 4 4`" ;; esac done stop_remote msg "Restore complete!"