Skip to content
Snippets Groups Projects
js_system.c 67.8 KiB
Newer Older
deuce's avatar
deuce committed
	BOOL		ret;

	if((js_fname=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_fname, fname, NULL);
	HANDLE_PENDING(cx, fname);
deuce's avatar
deuce committed
	if(fname==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(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));
deuce's avatar
deuce committed
	ret = findstr(str,fname);
	free(str);
	free(fname);
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 */
		JS_ValueToNumber(cx,argv[0],&ti);
	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)));
	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);
	JS_ValueToInt32(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;i++) {
		if(!JSVAL_IS_STRING(argv[i]))
			continue;
deuce's avatar
deuce committed
		if(from==NULL) {
			JSVALUE_TO_MSTRING(cx, argv[i], p, NULL);
			if(JS_IsExceptionPending(cx)) {
				if(prot)
					free(prot);
				if(action)
					free(action);
				if(reason)
					free(reason);
				if(host)
					free(host);
				if(ip_addr)
					free(ip_addr);
				if(to)
					free(to);
				if(from)
					free(from);
				if(p)
					free(p);
deuce's avatar
deuce committed
				return JS_FALSE;
			}
			if(p==NULL)
				continue;
			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 if(from==NULL)
				from=p;
			else
				free(p);
	ret=spamlog(sys->cfg,prot,action,reason,host,ip_addr,to,from);
deuce's avatar
deuce committed
	if(prot)
		free(prot);
	if(action)
		free(action);
	if(reason)
		free(reason);
	if(host)
		free(host);
	if(ip_addr)
		free(ip_addr);
	if(to)
		free(to);
	if(from)
		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)) {
				if(prot)
					free(prot);
				if(user)
					free(user);
				if(text)
					free(text);
				if(host)
					free(host);
				if(p)
					free(p);
deuce's avatar
deuce committed
				return JS_FALSE;
			}
		}
		if(p==NULL)
			continue;
		if(prot==NULL)
			prot=p;
		else if(user==NULL)
			user=p;
		else if(text==NULL)
			text=p;
		else if(host==NULL)
			host=p;
	}
	ret=hacklog(sys->cfg,prot,user,text,host,&addr);
deuce's avatar
deuce committed
	if(prot)
		free(prot);
	if(user)
		free(user);
	if(text)
		free(text);
	if(host)
		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;i++) {
		if(!JSVAL_IS_STRING(argv[i]))
			continue;
deuce's avatar
deuce committed
		if(fname==NULL) {
			JSVALUE_TO_MSTRING(cx, argv[i], p, NULL);
			if(JS_IsExceptionPending(cx)) {
				if(prot)
					free(prot);
				if(reason)
					free(reason);
				if(host)
					free(host);
				if(ip_addr)
					free(ip_addr);
				if(from)
					free(from);
				if(fname)
					free(fname);
				if(p)
					free(p);
deuce's avatar
deuce committed
				return JS_FALSE;
			}
		}
		if(p==NULL)
			continue;
		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);
