Imported Upstream version 3.2.0
[debian/amanda] / perl / Amanda / Device.pm
1 # This file was automatically generated by SWIG (http://www.swig.org).
2 # Version 1.3.39
3 #
4 # Do not make changes to this file unless you know what you are doing--modify
5 # the SWIG interface file instead.
6
7 package Amanda::Device;
8 use base qw(Exporter);
9 use base qw(DynaLoader);
10 require Amanda::Header;
11 package Amanda::Devicec;
12 bootstrap Amanda::Device;
13 package Amanda::Device;
14 @EXPORT = qw();
15
16 # ---------- BASE METHODS -------------
17
18 package Amanda::Device;
19
20 sub TIEHASH {
21     my ($classname,$obj) = @_;
22     return bless $obj, $classname;
23 }
24
25 sub CLEAR { }
26
27 sub FIRSTKEY { }
28
29 sub NEXTKEY { }
30
31 sub FETCH {
32     my ($self,$field) = @_;
33     my $member_func = "swig_${field}_get";
34     $self->$member_func();
35 }
36
37 sub STORE {
38     my ($self,$field,$newval) = @_;
39     my $member_func = "swig_${field}_set";
40     $self->$member_func($newval);
41 }
42
43 sub this {
44     my $ptr = shift;
45     return tied(%$ptr);
46 }
47
48
49 # ------- FUNCTION WRAPPERS --------
50
51 package Amanda::Device;
52
53 *unaliased_name = *Amanda::Devicec::unaliased_name;
54 *rait_device_open_from_children = *Amanda::Devicec::rait_device_open_from_children;
55 *write_random_to_device = *Amanda::Devicec::write_random_to_device;
56 *verify_random_from_device = *Amanda::Devicec::verify_random_from_device;
57 *IS_WRITABLE_ACCESS_MODE = *Amanda::Devicec::IS_WRITABLE_ACCESS_MODE;
58
59 ############# Class : Amanda::Device::DirectTCPConnection ##############
60
61 package Amanda::Device::DirectTCPConnection;
62 use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
63 @ISA = qw( Amanda::Device );
64 %OWNER = ();
65 %ITERATORS = ();
66 sub DESTROY {
67     return unless $_[0]->isa('HASH');
68     my $self = tied(%{$_[0]});
69     return unless defined $self;
70     delete $ITERATORS{$self};
71     if (exists $OWNER{$self}) {
72         Amanda::Devicec::delete_DirectTCPConnection($self);
73         delete $OWNER{$self};
74     }
75 }
76
77 *close = *Amanda::Devicec::DirectTCPConnection_close;
78 sub new {
79     my $pkg = shift;
80     my $self = Amanda::Devicec::new_DirectTCPConnection(@_);
81     bless $self, $pkg if defined($self);
82 }
83
84 sub DISOWN {
85     my $self = shift;
86     my $ptr = tied(%$self);
87     delete $OWNER{$ptr};
88 }
89
90 sub ACQUIRE {
91     my $self = shift;
92     my $ptr = tied(%$self);
93     $OWNER{$ptr} = 1;
94 }
95
96
97 ############# Class : Amanda::Device::Device ##############
98
99 package Amanda::Device::Device;
100 use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
101 @ISA = qw( Amanda::Device );
102 %OWNER = ();
103 %ITERATORS = ();
104 sub new {
105     my $pkg = shift;
106     my $self = Amanda::Devicec::new_Device(@_);
107     bless $self, $pkg if defined($self);
108 }
109
110 sub DESTROY {
111     return unless $_[0]->isa('HASH');
112     my $self = tied(%{$_[0]});
113     return unless defined $self;
114     delete $ITERATORS{$self};
115     if (exists $OWNER{$self}) {
116         Amanda::Devicec::delete_Device($self);
117         delete $OWNER{$self};
118     }
119 }
120
121 *configure = *Amanda::Devicec::Device_configure;
122 *error = *Amanda::Devicec::Device_error;
123 *status_error = *Amanda::Devicec::Device_status_error;
124 *error_or_status = *Amanda::Devicec::Device_error_or_status;
125 *read_label = *Amanda::Devicec::Device_read_label;
126 *start = *Amanda::Devicec::Device_start;
127 *finish = *Amanda::Devicec::Device_finish;
128 *start_file = *Amanda::Devicec::Device_start_file;
129 *write_block = *Amanda::Devicec::Device_write_block;
130 *finish_file = *Amanda::Devicec::Device_finish_file;
131 *seek_file = *Amanda::Devicec::Device_seek_file;
132 *seek_block = *Amanda::Devicec::Device_seek_block;
133 *read_block = *Amanda::Devicec::Device_read_block;
134 *erase = *Amanda::Devicec::Device_erase;
135 *eject = *Amanda::Devicec::Device_eject;
136 *directtcp_supported = *Amanda::Devicec::Device_directtcp_supported;
137 *listen = *Amanda::Devicec::Device_listen;
138 *accept = *Amanda::Devicec::Device_accept;
139 *connect = *Amanda::Devicec::Device_connect;
140 *use_connection = *Amanda::Devicec::Device_use_connection;
141 *write_from_connection = *Amanda::Devicec::Device_write_from_connection;
142 *read_to_connection = *Amanda::Devicec::Device_read_to_connection;
143 *property_list = *Amanda::Devicec::Device_property_list;
144 *property_get = *Amanda::Devicec::Device_property_get;
145 *property_set = *Amanda::Devicec::Device_property_set;
146 *property_set_ex = *Amanda::Devicec::Device_property_set_ex;
147 *recycle_file = *Amanda::Devicec::Device_recycle_file;
148 *file = *Amanda::Devicec::Device_file;
149 *block = *Amanda::Devicec::Device_block;
150 *in_file = *Amanda::Devicec::Device_in_file;
151 *device_name = *Amanda::Devicec::Device_device_name;
152 *access_mode = *Amanda::Devicec::Device_access_mode;
153 *is_eof = *Amanda::Devicec::Device_is_eof;
154 *is_eom = *Amanda::Devicec::Device_is_eom;
155 *volume_label = *Amanda::Devicec::Device_volume_label;
156 *volume_time = *Amanda::Devicec::Device_volume_time;
157 *status = *Amanda::Devicec::Device_status;
158 *min_block_size = *Amanda::Devicec::Device_min_block_size;
159 *max_block_size = *Amanda::Devicec::Device_max_block_size;
160 *block_size = *Amanda::Devicec::Device_block_size;
161 *volume_header = *Amanda::Devicec::Device_volume_header;
162 sub DISOWN {
163     my $self = shift;
164     my $ptr = tied(%$self);
165     delete $OWNER{$ptr};
166 }
167
168 sub ACQUIRE {
169     my $self = shift;
170     my $ptr = tied(%$self);
171     $OWNER{$ptr} = 1;
172 }
173
174
175 # ------- VARIABLE STUBS --------
176
177 package Amanda::Device;
178
179 *ACCESS_NULL = *Amanda::Devicec::ACCESS_NULL;
180 *ACCESS_READ = *Amanda::Devicec::ACCESS_READ;
181 *ACCESS_WRITE = *Amanda::Devicec::ACCESS_WRITE;
182 *ACCESS_APPEND = *Amanda::Devicec::ACCESS_APPEND;
183 *DEVICE_STATUS_SUCCESS = *Amanda::Devicec::DEVICE_STATUS_SUCCESS;
184 *DEVICE_STATUS_DEVICE_ERROR = *Amanda::Devicec::DEVICE_STATUS_DEVICE_ERROR;
185 *DEVICE_STATUS_DEVICE_BUSY = *Amanda::Devicec::DEVICE_STATUS_DEVICE_BUSY;
186 *DEVICE_STATUS_VOLUME_MISSING = *Amanda::Devicec::DEVICE_STATUS_VOLUME_MISSING;
187 *DEVICE_STATUS_VOLUME_UNLABELED = *Amanda::Devicec::DEVICE_STATUS_VOLUME_UNLABELED;
188 *DEVICE_STATUS_VOLUME_ERROR = *Amanda::Devicec::DEVICE_STATUS_VOLUME_ERROR;
189 *DEVICE_STATUS_FLAGS_MAX = *Amanda::Devicec::DEVICE_STATUS_FLAGS_MAX;
190 *PROPERTY_PHASE_BEFORE_START = *Amanda::Devicec::PROPERTY_PHASE_BEFORE_START;
191 *PROPERTY_PHASE_BETWEEN_FILE_WRITE = *Amanda::Devicec::PROPERTY_PHASE_BETWEEN_FILE_WRITE;
192 *PROPERTY_PHASE_INSIDE_FILE_WRITE = *Amanda::Devicec::PROPERTY_PHASE_INSIDE_FILE_WRITE;
193 *PROPERTY_PHASE_BETWEEN_FILE_READ = *Amanda::Devicec::PROPERTY_PHASE_BETWEEN_FILE_READ;
194 *PROPERTY_PHASE_INSIDE_FILE_READ = *Amanda::Devicec::PROPERTY_PHASE_INSIDE_FILE_READ;
195 *PROPERTY_PHASE_MAX = *Amanda::Devicec::PROPERTY_PHASE_MAX;
196 *PROPERTY_PHASE_MASK = *Amanda::Devicec::PROPERTY_PHASE_MASK;
197 *PROPERTY_PHASE_SHIFT = *Amanda::Devicec::PROPERTY_PHASE_SHIFT;
198 *PROPERTY_ACCESS_GET_BEFORE_START = *Amanda::Devicec::PROPERTY_ACCESS_GET_BEFORE_START;
199 *PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE = *Amanda::Devicec::PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE;
200 *PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE = *Amanda::Devicec::PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE;
201 *PROPERTY_ACCESS_GET_BETWEEN_FILE_READ = *Amanda::Devicec::PROPERTY_ACCESS_GET_BETWEEN_FILE_READ;
202 *PROPERTY_ACCESS_GET_INSIDE_FILE_READ = *Amanda::Devicec::PROPERTY_ACCESS_GET_INSIDE_FILE_READ;
203 *PROPERTY_ACCESS_SET_BEFORE_START = *Amanda::Devicec::PROPERTY_ACCESS_SET_BEFORE_START;
204 *PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE = *Amanda::Devicec::PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE;
205 *PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE = *Amanda::Devicec::PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE;
206 *PROPERTY_ACCESS_SET_BETWEEN_FILE_READ = *Amanda::Devicec::PROPERTY_ACCESS_SET_BETWEEN_FILE_READ;
207 *PROPERTY_ACCESS_SET_INSIDE_FILE_READ = *Amanda::Devicec::PROPERTY_ACCESS_SET_INSIDE_FILE_READ;
208 *PROPERTY_ACCESS_GET_MASK = *Amanda::Devicec::PROPERTY_ACCESS_GET_MASK;
209 *PROPERTY_ACCESS_SET_MASK = *Amanda::Devicec::PROPERTY_ACCESS_SET_MASK;
210 *CONCURRENCY_PARADIGM_EXCLUSIVE = *Amanda::Devicec::CONCURRENCY_PARADIGM_EXCLUSIVE;
211 *CONCURRENCY_PARADIGM_SHARED_READ = *Amanda::Devicec::CONCURRENCY_PARADIGM_SHARED_READ;
212 *CONCURRENCY_PARADIGM_RANDOM_ACCESS = *Amanda::Devicec::CONCURRENCY_PARADIGM_RANDOM_ACCESS;
213 *STREAMING_REQUIREMENT_NONE = *Amanda::Devicec::STREAMING_REQUIREMENT_NONE;
214 *STREAMING_REQUIREMENT_DESIRED = *Amanda::Devicec::STREAMING_REQUIREMENT_DESIRED;
215 *STREAMING_REQUIREMENT_REQUIRED = *Amanda::Devicec::STREAMING_REQUIREMENT_REQUIRED;
216 *MEDIA_ACCESS_MODE_READ_ONLY = *Amanda::Devicec::MEDIA_ACCESS_MODE_READ_ONLY;
217 *MEDIA_ACCESS_MODE_WORM = *Amanda::Devicec::MEDIA_ACCESS_MODE_WORM;
218 *MEDIA_ACCESS_MODE_READ_WRITE = *Amanda::Devicec::MEDIA_ACCESS_MODE_READ_WRITE;
219 *MEDIA_ACCESS_MODE_WRITE_ONLY = *Amanda::Devicec::MEDIA_ACCESS_MODE_WRITE_ONLY;
220 *PROPERTY_SURETY_BAD = *Amanda::Devicec::PROPERTY_SURETY_BAD;
221 *PROPERTY_SURETY_GOOD = *Amanda::Devicec::PROPERTY_SURETY_GOOD;
222 *PROPERTY_SOURCE_DEFAULT = *Amanda::Devicec::PROPERTY_SOURCE_DEFAULT;
223 *PROPERTY_SOURCE_DETECTED = *Amanda::Devicec::PROPERTY_SOURCE_DETECTED;
224 *PROPERTY_SOURCE_USER = *Amanda::Devicec::PROPERTY_SOURCE_USER;
225
226 @EXPORT_OK = ();
227 %EXPORT_TAGS = ();
228
229
230 =head1 NAME
231
232 Amanda::Device - interact with Amanda data-storage devices
233
234 =head1 SYNOPSIS
235
236   use Amanda::Device qw( :constants );
237
238   my $dev = Amanda::Device->new($device_name);
239   if ($dev->read_label() == $DEVICE_STATUS_SUCCESS) {
240       print "Label on $device_name is '$dev->volume_label'\n";
241   }
242
243 =head1 DATA MODEL
244
245 A volume is a container for data which can be "loaded" into a particular
246 device. For tape devices, a volume is a tape, but most other devices do not
247 deal with such physical objects. Each volume has a volume header giving, among
248 other things, the label of the volume and the timestamp on which it was
249 written. The header may also indicate that the volume is not an Amanda volume.
250 Aside from the header, a volume contains a sequence of files, numbered starting
251 at 1. While writing, devices number files sequentially, but devices that
252 support partial volume recycling may have "holes" in the sequence of file
253 numbers where files have been deleted. The C<seek_file> method, below,
254 describes how the API represents this situation. Each file has a header, too,
255 which contains lots of information about the file. See L<Amanda::Header> for
256 the full list. After the header, a file is just a sequence of bytes.
257
258 Reads and writes to devices take place in blocks. Unlike a typical
259 operating-system file, in which any block boundaries are lost after the file is
260 written, devices must be read back with the block sizes that were used to read.
261 See C<amanda-devices(7)> for more in block sizes, and the read_block and
262 write_block sections, below, for more information.
263
264 =head1 USING THE DEVICE API
265
266 The Device API is object-oriented, so the first task in using the API is to
267 make a Device object:
268
269     $dev = Amanda::Device->new("tape:/dev/nst0");
270
271 This function takes a device name (possibly a device alias) and returns a
272 device object. This function always returns a Device, although it may be a Null
273 device with an error condition. Any C<new> call should be followed by a check
274 of the device's status:
275
276     $dev = Amanda::Device->new($device_name);
277     if ($dev->status() != $Amanda::Device::DEVICE_STATUS_SUCCESS) {
278       die "Could not open '$device_name': " . $dev->error();
279     }
280
281 This function does not access the underlying hardware or any other external
282 systems in any way: that doesn't happen until C<read_label> or C<start>.  An
283 Amanda configuration must be loaded when this function is called, as it
284 searches the configuation for device definitions.  The member variable
285 C<device_name> is set when this function has returned.
286
287 It is unusual for higher-level code to call C<< Amanda::Device->new >>.
288 Intead, use L<Amanda::Changer> to load a volume and reserve access to it; the
289 resulting reservation will contain an already-created Device object.
290
291 While Amanda proivdes multiple implementations of the Device class, they are
292 not distinguishable via the usual Perl methods (C<ref> or C<< $dev->isa >>).
293
294 Device users generally call device methods in the following order for reading:
295
296     read_label (optional)
297     start
298     seek_file (optional)
299     read_block (repeated)
300
301 or, when writing or appending:
302
303     read_label (optional)
304     start
305     start_file
306     write_block (repeated)
307     finish_file
308     finish
309
310 =head2 Alternate Constructor
311
312 To create a new RAIT device from a collection of device objects, call
313 C<< Amanda::Device->new_rait_from_children($child1, $child2, ..) >>.
314 If one of the child objects is C<undef>, the resulting RAIT device
315 will operate in degraded mode.
316
317 =head2 Error Handling
318
319 Device methods return a particular value to signal the presence of an error
320 condition. In many cases, this is simply false (exceptions are listed below).
321
322 When a device signals an error, C<< $dev->status >> and C<< $dev->error >>
323 contain details of what went wrong. Status is a bitfield where each bit that is
324 set indicates a possible problem. Unfortunately, some devices are unable to
325 distinguish states due to limitations of an external system. For example, the
326 tape device often cannot distinguish an empty drive
327 (C<$DEVICE_STATUS_VOLUME_MISSING>) from a hard device error
328 (C<$DEVICE_STATUS_DEVICE_ERROR>), leading to the status
329 C<$DEVICE_STATUS_VOLUME_MISSING>|C<$DEVICE_STATUS_DEVICE_ERROR>.  To be clear:
330 as few as one of the status bits may represent a actual problem.  If
331 C<$DEVICE_STATUS_VOLUME_UNLABELED> is set along with other bits, it is I<not>
332 safe to assume that an unlabeled volume is available.  However, if the bit is
333 not set, then it is safe to assume there is no unlabeled volume present.
334
335 =over 2
336
337 =item C<$DEVICE_STATUS_SUCCESS>
338
339 All OK (no bits set)
340
341 =item C<$DEVICE_STATUS_DEVICE_ERROR>
342
343 The device is in an unresolvable error state, and further retries are unlikely
344 to change the status
345
346 =item C<$DEVICE_STATUS_DEVICE_BUSY>
347
348 The device is in use, and should be retried later
349
350 =item C<$DEVICE_STATUS_VOLUME_MISSING>
351
352 The device itself is OK, but has no media loaded. This may change if media is
353 loaded by the user or a changer
354
355 =item C<$DEVICE_STATUS_VOLUME_UNLABELED>
356
357 The device is OK and media is laoded, but there is no Amanda header or an
358 invalid header on the media.
359
360 =item C<$DEVICE_STATUS_VOLUME_ERROR>
361
362 The device is OK, but there was an unresolvable error loading the header from
363 the media, so subsequent reads or writes will probably fail.
364
365 =back
366
367 At the risk of being repetitive, never test a device's status with C<==>,
368 unless it is to C<$DEVICE_STATUS_SUCCESS>. Furthermore, never try to parse the
369 device error messages -- they are only for user consumption, and may differ
370 from device to device.
371
372 In addition to the status bitfield, a Device also provides a
373 user-comprehensible error message, available from the methods C<error>
374 (returning the error message), C<status_error> (returning the string form of
375 the status), or C<status_or_error> (returning the error message if one is set,
376 otherwise the string form of the status). None of these functions will ever
377 return C<undef>.
378
379 =head2 Properties
380
381 Device properties provide a bidirectional means of communication between
382 devices and their users. A device provides values for some properties, which
383 other parts of Amanda can use to adjust their behavior to suit the device. For
384 example, Amanda will only attempt to append to a volume if the device's
385 properties indicate that it supports this activity. Some devices have
386 additional properties that can be set to control its activity. For example, the
387 S3 Device requires that the users' keys be given via properties.
388
389 See C<amanda-devices(7)> for more information on device properties and their
390 meanings.
391
392 The methods C<property_get> and C<property_set> are used to get and set
393 properties, respectively. If the indicated property simply does not exist,
394 these functions return an error indication (FALSE), but the device's status
395 remains C<$DEVICE_STATUS_SUCCESS>. If a more serious error occurs, then the
396 device's status is set appropriately.
397
398 Device properties are easy to handle, as the Perl-to-C glue takes care of all
399 necessary type conversions:
400
401     $success = $device->property_set("BLOCK_SIZE", $blocksize);
402     $blocksize = $device->property_get("BLOCK_SIZE");
403
404 If C<property_get> is called in an array context, it returns the property
405 value, its surety, and its source, in that order.  If there is an error
406 fetching the property, C<property_get> returns C<undef>.
407
408 The C<property_list()> method returns a list of all properties:
409
410   my @props = $device->property_list();
411
412 its return is an array of hashes:
413
414   ( { 'access' => $access_flags,
415       'name' => $property_name,
416       'description' => $property_description },
417     ...
418   )
419
420 =head3 Surety and Source
421
422 All properties have a source - where the value came from - and surety - a level
423 of confidence in the value. This can be used to decide which of two potentially
424 contradictory properties to believe. For example, the RAIT device examines the
425 source and surety of child devices' block sizes, prefering properties set by
426 the user (C<$PROPERTY_SOURCE_USER>) over others.
427
428 Set a property's source and surety with C<property_set_ex>:
429     $dev->property_set_ex("my_prop", 13, $PROPERTY_SURETY_BAD, $PROPERTY_SOURCE_DEFAULT);
430 The surety and source are returned after the property value in list context:
431     my ($val, $sur, $sou) = $dev->property_get("my_prop");
432
433 The available sureties are:
434
435   $PROPERTY_SURETY_GOOD
436   $PROPERTY_SURETY_BAD
437
438 and the sources are:
439
440   $PROPERTY_SOURCE_DEFAULT
441   $PROPERTY_SOURCE_DETECTED
442   $PROPERTY_SOURCE_USER
443
444 =head2 Concurrency
445
446 Some devices can perform more than one operation simultaneously, while others
447 are more limited. For example, a tape device is exclusive to a single process
448 while it is in use, while a VFS device can support concurrent reads and writes
449 on the same volume.
450
451 As of this writing, device locking is not correctly implemented in many
452 devices; consult the source code and check with the Amanda developers before
453 depending on concurrent operation of devices.
454
455 =head2 EOM and EOF
456
457 When writing to a volume, an EOM (end-of-media) condition occurs when no more
458 space is available on the volume.  Some devices (currently only those
459 supporting DirectTCP) distinguish a logical EOM (LEOM) from a physical EOM
460 (PEOM).  The logical EOM comes some distance before the physical EOM, with
461 enough space left to finish a data block and write any additional bookkeeping
462 data before PEOM.
463
464 In such devices, the C<is_eom> attribute is set once LEOM is detected.  Such
465 detection can happen in any method that writes to the volume, including
466 C<start>, C<start_file>, C<finish_file>, and C<finish>.  API users that
467 understand LEOM should take this as a signal to complete writing to the device
468 and move on before hitting PEOM.
469
470 Devices which do not support LEOM simply return a VOLUME_ERROR when the volume
471 is full.  If this occurs during a C<write_block> operation, then the volume may
472 or may not contain the block - the situation is indeterminate.
473
474 Devices indicate their support for LEOM with the LEOM property.
475
476 =head2 Device Resources
477
478 Some device types have a "locking" mechanism that prevents other parts of the
479 system from accessing the underlying resource while an operation is in
480 progress.  For example, a typical UNIX tape driver cannot be opened by two
481 processes at once.
482
483 Amanda Devices will lock the underlying resource when C<start> or C<read_label>
484 is called, and unlock the resource either when the Device object is
485 garbage-collected or in the C<finish> method.  Thus in a calling sequence such as
486
487     read_label
488     start
489     seek_file
490     ...
491     finish
492
493 the underlying resource remains locked for the entire sequence, even between
494 read_label and finish.
495
496 It is unwise to rely on Perl's garbage-collection to automatically release
497 resources.  Instead, always explicitly release resources with a C<finish> call.
498 The Changer API is careful to do this in its C<release> method.
499
500 =head2 Member Variables
501
502 All member variables are implemented using accessor methods, rather than the
503 more common hashref technique.  Use
504
505   print $dev->device_name, "\n";
506
507 instead of
508
509   print $dev->{'device_name'}, "\n";
510
511 The member variables are:
512
513 =over 4
514
515 =item C<file>
516
517 the current file number, if any
518
519 =item C<block>
520
521 the current block number, if any
522
523 =item C<in_file>
524
525 true if the device is in the middle of reading or writing a file
526
527 =item C<device_name>
528
529 the name with which the device was constructed; note that this is not set until after open_device is finished -- it is an error to access this variable in an open_device implementation
530
531 =item C<access_mode>
532
533 the current access mode (C<$ACCESS_NULL>, or that supplied to start)
534
535 =item C<is_eof>
536
537 true if an EOF occurred while reading; also used by C<write_from_connection>
538
539 =item C<is_eom>
540
541 true if a write operation reached the end of the volume (end-of-medium)
542
543 =item C<volume_label>
544
545 the label of the current volume, set by start and read_label
546
547 =item C<volume_time>
548
549 the timestamp of the current volume, set by start and read_label
550
551 =item C<volume_header>
552
553 the header of the current volume, set by read_label
554
555 =item C<status>
556
557 the device's error status (bit flags) as an integer
558
559 =item C<status_error>
560
561 the device's error status (bit flags) as a string
562
563 =item C<error>
564
565 the device's error message
566
567 =item C<error_or_status>
568
569 the device's error message, if set, otherwise the same as C<status_error> --
570 use this to display error messages from devices
571
572 =item C<block_size>
573
574 the device's currently configured block size. This is also available via the
575 BLOCK_SIZE property. Writers should use block_size-byte blocks, and readers
576 should initially use block_size, and expand buffers as directed by
577 C<read_block>.
578
579 =item C<min_block_size>
580
581 minimum allowed block size for this device
582
583 =item C<max_block_size>
584
585 maximum allowed block size for this device
586
587 =back
588
589 =head2 Object Methods
590
591 =head3 configure($use_global_config)
592
593     $dev->configure(1);
594
595 Once you have a new device, you should configure it. This sets properties on
596 the device based on the user's configuation. If C<$use_global_config> is true,
597 then any global C<device_property> parameters are processed, along with
598 tapetype and other relevant parameters. Otherwise, only parameters from the
599 device definition (if the device was opened via an alias) are processed.
600
601 This method is I<deprecated>.  All access to Devices should be via the Changer
602 API (see L<Amanda::Changer>), which implements its own, more advanced method of
603 configuring devices.  The C<configure> method may be removed in a future
604 release.
605
606 =head3 read_label
607
608     $status = $dev->read_label();
609
610 This function reads the tape header of the current volume, returning the
611 Device's status (see "Error Handling", above). Since this is often the first
612 function to accses the underlying hardware, its error status is the one most
613 often reported to the user. In fact, C<amdevcheck(8)> is little more than a
614 wrapper around read_label.
615
616 The method sets the following member variables:
617
618 =over 4
619
620 =item C<volume_header>
621
622 if any header data was read from the volume, it is represented here. The
623 header's type may be F_WEIRD if the header was not recognized by Amanda.
624
625 =item C<volume_label>
626
627 if read_label read the header successfully, then volume_label contains the
628 label
629
630 =item C<volume_time>
631
632 smililarly, if read_label read the header successfully, then volume_time
633 contains the timestamp from the header
634
635 =back
636
637 =head3 start
638
639     $succss = $dev->start($ACCESS_WRITE, $label, $timestamp);
640
641 Start starts the device and prepares it for the use described by its second
642 parameter. This function can be called regardless of whether C<read_label> has
643 already been called.
644
645 If the access mode is C<$ACCESS_WRITE>, then the label and timestamp must be
646 supplied (although leaving the timestamp undef will use the current time), and
647 they will be used to write a new volume header. Otherwise, these parameters
648 should be undef.
649
650 On completion, start leaves the device's C<access_mode>, C<volume_label> and
651 C<volume_time> member variables set, by reading the tape header if necessary.
652 Note that in mode C<$ACCESS_APPEND>, the C<file> member variable is not set
653 until after C<start_file> has been called.
654
655 =head3 start_file
656
657  $success = $dev->start_file($header);
658
659 This method prepares the device to write data into a file, beginning by writing
660 the supplied header to the volume. On successful completion, the device's
661 C<file> is set to the current file number, C<block> is zero, and C<in_file> is
662 true.  If the volume is out of space, the C<is_eom> member is set to true and
663 the method returns false with status C<DEVICE_STATUS_VOLUME_ERROR>.
664
665 =head3 write_block
666
667  # (not available from Perl)
668  success = device_write_block(dev, blocksize, buf);
669
670 This method writes a single block of data to the volume.  It is only available
671 from C -- Perl code should not be handling raw data, as it is far too slow.
672 Use the transfer architecture (L<Amanda::Xfer>) for that purpose.
673
674 The C<blocksize> must be the device's block size, unless
675 this is a short write.  A short write must be the last block
676 of a file. Some devices will zero-pad a short write to a full
677 blocksize. This method returns false on error.  If the volume is
678 out of space, C<is_eom> is set and the method returns false with
679 status C<DEVICE_STATUS_VOLUME_ERROR>.  Note that not all devices can
680 differentiate an EOM condition from other errors; these devices will
681 set C<is_eom> whenever the situation is ambiguous.
682
683 This function ensures that C<block> is correct on exit. Even in an
684 error condition, it does not finish the current file for the caller.
685
686 =head3 finish_file
687
688  $success = $dev->finish_file();
689
690 Once an entire file has been written, finish_file performs any
691 cleanup required on the volume, such as writing filemarks. On exit,
692 C<in_file> is false.  If the device runs out of space while finishing
693 (e.g., the filemark does not fit), then this method returns false
694 with status C<DEVICE_STATUS_VOLUME_ERROR> and C<is_eom> is set.
695
696 This function should not be used while reading -- instead, just seek
697 to the next file.
698
699 =head3 seek_file
700
701  $header = $dev->seek_file($fileno);
702
703 In C<$ACCESS_READ>, C<seek_file> sets up the device to read from file
704 C<$fileno>. This function is not available in C<$ACCESS_WRITE> and
705 C<$ACCESS_APPEND>. It returns the header from the requested file on success, or
706 undef on error.
707
708 If the requested file doesn't exist, as might happen when a volume has had
709 files recycled, then C<seek_file> will seek to the next file that does exist. The
710 file this function selected is indicated by the C<file> member variable on exit.
711 If the requested file number is exactly one more than the last valid file, this
712 function returns a C<$F_TAPEEND> header.
713
714 As an example, on a volume with only files 1 and 3:
715
716  $dev->seek_file(1) returns header for file 1, $dev->file == 1
717  $dev->seek_file(2) returns header for file 3, $dev->file == 3
718  $dev->seek_file(3) returns header for file 3, $dev->file == 3
719  $dev->seek_file(4) returns a tapend header, $dev->file == 4
720  $dev->seek_file(5) returns NULL/undef
721
722 On exit, C<is_eof> is false, C<in_file> is true unless no file was found (tapeend or NULL), C<file> is the discovered file, and C<block> is zero.
723
724 =head3 seek_block
725
726  $success = $dev->seek_block($block);
727
728 After seeking to a file, the caller can optionally seek to a particular block
729 in the file. This function will set C<block> appropriately. Note that it may
730 not be possible to detect EOF, so this function may fail to set C<is_eof> even
731 though a subsequent C<read_block> will return no data.
732
733 =head3 read_block
734
735  # (not available from Perl)
736  bytes_read = device_read_block(dev, buffer, *blocksize);
737
738 This method is the complement of C<write_block>, and reads the next block from
739 the device, or returns -1 on error. Pass a buffer and its size. If the buffer
740 is not big enough, no read is performed, the parameter C<blocksize> is set to
741 the required blocksize, and the method returns 0. As a special case, passing a
742 C<NULL> buffer and C<*blocksize == 0> is treated as a request for the required block
743 size. It is not an error to pass a buffer that is too large (and, in fact, this
744 is precisely the effect of setting the C<read_block_size> configuration
745 parameter).
746
747 On EOF, this method returns -1, but sets C<is_eof> and leaves the device's
748 status set to C<$DEVICE_STATUS_SUCCESS>. Some devices may be able to detect EOF
749 while reading the last block, and will set C<is_eof> at that time. Others must
750 wait for the next read to fail. It is never an error to call C<read_block>
751 after an EOF, so there is no need to check C<is_eof> except when C<read_block>
752 returns -1.
753
754 =head3 finish
755
756  $success = $dev->finish();
757
758 This undoes the effects of start, returning the device to a neutral state
759 (C<$ACCESS_NULL>).  It will also release any resources acquired by
760 C<read_label>, even if C<start> was not called.  After C<finish>, it is not an
761 error to call C<start> again, even with a different mode.
762
763 =head3 recycle_file
764
765  $success = $dev->recycle_file(fileno);
766
767 On devices that support it, this removes the indicated file from the volume,
768 presumably freeing its space to be used for other files. File numbers of
769 existing files will not change, so this operation may leave "holes" in the
770 sequence of file numbers. See C<seek_file> to see how this is handled.
771
772 This method cannot be called while in a file, nor while in C<$ACCESS_READ>
773 mode.
774
775 =head3 erase
776
777  $success = $dev->erase(fileno);
778
779 On devices that support it, this erases all data from the volume, presumably
780 freeing the space.  This method must be called before start and after finish --
781 that is, while the device is in a neutral state (C<$ACCESS_NULL>). You can
782 detect whether or not this operation is supported using the C<full_deletion>
783 property.
784
785 =head3 eject
786
787  $success = $dev->eject();
788
789 On devices that support it, this eject the volume.  This method can be called
790 before start and after finish.
791
792 =head3 directtcp_supported
793
794   $supp = $dev->directtcp_supported();
795
796 This method returns TRUE if the DirectTCP-related methods (C<listen>,
797 C<accept>, C<write_from_connection>, and C<read_to_connection>) are implemented
798 by this device.
799
800 =head3 listen
801
802   $addrs = $dev->listen($for_writing);
803
804 The C<listen> method starts the device listening for an incoming DirectTCP
805 connection.  The method returns a set of IP:PORT pairs to which a TCP
806 connection can be made.  The boolean C<for_writing> is TRUE if
807 this connection will be used to write to the device.
808
809 This method can be called at any time, but between the time C<listen> is called
810 and when C<accept> returns, no other methods of the device should be called.
811
812 The return value might look like:
813
814   $addrs = [ [ "127.0.0.1", 9382 ] ]
815
816 In C, the memory for these addresses remains the responsibility of the device,
817 and will remain unchanged until C<accept> returns.
818
819 =head3 accept
820
821   $conn = $dev->accept();
822
823 This method accepts a connection to one of the addresses returned by C<listen>,
824 returning an established DirectTCPConnection object (see below).  It returns
825 C<undef> on failure.  Note that this method may block indefinitely if no
826 connection ever occurs.  The C implementation returns an already-referenced
827 connection object, so the caller should call C<g_object_unref> when the
828 connection is no longer needed.
829
830 =head3 connect
831
832   $conn = $dev->connect($for_writing, $addrs);
833
834 This method initiates a connection to one of the addresses in C<$addrs>,
835 returning an established DirectTCPConnection object (see below).  The
836 C<$for_writing> parameter is TRUE if the connection will be used to write to
837 the device.  It returns C<undef> on failure.  Note that this method may block
838 indefinitely if no connection ever occurs.  The C implementation returns an
839 already-referenced connection object, so the caller should call
840 C<g_object_unref> when the connection is no longer needed.
841
842 =head3 use_connection
843
844   my $ok = $dev->use_connection($conn);
845
846 Call this method to use a DirectTCPConnection object created with another
847 device.  The method must be called before the device is started (so
848 C<access_mode> is C<$ACCESS_NULL>), as some devices cannot support switching
849 connections without rewinding.  Any subsequent C<read_to_connection> or
850 C<write_from_connection> calls will use this connection.
851
852 =head3 write_from_connection
853
854   ($ok, $actual_size) = $dev->write_from_connection($size);
855
856 This method reads data from the DirectTCPConnection specified with
857 C<use_connection> or returned from C<accept> or C<connect> and writes it to the
858 volume.   It writes at most C<$size> bytes, and returns the number of bytes
859 written in C<$actual_size>.  If C<$size> is zero, it will write until EOF, EOM,
860 or a device error.  On error, C<$ok> is false.
861
862 When an EOF is received over the connection, signalling the end of the data
863 stream, then this method returns without error (C<$ok> is true), with
864 C<$actual_size> indicating the number of bytes written to the device (which may
865 be zero).  In this case, the C<is_eof> attribute is true on return.
866
867 Similarly, when the device encounters logical EOM in this method, it returns
868 the total bytes transferred in C<$actual_size>, with C<$ok> true, and the
869 C<is_eom> attribute true.  No data is lost.  If writes continue until physical
870 EOM, data may be lost.
871
872 =head3 read_to_connection
873
874   ($ok, $actual_size) = $dev->read_to_connection($size);
875
876 This method is similar to C<write_from_connection> but the data flows in the
877 opposite direction.  It reads at most C<$size> bytes, and returns the total
878 number of bytes read in C<$actual_size>.
879
880 When the method encounters an EOF, it stops early and returns successfully with
881 the number of bytes actually read (which may be zero).
882
883 =head3 property_get
884
885 Get a property value, where the property is specified by name.  See "Properties", above.
886
887 =head3 property_set
888
889 Set a simple property value.  See "Properties", above.
890
891 =head3 property_set_ex
892
893 Set a property value with surety and source.  See "Properties", above.
894
895 =head2 CONSTANTS
896
897 This module defines a large number of constant scalars.  These constants are
898 available from the package namespace (e.g., C<$Amanda::Device::ACCESS_WRITE>),
899 or imported with the C<:constant> import tag.
900
901 =head2 DirectTCPConnection objects
902
903 The C<accept> and C<connect> methods return an object to represent the ongoing
904 DirectTCP connection.  This object is mostly useful as a "token" to be passed
905 to C<write_from_connection> and C<read_to_connection>.  In particular, a
906 connection created by one device can be used with another device; this is how
907 DirectTCP dumps are spanned over multiple volumes.
908
909 The class does have one critical method, though:
910
911   $conn->close();
912
913 This method closes the connection, releasing all resources allocated to it.  It
914 can be called at any time, whether the remote side has closed the connection
915 already or not.
916
917 =cut
918
919
920 sub new_rait_from_children {
921     my $class = shift; # strip the $class from the arguments
922     return rait_device_open_from_children([@_]);
923 }
924
925 push @EXPORT_OK, qw(DeviceAccessMode_to_strings);
926 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw(DeviceAccessMode_to_strings);
927
928 my %_DeviceAccessMode_VALUES;
929 #Convert a flag value to a list of names for flags that are set.
930 sub DeviceAccessMode_to_strings {
931     my ($flags) = @_;
932     my @result = ();
933
934     for my $k (keys %_DeviceAccessMode_VALUES) {
935         my $v = $_DeviceAccessMode_VALUES{$k};
936
937         #is this a matching flag?
938         if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
939             push @result, $k;
940         }
941     }
942
943 #by default, just return the number as a 1-element list
944     if (!@result) {
945         return ($flags);
946     }
947
948     return @result;
949 }
950
951 push @EXPORT_OK, qw($ACCESS_NULL);
952 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw($ACCESS_NULL);
953
954 $_DeviceAccessMode_VALUES{"NULL"} = $ACCESS_NULL;
955
956 push @EXPORT_OK, qw($ACCESS_READ);
957 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw($ACCESS_READ);
958
959 $_DeviceAccessMode_VALUES{"READ"} = $ACCESS_READ;
960
961 push @EXPORT_OK, qw($ACCESS_WRITE);
962 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw($ACCESS_WRITE);
963
964 $_DeviceAccessMode_VALUES{"WRITE"} = $ACCESS_WRITE;
965
966 push @EXPORT_OK, qw($ACCESS_APPEND);
967 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw($ACCESS_APPEND);
968
969 $_DeviceAccessMode_VALUES{"APPEND"} = $ACCESS_APPEND;
970
971 push @EXPORT_OK, qw(IS_WRITABLE_ACCESS_MODE);
972 push @{$EXPORT_TAGS{"DeviceAccessMode"}}, qw(IS_WRITABLE_ACCESS_MODE);
973
974 #copy symbols in DeviceAccessMode to constants
975 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"DeviceAccessMode"}};
976
977 push @EXPORT_OK, qw(DeviceStatusFlags_to_strings);
978 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw(DeviceStatusFlags_to_strings);
979
980 my %_DeviceStatusFlags_VALUES;
981 #Convert a flag value to a list of names for flags that are set.
982 sub DeviceStatusFlags_to_strings {
983     my ($flags) = @_;
984     my @result = ();
985
986     for my $k (keys %_DeviceStatusFlags_VALUES) {
987         my $v = $_DeviceStatusFlags_VALUES{$k};
988
989         #is this a matching flag?
990         if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
991             push @result, $k;
992         }
993     }
994
995 #by default, just return the number as a 1-element list
996     if (!@result) {
997         return ($flags);
998     }
999
1000     return @result;
1001 }
1002
1003 push @EXPORT_OK, qw($DEVICE_STATUS_SUCCESS);
1004 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_SUCCESS);
1005
1006 $_DeviceStatusFlags_VALUES{"SUCCESS"} = $DEVICE_STATUS_SUCCESS;
1007
1008 push @EXPORT_OK, qw($DEVICE_STATUS_DEVICE_ERROR);
1009 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_DEVICE_ERROR);
1010
1011 $_DeviceStatusFlags_VALUES{"DEVICE_ERROR"} = $DEVICE_STATUS_DEVICE_ERROR;
1012
1013 push @EXPORT_OK, qw($DEVICE_STATUS_DEVICE_BUSY);
1014 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_DEVICE_BUSY);
1015
1016 $_DeviceStatusFlags_VALUES{"DEVICE_BUSY"} = $DEVICE_STATUS_DEVICE_BUSY;
1017
1018 push @EXPORT_OK, qw($DEVICE_STATUS_VOLUME_MISSING);
1019 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_VOLUME_MISSING);
1020
1021 $_DeviceStatusFlags_VALUES{"VOLUME_MISSING"} = $DEVICE_STATUS_VOLUME_MISSING;
1022
1023 push @EXPORT_OK, qw($DEVICE_STATUS_VOLUME_UNLABELED);
1024 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_VOLUME_UNLABELED);
1025
1026 $_DeviceStatusFlags_VALUES{"VOLUME_UNLABELED"} = $DEVICE_STATUS_VOLUME_UNLABELED;
1027
1028 push @EXPORT_OK, qw($DEVICE_STATUS_VOLUME_ERROR);
1029 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_VOLUME_ERROR);
1030
1031 $_DeviceStatusFlags_VALUES{"VOLUME_ERROR"} = $DEVICE_STATUS_VOLUME_ERROR;
1032
1033 push @EXPORT_OK, qw($DEVICE_STATUS_FLAGS_MAX);
1034 push @{$EXPORT_TAGS{"DeviceStatusFlags"}}, qw($DEVICE_STATUS_FLAGS_MAX);
1035
1036 #copy symbols in DeviceStatusFlags to constants
1037 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"DeviceStatusFlags"}};
1038
1039 push @EXPORT_OK, qw(PropertyPhaseFlags_to_strings);
1040 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw(PropertyPhaseFlags_to_strings);
1041
1042 my %_PropertyPhaseFlags_VALUES;
1043 #Convert a flag value to a list of names for flags that are set.
1044 sub PropertyPhaseFlags_to_strings {
1045     my ($flags) = @_;
1046     my @result = ();
1047
1048     for my $k (keys %_PropertyPhaseFlags_VALUES) {
1049         my $v = $_PropertyPhaseFlags_VALUES{$k};
1050
1051         #is this a matching flag?
1052         if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
1053             push @result, $k;
1054         }
1055     }
1056
1057 #by default, just return the number as a 1-element list
1058     if (!@result) {
1059         return ($flags);
1060     }
1061
1062     return @result;
1063 }
1064
1065 push @EXPORT_OK, qw($PROPERTY_PHASE_BEFORE_START);
1066 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_BEFORE_START);
1067
1068 $_PropertyPhaseFlags_VALUES{"BEFORE_START"} = $PROPERTY_PHASE_BEFORE_START;
1069
1070 push @EXPORT_OK, qw($PROPERTY_PHASE_BETWEEN_FILE_WRITE);
1071 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_BETWEEN_FILE_WRITE);
1072
1073 $_PropertyPhaseFlags_VALUES{"BETWEEN_FILE_WRITE"} = $PROPERTY_PHASE_BETWEEN_FILE_WRITE;
1074
1075 push @EXPORT_OK, qw($PROPERTY_PHASE_INSIDE_FILE_WRITE);
1076 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_INSIDE_FILE_WRITE);
1077
1078 $_PropertyPhaseFlags_VALUES{"INSIDE_FILE_WRITE"} = $PROPERTY_PHASE_INSIDE_FILE_WRITE;
1079
1080 push @EXPORT_OK, qw($PROPERTY_PHASE_BETWEEN_FILE_READ);
1081 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_BETWEEN_FILE_READ);
1082
1083 $_PropertyPhaseFlags_VALUES{"BETWEEN_FILE_READ"} = $PROPERTY_PHASE_BETWEEN_FILE_READ;
1084
1085 push @EXPORT_OK, qw($PROPERTY_PHASE_INSIDE_FILE_READ);
1086 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_INSIDE_FILE_READ);
1087
1088 $_PropertyPhaseFlags_VALUES{"INSIDE_FILE_READ"} = $PROPERTY_PHASE_INSIDE_FILE_READ;
1089
1090 push @EXPORT_OK, qw($PROPERTY_PHASE_MAX);
1091 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_MAX);
1092
1093 push @EXPORT_OK, qw($PROPERTY_PHASE_MASK);
1094 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_MASK);
1095
1096 push @EXPORT_OK, qw($PROPERTY_PHASE_SHIFT);
1097 push @{$EXPORT_TAGS{"PropertyPhaseFlags"}}, qw($PROPERTY_PHASE_SHIFT);
1098
1099 #copy symbols in PropertyPhaseFlags to constants
1100 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"PropertyPhaseFlags"}};
1101
1102 push @EXPORT_OK, qw(PropertyAccessFlags_to_strings);
1103 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw(PropertyAccessFlags_to_strings);
1104
1105 my %_PropertyAccessFlags_VALUES;
1106 #Convert a flag value to a list of names for flags that are set.
1107 sub PropertyAccessFlags_to_strings {
1108     my ($flags) = @_;
1109     my @result = ();
1110
1111     for my $k (keys %_PropertyAccessFlags_VALUES) {
1112         my $v = $_PropertyAccessFlags_VALUES{$k};
1113
1114         #is this a matching flag?
1115         if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
1116             push @result, $k;
1117         }
1118     }
1119
1120 #by default, just return the number as a 1-element list
1121     if (!@result) {
1122         return ($flags);
1123     }
1124
1125     return @result;
1126 }
1127
1128 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_BEFORE_START);
1129 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_BEFORE_START);
1130
1131 $_PropertyAccessFlags_VALUES{"GET_BEFORE_START"} = $PROPERTY_ACCESS_GET_BEFORE_START;
1132
1133 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE);
1134 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE);
1135
1136 $_PropertyAccessFlags_VALUES{"GET_BETWEEN_FILE_WRITE"} = $PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE;
1137
1138 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE);
1139 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE);
1140
1141 $_PropertyAccessFlags_VALUES{"GET_INSIDE_FILE_WRITE"} = $PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE;
1142
1143 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_BETWEEN_FILE_READ);
1144 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_BETWEEN_FILE_READ);
1145
1146 $_PropertyAccessFlags_VALUES{"GET_BETWEEN_FILE_READ"} = $PROPERTY_ACCESS_GET_BETWEEN_FILE_READ;
1147
1148 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_INSIDE_FILE_READ);
1149 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_INSIDE_FILE_READ);
1150
1151 $_PropertyAccessFlags_VALUES{"GET_INSIDE_FILE_READ"} = $PROPERTY_ACCESS_GET_INSIDE_FILE_READ;
1152
1153 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_BEFORE_START);
1154 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_BEFORE_START);
1155
1156 $_PropertyAccessFlags_VALUES{"SET_BEFORE_START"} = $PROPERTY_ACCESS_SET_BEFORE_START;
1157
1158 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE);
1159 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE);
1160
1161 $_PropertyAccessFlags_VALUES{"SET_BETWEEN_FILE_WRITE"} = $PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE;
1162
1163 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE);
1164 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE);
1165
1166 $_PropertyAccessFlags_VALUES{"SET_INSIDE_FILE_WRITE"} = $PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE;
1167
1168 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_BETWEEN_FILE_READ);
1169 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_BETWEEN_FILE_READ);
1170
1171 $_PropertyAccessFlags_VALUES{"SET_BETWEEN_FILE_READ"} = $PROPERTY_ACCESS_SET_BETWEEN_FILE_READ;
1172
1173 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_INSIDE_FILE_READ);
1174 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_INSIDE_FILE_READ);
1175
1176 $_PropertyAccessFlags_VALUES{"SET_INSIDE_FILE_READ"} = $PROPERTY_ACCESS_SET_INSIDE_FILE_READ;
1177
1178 push @EXPORT_OK, qw($PROPERTY_ACCESS_GET_MASK);
1179 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_GET_MASK);
1180
1181 push @EXPORT_OK, qw($PROPERTY_ACCESS_SET_MASK);
1182 push @{$EXPORT_TAGS{"PropertyAccessFlags"}}, qw($PROPERTY_ACCESS_SET_MASK);
1183
1184 #copy symbols in PropertyAccessFlags to constants
1185 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"PropertyAccessFlags"}};
1186
1187 push @EXPORT_OK, qw(ConcurrencyParadigm_to_string);
1188 push @{$EXPORT_TAGS{"ConcurrencyParadigm"}}, qw(ConcurrencyParadigm_to_string);
1189
1190 my %_ConcurrencyParadigm_VALUES;
1191 #Convert an enum value to a single string
1192 sub ConcurrencyParadigm_to_string {
1193     my ($enumval) = @_;
1194
1195     for my $k (keys %_ConcurrencyParadigm_VALUES) {
1196         my $v = $_ConcurrencyParadigm_VALUES{$k};
1197
1198         #is this a matching flag?
1199         if ($enumval == $v) {
1200             return $k;
1201         }
1202     }
1203
1204 #default, just return the number
1205     return $enumval;
1206 }
1207
1208 push @EXPORT_OK, qw($CONCURRENCY_PARADIGM_EXCLUSIVE);
1209 push @{$EXPORT_TAGS{"ConcurrencyParadigm"}}, qw($CONCURRENCY_PARADIGM_EXCLUSIVE);
1210
1211 $_ConcurrencyParadigm_VALUES{"EXCLUSIVE"} = $CONCURRENCY_PARADIGM_EXCLUSIVE;
1212
1213 push @EXPORT_OK, qw($CONCURRENCY_PARADIGM_SHARED_READ);
1214 push @{$EXPORT_TAGS{"ConcurrencyParadigm"}}, qw($CONCURRENCY_PARADIGM_SHARED_READ);
1215
1216 $_ConcurrencyParadigm_VALUES{"SHARED_READ"} = $CONCURRENCY_PARADIGM_SHARED_READ;
1217
1218 push @EXPORT_OK, qw($CONCURRENCY_PARADIGM_RANDOM_ACCESS);
1219 push @{$EXPORT_TAGS{"ConcurrencyParadigm"}}, qw($CONCURRENCY_PARADIGM_RANDOM_ACCESS);
1220
1221 $_ConcurrencyParadigm_VALUES{"RANDOM_ACCESS"} = $CONCURRENCY_PARADIGM_RANDOM_ACCESS;
1222
1223 #copy symbols in ConcurrencyParadigm to constants
1224 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"ConcurrencyParadigm"}};
1225
1226 push @EXPORT_OK, qw(StreamingRequirement_to_string);
1227 push @{$EXPORT_TAGS{"StreamingRequirement"}}, qw(StreamingRequirement_to_string);
1228
1229 my %_StreamingRequirement_VALUES;
1230 #Convert an enum value to a single string
1231 sub StreamingRequirement_to_string {
1232     my ($enumval) = @_;
1233
1234     for my $k (keys %_StreamingRequirement_VALUES) {
1235         my $v = $_StreamingRequirement_VALUES{$k};
1236
1237         #is this a matching flag?
1238         if ($enumval == $v) {
1239             return $k;
1240         }
1241     }
1242
1243 #default, just return the number
1244     return $enumval;
1245 }
1246
1247 push @EXPORT_OK, qw($STREAMING_REQUIREMENT_NONE);
1248 push @{$EXPORT_TAGS{"StreamingRequirement"}}, qw($STREAMING_REQUIREMENT_NONE);
1249
1250 $_StreamingRequirement_VALUES{"NONE"} = $STREAMING_REQUIREMENT_NONE;
1251
1252 push @EXPORT_OK, qw($STREAMING_REQUIREMENT_DESIRED);
1253 push @{$EXPORT_TAGS{"StreamingRequirement"}}, qw($STREAMING_REQUIREMENT_DESIRED);
1254
1255 $_StreamingRequirement_VALUES{"DESIRED"} = $STREAMING_REQUIREMENT_DESIRED;
1256
1257 push @EXPORT_OK, qw($STREAMING_REQUIREMENT_REQUIRED);
1258 push @{$EXPORT_TAGS{"StreamingRequirement"}}, qw($STREAMING_REQUIREMENT_REQUIRED);
1259
1260 $_StreamingRequirement_VALUES{"REQUIRED"} = $STREAMING_REQUIREMENT_REQUIRED;
1261
1262 #copy symbols in StreamingRequirement to constants
1263 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"StreamingRequirement"}};
1264
1265 push @EXPORT_OK, qw(MediaAccessMode_to_string);
1266 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw(MediaAccessMode_to_string);
1267
1268 my %_MediaAccessMode_VALUES;
1269 #Convert an enum value to a single string
1270 sub MediaAccessMode_to_string {
1271     my ($enumval) = @_;
1272
1273     for my $k (keys %_MediaAccessMode_VALUES) {
1274         my $v = $_MediaAccessMode_VALUES{$k};
1275
1276         #is this a matching flag?
1277         if ($enumval == $v) {
1278             return $k;
1279         }
1280     }
1281
1282 #default, just return the number
1283     return $enumval;
1284 }
1285
1286 push @EXPORT_OK, qw($MEDIA_ACCESS_MODE_READ_ONLY);
1287 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw($MEDIA_ACCESS_MODE_READ_ONLY);
1288
1289 $_MediaAccessMode_VALUES{"READ_ONLY"} = $MEDIA_ACCESS_MODE_READ_ONLY;
1290
1291 push @EXPORT_OK, qw($MEDIA_ACCESS_MODE_WORM);
1292 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw($MEDIA_ACCESS_MODE_WORM);
1293
1294 $_MediaAccessMode_VALUES{"WORM"} = $MEDIA_ACCESS_MODE_WORM;
1295
1296 push @EXPORT_OK, qw($MEDIA_ACCESS_MODE_READ_WRITE);
1297 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw($MEDIA_ACCESS_MODE_READ_WRITE);
1298
1299 $_MediaAccessMode_VALUES{"READ_WRITE"} = $MEDIA_ACCESS_MODE_READ_WRITE;
1300
1301 push @EXPORT_OK, qw($MEDIA_ACCESS_MODE_WRITE_ONLY);
1302 push @{$EXPORT_TAGS{"MediaAccessMode"}}, qw($MEDIA_ACCESS_MODE_WRITE_ONLY);
1303
1304 $_MediaAccessMode_VALUES{"WRITE_ONLY"} = $MEDIA_ACCESS_MODE_WRITE_ONLY;
1305
1306 #copy symbols in MediaAccessMode to constants
1307 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"MediaAccessMode"}};
1308
1309 push @EXPORT_OK, qw(PropertySurety_to_strings);
1310 push @{$EXPORT_TAGS{"PropertySurety"}}, qw(PropertySurety_to_strings);
1311
1312 my %_PropertySurety_VALUES;
1313 #Convert a flag value to a list of names for flags that are set.
1314 sub PropertySurety_to_strings {
1315     my ($flags) = @_;
1316     my @result = ();
1317
1318     for my $k (keys %_PropertySurety_VALUES) {
1319         my $v = $_PropertySurety_VALUES{$k};
1320
1321         #is this a matching flag?
1322         if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
1323             push @result, $k;
1324         }
1325     }
1326
1327 #by default, just return the number as a 1-element list
1328     if (!@result) {
1329         return ($flags);
1330     }
1331
1332     return @result;
1333 }
1334
1335 push @EXPORT_OK, qw($PROPERTY_SURETY_BAD);
1336 push @{$EXPORT_TAGS{"PropertySurety"}}, qw($PROPERTY_SURETY_BAD);
1337
1338 $_PropertySurety_VALUES{"SURETY_BAD"} = $PROPERTY_SURETY_BAD;
1339
1340 push @EXPORT_OK, qw($PROPERTY_SURETY_GOOD);
1341 push @{$EXPORT_TAGS{"PropertySurety"}}, qw($PROPERTY_SURETY_GOOD);
1342
1343 $_PropertySurety_VALUES{"SURETY_GOOD"} = $PROPERTY_SURETY_GOOD;
1344
1345 #copy symbols in PropertySurety to constants
1346 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"PropertySurety"}};
1347
1348 push @EXPORT_OK, qw(PropertySource_to_strings);
1349 push @{$EXPORT_TAGS{"PropertySource"}}, qw(PropertySource_to_strings);
1350
1351 my %_PropertySource_VALUES;
1352 #Convert a flag value to a list of names for flags that are set.
1353 sub PropertySource_to_strings {
1354     my ($flags) = @_;
1355     my @result = ();
1356
1357     for my $k (keys %_PropertySource_VALUES) {
1358         my $v = $_PropertySource_VALUES{$k};
1359
1360         #is this a matching flag?
1361         if (($v == 0 && $flags == 0) || ($v != 0 && ($flags & $v) == $v)) {
1362             push @result, $k;
1363         }
1364     }
1365
1366 #by default, just return the number as a 1-element list
1367     if (!@result) {
1368         return ($flags);
1369     }
1370
1371     return @result;
1372 }
1373
1374 push @EXPORT_OK, qw($PROPERTY_SOURCE_DEFAULT);
1375 push @{$EXPORT_TAGS{"PropertySource"}}, qw($PROPERTY_SOURCE_DEFAULT);
1376
1377 $_PropertySource_VALUES{"SOURCE_DEFAULT"} = $PROPERTY_SOURCE_DEFAULT;
1378
1379 push @EXPORT_OK, qw($PROPERTY_SOURCE_DETECTED);
1380 push @{$EXPORT_TAGS{"PropertySource"}}, qw($PROPERTY_SOURCE_DETECTED);
1381
1382 $_PropertySource_VALUES{"SOURCE_DETECTED"} = $PROPERTY_SOURCE_DETECTED;
1383
1384 push @EXPORT_OK, qw($PROPERTY_SOURCE_USER);
1385 push @{$EXPORT_TAGS{"PropertySource"}}, qw($PROPERTY_SOURCE_USER);
1386
1387 $_PropertySource_VALUES{"SOURCE_USER"} = $PROPERTY_SOURCE_USER;
1388
1389 #copy symbols in PropertySource to constants
1390 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"PropertySource"}};
1391
1392
1393 # SWIG produces a sub-package for the Device "class", in this case named
1394 # Amanda::Device::Device.  For user convenience, we allow Amanda::Device->new(..) to
1395 # do the same thing.  This is a wrapper function, and not just a typeglob assignment,
1396 # because we want to get the right blessing.
1397 sub new {
1398     my $pkg = shift;
1399     Amanda::Device::Device->new(@_);
1400 }
1401 1;