diff --git a/src/sbbs3/jsexec.c b/src/sbbs3/jsexec.c
index 87e85a0066ff4b9c151602de4355f4cc53c25564..b99b764aa92515a9de2a4cf40762270afae57c8e 100644
--- a/src/sbbs3/jsexec.c
+++ b/src/sbbs3/jsexec.c
@@ -46,6 +46,7 @@
 #include "sbbs.h"
 
 #define DEFAULT_LOG_MASK	0xff	/* Display all LOG levels */
+#define DEFAULT_ERR_LOG_LVL	LOG_WARNING
 
 JSRuntime*	js_runtime;
 JSContext*	js_cx;
@@ -66,6 +67,7 @@ BOOL		pause_on_error=FALSE;
 BOOL		terminated=FALSE;
 BOOL		terminate_immediately=FALSE;
 DWORD		log_mask=DEFAULT_LOG_MASK;
+int  		err_level=DEFAULT_ERR_LOG_LVL;
 
 void banner(FILE* fp)
 {
@@ -83,34 +85,56 @@ void usage(FILE* fp)
 
 	fprintf(fp,"\nusage: jsexec [-opts] [path]module[.js] [args]\n"
 		"\navailable opts:\n\n"
-		"\t-c <ctrl_dir>   specify path to Synchronet CTRL directory\n"
-		"\t-m <bytes>      set maximum heap size (default=%u bytes)\n"
-		"\t-s <bytes>      set context stack size (default=%u bytes)\n"
-		"\t-b <limit>      set branch limit (default=%u, 0=unlimited)\n"
-		"\t-y <interval>   set yield interval (default=%u, 0=never)\n"
-		"\t-g <interval>   set garbage collection interval (default=%u, 0=never)\n"
-		"\t-H              use local host name (instead of SCFG value)\n"
-		"\t-h <hostname>   use specified host name (instead of SCFG value)\n"
-		"\t-L <mask>       set log mask (default=0x%x)\n"
-		"\t-t <filename>   send console output to stdout and filename\n"
-		"\t-e              send error messages to console instead of stderr\n"
-		"\t-n              send status messages to %s instead of stdout\n"
-		"\t-q              send console messages to %s instead of stderr\n"
-		"\t-x              terminate immediately on local abort signal\n"
-		"\t-l              loop until intentionally terminated\n"
-		"\t-p              wait for keypress (pause) on exit\n"
-		"\t-!              wait for keypress (pause) on error\n"
+		"\t-c<ctrl_dir>   specify path to Synchronet CTRL directory\n"
+		"\t-m<bytes>      set maximum heap size (default=%u bytes)\n"
+		"\t-s<bytes>      set context stack size (default=%u bytes)\n"
+		"\t-b<limit>      set branch limit (default=%u, 0=unlimited)\n"
+		"\t-y<interval>   set yield interval (default=%u, 0=never)\n"
+		"\t-g<interval>   set garbage collection interval (default=%u, 0=never)\n"
+		"\t-h[hostname]   use local or specified host name (instead of SCFG value)\n"
+		"\t-L<mask>       set log level mask (default=0x%x)\n"
+		"\t-E<level>      set error log level threshold (default=%d)\n"
+		"\t-e<filename>   send error messages to file in addition to stderr\n"
+		"\t-o<filename>   send console messages to file instead of stdout\n"
+		"\t-n             send status messages to %s instead of stderr\n"
+		"\t-q             send console messages to %s instead of stdout\n"
+		"\t-x             terminate immediately on local abort signal\n"
+		"\t-l             loop until intentionally terminated\n"
+		"\t-p             wait for keypress (pause) on exit\n"
+		"\t-!             wait for keypress (pause) on error\n"
 		,JAVASCRIPT_MAX_BYTES
 		,JAVASCRIPT_CONTEXT_STACK
 		,JAVASCRIPT_BRANCH_LIMIT
 		,JAVASCRIPT_YIELD_INTERVAL
 		,JAVASCRIPT_GC_INTERVAL
 		,DEFAULT_LOG_MASK
+		,DEFAULT_ERR_LOG_LVL
 		,_PATH_DEVNULL
 		,_PATH_DEVNULL
 		);
 }
 
+/* Log printf */
+int lprintf(int level, char *fmt, ...)
+{
+	va_list argptr;
+	char sbuf[1024];
+	int ret;
+
+	if(!(log_mask&(1<<level)))
+		return(0);
+
+    va_start(argptr,fmt);
+    vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
+	sbuf[sizeof(sbuf)-1]=0;
+    va_end(argptr);
+	if(level<=err_level)
+		ret=fprintf(errfp,"%s",sbuf);
+	if(level>err_level || (errfp!=stderr && errfp!=confp))
+		ret=fprintf(confp,"%s",sbuf);
+    return(ret);
+}
+
 #if defined(_WINSOCKAPI_)
 
 WSADATA WSAData;
