summaryrefslogtreecommitdiff
path: root/tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcp.c')
-rw-r--r--tcp.c118
1 files changed, 92 insertions, 26 deletions
diff --git a/tcp.c b/tcp.c
index 8ed6060..bd35391 100644
--- a/tcp.c
+++ b/tcp.c
@@ -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);
}