#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 }; char *s = fgets(buffer, sizeof(buffer), output); pclose(output); if (s == NULL) { log_value_warn("Failed to execute a script", "s:label", block->label, "s:script", script->script); return; } 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 config_status_t block_script_change(block_t *block, config_t *config, const char *key, const char *value) { if (!strcmp(key, "text")) { log_panic("TODO"); return CONFIG_SUCCESS; } extern const config_entry_t block_text_entries[]; return config_read_entry(block_text_entries, block, NULL, key, value); } const block_scheme_t block_script_scheme = { .name = "script", .entries = NULL, .size = sizeof(block_script_t), .init_fn = block_script_init, .clean_fn = block_script_clean, .validate_fn = block_script_validate, .change_fn = block_script_change, };