js_file.c 35.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/* 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)		*
 *																			*
11
 * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html		*
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 *																			*
 * 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"
39
40
#include "md5.h"
#include "base64.h"
41
#include "uucode.h"
42
#include "ini_file.h"
43
44
45
46
47

#ifdef JAVASCRIPT

typedef struct
{
48
	FILE*	fp;
49
50
	char	name[MAX_PATH+1];
	char	mode[4];
51
	uchar	etx;
52
53
	BOOL	external;	/* externally created, don't close */
	BOOL	debug;
54
	BOOL	rot13;
55
	BOOL	uuencoded;
56
57
	BOOL	b64encoded;
	BOOL	network_byte_order;
58
59
60

} private_t;

61
static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";
62
63
64
65
66
67
68
69
70
71

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);
72
73
    vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
	sbuf[sizeof(sbuf)-1]=0;
74
75
    va_end(argptr);
	
76
	lprintf("%04u File %s%s",p->fp ? fileno(p->fp) : 0,error ? "ERROR: ":"",sbuf);
77
78
}

79
80
81
82
83
84
85
86
/* 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;
87
88
	else
		flags|=O_TEXT;
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

	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;
	}

	return(flags);
}
117
118
119
120
121
122
123

/* File Object Methods */

static JSBool
js_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	char*		mode="w+";	/* default mode */
124
125
	BOOL		shareable=FALSE;
	int			file;
126
	uintN		i;
127
	jsint		bufsize=2*1024;
128
129
130
	JSString*	str;
	private_t*	p;

131
	*rval = JSVAL_FALSE;
132

133
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
134
		JS_ReportError(cx,getprivate_failure,WHERE);
135
		return(JS_FALSE);
136
	}
137
138
139

	if(p->fp!=NULL)  
		return(JS_TRUE);
140
141
142
143

	for(i=0;i<argc;i++) {
		if(JSVAL_IS_STRING(argv[i])) {	/* mode */
			if((str = JS_ValueToString(cx, argv[i]))==NULL) {
144
145
				JS_ReportError(cx,"Invalid mode specified: %s",str);
				return(JS_TRUE);
146
147
			}
			mode=JS_GetStringBytes(str);
148
149
150
		} else if(JSVAL_IS_BOOLEAN(argv[i]))	/* shareable */
			shareable=JSVAL_TO_BOOLEAN(argv[i]);
		else	/* bufsize */
151
			JS_ValueToInt32(cx,argv[i],&bufsize);
152
	}
153
	SAFECOPY(p->mode,mode);
154

155
156
157
158
159
160
161
162
	if(shareable)
		p->fp=fopen(p->name,p->mode);
	else {
		if((file=nopen(p->name,fopenflags(p->mode)))!=-1) {
			if((p->fp=fdopen(file,p->mode))==NULL)
				close(file);
		}
	}
163
	if(p->fp!=NULL) {
164
		*rval = JSVAL_TRUE;
165
		dbprintf(FALSE, p, "opened: %s",p->name);
166
167
168
169
170
		if(!bufsize)
			setvbuf(p->fp,NULL,_IONBF,0);	/* no buffering */
		else
			setvbuf(p->fp,NULL,_IOFBF,bufsize);
	}
171
172
173
174
175
176
177
178
179
180

	return(JS_TRUE);
}


static JSBool
js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	private_t*	p;

181
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
182
		JS_ReportError(cx,getprivate_failure,WHERE);
183
		return(JS_FALSE);
184
	}
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200

	*rval = JSVAL_VOID;

	if(p->fp==NULL)
		return(JS_TRUE);

	fclose(p->fp);

	dbprintf(FALSE, p, "closed");

	p->fp=NULL; 

	return(JS_TRUE);
}

static JSBool
201
js_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
202
203
{
	char*		cp;
204
	char*		buf;
205
	char*		uubuf;
206
207
	int32		len;
	int32		offset;
208
	int32		uulen;
209
210
211
	JSString*	str;
	private_t*	p;

212
213
	*rval = JSVAL_NULL;

214
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
215
		JS_ReportError(cx,getprivate_failure,WHERE);
216
		return(JS_FALSE);
217
	}
218

219
220
	if(p->fp==NULL)
		return(JS_TRUE);
221

222
	if(argc)
223
		JS_ValueToInt32(cx,argv[0],&len);
224
225
226
227
228
229
230
231
	else {
		len=filelength(fileno(p->fp));
		offset=ftell(p->fp);
		if(offset>0)
			len-=offset;
	}
	if(len<0)
		len=512;
232

233
234
235
236
237
238
239
240
241
242
243
244
245
	if((buf=malloc(len+1))==NULL)
		return(JS_TRUE);

	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; 
	}

246
247
248
	if(p->rot13)
		rot13(buf);

249
	if(p->uuencoded || p->b64encoded) {
250
251
252
		uulen=len*2;
		if((uubuf=malloc(uulen))==NULL)
			return(JS_TRUE);
253
254
255
256
		if(p->uuencoded)
			uulen=uuencode(uubuf,uulen,buf,len);
		else
			uulen=b64_encode(uubuf,uulen,buf,len);
257
258
259
260
261
262
263
		if(uulen>=0) {
			free(buf);
			buf=uubuf;
		} else
			free(uubuf);
	}

264
265
266
267
	str = JS_NewStringCopyZ(cx, buf);

	free(buf);

268
269
270
	if(str==NULL)
		return(JS_FALSE);

271
272
273
	*rval = STRING_TO_JSVAL(str);

	dbprintf(FALSE, p, "read %u bytes",len);
274
275
276
277
278
		
	return(JS_TRUE);
}

static JSBool
279
js_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
280
{
281
282
	char*		cp;
	char*		buf;
283
	int32		len=512;
284
	JSString*	js_str;
285
286
	private_t*	p;

287
	*rval = JSVAL_NULL;
288

289
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
290
		JS_ReportError(cx,getprivate_failure,WHERE);
291
		return(JS_FALSE);
292
	}
293
294
295

	if(p->fp==NULL)
		return(JS_TRUE);
296
297
	
	if(argc)
298
		JS_ValueToInt32(cx,argv[0],&len);
299

300
301
302
303
	if((buf=malloc(len))==NULL)
		return(JS_TRUE);

	if(fgets(buf,len,p->fp)!=NULL) {
304
305
306
307
		len=strlen(buf);
		while(len>0 && (buf[len-1]=='\r' || buf[len-1]=='\n'))
			len--;
		buf[len]=0;
308
309
310
311
		if(p->etx) {
			cp=strchr(buf,p->etx);
			if(cp) *cp=0; 
		}
312
313
		if(p->rot13)
			rot13(buf);
314
315
		if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
			*rval = STRING_TO_JSVAL(js_str);
316
317
	}

318
319
	free(buf);

320
321
322
323
	return(JS_TRUE);
}

static JSBool
324
js_readbin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
325
326
327
328
329
330
331
{
	BYTE		b;
	WORD		w;
	DWORD		l;
	size_t		size=sizeof(DWORD);
	private_t*	p;

332
	*rval = INT_TO_JSVAL(-1);
333

334
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
335
		JS_ReportError(cx,getprivate_failure,WHERE);
336
		return(JS_FALSE);
337
	}
338
339
340
341

	if(p->fp==NULL)
		return(JS_TRUE);

342
	if(argc) 
343
		JS_ValueToInt32(cx,argv[0],(int32*)&size);
344
345
346

	switch(size) {
		case sizeof(BYTE):
347
348
			if(fread(&b,1,size,p->fp)==size)
				*rval = INT_TO_JSVAL(b);
349
350
			break;
		case sizeof(WORD):
351
352
353
			if(fread(&w,1,size,p->fp)==size) {
				if(p->network_byte_order)
					w=ntohs(w);
354
				*rval = INT_TO_JSVAL(w);
355
			}
356
357
			break;
		case sizeof(DWORD):
358
359
360
			if(fread(&l,1,size,p->fp)==size) {
				if(p->network_byte_order)
					l=ntohl(l);
361
				JS_NewNumberValue(cx,l,rval);
362
			}
363
364
365
366
367
368
369
			break;
	}
		
	return(JS_TRUE);
}

static JSBool
370
js_readall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
371
{
372
373
374
    jsint       len=0;
    jsval       line;
    JSObject*	array;
375
376
	private_t*	p;

377
378
	*rval = JSVAL_NULL;

379
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
380
		JS_ReportError(cx,getprivate_failure,WHERE);
381
		return(JS_FALSE);
382
	}
383

384
385
	if(p->fp==NULL)
		return(JS_TRUE);
