--- sbbs/src/sbbs3/js_file.c 2018/04/24 16:41:24 1.1.1.1 +++ sbbs/src/sbbs3/js_file.c 2018/04/24 16:43:49 1.1.1.2 @@ -2,13 +2,13 @@ /* Synchronet JavaScript "File" Object */ -/* $Id: js_file.c,v 1.1.1.1 2018/04/24 16:41:24 root Exp $ */ +/* $Id: js_file.c,v 1.1.1.2 2018/04/24 16:43:49 root Exp $ */ /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * * * - * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * + * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * @@ -44,6 +44,7 @@ #ifdef JAVASCRIPT +#include "js_request.h" #include "jsdate.h" /* Yes, I know this is a private header file */ typedef struct @@ -59,6 +60,7 @@ typedef struct BOOL uuencoded; BOOL b64encoded; BOOL network_byte_order; + BOOL pipe; /* Opened with popen() use pclose() to close */ } private_t; @@ -134,6 +136,7 @@ js_open(JSContext *cx, JSObject *obj, ui jsint bufsize=2*1024; JSString* str; private_t* p; + jsrefcount rc; *rval = JSVAL_FALSE; @@ -161,11 +164,15 @@ js_open(JSContext *cx, JSObject *obj, ui } SAFECOPY(p->mode,mode); + rc=JS_SUSPENDREQUEST(cx); if(shareable) p->fp=fopen(p->name,p->mode); else { if((file=nopen(p->name,fopenflags(p->mode)))!=-1) { - if((p->fp=fdopen(file,p->mode))==NULL) + char fdomode[4]; + SAFECOPY(fdomode,p->mode); + fdomode[strspn(fdomode,"abrwt+")]=0; /* MSVC10 fdopen() asserts when passed a mode with an unsupported char (e.g. 'e') */ + if((p->fp=fdopen(file,fdomode))==NULL) close(file); } } @@ -177,15 +184,67 @@ js_open(JSContext *cx, JSObject *obj, ui else setvbuf(p->fp,NULL,_IOFBF,bufsize); } + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } +static JSBool +js_popen(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char* mode="r+"; /* default mode */ + uintN i; + jsint bufsize=2*1024; + JSString* str; + private_t* p; + jsrefcount rc; + + *rval = JSVAL_FALSE; + + if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { + JS_ReportError(cx,getprivate_failure,WHERE); + return(JS_FALSE); + } + + if(p->fp!=NULL) + return(JS_TRUE); + + for(i=0;imode,mode); + + rc=JS_SUSPENDREQUEST(cx); + p->fp=popen(p->name,p->mode); + if(p->fp!=NULL) { + p->pipe=TRUE; + *rval = JSVAL_TRUE; + dbprintf(FALSE, p, "popened: %s",p->name); + if(!bufsize) + setvbuf(p->fp,NULL,_IONBF,0); /* no buffering */ + else + setvbuf(p->fp,NULL,_IOFBF,bufsize); + } + JS_RESUMEREQUEST(cx, rc); + + return(JS_TRUE); +} static JSBool js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { private_t* p; + jsrefcount rc; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -195,11 +254,18 @@ js_close(JSContext *cx, JSObject *obj, u if(p->fp==NULL) return(JS_TRUE); - fclose(p->fp); + rc=JS_SUSPENDREQUEST(cx); +#ifdef __unix__ + if(p->pipe) + pclose(p->fp); + else +#endif + fclose(p->fp); dbprintf(FALSE, p, "closed"); p->fp=NULL; + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -215,6 +281,7 @@ js_read(JSContext *cx, JSObject *obj, ui int32 uulen; JSString* str; private_t* p; + jsrefcount rc; *rval = JSVAL_NULL; @@ -230,10 +297,12 @@ js_read(JSContext *cx, JSObject *obj, ui if(!JS_ValueToInt32(cx,argv[0],&len)) return(JS_FALSE); } else { - len=filelength(fileno(p->fp)); - offset=ftell(p->fp); + rc=JS_SUSPENDREQUEST(cx); + len=(long)filelength(fileno(p->fp)); + offset=(long)ftell(p->fp); if(offset>0) len-=offset; + JS_RESUMEREQUEST(cx, rc); } if(len<0) len=512; @@ -241,6 +310,7 @@ js_read(JSContext *cx, JSObject *obj, ui if((buf=malloc(len+1))==NULL) return(JS_TRUE); + rc=JS_SUSPENDREQUEST(cx); len = fread(buf,1,len,p->fp); if(len<0) len=0; @@ -259,6 +329,7 @@ js_read(JSContext *cx, JSObject *obj, ui uulen=len*2; if((uubuf=malloc(uulen))==NULL) { free(buf); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } if(p->uuencoded) @@ -275,6 +346,7 @@ js_read(JSContext *cx, JSObject *obj, ui else free(uubuf); } + JS_RESUMEREQUEST(cx, rc); str = JS_NewStringCopyN(cx, buf, len); free(buf); @@ -284,7 +356,9 @@ js_read(JSContext *cx, JSObject *obj, ui *rval = STRING_TO_JSVAL(str); + rc=JS_SUSPENDREQUEST(cx); dbprintf(FALSE, p, "read %u bytes",len); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -297,6 +371,7 @@ js_readln(JSContext *cx, JSObject *obj, int32 len=512; JSString* js_str; private_t* p; + jsrefcount rc; *rval = JSVAL_NULL; @@ -316,6 +391,7 @@ js_readln(JSContext *cx, JSObject *obj, if((buf=alloca(len))==NULL) return(JS_TRUE); + rc=JS_SUSPENDREQUEST(cx); if(fgets(buf,len,p->fp)!=NULL) { len=strlen(buf); while(len>0 && (buf[len-1]=='\r' || buf[len-1]=='\n')) @@ -327,8 +403,11 @@ js_readln(JSContext *cx, JSObject *obj, } if(p->rot13) rot13(buf); + JS_RESUMEREQUEST(cx, rc); if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL) /* exception here Feb-12-2005 */ *rval = STRING_TO_JSVAL(js_str); /* _CrtDbgBreak from _heap_alloc_dbg */ + } else { + JS_RESUMEREQUEST(cx, rc); } return(JS_TRUE); @@ -337,11 +416,18 @@ js_readln(JSContext *cx, JSObject *obj, static JSBool js_readbin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - BYTE b; - WORD w; - DWORD l; + BYTE *b; + WORD *w; + DWORD *l; size_t size=sizeof(DWORD); private_t* p; + size_t count=1; + size_t retlen; + void *buffer=NULL; + size_t i; + JSObject* array; + jsval v; + jsrefcount rc; *rval = INT_TO_JSVAL(-1); @@ -356,29 +442,74 @@ js_readbin(JSContext *cx, JSObject *obj, if(argc) { if(!JS_ValueToInt32(cx,argv[0],(int32*)&size)) return(JS_FALSE); + if(argc>1) { + if(!JS_ValueToInt32(cx,argv[1],(int32*)&count)) + return(JS_FALSE); + } + } + + rc=JS_SUSPENDREQUEST(cx); + if(size != sizeof(BYTE) && size != sizeof(WORD) && size != sizeof(DWORD)) { + /* unknown size */ + dbprintf(TRUE, p, "unsupported binary read size: %d",size); + JS_RESUMEREQUEST(cx, rc); + return(JS_TRUE); } - switch(size) { - case sizeof(BYTE): - if(fread(&b,1,size,p->fp)==size) - *rval = INT_TO_JSVAL(b); - break; - case sizeof(WORD): - if(fread(&w,1,size,p->fp)==size) { - if(p->network_byte_order) - w=ntohs(w); - *rval = INT_TO_JSVAL(w); + buffer=malloc(size*count); + if(buffer==NULL) { + dbprintf(TRUE, p, "malloc failure of %u bytes", size*count); + JS_RESUMEREQUEST(cx, rc); + return(JS_FALSE); + } + b=buffer; + w=buffer; + l=buffer; + retlen=fread(buffer, size, count, p->fp); + if(count==1) { + if(retlen==1) { + switch(size) { + case sizeof(BYTE): + *rval = INT_TO_JSVAL(*b); + break; + case sizeof(WORD): + *rval = INT_TO_JSVAL(*w); + break; + case sizeof(DWORD): + JS_RESUMEREQUEST(cx, rc); + JS_NewNumberValue(cx,*l,rval); + rc=JS_SUSPENDREQUEST(cx); + break; } - break; - case sizeof(DWORD): - if(fread(&l,1,size,p->fp)==size) { - if(p->network_byte_order) - l=ntohl(l); - JS_NewNumberValue(cx,l,rval); + } + } + else { + JS_RESUMEREQUEST(cx, rc); + array = JS_NewArrayObject(cx, 0, NULL); + + for(i=0; ifp,section,key,NULL,buf)); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -492,37 +630,53 @@ js_iniGetValue(JSContext *cx, JSObject * iniReadBool(p->fp,section,key,JSVAL_TO_BOOLEAN(dflt))); break; case JSVAL_DOUBLE: + rc=JS_SUSPENDREQUEST(cx); + dbl=iniReadFloat(p->fp,section,key,*JSVAL_TO_DOUBLE(dflt)); + JS_RESUMEREQUEST(cx, rc); JS_NewNumberValue(cx - ,iniReadFloat(p->fp,section,key,*JSVAL_TO_DOUBLE(dflt)),rval); + ,dbl,rval); break; case JSVAL_OBJECT: if((dflt_obj = JSVAL_TO_OBJECT(dflt))!=NULL && js_DateIsValid(cx, dflt_obj)) { - date_obj = js_NewDateObjectMsec(cx - ,(jsdouble)iniReadDateTime(p->fp,section,key - ,(time_t)(js_DateGetMsecSinceEpoch(cx,dflt_obj)/1000.0)) - *1000.0); + tt=(time_t)(js_DateGetMsecSinceEpoch(cx,dflt_obj)/1000.0); + rc=JS_SUSPENDREQUEST(cx); + dbl=iniReadDateTime(p->fp,section,key,tt); + JS_RESUMEREQUEST(cx, rc); + date_obj = js_NewDateObjectMsec(cx, dbl); if(date_obj!=NULL) *rval = OBJECT_TO_JSVAL(date_obj); break; } array = JS_NewArrayObject(cx, 0, NULL); - list=iniReadStringList(p->fp,section,key,",",JS_GetStringBytes(JS_ValueToString(cx,dflt))); + cstr=JS_GetStringBytes(JS_ValueToString(cx,dflt)); + rc=JS_SUSPENDREQUEST(cx); + list=iniReadStringList(p->fp,section,key,",",cstr); + JS_RESUMEREQUEST(cx, rc); for(i=0;list && list[i];i++) { val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i])); if(!JS_SetElement(cx, array, i, &val)) break; } + rc=JS_SUSPENDREQUEST(cx); iniFreeStringList(list); + JS_RESUMEREQUEST(cx, rc); *rval = OBJECT_TO_JSVAL(array); break; default: if(JSVAL_IS_NUMBER(dflt)) { if(!JS_ValueToInt32(cx,dflt,&i)) return(JS_FALSE); - JS_NewNumberValue(cx,iniReadInteger(p->fp,section,key,i),rval); - } else - *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx - ,iniReadString(p->fp,section,key,JS_GetStringBytes(JS_ValueToString(cx,dflt)),buf))); + rc=JS_SUSPENDREQUEST(cx); + i=iniReadInteger(p->fp,section,key,i); + JS_RESUMEREQUEST(cx, rc); + JS_NewNumberValue(cx,i,rval); + } else { + cstr=JS_GetStringBytes(JS_ValueToString(cx,dflt)); + rc=JS_SUSPENDREQUEST(cx); + cstr2=iniReadString(p->fp,section,key,cstr,buf); + JS_RESUMEREQUEST(cx, rc); + *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cstr2)); + } break; } @@ -540,6 +694,9 @@ js_iniSetValue(JSContext *cx, JSObject * private_t* p; str_list_t list; JSObject* value_obj; + jsrefcount rc; + char* cstr; + time_t tt; *rval = JSVAL_FALSE; @@ -555,11 +712,18 @@ js_iniSetValue(JSContext *cx, JSObject * section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); key=JS_GetStringBytes(JS_ValueToString(cx, argv[1])); - if((list=iniReadFile(p->fp))==NULL) + rc=JS_SUSPENDREQUEST(cx); + if((list=iniReadFile(p->fp))==NULL) { + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); + } + JS_RESUMEREQUEST(cx, rc); - if(value==JSVAL_VOID) /* unspecified value */ + if(value==JSVAL_VOID) { /* unspecified value */ + rc=JS_SUSPENDREQUEST(cx); result = iniSetString(&list,section,key,"",NULL); + JS_RESUMEREQUEST(cx, rc); + } else { switch(JSVAL_TAG(value)) { @@ -573,25 +737,34 @@ js_iniSetValue(JSContext *cx, JSObject * if(JSVAL_IS_NUMBER(value)) { if(!JS_ValueToInt32(cx,value,&i)) return(JS_FALSE); + rc=JS_SUSPENDREQUEST(cx); result = iniSetInteger(&list,section,key,i,NULL); + JS_RESUMEREQUEST(cx, rc); } else { if(JSVAL_IS_OBJECT(value) && (value_obj = JSVAL_TO_OBJECT(value))!=NULL && js_DateIsValid(cx, value_obj)) { - result = iniSetDateTime(&list,section,key,/* include_time */TRUE - ,(time_t)(js_DateGetMsecSinceEpoch(cx,value_obj)/1000.0),NULL); - } else - result = iniSetString(&list,section,key - ,JS_GetStringBytes(JS_ValueToString(cx,value)),NULL); + tt=(time_t)(js_DateGetMsecSinceEpoch(cx,value_obj)/1000.0); + rc=JS_SUSPENDREQUEST(cx); + result = iniSetDateTime(&list,section,key,/* include_time */TRUE, tt,NULL); + JS_RESUMEREQUEST(cx, rc); + } else { + cstr=JS_GetStringBytes(JS_ValueToString(cx,value)); + rc=JS_SUSPENDREQUEST(cx); + result = iniSetString(&list,section,key, cstr,NULL); + JS_RESUMEREQUEST(cx, rc); + } } break; } } + rc=JS_SUSPENDREQUEST(cx); if(result != NULL) *rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list)); strListFree(&list); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -603,6 +776,7 @@ js_iniRemoveKey(JSContext *cx, JSObject char* key; private_t* p; str_list_t list; + jsrefcount rc; *rval = JSVAL_FALSE; @@ -618,13 +792,17 @@ js_iniRemoveKey(JSContext *cx, JSObject section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); key=JS_GetStringBytes(JS_ValueToString(cx, argv[1])); - if((list=iniReadFile(p->fp))==NULL) + rc=JS_SUSPENDREQUEST(cx); + if((list=iniReadFile(p->fp))==NULL) { + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); + } if(iniRemoveKey(&list,section,key)) *rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list)); strListFree(&list); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -635,6 +813,7 @@ js_iniRemoveSection(JSContext *cx, JSObj char* section=ROOT_SECTION; private_t* p; str_list_t list; + jsrefcount rc; *rval = JSVAL_FALSE; @@ -649,13 +828,17 @@ js_iniRemoveSection(JSContext *cx, JSObj if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL) section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); - if((list=iniReadFile(p->fp))==NULL) + rc=JS_SUSPENDREQUEST(cx); + if((list=iniReadFile(p->fp))==NULL) { + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); + } if(iniRemoveSection(&list,section)) *rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list)); strListFree(&list); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -670,6 +853,7 @@ js_iniGetSections(JSContext *cx, JSObjec jsval val; JSObject* array; private_t* p; + jsrefcount rc; *rval = JSVAL_NULL; @@ -686,13 +870,17 @@ js_iniGetSections(JSContext *cx, JSObjec array = JS_NewArrayObject(cx, 0, NULL); + rc=JS_SUSPENDREQUEST(cx); list = iniReadSectionList(p->fp,prefix); + JS_RESUMEREQUEST(cx, rc); for(i=0;list && list[i];i++) { val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i])); if(!JS_SetElement(cx, array, i, &val)) break; } + rc=JS_SUSPENDREQUEST(cx); iniFreeStringList(list); + JS_RESUMEREQUEST(cx, rc); *rval = OBJECT_TO_JSVAL(array); @@ -708,6 +896,7 @@ js_iniGetKeys(JSContext *cx, JSObject *o jsval val; JSObject* array; private_t* p; + jsrefcount rc; *rval = JSVAL_NULL; @@ -723,13 +912,17 @@ js_iniGetKeys(JSContext *cx, JSObject *o section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); array = JS_NewArrayObject(cx, 0, NULL); + rc=JS_SUSPENDREQUEST(cx); list = iniReadKeyList(p->fp,section); + JS_RESUMEREQUEST(cx, rc); for(i=0;list && list[i];i++) { val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i])); if(!JS_SetElement(cx, array, i, &val)) break; } + rc=JS_SUSPENDREQUEST(cx); iniFreeStringList(list); + JS_RESUMEREQUEST(cx, rc); *rval = OBJECT_TO_JSVAL(array); @@ -744,6 +937,7 @@ js_iniGetObject(JSContext *cx, JSObject JSObject* object; private_t* p; named_string_t** list; + jsrefcount rc; *rval = JSVAL_NULL; @@ -757,16 +951,27 @@ js_iniGetObject(JSContext *cx, JSObject if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL) section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); - object = JS_NewObject(cx, NULL, NULL, obj); + rc=JS_SUSPENDREQUEST(cx); list = iniReadNamedStringList(p->fp,section); + JS_RESUMEREQUEST(cx, rc); + + if(list==NULL) { /* New behavior at request of MCMLXXIX: return NULL/undefined if specified section doesn't exist */ + *rval = JSVAL_NULL; + return(JS_TRUE); + } + + object = JS_NewObject(cx, NULL, NULL, obj); + for(i=0;list && list[i];i++) { JS_DefineProperty(cx, object, list[i]->name ,get_value(cx,list[i]->value) ,NULL,NULL,JSPROP_ENUMERATE); } + rc=JS_SUSPENDREQUEST(cx); iniFreeNamedStringList(list); + JS_RESUMEREQUEST(cx, rc); *rval = OBJECT_TO_JSVAL(object); @@ -821,6 +1026,7 @@ js_iniGetAllObjects(JSContext *cx, JSObj JSObject* object; private_t* p; named_string_t** key_list; + jsrefcount rc; *rval = JSVAL_NULL; @@ -840,7 +1046,9 @@ js_iniGetAllObjects(JSContext *cx, JSObj array = JS_NewArrayObject(cx, 0, NULL); + rc=JS_SUSPENDREQUEST(cx); sec_list = iniReadSectionList(p->fp,prefix); + JS_RESUMEREQUEST(cx, rc); for(i=0;sec_list && sec_list[i];i++) { object = JS_NewObject(cx, NULL, NULL, obj); @@ -851,18 +1059,65 @@ js_iniGetAllObjects(JSContext *cx, JSObj ,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,sec_name)) ,NULL,NULL,JSPROP_ENUMERATE); + rc=JS_SUSPENDREQUEST(cx); key_list = iniReadNamedStringList(p->fp,sec_list[i]); + JS_RESUMEREQUEST(cx, rc); for(k=0;key_list && key_list[k];k++) JS_DefineProperty(cx, object, key_list[k]->name ,get_value(cx,key_list[k]->value) ,NULL,NULL,JSPROP_ENUMERATE); + rc=JS_SUSPENDREQUEST(cx); iniFreeNamedStringList(key_list); + JS_RESUMEREQUEST(cx, rc); val=OBJECT_TO_JSVAL(object); + /* exception here, Apr-4-2010: + + 2000007a() +js_iniGetAllObjects(JSContext * 0x049383e0, JSObject * 0x049c76a8, unsigned int 0x00000001, long * 0x049c0490, long * 0x02c5c494) line 1064 + 24 bytes +js_Invoke(JSContext * 0x049383e0, unsigned int 0x00000001, unsigned int 0x00000000) line 1375 + 23 bytes +js_Interpret(JSContext * 0x049383e0, unsigned char * 0x031ab4b2, long * 0x02c5d6ac) line 3944 + 15 bytes +js_Execute(JSContext * 0x049383e0, JSObject * 0x049b73e8, JSScript * 0x02f2a7e0, JSStackFrame * 0x00000000, unsigned int 0x00000000, long * 0x02c5d7bc) line 1633 + 19 bytes +JS_ExecuteScript(JSContext * 0x049383e0, JSObject * 0x049b73e8, JSScript * 0x02f2a7e0, long * 0x02c5d7bc) line 4188 + 25 bytes +sbbs_t::js_execfile(const char * 0x0226b59a, const char * 0x022060fa) line 668 + 39 bytes +sbbs_t::external(const char * 0x0226b599, long 0x00000100, const char * 0x022060fa) line 413 + 30 bytes +event_thread(void * 0x022622b8) line 2745 + 113 bytes +_threadstart(void * 0x0227dab0) line 187 + 13 bytes + + +and July-15-2010: + + 20000000() + js32.dll!JS_SetElement(JSContext * cx, JSObject * obj, long index, long * vp) Line 3178 + 0x20 bytes C +> sbbs.dll!js_iniGetAllObjects(JSContext * cx, JSObject * obj, unsigned int argc, long * argv, long * rval) Line 1081 + 0x18 bytes C + js32.dll!js_Invoke(JSContext * cx, unsigned int argc, unsigned int flags) Line 1375 + 0x17 bytes C + js32.dll!js_Interpret(JSContext * cx, unsigned char * pc, long * result) Line 3944 + 0xf bytes C + js32.dll!js_Execute(JSContext * cx, JSObject * chain, JSScript * script, JSStackFrame * down, unsigned int flags, long * result) Line 1633 + 0x13 bytes C + js32.dll!JS_ExecuteScript(JSContext * cx, JSObject * obj, JSScript * script, long * rval) Line 4188 + 0x19 bytes C + sbbs.dll!sbbs_t::js_execfile(const char * cmd, const char * startup_dir) Line 686 + 0x27 bytes C++ + sbbs.dll!sbbs_t::external(const char * cmdline, long mode, const char * startup_dir) Line 413 + 0x1e bytes C++ + sbbs.dll!event_thread(void * arg) Line 2745 + 0x71 bytes C++ + +And July-22-2010: + + js32.dll!JS_SetElement(JSContext * cx, JSObject * obj, long index, long * vp) Line 3178 + 0x20 bytes C +> sbbs.dll!js_iniGetAllObjects(JSContext * cx, JSObject * obj, unsigned int argc, long * argv, long * rval) Line 1095 + 0x18 bytes C + js32.dll!js_Invoke(JSContext * cx, unsigned int argc, unsigned int flags) Line 1375 + 0x17 bytes C + js32.dll!js_Interpret(JSContext * cx, unsigned char * pc, long * result) Line 3944 + 0xf bytes C + js32.dll!js_Execute(JSContext * cx, JSObject * chain, JSScript * script, JSStackFrame * down, unsigned int flags, long * result) Line 1633 + 0x13 bytes C + js32.dll!JS_ExecuteScript(JSContext * cx, JSObject * obj, JSScript * script, long * rval) Line 4188 + 0x19 bytes C + websrvr.dll!exec_ssjs(http_session_t * session, char * script) Line 4638 + 0x24 bytes C + websrvr.dll!respond(http_session_t * session) Line 4684 + 0x12 bytes C + websrvr.dll!http_session_thread(void * arg) Line 5091 + 0xc bytes C + + + */ if(!JS_SetElement(cx, array, i, &val)) break; } + rc=JS_SUSPENDREQUEST(cx); iniFreeStringList(sec_list); + JS_RESUMEREQUEST(cx, rc); *rval = OBJECT_TO_JSVAL(array); @@ -874,13 +1129,17 @@ js_iniSetAllObjects(JSContext *cx, JSObj { char* name="name"; jsuint i; + jsint j; jsuint count; JSObject* array; - jsval set_argv[2]; + JSObject* object; + jsval oval; + jsval set_argv[3]; + JSIdArray* id_array; *rval = JSVAL_FALSE; - if(!JSVAL_IS_OBJECT(argv[0])) + if(JSVAL_IS_NULL(argv[0]) || !JSVAL_IS_OBJECT(argv[0])) return(JS_TRUE); array = JSVAL_TO_OBJECT(argv[0]); @@ -896,14 +1155,29 @@ js_iniSetAllObjects(JSContext *cx, JSObj /* enumerate the array */ for(i=0; ilength; j++) { + /* property */ + JS_IdToValue(cx,id_array->vector[j],&set_argv[1]); + /* check if not name */ + if(strcmp(JS_GetStringBytes(JS_ValueToString(cx, set_argv[1])),name)==0) + continue; + /* value */ + JS_GetProperty(cx,object,JS_GetStringBytes(JSVAL_TO_STRING(set_argv[1])),&set_argv[2]); + if(!js_iniSetValue(cx,obj,3,set_argv,rval)) + break; + } + + JS_DestroyIdArray(cx,id_array); } return(JS_TRUE); @@ -918,6 +1192,7 @@ js_write(JSContext *cx, JSObject *obj, u int tlen; /* total length to write (may be greater than len) */ JSString* str; private_t* p; + jsrefcount rc; *rval = JSVAL_FALSE; @@ -933,6 +1208,7 @@ js_write(JSContext *cx, JSObject *obj, u cp = JS_GetStringBytes(str); len = JS_GetStringLength(str); + rc=JS_SUSPENDREQUEST(cx); if((p->uuencoded || p->b64encoded || p->yencoded) && len && (uubuf=malloc(len))!=NULL) { if(p->uuencoded) @@ -943,6 +1219,7 @@ js_write(JSContext *cx, JSObject *obj, u len=b64_decode(uubuf,len,cp,len); if(len<0) { free(uubuf); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } cp=uubuf; @@ -951,6 +1228,7 @@ js_write(JSContext *cx, JSObject *obj, u if(p->rot13) rot13(cp); + JS_RESUMEREQUEST(cx, rc); tlen=len; if(argc>1) { if(!JS_ValueToInt32(cx,argv[1],(int32*)&tlen)) { @@ -961,10 +1239,12 @@ js_write(JSContext *cx, JSObject *obj, u len=tlen; } + rc=JS_SUSPENDREQUEST(cx); if(fwrite(cp,1,len,p->fp)==(size_t)len) { if(tlen>len) { len=tlen-len; if((cp=malloc(len))==NULL) { + JS_RESUMEREQUEST(cx, rc); FREE_AND_NULL(uubuf); dbprintf(TRUE, p, "malloc failure of %u bytes", len); return(JS_TRUE); @@ -979,6 +1259,7 @@ js_write(JSContext *cx, JSObject *obj, u dbprintf(TRUE, p, "write of %u bytes failed",len); FREE_AND_NULL(uubuf); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -989,6 +1270,7 @@ js_writeln(JSContext *cx, JSObject *obj, char* cp=""; JSString* str; private_t* p; + jsrefcount rc; *rval = JSVAL_FALSE; @@ -1008,11 +1290,13 @@ js_writeln(JSContext *cx, JSObject *obj, cp = JS_GetStringBytes(str); } + rc=JS_SUSPENDREQUEST(cx); if(p->rot13) rot13(cp); if(fprintf(p->fp,"%s\n",cp)!=0) *rval = JSVAL_TRUE; + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1020,13 +1304,18 @@ js_writeln(JSContext *cx, JSObject *obj, static JSBool js_writebin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - BYTE b; - WORD w; - DWORD l; - int32 val=0; + BYTE *b; + WORD *w; + DWORD *l; size_t wr=0; size_t size=sizeof(DWORD); + jsuint count=1; + void *buffer; private_t* p; + JSObject* array=NULL; + jsval elemval; + jsdouble val=0; + jsrefcount rc; *rval = JSVAL_FALSE; @@ -1038,38 +1327,79 @@ js_writebin(JSContext *cx, JSObject *obj if(p->fp==NULL) return(JS_TRUE); - if(!JS_ValueToInt32(cx,argv[0],&val)) - return(JS_FALSE); + if(JSVAL_IS_OBJECT(argv[0]) && !JSVAL_IS_NULL(argv[0])) { + array = JSVAL_TO_OBJECT(argv[0]); + if(JS_IsArrayObject(cx, array)) { + if(!JS_GetArrayLength(cx, array, &count)) + return(JS_TRUE); + } + else + array=NULL; + } + if(array==NULL) { + if(!JS_ValueToNumber(cx,argv[0],&val)) + return(JS_FALSE); + } if(argc>1) { if(!JS_ValueToInt32(cx,argv[1],(int32*)&size)) return(JS_FALSE); } - - switch(size) { - case sizeof(BYTE): - b = (BYTE)val; - wr=fwrite(&b,1,size,p->fp); - break; - case sizeof(WORD): - w = (WORD)val; - if(p->network_byte_order) - w=htons(w); - wr=fwrite(&w,1,size,p->fp); - break; - case sizeof(DWORD): - l = val; - if(p->network_byte_order) - l=htonl(l); - wr=fwrite(&l,1,size,p->fp); - break; - default: - /* unknown size */ - dbprintf(TRUE, p, "unsupported binary write size: %d",size); - break; + if(size != sizeof(BYTE) && size != sizeof(WORD) && size != sizeof(DWORD)) { + rc=JS_SUSPENDREQUEST(cx); + dbprintf(TRUE, p, "unsupported binary write size: %d",size); + JS_RESUMEREQUEST(cx, rc); + return(JS_TRUE); + } + buffer=malloc(size*count); + if(buffer==NULL) { + rc=JS_SUSPENDREQUEST(cx); + dbprintf(TRUE, p, "malloc failure of %u bytes", size*count); + JS_RESUMEREQUEST(cx, rc); + return(JS_FALSE); + } + b=buffer; + w=buffer; + l=buffer; + if(array==NULL) { + switch(size) { + case sizeof(BYTE): + *b=(BYTE)val; + break; + case sizeof(WORD): + *w=(WORD)val; + break; + case sizeof(DWORD): + *l=(DWORD)val; + break; + } } - if(wr==size) - *rval = JSVAL_TRUE; - + else { + for(wr=0; wrfp); + JS_RESUMEREQUEST(cx, rc); + if(wr==count) + *rval=JSVAL_TRUE; + +end: + free(buffer); return(JS_TRUE); } @@ -1092,7 +1422,7 @@ js_writeall(JSContext *cx, JSObject *obj if(p->fp==NULL) return(JS_TRUE); - if(!JSVAL_IS_OBJECT(argv[0])) + if(JSVAL_IS_NULL(argv[0]) || !JSVAL_IS_OBJECT(argv[0])) return(JS_TRUE); array = JSVAL_TO_OBJECT(argv[0]); @@ -1119,9 +1449,11 @@ js_writeall(JSContext *cx, JSObject *obj static JSBool js_lock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - int32 offset=0; - int32 len=0; + off_t offset=0; + off_t len=0; private_t* p; + jsrefcount rc; + jsdouble val; *rval = JSVAL_FALSE; @@ -1135,21 +1467,25 @@ js_lock(JSContext *cx, JSObject *obj, ui /* offset */ if(argc) { - if(!JS_ValueToInt32(cx,argv[0],&offset)) + if(!JS_ValueToNumber(cx,argv[0],&val)) return(JS_FALSE); + offset=(off_t)val; } /* length */ if(argc>1) { - if(!JS_ValueToInt32(cx,argv[1],&len)) + if(!JS_ValueToNumber(cx,argv[1],&val)) return(JS_FALSE); + len=(off_t)val; } + rc=JS_SUSPENDREQUEST(cx); if(len==0) len=filelength(fileno(p->fp))-offset; if(lock(fileno(p->fp),offset,len)==0) *rval = JSVAL_TRUE; + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1157,9 +1493,11 @@ js_lock(JSContext *cx, JSObject *obj, ui static JSBool js_unlock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - int32 offset=0; - int32 len=0; + off_t offset=0; + off_t len=0; private_t* p; + jsrefcount rc; + jsdouble val; *rval = JSVAL_FALSE; @@ -1173,21 +1511,25 @@ js_unlock(JSContext *cx, JSObject *obj, /* offset */ if(argc) { - if(!JS_ValueToInt32(cx,argv[0],&offset)) + if(!JS_ValueToNumber(cx,argv[0],&val)) return(JS_FALSE); + offset=(off_t)val; } /* length */ if(argc>1) { - if(!JS_ValueToInt32(cx,argv[1],&len)) + if(!JS_ValueToNumber(cx,argv[1],&val)) return(JS_FALSE); + len=(off_t)val; } + rc=JS_SUSPENDREQUEST(cx); if(len==0) len=filelength(fileno(p->fp))-offset; if(unlock(fileno(p->fp),offset,len)==0) *rval = JSVAL_TRUE; + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1196,6 +1538,7 @@ static JSBool js_delete(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { private_t* p; + jsrefcount rc; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -1207,7 +1550,9 @@ js_delete(JSContext *cx, JSObject *obj, p->fp=NULL; } + rc=JS_SUSPENDREQUEST(cx); *rval = BOOLEAN_TO_JSVAL(remove(p->name)==0); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1216,16 +1561,19 @@ static JSBool js_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { private_t* p; + jsrefcount rc; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); return(JS_FALSE); } + rc=JS_SUSPENDREQUEST(cx); if(p->fp==NULL) *rval = JSVAL_FALSE; else *rval = BOOLEAN_TO_JSVAL(fflush(p->fp)==0); + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1234,18 +1582,21 @@ static JSBool js_rewind(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { private_t* p; + jsrefcount rc; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); return(JS_FALSE); } + rc=JS_SUSPENDREQUEST(cx); if(p->fp==NULL) *rval = JSVAL_FALSE; else { *rval = JSVAL_TRUE; rewind(p->fp); } + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1255,6 +1606,7 @@ js_truncate(JSContext *cx, JSObject *obj { private_t* p; int32 len=0; + jsrefcount rc; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -1266,11 +1618,13 @@ js_truncate(JSContext *cx, JSObject *obj return(JS_FALSE); } + rc=JS_SUSPENDREQUEST(cx); *rval = JSVAL_FALSE; if(p->fp!=NULL && chsize(fileno(p->fp),len)==0) { fseek(p->fp,len,SEEK_SET); *rval = JSVAL_TRUE; } + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1279,18 +1633,21 @@ static JSBool js_clear_error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { private_t* p; + jsrefcount rc; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); return(JS_FALSE); } + rc=JS_SUSPENDREQUEST(cx); if(p->fp==NULL) *rval = JSVAL_FALSE; else { clearerr(p->fp); *rval = JSVAL_TRUE; } + JS_RESUMEREQUEST(cx, rc); return(JS_TRUE); } @@ -1300,6 +1657,7 @@ js_fprintf(JSContext *cx, JSObject *obj, { char* cp; private_t* p; + jsrefcount rc; *rval = JSVAL_FALSE; @@ -1316,7 +1674,9 @@ js_fprintf(JSContext *cx, JSObject *obj, return(JS_FALSE); } + rc=JS_SUSPENDREQUEST(cx); *rval = INT_TO_JSVAL(fwrite(cp,1,strlen(cp),p->fp)); + JS_RESUMEREQUEST(cx, rc); js_sprintf_free(cp); return(JS_TRUE); @@ -1357,6 +1717,7 @@ static JSBool js_file_set(JSContext *cx, int32 i=0; jsint tiny; private_t* p; + jsrefcount rc; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -1365,7 +1726,9 @@ static JSBool js_file_set(JSContext *cx, tiny = JSVAL_TO_INT(id); + rc=JS_SUSPENDREQUEST(cx); dbprintf(FALSE, p, "setting property %d",tiny); + JS_RESUMEREQUEST(cx, rc); switch(tiny) { case FILE_PROP_DEBUG: @@ -1390,25 +1753,33 @@ static JSBool js_file_set(JSContext *cx, if(p->fp!=NULL) { if(!JS_ValueToInt32(cx,*vp,&i)) return(JS_FALSE); + rc=JS_SUSPENDREQUEST(cx); fseek(p->fp,i,SEEK_SET); + JS_RESUMEREQUEST(cx, rc); } break; case FILE_PROP_DATE: if(!JS_ValueToInt32(cx,*vp,&i)) return(JS_FALSE); + rc=JS_SUSPENDREQUEST(cx); setfdate(p->name,i); + JS_RESUMEREQUEST(cx, rc); break; case FILE_PROP_LENGTH: if(p->fp!=NULL) { if(!JS_ValueToInt32(cx,*vp,&i)) return(JS_FALSE); + rc=JS_SUSPENDREQUEST(cx); chsize(fileno(p->fp),i); + JS_RESUMEREQUEST(cx, rc); } break; case FILE_PROP_ATTRIBUTES: if(!JS_ValueToInt32(cx,*vp,&i)) return(JS_FALSE); + rc=JS_SUSPENDREQUEST(cx); CHMOD(p->name,i); + JS_RESUMEREQUEST(cx, rc); break; case FILE_PROP_ETX: if(!JS_ValueToInt32(cx,*vp,&i)) @@ -1425,7 +1796,7 @@ static JSBool js_file_get(JSContext *cx, char str[128]; size_t i; size_t rd; - long offset; + off_t offset; ulong sum=0; ushort c16=0; ulong c32=~0; @@ -1435,6 +1806,10 @@ static JSBool js_file_get(JSContext *cx, jsint tiny; JSString* js_str=NULL; private_t* p; + jsrefcount rc; + time_t tt; + off_t lng; + int in; if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { JS_ReportError(cx,getprivate_failure,WHERE); @@ -1461,41 +1836,63 @@ static JSBool js_file_get(JSContext *cx, case FILE_PROP_EXISTS: if(p->fp) /* open? */ *vp = JSVAL_TRUE; - else + else { + rc=JS_SUSPENDREQUEST(cx); *vp = BOOLEAN_TO_JSVAL(fexistcase(p->name)); + JS_RESUMEREQUEST(cx, rc); + } break; case FILE_PROP_DATE: - JS_NewNumberValue(cx,fdate(p->name),vp); + rc=JS_SUSPENDREQUEST(cx); + tt=fdate(p->name); + JS_RESUMEREQUEST(cx, rc); + JS_NewNumberValue(cx,tt,vp); break; case FILE_PROP_IS_OPEN: *vp = BOOLEAN_TO_JSVAL(p->fp!=NULL); break; case FILE_PROP_EOF: - if(p->fp) + if(p->fp) { + rc=JS_SUSPENDREQUEST(cx); *vp = BOOLEAN_TO_JSVAL(feof(p->fp)!=0); + JS_RESUMEREQUEST(cx, rc); + } else *vp = JSVAL_TRUE; break; case FILE_PROP_ERROR: - if(p->fp) + if(p->fp) { + rc=JS_SUSPENDREQUEST(cx); *vp = INT_TO_JSVAL(ferror(p->fp)); + JS_RESUMEREQUEST(cx, rc); + } else *vp = INT_TO_JSVAL(errno); break; case FILE_PROP_POSITION: - if(p->fp) - JS_NewNumberValue(cx,ftell(p->fp),vp); + if(p->fp) { + rc=JS_SUSPENDREQUEST(cx); + lng=ftell(p->fp); + JS_RESUMEREQUEST(cx, rc); + JS_NewNumberValue(cx,(double)lng,vp); + } else *vp = INT_TO_JSVAL(-1); break; case FILE_PROP_LENGTH: + rc=JS_SUSPENDREQUEST(cx); if(p->fp) /* open? */ - JS_NewNumberValue(cx,filelength(fileno(p->fp)),vp); + lng = filelength(fileno(p->fp)); else - JS_NewNumberValue(cx,flength(p->name),vp); + lng = flength(p->name); + JS_RESUMEREQUEST(cx, rc); + JS_NewNumberValue(cx,(double)lng,vp); break; case FILE_PROP_ATTRIBUTES: - JS_NewNumberValue(cx,getfattr(p->name),vp); + rc=JS_SUSPENDREQUEST(cx); + in=getfattr(p->name); + JS_RESUMEREQUEST(cx, rc); + JS_NewNumberValue(cx,in,vp); break; case FILE_PROP_DEBUG: *vp = BOOLEAN_TO_JSVAL(p->debug); @@ -1536,6 +1933,7 @@ static JSBool js_file_get(JSContext *cx, *vp = JSVAL_VOID; if(p->fp==NULL) break; + rc=JS_SUSPENDREQUEST(cx); offset=ftell(p->fp); /* save current file position */ fseek(p->fp,0,SEEK_SET); @@ -1570,6 +1968,7 @@ static JSBool js_file_get(JSContext *cx, break; } } + JS_RESUMEREQUEST(cx, rc); /* finalize */ switch(tiny) { @@ -1594,7 +1993,9 @@ static JSBool js_file_get(JSContext *cx, js_str=JS_NewStringCopyZ(cx, str); break; } + rc=JS_SUSPENDREQUEST(cx); fseek(p->fp,offset,SEEK_SET); /* restore saved file position */ + JS_RESUMEREQUEST(cx, rc); if(js_str!=NULL) *vp = STRING_TO_JSVAL(js_str); break; @@ -1639,7 +2040,7 @@ static jsSyncPropertySpec js_file_proper static char* file_prop_desc[] = { "filename specified in constructor - READ ONLY" ,"mode string specified in open call - READ ONLY" - ,"true if the file exists - READ ONLY" + ,"true if the file is open or exists (case-insensitive) - READ ONLY" ,"true if the file has been opened successfully - READ ONLY" ,"true if the current file position is at the end of file - READ ONLY" ,"the last occurred error value (use clear_error to clear) - READ ONLY" @@ -1679,12 +2080,36 @@ static jsSyncMethodSpec js_file_function " open a non-shareable file (that must not already exist) for exclusive access (introduced in v3.12)
" "
Note: When using the iniSet methods to modify a .ini file, " "the file must be opened for both reading and writing.
" - "
Note: To open an existing or create a new file for both reading and writing, " - "use the file_exists function like so:
" - "file.open(file_exists(file.name) ? 'r+':'w+');" + "
Note: To open an existing or create a new file for both reading and writing " + "(e.g. updating an .ini file) " + "use the exists property like so:
" + "file.open(file.exists ? 'r+':'w+');" + "
Note: When shareable is false, uses nopen() which will lock the file " + "and perform automatic retries. The lock mode is as follows:
" + " DENYWRITE - Allows other scripts to open the file for reading, but not for writing.
" + " DENYALL - Does not allow other scripts to open the file when shareable is set to true
" + " DENYALL - Does not allow other scripts to open the file when shareable is set to true
" + "r+ DENYALL - Does not allow other scripts to open the file when shareable is set to true
" + "w+ DENYALL - Does not allow other scripts to open the file when shareable is set to true
" + "a+ DENYALL - Does not allow other scripts to open the file when shareable is set to true
" + "When shareable is true uses fopen(), " + "and will only attempt to open the file once and will perform no locking. The behaviour " + "when one script has a file opened with shareable set to a different value than is used " + "with a new call is OS specific. On Windows, the second open will always fail and on *nix, " + "the second open will always succeed.
" ) ,310 }, + {"popen", js_popen, 1, JSTYPE_BOOLEAN, JSDOCSTR("[mode=\"r+\"] [,buffer_length]") + ,JSDOCSTR("open pipe to command, buffer_length defaults to 2048 bytes, " + "mode (default: 'r+') specifies the type of access requested for the file, as follows:
" + " read the programs stdout;
" + " write to the programs stdin
" + "r+ open for both reading stdout and writing stdin
" + "(only functional on UNIX systems)" + ) + ,315 + }, {"close", js_close, 0, JSTYPE_VOID, JSDOCSTR("") ,JSDOCSTR("close file") ,310 @@ -1729,8 +2154,9 @@ static jsSyncMethodSpec js_file_function ,JSDOCSTR("read a line-feed terminated string, maxlen defaults to 512 characters") ,310 }, - {"readBin", js_readbin, 0, JSTYPE_NUMBER, JSDOCSTR("[bytes=4]") - ,JSDOCSTR("read a binary integer from the file, default number of bytes is 4 (32-bits)") + {"readBin", js_readbin, 0, JSTYPE_NUMBER, JSDOCSTR("[bytes=4 [,count=1]") + ,JSDOCSTR("read one or more binary integers from the file, default number of bytes is 4 (32-bits). " + "if count is not equal to 1, an array is returned (even if no integers were read)") ,310 }, {"readAll", js_readall, 0, JSTYPE_ARRAY, JSDOCSTR("[maxlen=512]") @@ -1745,8 +2171,9 @@ static jsSyncMethodSpec js_file_function ,JSDOCSTR("write a line-feed terminated string to the file") ,310 }, - {"writeBin", js_writebin, 1, JSTYPE_BOOLEAN, JSDOCSTR("value [,bytes=4]") - ,JSDOCSTR("write a binary integer to the file, default number of bytes is 4 (32-bits)") + {"writeBin", js_writebin, 1, JSTYPE_BOOLEAN, JSDOCSTR("value(s) [,bytes=4]") + ,JSDOCSTR("write one or more binary integers to the file, default number of bytes is 4 (32-bits)." + "If value is an array, writes the entire array to the file.") ,310 }, {"writeAll", js_writeall, 0, JSTYPE_BOOLEAN, JSDOCSTR("array lines") @@ -1840,6 +2267,21 @@ static void js_finalize_file(JSContext * JS_SetPrivate(cx, obj, NULL); } +static JSBool js_file_resolve(JSContext *cx, JSObject *obj, jsval id) +{ + char* name=NULL; + + if(id != JSVAL_NULL) + name=JS_GetStringBytes(JSVAL_TO_STRING(id)); + + return(js_SyncResolve(cx, obj, name, js_file_properties, js_file_functions, NULL, 0)); +} + +static JSBool js_file_enumerate(JSContext *cx, JSObject *obj) +{ + return(js_file_resolve(cx, obj, JSVAL_NULL)); +} + static JSClass js_file_class = { "File" /* name */ ,JSCLASS_HAS_PRIVATE /* flags */ @@ -1847,8 +2289,8 @@ static JSClass js_file_class = { ,JS_PropertyStub /* delProperty */ ,js_file_get /* getProperty */ ,js_file_set /* setProperty */ - ,JS_EnumerateStub /* enumerate */ - ,JS_ResolveStub /* resolve */ + ,js_file_enumerate /* enumerate */ + ,js_file_resolve /* resolve */ ,JS_ConvertStub /* convert */ ,js_finalize_file /* finalize */ }; @@ -1866,8 +2308,6 @@ js_file_constructor(JSContext *cx, JSObj return(JS_FALSE); } - *rval = JSVAL_VOID; - if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL) { JS_ReportError(cx,"calloc failed"); return(JS_FALSE); @@ -1880,16 +2320,6 @@ js_file_constructor(JSContext *cx, JSObj return(JS_FALSE); } - if(!js_DefineSyncProperties(cx, obj, js_file_properties)) { - dbprintf(TRUE, p, "js_DefineSyncProperties failed"); - return(JS_FALSE); - } - - if(!js_DefineSyncMethods(cx, obj, js_file_functions, FALSE)) { - dbprintf(TRUE, p, "js_DefineSyncMethods failed"); - return(JS_FALSE); - } - #ifdef BUILD_JSDOCS js_DescribeSyncObject(cx,obj,"Class used for opening, creating, reading, or writing files on the local file system

" "Special features include:

    " @@ -1953,12 +2383,6 @@ JSObject* DLLCALL js_CreateFileObject(JS if(obj==NULL) return(NULL); - if(!js_DefineSyncProperties(cx, obj, js_file_properties)) - return(NULL); - - if (!js_DefineSyncMethods(cx, obj, js_file_functions, FALSE)) - return(NULL); - if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL) return(NULL);