Annotation of sbbs/src/sbbs3/js_file.c, revision 1.1.1.2

1.1       root        1: /* js_file.c */
                      2: 
                      3: /* Synchronet JavaScript "File" Object */
                      4: 
1.1.1.2 ! root        5: /* $Id: js_file.c,v 1.126 2011/07/16 07:57:46 rswindell Exp $ */
1.1       root        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:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       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: #include "sbbs.h"
                     39: #include "md5.h"
                     40: #include "base64.h"
                     41: #include "uucode.h"
                     42: #include "yenc.h"
                     43: #include "ini_file.h"
                     44: 
                     45: #ifdef JAVASCRIPT
                     46: 
1.1.1.2 ! root       47: #include "js_request.h"
1.1       root       48: #include "jsdate.h"    /* Yes, I know this is a private header file */
                     49: 
                     50: typedef struct
                     51: {
                     52:        FILE*   fp;
                     53:        char    name[MAX_PATH+1];
                     54:        char    mode[4];
                     55:        uchar   etx;
                     56:        BOOL    external;       /* externally created, don't close */
                     57:        BOOL    debug;
                     58:        BOOL    rot13;
                     59:        BOOL    yencoded;
                     60:        BOOL    uuencoded;
                     61:        BOOL    b64encoded;
                     62:        BOOL    network_byte_order;
1.1.1.2 ! root       63:        BOOL    pipe;           /* Opened with popen() use pclose() to close */
1.1       root       64: 
                     65: } private_t;
                     66: 
                     67: static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";
                     68: 
                     69: static void dbprintf(BOOL error, private_t* p, char* fmt, ...)
                     70: {
                     71:        va_list argptr;
                     72:        char sbuf[1024];
                     73: 
                     74:        if(p==NULL || (!p->debug && !error))
                     75:                return;
                     76: 
                     77:     va_start(argptr,fmt);
                     78:     vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
                     79:        sbuf[sizeof(sbuf)-1]=0;
                     80:     va_end(argptr);
                     81:        
                     82:        lprintf(LOG_DEBUG,"%04u File %s%s",p->fp ? fileno(p->fp) : 0,error ? "ERROR: ":"",sbuf);
                     83: }
                     84: 
                     85: /* Converts fopen() style 'mode' string into open() style 'flags' integer */
                     86: 
                     87: static int fopenflags(char *mode)
                     88: {
                     89:        int flags=0;
                     90: 
                     91:        if(strchr(mode,'b'))
                     92:                flags|=O_BINARY;
                     93:        else
                     94:                flags|=O_TEXT;
                     95: 
                     96:        if(strchr(mode,'w')) {
                     97:                flags|=O_CREAT|O_TRUNC;
                     98:                if(strchr(mode,'+'))
                     99:                        flags|=O_RDWR;
                    100:                else
                    101:                        flags|=O_WRONLY;
                    102:                return(flags);
                    103:        }
                    104: 
                    105:        if(strchr(mode,'a')) {
                    106:                flags|=O_CREAT|O_APPEND;
                    107:                if(strchr(mode,'+'))
                    108:                        flags|=O_RDWR;
                    109:                else
                    110:                        flags|=O_WRONLY;
                    111:                return(flags);
                    112:        }
                    113: 
                    114:        if(strchr(mode,'r')) {
                    115:                if(strchr(mode,'+'))
                    116:                        flags|=O_RDWR;
                    117:                else
                    118:                        flags|=O_RDONLY;
                    119:        }
                    120: 
                    121:        if(strchr(mode,'e'))
                    122:                flags|=O_EXCL;
                    123: 
                    124:        return(flags);
                    125: }
                    126: 
                    127: /* File Object Methods */
                    128: 
                    129: static JSBool
                    130: js_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    131: {
                    132:        char*           mode="w+";      /* default mode */
                    133:        BOOL            shareable=FALSE;
                    134:        int                     file;
                    135:        uintN           i;
                    136:        jsint           bufsize=2*1024;
                    137:        JSString*       str;
                    138:        private_t*      p;
1.1.1.2 ! root      139:        jsrefcount      rc;
1.1       root      140: 
                    141:        *rval = JSVAL_FALSE;
                    142: 
                    143:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    144:                JS_ReportError(cx,getprivate_failure,WHERE);
                    145:                return(JS_FALSE);
                    146:        }
                    147: 
                    148:        if(p->fp!=NULL)  
                    149:                return(JS_TRUE);
                    150: 
                    151:        for(i=0;i<argc;i++) {
                    152:                if(JSVAL_IS_STRING(argv[i])) {  /* mode */
                    153:                        if((str = JS_ValueToString(cx, argv[i]))==NULL) {
                    154:                                JS_ReportError(cx,"Invalid mode specified: %s",str);
                    155:                                return(JS_TRUE);
                    156:                        }
                    157:                        mode=JS_GetStringBytes(str);
                    158:                } else if(JSVAL_IS_BOOLEAN(argv[i]))    /* shareable */
                    159:                        shareable=JSVAL_TO_BOOLEAN(argv[i]);
                    160:                else if(JSVAL_IS_NUMBER(argv[i])) {     /* bufsize */
                    161:                        if(!JS_ValueToInt32(cx,argv[i],&bufsize))
                    162:                                return(JS_FALSE);
                    163:                }
                    164:        }
                    165:        SAFECOPY(p->mode,mode);
                    166: 
1.1.1.2 ! root      167:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      168:        if(shareable)
                    169:                p->fp=fopen(p->name,p->mode);
                    170:        else {
                    171:                if((file=nopen(p->name,fopenflags(p->mode)))!=-1) {
1.1.1.2 ! root      172:                        char fdomode[4];
        !           173:                        SAFECOPY(fdomode,p->mode);
        !           174:                        fdomode[strspn(fdomode,"abrwt+")]=0;    /* MSVC10 fdopen() asserts when passed a mode with an unsupported char (e.g. 'e') */
        !           175:                        if((p->fp=fdopen(file,fdomode))==NULL)
1.1       root      176:                                close(file);
                    177:                }
                    178:        }
                    179:        if(p->fp!=NULL) {
                    180:                *rval = JSVAL_TRUE;
                    181:                dbprintf(FALSE, p, "opened: %s",p->name);
                    182:                if(!bufsize)
                    183:                        setvbuf(p->fp,NULL,_IONBF,0);   /* no buffering */
                    184:                else
                    185:                        setvbuf(p->fp,NULL,_IOFBF,bufsize);
                    186:        }
1.1.1.2 ! root      187:        JS_RESUMEREQUEST(cx, rc);
1.1       root      188: 
                    189:        return(JS_TRUE);
                    190: }
                    191: 
1.1.1.2 ! root      192: static JSBool
        !           193: js_popen(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !           194: {
        !           195:        char*           mode="r+";      /* default mode */
        !           196:        uintN           i;
        !           197:        jsint           bufsize=2*1024;
        !           198:        JSString*       str;
        !           199:        private_t*      p;
        !           200:        jsrefcount      rc;
        !           201: 
        !           202:        *rval = JSVAL_FALSE;
        !           203: 
        !           204:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
        !           205:                JS_ReportError(cx,getprivate_failure,WHERE);
        !           206:                return(JS_FALSE);
        !           207:        }
        !           208: 
        !           209:        if(p->fp!=NULL)  
        !           210:                return(JS_TRUE);
        !           211: 
        !           212:        for(i=0;i<argc;i++) {
        !           213:                if(JSVAL_IS_STRING(argv[i])) {  /* mode */
        !           214:                        if((str = JS_ValueToString(cx, argv[i]))==NULL) {
        !           215:                                JS_ReportError(cx,"Invalid mode specified: %s",str);
        !           216:                                return(JS_TRUE);
        !           217:                        }
        !           218:                        mode=JS_GetStringBytes(str);
        !           219:                }
        !           220:                else if(JSVAL_IS_NUMBER(argv[i])) {     /* bufsize */
        !           221:                        if(!JS_ValueToInt32(cx,argv[i],&bufsize))
        !           222:                                return(JS_FALSE);
        !           223:                }
        !           224:        }
        !           225:        SAFECOPY(p->mode,mode);
        !           226: 
        !           227:        rc=JS_SUSPENDREQUEST(cx);
        !           228:        p->fp=popen(p->name,p->mode);
        !           229:        if(p->fp!=NULL) {
        !           230:                p->pipe=TRUE;
        !           231:                *rval = JSVAL_TRUE;
        !           232:                dbprintf(FALSE, p, "popened: %s",p->name);
        !           233:                if(!bufsize)
        !           234:                        setvbuf(p->fp,NULL,_IONBF,0);   /* no buffering */
        !           235:                else
        !           236:                        setvbuf(p->fp,NULL,_IOFBF,bufsize);
        !           237:        }
        !           238:        JS_RESUMEREQUEST(cx, rc);
        !           239: 
        !           240:        return(JS_TRUE);
        !           241: }
1.1       root      242: 
                    243: static JSBool
                    244: js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    245: {
                    246:        private_t*      p;
1.1.1.2 ! root      247:        jsrefcount      rc;
1.1       root      248: 
                    249:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    250:                JS_ReportError(cx,getprivate_failure,WHERE);
                    251:                return(JS_FALSE);
                    252:        }
                    253: 
                    254:        if(p->fp==NULL)
                    255:                return(JS_TRUE);
                    256: 
1.1.1.2 ! root      257:        rc=JS_SUSPENDREQUEST(cx);
        !           258: #ifdef __unix__
        !           259:        if(p->pipe)
        !           260:                pclose(p->fp);
        !           261:        else
        !           262: #endif
        !           263:                fclose(p->fp);
1.1       root      264: 
                    265:        dbprintf(FALSE, p, "closed");
                    266: 
                    267:        p->fp=NULL; 
1.1.1.2 ! root      268:        JS_RESUMEREQUEST(cx, rc);
1.1       root      269: 
                    270:        return(JS_TRUE);
                    271: }
                    272: 
                    273: static JSBool
                    274: js_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    275: {
                    276:        char*           cp;
                    277:        char*           buf;
                    278:        char*           uubuf;
                    279:        int32           len;
                    280:        int32           offset;
                    281:        int32           uulen;
                    282:        JSString*       str;
                    283:        private_t*      p;
1.1.1.2 ! root      284:        jsrefcount      rc;
1.1       root      285: 
                    286:        *rval = JSVAL_NULL;
                    287: 
                    288:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    289:                JS_ReportError(cx,getprivate_failure,WHERE);
                    290:                return(JS_FALSE);
                    291:        }
                    292: 
                    293:        if(p->fp==NULL)
                    294:                return(JS_TRUE);
                    295: 
                    296:        if(argc) {
                    297:                if(!JS_ValueToInt32(cx,argv[0],&len))
                    298:                        return(JS_FALSE);
                    299:        } else {
1.1.1.2 ! root      300:                rc=JS_SUSPENDREQUEST(cx);
        !           301:                len=(long)filelength(fileno(p->fp));
        !           302:                offset=(long)ftell(p->fp);
1.1       root      303:                if(offset>0)
                    304:                        len-=offset;
1.1.1.2 ! root      305:                JS_RESUMEREQUEST(cx, rc);
1.1       root      306:        }
                    307:        if(len<0)
                    308:                len=512;
                    309: 
                    310:        if((buf=malloc(len+1))==NULL)
                    311:                return(JS_TRUE);
                    312: 
1.1.1.2 ! root      313:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      314:        len = fread(buf,1,len,p->fp);
                    315:        if(len<0) 
                    316:                len=0;
                    317:        buf[len]=0;
                    318: 
                    319:        if(p->etx) {
                    320:                cp=strchr(buf,p->etx);
                    321:                if(cp) *cp=0; 
                    322:                len=strlen(buf);
                    323:        }
                    324: 
                    325:        if(p->rot13)
                    326:                rot13(buf);
                    327: 
                    328:        if(p->uuencoded || p->b64encoded || p->yencoded) {
                    329:                uulen=len*2;
                    330:                if((uubuf=malloc(uulen))==NULL) {
                    331:                        free(buf);
1.1.1.2 ! root      332:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      333:                        return(JS_TRUE);
                    334:                }
                    335:                if(p->uuencoded)
                    336:                        uulen=uuencode(uubuf,uulen,buf,len);
                    337:                else if(p->yencoded)
                    338:                        uulen=yencode(uubuf,uulen,buf,len);
                    339:                else
                    340:                        uulen=b64_encode(uubuf,uulen,buf,len);
                    341:                if(uulen>=0) {
                    342:                        free(buf);
                    343:                        buf=uubuf;
                    344:                        len=uulen;
                    345:                }
                    346:                else
                    347:                        free(uubuf);
                    348:        }
1.1.1.2 ! root      349:        JS_RESUMEREQUEST(cx, rc);
1.1       root      350: 
                    351:        str = JS_NewStringCopyN(cx, buf, len);
                    352:        free(buf);
                    353: 
                    354:        if(str==NULL)
                    355:                return(JS_FALSE);
                    356: 
                    357:        *rval = STRING_TO_JSVAL(str);
                    358: 
1.1.1.2 ! root      359:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      360:        dbprintf(FALSE, p, "read %u bytes",len);
1.1.1.2 ! root      361:        JS_RESUMEREQUEST(cx, rc);
1.1       root      362:                
                    363:        return(JS_TRUE);
                    364: }
                    365: 
                    366: static JSBool
                    367: js_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    368: {
                    369:        char*           cp;
                    370:        char*           buf;
                    371:        int32           len=512;
                    372:        JSString*       js_str;
                    373:        private_t*      p;
1.1.1.2 ! root      374:        jsrefcount      rc;
1.1       root      375: 
                    376:        *rval = JSVAL_NULL;
                    377: 
                    378:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    379:                JS_ReportError(cx,getprivate_failure,WHERE);
                    380:                return(JS_FALSE);
                    381:        }
                    382: 
                    383:        if(p->fp==NULL)
                    384:                return(JS_TRUE);
                    385:        
                    386:        if(argc) {
                    387:                if(!JS_ValueToInt32(cx,argv[0],&len))
                    388:                        return(JS_FALSE);
                    389:        }
                    390: 
                    391:        if((buf=alloca(len))==NULL)
                    392:                return(JS_TRUE);
                    393: 
