SO2019/server.c

222 lines
6.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <ncurses.h>
#include <signal.h>
//estructuras e outras coisas uteis
#include "util.h"
//declaraao de funcoes
#include "dec.h"
int main(int argc, char *argv[]){
int sair=0, mopt=-1, n;
//cliente <> server comms
sv2cl msg2cl;
cl2sv clResp;
//utilizadores
clients *users = NULL;
clients *uinit = users;
int userCounter = 0;
srand(time(NULL));
int fd_servidor, fd_cliente, fd_child[2];
/* VERIFICAR SE EXISTE "CP" DO SERVIDOR (access) -- APENAS UM!!!*/
if(access("CPservidor", F_OK)==0){
printf("[SERVIDOR] Ja existe um servidor!\n");
exit(1);
}
/* CRIAR "CP" DO SERVIDOR - MINHA (mkfifo) */
mkfifo("CPservidor", 0600);
/* ABRIR "CP" DO SERVIDOR - MINHA (open - O_RDONLY) */
fd_servidor = open("CPservidor", O_RDWR);
printf("[SERVER] Servidor Iniciado!\n");
/* Fazer coisas aqui! */
do{
n = read(fd_servidor,&clResp, sizeof(clResp));
if(n == 0){
printf("[SERVER] nao da\n");
sleep(1);
continue;
}else if(strcmp(clResp.cmd,"shutdown")==0){
printf("[SERVER] O servidor vai desligar\n");
desligarClientes(users);
//TODO implementar desligar outros clientes!
sair = 1;
}else if(strcmp(clResp.cmd,"send")==0){
printf("funciona!\n");
printf("%s\n",clResp.opts);
}else if(strcmp(clResp.cmd,"register")==0){
clResp.opts[strlen(clResp.opts)-1]='\0';
if(verifyUserName(users,&userCounter,clResp.opts)==1){
msg2cl.code=2;
//responde
fd_cliente = open(clResp.fifostr,O_WRONLY);
write(fd_cliente,&msg2cl,sizeof(msg2cl));
close(fd_cliente);
//fim resposta
}else{
printf("[SERVER] Novo utilizador adicionado!\n");
users = addUser(users,&userCounter,clResp.opts,clResp.pid,clResp.fifostr);
msg2cl.code=1;
//responde
fd_cliente = open(clResp.fifostr,O_WRONLY);
write(fd_cliente,&msg2cl,sizeof(msg2cl));
close(fd_cliente);
//fim resposta
}
}else if(strcmp(clResp.cmd,"ping")==0){
sprintf(msg2cl.resp,"[SV] Olá %s (%s)\n",getUsernameFromfifo(users,clResp.fifostr), clResp.fifostr);
printf("[SERVER] A responder ao Cliente %s",clResp.fifostr);
//responde
fd_cliente = open(clResp.fifostr,O_WRONLY);
write(fd_cliente,&msg2cl,sizeof(msg2cl));
close(fd_cliente);
//fim da resposta
}else if(strcmp(clResp.cmd,"list")==0){
printf("[SERVER] A listar %d clientes...\n",userCounter);
listusers(users);
}else if(strcmp(clResp.cmd,"leaving")==0){
printf("[SERVER] Cliente desligado...\n");
users=removeUser(users,clResp.fifostr,&userCounter);
printf("[SERVER] Cliente removido!\n");
uinit = users;
}else if(strcmp(clResp.cmd,"verifica")==0){
printf("[SERVER] A verificar '%s'\n",clResp.opts);
pipe(fd_child);
switch(fork()){
case 0://child
close(fd_child[1]);
dup2(fd_child[0], STDIN_FILENO);
close(fd_child[0]);
execl("verificador", "./verificador", "words.txt", NULL);
default://me
close(fd_child[0]);
write(fd_child[1], clResp.opts, sizeof(clResp.opts));
close(fd_child[1]);
wait(NULL);
}
}
}while(sair==0);
printf("[SERVER] SERVIDOR DESLIGADO\n");
/* FECHAR "CP" DO SERVIDOR - MINHA (close) */
close(fd_servidor);
/* REMOVER "CP" DO SERVIDOR- MINHA (UNLINK) */
unlink("CPservidor");
exit(0);
}
int obtem_rand(int min, int max){
int random;
random = min + (rand() % (max - min + 1));
return random;
}
int verifyUserName(clients *users, int *nUsers, char *username){
clients *uinit = users;
while(users!=NULL){
if(strcmp(users->nome,username)==0){
users = uinit;
return 1;
}else{
users=users->prox;
}
}
users = uinit;
return 0;
}
clients *addUser(clients *users, int *nUsers, char *username, int pid, char *fifostr){
(*nUsers)++;
clients *uinit = users;
if(users == NULL){//adicionar primeiro user
users = malloc(sizeof(clients));
strcpy(users->nome,username);
strcpy(users->fifostr,fifostr);
users->pid=pid;
users->prox = NULL;
uinit = users;
}else{//adicionar outros users
while(users->prox!=NULL){
users=users->prox;
}
users->prox = malloc(sizeof(clients));
users = users->prox;
strcpy(users->nome,username);
strcpy(users->fifostr,fifostr);
users->pid=pid;
users->prox = NULL;
users = uinit;
}
return users;
}
char *getUsernameFromfifo(clients *users, char *fifo){
clients *uinit = users;
char send[100];
while(users!=NULL){
if(strcmp(users->fifostr,fifo)==0){
strcpy(send,users->nome);
users = uinit;
return send;
}
users=users->prox;
}
strcpy(send,"-ERROR");
return send;
}
void listusers(clients *users){
clients *uinit = users;
while(users!=NULL){
printf("Nome: %s, Fifo: %s\n",users->nome,users->fifostr);
users=users->prox;
}
users = uinit;
}
void desligarClientes(clients *users){
while(users!=NULL){
kill(users->pid,10);
users=users->prox;
}
}
clients *removeUser(clients *users, char *cp, int *nUsers){
(*nUsers)--;
clients *uinit = users;
clients *prev;
//verificar se o user que saiu foi o 1. na lista
if(strcmp(users->fifostr,cp)==0){
//é o primeiro do lista
uinit=users->prox;
free(users);
}else{
//nao é o primeiro da lista
while(users!=NULL){
prev = users;
users = users->prox;
if(strcmp(users->fifostr,cp)==0){
prev->prox = users->prox;
free(users);
break;
}
}
}
return uinit;
}