diff --git a/Makefile b/Makefile index 564a4c8..6780bed 100644 --- a/Makefile +++ b/Makefile @@ -34,8 +34,9 @@ $(NAME): $(OBJS) $(CC) $(CFLAGS) $(OBJS) -o $(NAME) $(LIB) $(LFLAGS) coverage: + make -C lib fclean test make -C tests fclean coverage - gcov -o src/ src/args.c + gcov -o src/ $(SRCS) doc: doxygen docs/doxyfile diff --git a/inc/launch_server.h b/inc/launch_server.h new file mode 100644 index 0000000..c483624 --- /dev/null +++ b/inc/launch_server.h @@ -0,0 +1,22 @@ +/*********************************** LICENSE **********************************\ +* Copyright 2017 Morphux * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +\******************************************************************************/ + +#ifndef LAUNCH_SERVER_H +# define LAUNCH_SERVER_H + +void launch_server(void); + +#endif diff --git a/lib b/lib index 5268bdf..d669289 160000 --- a/lib +++ b/lib @@ -1 +1 @@ -Subproject commit 5268bdf6830c736b19fe93a3ae49735240302695 +Subproject commit d669289ca641ddeba99af37c586e727c95ef0e9d diff --git a/src/args.c b/src/args.c index de75a28..95c59c7 100644 --- a/src/args.c +++ b/src/args.c @@ -31,23 +31,29 @@ typedef struct flags_s { * Default: true */ bool daemonize; + + /** + * If defined, don't output anything. + * Overrides all logging and output flags + * Default: false + */ bool quiet; /** * Flag that will define the port * to listen on. - * Default: 6694 + * Default: 5982 */ u32_t port; /** - * Path of the specified log file, if defined + * Path of the specified log file, if defined. * Default: NULL */ char *pid_file; /** - * Path of the specifiedd PID file, if defined + * Path of the specified PID file, if defined. * Default: NULL */ char *log_file; @@ -58,7 +64,7 @@ static flags_t g_flags; void flags_init(void) { g_flags.verbose = 0; g_flags.daemonize = true; - g_flags.port = 6694; + g_flags.port = 5982; g_flags.pid_file = NULL; g_flags.log_file = NULL; } @@ -112,13 +118,20 @@ u32_t flags_get_port(void) { return g_flags.port; } -bool flags_set_verbose(const char *str) { +bool flags_inc_verbose(const char *str) { (void)str; if (g_flags.verbose < FLAGS_VERBOSE_MAX) g_flags.verbose++; return true; } +/* TODO HERE */ +bool flags_set_verbose(const char *str) { + if (str != NULL) + g_flags.port = strtoul(str, (char **)NULL, 10); + return true; +} + u8_t flags_get_verbose(void) { return g_flags.verbose; } diff --git a/src/builder.c b/src/builder.c index c40fba5..1d8684a 100644 --- a/src/builder.c +++ b/src/builder.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #ifndef COMPILE_WITH_TEST @@ -73,15 +74,31 @@ int main(int ac, char *av[]) { .desc = "Do not fork", .callback = &flags_set_nofork }, + { + .opt = 'q', + .s_opt = "quiet", + .desc = "Don't output anything", + .callback = &flags_set_quiet + }, + { + /* Same features as -d, but here because this is standard */ + .opt = 'v', + .desc = "Increase the verbose level (Up to 3)", + .callback = &flags_inc_verbose, + .usage = "-v|-vv|-vvv" + }, { .opt = 'd', - .desc = "Increase the debug level", + .desc = "Increase the verbose level (Up to 3)", + .callback = &flags_inc_verbose, + .usage = "-d|-dd|-ddd" }, { .opt = 'D', .s_opt = "set-debug-level", - .desc = "Set the debug level", + .desc = "Set the verbose level", .take_arg = true, + .callback = &flags_set_verbose, .usage = "[1-3]" }, { @@ -108,11 +125,6 @@ int main(int ac, char *av[]) { .callback = &flags_set_logfile, .usage = "LOG_FILE" }, - { - .opt = 'v', - .desc = "Increase the verbose level (Up to 3)", - .callback = &flags_set_verbose - }, ARGS_EOL }; mlist_t *params = NULL; @@ -132,6 +144,7 @@ int main(int ac, char *av[]) { if (flags_get_nofork() == true) daemonize(); + launch_server(); flags_cleanup(); return 0; } diff --git a/src/launch_server.c b/src/launch_server.c new file mode 100644 index 0000000..0b830c0 --- /dev/null +++ b/src/launch_server.c @@ -0,0 +1,135 @@ +/*********************************** LICENSE **********************************\ +* Copyright 2017 Morphux * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +\******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BACKLOG 10 /* How many pending connection we will keep in queue */ + +// get sockaddr, IPv4 or IPv6: +static void *get_in_addr(struct sockaddr *sa) +{ + if (!sa) + return NULL; + if (sa->sa_family == AF_INET) + { + return &(((struct sockaddr_in*)sa)->sin_addr); + } + + return &(((struct sockaddr_in6*)sa)->sin6_addr); +} + +void launch_server(void) { + int sockfd = 0, /* Read on this one */ + rem_fd = 0, /* Fd that will be attributed to the client */ + rval; /* To stock getaddrinfo() return */ + bool enable = 1; /* Int to enable the option in setsockopt */ + struct addrinfo hints, /* Flags of getaddrinfo() */ + *servinfo, /* Result of getaddrinfo() */ + *ptr; /* Variable used to loop into the linked lst*/ + char port_str[6]; /* Buffer to hold the port number */ + + struct sockaddr_storage rem_addr; /* Hold client infos */ + socklen_t sin_size = 0; /* Size of rem_addr */ + + char str[INET6_ADDRSTRLEN]; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; /* Don't care IPv4 and IPv6 */ + hints.ai_socktype = SOCK_STREAM; /* Use TCP stream socket */ + + /* Get port number as a string */ + snprintf(port_str, 6, "%d", flags_get_port()); + + if ((rval = getaddrinfo(NULL, port_str, &hints, &servinfo)) != 0) + { + /* Exit if getaddrinfo fails */ + m_panic("getaddrinfo failed : %s\n", gai_strerror(rval)); + } + + /* Now we will loop into the linked list */ + for (ptr = servinfo; ptr != NULL; ptr = ptr->ai_next) + { + /* Try to get a fd from node of linked list */ + if ((sockfd = socket(ptr->ai_family, + ptr->ai_socktype, ptr->ai_protocol)) == -1) + { + /* If it fails, display the error and try with the next struct */ + m_error("Server: socket %s" , strerror(errno)); + continue ; + } + /* If socket succeded, call setsockopt */ + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, + sizeof(int)) == -1) + { + /* If it fails, cleanup, display the error and exit */ + freeaddrinfo(servinfo); + m_panic("Server: setsockopt %s" , strerror(errno)); + } + /* If we got here, try to bind to the socket */ + if (bind(sockfd, ptr->ai_addr, ptr->ai_addrlen) == -1) + { + /* If it fails, display the error and try with the next struct */ + close(sockfd); + m_error("Server: bind %s" , strerror(errno)); + continue ; + } + /* If all that succeded, get out of the loop */ + break ; + } + /* Don't need this struct anymore */ + freeaddrinfo(servinfo); + + if (ptr == NULL) + { + /* Exit if we looked at all the stucts and bound on none */ + m_panic("Server: failed to bind"); + } + + if (listen(sockfd, BACKLOG) == -1) + { + /* Exit if listen() fails */ + m_panic("Server: listen %s" , strerror(errno)); + } + + m_info("Waiting for connections ...\n"); + + /* This is the main accept() loop */ + while (1) + { + sin_size = sizeof(rem_addr); + /* Try to get a fd for the client */ + if ((rem_fd = accept(sockfd, (struct sockaddr *)&rem_addr, + &sin_size)) == -1) + { + /* If it fails, try again */ + m_error("Server: accept %s", strerror); + continue ; + } + inet_ntop(rem_addr.ss_family, get_in_addr((struct sockaddr *)&rem_addr), + str, sizeof(str)); + m_info("Server: Got connection from %s\n", str); + } +} diff --git a/tests/Makefile b/tests/Makefile index fdd0866..9885832 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -20,13 +20,12 @@ CFLAGS = -Wall -Wextra -Wno-unused-result -g -O3 -I../lib/inc -I../inc -lmorphux SRCS = $(wildcard *.c) $(wildcard ../src/*.c) OBJS = $(SRCS:%.c=%.o) OSTYPE = $(shell uname) -COVFLAGS = "-coverage -lgcov" +COVFLAGS = -coverage -lgcov all: $(NAME) $(NAME): $(OBJS) - make -C ../lib clean test - $(CC) $(CFLAGS) $(OBJS) -o $(NAME) -L../lib/ -lmorphux + $(CC) $(CFLAGS) $(OBJS) -o $(NAME) -L../lib/ -lmorphux -ldl check: $(NAME) ./$(NAME) @@ -40,6 +39,8 @@ coverage: clean: rm -f $(OBJS) + rm -f *.gcda + rm -f *.gcno fclean: clean rm -f $(NAME) diff --git a/tests/test_args.c b/tests/test_args.c index 735814e..b57f8dd 100644 --- a/tests/test_args.c +++ b/tests/test_args.c @@ -4,7 +4,7 @@ TEST(flags_init) { flags_init(); TEST_ASSERT(flags_get_verbose() == 0, "Value is wrong"); TEST_ASSERT(flags_get_nofork() == true, "Value is wrong"); - TEST_ASSERT(flags_get_port() == 6694, "Value is wrong") + TEST_ASSERT(flags_get_port() == 5982, "Value is wrong") TEST_ASSERT(flags_get_logfile() == NULL, "Value is wrong"); TEST_ASSERT(flags_get_pidfile() == NULL, "Value is wrong"); return TEST_SUCCESS; @@ -32,7 +32,8 @@ TEST(flags_logfile) { flags_cleanup(); TEST_ASSERT(flags_get_logfile() == NULL, "Return value is wrong"); flags_set_logfile("Something"); - TEST_ASSERT(strcmp(flags_get_logfile(), "Something") == 0, "Return value is wrong"); + TEST_ASSERT(strcmp(flags_get_logfile(), "Something") == 0, + "Return value is wrong"); return TEST_SUCCESS; } @@ -40,7 +41,8 @@ TEST(flags_pidfile) { flags_cleanup(); TEST_ASSERT(flags_get_pidfile() == NULL, "Return value is wrong"); flags_set_pidfile("Something"); - TEST_ASSERT(strcmp(flags_get_pidfile(), "Something") == 0, "Return value is wrong"); + TEST_ASSERT(strcmp(flags_get_pidfile(), "Something") == 0, + "Return value is wrong"); return TEST_SUCCESS; } diff --git a/tests/test_server.c b/tests/test_server.c new file mode 100644 index 0000000..8ccc444 --- /dev/null +++ b/tests/test_server.c @@ -0,0 +1,16 @@ +/*********************************** LICENSE **********************************\ +* Copyright 2017 Morphux * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +\******************************************************************************/ +