Skip to content
Snippets Groups Projects
js_msgbase.c 104 KiB
Newer Older
				JS_DefineProperty(cx, hdrobj, "tally", OBJECT_TO_JSVAL(array)
					,NULL, NULL, JSPROP_ENUMERATE);
				for(int i=0; i < MSG_POLL_MAX_ANSWERS;i++)
					JS_DefineElement(cx, array, i, UINT_TO_JSVAL(post[off].votes[i])
						,NULL, NULL, JSPROP_ENUMERATE);
			}
		}
		if(!JS_SetPrivate(cx, hdrobj, p)) {
			JS_ReportError(cx,"JS_SetPrivate failed");
			smb_unlocksmbhdr(&(priv->smb));
		}

		val=OBJECT_TO_JSVAL(hdrobj);
		sprintf(numstr,"%"PRIu32, p->msg.hdr.number);
		JS_SetProperty(cx, retobj, numstr, &val);
	}
	smb_unlocksmbhdr(&(priv->smb));
static JSBool
js_dump_msg_header(JSContext *cx, uintN argc, jsval *arglist)
{
	jsval *argv=JS_ARGV(cx, arglist);
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);

	if(argc >= 1 && JSVAL_IS_OBJECT(argv[0])) {
		JSObject* hdr = JSVAL_TO_OBJECT(argv[0]);
		if(hdr == NULL)		/* no header supplied? */
			return JS_TRUE;
		privatemsg_t* mp = (privatemsg_t*)JS_GetPrivate(cx, hdr);
		if(mp == NULL)
			return JS_TRUE;
		str_list_t list = smb_msghdr_str_list(&mp->msg);
		if(list != NULL) {
			JSObject* array;
			if((array = JS_NewArrayObject(cx, 0, NULL)) == NULL) {
				JS_ReportError(cx, "JS_NewArrayObject failure");
				return JS_FALSE;
			}
			JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
			for(int i = 0; list[i] != NULL; i++) {
				JSString* js_str = JS_NewStringCopyZ(cx, list[i]);
				if(js_str == NULL)
					break;
				JS_DefineElement(cx, array, i, STRING_TO_JSVAL(js_str), NULL, NULL, JSPROP_ENUMERATE);
			}
			strListFree(&list);
		}
	}
	return JS_TRUE;
}

static JSBool
js_put_msg_header(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	smbmsg_t	msg;
	private_t*	p;
deuce's avatar
deuce committed
	jsrefcount	rc;
	char*		cstr;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {

	if(!SMB_IS_OPEN(&(p->smb)))

	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 */
				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;
			}
		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
deuce's avatar
deuce committed
			JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(argv[n]), cstr, NULL);
			HANDLE_PENDING(cx, cstr);
