text:
package Archive::Extract;

use strict;

use Cwd                         qw[cwd chdir];
use Carp                        qw[carp];
use IPC::Cmd                    qw[run can_run];
use FileHandle;
use File::Path                  qw[mkpath];
use File::Spec;
use File::Basename              qw[dirname basename];
use Params::Check               qw[check];
use Module::Load::Conditional   qw[can_load check_install];
use Locale::Maketext::Simple    Style => 'gettext';

### solaris has silly /bin/tar output ###
use constant ON_SOLARIS     => $^O eq 'solaris' ? 1 : 0;
use constant ON_NETBSD      => $^O eq 'netbsd' ? 1 : 0;
use constant ON_FREEBSD     => $^O eq 'freebsd' ? 1 : 0;
use constant ON_LINUX       => $^O eq 'linux' ? 1 : 0;
use constant FILE_EXISTS    => sub { -e $_[0] ? 1 : 0 };

### VMS may require quoting upper case command options
use constant ON_VMS         => $^O eq 'VMS' ? 1 : 0;

### Windows needs special treatment of Tar options
use constant ON_WIN32       => $^O eq 'MSWin32' ? 1 : 0;

### we can't use this extraction method, because of missing
### modules/binaries:
use constant METHOD_NA      => [];

### If these are changed, update @TYPES and the new() POD
use constant TGZ            => 'tgz';
use constant TAR            => 'tar';
use constant GZ             => 'gz';
use constant ZIP            => 'zip';
use constant BZ2            => 'bz2';
use constant TBZ            => 'tbz';
use constant Z              => 'Z';
use constant LZMA           => 'lzma';
use constant XZ             => 'xz';
use constant TXZ            => 'txz';

use vars qw[$VERSION $PREFER_BIN $PROGRAMS $WARN $DEBUG
            $_ALLOW_BIN $_ALLOW_PURE_PERL $_ALLOW_TAR_ITER
         ];

$VERSION            = '0.60';
$PREFER_BIN         = 0;
$WARN               = 1;
$DEBUG              = 0;
$_ALLOW_PURE_PERL   = 1;    # allow pure perl extractors
$_ALLOW_BIN         = 1;    # allow binary extractors
$_ALLOW_TAR_ITER        = 1;    # try to use Archive::Tar->iter if available

# same as all constants
my @Types           = ( TGZ, TAR, GZ, ZIP, BZ2, TBZ, Z, LZMA, XZ, TXZ );

local $Params::Check::VERBOSE = $Params::Check::VERBOSE = 1;

=pod

=head1 NAME

Archive::Extract - A generic archive extracting mechanism

=head1 SYNOPSIS

    use Archive::Extract;

    ### build an Archive::Extract object ###
    my $ae = Archive::Extract->new( archive => 'foo.tgz' );

    ### extract to cwd() ###
    my $ok = $ae->extract;

    ### extract to /tmp ###
    my $ok = $ae->extract( to => '/tmp' );

    ### what if something went wrong?
    my $ok = $ae->extract or die $ae->error;

    ### files from the archive ###
    my $files   = $ae->files;

    ### dir that was extracted to ###
    my $outdir  = $ae->extract_path;

    ### quick check methods ###
    $ae->is_tar     # is it a .tar file?
    $ae->is_tgz     # is it a .tar.gz or .tgz file?
    $ae->is_gz;     # is it a .gz file?
    $ae->is_zip;    # is it a .zip file?
    $ae->is_bz2;    # is it a .bz2 file?
    $ae->is_tbz;    # is it a .tar.bz2 or .tbz file?
    $ae->is_lzma;   # is it a .lzma file?
    $ae->is_xz;     # is it a .xz file?
    $ae->is_txz;    # is it a .tar.xz or .txz file?

    ### absolute path to the archive you provided ###
    $ae->archive;

    ### commandline tools, if found ###
    $ae->bin_tar     # path to /bin/tar, if found
    $ae->bin_gzip    # path to /bin/gzip, if found
    $ae->bin_unzip   # path to /bin/unzip, if found
    $ae->bin_bunzip2 # path to /bin/bunzip2 if found
    $ae->bin_unlzma  # path to /bin/unlzma if found
    $ae->bin_unxz    # path to /bin/unxz if found

=head1 DESCRIPTION

Archive::Extract is a generic archive extraction mechanism.

It allows you to extract any archive file of the type .tar, .tar.gz,
.gz, .Z, tar.bz2, .tbz, .bz2, .zip, .xz,, .txz, .tar.xz or .lzma
without having to worry how it
does so, or use different interfaces for each type by using either
perl modules, or commandline tools on your system.

See the C<HOW IT WORKS> section further down for details.

=cut

### see what /bin/programs are available ###
$PROGRAMS = {};
CMD: for my $pgm (qw[tar unzip gzip bunzip2 uncompress unlzma unxz]) {
    if ( $pgm eq 'unzip' and ( ON_NETBSD or ON_FREEBSD ) ) {
      local $IPC::Cmd::INSTANCES = 1;
      ($PROGRAMS->{$pgm}) = grep { ON_NETBSD ? m!/usr/pkg/! : m!/usr/local! } can_run($pgm);
      next CMD;
    }
    if ( $pgm eq 'unzip' and ON_LINUX ) {
      # Check if 'unzip' is busybox masquerading
      local $IPC::Cmd::INSTANCES = 1;
      my $opt = ON_VMS ? '"-Z"' : '-Z';
      ($PROGRAMS->{$pgm}) = grep { scalar run(command=> [ $_, $opt, '-1' ]) } can_run($pgm);
      next CMD;
    }
    $PROGRAMS->{$pgm} = can_run($pgm);
}

### mapping from types to extractor methods ###
my $Mapping = {  # binary program           # pure perl module
    is_tgz  => { bin => '_untar_bin',       pp => '_untar_at'   },
    is_tar  => { bin => '_untar_bin',       pp => '_untar_at'   },
    is_gz   => { bin => '_gunzip_bin',      pp => '_gunzip_cz'  },
    is_zip  => { bin => '_unzip_bin',       pp => '_unzip_az'   },
    is_tbz  => { bin => '_untar_bin',       pp => '_untar_at'   },
    is_bz2  => { bin => '_bunzip2_bin',     pp => '_bunzip2_bz2'},
    is_Z    => { bin => '_uncompress_bin',  pp => '_gunzip_cz'  },
    is_lzma => { bin => '_unlzma_bin',      pp => '_unlzma_cz'  },
    is_xz   => { bin => '_unxz_bin',        pp => '_unxz_cz'    },
    is_txz  => { bin => '_untar_bin',       pp => '_untar_at'   },
};

{   ### use subs so we re-generate array refs etc for the no-override flags
    ### if we don't, then we reuse the same arrayref, meaning objects store
    ### previous errors
    my $tmpl = {
        archive         => sub { { required => 1, allow => FILE_EXISTS }    },
        type            => sub { { default => '', allow => [ @Types ] }     },
        _error_msg      => sub { { no_override => 1, default => [] }        },
        _error_msg_long => sub { { no_override => 1, default => [] }        },
    };

    ### build accessors ###
    for my $method( keys %$tmpl,
                    qw[_extractor _gunzip_to files extract_path],
    ) {
        no strict 'refs';
        *$method = sub {
                        my $self = shift;
                        $self->{$method} = $_[0] if @_;
                        return $self->{$method};
                    }
    }

=head1 METHODS

=head2 $ae = Archive::Extract->new(archive => '/path/to/archive',[type => TYPE])

Creates a new C<Archive::Extract> object based on the archive file you
passed it. Automatically determines the type of archive based on the
extension, but you can override that by explicitly providing the
C<type> argument.

Valid values for C<type> are:

=over 4

=item tar

Standard tar files, as produced by, for example, C</bin/tar>.
Corresponds to a C<.tar> suffix.

=item tgz

Gzip compressed tar files, as produced by, for example C</bin/tar -z>.
Corresponds to a C<.tgz> or C<.tar.gz> suffix.

=item gz

Gzip compressed file, as produced by, for example C</bin/gzip>.
Corresponds to a C<.gz> suffix.

=item Z

Lempel-Ziv compressed file, as produced by, for example C</bin/compress>.
Corresponds to a C<.Z> suffix.

=item zip

Zip compressed file, as produced by, for example C</bin/zip>.
Corresponds to a C<.zip>, C<.jar> or C<.par> suffix.

=item bz2

Bzip2 compressed file, as produced by, for example, C</bin/bzip2>.
Corresponds to a C<.bz2> suffix.

=item tbz

Bzip2 compressed tar file, as produced by, for example C</bin/tar -j>.
Corresponds to a C<.tbz> or C<.tar.bz2> suffix.

=item lzma

Lzma compressed file, as produced by C</bin/lzma>.
Corresponds to a C<.lzma> suffix.

=item xz

Xz compressed file, as produced by C</bin/xz>.
Corresponds to a C<.xz> suffix.

=item txz

Xz compressed tar file, as produced by, for example C</bin/tar -J>.
Corresponds to a C<.txz> or C<.tar.xz> suffix.

=back

Returns a C<Archive::Extract> object on success, or false on failure.

=cut

    ### constructor ###
    sub new {
        my $class   = shift;
        my %hash    = @_;

        ### see above why we use subs here and generate the template;
        ### it's basically to not re-use arrayrefs
        my %utmpl   = map { $_ => $tmpl->{$_}->() } keys %$tmpl;

        my $parsed = check( \%utmpl, \%hash ) or return;

        ### make sure we have an absolute path ###
        my $ar = $parsed->{archive} = File::Spec->rel2abs( $parsed->{archive} );

        ### figure out the type, if it wasn't already specified ###
        unless ( $parsed->{type} ) {
            $parsed->{type} =
                $ar =~ /.+?\.(?:tar\.gz|tgz)$/i         ? TGZ   :
                $ar =~ /.+?\.gz$/i                      ? GZ    :
                $ar =~ /.+?\.tar$/i                     ? TAR   :
                $ar =~ /.+?\.(zip|jar|ear|war|par)$/i   ? ZIP   :
                $ar =~ /.+?\.(?:tbz2?|tar\.bz2?)$/i     ? TBZ   :
                $ar =~ /.+?\.bz2$/i                     ? BZ2   :
                $ar =~ /.+?\.Z$/                        ? Z     :
                $ar =~ /.+?\.lzma$/                     ? LZMA  :
                $ar =~ /.+?\.(?:txz|tar\.xz)$/i         ? TXZ   :
                $ar =~ /.+?\.xz$/                       ? XZ    :
                '';

        }

        bless $parsed, $class;

        ### don't know what type of file it is
        ### XXX this *has* to be an object call, not a package call
        return $parsed->_error(loc("Cannot determine file type for '%1'",
                                $parsed->{archive} )) unless $parsed->{type};
        return $parsed;
    }
}

=head2 $ae->extract( [to => '/output/path'] )

Extracts the archive represented by the C<Archive::Extract> object to
the path of your choice as specified by the C<to> argument. Defaults to
C<cwd()>.

Since C<.gz> files never hold a directory, but only a single file; if
the C<to> argument is an existing directory, the file is extracted
there, with its C<.gz> suffix stripped.
If the C<to> argument is not an existing directory, the C<to> argument
is understood to be a filename, if the archive type is C<gz>.
In the case that you did not specify a C<to> argument, the output
file will be the name of the archive file, stripped from its C<.gz>
suffix, in the current working directory.

C<extract> will try a pure perl solution first, and then fall back to
commandline tools if they are available. See the C<GLOBAL VARIABLES>
section below on how to alter this behaviour.

It will return true on success, and false on failure.

On success, it will also set the follow attributes in the object:

=over 4

=item $ae->extract_path

This is the directory that the files where extracted to.

=item $ae->files

This is an array ref with the paths of all the files in the archive,
relative to the C<to> argument you specified.
To get the full path to an extracted file, you would use:

    File::Spec->catfile( $to, $ae->files->[0] );

