Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 

247 wiersze
8.3 KiB

  1. <?php
  2. /**
  3. * PemFTP - A Ftp implementation in pure PHP
  4. *
  5. * @package PemFTP
  6. * @since 2.5.0
  7. *
  8. * @version 1.0
  9. * @copyright Alexey Dotsenko
  10. * @author Alexey Dotsenko
  11. * @link http://www.phpclasses.org/browse/package/1743.html Site
  12. * @license LGPL http://www.opensource.org/licenses/lgpl-license.html
  13. */
  14. /**
  15. * Socket Based FTP implementation
  16. *
  17. * @package PemFTP
  18. * @subpackage Socket
  19. * @since 2.5.0
  20. *
  21. * @version 1.0
  22. * @copyright Alexey Dotsenko
  23. * @author Alexey Dotsenko
  24. * @link http://www.phpclasses.org/browse/package/1743.html Site
  25. * @license LGPL http://www.opensource.org/licenses/lgpl-license.html
  26. */
  27. class ftp_sockets extends ftp_base {
  28. function __construct($verb=FALSE, $le=FALSE) {
  29. parent::__construct(true, $verb, $le);
  30. }
  31. // <!-- --------------------------------------------------------------------------------------- -->
  32. // <!-- Private functions -->
  33. // <!-- --------------------------------------------------------------------------------------- -->
  34. function _settimeout($sock) {
  35. if(!@socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
  36. $this->PushError('_connect','socket set receive timeout',socket_strerror(socket_last_error($sock)));
  37. @socket_close($sock);
  38. return FALSE;
  39. }
  40. if(!@socket_set_option($sock, SOL_SOCKET , SO_SNDTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
  41. $this->PushError('_connect','socket set send timeout',socket_strerror(socket_last_error($sock)));
  42. @socket_close($sock);
  43. return FALSE;
  44. }
  45. return true;
  46. }
  47. function _connect($host, $port) {
  48. $this->SendMSG("Creating socket");
  49. if(!($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
  50. $this->PushError('_connect','socket create failed',socket_strerror(socket_last_error($sock)));
  51. return FALSE;
  52. }
  53. if(!$this->_settimeout($sock)) return FALSE;
  54. $this->SendMSG("Connecting to \"".$host.":".$port."\"");
  55. if (!($res = @socket_connect($sock, $host, $port))) {
  56. $this->PushError('_connect','socket connect failed',socket_strerror(socket_last_error($sock)));
  57. @socket_close($sock);
  58. return FALSE;
  59. }
  60. $this->_connected=true;
  61. return $sock;
  62. }
  63. function _readmsg($fnction="_readmsg"){
  64. if(!$this->_connected) {
  65. $this->PushError($fnction,'Connect first');
  66. return FALSE;
  67. }
  68. $result=true;
  69. $this->_message="";
  70. $this->_code=0;
  71. $go=true;
  72. do {
  73. $tmp=@socket_read($this->_ftp_control_sock, 4096, PHP_BINARY_READ);
  74. if($tmp===false) {
  75. $go=$result=false;
  76. $this->PushError($fnction,'Read failed', socket_strerror(socket_last_error($this->_ftp_control_sock)));
  77. } else {
  78. $this->_message.=$tmp;
  79. $go = !preg_match("/^([0-9]{3})(-.+\\1)? [^".CRLF."]+".CRLF."$/Us", $this->_message, $regs);
  80. }
  81. } while($go);
  82. if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
  83. $this->_code=(int)$regs[1];
  84. return $result;
  85. }
  86. function _exec($cmd, $fnction="_exec") {
  87. if(!$this->_ready) {
  88. $this->PushError($fnction,'Connect first');
  89. return FALSE;
  90. }
  91. if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
  92. $status=@socket_write($this->_ftp_control_sock, $cmd.CRLF);
  93. if($status===false) {
  94. $this->PushError($fnction,'socket write failed', socket_strerror(socket_last_error($this->stream)));
  95. return FALSE;
  96. }
  97. $this->_lastaction=time();
  98. if(!$this->_readmsg($fnction)) return FALSE;
  99. return TRUE;
  100. }
  101. function _data_prepare($mode=FTP_ASCII) {
  102. if(!$this->_settype($mode)) return FALSE;
  103. $this->SendMSG("Creating data socket");
  104. $this->_ftp_data_sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  105. if ($this->_ftp_data_sock < 0) {
  106. $this->PushError('_data_prepare','socket create failed',socket_strerror(socket_last_error($this->_ftp_data_sock)));
  107. return FALSE;
  108. }
  109. if(!$this->_settimeout($this->_ftp_data_sock)) {
  110. $this->_data_close();
  111. return FALSE;
  112. }
  113. if($this->_passive) {
  114. if(!$this->_exec("PASV", "pasv")) {
  115. $this->_data_close();
  116. return FALSE;
  117. }
  118. if(!$this->_checkCode()) {
  119. $this->_data_close();
  120. return FALSE;
  121. }
  122. $ip_port = explode(",", preg_replace("/^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*$/s", "\\1", $this->_message));
  123. $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
  124. $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
  125. $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
  126. if(!@socket_connect($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
  127. $this->PushError("_data_prepare","socket_connect", socket_strerror(socket_last_error($this->_ftp_data_sock)));
  128. $this->_data_close();
  129. return FALSE;
  130. }
  131. else $this->_ftp_temp_sock=$this->_ftp_data_sock;
  132. } else {
  133. if(!@socket_getsockname($this->_ftp_control_sock, $addr, $port)) {
  134. $this->PushError("_data_prepare","can't get control socket information", socket_strerror(socket_last_error($this->_ftp_control_sock)));
  135. $this->_data_close();
  136. return FALSE;
  137. }
  138. if(!@socket_bind($this->_ftp_data_sock,$addr)){
  139. $this->PushError("_data_prepare","can't bind data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
  140. $this->_data_close();
  141. return FALSE;
  142. }
  143. if(!@socket_listen($this->_ftp_data_sock)) {
  144. $this->PushError("_data_prepare","can't listen data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
  145. $this->_data_close();
  146. return FALSE;
  147. }
  148. if(!@socket_getsockname($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
  149. $this->PushError("_data_prepare","can't get data socket information", socket_strerror(socket_last_error($this->_ftp_data_sock)));
  150. $this->_data_close();
  151. return FALSE;
  152. }
  153. if(!$this->_exec('PORT '.str_replace('.',',',$this->_datahost.'.'.($this->_dataport>>8).'.'.($this->_dataport&0x00FF)), "_port")) {
  154. $this->_data_close();
  155. return FALSE;
  156. }
  157. if(!$this->_checkCode()) {
  158. $this->_data_close();
  159. return FALSE;
  160. }
  161. }
  162. return TRUE;
  163. }
  164. function _data_read($mode=FTP_ASCII, $fp=NULL) {
  165. $NewLine=$this->_eol_code[$this->OS_local];
  166. if(is_resource($fp)) $out=0;
  167. else $out="";
  168. if(!$this->_passive) {
  169. $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
  170. $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
  171. if($this->_ftp_temp_sock===FALSE) {
  172. $this->PushError("_data_read","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
  173. $this->_data_close();
  174. return FALSE;
  175. }
  176. }
  177. while(($block=@socket_read($this->_ftp_temp_sock, $this->_ftp_buff_size, PHP_BINARY_READ))!==false) {
  178. if($block==="") break;
  179. if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
  180. if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
  181. else $out.=$block;
  182. }
  183. return $out;
  184. }
  185. function _data_write($mode=FTP_ASCII, $fp=NULL) {
  186. $NewLine=$this->_eol_code[$this->OS_local];
  187. if(is_resource($fp)) $out=0;
  188. else $out="";
  189. if(!$this->_passive) {
  190. $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
  191. $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
  192. if($this->_ftp_temp_sock===FALSE) {
  193. $this->PushError("_data_write","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
  194. $this->_data_close();
  195. return false;
  196. }
  197. }
  198. if(is_resource($fp)) {
  199. while(!feof($fp)) {
  200. $block=fread($fp, $this->_ftp_buff_size);
  201. if(!$this->_data_write_block($mode, $block)) return false;
  202. }
  203. } elseif(!$this->_data_write_block($mode, $fp)) return false;
  204. return true;
  205. }
  206. function _data_write_block($mode, $block) {
  207. if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
  208. do {
  209. if(($t=@socket_write($this->_ftp_temp_sock, $block))===FALSE) {
  210. $this->PushError("_data_write","socket_write", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
  211. $this->_data_close();
  212. return FALSE;
  213. }
  214. $block=substr($block, $t);
  215. } while(!empty($block));
  216. return true;
  217. }
  218. function _data_close() {
  219. @socket_close($this->_ftp_temp_sock);
  220. @socket_close($this->_ftp_data_sock);
  221. $this->SendMSG("Disconnected data from remote host");
  222. return TRUE;
  223. }
  224. function _quit() {
  225. if($this->_connected) {
  226. @socket_close($this->_ftp_control_sock);
  227. $this->_connected=false;
  228. $this->SendMSG("Socket closed");
  229. }
  230. }
  231. }
  232. ?>