diff --git a/.gitignore b/.gitignore index 92b2793..19e5fb8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .direnv +a.out diff --git a/a.out b/a.out deleted file mode 100755 index ad79be9..0000000 Binary files a/a.out and /dev/null differ diff --git a/mini_serv.c b/mini_serv.c index b91d3c6..59fd124 100644 --- a/mini_serv.c +++ b/mini_serv.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -22,23 +23,102 @@ int sockfd; fd_set main_fd, read_fd; +void send_all(); + +int extract_message(char **buf, char **msg) { + char *newbuf; + int i; + + *msg = 0; + if (*buf == 0) + return (0); + i = 0; + while ((*buf)[i]) { + if ((*buf)[i] == '\n') { + newbuf = calloc(1, sizeof(*newbuf) * (strlen(*buf + i + 1) + 1)); + if (newbuf == 0) + return (-1); + strcpy(newbuf, *buf + i + 1); + *msg = *buf; + (*msg)[i + 1] = 0; + *buf = newbuf; + return (1); + } + i++; + } + return (0); +} + +char *str_join(char *buf, char *add) { + char *newbuf; + int len; + + if (buf == 0) + len = 0; + else + len = strlen(buf); + newbuf = malloc(sizeof(*newbuf) * (len + strlen(add) + 1)); + if (newbuf == 0) + return (0); + newbuf[0] = 0; + if (buf != 0) + strcat(newbuf, buf); + free(buf); + strcat(newbuf, add); + return (newbuf); +} + void append_client(int cli_fd) { lastid++; clients[cli_fd].id = lastid; clients[cli_fd].msg = NULL; FD_SET(cli_fd, &main_fd); + bzero(send_buf, 3000); + sprintf(send_buf, "server: client %d just arrived\n", lastid); + send_all(cli_fd); } -void send_all() { +void rm_client(int cli_fd) { + FD_CLR(cli_fd, &read_fd); + sprintf(send_buf, "server: client %d, just left\n", clients[cli_fd].id); + send_all(cli_fd); + clients[cli_fd].id = -1; + if (clients[cli_fd].msg != NULL) { + free(clients[cli_fd].msg); + clients[cli_fd].msg = NULL; + } + FD_CLR(cli_fd, &main_fd); + close(cli_fd); +} + +int read_client(int fd) { + char tmp[3000]; + int bytes; + if ((bytes = recv(fd, tmp, 3000, 0)) <= 0) + return (rm_client(fd), 0); + tmp[bytes] = 0; + clients[fd].msg = str_join(clients[fd].msg, tmp); + char *line = 0; + while (extract_message(&clients[fd].msg, &line)) { + bzero(send_buf, 3000); + sprintf(send_buf, "client %d: %s", clients[fd].id, line); + send_all(fd); + free(line); + } + return 1; +} + +void send_all(int cli_fd) { size_t len = strlen(send_buf); + printf("%s", send_buf); for (int i = 0; i <= maxfd; i++) - if (FD_ISSET(i, &read_fd)) + if (FD_ISSET(i, &main_fd) != 0 && i != cli_fd && i != sockfd) send(i, send_buf, len, 0); } int send_error(void) { - for (int i = 0; i < FD_SETSIZE; i++) + for (int i = 0; i < maxfd; i++) if (FD_ISSET(i, &main_fd)) close(i); close(sockfd); @@ -66,7 +146,7 @@ int main(int ac, char **av) { if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) return (send_error()); - if (listen(sockfd, 10) != 0) + if (listen(sockfd, SOMAXCONN) != 0) return (send_error()); FD_ZERO(&main_fd); @@ -91,11 +171,10 @@ int main(int ac, char **av) { if (cli_fd > maxfd) maxfd = cli_fd; append_client(cli_fd); - bzero(send_buf, 3000); - sprintf(send_buf, "server: client %d just arrived\n", - lastid); - send_all(); + break; } else { + if (!read_client(i)) + break; } } }