Skip to content
Snippets Groups Projects
js_socket.c 84.9 KiB
Newer Older
#endif

	dbprintf(FALSE, p, "object constructed");

	return(JS_TRUE);

fail:
	if (protocol)
		free(protocol);
	free(set);
js_socket_constructor(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj;
	jsval *argv=JS_ARGV(cx, arglist);
	int32	type=SOCK_STREAM;	/* default = TCP */
	int		domain = AF_INET; /* default = IPv4 */
deuce's avatar
deuce committed
	js_socket_private_t* p;
	BOOL	from_descriptor=FALSE;
	i = 0;
	if(JSVAL_IS_BOOLEAN(argv[i]) && argc > 1) {
		from_descriptor = JSVAL_TO_BOOLEAN(argv[i]);
		i++;
		if (from_descriptor) {
			uint32 sock;
			if(!JS_ValueToECMAUint32(cx,argv[i],&sock)) {
				JS_ReportError(cx, "Failed to convert socket descriptor to uint32");
				return JS_FALSE;
			obj = js_CreateSocketObjectWithoutParent(cx, sock, -1);
			if (obj == NULL) {
				JS_ReportError(cx, "Failed to create external socket object");
				return JS_FALSE;
			}
			JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));
			FREE_AND_NULL(protocol);
			return JS_TRUE;
	}

	for(;i<argc;i++) {
		if(JSVAL_IS_NUMBER(argv[i])) {
			JS_ValueToInt32(cx,argv[i],&type);
		}
		else if(JSVAL_IS_BOOLEAN(argv[i])) {
			if(argv[i] == JSVAL_TRUE)
				domain = AF_INET6;
		}
		else if(JSVAL_IS_STRING(argv[i])) {
			if(protocol == NULL) {
				JSVALUE_TO_MSTRING(cx, argv[i], protocol, NULL);
				HANDLE_PENDING(cx, protocol);
			}
deuce's avatar
deuce committed
		}

	obj=JS_NewObject(cx, &js_socket_class, NULL, NULL);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));

