mirror of
https://github.com/lxsang/ant-http
synced 2024-12-26 16:58:22 +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
|
SERVER=plugin_manager.o ini.o http_server.o plugins/dictionary.o plugins/utils.o
|
||||||
SERVERLIB=-lpthread -ldl
|
SERVERLIB=-lpthread -ldl
|
||||||
#-lsocket
|
#-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
|
PLUGINSDEP = plugins/plugin.o plugins/dbhelper.o plugins/dictionary.o plugins/utils.o plugins/list.o
|
||||||
PLUGINLIBS = -lsqlite3
|
PLUGINLIBS = -lsqlite3
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" type="text/css" href="style/font.min.css"/>
|
<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/jquery.min.js"></script>
|
||||||
<script src="scripts/w2ui-1.4.2.js"></script>
|
<script src="scripts/w2ui-1.4.2.js"></script>
|
||||||
<script src="scripts/pluginman.js"></script>
|
<script src="scripts/pluginman.js"></script>
|
||||||
<script src="scripts/fileman.js"></script>
|
<script src="scripts/fileman.js"></script>
|
||||||
<script src="scripts/camviewer.js"></script>
|
<script src="scripts/camviewer.js"></script>
|
||||||
|
<script src="scripts/wterm.js"></script>
|
||||||
<script src="scripts/sidebar.js"></script>
|
<script src="scripts/sidebar.js"></script>
|
||||||
<script src="scripts/rcar.js"></script>
|
<script src="scripts/rcar.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
var picam_config = {
|
var picam_config = {
|
||||||
name: 'picam_layout',
|
name: 'picam_layout',
|
||||||
toolbar:{
|
toolbar:{
|
||||||
|
@ -14,7 +14,8 @@ var sidebar_config = {
|
|||||||
text: 'Plugins',
|
text: 'Plugins',
|
||||||
icon: 'fa-cogs'
|
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':
|
case 'level-picam':
|
||||||
w2ui.layout.content('main', w2ui.picam_layout);
|
w2ui.layout.content('main', w2ui.picam_layout);
|
||||||
break;
|
break;
|
||||||
|
case 'level-wterm':
|
||||||
|
w2ui.layout.content('main', w2ui.wterm_layout);
|
||||||
|
break;
|
||||||
default: //do nothing
|
default: //do nothing
|
||||||
w2ui.layout.content('main',"Empty page");
|
w2ui.layout.content('main',"Empty page");
|
||||||
console.log('Event: ' + event.type + ' Target: ' + event.target);
|
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