~canonical-sysadmins/wordpress/4.7.2

« back to all changes in this revision

Viewing changes to wp-admin/includes/class-ftp.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 * Defines the newline characters, if not defined already.
 
17
 *
 
18
 * This can be redefined.
 
19
 *
 
20
 * @since 2.5
 
21
 * @var string
 
22
 */
 
23
if(!defined('CRLF')) define('CRLF',"\r\n");
 
24
 
 
25
/**
 
26
 * Sets whatever to autodetect ASCII mode.
 
27
 *
 
28
 * This can be redefined.
 
29
 *
 
30
 * @since 2.5
 
31
 * @var int
 
32
 */
 
33
if(!defined("FTP_AUTOASCII")) define("FTP_AUTOASCII", -1);
 
34
 
 
35
/**
 
36
 *
 
37
 * This can be redefined.
 
38
 * @since 2.5
 
39
 * @var int
 
40
 */
 
41
if(!defined("FTP_BINARY")) define("FTP_BINARY", 1);
 
42
 
 
43
/**
 
44
 *
 
45
 * This can be redefined.
 
46
 * @since 2.5
 
47
 * @var int
 
48
 */
 
49
if(!defined("FTP_ASCII")) define("FTP_ASCII", 0);
 
50
 
 
51
/**
 
52
 * Whether to force FTP.
 
53
 *
 
54
 * This can be redefined.
 
55
 *
 
56
 * @since 2.5
 
57
 * @var bool
 
58
 */
 
59
if(!defined('FTP_FORCE')) define('FTP_FORCE', true);
 
60
 
 
61
/**
 
62
 * @since 2.5
 
63
 * @var string
 
64
 */
 
65
define('FTP_OS_Unix','u');
 
66
 
 
67
/**
 
68
 * @since 2.5
 
69
 * @var string
 
70
 */
 
71
define('FTP_OS_Windows','w');
 
72
 
 
73
/**
 
74
 * @since 2.5
 
75
 * @var string
 
76
 */
 
77
define('FTP_OS_Mac','m');
 
78
 
 
79
/**
 
80
 * PemFTP base class
 
81
 *
 
82
 */
 
83
class ftp_base {
 
84
        /* Public variables */
 
85
        var $LocalEcho;
 
86
        var $Verbose;
 
87
        var $OS_local;
 
88
        var $OS_remote;
 
89
 
 
90
        /* Private variables */
 
91
        var $_lastaction;
 
92
        var $_errors;
 
93
        var $_type;
 
94
        var $_umask;
 
95
        var $_timeout;
 
96
        var $_passive;
 
97
        var $_host;
 
98
        var $_fullhost;
 
99
        var $_port;
 
100
        var $_datahost;
 
101
        var $_dataport;
 
102
        var $_ftp_control_sock;
 
103
        var $_ftp_data_sock;
 
104
        var $_ftp_temp_sock;
 
105
        var $_ftp_buff_size;
 
106
        var $_login;
 
107
        var $_password;
 
108
        var $_connected;
 
109
        var $_ready;
 
110
        var $_code;
 
111
        var $_message;
 
112
        var $_can_restore;
 
113
        var $_port_available;
 
114
        var $_curtype;
 
115
        var $_features;
 
116
 
 
117
        var $_error_array;
 
118
        var $AuthorizedTransferMode;
 
119
        var $OS_FullName;
 
120
        var $_eol_code;
 
121
        var $AutoAsciiExt;
 
122
 
 
123
        /* Constructor */
 
124
        function ftp_base($port_mode=FALSE) {
 
125
                $this->__construct($port_mode);
 
126
        }
 
127
 
 
128
        function __construct($port_mode=FALSE, $verb=FALSE, $le=FALSE) {
 
129
                $this->LocalEcho=$le;
 
130
                $this->Verbose=$verb;
 
131
                $this->_lastaction=NULL;
 
132
                $this->_error_array=array();
 
133
                $this->_eol_code=array(FTP_OS_Unix=>"\n", FTP_OS_Mac=>"\r", FTP_OS_Windows=>"\r\n");
 
134
                $this->AuthorizedTransferMode=array(FTP_AUTOASCII, FTP_ASCII, FTP_BINARY);
 
135
                $this->OS_FullName=array(FTP_OS_Unix => 'UNIX', FTP_OS_Windows => 'WINDOWS', FTP_OS_Mac => 'MACOS');
 
136
                $this->AutoAsciiExt=array("ASP","BAT","C","CPP","CSS","CSV","JS","H","HTM","HTML","SHTML","INI","LOG","PHP3","PHTML","PL","PERL","SH","SQL","TXT");
 
137
                $this->_port_available=($port_mode==TRUE);
 
138
                $this->SendMSG("Staring FTP client class".($this->_port_available?"":" without PORT mode support"));
 
139
                $this->_connected=FALSE;
 
140
                $this->_ready=FALSE;
 
141
                $this->_can_restore=FALSE;
 
142
                $this->_code=0;
 
143
                $this->_message="";
 
144
                $this->_ftp_buff_size=4096;
 
145
                $this->_curtype=NULL;
 
146
                $this->SetUmask(0022);
 
147
                $this->SetType(FTP_AUTOASCII);
 
148
                $this->SetTimeout(30);
 
149
                $this->Passive(!$this->_port_available);
 
150
                $this->_login="anonymous";
 
151
                $this->_password="anon@ftp.com";
 
152
                $this->_features=array();
 
153
            $this->OS_local=FTP_OS_Unix;
 
154
                $this->OS_remote=FTP_OS_Unix;
 
155
                $this->features=array();
 
156
                if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $this->OS_local=FTP_OS_Windows;
 
157
                elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'MAC') $this->OS_local=FTP_OS_Mac;
 
158
        }
 