deuce's avatar
deuce committed
					,cstr
					,&msg.offset)) {
deuce's avatar
deuce committed
				free(cstr);
				return JS_TRUE;	/* ID not found */
deuce's avatar
deuce committed
			free(cstr);
rswindell's avatar
rswindell committed
		}
		else if(JSVAL_IS_OBJECT(argv[n])) {
rswindell's avatar
rswindell committed
	if(hdr == NULL)		/* no header supplied? */
	privatemsg_t* mp;
	mp=(privatemsg_t*)JS_GetPrivate(cx,hdr);
rswindell's avatar
rswindell committed
	if(mp != NULL) {
		if(mp->expand_fields) {
			JS_ReportError(cx, "Message header has 'expanded fields'");
rswindell's avatar
rswindell committed
			return JS_FALSE;
		}
	if((p->smb_result=smb_getmsgidx(&(p->smb), &msg))!=SMB_SUCCESS) {
	if((p->smb_result=smb_lockmsghdr(&(p->smb), &msg))!=SMB_SUCCESS) {
		if((p->smb_result=smb_getmsghdr(&(p->smb), &msg))!=SMB_SUCCESS)
		smb_freemsghdrmem(&msg);	/* prevent duplicate header fields */
		if(!parse_header_object(cx, p, hdr, &msg, TRUE)) {
rswindell's avatar
rswindell committed
			SAFECOPY(p->smb.last_error,"Header parsing failure (required field missing?)");
		if((p->smb_result=smb_putmsg(&(p->smb), &msg))!=SMB_SUCCESS)
		if(mp != NULL) {
			smb_freemsgmem(&mp->msg);
			smb_copymsgmem(&(p->smb), &mp->msg, &msg);
		}

		JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
	smb_unlockmsghdr(&(p->smb), &msg); 
rswindell's avatar
rswindell committed
	smb_freemsgmem(&msg);
rswindell's avatar
rswindell committed
static JSBool
js_remove_msg(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
rswindell's avatar
rswindell committed
	uintN		n;
	JSBool		by_offset=JS_FALSE;
	JSBool		msg_specified=JS_FALSE;
	smbmsg_t	msg;
	private_t*	p;
	char*		cstr = NULL;
deuce's avatar
deuce committed
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
rswindell's avatar
rswindell committed
	}

	if(!SMB_IS_OPEN(&(p->smb)))
rswindell's avatar
rswindell committed

	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 */
				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;
			}
rswindell's avatar
rswindell committed
			msg_specified=JS_TRUE;
			n++;
			break;
		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
deuce's avatar
deuce committed
			JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(argv[n]), cstr, NULL);
			HANDLE_PENDING(cx, cstr);
			if(cstr == NULL)
				return JS_FALSE;
deuce's avatar
deuce committed
					,cstr
					,&msg.offset)) {
				free(cstr);
				return JS_TRUE;	/* ID not found */
			free(cstr);
rswindell's avatar
rswindell committed
			msg_specified=JS_TRUE;
			n++;
			break;
		}
	}

	if((p->smb_result=smb_getmsgidx(&(p->smb), &msg))==SMB_SUCCESS
		&& (p->smb_result=smb_getmsghdr(&(p->smb), &msg))==SMB_SUCCESS) {
rswindell's avatar
rswindell committed

		msg.hdr.attr|=MSG_DELETE;

		if((p->smb_result=smb_updatemsg(&(p->smb), &msg))==SMB_SUCCESS)
			JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
rswindell's avatar
rswindell committed

	smb_freemsgmem(&msg);
static char* get_msg_text(private_t* p, smbmsg_t* msg, BOOL strip_ctrl_a, BOOL dot_stuffing, ulong mode, JSBool existing)
		if((p->smb_result=smb_lockmsghdr(&(p->smb),msg))!=SMB_SUCCESS)
		if((p->smb_result=smb_getmsgidx(&(p->smb), msg))!=SMB_SUCCESS)
		if((p->smb_result=smb_lockmsghdr(&(p->smb),msg))!=SMB_SUCCESS)
		if((p->smb_result=smb_getmsghdr(&(p->smb), msg))!=SMB_SUCCESS) {
			smb_unlockmsghdr(&(p->smb), msg);
	if((buf=smb_getmsgtxt(&(p->smb), msg, mode))==NULL) {
		if(!existing)
			smb_freemsgmem(msg);
	smb_unlockmsghdr(&(p->smb), msg);
	if(!existing)
		smb_freemsgmem(msg);
	if(strip_ctrl_a)
		remove_ctrl_a(buf, buf);
	if(dot_stuffing) {	/* must escape lines starting with dot ('.'), e.g. RFC821 */
		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++]='.';
js_get_msg_body(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	JSBool		strip_ctrl_a=JS_FALSE;
	JSBool		dot_stuffing=JS_FALSE;
	JSBool		msg_specified=JS_FALSE;
	JSBool		existing_msg=JS_FALSE;
	JSString*	js_str;
deuce's avatar
deuce committed
	char*		cstr;
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
	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 */
				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;
			}
			break;
		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
deuce's avatar
deuce committed
			JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(argv[n]), cstr, NULL);
			HANDLE_PENDING(cx, cstr);
deuce's avatar
deuce committed
					,cstr
					,&msg.offset)) {
deuce's avatar
deuce committed
				free(cstr);
				return JS_TRUE;	/* ID not found */
deuce's avatar
deuce committed
			free(cstr);
		} else if(JSVAL_IS_OBJECT(argv[n])) {		/* Use existing header */
			JSClass *oc=JS_GetClass(cx, JSVAL_TO_OBJECT(argv[n]));
			if(oc != NULL && strcmp(oc->name, js_msghdr_class.name) == 0) {
				privatemsg_t	*pmsg=JS_GetPrivate(cx,JSVAL_TO_OBJECT(argv[n]));

				if(pmsg != NULL) {
					msg_specified=JS_TRUE;
					existing_msg=JS_TRUE;
					msgptr=&pmsg->msg;
				}
			}
			n++;
			break;
	if(!msg_specified)	/* No message number or id specified */
	if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
		strip_ctrl_a=JSVAL_TO_BOOLEAN(argv[n++]);
	if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
		dot_stuffing=JSVAL_TO_BOOLEAN(argv[n++]);
	if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
		tails=JSVAL_TO_BOOLEAN(argv[n++]);
	if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
		plain=JSVAL_TO_BOOLEAN(argv[n++]);

	if(tails)
		getmsgtxtmode |= GETMSGTXT_TAILS;

	if(plain)
		getmsgtxtmode |= GETMSGTXT_PLAIN;

	buf = get_msg_text(p, msgptr, strip_ctrl_a, dot_stuffing, getmsgtxtmode, existing_msg);
	if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
		JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
js_get_msg_tail(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	JSBool		dot_stuffing=JS_FALSE;
	JSBool		msg_specified=JS_FALSE;
	JSBool		existing_msg=JS_FALSE;
	JSString*	js_str;
deuce's avatar
deuce committed
	char*		cstr;
	jsrefcount	rc;
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
	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 */
				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;
			}
			break;
		} else if(JSVAL_IS_STRING(argv[n]))	{		/* Get by ID */
deuce's avatar
deuce committed
			JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(argv[n]), cstr, NULL);
			HANDLE_PENDING(cx, cstr);
