1/* 2 * Copyright (c) 2009-2013 Zmanda, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * for more details. 13 * 14 * You should have received a copy of the GNU General Public License along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * 18 * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300 19 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com 20 */ 21 22%perlcode %{ 23 24=head1 NAME 25 26Amanda::Archive - Perl access to the amanda archive library 27 28=head1 SYNOPSIS 29 30 use Amanda::Archive 31 32 # Write to the file descriptor or file handle $fd, and 33 # add /etc/hosts to it 34 my $archive = Amanda::Archive->new($fd, ">"); 35 my $file = $archive->new_file("/etc/hosts"); 36 my $attr = $file->new_attr(16); 37 open(my $fh, "<", "/etc/hosts"); 38 $attr->add_data_fd($fh, 1); 39 $file->close(); 40 $archive->close(); 41 42 # Read from an archive 43 my $archive = Amanda::Archive->new($fd, "<"); 44 $ar->read( 45 file_start => sub { 46 my ($user_data, $filenum, $filename) = @_; 47 # ... 48 return "foo"; # this becomes $file_data 49 }, 50 file_finish => sub { 51 my ($user_data, $file_data, $filenum, $truncated) = @_; 52 # ... 53 }, 54 21 => [ 32768, # buffer into 32k chunks 55 sub { 56 my ($user_data, $filenum, $file_data, $attrid, 57 $attr_data, $data, $eoa, $truncated) = @_; 58 return "pants"; # becomes the new $attr_data for 59 # any subsequent fragments 60 } ], 61 0 => sub { # note no buffering here; attrid 0 is "default" 62 my ($user_data, $filenum, $file_data, $attrid, 63 $attr_data, $data, $eoa, $truncated) = @_; 64 return "shorts"; # becomes the new $attr_data for 65 # any subsequent fragments 66 }, 67 user_data => [ "mydata" ], # sent to all callbacks 68 ); 69 70=head1 WRITING 71 72=head2 Amanda::Archive::Archive Objects 73 74Note that C<< Amanda::Archive->new >> and C<< 75Amanda::Archive::Archive->new >> are equivalent. 76 77=over 78 79=item C<new($fd, $mode)> 80 81Create a new archive for reading ("<") or writing (">") from or to 82file C<$fd> (a file handle or integer file descriptor). 83 84=item C<size()> 85 86Return the number of bytes already written to the archive. 87 88=item C<new_file($filename, $want_posn)> 89 90Create a new C<Amanda::Archive::File> object with the given filename 91(writing only). Equivalent to 92 93 Amanda::Archive::File->new($archive, $filename, $want_posn); 94 95if C<$want_posn> is false, then this method returns a new 96C<Amanda::Archive::File> object. If C<$want_posn> is true, then it 97returns C<($file, $posn)> where C<$file> is the object and C<$posn> is 98the offset into the datastream at which this file begins. This offset 99can be stored in an index and used later to seek into the file. 100 101=item C<read(..)> 102 103See I<READING>, below. 104 105=item C<close()> 106 107Flush all buffers and close this archive. This does not close the file 108descriptor. 109 110=back 111 112=head2 Amanda::Archive::File Objects 113 114=over 115 116=item C<new($archive, $filename, $want_posn)> 117 118Create a new file in the given archive. See 119C<Amanda::Archive::Archive::new_file>, above. 120 121=item C<new_attr($attrid)> 122 123Create a new C<Amanda::Archive::Attribute> object. Equivalent to 124 125 Amanda::Archive::Attr->new($file, $attrid); 126 127=item C<size()> 128 129Return the size on the archive of all attributes of the file. 130 131=item C<close()> 132 133Close this file, writing an EOF record. 134 135=back 136 137=head2 Amanda::Archive::Attribute Objects 138 139=over 140 141=item C<add_data($data, $eoa)> 142 143Add C<$data> to this attribute, adding an EOA (end-of-attribute) bit 144if C<$eoa> is true. 145 146=item C<add_data_fd($fh, $eoa)> 147 148Copy data from C<$fh> to this attribute, adding an EOA 149(end-of-attribute) bit if C<$eoa> is true. 150 151=item C<add_data_fd_in_thread($fh, $eoa)> 152 153Same as C<add_data_fd> but the copy is done in a newly created thread. 154This function return immediately. 155Nothing should be done on the archive while it is running. 156The next action on the archive must be $attr->close(). 157 158=item C<size()> 159 160Return the size of the data of the attribute. 161 162=item C<close()> 163 164Close this attribute, adding an EOA bit if none has been written 165already. 166 167=back 168 169=head1 READING 170 171The C<Amanda::Archive::Archive> method C<read()> handles reading 172archives via a callback mechanism. It takes its arguments in hash 173form, with the following keys: 174 175 file_start => sub { 176 my ($user_data, $filenum, $filename) = @_; 177 # .. 178 }, 179 180C<file_start> gives a sub which is called for every file in the 181archive. It can return an arbitrary value which will become the 182C<$file_data> for subsequent callbacks in this file, or the string 183"IGNORE" which will cause the reader to ignore all data for this file. 184In this case, no other callbacks will be made for the file (not even 185C<file_finish>). 186 187 file_finish => sub { 188 my ($user_data, $file_data, $filenum, $truncated) = @_; 189 # .. 190 }, 191 192C<file_finish> gives a sub which is called when an EOF record appears. 193C<$file_data> comes from the return value of the C<file_start> 194callback. C<$truncated> is true if the file may be missing data 195(e.g., when an early EOF is detected). 196 197 user_data => $my_object, 198 199C<user_data> gives an arbitrary value which is passed to each callback 200as C<$user_data>. 201 202 13 => sub { 203 my ($user_data, $filenum, $file_data, $attrid, 204 $attr_data, $data, $eoa, $truncated) = @_; 205 # ... 206 }, 207 19 => [ 10240, sub { ... } ], 208 209Any numeric key is treated as an attribute ID, and specifies the 210handling for that attribute. Attribute ID zero is treated as a 211wildcard, and will match any attribute without an explicit handler. 212The handler can be specified as a sub (as for attribute ID 13 in the 213example above) or as an arrayref C<[$minsize, $sub]>. In the latter 214case, the sub is only called when at least C<$minsize> bytes of data 215are available for the attribute, or at the end of the attribute data. 216 217The parameters to the callback include C<$file_data>, the value 218returned from C<file_start>, and C<$attr_data>, which is the return 219value of the last invocation of this sub for this attribute. If this 220is the last fragment of data for this attribute, then C<$eoa> is true. 221The meaning of C<$truncated> is similar to that in C<file_finish>. 222 223=head2 EXAMPLE 224 225 sub read_to_files { 226 my ($arch_fh, $basedir) = @_; 227 228 my $arch = Amanda::Archive->new(fileno($arch_fh), "<"); 229 $arch->read( 230 file_start => sub { 231 my ($user_data, $filenum, $filename) = @_; 232 return "$basedir/$filenum"; # becomes $file_data 233 }, 234 0 => [ 32768, sub { 235 my ($user_data, $filenum, $file_data, $attrid, 236 $attr_data, $data, $eoa, $truncated) = @_; 237 warn("file $filename attribute $attrid is truncated") 238 if ($truncated); 239 # store the open filehandle in $attr_data 240 if (!$attr_data) { 241 open($attr_data, "$file_data.$attrid", ">") 242 or die("open: $!"); 243 } 244 print $attr_data $data; 245 if ($eoa) { 246 close($attr_data); 247 } 248 return $attr_data; 249 }, 250 ); 251 } 252 253=cut 254 255 256%} 257