Imported Upstream version 3.1.0
[debian/amanda] / perl / Amanda / Xfer.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::Xfer;
8 use base qw(Exporter);
9 use base qw(DynaLoader);
10 require Amanda::MainLoop;
11 package Amanda::Xferc;
12 bootstrap Amanda::Xfer;
13 package Amanda::Xfer;
14 @EXPORT = qw();
15
16 # ---------- BASE METHODS -------------
17
18 package Amanda::Xfer;
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::Xfer;
52
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;
79
80 # ------- VARIABLE STUBS --------
81
82 package Amanda::Xfer;
83
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;
94
95 @EXPORT_OK = ();
96 %EXPORT_TAGS = ();
97
98
99 =head1 NAME
100
101 Amanda::Xfer - the transfer architecture
102
103 =head1 SYNOPSIS
104
105   use Amanda::MainLoop;
106   use Amanda::Xfer qw( :constants );
107   use POSIX;
108
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)
114   ]);
115   $xfer->start(sub {
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();
120       }
121   });
122   Amanda::MainLoop::run();
123
124 See L<http://wiki.zmanda.com/index.php/XFA> for background on the
125 transfer architecture.
126
127 =head1 Amanda::Xfer Objects
128
129 A new transfer is created with C<< Amanda::Xfer->new() >>, which takes
130 an arrayref giving the transfer elements which should compose the
131 transfer.
132
133 The resulting object has the following methods:
134
135 =over
136
137 =item start($cb)
138
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.
144
145 There is no need to remove the source on completion of the transfer - that is
146 handled for you.
147
148 =item cancel()
149
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>.
153
154 =item get_status()
155
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>.
159
160 =item repr()
161
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:
165
166   print "Starting $xfer\n";
167
168 =item get_source()
169
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. 
173
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!
177
178 =back
179
180 =head1 Amanda::Xfer::Element objects
181
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.
186
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.
190
191 =head2 Transfer Sources
192
193 =head3 Amanda::Xfer::Source::Device (SERVER ONLY)
194
195   Amanda::Xfer::Source::Device->new($device);
196
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.
200
201 =head3 Amanda::Xfer::Source::Fd
202
203   Amanda::Xfer::Source::Fd->new(fileno($fh));
204
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
207 the file for you!
208
209 =head3 Amanda::Xfer::Source::Holding (SERVER-ONLY)
210
211   Amanda::Xfer::Source::Holding->new($filename);
212
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::Splitter> (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.
218
219 =head3 Amanda::Xfer::Source::Random
220
221   Amanda::Xfer::Source::Random->new($length, $seed);
222
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.
227
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
230
231   my $seed = $src->get_seed();
232
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.
236
237 =head3 Amanda::Xfer::Source::Pattern
238
239   Amanda::Xfer::Source::Pattern->new($length, $pattern);
240
241 This source provides I<length> bytes containing copies of
242 I<pattern>. If I<length> is zero, the source provides an unlimited
243 number of bytes.
244
245 =head3 Amanda::Xfer::Source::Recovery (SERVER ONLY)
246
247   Amanda::Xfer::Source::Recovery->new($first_device);
248
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.
252
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>.
256
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:
259
260   $src->start_part($device);
261
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:
265
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
269
270 Call C<start_part> with C<$device = undef> to indicate that there are no more
271 parts.
272
273 To switch to a new device in mid-transfer, use C<use_device>:
274
275   $dest->use_device($device);
276
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.
279
280 =head3 Amanda::Xfer::Source::DirectTCPListen
281
282   Amanda::Xfer::Source::DirectTCPListen->new();
283
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>.  Set up the
286 transfer, and after starting it, call its C<get_addrs> method to get an
287 arrayref of ip/port pairs, e.g., C<[ "192.168.4.5", 9924 ]>, all of which are
288 listening for an incoming data connection.  Once a connection arrives, this
289 element will read data from it and send those data into the transfer.
290
291   my $addrs = $src->get_addrs();
292
293 =head3 Amanda::Xfer::Source::DirectTCPConnect
294
295   Amanda::Xfer::Source::DirectTCPConnect->new($addrs);
296
297 This source is for use when the transfer data will come in via DirectTCP, with
298 the data's I<destination> connecting to the the data's I<source>.  The element
299 connects to C<$addrs> and reads the transfer data from the connection.
300
301 =head2 Transfer Filters
302
303 =head3 Amanda::Xfer::Filter:Process
304
305   Amanda::Xfer::Filter::Process->new([@args], $need_root);
306
307 This filter will pipe data through the standard file descriptors of the
308 subprocess specified by C<@args>.  If C<$need_root> is true, it will attempt to
309 change to uid 0 before executing the process.  Standard output from the process
310 is redirected to the debug log.  Note that the process is invoked directly, not
311 via a shell, so shell metacharcters (e.g., C<< 2>&1 >>) will not function as
312 expected.
313
314 =head3 Amanda::Xfer::Filter:Xor
315
316   Amanda::Xfer::Filter::Xor->new($key);
317
318 This filter applies a bytewise XOR operation to the data flowing
319 through it.
320
321 =head2 Transfer Destinations
322
323 =head3 Amanda::Xfer::Dest::Device (SERVER ONLY)
324
325   Amanda::Xfer::Dest::Device->new($device, $max_memory);
326
327 This source writes data to a device.  The device should be ready for
328 writing (C<< $device->start_file(..) >>).  No more than C<$max_memory>
329 will be used for buffers.  Use zero for the default buffer size.  On
330 completion of the transfer, the file will be finished.
331
332 =head3 Amanda::Xfer::Dest::Buffer
333
334   Amanda::Xfer::Dest::Buffer->new($max_size);
335
336 This destination records data into an in-memory buffer which can grow up to
337 C<$max_size> bytes.  The buffer is available with the C<get> method, which
338 returns a copy of the buffer as a perl scalar:
339
340     my $buf = $xdb->get();
341
342 =head3 Amanda::Xfer::Dest::DirectTCPListen
343
344   Amanda::Xfer::Dest::DirectTCPListen->new();
345
346 This destination is for use when the transfer data will come in via DirectTCP,
347 with the data's I<destination> connecting to the data's I<source>.  Set up the
348 transfer, and after starting it, call this element's C<get_addrs> method to get
349 an arrayref of ip/port pairs, e.g., C<[ "192.168.4.5", 9924 ]>, all of which
350 are listening for an incoming data connection.  Once a connection arrives, this
351 element will write the transfer data to it.
352
353   my $addrs = $src->get_addrs();
354
355 =head3 Amanda::Xfer::Dest::DirectTCPConnect
356
357   Amanda::Xfer::Dest::DirectTCPConnect->new($addrs);
358
359 This destination is for use when the transfer data will come in via DirectTCP,
360 with the data's I<source> connecting to the the data's I<destination>.  The
361 element connects to C<$addrs> and writes the transfer data to the connection.
362
363 =head3 Amanda::Xfer::Dest::Fd
364
365   Amanda::Xfer::Dest::Fd->new(fileno($fh));
366
367 This destination writes data to a file descriptor.  The file is not
368 closed after the transfer is completed.  Be careful not to let Perl
369 close the file for you!
370
371 =head3 Amanda::Xfer::Dest::Null
372
373   Amanda::Xfer::Dest::Null->new($seed);
374
375 This destination discards the data it receives.  If C<$seed> is
376 nonzero, then the element will validate that it receives the data that
377 C<Amanda::Xfer::Source::Random> produced with the same seed.  No
378 validation is performed if C<$seed> is zero.
379
380 =head3 Amanda::Xfer::Dest::Taper (SERVER ONLY)
381
382 This is the parent class to C<Amanda::Xfer::Dest::Taper::Splitter> and
383 C<Amanda::Xfer::Dest::Taper::DirectTCP>. These subclasses allow a single
384 transfer to write to multiple files (parts) on a device, and even spread those
385 parts over multiple devices, without interrupting the transfer itself.
386
387 The subclass constructors all take a C<$first_device>, which should be
388 configured but not yet started; and a C<$part_size> giving the maximum size of
389 each part.  Note that this value may be rounded up internally as necessary.
390
391 When a transfer using a taper destination element is first started, no data is
392 transfered until the element's C<start_part> method is called:
393
394   $dest->start_part($retry_part);
395
396 where C<$device> is the device to which the part should be written.  The device
397 should have a file open and ready to write (that is, 
398 C<< $device->start_file(..) >> has already been called).  If C<$retry_part> is
399 true, then the previous, unsuccessful part will be retried.
400
401 As each part is completed, the element sends an C<$XMSG_PART_DONE>
402 C<Amanda::Xfer::Msg>, with the following keys:
403
404  successful true if the part was written successfully
405  eof        recipient should not call start_part again
406  eom        this volume is at EOM; a new volume is required
407  size       bytes written to volume
408  duration   time spent writing, not counting changer ops, etc.
409  partnum    the zero-based number of this part in the overall dumpfile
410  fileno     the on-media file number used for this part, or 0 if no file
411             was used
412
413 If C<eom> is true, then the caller should find a new volume before
414 continuing.  If C<eof> is not true, then C<start_part> should be called
415 again, with C<$retry_part = !successful>.  Note that it is possible
416 for some destinations to write a portion of a part successfully,
417 but still stop at EOM.  That is, C<eom> does not necessarily imply
418 C<!successful>.
419
420 To switch to a new device in mid-transfer, use C<use_device>:
421
422   $dest->use_device($device);
423
424 This method must be called with a device that is not yet started.
425
426 If neither the memory nor disk caches are in use, but the dumpfile is
427 available on disk, then the C<cache_inform> method allows the element
428 to use that on-disk data to support retries.  This is intended to
429 support transfers from Amanda's holding disk (see
430 C<Amanda::Xfer::Source::Holding>), but may be useful for other
431 purposes.
432
433   $dest->cache_inform($filename, $offset, $length);
434
435 This function indicates that C<$filename> contains C<$length> bytes of
436 data, beginning at offset C<$offset> from the beginning of the file.
437 These bytes are assumed to follow immediately after any bytes
438 previously specified to C<cache_inform>.  That is, no gaps or overlaps
439 are allowed in the data stream described to C<cache_inform>.
440 Furthermore, the location of each byte must be specified to this
441 method I<before> it is sent through the transfer.
442
443   $dest->get_part_bytes_written();
444
445 This function returns the number of bytes written for the current part
446 to the device.
447
448 =head3 Amanda::Xfer::Dest::Taper::Splitter
449
450   Amanda::Xfer::Dest::Taper::Splitter->new($first_device, $max_memory,
451                         $part_size, $use_mem_cache, $disk_cache_dirname);
452
453 This class caches data from each part in one of a variety of ways, and supports
454 "rewinding" to retry a failed part (e.g., one that does not fit on a device).
455 It assumes that when a device reaches EOM while writing, the entire file is
456 corrupt.  It does not (yet) support logical EOM, which can render this
457 assumption incorrect.
458
459 The C<$first_device> is used to calculate some internal constants, notably the
460 slab size, based on the device characteristics.   Subsequent devices must have
461 the same block size.  The C<$part_size> and C<$first_device> parameters are
462 described above.
463
464 If C<$use_mem_cache> is true, each part will be cached in memory (using
465 C<$part_size> bytes of memory; plan accordingly!).  If C<$disk_cache_dirname>
466 is defined, then each part will be cached on-disk in a file in this directory.
467 It is an error to specify both in-memory and on-disk caching.  If neither
468 option is specified, the element will operate successfully, but will not be
469 able to retry a part unless C<cache_inform> has been used properly (see above).
470
471 =head3 Amanda::Xfer::Dest::Taper::DirectTCP
472
473   Amanda::Xfer::Dest::Taper::DirectTCP->new($first_device, $part_size);
474
475 This class uses the Device API DirectTCP methods to write data to a device via
476 DirectTCP.  Since all DirectTCP devices support logical EOM, this class does
477 not cache any data, and will never re-start an unsuccessful part.
478
479 As state above, C<$first_device> must not be started when C<new> is called.
480 Furthermore, no use of that device is allowed until the element sens an
481 C<$XMSG_READY> to indicate that it is finished with the device.  The
482 C<start_part> method must not be called until this method is received either.
483
484 =head1 Amanda::Xfer::Msg objects
485
486 Messages are simple hashrefs, with a few convenience methods.  Like
487 transfers, they have a C<repr()> method that formats the message
488 nicely, and is available through string interpolation:
489
490   print "Received message $msg\n";
491
492 The canonical description of the message types and keys is in
493 C<xfer-src/xmsg.h>, and is not duplicated here.  Every message has the
494 following basic keys.
495
496 =over
497
498 =item type
499
500 The message type -- one of the C<xmsg_type> constants available from
501 the import tag C<:constants>.
502
503 =item elt
504
505 The transfer element that sent the message.
506
507 =item version
508
509 The version of the message.  This is used to support extensibility of
510 the protocol.
511
512 =back
513
514 Additional keys are described in the documentation for the elements
515 that use them.  All keys are listed in C<xfer-src/xmsg.h>.
516
517 =cut
518
519
520
521 push @EXPORT_OK, qw(xfer_status_to_string);
522 push @{$EXPORT_TAGS{"xfer_status"}}, qw(xfer_status_to_string);
523
524 my %_xfer_status_VALUES;
525 #Convert an enum value to a single string
526 sub xfer_status_to_string {
527     my ($enumval) = @_;
528
529     for my $k (keys %_xfer_status_VALUES) {
530         my $v = $_xfer_status_VALUES{$k};
531
532         #is this a matching flag?
533         if ($enumval == $v) {
534             return $k;
535         }
536     }
537
538 #default, just return the number
539     return $enumval;
540 }
541
542 push @EXPORT_OK, qw($XFER_INIT);
543 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_INIT);
544
545 $_xfer_status_VALUES{"XFER_INIT"} = $XFER_INIT;
546
547 push @EXPORT_OK, qw($XFER_START);
548 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_START);
549
550 $_xfer_status_VALUES{"XFER_START"} = $XFER_START;
551
552 push @EXPORT_OK, qw($XFER_RUNNING);
553 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_RUNNING);
554
555 $_xfer_status_VALUES{"XFER_RUNNING"} = $XFER_RUNNING;
556
557 push @EXPORT_OK, qw($XFER_DONE);
558 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_DONE);
559
560 $_xfer_status_VALUES{"XFER_DONE"} = $XFER_DONE;
561
562 #copy symbols in xfer_status to constants
563 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"xfer_status"}};
564
565 push @EXPORT_OK, qw(xmsg_type_to_string);
566 push @{$EXPORT_TAGS{"xmsg_type"}}, qw(xmsg_type_to_string);
567
568 my %_xmsg_type_VALUES;
569 #Convert an enum value to a single string
570 sub xmsg_type_to_string {
571     my ($enumval) = @_;
572
573     for my $k (keys %_xmsg_type_VALUES) {
574         my $v = $_xmsg_type_VALUES{$k};
575
576         #is this a matching flag?
577         if ($enumval == $v) {
578             return $k;
579         }
580     }
581
582 #default, just return the number
583     return $enumval;
584 }
585
586 push @EXPORT_OK, qw($XMSG_INFO);
587 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_INFO);
588
589 $_xmsg_type_VALUES{"XMSG_INFO"} = $XMSG_INFO;
590
591 push @EXPORT_OK, qw($XMSG_ERROR);
592 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_ERROR);
593
594 $_xmsg_type_VALUES{"XMSG_ERROR"} = $XMSG_ERROR;
595
596 push @EXPORT_OK, qw($XMSG_DONE);
597 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_DONE);
598
599 $_xmsg_type_VALUES{"XMSG_DONE"} = $XMSG_DONE;
600
601 push @EXPORT_OK, qw($XMSG_CANCEL);
602 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_CANCEL);
603
604 $_xmsg_type_VALUES{"XMSG_CANCEL"} = $XMSG_CANCEL;
605
606 push @EXPORT_OK, qw($XMSG_PART_DONE);
607 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_PART_DONE);
608
609 $_xmsg_type_VALUES{"XMSG_PART_DONE"} = $XMSG_PART_DONE;
610
611 push @EXPORT_OK, qw($XMSG_READY);
612 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_READY);
613
614 $_xmsg_type_VALUES{"XMSG_READY"} = $XMSG_READY;
615
616 #copy symbols in xmsg_type to constants
617 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"xmsg_type"}};
618
619 sub xfer_start_with_callback {
620     my ($xfer, $cb) = @_;
621     if (defined $cb) {
622         my $releasing_cb = sub {
623             my ($src, $msg, $xfer) = @_;
624             my $done = $msg->{'type'} == $XMSG_DONE;
625             $src->remove() if $done;
626             $cb->(@_);
627             $cb = undef if $done; # break potential reference loop
628         };
629         $xfer->get_source()->set_callback($releasing_cb);
630     }
631     xfer_start($xfer);
632 }
633
634 package Amanda::Xfer::Xfer;
635
636 sub new { 
637     my $pkg = shift;
638
639
640     Amanda::Xfer::xfer_new(@_);
641 }
642 *DESTROY = *Amanda::Xfer::xfer_unref;
643
644 use overload '""' => sub { $_[0]->repr(); };
645
646 use overload '==' => sub {     Amanda::Xfer::same_elements($_[0], $_[1]); };
647 use overload '!=' => sub { not Amanda::Xfer::same_elements($_[0], $_[1]); };
648 *repr = *Amanda::Xfer::xfer_repr;
649 *get_status = *Amanda::Xfer::xfer_get_status;
650 *get_source = *Amanda::Xfer::xfer_get_amglue_source;
651 *start = *Amanda::Xfer::xfer_start_with_callback;
652 *cancel = *Amanda::Xfer::xfer_cancel;
653
654 package Amanda::Xfer::Element;
655 *DESTROY = *Amanda::Xfer::xfer_element_unref;
656
657 use overload '""' => sub { $_[0]->repr(); };
658
659 use overload '==' => sub {     Amanda::Xfer::same_elements($_[0], $_[1]); };
660 use overload '!=' => sub { not Amanda::Xfer::same_elements($_[0], $_[1]); };
661 *repr = *Amanda::Xfer::xfer_element_repr;
662
663 package Amanda::Xfer::Element::Glue;
664
665 use vars qw(@ISA);
666 @ISA = qw( Amanda::Xfer::Element );
667
668 package Amanda::Xfer::Source::Fd;
669
670 use vars qw(@ISA);
671 @ISA = qw( Amanda::Xfer::Element );
672
673 sub new { 
674     my $pkg = shift;
675
676
677     Amanda::Xfer::xfer_source_fd(@_);
678 }
679
680 package Amanda::Xfer::Source::Random;
681
682 use vars qw(@ISA);
683 @ISA = qw( Amanda::Xfer::Element );
684
685 sub new { 
686     my $pkg = shift;
687
688
689     Amanda::Xfer::xfer_source_random(@_);
690 }
691 *get_seed = *Amanda::Xfer::xfer_source_random_get_seed;
692
693 package Amanda::Xfer::Source::DirectTCPListen;
694
695 use vars qw(@ISA);
696 @ISA = qw( Amanda::Xfer::Element );
697
698 sub new { 
699     my $pkg = shift;
700
701
702     Amanda::Xfer::xfer_source_directtcp_listen(@_);
703 }
704 *get_addrs = *Amanda::Xfer::xfer_source_directtcp_listen_get_addrs;
705
706 package Amanda::Xfer::Source::DirectTCPConnect;
707
708 use vars qw(@ISA);
709 @ISA = qw( Amanda::Xfer::Element );
710
711 sub new { 
712     my $pkg = shift;
713
714
715     Amanda::Xfer::xfer_source_directtcp_connect(@_);
716 }
717
718 package Amanda::Xfer::Source::Pattern;
719
720 use vars qw(@ISA);
721 @ISA = qw( Amanda::Xfer::Element );
722
723 sub new { 
724     my $pkg = shift;
725
726
727     Amanda::Xfer::xfer_source_pattern(@_);
728 }
729
730 package Amanda::Xfer::Filter::Xor;
731
732 use vars qw(@ISA);
733 @ISA = qw( Amanda::Xfer::Element );
734
735 sub new { 
736     my $pkg = shift;
737
738
739     Amanda::Xfer::xfer_filter_xor(@_);
740 }
741
742 package Amanda::Xfer::Filter::Process;
743
744 use vars qw(@ISA);
745 @ISA = qw( Amanda::Xfer::Element );
746
747 sub new { 
748     my $pkg = shift;
749
750
751     Amanda::Xfer::xfer_filter_process(@_);
752 }
753
754 package Amanda::Xfer::Dest::Fd;
755
756 use vars qw(@ISA);
757 @ISA = qw( Amanda::Xfer::Element );
758
759 sub new { 
760     my $pkg = shift;
761
762
763     Amanda::Xfer::xfer_dest_fd(@_);
764 }
765
766 package Amanda::Xfer::Dest::Null;
767
768 use vars qw(@ISA);
769 @ISA = qw( Amanda::Xfer::Element );
770
771 sub new { 
772     my $pkg = shift;
773
774
775     Amanda::Xfer::xfer_dest_null(@_);
776 }
777
778 package Amanda::Xfer::Dest::Buffer;
779
780 use vars qw(@ISA);
781 @ISA = qw( Amanda::Xfer::Element );
782
783 sub new { 
784     my $pkg = shift;
785
786
787     Amanda::Xfer::xfer_dest_buffer(@_);
788 }
789 *get = *Amanda::Xfer::xfer_dest_buffer_get;
790
791 package Amanda::Xfer::Dest::DirectTCPListen;
792
793 use vars qw(@ISA);
794 @ISA = qw( Amanda::Xfer::Element );
795
796 sub new { 
797     my $pkg = shift;
798
799
800     Amanda::Xfer::xfer_dest_directtcp_listen(@_);
801 }
802 *get_addrs = *Amanda::Xfer::xfer_dest_directtcp_listen_get_addrs;
803
804 package Amanda::Xfer::Dest::DirectTCPConnect;
805
806 use vars qw(@ISA);
807 @ISA = qw( Amanda::Xfer::Element );
808
809 sub new { 
810     my $pkg = shift;
811
812
813     Amanda::Xfer::xfer_dest_directtcp_connect(@_);
814 }
815
816 package Amanda::Xfer::Msg;
817
818 use Data::Dumper;
819 use overload '""' => sub { $_[0]->repr(); };
820
821 sub repr {
822     my ($self) = @_;
823     local $Data::Dumper::Indent = 0;
824     local $Data::Dumper::Terse = 1;
825     local $Data::Dumper::Useqq = 1;
826
827     my $typestr = Amanda::Xfer::xmsg_type_to_string($self->{'type'});
828     my $str = "{ type => \$$typestr, elt => $self->{'elt'}, version => $self->{'version'},";
829
830     my %skip = ( "type" => 1, "elt" => 1, "version" => 1 );
831     for my $k (keys %$self) {
832         next if $skip{$k};
833         $str .= " $k => " . Dumper($self->{$k}) . ",";
834     }
835
836     # strip the trailing comma and add a closing brace
837     $str =~ s/,$/ }/g;
838
839     return $str;
840 }
841
842 package Amanda::Xfer;
843
844 # make Amanda::Xfer->new equivalent to Amanda::Xfer::Xfer->new (don't
845 # worry, the blessings work out just fine)
846 *new = *Amanda::Xfer::Xfer::new;
847
848 # try to load Amanda::XferServer, which is server-only.  If it's not found, then
849 # its classes just remain undefined.
850 BEGIN {
851     eval "use Amanda::XferServer;";
852 }
853 1;