Merge commit 'upstream/3.1.0'
[debian/amanda] / changer-src / chg-mcutil.sh
1 #!@SHELL@ 
2 #
3 # Author: Robert Dege
4 #
5 #
6 # version 1.2
7 # -----------
8 # fixed last_cleaned file so that if it doesn't exist, it gets created with current date, not '0,0'
9 # fixed a bug that was reporting the wrong slot # to amcheck
10 #
11 # version 1.1
12 # -----------
13 # amverify was failing when using -slot current.  Fixed exit $code from 1 -> 0.
14 # removed useless $current variables from movetape() function.
15 #
16 #
17 #
18 # Exit Status:
19 # 0 Alles Ok
20 # 1 Illegal Request
21 # 2 Fatal Error
22 #
23
24
25 #
26 # Set Path so that it includes Amanda binaries, and access to tapechanger & drive programs
27 #
28 prefix="@prefix@"
29 exec_prefix="@exec_prefix@"
30 sbindir="@sbindir@"
31 amlibexecdir="@amlibexecdir@"
32 . "${amlibexecdir}/amanda-sh-lib.sh"
33
34 # add sbin and ucb dirs
35 PATH="$PATH:/usr/sbin:/sbin:/usr/ucb"
36 export PATH
37
38
39 #
40 # Load configuration data from the config file
41 #
42
43 ourconf=`amgetconf changerfile`
44 myname=$0
45
46
47 if [ ! -f "$ourconf" ]; then
48         code=2
49         echo `_ 'Command Line ->'` $myname $@
50         echo `_ 'Exit(%s): %s not found as listed in amanda.conf' "$code" "$ourconf"` 1>&2
51         exit $code
52 fi
53
54
55 # grab mcutil info
56 tmpval1=`grep ^mcutil $ourconf | awk -F\  '{print $2}'`
57 tmpval2=`grep ^mcutil $ourconf | awk -F= '{print $2}'`
58 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
59         code=2
60         echo `_ 'Command Line ->'` $myname $@
61         echo `_ 'Exit(%s): mcutil not specified in %s' "$code" "$ourconf"` 1>&2
62         exit $code
63 elif [ -z "$tmpval1" ]; then
64         MCUTIL=$tmpval2
65 else
66         MCUTIL=$tmpval1
67 fi
68
69
70 # grab tape info
71 tmpval1=`grep ^tape $ourconf | awk -F\  '{print $2}'`
72 tmpval2=`grep ^tape $ourconf | awk -F= '{print $2}'`
73 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
74         code=2
75         echo `_ 'Command Line ->'` $myname $@
76         echo `_ 'Exit(%s): tape not specified in %s' "$code" "$ourconf"` 1>&2
77         exit $code
78 elif [ -z "$tmpval1" ]; then
79         tape=$tmpval2
80 else
81         tape=$tmpval1
82 fi
83
84
85 # grab firstslot info
86 tmpval1=`grep ^firstslot $ourconf | awk -F\  '{print $2}'`
87 tmpval2=`grep ^firstslot $ourconf | awk -F= '{print $2}'`
88 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
89         code=2
90         echo `_ 'Command Line ->'` $myname $@
91         echo `_ 'Exit(%s): firstslot not specified in %s' "$code" "$ourconf"` 1>&2
92         exit $code
93 elif [ -z "$tmpval1" ]; then
94         firstslot=$tmpval2
95 else
96         firstslot=$tmpval1
97 fi
98
99
100 # grab lastslot info
101 tmpval1=`grep ^lastslot $ourconf | awk -F\  '{print $2}'`
102 tmpval2=`grep ^lastslot $ourconf | awk -F= '{print $2}'`
103 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
104         code=2
105         echo `_ 'Command Line ->'` $myname $@
106         echo `_ 'Exit(%s): lastslot not specified in %s' "$code" "$ourconf"` 1>&2
107 elif [ -z "$tmpval1" ]; then
108         lastslot=$tmpval2
109 else
110         lastslot=$tmpval1
111 fi
112
113
114 # grab use_cleaning info
115 tmpval1=`grep ^use_cleaning $ourconf | awk -F\  '{print $2}'`
116 tmpval2=`grep ^use_cleaning $ourconf | awk -F= '{print $2}'`
117 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
118         code=2
119         echo `_ 'Command Line ->'` $myname $@
120         echo `_ 'Exit(%s): use_cleaning not specified in %s' "$code" "$ourconf"` 1>&2
121         exit $code
122 elif [ -z "$tmpval1" ]; then
123         use_cleaning=$tmpval2
124 else
125         use_cleaning=$tmpval1
126 fi
127
128
129 # grab cleanslot info
130 tmpval1=`grep ^cleanslot $ourconf | awk -F\  '{print $2}'`
131 tmpval2=`grep ^cleanslot $ourconf | awk -F= '{print $2}'`
132 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
133         code=2
134         echo `_ 'Command Line ->'` $myname $@
135         echo `_ 'Exit(%s): cleanslot not specified in %s' "$code" "$ourconf"` 1>&2
136         exit $code
137 elif [ -z "$tmpval1" ]; then
138         cleanslot=$tmpval2
139 else
140         cleanslot=$tmpval1
141 fi
142
143
144 # grab cleansleep info
145 tmpval1=`grep ^cleansleep $ourconf | awk -F\  '{print $2}'`
146 tmpval2=`grep ^cleansleep $ourconf | awk -F= '{print $2}'`
147 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
148         code=2
149         echo `_ 'Command Line ->'` $myname $@
150         echo `_ 'Exit(%s): cleansleep not specified in %s' "$code" "$ourconf"` 1>&2
151         exit $code
152 elif [ -z "$tmpval1" ]; then
153         cleansleep=$tmpval2
154 else
155         cleansleep=$tmpval1
156 fi
157
158
159 # grab cleanme info
160 tmpval1=`grep ^cleanme $ourconf | awk -F\  '{print $2}'`
161 tmpval2=`grep ^cleanme $ourconf | awk -F= '{print $2}'`
162 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
163         code=2
164         echo `_ 'Command Line ->'` $myname $@
165         echo `_ 'Exit(%s): cleanme not specified in %s' "$code" "$ourconf"` 1>&2
166         exit $code
167 elif [ -z "$tmpval1" ]; then
168         cleanme=$tmpval2
169 else
170         cleanme=$tmpval1
171 fi
172
173
174 # grab cleanfile info
175 tmpval1=`grep ^cleanfile $ourconf | awk -F\  '{print $2}'`
176 tmpval2=`grep ^cleanfile $ourconf | awk -F= '{print $2}'`
177 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
178         code=2
179         echo `_ 'Command Line ->'` $myname $@
180         echo `_ 'Exit(%s): cleanfile not specified in %s' "$code" "$ourconf"` 1>&2
181         exit $code
182 elif [ -z "$tmpval1" ]; then
183         cleanfile=$tmpval2
184 else
185         cleanfile=$tmpval1
186 fi
187
188
189 # grab lastfile info
190 tmpval1=`grep ^lastfile $ourconf | awk -F\  '{print $2}'`
191 tmpval2=`grep ^lastfile $ourconf | awk -F= '{print $2}'`
192 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
193         code=2
194         echo `_ 'Command Line ->'` $myname $@
195         echo `_ 'Exit(%s): lastfile not specified in %s' "$code" "$ourconf"` 1>&2
196         exit $code
197 elif [ -z "$tmpval1" ]; then
198         lastfile=$tmpval2
199 else
200         lastfile=$tmpval1
201 fi
202
203
204 # grab currentslot info
205 tmpval1=`grep ^currentslot $ourconf | awk -F\  '{print $2}'`
206 tmpval2=`grep ^currentslot $ourconf | awk -F= '{print $2}'`
207 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
208         code=2
209         echo `_ 'Command Line ->'` $myname $@
210         echo `_ 'Exit(%s): currentslot not specified in %s' "$code" "$ourconf"` 1>&2
211         exit $code
212 elif [ -z "$tmpval1" ]; then
213         currentslot=$tmpval2
214 else
215         currentslot=$tmpval1
216 fi
217
218
219 # grab logfile info
220 tmpval1=`grep ^logfile $ourconf | awk -F\  '{print $2}'`
221 tmpval2=`grep ^logfile $ourconf | awk -F= '{print $2}'`
222 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
223         code=2
224         echo `_ 'Command Line ->'` $myname $@
225         echo `_ 'Exit(%s): logfile not specified in %s' "$code" "$ourconf"` 1>&2
226         exit $code
227 elif [ -z "$tmpval1" ]; then
228         logfile=$tmpval2
229 else
230         logfile=$tmpval1
231 fi
232
233 [ ! -w $logfile ] && logfile=/dev/null
234
235
236 # grab slot0source info
237 tmpval1=`grep ^slot0source $ourconf | awk -F\  '{print $2}'`
238 tmpval2=`grep ^slot0source $ourconf | awk -F= '{print $2}'`
239 if [ -z "$tmpval1" ] && [ -z "$tmpval2" ]; then
240         code=2
241         echo `_ 'Command Line ->'` $myname $@
242         echo `_ 'Exit(%s): slot0source not specified in %s' "$code" "$ourconf"` 1>&2
243         exit $code
244 elif [ -z "$tmpval1" ]; then
245         slot0source=$tmpval2
246 else
247         slot0source=$tmpval1
248 fi
249
250
251
252 #
253 # Verify currentslot contains a value
254 #
255 if [ ! -f $currentslot ] || [ `cat $currentslot` -lt $firstslot ];then
256    readstatus
257    echo $used > $currentslot
258 fi
259
260 current=`cat $currentslot`
261
262
263 # Start logging to $logfile
264 echo >> $logfile
265 echo >> $logfile
266 echo "==== `date` ====" >> $logfile
267 echo `_ 'Command Line ->'` $myname $@ >> $logfile
268
269
270 #
271 # is Use Cleaning activated?
272 #
273 if [ $use_cleaning -eq 1 ]; then
274    curday=`date +%j`
275    curyear=`date +%Y`
276
277    [ ! -f $cleanfile ] && echo 0 > $cleanfile
278    [ ! -f $lastfile ] && echo $curday,$curyear > $lastfile
279
280
281 #
282 # Check to see when tape drive was last cleaned
283 # output warning message if it's been too long
284 # Currently, if it's been more than 45days, then
285 # an error message is displayed everytime the
286 # script is called, until the clean parameter
287 # is run
288 #
289    cleaned=`cat $cleanfile`
290    lastcleaned=`cut -d, -f1 $lastfile`
291    yearcleaned=`cut -d, -f2 $lastfile`
292
293   if [ `expr $curday - $lastcleaned`  -lt 0 ];then
294      diffday=`expr $curday - $lastcleaned + 365`
295      diffyear=`expr $curyear - $yearcleaned - 1`
296   else
297      diffday=`expr $curday - $lastcleaned`
298      diffyear=`expr $curyear - $yearcleaned`
299   fi
300
301   if [ $diffday -gt $cleanme ] || [ $diffyear -ge 1 ];then
302      if [ $diffyear -ge 1 ];then
303           echo `_ "Warning, it's been %s year(s) & %s day(s) since you last cleaned the tape drive!" "$diffyear" "$diffday"`
304      else
305           echo `_ "Warning, it's been %s day(s) since you last cleaned the tape drive!" "$diffday"`
306      fi
307   fi
308
309 fi
310
311
312 #
313 # Read if there is a tape in the tape drive
314 # If so, determine what slot is the tape from
315 #
316 readstatus() {
317   echo `_ "querying tape drive....."` >> $logfile
318   used=`expr \`$MCUTIL -e drive | tr = \] | cut -d\] -f2\` - $slot0source`
319   echo `_ " Done"` >> $logfile
320
321   # Give changer a chance to reset itself
322   sleep 3
323 }
324
325
326 #
327 # If tape is in the drive, eject it
328 #
329 eject() {
330   echo `_ "tape drive eject was called"` >> $logfile
331
332   readstatus 
333
334   if [ $used -ge $firstslot ];then
335     $MCUTIL -m drive slot:$used
336     code=$?
337   else
338     code=1
339   fi
340
341   if [ $code -eq 0 ];then
342     answer=`_ 'Cartridge %s successfully ejected from %s' "$used" "$tape"`
343     echo `_ "Exit(%s): %s" "$code" "$answer"` >> $logfile
344     echo $current $answer       #For amtape output  
345     return $code
346   elif [ $code -eq 1 ];then
347     answer=`_ "No Cartridge in Tape Drive"`
348     echo `_ 'Exit(%s): %s' "$code" "$answer"` >> $logfile
349     echo $current $answer       #For amtape output
350     exit $code
351   else
352     answer=`_ 'Tape abnormally failed'`
353     echo `_ 'Exit(%s): %s' "$code" "$answer"` >> $logfile
354     echo $current $answer       #For amtape output
355     exit $code
356   fi
357 }
358
359
360 #
361 # reset tape drive to a current state.
362 # This involves ejecting the current tape (if occupied)
363 # and inserting the tape in $firstslot
364 #
365 reset() {
366   echo `_ 'tape drive reset was called'` >> $logfile
367
368   readstatus
369
370   if [ $used -ge $firstslot ];then
371      eject
372   fi
373
374   res=`$MCUTIL -m slot:$firstslot drive`
375   code=$?
376
377
378   if [ $code -eq 0 ];then
379     echo $firstslot > $currentslot
380     answer=`_ '%s - Tape drive was successfully reset' "$firstslot"`
381   elif [ $code -eq 1 ];then
382     answer=`_ '%s - Tape drive reset failed\nCommand -> %s' "$firstslot" "$res"`
383   else
384     code=2
385     answer=`_ '%s - Tape abnormally failed -> %s' "$firstslot" "$res"`
386   fi
387
388   echo `_ 'Exit(%s): slot %s' "$code" "$answer"` >> $logfile
389   echo $firstslot       #For amtape output 
390   exit $code
391 }
392
393
394
395
396 #
397 # Load a specific cartridge into the changer
398 #
399 loadslot() {
400   echo `_ "loadslot was called"` >> $logfile
401
402   readstatus
403
404   whichslot=$1
405
406   case $whichslot in
407     current)
408         if [ $current -ge $firstslot ];then
409            load=$current
410         else
411            load=$used
412         fi
413
414         movetape
415         ;;
416     next|advance)
417           [ $used -lt $firstslot ] && used=$current
418
419           load=`expr $used + 1`
420           [ $load -gt $lastslot ] && load=$firstslot
421
422           if [ $whichslot = advance ];then
423              echo $load > $currentslot
424              code=0
425              answer=`_ 'advancing to slot %s' "$load"`
426              echo `_ 'Exit(%s): %s' "$code" "$answer"` >> $logfile
427              echo $load $code
428              exit $code
429           else
430              movetape
431           fi
432           ;;
433     prev)
434           [ $used -lt $firstslot ] && used=$current
435
436           load=`expr $used - 1`
437           [ $load -lt $firstslot ] && load=$lastslot
438           movetape
439           ;;
440     first)
441           load=$firstslot
442           movetape
443           ;;
444     last)
445           load=$lastslot
446           movetape
447           ;;
448     [$firstslot-$lastslot])
449              load=$1
450              movetape
451           ;;
452     clean)
453           if [ use_cleaning -eq 1 ];then
454              current=$cleanslot
455              eject
456              $MCUTIL slot:$cleanslot drive
457              sleep $cleansleep
458              echo "$curday,$curyear" > $lastfile
459              echo `expr $cleaned + 1` > $cleanfile
460              reset
461           else
462              code=1
463              answer=`_ "Cleaning not enabled in config"`
464              echo `_ 'Exit(%s): %s' "$code" "$answer"` >> $logfile
465              echo $cleanslot $answer
466              exit $code
467           fi
468           ;;
469     *)
470        code=1
471        answer=`_ '"%s" invalid menu option' "$whichslot"`
472        echo `_ 'Exit(%s): %s' "$code" "$answer"` >> $logfile
473        echo "$answer"
474        exit $code
475        ;;
476     esac
477 }
478
479
480 #
481 # sub-function that slot calls to actually eject the tape
482 # & load in the correct slot cartridge
483 #
484 movetape() {
485
486     # If the requested slot is already loaded in the tape drive
487     if [ $load -eq $used ]; then
488         code=0
489         answer=`_ 'slot %s is already loaded' "$load"`
490         echo `_ 'Exit(%s): %s' "$code" "$answer"` >> $logfile
491         echo $load $tape        # For amtape output
492         exit $code
493     elif [ $used -ge $firstslot ];then
494         current=$load
495         eject
496     else
497         echo $load $tape        # For amtape output
498     fi
499
500     echo `_ 'Loading slot %s into Tape drive' "$load"` >> $logfile
501     $MCUTIL -m  slot:$load drive
502     code=$?
503
504     if [ $code -eq 0 ];then
505         echo $load > $currentslot
506         answer=`_ 'Cartridge %s successfully loaded in Tape drive' "$load"`
507     else
508         answer=`_ 'Cartridge %s failed to load in Tape drive' "$load"`
509     fi
510     echo `_ 'Exit(%s): %s' "$code" "$answer"` >> $logfile
511     exit $code
512 }
513
514
515 info() {
516   echo `_ 'tape drive info was called'` >> $logfile
517
518   readstatus
519
520   if [ $used -lt 0 ];then
521     used=0
522   fi
523
524   code=0
525   answer="$used $lastslot 1"
526   echo `_ 'Exit(%s): %s' "$code" "$answer"` >> $logfile
527   echo "$answer"
528   exit $code
529 }
530
531
532   case $1 in
533     -slot)
534            shift
535            loadslot $*
536            ;;
537     -device)
538            echo $tape
539            ;;
540     -info)
541             shift
542             info
543             ;;
544     -reset)
545             shift
546             reset
547             ;;
548     -eject)
549             shift
550             eject
551             ;;
552     --help|-help)
553             echo `_ '-slot {current|next|previous|first|last|%s-%s|clean}' "$firstslot" "$lastslot"`
554             echo `_ '   current  - show contents of current slot'`
555             echo `_ '   next     - load tape from next slot'`
556             echo `_ '   previous - load tape from previous slot'`
557             echo `_ '   first    - load tape from first slot'`
558             echo `_ '   last     - load tape from last slot'`
559             echo `_ '   %s - %s  - load tape from slot <slot #>' "$firstslot" "$lastslot"`
560             echo `_ '   clean    - Clean the drive'`
561             echo `_ '-device   : Show current tape device'`
562             echo `_ '-reset    : Reset changer to known state'`
563             echo `_ '-eject    : Eject current tape from drive'`
564             echo `_ '-info     : Output {current slot | # of slots | can changer go backwards}'`
565             echo `_ '-help     : Display this help'`
566             ;;
567     *)
568        echo `_ "<usage> %s -{slot|device|reset|eject|help}" "$myname"`
569        ;;
570  esac