Merge pull request #286 from KLuka/master

Partial fixes for issues #103, #203, #195 and README.md
This commit is contained in:
Luka Krajger 2015-03-06 13:43:12 +01:00
commit cc3f2fe917
7 changed files with 101 additions and 16 deletions

29
README.md Normal file
View file

@ -0,0 +1,29 @@
shellinabox
===========
This is unofficial fork of project **shellinabox**. Fork was created because
original project is not maintained anymore and we cannot contact original
repository owners.
Our aim is to continue with maintanince of shellinabox project.
If you have any questions, issues or patches, please fell free to submit pull
request or report an issue. You can also drop an email to original project
[issue #261](https://code.google.com/p/shellinabox/issues/detail?id=261) discusion
from where this fork started.
About shellinabox
-----------------
Shell In A Box implements a web server that can export arbitrary command line
tools to a web based terminal emulator. This emulator is accessible to any
JavaScript and CSS enabled web browser and does not require any additional
browser plugins.
More information:
* [Official site](https://code.google.com/p/shellinabox)
* [Official wiki](https://code.google.com/p/shellinabox/wiki/shellinaboxd_man)

View file

@ -520,6 +520,7 @@ int launchChild(int service, struct Session *session, const char *url) {
ssize_t len = sizeof(struct LaunchRequest) + strlen(u) + 1; ssize_t len = sizeof(struct LaunchRequest) + strlen(u) + 1;
check(request = calloc(len, 1)); check(request = calloc(len, 1));
request->service = service; request->service = service;
request->terminate = -1;
request->width = session->width; request->width = session->width;
request->height = session->height; request->height = session->height;
strncat(request->peerName, httpGetPeerName(session->http), strncat(request->peerName, httpGetPeerName(session->http),
@ -547,6 +548,7 @@ int launchChild(int service, struct Session *session, const char *url) {
return -1; return -1;
} }
check(bytes == sizeof(pid)); check(bytes == sizeof(pid));
check(session->pid = pid);
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
check(cmsg); check(cmsg);
check(cmsg->cmsg_level == SOL_SOCKET); check(cmsg->cmsg_level == SOL_SOCKET);
@ -555,6 +557,34 @@ int launchChild(int service, struct Session *session, const char *url) {
return pid; return pid;
} }
int terminateChild(struct Session *session) {
if (launcher < 0) {
errno = EINVAL;
return -1;
}
if (session->pid < 1) {
debug("Child pid for termination not valid!");
return -1;
}
// Send terminate request to launcher process
struct LaunchRequest *request;
ssize_t len = sizeof(struct LaunchRequest);
check(request = calloc(len, 1));
request->terminate = session->pid;
if (NOINTR(write(launcher, request, len)) != len) {
debug("Child %d termination request failed!", request->terminate);
free(request);
return -1;
}
free(request);
session->pid = 0;
session->cleanup = 0;
return 0;
}
struct Utmp { struct Utmp {
const char pid[32]; const char pid[32];
int pty; int pty;
@ -1616,7 +1646,7 @@ static void launcherDaemon(int fd) {
int status; int status;
pid_t pid; pid_t pid;
while (NOINTR(pid = waitpid(-1, &status, WNOHANG)) > 0) { while (NOINTR(pid = waitpid(-1, &status, WNOHANG)) > 0) {
debug("Child %d exited with exit code %d\n", pid, WEXITSTATUS(status)); debug("Child %d exited with exit code %d", pid, WEXITSTATUS(status));
if (WIFEXITED(status) || WIFSIGNALED(status)) { if (WIFEXITED(status) || WIFSIGNALED(status)) {
char key[32]; char key[32];
snprintf(&key[0], sizeof(key), "%d", pid); snprintf(&key[0], sizeof(key), "%d", pid);
@ -1627,6 +1657,21 @@ static void launcherDaemon(int fd) {
continue; continue;
} }
// Check if we received terminate request from parent process and
// try to terminate child, if child is still running
if (request.terminate > 0) {
errno = 0;
NOINTR(pid = waitpid(request.terminate, &status, WNOHANG));
if (pid == 0 && errno == 0) {
if (kill(request.terminate, SIGTERM) == 0) {
debug("Terminating child %d (kill)", request.terminate);
} else {
debug("Terminating child failed [%s]", strerror(errno));
}
}
continue;
}
char *url; char *url;
check(url = calloc(request.urlLength + 1, 1)); check(url = calloc(request.urlLength + 1, 1));
readURL: readURL:
@ -1637,7 +1682,7 @@ static void launcherDaemon(int fd) {
break; break;
} }
while (NOINTR(pid = waitpid(-1, &status, WNOHANG)) > 0) { while (NOINTR(pid = waitpid(-1, &status, WNOHANG)) > 0) {
debug("Child %d exited with exit code %d\n", pid, WEXITSTATUS(status)); debug("Child %d exited with exit code %d", pid, WEXITSTATUS(status));
if (WIFEXITED(status) || WIFSIGNALED(status)) { if (WIFEXITED(status) || WIFSIGNALED(status)) {
char key[32]; char key[32];
snprintf(&key[0], sizeof(key), "%d", pid); snprintf(&key[0], sizeof(key), "%d", pid);
@ -1682,6 +1727,7 @@ static void launcherDaemon(int fd) {
childProcesses = newHashMap(destroyUtmpHashEntry, NULL); childProcesses = newHashMap(destroyUtmpHashEntry, NULL);
} }
addToHashMap(childProcesses, utmp->pid, (char *)utmp); addToHashMap(childProcesses, utmp->pid, (char *)utmp);
debug("Child %d launched", pid);
} else { } else {
int fds[2]; int fds[2];
if (!pipe(fds)) { if (!pipe(fds)) {

View file

@ -52,15 +52,17 @@
struct LaunchRequest { struct LaunchRequest {
int service; int service;
int width, height; int width, height;
char peerName[128]; pid_t terminate;
int urlLength; char peerName[128];
char url[0]; int urlLength;
char url[0];
}; };
int supportsPAM(void); int supportsPAM(void);
int launchChild(int service, struct Session *session, const char *url); int launchChild(int service, struct Session *session, const char *url);
int terminateChild(struct Session *session);
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);

View file

@ -121,6 +121,8 @@ void initSession(struct Session *session, const char *sessionKey,
session->height = 0; session->height = 0;
session->buffered = NULL; session->buffered = NULL;
session->len = 0; session->len = 0;
session->pid = 0;
session->cleanup = 0;
} }
struct Session *newSession(const char *sessionKey, Server *server, URL *url, struct Session *newSession(const char *sessionKey, Server *server, URL *url,

View file

@ -63,6 +63,8 @@ struct Session {
int height; int height;
char *buffered; char *buffered;
int len; int len;
pid_t pid;
int cleanup;
}; };
void addToGraveyard(struct Session *session); void addToGraveyard(struct Session *session);

View file

@ -274,8 +274,11 @@ static int completePendingRequest(struct Session *session,
} }
static void sessionDone(void *arg) { static void sessionDone(void *arg) {
debug("Child terminated");
struct Session *session = (struct Session *)arg; struct Session *session = (struct Session *)arg;
debug("Session %s done", session->sessionKey);
if (session->cleanup) {
terminateChild(session);
}
session->done = 1; session->done = 1;
addToGraveyard(session); addToGraveyard(session);
completePendingRequest(session, "", 0, INT_MAX); completePendingRequest(session, "", 0, INT_MAX);
@ -301,6 +304,7 @@ static int handleSession(struct ServerConnection *connection, void *arg,
if (bytes || timedOut) { if (bytes || timedOut) {
if (!session->http && timedOut) { if (!session->http && timedOut) {
debug("Timeout. Closing session."); debug("Timeout. Closing session.");
session->cleanup = 1;
return 0; return 0;
} }
check(!session->done); check(!session->done);

View file

@ -3089,6 +3089,7 @@ VT100.prototype.keyUp = function(event) {
asciiKey || asciiKey ||
event.keyCode == 50 || event.keyCode == 50 ||
event.keyCode >= 96 && event.keyCode <= 105; event.keyCode >= 96 && event.keyCode <= 105;
// Not used ???
var normalKey = var normalKey =
alphNumKey || alphNumKey ||
event.keyCode == 59 || event.keyCode == 61 || event.keyCode == 59 || event.keyCode == 61 ||
@ -3279,7 +3280,6 @@ VT100.prototype.lf = function(count) {
this.scrollRegion(0, this.top + 1, this.scrollRegion(0, this.top + 1,
this.terminalWidth, this.bottom - this.top - 1, this.terminalWidth, this.bottom - this.top - 1,
0, -1, this.color, this.style); 0, -1, this.color, this.style);
offset = undefined;
} else if (this.cursorY < this.terminalHeight - 1) { } else if (this.cursorY < this.terminalHeight - 1) {
this.gotoXY(this.cursorX, this.cursorY + 1); this.gotoXY(this.cursorX, this.cursorY + 1);
} }
@ -3723,7 +3723,7 @@ VT100.prototype.csiJ = function(number) {
default: default:
return; return;
} }
needWrap = false; this.needWrap = false;
}; };
VT100.prototype.csiK = function(number) { VT100.prototype.csiK = function(number) {
@ -3744,7 +3744,7 @@ VT100.prototype.csiK = function(number) {
default: default:
return; return;
} }
needWrap = false; this.needWrap = false;
}; };
VT100.prototype.csiL = function(number) { VT100.prototype.csiL = function(number) {
@ -3761,7 +3761,7 @@ VT100.prototype.csiL = function(number) {
this.scrollRegion(0, this.cursorY, this.scrollRegion(0, this.cursorY,
this.terminalWidth, this.bottom - this.cursorY - number, this.terminalWidth, this.bottom - this.cursorY - number,
0, number, this.color, this.style); 0, number, this.color, this.style);
needWrap = false; this.needWrap = false;
}; };
VT100.prototype.csiM = function(number) { VT100.prototype.csiM = function(number) {
@ -3773,12 +3773,12 @@ VT100.prototype.csiM = function(number) {
number = 1; number = 1;
} }
if (number > this.bottom - this.cursorY) { if (number > this.bottom - this.cursorY) {
number = bottom - cursorY; number = this.bottom - this.cursorY;
} }
this.scrollRegion(0, this.cursorY + number, this.scrollRegion(0, this.cursorY + number,
this.terminalWidth, this.bottom - this.cursorY - number, this.terminalWidth, this.bottom - this.cursorY - number,
0, -number, this.color, this.style); 0, -number, this.color, this.style);
needWrap = false; this.needWrap = false;
}; };
VT100.prototype.csim = function() { VT100.prototype.csim = function() {
@ -3839,7 +3839,7 @@ VT100.prototype.csiP = function(number) {
this.scrollRegion(this.cursorX + number, this.cursorY, this.scrollRegion(this.cursorX + number, this.cursorY,
this.terminalWidth - this.cursorX - number, 1, this.terminalWidth - this.cursorX - number, 1,
-number, 0, this.color, this.style); -number, 0, this.color, this.style);
needWrap = false; this.needWrap = false;
}; };
VT100.prototype.csiX = function(number) { VT100.prototype.csiX = function(number) {
@ -3852,7 +3852,7 @@ VT100.prototype.csiX = function(number) {
} }
this.clearRegion(this.cursorX, this.cursorY, number, 1, this.clearRegion(this.cursorX, this.cursorY, number, 1,
this.color, this.style); this.color, this.style);
needWrap = false; this.needWrap = false;
}; };
VT100.prototype.settermCommand = function() { VT100.prototype.settermCommand = function() {