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