@@ -121,12 +145,12 @@ static BOOL winsock_startup(void)
 	int		status;             /* Status Code */
 
     if((status = WSAStartup(MAKEWORD(1,1), &WSAData))==0) {
-		fprintf(statfp,"%s %s\n",WSAData.szDescription, WSAData.szSystemStatus);
+/*		fprintf(statfp,"%s %s\n",WSAData.szDescription, WSAData.szSystemStatus); */
 		WSAInitialized=TRUE;
 		return(TRUE);
 	}
 
-    fprintf(errfp,"!WinSock startup ERROR %d\n", status);
+    lprintf(LOG_ERR,"!WinSock startup ERROR %d\n", status);
 	return(FALSE);
 }
 
@@ -141,7 +165,7 @@ void bail(int code)
 
 #if defined(_WINSOCKAPI_)
 	if(WSAInitialized && WSACleanup()!=0) 
-		fprintf(errfp,"!WSACleanup ERROR %d\n",ERROR_VALUE);
+		lprintf(LOG_ERR,"!WSACleanup ERROR %d\n",ERROR_VALUE);
 #endif
 
 	if(pause_on_exit || (code && pause_on_error)) {
@@ -164,15 +188,13 @@ js_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 	if(JSVAL_IS_NUMBER(argv[i]))
 		JS_ValueToInt32(cx,argv[i++],&level);
 
-	if(log_mask&(1<<level)) {
-		for(; i<argc; i++) {
-			if((str=JS_ValueToString(cx, argv[i]))==NULL)
-				return(JS_FALSE);
-			fprintf(errfp,"%s",JS_GetStringBytes(str));
-		}
-		if(argc)
-			fprintf(errfp,"\n");
+	for(; i<argc; i++) {
+		if((str=JS_ValueToString(cx, argv[i]))==NULL)
+			return(JS_FALSE);
+		lprintf(level,"%s",JS_GetStringBytes(str));
 	}
+	if(argc)
+		lprintf(level,"\n");
 
 	*rval = JSVAL_VOID;
     return(JS_TRUE);
@@ -374,7 +396,7 @@ js_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 	const char*	warning;
 
 	if(report==NULL) {
-		fprintf(errfp,"!JavaScript: %s\n", message);
+		lprintf(LOG_ERR,"!JavaScript: %s\n", message);
 		return;
     }
 
@@ -396,7 +418,7 @@ js_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 	} else
 		warning="";
 
-	fprintf(errfp,"!JavaScript %s%s%s: %s\n",warning,file,line,message);
+	lprintf(LOG_ERR,"!JavaScript %s%s%s: %s\n",warning,file,line,message);
 }
 
 static JSBool
@@ -541,12 +563,12 @@ long js_exec(const char *fname, char** args)
 			SAFECOPY(path,fname);
 
 		if(!fexistcase(path)) {
-			fprintf(errfp,"!Module file (%s) doesn't exist\n",path);
+			lprintf(LOG_ERR,"!Module file (%s) doesn't exist\n",path);
 			return(-1); 
 		}
 
 		if((fp=fopen(path,"r"))==NULL) {
-			fprintf(errfp,"!Error %d (%s) opening %s\n",errno,STRERROR(errno),path);
+			lprintf(LOG_ERR,"!Error %d (%s) opening %s\n",errno,STRERROR(errno),path);
 			return(-1);
 		}
 	}
