Newer
Older
return(JS_TRUE);
}
static JSBool
js_save_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
char* body=NULL;
uintN n;
JSObject* hdr=NULL;
jsval open_rval;
private_t* p;
*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
if(argc<2)
return(JS_TRUE);
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]))
hdr = JSVAL_TO_OBJECT(argv[n]);
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(!parse_header_object(cx, p, hdr, &msg))
if(msg.hdr.when_written.time==0) {
msg.hdr.when_written.time=time(NULL);
msg.hdr.when_written.zone=scfg->sys_timezone;
}
truncsp(body);
if(savemsg(scfg, &(p->smb), &msg, body)==0)
*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
return(JS_TRUE);
}
/* MsgBase Object Properites */
enum {
SMB_PROP_LAST_ERROR
,SMB_PROP_FILE
,SMB_PROP_DEBUG
,SMB_PROP_RETRY_TIME
,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:
p->smb.retry_time = JSVAL_TO_BOOLEAN(*vp);
break;
case SMB_PROP_DEBUG:
p->debug = JSVAL_TO_BOOLEAN(*vp);
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_DEBUG:
*vp = INT_TO_JSVAL(p->debug);
break;
case SMB_PROP_FIRST_MSG:
memset(&idx,0,sizeof(idx));
smb_getfirstidx(&(p->smb),&idx);
*vp = INT_TO_JSVAL(idx.number);
break;
case SMB_PROP_LAST_MSG:
smb_getstatus(&(p->smb));
*vp = INT_TO_JSVAL(p->smb.status.last_msg);
break;
case SMB_PROP_TOTAL_MSGS:
smb_getstatus(&(p->smb));
*vp = INT_TO_JSVAL(p->smb.status.total_msgs);
break;
case SMB_PROP_MAX_CRCS:
*vp = INT_TO_JSVAL(p->smb.status.max_crcs);
break;
case SMB_PROP_MAX_MSGS:
*vp = INT_TO_JSVAL(p->smb.status.max_msgs);
break;
case SMB_PROP_MAX_AGE:
*vp = INT_TO_JSVAL(p->smb.status.max_age);
break;
case SMB_PROP_ATTR:
*vp = INT_TO_JSVAL(p->smb.status.attr);
break;
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 struct JSPropertySpec js_msgbase_properties[] = {
/* name ,tinyid ,flags, getter, setter */
{ "last_error" ,SMB_PROP_LAST_ERROR ,SMB_PROP_FLAGS, NULL,NULL},
{ "file" ,SMB_PROP_FILE ,SMB_PROP_FLAGS, NULL,NULL},
{ "debug" ,SMB_PROP_DEBUG ,0, NULL,NULL},
{ "retry_time" ,SMB_PROP_RETRY_TIME ,JSPROP_ENUMERATE, NULL,NULL},
{ "first_msg" ,SMB_PROP_FIRST_MSG ,SMB_PROP_FLAGS, NULL,NULL},
{ "last_msg" ,SMB_PROP_LAST_MSG ,SMB_PROP_FLAGS, NULL,NULL},
{ "total_msgs" ,SMB_PROP_TOTAL_MSGS ,SMB_PROP_FLAGS, NULL,NULL},
{ "max_crcs" ,SMB_PROP_MAX_CRCS ,SMB_PROP_FLAGS, NULL,NULL},
{ "max_msgs" ,SMB_PROP_MAX_MSGS ,SMB_PROP_FLAGS, NULL,NULL},
{ "max_age" ,SMB_PROP_MAX_AGE ,SMB_PROP_FLAGS, NULL,NULL},
{ "attributes" ,SMB_PROP_ATTR ,SMB_PROP_FLAGS, NULL,NULL},
{ "subnum" ,SMB_PROP_SUBNUM ,SMB_PROP_FLAGS, NULL,NULL},
{ "is_open" ,SMB_PROP_IS_OPEN ,SMB_PROP_FLAGS, NULL,NULL},
#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)"
,"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 jsMethodSpec js_msgbase_functions[] = {
{"open", js_open, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("open message base")
},
{"close", js_close, 0, JSTYPE_BOOLEAN, JSDOCSTR("")
,JSDOCSTR("close message base (if open)")
},
{"get_msg_header", js_get_msg_header, 2, JSTYPE_OBJECT, JSDOCSTR("boolean by_offset, number")
,JSDOCSTR("returns a specific message header, <i>null</i> on failure")
},
{"put_msg_header", js_put_msg_header, 2, JSTYPE_BOOLEAN, JSDOCSTR("boolean by_offset, number, object header")
,JSDOCSTR("write a message header")
},
{"get_msg_body", js_get_msg_body, 2, JSTYPE_STRING, JSDOCSTR("boolean by_offset, number [,boolean strip_ctrl_a]")
,JSDOCSTR("returns the body text of a specific message, <i>null</i> on failure")
},
{"get_msg_tail", js_get_msg_tail, 2, JSTYPE_STRING, JSDOCSTR("boolean by_offset, number [,boolean strip_ctrl_a]")
,JSDOCSTR("returns the tail text of a specific message, <i>null</i> on failure")
},
{"save_msg", js_save_msg, 2, JSTYPE_BOOLEAN, JSDOCSTR("object header, string body_text")
,JSDOCSTR("create a new message in message base")
},
/* 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);
}
JS_DefineProperties(cx,obj,js_msgbase_properties);
#ifdef _DEBUG
js_DescribeObject(cx,obj,"Class used for accessing message bases");
js_DescribeConstructor(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))
break;
}
if(p->smb.subnum<scfg->total_subs) {
cfgobj=JS_NewObject(cx,NULL,NULL,obj);
js_CreateMsgAreaProperties(cx, cfgobj, scfg->sub[p->smb.subnum]);
#ifdef _DEBUG
js_DescribeObject(cx,cfgobj
,"Configuration parameters for this message area (<i>sub-boards only</i>) "
"- <small>READ ONLY</small>");
#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_DefineMethods(cx, obj, js_msgbase_functions)) {
JS_ReportError(cx,"js_DefineMethods 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);
}