159
 
 
160
// <!-- --------------------------------------------------------------------------------------- -->
 
161
// <!--       Public functions                                                                  -->
 
162
// <!-- --------------------------------------------------------------------------------------- -->
 
163
 
 
164
        function parselisting($line) {
 
165
                $is_windows = ($this->OS_remote == FTP_OS_Windows);
 
166
                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)) {
 
167
                        $b = array();
 
168
                        if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
 
169
                        $b['isdir'] = ($lucifer[7]=="<DIR>");
 
170
                        if ( $b['isdir'] )
 
171
                                $b['type'] = 'd';
 
172
                        else
 
173
                                $b['type'] = 'f';
 
174
                        $b['size'] = $lucifer[7];
 
175
                        $b['month'] = $lucifer[1];
 
176
                        $b['day'] = $lucifer[2];
 
177
                        $b['year'] = $lucifer[3];
 
178
                        $b['hour'] = $lucifer[4];
 
179
                        $b['minute'] = $lucifer[5];
 
180
                        $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]);
 
181
                        $b['am/pm'] = $lucifer[6];
 
182
                        $b['name'] = $lucifer[8];
 
183
                } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) {
 
184
                        //echo $line."\n";
 
185
                        $lcount=count($lucifer);
 
186
                        if ($lcount<8) return '';
 
187
                        $b = array();
 
188
                        $b['isdir'] = $lucifer[0]{0} === "d";
 
189
                        $b['islink'] = $lucifer[0]{0} === "l";
 
190
                        if ( $b['isdir'] )
 
191
                                $b['type'] = 'd';
 
192
                        elseif ( $b['islink'] )
 
193
                                $b['type'] = 'l';
 
194
                        else
 
195
                                $b['type'] = 'f';
 
196
                        $b['perms'] = $lucifer[0];
 
197
                        $b['number'] = $lucifer[1];
 
198
                        $b['owner'] = $lucifer[2];
 
199
                        $b['group'] = $lucifer[3];
 
200
                        $b['size'] = $lucifer[4];
 
201
                        if ($lcount==8) {
 
202
                                sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']);
 
203
                                sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']);
 
204
                                $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']);
 
205
                                $b['name'] = $lucifer[7];
 
206
                        } else {
 
207
                                $b['month'] = $lucifer[5];
 
208
                                $b['day'] = $lucifer[6];
 
209
                                if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) {
 
210
                                        $b['year'] = date("Y");
 
211
                                        $b['hour'] = $l2[1];
 
212
                                        $b['minute'] = $l2[2];
 
213
                                } else {
 
214
                                        $b['year'] = $lucifer[7];
 
215
                                        $b['hour'] = 0;
 
216
                                        $b['minute'] = 0;
 
217
                                }
 
218
                                $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute']));
 
219
                                $b['name'] = $lucifer[8];
 
220
                        }
 
221
                }
 
222
 
 
223
                return $b;
 
224
        }
 
225
 
 
226
        function SendMSG($message = "", $crlf=true) {
 
227
                if ($this->Verbose) {
 
228
                        echo $message.($crlf?CRLF:"");
 
229
                        flush();
 
230
                }
 
231
                return TRUE;
 
232
        }
 
233
 
 
234
        function SetType($mode=FTP_AUTOASCII) {
 
235
                if(!in_array($mode, $this->AuthorizedTransferMode)) {
 
236
                        $this->SendMSG("Wrong type");
 
237
                        return FALSE;
 
238
                }
 
239
                $this->_type=$mode;
 
240
                $this->SendMSG("Transfer type: ".($this->_type==FTP_BINARY?"binary":($this->_type==FTP_ASCII?"ASCII":"auto ASCII") ) );
 
241
                return TRUE;
 
242
        }
 
243
 
 
244
        function _settype($mode=FTP_ASCII) {
 
245
                if($this->_ready) {
 
246
                        if($mode==FTP_BINARY) {
 
247
                                if($this->_curtype!=FTP_BINARY) {
 
248
                                        if(!$this->_exec("TYPE I", "SetType")) return FALSE;
 
249
                                        $this->_curtype=FTP_BINARY;
 
250
                                }
 
251
                        } elseif($this->_curtype!=FTP_ASCII) {
 
252
                                if(!$this->_exec("TYPE A", "SetType")) return FALSE;
 
253
                                $this->_curtype=FTP_ASCII;
 
254
                        }
 
255
                } else return FALSE;
 
256
                return TRUE;
 
257
        }
 
