1# This file was automatically generated by SWIG (http://www.swig.org).
2# Version 3.0.7
3#
4# Do not make changes to this file unless you know what you are doing--modify
5# the SWIG interface file instead.
6
7package Amanda::Archive;
8use base qw(Exporter);
9use base qw(DynaLoader);
10package Amanda::Archivec;
11bootstrap Amanda::Archive;
12package Amanda::Archive;
13@EXPORT = qw();
14
15# ---------- BASE METHODS -------------
16
17package Amanda::Archive;
18
19sub TIEHASH {
20    my ($classname,$obj) = @_;
21    return bless $obj, $classname;
22}
23
24sub CLEAR { }
25
26sub FIRSTKEY { }
27
28sub NEXTKEY { }
29
30sub FETCH {
31    my ($self,$field) = @_;
32    my $member_func = "swig_${field}_get";
33    $self->$member_func();
34}
35
36sub STORE {
37    my ($self,$field,$newval) = @_;
38    my $member_func = "swig_${field}_set";
39    $self->$member_func($newval);
40}
41
42sub this {
43    my $ptr = shift;
44    return tied(%$ptr);
45}
46
47
48# ------- FUNCTION WRAPPERS --------
49
50package Amanda::Archive;
51
52*amar_new = *Amanda::Archivec::amar_new;
53*amar_size = *Amanda::Archivec::amar_size;
54*amar_close = *Amanda::Archivec::amar_close;
55*amar_new_file = *Amanda::Archivec::amar_new_file;
56*amar_file_size = *Amanda::Archivec::amar_file_size;
57*amar_file_close = *Amanda::Archivec::amar_file_close;
58*amar_new_attr = *Amanda::Archivec::amar_new_attr;
59*amar_attr_size = *Amanda::Archivec::amar_attr_size;
60*amar_attr_close = *Amanda::Archivec::amar_attr_close;
61*amar_attr_add_data_buffer = *Amanda::Archivec::amar_attr_add_data_buffer;
62*amar_attr_add_data_fd = *Amanda::Archivec::amar_attr_add_data_fd;
63*amar_attr_add_data_fd_in_thread = *Amanda::Archivec::amar_attr_add_data_fd_in_thread;
64*amar_read = *Amanda::Archivec::amar_read;
65*amar_read_to = *Amanda::Archivec::amar_read_to;
66*amar_stop_read = *Amanda::Archivec::amar_stop_read;
67*amar_start_read = *Amanda::Archivec::amar_start_read;
68*destroy_read_cb = *Amanda::Archivec::destroy_read_cb;
69*set_amar_read_cb = *Amanda::Archivec::set_amar_read_cb;
70
71# ------- VARIABLE STUBS --------
72
73package Amanda::Archive;
74
75*AMAR_ATTR_FILENAME = *Amanda::Archivec::AMAR_ATTR_FILENAME;
76*AMAR_ATTR_EOF = *Amanda::Archivec::AMAR_ATTR_EOF;
77*AMAR_ATTR_GENERIC_DATA = *Amanda::Archivec::AMAR_ATTR_GENERIC_DATA;
78*AMAR_ATTR_RMAN_DATA = *Amanda::Archivec::AMAR_ATTR_RMAN_DATA;
79
80@EXPORT_OK = ();
81%EXPORT_TAGS = ();
82
83
84=head1 NAME
85
86Amanda::Archive - Perl access to the  amanda archive library
87
88=head1 SYNOPSIS
89
90  use Amanda::Archive
91
92  # Write to the file descriptor or file handle $fd, and
93  # add /etc/hosts to it
94  my $archive = Amanda::Archive->new($fd, ">");
95  my $file = $archive->new_file("/etc/hosts");
96  my $attr = $file->new_attr(16);
97  open(my $fh, "<", "/etc/hosts");
98  $attr->add_data_fd($fh, 1);
99  $file->close();
100  $archive->close();
101
102  # Read from an archive
103  my $archive = Amanda::Archive->new($fd, "<");
104  $ar->read(
105      file_start => sub {
106	  my ($user_data, $filenum, $filename) = @_;
107	  # ...
108	  return "foo"; # this becomes $file_data
109      },
110      file_finish => sub {
111	  my ($user_data, $file_data, $filenum, $truncated) = @_;
112	  # ...
113      },
114      21 => [ 32768,	# buffer into 32k chunks
115	      sub {
116		  my ($user_data, $filenum, $file_data, $attrid,
117		      $attr_data, $data, $eoa, $truncated) = @_;
118		  return "pants"; # becomes the new $attr_data for
119				  # any subsequent fragments
120	      } ],
121      0 => sub {	# note no buffering here; attrid 0 is "default"
122	  my ($user_data, $filenum, $file_data, $attrid,
123	      $attr_data, $data, $eoa, $truncated) = @_;
124	  return "shorts"; # becomes the new $attr_data for
125			   # any subsequent fragments
126      },
127      user_data => [ "mydata" ], # sent to all callbacks
128  );
129
130=head1 WRITING
131
132=head2 Amanda::Archive::Archive Objects
133
134Note that C<< Amanda::Archive->new >> and C<<
135Amanda::Archive::Archive->new >> are equivalent.
136
137=over
138
139=item C<new($fd, $mode)>
140
141Create a new archive for reading ("<") or writing (">") from or to
142file C<$fd> (a file handle or integer file descriptor).
143
144=item C<size()>
145
146Return the number of bytes already written to the archive.
147
148=item C<new_file($filename, $want_posn)>
149
150Create a new C<Amanda::Archive::File> object with the given filename
151(writing only).  Equivalent to
152
153  Amanda::Archive::File->new($archive, $filename, $want_posn);
154
155if C<$want_posn> is false, then this method returns a new
156C<Amanda::Archive::File> object.  If C<$want_posn> is true, then it
157returns C<($file, $posn)> where C<$file> is the object and C<$posn> is
158the offset into the datastream at which this file begins.  This offset
159can be stored in an index and used later to seek into the file.
160
161=item C<read(..)>
162
163See I<READING>, below.
164
165=item C<close()>
166
167Flush all buffers and close this archive. This does not close the file
168descriptor.
169
170=back
171
172=head2 Amanda::Archive::File Objects
173
174=over
175
176=item C<new($archive, $filename, $want_posn)>
177
178Create a new file in the given archive.  See
179C<Amanda::Archive::Archive::new_file>, above.
180
181=item C<new_attr($attrid)>
182
183Create a new C<Amanda::Archive::Attribute> object.  Equivalent to
184
185  Amanda::Archive::Attr->new($file, $attrid);
186
187=item C<size()>
188
189Return the size on the archive of all attributes of the file.
190
191=item C<close()>
192
193Close this file, writing an EOF record.
194
195=back
196
197=head2 Amanda::Archive::Attribute Objects
198
199=over
200
201=item C<add_data($data, $eoa)>
202
203Add C<$data> to this attribute, adding an EOA (end-of-attribute) bit
204if C<$eoa> is true.
205
206=item C<add_data_fd($fh, $eoa)>
207
208Copy data from C<$fh> to this attribute, adding an EOA
209(end-of-attribute) bit if C<$eoa> is true.
210
211=item C<add_data_fd_in_thread($fh, $eoa)>
212
213Same as C<add_data_fd> but the copy is done in a newly created thread.
214This function return immediately.
215Nothing should be done on the archive while it is running.
216The next action on the archive must be $attr->close().
217
218=item C<size()>
219
220Return the size of the data of the attribute.
221
222=item C<close()>
223
224Close this attribute, adding an EOA bit if none has been written
225already.
226
227=back
228
229=head1 READING
230
231The C<Amanda::Archive::Archive> method C<read()> handles reading
232archives via a callback mechanism.  It takes its arguments in hash
233form, with the following keys:
234
235    file_start => sub {
236	my ($user_data, $filenum, $filename) = @_;
237	# ..
238    },
239
240C<file_start> gives a sub which is called for every file in the
241archive.  It can return an arbitrary value which will become the
242C<$file_data> for subsequent callbacks in this file, or the string
243"IGNORE" which will cause the reader to ignore all data for this file.
244In this case, no other callbacks will be made for the file (not even
245C<file_finish>).
246
247    file_finish => sub {
248	my ($user_data, $file_data, $filenum, $truncated) = @_;
249	# ..
250    },
251
252C<file_finish> gives a sub which is called when an EOF record appears.
253C<$file_data> comes from the return value of the C<file_start>
254callback.  C<$truncated> is true if the file may be missing data
255(e.g., when an early EOF is detected).
256
257    user_data => $my_object,
258
259C<user_data> gives an arbitrary value which is passed to each callback
260as C<$user_data>.
261
262    13 => sub {
263	my ($user_data, $filenum, $file_data, $attrid,
264	    $attr_data, $data, $eoa, $truncated) = @_;
265	# ...
266    },
267    19 => [ 10240, sub { ... } ],
268
269Any numeric key is treated as an attribute ID, and specifies the
270handling for that attribute.  Attribute ID zero is treated as a
271wildcard, and will match any attribute without an explicit handler.
272The handler can be specified as a sub (as for attribute ID 13 in the
273example above) or as an arrayref C<[$minsize, $sub]>.  In the latter
274case, the sub is only called when at least C<$minsize> bytes of data
275are available for the attribute, or at the end of the attribute data.
276
277The parameters to the callback include C<$file_data>, the value
278returned from C<file_start>, and C<$attr_data>, which is the return
279value of the last invocation of this sub for this attribute.  If this
280is the last fragment of data for this attribute, then C<$eoa> is true.
281The meaning of C<$truncated> is similar to that in C<file_finish>.
282
283=head2 EXAMPLE
284
285    sub read_to_files {
286	my ($arch_fh, $basedir) = @_;
287
288	my $arch = Amanda::Archive->new(fileno($arch_fh), "<");
289	$arch->read(
290	    file_start => sub {
291		my ($user_data, $filenum, $filename) = @_;
292		return "$basedir/$filenum"; # becomes $file_data
293	    },
294	    0 => [ 32768, sub {
295		my ($user_data, $filenum, $file_data, $attrid,
296		    $attr_data, $data, $eoa, $truncated) = @_;
297		warn("file $filename attribute $attrid is truncated")
298		    if ($truncated);
299		# store the open filehandle in $attr_data
300		if (!$attr_data) {
301		    open($attr_data, "$file_data.$attrid", ">")
302			or die("open: $!");
303		}
304		print $attr_data $data;
305		if ($eoa) {
306		    close($attr_data);
307		}
308		return $attr_data;
309	    },
310	);
311    }
312
313=cut
314
315
316
317push @EXPORT_OK, qw(amar_attr_to_string);
318push @{$EXPORT_TAGS{"amar_attr"}}, qw(amar_attr_to_string);
319
320my %_amar_attr_VALUES;
321#Convert an enum value to a single string
322sub amar_attr_to_string {
323    my ($enumval) = @_;
324
325    for my $k (keys %_amar_attr_VALUES) {
326	my $v = $_amar_attr_VALUES{$k};
327
328	#is this a matching flag?
329	if ($enumval == $v) {
330	    return $k;
331	}
332    }
333
334#default, just return the number
335    return $enumval;
336}
337
338push @EXPORT_OK, qw( $AMAR_ATTR_FILENAME  $AMAR_ATTR_EOF  $AMAR_ATTR_GENERIC_DATA  $AMAR_ATTR_RMAN_DATA);
339push @{$EXPORT_TAGS{"amar_attr"}}, qw( $AMAR_ATTR_FILENAME  $AMAR_ATTR_EOF  $AMAR_ATTR_GENERIC_DATA  $AMAR_ATTR_RMAN_DATA);
340      foreach (qw(  AMAR_ATTR_FILENAME  AMAR_ATTR_EOF  AMAR_ATTR_GENERIC_DATA  AMAR_ATTR_RMAN_DATA)) {  	$_amar_attr_VALUES{$_} = $$_;      }
341
342require Amanda::Config::FoldingHash;
343
344=pod
345
346Amar default attribute:       C<$AMAR_ATTR_FILENAME>  C<$AMAR_ATTR_EOF>  C<$AMAR_ATTR_GENERIC_DATA>  C<$AMAR_ATTR_RMAN_DATA>
347
348=cut
349
350package Amanda::Archive;
351
352# Expose the Archive constructor at Amanda::Archive->new
353sub new {
354    my $pkg = shift;
355    Amanda::Archive::Archive->new(@_);
356}
357
358package Amanda::Archive::Archive;
359
360sub new {
361    my ($class, $fd, $mode) = @_;
362    my $arch = Amanda::Archive::amar_new($fd, $mode);
363    return bless (\$arch, $class);
364}
365
366my $dat = undef;
367sub close {
368    my $self = shift;
369    if ($$self) {
370	Amanda::Archive::amar_close($$self);
371	if ($dat) {
372	    Amanda::Archive::destroy_read_cb($dat);
373	    $dat = undef;
374	}
375	$$self = undef;
376    }
377}
378
379sub size {
380    my $self = shift;
381    if ($$self) {
382	return Amanda::Archive::amar_size($$self);
383    }
384    return 0;
385}
386
387sub DESTROY {
388    my $self = shift;
389    if ($dat) {
390	Amanda::Archive::destroy_read_cb($dat);
391	$dat = undef;
392    }
393    $self->close();
394}
395
396sub new_file {
397    my ($self, $filename, $want_offset) = @_;
398    return Amanda::Archive::File->new($self, $filename, $want_offset);
399}
400
401sub Amanda::Archive::Archive::read {
402    my $self = shift;
403    die "Archive is not open" unless ($$self);
404    # pass a hashref to the C code
405    my %h = @_;
406    Amanda::Archive::amar_read($$self, \%h);
407}
408
409sub Amanda::Archive::Archive::set_read_cb {
410    my $self = shift;
411    die "Archive is not open" unless ($$self);
412    # pass a hashref to the C code
413    my %h = @_;
414    $dat = Amanda::Archive::set_amar_read_cb($$self, \%h);
415}
416
417sub Amanda::Archive::Archive::read_to {
418    my $self = shift;
419    die "Archive is not open" unless ($$self);
420    my $filenum  = shift;
421    my $attrid   = shift;
422    my $fd       = shift;
423    Amanda::Archive::amar_read_to($$self, $filenum, $attrid, $fd);
424}
425
426sub Amanda::Archive::Archive::stop_read {
427    my $self = shift;
428    die "Archive is not open" unless ($$self);
429    Amanda::Archive::amar_stop_read($$self);
430}
431
432sub Amanda::Archive::Archive::start_read {
433    my $self = shift;
434    die "Archive is not open" unless ($$self);
435    Amanda::Archive::amar_start_read($$self);
436}
437
438package Amanda::Archive::File;
439
440sub new {
441    my ($class, $arch, $filename, $want_offset) = @_;
442    die "Archive is not open" unless ($$arch);
443    if ($want_offset) {
444	# note that posn is returned first by the SWIG wrapper
445	my ($file, $posn) = Amanda::Archive::amar_new_file($$arch, $filename, $want_offset);
446	return (bless([ $file, $arch ], $class), $posn);
447    } else {
448	my $file = Amanda::Archive::amar_new_file($$arch, $filename, $want_offset);
449	return bless([ $file, $arch ], $class);
450    }
451}
452
453sub size {
454    my $self = shift;
455    if ($self->[0]) {
456	return Amanda::Archive::amar_file_size($self->[0]);
457    }
458    return 0;
459}
460
461sub close {
462    my $self = shift;
463    if ($self->[0]) {
464	Amanda::Archive::amar_file_close($self->[0]);
465	$self->[0] = undef;
466    }
467}
468
469sub DESTROY {
470    my $self = shift;
471    $self->close();
472}
473
474sub new_attr {
475    my ($self, $attrid) = @_;
476    return Amanda::Archive::Attr->new($self, $attrid);
477}
478
479package Amanda::Archive::Attr;
480
481sub new {
482    my ($class, $file, $attrid) = @_;
483    die "File is not open" unless ($file->[0]);
484    my $attr = Amanda::Archive::amar_new_attr($file->[0], $attrid);
485    return bless ([$attr, $file], $class);
486}
487
488sub size {
489    my $self = shift;
490    if ($self->[0]) {
491	return Amanda::Archive::amar_attr_size($self->[0]);
492    }
493    return 0;
494}
495
496sub close {
497    my $self = shift;
498    if ($self->[0]) {
499	Amanda::Archive::amar_attr_close($self->[0]);
500	$self->[0] = undef;
501    }
502}
503
504sub DESTROY {
505    my $self = shift;
506    $self->close();
507}
508
509sub add_data {
510    my ($self, $data, $eoa) = @_;
511    die "Attr is not open" unless ($self->[0]);
512    Amanda::Archive::amar_attr_add_data_buffer($self->[0], $data, $eoa);
513}
514
515sub add_data_fd {
516    my ($self, $fd, $eoa) = @_;
517    die "Attr is not open" unless ($self->[0]);
518    return Amanda::Archive::amar_attr_add_data_fd($self->[0], $fd, $eoa);
519}
520
521sub add_data_fd_in_thread {
522    my ($self, $fd, $eoa) = @_;
523    die "Attr is not open" unless ($self->[0]);
524    return Amanda::Archive::amar_attr_add_data_fd_in_thread($self->[0], $fd, $eoa);
525}
5261;
527