For Debian packages, install user CSS style options in /etc/shellinabox and

automatically pick them up when the service starts.

Persist preferences when the user changes them in the context menu.


git-svn-id: https://shellinabox.googlecode.com/svn/trunk@170 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac 2009-08-15 05:24:31 +00:00
parent 5eade3daff
commit e3a4eb95e3
16 changed files with 278 additions and 33 deletions

View file

@ -37,6 +37,8 @@ EXTRA_DIST = demo/beep.wav \
shellinabox/shell_in_a_box.js \ shellinabox/shell_in_a_box.js \
shellinabox/vt100.js \ shellinabox/vt100.js \
debian/README \ debian/README \
debian/README.available \
debian/README.enabled \
debian/changelog \ debian/changelog \
debian/compat \ debian/compat \
debian/control \ debian/control \

View file

@ -277,6 +277,8 @@ EXTRA_DIST = demo/beep.wav \
shellinabox/shell_in_a_box.js \ shellinabox/shell_in_a_box.js \
shellinabox/vt100.js \ shellinabox/vt100.js \
debian/README \ debian/README \
debian/README.available \
debian/README.enabled \
debian/changelog \ debian/changelog \
debian/compat \ debian/compat \
debian/control \ debian/control \

View file

@ -138,7 +138,7 @@
#define STDC_HEADERS 1 #define STDC_HEADERS 1
/* Most recent revision number in the version control system */ /* Most recent revision number in the version control system */
#define VCS_REVISION "169" #define VCS_REVISION "170"
/* Version number of package */ /* Version number of package */
#define VERSION "2.9" #define VERSION "2.9"

2
configure vendored
View file

@ -2317,7 +2317,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_compiler_gnu=$ac_cv_c_compiler_gnu
VCS_REVISION=169 VCS_REVISION=170
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF

View file

@ -2,7 +2,7 @@ AC_PREREQ(2.57)
dnl This is the one location where the authoritative version number is stored dnl This is the one location where the authoritative version number is stored
AC_INIT(shellinabox, 2.9, markus@shellinabox.com) AC_INIT(shellinabox, 2.9, markus@shellinabox.com)
VCS_REVISION=169 VCS_REVISION=170
AC_SUBST(VCS_REVISION) AC_SUBST(VCS_REVISION)
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}", AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
[Most recent revision number in the version control system]) [Most recent revision number in the version control system])

21
debian/README.available vendored Normal file
View file

@ -0,0 +1,21 @@
This directory contains all of the available user CSS style sheets.
These options will show up in the right click context menu.
In order to en-/disable the availability of options, add/remove the
appropriate symbolic link in "/etc/shellinabox/options-enabled" and
restart the daemon with "sudo /etc/init.d/shellinabox restart".
All options are of the form "ID_Name of Option.css". Any options with
identical IDs will be put into the same option group. They are
mutually exclusive and only one such option can selected at any given
time.
Please note that ':', ',', and ';' are all invalid characters in
option names.
Options that should be turned on by default have the "_" character
replaced with a "+" character.
In any group of mutually exclusive options, there must be exactly one
option that is turned on.

3
debian/README.enabled vendored Normal file
View file

@ -0,0 +1,3 @@
This directory contains links to "/etc/shellinabox/options-available". See
that directory for more details on how to enable or disable options that
show up in the right-click context menu.

2
debian/compat vendored
View file

@ -1 +1 @@
4 7

4
debian/docs vendored
View file

@ -5,7 +5,3 @@ INSTALL
NEWS NEWS
README README
TODO TODO
shellinabox/white-on-black.css
shellinabox/black-on-white.css
shellinabox/monochrome.css
shellinabox/color.css

21
debian/rules vendored
View file

