1 # This file was automatically generated by SWIG (http://www.swig.org).
4 # Do not make changes to this file unless you know what you are doing--modify
5 # the SWIG interface file instead.
9 use base qw(DynaLoader);
10 require Amanda::MainLoop;
11 package Amanda::Xferc;
12 bootstrap Amanda::Xfer;
16 # ---------- BASE METHODS -------------
21 my ($classname,$obj) = @_;
22 return bless $obj, $classname;
32 my ($self,$field) = @_;
33 my $member_func = "swig_${field}_get";
34 $self->$member_func();
38 my ($self,$field,$newval) = @_;
39 my $member_func = "swig_${field}_set";
40 $self->$member_func($newval);
49 # ------- FUNCTION WRAPPERS --------
53 *xfer_new = *Amanda::Xferc::xfer_new;
54 *xfer_unref = *Amanda::Xferc::xfer_unref;
55 *xfer_get_status = *Amanda::Xferc::xfer_get_status;
56 *xfer_repr = *Amanda::Xferc::xfer_repr;
57 *xfer_start = *Amanda::Xferc::xfer_start;
58 *xfer_cancel = *Amanda::Xferc::xfer_cancel;
59 *xfer_element_unref = *Amanda::Xferc::xfer_element_unref;
60 *xfer_element_repr = *Amanda::Xferc::xfer_element_repr;
61 *same_elements = *Amanda::Xferc::same_elements;
62 *xfer_source_random = *Amanda::Xferc::xfer_source_random;
63 *xfer_source_random_get_seed = *Amanda::Xferc::xfer_source_random_get_seed;
64 *xfer_source_pattern = *Amanda::Xferc::xfer_source_pattern;
65 *xfer_source_fd = *Amanda::Xferc::xfer_source_fd;
66 *xfer_source_directtcp_listen = *Amanda::Xferc::xfer_source_directtcp_listen;
67 *xfer_source_directtcp_listen_get_addrs = *Amanda::Xferc::xfer_source_directtcp_listen_get_addrs;
68 *xfer_source_directtcp_connect = *Amanda::Xferc::xfer_source_directtcp_connect;
69 *xfer_filter_xor = *Amanda::Xferc::xfer_filter_xor;
70 *xfer_filter_process = *Amanda::Xferc::xfer_filter_process;
71 *xfer_dest_null = *Amanda::Xferc::xfer_dest_null;
72 *xfer_dest_buffer = *Amanda::Xferc::xfer_dest_buffer;
73 *xfer_dest_buffer_get = *Amanda::Xferc::xfer_dest_buffer_get;
74 *xfer_dest_fd = *Amanda::Xferc::xfer_dest_fd;
75 *xfer_dest_directtcp_listen = *Amanda::Xferc::xfer_dest_directtcp_listen;
76 *xfer_dest_directtcp_listen_get_addrs = *Amanda::Xferc::xfer_dest_directtcp_listen_get_addrs;
77 *xfer_dest_directtcp_connect = *Amanda::Xferc::xfer_dest_directtcp_connect;
78 *xfer_get_amglue_source = *Amanda::Xferc::xfer_get_amglue_source;
80 # ------- VARIABLE STUBS --------
84 *XFER_INIT = *Amanda::Xferc::XFER_INIT;
85 *XFER_START = *Amanda::Xferc::XFER_START;
86 *XFER_RUNNING = *Amanda::Xferc::XFER_RUNNING;
87 *XFER_DONE = *Amanda::Xferc::XFER_DONE;
88 *XMSG_INFO = *Amanda::Xferc::XMSG_INFO;
89 *XMSG_ERROR = *Amanda::Xferc::XMSG_ERROR;
90 *XMSG_DONE = *Amanda::Xferc::XMSG_DONE;
91 *XMSG_CANCEL = *Amanda::Xferc::XMSG_CANCEL;
92 *XMSG_PART_DONE = *Amanda::Xferc::XMSG_PART_DONE;
93 *XMSG_READY = *Amanda::Xferc::XMSG_READY;
101 Amanda::Xfer - the transfer architecture
105 use Amanda::MainLoop;
106 use Amanda::Xfer qw( :constants );
109 my $infd = POSIX::open("input", POSIX::O_RDONLY, 0);
110 my $outfd = POSIX::open("output", POSIX::O_CREAT|POSIX::O_WRONLY, 0640);
111 my $xfer = Amanda::Xfer->new([
112 Amanda::Xfer::Source::Fd->new($infd),
113 Amanda::Xfer::Dest::Fd->new($outfd)
116 my ($src, $xmsg, $xfer) = @_;
117 print "Message from $xfer: $xmsg\n"; # use stringify operations
118 if ($msg->{'type'} == $XMSG_DONE) {
119 Amanda::MainLoop::quit();
122 Amanda::MainLoop::run();
124 See L<http://wiki.zmanda.com/index.php/XFA> for background on the
125 transfer architecture.
127 =head1 Amanda::Xfer Objects
129 A new transfer is created with C<< Amanda::Xfer->new() >>, which takes
130 an arrayref giving the transfer elements which should compose the
133 The resulting object has the following methods:
139 Start this transfer. Processing takes place asynchronously, and messages will
140 begin queueing up immediately. If C<$cb> is given, then it is installed as the
141 callback for messages from this transfer. The callback receives three
142 arguments: the event source, the message, and a reference to the controlling
143 transfer. See the description of C<Amanda::Xfer::Msg>, below, for details.
145 There is no need to remove the source on completion of the transfer - that is
150 Stop transferring data. The transfer will send an C<XMSG_CANCEL>,
151 "drain" any buffered data as best it can, and then complete normally
152 with an C<XMSG_DONE>.
156 Get the transfer's status. The result will be one of C<$XFER_INIT>,
157 C<$XFER_START>, C<$XFER_RUNNING>, or C<$XFER_DONE>. These symbols are
158 available for import with the tag C<:constants>.
162 Return a string representation of this transfer, suitable for use in
163 debugging messages. This method is automatically invoked when a
164 transfer is interpolated into a string:
166 print "Starting $xfer\n";
170 Get the L<Amanda::MainLoop> event source through which messages will
171 be delivered for this transfer. Use its C<set_callback> method to
172 connect a perl sub for processing events.
174 Use of this method is deprecated; instead, pass a callback to the C<start>
175 method. If you set a callback via C<get_source>, then you I<must> C<remove>
176 the source when the transfer is complete!
180 =head1 Amanda::Xfer::Element objects
182 The individual transfer elements that compose a transfer are instances
183 of subclasses of Amanda::Xfer::Element. All such objects have a
184 C<repr()> method, similar to that for transfers, and support a similar
185 kind of string interpolation.
187 Note that the names of these classes contain the words "Source",
188 "Filter", and "Dest". This is merely suggestive of their intended
189 purpose -- there are no such abstract classes.
191 =head2 Transfer Sources
193 =head3 Amanda::Xfer::Source::Device (SERVER ONLY)
195 Amanda::Xfer::Source::Device->new($device);
197 This source reads data from a device. The device should already be
198 queued up for reading (C<< $device->seek_file(..) >>). The element
199 will read until the end of the device file.
201 =head3 Amanda::Xfer::Source::Fd
203 Amanda::Xfer::Source::Fd->new(fileno($fh));
205 This source reads data from a file descriptor. It reads until EOF,
206 but does not close the descriptor. Be careful not to let Perl close
209 =head3 Amanda::Xfer::Source::Holding (SERVER-ONLY)
211 Amanda::Xfer::Source::Holding->new($filename);
213 This source reads data from a holding file (see L<Amanda::Holding>).
214 If the transfer only consists of a C<Amanda::Xfer::Source::Holding>
215 and an C<Amanda::Xfer::Dest::Taper::Cacher> (with no filters), then the source
216 will call the destination's C<cache_inform> method so that it can use
217 holding chunks for a split-part cache.
219 =head3 Amanda::Xfer::Source::Random
221 Amanda::Xfer::Source::Random->new($length, $seed);
223 This source provides I<length> bytes of random data (or an unlimited
224 amount of data if I<length> is zero). C<$seed> is the seed used to
225 generate the random numbers; this seed can be used in a destination to
226 check for correct output.
228 If you need to string multiple transfers together into a coherent sequence of
229 random numbers, for example when testing the re-assembly of spanned dumps, call
231 my $seed = $src->get_seed();
233 to get the finishing seed for the source, then pass this to the source
234 constructor for the next transfer. When concatenated, the bytestreams from the
235 transfers will verify correctly using the original random seed.
237 =head3 Amanda::Xfer::Source::Pattern
239 Amanda::Xfer::Source::Pattern->new($length, $pattern);
241 This source provides I<length> bytes containing copies of
242 I<pattern>. If I<length> is zero, the source provides an unlimited
245 =head3 Amanda::Xfer::Source::Recovery (SERVER ONLY)
247 Amanda::Xfer::Source::Recovery->new($first_device);
249 This source reads a datastream composed of on-device files. Its constructor
250 takes a pointer to the first device that will be read from; this is used
251 internally to determine whether DirectTCP is supported.
253 The element sense C<$XMSG_READY> when it is ready for the first C<start_part>
254 invocation. Don't do anything with the device between the start of the
255 transfer and when the element sends an C<$XMSG_READY>.
257 The element contains no logic to decide I<which> files to assemble into the
258 datastream; instead, it relies on the caller to supply pre-positioned devices:
260 $src->start_part($device);
262 Once C<start_part> is called, the source will read until C<$device> produces an
263 EOF. As each part is completed, the element sends an C<$XMSG_PART_DONE>
264 L<Amanda::Xfer::Msg>, with the following keys:
266 size bytes read from the device
267 duration time spent reading
268 fileno the on-media file number from which the part was read
270 Call C<start_part> with C<$device = undef> to indicate that there are no more
273 To switch to a new device in mid-transfer, use C<use_device>:
275 $dest->use_device($device);
277 This method must be called with a device that is not yet started, and thus must
278 be called before the C<start_part> method is called with a new device.
280 =head3 Amanda::Xfer::Source::DirectTCPListen
282 Amanda::Xfer::Source::DirectTCPListen->new();
284 This source is for use when the transfer data will come in via DirectTCP, with
285 the data's I<source> connecting to the data's I<destination>. That is, the
286 data source is the connection initiator. Set up the transfer, and after
287 starting it, call this element's C<get_addrs> method to get an arrayref of ip/port pairs,
288 e.g., C<[ "192.168.4.5", 9924 ]>, all of which are listening for an incoming
289 data connection. Once a connection arrives, this element will read data from
290 it and send those data into the transfer.
292 my $addrs = $src->get_addrs();
294 =head3 Amanda::Xfer::Source::DirectTCPConnect
296 Amanda::Xfer::Source::DirectTCPConnect->new($addrs);
298 This source is for use when the transfer data will come in via DirectTCP, with
299 the data's I<destination> connecting to the the data's I<source>. That is, the
300 data destination is the connection initiator. The element connects to
301 C<$addrs> and reads the transfer data from the connection.
303 =head2 Transfer Filters
305 =head3 Amanda::Xfer::Filter:Process
307 Amanda::Xfer::Filter::Process->new([@args], $need_root, $log_stderr);
309 This filter will pipe data through the standard file descriptors of the
310 subprocess specified by C<@args>. If C<$need_root> is true, it will attempt to
311 change to uid 0 before executing the process. Standard output from the process
312 is redirected to the debug log. Note that the process is invoked directly, not
313 via a shell, so shell metacharcters (e.g., C<< 2>&1 >>) will not function as
314 expected. If C<$log_stderr> is set, then the filter's standard error is sent
315 to the debug log; otherwise, it is sent to the parent process's stderr.
317 =head3 Amanda::Xfer::Filter:Xor
319 Amanda::Xfer::Filter::Xor->new($key);
321 This filter applies a bytewise XOR operation to the data flowing
324 =head2 Transfer Destinations
326 =head3 Amanda::Xfer::Dest::Device (SERVER ONLY)
328 Amanda::Xfer::Dest::Device->new($device, $cancel_at_eom);
330 This source writes data to a device. The device should be ready for writing
331 (C<< $device->start_file(..) >>). On completion of the transfer, the file will
332 be finished. If an error occurs, or if C<$cancel_at_eom> is true and the
333 device signals LEOM, the transfer will be cancelled.
335 Note that this element does not apply any sort of stream buffering.
337 =head3 Amanda::Xfer::Dest::Buffer
339 Amanda::Xfer::Dest::Buffer->new($max_size);
341 This destination records data into an in-memory buffer which can grow up to
342 C<$max_size> bytes. The buffer is available with the C<get> method, which
343 returns a copy of the buffer as a perl scalar:
345 my $buf = $xdb->get();
347 =head3 Amanda::Xfer::Dest::DirectTCPListen
349 Amanda::Xfer::Dest::DirectTCPListen->new();
351 This destination is for use when the transfer data will come in via DirectTCP,
352 with the data's I<destination> connecting to the data's I<source>. That is,
353 the data destination is the connection initiator. Set up the transfer, and
354 after starting it, call this element's C<get_addrs> method to get an arrayref
355 of ip/port pairs, e.g., C<[ "192.168.4.5", 9924 ]>, all of which are listening
356 for an incoming data connection. Once a connection arrives, this element will
357 write the transfer data to it.
359 my $addrs = $src->get_addrs();
361 =head3 Amanda::Xfer::Dest::DirectTCPConnect
363 Amanda::Xfer::Dest::DirectTCPConnect->new($addrs);
365 This destination is for use when the transfer data will come in via DirectTCP,
366 with the data's I<source> connecting to the the data's I<destination>. That
367 is, the data source is the connection initiator. The element connects to
368 C<$addrs> and writes the transfer data to the connection.
370 =head3 Amanda::Xfer::Dest::Fd
372 Amanda::Xfer::Dest::Fd->new(fileno($fh));
374 This destination writes data to a file descriptor. The file is not
375 closed after the transfer is completed. Be careful not to let Perl
376 close the file for you!
378 =head3 Amanda::Xfer::Dest::Null
380 Amanda::Xfer::Dest::Null->new($seed);
382 This destination discards the data it receives. If C<$seed> is
383 nonzero, then the element will validate that it receives the data that
384 C<Amanda::Xfer::Source::Random> produced with the same seed. No
385 validation is performed if C<$seed> is zero.
387 =head3 Amanda::Xfer::Dest::Taper (SERVER ONLY)
389 This is the parent class to C<Amanda::Xfer::Dest::Taper::Cacher> and
390 C<Amanda::Xfer::Dest::Taper::DirectTCP>. These subclasses allow a single
391 transfer to write to multiple files (parts) on a device, and even spread those
392 parts over multiple devices, without interrupting the transfer itself.
394 The subclass constructors all take a C<$first_device>, which should be
395 configured but not yet started; and a C<$part_size> giving the maximum size of
396 each part. Note that this value may be rounded up internally as necessary.
398 When a transfer using a taper destination element is first started, no data is
399 transfered until the element's C<start_part> method is called:
401 $dest->start_part($retry_part);
403 where C<$device> is the device to which the part should be written. The device
404 should have a file open and ready to write (that is,
405 C<< $device->start_file(..) >> has already been called). If C<$retry_part> is
406 true, then the previous, unsuccessful part will be retried.
408 As each part is completed, the element sends an C<$XMSG_PART_DONE>
409 C<Amanda::Xfer::Msg>, with the following keys:
411 successful true if the part was written successfully
412 eof recipient should not call start_part again
413 eom this volume is at EOM; a new volume is required
414 size bytes written to volume
415 duration time spent writing, not counting changer ops, etc.
416 partnum the zero-based number of this part in the overall dumpfile
417 fileno the on-media file number used for this part, or 0 if no file
420 If C<eom> is true, then the caller should find a new volume before
421 continuing. If C<eof> is not true, then C<start_part> should be called
422 again, with C<$retry_part = !successful>. Note that it is possible
423 for some destinations to write a portion of a part successfully,
424 but still stop at EOM. That is, C<eom> does not necessarily imply
427 To switch to a new device in mid-transfer, use C<use_device>:
429 $dest->use_device($device);
431 This method must be called with a device that is not yet started.
433 If neither the memory nor disk caches are in use, but the dumpfile is
434 available on disk, then the C<cache_inform> method allows the element
435 to use that on-disk data to support retries. This is intended to
436 support transfers from Amanda's holding disk (see
437 C<Amanda::Xfer::Source::Holding>), but may be useful for other
440 $dest->cache_inform($filename, $offset, $length);
442 This function indicates that C<$filename> contains C<$length> bytes of
443 data, beginning at offset C<$offset> from the beginning of the file.
444 These bytes are assumed to follow immediately after any bytes
445 previously specified to C<cache_inform>. That is, no gaps or overlaps
446 are allowed in the data stream described to C<cache_inform>.
447 Furthermore, the location of each byte must be specified to this
448 method I<before> it is sent through the transfer.
450 $dest->get_part_bytes_written();
452 This function returns the number of bytes written for the current part
455 =head3 Amanda::Xfer::Dest::Taper::Splitter
457 Amanda::Xfer::Dest::Taper::Splitter->new($first_device, $max_memory,
458 $part_size, $expect_cache_inform);
460 This class splits a data stream into parts on the storage media. It is for use
461 when the device supports LEOM, when the dump is already available on disk
462 (C<cache_inform>), or when no caching is desired. It does not cache parts, so
463 it can only retry a partial part if the transfer source is calling
464 C<cache_inform>. If the element is used with devices that do not support LEOM,
465 then it will cancel the entire transfer if the device reaches EOM and
466 C<cache_inform> is not in use. Set C<$expect_cache_inform> appropriately based
467 on the incoming data.
469 The C<$part_size> and C<$first_device> parameters are described above for
470 C<Amanda::Xfer::Dest::Taper>.
472 =head3 Amanda::Xfer::Dest::Taper::Cacher
474 Amanda::Xfer::Dest::Taper::Cacher->new($first_device, $max_memory,
475 $part_size, $use_mem_cache, $disk_cache_dirname);
477 This class is similar to the splitter, but caches data from each part in one of
478 a variety of ways to support "rewinding" to retry a failed part (e.g., one that
479 does not fit on a device). It assumes that when a device reaches EOM while
480 writing, the entire on-volume file is corrupt - that is, that the device does
481 not support logical EOM. The class does not support C<cache_inform>.
483 The C<$part_size> and C<$first_device> parameters are described above for
484 C<Amanda::Xfer::Dest::Taper>.
486 If C<$use_mem_cache> is true, each part will be cached in memory (using
487 C<$part_size> bytes of memory; plan accordingly!). If C<$disk_cache_dirname>
488 is defined, then each part will be cached on-disk in a file in this directory.
489 It is an error to specify both in-memory and on-disk caching. If neither
490 option is specified, the element will operate successfully, but will not be
491 able to retry a part, and will cancel the transfer if a part fails.
493 =head3 Amanda::Xfer::Dest::Taper::DirectTCP
495 Amanda::Xfer::Dest::Taper::DirectTCP->new($first_device, $part_size);
497 This class uses the Device API DirectTCP methods to write data to a device via
498 DirectTCP. Since all DirectTCP devices support logical EOM, this class does
499 not cache any data, and will never re-start an unsuccessful part.
501 As state above, C<$first_device> must not be started when C<new> is called.
502 Furthermore, no use of that device is allowed until the element sens an
503 C<$XMSG_READY> to indicate that it is finished with the device. The
504 C<start_part> method must not be called until this method is received either.
506 =head1 Amanda::Xfer::Msg objects
508 Messages are simple hashrefs, with a few convenience methods. Like
509 transfers, they have a C<repr()> method that formats the message
510 nicely, and is available through string interpolation:
512 print "Received message $msg\n";
514 The canonical description of the message types and keys is in
515 C<xfer-src/xmsg.h>, and is not duplicated here. Every message has the
516 following basic keys.
522 The message type -- one of the C<xmsg_type> constants available from
523 the import tag C<:constants>.
527 The transfer element that sent the message.
531 The version of the message. This is used to support extensibility of
536 Additional keys are described in the documentation for the elements
537 that use them. All keys are listed in C<xfer-src/xmsg.h>.
543 push @EXPORT_OK, qw(xfer_status_to_string);
544 push @{$EXPORT_TAGS{"xfer_status"}}, qw(xfer_status_to_string);
546 my %_xfer_status_VALUES;
547 #Convert an enum value to a single string
548 sub xfer_status_to_string {
551 for my $k (keys %_xfer_status_VALUES) {
552 my $v = $_xfer_status_VALUES{$k};
554 #is this a matching flag?
555 if ($enumval == $v) {
560 #default, just return the number
564 push @EXPORT_OK, qw($XFER_INIT);
565 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_INIT);
567 $_xfer_status_VALUES{"XFER_INIT"} = $XFER_INIT;
569 push @EXPORT_OK, qw($XFER_START);
570 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_START);
572 $_xfer_status_VALUES{"XFER_START"} = $XFER_START;
574 push @EXPORT_OK, qw($XFER_RUNNING);
575 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_RUNNING);
577 $_xfer_status_VALUES{"XFER_RUNNING"} = $XFER_RUNNING;
579 push @EXPORT_OK, qw($XFER_DONE);
580 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_DONE);
582 $_xfer_status_VALUES{"XFER_DONE"} = $XFER_DONE;
584 #copy symbols in xfer_status to constants
585 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"xfer_status"}};
587 push @EXPORT_OK, qw(xmsg_type_to_string);
588 push @{$EXPORT_TAGS{"xmsg_type"}}, qw(xmsg_type_to_string);
590 my %_xmsg_type_VALUES;
591 #Convert an enum value to a single string
592 sub xmsg_type_to_string {
595 for my $k (keys %_xmsg_type_VALUES) {
596 my $v = $_xmsg_type_VALUES{$k};
598 #is this a matching flag?
599 if ($enumval == $v) {
604 #default, just return the number
608 push @EXPORT_OK, qw($XMSG_INFO);
609 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_INFO);
611 $_xmsg_type_VALUES{"XMSG_INFO"} = $XMSG_INFO;
613 push @EXPORT_OK, qw($XMSG_ERROR);
614 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_ERROR);
616 $_xmsg_type_VALUES{"XMSG_ERROR"} = $XMSG_ERROR;
618 push @EXPORT_OK, qw($XMSG_DONE);
619 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_DONE);
621 $_xmsg_type_VALUES{"XMSG_DONE"} = $XMSG_DONE;
623 push @EXPORT_OK, qw($XMSG_CANCEL);
624 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_CANCEL);
626 $_xmsg_type_VALUES{"XMSG_CANCEL"} = $XMSG_CANCEL;
628 push @EXPORT_OK, qw($XMSG_PART_DONE);
629 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_PART_DONE);
631 $_xmsg_type_VALUES{"XMSG_PART_DONE"} = $XMSG_PART_DONE;
633 push @EXPORT_OK, qw($XMSG_READY);
634 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_READY);
636 $_xmsg_type_VALUES{"XMSG_READY"} = $XMSG_READY;
638 #copy symbols in xmsg_type to constants
639 push @{$EXPORT_TAGS{"constants"}}, @{$EXPORT_TAGS{"xmsg_type"}};
641 sub xfer_start_with_callback {
642 my ($xfer, $cb) = @_;
644 my $releasing_cb = sub {
645 my ($src, $msg, $xfer) = @_;
646 my $done = $msg->{'type'} == $XMSG_DONE;
647 $src->remove() if $done;
649 $cb = undef if $done; # break potential reference loop
651 $xfer->get_source()->set_callback($releasing_cb);
656 sub xfer_set_callback {
657 my ($xfer, $cb) = @_;
659 my $releasing_cb = sub {
660 my ($src, $msg, $xfer) = @_;
661 my $done = $msg->{'type'} == $XMSG_DONE;
662 $src->remove() if $done;
664 $cb = undef if $done; # break potential reference loop
666 $xfer->get_source()->set_callback($releasing_cb);
668 $xfer->get_source()->set_callback(undef);
672 package Amanda::Xfer::Xfer;
678 Amanda::Xfer::xfer_new(@_);
680 *DESTROY = *Amanda::Xfer::xfer_unref;
682 use overload '""' => sub { $_[0]->repr(); };
684 use overload '==' => sub { Amanda::Xfer::same_elements($_[0], $_[1]); };
685 use overload '!=' => sub { not Amanda::Xfer::same_elements($_[0], $_[1]); };
686 *repr = *Amanda::Xfer::xfer_repr;
687 *get_status = *Amanda::Xfer::xfer_get_status;
688 *get_source = *Amanda::Xfer::xfer_get_amglue_source;
689 *start = *Amanda::Xfer::xfer_start_with_callback;
690 *set_callback = *Amanda::Xfer::xfer_set_callback;
691 *cancel = *Amanda::Xfer::xfer_cancel;
693 package Amanda::Xfer::Element;
694 *DESTROY = *Amanda::Xfer::xfer_element_unref;
696 use overload '""' => sub { $_[0]->repr(); };
698 use overload '==' => sub { Amanda::Xfer::same_elements($_[0], $_[1]); };
699 use overload '!=' => sub { not Amanda::Xfer::same_elements($_[0], $_[1]); };
700 *repr = *Amanda::Xfer::xfer_element_repr;
702 package Amanda::Xfer::Element::Glue;
705 @ISA = qw( Amanda::Xfer::Element );
707 package Amanda::Xfer::Source::Fd;
710 @ISA = qw( Amanda::Xfer::Element );
716 Amanda::Xfer::xfer_source_fd(@_);
719 package Amanda::Xfer::Source::Random;
722 @ISA = qw( Amanda::Xfer::Element );
728 Amanda::Xfer::xfer_source_random(@_);
730 *get_seed = *Amanda::Xfer::xfer_source_random_get_seed;
732 package Amanda::Xfer::Source::DirectTCPListen;
735 @ISA = qw( Amanda::Xfer::Element );
741 Amanda::Xfer::xfer_source_directtcp_listen(@_);
743 *get_addrs = *Amanda::Xfer::xfer_source_directtcp_listen_get_addrs;
745 package Amanda::Xfer::Source::DirectTCPConnect;
748 @ISA = qw( Amanda::Xfer::Element );
754 Amanda::Xfer::xfer_source_directtcp_connect(@_);
757 package Amanda::Xfer::Source::Pattern;
760 @ISA = qw( Amanda::Xfer::Element );
766 Amanda::Xfer::xfer_source_pattern(@_);
769 package Amanda::Xfer::Filter::Xor;
772 @ISA = qw( Amanda::Xfer::Element );
778 Amanda::Xfer::xfer_filter_xor(@_);
781 package Amanda::Xfer::Filter::Process;
784 @ISA = qw( Amanda::Xfer::Element );
790 Amanda::Xfer::xfer_filter_process(@_);
793 package Amanda::Xfer::Dest::Fd;
796 @ISA = qw( Amanda::Xfer::Element );
802 Amanda::Xfer::xfer_dest_fd(@_);
805 package Amanda::Xfer::Dest::Null;
808 @ISA = qw( Amanda::Xfer::Element );
814 Amanda::Xfer::xfer_dest_null(@_);
817 package Amanda::Xfer::Dest::Buffer;
820 @ISA = qw( Amanda::Xfer::Element );
826 Amanda::Xfer::xfer_dest_buffer(@_);
828 *get = *Amanda::Xfer::xfer_dest_buffer_get;
830 package Amanda::Xfer::Dest::DirectTCPListen;
833 @ISA = qw( Amanda::Xfer::Element );
839 Amanda::Xfer::xfer_dest_directtcp_listen(@_);
841 *get_addrs = *Amanda::Xfer::xfer_dest_directtcp_listen_get_addrs;
843 package Amanda::Xfer::Dest::DirectTCPConnect;
846 @ISA = qw( Amanda::Xfer::Element );
852 Amanda::Xfer::xfer_dest_directtcp_connect(@_);
855 package Amanda::Xfer::Msg;
858 use overload '""' => sub { $_[0]->repr(); };
862 local $Data::Dumper::Indent = 0;
863 local $Data::Dumper::Terse = 1;
864 local $Data::Dumper::Useqq = 1;
866 my $typestr = Amanda::Xfer::xmsg_type_to_string($self->{'type'});
867 my $str = "{ type => \$$typestr, elt => $self->{'elt'}, version => $self->{'version'},";
869 my %skip = ( "type" => 1, "elt" => 1, "version" => 1 );
870 for my $k (keys %$self) {
872 $str .= " $k => " . Dumper($self->{$k}) . ",";
875 # strip the trailing comma and add a closing brace
881 package Amanda::Xfer;
883 # make Amanda::Xfer->new equivalent to Amanda::Xfer::Xfer->new (don't
884 # worry, the blessings work out just fine)
885 *new = *Amanda::Xfer::Xfer::new;
887 # try to load Amanda::XferServer, which is server-only. If it's not found, then
888 # its classes just remain undefined.
891 if (Amanda::Util::built_with_component("server")) {
892 eval "use Amanda::XferServer;";