diff options
Diffstat (limited to 'src/blocks')
| -rw-r--r-- | src/blocks/group.c | 2 | ||||
| -rw-r--r-- | src/blocks/ram.c | 110 | ||||
| -rw-r--r-- | src/blocks/scheme.h | 5 | ||||
| -rw-r--r-- | src/blocks/text.c | 14 |
4 files changed, 125 insertions, 6 deletions
diff --git a/src/blocks/group.c b/src/blocks/group.c index fb4457e..4fcb420 100644 --- a/src/blocks/group.c +++ b/src/blocks/group.c @@ -7,6 +7,6 @@ const block_scheme_t block_group_scheme = { }, .size = 0, .entries = NULL, - .verify = NULL, + .validate = NULL, }; diff --git a/src/blocks/ram.c b/src/blocks/ram.c index a626413..44dd1a3 100644 --- a/src/blocks/ram.c +++ b/src/blocks/ram.c @@ -1,12 +1,118 @@ +#include <string.h> +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> + #include "scheme.h" +#include "../any_log.h" + +char *str_replace(char *orig, char *rep, char *with) { + char *result; // the return string + char *ins; // the next insert point + char *tmp; // varies + int len_rep; // length of rep (the string to remove) + int len_with; // length of with (the string to replace rep with) + int len_front; // distance between rep and end of last rep + int count; // number of replacements + + // sanity checks and initialization + if (!orig || !rep) + return NULL; + len_rep = strlen(rep); + if (len_rep == 0) + return NULL; // empty rep causes infinite loop during count + if (!with) + with = ""; + len_with = strlen(with); + + // count the number of replacements needed + ins = orig; + for (count = 0; (tmp = strstr(ins, rep)); ++count) { + ins = tmp + len_rep; + } + + tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1); + + if (!result) + return NULL; + + // first time through the loop, all the variable are set correctly + // from here on, + // tmp points to the end of the result string + // ins points to the next occurrence of rep in orig + // orig points to the remainder of orig after "end of rep" + while (count--) { + ins = strstr(orig, rep); + len_front = ins - orig; + tmp = strncpy(tmp, orig, len_front) + len_front; + tmp = strcpy(tmp, with) + len_with; + orig += len_front + len_rep; // move to next "end of rep" + } + strcpy(tmp, orig); + return result; +} + +static void block_ram_update(block_t *block) +{ + FILE *meminfo = fopen("/proc/meminfo", "rb"); + assert(meminfo != NULL); + + uintmax_t total, unused, 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, &buffers, &buffers, &cached)); + + int usage = 100 * (total - unused - buffers - cached) / total; + fclose(meminfo); + + free(block->text.text); + + char str[100]; + sprintf(str, "%d", usage); + + block->text.text = str_replace(block->state, "%{ram}", str); + 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) +{ + block->state = block->text.text; + block->text.text = NULL; + + if (block->state == NULL) { + log_error("Block '%s' requires key '%s'", block->label, "text"); + return false; + } + + if (strstr(block->state, "%{ram}") != NULL) + log_warn("Block '%s' does not have a ram format", block->label); + + return true; +} + const block_scheme_t block_ram_scheme = { .name = "ram", .block = { .type = BLOCK_TEXT, + .update_interval = { + .tv_sec = 1, + .tv_nsec = 0, + }, + .update_cb = block_ram_update, + .finalize_cb = block_ram_finalize, }, - .size = 0, + .size = sizeof(char *), .entries = NULL, - .verify = NULL, + .validate = block_ram_validate, }; diff --git a/src/blocks/scheme.h b/src/blocks/scheme.h index 2bcca97..1795013 100644 --- a/src/blocks/scheme.h +++ b/src/blocks/scheme.h @@ -5,14 +5,15 @@ typedef struct block_scheme block_scheme_t; -typedef bool (*block_scheme_verify_t)(block_t *block, block_scheme_t *scheme); +typedef bool (*block_validate_t)(block_t *block, const block_scheme_t *scheme); struct block_scheme { const char *name; block_t block; size_t size; const config_entry_t *entries; - block_scheme_verify_t verify; + block_validate_t validate; + //block_resolve_t resolve; }; extern const block_scheme_t *block_schemes[]; diff --git a/src/blocks/text.c b/src/blocks/text.c index 0e5fc31..f2c1651 100644 --- a/src/blocks/text.c +++ b/src/blocks/text.c @@ -1,5 +1,17 @@ #include "scheme.h" +#include "../any_log.h" + +static bool block_text_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; + } + + return true; +} + const block_scheme_t block_text_scheme = { .name = "text", .block = { @@ -7,5 +19,5 @@ const block_scheme_t block_text_scheme = { }, .size = 0, .entries = NULL, - .verify = NULL, + .validate = block_text_validate, }; |
