/[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 110 by dpavlin, Sun Aug 2 02:04:00 2009 UTC revision 548 by dpavlin, Sat Oct 9 20:06:44 2010 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 Module::Refresh;  use store;
10    
11  use server;  use server;
12    
# Line 22  sub path { Line 23  sub path {
23          return $path;          return $path;
24  }  }
25    
26  STDERR->autoflush(1);  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 STDERR "RRQ %s %u\/%u\r", map { $req->{_REQUEST_}->{$_} } ( 'FileName', 'LASTACK', '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 STDERR "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    $SIG{CHLD}='IGNORE';
44    
45  sub tftp_request {  sub tftp_request {
46          my $request = shift;          my $request = shift;
47    
48          warn 'request: ', dump( $request ) if $debug;          warn 'request: ', dump( $request ) if $debug;
49    
50          config::for_ip();          if ( my $pid = fork ) {
51                    # parent
52                    warn "# forked $pid\n";
53                    return;
54            }
55    
56    
57            my $ip = $request->{_REQUEST_}->{PeerAddr};
58            config::for_ip( $ip );
59    
60          if ( $request->{RootDir} ne $dir ) {          if ( $request->{RootDir} ne $dir ) {
61                  $request->{RootDir} = $dir;                  $request->{RootDir} = $dir;
# Line 49  sub tftp_request { Line 63  sub tftp_request {
63          }          }
64    
65          my $file = $request->{'_REQUEST_'}{'FileName'};          my $file = $request->{'_REQUEST_'}{'FileName'};
66          # received request          my $opcode = $OPCODES{$request->{'_REQUEST_'}{'OPCODE'}};
67          print $OPCODES{$request->{'_REQUEST_'}{'OPCODE'}}, " $file\n";  
68            my $audit = {
69                    ip => $ip,
70                    opcode => $opcode,
71                    path => $file,
72                    state => 'start',
73            };
74            store::audit( $opcode, $audit );
75    
76            progress_bar::start;
77    
78          # process the request          # process the request
79          if( $request->processRQ() ) {          if( $request->processRQ() ) {
80                  print "\nOK completed $file ", -s "$dir/$file", "\n";                  my $size = -s "$dir/$file";
81                    $audit->{state} = 'finish';
82                    $audit->{size} = $size;
83                    store::audit( $opcode, $audit );
84          } else {          } else {
85                  print "ERROR ", Net::TFTPd->error, "\n";                  $audit->{state} = 'error';
86                  $request->processRQ();                  $audit->{error} = Net::TFTPd->error;
87                    store::audit( $opcode, $audit );
88          }          }
89    
90            exit 0;
91  }  }
92    
93  use server;  use server;
# Line 68  sub start { Line 96  sub start {
96    
97          warn 'start';          warn 'start';
98    
99          my $listener = Net::TFTPd->new(          # XXX we need to setup listener ourselfs because we need Reuse
100            my %params = (
101                    Proto => 'udp',
102    #               LocalAddr => $server::ip,
103    #               LocalAddr => '0.0.0.0',
104                    LocalPort => 69,
105                    Reuse => 1,
106            );
107    
108            my $udpserver = IO::Socket::INET->new(%params);
109            die "can't start server ",dump( \%params ), " $!" unless $udpserver;
110    
111            my $listener = bless {
112                  RootDir => $dir,                  RootDir => $dir,
113                  Writable => 0,  
114                  Timeout => 3600,                  ACKtimeout  => 1, # 4
115                    ACKretries  => 2, # 4
116                    Readable    => 1,
117                    Writable    => 0,
118                    Timeout => 3600,
119    
120                  CallBack => \&transfer_status,                  CallBack => \&transfer_status,
 #               LocalAddr => $server::ip,  
                 LocalAddr => '0.0.0.0',  
121  #               BlkSize => 8192,  #               BlkSize => 8192,
122  #               BlkSize => 512,                  BlkSize => 512,         # Dell's RAC doesn't like bigger packets
123                  BlkSize => 1456,        # IBM GE seems to be picky  #               BlkSize => 1456,        # IBM GE seems to be picky
124                  Debug => 99,                  Debug => 99,
125          ) || die Net::TFTPd->error;                  %params, # merge user parameters
126                    _UDPSERVER_ => $udpserver,
127            }, 'Net::TFTPd';
128    
129          warn 'listener: ',dump( $listener ) if $debug;          warn 'listener: ',dump( $listener ) if $debug;
130    
131          printf "TFTP listen %s:%d timeout: %d dir: $dir\n",          store::audit( 'start', {
132                  $listener->{LocalAddr},                  addr => $listener->{LocalAddr},
133                  $listener->{LocalPort},                  port => $listener->{LocalPort},
134                  $listener->{Timeout};                  timeout => $listener->{Timeout},
135                    params => { %params },
136            });
137    
138          while(1) {          while(1) {
139    
                 Module::Refresh->refresh;  
   
140                  # wait for any request (RRQ or WRQ)                  # wait for any request (RRQ or WRQ)
141                  if(my $request = $listener->waitRQ()) {                  if(my $request = $listener->waitRQ()) {
142                            server->refresh;
143                          tftp_request $request;                          tftp_request $request;
144                  } else {                  } elsif ( my $error = Net::TFTPd->error ) {
145                          warn Net::TFTPd->error;                          warn $error;
146                  }                  }
147    
148          }          }

Legend:
Removed from v.110  
changed lines
  Added in v.548

  ViewVC Help
Powered by ViewVC 1.1.26