258
 
 
259
        function Passive($pasv=NULL) {
 
260
                if(is_null($pasv)) $this->_passive=!$this->_passive;
 
261
                else $this->_passive=$pasv;
 
262
                if(!$this->_port_available and !$this->_passive) {
 
263
                        $this->SendMSG("Only passive connections available!");
 
264
                        $this->_passive=TRUE;
 
265
                        return FALSE;
 
266
                }
 
267
                $this->SendMSG("Passive mode ".($this->_passive?"on":"off"));
 
268
                return TRUE;
 
269
        }
 
270
 
 
271
        function SetServer($host, $port=21, $reconnect=true) {
 
272
                if(!is_long($port)) {
 
273
                $this->verbose=true;
 
274
            $this->SendMSG("Incorrect port syntax");
 
275
                        return FALSE;
 
276
                } else {
 
277
                        $ip=@gethostbyname($host);
 
278
                $dns=@gethostbyaddr($host);
 
279
                if(!$ip) $ip=$host;
 
280
                if(!$dns) $dns=$host;
 
281
                // Validate the IPAddress PHP4 returns -1 for invalid, PHP5 false
 
282
                // -1 === "255.255.255.255" which is the broadcast address which is also going to be invalid
 
283
                $ipaslong = ip2long($ip);
 
284
                        if ( ($ipaslong == false) || ($ipaslong === -1) ) {
 
285
                                $this->SendMSG("Wrong host name/address \"".$host."\"");
 
286
                                return FALSE;
 
287
                        }
 
288
                $this->_host=$ip;
 
289
                $this->_fullhost=$dns;
 
290
                $this->_port=$port;
 
291
                $this->_dataport=$port-1;
 
292
                }
 
293
                $this->SendMSG("Host \"".$this->_fullhost."(".$this->_host."):".$this->_port."\"");
 
294
                if($reconnect){
 
295
                        if($this->_connected) {
 
296
                                $this->SendMSG("Reconnecting");
 
297
                                if(!$this->quit(FTP_FORCE)) return FALSE;
 
298
                                if(!$this->connect()) return FALSE;
 
299
                        }
 
300
                }
 
301
                return TRUE;
 
302
        }
 
303
 
 
304
        function SetUmask($umask=0022) {
 
305
                $this->_umask=$umask;
 
306
                umask($this->_umask);
 
307
                $this->SendMSG("UMASK 0".decoct($this->_umask));
 
308
                return TRUE;
 
309
        }
 
310
 
 
311
        function SetTimeout($timeout=30) {
 
312
                $this->_timeout=$timeout;
 
313
                $this->SendMSG("Timeout ".$this->_timeout);
 
314
                if($this->_connected)
 
315
                        if(!$this->_settimeout($this->_ftp_control_sock)) return FALSE;
 
316
                return TRUE;
 
317
        }
 
318
 
 
319
        function connect($server=NULL) {
 
320
                if(!empty($server)) {
 
321
                        if(!$this->SetServer($server)) return false;
 
322
                }
 
323
                if($this->_ready) return true;
 
324
            $this->SendMsg('Local OS : '.$this->OS_FullName[$this->OS_local]);
 
325
                if(!($this->_ftp_control_sock = $this->_connect($this->_host, $this->_port))) {
 
326
                        $this->SendMSG("Error : Cannot connect to remote host \"".$this->_fullhost." :".$this->_port."\"");
 
327
                        return FALSE;
 
328
                }
 
329
                $this->SendMSG("Connected to remote host \"".$this->_fullhost.":".$this->_port."\". Waiting for greeting.");
 
330
                do {
 
331
                        if(!$this->_readmsg()) return FALSE;
 
332
                        if(!$this->_checkCode()) return FALSE;
 
333
                        $this->_lastaction=time();
 
334
                } while($this->_code<200);
 
335
                $this->_ready=true;
 
336
                $syst=$this->systype();
 
337
                if(!$syst) $this->SendMSG("Can't detect remote OS");
 
338
                else {
 
339
                        if(preg_match("/win|dos|novell/i", $syst[0])) $this->OS_remote=FTP_OS_Windows;
 
340
                        elseif(preg_match("/os/i", $syst[0])) $this->OS_remote=FTP_OS_Mac;
 
341
                        elseif(preg_match("/(li|u)nix/i", $syst[0])) $this->OS_remote=FTP_OS_Unix;
 
342
                        else $this->OS_remote=FTP_OS_Mac;
 
343
                        $this->SendMSG("Remote OS: ".$this->OS_FullName[$this->OS_remote]);
 
344
                }
 
345
                if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled");
 
346
                else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features)));
 
347
                return TRUE;
 
348
        }
 
