Annotation of sbbs/src/sbbs3/js_user.c, revision 1.1.1.1

1.1       root        1: /* js_user.c */
                      2: 
                      3: /* Synchronet JavaScript "User" Object */
                      4: 
                      5: /* $Id: js_user.c,v 1.62 2006/06/06 17:17:18 rswindell Exp $ */
                      6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
                     11:  * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html         *
                     12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU General Public License                         *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #include "sbbs.h"
                     39: 
                     40: #ifdef JAVASCRIPT
                     41: 
                     42: static scfg_t* scfg=NULL;
                     43: 
                     44: static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";
                     45: 
                     46: typedef struct
                     47: {
                     48:        user_t  user;
                     49:        BOOL    cached;
                     50:        scfg_t* cfg;
                     51: 
                     52: } private_t;
                     53: 
                     54: /* User Object Properites */
                     55: enum {
                     56:         USER_PROP_NUMBER
                     57:        ,USER_PROP_ALIAS        
                     58:        ,USER_PROP_NAME         
                     59:        ,USER_PROP_HANDLE       
                     60:        ,USER_PROP_NOTE         
                     61:        ,USER_PROP_COMP         
                     62:        ,USER_PROP_COMMENT      
                     63:        ,USER_PROP_NETMAIL      
                     64:        ,USER_PROP_EMAIL        /* READ ONLY */
                     65:        ,USER_PROP_ADDRESS      
                     66:        ,USER_PROP_LOCATION     
                     67:        ,USER_PROP_ZIPCODE
                     68:        ,USER_PROP_PASS
                     69:        ,USER_PROP_PHONE        
                     70:        ,USER_PROP_BIRTH  
                     71:        ,USER_PROP_AGE          /* READ ONLY */
                     72:        ,USER_PROP_MODEM     
                     73:        ,USER_PROP_LASTON       
                     74:        ,USER_PROP_FIRSTON      
                     75:        ,USER_PROP_EXPIRE    
                     76:        ,USER_PROP_PWMOD     
                     77:        ,USER_PROP_LOGONS    
                     78:        ,USER_PROP_LTODAY    
                     79:        ,USER_PROP_TIMEON    
                     80:        ,USER_PROP_TEXTRA       
                     81:        ,USER_PROP_TTODAY    
                     82:        ,USER_PROP_TLAST     
                     83:        ,USER_PROP_POSTS     
                     84:        ,USER_PROP_EMAILS    
                     85:        ,USER_PROP_FBACKS    
                     86:        ,USER_PROP_ETODAY       
                     87:        ,USER_PROP_PTODAY
                     88:        ,USER_PROP_MAIL_WAITING
                     89:        ,USER_PROP_MAIL_PENDING
                     90:        ,USER_PROP_ULB       
                     91:        ,USER_PROP_ULS       
                     92:        ,USER_PROP_DLB       
                     93:        ,USER_PROP_DLS       
                     94:        ,USER_PROP_CDT          
                     95:        ,USER_PROP_MIN          
                     96:        ,USER_PROP_LEVEL        
                     97:        ,USER_PROP_FLAGS1       
                     98:        ,USER_PROP_FLAGS2       
                     99:        ,USER_PROP_FLAGS3       
                    100:        ,USER_PROP_FLAGS4       
                    101:        ,USER_PROP_EXEMPT       
                    102:        ,USER_PROP_REST         
                    103:        ,USER_PROP_ROWS         
                    104:        ,USER_PROP_SEX          
                    105:        ,USER_PROP_MISC         
                    106:        ,USER_PROP_LEECH        
                    107:        ,USER_PROP_CURSUB       
                    108:        ,USER_PROP_CURDIR       
                    109:        ,USER_PROP_CURXTRN
                    110:        ,USER_PROP_FREECDT      
                    111:        ,USER_PROP_XEDIT        
                    112:        ,USER_PROP_SHELL        
                    113:        ,USER_PROP_QWK          
                    114:        ,USER_PROP_TMPEXT       
                    115:        ,USER_PROP_CHAT         
                    116:        ,USER_PROP_NS_TIME      
                    117:        ,USER_PROP_PROT         
                    118:        ,USER_PROP_LOGONTIME
                    119:        ,USER_PROP_TIMEPERCALL
                    120:        ,USER_PROP_TIMEPERDAY
                    121:        ,USER_PROP_CALLSPERDAY
                    122:        ,USER_PROP_LINESPERMSG
                    123:        ,USER_PROP_EMAILPERDAY
                    124:        ,USER_PROP_POSTSPERDAY
                    125:        ,USER_PROP_FREECDTPERDAY
                    126:        ,USER_PROP_CACHED
                    127: };
                    128: 
                    129: static void js_getuserdat(private_t* p)
                    130: {
                    131:        if(!p->cached) {
                    132:                if(getuserdat(p->cfg,&p->user)==0)
                    133:                        p->cached=TRUE;
                    134:        }
                    135: }
                    136: 
                    137: 
                    138: static JSBool js_user_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                    139: {
                    140:        char*           s=NULL;
                    141:        char            tmp[128];
                    142:        ulong           val=0;
                    143:     jsint       tiny;
                    144:        JSString*       js_str;
                    145:        private_t*      p;
                    146: 
                    147:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    148:                JS_ReportError(cx,getprivate_failure,WHERE);
                    149:                return(JS_FALSE);
                    150:        }
                    151: 
                    152:        js_getuserdat(p);
                    153: 
                    154:     tiny = JSVAL_TO_INT(id);
                    155: 
                    156:        switch(tiny) {
                    157:                case USER_PROP_NUMBER:
                    158:                        val=p->user.number;
                    159:                        break;
                    160:                case USER_PROP_ALIAS: 
                    161:                        s=p->user.alias;
                    162:                        break;
                    163:                case USER_PROP_NAME:
                    164:                        s=p->user.name;
                    165:                        break;
                    166:                case USER_PROP_HANDLE:
                    167:                        s=p->user.handle;
                    168:                        break;
                    169:                case USER_PROP_NOTE:
                    170:                        s=p->user.note;
                    171:                        break;
                    172:                case USER_PROP_COMP:
                    173:                        s=p->user.comp;
                    174:                        break;
                    175:                case USER_PROP_COMMENT:
                    176:                        s=p->user.comment;
                    177:                        break;
                    178:                case USER_PROP_NETMAIL:
                    179:                        s=p->user.netmail;
                    180:                        break;
                    181:                case USER_PROP_EMAIL:
                    182:                        s=usermailaddr(p->cfg, tmp
                    183:                                ,p->cfg->inetmail_misc&NMAIL_ALIAS ? p->user.alias : p->user.name);
                    184:                        break;
                    185:                case USER_PROP_ADDRESS:
                    186:                        s=p->user.address;
                    187:                        break;
                    188:                case USER_PROP_LOCATION:
                    189:                        s=p->user.location;
                    190:                        break;
                    191:                case USER_PROP_ZIPCODE:
                    192:                        s=p->user.zipcode;
                    193:                        break;
                    194:                case USER_PROP_PASS:
                    195:                        s=p->user.pass;
                    196:                        break;
                    197:                case USER_PROP_PHONE:
                    198:                        s=p->user.phone;
                    199:                        break;
                    200:                case USER_PROP_BIRTH:
                    201:                        s=p->user.birth;
                    202:                        break;
                    203:                case USER_PROP_AGE:
                    204:                        val=getage(p->cfg,p->user.birth);
                    205:                        break;
                    206:                case USER_PROP_MODEM:
                    207:                        s=p->user.modem;
                    208:                        break;
                    209:                case USER_PROP_LASTON:
                    210:                        val=p->user.laston;
                    211:                        break;
                    212:                case USER_PROP_FIRSTON:
                    213:                        val=p->user.firston;
                    214:                        break;
                    215:                case USER_PROP_EXPIRE:
                    216:                        val=p->user.expire;
                    217:                        break;
                    218:                case USER_PROP_PWMOD: 
                    219:                        val=p->user.pwmod;
                    220:                        break;
                    221:                case USER_PROP_LOGONS:
                    222:                        val=p->user.logons;
                    223:                        break;
                    224:                case USER_PROP_LTODAY:
                    225:                        val=p->user.ltoday;
                    226:                        break;
                    227:                case USER_PROP_TIMEON:
                    228:                        val=p->user.timeon;
                    229:                        break;
                    230:                case USER_PROP_TEXTRA:
                    231:                        val=p->user.textra;
                    232:                        break;
                    233:                case USER_PROP_TTODAY:
                    234:                        val=p->user.ttoday;
                    235:                        break;
                    236:                case USER_PROP_TLAST: 
                    237:                        val=p->user.tlast;
                    238:                        break;
                    239:                case USER_PROP_POSTS: 
                    240:                        val=p->user.posts;
                    241:                        break;
                    242:                case USER_PROP_EMAILS: 
                    243:                        val=p->user.emails;
                    244:                        break;
                    245:                case USER_PROP_FBACKS: 
                    246:                        val=p->user.fbacks;
                    247:                        break;
                    248:                case USER_PROP_ETODAY:  
                    249:                        val=p->user.etoday;
                    250:                        break;
                    251:                case USER_PROP_PTODAY:
                    252:                        val=p->user.ptoday;
                    253:                        break;
                    254:                case USER_PROP_ULB:
                    255:                        val=p->user.ulb;
                    256:                        break;
                    257:                case USER_PROP_ULS:
                    258:                        val=p->user.uls;
                    259:                        break;
                    260:                case USER_PROP_DLB:
                    261:                        val=p->user.dlb;
                    262:                        break;
                    263:                case USER_PROP_DLS:
                    264:                        val=p->user.dls;
                    265:                        break;
                    266:                case USER_PROP_CDT:
                    267:                        val=p->user.cdt;
                    268:                        break;
                    269:                case USER_PROP_MIN:
                    270:                        val=p->user.min;
                    271:                        break;
                    272:                case USER_PROP_LEVEL:
                    273:                        val=p->user.level;
                    274:                        break;
                    275:                case USER_PROP_FLAGS1:
                    276:                        val=p->user.flags1;
                    277:                        break;
                    278:                case USER_PROP_FLAGS2:
                    279:                        val=p->user.flags2;
                    280:                        break;
                    281:                case USER_PROP_FLAGS3:
                    282:                        val=p->user.flags3;
                    283:                        break;
                    284:                case USER_PROP_FLAGS4:
                    285:                        val=p->user.flags4;
                    286:                        break;
                    287:                case USER_PROP_EXEMPT:
                    288:                        val=p->user.exempt;
                    289:                        break;
                    290:                case USER_PROP_REST:
                    291:                        val=p->user.rest;
                    292:                        break;
                    293:                case USER_PROP_ROWS:
                    294:                        val=p->user.rows;
                    295:                        break;
                    296:                case USER_PROP_SEX:
                    297:                        sprintf(tmp,"%c",p->user.sex);
                    298:                        s=tmp;
                    299:                        break;
                    300:                case USER_PROP_MISC:
                    301:                        val=p->user.misc;
                    302:                        break;
                    303:                case USER_PROP_LEECH:
                    304:                        val=p->user.leech;
                    305:                        break;
                    306:                case USER_PROP_CURSUB:
                    307:                        s=p->user.cursub;
                    308:                        break;
                    309:                case USER_PROP_CURDIR:
                    310:                        s=p->user.curdir;
                    311:                        break;
                    312:                case USER_PROP_CURXTRN:
                    313:                        s=p->user.curxtrn;
                    314:                        break;
                    315: 
                    316:                case USER_PROP_FREECDT:
                    317:                        val=p->user.freecdt;
                    318:                        break;
                    319:                case USER_PROP_XEDIT:
                    320:                        if(p->user.xedit>0 && p->user.xedit<=p->cfg->total_xedits)
                    321:                                s=p->cfg->xedit[p->user.xedit-1]->code;
                    322:                        else
                    323:                                s=""; /* internal editor */
                    324:                        break;
                    325:                case USER_PROP_SHELL:
                    326:                        s=p->cfg->shell[p->user.shell]->code;
                    327:                        break;
                    328:                case USER_PROP_QWK:
                    329:                        val=p->user.qwk;
                    330:                        break;
                    331:                case USER_PROP_TMPEXT:
                    332:                        s=p->user.tmpext;
                    333:                        break;
                    334:                case USER_PROP_CHAT:
                    335:                        val=p->user.chat;
                    336:                        break;
                    337:                case USER_PROP_NS_TIME:
                    338:                        val=p->user.ns_time;
                    339:                        break;
                    340:                case USER_PROP_PROT:
                    341:                        sprintf(tmp,"%c",p->user.prot);
                    342:                        s=tmp;
                    343:                        break;
                    344:                case USER_PROP_LOGONTIME:
                    345:                        val=p->user.logontime;
                    346:                        break;
                    347:                case USER_PROP_TIMEPERCALL:
                    348:                        val=p->cfg->level_timepercall[p->user.level];
                    349:                        break;
                    350:                case USER_PROP_TIMEPERDAY:
                    351:                        val=p->cfg->level_timeperday[p->user.level];
                    352:                        break;
                    353:                case USER_PROP_CALLSPERDAY:
                    354:                        val=p->cfg->level_callsperday[p->user.level];
                    355:                        break;
                    356:                case USER_PROP_LINESPERMSG:
                    357:                        val=p->cfg->level_linespermsg[p->user.level];
                    358:                        break;
                    359:                case USER_PROP_POSTSPERDAY:
                    360:                        val=p->cfg->level_postsperday[p->user.level];
                    361:                        break;
                    362:                case USER_PROP_EMAILPERDAY:
                    363:                        val=p->cfg->level_emailperday[p->user.level];
                    364:                        break;
                    365:                case USER_PROP_FREECDTPERDAY:
                    366:                        val=p->cfg->level_freecdtperday[p->user.level];
                    367:                        break;
                    368:                case USER_PROP_MAIL_WAITING:
                    369:                        val=getmail(p->cfg,p->user.number,/* sent? */FALSE);
                    370:                        break;
                    371:                case USER_PROP_MAIL_PENDING:
                    372:                        val=getmail(p->cfg,p->user.number,/* sent? */TRUE);
                    373:                        break;
                    374: 
                    375:                case USER_PROP_CACHED:
                    376:                        *vp = BOOLEAN_TO_JSVAL(p->cached);
                    377:                        return(JS_TRUE);        /* intentional early return */
                    378: 
                    379:                default:        
                    380:                        /* This must not set vp in order for child objects to work (stats and security) */
                    381:                        return(JS_TRUE);
                    382:        }
                    383:        if(s!=NULL) {
                    384:                if((js_str=JS_NewStringCopyZ(cx, s))==NULL)
                    385:                        return(JS_FALSE);
                    386:                *vp = STRING_TO_JSVAL(js_str);
                    387:        } else
                    388:                JS_NewNumberValue(cx,val,vp);
                    389: 
                    390:        return(JS_TRUE);
                    391: }
                    392: 
                    393: static JSBool js_user_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                    394: {
                    395:        char*           str;
                    396:        char            tmp[64];
                    397:        jsint           val;
                    398:        ulong           usermisc;
                    399:     jsint       tiny;
                    400:        JSString*       js_str;
                    401:        private_t*      p;
                    402:        int32           usernumber;
                    403: 
                    404:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    405:                JS_ReportError(cx,getprivate_failure,WHERE);
                    406:                return(JS_FALSE);
                    407:        }
                    408: 
                    409:        if((js_str=JS_ValueToString(cx,*vp))==NULL)
                    410:                return(JS_FALSE);
                    411: 
                    412:        if((str=JS_GetStringBytes(js_str))==NULL)
                    413:                return(JS_FALSE);
                    414: 
                    415:     tiny = JSVAL_TO_INT(id);
                    416: 
                    417:        switch(tiny) {
                    418:                case USER_PROP_NUMBER:
                    419:                        JS_ValueToInt32(cx, *vp, &usernumber);
                    420:                        if(usernumber!=p->user.number)
                    421:                                p->user.number=(ushort)usernumber;
                    422:                        break;
                    423:                case USER_PROP_ALIAS:
                    424:                        /* update USER.DAT */
                    425:                        putuserrec(p->cfg,p->user.number,U_ALIAS,LEN_ALIAS,str);
                    426: 
                    427:                        /* update NAME.DAT */
                    428:                        getuserrec(p->cfg,p->user.number,U_MISC,8,tmp);
                    429:                        usermisc=ahtoul(tmp);
                    430:                        if(!(usermisc&DELETED))
                    431:                                putusername(p->cfg,p->user.number,str);
                    432:                        break;
                    433:                case USER_PROP_NAME:
                    434:                        putuserrec(p->cfg,p->user.number,U_NAME,LEN_NAME,str);
                    435:                        break;
                    436:                case USER_PROP_HANDLE:
                    437:                        putuserrec(p->cfg,p->user.number,U_HANDLE,LEN_HANDLE,str);
                    438:                        break;
                    439:                case USER_PROP_NOTE:             
                    440:                        putuserrec(p->cfg,p->user.number,U_NOTE,LEN_NOTE,str);
                    441:                        break;
                    442:                case USER_PROP_COMP:             
                    443:                        putuserrec(p->cfg,p->user.number,U_COMP,LEN_COMP,str);
                    444:                        break;
                    445:                case USER_PROP_COMMENT:  
                    446:                        putuserrec(p->cfg,p->user.number,U_COMMENT,LEN_COMMENT,str);
                    447:                        break;
                    448:                case USER_PROP_NETMAIL:  
                    449:                        putuserrec(p->cfg,p->user.number,U_NETMAIL,LEN_NETMAIL,str);
                    450:                        break;
                    451:                case USER_PROP_ADDRESS:  
                    452:                        putuserrec(p->cfg,p->user.number,U_ADDRESS,LEN_ADDRESS,str);
                    453:                        break;
                    454:                case USER_PROP_LOCATION:         
                    455:                        putuserrec(p->cfg,p->user.number,U_LOCATION,LEN_LOCATION,str);
                    456:                        break;
                    457:                case USER_PROP_ZIPCODE:  
                    458:                        putuserrec(p->cfg,p->user.number,U_ZIPCODE,LEN_ZIPCODE,str);
                    459:                        break;
                    460:                case USER_PROP_PHONE:    
                    461:                        putuserrec(p->cfg,p->user.number,U_PHONE,LEN_PHONE,str);
                    462:                        break;
                    463:                case USER_PROP_BIRTH:    
                    464:                        putuserrec(p->cfg,p->user.number,U_BIRTH,LEN_BIRTH,str);
                    465:                        break;
                    466:                case USER_PROP_MODEM:     
                    467:                        putuserrec(p->cfg,p->user.number,U_MODEM,LEN_MODEM,str);
                    468:                        break;
                    469:                case USER_PROP_ROWS:             
                    470:                        putuserrec(p->cfg,p->user.number,U_ROWS,0,str); /* base 10 */
                    471:                        break;
                    472:                case USER_PROP_SEX:              
                    473:                        putuserrec(p->cfg,p->user.number,U_SEX,0,strupr(str));  /* single char */
                    474:                        break;
                    475:                case USER_PROP_CURSUB:   
                    476:                        putuserrec(p->cfg,p->user.number,U_CURSUB,0,strupr(str));
                    477:                        break;
                    478:                case USER_PROP_CURDIR:   
                    479:                        putuserrec(p->cfg,p->user.number,U_CURDIR,0,strupr(str));
                    480:                        break;
                    481:                case USER_PROP_CURXTRN:  
                    482:                        putuserrec(p->cfg,p->user.number,U_CURXTRN,0,strupr(str));
                    483:                        break;
                    484:                case USER_PROP_XEDIT:    
                    485:                        putuserrec(p->cfg,p->user.number,U_XEDIT,0,strupr(str));
                    486:                        break;
                    487:                case USER_PROP_SHELL:    
                    488:                        putuserrec(p->cfg,p->user.number,U_COMP,0,strupr(str));
                    489:                        break;
                    490:                case USER_PROP_MISC:
                    491:                        if(JS_ValueToInt32(cx,*vp,&val))
                    492:                                putuserrec(p->cfg,p->user.number,U_MISC,0,ultoa(val,tmp,16));
                    493:                        break;
                    494:                case USER_PROP_QWK:              
                    495:                        if(JS_ValueToInt32(cx,*vp,&val))
                    496:                                putuserrec(p->cfg,p->user.number,U_QWK,0,ultoa(val,tmp,16));
                    497:                        break;
                    498:                case USER_PROP_CHAT:             
                    499:                        if(JS_ValueToInt32(cx,*vp,&val))
                    500:                                putuserrec(p->cfg,p->user.number,U_CHAT,0,ultoa(val,tmp,16));
                    501:                        break;
                    502:                case USER_PROP_TMPEXT:   
                    503:                        putuserrec(p->cfg,p->user.number,U_TMPEXT,0,str);
                    504:                        break;
                    505:                case USER_PROP_NS_TIME:  
                    506:                        if(JS_ValueToInt32(cx,*vp,&val))
                    507:                                putuserrec(p->cfg,p->user.number,U_NS_TIME,0,ultoa(val,tmp,16));
                    508:                        break;
                    509:                case USER_PROP_PROT:    
                    510:                        putuserrec(p->cfg,p->user.number,U_PROT,0,strupr(str)); /* single char */
                    511:                        break;
                    512:                case USER_PROP_LOGONTIME:        
                    513:                        if(JS_ValueToInt32(cx,*vp,&val))
                    514:                                putuserrec(p->cfg,p->user.number,U_LOGONTIME,0,ultoa(val,tmp,16));
                    515:                        break;
                    516:                        
                    517:                /* security properties*/
                    518:                case USER_PROP_PASS:    
                    519:                        putuserrec(p->cfg,p->user.number,U_PASS,LEN_PASS,strupr(str));
                    520:                        break;
                    521:                case USER_PROP_PWMOD:
                    522:                        if(JS_ValueToInt32(cx,*vp,&val))
                    523:                                putuserrec(p->cfg,p->user.number,U_PWMOD,0,ultoa(val,tmp,16));
                    524:                        break;
                    525:                case USER_PROP_LEVEL: 
                    526:                        putuserrec(p->cfg,p->user.number,U_LEVEL,0,str);
                    527:                        break;
                    528:                case USER_PROP_FLAGS1:
                    529:                        if(JS_ValueToInt32(cx,*vp,&val))
                    530:                                putuserrec(p->cfg,p->user.number,U_FLAGS1,0,ultoa(val,tmp,16));
                    531:                        break;
                    532:                case USER_PROP_FLAGS2:
                    533:                        if(JS_ValueToInt32(cx,*vp,&val))
                    534:                                putuserrec(p->cfg,p->user.number,U_FLAGS2,0,ultoa(val,tmp,16));
                    535:                        break;
                    536:                case USER_PROP_FLAGS3:
                    537:                        if(JS_ValueToInt32(cx,*vp,&val))
                    538:                                putuserrec(p->cfg,p->user.number,U_FLAGS3,0,ultoa(val,tmp,16));
                    539:                        break;
                    540:                case USER_PROP_FLAGS4:
                    541:                        if(JS_ValueToInt32(cx,*vp,&val))
                    542:                                putuserrec(p->cfg,p->user.number,U_FLAGS4,0,ultoa(val,tmp,16));
                    543:                        break;
                    544:                case USER_PROP_EXEMPT:
                    545:                        if(JS_ValueToInt32(cx,*vp,&val))
                    546:                                putuserrec(p->cfg,p->user.number,U_EXEMPT,0,ultoa(val,tmp,16));
                    547:                        break;
                    548:                case USER_PROP_REST:    
                    549:                        if(JS_ValueToInt32(cx,*vp,&val))
                    550:                                putuserrec(p->cfg,p->user.number,U_REST,0,ultoa(val,tmp,16));
                    551:                        break;
                    552:                case USER_PROP_CDT:     
                    553:                        putuserrec(p->cfg,p->user.number,U_CDT,0,str);
                    554:                        break;
                    555:                case USER_PROP_FREECDT:
                    556:                        putuserrec(p->cfg,p->user.number,U_FREECDT,0,str);
                    557:                        break;
                    558:                case USER_PROP_MIN:     
                    559:                        putuserrec(p->cfg,p->user.number,U_MIN,0,str);
                    560:                        break;
                    561:                case USER_PROP_TEXTRA:  
                    562:                        putuserrec(p->cfg,p->user.number,U_TEXTRA,0,str);
                    563:                        break;
                    564:                case USER_PROP_EXPIRE:  
                    565:                        if(JS_ValueToInt32(cx,*vp,&val))
                    566:                                putuserrec(p->cfg,p->user.number,U_EXPIRE,0,ultoa(val,tmp,16));
                    567:                        break;
                    568: 
                    569:                case USER_PROP_CACHED:
                    570:                        JS_ValueToBoolean(cx, *vp, &p->cached);
                    571:                        return(JS_TRUE);        /* intentional early return */
                    572: 
                    573:        }
                    574:        p->cached=FALSE;
                    575: 
                    576: 
                    577:        return(JS_TRUE);
                    578: }
                    579: 
                    580: #define USER_PROP_FLAGS JSPROP_ENUMERATE
                    581: 
                    582: static jsSyncPropertySpec js_user_properties[] = {
                    583: /*              name                           ,tinyid                                 ,flags,                                 ver     */
                    584: 
                    585:        {       "number"                        ,USER_PROP_NUMBER               ,USER_PROP_FLAGS,               310},
                    586:        {       "alias"                         ,USER_PROP_ALIAS                ,USER_PROP_FLAGS,               310},
                    587:        {       "name"                          ,USER_PROP_NAME                 ,USER_PROP_FLAGS,               310},
                    588:        {       "handle"                        ,USER_PROP_HANDLE               ,USER_PROP_FLAGS,               310},
                    589:        {       "ip_address"            ,USER_PROP_NOTE                 ,USER_PROP_FLAGS,               310},
                    590:        {       "note"                          ,USER_PROP_NOTE                 ,USER_PROP_FLAGS,               310},
                    591:        {       "host_name"                     ,USER_PROP_COMP                 ,USER_PROP_FLAGS,               310},
                    592:        {       "computer"                      ,USER_PROP_COMP                 ,USER_PROP_FLAGS,               310},
                    593:        {       "comment"                       ,USER_PROP_COMMENT              ,USER_PROP_FLAGS,               310},
                    594:        {       "netmail"                       ,USER_PROP_NETMAIL              ,USER_PROP_FLAGS,               310},
                    595:        {       "email"                         ,USER_PROP_EMAIL                ,USER_PROP_FLAGS|JSPROP_READONLY,               310},
                    596:        {       "address"                       ,USER_PROP_ADDRESS              ,USER_PROP_FLAGS,               310},
                    597:        {       "location"                      ,USER_PROP_LOCATION             ,USER_PROP_FLAGS,               310},
                    598:        {       "zipcode"                       ,USER_PROP_ZIPCODE              ,USER_PROP_FLAGS,               310},
                    599:        {       "phone"                         ,USER_PROP_PHONE                ,USER_PROP_FLAGS,               310},
                    600:        {       "birthdate"                     ,USER_PROP_BIRTH                ,USER_PROP_FLAGS,               310},
                    601:        {       "age"                           ,USER_PROP_AGE                  ,USER_PROP_FLAGS|JSPROP_READONLY,               310},
                    602:        {       "connection"            ,USER_PROP_MODEM        ,USER_PROP_FLAGS,               310},
                    603:        {       "modem"                         ,USER_PROP_MODEM        ,USER_PROP_FLAGS,               310},
                    604:        {       "screen_rows"           ,USER_PROP_ROWS                 ,USER_PROP_FLAGS,               310},
                    605:        {       "gender"                        ,USER_PROP_SEX                  ,USER_PROP_FLAGS,               310},
                    606:        {       "cursub"                        ,USER_PROP_CURSUB               ,USER_PROP_FLAGS,               310},
                    607:        {       "curdir"                        ,USER_PROP_CURDIR               ,USER_PROP_FLAGS,               310},
                    608:        {       "curxtrn"                       ,USER_PROP_CURXTRN              ,USER_PROP_FLAGS,               310},
                    609:        {       "editor"                        ,USER_PROP_XEDIT                ,USER_PROP_FLAGS,               310},
                    610:        {       "command_shell"         ,USER_PROP_SHELL                ,USER_PROP_FLAGS,               310},
                    611:        {       "settings"                      ,USER_PROP_MISC                 ,USER_PROP_FLAGS,               310},
                    612:        {       "qwk_settings"          ,USER_PROP_QWK                  ,USER_PROP_FLAGS,               310},
                    613:        {       "chat_settings"         ,USER_PROP_CHAT                 ,USER_PROP_FLAGS,               310},
                    614:        {       "temp_file_ext"         ,USER_PROP_TMPEXT               ,USER_PROP_FLAGS,               310},
                    615:        {       "new_file_time"         ,USER_PROP_NS_TIME              ,USER_PROP_FLAGS,               311},
                    616:        {       "newscan_date"          ,USER_PROP_NS_TIME              ,0, /* Alias */                 310},
                    617:        {       "download_protocol"     ,USER_PROP_PROT                 ,USER_PROP_FLAGS,               310},
                    618:        {       "logontime"                     ,USER_PROP_LOGONTIME    ,USER_PROP_FLAGS,               310},
                    619:        {       "cached"                        ,USER_PROP_CACHED               ,USER_PROP_FLAGS,               314},
                    620:        {0}
                    621: };
                    622: 
                    623: #ifdef BUILD_JSDOCS
                    624: static char* user_prop_desc[] = {
                    625: 
                    626:         "record number (1-based)"
                    627:        ,"alias/name"
                    628:        ,"real name"
                    629:        ,"chat handle"
                    630:        ,"IP address last logged on from"
                    631:        ,"AKA ip_address"
                    632:        ,"host name last logged on from"
                    633:        ,"AKA host_name"
                    634:        ,"sysop's comment"
                    635:        ,"external e-mail address"
                    636:        ,"local Internet e-mail address - <small>READ ONLY</small>"
                    637:        ,"street address"
                    638:        ,"location (city, state)"
                    639:        ,"zip/postal code"
                    640:        ,"phone number"
                    641:        ,"birth date"
                    642:        ,"calculated age in years - <small>READ ONLY</small>"
                    643:        ,"connection type"
                    644:        ,"AKA connection"
                    645:        ,"terminal rows (lines)"
                    646:        ,"gender type"
                    647:        ,"current message sub-board"
                    648:        ,"current file directory"
                    649:        ,"current external program being run"
                    650:        ,"external message editor"
                    651:        ,"command shell"
                    652:        ,"settings bitfield - see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
                    653:        ,"QWK packet settings bitfield - see <tt>QWK_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
                    654:        ,"chat settings bitfield - see <tt>CHAT_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions"
                    655:        ,"temporary file type (extension)"
                    656:        ,"new file scan date/time (time_t format)"
                    657:        ,"file transfer protocol (command key)"
                    658:        ,"logon time (time_t format)"
                    659:        ,"record is currently cached in memory"
                    660:        ,NULL
                    661: };
                    662: #endif
                    663: 
                    664: 
                    665: /* user.security */
                    666: static jsSyncPropertySpec js_user_security_properties[] = {
                    667: /*              name                           ,tinyid                                 ,flags,                         ver     */
                    668: 
                    669:        {       "password"                      ,USER_PROP_PASS                 ,USER_PROP_FLAGS,       310 },
                    670:        {       "password_date"         ,USER_PROP_PWMOD        ,USER_PROP_FLAGS,       310 },
                    671:        {       "level"                         ,USER_PROP_LEVEL                ,USER_PROP_FLAGS,       310 },
                    672:        {       "flags1"                        ,USER_PROP_FLAGS1               ,USER_PROP_FLAGS,       310 },
                    673:        {       "flags2"                        ,USER_PROP_FLAGS2               ,USER_PROP_FLAGS,       310 },
                    674:        {       "flags3"                        ,USER_PROP_FLAGS3               ,USER_PROP_FLAGS,       310 },
                    675:        {       "flags4"                        ,USER_PROP_FLAGS4               ,USER_PROP_FLAGS,       310 },
                    676:        {       "exemptions"            ,USER_PROP_EXEMPT               ,USER_PROP_FLAGS,       310 },
                    677:        {       "restrictions"          ,USER_PROP_REST                 ,USER_PROP_FLAGS,       310 },
                    678:        {       "credits"                       ,USER_PROP_CDT                  ,USER_PROP_FLAGS,       310 },
                    679:        {       "free_credits"          ,USER_PROP_FREECDT              ,USER_PROP_FLAGS,       310 },
                    680:        {       "minutes"                       ,USER_PROP_MIN                  ,USER_PROP_FLAGS,       310 },
                    681:        {       "extra_time"            ,USER_PROP_TEXTRA               ,USER_PROP_FLAGS,       310 },
                    682:        {       "expiration_date"       ,USER_PROP_EXPIRE       ,USER_PROP_FLAGS,       310 },
                    683:        {0}
                    684: };
                    685: 
                    686: #ifdef BUILD_JSDOCS
                    687: static char* user_security_prop_desc[] = {
                    688: 
                    689:         "password"
                    690:        ,"date password last modified (time_t format)"
                    691:        ,"security level (0-99)"
                    692:        ,"flag set #1 (bitfield)"
                    693:        ,"flag set #2 (bitfield)"
                    694:        ,"flag set #3 (bitfield)"
                    695:        ,"flag set #4 (bitfield)"
                    696:        ,"exemption flags (bitfield)"
                    697:        ,"restriction flags (bitfield)"
                    698:        ,"credits"
                    699:        ,"free credits (for today only)"
                    700:        ,"extra minutes (time bank)"
                    701:        ,"extra minutes (for today only)"
                    702:        ,"expiration date/time (time_t format)"
                    703:        ,NULL
                    704: };
                    705: #endif
                    706: 
                    707: #undef  USER_PROP_FLAGS
                    708: #define USER_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
                    709: 
                    710: /* user.limits: These should be READ ONLY by nature */
                    711: static jsSyncPropertySpec js_user_limits_properties[] = {
                    712: /*              name                                   ,tinyid                                 ,flags,                         ver     */
                    713: 
                    714:        {       "time_per_logon"                ,USER_PROP_TIMEPERCALL  ,USER_PROP_FLAGS,       311 },
                    715:        {       "time_per_day"                  ,USER_PROP_TIMEPERDAY   ,USER_PROP_FLAGS,       311 },
                    716:        {       "logons_per_day"                ,USER_PROP_CALLSPERDAY  ,USER_PROP_FLAGS,       311 },
                    717:        {       "lines_per_message"             ,USER_PROP_LINESPERMSG  ,USER_PROP_FLAGS,       311 },
                    718:        {       "email_per_day"                 ,USER_PROP_EMAILPERDAY  ,USER_PROP_FLAGS,       311 },
                    719:        {       "posts_per_day"                 ,USER_PROP_POSTSPERDAY  ,USER_PROP_FLAGS,       311 },
                    720:        {       "free_credits_per_day"  ,USER_PROP_FREECDTPERDAY,USER_PROP_FLAGS,       311 },
                    721:        {0}
                    722: };
                    723: 
                    724: 
                    725: #ifdef BUILD_JSDOCS
                    726: static char* user_limits_prop_desc[] = {
                    727: 
                    728:         "time (in minutes) per logon"
                    729:        ,"time (in minutes) per day"
                    730:        ,"logons per day"
                    731:        ,"lines per message (post or email)"
                    732:        ,"email sent per day"
                    733:        ,"messages posted per day"
                    734:        ,"free credits given per day"
                    735:        ,NULL
                    736: };
                    737: #endif
                    738: 
                    739: 
                    740: #undef  USER_PROP_FLAGS
                    741: #define USER_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
                    742: 
                    743: /* user.stats: These should be READ ONLY by nature */
                    744: static jsSyncPropertySpec js_user_stats_properties[] = {
                    745: /*              name                           ,tinyid                                 ,flags,                                 ver     */
                    746: 
                    747:        {       "laston_date"           ,USER_PROP_LASTON               ,USER_PROP_FLAGS,               310 },
                    748:        {       "firston_date"          ,USER_PROP_FIRSTON              ,USER_PROP_FLAGS,               310 },
                    749:        {       "total_logons"          ,USER_PROP_LOGONS       ,USER_PROP_FLAGS,               310 },
                    750:        {       "logons_today"          ,USER_PROP_LTODAY       ,USER_PROP_FLAGS,               310 },
                    751:        {       "total_timeon"          ,USER_PROP_TIMEON       ,USER_PROP_FLAGS,               310 },
                    752:        {       "timeon_today"          ,USER_PROP_TTODAY       ,USER_PROP_FLAGS,               310 },
                    753:        {       "timeon_last_logon"     ,USER_PROP_TLAST        ,USER_PROP_FLAGS,               310 },
                    754:        {       "total_posts"           ,USER_PROP_POSTS        ,USER_PROP_FLAGS,               310 },
                    755:        {       "total_emails"          ,USER_PROP_EMAILS       ,USER_PROP_FLAGS,               310 },
                    756:        {       "total_feedbacks"       ,USER_PROP_FBACKS       ,USER_PROP_FLAGS,               310 },
                    757:        {       "email_today"           ,USER_PROP_ETODAY               ,USER_PROP_FLAGS,               310 },
                    758:        {       "posts_today"           ,USER_PROP_PTODAY               ,USER_PROP_FLAGS,               310 },
                    759:        {       "bytes_uploaded"        ,USER_PROP_ULB          ,USER_PROP_FLAGS,               310 },
                    760:        {       "files_uploaded"        ,USER_PROP_ULS          ,USER_PROP_FLAGS,               310 },
                    761:        {       "bytes_downloaded"      ,USER_PROP_DLB          ,USER_PROP_FLAGS,               310 },
                    762:        {       "files_downloaded"      ,USER_PROP_DLS          ,USER_PROP_FLAGS,               310 },
                    763:        {       "leech_attempts"        ,USER_PROP_LEECH                ,USER_PROP_FLAGS,               310 },
                    764:        {       "mail_waiting"          ,USER_PROP_MAIL_WAITING ,USER_PROP_FLAGS,               312     },
                    765:        {       "mail_pending"          ,USER_PROP_MAIL_PENDING ,USER_PROP_FLAGS,               312     },
                    766:        {0}
                    767: };
                    768: 
                    769: #ifdef BUILD_JSDOCS
                    770: static char* user_stats_prop_desc[] = {
                    771: 
                    772:         "date of previous logon"
                    773:        ,"date of first logon"
                    774:        ,"total number of logons"
                    775:        ,"total logons today"
                    776:        ,"total time used (in minutes)"
                    777:        ,"time used today"
                    778:        ,"time used last session"
                    779:        ,"total messages posted"
                    780:        ,"total e-mails sent"
                    781:        ,"total feedback messages sent"
                    782:        ,"e-mail sent today"
                    783:        ,"messages posted today"
                    784:        ,"total bytes uploaded"
                    785:        ,"total files uploaded"
                    786:        ,"total bytes downloaded"
                    787:        ,"total files downloaded"
                    788:        ,"suspected leech downloads"
                    789:        ,"number of e-mail messages currently waiting"
                    790:        ,"number of e-mail messages sent, currently pending deletion"
                    791:        ,NULL
                    792: };
                    793: #endif
                    794: 
                    795: 
                    796: static void js_user_finalize(JSContext *cx, JSObject *obj)
                    797: {
                    798:        private_t* p;
                    799: 
                    800:        p=(private_t*)JS_GetPrivate(cx,obj);
                    801: 
                    802:        if(p!=NULL && (scfg_t*)p!=scfg)
                    803:                free(p);
                    804: 
                    805:        p=NULL;
                    806:        JS_SetPrivate(cx,obj,p);
                    807: }
                    808: 
                    809: static JSBool
                    810: js_chk_ar(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    811: {
                    812:        uchar*          ar;
                    813:        JSString*       js_str;
                    814:        private_t*      p;
                    815: 
                    816:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                    817:                return JS_FALSE;
                    818: 
                    819:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
                    820:                return JS_FALSE;
                    821: 
                    822:        ar = arstr(NULL,JS_GetStringBytes(js_str),p->cfg);
                    823: 
                    824:        js_getuserdat(p);
                    825: 
                    826:        *rval = BOOLEAN_TO_JSVAL(chk_ar(p->cfg,ar,&p->user));
                    827: 
                    828:        if(ar!=NULL && ar!=nular)
                    829:                free(ar);
                    830: 
                    831:        return JS_TRUE;
                    832: }
                    833: 
                    834: static JSBool
                    835: js_posted_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    836: {
                    837:        private_t*      p;
                    838:        int32   count=1;
                    839: 
                    840:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                    841:                return JS_FALSE;
                    842: 
                    843:        if(argc)
                    844:                JS_ValueToInt32(cx, argv[0], &count);
                    845: 
                    846:        js_getuserdat(p);
                    847: 
                    848:        *rval = BOOLEAN_TO_JSVAL(user_posted_msg(p->cfg, &p->user, count));
                    849: 
                    850:        return JS_TRUE;
                    851: }
                    852: 
                    853: static JSBool
                    854: js_sent_email(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    855: {
                    856:        private_t*      p;
                    857:        int32   count=1;
                    858:        BOOL    feedback=FALSE;
                    859: 
                    860:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                    861:                return JS_FALSE;
                    862: 
                    863:        if(argc)
                    864:                JS_ValueToInt32(cx, argv[0], &count);
                    865:        if(argc>1)
                    866:                JS_ValueToBoolean(cx, argv[1], &feedback);
                    867: 
                    868:        js_getuserdat(p);
                    869: 
                    870:        *rval = BOOLEAN_TO_JSVAL(user_sent_email(p->cfg, &p->user, count, feedback));
                    871: 
                    872:        return JS_TRUE;
                    873: }
                    874: 
                    875: static JSBool
                    876: js_downloaded_file(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    877: {
                    878:        private_t*      p;
                    879:        int32   files=1;
                    880:        int32   bytes=0;
                    881: 
                    882:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                    883:                return JS_FALSE;
                    884: 
                    885:        if(argc)
                    886:                JS_ValueToInt32(cx, argv[0], &bytes);
                    887:        if(argc>1)
                    888:                JS_ValueToInt32(cx, argv[1], &files);
                    889: 
                    890:        js_getuserdat(p);
                    891: 
                    892:        *rval = BOOLEAN_TO_JSVAL(user_downloaded(p->cfg, &p->user, files, bytes));
                    893: 
                    894:        return JS_TRUE;
                    895: }
                    896: 
                    897: static JSBool
                    898: js_uploaded_file(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    899: {
                    900:        private_t*      p;
                    901:        int32   files=1;
                    902:        int32   bytes=0;
                    903: 
                    904:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                    905:                return JS_FALSE;
                    906: 
                    907:        if(argc)
                    908:                JS_ValueToInt32(cx, argv[0], &bytes);
                    909:        if(argc>1)
                    910:                JS_ValueToInt32(cx, argv[1], &files);
                    911: 
                    912:        js_getuserdat(p);
                    913: 
                    914:        *rval = BOOLEAN_TO_JSVAL(user_uploaded(p->cfg, &p->user, files, bytes));
                    915: 
                    916:        return JS_TRUE;
                    917: }
                    918: 
                    919: static JSBool
                    920: js_adjust_credits(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    921: {
                    922:        private_t*      p;
                    923:        int32   count=0;
                    924: 
                    925:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                    926:                return JS_FALSE;
                    927: 
                    928:        if(argc)
                    929:                JS_ValueToInt32(cx, argv[0], &count);
                    930: 
                    931:        js_getuserdat(p);
                    932: 
                    933:        *rval = BOOLEAN_TO_JSVAL(user_adjust_credits(p->cfg, &p->user, count));
                    934: 
                    935:        return JS_TRUE;
                    936: }
                    937: 
                    938: static JSBool
                    939: js_adjust_minutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    940: {
                    941:        private_t*      p;
                    942:        int32   count=0;
                    943: 
                    944:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                    945:                return JS_FALSE;
                    946: 
                    947:        if(argc)
                    948:                JS_ValueToInt32(cx, argv[0], &count);
                    949: 
                    950:        js_getuserdat(p);
                    951: 
                    952:        *rval = BOOLEAN_TO_JSVAL(user_adjust_minutes(p->cfg, &p->user, count));
                    953: 
                    954:        return JS_TRUE;
                    955: }
                    956: 
                    957: static jsSyncMethodSpec js_user_functions[] = {
                    958:        {"compare_ars",         js_chk_ar,                      1,      JSTYPE_BOOLEAN, JSDOCSTR("string ars")
                    959:        ,JSDOCSTR("Verify user meets access requirements string")
                    960:        ,310
                    961:        },              
                    962:        {"adjust_credits",      js_adjust_credits,      1,      JSTYPE_BOOLEAN, JSDOCSTR("count")
                    963:        ,JSDOCSTR("Adjust user's credits by <i>count</i> (negative to subtract)")
                    964:        ,314
                    965:        },              
                    966:        {"adjust_minutes",      js_adjust_minutes,      1,      JSTYPE_BOOLEAN, JSDOCSTR("count")
                    967:        ,JSDOCSTR("Adjust user's extra minutes <i>count</i> (negative to subtract)")
                    968:        ,314
                    969:        },              
                    970:        {"posted_message",      js_posted_msg,          1,      JSTYPE_BOOLEAN, JSDOCSTR("[count]")
                    971:        ,JSDOCSTR("Adjust user's posted-messages statistics by <i>count</i> (default: 1) (negative to subtract)")
                    972:        ,314
                    973:        },              
                    974:        {"sent_email",          js_sent_email,          1,      JSTYPE_BOOLEAN, JSDOCSTR("[count] [,bool feedback]")
                    975:        ,JSDOCSTR("Adjust user's email/feedback-sent statistics by <i>count</i> (default: 1) (negative to subtract)")
                    976:        ,314
                    977:        },              
                    978:        {"uploaded_file",       js_uploaded_file,       1,      JSTYPE_BOOLEAN, JSDOCSTR("[bytes] [,files]")
                    979:        ,JSDOCSTR("Adjust user's files/bytes-uploaded statistics")
                    980:        ,314
                    981:        },              
                    982:        {"downloaded_file",     js_downloaded_file,     1,      JSTYPE_BOOLEAN, JSDOCSTR("[bytes] [,files]")
                    983:        ,JSDOCSTR("Adjust user's files/bytes-downloaded statistics")
                    984:        ,314
                    985:        },              
                    986:        {0}
                    987: };
                    988: 
                    989: static JSClass js_user_class = {
                    990:      "User"                                    /* name                 */
                    991:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                    992:        ,JS_PropertyStub                /* addProperty  */
                    993:        ,JS_PropertyStub                /* delProperty  */
                    994:        ,js_user_get                    /* getProperty  */
                    995:        ,js_user_set                    /* setProperty  */
                    996:        ,JS_EnumerateStub               /* enumerate    */
                    997:        ,JS_ResolveStub                 /* resolve              */
                    998:        ,JS_ConvertStub                 /* convert              */
                    999:        ,js_user_finalize               /* finalize             */
                   1000: };
                   1001: 
                   1002: static JSClass js_user_stats_class = {
                   1003:      "UserStats"                       /* name                 */
                   1004:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                   1005:        ,JS_PropertyStub                /* addProperty  */
                   1006:        ,JS_PropertyStub                /* delProperty  */
                   1007:        ,js_user_get                    /* getProperty  */
                   1008:        ,js_user_set                    /* setProperty  */
                   1009:        ,JS_EnumerateStub               /* enumerate    */
                   1010:        ,JS_ResolveStub                 /* resolve              */
                   1011:        ,JS_ConvertStub                 /* convert              */
                   1012:        ,JS_FinalizeStub        /* finalize             */
                   1013: };
                   1014: 
                   1015: static JSClass js_user_security_class = {
                   1016:      "UserSecurity"                    /* name                 */
                   1017:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                   1018:        ,JS_PropertyStub                /* addProperty  */
                   1019:        ,JS_PropertyStub                /* delProperty  */
                   1020:        ,js_user_get                    /* getProperty  */
                   1021:        ,js_user_set                    /* setProperty  */
                   1022:        ,JS_EnumerateStub               /* enumerate    */
                   1023:        ,JS_ResolveStub                 /* resolve              */
                   1024:        ,JS_ConvertStub                 /* convert              */
                   1025:        ,JS_FinalizeStub        /* finalize             */
                   1026: };
                   1027: 
                   1028: static JSClass js_user_limits_class = {
                   1029:      "UserLimits"                      /* name                 */
                   1030:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                   1031:        ,JS_PropertyStub                /* addProperty  */
                   1032:        ,JS_PropertyStub                /* delProperty  */
                   1033:        ,js_user_get                    /* getProperty  */
                   1034:        ,js_user_set                    /* setProperty  */
                   1035:        ,JS_EnumerateStub               /* enumerate    */
                   1036:        ,JS_ResolveStub                 /* resolve              */
                   1037:        ,JS_ConvertStub                 /* convert              */
                   1038:        ,JS_FinalizeStub        /* finalize             */
                   1039: };
                   1040: 
                   1041: /* User Constructor (creates instance of user class) */
                   1042: 
                   1043: static JSBool
                   1044: js_user_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1045: {
                   1046:        int                     i;
                   1047:        int32           val=0;
                   1048:        user_t          user;
                   1049:        private_t*      p;
                   1050:        JSObject*       statsobj;
                   1051:        JSObject*       securityobj;
                   1052:        JSObject*       limitsobj;
                   1053: 
                   1054:        JS_ValueToInt32(cx,argv[0],&val);
                   1055:        user.number=(ushort)val;
                   1056:        if(user.number!=0 && (i=getuserdat(scfg,&user))!=0) {
                   1057:                JS_ReportError(cx,"Error %d reading user number %d",i,val);
                   1058:                return(JS_FALSE);
                   1059:        }
                   1060: 
                   1061:        /* user.stats */
                   1062:        if((statsobj=JS_DefineObject(cx, obj, "stats"
                   1063:                ,&js_user_stats_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL) 
                   1064:                return(JS_FALSE);
                   1065: 
                   1066:        if(!js_DefineSyncProperties(cx, statsobj, js_user_stats_properties))
                   1067:                return(JS_FALSE);
                   1068: 
                   1069:        /* user.security */
                   1070:        if((securityobj=JS_DefineObject(cx, obj, "security"
                   1071:                ,&js_user_security_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL) 
                   1072:                return(JS_FALSE);
                   1073: 
                   1074:        if(!js_DefineSyncProperties(cx, securityobj, js_user_security_properties))
                   1075:                return(JS_FALSE);
                   1076: 
                   1077:        /* user.limits */
                   1078:        if((limitsobj=JS_DefineObject(cx, obj, "limits"
                   1079:                ,&js_user_limits_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY))==NULL) 
                   1080:                return(JS_FALSE);
                   1081: 
                   1082:        if(!js_DefineSyncProperties(cx, limitsobj, js_user_limits_properties))
                   1083:                return(JS_FALSE);
                   1084: 
                   1085:        /* other user properties */
                   1086:        if(!js_DefineSyncProperties(cx, obj, js_user_properties))
                   1087:                return(JS_FALSE);
                   1088: 
                   1089:        if((p=(private_t*)malloc(sizeof(private_t)))==NULL)
                   1090:                return(JS_FALSE);
                   1091: 
                   1092:        p->cfg = scfg;
                   1093:        p->user = user;
                   1094:        p->cached = (user.number==0 ? FALSE : TRUE);
                   1095: 
                   1096:        JS_SetPrivate(cx, obj, p);      /* Must do this before calling js_DefineSyncMethods() */
                   1097: 
                   1098:        if(!js_DefineSyncMethods(cx, obj, js_user_functions, FALSE)) {
                   1099:                JS_SetPrivate(cx, obj, NULL);
                   1100:                free(p);
                   1101:                return(JS_FALSE);
                   1102:        }
                   1103: 
                   1104:        JS_SetPrivate(cx, statsobj, p);
                   1105:        JS_SetPrivate(cx, securityobj, p);
                   1106:        JS_SetPrivate(cx, limitsobj, p);
                   1107: 
                   1108:        return(JS_TRUE);
                   1109: }
                   1110: 
                   1111: JSObject* DLLCALL js_CreateUserClass(JSContext* cx, JSObject* parent, scfg_t* cfg)
                   1112: {
                   1113:        JSObject*       userclass;
                   1114: 
                   1115:        scfg = cfg;
                   1116:        userclass = JS_InitClass(cx, parent, NULL
                   1117:                ,&js_user_class
                   1118:                ,js_user_constructor
                   1119:                ,1      /* number of constructor args */
                   1120:                ,NULL /* props, defined in constructor */
                   1121:                ,NULL /* funcs, defined in constructor */
                   1122:                ,NULL,NULL);
                   1123: 
                   1124:        return(userclass);
                   1125: }
                   1126: 
                   1127: JSObject* DLLCALL js_CreateUserObject(JSContext* cx, JSObject* parent, scfg_t* cfg, char* name
                   1128:                                                                          , uint usernumber)
                   1129: {
                   1130:        JSObject*       userobj;
                   1131:        JSObject*       statsobj;
                   1132:        JSObject*       limitsobj;
                   1133:        JSObject*       securityobj;
                   1134:        private_t*      p;
                   1135:        jsval           val;
                   1136: 
                   1137:        if(name==NULL)
                   1138:            userobj = JS_NewObject(cx, &js_user_class, NULL, parent);
                   1139:        else if(JS_GetProperty(cx,parent,name,&val) && val!=JSVAL_VOID)
                   1140:                userobj = JSVAL_TO_OBJECT(val); /* Return existing user object */
                   1141:        else
                   1142:                userobj = JS_DefineObject(cx, parent, name, &js_user_class
                   1143:                                                                , NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
                   1144:        if(userobj==NULL)
                   1145:                return(NULL);
                   1146: 
                   1147:        if((p=JS_GetPrivate(cx, userobj)) == NULL)      /* Uses existing private pointer: Fix memory leak? */
                   1148:                if((p=(private_t*)malloc(sizeof(private_t)))==NULL)
                   1149:                        return(NULL);
                   1150: 
                   1151:        p->cfg = cfg;
                   1152:        p->user.number = usernumber;
                   1153:        p->cached = FALSE;
                   1154: 
                   1155:        JS_SetPrivate(cx, userobj, p);  
                   1156: 
                   1157:        if(!js_DefineSyncProperties(cx, userobj, js_user_properties)) {
                   1158:                free(p);
                   1159:                return(NULL);
                   1160:        }
                   1161: 
                   1162: #ifdef BUILD_JSDOCS
                   1163:        js_DescribeSyncObject(cx,userobj
                   1164:                ,"Instance of <i>User</i> class, representing current user online"
                   1165:                ,310);
                   1166:        js_DescribeSyncConstructor(cx,userobj
                   1167:                ,"To create a new user object: <tt>var u = new User(<i>number</i>)</tt>");
                   1168:        js_CreateArrayOfStrings(cx, userobj
                   1169:                ,"_property_desc_list", user_prop_desc, JSPROP_READONLY);
                   1170: #endif
                   1171: 
                   1172:        js_DefineSyncMethods(cx, userobj, js_user_functions, FALSE);
                   1173: 
                   1174:        /* user.stats */
                   1175:        statsobj = JS_DefineObject(cx, userobj, "stats"
                   1176:                ,&js_user_stats_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
                   1177: 
                   1178:        if(statsobj==NULL) {
                   1179:                free(p);
                   1180:                return(NULL);
                   1181:        }
                   1182: 
                   1183:        JS_SetPrivate(cx, statsobj, p);
                   1184: 
                   1185:        if(!js_DefineSyncProperties(cx, statsobj, js_user_stats_properties)) {
                   1186:                free(p);
                   1187:                return(NULL);
                   1188:        }
                   1189: 
                   1190: #ifdef BUILD_JSDOCS
                   1191:        js_DescribeSyncObject(cx,statsobj,"User statistics (all <small>READ ONLY</small>)",310);
                   1192:        js_CreateArrayOfStrings(cx, statsobj, "_property_desc_list", user_stats_prop_desc, JSPROP_READONLY);
                   1193: #endif
                   1194: 
                   1195:        /* user.limits */
                   1196:        limitsobj = JS_DefineObject(cx, userobj, "limits"
                   1197:                ,&js_user_limits_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
                   1198: 
                   1199:        if(limitsobj==NULL) {
                   1200:                free(p);
                   1201:                return(NULL);
                   1202:        }
                   1203: 
                   1204:        JS_SetPrivate(cx, limitsobj, p);
                   1205: 
                   1206:        if(!js_DefineSyncProperties(cx, limitsobj, js_user_limits_properties)) {
                   1207:                free(p);
                   1208:                return(NULL);
                   1209:        }
                   1210: 
                   1211: #ifdef BUILD_JSDOCS
                   1212:        js_DescribeSyncObject(cx,limitsobj,"User limitations based on security level (all <small>READ ONLY</small>)",311);
                   1213:        js_CreateArrayOfStrings(cx, limitsobj, "_property_desc_list", user_limits_prop_desc, JSPROP_READONLY);
                   1214: #endif
                   1215: 
                   1216: 
                   1217:        /* user.security */
                   1218:        securityobj = JS_DefineObject(cx, userobj, "security"
                   1219:                ,&js_user_security_class, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
                   1220: 
                   1221:        if(securityobj==NULL) {
                   1222:                free(p);
                   1223:                return(NULL);
                   1224:        }
                   1225: 
                   1226:        JS_SetPrivate(cx, securityobj, p);
                   1227: 
                   1228:        if(!js_DefineSyncProperties(cx, securityobj, js_user_security_properties)) {
                   1229:                free(p);
                   1230:                return(NULL);
                   1231:        }
                   1232: 
                   1233: #ifdef BUILD_JSDOCS
                   1234:        js_DescribeSyncObject(cx,securityobj,"User security settings",310);
                   1235:        js_CreateArrayOfStrings(cx, securityobj, "_property_desc_list", user_security_prop_desc, JSPROP_READONLY);
                   1236: #endif
                   1237: 
                   1238:        return(userobj);
                   1239: }
                   1240: 
                   1241: /****************************************************************************/
                   1242: /* Creates all the user-specific objects: user, msg_area, file_area                    */
                   1243: /****************************************************************************/
                   1244: JSBool DLLCALL
                   1245: js_CreateUserObjects(JSContext* cx, JSObject* parent, scfg_t* cfg, user_t* user
                   1246:                                         ,char* html_index_file, subscan_t* subscan)
                   1247: {
                   1248:        if(js_CreateUserObject(cx,parent,cfg,"user",user==NULL ? 0 : user->number)==NULL)
                   1249:                return(JS_FALSE);
                   1250:        if(js_CreateFileAreaObject(cx,parent,cfg,user,html_index_file)==NULL) 
                   1251:                return(JS_FALSE);
                   1252:        if(js_CreateMsgAreaObject(cx,parent,cfg,user,subscan)==NULL) 
                   1253:                return(JS_FALSE);
                   1254:        if(js_CreateXtrnAreaObject(cx,parent,cfg,user)==NULL)
                   1255:                return(JS_FALSE);
                   1256: 
                   1257:        return(JS_TRUE);
                   1258: }
                   1259: 
                   1260: #endif /* JAVSCRIPT */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.