diff --git a/src/sbbs3/exec.cpp b/src/sbbs3/exec.cpp
index 9e9f04d6e84b516ea1a20b146af8f0c12e81c4e7..718c9f6a9d89fb115ca02da46139759f951c204a 100644
--- a/src/sbbs3/exec.cpp
+++ b/src/sbbs3/exec.cpp
@@ -543,6 +543,12 @@ long sbbs_t::js_execfile(char *cmd)
 	JSScript*	js_script=NULL;
 	jsval		rval;
 	
+	if(js_cx==NULL) {
+		errormsg(WHERE,ERR_CHK,"JavaScript support",0);
+		errormsg(WHERE,ERR_EXEC,cmd,0);
+		return(-1);
+	}
+
 	sprintf(cmdline,"%.*s",sizeof(cmdline)-1,cmd);
 	p=strchr(cmdline,' ');
 	if(p!=NULL) {
diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c
index 3abc298c20bdeb113c836c46424907cd957df8b5..ebc80ebf620678792987effb82581d68314d13ce 100644
--- a/src/sbbs3/ftpsrvr.c
+++ b/src/sbbs3/ftpsrvr.c
@@ -2119,7 +2119,7 @@ static void ctrl_thread(void* arg)
 	struct tm 	cur_tm;
 #ifdef JAVASCRIPT
 	jsval		js_val;
-	JSContext*	js_cx;
+	JSContext*	js_cx=NULL;
 	JSObject*	js_glob;
 	JSObject*	js_ftp;
 #endif
@@ -2144,12 +2144,14 @@ static void ctrl_thread(void* arg)
 #endif
 
 #ifdef JAVASCRIPT
-	if(((js_cx=js_initcx(sock,&js_glob,&js_ftp))==NULL)) {
-		lprintf("%04d !ERROR initializing JavaScript context",sock);
-		sockprintf(sock,"425 Error initializing JavaScript context");
-		ftp_close_socket(&sock,__LINE__);
-		thread_down();
-		return;
+	if(!(startup->options&FTP_OPT_NO_JAVASCRIPT)) {
+		if(((js_cx=js_initcx(sock,&js_glob,&js_ftp))==NULL)) {
+			lprintf("%04d !ERROR initializing JavaScript context",sock);
+			sockprintf(sock,"425 Error initializing JavaScript context");
+			ftp_close_socket(&sock,__LINE__);
+			thread_down();
+			return;
+		}
 	}
 #endif
 
@@ -2438,22 +2440,24 @@ static void ctrl_thread(void* arg)
 			}
 
 #ifdef JAVASCRIPT
-			JS_BeginRequest(js_cx);	/* Required for multi-thread support */
+			if(js_cx!=NULL) {
+				JS_BeginRequest(js_cx);	/* Required for multi-thread support */
 
-			if(js_CreateUserClass(js_cx, js_glob, &scfg)==NULL) 
-				lprintf("%04d !JavaScript ERROR creating user class",sock);
+				if(js_CreateUserClass(js_cx, js_glob, &scfg)==NULL) 
+					lprintf("%04d !JavaScript ERROR creating user class",sock);
 
-			if(js_CreateUserObject(js_cx, js_glob, &scfg, "user", user.number)==NULL) 
-				lprintf("%04d !JavaScript ERROR creating user object",sock);
+				if(js_CreateUserObject(js_cx, js_glob, &scfg, "user", user.number)==NULL) 
+					lprintf("%04d !JavaScript ERROR creating user object",sock);
 
-			if(js_CreateClientObject(js_cx, js_glob, "client", &client, sock)==NULL) 
-				lprintf("%04d !JavaScript ERROR creating client object",sock);
+				if(js_CreateClientObject(js_cx, js_glob, "client", &client, sock)==NULL) 
+					lprintf("%04d !JavaScript ERROR creating client object",sock);
 
-			if(js_CreateFileAreaObject(js_cx, js_glob, &scfg, &user
-				,startup->html_index_file)==NULL) 
-				lprintf("%04d !JavaScript ERROR creating file area object",sock);
+				if(js_CreateFileAreaObject(js_cx, js_glob, &scfg, &user
+					,startup->html_index_file)==NULL) 
+					lprintf("%04d !JavaScript ERROR creating file area object",sock);
 
-			JS_EndRequest(js_cx);	/* Required for multi-thread support */
+				JS_EndRequest(js_cx);	/* Required for multi-thread support */
+			}
 #endif
 
 			if(sysop)
@@ -3464,6 +3468,13 @@ static void ctrl_thread(void* arg)
 				|| !strnicmp(p,html_index_ext,strlen(html_index_ext)))
 				&& !delecmd) {
 #ifdef JAVASCRIPT
+				if(js_cx==NULL) {
+					lprintf("%04d !JavaScript disabled, cannot generate %s",sock,fname);
+					sockprintf(sock, "451 JavaScript disabled");
+					filepos=0;
+					continue;
+				}
+
 				JS_BeginRequest(js_cx);	/* Required for multi-thread support */
 
 				js_val=STRING_TO_JSVAL(JS_NewStringCopyZ(js_cx, "name"));
@@ -3972,8 +3983,10 @@ static void ctrl_thread(void* arg)
 #endif
 
 #ifdef JAVASCRIPT
-	lprintf("%04d JavaScript: Destroying context",sock);
-	JS_DestroyContext(js_cx);	/* Free Context */
+	if(js_cx!=NULL) {
+		lprintf("%04d JavaScript: Destroying context",sock);
+		JS_DestroyContext(js_cx);	/* Free Context */
+	}
 #endif
 
 	status(STATUS_WFC);
@@ -4018,8 +4031,8 @@ static void cleanup(int code)
 #endif
 
 #ifdef JAVASCRIPT
-	lprintf("0000 JavaScript: Destroying runtime");
 	if(js_runtime!=NULL) {
+		lprintf("0000 JavaScript: Destroying runtime");
 		JS_DestroyRuntime(js_runtime);
 		js_runtime=NULL;
 	}
@@ -4091,12 +4104,11 @@ void DLLCALL ftp_server(void* arg)
 	if(startup->max_inactivity==0)			startup->max_inactivity=300;	/* seconds */
 	if(startup->index_file_name[0]==0)		strcpy(startup->index_file_name,"00index");
 	if(startup->html_index_file[0]==0)		strcpy(startup->html_index_file,"00index.html");
-	if(startup->html_index_script[0]==0)	strcpy(startup->html_index_script,"ftp-html.js");
-
-	/*temporary*/
-#ifdef JAVASCRIPT
-	startup->options|=FTP_OPT_HTML_INDEX_FILE;
-#endif
+	if(startup->html_index_script[0]==0) {	strcpy(startup->html_index_script,"ftp-html.js");
+											startup->options|=FTP_OPT_HTML_INDEX_FILE;
+	}
+	if(!(startup->options&FTP_OPT_HTML_INDEX_FILE))
+		startup->options|=FTP_OPT_NO_JAVASCRIPT;
 
 	thread_up();
 
@@ -4189,16 +4201,17 @@ void DLLCALL ftp_server(void* arg)
 		strlwr(scfg.dir[i]->code);
 
 #ifdef JAVASCRIPT
-	lprintf("JavaScript: Creating runtime: %lu bytes"
-		,JAVASCRIPT_RUNTIME_MEMORY);
+	if(!(startup->options&FTP_OPT_NO_JAVASCRIPT)) {
+		lprintf("JavaScript: Creating runtime: %lu bytes"
+			,JAVASCRIPT_RUNTIME_MEMORY);
 
-	if((js_runtime = JS_NewRuntime(JAVASCRIPT_RUNTIME_MEMORY))==NULL) {
-		lprintf("!JS_NewRuntime failed");
-		cleanup(1);
-		return;
+		if((js_runtime = JS_NewRuntime(JAVASCRIPT_RUNTIME_MEMORY))==NULL) {
+			lprintf("!JS_NewRuntime failed");
+			cleanup(1);
+			return;
+		}
+		lprintf("JavaScript: Context stack: %lu bytes", JAVASCRIPT_CONTEXT_STACK);
 	}
-
-	lprintf("JavaScript: Context stack: %lu bytes", JAVASCRIPT_CONTEXT_STACK);
 #endif
 
     /* open a socket and wait for a client */
diff --git a/src/sbbs3/ftpsrvr.h b/src/sbbs3/ftpsrvr.h
index b71d928d0b4856bc4d0331d1cd68f7752f036037..3a2774e8759b4d68f3ef6cac3b33fe0b4a0bb80b 100644
--- a/src/sbbs3/ftpsrvr.h
+++ b/src/sbbs3/ftpsrvr.h
@@ -100,6 +100,7 @@ typedef struct {
 #define FTP_OPT_KEEP_TEMP_FILES		(1<<7)	/* Don't delete temp files (for debugging) */
 #define FTP_OPT_HTML_INDEX_FILE		(1<<8)	/* Auto-generate HTML index files */
 #define FTP_OPT_NO_HOST_LOOKUP		(1<<11)
+#define FTP_OPT_NO_JAVASCRIPT		(1<<29)	/* JavaScript disabled				*/
 #define FTP_OPT_LOCAL_TIMEZONE		(1<<30)	/* Don't force UCT/GMT */
 #define FTP_OPT_MUTE				(1<<31)
 
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 6cd8dc52686b003d619c7a338755db61f6a00c9b..b6881901a7393b1d072c7533efecd45c5ddb666c 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -899,7 +899,8 @@ void event_thread(void* arg)
 	thread_up();
 
 #ifdef JAVASCRIPT
-	sbbs->js_initcx();	/* This must be done in the context of the event thread */
+	if(!(startup->options&BBS_OPT_NO_JAVASCRIPT)) 
+		sbbs->js_initcx();	/* This must be done in the context of the event thread */
 #endif
 
 	while(1) {
@@ -909,6 +910,8 @@ void event_thread(void* arg)
 		if(sbbs->terminated || telnet_socket==INVALID_SOCKET)
 			break;
 
+		sbbs->online=0;	/* reset this from ON_LOCAL */
+
 		if(scfg_reloaded==true) {
 
 			for(i=0;i<TOTAL_TEXT;i++)
@@ -2536,27 +2539,30 @@ void node_thread(void* arg)
 	sbbs_random(10);	/* Throw away first number */
 
 #ifdef JAVASCRIPT
-	sbbs->js_initcx();	/* This must be done in the context of the node thread */
+	if(!(startup->options&BBS_OPT_NO_JAVASCRIPT)) 
+		sbbs->js_initcx();	/* This must be done in the context of the node thread */
 #endif
 
 	if(sbbs->answer()) {
 
 #ifdef JAVASCRIPT
-		JS_BeginRequest(sbbs->js_cx);	/* Required for multi-thread support */
+		if(sbbs->js_cx!=NULL) {
+			JS_BeginRequest(sbbs->js_cx);	/* Required for multi-thread support */
 
-		/* User Class */
-		if(js_CreateUserClass(sbbs->js_cx, sbbs->js_glob, &sbbs->cfg)==NULL) 
-			lprintf("!JavaScript ERROR creating user class");
+			/* User Class */
+			if(js_CreateUserClass(sbbs->js_cx, sbbs->js_glob, &sbbs->cfg)==NULL) 
+				lprintf("!JavaScript ERROR creating user class");
 
-		/* User Object */
-		if(js_CreateUserObject(sbbs->js_cx, sbbs->js_glob, &sbbs->cfg, "user", sbbs->useron.number)==NULL) 
-			lprintf("!JavaScript ERROR creating user object");
+			/* User Object */
+			if(js_CreateUserObject(sbbs->js_cx, sbbs->js_glob, &sbbs->cfg, "user", sbbs->useron.number)==NULL) 
+				lprintf("!JavaScript ERROR creating user object");
 
-		/* FileArea Object */
-		if(js_CreateFileAreaObject(sbbs->js_cx, sbbs->js_glob, &sbbs->cfg, &sbbs->useron, "")==NULL) 
-			lprintf("!JavaScript ERROR createing file_area object");
+			/* FileArea Object */
+			if(js_CreateFileAreaObject(sbbs->js_cx, sbbs->js_glob, &sbbs->cfg, &sbbs->useron, "")==NULL) 
+				lprintf("!JavaScript ERROR createing file_area object");
 
-		JS_EndRequest(sbbs->js_cx);	/* Required for multi-thread support */
+			JS_EndRequest(sbbs->js_cx);	/* Required for multi-thread support */
+		}
 #endif
 
 		if(sbbs->qwklogon) {
@@ -3070,14 +3076,16 @@ void DLLCALL bbs_thread(void* arg)
 	startup->node_inbuf=node_inbuf;
 
 #ifdef JAVASCRIPT
-	lprintf("JavaScript: %s",JS_GetImplementationVersion());
-	lprintf("JavaScript: Creating runtime: %lu bytes", JAVASCRIPT_RUNTIME_MEMORY);
-	if((js_runtime = JS_NewRuntime(JAVASCRIPT_RUNTIME_MEMORY))==NULL) {
-		lprintf("!JS_NewRuntime failed");
-		cleanup(1);
-		return;
+	if(!(startup->options&BBS_OPT_NO_JAVASCRIPT)) {
+		lprintf("JavaScript: %s",JS_GetImplementationVersion());
+		lprintf("JavaScript: Creating runtime: %lu bytes", JAVASCRIPT_RUNTIME_MEMORY);
+		if((js_runtime = JS_NewRuntime(JAVASCRIPT_RUNTIME_MEMORY))==NULL) {
+			lprintf("!JS_NewRuntime failed");
+			cleanup(1);
+			return;
+		}
+		lprintf("JavaScript: Context stack: %lu bytes", JAVASCRIPT_CONTEXT_STACK);
 	}
-	lprintf("JavaScript: Context stack: %lu bytes", JAVASCRIPT_CONTEXT_STACK);
 #endif
 
     /* open a socket and wait for a client */
diff --git a/src/sbbs3/startup.h b/src/sbbs3/startup.h
index c10bae3e833d8297123f19cda2eb5bbdd1e2fb37..6e83ba4f1e83bb9f180221ca0e246d07e935e8fb 100644
--- a/src/sbbs3/startup.h
+++ b/src/sbbs3/startup.h
@@ -98,6 +98,7 @@ typedef struct {
 #define BBS_OPT_USE_2ND_RLOGIN		(1<<6)	/* Use 2nd username in BSD RLogin	*/
 #define BBS_OPT_NO_QWK_EVENTS		(1<<7)	/* Don't run QWK-related events		*/
 #define BBS_OPT_NO_HOST_LOOKUP		(1<<11)
+#define BBS_OPT_NO_JAVASCRIPT		(1<<29)	/* JavaScript disabled				*/
 #define BBS_OPT_LOCAL_TIMEZONE		(1<<30)	/* Don't force UCT/GMT				*/
 #define BBS_OPT_MUTE				(1<<31)	/* Mute sounds						*/