Note that all files from a tar archive will be in unix format, as per
the tar specification.

=back

=cut

sub extract {
    my $self = shift;
    my %hash = @_;

    ### reset error messages
    $self->_error_msg( [] );
    $self->_error_msg_long( [] );

    my $to;
    my $tmpl = {
        to  => { default => '.', store => \$to }
    };

    check( $tmpl, \%hash ) or return;

    ### so 'to' could be a file or a dir, depending on whether it's a .gz
    ### file, or basically anything else.
    ### so, check that, then act accordingly.
    ### set an accessor specifically so _gunzip can know what file to extract
    ### to.
    my $dir;
    {   ### a foo.gz file
        if( $self->is_gz or $self->is_bz2 or $self->is_Z or $self->is_lzma or $self->is_xz ) {

            my $cp = $self->archive; $cp =~ s/\.(?:gz|bz2?|Z|lzma|xz)$//i;

            ### to is a dir?
            if ( -d $to ) {
                $dir = $to;
                $self->_gunzip_to( basename($cp) );

            ### then it's a filename
            } else {
                $dir = dirname($to);
                $self->_gunzip_to( basename($to) );
            }

        ### not a foo.gz file
        } else {
            $dir = $to;
        }
    }

    ### make the dir if it doesn't exist ###
    unless( -d $dir ) {
        eval { mkpath( $dir ) };

        return $self->_error(loc("Could not create path '%1': %2", $dir, $@))
            if $@;
    }

    ### get the current dir, to restore later ###
    my $cwd = cwd();

    my $ok = 1;
    EXTRACT: {

        ### chdir to the target dir ###
        unless( chdir $dir ) {
            $self->_error(loc("Could not chdir to '%1': %2", $dir, $!));
            $ok = 0; last EXTRACT;
        }

        ### set files to an empty array ref, so there's always an array
        ### ref IN the accessor, to avoid errors like:
        ### Can't use an undefined value as an ARRAY reference at
        ### ../lib/Archive/Extract.pm line 742. (rt #19815)
        $self->files( [] );

        ### find out the dispatch methods needed for this type of
        ### archive. Do a $self->is_XXX to figure out the type, then
        ### get the hashref with bin + pure perl dispatchers.
        my ($map) = map { $Mapping->{$_} } grep { $self->$_ } keys %$Mapping;

        ### add pure perl extractor if allowed & add bin extractor if allowed
        my @methods;
        push @methods, $map->{'pp'}  if $_ALLOW_PURE_PERL;
        push @methods, $map->{'bin'} if $_ALLOW_BIN;

        ### reverse it if we prefer bin extractors
        @methods = reverse @methods if $PREFER_BIN;

        my($na, $fail);
        for my $method (@methods) {
            $self->debug( "# Extracting with ->$method\n" );

            my $rv = $self->$method;

            ### a positive extraction
            if( $rv and $rv ne METHOD_NA ) {
                $self->debug( "# Extraction succeeded\n" );
                $self->_extractor($method);
                last;

            ### method is not available
            } elsif ( $rv and $rv eq METHOD_NA ) {
                $self->debug( "# Extraction method not available\n" );
                $na++;
            } else {
                $self->debug( "# Extraction method failed\n" );
                $fail++;
            }
        }

        ### warn something went wrong if we didn't get an extractor
        unless( $self->_extractor ) {
            my $diag = $fail ? loc("Extract failed due to errors") :
                       $na   ? loc("Extract failed; no extractors available") :
                       '';

            $self->_error($diag);
            $ok = 0;
        }
    }

    ### and chdir back ###
    unless( chdir $cwd ) {
        $self->_error(loc("Could not chdir back to start dir '%1': %2'",
                            $cwd, $!));
    }

    return $ok;
}

=pod

=head1 ACCESSORS

=head2 $ae->error([BOOL])

Returns the last encountered error as string.
Pass it a true value to get the C<Carp::longmess()> output instead.

=head2 $ae->extract_path

This is the directory the archive got extracted to.
See C<extract()> for details.

=head2 $ae->files

This is an array ref holding all the paths from the archive.
See C<extract()> for details.

=head2 $ae->archive

This is the full path to the archive file represented by this
C<Archive::Extract> object.

=head2 $ae->type

This is the type of archive represented by this C<Archive::Extract>
object. See accessors below for an easier way to use this.
See the C<new()> method for details.

=head2 $ae->types

Returns a list of all known C<types> for C<Archive::Extract>'s
C<new> method.

=cut

sub types { return @Types }

=head2 $ae->is_tgz

Returns true if the file is of type C<.tar.gz>.
See the C<new()> method for details.

=head2 $ae->is_tar

Returns true if the file is of type C<.tar>.
See the C<new()> method for details.

=head2 $ae->is_gz

Returns true if the file is of type C<.gz>.
See the C<new()> method for details.

=head2 $ae->is_Z

Returns true if the file is of type C<.Z>.
See the C<new()> method for details.

=head2 $ae->is_zip

Returns true if the file is of type C<.zip>.
See the C<new()> method for details.

=head2 $ae->is_lzma

Returns true if the file is of type C<.lzma>.
See the C<new()> method for details.

=head2 $ae->is_xz

Returns true if the file is of type C<.xz>.
See the C<new()> method for details.

=cut

### quick check methods ###
sub is_tgz  { return $_[0]->type eq TGZ }
sub is_tar  { return $_[0]->type eq TAR }
sub is_gz   { return $_[0]->type eq GZ  }
sub is_zip  { return $_[0]->type eq ZIP }
sub is_tbz  { return $_[0]->type eq TBZ }
sub is_bz2  { return $_[0]->type eq BZ2 }
sub is_Z    { return $_[0]->type eq Z   }
sub is_lzma { return $_[0]->type eq LZMA }
sub is_xz   { return $_[0]->type eq XZ   }
sub is_txz  { return $_[0]->type eq TXZ }

=pod

=head2 $ae->bin_tar

Returns the full path to your tar binary, if found.

=head2 $ae->bin_gzip

Returns the full path to your gzip binary, if found

=head2 $ae->bin_unzip

Returns the full path to your unzip binary, if found

=head2 $ae->bin_unlzma

Returns the full path to your unlzma binary, if found

=head2 $ae->bin_unxz

Returns the full path to your unxz binary, if found

=cut

### paths to commandline tools ###
sub bin_gzip        { return $PROGRAMS->{'gzip'}    if $PROGRAMS->{'gzip'}  }
sub bin_unzip       { return $PROGRAMS->{'unzip'}   if $PROGRAMS->{'unzip'} }
sub bin_tar         { return $PROGRAMS->{'tar'}     if $PROGRAMS->{'tar'}   }
sub bin_bunzip2     { return $PROGRAMS->{'bunzip2'} if $PROGRAMS->{'bunzip2'} }
sub bin_uncompress  { return $PROGRAMS->{'uncompress'}
                                                 if $PROGRAMS->{'uncompress'} }
sub bin_unlzma      { return $PROGRAMS->{'unlzma'}  if $PROGRAMS->{'unlzma'} }
sub bin_unxz        { return $PROGRAMS->{'unxz'}    if $PROGRAMS->{'unxz'} }

=head2 $bool = $ae->have_old_bunzip2

Older versions of C</bin/bunzip2>, from before the C<bunzip2 1.0> release,
require all archive names to end in C<.bz2> or it will not extract
them. This method checks if you have a recent version of C<bunzip2>
that allows any extension, or an older one that doesn't.

=cut

sub have_old_bunzip2 {
    my $self = shift;

    ### no bunzip2? no old bunzip2 either :)
    return unless $self->bin_bunzip2;

    ### if we can't run this, we can't be sure if it's too old or not
    ### XXX stupid stupid stupid bunzip2 doesn't understand --version
    ### is not a request to extract data:
    ### $ bunzip2 --version
    ### bzip2, a block-sorting file compressor.  Version 1.0.2, 30-Dec-2001.
    ### [...]
    ### bunzip2: I won't read compressed data from a terminal.
    ### bunzip2: For help, type: `bunzip2 --help'.
    ### $ echo $?
    ### 1
    ### HATEFUL!

    ### double hateful: bunzip2 --version also hangs if input is a pipe
    ### See #32370: Archive::Extract will hang if stdin is a pipe [+PATCH]
    ### So, we have to provide *another* argument which is a fake filename,
    ### just so it wont try to read from stdin to print its version..
    ### *sigh*
    ### Even if the file exists, it won't clobber or change it.
    my $buffer;
    scalar run(
         command => [$self->bin_bunzip2, '--version', 'NoSuchFile'],
         verbose => 0,
         buffer  => \$buffer
    );

    ### no output
    return unless $buffer;

    my ($version) = $buffer =~ /version \s+ (\d+)/ix;

    return 1 if $version < 1;
    return;
}

#################################
#
# Untar code
#
#################################

### annoying issue with (gnu) tar on win32, as illustrated by this
### bug: https://rt.cpan.org/Ticket/Display.html?id=40138
### which shows that (gnu) tar will interpret a file name with a :
### in it as a remote file name, so C:\tmp\foo.txt is interpreted
### as a remote shell, and the extract fails.
{   my @ExtraTarFlags;
    if( ON_WIN32 and my $cmd = __PACKAGE__->bin_tar ) {

        ### if this is gnu tar we are running, we need to use --force-local
        push @ExtraTarFlags, '--force-local' if `$cmd --version` =~ /gnu tar/i;
    }

    ### use /bin/tar to extract ###
    sub _untar_bin {
        my $self = shift;

        ### check for /bin/tar ###
        ### check for /bin/gzip if we need it ###
        ### if any of the binaries are not available, return NA
        {   my $diag =  not $self->bin_tar ?
                            loc("No '%1' program found", '/bin/tar') :
                        $self->is_tgz && !$self->bin_gzip ?
                            loc("No '%1' program found", '/bin/gzip') :
                        $self->is_tbz && !$self->bin_bunzip2 ?
                            loc("No '%1' program found", '/bin/bunzip2') :
                        $self->is_txz && !$self->bin_unxz ?
                            loc("No '%1' program found", '/bin/unxz') :
                        '';

            if( $diag ) {
                $self->_error( $diag );
                return METHOD_NA;
            }
        }

        ### XXX figure out how to make IPC::Run do this in one call --
        ### currently i don't know how to get output of a command after a pipe
        ### trapped in a scalar. Mailed barries about this 5th of june 2004.

        ### see what command we should run, based on whether
        ### it's a .tgz or .tar

        ### GNU tar can't handled VMS filespecs, but VMSTAR can handle Unix filespecs.
        my $archive = $self->archive;
        $archive = VMS::Filespec::unixify($archive) if ON_VMS;

        ### XXX solaris tar and bsdtar are having different outputs
        ### depending whether you run with -x or -t
        ### compensate for this insanity by running -t first, then -x
        {    my $cmd =
                $self->is_tgz ? [$self->bin_gzip, '-cdf', $archive, '|',
                                 $self->bin_tar, '-tf', '-'] :
                $self->is_tbz ? [$self->bin_bunzip2, '-cd', $archive, '|',
                                 $self->bin_tar, '-tf', '-'] :
                $self->is_txz ? [$self->bin_unxz, '-cd', $archive, '|',
                                 $self->bin_tar, '-tf', '-'] :
                [$self->bin_tar, @ExtraTarFlags, '-tf', $archive];

            ### run the command
            ### newer versions of 'tar' (1.21 and up) now print record size
            ### to STDERR as well if v OR t is given (used to be both). This
            ### is a 'feature' according to the changelog, so we must now only
            ### inspect STDOUT, otherwise, failures like these occur:
            ### http://www.cpantesters.org/cpan/report/3230366
            my $buffer  = '';
            my @out     = run(  command => $cmd,
                                buffer  => \$buffer,
                                verbose => $DEBUG );

            ### command was unsuccessful
            unless( $out[0] ) {
                return $self->_error(loc(
                                "Error listing contents of archive '%1': %2",
                                $archive, $buffer ));
            }

            ### no buffers available?
            if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
                $self->_error( $self->_no_buffer_files( $archive ) );

            } else {
                ### if we're on solaris we /might/ be using /bin/tar, which has
                ### a weird output format... we might also be using
                ### /usr/local/bin/tar, which is gnu tar, which is perfectly
                ### fine... so we have to do some guessing here =/
                my @files = map { chomp;
                              !ON_SOLARIS ? $_
                                          : (m|^ x \s+  # 'xtract' -- sigh
                                                (.+?),  # the actual file name
                                                \s+ [\d,.]+ \s bytes,
                                                \s+ [\d,.]+ \s tape \s blocks
                                            |x ? $1 : $_);

                        ### only STDOUT, see above. Sometimes, extra whitespace
                        ### is present, so make sure we only pick lines with
                        ### a length
                        } grep { length } map { split $/, $_ } join '', @{$out[3]};

                ### store the files that are in the archive ###
                $self->files(\@files);
            }
        }

        ### now actually extract it ###
        {   my $cmd =
                $self->is_tgz ? [$self->bin_gzip, '-cdf', $archive, '|',
                                 $self->bin_tar, '-xf', '-'] :
                $self->is_tbz ? [$self->bin_bunzip2, '-cd', $archive, '|',
                                 $self->bin_tar, '-xf', '-'] :
                $self->is_txz ? [$self->bin_unxz, '-cd', $archive, '|',
                                 $self->bin_tar, '-xf', '-'] :
                [$self->bin_tar, @ExtraTarFlags, '-xf', $archive];

            my $buffer = '';
            unless( scalar run( command => $cmd,
                                buffer  => \$buffer,
                                verbose => $DEBUG )
            ) {
                return $self->_error(loc("Error extracting archive '%1': %2",
                                $archive, $buffer ));
            }

            ### we might not have them, due to lack of buffers
            if( $self->files ) {
                ### now that we've extracted, figure out where we extracted to
                my $dir = $self->__get_extract_dir( $self->files );

                ### store the extraction dir ###
                $self->extract_path( $dir );
            }
        }

        ### we got here, no error happened
        return 1;
    }
}

