static void nc_telnet_cooker(noit_console_closure_t ncct) { char *tmpbuf, *p, *n; int r; tmpbuf = ncct->outbuf; if(ncct->outbuf_len == 0) return; p = ncct->outbuf + ncct->outbuf_completed; r = ncct->outbuf_len - ncct->outbuf_completed; n = memchr(p, '\n', r); /* No '\n'? Nothin' to do */ if(!n) { ncct->outbuf_cooked = ncct->outbuf_len; return; } /* Forget the outbuf -- it is now tmpbuf */ ncct->outbuf = NULL; ncct->outbuf_allocd = 0; ncct->outbuf_len = 0; ncct->outbuf_completed = 0; ncct->outbuf_cooked = 0; do { nc_write(ncct, p, n-p); r -= n-p; if(n == tmpbuf || *(n-1) != '\r') nc_write(ncct, "\r", 1); p = n; n = memchr(p+1, '\n', r-1); } while(n); nc_write(ncct, p, r); ncct->outbuf_cooked = ncct->outbuf_len; free(tmpbuf); }
int hc_post_request(struct hc * hc, int (*callback)(unsigned char *, size_t, void *), void * v) { char buffer[1024]; size_t l; struct hc_headers * h; l = strlen(hc->localpart) + strlen("POST HTTP/1.0\r\n"); for (h = hc->req_headers; h; h = h->next) l += strlen(h->tag) + strlen(h->value) + 4; l += 3; if (l > sizeof buffer) { fprintf(stderr, "ERROR: hc_post_request: buffer too small; need %lu\n", (unsigned long)l); return -1; } l = sprintf(buffer, "POST %s HTTP/1.0\r\n", hc->localpart); for (h = hc->req_headers; h; h = h->next) l += sprintf(buffer+l, "%s: %s\r\n", h->tag, h->value); l += sprintf(buffer+l, "\r\n"); nc_write(hc->nc, buffer, l); while ((l = callback(buffer, sizeof buffer, v)) != 0) { int r; r = nc_write(hc->nc, buffer, l); // fprintf(stderr, "%d\n", r); } if (nc_read_line(hc->nc, buffer, sizeof buffer) <= 0) { perror("ERROR: hc_post_request nc_read_line"); return -1; } hc->status = strdup(buffer); while (nc_read_line(hc->nc, buffer, sizeof buffer) > 0) { char * e; e = strchr(buffer, ':'); if (e) { *e = '\0'; e++; while (isspace(*e)) e++; h = hc_h_make(buffer, e); h->next = hc->rsp_headers; hc->rsp_headers = h; } else { fprintf(stderr, "ERROR: hc_post_request got invalid header line :%s:\n", buffer); } } return 0; }
static int nc_write_endtag(struct nc_session *session) { int ret; if (session->version == NC_VERSION_11) { ret = nc_write(session, "\n##\n", 4); } else { ret = nc_write(session, "]]>]]>", 6); } return ret; }
void _log_stderr(const char *fmt, ...) { struct logger *l = &logger; int len, size, errno_save; char buf[4 * LOG_MAX_LEN]; va_list args; ssize_t n; errno_save = errno; len = 0; /* length of output buffer */ size = 4 * LOG_MAX_LEN; /* size of output buffer */ va_start(args, fmt); len += nc_vscnprintf(buf, size, fmt, args); va_end(args); buf[len++] = '\n'; n = nc_write(STDERR_FILENO, buf, len); if (n < 0) { l->nerror++; } errno = errno_save; }
static rstatus_t nc_create_pidfile(struct instance *nci) { char pid[NC_UINTMAX_MAXLEN]; int fd, pid_len; ssize_t n; fd = open(nci->pid_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd < 0) { log_error("opening pid file '%s' failed: %s", nci->pid_filename, strerror(errno)); return NC_ERROR; } nci->pidfile = 1; pid_len = nc_snprintf(pid, NC_UINTMAX_MAXLEN, "%d", nci->pid); n = nc_write(fd, pid, pid_len); if (n < 0) { log_error("write to pid file '%s' failed: %s", nci->pid_filename, strerror(errno)); return NC_ERROR; } close(fd); return NC_OK; }
static int noit_console_logio_write(noit_log_stream_t ls, const void *buf, size_t len) { noit_console_closure_t ncct; ncct = noit_log_stream_get_ctx(ls); int rv, rlen, mask; if(!ncct) return 0; rlen = nc_write(ncct, buf, len); while((rv = noit_console_continue_sending(ncct, &mask)) == -1 && errno == EINTR); if(rv == -1 && errno == EAGAIN) { eventer_update(ncct->e, mask | EVENTER_EXCEPTION); } return rlen; }
static int nc_write_starttag_and_msg(struct nc_session *session, const void *buf, size_t count) { int ret = 0, c; char chunksize[20]; if (session->version == NC_VERSION_11) { sprintf(chunksize, "\n#%zu\n", count); ret = nc_write(session, chunksize, strlen(chunksize)); if (ret == -1) { return -1; } } c = nc_write(session, buf, count); if (c == -1) { return -1; } ret += c; return ret; }
static ssize_t conn_send_buf(struct conn *conn, void *buf, size_t size) { ssize_t n; ASSERT(buf != NULL); ASSERT(size > 0); ASSERT(conn->send_ready); for (;;) { n = nc_write(conn->fd, buf, size); log_verb("sendv on fd %d %zd of %zu", conn->fd, n, size); if (n > 0) { if (n < (ssize_t)size) { conn->send_ready = 0; } conn->send_bytes += (size_t)n; return n; } if (n == 0) { log_warn("sendv on fd %d returned zero", conn->fd); conn->send_ready = 0; return 0; } if (errno == EINTR) { log_verb("sendv on fd %d not ready - eintr", conn->fd); continue; } else if (errno == EAGAIN || errno == EWOULDBLOCK) { conn->send_ready = 0; log_verb("sendv on fd %d not ready - eagain", conn->fd); return NC_EAGAIN; } else { conn->send_ready = 0; conn->err = errno; log_error("sendv on fd %d failed: %s", conn->fd, strerror(errno)); return NC_ERROR; } } NOT_REACHED(); return NC_ERROR; }
static rstatus_t stats_send_rsp(struct stats *st) { rstatus_t status; ssize_t n; int sd; int fd; status = stats_make_rsp(st); if (status != NC_OK) { return status; } /* sd = accept(st->sd, NULL, NULL); if (sd < 0) { log_error("accept on m %d failed: %s", st->sd, strerror(errno)); return NC_ERROR; } log_debug(LOG_VERB, "send stats on sd %d %d bytes", sd, st->buf.len); n = nc_sendn(sd, st->buf.data, st->buf.len); if (n < 0) { log_error("send stats on sd %d failed: %s", sd, strerror(errno)); close(sd); return NC_ERROR; } close(sd); */ fd = get_logger_fd(); if (fd < 0) { return; } n = nc_write(fd, st->buf.data, st->buf.len); if (n < 0) { log_error("nc_write %d failed: %s", fd, strerror(errno)); return NC_ERROR; } return NC_OK; }
void _log(int level, const char *file, int line, int panic, const char *fmt, ...) { struct logger *l = &logger; int len, size, errno_save; char buf[LOG_MAX_LEN]; va_list args; ssize_t n; struct timeval tv; if (l->fd < 0) { return; } errno_save = errno; len = 0; /* length of output buffer */ size = LOG_MAX_LEN; /* size of output buffer */ gettimeofday(&tv, NULL); buf[len++] = '['; len += (int)strftime(buf + len, (size_t)(size - len), "%Y-%m-%d %H:%M:%S.", localtime(&tv.tv_sec)); len += nc_scnprintf(buf + len, size - len, "%03d", (int)tv.tv_usec/1000); len += nc_scnprintf(buf + len, size - len, "] %6s [%"PRIu64"] ", log_level_s(level), gettid()); len += nc_scnprintf(buf + len, size - len, "%s:%d ", file, line); va_start(args, fmt); len += nc_vscnprintf(buf + len, size - len, fmt, args); va_end(args); buf[len++] = '\n'; n = nc_write(l->fd, buf, len); if (n < 0) { l->nerror++; } errno = errno_save; if (panic) { abort(); } }
static void nc_attr_show(noit_console_closure_t ncct, const char *name, xmlNodePtr cnode, xmlNodePtr anode, const char *value) { const char *cpath, *apath; cpath = cnode ? (char *)xmlGetNodePath(cnode) : ""; apath = anode ? (char *)xmlGetNodePath(anode) : ""; nc_printf(ncct, " %s: %s", name, value ? value : "[undef]"); if(value && cpath && apath) { int clen = strlen(cpath); int plen = strlen("/noit/checks/"); if(!strncmp(cpath, apath, clen) && apath[clen] == '/') { /* we have a match, which means it isn't inherited */ } else { nc_printf(ncct, " [inherited from %s]", strlen(apath) > plen ? apath + plen : apath); } } nc_write(ncct, "\n", 1); }
int noit_console_handler(eventer_t e, int mask, void *closure, struct timeval *now) { int newmask = EVENTER_READ | EVENTER_EXCEPTION; int keep_going; acceptor_closure_t *ac = closure; noit_console_closure_t ncct = ac->service_ctx; if(mask & EVENTER_EXCEPTION || (ncct && ncct->wants_shutdown)) { socket_error: /* Exceptions cause us to simply snip the connection */ /* This removes the log feed which is important to do before calling close */ eventer_remove_fd(e->fd); if(ncct) noit_console_closure_free(ncct); if(ac) acceptor_closure_free(ac); e->opset->close(e->fd, &newmask, e); return 0; } if(!ac->service_ctx) { ncct = ac->service_ctx = noit_console_closure_alloc(); } if(!ncct->initialized) { ncct->e = e; if(allocate_pty(&ncct->pty_master, &ncct->pty_slave)) { nc_printf(ncct, "Failed to open pty: %s\n", strerror(errno)); ncct->wants_shutdown = 1; goto socket_error; } else { int i; const char *line_protocol; HistEvent ev; ncct->hist = history_init(); history(ncct->hist, &ev, H_SETSIZE, 500); ncct->el = el_init("noitd", ncct->pty_master, NULL, e->fd, e, e->fd, e); if(!ncct->el) goto socket_error; if(el_set(ncct->el, EL_USERDATA, ncct)) { noitL(noit_error, "Cannot set userdata on noitedit session\n"); goto socket_error; } if(el_set(ncct->el, EL_EDITOR, "emacs")) noitL(noit_error, "Cannot set emacs mode on console\n"); if(el_set(ncct->el, EL_HIST, history, ncct->hist)) noitL(noit_error, "Cannot set history on console\n"); el_set(ncct->el, EL_ADDFN, "noit_complete", "auto completion functions for noit", noit_edit_complete); el_set(ncct->el, EL_BIND, "^I", "noit_complete", NULL); for(i=EL_NUM_FCNS; i < ncct->el->el_map.nfunc; i++) { if(ncct->el->el_map.func[i] == noit_edit_complete) { ncct->noit_edit_complete_cmdnum = i; break; } } if(!noit_hash_retr_str(ac->config, "line_protocol", strlen("line_protocol"), &line_protocol)) { line_protocol = NULL; } if(line_protocol && !strcasecmp(line_protocol, "telnet")) { ncct->telnet = noit_console_telnet_alloc(ncct); ncct->output_cooker = nc_telnet_cooker; } noit_console_state_init(ncct); } snprintf(ncct->feed_path, sizeof(ncct->feed_path), "console/%d", e->fd); noit_log_stream_new(ncct->feed_path, "noit_console", ncct->feed_path, ncct, NULL); noit_console_motd(e, ac, ncct); ncct->initialized = 1; } /* If we still have data to send back to the client, this will take * care of that */ if(noit_console_continue_sending(ncct, &newmask) < 0) { if(ncct->wants_shutdown || errno != EAGAIN) goto socket_error; return newmask | EVENTER_EXCEPTION; } for(keep_going=1 ; keep_going ; ) { int len, plen; char sbuf[4096]; const char *buffer; keep_going = 0; buffer = el_gets(ncct->el, &plen); if(!el_eagain(ncct->el)) { if(!buffer) { buffer = "exit"; plen = 4; nc_write(ncct, "\n", 1); } keep_going++; } len = e->opset->read(e->fd, sbuf, sizeof(sbuf)-1, &newmask, e); if(len == 0 || (len < 0 && errno != EAGAIN)) { eventer_remove_fd(e->fd); if(ncct) noit_console_closure_free(ncct); if(ac) acceptor_closure_free(ac); e->opset->close(e->fd, &newmask, e); return 0; } if(len > 0) { keep_going++; sbuf[len] = '\0'; if(ncct->telnet) { noit_console_telnet_telrcv(ncct, sbuf, len); ptyflush(ncct); } else { int written; written = write(ncct->pty_slave, sbuf, len); if(written <= 0) goto socket_error; assert(written == len); } } if(buffer) { char *cmd_buffer; cmd_buffer = malloc(plen+1); memcpy(cmd_buffer, buffer, plen); /* chomp */ cmd_buffer[plen] = '\0'; if(cmd_buffer[plen-1] == '\n') cmd_buffer[plen-1] = '\0'; noitL(noit_debug, "IN[%d]: '%s'\n", plen, cmd_buffer); noit_console_dispatch(e, cmd_buffer, ncct); free(cmd_buffer); } if(noit_console_continue_sending(ncct, &newmask) == -1) { if(ncct->wants_shutdown || errno != EAGAIN) goto socket_error; return newmask | EVENTER_EXCEPTION; } if(ncct->wants_shutdown) goto socket_error; } return newmask | EVENTER_EXCEPTION; }
static rstatus_t stats_master_send_rsp(int *psd) { int n; ssize_t len; int sd; int i; nc_channel_msg_t message; char buf[1000]; memset(buf, 0, sizeof(char)*1000); char *snd_buf = NULL; memset(&message, 0, sizeof(nc_channel_msg_t)); message.command = NC_CMD_GET_STATS; if (*psd) { sd = accept(*psd, NULL, NULL); if (sd < 0) { log_error("accept on m %d failed: %s", sd, strerror(errno)); return NC_ERROR; } } // still in reconfiguration process if (nc_reload_start) { sprintf(buf, "%s", "no stats get due to still during reconfiguration period."); if (*psd) { len = nc_strlen(buf)+1; len = nc_sendn(sd, buf, len); if (len < 0) { log_error("send stats on sd %d failed: %s", sd, strerror(errno)); } close(sd); } return NC_OK; } //broadcast for (i = 0; i < nc_last_process; i++) { if (nc_processes[i].pid == -1 || nc_processes[i].pid == 0) { continue; } if (nc_write_channel(nc_processes[i].channel[0], &message, sizeof(nc_channel_msg_t)) == NC_OK) { if (nc_set_blocking(nc_processes[i].channel[0]) < 0) { log_error("set channel %d block failed while core timeout %s", nc_processes[i].channel[0] , strerror(errno)); continue; } n = nc_read_channel(nc_processes[i].channel[0], &env_global.ctrl_msg, sizeof(nc_channel_msg_t)); if (env_global.ctrl_msg.command != NC_CMD_GET_STATS || n < 0) { log_error("failure: get stats from worker %d receive length, %s", nc_processes[i].channel[0] , strerror(errno)); } else { log_error("success: get stats from worker %d receive length, %d", nc_processes[i].channel[0] , n); snd_buf = nc_alloc(n + n); len = nc_recvn(nc_processes[i].channel[0], snd_buf, n); if (len < 0) { if (*psd) { log_error("recv stats on sd %d failed: %s", sd, strerror(errno)); } nc_free(snd_buf); snd_buf = NULL; continue; } if (*psd) { len = nc_sendn(sd, snd_buf, len); if (len < 0) { log_error("send stats on sd %d failed: %s", sd, strerror(errno)); nc_free(snd_buf); snd_buf = NULL; continue; } } len = nc_write(env_global.stats_fd, snd_buf, len); if (len < 0) { log_error("nc_write %d failed: %s", env_global.stats_fd, strerror(errno)); continue; } nc_free(snd_buf); snd_buf = NULL; } if (nc_set_nonblocking(nc_processes[i].channel[0]) < 0) { log_error("set channel %d nonblock failed while core timeout %s", nc_processes[i].channel[0] , strerror(errno)); } } } if (*psd) { shutdown(sd, SHUT_RDWR); close(sd); } return NC_OK; }
static int noit_console_config_show(noit_console_closure_t ncct, int argc, char **argv, noit_console_state_t *state, void *closure) { noit_hash_iter iter = NOIT_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]; noit_conf_t_userdata_t *info = NULL; noit_hash_table *config; xmlXPathObjectPtr pobj = NULL; xmlXPathContextPtr xpath_ctxt = NULL, current_ctxt; xmlDocPtr master_config = NULL; xmlNodePtr node = NULL; noit_conf_xml_xpath(&master_config, &xpath_ctxt); if(argc > 1) { nc_printf(ncct, "too many arguments\n"); return -1; } info = noit_console_userdata_get(ncct, NOIT_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 = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); if(!strcmp((char *)node->name, "check")) continue; if(node->children && node->children == xmlGetLastChild(node) && xmlNodeIsText(node->children)) { if(!titled++) nc_printf(ncct, "== Section Settings ==\n"); nc_printf(ncct, "%s: %s\n", xmlGetNodePath(node) + cliplen, xmlXPathCastNodeToString(node->children)); } } 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 = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, 0); titled = 0; config = noit_conf_get_hash(node, "config"); while(noit_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); } noit_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++) { node = (noit_conf_section_t)xmlXPathNodeSetItem(pobj->nodesetval, i); if(!strcmp((char *)node->name, "check")) continue; if(!strcmp((char *)node->name, "filterset")) continue; if(!strcmp((char *)xmlGetNodePath(node) + cliplen, "config")) continue; if(!(node->children && node->children == xmlGetLastChild(node) && xmlNodeIsText(node->children))) { if(!titled++) nc_printf(ncct, "== Subsections ==\n"); nc_printf(ncct, "%s\n", xmlGetNodePath(node) + cliplen); } } titled = 0; for(i=0; i<cnt; i++) { node = (noit_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 = "undefined"; 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); } if(uuid_str) { uuid_t checkid; nc_printf(ncct, "check[@uuid=\"%s\"] ", uuid_str); if(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); } } } else nc_printf(ncct, "%s ", xmlGetNodePath(node) + cliplen); 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_show_check(noit_console_closure_t ncct, int argc, char **argv, noit_console_state_t *state, void *closure) { int i, cnt; noit_conf_t_userdata_t *info; char xpath[1024]; xmlXPathObjectPtr pobj = NULL; xmlXPathContextPtr xpath_ctxt = NULL; noit_conf_xml_xpath(NULL, &xpath_ctxt); if(argc > 1) { nc_printf(ncct, "requires zero or one arguments\n"); return -1; } info = noit_console_userdata_get(ncct, NOIT_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++) { noit_hash_iter iter = NOIT_HASH_ITER_ZERO; const char *k; int klen; void *data; uuid_t checkid; noit_check_t *check; noit_hash_table *config; xmlNodePtr node, anode, mnode = NULL; char *uuid_conf; char *module, *value; node = (noit_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); #define MYATTR(a,n,b) _noit_conf_get_string(node, &(n), "@" #a, &(b)) #define INHERIT(a,n,b) \ _noit_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); \ } while(0) if(!INHERIT(module, mnode, module)) module = NULL; if(MYATTR(name, anode, value)) nc_printf(ncct, " name: %s\n", value); else nc_printf(ncct, " name: %s [from module]\n", module ? module : "[undef]"); nc_attr_show(ncct, "module", node, mnode, module); SHOW_ATTR(target); SHOW_ATTR(period); SHOW_ATTR(timeout); SHOW_ATTR(oncheck); SHOW_ATTR(filterset); SHOW_ATTR(disable); /* Print out all the config settings */ config = noit_conf_get_hash(node, "config"); while(noit_hash_next(config, &iter, &k, &klen, &data)) { nc_printf(ncct, " config::%s: %s\n", k, (const char *)data); } noit_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; nc_printf(ncct, " currently: "); if(NOIT_CHECK_RUNNING(check)) nc_printf(ncct, "%srunning", 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->stats.current.whence.tv_sec == 0) { nc_printf(ncct, " last run: never\n"); } else { stats_t *c = &check->stats.current; struct timeval now, diff; gettimeofday(&now, NULL); sub_timeval(now, c->whence, &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(c->available), noit_check_state_string(c->state)); nc_printf(ncct, " status: %s\n", c->status ? c->status : "[[null]]"); nc_printf(ncct, " metrics:\n"); memset(&iter, 0, sizeof(iter)); while(noit_hash_next(&c->metrics, &iter, &k, &klen, &data)) { char buff[256]; noit_boolean filtered; noit_stats_snprint_metric(buff, sizeof(buff), (metric_t *)data); filtered = !noit_apply_filterset(check->filterset, check, (metric_t *)data); nc_printf(ncct, " %c%s\n", filtered ? '*' : ' ', buff); } } } } out: if(pobj) xmlXPathFreeObject(pobj); return 0; }
int noit_console_write_xml(void *vncct, const char *buffer, int len) { noit_console_closure_t ncct = vncct; return nc_write(ncct, buffer, len); }
/* * Hexadecimal dump in the canonical hex + ascii display * See -C option in man hexdump */ void _log_hexdump(const char *file, int line, char *data, int datalen, const char *fmt, ...) { struct logger *l = &logger; char buf[8 * LOG_MAX_LEN]; int i, off, len, size, errno_save; ssize_t n; if (l->fd < 0) { return; } /* log hexdump */ errno_save = errno; off = 0; /* data offset */ len = 0; /* length of output buffer */ size = 8 * LOG_MAX_LEN; /* size of output buffer */ while (datalen != 0 && (len < size - 1)) { char *save, *str; unsigned char c; int savelen; len += nc_scnprintf(buf + len, size - len, "%08x ", off); save = data; savelen = datalen; for (i = 0; datalen != 0 && i < 16; data++, datalen--, i++) { c = (unsigned char)(*data); str = (i == 7) ? " " : " "; len += nc_scnprintf(buf + len, size - len, "%02x%s", c, str); } for ( ; i < 16; i++) { str = (i == 7) ? " " : " "; len += nc_scnprintf(buf + len, size - len, " %s", str); } data = save; datalen = savelen; len += nc_scnprintf(buf + len, size - len, " |"); for (i = 0; datalen != 0 && i < 16; data++, datalen--, i++) { c = (unsigned char)(isprint(*data) ? *data : '.'); len += nc_scnprintf(buf + len, size - len, "%c", c); } len += nc_scnprintf(buf + len, size - len, "|\n"); off += 16; } n = nc_write(l->fd, buf, len); if (n < 0) { l->nerror++; } if (len >= size - 1) { n = nc_write(l->fd, "\n", 1); if (n < 0) { l->nerror++; } } errno = errno_save; }
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; }