js_msgbase.c 86.9 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
140
	char*		cp=NULL;
	size_t		cp_sz=0;
141
	char		to[256];
142
	ushort		nettype=NET_UNKNOWN;
143
144
145
146
	ushort		agent;
	int32		i32;
	jsval		val;

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

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

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

189
	if(JS_GetProperty(cx, hdr, "to_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
190
191
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
192
193
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to_org\" string in recipient object");
rswindell's avatar
rswindell committed
194
			return(FALSE);
195
196
		}
		if((p->status=smb_hfield_str(msg, RECIPIENTORG, cp))!=SMB_SUCCESS) {
197
			free(cp);
198
			JS_ReportError(cx, "Error %d adding RECIPIENTORG field to message header", p->status);
199
			return(FALSE);
200
		}
rswindell's avatar
rswindell committed
201
202
	}

203
	if(JS_GetProperty(cx, hdr, "to_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
204
205
		if(!JS_ValueToInt32(cx,val,&i32))
			return(FALSE);
rswindell's avatar
rswindell committed
206
207
208
		nettype=(ushort)i32;
	}

209
	if(JS_GetProperty(cx, hdr, "to_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
210
211
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
212
213
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to_net_addr\" string in recipient object");
rswindell's avatar
rswindell committed
214
			return(FALSE);
215
216
		}
		if((p->status=smb_hfield_netaddr(msg, RECIPIENTNETADDR, cp, &nettype))!=SMB_SUCCESS) {
217
			free(cp);
218
			JS_ReportError(cx, "Error %d adding RECIPIENTADDR field to message header", p->status);
219
			return(FALSE);
220
		}
221
	}
222
	free(cp);
223
224
225
226

	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
		if(p->smb.status.attr&SMB_EMAIL)
			msg->idx.to=0;
227
		if((p->status=smb_hfield_bin(msg, RECIPIENTNETTYPE, nettype))!=SMB_SUCCESS) {
228
			JS_ReportError(cx, "Error %d adding RECIPIENTNETTYPE field to message header", p->status);
229
			return(FALSE);
230
		}
rswindell's avatar
rswindell committed
231
232
	}

233
	if(JS_GetProperty(cx, hdr, "to_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
234
235
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
rswindell's avatar
rswindell committed
236
		agent=(ushort)i32;
237
		if((p->status=smb_hfield_bin(msg, RECIPIENTAGENT, agent))!=SMB_SUCCESS) {
238
			JS_ReportError(cx, "Error %d adding RECIPIENTAGENT field to message header", p->status);
239
			return(FALSE);
240
		}
rswindell's avatar
rswindell committed
241
	}
242
243
244
245
246
247
248

	return(TRUE);
}

static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg
								,BOOL recipient)
{
249
250
	char*		cp=NULL;
	size_t		cp_sz=0;
251
	char		from[256];
252
	ushort		nettype=NET_UNKNOWN;
253
	ushort		type;
254
255
	ushort		agent;
	int32		i32;
256
	jsval		val;
257
258
259
	JSObject*	array;
	JSObject*	field;
	jsuint		i,len;
260

261
262
	if(hdr==NULL) {
		JS_ReportError(cx, "NULL header object");
263
		goto err;
264
	}
265

266
	if(recipient && !parse_recipient_object(cx,p,hdr,msg))
267
		goto err;
268

269
	/* Required Header Fields */
270
	if(JS_GetProperty(cx, hdr, "subject", &val) && !JSVAL_NULL_OR_VOID(val)) {
271
272
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
273
274
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"subject\" string in header object");
275
			goto err;
276
		}
277
	} else
278
		cp=strdup("");
279
280

	if((p->status=smb_hfield_str(msg, SUBJECT, cp))!=SMB_SUCCESS) {
281
		JS_ReportError(cx, "Error %d adding SUBJECT field to message header", p->status);
282
		goto err;
283
	}
284
	msg->idx.subj=smb_subject_crc(cp);
285

286
	if(JS_GetProperty(cx, hdr, "from", &val) && !JSVAL_NULL_OR_VOID(val)) {
287
288
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
289
290
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from\" string in header object");
291
			goto err;
