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

unix.superglobalmegacorp.com

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