#include #include #include #include #include "../block.h" #include "../any_log.h" typedef struct { block_text_t block; char *script; } block_script_t; static const struct timespec block_script_interval = { .tv_sec = 30, .tv_nsec = 0, }; static void block_script_update(block_t *block) { block_script_t *script = (block_script_t *)block; FILE *output = popen(script->script, "r"); if (output == NULL) { log_value_debug("Failed to execute a script", "s:label", block->label, "s:script", script->script, "i:errno", errno); return; } char buffer[128] = { 0 }; fgets(buffer, sizeof(buffer), output); pclose(output); log_value_trace("Executed a script", "s:label", block->label, "s:script", script->script); free(script->block.text); script->block.text = strcopy(buffer); assert(script->block.text != NULL); } static void block_script_init(block_t *block) { extern const block_scheme_t block_text_scheme; block_text_scheme.init_fn(block); block->update_interval = block_script_interval; block->update_fn = block_script_update; } static void block_script_clean(block_t *block) { block_script_t *script = (block_script_t *)block; free(script->script); free(script->block.text); } static int block_script_validate(block_t *block, config_t *config) { block_script_t *script = (block_script_t *)block; int errors = 0; if (script->block.text == NULL) { log_error("Block '%s' requires key '%s'", block->label, "text"); errors++; } script->script = script->block.text; script->block.text = strcopy("?"); return errors; } static const config_entry_t block_script_entries[] = { { 0 }, }; const block_scheme_t block_script_scheme = { .name = "script", .entries = block_script_entries, .size = sizeof(block_script_t), .init_fn = block_script_init, .clean_fn = block_script_clean, .validate_fn = block_script_validate, };