Passed
Push — master ( 80a4ed...26ec76 )
by Robin
73:34 queued 71:57
created

RawConnection::getInputStream()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 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\Wrapped;
9
10
use Icewind\SMB\Exception\ConnectException;
11
use Icewind\SMB\Exception\ConnectionException;
12
use Icewind\SMB\Exception\ConnectionResetException;
13
14
class RawConnection {
15
	/**
16
	 * @var string
17
	 */
18
	private $command;
19
20
	/**
21
	 * @var string[]
22
	 */
23
	private $env;
24
25
	/**
26
	 * @var resource[] $pipes
27
	 *
28
	 * $pipes[0] holds STDIN for smbclient
29
	 * $pipes[1] holds STDOUT for smbclient
30
	 * $pipes[3] holds the authfile for smbclient
31
	 * $pipes[4] holds the stream for writing files
32
	 * $pipes[5] holds the stream for reading files
33
	 */
34
	private $pipes;
35
36
	/**
37
	 * @var resource $process
38
	 */
39
	private $process;
40
41
	/**
42
	 * @var resource|null $authStream
43
	 */
44
	private $authStream = null;
45
46
	private $connected = false;
47
48 494
	public function __construct($command, array $env = []) {
49 494
		$this->command = $command;
50 494
		$this->env = $env;
51 494
	}
52
53
	/**
54
	 * @throws ConnectException
55
	 */
56 494
	public function connect() {
57 494
		if (is_null($this->getAuthStream())) {
58
			throw new ConnectException('Authentication not set before connecting');
59
		}
60
61
		$descriptorSpec = [
62 494
			0 => ['pipe', 'r'], // child reads from stdin
63
			1 => ['pipe', 'w'], // child writes to stdout
64
			2 => ['pipe', 'w'], // child writes to stderr
65 494
			3 => $this->getAuthStream(), // child reads from fd#3
66
			4 => ['pipe', 'r'], // child reads from fd#4
67
			5 => ['pipe', 'w']  // child writes to fd#5
68
		];
69
70 494
		setlocale(LC_ALL, Server::LOCALE);
71 494
		$env = array_merge($this->env, [
72 494
			'CLI_FORCE_INTERACTIVE' => 'y', // Needed or the prompt isn't displayed!!
73
			'LC_ALL'                => Server::LOCALE,
74
			'LANG'                  => Server::LOCALE,
75
			'COLUMNS'               => 8192 // prevent smbclient from line-wrapping it's output
76
		]);
77 494
		$this->process = proc_open($this->command, $descriptorSpec, $this->pipes, '/', $env);
78 494
		if (!$this->isValid()) {
79
			throw new ConnectionException();
80
		}
81 494
		$this->connected = true;
82 494
	}
83
84
	/**
85
	 * check if the connection is still active
86
	 *
87
	 * @return bool
88
	 */
89 494
	public function isValid() {
90 494
		if (is_resource($this->process)) {
91 494
			$status = proc_get_status($this->process);
92 494
			return $status['running'];
93
		} else {
94
			return false;
95
		}
96
	}
97
98
	/**
99
	 * send input to the process
100
	 *
101
	 * @param string $input
102
	 */
103 486
	public function write($input) {
104 486
		$result = @fwrite($this->getInputStream(), $input);
105 486
		fflush($this->getInputStream());
106 486
		return $result;
107
	}
108
109
	/**
110
	 * read a line of output
111
	 *
112
	 * @return string|false
113
	 */
114 494
	public function readLine() {
115 494
		return stream_get_line($this->getOutputStream(), 4086, "\n");
116
	}
117
118
	/**
119
	 * read a line of output
120
	 *
121
	 * @return string
122
	 */
123
	public function readError() {
124
		return trim(stream_get_line($this->getErrorStream(), 4086));
125
	}
126
127
	/**
128
	 * get all output until the process closes
129
	 *
130
	 * @return array
131
	 */
132 10
	public function readAll() {
133 10
		$output = [];
134 10
		while ($line = $this->readLine()) {
135 10
			$output[] = $line;
136
		}
137 10
		return $output;
138
	}
139
140 486
	public function getInputStream() {
141 486
		return $this->pipes[0];
142
	}
143
144 494
	public function getOutputStream() {
145 494
		return $this->pipes[1];
146
	}
147
148
	public function getErrorStream() {
149
		return $this->pipes[2];
150
	}
151
152 494
	public function getAuthStream() {
153 494
		return $this->authStream;
154
	}
155
156 32
	public function getFileInputStream() {
157 32
		return $this->pipes[4];
158
	}
159
160 32
	public function getFileOutputStream() {
161 32
		return $this->pipes[5];
162
	}
163
164 494
	public function writeAuthentication($user, $password) {
165 494
		$auth = ($password === false)
166
			? "username=$user"
167 494
			: "username=$user\npassword=$password\n";
168
169 494
		$this->authStream = fopen('php://temp', 'w+');
170 494
		fwrite($this->getAuthStream(), $auth);
171 494
	}
172
173 494
	public function close($terminate = true) {
174 494
		if (!is_resource($this->process)) {
175 34
			return;
176
		}
177 494
		if ($terminate) {
178 494
			proc_terminate($this->process);
179
		}
180 494
		proc_close($this->process);
181 494
	}
182
183 2
	public function reconnect() {
184 2
		$this->close();
185 2
		$this->connect();
186 2
	}
187
188 494
	public function __destruct() {
189 494
		$this->close();
190 494
	}
191
}
192