1.1.1.2 ! root      394:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      395:        if(fgets(buf,len,p->fp)!=NULL) {
                    396:                len=strlen(buf);
                    397:                while(len>0 && (buf[len-1]=='\r' || buf[len-1]=='\n'))
                    398:                        len--;
                    399:                buf[len]=0;
                    400:                if(p->etx) {
                    401:                        cp=strchr(buf,p->etx);
                    402:                        if(cp) *cp=0; 
                    403:                }
                    404:                if(p->rot13)
                    405:                        rot13(buf);
1.1.1.2 ! root      406:                JS_RESUMEREQUEST(cx, rc);
1.1       root      407:                if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)    /* exception here Feb-12-2005 */
                    408:                        *rval = STRING_TO_JSVAL(js_str);                        /* _CrtDbgBreak from _heap_alloc_dbg */
1.1.1.2 ! root      409:        } else {
        !           410:                JS_RESUMEREQUEST(cx, rc);
1.1       root      411:        }
                    412: 
                    413:        return(JS_TRUE);
                    414: }
                    415: 
                    416: static JSBool
                    417: js_readbin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    418: {
1.1.1.2 ! root      419:        BYTE            *b;
        !           420:        WORD            *w;
        !           421:        DWORD           *l;
1.1       root      422:        size_t          size=sizeof(DWORD);
                    423:        private_t*      p;
1.1.1.2 ! root      424:        size_t          count=1;
        !           425:        size_t          retlen;
        !           426:        void            *buffer=NULL;
        !           427:        size_t          i;
        !           428:     JSObject*  array;
        !           429:     jsval       v;
        !           430:        jsrefcount      rc;
1.1       root      431: 
                    432:        *rval = INT_TO_JSVAL(-1);
                    433: 
                    434:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    435:                JS_ReportError(cx,getprivate_failure,WHERE);
                    436:                return(JS_FALSE);
                    437:        }
                    438: 
                    439:        if(p->fp==NULL)
                    440:                return(JS_TRUE);
                    441: 
                    442:        if(argc) {
                    443:                if(!JS_ValueToInt32(cx,argv[0],(int32*)&size))
                    444:                        return(JS_FALSE);
1.1.1.2 ! root      445:                if(argc>1) {
        !           446:                        if(!JS_ValueToInt32(cx,argv[1],(int32*)&count))
        !           447:                                return(JS_FALSE);
        !           448:                }
        !           449:        }
        !           450: 
        !           451:        rc=JS_SUSPENDREQUEST(cx);
        !           452:        if(size != sizeof(BYTE) && size != sizeof(WORD) && size != sizeof(DWORD)) {
        !           453:                /* unknown size */
        !           454:                dbprintf(TRUE, p, "unsupported binary read size: %d",size);
        !           455:                JS_RESUMEREQUEST(cx, rc);
        !           456:                return(JS_TRUE);
1.1       root      457:        }
                    458: 
1.1.1.2 ! root      459:        buffer=malloc(size*count);
        !           460:        if(buffer==NULL) {
        !           461:                dbprintf(TRUE, p, "malloc failure of %u bytes", size*count);
        !           462:                JS_RESUMEREQUEST(cx, rc);
        !           463:                return(JS_FALSE);
        !           464:        }
        !           465:        b=buffer;
        !           466:        w=buffer;
        !           467:        l=buffer;
        !           468:        retlen=fread(buffer, size, count, p->fp);
        !           469:        if(count==1) {
        !           470:                if(retlen==1) {
        !           471:                        switch(size) {
        !           472:                                case sizeof(BYTE):
        !           473:                                        *rval = INT_TO_JSVAL(*b);
        !           474:                                        break;
        !           475:                                case sizeof(WORD):
        !           476:                                        *rval = INT_TO_JSVAL(*w);
        !           477:                                        break;
        !           478:                                case sizeof(DWORD):
        !           479:                                        JS_RESUMEREQUEST(cx, rc);
        !           480:                                        JS_NewNumberValue(cx,*l,rval);
        !           481:                                        rc=JS_SUSPENDREQUEST(cx);
        !           482:                                        break;
1.1       root      483:                        }
1.1.1.2 ! root      484:                }
        !           485:        }
        !           486:        else {
        !           487:                JS_RESUMEREQUEST(cx, rc);
        !           488:        array = JS_NewArrayObject(cx, 0, NULL);
        !           489: 
        !           490:                for(i=0; i<retlen; i++) {
        !           491:                        switch(size) {
        !           492:                                case sizeof(BYTE):
        !           493:                                        v = INT_TO_JSVAL(*(b++));
        !           494:                                        break;
        !           495:                                case sizeof(WORD):
        !           496:                                        v = INT_TO_JSVAL(*(w++));
        !           497:                                        break;
        !           498:                                case sizeof(DWORD):
        !           499:                                        JS_NewNumberValue(cx,*(l++),&v);
        !           500:                                        break;
1.1       root      501:                        }
1.1.1.2 ! root      502:                if(!JS_SetElement(cx, array, i, &v)) {
        !           503:                                rc=JS_SUSPENDREQUEST(cx);
        !           504:                                goto end;
        !           505:                        }
        !           506:                }
        !           507:        *rval = OBJECT_TO_JSVAL(array);
1.1       root      508:        }
1.1.1.2 ! root      509: 
        !           510: end:
        !           511:        free(buffer);
        !           512:        JS_RESUMEREQUEST(cx, rc);
1.1       root      513:        return(JS_TRUE);
                    514: }
                    515: 
                    516: static JSBool
                    517: js_readall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    518: {
                    519:     jsint       len=0;
                    520:     jsval       line;
                    521:     JSObject*  array;
                    522:        private_t*      p;
                    523: 
                    524:        *rval = JSVAL_NULL;
                    525: 
                    526:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    527:                JS_ReportError(cx,getprivate_failure,WHERE);
                    528:                return(JS_FALSE);
                    529:        }
                    530: 
                    531:        if(p->fp==NULL)
                    532:                return(JS_TRUE);
                    533: 
                    534:     array = JS_NewArrayObject(cx, 0, NULL);
                    535: 
                    536:     while(!feof(p->fp)) {
                    537:                js_readln(cx, obj, argc, argv, &line);
                    538:                if(line==JSVAL_NULL)
                    539:                        break;
                    540:         if(!JS_SetElement(cx, array, len++, &line))
                    541:                        break;
                    542:        }
                    543:     *rval = OBJECT_TO_JSVAL(array);
                    544: 
                    545:     return(JS_TRUE);
                    546: }
                    547: 
                    548: static jsval get_value(JSContext *cx, char* value)
                    549: {
                    550:        char*   p;
                    551:        BOOL    f=FALSE;
                    552:        jsval   val;
                    553: 
                    554:        if(value==NULL || *value==0)
                    555:                return(JSVAL_VOID);
                    556: 
                    557:        /* integer or float? */
                    558:        for(p=value;*p;p++) {
                    559:                if(*p=='.' && !f)
                    560:                        f=TRUE;
                    561:                else if(!isdigit(*p))
                    562:                        break;
                    563:        }
                    564:        if(*p==0) {     
                    565:                JS_NewNumberValue(cx, f ? atof(value) : strtoul(value,NULL,10), &val);
                    566:                return(val);
                    567:        }
                    568:        /* hexadecimal number? */
                    569:        if(!strncmp(value,"0x",2)) {    
                    570:                for(p=value+2;*p;p++)
                    571:                        if(!isxdigit(*p))
                    572:                                break;
                    573:                if(*p==0) {     
                    574:                        JS_NewNumberValue(cx,strtoul(value,NULL,0),&val);
                    575:                        return(val);
                    576:                }
                    577:        }
                    578:        /* Boolean? */
                    579:        if(!stricmp(value,"true"))
                    580:                return(JSVAL_TRUE);
                    581:        if(!stricmp(value,"false"))
                    582:                return(JSVAL_FALSE);
                    583: 
                    584:        /* String */
                    585:        return(STRING_TO_JSVAL(JS_NewStringCopyZ(cx,value)));
                    586: }
                    587: 
                    588: static JSBool
                    589: js_iniGetValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    590: {
                    591:        char*   section=ROOT_SECTION;
                    592:        char*   key;
                    593:        char**  list;
                    594:        char    buf[INI_MAX_VALUE_LEN];
                    595:        int32   i;
                    596:        jsval   val;
                    597:        jsval   dflt=argv[2];
                    598:        private_t*      p;
                    599:        JSObject*       array;
                    600:        JSObject*       dflt_obj;
                    601:        JSObject*       date_obj;
1.1.1.2 ! root      602:        jsrefcount      rc;
        !           603:        double          dbl;
        !           604:        time_t          tt;
        !           605:        char*           cstr;
        !           606:        char*           cstr2;
1.1       root      607: 
                    608:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    609:                JS_ReportError(cx,getprivate_failure,WHERE);
                    610:                return(JS_FALSE);
                    611:        }
                    612: 
                    613:        if(p->fp==NULL)
                    614:                return(JS_TRUE);
                    615: 
                    616:        if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
                    617:                section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
                    618:        key=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
                    619: 
                    620:        if(dflt==JSVAL_VOID) {  /* unspecified default value */
1.1.1.2 ! root      621:                rc=JS_SUSPENDREQUEST(cx);
1.1       root      622:                *rval=get_value(cx,iniReadString(p->fp,section,key,NULL,buf));
1.1.1.2 ! root      623:                JS_RESUMEREQUEST(cx, rc);
1.1       root      624:                return(JS_TRUE);
                    625:        }
                    626: 
                    627:        switch(JSVAL_TAG(dflt)) {
                    628:                case JSVAL_BOOLEAN:
                    629:                        *rval = BOOLEAN_TO_JSVAL(
                    630:                                iniReadBool(p->fp,section,key,JSVAL_TO_BOOLEAN(dflt)));
                    631:                        break;
                    632:                case JSVAL_DOUBLE:
1.1.1.2 ! root      633:                        rc=JS_SUSPENDREQUEST(cx);
        !           634:                        dbl=iniReadFloat(p->fp,section,key,*JSVAL_TO_DOUBLE(dflt));
        !           635:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      636:                        JS_NewNumberValue(cx
1.1.1.2 ! root      637:                                ,dbl,rval);
1.1       root      638:                        break;
                    639:                case JSVAL_OBJECT:
                    640:                        if((dflt_obj = JSVAL_TO_OBJECT(dflt))!=NULL && js_DateIsValid(cx, dflt_obj)) {
1.1.1.2 ! root      641:                                tt=(time_t)(js_DateGetMsecSinceEpoch(cx,dflt_obj)/1000.0);
        !           642:                                rc=JS_SUSPENDREQUEST(cx);
        !           643:                                dbl=iniReadDateTime(p->fp,section,key,tt);
        !           644:                                JS_RESUMEREQUEST(cx, rc);
        !           645:                                date_obj = js_NewDateObjectMsec(cx, dbl);
1.1       root      646:                                if(date_obj!=NULL)
                    647:                                        *rval = OBJECT_TO_JSVAL(date_obj);
                    648:                                break;
                    649:                        }
                    650:                    array = JS_NewArrayObject(cx, 0, NULL);
1.1.1.2 ! root      651:                        cstr=JS_GetStringBytes(JS_ValueToString(cx,dflt));
        !           652:                        rc=JS_SUSPENDREQUEST(cx);
        !           653:                        list=iniReadStringList(p->fp,section,key,",",cstr);
        !           654:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      655:                        for(i=0;list && list[i];i++) {
                    656:                                val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i]));
                    657:                                if(!JS_SetElement(cx, array, i, &val))
                    658:                                        break;
                    659:                        }
1.1.1.2 ! root      660:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      661:                        iniFreeStringList(list);
1.1.1.2 ! root      662:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      663:                        *rval = OBJECT_TO_JSVAL(array);
                    664:                        break;
                    665:                default:
                    666:                        if(JSVAL_IS_NUMBER(dflt)) {
                    667:                                if(!JS_ValueToInt32(cx,dflt,&i))
                    668:                                        return(JS_FALSE);
1.1.1.2 ! root      669:                                rc=JS_SUSPENDREQUEST(cx);
        !           670:                                i=iniReadInteger(p->fp,section,key,i);
        !           671:                                JS_RESUMEREQUEST(cx, rc);
        !           672:                                JS_NewNumberValue(cx,i,rval);
        !           673:                        } else {
        !           674:                                cstr=JS_GetStringBytes(JS_ValueToString(cx,dflt));
        !           675:                                rc=JS_SUSPENDREQUEST(cx);
        !           676:                                cstr2=iniReadString(p->fp,section,key,cstr,buf);
        !           677:                                JS_RESUMEREQUEST(cx, rc);
        !           678:                                *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cstr2));
        !           679:                        }
1.1       root      680:                        break;
                    681:        }
                    682: 
                    683:        return(JS_TRUE);
                    684: }
                    685: 
                    686: static JSBool
                    687: js_iniSetValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    688: {
                    689:        char*   section=ROOT_SECTION;
                    690:        char*   key;
                    691:        char*   result=NULL;
                    692:        int32   i;
                    693:        jsval   value=argv[2];
                    694:        private_t*      p;
                    695:        str_list_t      list;
                    696:        JSObject*       value_obj;
1.1.1.2 ! root      697:        jsrefcount      rc;
        !           698:        char*           cstr;
        !           699:        time_t          tt;
1.1       root      700: 
                    701:        *rval = JSVAL_FALSE;
                    702: 
                    703:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    704:                JS_ReportError(cx,getprivate_failure,WHERE);
                    705:                return(JS_FALSE);
                    706:        }
                    707: 
                    708:        if(p->fp==NULL)
                    709:                return(JS_TRUE);
                    710: 
                    711:        if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
                    712:                section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
                    713:        key=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
                    714: 
