js_msgbase.c 84.8 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 2012 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
#include "js_request.h"
40
#include "userdat.h"
41
42
43

#ifdef JAVASCRIPT

44
static scfg_t* 		scfg=NULL;
45
46
47
48

typedef struct
{
	smb_t	smb;
49
	int		status;
50
51
52
53
	BOOL	debug;

} private_t;

54
55
56
57
58
59
60
61
typedef struct
{
	private_t	*p;
	BOOL		expand_fields;
	smbmsg_t	msg;

} privatemsg_t;

62
63
static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* 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 */

83
static JSBool
84
js_open(JSContext *cx, uintN argc, jsval *arglist)
85
{
86
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
87
	private_t* p;
deuce's avatar
deuce committed
88
	jsrefcount	rc;
89
90
	
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
91
		JS_ReportError(cx,getprivate_failure,WHERE);
92
93
94
		return(JS_FALSE);
	}

95
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
96
97
98
99
100
101
102
103

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

104
	rc=JS_SUSPENDREQUEST(cx);
deuce's avatar
deuce committed
105
	if((p->status=smb_open(&(p->smb)))!=SMB_SUCCESS) {
106
		JS_RESUMEREQUEST(cx, rc);
107
		return(JS_TRUE);
deuce's avatar
deuce committed
108
	}
109
	JS_RESUMEREQUEST(cx, rc);
110

111
	JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
112
113
114
115
	return(JS_TRUE);
}


116
static JSBool
117
js_close(JSContext *cx, uintN argc, jsval *arglist)
118
{
119
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
120
	private_t* p;
deuce's avatar
deuce committed
121
	jsrefcount	rc;
122
	
123
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
124
		JS_ReportError(cx,getprivate_failure,WHERE);
125
		return(JS_FALSE);
126
	}
127

128
129
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

130
	rc=JS_SUSPENDREQUEST(cx);
131
	smb_close(&(p->smb));
132
	JS_RESUMEREQUEST(cx, rc);
133
134
135
136

	return(JS_TRUE);
}

137
static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg)
138
139
{
	char*		cp;
140
	char		to[256];
141
	ushort		nettype=NET_UNKNOWN;
142
143
144
145
	ushort		agent;
	int32		i32;
	jsval		val;

146
	if(JS_GetProperty(cx, hdr, "to", &val) && !JSVAL_NULL_OR_VOID(val)) {
147
		JSVALUE_TO_STRING(cx, val, cp, NULL);
148
149
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to\" string in recipient object");
150
			return(FALSE);
151
		}
152
	} else {
153
154
		if(p->smb.status.attr&SMB_EMAIL) {	/* e-mail */
			JS_ReportError(cx, "\"to\" property not included in email recipient object");
155
			return(FALSE);					/* "to" property required */
156
		}
157
158
		cp="All";
	}
deuce's avatar
deuce committed
159

160
	if((p->status=smb_hfield_str(msg, RECIPIENT, cp))!=SMB_SUCCESS) {
161
		JS_ReportError(cx, "Error %d adding RECIPIENT field to message header", p->status);
162
		return(FALSE);
163
	}
164
165
166
167
168
169
	if(!(p->smb.status.attr&SMB_EMAIL)) {
		SAFECOPY(to,cp);
		strlwr(to);
		msg->idx.to=crc16(to,0);
	}

170
	if(JS_GetProperty(cx, hdr, "to_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
171
		JSVALUE_TO_STRING(cx, val, cp, NULL);
172
173
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to_ext\" string in recipient object");
rswindell's avatar
rswindell committed
174
			return(FALSE);
175
176
		}
		if((p->status=smb_hfield_str(msg, RECIPIENTEXT, cp))!=SMB_SUCCESS) {
177
			JS_ReportError(cx, "Error %d adding RECIPIENTEXT field to message header", p->status);
178
			return(FALSE);
179
		}
rswindell's avatar
rswindell committed
180
181
182
183
		if(p->smb.status.attr&SMB_EMAIL)
			msg->idx.to=atoi(cp);
	}

