#include #include #include #include #include "scheme.h" #include "../any_log.h" static void block_ram_update(block_t *block) { FILE *meminfo = fopen("/proc/meminfo", "rb"); assert(meminfo != NULL); uintmax_t total, unused, available, buffers, cached; assert(5 == fscanf(meminfo, "MemTotal: %ju kB\n" "MemFree: %ju kB\n" "MemAvailable: %ju kB\n" "Buffers: %ju kB\n" "Cached: %ju kB\n", &total, &unused, &available, &buffers, &cached)); fclose(meminfo); static const char *ram_formats[] = { "total", "free", "used", "free-percentage", "used-percentage", NULL, }; char buffer[32][5] = { 0 }; snprintf(buffer[0], 32, "%ld", total); snprintf(buffer[1], 32, "%ld", available); snprintf(buffer[2], 32, "%ld", total - available); snprintf(buffer[3], 32, "%ld", 100 * available / total); snprintf(buffer[4], 32, "%ld", 100 * (total - available) / total); const char *ram_values[] = { buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], NULL, }; free(block->text.text); block->text.text = strformat(block->state, '%', ram_formats, ram_values); assert(block->text.text != NULL); } static void block_ram_finalize(block_t *block) { free(block->state); } static bool block_ram_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 ram variable", block->label); block->update = NULL; log_debug("Disabled updates for block '%s'", block->label); return true; } block->state = block->text.text; block->text.text = NULL; return true; } const block_scheme_t block_ram_scheme = { .name = "ram", .block = { .type = BLOCK_TEXT, .update_interval = { .tv_sec = 1, .tv_nsec = 0, }, .update = block_ram_update, .finalize = block_ram_finalize, }, .size = sizeof(char *), .entries = NULL, .validate = block_ram_validate, };