├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── include ├── list.h ├── network.h └── ringbuffer.h └── src ├── add_list.c ├── data.c ├── del_list.c ├── handle_poll.c ├── list.c ├── network.c ├── network_client.c ├── network_server.c ├── ringbuffer.c └── utils.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project (libnetk) 4 | set(CMAKE_BUILD_TYPE Release) 5 | 6 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 7 | add_library(netk STATIC src/add_list.c 8 | src/data.c 9 | src/del_list.c 10 | src/handle_poll.c 11 | src/list.c 12 | src/network.c 13 | src/network_client.c 14 | src/network_server.c 15 | src/ringbuffer.c 16 | src/utils.c 17 | ) 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Emeline Gaulard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetworkLib 2 | Useful library in C to send or receive data using ringbuffers and poll. It makes use of the UNIX Network APIs. 3 | 4 | ## Compile it 5 | 6 | ```sh 7 | mkdir build 8 | cd build 9 | cmake .. 10 | make 11 | ``` 12 | -------------------------------------------------------------------------------- /include/list.h: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #ifndef LIST_H_ 24 | # define LIST_H_ 25 | 26 | # include 27 | 28 | # define TRUE 0 29 | # define FALSE 1 30 | 31 | typedef struct s_list 32 | { 33 | int fd; 34 | ssize_t ret; 35 | char *msg; 36 | struct s_list *next; 37 | } t_list; 38 | 39 | /* 40 | ** list.c 41 | */ 42 | unsigned int list_get_size(t_list *list); 43 | int list_is_empty(t_list *list); 44 | void list_dump(t_list *list); 45 | char *list_get_elem(t_list *list, int fd); 46 | void add_ret(t_list *list, int fd, int ret); 47 | 48 | /* 49 | ** add_list.c 50 | */ 51 | int list_add_elem_at_front(t_list **front_ptr, char *msg, int fd); 52 | int list_add_elem_at_back(t_list **front_ptr, char *msg, int fd); 53 | int list_add_elem_at_position(t_list **front_ptr, char *msg, int fd, 54 | unsigned int position); 55 | void list_update_elem(t_list *list, int fd, ssize_t ret); 56 | 57 | /* 58 | ** del_list.c 59 | */ 60 | int list_del_elem_at_front(t_list **front_ptr); 61 | int list_del_elem_at_back(t_list **front_ptr); 62 | int list_del_elem(t_list **front_ptr, int fd); 63 | 64 | #endif /* !LIST_H_ */ 65 | -------------------------------------------------------------------------------- /include/network.h: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #ifndef NETWORK_H_ 24 | # define NETWORK_H_ 25 | 26 | # include 27 | # include 28 | # include 29 | # include 30 | # include 31 | # include 32 | # include 33 | # include 34 | # include 35 | # include 36 | # include "ringbuffer.h" 37 | # include "list.h" 38 | 39 | # define SUCCESS 0 40 | # define ERROR -1 41 | # define CLOSE_ERR -1 42 | # define SOCK_ERR -1 43 | # define CLOSE_CONN 2 44 | 45 | typedef struct s_network 46 | { 47 | struct protoent *pe; 48 | struct sockaddr_in s_in; 49 | int fd; 50 | } t_network; 51 | 52 | typedef struct s_server 53 | { 54 | t_network network; 55 | struct pollfd clientfds[1024]; 56 | t_ringbuffer **clientbuffer; 57 | t_list *to_send; 58 | nfds_t nfds; 59 | int timeout; 60 | int actual; 61 | int max; 62 | } t_server; 63 | 64 | typedef struct s_client 65 | { 66 | t_network network; 67 | struct pollfd server; 68 | t_ringbuffer *buffer; 69 | t_list *to_send; 70 | nfds_t nfds; 71 | int timeout; 72 | int max; 73 | } t_client; 74 | 75 | /* 76 | ** network.c 77 | ** This file contains the most important functions to auto start client/server 78 | */ 79 | void init_struct(struct sockaddr_in *s_in, int port, char *ip); 80 | int error(char *str); 81 | void update_max(t_server *server, int nb); 82 | t_server *start_server(int port, int nb); 83 | t_client *start_client(int port, char *ip); 84 | 85 | /* 86 | ** network_client.c 87 | ** init_client start a client 88 | */ 89 | int init_client(t_client *client, int port, char *ip); 90 | 91 | /* 92 | ** network_server.c 93 | ** Contains all functions to initialize connection of the server part 94 | */ 95 | int init_bind(int fd, struct sockaddr_in *s_in); 96 | int init_server(t_network *network, int port, int nb); 97 | int to_listen(int fd, int nb); 98 | int to_accept(int fd); 99 | int init_ringbuffer(t_server *server, int nb); 100 | 101 | /* 102 | ** utils.c 103 | ** This file contains the useful functions to : 104 | ** - set a new client 105 | ** - close client/server 106 | ** - find the index of the good ringbuffer corresponding to one fd 107 | */ 108 | int check_slot(t_server *server); 109 | int fill_slot(t_server *server); 110 | int close_server(t_server *server); 111 | int close_client(t_client *client); 112 | int get_index(t_server *server, int fd); 113 | 114 | /* 115 | ** handle_poll.c 116 | ** This file is about polling events and accepting new clients 117 | */ 118 | int disconnect_client(t_server *server, int idx); 119 | void order_fds(t_server *server); 120 | int handle(t_server *server, int timeout); 121 | 122 | /* 123 | ** data.c 124 | ** This file contains the functions about receiving and sending data 125 | */ 126 | int send_data(int fd, t_list **list); 127 | int receive_data(int fd, t_ringbuffer *client); 128 | 129 | #endif /* !NETWORK_H_ */ 130 | -------------------------------------------------------------------------------- /include/ringbuffer.h: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #ifndef RINGBUFFER_H_ 24 | # define RINGBUFFER_H_ 25 | 26 | # include 27 | # include 28 | 29 | # define EMPTY 2 30 | # define FULL 1 31 | # define OK 0 32 | # define ERROR -1 33 | 34 | /* 35 | ** Ring buffer struct 36 | ** Contains: 37 | ** - a pointer on the actual buffer in memory 38 | ** - a pointer on the buffer end in memory 39 | ** - a pointer to the start of valid data 40 | ** - a pointer to the end of valid data 41 | ** - the number of actual items 42 | */ 43 | typedef struct s_ringbuffer 44 | { 45 | char *buffer; 46 | unsigned int start; 47 | unsigned int end; 48 | size_t count; 49 | size_t max; 50 | size_t cap; 51 | } t_ringbuffer; 52 | 53 | t_ringbuffer *init_buffer(size_t max, size_t size); 54 | void add_item(t_ringbuffer *buffer, char *item); 55 | char *get_item(t_ringbuffer *buffer, char delim); 56 | void free_buffer(t_ringbuffer *buf); 57 | int buffer_status(t_ringbuffer *buf); 58 | 59 | #endif /* !RINGBUFFER_H_ */ 60 | -------------------------------------------------------------------------------- /src/add_list.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include "list.h" 24 | 25 | int list_add_elem_at_front(t_list **front_ptr, char *msg, int fd) 26 | { 27 | t_list *new; 28 | 29 | if ((new = malloc(sizeof(t_list))) == NULL) 30 | return (FALSE); 31 | if (*front_ptr == NULL) 32 | { 33 | if ((new = malloc(sizeof(t_list))) == NULL) 34 | return (FALSE); 35 | new->msg = msg; 36 | new->ret = 0; 37 | new->fd = fd; 38 | new->next = NULL; 39 | *front_ptr = new; 40 | return (TRUE); 41 | } 42 | new->msg = msg; 43 | new->ret = 0; 44 | new->fd = fd; 45 | new->next = *front_ptr; 46 | *front_ptr = new; 47 | return (TRUE); 48 | } 49 | 50 | int list_add_elem_at_back(t_list **front_ptr, char *msg, int fd) 51 | { 52 | t_list *tmp; 53 | t_list *new; 54 | 55 | if ((new = malloc(sizeof(t_list))) == NULL) 56 | return (FALSE); 57 | tmp = *front_ptr; 58 | if (tmp == NULL) 59 | { 60 | if ((tmp = malloc(sizeof(t_list))) == NULL) 61 | return (FALSE); 62 | tmp->msg = msg; 63 | tmp->fd = fd; 64 | tmp->ret = 0; 65 | tmp->next = NULL; 66 | *front_ptr = tmp; 67 | return (TRUE); 68 | } 69 | while (tmp->next) 70 | tmp = tmp->next; 71 | tmp->next = new; 72 | new->msg = msg; 73 | new->ret = 0; 74 | new->fd = fd; 75 | new->next = NULL; 76 | return (TRUE); 77 | } 78 | 79 | int list_add_elem_at_position(t_list **front_ptr, char *msg, int fd, 80 | unsigned int position) 81 | { 82 | unsigned int pos = 0; 83 | t_list *tmp; 84 | t_list *tmp2; 85 | t_list *new; 86 | 87 | if ((new = malloc(sizeof(t_list))) == NULL) 88 | return (FALSE); 89 | if (position == 0) 90 | return (list_add_elem_at_front(front_ptr, msg, fd)); 91 | tmp = *front_ptr; 92 | tmp2 = (*front_ptr)->next; 93 | while (pos != (position - 2) && tmp->next != NULL) 94 | { 95 | tmp = tmp->next; 96 | tmp2 = tmp2->next; 97 | pos++; 98 | } 99 | tmp->next = new; 100 | new->msg = msg; 101 | new->ret = 0; 102 | new->fd = fd; 103 | new->next = tmp2; 104 | return (TRUE); 105 | } 106 | 107 | void list_update_elem(t_list *list, int fd, ssize_t ret) 108 | { 109 | t_list *tmp; 110 | 111 | if (!list) 112 | return ; 113 | tmp = list; 114 | while (tmp) 115 | { 116 | if (tmp->fd == fd) 117 | { 118 | tmp->ret = ret; 119 | return ; 120 | } 121 | tmp = tmp->next; 122 | } 123 | return ; 124 | } 125 | -------------------------------------------------------------------------------- /src/data.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include "network.h" 24 | 25 | int send_data(int fd, t_list **list) 26 | { 27 | char *tmp; 28 | ssize_t ret; 29 | 30 | ret = 0; 31 | if ((tmp = list_get_elem(*list, fd)) == NULL) 32 | return (0); 33 | if ((ret = send(fd, &tmp[ret], strlen(&tmp[ret]), 0)) == ERROR) 34 | return (CLOSE_CONN); 35 | if (ret == (ssize_t)strlen(tmp)) 36 | return (list_del_elem(list, fd)); 37 | else 38 | list_update_elem(*list, fd, ret); 39 | return (SUCCESS); 40 | } 41 | 42 | int receive_data(int fd, t_ringbuffer *client) 43 | { 44 | char buffer[512]; 45 | int ret; 46 | 47 | if ((ret = recv(fd, buffer, 514, 0)) > 0) 48 | { 49 | buffer[ret] = 0; 50 | add_item(client, buffer); 51 | } 52 | if (ret == 0) 53 | return (CLOSE_CONN); 54 | return (SUCCESS); 55 | } 56 | -------------------------------------------------------------------------------- /src/del_list.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include "list.h" 24 | 25 | int list_del_elem_at_front(t_list **front_ptr) 26 | { 27 | t_list *tmp; 28 | t_list *tmp2; 29 | 30 | if (front_ptr == NULL) 31 | return (FALSE); 32 | tmp = *front_ptr; 33 | tmp2 = (*front_ptr)->next; 34 | free(tmp); 35 | (*front_ptr) = tmp2; 36 | return (TRUE); 37 | } 38 | 39 | int list_del_elem_at_back(t_list **front_ptr) 40 | { 41 | t_list *tmp; 42 | t_list *tmp2; 43 | 44 | if (!front_ptr) 45 | return (FALSE); 46 | tmp = *front_ptr; 47 | tmp2 = (*front_ptr)->next; 48 | while (tmp2->next) 49 | { 50 | tmp = tmp->next; 51 | tmp2 = tmp2->next; 52 | } 53 | free(tmp2); 54 | tmp->next = NULL; 55 | return (TRUE); 56 | } 57 | 58 | int list_del_elem(t_list **front_ptr, int fd) 59 | { 60 | t_list *tmp; 61 | t_list *tmp2; 62 | 63 | if (front_ptr == NULL) 64 | return (FALSE); 65 | if (*front_ptr == NULL) 66 | return (FALSE); 67 | tmp = (*front_ptr)->next; 68 | tmp2 = *front_ptr; 69 | if (tmp2->fd == fd) 70 | return (list_del_elem_at_front(front_ptr)); 71 | while (tmp) 72 | { 73 | if (tmp->fd == fd) 74 | { 75 | tmp = tmp->next; 76 | free(tmp2->next); 77 | tmp2->next = tmp; 78 | return (TRUE); 79 | } 80 | tmp = tmp->next; 81 | tmp2 = tmp2->next; 82 | } 83 | return (FALSE); 84 | } 85 | -------------------------------------------------------------------------------- /src/handle_poll.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include 24 | #include "network.h" 25 | 26 | int disconnect_client(t_server *server, int idx) 27 | { 28 | int ret; 29 | 30 | ret = 0; 31 | while (ret == 0) 32 | ret = list_del_elem(&(server->to_send), server->clientfds[idx].fd); 33 | free_buffer(server->clientbuffer[idx]); 34 | if (close(server->clientfds[idx].fd)) 35 | return (ERROR); 36 | server->clientfds[idx].fd = -1; 37 | order_fds(server); 38 | return (SUCCESS); 39 | } 40 | 41 | void order_fds(t_server *server) 42 | { 43 | int i; 44 | int j; 45 | 46 | for (i = 0; i < server->actual; ++i) 47 | { 48 | if (server->clientfds[i].fd == -1) 49 | { 50 | for (j = i; j < server->actual - 1; ++j) 51 | { 52 | server->clientfds[j].fd = server->clientfds[j + 1].fd; 53 | server->clientbuffer[j] = server->clientbuffer[j + 1]; 54 | } 55 | server->clientfds[j].fd = -1; 56 | server->clientbuffer[j] = init_buffer(10, 512); 57 | i--; 58 | server->actual--; 59 | } 60 | } 61 | } 62 | 63 | int data_incoming(t_server *server, int i) 64 | { 65 | if (server->clientfds[i].fd == server->clientfds[0].fd) 66 | { 67 | if ((server->clientfds[server->actual].fd = 68 | to_accept(server->clientfds[0].fd)) == ERROR) 69 | return (ERROR); 70 | fill_slot(server); 71 | } 72 | if (receive_data(server->clientfds[i].fd, server->clientbuffer[i]) 73 | == CLOSE_CONN) 74 | { 75 | if (disconnect_client(server, i) == ERROR) 76 | return (ERROR); 77 | printf("we are closing connection\n"); 78 | } 79 | return (SUCCESS); 80 | } 81 | 82 | int check_fd(t_server *server) 83 | { 84 | int i; 85 | 86 | for (i = 0; i <= server->actual; i++) 87 | { 88 | if (server->clientfds[i].revents & POLLOUT) 89 | if (send_data(server->clientfds[i].fd, &(server->to_send)) == CLOSE_CONN) 90 | if (disconnect_client(server, i) == ERROR) 91 | return (ERROR); 92 | if (server->clientfds[i].revents & POLLIN) 93 | data_incoming(server, i); 94 | } 95 | return (SUCCESS); 96 | } 97 | 98 | int handle(t_server *server, int timeout) 99 | { 100 | int ret; 101 | 102 | server->clientfds[0].fd = server->network.fd; 103 | for (ret = 0; ret < server->actual; ++ret) 104 | { 105 | server->clientfds[ret].events = POLLIN | POLLOUT; 106 | server->clientfds[ret].revents = 0; 107 | } 108 | ret = 0; 109 | ret = poll(server->clientfds, server->max, timeout); 110 | if (ret == 0) 111 | return (SUCCESS); 112 | if (ret > 0) 113 | return (check_fd(server)); 114 | return (SUCCESS); 115 | } 116 | -------------------------------------------------------------------------------- /src/list.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include 24 | #include "list.h" 25 | 26 | unsigned int list_get_size(t_list *list) 27 | { 28 | unsigned int size; 29 | t_list *tmp; 30 | 31 | size = 0; 32 | tmp = list; 33 | if (tmp == NULL) 34 | return (0); 35 | while (tmp) 36 | { 37 | size++; 38 | tmp = tmp->next; 39 | } 40 | return (size); 41 | } 42 | 43 | int list_is_empty(t_list *list) 44 | { 45 | if (list == NULL) 46 | return (TRUE); 47 | return (FALSE); 48 | } 49 | 50 | void list_dump(t_list *list) 51 | { 52 | t_list *tmp; 53 | 54 | tmp = list; 55 | while (tmp != NULL) 56 | { 57 | printf("fd = %d ret = %d msg = %s\n", tmp->fd, (int)tmp->ret, tmp->msg); 58 | tmp = tmp->next; 59 | } 60 | } 61 | 62 | /* Value Access */ 63 | char *list_get_elem(t_list *list, int fd) 64 | { 65 | t_list *tmp; 66 | 67 | if (!list) 68 | return (NULL); 69 | tmp = list; 70 | while (tmp) 71 | { 72 | if (tmp->fd == fd) 73 | return (&(tmp->msg[tmp->ret])); 74 | tmp = tmp->next; 75 | } 76 | return (NULL); 77 | } 78 | 79 | void add_ret(t_list *list, int fd, int ret) 80 | { 81 | t_list *tmp; 82 | 83 | if (!list) 84 | return ; 85 | tmp = list; 86 | while (tmp) 87 | { 88 | if (tmp->fd == fd) 89 | { 90 | tmp->ret = ret; 91 | return ; 92 | } 93 | tmp = tmp->next; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/network.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include 24 | #include "network.h" 25 | 26 | int error(char *str) 27 | { 28 | fprintf(stderr, "%s\n", str); 29 | return (-1); 30 | } 31 | 32 | void init_struct(struct sockaddr_in *s_in, int port, char *ip) 33 | { 34 | s_in->sin_family = AF_INET; 35 | s_in->sin_port = htons(port); 36 | if (!ip) 37 | s_in->sin_addr.s_addr = INADDR_ANY; 38 | else 39 | s_in->sin_addr.s_addr = inet_addr(ip); 40 | } 41 | 42 | void update_max(t_server *server, int nb) 43 | { 44 | server->max += nb; 45 | if (server->max > 256) 46 | server->max = 256; 47 | } 48 | 49 | /* 50 | ** This function handle a server by itself, just have to tell the port 51 | ** and the number of clients expected 52 | */ 53 | t_server *start_server(int port, int nb) 54 | { 55 | t_server *server; 56 | 57 | if ((server = malloc(sizeof(t_server))) == NULL) 58 | { 59 | dprintf(2, "Malloc failed\n"); 60 | return (NULL); 61 | } 62 | memset(server->clientfds, 0 , sizeof(server->clientfds)); 63 | if (init_server(&(server->network), port, nb) == ERROR) 64 | return (NULL); 65 | if (init_ringbuffer(server, nb) == ERROR) 66 | return (NULL); 67 | server->to_send = NULL; 68 | server->clientfds[0].fd = server->network.fd; 69 | server->clientfds[0].events = POLLIN | POLLOUT; 70 | server->clientfds[0].revents = 0; 71 | server->actual = 1; 72 | server->max = nb; 73 | if (nb > 1014) 74 | server->max = 1014; 75 | return (server); 76 | } 77 | 78 | t_client *start_client(int port, char *ip) 79 | { 80 | t_client *client; 81 | 82 | if ((client = malloc(sizeof(t_client))) == NULL) 83 | { 84 | dprintf(2, "Malloc failed\n"); 85 | return (NULL); 86 | } 87 | if (init_client(client, port, ip) == ERROR) 88 | return (NULL); 89 | printf("socket client : [%d]\n", client->network.fd); 90 | return (client); 91 | } 92 | -------------------------------------------------------------------------------- /src/network_client.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include 24 | #include "network.h" 25 | 26 | int connect_client(int fd, struct sockaddr_in s_in) 27 | { 28 | if (connect(fd, (struct sockaddr *)&s_in, sizeof(s_in)) == ERROR) 29 | { 30 | if (close(fd) == CLOSE_ERR) 31 | return (error("close failed after connect failed")); 32 | return (error("connect failed")); 33 | } 34 | return (SUCCESS); 35 | } 36 | 37 | t_client *set_value(t_client *client) 38 | { 39 | client->buffer = init_buffer(10, 1024); 40 | client->to_send = NULL; 41 | client->server.fd = client->network.fd; 42 | client->server.events = POLLIN | POLLOUT | POLLHUP; 43 | client->server.revents = 0; 44 | return (client); 45 | } 46 | 47 | int init_client(t_client *client, int port, char *ip) 48 | { 49 | struct hostent *p; 50 | int opt; 51 | 52 | if ((client->network.pe = getprotobyname("TCP")) == NULL) 53 | return (error("getprotobyname failed")); 54 | if ((client->network.fd = socket(AF_INET, SOCK_STREAM, 55 | client->network.pe->p_proto)) == SOCK_ERR) 56 | return (error("socket failed")); 57 | opt = 1; 58 | if (setsockopt(client->network.fd, SOL_SOCKET, SO_REUSEADDR, 59 | &opt, sizeof(opt)) == SOCK_ERR) 60 | { 61 | if (close(client->network.fd) == CLOSE_ERR) 62 | return (error("close failed after setsockopt failed")); 63 | return (error("setsockopt failed")); 64 | } 65 | if ((p = gethostbyname(ip)) == NULL) 66 | return (error("gethostbyname failed")); 67 | init_struct(&(client->network.s_in), port, 68 | inet_ntoa(*((struct in_addr *)p->h_addr))); 69 | if (connect_client(client->network.fd, client->network.s_in) == ERROR) 70 | return (ERROR); 71 | client = set_value(client); 72 | return (SUCCESS); 73 | } 74 | -------------------------------------------------------------------------------- /src/network_server.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include "network.h" 24 | 25 | int init_bind(int fd, struct sockaddr_in *s_in) 26 | { 27 | if (bind(fd, (const struct sockaddr *)s_in, sizeof(*s_in)) == SOCK_ERR) 28 | { 29 | if (close(fd) == CLOSE_ERR) 30 | return (error("close failed after bind failed")); 31 | return (ERROR); 32 | } 33 | return (SUCCESS); 34 | } 35 | 36 | int to_listen(int fd, int nb) 37 | { 38 | if (listen(fd, nb) == SOCK_ERR) 39 | { 40 | if (close(fd) == CLOSE_ERR) 41 | return (error("close failed after listen failed")); 42 | return (error("listen failed")); 43 | } 44 | return (SUCCESS); 45 | } 46 | 47 | int to_accept(int fd) 48 | { 49 | int client_fd; 50 | struct sockaddr_in sin; 51 | socklen_t s_size; 52 | 53 | s_size = sizeof(sin); 54 | if ((client_fd = accept(fd, (struct sockaddr *)&sin, &s_size)) == ERROR) 55 | { 56 | if (close(fd) == CLOSE_ERR) 57 | return (error("close failed after accept failed")); 58 | return (error("accept failed")); 59 | } 60 | return (client_fd); 61 | } 62 | 63 | int init_server(t_network *network, int port, int nb) 64 | { 65 | int opt; 66 | 67 | if ((network->pe = getprotobyname("TCP")) == NULL) 68 | return (error("getprotobyname failed")); 69 | if ((network->fd = socket(AF_INET, SOCK_STREAM, 70 | network->pe->p_proto)) == SOCK_ERR) 71 | return (error("socket failed")); 72 | init_struct(&(network->s_in), port, NULL); 73 | opt = 1; 74 | if (setsockopt(network->fd, SOL_SOCKET, SO_REUSEADDR, 75 | &opt, sizeof(opt)) == SOCK_ERR) 76 | { 77 | if (close(network->fd) == CLOSE_ERR) 78 | return (error("close failed after setsockopt failed")); 79 | return (error("setsockopt failed")); 80 | } 81 | if (init_bind(network->fd, &(network->s_in)) == ERROR) 82 | return (ERROR); 83 | if (to_listen(network->fd, nb) == ERROR) 84 | return (ERROR); 85 | return (SUCCESS); 86 | } 87 | 88 | int init_ringbuffer(t_server *server, int nb) 89 | { 90 | int i; 91 | 92 | if ((server->clientbuffer = malloc(sizeof(t_ringbuffer *) * nb)) == NULL) 93 | return (ERROR); 94 | for (i = 0; i < nb; ++i) 95 | if ((server->clientbuffer[i] = init_buffer(10, 512)) == NULL) 96 | return (ERROR); 97 | return (SUCCESS); 98 | } 99 | -------------------------------------------------------------------------------- /src/ringbuffer.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include "ringbuffer.h" 24 | 25 | /* 26 | ** Initialization of ring buffer 27 | ** the size_t max is about the number of slots to open 28 | ** the size_t size is about the size of one slot 29 | */ 30 | t_ringbuffer *init_buffer(size_t max, size_t size) 31 | { 32 | t_ringbuffer *buffer; 33 | 34 | if ((buffer = malloc(sizeof(t_ringbuffer))) == NULL) 35 | return (NULL); 36 | if ((buffer->buffer = malloc(sizeof(char) * (max * size))) == NULL) 37 | return (NULL); 38 | buffer->max = max; 39 | buffer->cap = size; 40 | buffer->count = 0; 41 | buffer->end = 0; 42 | buffer->start = 0; 43 | return (buffer); 44 | } 45 | 46 | /* 47 | ** Add char* to the actual buffer if there is a slot open 48 | */ 49 | void add_item(t_ringbuffer *buffer, char *item) 50 | { 51 | unsigned int i; 52 | unsigned int next; 53 | 54 | if (!buffer) 55 | return ; 56 | if (buffer->count >= buffer->max) 57 | return ; 58 | for (i = 0; i < strlen(item); ++ i) 59 | { 60 | if (item[i] == '\n') 61 | buffer->count += 1; 62 | next = (unsigned int)(buffer->start + 1) % (buffer->cap * buffer->max); 63 | if (next != buffer->end) 64 | { 65 | buffer->buffer[buffer->start] = item[i]; 66 | buffer->start += 1; 67 | } 68 | } 69 | } 70 | 71 | /* 72 | ** This function returns a char* of characters of the buffer until the delim character 73 | */ 74 | char *get_item(t_ringbuffer *buf, char delim) 75 | { 76 | unsigned int idx; 77 | unsigned int size; 78 | char *tmp; 79 | 80 | if (buffer_status(buf) == EMPTY) 81 | return (NULL); 82 | size = 0; 83 | for (idx = buf->end; buf->buffer[idx] != delim 84 | && idx < buf->max * buf->cap; ++idx) 85 | size++; 86 | if (size == buf->max * buf->cap) 87 | return (NULL); 88 | if ((tmp = malloc(sizeof(char) * (size + 1))) == NULL) 89 | return (NULL); 90 | for (idx = 0; idx < size; ++idx) 91 | { 92 | tmp[idx] = buf->buffer[buf->end]; 93 | buf->end = (unsigned int)(buf->end + 1 % (buf->max * buf->cap)); 94 | } 95 | tmp[idx] = '\0'; 96 | if (buf->buffer[buf->end] == delim) 97 | buf->end = (unsigned int)(buf->end + 1 % (buf->max * buf->cap)); 98 | buf->count -= 1; 99 | return (tmp); 100 | } 101 | 102 | void free_buffer(t_ringbuffer *buf) 103 | { 104 | if (buf->buffer) 105 | free(buf->buffer); 106 | free(buf); 107 | } 108 | 109 | /* 110 | ** Return the actual buffer's status 111 | */ 112 | int buffer_status(t_ringbuffer *buf) 113 | { 114 | if (!buf) 115 | return (ERROR); 116 | if (buf->count == 0) 117 | return (EMPTY); 118 | else if (buf->start + 1 == buf->end) 119 | return (FULL); 120 | else 121 | return (OK); 122 | return (OK); 123 | } 124 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015 Emeline Gaulard 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #include "network.h" 24 | 25 | int check_slot(t_server *server) 26 | { 27 | if (server->actual < server->max) 28 | return (SUCCESS); 29 | return (ERROR); 30 | } 31 | 32 | int fill_slot(t_server *server) 33 | { 34 | int ret; 35 | 36 | ret = 0; 37 | if (check_slot(server) == ERROR) 38 | return (ERROR); 39 | server->clientfds[server->actual].events = POLLIN | POLLOUT; 40 | server->clientfds[server->actual].revents = 0; 41 | server->clientbuffer[server->actual] = init_buffer(10, 512); 42 | server->actual += 1; 43 | if ((ret = send(server->clientfds[server->actual - 1].fd, "BIENVENUE\n", 44 | strlen("BIENVENUE\n"), 0)) == ERROR) 45 | return (error("send welcome message failed")); 46 | return (SUCCESS); 47 | } 48 | 49 | int close_server(t_server *server) 50 | { 51 | int i; 52 | 53 | if (!server) 54 | return (ERROR); 55 | for (i = 0; i < server->max; ++i) 56 | { 57 | if (i < server->actual) 58 | { 59 | if (close(server->clientfds[i].fd) == CLOSE_ERR) 60 | return (error("Closing fd on close_server() failed")); 61 | } 62 | free_buffer(server->clientbuffer[i]); 63 | } 64 | free(server); 65 | return (SUCCESS); 66 | } 67 | 68 | int close_client(t_client *client) 69 | { 70 | if (!client) 71 | return (ERROR); 72 | if (close(client->server.fd) == CLOSE_ERR) 73 | return (error("Closing client fd failed")); 74 | free_buffer(client->buffer); 75 | while (list_is_empty(client->to_send) == FALSE) 76 | list_del_elem_at_back(&(client->to_send)); 77 | if (client) 78 | free(client); 79 | return (SUCCESS); 80 | } 81 | 82 | int get_index(t_server *server, int fd) 83 | { 84 | int i; 85 | 86 | for (i = 0; i <= server->actual; ++i) 87 | { 88 | if (server->clientfds[i].fd == fd) 89 | return (i); 90 | } 91 | return (-1); 92 | } 93 | --------------------------------------------------------------------------------