292
293
294
		}
	} else {
		JS_ReportError(cx, "\"from\" property required in header");
295
		goto err;	/* "from" property required */
296
297
	}
	if((p->status=smb_hfield_str(msg, SENDER, cp))!=SMB_SUCCESS) {
298
		JS_ReportError(cx, "Error %d adding SENDER field to message header", p->status);
299
		goto err;
300
	}
301
	if(!(p->smb.status.attr&SMB_EMAIL)) {
302
303
		SAFECOPY(from,cp);
		strlwr(from);
304
		msg->idx.from=crc16(from,0);
305
	}
306
307

	/* Optional Header Fields */
308
	if(JS_GetProperty(cx, hdr, "from_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
309
310
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
311
312
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_ext\" string in header object");
313
			goto err;
314
315
		}
		if((p->status=smb_hfield_str(msg, SENDEREXT, cp))!=SMB_SUCCESS) {
316
			JS_ReportError(cx, "Error %d adding SENDEREXT field to message header", p->status);
317
			goto err;
318
		}
319
		if(p->smb.status.attr&SMB_EMAIL)
320
321
322
			msg->idx.from=atoi(cp);
	}

323
	if(JS_GetProperty(cx, hdr, "from_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
324
325
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
326
327
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_org\" string in header object");
328
			goto err;
329
330
		}
		if((p->status=smb_hfield_str(msg, SENDERORG, cp))!=SMB_SUCCESS) {
331
			JS_ReportError(cx, "Error %d adding SENDERORG field to message header", p->status);
332
			goto err;
333
		}
334
335
	}

336
	if(JS_GetProperty(cx, hdr, "from_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
337
338
339
		if(!JS_ValueToInt32(cx,val,&i32)) {
			goto err;
		}
340
		nettype=(ushort)i32;
341
342
	}

343
	if(JS_GetProperty(cx, hdr, "from_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
344
345
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
346
347
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_net_addr\" string in header object");
348
			goto err;
349
350
		}
		if((p->status=smb_hfield_netaddr(msg, SENDERNETADDR, cp, &nettype))!=SMB_SUCCESS) {
351
			JS_ReportError(cx, "Error %d adding SENDERNETADDR field to message header", p->status);
352
			goto err;
353
		}
354
355
356
357
358
	}
	
	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
		if(p->smb.status.attr&SMB_EMAIL)
			msg->idx.from=0;
359
		if((p->status=smb_hfield_bin(msg, SENDERNETTYPE, nettype))!=SMB_SUCCESS) {
360
			JS_ReportError(cx, "Error %d adding SENDERNETTYPE field to message header", p->status);
361
			goto err;
362
		}
363
364
	}

365
	if(JS_GetProperty(cx, hdr, "from_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
366
		if(!JS_ValueToInt32(cx,val,&i32))
367
			goto err;
368
		agent=(ushort)i32;
369
		if((p->status=smb_hfield_bin(msg, SENDERAGENT, agent))!=SMB_SUCCESS) {
370
			JS_ReportError(cx, "Error %d adding SENDERAGENT field to message header", p->status);
371
			goto err;
372
		}
373
374
	}

375
	if(JS_GetProperty(cx, hdr, "from_ip_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
376
377
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
378
379
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_ip_addr\" string in header object");
380
			goto err;
381
382
		}
		if((p->status=smb_hfield_str(msg, SENDERIPADDR, cp))!=SMB_SUCCESS) {
383
			JS_ReportError(cx, "Error %d adding SENDERIPADDR field to message header", p->status);
384
			goto err;
385
		}
386
387
	}

388
	if(JS_GetProperty(cx, hdr, "from_host_name", &val) && !JSVAL_NULL_OR_VOID(val)) {
389
390
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
391
392
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_host_name\" string in header object");
393
			goto err;
394
395
		}
		if((p->status=smb_hfield_str(msg, SENDERHOSTNAME, cp))!=SMB_SUCCESS) {
396
			JS_ReportError(cx, "Error %d adding SENDERHOSTNAME field to message header", p->status);
397
			goto err;
398
		}
399
400
	}

401
	if(JS_GetProperty(cx, hdr, "from_protocol", &val) && !JSVAL_NULL_OR_VOID(val)) {
402
403
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
404
405
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_protocol\" string in header object");
406
			goto err;
