js_msgbase.c 47.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/* js_msgbase.c */

/* Synchronet JavaScript "MsgBase" 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 39 40 41 42 43 44 45 46 47 48 49 50
 *																			*
 * 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"

#ifdef JAVASCRIPT

static scfg_t* scfg=NULL;

typedef struct
{
	smb_t	smb;
	BOOL	debug;

} private_t;

51 52
static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
/* Destructor */

static void js_finalize_msgbase(JSContext *cx, JSObject *obj)
{
	private_t* p;
	
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
		return;

	if(SMB_IS_OPEN(&(p->smb)))
		smb_close(&(p->smb));

	free(p);

	JS_SetPrivate(cx, obj, NULL);
}

/* Methods */

72 73 74 75 76 77
static JSBool
js_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	private_t* p;
	
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
78
		JS_ReportError(cx,getprivate_failure,WHERE);
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
		return(JS_FALSE);
	}

	*rval = JSVAL_FALSE;

	if(p->smb.subnum==INVALID_SUB 
		&& strchr(p->smb.file,'/')==NULL
		&& strchr(p->smb.file,'\\')==NULL) {
		JS_ReportError(cx,"Unrecognized msgbase code: %s",p->smb.file);
		return(JS_TRUE);
	}

	if(smb_open(&(p->smb))!=0)
		return(JS_TRUE);

	*rval = JSVAL_TRUE;
	return(JS_TRUE);
}


99 100 101 102 103
static JSBool
js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	private_t* p;
	
104
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
105
		JS_ReportError(cx,getprivate_failure,WHERE);
106
		return(JS_FALSE);
107
	}
108 109 110 111 112 113 114

	smb_close(&(p->smb));

	*rval = JSVAL_VOID;
	return(JS_TRUE);
}

