[VD:FTP] support IIS (LIST type of Windows MS-DOS)

This commit is contained in:
nao-pon
2015-10-16 20:28:47 +09:00
parent bad82edacf
commit e3f162cf0f
2 changed files with 94 additions and 195 deletions
+94 -61
View File
@@ -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]))) {
-134
View File
@@ -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