|
|
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 </tt> open for reading; if the file does not exist or cannot be found, the open call fails<br>"
2074: "<tt>w </tt> open an empty file for writing; if the given file exists, its contents are destroyed<br>"
2075: "<tt>a </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 </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 </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 </tt> DENYWRITE - Allows other scripts to open the file for reading, but not for writing.<br>"
! 2090: "<tt>w </tt> DENYALL - Does not allow other scripts to open the file when <i>shareable</i> is set to true<br>"
! 2091: "<tt>a </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 </tt> read the programs stdout;<br>"
! 2107: "<tt>w </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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.