diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c index 9588390afd5541e1c016e639a8e8865d051cdd3b..399ca9f0bdecc48e4ea18579b90bb254623cbe04 100644 --- a/src/sbbs3/services.c +++ b/src/sbbs3/services.c @@ -301,8 +301,14 @@ js_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) static JSBool js_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { + char ch; char* buf; + int i; int32 len=512; + BOOL rd; + time_t start; + int32 timeout=30; /* seconds */ + JSString* str; service_client_t* client; if((client=(service_client_t*)JS_GetContextPrivate(cx))==NULL) @@ -310,15 +316,48 @@ js_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if(argc) JS_ValueToInt32(cx,argv[0],&len); - - if((buf=alloca(len))==NULL) - return(JS_TRUE); - len=recv(client->socket,buf,len,0); /* Need to switch to sockreadline */ + if((buf=(char*)alloca(len+1))==NULL) { + JS_ReportError(cx,"Error allocating %u bytes",len+1); + return(JS_FALSE); + } + + if(argc>1) + JS_ValueToInt32(cx,argv[1],(int32*)&timeout); - if(len>0) - *rval = STRING_TO_JSVAL(JS_NewStringCopyN(cx,buf,len)); + start=time(NULL); + for(i=0;i<len;) { + + if(!socket_check(client->socket,&rd,NULL,1000)) + break; /* disconnected */ + + if(!rd) { + if(time(NULL)-start>timeout) { + *rval = JSVAL_NULL; + return(JS_TRUE); /* time-out */ + } + continue; /* no data */ + } + + if(recv(client->socket, &ch, 1, 0)!=1) + break; + + if(ch=='\n' /* && i>=1 */) /* Mar-9-2003: terminate on sole LF */ + break; + + buf[i++]=ch; + } + if(i>0 && buf[i-1]=='\r') + buf[i-1]=0; + else + buf[i]=0; + + str = JS_NewStringCopyZ(cx, buf); + if(str==NULL) + return(JS_FALSE); + *rval = STRING_TO_JSVAL(str); + return(JS_TRUE); }