184
	if(JS_GetProperty(cx, hdr, "to_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
185
		JSVALUE_TO_STRING(cx, val, cp, NULL);
186
187
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to_org\" string in recipient object");
rswindell's avatar
rswindell committed
188
			return(FALSE);
189
190
		}
		if((p->status=smb_hfield_str(msg, RECIPIENTORG, cp))!=SMB_SUCCESS) {
191
			JS_ReportError(cx, "Error %d adding RECIPIENTORG field to message header", p->status);
192
			return(FALSE);
193
		}
rswindell's avatar
rswindell committed
194
195
	}

196
	if(JS_GetProperty(cx, hdr, "to_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
197
198
		if(!JS_ValueToInt32(cx,val,&i32))
			return(FALSE);
rswindell's avatar
rswindell committed
199
200
201
		nettype=(ushort)i32;
	}

202
	if(JS_GetProperty(cx, hdr, "to_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
203
		JSVALUE_TO_STRING(cx, val, cp, NULL);
204
205
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to_net_addr\" string in recipient object");
rswindell's avatar
rswindell committed
206
			return(FALSE);
207
208
		}
		if((p->status=smb_hfield_netaddr(msg, RECIPIENTNETADDR, cp, &nettype))!=SMB_SUCCESS) {
209
			JS_ReportError(cx, "Error %d adding RECIPIENTADDR field to message header", p->status);
210
			return(FALSE);
211
		}
212
213
214
215
216
	}

	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
		if(p->smb.status.attr&SMB_EMAIL)
			msg->idx.to=0;
217
		if((p->status=smb_hfield_bin(msg, RECIPIENTNETTYPE, nettype))!=SMB_SUCCESS) {
218
			JS_ReportError(cx, "Error %d adding RECIPIENTNETTYPE field to message header", p->status);
219
			return(FALSE);
220
		}
rswindell's avatar
rswindell committed
221
222
	}

223
	if(JS_GetProperty(cx, hdr, "to_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
224
225
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
rswindell's avatar
rswindell committed
226
		agent=(ushort)i32;
227
		if((p->status=smb_hfield_bin(msg, RECIPIENTAGENT, agent))!=SMB_SUCCESS) {
228
			JS_ReportError(cx, "Error %d adding RECIPIENTAGENT field to message header", p->status);
229
			return(FALSE);
230
		}
rswindell's avatar
rswindell committed
231
	}
232
233
234
235
236
237
238
239

	return(TRUE);
}

static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg
								,BOOL recipient)
{
	char*		cp;
240
	char		from[256];
241
	ushort		nettype=NET_UNKNOWN;
242
	ushort		type;
243
244
	ushort		agent;
	int32		i32;
245
	jsval		val;
246
247
248
	JSObject*	array;
	JSObject*	field;
	jsuint		i,len;
249

250
251
	if(hdr==NULL) {
		JS_ReportError(cx, "NULL header object");
252
		return(FALSE);
253
	}
254

255
256
257
	if(recipient && !parse_recipient_object(cx,p,hdr,msg))
		return(FALSE);

258
	/* Required Header Fields */
259
	if(JS_GetProperty(cx, hdr, "subject", &val) && !JSVAL_NULL_OR_VOID(val)) {
260
		JSVALUE_TO_STRING(cx, val, cp, NULL);
261
262
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"subject\" string in header object");
263
			return(FALSE);
264
		}
265
266
	} else
		cp="";
267
268

	if((p->status=smb_hfield_str(msg, SUBJECT, cp))!=SMB_SUCCESS) {
269
		JS_ReportError(cx, "Error %d adding SUBJECT field to message header", p->status);
270
		return(FALSE);
271
	}
272
	msg->idx.subj=smb_subject_crc(cp);
273

274
	if(JS_GetProperty(cx, hdr, "from", &val) && !JSVAL_NULL_OR_VOID(val)) {
275
		JSVALUE_TO_STRING(cx, val, cp, NULL);
276
277
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from\" string in header object");
278
			return(FALSE);
