Newer
Older
if((p->p->status=smb_getmsgidx(&(p->p->smb), &(p->msg)))!=SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
if((p->p->status=smb_lockmsghdr(&(p->p->smb),&(p->msg)))!=SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE);
if((p->p->status=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);
break;
} else if(JSVAL_IS_STRING(argv[n])) { /* Get by ID */
cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
rc=JS_SUSPENDREQUEST(cx);
if((p->p->status=smb_getmsghdr_by_msgid(&(p->p->smb),&(p->msg)
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE); /* ID not found */
JS_RESUMEREQUEST(cx, rc);
break;
}
}
if((p->msg).hdr.number==0) /* No valid message number/id/offset specified */
return(JS_TRUE);
if((hdrobj=JS_NewObject(cx,&js_msghdr_class,hdr_proto,obj))==NULL) {
smb_freemsgmem(&(p->msg));
if(!JS_SetPrivate(cx, hdrobj, p)) {
JS_ReportError(cx,"JS_SetPrivate failed");
free(p);
return(JS_FALSE);
}
*rval = OBJECT_TO_JSVAL(hdrobj);
return(JS_TRUE);
}
static JSBool
js_put_msg_header(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
uintN n;
JSBool by_offset=JS_FALSE;
JSBool msg_specified=JS_FALSE;
JSObject* hdr=NULL;
*rval = JSVAL_FALSE;
if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
JS_ReportError(cx,getprivate_failure,WHERE);
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_NUM(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 */
cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
rc=JS_SUSPENDREQUEST(cx);
if(!msg_offset_by_id(p
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE); /* ID not found */
JS_RESUMEREQUEST(cx, rc);
msg_specified=JS_TRUE;
n++;
break;
}
}
if(!msg_specified)
return(JS_TRUE);
if(n==argc || !JSVAL_IS_OBJECT(argv[n])) /* no header supplied? */
return(JS_TRUE);
hdr = JSVAL_TO_OBJECT(argv[n++]);
rc=JS_SUSPENDREQUEST(cx);
if((p->status=smb_getmsgidx(&(p->smb), &msg))!=SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
if((p->status=smb_lockmsghdr(&(p->smb),&msg))!=SMB_SUCCESS) {
JS_RESUMEREQUEST(cx, rc);
if((p->status=smb_getmsghdr(&(p->smb), &msg))!=SMB_SUCCESS)
smb_freemsghdrmem(&msg); /* prevent duplicate header fields */
JS_RESUMEREQUEST(cx, rc);
if(!parse_header_object(cx, p, hdr, &msg, TRUE)) {
SAFECOPY(p->smb.last_error,"Header parsing failure (required field missing?)");
rc=JS_SUSPENDREQUEST(cx);
if((p->status=smb_putmsg(&(p->smb), &msg))!=SMB_SUCCESS)
break;
*rval = JSVAL_TRUE;
} while(0);
smb_unlockmsghdr(&(p->smb),&msg);
JS_RESUMEREQUEST(cx, rc);
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_NUM(argv[n])) {
JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
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 */
cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
rc=JS_SUSPENDREQUEST(cx);
if(!msg_offset_by_id(p
JS_RESUMEREQUEST(cx, rc);
JS_RESUMEREQUEST(cx, rc);
msg_specified=JS_TRUE;
n++;
break;
}
}
if(!msg_specified)
return(JS_TRUE);
rc=JS_SUSPENDREQUEST(cx);
if((p->status=smb_getmsgidx(&(p->smb), &msg))==SMB_SUCCESS
&& (p->status=smb_getmsghdr(&(p->smb), &msg))==SMB_SUCCESS) {
if((p->status=smb_updatemsg(&(p->smb), &msg))==SMB_SUCCESS)
*rval = JSVAL_TRUE;
}
JS_RESUMEREQUEST(cx, rc);
static char* get_msg_text(private_t* p, smbmsg_t* msg, BOOL strip_ctrl_a, BOOL rfc822, ulong mode)
{
char* buf;
if((p->status=smb_getmsgidx(&(p->smb), msg))!=SMB_SUCCESS)
return(NULL);
if((p->status=smb_lockmsghdr(&(p->smb),msg))!=SMB_SUCCESS)
return(NULL);
if((p->status=smb_getmsghdr(&(p->smb), msg))!=SMB_SUCCESS) {
smb_unlockmsghdr(&(p->smb), msg);
return(NULL);
}
if((buf=smb_getmsgtxt(&(p->smb), msg, mode))==NULL) {
smb_unlockmsghdr(&(p->smb),msg);
return(NULL);
}
smb_unlockmsghdr(&(p->smb), msg);
if(strip_ctrl_a)
remove_ctrl_a(buf, buf);
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;
*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_NUM(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 */
cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
rc=JS_SUSPENDREQUEST(cx);
if(!msg_offset_by_id(p
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE); /* ID not found */
JS_RESUMEREQUEST(cx, rc);
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++]);
rc=JS_SUSPENDREQUEST(cx);
buf = get_msg_text(p, &msg, strip_ctrl_a, rfc822, tails ? GETMSGTXT_TAILS : 0);
JS_RESUMEREQUEST(cx, rc);
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_NUM(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 */
cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
rc=JS_SUSPENDREQUEST(cx);
if(!msg_offset_by_id(p
JS_RESUMEREQUEST(cx, rc);
return(JS_TRUE); /* ID not found */
JS_RESUMEREQUEST(cx, rc);
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++]);
rc=JS_SUSPENDREQUEST(cx);
buf = get_msg_text(p, &msg, strip_ctrl_a, rfc822, GETMSGTXT_TAILS|GETMSGTXT_NO_BODY);
JS_RESUMEREQUEST(cx, rc);
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;
jsuint i;
jsuint rcpt_list_length;
jsval val;
JSObject* hdr=NULL;
JSObject* objarg;
JSObject* rcpt_list=NULL;
JSClass* cl;
smbmsg_t rcpt_msg;
client_t* client=NULL;
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((cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0) {
client=JS_GetPrivate(cx,objarg);
continue;
}
if(JS_IsArrayObject(cx, objarg)) { /* recipient_list is an array of objects */
if(body!=NULL && rcpt_list==NULL) { /* body text already specified */
rcpt_list = objarg;
continue;
}
}
else if(hdr==NULL) {
hdr = objarg;
continue;
if(body==NULL
&& (body=JS_GetStringBytes(JS_ValueToString(cx,argv[n])))==NULL) {
JS_ReportError(cx,"JS_GetStringBytes failed");
return(JS_FALSE);
}
if(hdr==NULL)
if(body==NULL)
body="";
if(rcpt_list!=NULL) {
if(!JS_GetArrayLength(cx, rcpt_list, &rcpt_list_length))
return(JS_TRUE);
if(!rcpt_list_length)
return(JS_TRUE);
}
if(parse_header_object(cx, p, hdr, &msg, rcpt_list==NULL)) {
if(body[0])
truncsp(body);
if((p->status=savemsg(scfg, &(p->smb), &msg, client, body))==SMB_SUCCESS) {
*rval = JSVAL_TRUE;
if(rcpt_list!=NULL) { /* Sending to a list of recipients */
*rval = JSVAL_FALSE; /* failure, by default */
SAFECOPY(p->smb.last_error,"Recipient list parsing failure");
if(!JS_GetElement(cx, rcpt_list, i, &val))
break;
if(!JSVAL_IS_OBJECT(val))
break;
if((p->status=smb_copymsgmem(&(p->smb), &rcpt_msg, &msg))!=SMB_SUCCESS)
break;
if(!parse_recipient_object(cx, p, JSVAL_TO_OBJECT(val), &rcpt_msg))
break;
if((p->status=smb_addmsghdr(&(p->smb), &rcpt_msg, SMB_SELFPACK))!=SMB_SUCCESS)
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 */
}
}
SAFECOPY(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_FIRST_MSG /* first message number */
,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_SUBNUM /* sub-board number */
,SMB_PROP_IS_OPEN
,SMB_PROP_STATUS /* Last SMBLIB returned status value (e.g. retval) */
};
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;
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:
case SMB_PROP_STATUS:
*vp = INT_TO_JSVAL(p->status);
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;
rc=JS_SUSPENDREQUEST(cx);
memset(&idx,0,sizeof(idx));
smb_getfirstidx(&(p->smb),&idx);
JS_RESUMEREQUEST(cx, rc);
JS_NewNumberValue(cx,idx.number,vp);
case SMB_PROP_LAST_MSG:
rc=JS_SUSPENDREQUEST(cx);
smb_getstatus(&(p->smb));
JS_RESUMEREQUEST(cx, rc);
JS_NewNumberValue(cx,p->smb.status.last_msg,vp);
break;
case SMB_PROP_TOTAL_MSGS:
rc=JS_SUSPENDREQUEST(cx);
smb_getstatus(&(p->smb));
JS_RESUMEREQUEST(cx, rc);
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 */
{ "status" ,SMB_PROP_STATUS ,SMB_PROP_FLAGS, 312 },
{ "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 BUILD_JSDOCS
static char* msgbase_prop_desc[] = {
"last occurred message base error - <small>READ ONLY</small>"
,"return value of last <i>SMB Library</i> function call - <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, 65535 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 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("[by_offset=<tt>false</tt>,] number_or_id [,expand_fields=<tt>true</tt>]")
,JSDOCSTR("returns a specific message header, <i>null</i> on failure. "
"<br><i>New in v3.12:</i> 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>")
,312
{"put_msg_header", js_put_msg_header, 2, JSTYPE_BOOLEAN, JSDOCSTR("[by_offset=<tt>false</tt>,] number, object header")
,JSDOCSTR("write a message header")
,310
{"get_msg_body", js_get_msg_body, 2, JSTYPE_STRING, JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id [,strip_ctrl_a=<tt>false</tt>] "
"[,rfc822_encoded=<tt>false</tt>] [,include_tails=<tt>true</tt>]")
,JSDOCSTR("returns the body text of a specific message, <i>null</i> on failure. "
"The default behavior is to leave Ctrl-A codes intact, perform no RFC-822 encoding, and to include tails (if any) in the "
"returned body text."
)
,310
{"get_msg_tail", js_get_msg_tail, 2, JSTYPE_STRING, JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id [,strip_ctrl_a]=<tt>false</tt>")
,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("[by_offset=<tt>false</tt>,] number")
,JSDOCSTR("returns a specific message index, <i>null</i> on failure. "
"The index object will contain the following properties:<br>"
"<table>"
"<tr><td align=top><tt>subject</tt><td>CRC-16 of lowercase message subject"
"<tr><td align=top><tt>to</tt><td>CRC-16 of lowercase recipient's name (or user number if e-mail)"
"<tr><td align=top><tt>from</tt><td>CRC-16 of lowercase sender's name (or user number if e-mail)"
"<tr><td align=top><tt>attr</tt><td>Attribute bitfield"
"<tr><td align=top><tt>time</tt><td>Date/time imported (in time_t format)"
"<tr><td align=top><tt>number</tt><td>Message number"
"<tr><td align=top><tt>offset</tt><td>Record number in index file"
"</table>")
,311
},
{"remove_msg", js_remove_msg, 2, JSTYPE_BOOLEAN, JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id")
,311
{"save_msg", js_save_msg, 2, JSTYPE_BOOLEAN, JSDOCSTR("object header [,client=<i>none</i>] [,body_text=<tt>\"\"</tt>] [,array rcpt_list=<i>none</i>]")
,JSDOCSTR("create a new message in message base, the <i>header</i> object may contain the following properties:<br>"
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
"<tr><td align=top><tt>subject</tt><td>Message subject <i>(required)</i>"
"<tr><td align=top><tt>to</tt><td>Recipient's name <i>(required)</i>"
"<tr><td align=top><tt>to_ext</tt><td>Recipient's user number (for local e-mail)"
"<tr><td align=top><tt>to_org</tt><td>Recipient's organization"
"<tr><td align=top><tt>to_net_type</tt><td>Recipient's network type (default: 0 for local)"
"<tr><td align=top><tt>to_net_addr</tt><td>Recipient's network address"
"<tr><td align=top><tt>to_agent</tt><td>Recipient's agent type"
"<tr><td align=top><tt>from</tt><td>Sender's name <i>(required)</i>"
"<tr><td align=top><tt>from_ext</tt><td>Sender's user number"
"<tr><td align=top><tt>from_org</tt><td>Sender's organization"
"<tr><td align=top><tt>from_net_type</tt><td>Sender's network type (default: 0 for local)"
"<tr><td align=top><tt>from_net_addr</tt><td>Sender's network address"
"<tr><td align=top><tt>from_agent</tt><td>Sender's agent type"
"<tr><td align=top><tt>from_ip_addr</tt><td>Sender's IP address (if available, for security tracking)"
"<tr><td align=top><tt>from_host_name</tt><td>Sender's host name (if available, for security tracking)"
"<tr><td align=top><tt>from_protocol</tt><td>TCP/IP protocol used by sender (if available, for security tracking)"
"<tr><td align=top><tt>from_port</tt><td>TCP/UDP port number used by sender (if available, for security tracking)"
"<tr><td align=top><tt>replyto</tt><td>Replies should be sent to this name"
"<tr><td align=top><tt>replyto_ext</tt><td>Replies should be sent to this user number"
"<tr><td align=top><tt>replyto_org</tt><td>Replies should be sent to organization"
"<tr><td align=top><tt>replyto_net_type</tt><td>Replies should be sent to this network type"
"<tr><td align=top><tt>replyto_net_addr</tt><td>Replies should be sent to this network address"
"<tr><td align=top><tt>replyto_agent</tt><td>Replies should be sent to this agent type"
"<tr><td align=top><tt>id</tt><td>Message's RFC-822 compliant Message-ID"
"<tr><td align=top><tt>reply_id</tt><td>Message's RFC-822 compliant Reply-ID"
"<tr><td align=top><tt>reverse_path</tt><td>Message's SMTP sender address"
"<tr><td align=top><tt>forward_path</tt><td>Argument to SMTP 'RCPT TO' command"
"<tr><td align=top><tt>path</tt><td>Messages's NNTP path"
"<tr><td align=top><tt>newsgroups</tt><td>Message's NNTP newsgroups header"
"<tr><td align=top><tt>ftn_msgid</tt><td>FidoNet FTS-9 Message-ID"
"<tr><td align=top><tt>ftn_reply</tt><td>FidoNet FTS-9 Reply-ID"
"<tr><td align=top><tt>ftn_area</tt><td>FidoNet FTS-4 echomail AREA tag"
"<tr><td align=top><tt>ftn_flags</tt><td>FidoNet FSC-53 FLAGS"
"<tr><td align=top><tt>ftn_pid</tt><td>FidoNet FSC-46 Program Identifier"
"<tr><td align=top><tt>ftn_tid</tt><td>FidoNet FSC-46 Tosser Identifier"
"<tr><td align=top><tt>date</tt><td>RFC-822 formatted date/time"
"<tr><td align=top><tt>attr</tt><td>Attribute bitfield"
"<tr><td align=top><tt>auxattr</tt><td>Auxillary attribute bitfield"
"<tr><td align=top><tt>netattr</tt><td>Network attribute bitfield"
"<tr><td align=top><tt>when_written_time</tt><td>Date/time (in time_t format)"
"<tr><td align=top><tt>when_written_zone</tt><td>Time zone (in SMB format)"
"<tr><td align=top><tt>when_written_zone_offset</tt><td>Time zone in minutes east of UTC"
"<tr><td align=top><tt>when_imported_time</tt><td>Date/time message was imported"
"<tr><td align=top><tt>when_imported_zone</tt><td>Time zone (in SMB format)"
"<tr><td align=top><tt>when_imported_zone_offset</tt><td>Time zone in minutes east of UTC"
"<tr><td align=top><tt>thread_back</tt><td>Message number that this message is a reply to"
"<tr><td align=top><tt>thread_next</tt><td>Message number of the next reply to the original message in this thread"
"<tr><td align=top><tt>thread_first</tt><td>Message number of the first reply to this message"
"<tr><td align=top><tt>field_list[].type</tt><td>Other SMB header fields (type)"
"<tr><td align=top><tt>field_list[].data</tt><td>Other SMB header fields (data)"
"</table>"
"<br><i>New in v3.12:</i> "
"The optional <i>client</i> argument is an instance of the <i>Client</i> class to be used for the "
"security log header fields (e.g. sender IP address, hostname, protocol, and port). "
"<br><br><i>New in v3.12:</i> "
"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>"
)
,312
},
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
static JSBool js_msgbase_resolve(JSContext *cx, JSObject *obj, jsval id)
{
char* name=NULL;
if(id != JSVAL_NULL)
name=JS_GetStringBytes(JSVAL_TO_STRING(id));
return(js_SyncResolve(cx, obj, name, js_msgbase_properties, js_msgbase_functions, NULL, 0));
}
static JSBool js_msgbase_enumerate(JSContext *cx, JSObject *obj)
{
return(js_msgbase_resolve(cx, obj, JSVAL_NULL));
}
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_msgbase_enumerate /* enumerate */
,js_msgbase_resolve /* resolve */
,JS_ConvertStub /* convert */
,js_finalize_msgbase /* finalize */
};
/* 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);
}
#ifdef BUILD_JSDOCS
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; /* and again, Aug-18-2004 upon recycle */
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
/* One more time, Mon Jan 26 22:44:23 PST 2009 */
/*
#0 0x282d61b6 in js_msgbase_constructor (cx=0x288bf180, obj=0x29e39460, argc=1, argv=0x28e7413c, rval=0xbf0e8b30)
at js_msgbase.c:1905
#1 0x2813cb9f in js_Invoke (cx=0x288bf180, argc=1, flags=1) at jsinterp.c:1375
#2 0x2813e6c7 in js_InvokeConstructor (cx=0x288bf180, vp=0x28e74134, argc=1) at jsinterp.c:1947
#3 0x28146a3b in js_Interpret (cx=0x288bf180, pc=0x28e828dd "#", result=0xbf0e9450) at jsinterp.c:3396
#4 0x2813d669 in js_Execute (cx=0x288bf180, chain=0x288c79a0, script=0x28e82800, down=0x0, flags=0,
result=0xbf0e9a60) at jsinterp.c:1633
#5 0x2810208a in JS_ExecuteScript (cx=0x288bf180, obj=0x288c79a0, script=0x28e82800, rval=0xbf0e9a60)
at jsapi.c:4188
#6 0x282c4f1f in js_load (cx=0x288bf180, obj=0x288c66c0, argc=1, argv=0x28e74024, rval=0xbf0e9a60)
at js_global.c:364
#7 0x2813cb9f in js_Invoke (cx=0x288bf180, argc=1, flags=0) at jsinterp.c:1375
#8 0x2814bfe3 in js_Interpret (cx=0x288bf180, pc=0x28e17a97 ":", result=0xbf0ea300) at jsinterp.c:3944
#9 0x2813d669 in js_Execute (cx=0x288bf180, chain=0x288c79a0, script=0x28e17a60, down=0x0, flags=0,
result=0xbf0eabc0) at jsinterp.c:1633
#10 0x2810208a in JS_ExecuteScript (cx=0x288bf180, obj=0x288c79a0, script=0x28e17a60, rval=0xbf0eabc0)
at jsapi.c:4188
#11 0x2828c066 in sbbs_t::js_execfile (this=0x28ac8000, cmd=0x28ad178e "chinkmaster.js") at exec.cpp:645
#12 0x283725c7 in sbbs_t::external (this=0x28ac8000, cmdline=0x28ad178d "?chinkmaster.js", mode=256,
startup_dir=0x28a2bcaa "") at xtrn.cpp:1318
#13 0x283068d9 in event_thread (arg=0x28ac8000) at main.cpp:2713
#14 0x28550a99 in pthread_getprio () from /lib/libthr.so.3
#15 0x00000000 in ?? ()
(gdb) print scfg
$1 = (scfg_t *) 0x2842f480
(gdb) print scfg->sub
$2 = (sub_t **) 0x0
(gdb) print scfg->sub
$3 = (sub_t **) 0x0
(gdb) print p
$4 = (private_t *) 0x29e3c000
(gdb) print *scfg
$5 = {size = 23200, prepped = 1, grp = 0x0, total_grps = 3, sub = 0x0, total_subs = 79, lib = 0x0,
total_libs = 6, dir = 0x0, total_dirs = 232, txtsec = 0x0, total_txtsecs = 0, xtrnsec = 0x0,
total_xtrnsecs = 3, xtrn = 0x0, total_xtrns = 44, mdm_result = 0x0, mdm_results = 3, prot = 0x0,
total_prots = 9, fextr = 0x0, total_fextrs = 3, fcomp = 0x0, total_fcomps = 3, fview = 0x0, total_fviews = 12,
ftest = 0x0, total_ftests = 5, xedit = 0x0, total_xedits = 4, qhub = 0x0, total_qhubs = 1, phub = 0x0,
total_phubs = 0, chan = 0x0, total_chans = 3, chatact = 0x0, total_chatacts = 132, actset = 0x0,
total_actsets = 1, page = 0x0, total_pages = 2, event = 0x0, total_events = 16, dlevent = 0x0,
total_dlevents = 0, faddr = 0x0, total_faddrs = 0, swap = 0x0, total_swaps = 19, natvpgm = 0x0,
total_natvpgms = 10, guru = 0x0, total_gurus = 1, shell = 0x0, total_shells = 11, hotkey = 0x0,
total_hotkeys = 0, com_base = 15, com_irq = 3, com_rate = 2400, com_port = 1 '\001',
mdm_init = "AT&FS0=0S2=128E0V0X4&C1&D2", '\0' <repeats 37 times>, mdm_spec = '\0' <repeats 63 times>,
mdm_term = "ATE1V1", '\0' <repeats 57 times>, mdm_dial = "ATDT", '\0' <repeats 59 times>,
mdm_offh = "ATM0H1", '\0' <repeats 57 times>, mdm_answ = "ATA", '\0' <repeats 60 times>,
mdm_hang = '\0' <repeats 63 times>, mdm_misc = 0, mdm_reinit = 0, mdm_ansdelay = 5, mdm_rings = 1 '\001',
sys_misc = -2045643832, sys_pass = "XXXXXXXX", '\0' <repeats 32 times>,
sys_name = "Synchronix", '\0' <repeats 30 times>, sys_id = "SYNCNIX\000", sys_psname = '\0' <repeats 12 times>,
sys_psnum = 0, sys_inetaddr = "nix.synchro.net", '\0' <repeats 112 times>,
sys_location = "Springside, SK", '\0' <repeats 26 times>, sys_timezone = 16864,
sys_daily = '\0' <repeats 63 times>, sys_logon = '\0' <repeats 63 times>, sys_logout = '\0' <repeats 63 times>,
sys_pwdays = 0, sys_deldays = 14, sys_autodel = 180, sys_nodes = 4, sys_op = "Deuce", '\0' <repeats 35 times>,
sys_guru = "The Guru", '\0' <repeats 32 times>, sys_exp_warn = 30 '\036', sys_def_stat = 1 '\001',
sys_phonefmt = '!' <repeats 12 times>, sys_lastnode = 250, sys_autonode = 1,
sys_chat_arstr = '\0' <repeats 40 times>, sys_chat_ar = 0x2837ca04 "", msg_misc = -65536, file_misc = 0,
xtrn_misc = 0, node_comspec = '\0' <repeats 63 times>, node_editor = '\0' <repeats 63 times>,
node_viewer = "%!list %f", '\0' <repeats 54 times>, node_daily = '\0' <repeats 63 times>,
node_scrnlen = 0 '\0', node_scrnblank = 0 '\0', node_misc = 33298, node_valuser = 1, node_ivt = 1,
node_swap = 2 '\002', node_swapdir = '\0' <repeats 63 times>, node_minbps = 300, node_num = 1,
node_phone = "XXX-XXX-XXXX", node_name = "Node 1", '\0' <repeats 34 times>,
node_arstr = '\0' <repeats 40 times>, node_ar = 0x2837ca04 "", node_cost = 0, node_dollars_per_call = 0 '\0',
node_sem_check = 5, node_stat_check = 5, new_install = 0 '\0', new_pass = '\0' <repeats 40 times>,
new_magic = '\0' <repeats 20 times>, new_sif = "\000\000\000\000\000\000\000\000",
new_sof = "\000\000\000\000\000\000\000\000", new_level = 50 '2', new_flags1 = 0, new_flags2 = 0,
new_flags3 = 0, new_flags4 = 0, new_exempt = 0, new_rest = 0, new_cdt = 10485760, new_min = 0,
new_xedit = "\000\000\000\000\000\000\000\000", new_shell = 0, new_misc = 26896, new_expire = 0,
new_prot = 90 'Z', val_level = "\n\n\024\036(2<FPZ", val_flags1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_flags2 = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_flags3 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_flags4 = {0, 0, 0, 0, 0, 0,
0, 0, 0, 0}, val_exempt = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_rest = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
val_cdt = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_expire = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
---Type <return> to continue, or q <return> to quit---
level_expireto = '\0' <repeats 99 times>, level_timepercall = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 240, 51, 52, 53, 54, 55, 56, 57, 58, 59, 90, 120, 90, 63, 64, 65, 66, 67,
68, 69, 120, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 120, 120, 120, 120, 120,
120, 120, 120, 120, 480, 500}, level_timeperday = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 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, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 480, 51, 52, 53, 54, 55, 56, 57, 58, 59, 120, 120, 120, 63, 64, 65, 66, 67, 68, 69,
120, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 480, 240, 240, 240, 240, 240,
240, 240, 240, 500, 500}, level_callsperday = {0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
4 <repeats 29 times>, 50, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 10 <repeats 11 times>, 4,
4, 4, 4, 4, 4, 4, 4, 200, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500}, level_linespermsg = {
20 <repeats 11 times>, 40 <repeats 39 times>, 200, 50, 50, 50, 50, 50, 50, 50, 50, 50, 60 <repeats 11 times>,
70, 70, 70, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 90, 90, 90, 90, 90, 90, 90, 90,
90, 9999}, level_postsperday = {50 <repeats 50 times>, 20, 50 <repeats 48 times>, 500}, level_emailperday = {
50 <repeats 50 times>, 20, 50 <repeats 48 times>, 500}, level_freecdtperday = {0 <repeats 50 times>, 4194304,
0 <repeats 49 times>}, level_misc = {0 <repeats 100 times>}, expired_level = 0 '\0', expired_flags1 = 0,
expired_flags2 = 0, expired_flags3 = 0, expired_flags4 = 0, expired_exempt = 0, expired_rest = 0,
min_dspace = 4096, max_batup = 25, max_batdn = 100, max_userxfer = 5, max_minutes = 0, max_qwkmsgs = 10000,
preqwk_arstr = '\0' <repeats 40 times>, preqwk_ar = 0x2837ca04 "", cdt_min_value = 6, cdt_per_dollar = 2097152,
cdt_up_pct = 100, cdt_dn_pct = 90, node_dir = "/synchronet/sbbs/node1/", '\0' <repeats 40 times>,
ctrl_dir = "/synchronet/sbbs/ctrl/", '\0' <repeats 41 times>,
data_dir = "/synchronet/sbbs/data/", '\0' <repeats 41 times>,
text_dir = "/synchronet/sbbs/text/", '\0' <repeats 41 times>,
exec_dir = "/synchronet/sbbs/exec/", '\0' <repeats 41 times>,