Completed
Push — master ( 65afed...db16d4 )
by Robin
03:00
created

NativeState   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 284
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

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