|
|
1.1 ! root 1: /* js_global.c */ ! 2: ! 3: /* Synchronet JavaScript "global" object properties/methods for all servers */ ! 4: ! 5: /* $Id: js_global.c,v 1.210 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: #define JS_THREADSAFE /* needed for JS_SetContextThread */ ! 39: ! 40: #include "sbbs.h" ! 41: #include "md5.h" ! 42: #include "base64.h" ! 43: #include "htmlansi.h" ! 44: #include "ini_file.h" ! 45: ! 46: /* SpiderMonkey: */ ! 47: #include <jsfun.h> ! 48: ! 49: #define MAX_ANSI_SEQ 16 ! 50: #define MAX_ANSI_PARAMS 8 ! 51: ! 52: #ifdef JAVASCRIPT ! 53: ! 54: /* Global Object Properites */ ! 55: enum { ! 56: GLOB_PROP_ERRNO ! 57: ,GLOB_PROP_ERRNO_STR ! 58: ,GLOB_PROP_SOCKET_ERRNO ! 59: }; ! 60: ! 61: static JSBool js_system_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) ! 62: { ! 63: jsint tiny; ! 64: JSString* js_str; ! 65: ! 66: tiny = JSVAL_TO_INT(id); ! 67: ! 68: switch(tiny) { ! 69: case GLOB_PROP_SOCKET_ERRNO: ! 70: JS_NewNumberValue(cx,ERROR_VALUE,vp); ! 71: break; ! 72: case GLOB_PROP_ERRNO: ! 73: JS_NewNumberValue(cx,errno,vp); ! 74: break; ! 75: case GLOB_PROP_ERRNO_STR: ! 76: if((js_str=JS_NewStringCopyZ(cx, strerror(errno)))==NULL) ! 77: return(JS_FALSE); ! 78: *vp = STRING_TO_JSVAL(js_str); ! 79: break; ! 80: } ! 81: return(JS_TRUE); ! 82: } ! 83: ! 84: #define GLOBOBJ_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED ! 85: ! 86: static struct JSPropertySpec js_global_properties[] = { ! 87: /* name, tinyid, flags */ ! 88: ! 89: { "errno" ,GLOB_PROP_ERRNO ,GLOBOBJ_FLAGS }, ! 90: { "errno_str" ,GLOB_PROP_ERRNO_STR ,GLOBOBJ_FLAGS }, ! 91: { "socket_errno" ,GLOB_PROP_SOCKET_ERRNO ,GLOBOBJ_FLAGS }, ! 92: {0} ! 93: }; ! 94: ! 95: typedef struct { ! 96: JSRuntime* runtime; ! 97: JSContext* cx; ! 98: JSContext* parent_cx; ! 99: JSObject* obj; ! 100: JSScript* script; ! 101: msg_queue_t* msg_queue; ! 102: js_branch_t branch; ! 103: JSErrorReporter error_reporter; ! 104: JSNative log; ! 105: } background_data_t; ! 106: ! 107: static void background_thread(void* arg) ! 108: { ! 109: background_data_t* bg = (background_data_t*)arg; ! 110: jsval result=JSVAL_VOID; ! 111: jsval exit_code; ! 112: ! 113: msgQueueAttach(bg->msg_queue); ! 114: JS_SetContextThread(bg->cx); ! 115: if(!JS_ExecuteScript(bg->cx, bg->obj, bg->script, &result) ! 116: && JS_GetProperty(bg->cx, bg->obj, "exit_code", &exit_code)) ! 117: result=exit_code; ! 118: js_EvalOnExit(bg->cx, bg->obj, &bg->branch); ! 119: js_enqueue_value(bg->cx, bg->msg_queue, result, NULL); ! 120: JS_DestroyScript(bg->cx, bg->script); ! 121: JS_DestroyContext(bg->cx); ! 122: JS_DestroyRuntime(bg->runtime); ! 123: free(bg); ! 124: } ! 125: ! 126: static void ! 127: js_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) ! 128: { ! 129: background_data_t* bg; ! 130: ! 131: if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL) ! 132: return; ! 133: ! 134: /* Use parent's context private data */ ! 135: JS_SetContextPrivate(cx, JS_GetContextPrivate(bg->parent_cx)); ! 136: ! 137: /* Call parent's error reporter */ ! 138: bg->error_reporter(cx, message, report); ! 139: ! 140: /* Restore our context private data */ ! 141: JS_SetContextPrivate(cx, bg); ! 142: } ! 143: ! 144: static JSBool js_BranchCallback(JSContext *cx, JSScript* script) ! 145: { ! 146: background_data_t* bg; ! 147: ! 148: if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL) ! 149: return(JS_FALSE); ! 150: ! 151: if(bg->parent_cx!=NULL && !JS_IsRunning(bg->parent_cx)) /* die when parent dies */ ! 152: return(JS_FALSE); ! 153: ! 154: return js_CommonBranchCallback(cx,&bg->branch); ! 155: } ! 156: ! 157: static JSBool ! 158: js_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 159: { ! 160: JSBool retval; ! 161: background_data_t* bg; ! 162: ! 163: if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL) ! 164: return JS_FALSE; ! 165: ! 166: /* Use parent's context private data */ ! 167: JS_SetContextPrivate(cx, JS_GetContextPrivate(bg->parent_cx)); ! 168: ! 169: /* Call parent's log() function */ ! 170: retval = bg->log(cx, obj, argc, argv, rval); ! 171: ! 172: /* Restore our context private data */ ! 173: JS_SetContextPrivate(cx, bg); ! 174: ! 175: return retval; ! 176: } ! 177: ! 178: /* Create a new value in the new context with a value from the original context */ ! 179: /* Note: objects (including arrays) not currently supported */ ! 180: static jsval* js_CopyValue(JSContext* cx, jsval val, JSContext* new_cx, jsval* rval) ! 181: { ! 182: *rval = JSVAL_VOID; ! 183: ! 184: if(cx==new_cx ! 185: || JSVAL_IS_BOOLEAN(val) ! 186: || JSVAL_IS_NULL(val) ! 187: || JSVAL_IS_VOID(val) ! 188: || JSVAL_IS_INT(val)) ! 189: *rval = val; ! 190: else if(JSVAL_IS_NUMBER(val)) { ! 191: jsdouble d; ! 192: if(JS_ValueToNumber(cx,val,&d)) ! 193: JS_NewNumberValue(new_cx,d,rval); ! 194: } ! 195: else { ! 196: JSString* str; ! 197: size_t len; ! 198: char* p; ! 199: ! 200: if((p=js_ValueToStringBytes(cx,val,&len)) != NULL ! 201: && (str=JS_NewStringCopyN(new_cx,p,len)) != NULL) ! 202: *rval=STRING_TO_JSVAL(str); ! 203: } ! 204: ! 205: return rval; ! 206: } ! 207: ! 208: static JSBool ! 209: js_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 210: { ! 211: char path[MAX_PATH+1]; ! 212: uintN i; ! 213: uintN argn=0; ! 214: const char* filename; ! 215: JSScript* script; ! 216: scfg_t* cfg; ! 217: jsval val; ! 218: JSObject* js_argv; ! 219: JSObject* exec_obj; ! 220: JSContext* exec_cx=cx; ! 221: JSBool success; ! 222: JSBool background=JS_FALSE; ! 223: background_data_t* bg; ! 224: ! 225: *rval=JSVAL_VOID; ! 226: ! 227: if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) ! 228: return(JS_FALSE); ! 229: ! 230: exec_obj=JS_GetScopeChain(cx); ! 231: ! 232: if(JSVAL_IS_BOOLEAN(argv[argn])) ! 233: background=JSVAL_TO_BOOLEAN(argv[argn++]); ! 234: ! 235: if(background) { ! 236: ! 237: if((bg=(background_data_t*)malloc(sizeof(background_data_t)))==NULL) ! 238: return(JS_FALSE); ! 239: memset(bg,0,sizeof(background_data_t)); ! 240: ! 241: bg->parent_cx = cx; ! 242: ! 243: /* Setup default values for branch settings */ ! 244: bg->branch.limit=JAVASCRIPT_BRANCH_LIMIT; ! 245: bg->branch.gc_interval=JAVASCRIPT_GC_INTERVAL; ! 246: bg->branch.yield_interval=JAVASCRIPT_YIELD_INTERVAL; ! 247: if(JS_GetProperty(cx, obj,"js",&val)) /* copy branch settings from parent */ ! 248: memcpy(&bg->branch,JS_GetPrivate(cx,JSVAL_TO_OBJECT(val)),sizeof(bg->branch)); ! 249: bg->branch.terminated=NULL; /* could be bad pointer at any time */ ! 250: bg->branch.counter=0; ! 251: bg->branch.gc_attempts=0; ! 252: ! 253: if((bg->runtime = JS_NewRuntime(JAVASCRIPT_MAX_BYTES))==NULL) ! 254: return(JS_FALSE); ! 255: ! 256: if((bg->cx = JS_NewContext(bg->runtime, JAVASCRIPT_CONTEXT_STACK))==NULL) ! 257: return(JS_FALSE); ! 258: ! 259: if((bg->obj=js_CreateCommonObjects(bg->cx ! 260: ,cfg /* common config */ ! 261: ,NULL /* node-specific config */ ! 262: ,NULL /* additional global methods */ ! 263: ,0 /* uptime */ ! 264: ,"" /* hostname */ ! 265: ,"" /* socklib_desc */ ! 266: ,&bg->branch /* js */ ! 267: ,NULL /* client */ ! 268: ,INVALID_SOCKET /* client_socket */ ! 269: ,NULL /* server props */ ! 270: ))==NULL) ! 271: return(JS_FALSE); ! 272: ! 273: bg->msg_queue = msgQueueInit(NULL,MSG_QUEUE_BIDIR); ! 274: ! 275: js_CreateQueueObject(bg->cx, bg->obj, "parent_queue", bg->msg_queue); ! 276: ! 277: /* Save parent's error reporter (for later use by our error reporter) */ ! 278: bg->error_reporter=JS_SetErrorReporter(cx,NULL); ! 279: JS_SetErrorReporter(cx,bg->error_reporter); ! 280: JS_SetErrorReporter(bg->cx,js_ErrorReporter); ! 281: ! 282: /* Set our branch callback (which calls the generic branch callback) */ ! 283: JS_SetContextPrivate(bg->cx, bg); ! 284: JS_SetBranchCallback(bg->cx, js_BranchCallback); ! 285: ! 286: /* Save parent's 'log' function (for later use by our log function) */ ! 287: if(JS_GetProperty(cx, obj, "log", &val)) { ! 288: JSFunction* func; ! 289: if((func=JS_ValueToFunction(cx, val))!=NULL && !func->interpreted) { ! 290: bg->log=func->u.native; ! 291: JS_DefineFunction(bg->cx, bg->obj ! 292: ,"log", js_log, func->nargs, func->flags); ! 293: } ! 294: } ! 295: ! 296: exec_cx = bg->cx; ! 297: exec_obj = bg->obj; ! 298: ! 299: } else if(JSVAL_IS_OBJECT(argv[argn])) { ! 300: JSObject* tmp_obj=JSVAL_TO_OBJECT(argv[argn++]); ! 301: if(!JS_ObjectIsFunction(cx,tmp_obj)) /* Scope specified */ ! 302: exec_obj=tmp_obj; ! 303: } ! 304: ! 305: if(argn==argc) { ! 306: JS_ReportError(cx,"no filename specified"); ! 307: return(JS_FALSE); ! 308: } ! 309: if((filename=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL) ! 310: return(JS_FALSE); ! 311: ! 312: if(argc>argn || background) { ! 313: ! 314: if((js_argv=JS_NewArrayObject(exec_cx, 0, NULL)) == NULL) ! 315: return(JS_FALSE); ! 316: ! 317: JS_DefineProperty(exec_cx, exec_obj, "argv", OBJECT_TO_JSVAL(js_argv) ! 318: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY); ! 319: ! 320: for(i=argn; i<argc; i++) ! 321: JS_SetElement(exec_cx, js_argv, i-argn, js_CopyValue(cx,argv[i],exec_cx,&val)); ! 322: ! 323: JS_DefineProperty(exec_cx, exec_obj, "argc", INT_TO_JSVAL(argc-argn) ! 324: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY); ! 325: } ! 326: ! 327: errno = 0; ! 328: if(isfullpath(filename)) ! 329: strcpy(path,filename); ! 330: else { ! 331: sprintf(path,"%s%s",cfg->mods_dir,filename); ! 332: if(cfg->mods_dir[0]==0 || !fexistcase(path)) ! 333: sprintf(path,"%s%s",cfg->exec_dir,filename); ! 334: } ! 335: ! 336: JS_ClearPendingException(exec_cx); ! 337: ! 338: if((script=JS_CompileFile(exec_cx, exec_obj, path))==NULL) ! 339: return(JS_FALSE); ! 340: ! 341: if(background) { ! 342: ! 343: bg->script = script; ! 344: *rval = OBJECT_TO_JSVAL(js_CreateQueueObject(cx, obj, NULL, bg->msg_queue)); ! 345: success = _beginthread(background_thread,0,bg)!=-1; ! 346: ! 347: } else { ! 348: ! 349: success = JS_ExecuteScript(exec_cx, exec_obj, script, rval); ! 350: JS_DestroyScript(exec_cx, script); ! 351: } ! 352: ! 353: return(success); ! 354: } ! 355: ! 356: static JSBool ! 357: js_format(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 358: { ! 359: char* p; ! 360: JSString* str; ! 361: ! 362: if((p=js_sprintf(cx, 0, argc, argv))==NULL) { ! 363: JS_ReportError(cx,"js_sprintf failed"); ! 364: return(JS_FALSE); ! 365: } ! 366: ! 367: str = JS_NewStringCopyZ(cx, p); ! 368: js_sprintf_free(p); ! 369: ! 370: if(str==NULL) ! 371: return(JS_FALSE); ! 372: ! 373: *rval = STRING_TO_JSVAL(str); ! 374: return(JS_TRUE); ! 375: } ! 376: ! 377: static JSBool ! 378: js_yield(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 379: { ! 380: BOOL forced=TRUE; ! 381: ! 382: if(argc) ! 383: JS_ValueToBoolean(cx, argv[0], &forced); ! 384: if(forced) { ! 385: YIELD(); ! 386: } else { ! 387: MAYBE_YIELD(); ! 388: } ! 389: ! 390: return(JS_TRUE); ! 391: } ! 392: ! 393: static JSBool ! 394: js_mswait(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 395: { ! 396: int32 val=1; ! 397: clock_t start=msclock(); ! 398: ! 399: if(argc) ! 400: JS_ValueToInt32(cx,argv[0],&val); ! 401: mswait(val); ! 402: ! 403: JS_NewNumberValue(cx,msclock()-start,rval); ! 404: ! 405: return(JS_TRUE); ! 406: } ! 407: ! 408: static JSBool ! 409: js_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 410: { ! 411: int32 val=100; ! 412: ! 413: if(argc) ! 414: JS_ValueToInt32(cx,argv[0],&val); ! 415: ! 416: JS_NewNumberValue(cx,sbbs_random(val),rval); ! 417: return(JS_TRUE); ! 418: } ! 419: ! 420: static JSBool ! 421: js_time(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 422: { ! 423: JS_NewNumberValue(cx,time(NULL),rval); ! 424: return(JS_TRUE); ! 425: } ! 426: ! 427: ! 428: static JSBool ! 429: js_beep(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 430: { ! 431: int32 freq=500; ! 432: int32 dur=500; ! 433: ! 434: if(argc) ! 435: JS_ValueToInt32(cx,argv[0],&freq); ! 436: if(argc>1) ! 437: JS_ValueToInt32(cx,argv[1],&dur); ! 438: ! 439: sbbs_beep(freq,dur); ! 440: return(JS_TRUE); ! 441: } ! 442: ! 443: static JSBool ! 444: js_exit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 445: { ! 446: if(argc) ! 447: JS_DefineProperty(cx, obj, "exit_code", argv[0] ! 448: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY); ! 449: ! 450: return(JS_FALSE); ! 451: } ! 452: ! 453: static JSBool ! 454: js_crc16(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 455: { ! 456: char* p; ! 457: size_t len; ! 458: ! 459: if(JSVAL_IS_VOID(argv[0])) ! 460: return(JS_TRUE); ! 461: ! 462: if((p=js_ValueToStringBytes(cx, argv[0], &len))==NULL) ! 463: return(JS_FALSE); ! 464: ! 465: *rval = INT_TO_JSVAL(crc16(p,len)); ! 466: return(JS_TRUE); ! 467: } ! 468: ! 469: static JSBool ! 470: js_crc32(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 471: { ! 472: char* p; ! 473: size_t len; ! 474: ! 475: if(JSVAL_IS_VOID(argv[0])) ! 476: return(JS_TRUE); ! 477: ! 478: if((p=js_ValueToStringBytes(cx, argv[0], &len))==NULL) ! 479: return(JS_FALSE); ! 480: ! 481: JS_NewNumberValue(cx,crc32(p,len),rval); ! 482: return(JS_TRUE); ! 483: } ! 484: ! 485: static JSBool ! 486: js_chksum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 487: { ! 488: ulong sum=0; ! 489: char* p; ! 490: size_t len; ! 491: ! 492: if(JSVAL_IS_VOID(argv[0])) ! 493: return(JS_TRUE); ! 494: ! 495: if((p=js_ValueToStringBytes(cx, argv[0], &len))==NULL) ! 496: return(JS_FALSE); ! 497: ! 498: while(len--) sum+=*(p++); ! 499: ! 500: JS_NewNumberValue(cx,sum,rval); ! 501: return(JS_TRUE); ! 502: } ! 503: ! 504: static JSBool ! 505: js_ascii(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 506: { ! 507: char* p; ! 508: char str[2]; ! 509: int32 i=0; ! 510: JSString* js_str; ! 511: ! 512: if(JSVAL_IS_VOID(argv[0])) ! 513: return(JS_TRUE); ! 514: ! 515: if(JSVAL_IS_STRING(argv[0])) { /* string to ascii-int */ ! 516: ! 517: if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL) ! 518: return(JS_FALSE); ! 519: ! 520: *rval=INT_TO_JSVAL(*p); ! 521: return(JS_TRUE); ! 522: } ! 523: ! 524: /* ascii-int to str */ ! 525: JS_ValueToInt32(cx,argv[0],&i); ! 526: str[0]=(uchar)i; ! 527: str[1]=0; ! 528: ! 529: if((js_str = JS_NewStringCopyZ(cx, str))==NULL) ! 530: return(JS_FALSE); ! 531: ! 532: *rval = STRING_TO_JSVAL(js_str); ! 533: return(JS_TRUE); ! 534: } ! 535: ! 536: static JSBool ! 537: js_ctrl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 538: { ! 539: char ch; ! 540: char* p; ! 541: char str[2]; ! 542: int32 i=0; ! 543: JSString* js_str; ! 544: ! 545: if(JSVAL_IS_VOID(argv[0])) ! 546: return(JS_TRUE); ! 547: ! 548: if(JSVAL_IS_STRING(argv[0])) { ! 549: ! 550: if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL) ! 551: return(JS_FALSE); ! 552: ch=*p; ! 553: } else { ! 554: JS_ValueToInt32(cx,argv[0],&i); ! 555: ch=(char)i; ! 556: } ! 557: ! 558: str[0]=toupper(ch)&~0x40; ! 559: str[1]=0; ! 560: ! 561: if((js_str = JS_NewStringCopyZ(cx, str))==NULL) ! 562: return(JS_FALSE); ! 563: ! 564: *rval = STRING_TO_JSVAL(js_str); ! 565: return(JS_TRUE); ! 566: } ! 567: ! 568: static JSBool ! 569: js_ascii_str(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 570: { ! 571: char* p; ! 572: char* buf; ! 573: JSString* str; ! 574: ! 575: if(JSVAL_IS_VOID(argv[0])) ! 576: return(JS_TRUE); ! 577: ! 578: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 579: return(JS_FALSE); ! 580: ! 581: if((buf=strdup(p))==NULL) ! 582: return(JS_FALSE); ! 583: ! 584: ascii_str(buf); ! 585: ! 586: str = JS_NewStringCopyZ(cx, buf); ! 587: free(buf); ! 588: if(str==NULL) ! 589: return(JS_FALSE); ! 590: ! 591: *rval = STRING_TO_JSVAL(str); ! 592: return(JS_TRUE); ! 593: } ! 594: ! 595: ! 596: static JSBool ! 597: js_strip_ctrl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 598: { ! 599: char* p; ! 600: char* buf; ! 601: JSString* js_str; ! 602: ! 603: if(JSVAL_IS_VOID(argv[0])) ! 604: return(JS_TRUE); ! 605: ! 606: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 607: return(JS_FALSE); ! 608: ! 609: if((buf=strdup(p))==NULL) ! 610: return(JS_FALSE); ! 611: ! 612: strip_ctrl(buf); ! 613: ! 614: js_str = JS_NewStringCopyZ(cx, buf); ! 615: free(buf); ! 616: if(js_str==NULL) ! 617: return(JS_FALSE); ! 618: ! 619: *rval = STRING_TO_JSVAL(js_str); ! 620: return(JS_TRUE); ! 621: } ! 622: ! 623: static JSBool ! 624: js_strip_exascii(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 625: { ! 626: char* p; ! 627: char* buf; ! 628: JSString* js_str; ! 629: ! 630: if(JSVAL_IS_VOID(argv[0])) ! 631: return(JS_TRUE); ! 632: ! 633: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 634: return(JS_FALSE); ! 635: ! 636: if((buf=strdup(p))==NULL) ! 637: return(JS_FALSE); ! 638: ! 639: strip_exascii(buf); ! 640: ! 641: js_str = JS_NewStringCopyZ(cx, buf); ! 642: free(buf); ! 643: if(js_str==NULL) ! 644: return(JS_FALSE); ! 645: ! 646: *rval = STRING_TO_JSVAL(js_str); ! 647: return(JS_TRUE); ! 648: } ! 649: ! 650: static JSBool ! 651: js_lfexpand(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 652: { ! 653: ulong i,j; ! 654: char* inbuf; ! 655: char* outbuf; ! 656: JSString* str; ! 657: ! 658: if(JSVAL_IS_VOID(argv[0])) ! 659: return(JS_TRUE); ! 660: ! 661: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 662: return(JS_FALSE); ! 663: ! 664: if((outbuf=(char*)malloc((strlen(inbuf)*2)+1))==NULL) ! 665: return(JS_FALSE); ! 666: ! 667: for(i=j=0;inbuf[i];i++) { ! 668: if(inbuf[i]=='\n' && (!i || inbuf[i-1]!='\r')) ! 669: outbuf[j++]='\r'; ! 670: outbuf[j++]=inbuf[i]; ! 671: } ! 672: outbuf[j]=0; ! 673: ! 674: str = JS_NewStringCopyZ(cx, outbuf); ! 675: free(outbuf); ! 676: if(str==NULL) ! 677: return(JS_FALSE); ! 678: ! 679: *rval = STRING_TO_JSVAL(str); ! 680: return(JS_TRUE); ! 681: } ! 682: ! 683: static int get_prefix(char *text, int *bytes, int *len, int maxlen) ! 684: { ! 685: int tmp_prefix_bytes,tmp_prefix_len; ! 686: int expect; ! 687: int depth; ! 688: ! 689: *bytes=0; ! 690: *len=0; ! 691: tmp_prefix_bytes=0; ! 692: tmp_prefix_len=0; ! 693: depth=0; ! 694: expect=1; ! 695: if(text[0]!=' ') ! 696: expect=2; ! 697: while(expect) { ! 698: tmp_prefix_bytes++; ! 699: /* Skip CTRL-A codes */ ! 700: while(text[tmp_prefix_bytes-1]=='\x01') { ! 701: tmp_prefix_bytes++; ! 702: if(text[tmp_prefix_bytes-1]=='\x01') ! 703: break; ! 704: tmp_prefix_bytes++; ! 705: } ! 706: tmp_prefix_len++; ! 707: if(text[tmp_prefix_bytes-1]==0 || text[tmp_prefix_bytes-1]=='\n' || text[tmp_prefix_bytes-1]=='\r') ! 708: break; ! 709: switch(expect) { ! 710: case 1: /* At start of possible quote (Next char should be space) */ ! 711: if(text[tmp_prefix_bytes-1]!=' ') ! 712: expect=0; ! 713: else ! 714: expect++; ! 715: break; ! 716: case 2: /* At start of nick (next char should be alphanum or '>') */ ! 717: case 3: /* At second nick initial (next char should be alphanum or '>') */ ! 718: case 4: /* At third nick initial (next char should be alphanum or '>') */ ! 719: if(text[tmp_prefix_bytes-1]==' ' || text[tmp_prefix_bytes-1]==0) ! 720: expect=0; ! 721: else ! 722: if(text[tmp_prefix_bytes-1]=='>') ! 723: expect=6; ! 724: else ! 725: expect++; ! 726: break; ! 727: case 5: /* After three regular chars, next HAS to be a '>') */ ! 728: if(text[tmp_prefix_bytes-1]!='>') ! 729: expect=0; ! 730: else ! 731: expect++; ! 732: break; ! 733: case 6: /* At '>' next char must be a space */ ! 734: if(text[tmp_prefix_bytes-1]!=' ') ! 735: expect=0; ! 736: else { ! 737: expect=1; ! 738: *len=tmp_prefix_len; ! 739: *bytes=tmp_prefix_bytes; ! 740: depth++; ! 741: /* Some editors don't put double spaces in between */ ! 742: if(text[tmp_prefix_bytes]!=' ') ! 743: expect++; ! 744: } ! 745: break; ! 746: default: ! 747: expect=0; ! 748: break; ! 749: } ! 750: } ! 751: if(*bytes >= maxlen) { ! 752: lprintf(LOG_CRIT, "Prefix bytes %u is larger than buffer (%u) here: %*.*s",*bytes,maxlen,maxlen,maxlen,text); ! 753: *bytes=maxlen-1; ! 754: } ! 755: return(depth); ! 756: } ! 757: ! 758: static void outbuf_append(char **outbuf, char **outp, char *append, int len, int *outlen) ! 759: { ! 760: char *p; ! 761: ! 762: /* Terminate outbuf */ ! 763: **outp=0; ! 764: /* Check if there's room */ ! 765: if(*outp - *outbuf + len < *outlen) { ! 766: memcpy(*outp, append, len); ! 767: *outp+=len; ! 768: return; ! 769: } ! 770: /* Not enough room, double the size. */ ! 771: *outlen *= 2; ! 772: p=realloc(*outbuf, *outlen); ! 773: if(p==NULL) { ! 774: /* Can't do it. */ ! 775: *outlen/=2; ! 776: return; ! 777: } ! 778: /* Set outp for new buffer */ ! 779: *outp=p+(*outp - *outbuf); ! 780: *outbuf=p; ! 781: memcpy(*outp, append, len); ! 782: *outp+=len; ! 783: return; ! 784: } ! 785: ! 786: static JSBool ! 787: js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 788: { ! 789: int32 l,len=79; ! 790: int32 oldlen=79; ! 791: int32 crcount=0; ! 792: JSBool handle_quotes=JS_TRUE; ! 793: long i,k,t; ! 794: int ocol=1; ! 795: int icol=1; ! 796: uchar* inbuf; ! 797: char* outbuf; ! 798: char* outp; ! 799: char* linebuf; ! 800: char* prefix=NULL; ! 801: int prefix_len=0; ! 802: int prefix_bytes=0; ! 803: int quote_count=0; ! 804: int old_prefix_bytes=0; ! 805: int outbuf_size=0; ! 806: JSString* js_str; ! 807: ! 808: if(JSVAL_IS_VOID(argv[0])) ! 809: return(JS_TRUE); ! 810: ! 811: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 812: return(JS_FALSE); ! 813: ! 814: outbuf_size=strlen(inbuf)*3+1; ! 815: if((outbuf=(char*)malloc(outbuf_size))==NULL) ! 816: return(JS_FALSE); ! 817: outp=outbuf; ! 818: ! 819: if(argc>1) ! 820: JS_ValueToInt32(cx,argv[1],&len); ! 821: ! 822: if(argc>2) ! 823: JS_ValueToInt32(cx,argv[2],&oldlen); ! 824: ! 825: if(argc>3 && JSVAL_IS_BOOLEAN(argv[3])) ! 826: handle_quotes=JSVAL_TO_BOOLEAN(argv[3]); ! 827: ! 828: if((linebuf=(char*)alloca((len*2)+2))==NULL) /* room for ^A codes ToDo: This isn't actually "enough" room */ ! 829: return(JS_FALSE); ! 830: ! 831: if(handle_quotes) { ! 832: if((prefix=(char *)alloca((len*2)+2))==NULL) /* room for ^A codes ToDo: This isn't actually "enough" room */ ! 833: return(JS_FALSE); ! 834: prefix[0]=0; ! 835: } ! 836: ! 837: outbuf[0]=0; ! 838: /* Get prefix from the first line (ouch) */ ! 839: l=0; ! 840: i=0; ! 841: if(handle_quotes && (quote_count=get_prefix(inbuf, &prefix_bytes, &prefix_len, len*2+2))!=0) { ! 842: i+=prefix_bytes; ! 843: if(prefix_len>len/3*2) { ! 844: /* This prefix is insane (more than 2/3rds of the new width) hack it down to size */ ! 845: /* Since we're hacking it, we will always end up with a hardcr on this line. */ ! 846: /* ToDo: Something prettier would be nice. */ ! 847: sprintf(prefix," %d> ",quote_count); ! 848: prefix_len=strlen(prefix); ! 849: prefix_bytes=strlen(prefix); ! 850: } ! 851: else { ! 852: memcpy(prefix,inbuf,prefix_bytes); ! 853: /* Terminate prefix */ ! 854: prefix[prefix_bytes]=0; ! 855: } ! 856: memcpy(linebuf,prefix,prefix_bytes); ! 857: l=prefix_bytes; ! 858: ocol=prefix_len+1; ! 859: icol=prefix_len+1; ! 860: old_prefix_bytes=prefix_bytes; ! 861: } ! 862: for(; inbuf[i]; i++) { ! 863: if(l>=len*2+2) { ! 864: l-=4; ! 865: linebuf[l]=0; ! 866: lprintf(LOG_CRIT, "Word wrap line buffer exceeded... munging line %s",linebuf); ! 867: } ! 868: switch(inbuf[i]) { ! 869: case '\r': ! 870: crcount++; ! 871: break; ! 872: case '\n': ! 873: if(handle_quotes && (quote_count=get_prefix(inbuf+i+1, &prefix_bytes, &prefix_len, len*2+2))!=0) { ! 874: /* Move the input pointer offset to the last char of the prefix */ ! 875: i+=prefix_bytes; ! 876: } ! 877: if(!inbuf[i+1]) { /* EOF */ ! 878: linebuf[l++]='\r'; ! 879: linebuf[l++]='\n'; ! 880: outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size); ! 881: l=0; ! 882: ocol=1; ! 883: } ! 884: /* If there's a new prefix, it is a hardcr */ ! 885: else if(prefix_bytes != old_prefix_bytes || (memcmp(prefix,inbuf+i+1-prefix_bytes,prefix_bytes))) { ! 886: if(prefix_len>len/3*2) { ! 887: /* This prefix is insane (more than 2/3rds of the new width) hack it down to size */ ! 888: /* Since we're hacking it, we will always end up with a hardcr on this line. */ ! 889: /* ToDo: Something prettier would be nice. */ ! 890: sprintf(prefix," %d> ",quote_count); ! 891: prefix_len=strlen(prefix); ! 892: prefix_bytes=strlen(prefix); ! 893: } ! 894: else { ! 895: memcpy(prefix,inbuf+i+1-prefix_bytes,prefix_bytes); ! 896: /* Terminate prefix */ ! 897: prefix[prefix_bytes]=0; ! 898: } ! 899: linebuf[l++]='\r'; ! 900: linebuf[l++]='\n'; ! 901: outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size); ! 902: memcpy(linebuf,prefix,prefix_bytes); ! 903: l=prefix_bytes; ! 904: ocol=prefix_len+1; ! 905: old_prefix_bytes=prefix_bytes; ! 906: } ! 907: else if(isspace(inbuf[i+1])) { /* Next line starts with whitespace. This is a "hard" CR. */ ! 908: linebuf[l++]='\r'; ! 909: linebuf[l++]='\n'; ! 910: outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size); ! 911: l=0; ! 912: ocol=1; ! 913: } ! 914: else { ! 915: if(icol < oldlen) { /* If this line is overly long, It's impossible for the next word to fit */ ! 916: /* k will equal the length of the first word on the next line */ ! 917: for(k=0; inbuf[i+1+k] && (!isspace(inbuf[i+1+k])); k++); ! 918: if(icol+k+1 < oldlen) { /* The next word would have fit but isn't here. Must be a hard CR */ ! 919: linebuf[l++]='\r'; ! 920: linebuf[l++]='\n'; ! 921: outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size); ! 922: if(prefix) ! 923: memcpy(linebuf,prefix,prefix_bytes); ! 924: l=prefix_bytes; ! 925: ocol=prefix_len+1; ! 926: } ! 927: else { /* Not a hard CR... add space if needed */ ! 928: if(l<1 || !isspace(linebuf[l-1])) { ! 929: linebuf[l++]=' '; ! 930: ocol++; ! 931: } ! 932: } ! 933: } ! 934: else { /* Not a hard CR... add space if needed */ ! 935: if(l<1 || !isspace(linebuf[l-1])) { ! 936: linebuf[l++]=' '; ! 937: ocol++; ! 938: } ! 939: } ! 940: } ! 941: icol=prefix_len+1; ! 942: break; ! 943: case '\x1f': /* Delete... meaningless... strip. */ ! 944: break; ! 945: case '\b': /* Backspace... handle if possible, but don't go crazy. */ ! 946: if(l>0) { ! 947: if(l>1 && linebuf[l-2]=='\x01') { ! 948: if(linebuf[l-1]=='\x01') { ! 949: ocol--; ! 950: icol--; ! 951: } ! 952: l-=2; ! 953: } ! 954: else { ! 955: l--; ! 956: ocol--; ! 957: icol--; ! 958: } ! 959: } ! 960: break; ! 961: case '\t': /* TAB */ ! 962: linebuf[l++]=inbuf[i]; ! 963: /* Can't ever wrap on whitespace remember. */ ! 964: icol++; ! 965: ocol++; ! 966: while(ocol%8) ! 967: ocol++; ! 968: while(icol%8) ! 969: icol++; ! 970: break; ! 971: case '\x01': /* CTRL-A */ ! 972: linebuf[l++]=inbuf[i++]; ! 973: if(inbuf[i]!='\x01') { ! 974: linebuf[l++]=inbuf[i]; ! 975: break; ! 976: } ! 977: default: ! 978: linebuf[l++]=inbuf[i]; ! 979: ocol++; ! 980: icol++; ! 981: if(ocol>len && !isspace(inbuf[i])) { /* Need to wrap here */ ! 982: /* Find the start of the last word */ ! 983: k=l; /* Original next char */ ! 984: l--; /* Move back to the last char */ ! 985: while((!isspace(linebuf[l])) && l>0) /* Move back to the last non-space char */ ! 986: l--; ! 987: if(l==0) { /* Couldn't wrap... must chop. */ ! 988: l=k; ! 989: while(l>1 && linebuf[l-2]=='\x01' && linebuf[l-1]!='\x01') ! 990: l-=2; ! 991: if(l>0 && linebuf[l-1]=='\x01') ! 992: l--; ! 993: if(l>0) ! 994: l--; ! 995: } ! 996: t=l+1; /* Store start position of next line */ ! 997: /* Move to start of whitespace */ ! 998: while(l>0 && isspace(l)) ! 999: l--; ! 1000: outbuf_append(&outbuf, &outp, linebuf, l+1, &outbuf_size); ! 1001: outbuf_append(&outbuf, &outp, "\r\n", 2, &outbuf_size); ! 1002: /* Move trailing words to start of buffer. */ ! 1003: l=prefix_bytes; ! 1004: if(k-t>0) /* k-1 is the last char position. t is the start of the next line position */ ! 1005: memmove(linebuf+l, linebuf+t, k-t); ! 1006: l+=k-t; ! 1007: /* Find new ocol */ ! 1008: for(ocol=prefix_len+1,t=prefix_bytes; t<l; t++) { ! 1009: switch(linebuf[t]) { ! 1010: case '\x01': /* CTRL-A */ ! 1011: if(linebuf[t+1]!='\x01') ! 1012: break; ! 1013: t++; ! 1014: /* Fall-through */ ! 1015: default: ! 1016: ocol++; ! 1017: } ! 1018: } ! 1019: } ! 1020: } ! 1021: } ! 1022: /* Trailing bits. */ ! 1023: if(l) { ! 1024: linebuf[l++]='\r'; ! 1025: linebuf[l++]='\n'; ! 1026: outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size); ! 1027: } ! 1028: *outp=0; ! 1029: /* If there were no CRs in the input, strip all CRs */ ! 1030: if(!crcount) { ! 1031: for(inbuf=outbuf; *inbuf; inbuf++) { ! 1032: if(*inbuf=='\r') ! 1033: memmove(inbuf, inbuf+1, strlen(inbuf)); ! 1034: } ! 1035: } ! 1036: ! 1037: js_str = JS_NewStringCopyZ(cx, outbuf); ! 1038: free(outbuf); ! 1039: if(js_str==NULL) ! 1040: return(JS_FALSE); ! 1041: ! 1042: *rval = STRING_TO_JSVAL(js_str); ! 1043: return(JS_TRUE); ! 1044: } ! 1045: ! 1046: static JSBool ! 1047: js_quote_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1048: { ! 1049: int32 len=79; ! 1050: int i,l,clen; ! 1051: uchar* inbuf; ! 1052: char* outbuf; ! 1053: char* linebuf; ! 1054: char* prefix=" > "; ! 1055: JSString* js_str; ! 1056: ! 1057: if(JSVAL_IS_VOID(argv[0])) ! 1058: return(JS_TRUE); ! 1059: ! 1060: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 1061: return(JS_FALSE); ! 1062: ! 1063: if(argc>1) ! 1064: JS_ValueToInt32(cx,argv[1],&len); ! 1065: ! 1066: if(argc>2) ! 1067: prefix=js_ValueToStringBytes(cx, argv[2], NULL); ! 1068: ! 1069: if((outbuf=(char*)malloc((strlen(inbuf)*strlen(prefix))+1))==NULL) ! 1070: return(JS_FALSE); ! 1071: ! 1072: len-=strlen(prefix); ! 1073: if(len<=0) ! 1074: return(JS_FALSE); ! 1075: ! 1076: if((linebuf=(char*)alloca(len*2+2))==NULL) /* (Hopefully) Room for ^A codes. ToDo */ ! 1077: return(JS_FALSE); ! 1078: ! 1079: outbuf[0]=0; ! 1080: clen=0; ! 1081: for(i=l=0;inbuf[i];i++) { ! 1082: if(l==0) /* Do not use clen here since if the line starts with ^A, could stay at zero */ ! 1083: strcat(outbuf,prefix); ! 1084: if(clen<len || inbuf[i]=='\n' || inbuf[i]=='\r') ! 1085: linebuf[l++]=inbuf[i]; ! 1086: if(inbuf[i]=='\x01') { /* Handle CTRL-A */ ! 1087: linebuf[l++]=inbuf[++i]; ! 1088: if(inbuf[i]=='\x01') ! 1089: clen++; ! 1090: } ! 1091: else ! 1092: clen++; ! 1093: /* ToDo: Handle TABs etc. */ ! 1094: if(inbuf[i]=='\n') { ! 1095: strncat(outbuf,linebuf,l); ! 1096: l=0; ! 1097: clen=0; ! 1098: } ! 1099: } ! 1100: if(l) /* remainder */ ! 1101: strncat(outbuf,linebuf,l); ! 1102: ! 1103: js_str = JS_NewStringCopyZ(cx, outbuf); ! 1104: free(outbuf); ! 1105: if(js_str==NULL) ! 1106: return(JS_FALSE); ! 1107: ! 1108: *rval = STRING_TO_JSVAL(js_str); ! 1109: return(JS_TRUE); ! 1110: } ! 1111: ! 1112: static JSBool ! 1113: js_netaddr_type(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1114: { ! 1115: char* str; ! 1116: ! 1117: if(JSVAL_IS_VOID(argv[0])) ! 1118: return(JS_TRUE); ! 1119: ! 1120: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 1121: return(JS_FALSE); ! 1122: ! 1123: *rval = INT_TO_JSVAL(smb_netaddr_type(str)); ! 1124: ! 1125: return(JS_TRUE); ! 1126: } ! 1127: ! 1128: static JSBool ! 1129: js_rot13(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1130: { ! 1131: char* p; ! 1132: char* str; ! 1133: JSString* js_str; ! 1134: ! 1135: if(JSVAL_IS_VOID(argv[0])) ! 1136: return(JS_TRUE); ! 1137: ! 1138: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 1139: return(JS_FALSE); ! 1140: ! 1141: if((p=strdup(str))==NULL) ! 1142: return(JS_FALSE); ! 1143: ! 1144: js_str = JS_NewStringCopyZ(cx, rot13(p)); ! 1145: free(p); ! 1146: if(js_str==NULL) ! 1147: return(JS_FALSE); ! 1148: ! 1149: *rval = STRING_TO_JSVAL(js_str); ! 1150: return(JS_TRUE); ! 1151: } ! 1152: ! 1153: /* This table is used to convert between IBM ex-ASCII and HTML character entities */ ! 1154: /* Much of this table supplied by Deuce (thanks!) */ ! 1155: static struct { ! 1156: int value; ! 1157: char* name; ! 1158: } exasctbl[128] = { ! 1159: /* HTML val,name ASCII description */ ! 1160: { 199 ,"Ccedil" }, /* 128 C, cedilla */ ! 1161: { 252 ,"uuml" }, /* 129 u, umlaut */ ! 1162: { 233 ,"eacute" }, /* 130 e, acute accent */ ! 1163: { 226 ,"acirc" }, /* 131 a, circumflex accent */ ! 1164: { 228 ,"auml" }, /* 132 a, umlaut */ ! 1165: { 224 ,"agrave" }, /* 133 a, grave accent */ ! 1166: { 229 ,"aring" }, /* 134 a, ring */ ! 1167: { 231 ,"ccedil" }, /* 135 c, cedilla */ ! 1168: { 234 ,"ecirc" }, /* 136 e, circumflex accent */ ! 1169: { 235 ,"euml" }, /* 137 e, umlaut */ ! 1170: { 232 ,"egrave" }, /* 138 e, grave accent */ ! 1171: { 239 ,"iuml" }, /* 139 i, umlaut */ ! 1172: { 238 ,"icirc" }, /* 140 i, circumflex accent */ ! 1173: { 236 ,"igrave" }, /* 141 i, grave accent */ ! 1174: { 196 ,"Auml" }, /* 142 A, umlaut */ ! 1175: { 197 ,"Aring" }, /* 143 A, ring */ ! 1176: { 201 ,"Eacute" }, /* 144 E, acute accent */ ! 1177: { 230 ,"aelig" }, /* 145 ae ligature */ ! 1178: { 198 ,"AElig" }, /* 146 AE ligature */ ! 1179: { 244 ,"ocirc" }, /* 147 o, circumflex accent */ ! 1180: { 246 ,"ouml" }, /* 148 o, umlaut */ ! 1181: { 242 ,"ograve" }, /* 149 o, grave accent */ ! 1182: { 251 ,"ucirc" }, /* 150 u, circumflex accent */ ! 1183: { 249 ,"ugrave" }, /* 151 u, grave accent */ ! 1184: { 255 ,"yuml" }, /* 152 y, umlaut */ ! 1185: { 214 ,"Ouml" }, /* 153 O, umlaut */ ! 1186: { 220 ,"Uuml" }, /* 154 U, umlaut */ ! 1187: { 162 ,"cent" }, /* 155 Cent sign */ ! 1188: { 163 ,"pound" }, /* 156 Pound sign */ ! 1189: { 165 ,"yen" }, /* 157 Yen sign */ ! 1190: { 8359 ,NULL }, /* 158 Pt (unicode) */ ! 1191: { 402 ,NULL }, /* 402 Florin (non-standard alsi 159?) */ ! 1192: { 225 ,"aacute" }, /* 160 a, acute accent */ ! 1193: { 237 ,"iacute" }, /* 161 i, acute accent */ ! 1194: { 243 ,"oacute" }, /* 162 o, acute accent */ ! 1195: { 250 ,"uacute" }, /* 163 u, acute accent */ ! 1196: { 241 ,"ntilde" }, /* 164 n, tilde */ ! 1197: { 209 ,"Ntilde" }, /* 165 N, tilde */ ! 1198: { 170 ,"ordf" }, /* 166 Feminine ordinal */ ! 1199: { 186 ,"ordm" }, /* 167 Masculine ordinal */ ! 1200: { 191 ,"iquest" }, /* 168 Inverted question mark */ ! 1201: { 8976 ,NULL }, /* 169 Inverse "Not sign" (unicode) */ ! 1202: { 172 ,"not" }, /* 170 Not sign */ ! 1203: { 189 ,"frac12" }, /* 171 Fraction one-half */ ! 1204: { 188 ,"frac14" }, /* 172 Fraction one-fourth */ ! 1205: { 161 ,"iexcl" }, /* 173 Inverted exclamation point */ ! 1206: { 171 ,"laquo" }, /* 174 Left angle quote */ ! 1207: { 187 ,"raquo" }, /* 175 Right angle quote */ ! 1208: { 9617 ,NULL }, /* 176 drawing symbol (unicode) */ ! 1209: { 9618 ,NULL }, /* 177 drawing symbol (unicode) */ ! 1210: { 9619 ,NULL }, /* 178 drawing symbol (unicode) */ ! 1211: { 9474 ,NULL }, /* 179 drawing symbol (unicode) */ ! 1212: { 9508 ,NULL }, /* 180 drawing symbol (unicode) */ ! 1213: { 9569 ,NULL }, /* 181 drawing symbol (unicode) */ ! 1214: { 9570 ,NULL }, /* 182 drawing symbol (unicode) */ ! 1215: { 9558 ,NULL }, /* 183 drawing symbol (unicode) */ ! 1216: { 9557 ,NULL }, /* 184 drawing symbol (unicode) */ ! 1217: { 9571 ,NULL }, /* 185 drawing symbol (unicode) */ ! 1218: { 9553 ,NULL }, /* 186 drawing symbol (unicode) */ ! 1219: { 9559 ,NULL }, /* 187 drawing symbol (unicode) */ ! 1220: { 9565 ,NULL }, /* 188 drawing symbol (unicode) */ ! 1221: { 9564 ,NULL }, /* 189 drawing symbol (unicode) */ ! 1222: { 9563 ,NULL }, /* 190 drawing symbol (unicode) */ ! 1223: { 9488 ,NULL }, /* 191 drawing symbol (unicode) */ ! 1224: { 9492 ,NULL }, /* 192 drawing symbol (unicode) */ ! 1225: { 9524 ,NULL }, /* 193 drawing symbol (unicode) */ ! 1226: { 9516 ,NULL }, /* 194 drawing symbol (unicode) */ ! 1227: { 9500 ,NULL }, /* 195 drawing symbol (unicode) */ ! 1228: { 9472 ,NULL }, /* 196 drawing symbol (unicode) */ ! 1229: { 9532 ,NULL }, /* 197 drawing symbol (unicode) */ ! 1230: { 9566 ,NULL }, /* 198 drawing symbol (unicode) */ ! 1231: { 9567 ,NULL }, /* 199 drawing symbol (unicode) */ ! 1232: { 9562 ,NULL }, /* 200 drawing symbol (unicode) */ ! 1233: { 9556 ,NULL }, /* 201 drawing symbol (unicode) */ ! 1234: { 9577 ,NULL }, /* 202 drawing symbol (unicode) */ ! 1235: { 9574 ,NULL }, /* 203 drawing symbol (unicode) */ ! 1236: { 9568 ,NULL }, /* 204 drawing symbol (unicode) */ ! 1237: { 9552 ,NULL }, /* 205 drawing symbol (unicode) */ ! 1238: { 9580 ,NULL }, /* 206 drawing symbol (unicode) */ ! 1239: { 9575 ,NULL }, /* 207 drawing symbol (unicode) */ ! 1240: { 9576 ,NULL }, /* 208 drawing symbol (unicode) */ ! 1241: { 9572 ,NULL }, /* 209 drawing symbol (unicode) */ ! 1242: { 9573 ,NULL }, /* 210 drawing symbol (unicode) */ ! 1243: { 9561 ,NULL }, /* 211 drawing symbol (unicode) */ ! 1244: { 9560 ,NULL }, /* 212 drawing symbol (unicode) */ ! 1245: { 9554 ,NULL }, /* 213 drawing symbol (unicode) */ ! 1246: { 9555 ,NULL }, /* 214 drawing symbol (unicode) */ ! 1247: { 9579 ,NULL }, /* 215 drawing symbol (unicode) */ ! 1248: { 9578 ,NULL }, /* 216 drawing symbol (unicode) */ ! 1249: { 9496 ,NULL }, /* 217 drawing symbol (unicode) */ ! 1250: { 9484 ,NULL }, /* 218 drawing symbol (unicode) */ ! 1251: { 9608 ,NULL }, /* 219 drawing symbol (unicode) */ ! 1252: { 9604 ,NULL }, /* 220 drawing symbol (unicode) */ ! 1253: { 9612 ,NULL }, /* 221 drawing symbol (unicode) */ ! 1254: { 9616 ,NULL }, /* 222 drawing symbol (unicode) */ ! 1255: { 9600 ,NULL }, /* 223 drawing symbol (unicode) */ ! 1256: { 945 ,NULL }, /* 224 alpha symbol */ ! 1257: { 223 ,"szlig" }, /* 225 sz ligature (beta symbol) */ ! 1258: { 915 ,NULL }, /* 226 omega symbol */ ! 1259: { 960 ,NULL }, /* 227 pi symbol*/ ! 1260: { 931 ,NULL }, /* 228 epsilon symbol */ ! 1261: { 963 ,NULL }, /* 229 o with stick */ ! 1262: { 181 ,"micro" }, /* 230 Micro sign (Greek mu) */ ! 1263: { 964 ,NULL }, /* 231 greek char? */ ! 1264: { 934 ,NULL }, /* 232 greek char? */ ! 1265: { 920 ,NULL }, /* 233 greek char? */ ! 1266: { 937 ,NULL }, /* 234 greek char? */ ! 1267: { 948 ,NULL }, /* 235 greek char? */ ! 1268: { 8734 ,NULL }, /* 236 infinity symbol (unicode) */ ! 1269: { 966 ,"oslash" }, /* 237 Greek Phi */ ! 1270: { 949 ,NULL }, /* 238 rounded E */ ! 1271: { 8745 ,NULL }, /* 239 unside down U (unicode) */ ! 1272: { 8801 ,NULL }, /* 240 drawing symbol (unicode) */ ! 1273: { 177 ,"plusmn" }, /* 241 Plus or minus */ ! 1274: { 8805 ,NULL }, /* 242 drawing symbol (unicode) */ ! 1275: { 8804 ,NULL }, /* 243 drawing symbol (unicode) */ ! 1276: { 8992 ,NULL }, /* 244 drawing symbol (unicode) */ ! 1277: { 8993 ,NULL }, /* 245 drawing symbol (unicode) */ ! 1278: { 247 ,"divide" }, /* 246 Division sign */ ! 1279: { 8776 ,NULL }, /* 247 two squiggles (unicode) */ ! 1280: { 176 ,"deg" }, /* 248 Degree sign */ ! 1281: { 8729 ,NULL }, /* 249 drawing symbol (unicode) */ ! 1282: { 183 ,"middot" }, /* 250 Middle dot */ ! 1283: { 8730 ,NULL }, /* 251 check mark (unicode) */ ! 1284: { 8319 ,NULL }, /* 252 superscript n (unicode) */ ! 1285: { 178 ,"sup2" }, /* 253 superscript 2 */ ! 1286: { 9632 ,NULL }, /* 254 drawing symbol (unicode) */ ! 1287: { 160 ,"nbsp" } /* 255 non-breaking space */ ! 1288: }; ! 1289: ! 1290: static struct { ! 1291: int value; ! 1292: char* name; ! 1293: } lowasctbl[32] = { ! 1294: { 160 ,"nbsp" }, /* NULL non-breaking space */ ! 1295: { 9786 ,NULL }, /* white smiling face */ ! 1296: { 9787 ,NULL }, /* black smiling face */ ! 1297: { 9829 ,"hearts" }, /* black heart suit */ ! 1298: { 9830 ,"diams" }, /* black diamond suit */ ! 1299: { 9827 ,"clubs" }, /* black club suit */ ! 1300: { 9824 ,"spades" }, /* black spade suit */ ! 1301: { 8226 ,"bull" }, /* bullet */ ! 1302: { 9688 ,NULL }, /* inverse bullet */ ! 1303: { 9702 ,NULL }, /* white bullet */ ! 1304: { 9689 ,NULL }, /* inverse white circle */ ! 1305: { 9794 ,NULL }, /* male sign */ ! 1306: { 9792 ,NULL }, /* female sign */ ! 1307: { 9834 ,NULL }, /* eighth note */ ! 1308: { 9835 ,NULL }, /* beamed eighth notes */ ! 1309: { 9788 ,NULL }, /* white sun with rays */ ! 1310: { 9654 ,NULL }, /* black right-pointing triangle */ ! 1311: { 9664 ,NULL }, /* black left-pointing triangle */ ! 1312: { 8597 ,NULL }, /* up down arrow */ ! 1313: { 8252 ,NULL }, /* double exclamation mark */ ! 1314: { 182 ,"para" }, /* pilcrow sign */ ! 1315: { 167 ,"sect" }, /* section sign */ ! 1316: { 9644 ,NULL }, /* black rectangle */ ! 1317: { 8616 ,NULL }, /* up down arrow with base */ ! 1318: { 8593 ,"uarr" }, /* upwards arrow */ ! 1319: { 8595 ,"darr" }, /* downwards arrow */ ! 1320: { 8594 ,"rarr" }, /* rightwards arrow */ ! 1321: { 8592 ,"larr" }, /* leftwards arrow */ ! 1322: { 8985 ,NULL }, /* turned not sign */ ! 1323: { 8596 ,"harr" }, /* left right arrow */ ! 1324: { 9650 ,NULL }, /* black up-pointing triangle */ ! 1325: { 9660 ,NULL } /* black down-pointing triangle */ ! 1326: }; ! 1327: ! 1328: static JSBool ! 1329: js_html_encode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1330: { ! 1331: int ch; ! 1332: ulong i,j; ! 1333: uchar* inbuf; ! 1334: uchar* tmpbuf; ! 1335: uchar* outbuf; ! 1336: uchar* param; ! 1337: char* lastparam; ! 1338: JSBool exascii=JS_TRUE; ! 1339: JSBool wsp=JS_TRUE; ! 1340: JSBool ansi=JS_TRUE; ! 1341: JSBool ctrl_a=JS_TRUE; ! 1342: JSString* js_str; ! 1343: int32 fg=7; ! 1344: int32 bg=0; ! 1345: JSBool blink=FALSE; ! 1346: JSBool bold=FALSE; ! 1347: int esccount=0; ! 1348: char ansi_seq[MAX_ANSI_SEQ+1]; ! 1349: int ansi_param[MAX_ANSI_PARAMS]; ! 1350: int k,l; ! 1351: ulong savepos=0; ! 1352: int32 hpos=0; ! 1353: int32 currrow=0; ! 1354: int savehpos=0; ! 1355: int savevpos=0; ! 1356: int32 wraphpos=-2; ! 1357: int32 wrapvpos=-2; ! 1358: int32 wrappos=0; ! 1359: BOOL extchar=FALSE; ! 1360: ulong obsize; ! 1361: int32 lastcolor=7; ! 1362: char tmp1[128]; ! 1363: struct tm tm; ! 1364: time_t now; ! 1365: BOOL nodisplay=FALSE; ! 1366: scfg_t* cfg; ! 1367: uchar attr_stack[64]; /* Saved attributes (stack) */ ! 1368: int attr_sp=0; /* Attribute stack pointer */ ! 1369: ulong clear_screen=0; ! 1370: JSObject* stateobj=NULL; ! 1371: jsval val; ! 1372: ! 1373: if(JSVAL_IS_VOID(argv[0])) ! 1374: return(JS_TRUE); ! 1375: ! 1376: if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) /* Will this work? Ask DM */ ! 1377: return(JS_FALSE); ! 1378: ! 1379: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 1380: return(JS_FALSE); ! 1381: ! 1382: if(argc>1 && JSVAL_IS_BOOLEAN(argv[1])) ! 1383: exascii=JSVAL_TO_BOOLEAN(argv[1]); ! 1384: ! 1385: if(argc>2 && JSVAL_IS_BOOLEAN(argv[2])) ! 1386: wsp=JSVAL_TO_BOOLEAN(argv[2]); ! 1387: ! 1388: if(argc>3 && JSVAL_IS_BOOLEAN(argv[3])) ! 1389: ansi=JSVAL_TO_BOOLEAN(argv[3]); ! 1390: ! 1391: if(argc>4 && JSVAL_IS_BOOLEAN(argv[4])) ! 1392: { ! 1393: ctrl_a=JSVAL_TO_BOOLEAN(argv[4]); ! 1394: if(ctrl_a) ! 1395: ansi=ctrl_a; ! 1396: } ! 1397: ! 1398: if(argc>5 && JSVAL_IS_OBJECT(argv[5])) { ! 1399: stateobj=JSVAL_TO_OBJECT(argv[5]); ! 1400: JS_GetProperty(cx,stateobj,"fg",&val); ! 1401: if(JSVAL_IS_NUMBER(val)) ! 1402: fg=JS_ValueToInt32(cx, val, &fg); ! 1403: JS_GetProperty(cx,stateobj,"bg",&val); ! 1404: if(JSVAL_IS_NUMBER(val)) ! 1405: fg=JS_ValueToInt32(cx, val, &bg); ! 1406: JS_GetProperty(cx,stateobj,"lastcolor",&val); ! 1407: if(JSVAL_IS_NUMBER(val)) ! 1408: fg=JS_ValueToInt32(cx, val, &lastcolor); ! 1409: JS_GetProperty(cx,stateobj,"blink",&val); ! 1410: if(JSVAL_IS_BOOLEAN(val)) ! 1411: fg=JS_ValueToBoolean(cx, val, &blink); ! 1412: JS_GetProperty(cx,stateobj,"bold",&val); ! 1413: if(JSVAL_IS_BOOLEAN(val)) ! 1414: fg=JS_ValueToBoolean(cx, val, &bold); ! 1415: JS_GetProperty(cx,stateobj,"hpos",&val); ! 1416: if(JSVAL_IS_NUMBER(val)) ! 1417: fg=JS_ValueToInt32(cx, val, &hpos); ! 1418: JS_GetProperty(cx,stateobj,"currrow",&val); ! 1419: if(JSVAL_IS_NUMBER(val)) ! 1420: fg=JS_ValueToInt32(cx, val, &currrow); ! 1421: JS_GetProperty(cx,stateobj,"wraphpos",&val); ! 1422: if(JSVAL_IS_NUMBER(val)) ! 1423: fg=JS_ValueToInt32(cx, val, &wraphpos); ! 1424: JS_GetProperty(cx,stateobj,"wrapvpos",&val); ! 1425: if(JSVAL_IS_NUMBER(val)) ! 1426: fg=JS_ValueToInt32(cx, val, &wrapvpos); ! 1427: JS_GetProperty(cx,stateobj,"wrappos",&val); ! 1428: if(JSVAL_IS_NUMBER(val)) ! 1429: fg=JS_ValueToInt32(cx, val, &wrappos); ! 1430: } ! 1431: ! 1432: if((tmpbuf=(char*)malloc((strlen(inbuf)*10)+1))==NULL) ! 1433: return(JS_FALSE); ! 1434: ! 1435: for(i=j=0;inbuf[i];i++) { ! 1436: switch(inbuf[i]) { ! 1437: case TAB: ! 1438: case LF: ! 1439: case CR: ! 1440: if(wsp) ! 1441: j+=sprintf(tmpbuf+j,"&#%u;",inbuf[i]); ! 1442: else ! 1443: tmpbuf[j++]=inbuf[i]; ! 1444: break; ! 1445: case '"': ! 1446: j+=sprintf(tmpbuf+j,"""); ! 1447: break; ! 1448: case '&': ! 1449: j+=sprintf(tmpbuf+j,"&"); ! 1450: break; ! 1451: case '<': ! 1452: j+=sprintf(tmpbuf+j,"<"); ! 1453: break; ! 1454: case '>': ! 1455: j+=sprintf(tmpbuf+j,">"); ! 1456: break; ! 1457: case '\b': ! 1458: j--; ! 1459: break; ! 1460: default: ! 1461: if(inbuf[i]&0x80) { ! 1462: if(exascii) { ! 1463: ch=inbuf[i]^0x80; ! 1464: if(exasctbl[ch].name!=NULL) ! 1465: j+=sprintf(tmpbuf+j,"&%s;",exasctbl[ch].name); ! 1466: else ! 1467: j+=sprintf(tmpbuf+j,"&#%u;",exasctbl[ch].value); ! 1468: } else ! 1469: tmpbuf[j++]=inbuf[i]; ! 1470: } ! 1471: else if(inbuf[i]>=' ' && inbuf[i]<DEL) ! 1472: tmpbuf[j++]=inbuf[i]; ! 1473: #if 0 /* ASCII 127 - Not displayed? */ ! 1474: else if(inbuf[i]==DEL && exascii) ! 1475: j+=sprintf(tmpbuf+j,"⌂",exasctbl[ch].value); ! 1476: #endif ! 1477: else if(inbuf[i]<' ') /* unknown control chars */ ! 1478: { ! 1479: if(ansi && inbuf[i]==ESC) ! 1480: { ! 1481: esccount++; ! 1482: tmpbuf[j++]=inbuf[i]; ! 1483: } ! 1484: else if(ctrl_a && inbuf[i]==1) ! 1485: { ! 1486: esccount++; ! 1487: tmpbuf[j++]=inbuf[i]; ! 1488: tmpbuf[j++]=inbuf[++i]; ! 1489: } ! 1490: else if(exascii) { ! 1491: ch=inbuf[i]; ! 1492: if(lowasctbl[ch].name!=NULL) ! 1493: j+=sprintf(tmpbuf+j,"&%s;",lowasctbl[ch].name); ! 1494: else ! 1495: j+=sprintf(tmpbuf+j,"&#%u;",lowasctbl[ch].value); ! 1496: } else ! 1497: j+=sprintf(tmpbuf+j,"&#%u;",inbuf[i]); ! 1498: } ! 1499: break; ! 1500: } ! 1501: } ! 1502: tmpbuf[j]=0; ! 1503: ! 1504: if(ansi) ! 1505: { ! 1506: obsize=(strlen(tmpbuf)+(esccount+1)*MAX_COLOR_STRING)+1; ! 1507: if(obsize<2048) ! 1508: obsize=2048; ! 1509: if((outbuf=(uchar*)malloc(obsize))==NULL) ! 1510: { ! 1511: free(tmpbuf); ! 1512: return(JS_FALSE); ! 1513: } ! 1514: j=sprintf(outbuf,"<span style=\"%s\">",htmlansi[7]); ! 1515: clear_screen=j; ! 1516: for(i=0;tmpbuf[i];i++) { ! 1517: if(j>(obsize/2)) /* Completely arbitrary here... must be carefull with this eventually ToDo */ ! 1518: { ! 1519: obsize+=(obsize/2); ! 1520: if((param=realloc(outbuf,obsize))==NULL) ! 1521: { ! 1522: free(tmpbuf); ! 1523: free(outbuf); ! 1524: return(JS_FALSE); ! 1525: } ! 1526: outbuf=param; ! 1527: } ! 1528: if(tmpbuf[i]==ESC && tmpbuf[i+1]=='[') ! 1529: { ! 1530: if(nodisplay) ! 1531: continue; ! 1532: k=0; ! 1533: memset(&ansi_param,0xff,sizeof(int)*MAX_ANSI_PARAMS); ! 1534: strncpy(ansi_seq, tmpbuf+i+2, MAX_ANSI_SEQ); ! 1535: ansi_seq[MAX_ANSI_SEQ]=0; ! 1536: for(lastparam=ansi_seq;*lastparam;lastparam++) ! 1537: { ! 1538: if(isalpha(*lastparam)) ! 1539: { ! 1540: *(++lastparam)=0; ! 1541: break; ! 1542: } ! 1543: } ! 1544: k=0; ! 1545: param=ansi_seq; ! 1546: if(*param=='?') /* This is to fix ESC[?7 whatever that is */ ! 1547: param++; ! 1548: if(isdigit(*param)) ! 1549: ansi_param[k++]=atoi(ansi_seq); ! 1550: while(isspace(*param) || isdigit(*param)) ! 1551: param++; ! 1552: lastparam=param; ! 1553: while((param=strchr(param,';'))!=NULL) ! 1554: { ! 1555: param++; ! 1556: ansi_param[k++]=atoi(param); ! 1557: while(isspace(*param) || isdigit(*param)) ! 1558: param++; ! 1559: lastparam=param; ! 1560: } ! 1561: switch(*lastparam) ! 1562: { ! 1563: case 'm': /* Colour */ ! 1564: for(k=0;ansi_param[k]>=0;k++) ! 1565: { ! 1566: switch(ansi_param[k]) ! 1567: { ! 1568: case 0: ! 1569: fg=7; ! 1570: bg=0; ! 1571: blink=FALSE; ! 1572: bold=FALSE; ! 1573: break; ! 1574: case 1: ! 1575: bold=TRUE; ! 1576: break; ! 1577: case 2: ! 1578: bold=FALSE; ! 1579: break; ! 1580: case 5: ! 1581: blink=TRUE; ! 1582: break; ! 1583: case 6: ! 1584: blink=TRUE; ! 1585: break; ! 1586: case 7: ! 1587: l=fg; ! 1588: fg=bg; ! 1589: bg=l; ! 1590: break; ! 1591: case 8: ! 1592: fg=bg; ! 1593: blink=FALSE; ! 1594: bold=FALSE; ! 1595: break; ! 1596: case 30: ! 1597: case 31: ! 1598: case 32: ! 1599: case 33: ! 1600: case 34: ! 1601: case 35: ! 1602: case 36: ! 1603: case 37: ! 1604: fg=ansi_param[k]-30; ! 1605: break; ! 1606: case 40: ! 1607: case 41: ! 1608: case 42: ! 1609: case 43: ! 1610: case 44: ! 1611: case 45: ! 1612: case 46: ! 1613: case 47: ! 1614: bg=ansi_param[k]-40; ! 1615: break; ! 1616: } ! 1617: } ! 1618: break; ! 1619: case 'C': /* Move right */ ! 1620: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX); ! 1621: lastcolor=0; ! 1622: l=ansi_param[0]>0?ansi_param[0]:1; ! 1623: if(wrappos==0 && wrapvpos==currrow) { ! 1624: /* j+=sprintf(outbuf+j,"<!-- \r\nC after A l=%d hpos=%d -->",l,hpos); */ ! 1625: l=l-hpos; ! 1626: wrapvpos=-2; /* Prevent additional move right */ ! 1627: } ! 1628: if(l>81-hpos) ! 1629: l=81-hpos; ! 1630: for(k=0; k<l; k++) ! 1631: { ! 1632: j+=sprintf(outbuf+j,"%s"," "); ! 1633: hpos++; ! 1634: } ! 1635: break; ! 1636: case 's': /* Save position */ ! 1637: savepos=j; ! 1638: savehpos=hpos; ! 1639: savevpos=currrow; ! 1640: break; ! 1641: case 'u': /* Restore saved position */ ! 1642: j=savepos; ! 1643: hpos=savehpos; ! 1644: currrow=savevpos; ! 1645: break; ! 1646: case 'H': /* Move */ ! 1647: k=ansi_param[0]; ! 1648: if(k<=0) ! 1649: k=1; ! 1650: k--; ! 1651: l=ansi_param[1]; ! 1652: if(l<=0) ! 1653: l=1; ! 1654: l--; ! 1655: while(k>currrow) ! 1656: { ! 1657: hpos=0; ! 1658: currrow++; ! 1659: outbuf[j++]='\r'; ! 1660: outbuf[j++]='\n'; ! 1661: } ! 1662: if(l>hpos) ! 1663: { ! 1664: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX); ! 1665: lastcolor=0; ! 1666: while(l>hpos) ! 1667: { ! 1668: j+=sprintf(outbuf+j,"%s"," "); ! 1669: hpos++; ! 1670: } ! 1671: } ! 1672: break; ! 1673: case 'B': /* Move down */ ! 1674: l=ansi_param[0]; ! 1675: if(l<=0) ! 1676: l=1; ! 1677: for(k=0; k < l; k++) ! 1678: { ! 1679: currrow++; ! 1680: outbuf[j++]='\r'; ! 1681: outbuf[j++]='\n'; ! 1682: } ! 1683: if(hpos!=0 && tmpbuf[i+1]!=CR) ! 1684: { ! 1685: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX); ! 1686: lastcolor=0; ! 1687: for(k=0; k<hpos ; k++) ! 1688: { ! 1689: j+=sprintf(outbuf+j,"%s"," "); ! 1690: } ! 1691: break; ! 1692: } ! 1693: break; ! 1694: case 'A': /* Move up */ ! 1695: l=wrappos; ! 1696: if(j > (ulong)wrappos && hpos==0 && currrow==wrapvpos+1 && ansi_param[0]<=1) { ! 1697: hpos=wraphpos; ! 1698: currrow=wrapvpos; ! 1699: j=wrappos; ! 1700: wrappos=0; /* Prevent additional move up */ ! 1701: } ! 1702: break; ! 1703: case 'J': /* Clear */ ! 1704: if(ansi_param[0]==2) { ! 1705: j=clear_screen; ! 1706: hpos=0; ! 1707: currrow=0; ! 1708: wraphpos=-2; ! 1709: wrapvpos=-2; ! 1710: wrappos=0; ! 1711: } ! 1712: break; ! 1713: } ! 1714: i+=(int)(lastparam-ansi_seq)+2; ! 1715: } ! 1716: else if(ctrl_a && tmpbuf[i]==1) /* CTRL-A codes */ ! 1717: { ! 1718: /* j+=sprintf(outbuf+j,"<!-- CTRL-A-%c (%u) -->",tmpbuf[i+1],tmpbuf[i+1]); */ ! 1719: if(nodisplay && tmpbuf[i+1] != ')') ! 1720: continue; ! 1721: if(tmpbuf[i+1]>0x7f) ! 1722: { ! 1723: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX); ! 1724: lastcolor=0; ! 1725: l=tmpbuf[i+1]-0x7f; ! 1726: if(l>81-hpos) ! 1727: l=81-hpos; ! 1728: for(k=0; k<l; k++) ! 1729: { ! 1730: j+=sprintf(outbuf+j,"%s"," "); ! 1731: hpos++; ! 1732: } ! 1733: } ! 1734: else switch(toupper(tmpbuf[i+1])) ! 1735: { ! 1736: case 'K': ! 1737: fg=0; ! 1738: break; ! 1739: case 'R': ! 1740: fg=1; ! 1741: break; ! 1742: case 'G': ! 1743: fg=2; ! 1744: break; ! 1745: case 'Y': ! 1746: fg=3; ! 1747: break; ! 1748: case 'B': ! 1749: fg=4; ! 1750: break; ! 1751: case 'M': ! 1752: fg=5; ! 1753: break; ! 1754: case 'C': ! 1755: fg=6; ! 1756: break; ! 1757: case 'W': ! 1758: fg=7; ! 1759: break; ! 1760: case '0': ! 1761: bg=0; ! 1762: break; ! 1763: case '1': ! 1764: bg=1; ! 1765: break; ! 1766: case '2': ! 1767: bg=2; ! 1768: break; ! 1769: case '3': ! 1770: bg=3; ! 1771: break; ! 1772: case '4': ! 1773: bg=4; ! 1774: break; ! 1775: case '5': ! 1776: bg=5; ! 1777: break; ! 1778: case '6': ! 1779: bg=6; ! 1780: break; ! 1781: case '7': ! 1782: bg=7; ! 1783: break; ! 1784: case 'H': ! 1785: bold=TRUE; ! 1786: break; ! 1787: case 'I': ! 1788: blink=TRUE; ! 1789: break; ! 1790: case '+': ! 1791: if(attr_sp<(int)sizeof(attr_stack)) ! 1792: attr_stack[attr_sp++]=(blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | (int)fg; ! 1793: break; ! 1794: case '-': ! 1795: if(attr_sp>0) ! 1796: { ! 1797: blink=(attr_stack[--attr_sp]&(1<<7))?TRUE:FALSE; ! 1798: bg=(attr_stack[attr_sp] >> 4) & 7; ! 1799: blink=(attr_stack[attr_sp]&(1<<3))?TRUE:FALSE; ! 1800: fg=attr_stack[attr_sp] & 7; ! 1801: } ! 1802: else if(bold || blink || bg) ! 1803: { ! 1804: bold=FALSE; ! 1805: blink=FALSE; ! 1806: fg=7; ! 1807: bg=0; ! 1808: } ! 1809: break; ! 1810: case '_': ! 1811: if(blink || bg) ! 1812: { ! 1813: bold=FALSE; ! 1814: blink=FALSE; ! 1815: fg=7; ! 1816: bg=0; ! 1817: } ! 1818: break; ! 1819: case 'N': ! 1820: bold=FALSE; ! 1821: blink=FALSE; ! 1822: fg=7; ! 1823: bg=0; ! 1824: break; ! 1825: case 'P': ! 1826: case 'Q': ! 1827: case ',': ! 1828: case ';': ! 1829: case '.': ! 1830: case 'S': ! 1831: case '>': ! 1832: case '<': ! 1833: break; ! 1834: ! 1835: case '!': /* This needs to be fixed! (Somehow) */ ! 1836: case '@': ! 1837: case '#': ! 1838: case '$': ! 1839: case '%': ! 1840: case '^': ! 1841: case '&': ! 1842: case '*': ! 1843: case '(': ! 1844: nodisplay=TRUE; ! 1845: break; ! 1846: case ')': ! 1847: nodisplay=FALSE; ! 1848: break; ! 1849: ! 1850: case 'D': ! 1851: now=time(NULL); ! 1852: j+=sprintf(outbuf+j,"%s",unixtodstr(cfg,now,tmp1)); ! 1853: break; ! 1854: case 'T': ! 1855: now=time(NULL); ! 1856: localtime_r(&now,&tm); ! 1857: j+=sprintf(outbuf+j,"%02d:%02d %s" ! 1858: ,tm.tm_hour==0 ? 12 ! 1859: : tm.tm_hour>12 ? tm.tm_hour-12 ! 1860: : tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am"); ! 1861: break; ! 1862: ! 1863: case 'L': ! 1864: currrow=0; ! 1865: hpos=0; ! 1866: outbuf[j++]='\r'; ! 1867: outbuf[j++]='\n'; ! 1868: break; ! 1869: case ']': ! 1870: currrow++; ! 1871: if(hpos!=0 && tmpbuf[i+2]!=CR && !(tmpbuf[i+2]==1 && tmpbuf[i+3]=='[')) ! 1872: { ! 1873: outbuf[j++]='\r'; ! 1874: outbuf[j++]='\n'; ! 1875: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX); ! 1876: lastcolor=0; ! 1877: for(k=0; k<hpos ; k++) ! 1878: { ! 1879: j+=sprintf(outbuf+j,"%s"," "); ! 1880: } ! 1881: break; ! 1882: } ! 1883: outbuf[j++]='\n'; ! 1884: break; ! 1885: case '[': ! 1886: outbuf[j++]='\r'; ! 1887: hpos=0; ! 1888: break; ! 1889: case 'Z': ! 1890: outbuf[j++]=0; ! 1891: break; ! 1892: case 'A': ! 1893: default: ! 1894: if(exascii) { ! 1895: ch=tmpbuf[i]; ! 1896: if(lowasctbl[ch].name!=NULL) ! 1897: j+=sprintf(outbuf+j,"&%s;",lowasctbl[ch].name); ! 1898: else ! 1899: j+=sprintf(outbuf+j,"&#%u;",lowasctbl[ch].value); ! 1900: } else ! 1901: j+=sprintf(outbuf+j,"&#%u;",inbuf[i]); ! 1902: i--; ! 1903: } ! 1904: i++; ! 1905: } ! 1906: else ! 1907: { ! 1908: if(nodisplay) ! 1909: continue; ! 1910: switch(tmpbuf[i]) ! 1911: { ! 1912: case TAB: /* This assumes that tabs do NOT use the current background. */ ! 1913: l=hpos%8; ! 1914: if(l==0) ! 1915: l=8; ! 1916: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX); ! 1917: lastcolor=0; ! 1918: for(k=0; k<l ; k++) ! 1919: { ! 1920: j+=sprintf(outbuf+j,"%s"," "); ! 1921: hpos++; ! 1922: } ! 1923: break; ! 1924: case LF: ! 1925: wrapvpos=currrow; ! 1926: if((ulong)wrappos<j-3) ! 1927: wrappos=j; ! 1928: currrow++; ! 1929: if(hpos!=0 && tmpbuf[i+1]!=CR) ! 1930: { ! 1931: outbuf[j++]='\r'; ! 1932: outbuf[j++]='\n'; ! 1933: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX); ! 1934: lastcolor=0; ! 1935: for(k=0; k<hpos ; k++) ! 1936: { ! 1937: j+=sprintf(outbuf+j,"%s"," "); ! 1938: } ! 1939: break; ! 1940: } ! 1941: case CR: ! 1942: if(wraphpos==-2 || hpos!=0) ! 1943: wraphpos=hpos; ! 1944: if((ulong)wrappos<j-3) ! 1945: wrappos=j; ! 1946: outbuf[j++]=tmpbuf[i]; ! 1947: hpos=0; ! 1948: break; ! 1949: default: ! 1950: if(lastcolor != ((blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | fg)) ! 1951: { ! 1952: lastcolor=(blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | fg; ! 1953: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[lastcolor],HTML_COLOR_SUFFIX); ! 1954: } ! 1955: outbuf[j++]=tmpbuf[i]; ! 1956: if(tmpbuf[i]=='&') ! 1957: extchar=TRUE; ! 1958: if(tmpbuf[i]==';') ! 1959: extchar=FALSE; ! 1960: if(!extchar) ! 1961: hpos++; ! 1962: /* ToDo: Fix hard-coded terminal window width (80) */ ! 1963: if(hpos>=80 && tmpbuf[i+1] != '\r' && tmpbuf[i+1] != '\n' && tmpbuf[i+1] != ESC) ! 1964: { ! 1965: wrapvpos=-2; ! 1966: wraphpos=-2; ! 1967: wrappos=0; ! 1968: hpos=0; ! 1969: currrow++; ! 1970: outbuf[j++]='\r'; ! 1971: outbuf[j++]='\n'; ! 1972: } ! 1973: } ! 1974: } ! 1975: } ! 1976: strcpy(outbuf+j,"</span>"); ! 1977: ! 1978: js_str = JS_NewStringCopyZ(cx, outbuf); ! 1979: free(outbuf); ! 1980: } ! 1981: else ! 1982: js_str = JS_NewStringCopyZ(cx, tmpbuf); ! 1983: ! 1984: free(tmpbuf); /* assertion here, Feb-20-2006 */ ! 1985: if(js_str==NULL) ! 1986: return(JS_FALSE); ! 1987: ! 1988: *rval = STRING_TO_JSVAL(js_str); ! 1989: ! 1990: if(stateobj!=NULL) { ! 1991: JS_DefineProperty(cx, stateobj, "fg", INT_TO_JSVAL(fg) ! 1992: ,NULL,NULL,JSPROP_ENUMERATE); ! 1993: JS_DefineProperty(cx, stateobj, "bg", INT_TO_JSVAL(bg) ! 1994: ,NULL,NULL,JSPROP_ENUMERATE); ! 1995: JS_DefineProperty(cx, stateobj, "lastcolor", INT_TO_JSVAL(lastcolor) ! 1996: ,NULL,NULL,JSPROP_ENUMERATE); ! 1997: JS_DefineProperty(cx, stateobj, "blink", BOOLEAN_TO_JSVAL(blink) ! 1998: ,NULL,NULL,JSPROP_ENUMERATE); ! 1999: JS_DefineProperty(cx, stateobj, "bold", BOOLEAN_TO_JSVAL(bold) ! 2000: ,NULL,NULL,JSPROP_ENUMERATE); ! 2001: JS_DefineProperty(cx, stateobj, "hpos", INT_TO_JSVAL(hpos) ! 2002: ,NULL,NULL,JSPROP_ENUMERATE); ! 2003: JS_DefineProperty(cx, stateobj, "currrow", INT_TO_JSVAL(currrow) ! 2004: ,NULL,NULL,JSPROP_ENUMERATE); ! 2005: JS_DefineProperty(cx, stateobj, "wraphpos", INT_TO_JSVAL(wraphpos) ! 2006: ,NULL,NULL,JSPROP_ENUMERATE); ! 2007: JS_DefineProperty(cx, stateobj, "wrapvpos", INT_TO_JSVAL(wrapvpos) ! 2008: ,NULL,NULL,JSPROP_ENUMERATE); ! 2009: JS_DefineProperty(cx, stateobj, "wrappos", INT_TO_JSVAL(wrappos) ! 2010: ,NULL,NULL,JSPROP_ENUMERATE); ! 2011: } ! 2012: ! 2013: return(JS_TRUE); ! 2014: } ! 2015: ! 2016: static JSBool ! 2017: js_html_decode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2018: { ! 2019: int ch; ! 2020: int val; ! 2021: ulong i,j; ! 2022: uchar* inbuf; ! 2023: uchar* outbuf; ! 2024: char token[16]; ! 2025: size_t t; ! 2026: JSString* js_str; ! 2027: ! 2028: if(JSVAL_IS_VOID(argv[0])) ! 2029: return(JS_TRUE); ! 2030: ! 2031: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2032: return(JS_FALSE); ! 2033: ! 2034: if((outbuf=(char*)malloc(strlen(inbuf)+1))==NULL) ! 2035: return(JS_FALSE); ! 2036: ! 2037: for(i=j=0;inbuf[i];i++) { ! 2038: if(inbuf[i]!='&') { ! 2039: outbuf[j++]=inbuf[i]; ! 2040: continue; ! 2041: } ! 2042: for(i++,t=0; inbuf[i]!=0 && inbuf[i]!=';' && t<sizeof(token)-1; i++, t++) ! 2043: token[t]=inbuf[i]; ! 2044: if(inbuf[i]==0) ! 2045: break; ! 2046: token[t]=0; ! 2047: ! 2048: /* First search the ex-ascii table for a name match */ ! 2049: for(ch=0;ch<128;ch++) ! 2050: if(exasctbl[ch].name!=NULL && strcmp(token,exasctbl[ch].name)==0) ! 2051: break; ! 2052: if(ch<128) { ! 2053: outbuf[j++]=ch|0x80; ! 2054: continue; ! 2055: } ! 2056: if(token[0]=='#') { /* numeric constant */ ! 2057: val=atoi(token+1); ! 2058: ! 2059: /* search ex-ascii table for a value match */ ! 2060: for(ch=0;ch<128;ch++) ! 2061: if(exasctbl[ch].value==val) ! 2062: break; ! 2063: if(ch<128) { ! 2064: outbuf[j++]=ch|0x80; ! 2065: continue; ! 2066: } ! 2067: ! 2068: if((val>=' ' && val<=0xff) || val=='\r' || val=='\n' || val=='\t') { ! 2069: outbuf[j++]=val; ! 2070: continue; ! 2071: } ! 2072: } ! 2073: if(strcmp(token,"quot")==0) { ! 2074: outbuf[j++]='"'; ! 2075: continue; ! 2076: } ! 2077: if(strcmp(token,"amp")==0) { ! 2078: outbuf[j++]='&'; ! 2079: continue; ! 2080: } ! 2081: if(strcmp(token,"lt")==0) { ! 2082: outbuf[j++]='<'; ! 2083: continue; ! 2084: } ! 2085: if(strcmp(token,"gt")==0) { ! 2086: outbuf[j++]='>'; ! 2087: continue; ! 2088: } ! 2089: if(strcmp(token,"curren")==0) { ! 2090: outbuf[j++]=CTRL_O; ! 2091: continue; ! 2092: } ! 2093: if(strcmp(token,"para")==0) { ! 2094: outbuf[j++]=CTRL_T; ! 2095: continue; ! 2096: } ! 2097: if(strcmp(token,"sect")==0) { ! 2098: outbuf[j++]=CTRL_U; ! 2099: continue; ! 2100: } ! 2101: /* Unknown character entity, leave intact */ ! 2102: j+=sprintf(outbuf+j,"&%s;",token); ! 2103: ! 2104: } ! 2105: outbuf[j]=0; ! 2106: ! 2107: js_str = JS_NewStringCopyZ(cx, outbuf); ! 2108: free(outbuf); ! 2109: if(js_str==NULL) ! 2110: return(JS_FALSE); ! 2111: ! 2112: *rval = STRING_TO_JSVAL(js_str); ! 2113: return(JS_TRUE); ! 2114: } ! 2115: ! 2116: static JSBool ! 2117: js_b64_encode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2118: { ! 2119: int res; ! 2120: size_t len; ! 2121: size_t inbuf_len; ! 2122: uchar* inbuf; ! 2123: uchar* outbuf; ! 2124: JSString* js_str; ! 2125: ! 2126: *rval = JSVAL_NULL; ! 2127: ! 2128: if(JSVAL_IS_VOID(argv[0])) ! 2129: return(JS_TRUE); ! 2130: ! 2131: if((inbuf=js_ValueToStringBytes(cx, argv[0], &inbuf_len))==NULL) ! 2132: return(JS_FALSE); ! 2133: ! 2134: len=(inbuf_len*10)+1; ! 2135: ! 2136: if((outbuf=(char*)malloc(len))==NULL) ! 2137: return(JS_FALSE); ! 2138: ! 2139: res=b64_encode(outbuf,len,inbuf,inbuf_len); ! 2140: ! 2141: if(res<1) { ! 2142: free(outbuf); ! 2143: return(JS_TRUE); ! 2144: } ! 2145: ! 2146: js_str = JS_NewStringCopyZ(cx, outbuf); ! 2147: free(outbuf); ! 2148: if(js_str==NULL) ! 2149: return(JS_FALSE); ! 2150: ! 2151: *rval = STRING_TO_JSVAL(js_str); ! 2152: return(JS_TRUE); ! 2153: } ! 2154: ! 2155: static JSBool ! 2156: js_b64_decode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2157: { ! 2158: int res; ! 2159: size_t len; ! 2160: uchar* inbuf; ! 2161: uchar* outbuf; ! 2162: JSString* js_str; ! 2163: ! 2164: *rval = JSVAL_NULL; ! 2165: ! 2166: if(JSVAL_IS_VOID(argv[0])) ! 2167: return(JS_TRUE); ! 2168: ! 2169: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2170: return(JS_FALSE); ! 2171: ! 2172: len=strlen(inbuf)+1; ! 2173: ! 2174: if((outbuf=(char*)malloc(len))==NULL) ! 2175: return(JS_FALSE); ! 2176: ! 2177: res=b64_decode(outbuf,len,inbuf,strlen(inbuf)); ! 2178: ! 2179: if(res<1) { ! 2180: free(outbuf); ! 2181: return(JS_TRUE); ! 2182: } ! 2183: ! 2184: js_str = JS_NewStringCopyN(cx, outbuf, res); ! 2185: free(outbuf); ! 2186: if(js_str==NULL) ! 2187: return(JS_FALSE); ! 2188: ! 2189: *rval = STRING_TO_JSVAL(js_str); ! 2190: return(JS_TRUE); ! 2191: } ! 2192: ! 2193: static JSBool ! 2194: js_md5_calc(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) ! 2195: { ! 2196: BYTE digest[MD5_DIGEST_SIZE]; ! 2197: JSBool hex=JS_FALSE; ! 2198: size_t inbuf_len; ! 2199: char* inbuf; ! 2200: char outbuf[64]; ! 2201: JSString* js_str; ! 2202: ! 2203: *rval = JSVAL_NULL; ! 2204: ! 2205: if(JSVAL_IS_VOID(argv[0])) ! 2206: return(JS_TRUE); ! 2207: ! 2208: if((inbuf=js_ValueToStringBytes(cx, argv[0], &inbuf_len))==NULL) ! 2209: return(JS_FALSE); ! 2210: ! 2211: if(argc>1 && JSVAL_IS_BOOLEAN(argv[1])) ! 2212: hex=JSVAL_TO_BOOLEAN(argv[1]); ! 2213: ! 2214: MD5_calc(digest,inbuf,inbuf_len); ! 2215: ! 2216: if(hex) ! 2217: MD5_hex(outbuf,digest); ! 2218: else ! 2219: b64_encode(outbuf,sizeof(outbuf),digest,sizeof(digest)); ! 2220: ! 2221: js_str = JS_NewStringCopyZ(cx, outbuf); ! 2222: if(js_str==NULL) ! 2223: return(JS_FALSE); ! 2224: ! 2225: *rval = STRING_TO_JSVAL(js_str); ! 2226: return(JS_TRUE); ! 2227: } ! 2228: ! 2229: static JSBool ! 2230: js_truncsp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2231: { ! 2232: char* p; ! 2233: char* str; ! 2234: JSString* js_str; ! 2235: ! 2236: if(JSVAL_IS_VOID(argv[0])) ! 2237: return(JS_TRUE); ! 2238: ! 2239: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2240: return(JS_FALSE); ! 2241: ! 2242: if((p=strdup(str))==NULL) ! 2243: return(JS_FALSE); ! 2244: ! 2245: truncsp(p); ! 2246: ! 2247: js_str = JS_NewStringCopyZ(cx, p); ! 2248: free(p); ! 2249: if(js_str==NULL) ! 2250: return(JS_FALSE); ! 2251: ! 2252: *rval = STRING_TO_JSVAL(js_str); ! 2253: return(JS_TRUE); ! 2254: } ! 2255: ! 2256: static JSBool ! 2257: js_truncstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2258: { ! 2259: char* p; ! 2260: char* str; ! 2261: char* set; ! 2262: JSString* js_str; ! 2263: ! 2264: if(JSVAL_IS_VOID(argv[0])) ! 2265: return(JS_TRUE); ! 2266: ! 2267: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2268: return(JS_FALSE); ! 2269: ! 2270: if((set=js_ValueToStringBytes(cx, argv[1], NULL))==NULL) ! 2271: return(JS_FALSE); ! 2272: ! 2273: if((p=strdup(str))==NULL) ! 2274: return(JS_FALSE); ! 2275: ! 2276: truncstr(p,set); ! 2277: ! 2278: js_str = JS_NewStringCopyZ(cx, p); ! 2279: free(p); ! 2280: if(js_str==NULL) ! 2281: return(JS_FALSE); ! 2282: ! 2283: *rval = STRING_TO_JSVAL(js_str); ! 2284: return(JS_TRUE); ! 2285: } ! 2286: ! 2287: static JSBool ! 2288: js_backslash(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2289: { ! 2290: char path[MAX_PATH+1]; ! 2291: char* str; ! 2292: JSString* js_str; ! 2293: ! 2294: if(JSVAL_IS_VOID(argv[0])) ! 2295: return(JS_TRUE); ! 2296: ! 2297: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2298: return(JS_FALSE); ! 2299: ! 2300: SAFECOPY(path,str); ! 2301: backslash(path); ! 2302: ! 2303: if((js_str = JS_NewStringCopyZ(cx, path))==NULL) ! 2304: return(JS_FALSE); ! 2305: ! 2306: *rval = STRING_TO_JSVAL(js_str); ! 2307: return(JS_TRUE); ! 2308: } ! 2309: ! 2310: ! 2311: static JSBool ! 2312: js_getfname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2313: { ! 2314: char* str; ! 2315: JSString* js_str; ! 2316: ! 2317: if(JSVAL_IS_VOID(argv[0])) ! 2318: return(JS_TRUE); ! 2319: ! 2320: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2321: return(JS_FALSE); ! 2322: ! 2323: js_str = JS_NewStringCopyZ(cx, getfname(str)); ! 2324: if(js_str==NULL) ! 2325: return(JS_FALSE); ! 2326: ! 2327: *rval = STRING_TO_JSVAL(js_str); ! 2328: return(JS_TRUE); ! 2329: } ! 2330: ! 2331: static JSBool ! 2332: js_getfext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2333: { ! 2334: char* str; ! 2335: char* p; ! 2336: JSString* js_str; ! 2337: ! 2338: if(JSVAL_IS_VOID(argv[0])) ! 2339: return(JS_TRUE); ! 2340: ! 2341: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2342: return(JS_FALSE); ! 2343: ! 2344: if((p=getfext(str))==NULL) ! 2345: return(JS_TRUE); ! 2346: ! 2347: js_str = JS_NewStringCopyZ(cx, p); ! 2348: if(js_str==NULL) ! 2349: return(JS_FALSE); ! 2350: ! 2351: *rval = STRING_TO_JSVAL(js_str); ! 2352: return(JS_TRUE); ! 2353: } ! 2354: ! 2355: static JSBool ! 2356: js_getfcase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2357: { ! 2358: char* str; ! 2359: char path[MAX_PATH+1]; ! 2360: JSString* js_str; ! 2361: ! 2362: if(JSVAL_IS_VOID(argv[0])) ! 2363: return(JS_TRUE); ! 2364: ! 2365: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2366: return(JS_FALSE); ! 2367: ! 2368: SAFECOPY(path,str); ! 2369: if(fexistcase(path)) { ! 2370: js_str = JS_NewStringCopyZ(cx, path); ! 2371: if(js_str==NULL) ! 2372: return(JS_FALSE); ! 2373: ! 2374: *rval = STRING_TO_JSVAL(js_str); ! 2375: } ! 2376: return(JS_TRUE); ! 2377: } ! 2378: ! 2379: static JSBool ! 2380: js_cfgfname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2381: { ! 2382: char* path; ! 2383: char* fname; ! 2384: char result[MAX_PATH+1]; ! 2385: ! 2386: if(JSVAL_IS_VOID(argv[0])) ! 2387: return(JS_TRUE); ! 2388: ! 2389: if((path=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2390: return(JS_FALSE); ! 2391: ! 2392: if((fname=js_ValueToStringBytes(cx, argv[1], NULL))==NULL) ! 2393: return(JS_FALSE); ! 2394: ! 2395: *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,iniFileName(result,sizeof(result),path,fname))); ! 2396: ! 2397: return(JS_TRUE); ! 2398: } ! 2399: ! 2400: static JSBool ! 2401: js_fexist(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2402: { ! 2403: char* p; ! 2404: ! 2405: if(JSVAL_IS_VOID(argv[0])) ! 2406: return(JS_TRUE); ! 2407: ! 2408: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2409: return(JS_FALSE); ! 2410: ! 2411: *rval = BOOLEAN_TO_JSVAL(fexist(p)); ! 2412: return(JS_TRUE); ! 2413: } ! 2414: ! 2415: static JSBool ! 2416: js_removecase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2417: { ! 2418: char* p; ! 2419: ! 2420: if(JSVAL_IS_VOID(argv[0])) ! 2421: return(JS_TRUE); ! 2422: ! 2423: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2424: return(JS_FALSE); ! 2425: ! 2426: *rval = BOOLEAN_TO_JSVAL(removecase(p)==0); ! 2427: return(JS_TRUE); ! 2428: } ! 2429: ! 2430: static JSBool ! 2431: js_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2432: { ! 2433: char* p; ! 2434: ! 2435: if(JSVAL_IS_VOID(argv[0])) ! 2436: return(JS_TRUE); ! 2437: ! 2438: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2439: return(JS_FALSE); ! 2440: ! 2441: *rval = BOOLEAN_TO_JSVAL(remove(p)==0); ! 2442: return(JS_TRUE); ! 2443: } ! 2444: ! 2445: static JSBool ! 2446: js_rename(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2447: { ! 2448: char* oldname; ! 2449: char* newname; ! 2450: ! 2451: if(JSVAL_IS_VOID(argv[0])) ! 2452: return(JS_TRUE); ! 2453: ! 2454: *rval = BOOLEAN_TO_JSVAL(JS_FALSE); ! 2455: if((oldname=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2456: return(JS_TRUE); ! 2457: if((newname=js_ValueToStringBytes(cx, argv[1], NULL))==NULL) ! 2458: return(JS_TRUE); ! 2459: ! 2460: *rval = BOOLEAN_TO_JSVAL(rename(oldname,newname)==0); ! 2461: return(JS_TRUE); ! 2462: } ! 2463: ! 2464: static JSBool ! 2465: js_fcopy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2466: { ! 2467: char* src; ! 2468: char* dest; ! 2469: ! 2470: if(JSVAL_IS_VOID(argv[0])) ! 2471: return(JS_TRUE); ! 2472: ! 2473: *rval = BOOLEAN_TO_JSVAL(JS_FALSE); ! 2474: if((src=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2475: return(JS_TRUE); ! 2476: if((dest=js_ValueToStringBytes(cx, argv[1], NULL))==NULL) ! 2477: return(JS_TRUE); ! 2478: ! 2479: *rval = BOOLEAN_TO_JSVAL(fcopy(src,dest)); ! 2480: return(JS_TRUE); ! 2481: } ! 2482: ! 2483: static JSBool ! 2484: js_fcompare(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2485: { ! 2486: char* fn1; ! 2487: char* fn2; ! 2488: ! 2489: if(JSVAL_IS_VOID(argv[0])) ! 2490: return(JS_TRUE); ! 2491: ! 2492: *rval = BOOLEAN_TO_JSVAL(JS_FALSE); ! 2493: if((fn1=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2494: return(JS_TRUE); ! 2495: if((fn2=js_ValueToStringBytes(cx, argv[1], NULL))==NULL) ! 2496: return(JS_TRUE); ! 2497: ! 2498: *rval = BOOLEAN_TO_JSVAL(fcompare(fn1,fn2)); ! 2499: return(JS_TRUE); ! 2500: } ! 2501: ! 2502: static JSBool ! 2503: js_backup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2504: { ! 2505: char* fname; ! 2506: int32 level=5; ! 2507: BOOL ren=FALSE; ! 2508: ! 2509: if(JSVAL_IS_VOID(argv[0])) ! 2510: return(JS_TRUE); ! 2511: ! 2512: *rval = BOOLEAN_TO_JSVAL(JS_FALSE); ! 2513: if((fname=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2514: return(JS_TRUE); ! 2515: ! 2516: if(argc>1) ! 2517: JS_ValueToInt32(cx,argv[1],&level); ! 2518: if(argc>2) ! 2519: JS_ValueToBoolean(cx,argv[2],&ren); ! 2520: ! 2521: *rval = BOOLEAN_TO_JSVAL(backup(fname,level,ren)); ! 2522: return(JS_TRUE); ! 2523: } ! 2524: ! 2525: static JSBool ! 2526: js_isdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2527: { ! 2528: char* p; ! 2529: ! 2530: if(JSVAL_IS_VOID(argv[0])) ! 2531: return(JS_TRUE); ! 2532: ! 2533: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2534: return(JS_FALSE); ! 2535: ! 2536: *rval = BOOLEAN_TO_JSVAL(isdir(p)); ! 2537: return(JS_TRUE); ! 2538: } ! 2539: ! 2540: static JSBool ! 2541: js_fattr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2542: { ! 2543: char* p; ! 2544: ! 2545: if(JSVAL_IS_VOID(argv[0])) ! 2546: return(JS_TRUE); ! 2547: ! 2548: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2549: return(JS_FALSE); ! 2550: ! 2551: JS_NewNumberValue(cx,getfattr(p),rval); ! 2552: return(JS_TRUE); ! 2553: } ! 2554: ! 2555: static JSBool ! 2556: js_fdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2557: { ! 2558: char* p; ! 2559: ! 2560: if(JSVAL_IS_VOID(argv[0])) ! 2561: return(JS_TRUE); ! 2562: ! 2563: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2564: return(JS_FALSE); ! 2565: ! 2566: JS_NewNumberValue(cx,fdate(p),rval); ! 2567: return(JS_TRUE); ! 2568: } ! 2569: ! 2570: static JSBool ! 2571: js_utime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2572: { ! 2573: char* fname; ! 2574: int32 actime; ! 2575: int32 modtime; ! 2576: struct utimbuf tbuf; ! 2577: struct utimbuf* t=NULL; ! 2578: ! 2579: if(JSVAL_IS_VOID(argv[0])) ! 2580: return(JS_TRUE); ! 2581: ! 2582: *rval = JSVAL_FALSE; ! 2583: ! 2584: if((fname=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2585: return(JS_FALSE); ! 2586: ! 2587: if(argc>1) { ! 2588: memset(&tbuf,0,sizeof(tbuf)); ! 2589: actime=modtime=time(NULL); ! 2590: JS_ValueToInt32(cx,argv[1],&actime); ! 2591: JS_ValueToInt32(cx,argv[2],&modtime); ! 2592: tbuf.actime=actime; ! 2593: tbuf.modtime=modtime; ! 2594: t=&tbuf; ! 2595: } ! 2596: ! 2597: *rval = BOOLEAN_TO_JSVAL(utime(fname,t)==0); ! 2598: ! 2599: return(JS_TRUE); ! 2600: } ! 2601: ! 2602: ! 2603: static JSBool ! 2604: js_flength(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2605: { ! 2606: char* p; ! 2607: ! 2608: if(JSVAL_IS_VOID(argv[0])) ! 2609: return(JS_TRUE); ! 2610: ! 2611: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2612: return(JS_FALSE); ! 2613: ! 2614: JS_NewNumberValue(cx,flength(p),rval); ! 2615: return(JS_TRUE); ! 2616: } ! 2617: ! 2618: ! 2619: static JSBool ! 2620: js_ftouch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2621: { ! 2622: char* fname; ! 2623: ! 2624: if(JSVAL_IS_VOID(argv[0])) ! 2625: return(JS_TRUE); ! 2626: ! 2627: if((fname=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2628: return(JS_FALSE); ! 2629: ! 2630: *rval = BOOLEAN_TO_JSVAL(ftouch(fname)); ! 2631: return(JS_TRUE); ! 2632: } ! 2633: ! 2634: static JSBool ! 2635: js_fmutex(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2636: { ! 2637: char* fname; ! 2638: char* text=NULL; ! 2639: int32 max_age=0; ! 2640: uintN argn=0; ! 2641: ! 2642: if(JSVAL_IS_VOID(argv[0])) ! 2643: return(JS_TRUE); ! 2644: ! 2645: if((fname=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL) ! 2646: return(JS_FALSE); ! 2647: if(argc > argn && JSVAL_IS_STRING(argv[argn])) ! 2648: text=js_ValueToStringBytes(cx, argv[argn++], NULL); ! 2649: if(argc > argn && JSVAL_IS_NUMBER(argv[argn])) ! 2650: JS_ValueToInt32(cx, argv[argn++], &max_age); ! 2651: ! 2652: *rval = BOOLEAN_TO_JSVAL(fmutex(fname,text,max_age)); ! 2653: return(JS_TRUE); ! 2654: } ! 2655: ! 2656: static JSBool ! 2657: js_sound(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2658: { ! 2659: char* p; ! 2660: ! 2661: if(!argc) { /* Stop playing sound */ ! 2662: #ifdef _WIN32 ! 2663: PlaySound(NULL,NULL,0); ! 2664: #endif ! 2665: *rval = BOOLEAN_TO_JSVAL(JS_TRUE); ! 2666: return(JS_TRUE); ! 2667: } ! 2668: ! 2669: if(JSVAL_IS_VOID(argv[0])) ! 2670: return(JS_TRUE); ! 2671: ! 2672: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2673: return(JS_FALSE); ! 2674: ! 2675: #ifdef _WIN32 ! 2676: *rval = BOOLEAN_TO_JSVAL(PlaySound(p, NULL, SND_ASYNC|SND_FILENAME)); ! 2677: #else ! 2678: *rval = BOOLEAN_TO_JSVAL(JS_FALSE); ! 2679: #endif ! 2680: ! 2681: return(JS_TRUE); ! 2682: } ! 2683: ! 2684: static JSBool ! 2685: js_directory(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2686: { ! 2687: int i; ! 2688: int32 flags=GLOB_MARK; ! 2689: char* p; ! 2690: glob_t g; ! 2691: JSObject* array; ! 2692: JSString* js_str; ! 2693: jsint len=0; ! 2694: jsval val; ! 2695: ! 2696: if(JSVAL_IS_VOID(argv[0])) ! 2697: return(JS_TRUE); ! 2698: ! 2699: *rval = JSVAL_NULL; ! 2700: ! 2701: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2702: return(JS_FALSE); ! 2703: ! 2704: if(argc>1) ! 2705: JS_ValueToInt32(cx,argv[1],&flags); ! 2706: ! 2707: if((array = JS_NewArrayObject(cx, 0, NULL))==NULL) ! 2708: return(JS_FALSE); ! 2709: ! 2710: glob(p,flags,NULL,&g); ! 2711: for(i=0;i<(int)g.gl_pathc;i++) { ! 2712: if((js_str=JS_NewStringCopyZ(cx,g.gl_pathv[i]))==NULL) ! 2713: break; ! 2714: val=STRING_TO_JSVAL(js_str); ! 2715: if(!JS_SetElement(cx, array, len++, &val)) ! 2716: break; ! 2717: } ! 2718: globfree(&g); ! 2719: ! 2720: *rval = OBJECT_TO_JSVAL(array); ! 2721: ! 2722: return(JS_TRUE); ! 2723: } ! 2724: ! 2725: static JSBool ! 2726: js_wildmatch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2727: { ! 2728: BOOL case_sensitive=FALSE; ! 2729: BOOL path=FALSE; ! 2730: char* fname; ! 2731: char* spec="*"; ! 2732: uintN argn=0; ! 2733: ! 2734: if(JSVAL_IS_BOOLEAN(argv[argn])) ! 2735: JS_ValueToBoolean(cx, argv[argn++], &case_sensitive); ! 2736: ! 2737: if((fname=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL) ! 2738: return(JS_FALSE); ! 2739: ! 2740: if(argn<argc && argv[argn]!=JSVAL_VOID) ! 2741: if((spec=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL) ! 2742: return(JS_FALSE); ! 2743: ! 2744: if(argn<argc && argv[argn]!=JSVAL_VOID) ! 2745: JS_ValueToBoolean(cx, argv[argn++], &path); ! 2746: ! 2747: if(case_sensitive) ! 2748: *rval = BOOLEAN_TO_JSVAL(wildmatch(fname, spec, path)); ! 2749: else ! 2750: *rval = BOOLEAN_TO_JSVAL(wildmatchi(fname, spec, path)); ! 2751: ! 2752: return(JS_TRUE); ! 2753: } ! 2754: ! 2755: ! 2756: static JSBool ! 2757: js_freediskspace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2758: { ! 2759: int32 unit=0; ! 2760: char* p; ! 2761: ! 2762: if(JSVAL_IS_VOID(argv[0])) ! 2763: return(JS_TRUE); ! 2764: ! 2765: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2766: return(JS_FALSE); ! 2767: ! 2768: if(argc>1) ! 2769: JS_ValueToInt32(cx,argv[1],&unit); ! 2770: ! 2771: JS_NewNumberValue(cx,getfreediskspace(p,unit),rval); ! 2772: ! 2773: return(JS_TRUE); ! 2774: } ! 2775: ! 2776: static JSBool ! 2777: js_disksize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2778: { ! 2779: int32 unit=0; ! 2780: char* p; ! 2781: ! 2782: if(JSVAL_IS_VOID(argv[0])) ! 2783: return(JS_TRUE); ! 2784: ! 2785: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2786: return(JS_FALSE); ! 2787: ! 2788: if(argc>1) ! 2789: JS_ValueToInt32(cx,argv[1],&unit); ! 2790: ! 2791: JS_NewNumberValue(cx,getdisksize(p,unit),rval); ! 2792: ! 2793: return(JS_TRUE); ! 2794: } ! 2795: ! 2796: ! 2797: static JSBool ! 2798: js_socket_select(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2799: { ! 2800: JSObject* inarray=NULL; ! 2801: JSObject* rarray; ! 2802: BOOL poll_for_write=FALSE; ! 2803: fd_set socket_set; ! 2804: fd_set* rd_set=NULL; ! 2805: fd_set* wr_set=NULL; ! 2806: uintN argn; ! 2807: SOCKET sock; ! 2808: SOCKET maxsock=0; ! 2809: struct timeval tv = {0, 0}; ! 2810: jsuint i; ! 2811: jsuint limit; ! 2812: SOCKET* index; ! 2813: jsval val; ! 2814: int len=0; ! 2815: ! 2816: *rval = JSVAL_NULL; ! 2817: ! 2818: for(argn=0;argn<argc;argn++) { ! 2819: if(JSVAL_IS_BOOLEAN(argv[argn])) ! 2820: poll_for_write=JSVAL_TO_BOOLEAN(argv[argn]); ! 2821: else if(JSVAL_IS_OBJECT(argv[argn])) ! 2822: inarray = JSVAL_TO_OBJECT(argv[argn]); ! 2823: else if(JSVAL_IS_NUMBER(argv[argn])) ! 2824: js_timeval(cx,argv[argn],&tv); ! 2825: } ! 2826: ! 2827: if(inarray==NULL || !JS_IsArrayObject(cx, inarray)) ! 2828: return(JS_TRUE); /* This not a fatal error */ ! 2829: ! 2830: if(!JS_GetArrayLength(cx, inarray, &limit)) ! 2831: return(JS_TRUE); ! 2832: ! 2833: /* Return array */ ! 2834: if((rarray = JS_NewArrayObject(cx, 0, NULL))==NULL) ! 2835: return(JS_FALSE); ! 2836: ! 2837: if((index=(SOCKET *)alloca(sizeof(SOCKET)*limit))==NULL) ! 2838: return(JS_FALSE); ! 2839: ! 2840: FD_ZERO(&socket_set); ! 2841: if(poll_for_write) ! 2842: wr_set=&socket_set; ! 2843: else ! 2844: rd_set=&socket_set; ! 2845: ! 2846: for(i=0;i<limit;i++) { ! 2847: if(!JS_GetElement(cx, inarray, i, &val)) ! 2848: break; ! 2849: sock=js_socket(cx,val); ! 2850: index[i]=sock; ! 2851: if(sock!=INVALID_SOCKET) { ! 2852: FD_SET(sock,&socket_set); ! 2853: if(sock>maxsock) ! 2854: maxsock=sock; ! 2855: } ! 2856: } ! 2857: ! 2858: if(select(maxsock+1,rd_set,wr_set,NULL,&tv)<0) ! 2859: lprintf(LOG_DEBUG,"Error in socket_select() %s (%d)",strerror(errno),errno); ! 2860: ! 2861: for(i=0;i<limit;i++) { ! 2862: if(index[i]!=INVALID_SOCKET && FD_ISSET(index[i],&socket_set)) { ! 2863: val=INT_TO_JSVAL(i); ! 2864: if(!JS_SetElement(cx, rarray, len++, &val)) ! 2865: break; ! 2866: } ! 2867: } ! 2868: ! 2869: *rval = OBJECT_TO_JSVAL(rarray); ! 2870: ! 2871: return(JS_TRUE); ! 2872: } ! 2873: ! 2874: static JSBool ! 2875: js_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2876: { ! 2877: char* p; ! 2878: ! 2879: if(JSVAL_IS_VOID(argv[0])) ! 2880: return(JS_TRUE); ! 2881: ! 2882: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2883: return(JS_FALSE); ! 2884: ! 2885: *rval = BOOLEAN_TO_JSVAL(MKDIR(p)==0); ! 2886: return(JS_TRUE); ! 2887: } ! 2888: ! 2889: static JSBool ! 2890: js_rmdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2891: { ! 2892: char* p; ! 2893: ! 2894: if(JSVAL_IS_VOID(argv[0])) ! 2895: return(JS_TRUE); ! 2896: ! 2897: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2898: return(JS_FALSE); ! 2899: ! 2900: *rval = BOOLEAN_TO_JSVAL(rmdir(p)==0); ! 2901: return(JS_TRUE); ! 2902: } ! 2903: ! 2904: ! 2905: static JSBool ! 2906: js_strftime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2907: { ! 2908: char str[128]; ! 2909: char* fmt; ! 2910: int32 i=time(NULL); ! 2911: time_t t; ! 2912: struct tm tm; ! 2913: JSString* js_str; ! 2914: ! 2915: if(JSVAL_IS_VOID(argv[0])) ! 2916: return(JS_TRUE); ! 2917: ! 2918: if((fmt=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2919: return(JS_FALSE); ! 2920: ! 2921: if(argc>1) ! 2922: JS_ValueToInt32(cx,argv[1],&i); ! 2923: ! 2924: strcpy(str,"-Invalid time-"); ! 2925: t=i; ! 2926: if(localtime_r(&t,&tm)==NULL) ! 2927: memset(&tm,0,sizeof(tm)); ! 2928: strftime(str,sizeof(str),fmt,&tm); ! 2929: ! 2930: if((js_str=JS_NewStringCopyZ(cx, str))==NULL) ! 2931: return(JS_FALSE); ! 2932: ! 2933: *rval = STRING_TO_JSVAL(js_str); ! 2934: return(JS_TRUE); ! 2935: } ! 2936: ! 2937: static JSBool ! 2938: js_resolve_ip(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2939: { ! 2940: struct in_addr addr; ! 2941: JSString* str; ! 2942: char* p; ! 2943: ! 2944: *rval = JSVAL_NULL; ! 2945: ! 2946: if(JSVAL_IS_VOID(argv[0])) ! 2947: return(JS_TRUE); ! 2948: ! 2949: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2950: return(JS_FALSE); ! 2951: ! 2952: if((addr.s_addr=resolve_ip(p))==INADDR_NONE) ! 2953: return(JS_TRUE); ! 2954: ! 2955: if((str=JS_NewStringCopyZ(cx, inet_ntoa(addr)))==NULL) ! 2956: return(JS_FALSE); ! 2957: ! 2958: *rval = STRING_TO_JSVAL(str); ! 2959: return(JS_TRUE); ! 2960: } ! 2961: ! 2962: ! 2963: static JSBool ! 2964: js_resolve_host(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2965: { ! 2966: struct in_addr addr; ! 2967: HOSTENT* h; ! 2968: char* p; ! 2969: ! 2970: *rval = JSVAL_NULL; ! 2971: ! 2972: if(JSVAL_IS_VOID(argv[0])) ! 2973: return(JS_TRUE); ! 2974: ! 2975: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL) ! 2976: return(JS_FALSE); ! 2977: ! 2978: addr.s_addr=inet_addr(p); ! 2979: h=gethostbyaddr((char *)&addr,sizeof(addr),AF_INET); ! 2980: ! 2981: if(h!=NULL && h->h_name!=NULL) ! 2982: *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,h->h_name)); ! 2983: ! 2984: return(JS_TRUE); ! 2985: ! 2986: } ! 2987: ! 2988: extern link_list_t named_queues; /* js_queue.c */ ! 2989: ! 2990: static JSBool ! 2991: js_list_named_queues(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 2992: { ! 2993: JSObject* array; ! 2994: jsint len=0; ! 2995: jsval val; ! 2996: list_node_t* node; ! 2997: msg_queue_t* q; ! 2998: ! 2999: if((array = JS_NewArrayObject(cx, 0, NULL))==NULL) ! 3000: return(JS_FALSE); ! 3001: ! 3002: for(node=listFirstNode(&named_queues);node!=NULL;node=listNextNode(node)) { ! 3003: if((q=listNodeData(node))==NULL) ! 3004: continue; ! 3005: val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,q->name)); ! 3006: if(!JS_SetElement(cx, array, len++, &val)) ! 3007: break; ! 3008: } ! 3009: ! 3010: *rval = OBJECT_TO_JSVAL(array); ! 3011: ! 3012: return(JS_TRUE); ! 3013: } ! 3014: ! 3015: static JSBool ! 3016: js_flags_str(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 3017: { ! 3018: char* p; ! 3019: char str[64]; ! 3020: jsdouble d; ! 3021: JSString* js_str; ! 3022: ! 3023: if(JSVAL_IS_VOID(argv[0])) ! 3024: return(JS_TRUE); ! 3025: ! 3026: if(JSVAL_IS_STRING(argv[0])) { /* string to long */ ! 3027: ! 3028: if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL) ! 3029: return(JS_FALSE); ! 3030: ! 3031: JS_NewNumberValue(cx,aftol(p),rval); ! 3032: return(JS_TRUE); ! 3033: } ! 3034: ! 3035: /* number to string */ ! 3036: JS_ValueToNumber(cx,argv[0],&d); ! 3037: ! 3038: if((js_str = JS_NewStringCopyZ(cx, ltoaf((long)d,str)))==NULL) ! 3039: return(JS_FALSE); ! 3040: ! 3041: *rval = STRING_TO_JSVAL(js_str); ! 3042: return(JS_TRUE); ! 3043: } ! 3044: ! 3045: static JSClass js_global_class = { ! 3046: "Global" /* name */ ! 3047: ,JSCLASS_HAS_PRIVATE /* flags */ ! 3048: ,JS_PropertyStub /* addProperty */ ! 3049: ,JS_PropertyStub /* delProperty */ ! 3050: ,js_system_get /* getProperty */ ! 3051: ,JS_PropertyStub /* setProperty */ ! 3052: ,JS_EnumerateStub /* enumerate */ ! 3053: ,JS_ResolveStub /* resolve */ ! 3054: ,JS_ConvertStub /* convert */ ! 3055: ,JS_FinalizeStub /* finalize */ ! 3056: }; ! 3057: ! 3058: static jsSyncMethodSpec js_global_functions[] = { ! 3059: {"exit", js_exit, 0, JSTYPE_VOID, "[exit_code]" ! 3060: ,JSDOCSTR("stop script execution, " ! 3061: "optionally setting the global property <tt>exit_code</tt> to the specified numeric value") ! 3062: ,311 ! 3063: }, ! 3064: {"load", js_load, 1, JSTYPE_UNDEF ! 3065: ,JSDOCSTR("[<i>bool</i> background or <i>object</i> scope,] <i>string</i> filename [,args]") ! 3066: ,JSDOCSTR("load and execute a JavaScript module (<i>filename</i>), " ! 3067: "optionally specifying a target <i>scope</i> object (default: <i>this</i>) " ! 3068: "and a list of arguments to pass to the module (as <i>argv</i>). " ! 3069: "Returns the result (last executed statement) of the executed script " ! 3070: "or a newly created <i>Queue</i> object if <i>background</i> is <i>true</i>).<br><br>" ! 3071: "<b>Background</b> (added in v3.12):<br>" ! 3072: "If <i>background</i> is <i>true</i>, the loaded script runs in the background " ! 3073: "(in a child thread) but may communicate with the parent " ! 3074: "script/thread by reading from and/or writing to the <i>parent_queue</i> " ! 3075: "(an automatically created <i>Queue</i> object). " ! 3076: "The result (last executed statement) of the executed script " ! 3077: "(or the optional <i>exit_code</i> passed to the <i>exit()/<i> function) " ! 3078: "will be automatically written to the <i>parent_queue</i> " ! 3079: "which may be read later by the parent script (using <i>load_result.read()</i>, for example).") ! 3080: ,312 ! 3081: }, ! 3082: {"sleep", js_mswait, 0, JSTYPE_ALIAS }, ! 3083: {"mswait", js_mswait, 0, JSTYPE_NUMBER, JSDOCSTR("[milliseconds=<tt>1</tt>]") ! 3084: ,JSDOCSTR("millisecond wait/sleep routine (AKA sleep), returns number of elapsed clock ticks (in v3.13)") ! 3085: ,313 ! 3086: }, ! 3087: {"yield", js_yield, 0, JSTYPE_VOID, JSDOCSTR("[forced=<tt>true</tt>]") ! 3088: ,JSDOCSTR("release current thread time-slice, " ! 3089: "a <i>forced</i> yield will yield to all other pending tasks (lowering CPU utilization), " ! 3090: "a non-<i>forced</i> yield will yield only to pending tasks of equal or higher priority. " ! 3091: "<i>forced</i> defaults to <i>true</i>") ! 3092: ,311 ! 3093: }, ! 3094: {"random", js_random, 1, JSTYPE_NUMBER, JSDOCSTR("max_number=<tt>100</tt>") ! 3095: ,JSDOCSTR("return random integer between <tt>0</tt> and <i>max_number</i>-1") ! 3096: ,310 ! 3097: }, ! 3098: {"time", js_time, 0, JSTYPE_NUMBER, "" ! 3099: ,JSDOCSTR("return current time and date in Unix (time_t) format " ! 3100: "(number of seconds since Jan-01-1970)") ! 3101: ,310 ! 3102: }, ! 3103: {"beep", js_beep, 0, JSTYPE_VOID, JSDOCSTR("[frequency=<tt>500</tt>] [,duration=<tt>500</tt>]") ! 3104: ,JSDOCSTR("produce a tone on the local speaker at specified frequency for specified duration (in milliseconds)") ! 3105: ,310 ! 3106: }, ! 3107: {"sound", js_sound, 0, JSTYPE_BOOLEAN, JSDOCSTR("[filename]") ! 3108: ,JSDOCSTR("play a waveform (.wav) sound file (currently, on Windows platforms only)") ! 3109: ,310 ! 3110: }, ! 3111: {"ctrl", js_ctrl, 1, JSTYPE_STRING, JSDOCSTR("number or string") ! 3112: ,JSDOCSTR("return ASCII control character representing character passed - Example: <tt>ctrl('C') returns '\3'</tt>") ! 3113: ,311 ! 3114: }, ! 3115: {"ascii", js_ascii, 1, JSTYPE_UNDEF, JSDOCSTR("[string text] or [number value]") ! 3116: ,JSDOCSTR("convert single character to numeric ASCII value or vice-versa (returns number OR string)") ! 3117: ,310 ! 3118: }, ! 3119: {"ascii_str", js_ascii_str, 1, JSTYPE_STRING, JSDOCSTR("text") ! 3120: ,JSDOCSTR("convert extended-ASCII in text string to plain ASCII, returns modified string") ! 3121: ,310 ! 3122: }, ! 3123: {"strip_ctrl", js_strip_ctrl, 1, JSTYPE_STRING, JSDOCSTR("text") ! 3124: ,JSDOCSTR("strip control characters from string, returns modified string") ! 3125: ,310 ! 3126: }, ! 3127: {"strip_exascii", js_strip_exascii, 1, JSTYPE_STRING, JSDOCSTR("text") ! 3128: ,JSDOCSTR("strip extended-ASCII characters from string, returns modified string") ! 3129: ,310 ! 3130: }, ! 3131: {"truncsp", js_truncsp, 1, JSTYPE_STRING, JSDOCSTR("text") ! 3132: ,JSDOCSTR("truncate (trim) white-space characters off end of string, returns modified string") ! 3133: ,310 ! 3134: }, ! 3135: {"truncstr", js_truncstr, 2, JSTYPE_STRING, JSDOCSTR("text, charset") ! 3136: ,JSDOCSTR("truncate (trim) string at first char in <i>charset</i>, returns modified string") ! 3137: ,310 ! 3138: }, ! 3139: {"lfexpand", js_lfexpand, 1, JSTYPE_STRING, JSDOCSTR("text") ! 3140: ,JSDOCSTR("expand line-feeds (LF) to carriage-return/line-feeds (CRLF), returns modified string") ! 3141: ,310 ! 3142: }, ! 3143: {"wildmatch", js_wildmatch, 2, JSTYPE_BOOLEAN, JSDOCSTR("[case_sensitive=<tt>false</tt>,] string [,pattern=<tt>'*'</tt>] [,path=<tt>false</tt>]") ! 3144: ,JSDOCSTR("returns <tt>true</tt> if the <i>string</i> matches the wildcard <i>pattern</i> (wildcards supported are '*' and '?'), " ! 3145: "if <i>path</i> is <tt>true</tt>, '*' will not match path delimeter characters (e.g. '/')") ! 3146: ,314 ! 3147: }, ! 3148: {"backslash", js_backslash, 1, JSTYPE_STRING, JSDOCSTR("path") ! 3149: ,JSDOCSTR("returns directory path with trailing (platform-specific) path delimeter " ! 3150: "(i.e. \"slash\" or \"backslash\")") ! 3151: ,312 ! 3152: }, ! 3153: {"file_getname", js_getfname, 1, JSTYPE_STRING, JSDOCSTR("path/filename") ! 3154: ,JSDOCSTR("returns filename portion of passed path string") ! 3155: ,311 ! 3156: }, ! 3157: {"file_getext", js_getfext, 1, JSTYPE_STRING, JSDOCSTR("path/filename") ! 3158: ,JSDOCSTR("returns file extension portion of passed path/filename string (including '.') " ! 3159: "or <i>undefined</i> if no extension is found") ! 3160: ,311 ! 3161: }, ! 3162: {"file_getcase", js_getfcase, 1, JSTYPE_STRING, JSDOCSTR("path/filename") ! 3163: ,JSDOCSTR("returns correct case of filename (long version of filename on Win32) " ! 3164: "or <i>undefined</i> if the file doesn't exist") ! 3165: ,311 ! 3166: }, ! 3167: {"file_cfgname", js_cfgfname, 2, JSTYPE_STRING, JSDOCSTR("path, filename") ! 3168: ,JSDOCSTR("returns completed configuration filename from supplied <i>path</i> and <i>filename</i>, " ! 3169: "optionally including the local hostname (e.g. <tt>path/file.<i>host</i>.<i>domain</i>.ext</tt> " ! 3170: "or <tt>path/file.<i>host</i>.ext</tt>) if such a variation of the filename exists") ! 3171: ,312 ! 3172: }, ! 3173: {"file_exists", js_fexist, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename") ! 3174: ,JSDOCSTR("verify a file's existence") ! 3175: ,310 ! 3176: }, ! 3177: {"file_remove", js_remove, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename") ! 3178: ,JSDOCSTR("delete a file") ! 3179: ,310 ! 3180: }, ! 3181: {"file_removecase", js_removecase, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename") ! 3182: ,JSDOCSTR("delete files case insensitively") ! 3183: ,314 ! 3184: }, ! 3185: {"file_rename", js_rename, 2, JSTYPE_BOOLEAN, JSDOCSTR("path/oldname, path/newname") ! 3186: ,JSDOCSTR("rename a file, possibly moving it to another directory in the process") ! 3187: ,311 ! 3188: }, ! 3189: {"file_copy", js_fcopy, 2, JSTYPE_BOOLEAN, JSDOCSTR("path/source, path/destination") ! 3190: ,JSDOCSTR("copy a file from one directory or filename to another") ! 3191: ,311 ! 3192: }, ! 3193: {"file_backup", js_backup, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename [,level=<tt>5</tt>] [,rename=<tt>false</tt>]") ! 3194: ,JSDOCSTR("backup the specified <i>filename</i> as <tt>filename.<i>number</i>.extension</tt> " ! 3195: "where <i>number</i> is the backup number 0 through <i>level</i>-1 " ! 3196: "(default backup <i>level</i> is 5), " ! 3197: "if <i>rename</i> is <i>true</i>, the original file is renamed instead of copied " ! 3198: "(default is <i>false</i>)") ! 3199: ,311 ! 3200: }, ! 3201: {"file_isdir", js_isdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename") ! 3202: ,JSDOCSTR("check if specified <i>filename</i> is a directory") ! 3203: ,310 ! 3204: }, ! 3205: {"file_attrib", js_fattr, 1, JSTYPE_NUMBER, JSDOCSTR("path/filename") ! 3206: ,JSDOCSTR("get a file's permissions/attributes") ! 3207: ,310 ! 3208: }, ! 3209: {"file_date", js_fdate, 1, JSTYPE_NUMBER, JSDOCSTR("path/filename") ! 3210: ,JSDOCSTR("get a file's last modified date/time (in time_t format)") ! 3211: ,310 ! 3212: }, ! 3213: {"file_size", js_flength, 1, JSTYPE_NUMBER, JSDOCSTR("path/filename") ! 3214: ,JSDOCSTR("get a file's length (in bytes)") ! 3215: ,310 ! 3216: }, ! 3217: {"file_utime", js_utime, 3, JSTYPE_BOOLEAN, JSDOCSTR("path/filename [,access_time=<i>current</i>] [,mod_time=<i>current</i>]") ! 3218: ,JSDOCSTR("change a file's last accessed and modification date/time (in time_t format), " ! 3219: "or change to current time") ! 3220: ,311 ! 3221: }, ! 3222: {"file_touch", js_ftouch, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename") ! 3223: ,JSDOCSTR("updates a file's last modification date/time to current time, " ! 3224: "creating an empty file if it doesn't already exist") ! 3225: ,311 ! 3226: }, ! 3227: {"file_mutex", js_fmutex, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename [,text=<i>local_hostname</i>] [,max_age=<tt>0</tt>]") ! 3228: ,JSDOCSTR("attempts to create an mutual-exclusion (e.g. lock) file, " ! 3229: "optionally with the contents of <i>text</i>. " ! 3230: "If a non-zero <i>max_age</i> (supported in v3.13b+) is specified " ! 3231: "and the lock file exists, but is older than this value (in seconds), " ! 3232: "it is presumed stale and removed/over-written") ! 3233: ,312 ! 3234: }, ! 3235: {"file_compare", js_fcompare, 2, JSTYPE_BOOLEAN, JSDOCSTR("path/file1, path/file2") ! 3236: ,JSDOCSTR("compare 2 files, returning <i>true</i> if they are identical, <i>false</i> otherwise") ! 3237: ,314 ! 3238: }, ! 3239: {"directory", js_directory, 1, JSTYPE_ARRAY, JSDOCSTR("path/pattern [,flags=<tt>GLOB_MARK</tt>]") ! 3240: ,JSDOCSTR("returns an array of directory entries, " ! 3241: "<i>pattern</i> is the path and filename or wildcards to search for (e.g. '/subdir/*.txt'), " ! 3242: "<i>flags</i> is a bitfield of optional <tt>glob</tt> flags (default is <tt>GLOB_MARK</tt>)") ! 3243: ,310 ! 3244: }, ! 3245: {"dir_freespace", js_freediskspace, 2, JSTYPE_NUMBER, JSDOCSTR("directory [,unit_size=<tt>1</tt>]") ! 3246: ,JSDOCSTR("returns the amount of available disk space in the specified <i>directory</i> " ! 3247: "using the specified <i>unit_size</i> in bytes (default: 1), " ! 3248: "specify a <i>unit_size</i> of <tt>1024</tt> to return the available space in <i>kilobytes</i>.") ! 3249: ,311 ! 3250: }, ! 3251: {"disk_size", js_disksize, 2, JSTYPE_NUMBER, JSDOCSTR("directory [,unit_size=<tt>1</tt>]") ! 3252: ,JSDOCSTR("returns the total disk size of the specified <i>directory</i> " ! 3253: "using the specified <i>unit_size</i> in bytes (default: 1), " ! 3254: "specify a <i>unit_size</i> of <tt>1024</tt> to return the total disk size in <i>kilobytes</i>.") ! 3255: ,314 ! 3256: }, ! 3257: {"socket_select", js_socket_select, 0, JSTYPE_ARRAY, JSDOCSTR("[array of socket objects or descriptors] [,timeout=<tt>0</tt>] [,write=<tt>false</tt>]") ! 3258: ,JSDOCSTR("checks an array of socket objects or descriptors for read or write ability (default is <i>read</i>), " ! 3259: "default timeout value is 0.0 seconds (immediate timeout), " ! 3260: "returns an array of 0-based index values into the socket array, representing the sockets that were ready for reading or writing") ! 3261: ,311 ! 3262: }, ! 3263: {"mkdir", js_mkdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/directory") ! 3264: ,JSDOCSTR("make a directory") ! 3265: ,310 ! 3266: }, ! 3267: {"rmdir", js_rmdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/directory") ! 3268: ,JSDOCSTR("remove a directory") ! 3269: ,310 ! 3270: }, ! 3271: {"strftime", js_strftime, 1, JSTYPE_STRING, JSDOCSTR("format [,time=<i>current</i>]") ! 3272: ,JSDOCSTR("return a formatted time string (ala C strftime)") ! 3273: ,310 ! 3274: }, ! 3275: {"format", js_format, 1, JSTYPE_STRING, JSDOCSTR("format [,args]") ! 3276: ,JSDOCSTR("return a formatted string (ala the standard C <tt>sprintf</tt> function)") ! 3277: ,310 ! 3278: }, ! 3279: {"html_encode", js_html_encode, 1, JSTYPE_STRING, JSDOCSTR("text [,ex_ascii=<tt>true</tt>] [,white_space=<tt>true</tt>] [,ansi=<tt>true</tt>] [,ctrl_a=<tt>true</tt>] [, state (object)]") ! 3280: ,JSDOCSTR("return an HTML-encoded text string (using standard HTML character entities), " ! 3281: "escaping IBM extended-ASCII, white-space characters, ANSI codes, and CTRL-A codes by default." ! 3282: "Optionally storing the current ANSI state in <i>state</i> object") ! 3283: ,311 ! 3284: }, ! 3285: {"html_decode", js_html_decode, 1, JSTYPE_STRING, JSDOCSTR("html") ! 3286: ,JSDOCSTR("return a decoded HTML-encoded text string") ! 3287: ,311 ! 3288: }, ! 3289: {"word_wrap", js_word_wrap, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=<tt>79</tt> [, orig_line_length=<tt>79</tt> [, handle_quotes=<tt>true</tt>]]]]") ! 3290: ,JSDOCSTR("returns a word-wrapped version of the text string argument optionally handing quotes magically, " ! 3291: "<i>line_length</i> defaults to <i>79</i> <i>orig_line_length</i> defaults to <i>79</i> " ! 3292: "and <i>handle_quotes</i> defaults to <i>true</i>") ! 3293: ,311 ! 3294: }, ! 3295: {"quote_msg", js_quote_msg, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=<tt>79</tt>] [,prefix=<tt>\" > \"</tt>]") ! 3296: ,JSDOCSTR("returns a quoted version of the message text string argument, <i>line_length</i> defaults to <i>79</i>, " ! 3297: "<i>prefix</i> defaults to <tt>\" > \"</tt>") ! 3298: ,311 ! 3299: }, ! 3300: {"rot13_translate", js_rot13, 1, JSTYPE_STRING, JSDOCSTR("text") ! 3301: ,JSDOCSTR("returns ROT13-translated version of text string (will encode or decode text)") ! 3302: ,311 ! 3303: }, ! 3304: {"base64_encode", js_b64_encode, 1, JSTYPE_STRING, JSDOCSTR("text") ! 3305: ,JSDOCSTR("returns base64-encoded version of text string or <i>null</i> on error") ! 3306: ,311 ! 3307: }, ! 3308: {"base64_decode", js_b64_decode, 1, JSTYPE_STRING, JSDOCSTR("text") ! 3309: ,JSDOCSTR("returns base64-decoded text string or <i>null</i> on error") ! 3310: ,311 ! 3311: }, ! 3312: {"crc16_calc", js_crc16, 1, JSTYPE_NUMBER, JSDOCSTR("text") ! 3313: ,JSDOCSTR("calculate and return 16-bit CRC of text string") ! 3314: ,311 ! 3315: }, ! 3316: {"crc32_calc", js_crc32, 1, JSTYPE_NUMBER, JSDOCSTR("text") ! 3317: ,JSDOCSTR("calculate and return 32-bit CRC of text string") ! 3318: ,311 ! 3319: }, ! 3320: {"chksum_calc", js_chksum, 1, JSTYPE_NUMBER, JSDOCSTR("text") ! 3321: ,JSDOCSTR("calculate and return 32-bit checksum of text string") ! 3322: ,311 ! 3323: }, ! 3324: {"md5_calc", js_md5_calc, 1, JSTYPE_STRING, JSDOCSTR("text [,hex=<tt>false</tt>]") ! 3325: ,JSDOCSTR("calculate and return 128-bit MD5 digest of text string, result encoded in base64 (default) or hexadecimal") ! 3326: ,311 ! 3327: }, ! 3328: {"gethostbyname", js_resolve_ip, 1, JSTYPE_ALIAS }, ! 3329: {"resolve_ip", js_resolve_ip, 1, JSTYPE_STRING, JSDOCSTR("hostname") ! 3330: ,JSDOCSTR("resolve IP address of specified hostname (AKA gethostbyname)") ! 3331: ,311 ! 3332: }, ! 3333: {"gethostbyaddr", js_resolve_host, 1, JSTYPE_ALIAS }, ! 3334: {"resolve_host", js_resolve_host, 1, JSTYPE_STRING, JSDOCSTR("ip_address") ! 3335: ,JSDOCSTR("resolve hostname of specified IP address (AKA gethostbyaddr)") ! 3336: ,311 ! 3337: }, ! 3338: {"netaddr_type", js_netaddr_type, 1, JSTYPE_NUMBER, JSDOCSTR("email_address") ! 3339: ,JSDOCSTR("returns the proper message <i>net_type</i> for the specified <i>email_address</i>, " ! 3340: "(e.g. <tt>NET_INTERNET</tt> for Internet e-mail or <tt>NET_NONE</tt> for local e-mail)") ! 3341: ,312 ! 3342: }, ! 3343: {"list_named_queues",js_list_named_queues,0,JSTYPE_ARRAY, JSDOCSTR("") ! 3344: ,JSDOCSTR("returns an array of <i>named queues</i> (created with the <i>Queue</i> constructor)") ! 3345: ,312 ! 3346: }, ! 3347: {"flags_str", js_flags_str, 1, JSTYPE_UNDEF, JSDOCSTR("[string] or [number]") ! 3348: ,JSDOCSTR("convert a string of security flags (letters) into their numeric value or vice-versa " ! 3349: "(returns number OR string) - (added in v3.13)") ! 3350: ,313 ! 3351: }, ! 3352: {0} ! 3353: }; ! 3354: ! 3355: static jsConstIntSpec js_global_const_ints[] = { ! 3356: /* Numeric error constants from errno.h (platform-dependant) */ ! 3357: {"EPERM" ,EPERM }, ! 3358: {"ENOENT" ,ENOENT }, ! 3359: {"ESRCH" ,ESRCH }, ! 3360: {"EIO" ,EIO }, ! 3361: {"ENXIO" ,ENXIO }, ! 3362: {"E2BIG" ,E2BIG }, ! 3363: {"ENOEXEC" ,ENOEXEC }, ! 3364: {"EBADF" ,EBADF }, ! 3365: {"ECHILD" ,ECHILD }, ! 3366: {"EAGAIN" ,EAGAIN }, ! 3367: {"ENOMEM" ,ENOMEM }, ! 3368: {"EACCES" ,EACCES }, ! 3369: {"EFAULT" ,EFAULT }, ! 3370: {"EBUSY" ,EBUSY }, ! 3371: {"EEXIST" ,EEXIST }, ! 3372: {"EXDEV" ,EXDEV }, ! 3373: {"ENODEV" ,ENODEV }, ! 3374: {"ENOTDIR" ,ENOTDIR }, ! 3375: {"EISDIR" ,EISDIR }, ! 3376: {"EINVAL" ,EINVAL }, ! 3377: {"ENFILE" ,ENFILE }, ! 3378: {"EMFILE" ,EMFILE }, ! 3379: {"ENOTTY" ,ENOTTY }, ! 3380: {"EFBIG" ,EFBIG }, ! 3381: {"ENOSPC" ,ENOSPC }, ! 3382: {"ESPIPE" ,ESPIPE }, ! 3383: {"EROFS" ,EROFS }, ! 3384: {"EMLINK" ,EMLINK }, ! 3385: {"EPIPE" ,EPIPE }, ! 3386: {"EDOM" ,EDOM }, ! 3387: {"ERANGE" ,ERANGE }, ! 3388: {"EDEADLOCK" ,EDEADLOCK }, ! 3389: {"ENAMETOOLONG" ,ENAMETOOLONG }, ! 3390: {"ENOTEMPTY" ,ENOTEMPTY }, ! 3391: ! 3392: /* Socket errors */ ! 3393: {"EINTR" ,EINTR }, ! 3394: {"ENOTSOCK" ,ENOTSOCK }, ! 3395: {"EMSGSIZE" ,EMSGSIZE }, ! 3396: {"EWOULDBLOCK" ,EWOULDBLOCK }, ! 3397: {"EPROTOTYPE" ,EPROTOTYPE }, ! 3398: {"ENOPROTOOPT" ,ENOPROTOOPT }, ! 3399: {"EPROTONOSUPPORT" ,EPROTONOSUPPORT}, ! 3400: {"ESOCKTNOSUPPORT" ,ESOCKTNOSUPPORT}, ! 3401: {"EOPNOTSUPP" ,EOPNOTSUPP }, ! 3402: {"EPFNOSUPPORT" ,EPFNOSUPPORT }, ! 3403: {"EAFNOSUPPORT" ,EAFNOSUPPORT }, ! 3404: {"EADDRINUSE" ,EADDRINUSE }, ! 3405: {"EADDRNOTAVAIL" ,EADDRNOTAVAIL }, ! 3406: {"ECONNABORTED" ,ECONNABORTED }, ! 3407: {"ECONNRESET" ,ECONNRESET }, ! 3408: {"ENOBUFS" ,ENOBUFS }, ! 3409: {"EISCONN" ,EISCONN }, ! 3410: {"ENOTCONN" ,ENOTCONN }, ! 3411: {"ESHUTDOWN" ,ESHUTDOWN }, ! 3412: {"ETIMEDOUT" ,ETIMEDOUT }, ! 3413: {"ECONNREFUSED" ,ECONNREFUSED }, ! 3414: {"EINPROGRESS" ,EINPROGRESS }, ! 3415: ! 3416: /* Log priority values from syslog.h/sbbsdefs.h (possibly platform-dependant) */ ! 3417: {"LOG_EMERG" ,LOG_EMERG }, ! 3418: {"LOG_ALERT" ,LOG_ALERT }, ! 3419: {"LOG_CRIT" ,LOG_CRIT }, ! 3420: {"LOG_ERR" ,LOG_ERR }, ! 3421: {"LOG_ERROR" ,LOG_ERR }, ! 3422: {"LOG_WARNING" ,LOG_WARNING }, ! 3423: {"LOG_NOTICE" ,LOG_NOTICE }, ! 3424: {"LOG_INFO" ,LOG_INFO }, ! 3425: {"LOG_DEBUG" ,LOG_DEBUG }, ! 3426: ! 3427: /* Other useful constants */ ! 3428: {"INVALID_SOCKET" ,INVALID_SOCKET }, ! 3429: ! 3430: /* Terminator (Governor Arnold) */ ! 3431: {0} ! 3432: }; ! 3433: ! 3434: JSObject* DLLCALL js_CreateGlobalObject(JSContext* cx, scfg_t* cfg, jsSyncMethodSpec* methods) ! 3435: { ! 3436: JSObject* glob; ! 3437: ! 3438: if((glob = JS_NewObject(cx, &js_global_class, NULL, NULL)) ==NULL) ! 3439: return(NULL); ! 3440: ! 3441: if (!JS_InitStandardClasses(cx, glob)) ! 3442: return(NULL); ! 3443: ! 3444: if(methods!=NULL && !js_DefineSyncMethods(cx, glob, methods, TRUE)) ! 3445: return(NULL); ! 3446: ! 3447: if(!js_DefineSyncMethods(cx, glob, js_global_functions, TRUE)) ! 3448: return(NULL); ! 3449: ! 3450: if(!JS_DefineProperties(cx, glob, js_global_properties)) ! 3451: return(NULL); ! 3452: ! 3453: if(!JS_SetPrivate(cx, glob, cfg)) /* Store a pointer to scfg_t */ ! 3454: return(NULL); ! 3455: ! 3456: #ifdef BUILD_JSDOCS ! 3457: js_DescribeSyncObject(cx,glob ! 3458: ,"Top-level functions and properties (common to all servers and services)",310); ! 3459: #endif ! 3460: ! 3461: if(!js_DefineConstIntegers(cx, glob, js_global_const_ints, JSPROP_READONLY)) ! 3462: return(NULL); ! 3463: ! 3464: return(glob); ! 3465: } ! 3466: ! 3467: JSObject* DLLCALL js_CreateCommonObjects(JSContext* js_cx ! 3468: ,scfg_t* cfg /* common */ ! 3469: ,scfg_t* node_cfg /* node-specific */ ! 3470: ,jsSyncMethodSpec* methods /* global */ ! 3471: ,time_t uptime /* system */ ! 3472: ,char* host_name /* system */ ! 3473: ,char* socklib_desc /* system */ ! 3474: ,js_branch_t* branch /* js */ ! 3475: ,client_t* client /* client */ ! 3476: ,SOCKET client_socket /* client */ ! 3477: ,js_server_props_t* props /* server */ ! 3478: ) ! 3479: { ! 3480: JSObject* js_glob; ! 3481: ! 3482: if(node_cfg==NULL) ! 3483: node_cfg=cfg; ! 3484: ! 3485: /* Global Object */ ! 3486: if((js_glob=js_CreateGlobalObject(js_cx, cfg, methods))==NULL) ! 3487: return(NULL); ! 3488: ! 3489: /* System Object */ ! 3490: if(js_CreateSystemObject(js_cx, js_glob, node_cfg, uptime, host_name, socklib_desc)==NULL) ! 3491: return(NULL); ! 3492: ! 3493: /* Internal JS Object */ ! 3494: if(branch!=NULL ! 3495: && js_CreateInternalJsObject(js_cx, js_glob, branch)==NULL) ! 3496: return(NULL); ! 3497: ! 3498: /* Client Object */ ! 3499: if(client!=NULL ! 3500: && js_CreateClientObject(js_cx, js_glob, "client", client, client_socket)==NULL) ! 3501: return(NULL); ! 3502: ! 3503: /* Server */ ! 3504: if(props!=NULL ! 3505: && js_CreateServerObject(js_cx, js_glob, props)==NULL) ! 3506: return(NULL); ! 3507: ! 3508: /* Socket Class */ ! 3509: if(js_CreateSocketClass(js_cx, js_glob)==NULL) ! 3510: return(NULL); ! 3511: ! 3512: /* Queue Class */ ! 3513: if(js_CreateQueueClass(js_cx, js_glob)==NULL) ! 3514: return(NULL); ! 3515: ! 3516: /* MsgBase Class */ ! 3517: if(js_CreateMsgBaseClass(js_cx, js_glob, cfg)==NULL) ! 3518: return(NULL); ! 3519: ! 3520: /* File Class */ ! 3521: if(js_CreateFileClass(js_cx, js_glob)==NULL) ! 3522: return(NULL); ! 3523: ! 3524: /* User class */ ! 3525: if(js_CreateUserClass(js_cx, js_glob, cfg)==NULL) ! 3526: return(NULL); ! 3527: ! 3528: /* Area Objects */ ! 3529: if(!js_CreateUserObjects(js_cx, js_glob, cfg, NULL, NULL, NULL)) ! 3530: return(NULL); ! 3531: ! 3532: return(js_glob); ! 3533: } ! 3534: ! 3535: ! 3536: #endif /* JAVSCRIPT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.