386

387
    array = JS_NewArrayObject(cx, 0, NULL);
388

389
390
391
392
    while(!feof(p->fp)) {
		js_readln(cx, obj, 0, NULL, &line); 
		if(line==JSVAL_NULL)
			break;
393
394
        if(!JS_SetElement(cx, array, len++, &line))
			break;
395
	}
396
    *rval = OBJECT_TO_JSVAL(array);
397

398
399
    return(JS_TRUE);
}
400

401
static JSBool
402
js_iniGetValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
403
404
405
{
	char*	section;
	char*	key;
406
	char**	list;
407
	char	buf[MAX_VALUE_LEN];
408
409
	int32	i;
	jsval	val;
410
411
	jsval	dflt=argv[2];
	private_t*	p;
412
	JSObject*	array;
413

414
	*rval = JSVAL_VOID;
415
416
417
418
419
420
421
422
423
424
425

	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
		JS_ReportError(cx,getprivate_failure,WHERE);
		return(JS_FALSE);
	}

	section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
	key=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
	switch(JSVAL_TAG(dflt)) {
		case JSVAL_STRING:
			*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,
426
				iniGetString(p->fp,section,key
427
					,JS_GetStringBytes(JS_ValueToString(cx,dflt)),buf)));
428
429
430
			break;
		case JSVAL_BOOLEAN:
			*rval = BOOLEAN_TO_JSVAL(
431
				iniGetBool(p->fp,section,key,JSVAL_TO_BOOLEAN(dflt)));
432
433
434
			break;
		case JSVAL_DOUBLE:
			JS_NewNumberValue(cx
435
				,iniGetFloat(p->fp,section,key,*JSVAL_TO_DOUBLE(dflt)),rval);
436
			break;
437
438
		case JSVAL_OBJECT:
		    array = JS_NewArrayObject(cx, 0, NULL);
439
			list=iniGetStringList(p->fp,section,key,",",JS_GetStringBytes(JS_ValueToString(cx,dflt)));
440
441
442
443
444
445
446
447
			for(i=0;list && list[i];i++) {
				val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i]));
				if(!JS_SetElement(cx, array, i, &val))
					break;
			}
			iniFreeStringList(list);
			*rval = OBJECT_TO_JSVAL(array);
			break;
448
449
450
		default:
			if(JSVAL_IS_INT(dflt)) {
				*rval = INT_TO_JSVAL(
451
					iniGetInteger(p->fp,section,key,JSVAL_TO_INT(dflt)));
452
453
454
455
456
457
458
459
				break;
			}
			break;
	}

	return(JS_TRUE);
}

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
static JSBool
js_iniGetSections(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	char**		list;
    jsint       i;
    jsval       val;
    JSObject*	array;
	private_t*	p;

	*rval = JSVAL_NULL;

	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
		JS_ReportError(cx,getprivate_failure,WHERE);
		return(JS_FALSE);
	}

    array = JS_NewArrayObject(cx, 0, NULL);

478
	list = iniGetSectionList(p->fp);
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
    for(i=0;list && list[i];i++) {
		val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i]));
        if(!JS_SetElement(cx, array, i, &val))
			break;
	}
	iniFreeStringList(list);

    *rval = OBJECT_TO_JSVAL(array);

    return(JS_TRUE);
}

static JSBool
js_iniGetKeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	char*		section;
	char**		list;
    jsint       i;
    jsval       val;
    JSObject*	array;
	private_t*	p;

	*rval = JSVAL_NULL;

	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
		JS_ReportError(cx,getprivate_failure,WHERE);
		return(JS_FALSE);
	}

	section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
    array = JS_NewArrayObject(cx, 0, NULL);

511
	list = iniGetKeyList(p->fp,section);
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
    for(i=0;list && list[i];i++) {
		val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i]));
        if(!JS_SetElement(cx, array, i, &val))
			break;
	}
	iniFreeStringList(list);

    *rval = OBJECT_TO_JSVAL(array);

    return(JS_TRUE);
}

static JSBool
js_iniGetObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	char*		section;
    jsint       i;
    JSObject*	object;
	private_t*	p;
531
	named_string_t** list;
532
533
534
535
536
537
538
539
540
541
542

	*rval = JSVAL_NULL;

	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
		JS_ReportError(cx,getprivate_failure,WHERE);
		return(JS_FALSE);
	}

	section=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
    object = JS_NewObject(cx, NULL, NULL, obj);

