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

unix.superglobalmegacorp.com

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