deuce's avatar
deuce committed
	if(prot)
		free(prot);
	if(reason)
		free(reason);
	if(host)
		free(host);
	if(ip_addr)
		free(ip_addr);
	if(from)
		free(from);
	if(fname)
		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) 
		JS_ValueToInt32(cx,argv[0],&node_num);
	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;

	node_num=cfg->node_num;
	if(argc) 
		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)
		node=1;

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

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) 
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)
		usernumber=1;

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

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) 
		return JS_FALSE;

	if(argc > 2) {
		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(argc<1 || JSVAL_NULL_OR_VOID(argv[0])) {
		JS_ReportError(cx,"Missing or 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((cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0) {
				client=JS_GetPrivate(cx,objarg);
				continue;
			}
		}
	}
	// 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((cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0)
				client=JS_GetPrivate(cx,objarg);
		}
	}
	if(client!=NULL) {
		SAFECOPY(user.modem,client->protocol);
		SAFECOPY(user.comp,client->host);
deuce's avatar
deuce committed
		SAFECOPY(user.ipaddr,client->addr);
	user.firston=user.laston=user.pwmod=time32(NULL);

	/* security */
	user.level=cfg->new_level;
	user.flags1=cfg->new_flags1;
	user.flags2=cfg->new_flags2;
	user.flags3=cfg->new_flags3;
	user.flags4=cfg->new_flags4;
	user.rest=cfg->new_rest;
	user.exempt=cfg->new_exempt;

	user.cdt=cfg->new_cdt;
	user.min=cfg->new_min;
	user.freecdt=cfg->level_freecdtperday[user.level];
	if(cfg->new_expire)
		user.expire=user.firston+((long)cfg->new_expire*24L*60L*60L);
	else
		user.expire=0;

	/* settings */
	if(cfg->total_fcomps)
		strcpy(user.tmpext,cfg->fcomp[0]->ext);
	else
		strcpy(user.tmpext,"ZIP");

	user.shell=cfg->new_shell;
	user.misc=cfg->new_misc|(AUTOTERM|COLOR);
	user.prot=cfg->new_prot;
rswindell's avatar
rswindell committed
		if(!stricmp(cfg->xedit[i]->code,cfg->new_xedit) && chk_ar(cfg,cfg->xedit[i]->ar,&user,/* client: */NULL))
		userobj=js_CreateUserObject(cx, obj, cfg, NULL, &user, /* client: */NULL, /* global_user: */FALSE);
		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;
	char		str[128];

	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 */
	if(getuserdat(sys->cfg, &user)==0
		&& putuserrec(sys->cfg,n,U_MISC,8,ultoa(user.misc|DELETED,str,16))==0
		&& putusername(sys->cfg,n,nulstr)==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(argc<1)
		return(JS_TRUE);

	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);

deuce's avatar
deuce committed
	JSVALUE_TO_ASTRING(cx, argv[0], str, (LEN_ALIAS > LEN_NAME)?LEN_ALIAS+2:LEN_NAME+2, NULL);

	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(check_name(sys->cfg,str)));
js_chkpid(JSContext *cx, uintN argc, jsval *arglist)
	jsval *argv=JS_ARGV(cx, arglist);
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);

	if(argc<1)
		return(JS_TRUE);

	JS_ValueToInt32(cx,argv[0],&pid);

	rc=JS_SUSPENDREQUEST(cx);
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(check_pid(pid)));
js_killpid(JSContext *cx, uintN argc, jsval *arglist)
	jsval *argv=JS_ARGV(cx, arglist);
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);

	if(argc<1)
		return(JS_TRUE);

	JS_ValueToInt32(cx,argv[0],&pid);

	rc=JS_SUSPENDREQUEST(cx);
	JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(terminate_pid(pid)));
static jsSyncMethodSpec js_system_functions[] = {
	{"username",		js_username,		1,	JSTYPE_STRING,	JSDOCSTR("user_number")
	,JSDOCSTR("returns name of user in specified user record <i>number</i>, or empty string if not found")
rswindell's avatar
rswindell committed
	{"alias",			js_alias,			1,	JSTYPE_STRING,	JSDOCSTR("alias")
	,JSDOCSTR("returns name of user that matches alias (if found in <tt>ctrl/alias.cfg</tt>)")
rswindell's avatar
rswindell committed
	{"matchuser",		js_matchuser,		1,	JSTYPE_NUMBER,	JSDOCSTR("username [,sysop_alias=<tt>true</tt>]")
	,JSDOCSTR("exact user name matching, returns number of user whose name/alias matches <i>username</i> "
		" or 0 if not found, matches well-known sysop aliases by default")
	{"matchuserdata",	js_matchuserdata,	2,	JSTYPE_NUMBER,	JSDOCSTR("field, data [,usernumber, match_next=<tt>false</tt>]")
	,JSDOCSTR("search user database for data in a specific field (see <tt>U_*</tt> in <tt>sbbsdefs.js</tt>), "
		"returns first matching user record number, optional <i>usernumber</i> specifies user record to skip, "
		"or record at which to begin searching if optional <i>match_next</i> is <tt>true</tt>")
	{"trashcan",		js_trashcan,		2,	JSTYPE_BOOLEAN,	JSDOCSTR("basename, find_string")
	,JSDOCSTR("search <tt>text/<i>basename</i>.can</tt> for pseudo-regexp")
rswindell's avatar
rswindell committed
	{"findstr",			js_findstr,			2,	JSTYPE_BOOLEAN,	JSDOCSTR("path/filename, find_string")
	,JSDOCSTR("search any file for pseudo-regexp")