diff --git a/src/sbbs3/js_user.c b/src/sbbs3/js_user.c index b74700c6924614063e0231aba4be6ed570bfabcf..8f0eb169d8212438cba43264e415e15c5ad4463c 100644 --- a/src/sbbs3/js_user.c +++ b/src/sbbs3/js_user.c @@ -45,7 +45,8 @@ static const char* getprivate_failure = "line %d %s JS_GetPrivate failed"; typedef struct { - uint usernumber; + user_t user; + BOOL cached; scfg_t* cfg; } private_t; @@ -122,8 +123,17 @@ enum { ,USER_PROP_EMAILPERDAY ,USER_PROP_POSTSPERDAY ,USER_PROP_FREECDTPERDAY + ,USER_PROP_CACHED }; +static void js_getuserdat(private_t* p) +{ + if(!p->cached) { + if(getuserdat(p->cfg,&p->user)==0) + p->cached=TRUE; + } +} + static JSBool js_user_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) { @@ -132,7 +142,6 @@ static JSBool js_user_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) ulong val=0; jsint tiny; JSString* js_str; - user_t user; private_t* p; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { @@ -140,230 +149,233 @@ static JSBool js_user_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) return(JS_FALSE); } - user.number=p->usernumber; - getuserdat(p->cfg,&user); + js_getuserdat(p); tiny = JSVAL_TO_INT(id); switch(tiny) { case USER_PROP_NUMBER: - val=user.number; + val=p->user.number; break; case USER_PROP_ALIAS: - s=user.alias; + s=p->user.alias; break; case USER_PROP_NAME: - s=user.name; + s=p->user.name; break; case USER_PROP_HANDLE: - s=user.handle; + s=p->user.handle; break; case USER_PROP_NOTE: - s=user.note; + s=p->user.note; break; case USER_PROP_COMP: - s=user.comp; + s=p->user.comp; break; case USER_PROP_COMMENT: - s=user.comment; + s=p->user.comment; break; case USER_PROP_NETMAIL: - s=user.netmail; + s=p->user.netmail; break; case USER_PROP_EMAIL: s=usermailaddr(p->cfg, tmp - ,p->cfg->inetmail_misc&NMAIL_ALIAS ? user.alias : user.name); + ,p->cfg->inetmail_misc&NMAIL_ALIAS ? p->user.alias : p->user.name); break; case USER_PROP_ADDRESS: - s=user.address; + s=p->user.address; break; case USER_PROP_LOCATION: - s=user.location; + s=p->user.location; break; case USER_PROP_ZIPCODE: - s=user.zipcode; + s=p->user.zipcode; break; case USER_PROP_PASS: - s=user.pass; + s=p->user.pass; break; case USER_PROP_PHONE: - s=user.phone; + s=p->user.phone; break; case USER_PROP_BIRTH: - s=user.birth; + s=p->user.birth; break; case USER_PROP_AGE: - val=getage(p->cfg,user.birth); + val=getage(p->cfg,p->user.birth); break; case USER_PROP_MODEM: - s=user.modem; + s=p->user.modem; break; case USER_PROP_LASTON: - val=user.laston; + val=p->user.laston; break; case USER_PROP_FIRSTON: - val=user.firston; + val=p->user.firston; break; case USER_PROP_EXPIRE: - val=user.expire; + val=p->user.expire; break; case USER_PROP_PWMOD: - val=user.pwmod; + val=p->user.pwmod; break; case USER_PROP_LOGONS: - val=user.logons; + val=p->user.logons; break; case USER_PROP_LTODAY: - val=user.ltoday; + val=p->user.ltoday; break; case USER_PROP_TIMEON: - val=user.timeon; + val=p->user.timeon; break; case USER_PROP_TEXTRA: - val=user.textra; + val=p->user.textra; break; case USER_PROP_TTODAY: - val=user.ttoday; + val=p->user.ttoday; break; case USER_PROP_TLAST: - val=user.tlast; + val=p->user.tlast; break; case USER_PROP_POSTS: - val=user.posts; + val=p->user.posts; break; case USER_PROP_EMAILS: - val=user.emails; + val=p->user.emails; break; case USER_PROP_FBACKS: - val=user.fbacks; + val=p->user.fbacks; break; case USER_PROP_ETODAY: - val=user.etoday; + val=p->user.etoday; break; case USER_PROP_PTODAY: - val=user.ptoday; + val=p->user.ptoday; break; case USER_PROP_ULB: - val=user.ulb; + val=p->user.ulb; break; case USER_PROP_ULS: - val=user.uls; + val=p->user.uls; break; case USER_PROP_DLB: - val=user.dlb; + val=p->user.dlb; break; case USER_PROP_DLS: - val=user.dls; + val=p->user.dls; break; case USER_PROP_CDT: - val=user.cdt; + val=p->user.cdt; break; case USER_PROP_MIN: - val=user.min; + val=p->user.min; break; case USER_PROP_LEVEL: - val=user.level; + val=p->user.level; break; case USER_PROP_FLAGS1: - val=user.flags1; + val=p->user.flags1; break; case USER_PROP_FLAGS2: - val=user.flags2; + val=p->user.flags2; break; case USER_PROP_FLAGS3: - val=user.flags3; + val=p->user.flags3; break; case USER_PROP_FLAGS4: - val=user.flags4; + val=p->user.flags4; break; case USER_PROP_EXEMPT: - val=user.exempt; + val=p->user.exempt; break; case USER_PROP_REST: - val=user.rest; + val=p->user.rest; break; case USER_PROP_ROWS: - val=user.rows; + val=p->user.rows; break; case USER_PROP_SEX: - sprintf(tmp,"%c",user.sex); + sprintf(tmp,"%c",p->user.sex); s=tmp; break; case USER_PROP_MISC: - val=user.misc; + val=p->user.misc; break; case USER_PROP_LEECH: - val=user.leech; + val=p->user.leech; break; case USER_PROP_CURSUB: - s=user.cursub; + s=p->user.cursub; break; case USER_PROP_CURDIR: - s=user.curdir; + s=p->user.curdir; break; case USER_PROP_CURXTRN: - s=user.curxtrn; + s=p->user.curxtrn; break; case USER_PROP_FREECDT: - val=user.freecdt; + val=p->user.freecdt; break; case USER_PROP_XEDIT: - if(user.xedit>0 && user.xedit<=p->cfg->total_xedits) - s=p->cfg->xedit[user.xedit-1]->code; + if(p->user.xedit>0 && p->user.xedit<=p->cfg->total_xedits) + s=p->cfg->xedit[p->user.xedit-1]->code; else s=""; /* internal editor */ break; case USER_PROP_SHELL: - s=p->cfg->shell[user.shell]->code; + s=p->cfg->shell[p->user.shell]->code; break; case USER_PROP_QWK: - val=user.qwk; + val=p->user.qwk; break; case USER_PROP_TMPEXT: - s=user.tmpext; + s=p->user.tmpext; break; case USER_PROP_CHAT: - val=user.chat; + val=p->user.chat; break; case USER_PROP_NS_TIME: - val=user.ns_time; + val=p->user.ns_time; break; case USER_PROP_PROT: - sprintf(tmp,"%c",user.prot); + sprintf(tmp,"%c",p->user.prot); s=tmp; break; case USER_PROP_LOGONTIME: - val=user.logontime; + val=p->user.logontime; break; case USER_PROP_TIMEPERCALL: - val=p->cfg->level_timepercall[user.level]; + val=p->cfg->level_timepercall[p->user.level]; break; case USER_PROP_TIMEPERDAY: - val=p->cfg->level_timeperday[user.level]; + val=p->cfg->level_timeperday[p->user.level]; break; case USER_PROP_CALLSPERDAY: - val=p->cfg->level_callsperday[user.level]; + val=p->cfg->level_callsperday[p->user.level]; break; case USER_PROP_LINESPERMSG: - val=p->cfg->level_linespermsg[user.level]; + val=p->cfg->level_linespermsg[p->user.level]; break; case USER_PROP_POSTSPERDAY: - val=p->cfg->level_postsperday[user.level]; + val=p->cfg->level_postsperday[p->user.level]; break; case USER_PROP_EMAILPERDAY: - val=p->cfg->level_emailperday[user.level]; + val=p->cfg->level_emailperday[p->user.level]; break; case USER_PROP_FREECDTPERDAY: - val=p->cfg->level_freecdtperday[user.level]; + val=p->cfg->level_freecdtperday[p->user.level]; break; case USER_PROP_MAIL_WAITING: - val=getmail(p->cfg,user.number,/* sent? */FALSE); + val=getmail(p->cfg,p->user.number,/* sent? */FALSE); break; case USER_PROP_MAIL_PENDING: - val=getmail(p->cfg,user.number,/* sent? */TRUE); + val=getmail(p->cfg,p->user.number,/* sent? */TRUE); break; + case USER_PROP_CACHED: + *vp = BOOLEAN_TO_JSVAL(p->cached); + return(JS_TRUE); /* intentional early return */ + default: /* This must not set vp in order for child objects to work (stats and security) */ return(JS_TRUE); @@ -387,6 +399,7 @@ static JSBool js_user_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) jsint tiny; JSString* js_str; private_t* p; + int32 usernumber; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -403,154 +416,163 @@ static JSBool js_user_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) switch(tiny) { case USER_PROP_NUMBER: - JS_ValueToInt32(cx, *vp, (jsint*)&p->usernumber); + JS_ValueToInt32(cx, *vp, &usernumber); + if(usernumber!=p->user.number) + p->user.number=(ushort)usernumber; break; case USER_PROP_ALIAS: /* update USER.DAT */ - putuserrec(p->cfg,p->usernumber,U_ALIAS,LEN_ALIAS,str); + putuserrec(p->cfg,p->user.number,U_ALIAS,LEN_ALIAS,str); /* update NAME.DAT */ - getuserrec(p->cfg,p->usernumber,U_MISC,8,tmp); + getuserrec(p->cfg,p->user.number,U_MISC,8,tmp); usermisc=ahtoul(tmp); if(!(usermisc&DELETED)) - putusername(p->cfg,p->usernumber,str); + putusername(p->cfg,p->user.number,str); break; case USER_PROP_NAME: - putuserrec(p->cfg,p->usernumber,U_NAME,LEN_NAME,str); + putuserrec(p->cfg,p->user.number,U_NAME,LEN_NAME,str); break; case USER_PROP_HANDLE: - putuserrec(p->cfg,p->usernumber,U_HANDLE,LEN_HANDLE,str); + putuserrec(p->cfg,p->user.number,U_HANDLE,LEN_HANDLE,str); break; case USER_PROP_NOTE: - putuserrec(p->cfg,p->usernumber,U_NOTE,LEN_NOTE,str); + putuserrec(p->cfg,p->user.number,U_NOTE,LEN_NOTE,str); break; case USER_PROP_COMP: - putuserrec(p->cfg,p->usernumber,U_COMP,LEN_COMP,str); + putuserrec(p->cfg,p->user.number,U_COMP,LEN_COMP,str); break; case USER_PROP_COMMENT: - putuserrec(p->cfg,p->usernumber,U_COMMENT,LEN_COMMENT,str); + putuserrec(p->cfg,p->user.number,U_COMMENT,LEN_COMMENT,str); break; case USER_PROP_NETMAIL: - putuserrec(p->cfg,p->usernumber,U_NETMAIL,LEN_NETMAIL,str); + putuserrec(p->cfg,p->user.number,U_NETMAIL,LEN_NETMAIL,str); break; case USER_PROP_ADDRESS: - putuserrec(p->cfg,p->usernumber,U_ADDRESS,LEN_ADDRESS,str); + putuserrec(p->cfg,p->user.number,U_ADDRESS,LEN_ADDRESS,str); break; case USER_PROP_LOCATION: - putuserrec(p->cfg,p->usernumber,U_LOCATION,LEN_LOCATION,str); + putuserrec(p->cfg,p->user.number,U_LOCATION,LEN_LOCATION,str); break; case USER_PROP_ZIPCODE: - putuserrec(p->cfg,p->usernumber,U_ZIPCODE,LEN_ZIPCODE,str); + putuserrec(p->cfg,p->user.number,U_ZIPCODE,LEN_ZIPCODE,str); break; case USER_PROP_PHONE: - putuserrec(p->cfg,p->usernumber,U_PHONE,LEN_PHONE,str); + putuserrec(p->cfg,p->user.number,U_PHONE,LEN_PHONE,str); break; case USER_PROP_BIRTH: - putuserrec(p->cfg,p->usernumber,U_BIRTH,LEN_BIRTH,str); + putuserrec(p->cfg,p->user.number,U_BIRTH,LEN_BIRTH,str); break; case USER_PROP_MODEM: - putuserrec(p->cfg,p->usernumber,U_MODEM,LEN_MODEM,str); + putuserrec(p->cfg,p->user.number,U_MODEM,LEN_MODEM,str); break; case USER_PROP_ROWS: - putuserrec(p->cfg,p->usernumber,U_ROWS,0,str); /* base 10 */ + putuserrec(p->cfg,p->user.number,U_ROWS,0,str); /* base 10 */ break; case USER_PROP_SEX: - putuserrec(p->cfg,p->usernumber,U_SEX,0,strupr(str)); /* single char */ + putuserrec(p->cfg,p->user.number,U_SEX,0,strupr(str)); /* single char */ break; case USER_PROP_CURSUB: - putuserrec(p->cfg,p->usernumber,U_CURSUB,0,strupr(str)); + putuserrec(p->cfg,p->user.number,U_CURSUB,0,strupr(str)); break; case USER_PROP_CURDIR: - putuserrec(p->cfg,p->usernumber,U_CURDIR,0,strupr(str)); + putuserrec(p->cfg,p->user.number,U_CURDIR,0,strupr(str)); break; case USER_PROP_CURXTRN: - putuserrec(p->cfg,p->usernumber,U_CURXTRN,0,strupr(str)); + putuserrec(p->cfg,p->user.number,U_CURXTRN,0,strupr(str)); break; case USER_PROP_XEDIT: - putuserrec(p->cfg,p->usernumber,U_XEDIT,0,strupr(str)); + putuserrec(p->cfg,p->user.number,U_XEDIT,0,strupr(str)); break; case USER_PROP_SHELL: - putuserrec(p->cfg,p->usernumber,U_COMP,0,strupr(str)); + putuserrec(p->cfg,p->user.number,U_COMP,0,strupr(str)); break; case USER_PROP_MISC: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_MISC,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_MISC,0,ultoa(val,tmp,16)); break; case USER_PROP_QWK: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_QWK,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_QWK,0,ultoa(val,tmp,16)); break; case USER_PROP_CHAT: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_CHAT,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_CHAT,0,ultoa(val,tmp,16)); break; case USER_PROP_TMPEXT: - putuserrec(p->cfg,p->usernumber,U_TMPEXT,0,str); + putuserrec(p->cfg,p->user.number,U_TMPEXT,0,str); break; case USER_PROP_NS_TIME: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_NS_TIME,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_NS_TIME,0,ultoa(val,tmp,16)); break; case USER_PROP_PROT: - putuserrec(p->cfg,p->usernumber,U_PROT,0,strupr(str)); /* single char */ + putuserrec(p->cfg,p->user.number,U_PROT,0,strupr(str)); /* single char */ break; case USER_PROP_LOGONTIME: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_LOGONTIME,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_LOGONTIME,0,ultoa(val,tmp,16)); break; /* security properties*/ case USER_PROP_PASS: - putuserrec(p->cfg,p->usernumber,U_PASS,LEN_PASS,strupr(str)); + putuserrec(p->cfg,p->user.number,U_PASS,LEN_PASS,strupr(str)); break; case USER_PROP_PWMOD: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_PWMOD,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_PWMOD,0,ultoa(val,tmp,16)); break; case USER_PROP_LEVEL: - putuserrec(p->cfg,p->usernumber,U_LEVEL,0,str); + putuserrec(p->cfg,p->user.number,U_LEVEL,0,str); break; case USER_PROP_FLAGS1: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_FLAGS1,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_FLAGS1,0,ultoa(val,tmp,16)); break; case USER_PROP_FLAGS2: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_FLAGS2,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_FLAGS2,0,ultoa(val,tmp,16)); break; case USER_PROP_FLAGS3: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_FLAGS3,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_FLAGS3,0,ultoa(val,tmp,16)); break; case USER_PROP_FLAGS4: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_FLAGS4,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_FLAGS4,0,ultoa(val,tmp,16)); break; case USER_PROP_EXEMPT: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_EXEMPT,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_EXEMPT,0,ultoa(val,tmp,16)); break; case USER_PROP_REST: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_REST,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_REST,0,ultoa(val,tmp,16)); break; case USER_PROP_CDT: - putuserrec(p->cfg,p->usernumber,U_CDT,0,str); + putuserrec(p->cfg,p->user.number,U_CDT,0,str); break; case USER_PROP_FREECDT: - putuserrec(p->cfg,p->usernumber,U_FREECDT,0,str); + putuserrec(p->cfg,p->user.number,U_FREECDT,0,str); break; case USER_PROP_MIN: - putuserrec(p->cfg,p->usernumber,U_MIN,0,str); + putuserrec(p->cfg,p->user.number,U_MIN,0,str); break; case USER_PROP_TEXTRA: - putuserrec(p->cfg,p->usernumber,U_TEXTRA,0,str); + putuserrec(p->cfg,p->user.number,U_TEXTRA,0,str); break; case USER_PROP_EXPIRE: if(JS_ValueToInt32(cx,*vp,&val)) - putuserrec(p->cfg,p->usernumber,U_EXPIRE,0,ultoa(val,tmp,16)); + putuserrec(p->cfg,p->user.number,U_EXPIRE,0,ultoa(val,tmp,16)); break; + + case USER_PROP_CACHED: + JS_ValueToBoolean(cx, *vp, &p->cached); + return(JS_TRUE); /* intentional early return */ + } + p->cached=FALSE; + return(JS_TRUE); } @@ -594,6 +616,7 @@ static jsSyncPropertySpec js_user_properties[] = { { "newscan_date" ,USER_PROP_NS_TIME ,0, /* Alias */ 310}, { "download_protocol" ,USER_PROP_PROT ,USER_PROP_FLAGS, 310}, { "logontime" ,USER_PROP_LOGONTIME ,USER_PROP_FLAGS, 310}, + { "cached" ,USER_PROP_CACHED ,USER_PROP_FLAGS, 31301}, {0} }; @@ -633,6 +656,7 @@ static char* user_prop_desc[] = { ,"new file scan date/time (time_t format)" ,"file transfer protocol (command key)" ,"logon time (time_t format)" + ,"record is currently cached in memory" ,NULL }; #endif @@ -787,7 +811,6 @@ js_chk_ar(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { uchar* ar; JSString* js_str; - user_t user; private_t* p; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) @@ -798,10 +821,9 @@ js_chk_ar(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ar = arstr(NULL,JS_GetStringBytes(js_str),p->cfg); - user.number=p->usernumber; - getuserdat(p->cfg,&user); + js_getuserdat(p); - *rval = BOOLEAN_TO_JSVAL(chk_ar(p->cfg,ar,&user)); + *rval = BOOLEAN_TO_JSVAL(chk_ar(p->cfg,ar,&p->user)); if(ar!=NULL && ar!=nular) free(ar); @@ -922,7 +944,8 @@ js_user_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval return(JS_FALSE); p->cfg = scfg; - p->usernumber = user.number; + p->user = user; + p->cached = (user.number==0 ? FALSE : TRUE); JS_SetPrivate(cx, obj, p); /* Must do this before calling js_DefineSyncMethods() */ @@ -979,7 +1002,8 @@ JSObject* DLLCALL js_CreateUserObject(JSContext* cx, JSObject* parent, scfg_t* c return(NULL); p->cfg = cfg; - p->usernumber = usernumber; + p->user.number = usernumber; + p->cached = FALSE; JS_SetPrivate(cx, userobj, p);