407
408
		}
		if((p->status=smb_hfield_str(msg, SENDERPROTOCOL, cp))!=SMB_SUCCESS) {
409
			JS_ReportError(cx, "Error %d adding SENDERPROTOCOL field to message header", p->status);
410
			goto err;
411
		}
412
413
	}

414
	if(JS_GetProperty(cx, hdr, "from_port", &val) && !JSVAL_NULL_OR_VOID(val)) {
415
416
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
417
418
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_port\" string in header object");
419
			goto err;
420
421
		}
		if((p->status=smb_hfield_str(msg, SENDERPORT, cp))!=SMB_SUCCESS) {
422
			JS_ReportError(cx, "Error %d adding SENDERPORT field to message header", p->status);
423
			goto err;
424
		}
425
426
	}

427
	if(JS_GetProperty(cx, hdr, "sender_userid", &val) && !JSVAL_NULL_OR_VOID(val)) {
428
429
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
430
431
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"sender_userid\" string in header object");
432
			goto err;
433
434
435
		}
		if((p->status=smb_hfield_str(msg, SENDERUSERID, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SENDERUSERID field to message header", p->status);
436
			goto err;
437
438
439
440
		}
	}

	if(JS_GetProperty(cx, hdr, "sender_server", &val) && !JSVAL_NULL_OR_VOID(val)) {
441
442
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
443
444
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"sender_server\" string in header object");
445
			goto err;
446
447
448
		}
		if((p->status=smb_hfield_str(msg, SENDERSERVER, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SENDERSERVER field to message header", p->status);
449
			goto err;
450
451
452
453
		}
	}

	if(JS_GetProperty(cx, hdr, "sender_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
454
455
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
456
457
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"sender_time\" string in header object");
458
			goto err;
459
460
461
		}
		if((p->status=smb_hfield_str(msg, SENDERTIME, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SENDERTIME field to message header", p->status);
462
			goto err;
463
464
465
		}
	}
	
466
	if(JS_GetProperty(cx, hdr, "replyto", &val) && !JSVAL_NULL_OR_VOID(val)) {
467
468
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
469
470
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto\" string in header object");
471
			goto err;
472
473
		}
		if((p->status=smb_hfield_str(msg, REPLYTO, cp))!=SMB_SUCCESS) {
474
			JS_ReportError(cx, "Error %d adding REPLYTO field to message header", p->status);
475
			goto err;
476
		}
477
478
	}

479
	if(JS_GetProperty(cx, hdr, "replyto_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
480
481
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
482
483
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_ext\" string in header object");
484
			goto err;
485
486
		}
		if((p->status=smb_hfield_str(msg, REPLYTOEXT, cp))!=SMB_SUCCESS) {
487
			JS_ReportError(cx, "Error %d adding REPLYTOEXT field to message header", p->status);
488
			goto err;
489
		}
490
491
	}

492
	if(JS_GetProperty(cx, hdr, "replyto_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
493
494
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
495
496
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_org\" string in header object");
497
			goto err;
498
499
		}
		if((p->status=smb_hfield_str(msg, REPLYTOORG, cp))!=SMB_SUCCESS) {
500
			JS_ReportError(cx, "Error %d adding REPLYTOORG field to message header", p->status);
501
			goto err;
502
		}
503
504
	}

505
	nettype=NET_UNKNOWN;
506
	if(JS_GetProperty(cx, hdr, "replyto_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
507
		if(!JS_ValueToInt32(cx,val,&i32))
508
			goto err;
509
		nettype=(ushort)i32;
510
	}
511
	if(JS_GetProperty(cx, hdr, "replyto_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
512
513
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
514
515
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_net_addr\" string in header object");
516
			goto err;
517
518
		}
		if((p->status=smb_hfield_netaddr(msg, REPLYTONETADDR, cp, &nettype))!=SMB_SUCCESS) {
519
			JS_ReportError(cx, "Error %d adding REPLYTONETADDR field to message header", p->status);
520
			goto err;
521
		}
522
523
	}
	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
524
		if((p->status=smb_hfield_bin(msg, REPLYTONETTYPE, nettype))!=SMB_SUCCESS) {
525
			JS_ReportError(cx, "Error %d adding REPLYTONETTYPE field to message header", p->status);
526
			goto err;
527
		}
