static int
noit_conf_mkcheck_under(const char *ppath, int argc, char **argv, uuid_t out) {
  int rv = -1;
  const char *path;
  char xpath[1024];
  xmlXPathContextPtr xpath_ctxt = NULL;
  xmlXPathObjectPtr pobj = NULL;
  xmlNodePtr node = NULL, newnode;

  /* attr val [or] no attr (sets of two) */
  if(argc % 2) goto out;

  mtev_conf_xml_xpath(NULL, &xpath_ctxt);
  path = strcmp(ppath, "/") ? ppath : "";
  snprintf(xpath, sizeof(xpath), "/noit%s", path);
  pobj = xmlXPathEval((xmlChar *)xpath, xpath_ctxt);
  if(!pobj || pobj->type != XPATH_NODESET ||
     xmlXPathNodeSetGetLength(pobj->nodesetval) != 1) {
    goto out;
  }
  node = (mtev_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
  if((newnode = xmlNewChild(node, NULL, (xmlChar *)"check", NULL)) != NULL) {
    char outstr[37];
    uuid_generate(out);
    uuid_unparse_lower(out, outstr);
    xmlSetProp(newnode, (xmlChar *)"uuid", (xmlChar *)outstr);
    xmlSetProp(newnode, (xmlChar *)"disable", (xmlChar *)"true");

    /* No risk of running off the end (we checked this above) */
    if(noit_config_check_update_attrs(newnode, argc, argv)) {
      /* Something went wrong, remove the node */
      xmlUnlinkNode(newnode);
    }
    else {
      CONF_DIRTY(newnode);
      mtev_conf_mark_changed();
      rv = 0;
    }
  }
 out:
  if(pobj) xmlXPathFreeObject(pobj);
  return rv;
}
Example #2
0
static int
noit_console_check(noit_console_closure_t ncct,
                   int argc, char **argv,
                   noit_console_state_t *state, void *closure) {
  int cnt;
  noit_conf_t_userdata_t *info;
  char xpath[1024], newuuid_str[37];
  char *uuid_conf, *wanted;
  uuid_t checkid;
  xmlXPathContextPtr xpath_ctxt = NULL;
  xmlXPathObjectPtr pobj = NULL;
  xmlNodePtr node = NULL;
  noit_boolean creating_new = noit_false;

  if(closure) {
    char *fake_argv[1] = { ".." };
    noit_console_state_pop(ncct, 0, argv, NULL, NULL);
    noit_console_config_cd(ncct, 1, fake_argv, NULL, NULL);
  }

  noit_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 = noit_console_userdata_get(ncct, NOIT_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 = noit_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 = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0);
  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"));
    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");

  if(info) {
    if(info->path) free(info->path);
    info->path = strdup((char *)xmlGetNodePath(node) + strlen("/noit"));
    uuid_copy(info->current_check, checkid);
    if(argc > 1) refresh_subchecks(ncct, info);
    if(state) {
      noit_console_state_push_state(ncct, state);
      noit_console_state_init(ncct);
    }
    goto out;
  }
 out:
  if(pobj) xmlXPathFreeObject(pobj);
  return 0;
}