Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}