115
static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg)
116 117
{
	char*		cp;
118 119
	char		to[256];
	char		from[256];
120
	ushort		nettype;
121
	ushort		type;
122 123
	ushort		agent;
	int32		i32;
124
	jsval		val;
125 126 127
	JSObject*	array;
	JSObject*	field;
	jsuint		i,len;
128

129 130 131
	if(hdr==NULL)
		return(FALSE);

132
	/* Required Header Fields */
133
	if(JS_GetProperty(cx, hdr, "subject", &val) && val!=JSVAL_VOID) {
134
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
135 136 137
			return(FALSE);
	} else
		cp="";
138
	smb_hfield_str(msg, SUBJECT, cp);
139
	msg->idx.subj=subject_crc(cp);
140

141
	if(JS_GetProperty(cx, hdr, "to", &val) && val!=JSVAL_VOID) {
142
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
143 144
			return(FALSE);
	} else {
145 146
		if(p->smb.status.attr&SMB_EMAIL)	/* e-mail */
			return(FALSE);					/* "to" property required */
147 148
		cp="All";
	}
149
	smb_hfield_str(msg, RECIPIENT, cp);
150
	if(!(p->smb.status.attr&SMB_EMAIL)) {
151 152
		SAFECOPY(to,cp);
		strlwr(to);
153
		msg->idx.to=crc16(to,0);
154
	}
155

156
	if(JS_GetProperty(cx, hdr, "from", &val) && val!=JSVAL_VOID) {
157
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
158 159 160
			return(FALSE);
	} else
		return(FALSE);	/* "from" property required */
161
	smb_hfield_str(msg, SENDER, cp);
162
	if(!(p->smb.status.attr&SMB_EMAIL)) {
163 164
		SAFECOPY(from,cp);
		strlwr(from);
165
		msg->idx.from=crc16(from,0);
166
	}
167 168

	/* Optional Header Fields */
169
	if(JS_GetProperty(cx, hdr, "from_ext", &val) && val!=JSVAL_VOID) {
170
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
171
			return(FALSE);
172
		smb_hfield_str(msg, SENDEREXT, cp);
173
		if(p->smb.status.attr&SMB_EMAIL)
174 175 176
			msg->idx.from=atoi(cp);
	}

177
	if(JS_GetProperty(cx, hdr, "from_org", &val) && val!=JSVAL_VOID) {
178
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
179
			return(FALSE);
180
		smb_hfield_str(msg, SENDERORG, cp);
181 182
	}

183
	if(JS_GetProperty(cx, hdr, "from_net_type", &val) && val!=JSVAL_VOID) {
184 185
		JS_ValueToInt32(cx,val,&i32);
		nettype=(ushort)i32;
186
		smb_hfield(msg, SENDERNETTYPE, sizeof(nettype), &nettype);
187
		if(p->smb.status.attr&SMB_EMAIL && nettype!=NET_NONE)
188 189 190
			msg->idx.from=0;
	}

191
	if(JS_GetProperty(cx, hdr, "from_net_addr", &val) && val!=JSVAL_VOID) {
192
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
193
			return(FALSE);
194
		smb_hfield_str(msg, SENDERNETADDR, cp);
195 196
	}

197
	if(JS_GetProperty(cx, hdr, "from_agent", &val) && val!=JSVAL_VOID) {
198 199 200 201 202
		JS_ValueToInt32(cx,val,&i32);
		agent=(ushort)i32;
		smb_hfield(msg, SENDERAGENT, sizeof(agent), &agent);
	}

203 204 205 206 207 208 209 210 211 212 213 214
	if(JS_GetProperty(cx, hdr, "from_ip_addr", &val) && val!=JSVAL_VOID) {
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
			return(FALSE);
		smb_hfield_str(msg, SENDERIPADDR, cp);
	}

	if(JS_GetProperty(cx, hdr, "from_host_name", &val) && val!=JSVAL_VOID) {
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
			return(FALSE);
		smb_hfield_str(msg, SENDERHOSTNAME, cp);
	}

215
	if(JS_GetProperty(cx, hdr, "to_ext", &val) && val!=JSVAL_VOID) {
216
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
217
			return(FALSE);
218
		smb_hfield_str(msg, RECIPIENTEXT, cp);
219
		if(p->smb.status.attr&SMB_EMAIL)
220 221 222
			msg->idx.to=atoi(cp);
	}

223
	if(JS_GetProperty(cx, hdr, "to_org", &val) && val!=JSVAL_VOID) {
224 225
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
			return(FALSE);
226
		smb_hfield_str(msg, RECIPIENTORG, cp);
227 228
	}

229
	if(JS_GetProperty(cx, hdr, "to_net_type", &val) && val!=JSVAL_VOID) {
230 231
		JS_ValueToInt32(cx,val,&i32);
		nettype=(ushort)i32;
232
		smb_hfield(msg, RECIPIENTNETTYPE, sizeof(nettype), &nettype);
233
		if(p->smb.status.attr&SMB_EMAIL && nettype!=NET_NONE)
234 235 236
			msg->idx.to=0;
	}

237
	if(JS_GetProperty(cx, hdr, "to_net_addr", &val) && val!=JSVAL_VOID) {
238
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
239
			return(FALSE);
240
		smb_hfield_str(msg, RECIPIENTNETADDR, cp);
241
	}
242

243
	if(JS_GetProperty(cx, hdr, "to_agent", &val) && val!=JSVAL_VOID) {
244 245 246 247 248
		JS_ValueToInt32(cx,val,&i32);
		agent=(ushort)i32;
		smb_hfield(msg, RECIPIENTAGENT, sizeof(agent), &agent);
	}

249
	if(JS_GetProperty(cx, hdr, "replyto", &val) && val!=JSVAL_VOID) {
250
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
251
			return(FALSE);
252
		smb_hfield_str(msg, REPLYTO, cp);
253 254
	}

255
	if(JS_GetProperty(cx, hdr, "replyto_ext", &val) && val!=JSVAL_VOID) {
256
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
257
			return(FALSE);
258
		smb_hfield_str(msg, REPLYTOEXT, cp);
259 260
	}

261
	if(JS_GetProperty(cx, hdr, "replyto_org", &val) && val!=JSVAL_VOID) {
262 263
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
			return(FALSE);
264
		smb_hfield_str(msg, REPLYTOORG, cp);
265 266
	}

267
	if(JS_GetProperty(cx, hdr, "replyto_net_type", &val) && val!=JSVAL_VOID) {
268 269
		JS_ValueToInt32(cx,val,&i32);
		nettype=(ushort)i32;
270 271 272
		smb_hfield(msg, REPLYTONETTYPE, sizeof(nettype), &nettype);
	}

273
	if(JS_GetProperty(cx, hdr, "replyto_net_addr", &val) && val!=JSVAL_VOID) {
274
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
275
			return(FALSE);
276
		smb_hfield_str(msg, REPLYTONETADDR, cp);
277 278
	}

279
	if(JS_GetProperty(cx, hdr, "replyto_agent", &val) && val!=JSVAL_VOID) {
280 281 282 283 284
		JS_ValueToInt32(cx,val,&i32);
		agent=(ushort)i32;
		smb_hfield(msg, REPLYTOAGENT, sizeof(agent), &agent);
	}

285
	/* RFC822 headers */
286
	if(JS_GetProperty(cx, hdr, "id", &val) && val!=JSVAL_VOID) {
287
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
288
			return(FALSE);
289
		smb_hfield_str(msg, RFC822MSGID, cp);
290 291
	}

292
	if(JS_GetProperty(cx, hdr, "reply_id", &val) && val!=JSVAL_VOID) {
293
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
294
			return(FALSE);
295
		smb_hfield_str(msg, RFC822REPLYID, cp);
296 297
	}

298
	if(JS_GetProperty(cx, hdr, "reverse_path", &val) && val!=JSVAL_VOID) {
299
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
300
			return(FALSE);
301
		smb_hfield_str(msg, SMTPREVERSEPATH, cp);
302 303
	}

304
	/* USENET headers */
305
	if(JS_GetProperty(cx, hdr, "path", &val) && val!=JSVAL_VOID) {
306
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
307
			return(FALSE);
308
		smb_hfield_str(msg, USENETPATH, cp);
309 310
	}

311
	if(JS_GetProperty(cx, hdr, "newsgroups", &val) && val!=JSVAL_VOID) {
312
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
313
			return(FALSE);
314
		smb_hfield_str(msg, USENETNEWSGROUPS, cp);
315 316 317
	}

	/* FTN headers */
318
	if(JS_GetProperty(cx, hdr, "ftn_msgid", &val) && val!=JSVAL_VOID) {
319
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
320
			return(FALSE);
321
		smb_hfield_str(msg, FIDOMSGID, cp);
322 323
	}

324
	if(JS_GetProperty(cx, hdr, "ftn_reply", &val) && val!=JSVAL_VOID) {
325
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
326
			return(FALSE);
327
		smb_hfield_str(msg, FIDOREPLYID, cp);
328 329
	}

330
	if(JS_GetProperty(cx, hdr, "ftn_area", &val) && val!=JSVAL_VOID) {
331
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
332
			return(FALSE);
333
		smb_hfield_str(msg, FIDOAREA, cp);
334 335
	}

336
	if(JS_GetProperty(cx, hdr, "ftn_flags", &val) && val!=JSVAL_VOID) {
337
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
338
			return(FALSE);
339
		smb_hfield_str(msg, FIDOFLAGS, cp);
340 341
	}

342
	if(JS_GetProperty(cx, hdr, "ftn_pid", &val) && val!=JSVAL_VOID) {
343
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
344
			return(FALSE);
345
		smb_hfield_str(msg, FIDOPID, cp);
346 347
	}

348
	if(JS_GetProperty(cx, hdr, "ftn_tid", &val) && val!=JSVAL_VOID) {
349
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
350
			return(FALSE);
351
		smb_hfield_str(msg, FIDOTID, cp);
352 353
	}

354
	if(JS_GetProperty(cx, hdr, "date", &val) && val!=JSVAL_VOID) {
355
		if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
356 357 358
			return(FALSE);
		msg->hdr.when_written=rfc822date(cp);
	}
359 360
	
	/* Numeric Header Fields */
361
	if(JS_GetProperty(cx, hdr, "attr", &val) && val!=JSVAL_VOID) {
362 363
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.attr=(ushort)i32;
364 365
		msg->idx.attr=msg->hdr.attr;
	}
366
	if(JS_GetProperty(cx, hdr, "auxattr", &val) && val!=JSVAL_VOID) {
367 368 369
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.auxattr=i32;
	}
370
	if(JS_GetProperty(cx, hdr, "netattr", &val) && val!=JSVAL_VOID) {
371 372 373
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.netattr=i32;
	}
374
	if(JS_GetProperty(cx, hdr, "when_written_time", &val) && val!=JSVAL_VOID)  {
375 376 377
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.when_written.time=i32;
	}
378
	if(JS_GetProperty(cx, hdr, "when_written_zone", &val) && val!=JSVAL_VOID) {
379 380 381
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.when_written.zone=(short)i32;
	}
382
	if(JS_GetProperty(cx, hdr, "when_imported_time", &val) && val!=JSVAL_VOID) {
383 384 385
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.when_imported.time=i32;
	}
386
	if(JS_GetProperty(cx, hdr, "when_imported_zone", &val) && val!=JSVAL_VOID) {
387 388 389 390
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.when_imported.zone=(short)i32;
	}

391
	if(JS_GetProperty(cx, hdr, "thread_orig", &val) && val!=JSVAL_VOID) {
392 393 394
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.thread_orig=i32;
	}
395
	if(JS_GetProperty(cx, hdr, "thread_next", &val) && val!=JSVAL_VOID) {
396 397 398
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.thread_next=i32;
	}
399
	if(JS_GetProperty(cx, hdr, "thread_first", &val) && val!=JSVAL_VOID) {
400 401 402
		JS_ValueToInt32(cx,val,&i32);
		msg->hdr.thread_first=i32;
	}
403

404 405 406
	if(JS_GetProperty(cx, hdr, "field_list", &val) && JSVAL_IS_OBJECT(val)) {
		array=JSVAL_TO_OBJECT(val);
		len=0;
407 408
		if(!JS_GetArrayLength(cx, array, &len))
			return(FALSE);
409 410 411 412 413 414 415

		for(i=0;i<len;i++) {
			if(!JS_GetElement(cx, array, i, &val))
				continue;
			if(!JSVAL_IS_OBJECT(val))
				continue;
			field=JSVAL_TO_OBJECT(val);
416
			if(!JS_GetProperty(cx, field, "type", &val))
417
				continue;
418 419 420 421 422 423
			if(JSVAL_IS_STRING(val))
				type=smb_hfieldtypelookup(JS_GetStringBytes(JS_ValueToString(cx,val)));
			else {
				JS_ValueToInt32(cx,val,&i32);
				type=(ushort)i32;
			}
424
			if(!JS_GetProperty(cx, field, "data", &val))
425
				continue;
426
			if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
427
				return(FALSE);
428
			smb_hfield_str(msg, type, cp);
429 430 431
		}
	}

432 433 434
	return(TRUE);
}

