Annotation of sbbs/src/sbbs3/js_global.c, revision 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.