Newer
Older
if(smb_putmsg(&(p->smb), &msg)!=0)
break;
*rval = JSVAL_TRUE;
} while(0);
smb_unlockmsghdr(&(p->smb),&msg);
static JSBool
js_remove_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
uintN n;
JSBool by_offset=JS_FALSE;
JSBool msg_specified=JS_FALSE;
smbmsg_t msg;
private_t* p;
*rval = JSVAL_FALSE;
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
return(JS_FALSE);
}
if(!SMB_IS_OPEN(&(p->smb)))
return(JS_TRUE);
memset(&msg,0,sizeof(msg));
for(n=0;n<argc;n++) {
if(JSVAL_IS_BOOLEAN(argv[n]))
by_offset=JSVAL_TO_BOOLEAN(argv[n]);
else if(JSVAL_IS_NUMBER(argv[n])) {
JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
1042
1043
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
msg_specified=JS_TRUE;
n++;
break;
} else if(JSVAL_IS_STRING(argv[n])) { /* Get by ID */
if(!msg_offset_by_id(scfg,&(p->smb)
,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))
,&msg.offset))
return(JS_TRUE); /* ID not found */
msg_specified=JS_TRUE;
n++;
break;
}
}
if(!msg_specified)
return(JS_TRUE);
if(smb_getmsgidx(&(p->smb), &msg)!=0)
return(JS_TRUE);
if(smb_lockmsghdr(&(p->smb),&msg)!=0)
return(JS_TRUE);
do {
if(smb_getmsghdr(&(p->smb), &msg)!=0)
break;
smb_freemsghdrmem(&msg); /* prevent duplicate header fields */
msg.hdr.attr|=MSG_DELETE;
msg.idx.attr=msg.hdr.attr;
if(smb_putmsg(&(p->smb), &msg)!=0)
break;
*rval = JSVAL_TRUE;
} while(0);
smb_unlockmsghdr(&(p->smb),&msg);
smb_freemsgmem(&msg);
return(JS_TRUE);
}
static char* get_msg_text(smb_t* smb, smbmsg_t* msg, BOOL strip_ctrl_a, BOOL rfc822, ulong mode)
{
char* buf;
if(smb_getmsgidx(smb, msg)!=0)
return(NULL);
if(smb_lockmsghdr(smb,msg)!=0)
return(NULL);
if(smb_getmsghdr(smb, msg)!=0) {
smb_unlockmsghdr(smb, msg);
return(NULL);
}
if((buf=smb_getmsgtxt(smb, msg, mode))==NULL) {
smb_unlockmsghdr(smb,msg);
return(NULL);
}
smb_unlockmsghdr(smb, msg);
if(strip_ctrl_a) {
char* newbuf;
if((newbuf=malloc(strlen(buf)+1))!=NULL) {
int i,j;
for(i=j=0;buf[i];i++) {
if(buf[i]==CTRL_A && buf[i+1]!=0)
i++;
else newbuf[j++]=buf[i];
}
newbuf[j]=0;
strcpy(buf,newbuf);
free(newbuf);
}
}
if(rfc822) { /* must escape lines starting with dot ('.') */
char* newbuf;
if((newbuf=malloc((strlen(buf)*2)+1))!=NULL) {
int i,j;
for(i=j=0;buf[i];i++) {
if((i==0 || buf[i-1]=='\n') && buf[i]=='.')
newbuf[j++]='.';
newbuf[j++]=buf[i];
}
newbuf[j]=0;
free(buf);
buf = newbuf;
}
}
return(buf);
}
static JSBool
js_get_msg_body(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* buf;
uintN n;
JSBool by_offset=JS_FALSE;
JSBool strip_ctrl_a=JS_FALSE;
JSBool tails=JS_TRUE;
JSBool rfc822=JS_FALSE;
JSBool msg_specified=JS_FALSE;
private_t* p;
*rval = JSVAL_NULL;
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
return(JS_FALSE);
if(!SMB_IS_OPEN(&(p->smb)))
return(JS_TRUE);
memset(&msg,0,sizeof(msg));
for(n=0;n<argc;n++) {
if(JSVAL_IS_BOOLEAN(argv[n]))
by_offset=JSVAL_TO_BOOLEAN(argv[n]);
else if(JSVAL_IS_NUMBER(argv[n])) {
if(by_offset) /* Get by offset */
JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
else /* Get by number */
JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
msg_specified=JS_TRUE;
n++;
break;
} else if(JSVAL_IS_STRING(argv[n])) { /* Get by ID */
if(!msg_offset_by_id(scfg,&(p->smb)
,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))
,&msg.offset))
return(JS_TRUE); /* ID not found */
msg_specified=JS_TRUE;
n++;
break;
}
}
if(!msg_specified) /* No message number or id specified */
return(JS_TRUE);
if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
strip_ctrl_a=JSVAL_TO_BOOLEAN(argv[n++]);
if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
rfc822=JSVAL_TO_BOOLEAN(argv[n++]);
if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
tails=JSVAL_TO_BOOLEAN(argv[n++]);
buf = get_msg_text(&(p->smb), &msg, strip_ctrl_a, rfc822, tails ? GETMSGTXT_TAILS : 0);
if(buf==NULL)
return(JS_TRUE);
if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
*rval = STRING_TO_JSVAL(js_str);
smb_freemsgtxt(buf);
return(JS_TRUE);
}
static JSBool
js_get_msg_tail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* buf;
uintN n;
smbmsg_t msg;
JSBool by_offset=JS_FALSE;
JSBool strip_ctrl_a=JS_FALSE;
JSBool rfc822=JS_FALSE;
JSBool msg_specified=JS_FALSE;
private_t* p;
*rval = JSVAL_NULL;
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
return(JS_FALSE);
if(!SMB_IS_OPEN(&(p->smb)))
return(JS_TRUE);
memset(&msg,0,sizeof(msg));
for(n=0;n<argc;n++) {
if(JSVAL_IS_BOOLEAN(argv[n]))
by_offset=JSVAL_TO_BOOLEAN(argv[n]);
else if(JSVAL_IS_NUMBER(argv[n])) {
if(by_offset) /* Get by offset */
JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
else /* Get by number */
JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
msg_specified=JS_TRUE;
n++;
break;
} else if(JSVAL_IS_STRING(argv[n])) { /* Get by ID */
if(!msg_offset_by_id(scfg,&(p->smb)
,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))
,&msg.offset))
return(JS_TRUE); /* ID not found */
msg_specified=JS_TRUE;
n++;
break;
}
}
if(!msg_specified) /* No message number or id specified */
return(JS_TRUE);
if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
strip_ctrl_a=JSVAL_TO_BOOLEAN(argv[n++]);
if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
rfc822=JSVAL_TO_BOOLEAN(argv[n++]);
buf = get_msg_text(&(p->smb), &msg, strip_ctrl_a, rfc822, GETMSGTXT_TAILS|GETMSGTXT_NO_BODY);
if(buf==NULL)
return(JS_TRUE);
if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
*rval = STRING_TO_JSVAL(js_str);
smb_freemsgtxt(buf);
return(JS_TRUE);
}
static JSBool
js_save_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* body=NULL;
uintN n;
jsuint i;
jsuint rcpt_list_length;
jsval val;
JSObject* hdr=NULL;
JSObject* objarg;
JSObject* rcpt_list=NULL;
smbmsg_t rcpt_msg;
jsval open_rval;
*rval = JSVAL_FALSE;
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
if(!SMB_IS_OPEN(&(p->smb))) {
if(!js_open(cx, obj, 0, NULL, &open_rval))
return(JS_FALSE);
if(open_rval == JSVAL_FALSE)
return(JS_TRUE);
}
for(n=0;n<argc;n++) {
if(JSVAL_IS_OBJECT(argv[n])) {
objarg = JSVAL_TO_OBJECT(argv[n]);
if(JS_IsArrayObject(cx, objarg)) /* recipient_list is an array of objects */
rcpt_list = objarg;
else
hdr = objarg;
}
else if(JSVAL_IS_STRING(argv[n])) {
if((body=JS_GetStringBytes(JSVAL_TO_STRING(argv[n])))==NULL) {
JS_ReportError(cx,"JS_GetStringBytes failed");
return(JS_FALSE);
}
}
}
if(hdr==NULL || body==NULL)
if(rcpt_list!=NULL) {
if(!JS_GetArrayLength(cx, rcpt_list, &rcpt_list_length))
return(JS_TRUE);
if(!rcpt_list_length)
return(JS_TRUE);
}
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
if(parse_header_object(cx, p, hdr, &msg, rcpt_list==NULL)) {
truncsp(body);
if(savemsg(scfg, &(p->smb), &msg, body)==0)
*rval = JSVAL_TRUE;
if(rcpt_list!=NULL) { /* Sending to a list of recipients */
*rval = JSVAL_FALSE; /* failure, by default */
memset(&rcpt_msg, 0, sizeof(rcpt_msg));
for(i=0;i<rcpt_list_length;i++) {
if(!JS_GetElement(cx, rcpt_list, i, &val))
break;
if(!JSVAL_IS_OBJECT(val))
break;
if(smb_copymsgmem(&(p->smb), &rcpt_msg, &msg)!=0)
break;
if(!parse_recipient_object(cx, p, JSVAL_TO_OBJECT(val), &rcpt_msg))
break;
if(smb_addmsghdr(&(p->smb), &rcpt_msg, SMB_SELFPACK)!=0)
break;
smb_freemsgmem(&rcpt_msg);
}
smb_freemsgmem(&rcpt_msg); /* just in case we broke the loop */
if(i==rcpt_list_length)
*rval = JSVAL_TRUE; /* success */
}
} else
sprintf(p->smb.last_error,"Header parsing failure (required field missing?)");
smb_freemsgmem(&msg);
/* MsgBase Object Properites */
enum {
SMB_PROP_LAST_ERROR
,SMB_PROP_FILE
,SMB_PROP_DEBUG
,SMB_PROP_RETRY_TIME
,SMB_PROP_RETRY_DELAY
,SMB_PROP_LAST_MSG // last message number
,SMB_PROP_TOTAL_MSGS // total messages
,SMB_PROP_MAX_CRCS // Maximum number of CRCs to keep in history
,SMB_PROP_MAX_MSGS // Maximum number of message to keep in sub
,SMB_PROP_MAX_AGE // Maximum age of message to keep in sub (in days)
,SMB_PROP_ATTR // Attributes for this message base (SMB_HYPER,etc)
,SMB_PROP_IS_OPEN
};
static JSBool js_msgbase_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
jsint tiny;
private_t* p;
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
return(JS_FALSE);
tiny = JSVAL_TO_INT(id);
switch(tiny) {
case SMB_PROP_RETRY_TIME:
JS_ValueToInt32(cx,*vp,(int32*)&p->smb.retry_time);
break;
case SMB_PROP_RETRY_DELAY:
JS_ValueToInt32(cx,*vp,(int32*)&p->smb.retry_delay);
break;
case SMB_PROP_DEBUG:
JS_ValueToBoolean(cx,*vp,&p->debug);
break;
}
return(JS_TRUE);
}
static JSBool js_msgbase_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
char* s=NULL;
JSString* js_str;
private_t* p;
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
return(JS_FALSE);
tiny = JSVAL_TO_INT(id);
switch(tiny) {
case SMB_PROP_FILE:
break;
case SMB_PROP_LAST_ERROR:
break;
case SMB_PROP_RETRY_TIME:
*vp = INT_TO_JSVAL(p->smb.retry_time);
break;
case SMB_PROP_RETRY_DELAY:
*vp = INT_TO_JSVAL(p->smb.retry_delay);
break;
case SMB_PROP_DEBUG:
*vp = INT_TO_JSVAL(p->debug);
break;
case SMB_PROP_FIRST_MSG:
memset(&idx,0,sizeof(idx));
smb_getfirstidx(&(p->smb),&idx);
JS_NewNumberValue(cx,idx.number,vp);
case SMB_PROP_LAST_MSG:
smb_getstatus(&(p->smb));
JS_NewNumberValue(cx,p->smb.status.last_msg,vp);
break;
case SMB_PROP_TOTAL_MSGS:
smb_getstatus(&(p->smb));
JS_NewNumberValue(cx,p->smb.status.total_msgs,vp);
break;
case SMB_PROP_MAX_CRCS:
JS_NewNumberValue(cx,p->smb.status.max_crcs,vp);
break;
case SMB_PROP_MAX_MSGS:
JS_NewNumberValue(cx,p->smb.status.max_msgs,vp);
break;
case SMB_PROP_MAX_AGE:
JS_NewNumberValue(cx,p->smb.status.max_age,vp);
break;
case SMB_PROP_ATTR:
JS_NewNumberValue(cx,p->smb.status.attr,vp);
case SMB_PROP_SUBNUM:
*vp = INT_TO_JSVAL(p->smb.subnum);
break;
case SMB_PROP_IS_OPEN:
*vp = BOOLEAN_TO_JSVAL(SMB_IS_OPEN(&(p->smb)));
break;
if(s!=NULL) {
if((js_str=JS_NewStringCopyZ(cx, s))==NULL)
return(JS_FALSE);
*vp = STRING_TO_JSVAL(js_str);
}
return(JS_TRUE);
}
#define SMB_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
static jsSyncPropertySpec js_msgbase_properties[] = {
/* name ,tinyid ,flags, ver */
{ "error" ,SMB_PROP_LAST_ERROR ,SMB_PROP_FLAGS, 310 },
{ "last_error" ,SMB_PROP_LAST_ERROR ,JSPROP_READONLY, 311 }, /* alias */
{ "file" ,SMB_PROP_FILE ,SMB_PROP_FLAGS, 310 },
{ "debug" ,SMB_PROP_DEBUG ,0, 310 },
{ "retry_time" ,SMB_PROP_RETRY_TIME ,JSPROP_ENUMERATE, 310 },
{ "retry_delay" ,SMB_PROP_RETRY_DELAY ,JSPROP_ENUMERATE, 311 },
{ "first_msg" ,SMB_PROP_FIRST_MSG ,SMB_PROP_FLAGS, 310 },
{ "last_msg" ,SMB_PROP_LAST_MSG ,SMB_PROP_FLAGS, 310 },
{ "total_msgs" ,SMB_PROP_TOTAL_MSGS ,SMB_PROP_FLAGS, 310 },
{ "max_crcs" ,SMB_PROP_MAX_CRCS ,SMB_PROP_FLAGS, 310 },
{ "max_msgs" ,SMB_PROP_MAX_MSGS ,SMB_PROP_FLAGS, 310 },
{ "max_age" ,SMB_PROP_MAX_AGE ,SMB_PROP_FLAGS, 310 },
{ "attributes" ,SMB_PROP_ATTR ,SMB_PROP_FLAGS, 310 },
{ "subnum" ,SMB_PROP_SUBNUM ,SMB_PROP_FLAGS, 310 },
{ "is_open" ,SMB_PROP_IS_OPEN ,SMB_PROP_FLAGS, 310 },
#ifdef _DEBUG
static char* msgbase_prop_desc[] = {
"last occurred message base error - <small>READ ONLY</small>"
,"base path and filename of message base - <small>READ ONLY</small>"
,"message base open/lock retry timeout (in seconds)"
,"delay between message base open/lock retries (in milliseconds)"
,"first message number - <small>READ ONLY</small>"
,"last message number - <small>READ ONLY</small>"
,"total number of messages - <small>READ ONLY</small>"
,"maximum number of message CRCs to store (for dupe checking) - <small>READ ONLY</small>"
,"maximum number of messages before expiration - <small>READ ONLY</small>"
,"maximum age (in days) of messages to store - <small>READ ONLY</small>"
,"message base attributes - <small>READ ONLY</small>"
,"sub-board number (0-based, -1 for e-mail) - <small>READ ONLY</small>"
,"<i>true</i> if the message base has been opened successfully - <small>READ ONLY</small>"
,NULL
};
#endif
static JSClass js_msgbase_class = {
"MsgBase" /* name */
,JSCLASS_HAS_PRIVATE /* flags */
,JS_PropertyStub /* addProperty */
,JS_PropertyStub /* delProperty */
,js_msgbase_get /* getProperty */
,js_msgbase_set /* setProperty */
,JS_EnumerateStub /* enumerate */
,JS_ResolveStub /* resolve */
,JS_ConvertStub /* convert */
,js_finalize_msgbase /* finalize */
};
static jsSyncMethodSpec js_msgbase_functions[] = {
{"open", js_open, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("open message base")
,310
},
{"close", js_close, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("close message base (if open)")
,310
{"get_msg_header", js_get_msg_header, 2, JSTYPE_OBJECT, JSDOCSTR("[boolean by_offset,] number_or_id [,boolean expand_fields]")
,JSDOCSTR("returns a specific message header, <i>null</i> on failure. "
"Pass <i>false</i> for the <i>expand_fields</i> argument (default: <i>true</i>) "
"if you will be re-writing the header later with <i>put_msg_header()</i>")
,310
{"put_msg_header", js_put_msg_header, 2, JSTYPE_BOOLEAN, JSDOCSTR("[boolean by_offset,] number, object header")
,JSDOCSTR("write a message header")
,310
{"get_msg_body", js_get_msg_body, 2, JSTYPE_STRING, JSDOCSTR("[boolean by_offset,] number_or_id [,boolean strip_ctrl_a]")
,JSDOCSTR("returns the body text of a specific message, <i>null</i> on failure")
,310
{"get_msg_tail", js_get_msg_tail, 2, JSTYPE_STRING, JSDOCSTR("[boolean by_offset,] number_or_id [,boolean strip_ctrl_a]")
,JSDOCSTR("returns the tail text of a specific message, <i>null</i> on failure")
,310
{"get_msg_index", js_get_msg_index, 2, JSTYPE_OBJECT, JSDOCSTR("[boolean by_offset,] number")
,JSDOCSTR("returns a specific message index, <i>null</i> on failure. "
"The index object will contain the following properties:<br>"
"<table>"
"<tr><td><tt>subject</tt><td>CRC-16 of lowercase message subject"
"<tr><td><tt>to</tt><td>CRC-16 of lowercase recipient's name (or user number if e-mail)"
"<tr><td><tt>from</tt><td>CRC-16 of lowercase sender's name (or user number if e-mail)"
"<tr><td><tt>attr</tt><td>Attribute bitfield"
"<tr><td><tt>time</tt><td>Date/time (in time_t format)"
"<tr><td><tt>number</tt><td>Message number"
"<tr><td><tt>offset</tt><td>Byte-offset into header file"
"</table>")
,311
},
{"remove_msg", js_remove_msg, 2, JSTYPE_BOOLEAN, JSDOCSTR("[boolean by_offset,] number_or_id")
,JSDOCSTR("mark message as deleted")
,311
{"save_msg", js_save_msg, 2, JSTYPE_BOOLEAN, JSDOCSTR("object header, string body_text [,array rcpt_list]")
,JSDOCSTR("create a new message in message base, the <i>header</i> object may contain the following properties:<br>"
"<table>"
"<tr><td><tt>subject</tt><td>Message subject <i>(required)</i>"
"<tr><td><tt>to</tt><td>Recipient's name <i>(required)</i>"
"<tr><td><tt>to_ext</tt><td>Recipient's user number (for local e-mail)"
"<tr><td><tt>to_org</tt><td>Recipient's organization"
"<tr><td><tt>to_net_type</tt><td>Recipient's network type (default: 0 for local)"
"<tr><td><tt>to_net_addr</tt><td>Recipient's network address"
"<tr><td><tt>to_agent</tt><td>Recipient's agent type"
"<tr><td><tt>from</tt><td>Sender's name <i>(required)</i>"
"<tr><td><tt>from_ext</tt><td>Sender's user number"
"<tr><td><tt>from_org</tt><td>Sender's organization"
"<tr><td><tt>from_net_type</tt><td>Sender's network type (default: 0 for local)"
"<tr><td><tt>from_net_addr</tt><td>Sender's network address"
"<tr><td><tt>from_agent</tt><td>Sender's agent type"
"<tr><td><tt>from_ip_addr</tt><td>Sender's IP address (if available, for security tracking)"
"<tr><td><tt>from_host_name</tt><td>Sender's host name (if available, for security tracking)"
"<tr><td><tt>from_protocol</tt><td>TCP/IP protocol used by sender (if available, for security tracking)"
"<tr><td><tt>from_port</tt><td>TCP/UDP port number used by sender (if available, for security tracking)"
"<tr><td><tt>replyto</tt><td>Replies should be sent to this name"
"<tr><td><tt>replyto_ext</tt><td>Replies should be sent to this user number"
"<tr><td><tt>replyto_org</tt><td>Replies should be sent to organization"
"<tr><td><tt>replyto_net_type</tt><td>Replies should be sent to this network type"
"<tr><td><tt>replyto_net_addr</tt><td>Replies should be sent to this network address"
"<tr><td><tt>replyto_agent</tt><td>Replies should be sent to this agent type"
"<tr><td><tt>id</tt><td>Message's RFC-822 compliant Message-ID"
"<tr><td><tt>reply_id</tt><td>Message's RFC-822 compliant Reply-ID"
"<tr><td><tt>reverse_path</tt><td>Message's SMTP sender address"
"<tr><td><tt>path</tt><td>Messages's NNTP path"
"<tr><td><tt>newsgroups</tt><td>Message's NNTP newsgroups header"
"<tr><td><tt>ftn_msgid</tt><td>FidoNet FTS-9 Message-ID"
"<tr><td><tt>ftn_reply</tt><td>FidoNet FTS-9 Reply-ID"
"<tr><td><tt>ftn_area</tt><td>FidoNet FTS-4 echomail AREA tag"
"<tr><td><tt>ftn_flags</tt><td>FidoNet FSC-53 FLAGS"
"<tr><td><tt>ftn_pid</tt><td>FidoNet FSC-46 Program Identifier"
"<tr><td><tt>ftn_tid</tt><td>FidoNet FSC-46 Tosser Identifier"
"<tr><td><tt>date</tt><td>RFC-822 formatted date/time"
"<tr><td><tt>attr</tt><td>Attribute bitfield"
"<tr><td><tt>auxattr</tt><td>Auxillary attribute bitfield"
"<tr><td><tt>netattr</tt><td>Network attribute bitfield"
"<tr><td><tt>when_written_time</tt><td>Date/time (in time_t format)"
"<tr><td><tt>when_written_zone</tt><td>Time zone"
"<tr><td><tt>when_imported_time</tt><td>Date/time message was imported"
"<tr><td><tt>when_imported_zone</tt><td>Time zone"
"<tr><td><tt>thread_orig</tt><td>Replying to this message number"
"<tr><td><tt>thread_next</tt><td>Number of next message in this thread"
"<tr><td><tt>thread_first</tt><td>Number of first reply to this message"
"<tr><td><tt>field_list[].type</tt><td>Other SMB header fields (type)"
"<tr><td><tt>field_list[].data</tt><td>Other SMB header fields (data)"
"</table>"
"<br>"
"The optional <i>rcpt_list</i> is an array of objects that specifies multiple recipients "
"for a single message (e.g. bulk e-mail). Each object in the array may include the following header properties "
"(described above): <br>"
"<i>to</i>, <i>to_ext</i>, <i>to_org</i>, <i>to_net_type</i>, <i>to_net_addr</i>, and <i>to_agent</i>"
)
,310
},
/* MsgBase Constructor (open message base) */
static JSBool
js_msgbase_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSString* js_str;
JSObject* cfgobj;
char* base;
private_t* p;
if((p=(private_t*)malloc(sizeof(private_t)))==NULL) {
JS_ReportError(cx,"malloc failed");
return(JS_FALSE);
}
memset(p,0,sizeof(private_t));
p->smb.retry_time=scfg->smb_retry_time;
js_str = JS_ValueToString(cx, argv[0]);
base=JS_GetStringBytes(js_str);
p->debug=JS_FALSE;
if(!JS_SetPrivate(cx, obj, p)) {
JS_ReportError(cx,"JS_SetPrivate failed");
free(p);
return(JS_FALSE);
}
if(!js_DefineSyncProperties(cx,obj,js_msgbase_properties)) {
free(p);
return(JS_FALSE);
}
#ifdef _DEBUG
js_DescribeSyncObject(cx,obj,"Class used for accessing message bases",310);
js_DescribeSyncConstructor(cx,obj,"To create a new MsgBase object: "
"<tt>var msgbase = new MsgBase('<i>code</i>')</tt><br>"
"where <i>code</i> is a sub-board internal code, or <tt>mail</tt> for the e-mail message base");
js_CreateArrayOfStrings(cx, obj, "_property_desc_list", msgbase_prop_desc, JSPROP_READONLY);
#endif
if(stricmp(base,"mail")==0) {
p->smb.subnum=INVALID_SUB;
snprintf(p->smb.file,sizeof(p->smb.file),"%s%s",scfg->data_dir,"mail");
} else {
for(p->smb.subnum=0;p->smb.subnum<scfg->total_subs;p->smb.subnum++) {
if(!stricmp(scfg->sub[p->smb.subnum]->code,base)) /* null ptr dereference here Apr-16-2003 */
break;
}
if(p->smb.subnum<scfg->total_subs) {
cfgobj=JS_NewObject(cx,NULL,NULL,obj);
js_CreateMsgAreaProperties(cx, scfg, cfgobj, p->smb.subnum);
#ifdef _DEBUG
js_DescribeSyncObject(cx,cfgobj
,"Configuration parameters for this message area (<i>sub-boards only</i>) "
"- <small>READ ONLY</small>"
,310);
#endif
JS_DefineProperty(cx,obj,"cfg",OBJECT_TO_JSVAL(cfgobj)
,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
snprintf(p->smb.file,sizeof(p->smb.file),"%s%s"
,scfg->sub[p->smb.subnum]->data_dir,scfg->sub[p->smb.subnum]->code);
} else { /* unknown code */
SAFECOPY(p->smb.file,base);
p->smb.subnum=INVALID_SUB;
}
}
if(!js_DefineSyncMethods(cx, obj, js_msgbase_functions, FALSE)) {
JS_ReportError(cx,"js_DefineSyncMethods failed");
return(JS_FALSE);
}
return(JS_TRUE);
}
JSObject* DLLCALL js_CreateMsgBaseClass(JSContext* cx, JSObject* parent, scfg_t* cfg)
{
JSObject* obj;
scfg = cfg;
obj = JS_InitClass(cx, parent, NULL
,&js_msgbase_class
,js_msgbase_constructor
,1 /* number of constructor args */
,NULL //js_msgbase_properties
,NULL //js_msgbase_functions
,NULL,NULL);
return(obj);
}