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

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

unix.superglobalmegacorp.com

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