js_file.c 38.4 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 "yenc.h"
43
#include "ini_file.h"
44
45
46
47
48

#ifdef JAVASCRIPT

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

} private_t;

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

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

81
82
83
84
85
86
87
88
/* 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;
89
90
	else
		flags|=O_TEXT;
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
117
118

	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);
}
119
120
121
122
123
124
125

/* File Object Methods */

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

133
	*rval = JSVAL_FALSE;
134

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

	if(p->fp!=NULL)  
		return(JS_TRUE);
142
143
144
145

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

157
158
159
160
161
162
163
164
	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);
		}
	}
165
	if(p->fp!=NULL) {
166
		*rval = JSVAL_TRUE;
167
		dbprintf(FALSE, p, "opened: %s",p->name);
168
169
170
171
172
		if(!bufsize)
			setvbuf(p->fp,NULL,_IONBF,0);	/* no buffering */
		else
			setvbuf(p->fp,NULL,_IOFBF,bufsize);
	}
173
174
175
176
177
178
179
180
181
182

	return(JS_TRUE);
}


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

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

	*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
203
js_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
204
205
{
	char*		cp;
206
	char*		buf;
207
	char*		uubuf;
208
209
	int32		len;
	int32		offset;
210
	int32		uulen;
211
212
213
	JSString*	str;
	private_t*	p;

214
215
	*rval = JSVAL_NULL;

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

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

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

235
236
237
238
239
240
241
242
243
244
245
246
247
	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; 
	}

248
249
250
	if(p->rot13)
		rot13(buf);

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

268
269
270
271
	str = JS_NewStringCopyZ(cx, buf);

	free(buf);

272
273
274
	if(str==NULL)
		return(JS_FALSE);

275
276
277
	*rval = STRING_TO_JSVAL(str);

	dbprintf(FALSE, p, "read %u bytes",len);
278
279
280
281
282
		
	return(JS_TRUE);
}

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

291
	*rval = JSVAL_NULL;
292

293
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
294
		JS_ReportError(cx,getprivate_failure,WHERE);
295
		return(JS_FALSE);
296
	}
297
298
299

	if(p->fp==NULL)
		return(JS_TRUE);
300
301
	
	if(argc)
302
		JS_ValueToInt32(cx,argv[0],&len);
303

304
305
306
307
	if((buf=malloc(len))==NULL)
		return(JS_TRUE);

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

322
323
	free(buf);

324
325
326
327
	return(JS_TRUE);
}

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

336
	*rval = INT_TO_JSVAL(-1);
337

338
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
339
		JS_ReportError(cx,getprivate_failure,WHERE);
340
		return(JS_FALSE);
341
	}
342
343
344
345

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

346
	if(argc) 
347
		JS_ValueToInt32(cx,argv[0],(int32*)&size);
348
349
350

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

static JSBool
374
js_readall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
375
{
376
377
378
    jsint       len=0;
    jsval       line;
    JSObject*	array;
379
380
	private_t*	p;

381
382
	*rval = JSVAL_NULL;

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

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

391
    array = JS_NewArrayObject(cx, 0, NULL);
392

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

402
403
    return(JS_TRUE);
}
404

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

418
	*rval = JSVAL_VOID;
419
420
421
422
423
424
425
426
427
428
429

	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,
430
				iniGetString(p->fp,section,key
431
					,JS_GetStringBytes(JS_ValueToString(cx,dflt)),buf)));
432
433
434
			break;
		case JSVAL_BOOLEAN:
			*rval = BOOLEAN_TO_JSVAL(
435
				iniGetBool(p->fp,section,key,JSVAL_TO_BOOLEAN(dflt)));
436
437
438
			break;
		case JSVAL_DOUBLE:
			JS_NewNumberValue(cx
439
				,iniGetFloat(p->fp,section,key,*JSVAL_TO_DOUBLE(dflt)),rval);
440
			break;
441
442
		case JSVAL_OBJECT:
		    array = JS_NewArrayObject(cx, 0, NULL);
443
			list=iniGetStringList(p->fp,section,key,",",JS_GetStringBytes(JS_ValueToString(cx,dflt)));
444
445
446
447
448
449
450
451
			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;