1.1.1.2 ! root      715:        rc=JS_SUSPENDREQUEST(cx);
        !           716:        if((list=iniReadFile(p->fp))==NULL) {
        !           717:                JS_RESUMEREQUEST(cx, rc);
1.1       root      718:                return(JS_TRUE);
1.1.1.2 ! root      719:        }
        !           720:        JS_RESUMEREQUEST(cx, rc);
1.1       root      721: 
1.1.1.2 ! root      722:        if(value==JSVAL_VOID) {         /* unspecified value */
        !           723:                rc=JS_SUSPENDREQUEST(cx);
1.1       root      724:                result = iniSetString(&list,section,key,"",NULL);
1.1.1.2 ! root      725:                JS_RESUMEREQUEST(cx, rc);
        !           726:        }
1.1       root      727:        else {
                    728: 
                    729:                switch(JSVAL_TAG(value)) {
                    730:                        case JSVAL_BOOLEAN:
                    731:                                result = iniSetBool(&list,section,key,JSVAL_TO_BOOLEAN(value),NULL);
                    732:                                break;
                    733:                        case JSVAL_DOUBLE:
                    734:                                result = iniSetFloat(&list,section,key,*JSVAL_TO_DOUBLE(value),NULL);
                    735:                                break;
                    736:                        default:
                    737:                                if(JSVAL_IS_NUMBER(value)) {
                    738:                                        if(!JS_ValueToInt32(cx,value,&i))
                    739:                                                return(JS_FALSE);
1.1.1.2 ! root      740:                                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      741:                                        result = iniSetInteger(&list,section,key,i,NULL);
1.1.1.2 ! root      742:                                        JS_RESUMEREQUEST(cx, rc);
1.1       root      743:                                } else {
                    744:                                        if(JSVAL_IS_OBJECT(value) 
                    745:                                                && (value_obj = JSVAL_TO_OBJECT(value))!=NULL
                    746:                                                && js_DateIsValid(cx, value_obj)) {
1.1.1.2 ! root      747:                                                tt=(time_t)(js_DateGetMsecSinceEpoch(cx,value_obj)/1000.0);
        !           748:                                                rc=JS_SUSPENDREQUEST(cx);
        !           749:                                                result = iniSetDateTime(&list,section,key,/* include_time */TRUE, tt,NULL);
        !           750:                                                JS_RESUMEREQUEST(cx, rc);
        !           751:                                        } else {
        !           752:                                                cstr=JS_GetStringBytes(JS_ValueToString(cx,value));
        !           753:                                                rc=JS_SUSPENDREQUEST(cx);
        !           754:                                                result = iniSetString(&list,section,key, cstr,NULL);
        !           755:                                                JS_RESUMEREQUEST(cx, rc);
        !           756:                                        }
1.1       root      757:                                }
                    758:                                break;
                    759:                }
                    760:        }
                    761: 
1.1.1.2 ! root      762:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      763:        if(result != NULL)
                    764:                *rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list));
                    765: 
                    766:        strListFree(&list);
1.1.1.2 ! root      767:        JS_RESUMEREQUEST(cx, rc);
1.1       root      768: 
                    769:        return(JS_TRUE);
                    770: }
                    771: 
                    772: static JSBool
                    773: js_iniRemoveKey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    774: {
                    775:        char*   section=ROOT_SECTION;
                    776:        char*   key;
                    777:        private_t*      p;
                    778:        str_list_t      list;
1.1.1.2 ! root      779:        jsrefcount      rc;
1.1       root      780: 
                    781:        *rval = JSVAL_FALSE;
                    782: 
                    783:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    784:                JS_ReportError(cx,getprivate_failure,WHERE);
                    785:                return(JS_FALSE);
                    786:        }
                    787: 
                    788:        if(p->fp==NULL)
                    789:                return(JS_TRUE);
                    790: 
                    791:        if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
                    792:                section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
                    793:        key=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
                    794: 
1.1.1.2 ! root      795:        rc=JS_SUSPENDREQUEST(cx);
        !           796:        if((list=iniReadFile(p->fp))==NULL) {
        !           797:                JS_RESUMEREQUEST(cx, rc);
1.1       root      798:                return(JS_TRUE);
1.1.1.2 ! root      799:        }
1.1       root      800: 
                    801:        if(iniRemoveKey(&list,section,key))
                    802:                *rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list));
                    803: 
                    804:        strListFree(&list);
1.1.1.2 ! root      805:        JS_RESUMEREQUEST(cx, rc);
1.1       root      806: 
                    807:        return(JS_TRUE);
                    808: }
                    809: 
                    810: static JSBool
                    811: js_iniRemoveSection(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    812: {
                    813:        char*   section=ROOT_SECTION;
                    814:        private_t*      p;
                    815:        str_list_t      list;
1.1.1.2 ! root      816:        jsrefcount      rc;
1.1       root      817: 
                    818:        *rval = JSVAL_FALSE;
                    819: 
                    820:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    821:                JS_ReportError(cx,getprivate_failure,WHERE);
                    822:                return(JS_FALSE);
                    823:        }
                    824: 
                    825:        if(p->fp==NULL)
                    826:                return(JS_TRUE);
                    827: 
                    828:        if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
                    829:                section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
                    830: 
1.1.1.2 ! root      831:        rc=JS_SUSPENDREQUEST(cx);
        !           832:        if((list=iniReadFile(p->fp))==NULL) {
        !           833:                JS_RESUMEREQUEST(cx, rc);
1.1       root      834:                return(JS_TRUE);
1.1.1.2 ! root      835:        }
1.1       root      836: 
                    837:        if(iniRemoveSection(&list,section))
                    838:                *rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list));
                    839: 
                    840:        strListFree(&list);
1.1.1.2 ! root      841:        JS_RESUMEREQUEST(cx, rc);
1.1       root      842: 
                    843:        return(JS_TRUE);
                    844: }
                    845: 
                    846: 
                    847: static JSBool
                    848: js_iniGetSections(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    849: {
                    850:        char*           prefix=NULL;
                    851:        char**          list;
                    852:     jsint       i;
                    853:     jsval       val;
                    854:     JSObject*  array;
                    855:        private_t*      p;
1.1.1.2 ! root      856:        jsrefcount      rc;
1.1       root      857: 
                    858:        *rval = JSVAL_NULL;
                    859: 
                    860:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    861:                JS_ReportError(cx,getprivate_failure,WHERE);
                    862:                return(JS_FALSE);
                    863:        }
                    864: 
                    865:        if(p->fp==NULL)
                    866:                return(JS_TRUE);
                    867: 
                    868:        if(argc)
                    869:                prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
                    870: 
                    871:     array = JS_NewArrayObject(cx, 0, NULL);
                    872: 
1.1.1.2 ! root      873:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      874:        list = iniReadSectionList(p->fp,prefix);
1.1.1.2 ! root      875:        JS_RESUMEREQUEST(cx, rc);
1.1       root      876:     for(i=0;list && list[i];i++) {
                    877:                val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i]));
                    878:         if(!JS_SetElement(cx, array, i, &val))
                    879:                        break;
                    880:        }
1.1.1.2 ! root      881:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      882:        iniFreeStringList(list);
1.1.1.2 ! root      883:        JS_RESUMEREQUEST(cx, rc);
1.1       root      884: 
                    885:     *rval = OBJECT_TO_JSVAL(array);
                    886: 
                    887:     return(JS_TRUE);
                    888: }
                    889: 
                    890: static JSBool
                    891: js_iniGetKeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    892: {
                    893:        char*           section=ROOT_SECTION;
                    894:        char**          list;
                    895:     jsint       i;
                    896:     jsval       val;
                    897:     JSObject*  array;
                    898:        private_t*      p;
1.1.1.2 ! root      899:        jsrefcount      rc;
1.1       root      900: 
                    901:        *rval = JSVAL_NULL;
                    902: 
                    903:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    904:                JS_ReportError(cx,getprivate_failure,WHERE);
                    905:                return(JS_FALSE);
                    906:        }
                    907: 
                    908:        if(p->fp==NULL)
                    909:                return(JS_TRUE);
                    910: 
                    911:        if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
                    912:                section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
                    913:     array = JS_NewArrayObject(cx, 0, NULL);
                    914: 
1.1.1.2 ! root      915:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      916:        list = iniReadKeyList(p->fp,section);
1.1.1.2 ! root      917:        JS_RESUMEREQUEST(cx, rc);
1.1       root      918:     for(i=0;list && list[i];i++) {
                    919:                val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i]));
                    920:         if(!JS_SetElement(cx, array, i, &val))
                    921:                        break;
                    922:        }
1.1.1.2 ! root      923:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      924:        iniFreeStringList(list);
1.1.1.2 ! root      925:        JS_RESUMEREQUEST(cx, rc);
1.1       root      926: 
                    927:     *rval = OBJECT_TO_JSVAL(array);
                    928: 
                    929:     return(JS_TRUE);
                    930: }
                    931: 
                    932: static JSBool
                    933: js_iniGetObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    934: {
                    935:        char*           section=ROOT_SECTION;
                    936:     jsint       i;
                    937:     JSObject*  object;
                    938:        private_t*      p;
                    939:        named_string_t** list;
1.1.1.2 ! root      940:        jsrefcount      rc;
1.1       root      941: 
                    942:        *rval = JSVAL_NULL;
                    943: 
                    944:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    945:                JS_ReportError(cx,getprivate_failure,WHERE);
                    946:                return(JS_FALSE);
                    947:        }
                    948: 
                    949:        if(p->fp==NULL)
                    950:                return(JS_TRUE);
                    951: 
                    952:        if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
                    953:                section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
                    954: 
1.1.1.2 ! root      955:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      956:        list = iniReadNamedStringList(p->fp,section);
1.1.1.2 ! root      957:        JS_RESUMEREQUEST(cx, rc);
        !           958: 
        !           959:        if(list==NULL) {        /* New behavior at request of MCMLXXIX: return NULL/undefined if specified section doesn't exist */
        !           960:                *rval = JSVAL_NULL;
        !           961:                return(JS_TRUE);
        !           962:        }
        !           963: 
        !           964:     object = JS_NewObject(cx, NULL, NULL, obj);
        !           965: 
1.1       root      966:     for(i=0;list && list[i];i++) {
                    967:                JS_DefineProperty(cx, object, list[i]->name
                    968:                        ,get_value(cx,list[i]->value)
                    969:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    970: 
                    971:        }
1.1.1.2 ! root      972:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      973:        iniFreeNamedStringList(list);
1.1.1.2 ! root      974:        JS_RESUMEREQUEST(cx, rc);
1.1       root      975: 
                    976:     *rval = OBJECT_TO_JSVAL(object);
                    977: 
                    978:     return(JS_TRUE);
                    979: }
                    980: 
                    981: static JSBool
                    982: js_iniSetObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    983: {
                    984:     jsint       i;
                    985:     JSObject*  object;
                    986:        JSIdArray*      id_array;
                    987:        jsval           set_argv[3];
                    988: 
                    989:        *rval = JSVAL_FALSE;
                    990: 
                    991:        set_argv[0]=argv[0];    /* section */
                    992: 
                    993:        if(!JSVAL_IS_OBJECT(argv[1]) || argv[1]==JSVAL_NULL)
                    994:                return(JS_TRUE);
                    995: 
                    996:     object = JSVAL_TO_OBJECT(argv[1]);
                    997: 
                    998:        if((id_array=JS_Enumerate(cx,object))==NULL)
                    999:                return(JS_TRUE);
                   1000: 
                   1001:        for(i=0; i<id_array->length; i++)  {
                   1002:                /* property */
                   1003:                JS_IdToValue(cx,id_array->vector[i],&set_argv[1]);      
                   1004:                /* value */
                   1005:                JS_GetProperty(cx,object,JS_GetStringBytes(JSVAL_TO_STRING(set_argv[1])),&set_argv[2]);
                   1006:                if(!js_iniSetValue(cx,obj,3,set_argv,rval))
                   1007:                        break;
                   1008:        }
                   1009: 
                   1010:        JS_DestroyIdArray(cx,id_array);
                   1011: 
                   1012:     return(JS_TRUE);
                   1013: }
                   1014: 
                   1015: 
                   1016: static JSBool
                   1017: js_iniGetAllObjects(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1018: {
                   1019:        char*           name="name";
                   1020:        char*           sec_name;
                   1021:        char*           prefix=NULL;
                   1022:        char**          sec_list;
                   1023:     jsint       i,k;
                   1024:     jsval       val;
                   1025:     JSObject*  array;
                   1026:     JSObject*  object;
                   1027:        private_t*      p;
                   1028:        named_string_t** key_list;
1.1.1.2 ! root     1029:        jsrefcount      rc;
1.1       root     1030: 
                   1031:        *rval = JSVAL_NULL;
                   1032: 
                   1033:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1034:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1035:                return(JS_FALSE);
                   1036:        }
                   1037: 
                   1038:        if(p->fp==NULL)
                   1039:                return(JS_TRUE);
                   1040: 
                   1041:        if(argc)
                   1042:                name=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
                   1043: 
                   1044:        if(argc>1)
                   1045:                prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
                   1046: 
                   1047:     array = JS_NewArrayObject(cx, 0, NULL);
                   1048: 
1.1.1.2 ! root     1049:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1050:        sec_list = iniReadSectionList(p->fp,prefix);
1.1.1.2 ! root     1051:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1052:     for(i=0;sec_list && sec_list[i];i++) {
                   1053:            object = JS_NewObject(cx, NULL, NULL, obj);
                   1054: 
                   1055:                sec_name=sec_list[i];
                   1056:                if(prefix!=NULL)
                   1057:                        sec_name+=strlen(prefix);
                   1058:                JS_DefineProperty(cx, object, name
                   1059:                        ,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,sec_name))
                   1060:                        ,NULL,NULL,JSPROP_ENUMERATE);
                   1061: 
1.1.1.2 ! root     1062:                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1063:                key_list = iniReadNamedStringList(p->fp,sec_list[i]);
1.1.1.2 ! root     1064:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1065:                for(k=0;key_list && key_list[k];k++)
                   1066:                        JS_DefineProperty(cx, object, key_list[k]->name
                   1067:                                ,get_value(cx,key_list[k]->value)
                   1068:                                ,NULL,NULL,JSPROP_ENUMERATE);
