Newer
Older
/* Synchronet JavaScript "MsgBase" Object */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* 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 *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sbbs.h"
#include "js_request.h"
#include "userdat.h"
#ifdef JAVASCRIPT
typedef struct
{
smb_t smb;
int smb_result;
JSBool debug;
uint32_t first_msg;
typedef struct
{
private_t *p;
bool expand_fields;
bool enumerated;
smbmsg_t msg;
post_t post;
} privatemsg_t;
/* Destructor */
static void js_finalize_msgbase(JSContext *cx, JSObject *obj)
{
private_t* p;
if ((p = (private_t*)JS_GetPrivate(cx, obj)) == NULL)
if (SMB_IS_OPEN(&(p->smb)))
smb_close(&(p->smb));
free(p);
JS_SetPrivate(cx, obj, NULL);
}
/* Methods */
extern JSClass js_msgbase_class;
static JSBool
js_open(JSContext *cx, uintN argc, jsval *arglist)
JSObject * obj = JS_THIS_OBJECT(cx, arglist);
private_t* p;
jsrefcount rc;
scfg_t* scfg;
scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));
JS_ReportError(cx, "JS_GetRuntimePrivate returned NULL");
return JS_FALSE;
}
if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class)) == NULL) {
}
JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
if (!subnum_is_valid(scfg, p->smb.subnum)
&& strchr(p->smb.file, '/') == NULL
&& strchr(p->smb.file, '\\') == NULL) {
JS_ReportError(cx, "Unrecognized msgbase code: %s", p->smb.file);
return JS_FALSE;
}
rc = JS_SUSPENDREQUEST(cx);
if (!subnum_is_valid(scfg, p->smb.subnum) && p->smb.subnum != INVALID_SUB)
p->smb_result = smb_open(&(p->smb));
else
p->smb_result = smb_open_sub(scfg, &(p->smb), p->smb.subnum);
if (p->smb_result != SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
JS_RESUMEREQUEST(cx, rc);
JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
}
js_close(JSContext *cx, uintN argc, jsval *arglist)
JSObject * obj = JS_THIS_OBJECT(cx, arglist);
if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class)) == NULL) {
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
rc = JS_SUSPENDREQUEST(cx);
smb_close(&(p->smb));
JS_RESUMEREQUEST(cx, rc);
static bool parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg)
char* cp = NULL;
size_t cp_sz = 0;
char to[256];
ushort nettype = NET_UNKNOWN;
ushort agent;
int32 i32;
jsval val;
scfg_t* scfg;
int smb_result = SMB_SUCCESS;
scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));
if (JS_GetProperty(cx, hdr, "to", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"to\" string in recipient object");
} else {
if ((p != NULL) && (p->smb.status.attr & SMB_EMAIL)) { /* e-mail */
JS_ReportError(cx, "\"to\" property not included in email recipient object");
return false; /* "to" property required */
}
if ((smb_result = smb_hfield_str(msg, RECIPIENT, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENT field to message header", smb_result);
goto err;
if ((p != NULL) && !(p->smb.status.attr & SMB_EMAIL)) {
SAFECOPY(to, cp);
strlwr(to);
msg->idx.to = crc16(to, 0);
}
if (JS_GetProperty(cx, hdr, "to_list", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"to_list\" string in recipient object");
if ((smb_result = smb_hfield_str(msg, RECIPIENTLIST, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTLIST field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "cc_list", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"cc_list\" string in recipient object");
if ((smb_result = smb_hfield_str(msg, SMB_CARBONCOPY, cp)) != SMB_SUCCESS) {
free(cp);
JS_ReportError(cx, "Error %d adding SMB_CARBONCOPY field to message header", smb_result);
goto err;
}
}
if (JS_GetProperty(cx, hdr, "to_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"to_ext\" string in recipient object");
if ((smb_result = smb_hfield_str(msg, RECIPIENTEXT, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTEXT field to message header", smb_result);
goto err;
if ((p != NULL) && (p->smb.status.attr & SMB_EMAIL))
msg->idx.to = atoi(cp);
if (JS_GetProperty(cx, hdr, "to_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"to_org\" string in recipient object");
if ((smb_result = smb_hfield_str(msg, RECIPIENTORG, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTORG field to message header", smb_result);
goto err;
if (JS_GetProperty(cx, hdr, "to_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32)) {
free(cp);
nettype = (ushort)i32;
if (JS_GetProperty(cx, hdr, "to_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"to_net_addr\" string in recipient object");
if ((smb_result = smb_hfield_netaddr(msg, RECIPIENTNETADDR, cp, &nettype)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTADDR field to message header", smb_result);
goto err;
if (nettype != NET_UNKNOWN) {
if ((p != NULL) && (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, "Unroutable QWKnet \"to_net_addr\" (%s) in recipient object"
if ((smb_result = smb_hfield_str(msg, RECIPIENTNETADDR, fulladdr)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTADDR field to message header"
goto err;
if (msg->idx.to != 0) {
char ext[32];
sprintf(ext, "%u", msg->idx.to);
if ((smb_result = smb_hfield_str(msg, RECIPIENTEXT, ext)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTEXT field to message header"
goto err;
}
}
} else
if ((smb_result = smb_hfield_bin(msg, RECIPIENTNETTYPE, nettype)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTNETTYPE field to message header", smb_result);
goto err;
if (JS_GetProperty(cx, hdr, "to_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32))
agent = (ushort)i32;
if ((smb_result = smb_hfield_bin(msg, RECIPIENTAGENT, agent)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RECIPIENTAGENT field to message header", smb_result);
goto err;
if (smb_result != SMB_SUCCESS && p != NULL)
p->smb_result = smb_result;
}
static bool parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg
{
char* cp = NULL;
size_t cp_sz = 0;
char from[256];
ushort nettype = NET_UNKNOWN;
ushort type;
ushort agent;
int32 i32;
uint32 u32;
jsval val;
JSObject* array;
JSObject* field;
jsuint i, len;
int smb_result = SMB_SUCCESS;
if (hdr == NULL) {
JS_ReportError(cx, "NULL header object");
if (recipient && !parse_recipient_object(cx, p, hdr, msg))
if (msg->hdr.type != SMB_MSG_TYPE_BALLOT) {
/* 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, cp);
JS_ReportError(cx, "Invalid \"subject\" string in header object");
goto err;
}
} else
if ((smb_result = smb_hfield_str(msg, SUBJECT, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SUBJECT field to message header", smb_result);
msg->idx.subj = smb_subject_crc(cp);
if (JS_GetProperty(cx, hdr, "from", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"from\" string in header object");
}
} else {
JS_ReportError(cx, "\"from\" property required in header");
goto err; /* "from" property required */
if ((smb_result = smb_hfield_str(msg, SENDER, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDER field to message header", smb_result);
if ((p != NULL) && !(p->smb.status.attr & SMB_EMAIL) && msg->hdr.type != SMB_MSG_TYPE_BALLOT) {
SAFECOPY(from, cp);
strlwr(from);
msg->idx.from = crc16(from, 0);
}
if (JS_GetProperty(cx, hdr, "from_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"from_ext\" string in header object");
if ((smb_result = smb_hfield_str(msg, SENDEREXT, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDEREXT field to message header", smb_result);
if ((p != NULL) && (p->smb.status.attr & SMB_EMAIL))
msg->idx.from = atoi(cp);
if (JS_GetProperty(cx, hdr, "from_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"from_org\" string in header object");
if ((smb_result = smb_hfield_str(msg, SENDERORG, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERORG field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "from_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32)) {
nettype = (ushort)i32;
if (JS_GetProperty(cx, hdr, "from_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"from_net_addr\" string in header object");
if ((smb_result = smb_hfield_netaddr(msg, SENDERNETADDR, cp, &nettype)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERNETADDR field to message header", smb_result);
if (nettype != NET_UNKNOWN) {
if ((p != NULL) && (p->smb.status.attr & SMB_EMAIL))
msg->idx.from = 0;
if ((smb_result = smb_hfield_bin(msg, SENDERNETTYPE, nettype)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERNETTYPE field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "from_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32))
agent = (ushort)i32;
if ((smb_result = smb_hfield_bin(msg, SENDERAGENT, agent)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERAGENT field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "from_ip_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"from_ip_addr\" string in header object");
if ((smb_result = smb_hfield_str(msg, SENDERIPADDR, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERIPADDR field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "from_host_name", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"from_host_name\" string in header object");
if ((smb_result = smb_hfield_str(msg, SENDERHOSTNAME, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERHOSTNAME field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "from_protocol", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"from_protocol\" string in header object");
if ((smb_result = smb_hfield_str(msg, SENDERPROTOCOL, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERPROTOCOL field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "from_port", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"from_port\" string in header object");
if ((smb_result = smb_hfield_str(msg, SENDERPORT, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERPORT field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "sender_userid", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"sender_userid\" string in header object");
}
if ((smb_result = smb_hfield_str(msg, SENDERUSERID, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERUSERID field to message header", smb_result);
}
}
if (JS_GetProperty(cx, hdr, "sender_server", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"sender_server\" string in header object");
}
if ((smb_result = smb_hfield_str(msg, SENDERSERVER, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERSERVER field to message header", smb_result);
}
}
if (JS_GetProperty(cx, hdr, "sender_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"sender_time\" string in header object");
}
if ((smb_result = smb_hfield_str(msg, SENDERTIME, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SENDERTIME field to message header", smb_result);
}
}
if (JS_GetProperty(cx, hdr, "replyto", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"replyto\" string in header object");
if ((smb_result = smb_hfield_str(msg, REPLYTO, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding REPLYTO field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "replyto_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"replyto_ext\" string in header object");
if ((smb_result = smb_hfield_str(msg, REPLYTOEXT, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding REPLYTOEXT field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "replyto_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"replyto_org\" string in header object");
if ((smb_result = smb_hfield_str(msg, REPLYTOORG, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding REPLYTOORG field to message header", smb_result);
nettype = NET_UNKNOWN;
if (JS_GetProperty(cx, hdr, "replyto_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32))
nettype = (ushort)i32;
if (JS_GetProperty(cx, hdr, "replyto_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"replyto_net_addr\" string in header object");
if ((smb_result = smb_hfield_netaddr(msg, REPLYTONETADDR, cp, &nettype)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding REPLYTONETADDR field to message header", smb_result);
}
if (nettype != NET_UNKNOWN) {
if ((smb_result = smb_hfield_bin(msg, REPLYTONETTYPE, nettype)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding REPLYTONETTYPE field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "replyto_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32))
agent = (ushort)i32;
if ((smb_result = smb_hfield_bin(msg, REPLYTOAGENT, agent)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding REPLYTOAGENT field to message header", smb_result);
/* RFC822 headers */
if (JS_GetProperty(cx, hdr, "replyto_list", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"replyto_list\" string in header object");
goto err;
}
if ((smb_result = smb_hfield_str(msg, REPLYTOLIST, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding REPLYTOLIST field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "id", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"id\" string in header object");
if ((smb_result = smb_hfield_str(msg, RFC822MSGID, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RFC822MSGID field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "reply_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"reply_id\" string in header object");
if ((smb_result = smb_hfield_str(msg, RFC822REPLYID, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding RFC822REPLYID field to message header", smb_result);
}
/* SMTP headers */
if (JS_GetProperty(cx, hdr, "reverse_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"reverse_path\" string in header object");
if ((smb_result = smb_hfield_str(msg, SMTPREVERSEPATH, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SMTPREVERSEPATH field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "forward_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"forward_path\" string in header object");
if ((smb_result = smb_hfield_str(msg, SMTPFORWARDPATH, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding SMTPFORWARDPATH field to message header", smb_result);
}
/* USENET headers */
if (JS_GetProperty(cx, hdr, "path", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"path\" string in header object");
if ((smb_result = smb_hfield_str(msg, USENETPATH, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding USENETPATH field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "newsgroups", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"newsgroups\" string in header object");
if ((smb_result = smb_hfield_str(msg, USENETNEWSGROUPS, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding USENETNEWSGROUPS field to message header", smb_result);
}
/* FTN headers */
if (JS_GetProperty(cx, hdr, "ftn_msgid", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"ftn_msgid\" string in header object");
if ((smb_result = smb_hfield_str(msg, FIDOMSGID, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding FIDOMSGID field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "ftn_reply", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"ftn_reply\" string in header object");
if ((smb_result = smb_hfield_str(msg, FIDOREPLYID, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding FIDOREPLYID field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "ftn_area", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"ftn_area\" string in header object");
if ((smb_result = smb_hfield_str(msg, FIDOAREA, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding FIDOAREA field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "ftn_flags", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"ftn_flags\" string in header object");
if ((smb_result = smb_hfield_str(msg, FIDOFLAGS, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding FIDOFLAGS field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "ftn_pid", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"ftn_pid\" string in header object");
if ((smb_result = smb_hfield_str(msg, FIDOPID, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding FIDOPID field to message header", smb_result);
if (JS_GetProperty(cx, hdr, "ftn_tid", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"ftn_tid\" string in header object");
if ((smb_result = smb_hfield_str(msg, FIDOTID, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding FIDOTID field to message header", smb_result);
}
if (JS_GetProperty(cx, hdr, "ftn_charset", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"ftn_charset\" string in header object");
goto err;
}
if ((smb_result = smb_hfield_str(msg, FIDOCHARSET, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding FIDOCHARSET field to message header", smb_result);
goto err;
}
}
if (JS_GetProperty(cx, hdr, "ftn_bbsid", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"ftn_bbsid\" string in header object");
goto err;
}
if ((smb_result = smb_hfield_str(msg, FIDOBBSID, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding FIDOBBSID field to message header", smb_result);
goto err;
}
}
if (JS_GetProperty(cx, hdr, "date", &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"date\" string in header object");
msg->hdr.when_written = rfc822date(cp);
const char* prop_name = "summary";
uint16_t hfield_type = SMB_SUMMARY;
if (JS_GetProperty(cx, hdr, prop_name, &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"%s\" string in header object", prop_name);
goto err;
}
if ((smb_result = smb_hfield_str(msg, hfield_type, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding %s field to message header", smb_result, smb_hfieldtype(hfield_type));
goto err;
}
}
prop_name = "tags";
hfield_type = SMB_TAGS;
if (JS_GetProperty(cx, hdr, prop_name, &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"%s\" string in header object", prop_name);
goto err;
}
if ((smb_result = smb_hfield_str(msg, hfield_type, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding %s field to message header", smb_result, smb_hfieldtype(hfield_type));
goto err;
}
}
prop_name = "editor";
hfield_type = SMB_EDITOR;
if (JS_GetProperty(cx, hdr, prop_name, &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid \"%s\" string in header object", prop_name);
goto err;
}
if ((smb_result = smb_hfield_str(msg, hfield_type, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding %s field to message header", smb_result, smb_hfieldtype(hfield_type));
goto err;
}
}
prop_name = "columns";
hfield_type = SMB_COLUMNS;
if (JS_GetProperty(cx, hdr, prop_name, &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32)) {
JS_ReportError(cx, "Invalid \"%s\" number in header object", prop_name);
goto err;
}
uint8_t u8 = u32;
if ((smb_result = smb_hfield_bin(msg, hfield_type, u8)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding %s field to message header", smb_result, smb_hfieldtype(hfield_type));
goto err;
}
}
if (JS_GetProperty(cx, hdr, "attr", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.attr = (ushort)u32;
msg->idx.attr = msg->hdr.attr;
if (JS_GetProperty(cx, hdr, "votes", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
goto err;
msg->hdr.votes = (ushort)u32;
if (msg->hdr.type == SMB_MSG_TYPE_BALLOT)
msg->idx.votes = msg->hdr.votes;
if (JS_GetProperty(cx, hdr, "auxattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.auxattr = u32;
if (JS_GetProperty(cx, hdr, "netattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.netattr = u32;
if (JS_GetProperty(cx, hdr, "when_written_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.when_written = smb_when(u32, msg->hdr.when_written.zone);
if (JS_GetProperty(cx, hdr, "when_written_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32))
msg->hdr.when_written.zone = (short)i32;
if (JS_GetProperty(cx, hdr, "when_imported_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.when_imported.time = u32;
if (JS_GetProperty(cx, hdr, "when_imported_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32))
msg->hdr.when_imported.zone = (short)i32;
if (JS_GetProperty(cx, hdr, "thread_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.thread_id = u32;
}
if ((JS_GetProperty(cx, hdr, "thread_orig", &val) && (!JSVAL_NULL_OR_VOID(val)))
|| (JS_GetProperty(cx, hdr, "thread_back", &val) && !JSVAL_NULL_OR_VOID(val))) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.thread_back = u32;
if (JS_GetProperty(cx, hdr, "thread_next", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.thread_next = u32;
if (JS_GetProperty(cx, hdr, "thread_first", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.thread_first = u32;
if (JS_GetProperty(cx, hdr, "delivery_attempts", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.delivery_attempts = u32;
if (JS_GetProperty(cx, hdr, "priority", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToInt32(cx, val, &i32))
goto err;
msg->hdr.priority = i32;
}
if (JS_GetProperty(cx, hdr, "field_list", &val) && JSVAL_IS_OBJECT(val)) {
array = JSVAL_TO_OBJECT(val);
len = 0;
if (array == NULL || !JS_GetArrayLength(cx, array, &len)) {
JS_ReportError(cx, "Invalid \"field_list\" array in header object");
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);
if (field == NULL || !JS_GetProperty(cx, field, "type", &val))
continue;
if (JSVAL_IS_STRING(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
type = smb_hfieldtypelookup(cp);
else {
if (!JS_ValueToInt32(cx, val, &i32))
}
if (!JS_GetProperty(cx, field, "data", &val))
continue;
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
JS_ReportError(cx, "Invalid data string in \"field_list\" array");
if ((smb_result = smb_hfield_str(msg, type, cp)) != SMB_SUCCESS) {
JS_ReportError(cx, "Error %d adding field (type %02Xh) to message header", smb_result, type);
}
}
if (msg->hdr.number == 0 && JS_GetProperty(cx, hdr, "number", &val) && !JSVAL_NULL_OR_VOID(val)) {
if (!JS_ValueToECMAUint32(cx, val, &u32))
msg->hdr.number = u32;
if (smb_result != SMB_SUCCESS && p != NULL)
p->smb_result = smb_result;