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

1.1     ! root        1: /* js_console.cpp */
        !             2: 
        !             3: /* Synchronet JavaScript "Console" Object */
        !             4: 
        !             5: /* $Id: js_console.cpp,v 1.66 2006/12/27 09:19:26 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: /* Console Object Properites */
        !            44: /*****************************/
        !            45: enum {
        !            46:         CON_PROP_STATUS
        !            47:        ,CON_PROP_LNCNTR 
        !            48:        ,CON_PROP_ATTR
        !            49:        ,CON_PROP_TOS
        !            50:        ,CON_PROP_ROWS
        !            51:        ,CON_PROP_COLUMNS
        !            52:        ,CON_PROP_AUTOTERM
        !            53:        ,CON_PROP_TERMINAL
        !            54:        ,CON_PROP_WORDWRAP
        !            55:        ,CON_PROP_QUESTION
        !            56:        ,CON_PROP_TIMEOUT                       /* User inactivity timeout reference */
        !            57:        ,CON_PROP_TIMELEFT_WARN         /* low timeleft warning flag */
        !            58:        ,CON_PROP_ABORTED
        !            59:        ,CON_PROP_ABORTABLE
        !            60:        ,CON_PROP_TELNET_MODE
        !            61:        ,CON_PROP_GETSTR_OFFSET
        !            62:        ,CON_PROP_CTRLKEY_PASSTHRU
        !            63:        /* read only */
        !            64:        ,CON_PROP_INBUF_LEVEL
        !            65:        ,CON_PROP_INBUF_SPACE
        !            66:        ,CON_PROP_OUTBUF_LEVEL
        !            67:        ,CON_PROP_OUTBUF_SPACE
        !            68: };
        !            69: 
        !            70: static JSBool js_console_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
        !            71: {
        !            72:        ulong           val;
        !            73:     jsint       tiny;
        !            74:        JSString*       js_str;
        !            75:        sbbs_t*         sbbs;
        !            76: 
        !            77:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !            78:                return(JS_FALSE);
        !            79: 
        !            80:     tiny = JSVAL_TO_INT(id);
        !            81: 
        !            82:        switch(tiny) {
        !            83:                case CON_PROP_STATUS:
        !            84:                        val=sbbs->console;
        !            85:                        break;
        !            86:                case CON_PROP_LNCNTR:
        !            87:                        val=sbbs->lncntr;
        !            88:                        break;
        !            89:                case CON_PROP_ATTR:
        !            90:                        val=sbbs->curatr;
        !            91:                        break;
        !            92:                case CON_PROP_TOS:
        !            93:                        val=sbbs->tos;
        !            94:                        break;
        !            95:                case CON_PROP_ROWS:
        !            96:                        val=sbbs->rows;
        !            97:                        break;
        !            98:                case CON_PROP_COLUMNS:
        !            99:                        val=sbbs->cols;
        !           100:                        break;
        !           101:                case CON_PROP_AUTOTERM:
        !           102:                        val=sbbs->autoterm;
        !           103:                        break;
        !           104:                case CON_PROP_TERMINAL:
        !           105:                        if((js_str=JS_NewStringCopyZ(cx, sbbs->terminal))==NULL)
        !           106:                                return(JS_FALSE);
        !           107:                        *vp = STRING_TO_JSVAL(js_str);
        !           108:                        return(JS_TRUE);
        !           109:                case CON_PROP_TIMEOUT:
        !           110:                        val=sbbs->timeout;
        !           111:                        break;
        !           112:                case CON_PROP_TIMELEFT_WARN:
        !           113:                        val=sbbs->timeleft_warn;
        !           114:                        break;
        !           115:                case CON_PROP_ABORTED:
        !           116:                        *vp=BOOLEAN_TO_JSVAL(INT_TO_BOOL(sbbs->sys_status&SS_ABORT));
        !           117:                        return(JS_TRUE);
        !           118:                case CON_PROP_ABORTABLE:
        !           119:                        *vp=BOOLEAN_TO_JSVAL(INT_TO_BOOL(sbbs->rio_abortable));
        !           120:                        return(JS_TRUE);
        !           121:                case CON_PROP_TELNET_MODE:
        !           122:                        val=sbbs->telnet_mode;
        !           123:                        break;
        !           124:                case CON_PROP_GETSTR_OFFSET:
        !           125:                        val=sbbs->getstr_offset;
        !           126:                        break;
        !           127:                case CON_PROP_WORDWRAP:
        !           128:                        if((js_str=JS_NewStringCopyZ(cx, sbbs->wordwrap))==NULL)
        !           129:                                return(JS_FALSE);
        !           130:                        *vp = STRING_TO_JSVAL(js_str);
        !           131:                        return(JS_TRUE);
        !           132:                case CON_PROP_QUESTION:
        !           133:                        if((js_str=JS_NewStringCopyZ(cx, sbbs->question))==NULL)
        !           134:                                return(JS_FALSE);
        !           135:                        *vp = STRING_TO_JSVAL(js_str);
        !           136:                        return(JS_TRUE);
        !           137:                case CON_PROP_CTRLKEY_PASSTHRU:
        !           138:                        val=sbbs->cfg.ctrlkey_passthru;
        !           139:                        break;
        !           140:                case CON_PROP_INBUF_LEVEL:
        !           141:                        val=RingBufFull(&sbbs->inbuf);
        !           142:                        break;
        !           143:                case CON_PROP_INBUF_SPACE:
        !           144:                        val=RingBufFree(&sbbs->inbuf);
        !           145:                        break;
        !           146:                case CON_PROP_OUTBUF_LEVEL:
        !           147:                        val=RingBufFull(&sbbs->outbuf);
        !           148:                        break;
        !           149:                case CON_PROP_OUTBUF_SPACE:
        !           150:                        val=RingBufFree(&sbbs->outbuf);
        !           151:                        break;
        !           152:                default:
        !           153:                        return(JS_TRUE);
        !           154:        }
        !           155: 
        !           156:        *vp = INT_TO_JSVAL(val);
        !           157: 
        !           158:        return(JS_TRUE);
        !           159: }
        !           160: 
        !           161: static JSBool js_console_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
        !           162: {
        !           163:        int32           val=0;
        !           164:     jsint       tiny;
        !           165:        sbbs_t*         sbbs;
        !           166:        JSString*       str;
        !           167: 
        !           168:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           169:                return(JS_FALSE);
        !           170: 
        !           171:     tiny = JSVAL_TO_INT(id);
        !           172: 
        !           173:        if(JSVAL_IS_NUMBER(*vp) || JSVAL_IS_BOOLEAN(*vp))
        !           174:                JS_ValueToInt32(cx, *vp, &val);
        !           175: 
        !           176:        switch(tiny) {
        !           177:                case CON_PROP_STATUS:
        !           178:                        sbbs->console=val;
        !           179:                        break;
        !           180:                case CON_PROP_LNCNTR:
        !           181:                        sbbs->lncntr=val;
        !           182:                        break;
        !           183:                case CON_PROP_ATTR:
        !           184:                        if(JSVAL_IS_STRING(*vp)) {
        !           185:                                if((str=JS_ValueToString(cx, *vp))==NULL)
        !           186:                                        break;
        !           187:                                val=attrstr(JS_GetStringBytes(str));
        !           188:                        }
        !           189:                        sbbs->attr(val);
        !           190:                        break;
        !           191:                case CON_PROP_TOS:
        !           192:                        sbbs->tos=val;
        !           193:                        break;
        !           194:                case CON_PROP_ROWS:
        !           195:                        sbbs->rows=val;
        !           196:                        break;
        !           197:                case CON_PROP_COLUMNS:
        !           198:                        sbbs->cols=val;
        !           199:                        break;
        !           200:                case CON_PROP_AUTOTERM:
        !           201:                        sbbs->autoterm=val;
        !           202:                        break;
        !           203:                case CON_PROP_TERMINAL:
        !           204:                        if((str=JS_ValueToString(cx, *vp))==NULL)
        !           205:                                break;
        !           206:                        SAFECOPY(sbbs->terminal,JS_GetStringBytes(str));
        !           207:                        break;
        !           208:                case CON_PROP_TIMEOUT:
        !           209:                        sbbs->timeout=val;
        !           210:                        break;
        !           211:                case CON_PROP_TIMELEFT_WARN:
        !           212:                        sbbs->timeleft_warn=val;
        !           213:                        break;
        !           214:                case CON_PROP_ABORTED:
        !           215:                        if(val)
        !           216:                                sbbs->sys_status|=SS_ABORT;
        !           217:                        else
        !           218:                                sbbs->sys_status&=~SS_ABORT;
        !           219:                        break;
        !           220:                case CON_PROP_ABORTABLE:
        !           221:                        sbbs->rio_abortable=val 
        !           222:                                ? true:false; // This is a dumb bool conversion to make BC++ happy
        !           223:                        break;
        !           224:                case CON_PROP_TELNET_MODE:
        !           225:                        sbbs->telnet_mode=val;
        !           226:                        break;
        !           227:                case CON_PROP_GETSTR_OFFSET:
        !           228:                        sbbs->getstr_offset=val;
        !           229:                        break;
        !           230:                case CON_PROP_QUESTION:
        !           231:                        if((str=JS_ValueToString(cx, *vp))==NULL)
        !           232:                                break;
        !           233:                        SAFECOPY(sbbs->question,JS_GetStringBytes(str));
        !           234:                        break;
        !           235:                case CON_PROP_CTRLKEY_PASSTHRU:
        !           236:                        if(JSVAL_IS_STRING(*vp)) {
        !           237:                                /* op can be 0 for replace, + for add, or - for remove */
        !           238:                                int op=0;
        !           239:                                char *s;
        !           240:                                char ctrl;
        !           241: 
        !           242:                                if((str=JS_ValueToString(cx, *vp))==NULL)
        !           243:                                        break;
        !           244:                                val=sbbs->cfg.ctrlkey_passthru;
        !           245:                                for(s=JS_GetStringBytes(str); *s; s++) {
        !           246:                                        if(*s=='+')
        !           247:                                                op=1;
        !           248:                                        else if(*s=='-')
        !           249:                                                op=2;
        !           250:                                        else {
        !           251:                                                if(!op) {
        !           252:                                                        val=0;
        !           253:                                                        op=1;
        !           254:                                                }
        !           255:                                                ctrl=toupper(*s);
        !           256:                                                ctrl&=0x1f;                     /* Ensure it fits */
        !           257:                                                switch(op) {
        !           258:                                                        case 1:         /* Add to the set */
        !           259:                                                                val |= 1<<ctrl;
        !           260:                                                                break;
        !           261:                                                        case 2:         /* Remove from the set */
        !           262:                                                                val &= ~(1<<ctrl);
        !           263:                                                                break;
        !           264:                                                }
        !           265:                                        }
        !           266:                                }
        !           267:                        }
        !           268:                        sbbs->cfg.ctrlkey_passthru=val;
        !           269:                        break;
        !           270:                default:
        !           271:                        return(JS_TRUE);
        !           272:        }
        !           273: 
        !           274:        return(JS_TRUE);
        !           275: }
        !           276: 
        !           277: #define CON_PROP_FLAGS JSPROP_ENUMERATE
        !           278: 
        !           279: static jsSyncPropertySpec js_console_properties[] = {
        !           280: /*              name                           ,tinyid                                         ,flags                  ,ver    */
        !           281: 
        !           282:        {       "status"                        ,CON_PROP_STATUS                        ,CON_PROP_FLAGS ,310},
        !           283:        {       "line_counter"          ,CON_PROP_LNCNTR                        ,CON_PROP_FLAGS ,310},
        !           284:        {       "attributes"            ,CON_PROP_ATTR                          ,CON_PROP_FLAGS ,310},
        !           285:        {       "top_of_screen"         ,CON_PROP_TOS                           ,CON_PROP_FLAGS ,310},
        !           286:        {       "screen_rows"           ,CON_PROP_ROWS                          ,CON_PROP_FLAGS ,310},
        !           287:        {       "screen_columns"        ,CON_PROP_COLUMNS                       ,CON_PROP_FLAGS ,311},
        !           288:        {       "autoterm"                      ,CON_PROP_AUTOTERM                      ,CON_PROP_FLAGS ,310},
        !           289:        {       "terminal"                      ,CON_PROP_TERMINAL                      ,CON_PROP_FLAGS ,311},
        !           290:        {       "timeout"                       ,CON_PROP_TIMEOUT                       ,CON_PROP_FLAGS ,310},
        !           291:        {       "timeleft_warning"      ,CON_PROP_TIMELEFT_WARN         ,CON_PROP_FLAGS ,310},
        !           292:        {       "aborted"                       ,CON_PROP_ABORTED                       ,CON_PROP_FLAGS ,310},
        !           293:        {       "abortable"                     ,CON_PROP_ABORTABLE                     ,CON_PROP_FLAGS ,310},
        !           294:        {       "telnet_mode"           ,CON_PROP_TELNET_MODE           ,CON_PROP_FLAGS ,310},
        !           295:        {       "wordwrap"                      ,CON_PROP_WORDWRAP                      ,JSPROP_ENUMERATE|JSPROP_READONLY ,310},
        !           296:        {       "question"                      ,CON_PROP_QUESTION                      ,CON_PROP_FLAGS ,310},
        !           297:        {       "getstr_offset"         ,CON_PROP_GETSTR_OFFSET         ,CON_PROP_FLAGS ,311},
        !           298:        {       "ctrlkey_passthru"      ,CON_PROP_CTRLKEY_PASSTHRU      ,CON_PROP_FLAGS ,310},
        !           299:        {       "input_buffer_level",CON_PROP_INBUF_LEVEL               ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
        !           300:        {       "input_buffer_space",CON_PROP_INBUF_SPACE               ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
        !           301:        {       "output_buffer_level",CON_PROP_OUTBUF_LEVEL             ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
        !           302:        {       "output_buffer_space",CON_PROP_OUTBUF_SPACE             ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
        !           303:        {0}
        !           304: };
        !           305: 
        !           306: #ifdef BUILD_JSDOCS
        !           307: static char* con_prop_desc[] = {
        !           308:         "status bitfield (see <tt>CON_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
        !           309:        ,"current line counter (used for automatic screen pause)"
        !           310:        ,"current display attributes (set with number or string value)"
        !           311:        ,"set to 1 if the terminal cursor is already at the top of the screen"
        !           312:        ,"number of terminal screen rows (in lines)"
        !           313:        ,"number of terminal screen columns (in character cells)"
        !           314:        ,"bitfield of automatically detected terminal settings "
        !           315:                "(see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
        !           316:        ,"terminal type description (e.g. 'ANSI')"
        !           317:        ,"user inactivity timeout reference"
        !           318:        ,"low timeleft warning flag"
        !           319:        ,"input/output has been aborted"
        !           320:        ,"output can be aborted with Ctrl-C"
        !           321:        ,"current telnet mode bitfield (see <tt>TELNET_MODE_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
        !           322:        ,"word-wrap buffer (used by getstr) - <small>READ ONLY</small>"
        !           323:        ,"current yes/no question (set by yesno and noyes)"
        !           324:        ,"cursor position offset for use with <tt>getstr(K_USEOFFSET)</tt>"
        !           325:        ,"control key pass-through bitmask, set bits represent control key combinations "
        !           326:                "<i>not</i> handled by <tt>inkey()</tt> method "
        !           327:                "This may optionally be specified as a string of characters. "
        !           328:                "The format of this string is [+-][@-_]. If neither plus nor minus is "
        !           329:                "the first character, the value will be replaced by one constructed "
        !           330:                "from the string. A + indicates that characters following will be "
        !           331:                "added to the set, and a - indicates they should be removed. "
        !           332:                "ex: <tt>console.ctrlkey_passthru=\"-UP+AB\"</tt> will clear CTRL-U and "
        !           333:                "CTRL-P and set CTRL-A and CTRL-B."
        !           334:        ,"number of bytes currently in the input buffer (from the remote client) - <small>READ ONLY</small>"
        !           335:        ,"number of bytes available in the input buffer - <small>READ ONLY</small>"
        !           336:        ,"number of bytes currently in the output buffer (from the local server) - <small>READ ONLY</small>"
        !           337:        ,"number of bytes available in the output buffer - <small>READ ONLY</small>"
        !           338:        ,NULL
        !           339: };
        !           340: #endif
        !           341: 
        !           342: /**************************/
        !           343: /* Console Object Methods */
        !           344: /**************************/
        !           345: 
        !           346: static JSBool
        !           347: js_inkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           348: {
        !           349:        char            key[2];
        !           350:        int32           mode=0;
        !           351:        int32           timeout=0;
        !           352:        sbbs_t*         sbbs;
        !           353:     JSString*  js_str;
        !           354: 
        !           355:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           356:                return(JS_FALSE);
        !           357: 
        !           358:        if(argc)
        !           359:                JS_ValueToInt32(cx,argv[0],&mode);
        !           360:        if(argc>1)
        !           361:                JS_ValueToInt32(cx,argv[1],&timeout);
        !           362:        key[0]=sbbs->inkey(mode,timeout);
        !           363:        key[1]=0;
        !           364: 
        !           365:        if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
        !           366:                return(JS_FALSE);
        !           367: 
        !           368:        *rval = STRING_TO_JSVAL(js_str);
        !           369:     return(JS_TRUE);
        !           370: }
        !           371: 
        !           372: static JSBool
        !           373: js_getkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           374: {
        !           375:        char            key[2];
        !           376:        int32           mode=0;
        !           377:        sbbs_t*         sbbs;
        !           378:     JSString*  js_str;
        !           379: 
        !           380:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           381:                return(JS_FALSE);
        !           382: 
        !           383:        if(argc)
        !           384:                JS_ValueToInt32(cx,argv[0],&mode);
        !           385:        key[0]=sbbs->getkey(mode);
        !           386:        key[1]=0;
        !           387: 
        !           388:        if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
        !           389:                return(JS_FALSE);
        !           390: 
        !           391:        *rval = STRING_TO_JSVAL(js_str);
        !           392:     return(JS_TRUE);
        !           393: }
        !           394: 
        !           395: static JSBool
        !           396: js_handle_ctrlkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           397: {
        !           398:        char            key;
        !           399:        int32           mode=0;
        !           400:        sbbs_t*         sbbs;
        !           401:     JSString*  js_str;
        !           402: 
        !           403:        *rval = JSVAL_FALSE;
        !           404: 
        !           405:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           406:                return(JS_FALSE);
        !           407: 
        !           408:        if(JSVAL_IS_INT(argv[0]))
        !           409:                key=(char)JSVAL_TO_INT(argv[0]);
        !           410:        else {
        !           411:                if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
        !           412:                        return(JS_FALSE);
        !           413:                key=*JS_GetStringBytes(js_str);
        !           414:        }
        !           415: 
        !           416:        if(argc>1)
        !           417:                JS_ValueToInt32(cx, argv[1], &mode);
        !           418: 
        !           419:        *rval = BOOLEAN_TO_JSVAL(sbbs->handle_ctrlkey(key,mode)==0);
        !           420:     return(JS_TRUE);
        !           421: }
        !           422: 
        !           423: static JSBool
        !           424: js_getstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           425: {
        !           426:        char            *p;
        !           427:        long            mode=0;
        !           428:        uintN           i;
        !           429:        size_t          maxlen=0;
        !           430:        sbbs_t*         sbbs;
        !           431:     JSString*  js_str=NULL;
        !           432: 
        !           433:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           434:                return(JS_FALSE);
        !           435: 
        !           436:        for(i=0;i<argc;i++) {
        !           437:                if(JSVAL_IS_NUMBER(argv[i])) {
        !           438:                        if(!maxlen)
        !           439:                                JS_ValueToInt32(cx,argv[i],(int32*)&maxlen);
        !           440:                        else
        !           441:                                JS_ValueToInt32(cx,argv[i],(int32*)&mode);
        !           442:                        continue;
        !           443:                }
        !           444:                if(JSVAL_IS_STRING(argv[i])) {
        !           445:                        js_str = JS_ValueToString(cx, argv[i]);
        !           446:                        if (!js_str)
        !           447:                            return(JS_FALSE);
        !           448:                }
        !           449:        }
        !           450: 
        !           451:        if(!maxlen) maxlen=128;
        !           452: 
        !           453:        if((p=(char *)calloc(1,maxlen+1))==NULL)
        !           454:                return(JS_FALSE);
        !           455: 
        !           456:        if(js_str!=NULL)
        !           457:                sprintf(p,"%.*s",(int)maxlen,JS_GetStringBytes(js_str));
        !           458: 
        !           459:        sbbs->getstr(p,maxlen,mode);
        !           460: 
        !           461:        js_str = JS_NewStringCopyZ(cx, p);
        !           462: 
        !           463:        free(p);
        !           464: 
        !           465:        if(js_str==NULL)
        !           466:                return(JS_FALSE);
        !           467: 
        !           468:        *rval = STRING_TO_JSVAL(js_str);
        !           469:     return(JS_TRUE);
        !           470: }
        !           471: 
        !           472: static JSBool
        !           473: js_getnum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           474: {
        !           475:        ulong           maxnum=~0;
        !           476:        sbbs_t*         sbbs;
        !           477: 
        !           478:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           479:                return(JS_FALSE);
        !           480: 
        !           481:        if(argc && JSVAL_IS_NUMBER(argv[0]))
        !           482:                JS_ValueToInt32(cx,argv[0],(int32*)&maxnum);
        !           483: 
        !           484:        *rval = INT_TO_JSVAL(sbbs->getnum(maxnum));
        !           485:     return(JS_TRUE);
        !           486: }
        !           487: 
        !           488: static JSBool
        !           489: js_getkeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           490: {
        !           491:        char            key[2];
        !           492:        uintN           i;
        !           493:        long            val;
        !           494:        ulong           maxnum=~0;
        !           495:        sbbs_t*         sbbs;
        !           496:     JSString*  js_str=NULL;
        !           497: 
        !           498:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           499:                return(JS_FALSE);
        !           500: 
        !           501:        for(i=0;i<argc;i++) {
        !           502:                if(JSVAL_IS_NUMBER(argv[i])) {
        !           503:                        JS_ValueToInt32(cx,argv[i],(int32*)&maxnum);
        !           504:                        continue;
        !           505:                }
        !           506:                if(JSVAL_IS_STRING(argv[i])) {
        !           507:                        js_str = JS_ValueToString(cx, argv[i]);
        !           508:                }
        !           509:        }
        !           510:        if(js_str==NULL)
        !           511:                return(JS_FALSE);
        !           512: 
        !           513:        val=sbbs->getkeys(JS_GetStringBytes(js_str),maxnum);
        !           514: 
        !           515:        if(val==-1) {                   // abort
        !           516:                *rval = INT_TO_JSVAL(0);
        !           517:        } else if(val<0) {              // number
        !           518:                val&=~0x80000000;
        !           519:                *rval = INT_TO_JSVAL(val);
        !           520:        } else {                                // key
        !           521:                key[0]=(uchar)val;
        !           522:                key[1]=0;
        !           523:                if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
        !           524:                        return(JS_FALSE);
        !           525:                *rval = STRING_TO_JSVAL(js_str);
        !           526:        }
        !           527: 
        !           528:     return(JS_TRUE);
        !           529: }
        !           530: 
        !           531: static JSBool
        !           532: js_gettemplate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           533: {
        !           534:        char            str[128];
        !           535:        long            mode=0;
        !           536:        uintN           i;
        !           537:        sbbs_t*         sbbs;
        !           538:     JSString*  js_str=NULL;
        !           539:     JSString*  js_fmt=NULL;
        !           540: 
        !           541:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           542:                return(JS_FALSE);
        !           543: 
        !           544:        for(i=0;i<argc;i++) {
        !           545:                if(JSVAL_IS_STRING(argv[i])) {
        !           546:                        if(js_fmt==NULL)
        !           547:                                js_fmt = JS_ValueToString(cx, argv[i]);
        !           548:                        else
        !           549:                                js_str = JS_ValueToString(cx, argv[i]);
        !           550:                } else if(JSVAL_IS_NUMBER(argv[i]))
        !           551:                        JS_ValueToInt32(cx,argv[i],(int32*)&mode);
        !           552:        }
        !           553: 
        !           554:        if(js_fmt==NULL)
        !           555:                return(JS_FALSE);
        !           556: 
        !           557:        if(js_str==NULL)
        !           558:                str[0]=0;
        !           559:        else
        !           560:                SAFECOPY(str,JS_GetStringBytes(js_str));
        !           561: 
        !           562:        sbbs->gettmplt(str,JS_GetStringBytes(js_fmt),mode);
        !           563: 
        !           564:        if((js_str=JS_NewStringCopyZ(cx, str))==NULL)
        !           565:                return(JS_FALSE);
        !           566: 
        !           567:        *rval = STRING_TO_JSVAL(js_str);
        !           568:     return(JS_TRUE);
        !           569: }
        !           570: 
        !           571: static JSBool
        !           572: js_ungetstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           573: {
        !           574:        char*           p;
        !           575:        sbbs_t*         sbbs;
        !           576:     JSString*  js_str;
        !           577: 
        !           578:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           579:                return(JS_FALSE);
        !           580:        
        !           581:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
        !           582:                return(JS_FALSE);
        !           583: 
        !           584:        p=JS_GetStringBytes(js_str);
        !           585: 
        !           586:        while(p && *p)
        !           587:                sbbs->ungetkey(*(p++));
        !           588:     return(JS_TRUE);
        !           589: }
        !           590: 
        !           591: static JSBool
        !           592: js_yesno(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           593: {
        !           594:        sbbs_t*         sbbs;
        !           595:     JSString*  js_str;
        !           596: 
        !           597:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           598:                return(JS_FALSE);
        !           599:        
        !           600:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
        !           601:                return(JS_FALSE);
        !           602: 
        !           603:        *rval = BOOLEAN_TO_JSVAL(sbbs->yesno(JS_GetStringBytes(js_str)));
        !           604:     return(JS_TRUE);
        !           605: }
        !           606: 
        !           607: static JSBool
        !           608: js_noyes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           609: {
        !           610:        sbbs_t*         sbbs;
        !           611:     JSString*  js_str;
        !           612: 
        !           613:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           614:                return(JS_FALSE);
        !           615:        
        !           616:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
        !           617:                return(JS_FALSE);
        !           618: 
        !           619:        *rval = BOOLEAN_TO_JSVAL(sbbs->noyes(JS_GetStringBytes(js_str)));
        !           620:     return(JS_TRUE);
        !           621: }
        !           622: 
        !           623: static JSBool
        !           624: js_mnemonics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           625: {
        !           626:        sbbs_t*         sbbs;
        !           627:     JSString*  js_str;
        !           628: 
        !           629:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           630:                return(JS_FALSE);
        !           631: 
        !           632:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
        !           633:                return(JS_FALSE);
        !           634:        
        !           635:        sbbs->mnemonics(JS_GetStringBytes(js_str));
        !           636:     return(JS_TRUE);
        !           637: }
        !           638: 
        !           639: static void
        !           640: js_set_attr(JSContext* cx, sbbs_t* sbbs, jsval val)
        !           641: {
        !           642:        int32           attr;
        !           643: 
        !           644:        if(JSVAL_IS_STRING(val))
        !           645:                attr=attrstr(js_ValueToStringBytes(cx,val,NULL));
        !           646:        else
        !           647:                JS_ValueToInt32(cx, val, &attr);
        !           648: 
        !           649:        sbbs->attr(attr);
        !           650: }
        !           651: 
        !           652: static JSBool
        !           653: js_clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           654: {
        !           655:        sbbs_t*         sbbs;
        !           656: 
        !           657:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           658:                return(JS_FALSE);
        !           659: 
        !           660:        if(argc)
        !           661:                js_set_attr(cx, sbbs, argv[0]);
        !           662: 
        !           663:        sbbs->CLS;
        !           664:     return(JS_TRUE);
        !           665: }
        !           666: 
        !           667: static JSBool
        !           668: js_clearline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           669: {
        !           670:        sbbs_t*         sbbs;
        !           671: 
        !           672:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           673:                return(JS_FALSE);
        !           674: 
        !           675:        if(argc)
        !           676:                js_set_attr(cx, sbbs, argv[0]);
        !           677: 
        !           678:        sbbs->clearline();
        !           679:     return(JS_TRUE);
        !           680: }
        !           681: 
        !           682: static JSBool
        !           683: js_cleartoeol(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           684: {
        !           685:        sbbs_t*         sbbs;
        !           686: 
        !           687:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           688:                return(JS_FALSE);
        !           689: 
        !           690:        if(argc)
        !           691:                js_set_attr(cx, sbbs, argv[0]);
        !           692: 
        !           693:        sbbs->cleartoeol();
        !           694:     return(JS_TRUE);
        !           695: }
        !           696: 
        !           697: static JSBool
        !           698: js_crlf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           699: {
        !           700:        sbbs_t*         sbbs;
        !           701: 
        !           702:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           703:                return(JS_FALSE);
        !           704: 
        !           705:        sbbs->outchar(CR);
        !           706:        sbbs->outchar(LF);
        !           707:     return(JS_TRUE);
        !           708: }
        !           709: 
        !           710: static JSBool
        !           711: js_pause(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           712: {
        !           713:        sbbs_t*         sbbs;
        !           714: 
        !           715:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           716:                return(JS_FALSE);
        !           717: 
        !           718:        sbbs->pause();
        !           719:     return(JS_TRUE);
        !           720: }
        !           721: 
        !           722: static JSBool
        !           723: js_beep(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           724: {
        !           725:        sbbs_t*         sbbs;
        !           726:        int32           i;
        !           727:        int32           count=1;
        !           728: 
        !           729:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           730:                return(JS_FALSE);
        !           731: 
        !           732:        if(argc)
        !           733:                JS_ValueToInt32(cx, argv[0], &count);
        !           734:        for(i=0;i<count;i++)
        !           735:                sbbs->outchar('\a');
        !           736:        
        !           737:     return(JS_TRUE);
        !           738: }
        !           739: 
        !           740: static JSBool
        !           741: js_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           742: {
        !           743:     JSString*  str;
        !           744:        sbbs_t*         sbbs;
        !           745: 
        !           746:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           747:                return(JS_FALSE);
        !           748: 
        !           749:        str = JS_ValueToString(cx, argv[0]);
        !           750:        if (!str)
        !           751:                return(JS_FALSE);
        !           752: 
        !           753:        sbbs->bputs(JS_GetStringBytes(str));
        !           754:     return(JS_TRUE);
        !           755: }
        !           756: 
        !           757: static JSBool
        !           758: js_strlen(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           759: {
        !           760:     JSString*  str;
        !           761: 
        !           762:        if((str=JS_ValueToString(cx, argv[0]))==NULL)
        !           763:                return(JS_FALSE);
        !           764: 
        !           765:        *rval = INT_TO_JSVAL(bstrlen(JS_GetStringBytes(str)));
        !           766:     return(JS_TRUE);
        !           767: }
        !           768: 
        !           769: static JSBool
        !           770: js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           771: {
        !           772:     JSString*  str;
        !           773:        sbbs_t*         sbbs;
        !           774: 
        !           775:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           776:                return(JS_FALSE);
        !           777: 
        !           778:        str = JS_ValueToString(cx, argv[0]);
        !           779:        if (!str)
        !           780:                return(JS_FALSE);
        !           781: 
        !           782:        sbbs->rputs(JS_GetStringBytes(str));
        !           783:     return(JS_TRUE);
        !           784: }
        !           785: 
        !           786: static JSBool
        !           787: js_putmsg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           788: {
        !           789:        long            mode=0;
        !           790:     JSString*  str;
        !           791:        sbbs_t*         sbbs;
        !           792: 
        !           793:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           794:                return(JS_FALSE);
        !           795: 
        !           796:        str = JS_ValueToString(cx, argv[0]);
        !           797:        if (!str)
        !           798:                return(JS_FALSE);
        !           799: 
        !           800:        if(argc>1 && JSVAL_IS_NUMBER(argv[1]))
        !           801:                JS_ValueToInt32(cx,argv[1],(int32*)&mode);
        !           802: 
        !           803:        sbbs->putmsg(JS_GetStringBytes(str),mode);
        !           804:     return(JS_TRUE);
        !           805: }
        !           806: 
        !           807: static JSBool
        !           808: js_printfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           809: {
        !           810:        long            mode=0;
        !           811:     JSString*  str;
        !           812:        sbbs_t*         sbbs;
        !           813: 
        !           814:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           815:                return(JS_FALSE);
        !           816: 
        !           817:        str = JS_ValueToString(cx, argv[0]);
        !           818:        if (!str)
        !           819:                return(JS_FALSE);
        !           820: 
        !           821:        if(argc>1 && JSVAL_IS_NUMBER(argv[1]))
        !           822:                JS_ValueToInt32(cx,argv[1],(int32*)&mode);
        !           823: 
        !           824:        sbbs->printfile(JS_GetStringBytes(str),mode);
        !           825:     return(JS_TRUE);
        !           826: }
        !           827: 
        !           828: static JSBool
        !           829: js_printtail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           830: {
        !           831:        int                     lines=0;
        !           832:        long            mode=0;
        !           833:        uintN           i;
        !           834:        sbbs_t*         sbbs;
        !           835:     JSString*  js_str=NULL;
        !           836: 
        !           837:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           838:                return(JS_FALSE);
        !           839: 
        !           840:        for(i=0;i<argc;i++) {
        !           841:                if(JSVAL_IS_NUMBER(argv[i])) {
        !           842:                        if(!lines)
        !           843:                                JS_ValueToInt32(cx,argv[i],(int32*)&lines);
        !           844:                        else
        !           845:                                JS_ValueToInt32(cx,argv[i],(int32*)&mode);
        !           846:                } else if(JSVAL_IS_STRING(argv[i]))
        !           847:                        js_str = JS_ValueToString(cx, argv[i]);
        !           848:        }
        !           849: 
        !           850:        if(js_str==NULL)
        !           851:                return(JS_FALSE);
        !           852: 
        !           853:        if(!lines) 
        !           854:                lines=5;
        !           855: 
        !           856:        sbbs->printtail(JS_GetStringBytes(js_str),lines,mode);
        !           857:     return(JS_TRUE);
        !           858: }
        !           859: 
        !           860: static JSBool
        !           861: js_editfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           862: {
        !           863:     JSString*  str;
        !           864:        sbbs_t*         sbbs;
        !           865: 
        !           866:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           867:                return(JS_FALSE);
        !           868: 
        !           869:        if((str=JS_ValueToString(cx, argv[0]))==NULL)
        !           870:                return(JS_FALSE);
        !           871: 
        !           872:        sbbs->editfile(JS_GetStringBytes(str));
        !           873:     return(JS_TRUE);
        !           874: }
        !           875: 
        !           876: 
        !           877: static JSBool
        !           878: js_uselect(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           879: {
        !           880:        uintN           i;
        !           881:        int32           num=0;
        !           882:        char*           title=NULL;
        !           883:        char*           item=NULL;
        !           884:        char*           ar_str;
        !           885:        uchar*          ar=NULL;
        !           886:        sbbs_t*         sbbs;
        !           887:     JSString*  js_str;
        !           888: 
        !           889:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           890:                return(JS_FALSE);
        !           891:        
        !           892:        if(!argc) {
        !           893:                *rval = INT_TO_JSVAL(sbbs->uselect(0,0,NULL,NULL,NULL));
        !           894:                return(JS_TRUE);
        !           895:        }
        !           896:        
        !           897:        for(i=0;i<argc;i++) {
        !           898:                if(JSVAL_IS_NUMBER(argv[i])) {
        !           899:                        JS_ValueToInt32(cx,argv[i],&num);
        !           900:                        continue;
        !           901:                }
        !           902:                if((js_str=JS_ValueToString(cx, argv[i]))==NULL)
        !           903:                        return(JS_FALSE);
        !           904: 
        !           905:                if(title==NULL) 
        !           906:                        title=JS_GetStringBytes(js_str);
        !           907:                else if(item==NULL)
        !           908:                        item=JS_GetStringBytes(js_str);
        !           909:                else {
        !           910:                        ar_str=JS_GetStringBytes(js_str);
        !           911:                        ar=arstr(NULL,ar_str,&sbbs->cfg);
        !           912:                }
        !           913:        }
        !           914: 
        !           915:        *rval = INT_TO_JSVAL(sbbs->uselect(1, num, title, item, ar));
        !           916:     return(JS_TRUE);
        !           917: }
        !           918: 
        !           919: static JSBool
        !           920: js_center(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           921: {
        !           922:     JSString*  str;
        !           923:        sbbs_t*         sbbs;
        !           924: 
        !           925:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           926:                return(JS_FALSE);
        !           927: 
        !           928:        str = JS_ValueToString(cx, argv[0]);
        !           929:        if (!str)
        !           930:                return(JS_FALSE);
        !           931: 
        !           932:        sbbs->center(JS_GetStringBytes(str));
        !           933:     return(JS_TRUE);
        !           934: }
        !           935: 
        !           936: static JSBool
        !           937: js_saveline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           938: {
        !           939:        sbbs_t*         sbbs;
        !           940: 
        !           941:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           942:                return(JS_FALSE);
        !           943: 
        !           944:        sbbs->slatr[sbbs->slcnt]=sbbs->latr; 
        !           945:        sprintf(sbbs->slbuf[sbbs->slcnt<SAVE_LINES ? sbbs->slcnt++ : sbbs->slcnt] 
        !           946:                        ,"%.*s",sbbs->lbuflen,sbbs->lbuf); 
        !           947:        sbbs->lbuflen=0; 
        !           948:     return(JS_TRUE);
        !           949: }
        !           950: 
        !           951: static JSBool
        !           952: js_restoreline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           953: {
        !           954:        sbbs_t*         sbbs;
        !           955: 
        !           956:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           957:                return(JS_FALSE);
        !           958: 
        !           959:        sbbs->lbuflen=0; 
        !           960:        sbbs->attr(sbbs->slatr[--sbbs->slcnt]);
        !           961:        sbbs->rputs(sbbs->slbuf[sbbs->slcnt]); 
        !           962:        sbbs->curatr=LIGHTGRAY;
        !           963:     return(JS_TRUE);
        !           964: }
        !           965: 
        !           966: static JSBool
        !           967: js_ansi(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           968: {
        !           969:        int32           attr=0;
        !           970:        JSString*       js_str;
        !           971:        sbbs_t*         sbbs;
        !           972: 
        !           973:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           974:                return(JS_FALSE);
        !           975: 
        !           976:        if(argc)
        !           977:                JS_ValueToInt32(cx,argv[0],&attr);
        !           978:        if((js_str=JS_NewStringCopyZ(cx,sbbs->ansi(attr)))==NULL)
        !           979:                return(JS_FALSE);
        !           980: 
        !           981:        *rval = STRING_TO_JSVAL(js_str);
        !           982:     return(JS_TRUE);
        !           983: }
        !           984: 
        !           985: static JSBool
        !           986: js_pushxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           987: {
        !           988:        sbbs_t*         sbbs;
        !           989: 
        !           990:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !           991:                return(JS_FALSE);
        !           992: 
        !           993:        sbbs->ANSI_SAVE();
        !           994:     return(JS_TRUE);
        !           995: }
        !           996: 
        !           997: static JSBool
        !           998: js_popxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           999: {
        !          1000:        sbbs_t*         sbbs;
        !          1001: 
        !          1002:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1003:                return(JS_FALSE);
        !          1004: 
        !          1005:        sbbs->ANSI_RESTORE();
        !          1006:     return(JS_TRUE);
        !          1007: }
        !          1008: 
        !          1009: static JSBool
        !          1010: js_gotoxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1011: {
        !          1012:        int32           x=1,y=1;
        !          1013:        jsval           val;
        !          1014:        sbbs_t*         sbbs;
        !          1015: 
        !          1016:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1017:                return(JS_FALSE);
        !          1018: 
        !          1019:        if(JSVAL_IS_OBJECT(argv[0])) {
        !          1020:                JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[0]),"x", &val);
        !          1021:                JS_ValueToInt32(cx,val,&x);
        !          1022:                JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[0]),"y", &val);
        !          1023:                JS_ValueToInt32(cx,val,&y);
        !          1024:        } else {
        !          1025:                JS_ValueToInt32(cx,argv[0],&x);
        !          1026:                JS_ValueToInt32(cx,argv[1],&y);
        !          1027:        }
        !          1028: 
        !          1029:        sbbs->GOTOXY(x,y);
        !          1030:     return(JS_TRUE);
        !          1031: }
        !          1032: 
        !          1033: 
        !          1034: static JSBool
        !          1035: js_getxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1036: {
        !          1037:        sbbs_t*         sbbs;
        !          1038:        int                     x,y;
        !          1039:        JSObject*       screen;
        !          1040: 
        !          1041:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1042:                return(JS_FALSE);
        !          1043:  
        !          1044:        sbbs->ansi_getxy(&x,&y);
        !          1045: 
        !          1046:        if((screen=JS_NewObject(cx,NULL,NULL,obj))==NULL)
        !          1047:                return(JS_TRUE);
        !          1048: 
        !          1049:        JS_DefineProperty(cx, screen, "x", INT_TO_JSVAL(x)
        !          1050:                ,NULL,NULL,JSPROP_ENUMERATE);
        !          1051:        JS_DefineProperty(cx, screen, "y", INT_TO_JSVAL(y)
        !          1052:                ,NULL,NULL,JSPROP_ENUMERATE);
        !          1053: 
        !          1054:        *rval = OBJECT_TO_JSVAL(screen);
        !          1055:     return(JS_TRUE);
        !          1056: }
        !          1057: 
        !          1058: static JSBool
        !          1059: js_cursor_home(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1060: {
        !          1061:        sbbs_t*         sbbs;
        !          1062: 
        !          1063:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1064:                return(JS_FALSE);
        !          1065: 
        !          1066:        sbbs->cursor_home();
        !          1067:     return(JS_TRUE);
        !          1068: }
        !          1069: 
        !          1070: static JSBool
        !          1071: js_cursor_up(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1072: {
        !          1073:        int32           val=1;
        !          1074:        sbbs_t*         sbbs;
        !          1075: 
        !          1076:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1077:                return(JS_FALSE);
        !          1078: 
        !          1079:        if(argc)
        !          1080:                JS_ValueToInt32(cx,argv[0],&val);
        !          1081:        sbbs->cursor_up(val);
        !          1082:     return(JS_TRUE);
        !          1083: }
        !          1084: 
        !          1085: static JSBool
        !          1086: js_cursor_down(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1087: {
        !          1088:        int32           val=1;
        !          1089:        sbbs_t*         sbbs;
        !          1090: 
        !          1091:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1092:                return(JS_FALSE);
        !          1093: 
        !          1094:        if(argc)
        !          1095:                JS_ValueToInt32(cx,argv[0],&val);
        !          1096:        sbbs->cursor_down(val);
        !          1097:     return(JS_TRUE);
        !          1098: }
        !          1099: 
        !          1100: static JSBool
        !          1101: js_cursor_right(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1102: {
        !          1103:        int32           val=1;
        !          1104:        sbbs_t*         sbbs;
        !          1105: 
        !          1106:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1107:                return(JS_FALSE);
        !          1108: 
        !          1109:        if(argc)
        !          1110:                JS_ValueToInt32(cx,argv[0],&val);
        !          1111:        sbbs->cursor_right(val);
        !          1112:     return(JS_TRUE);
        !          1113: }
        !          1114: 
        !          1115: static JSBool
        !          1116: js_cursor_left(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1117: {
        !          1118:        int32           val=1;
        !          1119:        sbbs_t*         sbbs;
        !          1120: 
        !          1121:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1122:                return(JS_FALSE);
        !          1123: 
        !          1124:        if(argc)
        !          1125:                JS_ValueToInt32(cx,argv[0],&val);
        !          1126:        sbbs->cursor_left(val);
        !          1127:     return(JS_TRUE);
        !          1128: }
        !          1129: 
        !          1130: static JSBool
        !          1131: js_getlines(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1132: {
        !          1133:        sbbs_t*         sbbs;
        !          1134: 
        !          1135:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1136:                return(JS_FALSE);
        !          1137: 
        !          1138:        sbbs->ansi_getlines();
        !          1139:     return(JS_TRUE);
        !          1140: }
        !          1141: 
        !          1142: static JSBool
        !          1143: js_lock_input(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1144: {
        !          1145:        sbbs_t*         sbbs;
        !          1146:        JSBool          lock=TRUE;
        !          1147: 
        !          1148:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1149:                return(JS_FALSE);
        !          1150: 
        !          1151:        if(argc)
        !          1152:                JS_ValueToBoolean(cx, argv[0], &lock);
        !          1153: 
        !          1154:        if(lock) {
        !          1155:                pthread_mutex_lock(&sbbs->input_thread_mutex);
        !          1156:                sbbs->input_thread_mutex_locked=true;
        !          1157:        } else if(sbbs->input_thread_mutex_locked) {
        !          1158:                pthread_mutex_unlock(&sbbs->input_thread_mutex);
        !          1159:                sbbs->input_thread_mutex_locked=false;
        !          1160:        }
        !          1161: 
        !          1162:     return(JS_TRUE);
        !          1163: }
        !          1164: 
        !          1165: static JSBool
        !          1166: js_telnet_cmd(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1167: {
        !          1168:        sbbs_t*         sbbs;
        !          1169:        int32           cmd,opt=0;
        !          1170: 
        !          1171:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1172:                return(JS_FALSE);
        !          1173: 
        !          1174:        JS_ValueToInt32(cx,argv[0],&cmd);
        !          1175:        if(argc>1)
        !          1176:                JS_ValueToInt32(cx,argv[1],&opt);
        !          1177: 
        !          1178:        sbbs->send_telnet_cmd((uchar)cmd,(uchar)opt);
        !          1179: 
        !          1180:     return(JS_TRUE);
        !          1181: }
        !          1182: 
        !          1183: static JSBool
        !          1184: js_term_supports(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1185: {
        !          1186:        sbbs_t*         sbbs;
        !          1187:        int32           flags;
        !          1188: 
        !          1189:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1190:                return(JS_FALSE);
        !          1191: 
        !          1192:        if(argc) {
        !          1193:                if(!JS_ValueToInt32(cx,argv[0],&flags))
        !          1194:                        return(JS_FALSE);
        !          1195:                *rval = BOOLEAN_TO_JSVAL(sbbs->term_supports(flags));
        !          1196:        } else
        !          1197:                JS_NewNumberValue(cx,sbbs->term_supports(),rval);
        !          1198: 
        !          1199:     return(JS_TRUE);
        !          1200: }
        !          1201: 
        !          1202: static jsSyncMethodSpec js_console_functions[] = {
        !          1203:        {"inkey",                       js_inkey,                       0, JSTYPE_STRING,       JSDOCSTR("[mode=<tt>K_NONE</tt>] [,timeout=<tt>0</tt>]")
        !          1204:        ,JSDOCSTR("get a single key with optional <i>timeout</i> in milliseconds (defaults to 0, for no wait), "
        !          1205:                "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
        !          1206:        ,311
        !          1207:        },              
        !          1208:        {"getkey",                      js_getkey,                      0, JSTYPE_STRING,       JSDOCSTR("[mode=<tt>K_NONE</tt>]")
        !          1209:        ,JSDOCSTR("get a single key, with wait, "
        !          1210:                "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
        !          1211:        ,310
        !          1212:        },              
        !          1213:        {"getstr",                      js_getstr,                      0, JSTYPE_STRING,       JSDOCSTR("[string] [,maxlen=<tt>128</tt>] [,mode=<tt>K_NONE</tt>]")
        !          1214:        ,JSDOCSTR("get a text string from the user, "
        !          1215:                "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
        !          1216:        ,310
        !          1217:        },              
        !          1218:        {"getnum",                      js_getnum,                      0, JSTYPE_NUMBER,       JSDOCSTR("[maxnum]")
        !          1219:        ,JSDOCSTR("get a number between 1 and <i>maxnum</i> from the user")
        !          1220:        ,310
        !          1221:        },              
        !          1222:        {"getkeys",                     js_getkeys,                     1, JSTYPE_NUMBER,       JSDOCSTR("string keys [,maxnum]")
        !          1223:        ,JSDOCSTR("get one key from of a list of valid command <i>keys</i>, "
        !          1224:                "or a number between 1 and <i>maxnum</i>")
        !          1225:        ,310
        !          1226:        },              
        !          1227:        {"gettemplate",         js_gettemplate,         1, JSTYPE_STRING,       JSDOCSTR("format [,string] [,mode=<tt>0</tt>]")
        !          1228:        ,JSDOCSTR("get a string based on template")
        !          1229:        ,310
        !          1230:        },              
        !          1231:        {"ungetstr",            js_ungetstr,            1, JSTYPE_VOID,         JSDOCSTR("")
        !          1232:        ,JSDOCSTR("put a string in the keyboard buffer")
        !          1233:        ,310
        !          1234:        },              
        !          1235:        {"yesno",                       js_yesno,                       1, JSTYPE_BOOLEAN,      JSDOCSTR("question")
        !          1236:        ,JSDOCSTR("YES/no question")
        !          1237:        ,310
        !          1238:        },              
        !          1239:        {"noyes",                       js_noyes,                       1, JSTYPE_BOOLEAN,      JSDOCSTR("question")
        !          1240:        ,JSDOCSTR("NO/yes question")
        !          1241:        ,310
        !          1242:        },              
        !          1243:        {"mnemonics",           js_mnemonics,           1, JSTYPE_VOID,         JSDOCSTR("text")
        !          1244:        ,JSDOCSTR("print a mnemonics string, command keys highlighted with tilde (~) characters")
        !          1245:        ,310
        !          1246:        },              
        !          1247:        {"clear",           js_clear,                   0, JSTYPE_VOID,         JSDOCSTR("[attribute]")
        !          1248:        ,JSDOCSTR("clear screen and home cursor, "
        !          1249:                "optionally (in v3.13b+) setting current attribute first")
        !          1250:        ,310
        !          1251:        },
        !          1252:        {"home",            js_cursor_home,             0, JSTYPE_VOID,         JSDOCSTR("")
        !          1253:        ,JSDOCSTR("send cursor to home position (x,y:1,1)")
        !          1254:        ,311
        !          1255:        },
        !          1256:        {"clearline",       js_clearline,               0, JSTYPE_VOID,         JSDOCSTR("[attribute]")
        !          1257:        ,JSDOCSTR("clear current line, "
        !          1258:                "optionally (in v3.13b+) setting current attribute first")
        !          1259:        ,310
        !          1260:        },              
        !          1261:        {"cleartoeol",      js_cleartoeol,              0, JSTYPE_VOID,         JSDOCSTR("[attribute]")
        !          1262:        ,JSDOCSTR("clear to end-of-line (ANSI), "
        !          1263:                "optionally (in v3.13b+) setting current attribute first")
        !          1264:        ,311
        !          1265:        },              
        !          1266:        {"crlf",            js_crlf,                    0, JSTYPE_VOID,         JSDOCSTR("")
        !          1267:        ,JSDOCSTR("output a carriage-return/line-feed pair (new-line)")
        !          1268:        ,310
        !          1269:        },              
        !          1270:        {"pause",                       js_pause,                       0, JSTYPE_VOID,         JSDOCSTR("")
        !          1271:        ,JSDOCSTR("display pause prompt and wait for key hit")
        !          1272:        ,310
        !          1273:        },
        !          1274:        {"beep",                        js_beep,                        1, JSTYPE_VOID,         JSDOCSTR("[count=<tt>1</tt>]")
        !          1275:        ,JSDOCSTR("beep for count number of times (default count is 1)")
        !          1276:        ,311
        !          1277:        },
        !          1278:        {"print",                       js_print,                       1, JSTYPE_VOID,         JSDOCSTR("text")
        !          1279:        ,JSDOCSTR("display a string (supports Ctrl-A codes)")
        !          1280:        ,310
        !          1281:        },              
        !          1282:        {"write",                       js_write,                       1, JSTYPE_VOID,         JSDOCSTR("text")
        !          1283:        ,JSDOCSTR("display a raw string")
        !          1284:        ,310
        !          1285:        },              
        !          1286:        {"putmsg",                      js_putmsg,                      1, JSTYPE_VOID,         JSDOCSTR("text [,mode=<tt>P_NONE</tt>]")
        !          1287:        ,JSDOCSTR("display message text (Ctrl-A codes, @-codes, pipe codes, etc), "
        !          1288:                "see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
        !          1289:        ,310
        !          1290:        },              
        !          1291:        {"center",                      js_center,                      1, JSTYPE_VOID,         JSDOCSTR("text")
        !          1292:        ,JSDOCSTR("display a string centered on the screen")
        !          1293:        ,310
        !          1294:        },
        !          1295:        {"strlen",                      js_strlen,                      1, JSTYPE_NUMBER,       JSDOCSTR("text")
        !          1296:        ,JSDOCSTR("returns the number of characters in text, excluding Ctrl-A codes")
        !          1297:        ,310
        !          1298:        },
        !          1299:        {"printfile",           js_printfile,           1, JSTYPE_VOID,         JSDOCSTR("filename [,mode=<tt>P_NONE</tt>]")
        !          1300:        ,JSDOCSTR("print a message text file with optional mode")
        !          1301:        ,310
        !          1302:        },              
        !          1303:        {"printtail",           js_printtail,           2, JSTYPE_VOID,         JSDOCSTR("filename, lines [,mode=<tt>P_NONE</tt>]")
        !          1304:        ,JSDOCSTR("print last x lines of file with optional mode")
        !          1305:        ,310
        !          1306:        },              
        !          1307:        {"editfile",            js_editfile,            1, JSTYPE_VOID,         JSDOCSTR("filename")
        !          1308:        ,JSDOCSTR("edit/create a text file using the user's preferred message editor")
        !          1309:        ,310
        !          1310:        },              
        !          1311:        {"uselect",                     js_uselect,                     0, JSTYPE_NUMBER,       JSDOCSTR("[number, title, item] [,ars]")
        !          1312:        ,JSDOCSTR("user selection menu, call for each item, then with no args to display select menu")
        !          1313:        ,312
        !          1314:        },              
        !          1315:        {"saveline",            js_saveline,            0, JSTYPE_VOID,         JSDOCSTR("")
        !          1316:        ,JSDOCSTR("save last output line")
        !          1317:        ,310
        !          1318:        },              
        !          1319:        {"restoreline",         js_restoreline,         0, JSTYPE_VOID,         JSDOCSTR("")
        !          1320:        ,JSDOCSTR("restore last output line")
        !          1321:        ,310
        !          1322:        },              
        !          1323:        {"ansi",                        js_ansi,                        1, JSTYPE_STRING,       JSDOCSTR("attribute_number")
        !          1324:        ,JSDOCSTR("returns ANSI encoding of specified <i>attribute_number</i>")
        !          1325:        ,310
        !          1326:        },              
        !          1327:        {"ansi_save",           js_pushxy,                      0, JSTYPE_ALIAS },
        !          1328:        {"ansi_pushxy",         js_pushxy,                      0, JSTYPE_ALIAS },
        !          1329:        {"pushxy",                      js_pushxy,                      0, JSTYPE_VOID,         JSDOCSTR("")
        !          1330:        ,JSDOCSTR("save current cursor position (AKA ansi_save)")
        !          1331:        ,311
        !          1332:        },
        !          1333:        {"ansi_restore",        js_popxy,                       0, JSTYPE_ALIAS },
        !          1334:        {"ansi_popxy",          js_popxy,                       0, JSTYPE_ALIAS },
        !          1335:        {"popxy",                       js_popxy,                       0, JSTYPE_VOID,         JSDOCSTR("")
        !          1336:        ,JSDOCSTR("restore saved cursor position (AKA ansi_restore)")
        !          1337:        ,311
        !          1338:        },
        !          1339:        {"ansi_gotoxy",         js_gotoxy,                      1, JSTYPE_ALIAS },
        !          1340:        {"gotoxy",                      js_gotoxy,                      1, JSTYPE_VOID,         JSDOCSTR("[x,y] or [object { x,y }]")
        !          1341:        ,JSDOCSTR("move cursor to a specific screen coordinate (ANSI), "
        !          1342:        "arguments can be separate x and y cooridinates or an object with x and y properites "
        !          1343:        "(like that returned from <tt>console.getxy()</tt>)")
        !          1344:        ,311
        !          1345:        },
        !          1346:        {"ansi_up",                     js_cursor_up,           0, JSTYPE_ALIAS },
        !          1347:        {"up",                          js_cursor_up,           0, JSTYPE_VOID,         JSDOCSTR("[rows=<tt>1</tt>]")
        !          1348:        ,JSDOCSTR("move cursor up one or more rows (ANSI)")
        !          1349:        ,311
        !          1350:        },
        !          1351:        {"ansi_down",           js_cursor_down,         0, JSTYPE_ALIAS },
        !          1352:        {"down",                        js_cursor_down,         0, JSTYPE_VOID,         JSDOCSTR("[rows=<tt>1</tt>]")
        !          1353:        ,JSDOCSTR("move cursor down one or more rows (ANSI)")
        !          1354:        ,311
        !          1355:        },
        !          1356:        {"ansi_right",          js_cursor_right,        0, JSTYPE_ALIAS },
        !          1357:        {"right",                       js_cursor_right,        0, JSTYPE_VOID,         JSDOCSTR("[columns=<tt>1</tt>]")
        !          1358:        ,JSDOCSTR("move cursor right one or more columns (ANSI)")
        !          1359:        ,311
        !          1360:        },
        !          1361:        {"ansi_left",           js_cursor_left,         0, JSTYPE_ALIAS },
        !          1362:        {"left",                        js_cursor_left,         0, JSTYPE_VOID,         JSDOCSTR("[columns=<tt>1</tt>]")
        !          1363:        ,JSDOCSTR("move cursor left one or more columns (ANSI)")
        !          1364:        ,311
        !          1365:        },
        !          1366:        {"ansi_getlines",       js_getlines,            0, JSTYPE_ALIAS },
        !          1367:        {"getlines",            js_getlines,            0, JSTYPE_VOID,         JSDOCSTR("")
        !          1368:        ,JSDOCSTR("auto-detect the number of rows/lines on the user's terminal (ANSI)")
        !          1369:        ,311
        !          1370:        },
        !          1371:        {"ansi_getxy",          js_getxy,                       0, JSTYPE_ALIAS },
        !          1372:        {"getxy",                       js_getxy,                       0, JSTYPE_OBJECT,       JSDOCSTR("")
        !          1373:        ,JSDOCSTR("returns the current cursor position as an object (with x and y properties)")
        !          1374:        ,311
        !          1375:        },
        !          1376:        {"lock_input",          js_lock_input,          1, JSTYPE_VOID,         JSDOCSTR("[lock=<tt>true</tt>]")
        !          1377:        ,JSDOCSTR("lock the user input thread (allowing direct client socket access)")
        !          1378:        ,310
        !          1379:        },
        !          1380:        {"telnet_cmd",          js_telnet_cmd,          2, JSTYPE_VOID,         JSDOCSTR("command [,option=<tt>0</tt>]")
        !          1381:        ,JSDOCSTR("send Telnet command (with optional command option) to remote client")
        !          1382:        ,310
        !          1383:        },
        !          1384:        {"handle_ctrlkey",      js_handle_ctrlkey,      1, JSTYPE_BOOLEAN,      JSDOCSTR("key [,mode=<tt>K_NONE</tt>]")
        !          1385:        ,JSDOCSTR("call internal control key handler for specified control key, returns <tt>true</tt> if handled")
        !          1386:        ,311
        !          1387:        },
        !          1388:        {"term_supports",       js_term_supports,       1, JSTYPE_BOOLEAN,      JSDOCSTR("[terminal_flags]")
        !          1389:        ,JSDOCSTR("either returns <i>bool</i>, indicating whether or not the current user/client "
        !          1390:                "supports all the specified <i>terminal_flags</i>, or returns the current user/client's "
        !          1391:                "<i>terminal_flags</i> (numeric bit-field) if no <i>terminal_flags</i> were specified")
        !          1392:        ,314
        !          1393:        },
        !          1394:        {0}
        !          1395: };
        !          1396: 
        !          1397: 
        !          1398: static JSClass js_console_class = {
        !          1399:      "Console"                         /* name                 */
        !          1400:     ,0                                         /* flags                */
        !          1401:        ,JS_PropertyStub                /* addProperty  */
        !          1402:        ,JS_PropertyStub                /* delProperty  */
        !          1403:        ,js_console_get                 /* getProperty  */
        !          1404:        ,js_console_set                 /* setProperty  */
        !          1405:        ,JS_EnumerateStub               /* enumerate    */
        !          1406:        ,JS_ResolveStub                 /* resolve              */
        !          1407:        ,JS_ConvertStub                 /* convert              */
        !          1408:        ,JS_FinalizeStub                /* finalize             */
        !          1409: };
        !          1410: 
        !          1411: JSObject* js_CreateConsoleObject(JSContext* cx, JSObject* parent)
        !          1412: {
        !          1413:        JSObject*       obj;
        !          1414:        sbbs_t*         sbbs;
        !          1415: 
        !          1416:        if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
        !          1417:                return(NULL);
        !          1418: 
        !          1419:        if((obj=JS_DefineObject(cx, parent, "console", &js_console_class, NULL
        !          1420:                ,JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
        !          1421:                return(NULL);
        !          1422: 
        !          1423:        if(!js_DefineSyncProperties(cx, obj, js_console_properties))
        !          1424:                return(NULL);
        !          1425: 
        !          1426:        if (!js_DefineSyncMethods(cx, obj, js_console_functions, FALSE)) 
        !          1427:                return(NULL);
        !          1428: 
        !          1429:        /* Create an array of pre-defined colors */
        !          1430: 
        !          1431:        JSObject* color_list;
        !          1432: 
        !          1433:        if((color_list=JS_NewArrayObject(cx,0,NULL))==NULL)
        !          1434:                return(NULL);
        !          1435: 
        !          1436:        if(!JS_DefineProperty(cx, obj, "color_list", OBJECT_TO_JSVAL(color_list)
        !          1437:                ,NULL, NULL, 0))
        !          1438:                return(NULL);
        !          1439: 
        !          1440:        for(uint i=0;i<sbbs->cfg.total_colors;i++) {
        !          1441: 
        !          1442:                jsval val=INT_TO_JSVAL(sbbs->cfg.color[i]);
        !          1443:                if(!JS_SetElement(cx, color_list, i, &val))
        !          1444:                        return(NULL);
        !          1445:        }       
        !          1446: 
        !          1447: #ifdef BUILD_JSDOCS
        !          1448:        js_DescribeSyncObject(cx,obj,"Controls the user's Telnet/RLogin terminal",310);
        !          1449:        js_CreateArrayOfStrings(cx, obj, "_property_desc_list", con_prop_desc, JSPROP_READONLY);
        !          1450: #endif
        !          1451: 
        !          1452:        return(obj);
        !          1453: }
        !          1454: 
        !          1455: #endif /* JAVSCRIPT */

unix.superglobalmegacorp.com

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