1.1.1.2 ! root     1069:                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1070:                iniFreeNamedStringList(key_list);
1.1.1.2 ! root     1071:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1072: 
                   1073:                val=OBJECT_TO_JSVAL(object);
1.1.1.2 ! root     1074:                /* exception here, Apr-4-2010:
        !          1075: 
        !          1076:   2000007a()
        !          1077: js_iniGetAllObjects(JSContext * 0x049383e0, JSObject * 0x049c76a8, unsigned int 0x00000001, long * 0x049c0490, long * 0x02c5c494) line 1064 + 24 bytes
        !          1078: js_Invoke(JSContext * 0x049383e0, unsigned int 0x00000001, unsigned int 0x00000000) line 1375 + 23 bytes
        !          1079: js_Interpret(JSContext * 0x049383e0, unsigned char * 0x031ab4b2, long * 0x02c5d6ac) line 3944 + 15 bytes
        !          1080: js_Execute(JSContext * 0x049383e0, JSObject * 0x049b73e8, JSScript * 0x02f2a7e0, JSStackFrame * 0x00000000, unsigned int 0x00000000, long * 0x02c5d7bc) line 1633 + 19 bytes
        !          1081: JS_ExecuteScript(JSContext * 0x049383e0, JSObject * 0x049b73e8, JSScript * 0x02f2a7e0, long * 0x02c5d7bc) line 4188 + 25 bytes
        !          1082: sbbs_t::js_execfile(const char * 0x0226b59a, const char * 0x022060fa) line 668 + 39 bytes
        !          1083: sbbs_t::external(const char * 0x0226b599, long 0x00000100, const char * 0x022060fa) line 413 + 30 bytes
        !          1084: event_thread(void * 0x022622b8) line 2745 + 113 bytes
        !          1085: _threadstart(void * 0x0227dab0) line 187 + 13 bytes
        !          1086: 
        !          1087: 
        !          1088: and July-15-2010:
        !          1089: 
        !          1090:        20000000()      
        !          1091:        js32.dll!JS_SetElement(JSContext * cx, JSObject * obj, long index, long * vp)  Line 3178 + 0x20 bytes   C
        !          1092: >      sbbs.dll!js_iniGetAllObjects(JSContext * cx, JSObject * obj, unsigned int argc, long * argv, long * rval)  Line 1081 + 0x18 bytes       C
        !          1093:        js32.dll!js_Invoke(JSContext * cx, unsigned int argc, unsigned int flags)  Line 1375 + 0x17 bytes       C
        !          1094:        js32.dll!js_Interpret(JSContext * cx, unsigned char * pc, long * result)  Line 3944 + 0xf bytes C
        !          1095:        js32.dll!js_Execute(JSContext * cx, JSObject * chain, JSScript * script, JSStackFrame * down, unsigned int flags, long * result)  Line 1633 + 0x13 bytes        C
        !          1096:        js32.dll!JS_ExecuteScript(JSContext * cx, JSObject * obj, JSScript * script, long * rval)  Line 4188 + 0x19 bytes       C
        !          1097:        sbbs.dll!sbbs_t::js_execfile(const char * cmd, const char * startup_dir)  Line 686 + 0x27 bytes C++
        !          1098:        sbbs.dll!sbbs_t::external(const char * cmdline, long mode, const char * startup_dir)  Line 413 + 0x1e bytes     C++
        !          1099:        sbbs.dll!event_thread(void * arg)  Line 2745 + 0x71 bytes       C++
        !          1100: 
        !          1101: And July-22-2010:
        !          1102: 
        !          1103:        js32.dll!JS_SetElement(JSContext * cx, JSObject * obj, long index, long * vp)  Line 3178 + 0x20 bytes   C
        !          1104: >      sbbs.dll!js_iniGetAllObjects(JSContext * cx, JSObject * obj, unsigned int argc, long * argv, long * rval)  Line 1095 + 0x18 bytes       C
        !          1105:        js32.dll!js_Invoke(JSContext * cx, unsigned int argc, unsigned int flags)  Line 1375 + 0x17 bytes       C
        !          1106:        js32.dll!js_Interpret(JSContext * cx, unsigned char * pc, long * result)  Line 3944 + 0xf bytes C
        !          1107:        js32.dll!js_Execute(JSContext * cx, JSObject * chain, JSScript * script, JSStackFrame * down, unsigned int flags, long * result)  Line 1633 + 0x13 bytes        C
        !          1108:        js32.dll!JS_ExecuteScript(JSContext * cx, JSObject * obj, JSScript * script, long * rval)  Line 4188 + 0x19 bytes       C
        !          1109:        websrvr.dll!exec_ssjs(http_session_t * session, char * script)  Line 4638 + 0x24 bytes  C
        !          1110:        websrvr.dll!respond(http_session_t * session)  Line 4684 + 0x12 bytes   C
        !          1111:        websrvr.dll!http_session_thread(void * arg)  Line 5091 + 0xc bytes      C
        !          1112: 
        !          1113: 
        !          1114:   */
1.1       root     1115:         if(!JS_SetElement(cx, array, i, &val))
                   1116:                        break;
                   1117:        }
1.1.1.2 ! root     1118:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1119:        iniFreeStringList(sec_list);
1.1.1.2 ! root     1120:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1121: 
                   1122:     *rval = OBJECT_TO_JSVAL(array);
                   1123: 
                   1124:     return(JS_TRUE);
                   1125: }
                   1126: 
                   1127: static JSBool
                   1128: js_iniSetAllObjects(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1129: {
                   1130:        char*           name="name";
                   1131:     jsuint      i;
1.1.1.2 ! root     1132:     jsint       j;
1.1       root     1133:     jsuint      count;
                   1134:     JSObject*  array;
1.1.1.2 ! root     1135:     JSObject*  object;
        !          1136:        jsval           oval;
        !          1137:        jsval           set_argv[3];
        !          1138:        JSIdArray*      id_array;
1.1       root     1139: 
                   1140:        *rval = JSVAL_FALSE;
                   1141: 
1.1.1.2 ! root     1142:        if(JSVAL_IS_NULL(argv[0]) || !JSVAL_IS_OBJECT(argv[0]))
1.1       root     1143:                return(JS_TRUE);
                   1144: 
                   1145:     array = JSVAL_TO_OBJECT(argv[0]);
                   1146: 
                   1147:        if(!JS_IsArrayObject(cx, array))
                   1148:                return(JS_TRUE);
                   1149: 
                   1150:     if(!JS_GetArrayLength(cx, array, &count))
                   1151:                return(JS_TRUE);
                   1152: 
                   1153:        if(argc>1)
                   1154:                name=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
                   1155: 
                   1156:        /* enumerate the array */
                   1157:        for(i=0; i<count; i++)  {
1.1.1.2 ! root     1158:         if(!JS_GetElement(cx, array, i, &oval))
1.1       root     1159:                        break;
1.1.1.2 ! root     1160:                if(!JSVAL_IS_OBJECT(oval))      /* must be an array of objects */
1.1       root     1161:                        break;
1.1.1.2 ! root     1162:                object=JSVAL_TO_OBJECT(oval);
        !          1163:                if(!JS_GetProperty(cx, object, name, &set_argv[0]))
1.1       root     1164:                        continue;
1.1.1.2 ! root     1165:                if((id_array=JS_Enumerate(cx,object))==NULL)
        !          1166:                        return(JS_TRUE);
        !          1167: 
        !          1168:                for(j=0; j<id_array->length; j++)  {
        !          1169:                        /* property */
        !          1170:                        JS_IdToValue(cx,id_array->vector[j],&set_argv[1]);      
        !          1171:                        /* check if not name */
        !          1172:                        if(strcmp(JS_GetStringBytes(JS_ValueToString(cx, set_argv[1])),name)==0)
        !          1173:                                continue;
        !          1174:                        /* value */
        !          1175:                        JS_GetProperty(cx,object,JS_GetStringBytes(JSVAL_TO_STRING(set_argv[1])),&set_argv[2]);
        !          1176:                        if(!js_iniSetValue(cx,obj,3,set_argv,rval))
        !          1177:                                break;
        !          1178:                }
        !          1179: 
        !          1180:                JS_DestroyIdArray(cx,id_array);
1.1       root     1181:        }
                   1182: 
                   1183:     return(JS_TRUE);
                   1184: }
                   1185: 
                   1186: static JSBool
                   1187: js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1188: {
                   1189:        char*           cp;
                   1190:        char*           uubuf=NULL;
                   1191:        int                     len;    /* string length */
                   1192:        int                     tlen;   /* total length to write (may be greater than len) */
                   1193:        JSString*       str;
                   1194:        private_t*      p;
1.1.1.2 ! root     1195:        jsrefcount      rc;
1.1       root     1196: 
                   1197:        *rval = JSVAL_FALSE;
                   1198: 
                   1199:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1200:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1201:                return(JS_FALSE);
                   1202:        }
                   1203: 
                   1204:        if(p->fp==NULL)
                   1205:                return(JS_TRUE);
                   1206: 
                   1207:        str = JS_ValueToString(cx, argv[0]);
                   1208:        cp      = JS_GetStringBytes(str);
                   1209:        len     = JS_GetStringLength(str);
                   1210: 
1.1.1.2 ! root     1211:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1212:        if((p->uuencoded || p->b64encoded || p->yencoded)
                   1213:                && len && (uubuf=malloc(len))!=NULL) {
                   1214:                if(p->uuencoded)
                   1215:                        len=uudecode(uubuf,len,cp,len);
                   1216:                else if(p->yencoded)
                   1217:                        len=ydecode(uubuf,len,cp,len);
                   1218:                else
                   1219:                        len=b64_decode(uubuf,len,cp,len);
                   1220:                if(len<0) {
                   1221:                        free(uubuf);
1.1.1.2 ! root     1222:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1223:                        return(JS_TRUE);
                   1224:                }
                   1225:                cp=uubuf;
                   1226:        }
                   1227: 
                   1228:        if(p->rot13)
                   1229:                rot13(cp);
                   1230: 
1.1.1.2 ! root     1231:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1232:        tlen=len;
                   1233:        if(argc>1) {
                   1234:                if(!JS_ValueToInt32(cx,argv[1],(int32*)&tlen)) {
                   1235:                        FREE_AND_NULL(uubuf);
                   1236:                        return(JS_FALSE);
                   1237:                }
                   1238:                if(len>tlen)
                   1239:                        len=tlen;
                   1240:        }
                   1241: 
1.1.1.2 ! root     1242:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1243:        if(fwrite(cp,1,len,p->fp)==(size_t)len) {
                   1244:                if(tlen>len) {
                   1245:                        len=tlen-len;
                   1246:                        if((cp=malloc(len))==NULL) {
1.1.1.2 ! root     1247:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1248:                                FREE_AND_NULL(uubuf);
                   1249:                                dbprintf(TRUE, p, "malloc failure of %u bytes", len);
                   1250:                                return(JS_TRUE);
                   1251:                        }
                   1252:                        memset(cp,p->etx,len);
                   1253:                        fwrite(cp,1,len,p->fp);
                   1254:                        free(cp);
                   1255:                }
                   1256:                dbprintf(FALSE, p, "wrote %u bytes",tlen);
                   1257:                *rval = JSVAL_TRUE;
                   1258:        } else 
                   1259:                dbprintf(TRUE, p, "write of %u bytes failed",len);
                   1260: 
                   1261:        FREE_AND_NULL(uubuf);
1.1.1.2 ! root     1262:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1263:                
                   1264:        return(JS_TRUE);
                   1265: }
                   1266: 
                   1267: static JSBool
                   1268: js_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1269: {
                   1270:        char*           cp="";
                   1271:        JSString*       str;
                   1272:        private_t*      p;
1.1.1.2 ! root     1273:        jsrefcount      rc;
1.1       root     1274: 
                   1275:        *rval = JSVAL_FALSE;
                   1276: 
                   1277:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1278:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1279:                return(JS_FALSE);
                   1280:        }
                   1281: 
                   1282:        if(p->fp==NULL)
                   1283:                return(JS_TRUE);
                   1284: 
                   1285:        if(argc) {
                   1286:                if((str = JS_ValueToString(cx, argv[0]))==NULL) {
                   1287:                        JS_ReportError(cx,"JS_ValueToString failed");
                   1288:                        return(JS_FALSE);
                   1289:                }
                   1290:                cp = JS_GetStringBytes(str);
                   1291:        }
                   1292: 
1.1.1.2 ! root     1293:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1294:        if(p->rot13)
                   1295:                rot13(cp);
                   1296: 
                   1297:        if(fprintf(p->fp,"%s\n",cp)!=0)
                   1298:                *rval = JSVAL_TRUE;
1.1.1.2 ! root     1299:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1300: 
                   1301:        return(JS_TRUE);
                   1302: }
                   1303: 
                   1304: static JSBool
                   1305: js_writebin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1306: {
1.1.1.2 ! root     1307:        BYTE            *b;
        !          1308:        WORD            *w;
        !          1309:        DWORD           *l;
1.1       root     1310:        size_t          wr=0;
                   1311:        size_t          size=sizeof(DWORD);
1.1.1.2 ! root     1312:        jsuint          count=1;
        !          1313:        void            *buffer;
1.1       root     1314:        private_t*      p;
1.1.1.2 ! root     1315:     JSObject*  array=NULL;
        !          1316:     jsval       elemval;
        !          1317:        jsdouble        val=0;
        !          1318:        jsrefcount      rc;
1.1       root     1319: 
                   1320:        *rval = JSVAL_FALSE;
                   1321: 
                   1322:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1323:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1324:                return(JS_FALSE);
                   1325:        }
                   1326: 
                   1327:        if(p->fp==NULL)
                   1328:                return(JS_TRUE);
                   1329: 