452
453
454
		default:
			if(JSVAL_IS_INT(dflt)) {
				*rval = INT_TO_JSVAL(
455
					iniGetInteger(p->fp,section,key,JSVAL_TO_INT(dflt)));
456
457
458
459
460
461
462
463
				break;
			}
			break;
	}

	return(JS_TRUE);
}

464
465
466
static JSBool
js_iniGetSections(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
467
	char*		prefix=NULL;
468
469
470
471
472
473
474
475
476
477
478
479
480
	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);
	}

481
482
483
	if(argc)
		prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));

484
485
    array = JS_NewArrayObject(cx, 0, NULL);

486
	list = iniGetSectionList(p->fp,prefix);
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
    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);

519
	list = iniGetKeyList(p->fp,section);
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
    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;
539
	named_string_t** list;
540
541
542
543
544
545
546
547
548
549
550

	*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);

551
	list = iniGetNamedStringList(p->fp,section);
552
    for(i=0;list && list[i];i++) {
553
554
		JS_DefineProperty(cx, object, list[i]->name
			,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i]->value))
555
556
557
			,NULL,NULL,JSPROP_ENUMERATE);

	}
558
	iniFreeNamedStringList(list);
559
560
561
562
563
564

    *rval = OBJECT_TO_JSVAL(object);

    return(JS_TRUE);
}

565
566
567
568
static JSBool
js_iniGetAllObjects(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	char*		name="name";
569
	char*		sec_name;
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
	char*		prefix=NULL;
	char**		sec_list;
    jsint       i,k;
    jsval       val;
    JSObject*	array;
    JSObject*	object;
	private_t*	p;
	named_string_t** key_list;

	*rval = JSVAL_NULL;

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

	if(argc)
		name=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));

	if(argc>1)
		prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[1]));

    array = JS_NewArrayObject(cx, 0, NULL);

	sec_list = iniGetSectionList(p->fp,prefix);
    for(i=0;sec_list && sec_list[i];i++) {
	    object = JS_NewObject(cx, NULL, NULL, obj);

598
599
600
		sec_name=sec_list[i];
		if(prefix!=NULL)
			sec_name+=strlen(prefix);
601
		JS_DefineProperty(cx, object, name
602
			,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,sec_name))
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
			,NULL,NULL,JSPROP_ENUMERATE);

		key_list = iniGetNamedStringList(p->fp,sec_list[i]);
		for(k=0;key_list && key_list[k];k++)
			JS_DefineProperty(cx, object, key_list[k]->name
				,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,key_list[k]->value))
				,NULL,NULL,JSPROP_ENUMERATE);
		iniFreeNamedStringList(key_list);

		val=OBJECT_TO_JSVAL(object);
        if(!JS_SetElement(cx, array, i, &val))
			break;
	}
	iniFreeStringList(sec_list);

    *rval = OBJECT_TO_JSVAL(array);

    return(JS_TRUE);
}
622

623
624
625
626
static JSBool
js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	char*		cp;
627
628
629
	char*		uubuf=NULL;
	int			len;	/* string length */
	int			tlen;	/* total length to write (may be greater than len) */
630
	private_t*	p;
631

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

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

642
643
644
	cp=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
	len=strlen(cp);

645
	if((p->uuencoded || p->b64encoded || p->yencoded)
646
647
648
		&& len && (uubuf=malloc(len))!=NULL) {
		if(p->uuencoded)
			len=uudecode(uubuf,len,cp,len);
649
650
		else if(p->yencoded)
			len=ydecode(uubuf,len,cp,len);
651
652
		else
			len=b64_decode(uubuf,len,cp,len);
653
654
655
656
657
658
659
		if(len<0) {
			free(uubuf);
			return(JS_TRUE);
		}
		cp=uubuf;
	}

660
661
662
	if(p->rot13)
		rot13(cp);

663
	tlen=len;
664
	if(argc>1) {
665
		JS_ValueToInt32(cx,argv[1],(int32*)&tlen);
666
667
668
		if(len>tlen)
			len=tlen;
	}
669
670

	if(fwrite(cp,1,len,p->fp)==(size_t)len) {
671
672
673
674
675
676
677
678
679
680
681
		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);
682
		*rval = JSVAL_TRUE;
683
684
	} else 
		dbprintf(TRUE, p, "write of %u bytes failed",len);
685
		
686
687
688
	if(uubuf!=NULL)
		free(uubuf);

