Completed
Push — stable3.0 ( bd43cd...55b7d1 )
by Robin
08:57 queued 07:06
created

NativeState   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 282
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 95.1%

Importance

Changes 0
Metric Value
wmc 29
lcom 1
cbo 2
dl 0
loc 282
ccs 97
cts 102
cp 0.951
rs 10
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A handleError() 0 7 2
A testResult() 0 12 5
A init() 0 13 2
A opendir() 0 6 1
A readdir() 0 6 1
A closedir() 0 6 1
A rename() 0 6 1
A unlink() 0 6 1
A mkdir() 0 6 1
A rmdir() 0 6 1
A stat() 0 6 1
A fstat() 0 6 1
A open() 0 6 1
A create() 0 6 1
A read() 0 6 1
A write() 0 6 1
A lseek() 0 6 1
A ftruncate() 0 6 1
A close() 0 6 1
A getxattr() 0 6 1
A setxattr() 0 6 1
A __destruct() 0 5 2
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\Native;
9
10
use Icewind\SMB\Exception\AlreadyExistsException;
11
use Icewind\SMB\Exception\ConnectionRefusedException;
12
use Icewind\SMB\Exception\Exception;
13
use Icewind\SMB\Exception\FileInUseException;
14
use Icewind\SMB\Exception\ForbiddenException;
15
use Icewind\SMB\Exception\HostDownException;
16
use Icewind\SMB\Exception\InvalidArgumentException;
17
use Icewind\SMB\Exception\InvalidTypeException;
18
use Icewind\SMB\Exception\NoRouteToHostException;
19
use Icewind\SMB\Exception\NotEmptyException;
20
use Icewind\SMB\Exception\NotFoundException;
21
use Icewind\SMB\Exception\OutOfSpaceException;
22
use Icewind\SMB\Exception\TimedOutException;
23
use Icewind\SMB\IAuth;
24
25
/**
26
 * Low level wrapper for libsmbclient-php with error handling
27
 */
