XpressEngine Core  1.11.2
 All Classes Namespaces Files Functions Variables Pages
ftp.class.php
Go to the documentation of this file.
1 <?php
2  /*********************************************************************
3  *
4  * PHP FTP Client Class By TOMO ( groove@spencernetwork.org )
5  * Modified By NAVER ( developers@xpressengine.com )
6  *
7  * - Version 0.13 (2010/09/29)
8  *
9  * - This script is free but without any warranty.
10  * - You can freely copy, use, modify or redistribute this script
11  * for any purpose.
12  * - But please do not erase this information!!.
13  *
14  * Change log
15  * - Version 0.13 (2010/09/29)
16  * . use preg functions instead of ereg functions
17  * - Version 0.12 (2002/01/11)
18  *
19  ********************************************************************/
20 
21  /*********************************************************************
22  * List of available functions
23  * ftp_connect($server, $port = 21)
24  * ftp_login($user, $pass)
25  * ftp_pwd()
26  * ftp_size($pathname)
27  * ftp_mdtm($pathname)
28  * ftp_systype()
29  * ftp_cdup()
30  * ftp_chdir($pathname)
31  * ftp_delete($pathname)
32  * ftp_rmdir($pathname)
33  * ftp_mkdir($pathname)
34  * ftp_file_exists($pathname)
35  * ftp_rename($from, $to)
36  * ftp_nlist($arg = "", $pathname = "")
37  * ftp_rawlist($pathname = "")
38  * ftp_get($localfile, $remotefile, $mode = 1)
39  * ftp_put($remotefile, $localfile, $mode = 1)
40  * ftp_site($command)
41  * ftp_quit()
42  *********************************************************************/
43 
44  class ftp
45  {
46  /* Public variables */
47  var $debug;
48  var $umask;
49  var $timeout;
50 
51  /* Private variables */
52  var $ftp_sock;
53  var $ftp_resp;
54 
55  /* Constractor */
56  function ftp()
57  {
58  $this->debug = false;
59  $this->umask = 0022;
60  $this->timeout = 30;
61 
62  if (!defined("FTP_BINARY")) {
63  define("FTP_BINARY", 1);
64  }
65  if (!defined("FTP_ASCII")) {
66  define("FTP_ASCII", 0);
67  }
68 
69  $this->ftp_resp = "";
70  }
71 
72  /* Public functions */
73  function ftp_connect($server, $port = 21)
74  {
75  $this->ftp_debug("Trying to ".$server.":".$port." ...\n");
76  $this->ftp_sock = @fsockopen($server, $port, $errno, $errstr, $this->timeout);
77 
78  if (!$this->ftp_sock || !$this->ftp_ok()) {
79  $this->ftp_debug("Error : Cannot connect to remote host \"".$server.":".$port."\"\n");
80  $this->ftp_debug("Error : fsockopen() ".$errstr." (".$errno.")\n");
81  return FALSE;
82  }
83 
84  if(substr($this->ftp_resp, 0, 3) !== '220')
85  {
86  return FALSE;
87  }
88 
89  $this->ftp_debug("Connected to remote host \"".$server.":".$port."\"\n");
90 
91  return TRUE;
92  }
93 
94  function ftp_login($user, $pass)
95  {
96  $this->ftp_putcmd("USER", $user);
97  if (!$this->ftp_ok()) {
98  $this->ftp_debug("Error : USER command failed\n");
99  return FALSE;
100  }
101 
102  $this->ftp_putcmd("PASS", $pass);
103  if (!$this->ftp_ok()) {
104  $this->ftp_debug("Error : PASS command failed\n");
105  return FALSE;
106  }
107  $this->ftp_debug("Authentication succeeded\n");
108 
109  return TRUE;
110  }
111 
112  function ftp_pwd()
113  {
114  $this->ftp_putcmd("PWD");
115  if (!$this->ftp_ok()) {
116  $this->ftp_debug("Error : PWD command failed\n");
117  return FALSE;
118  }
119 
120  return preg_replace("@^[0-9]{3} \"(.+)\" .+\r\n@", "\\1", $this->ftp_resp);
121  }
122 
123  function ftp_size($pathname)
124  {
125  $this->ftp_putcmd("SIZE", $pathname);
126  if (!$this->ftp_ok()) {
127  $this->ftp_debug("Error : SIZE command failed\n");
128  return -1;
129  }
130 
131  return preg_replace("@^[0-9]{3} ([0-9]+)\r\n@", "\\1", $this->ftp_resp);
132  }
133 
134  function ftp_mdtm($pathname)
135  {
136  $this->ftp_putcmd("MDTM", $pathname);
137  if (!$this->ftp_ok()) {
138  $this->ftp_debug("Error : MDTM command failed\n");
139  return -1;
140  }
141  $mdtm = preg_replace("@^[0-9]{3} ([0-9]+)\r\n@", "\\1", $this->ftp_resp);
142  $date = sscanf($mdtm, "%4d%2d%2d%2d%2d%2d");
143  $timestamp = mktime($date[3], $date[4], $date[5], $date[1], $date[2], $date[0]);
144 
145  return $timestamp;
146  }
147 
148  function ftp_systype()
149  {
150  $this->ftp_putcmd("SYST");
151  if (!$this->ftp_ok()) {
152  $this->ftp_debug("Error : SYST command failed\n");
153  return FALSE;
154  }
155  $DATA = explode(" ", $this->ftp_resp);
156 
157  return $DATA[1];
158  }
159 
160  function ftp_cdup()
161  {
162  $this->ftp_putcmd("CDUP");
163  $response = $this->ftp_ok();
164  if (!$response) {
165  $this->ftp_debug("Error : CDUP command failed\n");
166  }
167  return $response;
168  }
169 
170  function ftp_chdir($pathname)
171  {
172  $this->ftp_putcmd("CWD", $pathname);
173  $response = $this->ftp_ok();
174  if (!$response) {
175  $this->ftp_debug("Error : CWD command failed\n");
176  }
177  return $response;
178  }
179 
180  function ftp_delete($pathname)
181  {
182  $this->ftp_putcmd("DELE", $pathname);
183  $response = $this->ftp_ok();
184  if (!$response) {
185  $this->ftp_debug("Error : DELE command failed\n");
186  }
187  return $response;
188  }
189 
190  function ftp_rmdir($pathname)
191  {
192  $this->ftp_putcmd("RMD", $pathname);
193  $response = $this->ftp_ok();
194  if (!$response) {
195  $this->ftp_debug("Error : RMD command failed\n");
196  }
197  return $response;
198  }
199 
200  function ftp_mkdir($pathname)
201  {
202  $this->ftp_putcmd("MKD", $pathname);
203  $response = $this->ftp_ok();
204  if (!$response) {
205  $this->ftp_debug("Error : MKD command failed\n");
206  }
207  return $response;
208  }
209 
210  function ftp_file_exists($pathname)
211  {
212  if (!($remote_list = $this->ftp_nlist("-a"))) {
213  $this->ftp_debug("Error : Cannot get remote file list\n");
214  return -1;
215  }
216 
217  reset($remote_list);
218  while (list(,$value) = each($remote_list)) {
219  if ($value == $pathname) {
220  $this->ftp_debug("Remote file ".$pathname." exists\n");
221  return 1;
222  }
223  }
224  $this->ftp_debug("Remote file ".$pathname." does not exist\n");
225 
226  return 0;
227  }
228 
229  function ftp_rename($from, $to)
230  {
231  $this->ftp_putcmd("RNFR", $from);
232  if (!$this->ftp_ok()) {
233  $this->ftp_debug("Error : RNFR command failed\n");
234  return FALSE;
235  }
236  $this->ftp_putcmd("RNTO", $to);
237 
238  $response = $this->ftp_ok();
239  if (!$response) {
240  $this->ftp_debug("Error : RNTO command failed\n");
241  }
242  return $response;
243  }
244 
245  function ftp_nlist($arg = "", $pathname = "")
246  {
247  if (!($string = $this->ftp_pasv())) {
248  return FALSE;
249  }
250 
251  if ($arg == "") {
252  $nlst = "NLST";
253  } else {
254  $nlst = "NLST ".$arg;
255  }
256  $this->ftp_putcmd($nlst, $pathname);
257 
258  $sock_data = $this->ftp_open_data_connection($string);
259  if (!$sock_data || !$this->ftp_ok()) {
260  $this->ftp_debug("Error : Cannot connect to remote host\n");
261  $this->ftp_debug("Error : NLST command failed\n");
262  return FALSE;
263  }
264  $this->ftp_debug("Connected to remote host\n");
265 
266  $list = array();
267  while (!feof($sock_data)) {
268  $list[] = preg_replace("@[\r\n]@", "", fgets($sock_data, 512));
269  }
270  $this->ftp_close_data_connection($sock_data);
271  $this->ftp_debug(implode("\n", $list));
272 
273  if (!$this->ftp_ok()) {
274  $this->ftp_debug("Error : NLST command failed\n");
275  return FALSE;
276  }
277 
278  return $list;
279  }
280 
281  function ftp_rawlist($pathname = "")
282  {
283  if (!($string = $this->ftp_pasv())) {
284  return FALSE;
285  }
286 
287  $this->ftp_putcmd("LIST", $pathname);
288 
289  $sock_data = $this->ftp_open_data_connection($string);
290  if (!$sock_data || !$this->ftp_ok()) {
291  $this->ftp_debug("Error : Cannot connect to remote host\n");
292  $this->ftp_debug("Error : LIST command failed\n");
293  return FALSE;
294  }
295 
296  $this->ftp_debug("Connected to remote host\n");
297 
298  while (!feof($sock_data)) {
299  $list[] = preg_replace("@[\r\n]@", "", fgets($sock_data, 512));
300  }
301  $this->ftp_debug(implode("\n", $list));
302  $this->ftp_close_data_connection($sock_data);
303 
304  if (!$this->ftp_ok()) {
305  $this->ftp_debug("Error : LIST command failed\n");
306  return FALSE;
307  }
308 
309  return $list;
310  }
311 
312  function ftp_get($localfile, $remotefile, $mode = 1)
313  {
314  umask($this->umask);
315 
316  if (@file_exists($localfile)) {
317  $this->ftp_debug("Warning : local file will be overwritten\n");
318  }
319 
320  $fp = @fopen($localfile, "w");
321  if (!$fp) {
322  $this->ftp_debug("Error : Cannot create \"".$localfile."\"");
323  $this->ftp_debug("Error : GET command failed\n");
324  return FALSE;
325  }
326 
327  if (!$this->ftp_type($mode)) {
328  $this->ftp_debug("Error : GET command failed\n");
329  return FALSE;
330  }
331 
332  if (!($string = $this->ftp_pasv())) {
333  $this->ftp_debug("Error : GET command failed\n");
334  return FALSE;
335  }
336 
337  $this->ftp_putcmd("RETR", $remotefile);
338 
339  $sock_data = $this->ftp_open_data_connection($string);
340  if (!$sock_data || !$this->ftp_ok()) {
341  $this->ftp_debug("Error : Cannot connect to remote host\n");
342  $this->ftp_debug("Error : GET command failed\n");
343  return FALSE;
344  }
345  $this->ftp_debug("Connected to remote host\n");
346  $this->ftp_debug("Retrieving remote file \"".$remotefile."\" to local file \"".$localfile."\"\n");
347  while (!feof($sock_data)) {
348  fputs($fp, fread($sock_data, 4096));
349  }
350  fclose($fp);
351 
352  $this->ftp_close_data_connection($sock_data);
353 
354  $response = $this->ftp_ok();
355  if (!$response) {
356  $this->ftp_debug("Error : GET command failed\n");
357  }
358  return $response;
359  }
360 
361  function ftp_put($remotefile, $localfile, $mode = 1)
362  {
363 
364  if (!@file_exists($localfile)) {
365  $this->ftp_debug("Error : No such file or directory \"".$localfile."\"\n");
366  $this->ftp_debug("Error : PUT command failed\n");
367  return FALSE;
368  }
369 
370  $fp = @fopen($localfile, "r");
371  if (!$fp) {
372  $this->ftp_debug("Error : Cannot read file \"".$localfile."\"\n");
373  $this->ftp_debug("Error : PUT command failed\n");
374  return FALSE;
375  }
376 
377  if (!$this->ftp_type($mode)) {
378  $this->ftp_debug("Error : PUT command failed\n");
379  return FALSE;
380  }
381 
382  if (!($string = $this->ftp_pasv())) {
383  $this->ftp_debug("Error : PUT command failed\n");
384  return FALSE;
385  }
386 
387  $this->ftp_putcmd("STOR", $remotefile);
388 
389  $sock_data = $this->ftp_open_data_connection($string);
390  if (!$sock_data || !$this->ftp_ok()) {
391  $this->ftp_debug("Error : Cannot connect to remote host\n");
392  $this->ftp_debug("Error : PUT command failed\n");
393  return FALSE;
394  }
395  $this->ftp_debug("Connected to remote host\n");
396  $this->ftp_debug("Storing local file \"".$localfile."\" to remote file \"".$remotefile."\"\n");
397  while (!feof($fp)) {
398  fputs($sock_data, fread($fp, 4096));
399  }
400  fclose($fp);
401 
402  $this->ftp_close_data_connection($sock_data);
403 
404  $response = $this->ftp_ok();
405  if (!$response) {
406  $this->ftp_debug("Error : PUT command failed\n");
407  }
408  return $response;
409  }
410 
411  function ftp_site($command)
412  {
413  $this->ftp_putcmd("SITE", $command);
414  $response = $this->ftp_ok();
415  if (!$response) {
416  $this->ftp_debug("Error : SITE command failed\n");
417  }
418  return $response;
419  }
420 
421  function ftp_quit()
422  {
423  $this->ftp_putcmd("QUIT");
424  if (!$this->ftp_ok() || !fclose($this->ftp_sock)) {
425  $this->ftp_debug("Error : QUIT command failed\n");
426  return FALSE;
427  }
428  $this->ftp_debug("Disconnected from remote host\n");
429  return TRUE;
430  }
431 
432  /* Private Functions */
433 
434  function ftp_type($mode)
435  {
436  if ($mode) {
437  $type = "I"; //Binary mode
438  } else {
439  $type = "A"; //ASCII mode
440  }
441  $this->ftp_putcmd("TYPE", $type);
442  $response = $this->ftp_ok();
443  if (!$response) {
444  $this->ftp_debug("Error : TYPE command failed\n");
445  }
446  return $response;
447  }
448 
449  function ftp_port($ip_port)
450  {
451  $this->ftp_putcmd("PORT", $ip_port);
452  $response = $this->ftp_ok();
453  if (!$response) {
454  $this->ftp_debug("Error : PORT command failed\n");
455  }
456  return $response;
457  }
458 
459  function ftp_pasv()
460  {
461  $this->ftp_putcmd("PASV");
462  if (!$this->ftp_ok()) {
463  $this->ftp_debug("Error : PASV command failed\n");
464  return FALSE;
465  }
466 
467  $ip_port = preg_replace("@^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*\r\n$@", "\\1", $this->ftp_resp);
468  return $ip_port;
469  }
470 
471  function ftp_putcmd($cmd, $arg = "")
472  {
473  if ($arg != "") {
474  $cmd = $cmd." ".$arg;
475  }
476 
477  fputs($this->ftp_sock, $cmd."\r\n");
478  $this->ftp_debug("> ".$cmd."\n");
479 
480  return TRUE;
481  }
482 
483  function ftp_ok()
484  {
485  $this->ftp_resp = "";
486 
487  // 한줄을 읽는다.
488  $line = '';
489  while(($char = fgetc($this->ftp_sock)) !== FALSE)
490  {
491  $line .= $char;
492  if($char === "\n") break;
493  }
494 
495  // 세자리 응답 코드가 나와야 한다.
496  if(!preg_match('@^[0-9]{3}@', $line))
497  {
498  return FALSE;
499  }
500 
501  $this->ftp_resp = $line;
502 
503  // 4번째 문자가 -이면 여러줄인 응답이다.
504  if($line[3] === '-')
505  {
506  $code = substr($line, 0, 3);
507 
508  // 한줄 단위로 읽어 나간다.
509  do
510  {
511  $line = '';
512  while(($char = fgetc($this->ftp_sock)) !== FALSE)
513  {
514  $line .= $char;
515  if($char === "\n") break;
516  }
517  $this->ftp_resp .= $line;
518 
519  // 응답 코드와 같은 코드가 나오고 공백이 있으면 끝
520  if($code . ' ' === substr($line, 0, 4)) break;
521  }while($line);
522  }
523 
524  $this->ftp_debug(str_replace("\r\n", "\n", $this->ftp_resp));
525 
526  if (!preg_match("@^[123]@", $this->ftp_resp)) {
527  return FALSE;
528  }
529 
530  return TRUE;
531  }
532 
534  {
535  $this->ftp_debug("Disconnected from remote host\n");
536  return fclose($sock);
537  }
538 
539  function ftp_open_data_connection($ip_port)
540  {
541  if (!preg_match("@[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+@", $ip_port)) {
542  $this->ftp_debug("Error : Illegal ip-port format(".$ip_port.")\n");
543  return FALSE;
544  }
545 
546  $DATA = explode(",", $ip_port);
547  $ipaddr = $DATA[0].".".$DATA[1].".".$DATA[2].".".$DATA[3];
548  $port = $DATA[4]*256 + $DATA[5];
549  $this->ftp_debug("Trying to ".$ipaddr.":".$port." ...\n");
550  $data_connection = @fsockopen($ipaddr, $port, $errno, $errstr);
551  if (!$data_connection) {
552  $this->ftp_debug("Error : Cannot open data connection to ".$ipaddr.":".$port."\n");
553  $this->ftp_debug("Error : ".$errstr." (".$errno.")\n");
554  return FALSE;
555  }
556 
557  return $data_connection;
558  }
559 
560  function ftp_debug($message = "")
561  {
562  if ($this->debug) {
563  echo $message;
564  }
565 
566  return TRUE;
567  }
568  }
569 ?>
ftp_rename($from, $to)
Definition: ftp.class.php:229
ftp_mdtm($pathname)
Definition: ftp.class.php:134
ftp_ok()
Definition: ftp.class.php:483
ftp_file_exists($pathname)
Definition: ftp.class.php:210
$ftp_sock
Definition: ftp.class.php:52
ftp_delete($pathname)
Definition: ftp.class.php:180
ftp_systype()
Definition: ftp.class.php:148
ftp_putcmd($cmd, $arg="")
Definition: ftp.class.php:471
ftp_connect($server, $port=21)
Definition: ftp.class.php:73
$ftp_resp
Definition: ftp.class.php:53
ftp_get($localfile, $remotefile, $mode=1)
Definition: ftp.class.php:312
ftp()
Definition: ftp.class.php:56
ftp_type($mode)
Definition: ftp.class.php:434
ftp_rmdir($pathname)
Definition: ftp.class.php:190
$umask
Definition: ftp.class.php:48
ftp_quit()
Definition: ftp.class.php:421
ftp_login($user, $pass)
Definition: ftp.class.php:94
ftp_cdup()
Definition: ftp.class.php:160
ftp_put($remotefile, $localfile, $mode=1)
Definition: ftp.class.php:361
ftp_nlist($arg="", $pathname="")
Definition: ftp.class.php:245
ftp_open_data_connection($ip_port)
Definition: ftp.class.php:539
ftp_rawlist($pathname="")
Definition: ftp.class.php:281
ftp_size($pathname)
Definition: ftp.class.php:123
ftp_mkdir($pathname)
Definition: ftp.class.php:200
ftp_pwd()
Definition: ftp.class.php:112
ftp_pasv()
Definition: ftp.class.php:459
ftp_chdir($pathname)
Definition: ftp.class.php:170
$debug
Definition: ftp.class.php:47
$timeout
Definition: ftp.class.php:49
ftp_port($ip_port)
Definition: ftp.class.php:449
ftp_site($command)
Definition: ftp.class.php:411
ftp_debug($message="")
Definition: ftp.class.php:560
ftp_close_data_connection($sock)
Definition: ftp.class.php:533