543
	list = iniGetNamedStringList(p->fp,section);
544
    for(i=0;list && list[i];i++) {
545
546
		JS_DefineProperty(cx, object, list[i]->name
			,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i]->value))
547
548
549
			,NULL,NULL,JSPROP_ENUMERATE);

	}
550
	iniFreeNamedStringList(list);
551
552
553
554
555
556
557

    *rval = OBJECT_TO_JSVAL(object);

    return(JS_TRUE);
}


558
559
560
561
static JSBool
js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	char*		cp;
562
563
564
	char*		uubuf=NULL;
	int			len;	/* string length */
	int			tlen;	/* total length to write (may be greater than len) */
565
	private_t*	p;
566

567
	*rval = JSVAL_FALSE;
568

569
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
570
		JS_ReportError(cx,getprivate_failure,WHERE);
571
		return(JS_FALSE);
572
	}
573
574
575
576

	if(p->fp==NULL)
		return(JS_TRUE);

577
578
579
	cp=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
	len=strlen(cp);

580
581
582
583
584
585
	if((p->uuencoded || p->b64encoded)
		&& len && (uubuf=malloc(len))!=NULL) {
		if(p->uuencoded)
			len=uudecode(uubuf,len,cp,len);
		else
			len=b64_decode(uubuf,len,cp,len);
586
587
588
589
590
591
592
		if(len<0) {
			free(uubuf);
			return(JS_TRUE);
		}
		cp=uubuf;
	}

593
594
595
	if(p->rot13)
		rot13(cp);

596
	tlen=len;
597
	if(argc>1) {
598
		JS_ValueToInt32(cx,argv[1],(int32*)&tlen);
599
600
601
		if(len>tlen)
			len=tlen;
	}
602
603

	if(fwrite(cp,1,len,p->fp)==(size_t)len) {
604
605
606
607
608
609
610
611
612
613
614
		if(tlen>len) {
			len=tlen-len;
			if((cp=malloc(len))==NULL) {
				dbprintf(TRUE, p, "malloc failure of %u bytes", len);
				return(JS_TRUE);
			}
			memset(cp,p->etx,len);
			fwrite(cp,1,len,p->fp);
			free(cp);
		}
		dbprintf(FALSE, p, "wrote %u bytes",tlen);
615
		*rval = JSVAL_TRUE;
616
617
	} else 
		dbprintf(TRUE, p, "write of %u bytes failed",len);
618
		
619
620
621
	if(uubuf!=NULL)
		free(uubuf);

622
623
624
625
	return(JS_TRUE);
}

static JSBool
626
js_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
627
{
628
629
630
631
	char*		cp="";
	JSString*	str;
	private_t*	p;

632
	*rval = JSVAL_FALSE;
633

634
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
635
		JS_ReportError(cx,getprivate_failure,WHERE);
636
		return(JS_FALSE);
637
	}
638
639
640
641
642

	if(p->fp==NULL)
		return(JS_TRUE);

	if(argc) {
643
644
		if((str = JS_ValueToString(cx, argv[0]))==NULL) {
			JS_ReportError(cx,"JS_ValueToString failed");
645
			return(JS_FALSE);
646
		}
647
648
649
		cp = JS_GetStringBytes(str);
	}

650
651
652
	if(p->rot13)
		rot13(cp);

653
	if(fprintf(p->fp,"%s\n",cp)!=0)
654
		*rval = JSVAL_TRUE;
655

656
657
	return(JS_TRUE);
}
658

659
static JSBool
660
js_writebin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
661
{
662
663
664
	BYTE		b;
	WORD		w;
	DWORD		l;
665
	int32		val=0;
666
	size_t		wr=0;
667
	size_t		size=sizeof(DWORD);
668
669
	private_t*	p;

670
	*rval = JSVAL_FALSE;
671

672
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
673
		JS_ReportError(cx,getprivate_failure,WHERE);
674
		return(JS_FALSE);
675
	}
676

677
678
	if(p->fp==NULL)
		return(JS_TRUE);
679

680
	JS_ValueToInt32(cx,argv[0],&val);
681
	if(argc>1) 
682
		JS_ValueToInt32(cx,argv[1],(int32*)&size);
683