### use archive::tar to extract ###
sub _untar_at {
    my $self = shift;

    ### Loading Archive::Tar is going to set it to 1, so make it local
    ### within this block, starting with its initial value. Whatever
    ### Achive::Tar does will be undone when we return.
    ###
    ### Also, later, set $Archive::Tar::WARN to $Archive::Extract::WARN
    ### so users don't have to even think about this variable. If they
    ### do, they still get their set value outside of this call.
    local $Archive::Tar::WARN = $Archive::Tar::WARN;

    ### we definitely need Archive::Tar, so load that first
    {   my $use_list = { 'Archive::Tar' => '0.0' };

        unless( can_load( modules => $use_list ) ) {

            $self->_error(loc("You do not have '%1' installed - " .
                              "Please install it as soon as possible.",
                              'Archive::Tar'));

            return METHOD_NA;
        }
    }

    ### we might pass it a filehandle if it's a .tbz file..
    my $fh_to_read = $self->archive;

    ### we will need Compress::Zlib too, if it's a tgz... and IO::Zlib
    ### if A::T's version is 0.99 or higher
    if( $self->is_tgz ) {
        my $use_list = { 'Compress::Zlib' => '0.0' };
           $use_list->{ 'IO::Zlib' } = '0.0'
                if $Archive::Tar::VERSION >= '0.99';

        unless( can_load( modules => $use_list ) ) {
            my $which = join '/', sort keys %$use_list;

            $self->_error(loc(
                "You do not have '%1' installed - Please ".
                "install it as soon as possible.", $which)
            );

            return METHOD_NA;
        }

    } elsif ( $self->is_tbz ) {
        my $use_list = { 'IO::Uncompress::Bunzip2' => '0.0' };
        unless( can_load( modules => $use_list ) ) {
            $self->_error(loc(
                "You do not have '%1' installed - Please " .
                "install it as soon as possible.",
                'IO::Uncompress::Bunzip2')
            );

            return METHOD_NA;
        }

        my $bz = IO::Uncompress::Bunzip2->new( $self->archive ) or
            return $self->_error(loc("Unable to open '%1': %2",
                            $self->archive,
                            $IO::Uncompress::Bunzip2::Bunzip2Error));

        $fh_to_read = $bz;
    } elsif ( $self->is_txz ) {
        my $use_list = { 'IO::Uncompress::UnXz' => '0.0' };
        unless( can_load( modules => $use_list ) ) {
            $self->_error(loc(
                "You do not have '%1' installed - Please " .
                "install it as soon as possible.",
                'IO::Uncompress::UnXz')
            );

            return METHOD_NA;
        }

        my $xz = IO::Uncompress::UnXz->new( $self->archive ) or
            return $self->_error(loc("Unable to open '%1': %2",
                            $self->archive,
                            $IO::Uncompress::UnXz::UnXzError));

        $fh_to_read = $xz;
    }

    my @files;
    {
        ### $Archive::Tar::WARN is 1 by default in Archive::Tar, but we've
        ### localized $Archive::Tar::WARN already.
        $Archive::Tar::WARN = $Archive::Extract::WARN;

        ### only tell it it's compressed if it's a .tgz, as we give it a file
        ### handle if it's a .tbz
        my @read = ( $fh_to_read, ( $self->is_tgz ? 1 : 0 ) );

        ### for version of Archive::Tar > 1.04
        local $Archive::Tar::CHOWN = 0;

        ### use the iterator if we can. it's a feature of A::T 1.40 and up
        if ( $_ALLOW_TAR_ITER && Archive::Tar->can( 'iter' ) ) {

            my $next;
            unless ( $next = Archive::Tar->iter( @read ) ) {
                return $self->_error(loc(
                            "Unable to read '%1': %2", $self->archive,
                            $Archive::Tar::error));
            }

            while ( my $file = $next->() ) {
                push @files, $file->full_path;

                $file->extract or return $self->_error(loc(
                        "Unable to read '%1': %2",
                        $self->archive,
                        $Archive::Tar::error));
            }

        ### older version, read the archive into memory
        } else {

            my $tar = Archive::Tar->new();

            unless( $tar->read( @read ) ) {
                return $self->_error(loc("Unable to read '%1': %2",
                            $self->archive, $Archive::Tar::error));
            }

            ### workaround to prevent Archive::Tar from setting uid, which
            ### is a potential security hole. -autrijus
            ### have to do it here, since A::T needs to be /loaded/ first ###
            {   no strict 'refs'; local $^W;

                ### older versions of archive::tar <= 0.23
                *Archive::Tar::chown = sub {};
            }

            {   local $^W;  # quell 'splice() offset past end of array' warnings
                            # on older versions of A::T

                ### older archive::tar always returns $self, return value
                ### slightly fux0r3d because of it.
                $tar->extract or return $self->_error(loc(
                        "Unable to extract '%1': %2",
                        $self->archive, $Archive::Tar::error ));
            }

            @files = $tar->list_files;
        }
    }

    my $dir = $self->__get_extract_dir( \@files );

    ### store the files that are in the archive ###
    $self->files(\@files);

    ### store the extraction dir ###
    $self->extract_path( $dir );

    ### check if the dir actually appeared ###
    return 1 if -d $self->extract_path;

    ### no dir, we failed ###
    return $self->_error(loc("Unable to extract '%1': %2",
                                $self->archive, $Archive::Tar::error ));
}

#################################
#
# Gunzip code
#
#################################

sub _gunzip_bin {
    my $self = shift;

    ### check for /bin/gzip -- we need it ###
    unless( $self->bin_gzip ) {
        $self->_error(loc("No '%1' program found", '/bin/gzip'));
        return METHOD_NA;
    }

    my $fh = FileHandle->new('>'. $self->_gunzip_to) or
        return $self->_error(loc("Could not open '%1' for writing: %2",
                            $self->_gunzip_to, $! ));

    my $cmd = [ $self->bin_gzip, '-cdf', $self->archive ];

    my $buffer;
    unless( scalar run( command => $cmd,
                        verbose => $DEBUG,
                        buffer  => \$buffer )
    ) {
        return $self->_error(loc("Unable to gunzip '%1': %2",
                                    $self->archive, $buffer));
    }

    ### no buffers available?
    if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
        $self->_error( $self->_no_buffer_content( $self->archive ) );
    }

    $self->_print($fh, $buffer) if defined $buffer;

    close $fh;

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

sub _gunzip_cz {
    my $self = shift;

    my $use_list = { 'Compress::Zlib' => '0.0' };
    unless( can_load( modules => $use_list ) ) {
        $self->_error(loc("You do not have '%1' installed - Please " .
                    "install it as soon as possible.", 'Compress::Zlib'));
        return METHOD_NA;
    }

    my $gz = Compress::Zlib::gzopen( $self->archive, "rb" ) or
                return $self->_error(loc("Unable to open '%1': %2",
                            $self->archive, $Compress::Zlib::gzerrno));

    my $fh = FileHandle->new('>'. $self->_gunzip_to) or
        return $self->_error(loc("Could not open '%1' for writing: %2",
                            $self->_gunzip_to, $! ));

    my $buffer;
    $self->_print($fh, $buffer) while $gz->gzread($buffer) > 0;
    $fh->close;

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

#################################
#
# Uncompress code
#
#################################

sub _uncompress_bin {
    my $self = shift;

    ### check for /bin/gzip -- we need it ###
    unless( $self->bin_uncompress ) {
        $self->_error(loc("No '%1' program found", '/bin/uncompress'));
        return METHOD_NA;
    }

    my $fh = FileHandle->new('>'. $self->_gunzip_to) or
        return $self->_error(loc("Could not open '%1' for writing: %2",
                            $self->_gunzip_to, $! ));

    my $cmd = [ $self->bin_uncompress, '-c', $self->archive ];

    my $buffer;
    unless( scalar run( command => $cmd,
                        verbose => $DEBUG,
                        buffer  => \$buffer )
    ) {
        return $self->_error(loc("Unable to uncompress '%1': %2",
                                    $self->archive, $buffer));
    }

    ### no buffers available?
    if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
        $self->_error( $self->_no_buffer_content( $self->archive ) );
    }

    $self->_print($fh, $buffer) if defined $buffer;

    close $fh;

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

#################################
#
# Unzip code
#
#################################

sub _unzip_bin {
    my $self = shift;

    ### check for /bin/gzip if we need it ###
    unless( $self->bin_unzip ) {
        $self->_error(loc("No '%1' program found", '/bin/unzip'));
        return METHOD_NA;
    }

    ### first, get the files.. it must be 2 different commands with 'unzip' :(
    {   ### on VMS, capital letter options have to be quoted. This is
        ### reported by John Malmberg on P5P Tue 21 Aug 2007 05:05:11
        ### Subject: [patch@31735]Archive Extract fix on VMS.
        my $opt = ON_VMS ? '"-Z"' : '-Z';
        my $cmd = [ $self->bin_unzip, $opt, '-1', $self->archive ];

        my $buffer = '';
        unless( scalar run( command => $cmd,
                            verbose => $DEBUG,
                            buffer  => \$buffer )
        ) {
            return $self->_error(loc("Unable to unzip '%1': %2",
                                        $self->archive, $buffer));
        }

        ### no buffers available?
        if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
            $self->_error( $self->_no_buffer_files( $self->archive ) );

        } else {
            ### Annoyingly, pesky MSWin32 can either have 'native' tools
            ### which have \r\n line endings or Cygwin-based tools which
            ### have \n line endings. Jan Dubois suggested using this fix
            local $/ = ON_WIN32 ? qr/\r?\n/ : "\n";
            $self->files( [split $/, $buffer] );
        }
    }

    ### now, extract the archive ###
    {   my $cmd = [ $self->bin_unzip, '-qq', '-o', $self->archive ];

        my $buffer;
        unless( scalar run( command => $cmd,
                            verbose => $DEBUG,
                            buffer  => \$buffer )
        ) {
            return $self->_error(loc("Unable to unzip '%1': %2",
                                        $self->archive, $buffer));
        }

        if( scalar @{$self->files} ) {
            my $files   = $self->files;
            my $dir     = $self->__get_extract_dir( $files );

            $self->extract_path( $dir );
        }
    }

    return 1;
}