435
BOOL msg_offset_by_id(scfg_t* scfg, smb_t* smb, char* id, ulong* offset)
436 437 438
{
	smbmsg_t msg;

439
	if(!get_msg_by_id(scfg,smb,id,&msg))
440 441 442 443 444 445 446 447
		return(FALSE);

	smb_freemsgmem(&msg);

	*offset = msg.offset;
	return(TRUE);
}

448 449 450 451
static JSBool
js_get_msg_index(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
	uintN		n;
452
	jsval		val;
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
	smbmsg_t	msg;
	JSObject*	idxobj;
	JSBool		by_offset=JS_FALSE;
	private_t*	p;

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

	if(!SMB_IS_OPEN(&(p->smb)))
		return(JS_TRUE);

	memset(&msg,0,sizeof(msg));

	for(n=0;n<argc;n++) {
		if(JSVAL_IS_BOOLEAN(argv[n]))
			by_offset=JSVAL_TO_BOOLEAN(argv[n]);
473
		else if(JSVAL_IS_NUMBER(argv[n])) {
474
			if(by_offset)							/* Get by offset */
475
				JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
476
			else									/* Get by number */
477
				JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
478 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

			if(smb_getmsgidx(&(p->smb), &msg)!=0)
				return(JS_TRUE);

			break;
		}
	}

	if((idxobj=JS_NewObject(cx,NULL,NULL,obj))==NULL)
		return(JS_TRUE);

	JS_DefineProperty(cx, idxobj, "number", INT_TO_JSVAL(msg.idx.number)
		,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

	JS_DefineProperty(cx, idxobj, "to" ,INT_TO_JSVAL(msg.idx.to)
		,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

	JS_DefineProperty(cx, idxobj, "from" ,INT_TO_JSVAL(msg.idx.from)
		,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

	JS_DefineProperty(cx, idxobj, "subject" ,INT_TO_JSVAL(msg.idx.subj)
		,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

	JS_DefineProperty(cx, idxobj, "attr" ,INT_TO_JSVAL(msg.idx.attr)
		,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

504 505
	JS_NewNumberValue(cx,msg.idx.offset,&val);
	JS_DefineProperty(cx, idxobj, "offset", val
506 507
		,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

508 509
	JS_NewNumberValue(cx,msg.idx.time,&val);
	JS_DefineProperty(cx, idxobj, "time", val
510 511 512 513 514 515 516
		,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

	*rval = OBJECT_TO_JSVAL(idxobj);

	return(JS_TRUE);
}

517 518 519
static JSBool
js_get_msg_header(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
520
	char		date[128];
521 522
	char		msg_id[256];
	char		reply_id[256];
523
	char*		val;
524
	int			i;
525
	uintN		n;
526
	smbmsg_t	msg;
527
	smbmsg_t	orig_msg;
528
	JSObject*	hdrobj;
529 530
	JSObject*	array;
	JSObject*	field;
531
	JSString*	js_str;
532
	jsint		items;
533
	jsval		v;
534
	JSBool		by_offset=JS_FALSE;
535 536 537 538
	private_t*	p;

	*rval = JSVAL_NULL;
	
539
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
540
		JS_ReportError(cx,getprivate_failure,WHERE);
541
		return(JS_FALSE);
542
	}
543

544 545 546
	if(!SMB_IS_OPEN(&(p->smb)))
		return(JS_TRUE);

547 548
	memset(&msg,0,sizeof(msg));

549 550 551
	for(n=0;n<argc;n++) {
		if(JSVAL_IS_BOOLEAN(argv[n]))
			by_offset=JSVAL_TO_BOOLEAN(argv[n]);
552
		else if(JSVAL_IS_NUMBER(argv[n])) {
553
			if(by_offset)							/* Get by offset */
554
				JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
555
			else									/* Get by number */
556
				JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
557 558 559 560 561 562 563 564 565 566 567 568 569

			if(smb_getmsgidx(&(p->smb), &msg)!=0)
				return(JS_TRUE);

			if(smb_lockmsghdr(&(p->smb),&msg)!=0)
				return(JS_TRUE);

			if(smb_getmsghdr(&(p->smb), &msg)!=0) {
				smb_unlockmsghdr(&(p->smb),&msg); 
				return(JS_TRUE);
			}

			smb_unlockmsghdr(&(p->smb),&msg); 
570 571
			break;
		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
572
			if(!get_msg_by_id(scfg,&(p->smb)
573
				,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))
574
				,&msg))
575
				return(JS_TRUE);	/* ID not found */
576

577 578 579
			break;
		}
	}
580

581
	if(msg.hdr.number==0) /* No valid message number/id/offset specified */
582 583
		return(JS_TRUE);

584
	if((hdrobj=JS_NewObject(cx,NULL,NULL,obj))==NULL) {
rswindell's avatar
rswindell committed
585
		smb_freemsgmem(&msg);
586
		return(JS_TRUE);
rswindell's avatar
rswindell committed
587
	}
588

589 590
	JS_NewNumberValue(cx,msg.hdr.number,&v);
	JS_DefineProperty(cx, hdrobj, "number", v, NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
591 592 593

	if((js_str=JS_NewStringCopyZ(cx,truncsp(msg.to)))==NULL)
		return(JS_FALSE);
594
	JS_DefineProperty(cx, hdrobj, "to"
595
		,STRING_TO_JSVAL(js_str)
596
		,NULL,NULL,JSPROP_ENUMERATE);
597 598 599

	if((js_str=JS_NewStringCopyZ(cx,truncsp(msg.from)))==NULL)
		return(JS_FALSE);
600
	JS_DefineProperty(cx, hdrobj, "from"
601
		,STRING_TO_JSVAL(js_str)
602
		,NULL,NULL,JSPROP_ENUMERATE);
603 604 605

	if((js_str=JS_NewStringCopyZ(cx,truncsp(msg.subj)))==NULL)
		return(JS_FALSE);
606
	JS_DefineProperty(cx, hdrobj, "subject"
607
		,STRING_TO_JSVAL(js_str)
608
		,NULL,NULL,JSPROP_ENUMERATE);
609 610
	if(msg.summary!=NULL 
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.summary)))!=NULL)
611
		JS_DefineProperty(cx, hdrobj, "summary"
612
			,STRING_TO_JSVAL(js_str)
613
			,NULL,NULL,JSPROP_ENUMERATE);
614 615
	if(msg.to_ext!=NULL 
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.to_ext)))!=NULL)
616
		JS_DefineProperty(cx, hdrobj, "to_ext"
617
			,STRING_TO_JSVAL(js_str)
618
			,NULL,NULL,JSPROP_ENUMERATE);