349
 
 
350
        function quit($force=false) {
 
351
                if($this->_ready) {
 
352
                        if(!$this->_exec("QUIT") and !$force) return FALSE;
 
353
                        if(!$this->_checkCode() and !$force) return FALSE;
 
354
                        $this->_ready=false;
 
355
                        $this->SendMSG("Session finished");
 
356
                }
 
357
                $this->_quit();
 
358
                return TRUE;
 
359
        }
 
360
 
 
361
        function login($user=NULL, $pass=NULL) {
 
362
                if(!is_null($user)) $this->_login=$user;
 
363
                else $this->_login="anonymous";
 
364
                if(!is_null($pass)) $this->_password=$pass;
 
365
                else $this->_password="anon@anon.com";
 
366
                if(!$this->_exec("USER ".$this->_login, "login")) return FALSE;
 
367
                if(!$this->_checkCode()) return FALSE;
 
368
                if($this->_code!=230) {
 
369
                        if(!$this->_exec((($this->_code==331)?"PASS ":"ACCT ").$this->_password, "login")) return FALSE;
 
370
                        if(!$this->_checkCode()) return FALSE;
 
371
                }
 
372
                $this->SendMSG("Authentication succeeded");
 
373
                if(empty($this->_features)) {
 
374
                        if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled");
 
375
                        else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features)));
 
376
                }
 
377
                return TRUE;
 
378
        }
 
379
 
 
380
        function pwd() {
 
381
                if(!$this->_exec("PWD", "pwd")) return FALSE;
 
382
                if(!$this->_checkCode()) return FALSE;
 
383
                return ereg_replace("^[0-9]{3} \"(.+)\".+", "\\1", $this->_message);
 
384
        }
 
385
 
 
386
        function cdup() {
 
387
                if(!$this->_exec("CDUP", "cdup")) return FALSE;
 
388
                if(!$this->_checkCode()) return FALSE;
 
389
                return true;
 
390
        }
 
391
 
 
392
        function chdir($pathname) {
 
393
                if(!$this->_exec("CWD ".$pathname, "chdir")) return FALSE;
 
394
                if(!$this->_checkCode()) return FALSE;
 
395
                return TRUE;
 
396
        }
 
397
 
 
398
        function rmdir($pathname) {
 
399
                if(!$this->_exec("RMD ".$pathname, "rmdir")) return FALSE;
 
400
                if(!$this->_checkCode()) return FALSE;
 
401
                return TRUE;
 
402
        }
 
403
 
 
404
        function mkdir($pathname) {
 
405
                if(!$this->_exec("MKD ".$pathname, "mkdir")) return FALSE;
 
406
                if(!$this->_checkCode()) return FALSE;
 
407
                return TRUE;
 
408
        }
 
409
 
 
410
        function rename($from, $to) {
 
411
                if(!$this->_exec("RNFR ".$from, "rename")) return FALSE;
 
412
                if(!$this->_checkCode()) return FALSE;
 
413
                if($this->_code==350) {
 
414
                        if(!$this->_exec("RNTO ".$to, "rename")) return FALSE;
 
415
                        if(!$this->_checkCode()) return FALSE;
 
416
                } else return FALSE;
 
417
                return TRUE;
 
418
        }
 
419
 
 
420
        function filesize($pathname) {
 
421
                if(!isset($this->_features["SIZE"])) {
 
422
                        $this->PushError("filesize", "not supported by server");
 
423
                        return FALSE;
 
424
                }
 
425
                if(!$this->_exec("SIZE ".$pathname, "filesize")) return FALSE;
 
426
                if(!$this->_checkCode()) return FALSE;
 
427
                return ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message);
 
428
        }
 
429
 
 
430
        function abort() {
 
431
                if(!$this->_exec("ABOR", "abort")) return FALSE;
 
432
                if(!$this->_checkCode()) {
 
433
                        if($this->_code!=426) return FALSE;
 
434
                        if(!$this->_readmsg("abort")) return FALSE;
 
435
                        if(!$this->_checkCode()) return FALSE;
 
436
                }
 
437
                return true;
 
438
        }
 
439
 
 
440
        function mdtm($pathname) {
 
441
                if(!isset($this->_features["MDTM"])) {
 
442
                        $this->PushError("mdtm", "not supported by server");
 
443
                        return FALSE;
 
444
                }
 
445
                if(!$this->_exec("MDTM ".$pathname, "mdtm")) return FALSE;
 
446
                if(!$this->_checkCode()) return FALSE;
 
447
                $mdtm = ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message);
 
448
                $date = sscanf($mdtm, "%4d%2d%2d%2d%2d%2d");
 
449
                $timestamp = mktime($date[3], $date[4], $date[5], $date[1], $date[2], $date[0]);
 
450
                return $timestamp;
 
451
        }
 
452
 
 
453
        function systype() {
 
454
                if(!$this->_exec("SYST", "systype")) return FALSE;
 
455
                if(!$this->_checkCode()) return FALSE;
 
456
                $DATA = explode(" ", $this->_message);
 
457
                return array($DATA[1], $DATA[3]);
 
458
        }
 
