Newer
Older
/* js_file.c */
/* 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 2013 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"
#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 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);
}
287
288
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
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) {
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);
HANDLE_PENDING(cx);
if(key==NULL) {
JS_ReportError(cx, "Invalid NULL key specified");
FREE_AND_NULL(section);
rc=JS_SUSPENDREQUEST(cx);
JS_RESUMEREQUEST(cx, rc);
FREE_AND_NULL(section);
FREE_AND_NULL(key);
return(JS_TRUE);
if(iniRemoveKey(&list,section,key))
JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list)));
FREE_AND_NULL(section);
FREE_AND_NULL(key);
strListFree(&list);
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
}
static JSBool
js_iniRemoveSection(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) {
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);
HANDLE_PENDING(cx);
}
rc=JS_SUSPENDREQUEST(cx);
JS_RESUMEREQUEST(cx, rc);
FREE_AND_NULL(section);
return(JS_TRUE);