528
529
	}

530
	if(JS_GetProperty(cx, hdr, "replyto_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
531
		if(!JS_ValueToInt32(cx,val,&i32))
532
			goto err;
533
		agent=(ushort)i32;
534
		if((p->status=smb_hfield_bin(msg, REPLYTOAGENT, agent))!=SMB_SUCCESS) {
535
			JS_ReportError(cx, "Error %d adding REPLYTOAGENT field to message header", p->status);
536
			goto err;
537
		}
538
539
	}

540
	/* RFC822 headers */
541
	if(JS_GetProperty(cx, hdr, "id", &val) && !JSVAL_NULL_OR_VOID(val)) {
542
543
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
544
545
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"id\" string in header object");
546
			goto err;
547
548
		}
		if((p->status=smb_hfield_str(msg, RFC822MSGID, cp))!=SMB_SUCCESS) {
549
			JS_ReportError(cx, "Error %d adding RFC822MSGID field to message header", p->status);
550
			goto err;
551
		}
552
553
	}

554
	if(JS_GetProperty(cx, hdr, "reply_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
555
556
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
557
558
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"reply_id\" string in header object");
559
			goto err;
560
561
		}
		if((p->status=smb_hfield_str(msg, RFC822REPLYID, cp))!=SMB_SUCCESS) {
562
			JS_ReportError(cx, "Error %d adding RFC822REPLYID field to message header", p->status);
563
			goto err;
564
		}
565
566
	}

567
	/* SMTP headers */
568
	if(JS_GetProperty(cx, hdr, "reverse_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
569
570
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
571
572
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"reverse_path\" string in header object");
573
			goto err;
574
575
		}
		if((p->status=smb_hfield_str(msg, SMTPREVERSEPATH, cp))!=SMB_SUCCESS) {
576
			JS_ReportError(cx, "Error %d adding SMTPREVERSEPATH field to message header", p->status);
577
			goto err;
578
		}
579
580
	}

581
	if(JS_GetProperty(cx, hdr, "forward_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
582
583
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
584
585
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"forward_path\" string in header object");
586
			goto err;
587
588
		}
		if((p->status=smb_hfield_str(msg, SMTPFORWARDPATH, cp))!=SMB_SUCCESS) {
589
			JS_ReportError(cx, "Error %d adding SMTPFORWARDPATH field to message header", p->status);
590
			goto err;
591
		}
592
593
	}

594
	/* USENET headers */
595
	if(JS_GetProperty(cx, hdr, "path", &val) && !JSVAL_NULL_OR_VOID(val)) {
596
597
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
598
599
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"path\" string in header object");
600
			goto err;
601
602
		}
		if((p->status=smb_hfield_str(msg, USENETPATH, cp))!=SMB_SUCCESS) {
603
			JS_ReportError(cx, "Error %d adding USENETPATH field to message header", p->status);
604
			goto err;
605
		}
606
607
	}

608
	if(JS_GetProperty(cx, hdr, "newsgroups", &val) && !JSVAL_NULL_OR_VOID(val)) {
609
610
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
611
612
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"newsgroups\" string in header object");
613
			goto err;
614
615
		}
		if((p->status=smb_hfield_str(msg, USENETNEWSGROUPS, cp))!=SMB_SUCCESS) {
616
			JS_ReportError(cx, "Error %d adding USENETNEWSGROUPS field to message header", p->status);
617
			goto err;
618
		}
619
620
621
	}

	/* FTN headers */
622
	if(JS_GetProperty(cx, hdr, "ftn_msgid", &val) && !JSVAL_NULL_OR_VOID(val)) {
623
624
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
625
626
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_msgid\" string in header object");
627
			goto err;
628
629
		}
		if((p->status=smb_hfield_str(msg, FIDOMSGID, cp))!=SMB_SUCCESS) {
630
			JS_ReportError(cx, "Error %d adding FIDOMSGID field to message header", p->status);
631
			goto err;
632
		}
633
634
	}

635
	if(JS_GetProperty(cx, hdr, "ftn_reply", &val) && !JSVAL_NULL_OR_VOID(val)) {
636
637
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
638
639
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_reply\" string in header object");
640
			goto err;
