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   175750 use strict;
  12         55  
  12         313  
4 12     12   55 use warnings;
  12         17  
  12         290  
5 12     12   199 use 5.010;
  12         54  
6 12     12   423 use Moo;
  12         8530  
  12         62  
7 12     12   5031 use File::chdir;
  12         4585  
  12         1215  
8 12     12   75 use File::Spec;
  12         53  
  12         2039  
9              
10             extends 'AnyEvent::FTP::Server::Context';
11              
12             # ABSTRACT: FTP server context that uses real file system (no transfers)
13             our $VERSION = '0.19'; # 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 533 my($self, $value) = @_;
25 217 100       859 $self->{cwd} = $value if defined $value;
26 217   100     1351 $self->{cwd} //= '/';
27             }
28              
29              
30             sub rename_from
31             {
32 18     18 1 36 my($self, $value) = @_;
33 18 100       47 $self->{rename_from} = $value if defined $value;
34 18         231 $self->{rename_from};
35             }
36              
37              
38 1     1 0 3 sub help_cwd { 'CWD pathname' }
39              
40             sub cmd_cwd
41             {
42 36     36 0 75 my($self, $con, $req) = @_;
43              
44 36         80 my $dir = $req->args;
45              
46 36         74 eval {
47 36 100       97 die unless $dir;
48 12     12   777 use autodie;
  12         20783  
  12         63  
49 34         132 local $CWD = $self->cwd;
50 34         1699 $CWD = $dir;
51 33         578 $self->cwd($CWD);
52 33         120 $con->send_response(250 => 'CWD command successful');
53             };
54 36 100       1313 $con->send_response(550 => 'CWD error') if $@;
55              
56 36         126 $self->done;
57             }
58              
59              
60 1     1 0 3 sub help_cdup { 'CDUP' }
61              
62             sub cmd_cdup
63             {
64 5     5 0 26 my($self, $con, $req) = @_;
65              
66 5         16 eval {
67 12     12   69232 use autodie;
  12         30  
  12         61  
68 5         20 local $CWD = $self->cwd;
69 5         268 $CWD = File::Spec->updir;
70 5         87 $self->cwd($CWD);
71 5         30 $con->send_response(250 => 'CDUP command successful');
72             };
73 5 50       133 $con->send_response(550 => 'CDUP error') if $@;
74              
75 5         115 $self->done;
76             }
77              
78              
79 1     1 0 11 sub help_pwd { 'PWD' }
80              
81             sub cmd_pwd
82             {
83 9     9 0 33 my($self, $con, $req) = @_;
84              
85 9         27 my $cwd = $self->cwd;
86 9 50       96 if($^O eq 'MSWin32')
87             {
88 0         0 (undef,$cwd) = File::Spec->splitpath($cwd, 1);
89 0         0 $cwd =~ s{\\}{/}g;
90             }
91 9         64 $con->send_response(257 => "\"$cwd\" is the current directory");
92 9         30 $self->done;
93             }
94              
95              
96 1     1 0 3 sub help_size { 'SIZE pathname' }
97              
98             sub cmd_size
99             {
100 12     12 0 39 my($self, $con, $req) = @_;
101              
102 12         20 eval {
103 12     12   58568 use autodie;
  12         26  
  12         51  
104 12         34 local $CWD = $self->cwd;
105 12 100       563 if(-f $req->args)
    100          
106             {
107 8         110 my $size = -s $req->args;
108 8         47 $con->send_response(213 => $size);
109             }
110             elsif(-e $req->args)
111             {
112 2         8 $con->send_response(550 => $req->args . ": not a regular file");
113             }
114             else
115             {
116 2         16 die;
117             }
118             };
119 12 100       287 if($@)
120             {
121 2         6 $con->send_response(550 => $req->args . ": No such file or directory");
122             }
123 12         50 $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 21 my($self, $con, $req) = @_;
132              
133 7         20 my $dir = $req->args;
134 7         11 eval {
135 12     12   57407 use autodie;
  12         27  
  12         51  
136 7         19 local $CWD = $self->cwd;
137 7         267 mkdir $dir;
138 5         1455 $con->send_response(257 => "Directory created");
139             };
140 7 100       6672 $con->send_response(550 => "MKD error") if $@;
141 7         24 $self->done;
142             }
143              
144              
145 1     1 0 3 sub help_rmd { 'RMD pathname' }
146              
147             sub cmd_rmd
148             {
149 9     9 0 36 my($self, $con, $req) = @_;
150              
151 9         28 my $dir = $req->args;
152 9         15 eval {
153 12     12   56128 use autodie;
  12         25  
  12         59  
154 9         26 local $CWD = $self->cwd;
155 9         334 rmdir $dir;
156 5         949 $con->send_response(250 => "Directory removed");
157             };
158 9 100       4031 $con->send_response(550 => "RMD error") if $@;
159 9         37 $self->done;
160             }
161              
162              
163 1     1 0 3 sub help_dele { 'DELE pathname' }
164              
165             sub cmd_dele
166             {
167 10     10 0 32 my($self, $con, $req) = @_;
168              
169 10         28 my $file = $req->args;
170 10         19 eval {
171 12     12   59029 use autodie;
  12         25  
  12         61  
172 10         38 local $CWD = $self->cwd;
173 10         430 unlink $file;
174 5         824 $con->send_response(250 => "File removed");
175             };
176 10 100       8217 $con->send_response(550 => "DELE error") if $@;
177 10         37 $self->done;
178             }
179              
180              
181 1     1 0 4 sub help_rnfr { 'RNFR pathname' }
182              
183             sub cmd_rnfr
184             {
185 10     10 0 37 my($self, $con, $req) = @_;
186              
187 10         26 my $path = $req->args;
188              
189 10 100       26 if($path)
190             {
191 8         15 eval {
192 8         20 local $CWD = $self->cwd;
193 8 100       399 if(!-e $path)
    50          
194             {
195 2         10 $con->send_response(550 => 'No such file or directory');
196             }
197             elsif(-w $path)
198             {
199 6         41 $self->rename_from($path);
200 6         33 $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       183 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         7 $con->send_response(501 => 'Invalid number of arguments');
216             }
217 10         47 $self->done;
218             }
219              
220              
221 1     1 0 3 sub help_rnto { 'RNTO pathname' }
222              
223             sub cmd_rnto
224             {
225 6     6 0 23 my($self, $con, $req) = @_;
226              
227 6         20 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         10 eval {
240 6         14 local $CWD = $self->cwd;
241 6 50       311 if(! -e $path)
242             {
243 6         28 rename $self->rename_from, $path;
244 6         44 $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       131 if(my $error = $@)
252             {
253 0         0 warn $error;
254 0         0 $con->send_response(550 => 'Rename failed');
255             }
256             }
257 6         29 $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 23 my($self, $con, $req) = @_;
266              
267 9         17 my $path = $req->args;
268              
269 9 100       17 if($path)
270             {
271 6         8 do {
272 6         14 local $CWD = $self->cwd;
273 6 100       355 if(-d $path)
    100          
274             {
275 3         17 $con->send_response(211 => "it's a directory");
276             }
277             elsif(-f $path)
278             {
279 2         9 $con->send_response(211 => "it's a file");
280             }
281             else
282             {
283 1         10 $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         13 $con->send_response(211 => "it's all good.");
292             }
293 9         136 $self->done;
294             }
295              
296             1;
297              
298             __END__