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