Archive-Tar-Builder

 view release on metacpan or  search on metacpan

lib/Archive/Tar/Builder/UserCache.pm  view on Meta::CPAN

sub new {
    my ($class) = @_;

    return bless {
        'users'  => {},
        'groups' => {}
    }, $class;
}

sub lookup {
    my ( $self, $uid, $gid ) = @_;

    unless ( exists $self->{'users'}->{$uid} ) {
        if ( my @pwent = getpwuid($uid) ) {
            $self->{'users'}->{$uid} = $pwent[0];
        }
        else {
            $self->{'users'}->{$uid} = undef;
        }
    }

    unless ( exists $self->{'groups'}->{$gid} ) {
        if ( my @grent = getgrgid($gid) ) {
            $self->{'groups'}->{$gid} = $grent[0];
        }
        else {
            $self->{'groups'}->{$gid} = undef;
        }
    }

    return ( $self->{'users'}->{$uid}, $self->{'groups'}->{$gid} );
}

1;

src/Builder.xs  view on Meta::CPAN


#include <sys/types.h>
#include <errno.h>
#include "b_string.h"
#include "b_find.h"
#include "b_error.h"
#include "b_builder.h"

typedef b_builder * Archive__Tar__Builder;

static int user_lookup(SV *cache, uid_t uid, gid_t gid, b_string **user, b_string **group) {
    dSP;
    I32 retc;

    ENTER;
    SAVETMPS;

    /*
     * Prepare the stack for $cache->getpwuid()
     */
    PUSHMARK(SP);
    XPUSHs(cache);
    XPUSHs(sv_2mortal(newSViv(uid)));
    XPUSHs(sv_2mortal(newSViv(gid)));
    PUTBACK;

    retc = call_method("lookup", G_ARRAY);

    SPAGAIN;

    if (retc < 2) {
        goto error_lookup;
    }

src/b_builder.c  view on Meta::CPAN


    if ((path_data = path_split(member_name, st)) == NULL) {
        goto error_path_data;
    }

    ret->truncated = path_data->truncated;
    ret->prefix    = path_data->prefix;
    ret->suffix    = path_data->suffix;
    ret->mode      = st->st_mode;
    ret->uid       = st->st_uid;
    ret->gid       = st->st_gid;
    ret->size      = (st->st_mode & S_IFMT) == S_IFREG? st->st_size: 0;
    ret->mtime     = st->st_mtime;
    ret->major     = major(st->st_dev);
    ret->minor     = minor(st->st_dev);
    ret->linktype  = inode_linktype(st);
    ret->linkdest  = NULL;
    ret->user      = NULL;
    ret->group     = NULL;

    ret->truncated_link = 0;

src/b_builder.c  view on Meta::CPAN

    }

    /*
     * If there is a user lookup service installed, then resolve the user and
     * group of the current filesystem object and supply them within the
     * b_header object.
     */
    if (builder->user_lookup != NULL) {
        b_string *user = NULL, *group = NULL;

        if (builder->user_lookup(builder->user_cache, st->st_uid, st->st_gid, &user, &group) < 0) {
            if (err) {
                b_error_set(err, B_ERROR_WARN, errno, "Cannot lookup user and group for file", path);
            }

            goto error_lookup;
        }

        if (b_header_set_usernames(header, user, group) < 0) {
            goto error_lookup;
        }

src/b_builder.h  view on Meta::CPAN

    B_BUILDER_GNU_EXTENSIONS     = 1 << 4,
    B_BUILDER_PAX_EXTENSIONS     = 1 << 5,
    B_BUILDER_IGNORE_SOCKETS     = 1 << 6,
    B_BUILDER_EXTENSIONS_MASK    = (B_BUILDER_GNU_EXTENSIONS |
                                    B_BUILDER_PAX_EXTENSIONS)
};

typedef int (*b_user_lookup)(
    void *      ctx,
    uid_t       uid,
    gid_t       gid,
    b_string ** user,
    b_string ** group
);

typedef b_string * (*b_hardlink_lookup)(
    void *     ctx,
    dev_t      dev,
    ino_t      ino,
    b_string * path
);

src/b_header.c  view on Meta::CPAN

}