1.1.1.2 ! root     1330:        if(JSVAL_IS_OBJECT(argv[0]) && !JSVAL_IS_NULL(argv[0])) {
        !          1331:                array = JSVAL_TO_OBJECT(argv[0]);
        !          1332:                if(JS_IsArrayObject(cx, array)) {
        !          1333:                    if(!JS_GetArrayLength(cx, array, &count))
        !          1334:                                return(JS_TRUE);
        !          1335:                }
        !          1336:                else
        !          1337:                        array=NULL;
        !          1338:        }
        !          1339:        if(array==NULL) {
        !          1340:                if(!JS_ValueToNumber(cx,argv[0],&val))
        !          1341:                        return(JS_FALSE);
        !          1342:        }
1.1       root     1343:        if(argc>1) {
                   1344:                if(!JS_ValueToInt32(cx,argv[1],(int32*)&size))
                   1345:                        return(JS_FALSE);
                   1346:        }
1.1.1.2 ! root     1347:        if(size != sizeof(BYTE) && size != sizeof(WORD) && size != sizeof(DWORD)) {
        !          1348:                rc=JS_SUSPENDREQUEST(cx);
        !          1349:                dbprintf(TRUE, p, "unsupported binary write size: %d",size);
        !          1350:                JS_RESUMEREQUEST(cx, rc);
        !          1351:                return(JS_TRUE);
        !          1352:        }
        !          1353:        buffer=malloc(size*count);
        !          1354:        if(buffer==NULL) {
        !          1355:                rc=JS_SUSPENDREQUEST(cx);
        !          1356:                dbprintf(TRUE, p, "malloc failure of %u bytes", size*count);
        !          1357:                JS_RESUMEREQUEST(cx, rc);
        !          1358:                return(JS_FALSE);
        !          1359:        }
        !          1360:        b=buffer;
        !          1361:        w=buffer;
        !          1362:        l=buffer;
        !          1363:        if(array==NULL) {
        !          1364:                switch(size) {
        !          1365:                        case sizeof(BYTE):
        !          1366:                                *b=(BYTE)val;
        !          1367:                                break;
        !          1368:                        case sizeof(WORD):
        !          1369:                                *w=(WORD)val;
        !          1370:                                break;
        !          1371:                        case sizeof(DWORD):
        !          1372:                                *l=(DWORD)val;
        !          1373:                                break;
        !          1374:                }
1.1       root     1375:        }
1.1.1.2 ! root     1376:        else {
        !          1377:                for(wr=0; wr<count; wr++) {
        !          1378:                if(!JS_GetElement(cx, array, wr, &elemval))
        !          1379:                                goto end;
        !          1380:                        if(!JS_ValueToNumber(cx,elemval,&val))
        !          1381:                                goto end;
        !          1382:                        switch(size) {
        !          1383:                                case sizeof(BYTE):
        !          1384:                                        *(b++)=(BYTE)val;
        !          1385:                                        break;
        !          1386:                                case sizeof(WORD):
        !          1387:                                        *(w++)=(WORD)val;
        !          1388:                                        break;
        !          1389:                                case sizeof(DWORD):
        !          1390:                                        *(l++)=(DWORD)val;
        !          1391:                                        break;
        !          1392:                        }
        !          1393:                }
        !          1394:        }
        !          1395:        rc=JS_SUSPENDREQUEST(cx);
        !          1396:        wr=fwrite(buffer,size,count,p->fp);
        !          1397:        JS_RESUMEREQUEST(cx, rc);
        !          1398:        if(wr==count)
        !          1399:                *rval=JSVAL_TRUE;
        !          1400: 
        !          1401: end:
        !          1402:        free(buffer);
1.1       root     1403:        return(JS_TRUE);
                   1404: }
                   1405: 
                   1406: static JSBool
                   1407: js_writeall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1408: {
                   1409:     jsuint      i;
                   1410:     jsuint      limit;
                   1411:     JSObject*  array;
                   1412:     jsval       elemval;
                   1413:        private_t*      p;
                   1414: 
                   1415:        *rval = JSVAL_FALSE;
                   1416: 
                   1417:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1418:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1419:                return(JS_FALSE);
                   1420:        }
                   1421: 
                   1422:        if(p->fp==NULL)
                   1423:                return(JS_TRUE);
                   1424: 
1.1.1.2 ! root     1425:        if(JSVAL_IS_NULL(argv[0]) || !JSVAL_IS_OBJECT(argv[0]))
1.1       root     1426:                return(JS_TRUE);
                   1427: 
                   1428:     array = JSVAL_TO_OBJECT(argv[0]);
                   1429: 
                   1430:     if(!JS_IsArrayObject(cx, array))
                   1431:                return(JS_TRUE);
                   1432: 
                   1433:     if(!JS_GetArrayLength(cx, array, &limit))
                   1434:                return(JS_FALSE);
                   1435: 
                   1436:     *rval = JSVAL_TRUE;
                   1437: 
                   1438:     for(i=0;i<limit;i++) {
                   1439:         if(!JS_GetElement(cx, array, i, &elemval))
                   1440:                        break;
                   1441:         js_writeln(cx, obj, 1, &elemval, rval);
                   1442:                if(*rval!=JSVAL_TRUE)
                   1443:                        break;
                   1444:     }
                   1445: 
                   1446:     return(JS_TRUE);
                   1447: }
                   1448: 
                   1449: static JSBool
                   1450: js_lock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1451: {
1.1.1.2 ! root     1452:        off_t           offset=0;
        !          1453:        off_t           len=0;
1.1       root     1454:        private_t*      p;
1.1.1.2 ! root     1455:        jsrefcount      rc;
        !          1456:        jsdouble        val;
1.1       root     1457: 
                   1458:        *rval = JSVAL_FALSE;
                   1459: 
                   1460:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1461:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1462:                return(JS_FALSE);
                   1463:        }
                   1464: 
                   1465:        if(p->fp==NULL)
                   1466:                return(JS_TRUE);
                   1467: 
                   1468:        /* offset */
                   1469:        if(argc) {
1.1.1.2 ! root     1470:                if(!JS_ValueToNumber(cx,argv[0],&val))
1.1       root     1471:                        return(JS_FALSE);
1.1.1.2 ! root     1472:                offset=(off_t)val;
1.1       root     1473:        }
                   1474: 
                   1475:        /* length */
                   1476:        if(argc>1) {
1.1.1.2 ! root     1477:                if(!JS_ValueToNumber(cx,argv[1],&val))
1.1       root     1478:                        return(JS_FALSE);
1.1.1.2 ! root     1479:                len=(off_t)val;
1.1       root     1480:        }
                   1481: 
1.1.1.2 ! root     1482:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1483:        if(len==0)
                   1484:                len=filelength(fileno(p->fp))-offset;
                   1485: 
                   1486:        if(lock(fileno(p->fp),offset,len)==0)
                   1487:                *rval = JSVAL_TRUE;
1.1.1.2 ! root     1488:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1489: 
                   1490:        return(JS_TRUE);
                   1491: }
                   1492: 
                   1493: static JSBool
                   1494: js_unlock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1495: {
1.1.1.2 ! root     1496:        off_t           offset=0;
        !          1497:        off_t           len=0;
1.1       root     1498:        private_t*      p;
1.1.1.2 ! root     1499:        jsrefcount      rc;
        !          1500:        jsdouble        val;
1.1       root     1501: 
                   1502:        *rval = JSVAL_FALSE;
                   1503: 
                   1504:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1505:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1506:                return(JS_FALSE);
                   1507:        }
                   1508: 
                   1509:        if(p->fp==NULL)
                   1510:                return(JS_TRUE);
                   1511: 
                   1512:        /* offset */
                   1513:        if(argc) {
1.1.1.2 ! root     1514:                if(!JS_ValueToNumber(cx,argv[0],&val))
1.1       root     1515:                        return(JS_FALSE);
1.1.1.2 ! root     1516:                offset=(off_t)val;
1.1       root     1517:        }
                   1518: 
                   1519:        /* length */
                   1520:        if(argc>1) {
1.1.1.2 ! root     1521:                if(!JS_ValueToNumber(cx,argv[1],&val))
1.1       root     1522:                        return(JS_FALSE);
1.1.1.2 ! root     1523:                len=(off_t)val;
1.1       root     1524:        }
                   1525: 
1.1.1.2 ! root     1526:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1527:        if(len==0)
                   1528:                len=filelength(fileno(p->fp))-offset;
                   1529: 
                   1530:        if(unlock(fileno(p->fp),offset,len)==0)
                   1531:                *rval = JSVAL_TRUE;
1.1.1.2 ! root     1532:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1533: 
                   1534:        return(JS_TRUE);
                   1535: }
                   1536: 
                   1537: static JSBool
                   1538: js_delete(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1539: {
                   1540:        private_t*      p;
1.1.1.2 ! root     1541:        jsrefcount      rc;
1.1       root     1542: 
                   1543:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1544:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1545:                return(JS_FALSE);
                   1546:        }
                   1547: 
                   1548:        if(p->fp!=NULL) {       /* close it if it's open */
                   1549:                fclose(p->fp);
                   1550:                p->fp=NULL;
                   1551:        }
                   1552: 
1.1.1.2 ! root     1553:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1554:        *rval = BOOLEAN_TO_JSVAL(remove(p->name)==0);
1.1.1.2 ! root     1555:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1556: 
                   1557:        return(JS_TRUE);
                   1558: }
                   1559: 
                   1560: static JSBool
                   1561: js_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1562: {
                   1563:        private_t*      p;
1.1.1.2 ! root     1564:        jsrefcount      rc;
1.1       root     1565: 
                   1566:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1567:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1568:                return(JS_FALSE);
                   1569:        }
                   1570: 
1.1.1.2 ! root     1571:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1572:        if(p->fp==NULL)
                   1573:                *rval = JSVAL_FALSE;
                   1574:        else 
                   1575:                *rval = BOOLEAN_TO_JSVAL(fflush(p->fp)==0);
1.1.1.2 ! root     1576:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1577: 
                   1578:        return(JS_TRUE);
                   1579: }
                   1580: 
                   1581: static JSBool
                   1582: js_rewind(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1583: {
                   1584:        private_t*      p;
1.1.1.2 ! root     1585:        jsrefcount      rc;
1.1       root     1586: 
                   1587:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1588:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1589:                return(JS_FALSE);
                   1590:        }
                   1591: 
1.1.1.2 ! root     1592:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1593:        if(p->fp==NULL)
                   1594:                *rval = JSVAL_FALSE;
                   1595:        else  {
                   1596:                *rval = JSVAL_TRUE;
                   1597:                rewind(p->fp);
                   1598:        }
1.1.1.2 ! root     1599:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1600: 
                   1601:        return(JS_TRUE);
                   1602: }
                   1603: 
                   1604: static JSBool
                   1605: js_truncate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1606: {
                   1607:        private_t*      p;
                   1608:        int32           len=0;
1.1.1.2 ! root     1609:        jsrefcount      rc;
1.1       root     1610: 
                   1611:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1612:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1613:                return(JS_FALSE);
                   1614:        }
                   1615: 
                   1616:        if(argc) {
                   1617:                if(!JS_ValueToInt32(cx,argv[0],&len))
                   1618:                        return(JS_FALSE);
                   1619:        }
                   1620: 
1.1.1.2 ! root     1621:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1622:        *rval = JSVAL_FALSE;
                   1623:        if(p->fp!=NULL && chsize(fileno(p->fp),len)==0) {
                   1624:                fseek(p->fp,len,SEEK_SET);
                   1625:                *rval = JSVAL_TRUE;
                   1626:        }
1.1.1.2 ! root     1627:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1628: 
                   1629:        return(JS_TRUE);
                   1630: }
                   1631: 
                   1632: static JSBool
                   1633: js_clear_error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1634: {
                   1635:        private_t*      p;
1.1.1.2 ! root     1636:        jsrefcount      rc;
1.1       root     1637: 
                   1638:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1639:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1640:                return(JS_FALSE);
                   1641:        }
                   1642: 
1.1.1.2 ! root     1643:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1644:        if(p->fp==NULL)
                   1645:                *rval = JSVAL_FALSE;
                   1646:        else  {
                   1647:                clearerr(p->fp);
                   1648:                *rval = JSVAL_TRUE;
                   1649:        }
1.1.1.2 ! root     1650:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1651: 
                   1652:        return(JS_TRUE);
                   1653: }
                   1654: 
                   1655: static JSBool
                   1656: js_fprintf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1657: {
                   1658:        char*           cp;
                   1659:        private_t*      p;
1.1.1.2 ! root     1660:        jsrefcount      rc;
1.1       root     1661: 
                   1662:        *rval = JSVAL_FALSE;
                   1663: 
                   1664:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1665:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1666:                return(JS_FALSE);
                   1667:        }
                   1668: 
                   1669:        if(p->fp==NULL)
                   1670:                return(JS_TRUE);
                   1671: 
                   1672:        if((cp=js_sprintf(cx, 0, argc, argv))==NULL) {
                   1673:                JS_ReportError(cx,"js_sprintf failed");
                   1674:                return(JS_FALSE);
                   1675:        }
                   1676: 
