Skip to content

Commit

Permalink
gqie
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthur Axel 'fREW' Schmidt committed Apr 20, 2014
1 parent c98c80d commit f8c8370
Show file tree
Hide file tree
Showing 11 changed files with 830 additions and 866 deletions.
666 changes: 328 additions & 338 deletions lib/Cogit.pm

Large diffs are not rendered by default.

219 changes: 108 additions & 111 deletions lib/Cogit/Protocol.pm
Original file line number Diff line number Diff line change
Expand Up @@ -9,149 +9,146 @@ use Cogit::Protocol::SSH;
use Cogit::Protocol::File;

has remote => (
is => 'ro',
isa => Str,
required => 1,
is => 'ro',
isa => Str,
required => 1,
);

has read_socket => ( is => 'rw' );
has write_socket => ( is => 'rw' );
has read_socket => (is => 'rw');
has write_socket => (is => 'rw');

sub connect {
my $self = shift;

my @args = ( remote => $self->remote );

my $ret;
if ($self->remote =~ m{^git://(.*?@)?(.*?)(/.*)}) {
$ret = Cogit::Protocol::Git->new(
@args,
hostname => $2,
project => $3,
);
} elsif ($self->remote =~ m{^file://(/.*)}) {
$ret = Cogit::Protocol::File->new(
@args,
path => $1,
);
} elsif ($self->remote =~ m{^ssh://(?:(.*?)@)?(.*?)(/.*)}
or $self->remote =~ m{^(?:(.*?)@)?(.*?):(.*)}) {
$ret = Cogit::Protocol::SSH->new(
@args,
$1 ? (username => $1) : (),
hostname => $2,
path => $3,
);
}

$ret->connect_socket;

return $ret
my $self = shift;

my @args = (remote => $self->remote);

my $ret;
if ($self->remote =~ m{^git://(.*?@)?(.*?)(/.*)}) {
$ret = Cogit::Protocol::Git->new(
@args,
hostname => $2,
project => $3,
);
} elsif ($self->remote =~ m{^file://(/.*)}) {
$ret = Cogit::Protocol::File->new(@args, path => $1,);
} elsif ($self->remote =~ m{^ssh://(?:(.*?)@)?(.*?)(/.*)}
or $self->remote =~ m{^(?:(.*?)@)?(.*?):(.*)}) {
$ret = Cogit::Protocol::SSH->new(
@args,
$1 ? (username => $1) : (),
hostname => $2,
path => $3,
);
}

$ret->connect_socket;

return $ret
}

sub fetch {
my $self = shift;
my $self = shift;

my %sha1s;
while ( my $line = $self->read_line() ) {
my %sha1s;
while (my $line = $self->read_line()) {

# warn "S $line";
my ( $sha1, $name ) = $line =~ /^([a-z0-9]+) ([^\0\n]+)/;
# warn "S $line";
my ($sha1, $name) = $line =~ /^([a-z0-9]+) ([^\0\n]+)/;

#use YAML; warn Dump $line;
$sha1s{$name} = $sha1;
}
return \%sha1s;
#use YAML; warn Dump $line;
$sha1s{$name} = $sha1;
}
return \%sha1s;
}

sub fetch_pack {
my ( $self, $sha1 ) = @_;
$self->send_line("want $sha1 side-band-64k\n");
my ($self, $sha1) = @_;
$self->send_line("want $sha1 side-band-64k\n");

#send_line(
# "want 0c7b3d23c0f821e58cd20e60d5e63f5ed12ef391 multi_ack side-band-64k ofs-delta\n"
#);
$self->send_line('');
$self->send_line('done');

my $pack;

while ( my $line = $self->read_line() ) {
if ( $line =~ s/^\x02// ) {
print $line;
} elsif ( $line =~ /^NAK\n/ ) {
} elsif ( $line =~ s/^\x01// ) {
$pack .= $line;
} else {
die "Unknown line: $line";
}

#say "s $line";
}
return $pack;
$self->send_line('');
$self->send_line('done');

my $pack;

while (my $line = $self->read_line()) {
if ($line =~ s/^\x02//) {
print $line;
} elsif ($line =~ /^NAK\n/) {
} elsif ($line =~ s/^\x01//) {
$pack .= $line;
} else {
die "Unknown line: $line";
}

#say "s $line";
}
return $pack;
}

sub send_line {
my ( $self, $line ) = @_;
my $length = length($line);
if ( $length == 0 ) {
} else {
$length += 4;
}

#warn "length $length";
my $prefix = sprintf( "%04X", $length );
my $text = $prefix . $line;

# warn "$text";
$self->write_socket->print($text) || die $!;
my ($self, $line) = @_;
my $length = length($line);
if ($length == 0) {
} else {
$length += 4;
}

#warn "length $length";
my $prefix = sprintf("%04X", $length);
my $text = $prefix . $line;

# warn "$text";
$self->write_socket->print($text) || die $!;
}

sub read {
my $self = shift;
my $len = shift;

my $ret = "";
use bytes;
while (1) {
my $got = $self->read_socket->read( my $data, $len - length($ret));
if (not defined $got) {
die "error: $!";
} elsif ( $got == 0) {
die "EOF"
}
$ret .= $data;
if (length($ret) == $len) {
return $ret;
}
}
my $self = shift;
my $len = shift;

my $ret = "";
use bytes;
while (1) {
my $got = $self->read_socket->read(my $data, $len - length($ret));
if (not defined $got) {
die "error: $!";
} elsif ($got == 0) {
die "EOF"
}
$ret .= $data;
if (length($ret) == $len) {
return $ret;
}
}
}

sub read_line {
my $self = shift;
my $socket = $self->read_socket;
my $self = shift;
my $socket = $self->read_socket;

my $prefix = $self->read( 4 );
my $prefix = $self->read(4);

return if $prefix eq '0000';
return if $prefix eq '0000';

# warn "read prefix [$prefix]";
# warn "read prefix [$prefix]";

my $len = 0;
for my $n ( 0 .. 3 ) {
my $c = substr( $prefix, $n, 1 );
$len <<= 4;
my $len = 0;
for my $n (0 .. 3) {
my $c = substr($prefix, $n, 1);
$len <<= 4;

if ( $c ge '0' && $c le '9' ) {
$len += ord($c) - ord('0');
} elsif ( $c ge 'a' && $c le 'f' ) {
$len += ord($c) - ord('a') + 10;
} elsif ( $c ge 'A' && $c le 'F' ) {
$len += ord($c) - ord('A') + 10;
}
}
if ($c ge '0' && $c le '9') {
$len += ord($c) - ord('0');
} elsif ($c ge 'a' && $c le 'f') {
$len += ord($c) - ord('a') + 10;
} elsif ($c ge 'A' && $c le 'F') {
$len += ord($c) - ord('A') + 10;
}
}

return $self->read( $len - 4 );
return $self->read($len - 4);
}

1;
47 changes: 22 additions & 25 deletions lib/Cogit/Protocol/Git.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,37 @@ use namespace::clean;
extends 'Cogit::Protocol';

has hostname => (
is => 'ro',
isa => Str,
required => 1,
is => 'ro',
isa => Str,
required => 1,
);

has port => (
is => 'ro',
isa => Int,
default => sub { 9418 },
is => 'ro',
isa => Int,
default => sub { 9418 },
);

has project => (
is => 'rw',
isa => Str,
required => 1,
is => 'rw',
isa => Str,
required => 1,
);

sub connect_socket {
my $self = shift;

my $socket = IO::Socket::INET->new(
PeerAddr => $self->hostname,
PeerPort => $self->port,
Proto => 'tcp'
) || die $! . ' ' . $self->hostname . ':' . $self->port;
$socket->autoflush(1) || die $!;
$self->read_socket($socket);
$self->write_socket($socket);

$self->send_line( "git-upload-pack "
. $self->project
. "\0host="
. $self->hostname
. "\0" );
my $self = shift;

my $socket = IO::Socket::INET->new(
PeerAddr => $self->hostname,
PeerPort => $self->port,
Proto => 'tcp'
) || die $! . ' ' . $self->hostname . ':' . $self->port;
$socket->autoflush(1) || die $!;
$self->read_socket($socket);
$self->write_socket($socket);

$self->send_line(
"git-upload-pack " . $self->project . "\0host=" . $self->hostname . "\0");
}

1;
42 changes: 19 additions & 23 deletions lib/Cogit/Protocol/SSH.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,34 @@ use namespace::clean;
extends 'Cogit::Protocol';

has hostname => (
is => 'ro',
isa => Str,
required => 1,
is => 'ro',
isa => Str,
required => 1,
);

has username => (
is => 'ro',
isa => Str,
is => 'ro',
isa => Str,
);

has path => (
is => 'ro',
isa => Str,
required => 1,
is => 'ro',
isa => Str,
required => 1,
);

sub connect_socket {
my $self = shift;

my ($read, $write);
my $connect = join('@', grep {defined} $self->username, $self->hostname);
my $pid = open2(
$read, $write,
"ssh", $connect,
"-o", "BatchMode yes",
"git-upload-pack", $self->path,
);

$read->autoflush(1);
$write->autoflush(1);
$self->read_socket($read);
$self->write_socket($write);
my $self = shift;

my ($read, $write);
my $connect = join('@', grep { defined } $self->username, $self->hostname);
my $pid = open2($read, $write, "ssh", $connect, "-o", "BatchMode yes",
"git-upload-pack", $self->path,);

$read->autoflush(1);
$write->autoflush(1);
$self->read_socket($read);
$self->write_socket($write);
}

1;
Loading

0 comments on commit f8c8370

Please sign in to comment.