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