619 620
	if(msg.from_ext!=NULL 
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.from_ext)))!=NULL)
621
		JS_DefineProperty(cx, hdrobj, "from_ext"
622
			,STRING_TO_JSVAL(js_str)
623
			,NULL,NULL,JSPROP_ENUMERATE);
624 625
	if(msg.from_org!=NULL
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.from_org)))!=NULL)
626
		JS_DefineProperty(cx, hdrobj, "from_org"
627
			,STRING_TO_JSVAL(js_str)
628
			,NULL,NULL,JSPROP_ENUMERATE);
629 630
	if(msg.replyto!=NULL
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.replyto)))!=NULL)
631
		JS_DefineProperty(cx, hdrobj, "replyto"
632
			,STRING_TO_JSVAL(js_str)
633
			,NULL,NULL,JSPROP_ENUMERATE);
634 635
	if(msg.replyto_ext!=NULL
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.replyto_ext)))!=NULL)
636
		JS_DefineProperty(cx, hdrobj, "replyto_ext"
637
			,STRING_TO_JSVAL(js_str)
638
			,NULL,NULL,JSPROP_ENUMERATE);
639 640
	if(msg.reverse_path!=NULL
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.reverse_path)))!=NULL)
641
		JS_DefineProperty(cx, hdrobj, "reverse_path"
642
			,STRING_TO_JSVAL(js_str)
643
			,NULL,NULL,JSPROP_ENUMERATE);