sub _unzip_az {
    my $self = shift;

    my $use_list = { 'Archive::Zip' => '0.0' };
    unless( can_load( modules => $use_list ) ) {
        $self->_error(loc("You do not have '%1' installed - Please " .
                      "install it as soon as possible.", 'Archive::Zip'));
        return METHOD_NA;
    }

    my $zip = Archive::Zip->new();

    unless( $zip->read( $self->archive ) == &Archive::Zip::AZ_OK ) {
        return $self->_error(loc("Unable to read '%1'", $self->archive));
    }

    my @files;

    ### Address: #43278: Explicitly tell Archive::Zip where to put the files:
    ### "In my BackPAN indexing, Archive::Zip was extracting things
    ### in my script's directory instead of the current working directory.
    ### I traced this back through Archive::Zip::_asLocalName which
    ### eventually calls File::Spec::Win32::rel2abs which on Windows might
    ### call Cwd::getdcwd. getdcwd returns the wrong directory in my
    ### case, even though I think I'm on the same drive.
    ###
    ### To fix this, I pass the optional second argument to
    ### extractMember using the cwd from Archive::Extract." --bdfoy

    ## store cwd() before looping; calls to cwd() can be expensive, and
    ### it won't change during the loop
    my $extract_dir = cwd();

    ### have to extract every member individually ###
    for my $member ($zip->members) {
        push @files, $member->{fileName};

        ### file to extract to, to avoid the above problem
        my $to = File::Spec->catfile( $extract_dir, $member->{fileName} );

        unless( $zip->extractMember($member, $to) == &Archive::Zip::AZ_OK ) {
            return $self->_error(loc("Extraction of '%1' from '%2' failed",
                        $member->{fileName}, $self->archive ));
        }
    }

    my $dir = $self->__get_extract_dir( \@files );

    ### set what files where extract, and where they went ###
    $self->files( \@files );
    $self->extract_path( File::Spec->rel2abs($dir) );

    return 1;
}

sub __get_extract_dir {
    my $self    = shift;
    my $files   = shift || [];

    return unless scalar @$files;

    my($dir1, $dir2);
    for my $aref ( [ \$dir1, 0 ], [ \$dir2, -1 ] ) {
        my($dir,$pos) = @$aref;

        ### add a catdir(), so that any trailing slashes get
        ### take care of (removed)
        ### also, a catdir() normalises './dir/foo' to 'dir/foo';
        ### which was the problem in bug #23999
        my $res = -d $files->[$pos]
                    ? File::Spec->catdir( $files->[$pos], '' )
                    : File::Spec->catdir( dirname( $files->[$pos] ) );

        $$dir = $res;
    }

    ### if the first and last dir don't match, make sure the
    ### dirname is not set wrongly
    my $dir;

    ### dirs are the same, so we know for sure what the extract dir is
    if( $dir1 eq $dir2 ) {
        $dir = $dir1;

    ### dirs are different.. do they share the base dir?
    ### if so, use that, if not, fall back to '.'
    } else {
        my $base1 = [ File::Spec->splitdir( $dir1 ) ]->[0];
        my $base2 = [ File::Spec->splitdir( $dir2 ) ]->[0];

        $dir = File::Spec->rel2abs( $base1 eq $base2 ? $base1 : '.' );
    }

    return File::Spec->rel2abs( $dir );
}

#################################
#
# Bunzip2 code
#
#################################

sub _bunzip2_bin {
    my $self = shift;

    ### check for /bin/gzip -- we need it ###
    unless( $self->bin_bunzip2 ) {
        $self->_error(loc("No '%1' program found", '/bin/bunzip2'));
        return METHOD_NA;
    }

    my $fh = FileHandle->new('>'. $self->_gunzip_to) or
        return $self->_error(loc("Could not open '%1' for writing: %2",
                            $self->_gunzip_to, $! ));

    ### guard against broken bunzip2. See ->have_old_bunzip2()
    ### for details
    if( $self->have_old_bunzip2 and $self->archive !~ /\.bz2$/i ) {
        return $self->_error(loc("Your bunzip2 version is too old and ".
                                 "can only extract files ending in '%1'",
                                 '.bz2'));
    }

    my $cmd = [ $self->bin_bunzip2, '-cd', $self->archive ];

    my $buffer;
    unless( scalar run( command => $cmd,
                        verbose => $DEBUG,
                        buffer  => \$buffer )
    ) {
        return $self->_error(loc("Unable to bunzip2 '%1': %2",
                                    $self->archive, $buffer));
    }

    ### no buffers available?
    if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
        $self->_error( $self->_no_buffer_content( $self->archive ) );
    }

    $self->_print($fh, $buffer) if defined $buffer;

    close $fh;

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

### using cz2, the compact versions... this we use mainly in archive::tar
### extractor..
# sub _bunzip2_cz1 {
#     my $self = shift;
#
#     my $use_list = { 'IO::Uncompress::Bunzip2' => '0.0' };
#     unless( can_load( modules => $use_list ) ) {
#         return $self->_error(loc("You do not have '%1' installed - Please " .
#                         "install it as soon as possible.",
#                         'IO::Uncompress::Bunzip2'));
#     }
#
#     my $bz = IO::Uncompress::Bunzip2->new( $self->archive ) or
#                 return $self->_error(loc("Unable to open '%1': %2",
#                             $self->archive,
#                             $IO::Uncompress::Bunzip2::Bunzip2Error));
#
#     my $fh = FileHandle->new('>'. $self->_gunzip_to) or
#         return $self->_error(loc("Could not open '%1' for writing: %2",
#                             $self->_gunzip_to, $! ));
#
#     my $buffer;
#     $fh->print($buffer) while $bz->read($buffer) > 0;
#     $fh->close;
#
#     ### set what files where extract, and where they went ###
#     $self->files( [$self->_gunzip_to] );
#     $self->extract_path( File::Spec->rel2abs(cwd()) );
#
#     return 1;
# }