@ -72,8 +72,23 @@ install: build
dh_clean -k dh_clean -k
dh_installdirs dh_installdirs
@# Add here commands to install the package into debian/tmp @# Add here commands to install the package into debian/tmp
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp $(MAKE) install DESTDIR="$(CURDIR)/debian/tmp"
# Set up system-wide user CSS style options
mkdir -p "$(CURDIR)/debian/tmp/etc/shellinabox/options-available" \
"$(CURDIR)/debian/tmp/etc/shellinabox/options-enabled"
for i in "00+Black on White" "00_White On Black" \
"01_Monochrome" "01+Color Terminal"; do \
ln "$(CURDIR)/debian/tmp/usr/share/doc/shellinabox/$$(echo "$$i"| \
sed -e 's/[0-9]*[_+]\([^ ]*\).*/\1/'| \
tr A-Z a-z)"*.css \
"$(CURDIR)/debian/tmp/etc/shellinabox/options-available/$$i.css";\
done
cd "$(CURDIR)/debian/tmp/etc/shellinabox/options-enabled" && \
ln -s ../options-available/*.css .
cp "$(CURDIR)/debian/README.available" \
"$(CURDIR)/debian/tmp/etc/shellinabox/options-available/README"
cp "$(CURDIR)/debian/README.enabled" \
"$(CURDIR)/debian/tmp/etc/shellinabox/options-enabled/README"
# Build architecture-independent files here. # Build architecture-independent files here.
binary-indep: build install binary-indep: build install
@ -86,7 +101,7 @@ binary-arch: build install
dh_installchangelogs ChangeLog dh_installchangelogs ChangeLog
dh_installdocs --exclude COPYING --exclude INSTALL --exclude ChangeLog dh_installdocs --exclude COPYING --exclude INSTALL --exclude ChangeLog
dh_installexamples dh_installexamples
dh_install --sourcedir=debian/tmp dh_install
# dh_installmenu # dh_installmenu
# dh_installdebconf # dh_installdebconf
# dh_installlogrotate # dh_installlogrotate

View file

@ -44,6 +44,20 @@ d_start() {
--exec "'$DAEMON'" -- -q --background="'$PIDFILE'" \ --exec "'$DAEMON'" -- -q --background="'$PIDFILE'" \
-c "'${SHELLINABOX_DATADIR}'" -p "'${SHELLINABOX_PORT}'" \ -c "'${SHELLINABOX_DATADIR}'" -p "'${SHELLINABOX_PORT}'" \
-u "'${SHELLINABOX_USER}'" -g "'${SHELLINABOX_GROUP}'" \ -u "'${SHELLINABOX_USER}'" -g "'${SHELLINABOX_GROUP}'" \
$(for i in $(ls /etc/shellinabox/options-enabled/*.css |
sed -e \
's/.*[/]\([0-9]*\)[-_+][^/:,;]*[.]css/\1/'|
sort -u); do
for j in /etc/shellinabox/options-enabled/"$i"*.css; do
echo -n "$j" |
sed -e 's/\(.*[/]\)\([0-9]*\)\([-_+]\)\([^/:,;]*\)[.]css/\4:\3\1\2\3\4.css,/
s/:_/:-/'
done |
sed -e 's/,$/;/'
done |
sed -e 's/;$//
//b
s/.*/--user-css "\0"/') \
"${SHELLINABOX_ARGS}" "${SHELLINABOX_ARGS}"
} }

View file

