From: Hemmo Nieminen <[email protected]>
Signed-off-by: Hemmo Nieminen <[email protected]>
---
include/libbb.h | 4 ++
libbb/Config.src | 6 +++
libbb/Kbuild.src | 1 +
libbb/bb_tally.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 148 insertions(+)
create mode 100644 libbb/bb_tally.c
diff --git a/include/libbb.h b/include/libbb.h
index 03f9c35f3..50a302f17 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2587,6 +2587,10 @@ void bbunit_settestfailed(void);
} \
} while (0)
+#if ENABLE_FEATURE_TALLY
+int FAST_FUNC bb_tally_add(char const * const path);
+int FAST_FUNC bb_tally_reset(char const * const path);
+#endif
POP_SAVED_FUNCTION_VISIBILITY
diff --git a/libbb/Config.src b/libbb/Config.src
index f97de8ef7..23d821916 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -395,3 +395,9 @@ config FEATURE_HWIB
default y
help
Support for printing infiniband addresses in network applets.
+
+config FEATURE_TALLY
+ bool "Support tallying with files"
+ default n
+ help
+ Add support to libbb for tallying e.g. events via files.
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 676300801..35448f805 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -153,6 +153,7 @@ lib-$(CONFIG_SULOGIN) += pw_encrypt.o correct_password.o
lib-$(CONFIG_VLOCK) += pw_encrypt.o correct_password.o
lib-$(CONFIG_SU) += pw_encrypt.o correct_password.o
lib-$(CONFIG_LOGIN) += pw_encrypt.o correct_password.o
+lib-$(CONFIG_FEATURE_TALLY) += bb_tally.o
lib-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) += pw_encrypt.o
lib-$(CONFIG_FEATURE_FTP_AUTHENTICATION) += pw_encrypt.o
diff --git a/libbb/bb_tally.c b/libbb/bb_tally.c
new file mode 100644
index 000000000..05e06a0cf
--- /dev/null
+++ b/libbb/bb_tally.c
@@ -0,0 +1,137 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Utility routines to do tallying with files.
+ *
+ * Copyright (C) 2021 Hemmo Nieminen
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include "libbb.h"
+
+int FAST_FUNC
+bb_tally_add(char const * const path)
+{
+ int retval = 0;
+ FILE * f;
+ struct stat buf;
+ int fd = open(path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+
+ if (fd < 0)
+ return -1;;
+
+ f = fdopen(fd, "w+");
+ if (!f) {
+ close(fd);
+ return -1;
+ }
+
+ if (fstat(fd, &buf) < 0
+ || buf.st_uid != getuid()
+ || (buf.st_size != 0 && (fscanf(f, "%d", &retval) != 1
|| retval < 0))
+ || fseek(f, 0, SEEK_SET) < 0
+ || fprintf(f, "%d", ++retval) < 1) {
+ fclose(f);
+ return -1;
+ }
+
+ if (fclose(f) < 0)
+ return -1;
+
+ return retval;
+}
+
+int FAST_FUNC
+bb_tally_reset(char const * const path)
+{
+ struct stat buf;
+
+ if (stat(path, &buf) == 0 && buf.st_uid == geteuid())
+ return remove(path);
+
+ return 0;
+}
+
+#if ENABLE_UNIT_TEST
+
+#define TALLY_FILE_PREFIX "tally_test."
+
+BBUNIT_DEFINE_TEST(test_tally_add)
+{
+ remove(TALLY_FILE_PREFIX "one");
+ remove(TALLY_FILE_PREFIX "two");
+ remove(TALLY_FILE_PREFIX "three");
+
+ for (int i = 0; i < 1000; i++) {
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "one"), i + 1);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 2*i +
1);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "three"), i +
1);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 2*i +
2);
+ }
+
+ BBUNIT_ASSERT_EQ(bb_tally_reset(TALLY_FILE_PREFIX "three"), 0);
+ BBUNIT_ASSERT_EQ(bb_tally_reset(TALLY_FILE_PREFIX "one"), 0);
+
+ for (int i = 0; i < 1000; i++) {
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "one"), i + 1);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 2000 +
i + 1);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "three"), i +
1);
+ }
+
+ BBUNIT_ENDTEST;
+
+ remove(TALLY_FILE_PREFIX "one");
+ remove(TALLY_FILE_PREFIX "two");
+ remove(TALLY_FILE_PREFIX "three");
+}
+
+BBUNIT_DEFINE_TEST(test_tally_reset)
+{
+ remove(TALLY_FILE_PREFIX "one");
+ remove(TALLY_FILE_PREFIX "two");
+ remove(TALLY_FILE_PREFIX "three");
+
+ BBUNIT_ASSERT_EQ(bb_tally_reset(TALLY_FILE_PREFIX "two"), 0);
+
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "three"), 1);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 1);
+ BBUNIT_ASSERT_EQ(bb_tally_reset(TALLY_FILE_PREFIX "two"), 0);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "three"), 2);
+
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 1);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 2);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 3);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 4);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "one"), 1);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "one"), 2);
+ BBUNIT_ASSERT_EQ(bb_tally_reset(TALLY_FILE_PREFIX "two"), 0);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "one"), 3);
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "two"), 1);
+
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "three"), 3);
+ BBUNIT_ASSERT_EQ(bb_tally_reset(TALLY_FILE_PREFIX "three"), 0);
+ BBUNIT_ASSERT_EQ(bb_tally_reset(TALLY_FILE_PREFIX "three"), 0);
+
+ BBUNIT_ENDTEST;
+
+ remove(TALLY_FILE_PREFIX "one");
+ remove(TALLY_FILE_PREFIX "two");
+ remove(TALLY_FILE_PREFIX "three");
+}
+
+BBUNIT_DEFINE_TEST(test_nonexisting_file)
+{
+ remove(TALLY_FILE_PREFIX "non-existing-file");
+
+ BBUNIT_ASSERT_EQ(bb_tally_reset(TALLY_FILE_PREFIX "non-existing-file"),
0);
+ BBUNIT_ASSERT_EQ(remove(TALLY_FILE_PREFIX "non-existing-file"), -1);
+
+ BBUNIT_ASSERT_EQ(bb_tally_add(TALLY_FILE_PREFIX "non-existing-file"),
1);
+ BBUNIT_ASSERT_EQ(remove(TALLY_FILE_PREFIX "non-existing-file"), 0);
+
+ BBUNIT_ENDTEST;
+}
+
+#endif
--
2.31.1
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox