Imported Upstream version 2.5.1p3
[debian/amanda] / changer-src / chg-rth.pl.in
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 $libexecdir="@libexecdir@";
39 if ("@USE_VERSION_SUFFIXES@" eq "yes") {
40     $suf = "-@VERSION@";
41 } else {
42     $suf = "";
43 }
44
45 if (-x "$sbindir/ammt$SUF") {
46         $MT="$sbindir/ammt$SUF";
47         $MTF="-f";
48 } elsif (-x "@MT@") {
49         $MT="@MT@";
50         $MTF="@MT_FILE_FLAG@";
51 } else {
52         print "<none> $pname: mt program not found\n";
53         exit(1);
54 }
55
56 $tapeDevice=`$sbindir/amgetconf$SUF tapedev`;
57 die "tapedev not found in amanda.conf"
58         if !$tapeDevice or $tapeDevice eq "" or
59             $tapeDevice =~ m/no such parameter/;
60
61 sub getCurrentTape {
62
63   if (!sysopen(RTH, $tapeDevice, 2)) {
64     print "$currentTape $pname: error in opening `$tapeDevice' for getting current tape: $!\n";
65     exit(2);
66   }
67   if (syswrite(RTH, "Rd_ElS", 6) != 6) {
68     print "$currentTape $pname: error in writing `Rd_ElS' to `$tapeDevice': $!\n";
69     exit(2);
70   }
71   if (!close(RTH)) {
72     print "$currentTape $pname: error in closing `$tapeDevice' for getting current tape: $!\n";
73     exit(2);
74   }
75
76   if (!sysopen(RTH, $tapeDevice, 2)) {
77     print "$currentTape $pname: error in opening `$tapeDevice' for getting current tape: $!\n";
78     exit(2);
79   }
80   if (sysread(RTH, $status, 136) != 136) {
81     print "$currentTape $pname: error in reading rth status.\n";
82     exit(2);
83   }
84   if (!close(RTH)) {
85     print "$currentTape $pname: error in closing `$tapeDevice' for getting current tape: $!\n";
86     exit(2);
87   }
88
89   @statusBits=unpack("c*",$status);
90
91   if( ($statusBits[18] == 0x1) || ($statusBits[18]== 0x9)) {
92     return ($statusBits[27]-1);
93   }
94
95   return (0);
96 }
97
98
99 sub getTapeStatus {
100
101   if (!sysopen(RTH, $tapeDevice, 2)) {
102     print "$currentTape $pname: error in opening `$tapeDevice' for getting tape status: $!\n";
103     exit(2);
104   }
105   if (syswrite(RTH, "Rd_ElS", 6) != 6) {
106     print "$currentTape $pname: error in writing `Rd_ElS' to `$tapeDevice': $!\n";
107     exit(2);
108   }
109   if (!close(RTH)) {
110     print "$currentTape $pname: error in closing `$tapeDevice' for getting tpae status: $!\n";
111     exit(2);
112   }
113
114   if (!sysopen(RTH, $tapeDevice, 2)) {
115     print "$currentTape $pname: error in opening `$tapeDevice' for getting tape status: $!\n";
116     exit(2);
117   }
118   if (sysread(RTH, $status, 136) != 136) {
119     print "$currentTape $pname: error in reading rth status for tape $currentTape.\n";
120     exit(2);
121   }
122   if (!close(RTH)) {
123     print "$currentTape $pname: error in closing `$tapeDevice' for getting tape status: $!\n";
124     exit(2);
125   }
126
127   @statusBits=unpack("c*",$status);
128
129   $curTape=0;
130   for($i=42;$i<187;$i+=16) {
131     if($statusBits[$i] == 0x9) {
132       $slots[$curTape] = 1;
133     }
134     else {
135       $slots[$curTape] = 0;
136     }
137     $curTape++;
138   }
139
140   return (@slots);
141 }
142
143 sub rthLoad {
144   my($tape) = @_;
145
146   $command = sprintf "GeT%d", $tape;
147   if (!sysopen(RTH, $tapeDevice, 2)) {
148     print "$currentTape $pname: error in opening `$tapeDevice' for loading tape: $!\n";
149     exit(2);
150   }
151   if (syswrite(RTH, $command, 4) != 4) {
152     print "$currentTape $pname: error in loading tape by writing `$command' to `$tapeDevice': $!\n";
153     exit(2);
154   }
155   if (!close (RTH)) {
156     print "$currentTape $pname: error in closing `$tapeDevice' when trying to load tape: $!\n";
157     exit(2);
158   }
159 }
160
161 sub rthUnload {
162   my($tape) = @_;
163
164   $command = sprintf "PuT%d", $tape;
165   if (!sysopen(RTH, $tapeDevice, 2)) {
166     print "$currentTape $pname: error in opening `$tapeDevice' for unloading tape: $!\n";
167     exit(2);
168   }
169   if (syswrite(RTH, $command, 4) != 4) {
170     print "$currentTape $pname: error in unloading tape by writing `$command' to `$tapeDevice': $!\n";
171     exit(2);
172   }
173   if (!close (RTH)) {
174     print "$currentTape $pname: error in closing `$tapeDevice' when trying to unload tape: $!\n";
175     exit(2);
176   }
177 }
178
179 sub testTape {
180   my($tape) = @_;
181
182   @slots=getTapeStatus();
183
184   if($currentTape == $tape) {
185     return;
186   }
187
188   if($slots[$tape-1] == 0) {
189     print "<none> $pname: no tape in slot requested\n";
190     exit(1);
191   }
192   if($tape>6) {
193     print $tape," $pname: requested a tape > 6\n";
194     exit(2);
195   }
196   if($tape<1) {
197     print $tape," $pname: requested a tape < 1\n";
198     exit(2);
199   }
200   return;
201 }
202
203 sub changeTape {
204   my($tape) = @_;
205
206   if($tape==$currentTape) {
207     return;
208   }
209
210   testTape($tape);
211
212   if($currentTape==0) {
213     rthLoad($tape);
214     $currentTape=$tape;
215     return;
216   }
217   else {
218     rthUnload($currentTape);
219     rthLoad($tape);
220     $currentTape=$tape;
221   }
222 }
223     
224
225 $result = &GetOptions("slot=s", "info", "reset", "eject"); 
226
227 system($MT, 'rewind');
228
229 $nSlots=6;
230 $firstTape=1;
231 $lastTape=6;
232 $currentTape=getCurrentTape(); 
233
234 if($opt_slot) {
235   if($opt_slot =~ /first/) {
236     changeTape(1);
237     print $currentTape, " ", $tapeDevice, "\n";
238   }
239   if($opt_slot =~ /last/) {
240     changeTape(6);
241     print $currentTape, " ", $tapeDevice, "\n";
242   }
243   if($opt_slot =~ /current/) {
244     changeTape($currentTape);
245     print $currentTape, " ", $tapeDevice, "\n";
246   }
247   if($opt_slot =~ /next/) {
248     $tape=$currentTape+1;
249     if ($tape>6) {
250       $tape=1;
251     }
252     changeTape($tape);
253     print $currentTape, " ", $tapeDevice,"\n";
254   }
255   if($opt_slot =~ /prev/) {
256     $tape=$currentTape-1;
257     if($tape<1) {
258       $tape=6;
259     }
260     changeTape($tape);
261     print $currentTape, " ", $tapeDevice,"\n";
262   }
263   if($opt_slot =~ /\d/) {
264     changeTape($opt_slot);
265     print $currentTape, " ", $tapeDevice,"\n";
266   }
267   if($opt_slot =~ /advance/) {
268     $tape=$currentTape+1;
269     if ($tape>6) {
270       $tape=1;
271     }
272     if($currentTape) { 
273       rthUnload($currentTape);
274     }
275     print $currentTape, " ", "/dev/null","\n";
276   }
277
278   exit 0;
279 }
280
281 if($opt_info) {
282  
283   print $currentTape, " 6 1\n";
284
285   exit 0;
286 }
287
288 if($opt_reset) {
289   changeTape(1);
290   print $currentTape, " ",$tapeDevice,"\n";
291   exit 0;
292 }
293
294 if($opt_eject) {
295   if($currentTape) { 
296     rthUnload($currentTape);
297     print "0 ",$tapeDevice,"\n";
298     exit 0;
299   } 
300   else {
301     print "0 $pname: drive was not loaded\n";
302     exit 1;
303   }
304 }
305
306 print "$pname: No command was received.  Exiting.\n";
307 exit 1;