Imported Upstream version 2.5.1p3
[debian/amanda] / changer-src / chg-disk.sh.in
1 #! @SHELL@
2 #
3 # Amanda, The Advanced Maryland Automatic Network Disk Archiver
4 # Copyright (c) 1991-1999 University of Maryland at College Park
5 # All Rights Reserved.
6 #
7 # Permission to use, copy, modify, distribute, and sell this software and its
8 # documentation for any purpose is hereby granted without fee, provided that
9 # the above copyright notice appear in all copies and that both that
10 # copyright notice and this permission notice appear in supporting
11 # documentation, and that the name of U.M. not be used in advertising or
12 # publicity pertaining to distribution of the software without specific,
13 # written prior permission.  U.M. makes no representations about the
14 # suitability of this software for any purpose.  It is provided "as is"
15 # without express or implied warranty.
16 #
17 # U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 #
24 # Author: Jean-Christian SIMONETTI, System and Network Engineer
25 #                                   Wanadoo Portails
26 #                                   Sophia Antipolis, France
27 #
28 #       This changer script is based on a directory structure like:
29 #       slot_root_dir -|
30 #                      |- info
31 #                      |- data -> slot1
32 #                      |- slot1
33 #                      |- slot2
34 #                      |- ...
35 #                      |- slotn
36 #       where 'slot_root_dir' is the tapedev 'file:xxx' parameter and 'n'
37 #       is the LASTSLOT value of your changerfile config file. If LASTSLOT is
38 #       not defined, the value of the tapecycle parameter is used.
39 #
40 #       To use this driver, just put the line 'tpchanger "chg-disk"' in your
41 #       amanda.conf.
42 #
43 #       Example of use (amanda.conf):
44 #       --- cut here ---
45 #       tapedev  "file:/BACKUP2/slots/"
46 #       rawtapedev "file:/BACKUP2/slots/"
47 #       changerdev "/dev/null"
48 #       changerfile "chg-disk"
49 #       tpchanger "chg-disk"
50 #       changerfile "/usr/local/amanda/etc/changer"
51 #       tapetype HARD-DISK
52 #       define tapetype HARD-DISK {
53 #           length 12000 mbytes
54 #       }
55 #       --- cut here ---
56 #
57 #       Example changerfile (chg-disk.conf):
58 #       --- cut here ---
59 #       LASTSLOT=12
60 #       --- cut here ---
61 #
62 #       The number of slot is equal to your LASTSLOT or tapecycle.
63 #       You must create the slots and data directory.
64 #
65
66
67 prefix=@prefix@
68 exec_prefix=@exec_prefix@
69 sbindir=@sbindir@
70 libexecdir=@libexecdir@
71  
72 PATH=$sbindir:$libexecdir:/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb:/usr/local/bin
73 export PATH
74
75 USE_VERSION_SUFFIXES="@USE_VERSION_SUFFIXES@"
76 if test "$USE_VERSION_SUFFIXES" = "yes"; then
77     SUF="-@VERSION@"
78 else
79     SUF=
80 fi
81
82 MYNAME=$0
83
84 TAPE=`amgetconf$SUF tapedev`
85 if test X"$TAPE" == X""; then
86     echo "<none> tapedev not specified in amanda.conf." 1>&2
87     exit 2
88 fi
89 SLOTDIR=`echo $TAPE | sed 's/^file://'`
90
91 isinteger() {
92             # should be exactly one arg
93         [ $# = 1 ]  || return 1
94             # if arg is null, no expr needed
95         [ "${1}" = '' ] && return 1
96             # expr will return 0 on match
97         expr "$1" : '[0-9][0-9]*$' > /dev/null 2>&1
98 }
99
100 # Need rwx access to the virtual tape itself.
101 if ! test -d $SLOTDIR; then
102     echo "Virtual-tape directory $SLOTDIR does not exist." 1>&2
103     exit 2
104 fi
105 if ! test -w $SLOTDIR; then
106     echo "Virtual-tape directory $SLOTDIR is not writable." 1>&2
107     exit 2
108 fi
109
110
111 # need rwx access to directory of changer file
112 CHANGERFILE=`amgetconf$SUF changerfile`
113 conf_match=`expr "$CHANGERFILE" : .\*\.conf\$`
114 if [ $conf_match -ge 6 ]; then
115         CONFIGFILE=$CHANGERFILE
116         CHANGERFILE=`echo $CHANGERFILE | sed 's/.conf$//g'`
117 else
118         CONFIGFILE=$CHANGERFILE.conf
119 fi
120
121 CFDir=`dirname ${CHANGERFILE}`
122 [ -d ${CFDir} -a -r ${CFDir} -a -w ${CFDir} -a -x ${CFDir} ] ||
123         { echo "$MYNAME: need 'rwx' access to '$CFDir'" 1>&2 ; exit 2 ; }
124
125 # check or create changer metadata files
126 ACCESSFILE=$CHANGERFILE-access
127 [ -f $ACCESSFILE -a -r $ACCESSFILE -a -w $ACCESSFILE ] ||
128         echo 0 > $ACCESSFILE ||
129         { echo "$MYNAME: could not access or create '$ACCESSFILE'" 1>&2 ; exit 2 ; }
130 CLEANFILE=$CHANGERFILE-clean
131 [ -f $CLEANFILE -a -r $CLEANFILE -a -w $CLEANFILE ] ||
132         echo 0 > $CLEANFILE ||
133         { echo "$MYNAME: could not access or create '$CLEANFILE'" 1>&2 ; exit 2 ; }
134 SLOTFILE=$CHANGERFILE-slot
135 [ -f $SLOTFILE -a -r $SLOTFILE -a -w $SLOTFILE ] ||
136         echo 0 > $SLOTFILE ||
137         { echo "$MYNAME: could not access or create '$SLOTFILE'" 1>&2 ; exit 2 ; }
138
139 # read and check metadata
140 ACCESSCOUNT=`cat $ACCESSFILE`
141 isinteger $ACCESSCOUNT || { ACCESSCOUNT=0 ; echo 0 > $ACCESSFILE ; }
142 CLEANCOUNT=`cat $CLEANFILE`
143 isinteger $CLEANCOUNT || { CLEANCOUNT=0 ; echo 0 > $CLEANFILE ; }
144
145 FIRSTSLOT=1
146 LASTSLOT=`amgetconf$SUF tapecycle`
147 if test -r $CONFIGFILE; then
148     . $CONFIGFILE
149 fi
150 CURSLOT=0
151 CLEANSLOT=$LASTSLOT
152 NSLOT=`expr $LASTSLOT - $FIRSTSLOT + 1`
153
154 load() {
155   WHICHSLOT=$1;
156   # unload should have been called, but just in case ...
157   [ -h $SLOTDIR/data ] && unload
158   ln -s $SLOTDIR/slot$WHICHSLOT $SLOTDIR/data
159   echo $WHICHSLOT > $SLOTFILE
160 }
161
162 unload() {
163   rm -f $SLOTDIR/data
164   echo "0" > $SLOTFILE
165 }
166
167 readstatus() {
168   CURSLOT=`cat $SLOTFILE`
169 }
170
171 loadslot() {
172   WHICHSLOT=$1
173
174   TYPE=string   # default if not numeric
175   isinteger $WHICHSLOT && TYPE=digit
176
177   readstatus
178   NEWSLOT=0
179   if [ $WHICHSLOT = "current" ]; then
180     if [ $CURSLOT -le 0 ]; then
181       load $FIRSTSLOT
182       echo "$FIRSTSLOT $TAPE"
183       exit 0
184     else
185       echo "$CURSLOT $TAPE"
186       exit 0
187     fi
188   elif [ $WHICHSLOT = "next" -o $WHICHSLOT = "advance" ]; then
189     NEWSLOT=`expr $CURSLOT + 1`
190     [ $NEWSLOT -gt $LASTSLOT ] && NEWSLOT=$FIRSTSLOT
191   elif [ $WHICHSLOT = "prev" ]; then
192       NEWSLOT=`expr $CURSLOT - 1`
193       [ $NEWSLOT -lt $FIRSTSLOT ] && NEWSLOT=$LASTSLOT
194   elif [ $WHICHSLOT = "first" ]; then
195       NEWSLOT=$FIRSTSLOT
196   elif [ $WHICHSLOT = "last" ]; then
197       NEWSLOT=$LASTSLOT
198   elif [ $TYPE = "digit" ]; then
199     if [ $WHICHSLOT -ge $FIRSTSLOT -a $WHICHSLOT -le $LASTSLOT ]; then
200       NEWSLOT=$WHICHSLOT
201     else
202       echo "$WHICHSLOT illegal slot"
203       exit 1
204     fi
205   elif [ $WHICHSLOT = "clean" ]; then
206     NEWSLOT=$CLEANSLOT
207   else
208     echo "$WHICHSLOT illegal request"
209     exit 1
210   fi
211   if [ $NEWSLOT = $CURSLOT ]; then
212     echo "$CURSLOT $TAPE"
213     exit 0
214   fi
215   if [ $NEWSLOT = $CLEANSLOT ]; then
216     expr ${CLEANCOUNT:=0} + 1 > $CLEANFILE
217     echo 0 > $ACCESSFILE
218   else
219     expr ${ACCESSCOUNT:=0} + 1 > $ACCESSFILE
220     if [ $ACCESSCOUNT -gt $LASTSLOT ]; then
221       $MYNAME -slot clean >/dev/null
222     fi
223   fi
224
225   readstatus
226   if [ $CURSLOT -ne 0 ]; then
227     unload
228   fi
229
230   if [ $WHICHSLOT = "advance" ]; then
231     echo "$NEWSLOT /dev/null"
232     exit 0
233   fi
234   load $NEWSLOT
235   echo "$NEWSLOT $TAPE"
236   exit 0
237 }
238
239 info() {
240   readstatus
241   echo "$CURSLOT $NSLOT 1"
242   exit 0
243 }
244
245 reset() {
246   readstatus
247   [ $CURSLOT -gt 0 ] && unload
248   load $FIRSTSLOT
249   echo "$FIRSTSLOT $tape"
250   exit 0
251 }
252
253 eject() {
254   readstatus
255   if [ $CURSLOT -le 0 ]; then
256     echo "0 Drive was not loaded"
257     exit 1
258   else
259     unload
260     echo $CURSLOT
261     exit 0
262   fi
263 }
264
265
266 while [ $# -ge 1 ];do
267   case $1 in
268     -slot)
269            shift
270            loadslot $*
271            ;;
272     -clean)
273            shift
274            loadslot clean
275            ;;
276     -current)
277            shift
278            loadslot current
279            ;;
280     -next)
281            shift
282            loadslot next
283            ;;
284     -advance)
285            shift
286            loadslot advance
287            ;;
288     -prev)
289            shift
290            loadslot prev
291            ;;
292     -first)
293            shift
294            loadslot first
295            ;;
296     -last)
297            shift
298            loadslot last
299            ;;
300     -info)
301            shift
302            info
303            ;;
304     -reset)
305             shift
306             reset
307             ;;
308     -eject)
309             shift
310             eject
311             ;;
312     *)
313        echo "Unknown option $1"
314        exit 2
315        ;;
316   esac
317 done
318