279
280
281
		}
	} else {
		JS_ReportError(cx, "\"from\" property required in header");
282
		return(FALSE);	/* "from" property required */
283
284
	}
	if((p->status=smb_hfield_str(msg, SENDER, cp))!=SMB_SUCCESS) {
285
		JS_ReportError(cx, "Error %d adding SENDER field to message header", p->status);
286
		return(FALSE);
287
	}
288
	if(!(p->smb.status.attr&SMB_EMAIL)) {
289
290
		SAFECOPY(from,cp);
		strlwr(from);
291
		msg->idx.from=crc16(from,0);
292
	}
293
294

	/* Optional Header Fields */
295
	if(JS_GetProperty(cx, hdr, "from_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
296
		JSVALUE_TO_STRING(cx, val, cp, NULL);
297
298
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_ext\" string in header object");
299
			return(FALSE);
300
301
		}
		if((p->status=smb_hfield_str(msg, SENDEREXT, cp))!=SMB_SUCCESS) {
302
			JS_ReportError(cx, "Error %d adding SENDEREXT field to message header", p->status);
303
			return(FALSE);
304
		}
305
		if(p->smb.status.attr&SMB_EMAIL)
306
307
308
			msg->idx.from=atoi(cp);
	}

309
	if(JS_GetProperty(cx, hdr, "from_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
310
		JSVALUE_TO_STRING(cx, val, cp, NULL);
311
312
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_org\" string in header object");
313
			return(FALSE);
314
315
		}
		if((p->status=smb_hfield_str(msg, SENDERORG, cp))!=SMB_SUCCESS) {
316
			JS_ReportError(cx, "Error %d adding SENDERORG field to message header", p->status);
317
			return(FALSE);
318
		}
319
320
	}

321
	if(JS_GetProperty(cx, hdr, "from_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
322
323
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
324
		nettype=(ushort)i32;
325
326
	}

327
	if(JS_GetProperty(cx, hdr, "from_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
328
		JSVALUE_TO_STRING(cx, val, cp, NULL);
329
330
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_net_addr\" string in header object");
331
			return(FALSE);
332
333
		}
		if((p->status=smb_hfield_netaddr(msg, SENDERNETADDR, cp, &nettype))!=SMB_SUCCESS) {
334
			JS_ReportError(cx, "Error %d adding SENDERNETADDR field to message header", p->status);
335
			return(FALSE);
336
		}
337
338
339
340
341
	}
	
	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
		if(p->smb.status.attr&SMB_EMAIL)
			msg->idx.from=0;
342
		if((p->status=smb_hfield_bin(msg, SENDERNETTYPE, nettype))!=SMB_SUCCESS) {
343
			JS_ReportError(cx, "Error %d adding SENDERNETTYPE field to message header", p->status);
344
			return(FALSE);
345
		}
346
347
	}

348
	if(JS_GetProperty(cx, hdr, "from_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
349
350
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
351
		agent=(ushort)i32;
352
		if((p->status=smb_hfield_bin(msg, SENDERAGENT, agent))!=SMB_SUCCESS) {
353
			JS_ReportError(cx, "Error %d adding SENDERAGENT field to message header", p->status);
354
			return(FALSE);
355
		}
356
357
	}

358
	if(JS_GetProperty(cx, hdr, "from_ip_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
359
		JSVALUE_TO_STRING(cx, val, cp, NULL);
360
361
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_ip_addr\" string in header object");
362
			return(FALSE);
363
364
		}
		if((p->status=smb_hfield_str(msg, SENDERIPADDR, cp))!=SMB_SUCCESS) {
365
			JS_ReportError(cx, "Error %d adding SENDERIPADDR field to message header", p->status);
366
			return(FALSE);
367
		}
368
369
	}

370
	if(JS_GetProperty(cx, hdr, "from_host_name", &val) && !JSVAL_NULL_OR_VOID(val)) {
371
		JSVALUE_TO_STRING(cx, val, cp, NULL);
372
373
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_host_name\" string in header object");
374
			return(FALSE);