459
 
 
460
        function delete($pathname) {
 
461
                if(!$this->_exec("DELE ".$pathname, "delete")) return FALSE;
 
462
                if(!$this->_checkCode()) return FALSE;
 
463
                return TRUE;
 
464
        }
 
465
 
 
466
        function site($command, $fnction="site") {
 
467
                if(!$this->_exec("SITE ".$command, $fnction)) return FALSE;
 
468
                if(!$this->_checkCode()) return FALSE;
 
469
                return TRUE;
 
470
        }
 
471
 
 
472
        function chmod($pathname, $mode) {
 
473
                if(!$this->site( sprintf('CHMOD %o %s', $mode, $pathname), "chmod")) return FALSE;
 
474
                return TRUE;
 
475
        }
 
476
 
 
477
        function restore($from) {
 
478
                if(!isset($this->_features["REST"])) {
 
479
                        $this->PushError("restore", "not supported by server");
 
480
                        return FALSE;
 
481
                }
 
482
                if($this->_curtype!=FTP_BINARY) {
 
483
                        $this->PushError("restore", "can't restore in ASCII mode");
 
484
                        return FALSE;
 
485
                }
 
486
                if(!$this->_exec("REST ".$from, "resore")) return FALSE;
 
487
                if(!$this->_checkCode()) return FALSE;
 
488
                return TRUE;
 
489
        }
 
490
 
 
491
        function features() {
 
492
                if(!$this->_exec("FEAT", "features")) return FALSE;
 
493
                if(!$this->_checkCode()) return FALSE;
 
494
                $f=preg_split("/[".CRLF."]+/", preg_replace("/[0-9]{3}[ -].*[".CRLF."]+/", "", $this->_message), -1, PREG_SPLIT_NO_EMPTY);
 
495
                $this->_features=array();
 
496
                foreach($f as $k=>$v) {
 
497
                        $v=explode(" ", trim($v));
 
498
                        $this->_features[array_shift($v)]=$v;
 
499
                }
 
500
                return true;
 
501
        }
 
502
 
 
503
        function rawlist($pathname="", $arg="") {
 
504
                return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "LIST", "rawlist");
 
505
        }
 
506
 
 
507
        function nlist($pathname="") {
 
508
                return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "NLST", "nlist");
 
509
        }
 
510
 
 
511
        function is_exists($pathname) {
 
512
                return $this->file_exists($pathname);
 
513
        }
 
514
 
 
515
        function file_exists($pathname) {
 
516
                $exists=true;
 
517
                if(!$this->_exec("RNFR ".$pathname, "rename")) $exists=FALSE;
 
518
                else {
 
519
                        if(!$this->_checkCode()) $exists=FALSE;
 
520
                        $this->abort();
 
521
                }
 
522
                if($exists) $this->SendMSG("Remote file ".$pathname." exists");
 
523
                else $this->SendMSG("Remote file ".$pathname." does not exist");
 
524
                return $exists;
 
525
        }
 
526
 
 
527
        function fget($fp, $remotefile,$rest=0) {
 
528
                if($this->_can_restore and $rest!=0) fseek($fp, $rest);
 
529
                $pi=pathinfo($remotefile);
 
530
                if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
 
531
                else $mode=FTP_BINARY;
 
532
                if(!$this->_data_prepare($mode)) {
 
533
                        return FALSE;
 
534
                }
 
535
                if($this->_can_restore and $rest!=0) $this->restore($rest);
 
536
                if(!$this->_exec("RETR ".$remotefile, "get")) {
 
537
                        $this->_data_close();
 
538
                        return FALSE;
 
539
                }
 
540
                if(!$this->_checkCode()) {
 
541
                        $this->_data_close();
 
542
                        return FALSE;
 
543
                }
 
544
                $out=$this->_data_read($mode, $fp);
 
545
                $this->_data_close();
 
546
                if(!$this->_readmsg()) return FALSE;
 
547
                if(!$this->_checkCode()) return FALSE;
 
548
                return $out;
 
549
        }
 
550
 
 
551
        function get($remotefile, $localfile=NULL, $rest=0) {
 
552
                if(is_null($localfile)) $localfile=$remotefile;
 
553
                if (@file_exists($localfile)) $this->SendMSG("Warning : local file will be overwritten");
 
554
                $fp = @fopen($localfile, "w");
 
555
                if (!$fp) {
 
556
                        $this->PushError("get","can't open local file", "Cannot create \"".$localfile."\"");
 
557
                        return FALSE;
 
558
                }
 
559
                if($this->_can_restore and $rest!=0) fseek($fp, $rest);
 
560
                $pi=pathinfo($remotefile);
 
561
                if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
 
562
                else $mode=FTP_BINARY;
 
563
                if(!$this->_data_prepare($mode)) {
 
564
                        fclose($fp);
 
565
                        return FALSE;
 
566
                }
 
567
                if($this->_can_restore and $rest!=0) $this->restore($rest);
 
568
                if(!$this->_exec("RETR ".$remotefile, "get")) {
 
569
                        $this->_data_close();
 
570
                        fclose($fp);
 
571
                        return FALSE;
 
572
                }
 
573
                if(!$this->_checkCode()) {
 
574
                        $this->_data_close();
 
575
                        fclose($fp);
 
576
                        return FALSE;
 
577
                }
 
578
                $out=$this->_data_read($mode, $fp);
 
579
                fclose($fp);
 
580
                $this->_data_close();
 
581
                if(!$this->_readmsg()) return FALSE;
 
582
                if(!$this->_checkCode()) return FALSE;
 
583
                return $out;
 
584
        }
 
