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