644

645
	JS_DefineProperty(cx, hdrobj, "to_agent",INT_TO_JSVAL(msg.to_agent)
646
		,NULL,NULL,JSPROP_ENUMERATE);
647
	JS_DefineProperty(cx, hdrobj, "from_agent",INT_TO_JSVAL(msg.from_agent)
648
		,NULL,NULL,JSPROP_ENUMERATE);
649
	JS_DefineProperty(cx, hdrobj, "replyto_agent",INT_TO_JSVAL(msg.replyto_agent)
650
		,NULL,NULL,JSPROP_ENUMERATE);
651 652

	JS_DefineProperty(cx, hdrobj, "to_net_type",INT_TO_JSVAL(msg.to_net.type)
653
		,NULL,NULL,JSPROP_ENUMERATE);
654 655
	if(msg.to_net.type
		&& (js_str=JS_NewStringCopyZ(cx,net_addr(&msg.to_net)))!=NULL)
656
		JS_DefineProperty(cx, hdrobj, "to_net_addr"
657
			,STRING_TO_JSVAL(js_str)
658
			,NULL,NULL,JSPROP_ENUMERATE);
659 660

	JS_DefineProperty(cx, hdrobj, "from_net_type",INT_TO_JSVAL(msg.from_net.type)
661
		,NULL,NULL,JSPROP_ENUMERATE);
