From 01438bd1be578c3b43c9ad29b0a2d6707ee122b8 Mon Sep 17 00:00:00 2001 From: "Mr. Goblin" Date: Sat, 19 Sep 2026 19:09:11 +0300 Subject: all files are in root; changed help message --- Makefile | 46 ++++++++++++++ btasktd.1 | 3 +- btasktd.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++ cliflags.c | 94 +++++++++++++++++++++++++++ cliflags.h | 75 ++++++++++++++++++++++ db.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ db.h | 59 +++++++++++++++++ dist.sh | 7 -- src/Makefile | 37 ----------- src/btasktd.c | 189 ------------------------------------------------------ src/cliflags.c | 94 --------------------------- src/cliflags.h | 75 ---------------------- src/db.c | 198 --------------------------------------------------------- src/db.h | 59 ----------------- 14 files changed, 660 insertions(+), 660 deletions(-) create mode 100644 Makefile create mode 100644 btasktd.c create mode 100644 cliflags.c create mode 100644 cliflags.h create mode 100644 db.c create mode 100644 db.h delete mode 100755 dist.sh delete mode 100644 src/Makefile delete mode 100644 src/btasktd.c delete mode 100644 src/cliflags.c delete mode 100644 src/cliflags.h delete mode 100644 src/db.c delete mode 100644 src/db.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6def93e --- /dev/null +++ b/Makefile @@ -0,0 +1,46 @@ +# Copyright (c) 2026, Mr. Goblin +# +# SPDX-License-Identifier: BSD-2-Clause + +# CC = cc -fno-caret-diagnostics -fno-color-diagnostics +CC = gcc -fno-diagnostics-show-caret -fdiagnostics-color=never +# CC = gcc +CFLAGS = -Wall -Wextra -pedantic -std=c99 + +# DEBUG = -g +# DEBUG = -ggdb +DEBUG = + +# STATIC = -static +STATIC = -static -s +# STATIC = + +PROG_NAME=btasktd +VER=0.0.0 +DIST_NAME=$(PROG_NAME)-$(VER) + + +MAINBINARIES = btasktd + +.SUFFIXES: +.SUFFIXES: .c .o + +all: $(MAINBINARIES) + +dist: + git archive --format=tar --prefix=$(DIST_NAME)/ HEAD | \ + bzip2 > $(DIST_NAME).tar.bz2 + +clean: + rm -f $(MAINBINARIES) *.o *.test + +.c.o: + $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ + + +BTASKTD_OBJECTS = btasktd.o cliflags.o +BTASKTD_LIBS = -lc + +btasktd: $(BTASKTD_OBJECTS) + $(CC) $(DEBUG) $(CFLAGS) $(STATIC) $(BTASKTD_OBJECTS) -o $@ \ + $(BTASKTD_LIBS) diff --git a/btasktd.1 b/btasktd.1 index e354724..d7ee07c 100644 --- a/btasktd.1 +++ b/btasktd.1 @@ -27,11 +27,12 @@ Show help message .It Fl p Ar port Set port for server to listen to .It Fl u Ar users -Set max clients count +Set max connected clients count .El . .Sh AUTHORS .An Mr. Goblin +.Aq Lk http://mrgoblin.net . .Sh LICENSE .Nm diff --git a/btasktd.c b/btasktd.c new file mode 100644 index 0000000..81100bf --- /dev/null +++ b/btasktd.c @@ -0,0 +1,186 @@ +/*- + * Copyright (c) 2026, Mr. Goblin + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cliflags.h" + +#define BTASKTD_HELP_STR \ + "Copyright (c) 2026 Mr. Goblin\n" \ + "btasktd - task tracking TCP-server\n" \ + "Usage: btasktd [-Vh] [-p port] [-u users]\n" \ + "For more info read program's man page\n" + +#define BTASKTD_VERSION_STR \ + "0.0.0" + +#ifndef BTASKTD_QUEUE_LEN +# define BTASKTD_QUEUE_LEN 16 +#endif + +static void +fprint_help(FILE *f) +{ + fputs(BTASKTD_HELP_STR, f); +} + +static void +set_nonblock(int fd) +{ + int fflags = fcntl(fd, F_GETFL); + fcntl(fd, F_SETFL, fflags|O_NONBLOCK); +} + +int +main(int argc, char **argv) +{ + int server_fd, opt = 1, res, port, passed_flags = 1, users_cnt; + int *users = NULL; + struct sockaddr_in addr = {0}; + struct int_flag_val int_res; + struct bool_flag_val show_ver, show_help; + + show_ver = extract_bool_flag('V', argc, argv); + if (fvr_ok == show_ver.code && show_ver.data) { + printf("btasktd version %s\n", BTASKTD_VERSION_STR); + return 0; + } + + show_help = extract_bool_flag('h', argc, argv); + if (show_help.code == fvr_ok && show_help.data) { + fprint_help(stdout); + return 0; + } + + int_res = extract_int_flag('p', argc, argv); + switch (int_res.code) { + case fvr_not_found: +# ifdef BTASKTD_DEFAULT_PORT + port = BTASKTD_DEFAULT_PORT; +# else + fputs("No port specified!\n", stderr); + passed_flags = 0; +# endif + break; + case fvr_ok: + port = int_res.data; + if (port > 0) + break; + /* fallthrough */ + case fvr_invalid: + fputs("Invalid port!\n", stderr); + return 1; + break; + } + + int_res = extract_int_flag('u', argc, argv); + switch (int_res.code) { + case fvr_not_found: +# ifdef BTASKTD_DEFAULT_USERS_CNT + users_cnt = BTASKTD_DEFAULT_USERS_CNT; +# else + fputs("No users count specified!\n", stderr); + passed_flags = 0; +# endif + break; + case fvr_ok: + users_cnt = int_res.data; + if (users_cnt > 0) + break; + /* fallthrough */ + case fvr_invalid: + fputs("Invalid users count!\n", stderr); + return 1; + break; + } + + if (!passed_flags) { + fputs("-\n", stderr); + fprint_help(stderr); + return 1; + } + + users = (int*)malloc(users_cnt * sizeof(int)); + if (NULL == users) { + fputs("No memory!\n", stderr); + return 1; + } + + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + free(users); + perror("socket"); + return 1; + } + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + res = bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)); + if (0 != res) { + close(server_fd); + free(users); + perror("bind"); + return 1; + } + res = listen(server_fd, BTASKTD_QUEUE_LEN); + if (0 != res) { + close(server_fd); + free(users); + perror("listen"); + return 1; + } + res = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, + &opt, sizeof(opt)); + if (0 != res) { + close(server_fd); + free(users); + perror("setsockopt"); + return 1; + } + + set_nonblock(server_fd); + printf("btaskt server btasktd started on port %d\n", port); + + /* main loop here */ + + printf("btaskt server btasktd stopped\n"); + close(server_fd); + free(users); + return 0; +} diff --git a/cliflags.c b/cliflags.c new file mode 100644 index 0000000..e3ff7f2 --- /dev/null +++ b/cliflags.c @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 2026, Mr. Goblin + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include +#include + +#include "cliflags.h" + +/* -f */ +struct bool_flag_val +extract_bool_flag(char flagletter, int argc, char **argv) +{ + struct bool_flag_val res = {0}; + char flagstr[3] = { '-', ' ', '\0' }; + int i; + flagstr[1] = flagletter; + res.code = fvr_not_found; + res.data = 0; + for (i = 1; i < argc; i++) { + if (0 == strcmp(flagstr, argv[i])) { + res.code = fvr_ok; + res.data = 1; + break; + } + } + return res; +} + +/* -f the_str */ +struct str_flag_val +extract_str_flag(char flagletter, int argc, char **argv) +{ + struct str_flag_val res = {0}; + char flagstr[3] = { '-', ' ', '\0' }; + int i; + flagstr[1] = flagletter; + for (i = 1; i < argc; i++) + if (0 == strcmp(flagstr, argv[i])) + break; + if (argc <= i) { + res.code = fvr_not_found; + } else if (argc-1 == i) { + res.code = fvr_invalid; + } else { + res.code = fvr_ok; + res.data = argv[i+1]; + } + return res; +} + +/* -f number */ +struct int_flag_val +extract_int_flag(char flagletter, int argc, char **argv) +{ + struct int_flag_val res; + struct str_flag_val strres = + extract_str_flag(flagletter, argc, argv); + char *endptr; + res.code = strres.code; + if (fvr_ok != res.code) { + return res; + } + res.data = strtol(strres.data, &endptr, 10); + if ('\0' != *endptr) + res.code = fvr_invalid; + return res; +} diff --git a/cliflags.h b/cliflags.h new file mode 100644 index 0000000..5bf251b --- /dev/null +++ b/cliflags.h @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 2026, Mr. Goblin + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifndef BTASKTD_CLIFLAGS_H_SENTRY +#define BTASKTD_CLIFLAGS_H_SENTRY +#ifdef __cplusplus +extern "C" { +#endif + +enum flag_val_res { + fvr_ok = 0, + fvr_min = fvr_ok, + fvr_not_found, + fvr_invalid, + fvr_max = fvr_invalid +}; + +struct str_flag_val { + enum flag_val_res code; + char *data; +}; + +struct int_flag_val { + enum flag_val_res code; + int data; +}; + +struct bool_flag_val { + enum flag_val_res code; + int data; +}; + +/* -f */ +struct bool_flag_val +extract_bool_flag(char flagletter, int argc, char **argv); + +/* -f the_str */ +struct str_flag_val +extract_str_flag(char flagletter, int argc, char **argv); + +/* -f number */ +struct int_flag_val +extract_int_flag(char flagletter, int argc, char **argv); + +#ifdef __cplusplus +} +#endif +#endif /* BTASKTD_CLIFLAGS_H_SENTRY */ diff --git a/db.c b/db.c new file mode 100644 index 0000000..c547013 --- /dev/null +++ b/db.c @@ -0,0 +1,198 @@ +/*- + * Copyright (c) 2026, Mr. Goblin + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "db.h" + +#ifndef PATH_MAX +# define PATH_MAX 4096 +#endif + +#ifndef NAME_MAX +# define NAME_MAX 255 +#endif + +#define DIR_NAME_BUF_SIZE (NAME_MAX+1) + + +static const char * +find_chr_or_zero(const char *s, char ch) +{ + while (*s && *s != ch) + s++; + return s; +} + +static const char * +find_chr_or_zero_n(const char *s, char ch, int n) +{ + int i = 0; + while (i < n && *s && *s != ch) { + s++; + i++; + } + return s; +} + +static struct db_value_int +does_dir_exist(const char *path) +{ + struct db_value_int res = {0}; + struct stat st = {0}; + int code; + res.code = dbe_ok; + res.data = 1; + code = stat(path, &st); + if (0 != code) { + if (ENOENT == errno) + res.data = 0; + else if (EACCES == errno) + res.code = dbe_access; + else + res.code = dbe_unknown; + } else { + res.data = S_IFDIR == (st.st_mode & S_IFMT); + } + return res; +} + +static enum db_error +make_dir_ifne(const char *path, int rights) +{ + struct db_value_int val = {0}; + int code; + val = does_dir_exist(path); + if (dbe_ok != val.code) + return val.code; + else if (val.data) + return dbe_ok; + code = mkdir(path, rights); + if (code != 0) { + if (EACCES == errno) + return dbe_access; + else if (EEXIST == errno) + return dbe_notdir; + } + return dbe_ok; +} + +static enum db_error +do_make_dir_path(const char *path, int rights) +{ + char buf[DIR_NAME_BUF_SIZE] = {0}; + const char *p = find_chr_or_zero(path, '/'); + unsigned sz = p - path + 1, code; + if (sizeof(buf) < sz) + return dbe_inval; + strncpy(buf, path, sz); + buf[sz-1] = '\0'; + code = make_dir_ifne(buf, rights); + if (dbe_ok != code) + return code; + if (*p) { + code = chdir(buf); + if (0 != code) + return dbe_access; + code = do_make_dir_path(p+1, rights); + if (dbe_ok != code) + return code; + code = chdir(".."); + if (0 != code) + return dbe_access; + } + return dbe_ok; +} + +/* mkdir -p */ +enum db_error +make_dir_path(const char *path, int rights) +{ + return do_make_dir_path(path, rights); +} + +/* ==================================================================== */ + +#ifdef BTASKTD_DB_TEST + +#include + +#define TEST_CODE(code) \ + do { \ + const char *s = NULL; \ + switch (code) { \ + case dbe_ok: s = "NO_ERROR"; break; \ + case dbe_notdir: s = "NOT_DIR"; break; \ + case dbe_inval: s = "INV_INPUT"; break; \ + case dbe_access: s = "ACCESS"; break; \ + default: s = "UNKNOWN"; \ + } \ + fprintf(stderr, "%s\n", s); \ + } while (0) + + +int +main(void) +{ + int i, pid; + const char *path = "test_db/super_test/mtest"; + for (i = 0; i < 10; i++) + TEST_CODE(make_dir_path(path, 0777)); + pid = fork(); + if (-1 == pid) { + fprintf(stderr, "can't fork\n"); + return 1; + } else if (0 == pid) { + execlp("ls", "ls", "-laR", NULL); + _exit(128); + } else { + wait(NULL); + } + pid = fork(); + if (-1 == pid) { + fprintf(stderr, "can't fork\n"); + return 1; + } else if (0 == pid) { + execlp("rm", "rm", "-rf", "test_db", NULL); + _exit(127); + } else { + wait(NULL); + } + return 0; +} + +#endif diff --git a/db.h b/db.h new file mode 100644 index 0000000..ebb42c5 --- /dev/null +++ b/db.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2026, Mr. Goblin + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifndef BTASKT_DB_H_SENTRY +#define BTASKT_DB_H_SENTRY +#ifdef __cplusplus +extern "C" { +#endif + +enum db_error { + dbe_ok = 0, + dbe_min = dbe_ok, + dbe_notdir, + dbe_inval, + dbe_access, + dbe_unknown, + dbe_max = dbe_unknown +}; + +struct db_value_int { + enum db_error code; + int data; +}; + +/* mkdir -p */ +enum db_error +make_dir_path(const char *path, int rights); + +#ifdef __cplusplus +} +#endif +#endif /* BTASKT_DB_H_SENTRY */ diff --git a/dist.sh b/dist.sh deleted file mode 100755 index cb05b36..0000000 --- a/dist.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -PROG_NAME="btasktd" -VER="0.0.0" -DIST_NAME="$PROG_NAME-$VER" - -git archive --format=tar --prefix="$DIST_NAME/" HEAD | bzip2 > "$DIST_NAME.tar.bz2" diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index c09b5a5..0000000 --- a/src/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) 2026, Mr. Goblin -# -# SPDX-License-Identifier: BSD-2-Clause - -# CC = cc -fno-caret-diagnostics -fno-color-diagnostics -CC = gcc -fno-diagnostics-show-caret -fdiagnostics-color=never -# CC = gcc -CFLAGS = -Wall -Wextra -pedantic -std=c99 - -# DEBUG = -g -# DEBUG = -ggdb -DEBUG = - -# STATIC = -static -STATIC = -static -s -# STATIC = - -MAINBINARIES = btasktd - -.SUFFIXES: -.SUFFIXES: .c .o - -all: $(MAINBINARIES) - -clean: - rm -f $(MAINBINARIES) *.o *.test - -.c.o: - $(CC) $(DEBUG) $(CFLAGS) -c $< -o $@ - - -BTASKTD_OBJECTS = btasktd.o cliflags.o -BTASKTD_LIBS = -lc - -btasktd: $(BTASKTD_OBJECTS) - $(CC) $(DEBUG) $(CFLAGS) $(STATIC) $(BTASKTD_OBJECTS) -o $@ \ - $(BTASKTD_LIBS) diff --git a/src/btasktd.c b/src/btasktd.c deleted file mode 100644 index 9878a3d..0000000 --- a/src/btasktd.c +++ /dev/null @@ -1,189 +0,0 @@ -/*- - * Copyright (c) 2026, Mr. Goblin - * - * SPDX-License-Identifier: BSD-2-Clause - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT - * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cliflags.h" - -#define BTASKTD_HELP_STR \ - "btasktd - task tracking TCP-server\n" \ - "flags:\n" \ - " -p PORT\n" \ - " sets the port server should listen to\n" \ - " -h\n" \ - " prints the help message (the server won't start!)\n" \ - " -V\n" \ - " prints version (the server won't start!)\n" - -#define BTASKTD_VERSION_STR \ - "0.0.0" - -#ifndef BTASKTD_QUEUE_LEN -# define BTASKTD_QUEUE_LEN 16 -#endif - -static void -fprint_help(FILE *f) -{ - fputs(BTASKTD_HELP_STR, f); -} - -static void -set_nonblock(int fd) -{ - int fflags = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, fflags|O_NONBLOCK); -} - -int -main(int argc, char **argv) -{ - int server_fd, opt = 1, res, port, passed_flags = 1, users_cnt; - int *users = NULL; - struct sockaddr_in addr = {0}; - struct int_flag_val int_res; - struct bool_flag_val show_ver, show_help; - - show_ver = extract_bool_flag('V', argc, argv); - if (fvr_ok == show_ver.code && show_ver.data) { - printf("btasktd version %s\n", BTASKTD_VERSION_STR); - return 0; - } - - show_help = extract_bool_flag('h', argc, argv); - if (show_help.code == fvr_ok && show_help.data) { - fprint_help(stdout); - return 0; - } - - int_res = extract_int_flag('p', argc, argv); - switch (int_res.code) { - case fvr_not_found: -# ifdef BTASKTD_DEFAULT_PORT - port = BTASKTD_DEFAULT_PORT; -# else - fputs("No port specified!\n", stderr); - passed_flags = 0; -# endif - break; - case fvr_ok: - port = int_res.data; - if (port > 0) - break; - /* fallthrough */ - case fvr_invalid: - fputs("Invalid port!\n", stderr); - return 1; - break; - } - - int_res = extract_int_flag('u', argc, argv); - switch (int_res.code) { - case fvr_not_found: -# ifdef BTASKTD_DEFAULT_USERS_CNT - users_cnt = BTASKTD_DEFAULT_USERS_CNT; -# else - fputs("No users count specified!\n", stderr); - passed_flags = 0; -# endif - break; - case fvr_ok: - users = int_res.data; - if (users > 0) - break; - /* fallthrough */ - case fvr_invalid: - fputs("Invalid users count!\n", stderr); - return 1; - break; - } - - if (!passed_flags) { - fprint_help(stderr); - return 1; - } - - users = (int*)malloc(users_cnt * sizeof(int)); - if (NULL == users) { - fputs("No memory!\n", stderr); - return 1; - } - - server_fd = socket(AF_INET, SOCK_STREAM, 0); - if (server_fd < 0) { - free(users); - perror("socket"); - return 1; - } - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - res = bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)); - if (0 != res) { - close(server_fd); - free(users); - perror("bind"); - return 1; - } - res = listen(server_fd, BTASKTD_QUEUE_LEN); - if (0 != res) { - close(server_fd); - free(users); - perror("listen"); - return 1; - } - res = setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, - &opt, sizeof(opt)); - if (0 != res) { - close(server_fd); - free(users); - perror("setsockopt"); - return 1; - } - - set_nonblock(server_fd); - printf("btaskt server btasktd started on port %d\n", port); - - /* main loop here */ - - printf("btaskt server btasktd stopped\n"); - close(server_fd); - free(users); - return 0; -} diff --git a/src/cliflags.c b/src/cliflags.c deleted file mode 100644 index e3ff7f2..0000000 --- a/src/cliflags.c +++ /dev/null @@ -1,94 +0,0 @@ -/*- - * Copyright (c) 2026, Mr. Goblin - * - * SPDX-License-Identifier: BSD-2-Clause - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT - * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#include -#include - -#include "cliflags.h" - -/* -f */ -struct bool_flag_val -extract_bool_flag(char flagletter, int argc, char **argv) -{ - struct bool_flag_val res = {0}; - char flagstr[3] = { '-', ' ', '\0' }; - int i; - flagstr[1] = flagletter; - res.code = fvr_not_found; - res.data = 0; - for (i = 1; i < argc; i++) { - if (0 == strcmp(flagstr, argv[i])) { - res.code = fvr_ok; - res.data = 1; - break; - } - } - return res; -} - -/* -f the_str */ -struct str_flag_val -extract_str_flag(char flagletter, int argc, char **argv) -{ - struct str_flag_val res = {0}; - char flagstr[3] = { '-', ' ', '\0' }; - int i; - flagstr[1] = flagletter; - for (i = 1; i < argc; i++) - if (0 == strcmp(flagstr, argv[i])) - break; - if (argc <= i) { - res.code = fvr_not_found; - } else if (argc-1 == i) { - res.code = fvr_invalid; - } else { - res.code = fvr_ok; - res.data = argv[i+1]; - } - return res; -} - -/* -f number */ -struct int_flag_val -extract_int_flag(char flagletter, int argc, char **argv) -{ - struct int_flag_val res; - struct str_flag_val strres = - extract_str_flag(flagletter, argc, argv); - char *endptr; - res.code = strres.code; - if (fvr_ok != res.code) { - return res; - } - res.data = strtol(strres.data, &endptr, 10); - if ('\0' != *endptr) - res.code = fvr_invalid; - return res; -} diff --git a/src/cliflags.h b/src/cliflags.h deleted file mode 100644 index 5bf251b..0000000 --- a/src/cliflags.h +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 2026, Mr. Goblin - * - * SPDX-License-Identifier: BSD-2-Clause - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT - * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#ifndef BTASKTD_CLIFLAGS_H_SENTRY -#define BTASKTD_CLIFLAGS_H_SENTRY -#ifdef __cplusplus -extern "C" { -#endif - -enum flag_val_res { - fvr_ok = 0, - fvr_min = fvr_ok, - fvr_not_found, - fvr_invalid, - fvr_max = fvr_invalid -}; - -struct str_flag_val { - enum flag_val_res code; - char *data; -}; - -struct int_flag_val { - enum flag_val_res code; - int data; -}; - -struct bool_flag_val { - enum flag_val_res code; - int data; -}; - -/* -f */ -struct bool_flag_val -extract_bool_flag(char flagletter, int argc, char **argv); - -/* -f the_str */ -struct str_flag_val -extract_str_flag(char flagletter, int argc, char **argv); - -/* -f number */ -struct int_flag_val -extract_int_flag(char flagletter, int argc, char **argv); - -#ifdef __cplusplus -} -#endif -#endif /* BTASKTD_CLIFLAGS_H_SENTRY */ diff --git a/src/db.c b/src/db.c deleted file mode 100644 index c547013..0000000 --- a/src/db.c +++ /dev/null @@ -1,198 +0,0 @@ -/*- - * Copyright (c) 2026, Mr. Goblin - * - * SPDX-License-Identifier: BSD-2-Clause - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT - * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "db.h" - -#ifndef PATH_MAX -# define PATH_MAX 4096 -#endif - -#ifndef NAME_MAX -# define NAME_MAX 255 -#endif - -#define DIR_NAME_BUF_SIZE (NAME_MAX+1) - - -static const char * -find_chr_or_zero(const char *s, char ch) -{ - while (*s && *s != ch) - s++; - return s; -} - -static const char * -find_chr_or_zero_n(const char *s, char ch, int n) -{ - int i = 0; - while (i < n && *s && *s != ch) { - s++; - i++; - } - return s; -} - -static struct db_value_int -does_dir_exist(const char *path) -{ - struct db_value_int res = {0}; - struct stat st = {0}; - int code; - res.code = dbe_ok; - res.data = 1; - code = stat(path, &st); - if (0 != code) { - if (ENOENT == errno) - res.data = 0; - else if (EACCES == errno) - res.code = dbe_access; - else - res.code = dbe_unknown; - } else { - res.data = S_IFDIR == (st.st_mode & S_IFMT); - } - return res; -} - -static enum db_error -make_dir_ifne(const char *path, int rights) -{ - struct db_value_int val = {0}; - int code; - val = does_dir_exist(path); - if (dbe_ok != val.code) - return val.code; - else if (val.data) - return dbe_ok; - code = mkdir(path, rights); - if (code != 0) { - if (EACCES == errno) - return dbe_access; - else if (EEXIST == errno) - return dbe_notdir; - } - return dbe_ok; -} - -static enum db_error -do_make_dir_path(const char *path, int rights) -{ - char buf[DIR_NAME_BUF_SIZE] = {0}; - const char *p = find_chr_or_zero(path, '/'); - unsigned sz = p - path + 1, code; - if (sizeof(buf) < sz) - return dbe_inval; - strncpy(buf, path, sz); - buf[sz-1] = '\0'; - code = make_dir_ifne(buf, rights); - if (dbe_ok != code) - return code; - if (*p) { - code = chdir(buf); - if (0 != code) - return dbe_access; - code = do_make_dir_path(p+1, rights); - if (dbe_ok != code) - return code; - code = chdir(".."); - if (0 != code) - return dbe_access; - } - return dbe_ok; -} - -/* mkdir -p */ -enum db_error -make_dir_path(const char *path, int rights) -{ - return do_make_dir_path(path, rights); -} - -/* ==================================================================== */ - -#ifdef BTASKTD_DB_TEST - -#include - -#define TEST_CODE(code) \ - do { \ - const char *s = NULL; \ - switch (code) { \ - case dbe_ok: s = "NO_ERROR"; break; \ - case dbe_notdir: s = "NOT_DIR"; break; \ - case dbe_inval: s = "INV_INPUT"; break; \ - case dbe_access: s = "ACCESS"; break; \ - default: s = "UNKNOWN"; \ - } \ - fprintf(stderr, "%s\n", s); \ - } while (0) - - -int -main(void) -{ - int i, pid; - const char *path = "test_db/super_test/mtest"; - for (i = 0; i < 10; i++) - TEST_CODE(make_dir_path(path, 0777)); - pid = fork(); - if (-1 == pid) { - fprintf(stderr, "can't fork\n"); - return 1; - } else if (0 == pid) { - execlp("ls", "ls", "-laR", NULL); - _exit(128); - } else { - wait(NULL); - } - pid = fork(); - if (-1 == pid) { - fprintf(stderr, "can't fork\n"); - return 1; - } else if (0 == pid) { - execlp("rm", "rm", "-rf", "test_db", NULL); - _exit(127); - } else { - wait(NULL); - } - return 0; -} - -#endif diff --git a/src/db.h b/src/db.h deleted file mode 100644 index ebb42c5..0000000 --- a/src/db.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * Copyright (c) 2026, Mr. Goblin - * - * SPDX-License-Identifier: BSD-2-Clause - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT - * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - */ - -#ifndef BTASKT_DB_H_SENTRY -#define BTASKT_DB_H_SENTRY -#ifdef __cplusplus -extern "C" { -#endif - -enum db_error { - dbe_ok = 0, - dbe_min = dbe_ok, - dbe_notdir, - dbe_inval, - dbe_access, - dbe_unknown, - dbe_max = dbe_unknown -}; - -struct db_value_int { - enum db_error code; - int data; -}; - -/* mkdir -p */ -enum db_error -make_dir_path(const char *path, int rights); - -#ifdef __cplusplus -} -#endif -#endif /* BTASKT_DB_H_SENTRY */ -- cgit v1.3