Newer
Older
/* Synchronet JavaScript "File" Object */
/* $Id$ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 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 *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sbbs.h"
#include "md5.h"
#include "base64.h"
#include "uucode.h"
#include "yenc.h"
#include "ini_file.h"
#if !defined(__unix__)
#include <conio.h> /* for kbhit() */
#endif
#include "js_request.h"
char name[MAX_PATH+1];
char mode[4];
BOOL external; /* externally created, don't close */
BOOL debug;
BOOL rot13;
BOOL yencoded;
BOOL uuencoded;
BOOL b64encoded;
BOOL network_byte_order;
BOOL pipe; /* Opened with popen() use pclose() to close */
static const char* getprivate_failure = "line %d %s %s JS_GetPrivate failed";
static void dbprintf(BOOL error, private_t* p, char* fmt, ...)
{
va_list argptr;
char sbuf[1024];
if(p==NULL || (!p->debug && !error))
return;
va_start(argptr,fmt);
vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
sbuf[sizeof(sbuf)-1]=0;
lprintf(LOG_DEBUG,"%04u File %s%s",p->fp ? fileno(p->fp) : 0,error ? "ERROR: ":"",sbuf);
/* Converts fopen() style 'mode' string into open() style 'flags' integer */
static int fopenflags(char *mode)
{
int flags=0;
if(strchr(mode,'b'))
flags|=O_BINARY;
if(strchr(mode,'w')) {
flags|=O_CREAT|O_TRUNC;
if(strchr(mode,'+'))
flags|=O_RDWR;
else
flags|=O_WRONLY;
return(flags);
}
if(strchr(mode,'a')) {
flags|=O_CREAT|O_APPEND;
if(strchr(mode,'+'))
flags|=O_RDWR;
else
flags|=O_WRONLY;
return(flags);
}
if(strchr(mode,'r')) {
if(strchr(mode,'+'))
flags|=O_RDWR;
else
flags|=O_RDONLY;
}
if(strchr(mode,'e'))
flags|=O_EXCL;
return(flags);
}
/* File Object Methods */
static JSBool
js_open(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
BOOL shareable=FALSE;
int file;
JSString* str;
private_t* p;
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
if(p->fp!=NULL)
return(JS_TRUE);
SAFECOPY(p->mode,"w+"); /* default mode */
for(i=0;i<argc;i++) {
if(JSVAL_IS_STRING(argv[i])) { /* mode */
if((str = JS_ValueToString(cx, argv[i]))==NULL) {
JS_ReportError(cx,"Invalid mode specified: %s",str);
return(JS_TRUE);
JSSTRING_TO_STRBUF(cx, str, p->mode, sizeof(p->mode), NULL);
}
else if(JSVAL_IS_BOOLEAN(argv[i])) /* shareable */
shareable=JSVAL_TO_BOOLEAN(argv[i]);
else if(JSVAL_IS_NUMBER(argv[i])) { /* bufsize */
if(!JS_ValueToInt32(cx,argv[i],&bufsize))
return(JS_FALSE);
}
rc=JS_SUSPENDREQUEST(cx);
if(shareable)
p->fp=fopen(p->name,p->mode);
else {
if((file=nopen(p->name,fopenflags(p->mode)))!=-1) {
char *fdomode=strdup(p->mode);
char *e=fdomode;
if(fdomode && e) {
for(e=strchr(fdomode, 'e'); e ; e=strchr(e, 'e'))
memmove(e, e+1, strlen(e));
if((p->fp=fdopen(file,fdomode))==NULL)
close(file);
}
free(fdomode);
}
}
if(p->fp!=NULL) {
JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
dbprintf(FALSE, p, "opened: %s",p->name);
if(!bufsize)
setvbuf(p->fp,NULL,_IONBF,0); /* no buffering */
else {
#ifdef _WIN32
if(bufsize < 2)
bufsize = 2;
#endif
setvbuf(p->fp,NULL,_IOFBF,bufsize);
}
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_popen(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
uintN i;
jsint bufsize=2*1024;
JSString* str;
private_t* p;
JS_SET_RVAL(cx, arglist, 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);
SAFECOPY(p->mode,"r+"); /* default mode */
for(i=0;i<argc;i++) {
if(JSVAL_IS_STRING(argv[i])) { /* mode */
if((str = JS_ValueToString(cx, argv[i]))==NULL) {
JS_ReportError(cx,"Invalid mode specified: %s",str);
return(JS_TRUE);
}
JSSTRING_TO_STRBUF(cx, str, p->mode, sizeof(p->mode), NULL);
}
else if(JSVAL_IS_NUMBER(argv[i])) { /* bufsize */
if(!JS_ValueToInt32(cx,argv[i],&bufsize))
return(JS_FALSE);
}
}
rc=JS_SUSPENDREQUEST(cx);
p->fp=popen(p->name,p->mode);
if(p->fp!=NULL) {
p->pipe=TRUE;
JS_SET_RVAL(cx, arglist, 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);
}
js_close(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
if(p->fp==NULL)
return(JS_TRUE);
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);
}
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
static JSBool
js_raw_pollin(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
private_t* p;
jsrefcount rc;
int32 timeout = -1;
#ifdef __unix__
fd_set rd;
struct timeval tv = {0, 0};
#endif
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);
if(argc) {
if(!JS_ValueToInt32(cx,argv[0],&timeout))
return(JS_FALSE);
}
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(FALSE));
rc=JS_SUSPENDREQUEST(cx);
#ifdef __unix__
if (timeout >= 0) {
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout%1000)*1000;
}
FD_ZERO(&rd);
FD_SET(fileno(p->fp), &rd);
if (select(fileno(p->fp)+1, &rd, NULL, NULL, timeout < 0 ? NULL : &tv) == 1)
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(TRUE));
#else
while(timeout) {
if (isatty(fileno(p->fp))) {
if (kbhit()) {
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(TRUE));
rc=JS_SUSPENDREQUEST(cx);
break;
}
SLEEP(1);
if (timeout > 0)
timeout--;
}
else {
if (!eof(fileno(p->fp))) {
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(TRUE));
rc=JS_SUSPENDREQUEST(cx);
break;
}
SLEEP(1);
if (timeout > 0)
timeout--;
}
}
#endif
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
}
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
static JSBool
js_raw_read(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* buf;
int32 len;
JSString* str;
private_t* p;
jsrefcount rc;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
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);
if(argc) {
if(!JS_ValueToInt32(cx,argv[0],&len))
return(JS_FALSE);
} else
len = 1;
if(len<0)
len=1;
if((buf=malloc(len))==NULL)
return(JS_TRUE);
rc=JS_SUSPENDREQUEST(cx);
len = read(fileno(p->fp),buf,len);
if(len<0)
len=0;
JS_RESUMEREQUEST(cx, rc);
str = JS_NewStringCopyN(cx, buf, len);
free(buf);
if(str==NULL)
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(str));
rc=JS_SUSPENDREQUEST(cx);
dbprintf(FALSE, p, "read %u raw bytes",len);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
js_read(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* uubuf;
int32 len;
int32 offset;
int32 uulen;
JSString* str;
private_t* p;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
if(p->fp==NULL)
return(JS_TRUE);
if(argc) {
if(!JS_ValueToInt32(cx,argv[0],&len))
return(JS_FALSE);
} else {
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;
if((buf=malloc(len+1))==NULL)
rc=JS_SUSPENDREQUEST(cx);
len = fread(buf,1,len,p->fp);
if(len<0)
len=0;
buf[len]=0;
if(p->etx) {
cp=strchr(buf,p->etx);
if(cp) *cp=0;
len=strlen(buf);
if(p->rot13)
rot13(buf);
if(p->uuencoded || p->b64encoded || p->yencoded) {
uulen=len*2;
free(buf);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
if(p->uuencoded)
uulen=uuencode(uubuf,uulen,buf,len);
else if(p->yencoded)
uulen=yencode(uubuf,uulen,buf,len);
else
uulen=b64_encode(uubuf,uulen,buf,len);
if(uulen>=0) {
free(buf);
buf=uubuf;
len=uulen;
else
free(uubuf);
JS_RESUMEREQUEST(cx, rc);
str = JS_NewStringCopyN(cx, buf, len);
free(buf);
if(str==NULL)
return(JS_FALSE);
JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(str));
rc=JS_SUSPENDREQUEST(cx);
dbprintf(FALSE, p, "read %u bytes",len);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_readln(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
int32 len=512;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
if(p->fp==NULL)
return(JS_TRUE);
if(argc) {
if(!JS_ValueToInt32(cx,argv[0],&len))
return(JS_FALSE);
}
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'))
len--;
buf[len]=0;
if(p->etx) {
cp=strchr(buf,p->etx);
if(cp) *cp=0;
}
if(p->rot13)
rot13(buf);
JS_RESUMEREQUEST(cx, rc);
if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL) /* exception here Feb-12-2005 */
JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
} else {
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_readbin(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
BYTE *b;
WORD *w;
DWORD *l;
int32 size=sizeof(DWORD);
int32 count=1;
size_t retlen;
void *buffer=NULL;
JSObject* array;
jsval v;
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(-1));
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
if(p->fp==NULL)
return(JS_TRUE);
if(argc) {
if(!JS_ValueToInt32(cx,argv[0],&size))
return(JS_FALSE);
if(!JS_ValueToInt32(cx,argv[1],&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);
}
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):
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(*b));
break;
case sizeof(WORD):
JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(*w));
break;
case sizeof(DWORD):
JS_SET_RVAL(cx, arglist, UINT_TO_JSVAL(*l));
}
}
}
else {
JS_RESUMEREQUEST(cx, rc);
array = JS_NewArrayObject(cx, 0, NULL);
for(i=0; i<retlen; i++) {
switch(size) {
case sizeof(BYTE):
v = INT_TO_JSVAL(*(b++));
break;
case sizeof(WORD):
v = INT_TO_JSVAL(*(w++));
break;
case sizeof(DWORD):
v=UINT_TO_JSVAL(*(l++));
}
rc=JS_SUSPENDREQUEST(cx);
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
end:
free(buffer);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_readall(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsint len=0;
JSObject* array;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
if(p->fp==NULL)
return(JS_TRUE);
array = JS_NewArrayObject(cx, 0, NULL);
js_readln(cx, argc, arglist);
if(JS_RVAL(cx, arglist)==JSVAL_NULL)
if(!JS_SetElement(cx, array, len++, &JS_RVAL(cx, arglist)))
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
static jsval get_value(JSContext *cx, char* value)
{
char* p;
BOOL f=FALSE;
jsval val;
if(value==NULL || *value==0)
return(JSVAL_VOID);
/* integer or float? */
for(p=value;*p;p++) {
if(*p=='.' && !f)
f=TRUE;
break;
}
if(*p==0) {
if(f)
val=DOUBLE_TO_JSVAL(atof(value));
else
val=DOUBLE_TO_JSVAL((double)strtoul(value,NULL,10));
return(val);
}
/* hexadecimal number? */
if(!strncmp(value,"0x",2)) {
for(p=value+2;*p;p++)
break;
if(*p==0) {
val=DOUBLE_TO_JSVAL((double)strtoul(value,NULL,0));
return(val);
}
}
/* Boolean? */
if(!stricmp(value,"true"))
return(JSVAL_TRUE);
if(!stricmp(value,"false"))
return(JSVAL_FALSE);
/* String */
return(STRING_TO_JSVAL(JS_NewStringCopyZ(cx,value)));
}
static double js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj)
{
jsval rval;
if(!JS_CallFunctionName(cx, obj, "getTime", 0, NULL, &rval)) {
static JSBool
js_iniGetValue(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* key;
char** list;
char buf[INI_MAX_VALUE_LEN];
int32 i;
jsval val;
jsval dflt=argv[2];
private_t* p;
JSObject* array;
JSObject* dflt_obj;
JSObject* date_obj;
char* cstr=NULL;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
return(JS_FALSE);
}
if(argc && argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
JSVALUE_TO_MSTRING(cx, argv[0], section, NULL);
JSVALUE_TO_MSTRING(cx, argv[1], key, NULL);
if(JS_IsExceptionPending(cx)) {
FREE_AND_NULL(section);
FREE_AND_NULL(key);
/*
* Although section can be NULL (ie: root), a NULL key will cause a
* segfault.
*/
if(key==NULL) {
JS_ReportError(cx, "Invalid NULL key specified");
FREE_AND_NULL(section);
if(argc < 3 || dflt==JSVAL_VOID) { /* unspecified default value */
rc=JS_SUSPENDREQUEST(cx);
cstr=iniReadString(p->fp,section,key,NULL,buf);
FREE_AND_NULL(section);
FREE_AND_NULL(key);
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist, get_value(cx, cstr));
return(JS_TRUE);
}
if(JSVAL_IS_BOOLEAN(dflt)) {
JS_SET_RVAL(cx,arglist,BOOLEAN_TO_JSVAL(
iniReadBool(p->fp,section,key,JSVAL_TO_BOOLEAN(dflt))));
}
else if(JSVAL_IS_OBJECT(dflt)) {
if((dflt_obj = JSVAL_TO_OBJECT(dflt))!=NULL && (strcmp("Date",JS_GetClass(cx, dflt_obj)->name)==0)) {
tt=(time_t)(js_DateGetMsecSinceEpoch(cx,dflt_obj)/1000.0);
rc=JS_SUSPENDREQUEST(cx);
dbl=(double)iniReadDateTime(p->fp,section,key,tt);
JS_RESUMEREQUEST(cx, rc);
date_obj = JS_NewDateObjectMsec(cx, dbl);
if(date_obj!=NULL) {
array = JS_NewArrayObject(cx, 0, NULL);
cstr=NULL;
JSVALUE_TO_MSTRING(cx, dflt, cstr, NULL);
if(JS_IsExceptionPending(cx)) {
FREE_AND_NULL(cstr);
FREE_AND_NULL(section);
FREE_AND_NULL(key);
rc=JS_SUSPENDREQUEST(cx);
list=iniReadStringList(p->fp,section,key,",",cstr);
FREE_AND_NULL(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);
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
}
}
else if(JSVAL_IS_DOUBLE(dflt)) {
rc=JS_SUSPENDREQUEST(cx);
dbl=iniReadFloat(p->fp,section,key,JSVAL_TO_DOUBLE(dflt));
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist,DOUBLE_TO_JSVAL(dbl));
}
else if(JSVAL_IS_NUMBER(dflt)) {
if(!JS_ValueToInt32(cx,dflt,&i)) {
FREE_AND_NULL(section);
FREE_AND_NULL(key);
rc=JS_SUSPENDREQUEST(cx);
i=iniReadInteger(p->fp,section,key,i);
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist,INT_TO_JSVAL(i));
} else {
cstr=NULL;
JSVALUE_TO_MSTRING(cx, dflt, cstr, NULL);
if(JS_IsExceptionPending(cx)) {
FREE_AND_NULL(cstr);
FREE_AND_NULL(section);
FREE_AND_NULL(key);
rc=JS_SUSPENDREQUEST(cx);
cstr2=iniReadString(p->fp,section,key,cstr,buf);
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cstr2)));
}
FREE_AND_NULL(section);
FREE_AND_NULL(key);
return(JS_TRUE);
}
js_iniSetValue_internal(JSContext *cx, JSObject *obj, uintN argc, jsval* argv, str_list_t* list)
char* result=NULL;
int32 i;
jsval value=argv[2];
private_t* p;
JSObject* value_obj;
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);
if(argc && argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL)
JSVALUE_TO_MSTRING(cx, argv[0], section, NULL);
JSVALUE_TO_MSTRING(cx, argv[1], key, NULL);
if(JS_IsExceptionPending(cx)) {
FREE_AND_NULL(section);
FREE_AND_NULL(key);
if(value==JSVAL_VOID) { /* unspecified value */
rc=JS_SUSPENDREQUEST(cx);
result = iniSetString(list,section,key,"",NULL);
JS_RESUMEREQUEST(cx, rc);
result = iniSetBool(list,section,key,JSVAL_TO_BOOLEAN(value),NULL);
result = iniSetFloat(list,section,key,JSVAL_TO_DOUBLE(value),NULL);
if(!JS_ValueToInt32(cx,value,&i)) {
FREE_AND_NULL(section);
FREE_AND_NULL(key);
result = iniSetInteger(list,section,key,i,NULL);
JS_RESUMEREQUEST(cx, rc);
} else if(JSVAL_IS_OBJECT(value)
&& (value_obj = JSVAL_TO_OBJECT(value))!=NULL
&& (strcmp("Date",JS_GetClass(cx, value_obj)->name)==0)) {
tt=(time_t)(js_DateGetMsecSinceEpoch(cx,value_obj)/1000.0);
rc=JS_SUSPENDREQUEST(cx);
result = iniSetDateTime(list,section,key,/* include_time */TRUE, tt,NULL);
cstr=NULL;
JSVALUE_TO_MSTRING(cx, value, cstr, NULL);
if(JS_IsExceptionPending(cx)) {
FREE_AND_NULL(cstr);
FREE_AND_NULL(section);
FREE_AND_NULL(key);
result = iniSetString(list,section,key, cstr,NULL);
FREE_AND_NULL(cstr);
FREE_AND_NULL(section);
FREE_AND_NULL(key);
return(result != NULL);
static JSBool
js_iniSetValue(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
jsval rval=JSVAL_FALSE;
private_t* p;
str_list_t list;
jsrefcount rc;
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);
rc=JS_SUSPENDREQUEST(cx);
if((list=iniReadFile(p->fp)) != NULL) {
if(js_iniSetValue_internal(cx, obj, argc, argv, &list))
rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list));
}
strListFree(&list);
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
js_iniRemoveKey(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
char* section=ROOT_SECTION;
private_t* p;
str_list_t list;
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {