Annotation of sbbs/src/sbbs3/js_bbs.cpp, revision 1.1.1.2

1.1       root        1: /* js_bbs.cpp */
                      2: 
                      3: /* Synchronet JavaScript "bbs" Object */
                      4: 
1.1.1.2 ! root        5: /* $Id: js_bbs.cpp,v 1.118 2011/08/25 19:22:44 rswindell Exp $ */
1.1       root        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:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2009 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       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"
1.1.1.2 ! root       39: #include "js_request.h"
1.1       root       40: 
                     41: #ifdef JAVASCRIPT
                     42: 
                     43: /*****************************/
                     44: /* BBS Object Properites */
                     45: /*****************************/
                     46: enum {
                     47:         BBS_PROP_SYS_STATUS
                     48:        ,BBS_PROP_STARTUP_OPT
                     49:        ,BBS_PROP_ANSWER_TIME
                     50:        ,BBS_PROP_LOGON_TIME
                     51:        ,BBS_PROP_START_TIME
                     52:        ,BBS_PROP_NS_TIME
                     53:        ,BBS_PROP_LAST_NS_TIME
                     54:        ,BBS_PROP_ONLINE
                     55:        ,BBS_PROP_TIMELEFT
                     56:        ,BBS_PROP_EVENT_TIME
                     57:        ,BBS_PROP_EVENT_CODE
                     58: 
                     59:        ,BBS_PROP_NODE_NUM
                     60:        ,BBS_PROP_NODE_MISC
                     61:        ,BBS_PROP_NODE_ACTION
                     62:        ,BBS_PROP_NODE_VAL_USER
                     63: 
                     64:        ,BBS_PROP_LOGON_ULB
                     65:        ,BBS_PROP_LOGON_DLB
                     66:        ,BBS_PROP_LOGON_ULS
                     67:        ,BBS_PROP_LOGON_DLS
                     68:        ,BBS_PROP_LOGON_POSTS
                     69:        ,BBS_PROP_LOGON_EMAILS
                     70:        ,BBS_PROP_LOGON_FBACKS
                     71:        ,BBS_PROP_POSTS_READ
                     72: 
                     73:        ,BBS_PROP_MENU_DIR
                     74:        ,BBS_PROP_MENU_FILE
                     75:        ,BBS_PROP_MAIN_CMDS
                     76:        ,BBS_PROP_FILE_CMDS
                     77: 
                     78:        ,BBS_PROP_CURGRP
                     79:        ,BBS_PROP_CURSUB
                     80:        ,BBS_PROP_CURSUB_CODE
                     81:        ,BBS_PROP_CURLIB
                     82:        ,BBS_PROP_CURDIR
                     83:        ,BBS_PROP_CURDIR_CODE
                     84: 
                     85:        ,BBS_PROP_CONNECTION            /* READ ONLY */
                     86:        ,BBS_PROP_RLOGIN_NAME
1.1.1.2 ! root       87:        ,BBS_PROP_RLOGIN_PASS
1.1       root       88:        ,BBS_PROP_CLIENT_NAME
                     89: 
                     90:        ,BBS_PROP_ALTUL
                     91: 
                     92:        ,BBS_PROP_ERRORLEVEL            /* READ ONLY */
                     93: 
                     94:        /* READ ONLY */
                     95:        ,BBS_PROP_SMB_GROUP             
                     96:        ,BBS_PROP_SMB_GROUP_DESC
                     97:        ,BBS_PROP_SMB_GROUP_NUM
                     98:        ,BBS_PROP_SMB_SUB
                     99:        ,BBS_PROP_SMB_SUB_DESC
                    100:        ,BBS_PROP_SMB_SUB_CODE
                    101:        ,BBS_PROP_SMB_SUB_NUM
                    102:        ,BBS_PROP_SMB_ATTR
                    103:        ,BBS_PROP_SMB_LAST_MSG
                    104:        ,BBS_PROP_SMB_TOTAL_MSGS
                    105:        ,BBS_PROP_SMB_MSGS
                    106:        ,BBS_PROP_SMB_CURMSG
                    107: 
                    108:        /* READ ONLY */
                    109:        ,BBS_PROP_MSG_TO
                    110:        ,BBS_PROP_MSG_TO_EXT
                    111:        ,BBS_PROP_MSG_TO_NET
                    112:        ,BBS_PROP_MSG_TO_AGENT
                    113:        ,BBS_PROP_MSG_FROM
                    114:        ,BBS_PROP_MSG_FROM_EXT
                    115:        ,BBS_PROP_MSG_FROM_NET
                    116:        ,BBS_PROP_MSG_FROM_AGENT
                    117:        ,BBS_PROP_MSG_REPLYTO
                    118:        ,BBS_PROP_MSG_REPLYTO_EXT
                    119:        ,BBS_PROP_MSG_REPLYTO_NET
                    120:        ,BBS_PROP_MSG_REPLYTO_AGENT
                    121:        ,BBS_PROP_MSG_SUBJECT
                    122:        ,BBS_PROP_MSG_DATE
                    123:        ,BBS_PROP_MSG_TIMEZONE
                    124:        ,BBS_PROP_MSG_DATE_IMPORTED
                    125:        ,BBS_PROP_MSG_ATTR
                    126:        ,BBS_PROP_MSG_AUXATTR
                    127:        ,BBS_PROP_MSG_NETATTR
                    128:        ,BBS_PROP_MSG_OFFSET
                    129:        ,BBS_PROP_MSG_NUMBER
                    130:        ,BBS_PROP_MSG_EXPIRATION
                    131:        ,BBS_PROP_MSG_FORWARDED
                    132:        ,BBS_PROP_MSG_THREAD_BACK
                    133:        ,BBS_PROP_MSG_THREAD_NEXT
                    134:        ,BBS_PROP_MSG_THREAD_FIRST
                    135:        ,BBS_PROP_MSG_ID
                    136:        ,BBS_PROP_MSG_REPLY_ID
                    137:        ,BBS_PROP_MSG_DELIVERY_ATTEMPTS
                    138: 
                    139:        /* READ ONLY */
                    140:        ,BBS_PROP_BATCH_UPLOAD_TOTAL
                    141:        ,BBS_PROP_BATCH_DNLOAD_TOTAL
                    142: 
                    143:        ,BBS_PROP_COMMAND_STR
                    144: };
                    145: 
                    146: #ifdef BUILD_JSDOCS
                    147:        static char* bbs_prop_desc[] = {
                    148:         "system status bitfield (see <tt>SS_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
                    149:        ,"startup options bitfield (see <tt>BBS_OPT_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
                    150:        ,"answer time, in <i>time_t</i> format"
                    151:        ,"logon time, in <i>time_t</i> format"
                    152:        ,"time from which user's time left is calculated, in <i>time_t</i> format"
                    153:        ,"current file new-scan time, in <i>time_t</i> format"
                    154:        ,"previous file new-scan time, in <i>time_t</i> format"
                    155:        ,"online (see <tt>ON_*</tt> in <tt>sbbsdefs.js</tt> for valid values)"
                    156:        ,"time left (in seconds)"
                    157:        ,"time of next exclusive event (in <i>time_t</i> format), or 0 if none"
                    158:        ,"internal code of next exclusive event"
                    159: 
                    160:        ,"current node number"
                    161:        ,"current node settings bitfield (see <tt>NM_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
                    162:        ,"current node action (see <tt>nodedefs.js</tt> for valid values)"
                    163:        ,"validation feedback user for this node (or 0 for no validation feedback required)"
                    164: 
                    165:        ,"bytes uploaded during this session"
                    166:        ,"bytes downloaded during this session"
                    167:        ,"files uploaded during this session"
                    168:        ,"files downloaded during this session"
                    169:        ,"messages posted during this session"
                    170:        ,"e-mails sent during this session"
                    171:        ,"feedback messages sent during this session"
                    172:        ,"messages read during this session"
                    173: 
                    174:        ,"menu subdirectory (overrides default)"
                    175:        ,"menu file (overrides default)"
                    176:        ,"total main menu commands received from user during this session"
                    177:        ,"total file menu commands received from user during this session"
                    178: 
                    179:        ,"current message group"
                    180:        ,"current message sub-board"
                    181:        ,"current message sub-board internal code"
                    182:        ,"current file library"
                    183:        ,"current file directory"
                    184:        ,"current file directory internal code"
                    185: 
                    186:        ,"remote connection type"
1.1.1.2 ! root      187:        ,"login name given during RLogin negotiation"
        !           188:        ,"password specified during RLogin negotiation"
1.1       root      189:        ,"client name"
                    190: 
                    191:        ,"current alternate upload path number"
                    192: 
                    193:        ,"error level returned from last executed external program"
                    194: 
                    195:        /* READ ONLY */
                    196:        ,"message group name of message being read"
                    197:        ,"message group description of message being read"
                    198:        ,"message group number of message being read"
                    199:        ,"sub-board name of message being read"
                    200:        ,"sub-board description of message being read"
                    201:        ,"sub-board internal code of message being read"
                    202:        ,"sub-board number of message being read"
                    203:        ,"message base attributes"
                    204:        ,"highest message number in message base"
                    205:        ,"total number of messages in message base"
                    206:        ,"number of messages loaded from message base"
                    207:        ,"current message number in message base"
                    208: 
                    209:        /* READ ONLY */
                    210:        ,"message recipient name"
                    211:        ,"message recipient extension"
                    212:        ,"message recipient network type"
                    213:        ,"message recipient agent type"
                    214:        ,"message sender name"
                    215:        ,"message sender extension"
                    216:        ,"message sender network type"
                    217:        ,"message sender agent type"
                    218:        ,"message reply-to name"
                    219:        ,"message reply-to extension"
                    220:        ,"message reply-to network type"
                    221:        ,"message reply-to agent type"
                    222:        ,"message subject"
                    223:        ,"message date/time"
                    224:        ,"message time zone"
                    225:        ,"message date/time imported"
                    226:        ,"message attributes"
                    227:        ,"message auxillary attributes"
                    228:        ,"message network attributes"
                    229:        ,"message header offset"
                    230:        ,"message number"
                    231:        ,"message expiration"
                    232:        ,"message forwarded"
                    233:        ,"message thread, back message number (AKA msg_thread_orig)"
                    234:        ,"message thread, next message number"
                    235:        ,"message thread, first reply to this message"
                    236:        ,"message identifier"
                    237:        ,"message replied-to identifier"
                    238:        ,"message delivery attempt counter"
                    239: 
                    240:        ,"number of files in batch upload queue"
                    241:        ,"number of files in batch download queue"
                    242: 
                    243:        ,"current command shell/module <i>command string</i> value"
                    244:        ,NULL
                    245:        };
                    246: #endif
                    247: 
                    248: static JSBool js_bbs_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                    249: {
1.1.1.2 ! root      250:        char            tmp[128];
        !           251:        const char*     p=NULL;
        !           252:        const char*     nulstr="";
1.1       root      253:        ulong           val=0;
                    254:     jsint       tiny;
                    255:        sbbs_t*         sbbs;
1.1.1.2 ! root      256:        jsrefcount      rc;
1.1       root      257: 
                    258:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                    259:                return(JS_FALSE);
                    260: 
                    261:     tiny = JSVAL_TO_INT(id);
                    262: 
                    263:        switch(tiny) {
                    264:                case BBS_PROP_SYS_STATUS:
                    265:                        val=sbbs->sys_status;
                    266:                        break;
                    267:                case BBS_PROP_STARTUP_OPT:
                    268:                        val=sbbs->startup->options;
                    269:                        break;
                    270:                case BBS_PROP_ANSWER_TIME:
                    271:                        val=sbbs->answertime;
                    272:                        break;
                    273:                case BBS_PROP_LOGON_TIME:
                    274:                        val=sbbs->logontime;
                    275:                        break;
                    276:                case BBS_PROP_START_TIME:
                    277:                        val=sbbs->starttime;
                    278:                        break;
                    279:                case BBS_PROP_NS_TIME:
                    280:                        val=sbbs->ns_time;
                    281:                        break;
                    282:                case BBS_PROP_LAST_NS_TIME:
                    283:                        val=sbbs->last_ns_time;
                    284:                        break;
                    285:                case BBS_PROP_ONLINE:
                    286:                        val=sbbs->online;
                    287:                        break;
                    288:                case BBS_PROP_TIMELEFT:
1.1.1.2 ! root      289:                        rc=JS_SUSPENDREQUEST(cx);
        !           290:                        val=sbbs->gettimeleft(false);
        !           291:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      292:                        break;
                    293:                case BBS_PROP_EVENT_TIME:
                    294:                        val=sbbs->event_time;
                    295:                        break;
                    296:                case BBS_PROP_EVENT_CODE:
                    297:                        p=sbbs->event_code;
                    298:                        break;
                    299: 
                    300:                case BBS_PROP_NODE_NUM:
                    301:                        val=sbbs->cfg.node_num;
                    302:                        break;
                    303:                case BBS_PROP_NODE_MISC:
                    304:                        val=sbbs->cfg.node_misc;
                    305:                        break;
                    306:                case BBS_PROP_NODE_ACTION:
                    307:                        val=sbbs->action;
                    308:                        break;
                    309:                case BBS_PROP_NODE_VAL_USER:
                    310:                        val=sbbs->cfg.node_valuser;
                    311:                        break;
                    312: 
                    313:                case BBS_PROP_LOGON_ULB:
                    314:                        val=sbbs->logon_ulb;
                    315:                        break;
                    316:                case BBS_PROP_LOGON_DLB:
                    317:                        val=sbbs->logon_dlb;
                    318:                        break;
                    319:                case BBS_PROP_LOGON_ULS:
                    320:                        val=sbbs->logon_uls;
                    321:                        break;
                    322:                case BBS_PROP_LOGON_DLS:
                    323:                        val=sbbs->logon_dls;
                    324:                        break;
                    325:                case BBS_PROP_LOGON_POSTS:
                    326:                        val=sbbs->logon_posts;
                    327:                        break;
                    328:                case BBS_PROP_LOGON_EMAILS:
                    329:                        val=sbbs->logon_emails;
                    330:                        break;
                    331:                case BBS_PROP_LOGON_FBACKS:
                    332:                        val=sbbs->logon_fbacks;
                    333:                        break;
                    334:                case BBS_PROP_POSTS_READ:
                    335:                        val=sbbs->posts_read;
                    336:                        break;
                    337: 
                    338:                case BBS_PROP_MENU_DIR:
                    339:                        p=sbbs->menu_dir;
                    340:                        break;
                    341:                case BBS_PROP_MENU_FILE:
                    342:                        p=sbbs->menu_file;
                    343:                        break;
                    344:                case BBS_PROP_MAIN_CMDS:
                    345:                        val=sbbs->main_cmds;
                    346:                        break;
                    347:                case BBS_PROP_FILE_CMDS:
                    348:                        val=sbbs->xfer_cmds;
                    349:                        break;
                    350: 
                    351:                case BBS_PROP_CURGRP:
                    352:                        val=sbbs->curgrp;
                    353:                        break;
                    354:                case BBS_PROP_CURSUB:
                    355:                        if(sbbs->curgrp<sbbs->usrgrps)
                    356:                                val=sbbs->cursub[sbbs->curgrp];
                    357:                        break;
                    358:                case BBS_PROP_CURSUB_CODE:
                    359:                        if(sbbs->cursubnum<sbbs->cfg.total_subs)
                    360:                                p=sbbs->cfg.sub[sbbs->cursubnum]->code;
                    361:                        break;
                    362: 
                    363:                case BBS_PROP_CURLIB:
                    364:                        val=sbbs->curlib;
                    365:                        break;
                    366:                case BBS_PROP_CURDIR:
                    367:                        if(sbbs->curlib<sbbs->usrlibs)
                    368:                                val=sbbs->curdir[sbbs->curlib];
                    369:                        break;
                    370:                case BBS_PROP_CURDIR_CODE:
                    371:                        if(sbbs->curdirnum<sbbs->cfg.total_dirs)
                    372:                                p=sbbs->cfg.dir[sbbs->curdirnum]->code;
                    373:                        break;
                    374: 
                    375:                case BBS_PROP_CONNECTION:
                    376:                        p=sbbs->connection;
                    377:                        break;
                    378:                case BBS_PROP_RLOGIN_NAME:
                    379:                        p=sbbs->rlogin_name;
                    380:                        break;
1.1.1.2 ! root      381:                case BBS_PROP_RLOGIN_PASS:
        !           382:                        p=sbbs->rlogin_pass;
        !           383:                        break;
1.1       root      384:                case BBS_PROP_CLIENT_NAME:
                    385:                        p=sbbs->client_name;
                    386:                        break;
                    387: 
                    388:                case BBS_PROP_ALTUL:
                    389:                        val=sbbs->altul;
                    390:                        break;
                    391: 
                    392:                case BBS_PROP_ERRORLEVEL:
                    393:                        val=sbbs->errorlevel;
                    394:                        break;
                    395: 
                    396:                /* Currently Open Message Base (sbbs.smb) */
                    397:                case BBS_PROP_SMB_GROUP:
                    398:                        if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
                    399:                                p=nulstr;
                    400:                        else
                    401:                                p=sbbs->cfg.grp[sbbs->cfg.sub[sbbs->smb.subnum]->grp]->sname;
                    402:                        break;
                    403:                case BBS_PROP_SMB_GROUP_DESC:
                    404:                        if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
                    405:                                p=nulstr;
                    406:                        else
                    407:                                p=sbbs->cfg.grp[sbbs->cfg.sub[sbbs->smb.subnum]->grp]->lname;
                    408:                        break;
                    409:                case BBS_PROP_SMB_GROUP_NUM:
                    410:                        if(sbbs->smb.subnum!=INVALID_SUB && sbbs->smb.subnum<sbbs->cfg.total_subs) {
                    411:                                uint ugrp;
                    412:                                for(ugrp=0;ugrp<sbbs->usrgrps;ugrp++)
                    413:                                        if(sbbs->usrgrp[ugrp]==sbbs->cfg.sub[sbbs->smb.subnum]->grp)
                    414:                                                break;
                    415:                                val=ugrp+1;
                    416:                        }
                    417:                        break;
                    418:                case BBS_PROP_SMB_SUB:
                    419:                        if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
                    420:                                p=nulstr;
                    421:                        else
                    422:                                p=sbbs->cfg.sub[sbbs->smb.subnum]->sname;
                    423:                        break;
                    424:                case BBS_PROP_SMB_SUB_DESC:
                    425:                        if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
                    426:                                p=nulstr;
                    427:                        else
                    428:                                p=sbbs->cfg.sub[sbbs->smb.subnum]->lname;
                    429:                        break;
                    430:                case BBS_PROP_SMB_SUB_CODE:
                    431:                        if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
                    432:                                p=nulstr;
                    433:                        else
                    434:                                p=sbbs->cfg.sub[sbbs->smb.subnum]->code;
                    435:                        break;
                    436:                case BBS_PROP_SMB_SUB_NUM:
                    437:                        if(sbbs->smb.subnum!=INVALID_SUB && sbbs->smb.subnum<sbbs->cfg.total_subs) {
                    438:                                uint ugrp;
                    439:                                for(ugrp=0;ugrp<sbbs->usrgrps;ugrp++)
                    440:                                        if(sbbs->usrgrp[ugrp]==sbbs->cfg.sub[sbbs->smb.subnum]->grp)
                    441:                                                break;
                    442:                                uint usub;
                    443:                                for(usub=0;usub<sbbs->usrsubs[ugrp];usub++)
                    444:                                        if(sbbs->usrsub[ugrp][usub]==sbbs->smb.subnum)
                    445:                                                break;
                    446:                                val=usub+1;
                    447:                        }
                    448:                        break;
                    449:                case BBS_PROP_SMB_ATTR:
                    450:                        val=sbbs->smb.status.attr;
                    451:                        break;
                    452:                case BBS_PROP_SMB_LAST_MSG:
                    453:                        val=sbbs->smb.status.last_msg;
                    454:                        break;
                    455:                case BBS_PROP_SMB_TOTAL_MSGS:
                    456:                        val=sbbs->smb.status.total_msgs;
                    457:                        break;
                    458:                case BBS_PROP_SMB_MSGS:
                    459:                        val=sbbs->smb.msgs;
                    460:                        break;
                    461:                case BBS_PROP_SMB_CURMSG:
                    462:                        val=sbbs->smb.curmsg;
                    463:                        break;
                    464: 
                    465:                /* Currently Displayed Message Header (sbbs.current_msg) */
                    466:                case BBS_PROP_MSG_TO:
                    467:                        if(sbbs->current_msg==NULL || sbbs->current_msg->to==NULL)
                    468:                                p=nulstr;
                    469:                        else
                    470:                                p=sbbs->current_msg->to;
                    471:                        break;
                    472:                case BBS_PROP_MSG_TO_EXT:
                    473:                        if(sbbs->current_msg==NULL || sbbs->current_msg->to_ext==NULL)
                    474:                                p=nulstr;
                    475:                        else
                    476:                                p=sbbs->current_msg->to_ext;
                    477:                        break;
                    478:                case BBS_PROP_MSG_TO_NET:
                    479:                        if(sbbs->current_msg==NULL || sbbs->current_msg->to_net.type==NET_NONE)
                    480:                                p=nulstr;
                    481:                        else
1.1.1.2 ! root      482:                                p=smb_netaddrstr(&sbbs->current_msg->to_net,tmp);
1.1       root      483:                        break;
                    484:                case BBS_PROP_MSG_TO_AGENT:
                    485:                        if(sbbs->current_msg!=NULL)
                    486:                                val=sbbs->current_msg->to_agent;
                    487:                        break;
                    488:                case BBS_PROP_MSG_FROM:
                    489:                        if(sbbs->current_msg==NULL || sbbs->current_msg->from==NULL)
                    490:                                p=nulstr;
                    491:                        else
                    492:                                p=sbbs->current_msg->from;
                    493:                        break;
                    494:                case BBS_PROP_MSG_FROM_EXT:
                    495:                        if(sbbs->current_msg==NULL || sbbs->current_msg->from_ext==NULL)
                    496:                                p=nulstr;
                    497:                        else
                    498:                                p=sbbs->current_msg->from_ext;
                    499:                        break;
                    500:                case BBS_PROP_MSG_FROM_NET:
                    501:                        if(sbbs->current_msg==NULL || sbbs->current_msg->from_net.type==NET_NONE)
                    502:                                p=nulstr;
                    503:                        else
1.1.1.2 ! root      504:                                p=smb_netaddrstr(&sbbs->current_msg->from_net,tmp);
1.1       root      505:                        break;
                    506:                case BBS_PROP_MSG_FROM_AGENT:
                    507:                        if(sbbs->current_msg!=NULL)
                    508:                                val=sbbs->current_msg->from_agent;
                    509:                        break;
                    510:                case BBS_PROP_MSG_REPLYTO:
                    511:                        if(sbbs->current_msg==NULL || sbbs->current_msg->replyto==NULL)
                    512:                                p=nulstr;
                    513:                        else
                    514:                                p=sbbs->current_msg->replyto;
                    515:                        break;
                    516:                case BBS_PROP_MSG_REPLYTO_EXT:
                    517:                        if(sbbs->current_msg==NULL || sbbs->current_msg->replyto_ext==NULL)
                    518:                                p=nulstr;
                    519:                        else
                    520:                                p=sbbs->current_msg->replyto_ext;
                    521:                        break;
                    522:                case BBS_PROP_MSG_REPLYTO_NET:
                    523:                        if(sbbs->current_msg==NULL || sbbs->current_msg->replyto_net.type==NET_NONE)
                    524:                                p=nulstr;
                    525:                        else
1.1.1.2 ! root      526:                                p=smb_netaddrstr(&sbbs->current_msg->replyto_net,tmp);
1.1       root      527:                        break;
                    528:                case BBS_PROP_MSG_REPLYTO_AGENT:
                    529:                        if(sbbs->current_msg!=NULL)
                    530:                                val=sbbs->current_msg->replyto_agent;
                    531:                        break;
                    532: 
                    533:                case BBS_PROP_MSG_SUBJECT:
                    534:                        if(sbbs->current_msg==NULL || sbbs->current_msg->subj==NULL)
                    535:                                p=nulstr;
                    536:                        else
                    537:                                p=sbbs->current_msg->subj;
                    538:                        break;
                    539:                case BBS_PROP_MSG_DATE:
                    540:                        if(sbbs->current_msg!=NULL)
                    541:                                val=sbbs->current_msg->hdr.when_written.time;
                    542:                        break;
                    543:                case BBS_PROP_MSG_TIMEZONE:
                    544:                        if(sbbs->current_msg!=NULL)
                    545:                                val=sbbs->current_msg->hdr.when_written.zone;
                    546:                        break;
                    547:                case BBS_PROP_MSG_DATE_IMPORTED:
                    548:                        if(sbbs->current_msg!=NULL)
                    549:                                val=sbbs->current_msg->hdr.when_imported.time;
                    550:                        break;
                    551:                case BBS_PROP_MSG_ATTR:
                    552:                        if(sbbs->current_msg!=NULL)
                    553:                                val=sbbs->current_msg->hdr.attr;
                    554:                        break;
                    555:                case BBS_PROP_MSG_AUXATTR:
                    556:                        if(sbbs->current_msg!=NULL)
                    557:                                val=sbbs->current_msg->hdr.auxattr;
                    558:                        break;
                    559:                case BBS_PROP_MSG_NETATTR:
                    560:                        if(sbbs->current_msg!=NULL)
                    561:                                val=sbbs->current_msg->hdr.netattr;
                    562:                        break;
                    563:                case BBS_PROP_MSG_OFFSET:
                    564:                        if(sbbs->current_msg!=NULL)
                    565:                                val=sbbs->current_msg->offset;
                    566:                        break;
                    567:                case BBS_PROP_MSG_NUMBER:
                    568:                        if(sbbs->current_msg!=NULL)
                    569:                                val=sbbs->current_msg->hdr.number;
                    570:                        break;
                    571:                case BBS_PROP_MSG_EXPIRATION:
                    572:                        if(sbbs->current_msg!=NULL)
                    573:                                val=sbbs->current_msg->expiration;
                    574:                        break;
                    575:                case BBS_PROP_MSG_FORWARDED:
                    576:                        if(sbbs->current_msg!=NULL)
                    577:                                val=sbbs->current_msg->forwarded;
                    578:                        break;
                    579:                case BBS_PROP_MSG_THREAD_BACK:
                    580:                        if(sbbs->current_msg!=NULL)
                    581:                                val=sbbs->current_msg->hdr.thread_back;
                    582:                        break;
                    583:                case BBS_PROP_MSG_THREAD_NEXT:
                    584:                        if(sbbs->current_msg!=NULL)
                    585:                                val=sbbs->current_msg->hdr.thread_next;
                    586:                        break;
                    587:                case BBS_PROP_MSG_THREAD_FIRST:
                    588:                        if(sbbs->current_msg!=NULL)
                    589:                                val=sbbs->current_msg->hdr.thread_first;
                    590:                        break;
                    591:                case BBS_PROP_MSG_DELIVERY_ATTEMPTS:
                    592:                        if(sbbs->current_msg!=NULL)
                    593:                                val=sbbs->current_msg->hdr.delivery_attempts;
                    594:                        break;
                    595:                case BBS_PROP_MSG_ID:
                    596:                        if(sbbs->current_msg==NULL || sbbs->current_msg->id==NULL)
                    597:                                p=nulstr;
                    598:                        else
                    599:                                p=sbbs->current_msg->id;
                    600:                        break;
                    601:                case BBS_PROP_MSG_REPLY_ID:
                    602:                        if(sbbs->current_msg==NULL || sbbs->current_msg->reply_id==NULL)
                    603:                                p=nulstr;
                    604:                        else
                    605:                                p=sbbs->current_msg->reply_id;
                    606:                        break;
                    607: 
                    608:                case BBS_PROP_BATCH_UPLOAD_TOTAL:
                    609:                        val=sbbs->batup_total;
                    610:                        break;
                    611:                case BBS_PROP_BATCH_DNLOAD_TOTAL:
                    612:                        val=sbbs->batdn_total;
                    613:                        break;
                    614: 
                    615:                case BBS_PROP_COMMAND_STR:
                    616:                        p=sbbs->main_csi.str;
                    617:                        break;
                    618: 
                    619:                default:
                    620:                        return(JS_TRUE);
                    621:        }
                    622:        if(p!=NULL) {
                    623:                JSString* js_str=JS_NewStringCopyZ(cx, p);
                    624:                if(js_str==NULL)
                    625:                        return(JS_FALSE);
                    626:                *vp = STRING_TO_JSVAL(js_str);
                    627:        } else
                    628:                JS_NewNumberValue(cx,val,vp);
                    629: 
                    630:        return(JS_TRUE);
                    631: }
                    632: 
                    633: static JSBool js_bbs_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                    634: {
                    635:        char*           p=NULL;
                    636:        int32           val=0;
                    637:     jsint       tiny;
                    638:        JSString*       js_str;
                    639:        sbbs_t*         sbbs;
                    640: 
                    641:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                    642:                return(JS_FALSE);
                    643: 
                    644:     tiny = JSVAL_TO_INT(id);
                    645: 
                    646:        if(JSVAL_IS_NUM(*vp) || JSVAL_IS_BOOLEAN(*vp))
                    647:                JS_ValueToInt32(cx, *vp, &val);
                    648:        else if(JSVAL_IS_STRING(*vp)) {
                    649:                if((js_str = JS_ValueToString(cx, *vp))==NULL)
                    650:                        return(JS_FALSE);
                    651:                p=JS_GetStringBytes(js_str);
                    652:        }
                    653: 
                    654:        switch(tiny) {
                    655:                case BBS_PROP_SYS_STATUS:
                    656:                        sbbs->sys_status=val;
                    657:                        break;
                    658:                case BBS_PROP_STARTUP_OPT:
                    659:                        sbbs->startup->options=val;
                    660:                        break;
                    661:                case BBS_PROP_ANSWER_TIME:
                    662:                        sbbs->answertime=val;
                    663:                        break;
                    664:                case BBS_PROP_LOGON_TIME:
                    665:                        sbbs->logontime=val;
                    666:                        break;
                    667:                case BBS_PROP_START_TIME:
                    668:                        sbbs->starttime=val;
                    669:                        break;
                    670:                case BBS_PROP_NS_TIME:
                    671:                        sbbs->ns_time=val;
                    672:                        break;
                    673:                case BBS_PROP_LAST_NS_TIME:
                    674:                        sbbs->last_ns_time=val;
                    675:                        break;
                    676:                case BBS_PROP_ONLINE:
                    677:                        sbbs->online=val;
                    678:                        break;
                    679:                case BBS_PROP_NODE_MISC:
                    680:                        sbbs->cfg.node_misc=val;
                    681:                        break;
                    682:                case BBS_PROP_NODE_ACTION:
                    683:                        sbbs->action=(uchar)val;
                    684:                        break;
                    685:                case BBS_PROP_NODE_VAL_USER:
                    686:                        sbbs->cfg.node_valuser=(ushort)val;
                    687:                        break;
                    688:                case BBS_PROP_LOGON_ULB:
                    689:                        sbbs->logon_ulb=val;
                    690:                        break;
                    691:                case BBS_PROP_LOGON_DLB:
                    692:                        sbbs->logon_dlb=val;
                    693:                        break;
                    694:                case BBS_PROP_LOGON_ULS:
                    695:                        sbbs->logon_uls=val;
                    696:                        break;
                    697:                case BBS_PROP_LOGON_DLS:
                    698:                        sbbs->logon_dls=val;
                    699:                        break;
                    700:                case BBS_PROP_LOGON_POSTS:
                    701:                        sbbs->logon_posts=val;
                    702:                        break;
                    703:                case BBS_PROP_LOGON_EMAILS:
                    704:                        sbbs->logon_emails=val;
                    705:                        break;
                    706:                case BBS_PROP_LOGON_FBACKS:
                    707:                        sbbs->logon_fbacks=val;
                    708:                        break;
                    709:                case BBS_PROP_POSTS_READ:
                    710:                        sbbs->posts_read=val;
                    711:                        break;
                    712:                case BBS_PROP_MENU_DIR:
                    713:                        SAFECOPY(sbbs->menu_dir,p);
                    714:                        break;
                    715:                case BBS_PROP_MENU_FILE:
                    716:                        SAFECOPY(sbbs->menu_file,p);
                    717:                        break;
                    718:                case BBS_PROP_MAIN_CMDS:
                    719:                        sbbs->main_cmds=val;
                    720:                        break;
                    721:                case BBS_PROP_FILE_CMDS:
                    722:                        sbbs->xfer_cmds=val;
                    723:                        break;
                    724: 
                    725:                case BBS_PROP_CURGRP:
                    726:                        if(p!=NULL) {   /* set by name */
                    727:                                uint i;
                    728:                                for(i=0;i<sbbs->usrgrps;i++)
                    729:                                        if(!stricmp(sbbs->cfg.grp[sbbs->usrgrp[i]]->sname,p))
                    730:                                                break;
                    731:                                if(i<sbbs->usrgrps)
                    732:                                        sbbs->curgrp=i;
                    733:                                break;
                    734:                        }
                    735:                        if((uint)val<sbbs->cfg.total_grps && (uint)val<sbbs->usrgrps)
                    736:                                sbbs->curgrp=val;
                    737:                        break;
                    738:                case BBS_PROP_CURSUB:
                    739:                case BBS_PROP_CURSUB_CODE:
                    740:                        if(p!=NULL) {   /* set by code */
                    741:                                for(uint i=0;i<sbbs->usrgrps;i++)
                    742:                                        for(uint j=0;j<sbbs->usrsubs[i];j++)
                    743:                                                if(!stricmp(sbbs->cfg.sub[sbbs->usrsub[i][j]]->code,p)) {
                    744:                                                        sbbs->curgrp=i;
                    745:                                                        sbbs->cursub[i]=j;
                    746:                                                        break; 
                    747:                                                }
                    748:                                break;
                    749:                        }
                    750:                        if(sbbs->curgrp<sbbs->cfg.total_grps && (uint)val<sbbs->usrsubs[sbbs->curgrp])
                    751:                                sbbs->cursub[sbbs->curgrp]=val;
                    752:                        break;
                    753:                case BBS_PROP_CURLIB:
                    754:                        if(p!=NULL) {   /* set by name */
                    755:                                uint i;
                    756:                                for(i=0;i<sbbs->usrlibs;i++)
                    757:                                        if(!stricmp(sbbs->cfg.lib[sbbs->usrlib[i]]->sname,p))
                    758:                                                break;
                    759:                                if(i<sbbs->usrlibs)
                    760:                                        sbbs->curlib=i;
                    761:                                break;
                    762:                        }
                    763:                        if((uint)val<sbbs->cfg.total_libs && (uint)val<sbbs->usrlibs)
                    764:                                sbbs->curlib=val;
                    765:                        break;
                    766:                case BBS_PROP_CURDIR:
                    767:                case BBS_PROP_CURDIR_CODE:
                    768:                        if(p!=NULL) {   /* set by code */
                    769:                                for(uint i=0;i<sbbs->usrlibs;i++)
                    770:                                        for(uint j=0;j<sbbs->usrdirs[i];j++)
                    771:                                                if(!stricmp(sbbs->cfg.dir[sbbs->usrdir[i][j]]->code,p)) {
                    772:                                                        sbbs->curlib=i;
                    773:                                                        sbbs->curdir[i]=j;
                    774:                                                        break; 
                    775:                                                }
                    776:                                break;
                    777:                        }
                    778:                        if(sbbs->curlib<sbbs->cfg.total_libs && (uint)val<sbbs->usrdirs[sbbs->curlib])
                    779:                                sbbs->curdir[sbbs->curlib]=val;
                    780:                        break;
                    781: 
                    782:                case BBS_PROP_RLOGIN_NAME:
                    783:                        SAFECOPY(sbbs->rlogin_name,p);
                    784:                        break;
1.1.1.2 ! root      785:                case BBS_PROP_RLOGIN_PASS:
        !           786:                        SAFECOPY(sbbs->rlogin_pass,p);
        !           787:                        break;
1.1       root      788:                case BBS_PROP_CLIENT_NAME:
                    789:                        SAFECOPY(sbbs->client_name,p);
                    790:                        break;
                    791: 
                    792:                case BBS_PROP_ALTUL:
                    793:                        if(val<sbbs->cfg.altpaths)
                    794:                                sbbs->altul=(ushort)val;
                    795:                        break;
                    796: 
                    797:                case BBS_PROP_COMMAND_STR:
                    798:                        sprintf(sbbs->main_csi.str, "%.*s", 1024, p);
                    799:                        break;
                    800: 
                    801:                default:
                    802:                        return(JS_TRUE);
                    803:        }
                    804: 
                    805:        if(sbbs->usrgrps)
                    806:                sbbs->cursubnum=sbbs->usrsub[sbbs->curgrp][sbbs->cursub[sbbs->curgrp]];         /* Used for ARS */
                    807:        else
                    808:                sbbs->cursubnum=INVALID_SUB;
                    809:        if(sbbs->usrlibs) 
                    810:                sbbs->curdirnum=sbbs->usrdir[sbbs->curlib][sbbs->curdir[sbbs->curlib]];         /* Used for ARS */
                    811:        else 
                    812:                sbbs->curdirnum=INVALID_DIR;
                    813: 
                    814:        return(JS_TRUE);
                    815: }
                    816: 
                    817: #define PROP_READONLY JSPROP_ENUMERATE|JSPROP_READONLY
                    818: 
                    819: static jsSyncPropertySpec js_bbs_properties[] = {
                    820: /*              name                           ,tinyid                                 ,flags                          ,ver    */
                    821: 
                    822:        {       "sys_status"            ,BBS_PROP_SYS_STATUS    ,JSPROP_ENUMERATE       ,310},
                    823:        {       "startup_options"       ,BBS_PROP_STARTUP_OPT   ,JSPROP_ENUMERATE       ,310},
                    824:        {       "answer_time"           ,BBS_PROP_ANSWER_TIME   ,JSPROP_ENUMERATE       ,310},
                    825:        {       "logon_time"            ,BBS_PROP_LOGON_TIME    ,JSPROP_ENUMERATE       ,310},
                    826:        {       "start_time"            ,BBS_PROP_START_TIME    ,JSPROP_ENUMERATE       ,314},
                    827:        {       "new_file_time"         ,BBS_PROP_NS_TIME               ,JSPROP_ENUMERATE       ,310},
                    828:        {       "last_new_file_time",BBS_PROP_LAST_NS_TIME      ,JSPROP_ENUMERATE       ,310},
                    829:        {       "online"                        ,BBS_PROP_ONLINE                ,JSPROP_ENUMERATE       ,310},
                    830:        {       "timeleft"                      ,BBS_PROP_TIMELEFT              ,JSPROP_READONLY        ,310},  /* alias */
                    831:        {       "time_left"                     ,BBS_PROP_TIMELEFT              ,PROP_READONLY          ,311},
                    832:        {       "event_time"            ,BBS_PROP_EVENT_TIME    ,PROP_READONLY          ,311},
                    833:        {       "event_code"            ,BBS_PROP_EVENT_CODE    ,PROP_READONLY          ,311},
                    834:        {       "node_num"                      ,BBS_PROP_NODE_NUM              ,PROP_READONLY          ,310},
                    835:        {       "node_settings"         ,BBS_PROP_NODE_MISC             ,JSPROP_ENUMERATE       ,310},
                    836:        {       "node_action"           ,BBS_PROP_NODE_ACTION   ,JSPROP_ENUMERATE       ,310},
                    837:        {       "node_val_user"         ,BBS_PROP_NODE_VAL_USER ,JSPROP_ENUMERATE       ,310},
                    838:        {       "logon_ulb"                     ,BBS_PROP_LOGON_ULB             ,JSPROP_ENUMERATE       ,310},
                    839:        {       "logon_dlb"                     ,BBS_PROP_LOGON_DLB             ,JSPROP_ENUMERATE       ,310},
                    840:        {       "logon_uls"                     ,BBS_PROP_LOGON_ULS             ,JSPROP_ENUMERATE       ,310},
                    841:        {       "logon_dls"                     ,BBS_PROP_LOGON_DLS             ,JSPROP_ENUMERATE       ,310},
                    842:        {       "logon_posts"           ,BBS_PROP_LOGON_POSTS   ,JSPROP_ENUMERATE       ,310},
                    843:        {       "logon_emails"          ,BBS_PROP_LOGON_EMAILS  ,JSPROP_ENUMERATE       ,310},
                    844:        {       "logon_fbacks"          ,BBS_PROP_LOGON_FBACKS  ,JSPROP_ENUMERATE       ,310},
                    845:        {       "posts_read"            ,BBS_PROP_POSTS_READ    ,JSPROP_ENUMERATE       ,310},
                    846:        {       "menu_dir"                      ,BBS_PROP_MENU_DIR              ,JSPROP_ENUMERATE       ,310},
                    847:        {       "menu_file"                     ,BBS_PROP_MENU_FILE             ,JSPROP_ENUMERATE       ,310},
                    848:        {       "main_cmds"                     ,BBS_PROP_MAIN_CMDS             ,JSPROP_ENUMERATE       ,310},
                    849:        {       "file_cmds"                     ,BBS_PROP_FILE_CMDS             ,JSPROP_ENUMERATE       ,310},
                    850:        {       "curgrp"                        ,BBS_PROP_CURGRP                ,JSPROP_ENUMERATE       ,310},
                    851:        {       "cursub"                        ,BBS_PROP_CURSUB                ,JSPROP_ENUMERATE       ,310},
                    852:        {       "cursub_code"           ,BBS_PROP_CURSUB_CODE   ,JSPROP_ENUMERATE       ,314},
                    853:        {       "curlib"                        ,BBS_PROP_CURLIB                ,JSPROP_ENUMERATE       ,310},
                    854:        {       "curdir"                        ,BBS_PROP_CURDIR                ,JSPROP_ENUMERATE       ,310},
                    855:        {       "curdir_code"           ,BBS_PROP_CURDIR_CODE   ,JSPROP_ENUMERATE       ,314},
                    856:        {       "connection"            ,BBS_PROP_CONNECTION    ,PROP_READONLY          ,310},
                    857:        {       "rlogin_name"           ,BBS_PROP_RLOGIN_NAME   ,JSPROP_ENUMERATE       ,310},
1.1.1.2 ! root      858:        {       "rlogin_password"       ,BBS_PROP_RLOGIN_PASS   ,JSPROP_ENUMERATE       ,315},
1.1       root      859:        {       "client_name"           ,BBS_PROP_CLIENT_NAME   ,JSPROP_ENUMERATE       ,310},
                    860:        {       "alt_ul_dir"            ,BBS_PROP_ALTUL                 ,JSPROP_ENUMERATE       ,310},
                    861:        {       "errorlevel"            ,BBS_PROP_ERRORLEVEL    ,PROP_READONLY          ,312},
                    862: 
                    863:        {       "smb_group"                     ,BBS_PROP_SMB_GROUP                     ,PROP_READONLY  ,310},
                    864:        {       "smb_group_desc"        ,BBS_PROP_SMB_GROUP_DESC        ,PROP_READONLY  ,310},
                    865:        {       "smb_group_number"      ,BBS_PROP_SMB_GROUP_NUM         ,PROP_READONLY  ,310},
                    866:        {       "smb_sub"                       ,BBS_PROP_SMB_SUB                       ,PROP_READONLY  ,310},
                    867:        {       "smb_sub_desc"          ,BBS_PROP_SMB_SUB_DESC          ,PROP_READONLY  ,310},
                    868:        {       "smb_sub_code"          ,BBS_PROP_SMB_SUB_CODE          ,PROP_READONLY  ,310},
                    869:        {       "smb_sub_number"        ,BBS_PROP_SMB_SUB_NUM           ,PROP_READONLY  ,310},
                    870:        {       "smb_attr"                      ,BBS_PROP_SMB_ATTR                      ,PROP_READONLY  ,310},
                    871:        {       "smb_last_msg"          ,BBS_PROP_SMB_LAST_MSG          ,PROP_READONLY  ,310},
                    872:        {       "smb_total_msgs"        ,BBS_PROP_SMB_TOTAL_MSGS        ,PROP_READONLY  ,310},
                    873:        {       "smb_msgs"                      ,BBS_PROP_SMB_MSGS                      ,PROP_READONLY  ,310},
                    874:        {       "smb_curmsg"            ,BBS_PROP_SMB_CURMSG            ,PROP_READONLY  ,310},
                    875:                                                                                                                                                
                    876:        {       "msg_to"                        ,BBS_PROP_MSG_TO                        ,PROP_READONLY  ,310},
                    877:        {       "msg_to_ext"            ,BBS_PROP_MSG_TO_EXT            ,PROP_READONLY  ,310},
                    878:        {       "msg_to_net"            ,BBS_PROP_MSG_TO_NET            ,PROP_READONLY  ,310},
                    879:        {       "msg_to_agent"          ,BBS_PROP_MSG_TO_AGENT          ,PROP_READONLY  ,310},
                    880:        {       "msg_from"                      ,BBS_PROP_MSG_FROM                      ,PROP_READONLY  ,310},
                    881:        {       "msg_from_ext"          ,BBS_PROP_MSG_FROM_EXT          ,PROP_READONLY  ,310},
                    882:        {       "msg_from_net"          ,BBS_PROP_MSG_FROM_NET          ,PROP_READONLY  ,310},
                    883:        {       "msg_from_agent"        ,BBS_PROP_MSG_FROM_AGENT        ,PROP_READONLY  ,310},
                    884:        {       "msg_replyto"           ,BBS_PROP_MSG_REPLYTO           ,PROP_READONLY  ,310},
                    885:        {       "msg_replyto_ext"       ,BBS_PROP_MSG_REPLYTO_EXT       ,PROP_READONLY  ,310},
                    886:        {       "msg_replyto_net"       ,BBS_PROP_MSG_REPLYTO_NET       ,PROP_READONLY  ,310},
                    887:        {       "msg_replyto_agent"     ,BBS_PROP_MSG_REPLYTO_AGENT     ,PROP_READONLY  ,310},
                    888:        {       "msg_subject"           ,BBS_PROP_MSG_SUBJECT           ,PROP_READONLY  ,310},
                    889:        {       "msg_date"                      ,BBS_PROP_MSG_DATE                      ,PROP_READONLY  ,310},
                    890:        {       "msg_timezone"          ,BBS_PROP_MSG_TIMEZONE          ,PROP_READONLY  ,310},
                    891:        {       "msg_date_imported"     ,BBS_PROP_MSG_DATE_IMPORTED     ,PROP_READONLY  ,310},
                    892:        {       "msg_attr"                      ,BBS_PROP_MSG_ATTR                      ,PROP_READONLY  ,310},
                    893:        {       "msg_auxattr"           ,BBS_PROP_MSG_AUXATTR           ,PROP_READONLY  ,310},
                    894:        {       "msg_netattr"           ,BBS_PROP_MSG_NETATTR           ,PROP_READONLY  ,310},
                    895:        {       "msg_offset"            ,BBS_PROP_MSG_OFFSET            ,PROP_READONLY  ,310},
                    896:        {       "msg_number"            ,BBS_PROP_MSG_NUMBER            ,PROP_READONLY  ,310},
                    897:        {       "msg_expiration"        ,BBS_PROP_MSG_EXPIRATION        ,PROP_READONLY  ,310},
                    898:        {       "msg_forwarded"         ,BBS_PROP_MSG_FORWARDED         ,PROP_READONLY  ,310},
                    899:        {       "msg_thread_back"       ,BBS_PROP_MSG_THREAD_BACK       ,PROP_READONLY  ,312},
                    900:        {       "msg_thread_orig"       ,BBS_PROP_MSG_THREAD_BACK       ,JSPROP_READONLY,310},  /* alias */
                    901:        {       "msg_thread_next"       ,BBS_PROP_MSG_THREAD_NEXT       ,PROP_READONLY  ,310},
                    902:        {       "msg_thread_first"      ,BBS_PROP_MSG_THREAD_FIRST      ,PROP_READONLY  ,310},
                    903:        {       "msg_id"                        ,BBS_PROP_MSG_ID                        ,PROP_READONLY  ,310},
                    904:        {       "msg_reply_id"          ,BBS_PROP_MSG_REPLY_ID          ,PROP_READONLY  ,310},
                    905:        {       "msg_delivery_attempts" ,BBS_PROP_MSG_DELIVERY_ATTEMPTS
                    906:                                                                                                                ,PROP_READONLY  ,310},
                    907: 
                    908:        {       "batch_upload_total",BBS_PROP_BATCH_UPLOAD_TOTAL,PROP_READONLY  ,310},
                    909:        {       "batch_dnload_total",BBS_PROP_BATCH_DNLOAD_TOTAL,PROP_READONLY  ,310},
                    910: 
                    911:        {       "command_str"           ,BBS_PROP_COMMAND_STR           ,JSPROP_ENUMERATE, 314},
                    912:        {0}
                    913: };
                    914: 
                    915: /* Utility functions */
                    916: static uint get_subnum(JSContext* cx, sbbs_t* sbbs, jsval val)
                    917: {
                    918:        uint subnum=INVALID_SUB;
                    919: 
                    920:        if(JSVAL_IS_STRING(val)) {
                    921:                char* p=JS_GetStringBytes(JS_ValueToString(cx,val));
                    922:                for(subnum=0;subnum<sbbs->cfg.total_subs;subnum++)
                    923:                        if(!stricmp(sbbs->cfg.sub[subnum]->code,p))
                    924:                                break;
                    925:        } else if(JSVAL_IS_NUM(val))
                    926:                JS_ValueToInt32(cx,val,(int32*)&subnum);
                    927:        else if(sbbs->usrgrps>0)
                    928:                subnum=sbbs->usrsub[sbbs->curgrp][sbbs->cursub[sbbs->curgrp]];
                    929: 
                    930:        return(subnum);
                    931: }
                    932: 
                    933: static uint get_dirnum(JSContext* cx, sbbs_t* sbbs, jsval val)
                    934: {
                    935:        uint dirnum=INVALID_DIR;
                    936: 
                    937:        if(JSVAL_IS_STRING(val)) {
                    938:                char* p=JS_GetStringBytes(JS_ValueToString(cx,val));
                    939:                for(dirnum=0;dirnum<sbbs->cfg.total_dirs;dirnum++)
                    940:                        if(!stricmp(sbbs->cfg.dir[dirnum]->code,p))
                    941:                                break;
                    942:        } else if(JSVAL_IS_NUM(val))
                    943:                JS_ValueToInt32(cx,val,(int32*)&dirnum);
                    944:        else if(sbbs->usrlibs>0)
                    945:                dirnum=sbbs->usrdir[sbbs->curlib][sbbs->curdir[sbbs->curlib]];
                    946: 
                    947:        return(dirnum);
                    948: }
                    949: 
                    950: /**************************/
                    951: /* bbs Object Methods */
                    952: /**************************/
                    953: 
                    954: static JSBool
                    955: js_menu(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    956: {
                    957:     JSString*  str;
                    958:        sbbs_t*         sbbs;
1.1.1.2 ! root      959:        jsrefcount      rc;
1.1       root      960:  
                    961:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                    962:                return(JS_FALSE);
                    963:  
                    964:        str = JS_ValueToString(cx, argv[0]);
                    965:        if (!str)
                    966:                return(JS_FALSE);
                    967:  
1.1.1.2 ! root      968:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      969:        sbbs->menu(JS_GetStringBytes(str));
1.1.1.2 ! root      970:        JS_RESUMEREQUEST(cx, rc);
1.1       root      971: 
                    972:     return(JS_TRUE);
                    973: }
                    974:  
                    975: static JSBool
                    976: js_hangup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    977: {
                    978:        sbbs_t*         sbbs;
1.1.1.2 ! root      979:        jsrefcount      rc;
1.1       root      980: 
                    981:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                    982:                return(JS_FALSE);
                    983: 
1.1.1.2 ! root      984:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      985:        sbbs->hangup();
1.1.1.2 ! root      986:        JS_RESUMEREQUEST(cx, rc);
1.1       root      987: 
                    988:        return(JS_TRUE);
                    989: }
                    990: 
                    991: static JSBool
                    992: js_nodesync(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    993: {
                    994:        sbbs_t*         sbbs;
1.1.1.2 ! root      995:        jsrefcount      rc;
1.1       root      996: 
                    997:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                    998:                return(JS_FALSE);
                    999: 
1.1.1.2 ! root     1000:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1001:        sbbs->getnodedat(sbbs->cfg.node_num,&sbbs->thisnode,0);
                   1002:        sbbs->nodesync();
1.1.1.2 ! root     1003:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1004: 
                   1005:        return(JS_TRUE);
                   1006: }
                   1007: 
                   1008: static JSBool
                   1009: js_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1010: {
                   1011:        uintN           i;
                   1012:        sbbs_t*         sbbs;
1.1.1.2 ! root     1013:        int32           mode=0;
1.1       root     1014:     JSString*  cmd;
                   1015:        JSString*       startup_dir=NULL;
                   1016:        char*           p_startup_dir=NULL;
1.1.1.2 ! root     1017:        jsrefcount      rc;
        !          1018:        char*           cstr;
1.1       root     1019: 
                   1020:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1021:                return(JS_FALSE);
                   1022: 
                   1023:        if((cmd=JS_ValueToString(cx, argv[0]))==NULL)
                   1024:                return(JS_FALSE);
                   1025: 
                   1026:        for(i=1;i<argc;i++) {
                   1027:                if(JSVAL_IS_NUM(argv[i]))
1.1.1.2 ! root     1028:                        JS_ValueToInt32(cx,argv[i],&mode);
1.1       root     1029:                else if(JSVAL_IS_STRING(argv[i]))
                   1030:                        startup_dir=JS_ValueToString(cx,argv[i]);
                   1031:        }
                   1032: 
                   1033:        if(startup_dir!=NULL)
                   1034:                p_startup_dir=JS_GetStringBytes(startup_dir);
                   1035: 
1.1.1.2 ! root     1036:        cstr=JS_GetStringBytes(cmd);
        !          1037:        rc=JS_SUSPENDREQUEST(cx);
        !          1038:        *rval = INT_TO_JSVAL(sbbs->external(cstr,mode,p_startup_dir));
        !          1039:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1040: 
                   1041:     return(JS_TRUE);
                   1042: }
                   1043: 
                   1044: static JSBool
                   1045: js_exec_xtrn(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1046: {
                   1047:        int32           i=0;
                   1048:        char*           code;
                   1049:        sbbs_t*         sbbs;
                   1050:     JSString*  str;
1.1.1.2 ! root     1051:        jsrefcount      rc;
1.1       root     1052: 
                   1053:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1054:                return(JS_FALSE);
                   1055: 
                   1056:        if(JSVAL_IS_STRING(argv[0])) {
                   1057:                if((str=JS_ValueToString(cx, argv[0]))==NULL)
                   1058:                        return(JS_FALSE);
                   1059: 
                   1060:                if((code=JS_GetStringBytes(str))==NULL)
                   1061:                        return(JS_FALSE);
                   1062: 
                   1063:                for(i=0;i<sbbs->cfg.total_xtrns;i++)
                   1064:                        if(!stricmp(sbbs->cfg.xtrn[i]->code,code))
                   1065:                                break;
                   1066:        } else if(JSVAL_IS_NUM(argv[0]))
                   1067:                JS_ValueToInt32(cx,argv[0],&i);
                   1068: 
                   1069:        if(i>=sbbs->cfg.total_xtrns) {
                   1070:                *rval = JSVAL_FALSE;
                   1071:                return(JS_TRUE);
                   1072:        }
                   1073: 
1.1.1.2 ! root     1074:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1075:        *rval = BOOLEAN_TO_JSVAL(sbbs->exec_xtrn(i));
1.1.1.2 ! root     1076:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1077:        return(JS_TRUE);
                   1078: }
                   1079: 
                   1080: static JSBool
                   1081: js_user_event(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1082: {
                   1083:        int32           i=0;
                   1084:        sbbs_t*         sbbs;
1.1.1.2 ! root     1085:        jsrefcount      rc;
1.1       root     1086: 
                   1087:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1088:                return(JS_FALSE);
                   1089: 
                   1090:        if(JSVAL_IS_NUM(argv[0]))
                   1091:                JS_ValueToInt32(cx,argv[0],&i);
1.1.1.2 ! root     1092:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1093:        *rval = BOOLEAN_TO_JSVAL(sbbs->user_event((user_event_t)i));
1.1.1.2 ! root     1094:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1095:        return(JS_TRUE);
                   1096: }
                   1097: 
                   1098: static JSBool
                   1099: js_chksyspass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1100: {
                   1101:        sbbs_t*         sbbs;
1.1.1.2 ! root     1102:        jsrefcount      rc;
1.1       root     1103: 
                   1104:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1105:                return(JS_FALSE);
                   1106: 
1.1.1.2 ! root     1107:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1108:        *rval = BOOLEAN_TO_JSVAL(sbbs->chksyspass());
1.1.1.2 ! root     1109:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1110:        return(JS_TRUE);
                   1111: }
                   1112: 
                   1113: static JSBool
                   1114: js_chkpass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1115: {
                   1116:        sbbs_t*         sbbs;
1.1.1.2 ! root     1117:        char*           cstr;
        !          1118:        jsrefcount      rc;
1.1       root     1119: 
                   1120:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1121:                return(JS_FALSE);
                   1122: 
                   1123:        JSString* str=JS_ValueToString(cx,argv[0]);
                   1124: 
1.1.1.2 ! root     1125:        cstr=JS_GetStringBytes(str);
        !          1126:        rc=JS_SUSPENDREQUEST(cx);
        !          1127:        *rval = BOOLEAN_TO_JSVAL(sbbs->chkpass(cstr,&sbbs->useron,true));
        !          1128:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1129:        return(JS_TRUE);
                   1130: }
                   1131: 
                   1132: 
                   1133: static JSBool
                   1134: js_text(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1135: {
                   1136:        int32           i=0;
                   1137:        sbbs_t*         sbbs;
                   1138: 
                   1139:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1140:                return(JS_FALSE);
                   1141: 
                   1142:        if(JSVAL_IS_NUM(argv[0]))
                   1143:                JS_ValueToInt32(cx,argv[0],&i);
                   1144:        i--;
                   1145: 
                   1146:        if(i<0 || i>=TOTAL_TEXT)
                   1147:                *rval = JSVAL_NULL;
                   1148:        else {
                   1149:                JSString* js_str = JS_NewStringCopyZ(cx, sbbs->text[i]);
                   1150:                if(js_str==NULL)
                   1151:                        return(JS_FALSE);
                   1152:                *rval = STRING_TO_JSVAL(js_str);
                   1153:        }
                   1154: 
                   1155:        return(JS_TRUE);
                   1156: }
                   1157: 
                   1158: static JSBool
                   1159: js_replace_text(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1160: {
                   1161:        char*           p;
                   1162:        int32           i=0;
                   1163:        int                     len;
                   1164:        JSString*       js_str;
                   1165:        sbbs_t*         sbbs;
                   1166: 
                   1167:        *rval = JSVAL_FALSE;
                   1168: 
                   1169:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1170:                return(JS_FALSE);
                   1171: 
                   1172:        if(JSVAL_IS_NUM(argv[0]))
                   1173:                JS_ValueToInt32(cx,argv[0],&i);
                   1174:        i--;
                   1175: 
                   1176:        if(i<0 || i>=TOTAL_TEXT)
                   1177:                return(JS_TRUE);
                   1178: 
                   1179:        if(sbbs->text[i]!=sbbs->text_sav[i] && sbbs->text[i]!=nulstr)
                   1180:                free(sbbs->text[i]);
                   1181: 
                   1182:        if((js_str=JS_ValueToString(cx, argv[1]))==NULL)
                   1183:                return(JS_TRUE);
                   1184: 
                   1185:        if((p=JS_GetStringBytes(js_str))==NULL)
                   1186:                return(JS_TRUE);
                   1187: 
                   1188:        len=strlen(p);
                   1189:        if(!len) {
                   1190:                sbbs->text[i]=nulstr;
                   1191:                *rval = JSVAL_TRUE;
                   1192:        } else {
                   1193:                sbbs->text[i]=(char *)malloc(len+1);
                   1194:                if(sbbs->text[i]==NULL) {
                   1195:                        sbbs->text[i]=sbbs->text_sav[i];
                   1196:                } else {
                   1197:                        strcpy(sbbs->text[i],p);
                   1198:                        *rval = JSVAL_TRUE;
                   1199:                }
                   1200:        }
                   1201: 
                   1202:        return(JS_TRUE);
                   1203: }
                   1204: 
                   1205: static JSBool
                   1206: js_revert_text(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1207: {
                   1208:        int32           i=0;
                   1209:        sbbs_t*         sbbs;
                   1210: 
                   1211:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1212:                return(JS_FALSE);
                   1213: 
                   1214:        if(JSVAL_IS_NUM(argv[0]))
                   1215:                JS_ValueToInt32(cx,argv[0],&i);
                   1216:        i--;
                   1217: 
                   1218:        if(i<0 || i>=TOTAL_TEXT) {
                   1219:                for(i=0;i<TOTAL_TEXT;i++) {
                   1220:                        if(sbbs->text[i]!=sbbs->text_sav[i] && sbbs->text[i]!=nulstr)
                   1221:                                free(sbbs->text[i]);
                   1222:                        sbbs->text[i]=sbbs->text_sav[i]; 
                   1223:                }
                   1224:        } else {
                   1225:                if(sbbs->text[i]!=sbbs->text_sav[i] && sbbs->text[i]!=nulstr)
                   1226:                        free(sbbs->text[i]);
                   1227:                sbbs->text[i]=sbbs->text_sav[i];
                   1228:        }
                   1229: 
                   1230:        *rval = JSVAL_TRUE;
                   1231: 
                   1232:        return(JS_TRUE);
                   1233: }
                   1234: 
                   1235: static JSBool
                   1236: js_load_text(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1237: {
                   1238:        int                     i;
                   1239:        char            path[MAX_PATH+1];
                   1240:        FILE*           stream;
                   1241:        JSString*       js_str;
                   1242:        sbbs_t*         sbbs;
1.1.1.2 ! root     1243:        char*           cstr;
        !          1244:        jsrefcount      rc;
1.1       root     1245: 
                   1246:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1247:                return(JS_FALSE);
                   1248: 
                   1249:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
                   1250:                *rval = JSVAL_FALSE;
                   1251:                return(JS_TRUE);
                   1252:        }
1.1.1.2 ! root     1253:        cstr=JS_GetStringBytes(js_str);
1.1       root     1254: 
1.1.1.2 ! root     1255:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1256:        for(i=0;i<TOTAL_TEXT;i++) {
                   1257:                if(sbbs->text[i]!=sbbs->text_sav[i]) {
                   1258:                        if(sbbs->text[i]!=nulstr)
                   1259:                                free(sbbs->text[i]);
                   1260:                        sbbs->text[i]=sbbs->text_sav[i]; 
                   1261:                }
                   1262:        }
                   1263:        sprintf(path,"%s%s.dat"
1.1.1.2 ! root     1264:                ,sbbs->cfg.ctrl_dir,cstr);
1.1       root     1265: 
                   1266:        if((stream=fnopen(NULL,path,O_RDONLY))==NULL) {
                   1267:                *rval = JSVAL_FALSE;
1.1.1.2 ! root     1268:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1269:                return(JS_TRUE);
                   1270:        }
                   1271:        for(i=0;i<TOTAL_TEXT && !feof(stream);i++) {
1.1.1.2 ! root     1272:                if((sbbs->text[i]=readtext((long *)NULL,stream,i))==NULL) {
1.1       root     1273:                        i--;
                   1274:                        continue; 
                   1275:                }
                   1276:                if(!strcmp(sbbs->text[i],sbbs->text_sav[i])) {  /* If identical */
                   1277:                        free(sbbs->text[i]);                                    /* Don't alloc */
                   1278:                        sbbs->text[i]=sbbs->text_sav[i]; 
                   1279:                }
                   1280:                else if(sbbs->text[i][0]==0) {
                   1281:                        free(sbbs->text[i]);
                   1282:                        sbbs->text[i]=nulstr; 
                   1283:                } 
                   1284:        }
                   1285:        if(i<TOTAL_TEXT) 
                   1286:                *rval = JSVAL_FALSE;
                   1287:        else
                   1288:                *rval = JSVAL_TRUE;
                   1289: 
                   1290:        fclose(stream);
1.1.1.2 ! root     1291:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1292: 
                   1293:        return(JS_TRUE);
                   1294: }
                   1295: 
                   1296: static JSBool
                   1297: js_atcode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1298: {
                   1299:        sbbs_t*         sbbs;
1.1.1.2 ! root     1300:        char    str[128],str2[128],*p;
        !          1301:        char    *instr;
        !          1302:        int             disp_len;
        !          1303:        bool    padded_left=false;
        !          1304:        bool    padded_right=false;
        !          1305:        const char *cp;
        !          1306:        jsrefcount      rc;
1.1       root     1307: 
                   1308:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1309:                return(JS_FALSE);
                   1310: 
1.1.1.2 ! root     1311:        instr = strdup(JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
        !          1312:        if(instr==NULL)
        !          1313:                return(JS_FALSE);
1.1       root     1314: 
1.1.1.2 ! root     1315:        disp_len=strlen(instr);
        !          1316:        if((p=strstr(instr,"-L"))!=NULL)
        !          1317:                padded_left=true;
        !          1318:        else if((p=strstr(instr,"-R"))!=NULL)
        !          1319:                padded_right=true;
        !          1320:        if(p!=NULL) {
        !          1321:                if(*(p+2) && isdigit(*(p+2)))
        !          1322:                        disp_len=atoi(p+2);
        !          1323:                *p=0;
        !          1324:        }
1.1       root     1325: 
1.1.1.2 ! root     1326:        if(disp_len >= sizeof(str))
        !          1327:                disp_len=sizeof(str)-1;
        !          1328: 
        !          1329:        rc=JS_SUSPENDREQUEST(cx);
        !          1330:        cp=sbbs->atcode(instr,str2,sizeof(str2));
        !          1331:        free(instr);
        !          1332:        JS_RESUMEREQUEST(cx, rc);
        !          1333:        if(cp==NULL)
1.1       root     1334:                *rval = JSVAL_NULL;
                   1335:        else {
1.1.1.2 ! root     1336:                if(padded_left)
        !          1337:                        sprintf(str,"%-*.*s",disp_len,disp_len,cp);
        !          1338:                else if(padded_right)
        !          1339:                        sprintf(str,"%*.*s",disp_len,disp_len,cp);
        !          1340:                else
        !          1341:                        SAFECOPY(str,cp);
        !          1342: 
        !          1343:                JSString* js_str = JS_NewStringCopyZ(cx, str);
1.1       root     1344:                if(js_str==NULL)
                   1345:                        return(JS_FALSE);
                   1346:                *rval = STRING_TO_JSVAL(js_str);
                   1347:        }
                   1348: 
                   1349:        return(JS_TRUE);
                   1350: }
                   1351: 
                   1352: 
                   1353: static JSBool
                   1354: js_logkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1355: {
                   1356:        char*           p;
                   1357:        JSBool          comma=false;
                   1358:        JSString*       js_str;
                   1359:        sbbs_t*         sbbs;
1.1.1.2 ! root     1360:        jsrefcount      rc;
1.1       root     1361: 
                   1362:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1363:                return(JS_FALSE);
                   1364: 
                   1365:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
                   1366:                *rval = JSVAL_FALSE;
                   1367:                return(JS_TRUE);
                   1368:        }
                   1369: 
                   1370:        if(argc>1)
                   1371:                JS_ValueToBoolean(cx,argv[1],&comma);
                   1372: 
                   1373:        if((p=JS_GetStringBytes(js_str))==NULL) {
                   1374:                *rval = JSVAL_FALSE;
                   1375:                return(JS_TRUE);
                   1376:        }
                   1377: 
1.1.1.2 ! root     1378:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1379:        sbbs->logch(*p
                   1380:                ,comma ? true:false     // This is a dumb bool conversion to make BC++ happy
                   1381:                );
1.1.1.2 ! root     1382:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1383: 
                   1384:        *rval = JSVAL_TRUE;
                   1385:        return(JS_TRUE);
                   1386: }
                   1387: 
                   1388: static JSBool
                   1389: js_logstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1390: {
                   1391:        char*           p;
                   1392:        JSString*       js_str;
                   1393:        sbbs_t*         sbbs;
1.1.1.2 ! root     1394:        jsrefcount      rc;
1.1       root     1395: 
                   1396:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1397:                return(JS_FALSE);
                   1398: 
                   1399:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
                   1400:                *rval = JSVAL_FALSE;
                   1401:                return(JS_TRUE);
                   1402:        }
                   1403: 
                   1404:        if((p=JS_GetStringBytes(js_str))==NULL) {
                   1405:                *rval = JSVAL_FALSE;
                   1406:                return(JS_TRUE);
                   1407:        }
                   1408: 
1.1.1.2 ! root     1409:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1410:        sbbs->log(p);
1.1.1.2 ! root     1411:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1412: 
                   1413:        *rval = JSVAL_TRUE;
                   1414:        return(JS_TRUE);
                   1415: }
                   1416: 
                   1417: static JSBool
                   1418: js_finduser(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1419: {
                   1420:        char*           p;
                   1421:        JSString*       js_str;
                   1422:        sbbs_t*         sbbs;
1.1.1.2 ! root     1423:        jsrefcount      rc;
1.1       root     1424: 
                   1425:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1426:                return(JS_FALSE);
                   1427: 
                   1428:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
                   1429:                *rval = INT_TO_JSVAL(0);
                   1430:                return(JS_TRUE);
                   1431:        }
                   1432: 
                   1433:        if((p=JS_GetStringBytes(js_str))==NULL) {
                   1434:                *rval = INT_TO_JSVAL(0);
                   1435:                return(JS_TRUE);
                   1436:        }
                   1437: 
1.1.1.2 ! root     1438:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1439:        *rval = INT_TO_JSVAL(sbbs->finduser(p));
1.1.1.2 ! root     1440:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1441:        return(JS_TRUE);
                   1442: }
                   1443: 
                   1444: static JSBool
                   1445: js_trashcan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1446: {
                   1447:        char*           str;
                   1448:        char*           can;
                   1449:        JSString*       js_str;
                   1450:        JSString*       js_can;
                   1451:        sbbs_t*         sbbs;
1.1.1.2 ! root     1452:        jsrefcount      rc;
1.1       root     1453: 
                   1454:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1455:                return(JS_FALSE);
                   1456: 
                   1457:        if((js_can=JS_ValueToString(cx, argv[0]))==NULL) {
                   1458:                *rval = JSVAL_FALSE;
                   1459:                return(JS_TRUE);
                   1460:        }
                   1461: 
                   1462:        if((js_str=JS_ValueToString(cx, argv[1]))==NULL) {
                   1463:                *rval = JSVAL_FALSE;
                   1464:                return(JS_TRUE);
                   1465:        }
                   1466: 
                   1467:        if((can=JS_GetStringBytes(js_can))==NULL) {
                   1468:                *rval = JSVAL_FALSE;
                   1469:                return(JS_TRUE);
                   1470:        }
                   1471: 
                   1472:        if((str=JS_GetStringBytes(js_str))==NULL) {
                   1473:                *rval = JSVAL_FALSE;
                   1474:                return(JS_TRUE);
                   1475:        }
                   1476: 
1.1.1.2 ! root     1477:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1478:        *rval = BOOLEAN_TO_JSVAL(sbbs->trashcan(str,can));      // user args are reversed
1.1.1.2 ! root     1479:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1480:        return(JS_TRUE);
                   1481: }
                   1482: 
                   1483: static JSBool
                   1484: js_newuser(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1485: {
                   1486:        sbbs_t*         sbbs;
1.1.1.2 ! root     1487:        jsrefcount      rc;
1.1       root     1488: 
                   1489:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1490:                return(JS_FALSE);
                   1491: 
1.1.1.2 ! root     1492:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1493:        *rval = BOOLEAN_TO_JSVAL(sbbs->newuser());
1.1.1.2 ! root     1494:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1495:        return(JS_TRUE);
                   1496: }
                   1497: 
                   1498: static JSBool
                   1499: js_logon(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1500: {
                   1501:        sbbs_t*         sbbs;
1.1.1.2 ! root     1502:        jsrefcount      rc;
1.1       root     1503: 
                   1504:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1505:                return(JS_FALSE);
                   1506: 
1.1.1.2 ! root     1507:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1508:        *rval = BOOLEAN_TO_JSVAL(sbbs->logon());
1.1.1.2 ! root     1509:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1510:        return(JS_TRUE);
                   1511: }
                   1512: 
                   1513: static JSBool
                   1514: js_login(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1515: {
                   1516:        char*           name;
                   1517:        char*           pw;
                   1518:        JSString*       js_name;
                   1519:        JSString*       js_pw;
                   1520:        sbbs_t*         sbbs;
1.1.1.2 ! root     1521:        jsrefcount      rc;
1.1       root     1522: 
                   1523:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1524:                return(JS_FALSE);
                   1525: 
                   1526:        if((js_name=JS_ValueToString(cx, argv[0]))==NULL) 
                   1527:                return(JS_FALSE);
                   1528: 
                   1529:        if((js_pw=JS_ValueToString(cx, argv[1]))==NULL) 
                   1530:                return(JS_FALSE);
                   1531: 
                   1532:        if((name=JS_GetStringBytes(js_name))==NULL) 
                   1533:                return(JS_FALSE);
                   1534: 
                   1535:        if((pw=JS_GetStringBytes(js_pw))==NULL) 
                   1536:                return(JS_FALSE);
                   1537: 
1.1.1.2 ! root     1538:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1539:        *rval = BOOLEAN_TO_JSVAL(sbbs->login(name,pw)==LOGIC_TRUE ? JS_TRUE:JS_FALSE);
1.1.1.2 ! root     1540:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1541:        return(JS_TRUE);
                   1542: }
                   1543: 
                   1544: 
                   1545: static JSBool
                   1546: js_logoff(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1547: {
                   1548:        sbbs_t*         sbbs;
1.1.1.2 ! root     1549:        jsrefcount      rc;
        !          1550:        JSBool          prompt=JS_TRUE;
1.1       root     1551: 
                   1552:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1553:                return(JS_FALSE);
                   1554: 
1.1.1.2 ! root     1555:        if(argc)
        !          1556:                JS_ValueToBoolean(cx,argv[0],&prompt);
        !          1557: 
        !          1558:        rc=JS_SUSPENDREQUEST(cx);
        !          1559:        if(!prompt || !sbbs->noyes(sbbs->text[LogOffQ])) {
1.1       root     1560:                if(sbbs->cfg.logoff_mod[0])
                   1561:                        sbbs->exec_bin(sbbs->cfg.logoff_mod,&sbbs->main_csi);
                   1562:                sbbs->user_event(EVENT_LOGOFF);
                   1563:                sbbs->menu("logoff");
                   1564:                sbbs->hangup(); 
                   1565:        }
1.1.1.2 ! root     1566:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1567: 
                   1568:        return(JS_TRUE);
                   1569: }
                   1570: 
                   1571: static JSBool
                   1572: js_logout(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1573: {
                   1574:        sbbs_t*         sbbs;
1.1.1.2 ! root     1575:        jsrefcount      rc;
1.1       root     1576: 
                   1577:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1578:                return(JS_FALSE);
                   1579: 
1.1.1.2 ! root     1580:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1581:        sbbs->logout();
1.1.1.2 ! root     1582:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1583: 
                   1584:        return(JS_TRUE);
                   1585: }
                   1586: 
                   1587: static JSBool
                   1588: js_automsg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1589: {
                   1590:        sbbs_t*         sbbs;
1.1.1.2 ! root     1591:        jsrefcount      rc;
1.1       root     1592: 
                   1593:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1594:                return(JS_FALSE);
                   1595: 
1.1.1.2 ! root     1596:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1597:        sbbs->automsg();
1.1.1.2 ! root     1598:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1599: 
                   1600:        return(JS_TRUE);
                   1601: }
                   1602: 
                   1603: static JSBool
                   1604: js_time_bank(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1605: {
                   1606:        sbbs_t*         sbbs;
1.1.1.2 ! root     1607:        jsrefcount      rc;
1.1       root     1608: 
                   1609:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1610:                return(JS_FALSE);
                   1611: 
1.1.1.2 ! root     1612:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1613:        sbbs->time_bank();
1.1.1.2 ! root     1614:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1615: 
                   1616:        return(JS_TRUE);
                   1617: }
                   1618: 
                   1619: static JSBool
                   1620: js_text_sec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1621: {
                   1622:        sbbs_t*         sbbs;
1.1.1.2 ! root     1623:        jsrefcount      rc;
1.1       root     1624: 
                   1625:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1626:                return(JS_FALSE);
                   1627: 
1.1.1.2 ! root     1628:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1629:        sbbs->text_sec();
1.1.1.2 ! root     1630:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1631: 
                   1632:        return(JS_TRUE);
                   1633: }
                   1634: 
                   1635: static JSBool
                   1636: js_qwk_sec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1637: {
                   1638:        sbbs_t*         sbbs;
1.1.1.2 ! root     1639:        jsrefcount      rc;
1.1       root     1640: 
                   1641:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1642:                return(JS_FALSE);
                   1643: 
1.1.1.2 ! root     1644:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1645:        sbbs->qwk_sec();
1.1.1.2 ! root     1646:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1647: 
                   1648:        return(JS_TRUE);
                   1649: }
                   1650: 
                   1651: static JSBool
                   1652: js_xtrn_sec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1653: {
                   1654:        sbbs_t*         sbbs;
1.1.1.2 ! root     1655:        jsrefcount      rc;
1.1       root     1656: 
                   1657:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1658:                return(JS_FALSE);
                   1659: 
1.1.1.2 ! root     1660:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1661:        sbbs->xtrn_sec();
1.1.1.2 ! root     1662:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1663: 
                   1664:        return(JS_TRUE);
                   1665: }
                   1666: 
                   1667: static JSBool
                   1668: js_xfer_policy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1669: {
                   1670:        sbbs_t*         sbbs;
1.1.1.2 ! root     1671:        jsrefcount      rc;
1.1       root     1672: 
                   1673:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1674:                return(JS_FALSE);
                   1675: 
1.1.1.2 ! root     1676:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1677:        sbbs->xfer_policy();
1.1.1.2 ! root     1678:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1679: 
                   1680:        return(JS_TRUE);
                   1681: }
                   1682: 
                   1683: static JSBool
                   1684: js_batchmenu(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1685: {
                   1686:        sbbs_t*         sbbs;
1.1.1.2 ! root     1687:        jsrefcount      rc;
1.1       root     1688: 
                   1689:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1690:                return(JS_FALSE);
                   1691: 
1.1.1.2 ! root     1692:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1693:        sbbs->batchmenu();
1.1.1.2 ! root     1694:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1695: 
                   1696:        return(JS_TRUE);
                   1697: }
                   1698: 
                   1699: static JSBool
                   1700: js_batchdownload(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1701: {
                   1702:        sbbs_t*         sbbs;
1.1.1.2 ! root     1703:        jsrefcount      rc;
1.1       root     1704: 
                   1705:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1706:                return(JS_FALSE);
                   1707: 
1.1.1.2 ! root     1708:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1709:        *rval = BOOLEAN_TO_JSVAL(sbbs->start_batch_download());
1.1.1.2 ! root     1710:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1711:        return(JS_TRUE);
                   1712: }
                   1713: 
                   1714: static JSBool
                   1715: js_batchaddlist(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1716: {
                   1717:        sbbs_t*         sbbs;
1.1.1.2 ! root     1718:        jsrefcount      rc;
        !          1719:        char*           cstr;
1.1       root     1720: 
                   1721:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1722:                return(JS_FALSE);
                   1723: 
1.1.1.2 ! root     1724:        cstr=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
        !          1725:        rc=JS_SUSPENDREQUEST(cx);
        !          1726:        sbbs->batch_add_list(cstr);
        !          1727:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1728: 
                   1729:        return(JS_TRUE);
                   1730: }
                   1731: 
                   1732: static JSBool
                   1733: js_sendfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1734: {
                   1735:        sbbs_t*         sbbs;
                   1736:        char            prot=0;
                   1737:        char*           p;
1.1.1.2 ! root     1738:        jsrefcount      rc;
        !          1739:        char*           cstr;
1.1       root     1740: 
                   1741:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1742:                return(JS_FALSE);
                   1743: 
                   1744:        if(argc>1 && (p=js_ValueToStringBytes(cx, argv[1], NULL))!=NULL)
                   1745:                prot=*p;
                   1746: 
1.1.1.2 ! root     1747:        cstr=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
        !          1748:        rc=JS_SUSPENDREQUEST(cx);
        !          1749:        *rval = BOOLEAN_TO_JSVAL(sbbs->sendfile(cstr,prot));
        !          1750:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1751: 
                   1752:        return(JS_TRUE);
                   1753: }
                   1754: 
                   1755: static JSBool
                   1756: js_recvfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1757: {
                   1758:        sbbs_t*         sbbs;
                   1759:        char            prot=0;
                   1760:        char*           p;
1.1.1.2 ! root     1761:        char*           cstr;
        !          1762:        jsrefcount      rc;
1.1       root     1763: 
                   1764:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1765:                return(JS_FALSE);
                   1766: 
                   1767:        if(argc>1 && (p=js_ValueToStringBytes(cx, argv[1], NULL))!=NULL)
                   1768:                prot=*p;
                   1769: 
1.1.1.2 ! root     1770:        cstr=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
        !          1771:        rc=JS_SUSPENDREQUEST(cx);
        !          1772:        *rval = BOOLEAN_TO_JSVAL(sbbs->recvfile(cstr,prot));
        !          1773:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1774: 
                   1775:        return(JS_TRUE);
                   1776: }
                   1777: 
                   1778: static JSBool
                   1779: js_temp_xfer(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1780: {
                   1781:        sbbs_t*         sbbs;
1.1.1.2 ! root     1782:        jsrefcount      rc;
1.1       root     1783: 
                   1784:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1785:                return(JS_FALSE);
                   1786: 
1.1.1.2 ! root     1787:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1788:        sbbs->temp_xfer();
1.1.1.2 ! root     1789:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1790: 
                   1791:        return(JS_TRUE);
                   1792: }
                   1793: 
                   1794: static JSBool
                   1795: js_user_config(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1796: {
                   1797:        sbbs_t*         sbbs;
1.1.1.2 ! root     1798:        jsrefcount      rc;
1.1       root     1799: 
                   1800:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1801:                return(JS_FALSE);
                   1802: 
1.1.1.2 ! root     1803:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1804:        sbbs->maindflts(&sbbs->useron);
                   1805:        if(!(sbbs->useron.rest&FLAG('G')))    /* not guest */
                   1806:                getuserdat(&sbbs->cfg,&sbbs->useron);
1.1.1.2 ! root     1807:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1808: 
                   1809:        return(JS_TRUE);
                   1810: }
                   1811: 
                   1812: static JSBool
                   1813: js_user_sync(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1814: {
                   1815:        sbbs_t*         sbbs;
1.1.1.2 ! root     1816:        jsrefcount      rc;
1.1       root     1817: 
                   1818:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1819:                return(JS_FALSE);
                   1820: 
1.1.1.2 ! root     1821:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1822:        getuserdat(&sbbs->cfg,&sbbs->useron);
1.1.1.2 ! root     1823:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1824: 
                   1825:        return(JS_TRUE);
                   1826: }
                   1827: 
                   1828: static JSBool
                   1829: js_sys_info(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1830: {
                   1831:        sbbs_t*         sbbs;
1.1.1.2 ! root     1832:        jsrefcount      rc;
1.1       root     1833: 
                   1834:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1835:                return(JS_FALSE);
                   1836: 
1.1.1.2 ! root     1837:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1838:        sbbs->sys_info();
1.1.1.2 ! root     1839:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1840: 
                   1841:        return(JS_TRUE);
                   1842: }
                   1843: 
                   1844: static JSBool
                   1845: js_sub_info(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1846: {
                   1847:        sbbs_t*         sbbs;
1.1.1.2 ! root     1848:        jsrefcount      rc;
1.1       root     1849: 
                   1850:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1851:                return(JS_FALSE);
                   1852: 
                   1853:        uint subnum=get_subnum(cx,sbbs,argv[0]);
                   1854: 
1.1.1.2 ! root     1855:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1856:        if(subnum<sbbs->cfg.total_subs)
                   1857:                sbbs->subinfo(subnum);
1.1.1.2 ! root     1858:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1859: 
                   1860:        return(JS_TRUE);
                   1861: }
                   1862: 
                   1863: static JSBool
                   1864: js_dir_info(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1865: {
                   1866:        sbbs_t*         sbbs;
1.1.1.2 ! root     1867:        jsrefcount      rc;
1.1       root     1868: 
                   1869:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1870:                return(JS_FALSE);
                   1871: 
                   1872:        uint dirnum=get_dirnum(cx,sbbs,argv[0]);
1.1.1.2 ! root     1873:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1874:        if(dirnum<sbbs->cfg.total_dirs)
                   1875:                sbbs->dirinfo(dirnum);
1.1.1.2 ! root     1876:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1877: 
                   1878:        return(JS_TRUE);
                   1879: }
                   1880: 
                   1881: static JSBool
                   1882: js_user_info(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1883: {
                   1884:        sbbs_t*         sbbs;
1.1.1.2 ! root     1885:        jsrefcount      rc;
1.1       root     1886: 
                   1887:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1888:                return(JS_FALSE);
                   1889: 
1.1.1.2 ! root     1890:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1891:        sbbs->user_info();
1.1.1.2 ! root     1892:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1893: 
                   1894:        return(JS_TRUE);
                   1895: }
                   1896: 
                   1897: static JSBool
                   1898: js_ver(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1899: {
                   1900:        sbbs_t*         sbbs;
1.1.1.2 ! root     1901:        jsrefcount      rc;
1.1       root     1902: 
                   1903:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1904:                return(JS_FALSE);
                   1905: 
1.1.1.2 ! root     1906:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1907:        sbbs->ver();
1.1.1.2 ! root     1908:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1909: 
                   1910:        return(JS_TRUE);
                   1911: }
                   1912: 
                   1913: static JSBool
                   1914: js_sys_stats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1915: {
                   1916:        sbbs_t*         sbbs;
1.1.1.2 ! root     1917:        jsrefcount      rc;
1.1       root     1918: 
                   1919:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1920:                return(JS_FALSE);
                   1921: 
1.1.1.2 ! root     1922:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1923:        sbbs->sys_stats();
1.1.1.2 ! root     1924:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1925: 
                   1926:        return(JS_TRUE);
                   1927: }
                   1928: 
                   1929: static JSBool
                   1930: js_node_stats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1931: {
                   1932:        int32           node_num=0;
                   1933:        sbbs_t*         sbbs;
1.1.1.2 ! root     1934:        jsrefcount      rc;
1.1       root     1935: 
                   1936:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1937:                return(JS_FALSE);
                   1938: 
                   1939:        if(argc>0 && JSVAL_IS_NUM(argv[0]))
                   1940:                JS_ValueToInt32(cx,argv[0],&node_num);
                   1941: 
1.1.1.2 ! root     1942:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1943:        sbbs->node_stats(node_num);
1.1.1.2 ! root     1944:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1945: 
                   1946:        return(JS_TRUE);
                   1947: }
                   1948: 
                   1949: static JSBool
                   1950: js_userlist(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1951: {
                   1952:        int32           mode=UL_ALL;
                   1953:        sbbs_t*         sbbs;
1.1.1.2 ! root     1954:        jsrefcount      rc;
1.1       root     1955: 
                   1956:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1957:                return(JS_FALSE);
                   1958: 
                   1959:        if(argc>0 && JSVAL_IS_NUM(argv[0]))
                   1960:                JS_ValueToInt32(cx,argv[0],&mode);
                   1961: 
1.1.1.2 ! root     1962:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1963:        sbbs->userlist(mode);
1.1.1.2 ! root     1964:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1965: 
                   1966:        return(JS_TRUE);
                   1967: }
                   1968: 
                   1969: static JSBool
                   1970: js_useredit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1971: {
                   1972:        int32           usernumber=0;
                   1973:        sbbs_t*         sbbs;
1.1.1.2 ! root     1974:        jsrefcount      rc;
1.1       root     1975: 
                   1976:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1977:                return(JS_FALSE);
                   1978: 
                   1979:        if(argc>0 && JSVAL_IS_NUM(argv[0]))
                   1980:                JS_ValueToInt32(cx,argv[0],&usernumber);
                   1981: 
1.1.1.2 ! root     1982:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1983:        sbbs->useredit(usernumber);
1.1.1.2 ! root     1984:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1985: 
                   1986:        return(JS_TRUE);
                   1987: }
                   1988: 
                   1989: static JSBool
                   1990: js_change_user(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1991: {
                   1992:        sbbs_t*         sbbs;
1.1.1.2 ! root     1993:        jsrefcount      rc;
1.1       root     1994: 
                   1995:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   1996:                return(JS_FALSE);
                   1997: 
1.1.1.2 ! root     1998:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1999:        sbbs->change_user();
1.1.1.2 ! root     2000:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2001: 
                   2002:        return(JS_TRUE);
                   2003: }
                   2004: 
                   2005: static JSBool
                   2006: js_logonlist(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2007: {
                   2008:        sbbs_t*         sbbs;
1.1.1.2 ! root     2009:        jsrefcount      rc;
1.1       root     2010: 
                   2011:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2012:                return(JS_FALSE);
                   2013: 
1.1.1.2 ! root     2014:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2015:        sbbs->logonlist();
1.1.1.2 ! root     2016:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2017: 
                   2018:        return(JS_TRUE);
                   2019: }
                   2020: 
                   2021: static JSBool
                   2022: js_nodelist(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2023: {
                   2024:        sbbs_t*         sbbs;
1.1.1.2 ! root     2025:        jsrefcount      rc;
1.1       root     2026: 
                   2027:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2028:                return(JS_FALSE);
                   2029: 
1.1.1.2 ! root     2030:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2031:        sbbs->nodelist();
1.1.1.2 ! root     2032:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2033: 
                   2034:        return(JS_TRUE);
                   2035: }
                   2036: 
                   2037: static JSBool
                   2038: js_whos_online(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2039: {
                   2040:        sbbs_t*         sbbs;
1.1.1.2 ! root     2041:        jsrefcount      rc;
1.1       root     2042: 
                   2043:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2044:                return(JS_FALSE);
                   2045: 
1.1.1.2 ! root     2046:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2047:        sbbs->whos_online(true);
1.1.1.2 ! root     2048:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2049: 
                   2050:        return(JS_TRUE);
                   2051: }
                   2052: 
                   2053: static JSBool
                   2054: js_spy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2055: {
                   2056:        int32           node_num=0;
                   2057:        sbbs_t*         sbbs;
1.1.1.2 ! root     2058:        jsrefcount      rc;
1.1       root     2059: 
                   2060:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2061:                return(JS_FALSE);
                   2062: 
                   2063:        if(argc && JSVAL_IS_NUM(argv[0]))
                   2064:                JS_ValueToInt32(cx,argv[0],&node_num);
1.1.1.2 ! root     2065:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2066:        sbbs->spy(node_num);
1.1.1.2 ! root     2067:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2068: 
                   2069:        return(JS_TRUE);
                   2070: }
                   2071: 
                   2072: static JSBool
                   2073: js_readmail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2074: {
                   2075:        int32           readwhich=MAIL_YOUR;
                   2076:        int32           usernumber;
                   2077:        sbbs_t*         sbbs;
1.1.1.2 ! root     2078:        jsrefcount      rc;
1.1       root     2079: 
                   2080:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2081:                return(JS_FALSE);
                   2082: 
                   2083:        usernumber=sbbs->useron.number;
                   2084:        if(argc>0 && JSVAL_IS_NUM(argv[0]))
                   2085:                JS_ValueToInt32(cx,argv[0],&readwhich);
                   2086:        if(argc>1 && JSVAL_IS_NUM(argv[1]))
                   2087:                JS_ValueToInt32(cx,argv[1],&usernumber);
                   2088: 
1.1.1.2 ! root     2089:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2090:        sbbs->readmail(usernumber,readwhich);
1.1.1.2 ! root     2091:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2092: 
                   2093:        return(JS_TRUE);
                   2094: }
                   2095: 
                   2096: static JSBool
                   2097: js_email(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2098: {
                   2099:        int32           usernumber=1;
1.1.1.2 ! root     2100:        int32           mode=WM_EMAIL;
        !          2101:        const char*     top="";
        !          2102:        const char*     subj="";
1.1       root     2103:        JSString*       js_top=NULL;
                   2104:        JSString*       js_subj=NULL;
                   2105:        sbbs_t*         sbbs;
1.1.1.2 ! root     2106:        jsrefcount      rc;
1.1       root     2107: 
                   2108:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2109:                return(JS_FALSE);
                   2110: 
                   2111:        if(JSVAL_IS_NUM(argv[0]))
                   2112:                JS_ValueToInt32(cx,argv[0],&usernumber);
                   2113:        for(uintN i=1;i<argc;i++) {
                   2114:                if(JSVAL_IS_NUM(argv[i]))
1.1.1.2 ! root     2115:                        JS_ValueToInt32(cx,argv[i],&mode);
1.1       root     2116:                else if(JSVAL_IS_STRING(argv[i]) && js_top==NULL)
                   2117:                        js_top=JS_ValueToString(cx,argv[i]);
                   2118:                else if(JSVAL_IS_STRING(argv[i]))
                   2119:                        js_subj=JS_ValueToString(cx,argv[i]);
                   2120:        }
                   2121: 
                   2122:        if(js_top!=NULL)
                   2123:                top=JS_GetStringBytes(js_top);
                   2124:        if(js_subj!=NULL)
                   2125:                subj=JS_GetStringBytes(js_subj);
                   2126: 
1.1.1.2 ! root     2127:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2128:        *rval = BOOLEAN_TO_JSVAL(sbbs->email(usernumber,top,subj,mode));
1.1.1.2 ! root     2129:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2130:        return(JS_TRUE);
                   2131: }
                   2132: static JSBool
                   2133: js_netmail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2134: {
1.1.1.2 ! root     2135:        int32           mode=0;
        !          2136:        const char*     subj="";
1.1       root     2137:        JSString*       js_to;
                   2138:        JSString*       js_subj=NULL;
                   2139:        sbbs_t*         sbbs;
1.1.1.2 ! root     2140:        char*           cstr;
        !          2141:        jsrefcount      rc;
1.1       root     2142: 
                   2143:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2144:                return(JS_FALSE);
                   2145: 
                   2146:        if((js_to=JS_ValueToString(cx, argv[0]))==NULL)
                   2147:                return(JS_FALSE);
                   2148: 
                   2149:        for(uintN i=1;i<argc;i++) {
                   2150:                if(JSVAL_IS_NUM(argv[i]))
1.1.1.2 ! root     2151:                        JS_ValueToInt32(cx,argv[i],&mode);
1.1       root     2152:                else if(JSVAL_IS_STRING(argv[i]))
                   2153:                        js_subj=JS_ValueToString(cx,argv[i]);
                   2154:        }
                   2155: 
                   2156:        if(js_subj!=NULL)
                   2157:                subj=JS_GetStringBytes(js_subj);
                   2158: 
1.1.1.2 ! root     2159:        cstr=JS_GetStringBytes(js_to);
        !          2160:        rc=JS_SUSPENDREQUEST(cx);
        !          2161:        *rval = BOOLEAN_TO_JSVAL(sbbs->netmail(cstr,subj,mode));
        !          2162:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2163:        return(JS_TRUE);
                   2164: }
                   2165: 
                   2166: static JSBool
                   2167: js_bulkmail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2168: {
                   2169:        uchar*          ar=(uchar*)"";
                   2170:        JSString*       js_ars=NULL;
                   2171:        sbbs_t*         sbbs;
1.1.1.2 ! root     2172:        jsrefcount      rc;
1.1       root     2173: 
                   2174:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2175:                return(JS_FALSE);
                   2176: 
                   2177:        if(argc) {
                   2178:                if((js_ars=JS_ValueToString(cx, argv[0]))==NULL)
                   2179:                        return(JS_FALSE);
                   2180: 
                   2181:                ar=arstr(NULL,JS_GetStringBytes(js_ars), &sbbs->cfg);
                   2182:        }
1.1.1.2 ! root     2183:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2184:        sbbs->bulkmail(ar);
                   2185:        if(ar && ar[0])
                   2186:                free(ar);
1.1.1.2 ! root     2187:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2188: 
                   2189:        return(JS_TRUE);
                   2190: }
                   2191: 
                   2192: static JSBool
                   2193: js_upload_file(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2194: {
                   2195:        uint            dirnum=0;
                   2196:        sbbs_t*         sbbs;
1.1.1.2 ! root     2197:        jsrefcount      rc;
1.1       root     2198: 
                   2199:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2200:                return(JS_FALSE);
                   2201: 
                   2202:        dirnum=get_dirnum(cx,sbbs,argv[0]);
                   2203: 
                   2204:        if(dirnum>=sbbs->cfg.total_dirs) {
                   2205:                *rval = JSVAL_FALSE;
                   2206:                return(JS_TRUE);
                   2207:        }
                   2208: 
1.1.1.2 ! root     2209:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2210:        *rval = BOOLEAN_TO_JSVAL(sbbs->upload(dirnum));
1.1.1.2 ! root     2211:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2212:        return(JS_TRUE);
                   2213: }
                   2214: 
                   2215: 
                   2216: static JSBool
                   2217: js_bulkupload(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2218: {
                   2219:        uint            dirnum=0;
                   2220:        sbbs_t*         sbbs;
1.1.1.2 ! root     2221:        jsrefcount      rc;
1.1       root     2222: 
                   2223:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2224:                return(JS_FALSE);
                   2225: 
                   2226:        dirnum=get_dirnum(cx,sbbs,argv[0]);
                   2227: 
                   2228:        if(dirnum>=sbbs->cfg.total_dirs) {
                   2229:                *rval = JSVAL_FALSE;
                   2230:                return(JS_TRUE);
                   2231:        }
                   2232: 
1.1.1.2 ! root     2233:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2234:        *rval = BOOLEAN_TO_JSVAL(sbbs->bulkupload(dirnum)==0);
1.1.1.2 ! root     2235:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2236:        return(JS_TRUE);
                   2237: }
                   2238: 
                   2239: static JSBool
                   2240: js_resort_dir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2241: {
                   2242:        uint            dirnum=0;
                   2243:        sbbs_t*         sbbs;
1.1.1.2 ! root     2244:        jsrefcount      rc;
1.1       root     2245: 
                   2246:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2247:                return(JS_FALSE);
                   2248: 
                   2249:        dirnum=get_dirnum(cx,sbbs,argv[0]);
                   2250: 
                   2251:        if(dirnum>=sbbs->cfg.total_dirs) {
                   2252:                *rval = JSVAL_FALSE;
                   2253:                return(JS_TRUE);
                   2254:        }
                   2255: 
1.1.1.2 ! root     2256:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2257:        sbbs->resort(dirnum);
1.1.1.2 ! root     2258:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2259: 
                   2260:        *rval = JSVAL_TRUE;
                   2261:        return(JS_TRUE);
                   2262: }
                   2263: 
                   2264: static JSBool
                   2265: js_telnet_gate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2266: {
                   2267:        char*           addr;
                   2268:        int32           mode=0;
                   2269:        JSString*       js_addr;
                   2270:        sbbs_t*         sbbs;
1.1.1.2 ! root     2271:        jsrefcount      rc;
1.1       root     2272: 
                   2273:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2274:                return(JS_FALSE);
                   2275: 
                   2276:        if((js_addr=JS_ValueToString(cx, argv[0]))==NULL) 
                   2277:                return(JS_FALSE);
                   2278: 
                   2279:        if((addr=JS_GetStringBytes(js_addr))==NULL) 
                   2280:                return(JS_FALSE);
                   2281: 
                   2282:        if(argc>1 && JSVAL_IS_NUM(argv[1]))
                   2283:                JS_ValueToInt32(cx,argv[1],&mode);
                   2284: 
1.1.1.2 ! root     2285:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2286:        sbbs->telnet_gate(addr,mode);
1.1.1.2 ! root     2287:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2288:        
                   2289:        return(JS_TRUE);
                   2290: }
                   2291: 
                   2292: static JSBool
                   2293: js_pagesysop(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2294: {
                   2295:        sbbs_t*         sbbs;
1.1.1.2 ! root     2296:        jsrefcount      rc;
1.1       root     2297: 
                   2298:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2299:                return(JS_FALSE);
                   2300: 
1.1.1.2 ! root     2301:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2302:        *rval = BOOLEAN_TO_JSVAL(sbbs->sysop_page());
1.1.1.2 ! root     2303:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2304:        return(JS_TRUE);
                   2305: }
                   2306: 
                   2307: static JSBool
                   2308: js_pageguru(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2309: {
                   2310:        sbbs_t*         sbbs;
1.1.1.2 ! root     2311:        jsrefcount      rc;
1.1       root     2312: 
                   2313:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2314:                return(JS_FALSE);
                   2315: 
1.1.1.2 ! root     2316:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2317:        *rval = BOOLEAN_TO_JSVAL(sbbs->guru_page());
1.1.1.2 ! root     2318:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2319:        return(JS_TRUE);
                   2320: }
                   2321: 
                   2322: static JSBool
                   2323: js_multinode_chat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2324: {
                   2325:        sbbs_t*         sbbs;
                   2326:        int32           channel=1;
1.1.1.2 ! root     2327:        jsrefcount      rc;
1.1       root     2328: 
                   2329:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2330:                return(JS_FALSE);
                   2331: 
                   2332:        if(argc>1 && JSVAL_IS_NUM(argv[1]))
                   2333:                JS_ValueToInt32(cx,argv[1],&channel);
                   2334: 
1.1.1.2 ! root     2335:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2336:        sbbs->multinodechat(channel);
1.1.1.2 ! root     2337:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2338: 
                   2339:        return(JS_TRUE);
                   2340: }
                   2341: 
                   2342: static JSBool
                   2343: js_private_message(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2344: {
                   2345:        sbbs_t*         sbbs;
1.1.1.2 ! root     2346:        jsrefcount      rc;
1.1       root     2347: 
                   2348:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2349:                return(JS_FALSE);
                   2350: 
1.1.1.2 ! root     2351:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2352:        sbbs->nodemsg();
1.1.1.2 ! root     2353:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2354: 
                   2355:        return(JS_TRUE);
                   2356: }
                   2357: 
                   2358: static JSBool
                   2359: js_private_chat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2360: {
                   2361:        sbbs_t*         sbbs;
                   2362:        JSBool          local=false;
1.1.1.2 ! root     2363:        jsrefcount      rc;
1.1       root     2364: 
                   2365:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2366:                return(JS_FALSE);
                   2367: 
                   2368:        if(argc)
                   2369:                JS_ValueToBoolean(cx,argv[0],&local);
                   2370: 
1.1.1.2 ! root     2371:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2372:        sbbs->privchat(local ? true:false);     // <- eliminates stupid msvc6 "performance warning"
1.1.1.2 ! root     2373:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2374: 
                   2375:        return(JS_TRUE);
                   2376: }
                   2377: 
                   2378: static JSBool
                   2379: js_get_node_message(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2380: {
                   2381:        sbbs_t*         sbbs;
1.1.1.2 ! root     2382:        jsrefcount      rc;
1.1       root     2383: 
                   2384:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2385:                return(JS_FALSE);
                   2386: 
1.1.1.2 ! root     2387:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2388:        sbbs->getnmsg();
1.1.1.2 ! root     2389:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2390: 
                   2391:        return(JS_TRUE);
                   2392: }
                   2393: 
                   2394: static JSBool
                   2395: js_put_node_message(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2396: {
                   2397:        sbbs_t*         sbbs;
                   2398:        int32           node=0;
                   2399:        JSString*       js_msg;
                   2400:        char*           msg;
1.1.1.2 ! root     2401:        jsrefcount      rc;
1.1       root     2402: 
                   2403:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2404:                return(JS_FALSE);
                   2405: 
                   2406:        if(JSVAL_IS_NUM(argv[0]))
                   2407:                JS_ValueToInt32(cx,argv[0],&node);
                   2408:        if(node<1)
                   2409:                node=1;
                   2410: 
                   2411:        if((js_msg=JS_ValueToString(cx, argv[1]))==NULL) 
                   2412:                return(JS_FALSE);
                   2413: 
                   2414:        if((msg=JS_GetStringBytes(js_msg))==NULL) 
                   2415:                return(JS_FALSE);
                   2416: 
1.1.1.2 ! root     2417:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2418:        *rval = BOOLEAN_TO_JSVAL(putnmsg(&sbbs->cfg,node,msg)==0);
1.1.1.2 ! root     2419:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2420: 
                   2421:        return(JS_TRUE);
                   2422: }
                   2423: 
                   2424: static JSBool
                   2425: js_get_telegram(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2426: {
                   2427:        sbbs_t*         sbbs;
                   2428:        int32           usernumber;
1.1.1.2 ! root     2429:        jsrefcount      rc;
1.1       root     2430: 
                   2431:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2432:                return(JS_FALSE);
                   2433: 
                   2434:        usernumber=sbbs->useron.number;
                   2435:        if(argc && JSVAL_IS_NUM(argv[0]))
                   2436:                JS_ValueToInt32(cx,argv[0],&usernumber);
                   2437: 
1.1.1.2 ! root     2438:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2439:        sbbs->getsmsg(usernumber);
1.1.1.2 ! root     2440:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2441: 
                   2442:        return(JS_TRUE);
                   2443: }
                   2444: 
                   2445: static JSBool
                   2446: js_put_telegram(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2447: {
                   2448:        sbbs_t*         sbbs;
                   2449:        int32           usernumber=0;
                   2450:        JSString*       js_msg;
                   2451:        char*           msg;
1.1.1.2 ! root     2452:        jsrefcount      rc;
1.1       root     2453: 
                   2454:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2455:                return(JS_FALSE);
                   2456: 
                   2457:        if(JSVAL_IS_NUM(argv[0]))
                   2458:                JS_ValueToInt32(cx,argv[0],&usernumber);
                   2459:        if(usernumber<1)
                   2460:                usernumber=1;
                   2461: 
                   2462:        if((js_msg=JS_ValueToString(cx, argv[1]))==NULL) 
                   2463:                return(JS_FALSE);
                   2464: 
                   2465:        if((msg=JS_GetStringBytes(js_msg))==NULL) 
                   2466:                return(JS_FALSE);
                   2467: 
1.1.1.2 ! root     2468:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2469:        *rval = BOOLEAN_TO_JSVAL(putsmsg(&sbbs->cfg,usernumber,msg)==0);
1.1.1.2 ! root     2470:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2471: 
                   2472:        return(JS_TRUE);
                   2473: }
                   2474: 
                   2475: static JSBool
                   2476: js_cmdstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2477: {
                   2478:        char*           p;
1.1.1.2 ! root     2479:        const char*     fpath="";
        !          2480:        const char*     fspec="";
1.1       root     2481:        JSString*       js_str;
                   2482:        sbbs_t*         sbbs;
1.1.1.2 ! root     2483:        jsrefcount      rc;
1.1       root     2484: 
                   2485:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2486:                return(JS_FALSE);
                   2487: 
                   2488:        js_str = JS_ValueToString(cx, argv[0]);
                   2489:        if (!js_str)
                   2490:                return(JS_FALSE);
                   2491: 
                   2492:        p=JS_GetStringBytes(js_str);
                   2493: 
                   2494:        for(uintN i=1;i<argc;i++) {
                   2495:                if(JSVAL_IS_STRING(argv[i])) {
                   2496:                        js_str = JS_ValueToString(cx, argv[i]);
                   2497:                        if(fpath==NULL)
                   2498:                                fpath=JS_GetStringBytes(js_str);
                   2499:                        else
                   2500:                                fspec=JS_GetStringBytes(js_str);
                   2501:                }
                   2502:        }
                   2503: 
1.1.1.2 ! root     2504:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2505:        p=sbbs->cmdstr(p,fpath,fspec,NULL);
1.1.1.2 ! root     2506:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2507: 
                   2508:        if((js_str=JS_NewStringCopyZ(cx, p))==NULL)
                   2509:                return(JS_FALSE);
                   2510:        *rval = STRING_TO_JSVAL(js_str);
                   2511:        return(JS_TRUE);
                   2512: }
                   2513: 
                   2514: static JSBool
                   2515: js_getfilespec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2516: {
                   2517:        char*           p;
                   2518:        char            tmp[128];
                   2519:        sbbs_t*         sbbs;
1.1.1.2 ! root     2520:        jsrefcount      rc;
1.1       root     2521: 
                   2522:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2523:                return(JS_FALSE);
                   2524: 
1.1.1.2 ! root     2525:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2526:        p=sbbs->getfilespec(tmp);
1.1.1.2 ! root     2527:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2528: 
                   2529:        if(p==NULL)
                   2530:                *rval=JSVAL_NULL;
                   2531:        else {
                   2532:                JSString* js_str = JS_NewStringCopyZ(cx, p);
                   2533:                if(js_str==NULL)
                   2534:                        return(JS_FALSE);
                   2535:                *rval = STRING_TO_JSVAL(js_str);
                   2536:        }
                   2537:        return(JS_TRUE);
                   2538: }
                   2539: 
                   2540: static JSBool
                   2541: js_listfiles(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2542: {
1.1.1.2 ! root     2543:        int32           mode=0;
        !          2544:        const char*     fspec=ALLFILES;
1.1       root     2545:        char            buf[MAX_PATH+1];
                   2546:        uint            dirnum;
                   2547:     JSString*  js_str;
                   2548:        sbbs_t*         sbbs;
1.1.1.2 ! root     2549:        jsrefcount      rc;
1.1       root     2550: 
                   2551:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2552:                return(JS_FALSE);
                   2553: 
                   2554:        dirnum=get_dirnum(cx,sbbs,argv[0]);
                   2555: 
                   2556:        if(dirnum>=sbbs->cfg.total_dirs) {
                   2557:                *rval = INT_TO_JSVAL(0);
                   2558:                return(JS_TRUE);
                   2559:        }
                   2560: 
                   2561:        for(uintN i=1;i<argc;i++) {
                   2562:                if(JSVAL_IS_NUM(argv[i]))
1.1.1.2 ! root     2563:                        JS_ValueToInt32(cx,argv[i],&mode);
1.1       root     2564:                else if(JSVAL_IS_STRING(argv[i])) {
                   2565:                        js_str = JS_ValueToString(cx, argv[i]);
                   2566:                        fspec=JS_GetStringBytes(js_str);
                   2567:                }
                   2568:        }
                   2569: 
1.1.1.2 ! root     2570:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2571:        if(!(mode&(FL_FINDDESC|FL_EXFIND)))
                   2572:                fspec=padfname(fspec,buf);
                   2573: 
                   2574:        *rval = INT_TO_JSVAL(sbbs->listfiles(dirnum,fspec,0 /* tofile */,mode));
1.1.1.2 ! root     2575:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2576:        return(JS_TRUE);
                   2577: }
                   2578: 
                   2579: 
                   2580: static JSBool
                   2581: js_listfileinfo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2582: {
1.1.1.2 ! root     2583:        int32           mode=FI_INFO;
        !          2584:        const char*     fspec=ALLFILES;
1.1       root     2585:        char            buf[MAX_PATH+1];
                   2586:        uint            dirnum;
                   2587:     JSString*  js_str;
                   2588:        sbbs_t*         sbbs;
1.1.1.2 ! root     2589:        jsrefcount      rc;
1.1       root     2590: 
                   2591:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2592:                return(JS_FALSE);
                   2593: 
                   2594:        dirnum=get_dirnum(cx,sbbs,argv[0]);
                   2595: 
                   2596:        if(dirnum>=sbbs->cfg.total_dirs) {
                   2597:                *rval = INT_TO_JSVAL(0);
                   2598:                return(JS_TRUE);
                   2599:        }
                   2600: 
                   2601:        for(uintN i=1;i<argc;i++) {
                   2602:                if(JSVAL_IS_NUM(argv[i]))
1.1.1.2 ! root     2603:                        JS_ValueToInt32(cx,argv[i],&mode);
1.1       root     2604:                else if(JSVAL_IS_STRING(argv[i])) {
                   2605:                        js_str = JS_ValueToString(cx, argv[i]);
                   2606:                        fspec=JS_GetStringBytes(js_str);
                   2607:                }
                   2608:        }
                   2609: 
1.1.1.2 ! root     2610:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2611:        *rval = INT_TO_JSVAL(sbbs->listfileinfo(dirnum,padfname(fspec,buf),mode));
1.1.1.2 ! root     2612:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2613:        return(JS_TRUE);
                   2614: }
                   2615: 
                   2616: static JSBool
                   2617: js_postmsg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2618: {
1.1.1.2 ! root     2619:        int32           mode=0;
1.1       root     2620:        uint            subnum;
                   2621:        uintN           n;
                   2622:        JSObject*       hdrobj;
                   2623:        sbbs_t*         sbbs;
                   2624:        smbmsg_t*       remsg=NULL;
                   2625:        smbmsg_t        msg;
1.1.1.2 ! root     2626:        jsrefcount      rc;
1.1       root     2627: 
                   2628:        *rval = JSVAL_FALSE;
                   2629: 
                   2630:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2631:                return(JS_FALSE);
                   2632: 
                   2633:        subnum=get_subnum(cx,sbbs,argv[0]);
                   2634: 
                   2635:        if(subnum>=sbbs->cfg.total_subs)        // invalid sub-board
                   2636:                return(JS_TRUE);
                   2637: 
                   2638:        ZERO_VAR(msg);
                   2639: 
                   2640:        for(n=1; n<argc; n++) {
                   2641:                if(JSVAL_IS_NUM(argv[n]))
1.1.1.2 ! root     2642:                        JS_ValueToInt32(cx,argv[n],&mode);
1.1       root     2643:                else if(JSVAL_IS_OBJECT(argv[n])) {
                   2644:                        if((hdrobj=JSVAL_TO_OBJECT(argv[n]))==NULL)
                   2645:                                return(JS_TRUE);
                   2646:                        remsg=&msg;
                   2647:                        if(!js_ParseMsgHeaderObject(cx,hdrobj,remsg))
                   2648:                                return(JS_TRUE);
                   2649:                }
                   2650:        }
                   2651: 
1.1.1.2 ! root     2652:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2653:        *rval = BOOLEAN_TO_JSVAL(sbbs->postmsg(subnum,remsg,mode));
                   2654:        smb_freemsgmem(&msg);
1.1.1.2 ! root     2655:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2656: 
                   2657:        return(JS_TRUE);
                   2658: }
                   2659: 
                   2660: static JSBool
                   2661: js_msgscan_cfg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2662: {
1.1.1.2 ! root     2663:        int32           mode=SUB_CFG_NSCAN;
1.1       root     2664:        sbbs_t*         sbbs;
1.1.1.2 ! root     2665:        jsrefcount      rc;
1.1       root     2666: 
                   2667:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2668:                return(JS_FALSE);
                   2669: 
                   2670:        if(argc && JSVAL_IS_NUM(argv[0]))
1.1.1.2 ! root     2671:                JS_ValueToInt32(cx,argv[0],&mode);
1.1       root     2672: 
1.1.1.2 ! root     2673:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2674:        sbbs->new_scan_cfg(mode);
1.1.1.2 ! root     2675:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2676: 
                   2677:        return(JS_TRUE);
                   2678: }
                   2679: 
                   2680: 
                   2681: static JSBool
                   2682: js_msgscan_ptrs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2683: {
                   2684:        sbbs_t*         sbbs;
1.1.1.2 ! root     2685:        jsrefcount      rc;
1.1       root     2686: 
                   2687:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2688:                return(JS_FALSE);
                   2689: 
1.1.1.2 ! root     2690:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2691:        sbbs->new_scan_ptr_cfg();
1.1.1.2 ! root     2692:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2693: 
                   2694:        return(JS_TRUE);
                   2695: }
                   2696: 
                   2697: static JSBool
                   2698: js_msgscan_reinit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2699: {
                   2700:        sbbs_t*         sbbs;
1.1.1.2 ! root     2701:        jsrefcount      rc;
1.1       root     2702: 
                   2703:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2704:                return(JS_FALSE);
                   2705: 
1.1.1.2 ! root     2706:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2707:        for(uint i=0;i<sbbs->cfg.total_subs;i++) {
                   2708:                sbbs->subscan[i].ptr=sbbs->subscan[i].sav_ptr;
                   2709:                sbbs->subscan[i].last=sbbs->subscan[i].sav_last; 
                   2710:        }
                   2711:        sbbs->bputs(sbbs->text[MsgPtrsInitialized]);
1.1.1.2 ! root     2712:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2713: 
                   2714:        return(JS_TRUE);
                   2715: }
                   2716: 
                   2717: static JSBool
                   2718: js_scansubs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2719: {
1.1.1.2 ! root     2720:        int32           mode=SCAN_NEW;
1.1       root     2721:        BOOL            all=FALSE;
                   2722:        sbbs_t*         sbbs;
1.1.1.2 ! root     2723:        jsrefcount      rc;
1.1       root     2724: 
                   2725:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2726:                return(JS_FALSE);
                   2727: 
                   2728:        for(uintN i=0;i<argc;i++) {
                   2729:                if(JSVAL_IS_NUM(argv[i]))
1.1.1.2 ! root     2730:                        JS_ValueToInt32(cx,argv[i],&mode);
1.1       root     2731:                else if(JSVAL_IS_BOOLEAN(argv[i]))
                   2732:                        all=JSVAL_TO_BOOLEAN(argv[i]);
                   2733:        }
                   2734: 
1.1.1.2 ! root     2735:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2736:        if(all)
                   2737:                sbbs->scanallsubs(mode);
                   2738:        else
                   2739:                sbbs->scansubs(mode);
1.1.1.2 ! root     2740:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2741: 
                   2742:        return(JS_TRUE);
                   2743: }
                   2744: 
                   2745: static JSBool
                   2746: js_scandirs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2747: {
1.1.1.2 ! root     2748:        int32           mode=0;
1.1       root     2749:        BOOL            all=FALSE;
                   2750:        sbbs_t*         sbbs;
1.1.1.2 ! root     2751:        jsrefcount      rc;
1.1       root     2752: 
                   2753:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2754:                return(JS_FALSE);
                   2755: 
                   2756:        for(uintN i=0;i<argc;i++) {
                   2757:                if(JSVAL_IS_NUM(argv[i]))
1.1.1.2 ! root     2758:                        JS_ValueToInt32(cx,argv[i],&mode);
1.1       root     2759:                else if(JSVAL_IS_BOOLEAN(argv[i]))
                   2760:                        all=JSVAL_TO_BOOLEAN(argv[i]);
                   2761:        }
                   2762: 
1.1.1.2 ! root     2763:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2764:        if(all)
                   2765:                sbbs->scanalldirs(mode);
                   2766:        else
                   2767:                sbbs->scandirs(mode);
1.1.1.2 ! root     2768:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2769: 
                   2770:        return(JS_TRUE);
                   2771: }
                   2772: 
                   2773: static JSBool
                   2774: js_scanposts(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2775: {
1.1.1.2 ! root     2776:        const char*     find="";
        !          2777:        int32           mode=0;
1.1       root     2778:        uint            subnum;
                   2779:        sbbs_t*         sbbs;
1.1.1.2 ! root     2780:        jsrefcount      rc;
1.1       root     2781: 
                   2782:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2783:                return(JS_FALSE);
                   2784: 
                   2785:        subnum=get_subnum(cx,sbbs,argv[0]);
                   2786: 
                   2787:        if(subnum>=sbbs->cfg.total_subs) {      // invalid sub-board
                   2788:                *rval = JSVAL_FALSE;
                   2789:                return(JS_TRUE);
                   2790:        }
                   2791: 
                   2792:        for(uintN i=1;i<argc;i++) {
                   2793:                if(JSVAL_IS_NUM(argv[i]))
1.1.1.2 ! root     2794:                        JS_ValueToInt32(cx,argv[i],&mode);
1.1       root     2795:                else if(JSVAL_IS_STRING(argv[i]))
                   2796:                        find=JS_GetStringBytes(JS_ValueToString(cx,argv[i]));
                   2797:        }
                   2798: 
                   2799:        if(*find)
                   2800:                mode|=SCAN_FIND;
                   2801: 
1.1.1.2 ! root     2802:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2803:        *rval = BOOLEAN_TO_JSVAL(sbbs->scanposts(subnum,mode,find)==0);
1.1.1.2 ! root     2804:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2805:        return(JS_TRUE);
                   2806: }
                   2807: 
                   2808: static JSBool
                   2809: js_listmsgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2810: {
1.1.1.2 ! root     2811:        const char*     find="";
        !          2812:        int32           mode=0;
        !          2813:        int32           start=0;
1.1       root     2814:        uint            subnum;
                   2815:        sbbs_t*         sbbs;
                   2816:        uintN           argn=0;
1.1.1.2 ! root     2817:        jsrefcount      rc;
1.1       root     2818: 
                   2819:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2820:                return(JS_FALSE);
                   2821: 
                   2822:        *rval = INT_TO_JSVAL(0);
                   2823: 
                   2824:        subnum=get_subnum(cx,sbbs,argv[argn++]);
                   2825: 
                   2826:        if(subnum>=sbbs->cfg.total_subs)        // invalid sub-board
                   2827:                return(JS_TRUE);
                   2828: 
                   2829:        if(JSVAL_IS_NUM(argv[argn]))
1.1.1.2 ! root     2830:                JS_ValueToInt32(cx,argv[argn++],&mode);
1.1       root     2831:        if(JSVAL_IS_NUM(argv[argn]))
1.1.1.2 ! root     2832:                JS_ValueToInt32(cx,argv[argn++],&start);
1.1       root     2833:        if(JSVAL_IS_STRING(argv[argn]))
                   2834:                find=JS_GetStringBytes(JS_ValueToString(cx,argv[argn++]));
                   2835: 
1.1.1.2 ! root     2836:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2837:        *rval = INT_TO_JSVAL(sbbs->listsub(subnum,mode,start,find));
1.1.1.2 ! root     2838:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2839:        return(JS_TRUE);
                   2840: }
                   2841: 
                   2842: static JSBool
                   2843: js_getnstime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2844: {
                   2845:        time_t          t=time(NULL);
                   2846:        sbbs_t*         sbbs;
1.1.1.2 ! root     2847:        jsrefcount      rc;
1.1       root     2848: 
                   2849:        *rval = JSVAL_NULL;
                   2850: 
                   2851:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2852:                return(JS_FALSE);
                   2853: 
                   2854:        if(argc && JSVAL_IS_NUM(argv[0]))
                   2855:                JS_ValueToInt32(cx,argv[0],(int32*)&t);
                   2856: 
1.1.1.2 ! root     2857:        rc=JS_SUSPENDREQUEST(cx);
        !          2858:        if(sbbs->inputnstime(&t)==true) {
        !          2859:                JS_RESUMEREQUEST(cx, rc);
1.1       root     2860:                JS_NewNumberValue(cx,t,rval);
1.1.1.2 ! root     2861:        }
        !          2862:        else
        !          2863:                JS_RESUMEREQUEST(cx, rc);
1.1       root     2864: 
                   2865:        return(JS_TRUE);
                   2866: }
                   2867: 
                   2868: static JSBool
                   2869: js_select_shell(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2870: {
                   2871:        sbbs_t*         sbbs;
1.1.1.2 ! root     2872:        jsrefcount      rc;
1.1       root     2873: 
                   2874:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2875:                return(JS_FALSE);
                   2876: 
1.1.1.2 ! root     2877:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2878:        *rval = BOOLEAN_TO_JSVAL(sbbs->select_shell());
1.1.1.2 ! root     2879:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2880:        return(JS_TRUE);
                   2881: }
                   2882: 
                   2883: static JSBool
                   2884: js_select_editor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2885: {
                   2886:        sbbs_t*         sbbs;
1.1.1.2 ! root     2887:        jsrefcount      rc;
1.1       root     2888: 
                   2889:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
                   2890:                return(JS_FALSE);
                   2891: 
1.1.1.2 ! root     2892:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     2893:        *rval = BOOLEAN_TO_JSVAL(sbbs->select_editor());
1.1.1.2 ! root     2894:        JS_RESUMEREQUEST(cx, rc);
        !          2895:        return(JS_TRUE);
        !          2896: }
        !          2897: 
        !          2898: static JSBool
        !          2899: js_get_time_left(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          2900: {
        !          2901:        sbbs_t*         sbbs;
        !          2902:        jsrefcount      rc;
        !          2903: 
        !          2904:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          2905:                return(JS_FALSE);
        !          2906: 
        !          2907:        rc=JS_SUSPENDREQUEST(cx);
        !          2908:        *rval = INT_TO_JSVAL(sbbs->gettimeleft());
        !          2909:        JS_RESUMEREQUEST(cx, rc);
1.1       root     2910:        return(JS_TRUE);
                   2911: }
                   2912: 
1.1.1.2 ! root     2913: static JSBool
        !          2914: js_chk_ar(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          2915: {
        !          2916:        uchar*          ar;
        !          2917:        JSString*       js_str;
        !          2918:        sbbs_t*         sbbs;
        !          2919:        jsrefcount      rc;
        !          2920: 
        !          2921:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          2922:                return JS_FALSE;
        !          2923: 
        !          2924:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
        !          2925:                return JS_FALSE;
        !          2926: 
        !          2927:        rc=JS_SUSPENDREQUEST(cx);
        !          2928:        ar = arstr(NULL,JS_GetStringBytes(js_str),&sbbs->cfg);
        !          2929: 
        !          2930:        *rval = BOOLEAN_TO_JSVAL(sbbs->chk_ar(ar,&sbbs->useron,&sbbs->client));
        !          2931: 
        !          2932:        if(ar!=NULL && ar!=nular)
        !          2933:                free(ar);
        !          2934:        JS_RESUMEREQUEST(cx, rc);
        !          2935: 
        !          2936:        return JS_TRUE;
        !          2937: }
        !          2938: 
1.1       root     2939: static jsSyncMethodSpec js_bbs_functions[] = {
                   2940:        {"atcode",                      js_atcode,                      1,      JSTYPE_STRING,  JSDOCSTR("code_string")
                   2941:        ,JSDOCSTR("returns @-code value, specified <i>code</i> string does not include @ character delimiters")
                   2942:        ,310
                   2943:        },
                   2944:        /* text.dat */
                   2945:        {"text",                        js_text,                        1,      JSTYPE_STRING,  JSDOCSTR("line_number")
                   2946:        ,JSDOCSTR("returns specified text string from text.dat")
                   2947:        ,310
                   2948:        },
                   2949:        {"replace_text",        js_replace_text,        2,      JSTYPE_BOOLEAN, JSDOCSTR("line_number, string text")
                   2950:        ,JSDOCSTR("replaces specified text string in memory")
                   2951:        ,310
                   2952:        },
                   2953:        {"revert_text",         js_revert_text,         1,      JSTYPE_BOOLEAN, JSDOCSTR("[line_number=<i>all</i>]")
                   2954:        ,JSDOCSTR("reverts specified text string to original text string; "
                   2955:                "if <i>line_number</i> unspecified, reverts all text lines")
                   2956:        ,310
                   2957:        },
                   2958:        {"load_text",           js_load_text,           1,      JSTYPE_BOOLEAN, JSDOCSTR("base_filename")
                   2959:        ,JSDOCSTR("load an alternate text.dat from ctrl directory, automatically appends '.dat' to basefilename")
                   2960:        ,310
                   2961:        },
                   2962:        /* procedures */
                   2963:        {"newuser",                     js_newuser,                     0,      JSTYPE_VOID,    JSDOCSTR("")
                   2964:        ,JSDOCSTR("interactive new user procedure")
                   2965:        ,310
                   2966:        },
                   2967:        {"login",                       js_login,                       2,      JSTYPE_BOOLEAN, JSDOCSTR("user_name, password_prompt")
                   2968:        ,JSDOCSTR("login with <i>user_name</i>, displaying <i>password_prompt</i> for password (if required)")
                   2969:        ,310
                   2970:        },
                   2971:        {"logon",                       js_logon,                       0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   2972:        ,JSDOCSTR("interactive logon procedure")
                   2973:        ,310
                   2974:        },
1.1.1.2 ! root     2975:        {"logoff",                      js_logoff,                      1,      JSTYPE_VOID,    JSDOCSTR("[prompt=<i>true</i>]")
        !          2976:        ,JSDOCSTR("interactive logoff procedure, pass <i>false</i> for <i>prompt</i> argument to avoid yes/no prompt")
        !          2977:        ,315
1.1       root     2978:        },
                   2979:        {"logout",                      js_logout,                      0,      JSTYPE_VOID,    JSDOCSTR("")
                   2980:        ,JSDOCSTR("non-interactive logout procedure")
                   2981:        ,310
                   2982:        },
                   2983:        {"hangup",                      js_hangup,                      0,      JSTYPE_VOID,    JSDOCSTR("")
                   2984:        ,JSDOCSTR("hangup (disconnect) immediately")
                   2985:        ,310
                   2986:        },
                   2987:        {"node_sync",           js_nodesync,            0,      JSTYPE_ALIAS },
                   2988:        {"nodesync",            js_nodesync,            0,      JSTYPE_VOID,    JSDOCSTR("")
                   2989:        ,JSDOCSTR("synchronize with node database, checks for messages, interruption, etc. (AKA node_sync)")
                   2990:        ,310
                   2991:        },
                   2992:        {"auto_msg",            js_automsg,                     0,      JSTYPE_VOID,    JSDOCSTR("")
                   2993:        ,JSDOCSTR("read/create system's auto-message")
                   2994:        ,310
                   2995:        },              
                   2996:        {"time_bank",           js_time_bank,           0,      JSTYPE_VOID,    JSDOCSTR("")
                   2997:        ,JSDOCSTR("enter the time banking system")
                   2998:        ,310
                   2999:        },              
                   3000:        {"qwk_sec",                     js_qwk_sec,                     0,      JSTYPE_VOID,    JSDOCSTR("")
                   3001:        ,JSDOCSTR("enter the QWK message packet upload/download/config section")
                   3002:        ,310
                   3003:        },              
                   3004:        {"text_sec",            js_text_sec,            0,      JSTYPE_VOID,    JSDOCSTR("")
                   3005:        ,JSDOCSTR("enter the text files section")
                   3006:        ,310
                   3007:        },              
                   3008:        {"xtrn_sec",            js_xtrn_sec,            0,      JSTYPE_VOID,    JSDOCSTR("")
                   3009:        ,JSDOCSTR("enter the external programs section")
                   3010:        ,310
                   3011:        },              
                   3012:        {"xfer_policy",         js_xfer_policy,         0,      JSTYPE_VOID,    JSDOCSTR("")
                   3013:        ,JSDOCSTR("display the file transfer policy")
                   3014:        ,310
                   3015:        },              
                   3016:        {"batch_menu",          js_batchmenu,           0,      JSTYPE_VOID,    JSDOCSTR("")
                   3017:        ,JSDOCSTR("enter the batch file transfer menu")
                   3018:        ,310
                   3019:        },              
                   3020:        {"batch_download",      js_batchdownload,       0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   3021:        ,JSDOCSTR("start a batch download")
                   3022:        ,310
                   3023:        },              
                   3024:        {"batch_add_list",      js_batchaddlist,        1,      JSTYPE_VOID,    JSDOCSTR("list_filename")
                   3025:        ,JSDOCSTR("add file list to batch download queue")
                   3026:        ,310
                   3027:        },
                   3028:        {"send_file",           js_sendfile,            1,      JSTYPE_BOOLEAN, JSDOCSTR("filename [,protocol]")
                   3029:        ,JSDOCSTR("send specified filename (complete path) to user via user-prompted "
                   3030:                "(or optionally specified) protocol")
                   3031:        ,314
                   3032:        },
                   3033:        {"receive_file",        js_recvfile,            1,      JSTYPE_BOOLEAN, JSDOCSTR("filename [,protocol]")
                   3034:        ,JSDOCSTR("received specified filename (complete path) frome user via user-prompted "
                   3035:                "(or optionally specified) protocol")
                   3036:        ,314
                   3037:        },
                   3038:        {"temp_xfer",           js_temp_xfer,           0,      JSTYPE_VOID,    JSDOCSTR("")
                   3039:        ,JSDOCSTR("enter the temporary file tranfer menu")
                   3040:        ,310
                   3041:        },              
                   3042:        {"user_sync",           js_user_sync,           0,      JSTYPE_VOID,    JSDOCSTR("")
                   3043:        ,JSDOCSTR("read the current user data from the database")
                   3044:        ,310
                   3045:        },              
                   3046:        {"user_config",         js_user_config,         0,      JSTYPE_VOID,    JSDOCSTR("")
                   3047:        ,JSDOCSTR("enter the user settings configuration menu")
                   3048:        ,310
                   3049:        },              
                   3050:        {"sys_info",            js_sys_info,            0,      JSTYPE_VOID,    JSDOCSTR("")
                   3051:        ,JSDOCSTR("display system information")
                   3052:        ,310
                   3053:        },              
                   3054:        {"sub_info",            js_sub_info,            1,      JSTYPE_VOID,    JSDOCSTR("[sub-board=<i>current</i>]")
                   3055:        ,JSDOCSTR("display message sub-board information (current <i>sub-board</i>, if unspecified)")
                   3056:        ,310
                   3057:        },              
                   3058:        {"dir_info",            js_dir_info,            0,      JSTYPE_VOID,    JSDOCSTR("[directory=<i>current</i>]")
                   3059:        ,JSDOCSTR("display file directory information (current <i>directory</i>, if unspecified)")
                   3060:        ,310
                   3061:        },              
                   3062:        {"user_info",           js_user_info,           0,      JSTYPE_VOID,    JSDOCSTR("")
                   3063:        ,JSDOCSTR("display current user information")
                   3064:        ,310
                   3065:        },              
                   3066:        {"ver",                         js_ver,                         0,      JSTYPE_VOID,    JSDOCSTR("")
                   3067:        ,JSDOCSTR("display software version information")
                   3068:        ,310
                   3069:        },              
                   3070:        {"sys_stats",           js_sys_stats,           0,      JSTYPE_VOID,    JSDOCSTR("")
                   3071:        ,JSDOCSTR("display system statistics")
                   3072:        ,310
                   3073:        },              
                   3074:        {"node_stats",          js_node_stats,          0,      JSTYPE_VOID,    JSDOCSTR("[node_number=<i>current</i>]")
                   3075:        ,JSDOCSTR("display current (or specified) node statistics")
                   3076:        ,310
                   3077:        },              
                   3078:        {"list_users",          js_userlist,            0,      JSTYPE_VOID,    JSDOCSTR("[mode=<tt>UL_ALL</tt>]")
                   3079:        ,JSDOCSTR("display user list"
                   3080:        "(see <tt>UL_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> values)")
                   3081:        ,310
                   3082:        },              
                   3083:        {"edit_user",           js_useredit,            0,      JSTYPE_VOID,    JSDOCSTR("[user_number=<i>current</i>]")
                   3084:        ,JSDOCSTR("enter the user editor")
                   3085:        ,310
                   3086:        },              
                   3087:        {"change_user",         js_change_user,         0,      JSTYPE_VOID,    JSDOCSTR("")
                   3088:        ,JSDOCSTR("change to a different user")
                   3089:        ,310
                   3090:        },              
                   3091:        {"list_logons",         js_logonlist,           0,      JSTYPE_VOID,    JSDOCSTR("")
                   3092:        ,JSDOCSTR("display the logon list")
                   3093:        ,310
                   3094:        },              
                   3095:        {"read_mail",           js_readmail,            0,      JSTYPE_VOID,    JSDOCSTR("[which=<tt>MAIL_YOUR</tt>] [,user_number=<i>current</i>]")
                   3096:        ,JSDOCSTR("read private e-mail"
                   3097:        "(see <tt>MAIL_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>which</i> values)")
                   3098:        ,310
                   3099:        },              
                   3100:        {"email",                       js_email,                       1,      JSTYPE_BOOLEAN, JSDOCSTR("to_user_number [,mode=<tt>WM_EMAIL</tt>] [,top=<i>none</i>] [,subject=<i>none</i>]")
                   3101:        ,JSDOCSTR("send private e-mail to a local user")
                   3102:        ,310
                   3103:        },              
                   3104:        {"netmail",                     js_netmail,                     1,      JSTYPE_BOOLEAN, JSDOCSTR("address [,mode=<tt>WM_NONE</tt>] [,subject=<i>none</i>]")
                   3105:        ,JSDOCSTR("send private netmail")
                   3106:        ,310
                   3107:        },              
                   3108:        {"bulk_mail",           js_bulkmail,            0,      JSTYPE_VOID,    JSDOCSTR("[ars]")
                   3109:        ,JSDOCSTR("send bulk private e-mail, if <i>ars</i> not specified, prompt for destination users")
                   3110:        ,310
                   3111:        },              
                   3112:        {"upload_file",         js_upload_file,         1,      JSTYPE_BOOLEAN, JSDOCSTR("[directory=<i>current</i>]")
                   3113:        ,JSDOCSTR("upload file to file directory specified by number or internal code")
                   3114:        ,310
                   3115:        },              
                   3116:        {"bulk_upload",         js_bulkupload,          1,      JSTYPE_BOOLEAN, JSDOCSTR("[directory=<i>current</i>]")
                   3117:        ,JSDOCSTR("add files (already in local storage path) to file directory "
                   3118:                "specified by number or internal code")
                   3119:        ,310
                   3120:        },              
                   3121:        {"resort_dir",          js_resort_dir,          1,      JSTYPE_BOOLEAN, JSDOCSTR("[directory=<i>current</i>]")
                   3122:        ,JSDOCSTR("re-sort the file directory specified by number or internal code)")
                   3123:        ,310
                   3124:        },              
                   3125:        {"list_files",          js_listfiles,           1,      JSTYPE_NUMBER,  JSDOCSTR("[directory=<i>current</i>] [,filespec=<tt>\"*.*\"</tt> or search_string] [,mode=<tt>FL_NONE</tt>]")
                   3126:        ,JSDOCSTR("list files in the specified file directory, "
                   3127:                "optionally specifying a file specification (wildcards) or a description search string, "
                   3128:                "and <i>mode</i> (bitfield)")
                   3129:        ,310
                   3130:        },              
                   3131:        {"list_file_info",      js_listfileinfo,        1,      JSTYPE_NUMBER,  JSDOCSTR("[directory=<i>current</i>] [,filespec=<tt>\"*.*\"</tt>] [,mode=<tt>FI_INFO</tt>]")
                   3132:        ,JSDOCSTR("list extended file information for files in the specified file directory")
                   3133:        ,310
                   3134:        },              
                   3135:        {"post_msg",            js_postmsg,                     1,      JSTYPE_BOOLEAN, JSDOCSTR("[sub-board=<i>current</i>] [,mode=<tt>WM_MODE</tt>] [,object reply_header]")
                   3136:        ,JSDOCSTR("post a message in the specified message sub-board (number or internal code) "
                   3137:                "with optinal <i>mode</i> (bitfield)<br>"
                   3138:                "If <i>reply_header</i> is specified (a header object returned from <i>MsgBase.get_msg_header()</i>), that header "
                   3139:                "will be used for the in-reply-to header fields (this argument added in v3.13)")
                   3140:        ,313
                   3141:        },              
                   3142:        {"cfg_msg_scan",        js_msgscan_cfg,         0,      JSTYPE_VOID,    JSDOCSTR("[type=<tt>SCAN_CFG_NEW</tt>]")
                   3143:        ,JSDOCSTR("configure message scan "
                   3144:                "(<i>type</i> is either <tt>SCAN_CFG_NEW</tt> or <tt>SCAN_CFG_TOYOU</tt>)")
                   3145:        ,310
                   3146:        },              
                   3147:        {"cfg_msg_ptrs",        js_msgscan_ptrs,        0,      JSTYPE_VOID,    JSDOCSTR("")
                   3148:        ,JSDOCSTR("change message scan pointer values")
                   3149:        ,310
                   3150:        },              
                   3151:        {"reinit_msg_ptrs",     js_msgscan_reinit,      0,      JSTYPE_VOID,    JSDOCSTR("")
                   3152:        ,JSDOCSTR("re-initialize new message scan pointers")
                   3153:        ,310
                   3154:        },              
                   3155:        {"scan_subs",           js_scansubs,            0,      JSTYPE_VOID,    JSDOCSTR("[mode=<tt>SCAN_NEW</tt>] [,all=<tt>false</tt>]")
                   3156:        ,JSDOCSTR("scan sub-boards for messages")
                   3157:        ,310
                   3158:        },              
                   3159:        {"scan_dirs",           js_scandirs,            0,      JSTYPE_VOID,    JSDOCSTR("[mode=<tt>FL_NONE</tt>] [,all=<tt>false</tt>]")
                   3160:        ,JSDOCSTR("scan directories for files")
                   3161:        ,310
                   3162:        },              
                   3163:        {"scan_posts",          js_scanposts,           1,      JSTYPE_ALIAS },
                   3164:        {"scan_msgs",           js_scanposts,           1,      JSTYPE_BOOLEAN, JSDOCSTR("[sub-board=<i>current</i>] [,mode=<tt>SCAN_READ</tt>] [,string find]")
                   3165:        ,JSDOCSTR("scan messages in the specified message sub-board (number or internal code), "
                   3166:                "optionally search for 'find' string (AKA scan_posts)")
                   3167:        ,310
                   3168:        },              
                   3169:        {"list_msgs",           js_listmsgs,            1,      JSTYPE_NUMBER,  JSDOCSTR("[sub-board=<i>current</i>] [,mode=<tt>SCAN_READ</tt>] [,message_number=<tt>0</tt>] [,string find]")
                   3170:        ,JSDOCSTR("list messages in the specified message sub-board (number or internal code), "
                   3171:                "optionally search for 'find' string, returns number of messages listed")
                   3172:        ,314
                   3173:        },              
                   3174:        /* menuing */
                   3175:        {"menu",                        js_menu,                        1,      JSTYPE_VOID,    JSDOCSTR("base_filename")
                   3176:        ,JSDOCSTR("display a menu file from the text/menu directory")
                   3177:        ,310
                   3178:        },              
                   3179:        {"log_key",                     js_logkey,                      1,      JSTYPE_BOOLEAN, JSDOCSTR("key [,comma=<tt>false</tt>]")
                   3180:        ,JSDOCSTR("log key to node.log (comma optional)")
                   3181:        ,310
                   3182:        },              
                   3183:        {"log_str",                     js_logstr,                      1,      JSTYPE_BOOLEAN, JSDOCSTR("text")
                   3184:        ,JSDOCSTR("log string to node.log")
                   3185:        ,310
                   3186:        },              
                   3187:        /* users */
                   3188:        {"finduser",            js_finduser,            1,      JSTYPE_NUMBER,  JSDOCSTR("username_or_number")
                   3189:        ,JSDOCSTR("find user name (partial name support), interactive")
                   3190:        ,310
                   3191:        },              
                   3192:        {"trashcan",            js_trashcan,            2,      JSTYPE_BOOLEAN, JSDOCSTR("base_filename, search_string")
                   3193:        ,JSDOCSTR("search file for psuedo-regexp (search string) in trashcan file (text/base_filename.can)")
                   3194:        ,310
                   3195:        },              
                   3196:        /* xtrn programs/modules */
                   3197:        {"exec",                        js_exec,                        2,      JSTYPE_NUMBER,  JSDOCSTR("cmdline [,mode=<tt>EX_NONE</tt>] [,string startup_dir]")
                   3198:        ,JSDOCSTR("execute a program, optionally changing current directory to <i>startup_dir</i> "
                   3199:        "(see <tt>EX_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> bits)")
                   3200:        ,310
                   3201:        },              
                   3202:        {"exec_xtrn",           js_exec_xtrn,           1,      JSTYPE_BOOLEAN, JSDOCSTR("xtrn_number_or_code")
                   3203:        ,JSDOCSTR("execute external program by number or internal code")
                   3204:        ,310
                   3205:        },              
                   3206:        {"user_event",          js_user_event,          1,      JSTYPE_BOOLEAN, JSDOCSTR("event_type")
                   3207:        ,JSDOCSTR("execute user event by event type "
                   3208:        "(see <tt>EVENT_*</tt> in <tt>sbbsdefs.js</tt> for valid values)")
                   3209:        ,310
                   3210:        },              
                   3211:        {"telnet_gate",         js_telnet_gate,         1,      JSTYPE_VOID,    JSDOCSTR("address [,mode=<tt>TG_NONE</tt>]")
                   3212:        ,JSDOCSTR("external telnet/rlogin gateway (see <tt>TG_*</tt> in <tt>sbbsdefs.js</tt> for valid <i>mode</i> bits)")
                   3213:        ,310
                   3214:        },              
                   3215:        /* security */
                   3216:        {"check_syspass",       js_chksyspass,          0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   3217:        ,JSDOCSTR("prompt for and verify system password")
                   3218:        ,310
                   3219:        },
                   3220:        {"good_password",       js_chkpass,                     1,      JSTYPE_STRING,  JSDOCSTR("password")
                   3221:        ,JSDOCSTR("check if requested user password meets minimum password requirements "
                   3222:                "(length, uniqueness, etc.)")
                   3223:        ,310
                   3224:        },
                   3225:        /* chat/node stuff */
                   3226:        {"page_sysop",          js_pagesysop,           0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   3227:        ,JSDOCSTR("page the sysop for chat, returns <i>false</i> if the sysop could not be paged")
                   3228:        ,310
                   3229:        },              
                   3230:        {"page_guru",           js_pageguru,            0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   3231:        ,JSDOCSTR("page the guru for chat")
                   3232:        ,310
                   3233:        },              
                   3234:        {"multinode_chat",      js_multinode_chat,      0,      JSTYPE_VOID,    JSDOCSTR("")
                   3235:        ,JSDOCSTR("enter multi-node chat")
                   3236:        ,310
                   3237:        },              
                   3238:        {"private_message",     js_private_message,     0,      JSTYPE_VOID,    JSDOCSTR("")
                   3239:        ,JSDOCSTR("use the private inter-node message prompt")
                   3240:        ,310
                   3241:        },              
                   3242:        {"private_chat",        js_private_chat,        0,      JSTYPE_VOID,    JSDOCSTR("[local=<i>false</i>]")
                   3243:        ,JSDOCSTR("enter private inter-node chat, or local sysop chat (if <i>local</i>=<i>true</i>)")
                   3244:        ,310
                   3245:        },              
                   3246:        {"get_node_message",js_get_node_message,0,      JSTYPE_VOID,    JSDOCSTR("")
                   3247:        ,JSDOCSTR("receive and display an inter-node message")
                   3248:        ,310
                   3249:        },              
                   3250:        {"put_node_message",js_put_node_message,2,      JSTYPE_BOOLEAN, JSDOCSTR("node_number, text")
                   3251:        ,JSDOCSTR("send an inter-node message")
                   3252:        ,310
                   3253:        },              
                   3254:        {"get_telegram",        js_get_telegram,        1,      JSTYPE_VOID,    JSDOCSTR("[user_number=<i>current</i>]")
                   3255:        ,JSDOCSTR("receive and display waiting telegrams for specified (or current) user")
                   3256:        ,310
                   3257:        },              
                   3258:        {"put_telegram",        js_put_telegram,        2,      JSTYPE_BOOLEAN, JSDOCSTR("user_number, text")
                   3259:        ,JSDOCSTR("send a telegram to a user")
                   3260:        ,310
                   3261:        },              
                   3262:        {"list_nodes",          js_nodelist,            0,      JSTYPE_VOID,    JSDOCSTR("")
                   3263:        ,JSDOCSTR("list all nodes")
                   3264:        ,310
                   3265:        },              
                   3266:        {"whos_online",         js_whos_online,         0,      JSTYPE_VOID,    JSDOCSTR("")
                   3267:        ,JSDOCSTR("list active nodes only (who's online)")
                   3268:        ,310
                   3269:        },              
                   3270:        {"spy",                         js_spy,                         1,      JSTYPE_VOID,    JSDOCSTR("node_number")
                   3271:        ,JSDOCSTR("spy on a node")
                   3272:        ,310
                   3273:        },              
                   3274:        /* misc */
                   3275:        {"cmdstr",                      js_cmdstr,                      1,      JSTYPE_STRING,  JSDOCSTR("command_string [,string fpath=<tt>\"\"</tt>] [,string fspec=<tt>\"\"</tt>]")
                   3276:        ,JSDOCSTR("return expanded command string using Synchronet command-line specifiers")
                   3277:        ,310
                   3278:        },              
                   3279:        /* input */
                   3280:        {"get_filespec",        js_getfilespec,         0,      JSTYPE_STRING,  JSDOCSTR("")    
                   3281:        ,JSDOCSTR("returns a file specification input by the user (optionally with wildcards)")
                   3282:        ,310
                   3283:        },              
                   3284:        {"get_newscantime",     js_getnstime,           1,      JSTYPE_NUMBER,  JSDOCSTR("time=<i>current</i>")
                   3285:        ,JSDOCSTR("confirm or change a new-scan time, returns the new new-scan time value (<i>time_t</i> format)")
                   3286:        ,310
                   3287:        },              
                   3288:        {"select_shell",        js_select_shell,        0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   3289:        ,JSDOCSTR("prompt user to select a new command shell")
                   3290:        ,310
                   3291:        },
                   3292:        {"select_editor",       js_select_editor,       0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   3293:        ,JSDOCSTR("prompt user to select a new external message editor")
                   3294:        ,310
                   3295:        },
1.1.1.2 ! root     3296:        {"get_time_left",       js_get_time_left,       0,      JSTYPE_NUMBER,  JSDOCSTR("")
        !          3297:        ,JSDOCSTR("check the user's available remaining time online and return the value, in seconds<br>"
        !          3298:        "This method will inform (and disconnect) the user when they are out of time")
        !          3299:        ,31401
        !          3300:        },
        !          3301:        {"compare_ars",         js_chk_ar,                      1,      JSTYPE_BOOLEAN, JSDOCSTR("string ars")
        !          3302:        ,JSDOCSTR("verify the current user online meets the specified Access Requirements String")
        !          3303:        ,315
        !          3304:        },              
1.1       root     3305:        {0}
                   3306: };
                   3307: 
1.1.1.2 ! root     3308: static JSBool js_bbs_resolve(JSContext *cx, JSObject *obj, jsval id)
        !          3309: {
        !          3310:        char*                   name=NULL;
        !          3311: 
        !          3312:        if(id != JSVAL_NULL)
        !          3313:                name=JS_GetStringBytes(JSVAL_TO_STRING(id));
        !          3314: 
        !          3315:        return(js_SyncResolve(cx, obj, name, js_bbs_properties, js_bbs_functions, NULL, 0));
        !          3316: }
        !          3317: 
        !          3318: static JSBool js_bbs_enumerate(JSContext *cx, JSObject *obj)
        !          3319: {
        !          3320:        return(js_bbs_resolve(cx, obj, JSVAL_NULL));
        !          3321: }
1.1       root     3322: 
                   3323: static JSClass js_bbs_class = {
                   3324:      "BBS"                                     /* name                 */
                   3325:     ,0                                         /* flags                */
                   3326:        ,JS_PropertyStub                /* addProperty  */
                   3327:        ,JS_PropertyStub                /* delProperty  */
                   3328:        ,js_bbs_get                             /* getProperty  */
                   3329:        ,js_bbs_set                             /* setProperty  */
1.1.1.2 ! root     3330:        ,js_bbs_enumerate               /* enumerate    */
        !          3331:        ,js_bbs_resolve                 /* resolve              */
1.1       root     3332:        ,JS_ConvertStub                 /* convert              */
                   3333:        ,JS_FinalizeStub                /* finalize             */
                   3334: };
                   3335: 
                   3336: JSObject* js_CreateBbsObject(JSContext* cx, JSObject* parent)
                   3337: {
                   3338:        JSObject* obj;
                   3339:        JSObject* mods;
                   3340: 
                   3341:        obj = JS_DefineObject(cx, parent, "bbs", &js_bbs_class, NULL
                   3342:                ,JSPROP_ENUMERATE|JSPROP_READONLY);
                   3343: 
                   3344:        if(obj==NULL)
                   3345:                return(NULL);
                   3346: 
                   3347:        if((mods=JS_DefineObject(cx, obj, "mods", NULL, NULL ,JSPROP_ENUMERATE))==NULL)
                   3348:                return(NULL);
                   3349: 
                   3350: #ifdef BUILD_JSDOCS
                   3351:        js_DescribeSyncObject(cx,mods,"Global repository for 3rd party modifications",312);
1.1.1.2 ! root     3352:        js_DescribeSyncObject(cx,obj,"Controls the Telnet/SSH/RLogin BBS experience",310);
1.1       root     3353:        js_CreateArrayOfStrings(cx, obj, "_property_desc_list", bbs_prop_desc, JSPROP_READONLY);
                   3354: #endif
                   3355: 
                   3356:        return(obj);
                   3357: }
                   3358: 
                   3359: #endif /* JAVSCRIPT */

unix.superglobalmegacorp.com

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