@ -1,4 +1,4 @@
usr/bin/* etc/shellinabox/options-available
usr/share/man/man1/* etc/shellinabox/options-enabled
debian/tmp/usr/bin/* usr/bin
debian/tmp/usr/share/man/man1/* usr/share/man/man1

View file

@ -173,6 +173,7 @@ function VT100(container) {
// Optional arguments // Optional arguments
'(?:[?](?:(?![ \u00A0]|[,.)}"\u0027!]+[ \u00A0]|[,.)}"\u0027!]+$).)*)?'); '(?:[?](?:(?![ \u00A0]|[,.)}"\u0027!]+[ \u00A0]|[,.)}"\u0027!]+$).)*)?');
} }
this.getUserSettings();
this.initializeElements(container); this.initializeElements(container);
this.maxScrollbackLines = 500; this.maxScrollbackLines = 500;
this.npar = 0; this.npar = 0;
@ -203,10 +204,7 @@ VT100.prototype.reset = function(clearHistory) {
this.crLfMode = false; this.crLfMode = false;
this.offsetMode = false; this.offsetMode = false;
this.mouseReporting = false; this.mouseReporting = false;
this.utfEnabled = true; this.utfEnabled = this.utfPreferred;
this.visualBell = typeof suppressAllAudio !=
'undefined' &&
suppressAllAudio;
this.utfCount = 0; this.utfCount = 0;
this.utfChar = 0; this.utfChar = 0;
this.color = 'ansi0 bgAnsi15'; this.color = 'ansi0 bgAnsi15';
@ -248,6 +246,66 @@ VT100.prototype.addListener = function(elem, event, listener) {
} }
}; };
VT100.prototype.getUserSettings = function() {
// Compute hash signature to identify the entries in the userCSS menu.
// If the menu is unchanged from last time, default values can be
// looked up in a cookie associated with this page.
this.signature = 0;
this.utfPreferred = true;
this.visualBell = typeof suppressAllAudio != 'undefined' &&
suppressAllAudio;
if (this.visualBell) {
this.signature = Math.floor(16807*this.signature + 1) %
((1 << 31) - 1);
}
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
var label = userCSSList[i][0];
for (var j = 0; j < label.length; ++j) {
this.signature = Math.floor(16807*this.signature+
label.charCodeAt(j)) %
((1 << 31) - 1);
}
if (userCSSList[i][1]) {
this.signature = Math.floor(16807*this.signature + 1) %
((1 << 31) - 1);
}
}
}
var key = 'shellInABox=' + this.signature + ':';
var settings = document.cookie.indexOf(key);
if (settings >= 0) {
settings = document.cookie.substr(settings + key.length).
replace(/([0-1]*).*/, "$1");
if (settings.length == 2 + (typeof userCSSList == 'undefined' ?
0 : userCSSList.length)) {
this.utfPreferred = settings.charAt(0) != '0';
this.visualBell = settings.charAt(1) != '0';
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
userCSSList[i][2] = settings.charAt(i + 2) != '0';
}
}
}
}
this.utfEnabled = this.utfPreferred;
};
VT100.prototype.storeUserSettings = function() {
var settings = 'shellInABox=' + this.signature + ':' +
(this.utfEnabled ? '1' : '0') +
(this.visualBell ? '1' : '0');
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
settings += userCSSList[i][2] ? '1' : '0';
}
}
var d = new Date();
d.setDate(d.getDate() + 3653);
document.cookie = settings + ';expires=' + d.toGMTString();
};
VT100.prototype.initializeUserCSSStyles = function() { VT100.prototype.initializeUserCSSStyles = function() {
this.usercssActions = []; this.usercssActions = [];
if (typeof userCSSList != 'undefined') { if (typeof userCSSList != 'undefined') {
@ -334,6 +392,7 @@ VT100.prototype.initializeUserCSSStyles = function() {
} else { } else {
sheet.disabled = true; sheet.disabled = true;
} }
userCSSList[i][2] = !sheet.disabled;
} }
} }
entry = entry.nextSibling; entry = entry.nextSibling;
@ -1822,6 +1881,10 @@ VT100.prototype.pasteFnc = function() {
VT100.prototype.toggleUTF = function() { VT100.prototype.toggleUTF = function() {
this.utfEnabled = !this.utfEnabled; this.utfEnabled = !this.utfEnabled;
// We always persist the last value that the user selected. Not necessarily
// the last value that a random program requested.
this.utfPreferred = this.utfEnabled;
}; };
VT100.prototype.toggleBell = function() { VT100.prototype.toggleBell = function() {
@ -1829,7 +1892,7 @@ VT100.prototype.toggleBell = function() {
}; };
VT100.prototype.about = function() { VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.9 (revision 169)" + alert("VT100 Terminal Emulator " + "2.9 (revision 170)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com"); "For more information check http://shellinabox.com");
}; };
@ -1922,6 +1985,7 @@ VT100.prototype.showContextMenu = function(x, y) {
return function(event) { return function(event) {
vt100.hideContextMenu(); vt100.hideContextMenu();
action.call(vt100); action.call(vt100);
vt100.storeUserSettings();
return vt100.cancelEvent(event || window.event); return vt100.cancelEvent(event || window.event);
} }
}(this, actions[i])); }(this, actions[i]));

View file

