aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMr. Goblin <mrgoblin@mrgoblin.net>2026-09-19 15:06:12 +0300
committerMr. Goblin <mrgoblin@mrgoblin.net>2026-09-19 15:06:12 +0300
commit2b022e27d1939b46097e523c0973ffbf48d284b1 (patch)
tree8c2ca372445f65ed84231bc99c82b7033ecbb511
parent80f5d3071d92b57204e48f3cd9789651ab2ba83b (diff)
man page, dist.sh, README is now plain text, Makefile is now posix
-rw-r--r--.gitattributes3
-rw-r--r--README19
-rw-r--r--README.md1
-rw-r--r--btasktd.141
-rwxr-xr-xdist.sh7
-rw-r--r--src/Makefile16
-rw-r--r--src/btasktd.c58
-rw-r--r--src/cliflags.c8
-rw-r--r--src/db.c30
9 files changed, 152 insertions, 31 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..2f14ddf
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+.gitignore export-ignore
+.gitattributes export-ignore
+dist.sh export-ignore
diff --git a/README b/README
new file mode 100644
index 0000000..fbabbef
--- /dev/null
+++ b/README
@@ -0,0 +1,19 @@
+=========================================================================
+BTASKTD v0.0.0
+=========================================================================
+
+Lightweight, fast and free daemon for task tracking.
+
+Written in limited C99 (closer to C89), builds statically.
+
+-------------------------------------------------------------------------
+BUILD DEPENDENCIES
+-------------------------------------------------------------------------
+* make (either gmake or POSIX make)
+* any compiler that supports C99 (it is harder to find one that does NOT)
+* libc
+
+-------------------------------------------------------------------------
+RUNTIME DEPENDENCIES
+-------------------------------------------------------------------------
+* OS Kernel
diff --git a/README.md b/README.md
deleted file mode 100644
index eb10f22..0000000
--- a/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# btasktd
diff --git a/btasktd.1 b/btasktd.1
new file mode 100644
index 0000000..e354724
--- /dev/null
+++ b/btasktd.1
@@ -0,0 +1,41 @@
+.Dd September 19, 2026
+.Dt BTASKTD 1
+.Os
+.
+.Sh NAME
+.Nm btasktd
+.Nd task tracking TCP-server
+.
+.Sh SYNOPSIS
+.Nm
+.BK -words
+.Op Fl \&Vh
+.Op Fl p Ar port
+.Op Fl u Ar users
+.Ek
+.
+.Sh DESCRIPTION
+.Nm
+is a btaskt protocol server daemon.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl V
+Show version
+.It Fl h
+Show help message
+.It Fl p Ar port
+Set port for server to listen to
+.It Fl u Ar users
+Set max clients count
+.El
+.
+.Sh AUTHORS
+.An Mr. Goblin
+.
+.Sh LICENSE
+.Nm
+is licensed under terms of BSD 2-Clause License.
+See
+.Pa LICENSE
+file for copyright and license details.
diff --git a/dist.sh b/dist.sh
new file mode 100755
index 0000000..cb05b36
--- /dev/null
+++ b/dist.sh
@@ -0,0 +1,7 @@
+#!/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
index fa8ddc8..2e8dd64 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -5,18 +5,26 @@
# CC = cc -fno-caret-diagnostics -fno-color-diagnostics
CC = gcc -fno-diagnostics-show-caret -fdiagnostics-color=never
# CC = gcc
-CFLAGS = -g -Wall -Wextra -pedantic -std=c99
-STATIC = -static
+CFLAGS = -Wall -Wextra -pedantic -std=c99
+
+# DEBUG = -g
+# DEBUG = -ggdb
+DEBUG =
+
+# STATIC = -static
+STATIC = -static -s
# STATIC =
MAINBINARIES = btasktd
+.SUFFIXES = .c .o
+
all: $(MAINBINARIES)
clean:
- rm -f $(MAINBINARIES) *.o
+ rm -f $(MAINBINARIES) *.o *.test
-%.o: %.c
+.c.o:
$(CC) $(CFLAGS) -c $< -o $@
diff --git a/src/btasktd.c b/src/btasktd.c
index 34e1fae..9878a3d 100644
--- a/src/btasktd.c
+++ b/src/btasktd.c
@@ -64,16 +64,24 @@ 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, fflags, port, passed_flags = 1;
+ int server_fd, opt = 1, res, port, passed_flags = 1, users_cnt;
+ int *users = NULL;
struct sockaddr_in addr = {0};
- struct int_flag_val port_res;
+ struct int_flag_val int_res;
struct bool_flag_val show_ver, show_help;
show_ver = extract_bool_flag('V', argc, argv);
- if (show_ver.code == fvr_ok && show_ver.data) {
+ if (fvr_ok == show_ver.code && show_ver.data) {
printf("btasktd version %s\n", BTASKTD_VERSION_STR);
return 0;
}
@@ -84,8 +92,8 @@ main(int argc, char **argv)
return 0;
}
- port_res = extract_int_flag('p', argc, argv);
- switch (port_res.code) {
+ int_res = extract_int_flag('p', argc, argv);
+ switch (int_res.code) {
case fvr_not_found:
# ifdef BTASKTD_DEFAULT_PORT
port = BTASKTD_DEFAULT_PORT;
@@ -94,11 +102,35 @@ main(int argc, char **argv)
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:
- port = port_res.data;
+ users = int_res.data;
+ if (users > 0)
+ break;
+ /* fallthrough */
+ case fvr_invalid:
+ fputs("Invalid users count!\n", stderr);
+ return 1;
break;
}
@@ -107,8 +139,15 @@ main(int argc, char **argv)
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;
}
@@ -118,12 +157,14 @@ main(int argc, char **argv)
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;
}
@@ -131,17 +172,18 @@ main(int argc, char **argv)
&opt, sizeof(opt));
if (0 != res) {
close(server_fd);
+ free(users);
perror("setsockopt");
return 1;
}
- fflags = fcntl(server_fd, F_GETFL);
- fcntl(server_fd, F_SETFL, fflags|O_NONBLOCK);
+ 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
index f34a889..e3ff7f2 100644
--- a/src/cliflags.c
+++ b/src/cliflags.c
@@ -64,9 +64,9 @@ extract_str_flag(char flagletter, int argc, char **argv)
for (i = 1; i < argc; i++)
if (0 == strcmp(flagstr, argv[i]))
break;
- if (i >= argc) {
+ if (argc <= i) {
res.code = fvr_not_found;
- } else if (i == argc-1) {
+ } else if (argc-1 == i) {
res.code = fvr_invalid;
} else {
res.code = fvr_ok;
@@ -84,11 +84,11 @@ extract_int_flag(char flagletter, int argc, char **argv)
extract_str_flag(flagletter, argc, argv);
char *endptr;
res.code = strres.code;
- if (res.code != fvr_ok) {
+ if (fvr_ok != res.code) {
return res;
}
res.data = strtol(strres.data, &endptr, 10);
- if (*endptr != '\0')
+ if ('\0' != *endptr)
res.code = fvr_invalid;
return res;
}
diff --git a/src/db.c b/src/db.c
index 6357388..c547013 100644
--- a/src/db.c
+++ b/src/db.c
@@ -78,15 +78,15 @@ does_dir_exist(const char *path)
res.code = dbe_ok;
res.data = 1;
code = stat(path, &st);
- if (code != 0) {
- if (errno == ENOENT)
+ if (0 != code) {
+ if (ENOENT == errno)
res.data = 0;
- else if (errno == EACCES)
+ else if (EACCES == errno)
res.code = dbe_access;
else
res.code = dbe_unknown;
} else {
- res.data = ((st.st_mode & S_IFMT) == S_IFDIR) ? 1 : 0;
+ res.data = S_IFDIR == (st.st_mode & S_IFMT);
}
return res;
}
@@ -97,15 +97,15 @@ make_dir_ifne(const char *path, int rights)
struct db_value_int val = {0};
int code;
val = does_dir_exist(path);
- if (val.code != dbe_ok)
+ if (dbe_ok != val.code)
return val.code;
else if (val.data)
return dbe_ok;
code = mkdir(path, rights);
if (code != 0) {
- if (errno == EACCES)
+ if (EACCES == errno)
return dbe_access;
- else if (errno == EEXIST)
+ else if (EEXIST == errno)
return dbe_notdir;
}
return dbe_ok;
@@ -117,18 +117,20 @@ 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 (sz > sizeof(buf))
+ if (sizeof(buf) < sz)
return dbe_inval;
strncpy(buf, path, sz);
buf[sz-1] = '\0';
code = make_dir_ifne(buf, rights);
- if (code != dbe_ok)
+ if (dbe_ok != code)
return code;
if (*p) {
code = chdir(buf);
if (0 != code)
return dbe_access;
- do_make_dir_path(p+1, rights);
+ code = do_make_dir_path(p+1, rights);
+ if (dbe_ok != code)
+ return code;
code = chdir("..");
if (0 != code)
return dbe_access;
@@ -171,20 +173,20 @@ main(void)
for (i = 0; i < 10; i++)
TEST_CODE(make_dir_path(path, 0777));
pid = fork();
- if (pid == -1) {
+ if (-1 == pid) {
fprintf(stderr, "can't fork\n");
return 1;
- } else if (pid == 0) {
+ } else if (0 == pid) {
execlp("ls", "ls", "-laR", NULL);
_exit(128);
} else {
wait(NULL);
}
pid = fork();
- if (pid == -1) {
+ if (-1 == pid) {
fprintf(stderr, "can't fork\n");
return 1;
- } else if (pid == 0) {
+ } else if (0 == pid) {
execlp("rm", "rm", "-rf", "test_db", NULL);
_exit(127);
} else {