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:
parent
dfe41ce244
commit
9b8e3af162
11 changed files with 85 additions and 23 deletions
|
@ -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>
|
2009-08-11 Markus Gutschke <markus@shellinabox.com>
|
||||||
|
|
||||||
* Added support for user selectable style sheets. Included example
|
* Added support for user selectable style sheets. Included example
|
||||||
|
|
2
config.h
2
config.h
|
@ -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 "172"
|
#define VCS_REVISION "174"
|
||||||
|
|
||||||
/* Version number of package */
|
/* Version number of package */
|
||||||
#define VERSION "2.9"
|
#define VERSION "2.9"
|
||||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -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=172
|
VCS_REVISION=174
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
|
|
@ -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=172
|
VCS_REVISION=174
|
||||||
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])
|
||||||
|
|
|
@ -1892,7 +1892,7 @@ VT100.prototype.toggleBell = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.about = 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" +
|
"\nCopyright 2008-2009 by Markus Gutschke\n" +
|
||||||
"For more information check http://shellinabox.com");
|
"For more information check http://shellinabox.com");
|
||||||
};
|
};
|
||||||
|
|
|
@ -401,21 +401,27 @@ static int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int launchChild(int service, struct Session *session) {
|
int launchChild(int service, struct Session *session, const char *url) {
|
||||||
if (launcher < 0) {
|
if (launcher < 0) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LaunchRequest request = {
|
struct LaunchRequest *request;
|
||||||
.service = service,
|
size_t len = sizeof(struct LaunchRequest) + strlen(url) + 1;
|
||||||
.width = session->width,
|
check(request = calloc(len, 1));
|
||||||
.height = session->height };
|
request->service = service;
|
||||||
strncat(request.peerName, httpGetPeerName(session->http),
|
request->width = session->width;
|
||||||
sizeof(request.peerName) - 1);
|
request->height = session->height;
|
||||||
if (NOINTR(write(launcher, &request, sizeof(request))) != sizeof(request)) {
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
free(request);
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char cmsg_buf[CMSG_SPACE(sizeof(int))];
|
char cmsg_buf[CMSG_SPACE(sizeof(int))];
|
||||||
struct iovec iov = { 0 };
|
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,
|
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
|
// Create a hash table with all the variables that we can expand. This
|
||||||
// includes all environment variables being passed to the child.
|
// includes all environment variables being passed to the child.
|
||||||
HashMap *vars;
|
HashMap *vars;
|
||||||
|
@ -1059,6 +1066,8 @@ static void execService(int width, int height, struct Service *service,
|
||||||
addToHashMap(vars, key, value);
|
addToHashMap(vars, key, value);
|
||||||
check(key = strdup("uid"));
|
check(key = strdup("uid"));
|
||||||
addToHashMap(vars, key, stringPrintf(NULL, "%d", service->uid));
|
addToHashMap(vars, key, stringPrintf(NULL, "%d", service->uid));
|
||||||
|
check(key = strdup("url"));
|
||||||
|
addToHashMap(vars, key, strdup(url));
|
||||||
|
|
||||||
enum { ENV, ARGS } state = ENV;
|
enum { ENV, ARGS } state = ENV;
|
||||||
enum { NONE, SINGLE, DOUBLE
|
enum { NONE, SINGLE, DOUBLE
|
||||||
|
@ -1110,11 +1119,26 @@ static void execService(int width, int height, struct Service *service,
|
||||||
if (ch) {
|
if (ch) {
|
||||||
end++;
|
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);
|
memmove(ptr + replLen, end, strlen(end) + 1);
|
||||||
if (repl) {
|
if (repl) {
|
||||||
memcpy(ptr, repl, replLen);
|
memcpy(ptr, repl, replLen);
|
||||||
}
|
}
|
||||||
ptr += replLen;
|
ptr += replLen - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\\':
|
case '\\':
|
||||||
|
@ -1168,7 +1192,7 @@ static void execService(int width, int height, struct Service *service,
|
||||||
} else {
|
} else {
|
||||||
// Add entry to argv.
|
// Add entry to argv.
|
||||||
state = ARGS;
|
state = ARGS;
|
||||||
argv[argc++] = key;
|
argv[argc++] = strdup(key);
|
||||||
check(argv = realloc(argv, (argc + 1)*sizeof(char *)));
|
check(argv = realloc(argv, (argc + 1)*sizeof(char *)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1183,6 +1207,7 @@ static void execService(int width, int height, struct Service *service,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
free(cmdline);
|
||||||
argv[argc] = NULL;
|
argv[argc] = NULL;
|
||||||
deleteHashMap(vars);
|
deleteHashMap(vars);
|
||||||
check(argc);
|
check(argc);
|
||||||
|
@ -1217,7 +1242,8 @@ void setWindowSize(int pty, int width, int height) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void childProcess(struct Service *service, 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
|
// Set initial window size
|
||||||
setWindowSize(0, width, height);
|
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,
|
execle("/usr/bin/login", "login", "-p", "-h", peerName,
|
||||||
(void *)0, environment);
|
(void *)0, environment);
|
||||||
} else {
|
} else {
|
||||||
execService(width, height, service, peerName, environment);
|
execService(width, height, service, peerName, environment, url);
|
||||||
}
|
}
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
@ -1363,6 +1389,9 @@ static void launcherDaemon(int fd) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
int len = read(fd, &request, sizeof(request));
|
int len = read(fd, &request, sizeof(request));
|
||||||
if (len != sizeof(request) && errno != EINTR) {
|
if (len != sizeof(request) && errno != EINTR) {
|
||||||
|
if (len) {
|
||||||
|
debug("Failed to read launch request");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1381,6 +1410,26 @@ static void launcherDaemon(int fd) {
|
||||||
continue;
|
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 >= 0);
|
||||||
check(request.service < numServices);
|
check(request.service < numServices);
|
||||||
|
|
||||||
|
@ -1403,11 +1452,13 @@ static void launcherDaemon(int fd) {
|
||||||
services[request.service]->useLogin,
|
services[request.service]->useLogin,
|
||||||
&utmp, request.peerName)) == 0) {
|
&utmp, request.peerName)) == 0) {
|
||||||
childProcess(services[request.service], request.width, request.height,
|
childProcess(services[request.service], request.width, request.height,
|
||||||
utmp, request.peerName);
|
utmp, request.peerName, url);
|
||||||
|
free(url);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
} else {
|
} else {
|
||||||
// Remember the utmp entry so that we can clean up when the child
|
// Remember the utmp entry so that we can clean up when the child
|
||||||
// terminates.
|
// terminates.
|
||||||
|
free(url);
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
if (!childProcesses) {
|
if (!childProcesses) {
|
||||||
childProcesses = newHashMap(destroyUtmpHashEntry, NULL);
|
childProcesses = newHashMap(destroyUtmpHashEntry, NULL);
|
||||||
|
|
|
@ -55,10 +55,12 @@ struct LaunchRequest {
|
||||||
int service;
|
int service;
|
||||||
int width, height;
|
int width, height;
|
||||||
char peerName[128];
|
char peerName[128];
|
||||||
|
int urlLength;
|
||||||
|
char url[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
int supportsPAM(void);
|
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);
|
void setWindowSize(int pty, int width, int height);
|
||||||
int forkLauncher(void);
|
int forkLauncher(void);
|
||||||
void terminateLauncher(void);
|
void terminateLauncher(void);
|
||||||
|
|
|
@ -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 172)" +
|
alert("Shell In A Box version " + "2.9 (revision 174)" +
|
||||||
"\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 ?
|
||||||
|
|
|
@ -341,6 +341,7 @@ static int dataHandler(HttpConnection *http, struct Service *service,
|
||||||
const char *width = getFromHashMap(args, "width");
|
const char *width = getFromHashMap(args, "width");
|
||||||
const char *height = getFromHashMap(args, "height");
|
const char *height = getFromHashMap(args, "height");
|
||||||
const char *keys = getFromHashMap(args, "keys");
|
const char *keys = getFromHashMap(args, "keys");
|
||||||
|
const char *rootURL = getFromHashMap(args, "rooturl");
|
||||||
|
|
||||||
// Adjust window dimensions if provided by client
|
// Adjust window dimensions if provided by client
|
||||||
if (width && height) {
|
if (width && height) {
|
||||||
|
@ -362,7 +363,8 @@ static int dataHandler(HttpConnection *http, struct Service *service,
|
||||||
goto bad_new_session;
|
goto bad_new_session;
|
||||||
}
|
}
|
||||||
session->http = http;
|
session->http = http;
|
||||||
if (launchChild(service->id, session) < 0) {
|
if (launchChild(service->id, session,
|
||||||
|
rootURL && *rootURL ? rootURL : urlGetURL(url)) < 0) {
|
||||||
abandonSession(session);
|
abandonSession(session);
|
||||||
httpSendReply(http, 500, "Internal Error", NO_MSG);
|
httpSendReply(http, 500, "Internal Error", NO_MSG);
|
||||||
return HTTP_DONE;
|
return HTTP_DONE;
|
||||||
|
@ -809,7 +811,7 @@ static void parseArgs(int argc, char * const argv[]) {
|
||||||
HashMap *serviceTable = newHashMap(destroyServiceHashEntry, NULL);
|
HashMap *serviceTable = newHashMap(destroyServiceHashEntry, NULL);
|
||||||
extern char stylesStart[];
|
extern char stylesStart[];
|
||||||
extern char stylesEnd[];
|
extern char stylesEnd[];
|
||||||
check(cssStyleSheet = malloc(stylesEnd - stylesStart));
|
check(cssStyleSheet = malloc(stylesEnd - stylesStart + 1));
|
||||||
memcpy(cssStyleSheet, stylesStart, stylesEnd - stylesStart);
|
memcpy(cssStyleSheet, stylesStart, stylesEnd - stylesStart);
|
||||||
cssStyleSheet[stylesEnd - stylesStart] = '\000';
|
cssStyleSheet[stylesEnd - stylesStart] = '\000';
|
||||||
|
|
||||||
|
|
|
@ -403,6 +403,9 @@ name of remote peer.
|
||||||
.B ${uid}
|
.B ${uid}
|
||||||
numeric user id.
|
numeric user id.
|
||||||
.TP
|
.TP
|
||||||
|
.B ${url}
|
||||||
|
the URL that serves the terminal session.
|
||||||
|
.TP
|
||||||
.B ${user}
|
.B ${user}
|
||||||
user name.
|
user name.
|
||||||
.P
|
.P
|
||||||
|
|
|
@ -1892,7 +1892,7 @@ VT100.prototype.toggleBell = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
VT100.prototype.about = 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" +
|
"\nCopyright 2008-2009 by Markus Gutschke\n" +
|
||||||
"For more information check http://shellinabox.com");
|
"For more information check http://shellinabox.com");
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue