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   237694 use strict;
  12         40  
  12         429  
4 12     12   75 use warnings;
  12         32  
  12         392  
5 12     12   300 use 5.010;
  12         79  
6 12     12   628 use Moo;
  12         11776  
  12         97  
7 12     12   6850 use File::chdir;
  12         6483  
  12         1537  
8 12     12   90 use File::Spec;
  12         73  
  12         3043  
9              
10             extends 'AnyEvent::FTP::Server::Context';
11              
12             # ABSTRACT: FTP server context that uses real file system (no transfers)
13             our $VERSION = '0.17'; # 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 667 my($self, $value) = @_;
25 217 100       1261 $self->{cwd} = $value if defined $value;
26 217   100     1614 $self->{cwd} //= '/';
27             }
28              
29              
30             sub rename_from
31             {
32 18     18 1 51 my($self, $value) = @_;
33 18 100       90 $self->{rename_from} = $value if defined $value;
34 18         327 $self->{rename_from};
35             }
36              
37              
38 1     1 0 5 sub help_cwd { 'CWD pathname' }
39              
40             sub cmd_cwd
41             {
42 36     36 0 118 my($self, $con, $req) = @_;
43              
44 36         124 my $dir = $req->args;
45              
46 36         109 eval {
47 36 100       158 die unless $dir;
48 12     12   1133 use autodie;
  12         29418  
  12         95  
49 34         158 local $CWD = $self->cwd;
50 34         2050 $CWD = $dir;
51 33         875 $self->cwd($CWD);
52 33         157 $con->send_response(250 => 'CWD command successful');
53             };
54 36 100       1649 $con->send_response(550 => 'CWD error') if $@;
55              
56 36         154 $self->done;
57             }
58              
59              
60 1     1 0 6 sub help_cdup { 'CDUP' }
61              
62             sub cmd_cdup
63             {
64 5     5 0 50 my($self, $con, $req) = @_;
65              
66 5         25 eval {
67 12     12   87615 use autodie;
  12         46  
  12         83  
68 5         32 local $CWD = $self->cwd;
69 5         398 $CWD = File::Spec->updir;
70 5         148 $self->cwd($CWD);
71 5         54 $con->send_response(250 => 'CDUP command successful');
72             };
73 5 50       166 $con->send_response(550 => 'CDUP error') if $@;
74              
75 5         137 $self->done;
76             }
77              
78              
79 1     1 0 5 sub help_pwd { 'PWD' }
80              
81             sub cmd_pwd
82             {
83 9     9 0 46 my($self, $con, $req) = @_;
84              
85 9         31 my $cwd = $self->cwd;
86 9 50       137 if($^O eq 'MSWin32')
87             {
88 0         0 (undef,$cwd) = File::Spec->splitpath($cwd, 1);
89 0         0 $cwd =~ s{\\}{/}g;
90             }
91 9         76 $con->send_response(257 => "\"$cwd\" is the current directory");
92 9         50 $self->done;
93             }
94              
95              
96 1     1 0 6 sub help_size { 'SIZE pathname' }
97              
98             sub cmd_size
99             {
100 12     12 0 54 my($self, $con, $req) = @_;
101              
102 12         34 eval {
103 12     12   81715 use autodie;
  12         32  
  12         70  
104 12         52 local $CWD = $self->cwd;
105 12 100       879 if(-f $req->args)
    100          
106             {
107 8         55 my $size = -s $req->args;
108 8         83 $con->send_response(213 => $size);
109             }
110             elsif(-e $req->args)
111             {
112 2         29 $con->send_response(550 => $req->args . ": not a regular file");
113             }
114             else
115             {
116 2         23 die;
117             }
118             };
119 12 100       524 if($@)
120             {
121 2         9 $con->send_response(550 => $req->args . ": No such file or directory");
122             }
123 12         70 $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 36 my($self, $con, $req) = @_;
132              
133 7         31 my $dir = $req->args;
134 7         24 eval {
135 12     12   81450 use autodie;
  12         35  
  12         71  
136 7         36 local $CWD = $self->cwd;
137 7         523 mkdir $dir;
138 5         2162 $con->send_response(257 => "Directory created");
139             };
140 7 100       11260 $con->send_response(550 => "MKD error") if $@;
141 7         46 $self->done;
142             }
143              
144              
145 1     1 0 5 sub help_rmd { 'RMD pathname' }
146              
147             sub cmd_rmd
148             {
149 9     9 0 40 my($self, $con, $req) = @_;
150              
151 9         43 my $dir = $req->args;
152 9         23 eval {
153 12     12   80076 use autodie;
  12         31  
  12         85  
154 9         34 local $CWD = $self->cwd;
155 9         502 rmdir $dir;
156 5         1311 $con->send_response(250 => "Directory removed");
157             };
158 9 100       5657 $con->send_response(550 => "RMD error") if $@;
159 9         45 $self->done;
160             }
161              
162              
163 1     1 0 4 sub help_dele { 'DELE pathname' }
164              
165             sub cmd_dele
166             {
167 10     10 0 56 my($self, $con, $req) = @_;
168              
169 10         36 my $file = $req->args;
170 10         24 eval {
171 12     12   81194 use autodie;
  12         46  
  12         76  
172 10         36 local $CWD = $self->cwd;
173 10         588 unlink $file;
174 5         1171 $con->send_response(250 => "File removed");
175             };
176 10 100       12630 $con->send_response(550 => "DELE error") if $@;
177 10         55 $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 54 my($self, $con, $req) = @_;
186              
187 10         48 my $path = $req->args;
188              
189 10 100       38 if($path)
190             {
191 8         17 eval {
192 8         36 local $CWD = $self->cwd;
193 8 100       625 if(!-e $path)
    50          
194             {
195 2         13 $con->send_response(550 => 'No such file or directory');
196             }
197             elsif(-w $path)
198             {
199 6         68 $self->rename_from($path);
200 6         48 $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       293 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         10 $con->send_response(501 => 'Invalid number of arguments');
216             }
217 10         54 $self->done;
218             }
219              
220              
221 1     1 0 5 sub help_rnto { 'RNTO pathname' }
222              
223             sub cmd_rnto
224             {
225 6     6 0 47 my($self, $con, $req) = @_;
226              
227 6         33 my $path = $req->args;
228              
229 6 50       25 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         13 eval {
240 6         18 local $CWD = $self->cwd;
241 6 50       422 if(! -e $path)
242             {
243 6         27 rename $self->rename_from, $path;
244 6         70 $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       201 if(my $error = $@)
252             {
253 0         0 warn $error;
254 0         0 $con->send_response(550 => 'Rename failed');
255             }
256             }
257 6         28 $self->done;
258             }
259              
260              
261 1     1 0 4 sub help_stat { 'STAT [ pathname]' }
262              
263             sub cmd_stat
264             {
265 9     9 0 39 my($self, $con, $req) = @_;
266              
267 9         27 my $path = $req->args;
268              
269 9 100       49 if($path)
270             {
271 6         25 do {
272 6         26 local $CWD = $self->cwd;
273 6 100       510 if(-d $path)
    100          
274             {
275 3         28 $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         13 $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         18 $con->send_response(211 => "it's all good.");
292             }
293 9         219 $self->done;
294             }
295              
296             1;
297              
298             __END__