724 lines
23 KiB
PHP
724 lines
23 KiB
PHP
<?php
|
|
/**
|
|
* Codebase copyright 2002 Paul Gareau <paul@xhawk.net>. Adapted with
|
|
* permission by Patrice Levesque <wayne@ptaff.ca> 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 <paul@xhawk.net>
|
|
* @author Patrice Levesque <wayne@ptaff.ca>
|
|
* @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 <paul@xhawk.net>
|
|
* @author Patrice Levesque <wayne@ptaff.ca>
|
|
* @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');
|
|
|
|
/**
|
|
* Prefix to use for every path.
|
|
*
|
|
* Passed as a path suffix to the share parameter.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $_prefix = '';
|
|
|
|
/**
|
|
* Has the vfsroot already been created?
|
|
*
|
|
* @var boolean
|
|
*/
|
|
protected $_rootCreated = false;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param array $params A hash containing connection parameters.
|
|
*/
|
|
public function __construct($params = array())
|
|
{
|
|
parent::__construct($params);
|
|
if (!isset($this->_params['share'])) {
|
|
return;
|
|
}
|
|
$share_parts = explode('/', $this->_params['share']);
|
|
$this->_params['share'] = array_shift($share_parts);
|
|
if ($share_parts) {
|
|
$this->_prefix = implode('/', $share_parts);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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 <em>cannot</em> 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|resource $data The data as a string or stream resource.
|
|
* Resources allowed @since 2.4.0
|
|
* @param boolean $autocreate Automatically create directories?
|
|
*
|
|
* @throws Horde_Vfs_Exception
|
|
*/
|
|
public function writeData($path, $name, $data, $autocreate = false)
|
|
{
|
|
$tmpFile = Horde_Util::getTempFile('vfs');
|
|
if (is_resource($data)) {
|
|
rewind($data);
|
|
}
|
|
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)
|
|
{
|
|
$parts = array($path);
|
|
if (strlen($this->_prefix)) {
|
|
array_unshift($parts, $this->_prefix);
|
|
}
|
|
if (isset($this->_params['vfsroot']) &&
|
|
strlen($this->_params['vfsroot'])) {
|
|
array_unshift($parts, $this->_params['vfsroot']);
|
|
}
|
|
$path = implode('/', $parts);
|
|
|
|
// 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)
|
|
{
|
|
list($share) = $this->_escapeShellCommand($this->_params['share']);
|
|
|
|
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;
|
|
}
|
|
|
|
$root = trim($this->_params['vfsroot'] . '/' . $this->_prefix, '/');
|
|
$path = '';
|
|
foreach (explode('/', $root) 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) {
|
|
echo $e;
|
|
throw new Horde_Vfs_Exception(sprintf('Unable to create VFS root directory "%s".', $this->_params['vfsroot']));
|
|
}
|
|
}
|
|
$path .= '/' . $dir;
|
|
}
|
|
|
|
$this->_rootCreated = true;
|
|
}
|
|
}
|