662 663
	if(msg.from_net.type
		&& (js_str=JS_NewStringCopyZ(cx,net_addr(&msg.from_net)))!=NULL)
664
		JS_DefineProperty(cx, hdrobj, "from_net_addr"
665
			,STRING_TO_JSVAL(js_str)
666
			,NULL,NULL,JSPROP_ENUMERATE);
667 668

	JS_DefineProperty(cx, hdrobj, "replyto_net_type",INT_TO_JSVAL(msg.replyto_net.type)
669
		,NULL,NULL,JSPROP_ENUMERATE);
670 671
	if(msg.replyto_net.type
		&& (js_str=JS_NewStringCopyZ(cx,net_addr(&msg.replyto_net)))!=NULL)
672
		JS_DefineProperty(cx, hdrobj, "replyto_net_addr"
673
			,STRING_TO_JSVAL(js_str)
674
			,NULL,NULL,JSPROP_ENUMERATE);
675

676 677 678 679 680 681 682 683 684 685 686 687
	if((val=smb_get_hfield(&msg,SENDERIPADDR,NULL))!=NULL
		&& (js_str=JS_NewStringCopyZ(cx,val))!=NULL)
		JS_DefineProperty(cx, hdrobj, "from_ip_addr"
			,STRING_TO_JSVAL(js_str)
			,NULL,NULL,JSPROP_ENUMERATE);

	if((val=smb_get_hfield(&msg,SENDERHOSTNAME,NULL))!=NULL
		&& (js_str=JS_NewStringCopyZ(cx,val))!=NULL)
		JS_DefineProperty(cx, hdrobj, "from_host_name"
			,STRING_TO_JSVAL(js_str)
			,NULL,NULL,JSPROP_ENUMERATE);
		