375
376
		}
		if((p->status=smb_hfield_str(msg, SENDERHOSTNAME, cp))!=SMB_SUCCESS) {
377
			JS_ReportError(cx, "Error %d adding SENDERHOSTNAME field to message header", p->status);
378
			return(FALSE);
379
		}
380
381
	}

382
	if(JS_GetProperty(cx, hdr, "from_protocol", &val) && !JSVAL_NULL_OR_VOID(val)) {
383
		JSVALUE_TO_STRING(cx, val, cp, NULL);
384
385
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_protocol\" string in header object");
386
			return(FALSE);
387
388
		}
		if((p->status=smb_hfield_str(msg, SENDERPROTOCOL, cp))!=SMB_SUCCESS) {
389
			JS_ReportError(cx, "Error %d adding SENDERPROTOCOL field to message header", p->status);
390
			return(FALSE);
391
		}
392
393
	}

394
	if(JS_GetProperty(cx, hdr, "from_port", &val) && !JSVAL_NULL_OR_VOID(val)) {
395
		JSVALUE_TO_STRING(cx, val, cp, NULL);
396
397
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_port\" string in header object");
398
			return(FALSE);
399
400
		}
		if((p->status=smb_hfield_str(msg, SENDERPORT, cp))!=SMB_SUCCESS) {
401
			JS_ReportError(cx, "Error %d adding SENDERPORT field to message header", p->status);
402
			return(FALSE);
403
		}
404
405
	}

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
	if(JS_GetProperty(cx, hdr, "sender_userid", &val) && !JSVAL_NULL_OR_VOID(val)) {
		JSVALUE_TO_STRING(cx, val, cp, NULL);
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"sender_userid\" string in header object");
			return(FALSE);
		}
		if((p->status=smb_hfield_str(msg, SENDERUSERID, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SENDERUSERID field to message header", p->status);
			return(FALSE);
		}
	}

	if(JS_GetProperty(cx, hdr, "sender_server", &val) && !JSVAL_NULL_OR_VOID(val)) {
		JSVALUE_TO_STRING(cx, val, cp, NULL);
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"sender_server\" string in header object");
			return(FALSE);
		}
		if((p->status=smb_hfield_str(msg, SENDERSERVER, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SENDERSERVER field to message header", p->status);
			return(FALSE);
		}
	}

	if(JS_GetProperty(cx, hdr, "sender_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
		JSVALUE_TO_STRING(cx, val, cp, NULL);
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"sender_time\" string in header object");
			return(FALSE);
		}
		if((p->status=smb_hfield_str(msg, SENDERTIME, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SENDERTIME field to message header", p->status);
			return(FALSE);
		}
	}
	
442
	if(JS_GetProperty(cx, hdr, "replyto", &val) && !JSVAL_NULL_OR_VOID(val)) {
443
		JSVALUE_TO_STRING(cx, val, cp, NULL);
444
445
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto\" string in header object");
446
			return(FALSE);
447
448
		}
		if((p->status=smb_hfield_str(msg, REPLYTO, cp))!=SMB_SUCCESS) {
449
			JS_ReportError(cx, "Error %d adding REPLYTO field to message header", p->status);
450
			return(FALSE);
451
		}
452
453
	}

454
	if(JS_GetProperty(cx, hdr, "replyto_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
455
		JSVALUE_TO_STRING(cx, val, cp, NULL);
456
457
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_ext\" string in header object");
458
			return(FALSE);
459
460
		}
		if((p->status=smb_hfield_str(msg, REPLYTOEXT, cp))!=SMB_SUCCESS) {
461
			JS_ReportError(cx, "Error %d adding REPLYTOEXT field to message header", p->status);
462
			return(FALSE);
463
		}
464
465
	}

466
	if(JS_GetProperty(cx, hdr, "replyto_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
467
		JSVALUE_TO_STRING(cx, val, cp, NULL);
468
469
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_org\" string in header object");
470
			return(FALSE);
471
472
		}
		if((p->status=smb_hfield_str(msg, REPLYTOORG, cp))!=SMB_SUCCESS) {
473
			JS_ReportError(cx, "Error %d adding REPLYTOORG field to message header", p->status);
474
			return(FALSE);
475
		}
