From dabeb3a9fe2295e9b95a46e72de6e78e78f1befb Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Mon, 22 May 2017 20:59:49 +0200 Subject: server: WIP firebase --- firebase.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 firebase.c (limited to 'firebase.c') diff --git a/firebase.c b/firebase.c new file mode 100644 index 0000000..780b973 --- /dev/null +++ b/firebase.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include "db.h" +#include "firebase.h" + + +#define JS_PLUGIN_PATH "firebase-io/firebase-io.js" + +FILE *js_write=NULL; + + +static void write_field(FILE *f,const char *key,const char *value){ + fprintf(f," %s %zu %s",key,strlen(value),value); +} + +static void token_send(const char *token,const char *room,const char *user,const char *msg){ + fprintf(js_write,"message"); + write_field(js_write,"token",token); + write_field(js_write,"room",room); + write_field(js_write,"user",user); + write_field(js_write,"message",msg); + fprintf(js_write,"\n"); + fflush(js_write); +} + +static void script_output_listener(FILE *js_read){ + // Do not use js_write here, it's NULL + char *line=NULL; + size_t linecap=0; + ssize_t linelen; + while((linelen=getline(&line,&linecap,js_read))>0){ + if(line[linelen-1]!='\n'){ + fprintf(stderr,"firebase thread: unexpected EOF from js script\n"); + return; + } + line[linelen-1]='\0'; + linelen--; + + char *spacep=strchr(line,' '); + if(spacep==NULL)goto invalid_line; + *spacep='\0'; + char *cmd=line; + + if(strcmp(cmd,"add_token")==0||strcmp(cmd,"delete_token")==0){ + char *username=spacep+1; + spacep=strchr(username,' '); + if(spacep==NULL)goto invalid_line; + *spacep='\0'; + char *token=spacep+1; + + i64 userid=db_find_user(username); + if(userid==-1){ + fprintf(stderr,"firebase thread: unknown username '%s'\n",username); + continue; + } + + if(strcmp(cmd,"add_token")==0){ + db_add_token(userid,token); + } else { + db_delete_token(userid,token); + } + } + + continue; + + invalid_line: + fprintf(stderr,"firebase thread: Invalid line form js script: <%s>\n",line); + } +} + + +void firebase_init(void){ + int wrpipe[2],rdpipe[2]; + if(pipe(wrpipe)<0||pipe(rdpipe)<0){ + perror("pipe"); + exit(1); + } + + pid_t pid=fork(); // The JS script + if(pid<0){ + perror("fork"); + exit(1); + } + if(pid==0){ + close(wrpipe[1]); + close(rdpipe[0]); + dup2(wrpipe[0],0); + dup2(rdpipe[1],1); + execl(JS_PLUGIN_PATH,JS_PLUGIN_PATH); + perror("execl"); + exit(1); + } + close(wrpipe[0]); + close(rdpipe[1]); + + pid=fork(); // The script stdout listener + if(pid<0){ + perror("fork"); + exit(1); + } + if(pid==0){ + close(wrpipe[1]); + FILE *js_read=fdopen(rdpipe[0],"r"); + script_output_listener(js_read); + fclose(js_read); + exit(0); + } + + js_write=fdopen(wrpipe[1],"w"); + printf("Started js firebase plugin\n"); +} + +void firebase_stop(void){ + // Script will stop itself on EOF on stdin + fclose(js_write); +} + +void firebase_send_message(const char *room,i64 roomid,const char *user,const char *msg){ + if(roomid==-1)roomid=db_find_room(room); + if(roomid==-1){ + debug("firebase_send_message: Cannot find roomid for room '%s'",room); + return; + } + + struct db_user_list members=db_list_members(roomid); + for(i64 i=0;i