684
685
	switch(size) {
		case sizeof(BYTE):
686
			b = (BYTE)val;
687
			wr=fwrite(&b,1,size,p->fp);
688
689
			break;
		case sizeof(WORD):
690
			w = (WORD)val;
691
692
			if(p->network_byte_order)
				w=htons(w);
693
			wr=fwrite(&w,1,size,p->fp);
694
695
			break;
		case sizeof(DWORD):
696
			l = val;
697
698
			if(p->network_byte_order)
				l=htonl(l);
699
700
701
702
703
			wr=fwrite(&l,1,size,p->fp);
			break;
		default:	
			/* unknown size */
			dbprintf(TRUE, p, "unsupported binary write size: %d",size);
704
705
			break;
	}
706
	if(wr==size)
707
		*rval = JSVAL_TRUE;
708
		
709
710
711
	return(JS_TRUE);
}

712
713
714
715
716
717
718
719
720
static JSBool
js_writeall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    jsuint      i;
    jsuint      limit;
    JSObject*	array;
    jsval       elemval;
	private_t*	p;

721
	*rval = JSVAL_FALSE;
722

723
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
724
		JS_ReportError(cx,getprivate_failure,WHERE);
725
		return(JS_FALSE);
726
	}
727
728
729
730

	if(p->fp==NULL)
		return(JS_TRUE);

731
	if(!JSVAL_IS_OBJECT(argv[0]))
732
733
734
735
		return(JS_TRUE);

    array = JSVAL_TO_OBJECT(argv[0]);

736
737
738
    if(!JS_IsArrayObject(cx, array))
		return(JS_TRUE);

739
740
    if(!JS_GetArrayLength(cx, array, &limit))
		return(JS_FALSE);
741

742
    *rval = JSVAL_TRUE;
743

744
745
746
747
    for(i=0;i<limit;i++) {
        if(!JS_GetElement(cx, array, i, &elemval))
			break;
        js_writeln(cx, obj, 1, &elemval, rval);
748
		if(*rval!=JSVAL_TRUE)
749
			break;
750
751
752
753
754
    }

    return(JS_TRUE);
}

755
static JSBool
756
js_lock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
757
{
758
759
	int32		offset=0;
	int32		len=0;
760
761
	private_t*	p;

762
	*rval = JSVAL_FALSE;
763

764
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
765
		JS_ReportError(cx,getprivate_failure,WHERE);
766
		return(JS_FALSE);
767
	}
768
769
770
771

	if(p->fp==NULL)
		return(JS_TRUE);

772
773
774
775
776
777
778
779
780
781
782
783
	/* offset */
	if(argc)
		JS_ValueToInt32(cx,argv[0],&offset);

	/* length */
	if(argc>1)
		JS_ValueToInt32(cx,argv[1],&len);

	if(len==0)
		len=filelength(fileno(p->fp))-offset;

	if(lock(fileno(p->fp),offset,len)==0)
784
		*rval = JSVAL_TRUE;
785

786
787
	return(JS_TRUE);
}
788

789
static JSBool
790
js_unlock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
791
{
792
793
	int32		offset=0;
	int32		len=0;
794
795
	private_t*	p;

796
	*rval = JSVAL_FALSE;
797

798
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
799
		JS_ReportError(cx,getprivate_failure,WHERE);
800
		return(JS_FALSE);
801
	}
802
803
804
805

	if(p->fp==NULL)
		return(JS_TRUE);

806
807
808
809
810
811
812
813
814
815
816
	/* offset */
	if(argc)
		JS_ValueToInt32(cx,argv[0],&offset);

	/* length */
	if(argc>1)
		JS_ValueToInt32(cx,argv[1],&len);

	if(len==0)
		len=filelength(fileno(p->fp))-offset;

817
	if(unlock(fileno(p->fp),offset,len)==0)
818
		*rval = JSVAL_TRUE;
819

820
821
822
	return(JS_TRUE);
}

823
824
825
826
827
static JSBool
js_delete(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	private_t*	p;

828
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
829
		JS_ReportError(cx,getprivate_failure,WHERE);
830
		return(JS_FALSE);
831
	}
832
833
834
835
836
837
838
839
840
841

	if(p->fp!=NULL) {	/* close it if it's open */
		fclose(p->fp);
		p->fp=NULL;
	}

	*rval = BOOLEAN_TO_JSVAL(remove(p->name)==0);

	return(JS_TRUE);
}
842
843
844
845
846
847