476
477
	}

478
	nettype=NET_UNKNOWN;
479
	if(JS_GetProperty(cx, hdr, "replyto_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
480
481
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
482
		nettype=(ushort)i32;
483
	}
484
	if(JS_GetProperty(cx, hdr, "replyto_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
485
		JSVALUE_TO_STRING(cx, val, cp, NULL);
486
487
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_net_addr\" string in header object");
488
			return(FALSE);
489
490
		}
		if((p->status=smb_hfield_netaddr(msg, REPLYTONETADDR, cp, &nettype))!=SMB_SUCCESS) {
491
			JS_ReportError(cx, "Error %d adding REPLYTONETADDR field to message header", p->status);
492
			return(FALSE);
493
		}
494
495
	}
	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
496
		if((p->status=smb_hfield_bin(msg, REPLYTONETTYPE, nettype))!=SMB_SUCCESS) {
497
			JS_ReportError(cx, "Error %d adding REPLYTONETTYPE field to message header", p->status);
498
			return(FALSE);
499
		}
500
501
	}

502
	if(JS_GetProperty(cx, hdr, "replyto_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
503
504
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
505
		agent=(ushort)i32;
506
		if((p->status=smb_hfield_bin(msg, REPLYTOAGENT, agent))!=SMB_SUCCESS) {
507
			JS_ReportError(cx, "Error %d adding REPLYTOAGENT field to message header", p->status);
508
			return(FALSE);
509
		}
510
511
	}

512
	/* RFC822 headers */
513
	if(JS_GetProperty(cx, hdr, "id", &val) && !JSVAL_NULL_OR_VOID(val)) {
514
		JSVALUE_TO_STRING(cx, val, cp, NULL);
515
516
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"id\" string in header object");
517
			return(FALSE);
518
519
		}
		if((p->status=smb_hfield_str(msg, RFC822MSGID, cp))!=SMB_SUCCESS) {
520
			JS_ReportError(cx, "Error %d adding RFC822MSGID field to message header", p->status);
521
			return(FALSE);
522
		}
523
524
	}

525
	if(JS_GetProperty(cx, hdr, "reply_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
526
		JSVALUE_TO_STRING(cx, val, cp, NULL);
527
528
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"reply_id\" string in header object");
529
			return(FALSE);
530
531
		}
		if((p->status=smb_hfield_str(msg, RFC822REPLYID, cp))!=SMB_SUCCESS) {
532
			JS_ReportError(cx, "Error %d adding RFC822REPLYID field to message header", p->status);
533
			return(FALSE);
534
		}
535
536
	}

537
	/* SMTP headers */
538
	if(JS_GetProperty(cx, hdr, "reverse_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
539
		JSVALUE_TO_STRING(cx, val, cp, NULL);
540
541
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"reverse_path\" string in header object");
542
			return(FALSE);
543
544
		}
		if((p->status=smb_hfield_str(msg, SMTPREVERSEPATH, cp))!=SMB_SUCCESS) {
545
			JS_ReportError(cx, "Error %d adding SMTPREVERSEPATH field to message header", p->status);
546
			return(FALSE);
547
		}
548
549
	}

550
	if(JS_GetProperty(cx, hdr, "forward_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
551
		JSVALUE_TO_STRING(cx, val, cp, NULL);
552
553
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"forward_path\" string in header object");
554
			return(FALSE);
555
556
		}
		if((p->status=smb_hfield_str(msg, SMTPFORWARDPATH, cp))!=SMB_SUCCESS) {
557
			JS_ReportError(cx, "Error %d adding SMTPFORWARDPATH field to message header", p->status);
558
			return(FALSE);
559
		}
560
561
	}

562
	/* USENET headers */
563
	if(JS_GetProperty(cx, hdr, "path", &val) && !JSVAL_NULL_OR_VOID(val)) {
564
		JSVALUE_TO_STRING(cx, val, cp, NULL);
565
566
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"path\" string in header object");
567
			return(FALSE);
