Completed
Push — master ( 0bfb02...89f47c )
by Robin
02:44
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 fstat() 0 6 1
A handleError() 0 7 2
B 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 open() 0 6 1
A create() 0 6 1
A read() 0 6 1
A write() 0 6 1
A close() 0 6 1
A getxattr() 0 6 1
A setxattr() 0 6 1
A __destruct() 0 5 2
A lseek() 0 6 1
A ftruncate() 0 6 1
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 510
	protected function handleError($path) {
57 510
		$error = smbclient_state_errno($this->state);
58 510
		if ($error === 0) {
59 510
			return;
60
		}
61 38
		throw Exception::fromMap(self::EXCEPTION_MAP, $error, $path);
62
	}
63
64 510
	protected function testResult($result, $uri) {
65 510
		if ($result === false or $result === null) {
66
			// smb://host/share/path
67 510
			if (is_string($uri) && count(explode('/', $uri, 5)) > 4) {
68 38
				list(, , , , $path) = explode('/', $uri, 5);
69 38
				$path = '/' . $path;
70 19
			} else {
71 510
				$path = null;
72
			}
73 510
			$this->handleError($path);
74 255
		}
75 510
	}
76
77
	/**
78
	 * @param IAuth $auth
79
	 * @return bool
80
	 */
81 510
	public function init(IAuth $auth) {
82 510
		if ($this->connected) {
83
			return true;
84
		}
85 510
		$this->state = smbclient_state_new();
86 510
		smbclient_option_set($this->state, SMBCLIENT_OPT_AUTO_ANONYMOUS_LOGIN, false);
87 510
		$auth->setExtraSmbClientOptions($this->state);
88 510
		$result = @smbclient_state_init($this->state, $auth->getWorkgroup(), $auth->getUsername(), $auth->getPassword());
89
90 510
		$this->testResult($result, '');
91 510
		$this->connected = true;
92 510
		return $result;
93
	}
94
95
	/**
96
	 * @param string $uri
97
	 * @return resource
98
	 */
99 510
	public function opendir($uri) {
100 510
		$result = @smbclient_opendir($this->state, $uri);
101
102 510
		$this->testResult($result, $uri);
103 510
		return $result;
104
	}
105
106
	/**
107
	 * @param resource $dir
108
	 * @return array
109
	 */
110 510
	public function readdir($dir) {
111 510
		$result = @smbclient_readdir($this->state, $dir);
112
113 510
		$this->testResult($result, $dir);
114 510
		return $result;
115
	}
116
117
	/**
118
	 * @param $dir
119
	 * @return bool
120
	 */
121 510
	public function closedir($dir) {
122 510
		$result = smbclient_closedir($this->state, $dir);
123
124 510
		$this->testResult($result, $dir);
125 510
		return $result;
126
	}
127
128
	/**
129
	 * @param string $old
130
	 * @param string $new
131
	 * @return bool
132
	 */
133 38
	public function rename($old, $new) {
134 38
		$result = @smbclient_rename($this->state, $old, $this->state, $new);
135
136 38
		$this->testResult($result, $new);
137 32
		return $result;
138
	}
139
140
	/**
141
	 * @param string $uri
142
	 * @return bool
143
	 */
144 248
	public function unlink($uri) {
145 248
		$result = @smbclient_unlink($this->state, $uri);
146
147 248
		$this->testResult($result, $uri);
148 244
		return $result;
149
	}
150
151
	/**
152
	 * @param string $uri
153
	 * @param int $mask
154
	 * @return bool
155
	 */
156 510
	public function mkdir($uri, $mask = 0777) {
157 510
		$result = @smbclient_mkdir($this->state, $uri, $mask);
158
159 510
		$this->testResult($result, $uri);
160 510
		return $result;
161
	}
162
163
	/**
164
	 * @param string $uri
165
	 * @return bool
166
	 */
167 510
	public function rmdir($uri) {
168 510
		$result = @smbclient_rmdir($this->state, $uri);
169
170 510
		$this->testResult($result, $uri);
171 510
		return $result;
172
	}
173
174
	/**
175
	 * @param string $uri
176
	 * @return array
177
	 */
178 242
	public function stat($uri) {
179 242
		$result = @smbclient_stat($this->state, $uri);
180
181 242
		$this->testResult($result, $uri);
182 240
		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 108
	public function open($uri, $mode, $mask = 0666) {
203 108
		$result = @smbclient_open($this->state, $uri, $mode, $mask);
204
205 108
		$this->testResult($result, $uri);
206 104
		return $result;
207
	}
208
209
	/**
210
	 * @param string $uri
211
	 * @param int $mask
212
	 * @return resource
213
	 */
214 248
	public function create($uri, $mask = 0666) {
215 248
		$result = @smbclient_creat($this->state, $uri, $mask);
216
217 248
		$this->testResult($result, $uri);
218 244
		return $result;
219
	}
220
221
	/**
222
	 * @param resource $file
223
	 * @param int $bytes
224
	 * @return string
225
	 */
226 102
	public function read($file, $bytes) {
227 102
		$result = @smbclient_read($this->state, $file, $bytes);
228
229 102
		$this->testResult($result, $file);
230 102
		return $result;
231
	}
232
233
	/**
234
	 * @param resource $file
235
	 * @param string $data
236
	 * @param int $length
237
	 * @return int
238
	 */
239 244
	public function write($file, $data, $length = null) {
240 244
		$result = @smbclient_write($this->state, $file, $data, $length);
241
242 244
		$this->testResult($result, $file);
243 244
		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 2
	public function lseek($file, $offset, $whence = SEEK_SET) {
253 2
		$result = @smbclient_lseek($this->state, $file, $offset, $whence);
254
255 2
		$this->testResult($result, $file);
256 2
		return $result;
257
	}
258
259
	/**
260
	 * @param resource $file
261
	 * @param int $size
262
	 * @return bool
263
	 */
264 2
	public function ftruncate($file, $size) {
265 2
		$result = @smbclient_ftruncate($this->state, $file, $size);
266
267 2
		$this->testResult($result, $file);
268 2
		return $result;
269
	}
270
271 244
	public function close($file) {
272 244
		$result = @smbclient_close($this->state, $file);
273
274 244
		$this->testResult($result, $file);
275 244
		return $result;
276
	}
277
278
	/**
279
	 * @param string $uri
280
	 * @param string $key
281
	 * @return string
282
	 */
283 28
	public function getxattr($uri, $key) {
284 28
		$result = @smbclient_getxattr($this->state, $uri, $key);
285
286 28
		$this->testResult($result, $uri);
287 28
		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 16
	public function setxattr($uri, $key, $value, $flags = 0) {
298 16
		$result = @smbclient_setxattr($this->state, $uri, $key, $value, $flags);
299
300 16
		$this->testResult($result, $uri);
301 16
		return $result;
302
	}
303
304 510
	public function __destruct() {
305 510
		if ($this->connected) {
306 510
			smbclient_state_free($this->state);
307 255
		}
308 510
	}
309
}
310