689
690
691
692
	return(JS_TRUE);
}

static JSBool
693
js_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
694
{
695
696
697
698
	char*		cp="";
	JSString*	str;
	private_t*	p;

699
	*rval = JSVAL_FALSE;
700

701
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
702
		JS_ReportError(cx,getprivate_failure,WHERE);
703
		return(JS_FALSE);
704
	}
705
706
707
708
709

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

	if(argc) {
710
711
		if((str = JS_ValueToString(cx, argv[0]))==NULL) {
			JS_ReportError(cx,"JS_ValueToString failed");
712
			return(JS_FALSE);
713
		}
714
715
716
		cp = JS_GetStringBytes(str);
	}

717
718
719
	if(p->rot13)
		rot13(cp);

720
	if(fprintf(p->fp,"%s\n",cp)!=0)
721
		*rval = JSVAL_TRUE;
722

723
724
	return(JS_TRUE);
}
725

726
static JSBool
727
js_writebin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
728
{
729
730
731
	BYTE		b;
	WORD		w;
	DWORD		l;
732
	int32		val=0;
733
	size_t		wr=0;
734
	size_t		size=sizeof(DWORD);
735
736
	private_t*	p;

737
	*rval = JSVAL_FALSE;
738

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

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

747
	JS_ValueToInt32(cx,argv[0],&val);
748
	if(argc>1) 
749
		JS_ValueToInt32(cx,argv[1],(int32*)&size);
750

751
752
	switch(size) {
		case sizeof(BYTE):
753
			b = (BYTE)val;
754
			wr=fwrite(&b,1,size,p->fp);
755
756
			break;
		case sizeof(WORD):
757
			w = (WORD)val;
758
759
			if(p->network_byte_order)
				w=htons(w);
760
			wr=fwrite(&w,1,size,p->fp);
761
762
			break;
		case sizeof(DWORD):
763
			l = val;
764
765
			if(p->network_byte_order)
				l=htonl(l);
766
767
768
769
770
			wr=fwrite(&l,1,size,p->fp);
			break;
		default:	
			/* unknown size */
			dbprintf(TRUE, p, "unsupported binary write size: %d",size);
771
772
			break;
	}
773
	if(wr==size)
774
		*rval = JSVAL_TRUE;
775
		
776
777
778
	return(JS_TRUE);
}

779
780
781
782
783
784
785
786
787
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;

788
	*rval = JSVAL_FALSE;
789

790
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
791
		JS_ReportError(cx,getprivate_failure,WHERE);
792
		return(JS_FALSE);
793
	}
794
795
796
797

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

798
	if(!JSVAL_IS_OBJECT(argv[0]))
799
800
801
802
		return(JS_TRUE);

    array = JSVAL_TO_OBJECT(argv[0]);

803
804
805
    if(!JS_IsArrayObject(cx, array))
		return(JS_TRUE);

806
807
    if(!JS_GetArrayLength(cx, array, &limit))
		return(JS_FALSE);
808

809
    *rval = JSVAL_TRUE;
810

811
812
813
814
    for(i=0;i<limit;i++) {
        if(!JS_GetElement(cx, array, i, &elemval))
			break;
        js_writeln(cx, obj, 1, &elemval, rval);
815
		if(*rval!=JSVAL_TRUE)
816
			break;
817
818
819
820
821
    }

    return(JS_TRUE);
}

