Imported Upstream version 3.1.0
[debian/amanda] / changer-src / chg-rth.pl
1 #!@PERL@
2
3 # Catch for sh/csh on systems without #! ability.
4 eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
5         & eval 'exec @PERL@ -S $0 $argv:q'
6                 if 0;
7
8 # rth-changer - 
9 #   A tape changer script for the Robotic Tape Handling system OEM'd
10 #   by Andataco (RTH-406) for use with Amanda, the Advanced Maryland
11 #   Network Disk Archiver.
12 #
13 #    Author: Erik Frederick 1/10/97
14 #            edf@tyrell.mc.duke.edu
15 #
16 # This changer script controls the HP c1553 tape drive via a
17 # Peripheral Vision Inc. SCSI control subsystem that interprets
18 # commands sent on the SCSI bus.  It may work with other tape drives
19 # containing the PVI board.
20 #
21 # Permission to freely use and distribute is granted.
22 #
23
24 require 5.001;
25
26 use Getopt::Long;
27
28 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV', 'PATH'};
29 $ENV{'PATH'} = "/usr/bin:/usr/sbin:/sbin:/bin";
30
31 $pname = "rth-changer";
32
33 $prefix="@prefix@";
34 $prefix=$prefix;                # avoid warnings about possible typo
35 $exec_prefix="@exec_prefix@";
36 $exec_prefix=$exec_prefix;      # ditto
37 $sbindir="@sbindir@";
38 $amlibexecdir="@amlibexecdir@";
39
40 if (-x "$sbindir/ammt") {
41         $MT="$sbindir/ammt";
42         $MTF="-f";
43 } elsif (-x "@MT@") {
44         $MT="@MT@";
45         $MTF="@MT_FILE_FLAG@";
46 } else {
47         print "<none> $pname: mt program not found\n";
48         exit(1);
49 }
50
51 $tapeDevice=`$sbindir/amgetconf tapedev`;
52 die "tapedev not found in amanda.conf"
53         if !$tapeDevice or $tapeDevice eq "" or
54             $tapeDevice =~ m/no such parameter/;
55
56 sub getCurrentTape {
57
58   if (!sysopen(RTH, $tapeDevice, 2)) {
59     print "$currentTape $pname: error in opening `$tapeDevice' for getting current tape: $!\n";
60     exit(2);
61   }
62   if (syswrite(RTH, "Rd_ElS", 6) != 6) {
63     print "$currentTape $pname: error in writing `Rd_ElS' to `$tapeDevice': $!\n";
64     exit(2);
65   }
66   if (!close(RTH)) {
67     print "$currentTape $pname: error in closing `$tapeDevice' for getting current tape: $!\n";
68     exit(2);
69   }
70
71   if (!sysopen(RTH, $tapeDevice, 2)) {
72     print "$currentTape $pname: error in opening `$tapeDevice' for getting current tape: $!\n";
73     exit(2);
74   }
75   if (sysread(RTH, $status, 136) != 136) {
76     print "$currentTape $pname: error in reading rth status.\n";
77     exit(2);
78   }
79   if (!close(RTH)) {
80     print "$currentTape $pname: error in closing `$tapeDevice' for getting current tape: $!\n";
81     exit(2);
82   }
83
84   @statusBits=unpack("c*",$status);
85
86   if( ($statusBits[18] == 0x1) || ($statusBits[18]== 0x9)) {
87     return ($statusBits[27]-1);
88   }
89
90   return (0);
91 }
92
93
94 sub getTapeStatus {
95
96   if (!sysopen(RTH, $tapeDevice, 2)) {
97     print "$currentTape $pname: error in opening `$tapeDevice' for getting tape status: $!\n";
98     exit(2);
99   }
100   if (syswrite(RTH, "Rd_ElS", 6) != 6) {
101     print "$currentTape $pname: error in writing `Rd_ElS' to `$tapeDevice': $!\n";
102     exit(2);
103   }
104   if (!close(RTH)) {
105     print "$currentTape $pname: error in closing `$tapeDevice' for getting tpae status: $!\n";
106     exit(2);
107   }
108
109   if (!sysopen(RTH, $tapeDevice, 2)) {
110     print "$currentTape $pname: error in opening `$tapeDevice' for getting tape status: $!\n";
111     exit(2);
112   }
113   if (sysread(RTH, $status, 136) != 136) {
114     print "$currentTape $pname: error in reading rth status for tape $currentTape.\n";
115     exit(2);
116   }
117   if (!close(RTH)) {
118     print "$currentTape $pname: error in closing `$tapeDevice' for getting tape status: $!\n";
119     exit(2);
120   }
121
122   @statusBits=unpack("c*",$status);
123
124   $curTape=0;
125   for($i=42;$i<187;$i+=16) {
126     if($statusBits[$i] == 0x9) {
127       $slots[$curTape] = 1;
128     }
129     else {
130       $slots[$curTape] = 0;
131     }
132     $curTape++;
133   }
134
135   return (@slots);
136 }
137
138 sub rthLoad {
139   my($tape) = @_;
140
141   $command = sprintf "GeT%d", $tape;
142   if (!sysopen(RTH, $tapeDevice, 2)) {
143     print "$currentTape $pname: error in opening `$tapeDevice' for loading tape: $!\n";
144     exit(2);
145   }
146   if (syswrite(RTH, $command, 4) != 4) {
147     print "$currentTape $pname: error in loading tape by writing `$command' to `$tapeDevice': $!\n";
148     exit(2);
149   }
150   if (!close (RTH)) {
151     print "$currentTape $pname: error in closing `$tapeDevice' when trying to load tape: $!\n";
152     exit(2);
153   }
154 }
155
156 sub rthUnload {
157   my($tape) = @_;
158
159   $command = sprintf "PuT%d", $tape;
160   if (!sysopen(RTH, $tapeDevice, 2)) {
161     print "$currentTape $pname: error in opening `$tapeDevice' for unloading tape: $!\n";
162     exit(2);
163   }
164   if (syswrite(RTH, $command, 4) != 4) {
165     print "$currentTape $pname: error in unloading tape by writing `$command' to `$tapeDevice': $!\n";
166     exit(2);
167   }
168   if (!close (RTH)) {
169     print "$currentTape $pname: error in closing `$tapeDevice' when trying to unload tape: $!\n";
170     exit(2);
171   }
172 }
173
174 sub testTape {
175   my($tape) = @_;
176
177   @slots=getTapeStatus();
178
179   if($currentTape == $tape) {
180     return;
181   }
182
183   if($slots[$tape-1] == 0) {
184     print "<none> $pname: no tape in slot requested\n";
185     exit(1);
186   }
187   if($tape>6) {
188     print $tape," $pname: requested a tape > 6\n";
189     exit(2);
190   }
191   if($tape<1) {
192     print $tape," $pname: requested a tape < 1\n";
193     exit(2);
194   }
195   return;
196 }
197
198 sub changeTape {
199   my($tape) = @_;
200
201   if($tape==$currentTape) {
202     return;
203   }
204
205   testTape($tape);
206
207   if($currentTape==0) {
208     rthLoad($tape);
209     $currentTape=$tape;
210     return;
211   }
212   else {
213     rthUnload($currentTape);
214     rthLoad($tape);
215     $currentTape=$tape;
216   }
217 }
218     
219
220 $result = &GetOptions("slot=s", "info", "reset", "eject"); 
221
222 system($MT, 'rewind');
223
224 $nSlots=6;
225 $firstTape=1;
226 $lastTape=6;
227 $currentTape=getCurrentTape(); 
228
229 if($opt_slot) {
230   if($opt_slot =~ /first/) {
231     changeTape(1);
232     print $currentTape, " ", $tapeDevice, "\n";
233   }
234   if($opt_slot =~ /last/) {
235     changeTape(6);
236     print $currentTape, " ", $tapeDevice, "\n";
237   }
238   if($opt_slot =~ /current/) {
239     changeTape($currentTape);
240     print $currentTape, " ", $tapeDevice, "\n";
241   }
242   if($opt_slot =~ /next/) {
243     $tape=$currentTape+1;
244     if ($tape>6) {
245       $tape=1;
246     }
247     changeTape($tape);
248     print $currentTape, " ", $tapeDevice,"\n";
249   }
250   if($opt_slot =~ /prev/) {
251     $tape=$currentTape-1;
252     if($tape<1) {
253       $tape=6;
254     }
255     changeTape($tape);
256     print $currentTape, " ", $tapeDevice,"\n";
257   }
258   if($opt_slot =~ /\d/) {
259     changeTape($opt_slot);
260     print $currentTape, " ", $tapeDevice,"\n";
261   }
262   if($opt_slot =~ /advance/) {
263     $tape=$currentTape+1;
264     if ($tape>6) {
265       $tape=1;
266     }
267     if($currentTape) { 
268       rthUnload($currentTape);
269     }
270     print $currentTape, " ", "/dev/null","\n";
271   }
272
273   exit 0;
274 }
275
276 if($opt_info) {
277  
278   print $currentTape, " 6 1\n";
279
280   exit 0;
281 }
282
283 if($opt_reset) {
284   changeTape(1);
285   print $currentTape, " ",$tapeDevice,"\n";
286   exit 0;
287 }
288
289 if($opt_eject) {
290   if($currentTape) { 
291     rthUnload($currentTape);
292     print "0 ",$tapeDevice,"\n";
293     exit 0;
294   } 
295   else {
296     print "0 $pname: drive was not loaded\n";
297     exit 1;
298   }
299 }
300
301 print "$pname: No command was received.  Exiting.\n";
302 exit 1;