Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ftp_base often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ftp_base, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
83 | class ftp_base { |
||
84 | /* Public variables */ |
||
85 | var $LocalEcho; |
||
86 | var $Verbose; |
||
87 | var $OS_local; |
||
88 | var $OS_remote; |
||
89 | |||
90 | /* Private variables */ |
||
91 | var $_lastaction; |
||
92 | var $_errors; |
||
93 | var $_type; |
||
94 | var $_umask; |
||
95 | var $_timeout; |
||
96 | var $_passive; |
||
97 | var $_host; |
||
98 | var $_fullhost; |
||
99 | var $_port; |
||
100 | var $_datahost; |
||
101 | var $_dataport; |
||
102 | var $_ftp_control_sock; |
||
103 | var $_ftp_data_sock; |
||
104 | var $_ftp_temp_sock; |
||
105 | var $_ftp_buff_size; |
||
106 | var $_login; |
||
107 | var $_password; |
||
108 | var $_connected; |
||
109 | var $_ready; |
||
110 | var $_code; |
||
111 | var $_message; |
||
112 | var $_can_restore; |
||
113 | var $_port_available; |
||
114 | var $_curtype; |
||
115 | var $_features; |
||
116 | |||
117 | var $_error_array; |
||
118 | var $AuthorizedTransferMode; |
||
119 | var $OS_FullName; |
||
120 | var $_eol_code; |
||
121 | var $AutoAsciiExt; |
||
122 | |||
123 | /* Constructor */ |
||
124 | function __construct($port_mode=FALSE, $verb=FALSE, $le=FALSE) { |
||
|
|||
125 | $this->LocalEcho=$le; |
||
126 | $this->Verbose=$verb; |
||
127 | $this->_lastaction=NULL; |
||
128 | $this->_error_array=array(); |
||
129 | $this->_eol_code=array(FTP_OS_Unix=>"\n", FTP_OS_Mac=>"\r", FTP_OS_Windows=>"\r\n"); |
||
130 | $this->AuthorizedTransferMode=array(FTP_AUTOASCII, FTP_ASCII, FTP_BINARY); |
||
131 | $this->OS_FullName=array(FTP_OS_Unix => 'UNIX', FTP_OS_Windows => 'WINDOWS', FTP_OS_Mac => 'MACOS'); |
||
132 | $this->AutoAsciiExt=array("ASP","BAT","C","CPP","CSS","CSV","JS","H","HTM","HTML","SHTML","INI","LOG","PHP3","PHTML","PL","PERL","SH","SQL","TXT"); |
||
133 | $this->_port_available=($port_mode==TRUE); |
||
134 | $this->SendMSG("Staring FTP client class".($this->_port_available?"":" without PORT mode support")); |
||
135 | $this->_connected=FALSE; |
||
136 | $this->_ready=FALSE; |
||
137 | $this->_can_restore=FALSE; |
||
138 | $this->_code=0; |
||
139 | $this->_message=""; |
||
140 | $this->_ftp_buff_size=4096; |
||
141 | $this->_curtype=NULL; |
||
142 | $this->SetUmask(0022); |
||
143 | $this->SetType(FTP_AUTOASCII); |
||
144 | $this->SetTimeout(30); |
||
145 | $this->Passive(!$this->_port_available); |
||
146 | $this->_login="anonymous"; |
||
147 | $this->_password="[email protected]"; |
||
148 | $this->_features=array(); |
||
149 | $this->OS_local=FTP_OS_Unix; |
||
150 | $this->OS_remote=FTP_OS_Unix; |
||
151 | $this->features=array(); |
||
152 | if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $this->OS_local=FTP_OS_Windows; |
||
153 | elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'MAC') $this->OS_local=FTP_OS_Mac; |
||
154 | } |
||
155 | |||
156 | function ftp_base($port_mode=FALSE) { |
||
159 | |||
160 | // <!-- --------------------------------------------------------------------------------------- --> |
||
161 | // <!-- Public functions --> |
||
162 | // <!-- --------------------------------------------------------------------------------------- --> |
||
163 | |||
164 | function parselisting($line) { |
||
165 | $is_windows = ($this->OS_remote == FTP_OS_Windows); |
||
166 | if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/",$line,$lucifer)) { |
||
167 | $b = array(); |
||
168 | View Code Duplication | if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix |
|
169 | $b['isdir'] = ($lucifer[7]=="<DIR>"); |
||
170 | if ( $b['isdir'] ) |
||
171 | $b['type'] = 'd'; |
||
172 | else |
||
173 | $b['type'] = 'f'; |
||
174 | $b['size'] = $lucifer[7]; |
||
175 | $b['month'] = $lucifer[1]; |
||
176 | $b['day'] = $lucifer[2]; |
||
177 | $b['year'] = $lucifer[3]; |
||
178 | $b['hour'] = $lucifer[4]; |
||
179 | $b['minute'] = $lucifer[5]; |
||
180 | $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]); |
||
181 | $b['am/pm'] = $lucifer[6]; |
||
182 | $b['name'] = $lucifer[8]; |
||
183 | } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) { |
||
184 | //echo $line."\n"; |
||
185 | $lcount=count($lucifer); |
||
186 | if ($lcount<8) return ''; |
||
187 | $b = array(); |
||
188 | $b['isdir'] = $lucifer[0]{0} === "d"; |
||
189 | $b['islink'] = $lucifer[0]{0} === "l"; |
||
190 | View Code Duplication | if ( $b['isdir'] ) |
|
191 | $b['type'] = 'd'; |
||
192 | elseif ( $b['islink'] ) |
||
193 | $b['type'] = 'l'; |
||
194 | else |
||
195 | $b['type'] = 'f'; |
||
196 | $b['perms'] = $lucifer[0]; |
||
197 | $b['number'] = $lucifer[1]; |
||
198 | $b['owner'] = $lucifer[2]; |
||
199 | $b['group'] = $lucifer[3]; |
||
200 | $b['size'] = $lucifer[4]; |
||
201 | View Code Duplication | if ($lcount==8) { |
|
202 | sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']); |
||
203 | sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']); |
||
204 | $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']); |
||
205 | $b['name'] = $lucifer[7]; |
||
206 | } else { |
||
207 | $b['month'] = $lucifer[5]; |
||
208 | $b['day'] = $lucifer[6]; |
||
209 | if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) { |
||
210 | $b['year'] = date("Y"); |
||
211 | $b['hour'] = $l2[1]; |
||
212 | $b['minute'] = $l2[2]; |
||
213 | } else { |
||
214 | $b['year'] = $lucifer[7]; |
||
215 | $b['hour'] = 0; |
||
216 | $b['minute'] = 0; |
||
217 | } |
||
218 | $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute'])); |
||
219 | $b['name'] = $lucifer[8]; |
||
220 | } |
||
221 | } |
||
222 | |||
223 | return $b; |
||
224 | } |
||
225 | |||
226 | function SendMSG($message = "", $crlf=true) { |
||
227 | if ($this->Verbose) { |
||
228 | echo $message.($crlf?CRLF:""); |
||
229 | flush(); |
||
230 | } |
||
231 | return TRUE; |
||
232 | } |
||
233 | |||
234 | function SetType($mode=FTP_AUTOASCII) { |
||
243 | |||
244 | function _settype($mode=FTP_ASCII) { |
||
245 | if($this->_ready) { |
||
246 | if($mode==FTP_BINARY) { |
||
247 | if($this->_curtype!=FTP_BINARY) { |
||
248 | if(!$this->_exec("TYPE I", "SetType")) return FALSE; |
||
249 | $this->_curtype=FTP_BINARY; |
||
250 | } |
||
251 | } elseif($this->_curtype!=FTP_ASCII) { |
||
252 | if(!$this->_exec("TYPE A", "SetType")) return FALSE; |
||
253 | $this->_curtype=FTP_ASCII; |
||
254 | } |
||
255 | } else return FALSE; |
||
256 | return TRUE; |
||
257 | } |
||
258 | |||
259 | function Passive($pasv=NULL) { |
||
260 | if(is_null($pasv)) $this->_passive=!$this->_passive; |
||
261 | else $this->_passive=$pasv; |
||
262 | if(!$this->_port_available and !$this->_passive) { |
||
263 | $this->SendMSG("Only passive connections available!"); |
||
264 | $this->_passive=TRUE; |
||
265 | return FALSE; |
||
266 | } |
||
267 | $this->SendMSG("Passive mode ".($this->_passive?"on":"off")); |
||
268 | return TRUE; |
||
269 | } |
||
270 | |||
271 | function SetServer($host, $port=21, $reconnect=true) { |
||
272 | if(!is_long($port)) { |
||
273 | $this->verbose=true; |
||
274 | $this->SendMSG("Incorrect port syntax"); |
||
275 | return FALSE; |
||
276 | } else { |
||
277 | $ip=@gethostbyname($host); |
||
278 | $dns=@gethostbyaddr($host); |
||
279 | if(!$ip) $ip=$host; |
||
280 | if(!$dns) $dns=$host; |
||
281 | // Validate the IPAddress PHP4 returns -1 for invalid, PHP5 false |
||
282 | // -1 === "255.255.255.255" which is the broadcast address which is also going to be invalid |
||
283 | $ipaslong = ip2long($ip); |
||
284 | if ( ($ipaslong == false) || ($ipaslong === -1) ) { |
||
285 | $this->SendMSG("Wrong host name/address \"".$host."\""); |
||
286 | return FALSE; |
||
287 | } |
||
288 | $this->_host=$ip; |
||
289 | $this->_fullhost=$dns; |
||
290 | $this->_port=$port; |
||
291 | $this->_dataport=$port-1; |
||
292 | } |
||
293 | $this->SendMSG("Host \"".$this->_fullhost."(".$this->_host."):".$this->_port."\""); |
||
294 | if($reconnect){ |
||
295 | if($this->_connected) { |
||
296 | $this->SendMSG("Reconnecting"); |
||
297 | if(!$this->quit(FTP_FORCE)) return FALSE; |
||
298 | if(!$this->connect()) return FALSE; |
||
299 | } |
||
300 | } |
||
301 | return TRUE; |
||
302 | } |
||
303 | |||
304 | function SetUmask($umask=0022) { |
||
305 | $this->_umask=$umask; |
||
306 | umask($this->_umask); |
||
307 | $this->SendMSG("UMASK 0".decoct($this->_umask)); |
||
308 | return TRUE; |
||
309 | } |
||
310 | |||
311 | function SetTimeout($timeout=30) { |
||
312 | $this->_timeout=$timeout; |
||
313 | $this->SendMSG("Timeout ".$this->_timeout); |
||
314 | if($this->_connected) |
||
315 | if(!$this->_settimeout($this->_ftp_control_sock)) return FALSE; |
||
316 | return TRUE; |
||
317 | } |
||
318 | |||
319 | function connect($server=NULL) { |
||
320 | if(!empty($server)) { |
||
321 | if(!$this->SetServer($server)) return false; |
||
322 | } |
||
323 | if($this->_ready) return true; |
||
324 | $this->SendMsg('Local OS : '.$this->OS_FullName[$this->OS_local]); |
||
325 | if(!($this->_ftp_control_sock = $this->_connect($this->_host, $this->_port))) { |
||
326 | $this->SendMSG("Error : Cannot connect to remote host \"".$this->_fullhost." :".$this->_port."\""); |
||
327 | return FALSE; |
||
328 | } |
||
329 | $this->SendMSG("Connected to remote host \"".$this->_fullhost.":".$this->_port."\". Waiting for greeting."); |
||
330 | do { |
||
331 | if(!$this->_readmsg()) return FALSE; |
||
332 | if(!$this->_checkCode()) return FALSE; |
||
333 | $this->_lastaction=time(); |
||
334 | } while($this->_code<200); |
||
335 | $this->_ready=true; |
||
336 | $syst=$this->systype(); |
||
337 | if(!$syst) $this->SendMSG("Can't detect remote OS"); |
||
338 | else { |
||
339 | if(preg_match("/win|dos|novell/i", $syst[0])) $this->OS_remote=FTP_OS_Windows; |
||
340 | elseif(preg_match("/os/i", $syst[0])) $this->OS_remote=FTP_OS_Mac; |
||
341 | elseif(preg_match("/(li|u)nix/i", $syst[0])) $this->OS_remote=FTP_OS_Unix; |
||
342 | else $this->OS_remote=FTP_OS_Mac; |
||
343 | $this->SendMSG("Remote OS: ".$this->OS_FullName[$this->OS_remote]); |
||
344 | } |
||
345 | View Code Duplication | if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled"); |
|
346 | else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features))); |
||
347 | return TRUE; |
||
348 | } |
||
349 | |||
350 | function quit($force=false) { |
||
351 | if($this->_ready) { |
||
352 | if(!$this->_exec("QUIT") and !$force) return FALSE; |
||
353 | if(!$this->_checkCode() and !$force) return FALSE; |
||
354 | $this->_ready=false; |
||
355 | $this->SendMSG("Session finished"); |
||
356 | } |
||
357 | $this->_quit(); |
||
358 | return TRUE; |
||
359 | } |
||
360 | |||
361 | function login($user=NULL, $pass=NULL) { |
||
362 | if(!is_null($user)) $this->_login=$user; |
||
363 | else $this->_login="anonymous"; |
||
364 | if(!is_null($pass)) $this->_password=$pass; |
||
365 | else $this->_password="[email protected]"; |
||
366 | if(!$this->_exec("USER ".$this->_login, "login")) return FALSE; |
||
367 | if(!$this->_checkCode()) return FALSE; |
||
368 | if($this->_code!=230) { |
||
369 | if(!$this->_exec((($this->_code==331)?"PASS ":"ACCT ").$this->_password, "login")) return FALSE; |
||
370 | if(!$this->_checkCode()) return FALSE; |
||
371 | } |
||
372 | $this->SendMSG("Authentication succeeded"); |
||
373 | View Code Duplication | if(empty($this->_features)) { |
|
374 | if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled"); |
||
375 | else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features))); |
||
376 | } |
||
377 | return TRUE; |
||
378 | } |
||
379 | |||
380 | function pwd() { |
||
381 | if(!$this->_exec("PWD", "pwd")) return FALSE; |
||
382 | if(!$this->_checkCode()) return FALSE; |
||
383 | return preg_replace("/^[0-9]{3} \"(.+)\".*$/s", "\\1", $this->_message); |
||
384 | } |
||
385 | |||
386 | function cdup() { |
||
387 | if(!$this->_exec("CDUP", "cdup")) return FALSE; |
||
388 | if(!$this->_checkCode()) return FALSE; |
||
389 | return true; |
||
390 | } |
||
391 | |||
392 | function chdir($pathname) { |
||
393 | if(!$this->_exec("CWD ".$pathname, "chdir")) return FALSE; |
||
394 | if(!$this->_checkCode()) return FALSE; |
||
395 | return TRUE; |
||
396 | } |
||
397 | |||
398 | function rmdir($pathname) { |
||
399 | if(!$this->_exec("RMD ".$pathname, "rmdir")) return FALSE; |
||
400 | if(!$this->_checkCode()) return FALSE; |
||
401 | return TRUE; |
||
402 | } |
||
403 | |||
404 | function mkdir($pathname) { |
||
405 | if(!$this->_exec("MKD ".$pathname, "mkdir")) return FALSE; |
||
406 | if(!$this->_checkCode()) return FALSE; |
||
407 | return TRUE; |
||
408 | } |
||
409 | |||
410 | function rename($from, $to) { |
||
411 | if(!$this->_exec("RNFR ".$from, "rename")) return FALSE; |
||
412 | if(!$this->_checkCode()) return FALSE; |
||
413 | if($this->_code==350) { |
||
414 | if(!$this->_exec("RNTO ".$to, "rename")) return FALSE; |
||
415 | if(!$this->_checkCode()) return FALSE; |
||
416 | } else return FALSE; |
||
417 | return TRUE; |
||
418 | } |
||
419 | |||
420 | function filesize($pathname) { |
||
429 | |||
430 | function abort() { |
||
431 | if(!$this->_exec("ABOR", "abort")) return FALSE; |
||
432 | if(!$this->_checkCode()) { |
||
433 | if($this->_code!=426) return FALSE; |
||
434 | if(!$this->_readmsg("abort")) return FALSE; |
||
435 | if(!$this->_checkCode()) return FALSE; |
||
436 | } |
||
437 | return true; |
||
438 | } |
||
439 | |||
440 | function mdtm($pathname) { |
||
452 | |||
453 | function systype() { |
||
454 | if(!$this->_exec("SYST", "systype")) return FALSE; |
||
455 | if(!$this->_checkCode()) return FALSE; |
||
456 | $DATA = explode(" ", $this->_message); |
||
457 | return array($DATA[1], $DATA[3]); |
||
458 | } |
||
459 | |||
460 | function delete($pathname) { |
||
461 | if(!$this->_exec("DELE ".$pathname, "delete")) return FALSE; |
||
462 | if(!$this->_checkCode()) return FALSE; |
||
463 | return TRUE; |
||
464 | } |
||
465 | |||
466 | function site($command, $fnction="site") { |
||
467 | if(!$this->_exec("SITE ".$command, $fnction)) return FALSE; |
||
468 | if(!$this->_checkCode()) return FALSE; |
||
469 | return TRUE; |
||
470 | } |
||
471 | |||
472 | function chmod($pathname, $mode) { |
||
476 | |||
477 | function restore($from) { |
||
478 | if(!isset($this->_features["REST"])) { |
||
479 | $this->PushError("restore", "not supported by server"); |
||
480 | return FALSE; |
||
481 | } |
||
482 | if($this->_curtype!=FTP_BINARY) { |
||
483 | $this->PushError("restore", "can't restore in ASCII mode"); |
||
484 | return FALSE; |
||
485 | } |
||
486 | if(!$this->_exec("REST ".$from, "resore")) return FALSE; |
||
487 | if(!$this->_checkCode()) return FALSE; |
||
488 | return TRUE; |
||
489 | } |
||
490 | |||
491 | function features() { |
||
502 | |||
503 | function rawlist($pathname="", $arg="") { |
||
506 | |||
507 | function nlist($pathname="", $arg="") { |
||
510 | |||
511 | function is_exists($pathname) { |
||
514 | |||
515 | function file_exists($pathname) { |
||
526 | |||
527 | View Code Duplication | function fget($fp, $remotefile,$rest=0) { |
|
528 | if($this->_can_restore and $rest!=0) fseek($fp, $rest); |
||
529 | $pi=pathinfo($remotefile); |
||
530 | if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; |
||
531 | else $mode=FTP_BINARY; |
||
532 | if(!$this->_data_prepare($mode)) { |
||
533 | return FALSE; |
||
534 | } |
||
535 | if($this->_can_restore and $rest!=0) $this->restore($rest); |
||
536 | if(!$this->_exec("RETR ".$remotefile, "get")) { |
||
537 | $this->_data_close(); |
||
538 | return FALSE; |
||
539 | } |
||
540 | if(!$this->_checkCode()) { |
||
541 | $this->_data_close(); |
||
542 | return FALSE; |
||
543 | } |
||
544 | $out=$this->_data_read($mode, $fp); |
||
545 | $this->_data_close(); |
||
546 | if(!$this->_readmsg()) return FALSE; |
||
547 | if(!$this->_checkCode()) return FALSE; |
||
548 | return $out; |
||
549 | } |
||
550 | |||
551 | function get($remotefile, $localfile=NULL, $rest=0) { |
||
552 | if(is_null($localfile)) $localfile=$remotefile; |
||
553 | if (@file_exists($localfile)) $this->SendMSG("Warning : local file will be overwritten"); |
||
554 | $fp = @fopen($localfile, "w"); |
||
555 | if (!$fp) { |
||
556 | $this->PushError("get","can't open local file", "Cannot create \"".$localfile."\""); |
||
557 | return FALSE; |
||
558 | } |
||
559 | if($this->_can_restore and $rest!=0) fseek($fp, $rest); |
||
560 | $pi=pathinfo($remotefile); |
||
561 | if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; |
||
562 | else $mode=FTP_BINARY; |
||
563 | if(!$this->_data_prepare($mode)) { |
||
564 | fclose($fp); |
||
565 | return FALSE; |
||
566 | } |
||
567 | if($this->_can_restore and $rest!=0) $this->restore($rest); |
||
568 | View Code Duplication | if(!$this->_exec("RETR ".$remotefile, "get")) { |
|
569 | $this->_data_close(); |
||
570 | fclose($fp); |
||
571 | return FALSE; |
||
572 | } |
||
573 | if(!$this->_checkCode()) { |
||
574 | $this->_data_close(); |
||
575 | fclose($fp); |
||
576 | return FALSE; |
||
577 | } |
||
578 | $out=$this->_data_read($mode, $fp); |
||
579 | fclose($fp); |
||
580 | $this->_data_close(); |
||
581 | if(!$this->_readmsg()) return FALSE; |
||
582 | if(!$this->_checkCode()) return FALSE; |
||
583 | return $out; |
||
584 | } |
||
585 | |||
586 | View Code Duplication | function fput($remotefile, $fp) { |
|
587 | if($this->_can_restore and $rest!=0) fseek($fp, $rest); |
||
588 | $pi=pathinfo($remotefile); |
||
589 | if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; |
||
590 | else $mode=FTP_BINARY; |
||
591 | if(!$this->_data_prepare($mode)) { |
||
592 | return FALSE; |
||
593 | } |
||
594 | if($this->_can_restore and $rest!=0) $this->restore($rest); |
||
595 | if(!$this->_exec("STOR ".$remotefile, "put")) { |
||
596 | $this->_data_close(); |
||
597 | return FALSE; |
||
598 | } |
||
599 | if(!$this->_checkCode()) { |
||
600 | $this->_data_close(); |
||
601 | return FALSE; |
||
602 | } |
||
603 | $ret=$this->_data_write($mode, $fp); |
||
604 | $this->_data_close(); |
||
605 | if(!$this->_readmsg()) return FALSE; |
||
606 | if(!$this->_checkCode()) return FALSE; |
||
607 | return $ret; |
||
608 | } |
||
609 | |||
610 | function put($localfile, $remotefile=NULL, $rest=0) { |
||
611 | if(is_null($remotefile)) $remotefile=$localfile; |
||
612 | if (!file_exists($localfile)) { |
||
613 | $this->PushError("put","can't open local file", "No such file or directory \"".$localfile."\""); |
||
614 | return FALSE; |
||
615 | } |
||
616 | $fp = @fopen($localfile, "r"); |
||
617 | |||
618 | if (!$fp) { |
||
619 | $this->PushError("put","can't open local file", "Cannot read file \"".$localfile."\""); |
||
620 | return FALSE; |
||
621 | } |
||
622 | if($this->_can_restore and $rest!=0) fseek($fp, $rest); |
||
623 | $pi=pathinfo($localfile); |
||
624 | if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII; |
||
625 | else $mode=FTP_BINARY; |
||
626 | if(!$this->_data_prepare($mode)) { |
||
627 | fclose($fp); |
||
628 | return FALSE; |
||
629 | } |
||
630 | if($this->_can_restore and $rest!=0) $this->restore($rest); |
||
631 | View Code Duplication | if(!$this->_exec("STOR ".$remotefile, "put")) { |
|
632 | $this->_data_close(); |
||
633 | fclose($fp); |
||
634 | return FALSE; |
||
635 | } |
||
636 | if(!$this->_checkCode()) { |
||
637 | $this->_data_close(); |
||
638 | fclose($fp); |
||
639 | return FALSE; |
||
640 | } |
||
641 | $ret=$this->_data_write($mode, $fp); |
||
642 | fclose($fp); |
||
643 | $this->_data_close(); |
||
644 | if(!$this->_readmsg()) return FALSE; |
||
645 | if(!$this->_checkCode()) return FALSE; |
||
646 | return $ret; |
||
647 | } |
||
648 | |||
649 | function mput($local=".", $remote=NULL, $continious=false) { |
||
650 | $local=realpath($local); |
||
651 | View Code Duplication | if(!@file_exists($local)) { |
|
652 | $this->PushError("mput","can't open local folder", "Cannot stat folder \"".$local."\""); |
||
653 | return FALSE; |
||
654 | } |
||
655 | if(!is_dir($local)) return $this->put($local, $remote); |
||
656 | if(empty($remote)) $remote="."; |
||
657 | elseif(!$this->file_exists($remote) and !$this->mkdir($remote)) return FALSE; |
||
658 | if($handle = opendir($local)) { |
||
659 | $list=array(); |
||
660 | while (false !== ($file = readdir($handle))) { |
||
661 | if ($file != "." && $file != "..") $list[]=$file; |
||
662 | } |
||
663 | closedir($handle); |
||
664 | } else { |
||
665 | $this->PushError("mput","can't open local folder", "Cannot read folder \"".$local."\""); |
||
666 | return FALSE; |
||
667 | } |
||
668 | if(empty($list)) return TRUE; |
||
669 | $ret=true; |
||
670 | foreach($list as $el) { |
||
671 | if(is_dir($local."/".$el)) $t=$this->mput($local."/".$el, $remote."/".$el); |
||
672 | else $t=$this->put($local."/".$el, $remote."/".$el); |
||
673 | if(!$t) { |
||
674 | $ret=FALSE; |
||
675 | if(!$continious) break; |
||
676 | } |
||
677 | } |
||
678 | return $ret; |
||
679 | |||
680 | } |
||
681 | |||
682 | function mget($remote, $local=".", $continious=false) { |
||
683 | $list=$this->rawlist($remote, "-lA"); |
||
684 | View Code Duplication | if($list===false) { |
|
685 | $this->PushError("mget","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); |
||
686 | return FALSE; |
||
687 | } |
||
688 | if(empty($list)) return true; |
||
689 | View Code Duplication | if(!@file_exists($local)) { |
|
690 | if(!@mkdir($local)) { |
||
691 | $this->PushError("mget","can't create local folder", "Cannot create folder \"".$local."\""); |
||
692 | return FALSE; |
||
693 | } |
||
694 | } |
||
695 | View Code Duplication | foreach($list as $k=>$v) { |
|
696 | $list[$k]=$this->parselisting($v); |
||
697 | if( ! $list[$k] or $list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]); |
||
698 | } |
||
699 | $ret=true; |
||
700 | foreach($list as $el) { |
||
701 | if($el["type"]=="d") { |
||
702 | View Code Duplication | if(!$this->mget($remote."/".$el["name"], $local."/".$el["name"], $continious)) { |
|
703 | $this->PushError("mget", "can't copy folder", "Can't copy remote folder \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\""); |
||
704 | $ret=false; |
||
705 | if(!$continious) break; |
||
706 | } |
||
707 | View Code Duplication | } else { |
|
708 | if(!$this->get($remote."/".$el["name"], $local."/".$el["name"])) { |
||
709 | $this->PushError("mget", "can't copy file", "Can't copy remote file \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\""); |
||
710 | $ret=false; |
||
711 | if(!$continious) break; |
||
712 | } |
||
713 | } |
||
714 | @chmod($local."/".$el["name"], $el["perms"]); |
||
715 | $t=strtotime($el["date"]); |
||
716 | if($t!==-1 and $t!==false) @touch($local."/".$el["name"], $t); |
||
717 | } |
||
718 | return $ret; |
||
719 | } |
||
720 | |||
721 | function mdel($remote, $continious=false) { |
||
722 | $list=$this->rawlist($remote, "-la"); |
||
723 | View Code Duplication | if($list===false) { |
|
724 | $this->PushError("mdel","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); |
||
725 | return false; |
||
726 | } |
||
727 | |||
728 | View Code Duplication | foreach($list as $k=>$v) { |
|
729 | $list[$k]=$this->parselisting($v); |
||
730 | if( ! $list[$k] or $list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]); |
||
731 | } |
||
732 | $ret=true; |
||
733 | |||
734 | foreach($list as $el) { |
||
735 | if ( empty($el) ) |
||
736 | continue; |
||
737 | |||
738 | if($el["type"]=="d") { |
||
739 | if(!$this->mdel($remote."/".$el["name"], $continious)) { |
||
740 | $ret=false; |
||
741 | if(!$continious) break; |
||
742 | } |
||
743 | } else { |
||
744 | if (!$this->delete($remote."/".$el["name"])) { |
||
745 | $this->PushError("mdel", "can't delete file", "Can't delete remote file \"".$remote."/".$el["name"]."\""); |
||
746 | $ret=false; |
||
747 | if(!$continious) break; |
||
748 | } |
||
749 | } |
||
750 | } |
||
751 | |||
752 | if(!$this->rmdir($remote)) { |
||
753 | $this->PushError("mdel", "can't delete folder", "Can't delete remote folder \"".$remote."/".$el["name"]."\""); |
||
754 | $ret=false; |
||
755 | } |
||
756 | return $ret; |
||
757 | } |
||
758 | |||
759 | function mmkdir($dir, $mode = 0777) { |
||
760 | if(empty($dir)) return FALSE; |
||
761 | if($this->is_exists($dir) or $dir == "/" ) return TRUE; |
||
762 | if(!$this->mmkdir(dirname($dir), $mode)) return false; |
||
763 | $r=$this->mkdir($dir, $mode); |
||
764 | $this->chmod($dir,$mode); |
||
765 | return $r; |
||
766 | } |
||
767 | |||
768 | function glob($pattern, $handle=NULL) { |
||
769 | $path=$output=null; |
||
770 | if(PHP_OS=='WIN32') $slash='\\'; |
||
771 | else $slash='/'; |
||
772 | $lastpos=strrpos($pattern,$slash); |
||
773 | if(!($lastpos===false)) { |
||
774 | $path=substr($pattern,0,-$lastpos-1); |
||
775 | $pattern=substr($pattern,$lastpos); |
||
776 | } else $path=getcwd(); |
||
777 | if(is_array($handle) and !empty($handle)) { |
||
778 | while($dir=each($handle)) { |
||
779 | if($this->glob_pattern_match($pattern,$dir)) |
||
780 | $output[]=$dir; |
||
781 | } |
||
782 | } else { |
||
783 | $handle=@opendir($path); |
||
784 | if($handle===false) return false; |
||
785 | while($dir=readdir($handle)) { |
||
786 | if($this->glob_pattern_match($pattern,$dir)) |
||
787 | $output[]=$dir; |
||
788 | } |
||
789 | closedir($handle); |
||
790 | } |
||
791 | if(is_array($output)) return $output; |
||
792 | return false; |
||
793 | } |
||
794 | |||
795 | function glob_pattern_match($pattern,$string) { |
||
796 | $out=null; |
||
797 | $chunks=explode(';',$pattern); |
||
798 | foreach($chunks as $pattern) { |
||
799 | $escape=array('$','^','.','{','}','(',')','[',']','|'); |
||
800 | while(strpos($pattern,'**')!==false) |
||
801 | $pattern=str_replace('**','*',$pattern); |
||
802 | foreach($escape as $probe) |
||
803 | $pattern=str_replace($probe,"\\$probe",$pattern); |
||
804 | $pattern=str_replace('?*','*', |
||
805 | str_replace('*?','*', |
||
806 | str_replace('*',".*", |
||
807 | str_replace('?','.{1,1}',$pattern)))); |
||
808 | $out[]=$pattern; |
||
809 | } |
||
810 | if(count($out)==1) return($this->glob_regexp("^$out[0]$",$string)); |
||
811 | else { |
||
812 | foreach($out as $tester) |
||
813 | if($this->my_regexp("^$tester$",$string)) return true; |
||
814 | } |
||
815 | return false; |
||
816 | } |
||
817 | |||
818 | function glob_regexp($pattern,$probe) { |
||
819 | $sensitive=(PHP_OS!='WIN32'); |
||
820 | return ($sensitive? |
||
821 | preg_match( '/' . preg_quote( $pattern, '/' ) . '/', $probe ) : |
||
822 | preg_match( '/' . preg_quote( $pattern, '/' ) . '/i', $probe ) |
||
823 | ); |
||
824 | } |
||
825 | |||
826 | function dirlist($remote) { |
||
827 | $list=$this->rawlist($remote, "-la"); |
||
828 | View Code Duplication | if($list===false) { |
|
829 | $this->PushError("dirlist","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents"); |
||
830 | return false; |
||
831 | } |
||
832 | |||
833 | $dirlist = array(); |
||
834 | foreach($list as $k=>$v) { |
||
835 | $entry=$this->parselisting($v); |
||
836 | if ( empty($entry) ) |
||
837 | continue; |
||
838 | |||
839 | if($entry["name"]=="." or $entry["name"]=="..") |
||
840 | continue; |
||
841 | |||
842 | $dirlist[$entry['name']] = $entry; |
||
843 | } |
||
844 | |||
845 | return $dirlist; |
||
846 | } |
||
847 | // <!-- --------------------------------------------------------------------------------------- --> |
||
848 | // <!-- Private functions --> |
||
849 | // <!-- --------------------------------------------------------------------------------------- --> |
||
850 | function _checkCode() { |
||
853 | |||
854 | function _list($arg="", $cmd="LIST", $fnction="_list") { |
||
855 | if(!$this->_data_prepare()) return false; |
||
856 | if(!$this->_exec($cmd.$arg, $fnction)) { |
||
857 | $this->_data_close(); |
||
858 | return FALSE; |
||
859 | } |
||
860 | if(!$this->_checkCode()) { |
||
861 | $this->_data_close(); |
||
862 | return FALSE; |
||
863 | } |
||
864 | $out=""; |
||
865 | if($this->_code<200) { |
||
866 | $out=$this->_data_read(); |
||
867 | $this->_data_close(); |
||
868 | if(!$this->_readmsg()) return FALSE; |
||
869 | if(!$this->_checkCode()) return FALSE; |
||
870 | if($out === FALSE ) return FALSE; |
||
871 | $out=preg_split("/[".CRLF."]+/", $out, -1, PREG_SPLIT_NO_EMPTY); |
||
872 | // $this->SendMSG(implode($this->_eol_code[$this->OS_local], $out)); |
||
873 | } |
||
874 | return $out; |
||
875 | } |
||
876 | |||
877 | // <!-- --------------------------------------------------------------------------------------- --> |
||
878 | // <!-- Partie : gestion des erreurs --> |
||
879 | // <!-- --------------------------------------------------------------------------------------- --> |
||
880 | // Gnre une erreur pour traitement externe la classe |
||
881 | function PushError($fctname,$msg,$desc=false){ |
||
882 | $error=array(); |
||
883 | $error['time']=time(); |
||
884 | $error['fctname']=$fctname; |
||
885 | $error['msg']=$msg; |
||
886 | $error['desc']=$desc; |
||
887 | if($desc) $tmp=' ('.$desc.')'; else $tmp=''; |
||
888 | $this->SendMSG($fctname.': '.$msg.$tmp); |
||
889 | return(array_push($this->_error_array,$error)); |
||
890 | } |
||
891 | |||
892 | // Rcupre une erreur externe |
||
893 | function PopError(){ |
||
897 | } |
||
898 | |||
899 | $mod_sockets = extension_loaded( 'sockets' ); |
||
900 | if ( ! $mod_sockets && function_exists( 'dl' ) && is_callable( 'dl' ) ) { |
||
901 | $prefix = ( PHP_SHLIB_SUFFIX == 'dll' ) ? 'php_' : ''; |
||
902 | @dl( $prefix . 'sockets.' . PHP_SHLIB_SUFFIX ); |
||
903 | $mod_sockets = extension_loaded( 'sockets' ); |
||
904 | } |
||
905 | |||
906 | require_once dirname( __FILE__ ) . "/class-ftp-" . ( $mod_sockets ? "sockets" : "pure" ) . ".php"; |
||
907 |
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.