… | |
… | |
11 | my $ni = $fcp->txn_node_info->result; |
11 | my $ni = $fcp->txn_node_info->result; |
12 | my $ni = $fcp->node_info; |
12 | my $ni = $fcp->node_info; |
13 | |
13 | |
14 | =head1 DESCRIPTION |
14 | =head1 DESCRIPTION |
15 | |
15 | |
|
|
16 | This module implements the first version of the freenet client protocol, |
|
|
17 | for use with freenet versions 0.5. For freenet protocol version 2.0 |
|
|
18 | support (as used by freenet 0.7), see the L<AnyEvent::FCP> module. |
|
|
19 | |
16 | See L<http://freenet.sourceforge.net/index.php?page=fcp> for a description |
20 | See L<http://freenet.sourceforge.net/index.php?page=fcp> for a description |
17 | of what the messages do. I am too lazy to document all this here. |
21 | of what the messages do. |
18 | |
22 | |
19 | The module uses L<AnyEvent> to find a suitable Event module. |
23 | The module uses L<AnyEvent> to find a suitable Event module. |
20 | |
|
|
21 | =head1 WARNING |
|
|
22 | |
|
|
23 | This module is alpha. While it probably won't destroy (much :) of your |
|
|
24 | data, it currently falls short of what it should provide (intelligent uri |
|
|
25 | following, splitfile downloads, healing...) |
|
|
26 | |
24 | |
27 | =head2 IMPORT TAGS |
25 | =head2 IMPORT TAGS |
28 | |
26 | |
29 | Nothing much can be "imported" from this module right now. |
27 | Nothing much can be "imported" from this module right now. |
30 | |
28 | |
… | |
… | |
60 | |
58 | |
61 | package Net::FCP; |
59 | package Net::FCP; |
62 | |
60 | |
63 | use Carp; |
61 | use Carp; |
64 | |
62 | |
65 | $VERSION = '1.0'; |
63 | $VERSION = '1.2'; |
66 | |
64 | |
67 | no warnings; |
65 | no warnings; |
68 | |
66 | |
69 | use AnyEvent; |
67 | use AnyEvent; |
70 | |
68 | |
… | |
… | |
404 | |
402 | |
405 | socket my $fh, PF_INET, SOCK_STREAM, 0 |
403 | socket my $fh, PF_INET, SOCK_STREAM, 0 |
406 | or Carp::croak "unable to create new tcp socket: $!"; |
404 | or Carp::croak "unable to create new tcp socket: $!"; |
407 | binmode $fh, ":raw"; |
405 | binmode $fh, ":raw"; |
408 | fcntl $fh, F_SETFL, O_NONBLOCK; |
406 | fcntl $fh, F_SETFL, O_NONBLOCK; |
409 | connect $fh, (sockaddr_in $self->{fcp}{port}, inet_aton $self->{fcp}{host}) |
407 | connect $fh, (sockaddr_in $self->{fcp}{port}, inet_aton $self->{fcp}{host}); |
410 | and !$!{EWOULDBLOCK} |
|
|
411 | and !$!{EINPROGRESS} |
|
|
412 | and Carp::croak "FCP::txn: unable to connect to $self->{fcp}{host}:$self->{fcp}{port}: $!\n"; |
408 | # and Carp::croak "FCP::txn: unable to connect to $self->{fcp}{host}:$self->{fcp}{port}: $!\n"; |
413 | |
409 | |
414 | $self->{sbuf} = |
410 | $self->{sbuf} = |
415 | "\x00\x00\x00\x02" |
411 | "\x00\x00\x00\x02" |
416 | . (Net::FCP::touc $self->{type}) |
412 | . (Net::FCP::touc $self->{type}) |
417 | . "\012$attr$data"; |
413 | . "\012$attr$data"; |
… | |
… | |
487 | |
483 | |
488 | if ($len > 0) { |
484 | if ($len > 0) { |
489 | substr $self->{sbuf}, 0, $len, ""; |
485 | substr $self->{sbuf}, 0, $len, ""; |
490 | unless (length $self->{sbuf}) { |
486 | unless (length $self->{sbuf}) { |
491 | fcntl $self->{fh}, F_SETFL, 0; |
487 | fcntl $self->{fh}, F_SETFL, 0; |
492 | undef $self->{w}; #d# #workaround for buggy Tk versions |
|
|
493 | $self->{w} = AnyEvent->io (fh => $self->{fh}, poll => 'r', cb => sub { $self->fh_ready_r }); |
488 | $self->{w} = AnyEvent->io (fh => $self->{fh}, poll => 'r', cb => sub { $self->fh_ready_r }); |
494 | } |
489 | } |
495 | } elsif (defined $len) { |
490 | } elsif (defined $len) { |
496 | $self->throw (Net::FCP::Exception->new (network_error => { reason => "unexpected end of file while writing" })); |
491 | $self->throw (Net::FCP::Exception->new (network_error => { reason => "unexpected end of file while writing" })); |
497 | } else { |
492 | } else { |
… | |
… | |
500 | } |
495 | } |
501 | |
496 | |
502 | sub fh_ready_r { |
497 | sub fh_ready_r { |
503 | my ($self) = @_; |
498 | my ($self) = @_; |
504 | |
499 | |
505 | if (sysread $self->{fh}, $self->{buf}, 65536, length $self->{buf}) { |
500 | if (sysread $self->{fh}, $self->{buf}, 16384 + 1024, length $self->{buf}) { |
506 | for (;;) { |
501 | for (;;) { |
507 | if ($self->{datalen}) { |
502 | if ($self->{datalen}) { |
508 | #warn "expecting new datachunk $self->{datalen}, got ".(length $self->{buf})."\n";#d# |
503 | #warn "expecting new datachunk $self->{datalen}, got ".(length $self->{buf})."\n";#d# |
509 | if (length $self->{buf} >= $self->{datalen}) { |
504 | if (length $self->{buf} >= $self->{datalen}) { |
510 | $self->rcv_data (substr $self->{buf}, 0, delete $self->{datalen}, ""); |
505 | $self->rcv_data (substr $self->{buf}, 0, delete $self->{datalen}, ""); |