') {
$file['type'] = '**dir';
$file['size'] = -1;
} else {
$file['size'] = $item[2];
$name = explode('.', $file['name']);
if (count($name) == 1 || (substr($file['name'], 0, 1) === '.' && count($name) == 2)) {
$file['type'] = '**none';
} else {
$file['type'] = Horde_String::lower($name[count($name) - 1]);
}
}
}
// Filtering.
if ($this->_filterMatch($filter, $file['name'])) {
unset($file);
continue;
}
if ($dironly && $file['type'] !== '**dir') {
unset($file);
continue;
}
$files[$file['name']] = $file;
unset($file);
}
if (isset($olddir)) {
$this->_setPath($olddir);
}
return $files;
}
/**
* Copies a file through the backend.
*
* @param string $path The path of the original file.
* @param string $name The name of the original file.
* @param string $dest The name of the destination directory.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function copy($path, $name, $dest, $autocreate = false)
{
$this->_checkDestination($path, $dest);
$this->_connect();
if ($autocreate) {
$this->autocreatePath($dest);
}
foreach ($this->listFolder($dest, null, true) as $file) {
if ($file['name'] == $name) {
throw new Horde_Vfs_Exception(sprintf('%s already exists.', $this->_getPath($dest, $name)));
}
}
if ($this->isFolder($path, $name)) {
$this->_copyRecursive($path, $name, $dest);
} else {
$tmpFile = Horde_Util::getTempFile('vfs');
$orig = $this->_getPath($path, $name);
$fetch = @ftp_get($this->_stream, $tmpFile, $orig, FTP_BINARY);
if (!$fetch) {
unlink($tmpFile);
throw new Horde_Vfs_Exception(sprintf('Failed to copy from "%s".', $orig));
}
clearstatcache();
$this->_checkQuotaWrite('file', $tmpFile, $dest, $name);
if (!@ftp_put($this->_stream, $this->_getPath($dest, $name), $tmpFile, FTP_BINARY)) {
unlink($tmpFile);
throw new Horde_Vfs_Exception(sprintf('Failed to copy to "%s".', $this->_getPath($dest, $name)));
}
unlink($tmpFile);
}
}
/**
* Moves a file through the backend.
*
* @param string $path The path of the original file.
* @param string $name The name of the original file.
* @param string $dest The destination file name.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function move($path, $name, $dest, $autocreate = false)
{
$orig = $this->_getPath($path, $name);
if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
throw new Horde_Vfs_Exception('Cannot move file(s) - destination is within source.');
}
$this->_connect();
if ($autocreate) {
$this->autocreatePath($dest);
}
foreach ($this->listFolder($dest, null, true) as $file) {
if ($file['name'] == $name) {
throw new Horde_Vfs_Exception(sprintf('%s already exists.', $this->_getPath($dest, $name)));
}
}
if (!@ftp_rename($this->_stream, $orig, $this->_getPath($dest, $name))) {
throw new Horde_Vfs_Exception(sprintf('Failed to move to "%s".', $this->_getPath($dest, $name)));
}
}
/**
* Returns the current working directory on the FTP server.
*
* @return string The current working directory.
* @throws Horde_Vfs_Exception
*/
public function getCurrentDirectory()
{
$this->_connect();
return @ftp_pwd($this->_stream);
}
/**
* Returns the full path of an item.
*
* @param string $path The path of directory of the item.
* @param string $name The name of the item.
*
* @return mixed Full path when $path isset and just $name when not set.
*/
protected function _getPath($path, $name)
{
if (isset($this->_params['vfsroot']) &&
strlen($this->_params['vfsroot'])) {
if (strlen($path)) {
$path = $this->_params['vfsroot'] . '/' . $path;
} else {
$path = $this->_params['vfsroot'];
}
}
return parent::_getPath($path, $name);
}
/**
* Changes the current directory on the server.
*
* @param string $path The path to change to.
*
* @throws Horde_Vfs_Exception
*/
protected function _setPath($path)
{
if (!@ftp_chdir($this->_stream, $path)) {
throw new Horde_Vfs_Exception(sprintf('Unable to change to %s.', $path));
}
}
/**
* Attempts to open a connection to the FTP server.
*
* @throws Horde_Vfs_Exception
*/
protected function _connect()
{
if ($this->_stream !== false) {
return;
}
if (!extension_loaded('ftp')) {
throw new Horde_Vfs_Exception('The FTP extension is not available.');
}
if (!is_array($this->_params)) {
throw new Horde_Vfs_Exception('No configuration information specified for FTP VFS.');
}
$required = array('hostspec', 'username', 'password');
foreach ($required as $val) {
if (!isset($this->_params[$val])) {
throw new Horde_Vfs_Exception(sprintf('Required "%s" not specified in VFS configuration.', $val));
}
}
/* Connect to the ftp server using the supplied parameters. */
if (!empty($this->_params['ssl'])) {
if (function_exists('ftp_ssl_connect')) {
$this->_stream = @ftp_ssl_connect($this->_params['hostspec'], $this->_params['port']);
} else {
throw new Horde_Vfs_Exception('Unable to connect with SSL.');
}
} else {
$this->_stream = @ftp_connect($this->_params['hostspec'], $this->_params['port']);
}
if (!$this->_stream) {
throw new Horde_Vfs_Exception('Connection to FTP server failed.');
}
if (!@ftp_login($this->_stream, $this->_params['username'], $this->_params['password'])) {
@ftp_quit($this->_stream);
$this->_stream = false;
throw new Horde_Vfs_Exception('Authentication to FTP server failed.');
}
if (!empty($this->_params['pasv'])) {
@ftp_pasv($this->_stream, true);
}
if (!empty($this->_params['timeout'])) {
ftp_set_option($this->_stream, FTP_TIMEOUT_SEC, $this->_params['timeout']);
}
if (!empty($this->_params['vfsroot']) &&
!@ftp_chdir($this->_stream, $this->_params['vfsroot']) &&
!@ftp_mkdir($this->_stream, $this->_params['vfsroot'])) {
throw new Horde_Vfs_Exception(sprintf('Unable to create VFS root directory "%s".', $this->_params['vfsroot']));
}
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Gc.php 0000664 0001750 0001750 00000002674 12654104000 015110 0 ustar jan jan
* @package Vfs
*/
class Horde_Vfs_Gc
{
/**
* Garbage collect files in the VFS storage system.
*
* @param VFS $vfs The VFS object to perform garbage collection on.
* @param string $path The VFS path to clean.
* @param integer $secs The minimum amount of time (in seconds) required
* before a file is removed.
*/
public static function gc($vfs, $path, $secs = 345600)
{
/* A 0.1% chance we will run garbage collection during a call. */
if (substr(time(), -3) !== '000') {
return;
}
/* Use a backend-specific method if one exists. */
if (is_callable(array($vfs, 'gc'))) {
$vfs->gc($path, $secs);
}
/* Make sure cleaning is done recursively. */
try {
$modtime = time() - $secs;
foreach ($vfs->listFolder($path, null, true, false, true) as $val) {
if ($val['date'] < $modtime) {
$vfs->deleteFile($path, $val['name']);
}
}
} catch (Horde_Vfs_Exception $e) {
}
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Horde.php 0000664 0001750 0001750 00000012047 12654104000 015613 0 ustar jan jan
* 'horde_base' Filesystem location of a local Horde installation.
*
* Optional parameters:
* 'user' A valid Horde user name.
* 'password' The user's password.
*
* Copyright 2006-2016 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Jan Schneider
* @package Vfs
*/
class Horde_Vfs_Horde extends Horde_Vfs_Base
{
/**
* Reference to a Horde Registry instance.
*
* @var Horde_Registry
*/
protected $_registry;
/**
* Constructor.
*
* @param array $params A hash containing connection parameters.
* @throws Horde_Vfs_Exception
*/
public function __construct($params = array())
{
parent::__construct($params);
if (!isset($this->_params['horde_base'])) {
throw new Horde_Vfs_Exception('Required "horde_base" not specified in VFS configuration.');
}
require_once $this->_params['horde_base'] . '/lib/Application.php';
Horde_Registry::appInit('horde');
// Create the Registry object.
$this->_registry = $GLOBALS['registry'];
}
/**
*/
protected function _connect()
{
if (!empty($this->_params['user']) &&
!empty($this->_params['password'])) {
$GLOBALS['registry']->setAuth($this->_params['user'], array('password' => $this->_params['password']));
}
}
/**
* Retrieves a file from the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return string The file data.
*/
public function read($path, $name)
{
if (substr($path, 0, 1) == '/') {
$path = substr($path, 1);
}
$pieces = explode('/', $path);
try {
$data = $this->_registry->callByPackage($pieces[0], 'browse', array('path' => $path . '/' . $name));
} catch (Horde_Exception $e) {
return '';
}
return is_object($data) ? $data : $data['data'];
}
/**
* Returns an unsorted file list of the specified directory.
*
* @param string $path The path of the directory.
* @param string|array $filter Regular expression(s) to filter
* file/directory name on.
* @param boolean $dotfiles Show dotfiles?
* @param boolean $dironly Show only directories?
*
* @return array File list.
* @throws Horde_Vfs_Exception
*/
protected function _listFolder($path, $filter = null, $dotfiles = true,
$dironly = false)
{
$list = array();
if ($path == '/') {
try {
$apps = $this->_registry->listApps(null, false, Horde_Perms::READ);
} catch (Horde_Exception $e) {
throw new Horde_Vfs_Exception($e->getMessage());
}
foreach ($apps as $app) {
if ($this->_registry->hasMethod('browse', $app)) {
$file = array(
//'name' => $this->_registry->get('name', $app),
'name' => $app,
'date' => time(),
'type' => '**dir',
'size' => -1
);
$list[] = $file;
}
}
return $list;
}
if (substr($path, 0, 1) == '/') {
$path = substr($path, 1);
}
$pieces = explode('/', $path);
try {
$items = $this->_registry->callByPackage($pieces[0], 'browse', array('path' => $path, 'properties' => array('name', 'browseable', 'contenttype', 'contentlength', 'modified')));
} catch (Horde_Exception $e) {
throw new Horde_Vfs_Exception($e->getMessage());
}
if (!is_array(reset($items))) {
/* We return an object's content. */
throw new Horde_Vfs_Exception('Unknown error');
}
foreach ($items as $sub_path => $i) {
if ($dironly && !$i['browseable']) {
continue;
}
$name = basename($sub_path);
if ($this->_filterMatch($filter, $name)) {
continue;
}
$type = class_exists('Horde_Mime_Magic')
? Horde_Mime_Magic::mimeToExt(empty($i['contenttype']) ? 'application/octet-stream' : $i['contenttype'])
: '**none';
$file = array(
//'name' => $i['name'],
'name' => $name,
'date' => empty($i['modified']) ? 0 : $i['modified'],
'type' => $i['browseable'] ? '**dir' : $type,
'size' => empty($i['contentlength']) ? 0 : $i['contentlength']
);
$list[] = $file;
}
return $list;
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Mongo.php 0000664 0001750 0001750 00000033370 12654104000 015633 0 ustar jan jan
* @category Horde
* @copyright 2013-2016 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Vfs
*/
class Horde_Vfs_Mongo extends Horde_Vfs_Base
{
/* Metadata subdocument identifier. */
const MD = 'metadata';
/* Field (metadata) names. */
const FNAME = 'vfile';
const OWNER = 'owner';
const PATH = 'vpath';
/* Field (folders) names. */
const FOLDER_OWNER = 'owner';
const FOLDER_PATH = 'path';
const FOLDER_TS = 'ts';
/**
* The MongoDB GridFS object for the VFS data.
*
* @var MongoGridFS
*/
protected $_files;
/**
* The MongoDB collection for the VFS folder data.
*
* @var MongoGridCollection
*/
protected $_folders;
/**
* Constructor.
*
* @param array $params Additional parameters:
*
* - collection: (string) The collection name for the folders data.
* - gridfs: (string) The GridFS name.
* - mongo_db: [REQUIRED] (Horde_Mongo_Client) A MongoDB client object.
*
*/
public function __construct(array $params = array())
{
if (!isset($params['mongo_db'])) {
throw new InvalidArgumentException('Missing mongo_db parameter.');
}
parent::__construct(array_merge(array(
'collection' => 'horde_vfs_folders',
'gridfs' => 'horde_vfs'
), $params));
$this->_files = $this->_params['mongo_db']->selectDB(null)->getGridFS($this->_params['gridfs']);
$this->_folders = $this->_params['mongo_db']->selectDB(null)->selectCollection($this->_params['collection']);
}
/**
*/
public function size($path, $name)
{
if ($res = $this->_getFile($path, $name)) {
return $res->getSize();
}
throw new Horde_Vfs_Exception(sprintf('Unable to retrieve file size of "%s/%s".', $path, $name));
}
/**
*/
public function getFolderSize($path = null)
{
$query = array();
if (!is_null($path)) {
$query[$this->_mdKey(self::PATH)] = array(
'$regex' => '^' . $this->_convertPath($path)
);
}
$size = 0;
try {
foreach ($this->_files->find($query) as $val) {
$size += $val->getSize();
}
} catch (MongoException $e) {
throw new Horde_Vfs_Exception($e);
}
return $size;
}
/**
*/
public function read($path, $name)
{
if ($res = $this->_getFile($path, $name)) {
return $res->getBytes();
}
throw new Horde_Vfs_Exception(sprintf('Unable to read file "%s/%s".', $path, $name));
}
/**
*/
public function readByteRange($path, $name, &$offset, $length, &$remaining)
{
if (!($res = $this->_getFile($path, $name))) {
throw new Horde_Vfs_Exception(sprintf('Unable to read file "%s/%s".', $path, $name));
}
$stream = $res->getResource();
$data = stream_get_contents($stream, $length, $offset);
$curr = ftell($stream);
fclose($stream);
$offset = min($curr, $offset + $length);
$remaining = max(0, $res->getSize() - $curr);
return $data;
}
/**
* Open a read-only stream to a file in the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return resource The stream.
* @throws Horde_Vfs_Exception
*/
public function readStream($path, $name)
{
if ($res = $this->_getFile($path, $name)) {
return $res->getResource();
}
throw new Horde_Vfs_Exception(sprintf('Unable to read file "%s/%s".', $path, $name));
}
/**
*/
public function write($path, $name, $tmpFile, $autocreate = false)
{
$this->_write('file', $path, $name, $tmpFile, $autocreate);
}
/**
*/
public function writeData($path, $name, $data, $autocreate = false)
{
$this->_write('string', $path, $name, $data, $autocreate);
}
/**
*/
protected function _write($type, $path, $name, $data, $autocreate)
{
$this->_checkQuotaWrite($type, $data, $path, $name);
if ($autocreate) {
$this->autocreatePath($path);
} elseif (!$this->_isFolder($path)) {
throw new Horde_Vfs_Exception(sprintf('Folder "%s" does not exist', $path));
}
$orig = $this->_getFile($path, $name);
$mdata = array(
self::MD => array(
self::FNAME => $name,
self::OWNER => $this->_params['user'],
self::PATH => $this->_convertPath($path)
)
);
try {
switch ($type) {
case 'file':
$this->_files->storeFile($data, $mdata);
break;
case 'string':
$this->_files->storeBytes($data, $mdata);
break;
}
} catch (MongoException $e) {
throw new Horde_Vfs_Exception('Unable to write file data.');
}
if ($orig) {
$this->_files->delete($orig->file['_id']);
}
}
/**
*/
public function deleteFile($path, $name)
{
if ($orig = $this->_getFile($path, $name)) {
$this->_checkQuotaDelete($path, $name);
$this->_files->delete($orig->file['_id']);
} else {
throw new Horde_Vfs_Exception('Unable to delete VFS file.');
}
}
/**
*/
public function rename($oldpath, $oldname, $newpath, $newname)
{
if (!($res = $this->_getFile($oldpath, $oldname))) {
throw new Horde_Vfs_Exception('Unable to rename VFS file.');
}
$this->autocreatePath($newpath);
$res->file[self::MD][self::FNAME] = $newname;
$res->file[self::MD][self::PATH] = $newpath;
try {
$this->_files->save($res->file);
} catch (MongoException $e) {
throw new Horde_Vfs_Exception(sprintf('Unable to rename VFS file %s/%s.', $oldpath, $oldname));
}
}
/**
*/
public function createFolder($path, $name)
{
$query = array(
self::FOLDER_OWNER => $this->_params['user'],
self::FOLDER_PATH => $this->_convertPath($path . '/' . $name),
self::FOLDER_TS => new MongoDate()
);
try {
$this->_folders->insert($query);
} catch (MongoException $e) {}
}
/**
*/
public function isFolder($path, $name)
{
return $this->_isFolder($path . '/' . $name);
}
/**
*/
protected function _isFolder($path)
{
$path = $this->_convertPath($path);
if (!strlen($path)) {
return true;
}
$query = array(
self::FOLDER_PATH => $path
);
try {
return (bool) $this->_folders->find($query)->limit(1)->count();
} catch (MongoException $e) {
return false;
}
}
/**
*/
public function deleteFolder($path, $name, $recursive = false)
{
$fullpath = $path . '/' . $name;
if ($recursive) {
$this->emptyFolder($fullpath);
} else {
$query = array(
$this->_mdKey(self::PATH) => array(
'$regex' => '^' . $this->_convertPath($fullpath)
)
);
if ($this->_files->find($query)->limit(1)->count()) {
throw new Horde_Vfs_Exception(sprintf('Unable to delete %s/%s; the directory is not empty.', $path, $name));
}
}
try {
$this->_folders->remove(array(
self::FOLDER_PATH => $this->_convertPath($fullpath)
));
} catch (MongoException $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
*/
public function emptyFolder($path)
{
$query = array(
$this->_mdKey(self::PATH) => array(
'$regex' => '^' . $this->_convertPath($path)
)
);
$size = null;
try {
if (!is_null($this->_vfsSize)) {
$files = $this->_files->find($query);
$ids = array();
foreach ($files as $val) {
$ids[] = $val->file['_id'];
$size += $val->getSize();
}
$query = array(
'_id' => array(
'$in' => $ids
)
);
}
$this->_files->remove($query);
$this->_folders->remove(array(
self::FOLDER_PATH => array(
'$regex' => '^' . $this->_convertPath($path) . '/'
)
));
} catch (MongoException $e) {
throw new Horde_Vfs_Exception($e);
}
if (!is_null($size)) {
$this->_vfsSize -= $size;
}
}
/**
* Returns an an unsorted file list of the specified directory.
*
* @param string $path The path of the directory.
* @param mixed $filter String/hash to filter file/dirname on.
* @param boolean $dotfiles Show dotfiles?
* @param boolean $dironly Show only directories?
*
* @return array File list.
* @throws Horde_Vfs_Exception
*/
protected function _listFolder($path, $filter = null, $dotfiles = true,
$dironly = false)
{
if (!$this->_isFolder($path)) {
throw new Horde_Vfs_Exception(sprintf('Folder "%s" does not exist', $path));
}
$out = array();
$path = $this->_convertPath($path);
if (!$dironly) {
try {
$files = $this->_files->find(array(
$this->_mdKey(self::PATH) => $this->_convertPath($path)
));
} catch (MongoException $e) {
throw new Horde_Vfs_Exception($e);
}
foreach ($files as $val) {
$name = $val->file[self::MD][self::FNAME];
// Filter out dotfiles if they aren't wanted.
if (!$dotfiles && ($name[0] == '.')) {
continue;
}
// Filtering.
if ($this->_filterMatch($filter, $name)) {
continue;
}
$tmp = array(
'date' => $val->file['uploadDate']->sec,
'group' => '',
'name' => $name,
'owner' => $val->file[self::MD][self::OWNER],
'perms' => '',
'size' => $val->getSize()
);
$type = explode('.', $name);
$tmp['type'] = (count($type) == 1)
? '**none'
: Horde_String::lower(array_pop($type));
$out[$name] = $tmp;
}
}
try {
$folders = $this->_folders->find(array(
self::FOLDER_PATH => array(
'$regex' => '^' . (strlen($path) ? $path . '/' : '') . '[^\/]+$'
)
));
} catch (MongoException $e) {
throw new Horde_Vfs_Exception($e);
}
foreach ($folders as $val) {
$tmp = explode('/', $val[self::FOLDER_PATH]);
$path = array_pop($tmp);
if (isset($out[$path]) ||
$this->_filterMatch($filter, $path)) {
continue;
}
$out[$path] = array(
'date' => $val[self::FOLDER_TS]->sec,
'group' => '',
'name' => $path,
'owner' => $val[self::FOLDER_OWNER],
'perms' => '',
'size' => -1,
'type' => '**dir'
);
}
return $out;
}
/**
*/
public function gc($path, $secs = 345600)
{
$query = array(
$this->_mdKey(self::PATH) => array(
'$regex' => '^' . $this->_convertPath($path)
),
'uploadDate' => array(
'$lt' => new MongoDate(time() - $secs)
)
);
try {
$this->_files->remove($query);
} catch (MongoException $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
* Converts the path name from regular filesystem form to the internal
* format needed to access the file in the database.
*
* Namely, we will treat '/' as a base directory as this is pretty much
* the standard way to access base directories over most filesystems.
*
* @param string $path A VFS path.
*
* @return string The path with any surrouding slashes stripped off.
*/
protected function _convertPath($path)
{
return trim($path, '/');
}
/**
*/
protected function _getFile($path, $name)
{
$query = array(
$this->_mdKey(self::FNAME) => $name,
$this->_mdKey(self::PATH) => $this->_convertPath($path)
);
try {
return $this->_files->findOne($query);
} catch (MongoException $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
*/
protected function _mdKey($key)
{
return self::MD . '.' . $key;
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Musql.php 0000664 0001750 0001750 00000041451 12654104000 015654 0 ustar jan jan
* @author Mike Cochrane
* @package Vfs
*/
class Horde_Vfs_Musql extends Horde_Vfs_Sql
{
/* Permission for read access. */
const FLAG_READ = 1;
/* Permission for read access. */
const FLAG_WRITE = 2;
/**
* List of permissions and if they can be changed in this VFS
*
* @var array
*/
protected $_permissions = array(
'owner' => array(
'read' => false,
'write' => false,
'execute' => false
),
'group' => array(
'read' => false,
'write' => false,
'execute' => false
),
'all' => array(
'read' => true,
'write' => true,
'execute' => false
)
);
/**
* Stores a file in the VFS from raw data.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $data The file data.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function writeData($path, $name, $data, $autocreate = false)
{
/* Make sure we have write access to this and all parent paths. */
if ($path != '') {
$paths = explode('/', $path);
$path_name = array_pop($paths);
if (!$this->isFolder(implode('/', $paths), $path_name)) {
if (!$autocreate) {
throw new Horde_Vfs_Exception(sprintf('Folder "%s" does not exist'), $path);
} else {
$this->autocreatePath($path);
}
}
$paths[] = $path_name;
$previous = '';
foreach ($paths as $thispath) {
$sql = sprintf('SELECT vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ?',
$this->_params['table']);
try {
$results = $this->_db->selectAll($sql, array($previous, $thispath));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if (!is_array($results) || count($results) < 1) {
throw new Horde_Vfs_Exception('Unable to create VFS file.');
}
$allowed = false;
foreach ($results as $result) {
if ($result['vfs_owner'] == $this->_params['user'] ||
$result['vfs_perm'] & self::FLAG_WRITE) {
$allowed = true;
break;
}
}
if (!$allowed) {
throw new Horde_Vfs_Exception('Access denied creating VFS file.');
}
$previous = $thispath;
}
}
return parent::writeData($path, $name, $data, $autocreate);
}
/**
* Deletes a file from the VFS.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
*
* @throws Horde_Vfs_Exception
*/
public function deleteFile($path, $name)
{
$sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ? AND vfs_type = ?',
$this->_params['table']);
try {
$fileList = $this->_db->selectAll($sql, array($path, $name, self::FILE));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if (!is_array($fileList) || count($fileList) < 1) {
throw new Horde_Vfs_Exception('Unable to delete VFS file.');
}
/* There may be one or more files with the same name but the user may
* not have read access to them, so doesn't see them. So we have to
* delete the one they have access to. */
foreach ($fileList as $file) {
if ($file['vfs_owner'] == $this->_params['user'] ||
$file['vfs_perms'] & self::FLAG_WRITE) {
$sql = sprintf('DELETE FROM %s WHERE vfs_id = ?',
$this->_params['table']);
try {
$result = $this->_db->delete($sql, array($file['vfs_id']));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if ($result == 0) {
throw new Horde_Vfs_Exception('Unable to delete VFS file.');
}
return;
}
}
// FIXME: 'Access Denied deleting file %s/%s'
throw new Horde_Vfs_Exception('Unable to delete VFS file.');
}
/**
* Renames a file or folder in the VFS.
*
* @param string $oldpath The old path to the file.
* @param string $oldname The old filename.
* @param string $newpath The new path of the file.
* @param string $newname The new filename.
*
* @throws Horde_Vfs_Exception
*/
public function rename($oldpath, $oldname, $newpath, $newname)
{
$sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ?',
$this->_params['table']);
try {
$fileList = $this->_db->selectAll($sql, array($oldpath, $oldname));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if (!is_array($fileList) || count($fileList) < 1) {
throw new Horde_Vfs_Exception('Unable to rename VFS file.');
}
if (strpos($newpath, '/') === false) {
$parent = '';
$path = $newpath;
} else {
list($parent, $path) = explode('/', $newpath, 2);
}
if (!$this->isFolder($parent, $path)) {
$this->autocreatePath($newpath);
}
/* There may be one or more files with the same name but the user may
* not have read access to them, so doesn't see them. So we have to
* rename the one they have access to. */
foreach ($fileList as $file) {
if ($file['vfs_owner'] == $this->_params['user'] ||
$file['vfs_perms'] & self::FLAG_WRITE) {
$sql = sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?, vfs_modified = ?
WHERE vfs_id = ?',
$this->_params['table']);
try {
$this->_db->update(
$sql,
array($newpath, $newname, time(), $file['vfs_id']));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
}
throw new Horde_Vfs_Exception(sprintf('Unable to rename VFS file %s/%s.', $oldpath, $oldname));
}
/**
* Creates a folder on the VFS.
*
* @param string $path Holds the path of directory to create folder.
* @param string $name Holds the name of the new folder.
*
* @throws Horde_Vfs_Exception
*/
public function createFolder($path, $name)
{
/* Make sure we have write access to this and all parent paths. */
if (strlen($path)) {
$paths = explode('/', $path);
$previous = '';
foreach ($paths as $thispath) {
$sql = sprintf('SELECT vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ?',
$this->_params['table']);
try {
$results = $this->_db->selectAll($sql, array($previous, $thispath));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if (!is_array($results) || count($results) < 1) {
throw new Horde_Vfs_Exception('Unable to create VFS directory.');
}
$allowed = false;
foreach ($results as $result) {
if ($result['vfs_owner'] == $this->_params['user'] ||
$result['vfs_perms'] & self::FLAG_WRITE) {
$allowed = true;
break;
}
}
if (!$allowed) {
throw new Horde_Vfs_Exception('Access denied creating VFS directory.');
}
$previous = $thispath;
}
}
$sql = sprintf('INSERT INTO %s
(vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner, vfs_perms)
VALUES (?, ?, ?, ?, ?, ?)',
$this->_params['table']);
try {
$this->_db->insert(
$sql,
array(self::FOLDER, $path, $name, time(), $this->_params['user'], 0));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
* Deletes a folder from the VFS.
*
* @param string $path The path to delete the folder from.
* @param string $name The foldername to use.
* @param boolean $recursive Force a recursive delete?
*
* @throws Horde_Vfs_Exception
*/
public function deleteFolder($path, $name, $recursive = false)
{
if ($recursive) {
$this->emptyFolder($path . '/' . $name);
} else {
$list = $this->listFolder($path . '/' . $name);
if (count($list)) {
throw new Horde_Vfs_Exception(sprintf('Unable to delete %s, the directory is not empty', $path . '/' . $name));
}
}
$sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ? AND vfs_type = ?',
$this->_params['table']);
try {
$fileList = $this->_db->selectAll($sql, array($path, $name, self::FOLDER));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if (!is_array($fileList) || count($fileList) < 1) {
throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
}
/* There may be one or more folders with the same name but as the user
* may not have read access to them, they don't see them. So we have
* to delete the one they have access to */
foreach ($fileList as $file) {
if ($file['vfs_owner'] == $this->_params['user'] ||
$file['vfs_perms'] & self::FLAG_WRITE) {
$sql = sprintf('DELETE FROM %s WHERE vfs_id = ?',
$this->_params['table']);
try {
$result = $this->_db->delete($sql, array($file['vfs_id']));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if ($result == 0) {
throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
}
return $result;
}
}
// FIXME: 'Access Denied deleting folder %s/%s'
throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
}
/**
* Returns an an unsorted file list of the specified directory.
*
* @param string $path The path of the directory.
* @param mixed $filter String/hash to filter file/dirname on.
* @param boolean $dotfiles Show dotfiles?
* @param boolean $dironly Show only directories?
*
* @return array File list.
* @throws Horde_Vfs_Exception
*/
protected function _listFolder($path, $filter = null, $dotfiles = true,
$dironly = false)
{
$length_op = $this->_getFileSizeOp();
$sql = sprintf('SELECT vfs_name, vfs_type, vfs_modified, vfs_owner, vfs_perms, %s(vfs_data) length FROM %s
WHERE vfs_path = ? AND (vfs_owner = ? OR vfs_perms \&\& ?)',
$length_op, $this->_params['table']);
try {
$fileList = $this->_db->selectAll(
$sql,
array($path, $this->_params['user'], self::FLAG_READ));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
$files = array();
foreach ($fileList as $line) {
// Filter out dotfiles if they aren't wanted.
if (!$dotfiles && substr($line['vfs_name'], 0, 1) == '.') {
continue;
}
$file['name'] = stripslashes($line['vfs_name']);
if ($line['vfs_type'] == self::FILE) {
$name = explode('.', $line['vfs_name']);
if (count($name) == 1) {
$file['type'] = '**none';
} else {
$file['type'] = Horde_String::lower($name[count($name) - 1]);
}
$file['size'] = $line['length'];
} elseif ($line['vfs_type'] == self::FOLDER) {
$file['type'] = '**dir';
$file['size'] = -1;
}
$file['date'] = $line['vfs_modified'];
$file['owner'] = $line['vfs_owner'];
$line['vfs_perms'] = intval($line['vfs_perms']);
$file['perms'] = ($line['vfs_type'] == self::FOLDER) ? 'd' : '-';
$file['perms'] .= 'rw-';
$file['perms'] .= ($line['vfs_perms'] & self::FLAG_READ) ? 'r' : '-';
$file['perms'] .= ($line['vfs_perms'] & self::FLAG_WRITE) ? 'w' : '-';
$file['perms'] .= '-';
$file['group'] = '';
// Filtering.
if ($this->_filterMatch($filter, $file['name'])) {
unset($file);
continue;
}
if ($dironly && $file['type'] !== '**dir') {
unset($file);
continue;
}
$files[$file['name']] = $file;
unset($file);
}
return $files;
}
/**
* Changes permissions for an Item on the VFS.
*
* @param string $path The path of directory of the item.
* @param string $name The name of the item.
* @param string $permission The permission to set in octal notation.
*
* @throws Horde_Vfs_Exception
*/
public function changePermissions($path, $name, $permission)
{
$val = intval(substr($permission, -1));
$perm = 0;
$perm |= ($val & 4) ? self::FLAG_READ : 0;
$perm |= ($val & 2) ? self::FLAG_WRITE : 0;
$sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ?',
$this->_params['table']);
try {
$fileList = $this->_db->selectAll($sql, array($path, $name));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if (!is_array($fileList) || count($fileList) < 1) {
throw new Horde_Vfs_Exception('Unable to rename VFS file.');
}
/* There may be one or more files with the same name but the user may
* not have read access to them, so doesn't see them. So we have to
* chmod the one they have access to. */
foreach ($fileList as $file) {
if ($file['vfs_owner'] == $this->_params['user'] ||
$file['vfs_perms'] & self::FLAG_WRITE) {
$sql = sprintf('UPDATE %s SET vfs_perms = ?
WHERE vfs_id = ?',
$this->_params['table']);
try {
$this->_db->update($sql, array($perm, $file['vfs_id']));
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
}
throw new Horde_Vfs_Exception(sprintf('Unable to change permission for VFS file %s/%s.', $path, $name));
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Null.php 0000664 0001750 0001750 00000004150 12654104000 015460 0 ustar jan jan
* @category Horde
* @copyright 2014-2016 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Vfs
* @since 2.1.3
*/
class Horde_Vfs_Null extends Horde_Vfs_Base
{
/**
*/
public function size($path, $name)
{
return 0;
}
/**
*/
public function read($path, $name)
{
return '';
}
/**
*/
public function readFile($path, $name)
{
throw new Horde_Vfs_Exception('Unable to create temporary file.');
}
/**
*/
public function readByteRange($path, $name, &$offset, $length, &$remaining)
{
$remaining = 0;
return '';
}
/**
*/
public function write($path, $name, $tmpFile, $autocreate = false)
{
}
/**
*/
public function writeData($path, $name, $data, $autocreate = false)
{
}
/**
*/
public function deleteFile($path, $name)
{
}
/**
*/
public function rename($oldpath, $oldname, $newpath, $newname)
{
}
/**
*/
public function createFolder($path, $name)
{
}
/**
*/
public function deleteFolder($path, $name, $recursive = false)
{
}
/**
*/
protected function _listFolder($path, $filter = null, $dotfiles = true,
$dironly = false)
{
return array();
}
/**
*/
public function changePermissions($path, $name, $permission)
{
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Smb.php 0000664 0001750 0001750 00000054766 12654104000 015311 0 ustar jan jan . Adapted with
* permission by Patrice Levesque from phpsmb-0.8 code, and
* converted to the LGPL. Please do not taunt original author, contact
* Patrice Levesque or dev@lists.horde.org.
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @author Paul Gareau
* @author Patrice Levesque
* @package Vfs
* @todo Add driver for smbclient extension https://github.com/eduardok/libsmbclient-php
*/
/**
* Stateless VFS implementation for a SMB server, based on smbclient.
*
* Required values for $params:
* - username: (string) The username with which to connect to the SMB server.
* - password: (string) The password with which to connect to the SMB server.
* - hostspec: (string) The SMB server to connect to.
* - share: (string) The share to access on the SMB server. Any trailing
* paths will removed from the share and prepended to each path
* in further requests. Example: a share of 'myshare/basedir' and
* a request to 'dir/subdir' will result in a request to
* 'basedir/dir/subdir' on myshare.
* - smbclient: (string) The path to the 'smbclient' executable.
*
* Optional values for $params:
* - port: (integer) The SMB port number to connect to.
* - ipaddress: (string) The address of the server to connect to.
*
* Functions not implemented:
* - changePermissions(): The SMB permission style does not fit with the
* module.
*
* All paths need to use forward slashes!
*
* @author Paul Gareau
* @author Patrice Levesque
* @package Vfs
*/
class Horde_Vfs_Smb extends Horde_Vfs_Base
{
/**
* List of additional credentials required for this VFS backend.
*
* @var array
*/
protected $_credentials = array('username', 'password');
/**
* Has the vfsroot already been created?
*
* @var boolean
*/
protected $_rootCreated = false;
/**
* Retrieves the size of a file from the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return integer The file size.
* @throws Horde_Vfs_Exception
*/
public function size($path, $name)
{
$file = $this->readFile($path, $name);
return filesize($file);
}
/**
* Retrieves a file from the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return string The file data.
*/
public function read($path, $name)
{
$file = $this->readFile($path, $name);
$size = filesize($file);
return ($size === 0)
? ''
: file_get_contents($file);
}
/**
* Retrieves a file from the VFS as an on-disk local file.
*
* This function provides a file on local disk with the data of a VFS file
* in it. This file cannot be modified! The behavior if you do
* modify it is undefined. It will be removed at the end of the request.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return string A local filename.
*/
public function readFile($path, $name)
{
// Create a temporary file and register it for deletion at the
// end of this request.
if (!($localFile = Horde_Util::getTempFile('vfs'))) {
throw new Horde_Vfs_Exception('Unable to create temporary file.');
}
$this->_createRoot();
list($npath, $name) = $this->_escapeShellCommand($this->_getNativePath($path), $name);
$cmd = array('get \"' . $name . '\" ' . $localFile);
$this->_command($npath, $cmd);
if (!file_exists($localFile)) {
throw new Horde_Vfs_Exception(sprintf('Unable to open VFS file "%s".', $this->_getPath($path, $name)));
}
clearstatcache();
return $localFile;
}
/**
* Open a stream to a file in the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return resource The stream.
*/
public function readStream($path, $name)
{
return fopen($this->readFile($path, $name),
substr(PHP_OS, 0, 3) == 'WIN' ? 'rb' : 'r');
}
/**
* Stores a file in the VFS.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $tmpFile The temporary file containing the data to be
* stored.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function write($path, $name, $tmpFile, $autocreate = false)
{
$this->_createRoot();
// Double quotes not allowed in SMB filename.
$name = str_replace('"', "'", $name);
list($npath, $name) = $this->_escapeShellCommand($this->_getNativePath($path), $name);
$cmd = array('put \"' . $tmpFile . '\" \"' . $name . '\"');
// do we need to first autocreate the directory?
if ($autocreate) {
$this->autocreatePath($path);
}
$this->_command($npath, $cmd);
}
/**
* Stores a file in the VFS from raw data.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $data The file data.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function writeData($path, $name, $data, $autocreate = false)
{
$tmpFile = Horde_Util::getTempFile('vfs');
file_put_contents($tmpFile, $data);
try {
$this->write($path, $name, $tmpFile, $autocreate);
unlink($tmpFile);
} catch (Horde_Vfs_Exception $e) {
unlink($tmpFile);
throw $e;
}
}
/**
* Deletes a file from the VFS.
*
* @param string $path The path to delete the file from.
* @param string $name The filename to use.
*
* @throws Horde_Vfs_Exception
*/
public function deleteFile($path, $name)
{
$this->_createRoot();
list($path, $name) = $this->_escapeShellCommand($this->_getNativePath($path), $name);
$cmd = array('del \"' . $name . '\"');
$this->_command($path, $cmd);
}
/**
* Checks if a given pathname is a folder.
*
* @param string $path The path to the folder.
* @param string $name The file or folder name.
*
* @return boolean True if it is a folder, false otherwise.
*/
public function isFolder($path, $name)
{
$this->_createRoot();
list($path, $name) = $this->_escapeShellCommand($this->_getNativePath($path), $name);
try {
$this->_command($this->_getPath($path, $name), array('quit'));
return true;
} catch (Horde_Vfs_Exception $e) {
return false;
}
}
/**
* Deletes a folder from the VFS.
*
* @param string $path The path to delete the folder from.
* @param string $name The name of the folder to delete.
* @param boolean $recursive Force a recursive delete?
*
* @throws Horde_Vfs_Exception
*/
public function deleteFolder($path, $name, $recursive = false)
{
$this->_createRoot();
if (!$this->isFolder($path, $name)) {
throw new Horde_Vfs_Exception(sprintf('"%s" is not a directory.', $path . '/' . $name));
}
$file_list = $this->listFolder($this->_getPath($path, $name));
if ($file_list && !$recursive) {
throw new Horde_Vfs_Exception(sprintf('Unable to delete "%s", the directory is not empty.', $this->_getPath($path, $name)));
}
foreach ($file_list as $file) {
if ($file['type'] == '**dir') {
$this->deleteFolder($this->_getPath($path, $name), $file['name'], $recursive);
} else {
$this->deleteFile($this->_getPath($path, $name), $file['name']);
}
}
// Really delete the folder.
list($npath, $name) = $this->_escapeShellCommand($this->_getNativePath($path), $name);
$cmd = array('rmdir \"' . $name . '\"');
try {
$this->_command($npath, $cmd);
} catch (Horde_Vfs_Exception $e) {
throw new Horde_Vfs_Exception(sprintf('Unable to delete VFS folder "%s".', $this->_getPath($path, $name)));
}
}
/**
* Renames a file in the VFS.
*
* @param string $oldpath The old path to the file.
* @param string $oldname The old filename.
* @param string $newpath The new path of the file.
* @param string $newname The new filename.
*
* @throws Horde_Vfs_Exception
*/
public function rename($oldpath, $oldname, $newpath, $newname)
{
$this->_createRoot();
$this->autocreatePath($newpath);
// Double quotes not allowed in SMB filename. The '/' character should
// also be removed from the beginning/end of the names.
$oldname = str_replace('"', "'", trim($oldname, '/'));
$newname = str_replace('"', "'", trim($newname, '/'));
if (empty($oldname)) {
throw new Horde_Vfs_Exception('Unable to rename VFS file to same name.');
}
/* If the path was not empty (i.e. the path is not the root path),
* then add the trailing '/' character to path. */
if (!empty($oldpath)) {
$oldpath .= '/';
}
if (!empty($newpath)) {
$newpath .= '/';
}
list($file, $name) = $this->_escapeShellCommand($oldname, $newname);
$cmd = array(
'rename \"'
. str_replace('/', '\\\\', $this->_getNativePath($oldpath))
. $file . '\" \"'
. str_replace('/', '\\\\', $this->_getNativePath($newpath))
. $name . '\"'
);
try {
$this->_command('', $cmd);
} catch (Horde_Vfs_Exception $e) {
throw new Horde_Vfs_Exception(sprintf('Unable to rename VFS file "%s".', $this->_getPath($oldpath, $oldname)));
}
}
/**
* Creates a folder on the VFS.
*
* @param string $path The path of directory to create folder.
* @param string $name The name of the new folder.
*
* @throws Horde_Vfs_Exception
*/
public function createFolder($path, $name)
{
$this->_createRoot();
// Double quotes not allowed in SMB filename.
$name = str_replace('"', "'", $name);
list($dir, $mkdir) = $this->_escapeShellCommand($this->_getNativePath($path), $name);
$cmd = array('mkdir \"' . $mkdir . '\"');
try {
$this->_command($dir, $cmd);
} catch (Horde_Vfs_Exception $e) {
throw new Horde_Vfs_Exception(sprintf('Unable to create VFS folder "%s".', $this->_getPath($path, $name)));
}
}
/**
* Returns a file list of the directory passed in.
*
* @param string $path The path of the directory.
* @param string|array $filter Regular expression(s) to filter
* file/directory name on.
* @param boolean $dotfiles Show dotfiles?
* @param boolean $dironly Show only directories?
* @param boolean $recursive Return all directory levels recursively?
*
* @return array File list.
* @throws Horde_Vfs_Exception
*/
public function listFolder($path = '', $filter = null, $dotfiles = true,
$dironly = false, $recursive = false)
{
$this->_createRoot();
list($path) = $this->_escapeShellCommand($this->_getNativePath($path));
return $this->parseListing($this->_command($path, array('ls')),
$filter,
$dotfiles,
$dironly);
}
/**
*/
public function parseListing($res, $filter, $dotfiles, $dironly)
{
$num_lines = count($res);
$files = array();
for ($r = 0; $r < $num_lines; $r++) {
// Match file listing.
if (!preg_match('/^ (.+?) +([A-Z]*) +(\d+) (\w\w\w \w\w\w [ \d]\d \d\d:\d\d:\d\d \d\d\d\d)$/', $res[$r], $match)) {
continue;
}
// If the file name isn't . or ..
if ($match[1] == '.' || $match[1] == '..') {
continue;
}
$my_name = $match[1];
// Filter out dotfiles if they aren't wanted.
if (!$dotfiles && substr($my_name, 0, 1) == '.') {
continue;
}
$my_size = $match[3];
$ext_name = explode('.', $my_name);
if ((strpos($match[2], 'D') !== false)) {
$my_type = '**dir';
$my_size = -1;
} else {
$my_type = Horde_String::lower($ext_name[count($ext_name) - 1]);
}
$my_date = strtotime($match[4]);
$filedata = array('owner' => '',
'group' => '',
'perms' => '',
'name' => $my_name,
'type' => $my_type,
'date' => $my_date,
'size' => $my_size);
// watch for filters and dironly
if ($this->_filterMatch($filter, $my_name)) {
unset($file);
continue;
}
if ($dironly && $my_type !== '**dir') {
unset($file);
continue;
}
$files[$filedata['name']] = $filedata;
}
return $files;
}
/**
* Copies a file through the backend.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $dest The destination of the file.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function copy($path, $name, $dest, $autocreate = false)
{
$this->_checkDestination($path, $dest);
if ($autocreate) {
$this->autocreatePath($dest);
}
foreach ($this->listFolder($dest, null, true) as $file) {
if ($file['name'] == $name) {
throw new Horde_Vfs_Exception(sprintf('%s already exists.', $this->_getPath($dest, $name)));
}
}
if ($this->isFolder($path, $name)) {
$this->_copyRecursive($path, $name, $dest);
} else {
try {
$this->write($dest, $name, $this->readFile($path, $name));
} catch (Horde_Vfs_Exception $e) {
throw new Horde_Vfs_Exception(sprintf('Copy failed: %s', $this->_getPath($dest, $name)));
}
}
}
/**
* Moves a file through the backend.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $dest The destination of the file.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function move($path, $name, $dest, $autocreate = false)
{
$orig = $this->_getPath($path, $name);
if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
throw new Horde_Vfs_Exception('Cannot copy file(s) - destination is within source.');
}
if ($autocreate) {
$this->autocreatePath($dest);
}
foreach ($this->listFolder($dest, null, true) as $file) {
if ($file['name'] == $name) {
throw new Horde_Vfs_Exception(sprintf('%s already exists.', $this->_getPath($dest, $name)));
}
}
try {
$this->rename($path, $name, $dest, $name);
} catch (Horde_Vfs_Exception $e) {
throw new Horde_Vfs_Exception(sprintf('Failed to move to "%s".', $this->_getPath($dest, $name)));
}
}
/**
* Returns the full path of a directory.
*
* @param string $path The directory.
*
* @return string Full path to the directory.
*/
protected function _getNativePath($path)
{
if (isset($this->_params['vfsroot']) &&
strlen($this->_params['vfsroot'])) {
if (strlen($path)) {
$path = $this->_params['vfsroot'] . '/' . $path;
} else {
$path = $this->_params['vfsroot'];
}
}
// In some samba versions after samba-3.0.25-pre2, $path must
// end in a trailing slash.
if (substr($path, -1) != '/') {
$path .= '/';
}
return $path;
}
/**
* Replacement for escapeshellcmd(), variable length args, as we only want
* certain characters escaped.
*
* @param array $array Strings to escape.
*
* @return array TODO
*/
protected function _escapeShellCommand()
{
$ret = array();
$args = func_get_args();
foreach ($args as $arg) {
$ret[] = str_replace(array(';', '\\'), array('\;', '\\\\'), $arg);
}
return $ret;
}
/**
* Executes a command and returns output lines in array.
*
* @param string $cmd Command to be executed.
*
* @return array Array on success.
* @throws Horde_Vfs_Exception
*/
protected function _execute($cmd)
{
$cmd = str_replace('"-U%"', '-N', $cmd);
$proc = proc_open(
$cmd,
array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')),
$pipes);
if (!is_resource($proc)) {
// This should never happen.
throw new Horde_Vfs_Exception('Failed to call proc_open().');
}
$out = explode("\n", trim(stream_get_contents($pipes[1])));
$error = explode("\n", trim(stream_get_contents($pipes[2])));
$ret = proc_close($proc);
// In some cases, (like trying to delete a nonexistant file),
// smbclient will return success (at least on 2.2.7 version I'm
// testing on). So try to match error strings, even after success.
if ($ret != 0) {
$err = '';
foreach ($error as $line) {
if (strpos($line, 'Usage:') === 0) {
$err = 'Command syntax incorrect';
break;
}
if (strpos($line, 'ERRSRV') !== false ||
strpos($line, 'ERRDOS') !== false) {
$err = preg_replace('/.*\((.+)\).*/', '\\1', $line);
if (!$err) {
$err = $line;
}
break;
}
}
if (!$err) {
$err = $out ? $out[count($out) - 1] : $ret;
}
throw new Horde_Vfs_Exception($err);
}
// Check for errors even on success.
$err = '';
foreach ($out as $line) {
if (strpos($line, 'NT_STATUS_NO_SUCH_FILE') !== false ||
strpos($line, 'NT_STATUS_OBJECT_NAME_NOT_FOUND') !== false) {
$err = Horde_Vfs_Translation::t("No such file");
break;
} elseif (strpos($line, 'NT_STATUS_ACCESS_DENIED') !== false) {
$err = Horde_Vfs_Translation::t("Permission Denied");
break;
}
}
if ($err) {
throw new Horde_Vfs_Exception($err);
}
return $out;
}
/**
* Executes SMB commands - without authentication - and returns output
* lines in array.
*
* @param array $path Base path for command.
* @param array $cmd Commands to be executed.
*
* @return array Array on success.
* @throws Horde_Vfs_Exception
*/
protected function _command($path, $cmd)
{
$share_parts = explode('/', $this->_params['share']);
list($share) = $this->_escapeShellCommand(array_shift($share_parts));
if ($share_parts) {
$path = implode('/', $share_parts) . '/' . $path;
}
putenv('PASSWD=' . $this->_params['password']);
$port = isset($this->_params['port'])
? (' "-p' . $this->_params['port'] . '"')
: '';
$ipoption = isset($this->_params['ipaddress'])
? (' -I ' . $this->_params['ipaddress'])
: '';
$domain = isset($this->_params['domain'])
? (' -W ' . $this->_params['domain'])
: '';
$fullcmd = $this->_params['smbclient'] .
' "//' . $this->_params['hostspec'] . '/' . $share . '"' .
$port .
' "-U' . $this->_params['username'] . '"' .
' -D "' . $path . '" ' .
$ipoption .
$domain .
' -c "';
foreach ($cmd as $c) {
$fullcmd .= $c . ";";
}
$fullcmd .= '"';
return $this->_execute($fullcmd);
}
/**
* Authenticates a user on the SMB server and share.
*
* @throws Horde_Vfs_Exception
*/
protected function _connect()
{
try {
$this->_command('', array('quit'));
} catch (Horde_Vfs_Exception $e) {
throw new Horde_Vfs_Exception('Authentication to the SMB server failed.');
}
}
/**
* Creates the vfsroot.
*/
protected function _createRoot()
{
if ($this->_rootCreated) {
return;
}
if (!empty($this->_params['vfsroot'])) {
$path = '';
foreach (explode('/', $this->_params['vfsroot']) as $dir) {
try {
$this->_command($path . $dir, array());
} catch (Horde_Vfs_Exception $e) {
try {
$this->_command($path, array('mkdir \"' . $dir . '\"'));
} catch (Horde_Vfs_Exception $e) {
throw new Horde_Vfs_Exception(sprintf('Unable to create VFS root directory "%s".', $this->_params['vfsroot']));
}
}
$path .= '/' . $dir;
}
}
$this->_rootCreated = true;
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Sql.php 0000664 0001750 0001750 00000062654 12654104000 015322 0 ustar jan jan
* @author Jan Schneider
* @category Horde
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package VFS
*/
class Horde_Vfs_Sql extends Horde_Vfs_Base
{
/* File value for vfs_type column. */
const FILE = 1;
/* Folder value for vfs_type column. */
const FOLDER = 2;
/**
* Handle for the current database connection.
*
* @var Horde_Db
*/
protected $_db = false;
/**
* List of permissions and if they can be changed in this VFS backend.
*
* @var array
*/
protected $_permissions = array();
/**
* List of features that the VFS driver supports.
*
* @var array
*/
protected $_features = array(
'readByteRange' => true,
);
/**
* Constructor.
*
* @param array $params A hash containing connection parameters.
*/
public function __construct($params = array())
{
$params = array_merge(array('table' => 'horde_vfs'), $params);
parent::__construct($params);
$this->_db = $this->_params['db'];
unset($this->_params['db']);
}
/**
* Retrieves the filesize from the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return integer The file size.
* @throws Horde_Vfs_Exception
*/
public function size($path, $name)
{
$length_op = $this->_getFileSizeOp();
$path = $this->_convertPath($path);
list($op, $values) = $this->_nullString($path);
$sql = sprintf(
'SELECT %s(vfs_data) FROM %s WHERE vfs_path %s AND vfs_name = ?',
$length_op,
$this->_params['table'],
$op
);
$values[] = $name;
try {
$size = $this->_db->selectValue($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if ($size === false) {
throw new Horde_Vfs_Exception(sprintf('Unable to check file size of "%s/%s".', $path, $name));
}
return $size;
}
/**
* Returns the size of a folder.
*
* @param string $path The path of the folder.
*
* @return integer The size of the folder in bytes.
* @throws Horde_Vfs_Exception
*/
public function getFolderSize($path = null)
{
try {
$where = null;
$params = array();
if (strlen($path)) {
$where = 'WHERE vfs_path = ? OR vfs_path LIKE ?';
$path = $this->_convertPath($path);
$params = array($path, $path . '/%');
}
$sql = sprintf('SELECT SUM(%s(vfs_data)) FROM %s %s',
$this->_getFileSizeOp(),
$this->_params['table'],
$where);
$size = $this->_db->selectValue($sql, $params);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
return (int)$size;
}
/**
* Retrieves a file from the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return string The file data.
* @throws Horde_Vfs_Exception
*/
public function read($path, $name)
{
return $this->_readBlob($this->_params['table'], 'vfs_data', array(
'vfs_path' => $this->_convertPath($path),
'vfs_name' => $name
));
}
/**
* Retrieves a part of a file from the VFS. Particularly useful
* when reading large files which would exceed the PHP memory
* limits if they were stored in a string.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
* @param integer $offset The offset of the part. (The new offset will
* be stored in here).
* @param integer $length The length of the part. If the length = -1,
* the whole part after the offset is
* retrieved. If more bytes are given as exists
* after the given offset. Only the available
* bytes are read.
* @param integer $remaining The bytes that are left, after the part that
* is retrieved.
*
* @return string The file data.
* @throws Horde_Vfs_Exception
*/
public function readByteRange($path, $name, &$offset, $length, &$remaining)
{
$data = $this->_readBlob($this->_params['table'], 'vfs_data', array(
'vfs_path' => $this->_convertPath($path),
'vfs_name' => $name
));
// Calculate how many bytes MUST be read, so the remainging
// bytes and the new offset can be calculated correctly.
$size = strlen ($data);
if ($length == -1 || (($length + $offset) > $size)) {
$length = $size - $offset;
}
if ($remaining < 0) {
$remaining = 0;
}
$data = substr($data, $offset, $length);
$offset = $offset + $length;
$remaining = $size - $offset;
return $data;
}
/**
* Stores a file in the VFS.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $tmpFile The temporary file containing the data to
* be stored.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function write($path, $name, $tmpFile, $autocreate = false)
{
/* Don't need to check quota here since it will be checked when
* writeData() is called. */
return $this->writeData($path,
$name,
file_get_contents($tmpFile),
$autocreate);
}
/**
* Store a file in the VFS from raw data.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $data The file data.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function writeData($path, $name, $data, $autocreate = false)
{
$this->_checkQuotaWrite('string', $data, $path, $name);
$path = $this->_convertPath($path);
list($op, $values) = $this->_nullString($path);
/* Check to see if the data already exists. */
try {
$sql = sprintf(
'SELECT vfs_id FROM %s WHERE vfs_path %s AND vfs_name = ?',
$this->_params['table'],
$op
);
$values[] = $name;
$id = $this->_db->selectValue($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if ($id) {
$this->_updateBlob($this->_params['table'], 'vfs_data', $data,
array('vfs_id' => $id),
array('vfs_modified' => time()));
return;
}
/* Check to see if the folder already exists. */
$dirs = explode('/', $path);
$path_name = array_pop($dirs);
$parent = implode('/', $dirs);
if (!$this->isFolder($parent, $path_name)) {
if (!$autocreate) {
throw new Horde_Vfs_Exception(sprintf('Folder "%s" does not exist', $path));
}
$this->autocreatePath($path);
}
return $this->_insertBlob($this->_params['table'], 'vfs_data', $data, array(
'vfs_type' => self::FILE,
'vfs_path' => strlen($path) ? $path : null,
'vfs_name' => $name,
'vfs_modified' => time(),
'vfs_owner' => $this->_params['user']
));
}
/**
* Delete a file from the VFS.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
*
* @throws Horde_Vfs_Exception
*/
public function deleteFile($path, $name)
{
$this->_checkQuotaDelete($path, $name);
$path = $this->_convertPath($path);
list($op, $values) = $this->_nullString($path);
try {
$sql = sprintf(
'DELETE FROM %s WHERE vfs_type = ? AND vfs_path %s AND vfs_name = ?',
$this->_params['table'],
$op
);
array_unshift($values, self::FILE);
array_push($values, $name);
$result = $this->_db->delete($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if ($result == 0) {
throw new Horde_Vfs_Exception('Unable to delete VFS file.');
}
}
/**
* Rename a file or folder in the VFS.
*
* @param string $oldpath The old path to the file.
* @param string $oldname The old filename.
* @param string $newpath The new path of the file.
* @param string $newname The new filename.
*
* @throws Horde_Vfs_Exception
*/
public function rename($oldpath, $oldname, $newpath, $newname)
{
if (strpos($newpath, '/') === false) {
$parent = '';
$path = $newpath;
} else {
list($parent, $path) = explode('/', $newpath, 2);
}
if (!$this->isFolder($parent, $path)) {
$this->autocreatePath($newpath);
}
$oldpath = $this->_convertPath($oldpath);
$newpath = $this->_convertPath($newpath);
if (!strlen($newpath)) {
$newpath = null;
}
list($op, $values) = $this->_nullString($oldpath);
$sql = sprintf(
'UPDATE %s SET vfs_path = ?, vfs_name = ?, vfs_modified = ? WHERE vfs_path %s AND vfs_name = ?',
$this->_params['table'],
$op
);
$values = array_merge(
array($newpath, $newname, time()),
$values,
array($oldname)
);
try {
$result = $this->_db->update($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if ($result == 0) {
throw new Horde_Vfs_Exception('Unable to rename VFS file.');
}
$this->_recursiveRename($oldpath, $oldname, $newpath, $newname);
}
/**
* Creates a folder on the VFS.
*
* @param string $path Holds the path of directory to create folder.
* @param string $name Holds the name of the new folder.
*
* @throws Horde_Vfs_Exception
*/
public function createFolder($path, $name)
{
$path = $this->_convertPath($path);
if (!strlen($path)) {
$path = null;
}
$sql = sprintf(
'INSERT INTO %s (vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner) VALUES (?, ?, ?, ?, ?)',
$this->_params['table']
);
$values = array(self::FOLDER, $path, $name, time(), $this->_params['user'] ?: null);
try {
$this->_db->insert($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
* Horde_Vfs_Sql override of isFolder() to check for root folder.
*
* @param string $path Path to possible folder
* @param string $name Name of possible folder
*
* @return boolean True if $path/$name is a folder
*/
public function isFolder($path, $name)
{
$path = $this->_convertPath($path);
if ($path == '' && $name == '') {
// The root of VFS is always a folder.
return true;
}
$path = $this->_getNativePath($path, $name);
$name = basename($path);
$path = dirname($path);
if ($path == '.') {
$path = '';
}
list($op, $values) = $this->_nullString($path);
try {
return (bool)$this->_db->selectValue(
sprintf(
'SELECT 1 FROM %s WHERE vfs_type = ? AND vfs_path %s AND vfs_name = ?',
$this->_params['table'],
$op
),
array_merge(array(self::FOLDER), $values, array($name))
);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
* Delete a folder from the VFS.
*
* @param string $path The path of the folder.
* @param string $name The folder name to use.
* @param boolean $recursive Force a recursive delete?
*
* @throws Horde_Vfs_Exception
*/
public function deleteFolder($path, $name, $recursive = false)
{
$path = $this->_convertPath($path);
$folderPath = $this->_getNativePath($path, $name);
/* Check if not recursive and fail if directory not empty */
if (!$recursive) {
$folderList = $this->listFolder($folderPath, null, true);
if (!empty($folderList)) {
throw new Horde_Vfs_Exception(sprintf('Unable to delete %s, the directory is not empty', $path . '/' . $name));
}
}
/* Remember the size of the folder. */
if (!is_null($this->_vfsSize)) {
$size = $this->getFolderSize($folderPath);
}
/* First delete everything below the folder, so if error we get no
* orphans. */
try {
$sql = sprintf('DELETE FROM %s WHERE vfs_path %s',
$this->_params['table'],
' LIKE ' . $this->_db->quote($this->_getNativePath($folderPath, '%')));
$this->_db->delete($sql);
} catch (Horde_Db_Exception $e) {
$this->_vfsSize = null;
throw new Horde_Vfs_Exception('Unable to delete VFS recursively: ' . $e->getMessage());
}
/* Now delete everything inside the folder. */
list ($op, $values) = $this->_nullString($folderPath);
try {
$sql = sprintf(
'DELETE FROM %s WHERE vfs_path %s',
$this->_params['table'],
$op
);
$this->_db->delete($sql, $values);
} catch (Horde_Db_Exception $e) {
$this->_vfsSize = null;
throw new Horde_Vfs_Exception('Unable to delete VFS directory: ' . $e->getMessage());
}
/* All ok now delete the actual folder */
list($op, $values) = $this->_nullString($path);
try {
$sql = sprintf(
'DELETE FROM %s WHERE vfs_path %s AND vfs_name = ?',
$this->_params['table'],
$op
);
$values[] = $name;
$this->_db->delete($sql, $values);
} catch (Horde_Db_Exception $e) {
$this->_vfsSize = null;
throw new Horde_Vfs_Exception('Unable to delete VFS directory: ' . $e->getMessage());
}
/* Update VFS size. */
if (!is_null($this->_vfsSize)) {
$this->_vfsSize -= $size;
}
}
/**
* Returns an an unsorted file list of the specified directory.
*
* @param string $path The path of the directory.
* @param string|array $filter Regular expression(s) to filter
* file/directory name on.
* @param boolean $dotfiles Show dotfiles?
* @param boolean $dironly Show only directories?
*
* @return array File list.
* @throws Horde_Vfs_Exception
*/
protected function _listFolder($path, $filter = null, $dotfiles = true,
$dironly = false)
{
if (!$this->isFolder(dirname($path), basename($path))) {
throw new Horde_Vfs_Exception(sprintf('"%s" is not a folder.', $path));
}
$path = $this->_convertPath($path);
list($op, $values) = $this->_nullString($path);
try {
$length_op = $this->_getFileSizeOp();
$sql = sprintf(
'SELECT vfs_name, vfs_type, %s(vfs_data) length, vfs_modified, vfs_owner FROM %s WHERE vfs_path %s',
$length_op,
$this->_params['table'],
$op
);
$fileList = $this->_db->select($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
$files = array();
foreach ($fileList as $line) {
// Filter out dotfiles if they aren't wanted.
if (!$dotfiles && substr($line['vfs_name'], 0, 1) == '.') {
continue;
}
$file['name'] = $line['vfs_name'];
if ($line['vfs_type'] == self::FILE) {
$name = explode('.', $line['vfs_name']);
if (count($name) == 1) {
$file['type'] = '**none';
} else {
$file['type'] = Horde_String::lower($name[count($name) - 1]);
}
$file['size'] = $line['length'];
} elseif ($line['vfs_type'] == self::FOLDER) {
$file['type'] = '**dir';
$file['size'] = -1;
}
$file['date'] = $line['vfs_modified'];
$file['owner'] = isset($line['vfs_owner']) ? $line['vfs_owner'] : '';
$file['perms'] = '';
$file['group'] = '';
// filtering
if ($this->_filterMatch($filter, $file['name'])) {
unset($file);
continue;
}
if ($dironly && $file['type'] !== '**dir') {
unset($file);
continue;
}
$files[$file['name']] = $file;
unset($file);
}
return $files;
}
/**
* Garbage collect files in the VFS storage system.
*
* @param string $path The VFS path to clean.
* @param integer $secs The minimum amount of time (in seconds) required
* before a file is removed.
*
* @throws Horde_Vfs_Exception
*/
public function gc($path, $secs = 345600)
{
$path = $this->_convertPath($path);
list($op, $values) = $this->_nullString($path);
$sql = sprintf(
'DELETE FROM %s WHERE vfs_type = ? AND vfs_modified < ? AND (vfs_path %s OR vfs_path LIKE ?)',
$this->_params['table'],
$op
);
$values = array_merge(
array(self::FILE, time() - $secs),
$values,
array($path . '/%')
);
try {
$this->_db->delete($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
* Renames all child paths.
*
* @param string $path The path of the folder to rename.
* @param string $name The foldername to use.
*
* @throws Horde_Vfs_Exception
*/
protected function _recursiveRename($oldpath, $oldname, $newpath, $newname)
{
$oldpath = $this->_convertPath($oldpath);
$newpath = $this->_convertPath($newpath);
$sql = sprintf(
'SELECT vfs_name FROM %s WHERE vfs_type = ? AND vfs_path = ?',
$this->_params['table']
);
$values = array(self::FOLDER, $this->_getNativePath($oldpath, $oldname));
try {
$folderList = $this->_db->selectValues($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
foreach ($folderList as $folder) {
$this->_recursiveRename($this->_getNativePath($oldpath, $oldname), $folder, $this->_getNativePath($newpath, $newname), $folder);
}
$sql = sprintf(
'UPDATE %s SET vfs_path = ? WHERE vfs_path = ?',
$this->_params['table']
);
$values = array(
$this->_getNativePath($newpath, $newname),
$this->_getNativePath($oldpath, $oldname)
);
try {
$this->_db->update($sql, $values);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
* Return a full filename on the native filesystem, from a VFS
* path and name.
*
* @param string $path The VFS file path.
* @param string $name The VFS filename.
*
* @return string The full native filename.
*/
protected function _getNativePath($path, $name)
{
if (!strlen($path)) {
return $name;
}
if (isset($this->_params['home']) &&
preg_match('|^~/?(.*)$|', $path, $matches)) {
$path = $this->_params['home'] . '/' . $matches[1];
}
return $path . '/' . $name;
}
/**
* Read file data from the SQL VFS backend.
*
* @param string $table The VFS table name.
* @param string $field TODO
* @param array $criteria TODO
*
* @return mixed TODO
* @throws Horde_Vfs_Exception
*/
protected function _readBlob($table, $field, $criteria)
{
if (!count($criteria)) {
throw new Horde_Vfs_Exception('You must specify the fetch criteria');
}
$where = '';
foreach ($criteria as $key => $value) {
if (!empty($where)) {
$where .= ' AND ';
}
$where .= $key . ' = ' . $this->_db->quote($value);
}
$sql = sprintf('SELECT %s FROM %s WHERE %s',
$field, $table, $where);
try {
$result = $this->_db->selectValue($sql);
$columns = $this->_db->columns($table);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
if ($result === false) {
throw new Horde_Vfs_Exception('Unable to load SQL data.');
}
return $columns[$field]->binaryToString($result);
}
/**
* TODO
*
* @param string $table TODO
* @param string $field TODO
* @param string $data TODO
* @param string $attributes TODO
*
* @return mixed TODO
* @throws Horde_Vfs_Exception
*/
protected function _insertBlob($table, $field, $data, $attributes)
{
$attributes[$field] = new Horde_Db_Value_Binary($data);
/* Execute the query. */
try {
$this->_db->insertBlob($table, $attributes);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
* TODO
*
* @param string $table TODO
* @param string $field TODO
* @param string $data TODO
* @param string $where TODO
* @param array $alsoupdate TODO
*
* @return mixed TODO
* @throws Horde_Vfs_Exception
*/
protected function _updateBlob($table, $field, $data, $where, $alsoupdate)
{
$wherestring = '';
$wherevalues = array();
foreach ($where as $key => $value) {
if (!empty($wherestring)) {
$wherestring .= ' AND ';
}
$wherestring .= $key . ' = ?';
$wherevalues[] = $value;
}
/* Execute the query. */
try {
$this->_db->updateBlob(
$table,
array_merge(
$alsoupdate,
array($field => new Horde_Db_Value_Binary($data))
),
array($wherestring, $wherevalues)
);
} catch (Horde_Db_Exception $e) {
throw new Horde_Vfs_Exception($e);
}
}
/**
* Converts the path name from regular filesystem form to the internal
* format needed to access the file in the database.
*
* Namely, we will treat '/' as a base directory as this is pretty much
* the standard way to access base directories over most filesystems.
*
* @param string $path A VFS path.
*
* @return string The path with any surrouding slashes stripped off.
*/
protected function _convertPath($path)
{
return trim($path, '/');
}
/**
* TODO
*
* @return string TODO
*/
protected function _getFileSizeOp()
{
switch ($this->_db->adapterName()) {
case 'PostgreSQL':
case 'PDO_PostgreSQL':
return 'OCTET_LENGTH';
default:
return 'LENGTH';
}
}
/**
* Returns a comparison for a possibly empty string.
*
* Returns IS NULL instead of an equals operator if the string is empty.
*
* @param string $value A string.
*
* @return array
*/
protected function _nullString($value)
{
return strlen($value)
? array('= ?', array($value))
: array('IS NULL', array());
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/SqlFile.php 0000664 0001750 0001750 00000051452 12654104000 016114 0 ustar jan jan
* db - (DB) The DB object.
* vfsroot - (string) The root directory of where the files should be
* actually stored.
*
* Optional values:
* table - (string) The name of the vfs table in 'database'. Defaults to
* 'horde_vfs'.
*
* The table structure for the VFS can be found in data/vfs.sql.
*
* @author Michael Varghese
* @category Horde
* @package VFS
*/
class Horde_Vfs_SqlFile extends Horde_Vfs_File
{
/* File value for vfs_type column. */
const FILE = 1;
/* Folder value for vfs_type column. */
const FOLDER = 2;
/**
* Handle for the current database connection.
*
* @var DB
*/
protected $_db = false;
/**
* Constructor.
*
* @param array $params A hash containing connection parameters.
*/
public function __construct($params = array())
{
throw new Horde_Vfs_Exception('The SqlFile VFS driver needs to be refactored to a real composite driver.');
}
/**
* Store a file in the VFS, with the data copied from a temporary
* file.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $tmpFile The temporary file containing the data to be
* stored.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function write($path, $name, $tmpFile, $autocreate = false)
{
/* No need to check quota here as we will check it when we call
* writeData(). */
$data = file_get_contents($tmpFile);
return $this->writeData($path, $name, $data, $autocreate);
}
/**
* Store a file in the VFS from raw data.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $data The file data.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function writeData($path, $name, $data, $autocreate = false)
{
$this->_checkQuotaWrite('string', $data, $path, $name);
$fp = @fopen($this->_getNativePath($path, $name), 'w');
if (!$fp) {
if ($autocreate) {
$this->autocreatePath($path);
$fp = @fopen($this->_getNativePath($path, $name), 'w');
if (!$fp) {
throw new Horde_Vfs_Exception('Unable to open VFS file for writing.');
}
} else {
throw new Horde_Vfs_Exception('Unable to open VFS file for writing.');
}
}
if (!@fwrite($fp, $data)) {
throw new Horde_Vfs_Exception('Unable to write VFS file data.');
}
if ($this->_writeSQLData($path, $name) instanceof PEAR_Error) {
@unlink($this->_getNativePath($path, $name));
throw new Horde_Vfs_Exception('Unable to write VFS file data.');
}
}
/**
* Moves a file in the database and the file system.
*
* @param string $path The path to store the file in.
* @param string $name The old filename.
* @param string $dest The new filename.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function move($path, $name, $dest, $autocreate = false)
{
$orig = $this->_getNativePath($path, $name);
if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
throw new Horde_Vfs_Exception('Cannot move file(s) - destination is within source.');
}
if ($autocreate) {
$this->autocreatePath($dest);
}
foreach ($this->listFolder($dest, null, false) as $file) {
if ($file['name'] == $name) {
throw new Horde_Vfs_Exception('Unable to move VFS file.');
}
}
if (strpos($dest, $this->_getSQLNativePath($path, $name)) !== false) {
throw new Horde_Vfs_Exception('Unable to move VFS file.');
}
$this->rename($path, $name, $dest, $name);
}
/**
* Copies a file through the backend.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $dest The destination of the file.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function copy($path, $name, $dest, $autocreate = false)
{
$this->_checkDestination($path, $dest);
$this->_connect();
if ($autocreate) {
$this->autocreatePath($dest);
}
foreach ($this->listFolder($dest, null, false) as $file) {
if ($file['name'] == $name) {
throw new Horde_Vfs_Exception('Unable to copy VFS file.');
}
}
if (strpos($dest, $this->_getSQLNativePath($path, $name)) !== false) {
throw new Horde_Vfs_Exception('Unable to copy VFS file.');
}
if (is_dir($orig)) {
return $this->_recursiveCopy($path, $name, $dest);
}
$this->_checkQuotaWrite('file', $orig, $dest, $name);
if (!@copy($orig, $this->_getNativePath($dest, $name))) {
throw new Horde_Vfs_Exception('Unable to copy VFS file.');
}
$id = $this->_db->nextId($this->_params['table']);
$query = sprintf('INSERT INTO %s (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner) VALUES (?, ?, ?, ?, ?, ?)',
$this->_params['table']);
$values = array($id, self::FILE, $dest, $name, time(), $this->_params['user']);
$result = $this->_db->query($query, $values);
if ($result instanceof PEAR_Error) {
unlink($this->_getNativePath($dest, $name));
throw new Horde_Vfs_Exception($result->getMessage());
}
}
/**
* Creates a folder on the VFS.
*
* @param string $path Holds the path of directory to create folder.
* @param string $name Holds the name of the new folder.
*
* @throws Horde_Vfs_Exception
*/
public function createFolder($path, $name)
{
$this->_connect();
$id = $this->_db->nextId($this->_params['table']);
$result = $this->_db->query(sprintf('INSERT INTO %s (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner)
VALUES (?, ?, ?, ?, ?, ?)',
$this->_params['table']),
array($id, self::FOLDER, $path, $name, time(), $this->_params['user']));
if ($result instanceof PEAR_Error) {
throw new Horde_Vfs_Exception($result->getMessage());
}
if (!@mkdir($this->_getNativePath($path, $name))) {
$result = $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_id = ?',
$this->_params['table']),
array($id));
throw new Horde_Vfs_Exception('Unable to create VFS directory.');
}
}
/**
* Rename a file or folder in the VFS.
*
* @param string $oldpath The old path to the file.
* @param string $oldname The old filename.
* @param string $newpath The new path of the file.
* @param string $newname The new filename.
*
* @throws Horde_Vfs_Exception
*/
public function rename($oldpath, $oldname, $newpath, $newname)
{
$this->_connect();
if (strpos($newpath, '/') === false) {
$parent = '';
$path = $newpath;
} else {
list($parent, $path) = explode('/', $newpath, 2);
}
if (!$this->isFolder($parent, $path)) {
$this->autocreatePath($newpath);
}
$this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?, vfs_modified = ? WHERE vfs_path = ? AND vfs_name = ?', $this->_params['table']), array($newpath, $newname, time(), $oldpath, $oldname));
if ($this->_db->affectedRows() == 0) {
throw new Horde_Vfs_Exception('Unable to rename VFS file.');
}
if (is_a($this->_recursiveSQLRename($oldpath, $oldname, $newpath, $newname), 'PEAR_Error')) {
$this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ? WHERE vfs_path = ? AND vfs_name = ?', $this->_params['table']), array($oldpath, $oldname, $newpath, $newname));
throw new Horde_Vfs_Exception('Unable to rename VFS directory.');
}
if (!@is_dir($this->_getNativePath($newpath))) {
$this->autocreatePath($newpath);
}
if (!@rename($this->_getNativePath($oldpath, $oldname), $this->_getNativePath($newpath, $newname))) {
$this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ? WHERE vfs_path = ? AND vfs_name = ?', $this->_params['table']), array($oldpath, $oldname, $newpath, $newname));
return PEAR::raiseError(Horde_Vfs_Translation::t("Unable to rename VFS file."));
}
}
/**
* Delete a folder from the VFS.
*
* @param string $path The path to delete the folder from.
* @param string $name The foldername to use.
* @param boolean $recursive Force a recursive delete?
*
* @throws Horde_Vfs_Exception
*/
public function deleteFolder($path, $name, $recursive = false)
{
$this->_connect();
if ($recursive) {
$this->emptyFolder($path . '/' . $name);
} else {
$list = $this->listFolder($path . '/' . $name);
if (count($list)) {
throw new Horde_Vfs_Exception(sprintf('Unable to delete %s, the directory is not empty', $path . '/' . $name));
}
}
$result = $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ? AND vfs_name = ?', $this->_params['table']), array(self::FOLDER, $path, $name));
if ($this->_db->affectedRows() == 0 || ($result instanceof PEAR_Error)) {
throw new Horde_Vfs_Exception('Unable to delete VFS directory.');
}
if ($this->_recursiveSQLDelete($path, $name) instanceof PEAR_Error ||
$this->_recursiveLFSDelete($path, $name) instanceof PEAR_Error) {
throw new Horde_Vfs_Exception('Unable to delete VFS directory recursively.');
}
}
/**
* Delete a file from the VFS.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
*
* @throws Horde_Vfs_Exception
*/
public function deleteFile($path, $name)
{
$this->_checkQuotaDelete($path, $name);
$this->_connect();
$result = $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ? AND vfs_name = ?',
$this->_params['table']),
array(self::FILE, $path, $name));
if ($this->_db->affectedRows() == 0) {
throw new Horde_Vfs_Exception('Unable to delete VFS file.');
}
if ($result instanceof PEAR_Error) {
throw new Horde_Vfs_Exception($result->getMessage());
}
if (!@unlink($this->_getNativePath($path, $name))) {
throw new Horde_Vfs_Exception('Unable to delete VFS file.');
}
}
/**
* Returns an unsorted file list of the specified directory.
*
* @param string $path The path of the directory.
* @param string|array $filter Regular expression(s) to filter
* file/directory name on.
* @param boolean $dotfiles Show dotfiles?
* @param boolean $dironly Show only directories?
*
* @return array File list.
* @throws Horde_Vfs_Exception
*/
protected function _listFolder($path, $filter = null, $dotfiles = true,
$dironly = false)
{
$this->_connect();
$files = array();
$fileList = $this->_db->getAll(sprintf('SELECT vfs_name, vfs_type, vfs_modified, vfs_owner FROM %s
WHERE vfs_path = ?',
$this->_params['table']),
array($path));
if ($fileList instanceof PEAR_Error) {
throw new Horde_Vfs_Exception($fileList->getMessage());
}
foreach ($fileList as $line) {
// Filter out dotfiles if they aren't wanted.
if (!$dotfiles && substr($line[0], 0, 1) == '.') {
continue;
}
$file['name'] = $line[0];
if ($line[1] == self::FILE) {
$name = explode('.', $line[0]);
if (count($name) == 1) {
$file['type'] = '**none';
} else {
$file['type'] = Horde_String::lower($name[count($name) - 1]);
}
$file['size'] = filesize($this->_getNativePath($path, $line[0]));
} elseif ($line[1] == self::FOLDER) {
$file['type'] = '**dir';
$file['size'] = -1;
}
$file['date'] = $line[2];
$file['owner'] = $line[3];
$file['perms'] = '';
$file['group'] = '';
// Filtering.
if ($this->_filterMatch($filter, $file['name'])) {
unset($file);
continue;
}
if ($dironly && $file['type'] !== '**dir') {
unset($file);
continue;
}
$files[$file['name']] = $file;
unset($file);
}
return $files;
}
/**
* Recursively copies the contents of a folder to a destination.
*
* @param string $path The path to store the directory in.
* @param string $name The name of the directory.
* @param string $dest The destination of the directory.
*
* @throws Horde_Vfs_Exception
*/
protected function _recursiveCopy($path, $name, $dest)
{
$this->createFolder($dest, $name);
$file_list = $this->listFolder($this->_getSQLNativePath($path, $name));
foreach ($file_list as $file) {
$this->copy($this->_getSQLNativePath($path, $name), $file['name'], $this->_getSQLNativePath($dest, $name));
}
}
/**
* Store a files information within the database.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
*
* @throws Horde_Vfs_Exception
*/
protected function _writeSQLData($path, $name)
{
$this->_connect();
// File already exists in database
if ($this->exists($path, $name)) {
$query = 'UPDATE ' . $this->_params['table'] .
' SET vfs_modified = ?' .
' WHERE vfs_path = ? AND vfs_name = ?';
$values = array(time(), $path, $name);
} else {
$id = $this->_db->nextId($this->_params['table']);
$query = 'INSERT INTO ' . $this->_params['table'] .
' (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified,' .
' vfs_owner) VALUES (?, ?, ?, ?, ?, ?)';
$values = array($id, self::FILE, $path, $name, time(),
$this->_params['user']);
}
return $this->_db->query($query, $values);
}
/**
* Renames all child paths.
*
* @param string $oldpath The old path of the folder to rename.
* @param string $oldname The old name.
* @param string $newpath The new path of the folder to rename.
* @param string $newname The new name.
*
* @throws Horde_Vfs_Exception
*/
protected function _recursiveSQLRename($oldpath, $oldname, $newpath,
$newname)
{
$folderList = $this->_db->getCol(sprintf('SELECT vfs_name FROM %s WHERE vfs_type = ? AND vfs_path = ?',
$this->_params['table']),
0,
array(self::FOLDER, $this->_getSQLNativePath($oldpath, $oldname)));
foreach ($folderList as $folder) {
$this->_recursiveSQLRename($this->_getSQLNativePath($oldpath, $oldname), $folder, $this->_getSQLNativePath($newpath, $newname), $folder);
}
$result = $this->_db->query(sprintf('UPDATE %s SET vfs_path = ? WHERE vfs_path = ?',
$this->_params['table']),
array($this->_getSQLNativePath($newpath, $newname),
$this->_getSQLNativePath($oldpath, $oldname)));
if ($result instanceof PEAR_Error) {
throw new Horde_Vfs_Exception($result->getMessage());
}
}
/**
* Delete a folders contents from the VFS in the SQL database,
* recursively.
*
* @param string $path The path of the folder.
* @param string $name The foldername to use.
*
* @throws Horde_Vfs_Exception
*/
protected function _recursiveSQLDelete($path, $name)
{
$result = $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ?', $this->_params['table']), array(self::FILE, $this->_getSQLNativePath($path, $name)));
if ($result instanceof PEAR_Error) {
throw new Horde_Vfs_Exception($result->getMessage());
}
$folderList = $this->_db->getCol(sprintf('SELECT vfs_name FROM %s WHERE vfs_type = ? AND vfs_path = ?', $this->_params['table']), 0, array(self::FOLDER, $this->_getSQLNativePath($path, $name)));
foreach ($folderList as $folder) {
$this->_recursiveSQLDelete($this->_getSQLNativePath($path, $name), $folder);
}
$this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_name = ? AND vfs_path = ?', $this->_params['table']), array(self::FOLDER, $name, $path));
}
/**
* Delete a folders contents from the VFS, recursively.
*
* @param string $path The path of the folder.
* @param string $name The foldername to use.
*
* @throws Horde_Vfs_Exception
*/
protected function _recursiveLFSDelete($path, $name)
{
$dir = $this->_getNativePath($path, $name);
$dh = @opendir($dir);
while (false !== ($file = readdir($dh))) {
if ($file != '.' && $file != '..') {
if (is_dir($dir . '/' . $file)) {
$this->_recursiveLFSDelete(!strlen($path) ? $name : $path . '/' . $name, $file);
} else {
@unlink($dir . '/' . $file);
}
}
}
@closedir($dh);
rmdir($dir);
}
/**
* Attempts to open a persistent connection to the SQL server.
*
* @throws Horde_Vfs_Exception
*/
protected function _connect()
{
if ($this->_db !== false) {
return;
}
$required = array('db', 'vfsroot');
foreach ($required as $val) {
if (!isset($this->_params[$val])) {
throw new Horde_Vfs_Exception(sprintf('Required "%s" not specified in VFS configuration.', $val));
}
}
$this->_params = array_merge(array(
'table' => 'horde_vfs',
), $this->_params);
$this->_db = $this->_params['db'];
}
/**
* Return a full filename on the native filesystem, from a VFS
* path and name.
*
* @param string $path The VFS file path.
* @param string $name The VFS filename.
*
* @return string The full native filename.
*/
protected function _getNativePath($path, $name)
{
if (strlen($name)) {
$name = '/' . $name;
}
if (strlen($path)) {
if (isset($this->_params['home']) &&
preg_match('|^~/?(.*)$|', $path, $matches)) {
$path = $this->_params['home'] . '/' . $matches[1];
}
return $this->_params['vfsroot'] . '/' . $path . $name;
}
return $this->_params['vfsroot'] . $name;
}
/**
* Return a full SQL filename on the native filesystem, from a VFS
* path and name.
*
* @param string $path The VFS file path.
* @param string $name The VFS filename.
*
* @return string The full native filename.
*/
protected function _getSQLNativePath($path, $name)
{
return strlen($path)
? $path . '/' . $name
: $name;
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Ssh2.php 0000664 0001750 0001750 00000071716 12654104000 015401 0 ustar jan jan
* username - (string) The username with which to connect to the ssh2 server.
* password - (string) The password with which to connect to the ssh2 server.
* hostspec - (string) The ssh2 server to connect to.
*
* Optional values for $params:
* port - (integer) The port used to connect to the ssh2 server if other than
* 22.
*
* Copyright 2006-2016 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @editor Cliff Green
* @package Vfs
*/
class Horde_Vfs_Ssh2 extends Horde_Vfs_Base
{
/**
* List of additional credentials required for this VFS backend.
*
* @var array
*/
protected $_credentials = array('username', 'password');
/**
* List of permissions and if they can be changed in this VFS backend.
*
* @var array
*/
protected $_permissions = array(
'owner' => array(
'read' => true,
'write' => true,
'execute' => true
),
'group' => array(
'read' => true,
'write' => true,
'execute' => true
),
'all' => array(
'read' => true,
'write' => true,
'execute' => true
)
);
/**
* Variable holding the connection to the ssh2 server.
*
* @var resource
*/
protected $_stream = false;
/**
* The SFTP resource stream.
*
* @var resource
*/
protected $_sftp;
/**
* The current working directory.
*
* @var string
*/
protected $_cwd;
/**
* Local cache array for user IDs.
*
* @var array
*/
protected $_uids = array();
/**
* Local cache array for group IDs.
*
* @var array
*/
protected $_gids = array();
/**
* Returns the size of a file.
*
* @param string $path The path of the file.
* @param string $name The filename.
*
* @return integer The size of the file in bytes.
* @throws Horde_Vfs_Exception
*/
public function size($path, $name)
{
$this->_connect();
$statinfo = @ssh2_sftp_stat($this->_sftp, $this->_getPath($path, $name));
if (($size = $statinfo['size']) === false) {
throw new Horde_Vfs_Exception(sprintf('Unable to check file size of "%s".', $this->_getPath($path, $name)));
}
return $size;
}
/**
* Retrieves a file from the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return string The file data.
* @throws Horde_Vfs_Exception
*/
public function read($path, $name)
{
$file = $this->readFile($path, $name);
clearstatcache();
return (filesize($file) === 0)
? ''
: file_get_contents($file);
}
/**
* Retrieves a file from the VFS as an on-disk local file.
*
* This function provides a file on local disk with the data of a VFS file
* in it. This file cannot be modified! The behavior if you do
* modify it is undefined. It will be removed at the end of the request.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return string A local filename.
* @throws Horde_Vfs_Exception
*/
public function readFile($path, $name)
{
$this->_connect();
// Create a temporary file and register it for deletion at the
// end of this request.
if (!($localFile = Horde_Util::getTempFile('vfs'))) {
throw new Horde_Vfs_Exception('Unable to create temporary file.');
}
if (!$this->_recv($this->_getPath($path, $name), $localFile)) {
throw new Horde_Vfs_Exception(sprintf('Unable to open VFS file "%s".', $this->_getPath($path, $name)));
}
return $localFile;
}
/**
* Open a stream to a file in the VFS.
*
* @param string $path The pathname to the file.
* @param string $name The filename to retrieve.
*
* @return resource The stream.
* @throws Horde_Vfs_Exception
*/
public function readStream($path, $name)
{
$stream = @fopen($this->_wrap($this->_getPath($path, $name)), 'r');
if (!is_resource($stream)) {
throw new Horde_Vfs_Exception('Unable to open VFS file.');
}
return $stream;
}
/**
* Stores a file in the VFS.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $tmpFile The temporary file containing the data to
* be stored.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function write($path, $name, $tmpFile, $autocreate = false)
{
$this->_connect();
$this->_checkQuotaWrite('file', $tmpFile, $path, $name);
if (!$this->_send($tmpFile, $this->_getPath($path, $name))) {
if ($autocreate) {
$this->autocreatePath($path);
if ($this->_send($tmpFile, $this->_getPath($path, $name))) {
return;
}
}
throw new Horde_Vfs_Exception(sprintf('Unable to write VFS file "%s".', $this->_getPath($path, $name)));
}
}
/**
* Stores a file in the VFS from raw data.
*
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $data The file data.
* @param boolean $autocreate Automatically create directories?
*
* @throws Horde_Vfs_Exception
*/
public function writeData($path, $name, $data, $autocreate = false)
{
$tmpFile = Horde_Util::getTempFile('vfs');
file_put_contents($tmpFile, $data);
clearstatcache();
$this->write($path, $name, $tmpFile, $autocreate);
}
/**
* Deletes a file from the VFS.
*
* @param string $path The path to delete the file from.
* @param string $name The filename to delete.
*
* @throws Horde_Vfs_Exception
*/
public function deleteFile($path, $name)
{
$this->_checkQuotaDelete($path, $name);
$this->_connect();
if (!@ssh2_sftp_unlink($this->_sftp, $this->_getPath($path, $name))) {
throw new Horde_Vfs_Exception(sprintf('Unable to delete VFS file "%s".', $this->_getPath($path, $name)));
}
}
/**
* Checks if a given item is a folder.
*
* @param string $path The parent folder.
* @param string $name The item name.
*
* @return boolean True if it is a folder, false otherwise.
*/
public function isFolder($path, $name)
{
try {
$this->_connect();
} catch (Horde_Vfs_Exception $e) {
return false;
}
/* See if we can stat the remote filename. ANDed with 040000 is true
* if it is a directory. */
$statinfo = @ssh2_sftp_stat($this->_sftp, $this->_getPath($path, $name));
return $statinfo['mode'] & 040000;
}
/**
* Deletes a folder from the VFS.
*
* @param string $path The parent folder.
* @param string $name The name of the folder to delete.
* @param boolean $recursive Force a recursive delete?
*
* @throws Horde_Vfs_Exception
*/
public function deleteFolder($path, $name, $recursive = false)
{
$this->_connect();
$isDir = false;
foreach ($this->listFolder($path) as $file) {
if ($file['name'] == $name && $file['type'] == '**dir') {
$isDir = true;
break;
}
}
if ($isDir) {
$file_list = $this->listFolder($path . '/' . $name);
if (count($file_list) && !$recursive) {
throw new Horde_Vfs_Exception(sprintf('Unable to delete "%s", the directory is not empty.', $this->_getPath($path, $name)));
}
foreach ($file_list as $file) {
if ($file['type'] == '**dir') {
$this->deleteFolder($path . '/' . $name, $file['name'], $recursive);
} else {
$this->deleteFile($path . '/' . $name, $file['name']);
}
}
if (!@ssh2_sftp_rmdir($this->_sftp, $this->_getPath($path, $name))) {
throw new Horde_Vfs_Exception(sprintf('Cannot remove directory "%s".', $this->_getPath($path, $name)));
}
} else {
if (!@ssh2_sftp_unlink($this->_sftp, $this->_getPath($path, $name))) {
throw new Horde_Vfs_Exception(sprintf('Cannot delete file "%s".', $this->_getPath($path, $name)));
}
}
}
/**
* Renames a file in the VFS.
*
* @param string $oldpath The old path to the file.
* @param string $oldname The old filename.
* @param string $newpath The new path of the file.
* @param string $newname The new filename.
*
* @throws Horde_Vfs_Exception
*/
public function rename($oldpath, $oldname, $newpath, $newname)
{
$this->_connect();
$this->autocreatePath($newpath);
if (!@ssh2_sftp_rename($this->_sftp, $this->_getPath($oldpath, $oldname), $this->_getPath($newpath, $newname))) {
throw new Horde_Vfs_Exception(sprintf('Unable to rename VFS file "%s".', $this->_getPath($oldpath, $oldname)));
}
}
/**
* Creates a folder on the VFS.
*
* @param string $path The parent folder.
* @param string $name The name of the new folder.
*
* @throws Horde_Vfs_Exception
*/
public function createFolder($path, $name)
{
$this->_connect();
if (!@ssh2_sftp_mkdir($this->_sftp, $this->_getPath($path, $name))) {
throw new Horde_Vfs_Exception(sprintf('Unable to create VFS directory "%s".', $this->_getPath($path, $name)));
}
}
/**
* Changes permissions for an item on the VFS.
*
* @param string $path The parent folder of the item.
* @param string $name The name of the item.
* @param string $permission The permission to set in octal notation.
*
* @throws Horde_Vfs_Exception
*/
public function changePermissions($path, $name, $permission)
{
$this->_connect();
$full = $this->_getPath($path, $name);
if (!@ssh2_sftp_chmod($this->_sftp, $full, octdec($permission))) {
throw new Horde_Vfs_Exception(sprintf('Unable to change permission for VFS file "%s".', $full));
}
}
/**
* Returns an unsorted file list of the specified directory.
*
* @param string $path The path of the directory.
* @param string|array $filter Regular expression(s) to filter
* file/directory name on.
* @param boolean $dotfiles Show dotfiles?
* @param boolean $dironly Show only directories?
*
* @return array File list.
* @throws Horde_Vfs_Exception
*/
protected function _listFolder($path = '', $filter = null,
$dotfiles = true, $dironly = false)
{
$this->_connect();
$files = array();
/* If 'maplocalids' is set, check for the POSIX extension. */
$mapids = (!empty($this->_params['maplocalids']) && extension_loaded('posix'));
// THIS IS A PROBLEM.... there is no builtin systype() fn for SSH2.
// Go with unix-style listings for now...
$type = 'unix';
$olddir = $this->getCurrentDirectory();
$path = $this->_getPath('', $path);
if (strlen($path)) {
$this->_setPath($path);
}
if ($type == 'unix') {
$ls_args = 'l';
// Get numeric ids if we're going to use posix_* functions to
// map them.
if ($mapids) {
$ls_args .= 'n';
}
// If we don't want dotfiles, We can save work here by not doing
// an ls -a and then not doing the check later (by setting
// $dotfiles to true, the if is short-circuited).
if ($dotfiles) {
$ls_args .= 'a';
$dotfiles = true;
}
$stream = @ssh2_exec(
$this->_stream,
'ls -' . $ls_args . ' ' . escapeshellarg($path),
null,
array('LC_TIME' => 'C'));
} else {
$stream = @ssh2_exec($this->_stream, '');
}
stream_set_blocking($stream, true);
$errstream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
if ($error = stream_get_contents($errstream)) {
fclose($errstream);
fclose($stream);
throw new Horde_Vfs_Exception($error);
}
unset($list);
while (!feof($stream)) {
$line = fgets($stream);
if ($line === false) {
break;
}
$list[] = trim($line);
}
fclose($errstream);
fclose($stream);
if (!is_array($list)) {
if (isset($olddir)) {
$this->_setPath($olddir);
}
return array();
}
$currtime = time();
foreach ($list as $line) {
$file = array();
$item = preg_split('/\s+/', $line);
if (($type == 'unix') ||
(($type == 'win') &&
!preg_match('|\d\d-\d\d-\d\d|', $item[0]))) {
if ((count($item) < 8) || (substr($line, 0, 5) == 'total')) {
continue;
}
$file['perms'] = $item[0];
if ($mapids) {
if (!isset($this->_uids[$item[2]])) {
$entry = posix_getpwuid($item[2]);
$this->_uids[$item[2]] = (empty($entry)) ? $item[2] : $entry['name'];
}
$file['owner'] = $this->_uids[$item[2]];
if (!isset($this->_uids[$item[3]])) {
$entry = posix_getgrgid($item[3]);
$this->_uids[$item[3]] = (empty($entry)) ? $item[3] : $entry['name'];
}
$file['group'] = $this->_uids[$item[3]];
} else {
$file['owner'] = $item[2];
$file['group'] = $item[3];
}
// /dev file systems may have an additional column.
$addcol = 0;
if (substr($item[4], -1) == ',') {
$addcol = 1;
}
$file['name'] = substr($line, strpos($line, sprintf("%s %2s %5s", $item[5 + $addcol], $item[6 + $addcol], $item[7 + $addcol])) + 13);
// Filter out '.' and '..' entries.
if (preg_match('/^\.\.?\/?$/', $file['name'])) {
continue;
}
// Filter out dotfiles if they aren't wanted.
if (!$dotfiles && (substr($file['name'], 0, 1) == '.')) {
continue;
}
$p1 = substr($file['perms'], 0, 1);
if ($p1 === 'l') {
$file['link'] = substr($file['name'], strpos($file['name'], '->') + 3);
$file['name'] = substr($file['name'], 0, strpos($file['name'], '->') - 1);
$file['type'] = '**sym';
if ($this->isFolder('', $file['link'])) {
$file['linktype'] = '**dir';
} else {
$parts = explode('/', $file['link']);
$name = explode('.', array_pop($parts));
if ((count($name) == 1) ||
(($name[0] === '') && (count($name) == 2))) {
$file['linktype'] = '**none';
} else {
$file['linktype'] = Horde_String::lower(array_pop($name));
}
}
} elseif ($p1 === 'd') {
$file['type'] = '**dir';
} else {
$name = explode('.', $file['name']);
if ((count($name) == 1) ||
((substr($file['name'], 0, 1) === '.') &&
(count($name) == 2))) {
$file['type'] = '**none';
} else {
$file['type'] = Horde_String::lower($name[count($name) - 1]);
}
}
if ($file['type'] == '**dir') {
$file['size'] = -1;
} else {
$file['size'] = $item[4 + $addcol];
}
if (strpos($item[7 + $addcol], ':') !== false) {
$file['date'] = strtotime($item[7 + $addcol] . ':00' . $item[5 + $addcol] . ' ' . $item[6 + $addcol] . ' ' . date('Y', $currtime));
// If the ssh2 server reports a file modification date more
// less than one day in the future, don't try to subtract
// a year from the date. There is no way to know, for
// example, if the VFS server and the ssh2 server reside
// in different timezones. We should simply report to the
// user what the SSH2 server is returning.
if ($file['date'] > ($currtime + 86400)) {
$file['date'] = strtotime($item[7 + $addcol] . ':00' . $item[5 + $addcol] . ' ' . $item[6 + $addcol] . ' ' . (date('Y', $currtime) - 1));
}
} else {
$file['date'] = strtotime('00:00:00' . $item[5 + $addcol] . ' ' . $item[6 + $addcol] . ' ' . $item[7 + $addcol]);
}
} elseif ($type == 'netware') {
$file = array();
$file['perms'] = $item[1];
$file['owner'] = $item[2];
if ($item[0] == 'd') {
$file['type'] = '**dir';
} else {
$file['type'] = '**none';
}
$file['size'] = $item[3];
$file['name'] = $item[7];
for ($index = 8, $c = count($item); $index < $c; $index++) {
$file['name'] .= ' ' . $item[$index];
}
} else {
/* Handle Windows SSH2 servers returning DOS-style file
* listings. */
$file['perms'] = '';
$file['owner'] = '';
$file['group'] = '';
$file['name'] = $item[3];
for ($index = 4, $c = count($item); $index < $c; $index++) {
$file['name'] .= ' ' . $item[$index];
}
$file['date'] = strtotime($item[0] . ' ' . $item[1]);
if ($item[2] == '') {
$file['type'] = '**dir';
$file['size'] = -1;
} else {
$file['size'] = $item[2];
$name = explode('.', $file['name']);
if ((count($name) == 1) ||
((substr($file['name'], 0, 1) === '.') &&
(count($name) == 2))) {
$file['type'] = '**none';
} else {
$file['type'] = Horde_String::lower($name[count($name) - 1]);
}
}
}
// Filtering.
if ($this->_filterMatch($filter, $file['name'])) {
unset($file);
continue;
}
if ($dironly && $file['type'] !== '**dir') {
unset($file);
continue;
}
$files[$file['name']] = $file;
unset($file);
}
if (isset($olddir)) {
$this->_setPath($olddir);
}
return $files;
}
/**
* Returns if a given file or folder exists in a folder.
*
* @param string $path The path to the folder.
* @param string $name The file or folder name.
*
* @return boolean True if it exists, false otherwise.
*/
public function exists($path, $name)
{
$this->_connect();
return @ssh2_sftp_stat($this->_sftp, $this->_getPath($path, $name)) !== false;
}
/**
* Copies a file through the backend.
*
* @param string $path The path of the original file.
* @param string $name The name of the original file.
* @param string $dest The name of the destination directory.
* @param boolean $autocreate Auto-create the directory if it doesn't
* exist?
*
* @throws Horde_Vfs_Exception
*/
public function copy($path, $name, $dest, $autocreate = false)
{
$this->_checkDestination($path, $dest);
$this->_connect();
if ($autocreate) {
$this->autocreatePath($dest);
}
foreach ($this->listFolder($dest, null, true) as $file) {
if ($file['name'] == $name) {
throw new Horde_Vfs_Exception(sprintf('%s already exists.', $this->_getPath($dest, $name)));
}
}
if ($this->isFolder($path, $name)) {
$this->_copyRecursive($path, $name, $dest);
} else {
$tmpFile = Horde_Util::getTempFile('vfs');
if (!$this->_recv($this->_getPath($path, $name), $tmpFile)) {
throw new Horde_Vfs_Exception(sprintf('Failed to copy from "%s".', $this->_getPath($path, $name)));
}
clearstatcache();
$this->_checkQuotaWrite('file', $tmpFile, $dest, $name);
if (!$this->_send($tmpFile, $this->_getPath($dest, $name))) {
throw new Horde_Vfs_Exception(sprintf('Failed to copy to "%s".', $this->_getPath($dest, $name)));
}
}
}
/**
* Moves a file through the backend.
*
* @param string $path The path of the original file.
* @param string $name The name of the original file.
* @param string $dest The destination file name.
* @param boolean $autocreate Auto-create the directory if it doesn't
* exist?
*
* @throws Horde_Vfs_Exception
*/
public function move($path, $name, $dest, $autocreate = false)
{
$orig = $this->_getPath($path, $name);
if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
throw new Horde_Vfs_Exception('Cannot move file(s) - destination is within source.');
}
$this->_connect();
if ($autocreate) {
$this->autocreatePath($dest);
}
foreach ($this->listFolder($dest, null, true) as $file) {
if ($file['name'] == $name) {
throw new Horde_Vfs_Exception(sprintf('%s already exists.', $this->_getPath($dest, $name)));
}
}
if (!@ssh2_sftp_rename($this->_sftp, $orig, $this->_getPath($dest, $name))) {
throw new Horde_Vfs_Exception(sprintf('Failed to move to "%s".', $this->_getPath($dest, $name)));
}
}
/**
* Returns the current working directory on the SSH2 server.
*
* @return string The current working directory.
* @throws Horde_Vfs_Exception
*/
public function getCurrentDirectory()
{
$this->_connect();
if (!strlen($this->_cwd)) {
$stream = @ssh2_exec($this->_stream, 'pwd');
stream_set_blocking($stream, true);
$this->_cwd = trim(fgets($stream));
}
return $this->_cwd;
}
/**
* Changes the current directory on the server.
*
* @param string $path The path to change to.
*
* @throws Horde_Vfs_Exception
*/
protected function _setPath($path)
{
if (!($stream = @ssh2_exec($this->_stream, 'cd ' . escapeshellarg($path) . '; pwd'))) {
throw new Horde_Vfs_Exception(sprintf('Unable to change to %s.', $path));
}
stream_set_blocking($stream, true);
$this->_cwd = trim(fgets($stream));
fclose($stream);
}
/**
* Returns the full path of an item.
*
* @param string $path The directory of the item.
* @param string $name The name of the item.
*
* @return mixed Full path to the file when $path is not empty and just
* $name when not set.
*/
protected function _getPath($path, $name)
{
if (isset($this->_params['vfsroot']) &&
strlen($this->_params['vfsroot'])) {
if (strlen($path)) {
$path = $this->_params['vfsroot'] . '/' . $path;
} else {
$path = $this->_params['vfsroot'];
}
}
return parent::_getPath($path, $name);
}
/**
* Returns the parent directory of the specified path.
*
* @param string $path The path to get the parent of.
*
* @return string The parent directory.
* @throws Horde_Vfs_Exception
*/
protected function _parentDir($path)
{
$this->_connect();
$this->_setPath('cd ' . $path . '/..');
return $this->getCurrentDirectory();
}
/**
* Attempts to open a connection to the SSH2 server.
*
* @throws Horde_Vfs_Exception
*/
protected function _connect()
{
if ($this->_stream !== false) {
return;
}
if (!extension_loaded('ssh2')) {
throw new Horde_Vfs_Exception('The SSH2 PECL extension is not available.');
}
if (!is_array($this->_params)) {
throw new Horde_Vfs_Exception('No configuration information specified for SSH2 VFS.');
}
$required = array('hostspec', 'username', 'password');
foreach ($required as $val) {
if (!isset($this->_params[$val])) {
throw new Horde_Vfs_Exception(sprintf('Required "%s" not specified in VFS configuration.', $val));
}
}
/* Connect to the ssh2 server using the supplied parameters. */
if (empty($this->_params['port'])) {
$this->_stream = @ssh2_connect($this->_params['hostspec']);
} else {
$this->_stream = @ssh2_connect($this->_params['hostspec'], $this->_params['port']);
}
if (!$this->_stream) {
$this->_stream = false;
throw new Horde_Vfs_Exception('Connection to SSH2 server failed.');
}
if (!@ssh2_auth_password($this->_stream, $this->_params['username'], $this->_params['password'])) {
$this->_stream = false;
throw new Horde_Vfs_Exception('Authentication to SSH2 server failed.');
}
/* Create sftp resource. */
$this->_sftp = @ssh2_sftp($this->_stream);
if (!empty($this->_params['vfsroot']) &&
!@ssh2_sftp_stat($this->_sftp, $this->_params['vfsroot']) &&
!@ssh2_sftp_mkdir($this->_sftp, $this->_params['vfsroot'])) {
throw new Horde_Vfs_Exception(sprintf('Unable to create VFS root directory "%s".', $this->_params['vfsroot']));
}
}
/**
* Sends local file to remote host.
*
* This function exists because the ssh2_scp_send function doesn't seem to
* work on some hosts.
*
* @param string $local Full path to the local file.
* @param string $remote Full path to the remote location.
*
* @return boolean Success.
*/
protected function _send($local, $remote)
{
return @copy($local, $this->_wrap($remote));
}
/**
* Receives file from remote host.
*
* This function exists because the ssh2_scp_recv function doesn't seem to
* work on some hosts.
*
* @param string $local Full path to the local file.
* @param string $remote Full path to the remote location.
*
* @return boolean Success.
*/
protected function _recv($remote, $local)
{
return @copy($this->_wrap($remote), $local);
}
/**
* Generate a stream wrapper file spec for a remote file path
*
* @param string $remote Full path to the remote location
*
* @return string A full stream wrapper path to the remote location
*/
protected function _wrap($remote)
{
$wrapper = 'ssh2.sftp://' . $this->_params['username'] . ':'
. $this->_params['password'] . '@' . $this->_params['hostspec'];
if (!empty($this->_params['port'])) {
$wrapper .= ':' . $this->_params['port'];
}
if ($remote{0} != '/') {
$remote = $this->getCurrentDirectory() . '/' . $remote;
}
return $wrapper . $remote;
}
}
Horde_Vfs-2.3.1/lib/Horde/Vfs/Translation.php 0000664 0001750 0001750 00000001351 12654104000 017044 0 ustar jan jan
* @package Vfs
*/
class Horde_Vfs_Translation extends Horde_Translation_Autodetect
{
/**
* The translation domain
*
* @var string
*/
protected static $_domain = 'Horde_Vfs';
/**
* The absolute PEAR path to the translations for the default gettext handler.
*
* @var string
*/
protected static $_pearDirectory = '@data_dir@';
}
Horde_Vfs-2.3.1/lib/Horde/Vfs.php 0000664 0001750 0001750 00000002606 12654104000 014552 0 ustar jan jan
* @package Vfs
*/
class Horde_Vfs
{
/* Quota constants. */
const QUOTA_METRIC_BYTE = 1;
const QUOTA_METRIC_KB = 2;
const QUOTA_METRIC_MB = 3;
const QUOTA_METRIC_GB = 4;
/**
* Attempts to return a concrete instance based on $driver.
*
* @deprecated
*
* @param mixed $driver The type of concrete subclass to return. This
* is based on the storage driver ($driver). The
* code is dynamically included.
* @param array $params A hash containing any additional configuration or
* connection parameters a subclass might need.
*
* @return VFS The newly created concrete VFS instance.
* @throws Horde_Vfs_Exception
*/
public static function factory($driver, $params = array())
{
$class = 'Horde_Vfs_' . basename(Horde_String::ucfirst($driver));
if (class_exists($class)) {
return new $class($params);
}
throw new Horde_Vfs_Exception('Class definition of ' . $class . ' not found.');
}
}
Horde_Vfs-2.3.1/locale/ar/LC_MESSAGES/Horde_Vfs.mo 0000664 0001750 0001750 00000000572 12654104000 017336 0 ustar jan jan $ , 8 @ 9 Project-Id-Version: Horde_VFS
Report-Msgid-Bugs-To: dev@lists.horde.org
POT-Creation-Date: 2010-10-13 01:27+0200
PO-Revision-Date: 2010-10-13 01:27+0200
Last-Translator: Automatically generated
Language-Team: i18n@lists.horde.org
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Horde_Vfs-2.3.1/locale/ar/LC_MESSAGES/Horde_Vfs.po 0000664 0001750 0001750 00000001531 12654104000 017335 0 ustar jan jan # Arabic translations for Horde_VFS module.
# Copyright 2010-2016 Horde LLC (http://www.horde.org/)
# This file is distributed under the same license as the Horde_VFS module.
# Automatically generated, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: Horde_VFS\n"
"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
"POT-Creation-Date: 2010-10-13 01:27+0200\n"
"PO-Revision-Date: 2010-10-13 01:27+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: i18n@lists.horde.org\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: lib/VFS/smb.php:573
msgid "No such file"
msgstr ""
#: lib/VFS/smb.php:576
msgid "Permission Denied"
msgstr ""
#: lib/VFS/sql_file.php:264
#, fuzzy
msgid "Unable to rename VFS file."
msgstr "لا توجد إمكانية لتغيير اسم ملف الـ VFS %s/%s."
Horde_Vfs-2.3.1/locale/bg/LC_MESSAGES/Horde_Vfs.mo 0000664 0001750 0001750 00000000572 12654104000 017324 0 ustar jan jan $ , 8 @ 9 Project-Id-Version: Horde_VFS
Report-Msgid-Bugs-To: dev@lists.horde.org
POT-Creation-Date: 2010-10-13 01:27+0200
PO-Revision-Date: 2010-10-13 01:27+0200
Last-Translator: Automatically generated
Language-Team: i18n@lists.horde.org
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Horde_Vfs-2.3.1/locale/bg/LC_MESSAGES/Horde_Vfs.po 0000664 0001750 0001750 00000001542 12654104000 017325 0 ustar jan jan # Bulgarian translations for Horde_VFS module.
# Copyright 2010-2016 Horde LLC (http://www.horde.org/)
# This file is distributed under the same license as the Horde_VFS module.
# Automatically generated, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: Horde_VFS\n"
"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
"POT-Creation-Date: 2010-10-13 01:27+0200\n"
"PO-Revision-Date: 2010-10-13 01:27+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: i18n@lists.horde.org\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: lib/VFS/smb.php:573
msgid "No such file"
msgstr ""
#: lib/VFS/smb.php:576
#, fuzzy
msgid "Permission Denied"
msgstr "Права"
#: lib/VFS/sql_file.php:264
#, fuzzy
msgid "Unable to rename VFS file."
msgstr "Грешка при четенето на vfsroot папка."
Horde_Vfs-2.3.1/locale/bs/LC_MESSAGES/Horde_Vfs.mo 0000664 0001750 0001750 00000000572 12654104000 017340 0 ustar jan jan $ , 8 @ 9 Project-Id-Version: Horde_VFS
Report-Msgid-Bugs-To: dev@lists.horde.org
POT-Creation-Date: 2010-10-13 01:27+0200
PO-Revision-Date: 2010-10-13 01:27+0200
Last-Translator: Automatically generated
Language-Team: i18n@lists.horde.org
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Horde_Vfs-2.3.1/locale/bs/LC_MESSAGES/Horde_Vfs.po 0000664 0001750 0001750 00000001427 12654104000 017343 0 ustar jan jan # Bosnian translations for Horde_VFS module.
# Copyright 2010-2016 Horde LLC (http://www.horde.org/)
# This file is distributed under the same license as the Horde_VFS module.
# Automatically generated, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: Horde_VFS\n"
"Report-Msgid-Bugs-To: dev@lists.horde.org\n"
"POT-Creation-Date: 2010-10-13 01:27+0200\n"
"PO-Revision-Date: 2010-10-13 01:27+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: i18n@lists.horde.org\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: lib/VFS/smb.php:573
msgid "No such file"
msgstr ""
#: lib/VFS/smb.php:576
#, fuzzy
msgid "Permission Denied"
msgstr "Dozvole"
#: lib/VFS/sql_file.php:264
msgid "Unable to rename VFS file."
msgstr ""
Horde_Vfs-2.3.1/locale/ca/LC_MESSAGES/Horde_Vfs.mo 0000664 0001750 0001750 00000001101 12654104000 017304 0 ustar jan jan <