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