1.1.1.2 ! root     1677:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1678:        *rval = INT_TO_JSVAL(fwrite(cp,1,strlen(cp),p->fp));
1.1.1.2 ! root     1679:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1680:        js_sprintf_free(cp);
                   1681:        
                   1682:     return(JS_TRUE);
                   1683: }
                   1684: 
                   1685: 
                   1686: /* File Object Properites */
                   1687: enum {
                   1688:         FILE_PROP_NAME         
                   1689:        ,FILE_PROP_MODE
                   1690:        ,FILE_PROP_ETX
                   1691:        ,FILE_PROP_EXISTS       
                   1692:        ,FILE_PROP_DATE         
                   1693:        ,FILE_PROP_IS_OPEN      
                   1694:        ,FILE_PROP_EOF          
                   1695:        ,FILE_PROP_ERROR        
                   1696:        ,FILE_PROP_DESCRIPTOR
                   1697:        ,FILE_PROP_DEBUG        
                   1698:        ,FILE_PROP_POSITION     
                   1699:        ,FILE_PROP_LENGTH       
                   1700:        ,FILE_PROP_ATTRIBUTES
                   1701:        ,FILE_PROP_YENCODED
                   1702:        ,FILE_PROP_UUENCODED
                   1703:        ,FILE_PROP_B64ENCODED
                   1704:        ,FILE_PROP_ROT13
                   1705:        ,FILE_PROP_NETWORK_ORDER
                   1706:        /* dynamically calculated */
                   1707:        ,FILE_PROP_CHKSUM
                   1708:        ,FILE_PROP_CRC16
                   1709:        ,FILE_PROP_CRC32
                   1710:        ,FILE_PROP_MD5_HEX
                   1711:        ,FILE_PROP_MD5_B64
                   1712: };
                   1713: 
                   1714: 
                   1715: static JSBool js_file_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                   1716: {
                   1717:        int32           i=0;
                   1718:     jsint       tiny;
                   1719:        private_t*      p;
1.1.1.2 ! root     1720:        jsrefcount      rc;
1.1       root     1721: 
                   1722:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1723:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1724:                return(JS_FALSE);
                   1725:        }
                   1726: 
                   1727:     tiny = JSVAL_TO_INT(id);
                   1728: 
