#define _GNU_SOURCE #include #include #include #include #include #include #include #include "global.h" #include "memory.h" #include "tcp.h" #if 0 #define BUFFER_LENGTH 1024 static char recv_log_buffer[BUFFER_LENGTH],send_log_buffer[BUFFER_LENGTH]; static int recv_log_len=0,send_log_len=0; static int buffered_tag=-1; static ssize_t min(ssize_t a,ssize_t b){ return a>\n"); fclose(f); } static void flush_buf(int tag,const char *method,const char *buf,int *lenp){ if(*lenp>0){ do_log(tag,method,buf,*lenp); *lenp=0; } } static void buffer_destructor(void){ flush_buf(buffered_tag,"RECV",recv_log_buffer,&recv_log_len); flush_buf(buffered_tag,"SEND",send_log_buffer,&send_log_len); } __attribute__((constructor)) static void buffer_constructor(void){ signal(SIGINFO,(void(*)(int))buffer_destructor); atexit(buffer_destructor); } static void add_to_buf(int tag,const char *method,const char *data,size_t len,char *dstbuf,int *dstlenp){ size_t offset=0; while(*dstlenp+len-offset>BUFFER_LENGTH){ size_t num=min(len-offset,BUFFER_LENGTH-*dstlenp); memcpy(dstbuf+*dstlenp,data+offset,num); offset+=num; do_log(tag,method,dstbuf,num); *dstlenp=0; } if(len-offset>0){ memcpy(dstbuf+*dstlenp,data+offset,len-offset); *dstlenp+=len-offset; } } static ssize_t recv_wrapper(int socket,void *buffer,size_t length,int flags){ if(buffered_tag!=socket){ flush_buf(buffered_tag,"RECV",recv_log_buffer,&recv_log_len); flush_buf(buffered_tag,"SEND",send_log_buffer,&send_log_len); buffered_tag=socket; } ssize_t ret=recv(socket,buffer,length,flags); if(ret>0){ flush_buf(socket,"SEND",send_log_buffer,&send_log_len); add_to_buf(socket,"RECV",buffer,ret,recv_log_buffer,&recv_log_len); } return ret; } static ssize_t send_wrapper(int socket,const void *buffer,size_t length,int flags){ if(buffered_tag!=socket){ flush_buf(buffered_tag,"RECV",recv_log_buffer,&recv_log_len); flush_buf(buffered_tag,"SEND",send_log_buffer,&send_log_len); buffered_tag=socket; } ssize_t ret=send(socket,buffer,length,flags); if(ret>0){ flush_buf(socket,"RECV",recv_log_buffer,&recv_log_len); add_to_buf(socket,"SEND",buffer,ret,send_log_buffer,&send_log_len); } return ret; } #define recv recv_wrapper #define send send_wrapper #endif i64 tcp_read_line(int sock,char **buf,i64 *bufsz){ if(*bufsz==0||*buf==NULL){ *bufsz=512; *buf=malloc(*bufsz,char); } i64 len=0; while(true){ if(len==*bufsz-1){ *bufsz*=2; *buf=realloc(*buf,*bufsz,char); } i64 ret=recv(sock,*buf+len,1,0); if(ret<=0)return -1; if((*buf)[len]=='\n'){ (*buf)[len]='\0'; return len; } len++; } } i64 tcp_read_data(int sock,char *buf,i64 length){ i64 got=0; while(gotnitems=nitems; list->items=malloc(nitems,char*); walker=argstart; for(i64 i=0;iitems[i]=strdup(strsep(&walker," ")); } return list; } void tcp_list_destroy(TcpList *list){ free(list->items); free(list); } static const char* itoa(int n){ static char buf[64]; sprintf(buf,"%d",n); return buf; } int tcp_connect(const char *hostname,int port){ struct addrinfo hints,*res; memset(&hints,0,sizeof(hints)); hints.ai_family=AF_UNSPEC; hints.ai_socktype=SOCK_STREAM; int ret=getaddrinfo(hostname,itoa(port),&hints,&res); if(ret!=0){ return -1; } int sock=socket(res->ai_family,res->ai_socktype,res->ai_protocol); if(sock==-1)return -1; if(connect(sock,res->ai_addr,res->ai_addrlen)==-1)return -1; return sock; }