diff options
Diffstat (limited to 'tcp.c')
-rw-r--r-- | tcp.c | 118 |
1 files changed, 92 insertions, 26 deletions
@@ -132,13 +132,11 @@ static TcpList* interpret_list(char *buf,const char *tag){ i64 nitems=0; while((strsep(&walker," "))!=NULL)nitems++; if(word1==NULL||word2==NULL||word3==NULL||strcmp(word1,"list")!=0||strcmp(word2,tag)!=0){ - free(buf); return NULL; } char *endp; i64 word3i=strtoll(word3,&endp,10); if(word3[0]=='\0'||*endp!='\0'||word3i!=nitems){ - free(buf); return NULL; } @@ -184,58 +182,123 @@ TcpResponse* tcp_read_response(int sock,const char *tag){ char *walker=buf; char *word1=strsep(&walker," "); - char *word2=strsep(&walker," "); - if(word1==NULL||word2==NULL||strcmp(word2,tag)!=0){ + if(word1==NULL){ free(buf); return NULL; } TcpResponseType type; + char *gameidvalue,*roomidvalue; //Not yet strdup'd! + i64 idvalue; + char *messagevalue; i64 intvalue; TcpList *listvalue=NULL; - char *errorvalue=NULL; - if(strcmp(word1,"ok")==0&&walker==NULL){ - type=TCP_OK; - } else if(strcmp(word1,"error")==0){ - type=TCP_ERROR; - if(walker==NULL){ + char *errorvalue=NULL; //Not yet strdup'd! + + if(strcmp(word1,"room_join")==0||strcmp(word1,"room_leave")==0||strcmp(word1,"room_message")==0){ + if(word1[5]=='j')type=TCP_PUSH_JOIN; + else if(word1[5]=='l')type=TCP_PUSH_LEAVE; + else type=TCP_PUSH_MESSAGE; + + char *w1=strsep(&walker," "); + char *w2=strsep(&walker," "); + char *w3=strsep(&walker," "); + if(w1==NULL||w2==NULL||w3==NULL||(type==TCP_PUSH_MESSAGE?walker==NULL:walker!=NULL)){ free(buf); return NULL; } - errorvalue=walker; - } else if(strcmp(word1,"int")==0){ - type=TCP_INT; - char *token=strsep(&walker," "); - if(walker!=NULL||token==NULL){ + gameidvalue=w1; + roomidvalue=w2; + char *endp; + idvalue=strtoll(w3,&endp,10); + if(w3[0]=='\0'||*endp!='\0'||idvalue<0){ free(buf); return NULL; } - char *endp; - intvalue=strtoll(token,&endp,10); - if(token[0]=='\0'||*endp!='\0'){ + + if(type==TCP_PUSH_MESSAGE){ + char *w4=strsep(&walker," "); + if(w4==NULL||walker!=NULL){ + free(buf); + return NULL; + } + char *endp; + i64 msglength=strtoll(w4,&endp,10); + if(w4[0]=='\0'||*endp!='\0'||msglength<0){ + free(buf); + return NULL; + } + messagevalue=malloc(msglength+1,char); + if(tcp_read_data(sock,messagevalue,msglength)==-1){ + free(buf); + free(messagevalue); + return NULL; + } + messagevalue[msglength]='\0'; + } + } else { + char *word2=strsep(&walker," "); + if(word2==NULL||strcmp(word2,tag)!=0){ free(buf); return NULL; } - } else if(strcmp(word1,"list")==0){ - type=TCP_LIST; - listvalue=interpret_list(buf,tag); - if(listvalue==NULL){ + + if(strcmp(word1,"ok")==0&&walker==NULL){ + type=TCP_OK; + } else if(strcmp(word1,"error")==0){ + type=TCP_ERROR; + if(walker==NULL){ + free(buf); + return NULL; + } + errorvalue=walker; + } else if(strcmp(word1,"int")==0){ + type=TCP_INT; + char *token=strsep(&walker," "); + if(walker!=NULL||token==NULL){ + free(buf); + return NULL; + } + char *endp; + intvalue=strtoll(token,&endp,10); + if(token[0]=='\0'||*endp!='\0'){ + free(buf); + return NULL; + } + } else if(strcmp(word1,"list")==0){ + type=TCP_LIST; + listvalue=interpret_list(buf,tag); + if(listvalue==NULL){ + free(buf); + return NULL; + } + } else { free(buf); return NULL; } - } else { - free(buf); - return NULL; } TcpResponse *res=malloc(1,TcpResponse); res->type=type; switch(type){ case TCP_OK: break; - case TCP_ERROR: res->eval=errorvalue; break; + case TCP_ERROR: res->eval=strdup(errorvalue); break; case TCP_INT: res->ival=intvalue; break; case TCP_LIST: res->lval=listvalue; break; + case TCP_PUSH_JOIN: + case TCP_PUSH_LEAVE: + res->jval.gameid=strdup(gameidvalue); + res->jval.roomid=strdup(roomidvalue); + res->jval.id=idvalue; + break; + case TCP_PUSH_MESSAGE: + res->mval.gameid=strdup(gameidvalue); + res->mval.roomid=strdup(roomidvalue); + res->mval.id=idvalue; + res->mval.message=messagevalue; + break; } + free(buf); return res; } @@ -245,6 +308,9 @@ void tcp_response_destroy(TcpResponse *res){ case TCP_ERROR: free(res->eval); break; case TCP_INT: break; case TCP_LIST: tcp_list_destroy(res->lval); break; + case TCP_PUSH_JOIN: + case TCP_PUSH_LEAVE: free(res->jval.gameid); free(res->jval.roomid); break; + case TCP_PUSH_MESSAGE: free(res->mval.gameid); free(res->mval.roomid); free(res->mval.message); break; } free(res); } |