Completed
Push — master ( c92ae0...dc7863 )
by Robin
03:57
created

Connection::read()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 28
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
c 6
b 1
f 0
dl 0
loc 28
rs 8.439
cc 6
eloc 21
nc 6
nop 0
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;
9
10
use Icewind\SMB\Exception\AuthenticationException;
11
use Icewind\SMB\Exception\ConnectException;
12
use Icewind\SMB\Exception\ConnectionException;
13
use Icewind\SMB\Exception\InvalidHostException;
14
use Icewind\SMB\Exception\NoLoginServerException;
15
16
class Connection extends RawConnection {
17
	const DELIMITER = 'smb:';
18
19
	/**
20
	 * send input to smbclient
21
	 *
22
	 * @param string $input
23
	 */
24
	public function write($input) {
25
		parent::write($input . PHP_EOL);
26
	}
27
28
	/**
29
	 * get all unprocessed output from smbclient until the next prompt
30
	 *
31
	 * @return string
32
	 * @throws AuthenticationException
33
	 * @throws ConnectException
34
	 * @throws ConnectionException
35
	 * @throws InvalidHostException
36
	 * @throws NoLoginServerException
37
	 */
38
	public function read() {
39
		if (!$this->isValid()) {
40
			throw new ConnectionException('Connection not valid');
41
		}
42
		$promptLine = $this->readLine(); //first line is prompt
43
		$this->checkConnectionError($promptLine);
44
45
		$output = array();
46
		$line = $this->readLine();
47
		if ($line === false) {
48
			if ($promptLine) { //maybe we have some error we missed on the previous line
49
				throw new ConnectException('Unknown error (' . $promptLine . ')');
50
			} else {
51
				$error = $this->readError(); // maybe something on stderr
52
				if ($error) {
53
					throw new ConnectException('Unknown error (' . $error . ')');
54
				} else {
55
					throw new ConnectException('Unknown error');
56
				}
57
			}
58
		}
59
		$length = mb_strlen(self::DELIMITER);
60
		while (mb_substr($line, 0, $length) !== self::DELIMITER) { //next prompt functions as delimiter
61
			$output[] .= $line;
62
			$line = $this->readLine();
63
		}
64
		return $output;
65
	}
66
67
	/**
68
	 * check if the first line holds a connection failure
69
	 *
70
	 * @param $line
71
	 * @throws AuthenticationException
72
	 * @throws InvalidHostException
73
	 * @throws NoLoginServerException
74
	 */
75
	private function checkConnectionError($line) {
76
		$line = rtrim($line, ')');
77
		if (substr($line, -23) === ErrorCodes::LogonFailure) {
78
			throw new AuthenticationException('Invalid login');
79
		}
80
		if (substr($line, -26) === ErrorCodes::BadHostName) {
81
			throw new InvalidHostException('Invalid hostname');
82
		}
83
		if (substr($line, -22) === ErrorCodes::Unsuccessful) {
84
			throw new InvalidHostException('Connection unsuccessful');
85
		}
86
		if (substr($line, -28) === ErrorCodes::ConnectionRefused) {
87
			throw new InvalidHostException('Connection refused');
88
		}
89
		if (substr($line, -26) === ErrorCodes::NoLogonServers) {
90
			throw new NoLoginServerException('No login server');
91
		}
92
	}
93
94
	public function close($terminate = true) {
95
		if (is_resource($this->getInputStream())) {
96
			$this->write('close' . PHP_EOL);
97
		}
98
		parent::close($terminate);
99
	}
100
}
101