static JSBool
js_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	private_t*	p;

848
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
849
		JS_ReportError(cx,getprivate_failure,WHERE);
850
		return(JS_FALSE);
851
	}
852
853

	if(p->fp==NULL)
854
		*rval = JSVAL_FALSE;
855
856
857
858
859
860
861
862
863
864
865
	else 
		*rval = BOOLEAN_TO_JSVAL(fflush(p->fp)==0);

	return(JS_TRUE);
}

static JSBool
js_clear_error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	private_t*	p;

866
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
867
		JS_ReportError(cx,getprivate_failure,WHERE);
868
		return(JS_FALSE);
869
	}
870
871

	if(p->fp==NULL)
872
		*rval = JSVAL_FALSE;
873
874
	else  {
		clearerr(p->fp);
875
		*rval = JSVAL_TRUE;
876
877
878
879
880
	}

	return(JS_TRUE);
}

881
882
883
884
885
886
887
888
889
890
static JSBool
js_fprintf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	char*		cp;
    uintN		i;
	JSString *	fmt;
    JSString *	str;
	va_list		arglist[64];
	private_t*	p;

891
	*rval = JSVAL_FALSE;
892

893
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
894
		JS_ReportError(cx,getprivate_failure,WHERE);
895
		return(JS_FALSE);
896
	}
897
898
899
900

	if(p->fp==NULL)
		return(JS_TRUE);

901
902
	if((fmt=JS_ValueToString(cx, argv[0]))==NULL) {
		JS_ReportError(cx,"JS_ValueToString failed");
903
		return(JS_FALSE);
904
	}
905
906
907
908
909

	memset(arglist,0,sizeof(arglist));	/* Initialize arglist to NULLs */

    for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) {
		if(JSVAL_IS_STRING(argv[i])) {
910
911
			if((str=JS_ValueToString(cx, argv[i]))==NULL) {
				JS_ReportError(cx,"JS_ValueToString failed");
912
			    return(JS_FALSE);
913
			}
914
915
916
917
918
919
920
921
922
923
			arglist[i-1]=JS_GetStringBytes(str);	/* exception here July-29-2002 */
		}
		else if(JSVAL_IS_DOUBLE(argv[i]))
			arglist[i-1]=(char*)(unsigned long)*JSVAL_TO_DOUBLE(argv[i]);
		else if(JSVAL_IS_INT(argv[i]) || JSVAL_IS_BOOLEAN(argv[i]))
			arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]);
		else
			arglist[i-1]=NULL;
	}

924
925
	if((cp=JS_vsmprintf(JS_GetStringBytes(fmt),(char*)arglist))==NULL) {
		JS_ReportError(cx,"JS_vsmprintf failed");
926
		return(JS_FALSE);
927
	}
928
929
930
931
932
933
934

	*rval = INT_TO_JSVAL(fwrite(cp,1,strlen(cp),p->fp));
	JS_smprintf_free(cp);
	
    return(JS_TRUE);
}

935
936
937
938

/* File Object Properites */
enum {
	 FILE_PROP_NAME		
939
940
	,FILE_PROP_MODE
	,FILE_PROP_ETX
941
942
943
944
945
946
947
948
949
950
	,FILE_PROP_EXISTS	
	,FILE_PROP_DATE		
	,FILE_PROP_IS_OPEN	
	,FILE_PROP_EOF		
	,FILE_PROP_ERROR	
	,FILE_PROP_DESCRIPTOR
	,FILE_PROP_DEBUG	
	,FILE_PROP_POSITION	
	,FILE_PROP_LENGTH	
	,FILE_PROP_ATTRIBUTES
951
	,FILE_PROP_UUENCODED
952
	,FILE_PROP_B64ENCODED
953
	,FILE_PROP_ROT13
954
	,FILE_PROP_NETWORK_ORDER
955
956
957
958
959
	/* dynamically calculated */
	,FILE_PROP_CHKSUM
	,FILE_PROP_CRC16
	,FILE_PROP_CRC32
	,FILE_PROP_MD5_HEX
960
	,FILE_PROP_MD5_B64
961
962
};

rswindell's avatar
rswindell committed
963

964
965
966
967
968
static JSBool js_file_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    jsint       tiny;
	private_t*	p;