deuce's avatar
deuce committed
					,cstr
					,&msg.offset)) {
deuce's avatar
deuce committed
				free(cstr);
				return JS_TRUE;	/* ID not found */
deuce's avatar
deuce committed
			free(cstr);
		} else if(JSVAL_IS_OBJECT(argv[n])) {		/* Use existing header */
			JSClass *oc=JS_GetClass(cx, JSVAL_TO_OBJECT(argv[n]));
			if(oc != NULL && strcmp(oc->name, js_msghdr_class.name) == 0) {
				privatemsg_t	*pmsg=JS_GetPrivate(cx,JSVAL_TO_OBJECT(argv[n]));

				if(pmsg != NULL) {
					msg_specified=JS_TRUE;
					existing_msg=JS_TRUE;
					msgptr=&pmsg->msg;
				}
			}
			n++;
			break;
	if(!msg_specified)	/* No message number or id specified */
	if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
		strip_ctrl_a=JSVAL_TO_BOOLEAN(argv[n++]);
	if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
		dot_stuffing=JSVAL_TO_BOOLEAN(argv[n++]);
	buf = get_msg_text(p, msgptr, strip_ctrl_a, dot_stuffing, GETMSGTXT_TAILS|GETMSGTXT_NO_BODY, existing_msg);
	if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
		JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
rswindell's avatar
rswindell committed
static JSBool
js_save_msg(JSContext *cx, uintN argc, jsval *arglist)
rswindell's avatar
rswindell committed
{
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
	JSObject*	objarg;
	JSObject*	rcpt_list=NULL;
rswindell's avatar
rswindell committed
	smbmsg_t	msg;
rswindell's avatar
rswindell committed
	private_t*	p;
deuce's avatar
deuce committed
	jsrefcount	rc;
	scfg_t*			scfg;

	scfg=JS_GetRuntimePrivate(JS_GetRuntime(cx));
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
rswindell's avatar
rswindell committed

	if(argc<2)
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
deuce's avatar
deuce committed
		if(!js_open(cx, 0, arglist))
deuce's avatar
deuce committed
		if(JS_RVAL(cx, arglist) == JSVAL_FALSE)
rswindell's avatar
rswindell committed
	memset(&msg,0,sizeof(msg));

		if(JSVAL_IS_OBJECT(argv[n]) && !JSVAL_IS_NULL(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) {
deuce's avatar
deuce committed
		if(body==NULL) {
deuce's avatar
deuce committed
			JSVALUE_TO_MSTRING(cx, argv[n], body, NULL);
			HANDLE_PENDING(cx, body);
deuce's avatar
deuce committed
			if(body==NULL) {
				JS_ReportError(cx,"Invalid message body string");
	// Find and use the global client object if possible...
	if(client==NULL) {
		if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "client", &val) && !JSVAL_NULL_OR_VOID(val)) {
			objarg = JSVAL_TO_OBJECT(val);
			if((cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0)
				client=JS_GetPrivate(cx,objarg);
		}
	}

deuce's avatar
deuce committed
		body=strdup("");
		if(!JS_GetArrayLength(cx, rcpt_list, &rcpt_list_length) || !rcpt_list_length) {
			free(body);
	if(parse_header_object(cx, p, hdr, &msg, rcpt_list==NULL)) {

deuce's avatar
deuce committed
		rc=JS_SUSPENDREQUEST(cx);
		if((p->smb_result=savemsg(scfg, &(p->smb), &msg, client, /* ToDo server hostname: */NULL, body, /* remsg: */NULL))==SMB_SUCCESS) {
deuce's avatar
deuce committed
			JS_RESUMEREQUEST(cx, rc);
			JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
rswindell's avatar
rswindell committed
			if(rcpt_list!=NULL) {	/* Sending to a list of recipients */
				JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
rswindell's avatar
rswindell committed
				SAFECOPY(p->smb.last_error,"Recipient list parsing failure");
rswindell's avatar
rswindell committed
				memset(&rcpt_msg, 0, sizeof(rcpt_msg));
rswindell's avatar
rswindell committed
				for(i=0;i<rcpt_list_length;i++) {
rswindell's avatar
rswindell committed
					if(!JS_GetElement(cx, rcpt_list, i, &val))
						break;
rswindell's avatar
rswindell committed
					if(!JSVAL_IS_OBJECT(val))
						break;
deuce's avatar
deuce committed
					rc=JS_SUSPENDREQUEST(cx);
					if((p->smb_result=smb_copymsgmem(&(p->smb), &rcpt_msg, &msg))!=SMB_SUCCESS) {
deuce's avatar
deuce committed
						JS_RESUMEREQUEST(cx, rc);
rswindell's avatar
rswindell committed
						break;
deuce's avatar
deuce committed
					}
					JS_RESUMEREQUEST(cx, rc);
rswindell's avatar
rswindell committed
					if(!parse_recipient_object(cx, p, JSVAL_TO_OBJECT(val), &rcpt_msg))
						break;
deuce's avatar
deuce committed
					rc=JS_SUSPENDREQUEST(cx);
					if((p->smb_result=smb_addmsghdr(&(p->smb), &rcpt_msg, smb_storage_mode(scfg, &(p->smb))))!=SMB_SUCCESS) {
deuce's avatar
deuce committed
						JS_RESUMEREQUEST(cx, rc);
rswindell's avatar
rswindell committed
						break;
deuce's avatar
deuce committed
					}
rswindell's avatar
rswindell committed
					smb_freemsgmem(&rcpt_msg);
deuce's avatar
deuce committed
					JS_RESUMEREQUEST(cx, rc);
rswindell's avatar
rswindell committed
				}
				smb_freemsgmem(&rcpt_msg);	/* just in case we broke the loop */
rswindell's avatar
rswindell committed
				if(i==rcpt_list_length)
					JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
				if(i > 1)
					smb_incmsg_dfields(&(p->smb), &msg, (uint16_t)(i - 1));
rswindell's avatar
rswindell committed
			}
deuce's avatar
deuce committed
		else
			JS_RESUMEREQUEST(cx, rc);
rswindell's avatar
rswindell committed
		SAFECOPY(p->smb.last_error,"Header parsing failure (required field missing?)");
deuce's avatar
deuce committed
	free(body);
static JSBool
js_vote_msg(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject*	obj=JS_THIS_OBJECT(cx, arglist);
	jsval*		argv=JS_ARGV(cx, arglist);
	uintN		n;
	JSObject*	hdr=NULL;
	JSObject*	objarg;
	smbmsg_t	msg;
	private_t*	p;
	JSBool		ret=JS_TRUE;
	jsrefcount	rc;
	scfg_t*		scfg;

rswindell's avatar
rswindell committed
	scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));
rswindell's avatar
rswindell committed
	if(argc < 1)
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class)) == NULL) {
		return JS_FALSE;
	}

	if(!SMB_IS_OPEN(&(p->smb))) {
		if(!js_open(cx, 0, arglist))
			return JS_FALSE;
		if(JS_RVAL(cx, arglist) == JSVAL_FALSE)
			return JS_TRUE;
	}

rswindell's avatar
rswindell committed
	memset(&msg, 0, sizeof(msg));
	msg.hdr.type = SMB_MSG_TYPE_BALLOT;
rswindell's avatar
rswindell committed
	for(n=0; n<argc; n++) {
		if(JSVAL_IS_OBJECT(argv[n]) && !JSVAL_IS_NULL(argv[n])) {
			objarg = JSVAL_TO_OBJECT(argv[n]);
rswindell's avatar
rswindell committed
			if(hdr == NULL) {
rswindell's avatar
rswindell committed
	if(hdr == NULL)
		return JS_TRUE;

	if(parse_header_object(cx, p, hdr, &msg, FALSE)) {

		rc = JS_SUSPENDREQUEST(cx);
		if((p->smb_result=votemsg(scfg, &(p->smb), &msg, NULL, NULL)) == SMB_SUCCESS) {
rswindell's avatar
rswindell committed
			JS_RESUMEREQUEST(cx, rc);
			JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
		}
		else
			JS_RESUMEREQUEST(cx, rc);
	} else {
		ret = JS_FALSE;
		SAFECOPY(p->smb.last_error,"Header parsing failure (required field missing?)");
	}

	smb_freemsgmem(&msg);

	return ret;
}

static JSBool
js_add_poll(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject*	obj=JS_THIS_OBJECT(cx, arglist);
	jsval*		argv=JS_ARGV(cx, arglist);
	uintN		n;
	JSObject*	hdr=NULL;
	JSObject*	objarg;
	smbmsg_t	msg;
	private_t*	p;
	JSBool		ret=JS_TRUE;
	jsrefcount	rc;
	scfg_t*		scfg;

	scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));

	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);

	if(argc < 1)
		return JS_TRUE;
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class)) == NULL) {
rswindell's avatar
rswindell committed
		return JS_FALSE;
	}

	if(!SMB_IS_OPEN(&(p->smb))) {
		if(!js_open(cx, 0, arglist))
			return JS_FALSE;
		if(JS_RVAL(cx, arglist) == JSVAL_FALSE)
			return JS_TRUE;
	}

	memset(&msg, 0, sizeof(msg));
	msg.hdr.type = SMB_MSG_TYPE_POLL;

	for(n=0; n<argc; n++) {
		if(JSVAL_IS_OBJECT(argv[n]) && !JSVAL_IS_NULL(argv[n])) {
			objarg = JSVAL_TO_OBJECT(argv[n]);
			if(hdr == NULL) {
				hdr = objarg;
				continue;
			}
		}
	}

	if(hdr == NULL)
		return JS_TRUE;

	if(parse_header_object(cx, p, hdr, &msg, FALSE)) {

		rc=JS_SUSPENDREQUEST(cx);
		if((p->smb_result=postpoll(scfg, &(p->smb), &msg)) == SMB_SUCCESS) {
			JS_RESUMEREQUEST(cx, rc);
			JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
		}
		else
			JS_RESUMEREQUEST(cx, rc);
	} else {
rswindell's avatar
rswindell committed
		ret = JS_FALSE;
		SAFECOPY(p->smb.last_error,"Header parsing failure (required field missing?)");
	}

	smb_freemsgmem(&msg);

rswindell's avatar
rswindell committed
	return ret;
js_how_user_voted(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject*	obj=JS_THIS_OBJECT(cx, arglist);
	jsval*		argv=JS_ARGV(cx, arglist);
	int32		msgnum;
	private_t*	p;
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
		return JS_FALSE;
	}

	if(!SMB_IS_OPEN(&(p->smb)))
		return JS_TRUE;

	if(!JS_ValueToInt32(cx, argv[0], &msgnum))
		return JS_FALSE;

	JSVALUE_TO_MSTRING(cx, argv[1], name, NULL)
	HANDLE_PENDING(cx, name);
	votes = smb_voted_already(&(p->smb), msgnum, name, NET_NONE, NULL);
	free(name);

	JS_SET_RVAL(cx, arglist,UINT_TO_JSVAL(votes));

	return JS_TRUE;
}