688
	JS_DefineProperty(cx, hdrobj, "forwarded",INT_TO_JSVAL(msg.forwarded)
689
		,NULL,NULL,JSPROP_ENUMERATE);
690 691 692 693 694 695
	JS_NewNumberValue(cx,msg.expiration,&v);
	JS_DefineProperty(cx, hdrobj, "expiration",v,NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.priority,&v);
	JS_DefineProperty(cx, hdrobj, "priority",v,NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.cost,&v);
	JS_DefineProperty(cx, hdrobj, "cost",v,NULL,NULL,JSPROP_ENUMERATE);
696

697 698

	JS_DefineProperty(cx, hdrobj, "type", INT_TO_JSVAL(msg.hdr.type)
699
		,NULL,NULL,JSPROP_ENUMERATE);
700
	JS_DefineProperty(cx, hdrobj, "version", INT_TO_JSVAL(msg.hdr.version)
701
		,NULL,NULL,JSPROP_ENUMERATE);
702
	JS_DefineProperty(cx, hdrobj, "attr", INT_TO_JSVAL(msg.hdr.attr)
703
		,NULL,NULL,JSPROP_ENUMERATE);
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
	JS_NewNumberValue(cx,msg.hdr.auxattr,&v);
	JS_DefineProperty(cx, hdrobj, "auxattr", v, NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.hdr.netattr,&v);
	JS_DefineProperty(cx, hdrobj, "netattr", v, NULL,NULL,JSPROP_ENUMERATE);

	JS_NewNumberValue(cx,msg.hdr.when_written.time,&v);
	JS_DefineProperty(cx, hdrobj, "when_written_time", v, NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.hdr.when_written.zone,&v);
	JS_DefineProperty(cx, hdrobj, "when_written_zone", v, NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.hdr.when_imported.time,&v);
	JS_DefineProperty(cx, hdrobj, "when_imported_time", v, NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.hdr.when_imported.zone,&v);
	JS_DefineProperty(cx, hdrobj, "when_imported_zone", v, NULL,NULL,JSPROP_ENUMERATE);

	JS_NewNumberValue(cx,msg.hdr.thread_orig,&v);
	JS_DefineProperty(cx, hdrobj, "thread_orig", v, NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.hdr.thread_next,&v);
	JS_DefineProperty(cx, hdrobj, "thread_next", v, NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.hdr.thread_first,&v);
	JS_DefineProperty(cx, hdrobj, "thread_first", v, NULL,NULL,JSPROP_ENUMERATE);

	JS_NewNumberValue(cx,msg.hdr.delivery_attempts,&v);
	JS_DefineProperty(cx, hdrobj, "delivery_attempts", v, NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.hdr.last_downloaded,&v);
	JS_DefineProperty(cx, hdrobj, "last_downloaded", v, NULL,NULL,JSPROP_ENUMERATE);
	JS_NewNumberValue(cx,msg.hdr.times_downloaded,&v);
	JS_DefineProperty(cx, hdrobj, "times_downloaded", v, NULL,NULL,JSPROP_ENUMERATE);

	JS_NewNumberValue(cx,smb_getmsgdatlen(&msg),&v);
	JS_DefineProperty(cx, hdrobj, "data_length", v, NULL,NULL,JSPROP_ENUMERATE);
