mirror of
https://github.com/lxsang/ant-http
synced 2024-11-17 17:08:20 +01:00
add terminal plugin
This commit is contained in:
parent
27fd4a0134
commit
3333e41cae
2
Makefile
2
Makefile
@ -5,7 +5,7 @@ EXT=dylib
|
||||
SERVER=plugin_manager.o ini.o http_server.o plugins/dictionary.o plugins/utils.o
|
||||
SERVERLIB=-lpthread -ldl
|
||||
#-lsocket
|
||||
PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT)
|
||||
PLUGINS= dummy.$(EXT) fileman.$(EXT) pluginsman.$(EXT) wterm.$(EXT)
|
||||
|
||||
PLUGINSDEP = plugins/plugin.o plugins/dbhelper.o plugins/dictionary.o plugins/utils.o plugins/list.o
|
||||
PLUGINLIBS = -lsqlite3
|
||||
|
@ -1,12 +1,14 @@
|
||||
<HTML>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="style/font.min.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="style/w2ui-1.4.2.css" />
|
||||
<link rel="stylesheet" type="text/css" href="style/w2ui-1.4.2.css" />
|
||||
<link rel="stylesheet" type="text/css" href="style/site.css" />
|
||||
<script src="scripts/jquery.min.js"></script>
|
||||
<script src="scripts/w2ui-1.4.2.js"></script>
|
||||
<script src="scripts/pluginman.js"></script>
|
||||
<script src="scripts/fileman.js"></script>
|
||||
<script src="scripts/camviewer.js"></script>
|
||||
<script src="scripts/wterm.js"></script>
|
||||
<script src="scripts/sidebar.js"></script>
|
||||
<script src="scripts/rcar.js"></script>
|
||||
</head>
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
var picam_config = {
|
||||
name: 'picam_layout',
|
||||
toolbar:{
|
||||
|
@ -14,7 +14,8 @@ var sidebar_config = {
|
||||
text: 'Plugins',
|
||||
icon: 'fa-cogs'
|
||||
},
|
||||
{ id: 'level-fman', text: 'File manager', icon: 'fa-folder-open' }
|
||||
{ id: 'level-fman', text: 'File manager', icon: 'fa-folder-open' },
|
||||
{ id: 'level-wterm', text: 'Terminal', icon: 'fa-wrench' }
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -47,6 +48,9 @@ var sidebar_config = {
|
||||
case 'level-picam':
|
||||
w2ui.layout.content('main', w2ui.picam_layout);
|
||||
break;
|
||||
case 'level-wterm':
|
||||
w2ui.layout.content('main', w2ui.wterm_layout);
|
||||
break;
|
||||
default: //do nothing
|
||||
w2ui.layout.content('main',"Empty page");
|
||||
console.log('Event: ' + event.type + ' Target: ' + event.target);
|
||||
|
245
build/htdocs/scripts/wterm.js
Normal file
245
build/htdocs/scripts/wterm.js
Normal file
@ -0,0 +1,245 @@
|
||||
/*! terminal.js v2.0 | (c) 2014 Erik Österberg | https://github.com/eosterberg/terminaljs */
|
||||
|
||||
var Terminal = (function () {
|
||||
// PROMPT_TYPE
|
||||
var PROMPT_INPUT = 1, PROMPT_PASSWORD = 2, PROMPT_CONFIRM = 3
|
||||
|
||||
var fireCursorInterval = function (inputField, terminalObj) {
|
||||
var cursor = terminalObj._cursor
|
||||
setTimeout(function () {
|
||||
if (inputField.parentElement && terminalObj._shouldBlinkCursor) {
|
||||
cursor.style.visibility = cursor.style.visibility === 'visible' ? 'hidden' : 'visible'
|
||||
fireCursorInterval(inputField, terminalObj)
|
||||
} else {
|
||||
cursor.style.visibility = 'visible'
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
var firstPrompt = true;
|
||||
promptInput = function (terminalObj, message, PROMPT_TYPE, callback) {
|
||||
var shouldDisplayInput = (PROMPT_TYPE === PROMPT_INPUT)
|
||||
var inputField = document.createElement('input')
|
||||
|
||||
inputField.style.position = 'absolute'
|
||||
inputField.style.zIndex = '-100'
|
||||
inputField.style.outline = 'none'
|
||||
inputField.style.border = 'none'
|
||||
inputField.style.opacity = '0'
|
||||
inputField.style.fontSize = '0.2em'
|
||||
|
||||
terminalObj._inputLine.textContent = ''
|
||||
terminalObj._input.style.display = 'block'
|
||||
terminalObj.html.appendChild(inputField)
|
||||
fireCursorInterval(inputField, terminalObj)
|
||||
|
||||
if (message.length) terminalObj.msg(PROMPT_TYPE === PROMPT_CONFIRM ? message + ' (y/n)' : message)
|
||||
|
||||
inputField.onblur = function () {
|
||||
terminalObj._cursor.style.display = 'none'
|
||||
}
|
||||
|
||||
inputField.onfocus = function () {
|
||||
inputField.value = terminalObj._inputLine.textContent
|
||||
terminalObj._cursor.style.display = 'inline'
|
||||
}
|
||||
|
||||
terminalObj.html.onclick = function () {
|
||||
inputField.focus()
|
||||
}
|
||||
|
||||
inputField.onkeydown = function (e) {
|
||||
if (e.which === 37 || e.which === 39 || e.which === 38 || e.which === 40 || e.which === 9) {
|
||||
e.preventDefault()
|
||||
} else if (shouldDisplayInput && e.which !== 13) {
|
||||
setTimeout(function () {
|
||||
terminalObj._inputLine.textContent = inputField.value
|
||||
}, 1)
|
||||
}
|
||||
}
|
||||
inputField.onkeyup = function (e) {
|
||||
if (PROMPT_TYPE === PROMPT_CONFIRM || e.which === 13) {
|
||||
terminalObj._input.style.display = 'none'
|
||||
var inputValue = inputField.value
|
||||
if (shouldDisplayInput) terminalObj._print(message+inputValue,"wterm_input_div")
|
||||
terminalObj.html.removeChild(inputField)
|
||||
if (typeof(callback) === 'function') {
|
||||
if (PROMPT_TYPE === PROMPT_CONFIRM) {
|
||||
callback(inputValue.toUpperCase()[0] === 'Y' ? true : false)
|
||||
} else callback(inputValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (firstPrompt) {
|
||||
firstPrompt = false
|
||||
setTimeout(function () { inputField.focus() }, 50)
|
||||
} else {
|
||||
inputField.focus()
|
||||
}
|
||||
}
|
||||
|
||||
var terminalBeep
|
||||
|
||||
var TerminalConstructor = function (id) {
|
||||
if (!terminalBeep) {
|
||||
terminalBeep = document.createElement('audio')
|
||||
var source = '<source src="http://www.erikosterberg.com/terminaljs/beep.'
|
||||
terminalBeep.innerHTML = source + 'mp3" type="audio/mpeg">' + source + 'ogg" type="audio/ogg">'
|
||||
terminalBeep.volume = 0.05
|
||||
}
|
||||
|
||||
this.html = document.createElement('div')
|
||||
this.html.className = 'Terminal'
|
||||
if (typeof(id) === 'string') { this.html.id = id }
|
||||
|
||||
this._innerWindow = document.createElement('div')
|
||||
this._output = document.createElement('p')
|
||||
this._inputLine = document.createElement('span') //the span element where the users input is put
|
||||
this._cursor = document.createElement('span')
|
||||
this._input = document.createElement('p') //the full element administering the user input, including cursor
|
||||
this._input.className = "wterm_input_p"
|
||||
this._cursor.className = "wterm_cursor"
|
||||
//this._output.className = "wterm_output_p"
|
||||
this._input.appendChild(document.createElement('span'));
|
||||
this._shouldBlinkCursor = true
|
||||
|
||||
this.beep = function () {
|
||||
terminalBeep.load()
|
||||
terminalBeep.play()
|
||||
}
|
||||
this.msg = function (message) {
|
||||
this._input.firstChild.textContent = message
|
||||
}
|
||||
this._print = function(msg,cls)
|
||||
{
|
||||
var newLine = document.createElement('div')
|
||||
newLine.className = cls
|
||||
newLine.textContent = msg
|
||||
this._output.appendChild(newLine)
|
||||
}
|
||||
this.print = function (message) {
|
||||
this._print(message,"wterm_output_div")
|
||||
}
|
||||
|
||||
this.input = function (message, callback) {
|
||||
promptInput(this, message, PROMPT_INPUT, callback)
|
||||
}
|
||||
|
||||
this.password = function (message, callback) {
|
||||
promptInput(this, message, PROMPT_PASSWORD, callback)
|
||||
}
|
||||
|
||||
this.confirm = function (message, callback) {
|
||||
promptInput(this, message, PROMPT_CONFIRM, callback)
|
||||
}
|
||||
|
||||
this.clear = function () {
|
||||
this._output.innerHTML = ''
|
||||
}
|
||||
|
||||
this.sleep = function (milliseconds, callback) {
|
||||
setTimeout(callback, milliseconds)
|
||||
}
|
||||
|
||||
this.setTextSize = function (size) {
|
||||
this._output.style.fontSize = size
|
||||
this._input.style.fontSize = size
|
||||
}
|
||||
|
||||
this.setTextColor = function (col) {
|
||||
this.html.style.color = col
|
||||
this._cursor.style.background = col
|
||||
}
|
||||
|
||||
this.setBackgroundColor = function (col) {
|
||||
this.html.style.background = col
|
||||
}
|
||||
|
||||
this.setWidth = function (width) {
|
||||
this.html.style.width = width
|
||||
}
|
||||
|
||||
this.setHeight = function (height) {
|
||||
this.html.style.height = height
|
||||
}
|
||||
|
||||
this.blinkingCursor = function (bool) {
|
||||
bool = bool.toString().toUpperCase()
|
||||
this._shouldBlinkCursor = (bool === 'TRUE' || bool === '1' || bool === 'YES')
|
||||
}
|
||||
|
||||
this._input.appendChild(this._inputLine)
|
||||
this._input.appendChild(this._cursor)
|
||||
this._innerWindow.appendChild(this._output)
|
||||
this._innerWindow.appendChild(this._input)
|
||||
this.html.appendChild(this._innerWindow)
|
||||
|
||||
this.setBackgroundColor('black')
|
||||
this.setTextColor('white')
|
||||
this.setTextSize('1em')
|
||||
this.setWidth('100%')
|
||||
this.setHeight('100%')
|
||||
|
||||
this.html.style.fontFamily = 'Monaco, Courier'
|
||||
this.html.style.margin = '0'
|
||||
this._innerWindow.style.padding = '10px'
|
||||
this._input.style.margin = '0'
|
||||
this._output.style.margin = '0'
|
||||
this._cursor.style.background = '#00cc00'
|
||||
this._cursor.innerHTML = 'C' //put something in the cursor..
|
||||
this._cursor.style.display = 'none' //then hide it
|
||||
this._input.style.display = 'none'
|
||||
}
|
||||
|
||||
return TerminalConstructor
|
||||
}());
|
||||
var wtermobj;
|
||||
|
||||
var wterm_config = {
|
||||
name: 'wterm_layout',
|
||||
panels: [
|
||||
{
|
||||
type: 'main',
|
||||
style: 'padding: 0px;',
|
||||
content: '<div id="wterm" style="padding:0"></div>'
|
||||
}
|
||||
],
|
||||
onRefresh:function(event)
|
||||
{
|
||||
if($("#wterm_input") )
|
||||
{
|
||||
wtermobj = new Terminal();
|
||||
wtermobj.setTextSize(11);
|
||||
var nest_callback = function(data)
|
||||
{
|
||||
if(data.length>0)
|
||||
{
|
||||
//send to server
|
||||
var webtty = new EventSource('/wterm?cmd='+data);
|
||||
webtty.onmessage = function (e) {
|
||||
wtermobj.print(e.data);
|
||||
var par = $("#wterm");
|
||||
par.animate({
|
||||
scrollTop: par.get(0).scrollHeight
|
||||
}, 0);
|
||||
};
|
||||
webtty.onerror = function(e)
|
||||
{
|
||||
// finish the command
|
||||
webtty.close();
|
||||
wtermobj.input("antd> ",nest_callback);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wtermobj.input("antd> ",nest_callback);
|
||||
}
|
||||
};
|
||||
$("#wterm").html(wtermobj.html);
|
||||
$("#wterm").parent().css("overflow","hidden");
|
||||
$("#wterm").parent().css("background-color","black");
|
||||
wtermobj.input("antd> ",nest_callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
$().w2layout(wterm_config);
|
21
build/htdocs/style/site.css
Normal file
21
build/htdocs/style/site.css
Normal file
@ -0,0 +1,21 @@
|
||||
#wterm {
|
||||
width:100%;
|
||||
height: 100%;
|
||||
background-color:black;
|
||||
position:absolute;
|
||||
overflow:auto;
|
||||
}
|
||||
.wterm_output_div{
|
||||
padding-left:15px;
|
||||
}
|
||||
.wterm_input_div
|
||||
{
|
||||
color:#00cc00;
|
||||
}
|
||||
.wterm_input_p{
|
||||
color:#00cc00;
|
||||
}
|
||||
.wterm_cursor{
|
||||
color:#00cc00;
|
||||
background-color:#00cc00;
|
||||
}
|
BIN
build/httpd
BIN
build/httpd
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/plugins/wterm.dylib
Executable file
BIN
build/plugins/wterm.dylib
Executable file
Binary file not shown.
88
plugins/wterm/wterm.c
Normal file
88
plugins/wterm/wterm.c
Normal file
@ -0,0 +1,88 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include "../plugin.h"
|
||||
|
||||
void init();
|
||||
call __init__ = init;
|
||||
|
||||
void init()
|
||||
{
|
||||
|
||||
}
|
||||
void pexit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int read_buf(int fd, char*buf,int size)
|
||||
{
|
||||
int i = 0;
|
||||
char c = '\0';
|
||||
int n;
|
||||
while ((i < size - 1) && (c != '\n'))
|
||||
{
|
||||
n = read(fd, &c, 1);
|
||||
if (n > 0)
|
||||
{
|
||||
buf[i] = c;
|
||||
i++;
|
||||
}
|
||||
else if(n == -1) return n;
|
||||
else
|
||||
c = '\n';
|
||||
}
|
||||
buf[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
void execute(int client, const char* m, dictionary rq)
|
||||
{
|
||||
textstream(client);
|
||||
int filedes[2];
|
||||
char* code = R_STR(rq, "cmd");
|
||||
if(!code) return;
|
||||
if(pipe(filedes) == -1)
|
||||
{
|
||||
perror("pipe");
|
||||
return;
|
||||
}
|
||||
pid_t pid = fork();
|
||||
if(pid == -1)
|
||||
{
|
||||
perror("folk");
|
||||
return;
|
||||
} else if(pid == 0)
|
||||
{
|
||||
while ((dup2(filedes[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
|
||||
close(filedes[1]);
|
||||
close(filedes[0]);
|
||||
// executecomand
|
||||
system(code);
|
||||
//perror("execl");
|
||||
_exit(1);
|
||||
}
|
||||
close(filedes[1]);
|
||||
char buffer[1024];
|
||||
while (1) {
|
||||
ssize_t count = read_buf(filedes[0],buffer, sizeof(buffer));
|
||||
if (count == -1) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
} else {
|
||||
perror("read");
|
||||
return;
|
||||
}
|
||||
} else if (count == 0) {
|
||||
break;
|
||||
} else {
|
||||
__t(client,"data:%s\n",buffer);
|
||||
//handle_child_process_output(buffer, count);
|
||||
}
|
||||
}
|
||||
close(filedes[0]);
|
||||
wait(0);
|
||||
free(code);
|
||||
printf("Child process exit\n");
|
||||
}
|
Loading…
Reference in New Issue
Block a user