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

unix.superglobalmegacorp.com

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