deuce's avatar
deuce committed
	if((p=(js_socket_private_t*)malloc(sizeof(js_socket_private_t)))==NULL) {
		JS_ReportError(cx,"malloc failed");
deuce's avatar
deuce committed
		if(protocol)
			free(protocol);
deuce's avatar
deuce committed
	memset(p,0,sizeof(js_socket_private_t));
	if((p->sock=open_socket(domain,type,protocol))==INVALID_SOCKET) {
		JS_ReportError(cx,"open_socket failed with error %d",ERROR_VALUE);
deuce's avatar
deuce committed
		if(protocol)
			free(protocol);
		free(p);
deuce's avatar
deuce committed
	if(protocol)
		free(protocol);
	p->network_byte_order = TRUE;
deuce's avatar
deuce committed
	p->session=-1;
deuce's avatar
deuce committed
	p->unflushed = 0;
		JS_ReportError(cx,"JS_SetPrivate failed");
		free(p);
	js_DescribeSyncObject(cx,obj,"Class used for TCP/IP socket communications",310);
	js_DescribeSyncConstructor(cx,obj,"To create a new Socket object: "
		"<tt>load('sockdefs.js'); var s = new Socket(<i>type</i>, <i>protocol</i> ,<i>ipv6</i>=false)</tt><br>"
rswindell's avatar
rswindell committed
		"where <i>type</i> = <tt>SOCK_STREAM</tt> for TCP (default) or <tt>SOCK_DGRAM</tt> for UDP<br>"
		"and <i>protocol</i> (optional) = the name of the protocol or service the socket is to be used for<br>"
		"To create a socket from an existing socket descriptor: "
		"<tt>var s = new Socket(true, <i>descriptor</i>)</tt><br>"
		"where <i>descriptor</i> is the numerical value of an existing valid socket descriptor"
rswindell's avatar
rswindell committed
		);
	js_CreateArrayOfStrings(cx, obj, "_property_desc_list", socket_prop_desc, JSPROP_READONLY);
#endif

	if(!js_DefineSocketOptionsArray(cx, obj, type))
		return(JS_FALSE);

	dbprintf(FALSE, p, "object constructed");
	return(JS_TRUE);
}

rswindell's avatar
rswindell committed
JSObject* DLLCALL js_CreateSocketClass(JSContext* cx, JSObject* parent)
{
	JSObject*	sockobj;
	JSObject*	sockproto;
	JSObject*	csockobj;
	JSObject*	lsockobj;
	jsval		val;
	JSObject*	constructor;
rswindell's avatar
rswindell committed

	sockobj = JS_InitClass(cx, parent, NULL
		,&js_socket_class
		,js_socket_constructor
		,0	/* number of constructor args */
		,NULL /* props, specified in constructor */
		,NULL /* funcs, specified in constructor */
rswindell's avatar
rswindell committed
		,NULL,NULL);
	if (sockobj == NULL)
		return sockobj;
	if(JS_GetProperty(cx, parent, js_socket_class.name, &val) && !JSVAL_NULL_OR_VOID(val)) {
		JS_ValueToObject(cx,val,&constructor);
		JS_DefineProperty(cx, constructor, "PF_INET", INT_TO_JSVAL(PF_INET), NULL, NULL
			, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
		JS_DefineProperty(cx, constructor, "PF_INET6", INT_TO_JSVAL(PF_INET6), NULL, NULL
			, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
		JS_DefineProperty(cx, constructor, "AF_INET", INT_TO_JSVAL(AF_INET), NULL, NULL
			, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
		JS_DefineProperty(cx, constructor, "AF_INET6", INT_TO_JSVAL(AF_INET6), NULL, NULL
			, JSPROP_PERMANENT|JSPROP_ENUMERATE|JSPROP_READONLY);
	}
	sockproto = JS_GetPrototype(cx, sockobj);
	csockobj = JS_InitClass(cx, parent, sockproto
		,&js_connected_socket_class
		,js_connected_socket_constructor
		,2	/* number of constructor args */
		,NULL /* props, specified in constructor */
		,NULL /* funcs, specified in constructor */
		,NULL,NULL);
	lsockobj = JS_InitClass(cx, parent, sockproto
		,&js_listening_socket_class
		,js_listening_socket_constructor
		,2	/* number of constructor args */
		,NULL /* props, specified in constructor */
		,NULL /* funcs, specified in constructor */
		,NULL,NULL);
rswindell's avatar
rswindell committed

	return(sockobj);
}

JSObject* DLLCALL js_CreateSocketObject(JSContext* cx, JSObject* parent, char *name, SOCKET sock, CRYPT_CONTEXT session)
	obj = js_CreateSocketObjectWithoutParent(cx, sock, session);
rswindell's avatar
rswindell committed
	if(obj==NULL)
		return(NULL);
	JS_DefineProperty(cx, parent, name, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
deuce's avatar
deuce committed

	return(obj);
}

JSObject* DLLCALL js_CreateSocketObjectFromSet(JSContext* cx, JSObject* parent, char *name, struct xpms_set *set)
{
	JSObject*	obj;
	js_socket_private_t*	p;
	int			type=SOCK_STREAM;
	socklen_t	len;

	obj = JS_DefineObject(cx, parent, name, &js_socket_class, NULL
		,JSPROP_ENUMERATE|JSPROP_READONLY);

	if(obj==NULL)
		return(NULL);

	if(set->sock_count < 1)
		return NULL;

	len = sizeof(type);
	getsockopt(set->socks[0].sock,SOL_SOCKET,SO_TYPE,(void*)&type,&len);

	if(!js_DefineSocketOptionsArray(cx, obj, type))
		return(NULL);

	if((p=(js_socket_private_t*)malloc(sizeof(js_socket_private_t)))==NULL)
		return(NULL);
	memset(p,0,sizeof(js_socket_private_t));

	p->set = set;
	p->sock = INVALID_SOCKET;
	p->external = TRUE;
	p->network_byte_order = TRUE;
	p->session=-1;
deuce's avatar
deuce committed
	p->unflushed = 0;
	if(!JS_SetPrivate(cx, obj, p)) {
		dbprintf(TRUE, p, "JS_SetPrivate failed");
rswindell's avatar
rswindell committed
		return(NULL);
	}

	dbprintf(FALSE, p, "object created");
#endif	/* JAVSCRIPT */