--- sbbs/src/sbbs3/js_system.c 2018/04/24 16:41:24 1.1 +++ sbbs/src/sbbs3/js_system.c 2018/04/24 16:43:55 1.1.1.2 @@ -2,13 +2,13 @@ /* Synchronet JavaScript "system" Object */ -/* $Id: js_system.c,v 1.1 2018/04/24 16:41:24 root Exp $ */ +/* $Id: js_system.c,v 1.1.1.2 2018/04/24 16:43:55 root Exp $ */ /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -36,6 +36,7 @@ ****************************************************************************/ #include "sbbs.h" +#include "js_request.h" #ifdef JAVASCRIPT @@ -119,6 +120,7 @@ static JSBool js_system_get(JSContext *c JSString* js_str; ulong val; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -174,10 +176,12 @@ static JSBool js_system_get(JSContext *c break; case SYS_PROP_FREEDISKSPACE: case SYS_PROP_FREEDISKSPACEK: + rc=JS_SUSPENDREQUEST(cx); if(tiny==SYS_PROP_FREEDISKSPACE) val = getfreediskspace(cfg->temp_dir,0); else val = getfreediskspace(cfg->temp_dir,1024); + JS_RESUMEREQUEST(cx, rc); JS_NewNumberValue(cx,val,vp); break; @@ -215,7 +219,8 @@ static JSBool js_system_get(JSContext *c JS_NewNumberValue(cx,cfg->new_min,vp); break; case SYS_PROP_NEW_SHELL: - *vp = INT_TO_JSVAL(cfg->new_shell); + if(cfg->new_shelltotal_shells) + p=cfg->shell[cfg->new_shell]->code; break; case SYS_PROP_NEW_XEDIT: p=cfg->new_xedit; @@ -288,7 +293,9 @@ static JSBool js_system_get(JSContext *c break; case SYS_PROP_CMD_SHELL: + rc=JS_SUSPENDREQUEST(cx); p=os_cmdshell(); + JS_RESUMEREQUEST(cx, rc); break; case SYS_PROP_CLOCK: @@ -302,7 +309,9 @@ static JSBool js_system_get(JSContext *c break; case SYS_PROP_LOCAL_HOSTNAME: + rc=JS_SUSPENDREQUEST(cx); gethostname(str,sizeof(str)); + JS_RESUMEREQUEST(cx, rc); p=str; break; } @@ -494,6 +503,7 @@ static char* sys_prop_desc[] = { ,"Synchronet version number in decimal (e.g. 31301 for v3.13b)" ,"Synchronet version number in hexadecimal (e.g. 0x31301 for v3.13b)" ,"platform description (e.g. 'Win32', 'Linux', 'FreeBSD')" + ,"architecture description (e.g. 'i386', 'i686', 'x86_64')" ,"socket library version information" ,"message base library version information" ,"compiler used to build Synchronet" @@ -509,19 +519,6 @@ static char* sys_prop_desc[] = { #endif -static JSClass js_system_class = { - "System" /* name */ - ,JSCLASS_HAS_PRIVATE /* flags */ - ,JS_PropertyStub /* addProperty */ - ,JS_PropertyStub /* delProperty */ - ,js_system_get /* getProperty */ - ,js_system_set /* setProperty */ - ,JS_EnumerateStub /* enumerate */ - ,JS_ResolveStub /* resolve */ - ,JS_ConvertStub /* convert */ - ,JS_FinalizeStub /* finalize */ -}; - /* System Stats Propertiess */ enum { SYSSTAT_PROP_LOGONS @@ -551,14 +548,19 @@ static JSBool js_sysstats_get(JSContext stats_t stats; uint i; ulong l; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); tiny = JSVAL_TO_INT(id); - if(!getstats(cfg, 0, &stats)) + rc=JS_SUSPENDREQUEST(cx); + if(!getstats(cfg, 0, &stats)) { + JS_RESUMEREQUEST(cx, rc); return(FALSE); + } + JS_RESUMEREQUEST(cx, rc); switch(tiny) { case SYSSTAT_PROP_LOGONS: @@ -599,25 +601,35 @@ static JSBool js_sysstats_get(JSContext break; case SYSSTAT_PROP_TOTALUSERS: + rc=JS_SUSPENDREQUEST(cx); *vp = INT_TO_JSVAL(total_users(cfg)); + JS_RESUMEREQUEST(cx, rc); break; case SYSSTAT_PROP_TOTALMSGS: l=0; + rc=JS_SUSPENDREQUEST(cx); for(i=0;itotal_subs;i++) l+=getposts(cfg,i); + JS_RESUMEREQUEST(cx, rc); JS_NewNumberValue(cx,l,vp); break; case SYSSTAT_PROP_TOTALFILES: l=0; + rc=JS_SUSPENDREQUEST(cx); for(i=0;itotal_dirs;i++) l+=getfiles(cfg,i); + JS_RESUMEREQUEST(cx, rc); JS_NewNumberValue(cx,l,vp); break; case SYSSTAT_PROP_TOTALMAIL: + rc=JS_SUSPENDREQUEST(cx); *vp = INT_TO_JSVAL(getmail(cfg, 0,0)); + JS_RESUMEREQUEST(cx, rc); break; case SYSSTAT_PROP_FEEDBACK: + rc=JS_SUSPENDREQUEST(cx); *vp = INT_TO_JSVAL(getmail(cfg, 1,0)); + JS_RESUMEREQUEST(cx, rc); break; } @@ -672,6 +684,20 @@ static char* sysstat_prop_desc[] = { }; #endif +static JSBool js_sysstats_resolve(JSContext *cx, JSObject *obj, jsval id) +{ + char* name=NULL; + + if(id != JSVAL_NULL) + name=JS_GetStringBytes(JSVAL_TO_STRING(id)); + + return(js_SyncResolve(cx, obj, name, js_sysstats_properties, NULL, NULL, 0)); +} + +static JSBool js_sysstats_enumerate(JSContext *cx, JSObject *obj) +{ + return(js_sysstats_resolve(cx, obj, JSVAL_NULL)); +} static JSClass js_sysstats_class = { "Stats" /* name */ @@ -680,8 +706,8 @@ static JSClass js_sysstats_class = { ,JS_PropertyStub /* delProperty */ ,js_sysstats_get /* getProperty */ ,JS_PropertyStub /* setProperty */ - ,JS_EnumerateStub /* enumerate */ - ,JS_ResolveStub /* resolve */ + ,js_sysstats_enumerate /* enumerate */ + ,js_sysstats_resolve /* resolve */ ,JS_ConvertStub /* convert */ ,JS_FinalizeStub /* finalize */ }; @@ -693,6 +719,7 @@ js_alias(JSContext *cx, JSObject *obj, u char buf[128]; JSString* js_str; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -707,7 +734,9 @@ js_alias(JSContext *cx, JSObject *obj, u return(JS_TRUE); } + rc=JS_SUSPENDREQUEST(cx); p=alias(cfg,p,buf); + JS_RESUMEREQUEST(cx, rc); if((js_str = JS_NewStringCopyZ(cx, p))==NULL) return(JS_FALSE); @@ -723,6 +752,8 @@ js_username(JSContext *cx, JSObject *obj char buf[128]; JSString* js_str; scfg_t* cfg; + char* cstr; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -730,14 +761,16 @@ js_username(JSContext *cx, JSObject *obj val=0; JS_ValueToInt32(cx,argv[0],&val); - if((js_str = JS_NewStringCopyZ(cx, username(cfg,val,buf)))==NULL) + rc=JS_SUSPENDREQUEST(cx); + cstr=username(cfg,val,buf); + JS_RESUMEREQUEST(cx, rc); + if((js_str = JS_NewStringCopyZ(cx, cstr))==NULL) return(JS_FALSE); *rval = STRING_TO_JSVAL(js_str); return(JS_TRUE); } - static JSBool js_matchuser(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -745,6 +778,7 @@ js_matchuser(JSContext *cx, JSObject *ob JSString* js_str; scfg_t* cfg; BOOL sysop_alias=TRUE; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -762,7 +796,9 @@ js_matchuser(JSContext *cx, JSObject *ob return(JS_TRUE); } + rc=JS_SUSPENDREQUEST(cx); *rval = INT_TO_JSVAL(matchuser(cfg,p,sysop_alias)); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -775,28 +811,40 @@ js_matchuserdata(JSContext *cx, JSObject int32 usernumber=0; int len; scfg_t* cfg; + jsrefcount rc; + BOOL match_next=FALSE; + int argnum=2; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); JS_ValueToInt32(cx,argv[0],&offset); - if((len=user_rec_len(offset))<0) + rc=JS_SUSPENDREQUEST(cx); + len=user_rec_len(offset); + JS_RESUMEREQUEST(cx, rc); + if(len<0) { + JS_ReportError(cx,"Invalid user data offset: %d", offset); return(JS_FALSE); + } if((js_str=JS_ValueToString(cx, argv[1]))==NULL) { *rval = INT_TO_JSVAL(0); return(JS_TRUE); } - if(argc>2) - JS_ValueToInt32(cx,argv[2],&usernumber); - + 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); + if((p=JS_GetStringBytes(js_str))==NULL) { *rval = INT_TO_JSVAL(0); return(JS_TRUE); } - - *rval = INT_TO_JSVAL(userdatdupe(cfg,usernumber,offset,len,p,FALSE /* deleted users */)); + + rc=JS_SUSPENDREQUEST(cx); + *rval = INT_TO_JSVAL(userdatdupe(cfg,usernumber,offset,len,p,FALSE,match_next)); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -808,6 +856,7 @@ js_trashcan(JSContext *cx, JSObject *obj JSString* js_str; JSString* js_can; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -832,7 +881,9 @@ js_trashcan(JSContext *cx, JSObject *obj return(JS_TRUE); } + rc=JS_SUSPENDREQUEST(cx); *rval = BOOLEAN_TO_JSVAL(trashcan(cfg,str,can)); /* user args are reversed */ + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -843,6 +894,7 @@ js_findstr(JSContext *cx, JSObject *obj, char* fname; JSString* js_str; JSString* js_fname; + jsrefcount rc; if((js_fname=JS_ValueToString(cx, argv[0]))==NULL) { *rval = BOOLEAN_TO_JSVAL(JS_FALSE); @@ -864,11 +916,12 @@ js_findstr(JSContext *cx, JSObject *obj, return(JS_TRUE); } + rc=JS_SUSPENDREQUEST(cx); *rval = BOOLEAN_TO_JSVAL(findstr(str,fname)); /* user args are reversed */ + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } - static JSBool js_zonestr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -876,6 +929,8 @@ js_zonestr(JSContext *cx, JSObject *obj, short zone; int32 val=0; scfg_t* cfg; + jsrefcount rc; + char* cstr; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -887,7 +942,10 @@ js_zonestr(JSContext *cx, JSObject *obj, zone=(short)val; } - if((js_str = JS_NewStringCopyZ(cx, smb_zonestr(zone,NULL)))==NULL) + rc=JS_SUSPENDREQUEST(cx); + cstr=smb_zonestr(zone,NULL); + JS_RESUMEREQUEST(cx, rc); + if((js_str = JS_NewStringCopyZ(cx, cstr))==NULL) return(JS_FALSE); *rval = STRING_TO_JSVAL(js_str); @@ -903,6 +961,7 @@ js_timestr(JSContext *cx, JSObject *obj, time_t t; JSString* js_str; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -912,7 +971,9 @@ js_timestr(JSContext *cx, JSObject *obj, else JS_ValueToInt32(cx,argv[0],&i); t=i; - timestr(cfg,&t,str); + rc=JS_SUSPENDREQUEST(cx); + timestr(cfg,t,str); + JS_RESUMEREQUEST(cx, rc); if((js_str = JS_NewStringCopyZ(cx, str))==NULL) return(JS_FALSE); @@ -920,7 +981,6 @@ js_timestr(JSContext *cx, JSObject *obj, return(JS_TRUE); } - /* Returns a mm/dd/yy or dd/mm/yy formated string */ static JSBool js_datestr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) @@ -937,8 +997,7 @@ js_datestr(JSContext *cx, JSObject *obj, t=time(NULL); /* use current time */ else { if(JSVAL_IS_STRING(argv[0])) { /* convert from string to time_t? */ - *rval = INT_TO_JSVAL( - dstrtounix(cfg,JS_GetStringBytes(JS_ValueToString(cx, argv[0])))); + JS_NewNumberValue(cx,dstrtounix(cfg,JS_GetStringBytes(JS_ValueToString(cx, argv[0]))),rval); return(JS_TRUE); } JS_ValueToInt32(cx,argv[0],(int32*)&t); @@ -985,6 +1044,7 @@ js_spamlog(JSContext *cx, JSObject *obj, char* to=NULL; char* from=NULL; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -1010,7 +1070,9 @@ js_spamlog(JSContext *cx, JSObject *obj, else if(from==NULL) from=p; } + rc=JS_SUSPENDREQUEST(cx); *rval = BOOLEAN_TO_JSVAL(spamlog(cfg,prot,action,reason,host,ip_addr,to,from)); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1026,6 +1088,7 @@ js_hacklog(JSContext *cx, JSObject *obj, char* host=NULL; SOCKADDR_IN addr; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -1054,7 +1117,9 @@ js_hacklog(JSContext *cx, JSObject *obj, else if(host==NULL) host=p; } + rc=JS_SUSPENDREQUEST(cx); *rval = BOOLEAN_TO_JSVAL(hacklog(cfg,prot,user,text,host,&addr)); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1070,6 +1135,7 @@ js_filter_ip(JSContext *cx, JSObject *ob char* from=NULL; char* fname=NULL; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -1093,7 +1159,9 @@ js_filter_ip(JSContext *cx, JSObject *ob else if(fname==NULL) fname=p; } + rc=JS_SUSPENDREQUEST(cx); *rval = BOOLEAN_TO_JSVAL(filter_ip(cfg,prot,reason,host,ip_addr,from,fname)); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1104,6 +1172,7 @@ js_get_node_message(JSContext *cx, JSObj int32 node_num; JSString* js_str; scfg_t* cfg; + jsrefcount rc; *rval = JSVAL_NULL; @@ -1116,7 +1185,10 @@ js_get_node_message(JSContext *cx, JSObj if(node_num<1) node_num=1; - if((buf=getnmsg(cfg,node_num))==NULL) + rc=JS_SUSPENDREQUEST(cx); + buf=getnmsg(cfg,node_num); + JS_RESUMEREQUEST(cx, rc); + if(buf==NULL) return(JS_TRUE); js_str=JS_NewStringCopyZ(cx, buf); @@ -1128,7 +1200,6 @@ js_get_node_message(JSContext *cx, JSObj return(JS_TRUE); } - static JSBool js_put_node_message(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -1136,6 +1207,7 @@ js_put_node_message(JSContext *cx, JSObj JSString* js_msg; char* msg; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -1150,7 +1222,9 @@ js_put_node_message(JSContext *cx, JSObj if((msg=JS_GetStringBytes(js_msg))==NULL) return(JS_FALSE); + rc=JS_SUSPENDREQUEST(cx); *rval = BOOLEAN_TO_JSVAL(putnmsg(cfg,node,msg)==0); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1162,6 +1236,7 @@ js_get_telegram(JSContext *cx, JSObject int32 usernumber=1; JSString* js_str; scfg_t* cfg; + jsrefcount rc; *rval = JSVAL_NULL; @@ -1172,7 +1247,10 @@ js_get_telegram(JSContext *cx, JSObject if(usernumber<1) usernumber=1; - if((buf=getsmsg(cfg,usernumber))==NULL) + rc=JS_SUSPENDREQUEST(cx); + buf=getsmsg(cfg,usernumber); + JS_RESUMEREQUEST(cx, rc); + if(buf==NULL) return(JS_TRUE); js_str=JS_NewStringCopyZ(cx, buf); @@ -1191,6 +1269,7 @@ js_put_telegram(JSContext *cx, JSObject JSString* js_msg; char* msg; scfg_t* cfg; + jsrefcount rc; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); @@ -1205,7 +1284,9 @@ js_put_telegram(JSContext *cx, JSObject if((msg=JS_GetStringBytes(js_msg))==NULL) return(JS_FALSE); + rc=JS_SUSPENDREQUEST(cx); *rval = BOOLEAN_TO_JSVAL(putsmsg(cfg,usernumber,msg)==0); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1215,16 +1296,41 @@ js_new_user(JSContext *cx, JSObject *obj { char* alias; int i; + uintN n; scfg_t* cfg; user_t user; JSObject* userobj; + jsrefcount rc; + client_t* client=NULL; if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) return(JS_FALSE); alias=JS_GetStringBytes(JS_ValueToString(cx,argv[0])); + rc=JS_SUSPENDREQUEST(cx); + if(!check_name(cfg,alias)) { + JS_RESUMEREQUEST(cx, rc); + JS_ReportError(cx,"Invalid or duplicate user alias: %s", alias); + return JS_FALSE; + } + memset(&user,0,sizeof(user)); + for(n=0;nname,"Client")==0) { + client=JS_GetPrivate(cx,objarg); + continue; + } + } + } + if(client!=NULL) { + SAFECOPY(user.modem,client->protocol); + SAFECOPY(user.comp,client->host); + SAFECOPY(user.note,client->addr); + } user.sex=' '; SAFECOPY(user.alias,alias); @@ -1261,15 +1367,16 @@ js_new_user(JSContext *cx, JSObject *obj user.qwk=QWK_DEFAULT; for(i=0;itotal_xedits;i++) - if(!stricmp(cfg->xedit[i]->code,cfg->new_xedit) && chk_ar(cfg,cfg->xedit[i]->ar,&user)) + if(!stricmp(cfg->xedit[i]->code,cfg->new_xedit) && chk_ar(cfg,cfg->xedit[i]->ar,&user,/* client: */NULL)) break; if(itotal_xedits) user.xedit=i+1; i=newuserdat(cfg,&user); + JS_RESUMEREQUEST(cx, rc); if(i==0) { - userobj=js_CreateUserObject(cx, obj, cfg, NULL, user.number); + userobj=js_CreateUserObject(cx, obj, cfg, NULL, &user, /* client: */NULL, /* global_user: */FALSE); *rval = OBJECT_TO_JSVAL(userobj); } else *rval = INT_TO_JSVAL(i); @@ -1280,7 +1387,11 @@ js_new_user(JSContext *cx, JSObject *obj static JSBool js_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { + jsrefcount rc; + + rc=JS_SUSPENDREQUEST(cx); *rval = INT_TO_JSVAL(system(JS_GetStringBytes(JS_ValueToString(cx, argv[0])))); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1295,6 +1406,7 @@ js_popen(JSContext *cx, JSObject *obj, u jsval val; JSObject* array; JSString* js_str; + jsrefcount rc; if(argc<1) return(JS_TRUE); @@ -1303,18 +1415,28 @@ js_popen(JSContext *cx, JSObject *obj, u return(JS_FALSE); cmd=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); - if((fp=popen(cmd,"r"))==NULL) + rc=JS_SUSPENDREQUEST(cx); + if((fp=popen(cmd,"r"))==NULL) { + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); + } while(!feof(fp)) { if(fgets(str,sizeof(str),fp)==NULL) break; - if((js_str=JS_NewStringCopyZ(cx,str))==NULL) + JS_RESUMEREQUEST(cx, rc); + if((js_str=JS_NewStringCopyZ(cx,str))==NULL) { + rc=JS_SUSPENDREQUEST(cx); break; + } val=STRING_TO_JSVAL(js_str); - if(!JS_SetElement(cx, array, line++, &val)) + if(!JS_SetElement(cx, array, line++, &val)) { + rc=JS_SUSPENDREQUEST(cx); break; + } + rc=JS_SUSPENDREQUEST(cx); } pclose(fp); + JS_RESUMEREQUEST(cx, rc); *rval = OBJECT_TO_JSVAL(array); @@ -1335,6 +1457,63 @@ js_chksyspass(JSContext *cx, JSObject *o return(JS_TRUE); } +static JSBool +js_chkname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char* str; + scfg_t* cfg; + jsrefcount rc; + + str = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); + if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) + return(JS_FALSE); + + rc=JS_SUSPENDREQUEST(cx); + *rval = BOOLEAN_TO_JSVAL(check_name(cfg,str)); + JS_RESUMEREQUEST(cx, rc); + + return(JS_TRUE); +} + +static JSBool +js_chkpid(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + int32 pid=0; + jsrefcount rc; + + *rval = JSVAL_FALSE; + + if(argc<1) + return(JS_TRUE); + + JS_ValueToInt32(cx,argv[0],&pid); + + rc=JS_SUSPENDREQUEST(cx); + *rval = BOOLEAN_TO_JSVAL(check_pid(pid)); + JS_RESUMEREQUEST(cx, rc); + + return(JS_TRUE); +} + +static JSBool +js_killpid(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + int32 pid=0; + jsrefcount rc; + + *rval = JSVAL_FALSE; + + if(argc<1) + return(JS_TRUE); + + JS_ValueToInt32(cx,argv[0],&pid); + + rc=JS_SUSPENDREQUEST(cx); + *rval = BOOLEAN_TO_JSVAL(terminate_pid(pid)); + JS_RESUMEREQUEST(cx, rc); + + return(JS_TRUE); +} static jsSyncMethodSpec js_system_functions[] = { @@ -1351,13 +1530,14 @@ static jsSyncMethodSpec js_system_functi " or 0 if not found, matches well-known sysop aliases by default") ,310 }, - {"matchuserdata", js_matchuserdata, 2, JSTYPE_NUMBER, JSDOCSTR("field, data [,usernumber]") - ,JSDOCSTR("search user database for data in a specific field (specified by offset), " - "returns first matching user record number, optional usernumber specifies user record to skip") + {"matchuserdata", js_matchuserdata, 2, JSTYPE_NUMBER, JSDOCSTR("field, data [,usernumber, match_next=false]") + ,JSDOCSTR("search user database for data in a specific field (see U_* in sbbsdefs.js), " + "returns first matching user record number, optional usernumber specifies user record to skip, " + "or record at which to begin searching if optional match_next is true") ,310 }, - {"trashcan", js_trashcan, 2, JSTYPE_BOOLEAN, JSDOCSTR("path/filename, find_string") - ,JSDOCSTR("search text/filename.can for pseudo-regexp") + {"trashcan", js_trashcan, 2, JSTYPE_BOOLEAN, JSDOCSTR("basename, find_string") + ,JSDOCSTR("search text/basename.can for pseudo-regexp") ,310 }, {"findstr", js_findstr, 2, JSTYPE_BOOLEAN, JSDOCSTR("path/filename, find_string") @@ -1375,7 +1555,8 @@ static jsSyncMethodSpec js_system_functi }, {"datestr", js_datestr, 0, JSTYPE_STRING, JSDOCSTR("[time=current]") ,JSDOCSTR("convert time_t integer into a date string (in either MM/DD/YY or DD/MM/YY format), " - "defaults to current date if time not specified") + "defaults to current date if time not specified. " + "If time is a string in the appropriate format, returns the time_t.") ,310 }, {"secondstr", js_secondstr, 0, JSTYPE_STRING, JSDOCSTR("seconds") @@ -1411,8 +1592,9 @@ static jsSyncMethodSpec js_system_functi ,310 }, {"newuser", js_new_user, 1, JSTYPE_ALIAS }, - {"new_user", js_new_user, 1, JSTYPE_OBJECT, JSDOCSTR("name/alias") - ,JSDOCSTR("creates a new user record, returns a new User object representing the new user account") + {"new_user", js_new_user, 1, JSTYPE_OBJECT, JSDOCSTR("name/alias [,client object]") + ,JSDOCSTR("creates a new user record, returns a new User object representing the new user account, on success.
" + "returns an numeric error code on failure (optional client object argument added in v3.15a)") ,310 }, {"exec", js_exec, 1, JSTYPE_NUMBER, JSDOCSTR("command-line") @@ -1425,9 +1607,24 @@ static jsSyncMethodSpec js_system_functi ,311 }, {"check_syspass", js_chksyspass, 1, JSTYPE_BOOLEAN, JSDOCSTR("password") - ,JSDOCSTR("compares the supplied password against the system password and return's true if it matches") + ,JSDOCSTR("compares the supplied password against the system password and returns true if it matches") ,311 }, + {"check_name", js_chkname, 1, JSTYPE_BOOLEAN, JSDOCSTR("name/alias") + ,JSDOCSTR("checks that the provided name/alias string is suitable for a new user account, " + "returns true if it is valid") + ,315 + }, + {"check_pid", js_chkpid, 1, JSTYPE_BOOLEAN, JSDOCSTR("process-ID") + ,JSDOCSTR("checks that the provided process ID is a valid executing process on the system, " + "returns true if it is valid") + ,315 + }, + {"terminate_pid", js_killpid, 1, JSTYPE_BOOLEAN, JSDOCSTR("process-ID") + ,JSDOCSTR("terminates executing process on the system with the specified process ID, " + "returns true on success") + ,315 + }, {0} }; @@ -1443,6 +1640,7 @@ enum { ,NODE_PROP_MISC ,NODE_PROP_AUX ,NODE_PROP_EXTAUX + ,NODE_PROP_DIR }; #ifdef BUILD_JSDOCS @@ -1455,6 +1653,7 @@ static char* node_prop_desc[] = { ,"miscellaneous bitfield (see nodedefs.js)" ,"auxillary value" ,"extended auxillary value" + ,"node directory" ,NULL }; #endif @@ -1468,6 +1667,8 @@ static JSBool js_node_get(JSContext *cx, scfg_t* cfg; JSObject* sysobj; JSObject* node_list; + jsrefcount rc; + JSString* js_str; tiny = JSVAL_TO_INT(id); @@ -1482,9 +1683,13 @@ static JSBool js_node_get(JSContext *cx, node_num=(uint)JS_GetPrivate(cx,obj)>>1; + rc=JS_SUSPENDREQUEST(cx); memset(&node,0,sizeof(node)); - if(getnodedat(cfg, node_num, &node, NULL)) + if(getnodedat(cfg, node_num, &node, NULL)) { + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); + } + JS_RESUMEREQUEST(cx, rc); switch(tiny) { case NODE_PROP_STATUS: @@ -1511,6 +1716,11 @@ static JSBool js_node_get(JSContext *cx, case NODE_PROP_EXTAUX: JS_NewNumberValue(cx,node.extaux,vp); break; + case NODE_PROP_DIR: + if((js_str=JS_NewStringCopyZ(cx, cfg->node_path[node_num-1]))==NULL) + return(JS_FALSE); + *vp = STRING_TO_JSVAL(js_str); + break; } return(JS_TRUE); } @@ -1525,6 +1735,7 @@ static JSBool js_node_set(JSContext *cx, scfg_t* cfg; JSObject* sysobj; JSObject* node_list; + jsrefcount rc; if((node_list=JS_GetParent(cx, obj))==NULL) return(JS_FALSE); @@ -1537,14 +1748,19 @@ static JSBool js_node_set(JSContext *cx, node_num=(uint)JS_GetPrivate(cx,obj)>>1; + rc=JS_SUSPENDREQUEST(cx); memset(&node,0,sizeof(node)); - if(getnodedat(cfg, node_num, &node, &file)) + if(getnodedat(cfg, node_num, &node, &file)) { + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); + } + JS_RESUMEREQUEST(cx, rc); if(JSVAL_IS_NUMBER(*vp)) JS_ValueToInt32(cx, *vp, &val); tiny = JSVAL_TO_INT(id); + rc=JS_SUSPENDREQUEST(cx); switch(tiny) { case NODE_PROP_STATUS: @@ -1573,6 +1789,7 @@ static JSBool js_node_set(JSContext *cx, break; } putnodedat(cfg,node_num,&node,file); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1589,9 +1806,25 @@ static jsSyncPropertySpec js_node_proper { "misc", NODE_PROP_MISC, JSPROP_ENUMERATE, 310 }, { "aux", NODE_PROP_AUX, JSPROP_ENUMERATE, 310 }, { "extaux", NODE_PROP_EXTAUX, JSPROP_ENUMERATE, 310 }, + { "dir", NODE_PROP_DIR, JSPROP_ENUMERATE|JSPROP_READONLY, 315 }, {0} }; +static JSBool js_node_resolve(JSContext *cx, JSObject *obj, jsval id) +{ + char* name=NULL; + + if(id != JSVAL_NULL) + name=JS_GetStringBytes(JSVAL_TO_STRING(id)); + + return(js_SyncResolve(cx, obj, name, js_node_properties, NULL, NULL, 0)); +} + +static JSBool js_node_enumerate(JSContext *cx, JSObject *obj) +{ + return(js_node_resolve(cx, obj, JSVAL_NULL)); +} + static JSClass js_node_class = { "Node" /* name */ ,JSCLASS_HAS_PRIVATE /* flags */ @@ -1599,226 +1832,245 @@ static JSClass js_node_class = { ,JS_PropertyStub /* delProperty */ ,js_node_get /* getProperty */ ,js_node_set /* setProperty */ - ,JS_EnumerateStub /* enumerate */ - ,JS_ResolveStub /* resolve */ + ,js_node_enumerate /* enumerate */ + ,js_node_resolve /* resolve */ ,JS_ConvertStub /* convert */ ,JS_FinalizeStub /* finalize */ }; -JSObject* DLLCALL js_CreateSystemObject(JSContext* cx, JSObject* parent - ,scfg_t* cfg, time_t uptime, char* host_name, char* socklib_desc) +#define LAZY_INTEGER(PropName, PropValue) \ + if(name==NULL || strcmp(name, (PropName))==0) { \ + JS_NewNumberValue(cx,(PropValue),&val); \ + JS_DefineProperty(cx, obj, (PropName), val, NULL,NULL,JSPROP_ENUMERATE); \ + if(name) return(JS_TRUE); \ + } + +#define LAZY_STRING(PropName, PropValue) \ + if(name==NULL || strcmp(name, (PropName))==0) { \ + if((js_str=JS_NewStringCopyZ(cx, (PropValue)))!=NULL) { \ + JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, JSPROP_ENUMERATE); \ + if(name) return(JS_TRUE); \ + } \ + else if(name) return(JS_TRUE); \ + } + +#define LAZY_STRFUNC(PropName, Function, PropValue) \ + if(name==NULL || strcmp(name, (PropName))==0) { \ + Function; \ + if((js_str=JS_NewStringCopyZ(cx, (PropValue)))!=NULL) { \ + JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, JSPROP_ENUMERATE); \ + if(name) return(JS_TRUE); \ + } \ + else if(name) return(JS_TRUE); \ + } + +#define LAZY_STRFUNC_TRUNCSP(PropName, Function, PropValue) \ + if(name==NULL || strcmp(name, (PropName))==0) { \ + Function; \ + if((js_str=JS_NewStringCopyZ(cx, truncsp(PropValue)))!=NULL) { \ + JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, JSPROP_ENUMERATE); \ + if(name) return(JS_TRUE); \ + } \ + else if(name) return(JS_TRUE); \ + } + +static JSBool js_system_resolve(JSContext *cx, JSObject *obj, jsval id) { - char str[256]; - uint i; + char* name=NULL; jsval val; - JSObject* sysobj; - JSObject* statsobj; - JSObject* nodeobj; - JSObject* node_list; - JSObject* fido_addr_list; + char str[256]; JSString* js_str; + JSObject* newobj; + JSObject* nodeobj; + scfg_t* cfg; + uint i; - sysobj = JS_DefineObject(cx, parent, "system", &js_system_class, NULL - ,JSPROP_ENUMERATE|JSPROP_READONLY); - - if(sysobj==NULL) - return(NULL); - - if(!JS_SetPrivate(cx, sysobj, cfg)) /* Store a pointer to scfg_t */ - return(NULL); - - if(!js_DefineSyncProperties(cx, sysobj, js_system_properties)) - return(NULL); - - if (!js_DefineSyncMethods(cx, sysobj, js_system_functions, FALSE)) - return(NULL); - -#ifdef BUILD_JSDOCS - js_DescribeSyncObject(cx,sysobj,"Global system-related properties and methods",310); - js_CreateArrayOfStrings(cx, sysobj, "_property_desc_list", sys_prop_desc, JSPROP_READONLY); -#endif + if(id != JSVAL_NULL) + name=JS_GetStringBytes(JSVAL_TO_STRING(id)); /****************************/ /* static string properties */ - if((js_str=JS_NewStringCopyZ(cx, host_name))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "host_name", &val)) - return(NULL); - - if((js_str=JS_NewStringCopyZ(cx, VERSION))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "version", &val)) - return(NULL); - - sprintf(str,"%c",REVISION); - if((js_str=JS_NewStringCopyZ(cx, str))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "revision", &val)) - return(NULL); - - SAFECOPY(str,beta_version); - truncsp(str); - if((js_str=JS_NewStringCopyZ(cx, str))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "beta_version", &val)) - return(NULL); - - - sprintf(str,"%s%c%s",VERSION,REVISION,beta_version); - truncsp(str); + LAZY_STRING("version", VERSION); + LAZY_STRFUNC("revision", sprintf(str,"%c",REVISION), str); + LAZY_STRFUNC_TRUNCSP("beta_version", SAFECOPY(str, beta_version), str); + + if(name==NULL || strcmp(name, "full_version")==0) { + sprintf(str,"%s%c%s",VERSION,REVISION,beta_version); + truncsp(str); #if defined(_DEBUG) - strcat(str," Debug"); + strcat(str," Debug"); #endif - if((js_str=JS_NewStringCopyZ(cx, str))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "full_version", &val)) - return(NULL); + if((js_str=JS_NewStringCopyZ(cx, str))!=NULL) { + val = STRING_TO_JSVAL(js_str); + JS_SetProperty(cx, obj, "full_version", &val); + if(name) return(JS_TRUE); + } + else if(name) return(JS_TRUE); + } - if((js_str=JS_NewStringCopyZ(cx, VERSION_NOTICE))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "version_notice", &val)) - return(NULL); + LAZY_STRING("version_notice", VERSION_NOTICE); /* Numeric version properties */ - if(!JS_NewNumberValue(cx, VERSION_NUM, &val)) - return(NULL); - if(!JS_SetProperty(cx, sysobj, "version_num", &val)) - return(NULL); + LAZY_INTEGER("version_num", VERSION_NUM); + LAZY_INTEGER("version_hex", VERSION_HEX); - if(!JS_NewNumberValue(cx, VERSION_HEX, &val)) - return(NULL); - if(!JS_SetProperty(cx, sysobj, "version_hex", &val)) - return(NULL); + LAZY_STRING("platform", PLATFORM_DESC); + LAZY_STRING("architecture", ARCHITECTURE_DESC); + LAZY_STRFUNC("msgbase_lib", sprintf(str,"SMBLIB %s",smb_lib_ver()), str); + LAZY_STRFUNC("compiled_with", DESCRIBE_COMPILER(str), str); + LAZY_STRFUNC("compiled_when", sprintf(str,"%s %.5s",__DATE__,__TIME__), str); + LAZY_STRING("copyright", COPYRIGHT_NOTICE); + LAZY_STRING("js_version", (char *)JS_GetImplementationVersion()); + LAZY_STRING("os_version", os_version(str)); - if((js_str=JS_NewStringCopyZ(cx, PLATFORM_DESC))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "platform", &val)) - return(NULL); + /* fido_addr_list property */ + if(name==NULL || strcmp(name, "fido_addr_list")==0) { + if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) + return(JS_FALSE); - if((js_str=JS_NewStringCopyZ(cx, socklib_version(str, socklib_desc)))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "socket_lib", &val)) - return(NULL); + if((newobj=JS_NewArrayObject(cx, 0, NULL))==NULL) + return(JS_FALSE); - sprintf(str,"SMBLIB %s",smb_lib_ver()); - if((js_str=JS_NewStringCopyZ(cx, str))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "msgbase_lib", &val)) - return(NULL); + if(!JS_SetParent(cx, newobj, obj)) + return(JS_FALSE); - DESCRIBE_COMPILER(str); - if((js_str=JS_NewStringCopyZ(cx, str))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "compiled_with", &val)) - return(NULL); + if(!JS_DefineProperty(cx, obj, "fido_addr_list", OBJECT_TO_JSVAL(newobj) + , NULL, NULL, JSPROP_ENUMERATE)) + return(JS_FALSE); - sprintf(str,"%s %.5s",__DATE__,__TIME__); - if((js_str=JS_NewStringCopyZ(cx, str))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "compiled_when", &val)) - return(NULL); + for(i=0;itotal_faddrs;i++) { + val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,smb_faddrtoa(&cfg->faddr[i],str))); + JS_SetElement(cx, newobj, i, &val); + } + if(name) return(JS_TRUE); + } - if((js_str=JS_NewStringCopyZ(cx, COPYRIGHT_NOTICE))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "copyright", &val)) - return(NULL); + if(name==NULL || strcmp(name, "stats")==0) { + if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) + return(JS_FALSE); - if((js_str=JS_NewStringCopyZ(cx - ,(char *)JS_GetImplementationVersion()))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "js_version", &val)) - return(NULL); + newobj = JS_DefineObject(cx, obj, "stats", &js_sysstats_class, NULL + ,JSPROP_ENUMERATE|JSPROP_READONLY); - if((js_str=JS_NewStringCopyZ(cx,os_version(str)))==NULL) - return(NULL); - val = STRING_TO_JSVAL(js_str); - if(!JS_SetProperty(cx, sysobj, "os_version", &val)) - return(NULL); + if(newobj==NULL) + return(JS_FALSE); - /***********************/ + JS_SetPrivate(cx, newobj, cfg); /* Store a pointer to scfg_t */ + } - JS_NewNumberValue(cx,uptime,&val); - if(!JS_SetProperty(cx, sysobj, "uptime", &val)) - return(NULL); + /* node_list property */ + if(name==NULL || strcmp(name, "node_list")==0) { + if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) + return(JS_FALSE); - /* fido_addr_list property */ + if((newobj=JS_NewArrayObject(cx, 0, NULL))==NULL) + return(JS_FALSE); - if((fido_addr_list=JS_NewArrayObject(cx, 0, NULL))==NULL) - return(NULL); + if(!JS_SetParent(cx, newobj, obj)) + return(JS_FALSE); - if(!JS_DefineProperty(cx, sysobj, "fido_addr_list", OBJECT_TO_JSVAL(fido_addr_list) - , NULL, NULL, JSPROP_ENUMERATE)) - return(NULL); + if(!JS_DefineProperty(cx, obj, "node_list", OBJECT_TO_JSVAL(newobj) + , NULL, NULL, JSPROP_ENUMERATE)) + return(JS_FALSE); - for(i=0;itotal_faddrs;i++) { - val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,smb_faddrtoa(&cfg->faddr[i],str))); - JS_SetElement(cx, fido_addr_list, i, &val); + for(i=0;isys_nodes && isys_lastnode;i++) { + + nodeobj = JS_NewObject(cx, &js_node_class, NULL, newobj); + + if(nodeobj==NULL) + return(JS_FALSE); + + /* Store node number */ + /* We have to shift it to make it look like a pointer to JS. :-( */ + if(!JS_SetPrivate(cx, nodeobj, (char*)((i+1)<<1))) + return(JS_FALSE); + + #ifdef BUILD_JSDOCS + if(i==0) { + js_DescribeSyncObject(cx,nodeobj,"BBS node listing",310); + js_CreateArrayOfStrings(cx, nodeobj, "_property_desc_list", node_prop_desc, JSPROP_READONLY); + } + #endif + + val=OBJECT_TO_JSVAL(nodeobj); + if(!JS_SetElement(cx, newobj, i, &val)) + return(JS_FALSE); + } + if(name) return(JS_TRUE); } - statsobj = JS_DefineObject(cx, sysobj, "stats", &js_sysstats_class, NULL - ,JSPROP_ENUMERATE|JSPROP_READONLY); - if(statsobj==NULL) - return(NULL); + return(js_SyncResolve(cx, obj, name, js_system_properties, js_system_functions, NULL, 0)); +} - JS_SetPrivate(cx, statsobj, cfg); /* Store a pointer to scfg_t */ +static JSBool js_system_enumerate(JSContext *cx, JSObject *obj) +{ + return(js_node_resolve(cx, obj, JSVAL_NULL)); +} - if(!js_DefineSyncProperties(cx, statsobj, js_sysstats_properties)) - return(NULL); +static JSClass js_system_class = { + "System" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_system_get /* getProperty */ + ,js_system_set /* setProperty */ + ,js_system_enumerate /* enumerate */ + ,js_system_resolve /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; -#ifdef BUILD_JSDOCS - js_DescribeSyncObject(cx,statsobj,"System statistics",310); - js_CreateArrayOfStrings(cx, statsobj, "_property_desc_list", sysstat_prop_desc, JSPROP_READONLY); -#endif +JSObject* DLLCALL js_CreateSystemObject(JSContext* cx, JSObject* parent + ,scfg_t* cfg, time_t uptime, char* host_name, char* socklib_desc) +{ + jsval val; + JSObject* sysobj; + JSString* js_str; + char str[256]; - /* node_list property */ + sysobj = JS_DefineObject(cx, parent, "system", &js_system_class, NULL + ,JSPROP_ENUMERATE|JSPROP_READONLY); - if((node_list=JS_NewArrayObject(cx, 0, NULL))==NULL) + if(sysobj==NULL) return(NULL); - if(!JS_DefineProperty(cx, sysobj, "node_list", OBJECT_TO_JSVAL(node_list) - , NULL, NULL, JSPROP_ENUMERATE)) + if(!JS_SetPrivate(cx, sysobj, cfg)) /* Store a pointer to scfg_t */ return(NULL); - for(i=0;isys_nodes && isys_lastnode;i++) { - - nodeobj = JS_NewObject(cx, &js_node_class, NULL, node_list); + /****************************/ + /* static string properties */ + if((js_str=JS_NewStringCopyZ(cx, host_name))==NULL) + return(NULL); + val = STRING_TO_JSVAL(js_str); + if(!JS_SetProperty(cx, sysobj, "host_name", &val)) + return(NULL); - if(nodeobj==NULL) - return(NULL); + if((js_str=JS_NewStringCopyZ(cx, socklib_version(str, socklib_desc)))==NULL) + return(NULL); + val = STRING_TO_JSVAL(js_str); + if(!JS_SetProperty(cx, sysobj, "socket_lib", &val)) + return(NULL); - /* Store node number */ - /* We have to shift it to make it look like a pointer to JS. :-( */ - if(!JS_SetPrivate(cx, nodeobj, (char*)((i+1)<<1))) - return(NULL); + /***********************/ - if(!js_DefineSyncProperties(cx, nodeobj, js_node_properties)) - return(NULL); + JS_NewNumberValue(cx,uptime,&val); + if(!JS_SetProperty(cx, sysobj, "uptime", &val)) + return(NULL); #ifdef BUILD_JSDOCS - if(i==0) { - js_DescribeSyncObject(cx,nodeobj,"BBS node listing",310); - js_CreateArrayOfStrings(cx, nodeobj, "_property_desc_list", node_prop_desc, JSPROP_READONLY); - } + js_DescribeSyncObject(cx,sysobj,"Global system-related properties and methods",310); + js_CreateArrayOfStrings(cx, sysobj, "_property_desc_list", sys_prop_desc, JSPROP_READONLY); #endif - val=OBJECT_TO_JSVAL(nodeobj); - if(!JS_SetElement(cx, node_list, i, &val)) - return(NULL); - } +#ifdef BUILD_JSDOCS + { + JSObject* statsobj; + + js_DescribeSyncObject(cx,statsobj,"System statistics",310); + js_CreateArrayOfStrings(cx, statsobj, "_property_desc_list", sysstat_prop_desc, JSPROP_READONLY); + } +#endif return(sysobj); }