Added initial revision of demo application

git-svn-id: https://shellinabox.googlecode.com/svn/trunk@93 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac 2009-03-30 08:41:48 +00:00
parent c19ed2f3ca
commit 3e0241dde3
16 changed files with 916 additions and 43 deletions

View file

@ -1,3 +1,11 @@
2009-03-30 Markus Gutschke <markus@shellinabox.com>
* Added initial revision of demo application
2009-03-29 Markus Gutschke <markus@shellinabox.com>
* Added support for chained SSL certificates
2009-03-23 Markus Gutschke <markus@shellinabox.com>
* Added an INSTALL.Debian file with Debian-specific instructions on

View file

@ -1,9 +1,10 @@
AM_CPPFLAGS =
AM_CFLAGS = -g -std=gnu99 -Wall -Werror -Os
AM_CFLAGS = -g -std=gnu99 -Wall
AM_LDFLAGS = -g
noinst_LTLIBRARIES = libhttp.la \
liblogging.la
noinst_DATA = $(top_srcdir)/demo/demo.js
bin_PROGRAMS = shellinaboxd
man_MANS = shellinaboxd.1
noinst_HEADERS = libhttp/http.h
@ -15,7 +16,14 @@ dist_doc_DATA = AUTHORS \
NEWS \
README \
TODO
EXTRA_DIST = shellinabox/shellinaboxd.man.in \
EXTRA_DIST = demo/beep.wav \
demo/favicon.ico \
demo/demo.html \
demo/demo.js \
demo/demo.jspp \
demo/styles.css \
demo/vt100.js \
shellinabox/shellinaboxd.man.in \
shellinabox/shell_in_a_box.js \
shellinabox/vt100.js \
debian/README \

View file

@ -110,7 +110,7 @@ am__vpath_adj = case $$p in \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
dist_docDATA_INSTALL = $(INSTALL_DATA)
DATA = $(dist_doc_DATA)
DATA = $(dist_doc_DATA) $(noinst_DATA)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
@ -237,11 +237,12 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AM_CPPFLAGS =
AM_CFLAGS = -g -std=gnu99 -Wall -Werror -Os
AM_CFLAGS = -g -std=gnu99 -Wall
AM_LDFLAGS = -g
noinst_LTLIBRARIES = libhttp.la \
liblogging.la
noinst_DATA = $(top_srcdir)/demo/demo.js
man_MANS = shellinaboxd.1
noinst_HEADERS = libhttp/http.h
dist_doc_DATA = AUTHORS \
@ -253,7 +254,14 @@ dist_doc_DATA = AUTHORS \
README \
TODO
EXTRA_DIST = shellinabox/shellinaboxd.man.in \
EXTRA_DIST = demo/beep.wav \
demo/favicon.ico \
demo/demo.html \
demo/demo.js \
demo/demo.jspp \
demo/styles.css \
demo/vt100.js \
shellinabox/shellinaboxd.man.in \
shellinabox/shell_in_a_box.js \
shellinabox/vt100.js \
debian/README \

4
commit
View file

