js_msgbase.c 90.3 KB
Newer Older
1 2 3
/* Synchronet JavaScript "MsgBase" Object */

/* $Id$ */
4
// vi: tabstop=4
5 6 7 8 9

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
10
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
11 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
 *																			*
 * 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"
38
#include "js_request.h"
39
#include "userdat.h"
40 41 42 43 44 45

#ifdef JAVASCRIPT

typedef struct
{
	smb_t	smb;
46
	int		status;
47 48 49 50
	BOOL	debug;

} private_t;

51 52 53 54 55 56 57 58
typedef struct
{
	private_t	*p;
	BOOL		expand_fields;
	smbmsg_t	msg;

} privatemsg_t;

59
static const char* getprivate_failure = "line %d %s %s JS_GetPrivate failed";
60

61 62 63 64 65 66 67 68 69 70
JSBool JS_ValueToUint32(JSContext *cx, jsval v, uint32 *ip)
{
	jsdouble d;

	if(!JS_ValueToNumber(cx, v, &d))
		return JS_FALSE;
	*ip = (uint32)d;
	return JS_TRUE;
}

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
/* 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 */

90
static JSBool
91
js_open(JSContext *cx, uintN argc, jsval *arglist)
92
{
93
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
94
	private_t* p;
deuce's avatar
deuce committed
95
	jsrefcount	rc;
96 97
	
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
98
		JS_ReportError(cx,getprivate_failure,WHERE);
99
		return JS_FALSE;
100 101
	}

102
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
103 104 105 106 107

	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);
108
		return JS_TRUE;
109 110
	}

111
	rc=JS_SUSPENDREQUEST(cx);
deuce's avatar
deuce committed
112
	if((p->status=smb_open(&(p->smb)))!=SMB_SUCCESS) {
113
		JS_RESUMEREQUEST(cx, rc);
114
		return JS_TRUE;
deuce's avatar
deuce committed
115
	}
116
	JS_RESUMEREQUEST(cx, rc);
117

118
	JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
119
	return JS_TRUE;
120 121 122
}


123
static JSBool
124
js_close(JSContext *cx, uintN argc, jsval *arglist)
125
{
126
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
127
	private_t* p;
deuce's avatar
deuce committed
128
	jsrefcount	rc;
129
	
130
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
131
		JS_ReportError(cx,getprivate_failure,WHERE);
132
		return JS_FALSE;
133
	}
134

135 136
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

137
	rc=JS_SUSPENDREQUEST(cx);
138
	smb_close(&(p->smb));
139
	JS_RESUMEREQUEST(cx, rc);
140

141
	return JS_TRUE;
142 143
}

144
static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg)
145
{
146 147
	char*		cp=NULL;
	size_t		cp_sz=0;
148
	char		to[256];
149
	ushort		nettype=NET_UNKNOWN;
150 151 152
	ushort		agent;
	int32		i32;
	jsval		val;
153
	scfg_t*		scfg;
154

155 156
	scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));
	
157
	if(JS_GetProperty(cx, hdr, "to", &val) && !JSVAL_NULL_OR_VOID(val)) {
158 159
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
160 161
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to\" string in recipient object");
162
			return(FALSE);
163
		}
164
	} else {
165 166
		if(p->smb.status.attr&SMB_EMAIL) {	/* e-mail */
			JS_ReportError(cx, "\"to\" property not included in email recipient object");
167
			return(FALSE);					/* "to" property required */
168
		}
169
		cp=strdup("All");
170
	}
deuce's avatar
deuce committed
171

172
	if((p->status=smb_hfield_str(msg, RECIPIENT, cp))!=SMB_SUCCESS) {
173
		JS_ReportError(cx, "Error %d adding RECIPIENT field to message header", p->status);
174
		free(cp);
175
		return(FALSE);
176
	}
177 178 179 180 181 182
	if(!(p->smb.status.attr&SMB_EMAIL)) {
		SAFECOPY(to,cp);
		strlwr(to);
		msg->idx.to=crc16(to,0);
	}

