aboutsummaryrefslogtreecommitdiff
path: root/btasktd.c
diff options
context:
space:
mode:
Diffstat (limited to 'btasktd.c')
-rw-r--r--btasktd.c152
1 files changed, 134 insertions, 18 deletions
diff --git a/btasktd.c b/btasktd.c
index 7a6a5af..6abb00c 100644
--- a/btasktd.c
+++ b/btasktd.c
@@ -40,12 +40,13 @@
#include <unistd.h>
#include <errno.h>
#include "cliflags.h"
+#include "codes.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"
+ "For more info read the program's man page\n"
#define BTASKTD_VERSION_STR \
"0.0.0"
@@ -54,10 +55,26 @@
# define BTASKTD_QUEUE_LEN 16
#endif
+#ifndef BTASKTD_CLIENT_BUF_SIZE
+# define BTASKTD_CLIENT_BUF_SIZE 4096
+#endif
+
+struct user {
+ int fd;
+ char buf[BTASKTD_CLIENT_BUF_SIZE];
+ int bi;
+};
+
+struct btasktd {
+ int fd;
+ int users_cnt;
+ struct user *users;
+};
+
static void
fprint_help(FILE *f)
{
- fputs(BTASKTD_HELP_STR, f);
+ fprintf(f, "%s", BTASKTD_HELP_STR);
}
static void
@@ -67,23 +84,84 @@ set_nonblock(int fd)
fcntl(fd, F_SETFL, fflags|O_NONBLOCK);
}
+static int
+find_free_user(const struct user *arr, int count)
+{
+ int i;
+ for (i = 0; i < count; i++) {
+ if (-1 == arr[i].fd)
+ return i;
+ }
+ return -1;
+}
+
+static void
+send_client(int fd, const char *s)
+{
+ int len = strlen(s);
+ send(fd, s, len, 0);
+}
+
+static void
+handle_accept(struct btasktd *this)
+{
+ int idx;
+ struct sockaddr_in user_addr = {0};
+ socklen_t addrlen = sizeof(user_addr);
+ int fd = accept(this->fd, (struct sockaddr*)&user_addr, &addrlen);
+ if (-1 == fd) {
+ perror("accept");
+ return;
+ }
+ set_nonblock(fd);
+ idx = find_free_user(this->users, this->users_cnt);
+ if (-1 == idx) {
+ send_client(fd, CODE_503_STR);
+ close(fd);
+ }
+ this->users[idx].fd = fd;
+ this->users[idx].bi = 0;
+}
+
+static void
+handle_timeout(struct btasktd *this)
+{
+}
+
+static int
+buf_append(char *buf, int *bi, int bsize, const char *str)
+{
+ int len = strlen(str);
+ if (bi + len > bsize)
+ return -1;
+}
+
+static void
+handle_user(struct btasktd *this, int id)
+{
+}
+
int
main(int argc, char **argv)
{
+ struct btasktd server;
int server_fd, opt = 1, res, port, passed_flags = 1, users_cnt;
- int *users = NULL;
+ int max_fd;
+ struct user *users = NULL;
+ int i;
struct sockaddr_in addr = {0};
struct int_flag_val int_res;
- struct bool_flag_val show_ver, show_help;
+ struct bool_flag_val bool_res;
+ fd_set readfds;
- show_ver = extract_bool_flag('V', argc, argv);
- if (fvr_ok == show_ver.code && show_ver.data) {
+ bool_res = extract_bool_flag('V', argc, argv);
+ if (fvr_ok == bool_res.code && bool_res.data) {
printf("btasktd version %s\n", BTASKTD_VERSION_STR);
return 0;
}
- show_help = extract_bool_flag('h', argc, argv);
- if (fvr_ok == show_help.code && show_help.data) {
+ bool_res = extract_bool_flag('h', argc, argv);
+ if (fvr_ok == bool_res.code && bool_res.data) {
fprint_help(stdout);
return 0;
}
@@ -94,17 +172,17 @@ main(int argc, char **argv)
# ifdef BTASKTD_DEFAULT_PORT
port = BTASKTD_DEFAULT_PORT;
# else
- fputs("No port specified!\n", stderr);
+ fprintf(stderr, "No port specified!\n");
passed_flags = 0;
# endif
break;
case fvr_ok:
port = int_res.data;
- if (port < 0)
+ if (port > 0)
break;
/* fallthrough */
case fvr_invalid:
- fputs("Invalid port!\n", stderr);
+ fprintf(stderr, "Invalid port!\n");
return 1;
break;
}
@@ -115,32 +193,35 @@ main(int argc, char **argv)
# ifdef BTASKTD_DEFAULT_USERS_CNT
users_cnt = BTASKTD_DEFAULT_USERS_CNT;
# else
- fputs("No users count specified!\n", stderr);
+ fprintf(stderr, "No users count specified!\n");
passed_flags = 0;
# endif
break;
case fvr_ok:
users_cnt = int_res.data;
- if (users_cnt <= 0)
+ if (users_cnt > 0)
break;
/* fallthrough */
case fvr_invalid:
- fputs("Invalid users count!\n", stderr);
+ fprintf(stderr, "Invalid users count!\n");
return 1;
break;
}
if (!passed_flags) {
- fputs("-\n", stderr);
+ fprintf(stderr, "-\n");
fprint_help(stderr);
return 1;
}
- users = (int*)malloc(users_cnt * sizeof(int));
+ users = (struct user*)calloc(users_cnt, sizeof(struct user));
if (NULL == users) {
- fputs("No memory!\n", stderr);
+ fprintf(stderr, "No memory!\n");
return 1;
}
+ for (i = 0; i < users_cnt; i++) {
+ users[i].fd = -1;
+ }
server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
@@ -175,9 +256,44 @@ main(int argc, char **argv)
}
set_nonblock(server_fd);
+
+ server.fd = server_fd;
+ server.users_cnt = users_cnt;
+ server.users = users;
printf("btaskt server btasktd started on port %d\n", port);
- /* main loop here */
+ for (;;) {
+ FD_ZERO(&readfds);
+ FD_SET(server_fd, &readfds);
+ max_fd = server_fd;
+ for (i = 0; i < users_cnt; i++) {
+ if (-1 == users[i].fd)
+ continue;
+ FD_SET(users[i].fd, &readfds);
+ if (users[i].fd > max_fd)
+ max_fd = users[i].fd;
+ }
+ res = select(max_fd+1, &readfds, NULL, NULL, NULL);
+ if (-1 == res) {
+ if (EINTR == errno) {
+ /* signal handler called */
+ } else {
+ perror("select");
+ }
+ continue;
+ } else if (0 == res) {
+ handle_timeout(&server);
+ continue;
+ }
+ if (FD_ISSET(server_fd, &readfds))
+ handle_accept(&server);
+ for (i = 0; i < users_cnt; i++) {
+ if (-1 == users[i].fd)
+ continue;
+ if (FD_ISSET(users[i].fd, &readfds))
+ handle_user(&server, i);
+ }
+ }
printf("btaskt server btasktd stopped\n");
close(server_fd);