Newer
Older
p=(privatemsg_t*)JS_GetPrivate(cx,obj);
if(!parse_header_object(cx, p == NULL ? NULL : p->p, obj, msg, /* recipient */ TRUE)) {
smb_freemsgmem(msg);
return(FALSE);
}
/* obj must've been previously returned from get_msg_header() */
BOOL DLLCALL js_GetMsgHeaderObjectPrivates(JSContext* cx, JSObject* obj, smb_t** smb, smbmsg_t** msg, post_t** post)
{
privatemsg_t* p;
if((p=(privatemsg_t*)JS_GetPrivate(cx,obj))==NULL)
return FALSE;
if(smb != NULL) {
if(p->p == NULL)
return FALSE;
*smb = &(p->p->smb);
}
if(msg != NULL)
*msg = &p->msg;
return TRUE;
}
static BOOL msg_offset_by_id(private_t* p, char* id, int32_t* offset)
{
smbmsg_t msg;
if((p->smb_result = smb_getmsgidx_by_msgid(&(p->smb),&msg,id))!=SMB_SUCCESS)
return(FALSE);
*offset = msg.offset;
return(TRUE);
}
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
static bool set_msg_idx_properties(JSContext* cx, JSObject* obj, idxrec_t* idx, int32_t offset)
{
jsval val;
val = UINT_TO_JSVAL(idx->number);
if(!JS_DefineProperty(cx, obj, "number" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
if(idx->attr&MSG_VOTE && !(idx->attr&MSG_POLL)) {
val=UINT_TO_JSVAL(idx->votes);
if(!JS_DefineProperty(cx, obj, "votes" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
val=UINT_TO_JSVAL(idx->remsg);
if(!JS_DefineProperty(cx, obj, "remsg" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
} else { /* normal message */
val=UINT_TO_JSVAL(idx->to);
if(!JS_DefineProperty(cx, obj, "to" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
val=UINT_TO_JSVAL(idx->from);
if(!JS_DefineProperty(cx, obj, "from" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
val=UINT_TO_JSVAL(idx->subj);
if(!JS_DefineProperty(cx, obj, "subject" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
}
val=UINT_TO_JSVAL(idx->attr);
if(!JS_DefineProperty(cx, obj, "attr" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
// confusingly, this is the msg.offset, not the idx.offset value
val=INT_TO_JSVAL(offset);
if(!JS_DefineProperty(cx, obj, "offset" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
val=UINT_TO_JSVAL(idx->time);
if(!JS_DefineProperty(cx, obj, "time" ,val
,NULL,NULL,JSPROP_ENUMERATE))
return false;
return true;
}
static JSBool
js_get_msg_index(JSContext *cx, uintN argc, jsval *arglist)
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
jsval *argv=JS_ARGV(cx, arglist);
uintN n;
smbmsg_t msg;
JSObject* idxobj;
JSBool by_offset=JS_FALSE;
JSBool include_votes=JS_FALSE;
private_t* p;
JSObject* proto;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
}
if(!SMB_IS_OPEN(&(p->smb)))
memset(&msg,0,sizeof(msg));
if(n < argc && JSVAL_IS_BOOLEAN(argv[n]))
by_offset = JSVAL_TO_BOOLEAN(argv[n++]);
for(;n<argc;n++) {
if(JSVAL_IS_BOOLEAN(argv[n]))
include_votes = JSVAL_TO_BOOLEAN(argv[n]);
else if(JSVAL_IS_NUMBER(argv[n])) {
if(by_offset) { /* Get by offset */
if(!JS_ValueToInt32(cx, argv[n], (int32*)&msg.offset))
return JS_FALSE;
}
else { /* Get by number */
if(!JS_ValueToInt32(cx, argv[n], (int32*)&msg.hdr.number))
return JS_FALSE;
}
}
}
rc=JS_SUSPENDREQUEST(cx);
p->smb_result = smb_getmsgidx(&(p->smb), &msg);
JS_RESUMEREQUEST(cx, rc);
if(p->smb_result != SMB_SUCCESS)
return JS_TRUE;
if(!include_votes && (msg.idx.attr&MSG_VOTE))
return JS_TRUE;
if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "MsgBase", &val) && !JSVAL_NULL_OR_VOID(val)) {
JS_ValueToObject(cx,val,&proto);
if(JS_GetProperty(cx, proto, "IndexPrototype", &val) && !JSVAL_NULL_OR_VOID(val))
JS_ValueToObject(cx,val,&proto);
else
proto=NULL;
}
else
proto=NULL;
if((idxobj=JS_NewObject(cx,NULL,proto,obj))==NULL)
set_msg_idx_properties(cx, idxobj, &msg.idx, msg.offset);
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(idxobj));
return JS_TRUE;
}
static JSBool
js_get_index(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject* obj=JS_THIS_OBJECT(cx, arglist);
jsrefcount rc;
private_t* priv;
uint32_t off;
JSObject* array;
idxrec_t* idx;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((priv=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
return JS_FALSE;
if(!SMB_IS_OPEN(&(priv->smb)))
return JS_TRUE;
off_t index_length = filelength(fileno(priv->smb.sid_fp));
if(index_length < sizeof(*idx))
return JS_TRUE;
rc=JS_SUSPENDREQUEST(cx);
if(smb_getstatus(&(priv->smb)) != SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
}
if((array = JS_NewArrayObject(cx, 0, NULL)) == NULL) {
JS_RESUMEREQUEST(cx, rc);
JS_ReportError(cx, "JS_NewArrayObject failure");
return JS_FALSE;
}
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
uint32_t total_msgs = index_length / sizeof(*idx);
if(total_msgs > priv->smb.status.total_msgs)
total_msgs = priv->smb.status.total_msgs;
if(total_msgs < 1) {
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
if((idx = calloc(total_msgs, sizeof(*idx))) == NULL) {
JS_RESUMEREQUEST(cx, rc);
JS_ReportError(cx, "malloc error on line %d in %s of %s", WHERE);
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
return JS_FALSE;
}
if((priv->smb_result = smb_locksmbhdr(&(priv->smb))) != SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
free(idx);
return JS_TRUE;
}
rewind(priv->smb.sid_fp);
size_t fread_result = fread(idx, sizeof(*idx), total_msgs, priv->smb.sid_fp);
smb_unlocksmbhdr(&(priv->smb));
JS_RESUMEREQUEST(cx, rc);
if(fread_result != total_msgs) {
JS_ReportError(cx, "index read failed (%lu instead of %lu)", fread_result, total_msgs);
free(idx);
return JS_FALSE;
}
for(off=0; off < total_msgs; off++) {
JSObject* idxobj;
if((idxobj = JS_NewObject(cx, NULL, NULL, array)) == NULL) {
JS_ReportError(cx, "object allocation failure, line %d", __LINE__);
free(idx);
return JS_FALSE;
}
set_msg_idx_properties(cx, idxobj, &idx[off], off);
JS_DefineElement(cx, array, off, OBJECT_TO_JSVAL(idxobj), NULL, NULL, JSPROP_ENUMERATE);
}
free(idx);
}
#define LAZY_BOOLEAN(PropName, PropValue, flags) \
if(name==NULL || strcmp(name, (PropName))==0) { \
if(name) free(name); \
v=INT_TO_BOOL((PropValue)); \
JS_DefineProperty(cx, obj, (PropName), v, NULL,NULL,flags); \
if(name) return JS_TRUE; \
}
#define LAZY_INTEGER(PropName, PropValue, flags) \
if(name==NULL || strcmp(name, (PropName))==0) { \
if(name) free(name); \
v=INT_TO_JSVAL((PropValue)); \
JS_DefineProperty(cx, obj, (PropName), v, NULL,NULL,flags); \
if(name) return JS_TRUE; \
}
#define LAZY_UINTEGER(PropName, PropValue, flags) \
if(name) free(name); \
v=UINT_TO_JSVAL((PropValue)); \
JS_DefineProperty(cx, obj, (PropName), v, NULL,NULL,flags); \
if(name) return JS_TRUE; \
#define LAZY_UINTEGER_EXPAND(PropName, PropValue, flags) \
if(name) free(name); \
v=UINT_TO_JSVAL((PropValue)); \
JS_DefineProperty(cx, obj, (PropName), v, NULL,NULL,flags); \
if(name) return JS_TRUE; \
else if(name) return JS_TRUE; \
#define LAZY_UINTEGER_COND(PropName, Condition, PropValue, flags) \
if(name) free(name); \
v=UINT_TO_JSVAL((uint32_t)(PropValue)); \
JS_DefineProperty(cx, obj, (PropName), v, NULL,NULL,flags); \
if(name) return JS_TRUE; \
else if(name) return JS_TRUE; \
#define LAZY_STRING(PropName, PropValue, flags) \
if(name) free(name); \
if((js_str=JS_NewStringCopyZ(cx, (PropValue)))!=NULL) { \
JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, flags); \
if(name) return JS_TRUE; \
else if(name) return JS_TRUE; \
#define LAZY_STRING_TRUNCSP(PropName, PropValue, flags) \
if(name) free(name); \
if((js_str=JS_NewStringCopyZ(cx, truncsp(PropValue)))!=NULL) { \
JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, flags); \
if(name) return JS_TRUE; \
else if(name) return JS_TRUE; \
#define LAZY_STRING_COND(PropName, Condition, PropValue, flags) \
if(name) free(name); \
if((Condition) && (js_str=JS_NewStringCopyZ(cx, (PropValue)))!=NULL) { \
JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, flags); \
if(name) return JS_TRUE; \
else if(name) return JS_TRUE; \
#define LAZY_STRING_TRUNCSP_NULL(PropName, PropValue, flags) \
if(name) free(name); \
if((PropValue) != NULL && (js_str=JS_NewStringCopyZ(cx, truncsp(PropValue)))!=NULL) { \
JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, flags); \
if(name) return JS_TRUE; \
else if(name) return JS_TRUE; \
static JSBool js_get_msg_header_resolve(JSContext *cx, JSObject *obj, jsid id)
{
char date[128];
char msg_id[256];
char reply_id[256];
char tmp[128];
char* val;
int i;
smbmsg_t remsg;
JSObject* array;
JSObject* field;
JSString* js_str;
jsint items;
jsval v;
privatemsg_t* p;
char* name=NULL;
scfg_t* scfg;
scfg=JS_GetRuntimePrivate(JS_GetRuntime(cx));
if(JSVAL_IS_STRING(idval))
JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(idval), name, NULL);
/* If we have already enumerated, we're done here... */
if((p=(privatemsg_t*)JS_GetPrivate(cx,obj))==NULL || p->enumerated) {
if(name) free(name);
if((p->msg).hdr.number==0) { /* No valid message number/id/offset specified */
if(name) free(name);
LAZY_UINTEGER("number", p->msg.hdr.number, JSPROP_ENUMERATE);
LAZY_UINTEGER("offset", p->msg.offset, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP("to",p->msg.to, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP("from",p->msg.from, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP("subject",p->msg.subj, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("to_list",p->msg.to_list, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("cc_list",p->msg.cc_list, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("summary", p->msg.summary, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("tags", p->msg.tags, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("to_ext", p->msg.to_ext, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("from_ext", p->msg.from_ext, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("from_org", p->msg.from_org, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("replyto", p->msg.replyto, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("replyto_ext", p->msg.replyto_ext, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("replyto_list", p->msg.replyto_list, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("reverse_path", p->msg.reverse_path, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("forward_path", p->msg.forward_path, JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("to_agent", p->msg.to_agent, JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("from_agent", p->msg.from_agent, JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("replyto_agent", p->msg.replyto_agent, JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("to_net_type", p->msg.to_net.type, JSPROP_ENUMERATE);
LAZY_STRING_COND("to_net_addr", p->msg.to_net.addr, smb_netaddrstr(&(p->msg).to_net,tmp), JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("from_net_type", p->msg.from_net.type, JSPROP_ENUMERATE);
/* exception here because p->msg.from_net is NULL */
LAZY_STRING_COND("from_net_addr", p->msg.from_net.addr, smb_netaddrstr(&(p->msg).from_net,tmp), JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("replyto_net_type", p->msg.replyto_net.type, JSPROP_ENUMERATE);
LAZY_STRING_COND("replyto_net_addr", p->msg.replyto_net.addr, smb_netaddrstr(&(p->msg).replyto_net,tmp), JSPROP_ENUMERATE);
LAZY_STRING_COND("from_ip_addr", (val=smb_get_hfield(&(p->msg),SENDERIPADDR,NULL))!=NULL, val, JSPROP_ENUMERATE);
LAZY_STRING_COND("from_host_name", (val=smb_get_hfield(&(p->msg),SENDERHOSTNAME,NULL))!=NULL, val, JSPROP_ENUMERATE);
LAZY_STRING_COND("from_protocol", (val=smb_get_hfield(&(p->msg),SENDERPROTOCOL,NULL))!=NULL, val, JSPROP_ENUMERATE);
LAZY_STRING_COND("from_port", (val=smb_get_hfield(&(p->msg),SENDERPORT,NULL))!=NULL, val, JSPROP_ENUMERATE);
LAZY_STRING_COND("sender_userid", (val=smb_get_hfield(&(p->msg),SENDERUSERID,NULL))!=NULL, val, JSPROP_ENUMERATE);
LAZY_STRING_COND("sender_server", (val=smb_get_hfield(&(p->msg),SENDERSERVER,NULL))!=NULL, val, JSPROP_ENUMERATE);
LAZY_STRING_COND("sender_time", (val=smb_get_hfield(&(p->msg),SENDERTIME,NULL))!=NULL, val, JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("forwarded", p->msg.forwarded, JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("expiration", p->msg.expiration, JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("cost", p->msg.cost, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("editor", p->msg.editor, JSPROP_ENUMERATE);
LAZY_UINTEGER_EXPAND("columns", p->msg.columns, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("mime_version", p->msg.mime_version, JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_STRING_TRUNCSP_NULL("content_type", p->msg.content_type, JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_STRING_TRUNCSP_NULL("text_charset", p->msg.text_charset, JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_STRING_TRUNCSP_NULL("text_subtype", p->msg.text_subtype, JSPROP_ENUMERATE|JSPROP_READONLY);
/* Fixed length portion of msg header */
LAZY_UINTEGER("type", p->msg.hdr.type, JSPROP_ENUMERATE);
LAZY_UINTEGER("version", p->msg.hdr.version, JSPROP_ENUMERATE);
LAZY_UINTEGER("attr", p->msg.hdr.attr, JSPROP_ENUMERATE);
LAZY_UINTEGER("auxattr", p->msg.hdr.auxattr, JSPROP_ENUMERATE);
LAZY_UINTEGER("netattr", p->msg.hdr.netattr, JSPROP_ENUMERATE);
LAZY_UINTEGER("when_written_time", p->msg.hdr.when_written.time, JSPROP_ENUMERATE);
LAZY_INTEGER("when_written_zone", p->msg.hdr.when_written.zone, JSPROP_ENUMERATE);
LAZY_INTEGER("when_written_zone_offset", smb_tzutc(p->msg.hdr.when_written.zone), JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_UINTEGER("when_imported_time", p->msg.hdr.when_imported.time, JSPROP_ENUMERATE);
LAZY_INTEGER("when_imported_zone", p->msg.hdr.when_imported.zone, JSPROP_ENUMERATE);
LAZY_INTEGER("when_imported_zone_offset", smb_tzutc(p->msg.hdr.when_imported.zone), JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_UINTEGER("thread_id", p->msg.hdr.thread_id, JSPROP_ENUMERATE);
LAZY_UINTEGER("thread_back", p->msg.hdr.thread_back, JSPROP_ENUMERATE);
LAZY_UINTEGER("thread_orig", p->msg.hdr.thread_back, 0);
LAZY_UINTEGER("thread_next", p->msg.hdr.thread_next, JSPROP_ENUMERATE);
LAZY_UINTEGER("thread_first", p->msg.hdr.thread_first, JSPROP_ENUMERATE);
LAZY_UINTEGER("delivery_attempts", p->msg.hdr.delivery_attempts, JSPROP_ENUMERATE);
LAZY_UINTEGER("data_length", smb_getmsgdatlen(&(p->msg)), JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_UINTEGER("text_length", smb_getmsgtxtlen(&(p->msg)), JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_STRING("date", msgdate((p->msg).hdr.when_written,date), JSPROP_ENUMERATE);
LAZY_UINTEGER("votes", p->msg.hdr.votes, JSPROP_ENUMERATE);
LAZY_UINTEGER_COND("priority", p->msg.hdr.priority != SMB_PRIORITY_UNSPECIFIED, p->msg.hdr.priority, JSPROP_ENUMERATE);
// Convenience (not technically part of header: */
LAZY_UINTEGER("upvotes", p->msg.upvotes, JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_UINTEGER("downvotes", p->msg.downvotes, JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_UINTEGER("total_votes", p->msg.total_votes, JSPROP_ENUMERATE|JSPROP_READONLY);
LAZY_BOOLEAN("is_utf8", smb_msg_is_utf8(&p->msg), JSPROP_ENUMERATE|JSPROP_READONLY);
if(name==NULL || strcmp(name,"reply_id")==0) {
if(name) free(name);
/* Reply-ID (References) */
if((p->msg).reply_id!=NULL)
val=(p->msg).reply_id;
else {
reply_id[0]=0;
if(p->expand_fields && (p->msg).hdr.thread_back) {
rc=JS_SUSPENDREQUEST(cx);
memset(&remsg,0,sizeof(remsg));
remsg.hdr.number=(p->msg).hdr.thread_back;
if(smb_getmsgidx(&(p->p->smb), &remsg))
else
get_msgid(scfg,p->p->smb.subnum,&remsg,reply_id,sizeof(reply_id));
JS_RESUMEREQUEST(cx, rc);
}
val=reply_id;
}
if(val[0] && (js_str=JS_NewStringCopyZ(cx,truncsp(val)))!=NULL) {
JS_DefineProperty(cx, obj, "reply_id"
, STRING_TO_JSVAL(js_str)
,NULL,NULL,JSPROP_ENUMERATE);
if (name)
}
else if (name)
}
/* Message-ID */
if(name==NULL || strcmp(name,"id")==0) {
if(name) free(name);
if(p->expand_fields || (p->msg).id!=NULL) {
get_msgid(scfg,p->p->smb.subnum,&(p->msg),msg_id,sizeof(msg_id));
val=msg_id;
if((js_str=JS_NewStringCopyZ(cx,truncsp(val)))!=NULL) {
JS_DefineProperty(cx, obj, "id"
,STRING_TO_JSVAL(js_str)
,NULL,NULL,JSPROP_ENUMERATE);
if (name)
}
else if (name)
}
else if (name)
}
/* USENET Fields */
LAZY_STRING_TRUNCSP_NULL("path", p->msg.path, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("newsgroups", p->msg.newsgroups, JSPROP_ENUMERATE);
/* FidoNet Header Fields */
LAZY_STRING_TRUNCSP_NULL("ftn_msgid", p->msg.ftn_msgid, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("ftn_reply", p->msg.ftn_reply, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("ftn_pid", p->msg.ftn_pid, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("ftn_tid", p->msg.ftn_tid, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("ftn_area", p->msg.ftn_area, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("ftn_flags", p->msg.ftn_flags, JSPROP_ENUMERATE);
LAZY_STRING_TRUNCSP_NULL("ftn_charset", p->msg.ftn_charset, JSPROP_ENUMERATE);
if(name) free(name);
/* Create hdr.field_list[] with repeating header fields (including type and data) */
if((array=JS_NewArrayObject(cx,0,NULL))!=NULL) {
JS_DefineProperty(cx,obj,"field_list",OBJECT_TO_JSVAL(array)
,NULL,NULL,JSPROP_ENUMERATE);
items=0;
for(i=0;i<(p->msg).total_hfields;i++) {
switch((p->msg).hfield[i].type) {
case SMB_COMMENT:
case SMB_POLL_ANSWER:
case SMB_GROUP:
case FIDOCTRL:
case FIDOSEENBY:
case FIDOPATH:
case RFC822HEADER:
case SMTPRECEIVED:
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
case UNKNOWNASCII:
/* only support these header field types */
break;
default:
/* dupe or possibly binary header field */
continue;
}
if((field=JS_NewObject(cx,NULL,NULL,array))==NULL)
continue;
JS_DefineProperty(cx,field,"type"
,INT_TO_JSVAL((p->msg).hfield[i].type)
,NULL,NULL,JSPROP_ENUMERATE);
if((js_str=JS_NewStringCopyN(cx,(p->msg).hfield_dat[i],(p->msg).hfield[i].length))==NULL)
break;
JS_DefineProperty(cx,field,"data"
,STRING_TO_JSVAL(js_str)
,NULL,NULL,JSPROP_ENUMERATE);
JS_DefineElement(cx,array,items,OBJECT_TO_JSVAL(field)
,NULL,NULL,JSPROP_ENUMERATE);
items++;
}
if (name)
}
else if (name)
}
if(name==NULL || strcmp(name, "can_read")==0) {
if(name) free(name);
v=BOOLEAN_TO_JSVAL(JS_FALSE);
do {
client_t *client=NULL;
user_t *user=NULL;
jsval cov;
ushort aliascrc,namecrc,sysop=crc16("sysop",0);
/* dig a client object out of the global object */
JS_GetProperty(cx, JS_GetGlobalObject(cx), "client", &cov);
if(JSVAL_IS_OBJECT(cov)) {
JSObject *obj = JSVAL_TO_OBJECT(cov);
JSClass *cl;
if((cl=JS_GetClass(cx,obj))!=NULL && strcmp(cl->name,"Client")==0)
client=JS_GetPrivate(cx,obj);
}
/* dig a user object out of the global object */
JS_GetProperty(cx, JS_GetGlobalObject(cx), "user", &cov);
if(JSVAL_IS_OBJECT(cov)) {
JSObject *obj = JSVAL_TO_OBJECT(cov);
JSClass *cl;
if((cl=JS_GetClass(cx,obj))!=NULL && strcmp(cl->name,"User")==0) {
user=*(user_t **)(JS_GetPrivate(cx,obj));
namecrc=crc16(user->name, 0);
aliascrc=crc16(user->alias, 0);
}
}
if(p->msg.idx.attr&MSG_DELETE) { /* Pre-flagged */
if(!(scfg->sys_misc&SM_SYSVDELM)) /* Noone can view deleted msgs */
break;
if(!(scfg->sys_misc&SM_USRVDELM) /* Users can't view deleted msgs */
&& !is_user_subop(scfg, p->p->smb.subnum, user, client)) /* not sub-op */
if(user==NULL)
break;
if(!is_user_subop(scfg, p->p->smb.subnum, user, client) /* not sub-op */
&& p->msg.idx.from!=namecrc && p->msg.idx.from!=aliascrc) /* not for you */
break;
if((p->msg.idx.attr&MSG_MODERATED) && !(p->msg.idx.attr&MSG_VALIDATED)
&& (!is_user_subop(scfg, p->p->smb.subnum, user, client)))
break;
if(p->msg.idx.attr&MSG_PRIVATE) {
if(user==NULL)
break;
if(!is_user_subop(scfg, p->p->smb.subnum, user, client) && !(user->rest&FLAG('Q'))) {
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
if(p->msg.idx.to!=namecrc && p->msg.idx.from!=namecrc
&& p->msg.idx.to!=aliascrc && p->msg.idx.from!=aliascrc
&& (user->number!=1 || p->msg.idx.to!=sysop))
break;
if(stricmp(p->msg.to,user->alias)
&& stricmp(p->msg.from,user->alias)
&& stricmp(p->msg.to,user->name)
&& stricmp(p->msg.from,user->name)
&& (user->number!=1 || stricmp(p->msg.to,"sysop")
|| p->msg.from_net.type)) {
break;
}
}
}
v=BOOLEAN_TO_JSVAL(JS_TRUE);
} while(0);
JS_DefineProperty(cx, obj, "can_read", v, NULL,NULL,JSPROP_ENUMERATE);
if(name)
if(name) free(name);
/* DO NOT RETURN JS_FALSE on unknown names */
/* Doing so will prevent toString() among others from working. */
}
static JSBool js_get_msg_header_enumerate(JSContext *cx, JSObject *obj)
{
privatemsg_t* p;
if((p=(privatemsg_t*)JS_GetPrivate(cx,obj))==NULL)
p->enumerated = TRUE;
}
static void js_get_msg_header_finalize(JSContext *cx, JSObject *obj)
{
privatemsg_t* p;
if((p=(privatemsg_t*)JS_GetPrivate(cx,obj))==NULL)
return;
smb_freemsgmem(&(p->msg));
free(p);
JS_SetPrivate(cx, obj, NULL);
}
static JSClass js_msghdr_class = {
"MsgHeader" /* name */
,JSCLASS_HAS_PRIVATE /* flags */
,JS_PropertyStub /* addProperty */
,JS_PropertyStub /* delProperty */
,JS_PropertyStub /* getProperty */
,JS_StrictPropertyStub /* setProperty */
,js_get_msg_header_enumerate /* enumerate */
,js_get_msg_header_resolve /* resolve */
,JS_ConvertStub /* convert */
,js_get_msg_header_finalize /* finalize */
};
js_get_msg_header(JSContext *cx, uintN argc, jsval *arglist)
JSObject* obj=JS_THIS_OBJECT(cx, arglist);
jsval* argv=JS_ARGV(cx, arglist);
uintN n;
JSObject* hdrobj;
JSBool by_offset=JS_FALSE;
JSBool include_votes=JS_FALSE;
char* cstr = NULL;
privatemsg_t* p;
JSObject* proto;
jsval val;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((p=(privatemsg_t*)malloc(sizeof(privatemsg_t)))==NULL) {
JS_ReportError(cx,"malloc failed");
}
memset(p,0,sizeof(privatemsg_t));
if((p->p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
if(!SMB_IS_OPEN(&(p->p->smb))) {
free(p);
p->expand_fields=JS_TRUE; /* This parameter defaults to true */
if(n < argc && JSVAL_IS_BOOLEAN(argv[n]))
by_offset = JSVAL_TO_BOOLEAN(argv[n++]);
/* Now parse message offset/id and get message */
if(n < argc && JSVAL_IS_NUMBER(argv[n])) {
if(by_offset) { /* Get by offset */
if(!JS_ValueToInt32(cx,argv[n++],(int32*)&(p->msg).offset)) {
free(p);
}
else { /* Get by number */
if(!JS_ValueToInt32(cx,argv[n++],(int32*)&(p->msg).hdr.number)) {
free(p);
rc=JS_SUSPENDREQUEST(cx);
if((p->p->smb_result=smb_getmsgidx(&(p->p->smb), &(p->msg)))!=SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
}
if((p->p->smb_result=smb_lockmsghdr(&(p->p->smb),&(p->msg)))!=SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
}
if((p->p->smb_result=smb_getmsghdr(&(p->p->smb), &(p->msg)))!=SMB_SUCCESS) {
smb_unlockmsghdr(&(p->p->smb),&(p->msg));
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
}
smb_unlockmsghdr(&(p->p->smb),&(p->msg));
JS_RESUMEREQUEST(cx, rc);
} else if(n < argc && JSVAL_IS_STRING(argv[n])) { /* Get by ID */
JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(argv[n]), cstr, NULL);
n++;
if(JS_IsExceptionPending(cx)) {
free(cstr);
free(p);
return JS_FALSE;
}
if(cstr != NULL) {
rc=JS_SUSPENDREQUEST(cx);
if((p->p->smb_result=smb_getmsghdr_by_msgid(&(p->p->smb),&(p->msg)
,cstr))!=SMB_SUCCESS) {
free(cstr);
JS_RESUMEREQUEST(cx, rc);
free(p);
return JS_TRUE; /* ID not found */
}
JS_RESUMEREQUEST(cx, rc);
}
}
if(p->msg.hdr.number==0) { /* No valid message number/id/offset specified */
free(p);
if(n < argc && JSVAL_IS_BOOLEAN(argv[n]))
p->expand_fields = JSVAL_TO_BOOLEAN(argv[n++]);
if(n < argc && JSVAL_IS_BOOLEAN(argv[n]))
include_votes = JSVAL_TO_BOOLEAN(argv[n++]);
if(!include_votes && (p->msg.hdr.attr&MSG_VOTE)) {
smb_freemsgmem(&(p->msg));
return JS_TRUE;
}
if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "MsgBase", &val) && !JSVAL_NULL_OR_VOID(val)) {
JS_ValueToObject(cx,val,&proto);
if(JS_GetProperty(cx, proto, "HeaderPrototype", &val) && !JSVAL_NULL_OR_VOID(val))
JS_ValueToObject(cx,val,&proto);
else
proto=NULL;
}
else
proto=NULL;
if((hdrobj=JS_NewObject(cx,&js_msghdr_class,proto,obj))==NULL) {
smb_freemsgmem(&(p->msg));
if(!JS_SetPrivate(cx, hdrobj, p)) {
JS_ReportError(cx,"JS_SetPrivate failed");
free(p);
}
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(hdrobj));
static JSBool
js_get_all_msg_headers(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject* obj=JS_THIS_OBJECT(cx, arglist);
jsval* argv=JS_ARGV(cx, arglist);
JSObject* hdrobj;
jsrefcount rc;
privatemsg_t* p;
private_t* priv;
JSObject* proto;
jsval val;
uint32_t off;
JSObject* retobj;
char numstr[16];
JSBool include_votes=JS_FALSE;
post_t* post;
JS_SET_RVAL(cx, arglist, JSVAL_NULL);
if((priv=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
}
if(!SMB_IS_OPEN(&(priv->smb)))
off_t index_length = filelength(fileno(priv->smb.sid_fp));
if(index_length < sizeof(*idx))
return JS_TRUE;
rc=JS_SUSPENDREQUEST(cx);
if(smb_getstatus(&(priv->smb)) != SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
}
if((retobj = JS_NewObject(cx, NULL, NULL, obj)) == NULL) {
JS_RESUMEREQUEST(cx, rc);
JS_ReportError(cx, "JS_NewObject failure");
return JS_FALSE;
}
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(retobj));
uint32_t total_msgs = index_length / sizeof(*idx);
if(total_msgs > priv->smb.status.total_msgs)
total_msgs = priv->smb.status.total_msgs;
if(total_msgs < 1) {
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
if((post = calloc(total_msgs, sizeof(*post))) == NULL) {
JS_RESUMEREQUEST(cx, rc);
JS_ReportError(cx, "malloc error on line %d in %s of %s", WHERE);
return JS_FALSE;
}
if((idx = calloc(total_msgs, sizeof(*idx))) == NULL) {
JS_RESUMEREQUEST(cx, rc);
JS_ReportError(cx, "malloc error on line %d in %s of %s", WHERE);
free(post);
return JS_FALSE;
}
uintN argn = 0;
if(argn < argc && JSVAL_IS_BOOLEAN(argv[argn])) {
include_votes = JSVAL_TO_BOOLEAN(argv[argn]);
argn++;
}
if(argn < argc && JSVAL_IS_BOOLEAN(argv[argn])) {
expand_fields = JSVAL_TO_BOOLEAN(argv[argn]);
argn++;
}
if((priv->smb_result=smb_locksmbhdr(&(priv->smb)))!=SMB_SUCCESS) {
free(post);
}
if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "MsgBase", &val) && !JSVAL_NULL_OR_VOID(val)) {
JS_ValueToObject(cx,val,&proto);
if(JS_GetProperty(cx, proto, "HeaderPrototype", &val) && !JSVAL_NULL_OR_VOID(val))
JS_ValueToObject(cx,val,&proto);
else
proto=NULL;
}
else
proto=NULL;
rewind(priv->smb.sid_fp);
size_t fread_result = fread(idx, sizeof(*idx), total_msgs, priv->smb.sid_fp);
JS_RESUMEREQUEST(cx, rc);
if(fread_result != total_msgs) {
smb_unlocksmbhdr(&(priv->smb));
JS_ReportError(cx,"index read failed (%lu instead of %lu)", fread_result, total_msgs);
free(post);
free(idx);
return JS_FALSE;
}
for(off=0; off < total_msgs; off++) {
post[off].idx = idx[off];
if(idx[off].attr&MSG_VOTE && !(idx[off].attr&MSG_POLL)) {
ulong u;
for(u = 0; u < off; u++)
if(post[u].idx.number == idx[off].remsg)
break;
if(u < off) {
post[u].total_votes++;
switch(idx[off].attr&MSG_VOTE) {
case MSG_UPVOTE:
post[u].upvotes++;
break;
case MSG_DOWNVOTE:
post[u].downvotes++;
break;
for(int b=0; b < MSG_POLL_MAX_ANSWERS; b++) {
if(idx[off].votes&(1<<b))
post[u].votes[b]++;
}
}
}
}
}
for(off=0; off < total_msgs; off++) {
if((!include_votes) && (post[off].idx.attr&MSG_VOTE))
continue;
if((p=(privatemsg_t*)malloc(sizeof(privatemsg_t)))==NULL) {
smb_unlocksmbhdr(&(priv->smb));
JS_ReportError(cx,"malloc failed");
free(post);
}
memset(p,0,sizeof(privatemsg_t));
/* Parse boolean arguments first */
p->p=priv;
p->msg.idx = post[off].idx;
priv->smb_result = smb_getmsghdr(&(priv->smb), &(p->msg));
JS_RESUMEREQUEST(cx, rc);
if(priv->smb_result != SMB_SUCCESS) {
smb_unlocksmbhdr(&(priv->smb));
free(post);
free(p);
return JS_TRUE;
}
if((hdrobj=JS_NewObject(cx,&js_msghdr_class,proto,obj))==NULL) {
smb_freemsgmem(&(p->msg));
smb_unlocksmbhdr(&(priv->smb));
free(post);
free(p);
p->msg.upvotes = post[off].upvotes;
p->msg.downvotes = post[off].downvotes;
p->msg.total_votes = post[off].total_votes;
if(post[off].total_votes) {
JSObject* array;
if((array=JS_NewArrayObject(cx,0,NULL)) != NULL) {