585
 
 
586
        function fput($remotefile, $fp) {
 
587
                if($this->_can_restore and $rest!=0) fseek($fp, $rest);
 
588
                $pi=pathinfo($remotefile);
 
589
                if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
 
590
                else $mode=FTP_BINARY;
 
591
                if(!$this->_data_prepare($mode)) {
 
592
                        return FALSE;
 
593
                }
 
594
                if($this->_can_restore and $rest!=0) $this->restore($rest);
 
595
                if(!$this->_exec("STOR ".$remotefile, "put")) {
 
596
                        $this->_data_close();
 
597
                        return FALSE;
 
598
                }
 
599
                if(!$this->_checkCode()) {
 
600
                        $this->_data_close();
 
601
                        return FALSE;
 
602
                }
 
603
                $ret=$this->_data_write($mode, $fp);
 
604
                $this->_data_close();
 
605
                if(!$this->_readmsg()) return FALSE;
 
606
                if(!$this->_checkCode()) return FALSE;
 
607
                return $ret;
 
608
        }
 
609
 
 
610
        function put($localfile, $remotefile=NULL, $rest=0) {
 
611
                if(is_null($remotefile)) $remotefile=$localfile;
 
612
                if (!file_exists($localfile)) {
 
613
                        $this->PushError("put","can't open local file", "No such file or directory \"".$localfile."\"");
 
614
                        return FALSE;
 
615
                }
 
616
                $fp = @fopen($localfile, "r");
 
617
 
 
618
                if (!$fp) {
 
619
                        $this->PushError("put","can't open local file", "Cannot read file \"".$localfile."\"");
 
620
                        return FALSE;
 
621
                }
 
622
                if($this->_can_restore and $rest!=0) fseek($fp, $rest);
 
623
                $pi=pathinfo($localfile);
 
624
                if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
 
625
                else $mode=FTP_BINARY;
 
626
                if(!$this->_data_prepare($mode)) {
 
627
                        fclose($fp);
 
628
                        return FALSE;
 
629
                }
 
630
                if($this->_can_restore and $rest!=0) $this->restore($rest);
 
631
                if(!$this->_exec("STOR ".$remotefile, "put")) {
 
632
                        $this->_data_close();
 
633
                        fclose($fp);
 
634
                        return FALSE;
 
635
                }
 
636
                if(!$this->_checkCode()) {
 
637
                        $this->_data_close();
 
638
                        fclose($fp);
 
639
                        return FALSE;
 
640
                }
 
641
                $ret=$this->_data_write($mode, $fp);
 
642
                fclose($fp);
 
643
                $this->_data_close();
 
644
                if(!$this->_readmsg()) return FALSE;
 
645
                if(!$this->_checkCode()) return FALSE;
 
646
                return $ret;
 
647
        }
 
648
 
 
649
        function mput($local=".", $remote=NULL, $continious=false) {
 
650
                $local=realpath($local);
 
651
                if(!@file_exists($local)) {
 
652
                        $this->PushError("mput","can't open local folder", "Cannot stat folder \"".$local."\"");
 
653
                        return FALSE;
 
654
                }
 
655
                if(!is_dir($local)) return $this->put($local, $remote);
 
656
                if(empty($remote)) $remote=".";
 
657
                elseif(!$this->file_exists($remote) and !$this->mkdir($remote)) return FALSE;
 
658
                if($handle = opendir($local)) {
 
659
                        $list=array();
 
660
                        while (false !== ($file = readdir($handle))) {
 
661
                                if ($file != "." && $file != "..") $list[]=$file;
 
662
                        }
 
663
                        closedir($handle);
 
664
                } else {
 
665
                        $this->PushError("mput","can't open local folder", "Cannot read folder \"".$local."\"");
 
666
                        return FALSE;
 
667
                }
 
668
                if(empty($list)) return TRUE;
 
669
                $ret=true;
 
670
                foreach($list as $el) {
 
671
                        if(is_dir($local."/".$el)) $t=$this->mput($local."/".$el, $remote."/".$el);
 
672
                        else $t=$this->put($local."/".$el, $remote."/".$el);
 
673
                        if(!$t) {
 
674
                                $ret=FALSE;
 
675
                                if(!$continious) break;
 
676
                        }
 
677
                }
 
678
                return $ret;
 
679
 
 
680
        }
 