static JSBool
js_close_poll(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject*	obj=JS_THIS_OBJECT(cx, arglist);
	jsval*		argv=JS_ARGV(cx, arglist);
	int32		msgnum;
	private_t*	p;
	int			result;
	jsrefcount	rc;
	scfg_t*		scfg;

	scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx));

	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
		return JS_FALSE;
	}

	if(!SMB_IS_OPEN(&(p->smb)))
		return JS_TRUE;

	if(!JS_ValueToInt32(cx, argv[0], &msgnum))
		return JS_FALSE;

	JSVALUE_TO_MSTRING(cx, argv[1], name, NULL)
	HANDLE_PENDING(cx, name);
	if(name==NULL)
		return JS_TRUE;

	rc=JS_SUSPENDREQUEST(cx);
	result = closepoll(scfg, &(p->smb), msgnum, name);
	free(name);
	JS_RESUMEREQUEST(cx, rc);

	JS_SET_RVAL(cx, arglist, result == SMB_SUCCESS ? JSVAL_TRUE : JSVAL_FALSE);

	return JS_TRUE;
}

/* MsgBase Object Properties */
	,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_STATUS		/* Last SMBLIB returned status value (e.g. retval) */
static JSBool js_msgbase_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
	if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_msgbase_class))==NULL) {
    JS_IdToValue(cx, id, &idval);
    tiny = JSVAL_TO_INT(idval);

	switch(tiny) {
		case SMB_PROP_RETRY_TIME:
			if(!JS_ValueToInt32(cx,*vp,(int32*)&(p->smb).retry_time))
				return JS_FALSE;
			if(!JS_ValueToInt32(cx,*vp,(int32*)&(p->smb).retry_delay))
				return JS_FALSE;
			break;
		case SMB_PROP_DEBUG:
			JS_ValueToBoolean(cx,*vp,&p->debug);
static JSBool js_msgbase_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
	char*		s=NULL;
	JSString*	js_str;
rswindell's avatar
rswindell committed
	idxrec_t	idx;
deuce's avatar
deuce committed
	jsrefcount	rc;
	if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
    JS_IdToValue(cx, id, &idval);
    tiny = JSVAL_TO_INT(idval);

	switch(tiny) {
		case SMB_PROP_FILE:
			s=p->smb.file;
			break;
		case SMB_PROP_LAST_ERROR:
			s=p->smb.last_error;
			*vp = INT_TO_JSVAL(p->smb_result);
		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;
rswindell's avatar
rswindell committed
		case SMB_PROP_FIRST_MSG:
rswindell's avatar
rswindell committed
			memset(&idx,0,sizeof(idx));
			smb_getfirstidx(&(p->smb),&idx);
			*vp=UINT_TO_JSVAL(idx.number);
rswindell's avatar
rswindell committed
			break;
		case SMB_PROP_LAST_MSG:
			smb_getstatus(&(p->smb));
			*vp=UINT_TO_JSVAL(p->smb.status.last_msg);
			break;
		case SMB_PROP_TOTAL_MSGS:
			smb_getstatus(&(p->smb));
			*vp=UINT_TO_JSVAL(p->smb.status.total_msgs);
			break;
		case SMB_PROP_MAX_CRCS:
			*vp=UINT_TO_JSVAL(p->smb.status.max_crcs);
			break;
		case SMB_PROP_MAX_MSGS:
			*vp=UINT_TO_JSVAL(p->smb.status.max_msgs);