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   226125 use strict;
  12         28  
  12         513  
4 12     12   61 use warnings;
  12         25  
  12         723  
5 12     12   212 use 5.010;
  12         39  
6 12     12   484 use Moo;
  12         5654  
  12         95  
7 12     12   6776 use File::chdir;
  12         6082  
  12         1727  
8 12     12   127 use File::Spec;
  12         34  
  12         2972  
9              
10             extends 'AnyEvent::FTP::Server::Context';
11              
12             # ABSTRACT: FTP server context that uses real file system (no transfers)
13             our $VERSION = '0.20'; # 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 690 my($self, $value) = @_;
25 217 100       1215 $self->{cwd} = $value if defined $value;
26 217   100     2085 $self->{cwd} //= '/';
27             }
28              
29              
30             sub rename_from
31             {
32 18     18 1 48 my($self, $value) = @_;
33 18 100       63 $self->{rename_from} = $value if defined $value;
34 18         654 $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 101 my($self, $con, $req) = @_;
43              
44 36         164 my $dir = $req->args;
45              
46 36         84 eval {
47 36 100       123 die unless $dir;
48 12     12   1026 use autodie;
  12         32037  
  12         92  
49 34         181 local $CWD = $self->cwd;
50 34         2070 $CWD = $dir;
51 33         627 $self->cwd($CWD);
52 33         228 $con->send_response(250 => 'CWD command successful');
53             };
54 36 100       1482 $con->send_response(550 => 'CWD error') if $@;
55              
56 36         167 $self->done;
57             }
58              
59              
60 1     1 0 4 sub help_cdup { 'CDUP' }
61              
62             sub cmd_cdup
63             {
64 5     5 0 31 my($self, $con, $req) = @_;
65              
66 5         241 eval {
67 12     12   87828 use autodie;
  12         32  
  12         74  
68 5         39 local $CWD = $self->cwd;
69 5         364 $CWD = File::Spec->updir;
70 5         130 $self->cwd($CWD);
71 5         35 $con->send_response(250 => 'CDUP command successful');
72             };
73 5 50       158 $con->send_response(550 => 'CDUP error') if $@;
74              
75 5         32 $self->done;
76             }
77              
78              
79 1     1 0 5 sub help_pwd { 'PWD' }
80              
81             sub cmd_pwd
82             {
83 9     9 0 44 my($self, $con, $req) = @_;
84              
85 9         35 my $cwd = $self->cwd;
86 9 50       60 if($^O eq 'MSWin32')
87             {
88 0         0 (undef,$cwd) = File::Spec->splitpath($cwd, 1);
89 0         0 $cwd =~ s{\\}{/}g;
90             }
91 9         56 $con->send_response(257 => "\"$cwd\" is the current directory");
92 9         43 $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 37 my($self, $con, $req) = @_;
101              
102 12         32 eval {
103 12     12   82909 use autodie;
  12         52  
  12         163  
104 12         49 local $CWD = $self->cwd;
105 12 100       842 if(-f $req->args)
    100          
106             {
107 8         31 my $size = -s $req->args;
108 8         69 $con->send_response(213 => $size);
109             }
110             elsif(-e $req->args)
111             {
112 2         9 $con->send_response(550 => $req->args . ": not a regular file");
113             }
114             else
115             {
116 2         21 die;
117             }
118             };
119 12 100       372 if($@)
120             {
121 2         41 $con->send_response(550 => $req->args . ": No such file or directory");
122             }
123 12         74 $self->done;
124             }
125              
126              
127 1     1 0 4 sub help_mkd { 'MKD pathname' }
128              
129             sub cmd_mkd
130             {
131 7     7 0 26 my($self, $con, $req) = @_;
132              
133 7         26 my $dir = $req->args;
134 7         17 eval {
135 12     12   84873 use autodie;
  12         54  
  12         116  
136 7         27 local $CWD = $self->cwd;
137 7         465 mkdir $dir;
138 5         2081 $con->send_response(257 => "Directory created");
139             };
140 7 100       11682 $con->send_response(550 => "MKD error") if $@;
141 7         45 $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 42 my($self, $con, $req) = @_;
150              
151 9         50 my $dir = $req->args;
152 9         20 eval {
153 12     12   86023 use autodie;
  12         29  
  12         78  
154 9         51 local $CWD = $self->cwd;
155 9         524 rmdir $dir;
156 5         1581 $con->send_response(250 => "Directory removed");
157             };
158 9 100       8100 $con->send_response(550 => "RMD error") if $@;
159 9         55 $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 45 my($self, $con, $req) = @_;
168              
169 10         55 my $file = $req->args;
170 10         23 eval {
171 12     12   80439 use autodie;
  12         28  
  12         68  
172 10         42 local $CWD = $self->cwd;
173 10         650 unlink $file;
174 5         1852 $con->send_response(250 => "File removed");
175             };
176 10 100       19050 $con->send_response(550 => "DELE error") if $@;
177 10         69 $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 44 my($self, $con, $req) = @_;
186              
187 10         53 my $path = $req->args;
188              
189 10 100       30 if($path)
190             {
191 8         19 eval {
192 8         29 local $CWD = $self->cwd;
193 8 100       682 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         77 $self->rename_from($path);
200 6         40 $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       280 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         8 $con->send_response(501 => 'Invalid number of arguments');
216             }
217 10         61 $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 27 my($self, $con, $req) = @_;
226              
227 6         21 my $path = $req->args;
228              
229 6 50       23 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         12 eval {
240 6         19 local $CWD = $self->cwd;
241 6 50       521 if(! -e $path)
242             {
243 6         27 rename $self->rename_from, $path;
244 6         49 $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       202 if(my $error = $@)
252             {
253 0         0 warn $error;
254 0         0 $con->send_response(550 => 'Rename failed');
255             }
256             }
257 6         36 $self->done;
258             }
259              
260              
261 1     1 0 6 sub help_stat { 'STAT [ pathname]' }
262              
263             sub cmd_stat
264             {
265 9     9 0 28 my($self, $con, $req) = @_;
266              
267 9         27 my $path = $req->args;
268              
269 9 100       27 if($path)
270             {
271 6         13 do {
272 6         31 local $CWD = $self->cwd;
273 6 100       645 if(-d $path)
    100          
274             {
275 3         21 $con->send_response(211 => "it's a directory");
276             }
277             elsif(-f $path)
278             {
279 2         26 $con->send_response(211 => "it's a file");
280             }
281             else
282             {
283 1         17 $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         35 $con->send_response(211 => "it's all good.");
292             }
293 9         221 $self->done;
294             }
295              
296             1;
297              
298             __END__