@ -34,7 +34,9 @@ yes_no() {
test -r configure.ac
svn update
{
rev=$(($(svn info | sed -e 's/^Revision: \(.*\)/\1/;t1;d;:1;q')+1))
} 2>/dev/null
prj="$(sed -e 's/^AC_INIT(\([^,]*\),.*/\1/;t1;d;:1;q' configure.ac)"
ver="$(sed -e 's/^AC_INIT([^,]*, *\([^,]*\),.*/\1/;t1;d;:1;q' configure.ac)"
sed -ie 's/^\(VCS_REVISION=\).*/\1'"${rev}"'/' configure.ac
@ -43,7 +45,7 @@ make all distcheck
rm -f "${prj}-${ver}" &&
tar zfx "${prj}-${ver}.tar.gz" &&
cd "${prj}-${ver}" &&
{ fakeroot dpkg-buildpackage || :; } &&
fakeroot dpkg-buildpackage -us -uc &&
cd .. &&
rm -f $(ls "${prj}_${ver}-"*.* | egrep -v '.deb$') ) || :
svn diff $(svn st |

View file

@ -95,7 +95,7 @@
#define STDC_HEADERS 1
/* Most recent revision number in the version control system */
#define VCS_REVISION "91"
#define VCS_REVISION "93"
/* Version number of package */
#define VERSION "2.5"

54
configure vendored
View file

@ -754,6 +754,7 @@ PACKAGE_VERSION='2.5'
PACKAGE_STRING='shellinabox 2.5'
PACKAGE_BUGREPORT='markus@shellinabox.com'
ac_c_werror_flag=
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
@ -2055,7 +2056,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
VCS_REVISION=91
VCS_REVISION=93
cat >>confdefs.h <<_ACEOF
@ -2063,6 +2064,7 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
CFLAGS="${CFLAGS:--Os}"
am__api_version='1.10'
ac_aux_dir=
@ -3658,6 +3660,8 @@ else
fi
ac_c_werror_flag=yes
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
@ -4531,7 +4535,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
echo '#line 4534 "configure"' > conftest.$ac_ext
echo '#line 4538 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@ -7616,11 +7620,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7619: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7623: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7623: \$? = $ac_status" >&5
echo "$as_me:7627: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -7906,11 +7910,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7909: $lt_compile\"" >&5)
(eval echo "\"\$as_me:7913: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:7913: \$? = $ac_status" >&5
echo "$as_me:7917: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -8010,11 +8014,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:8013: $lt_compile\"" >&5)
(eval echo "\"\$as_me:8017: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:8017: \$? = $ac_status" >&5
echo "$as_me:8021: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -10423,7 +10427,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10426 "configure"
#line 10430 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -10523,7 +10527,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
#line 10526 "configure"
#line 10530 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@ -12932,11 +12936,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:12935: $lt_compile\"" >&5)
(eval echo "\"\$as_me:12939: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:12939: \$? = $ac_status" >&5
echo "$as_me:12943: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -13036,11 +13040,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:13039: $lt_compile\"" >&5)
(eval echo "\"\$as_me:13043: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:13043: \$? = $ac_status" >&5
echo "$as_me:13047: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -14634,11 +14638,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:14637: $lt_compile\"" >&5)
(eval echo "\"\$as_me:14641: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:14641: \$? = $ac_status" >&5
echo "$as_me:14645: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -14738,11 +14742,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:14741: $lt_compile\"" >&5)
(eval echo "\"\$as_me:14745: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:14745: \$? = $ac_status" >&5
echo "$as_me:14749: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -16966,11 +16970,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16969: $lt_compile\"" >&5)
(eval echo "\"\$as_me:16973: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:16973: \$? = $ac_status" >&5
echo "$as_me:16977: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -17256,11 +17260,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:17259: $lt_compile\"" >&5)
(eval echo "\"\$as_me:17263: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
echo "$as_me:17263: \$? = $ac_status" >&5
echo "$as_me:17267: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@ -17360,11 +17364,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:17363: $lt_compile\"" >&5)
(eval echo "\"\$as_me:17367: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
echo "$as_me:17367: \$? = $ac_status" >&5
echo "$as_me:17371: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@ -20565,7 +20569,7 @@ cat >>conftest.$ac_ext <<_ACEOF
int
main ()
{
ptsname_r(0, 0, 0);
char buf[10]; ptsname_r(0, buf, sizeof(buf));
;
return 0;
}

View file

@ -2,15 +2,17 @@ AC_PREREQ(2.57)
dnl This is the one location where the authoritative version number is stored
AC_INIT(shellinabox, 2.5, markus@shellinabox.com)
VCS_REVISION=91
VCS_REVISION=93
AC_SUBST(VCS_REVISION)
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
[Most recent revision number in the version control system])
dnl Set up autoconf/automake for building C libraries and binaries with GCC
CFLAGS="${CFLAGS:--Os}"
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_LANG_WERROR
AC_PROG_INSTALL
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
@ -34,7 +36,7 @@ AC_TRY_LINK([#ifndef _XOPEN_SOURCE
#define _GNU_SOURCE
#endif
#include <stdlib.h>],
[ptsname_r(0, 0, 0);],
[char buf[10]; ptsname_r(0, buf, sizeof(buf));],
[AC_DEFINE(HAVE_PTSNAME_R, 1,
Define to 1 if you have a re-entrant version of ptsname)])

1
demo/beep.wav Symbolic link
View file

@ -0,0 +1 @@
../shellinabox/beep.wav

79
demo/demo.html Normal file
View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xml:lang="en" lang="en">
<head>
<!--
ShellInABox - Make command line applications available as AJAX web applications
Copyright (C) 2008-2009 Markus Gutschke markus@shellinabox.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
In addition to these license terms, the author grants the following
additional rights:
If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the author
grants you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination
shall include the source code for the parts of OpenSSL used as well
as that of the covered work.
You may at your option choose to remove this additional permission from
the work, or from any part of it.
It is possible to build this program in a way that it loads OpenSSL
libraries at run-time. If doing so, the following notices are required
by the OpenSSL and SSLeay licenses:
This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit. (http://www.openssl.org/)
This product includes cryptographic software written by Eric Young
(eay@cryptsoft.com)
The most up-to-date version of this program is always available from
http://shellinabox.com
-->
<title>Shell In A Box</title>
<link rel="stylesheet" href="styles.css" type="text/css">
<script type="text/javascript"><!--
// We would like to hide overflowing lines as this can lead to
// visually jarring results if the browser substitutes oversized
// Unicode characters from different fonts. Unfortunately, a bug
// in Firefox prevents it from allowing multi-line text
// selections whenever we change the "overflow" style. So, only
// do so for non-Netscape browsers.
if (typeof navigator.appName == 'undefined' ||
navigator.appName != 'Netscape') {
document.write('<style type="text/css">' +
'#vt100 #console div, #vt100 #alt_console div {' +
' overflow: hidden;' +
'}' +
'</style>');
}
--></script>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<script type="text/javascript" src="vt100.js"></script>
<script type="text/javascript" src="demo.js"></script>
</head>
<!-- Load ShellInABox from a timer as Konqueror sometimes fails to
correctly deal with the enclosing frameset (if any), if we do not
do this
-->
<body onload="setTimeout('new Demo()', 100)"
scroll="no"><noscript>JavaScript
must be enabled for ShellInABox</noscript></body>
</html>

371
demo/demo.js Normal file
View file

@ -0,0 +1,371 @@
// Demo.js -- Demonstrate some of the features of ShellInABox
// Copyright (C) 2008-2009 Markus Gutschke <markus@shellinabox.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// In addition to these license terms, the author grants the following
// additional rights:
//
// If you modify this program, or any covered work, by linking or
// combining it with the OpenSSL project's OpenSSL library (or a
// modified version of that library), containing parts covered by the
// terms of the OpenSSL or SSLeay licenses, the author
// grants you additional permission to convey the resulting work.
// Corresponding Source for a non-source form of such a combination
// shall include the source code for the parts of OpenSSL used as well
// as that of the covered work.
//
// You may at your option choose to remove this additional permission from
// the work, or from any part of it.
//
// It is possible to build this program in a way that it loads OpenSSL
// libraries at run-time. If doing so, the following notices are required
// by the OpenSSL and SSLeay licenses:
//
// This product includes software developed by the OpenSSL Project
// for use in the OpenSSL Toolkit. (http://www.openssl.org/)
//
// This product includes cryptographic software written by Eric Young
// (eay@cryptsoft.com)
//
//
// The most up-to-date version of this program is always available from
// http://shellinabox.com
//
//
// Notes:
//
// The author believes that for the purposes of this license, you meet the
// requirements for publishing the source code, if your web server publishes
// the source in unmodified form (i.e. with licensing information, comments,
// formatting, and identifier names intact). If there are technical reasons
// that require you to make changes to the source code when serving the
// JavaScript (e.g to remove pre-processor directives from the source), these
// changes should be done in a reversible fashion.
//
// The author does not consider websites that reference this script in
// unmodified form, and web servers that serve this script in unmodified form
// to be derived works. As such, they are believed to be outside of the
// scope of this license and not subject to the rights or restrictions of the
// GNU General Public License.
//
// If in doubt, consult a legal professional familiar with the laws that
// apply in your country.
// #define STATE_IDLE 0
// #define STATE_INIT 1
// #define STATE_PROMPT 2
// #define STATE_READLINE 3
// #define STATE_COMMAND 4
// #define STATE_EVAL 5
// #define STATE_RUN 6
// #define STATE_EXEC 7
function extend(subClass, baseClass) {
function inheritance() { }
inheritance.prototype = baseClass.prototype;
subClass.prototype = new inheritance();
subClass.prototype.constructor = subClass;
subClass.prototype.superClass = baseClass.prototype;
};
function Demo(container) {
this.superClass.constructor.call(this, container);
this.gotoState(1 /* STATE_INIT */);
};
extend(Demo, VT100);
Demo.prototype.keysPressed = function(ch) {
this.keys += ch;
this.gotoState(this.state);
};
Demo.prototype.gotoState = function(state, tmo) {
this.state = state;
if (!this.timer || tmo) {
if (!tmo) {
tmo = 1;
}
this.timer = setTimeout(function(demo) {
return function() {
demo.demo();
};
}(this), tmo);
}
};
Demo.prototype.demo = function() {
var done = false;
while (!done) {
var state = this.state;
this.state = 0 /* STATE_IDLE */;
switch (state) {
case 1 /* STATE_INIT */:
this.doInit();
break;
case 2 /* STATE_PROMPT */:
this.doPrompt();
break;
case 3 /* STATE_READLINE */:
this.doReadLine();
if (this.state == 3 /* STATE_READLINE */) {
done = true;
}
break;
case 4 /* STATE_COMMAND */:
this.doCommand();
break;
case 5 /* STATE_EVAL */:
this.doEval();
break;
case 6 /* STATE_RUN */:
this.doRun();
break;
case 7 /* STATE_EXEC */:
if (this.doExec()) {
return;
}
break;
case 0 /* STATE_IDLE */:
default:
done = true;
break;
}
}
this.timer = undefined;
};
Demo.prototype.error = function(msg) {
if (msg == undefined) {
msg = 'Syntax Error';
}
this.vt100('\u0007? ' + msg + '\r\n');
this.gotoState(2 /* STATE_PROMPT */);
};
Demo.prototype.doInit = function() {
this.program = new Array();
this.vt100(
'\u001Bc\u001B[34;4m' +
'ShellInABox Demo Script\u001B[24;31m\r\n' +
'\r\n' +
'Copyright 2009 by Markus Gutschke <markus@shellinabox.com>\u001B[0m\r\n' +
'\r\n' +
'\r\n' +
'This script simulates a minimal BASIC interpreter, allowing you to\r\n' +
'experiment with the JavaScript terminal emulator that is part of\r\n' +
'the ShellInABox project.\r\n' +
'\r\n' +
'Type HELP for a list of commands.\r\n' +
'\r\n');
this.gotoState(2 /* STATE_PROMPT */);
};
Demo.prototype.doPrompt = function() {
this.keys = '';
this.line = '';
this.currentLineIndex = -1;
this.vt100('> ');
this.gotoState(3 /* STATE_READLINE */);
};
Demo.prototype.doReadLine = function() {
this.gotoState(3 /* STATE_READLINE */);
var keys = this.keys;
this.keys = '';
for (var i = 0; i < keys.length; i++) {
var ch = keys.charAt(i);
if (ch >= ' ' && ch < '\u007F' || ch > '\u00A0') {
this.line += ch;
this.vt100(ch);
} else if (ch == '\r' || ch == '\n') {
this.vt100('\r\n');
this.gotoState(4 /* STATE_COMMAND */);
} else if (ch == '\u0008' || ch == '\u007F') {
if (this.line.length > 0) {
this.line = this.line.substr(0, this.line.length - 1);
if (this.cursorX == 0) {
var x = this.terminalWidth - 1;
var y = this.cursorY - 1;
this.gotoXY(x, y);
this.vt100(' ');
this.gotoXY(x, y);
} else {
this.vt100('\u0008 \u0008');
}
} else {
this.vt100('\u0007');
}
} else if (ch == '\u001B') {
// This was probably a function key. Just eat all of the following keys.
break;
}
}
};
Demo.prototype.doCommand = function() {
this.gotoState(2 /* STATE_PROMPT */);
var tokens = new Tokens(this.line);
this.line = '';
var cmd = tokens.nextToken().toUpperCase();
if (cmd.match(/^[0-9]+$/)) {
tokens.removeLineNumber();
var lineNumber = parseInt(cmd);
var index = this.findLine(lineNumber);
if (tokens.nextToken() == undefined) {
if (index > 0) {
// Delete line from program
this.program.splice(index, 1);
}
} else {
if (index >= 0) {
// Replace line in program
this.program[index].setTokens(tokens);
} else {
// Add new line to program
this.program.splice(-index - 1, 0, new Line(lineNumber, tokens));
}
}
} else {
this.currentLineIndex = -1;
this.tokens = tokens;
this.gotoState(5 /* STATE_EVAL */);
}
tokens.reset();
};
Demo.prototype.doEval = function() {
this.gotoState(2 /* STATE_PROMPT */);
var cmd = this.tokens.nextToken().toUpperCase();
if (cmd == "HELP") {
this.vt100('Supported commands:\r\n' +
' HELP LIST RUN\r\n');
} else if (cmd == "LIST") {
if (this.tokens.nextToken() != undefined) {
this.error();
return false;
} else {
for (var i = 0; i < this.program.length; i++) {
var line = this.program[i];
this.vt100('' + line.lineNumber());
line.tokens().reset();
for (var token; (token = line.tokens().nextToken()) != undefined; ) {
this.vt100(' ' + token);
}
line.tokens().reset();
this.vt100('\r\n');
}
}
} else if (cmd == "RUN") {
if (this.tokens.nextToken() != undefined) {
this.error();
} else {
this.gotoState(6 /* STATE_RUN */);
}
return false;
} else {
this.error();
return false;
}
return true;
};
Demo.prototype.doRun = function() {
if (this.program.length > 0) {
this.currentLineIndex = 0;
this.gotoState(7 /* STATE_EXEC */);
}
};
Demo.prototype.doExec = function() {
this.tokens = this.program[this.currentLineIndex++].tokens();
this.tokens.reset();
if (this.doEval()) {
if (this.currentLineIndex >= this.program.length) {
this.gotoState(2 /* STATE_PROMPT */);
return false;
} else {
this.gotoState(7 /* STATE_EXEC */, 20);
return true;
}
}
};
Demo.prototype.findLine = function(lineNumber) {
var l = 0;
var h = this.program.length;
while (h > l) {
var m = Math.floor((l + h) / 2);
var n = this.program[m].lineNumber();
if (n == lineNumber) {
return m;
} else if (n > lineNumber) {
h = m;
} else {
l = m + 1;
}
}
return -l - 1;
};
function Tokens(line) {
this.tokens = line.split(' ');
this.index = 0;
};
Tokens.prototype.nextToken = function() {
while (this.index < this.tokens.length) {
var token = this.tokens[this.index++];
token = token.replace(/^[ \t]*/, '');
token = token.replace(/[ \t]*$/, '');
if (token.length) {
return token;
}
}
return undefined;
};
Tokens.prototype.removeLineNumber = function() {
if (this.tokens.length > 0) {
this.tokens.splice(0, 1);
if (this.index > 0) {
this.index--;
}
}
};
Tokens.prototype.reset = function() {
this.index = 0;
};
function Line(lineNumber, tokens) {
this.lineNumber_ = lineNumber;
this.tokens_ = tokens;
};
Line.prototype.lineNumber = function() {
return this.lineNumber_;
};
Line.prototype.tokens = function() {
return this.tokens_;
};
Line.prototype.setTokens = function(tokens) {
this.tokens_ = tokens;
};
Line.prototype.sort = function(a, b) {
return a.lineNumber_ - b.lineNumber_;
};

371
demo/demo.jspp Normal file
View file

@ -0,0 +1,371 @@
// Demo.js -- Demonstrate some of the features of ShellInABox
// Copyright (C) 2008-2009 Markus Gutschke <markus@shellinabox.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// In addition to these license terms, the author grants the following
// additional rights:
//
// If you modify this program, or any covered work, by linking or
// combining it with the OpenSSL project's OpenSSL library (or a
// modified version of that library), containing parts covered by the
// terms of the OpenSSL or SSLeay licenses, the author
// grants you additional permission to convey the resulting work.
// Corresponding Source for a non-source form of such a combination
// shall include the source code for the parts of OpenSSL used as well
// as that of the covered work.
//
// You may at your option choose to remove this additional permission from
// the work, or from any part of it.
//
// It is possible to build this program in a way that it loads OpenSSL
// libraries at run-time. If doing so, the following notices are required
// by the OpenSSL and SSLeay licenses:
//
// This product includes software developed by the OpenSSL Project
// for use in the OpenSSL Toolkit. (http://www.openssl.org/)
//
// This product includes cryptographic software written by Eric Young
// (eay@cryptsoft.com)
//
//
// The most up-to-date version of this program is always available from
// http://shellinabox.com
//
//
// Notes:
//
// The author believes that for the purposes of this license, you meet the
// requirements for publishing the source code, if your web server publishes
// the source in unmodified form (i.e. with licensing information, comments,
// formatting, and identifier names intact). If there are technical reasons
// that require you to make changes to the source code when serving the
// JavaScript (e.g to remove pre-processor directives from the source), these
// changes should be done in a reversible fashion.
//
// The author does not consider websites that reference this script in
// unmodified form, and web servers that serve this script in unmodified form
// to be derived works. As such, they are believed to be outside of the
// scope of this license and not subject to the rights or restrictions of the
// GNU General Public License.
//
// If in doubt, consult a legal professional familiar with the laws that
// apply in your country.
#define STATE_IDLE 0
#define STATE_INIT 1
#define STATE_PROMPT 2
#define STATE_READLINE 3
#define STATE_COMMAND 4
#define STATE_EVAL 5
#define STATE_RUN 6
#define STATE_EXEC 7
function extend(subClass, baseClass) {
function inheritance() { }
inheritance.prototype = baseClass.prototype;
subClass.prototype = new inheritance();
subClass.prototype.constructor = subClass;
subClass.prototype.superClass = baseClass.prototype;
};
function Demo(container) {
this.superClass.constructor.call(this, container);
this.gotoState(STATE_INIT);
};
extend(Demo, VT100);
Demo.prototype.keysPressed = function(ch) {
this.keys += ch;
this.gotoState(this.state);
};
Demo.prototype.gotoState = function(state, tmo) {
this.state = state;
if (!this.timer || tmo) {
if (!tmo) {
tmo = 1;
}
this.timer = setTimeout(function(demo) {
return function() {
demo.demo();
};
}(this), tmo);
}
};
Demo.prototype.demo = function() {
var done = false;
while (!done) {
var state = this.state;
this.state = STATE_IDLE;
switch (state) {
case STATE_INIT:
this.doInit();
break;
case STATE_PROMPT:
this.doPrompt();
break;
case STATE_READLINE:
this.doReadLine();
if (this.state == STATE_READLINE) {
done = true;
}
break;
case STATE_COMMAND:
this.doCommand();
break;
case STATE_EVAL:
this.doEval();
break;
case STATE_RUN:
this.doRun();
break;
case STATE_EXEC:
if (this.doExec()) {
return;
}
break;
case STATE_IDLE:
default:
done = true;
break;
}
}
this.timer = undefined;
};
Demo.prototype.error = function(msg) {
if (msg == undefined) {
msg = 'Syntax Error';
}
this.vt100('\u0007? ' + msg + '\r\n');
this.gotoState(STATE_PROMPT);
};
Demo.prototype.doInit = function() {
this.program = new Array();
this.vt100(
'\u001Bc\u001B[34;4m' +
'ShellInABox Demo Script\u001B[24;31m\r\n' +
'\r\n' +
'Copyright 2009 by Markus Gutschke <markus@shellinabox.com>\u001B[0m\r\n' +
'\r\n' +
'\r\n' +
'This script simulates a minimal BASIC interpreter, allowing you to\r\n' +
'experiment with the JavaScript terminal emulator that is part of\r\n' +
'the ShellInABox project.\r\n' +
'\r\n' +
'Type HELP for a list of commands.\r\n' +
'\r\n');
this.gotoState(STATE_PROMPT);
};
Demo.prototype.doPrompt = function() {
this.keys = '';
this.line = '';
this.currentLineIndex = -1;
this.vt100('> ');
this.gotoState(STATE_READLINE);
};
Demo.prototype.doReadLine = function() {
this.gotoState(STATE_READLINE);
var keys = this.keys;
this.keys = '';
for (var i = 0; i < keys.length; i++) {
var ch = keys.charAt(i);
if (ch >= ' ' && ch < '\u007F' || ch > '\u00A0') {
this.line += ch;
this.vt100(ch);
} else if (ch == '\r' || ch == '\n') {
this.vt100('\r\n');
this.gotoState(STATE_COMMAND);
} else if (ch == '\u0008' || ch == '\u007F') {
if (this.line.length > 0) {
this.line = this.line.substr(0, this.line.length - 1);
if (this.cursorX == 0) {
var x = this.terminalWidth - 1;
var y = this.cursorY - 1;
this.gotoXY(x, y);
this.vt100(' ');
this.gotoXY(x, y);
} else {
this.vt100('\u0008 \u0008');
}
} else {
this.vt100('\u0007');
}
} else if (ch == '\u001B') {
// This was probably a function key. Just eat all of the following keys.
break;
}
}
};
Demo.prototype.doCommand = function() {
this.gotoState(STATE_PROMPT);
var tokens = new Tokens(this.line);
this.line = '';
var cmd = tokens.nextToken().toUpperCase();
if (cmd.match(/^[0-9]+$/)) {
tokens.removeLineNumber();
var lineNumber = parseInt(cmd);
var index = this.findLine(lineNumber);
if (tokens.nextToken() == undefined) {
if (index > 0) {
// Delete line from program
this.program.splice(index, 1);
}
} else {
if (index >= 0) {
// Replace line in program
this.program[index].setTokens(tokens);
} else {
// Add new line to program
this.program.splice(-index - 1, 0, new Line(lineNumber, tokens));
}
}
} else {
this.currentLineIndex = -1;
this.tokens = tokens;
this.gotoState(STATE_EVAL);
}
tokens.reset();
};
Demo.prototype.doEval = function() {
this.gotoState(STATE_PROMPT);
var cmd = this.tokens.nextToken().toUpperCase();
if (cmd == "HELP") {
this.vt100('Supported commands:\r\n' +
' HELP LIST RUN\r\n');
} else if (cmd == "LIST") {
if (this.tokens.nextToken() != undefined) {
this.error();
return false;
} else {
for (var i = 0; i < this.program.length; i++) {
var line = this.program[i];
this.vt100('' + line.lineNumber());
line.tokens().reset();
for (var token; (token = line.tokens().nextToken()) != undefined; ) {
this.vt100(' ' + token);
}
line.tokens().reset();
this.vt100('\r\n');
}
}
} else if (cmd == "RUN") {
if (this.tokens.nextToken() != undefined) {
this.error();
} else {
this.gotoState(STATE_RUN);
}
return false;
} else {
this.error();
return false;
}
return true;
};
Demo.prototype.doRun = function() {
if (this.program.length > 0) {
this.currentLineIndex = 0;
this.gotoState(STATE_EXEC);
}
};
Demo.prototype.doExec = function() {
this.tokens = this.program[this.currentLineIndex++].tokens();
this.tokens.reset();
if (this.doEval()) {
if (this.currentLineIndex >= this.program.length) {
this.gotoState(STATE_PROMPT);
return false;
} else {
this.gotoState(STATE_EXEC, 20);
return true;
}
}
};
Demo.prototype.findLine = function(lineNumber) {
var l = 0;
var h = this.program.length;
while (h > l) {
var m = Math.floor((l + h) / 2);
var n = this.program[m].lineNumber();
if (n == lineNumber) {
return m;
} else if (n > lineNumber) {
h = m;
} else {
l = m + 1;
}
}
return -l - 1;
};
function Tokens(line) {
this.tokens = line.split(' ');
this.index = 0;
};
Tokens.prototype.nextToken = function() {
while (this.index < this.tokens.length) {
var token = this.tokens[this.index++];
token = token.replace(/^[ \t]*/, '');
token = token.replace(/[ \t]*$/, '');
if (token.length) {
return token;
}
}
return undefined;
};
Tokens.prototype.removeLineNumber = function() {
if (this.tokens.length > 0) {
this.tokens.splice(0, 1);
if (this.index > 0) {
this.index--;
}
}
};
Tokens.prototype.reset = function() {
this.index = 0;
};
function Line(lineNumber, tokens) {
this.lineNumber_ = lineNumber;
this.tokens_ = tokens;
};
Line.prototype.lineNumber = function() {
return this.lineNumber_;
};
Line.prototype.tokens = function() {
return this.tokens_;
};
Line.prototype.setTokens = function(tokens) {
this.tokens_ = tokens;
};
Line.prototype.sort = function(a, b) {
return a.lineNumber_ - b.lineNumber_;
};

1
demo/favicon.ico Symbolic link
View file

@ -0,0 +1 @@
../shellinabox/favicon.ico

1
demo/styles.css Symbolic link
View file

@ -0,0 +1 @@
../shellinabox/styles.css

1
demo/vt100.js Symbolic link
View file

@ -0,0 +1 @@
../shellinabox/vt100.js

View file

@ -46,6 +46,9 @@
#define _GNU_SOURCE
#include "config.h"
#define pthread_once x_pthread_once
#define pthread_sigmask x_pthread_sigmask
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
@ -61,6 +64,9 @@
#include "libhttp/httpconnection.h"
#include "logging/logging.h"
#undef pthread_once
#undef pthread_sigmask
#if defined(HAVE_OPENSSL) && !defined(OPENSSL_NO_TLSEXT) && \
defined(TLSEXT_NAMETYPE_host_name) && defined(SSL_TLSEXT_ERR_OK)
#define HAVE_TLSEXT
@ -683,8 +689,11 @@ void sslBlockSigPipe(void) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
dcheck(!(&pthread_sigmask ? pthread_sigmask : sigprocmask)
(SIG_BLOCK, &set, NULL));
if (&pthread_sigmask) {
dcheck(!pthread_sigmask(SIG_BLOCK, &set, NULL));
} else {
dcheck(!sigprocmask(SIG_BLOCK, &set, NULL));
}
}
int sslUnblockSigPipe(void) {
@ -696,8 +705,11 @@ int sslUnblockSigPipe(void) {
}
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
check(!(&pthread_sigmask ? pthread_sigmask : sigprocmask)
(SIG_UNBLOCK, &set, NULL));
if (&pthread_sigmask) {
dcheck(!pthread_sigmask(SIG_UNBLOCK, &set, NULL));
} else {
dcheck(!sigprocmask(SIG_UNBLOCK, &set, NULL));
}
return signum;
}

View file

@ -46,6 +46,8 @@
#define _GNU_SOURCE
#include "config.h"
#define pthread_once x_pthread_once
#include <dirent.h>
#include <dlfcn.h>
#include <fcntl.h>
@ -91,17 +93,19 @@ struct pam_conv;
typedef struct pam_handle pam_handle_t;
#endif
#if defined(HAVE_PTHREAD_H) && defined(__linux__)
#include <pthread.h>
extern int pthread_once(pthread_once_t *, void (*)(void))__attribute__((weak));
#endif
#include "shellinabox/launcher.h"
#include "shellinabox/privileges.h"
#include "shellinabox/service.h"
#include "libhttp/hashmap.h"
#include "logging/logging.h"
#undef pthread_once
#if defined(HAVE_PTHREAD_H) && defined(__linux__)
#include <pthread.h>
extern int pthread_once(pthread_once_t *, void (*)(void))__attribute__((weak));
#endif
// If PAM support is available, take advantage of it. Otherwise, silently fall
// back on legacy operations for session management.
#if defined(HAVE_SECURITY_PAM_APPL_H) && defined(HAVE_DLOPEN)