183
	if(JS_GetProperty(cx, hdr, "to_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
184 185
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
186 187
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to_ext\" string in recipient object");
rswindell's avatar
rswindell committed
188
			return(FALSE);
189 190
		}
		if((p->status=smb_hfield_str(msg, RECIPIENTEXT, cp))!=SMB_SUCCESS) {
191
			free(cp);
192
			JS_ReportError(cx, "Error %d adding RECIPIENTEXT field to message header", p->status);
193
			return(FALSE);
194
		}
rswindell's avatar
rswindell committed
195 196 197 198
		if(p->smb.status.attr&SMB_EMAIL)
			msg->idx.to=atoi(cp);
	}

199
	if(JS_GetProperty(cx, hdr, "to_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
200 201
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
202 203
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to_org\" string in recipient object");
rswindell's avatar
rswindell committed
204
			return(FALSE);
205 206
		}
		if((p->status=smb_hfield_str(msg, RECIPIENTORG, cp))!=SMB_SUCCESS) {
207
			free(cp);
208
			JS_ReportError(cx, "Error %d adding RECIPIENTORG field to message header", p->status);
209
			return(FALSE);
210
		}
rswindell's avatar
rswindell committed
211 212
	}

213
	if(JS_GetProperty(cx, hdr, "to_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
214 215
		if(!JS_ValueToInt32(cx,val,&i32))
			return(FALSE);
rswindell's avatar
rswindell committed
216 217 218
		nettype=(ushort)i32;
	}

219
	if(JS_GetProperty(cx, hdr, "to_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
220 221
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
222 223
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"to_net_addr\" string in recipient object");
rswindell's avatar
rswindell committed
224
			return(FALSE);
225
		}
226
		if((p->status=smb_hfield_netaddr(msg, RECIPIENTNETADDR, cp, &nettype))!=SMB_SUCCESS) {
227
			free(cp);
228
			JS_ReportError(cx, "Error %d adding RECIPIENTADDR field to message header", p->status);
229
			return(FALSE);
230
		}
231
	}
232
	free(cp);
233 234

	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
		if(p->smb.status.attr&SMB_EMAIL) {
			if(nettype==NET_QWK && msg->idx.to==0) {
				char fulladdr[128];
				msg->idx.to = qwk_route(scfg, msg->to_net.addr, fulladdr, sizeof(fulladdr)-1);
				if(fulladdr[0]==0) {
					JS_ReportError(cx, "Unrouteable QWKnet \"to_net_addr\" (%s) in recipient object"
						,msg->to_net.addr);
					return(FALSE);
				}
				if((p->status=smb_hfield_str(msg, RECIPIENTNETADDR, fulladdr))!=SMB_SUCCESS) {
					JS_ReportError(cx, "Error %d adding RECIPIENTADDR field to message header"
						,p->status);
					return(FALSE);
				}
				if(msg->idx.to != 0) {
					char ext[32];
					sprintf(ext,"%u",msg->idx.to);
					if((p->status=smb_hfield_str(msg, RECIPIENTEXT, ext))!=SMB_SUCCESS) {
						JS_ReportError(cx, "Error %d adding RECIPIENTEXT field to message header"
							,p->status);
						return(FALSE);
					}
				}
			} else
				msg->idx.to=0;
		}
261
		if((p->status=smb_hfield_bin(msg, RECIPIENTNETTYPE, nettype))!=SMB_SUCCESS) {
262
			JS_ReportError(cx, "Error %d adding RECIPIENTNETTYPE field to message header", p->status);
263
			return(FALSE);
264
		}
rswindell's avatar
rswindell committed
265 266
	}

267
	if(JS_GetProperty(cx, hdr, "to_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
268 269
		if(!JS_ValueToInt32(cx,val,&i32))
			return FALSE;
rswindell's avatar
rswindell committed
270
		agent=(ushort)i32;
271
		if((p->status=smb_hfield_bin(msg, RECIPIENTAGENT, agent))!=SMB_SUCCESS) {
272
			JS_ReportError(cx, "Error %d adding RECIPIENTAGENT field to message header", p->status);
273
			return(FALSE);
274
		}
rswindell's avatar
rswindell committed
275
	}
276 277 278 279 280 281 282

	return(TRUE);
}