734

735 736
	if((js_str=JS_NewStringCopyZ(cx,msgdate(msg.hdr.when_written,date)))==NULL)
		return(JS_FALSE);
737
	JS_DefineProperty(cx, hdrobj, "date"
738
		,STRING_TO_JSVAL(js_str)
739
		,NULL,NULL,JSPROP_ENUMERATE);
740

741
	/* Reply-ID (References) */
742
	if(msg.reply_id!=NULL)
743 744 745
		val=msg.reply_id;
	else {
		reply_id[0]=0;
746
		if(msg.hdr.thread_orig) {
747 748 749 750 751
			memset(&orig_msg,0,sizeof(orig_msg));
			orig_msg.hdr.number=msg.hdr.thread_orig;
			if(smb_getmsgidx(&(p->smb), &orig_msg))
				sprintf(reply_id,"<%s>",p->smb.last_error);
			else
752
				SAFECOPY(reply_id,get_msgid(scfg,p->smb.subnum,&orig_msg));
753
		}
754 755
		val=reply_id;
	}
756
	if(val[0] && (js_str=JS_NewStringCopyZ(cx,truncsp(val)))!=NULL)
757
		JS_DefineProperty(cx, hdrobj, "reply_id"
758
			, STRING_TO_JSVAL(js_str)
759
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
760 761

	/* Message-ID */
762 763
	SAFECOPY(msg_id,get_msgid(scfg,p->smb.subnum,&msg));
	val=msg_id;
764 765
	if((js_str=JS_NewStringCopyZ(cx,truncsp(val)))==NULL)
		return(JS_FALSE);
766
	JS_DefineProperty(cx, hdrobj, "id"
767
		,STRING_TO_JSVAL(js_str)
768 769
		,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);

770
	/* USENET Fields */
771 772
	if(msg.path!=NULL
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.path)))!=NULL)
773
		JS_DefineProperty(cx, hdrobj, "path"
774
			,STRING_TO_JSVAL(js_str)
775
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
776 777
	if(msg.newsgroups!=NULL
		&& (js_str=JS_NewStringCopyZ(cx,truncsp(msg.newsgroups)))!=NULL)
778
		JS_DefineProperty(cx, hdrobj, "newsgroups"