/** * Puts a file on RouterOS's file system. * * Puts a file on RouterOS's file system, regardless of the current menu. * Note that this is a **VERY VERY VERY** time consuming method - it takes a * minimum of a little over 4 seconds, most of which are in sleep. It waits * 2 seconds after a file is first created (required to actually start * writing to the file), and another 2 seconds after its contents is written * (performed in order to verify success afterwards). * Similarly for removal (when $data is NULL) - there are two seconds in * sleep, used to verify the file was really deleted. * * If you want an efficient way of transferring files, use (T)FTP. * If you want an efficient way of removing files, use * {@link static::setMenu()} to move to the "/file" menu, and call * {@link static::remove()} without performing verification afterwards. * * @param string $filename The filename to write data in. * @param string|resource|null $data The data the file is going to have * as a string or a seekable stream. * Setting the value to NULL removes a file of this name. * If a seekable stream is provided, it is sent from its current * posistion to its end, and the pointer is seeked back to its current * position after sending. * Non seekable streams, as well as all other types, are casted to a * string. * @param bool $overwrite Whether to overwrite the file if * it exists. * * @return bool TRUE on success, FALSE on failure. */ public function filePutContents($filename, $data, $overwrite = false) { $printRequest = new Request('/file/print .proplist=""', Query::where('name', $filename)); $fileExists = count($this->client->sendSync($printRequest)) > 1; if (null === $data) { if (!$fileExists) { return false; } $removeRequest = new Request('/file/remove'); $this->client->sendSync($removeRequest->setArgument('numbers', $filename)); //Required for RouterOS to REALLY remove the file. sleep(2); return !(count($this->client->sendSync($printRequest)) > 1); } if (!$overwrite && $fileExists) { return false; } $result = $this->client->sendSync($printRequest->setArgument('file', $filename)); if (count($result->getAllOfType(Response::TYPE_ERROR)) > 0) { return false; } //Required for RouterOS to write the initial file. sleep(2); $setRequest = new Request('/file/set contents=""'); $setRequest->setArgument('numbers', $filename); $this->client->sendSync($setRequest); $this->client->sendSync($setRequest->setArgument('contents', $data)); //Required for RouterOS to write the file's new contents. sleep(2); $fileSize = $this->client->sendSync($printRequest->setArgument('file', null)->setArgument('.proplist', 'size'))->getProperty('size'); if (Stream::isStream($fileSize)) { $fileSize = stream_get_contents($fileSize); } if (Communicator::isSeekableStream($data)) { return Communicator::seekableStreamLength($data) == $fileSize; } else { return sprintf('%u', strlen((string) $data)) === $fileSize; } }
/** * Sanitizes a value of an attribute (message or query one). * * @param mixed $value The value to sanitize. * * @return string The sanitized value. */ public static function sanitizeAttributeValue($value) { if (Communicator::isSeekableStream($value)) { return $value; } else { return (string) $value; } }