File Coverage

blib/lib/AnyEvent/FTP/Server/Context/FS.pm
Criterion Covered Total %
statement 142 152 93.4
branch 38 46 82.6
condition 2 2 100.0
subroutine 34 34 100.0
pod 2 22 9.0
total 218 256 85.1


line stmt bran cond sub pod time code
1             package AnyEvent::FTP::Server::Context::FS;
2              
3 12     12   233728 use strict;
  12         43  
  12         445  
4 12     12   75 use warnings;
  12         27  
  12         382  
5 12     12   293 use 5.010;
  12         66  
6 12     12   608 use Moo;
  12         11415  
  12         81  
7 12     12   6984 use File::chdir;
  12         6659  
  12         1661  
8 12     12   101 use File::Spec;
  12         72  
  12         3141  
9              
10             extends 'AnyEvent::FTP::Server::Context';
11              
12             # ABSTRACT: FTP server context that uses real file system (no transfers)
13             our $VERSION = '0.18'; # VERSION
14              
15              
16             with 'AnyEvent::FTP::Server::Role::Auth';
17             with 'AnyEvent::FTP::Server::Role::Help';
18             with 'AnyEvent::FTP::Server::Role::Old';
19             with 'AnyEvent::FTP::Server::Role::Type';
20              
21              
22             sub cwd
23             {
24 217     217 1 716 my($self, $value) = @_;
25 217 100       1304 $self->{cwd} = $value if defined $value;
26 217   100     1947 $self->{cwd} //= '/';
27             }
28              
29              
30             sub rename_from
31             {
32 18     18 1 52 my($self, $value) = @_;
33 18 100       77 $self->{rename_from} = $value if defined $value;
34 18         399 $self->{rename_from};
35             }
36              
37              
38 1     1 0 4 sub help_cwd { 'CWD pathname' }
39              
40             sub cmd_cwd
41             {
42 36     36 0 106 my($self, $con, $req) = @_;
43              
44 36         134 my $dir = $req->args;
45              
46 36         78 eval {
47 36 100       141 die unless $dir;
48 12     12   1188 use autodie;
  12         30131  
  12         97  
49 34         161 local $CWD = $self->cwd;
50 34         2407 $CWD = $dir;
51 33         858 $self->cwd($CWD);
52 33         172 $con->send_response(250 => 'CWD command successful');
53             };
54 36 100       1622 $con->send_response(550 => 'CWD error') if $@;
55              
56 36         167 $self->done;
57             }
58              
59              
60 1     1 0 5 sub help_cdup { 'CDUP' }
61              
62             sub cmd_cdup
63             {
64 5     5 0 47 my($self, $con, $req) = @_;
65              
66 5         22 eval {
67 12     12   88136 use autodie;
  12         45  
  12         67  
68 5         34 local $CWD = $self->cwd;
69 5         425 $CWD = File::Spec->updir;
70 5         132 $self->cwd($CWD);
71 5         46 $con->send_response(250 => 'CDUP command successful');
72             };
73 5 50       168 $con->send_response(550 => 'CDUP error') if $@;
74              
75 5         122 $self->done;
76             }
77              
78              
79 1     1 0 5 sub help_pwd { 'PWD' }
80              
81             sub cmd_pwd
82             {
83 9     9 0 48 my($self, $con, $req) = @_;
84              
85 9         41 my $cwd = $self->cwd;
86 9 50       134 if($^O eq 'MSWin32')
87             {
88 0         0 (undef,$cwd) = File::Spec->splitpath($cwd, 1);
89 0         0 $cwd =~ s{\\}{/}g;
90             }
91 9         139 $con->send_response(257 => "\"$cwd\" is the current directory");
92 9         51 $self->done;
93             }
94              
95              
96 1     1 0 5 sub help_size { 'SIZE pathname' }
97              
98             sub cmd_size
99             {
100 12     12 0 48 my($self, $con, $req) = @_;
101              
102 12         29 eval {
103 12     12   81496 use autodie;
  12         38  
  12         66  
104 12         60 local $CWD = $self->cwd;
105 12 100       700 if(-f $req->args)
    100          
106             {
107 8         45 my $size = -s $req->args;
108 8         54 $con->send_response(213 => $size);
109             }
110             elsif(-e $req->args)
111             {
112 2         10 $con->send_response(550 => $req->args . ": not a regular file");
113             }
114             else
115             {
116 2         21 die;
117             }
118             };
119 12 100       382 if($@)
120             {
121 2         10 $con->send_response(550 => $req->args . ": No such file or directory");
122             }
123 12         69 $self->done;
124             }
125              
126              
127 1     1 0 6 sub help_mkd { 'MKD pathname' }
128              
129             sub cmd_mkd
130             {
131 7     7 0 32 my($self, $con, $req) = @_;
132              
133 7         27 my $dir = $req->args;
134 7         22 eval {
135 12     12   78591 use autodie;
  12         33  
  12         91  
136 7         26 local $CWD = $self->cwd;
137 7         377 mkdir $dir;
138 5         1891 $con->send_response(257 => "Directory created");
139             };
140 7 100       9052 $con->send_response(550 => "MKD error") if $@;
141 7         35 $self->done;
142             }
143              
144              
145 1     1 0 4 sub help_rmd { 'RMD pathname' }
146              
147             sub cmd_rmd
148             {
149 9     9 0 55 my($self, $con, $req) = @_;
150              
151 9         41 my $dir = $req->args;
152 9         24 eval {
153 12     12   80005 use autodie;
  12         35  
  12         97  
154 9         69 local $CWD = $self->cwd;
155 9         493 rmdir $dir;
156 5         1593 $con->send_response(250 => "Directory removed");
157             };
158 9 100       5687 $con->send_response(550 => "RMD error") if $@;
159 9         59 $self->done;
160             }
161              
162              
163 1     1 0 5 sub help_dele { 'DELE pathname' }
164              
165             sub cmd_dele
166             {
167 10     10 0 46 my($self, $con, $req) = @_;
168              
169 10         36 my $file = $req->args;
170 10         23 eval {
171 12     12   78249 use autodie;
  12         31  
  12         70  
172 10         35 local $CWD = $self->cwd;
173 10         606 unlink $file;
174 5         1188 $con->send_response(250 => "File removed");
175             };
176 10 100       12595 $con->send_response(550 => "DELE error") if $@;
177 10         58 $self->done;
178             }
179              
180              
181 1     1 0 5 sub help_rnfr { 'RNFR pathname' }
182              
183             sub cmd_rnfr
184             {
185 10     10 0 60 my($self, $con, $req) = @_;
186              
187 10         49 my $path = $req->args;
188              
189 10 100       37 if($path)
190             {
191 8         18 eval {
192 8         39 local $CWD = $self->cwd;
193 8 100       665 if(!-e $path)
    50          
194             {
195 2         12 $con->send_response(550 => 'No such file or directory');
196             }
197             elsif(-w $path)
198             {
199 6         80 $self->rename_from($path);
200 6         45 $con->send_response(350 => 'File or directory exists, ready for destination name');
201             }
202             else
203             {
204 0         0 $con->send_response(550 => 'Permission denied');
205             }
206             };
207 8 50       278 if(my $error = $@)
208             {
209 0         0 warn $error;
210 0         0 $con->send_response(550 => 'Rename failed');
211             }
212             }
213             else
214             {
215 2         11 $con->send_response(501 => 'Invalid number of arguments');
216             }
217 10         59 $self->done;
218             }
219              
220              
221 1     1 0 4 sub help_rnto { 'RNTO pathname' }
222              
223             sub cmd_rnto
224             {
225 6     6 0 36 my($self, $con, $req) = @_;
226              
227 6         24 my $path = $req->args;
228              
229 6 50       20 if(! defined $self->rename_from)
    50          
230             {
231 0         0 $con->send_response(503 => 'Bad sequence of commands');
232             }
233             elsif(!$path)
234             {
235 0         0 $con->send_response(501 => 'Invalid number of arguments');
236             }
237             else
238             {
239 6         14 eval {
240 6         25 local $CWD = $self->cwd;
241 6 50       451 if(! -e $path)
242             {
243 6         38 rename $self->rename_from, $path;
244 6         65 $con->send_response(250 => 'Rename successful');
245             }
246             else
247             {
248 0         0 $con->send_response(550 => 'File already exists');
249             }
250             };
251 6 50       192 if(my $error = $@)
252             {
253 0         0 warn $error;
254 0         0 $con->send_response(550 => 'Rename failed');
255             }
256             }
257 6         37 $self->done;
258             }
259              
260              
261 1     1 0 5 sub help_stat { 'STAT [ pathname]' }
262              
263             sub cmd_stat
264             {
265 9     9 0 32 my($self, $con, $req) = @_;
266              
267 9         32 my $path = $req->args;
268              
269 9 100       32 if($path)
270             {
271 6         13 do {
272 6         22 local $CWD = $self->cwd;
273 6 100       557 if(-d $path)
    100          
274             {
275 3         29 $con->send_response(211 => "it's a directory");
276             }
277             elsif(-f $path)
278             {
279 2         13 $con->send_response(211 => "it's a file");
280             }
281             else
282             {
283 1         16 $con->send_response(450 => 'No such file or directory');
284             }
285             };
286             }
287             else
288             {
289             # TODO: did I have a good reason for making this
290             # not be an error?
291 3         20 $con->send_response(211 => "it's all good.");
292             }
293 9         211 $self->done;
294             }
295              
296             1;
297              
298             __END__