view release on metacpan or search on metacpan
- Archive::Libarchive 0.19 compatability
0.0706 2014-03-31 11:10:49 -0400
- fix for OpenBSD
0.0705 2014-03-27 12:59:38 -0400
- for libarchive 2.x, use our own Perl implementation of archive_read_open_memory
as interfacing with the C version is causing SIGSEGV.
0.0704 2014-03-27 10:41:31 -0400
- Take advantage of FFI::Raw 0.29's ability to return strings from callbacks
- And therefore remove dependency on Module::Build::FFI
0.0703 2014-03-24 17:17:33 -0400
- fixed some type declarations which were causing failures on 32bit Linux
(possibly others)
specifically: use int64_t instead of gid_t/uid_t for UID/GID types
use size_t instead of int64_t for buffer sizes
0.0702 2014-02-22 10:30:50 -0500
- require FFI::Raw 0.28 and FFI::Util 0.06 for recent bugfixes
lib/Archive/Libarchive/FFI/Callback.pm view on Meta::CPAN
package Archive::Libarchive::FFI::Callback;
use strict;
use warnings;
use 5.008;
# ABSTRACT: Libarchive callbacks
our $VERSION = '0.0902'; # VERSION
package
Archive::Libarchive::FFI;
BEGIN {
if(eval { require FFI::Sweet })
{
FFI::Sweet->import;
lib/Archive/Libarchive/FFI/Callback.pm view on Meta::CPAN
CB_READ => 1,
CB_CLOSE => 2,
CB_OPEN => 3,
CB_WRITE => 4,
CB_SKIP => 5,
CB_SEEK => 6,
CB_SWITCH => 7,
CB_BUFFER => 8,
};
my %callbacks;
do {
no warnings 'redefine';
sub _attach_function ($$$;$)
{
eval {
attach_function($_[0], $_[1], $_[2], $_[3]);
};
warn $@ if $@ && $ENV{ARCHIVE_LIBARCHIVE_FFI_VERBOSE};
}
};
my $myopen = FFI::Raw::Callback->new(sub {
my($archive) = @_;
my $status = eval {
$callbacks{$archive}->[CB_OPEN]->($archive, $callbacks{$archive}->[CB_DATA]);
};
if($@)
{
warn $@;
return ARCHIVE_FATAL();
}
$status;
}, _int, _ptr, _ptr);
my $mywrite = FFI::Raw::Callback->new(sub
{
my($archive, $null, $ptr, $size) = @_;
my $buffer = buffer_to_scalar($ptr, $size);
my $status = eval {
$callbacks{$archive}->[CB_WRITE]->($archive, $callbacks{$archive}->[CB_DATA], $buffer);
};
if($@)
{
warn $@;
return ARCHIVE_FATAL();
}
$status;
}, _int, _ptr, _ptr, _ptr, _size_t);
my $myread = FFI::Raw::Callback->new(sub
{
my($archive, $null, $optr) = @_;
my($status, $buffer) = eval {
$callbacks{$archive}->[CB_READ]->($archive, $callbacks{$archive}->[CB_DATA]);
};
if($@)
{
warn $@;
return ARCHIVE_FATAL();
}
my($ptr, $size) = scalar_to_buffer($buffer);
deref_ptr_set($optr, $ptr);
$size;
}, _uint64, _ptr, _ptr, _ptr);
my $myskip = FFI::Raw::Callback->new(sub
{
my($archive, $null, $request) = @_;
my $status = eval {
$callbacks{$archive}->[CB_SKIP]->($archive, $callbacks{$archive}->[CB_DATA], $request);
};
if($@)
{
warn $@;
return ARCHIVE_FATAL();
}
$status;
}, _uint64, _ptr, _ptr, _uint64);
my $myseek = FFI::Raw::Callback->new(sub
{
my($archive, $null, $offset, $whence) = @_;
my $status = eval {
$callbacks{$archive}->[CB_SEEK]->($archive, $callbacks{$archive}->[CB_DATA], $offset, $whence);
};
if($@)
{
warn $@;
return ARCHIVE_FATAL();
}
$status;
}, _uint64, _ptr, _ptr, _uint64, _int);
my $myclose = FFI::Raw::Callback->new(sub
{
my($archive) = @_;
my $status = eval {
$callbacks{$archive}->[CB_CLOSE]->($archive, $callbacks{$archive}->[CB_DATA]);
};
if($@)
{
warn $@;
return ARCHIVE_FATAL();
}
$status;
}, _int, _ptr, _ptr);
_attach_function 'archive_write_open', [ _ptr, _ptr, _ptr, _ptr, _ptr ], _int, sub
{
my($cb, $archive, $cd, $open, $write, $close) = @_;
$callbacks{$archive}->[CB_DATA] = $cd;
if(defined $open)
{
$callbacks{$archive}->[CB_OPEN] = $open;
$open = $myopen;
}
if(defined $write)
{
$callbacks{$archive}->[CB_WRITE] = $write;
$write = $mywrite;
}
if(defined $close)
{
$callbacks{$archive}->[CB_CLOSE] = $close;
$close = $myclose;
}
$cb->($archive, undef, $open||0, $write||0, $close||0);
};
sub archive_read_open ($$$$$)
{
my($archive, $data, $open, $read, $close) = @_;
archive_read_open2($archive, $data, $open, $read, undef, $close);
}
_attach_function 'archive_read_open2', [ _ptr, _ptr, _ptr, _ptr, _ptr, _ptr ], _int, sub
{
my($cb, $archive, $cd, $open, $read, $skip, $close) = @_;
$callbacks{$archive}->[CB_DATA] = $cd;
if(defined $open)
{
$callbacks{$archive}->[CB_OPEN] = $open;
$open = $myopen;
}
if(defined $read)
{
$callbacks{$archive}->[CB_READ] = $read;
$read = $myread;
}
if(defined $skip)
{
$callbacks{$archive}->[CB_SKIP] = $skip;
$skip = $myskip;
}
if(defined $close)
{
$callbacks{$archive}->[CB_CLOSE] = $close;
$close = $myclose;
}
$cb->($archive, undef, $open||0, $read||0, $skip||0, $close||0);
};
sub archive_read_set_callback_data ($$)
{
my($archive, $data) = @_;
$callbacks{$archive}->[CB_DATA] = $data;
ARCHIVE_OK();
}
foreach my $name (qw( open read skip close seek ))
{
my $const = 'CB_' . uc $name;
my $wrapper = eval '# line '. __LINE__ . ' "' . __FILE__ . "\n" . qq{
sub
{
my(\$cb, \$archive, \$callback) = \@_;
\$callbacks{\$archive}->[$const] = \$callback;
\$cb->(\$archive, \$my$name);
}
};die $@ if $@;
_attach_function "archive_read_set_$name\_callback", [ _ptr, _ptr ], _int;
}
if(archive_version_number() >= 3000000)
{
_attach_function 'archive_read_open_memory', [ _ptr, _ptr, _size_t ], _int, sub
{
my($cb, $archive, $buffer) = @_;
my $length = do { use bytes; length $buffer };
my $ptr = FFI::Raw::MemPtr->new_from_buf($buffer, $length);
$callbacks{$archive}->[CB_BUFFER] = $ptr; # TODO: CB_BUFFER or CB_DATA (or something else?)
$cb->($archive, $ptr, $length);
};
}
else
{
sub _archive_read_open_memory_read
{
my($archive, $data) = @_;
if($data->{done})
{
lib/Archive/Libarchive/FFI/Callback.pm view on Meta::CPAN
warn "error: " . archive_error_string($archive);
}
$r;
};
}
_attach_function archive_version_number() >= 3000000 ? 'archive_read_free' : [ archive_read_finish => 'archive_read_free' ], [ _ptr ], _int, sub
{
my($cb, $archive) = @_;
my $ret = $cb->($archive);
delete $callbacks{$archive};
$ret;
};
_attach_function archive_version_number() >= 3000000 ? 'archive_write_free' : [ archive_write_finish => 'archive_write_free' ], [ _ptr ], _int, sub
{
my($cb, $archive) = @_;
my $ret = $cb->($archive);
delete $callbacks{$archive};
$ret;
};
my %lookups;
use constant {
CB_LOOKUP_USER => 0,
CB_LOOKUP_GROUP => 1,
};
lib/Archive/Libarchive/FFI/Callback.pm view on Meta::CPAN
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Archive::Libarchive::FFI::Callback - Libarchive callbacks
=head1 VERSION
version 0.0902
=head1 SYNOPSIS
use Archive::Libarchive::FFI qw( :all );
# read
lib/Archive/Libarchive/FFI/Callback.pm view on Meta::CPAN
archive_read_open($archive, $data, \&myopen, \&myread, \&myclose);
# write
my $archive = archive_write_new();
archive_write_open($archive, $data, \&myopen, \&mywrite, \&myclose);
=head1 DESCRIPTION
This document provides information of callback routines for writing
custom input/output interfaces to the libarchive perl bindings. The
first two arguments passed into all callbacks are:
=over 4
=item $archive
The archive object (actually a pointer to the C structure that managed
the archive object).
=item $data
The callback data object (any legal Perl data structure).
=back
For the variable name / types conventions used in this document, see
L<Archive::Libarchive::FFI::Function>.
The expected return value for all callbacks EXCEPT the read callback
is a standard integer libarchive status value (example: C<ARCHIVE_OK>
or C<ARCHIVE_FATAL>).
If your callback dies (throws an exception), it will be caught at the
Perl level. The error will be sent to standard error via L<warn|perlfunc#warn>
and C<ARCHIVE_FATAL> will be passed back to libarchive.
=head2 data
There is a data field for callbacks associated with each $archive object.
It can be any native Perl type (example: scalar, hashref, coderef, etc).
You can set this by calling
L<archive_read_set_callback_data|Archive::Libarchive::FFI::Function#archive_read_set_callback_data>,
or by passing the data argument when you "open" the archive using
L<archive_read_open|Archive::Libarchive::FFI::Function#archive_read_open>,
L<archive_read_open2|Archive::Libarchive::FFI::Function#archive_read_open2> or
L<archive_write_open|Archive::Libarchive::FFI::Function#archive_write_open>.
The data field will be passed into each callback as its second argument.
lib/Archive/Libarchive/FFI/Function.pod view on Meta::CPAN
Undocumented libarchive function.
=head2 archive_read_disk_set_gname_lookup
my $status = archive_read_disk_set_gname_lookup($archive, $data, $lookup_callback, $cleanup_callback);
Register a callback for the lookup of GID from group names. In order to deregister call
C<archive_read_disk_set_gname_lookup> with both callback functions set to C<undef>.
See L<Archive::Libarchive::FFI::Callback> for calling conventions for the lookup and cleanup callbacks.
=head2 archive_read_disk_set_standard_lookup
my $status = archive_read_disk_set_standard_lookup($archive);
This convenience function installs a standard set of user and group name lookup functions.
These functions use C<getpwuid> and C<getgrgid> to convert ids to names, defaulting to C<undef>.
if the names cannot be looked up. These functions also implement a simple memory cache to
reduce the number of calls to C<getpwuid> and C<getgrgid>.
lib/Archive/Libarchive/FFI/Function.pod view on Meta::CPAN
This sets the mode used for handling symbolic links. The "physical" mode does not
follow any symbolic links.
=head2 archive_read_disk_set_uname_lookup
my $status = archive_read_disk_set_uname_lookup($archive, $data, $lookup_callback, $cleanup_callback);
Register a callback for the lookup of UID from user names. In order to deregister call
C<archive_read_disk_setugname_lookup> with both callback functions set to C<undef>.
See L<Archive::Libarchive::FFI::Callback> for calling conventions for the lookup and cleanup callbacks.
=head2 archive_read_disk_uname
my $string = archive_read_disk_uname($archive, $gid);
Returns a user name given a uid value. By default always
returns C<undef>.
=head2 archive_read_extract
lib/Archive/Libarchive/FFI/Function.pod view on Meta::CPAN
=head2 archive_read_open
my $status = archive_read_open($archive, $data, $open_cb, $read_cb, $close_cb);
The same as C<archive_read_open2>, except that the skip callback is assumed to be C<undef>.
=head2 archive_read_open1
my $status = archive_read_open1($archive);
Opening freezes the callbacks.
=head2 archive_read_open2
my $status = archive_read_open2($archive, $data, $open_cb, $read_cb, $skip_cb, $close_cb);
Freeze the settings, open the archive, and prepare for reading entries. This is the most
generic version of this call, which accepts four callback functions. Most clients will
want to use C<archive_read_open_filename>, C<archive_read_open_FILE>, C<archive_read_open_fd>,
or C<archive_read_open_memory> instead. The library invokes the client-provided functions to
obtain raw bytes from the archive.
lib/Archive/Libarchive/FFI/Function.pod view on Meta::CPAN
archive using C<archive_read_free>.
Bad things will happen if the buffer falls out of scope and is deallocated
before you free the archive, so make sure that there is a reference to the
buffer somewhere in your programmer until C<archive_read_free> is called.
=head2 archive_read_set_callback_data
my $status = archive_read_set_callback_data($archive, $data);
Set the client data for callbacks.
=head2 archive_read_set_close_callback
my $status = archive_read_set_close_callback($archive, $callback);
Set the close callback for the archive object.
=head2 archive_read_set_filter_option
my $status = archive_read_set_filter_option($archive, $module, $option, $value);
lib/Archive/Libarchive/FFI/Function.pod view on Meta::CPAN
my $count_or_status = archive_seek_data($archive, $offset, $whence);
Seek within the body of an entry. Similar to C<lseek>.
=head2 archive_set_error
my $status = archive_set_error($archive, $errno, $format, @args);
Sets the numeric error code and error description that will be returned by
L<archive_errno|Archive::Libarchive::FFI::Function#archive_errno> and L<archive_error_string|Archive::Libarchive::FFI::Function#archive_error_string>. This function should be
used within I/O callbacks to set system-specific error codes and error
descriptions. This function accepts a printf-like format string and
arguments (via perl's L<sprintf|perlfunc#sprintf>.
=head2 archive_version_number
my $version = archive_version_number();
Return the libarchive version as an integer.
=head2 archive_version_string
lib/Archive/Libarchive/FFI/Function.pod view on Meta::CPAN
my $status = archive_write_add_filter_none($archive);
Add none filter
=head2 archive_write_add_filter_program
my $status = archive_write_add_filter_program($archive, $cmd);
The archive will be fed into the specified compression program.
The output of that program is blocked and written to the client
write callbacks.
=head2 archive_write_add_filter_uuencode
my $status = archive_write_add_filter_uuencode($archive);
Add uuencode filter
=head2 archive_write_add_filter_xz
my $status = archive_write_add_filter_xz($archive);
lib/Archive/Libarchive/FFI/Function.pod view on Meta::CPAN
(Depending on the implementation), either way, it can be passed into
any of the write functions documented here with an C<$archive> argument.
=head2 archive_write_disk_set_group_lookup
my $status = archive_write_disk_set_group_lookup($archive, $data, $lookup_callback, $cleanup_callback);
Register a callback for the lookup of group names from group id numbers. In order to deregister
call C<archive_write_disk_set_group_lookup> with both callback functions set to C<undef>.
See L<Archive::Libarchive::FFI::Callback> for calling conventions for the lookup and cleanup callbacks.
=head2 archive_write_disk_set_options
my $status = archive_write_disk_set_options($archive, $flags);
The options field consists of a bitwise OR of one or more of the
following values:
=over 4
lib/Archive/Libarchive/FFI/Function.pod view on Meta::CPAN
a simple memory cache to reduce the number of calls to
C<getpwnam> and C<getgrnam>.
=head2 archive_write_disk_set_user_lookup
my $status = archive_write_disk_set_user_lookup($archive, $data, $lookup_callback, $cleanup_callback);
Register a callback for the lookup of user names from user id numbers. In order to deregister
call C<archive_write_disk_set_user_lookup> with both callback functions set to C<undef>.
See L<Archive::Libarchive::FFI::Callback> for calling conventions for the lookup and cleanup callbacks.
=head2 archive_write_disk_uid
my $int64 = archive_write_disk_uid($archive, $string, $int64);
Undocumented libarchive function.
=head2 archive_write_fail
my $status = archive_write_fail($archive);
xt/author/pod_spelling_system.t view on Meta::CPAN
Ollis
Mojolicious
plicease
CPAN
reinstall
TODO
filename
filenames
login
callback
callbacks
standalone
VMS
hostname
hostnames
TCP
UDP
IP
API
MSWin32
OpenBSD