#include<net.h>
-int net_wait(int sock, struct peer *info, void *p, size_t size) {
- return -1;
- /*if(-1==i) {
+static int cache(struct peer*,void*,size_t);
+static void* use_cached(struct peer*,void*,size_t*);
+
+static int cache(struct peer *info, void *p, size_t size) {
+ void *next;
+ size_t i;
+
+ next_size = (info->in!=NULL) ? size + info->in_size : size;
+ next = malloc(next_size);
+ if(NULL==next) { return -1; }
+
+ memcpy(next,p,size);
+ if(info->in!=NULL) {
+ memcpy(&(next[size]),info->in,info->in_size);
+ free(info->in);
+ }
+
+ info->in = next;
+ info->in_size = next_size;
+
+ return 1;
+}
+
+int net_wait(int sock, struct peer *info, void *buf, size_t buf_size) {
+ void *p;
+ size_t size;
+ ssize_t i;
+
+ size = buf_size;
+ p = use_cached(info,buf,&size);
+
+ i = recv(sock,p,size,0);
+ if(-1==i) {
if(!((errno==EAGAIN)||(errno==EWOULDBLOCK))) {
perror("recv");
return -1;
- }*/
+ }
+ }
+
+ if((i!=size)&&(size>0)) { goto cached; }
+
+ return 1;
+cached:
+ cache(info,p,i+(buf_size - size));
+ return 0;
+}
+
+static void *use_cached(struct peer *info,void *p,size_t *size) {
+ if(info->in!=NULL) {
+ if(info->in_size>(*size)) {
+ /* some cached left over */
+ memcpy(p,info->in,*size);
+ p += (*size);
+
+ info->in_size -= *size;
+ memmove(info->in,&(info[*size]),info->in_size);
+ *size = 0;
+ } else {
+ /* use up all cached data */
+ memcpy(p,info->in,info->in_size);
+ free(info->in);
+ info->in = NULL;
+
+ *size -= info->in_size;
+ p += info->in_size;
+ }
+ }
+
+ return p;
}