- Added Debian specific documentation to the manual page.
+2009-07-30 Markus Gutschke <markus@shellinabox.com>
+
+ * Added the --css command line option to make incremental changes
+ to the style sheet without having to load a full replacement with
+ the --static-file option. Added an example that enables white text
+ on a black background.
+
+ * Added Debian specific documentation to the manual page.
+
2009-07-29 Markus Gutschke <markus@shellinabox.com>
* Allow unprivileged users to run the daemon. This requires
INSTALL \
NEWS \
README \
- TODO
+ TODO \
+ shellinabox/white-on-black.css
EXTRA_DIST = demo/beep.wav \
demo/favicon.ico \
demo/demo.html \
else \
sed -e '/^#ifdef *HAVE_PAM$$/,/^#endif$$/d'; \
fi | \
+ if [ -n "${DPKGBUILD}" ]; then \
+ sed -e '/^#ifndef *DPKGBUILD$$/,/^#endif$$/d'; \
+ else \
+ sed -e '/^#ifdef *DPKGBUILD$$/,/^#endif$$/d'; \
+ fi | \
sed -e '/^#/d' >"$@"
@out=`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'`; \
man -Tps "./$@" >"$${out}" 2>/dev/null || rm -f "$${out}"
INSTALL \
NEWS \
README \
- TODO
+ TODO \
+ shellinabox/white-on-black.css
EXTRA_DIST = demo/beep.wav \
demo/favicon.ico \
else \
sed -e '/^#ifdef *HAVE_PAM$$/,/^#endif$$/d'; \
fi | \
+ if [ -n "${DPKGBUILD}" ]; then \
+ sed -e '/^#ifndef *DPKGBUILD$$/,/^#endif$$/d'; \
+ else \
+ sed -e '/^#ifdef *DPKGBUILD$$/,/^#endif$$/d'; \
+ fi | \
sed -e '/^#/d' >"$@"
@out=`echo "$@" 2>/dev/null|sed -e 's/\.[^.]*$$/.ps/'`; \
man -Tps "./$@" >"$${out}" 2>/dev/null || rm -f "$${out}"
#define STDC_HEADERS 1
/* Most recent revision number in the version control system */
-#define VCS_REVISION "157"
+#define VCS_REVISION "158"
/* Version number of package */
#define VERSION "2.9"
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-VCS_REVISION=157
+VCS_REVISION=158
cat >>confdefs.h <<_ACEOF
dnl This is the one location where the authoritative version number is stored
AC_INIT(shellinabox, 2.9, markus@shellinabox.com)
-VCS_REVISION=157
+VCS_REVISION=158
AC_SUBST(VCS_REVISION)
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
[Most recent revision number in the version control system])
NEWS
README
TODO
+shellinabox/white-on-black.css
build-stamp: config.status
dh_testdir
@# Add here commands to compile the package.
- $(MAKE)
+ $(MAKE) DPKGBUILD=true
touch build-stamp
};
VT100.prototype.about = function() {
- alert("VT100 Terminal Emulator " + "2.9 (revision 157)" +
+ alert("VT100 Terminal Emulator " + "2.9 (revision 158)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com");
};
check(!uname(&uts));
hostname = uts.nodename;
}
+ check(hostname = strdup(hostname));
+ char *dot = strchr(hostname, '.');
+ if (dot) {
+ *dot = '\000';
+ }
const struct passwd *pw;
pam_handle_t *pam = NULL;
_exit(1);
}
free(prompt);
- char *localhost = strstr(service->cmdline, "@localhost");
- if (localhost) {
- memcpy(localhost+1, "%s", 3);
- }
- char *cmdline = stringPrintf(NULL, service->cmdline, user,
- hostname);
+ char *cmdline = stringPrintf(NULL, service->cmdline, user);
free(user);
free((void *)service->cmdline);
service->cmdline = cmdline;
pw = getPWEnt(service->uid);
#endif
}
+ free((void *)hostname);
if (restricted &&
(service->uid != restricted || service->gid != pw->pw_gid)) {
};
ShellInABox.prototype.about = function() {
- alert("Shell In A Box version " + "2.9 (revision 157)" +
+ alert("Shell In A Box version " + "2.9 (revision 158)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com" +
(typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ?
static Server *cgiServer;
static char *cgiSessionKey;
static int cgiSessions;
+static char *cssStyleSheet;
static char *jsonEscape(const char *buf, int len) {
static const char *hexDigit = "0123456789ABCDEF";
httpTransfer(http, response, headerLength + contentLength);
} else if (pathInfoLength == 10 && !memcmp(pathInfo, "styles.css", 10)) {
// Serve the style sheet.
- extern char stylesStart[];
- extern char stylesEnd[];
- serveStaticFile(http, "text/css; charset=utf-8", stylesStart, stylesEnd);
+ serveStaticFile(http, "text/css; charset=utf-8",
+ cssStyleSheet, strrchr(cssStyleSheet, '\000'));
} else {
httpSendReply(http, 404, "File not found", NO_MSG);
}
"List of command line options:\n"
" -b, --background[=PIDFILE] run in background\n"
"%s"
+ " --css=FILE attach contents to CSS style sheet\n"
" --cgi[=PORTMIN-PORTMAX] run as CGI\n"
" -d, --debug enable debug mode\n"
" -f, --static-file=URL:FILE serve static file from URL path\n"
int verbosity = MSG_DEFAULT;
externalFiles = newHashMap(destroyExternalFileHashEntry, NULL);
HashMap *serviceTable = newHashMap(destroyServiceHashEntry, NULL);
+ extern char stylesStart[];
+ extern char stylesEnd[];
+ check(cssStyleSheet = malloc(stylesEnd - stylesStart));
+ memcpy(cssStyleSheet, stylesStart, stylesEnd - stylesStart);
+ cssStyleSheet[stylesEnd - stylesStart] = '\000';
+
for (;;) {
static const char optstring[] = "+hb::c:df:g:np:s:tqu:v";
static struct option options[] = {
{ "background", 2, 0, 'b' },
{ "cert", 1, 0, 'c' },
{ "cert-fd", 1, 0, 0 },
+ { "css", 1, 0, 0 },
{ "cgi", 2, 0, 0 },
{ "debug", 0, 0, 'd' },
{ "static-file", 1, 0, 'f' },
if (optarg && pidfile) {
fatal("Only one pidfile can be given");
}
- if (optarg) {
+ if (optarg && *optarg) {
pidfile = strdup(optarg);
}
} else if (!idx--) {
if (certificateDir) {
fatal("Only one certificate directory can be selected");
}
+ struct stat st;
+ if (!optarg || !*optarg || stat(optarg, &st) || !S_ISDIR(st.st_mode)) {
+ fatal("\"--cert\" expects a directory name");
+ }
check(certificateDir = strdup(optarg));
} else if (!idx--) {
// Certificate file descriptor
if (certificateFd >= 0) {
fatal("Only one certificate file handle can be provided");
}
+ if (!optarg || *optarg < '0' || *optarg > '9') {
+ fatal("\"--cert-fd\" expects a valid file handle");
+ }
int tmpFd = strtoint(optarg, 3, INT_MAX);
certificateFd = dup(tmpFd);
if (certificateFd < 0) {
fatal("Invalid certificate file handle");
}
check(!NOINTR(close(tmpFd)));
+ } else if (!idx--) {
+ // CSS
+ struct stat st;
+ if (!optarg || !*optarg || stat(optarg, &st) || !S_ISREG(st.st_mode)) {
+ fatal("\"--css\" expects a file name");
+ }
+ FILE *css = fopen(optarg, "r");
+ if (!css) {
+ fatal("Cannot read style sheet \"%s\"", optarg);
+ } else {
+ check(cssStyleSheet= realloc(cssStyleSheet, strlen(cssStyleSheet) +
+ st.st_size + 2));
+ char *newData = strrchr(cssStyleSheet, '\000');
+ *newData++ = '\n';
+ if (fread(newData, 1, st.st_size, css) != st.st_size) {
+ fatal("Failed to read style sheet \"%s\"", optarg);
+ }
+ newData[st.st_size]= '\000';
+ fclose(css);
+ }
} else if (!idx--) {
// CGI
if (demonize) {
fatal("Cannot specify a port for CGI operation");
}
cgi = 1;
- if (optarg) {
+ if (optarg && *optarg) {
char *ptr = strchr(optarg, '-');
if (!ptr) {
fatal("Syntax error in port range specification");
if (runAsGroup >= 0) {
fatal("Duplicate --group option.");
}
+ if (!optarg || !*optarg) {
+ fatal("\"--group\" expects a group name.");
+ }
runAsGroup = parseGroup(optarg, NULL);
} else if (!idx--) {
// Linkify
if (cgi) {
fatal("Cannot specifiy a port for CGI operation");
}
+ if (!optarg || *optarg < '0' || *optarg > '9') {
+ fatal("\"--port\" expects a port number.");
+ }
port = strtoint(optarg, 1, 65535);
} else if (!idx--) {
// Service
if (runAsUser >= 0) {
fatal("Duplicate --user option.");
}
+ if (!optarg || !*optarg) {
+ fatal("\"--user\" expects a user name.");
+ }
runAsUser = parseUser(optarg, NULL);
} else if (!idx--) {
// Verbose
[\ \fB-c\fP\ | \fB--cert=\fP\fIcertdir\fP\ ]
#endif
[\ \fB--cert-fd=\fP\fIfd\fP\ ]
+[\ \fB--css=\fP\fIfilename\fP\ ]
[\ \fB--cgi\fP[\fB=\fP\fIportrange\fP]\ ]
[\ \fB-d\fP\ | \fB--debug\fP\ ]
[\ \fB-f\fP\ | \fB--static-file=\fP\fIurl\fP:\fIfile\fP\ ]
the private key data to the daemon.
#endif
.TP
+\fB--css=\fP\fIfilename\fP
+Sometimes, it is not necessary to replace the entire style sheet using the
+.B --static-file
+option. But instead a small incremental change should be made to the visual
+appearance of the terminal. The
+.B --css
+option provides a means to append additional style rules to the end of
+the default
+.B styles.css
+sheet. More than one
+.B --css
+option can be given on the same command line.
+.TP
\fB--cgi\fP[\fB=\fP\fIportrange\fP]
Instead of running
.B shellinaboxd
.B Wyse 60\*(Tm
terminal. Again, this command should be run as
.BR root .
+.TP
+#ifndef DPKGBUILD
+.B shellinaboxd --css white-on-black.css
+#endif
+#ifdef DPKGBUILD
+.B shellinaboxd --css /usr/share/doc/shellinabox/white-on-black.css
+#endif
+Loads the
+.B white-on-black.css
+style sheet
+#ifndef DPKGBUILD
+from the current directory
+#endif
+and appends it to the built-in
+.B styles.css
+sheet. This causes the terminal to render white text on a black background.
.P
.SH DIAGNOSTICS
The daemon returns a non-zero exit code in case of failure. With the
lack of sufficient privileges to run a service, failure to find
SSL/TLS certificates, and failure to write newly generated
certificates to the certification directory.
+#ifdef DPKGBUILD
+.SH FILES
+.TP 10
+.I /etc/default/shellinabox
+The system-wide installation of
+.B shellinaboxd
+can be configured by editing this file. After making any changes, restart
+the daemon with \fBsudo service shellinabox restart\fP.
+.TP
+.I /etc/init.d/shellinabox
+This is the system-wide service definition. Usually, there is no need to
+edit this file.
+.TP
+.I /var/lib/shellinabox
+This directory contains the certificate files that
+.B shellinaboxd
+uses when serving encrypted SSL sessions. If suitable files do not exist, yet,
+it tries to populate the directory with self-signed certificates the first
+time a particular certificate is needed. Over time, it should contain
+\fBcertificate.pem\fP, \fBcertificate-localhost.pem\fP, and
+\fBcertificate-\fP\fIHOSTNAME\fP\fB.pem\fP.
+.TP
+.I /var/run/shellinaboxd.pid
+This file is created any time the system-wide service gets started.
+#endif
.SH "SEE ALSO"
.BR chmod (1),
.BR last (1),
};
VT100.prototype.about = function() {
- alert("VT100 Terminal Emulator " + "2.9 (revision 157)" +
+ alert("VT100 Terminal Emulator " + "2.9 (revision 158)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com");
};
--- /dev/null
+#vt100 #scrollable {
+ color: white;
+ background-color: black;
+}
+#vt100 #ansi0 { background-color: #ffffff; }
+#vt100 #ansi15 { background-color: #000000; }