681
 
 
682
        function mget($remote, $local=".", $continious=false) {
 
683
                $list=$this->rawlist($remote, "-lA");
 
684
                if($list===false) {
 
685
                        $this->PushError("mget","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
 
686
                        return FALSE;
 
687
                }
 
688
                if(empty($list)) return true;
 
689
                if(!@file_exists($local)) {
 
690
                        if(!@mkdir($local)) {
 
691
                                $this->PushError("mget","can't create local folder", "Cannot create folder \"".$local."\"");
 
692
                                return FALSE;
 
693
                        }
 
694
                }
 
695
                foreach($list as $k=>$v) {
 
696
                        $list[$k]=$this->parselisting($v);
 
697
                        if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
 
698
                }
 
699
                $ret=true;
 
700
                foreach($list as $el) {
 
701
                        if($el["type"]=="d") {
 
702
                                if(!$this->mget($remote."/".$el["name"], $local."/".$el["name"], $continious)) {
 
703
                                        $this->PushError("mget", "can't copy folder", "Can't copy remote folder \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
 
704
                                        $ret=false;
 
705
                                        if(!$continious) break;
 
706
                                }
 
707
                        } else {
 
708
                                if(!$this->get($remote."/".$el["name"], $local."/".$el["name"])) {
 
709
                                        $this->PushError("mget", "can't copy file", "Can't copy remote file \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
 
710
                                        $ret=false;
 
711
                                        if(!$continious) break;
 
712
                                }
 
713
                        }
 
714
                        @chmod($local."/".$el["name"], $el["perms"]);
 
715
                        $t=strtotime($el["date"]);
 
716
                        if($t!==-1 and $t!==false) @touch($local."/".$el["name"], $t);
 
717
                }
 
718
                return $ret;
 
719
        }
 
720
 
 
721
        function mdel($remote, $continious=false) {
 
722
                $list=$this->rawlist($remote, "-la");
 
723
                if($list===false) {
 
724
                        $this->PushError("mdel","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
 
725
                        return false;
 
726
                }
 
727
 
 
728
                foreach($list as $k=>$v) {
 
729
                        $list[$k]=$this->parselisting($v);
 
730
                        if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
 
731
                }
 
732
                $ret=true;
 
733
 
 
734
                foreach($list as $el) {
 
735
                        if ( empty($el) )
 
736
                                continue;
 
737
 
 
738
                        if($el["type"]=="d") {
 
739
                                if(!$this->mdel($remote."/".$el["name"], $continious)) {
 
740
                                        $ret=false;
 
741
                                        if(!$continious) break;
 
742
                                }
 
743
                        } else {
 
744
                                if (!$this->delete($remote."/".$el["name"])) {
 
745
                                        $this->PushError("mdel", "can't delete file", "Can't delete remote file \"".$remote."/".$el["name"]."\"");
 
746
                                        $ret=false;
 
747
                                        if(!$continious) break;
 
748
                                }
 
749
                        }
 
750
                }
 
751
 
 
752
                if(!$this->rmdir($remote)) {
 
753
                        $this->PushError("mdel", "can't delete folder", "Can't delete remote folder \"".$remote."/".$el["name"]."\"");
 
754
                        $ret=false;
 
755
                }
 
756
                return $ret;
 
757
        }
 
758
 
 
759
        function mmkdir($dir, $mode = 0777) {
 
760
                if(empty($dir)) return FALSE;
 
761
                if($this->is_exists($dir) or $dir == "/" ) return TRUE;
 
762
                if(!$this->mmkdir(dirname($dir), $mode)) return false;
 
763
                $r=$this->mkdir($dir, $mode);
 
764
                $this->chmod($dir,$mode);
 
765
                return $r;
 
766
        }
 
767
 
 
768
        function glob($pattern, $handle=NULL) {
 
769
                $path=$output=null;
 
770
                if(PHP_OS=='WIN32') $slash='\\';
 
771
                else $slash='/';
 
772
                $lastpos=strrpos($pattern,$slash);
 
773
                if(!($lastpos===false)) {
 
774
                        $path=substr($pattern,0,-$lastpos-1);
 
775
                        $pattern=substr($pattern,$lastpos);
 
776
                } else $path=getcwd();
 
777
                if(is_array($handle) and !empty($handle)) {
 
778
                        while($dir=each($handle)) {
 
779
                                if($this->glob_pattern_match($pattern,$dir))
 
780
                                $output[]=$dir;
 
781
                        }
 
782
                } else {
 
783
                        $handle=@opendir($path);
 
784
                        if($handle===false) return false;
 
785
                        while($dir=readdir($handle)) {
 
786
                                if($this->glob_pattern_match($pattern,$dir))
 
787
                                $output[]=$dir;
 
788
                        }
 
789
                        closedir($handle);
 
790
                }
 
791
                if(is_array($output)) return $output;
 
792
                return false;
 
793
        }
 
794
 
 
795
        function glob_pattern_match($pattern,$string) {
 
796
                $out=null;
 
797
                $chunks=explode(';',$pattern);
 
798
                foreach($chunks as $pattern) {
 
799
                        $escape=array('$','^','.','{','}','(',')','[',']','|');
 
800
                        while(strpos($pattern,'**')!==false)
 
801
                                $pattern=str_replace('**','*',$pattern);
 
802
                        foreach($escape as $probe)
 
803
                                $pattern=str_replace($probe,"\\$probe",$pattern);
 
804
                        $pattern=str_replace('?*','*',
 
805
                                str_replace('*?','*',
 
806
                                        str_replace('*',".*",
 
807
                                                str_replace('?','.{1,1}',$pattern))));
 
808
                        $out[]=$pattern;
 
809
                }
 
810
                if(count($out)==1) return($this->glob_regexp("^$out[0]$",$string));
 
811
                else {
 
812
                        foreach($out as $tester)
 
813
                                if($this->my_regexp("^$tester$",$string)) return true;
 
814
                }
 
815
                return false;
 
816
        }
 
817
 
 
818
        function glob_regexp($pattern,$probe) {
 
819
                $sensitive=(PHP_OS!='WIN32');
 
820
                return ($sensitive?
 
821
                        ereg($pattern,$probe):
 
822
                        eregi($pattern,$probe)
 
823
                );
 
824
        }
 
825
 
 
826
        function dirlist($remote) {
 
827
                $list=$this->rawlist($remote, "-la");
 
828
                if($list===false) {
 
829
                        $this->PushError("dirlist","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
 
830
                        return false;
 
831
                }
 
832
 
 
833
                $dirlist = array();
 
834
                foreach($list as $k=>$v) {
 
835
                        $entry=$this->parselisting($v);
 
836
                        if ( empty($entry) )
 
837
                                continue;
 
838
 
 
839
                        if($entry["name"]=="." or $entry["name"]=="..")
 
840
                                continue;
 
841
 
 
842
                        $dirlist[$entry['name']] = $entry;
 
843
                }
 
844
 
 
845
                return $dirlist;
 
846
        }
 
847
// <!-- --------------------------------------------------------------------------------------- -->
 
848
// <!--       Private functions                                                                 -->
 
849
// <!-- --------------------------------------------------------------------------------------- -->
 
850
        function _checkCode() {
 
851
                return ($this->_code<400 and $this->_code>0);
 
852
        }
 
853
 
 
854
        function _list($arg="", $cmd="LIST", $fnction="_list") {
 
855
                if(!$this->_data_prepare()) return false;
 
856
                if(!$this->_exec($cmd.$arg, $fnction)) {
 
857
                        $this->_data_close();
 
858
                        return FALSE;
 
859
                }
 
860
                if(!$this->_checkCode()) {
 
861
                        $this->_data_close();
 
862
                        return FALSE;
 
863
                }
 
864
                $out="";
 
865
                if($this->_code<200) {
 
866
                        $out=$this->_data_read();
 
867
                        $this->_data_close();
 
868
                        if(!$this->_readmsg()) return FALSE;
 
869
                        if(!$this->_checkCode()) return FALSE;
 
870
                        if($out === FALSE ) return FALSE;
 
871
                        $out=preg_split("/[".CRLF."]+/", $out, -1, PREG_SPLIT_NO_EMPTY);
 
872
//                      $this->SendMSG(implode($this->_eol_code[$this->OS_local], $out));
 
873
                }
 
874
                return $out;
 
875
        }
 
876
 
 
877
// <!-- --------------------------------------------------------------------------------------- -->
 
878
// <!-- Partie : gestion des erreurs                                                            -->
 
879
// <!-- --------------------------------------------------------------------------------------- -->
 
880
// Gnre une erreur pour traitement externe  la classe
 
881
        function PushError($fctname,$msg,$desc=false){
 
882
                $error=array();
 
883
                $error['time']=time();
 
884
                $error['fctname']=$fctname;
 
885
                $error['msg']=$msg;
 
886
                $error['desc']=$desc;
 
887
                if($desc) $tmp=' ('.$desc.')'; else $tmp='';
 
888
                $this->SendMSG($fctname.': '.$msg.$tmp);
 
889
                return(array_push($this->_error_array,$error));
 
890
        }
 
891
 
 
892
// Rcupre une erreur externe
 
893
        function PopError(){
 
894
                if(count($this->_error_array)) return(array_pop($this->_error_array));
 
895
                        else return(false);
 
896
        }
 
897
}
 
898
 
 
899
$mod_sockets = extension_loaded( 'sockets' );
 
900
if ( ! $mod_sockets && function_exists( 'dl' ) && is_callable( 'dl' ) ) {
 
901
        $prefix = ( PHP_SHLIB_SUFFIX == 'dll' ) ? 'php_' : '';
 
902
        @dl( $prefix . 'sockets.' . PHP_SHLIB_SUFFIX );
 
903
        $mod_sockets = extension_loaded( 'sockets' );
 
904
}
 
905
 
 
906
require_once "class-ftp-" . ( $mod_sockets ? "sockets" : "pure" ) . ".php";
 
907
?>