969
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
970
		JS_ReportError(cx,getprivate_failure,WHERE);
971
		return(JS_FALSE);
972
	}
973
974
975
976
977
978
979

    tiny = JSVAL_TO_INT(id);

	dbprintf(FALSE, p, "setting property %d",tiny);

	switch(tiny) {
		case FILE_PROP_DEBUG:
980
			JS_ValueToBoolean(cx,*vp,&(p->debug));
981
			break;
982
		case FILE_PROP_UUENCODED:
983
984
985
986
987
			JS_ValueToBoolean(cx,*vp,&(p->uuencoded));
			break;
		case FILE_PROP_B64ENCODED:
			JS_ValueToBoolean(cx,*vp,&(p->b64encoded));
			break;
988
989
990
		case FILE_PROP_ROT13:
			JS_ValueToBoolean(cx,*vp,&(p->rot13));
			break;
991
992
		case FILE_PROP_NETWORK_ORDER:
			JS_ValueToBoolean(cx,*vp,&(p->network_byte_order));
993
			break;
994
995
996
997
998
999
1000
1001
1002
1003
1004
		case FILE_PROP_POSITION:
			if(p->fp!=NULL)
				fseek(p->fp,JSVAL_TO_INT(*vp),SEEK_SET);
			break;
		case FILE_PROP_LENGTH:
			if(p->fp!=NULL)
				chsize(fileno(p->fp),JSVAL_TO_INT(*vp));
			break;
		case FILE_PROP_ATTRIBUTES:
			CHMOD(p->name,JSVAL_TO_INT(*vp));
			break;
1005
1006
1007
		case FILE_PROP_ETX:
			p->etx = (uchar)JSVAL_TO_INT(*vp);
			break;
1008
1009
1010
1011
1012
1013
1014
	}

	return(JS_TRUE);
}

static JSBool js_file_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
1015
1016
1017
1018
1019
1020
	BYTE*		buf;
	long		l;
	long		len;
	long		offset;
	ulong		sum;
	BYTE		digest[MD5_DIGEST_SIZE];
1021
    jsint       tiny;
1022
	JSString*	js_str=NULL;
1023
1024
	private_t*	p;

1025
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
1026
		JS_ReportError(cx,getprivate_failure,WHERE);
1027
		return(JS_FALSE);
1028
	}
1029
1030
1031
1032
1033
1034
1035
1036
1037

    tiny = JSVAL_TO_INT(id);

#if 0 /* just too much */
	dbprintf(FALSE, sock, "getting property %d",tiny);
#endif

	switch(tiny) {
		case FILE_PROP_NAME:
1038
1039
1040
			if((js_str=JS_NewStringCopyZ(cx, p->name))==NULL)
				return(JS_FALSE);
			*vp = STRING_TO_JSVAL(js_str);
1041
1042
			break;
		case FILE_PROP_MODE:
1043
1044
1045
			if((js_str=JS_NewStringCopyZ(cx, p->mode))==NULL)
				return(JS_FALSE);
			*vp = STRING_TO_JSVAL(js_str);
1046
1047
1048
			break;
		case FILE_PROP_EXISTS:
			if(p->fp)	/* open? */
1049
				*vp = JSVAL_TRUE;
1050
1051
1052
1053
			else
				*vp = BOOLEAN_TO_JSVAL(fexist(p->name));
			break;
		case FILE_PROP_DATE:
1054
			JS_NewNumberValue(cx,fdate(p->name),vp);
1055
1056
1057
1058
1059
			break;
		case FILE_PROP_IS_OPEN:
			*vp = BOOLEAN_TO_JSVAL(p->fp!=NULL);
			break;
		case FILE_PROP_EOF:
1060
1061
1062
			if(p->fp)
				*vp = BOOLEAN_TO_JSVAL(feof(p->fp)!=0);
			else
1063
				*vp = JSVAL_TRUE;
1064
1065
			break;
		case FILE_PROP_ERROR:
1066
1067
1068
			if(p->fp)
				*vp = INT_TO_JSVAL(ferror(p->fp));
			else
1069
				*vp = INT_TO_JSVAL(errno);
1070
1071
			break;
		case FILE_PROP_POSITION:
1072
			if(p->fp)
1073
				JS_NewNumberValue(cx,ftell(p->fp),vp);
1074
1075
			else
				*vp = INT_TO_JSVAL(-1);