aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMr. Goblin <mrgoblin@mrgoblin.net>2026-09-17 20:55:34 +0300
committerMr. Goblin <mrgoblin@mrgoblin.net>2026-09-17 20:55:34 +0300
commite8cac0c4441d3c77b7e0181da441d416f481edd7 (patch)
tree9ef0c02ae7a6ad20b7a66e80a63a3987bb5aee85 /src
parent51a1bad32dec2f0ebff5f16345759934c233ef71 (diff)
Implemented mkdir -p in db module (not used)
Diffstat (limited to 'src')
-rw-r--r--src/cliflags.h10
-rw-r--r--src/db.c166
-rw-r--r--src/db.h59
3 files changed, 230 insertions, 5 deletions
diff --git a/src/cliflags.h b/src/cliflags.h
index 21ffebc..5bf251b 100644
--- a/src/cliflags.h
+++ b/src/cliflags.h
@@ -28,16 +28,16 @@
* OF SUCH DAMAGE.
*/
-#ifndef BTASKT_CLIFLAGS_H_SENTRY
-#define BTASKT_CLIFLAGS_H_SENTRY
+#ifndef BTASKTD_CLIFLAGS_H_SENTRY
+#define BTASKTD_CLIFLAGS_H_SENTRY
#ifdef __cplusplus
extern "C" {
#endif
enum flag_val_res {
- fvr_not_found = -1,
- fvr_min = fvr_not_found,
fvr_ok = 0,
+ fvr_min = fvr_ok,
+ fvr_not_found,
fvr_invalid,
fvr_max = fvr_invalid
};
@@ -72,4 +72,4 @@ extract_int_flag(char flagletter, int argc, char **argv);
#ifdef __cplusplus
}
#endif
-#endif /* BTASKT_CLIFLAGS_H_SENTRY */
+#endif /* BTASKTD_CLIFLAGS_H_SENTRY */
diff --git a/src/db.c b/src/db.c
new file mode 100644
index 0000000..a46f806
--- /dev/null
+++ b/src/db.c
@@ -0,0 +1,166 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <wait.h>
+#include <string.h>
+#include <limits.h>
+#include <errno.h>
+#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 (code != 0) {
+ if (errno == ENOENT)
+ res.data = 0;
+ else if (errno == EACCES)
+ res.code = dbe_access;
+ else
+ res.code = dbe_unknown;
+ } else {
+ res.data = ((st.st_mode & S_IFMT) == S_IFDIR) ? 1 : 0;
+ }
+ 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 (val.code != dbe_ok)
+ return val.code;
+ else if (val.data)
+ return dbe_ok;
+ code = mkdir(path, rights);
+ if (code != 0) {
+ if (errno == EACCES)
+ return dbe_access;
+ else if (errno == EEXIST)
+ 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 (sz > sizeof(buf))
+ return dbe_inval;
+ strncpy(buf, path, sz);
+ buf[sz-1] = '\0';
+ code = make_dir_ifne(buf, rights);
+ if (code != dbe_ok)
+ return code;
+ if (*p) {
+ code = chdir(buf);
+ if (0 != code)
+ return dbe_access;
+ do_make_dir_path(p+1, rights);
+ 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 <stdio.h>
+
+#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 (pid == -1) {
+ fprintf(stderr, "can't fork\n");
+ return 1;
+ } else if (pid == 0) {
+ execlp("ls", "ls", "-laR", NULL);
+ _exit(128);
+ } else {
+ wait(NULL);
+ }
+ pid = fork();
+ if (pid == -1) {
+ fprintf(stderr, "can't fork\n");
+ return 1;
+ } else if (pid == 0) {
+ execlp("rm", "rm", "-rf", "test_db", NULL);
+ _exit(128);
+ } else {
+ wait(NULL);
+ }
+ return 0;
+}
+
+#endif
diff --git a/src/db.h b/src/db.h
new file mode 100644
index 0000000..ebb42c5
--- /dev/null
+++ b/src/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 */