From: <ag...@us...> - 2012-09-20 01:53:05
|
Revision: 2269 http://nagios.svn.sourceforge.net/nagios/?rev=2269&view=rev Author: ageric Date: 2012-09-20 01:52:59 +0000 (Thu, 20 Sep 2012) Log Message: ----------- nerd: Use the query-handler API This was easier than I thought, so might as well get it done right away. Signed-off-by: Andreas Ericsson <ae...@op...> Modified Paths: -------------- nagioscore/trunk/base/nerd.c Modified: nagioscore/trunk/base/nerd.c =================================================================== --- nagioscore/trunk/base/nerd.c 2012-09-20 01:52:41 UTC (rev 2268) +++ nagioscore/trunk/base/nerd.c 2012-09-20 01:52:59 UTC (rev 2269) @@ -7,7 +7,6 @@ * * This code uses the eventbroker api to get its data, which means * we're finally eating our own dogfood in that respect. - * */ #define _GNU_SOURCE 1 @@ -23,7 +22,6 @@ #include "include/nebmodules.h" #include "include/nebstructs.h" -static unsigned int max_subscribers = 32; /* make this configurable */ static unsigned int num_subscribers; static nebmodule *nerd_mod; /* fake module to get our callbacks accepted */ static int nerd_sock; /* teehee. nerd-socks :D */ @@ -95,14 +93,17 @@ return 0; } -static int subscribe(int sd, struct nerd_channel *chan, struct subscriber *sub, char *fmt) +static int subscribe(int sd, struct nerd_channel *chan, char *fmt) { struct subscription *subscr; + struct subscriber *sub; - subscr = malloc(sizeof(*subscr)); - if(!subscr) + if(!(sub = calloc(1, sizeof(*sub)))) return -1; + if(!(subscr = calloc(1, sizeof(*subscr)))) + return -1; + sub->sd = sd; subscr->chan = chan; subscr->sub = sub; subscr->format = fmt ? strdup(fmt) : NULL; @@ -148,17 +149,14 @@ return 0; } -static int unsubscribe(struct nerd_channel *chan, struct subscriber *sub, const char *fmt) +static int unsubscribe(int sd, struct nerd_channel *chan, const char *fmt) { objectlist *list, *next, *prev; - if(!sub) - return -1; - for(list = chan->subscriptions; list; list = next) { struct subscription *subscr = (struct subscription *)list->object_ptr; next = list->next; - if(subscr->sub != sub || (fmt && !subscr->format) || (!fmt && subscr->format)) { + if(subscr->sub->sd != sd || (fmt && !subscr->format) || (!fmt && subscr->format)) { prev = list; continue; } @@ -224,8 +222,12 @@ next = list->next; result = send(subscr->sub->sd, buf, len, MSG_NOSIGNAL); - if(result < 0 && errno == EPIPE) { + if(result < 0) { + if (errno == EAGAIN) + return 0; + cancel_subscriber(subscr->sub); + return 500; } } @@ -233,98 +235,6 @@ } -#define prefixcmp(buf, find) strncmp(buf, find, strlen(find)) -#define NERD_SUBSCRIBE 0 -#define NERD_UNSUBSCRIBE 1 -static int nerd_input_handler(int sd, int events, void *sub_) -{ - struct subscriber *sub = (struct subscriber *)sub_; - struct nerd_channel *chan; - char request[2048], *chan_name, *fmt; - int result, action = NERD_SUBSCRIBE; - - result = recv(sd, request, sizeof(request), MSG_NOSIGNAL); - printf("nerd_input(): recv() returned %d: %m\n", result); - if(result <= 0) { - cancel_subscriber(sub); - return 0; - } - request[result--] = 0; - printf("request: %s\n", request); - while(request[result] == '\n') - request[result--] = 0; - if(!result) /* empty request */ - return 0; - - chan_name = strchr(request, ' '); - if(result <= 0 || !chan_name) { - iobroker_close(nagios_iobs, sd); - } - - *chan_name = 0; - chan_name++; - if(strcmp(request, "subscribe ") && strcmp(request, "unsubscribe")) - action = NERD_SUBSCRIBE; - else if(!strcmp(request, "unsubscribe ")) - action = NERD_UNSUBSCRIBE; - else { - nsock_printf(sd, "Bad request. Do things right or go away\n"); - iobroker_close(nagios_iobs, sd); - } - - /* might have a format-string */ - fmt = strchr(chan_name, ':'); - if(fmt) { - *fmt = 0; - fmt++; - } - - chan = find_channel(chan_name); - if(!chan) { - nsock_printf(sd, "Invalid request"); - return 0; - } - - if(action == NERD_SUBSCRIBE) - subscribe(sd, chan, sub, fmt); - else - unsubscribe(chan, sub, fmt); - - return 0; -} - -static int nerd_tuneins(int in_sock, int events, void *discard) -{ - int sd; - struct sockaddr sa; - socklen_t slen; - struct subscriber *sub; - - sd = accept(in_sock, &sa, &slen); - printf("NERD tune-in discovered from %d (%m)\n", sd); - printf("num_subscribers: %u; max_subscribers: %u\n", - num_subscribers, max_subscribers); - - if(sd < 0) { - logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to accept() NERD tune-in: %s\n", - strerror(errno)); - return 0; - } - - if(num_subscribers >= max_subscribers) { - nsock_printf(sd, "We're full. Go away\n"); - close(sd); - iobroker_unregister(nagios_iobs, sd); - } - - sub = calloc(1, sizeof(*sub)); - num_subscribers++; - sub->sd = sd; - iobroker_register(nagios_iobs, sd, sub, nerd_input_handler); - - return 0; -} - static int chan_host_checks(int cb, void *data) { nebstruct_host_check_data *ds = (nebstruct_host_check_data *)data; @@ -414,19 +324,65 @@ return num_channels - 1; } +#define NERD_SUBSCRIBE 0 +#define NERD_UNSUBSCRIBE 1 +static int nerd_qh_handler(int sd, char *request, unsigned int len) +{ + char *chan_name, *fmt; + struct nerd_channel *chan; + int action; + + printf("Got request '%s'\n", request); + while(request[len] == 0 || request[len] == '\n') + request[len--] = 0; + chan_name = strchr(request, ' '); + if(!chan_name) + return 400; + + *chan_name = 0; + chan_name++; + if(strcmp(request, "subscribe ") && strcmp(request, "unsubscribe")) + 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) { + printf("Failed to find channel %s\n", chan_name); + return 400; + } + + if(action == NERD_SUBSCRIBE) + subscribe(sd, chan, fmt); + else + unsubscribe(sd, chan, fmt); + + return 0; +} + /* nebmod_init(), but loaded even if no modules are */ int nerd_init(void) { nerd_mod = calloc(1, sizeof(*nerd_mod)); nerd_mod->deinit_func = nerd_deinit; + if(qh_register_handler("nerd", 0, nerd_qh_handler) < 0) { + logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to register 'nerd' with query handler\n"); + return ERROR; + } + neb_add_core_module(nerd_mod); - nerd_sock = nsock_unix("/tmp/nerd.sock", 07, NSOCK_TCP | NSOCK_UNLINK); - printf("nsock_unix() returned %d: %m\n", nerd_sock); - iobroker_register(nagios_iobs, nerd_sock, NULL, nerd_tuneins); chan_host_checks_id = nerd_mkchan("hostchecks", chan_host_checks, nebcallback_flag(NEBCALLBACK_HOST_CHECK_DATA)); chan_service_checks_id = nerd_mkchan("servicechecks", chan_service_checks, nebcallback_flag(NEBCALLBACK_SERVICE_CHECK_DATA)); + logit(NSLOG_INFO_MESSAGE, TRUE, "NERD initialized and ready to rock!\n"); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |