App-SimpleBackuper

 view release on metacpan or  search on metacpan

local/lib/perl5/Net/SFTP/Foreign/Attributes.pm  view on Meta::CPAN

package Net::SFTP::Foreign::Attributes;

our $VERSION = '1.68_05';

use strict;
use warnings;
use Carp;

use Net::SFTP::Foreign::Constants qw( :att );
use Net::SFTP::Foreign::Buffer;

sub new {
    my $class = shift;
    return bless { flags => 0}, $class;
}

sub new_from_stat {
    if (@_ > 1) {
	my ($class, undef, undef, $mode, undef,
	    $uid, $gid, undef, $size, $atime, $mtime) = @_;
	my $self = $class->new;

	$self->set_perm($mode);
	$self->set_ugid($uid, $gid);
	$self->set_size($size);
	$self->set_amtime($atime, $mtime);
	return $self;
    }
    return undef;
}

sub new_from_buffer {
    my ($class, $buf) = @_;
    my $self = $class->new;
    my $flags = $self->{flags} = $buf->get_int32_untaint;

    if ($flags & SSH2_FILEXFER_ATTR_SIZE) {
	$self->{size} = $buf->get_int64_untaint;
    }

    if ($flags & SSH2_FILEXFER_ATTR_UIDGID) {
	$self->{uid} = $buf->get_int32_untaint;
	$self->{gid} = $buf->get_int32_untaint;
    }

    if ($flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
	$self->{perm} = $buf->get_int32_untaint;
    }

    if ($flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
	$self->{atime} = $buf->get_int32_untaint;
	$self->{mtime} = $buf->get_int32_untaint;
    }

    if ($flags & SSH2_FILEXFER_ATTR_EXTENDED) {
        my $n = $buf->get_int32;
	$n >= 0 and $n <= 10000 or return undef;
        my @pairs = map $buf->get_str, 1..2*$n;
        $self->{extended} = \@pairs;
    }

    $self;
}

sub skip_from_buffer {
    my ($class, $buf) = @_;
    my $flags = $buf->get_int32;
    if ($flags == ( SSH2_FILEXFER_ATTR_SIZE |
		    SSH2_FILEXFER_ATTR_UIDGID |
		    SSH2_FILEXFER_ATTR_PERMISSIONS |
		    SSH2_FILEXFER_ATTR_ACMODTIME )) {
	$buf->skip_bytes(28);
    }
    else {
	my $len = 0;
	$len += 8 if $flags & SSH2_FILEXFER_ATTR_SIZE;
	$len += 8 if $flags & SSH2_FILEXFER_ATTR_UIDGID;
	$len += 4 if $flags & SSH2_FILEXFER_ATTR_PERMISSIONS;
	$len += 8 if $flags & SSH2_FILEXFER_ATTR_ACMODTIME;
	$buf->skip_bytes($len);
	if ($flags & SSH2_FILEXFER_ATTR_EXTENDED) {
	    my $n = $buf->get_int32;
	    $buf->skip_str, $buf->skip_str for (1..$n);
	}
    }
}

sub as_buffer {
    my $a = shift;
    my $buf = Net::SFTP::Foreign::Buffer->new(int32 => $a->{flags});

    if ($a->{flags} & SSH2_FILEXFER_ATTR_SIZE) {
        $buf->put_int64(int $a->{size});
    }
    if ($a->{flags} & SSH2_FILEXFER_ATTR_UIDGID) {
        $buf->put(int32 => $a->{uid}, int32 => $a->{gid});
    }
    if ($a->{flags} & SSH2_FILEXFER_ATTR_PERMISSIONS) {
        $buf->put_int32($a->{perm});
    }
    if ($a->{flags} & SSH2_FILEXFER_ATTR_ACMODTIME) {
        $buf->put(int32 => $a->{atime}, int32 => $a->{mtime});
    }
    if ($a->{flags} & SSH2_FILEXFER_ATTR_EXTENDED) {
        my $pairs = $a->{extended};
        $buf->put_int32(int(@$pairs / 2));
        $buf->put_str($_) for @$pairs;
    }

    $buf;
}



( run in 0.943 second using v1.01-cache-2.11-cpan-39bf76dae61 )