ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-FCP/FCP.pm
(Generate patch)

Comparing cvsroot/Net-FCP/FCP.pm (file contents):
Revision 1.30 by root, Fri May 14 16:12:26 2004 UTC vs.
Revision 1.40 by root, Sun Dec 23 15:42:48 2007 UTC

13 13
14=head1 DESCRIPTION 14=head1 DESCRIPTION
15 15
16See L<http://freenet.sourceforge.net/index.php?page=fcp> for a description 16See L<http://freenet.sourceforge.net/index.php?page=fcp> for a description
17of what the messages do. I am too lazy to document all this here. 17of what the messages do. I am too lazy to document all this here.
18
19The module uses L<AnyEvent> to find a suitable Event module.
18 20
19=head1 WARNING 21=head1 WARNING
20 22
21This module is alpha. While it probably won't destroy (much :) of your 23This module is alpha. While it probably won't destroy (much :) of your
22data, it currently falls short of what it should provide (intelligent uri 24data, it currently falls short of what it should provide (intelligent uri
23following, splitfile downloads, healing...) 25following, splitfile downloads, healing...)
24 26
25=head2 IMPORT TAGS 27=head2 IMPORT TAGS
26 28
27Nothing much can be "imported" from this module right now. There are, 29Nothing much can be "imported" from this module right now.
28however, certain "import tags" that can be used to select the event model
29to be used.
30
31Event models are implemented as modules under the C<Net::FCP::Event::xyz>
32class, where C<xyz> is the event model to use. The default is C<Event> (or
33later C<Auto>).
34
35The import tag to use is named C<event=xyz>, e.g. C<event=Event>,
36C<event=Glib> etc.
37
38You should specify the event module to use only in the main program.
39
40If no event model has been specified, FCP tries to autodetect it on first
41use (e.g. first transaction), in this order: Coro, Event, Glib, Tk.
42 30
43=head2 FREENET BASICS 31=head2 FREENET BASICS
44 32
45Ok, this section will not explain any freenet basics to you, just some 33Ok, this section will not explain any freenet basics to you, just some
46problems I found that you might want to avoid: 34problems I found that you might want to avoid:
72 60
73package Net::FCP; 61package Net::FCP;
74 62
75use Carp; 63use Carp;
76 64
77$VERSION = 0.7; 65$VERSION = '1.1';
78 66
79no warnings; 67no warnings;
80 68
69use AnyEvent;
70
81use Net::FCP::Metadata; 71use Net::FCP::Metadata;
82 72use Net::FCP::Util qw(tolc touc xeh);
83our $EVENT = Net::FCP::Event::Auto::;
84
85sub import {
86 shift;
87
88 for (@_) {
89 if (/^event=(\w+)$/) {
90 $EVENT = "Net::FCP::Event::$1";
91 eval "require $EVENT";
92 }
93 }
94 die $@ if $@;
95}
96
97sub touc($) {
98 local $_ = shift;
99 1 while s/((?:^|_)(?:svk|chk|uri)(?:_|$))/\U$1/;
100 s/(?:^|_)(.)/\U$1/g;
101 $_;
102}
103
104sub tolc($) {
105 local $_ = shift;
106 1 while s/(SVK|CHK|URI)([^_])/$1\_$2/i;
107 1 while s/([^_])(SVK|CHK|URI)/$1\_$2/i;
108 s/(?<=[a-z])(?=[A-Z])/_/g;
109 lc $_;
110}
111
112# the opposite of hex
113sub xeh($) {
114 sprintf "%x", $_[0];
115}
116 73
117=item $fcp = new Net::FCP [host => $host][, port => $port][, progress => \&cb] 74=item $fcp = new Net::FCP [host => $host][, port => $port][, progress => \&cb]
118 75
119Create a new virtual FCP connection to the given host and port (default 76Create a new virtual FCP connection to the given host and port (default
120127.0.0.1:8481, or the environment variables C<FREDHOST> and C<FREDPORT>). 77127.0.0.1:8481, or the environment variables C<FREDHOST> and C<FREDPORT>).
274 cipher => $cipher || "Twofish"); 231 cipher => $cipher || "Twofish");
275}); 232});
276 233
277=item $txn = $fcp->txn_generate_svk_pair 234=item $txn = $fcp->txn_generate_svk_pair
278 235
279=item ($public, $private) = @{ $fcp->generate_svk_pair } 236=item ($public, $private, $crypto) = @{ $fcp->generate_svk_pair }
280 237
281Creates a new SVK pair. Returns an arrayref with the public key, the 238Creates a new SVK pair. Returns an arrayref with the public key, the
282private key and a crypto key, which is just additional entropy. 239private key and a crypto key, which is just additional entropy.
283 240
284 [ 241 [
425 382
426sub new { 383sub new {
427 my $class = shift; 384 my $class = shift;
428 my $self = bless { @_ }, $class; 385 my $self = bless { @_ }, $class;
429 386
430 $self->{signal} = $EVENT->new_signal; 387 $self->{signal} = AnyEvent->condvar;
431 388
432 $self->{fcp}{txn}{$self} = $self; 389 $self->{fcp}{txn}{$self} = $self;
433 390
434 my $attr = ""; 391 my $attr = "";
435 my $data = delete $self->{attr}{data}; 392 my $data = delete $self->{attr}{data};
447 404
448 socket my $fh, PF_INET, SOCK_STREAM, 0 405 socket my $fh, PF_INET, SOCK_STREAM, 0
449 or Carp::croak "unable to create new tcp socket: $!"; 406 or Carp::croak "unable to create new tcp socket: $!";
450 binmode $fh, ":raw"; 407 binmode $fh, ":raw";
451 fcntl $fh, F_SETFL, O_NONBLOCK; 408 fcntl $fh, F_SETFL, O_NONBLOCK;
452 connect $fh, (sockaddr_in $self->{fcp}{port}, inet_aton $self->{fcp}{host}) 409 connect $fh, (sockaddr_in $self->{fcp}{port}, inet_aton $self->{fcp}{host});
453 and !$!{EWOULDBLOCK}
454 and !$!{EINPROGRESS}
455 and Carp::croak "FCP::txn: unable to connect to $self->{fcp}{host}:$self->{fcp}{port}: $!\n"; 410# and Carp::croak "FCP::txn: unable to connect to $self->{fcp}{host}:$self->{fcp}{port}: $!\n";
456 411
457 $self->{sbuf} = 412 $self->{sbuf} =
458 "\x00\x00\x00\x02" 413 "\x00\x00\x00\x02"
459 . (Net::FCP::touc $self->{type}) 414 . (Net::FCP::touc $self->{type})
460 . "\012$attr$data"; 415 . "\012$attr$data";
461 416
462 #shutdown $fh, 1; # freenet buggy?, well, it's java... 417 #shutdown $fh, 1; # freenet buggy?, well, it's java...
463 418
464 $self->{fh} = $fh; 419 $self->{fh} = $fh;
465 420
466 $self->{w} = $EVENT->new_from_fh ($fh)->cb(sub { $self->fh_ready_w })->poll(0, 1, 1); 421 $self->{w} = AnyEvent->io (fh => $fh, poll => 'w', cb => sub { $self->fh_ready_w });
467 422
468 $self; 423 $self;
469} 424}
470 425
471=item $txn = $txn->cb ($coderef) 426=item $txn = $txn->cb ($coderef)
507 $self; 462 $self;
508} 463}
509 464
510=item $txn->cancel (%attr) 465=item $txn->cancel (%attr)
511 466
512Cancels the operation with a C<cancel> exception anf the given attributes 467Cancels the operation with a C<cancel> exception and the given attributes
513(consider at least giving the attribute C<reason>). 468(consider at least giving the attribute C<reason>).
514 469
515UNTESTED. 470UNTESTED.
516 471
517=cut 472=cut
530 485
531 if ($len > 0) { 486 if ($len > 0) {
532 substr $self->{sbuf}, 0, $len, ""; 487 substr $self->{sbuf}, 0, $len, "";
533 unless (length $self->{sbuf}) { 488 unless (length $self->{sbuf}) {
534 fcntl $self->{fh}, F_SETFL, 0; 489 fcntl $self->{fh}, F_SETFL, 0;
535 $self->{w}->cb(sub { $self->fh_ready_r })->poll (1, 0, 1); 490 $self->{w} = AnyEvent->io (fh => $self->{fh}, poll => 'r', cb => sub { $self->fh_ready_r });
536 } 491 }
537 } elsif (defined $len) { 492 } elsif (defined $len) {
538 $self->throw (Net::FCP::Exception->new (network_error => { reason => "unexpected end of file while writing" })); 493 $self->throw (Net::FCP::Exception->new (network_error => { reason => "unexpected end of file while writing" }));
539 } else { 494 } else {
540 $self->throw (Net::FCP::Exception->new (network_error => { reason => "$!" })); 495 $self->throw (Net::FCP::Exception->new (network_error => { reason => "$!" }));
542} 497}
543 498
544sub fh_ready_r { 499sub fh_ready_r {
545 my ($self) = @_; 500 my ($self) = @_;
546 501
547 if (sysread $self->{fh}, $self->{buf}, 65536, length $self->{buf}) { 502 if (sysread $self->{fh}, $self->{buf}, 16384 + 1024, length $self->{buf}) {
548 for (;;) { 503 for (;;) {
549 if ($self->{datalen}) { 504 if ($self->{datalen}) {
550 #warn "expecting new datachunk $self->{datalen}, got ".(length $self->{buf})."\n";#d# 505 #warn "expecting new datachunk $self->{datalen}, got ".(length $self->{buf})."\n";#d#
551 if (length $self->{buf} >= $self->{datalen}) { 506 if (length $self->{buf} >= $self->{datalen}) {
552 $self->rcv_data (substr $self->{buf}, 0, delete $self->{datalen}, ""); 507 $self->rcv_data (substr $self->{buf}, 0, delete $self->{datalen}, "");
605 my ($self, $result) = @_; 560 my ($self, $result) = @_;
606 561
607 unless (exists $self->{result}) { 562 unless (exists $self->{result}) {
608 $self->{result} = $result; 563 $self->{result} = $result;
609 $self->{cb}->($self) if exists $self->{cb}; 564 $self->{cb}->($self) if exists $self->{cb};
610 $self->{signal}->send; 565 $self->{signal}->broadcast;
611 } 566 }
612} 567}
613 568
614sub eof { 569sub eof {
615 my ($self) = @_; 570 my ($self) = @_;
855 810
856=head1 BUGS 811=head1 BUGS
857 812
858=head1 AUTHOR 813=head1 AUTHOR
859 814
860 Marc Lehmann <pcg@goof.com> 815 Marc Lehmann <schmorp@schmorp.de>
861 http://www.goof.com/pcg/marc/ 816 http://home.schmorp.de/
862 817
863=cut 818=cut
864 819
865package Net::FCP::Event::Auto; 8201
866 821
867my @models = (
868 [Coro => Coro::Event::],
869 [Event => Event::],
870 [Glib => Glib::],
871 [Tk => Tk::],
872);
873
874sub AUTOLOAD {
875 $AUTOLOAD =~ s/.*://;
876
877 for (@models) {
878 my ($model, $package) = @$_;
879 if (defined ${"$package\::VERSION"}) {
880 $EVENT = "Net::FCP::Event::$model";
881 eval "require $EVENT"; die if $@;
882 goto &{"$EVENT\::$AUTOLOAD"};
883 }
884 }
885
886 for (@models) {
887 my ($model, $package) = @$_;
888 $EVENT = "Net::FCP::Event::$model";
889 if (eval "require $EVENT") {
890 goto &{"$EVENT\::$AUTOLOAD"};
891 }
892 }
893
894 die "No event module selected for Net::FCP and autodetect failed. Install any of these: Coro, Event, Glib or Tk.";
895}
896
8971;
898

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines