2012-05-24 16:22:33 +00:00
< ? php
/**
* Copyright ( c ) 2012 Robin Appelman < icewind @ owncloud . com >
* This file is licensed under the Affero General Public License version 3 or
* later .
* See the COPYING - README file .
*/
2012-09-07 16:30:48 +00:00
namespace OC\Files\Storage ;
2013-08-18 17:14:14 +00:00
require_once __DIR__ . '/../3rdparty/smb4php/smb.php' ;
2012-05-24 16:22:33 +00:00
2012-09-07 16:30:48 +00:00
class SMB extends \OC\Files\Storage\StreamWrapper {
2012-05-24 16:22:33 +00:00
private $password ;
private $user ;
private $host ;
private $root ;
2012-06-07 23:29:46 +00:00
private $share ;
2012-05-24 16:22:33 +00:00
2013-03-08 17:15:20 +00:00
/**
* check if smbclient is installed
*/
public static function checkDependencies () {
if ( function_exists ( 'shell_exec' )) {
$output = shell_exec ( 'which smbclient' );
if ( ! empty ( $output )) {
return true ;
}
}
$l = new \OC_L10N ( 'files_external' );
2013-05-30 15:37:47 +00:00
return $l -> t ( '<b>Note:</b> "smbclient" is not installed. Mounting of CIFS/SMB shares is not possible. Please ask your system administrator to install it.' );
2013-03-08 17:15:20 +00:00
}
2012-09-07 13:22:01 +00:00
public function __construct ( $params ) {
2012-12-24 18:45:52 +00:00
if ( isset ( $params [ 'host' ]) && isset ( $params [ 'user' ]) && isset ( $params [ 'password' ]) && isset ( $params [ 'share' ])) {
$this -> host = $params [ 'host' ];
$this -> user = $params [ 'user' ];
$this -> password = $params [ 'password' ];
$this -> share = $params [ 'share' ];
$this -> root = isset ( $params [ 'root' ]) ? $params [ 'root' ] : '/' ;
if ( ! $this -> root || $this -> root [ 0 ] != '/' ) {
$this -> root = '/' . $this -> root ;
}
if ( substr ( $this -> root , - 1 , 1 ) != '/' ) {
$this -> root .= '/' ;
}
if ( ! $this -> share || $this -> share [ 0 ] != '/' ) {
$this -> share = '/' . $this -> share ;
}
if ( substr ( $this -> share , - 1 , 1 ) == '/' ) {
2013-02-20 00:12:14 +00:00
$this -> share = substr ( $this -> share , 0 , - 1 );
2012-12-24 18:45:52 +00:00
}
} else {
2014-03-18 20:15:11 +00:00
throw new \Exception ( 'Invalid configuration' );
2012-06-07 23:29:46 +00:00
}
2012-11-16 11:14:29 +00:00
}
2012-05-24 16:22:33 +00:00
2012-10-11 21:06:57 +00:00
public function getId (){
return 'smb::' . $this -> user . '@' . $this -> host . '/' . $this -> share . '/' . $this -> root ;
2012-05-24 16:22:33 +00:00
}
2012-09-07 13:22:01 +00:00
public function constructUrl ( $path ) {
2012-11-30 15:27:11 +00:00
if ( substr ( $path , - 1 ) == '/' ) {
2013-11-14 15:52:00 +00:00
$path = substr ( $path , 0 , - 1 );
2012-05-24 16:22:33 +00:00
}
2013-11-14 15:52:00 +00:00
if ( substr ( $path , 0 , 1 ) == '/' ) {
$path = substr ( $path , 1 );
}
// remove trailing dots which some versions of samba don't seem to like
$path = rtrim ( $path , '.' );
2013-02-11 20:25:29 +00:00
$path = urlencode ( $path );
2013-02-12 14:56:31 +00:00
$user = urlencode ( $this -> user );
$pass = urlencode ( $this -> password );
return 'smb://' . $user . ':' . $pass . '@' . $this -> host . $this -> share . $this -> root . $path ;
2012-06-17 00:54:23 +00:00
}
2012-09-07 13:22:01 +00:00
public function stat ( $path ) {
2012-11-30 15:27:11 +00:00
if ( ! $path and $this -> root == '/' ) { //mtime doesn't work for shares
2012-06-17 00:54:23 +00:00
$stat = stat ( $this -> constructUrl ( $path ));
2013-05-31 22:06:23 +00:00
if ( empty ( $stat )) {
return false ;
}
$mtime = $this -> shareMTime ();
2012-06-17 00:54:23 +00:00
$stat [ 'mtime' ] = $mtime ;
return $stat ;
2012-11-30 15:27:11 +00:00
} else {
2013-05-31 22:06:23 +00:00
$stat = stat ( $this -> constructUrl ( $path ));
// smb4php can return an empty array if the connection could not be established
if ( empty ( $stat )) {
return false ;
}
return $stat ;
2012-06-17 00:54:23 +00:00
}
}
2013-11-14 17:39:39 +00:00
/**
2013-11-29 11:58:57 +00:00
* Unlinks file or directory
2013-11-14 17:39:39 +00:00
* @ param string @ path
*/
public function unlink ( $path ) {
2013-11-29 11:58:57 +00:00
if ( $this -> is_dir ( $path )) {
$this -> rmdir ( $path );
}
else {
$url = $this -> constructUrl ( $path );
unlink ( $url );
clearstatcache ( false , $url );
}
2013-11-14 17:39:39 +00:00
// smb4php still returns false even on success so
// check here whether file was really deleted
return ! file_exists ( $path );
}
2012-06-17 00:54:23 +00:00
/**
* check if a file or folder has been updated since $time
2012-10-11 21:17:59 +00:00
* @ param string $path
2012-06-17 00:54:23 +00:00
* @ param int $time
* @ return bool
*/
2012-09-07 13:22:01 +00:00
public function hasUpdated ( $path , $time ) {
if ( ! $path and $this -> root == '/' ) {
2012-11-30 15:27:11 +00:00
// mtime doesn't work for shares, but giving the nature of the backend,
// doing a full update is still just fast enough
2012-06-17 00:54:23 +00:00
return true ;
2012-11-30 15:27:11 +00:00
} else {
2012-06-17 00:54:23 +00:00
$actualTime = $this -> filemtime ( $path );
return $actualTime > $time ;
}
}
/**
* get the best guess for the modification time of the share
*/
2012-09-07 13:22:01 +00:00
private function shareMTime () {
2012-06-17 00:54:23 +00:00
$dh = $this -> opendir ( '' );
$lastCtime = 0 ;
2013-09-04 11:06:04 +00:00
if ( is_resource ( $dh )) {
while (( $file = readdir ( $dh )) !== false ) {
if ( $file != '.' and $file != '..' ) {
$ctime = $this -> filemtime ( $file );
if ( $ctime > $lastCtime ) {
$lastCtime = $ctime ;
}
2012-06-17 00:54:23 +00:00
}
}
}
return $lastCtime ;
2012-05-24 16:22:33 +00:00
}
}