641
642
		}
		if((p->status=smb_hfield_str(msg, FIDOREPLYID, cp))!=SMB_SUCCESS) {
643
			JS_ReportError(cx, "Error %d adding FIDOREPLYID field to message header", p->status);
644
			goto err;
645
		}
646
647
	}

648
	if(JS_GetProperty(cx, hdr, "ftn_area", &val) && !JSVAL_NULL_OR_VOID(val)) {
649
650
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
651
652
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_area\" string in header object");
653
			goto err;
654
655
		}
		if((p->status=smb_hfield_str(msg, FIDOAREA, cp))!=SMB_SUCCESS) {
656
			JS_ReportError(cx, "Error %d adding FIDOAREA field to message header", p->status);
657
			goto err;
658
		}
659
660
	}

661
	if(JS_GetProperty(cx, hdr, "ftn_flags", &val) && !JSVAL_NULL_OR_VOID(val)) {
662
663
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
664
665
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_flags\" string in header object");
666
			goto err;
667
668
		}
		if((p->status=smb_hfield_str(msg, FIDOFLAGS, cp))!=SMB_SUCCESS) {
669
			JS_ReportError(cx, "Error %d adding FIDOFLAGS field to message header", p->status);
670
			goto err;
671
		}
672
673
	}

674
	if(JS_GetProperty(cx, hdr, "ftn_pid", &val) && !JSVAL_NULL_OR_VOID(val)) {
675
676
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
677
678
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_pid\" string in header object");
679
			goto err;
680
681
		}
		if((p->status=smb_hfield_str(msg, FIDOPID, cp))!=SMB_SUCCESS) {
682
			JS_ReportError(cx, "Error %d adding FIDOPID field to message header", p->status);
683
			goto err;
684
		}
685
686
	}

687
	if(JS_GetProperty(cx, hdr, "ftn_tid", &val) && !JSVAL_NULL_OR_VOID(val)) {
688
689
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
690
691
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_tid\" string in header object");
692
			goto err;
693
694
		}
		if((p->status=smb_hfield_str(msg, FIDOTID, cp))!=SMB_SUCCESS) {
695
			JS_ReportError(cx, "Error %d adding FIDOTID field to message header", p->status);
696
			goto err;
697
		}
698
699
	}

700
	if(JS_GetProperty(cx, hdr, "date", &val) && !JSVAL_NULL_OR_VOID(val)) {
701
702
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
703
704
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"date\" string in header object");
705
			goto err;
706
		}
707
708
		msg->hdr.when_written=rfc822date(cp);
	}
709

710
	/* Numeric Header Fields */
711
	if(JS_GetProperty(cx, hdr, "attr", &val) && !JSVAL_NULL_OR_VOID(val)) {
712
		if(!JS_ValueToInt32(cx,val,&i32))
713
			goto err;
714
		msg->hdr.attr=(ushort)i32;
715
716
		msg->idx.attr=msg->hdr.attr;
	}
717
	if(JS_GetProperty(cx, hdr, "auxattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
718
		if(!JS_ValueToInt32(cx,val,&i32))
719
			goto err;
720
721
		msg->hdr.auxattr=i32;
	}
722
	if(JS_GetProperty(cx, hdr, "netattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
723
		if(!JS_ValueToInt32(cx,val,&i32))
724
			goto err;
725
726
		msg->hdr.netattr=i32;
	}
727
	if(JS_GetProperty(cx, hdr, "when_written_time", &val) && !JSVAL_NULL_OR_VOID(val))  {
728
		if(!JS_ValueToInt32(cx,val,&i32))
729
			goto err;
730
731
		msg->hdr.when_written.time=i32;
	}
732
	if(JS_GetProperty(cx, hdr, "when_written_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
733
		if(!JS_ValueToInt32(cx,val,&i32))
734
			goto err;
735
736
		msg->hdr.when_written.zone=(short)i32;
	}
737
	if(JS_GetProperty(cx, hdr, "when_imported_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
738
		if(!JS_ValueToInt32(cx,val,&i32))
739
			goto err;
740
741
		msg->hdr.when_imported.time=i32;
	}
742
	if(JS_GetProperty(cx, hdr, "when_imported_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
743
		if(!JS_ValueToInt32(cx,val,&i32))