From a441b302c2c11c291df60fe642ec0d51646218dd Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Wed, 15 Mar 2017 10:20:55 +0100 Subject: Start with implementing online status etc for broadcasting --- command.c | 30 ++++++++++++++++++++++++++++++ db.c | 15 +++++++++++++++ db.h | 2 +- schema.sql | 2 +- user_data.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ user_data.h | 8 ++++++++ 6 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 user_data.c create mode 100644 user_data.h diff --git a/command.c b/command.c index 30d2223..3ede1cc 100644 --- a/command.c +++ b/command.c @@ -3,11 +3,19 @@ #include #include #include +#include #include #include "command.h" #include "db.h" +static i64 make_timestamp(void){ + struct timeval tv; + gettimeofday(&tv,NULL); + return (i64)tv.tv_sec+tv.tv_usec; +} + + static bool send_raw_text(int fd,const char *text,i64 len){ i64 cursor=0; while(cursorfd,tag); } +static bool cmd_send(struct conn_data *data,const char *tag,const char **args){ + if(data->userid==-1){ + send_error(data->fd,tag,"Not logged in"); + return false; + } + i64 roomid=db_find_room(args[0]); + if(roomid==-1){ + send_error(data->fd,tag,"Room not found"); + return false; + } + if(!db_is_member(roomid,data->userid)){ + send_error(data->fd,tag,"Not in that room"); + return false; + } + + db_create_message(roomid,data->userid,make_timestamp(),args[1]); + bool closed=send_ok(data->fd,tag); + +#warning TODO: broadcast +} + struct cmd_info{ const char *cmdname; @@ -184,6 +213,7 @@ static const struct cmd_info commands[]={ {"list_rooms",0,false,cmd_list_rooms}, {"create_room",0,false,cmd_create_room}, {"invite",2,false,cmd_invite}, + {"send",2,true,cmd_send}, }; #define NCOMMANDS (sizeof(commands)/sizeof(commands[0])) diff --git a/db.c b/db.c index 068817c..fa7603c 100644 --- a/db.c +++ b/db.c @@ -170,6 +170,21 @@ i64 db_find_user(const char *name){ } +void db_create_message(i64 roomid,i64 userid,i64 timestamp,const char *message){ + sqlite3_stmt *stmt; + SQLITE(prepare_v2,database, + "insert into Messages (room, user, time, message) " + "values (?, ?, ?, ?)" + ,-1,&stmt,NULL); + SQLITE(bind_int64,stmt,1,roomid); + SQLITE(bind_int64,stmt,2,userid); + SQLITE(bind_int64,stmt,3,timestamp); + SQLITE(bind_blob,stmt,4,message,strlen(message),SQLITE_STATIC); + if(sqlite3_step(stmt)!=SQLITE_DONE)die_sqlite("sqlite3_step"); + SQLITE(finalize,stmt); +} + + void db_nullify_name_id(struct db_name_id ni){ if(ni.name)free(ni.name); } diff --git a/db.h b/db.h index 9dc926c..8ca1227 100644 --- a/db.h +++ b/db.h @@ -42,7 +42,7 @@ char* db_get_pass(i64 userid); bool db_delete_user(i64 userid); i64 db_find_user(const char *name); // -1 if not found -bool db_create_message(i64 roomid,i64 userid,i64 timestamp,const char *message); +void db_create_message(i64 roomid,i64 userid,i64 timestamp,const char *message); struct db_message_list db_get_messages(i64 roomid,i64 timestamp,i64 count); // pass timestamp==-1 for last messages void db_nullify_name_id(struct db_name_id ni); diff --git a/schema.sql b/schema.sql index 321cb38..009308e 100644 --- a/schema.sql +++ b/schema.sql @@ -26,7 +26,7 @@ create table Messages ( room integer not null, user integer null, time integer not null, - message text, + message blob, foreign key(room) references Rooms(id) on delete cascade, foreign key(user) references Users(id) on delete set null ); diff --git a/user_data.c b/user_data.c new file mode 100644 index 0000000..5bd4a6d --- /dev/null +++ b/user_data.c @@ -0,0 +1,54 @@ +#include "user_data.h" + + +struct user_data{ + i64 userid; + + int *fds; + i64 fds_cap,fds_len; +}; + +struct hash_item{ + struct user_data data; + struct hash_item *next; +}; + +#define USER_HASH_SIZE (16) +static struct hash_item *user_hash[USER_HASH_SIZE]; + + +static struct hash_item* find_userdata(i64 userid){ + struct hash_item *item=user_hash[userid%USER_HASH_SIZE]; + while(item&&item->data.userid!=userid)item=item->next; + return item; +} + +void userdata_register(i64 userid,int fd){ + struct hash_item *item=find_userdata(userid); + if(item){ + for(i64 i=0;idata.fds_len;i++){ + if(item->data.fds[i]==fd){ + debug("userdata_register(%lld, %d) while pair already existed",userid,fd); + return; + } + } + if(item->data.fds_len==item->data.fds_cap){ + item->data.fds_cap*=2; + item->data.fds=realloc(item->data.fds,item->data.fds_cap,int); + } + item->data.fds[item->data.fds_len++]=fd; + } else { + item=malloc(1,struct hash_item); + item->data.userid=userid; + item->data.fds_cap=2; + item->data.fds_len=1; + item->data.fds=malloc(item->data.fds_cap,int); + item->data.fds[0]=fd; + item->next=user_hash[userid%USER_HASH_SIZE]; + user_hash[userid%USER_HASH_SIZE]=item; + } +} + +void userdata_unregister(i64 userid,int fd); + +bool userdata_online(i64 userid); diff --git a/user_data.h b/user_data.h new file mode 100644 index 0000000..572c97a --- /dev/null +++ b/user_data.h @@ -0,0 +1,8 @@ +#pragma once + +#include "global.h" + + +void userdata_register(i64 userid,int fd); +void userdata_unregister(i64 userid,int fd); +bool userdata_online(i64 userid); -- cgit v1.2.3-70-g09d2