static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg
								,BOOL recipient)
{
283 284
	char*		cp=NULL;
	size_t		cp_sz=0;
285
	char		from[256];
286
	ushort		nettype=NET_UNKNOWN;
287
	ushort		type;
288 289
	ushort		agent;
	int32		i32;
290
	jsval		val;
291 292 293
	JSObject*	array;
	JSObject*	field;
	jsuint		i,len;
294

295 296
	if(hdr==NULL) {
		JS_ReportError(cx, "NULL header object");
297
		goto err;
298
	}
299

300
	if(recipient && !parse_recipient_object(cx,p,hdr,msg))
301
		goto err;
302

303
	if(msg->hdr.type != SMB_MSG_TYPE_BALLOT) {
304 305 306 307 308 309 310 311 312 313 314 315 316
		/* Required Header Fields */
		if(JS_GetProperty(cx, hdr, "subject", &val) && !JSVAL_NULL_OR_VOID(val)) {
			JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
			HANDLE_PENDING(cx);
			if(cp==NULL) {
				JS_ReportError(cx, "Invalid \"subject\" string in header object");
				goto err;
			}
		} else
			cp=strdup("");

		if((p->status=smb_hfield_str(msg, SUBJECT, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SUBJECT field to message header", p->status);
317
			goto err;
318
		}
319
		msg->idx.subj=smb_subject_crc(cp);
320
	}
321
	if(JS_GetProperty(cx, hdr, "from", &val) && !JSVAL_NULL_OR_VOID(val)) {
322 323
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
324 325
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from\" string in header object");
326
			goto err;
327 328 329
		}
	} else {
		JS_ReportError(cx, "\"from\" property required in header");
330
		goto err;	/* "from" property required */
331 332
	}
	if((p->status=smb_hfield_str(msg, SENDER, cp))!=SMB_SUCCESS) {
333
		JS_ReportError(cx, "Error %d adding SENDER field to message header", p->status);
334
		goto err;
335
	}
336
	if(!(p->smb.status.attr&SMB_EMAIL) && msg->hdr.type != SMB_MSG_TYPE_BALLOT) {
337 338
		SAFECOPY(from,cp);
		strlwr(from);
339
		msg->idx.from=crc16(from,0);
340
	}
341 342

	/* Optional Header Fields */
343
	if(JS_GetProperty(cx, hdr, "from_ext", &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_ext\" string in header object");
348
			goto err;
349 350
		}
		if((p->status=smb_hfield_str(msg, SENDEREXT, cp))!=SMB_SUCCESS) {
351
			JS_ReportError(cx, "Error %d adding SENDEREXT field to message header", p->status);
352
			goto err;
353
		}
354
		if(p->smb.status.attr&SMB_EMAIL)
355 356 357
			msg->idx.from=atoi(cp);
	}

358
	if(JS_GetProperty(cx, hdr, "from_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
359 360
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
361 362
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_org\" string in header object");
363
			goto err;
364 365
		}
		if((p->status=smb_hfield_str(msg, SENDERORG, cp))!=SMB_SUCCESS) {
366
			JS_ReportError(cx, "Error %d adding SENDERORG field to message header", p->status);
367
			goto err;
368
		}
369 370
	}

371
	if(JS_GetProperty(cx, hdr, "from_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
372 373 374
		if(!JS_ValueToInt32(cx,val,&i32)) {
			goto err;
		}
375
		nettype=(ushort)i32;
376 377
	}

378
	if(JS_GetProperty(cx, hdr, "from_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
379 380
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
381 382
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_net_addr\" string in header object");
383
			goto err;
384
		}
385
		if((p->status=smb_hfield_netaddr(msg, SENDERNETADDR, cp, &nettype))!=SMB_SUCCESS) {
386
			JS_ReportError(cx, "Error %d adding SENDERNETADDR field to message header", p->status);
387
			goto err;
388
		}
389 390 391 392 393
	}
	
	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
		if(p->smb.status.attr&SMB_EMAIL)
			msg->idx.from=0;
394
		if((p->status=smb_hfield_bin(msg, SENDERNETTYPE, nettype))!=SMB_SUCCESS) {
395
			JS_ReportError(cx, "Error %d adding SENDERNETTYPE field to message header", p->status);
396
			goto err;
397
		}
398 399
	}