1.1.1.2 ! root     1729:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1730:        dbprintf(FALSE, p, "setting property %d",tiny);
1.1.1.2 ! root     1731:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1732: 
                   1733:        switch(tiny) {
                   1734:                case FILE_PROP_DEBUG:
                   1735:                        JS_ValueToBoolean(cx,*vp,&(p->debug));
                   1736:                        break;
                   1737:                case FILE_PROP_YENCODED:
                   1738:                        JS_ValueToBoolean(cx,*vp,&(p->yencoded));
                   1739:                        break;
                   1740:                case FILE_PROP_UUENCODED:
                   1741:                        JS_ValueToBoolean(cx,*vp,&(p->uuencoded));
                   1742:                        break;
                   1743:                case FILE_PROP_B64ENCODED:
                   1744:                        JS_ValueToBoolean(cx,*vp,&(p->b64encoded));
                   1745:                        break;
                   1746:                case FILE_PROP_ROT13:
                   1747:                        JS_ValueToBoolean(cx,*vp,&(p->rot13));
                   1748:                        break;
                   1749:                case FILE_PROP_NETWORK_ORDER:
                   1750:                        JS_ValueToBoolean(cx,*vp,&(p->network_byte_order));
                   1751:                        break;
                   1752:                case FILE_PROP_POSITION:
                   1753:                        if(p->fp!=NULL) {
                   1754:                                if(!JS_ValueToInt32(cx,*vp,&i))
                   1755:                                        return(JS_FALSE);
1.1.1.2 ! root     1756:                                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1757:                                fseek(p->fp,i,SEEK_SET);
1.1.1.2 ! root     1758:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1759:                        }
                   1760:                        break;
                   1761:                case FILE_PROP_DATE:
                   1762:                        if(!JS_ValueToInt32(cx,*vp,&i))
                   1763:                                return(JS_FALSE);
1.1.1.2 ! root     1764:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1765:                        setfdate(p->name,i);
1.1.1.2 ! root     1766:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1767:                        break;
                   1768:                case FILE_PROP_LENGTH:
                   1769:                        if(p->fp!=NULL) {
                   1770:                                if(!JS_ValueToInt32(cx,*vp,&i))
                   1771:                                        return(JS_FALSE);
1.1.1.2 ! root     1772:                                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1773:                                chsize(fileno(p->fp),i);
1.1.1.2 ! root     1774:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1775:                        }
                   1776:                        break;
                   1777:                case FILE_PROP_ATTRIBUTES:
                   1778:                        if(!JS_ValueToInt32(cx,*vp,&i))
                   1779:                                return(JS_FALSE);
1.1.1.2 ! root     1780:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1781:                        CHMOD(p->name,i);
1.1.1.2 ! root     1782:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1783:                        break;
                   1784:                case FILE_PROP_ETX:
                   1785:                        if(!JS_ValueToInt32(cx,*vp,&i))
                   1786:                                return(JS_FALSE);
                   1787:                        p->etx = (uchar)i;
                   1788:                        break;
                   1789:        }
                   1790: 
                   1791:        return(JS_TRUE);
                   1792: }
                   1793: 
                   1794: static JSBool js_file_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                   1795: {
                   1796:        char            str[128];
                   1797:        size_t          i;
                   1798:        size_t          rd;
1.1.1.2 ! root     1799:        off_t           offset;
1.1       root     1800:        ulong           sum=0;
                   1801:        ushort          c16=0;
                   1802:        ulong           c32=~0;
                   1803:        MD5                     md5_ctx;
                   1804:        BYTE            block[4096];
                   1805:        BYTE            digest[MD5_DIGEST_SIZE];
                   1806:     jsint       tiny;
                   1807:        JSString*       js_str=NULL;
                   1808:        private_t*      p;
1.1.1.2 ! root     1809:        jsrefcount      rc;
        !          1810:        time_t          tt;
        !          1811:        off_t           lng;
        !          1812:        int                     in;
1.1       root     1813: 
                   1814:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1815:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1816:                return(JS_FALSE);
                   1817:        }
                   1818: 
                   1819:     tiny = JSVAL_TO_INT(id);
                   1820: 
                   1821: #if 0 /* just too much */
                   1822:        dbprintf(FALSE, sock, "getting property %d",tiny);
                   1823: #endif
                   1824: 
                   1825:        switch(tiny) {
                   1826:                case FILE_PROP_NAME:
                   1827:                        if((js_str=JS_NewStringCopyZ(cx, p->name))==NULL)
                   1828:                                return(JS_FALSE);
                   1829:                        *vp = STRING_TO_JSVAL(js_str);
                   1830:                        break;
                   1831:                case FILE_PROP_MODE:
                   1832:                        if((js_str=JS_NewStringCopyZ(cx, p->mode))==NULL)
                   1833:                                return(JS_FALSE);
                   1834:                        *vp = STRING_TO_JSVAL(js_str);
                   1835:                        break;
                   1836:                case FILE_PROP_EXISTS:
                   1837:                        if(p->fp)       /* open? */
                   1838:                                *vp = JSVAL_TRUE;
1.1.1.2 ! root     1839:                        else {
        !          1840:                                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1841:                                *vp = BOOLEAN_TO_JSVAL(fexistcase(p->name));
1.1.1.2 ! root     1842:                                JS_RESUMEREQUEST(cx, rc);
        !          1843:                        }
1.1       root     1844:                        break;
                   1845:                case FILE_PROP_DATE:
1.1.1.2 ! root     1846:                        rc=JS_SUSPENDREQUEST(cx);
        !          1847:                        tt=fdate(p->name);
        !          1848:                        JS_RESUMEREQUEST(cx, rc);
        !          1849:                        JS_NewNumberValue(cx,tt,vp);
1.1       root     1850:                        break;
                   1851:                case FILE_PROP_IS_OPEN:
                   1852:                        *vp = BOOLEAN_TO_JSVAL(p->fp!=NULL);
                   1853:                        break;
                   1854:                case FILE_PROP_EOF:
1.1.1.2 ! root     1855:                        if(p->fp) {
        !          1856:                                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1857:                                *vp = BOOLEAN_TO_JSVAL(feof(p->fp)!=0);
1.1.1.2 ! root     1858:                                JS_RESUMEREQUEST(cx, rc);
        !          1859:                        }
1.1       root     1860:                        else
                   1861:                                *vp = JSVAL_TRUE;
                   1862:                        break;
                   1863:                case FILE_PROP_ERROR:
1.1.1.2 ! root     1864:                        if(p->fp) {
        !          1865:                                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1866:                                *vp = INT_TO_JSVAL(ferror(p->fp));
1.1.1.2 ! root     1867:                                JS_RESUMEREQUEST(cx, rc);
        !          1868:                        }
1.1       root     1869:                        else
                   1870:                                *vp = INT_TO_JSVAL(errno);
                   1871:                        break;
                   1872:                case FILE_PROP_POSITION:
1.1.1.2 ! root     1873:                        if(p->fp) {
        !          1874:                                rc=JS_SUSPENDREQUEST(cx);
        !          1875:                                lng=ftell(p->fp);
        !          1876:                                JS_RESUMEREQUEST(cx, rc);
        !          1877:                                JS_NewNumberValue(cx,(double)lng,vp);
        !          1878:                        }
1.1       root     1879:                        else
                   1880:                                *vp = INT_TO_JSVAL(-1);
                   1881:                        break;
                   1882:                case FILE_PROP_LENGTH:
1.1.1.2 ! root     1883:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1884:                        if(p->fp)       /* open? */
1.1.1.2 ! root     1885:                                lng = filelength(fileno(p->fp));
1.1       root     1886:                        else
1.1.1.2 ! root     1887:                                lng = flength(p->name);
        !          1888:                        JS_RESUMEREQUEST(cx, rc);
        !          1889:                        JS_NewNumberValue(cx,(double)lng,vp);
1.1       root     1890:                        break;
                   1891:                case FILE_PROP_ATTRIBUTES:
1.1.1.2 ! root     1892:                        rc=JS_SUSPENDREQUEST(cx);
        !          1893:                        in=getfattr(p->name);
        !          1894:                        JS_RESUMEREQUEST(cx, rc);
        !          1895:                        JS_NewNumberValue(cx,in,vp);
1.1       root     1896:                        break;
                   1897:                case FILE_PROP_DEBUG:
                   1898:                        *vp = BOOLEAN_TO_JSVAL(p->debug);
                   1899:                        break;
                   1900:                case FILE_PROP_YENCODED:
                   1901:                        *vp = BOOLEAN_TO_JSVAL(p->yencoded);
                   1902:                        break;
                   1903:                case FILE_PROP_UUENCODED:
                   1904:                        *vp = BOOLEAN_TO_JSVAL(p->uuencoded);
                   1905:                        break;
                   1906:                case FILE_PROP_B64ENCODED:
                   1907:                        *vp = BOOLEAN_TO_JSVAL(p->b64encoded);
                   1908:                        break;
                   1909:                case FILE_PROP_ROT13:
                   1910:                        *vp = BOOLEAN_TO_JSVAL(p->rot13);
                   1911:                        break;
                   1912:                case FILE_PROP_NETWORK_ORDER:
                   1913:                        *vp = BOOLEAN_TO_JSVAL(p->network_byte_order);
                   1914:                        break;
                   1915:                case FILE_PROP_DESCRIPTOR:
                   1916:                        if(p->fp)
                   1917:                                *vp = INT_TO_JSVAL(fileno(p->fp));
                   1918:                        else
                   1919:                                *vp = INT_TO_JSVAL(-1);
                   1920:                        break;
                   1921:                case FILE_PROP_ETX:
                   1922:                        *vp = INT_TO_JSVAL(p->etx);
                   1923:                        break;
                   1924:                case FILE_PROP_CHKSUM:
                   1925:                case FILE_PROP_CRC16:
                   1926:                case FILE_PROP_CRC32:
                   1927:                        *vp = JSVAL_ZERO;
                   1928:                        if(p->fp==NULL)
                   1929:                                break;
                   1930:                        /* fall-through */
                   1931:                case FILE_PROP_MD5_HEX:
                   1932:                case FILE_PROP_MD5_B64:
                   1933:                        *vp = JSVAL_VOID;
                   1934:                        if(p->fp==NULL)
                   1935:                                break;
1.1.1.2 ! root     1936:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1937:                        offset=ftell(p->fp);                    /* save current file position */
                   1938:                        fseek(p->fp,0,SEEK_SET);
                   1939: 
                   1940:                        /* Initialization */
                   1941:                        switch(tiny) {
                   1942:                                case FILE_PROP_MD5_HEX:
                   1943:                                case FILE_PROP_MD5_B64:
                   1944:                                        MD5_open(&md5_ctx);
                   1945:                                        break;
                   1946:                        }
                   1947: 
                   1948:                        /* calculate */
                   1949:                        while(!feof(p->fp)) {
                   1950:                                if((rd=fread(block,1,sizeof(block),p->fp))<1)
                   1951:                                        break;
                   1952:                                switch(tiny) {
                   1953:                                        case FILE_PROP_CHKSUM:
                   1954:                                                for(i=0;i<rd;i++)
                   1955:                                                        sum+=block[i];
                   1956:                                                break;
                   1957:                                        case FILE_PROP_CRC16:
                   1958:                                                for(i=0;i<rd;i++)
                   1959:                                                        c16=ucrc16(block[i],c16);
                   1960:                                                break;
                   1961:                                        case FILE_PROP_CRC32:
                   1962:                                                for(i=0;i<rd;i++)
                   1963:                                                        c32=ucrc32(block[i],c32);
                   1964:                                                break;
                   1965:                                        case FILE_PROP_MD5_HEX:
                   1966:                                        case FILE_PROP_MD5_B64:
                   1967:                                                MD5_digest(&md5_ctx,block,rd);
                   1968:                                                break;
                   1969:                                        }
                   1970:                        }
1.1.1.2 ! root     1971:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1972: 
                   1973:                        /* finalize */
                   1974:                        switch(tiny) {
                   1975:                                case FILE_PROP_CHKSUM:
                   1976:                                        JS_NewNumberValue(cx,sum,vp);
                   1977:                                        break;
                   1978:                                case FILE_PROP_CRC16:
                   1979:                                        if(!JS_NewNumberValue(cx,c16,vp))
                   1980:                                                *vp=JSVAL_ZERO;
                   1981:                                        break;
                   1982:                                case FILE_PROP_CRC32:
                   1983:                                        if(!JS_NewNumberValue(cx,~c32,vp))
                   1984:                                                *vp=JSVAL_ZERO;
                   1985:                                        break;
                   1986:                                case FILE_PROP_MD5_HEX:
                   1987:                                case FILE_PROP_MD5_B64:
                   1988:                                        MD5_close(&md5_ctx,digest);
                   1989:                                        if(tiny==FILE_PROP_MD5_HEX)
                   1990:                                                MD5_hex(str,digest);
                   1991:                                        else 
                   1992:                                                b64_encode(str,sizeof(str)-1,digest,sizeof(digest));
                   1993:                                        js_str=JS_NewStringCopyZ(cx, str);
                   1994:                                        break;
                   1995:                        }
1.1.1.2 ! root     1996:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1997:                        fseek(p->fp,offset,SEEK_SET);   /* restore saved file position */
1.1.1.2 ! root     1998:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1999:                        if(js_str!=NULL)
                   2000:                                *vp = STRING_TO_JSVAL(js_str);
                   2001:                        break;
                   2002:        }
                   2003: 
                   2004:        return(JS_TRUE);
                   2005: }
                   2006: 
                   2007: #define FILE_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
                   2008: 
                   2009: static jsSyncPropertySpec js_file_properties[] = {
                   2010: /*              name                           ,tinyid                                 ,flags,                         ver     */
                   2011:        {       "name"                          ,FILE_PROP_NAME                 ,FILE_PROP_FLAGS,       310},
                   2012:        {       "mode"                          ,FILE_PROP_MODE                 ,FILE_PROP_FLAGS,       310},
                   2013:        {       "exists"                        ,FILE_PROP_EXISTS               ,FILE_PROP_FLAGS,       310},
                   2014:        {       "is_open"                       ,FILE_PROP_IS_OPEN              ,FILE_PROP_FLAGS,       310},
                   2015:        {       "eof"                           ,FILE_PROP_EOF                  ,FILE_PROP_FLAGS,       310},
                   2016:        {       "error"                         ,FILE_PROP_ERROR                ,FILE_PROP_FLAGS,       310},
                   2017:        {       "descriptor"            ,FILE_PROP_DESCRIPTOR   ,FILE_PROP_FLAGS,       310},
                   2018:        /* writeable */
                   2019:        {       "etx"                           ,FILE_PROP_ETX                  ,JSPROP_ENUMERATE,  310},
                   2020:        {       "debug"                         ,FILE_PROP_DEBUG                ,JSPROP_ENUMERATE,      310},
                   2021:        {       "position"                      ,FILE_PROP_POSITION             ,JSPROP_ENUMERATE,      310},
                   2022:        {       "date"                          ,FILE_PROP_DATE                 ,JSPROP_ENUMERATE,      311},
                   2023:        {       "length"                        ,FILE_PROP_LENGTH               ,JSPROP_ENUMERATE,      310},
                   2024:        {       "attributes"            ,FILE_PROP_ATTRIBUTES   ,JSPROP_ENUMERATE,      310},
                   2025:        {       "network_byte_order",FILE_PROP_NETWORK_ORDER,JSPROP_ENUMERATE,  311},
                   2026:        {       "rot13"                         ,FILE_PROP_ROT13                ,JSPROP_ENUMERATE,      311},
                   2027:        {       "uue"                           ,FILE_PROP_UUENCODED    ,JSPROP_ENUMERATE,      311},
                   2028:        {       "yenc"                          ,FILE_PROP_YENCODED             ,JSPROP_ENUMERATE,      311},
                   2029:        {       "base64"                        ,FILE_PROP_B64ENCODED   ,JSPROP_ENUMERATE,      311},
                   2030:        /* dynamically calculated */
                   2031:        {       "crc16"                         ,FILE_PROP_CRC16                ,FILE_PROP_FLAGS,       311},
                   2032:        {       "crc32"                         ,FILE_PROP_CRC32                ,FILE_PROP_FLAGS,       311},
                   2033:        {       "chksum"                        ,FILE_PROP_CHKSUM               ,FILE_PROP_FLAGS,       311},
                   2034:        {       "md5_hex"                       ,FILE_PROP_MD5_HEX              ,FILE_PROP_FLAGS,       311},
                   2035:        {       "md5_base64"            ,FILE_PROP_MD5_B64              ,FILE_PROP_FLAGS,       311},
                   2036:        {0}
                   2037: };
                   2038: 
                   2039: #ifdef BUILD_JSDOCS
                   2040: static char* file_prop_desc[] = {
                   2041:         "filename specified in constructor - <small>READ ONLY</small>"
                   2042:        ,"mode string specified in <i>open</i> call - <small>READ ONLY</small>"
1.1.1.2 ! root     2043:        ,"<i>true</i> if the file is open or exists (case-insensitive) - <small>READ ONLY</small>"
1.1       root     2044:        ,"<i>true</i> if the file has been opened successfully - <small>READ ONLY</small>"
                   2045:        ,"<i>true</i> if the current file position is at the <i>end of file</i> - <small>READ ONLY</small>"
                   2046:        ,"the last occurred error value (use clear_error to clear) - <small>READ ONLY</small>"
                   2047:        ,"the open file descriptor (advanced use only) - <small>READ ONLY</small>"
                   2048:        ,"end-of-text character (advanced use only), if non-zero used by <i>read</i>, <i>readln</i>, and <i>write</i>"
                   2049:        ,"set to <i>true</i> to enable debug log output"
                   2050:        ,"the current file position (offset in bytes), change value to seek within file"
                   2051:        ,"last modified date/time (in time_t format)"
                   2052:        ,"the current length of the file (in bytes)"
                   2053:        ,"file mode/attributes"
                   2054:        ,"set to <i>true</i> if binary data is to be written and read in Network Byte Order (big end first)"
                   2055:        ,"set to <i>true</i> to enable automatic ROT13 translatation of text"
                   2056:        ,"set to <i>true</i> to enable automatic Unix-to-Unix encode and decode on <tt>read</tt> and <tt>write</tt> calls"
                   2057:        ,"set to <i>true</i> to enable automatic yEnc encode and decode on <tt>read</tt> and <tt>write</tt> calls"
                   2058:        ,"set to <i>true</i> to enable automatic Base64 encode and decode on <tt>read</tt> and <tt>write</tt> calls"
                   2059:        ,"calculated 16-bit CRC of file contents - <small>READ ONLY</small>"
                   2060:        ,"calculated 32-bit CRC of file contents - <small>READ ONLY</small>"
                   2061:        ,"calculated 32-bit checksum of file contents - <small>READ ONLY</small>"
                   2062:        ,"calculated 128-bit MD5 digest of file contents as hexadecimal string - <small>READ ONLY</small>"
                   2063:        ,"calculated 128-bit MD5 digest of file contents as base64-encoded string - <small>READ ONLY</small>"
                   2064:        ,NULL
                   2065: };
                   2066: #endif
                   2067: 
                   2068: 
                   2069: static jsSyncMethodSpec js_file_functions[] = {
                   2070:        {"open",                        js_open,                        1,      JSTYPE_BOOLEAN, JSDOCSTR("[mode=<tt>\"w+\"</tt>] [,shareable=<tt>false</tt>] [,buffer_length]")
                   2071:        ,JSDOCSTR("open file, <i>shareable</i> defaults to <i>false</i>, <i>buffer_length</i> defaults to 2048 bytes, "
                   2072:                "mode (default: <tt>'w+'</tt>) specifies the type of access requested for the file, as follows:<br>"
                   2073:                "<tt>r&nbsp</tt> open for reading; if the file does not exist or cannot be found, the open call fails<br>"
                   2074:                "<tt>w&nbsp</tt> open an empty file for writing; if the given file exists, its contents are destroyed<br>"
                   2075:                "<tt>a&nbsp</tt> open for writing at the end of the file (appending); creates the file first if it doesn�t exist<br>"
                   2076:                "<tt>r+</tt> open for both reading and writing (the file must exist)<br>"
                   2077:                "<tt>w+</tt> open an empty file for both reading and writing; if the given file exists, its contents are destroyed<br>"
                   2078:                "<tt>a+</tt> open for reading and appending<br>"
                   2079:                "<tt>b&nbsp</tt> open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed (e.g. <tt>r+b</tt>)<br>"
                   2080:                "<tt>e&nbsp</tt> open a <i>non-shareable</i> file (that must not already exist) for <i>exclusive</i> access <i>(introduced in v3.12)</i><br>"
                   2081:                "<br><b>Note:</b> When using the <tt>iniSet</tt> methods to modify a <tt>.ini</tt> file, "
                   2082:                "the file must be opened for both reading and writing.<br>"
1.1.1.2 ! root     2083:                "<br><b>Note:</b> To open an existing or create a new file for both reading and writing "
        !          2084:                "(e.g. updating an <tt>.ini</tt> file) "
        !          2085:                "use the <i>exists</i> property like so:<br>"
        !          2086:                "<tt>file.open(file.exists ? 'r+':'w+');</tt>"
        !          2087:                "<br><b>Note:</b> When <i>shareable</i> is false, uses nopen() which will lock the file "
        !          2088:                "and perform automatic retries.  The lock mode is as follows:<br>"
        !          2089:                "<tt>r&nbsp</tt> DENYWRITE - Allows other scripts to open the file for reading, but not for writing.<br>"
        !          2090:                "<tt>w&nbsp</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br>"
        !          2091:                "<tt>a&nbsp</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br>"
        !          2092:                "<tt>r+</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br>"
        !          2093:                "<tt>w+</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br>"
        !          2094:                "<tt>a+</tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br>"
        !          2095:                "When <i>shareable</i> is true uses fopen(), "
        !          2096:                "and will only attempt to open the file once and will perform no locking.  The behaviour "
        !          2097:                "when one script has a file opened with <i>shareable</i> set to a different value than is used "
        !          2098:                "with a new call is OS specific.  On Windows, the second open will always fail and on *nix, "
        !          2099:                "the second open will always succeed.<br>"
1.1       root     2100:                )
                   2101:        ,310
                   2102:        },              
1.1.1.2 ! root     2103:        {"popen",                       js_popen,                       1,      JSTYPE_BOOLEAN, JSDOCSTR("[mode=<tt>\"r+\"</tt>] [,buffer_length]")
        !          2104:        ,JSDOCSTR("open pipe to command, <i>buffer_length</i> defaults to 2048 bytes, "
        !          2105:                "mode (default: <tt>'r+'</tt>) specifies the type of access requested for the file, as follows:<br>"
        !          2106:                "<tt>r&nbsp</tt> read the programs stdout;<br>"
        !          2107:                "<tt>w&nbsp</tt> write to the programs stdin<br>"
        !          2108:                "<tt>r+</tt> open for both reading stdout and writing stdin<br>"
        !          2109:                "(<b>only functional on UNIX systems</b>)"
        !          2110:                )
        !          2111:        ,315
        !          2112:        },              
1.1       root     2113:        {"close",                       js_close,                       0,      JSTYPE_VOID,    JSDOCSTR("")
                   2114:        ,JSDOCSTR("close file")
                   2115:        ,310
                   2116:        },              
                   2117:        {"remove",                      js_delete,                      0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   2118:        ,JSDOCSTR("remove the file from the disk")
                   2119:        ,310
                   2120:        },
                   2121:        {"clearError",          js_clear_error,         0,      JSTYPE_ALIAS },
                   2122:        {"clear_error",         js_clear_error,         0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   2123:        ,JSDOCSTR("clears the current error value (AKA clearError)")
                   2124:        ,310
                   2125:        },
                   2126:        {"flush",                       js_flush,                       0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   2127:        ,JSDOCSTR("flush/commit buffers to disk")
                   2128:        ,310
                   2129:        },
                   2130:        {"rewind",                      js_rewind,                      0,      JSTYPE_BOOLEAN, JSDOCSTR("")
                   2131:        ,JSDOCSTR("repositions the file pointer (<i>position</i>) to the beginning of a file "
                   2132:                "and clears error and end-of-file indicators")
                   2133:        ,311
                   2134:        },
                   2135:        {"truncate",            js_truncate,            0,      JSTYPE_BOOLEAN, JSDOCSTR("[length=<tt>0</tt>]")
                   2136:        ,JSDOCSTR("changes the file <i>length</i> (default: 0) and repositions the file pointer "
                   2137:        "(<i>position</i>) to the new end-of-file")
                   2138:        ,314
                   2139:        },
                   2140:        {"lock",                        js_lock,                        2,      JSTYPE_BOOLEAN, JSDOCSTR("[offset=<tt>0</tt>] [,length=<i>file_length</i>-<i>offset</i>]")
                   2141:        ,JSDOCSTR("lock file record for exclusive access (file must be opened <i>shareable</i>)")
                   2142:        ,310
                   2143:        },              
                   2144:        {"unlock",                      js_unlock,                      2,      JSTYPE_BOOLEAN, JSDOCSTR("[offset=<tt>0</tt>] [,length=<i>file_length</i>-<i>offset</i>]")
                   2145:        ,JSDOCSTR("unlock file record for exclusive access")
                   2146:        ,310
                   2147:        },              
                   2148:        {"read",                        js_read,                        0,      JSTYPE_STRING,  JSDOCSTR("[maxlen=<i>file_length</i>-<i>file_position</i>]")
                   2149:        ,JSDOCSTR("read a string from file (optionally unix-to-unix or base64 decoding in the process), "
                   2150:                "<i>maxlen</i> defaults to the current length of the file minus the current file position")
                   2151:        ,310
                   2152:        },
                   2153:        {"readln",                      js_readln,                      0,      JSTYPE_STRING,  JSDOCSTR("[maxlen=<tt>512</tt>]")
                   2154:        ,JSDOCSTR("read a line-feed terminated string, <i>maxlen</i> defaults to 512 characters")
                   2155:        ,310
                   2156:        },              
1.1.1.2 ! root     2157:        {"readBin",                     js_readbin,                     0,      JSTYPE_NUMBER,  JSDOCSTR("[bytes=<tt>4</tt> [,count=<tt>1</tt>]")
        !          2158:        ,JSDOCSTR("read one or more binary integers from the file, default number of <i>bytes</i> is 4 (32-bits). "
        !          2159:                          "if count is not equal to 1, an array is returned (even if no integers were read)")
1.1       root     2160:        ,310
                   2161:        },
                   2162:        {"readAll",                     js_readall,                     0,      JSTYPE_ARRAY,   JSDOCSTR("[maxlen=<tt>512</tt>]")
                   2163:        ,JSDOCSTR("read all lines into an array of strings, <i>maxlen</i> defaults to 512 characters")
                   2164:        ,310
                   2165:        },
                   2166:        {"write",                       js_write,                       1,      JSTYPE_BOOLEAN, JSDOCSTR("text [,length=<i>text_length</i>]")
                   2167:        ,JSDOCSTR("write a string to the file (optionally unix-to-unix or base64 decoding in the process)")
                   2168:        ,310
                   2169:        },
                   2170:        {"writeln",                     js_writeln,                     0,      JSTYPE_BOOLEAN, JSDOCSTR("[text]")
                   2171:        ,JSDOCSTR("write a line-feed terminated string to the file")
                   2172:        ,310
                   2173:        },
1.1.1.2 ! root     2174:        {"writeBin",            js_writebin,            1,      JSTYPE_BOOLEAN, JSDOCSTR("value(s) [,bytes=<tt>4</tt>]")
        !          2175:        ,JSDOCSTR("write one or more binary integers to the file, default number of <i>bytes</i> is 4 (32-bits)."
        !          2176:                          "If value is an array, writes the entire array to the file.")
1.1       root     2177:        ,310
                   2178:        },
                   2179:        {"writeAll",            js_writeall,            0,      JSTYPE_BOOLEAN, JSDOCSTR("array lines")
                   2180:        ,JSDOCSTR("write an array of strings to file")
                   2181:        ,310
                   2182:        },              
                   2183:        {"printf",                      js_fprintf,                     0,      JSTYPE_NUMBER,  JSDOCSTR("format [,args]")
                   2184:        ,JSDOCSTR("write a formatted string to the file (ala fprintf) - "
                   2185:                "<small>CAUTION: for experienced C programmers ONLY</small>")
                   2186:        ,310
                   2187:        },
                   2188:        {"iniGetSections",      js_iniGetSections,      0,      JSTYPE_ARRAY,   JSDOCSTR("[prefix=<i>none</i>]")
                   2189:        ,JSDOCSTR("parse all section names from a <tt>.ini</tt> file (format = '<tt>[section]</tt>') "
                   2190:                "and return the section names as an <i>array of strings</i>, "
                   2191:                "optionally, only those section names that begin with the specified <i>prefix</i>")
                   2192:        ,311
                   2193:        },
                   2194:        {"iniGetKeys",          js_iniGetKeys,          1,      JSTYPE_ARRAY,   JSDOCSTR("[section=<i>root</i>]")
                   2195:        ,JSDOCSTR("parse all key names from the specified <i>section</i> in a <tt>.ini</tt> file "
                   2196:                "and return the key names as an <i>array of strings</i>. "
                   2197:                "if <i>section</i> is undefined, returns key names from the <i>root</i> section")
                   2198:        ,311
                   2199:        },
                   2200:        {"iniGetValue",         js_iniGetValue,         3,      JSTYPE_UNDEF,   JSDOCSTR("section, key [,default=<i>none</i>]")
                   2201:        ,JSDOCSTR("parse a key from a <tt>.ini</tt> file and return its value (format = '<tt>key = value</tt>'). "
                   2202:                "returns the specified <i>default</i> value if the key or value is missing or invalid. "
                   2203:                "to parse a key from the <i>root</i> section, pass <i>null</i> for <i>section</i>. "
                   2204:                "will return a <i>bool</i>, <i>number</i>, <i>string</i>, or an <i>array of strings</i> "
                   2205:                "determined by the type of <i>default</i> value specified")
                   2206:        ,311
                   2207:        },
                   2208:        {"iniSetValue",         js_iniSetValue,         3,      JSTYPE_BOOLEAN, JSDOCSTR("section, key, [value=<i>none</i>]")
                   2209:        ,JSDOCSTR("set the specified <i>key</i> to the specified <i>value</i> in the specified <i>section</i> "
                   2210:                "of a <tt>.ini</tt> file. "
                   2211:                "to set a key in the <i>root</i> section, pass <i>null</i> for <i>section</i>. ")
                   2212:        ,312
                   2213:        },
                   2214:        {"iniGetObject",        js_iniGetObject,        1,      JSTYPE_OBJECT,  JSDOCSTR("[section=<i>root</i>]")
                   2215:        ,JSDOCSTR("parse an entire section from a .ini file "
                   2216:                "and return all of its keys and values as properties of an object. "
                   2217:                "if <i>section</i> is undefined, returns key and values from the <i>root</i> section")
                   2218:        ,311
                   2219:        },
                   2220:        {"iniSetObject",        js_iniSetObject,        2,      JSTYPE_BOOLEAN, JSDOCSTR("section, object")
                   2221:        ,JSDOCSTR("write all the properties of the specified <i>object</i> as separate <tt>key=value</tt> pairs "
                   2222:                "in the specified <i>section</i> of a <tt>.ini</tt> file. "
                   2223:                "to write an object in the <i>root</i> section, pass <i>null</i> for <i>section</i>. ")
                   2224:        ,312
                   2225:        },
                   2226:        {"iniGetAllObjects",js_iniGetAllObjects,1,      JSTYPE_ARRAY,   JSDOCSTR("[name_property] [,prefix=<i>none</i>]")
                   2227:        ,JSDOCSTR("parse all sections from a .ini file and return all (non-<i>root</i>) sections "
                   2228:                "in an array of objects with each section's keys as properties of each object. "
                   2229:                "<i>name_property</i> is the name of the property to create to contain the section's name "
                   2230:                "(default is <tt>\"name\"</tt>), "
                   2231:                "the optional <i>prefix</i> has the same use as in the <tt>iniGetSections</tt> method, "
                   2232:                "if a <i>prefix</i> is specified, it is removed from each section's name" )
                   2233:        ,311
                   2234:        },
                   2235:        {"iniSetAllObjects",js_iniSetAllObjects,1,      JSTYPE_ARRAY,   JSDOCSTR("object array [,name_property=<tt>\"name\"</tt>]")
                   2236:        ,JSDOCSTR("write an array of objects to a .ini file, each object in its own section named "
                   2237:        "after the object's <i>name_property</i> (default: <tt>name</tt>)")
                   2238:        ,312
                   2239:        },
                   2240:        {"iniRemoveKey",        js_iniRemoveKey,        2,      JSTYPE_BOOLEAN, JSDOCSTR("section, key")
                   2241:        ,JSDOCSTR("remove specified <i>key</i> from specified <i>section</i> in <tt>.ini</tt> file.")
                   2242:        ,314
                   2243:        },
                   2244:        {"iniRemoveSection",js_iniRemoveSection,1,      JSTYPE_BOOLEAN, JSDOCSTR("section")
                   2245:        ,JSDOCSTR("remove specified <i>section</i> from <tt>.ini</tt> file.")
                   2246:        ,314
                   2247:        },
                   2248:        {0}
                   2249: };
                   2250: 
                   2251: /* File Destructor */
                   2252: 
                   2253: static void js_finalize_file(JSContext *cx, JSObject *obj)
                   2254: {
                   2255:        private_t* p;
                   2256:        
                   2257:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                   2258:                return;
                   2259: 
                   2260:        if(p->external==JS_FALSE && p->fp!=NULL)
                   2261:                fclose(p->fp);
                   2262: 
                   2263:        dbprintf(FALSE, p, "closed: %s",p->name);
                   2264: 
                   2265:        free(p);
                   2266: 
                   2267:        JS_SetPrivate(cx, obj, NULL);
                   2268: }
                   2269: 