@@ -586,7 +608,7 @@ long js_exec(const char *fname, char** args)
 #endif
 		len=strlen(line);
 		if((js_buf=realloc(js_buf,js_buflen+len))==NULL) {
-			fprintf(errfp,"!Error allocating %u bytes of memory\n"
+			lprintf(LOG_ERR,"!Error allocating %u bytes of memory\n"
 				,js_buflen+len);
 			return(-1);
 		}
@@ -597,7 +619,7 @@ long js_exec(const char *fname, char** args)
 		fclose(fp);
 
 	if((js_script=JS_CompileScript(js_cx, js_glob, js_buf, js_buflen, fname==NULL ? NULL : path, 1))==NULL) {
-		fprintf(errfp,"!Error compiling script from %s\n",path);
+		lprintf(LOG_ERR,"!Error compiling script from %s\n",path);
 		return(-1);
 	}
 	JS_ExecuteScript(js_cx, js_glob, js_script, &rval);
@@ -621,7 +643,7 @@ long js_exec(const char *fname, char** args)
 
 void break_handler(int type)
 {
-	fprintf(stderr,"\n-> Terminated Locally (signal: %d)\n",type);
+	fprintf(statfp,"\n-> Terminated Locally (signal: %d)\n",type);
 	terminated=TRUE;
 }
 
@@ -668,33 +690,55 @@ int main(int argc, char **argv, char** environ)
 
 	for(argn=1;argn<argc && module==NULL;argn++) {
 		if(argv[argn][0]=='-') {
+			p=argv[argn]+2;
 			switch(argv[argn][1]) {
 				case 'm':
-					js_max_bytes=strtoul(argv[++argn],NULL,0);
+					if(*p==0) p=argv[++argn];
+					js_max_bytes=strtoul(p,NULL,0);
 					break;
 				case 's':
-					js_cx_stack=strtoul(argv[++argn],NULL,0);
+					if(*p==0) p=argv[++argn];
+					js_cx_stack=strtoul(p,NULL,0);
 					break;
 				case 'b':
-					branch.limit=strtoul(argv[++argn],NULL,0);
+					if(*p==0) p=argv[++argn];
+					branch.limit=strtoul(p,NULL,0);
 					break;
 				case 'y':
-					branch.yield_interval=strtoul(argv[++argn],NULL,0);
+					if(*p==0) p=argv[++argn];
+					branch.yield_interval=strtoul(p,NULL,0);
 					break;
 				case 'g':
-					branch.gc_interval=strtoul(argv[++argn],NULL,0);
+					if(*p==0) p=argv[++argn];
+					branch.gc_interval=strtoul(p,NULL,0);
 					break;
 				case 'h':
-					host_name=argv[++argn];
-					break;
-				case 'H':
-					gethostname(host_name=host_name_buf,sizeof(host_name_buf));
+					if(*p==0)
+						gethostname(host_name=host_name_buf,sizeof(host_name_buf));
+					else
+						host_name=p;
 					break;
 				case 'L':
-					log_mask=strtol(argv[++argn],NULL,0);
+					if(*p==0) p=argv[++argn];
+					log_mask=strtol(p,NULL,0);
+					break;
+				case 'E':
+					if(*p==0) p=argv[++argn];
+					err_level=strtol(p,NULL,0);
 					break;
 				case 'e':
-					errfp=confp;
+					if(*p==0) p=argv[++argn];
+					if((errfp=fopen(p,"a"))==NULL) {
+						perror(p);
+						bail(1);
+					}
+					break;
+				case 'o':
+					if(*p==0) p=argv[++argn];
+					if((confp=fopen(p,"a"))==NULL) {
+						perror(p);
+						bail(1);
+					}
 					break;
 				case 'q':
 					confp=nulfp;
@@ -715,7 +759,8 @@ int main(int argc, char **argv, char** environ)
 					pause_on_error=TRUE;
 					break;
 				case 'c':
-					SAFECOPY(scfg.ctrl_dir,argv[++argn]);
+					if(*p==0) p=argv[++argn];
+					SAFECOPY(scfg.ctrl_dir,p);
 					break;
 				default:
 					fprintf(errfp,"\n!Unsupported option: %s\n",argv[argn]);
@@ -730,16 +775,16 @@ int main(int argc, char **argv, char** environ)
 
 	if(scfg.ctrl_dir[0]==0) {
 		if((p=getenv("SBBSCTRL"))==NULL) {
-			fprintf(errfp,"\nSBBSCTRL environment variable not set and -c option not specified.\n");
-			fprintf(errfp,"\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
-			fprintf(errfp,"\n     or: %s -c /sbbs/ctrl [module]\n",argv[0]);
+			lprintf(LOG_ERR,"\nSBBSCTRL environment variable not set and -c option not specified.\n");
+			lprintf(LOG_ERR,"\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
+			lprintf(LOG_ERR,"\n     or: %s -c /sbbs/ctrl [module]\n",argv[0]);
 			bail(1); 
 		}
 		SAFECOPY(scfg.ctrl_dir,p);
 	}	
 
 	if(module==NULL && isatty(fileno(stdin))) {
-		fprintf(errfp,"\n!Module name not specified\n");
+		lprintf(LOG_ERR,"\n!Module name not specified\n");
 		usage(errfp);
 		bail(1); 
 	}
@@ -747,11 +792,11 @@ int main(int argc, char **argv, char** environ)
 	banner(statfp);
 
 	if(chdir(scfg.ctrl_dir)!=0)
-		fprintf(errfp,"!ERROR changing directory to: %s", scfg.ctrl_dir);
+		lprintf(LOG_ERR,"!ERROR changing directory to: %s", scfg.ctrl_dir);
 
 	fprintf(statfp,"\nLoading configuration files from %s\n",scfg.ctrl_dir);
 	if(!load_cfg(&scfg,NULL,TRUE,error)) {
-		fprintf(errfp,"!ERROR loading configuration files: %s\n",error);
+		lprintf(LOG_ERR,"!ERROR loading configuration files: %s\n",error);
 		bail(1);
 	}
 	prep_dir(scfg.data_dir, scfg.temp_dir, sizeof(scfg.temp_dir));
@@ -778,7 +823,7 @@ int main(int argc, char **argv, char** environ)
 	do {
 
 		if(!js_init(environ)) {
-			fprintf(errfp,"!JavaScript initialization failure\n");
+			lprintf(LOG_ERR,"!JavaScript initialization failure\n");
 			bail(1);
 		}
 		fprintf(statfp,"\n");