aboutsummaryrefslogtreecommitdiff
path: root/src/blocks/fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/blocks/fs.c')
-rw-r--r--src/blocks/fs.c96
1 files changed, 69 insertions, 27 deletions
diff --git a/src/blocks/fs.c b/src/blocks/fs.c
index 74f8962..9c0a50c 100644
--- a/src/blocks/fs.c
+++ b/src/blocks/fs.c
@@ -7,15 +7,33 @@
#include <sys/stat.h>
#include "../block.h"
-
+#include "../format.h"
#include "../any_log.h"
typedef struct {
block_text_t block;
- char *format;
+ format_t format;
char *path;
} block_fs_t;
+typedef enum {
+ FS_STRING = 0,
+ FS_TOTAL,
+ FS_FREE,
+ FS_USED,
+ FS_FREE_PERC,
+ FS_USED_PERC,
+} block_fs_mark_t;
+
+static const format_pair_t block_fs_pairs[] = {
+ { "total", FS_TOTAL },
+ { "free", FS_FREE },
+ { "used", FS_USED },
+ { "free-percentage", FS_FREE_PERC },
+ { "used-percentage", FS_USED_PERC },
+ { NULL },
+};
+
static const struct timespec block_fs_interval = {
.tv_sec = 20,
.tv_nsec = 0,
@@ -34,28 +52,44 @@ static void block_fs_update(block_t *block)
return;
}
- static const char *fs_formats[] = {
- "total",
- "free",
- "used",
- "free-percentage",
- "used-percentage",
- NULL,
- };
-
- char buffer[5][32] = { 0 };
- snprintf(buffer[0], 32, "%lu", sbuf.f_bsize * (uint64_t)sbuf.f_blocks);
- snprintf(buffer[1], 32, "%lu", sbuf.f_bsize * (uint64_t)sbuf.f_bavail);
- snprintf(buffer[2], 32, "%lu", sbuf.f_bsize * (sbuf.f_blocks - sbuf.f_bavail));
- snprintf(buffer[3], 32, "%lu", (100 * sbuf.f_bavail) / sbuf.f_blocks);
- snprintf(buffer[4], 32, "%lu", (100 * (sbuf.f_blocks - sbuf.f_bavail)) / sbuf.f_blocks);
-
- const char *fs_values[] = {
- buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], NULL,
- };
+ char buffer[256] = { 0 };
+ size_t start = 0, size = sizeof(buffer);
+
+ for (size_t i = 0; i < fs->format.length; i++) {
+ size_t rest = start >= size ? 0 : size - start;
+ if (rest == 0) break;
+
+ switch (fs->format.marks[i]) {
+ case FS_STRING:
+ start += snprintf(buffer + start, rest, "%s", fs->format.parts[i]);
+ break;
+ case FS_TOTAL:
+ start += snprintf(buffer + start, rest, "%ld", sbuf.f_bsize * (uint64_t)sbuf.f_blocks);
+ break;
+
+ case FS_FREE:
+ start += snprintf(buffer + start, rest, "%ld", sbuf.f_bsize * (uint64_t)sbuf.f_bavail);
+ break;
+
+ case FS_USED:
+ start += snprintf(buffer + start, rest, "%ld", sbuf.f_bsize * (sbuf.f_blocks - sbuf.f_bavail));
+ break;
+
+ case FS_FREE_PERC:
+ start += snprintf(buffer + start, rest, "%ld", (100 * sbuf.f_bavail) / sbuf.f_blocks);
+ break;
+
+ case FS_USED_PERC:
+ start += snprintf(buffer + start, rest, "%ld", (100 * (sbuf.f_blocks - sbuf.f_bavail)) / sbuf.f_blocks);
+ break;
+
+ default:
+ unreachable();
+ }
+ }
free(fs->block.text);
- fs->block.text = strformat(fs->format, '%', fs_formats, fs_values);
+ fs->block.text = strcopy(buffer);
assert(fs->block.text != NULL);
}
@@ -71,7 +105,7 @@ static block_t *block_fs_alloc(const block_scheme_t *scheme)
static void block_fs_clean(block_t *block)
{
block_fs_t *fs = (block_fs_t *)block;
- free(fs->format);
+ format_free(&fs->format);
free(fs->path);
free(fs->block.text);
}
@@ -85,8 +119,17 @@ static bool block_fs_validate(block_t *block, const block_scheme_t *scheme)
return false;
}
- if (strstr(fs->block.text, "%{") == NULL) {
- log_warn("Block '%s' does not use any fs variable", block->label);
+ if (!format_init(&fs->format, fs->block.text, '%')) {
+ log_error("Block '%s' has an invalid format", block->label);
+ return false;
+ }
+
+ int marked = format_remark(&fs->format, block->label, block_fs_pairs);
+ if (marked < 0)
+ return false;
+
+ if (marked == 0) {
+ log_warn("Block '%s' does not use any fs option", block->label);
block->update_fn = NULL;
log_debug("Disabled updates for block '%s'", block->label);
@@ -95,12 +138,11 @@ static bool block_fs_validate(block_t *block, const block_scheme_t *scheme)
struct stat sbuf;
if (fs->path == NULL || stat(fs->path, &sbuf) < 0) {
+ log_trace("Failed to read file '%s': %s", fs->path, strerror(errno));
log_error("Block '%s' was given an invalid path '%s'", block->label, fs->path);
return false;
}
- fs->format = fs->block.text;
- fs->block.text = strcopy("?");
return true;
}