Imported Upstream version 3.1.0
[debian/amanda] / perl / Amanda / Archive.swg
index 22626c505d39d295019b09f30502ab4746d7bade..dc8057cdb4be0502267833516be4e04f63e22b58 100644 (file)
@@ -1,21 +1,21 @@
 /*
- * Copyright (c) Zmanda, Inc.  All Rights Reserved.
+ * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
  *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
  *
- * This library is distributed in the hope that it will be useful, but
+ * This program is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
- * License for more details.
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
  *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  *
- * Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300
- * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
+ * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
+ * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
  */
 
 %module "Amanda::Archive"
 %include "exception.i"
 %include "cstring.i"
 
+%include "Amanda/Archive.pod"
+
 %{
 #include "amar.h"
 %}
 
-%perlcode %{
-=head1 NAME
-
-Amanda::Archive - Perl access to the  amanda archive library
-
-=head1 SYNOPSIS
-
-  use Amanda::Archive
-
-  # Write to the file descriptor $fd, and add /etc/hosts to it
-  my $archive = Amanda::Archive->new($fd, ">");
-  my $file = $archive->new_file("/etc/hosts");
-  my $attr = $file->new_attr(16);
-  open(my $fh, "<", "/etc/hosts");
-  $attr->add_data_fd(fileno($fh), 1);
-  $file->close();
-  $archive->close();
-
-  # Read from an archive
-  my $archive = Amanda::Archive->new($fd, "<");
-  $ar->read(
-      file_start => sub {
-         my ($user_data, $filenum, $filename) = @_;
-         # ...
-         return "foo"; # this becomes $file_data
-      },
-      file_finish => sub {
-         my ($user_data, $file_data, $filenum, $truncated) = @_;
-         # ...
-      },
-      21 => [ 32768,   # buffer into 32k chunks
-             sub {
-                 my ($user_data, $filenum, $file_data, $attrid,
-                     $attr_data, $data, $eoa, $truncated) = @_;
-                 return "pants"; # becomes the new $attr_data for
-                                 # any subsequent fragments
-             } ],
-      0 => sub {       # note no buffering here; attrid 0 is "default"
-         my ($user_data, $filenum, $file_data, $attrid,
-             $attr_data, $data, $eoa, $truncated) = @_;
-         return "shorts"; # becomes the new $attr_data for
-                          # any subsequent fragments
-      },
-      user_data => [ "mydata" ], # sent to all callbacks
-  );
-
-=head1 WRITING
-
-=head2 Amanda::Archive::Archive Objects
-
-Note that C<Amanda::Archive->new> and C<Amanda::Archive::Archive->new> are
-equivalent.
-
-=over
-
-=item C<new($fd, $mode)>
-
-Create a new archive for reading ("<") or writing (">") from or to file
-descriptor C<$fd>.
-
-=item C<new_file($filename, $want_posn)>
-
-Create a new C<Amanda::Archive::File> object with the given filename (writing
-only).  Equivalent to
-
-  Amanda::Archive::File->new($archive, $filename, $want_posn);
-
-if C<$want_posn> is false, then this method returns a new
-C<Amanda::Archive::File> object.  If C<$want_posn> is true, then it returns
-C<($file, $posn)> where C<$file> is the object and C<$posn> is the offset into
-the datastream at which this file begins.  This offset can be stored in an
-index and used later to seek into the file.
-
-=item C<read(..)>
-
-See I<READING>, below.
-
-=item C<close()>
-
-Flush all buffers and close this archive. This does not close the file descriptor.
-
-=back
-
-=head2 Amanda::Archive::File Objects
-
-=over
-
-=item C<new($archive, $filename, $want_posn)>
-
-Create a new file in the given archive.  See C<Amanda::Archive::Archive::new_file>, above.
-
-=item C<new_attr($attrid)>
-
-Create a new C<Amanda::Archive::Attribute> object.  Equivalent to
-
-  Amanda::Archive::Attr->new($file, $attrid);
-
-=item C<close()>
-
-Close this file, writing an EOF record.
-
-=back
-
-=head2 Amanda::Archive::Attribute Objects
-
-=over
-
-=item C<add_data($data, $eoa)>
-
-Add C<$data> to this attribute, adding an EOA (end-of-attribute) bit if C<$eoa> is true.
-
-=item C<add_data_fd($fd, $eoa)>
-
-Copy data from C<$fd> to this attribute, adding an EOA (end-of-attribute) bit if C<$eoa> is true.
-
-=item C<close()>
-
-Close this attribute, adding an EOA bit if none has been written already.
-
-=back
-
-=head1 READING
-
-The C<Amanda::Archive::Archive> method C<read()> handles reading archives via a callback mechanism.  It takes its arguments in hash form, with the following keys:
-
-    file_start => sub {
-       my ($user_data, $filenum, $filename) = @_;
-       # ..
-    },
-
-C<file_start> gives a sub which is called for every file in the archive.  It
-can return an arbitrary value which will become the C<$file_data> for
-subsequent callbacks in this file, or the string "IGNORE" which will cause the
-reader to ignore all data for this file.  In this case, no other callbacks will
-be made for the file (not even C<file_finish>).
-
-    file_finish => sub {
-       my ($user_data, $file_data, $filenum, $truncated) = @_;
-       # ..
-    },
-
-C<file_finish> gives a sub which is called when an EOF record appears.
-C<$file_data> comes from the return value of the C<file_start> callback.
-C<$truncated> is true if the file may be missing data (e.g., when an early EOF
-is detected).
-
-    user_data => $my_object,
-
-C<user_data> gives an arbitrary value which is passed to each callback as C<$user_data>.
-
-    13 => sub {
-       my ($user_data, $filenum, $file_data, $attrid,
-           $attr_data, $data, $eoa, $truncated) = @_;
-       # ...
-    },
-    19 => [ 10240, sub { ... } ],
-
-Any numeric key is treated as an attribute ID, and specifies the handling for
-that attribute.  Attribute ID zero is treated as a wildcard, and will match any
-attribute without an explicit handler.  The handler can be specified as a sub
-(as for attribute ID 13 in the example above) or as an arrayref C<[$minsize,
-$sub]>.  In the latter case, the sub is only called when at least C<$minsize>
-bytes of data are available for the attribute, or at the end of the attribute
-data.
-
-The parameters to the callback include C<$file_data>, the value returned from
-C<file_start>, and C<$attr_data>, which is the return value of the last
-invocation of this sub for this attribute.  If this is the last fragment of
-data for this attribute, then C<$eoa> is true.  The meaning of C<$truncated>
-is similar to that in C<file_finish>.
-
-=head2 EXAMPLE
-
-    sub read_to_files {
-       my ($arch_fh, $basedir) = @_;
-
-       my $arch = Amanda::Archive->new(fileno($arch_fh), "<");
-       $arch->read(
-           file_start => sub {
-               my ($user_data, $filenum, $filename) = @_;
-               return "$basedir/$filenum"; # becomes $file_data
-           },
-           0 => [ 32768, sub {
-               my ($user_data, $filenum, $file_data, $attrid,
-                   $attr_data, $data, $eoa, $truncated) = @_;
-               warn("file $filename attribute $attrid is truncated")
-                   if ($truncated);
-               # store the open filehandle in $attr_data
-               if (!$attr_data) {
-                   open($attr_data, "$file_data.$attrid", ">")
-                       or die("open: $!");
-               }
-               print $attr_data $data;
-               if ($eoa) {
-                   close($attr_data);
-               }
-               return $attr_data;
-           },
-       );
-    }
-
-=cut
-%}
-
 %{
 /* Support code (not directly available from perl) */
 
+#define AMANDA_ARCHIVE_ERROR_DOMAIN "Amanda archive"
+
 /* A C object to contain all of the relevant callbacks and other state during a
  * read operation; this becomes the user_data during the read */
 typedef struct perl_read_data_s {
@@ -398,16 +198,6 @@ read_frag_cb(
     return TRUE;
 }
 
-static void
-croak_gerror(GError **error)
-{
-    static char *errstr = NULL;
-    if (errstr) g_free(errstr);
-    errstr = g_strdup((*error)->message);
-    g_clear_error(error);
-    croak("Amanda archive: %s", errstr);
-}
-
 /* generic function to recognize when a string+len represents a number and
  * incidentally return the resulting value.  Note that this does not handle
  * negative numbers. */
@@ -460,8 +250,9 @@ is_number(char *str, int len, int *result)
 }
 %typemap(argout) off_t *want_position {
     if ($1) {
-       $result = amglue_newSVi64(*$1);
-       argvi++;
+       SP += argvi; PUTBACK;
+       $result = sv_2mortal(amglue_newSVi64(*$1));
+       SPAGAIN; SP -= argvi; argvi++;
     }
 }
 
@@ -485,14 +276,14 @@ amar_t *amar_new_(int fd, char *modestr) {
        return rv;
     }
 
-    croak_gerror(&error);
+    croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
     return NULL;
 }
 
 void amar_close_(amar_t *arch) {
     GError *error = NULL;
     if (!amar_close(arch, &error))
-       croak_gerror(&error);
+       croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
 }
 
 amar_file_t *
@@ -505,14 +296,14 @@ amar_new_file_(amar_t *arch, char *filename, gsize filename_len, off_t *want_pos
     if (file)
        return file;
 
-    croak_gerror(&error);
+    croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
     return NULL;
 }
 
 void amar_file_close_(amar_file_t *file) {
     GError *error = NULL;
     if (!amar_file_close(file, &error))
-       croak_gerror(&error);
+       croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
 }
 
 amar_attr_t *
@@ -526,20 +317,20 @@ amar_new_attr_(amar_file_t *file, guint16 attrid) {
     if (attr)
        return attr;
 
-    croak_gerror(&error);
+    croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
     return NULL;
 }
 
 void amar_attr_close_(amar_attr_t *attr) {
     GError *error = NULL;
     if (!amar_attr_close(attr, &error))
-       croak_gerror(&error);
+       croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
 }
 
 void amar_attr_add_data_buffer_(amar_attr_t *attr, char *buffer, gsize size, gboolean eoa) {
     GError *error = NULL;
     if (!amar_attr_add_data_buffer(attr, buffer, size, eoa, &error))
-       croak_gerror(&error);
+       croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
 }
 
 size_t
@@ -547,7 +338,7 @@ amar_attr_add_data_fd_(amar_attr_t *attr, int fd, gboolean eoa) {
     GError *error = NULL;
     size_t rv = amar_attr_add_data_fd(attr, fd, eoa, &error);
     if (rv < 0)
-       croak_gerror(&error);
+       croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
     return rv;
 }
 
@@ -691,7 +482,7 @@ void amar_read_(amar_t *archive, SV *params_hashref) {
      * is still set */
     if (!success) {
        if (error)
-           croak_gerror(&error);
+           croak_gerror(AMANDA_ARCHIVE_ERROR_DOMAIN, &error);
        else
            croak(NULL);
     }