/** * Open a writable stream to a remote file * * @param string $target * @return resource a write only stream to upload a remote file * * @throws \Icewind\SMB\Exception\NotFoundException * @throws \Icewind\SMB\Exception\InvalidTypeException */ public function write($target) { $target = $this->escapePath($target); // since returned stream is closed by the caller we need to create a new instance // since we can't re-use the same file descriptor over multiple calls $workgroupArgument = $this->server->getWorkgroup() ? ' -W ' . escapeshellarg($this->server->getWorkgroup()) : ''; $command = sprintf('%s %s --authentication-file=%s %s', $this->system->getSmbclientPath(), $workgroupArgument, System::getFD(3), escapeshellarg('//' . $this->server->getHost() . '/' . $this->name)); $connection = new Connection($command); $connection->writeAuthentication($this->server->getUser(), $this->server->getPassword()); $fh = $connection->getFileInputStream(); $connection->write('put ' . System::getFD(4) . ' ' . $target); $connection->write('exit'); // use a close callback to ensure the upload is finished before continuing // this also serves as a way to keep the connection in scope return CallbackWrapper::wrap($fh, null, null, function () use($connection, $target) { $connection->close(false); // dont terminate, give the upload some time }); }
/** * @return \Icewind\SMB\IShare[] * * @throws \Icewind\SMB\Exception\AuthenticationException * @throws \Icewind\SMB\Exception\InvalidHostException */ public function listShares() { $workgroupArgument = $this->workgroup ? ' -W ' . escapeshellarg($this->workgroup) : ''; $command = sprintf('%s %s --authentication-file=%s -gL %s', $this->system->getSmbclientPath(), $workgroupArgument, System::getFD(3), escapeshellarg($this->getHost())); $connection = new RawConnection($command); $connection->writeAuthentication($this->getUser(), $this->getPassword()); $output = $connection->readAll(); $line = $output[0]; $line = rtrim($line, ')'); if (substr($line, -23) === ErrorCodes::LogonFailure) { throw new AuthenticationException(); } if (substr($line, -26) === ErrorCodes::BadHostName) { throw new InvalidHostException(); } if (substr($line, -22) === ErrorCodes::Unsuccessful) { throw new InvalidHostException(); } if (substr($line, -28) === ErrorCodes::ConnectionRefused) { throw new InvalidHostException(); } $shareNames = array(); foreach ($output as $line) { if (strpos($line, '|')) { list($type, $name, $description) = explode('|', $line); if (strtolower($type) === 'disk') { $shareNames[$name] = $description; } } } $shares = array(); foreach ($shareNames as $name => $description) { $shares[] = $this->getShare($name); } return $shares; }