822
static JSBool
823
js_lock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
824
{
825
826
	int32		offset=0;
	int32		len=0;
827
828
	private_t*	p;

829
	*rval = JSVAL_FALSE;
830

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

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

839
840
841
842
843
844
845
846
847
848
849
850
	/* 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)
851
		*rval = JSVAL_TRUE;
852

853
854
	return(JS_TRUE);
}
855

856
static JSBool
857
js_unlock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
858
{
859
860
	int32		offset=0;
	int32		len=0;
861
862
	private_t*	p;

863
	*rval = JSVAL_FALSE;
864

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

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

873
874
875
876
877
878
879
880
881
882
883
	/* 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;

884
	if(unlock(fileno(p->fp),offset,len)==0)
885
		*rval = JSVAL_TRUE;
886

887
888
889
	return(JS_TRUE);
}

890
891
892
893
894
static JSBool
js_delete(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	private_t*	p;

895
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
896
		JS_ReportError(cx,getprivate_failure,WHERE);
897
		return(JS_FALSE);
898
	}
899
900
901
902
903
904
905
906
907
908

	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);
}
909
910
911
912
913
914

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

915
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
916
		JS_ReportError(cx,getprivate_failure,WHERE);
917
		return(JS_FALSE);
918
	}
919
920

	if(p->fp==NULL)
921
		*rval = JSVAL_FALSE;
922
923
924
925
926
927
928
929
930
931
932
	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;

933
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
934
		JS_ReportError(cx,getprivate_failure,WHERE);
935
		return(JS_FALSE);
936
	}
937
938

	if(p->fp==NULL)
939
		*rval = JSVAL_FALSE;
940
941
	else  {
		clearerr(p->fp);
942
		*rval = JSVAL_TRUE;
943
944
945
946
947
	}

	return(JS_TRUE);
}

948
949
950
951
952
953
954
955
956
957
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;

958
	*rval = JSVAL_FALSE;
959

960
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
961
		JS_ReportError(cx,getprivate_failure,WHERE);
962
		return(JS_FALSE);
963
	}
964
965
966
967

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

968
969
	if((fmt=JS_ValueToString(cx, argv[0]))==NULL) {
		JS_ReportError(cx,"JS_ValueToString failed");
970
		return(JS_FALSE);
971
	}
972
973
974
975
976

	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])) {
977
978
			if((str=JS_ValueToString(cx, argv[i]))==NULL) {
				JS_ReportError(cx,"JS_ValueToString failed");
979
			    return(JS_FALSE);
980
			}
981
982
983
984
985
986
987
988
989
990
			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;
	}

991
992
	if((cp=JS_vsmprintf(JS_GetStringBytes(fmt),(char*)arglist))==NULL) {
		JS_ReportError(cx,"JS_vsmprintf failed");
993
		return(JS_FALSE);
994
	}
995
996
997
998
999
1000
1001

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

1002
1003
1004
1005

/* File Object Properites */
enum {
	 FILE_PROP_NAME		
1006
1007
	,FILE_PROP_MODE
	,FILE_PROP_ETX
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
	,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
1018
	,FILE_PROP_YENCODED
1019
	,FILE_PROP_UUENCODED
1020
	,FILE_PROP_B64ENCODED
1021
	,FILE_PROP_ROT13
1022
	,FILE_PROP_NETWORK_ORDER
1023
1024
1025
1026
1027
	/* dynamically calculated */
	,FILE_PROP_CHKSUM
	,FILE_PROP_CRC16
	,FILE_PROP_CRC32
	,FILE_PROP_MD5_HEX
1028
	,FILE_PROP_MD5_B64
1029
1030
};

rswindell's avatar
rswindell committed
1031

1032
1033
1034
1035
1036
static JSBool js_file_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    jsint       tiny;
	private_t*	p;

1037
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
1038
		JS_ReportError(cx,getprivate_failure,WHERE);
1039
		return(JS_FALSE);
1040
	}
1041
1042
1043
1044
1045
1046
1047

    tiny = JSVAL_TO_INT(id);

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

	switch(tiny) {
		case FILE_PROP_DEBUG:
1048
			JS_ValueToBoolean(cx,*vp,&(p->debug));
1049
			break;
1050
1051
1052
		case FILE_PROP_YENCODED:
			JS_ValueToBoolean(cx,*vp,&(p->yencoded));
			break;
1053
		case FILE_PROP_UUENCODED:
1054
1055
1056
1057
1058
			JS_ValueToBoolean(cx,*vp,&(p->uuencoded));
			break;
		case FILE_PROP_B64ENCODED:
			JS_ValueToBoolean(cx,*vp,&(p->b64encoded));
			break;
1059
1060
1061
		case FILE_PROP_ROT13:
			JS_ValueToBoolean(cx,*vp,&(p->rot13));
			break;
1062
1063
		case FILE_PROP_NETWORK_ORDER:
			JS_ValueToBoolean(cx,*vp,&(p->network_byte_order));
1064
			break;
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
		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;
1076
1077
1078
		case FILE_PROP_ETX:
			p->etx = (uchar)JSVAL_TO_INT(*vp);
			break;
1079
1080
1081
1082
1083
1084
1085
	}

	return(JS_TRUE);
}

static JSBool js_file_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
1086
	char		str