400
	if(JS_GetProperty(cx, hdr, "from_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
401
		if(!JS_ValueToInt32(cx,val,&i32))
402
			goto err;
403
		agent=(ushort)i32;
404
		if((p->status=smb_hfield_bin(msg, SENDERAGENT, agent))!=SMB_SUCCESS) {
405
			JS_ReportError(cx, "Error %d adding SENDERAGENT field to message header", p->status);
406
			goto err;
407
		}
408 409
	}

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

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

436
	if(JS_GetProperty(cx, hdr, "from_protocol", &val) && !JSVAL_NULL_OR_VOID(val)) {
437 438
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
439 440
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_protocol\" string in header object");
441
			goto err;
442 443
		}
		if((p->status=smb_hfield_str(msg, SENDERPROTOCOL, cp))!=SMB_SUCCESS) {
444
			JS_ReportError(cx, "Error %d adding SENDERPROTOCOL field to message header", p->status);
445
			goto err;
446
		}
447 448
	}

449
	if(JS_GetProperty(cx, hdr, "from_port", &val) && !JSVAL_NULL_OR_VOID(val)) {
450 451
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
452 453
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"from_port\" string in header object");
454
			goto err;
455 456
		}
		if((p->status=smb_hfield_str(msg, SENDERPORT, cp))!=SMB_SUCCESS) {
457
			JS_ReportError(cx, "Error %d adding SENDERPORT field to message header", p->status);
458
			goto err;
459
		}
460 461
	}

462
	if(JS_GetProperty(cx, hdr, "sender_userid", &val) && !JSVAL_NULL_OR_VOID(val)) {
463 464
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
465 466
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"sender_userid\" string in header object");
467
			goto err;
468 469 470
		}
		if((p->status=smb_hfield_str(msg, SENDERUSERID, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SENDERUSERID field to message header", p->status);
471
			goto err;
472 473 474 475
		}
	}

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

	if(JS_GetProperty(cx, hdr, "sender_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
489 490
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
491 492
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"sender_time\" string in header object");
493
			goto err;
494 495 496
		}
		if((p->status=smb_hfield_str(msg, SENDERTIME, cp))!=SMB_SUCCESS) {
			JS_ReportError(cx, "Error %d adding SENDERTIME field to message header", p->status);
497
			goto err;
498 499 500
		}
	}
	
501
	if(JS_GetProperty(cx, hdr, "replyto", &val) && !JSVAL_NULL_OR_VOID(val)) {
502 503
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
504 505
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto\" string in header object");
506
			goto err;
507 508
		}
		if((p->status=smb_hfield_str(msg, REPLYTO, cp))!=SMB_SUCCESS) {
509
			JS_ReportError(cx, "Error %d adding REPLYTO field to message header", p->status);
510
			goto err;
511
		}
512 513
	}

514
	if(JS_GetProperty(cx, hdr, "replyto_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
515 516
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
517 518
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_ext\" string in header object");
519
			goto err;
520 521
		}
		if((p->status=smb_hfield_str(msg, REPLYTOEXT, cp))!=SMB_SUCCESS) {
522
			JS_ReportError(cx, "Error %d adding REPLYTOEXT field to message header", p->status);
523
			goto err;
524
		}
525 526
	}

527
	if(JS_GetProperty(cx, hdr, "replyto_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
528 529
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
530 531
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_org\" string in header object");
532
			goto err;
533 534
		}
		if((p->status=smb_hfield_str(msg, REPLYTOORG, cp))!=SMB_SUCCESS) {
535
			JS_ReportError(cx, "Error %d adding REPLYTOORG field to message header", p->status);
536
			goto err;
537
		}
538 539
	}

540
	nettype=NET_UNKNOWN;
541
	if(JS_GetProperty(cx, hdr, "replyto_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
542
		if(!JS_ValueToInt32(cx,val,&i32))
543
			goto err;
544
		nettype=(ushort)i32;
545
	}
546
	if(JS_GetProperty(cx, hdr, "replyto_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
547 548
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
549 550
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"replyto_net_addr\" string in header object");
551
			goto err;
552
		}
553
		if((p->status=smb_hfield_netaddr(msg, REPLYTONETADDR, cp, &nettype))!=SMB_SUCCESS) {
554
			JS_ReportError(cx, "Error %d adding REPLYTONETADDR field to message header", p->status);
555
			goto err;
556
		}
557 558
	}
	if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
