![]() |
Xataface 2.0
Xataface Application Framework
|
00001 <?php 00002 00003 define("FTP_TIMEOUT",90); 00004 00005 // FTP Statuscodes 00006 define("FTP_COMMAND_OK",200); 00007 define("FTP_FILE_ACTION_OK",250); 00008 define("FTP_FILE_TRANSFER_OK",226); 00009 define("FTP_COMMAND_NOT_IMPLEMENTED",502); 00010 define("FTP_FILE_STATUS",213); 00011 define("FTP_NAME_SYSTEM_TYPE",215); 00012 define("FTP_PASSIVE_MODE",227); 00013 define("FTP_PATHNAME",257); 00014 define("FTP_SERVICE_READY",220); 00015 define("FTP_USER_LOGGED_IN",230); 00016 define("FTP_PASSWORD_NEEDED",331); 00017 define("FTP_USER_NOT_LOGGED_IN",530); 00018 00019 if (!defined("FTP_ASCII")) define("FTP_ASCII",0); 00020 if (!defined("FTP_BINARY")) define("FTP_BINARY",1); 00021 00022 class FTP { 00023 00024 var $passiveMode = TRUE; 00025 var $lastLines = array(); 00026 var $lastLine = ""; 00027 var $controlSocket = NULL; 00028 var $newResult = FALSE; 00029 var $lastResult = -1; 00030 var $pasvAddr = NULL; 00031 00032 var $error_no = NULL; 00033 var $error_msg = NULL; 00034 00035 function FTP() { 00036 } 00037 00038 function connect($host, $port=21, $timeout=FTP_TIMEOUT) { //Opens an FTP connection 00039 $this->_resetError(); 00040 00041 $err_no = 0; 00042 $err_msg = ""; 00043 $this->controlSocket = @fsockopen($host, $port, $err_no, $err_msg, $timeout) or $this->_setError(-1,"fsockopen failed"); 00044 if ($err_no<>0) $this->setError($err_no,$err_msg); 00045 00046 if ($this->_isError()) return false; 00047 00048 @socket_set_timeout($this->controlSocket,$timeout) or $this->_setError(-1,"socket_set_timeout failed"); 00049 if ($this->_isError()) return false; 00050 00051 $this->_waitForResult(); 00052 if ($this->_isError()) return false; 00053 00054 return $this->getLastResult() == FTP_SERVICE_READY; 00055 } 00056 00057 function isConnected() { 00058 return $this->controlSocket != NULL; 00059 } 00060 00061 function disconnect() { 00062 if (!$this->isConnected()) return; 00063 @fclose($this->controlSocket); 00064 } 00065 00066 function close() { //Closes an FTP connection 00067 $this->disconnect(); 00068 } 00069 00070 function login($user, $pass) { //Logs in to an FTP connection 00071 $this->_resetError(); 00072 00073 $this->_printCommand("USER $user"); 00074 if ($this->_isError()) return false; 00075 00076 $this->_waitForResult(); 00077 if ($this->_isError()) return false; 00078 00079 if ($this->getLastResult() == FTP_PASSWORD_NEEDED){ 00080 $this->_printCommand("PASS $pass"); 00081 if ($this->_isError()) return FALSE; 00082 00083 $this->_waitForResult(); 00084 if ($this->_isError()) return FALSE; 00085 } 00086 00087 $result = $this->getLastResult() == FTP_USER_LOGGED_IN; 00088 return $result; 00089 } 00090 00091 function cdup() { //Changes to the parent directory 00092 $this->_resetError(); 00093 00094 $this->_printCommand("CDUP"); 00095 $this->_waitForResult(); 00096 $lr = $this->getLastResult(); 00097 if ($this->_isError()) return FALSE; 00098 return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK); 00099 } 00100 00101 function cwd($path) { 00102 $this->_resetError(); 00103 00104 $this->_printCommand("CWD $path"); 00105 $this->_waitForResult(); 00106 $lr = $this->getLastResult(); 00107 if ($this->_isError()) return FALSE; 00108 return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK); 00109 } 00110 00111 function cd($path) { 00112 return $this->cwd($path); 00113 } 00114 00115 function chdir($path) { //Changes directories on a FTP server 00116 return $this->cwd($path); 00117 } 00118 00119 function chmod($mode,$filename) { //Set permissions on a file via FTP 00120 return $this->site("CHMOD $mode $filename"); 00121 } 00122 00123 function delete($filename) { //Deletes a file on the FTP server 00124 $this->_resetError(); 00125 00126 $this->_printCommand("DELE $filename"); 00127 $this->_waitForResult(); 00128 $lr = $this->getLastResult(); 00129 if ($this->_isError()) return FALSE; 00130 return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK); 00131 } 00132 00133 function exec($cmd) { //Requests execution of a program on the FTP server 00134 return $this->site("EXEC $cmd"); 00135 } 00136 00137 function fget($fp,$remote,$mode=FTP_BINARY,$resumepos=0) { //Downloads a file from the FTP server and saves to an open file 00138 $this->_resetError(); 00139 00140 $type = "I"; 00141 if ($mode==FTP_ASCII) $type = "A"; 00142 00143 $this->_printCommand("TYPE $type"); 00144 $this->_waitForResult(); 00145 $lr = $this->getLastResult(); 00146 if ($this->_isError()) return FALSE; 00147 00148 $result = $this->_download("RETR $remote"); 00149 if ($result) { 00150 fwrite($fp,$result); 00151 } 00152 return $result; 00153 } 00154 00155 function fput($remote,$resource,$mode=FTP_BINARY,$startpos=0) { //Uploads from an open file to the FTP server 00156 $this->_resetError(); 00157 00158 $type = "I"; 00159 if ($mode==FTP_ASCII) $type = "A"; 00160 00161 $this->_printCommand("TYPE $type"); 00162 $this->_waitForResult(); 00163 $lr = $this->getLastResult(); 00164 if ($this->_isError()) return FALSE; 00165 00166 if ($startpos>0) fseek($resource,$startpos); 00167 $result = $this->_uploadResource("STOR $remote",$resource); 00168 return $result; 00169 } 00170 00171 function get_option($option) { //Retrieves various runtime behaviours of the current FTP stream 00172 $this->_resetError(); 00173 00174 switch ($option) { 00175 case "FTP_TIMEOUT_SEC" : return FTP_TIMEOUT; 00176 case "PHP_FTP_OPT_AUTOSEEK" : return FALSE; 00177 } 00178 setError(-1,"Unknown option: $option"); 00179 return false; 00180 } 00181 00182 function get($locale,$remote,$mode=FTP_BINARY,$resumepos=0) { //Downloads a file from the FTP server 00183 if (!($fp = @fopen($locale,"wb"))) return FALSE; 00184 $result = $this->fget($fp,$remote,$mode,$resumepos); 00185 @fclose($fp); 00186 if (!$result) @unlink($locale); 00187 return $result; 00188 } 00189 function mdtm($name) { //Returns the last modified time of the given file 00190 $this->_resetError(); 00191 00192 $this->_printCommand("MDTM $name"); 00193 $this->_waitForResult(); 00194 $lr = $this->getLastResult(); 00195 if ($this->_isError()) return FALSE; 00196 if ($lr!=FTP_FILE_STATUS) return FALSE; 00197 $subject = trim(substr($this->lastLine,4)); 00198 $lucifer = array(); 00199 if (preg_match("/([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])/",$subject,$lucifer)) return mktime($lucifer[4],$lucifer[5],$lucifer[6],$lucifer[2],$lucifer[3],$lucifer[1],0); 00200 return FALSE; 00201 } 00202 00203 function mkdir($name) { //Creates a directory 00204 $this->_resetError(); 00205 00206 $this->_printCommand("MKD $name"); 00207 $this->_waitForResult(); 00208 $lr = $this->getLastResult(); 00209 if ($this->_isError()) return FALSE; 00210 return ($lr==FTP_PATHNAME || $lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK); 00211 } 00212 00213 function nb_continue() { //Continues retrieving/sending a file (non-blocking) 00214 $this->_resetError(); 00215 // todo 00216 } 00217 00218 function nb_fget() { //Retrieves a file from the FTP server and writes it to an open file (non-blocking) 00219 $this->_resetError(); 00220 // todo 00221 } 00222 00223 function nb_fput() { //Stores a file from an open file to the FTP server (non-blocking) 00224 $this->_resetError(); 00225 // todo 00226 } 00227 00228 function nb_get() { //Retrieves a file from the FTP server and writes it to a local file (non-blocking) 00229 $this->_resetError(); 00230 // todo 00231 } 00232 00233 function nb_put() { //Stores a file on the FTP server (non-blocking) 00234 $this->_resetError(); 00235 // todo 00236 } 00237 00238 function nlist($remote_filespec="") { //Returns a list of files in the given directory 00239 $this->_resetError(); 00240 $result = $this->_download(trim("NLST $remote_filespec")); 00241 return ($result !== FALSE) ? explode("\n",str_replace("\r","",trim($result))) : $result; 00242 } 00243 00244 function pasv($pasv) { //Turns passive mode on or off 00245 if (!$pasv) { 00246 $this->_setError("Active (PORT) mode is not supported"); 00247 return false; 00248 } 00249 return true; 00250 } 00251 00252 function put($remote,$local,$mode=FTP_BINARY,$startpos=0) { //Uploads a file to the FTP server 00253 if (!($fp = @fopen($local,"rb"))) return FALSE; 00254 $result = $this->fput($remote,$fp,$mode,$startpos); 00255 @fclose($fp); 00256 return $result; 00257 } 00258 00259 function pwd() { //Returns the current directory name 00260 $this->_resetError(); 00261 00262 $this->_printCommand("PWD"); 00263 $this->_waitForResult(); 00264 $lr = $this->getLastResult(); 00265 if ($this->_isError()) return FALSE; 00266 if ($lr!=FTP_PATHNAME) return FALSE; 00267 $subject = trim(substr($this->lastLine,4)); 00268 $lucifer = array(); 00269 if (preg_match("/\"(.*)\"/",$subject,$lucifer)) return $lucifer[1]; 00270 return FALSE; 00271 } 00272 00273 function quit() { //Alias of close 00274 $this->close(); 00275 } 00276 00277 function raw($cmd) { //Sends an arbitrary command to an FTP server 00278 $this->_resetError(); 00279 00280 $this->_printCommand($cmd); 00281 $this->_waitForResult(); 00282 $this->getLastResult(); 00283 return array($this->lastLine); 00284 } 00285 00286 function rawlist($remote_filespec="") { //Returns a detailed list of files in the given directory 00287 $this->_resetError(); 00288 $result = $this->_download(trim("LIST $remote_filespec")); 00289 return ($result !== FALSE) ? explode("\n",str_replace("\r","",trim($result))) : $result; 00290 } 00291 00292 function ls($remote_filespec="") { //Returns a parsed rawlist in an assoc array 00293 $a = $this->rawlist($remote_filespec); 00294 if (!$a) return $a; 00295 $systype = $this->systype(); 00296 $is_windows = stristr($systype,"WIN")!==FALSE; 00297 $b = array(); 00298 while (list($i,$line) = each($a)) { 00299 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)) { 00300 $b[$i] = array(); 00301 if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix 00302 $b[$i]['isdir'] = ($lucifer[7]=="<DIR>"); 00303 $b[$i]['size'] = $lucifer[7]; 00304 $b[$i]['month'] = $lucifer[1]; 00305 $b[$i]['day'] = $lucifer[2]; 00306 $b[$i]['year'] = $lucifer[3]; 00307 $b[$i]['hour'] = $lucifer[4]; 00308 $b[$i]['minute'] = $lucifer[5]; 00309 $b[$i]['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]); 00310 $b[$i]['am/pm'] = $lucifer[6]; 00311 $b[$i]['name'] = $lucifer[8]; 00312 } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) { 00313 echo $line."\n"; 00314 $lcount=count($lucifer); 00315 if ($lcount<8) continue; 00316 $b[$i] = array(); 00317 $b[$i]['isdir'] = $lucifer[0]{0} === "d"; 00318 $b[$i]['islink'] = $lucifer[0]{0} === "l"; 00319 $b[$i]['perms'] = $lucifer[0]; 00320 $b[$i]['number'] = $lucifer[1]; 00321 $b[$i]['owner'] = $lucifer[2]; 00322 $b[$i]['group'] = $lucifer[3]; 00323 $b[$i]['size'] = $lucifer[4]; 00324 if ($lcount==8) { 00325 sscanf($lucifer[5],"%d-%d-%d",$b[$i]['year'],$b[$i]['month'],$b[$i]['day']); 00326 sscanf($lucifer[6],"%d:%d",$b[$i]['hour'],$b[$i]['minute']); 00327 $b[$i]['time'] = @mktime($b[$i]['hour'],$b[$i]['minute'],0,$b[$i]['month'],$b[$i]['day'],$b[$i]['year']); 00328 $b[$i]['name'] = $lucifer[7]; 00329 } else { 00330 $b[$i]['month'] = $lucifer[5]; 00331 $b[$i]['day'] = $lucifer[6]; 00332 if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) { 00333 $b[$i]['year'] = date("Y"); 00334 $b[$i]['hour'] = $l2[1]; 00335 $b[$i]['minute'] = $l2[2]; 00336 } else { 00337 $b[$i]['year'] = $lucifer[7]; 00338 $b[$i]['hour'] = 0; 00339 $b[$i]['minute'] = 0; 00340 } 00341 $b[$i]['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b[$i]['day'],$b[$i]['month'],$b[$i]['year'],$b[$i]['hour'],$b[$i]['minute'])); 00342 $b[$i]['name'] = $lucifer[8]; 00343 } 00344 } 00345 } 00346 return $b; 00347 } 00348 00349 function rename($from,$to) { //Renames a file on the FTP server 00350 $this->_resetError(); 00351 00352 $this->_printCommand("RNFR $from"); 00353 $this->_waitForResult(); 00354 $lr = $this->getLastResult(); 00355 if ($this->_isError()) return FALSE; 00356 $this->_printCommand("RNTO $to"); 00357 $this->_waitForResult(); 00358 $lr = $this->getLastResult(); 00359 if ($this->_isError()) return FALSE; 00360 return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK); 00361 } 00362 00363 function rmdir($name) { //Removes a directory 00364 $this->_resetError(); 00365 00366 $this->_printCommand("RMD $name"); 00367 $this->_waitForResult(); 00368 $lr = $this->getLastResult(); 00369 if ($this->_isError()) return FALSE; 00370 return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK); 00371 } 00372 00373 function set_option() { //Set miscellaneous runtime FTP options 00374 $this->_resetError(); 00375 $this->_setError(-1,"set_option not supported"); 00376 return false; 00377 } 00378 00379 function site($cmd) { //Sends a SITE command to the server 00380 $this->_resetError(); 00381 00382 $this->_printCommand("SITE $cmd"); 00383 $this->_waitForResult(); 00384 $lr = $this->getLastResult(); 00385 if ($this->_isError()) return FALSE; 00386 return true; 00387 } 00388 00389 function size($name) { //Returns the size of the given file 00390 $this->_resetError(); 00391 00392 $this->_printCommand("SIZE $name"); 00393 $this->_waitForResult(); 00394 $lr = $this->getLastResult(); 00395 if ($this->_isError()) return FALSE; 00396 return $lr==FTP_FILE_STATUS ? trim(substr($this->lastLine,4)) : FALSE; 00397 } 00398 00399 function ssl_connect() { //Opens an Secure SSL-FTP connection 00400 $this->_resetError(); 00401 $this->_setError(-1,"ssl_connect not supported"); 00402 return false; 00403 } 00404 00405 function systype() { // Returns the system type identifier of the remote FTP server 00406 $this->_resetError(); 00407 00408 $this->_printCommand("SYST"); 00409 $this->_waitForResult(); 00410 $lr = $this->getLastResult(); 00411 if ($this->_isError()) return FALSE; 00412 return $lr==FTP_NAME_SYSTEM_TYPE ? trim(substr($this->lastLine,4)) : FALSE; 00413 } 00414 00415 function getLastResult() { 00416 $this->newResult = FALSE; 00417 return $this->lastResult; 00418 } 00419 00420 /* private */ 00421 function _hasNewResult() { 00422 return $this->newResult; 00423 } 00424 00425 /* private */ 00426 function _waitForResult() { 00427 while(!$this->_hasNewResult() && $this->_readln()!==FALSE && !$this->_isError()) { /* noop */ } 00428 } 00429 00430 /* private */ 00431 function _readln() { 00432 $line = fgets($this->controlSocket); 00433 if ($line === FALSE) { 00434 $this->_setError(-1,"fgets failed in _readln"); 00435 return FALSE; 00436 } 00437 if (strlen($line)==0) return $line; 00438 00439 $lucifer = array(); 00440 if (preg_match("/^[0-9][0-9][0-9] /",$line,$lucifer)) { 00441 //its a resultline 00442 $this->lastResult = intval($lucifer[0]); 00443 $this->newResult = TRUE; 00444 if (substr($lucifer[0],0,1)=='5') { 00445 $this->_setError($this->lastResult,trim(substr($line,4))); 00446 } 00447 } 00448 00449 $this->lastLine = trim($line); 00450 $this->lastLines[] = "< ".trim($line); 00451 return $line; 00452 } 00453 00454 /* private */ 00455 function _printCommand($line) { 00456 $this->lastLines[] = "> ".$line; 00457 fwrite($this->controlSocket,$line."\r\n"); 00458 fflush($this->controlSocket); 00459 } 00460 00461 /* private */ 00462 function _pasv() { 00463 $this->_resetError(); 00464 $this->_printCommand("PASV"); 00465 $this->_waitForResult(); 00466 $lr = $this->getLastResult(); 00467 if ($this->_isError()) return FALSE; 00468 if ($lr!=FTP_PASSIVE_MODE) return FALSE; 00469 $subject = trim(substr($this->lastLine,4)); 00470 $lucifer = array(); 00471 if (preg_match("/\\((\d{1,3}),(\d{1,3}),(\d{1,3}),(\d{1,3}),(\d{1,3}),(\d{1,3})\\)/",$subject,$lucifer)) { 00472 $this->pasvAddr=$lucifer; 00473 00474 $host = sprintf("%d.%d.%d.%d",$lucifer[1],$lucifer[2],$lucifer[3],$lucifer[4]); 00475 $port = $lucifer[5]*256 + $lucifer[6]; 00476 00477 $err_no=0; 00478 $err_msg=""; 00479 $passiveConnection = fsockopen($host,$port,$err_no,$err_msg, FTP_TIMEOUT); 00480 if ($err_no!=0) { 00481 $this->_setError($err_no,$err_msg); 00482 return FALSE; 00483 } 00484 00485 return $passiveConnection; 00486 } 00487 return FALSE; 00488 } 00489 00490 /* private */ 00491 function _download($cmd) { 00492 if (!($passiveConnection = $this->_pasv())) return FALSE; 00493 $this->_printCommand($cmd); 00494 $this->_waitForResult(); 00495 $lr = $this->getLastResult(); 00496 if (!$this->_isError()) { 00497 $result = ""; 00498 while (!feof($passiveConnection)) { 00499 $result .= fgets($passiveConnection); 00500 } 00501 fclose($passiveConnection); 00502 $this->_waitForResult(); 00503 $lr = $this->getLastResult(); 00504 return ($lr==FTP_FILE_TRANSFER_OK) || ($lr==FTP_FILE_ACTION_OK) || ($lr==FTP_COMMAND_OK) ? $result : FALSE; 00505 } else { 00506 fclose($passiveConnection); 00507 return FALSE; 00508 } 00509 } 00510 00511 /* upload */ 00512 function _uploadResource($cmd,$resource) { 00513 if (!($passiveConnection = $this->_pasv())) return FALSE; 00514 $this->_printCommand($cmd); 00515 $this->_waitForResult(); 00516 $lr = $this->getLastResult(); 00517 if (!$this->_isError()) { 00518 $result = ""; 00519 while (!feof($resource)) { 00520 $buf = fread($resource,1024); 00521 fwrite($passiveConnection,$buf); 00522 } 00523 fclose($passiveConnection); 00524 $this->_waitForResult(); 00525 $lr = $this->getLastResult(); 00526 return ($lr==FTP_FILE_TRANSFER_OK) || ($lr==FTP_FILE_ACTION_OK) || ($lr==FTP_COMMAND_OK) ? $result : FALSE; 00527 } else { 00528 fclose($passiveConnection); 00529 return FALSE; 00530 } 00531 } 00532 00533 /* private */ 00534 function _resetError() { 00535 $this->error_no = NULL; 00536 $this->error_msg = NULL; 00537 } 00538 00539 /* private */ 00540 function _setError($no,$msg) { 00541 if (is_array($this->error_no)) { 00542 $this->error_no[] = $no; 00543 $this->error_msg[] = $msg; 00544 } else if ($this->error_no!=NULL) { 00545 $this->error_no = array($this->error_no,$no); 00546 $this->error_msg = array($this->error_msg,$msg); 00547 } else { 00548 $this->error_no = $no; 00549 $this->error_msg = $msg; 00550 } 00551 } 00552 00553 /* private */ 00554 function _isError() { 00555 return ($this->error_no != NULL) && ($this->error_no !== 0); 00556 } 00557 00558 } 00559 ?>