@ -355,7 +355,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) {
}; };
ShellInABox.prototype.about = function() { ShellInABox.prototype.about = function() {
alert("Shell In A Box version " + "2.9 (revision 169)" + alert("Shell In A Box version " + "2.9 (revision 170)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com" + "For more information check http://shellinabox.com" +
(typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ? (typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ?

View file

@ -173,6 +173,7 @@ function VT100(container) {
// Optional arguments // Optional arguments
'(?:[?](?:(?![ \u00A0]|[,.)}"\u0027!]+[ \u00A0]|[,.)}"\u0027!]+$).)*)?'); '(?:[?](?:(?![ \u00A0]|[,.)}"\u0027!]+[ \u00A0]|[,.)}"\u0027!]+$).)*)?');
} }
this.getUserSettings();
this.initializeElements(container); this.initializeElements(container);
this.maxScrollbackLines = 500; this.maxScrollbackLines = 500;
this.npar = 0; this.npar = 0;
@ -203,10 +204,7 @@ VT100.prototype.reset = function(clearHistory) {
this.crLfMode = false; this.crLfMode = false;
this.offsetMode = false; this.offsetMode = false;
this.mouseReporting = false; this.mouseReporting = false;
this.utfEnabled = true; this.utfEnabled = this.utfPreferred;
this.visualBell = typeof suppressAllAudio !=
'undefined' &&
suppressAllAudio;
this.utfCount = 0; this.utfCount = 0;
this.utfChar = 0; this.utfChar = 0;
this.color = 'ansi0 bgAnsi15'; this.color = 'ansi0 bgAnsi15';
@ -248,6 +246,66 @@ VT100.prototype.addListener = function(elem, event, listener) {
} }
}; };
VT100.prototype.getUserSettings = function() {
// Compute hash signature to identify the entries in the userCSS menu.
// If the menu is unchanged from last time, default values can be
// looked up in a cookie associated with this page.
this.signature = 0;
this.utfPreferred = true;
this.visualBell = typeof suppressAllAudio != 'undefined' &&
suppressAllAudio;
if (this.visualBell) {
this.signature = Math.floor(16807*this.signature + 1) %
((1 << 31) - 1);
}
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
var label = userCSSList[i][0];
for (var j = 0; j < label.length; ++j) {
this.signature = Math.floor(16807*this.signature+
label.charCodeAt(j)) %
((1 << 31) - 1);
}
if (userCSSList[i][1]) {
this.signature = Math.floor(16807*this.signature + 1) %
((1 << 31) - 1);
}
}
}
var key = 'shellInABox=' + this.signature + ':';
var settings = document.cookie.indexOf(key);
if (settings >= 0) {
settings = document.cookie.substr(settings + key.length).
replace(/([0-1]*).*/, "$1");
if (settings.length == 2 + (typeof userCSSList == 'undefined' ?
0 : userCSSList.length)) {
this.utfPreferred = settings.charAt(0) != '0';
this.visualBell = settings.charAt(1) != '0';
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
userCSSList[i][2] = settings.charAt(i + 2) != '0';
}
}
}
}
this.utfEnabled = this.utfPreferred;
};
VT100.prototype.storeUserSettings = function() {
var settings = 'shellInABox=' + this.signature + ':' +
(this.utfEnabled ? '1' : '0') +
(this.visualBell ? '1' : '0');
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
settings += userCSSList[i][2] ? '1' : '0';
}
}
var d = new Date();
d.setDate(d.getDate() + 3653);
document.cookie = settings + ';expires=' + d.toGMTString();
};
VT100.prototype.initializeUserCSSStyles = function() { VT100.prototype.initializeUserCSSStyles = function() {
this.usercssActions = []; this.usercssActions = [];
if (typeof userCSSList != 'undefined') { if (typeof userCSSList != 'undefined') {
@ -334,6 +392,7 @@ VT100.prototype.initializeUserCSSStyles = function() {
} else { } else {
sheet.disabled = true; sheet.disabled = true;
} }
userCSSList[i][2] = !sheet.disabled;
} }
} }
entry = entry.nextSibling; entry = entry.nextSibling;
@ -1822,6 +1881,10 @@ VT100.prototype.pasteFnc = function() {
VT100.prototype.toggleUTF = function() { VT100.prototype.toggleUTF = function() {
this.utfEnabled = !this.utfEnabled; this.utfEnabled = !this.utfEnabled;
// We always persist the last value that the user selected. Not necessarily
// the last value that a random program requested.
this.utfPreferred = this.utfEnabled;
}; };
VT100.prototype.toggleBell = function() { VT100.prototype.toggleBell = function() {
@ -1829,7 +1892,7 @@ VT100.prototype.toggleBell = function() {
}; };
VT100.prototype.about = function() { VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.9 (revision 169)" + alert("VT100 Terminal Emulator " + "2.9 (revision 170)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" + "\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com"); "For more information check http://shellinabox.com");
}; };
@ -1922,6 +1985,7 @@ VT100.prototype.showContextMenu = function(x, y) {
return function(event) { return function(event) {
vt100.hideContextMenu(); vt100.hideContextMenu();
action.call(vt100); action.call(vt100);
vt100.storeUserSettings();
return vt100.cancelEvent(event || window.event); return vt100.cancelEvent(event || window.event);
} }
}(this, actions[i])); }(this, actions[i]));

View file

