/[pxelator]/lib/PXElator/tftpd.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /lib/PXElator/tftpd.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 59 by dpavlin, Thu Jul 30 15:23:16 2009 UTC revision 208 by dpavlin, Wed Aug 12 23:59:01 2009 UTC
# Line 4  use warnings; Line 4  use warnings;
4  use strict;  use strict;
5    
6  use Net::TFTPd 0.03 qw(%OPCODES);  use Net::TFTPd 0.03 qw(%OPCODES);
7    use IO::Socket::INET;
8  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
9    use CouchDB;
10    
11  use server;  use server;
12    
13    our $debug = server::debug;
14    
15  our $dir  = "$server::base_dir/tftp";  our $dir  = "$server::base_dir/tftp";
16    
17  sub path {  sub path {
18          my $glob = shift;          my $glob = shift;
19          my $path = glob("$dir/$glob");          my $path = (glob("$dir/$glob"))[0];
20          die "can't find anything for $dir/$glob" unless $path;          die "can't find anything for $dir/$glob" unless $path;
21  warn $path;          warn 'path ', $path if $debug;
22          $path =~ s{^$dir}{};          $path =~ s{^$dir}{};
23          return $path;          return $path;
24  }  }
25    
26    use progress_bar;
27    
28  sub transfer_status {  sub transfer_status {
29          my $req = shift;          my $request = shift;
30          if( $req->{'_REQUEST_'}{'OPCODE'} eq $OPCODES{'RRQ'} ) {          my $r = $request->{'_REQUEST_'} || die "no _REQUEST_ in ",dump( $request );
31                  printf "RRQ %u\/%u\r", $req->{'_REQUEST_'}{'LASTACK'}, $req->{'_REQUEST_'}{'LASTBLK'};  
32          } elsif ( $req->{'_REQUEST_'}{'OPCODE'} eq $OPCODES{'WRQ'} ) {          if( $r->{'OPCODE'} eq $OPCODES{'RRQ'} ) {
33                    progress_bar::tick( $r->{FileName}, $r->{BlkSize} * $r->{LASTACK}, $r->{BlkSize} * $r->{LASTBLK} );
34            } elsif ( $r->{'OPCODE'} eq $OPCODES{'WRQ'} ) {
35                  die "WRQ disabled";                  die "WRQ disabled";
                 printf "WRQ: %u\/%u\n", $req->{'_REQUEST_'}{'LASTBLK'}, $req->{'_REQUEST_'}{'LASTACK'};  
36          } else {          } else {
37                  warn "IGNORED: ", dump( $req );                  warn "IGNORED: ", dump( $request );
38          }          }
39  }  }
40    
41    use config;
42    
43  sub tftp_request {  sub tftp_request {
44          my $request = shift;          my $request = shift;
45    
46            server->refresh;
47    
48            warn 'request: ', dump( $request ) if $debug;
49    
50            my $ip = $request->{_REQUEST_}->{PeerAddr};
51            config::for_ip( $ip );
52    
53          if ( $request->{RootDir} ne $dir ) {          if ( $request->{RootDir} ne $dir ) {
54                  $request->{RootDir} = $dir;                  $request->{RootDir} = $dir;
55                  warn "new root: $dir";                  warn "new root: $dir";
56          }          }
57    
58          # received request          my $file = $request->{'_REQUEST_'}{'FileName'};
59          printf "Received a %s for file '%s'\n", $OPCODES{$request->{'_REQUEST_'}{'OPCODE'}}, $request->{'_REQUEST_'}{'FileName'};          my $opcode = $OPCODES{$request->{'_REQUEST_'}{'OPCODE'}};
60    
61            my $audit = {
62                    ip => $ip,
63                    opcode => $opcode,
64                    file => $file,
65                    state => 'start',
66            };
67            CouchDB::audit( $opcode, $audit );
68    
69            progress_bar::start;
70    
71          # process the request          # process the request
72          if( $request->processRQ() ) {          if( $request->processRQ() ) {
73                  print "OK, transfer completed successfully\n";                  my $size = -s "$dir/$file";
74                    $audit->{state} = 'finish';
75                    $audit->{size} = $size;
76                    CouchDB::audit( $opcode, $audit );
77          } else {          } else {
78                  warn Net::TFTPd->error;                  $audit->{state} = 'error';
79                    $audit->{error} = Net::TFTPd->error;
80                    CouchDB::audit( $opcode, $audit );
81                  $request->processRQ();                  $request->processRQ();
82          }          }
83    
# Line 58  sub start { Line 89  sub start {
89    
90          warn 'start';          warn 'start';
91    
92          my $listener = Net::TFTPd->new(          # XXX we need to setup listener ourselfs because we need Reuse
93            my %params = (
94                    Proto => 'udp',
95    #               LocalAddr => $server::ip,
96    #               LocalAddr => '0.0.0.0',
97                    LocalPort => 69,
98                    Reuse => 1,
99            );
100    
101            my $udpserver = IO::Socket::INET->new(%params);
102            die "can't start server ",dump( \%params ), " $!" unless $udpserver;
103    
104            my $listener = bless {
105                  RootDir => $dir,                  RootDir => $dir,
106                  Writable => 0,  
107                  Timeout => 3600,                  ACKtimeout  => 4,
108                    ACKretries  => 4,
109                    Readable    => 1,
110                    Writable    => 0,
111                    Timeout => 3600,
112    
113                  CallBack => \&transfer_status,                  CallBack => \&transfer_status,
 #               LocalAddr => $server::ip,  
                 LocalAddr => '0.0.0.0',  
114  #               BlkSize => 8192,  #               BlkSize => 8192,
115  #               BlkSize => 512,  #               BlkSize => 512,
116                  BlkSize => 1456,        # IBM GE seems to be picky                  BlkSize => 1456,        # IBM GE seems to be picky
117                  Debug => 99,                  Debug => 99,
118          ) || die Net::TFTPd->error;                  %params, # merge user parameters
119                    _UDPSERVER_ => $udpserver,
120          warn 'listener: ',dump( $listener );          }, 'Net::TFTPd';
121    
122            warn 'listener: ',dump( $listener ) if $debug;
123    
124            CouchDB::audit( 'start', {
125                    addr => $listener->{LocalAddr},
126                    port => $listener->{LocalPort},
127                    timeout => $listener->{Timeout},
128                    params => { %params },
129            });
130    
131          while(1) {          while(1) {
           
                 printf "TFTP listen %s:%d timeout: %d dir: $dir\n",  
                         $listener->{LocalAddr},  
                         $listener->{LocalPort},  
                         $listener->{Timeout};  
132    
133                  # wait for any request (RRQ or WRQ)                  # wait for any request (RRQ or WRQ)
134                  if(my $request = $listener->waitRQ()) {                  if(my $request = $listener->waitRQ()) {
135                          tftp_request $request;                          tftp_request $request;
136                  } else {                  } elsif ( my $error = Net::TFTPd->error ) {
137                          warn Net::TFTPd->error;                          warn $error;
138                  }                  }
139    
140          }          }

Legend:
Removed from v.59  
changed lines
  Added in v.208

  ViewVC Help
Powered by ViewVC 1.1.26