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.