Merge pull request #286 from KLuka/master
Partial fixes for issues #103, #203, #195 and README.md
This commit is contained in:
commit
cc3f2fe917
7 changed files with 101 additions and 16 deletions
29
README.md
Normal file
29
README.md
Normal 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)
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in a new issue