Skip to content
Snippets Groups Projects
js_system.c 76.4 KiB
Newer Older
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	JS_ValueToInt32(cx,argv[0],&field);
	len=user_field_len(field);
	if(len < 1) {
		JS_ReportError(cx,"Invalid user field: %d", field);

	if((js_str=JS_ValueToString(cx, argv[1]))==NULL) {
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
	if(JSVAL_IS_BOOLEAN(argv[argnum]))
		JS_ValueToBoolean(cx, argv[argnum], &match_del);
	if(JSVAL_IS_NUMBER(argv[argnum]))
		JS_ValueToInt32(cx, argv[argnum++], &usernumber);
	if(JSVAL_IS_BOOLEAN(argv[argnum]))
		JS_ValueToBoolean(cx, argv[argnum], &match_next);
deuce's avatar
deuce committed
	JSSTRING_TO_ASTRING(cx, js_str, p, 128, NULL);
deuce's avatar
deuce committed
	if(p==NULL) {
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(finduserstr(sys->cfg, usernumber, field, p, match_del, match_next, NULL, NULL)));

static JSBool
js_find_login_id(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	char*		p;
	JSString*	js_str;
	jsrefcount	rc;

	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;

	if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
		return(JS_TRUE);
	}

	JSSTRING_TO_ASTRING(cx, js_str, p, (LEN_ALIAS > LEN_NAME) ? LEN_ALIAS+2:LEN_NAME+2, NULL);
	if(p==NULL) {
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
		return(JS_TRUE);
	}

	rc=JS_SUSPENDREQUEST(cx);
	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(find_login_id(sys->cfg, p)));
	JS_RESUMEREQUEST(cx, rc);
	return(JS_TRUE);
}

