re-mark 1.29b-2 as not yet uploaded (merge madness!)
[debian/tar] / scripts / restore.in
1 #! /bin/sh
2 # Restore backups.
3
4 # Copyright 2004, 2006, 2013-2014, 2016 Free Software Foundation, Inc.
5
6 # This file is part of GNU tar.
7
8 # GNU tar is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
12
13 # GNU tar is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17
18 # You should have received a copy of the GNU General Public License
19 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 # Load library routines
22 SYSCONFDIR=${SYSCONFDIR-@sysconfdir@}
23 . ${LIBDIR-@libexecdir@}/backup.sh
24
25 usage() {
26         cat - <<EOF
27 usage: $PROGNAME [OPTIONS] [PATTERN [PATTERN...]]
28 Options are:
29
30    -a, --all               Restore all filesystems.
31    -l, --level=LEVEL       Start restoring from the given backup LEVEL
32                            (default $DUMP_LEVEL).
33    -v, --verbose[=LEVEL]   Set verbosity level. Default 100.
34
35 Informational options:
36    -h, --help              Display this help message.
37    -V, --version           Display program version.
38
39 Send bug reports to @PACKAGE_BUGREPORT@.
40 EOF
41 }
42
43 unset PATTERN
44 DUMP_LEVEL=0
45 CMDLINE="$0 $@"
46
47 for opt
48 do
49   if [ -z "$prev" ]; then
50       option=$opt
51       optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
52   else
53       option="${prev}=$opt"
54       prev=""
55       optarg=$opt
56   fi
57   case $option in
58   -a|--a|--al|--all)
59          RESTORE_ALL=1
60          ;;
61   --l=*|--le=*|--lev=*|--leve=*|--level=*)
62          DUMP_LEVEL=$optarg
63          ;;
64   -l?*)  DUMP_LEVEL=`expr $option : '-l\(.*\)'`;;
65   -l|--l|--le|--lev|--leve|--level)
66          prev=--level
67          ;;
68   --verb=*|--verbo=*|--verbos=*|--verbose=*)
69          VERBOSE=$optarg
70          ;;
71   -v|--verb|--verbo|--verbos|--verbose)
72          VERBOSE=100
73          ;;
74   -v*)   VERBOSE=`expr $option : '-v\(.*\)'`;;
75   -V|--v|--ve|--ver|--vers|--versi|--versio|--version)
76          echo "restore (@PACKAGE_NAME@) @VERSION@"
77          license
78          exit;;
79   -h|--h|--he|--hel|--help)
80          usage
81          exit;;
82   -*) bailout "Unknown option $opt. Try $PROGNAME --help for more info.";;
83   *)  if [ -z "$PATTERN" ]; then
84          PATTERN=$opt
85       else
86          PATTERN="$PATTERN|$opt"
87       fi
88       ;;
89   esac
90 done
91
92 if [ -z "$RESTORE_ALL" ]; then
93         if [ -z "$PATTERN" ]; then
94                 usage
95                 exit;
96         fi
97 fi
98
99 init_restore
100 cat > $LOGFILE <<EOF
101 This file contains any messages produced by $PROGNAME.
102
103 It was created by GNU $PROGNAME, from  @PACKAGE@ (@VERSION@).
104 Invocation command line was
105
106   \$ $CMDLINE
107
108 EOF
109
110 restore_fs()
111 {
112     fs="`echo \"${1}\" | sed -e 's/^.*://'`"
113     fs=`root_fs $fs`
114     fsname="`echo \"${1}\" | sed -e 's/\//:/g'`"
115     remotehost="`expr \"${1}\" : '\([^/][^/]*\):.*'`"
116     if [ -z "$remotehost" ]; then
117         remotehost=$localhost
118     fi
119     message 10 "fs=$fs"
120     message 10 "fsname=$fsname"
121     message 10 "remotehost=$remotehost"
122
123     LOGPAT="`level_log_name ${fsname} '[0-9]'`"
124     PREFIX="`level_log_name ${fsname} ''`"
125     message 10 LOGPAT=$LOGPAT
126     message 10 PREFIX=$PREFIX
127     LEVELS=`remote_run "${remotehost}" ls $LOGPAT |
128       sed "s,$PREFIX,," | sort -n`
129     message 10 "LEVELS=$LEVELS"
130
131     echo "Starting restore of ${1} at level $DUMP_LEVEL."
132     for level in $LEVELS
133     do
134       if [ $level -lt $DUMP_LEVEL ]; then
135           message 10 "Skipping level $level"
136           continue;
137       fi
138       message 10 "Restoring level $level"
139
140       DATE=`get_dump_time $level`
141       FILE="`level_log_name ${fsname} ${level}`"
142       message 10 "FILE=$FILE"
143
144       LABEL="`print_level $level` backup of ${fs} on ${remotehost} at ${DATE}"
145       ${RESTORE_BEGIN-:} $level $remotehost $fs $fsname
146       backup_host ${remotehost} \
147                   "--listed=\"$FILE\"" \
148                   "--label=\"$LABEL\"" \
149                   -C $fs
150       ${RESTORE_END-:} $level $remotehost $fs $fsname
151     done
152 }
153
154 restore_files()
155 {
156     LOGPAT="`level_log_name MISC '[0-9]'`"
157     PREFIX="`level_log_name MISC ''`"
158     message 10 LOGPAT=$LOGPAT
159     message 10 PREFIX=$PREFIX
160     LEVELS=`remote_run "${localhost}" ls $LOGPAT | sed "s,$PREFIX,," | sort -n`
161     message 10 "LEVELS=$LEVELS"
162
163     echo "Starting restore of miscellaneous files at level $DUMP_LEVEL."
164     for level in $LEVELS
165     do
166       if [ $level -lt $DUMP_LEVEL ]; then
167           message 10 "Skipping level $level"
168           continue;
169       fi
170       message 10 "Restoring level $level"
171
172       DATE=`get_dump_time $level`
173       FILE="`level_log_name MISC ${level}`"
174       message 10 "FILE=$FILE"
175
176       LABEL="`print_level $level` backup of miscellaneous files at ${DATE}"
177       ${RESTORE_BEGIN-:} $level $localhost MISC MISC
178       backup_host ${localhost} \
179                   "--listed=\"$FILE\"" \
180                   "--label=\"$LABEL\"" \
181                   -C ${ROOT_FS-/} $@
182       ${RESTORE_END-:} $level $localhost MISC MISC
183     done
184 }
185
186 # Operation Overwiew:
187 #
188 # 1. Determine the time of the last backup
189 # 2. Create list of incremental listings to process
190 # 3. For each filesystem:
191 #  3.1. Start at the requested dump level (default 0) and proceed up to
192 #       the last available level:
193 #   3.1.1 Deduce the volume label
194 #   3.1.2. Invoke [rsh] tar --listed=FILE --label=LABEL [opts] -xf $TAPE_FILE
195 # 4. End
196
197 (message 1 "Preparing for restore"
198
199 message 1 "processing backup directories"
200
201 for dir in ${BACKUP_DIRS}
202 do
203     message 1 "Processing $dir"
204     case $dir in
205         ${PATTERN-*}) restore_fs $dir;;
206     esac
207 done
208
209 if [ "x${BACKUP_FILES}" != "x" ] ; then
210     message 1 "processing miscellaneous files"
211     if [ -z "$PATTERN" ]; then
212         restore_files
213     else
214         RESTORE_FILES=""
215         for file in ${BACKUP_FILES}
216         do
217           rel_file=`expr $file : '/\(.*\)'`
218           case $file in
219               $PATTERN) if [ -z "$RESTORE_FILES" ]; then
220                            RESTORE_FILES="$rel_file"
221                         else
222                            RESTORE_FILES="$RESTORE_FILES $rel_file"
223                         fi;;
224           esac
225         done
226         [ -z "$RESTORE_FILES" ] || restore_files $RESTORE_FILES
227     fi
228
229 fi) 2>&1 | tee -a "${LOGFILE}"
230
231 # EOF