559
		if((p->status=smb_hfield_bin(msg, REPLYTONETTYPE, nettype))!=SMB_SUCCESS) {
560
			JS_ReportError(cx, "Error %d adding REPLYTONETTYPE field to message header", p->status);
561
			goto err;
562
		}
563 564
	}

565
	if(JS_GetProperty(cx, hdr, "replyto_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
566
		if(!JS_ValueToInt32(cx,val,&i32))
567
			goto err;
568
		agent=(ushort)i32;
569
		if((p->status=smb_hfield_bin(msg, REPLYTOAGENT, agent))!=SMB_SUCCESS) {
570
			JS_ReportError(cx, "Error %d adding REPLYTOAGENT field to message header", p->status);
571
			goto err;
572
		}
573 574
	}

575
	/* RFC822 headers */
576
	if(JS_GetProperty(cx, hdr, "id", &val) && !JSVAL_NULL_OR_VOID(val)) {
577 578
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
579 580
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"id\" string in header object");
581
			goto err;
582 583
		}
		if((p->status=smb_hfield_str(msg, RFC822MSGID, cp))!=SMB_SUCCESS) {
584
			JS_ReportError(cx, "Error %d adding RFC822MSGID field to message header", p->status);
585
			goto err;
586
		}
587 588
	}

589
	if(JS_GetProperty(cx, hdr, "reply_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
590 591
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
592 593
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"reply_id\" string in header object");
594
			goto err;
595 596
		}
		if((p->status=smb_hfield_str(msg, RFC822REPLYID, cp))!=SMB_SUCCESS) {
597
			JS_ReportError(cx, "Error %d adding RFC822REPLYID field to message header", p->status);
598
			goto err;
599
		}
600 601
	}

602
	/* SMTP headers */
603
	if(JS_GetProperty(cx, hdr, "reverse_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
604 605
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
606 607
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"reverse_path\" string in header object");
608
			goto err;
609 610
		}
		if((p->status=smb_hfield_str(msg, SMTPREVERSEPATH, cp))!=SMB_SUCCESS) {
611
			JS_ReportError(cx, "Error %d adding SMTPREVERSEPATH field to message header", p->status);
612
			goto err;
613
		}
614 615
	}

616
	if(JS_GetProperty(cx, hdr, "forward_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
617 618
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
619 620
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"forward_path\" string in header object");
621
			goto err;
622 623
		}
		if((p->status=smb_hfield_str(msg, SMTPFORWARDPATH, cp))!=SMB_SUCCESS) {
624
			JS_ReportError(cx, "Error %d adding SMTPFORWARDPATH field to message header", p->status);
625
			goto err;
626
		}
627 628
	}

629
	/* USENET headers */
630
	if(JS_GetProperty(cx, hdr, "path", &val) && !JSVAL_NULL_OR_VOID(val)) {
631 632
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
633 634
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"path\" string in header object");
635
			goto err;
636 637
		}
		if((p->status=smb_hfield_str(msg, USENETPATH, cp))!=SMB_SUCCESS) {
638
			JS_ReportError(cx, "Error %d adding USENETPATH field to message header", p->status);
639
			goto err;
640
		}
641 642
	}

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

	/* FTN headers */
657
	if(JS_GetProperty(cx, hdr, "ftn_msgid", &val) && !JSVAL_NULL_OR_VOID(val)) {
658 659
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
660 661
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_msgid\" string in header object");
662
			goto err;
663 664
		}
		if((p->status=smb_hfield_str(msg, FIDOMSGID, cp))!=SMB_SUCCESS) {
665
			JS_ReportError(cx, "Error %d adding FIDOMSGID field to message header", p->status);
666
			goto err;
667
		}
668 669
	}

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

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

696
	if(JS_GetProperty(cx, hdr, "ftn_flags", &val) && !JSVAL_NULL_OR_VOID(val)) {
697 698
		JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
		HANDLE_PENDING(cx);
699 700
		if(cp==NULL) {
			JS_ReportError(cx, "Invalid \"ftn_flags\" string in header object");
701
			goto err;
702 703
		}
		if((p->status=smb_hfield_str(msg, FIDOFLAGS, cp))!=SMB_SUCCESS) {
704
			JS_ReportError(cx, "Error %d adding FIDOFLAGS field to message header", p->status);
705
			goto err;
706
		}