Added a ${url} parameter that can be used in the service description

git-svn-id: https://shellinabox.googlecode.com/svn/trunk@174 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac 2009-08-19 19:08:30 +00:00
parent dfe41ce244
commit 9b8e3af162
11 changed files with 85 additions and 23 deletions

View file

@ -1,3 +1,7 @@
2009-08-19 Markus Gutschke <markus@shellinabox.com>
* Added a ${url} parameter that can be used in the service description.
2009-08-11 Markus Gutschke <markus@shellinabox.com>
* Added support for user selectable style sheets. Included example

View file

@ -138,7 +138,7 @@
#define STDC_HEADERS 1
/* Most recent revision number in the version control system */
#define VCS_REVISION "172"
#define VCS_REVISION "174"
/* Version number of package */
#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
VCS_REVISION=172
VCS_REVISION=174
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
AC_INIT(shellinabox, 2.9, markus@shellinabox.com)
VCS_REVISION=172
VCS_REVISION=174
AC_SUBST(VCS_REVISION)
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
[Most recent revision number in the version control system])

View file

@ -1892,7 +1892,7 @@ VT100.prototype.toggleBell = function() {
};
VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.9 (revision 172)" +
alert("VT100 Terminal Emulator " + "2.9 (revision 174)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com");
};

View file

