Newer
Older
{"readln", js_recvline, 0, JSTYPE_ALIAS },
{"recvline", js_recvline, 0, JSTYPE_STRING, JSDOCSTR("[maxlen=<tt>512</tt>] [,timeout=<tt>30.0</tt>]")
,JSDOCSTR("receive a line-feed terminated string, default maxlen is 512 characters, default timeout is 30 seconds (AKA readline and readln)")
,310
{"recvfrom", js_recvfrom, 0, JSTYPE_OBJECT, JSDOCSTR("[binary=<tt>false</tt>] [,maxlen=<tt>512</tt> or int_size=<tt>4</tt>]")
,JSDOCSTR("receive data (string or integer) from a socket (typically UDP)"
"<p>returns object with <i>ip_address</i> and <i>port</i> of sender along with <i>data</i> properties"
"<p><i>binary</i> defaults to <i>false</i>, <i>maxlen</i> defaults to 512 chars, <i>int_size</i> defaults to 4 bytes (32-bits)")
,311
},
{"readBin", js_recvbin, 0, JSTYPE_ALIAS },
{"recvBin", js_recvbin, 0, JSTYPE_NUMBER, JSDOCSTR("[bytes=<tt>4</tt>]")
,JSDOCSTR("receive a binary integer from the socket, default number of bytes is 4 (32-bits)")
,311
},
{"getoption", js_getsockopt, 1, JSTYPE_NUMBER, JSDOCSTR("option")
,JSDOCSTR("get socket option value, option may be socket option name "
"(see <tt>sockopts</tt> in <tt>sockdefs.js</tt>) or number")
,310
},
{"setoption", js_setsockopt, 2, JSTYPE_BOOLEAN, JSDOCSTR("option, value")
,JSDOCSTR("set socket option value, option may be socket option name "
"(see <tt>sockopts</tt> in <tt>sockdefs.js</tt>) or number")
,310
},
{"ioctl", js_ioctlsocket, 1, JSTYPE_NUMBER, JSDOCSTR("command [,argument=<tt>0</tt>]")
,JSDOCSTR("send socket IOCTL (advanced)")
,310
},
{"poll", js_poll, 1, JSTYPE_NUMBER, JSDOCSTR("[timeout=<tt>0</tt>] [,write=<tt>false</tt>]")
,JSDOCSTR("poll socket for read or write ability (default is <i>read</i>), "
"default timeout value is 0.0 seconds (immediate timeout)")
,310
},
static JSBool js_socket_resolve(JSContext *cx, JSObject *obj, jsid id)
if(id != JSID_VOID && id != JSID_EMPTY) {
jsval idval;
JS_IdToValue(cx, id, &idval);
if(JSVAL_IS_STRING(idval)) {
JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(idval), name, NULL);
HANDLE_PENDING(cx, name);
ret=js_SyncResolve(cx, obj, name, js_socket_properties, js_socket_functions, NULL, 0);
if(name)
free(name);
return ret;
}
static JSBool js_socket_enumerate(JSContext *cx, JSObject *obj)
{
}
static JSClass js_socket_class = {
"Socket" /* name */
,JSCLASS_HAS_PRIVATE /* flags */
,JS_PropertyStub /* addProperty */
,JS_PropertyStub /* delProperty */
,js_socket_get /* getProperty */
,js_socket_set /* setProperty */
,js_socket_enumerate /* enumerate */
,js_socket_resolve /* resolve */
,JS_ConvertStub /* convert */
,js_finalize_socket /* finalize */
};
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
static BOOL js_DefineSocketOptionsArray(JSContext *cx, JSObject *obj, int type)
{
size_t i;
size_t count=0;
jsval val;
JSObject* array;
socket_option_t* options;
if((options=getSocketOptionList())==NULL)
return(FALSE);
if((array=JS_NewArrayObject(cx, 0, NULL))==NULL)
return(FALSE);
if(!JS_DefineProperty(cx, obj, "option_list", OBJECT_TO_JSVAL(array)
, NULL, NULL, JSPROP_ENUMERATE))
return(FALSE);
for(i=0; options[i].name!=NULL; i++) {
if(options[i].type && options[i].type!=type)
continue;
val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,options[i].name));
JS_SetElement(cx, array, count++, &val);
}
return(TRUE);
}
/* Socket Constructor (creates socket descriptor) */
JSObject* DLLCALL js_CreateSocketObjectWithoutParent(JSContext* cx, SOCKET sock, CRYPT_CONTEXT session)
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
{
JSObject* obj;
js_socket_private_t* p;
int type=SOCK_STREAM;
socklen_t len;
obj=JS_NewObject(cx, &js_socket_class, NULL, NULL);
if(obj==NULL)
return(NULL);
len = sizeof(type);
getsockopt(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->sock = sock;
p->external = TRUE;
p->network_byte_order = TRUE;
p->session=session;
if (p->sock != INVALID_SOCKET) {
len=sizeof(p->remote_addr);
if(getpeername(p->sock, &p->remote_addr.addr,&len)==0)
p->is_connected=TRUE;
}
if(!JS_SetPrivate(cx, obj, p)) {
dbprintf(TRUE, p, "JS_SetPrivate failed");
return(NULL);
}
dbprintf(FALSE, p, "object created");
return(obj);
}
static JSBool
js_socket_constructor(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
int32 type=SOCK_STREAM; /* default = TCP */
uintN i;
char* protocol=NULL;
for(i=0;i<argc;i++) {
if(JSVAL_IS_NUMBER(argv[i])) {
if (from_descriptor) {
#ifdef WIN32
JS_ValueToECMAUint32(cx,argv[i],&sock);
#else
JS_ValueToInt32(cx,argv[i],&sock);
#endif
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));
return JS_TRUE;
}
else
JS_ValueToInt32(cx,argv[i],&type);
}
else if(JSVAL_IS_BOOLEAN(argv[i]))
from_descriptor = TRUE;
else if(protocol==NULL) {
JSVALUE_TO_MSTRING(cx, argv[i], protocol, NULL);
HANDLE_PENDING(cx, protocol);
}
obj=JS_NewObject(cx, &js_socket_class, NULL, NULL);
JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));
if((p=(js_socket_private_t*)malloc(sizeof(js_socket_private_t)))==NULL) {
JS_ReportError(cx,"malloc failed");
return(JS_FALSE);
}
if((p->sock=open_socket(type,protocol))==INVALID_SOCKET) {
JS_ReportError(cx,"open_socket failed with error %d",ERROR_VALUE);
return(JS_FALSE);
}
p->type = type;
p->network_byte_order = TRUE;
if(!JS_SetPrivate(cx, obj, p)) {
JS_ReportError(cx,"JS_SetPrivate failed");
return(JS_FALSE);
}
if(!js_DefineSocketOptionsArray(cx, obj, type))
return(JS_FALSE);
#ifdef BUILD_JSDOCS
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>)</tt><br>"
"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 a 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"
js_CreateArrayOfStrings(cx, obj, "_property_desc_list", socket_prop_desc, JSPROP_READONLY);
#endif
dbprintf(FALSE, p, "object constructed");
return(JS_TRUE);
}
JSObject* DLLCALL js_CreateSocketClass(JSContext* cx, JSObject* parent)
{
JSObject* sockobj;
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 */
JSObject* DLLCALL js_CreateSocketObject(JSContext* cx, JSObject* parent, char *name, SOCKET sock, CRYPT_CONTEXT session)
JSObject* obj;
obj = js_CreateSocketObjectWithoutParent(cx, sock, session);
JS_DefineProperty(cx, parent, name, OBJECT_TO_JSVAL(obj), NULL, NULL, JSPROP_ENUMERATE|JSPROP_READONLY);
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
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;
if(!JS_SetPrivate(cx, obj, p)) {
dbprintf(TRUE, p, "JS_SetPrivate failed");
dbprintf(FALSE, p, "object created");