568
569
		}
		if((p->status=smb_hfield_str(msg, USENETPATH, cp))!=SMB_SUCCESS) {
570
			JS_ReportError(cx, "Error %d adding USENETPATH field to message header", p->status);
571
			return(FALSE);
572
		}
573
574
	}

575
	if(JS_GetProperty(cx, hdr, "newsgroups", &val) && !JSVAL_NULL_OR_VOID(val)) {
576
		JSVALUE_TO_STRING(cx, val, cp, NULL);
577
578
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"newsgroups\" string in header object");
579
			return(FALSE);
580
581
		}
		if((p->status=smb_hfield_str(msg, USENETNEWSGROUPS, cp))!=SMB_SUCCESS) {
582
			JS_ReportError(cx, "Error %d adding USENETNEWSGROUPS field to message header", p->status);
583
			return(FALSE);
584
		}
585
586
587
	}

	/* FTN headers */
588
	if(JS_GetProperty(cx, hdr, "ftn_msgid", &val) && !JSVAL_NULL_OR_VOID(val)) {
589
		JSVALUE_TO_STRING(cx, val, cp, NULL);
590
591
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_msgid\" string in header object");
592
			return(FALSE);
593
594
		}
		if((p->status=smb_hfield_str(msg, FIDOMSGID, cp))!=SMB_SUCCESS) {
595
			JS_ReportError(cx, "Error %d adding FIDOMSGID field to message header", p->status);
596
			return(FALSE);
597
		}
598
599
	}

600
	if(JS_GetProperty(cx, hdr, "ftn_reply", &val) && !JSVAL_NULL_OR_VOID(val)) {
601
		JSVALUE_TO_STRING(cx, val, cp, NULL);
602
603
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_reply\" string in header object");
604
			return(FALSE);
605
606
		}
		if((p->status=smb_hfield_str(msg, FIDOREPLYID, cp))!=SMB_SUCCESS) {
607
			JS_ReportError(cx, "Error %d adding FIDOREPLYID field to message header", p->status);
608
			return(FALSE);
609
		}
610
611
	}

612
	if(JS_GetProperty(cx, hdr, "ftn_area", &val) && !JSVAL_NULL_OR_VOID(val)) {
613
		JSVALUE_TO_STRING(cx, val, cp, NULL);
614
615
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_area\" string in header object");
616
			return(FALSE);
617
618
		}
		if((p->status=smb_hfield_str(msg, FIDOAREA, cp))!=SMB_SUCCESS) {
619
			JS_ReportError(cx, "Error %d adding FIDOAREA field to message header", p->status);
620
			return(FALSE);
621
		}
622
623
	}

624
	if(JS_GetProperty(cx, hdr, "ftn_flags", &val) && !JSVAL_NULL_OR_VOID(val)) {
625
		JSVALUE_TO_STRING(cx, val, cp, NULL);
626
627
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_flags\" string in header object");
628
			return(FALSE);
629
630
		}
		if((p->status=smb_hfield_str(msg, FIDOFLAGS, cp))!=SMB_SUCCESS) {
631
			JS_ReportError(cx, "Error %d adding FIDOFLAGS field to message header", p->status);
632
			return(FALSE);
633
		}
634
635
	}

636
	if(JS_GetProperty(cx, hdr, "ftn_pid", &val) && !JSVAL_NULL_OR_VOID(val)) {
637
		JSVALUE_TO_STRING(cx, val, cp, NULL);
638
639
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_pid\" string in header object");
640
			return(FALSE);
641
642
		}
		if((p->status=smb_hfield_str(msg, FIDOPID, cp))!=SMB_SUCCESS) {
643
			JS_ReportError(cx, "Error %d adding FIDOPID field to message header", p->status);
644
			return(FALSE);
645
		}
646
647
	}

648
	if(JS_GetProperty(cx, hdr, "ftn_tid", &val) && !JSVAL_NULL_OR_VOID(val)) {
649
		JSVALUE_TO_STRING(cx, val, cp, NULL);
650
651
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_tid\" string in header object");
652
			return(FALSE);