static JSBool
js_trashcan(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	JSString*	js_str;
	JSString*	js_can;
deuce's avatar
deuce committed
	jsrefcount	rc;
deuce's avatar
deuce committed
	BOOL		ret;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;

	if((js_can=JS_ValueToString(cx, argv[0]))==NULL) {
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
		return(JS_TRUE);
	}

	if((js_str=JS_ValueToString(cx, argv[1]))==NULL) {
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
deuce's avatar
deuce committed
	JSSTRING_TO_MSTRING(cx, js_can, can, NULL);
	HANDLE_PENDING(cx, can);
deuce's avatar
deuce committed
	if(can==NULL) {
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
deuce's avatar
deuce committed
	JSSTRING_TO_MSTRING(cx, js_str, str, NULL);
	if(JS_IsExceptionPending(cx)) {
deuce's avatar
deuce committed
		free(can);
		return JS_FALSE;
	}
deuce's avatar
deuce committed
	if(str==NULL) {
deuce's avatar
deuce committed
		free(can);
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
deuce's avatar
deuce committed
	free(can);
	free(str);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));
js_findstr(JSContext *cx, uintN argc, jsval *arglist)
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	jsrefcount	rc;
deuce's avatar
deuce committed
	BOOL		ret;
	str_list_t	list = NULL;
	if(JSVAL_IS_OBJECT(argv[0]) && !JSVAL_IS_NULL(argv[0])) {
		JSObject* array = JSVAL_TO_OBJECT(argv[0]);
		if(array == NULL || !JS_IsArrayObject(cx, array))
			return(JS_TRUE);
		jsuint count;
		if(!JS_GetArrayLength(cx, array, &count))
			return(JS_TRUE);
		char* tmp = NULL;
		size_t tmplen = 0;
		for(jsuint i = 0; i < count; i++) {
			jsval val;
			if(!JS_GetElement(cx, array, i, &val))
				break;
			if(!JSVAL_IS_STRING(val))	/* must be an array of strings */
				break;
			JSVALUE_TO_RASTRING(cx, val, tmp, &tmplen, NULL);
			HANDLE_PENDING(cx, tmp);
			strListPush(&list, tmp);
		}
		free(tmp);
	else {
		if((js_fname=JS_ValueToString(cx, argv[0]))==NULL) {
			JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
			return(JS_TRUE);
		}
		JSSTRING_TO_MSTRING(cx, js_fname, fname, NULL);
		HANDLE_PENDING(cx, fname);
		if(fname==NULL) {
			JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
			return(JS_TRUE);
		}
	if((js_str=JS_ValueToString(cx, argv[1]))==NULL) {
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
		free(fname);
deuce's avatar
deuce committed
	JSSTRING_TO_MSTRING(cx, js_str, str, NULL);
	if(JS_IsExceptionPending(cx)) {
deuce's avatar
deuce committed
		free(fname);
		return JS_FALSE;
	}
deuce's avatar
deuce committed
	if(str==NULL) {
deuce's avatar
deuce committed
		free(fname);
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(JS_FALSE));
		ret = findstr_in_list(str, list, NULL);
	else
		ret = findstr(str, fname);
deuce's avatar
deuce committed
	free(str);
	free(fname);
	strListFree(&list);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));
static JSBool
js_zonestr(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	JSString*	js_str;
deuce's avatar
deuce committed
	jsrefcount	rc;
	char*		cstr;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	else {
		JS_ValueToInt32(cx,argv[0],&val);
		zone=(short)val;
	}
deuce's avatar
deuce committed
	cstr=smb_zonestr(zone,NULL);
deuce's avatar
deuce committed
	if((js_str = JS_NewStringCopyZ(cx, cstr))==NULL)
		return(JS_FALSE);
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
/* Returns a ctime()-like string in the system-preferred time format */
js_timestr(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
		ti=(jsdouble)time(NULL);	/* use current time */
		if(!JS_ValueToNumber(cx,argv[0],&ti))
			return JS_TRUE;
	if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
		return(JS_FALSE);
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
/* Returns a mm/dd/yy or dd/mm/yy formated string */
js_datestr(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	char		*p;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
		t=time32(NULL);	/* use current time */
	else {
		if(JSVAL_IS_STRING(argv[0])) {	/* convert from string to time_t? */
deuce's avatar
deuce committed
			JSVALUE_TO_ASTRING(cx, argv[0], p, 10, NULL);
			JS_SET_RVAL(cx, arglist, DOUBLE_TO_JSVAL((double)dstrtounix(sys->cfg, p)));
		JS_ValueToECMAUint32(cx,argv[0],(uint32_t*)&t);
	if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
		return(JS_FALSE);
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
js_secondstr(JSContext *cx, uintN argc, jsval *arglist)
	jsval *argv=JS_ARGV(cx, arglist);
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
 	if(!js_argc(cx, argc, 1))
		return JS_FALSE;
	if(JSVAL_NULL_OR_VOID(argv[0])) {
		JS_ReportError(cx, "Invalid argument");
		return JS_FALSE;
	}
	JS_ValueToECMAUint32(cx,argv[0],&t);
	if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
		return(JS_FALSE);
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
js_spamlog(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	char*		p=NULL;
	char*		prot=NULL;
	char*		reason=NULL;
	char*		host=NULL;
	char*		ip_addr=NULL;
	char*		to=NULL;
deuce's avatar
deuce committed
	jsrefcount	rc;
deuce's avatar
deuce committed
	BOOL		ret;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	for(i=0;i<argc && from == NULL;i++) {
		if(!JSVAL_IS_STRING(argv[i]))
			continue;
		JSVALUE_TO_MSTRING(cx, argv[i], p, NULL);
		if(p == NULL || JS_IsExceptionPending(cx)) {
			free(prot);
			free(action);
			free(reason);
			free(host);
			free(ip_addr);
			free(to);
			free(p);
			return JS_FALSE;
		if(prot==NULL)
			prot=p;
		else if(action==NULL)
			action=p;
		else if(reason==NULL)
			reason=p;
		else if(host==NULL)
			host=p;
		else if(ip_addr==NULL)
			ip_addr=p;
		else if(to==NULL)
			to=p;
		else
			from=p;
	ret=spamlog(sys->cfg, sys->mqtt, prot, action, reason, host, ip_addr, to, from);
	free(prot);
	free(action);
	free(reason);
	free(host);
	free(ip_addr);
	free(to);
	free(from);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));
	return(JS_TRUE);
}

static JSBool
js_hacklog(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	char*		p=NULL;
	char*		prot=NULL;
	char*		user=NULL;
	char*		text=NULL;
	char*		host=NULL;
deuce's avatar
deuce committed
	union xp_sockaddr	addr;
deuce's avatar
deuce committed
	jsrefcount	rc;
deuce's avatar
deuce committed
	BOOL		ret;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;

	memset(&addr,0,sizeof(addr));
	for(i=0;i<argc;i++) {
		if(JSVAL_IS_NUMBER(argv[i])) {
			JS_ValueToInt32(cx,argv[i],&i32);
deuce's avatar
deuce committed
			if(addr.in.sin_addr.s_addr==0)
				addr.in.sin_addr.s_addr=i32;
deuce's avatar
deuce committed
				addr.in.sin_port=(ushort)i32;
			continue;
		}
		if(!JSVAL_IS_STRING(argv[i]))
			continue;
deuce's avatar
deuce committed
		if(host==NULL) {
			JSVALUE_TO_MSTRING(cx, argv[i], p, NULL);
			if(JS_IsExceptionPending(cx) || p == NULL) {
				free(prot);
				free(user);
				free(text);
				free(p);
deuce's avatar
deuce committed
				return JS_FALSE;
			}
			if(prot==NULL)
				prot=p;
			else if(user==NULL)
				user=p;
			else if(text==NULL)
				text=p;
			else
				host=p;
	ret=hacklog(sys->cfg, sys->mqtt, prot, user, text, host, &addr);
	free(prot);
	free(user);
	free(text);
	free(host);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));
static JSBool
js_filter_ip(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	uintN		i;
	char*		p=NULL;
	char*		prot=NULL;
	char*		reason=NULL;
	char*		host=NULL;
	char*		ip_addr=NULL;
	char*		from=NULL;
deuce's avatar
deuce committed
	jsrefcount	rc;
deuce's avatar
deuce committed
	BOOL		ret;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	for(i=0; i<argc && fname == NULL; i++) {
		if(JSVAL_IS_NUMBER(argv[i])) {
			JS_ValueToInt32(cx, argv[i], &duration);
			continue;
		}
		if(!JSVAL_IS_STRING(argv[i]))
			continue;
		JSVALUE_TO_MSTRING(cx, argv[i], p, NULL);
		if(JS_IsExceptionPending(cx) || p == NULL) {
			free(prot);
			free(reason);
			free(host);
			free(ip_addr);
			free(from);
			free(p);
			return JS_FALSE;
		if(prot==NULL)
			prot=p;
		else if(reason==NULL)
			reason=p;
		else if(host==NULL)
			host=p;
		else if(ip_addr==NULL)
			ip_addr=p;
		else if(from==NULL)
			from=p;
	ret=filter_ip(sys->cfg,prot,reason,host,ip_addr,from,fname, duration);
	free(prot);
	free(reason);
	free(host);
	free(ip_addr);
	free(from);
	free(fname);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));
	return(JS_TRUE);
}

static JSBool
js_get_node(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject*	obj=JS_THIS_OBJECT(cx, arglist);
	JSObject*	nodeobj;
	jsval*		argv=JS_ARGV(cx, arglist);
	node_t		node = {0};
	int32		node_num;
	jsrefcount	rc;

	JS_SET_RVAL(cx, arglist, JSVAL_NULL);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	scfg_t* cfg = sys->cfg;

	node_num=cfg->node_num;
	if(argc)  {
		if(!JS_ValueToInt32(cx,argv[0],&node_num))
			return JS_TRUE;
	}
	if(node_num<1)
		node_num=1;

	rc=JS_SUSPENDREQUEST(cx);

	int retval = getnodedat(sys->cfg, node_num, &node, /* lockit: */FALSE, &sys->nodefile);
	sys->nodegets++;
	JS_RESUMEREQUEST(cx, rc);
	if(retval != 0) {
		JS_ReportError(cx, "getnodat(%d) returned %d", node_num, retval);
		return JS_TRUE;
	}
	if((nodeobj = JS_NewObject(cx, NULL, NULL, obj)) == NULL) {
		JS_ReportError(cx, "JS_NewObject failure");
		return JS_TRUE;
	}
	JS_DefineProperty(cx, nodeobj, "status", INT_TO_JSVAL((int)node.status), NULL, NULL, JSPROP_ENUMERATE);
	JS_DefineProperty(cx, nodeobj, "errors", INT_TO_JSVAL((int)node.errors), NULL, NULL, JSPROP_ENUMERATE);
	JS_DefineProperty(cx, nodeobj, "action", INT_TO_JSVAL((int)node.action), NULL, NULL, JSPROP_ENUMERATE);
	JS_DefineProperty(cx, nodeobj, "useron", INT_TO_JSVAL((int)node.useron), NULL, NULL, JSPROP_ENUMERATE);
	JS_DefineProperty(cx, nodeobj, "connection", INT_TO_JSVAL((int)node.connection), NULL, NULL, JSPROP_ENUMERATE);
	JS_DefineProperty(cx, nodeobj, "misc", INT_TO_JSVAL((int)node.misc), NULL, NULL, JSPROP_ENUMERATE);
	JS_DefineProperty(cx, nodeobj, "aux", INT_TO_JSVAL((int)node.aux), NULL, NULL, JSPROP_ENUMERATE);
	JS_DefineProperty(cx, nodeobj, "extaux", INT_TO_JSVAL((int)node.extaux), NULL, NULL, JSPROP_ENUMERATE);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(nodeobj));
	return JS_TRUE;
}

js_get_node_message(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	char*		buf;
	int32		node_num;
	JSString*	js_str;
deuce's avatar
deuce committed
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	scfg_t* cfg = sys->cfg;
		JS_ValueToInt32(cx,argv[0],&node_num);
	if(node_num<1)
		node_num=1;


	js_str=JS_NewStringCopyZ(cx, buf);
	free(buf);

	if(js_str==NULL)
		return(JS_FALSE);
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
js_put_node_message(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	jsrefcount	rc;
deuce's avatar
deuce committed
	BOOL		ret;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	JS_ValueToInt32(cx,argv[0],&node);
	if(node<1)
	if((js_msg=JS_ValueToString(cx, argv[1]))==NULL)
deuce's avatar
deuce committed
	JSSTRING_TO_MSTRING(cx, js_msg, msg, NULL);
	HANDLE_PENDING(cx, msg);
deuce's avatar
deuce committed
		return(JS_TRUE);
deuce's avatar
deuce committed
	free(msg);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));
js_get_telegram(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	char*		buf;
	int32		usernumber=1;
	JSString*	js_str;
deuce's avatar
deuce committed
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;

	JS_ValueToInt32(cx,argv[0],&usernumber);
	if(usernumber<1)
		usernumber=1;


	js_str=JS_NewStringCopyZ(cx, buf);
	free(buf);

	if(js_str==NULL)
		return(JS_FALSE);
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
js_put_telegram(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	jsrefcount	rc;
deuce's avatar
deuce committed
	BOOL		ret;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	JS_ValueToInt32(cx,argv[0],&usernumber);
	if(usernumber<1)
	if((js_msg=JS_ValueToString(cx, argv[1]))==NULL)
deuce's avatar
deuce committed
	JSSTRING_TO_MSTRING(cx, js_msg, msg, NULL);
	HANDLE_PENDING(cx, msg);
deuce's avatar
deuce committed
	if(msg==NULL)
		return(JS_TRUE);
	ret=putsmsg(sys->cfg,usernumber,msg)==0;
deuce's avatar
deuce committed
	free(msg);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));
static JSBool
js_notify(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	int32		usernumber=1;
	JSString*	js_subj;
	JSString*	js_msg;
	char*		subj;
	char*		msg = NULL;
	jsrefcount	rc;
	BOOL		ret;

	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;

	JS_ValueToInt32(cx,argv[0],&usernumber);
	if(usernumber<1)
		usernumber=1;

	if((js_subj=JS_ValueToString(cx, argv[1]))==NULL)
		if((js_msg=JS_ValueToString(cx, argv[2]))==NULL)
			return JS_FALSE;

		JSSTRING_TO_MSTRING(cx, js_msg, msg, NULL);
		HANDLE_PENDING(cx, msg);
		if(msg==NULL)
			return JS_TRUE;
	}

	JSSTRING_TO_MSTRING(cx, js_subj, subj, NULL);
	HANDLE_PENDING(cx,subj);
	if(subj==NULL) {
		free(msg);
		return JS_TRUE;
	}

	rc=JS_SUSPENDREQUEST(cx);
	ret=notify(sys->cfg, usernumber, subj, msg)==0;
	free(subj);
	free(msg);
	JS_RESUMEREQUEST(cx, rc);
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(ret));

	return JS_TRUE;
}

js_new_user(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	scfg_t* cfg = sys->cfg;
 	if(!js_argc(cx, argc, 1))
	if(JSVAL_NULL_OR_VOID(argv[0])) {
		JS_ReportError(cx, "Invalid argument");
		return JS_FALSE;
	}
deuce's avatar
deuce committed
	JSVALUE_TO_ASTRING(cx, argv[0], alias, LEN_ALIAS+2, NULL);
		JS_ReportError(cx,"Invalid or duplicate user alias: %s", alias);
		return JS_FALSE;
	}

	for(n=0;n<argc;n++) {
		if(JSVAL_IS_OBJECT(argv[n])) {
			objarg = JSVAL_TO_OBJECT(argv[n]);
			if(objarg != NULL && (cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0) {
	// Find and use the global client object if possible...
	if(client==NULL) {
		if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "client", &val) && !JSVAL_NULL_OR_VOID(val)) {
			objarg = JSVAL_TO_OBJECT(val);
			if(objarg != NULL && (cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0)
		SAFECOPY(user.modem,client->protocol);
		SAFECOPY(user.comp,client->host);
		SAFECOPY(user.ipaddr,client->addr);
	newuserdefaults(cfg, &user);
		userobj=js_CreateUserObject(cx, obj, NULL, &user, /* client: */NULL, /* global_user: */FALSE, (struct mqtt*)NULL);
		JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(userobj));
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(i));
static JSBool
js_del_user(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	jsrefcount	rc;
	int32		n;
	user_t		user;

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	if(!JS_ValueToInt32(cx,argv[0],&n))
		return(JS_FALSE);
	user.number=n;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);	/* fail, by default */
		&& putusermisc(sys->cfg, n, user.misc | DELETED)==0
		JS_SET_RVAL(cx, arglist, JSVAL_TRUE);	/* success */
js_sys_exec(JSContext *cx, uintN argc, jsval *arglist)
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	jsrefcount	rc;
deuce's avatar
deuce committed
	int		ret;
deuce's avatar
deuce committed
	JSVALUE_TO_MSTRING(cx, argv[0], cmd, NULL);
	HANDLE_PENDING(cx, cmd);
deuce's avatar
deuce committed
	if(cmd==NULL) {
		JS_ReportError(cx, "Illegal NULL command");
		return JS_FALSE;
	}
	if(*cmd == 0) {
		free(cmd);
		JS_ReportError(cx, "Missing or invalid argument");
		return JS_FALSE;
	}
deuce's avatar
deuce committed
	ret=system(cmd);
	free(cmd);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(ret));
js_popen(JSContext *cx, uintN argc, jsval *arglist)
	jsval *argv=JS_ARGV(cx, arglist);
	FILE*		fp;
	jsint		line=0;
	jsval		val;
	JSObject*	array;
	JSString*	js_str;
deuce's avatar
deuce committed
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

 	if(!js_argc(cx, argc, 1))
		return JS_FALSE;
	if(JSVAL_NULL_OR_VOID(argv[0])) {
		JS_ReportError(cx, "Invalid argument");
		return JS_FALSE;
	}
	if((array=JS_NewArrayObject(cx,0,NULL))==NULL)
		return(JS_FALSE);

deuce's avatar
deuce committed
	JSVALUE_TO_MSTRING(cx, argv[0], cmd, NULL);
	HANDLE_PENDING(cx, cmd);
deuce's avatar
deuce committed
	if(cmd==NULL) {
		JS_ReportError(cx, "Illegal NULL command");
		return JS_FALSE;
	}
deuce's avatar
deuce committed
	if((fp=popen(cmd,"r"))==NULL) {
deuce's avatar
deuce committed
		free(cmd);
deuce's avatar
deuce committed
	free(cmd);
	while(!feof(fp)) {
		if(fgets(str,sizeof(str),fp)==NULL)
			break;
deuce's avatar
deuce committed
		if((js_str=JS_NewStringCopyZ(cx,str))==NULL) {
		val=STRING_TO_JSVAL(js_str);
deuce's avatar
deuce committed
        if(!JS_SetElement(cx, array, line++, &val)) {
    JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
js_chksyspass(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	char		*pass;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
deuce's avatar
deuce committed
	JSVALUE_TO_ASTRING(cx, argv[0], pass, LEN_PASS+2, NULL); // +2 is so overly long passwords fail.
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(stricmp(pass,sys->cfg->sys_pass)==0));
js_chkname(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
deuce's avatar
deuce committed
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);