Completed
Push — master ( 5d1e55...65afed )
by Robin
03:37
created

NativeState::open()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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