|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.