@ -401,21 +401,27 @@ static int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen,
}
#endif
int launchChild(int service, struct Session *session) {
int launchChild(int service, struct Session *session, const char *url) {
if (launcher < 0) {
errno = EINVAL;
return -1;
}
struct LaunchRequest request = {
.service = service,
.width = session->width,
.height = session->height };
strncat(request.peerName, httpGetPeerName(session->http),
sizeof(request.peerName) - 1);
if (NOINTR(write(launcher, &request, sizeof(request))) != sizeof(request)) {
struct LaunchRequest *request;
size_t len = sizeof(struct LaunchRequest) + strlen(url) + 1;
check(request = calloc(len, 1));
request->service = service;
request->width = session->width;
request->height = session->height;
strncat(request->peerName, httpGetPeerName(session->http),
sizeof(request->peerName) - 1);
request->urlLength = strlen(url);
memcpy(&request->url, url, request->urlLength);
if (NOINTR(write(launcher, request, len)) != len) {
free(request);
return -1;
}
free(request);
pid_t pid;
char cmsg_buf[CMSG_SPACE(sizeof(int))];
struct iovec iov = { 0 };
@ -1023,7 +1029,8 @@ static void destroyVariableHashEntry(void *arg, char *key, char *value) {
}
static void execService(int width, int height, struct Service *service,
const char *peerName, char **environment) {
const char *peerName, char **environment,
const char *url) {
// Create a hash table with all the variables that we can expand. This
// includes all environment variables being passed to the child.
HashMap *vars;
@ -1059,6 +1066,8 @@ static void execService(int width, int height, struct Service *service,
addToHashMap(vars, key, value);
check(key = strdup("uid"));
addToHashMap(vars, key, stringPrintf(NULL, "%d", service->uid));
check(key = strdup("url"));
addToHashMap(vars, key, strdup(url));
enum { ENV, ARGS } state = ENV;
enum { NONE, SINGLE, DOUBLE
@ -1110,11 +1119,26 @@ static void execService(int width, int height, struct Service *service,
if (ch) {
end++;
}
int incr = replLen - (end - ptr);
if (incr > 0) {
char *oldCmdline = cmdline;
check(cmdline = realloc(cmdline,
(end - cmdline) + strlen(end) +
incr + 1));
ptr += cmdline - oldCmdline;
end += cmdline - oldCmdline;
if (key) {
key += cmdline - oldCmdline;
}
if (value) {
value += cmdline - oldCmdline;
}
}
memmove(ptr + replLen, end, strlen(end) + 1);
if (repl) {
memcpy(ptr, repl, replLen);
}
ptr += replLen;
ptr += replLen - 1;
}
break;
case '\\':
@ -1168,7 +1192,7 @@ static void execService(int width, int height, struct Service *service,
} else {
// Add entry to argv.
state = ARGS;
argv[argc++] = key;
argv[argc++] = strdup(key);
check(argv = realloc(argv, (argc + 1)*sizeof(char *)));
}
}
@ -1183,6 +1207,7 @@ static void execService(int width, int height, struct Service *service,
}
}
done:
free(cmdline);
argv[argc] = NULL;
deleteHashMap(vars);
check(argc);
@ -1217,7 +1242,8 @@ void setWindowSize(int pty, int width, int height) {
}
static void childProcess(struct Service *service, int width, int height,
struct Utmp *utmp, const char *peerName) {
struct Utmp *utmp, const char *peerName,
const char *url) {
// Set initial window size
setWindowSize(0, width, height);
@ -1343,7 +1369,7 @@ static void childProcess(struct Service *service, int width, int height,
execle("/usr/bin/login", "login", "-p", "-h", peerName,
(void *)0, environment);
} else {
execService(width, height, service, peerName, environment);
execService(width, height, service, peerName, environment, url);
}
_exit(1);
}
@ -1363,6 +1389,9 @@ static void launcherDaemon(int fd) {
errno = 0;
int len = read(fd, &request, sizeof(request));
if (len != sizeof(request) && errno != EINTR) {
if (len) {
debug("Failed to read launch request");
}
break;
}
@ -1381,6 +1410,26 @@ static void launcherDaemon(int fd) {
continue;
}
char *url;
check(url = calloc(request.urlLength + 1, 1));
readURL:
len = read(fd, url, request.urlLength + 1);
if (len != request.urlLength + 1 && errno != EINTR) {
debug("Failed to read URL");
free(url);
break;
}
while (NOINTR(pid = waitpid(-1, &status, WNOHANG)) > 0) {
if (WIFEXITED(pid) || WIFSIGNALED(pid)) {
char key[32];
snprintf(&key[0], sizeof(key), "%d", pid);
deleteFromHashMap(childProcesses, key);
}
}
if (len != request.urlLength + 1) {
goto readURL;
}
check(request.service >= 0);
check(request.service < numServices);
@ -1403,11 +1452,13 @@ static void launcherDaemon(int fd) {
services[request.service]->useLogin,
&utmp, request.peerName)) == 0) {
childProcess(services[request.service], request.width, request.height,
utmp, request.peerName);
utmp, request.peerName, url);
free(url);
_exit(1);
} else {
// Remember the utmp entry so that we can clean up when the child
// terminates.
free(url);
if (pid > 0) {
if (!childProcesses) {
childProcesses = newHashMap(destroyUtmpHashEntry, NULL);

View file

@ -55,10 +55,12 @@ struct LaunchRequest {
int service;
int width, height;
char peerName[128];
int urlLength;
char url[0];
};
int supportsPAM(void);
int launchChild(int service, struct Session *session);
int launchChild(int service, struct Session *session, const char *url);
void setWindowSize(int pty, int width, int height);
int forkLauncher(void);
void terminateLauncher(void);

View file

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

View file

@ -341,6 +341,7 @@ static int dataHandler(HttpConnection *http, struct Service *service,
const char *width = getFromHashMap(args, "width");
const char *height = getFromHashMap(args, "height");
const char *keys = getFromHashMap(args, "keys");
const char *rootURL = getFromHashMap(args, "rooturl");
// Adjust window dimensions if provided by client
if (width && height) {
@ -362,7 +363,8 @@ static int dataHandler(HttpConnection *http, struct Service *service,
goto bad_new_session;
}
session->http = http;
if (launchChild(service->id, session) < 0) {
if (launchChild(service->id, session,
rootURL && *rootURL ? rootURL : urlGetURL(url)) < 0) {
abandonSession(session);
httpSendReply(http, 500, "Internal Error", NO_MSG);
return HTTP_DONE;
@ -809,7 +811,7 @@ static void parseArgs(int argc, char * const argv[]) {
HashMap *serviceTable = newHashMap(destroyServiceHashEntry, NULL);
extern char stylesStart[];
extern char stylesEnd[];
check(cssStyleSheet = malloc(stylesEnd - stylesStart));
check(cssStyleSheet = malloc(stylesEnd - stylesStart + 1));
memcpy(cssStyleSheet, stylesStart, stylesEnd - stylesStart);
cssStyleSheet[stylesEnd - stylesStart] = '\000';

View file

@ -403,6 +403,9 @@ name of remote peer.
.B ${uid}
numeric user id.
.TP
.B ${url}
the URL that serves the terminal session.
.TP
.B ${user}
user name.
.P

View file

@ -1892,7 +1892,7 @@ VT100.prototype.toggleBell = function() {
};
VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.9 (revision 172)" +
alert("VT100 Terminal Emulator " + "2.9 (revision 174)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com");
};