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