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