static int qh_help(int sd, char *buf, unsigned int len) { struct query_handler *qh; if (!*buf || !strcmp(buf, "help")) { nsock_printf_nul(sd, " help <name> show help for handler <name>\n" " help list list registered handlers\n"); return 0; } if (!strcmp(buf, "list")) { for (qh = qhandlers; qh; qh = qh->next_qh) { nsock_printf(sd, "%-10s %s\n", qh->name, qh->description ? qh->description : "(No description available)"); } nsock_printf(sd, "%c", 0); return 0; } if (!(qh = qh_find_handler(buf))) { nsock_printf_nul(sd, "No handler named '%s' is registered\n", buf); } else if (qh->handler(sd, "help", 4) > 200) { nsock_printf_nul(sd, "The handler %s doesn't have any help yet.", buf); } return 0; }
static int nerd_qh_handler(int sd, char *request, unsigned int len) { char *chan_name, *fmt; struct nerd_channel *chan; int action; if (!*request || !strcmp(request, "help")) { nsock_printf_nul(sd, "Manage subscriptions to NERD channels.\n" "Valid commands:\n" " list list available channels\n" " subscribe <channel> subscribe to a channel\n" " unsubscribe <channel> unsubscribe to a channel\n"); return 0; } if (!strcmp(request, "list")) { unsigned int i; for (i = 0; i < num_channels; i++) { chan = channels[i]; nsock_printf(sd, "%-15s %s\n", chan->name, chan->description); } nsock_printf(sd, "%c", 0); return 0; } chan_name = strchr(request, ' '); if(!chan_name) return 400; *chan_name = 0; chan_name++; if(!strcmp(request, "subscribe")) action = NERD_SUBSCRIBE; else if(!strcmp(request, "unsubscribe")) action = NERD_UNSUBSCRIBE; else { return 400; } /* might have a format-string */ if((fmt = strchr(chan_name, ':'))) *(fmt++) = 0; chan = find_channel(chan_name); if(!chan) { return 400; } if(action == NERD_SUBSCRIBE) subscribe(sd, chan, fmt); else unsubscribe(sd, chan); return 0; }
static int handle_state_initial(struct npool *nsp, struct nevent *nse, void *udata) { struct proxy_chain_context *px_ctx = nse->iod->px_ctx; struct sockaddr_storage *ss; size_t sslen; unsigned short port; struct proxy_node *next; int timeout; px_ctx->px_state = PROXY_STATE_HTTP_TCP_CONNECTED; next = proxy_ctx_node_next(px_ctx); if (next) { ss = &next->ss; sslen = next->sslen; port = next->port; } else { ss = &px_ctx->target_ss; sslen = px_ctx->target_sslen; port = px_ctx->target_port; } timeout = TIMEVAL_MSEC_SUBTRACT(nse->timeout, nsock_tod); nsock_printf(nsp, (nsock_iod)nse->iod, nsock_proxy_ev_dispatch, timeout, udata, "CONNECT %s:%d HTTP/1.1\r\n\r\n", inet_ntop_ez(ss, sslen), (int)port); nsock_readlines(nsp, (nsock_iod)nse->iod, nsock_proxy_ev_dispatch, timeout, udata, 1); return 0; }
static int qh_registration_input(int sd, int events, void *bq_) { nm_bufferqueue *bq = (nm_bufferqueue *)bq_; struct sockaddr sa; socklen_t slen = 0; int nsd, result; memset(&sa, 0, sizeof(sa)); /* shut valgrind up */ nsd = accept(sd, &sa, &slen); if (qh_max_running && qh_running >= qh_max_running) { nsock_printf(nsd, "503: Server full"); close(nsd); return 0; } if (!(bq = nm_bufferqueue_create())) { nm_log(NSLOG_RUNTIME_ERROR, "qh: Failed to create iocache for inbound request\n"); nsock_printf(nsd, "500: Internal server error"); close(nsd); return 0; } /* * @todo: Stash the iocache and the socket in some * addressable list so we can release them on deinit */ result = iobroker_register(nagios_iobs, nsd, bq, qh_input); if (result < 0) { nm_log(NSLOG_RUNTIME_ERROR, "qh: Failed to register input socket %d with I/O broker: %s; errno=%d (%s)\n", nsd, iobroker_strerror(result), errno, strerror(errno)); nm_bufferqueue_destroy(bq); close(nsd); return 0; } /* make it non-blocking, but leave kernel buffers unchanged */ worker_set_sockopts(nsd, 0); qh_running++; return 0; }
int dump_event_stats(int sd) { unsigned int i; for (i = 0; i < ARRAY_SIZE(event_count); i++) { nsock_printf(sd, "%s=%u;", EVENT_TYPE_STR(i), event_count[i]); /* * VERSIONFIX: Make EVENT_SLEEP and EVENT_USER_FUNCTION * appear in linear order in include/nagios.h when we go * from 4.0 -> 4.1, so we can remove this junk. */ if (i == 16) i = 97; } nsock_printf_nul(sd, "SQUEUE_ENTRIES=%u", squeue_size(nagios_squeue)); return OK; }
static int wproc_query_handler(int sd, char *buf, unsigned int len) { char *space, *rbuf = NULL; if (!*buf || !strcmp(buf, "help")) { nsock_printf_nul(sd, "Control worker processes.\n" "Valid commands:\n" " wpstats Print general job information\n" " register <options> Register a new worker\n" " <options> can be name, pid, max_jobs and/or plugin.\n" " There can be many plugin args."); return 0; } if ((space = memchr(buf, ' ', len)) != NULL) *space = 0; rbuf = space ? space + 1 : buf; len -= (unsigned long)rbuf - (unsigned long)buf; if (!strcmp(buf, "register")) return register_worker(sd, rbuf, len); if (!strcmp(buf, "wpstats")) { unsigned int i; for (i = 0; i < workers.len; i++) { struct wproc_worker *wp = workers.wps[i]; nsock_printf(sd, "name=%s;pid=%d;jobs_running=%u;jobs_started=%u\n", wp->name, wp->pid, wp->jobs_running, wp->jobs_started); } return 0; } return 400; }
static int qh_input(int sd, int events, void *bq_) { nm_bufferqueue *bq = (nm_bufferqueue *)bq_; int result; size_t len; unsigned int query_len = 0; char *buf, *space; struct query_handler *qh; char *handler = NULL, *query = NULL; result = nm_bufferqueue_read(bq, sd); /* disconnect? */ if (result == 0 || (result < 0 && errno == EPIPE)) { nm_bufferqueue_destroy(bq); iobroker_close(nagios_iobs, sd); qh_running--; return 0; } /* * A request looks like this: '[@|#]<qh>[<SP>][<query>]\0'. * That is, optional '#' (oneshot) or '@' (keepalive), * followed by the name of a registered handler, followed by * an optional space and an optional query. If the handler * has no "default" handler, a query is required or an error * will be thrown. */ /* Use data up to the first nul byte */ nm_bufferqueue_unshift_to_delim(bq, "\0", 1, &len, (void **)&buf); if (!buf) return 0; /* Identify handler part and any magic query bytes */ if (*buf == '@' || *buf == '#') { handler = buf + 1; } else { handler = buf; } /* Locate query (if any) */ if ((space = strchr(buf, ' '))) { *space = 0; query = space + 1; query_len = len - ((unsigned long)query - (unsigned long)buf); } else { query = ""; query_len = 0; } /* locate the handler */ if (!(qh = qh_find_handler(handler))) { /* not found. that's a 404 */ nsock_printf(sd, "404: %s: No such handler", handler); nm_free(buf); iobroker_close(nagios_iobs, sd); nm_bufferqueue_destroy(bq); return 0; } /* strip trailing newlines */ while (query_len > 0 && (query[query_len - 1] == 0 || query[query_len - 1] == '\n')) query[--query_len] = 0; /* now pass the query to the handler */ if ((result = qh->handler(sd, query, query_len)) >= 100) { nsock_printf_nul(sd, "%d: %s", result, qh_strerror(result)); } if (result >= 300 || *buf != '@') { /* error code or one-shot query */ nm_free(buf); iobroker_close(nagios_iobs, sd); nm_bufferqueue_destroy(bq); return 0; } nm_free(buf); /* check for magic handler codes */ switch (result) { case QH_CLOSE: /* oneshot handler */ case -1: /* general error */ iobroker_close(nagios_iobs, sd); /* fallthrough */ case QH_TAKEOVER: /* handler takes over */ case 101: /* switch protocol (takeover + message) */ nm_bufferqueue_destroy(bq); break; } return 0; }