653
654
		}
		if((p->status=smb_hfield_str(msg, FIDOTID, cp))!=SMB_SUCCESS) {
655
			JS_ReportError(cx, "Error %d adding FIDOTID field to message header", p->status);
656
			return(FALSE);
657
		}
658
659
	}

660
	if(JS_GetProperty(cx, hdr, "date", &val) && !JSVAL_NULL_OR_VOID(val)) {
661
		JSVALUE_TO_STRING(cx, val, cp, NULL);
662
663
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"date\" string in header object");
664
			return(FALSE);
665
		}
666
667
		msg->hdr.when_written=rfc822date(cp);
	}
668

669
	/* Numeric Header Fields */
670
	if(JS_GetProperty(cx, hdr, "attr", &val) && !JSVAL_NULL_OR_VOID(val)) {
671
672
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
673
		msg->hdr.attr=(ushort)i32;
674
675
		msg->idx.attr=msg->hdr.attr;
	}
676
	if(JS_GetProperty(cx, hdr, "auxattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
677
678
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
679
680
		msg->hdr.auxattr=i32;
	}
681
	if(JS_GetProperty(cx, hdr, "netattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
682
683
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
684
685
		msg->hdr.netattr=i32;
	}
686
	if(JS_GetProperty(cx, hdr, "when_written_time", &val) && !JSVAL_NULL_OR_VOID(val))  {
687
688
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
689
690
		msg->hdr.when_written.time=i32;
	}
691
	if(JS_GetProperty(cx, hdr, "when_written_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
692
693
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
694
695
		msg->hdr.when_written.zone=(short)i32;
	}
696
	if(JS_GetProperty(cx, hdr, "when_imported_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
697
698
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
699
700
		msg->hdr.when_imported.time=i32;
	}
701
	if(JS_GetProperty(cx, hdr, "when_imported_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
702
703
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
704
705
706
		msg->hdr.when_imported.zone=(short)i32;
	}

707
708
709
710
711
	if(JS_GetProperty(cx, hdr, "thread_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
		msg->hdr.thread_id=i32;
	}
712
	if((JS_GetProperty(cx, hdr, "thread_orig", &val) 
713
714
715
			|| JS_GetProperty(cx, hdr, "thread_back", &val)) && !JSVAL_NULL_OR_VOID(val)) {
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
716
		msg->hdr.thread_back=i32;
717
	}
718
	if(JS_GetProperty(cx, hdr, "thread_next", &val) && !JSVAL_NULL_OR_VOID(val)) {
719
720
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
721
722
		msg->hdr.thread_next=i32;
	}
723
	if(JS_GetProperty(cx, hdr, "thread_first", &val) && !JSVAL_NULL_OR_VOID(val)) {
724
725
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
726
727
		msg->hdr.thread_first=i32;
	}
728

729
730
731
	if(JS_GetProperty(cx, hdr, "field_list", &val) && JSVAL_IS_OBJECT(val)) {
		array=JSVAL_TO_OBJECT(val);
		len=0;
732
733
		if(!JS_GetArrayLength(cx, array, &len)) {
			JS_ReportError(cx, "Invalid \"field_list\" array in header object");
734
			return(FALSE);
735
		}
736
737
738
739
740
741
742

		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);
743
			if(!JS_GetProperty(cx, field, "type", &val))
744
				continue;
deuce's avatar
deuce committed
745
			if(JSVAL_IS_STRING(val)) {
746
				JSVALUE_TO_STRING(cx, val, cp, NULL);
deuce's avatar
deuce committed
747
748
				type=smb_hfieldtypelookup(cp);
			}
749
			else {
750
751
				if(!JS_ValueToInt32(cx,val,&i32))
					return FALSE;
752
753
				type=(ushort)i32;
			}
754
			if(!JS_GetProperty(cx, field, "data", &val))
755
				continue;
756
			JSVALUE_TO_STRING(cx, val, cp, NULL);
757
			if(cp==NULL) {
758
				JS_ReportError(cx, "Invalid data string in \"field_list\" array");
759
				return(FALS