mirror of
https://github.com/Studio-42/elFinder
synced 2026-06-08 12:37:09 +00:00
[VD:FTP] support IIS (LIST type of Windows MS-DOS)
This commit is contained in:
@@ -1,12 +1,5 @@
|
||||
<?php
|
||||
|
||||
function chmodnum($chmod) {
|
||||
$trans = array('-' => '0', 'r' => '4', 'w' => '2', 'x' => '1');
|
||||
$chmod = substr(strtr($chmod, $trans), 1);
|
||||
$array = str_split($chmod, 3);
|
||||
return array_sum(str_split($array[0])) . array_sum(str_split($array[1])) . array_sum(str_split($array[2]));
|
||||
}
|
||||
|
||||
elFinder::$netDrivers['ftp'] = 'FTP';
|
||||
|
||||
/**
|
||||
@@ -294,65 +287,94 @@ class elFinderVolumeFTP extends elFinderVolumeDriver {
|
||||
$info = preg_split("/\s+/", $raw, 9);
|
||||
$stat = array();
|
||||
|
||||
if (count($info) < 9 || $info[8] == '.' || $info[8] == '..') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($this->ftpOsUnix)) {
|
||||
$this->ftpOsUnix = !preg_match('/\d/', substr($info[0], 0, 1));
|
||||
}
|
||||
if (!$this->ftpOsUnix) {
|
||||
$info = $this->normalizeRawWindows($raw);
|
||||
}
|
||||
|
||||
if ($this->ftpOsUnix) {
|
||||
|
||||
$name = $info[8];
|
||||
|
||||
if (preg_match('|(.+)\-\>(.+)|', $name, $m)) {
|
||||
$name = trim($m[1]);
|
||||
// check recursive processing
|
||||
if ($this->cacheDirTarget && $this->_joinPath($base, $name) !== $this->cacheDirTarget) {
|
||||
return array();
|
||||
}
|
||||
if (!$nameOnly) {
|
||||
$target = trim($m[2]);
|
||||
if (substr($target, 0, 1) !== $this->separator) {
|
||||
$target = $this->getFullPath($target, $base);
|
||||
}
|
||||
$target = $this->_normpath($target);
|
||||
$stat['name'] = $name;
|
||||
$stat['target'] = $target;
|
||||
return $stat;
|
||||
}
|
||||
if (count($info) < 9 || $info[8] == '.' || $info[8] == '..') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$name = $info[8];
|
||||
|
||||
if (preg_match('|(.+)\-\>(.+)|', $name, $m)) {
|
||||
$name = trim($m[1]);
|
||||
// check recursive processing
|
||||
if ($this->cacheDirTarget && $this->_joinPath($base, $name) !== $this->cacheDirTarget) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ($nameOnly) {
|
||||
return array('name' => $name);
|
||||
if (!$nameOnly) {
|
||||
$target = trim($m[2]);
|
||||
if (substr($target, 0, 1) !== $this->separator) {
|
||||
$target = $this->getFullPath($target, $base);
|
||||
}
|
||||
$target = $this->_normpath($target);
|
||||
$stat['name'] = $name;
|
||||
$stat['target'] = $target;
|
||||
return $stat;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($nameOnly) {
|
||||
return array('name' => $name);
|
||||
}
|
||||
|
||||
if (is_numeric($info[5]) && !$info[6] && !$info[7]) {
|
||||
// by normalizeRawWindows()
|
||||
$stat['ts'] = $info[5];
|
||||
} else {
|
||||
$stat['ts'] = strtotime($info[5].' '.$info[6].' '.$info[7]);
|
||||
if (empty($stat['ts'])) {
|
||||
$stat['ts'] = strtotime($info[6].' '.$info[5].' '.$info[7]);
|
||||
}
|
||||
|
||||
if ($this->options['statOwner']) {
|
||||
$stat['owner'] = $info[2];
|
||||
$stat['group'] = $info[3];
|
||||
$stat['perm'] = substr($info[0], 1);
|
||||
$stat['isowner'] = $stat['owner']? ($stat['owner'] == $this->options['user']) : $this->options['owner'];
|
||||
}
|
||||
|
||||
$perm = $this->parsePermissions($info[0], $stat['owner']);
|
||||
$stat['name'] = $name;
|
||||
$stat['mime'] = substr(strtolower($info[0]), 0, 1) == 'd' ? 'directory' : $this->mimetype($stat['name']);
|
||||
$stat['size'] = $stat['mime'] == 'directory' ? 0 : $info[4];
|
||||
$stat['read'] = $perm['read'];
|
||||
$stat['write'] = $perm['write'];
|
||||
} else {
|
||||
die('Windows ftp servers not supported yet');
|
||||
}
|
||||
|
||||
|
||||
$stat['owner'] = '';
|
||||
if ($this->options['statOwner']) {
|
||||
$stat['owner'] = $info[2];
|
||||
$stat['group'] = $info[3];
|
||||
$stat['perm'] = substr($info[0], 1);
|
||||
$stat['isowner'] = $stat['owner']? ($stat['owner'] == $this->options['user']) : $this->options['owner'];
|
||||
}
|
||||
|
||||
$perm = $this->parsePermissions($info[0], $stat['owner']);
|
||||
$stat['name'] = $name;
|
||||
$stat['mime'] = substr(strtolower($info[0]), 0, 1) == 'd' ? 'directory' : $this->mimetype($stat['name']);
|
||||
$stat['size'] = $stat['mime'] == 'directory' ? 0 : $info[4];
|
||||
$stat['read'] = $perm['read'];
|
||||
$stat['write'] = $perm['write'];
|
||||
|
||||
return $stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize MS-DOS style FTP LIST Raw line
|
||||
*
|
||||
* @param string $raw line from FTP LIST (MS-DOS style)
|
||||
* @return array
|
||||
* @author Naoki Sawada
|
||||
**/
|
||||
protected function normalizeRawWindows($raw) {
|
||||
$info = array_pad(array(), 9, '');
|
||||
$item = preg_replace('#\s+#', ' ', trim($raw), 3);
|
||||
list($date, $time, $size, $name) = explode(' ', $item, 4);
|
||||
$format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i';
|
||||
$dateObj = DateTime::createFromFormat($format, $date.$time);
|
||||
$info[5] = strtotime($dateObj->format('Y-m-d H:i'));
|
||||
$info[8] = $name;
|
||||
if ($size === '<DIR>') {
|
||||
$info[4] = 0;
|
||||
$info[0] = 'drwxr-xr-x';
|
||||
} else {
|
||||
$info[4] = (int)$size;
|
||||
$info[0] = '-rw-r--r--';
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse permissions string. Return array(read => true/false, write => true/false)
|
||||
*
|
||||
@@ -414,7 +436,7 @@ class elFinderVolumeFTP extends elFinderVolumeDriver {
|
||||
$stat['name'] = $name;
|
||||
$p = $prefix . $name;
|
||||
$cacheDirTarget = $this->cacheDirTarget;
|
||||
$this->cacheDirTarget = $target;
|
||||
$this->cacheDirTarget = $this->convEncIn($target, true);
|
||||
if ($tstat = $this->stat($target)) {
|
||||
$stat['size'] = $tstat['size'];
|
||||
$stat['alias'] = $target;
|
||||
@@ -629,8 +651,11 @@ class elFinderVolumeFTP extends elFinderVolumeDriver {
|
||||
* @author Dmitry (dio) Levashov
|
||||
**/
|
||||
protected function _stat($path) {
|
||||
if (isset($this->cache[$path])) {
|
||||
return $this->cache[$path];
|
||||
$outPath = $this->convEncOut($path);
|
||||
if (isset($this->cache[$outPath])) {
|
||||
return $this->convEncIn($this->cache[$outPath]);
|
||||
} else {
|
||||
$this->convEncIn();
|
||||
}
|
||||
if (!$this->MLSTsupprt) {
|
||||
if ($path === $this->root) {
|
||||
@@ -640,12 +665,8 @@ class elFinderVolumeFTP extends elFinderVolumeDriver {
|
||||
'dirs' => $this->_subdirs($path)
|
||||
);
|
||||
}
|
||||
$this->cacheDir($this->_dirname($path));
|
||||
if (isset($this->cache[$path])) {
|
||||
return $this->cache[$path];
|
||||
} else {
|
||||
return array();
|
||||
}
|
||||
$this->cacheDir($this->convEncOut($this->_dirname($path)));
|
||||
return $this->convEncIn(isset($this->cache[$outPath])? $this->cache[$outPath] : array());
|
||||
}
|
||||
$raw = ftp_raw($this->connect, 'MLST ' . $path);
|
||||
if (is_array($raw) && count($raw) > 1 && substr(trim($raw[0]), 0, 1) == 2) {
|
||||
@@ -757,6 +778,12 @@ class elFinderVolumeFTP extends elFinderVolumeDriver {
|
||||
|
||||
foreach (ftp_rawlist($this->connect, $path) as $str) {
|
||||
$info = preg_split('/\s+/', $str, 9);
|
||||
if (!isset($this->ftpOsUnix)) {
|
||||
$this->ftpOsUnix = !preg_match('/\d/', substr($info[0], 0, 1));
|
||||
}
|
||||
if (!$this->ftpOsUnix) {
|
||||
$info = $this->normalizeRawWindows($str);
|
||||
}
|
||||
$name = isset($info[8])? trim($info[8]) : '';
|
||||
if ($name && $name !== '.' && $name !== '..' && substr(strtolower($info[0]), 0, 1) === 'd') {
|
||||
return true;
|
||||
@@ -1282,6 +1309,12 @@ class elFinderVolumeFTP extends elFinderVolumeDriver {
|
||||
}
|
||||
foreach ($buff as $str) {
|
||||
$info = preg_split("/\s+/", $str, 9);
|
||||
if (!isset($this->ftpOsUnix)) {
|
||||
$this->ftpOsUnix = !preg_match('/\d/', substr($info[0], 0, 1));
|
||||
}
|
||||
if (!$this->ftpOsUnix) {
|
||||
$info = $this->normalizeRawWindows($str);
|
||||
}
|
||||
$type = substr($info[0], 0, 1);
|
||||
$name = trim($info[8]);
|
||||
if ($name !== '.' && $name !== '..' && (!$targets || isset($targets[$name]))) {
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Simple elFinder driver for IIS FTP
|
||||
*
|
||||
**/
|
||||
class elFinderVolumeFTPIIS extends elFinderVolumeFTP {
|
||||
|
||||
/**
|
||||
* Connect to ftp server
|
||||
*
|
||||
* @return bool
|
||||
**/
|
||||
protected function connect() {
|
||||
if (!($this->connect = ftp_connect($this->options['host'], $this->options['port'], $this->options['timeout']))) {
|
||||
return $this->setError('Unable to connect to FTP server '.$this->options['host']);
|
||||
}
|
||||
if (!ftp_login($this->connect, $this->options['user'], $this->options['pass'])) {
|
||||
$this->umount();
|
||||
return $this->setError('Unable to login into '.$this->options['host']);
|
||||
}
|
||||
|
||||
// switch off extended passive mode - may be usefull for some servers
|
||||
//@ftp_exec($this->connect, 'epsv4 off' );
|
||||
// enter passive mode if required
|
||||
$this->options['mode'] = 'active';
|
||||
ftp_pasv($this->connect, $this->options['mode'] == 'passive');
|
||||
|
||||
// enter root folder
|
||||
if (!ftp_chdir($this->connect, $this->root))
|
||||
{
|
||||
$this->umount();
|
||||
return $this->setError('Unable to open root folder.');
|
||||
}
|
||||
|
||||
$stat = array();
|
||||
$stat['name'] = $this->root;
|
||||
$stat['mime'] = 'directory';
|
||||
$this->filesCache[$this->root] = $stat;
|
||||
$this->cacheDir($this->root);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse line from ftp_rawlist() output and return file stat (array)
|
||||
*
|
||||
* @param string $raw line from ftp_rawlist() output
|
||||
* @return array
|
||||
**/
|
||||
protected function parseRaw($raw) {
|
||||
$info = preg_split("/\s+/", $raw, 9);
|
||||
$stat = array();
|
||||
|
||||
$stat['name'] = join(" ", array_slice($info, 3, 9));
|
||||
$stat['read'] = true;
|
||||
if ($info[2] == '<DIR>')
|
||||
{
|
||||
$stat['size'] = 0;
|
||||
$stat['mime'] = 'directory';
|
||||
}
|
||||
else
|
||||
{
|
||||
$stat['size'] = $info[2];
|
||||
$stat['mime'] = $this->mimetype($stat['name']);
|
||||
}
|
||||
|
||||
return $stat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache dir contents
|
||||
*
|
||||
* @param string $path dir path
|
||||
* @return void
|
||||
**/
|
||||
protected function cacheDir($path) {
|
||||
$this->dirsCache[$path] = array();
|
||||
|
||||
if (preg_match('/\'|\"/', $path)) {
|
||||
foreach (ftp_nlist($this->connect, $path) as $p) {
|
||||
if (($stat = $this->_stat($p)) &&empty($stat['hidden'])) {
|
||||
// $files[] = $stat;
|
||||
$this->dirsCache[$path][] = $p;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
foreach (ftp_rawlist($this->connect, $path) as $raw) {
|
||||
if (($stat = $this->parseRaw($raw))) {
|
||||
$p = $path.DIRECTORY_SEPARATOR.$stat['name'];
|
||||
// $files[] = $stat;
|
||||
$this->dirsCache[$path][] = $p;
|
||||
//$stat['name'] = $p;
|
||||
$this->filesCache[$p] = $stat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _stat($path) {
|
||||
$stat = array();
|
||||
|
||||
$stat = $this->filesCache[$path];
|
||||
|
||||
if (empty($stat))
|
||||
{
|
||||
$this->cacheDir($this->_dirname($path));
|
||||
$stat = $this->filesCache[$path];
|
||||
|
||||
}
|
||||
|
||||
return $stat;
|
||||
}
|
||||
|
||||
|
||||
protected function ftp_scan_dir($remote_directory)
|
||||
{
|
||||
$buff = ftp_rawlist($this->connect, $remote_directory, true);
|
||||
$items = array();
|
||||
foreach ($buff as $str) {
|
||||
$info = preg_split("/\s+/", $str, 9);
|
||||
$remote_file_path = $remote_directory . DIRECTORY_SEPARATOR . join(" ", array_slice($info, 3, 9));
|
||||
$item = array();
|
||||
$item['type'] = $info[2] == '<DIR>' ? 'd' : 'f';
|
||||
$item['path'] = $remote_file_path;
|
||||
$items[] = $item;
|
||||
|
||||
if ($item['type'] == 'd')
|
||||
$items = array_merge($items, $this->ftp_scan_dir($item['path']));
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
} // END class
|
||||
|
||||
Reference in New Issue
Block a user