Program Listing for File client_lifecycle.c¶
↰ Return to documentation for file (server/client/client_lifecycle.c)
#include <arpa/inet.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "utils/resizable_array.h"
#include "client.h"
#include "event.h"
#include "server.h"
static
bool add_client_state(server_t *srv, int fd)
{
static uint32_t id = 0;
client_state_t *client = client_manager_add(&srv->cm);
size_t idx;
if (client == nullptr)
return false;
client->fd = fd;
client->id = id;
idx = srv->cm.idx_of_gui - 1;
srv->cm.server_pfds[idx].fd = fd;
srv->cm.server_pfds[idx].events = POLLIN;
srv->cm.server_pfds[idx].revents = 0;
id++;
append_to_output(srv, client, "WELCOME\n");
return true;
}
void add_client(server_t *srv)
{
struct sockaddr_in addr;
socklen_t addr_len = sizeof(addr);
int new_fd = accept(srv->self_fd, (struct sockaddr *)&addr, &addr_len);
if (new_fd < 0) {
perror("accept failed");
return;
}
if (!add_client_state(srv, new_fd)) {
close(new_fd);
perror("failed to register client");
return;
}
DEBUG("New client connected: fd=%d, addr=%s:%d",
new_fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
}
void remove_client(server_t *srv, uint32_t idx)
{
if (idx >= srv->cm.count)
return;
if (srv->cm.clients[idx].team_id > TEAM_ID_GRAPHIC)
send_to_guis(srv, "pdi #%hd\n", srv->cm.clients[idx].id);
for (size_t i = 0; i < srv->events.nmemb; i++)
if (srv->events.buff[i].client_idx == (int)(idx))
srv->events.buff[i].client_idx = CLIENT_DEAD;
DEBUG("Client disconnected: %u, fd=%d", idx, srv->cm.clients[idx].fd);
if (srv->cm.clients[idx].fd >= 0)
close(srv->cm.clients[idx].fd);
free(srv->cm.clients[idx].input.buff);
free(srv->cm.clients[idx].output.buff);
client_manager_remove(&srv->cm, idx);
}