@ -173,6 +173,7 @@ function VT100(container) {
// Optional arguments // Optional arguments
'(?:[?](?:(?![ \u00A0]|[,.)}"\u0027!]+[ \u00A0]|[,.)}"\u0027!]+$).)*)?'); '(?:[?](?:(?![ \u00A0]|[,.)}"\u0027!]+[ \u00A0]|[,.)}"\u0027!]+$).)*)?');
} }
this.getUserSettings();
this.initializeElements(container); this.initializeElements(container);
this.maxScrollbackLines = 500; this.maxScrollbackLines = 500;
this.npar = 0; this.npar = 0;
@ -203,10 +204,7 @@ VT100.prototype.reset = function(clearHistory) {
this.crLfMode = false; this.crLfMode = false;
this.offsetMode = false; this.offsetMode = false;
this.mouseReporting = false; this.mouseReporting = false;
this.utfEnabled = true; this.utfEnabled = this.utfPreferred;
this.visualBell = typeof suppressAllAudio !=
'undefined' &&
suppressAllAudio;
this.utfCount = 0; this.utfCount = 0;
this.utfChar = 0; this.utfChar = 0;
this.color = 'ansi0 bgAnsi15'; this.color = 'ansi0 bgAnsi15';
@ -248,6 +246,66 @@ VT100.prototype.addListener = function(elem, event, listener) {
} }
}; };
VT100.prototype.getUserSettings = function() {
// Compute hash signature to identify the entries in the userCSS menu.
// If the menu is unchanged from last time, default values can be
// looked up in a cookie associated with this page.
this.signature = 0;
this.utfPreferred = true;
this.visualBell = typeof suppressAllAudio != 'undefined' &&
suppressAllAudio;
if (this.visualBell) {
this.signature = Math.floor(16807*this.signature + 1) %
((1 << 31) - 1);
}
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
var label = userCSSList[i][0];
for (var j = 0; j < label.length; ++j) {
this.signature = Math.floor(16807*this.signature+
label.charCodeAt(j)) %
((1 << 31) - 1);
}
if (userCSSList[i][1]) {
this.signature = Math.floor(16807*this.signature + 1) %
((1 << 31) - 1);
}
}
}
var key = 'shellInABox=' + this.signature + ':';
var settings = document.cookie.indexOf(key);
if (settings >= 0) {
settings = document.cookie.substr(settings + key.length).
replace(/([0-1]*).*/, "$1");
if (settings.length == 2 + (typeof userCSSList == 'undefined' ?
0 : userCSSList.length)) {
this.utfPreferred = settings.charAt(0) != '0';
this.visualBell = settings.charAt(1) != '0';
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
userCSSList[i][2] = settings.charAt(i + 2) != '0';
}
}
}
}
this.utfEnabled = this.utfPreferred;
};
VT100.prototype.storeUserSettings = function() {
var settings = 'shellInABox=' + this.signature + ':' +
(this.utfEnabled ? '1' : '0') +
(this.visualBell ? '1' : '0');
if (typeof userCSSList != 'undefined') {
for (var i = 0; i < userCSSList.length; ++i) {
settings += userCSSList[i][2] ? '1' : '0';
}
}
var d = new Date();
d.setDate(d.getDate() + 3653);
document.cookie = settings + ';expires=' + d.toGMTString();
};
VT100.prototype.initializeUserCSSStyles = function() { VT100.prototype.initializeUserCSSStyles = function() {
this.usercssActions = []; this.usercssActions = [];
if (typeof userCSSList != 'undefined') { if (typeof userCSSList != 'undefined') {
@ -334,6 +392,7 @@ VT100.prototype.initializeUserCSSStyles = function() {
} else { } else {
sheet.disabled = true; sheet.disabled = true;
} }
userCSSList[i][2] = !sheet.disabled;
} }
} }
entry = entry.nextSibling; entry = entry.nextSibling;
@ -1822,6 +1881,10 @@ VT100.prototype.pasteFnc = function() {
VT100.prototype.toggleUTF = function() { VT100.prototype.toggleUTF = function() {
this.utfEnabled = !this.utfEnabled; this.utfEnabled = !this.utfEnabled;
// We always persist the last value that the user selected. Not necessarily
// the last value that a random program requested.
this.utfPreferred = this.utfEnabled;
}; };
VT100.prototype.toggleBell = function() { VT100.prototype.toggleBell = function() {
@ -1922,6 +1985,7 @@ VT100.prototype.showContextMenu = function(x, y) {
return function(event) { return function(event) {
vt100.hideContextMenu(); vt100.hideContextMenu();
action.call(vt100); action.call(vt100);
vt100.storeUserSettings();
return vt100.cancelEvent(event || window.event); return vt100.cancelEvent(event || window.event);
} }
}(this, actions[i])); }(this, actions[i]));