1.1.1.2 ! root     2270: static JSBool js_file_resolve(JSContext *cx, JSObject *obj, jsval id)
        !          2271: {
        !          2272:        char*                   name=NULL;
        !          2273: 
        !          2274:        if(id != JSVAL_NULL)
        !          2275:                name=JS_GetStringBytes(JSVAL_TO_STRING(id));
        !          2276: 
        !          2277:        return(js_SyncResolve(cx, obj, name, js_file_properties, js_file_functions, NULL, 0));
        !          2278: }
        !          2279: 
        !          2280: static JSBool js_file_enumerate(JSContext *cx, JSObject *obj)
        !          2281: {
        !          2282:        return(js_file_resolve(cx, obj, JSVAL_NULL));
        !          2283: }
        !          2284: 
1.1       root     2285: static JSClass js_file_class = {
                   2286:      "File"                                    /* name                 */
                   2287:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                   2288:        ,JS_PropertyStub                /* addProperty  */
                   2289:        ,JS_PropertyStub                /* delProperty  */
                   2290:        ,js_file_get                    /* getProperty  */
                   2291:        ,js_file_set                    /* setProperty  */
1.1.1.2 ! root     2292:        ,js_file_enumerate              /* enumerate    */
        !          2293:        ,js_file_resolve                /* resolve              */
1.1       root     2294:        ,JS_ConvertStub                 /* convert              */
                   2295:        ,js_finalize_file               /* finalize             */
                   2296: };
                   2297: 
                   2298: /* File Constructor (creates file descriptor) */
                   2299: 
                   2300: static JSBool
                   2301: js_file_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   2302: {
                   2303:        JSString*       str;
                   2304:        private_t*      p;
                   2305: 
                   2306:        if((str = JS_ValueToString(cx, argv[0]))==NULL) {
                   2307:                JS_ReportError(cx,"No filename specified");
                   2308:                return(JS_FALSE);
                   2309:        }
                   2310: 
                   2311:        if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL) {
                   2312:                JS_ReportError(cx,"calloc failed");
                   2313:                return(JS_FALSE);
                   2314:        }
                   2315: 
                   2316:        SAFECOPY(p->name,JS_GetStringBytes(str));
                   2317: 
                   2318:        if(!JS_SetPrivate(cx, obj, p)) {
                   2319:                dbprintf(TRUE, p, "JS_SetPrivate failed");
                   2320:                return(JS_FALSE);
                   2321:        }
                   2322: 
                   2323: #ifdef BUILD_JSDOCS
                   2324:        js_DescribeSyncObject(cx,obj,"Class used for opening, creating, reading, or writing files on the local file system<p>"
                   2325:                "Special features include:</h2><ol type=disc>"
                   2326:                        "<li>Exclusive-access files (default) or shared files<ol type=circle>"
                   2327:                                "<li>optional record-locking"
                   2328:                                "<li>buffered or non-buffered I/O"
                   2329:                                "</ol>"
                   2330:                        "<li>Support for binary files<ol type=circle>"
                   2331:                                "<li>native or network byte order (endian)"
                   2332:                                "<li>automatic Unix-to-Unix (<i>UUE</i>), yEncode (<i>yEnc</i>) or Base64 encoding/decoding"
                   2333:                                "</ol>"
                   2334:                        "<li>Support for ASCII text files<ol type=circle>"
                   2335:                                "<li>supports line-based I/O<ol type=square>"
                   2336:                                        "<li>entire file may be read or written as an array of strings"
                   2337:                                        "<li>individual lines may be read or written one line at a time"
                   2338:                                        "</ol>"
                   2339:                                "<li>supports fixed-length records<ol type=square>"
                   2340:                                        "<li>optional end-of-text (<i>etx</i>) character for automatic record padding/termination"
                   2341:                                        "<li>Synchronet <tt>.dat</tt> files use an <i>etx</i> value of 3 (Ctrl-C)"
                   2342:                                        "</ol>"
                   2343:                                "<li>supports <tt>.ini</tt> formated configuration files<ol type=square>"
                   2344:                                        "<li>concept and support of <i>root</i> ini sections added in v3.12"
                   2345:                                        "</ol>"
                   2346:                                "<li>optional ROT13 encoding/translation"
                   2347:                                "</ol>"
                   2348:                        "<li>Dynamically-calculated industry standard checksums (e.g. CRC-16, CRC-32, MD5)"
                   2349:                        "</ol>"
                   2350:                        ,310
                   2351:                        );
                   2352:        js_DescribeSyncConstructor(cx,obj,"To create a new File object: <tt>var f = new File(<i>filename</i>)</tt>");
                   2353:        js_CreateArrayOfStrings(cx, obj, "_property_desc_list", file_prop_desc, JSPROP_READONLY);
                   2354: #endif
                   2355: 
                   2356:        dbprintf(FALSE, p, "object constructed");
                   2357:        return(JS_TRUE);
                   2358: }
                   2359: 
                   2360: JSObject* DLLCALL js_CreateFileClass(JSContext* cx, JSObject* parent)
                   2361: {
                   2362:        JSObject*       sockobj;
                   2363: 
                   2364:        sockobj = JS_InitClass(cx, parent, NULL
                   2365:                ,&js_file_class
                   2366:                ,js_file_constructor
                   2367:                ,1              /* number of constructor args */
                   2368:                ,NULL   /* props, set in constructor */
                   2369:                ,NULL   /* funcs, set in constructor */
                   2370:                ,NULL,NULL);
                   2371: 
                   2372:        return(sockobj);
                   2373: }
                   2374: 
                   2375: JSObject* DLLCALL js_CreateFileObject(JSContext* cx, JSObject* parent, char *name, FILE* fp)
                   2376: {
                   2377:        JSObject* obj;
                   2378:        private_t*      p;
                   2379: 
                   2380:        obj = JS_DefineObject(cx, parent, name, &js_file_class, NULL
                   2381:                ,JSPROP_ENUMERATE|JSPROP_READONLY);
                   2382: 
                   2383:        if(obj==NULL)
                   2384:                return(NULL);
                   2385: 
                   2386:        if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL)
                   2387:                return(NULL);
                   2388: 
                   2389:        p->fp=fp;
                   2390:        p->debug=JS_FALSE;
                   2391:        p->external=JS_TRUE;
                   2392: 
                   2393:        if(!JS_SetPrivate(cx, obj, p)) {
                   2394:                dbprintf(TRUE, p, "JS_SetPrivate failed");
                   2395:                return(NULL);
                   2396:        }
                   2397: 
                   2398:        dbprintf(FALSE, p, "object created");
                   2399: 
                   2400:        return(obj);
                   2401: }
                   2402: 
                   2403: 
                   2404: #endif /* JAVSCRIPT */

unix.superglobalmegacorp.com

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