aboutsummaryrefslogtreecommitdiff
path: root/btasktd.c
diff options
context:
space:
mode:
authorMr. Goblin <mrgoblin@mrgoblin.net>2026-09-19 19:09:11 +0300
committerMr. Goblin <mrgoblin@mrgoblin.net>2026-09-19 19:09:11 +0300
commit01438bd1be578c3b43c9ad29b0a2d6707ee122b8 (patch)
treed3e8dfd3b6482e1dac32837d0d57847f0d67ed2c /btasktd.c
parent2cba815df5713fbadecc86e373ec5f6c8a07ced5 (diff)
all files are in root; changed help message
Diffstat (limited to 'btasktd.c')
-rw-r--r--btasktd.c186
1 files changed, 186 insertions, 0 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#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;
+}