diff options
Diffstat (limited to 'command.c')
-rw-r--r-- | command.c | 123 |
1 files changed, 109 insertions, 14 deletions
@@ -40,20 +40,108 @@ static bool send_error(int fd,const char *tag,const char *msg){ return closed; } +static bool send_name(int fd,const char *tag,const char *name){ + char *buf=NULL; + i64 len=asprintf(&buf,"%s name %s\n",tag,name); + assert(buf); + bool closed=send_raw_text(fd,buf,len); + free(buf); + return closed; +} -static bool cmd_register(int fd,const char *tag,const char **args){ +static bool send_list(int fd,const char *tag,i64 count,const char **list){ + char *buf=NULL; + i64 len=asprintf(&buf,"%s list %lld",tag,count); + assert(buf); + bool closed=send_raw_text(fd,buf,len); + free(buf); + if(closed)return true; + + if(count>0){ + i64 bufsz=64; + buf=malloc(bufsz,char); + + for(i64 i=0;i<count;i++){ + i64 len=strlen(list[i]); + if(len>=bufsz){ + bufsz=len+512; + buf=realloc(buf,bufsz,char); + } + memcpy(buf+1,list[i],len); + buf[0]=' '; + if(send_raw_text(fd,buf,len+1)){ + free(buf); + return true; + } + } + + free(buf); + } + + return send_raw_text(fd,"\n",1); +} + + +static bool cmd_register(struct conn_data *data,const char *tag,const char **args){ i64 userid=db_find_user(args[0]); if(userid!=-1){ - send_error(fd,tag,"Username already exists"); + send_error(data->fd,tag,"Username already exists"); return false; } db_create_user(args[0],args[1]); - return send_ok(fd,tag); + return send_ok(data->fd,tag); } -static bool cmd_login(int fd,const char *tag,const char **args){ - (void)fd; (void)tag; (void)args; - return true; +static bool cmd_login(struct conn_data *data,const char *tag,const char **args){ + i64 userid=db_find_user(args[0]); + if(userid==-1){ + send_error(data->fd,tag,"Username does not exist"); + return false; + } + char *pass=db_get_pass(userid); + bool success=strcmp(args[1],pass)==0; + free(pass); + if(success){ + data->userid=userid; + send_ok(data->fd,tag); + } else { + data->userid=-1; + send_error(data->fd,tag,"Incorrect password"); + } + return false; +} + +static bool cmd_list_rooms(struct conn_data *data,const char *tag,const char **args){ + (void)args; + if(data->userid==-1){ + send_error(data->fd,tag,"Not logged in"); + return false; + } + struct db_room_list rl=db_list_rooms(data->userid); + if(rl.count<=0){ + db_nullify_room_list(rl); + return send_list(data->fd,tag,0,NULL); + } + const char *names[rl.count]; + for(i64 i=0;i<rl.count;i++){ + names[i]=rl.list[i].name; + } + bool closed=send_list(data->fd,tag,rl.count,names); + db_nullify_room_list(rl); + return closed; +} + +static bool cmd_create_room(struct conn_data *data,const char *tag,const char **args){ + (void)args; + if(data->userid==-1){ + send_error(data->fd,tag,"Not logged in"); + return false; + } + struct db_name_id room=db_create_room(); + db_add_member(room.id,data->userid); + bool closed=send_name(data->fd,tag,room.name); + db_nullify_name_id(room); + return closed; } @@ -61,20 +149,22 @@ struct cmd_info{ const char *cmdname; int nargs; bool longlast; // whether the last argument should span the rest of the input line - bool (*handler)(int fd,const char *tag,const char **args); + bool (*handler)(struct conn_data *data,const char *tag,const char **args); }; static const struct cmd_info commands[]={ - {"register",2,false,cmd_register}, - {"login",2,false,cmd_login}, + {"register",2,true,cmd_register}, + {"login",2,true,cmd_login}, + {"list_rooms",0,false,cmd_list_rooms}, + {"create_room",0,false,cmd_create_room}, }; #define NCOMMANDS (sizeof(commands)/sizeof(commands[0])) -bool handle_input_line(int fd,char *line,size_t linelen){ +bool handle_input_line(struct conn_data *data,char *line,size_t linelen){ char *sepp=memchr(line,' ',linelen); if(sepp==NULL){ - debug("No space in input line from connection %d",fd); + debug("No space in input line from connection %d",data->fd); return true; } char *tag=line; @@ -93,13 +183,18 @@ bool handle_input_line(int fd,char *line,size_t linelen){ } } + if(cmdi==NCOMMANDS){ + debug("Unknown command %s on connection %d",line,data->fd); + return true; + } + int nargs=commands[cmdi].nargs; char *args[nargs]; size_t cursor=cmdlen+1; for(int i=0;i<nargs;i++){ if(cursor>=linelen){ - debug("Connection %d sent too few parameters to command %s",fd,commands[cmdi].cmdname); + debug("Connection %d sent too few parameters to command %s",data->fd,commands[cmdi].cmdname); return true; } if(i==nargs-1&&commands[cmdi].longlast){ @@ -113,9 +208,9 @@ bool handle_input_line(int fd,char *line,size_t linelen){ cursor=sepp-line+1; } if(sepp-line<(i64)linelen){ - debug("Connection %d sent too many parameters to command %s",fd,commands[cmdi].cmdname); + debug("Connection %d sent too many parameters to command %s",data->fd,commands[cmdi].cmdname); return true; } - return commands[cmdi].handler(fd,tag,(const char**)args); + return commands[cmdi].handler(data,tag,(const char**)args); } |