static char * conf_t_check_prompt(EditLine *el) { mtev_console_closure_t ncct; mtev_conf_t_userdata_t *info; noit_check_t *check; static char *tl = "noit(conf)# "; static char *pfmt = "noit(conf:%s%s%s)# "; el_get(el, EL_USERDATA, (void *)&ncct); if(!ncct) return tl; info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); if(!info) return tl; check = noit_poller_lookup(info->current_check); if(check && check->target && check->target[0] && check->name && check->name[0]) snprintf(info->prompt, sizeof(info->prompt), pfmt, check->target, "`", check->name); else { char uuid_str[37]; uuid_unparse_lower(info->current_check, uuid_str); snprintf(info->prompt, sizeof(info->prompt), pfmt, "[", uuid_str, "]"); } return info->prompt; }
int noit_conf_check_unset_attr(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { struct _valid_attr_t *attrinfo = closure; mtev_conf_t_userdata_t *info; info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); if(!info || validate_attr_set_scope(info, attrinfo)) { nc_printf(ncct, "'%s' attribute only valid in %s scope\n", attrinfo->name, attrinfo->scope); return -1; } if(argc != 0) { nc_printf(ncct, "no arguments allowed to this command.\n"); return -1; } /* Okay, we have an attribute and it should be set/replaced on the * current path. */ if(replace_attr(ncct, info, attrinfo, NULL)) { return -1; } /* So, we updated an attribute, so we need to reload all checks * that are descendent-or-self of this node. */ if(!strncmp(info->path, "/checks", strlen("/checks"))) refresh_subchecks(ncct, info); if(!strncmp(info->path, "/filterset", strlen("/filterest"))) noit_refresh_filtersets(ncct, info); return 0; }
int noit_console_config_unsetconfig(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { mtev_conf_t_userdata_t *info; info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); if(argc != 1) { nc_printf(ncct, "one argument required.\n"); return -1; } /* Okay, we have an child name and it should be culled from * current path/config. */ if(replace_config(ncct, info, argv[0], NULL)) { return -1; } /* So, we updated an attribute, so we need to reload all checks * that are descendent-or-self of this node. */ refresh_subchecks(ncct, info); return 0; }
static int mtev_console_lua_repl_execute(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { lua_State *L; mtev_lua_repl_userdata_t *info; lua_general_conf_t *conf = NULL; lua_module_closure_t *lmc = NULL; char *buff; int i, rv; info = mtev_console_userdata_get(ncct, MTEV_LUA_REPL_USERDATA); if(info) { conf = get_config(info->self); lmc = pthread_getspecific(conf->key); } if(!lmc) { nc_printf(ncct, "Internal error, cannot find lua state.\n"); return -1; } #define EVALSIZE (1<<15) buff = malloc(EVALSIZE); buff[0] = '\0'; for(i=0;i<argc;i++) { if(i) strlcat(buff, " ", EVALSIZE); strlcat(buff, argv[i], EVALSIZE); } L = lmc->lua_state; lua_pushConsole(L, ncct); lua_getglobal(L, "mtev"); lua_getfield(L, -1, "extras"); lua_remove(L, -2); /* pop mtev */ lua_getfield(L, -1, "repl_eval"); lua_remove(L, -2); /* pop extras */ lua_pushstring(L, buff); lua_pushConsole(L, ncct); rv = lua_pcall(L, 2, LUA_MULTRET, -4); if(rv) { int i; i = lua_gettop(L); if(i>0) { if(lua_isstring(L, i)) { const char *err; size_t len; err = lua_tolstring(L, i, &len); nc_printf(ncct, "eval failed: %s\n", err); } } lua_pop(L, i); return -1; } lua_pop(L, lua_gettop(L)); free(buff); #undef EVALSIZE return 0; }
static int noit_console_filter_show(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { mtev_conf_t_userdata_t *info; char xpath[1024]; xmlNodePtr fsnode; mtev_conf_section_t *rules; int i, rulecnt; info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); snprintf(xpath, sizeof(xpath), "/%s", info->path); fsnode = mtev_conf_get_section(NULL, xpath); if(!fsnode) { nc_printf(ncct, "internal error\n"); return -1; } rules = mtev_conf_get_sections(fsnode, "rule", &rulecnt); for(i=0; i<rulecnt; i++) { char val[256]; val[0] = '\0'; mtev_conf_get_stringbuf(rules[i], "@type", val, sizeof(val)); nc_printf(ncct, "Rule %d [%s]:\n", i+1, val); #define DUMP_ATTR(a) do { \ char *vstr; \ mtev_conf_section_t ht; \ int cnt; \ ht = mtev_conf_get_sections(rules[i], #a, &cnt); \ if(ht && cnt) { \ nc_printf(ncct, "\t%s: hash match of %d items\n", #a, cnt); \ } \ else if(mtev_conf_get_string(rules[i], "@" #a, &vstr)) { \ nc_printf(ncct, "\t%s: /%s/\n", #a, val); \ free(vstr); \ } \ free(ht); \ } while(0) DUMP_ATTR(target); DUMP_ATTR(module); DUMP_ATTR(name); DUMP_ATTR(metric); DUMP_ATTR(id); DUMP_ATTR(skipto); } if(rules) free(rules); return 0; }
static char * conf_t_filterset_prompt(EditLine *el) { mtev_console_closure_t ncct; mtev_conf_t_userdata_t *info; static char *tl = "noit(conf)# "; static char *pfmt = "noit(conf:filterset:%.*s%s)# "; int max_space, namelen; el_get(el, EL_USERDATA, (void *)&ncct); if(!ncct) return tl; info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); if(!info) return tl; max_space = sizeof(info->prompt) - strlen(pfmt) + 6 - 1; namelen = strlen(info->filter_name); if(namelen > max_space) snprintf(info->prompt, sizeof(info->prompt), pfmt, max_space - 3, info->filter_name, "..."); else snprintf(info->prompt, sizeof(info->prompt), pfmt, namelen, info->filter_name, ""); return info->prompt; }
static char * lua_repl_prompt(EditLine *el) { mtev_console_closure_t ncct; mtev_lua_repl_userdata_t *info; static char *tl = "lua_general(%d/%p)# "; lua_general_conf_t *conf; lua_module_closure_t *lmc; el_get(el, EL_USERDATA, (void *)&ncct); if(!ncct) return tl; info = mtev_console_userdata_get(ncct, MTEV_LUA_REPL_USERDATA); if(!info) return tl; conf = get_config(info->self); lmc = pthread_getspecific(conf->key); if(!pthread_equal(eventer_get_owner(ncct->e), pthread_self())) snprintf(info->prompt, sizeof(info->prompt), "lua_general(...)# "); else snprintf(info->prompt, sizeof(info->prompt), tl, get_eventer_id(ncct), lmc->lua_state); return info->prompt; }
static int noit_console_filter_cull(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { int rv = 0; mtev_conf_t_userdata_t *info; info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); if(!info) { nc_printf(ncct, "internal error\n"); return -1; } if(strncmp(info->path, "/filtersets/", strlen("/filtersets/")) && strcmp(info->path, "/filtersets")) { nc_printf(ncct, "filterset only allows inside /filtersets (not %s)\n", info->path); return -1; } rv = noit_filtersets_cull_unused(); nc_printf(ncct, "Culled %d unused filtersets\n", rv); return 0; }
static int noit_console_config_show(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { mtev_hash_iter iter = MTEV_HASH_ITER_ZERO; const char *k; int klen; void *data; int i, cnt, titled = 0, cliplen = 0; const char *path = "", *basepath = NULL; char xpath[1024]; mtev_conf_t_userdata_t *info = NULL; mtev_hash_table *config; xmlXPathObjectPtr pobj = NULL; xmlXPathContextPtr xpath_ctxt = NULL, current_ctxt; xmlDocPtr master_config = NULL; xmlNodePtr node = NULL; mtev_conf_xml_xpath(&master_config, &xpath_ctxt); if(argc > 1) { nc_printf(ncct, "too many arguments\n"); return -1; } info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); if(info && info->path) path = basepath = info->path; if(!info && argc == 0) { nc_printf(ncct, "argument required when not in configuration mode\n"); return -1; } if(argc == 1) path = argv[0]; if(!basepath) basepath = path; /* { / } is a special case */ if(!strcmp(basepath, "/")) basepath = ""; if(!strcmp(path, "/")) path = ""; if(!master_config) { nc_printf(ncct, "no config\n"); return -1; } /* { / } is the only path that will end with a / * in XPath { / / * } means something _entirely different than { / * } * Ever notice how it is hard to describe xpath in C comments? */ /* We don't want to show the root node */ cliplen = strlen("/noit/"); /* If we are in configuration mode * and we are without an argument or the argument is absolute, * clip the current path off */ if(info && (argc == 0 || path[0] != '/')) cliplen += strlen(basepath); if(!path[0] || path[0] == '/') /* base only, or absolute path requested */ snprintf(xpath, sizeof(xpath), "/noit%s/@*", path); else snprintf(xpath, sizeof(xpath), "/noit%s/%s/@*", basepath, path); current_ctxt = xpath_ctxt; pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt); if(!pobj || pobj->type != XPATH_NODESET) { nc_printf(ncct, "no such object\n"); goto bad; } cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); titled = 0; for(i=0; i<cnt; i++) { node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); if(!strcmp((char *)node->name, "check")) continue; if(node->children && node->children == xmlGetLastChild(node) && xmlNodeIsText(node->children)) { char *node_str, *xmlpath; node_str = (char *)xmlXPathCastNodeToString(node->children); xmlpath = (char *)xmlGetNodePath(node); if(!titled++) nc_printf(ncct, "== Section Settings ==\n"); nc_printf(ncct, "%s: %s\n", xmlpath + cliplen, node_str); free(xmlpath); free(node_str); } } xmlXPathFreeObject(pobj); /* Print out all the config settings */ if(!path[0] || path[0] == '/') /* base only, or absolute path requested */ snprintf(xpath, sizeof(xpath), "/noit%s", path); else snprintf(xpath, sizeof(xpath), "/noit%s/%s", basepath, path); pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt); if(!pobj || pobj->type != XPATH_NODESET) { nc_printf(ncct, "no such object\n"); goto bad; } cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); if(cnt > 0) { node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); titled = 0; config = mtev_conf_get_hash(node, "config"); while(mtev_hash_next(config, &iter, &k, &klen, &data)) { if(!titled++) nc_printf(ncct, "== Section [Aggregated] Config ==\n"); nc_printf(ncct, "config::%s: %s\n", k, (const char *)data); } mtev_hash_destroy(config, free, free); free(config); } xmlXPathFreeObject(pobj); /* _shorten string_ turning last { / @ * } to { / * } */ if(!path[0] || path[0] == '/') /* base only, or absolute path requested */ snprintf(xpath, sizeof(xpath), "/noit%s/*", path); else snprintf(xpath, sizeof(xpath), "/noit%s/%s/*", basepath, path); pobj = xmlXPathEval((xmlChar *)xpath, current_ctxt); if(!pobj || pobj->type != XPATH_NODESET) { nc_printf(ncct, "no such object\n"); goto bad; } cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); titled = 0; for(i=0; i<cnt; i++) { char *xmlpath; node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); if(!strcmp((char *)node->name, "check")) continue; if(!strcmp((char *)node->name, "filterset")) continue; xmlpath = (char *)xmlGetNodePath(node); if(strcmp(xmlpath + cliplen, "config")) { if(!(node->children && node->children == xmlGetLastChild(node) && xmlNodeIsText(node->children))) { if(!titled++) nc_printf(ncct, "== Subsections ==\n"); nc_printf(ncct, "%s\n", xmlpath + cliplen); } } free(xmlpath); } titled = 0; for(i=0; i<cnt; i++) { node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); if(!strcmp((char *)node->name, "filterset")) { xmlAttr *attr; char *filter_name = NULL; for(attr=node->properties; attr; attr = attr->next) { if(!strcmp((char *)attr->name, "name")) filter_name = (char *)xmlXPathCastNodeToString(attr->children); } if(filter_name) { nc_printf(ncct, "filterset[@name=\"%s\"]\n", filter_name); xmlFree(filter_name); } else nc_printf(ncct, "fitlerset\n"); } else if(!strcmp((char *)node->name, "check")) { int busted = 1; xmlAttr *attr; char *uuid_str = NULL; uuid_t checkid; if(!titled++) nc_printf(ncct, "== Checks ==\n"); for(attr=node->properties; attr; attr = attr->next) { if(!strcmp((char *)attr->name, "uuid")) { uuid_str = (char *)xmlXPathCastNodeToString(attr->children); break; } } nc_printf(ncct, "check[@uuid=\"%s\"] ", uuid_str ? uuid_str : "undefined"); if(uuid_str && uuid_parse(uuid_str, checkid) == 0) { noit_check_t *check; check = noit_poller_lookup(checkid); if(check) { busted = 0; nc_printf(ncct, "%s`%s`%s", check->target, check->module, check->name); } } if(uuid_str) free(uuid_str); if(busted) nc_printf(ncct, "[check not in running system]"); nc_write(ncct, "\n", 1); } } xmlXPathFreeObject(pobj); return 0; bad: if(pobj) xmlXPathFreeObject(pobj); return -1; }
static int noit_console_config_nocheck(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { int i, cnt; const char *err = "internal error"; mtev_conf_t_userdata_t *info; xmlXPathObjectPtr pobj = NULL; xmlXPathContextPtr xpath_ctxt = NULL; char xpath[1024]; uuid_t checkid; mtev_conf_xml_xpath(NULL, &xpath_ctxt); if(argc < 1) { nc_printf(ncct, "requires one argument\n"); return -1; } info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); if(noit_console_mkcheck_xpath(xpath, sizeof(xpath), info, argv[0])) { nc_printf(ncct, "could not find check '%s'\n", argv[0]); return -1; } pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); if(!pobj || pobj->type != XPATH_NODESET || xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { err = "no checks found"; goto bad; } cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); for(i=0; i<cnt; i++) { xmlNodePtr node; char *uuid_conf; node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid"); if(!uuid_conf || uuid_parse(uuid_conf, checkid)) { nc_printf(ncct, "%s has invalid or missing UUID!\n", (char *)xmlGetNodePath(node) + strlen("/noit")); } else { if(argc > 1) { int j; for(j=1;j<argc;j++) xmlUnsetProp(node, (xmlChar *)argv[j]); noit_conf_check_bump_seq(node); CONF_DIRTY(node); } else { nc_printf(ncct, "descheduling %s\n", uuid_conf); noit_poller_deschedule(checkid, mtev_true); CONF_REMOVE(node); xmlUnlinkNode(node); } mtev_conf_mark_changed(); } xmlFree(uuid_conf); } if(argc > 1) { noit_poller_process_checks(xpath); noit_poller_reload(xpath); } nc_printf(ncct, "rebuilding causal map...\n"); noit_poller_make_causal_map(); if(pobj) xmlXPathFreeObject(pobj); return 0; bad: if(pobj) xmlXPathFreeObject(pobj); nc_printf(ncct, "%s\n", err); return -1; }
static int noit_console_show_check(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { int i, cnt; mtev_conf_t_userdata_t *info; char xpath[1024]; xmlXPathObjectPtr pobj = NULL; xmlXPathContextPtr xpath_ctxt = NULL; mtev_conf_xml_xpath(NULL, &xpath_ctxt); if(argc > 1) { nc_printf(ncct, "requires zero or one arguments\n"); return -1; } info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); /* We many not be in conf-t mode -- that's fine */ if(noit_console_mkcheck_xpath(xpath, sizeof(xpath), info, argc ? argv[0] : NULL)) { nc_printf(ncct, "could not find check '%s'\n", argv[0]); return -1; } pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); if(!pobj || pobj->type != XPATH_NODESET || xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { nc_printf(ncct, "no checks found\n"); goto out; } cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); if(info && cnt != 1) { nc_printf(ncct, "Ambiguous check specified\n"); goto out; } for(i=0; i<cnt; i++) { mtev_hash_iter iter = MTEV_HASH_ITER_ZERO; const char *k; int klen; void *data; uuid_t checkid; noit_check_t *check; mtev_hash_table *config; xmlNodePtr node, anode, mnode = NULL; char *uuid_conf; char *module, *value; node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid"); if(!uuid_conf || uuid_parse(uuid_conf, checkid)) { nc_printf(ncct, "%s has invalid or missing UUID!\n", (char *)xmlGetNodePath(node) + strlen("/noit")); continue; } nc_printf(ncct, "==== %s ====\n", uuid_conf); xmlFree(uuid_conf); #define MYATTR(a,n,b) _mtev_conf_get_string(node, &(n), "@" #a, &(b)) #define INHERIT(a,n,b) \ _mtev_conf_get_string(node, &(n), "ancestor-or-self::node()/@" #a, &(b)) #define SHOW_ATTR(a) do { \ anode = NULL; \ value = NULL; \ INHERIT(a, anode, value); \ nc_attr_show(ncct, #a, node, anode, value); \ if(value != NULL) free(value); \ } while(0) if(!INHERIT(module, mnode, module)) module = NULL; if(MYATTR(name, anode, value)) { nc_printf(ncct, " name: %s\n", value); free(value); } else nc_printf(ncct, " name: %s [from module]\n", module ? module : "[undef]"); nc_attr_show(ncct, "module", node, mnode, module); if(module) free(module); SHOW_ATTR(target); SHOW_ATTR(seq); SHOW_ATTR(resolve_rtype); SHOW_ATTR(period); SHOW_ATTR(timeout); SHOW_ATTR(oncheck); SHOW_ATTR(filterset); SHOW_ATTR(disable); /* Print out all the config settings */ config = mtev_conf_get_hash(node, "config"); while(mtev_hash_next(config, &iter, &k, &klen, &data)) { nc_printf(ncct, " config::%s: %s\n", k, (const char *)data); } mtev_hash_destroy(config, free, free); free(config); check = noit_poller_lookup(checkid); if(!check) { nc_printf(ncct, " ERROR: not in running system\n"); } else { int idx = 0; stats_t *c; struct timeval *whence; mtev_hash_table *metrics; nc_printf(ncct, " target_ip: %s\n", check->target_ip); nc_printf(ncct, " currently: %08x ", check->flags); if(NOIT_CHECK_RUNNING(check)) { nc_printf(ncct, "running"); idx++; } if(NOIT_CHECK_KILLED(check)) nc_printf(ncct, "%skilled", idx++?",":""); if(!NOIT_CHECK_CONFIGURED(check)) nc_printf(ncct, "%sunconfig", idx++?",":""); if(NOIT_CHECK_DISABLED(check)) nc_printf(ncct, "%sdisabled", idx++?",":""); if(!idx) nc_printf(ncct, "idle"); nc_write(ncct, "\n", 1); if (check->fire_event != NULL) { struct timeval now, diff; mtev_gettimeofday(&now, NULL); sub_timeval(check->fire_event->whence, now, &diff); nc_printf(ncct, " next run: %0.3f seconds\n", diff.tv_sec + (diff.tv_usec / 1000000.0)); } else { nc_printf(ncct, " next run: unscheduled\n"); } c = noit_check_get_stats_current(check); whence = noit_check_stats_whence(c, NULL); if(whence->tv_sec == 0) { nc_printf(ncct, " last run: never\n"); } else { const char *status; struct timeval now, *then, diff; mtev_gettimeofday(&now, NULL); then = noit_check_stats_whence(c, NULL); sub_timeval(now, *then, &diff); nc_printf(ncct, " last run: %0.3f seconds ago\n", diff.tv_sec + (diff.tv_usec / 1000000.0)); nc_printf(ncct, " availability/state: %s/%s\n", noit_check_available_string(noit_check_stats_available(c, NULL)), noit_check_state_string(noit_check_stats_state(c, NULL))); status = noit_check_stats_status(c, NULL); nc_printf(ncct, " status: %s\n", status); nc_printf(ncct, " feeds: %d\n", check->feeds ? check->feeds->size : 0); } c = noit_check_get_stats_inprogress(check); metrics = noit_check_stats_metrics(c); if(mtev_hash_size(metrics) > 0) { nc_printf(ncct, " metrics (inprogress):\n"); nc_print_stat_metrics(ncct, check, c); } c = noit_check_get_stats_current(check); metrics = noit_check_stats_metrics(c); if(mtev_hash_size(metrics)) { nc_printf(ncct, " metrics (current):\n"); nc_print_stat_metrics(ncct, check, c); } c = noit_check_get_stats_previous(check); metrics = noit_check_stats_metrics(c); if(mtev_hash_size(metrics) > 0) { nc_printf(ncct, " metrics (previous):\n"); nc_print_stat_metrics(ncct, check, c); } } } out: if(pobj) xmlXPathFreeObject(pobj); return 0; }
static int noit_console_check(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { int cnt; mtev_conf_t_userdata_t *info; char xpath[1024], newuuid_str[37]; char *uuid_conf = NULL, *wanted; uuid_t checkid; xmlXPathContextPtr xpath_ctxt = NULL; xmlXPathObjectPtr pobj = NULL; xmlNodePtr node = NULL; mtev_boolean creating_new = mtev_false; if(closure) { char *fake_argv[1] = { ".." }; mtev_console_state_pop(ncct, 0, argv, NULL, NULL); mtev_console_config_cd(ncct, 1, fake_argv, NULL, NULL); } mtev_conf_xml_xpath(NULL, &xpath_ctxt); if(argc < 1) { nc_printf(ncct, "requires at least one argument\n"); return -1; } if(argc % 2 == 0) { nc_printf(ncct, "wrong number of arguments\n"); return -1; } info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); wanted = strcmp(argv[0], "new") ? argv[0] : NULL; if(info && !wanted) { /* We are creating a new node */ uuid_t out; creating_new = mtev_true; if(strncmp(info->path, "/checks/", strlen("/checks/")) && strcmp(info->path, "/checks")) { nc_printf(ncct, "New checks must be under /checks/\n"); return -1; } if(noit_conf_mkcheck_under(info->path, argc - 1, argv + 1, out)) { nc_printf(ncct, "Error creating new check\n"); return -1; } newuuid_str[0] = '\0'; uuid_unparse_lower(out, newuuid_str); wanted = newuuid_str; } /* We many not be in conf-t mode -- that's fine */ if(noit_console_mkcheck_xpath(xpath, sizeof(xpath), info, wanted)) { nc_printf(ncct, "could not find check '%s'\n", wanted); return -1; } pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt); if(!pobj || pobj->type != XPATH_NODESET || xmlXPathNodeSetIsEmpty(pobj->nodesetval)) { nc_printf(ncct, "no checks found for '%s'\n", wanted); goto out; } cnt = xmlXPathNodeSetGetLength(pobj->nodesetval); if(info && cnt != 1) { nc_printf(ncct, "Ambiguous check specified\n"); goto out; } node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); uuid_conf = (char *)xmlGetProp(node, (xmlChar *)"uuid"); if(!node || !uuid_conf || uuid_parse(uuid_conf, checkid)) { nc_printf(ncct, "%s has invalid or missing UUID!\n", (char *)xmlGetNodePath(node) + strlen("/noit")); goto out; } if(argc > 1 && !creating_new) { if(noit_config_check_update_attrs(node, argc - 1, argv + 1)) nc_printf(ncct, "Partially successful, error setting some attributes\n"); noit_conf_check_bump_seq(node); } if(info) { char *xmlpath; if(info->path) free(info->path); xmlpath = (char *)xmlGetNodePath(node); info->path = strdup(xmlpath + strlen("/noit")); free(xmlpath); uuid_copy(info->current_check, checkid); if(argc > 1) refresh_subchecks(ncct, info); if(state) { mtev_console_state_push_state(ncct, state); mtev_console_state_init(ncct); } goto out; } out: if(uuid_conf) free(uuid_conf); if(pobj) xmlXPathFreeObject(pobj); return 0; }
static int noit_console_filter_configure(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { xmlNodePtr parent, fsnode = NULL; int rv = -1; mtev_conf_t_userdata_t *info; char xpath[1024]; info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); if(!info) { nc_printf(ncct, "internal error\n"); goto cleanup; } if(strncmp(info->path, "/filtersets/", strlen("/filtersets/")) && strcmp(info->path, "/filtersets")) { nc_printf(ncct, "filterset only allows inside /filtersets (not %s)\n", info->path); goto cleanup; } if(argc != 1) { nc_printf(ncct, "filterset requires one argument\n"); goto cleanup; } snprintf(xpath, sizeof(xpath), "/%s", info->path); parent = mtev_conf_get_section(NULL, xpath); if(!parent) { nc_printf(ncct, "internal error, can't final current working path\n"); goto cleanup; } snprintf(xpath, sizeof(xpath), "filterset[@name=\"%s\"]", argv[0]); fsnode = mtev_conf_get_section(parent, xpath); if(closure) { int removed; removed = noit_filter_remove(fsnode); nc_printf(ncct, "%sremoved filterset '%s'\n", removed ? "" : "failed to ", argv[0]); if(removed) { CONF_REMOVE(fsnode); xmlUnlinkNode(fsnode); xmlFreeNode(fsnode); } rv = !removed; goto cleanup; } if(!fsnode) { void *vfs; nc_printf(ncct, "Cannot find filterset '%s'\n", argv[0]); LOCKFS(); if(mtev_hash_retrieve(filtersets, argv[0], strlen(argv[0]), &vfs)) { UNLOCKFS(); nc_printf(ncct, "filter of the same name already exists\n"); goto cleanup; } UNLOCKFS(); /* Fine the parent path */ fsnode = xmlNewNode(NULL, (xmlChar *)"filterset"); xmlSetProp(fsnode, (xmlChar *)"name", (xmlChar *)argv[0]); xmlAddChild(parent, fsnode); nc_printf(ncct, "created new filterset\n"); } if(info) { char *xmlpath = NULL; free(info->path); xmlpath = (char *)xmlGetNodePath(fsnode); info->path = strdup(xmlpath + strlen("/noit")); free(xmlpath); strlcpy(info->filter_name, argv[0], sizeof(info->filter_name)); if(state) { mtev_console_state_push_state(ncct, state); mtev_console_state_init(ncct); } } cleanup: return rv; }
static int noit_console_rule_configure(mtev_console_closure_t ncct, int argc, char **argv, mtev_console_state_t *state, void *closure) { xmlNodePtr fsnode = NULL; mtev_conf_t_userdata_t *info; char xpath[1024]; info = mtev_console_userdata_get(ncct, MTEV_CONF_T_USERDATA); snprintf(xpath, sizeof(xpath), "/%s", info->path); fsnode = mtev_conf_get_section(NULL, xpath); if(!fsnode) { nc_printf(ncct, "internal error"); return -1; } if(closure) { int rulenum; xmlNodePtr byebye; /* removing a rule */ if(argc != 1) { nc_printf(ncct, "requires one argument\n"); return -1; } rulenum = atoi(argv[0]); snprintf(xpath, sizeof(xpath), "rule[%d]", rulenum); byebye = mtev_conf_get_section(fsnode, xpath); if(!byebye) { nc_printf(ncct, "cannot find rule\n"); return -1; } xmlUnlinkNode(byebye); xmlFreeNode(byebye); nc_printf(ncct, "removed\n"); } else { xmlNodePtr (*add_func)(xmlNodePtr, xmlNodePtr); xmlNodePtr add_arg, new_rule; int i, needs_type = 1; if(argc < 1 || argc % 2) { nc_printf(ncct, "even number of arguments required\n"); return -1; } if(!strcmp(argv[0], "before") || !strcmp(argv[0], "after")) { int rulenum = atoi(argv[1]); snprintf(xpath, sizeof(xpath), "rule[%d]", rulenum); add_arg = mtev_conf_get_section(fsnode, xpath); if(!add_arg) { nc_printf(ncct, "%s rule not found\n", xpath); return -1; } if(*argv[0] == 'b') add_func = xmlAddPrevSibling; else add_func = xmlAddNextSibling; argc -= 2; argv += 2; } else { add_func = xmlAddChild; add_arg = fsnode; } for(i=0;i<argc;i+=2) { if(!strcmp(argv[i], "type")) needs_type = 0; else if(strcmp(argv[i], "target") && strcmp(argv[i], "module") && strcmp(argv[i], "name") && strcmp(argv[i], "metric") && strcmp(argv[i], "id")) { nc_printf(ncct, "unknown attribute '%s'\n", argv[i]); return -1; } } if(needs_type) { nc_printf(ncct, "type <allow|deny> is required\n"); return -1; } new_rule = xmlNewNode(NULL, (xmlChar *)"rule"); for(i=0;i<argc;i+=2) xmlSetProp(new_rule, (xmlChar *)argv[i], (xmlChar *)argv[i+1]); add_func(add_arg, new_rule); noit_filter_compile_add((mtev_conf_section_t *)fsnode); } return 0; }