sub _bunzip2_bz2 {
    my $self = shift;

    my $use_list = { 'IO::Uncompress::Bunzip2' => '0.0' };
    unless( can_load( modules => $use_list ) ) {
        $self->_error(loc("You do not have '%1' installed - Please " .
                          "install it as soon as possible.",
                          'IO::Uncompress::Bunzip2'));
        return METHOD_NA;
    }

    IO::Uncompress::Bunzip2::bunzip2($self->archive => $self->_gunzip_to)
        or return $self->_error(loc("Unable to uncompress '%1': %2",
                            $self->archive,
                            $IO::Uncompress::Bunzip2::Bunzip2Error));

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

#################################
#
# UnXz code
#
#################################

sub _unxz_bin {
    my $self = shift;

    ### check for /bin/unxz -- we need it ###
    unless( $self->bin_unxz ) {
        $self->_error(loc("No '%1' program found", '/bin/unxz'));
        return METHOD_NA;
    }

    my $fh = FileHandle->new('>'. $self->_gunzip_to) or
        return $self->_error(loc("Could not open '%1' for writing: %2",
                            $self->_gunzip_to, $! ));

    my $cmd = [ $self->bin_unxz, '-cdf', $self->archive ];

    my $buffer;
    unless( scalar run( command => $cmd,
                        verbose => $DEBUG,
                        buffer  => \$buffer )
    ) {
        return $self->_error(loc("Unable to unxz '%1': %2",
                                    $self->archive, $buffer));
    }

    ### no buffers available?
    if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
        $self->_error( $self->_no_buffer_content( $self->archive ) );
    }

    $self->_print($fh, $buffer) if defined $buffer;

    close $fh;

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

sub _unxz_cz {
    my $self = shift;

    my $use_list = { 'IO::Uncompress::UnXz' => '0.0' };
    unless( can_load( modules => $use_list ) ) {
        $self->_error(loc("You do not have '%1' installed - Please " .
                          "install it as soon as possible.",
                          'IO::Uncompress::UnXz'));
        return METHOD_NA;
    }

    IO::Uncompress::UnXz::unxz($self->archive => $self->_gunzip_to)
        or return $self->_error(loc("Unable to uncompress '%1': %2",
                            $self->archive,
                            $IO::Uncompress::UnXz::UnXzError));

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

#################################
#
# unlzma code
#
#################################

sub _unlzma_bin {
    my $self = shift;

    ### check for /bin/unlzma -- we need it ###
    unless( $self->bin_unlzma ) {
        $self->_error(loc("No '%1' program found", '/bin/unlzma'));
        return METHOD_NA;
    }

    my $fh = FileHandle->new('>'. $self->_gunzip_to) or
        return $self->_error(loc("Could not open '%1' for writing: %2",
                            $self->_gunzip_to, $! ));

    my $cmd = [ $self->bin_unlzma, '-c', $self->archive ];

    my $buffer;
    unless( scalar run( command => $cmd,
                        verbose => $DEBUG,
                        buffer  => \$buffer )
    ) {
        return $self->_error(loc("Unable to unlzma '%1': %2",
                                    $self->archive, $buffer));
    }

    ### no buffers available?
    if( !IPC::Cmd->can_capture_buffer and !$buffer ) {
        $self->_error( $self->_no_buffer_content( $self->archive ) );
    }

    $self->_print($fh, $buffer) if defined $buffer;

    close $fh;

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

sub _unlzma_cz {
    my $self = shift;

    my $use_list1 = { 'IO::Uncompress::UnLzma' => '0.0' };
    my $use_list2 = { 'Compress::unLZMA' => '0.0' };

    if (can_load( modules => $use_list1 ) ) {
        IO::Uncompress::UnLzma::unlzma($self->archive => $self->_gunzip_to)
            or return $self->_error(loc("Unable to uncompress '%1': %2",
                                $self->archive,
                                $IO::Uncompress::UnLzma::UnLzmaError));
    }
    elsif (can_load( modules => $use_list2 ) ) {

        my $fh = FileHandle->new('>'. $self->_gunzip_to) or
            return $self->_error(loc("Could not open '%1' for writing: %2",
                                $self->_gunzip_to, $! ));

        my $buffer;
        $buffer = Compress::unLZMA::uncompressfile( $self->archive );
        unless ( defined $buffer ) {
            return $self->_error(loc("Could not unlzma '%1': %2",
                                        $self->archive, $@));
        }

        $self->_print($fh, $buffer) if defined $buffer;

        close $fh;
    }
    else {
        $self->_error(loc("You do not have '%1' or '%2' installed - Please " .
                    "install it as soon as possible.", 'Compress::unLZMA', 'IO::Uncompress::UnLzma'));
        return METHOD_NA;
    }

    ### set what files where extract, and where they went ###
    $self->files( [$self->_gunzip_to] );
    $self->extract_path( File::Spec->rel2abs(cwd()) );

    return 1;
}

#################################
#
# Error code
#
#################################

# For printing binaries that avoids interfering globals
sub _print {
    my $self = shift;
    my $fh = shift;

    local( $\, $", $, ) = ( undef, ' ', '' );
    return print $fh @_;
}

sub _error {
    my $self    = shift;
    my $error   = shift;
    my $lerror  = Carp::longmess($error);

    push @{$self->_error_msg},      $error;
    push @{$self->_error_msg_long}, $lerror;

    ### set $Archive::Extract::WARN to 0 to disable printing
    ### of errors
    if( $WARN ) {
        carp $DEBUG ? $lerror : $error;
    }

    return;
}

sub error {
    my $self = shift;

    ### make sure we have a fallback aref
    my $aref = do {
        shift()
            ? $self->_error_msg_long
            : $self->_error_msg
    } || [];

    return join $/, @$aref;
}

=head2 debug( MESSAGE )

This method outputs MESSAGE to the default filehandle if C<$DEBUG> is
true. It's a small method, but it's here if you'd like to subclass it
so you can so something else with any debugging output.

=cut

### this is really a stub for subclassing
sub debug {
    return unless $DEBUG;

    print $_[1];
}

sub _no_buffer_files {
    my $self = shift;
    my $file = shift or return;
    return loc("No buffer captured, unable to tell ".
               "extracted files or extraction dir for '%1'", $file);
}

sub _no_buffer_content {
    my $self = shift;
    my $file = shift or return;
    return loc("No buffer captured, unable to get content for '%1'", $file);
}
1;

=pod

=head1 HOW IT WORKS

C<Archive::Extract> tries first to determine what type of archive you
are passing it, by inspecting its suffix. It does not do this by using
Mime magic, or something related. See C<CAVEATS> below.

Once it has determined the file type, it knows which extraction methods
it can use on the archive. It will try a perl solution first, then fall
back to a commandline tool if that fails. If that also fails, it will
return false, indicating it was unable to extract the archive.
See the section on C<GLOBAL VARIABLES> to see how to alter this order.

=head1 CAVEATS

=head2 File Extensions

C<Archive::Extract> trusts on the extension of the archive to determine
what type it is, and what extractor methods therefore can be used. If
your archives do not have any of the extensions as described in the
C<new()> method, you will have to specify the type explicitly, or
C<Archive::Extract> will not be able to extract the archive for you.

=head2 Supporting Very Large Files

C<Archive::Extract> can use either pure perl modules or command line
programs under the hood. Some of the pure perl modules (like
C<Archive::Tar> and Compress::unLZMA) take the entire contents of the archive into memory,
which may not be feasible on your system. Consider setting the global
variable C<$Archive::Extract::PREFER_BIN> to C<1>, which will prefer
the use of command line programs and won't consume so much memory.

See the C<GLOBAL VARIABLES> section below for details.

=head2 Bunzip2 support of arbitrary extensions.

Older versions of C</bin/bunzip2> do not support arbitrary file
extensions and insist on a C<.bz2> suffix. Although we do our best
to guard against this, if you experience a bunzip2 error, it may
be related to this. For details, please see the C<have_old_bunzip2>
method.

=head1 GLOBAL VARIABLES

=head2 $Archive::Extract::DEBUG

Set this variable to C<true> to have all calls to command line tools
be printed out, including all their output.
This also enables C<Carp::longmess> errors, instead of the regular
C<carp> errors.

Good for tracking down why things don't work with your particular
setup.

Defaults to C<false>.

=head2 $Archive::Extract::WARN

This variable controls whether errors encountered internally by
C<Archive::Extract> should be C<carp>'d or not.

Set to false to silence warnings. Inspect the output of the C<error()>
method manually to see what went wrong.

Defaults to C<true>.

=head2 $Archive::Extract::PREFER_BIN

This variables controls whether C<Archive::Extract> should prefer the
use of perl modules, or commandline tools to extract archives.

Set to C<true> to have C<Archive::Extract> prefer commandline tools.

Defaults to C<false>.

=head1 TODO / CAVEATS

=over 4

=item Mime magic support

Maybe this module should use something like C<File::Type> to determine
the type, rather than blindly trust the suffix.

=item Thread safety

Currently, C<Archive::Extract> does a C<chdir> to the extraction dir before
extraction, and a C<chdir> back again after. This is not necessarily
thread safe. See C<rt.cpan.org> bug C<#45671> for details.

=back

=head1 BUG REPORTS

Please report bugs or other issues to E<lt>bug-archive-extract@rt.cpan.org<gt>.

=head1 AUTHOR

This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.

=head1 COPYRIGHT

This library is free software; you may redistribute and/or modify it
under the same terms as Perl itself.

=cut

# Local variables:
# c-indentation-style: bsd
# c-basic-offset: 4
# indent-tabs-mode: nil
# End:
# vim: expandtab shiftwidth=4:


text:
package org.apache.hadoop.mapreduce.lib.input;

import java.io.IOException;

import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.Seekable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.CodecPool;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.SplitCompressionInputStream;
import org.apache.hadoop.io.compress.SplittableCompressionCodec;
import org.apache.hadoop.io.compress.CompressionCodecFactory;
import org.apache.hadoop.io.compress.Decompressor;
import org.apache.hadoop.mapreduce.InputSplit;
import org.apache.hadoop.mapreduce.RecordReader;
import org.apache.hadoop.mapreduce.TaskAttemptContext;
import org.apache.hadoop.util.LineReader;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;

/**
 * Treats keys as offset in file and value as line.
 */
@InterfaceAudience.LimitedPrivate({"MapReduce", "Pig"})
@InterfaceStability.Evolving
public class LineRecordReader extends RecordReader<LongWritable, Text> {
  private static final Log LOG = LogFactory.getLog(LineRecordReader.class);
  public static final String MAX_LINE_LENGTH =
    "mapreduce.input.linerecordreader.line.maxlength";

  private CompressionCodecFactory compressionCodecs = null;
  private long start;
  private long pos;
  private long end;
  private LineReader in;
  private FSDataInputStream fileIn;
  private Seekable filePosition;
  private int maxLineLength;
  private LongWritable key = null;
  private Text value = null;
  private CompressionCodec codec;
  private Decompressor decompressor;
  private byte[] recordDelimiterBytes;

  public LineRecordReader() {
  }

  public LineRecordReader(byte[] recordDelimiter) {
    this.recordDelimiterBytes = recordDelimiter;
  }

  public void initialize(InputSplit genericSplit,
                         TaskAttemptContext context) throws IOException {
    FileSplit split = (FileSplit) genericSplit;
    Configuration job = context.getConfiguration();
    this.maxLineLength = job.getInt(MAX_LINE_LENGTH, Integer.MAX_VALUE);
    start = split.getStart();
    end = start + split.getLength();
    final Path file = split.getPath();
    compressionCodecs = new CompressionCodecFactory(job);
    codec = compressionCodecs.getCodec(file);

    // open the file and seek to the start of the split
    final FileSystem fs = file.getFileSystem(job);
    fileIn = fs.open(file);
    if (isCompressedInput()) {
      decompressor = CodecPool.getDecompressor(codec);
      if (codec instanceof SplittableCompressionCodec) {
        final SplitCompressionInputStream cIn =
          ((SplittableCompressionCodec)codec).createInputStream(
            fileIn, decompressor, start, end,
            SplittableCompressionCodec.READ_MODE.BYBLOCK);
        if (null == this.recordDelimiterBytes){
          in = new LineReader(cIn, job);
        } else {
          in = new LineReader(cIn, job, this.recordDelimiterBytes);
        }

        start = cIn.getAdjustedStart();
        end = cIn.getAdjustedEnd();
        filePosition = cIn;
      } else {
        if (null == this.recordDelimiterBytes) {
          in = new LineReader(codec.createInputStream(fileIn, decompressor),
              job);
        } else {
          in = new LineReader(codec.createInputStream(fileIn,
              decompressor), job, this.recordDelimiterBytes);
        }
        filePosition = fileIn;
      }
    } else {
      fileIn.seek(start);
      if (null == this.recordDelimiterBytes){
        in = new LineReader(fileIn, job);
      } else {
        in = new LineReader(fileIn, job, this.recordDelimiterBytes);
      }

      filePosition = fileIn;
    }
    // If this is not the first split, we always throw away first record
    // because we always (except the last split) read one extra line in
    // next() method.
    if (start != 0) {
      start += in.readLine(new Text(), 0, maxBytesToConsume(start));
    }
    this.pos = start;
  }

  private boolean isCompressedInput() {
    return (codec != null);
  }

  private int maxBytesToConsume(long pos) {
    return isCompressedInput()
      ? Integer.MAX_VALUE
      : (int) Math.min(Integer.MAX_VALUE, end - pos);
  }

  private long getFilePosition() throws IOException {
    long retVal;
    if (isCompressedInput() && null != filePosition) {
      retVal = filePosition.getPos();
    } else {
      retVal = pos;
    }
    return retVal;
  }

  public boolean nextKeyValue() throws IOException {
    if (key == null) {
      key = new LongWritable();
    }
    key.set(pos);
    if (value == null) {
      value = new Text();
    }
    int newSize = 0;
    // We always read one extra line, which lies outside the upper
    // split limit i.e. (end - 1)
    while (getFilePosition() <= end) {
      newSize = in.readLine(value, maxLineLength,
          Math.max(maxBytesToConsume(pos), maxLineLength));
      if (newSize == 0) {
        break;
      }
      pos += newSize;
      if (newSize < maxLineLength) {
        break;
      }

      // line too long. try again
      LOG.info("Skipped line of size " + newSize + " at pos " +
               (pos - newSize));
    }
    if (newSize == 0) {
      key = null;
      value = null;
      return false;
    } else {
      return true;
    }
  }

  @Override
  public LongWritable getCurrentKey() {
    return key;
  }

  @Override
  public Text getCurrentValue() {
    return value;
  }

  /**
   * Get the progress within the split
   */
  public float getProgress() throws IOException {
    if (start == end) {
      return 0.0f;
    } else {
      return Math.min(1.0f, (getFilePosition() - start) / (float)(end - start));
    }
  }

  public synchronized void close() throws IOException {
    try {
      if (in != null) {
        in.close();
      }
    } finally {
      if (decompressor != null) {
        CodecPool.returnDecompressor(decompressor);
      }
    }
  }
}

redpajama_set_name: RedPajamaGithub


text:
ActiveRecord::Schema.define(version: 20160513140037) do

  create_table "friendly_id_slugs", force: :cascade do |t|
    t.string   "slug",                      null: false
    t.integer  "sluggable_id",              null: false
    t.string   "sluggable_type", limit: 50
    t.string   "scope"
    t.datetime "created_at"
  end

  add_index "friendly_id_slugs", ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true
  add_index "friendly_id_slugs", ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type"
  add_index "friendly_id_slugs", ["sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_id"
  add_index "friendly_id_slugs", ["sluggable_type"], name: "index_friendly_id_slugs_on_sluggable_type"

  create_table "posts", force: :cascade do |t|
    t.string   "title"
    t.string   "body"
    t.integer  "user_id"
    t.string   "user_username"
    t.string   "slug"
    t.datetime "created_at",    null: false
    t.datetime "updated_at",    null: false
    t.string   "slugg"
  end

  create_table "users", force: :cascade do |t|
    t.string   "username"
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.string   "confirmation_token"
    t.datetime "confirmed_at"
    t.datetime "confirmation_sent_at"
    t.string   "unconfirmed_email"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "slug"
    t.string   "role"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

end


text:
class QWidget;
class QVBoxLayout;
class RgMenuItem;
class RgMenuTitlebar;
class RgMenuBuildSettingsItem;
class RgMenuFileItemOpencl;
class RgAddCreateMenuItem;
class RgBuildView;
struct RgCliBuildOutput;

class RgMenuOpencl : public RgMenu
{
    Q_OBJECT

public:
    RgMenuOpencl(QWidget* parent);
    virtual ~RgMenuOpencl() = default;

    // Initialize the view's default menu items.
    virtual void InitializeDefaultMenuItems(const std::shared_ptr<RgProjectClone> project_clone) override;

    // Connect the signals for the view's default menu items.
    virtual void ConnectDefaultItemSignals() override;

    // Connect signals for the menu file item.
    virtual void ConnectMenuFileItemSignals(RgMenuFileItem* menu_item) override;

    // Add an item to the menu.
    bool AddItem(const std::string& full_path, bool is_new_file_item);

    // Clear the file menu's build outputs for each source file in the project.
    void ClearBuildOutputs();

    // Gets whether or not showing entry point lists within file items is enabled.
    bool GetIsShowEntrypointListEnabled() const;

    // Offset the currently selected row in the entry point list by advancing or regressing the current index by the given offset.
    // This function will return true only when (current index + offset) is a valid index in the entry point list.
    bool OffsetCurrentFileEntrypoint(int offset);

    // Toggle the visibility of the entry point list for file items.
    void SetIsShowEntrypointListEnabled(bool is_enabled);

    // Update the file menu with the latest build output.
    void UpdateBuildOutput(const RgBuildOutputsMap& build_outputs);

    // Set the build settings button to have no focus.
    virtual void SetButtonsNoFocus() override;

    // Handler invoked when the user drags a file over.
    virtual void dragEnterEvent(QDragEnterEvent* event) override;

    // Handler invoked when the user drops a dragged file.
    virtual void dropEvent(QDropEvent* event) override;

    // Handler invoked when the user is moving the mouse while dragging.
    virtual void dragMoveEvent(QDragMoveEvent* event) override;

signals:
    // A signal emitted when the user drags and drops a file.
    void DragAndDropExistingFile(const std::string& filename);

    // Signal emitted when the user changes the selected entry point index for a given file.
    void SelectedEntrypointChanged(const std::string& input_file_path, const std::string& selected_entrypoint_name);

    // Signal emitted when the project was built successfully.
    void ProjectBuildSuccess();

public slots:
    // Handler for when a build has started.
    virtual void HandleBuildStarted() override;

    // Handler for when a build has ended.
    virtual void HandleBuildEnded() override;

    // Select/focus on the item indicated by focus_index_.
    virtual void SelectFocusItem(FileMenuActionType action_type) override;

    // Select/focus on the item indicated by focus_index_ when tab pressed.
    virtual void SelectTabFocusItem(bool shift_tab_focucs) override;

    // Handler invoked when the user presses the activate key (Enter).
    // This is used to handle pressing add/create buttons when in focus.
    virtual void HandleActivateItemAction() override;

    // Handler invoked when the user clicks on the build settings button.
    virtual void HandleBuildSettingsButtonClicked(bool checked) override;

    // Handler invoked when the selected entry point has been changed.
    void HandleSelectedEntrypointChanged(const std::string& target_gpu, const std::string& input_file_path, const std::string& selected_entrypoint_name);

    // Handler invoked when the user presses the Tab key to switch focus.
    virtual void HandleTabFocusPressed() override;

    // Handler invoked when the user presses the Shift+Tab keys to switch focus.
    virtual void HandleShiftTabFocusPressed() override;

    // Handler invoked when the user adds a new file so the buttons get reset.
    void HandleSourceFileAdded();

    // Handler invoked when the user changes the currently selected file item.
    virtual void HandleSelectedFileChanged(RgMenuFileItem* selected) override;

protected slots:
    // Handler invoked when the user triggers the next menu item action.
    virtual void HandleNextItemAction() override;

    // Handler invoked when the user triggers the previous menu item action.
    virtual void HandlePreviousItemAction();

protected:
    // Retrieve the number of extra buttons that get added to the menu after the file items.
    virtual int GetButtonCount() const override;

private:
    // The default menu item.
    RgAddCreateMenuItem* add_create_menu_item_ = nullptr;

    // A flag used to determine if the kernel list in file items are able to expand.
    bool is_show_entrypoint_list_enabled_ = true;

    // Connect signals for build settings and Pipeline state buttons.
    void ConnectButtonSignals();
};
#endif // RGA_RADEONGPUANALYZERGUI_INCLUDE_QT_RG_MENU_OPENCL_H


text:
package org.apache.phoenix.expression.aggregator;

import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;

import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.phoenix.expression.*;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.PDataType;
import org.apache.phoenix.schema.tuple.Tuple;

/**
 * Client side Aggregator for PERCENT_RANK aggregations
 *
 *
 * @since 1.2.1
 */
public class PercentRankClientAggregator extends DistinctValueWithCountClientAggregator {

    private final List<Expression> exps;

    public PercentRankClientAggregator(List<Expression> exps, SortOrder sortOrder) {
        super(sortOrder);
        this.exps = exps;
    }

    @Override
    public boolean evaluate(Tuple tuple, ImmutableBytesWritable ptr) {
        if (cachedResult == null) {
            ColumnExpression columnExp = (ColumnExpression)exps.get(0);
            // Second exp will be a LiteralExpression of Boolean type indicating whether the ordering to
            // be ASC/DESC
            LiteralExpression isAscendingExpression = (LiteralExpression)exps.get(1);
            boolean isAscending = (Boolean)isAscendingExpression.getValue();

            // Third expression will be LiteralExpression
            LiteralExpression valueExp = (LiteralExpression)exps.get(2);
            Map<Object, Integer> sorted = getSortedValueVsCount(isAscending, columnExp.getDataType());
            long distinctCountsSum = 0;
            Object value = valueExp.getValue();
            for (Entry<Object, Integer> entry : sorted.entrySet()) {
                Object colValue = entry.getKey();
                int compareResult = columnExp.getDataType().compareTo(colValue, value, valueExp.getDataType());
                boolean done = isAscending ? compareResult > 0 : compareResult <= 0;
                if (done) break;
                distinctCountsSum += entry.getValue();
            }

            float result = (float)distinctCountsSum / totalCount;
            this.cachedResult = new BigDecimal(result);
        }
        if (buffer == null) {
            initBuffer();
        }
        buffer = PDataType.DECIMAL.toBytes(this.cachedResult);
        ptr.set(buffer);
        return true;
    }

    @Override
    protected PDataType getResultDataType() {
        return PDataType.DECIMAL;
    }
}


text:
var _ = require('underscore'),
	model = require('./index'),
	db = model.db,
	schema = schema,
	act = require('./../www/act');

var thing = new schema({
	date: {type: Date, default: new Date()},
	user: {type: schema.Types.ObjectId, ref: 'user', index: true},
	public: {type: Boolean, default: false, index: true}
});

thing.statics.get = function(user, next){
	if(!user){
		return next(new Error('no user'));
	}
	this.findOne({'user': user.id}, next);
};

thing.statics.delete = function(user, next){
	if(!user){
		return next(new Error('no user'));
	}
	this.remove({'user': user.id}, next);
};

thing.statics.record = function(user, next){
	if(!user){
		return next(new Error('no user'));
	}
	var thing = this,
		create = function(public){
			thing.create({
				'user': user.id,
				'public': public
			}, next);
		},
		remove = function(next){
			thing.delete(user, next);
		};
	thing.get(user, function(error, thing){
		if(error){
			return next(error);
		}
		if(thing){
			remove(function(){
				create(thing.public);
			});
		}else{
			create();
		}
	});
};

thing = exports = module.exports = db.model('thing', thing);

act('thing.record', function(request, response, next){
	thing.record(request.user, next);
});

act('thing.delete', function(request, response, next){
	thing.delete(request.user, next);
});


text:
static const char* PLUGIN_NAME = "GME IDecoder";

static const std::string EXTERNAL_ID_PREFIX = "gme";

static const char* KEY_ALWAYS_LOOP_FOREVER = "always_loop_forever";
static const bool DEFAULT_ALWAYS_LOOP_FOREVER = false;
static const char* KEY_IGNORE_EMBEDDED_TRACK_LENGTH = "ignore_embedded_track_length";
static const bool DEFAULT_IGNORE_EMBEDDED_TRACK_LENGTH = false;
static const char* KEY_DEFAULT_TRACK_LENGTH = "default_track_length_secs";
static const double DEFAULT_TRACK_LENGTH = 60.0 * 3.0;
static const char* KEY_TRACK_FADE_OUT_LENGTH = "track_fade_out_length_secs";
static const double DEFAULT_FADE_OUT_LENGTH = 3.0;
static const char* KEY_ENABLE_M3U = "enable_m3u_support";
static const bool DEFAULT_ENABLE_M3U = false;
static const char* KEY_MINIMUM_TRACK_LENGTH = "minimum_track_length_secs";
static const double DEFAULT_MINIMUM_TRACK_LENGTH = 0.0;
static const char* KEY_EXCLUDE_SOUND_EFFECTS = "exclude_tracks_shorter_than_minimum_length";
static const bool DEFAULT_EXCLUDE_SOUND_EFFECTS = false;

static const std::set<std::string> FORMATS = {
    ".vgm", ".gym", ".spc", ".sap", ".nsfe",
    ".nsf", ".ay", ".gbs", ".hes", ".kss"
};

static inline musik::core::sdk::ISchema* CreateSchema() {
    auto schema = new musik::core::sdk::TSchema<>();
    schema->AddBool(KEY_ALWAYS_LOOP_FOREVER, DEFAULT_ALWAYS_LOOP_FOREVER);
    schema->AddBool(KEY_IGNORE_EMBEDDED_TRACK_LENGTH, DEFAULT_IGNORE_EMBEDDED_TRACK_LENGTH);
    schema->AddDouble(KEY_DEFAULT_TRACK_LENGTH, DEFAULT_TRACK_LENGTH);
    schema->AddDouble(KEY_TRACK_FADE_OUT_LENGTH, DEFAULT_FADE_OUT_LENGTH);
    schema->AddDouble(KEY_MINIMUM_TRACK_LENGTH, DEFAULT_MINIMUM_TRACK_LENGTH);
    schema->AddBool(KEY_EXCLUDE_SOUND_EFFECTS, DEFAULT_EXCLUDE_SOUND_EFFECTS);
    schema->AddBool(KEY_ENABLE_M3U, DEFAULT_ENABLE_M3U);
    return schema;
}

static inline bool canHandle(std::string fn) {
    std::transform(fn.begin(), fn.end(), fn.begin(), ::tolower);
    for (auto& ext : FORMATS) {
        if (fn.size() >= ext.size() &&
            fn.rfind(ext) == fn.size() - ext.size())
        {
            return true;
        }
    }
    return false;
}

static std::string getM3uFor(const std::string& fn) {
    size_t lastDot = fn.find_last_of(".");
    if (lastDot != std::string::npos) {
        std::string m3u = fn.substr(0, lastDot) + ".m3u";
#ifdef WIN32
        auto m3u16 = musik::core::sdk::str::u8to16(m3u.c_str());
        if (_waccess(m3u16.c_str(), R_OK) != -1) {
            return m3u;
        }
#else
        if (access(m3u.c_str(), R_OK) != -1) {
            return m3u;
        }
#endif
    }
    return "";
}


text:
let cursor
let prevCursorState

export function loadMouseCursor () {
  this.game.load.atlasJSONHash('mouse_cursors', 'assets/mouse_cursors.png', 'assets/mouse_cursors.json')
}

export function createMouseCursor () {
  // Track mouse cursor
  cursor = this.game.add.sprite(0, 0, 'mouse_cursors', 'neutral')
  prevCursorState = 'neutral'
  cursor.scale.setTo(0.5, 0.5)
  this.game.input.addMoveCallback(function (pointer, x, y) {
    cursor.x = x
    cursor.y = y
  })

  this.game.input.mousePointer.leftButton.onDown.add(() => {
    setMouseCursorState('click')
  }, this)

  this.game.input.mousePointer.leftButton.onUp.add(() => {
    revertMouseCursorState()
  }, this)

  // Ensure cursor stays on top of text
  const cursorGroup = this.game.add.group()
  cursorGroup.add(cursor)
  this.game.world.bringToTop(cursorGroup)
}

// click, highlight or neutral
export function setMouseCursorState (state) {
  prevCursorState = cursor.frameName
  cursor.frameName = state
}

export function revertMouseCursorState () {
  cursor.frameName = prevCursorState
}

export function hideMouseCursor () {
  cursor.visible = false
}

export function showMouseCursor () {
  cursor.visible = true
}

export function setHeldItem (item) {
  cursor.loadTexture(item.key, 0)
}

export function releaseItem () {
  cursor.loadTexture('mouse_cursors', 'neutral')
}


text:
package org.apache.ambari.server.security.authentication;

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;

import javax.servlet.FilterChain;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.ambari.server.audit.AuditLogger;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.security.AmbariEntryPoint;
import org.apache.ambari.server.security.authorization.PermissionHelper;
import org.apache.ambari.server.security.authorization.User;
import org.apache.ambari.server.security.authorization.UserType;
import org.apache.ambari.server.security.authorization.Users;
import org.apache.ambari.server.security.authorization.jwt.JwtAuthenticationProperties;
import org.easymock.EasyMockSupport;
import org.junit.BeforeClass;
import org.junit.Test;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.RSASSASigner;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

public class AmbariJWTAuthenticationFilterTest extends EasyMockSupport {
  private static RSAPublicKey publicKey;
  private static RSAPrivateKey privateKey;

  @BeforeClass
  public static void generateKeyPair() throws NoSuchAlgorithmException {
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(512);
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    publicKey = (RSAPublicKey) keyPair.getPublic();
    privateKey = (RSAPrivateKey) keyPair.getPrivate();
  }

  @Test
  public void testDoFilterSuccess() throws Exception {
    SignedJWT token = getSignedToken("foobar");

    AmbariEntryPoint entryPoint = createMock(AmbariEntryPoint.class);

    JwtAuthenticationProperties properties = createMock(JwtAuthenticationProperties.class);
    expect(properties.getAuthenticationProviderUrl()).andReturn("some url").once();
    expect(properties.getPublicKey()).andReturn(publicKey).once();
    expect(properties.getAudiences()).andReturn(Collections.singletonList("foobar")).once();
    expect(properties.getCookieName()).andReturn("chocolate chip").once();
    expect(properties.getOriginalUrlQueryParam()).andReturn("question").once();

    Configuration configuration = createMock(Configuration.class);
    expect(configuration.getJwtProperties()).andReturn(properties).once();

    User user = createMock(User.class);
    expect(user.getUserName()).andReturn("test-user").once();
    expect(user.getUserType()).andReturn(UserType.JWT).once();

    Users users = createMock(Users.class);
    expect(users.getUser("test-user", UserType.JWT)).andReturn(user).once();
    expect(users.getUserAuthorities("test-user", UserType.JWT)).andReturn(null).once();

    AuditLogger auditLogger = createMock(AuditLogger.class);
    expect(auditLogger.isEnabled()).andReturn(false).times(2);

    PermissionHelper permissionHelper = createMock(PermissionHelper.class);

    Cookie cookie = createMock(Cookie.class);
    expect(cookie.getName()).andReturn("chocolate chip").once();
    expect(cookie.getValue()).andReturn(token.serialize()).once();

    HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
    expect(servletRequest.getCookies()).andReturn(new Cookie[]{cookie}).once();

    HttpServletResponse servletResponse = createMock(HttpServletResponse.class);

    FilterChain filterChain = createMock(FilterChain.class);
    filterChain.doFilter(servletRequest, servletResponse);
    expectLastCall().once();

    replayAll();

    AmbariJWTAuthenticationFilter filter = new AmbariJWTAuthenticationFilter(entryPoint, configuration, users, auditLogger, permissionHelper);
    filter.doFilter(servletRequest, servletResponse, filterChain);

    verifyAll();
  }

  @Test
  public void testDoFilterFailure() throws Exception {
    AmbariEntryPoint entryPoint = createMock(AmbariEntryPoint.class);

    JwtAuthenticationProperties properties = createMock(JwtAuthenticationProperties.class);
    expect(properties.getAuthenticationProviderUrl()).andReturn("some url").once();
    expect(properties.getPublicKey()).andReturn(publicKey).once();
    expect(properties.getAudiences()).andReturn(Collections.singletonList("foobar")).once();
    expect(properties.getCookieName()).andReturn("chocolate chip").once();
    expect(properties.getOriginalUrlQueryParam()).andReturn("question").once();

    Configuration configuration = createMock(Configuration.class);
    expect(configuration.getJwtProperties()).andReturn(properties).once();

    Users users = createMock(Users.class);

    AuditLogger auditLogger = createMock(AuditLogger.class);
    expect(auditLogger.isEnabled()).andReturn(false).times(2);

    PermissionHelper permissionHelper = createMock(PermissionHelper.class);

    Cookie cookie = createMock(Cookie.class);
    expect(cookie.getName()).andReturn("chocolate chip").once();
    expect(cookie.getValue()).andReturn("invalid token").once();

    HttpServletRequest servletRequest = createMock(HttpServletRequest.class);
    expect(servletRequest.getCookies()).andReturn(new Cookie[]{cookie}).once();

    HttpServletResponse servletResponse = createMock(HttpServletResponse.class);

    FilterChain filterChain = createMock(FilterChain.class);
    filterChain.doFilter(servletRequest, servletResponse);
    expectLastCall().once();

    replayAll();

    AmbariJWTAuthenticationFilter filter = new AmbariJWTAuthenticationFilter(entryPoint, configuration, users, auditLogger, permissionHelper);
    filter.doFilter(servletRequest, servletResponse, filterChain);

    verifyAll();
  }

  private SignedJWT getSignedToken(String audience) throws JOSEException {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.DATE, 1); //add one day
    return getSignedToken(calendar.getTime(), audience);
  }

  private SignedJWT getSignedToken(Date expirationTime, String audience) throws JOSEException {
    RSASSASigner signer = new RSASSASigner(privateKey);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    JWTClaimsSet claimsSet = new JWTClaimsSet();
    claimsSet.setSubject("test-user");
    claimsSet.setIssuer("unit-test");
    claimsSet.setIssueTime(calendar.getTime());

    claimsSet.setExpirationTime(expirationTime);

    claimsSet.setAudience(audience);

    SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet);
    signedJWT.sign(signer);

    return signedJWT;
  }
}


text:
package android.provider.cts;

import android.content.ContentResolver;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Settings.System;
import android.test.AndroidTestCase;

public class Settings_SystemTest extends AndroidTestCase {
    private ContentResolver cr;

    private static final String INT_FIELD = "IntField";
    private static final String LONG_FIELD = "LongField";
    private static final String FLOAT_FIELD = "FloatField";
    private static final String STRING_FIELD = "StringField";

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        cr = mContext.getContentResolver();
        assertNotNull(cr);
    }

    private void deleteTestedRows() {
        String selection = System.NAME + "=\"" + INT_FIELD + "\"";
        cr.delete(System.CONTENT_URI, selection, null);

        selection = System.NAME + "=\"" + LONG_FIELD + "\"";
        cr.delete(System.CONTENT_URI, selection, null);

        selection = System.NAME + "=\"" + FLOAT_FIELD + "\"";
        cr.delete(System.CONTENT_URI, selection, null);

        selection = System.NAME + "=\"" + STRING_FIELD + "\"";
        cr.delete(System.CONTENT_URI, selection, null);

        selection = System.NAME + "=\"" + System.SHOW_GTALK_SERVICE_STATUS + "\"";
        cr.delete(System.CONTENT_URI, selection, null);
    }

    public void testSystemSettings() throws SettingNotFoundException {
        /**
         * first query the exist settings in System table, and then insert five
         * rows: an int, a long, a float, a String, and a ShowGTalkServiceStatus.
         * Get these six rows to check whether insert succeeded and then delete them.
         */
        // Precondition: these rows must not exist in the db when we begin
        deleteTestedRows();

        // first query exist rows
        Cursor c = cr.query(System.CONTENT_URI, null, null, null, null);
        try {
            assertNotNull(c);
            int origCount = c.getCount();
            c.close();

            String stringValue = "cts";

            // insert 5 rows, and update 1 rows
            assertTrue(System.putInt(cr, INT_FIELD, 10));
            assertTrue(System.putLong(cr, LONG_FIELD, 20l));
            assertTrue(System.putFloat(cr, FLOAT_FIELD, 30.0f));
            assertTrue(System.putString(cr, STRING_FIELD, stringValue));
            System.setShowGTalkServiceStatus(cr, true);

            c = cr.query(System.CONTENT_URI, null, null, null, null);
            assertNotNull(c);
            assertEquals(origCount + 5, c.getCount());
            c.close();

            // get these rows to assert
            assertEquals(10, System.getInt(cr, INT_FIELD));
            assertEquals(20l, System.getLong(cr, LONG_FIELD));
            assertEquals(30.0f, System.getFloat(cr, FLOAT_FIELD), 0.001);

            assertEquals(stringValue, System.getString(cr, STRING_FIELD));
            assertTrue(System.getShowGTalkServiceStatus(cr));

            // delete the tested rows again
            deleteTestedRows();

            c = cr.query(System.CONTENT_URI, null, null, null, null);
            assertNotNull(c);
            assertEquals(origCount, c.getCount());

            // backup fontScale
            Configuration cfg = new Configuration();
            System.getConfiguration(cr, cfg);
            float store = cfg.fontScale;

            // update fontScale row
            cfg = new Configuration();
            cfg.fontScale = 10.0f;
            assertTrue(System.putConfiguration(cr, cfg));

            System.getConfiguration(cr, cfg);
            assertEquals(10.0f, cfg.fontScale);

            // restore the fontScale
            cfg.fontScale = store;
            assertTrue(System.putConfiguration(cr, cfg));
        } finally {
            // TODO should clean up more better
            c.close();
        }
    }

    public void testGetDefaultValues() {
        assertEquals(10, System.getInt(cr, "int", 10));
        assertEquals(20, System.getLong(cr, "long", 20l));
        assertEquals(30.0f, System.getFloat(cr, "float", 30.0f), 0.001);
    }

    public void testGetUriFor() {
        String name = "table";

        Uri uri = System.getUriFor(name);
        assertNotNull(uri);
        assertEquals(Uri.withAppendedPath(System.CONTENT_URI, name), uri);
    }
}


text:
<?php

require_once __DIR__ . '/Parts.php';

/**
 * We drive the tests of our aggregate root through the command handler.
 *
 * A command handler scenario consists of three steps:
 *
 * - First, the scenario is setup with a history of events that already took place.
 * - Second, a command is dispatched (this is handled by the command handler)
 * - Third, the outcome is asserted. This can either be 1) some events are
 *   recorded, or 2) an exception is thrown.
 */
class PartsCommandHandlerTest extends Broadway\CommandHandling\Testing\CommandHandlerScenarioTestCase
{
    private $generator;

    public function setUp()
    {
        parent::setUp();
        $this->generator = new Broadway\UuidGenerator\Rfc4122\Version4Generator();
    }

    protected function createCommandHandler(Broadway\EventStore\EventStoreInterface $eventStore, Broadway\EventHandling\EventBusInterface $eventBus)
    {
        $repository = new PartRepository($eventStore, $eventBus);

        return new PartCommandHandler($repository);
    }

    /**
     * @test
     */
    public function it_can_manufacture()
    {
        $id = $this->generator->generate();

        $this->scenario
            ->withAggregateId($id)
            ->given([])
            ->when(new ManufacturePartCommand($id, 'acme', 'Acme, Inc'))
            ->then([new PartWasManufacturedEvent($id, 'acme', 'Acme, Inc')]);
    }

    /**
     * @test
     */
    public function it_can_rename_manufacturer()
    {
        $id = $this->generator->generate();

        $this->scenario
            ->withAggregateId($id)
            ->given([new PartWasManufacturedEvent($id, 'acme', 'Acme, Inc')])
            ->when(new RenameManufacturerForPartCommand($id, 'Acme, Inc.'))
            ->then([new PartManufacturerWasRenamedEvent($id, 'Acme, Inc.')]);
    }

    /**
     * @test
     */
    public function it_does_not_rename_manufacturer_to_the_same_name()
    {
        $id = $this->generator->generate();

        $this->scenario
            ->withAggregateId($id)
            ->given([
                new PartWasManufacturedEvent($id, 'acme', 'Acme, Inc'),
                new PartWasManufacturedEvent($id, 'acme', 'Acme, Inc.'),
            ])
            ->when(new RenameManufacturerForPartCommand($id, 'Acme, Inc.'))
            ->then([]);
    }
}


text:
package com.shl.common.captcha.word;

/**
 * 文字内容
 */
public interface WordFactory {

	String getNextWord();
}


text:
author: Olcay Bayram
layout: post
categories: Azure
published: true
title: Wildcard For Azure Devops Branch Policies
image: /img/AzureDevopsWildcardBranchCover.png
tags:
  - cloud
  - azure
  - devops
  - git
---
We use [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) as our branching model on Azure Devops. When we create a new Release branch, we want it to be protected by default. By protection I mean, preventing unreviewed code changes.

This is not like setting a branch policy for an existing branch, it would be a wildcard for future branches. You need to do one extra step to access the correct page for a wildcard and this is not documented yet.

<!--more-->

1. Go to Branches page under Repos on Azure Devops.
1. If you already have a folder in your repo, you can skip to step 5.
1. Click __New branch__ and fil in the name like _release/tempBranch_.
1. Click __Create__.
1. Click __⋮ (vertical ellipsis)__ next to a folder.

    ![Azure Devops Wildcard Branch](/img/AzureDevopsWildcardBranch.png)

1. Select __Branch policies__ in the menu.
1. It will redirect to the branch policies page with the title _Branch policies for {folderName}/*_.
1. Here you can set the policies.
1. After setting the policies in place you can remove the _tempBranch_ if you created one.

![Azure Devops Wildcard Branch Policies](/img/AzureDevopsWildcardBranchPolicies.png)

The existing or future branches which matches the wildcard will be using the policies.

Cover photo by [Jan Huber](https://unsplash.com/@jan_huber?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/s/photos/tree?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)


text:
using System;
using System.Collections.Generic;
using System.Text;

namespace ManagedSteam.SteamTypes
{
    /// <summary>
    /// Managed version of the \a ELeaderboardSortMethod enum
    /// </summary>
    public enum LeaderboardSortMethod
    {
        None = 0,
        /// <summary>
        /// top-score is lowest number
        /// </summary>
        Ascending = 1,
        /// <summary>
        /// top-score is highest number
        /// </summary>
        Descending = 2,
    };
}


text:
![CraftOS](http://oi43.tinypic.com/28aqgp0.jpg)
=======

CarftOS is a plugin that adds basic computer functionality to MineCraft.
Some of the features are:

* Script your own programs in Lua, you can create some interesting programs.
* Lua programs will always run in a sandbox environment, so they can't access server files, like ops.txt or bans.txt...
* A wireless connection between several computers makes it possible to create private chat sessions with your friends, or even remotly letting tnt explode!

CraftOS is open-source trough the MIT-license.

--------


text:
<?php

namespace Lcd\App\Core;

class PhalBaseController extends \Phalcon\Mvc\Controller
{
    public function initialize()
    {
        // Use trans: $this->trans->_("hi-name", ["name" => 'value']);
        $this->trans = \Lcd\App\Helpers\LangHelper::getTranslation();
    }

    /**
     * ajax
     * @param $message
     * @param int $code
     * @param array $data
     */
    protected function ajax_return($message, $code = 1, array $data = array())
    {
        $result = array(
            'code'    => $code,
            'message' => $message,
            'data'    => $data,
        );
        //$this -> response -> setContent(json_encode($result));
        $this->response->setJsonContent($result);
        $this->response->send();
    }

    /**
     * exception logging
     * @param \Exception $e
     */
    protected function write_exception_log(\Exception $e)
    {
        $logArray = array(
            'file'    => $e->getFile(),
            'line'    => $e->getLine(),
            'code'    => $e->getCode(),
            'message' => $e->getMessage(),
            'trace'   => $e->getTraceAsString(),
        );
        $this->logger->write_log($logArray);
    }

    /**
     * @method translate
     * @auth: ledung
     * @param  $url
     * @return
     */
    public function _($key, $field = null)
    {
        if (!empty($field) && is_array($field)) {
            return $this->trans->_($key, $field);
        } else if (!empty($field) && !is_array($field)) {
            return $this->trans->_($key). ' ' . $field;
        } else {
            return $this->trans->_($key);
        }
    }
}


text:
import { Directive, ElementRef, Input, Renderer } from '@angular/core';
import * as select from 'select2/dist/js/select2.js';
import * as  jQuery from 'jquery';
@Directive({
    selector : '[select]'
})

export class selectDirective{
    constructor(elem : ElementRef, renderer : Renderer){
        //@TODO :
    }
}


text:
package com.example;

import org.springframework.data.annotation.Id;

public record Foobar(@Id Integer id, String content) {
}


text:
#ifndef INCLUDED_flixel_input_gamepad_mappings_MFiMapping
#define INCLUDED_flixel_input_gamepad_mappings_MFiMapping

#ifndef HXCPP_H
#include <hxcpp.h>
#endif

#ifndef INCLUDED_flixel_input_gamepad_mappings_FlxGamepadMapping
#include <flixel/input/gamepad/mappings/FlxGamepadMapping.h>
#endif
HX_DECLARE_CLASS3(flixel,input,gamepad,FlxGamepadAttachment)
HX_DECLARE_CLASS4(flixel,input,gamepad,mappings,FlxGamepadMapping)
HX_DECLARE_CLASS4(flixel,input,gamepad,mappings,MFiMapping)
namespace flixel{
namespace input{
namespace gamepad{
namespace mappings{

class HXCPP_CLASS_ATTRIBUTES  MFiMapping_obj : public ::flixel::input::gamepad::mappings::FlxGamepadMapping_obj{
	public:
		typedef ::flixel::input::gamepad::mappings::FlxGamepadMapping_obj super;
		typedef MFiMapping_obj OBJ_;
		MFiMapping_obj();
		Void __construct(::flixel::input::gamepad::FlxGamepadAttachment attachment);

	public:
		inline void *operator new( size_t inSize, bool inContainer=true,const char *inName="flixel.input.gamepad.mappings.MFiMapping")
			{ return hx::Object::operator new(inSize,inContainer,inName); }
		static hx::ObjectPtr< MFiMapping_obj > __new(::flixel::input::gamepad::FlxGamepadAttachment attachment);
		static Dynamic __CreateEmpty();
		static Dynamic __Create(hx::DynamicArray inArgs);
		//~MFiMapping_obj();

		HX_DO_RTTI_ALL;
		Dynamic __Field(const ::String &inString, hx::PropertyAccess inCallProp);
		static void __register();
		::String __ToString() const { return HX_HCSTRING("MFiMapping","\xfe","\x35","\xe5","\x0b"); }

		virtual Void initValues( );

		virtual int getID( int rawID);

		virtual int getRawID( int ID);

		virtual int axisIndexToRawID( int axisID);

};

} // end namespace flixel
} // end namespace input
} // end namespace gamepad
} // end namespace mappings

#endif /* INCLUDED_flixel_input_gamepad_mappings_MFiMapping */


text:
package gossip

import (
	"encoding/json"
	"errors"
	"time"

	"code.google.com/p/go-uuid/uuid"
)

type Gossip struct {
	sendout  chan []byte
	receive  chan []byte
	inbound  chan []byte
	loopback chan *GossipMessage

	history map[string]time.Time

	countThreshold int
}

type GossipMessage struct {
	message []byte
	uuid    string
	count   int
}

func RunGossip(outbuffer, inbuffer int) (*Gossip, error) {

	if outbuffer < 1 {
		return nil, errors.New("outbuffer should be greater than 0")
	}

	if inbuffer < 1 {
		return nil, errors.New("inbuffer should be greater than 0")
	}

	g := &Gossip{}

	g.sendout = make(chan []byte, outbuffer)
	g.receive = make(chan []byte, inbuffer)
	g.inbound = make(chan []byte, inbuffer)
	g.loopback = make(chan *GossipMessage, outbuffer+inbuffer)

	go g.doSend()
	go g.doListen()

	g.countThreshold = 5 //TODO: let's make this setable

	return g, nil
}

func (g *Gossip) Send(encodedMessage []byte) {
	g.sendout <- encodedMessage
}

func (g *Gossip) Get() ([]byte, error) {
	x := <-g.receive
	return x, nil
}

//GetWithTimeout is blocking Get that timeouts after a given duration
// accepts: a time.Duration
// returns: a byte array of the message, an error
//
// Timeout is indicated by returning nil, errors.New("timeout")
func (g *Gossip) GetWithTimeout(td time.Duration) ([]byte, error) {
	//Create a timeout channel
	timeout := make(chan bool, 1)
	go func() {
		time.Sleep(td)
		timeout <- true
	}()

	select {
	//wait on Get()
	case x := <-g.receive:
		return x, nil
	//and wait on the timeout channel
	case <-timeout:
		return nil, errors.New("timeout")
	}
}

func (g *Gossip) doSend() {

	for g.stepSend() == nil {
	}
}

func (g *Gossip) stepSend() error {

	var m *GossipMessage
	select {
	//wait for messages originating from this node
	case msg := <-g.sendout:
		m = &GossipMessage{
			message: msg,
			uuid:    uuid.New(),
			count:   1}
		g.history[m.uuid] = time.Now()
	//wait for message originating from other nodes
	case m := <-g.loopback:
		m.count += 1
	}

	return nil
}

func (g *Gossip) doListen() {

	for g.stepListen() != nil {
	}
}

//stepListen waits for an inbounded encoded GossipMessage from the network,
//           checks to see if we have seen it before
//           passes it to the receive channel or discards it.
//
//	returns error
func (g *Gossip) stepListen() error {
	//pick up an encoded GossipMessage from the inbound channel
	enc := <-g.inbound
	m := &GossipMessage{}
	e := json.Unmarshal(enc, m) //TODO decouple this from json, should be able to use any encoding thanks to golang
	//if it can't be unmarshalled, discard the message
	if e != nil {
		return nil // TODO log this failure
	}
	//testto see if we have seen the message before
	if _, ok := g.history[m.uuid]; !ok {
		return nil //TODO log this discard
	}

	//this is our fist time seeing the message
	//add it to the history map
	g.history[m.uuid] = time.Now()

	if m.count >= g.countThreshold {
		return nil //Todo log this discard
	}
	g.loopback <- m
	return nil
}


text:
The project consists in using cognito and React/Redux to create a serverless authentication service that can be used as a sample for people interested on this

## Configure cognito in the project
Go to src/actions/index.js
```javascript
let poolData = {
    UserPoolId: 'Your user pool id here', // it should look like: us-east-1_3Zh1cICbd
    ClientId: 'Your client id here' // it should look like: 782ksft0keavlha75pb73aq2c6
};
```

## Instructions

To run the project:
- Download the project
- npm install
- npm run dev


text:
cask "golly" do
  version "4.0.1"
  sha256 "5e4e14c06ac979da93e8b99d0203073c759c8a540ac84ff81b265aa5777937c0"

  url "https://downloads.sourceforge.net/golly/golly/golly-#{version.major_minor}/Golly-#{version}-Mac.dmg",
      verified: "downloads.sourceforge.net/golly/"
  appcast "https://sourceforge.net/projects/golly/rss?path=/golly"
  name "Golly"
  desc "Explore Conway's Game of Life and other types of cellular automata"
  homepage "https://golly.sourceforge.io/"

  suite "golly-#{version}-mac"
  binary "#{appdir}/golly-#{version}-mac/bgolly"
end