1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Copyright (c) 2014 Robin Appelman <[email protected]> |
4
|
|
|
* This file is licensed under the Licensed under the MIT license: |
5
|
|
|
* http://opensource.org/licenses/MIT |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace Icewind\SMB\Wrapped; |
9
|
|
|
|
10
|
|
|
use Icewind\SMB\AbstractServer; |
11
|
|
|
use Icewind\SMB\Exception\AuthenticationException; |
12
|
|
|
use Icewind\SMB\Exception\ConnectException; |
13
|
|
|
use Icewind\SMB\Exception\ConnectionException; |
14
|
|
|
use Icewind\SMB\Exception\InvalidHostException; |
15
|
|
|
use Icewind\SMB\IShare; |
16
|
|
|
use Icewind\SMB\System; |
17
|
|
|
|
18
|
|
|
class Server extends AbstractServer { |
19
|
|
|
/** |
20
|
|
|
* Check if the smbclient php extension is available |
21
|
|
|
* |
22
|
|
|
* @param System $system |
23
|
|
|
* @return bool |
24
|
|
|
*/ |
25
|
|
|
public static function available(System $system) { |
26
|
|
|
return $system->getSmbclientPath(); |
27
|
|
|
} |
28
|
|
|
|
29
|
15 |
|
private function getAuthFileArgument() { |
30
|
15 |
|
return '-U ' . $this->getAuth()->getUsername() . '%' . $this->getAuth()->getPassword(); |
31
|
|
|
if ($this->getAuth()->getUsername()) { |
|
|
|
|
32
|
|
|
return '--authentication-file=' . System::getFD(3); |
33
|
|
|
} else { |
34
|
|
|
return ''; |
35
|
|
|
} |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @return IShare[] |
40
|
|
|
* |
41
|
|
|
* @throws AuthenticationException |
42
|
|
|
* @throws InvalidHostException |
43
|
|
|
* @throws ConnectException |
44
|
|
|
*/ |
45
|
15 |
|
public function listShares() { |
46
|
15 |
|
$command = sprintf('%s %s %s -L %s', |
47
|
15 |
|
$this->system->getSmbclientPath(), |
48
|
15 |
|
$this->getAuthFileArgument(), |
49
|
15 |
|
$this->getAuth()->getExtraCommandLineArguments(), |
50
|
15 |
|
escapeshellarg('//' . $this->getHost()) |
51
|
5 |
|
); |
52
|
15 |
|
$connection = new RawConnection($command); |
53
|
15 |
|
$connection->writeAuthentication($this->getAuth()->getUsername(), $this->getAuth()->getPassword()); |
54
|
15 |
|
$connection->connect(); |
55
|
15 |
|
if (!$connection->isValid()) { |
56
|
|
|
throw new ConnectionException($connection->readLine()); |
57
|
|
|
} |
58
|
15 |
|
$output = $connection->readAll(); |
59
|
|
|
// sometimes we get an empty line first |
60
|
15 |
|
if (count($output) === 0) { |
61
|
6 |
|
$output = $connection->readAll(); |
62
|
2 |
|
} |
63
|
15 |
|
$parser = new Parser($this->timezoneProvider); |
64
|
|
|
|
65
|
15 |
|
if (isset($output[0])) { |
66
|
15 |
|
$parser->checkConnectionError($output[0]); |
67
|
2 |
|
} |
68
|
|
|
|
69
|
6 |
|
$shareNames = $parser->parseListShares($output); |
70
|
|
|
|
71
|
6 |
|
$shares = array(); |
72
|
6 |
|
foreach ($shareNames as $name => $description) { |
73
|
6 |
|
$shares[] = $this->getShare($name); |
74
|
2 |
|
} |
75
|
6 |
|
return $shares; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @param string $name |
80
|
|
|
* @return IShare |
81
|
|
|
*/ |
82
|
768 |
|
public function getShare($name) { |
83
|
768 |
|
return new Share($this, $name, $this->system); |
84
|
|
|
} |
85
|
|
|
} |
86
|
|
|
|
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.