Annotation of sbbs/sbbs3/js_global.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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