28
class NativeState {
29
	/**
30
	 * @var resource
31
	 */
32
	protected $state;
33
34
	protected $handlerSet = false;
35
36
	protected $connected = false;
37
38
	// see error.h
39
	const EXCEPTION_MAP = [
40
		1   => ForbiddenException::class,
41
		2   => NotFoundException::class,
42
		13  => ForbiddenException::class,
43
		16  => FileInUseException::class,
44
		17  => AlreadyExistsException::class,
45
		20  => InvalidTypeException::class,
46
		21  => InvalidTypeException::class,
47
		22  => InvalidArgumentException::class,
48
		28  => OutOfSpaceException::class,
49
		39  => NotEmptyException::class,
50
		110 => TimedOutException::class,
51
		111 => ConnectionRefusedException::class,
52
		112 => HostDownException::class,
53
		113 => NoRouteToHostException::class
54
	];
55
56 255
	protected function handleError($path) {
57 255
		$error = smbclient_state_errno($this->state);
58 255
		if ($error === 0) {
59 255
			return;
60
		}
61 19
		throw Exception::fromMap(self::EXCEPTION_MAP, $error, $path);
62
	}
63
64 255
	protected function testResult($result, $uri) {
65 255
		if ($result === false or $result === null) {
66
			// smb://host/share/path
67 255
			if (is_string($uri) && count(explode('/', $uri, 5)) > 4) {
68 19
				list(, , , , $path) = explode('/', $uri, 5);
69 19
				$path = '/' . $path;
70 19
			} else {
71 255
				$path = null;
72
			}
73 255
			$this->handleError($path);
74 255
		}
75 255
	}
76
77
	/**
78
	 * @param IAuth $auth
79
	 * @return bool
80
	 */
81 255
	public function init(IAuth $auth) {
82 255
		if ($this->connected) {
83
			return true;
84
		}
85 255
		$this->state = smbclient_state_new();
86 255
		smbclient_option_set($this->state, SMBCLIENT_OPT_AUTO_ANONYMOUS_LOGIN, false);
87 255
		$auth->setExtraSmbClientOptions($this->state);
88 255
		$result = @smbclient_state_init($this->state, $auth->getWorkgroup(), $auth->getUsername(), $auth->getPassword());
89
90 255
		$this->testResult($result, '');
91 255
		$this->connected = true;
92 255
		return $result;
93
	}
94
95
	/**
96
	 * @param string $uri
97
	 * @return resource
98
	 */
99 255
	public function opendir($uri) {
100 255
		$result = @smbclient_opendir($this->state, $uri);
101
102 255
		$this->testResult($result, $uri);
103 255
		return $result;
104
	}
105
106
	/**
107
	 * @param resource $dir
108
	 * @return array
109
	 */
110 255
	public function readdir($dir) {
111 255
		$result = @smbclient_readdir($this->state, $dir);
112
113 255
		$this->testResult($result, $dir);
114 255
		return $result;
115
	}
116
117
	/**
118
	 * @param $dir
119
	 * @return bool
120
	 */
121 255
	public function closedir($dir) {
122 255
		$result = smbclient_closedir($this->state, $dir);
123
124 255
		$this->testResult($result, $dir);
125 255
		return $result;
126
	}
127
128
	/**
129
	 * @param string $old
130
	 * @param string $new
131
	 * @return bool
132
	 */
133 19
	public function rename($old, $new) {
134 19
		$result = @smbclient_rename($this->state, $old, $this->state, $new);
135
136 19
		$this->testResult($result, $new);
137 16
		return $result;
138
	}
139
140
	/**
141
	 * @param string $uri
142
	 * @return bool
143
	 */
144 124
	public function unlink($uri) {
145 124
		$result = @smbclient_unlink($this->state, $uri);
146
147 124
		$this->testResult($result, $uri);
148 122
		return $result;
149
	}
150
151
	/**
152
	 * @param string $uri
153
	 * @param int $mask
154
	 * @return bool
155
	 */
156 255
	public function mkdir($uri, $mask = 0777) {
157 255
		$result = @smbclient_mkdir($this->state, $uri, $mask);
158
159 255
		$this->testResult($result, $uri);
160 255
		return $result;
161
	}
162
163
	/**
164
	 * @param string $uri
165
	 * @return bool
166
	 */
167 255
	public function rmdir($uri) {
168 255
		$result = @smbclient_rmdir($this->state, $uri);
169
170 255
		$this->testResult($result, $uri);
171 255
		return $result;
172
	}
173
174
	/**
175
	 * @param string $uri
176
	 * @return array
177
	 */
178 121
	public function stat($uri) {
179 121
		$result = @smbclient_stat($this->state, $uri);
180
181 121
		$this->testResult($result, $uri);
182 120
		return $result;
183
	}
184
185
	/**
186
	 * @param resource $file
187
	 * @return array
188
	 */
189
	public function fstat($file) {
190
		$result = @smbclient_fstat($this->state, $file);
191
192
		$this->testResult($result, $file);
193
		return $result;
194
	}
195
196
	/**
197
	 * @param string $uri
198
	 * @param string $mode
199
	 * @param int $mask
200
	 * @return resource
201
	 */
202 54
	public function open($uri, $mode, $mask = 0666) {
203 54
		$result = @smbclient_open($this->state, $uri, $mode, $mask);
204
205 54
		$this->testResult($result, $uri);
206 52
		return $result;
207
	}
208
209
	/**
210
	 * @param string $uri
211
	 * @param int $mask
212
	 * @return resource
213
	 */
214 124
	public function create($uri, $mask = 0666) {
215 124
		$result = @smbclient_creat($this->state, $uri, $mask);
216
217 124
		$this->testResult($result, $uri);
218 122
		return $result;
219
	}
220
221
	/**
222
	 * @param resource $file
223
	 * @param int $bytes
224
	 * @return string
225
	 */
226 51
	public function read($file, $bytes) {
227 51
		$result = @smbclient_read($this->state, $file, $bytes);
228
229 51
		$this->testResult($result, $file);
230 51
		return $result;
231
	}
232
233
	/**
234
	 * @param resource $file
235
	 * @param string $data
236
	 * @param int $length
237
	 * @return int
238
	 */
239 122
	public function write($file, $data, $length = null) {
240 122
		$result = @smbclient_write($this->state, $file, $data, $length);
241
242 122
		$this->testResult($result, $file);
243 122
		return $result;
244
	}
245
246
	/**
247
	 * @param resource $file
248
	 * @param int $offset
249
	 * @param int $whence SEEK_SET | SEEK_CUR | SEEK_END
250
	 * @return int|bool new file offset as measured from the start of the file on success, false on failure.
251
	 */
252 1
	public function lseek($file, $offset, $whence = SEEK_SET) {
253 1
		$result = @smbclient_lseek($this->state, $file, $offset, $whence);
254
255 1
		$this->testResult($result, $file);
256 1
		return $result;
257
	}
258
259
	/**
260
	 * @param resource $file
261
	 * @param int $size
262
	 * @return bool
263
	 */
264 1
	public function ftruncate($file, $size) {
265 1
		$result = @smbclient_ftruncate($this->state, $file, $size);
266
267 1
		$this->testResult($result, $file);
268 1
		return $result;
269
	}
270
271 122
	public function close($file) {
272 122
		$result = @smbclient_close($this->state, $file);
273
274 122
		$this->testResult($result, $file);
275 122
		return $result;
276
	}
277
278
	/**
279
	 * @param string $uri
280
	 * @param string $key
281
	 * @return string
282
	 */
283 14
	public function getxattr($uri, $key) {
284 14
		$result = @smbclient_getxattr($this->state, $uri, $key);
285
286 14
		$this->testResult($result, $uri);
287 14
		return $result;
288
	}
289
290
	/**
291
	 * @param string $uri
292
	 * @param string $key
293
	 * @param string $value
294
	 * @param int $flags
295
	 * @return mixed
296
	 */
297 8
	public function setxattr($uri, $key, $value, $flags = 0) {
298 8
		$result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags);
299
300 8
		$this->testResult($result, $uri);
301 8
		return $result;
302
	}
303
304 255
	public function __destruct() {
305 255
		if ($this->connected) {
306 255
			smbclient_state_free($this->state);
307 255
		}
308 255
	}
309
}
310