b_header_block *b_header_encode_block(b_header_block *block, b_header *header) {
    if (header->suffix) {
        strncpy(block->suffix, header->suffix->str, 100);
    }

    snprintf(block->mode, B_HEADER_MODE_SIZE, B_HEADER_MODE_FORMAT, header->mode & S_IPERM);
    snprintf(block->uid,  B_HEADER_UID_SIZE,  B_HEADER_UID_FORMAT,  header->uid);
    snprintf(block->gid,  B_HEADER_GID_SIZE,  B_HEADER_GID_FORMAT,  header->gid);

    if (header->size >= B_HEADER_MAX_FILE_SIZE) {
        encode_base256_value(block->size, B_HEADER_SIZE_SIZE, header->size);
    } else {
        snprintf(block->size, B_HEADER_SIZE_SIZE, B_HEADER_LONG_SIZE_FORMAT, header->size);
    }

    snprintf(block->mtime, B_HEADER_MTIME_SIZE, B_HEADER_MTIME_FORMAT, header->mtime);

    block->linktype = header->linktype;

src/b_header.h  view on Meta::CPAN

#define B_HEADER_IS_HARDLINK(header) \
    (header->linktype == '0' + S_IF_HARDLINK)

#define B_HEADER_IS_IFREG(header) \
    (header->linktype == '0')

typedef struct _b_header {
    b_string * suffix;
    mode_t     mode;
    uid_t      uid;
    gid_t      gid;
    uint64_t   size;
    time_t     mtime;
    char       linktype;
    b_string * linkdest;
    b_string * user;
    b_string * group;
    dev_t      major;
    dev_t      minor;
    b_string * prefix;
    int        truncated;
    int        truncated_link;
} b_header;

typedef struct _b_header_block {
    char suffix   [B_HEADER_SUFFIX_SIZE];
    char mode     [B_HEADER_MODE_SIZE];
    char uid      [B_HEADER_UID_SIZE];
    char gid      [B_HEADER_GID_SIZE];
    char size     [B_HEADER_SIZE_SIZE];
    char mtime    [B_HEADER_MTIME_SIZE];
    char checksum [B_HEADER_CHECKSUM_SIZE];
    char linktype;
    char linkdest [B_HEADER_LINKDEST_SIZE];
    char magic    [B_HEADER_MAGIC_SIZE];
    char user     [B_HEADER_USER_SIZE];
    char group    [B_HEADER_GROUP_SIZE];
    char major    [B_HEADER_MAJOR_SIZE];
    char minor    [B_HEADER_MINOR_SIZE];

t/lib-Archive-Tar-Builder-UserCache.t  view on Meta::CPAN

# terms as Perl itself.  See the LICENSE file for further details.

use strict;
use warnings;

use Archive::Tar::Builder::UserCache ();

use Test::More ( 'tests' => 4 );

sub find_unused_ids {
    my ( $uid, $gid );

    for ( $uid = 99999; getpwuid($uid); $uid-- ) { }
    for ( $gid = 99999; getgrgid($gid); $gid-- ) { }

    return ( $uid, $gid );
}

#
# Test Archive::Tar::Builder internal methods
#
{
    my $cache = Archive::Tar::Builder::UserCache->new;

    my ( $unused_uid, $unused_gid ) = find_unused_ids();

    #
    # Test $cache->lookup()
    #
    my ( $root_name,   $root_group )   = $cache->lookup( 0,           0 );
    my ( $unused_name, $unused_group ) = $cache->lookup( $unused_uid, $unused_gid );

    #
    # I realize some stupid systems may actually not name root, 'root'...
    # I'm looking at you, OS X with your Directory Services...
    #
    # The root group name isn't frequently 'root' outside of the Linux circles,
    # by the by.
    #
    like( $root_name => qr/^(_|)root$/, '$cache->lookup() can locate known existing user name' );
    ok( defined $root_group, '$cache->lookup() can locate known existing group name ' . "'$root_group'" );

t/lib-Archive-Tar-Builder.t  view on Meta::CPAN

    }

    close $err;

    waitpid( $pid, 0 ) or die("Unable to waitpid() on $pid: $!");

    return $is_bsd_tar;
}

sub find_unused_ids {
    my ( $uid, $gid );

    for ( $uid = 99999; getpwuid($uid); $uid-- ) { }
    for ( $gid = 99999; getgrgid($gid); $gid-- ) { }

    return ( $uid, $gid );
}

sub build_tree {
    my $tmpdir = File::Temp::tempdir( 'CLEANUP' => 1 );
    my $file   = "$tmpdir/foo/exclude.txt";

    File::Path::mkpath("$tmpdir/foo/bar/baz/foo/cats");
    File::Path::mkpath("$tmpdir/foo/poop");
    File::Path::mkpath("$tmpdir/foo/cats/meow");
    File::Path::mkpath("$tmpdir/home/prrr/1327342027.M926735P26547V000000000000FD00I0000000001888287_0.one.two.threefour.five.S=2486:2.");



( run in 2.465 seconds using v1.01-cache-2.11-cpan-ceb78f64989 )