#include #include #include #include #include #include #include "scheme.h" #include "../any_log.h" static void block_fs_update(block_t *block) { const char *path = ((char **)block->state)[0]; const char *text = ((char **)block->state)[1]; struct statvfs sbuf; assert(statvfs(path, &sbuf) == 0); static const char *fs_formats[] = { "total", "free", "used", NULL, }; char buffer[32][3] = { 0 }; snprintf(buffer[0], 32, "%ld", sbuf.f_blocks * sbuf.f_frsize); snprintf(buffer[1], 32, "%ld", sbuf.f_bavail * sbuf.f_bsize); snprintf(buffer[2], 32, "%ld", (sbuf.f_blocks - sbuf.f_bavail) * sbuf.f_bsize); const char *fs_values[] = { buffer[0], buffer[1], buffer[2], NULL, }; free(block->text.text); block->text.text = strformat(text, '%', fs_formats, fs_values); assert(block->text.text != NULL); } static void block_fs_finalize(block_t *block) { free(block->state); } static bool block_fs_validate(block_t *block, const block_scheme_t *scheme) { if (block->text.text == NULL) { log_error("Block '%s' requires key '%s'", block->label, "text"); return false; } if (strstr(block->text.text, "%{") == NULL) { log_warn("Block '%s' does not use any fs variable", block->label); block->update_cb = NULL; log_debug("Disabled updates for block '%s'", block->label); return true; } const char *path = ((char **)block->state)[0]; struct stat sbuf; if (path == NULL || stat(path, &sbuf) < 0) { log_error("Block '%s' was given an invalid path '%s'", block->label, path); return false; } ((char **)block->state)[1] = block->text.text; block->text.text = NULL; return true; } static const config_entry_t block_fs_entries[] = { { "path", CONFIG_STRING, NULL, 0 }, { 0 }, }; const block_scheme_t block_fs_scheme = { .name = "fs", .block = { .type = BLOCK_TEXT, .update_interval = { .tv_sec = 20, .tv_nsec = 0, }, .update_cb = block_fs_update, .finalize_cb = block_fs_finalize, }, .size = 2 * sizeof(char *), .entries = block_fs_entries, .validate = block_fs_validate, };