mirror of
https://codeberg.org/icewind/SMB.git
synced 2026-06-03 17:24:07 +02:00
Improve locating file descriptors and smbclient/net commands
This commit is contained in:
parent
a07a5ad2ec
commit
b865f430d6
5 changed files with 100 additions and 18 deletions
|
|
@ -13,7 +13,8 @@
|
||||||
"icewind/streams": "0.2.*"
|
"icewind/streams": "0.2.*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"satooshi/php-coveralls" : "dev-master"
|
"satooshi/php-coveralls" : "dev-master",
|
||||||
|
"phpunit/phpunit": "^4.8"
|
||||||
},
|
},
|
||||||
"autoload" : {
|
"autoload" : {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ use Icewind\SMB\Exception\AuthenticationException;
|
||||||
use Icewind\SMB\Exception\InvalidHostException;
|
use Icewind\SMB\Exception\InvalidHostException;
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
const CLIENT = 'smbclient';
|
|
||||||
const LOCALE = 'en_US.UTF-8';
|
const LOCALE = 'en_US.UTF-8';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,6 +33,16 @@ class Server {
|
||||||
*/
|
*/
|
||||||
protected $workgroup;
|
protected $workgroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Icewind\SMB\System
|
||||||
|
*/
|
||||||
|
private $system;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var TimeZoneProvider
|
||||||
|
*/
|
||||||
|
private $timezoneProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the smbclient php extension is available
|
* Check if the smbclient php extension is available
|
||||||
*
|
*
|
||||||
|
|
@ -54,6 +63,8 @@ class Server {
|
||||||
$this->user = $user;
|
$this->user = $user;
|
||||||
$this->workgroup = $workgroup;
|
$this->workgroup = $workgroup;
|
||||||
$this->password = $password;
|
$this->password = $password;
|
||||||
|
$this->system = new System();
|
||||||
|
$this->timezoneProvider = new TimeZoneProvider($host, $this->system);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -115,8 +126,12 @@ class Server {
|
||||||
*/
|
*/
|
||||||
public function listShares() {
|
public function listShares() {
|
||||||
$workgroupArgument = ($this->workgroup) ? ' -W ' . escapeshellarg($this->workgroup) : '';
|
$workgroupArgument = ($this->workgroup) ? ' -W ' . escapeshellarg($this->workgroup) : '';
|
||||||
$command = Server::CLIENT . $workgroupArgument . ' --authentication-file=/proc/self/fd/3' .
|
$command = sprintf('%s %s --authentication-file=%s -gL %s',
|
||||||
' -gL ' . escapeshellarg($this->getHost());
|
$this->system->getSmbclientPath(),
|
||||||
|
$workgroupArgument,
|
||||||
|
System::getFD(3),
|
||||||
|
escapeshellarg($this->getHost())
|
||||||
|
);
|
||||||
$connection = new RawConnection($command);
|
$connection = new RawConnection($command);
|
||||||
$connection->writeAuthentication($this->getUser(), $this->getPassword());
|
$connection->writeAuthentication($this->getUser(), $this->getPassword());
|
||||||
$output = $connection->readAll();
|
$output = $connection->readAll();
|
||||||
|
|
@ -166,7 +181,6 @@ class Server {
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getTimeZone() {
|
public function getTimeZone() {
|
||||||
$command = 'net time zone -S ' . escapeshellarg($this->getHost());
|
return $this->timezoneProvider->get();
|
||||||
return exec($command);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@ class Share extends AbstractShare {
|
||||||
*/
|
*/
|
||||||
protected $parser;
|
protected $parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Icewind\SMB\System
|
||||||
|
*/
|
||||||
|
private $system;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Server $server
|
* @param Server $server
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
|
@ -42,7 +47,8 @@ class Share extends AbstractShare {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->server = $server;
|
$this->server = $server;
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
$this->parser = new Parser(new TimeZoneProvider($this->server->getHost()));
|
$this->system = new System();
|
||||||
|
$this->parser = new Parser(new TimeZoneProvider($this->server->getHost(), $this->system));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -55,9 +61,10 @@ class Share extends AbstractShare {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
|
||||||
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s',
|
$command = sprintf('%s %s --authentication-file=%s %s',
|
||||||
Server::CLIENT,
|
$this->system->getSmbclientPath(),
|
||||||
$workgroupArgument,
|
$workgroupArgument,
|
||||||
|
System::getFD(3),
|
||||||
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
|
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
|
||||||
);
|
);
|
||||||
$this->connection = new Connection($command);
|
$this->connection = new Connection($command);
|
||||||
|
|
@ -257,14 +264,15 @@ class Share extends AbstractShare {
|
||||||
// since returned stream is closed by the caller we need to create a new instance
|
// since returned stream is closed by the caller we need to create a new instance
|
||||||
// since we can't re-use the same file descriptor over multiple calls
|
// since we can't re-use the same file descriptor over multiple calls
|
||||||
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
|
||||||
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s',
|
$command = sprintf('%s %s --authentication-file=%s %s',
|
||||||
Server::CLIENT,
|
$this->system->getSmbclientPath(),
|
||||||
$workgroupArgument,
|
$workgroupArgument,
|
||||||
|
System::getFD(3),
|
||||||
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
|
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
|
||||||
);
|
);
|
||||||
$connection = new Connection($command);
|
$connection = new Connection($command);
|
||||||
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
|
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
|
||||||
$connection->write('get ' . $source . ' /proc/self/fd/5');
|
$connection->write('get ' . $source . ' ' . System::getFD(5));
|
||||||
$connection->write('exit');
|
$connection->write('exit');
|
||||||
$fh = $connection->getFileOutputStream();
|
$fh = $connection->getFileOutputStream();
|
||||||
stream_context_set_option($fh, 'file', 'connection', $connection);
|
stream_context_set_option($fh, 'file', 'connection', $connection);
|
||||||
|
|
@ -285,16 +293,17 @@ class Share extends AbstractShare {
|
||||||
// since returned stream is closed by the caller we need to create a new instance
|
// since returned stream is closed by the caller we need to create a new instance
|
||||||
// since we can't re-use the same file descriptor over multiple calls
|
// since we can't re-use the same file descriptor over multiple calls
|
||||||
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
|
$workgroupArgument = ($this->server->getWorkgroup()) ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : '';
|
||||||
$command = sprintf('%s %s --authentication-file=/proc/self/fd/3 %s',
|
$command = sprintf('%s %s --authentication-file=%s %s',
|
||||||
Server::CLIENT,
|
$this->system->getSmbclientPath(),
|
||||||
$workgroupArgument,
|
$workgroupArgument,
|
||||||
|
System::getFD(3),
|
||||||
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
|
escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)
|
||||||
);
|
);
|
||||||
$connection = new Connection($command);
|
$connection = new Connection($command);
|
||||||
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
|
$connection->writeAuthentication($this->server->getUser(), $this->server->getPassword());
|
||||||
$fh = $connection->getFileInputStream();
|
$fh = $connection->getFileInputStream();
|
||||||
|
|
||||||
$connection->write('put /proc/self/fd/4 ' . $target);
|
$connection->write('put ' . System::getFD(4) . ' ' . $target);
|
||||||
$connection->write('exit');
|
$connection->write('exit');
|
||||||
|
|
||||||
// use a close callback to ensure the upload is finished before continuing
|
// use a close callback to ensure the upload is finished before continuing
|
||||||
|
|
|
||||||
43
src/System.php
Normal file
43
src/System.php
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||||
|
* This file is licensed under the Licensed under the MIT license:
|
||||||
|
* http://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Icewind\SMB;
|
||||||
|
|
||||||
|
use Icewind\SMB\Exception\Exception;
|
||||||
|
|
||||||
|
class System {
|
||||||
|
private $smbclient;
|
||||||
|
|
||||||
|
private $net;
|
||||||
|
|
||||||
|
public static function getFD($num) {
|
||||||
|
$folders = [
|
||||||
|
'/proc/self/fd',
|
||||||
|
'/dev/fd'
|
||||||
|
];
|
||||||
|
foreach ($folders as $folder) {
|
||||||
|
if (file_exists($folder)) {
|
||||||
|
return $folder . '/' . $num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Exception('Cant find file descriptor path');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSmbclientPath() {
|
||||||
|
if (!$this->smbclient) {
|
||||||
|
$this->smbclient = trim(`which smbclient`);
|
||||||
|
}
|
||||||
|
return $this->smbclient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNetPath() {
|
||||||
|
if (!$this->net) {
|
||||||
|
$this->net = trim(`which net`);
|
||||||
|
}
|
||||||
|
return $this->net;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,16 +19,31 @@ class TimeZoneProvider {
|
||||||
private $timeZone;
|
private $timeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $host
|
* @var System
|
||||||
*/
|
*/
|
||||||
function __construct($host) {
|
private $system;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $host
|
||||||
|
* @param System $system
|
||||||
|
*/
|
||||||
|
function __construct($host, System $system) {
|
||||||
$this->host = $host;
|
$this->host = $host;
|
||||||
|
$this->system = $system;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get() {
|
public function get() {
|
||||||
if (!$this->timeZone) {
|
if (!$this->timeZone) {
|
||||||
$command = 'net time zone -S ' . escapeshellarg($this->host);
|
$net = $this->system->getNetPath();
|
||||||
|
if ($net) {
|
||||||
|
$command = sprintf('%s time zone -S %s',
|
||||||
|
$net,
|
||||||
|
escapeshellarg($this->host)
|
||||||
|
);
|
||||||
$this->timeZone = exec($command);
|
$this->timeZone = exec($command);
|
||||||
|
} else { // fallback to server timezone
|
||||||
|
$this->timeZone = date_default_timezone_get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $this->timeZone;
|
return $this->timeZone;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue