Ejemplo n.º 1
0
static int statuscolor_by_set(testedhost_t *h, long status, char *okcodes, char *badcodes)
{
	int result = -1;
	char codestr[10];
	pcre *ptn;

	/* Use code 999 to indicate we could not fetch the URL */
	sprintf(codestr, "%ld", (status ? status : 999));

	if (okcodes) {
		ptn = compileregex(okcodes);
		if (matchregex(codestr, ptn)) result = COL_GREEN; else result = COL_RED;
		freeregex(ptn);
	}

	if (badcodes) {
		ptn = compileregex(badcodes);
		if (matchregex(codestr, ptn)) result = COL_RED; else result = COL_GREEN;
		freeregex(ptn);
	}

	if (result == -1) result = statuscolor(h, status);

	dbgprintf("Host %s status %s [%s:%s] -> color %s\n", 
		  h->hostname, codestr, 
		  (okcodes ? okcodes : "<null>"),
		  (badcodes ? badcodes : "<null>"),
		  colorname(result));

	return result;
}
Ejemplo n.º 2
0
int processfile(const char *pattern, char* filename, int pipeflag) {
	FILE *fp;
	if(!pipeflag) fp = fopen(filename, "r");
	if(pipeflag)  fp = stdin;
	char *buffer = NULL;
	size_t bufsize;
	int size;
	int regexmatch = 0;
	char *matchedline = NULL;
//	char *searchstring = pattern;
	//printf("Search string: %s\n", pattern);
	int i = 0, j = 0, linestoprint=100000;
	printf("Pattern: %s, Filename: %s\n", pattern, filename);
	if(maxcount>0) linestoprint = maxcount;
	if(!fp) {printf("File can't be opened\n"); return 0;}
	
	while((size = getline(&buffer, &bufsize, fp))>0) {
		buffer[size] = '\0';
		matchedline = strstr((const char*)buffer, pattern);
		//printf("%s ", buffer);
		regexmatch = matchregex(buffer, pattern);
		//printf("Regexmatch return: %d\n", regexmatch);
		if(regexmatch && !invflag) {
			printf("%d %s",i, buffer);
			i++;
		} 
		if(!regexmatch && invflag) {
			printf("%d %s",i,  buffer);
			i++;
		}
   if(i==linestoprint) break;
	}
	return 1;
}
Ejemplo n.º 3
0
int do_ifstat_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp)
{
	static int pcres_compiled = 0;
	static pcre **ifstat_linux_pcres = NULL;
	static pcre **ifstat_freebsd_pcres = NULL;
	static pcre **ifstat_freebsdV8_pcres = NULL;
	static pcre **ifstat_openbsd_pcres = NULL;
	static pcre **ifstat_netbsd_pcres = NULL;
	static pcre **ifstat_darwin_pcres = NULL;
	static pcre **ifstat_solaris_pcres = NULL;
	static pcre **ifstat_aix_pcres = NULL;
	static pcre **ifstat_hpux_pcres = NULL;
	static pcre **ifstat_sco_sv_pcres = NULL;
	static pcre **ifstat_bbwin_pcres = NULL;

	enum ostype_t ostype;
	char *datapart = msg;
	char *bol, *eoln, *ifname, *rxstr, *txstr, *dummy;
	int dmatch;

	void *xmh;
	pcre *ifname_filter_pcre = NULL;

	xmh = hostinfo(hostname);
	if (xmh) {
		char *ifname_filter_expr = xmh_item(xmh, XMH_INTERFACES);
		if (ifname_filter_expr && *ifname_filter_expr) 
			ifname_filter_pcre = compileregex(ifname_filter_expr);
	}

	if (pcres_compiled == 0) {
		pcres_compiled = 1;
		ifstat_linux_pcres = compile_exprs("LINUX", ifstat_linux_exprs, 
						 (sizeof(ifstat_linux_exprs) / sizeof(ifstat_linux_exprs[0])));
		ifstat_freebsd_pcres = compile_exprs("FREEBSD", ifstat_freebsd_exprs, 
						 (sizeof(ifstat_freebsd_exprs) / sizeof(ifstat_freebsd_exprs[0])));
		ifstat_freebsdV8_pcres = compile_exprs("FREEBSD", ifstat_freebsdV8_exprs, 
						 (sizeof(ifstat_freebsdV8_exprs) / sizeof(ifstat_freebsdV8_exprs[0])));
		ifstat_openbsd_pcres = compile_exprs("OPENBSD", ifstat_openbsd_exprs, 
						 (sizeof(ifstat_openbsd_exprs) / sizeof(ifstat_openbsd_exprs[0])));
		ifstat_netbsd_pcres = compile_exprs("NETBSD", ifstat_netbsd_exprs, 
						 (sizeof(ifstat_netbsd_exprs) / sizeof(ifstat_netbsd_exprs[0])));
		ifstat_darwin_pcres = compile_exprs("DARWIN", ifstat_darwin_exprs, 
						 (sizeof(ifstat_darwin_exprs) / sizeof(ifstat_darwin_exprs[0])));
		ifstat_solaris_pcres = compile_exprs("SOLARIS", ifstat_solaris_exprs, 
						 (sizeof(ifstat_solaris_exprs) / sizeof(ifstat_solaris_exprs[0])));
		ifstat_aix_pcres = compile_exprs("AIX", ifstat_aix_exprs, 
						 (sizeof(ifstat_aix_exprs) / sizeof(ifstat_aix_exprs[0])));
		ifstat_hpux_pcres = compile_exprs("HPUX", ifstat_hpux_exprs, 
						 (sizeof(ifstat_hpux_exprs) / sizeof(ifstat_hpux_exprs[0])));
		ifstat_sco_sv_pcres = compile_exprs("SCO_SV", ifstat_sco_sv_exprs, 
						 (sizeof(ifstat_sco_sv_exprs) / sizeof(ifstat_sco_sv_exprs[0])));
		ifstat_bbwin_pcres = compile_exprs("BBWIN", ifstat_bbwin_exprs, 
						 (sizeof(ifstat_bbwin_exprs) / sizeof(ifstat_bbwin_exprs[0])));
	}


	if (ifstat_tpl == NULL) ifstat_tpl = setup_template(ifstat_params);

	if ((strncmp(msg, "status", 6) == 0) || (strncmp(msg, "data", 4) == 0)) {
		/* Skip the first line of full status- and data-messages. */
		datapart = strchr(msg, '\n');
		if (datapart) datapart++; else datapart = msg;
	}

	ostype = get_ostype(datapart);
	datapart = strchr(datapart, '\n');
	if (datapart) {
		datapart++; 
	}
	else {
		errprintf("Too few lines in ifstat report from %s\n", hostname);
		return -1;
	}

	dmatch = 0;
	ifname = rxstr = txstr = dummy = NULL;

	bol = datapart;
	while (bol) {
		eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0';

		switch (ostype) {
		  case OS_LINUX22:
		  case OS_LINUX:
		  case OS_RHEL3:
		  case OS_ZVM:
		  case OS_ZVSE:
		  case OS_ZOS:
			if (pickdata(bol, ifstat_linux_pcres[0], 1, &ifname)) {
				/*
				 * Linux' netif aliases mess up things. 
				 * Clear everything when we see an interface name.
				 * But we dont want to track the "lo" interface.
				 */

				/* Strip off the last character if it is a colon (:) */
				if (ifname[strlen(ifname)-1] == ':') ifname[strlen(ifname)-1] = '\0';

				if (strcmp(ifname, "lo") == 0) {
					xfree(ifname); ifname = NULL;
				}
				else {
					dmatch = 1;
					if (rxstr) { xfree(rxstr); rxstr = NULL; }
					if (txstr) { xfree(txstr); txstr = NULL; }
				}
			}
			else if (pickdata(bol, ifstat_linux_pcres[1], 1, &rxstr, &txstr)) dmatch |= 6;
			else if (pickdata(bol, ifstat_linux_pcres[2], 1, &rxstr)) dmatch |= 2;
			else if (pickdata(bol, ifstat_linux_pcres[3], 1, &txstr)) dmatch |= 4;
			break;

		  case OS_FREEBSD:
			/*
			 * FreeBSD 8 added an "Idrop" counter in the middle of the data.
			 * See if we match this expression, and if not then fall back to
			 * the old regex without that field.
			 */
			if (pickdata(bol, ifstat_freebsdV8_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
			else if (pickdata(bol, ifstat_freebsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
			break;

		  case OS_OPENBSD:
			if (pickdata(bol, ifstat_openbsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
			break;

		  case OS_NETBSD:
			if (pickdata(bol, ifstat_netbsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
			break;

		  case OS_SOLARIS: 
			if (pickdata(bol, ifstat_solaris_pcres[0], 0, &ifname, &txstr)) dmatch |= 1;
			else if (pickdata(bol, ifstat_solaris_pcres[1], 0, &dummy, &rxstr)) dmatch |= 6;

			if (ifname && dummy && (strcmp(ifname, dummy) != 0)) {
				/* They must match, drop the data */
				errprintf("Host %s has weird ifstat data - device name mismatch %s:%s\n", hostname, ifname, dummy);
				xfree(ifname); xfree(txstr); xfree(rxstr); xfree(dummy);
				dmatch = 0;
			}

			/* Ignore "mac" and "wrsmd" entries - these are for sub-devices for multiple nic's aggregated into one */
			/* See http://www.xymon.com/archive/2009/06/msg00204.html for more info */
			if (ifname && ((strcmp(ifname, "mac") == 0) || (strcmp(ifname, "wrsmd") == 0)) ) {
				xfree(ifname); xfree(txstr);
				dmatch = 0;
			}
			if (dummy && ((strcmp(dummy, "mac") == 0) || (strcmp(dummy, "wrsmd") == 0)) ) {
				xfree(dummy); xfree(rxstr);
				dmatch = 0;
			}
			break;

		  case OS_AIX: 
			if (pickdata(bol, ifstat_aix_pcres[0], 1, &ifname)) {
				/* Interface names comes first, so any rx/tx data is discarded */
				dmatch |= 1;
				if (rxstr) { xfree(rxstr); rxstr = NULL; }
				if (txstr) { xfree(txstr); txstr = NULL; }
			}
			else if (pickdata(bol, ifstat_aix_pcres[1], 1, &txstr, &rxstr)) dmatch |= 6;
			break;

		  case OS_HPUX: 
			if (pickdata(bol, ifstat_hpux_pcres[0], 1, &ifname)) {
				/* Interface names comes first, so any rx/tx data is discarded */
				dmatch |= 1;
				if (rxstr) { xfree(rxstr); rxstr = NULL; }
				if (txstr) { xfree(txstr); txstr = NULL; }
			}
			else if (pickdata(bol, ifstat_hpux_pcres[1], 1, &rxstr)) dmatch |= 2;
			else if (pickdata(bol, ifstat_hpux_pcres[2], 1, &txstr)) dmatch |= 4;
			break;

		  case OS_DARWIN:
			if (pickdata(bol, ifstat_darwin_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
			break;
			
 		  case OS_SCO_SV:
		        if (pickdata(bol, ifstat_sco_sv_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
			break;
			
		  case OS_WIN32_BBWIN:
			if (pickdata(bol, ifstat_bbwin_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
			break;

		  default:
			break;
		}

		if ((dmatch == 7) && ifname && rxstr && txstr) {
			if (!ifname_filter_pcre || matchregex(ifname, ifname_filter_pcre)) {
				setupfn2("%s.%s.rrd", "ifstat", ifname);
				snprintf(rrdvalues, sizeof(rrdvalues), "%d:%s:%s", (int)tstamp, txstr, rxstr);
				create_and_update_rrd(hostname, testname, classname, pagepaths, ifstat_params, ifstat_tpl);
			}

			xfree(ifname); xfree(rxstr); xfree(txstr);
			if (dummy) xfree(dummy);
			ifname = rxstr = txstr = dummy = NULL;
			dmatch = 0;
		}

		if (eoln) {
			*eoln = '\n';
			bol = eoln+1;
			if (*bol == '\0') bol = NULL;
		}
		else {
			bol = NULL;
		}
	}

	if (ifname_filter_pcre) freeregex(ifname_filter_pcre);

	if (ifname) xfree(ifname);
	if (rxstr) xfree(rxstr);
	if (txstr) xfree(txstr);
	if (dummy) xfree(dummy);

	return 0;
}
Ejemplo n.º 4
0
int main(int argc, char *argv[])
{
	int daemonize = 0;
	char *pidfile = NULL;
	char *envarea = NULL;
	int cnid = -1;
	pcre *msgfilter = NULL;
	pcre *stdfilter = NULL;

	int argi;
	struct sigaction sa;
	RbtIterator handle;


	/* Dont save the error buffer */
	save_errbuf = 0;

	/* Create the peer container */
	peers = rbtNew(name_compare);

	for (argi=1; (argi < argc); argi++) {
		if (argnmatch(argv[argi], "--debug")) {
			debug = 1;
		}
		else if (argnmatch(argv[argi], "--channel=")) {
			char *cn = strchr(argv[argi], '=') + 1;

			for (cnid = C_STATUS; (channelnames[cnid] && strcmp(channelnames[cnid], cn)); cnid++) ;
			if (channelnames[cnid] == NULL) cnid = -1;
		}
		else if (argnmatch(argv[argi], "--daemon")) {
			daemonize = 1;
		}
		else if (argnmatch(argv[argi], "--no-daemon")) {
			daemonize = 0;
		}
		else if (argnmatch(argv[argi], "--pidfile=")) {
			char *p = strchr(argv[argi], '=');
			pidfile = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--log=")) {
			char *p = strchr(argv[argi], '=');
			logfn = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--env=")) {
			char *p = strchr(argv[argi], '=');
			loadenv(p+1, envarea);
		}
		else if (argnmatch(argv[argi], "--area=")) {
			char *p = strchr(argv[argi], '=');
			envarea = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--locator=")) {
			char *p = strchr(argv[argi], '=');
			locator_init(p+1);
			locatorbased = 1;
		}
		else if (argnmatch(argv[argi], "--service=")) {
			char *p = strchr(argv[argi], '=');
			locatorservice = get_servicetype(p+1);
		}
		else if (argnmatch(argv[argi], "--filter=")) {
			char *p = strchr(argv[argi], '=');
			msgfilter = compileregex(p+1);
			if (!msgfilter) {
				errprintf("Invalid filter (bad expression): %s\n", p+1);
			}
			else {
				stdfilter = compileregex("^@@(logrotate|shutdown|drophost|droptest|renamehost|renametest)");
			}
		}
		else {
			char *childcmd;
			char **childargs;
			int i = 0;

			childcmd = argv[argi];
			childargs = (char **) calloc((1 + argc - argi), sizeof(char *));
			while (argi < argc) { childargs[i++] = argv[argi++]; }
			addlocalpeer(childcmd, childargs);
		}
	}

	/* Sanity checks */
	if (cnid == -1) {
		errprintf("No channel/unknown channel specified\n");
		return 1;
	}
	if (locatorbased && (locatorservice == ST_MAX)) {
		errprintf("Must specify --service when using locator\n");
		return 1;
	}
	if (!locatorbased && (rbtBegin(peers) == rbtEnd(peers))) {
		errprintf("Must specify command for local worker\n");
		return 1;
	}

	/* Do cache responses to avoid doing too many lookups */
	if (locatorbased) locator_prepcache(locatorservice, 0);

	/* Go daemon */
	if (daemonize) {
		/* Become a daemon */
		pid_t daemonpid = fork();
		if (daemonpid < 0) {
			/* Fork failed */
			errprintf("Could not fork child\n");
			exit(1);
		}
		else if (daemonpid > 0) {
			/* Parent creates PID file and exits */
			FILE *fd = NULL;
			if (pidfile) fd = fopen(pidfile, "w");
			if (fd) {
				fprintf(fd, "%d\n", (int)daemonpid);
				fclose(fd);
			}
			exit(0);
		}
		/* Child (daemon) continues here */
		setsid();
	}

	/* Catch signals */
	setup_signalhandler("xymond_channel");
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sig_handler;
	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGCHLD, &sa, NULL);
	signal(SIGALRM, SIG_IGN);

	/* Switch stdout/stderr to the logfile, if one was specified */
	freopen("/dev/null", "r", stdin);	/* xymond_channel's stdin is not used */
	if (logfn) {
		freopen(logfn, "a", stdout);
		freopen(logfn, "a", stderr);
	}

	/* Attach to the channel */
	channel = setup_channel(cnid, CHAN_CLIENT);
	if (channel == NULL) {
		errprintf("Channel not available\n");
		running = 0;
	}

	while (running) {
		/* 
		 * Wait for GOCLIENT to go up.
		 *
		 * Note that we use IPC_NOWAIT if there are messages in the
		 * queue, because then we just want to pick up a message if
		 * there is one, and if not we want to continue pushing the
		 * queued data to the worker.
		 */
		struct sembuf s;
		int n;

		s.sem_num = GOCLIENT; s.sem_op  = -1; s.sem_flg = ((pendingcount > 0) ? IPC_NOWAIT : 0);
		n = semop(channel->semid, &s, 1);

		if (n == 0) {
			/*
			 * GOCLIENT went high, and so we got alerted about a new
			 * message arriving. Copy the message to our own buffer queue.
			 */
			char *inbuf = NULL;

			if (!msgfilter || matchregex(channel->channelbuf, msgfilter) || matchregex(channel->channelbuf, stdfilter)) {
				inbuf = strdup(channel->channelbuf);
			}

			/* 
			 * Now we have safely stored the new message in our buffer.
			 * Wait until any other clients on the same channel have picked up 
			 * this message (GOCLIENT reaches 0).
			 *
			 * We wrap this into an alarm handler, because it can occasionally
			 * fail, causing the whole system to lock up. We dont want that....
			 * We'll set the alarm to trigger after 1 second. Experience shows
			 * that we'll either succeed in a few milliseconds, or fail completely
			 * and wait the full alarm-timer duration.
			 */
			gotalarm = 0; signal(SIGALRM, sig_handler); alarm(2); 
			do {
				s.sem_num = GOCLIENT; s.sem_op  = 0; s.sem_flg = 0;
				n = semop(channel->semid, &s, 1);
			} while ((n == -1) && (errno == EAGAIN) && running && (!gotalarm));
			signal(SIGALRM, SIG_IGN);

			if (gotalarm) {
				errprintf("Gave up waiting for GOCLIENT to go low.\n");
			}

			/* 
			 * Let master know we got it by downing BOARDBUSY.
			 * This should not block, since BOARDBUSY is upped
			 * by the master just before he ups GOCLIENT.
			 */
			do {
				s.sem_num = BOARDBUSY; s.sem_op  = -1; s.sem_flg = IPC_NOWAIT;
				n = semop(channel->semid, &s, 1);
			} while ((n == -1) && (errno == EINTR));
			if (n == -1) {
				errprintf("Tried to down BOARDBUSY: %s\n", strerror(errno));
			}

			if (inbuf) {
				/*
				 * See if they want us to rotate logs. We pass this on to
				 * the worker module as well, but must handle our own logfile.
				 */
				if (strncmp(inbuf, "@@logrotate", 11) == 0) {
					freopen(logfn, "a", stdout);
					freopen(logfn, "a", stderr);
				}

				/*
				 * Put the new message on our outbound queue.
				 */
				if (addmessage(inbuf) != 0) {
					/* Failed to queue message, free the buffer */
					xfree(inbuf);
				}
			}
		}
		else {
			if (errno != EAGAIN) {
				dbgprintf("Semaphore wait aborted: %s\n", strerror(errno));
				continue;
			}
		}

		/* 
		 * We've picked up messages from the master. Now we 
		 * must push them to the worker process. Since there 
		 * is no way to hang off both a semaphore and select(),
		 * we'll just push as much data as possible into the 
		 * pipe. If we get to a point where we would block,
		 * then wait a teeny bit of time and restart the 
		 * whole loop with checking for new messages from the
		 * master etc.
		 *
		 * In theory, this could become an almost busy-wait loop.
		 * In practice, however, the queue will be empty most
		 * of the time because we'll just shove the data to the
		 * worker child.
		 */
		for (handle = rbtBegin(peers); (handle != rbtEnd(peers)); handle = rbtNext(peers, handle)) {
			int canwrite = 1, hasfailed = 0;
			xymon_peer_t *pwalk;
			time_t msgtimeout = gettimer() - MSGTIMEOUT;
			int flushcount = 0;

			pwalk = (xymon_peer_t *) gettreeitem(peers, handle);
			if (pwalk->msghead == NULL) continue; /* Ignore peers with nothing queued */

			switch (pwalk->peerstatus) {
			  case P_UP:
				canwrite = 1;
				break;

			  case P_DOWN:
				openconnection(pwalk);
				canwrite = (pwalk->peerstatus == P_UP);
				break;

			  case P_FAILED:
				canwrite = 0;
				break;
			}

			/* See if we have stale messages queued */
			while (pwalk->msghead && (pwalk->msghead->tstamp < msgtimeout)) {
				flushmessage(pwalk);
				flushcount++;
			}

			if (flushcount) {
				errprintf("Flushed %d stale messages for %s:%d\n",
					  flushcount,
				  	  inet_ntoa(pwalk->peeraddr.sin_addr), 
					  ntohs(pwalk->peeraddr.sin_port));
			}

			while (pwalk->msghead && canwrite) {
				fd_set fdwrite;
				struct timeval tmo;

				/* Check that this peer is ready for writing. */
				FD_ZERO(&fdwrite); FD_SET(pwalk->peersocket, &fdwrite);
				tmo.tv_sec = 0; tmo.tv_usec = 2000;
				n = select(pwalk->peersocket+1, NULL, &fdwrite, NULL, &tmo);
				if (n == -1) {
					errprintf("select() failed: %s\n", strerror(errno));
					canwrite = 0; 
					hasfailed = 1;
					continue;
				}
				else if ((n == 0) || (!FD_ISSET(pwalk->peersocket, &fdwrite))) {
					canwrite = 0;
					continue;
				}

				n = write(pwalk->peersocket, pwalk->msghead->bufp, pwalk->msghead->buflen);
				if (n >= 0) {
					pwalk->msghead->bufp += n;
					pwalk->msghead->buflen -= n;
					if (pwalk->msghead->buflen == 0) flushmessage(pwalk);
				}
				else if (errno == EAGAIN) {
					/*
					 * Write would block ... stop for now. 
					 */
					canwrite = 0;
				}
				else {
					hasfailed = 1;
				}

				if (hasfailed) {
					/* Write failed, or message grew stale */
					errprintf("Peer at %s:%d failed: %s\n",
						  inet_ntoa(pwalk->peeraddr.sin_addr), ntohs(pwalk->peeraddr.sin_port),
						  strerror(errno));
					canwrite = 0;
					shutdownconnection(pwalk);
					if (pwalk->peertype == P_NET) locator_serverdown(pwalk->peername, locatorservice);
					pwalk->peerstatus = P_FAILED;
				}
			}
		}
	}

	/* Detach from channels */
	close_channel(channel, CHAN_CLIENT);

	/* Close peer connections */
	for (handle = rbtBegin(peers); (handle != rbtEnd(peers)); handle = rbtNext(peers, handle)) {
		xymon_peer_t *pwalk = (xymon_peer_t *) gettreeitem(peers, handle);
		shutdownconnection(pwalk);
	}

	/* Remove the PID file */
	if (pidfile) unlink(pidfile);

	return 0;
}
Ejemplo n.º 5
0
int main(int argc, char **argv)
{
	pcre *hostptn, *exhostptn, *pageptn, *expageptn;
	void *hwalk;
	char *hostname, *pagename;

	hostptn = exhostptn = pageptn = expageptn = NULL;

	if (getenv("QUERY_STRING") == NULL) {
		/* Not invoked through the CGI */
		if (argc < 4) {
			errprintf("Usage:\n%s HOSTNAME-PATTERN STARTTIME ENDTIME", argv[0]);
			return 1;
		}

		hostpattern = argv[1];
		if (strncmp(hostpattern, "--page=", 7) == 0) {
			pagepattern = strchr(argv[1], '=') + 1;
			hostpattern = NULL;
		}
		starttimedate = argv[2]; starttimehm = "00:00:00";
		endtimedate = argv[3]; endtimehm = "00:00:00";
		if (argc > 4) {
			if (strncmp(argv[4], "--csv", 5) == 0) {
				char *p;

				outform = O_CSV;
				if ((p = strchr(argv[4], '=')) != NULL) csvdelim = *(p+1);
			}
		}
	}
	else {
		char *envarea = NULL;
		int argi;

		for (argi = 1; (argi < argc); argi++) {
			if (argnmatch(argv[argi], "--env=")) {
				char *p = strchr(argv[argi], '=');
				loadenv(p+1, envarea);
			}
			else if (argnmatch(argv[argi], "--area=")) {
				char *p = strchr(argv[argi], '=');
				envarea = strdup(p+1);
			}
			else if (strcmp(argv[argi], "--debug") == 0) {
				debug = 1;
			}
		}

		/* Parse CGI parameters */
		parse_query();
		format_rrdtime(starttime, &starttimedate, &starttimehm);
		format_rrdtime(endtime, &endtimedate, &endtimehm);

		switch (outform) {
		  case O_XML:
			printf("Content-type: application/xml\n\n");
			break;

		  case O_CSV:
			printf("Content-type: text/csv\n\n");
			break;

		  case O_NONE:
			load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
			printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
			showform(stdout, "perfdata", "perfdata_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL);
			return 0;
		}
	}

	load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());

	if (hostpattern) hostptn = compileregex(hostpattern);
	if (exhostpattern) exhostptn = compileregex(exhostpattern);
	if (pagepattern) pageptn = compileregex(pagepattern);
	if (expagepattern) expageptn = compileregex(expagepattern);

	switch (outform) {
	  case O_XML:
		printf("<?xml version='1.0' encoding='ISO-8859-1'?>\n");
		printf("<datasets>\n");
		break;
	  default:
		break;
	}

	dbgprintf("Got hosts, it is %s\n", (first_host() == NULL) ? "empty" : "not empty");

	for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) {
		hostname = xmh_item(hwalk, XMH_HOSTNAME);
		pagename = xmh_item(hwalk, XMH_PAGEPATH);

		dbgprintf("Processing host %s\n", hostname);

		if (hostpattern && !matchregex(hostname, hostptn)) continue;
		if (exhostpattern && matchregex(hostname, exhostptn)) continue;
		if (pagepattern && !matchregex(pagename, pageptn)) continue;
		if (expagepattern && matchregex(pagename, expageptn)) continue;

		onehost(hostname, starttime, endtime);
	}

	switch (outform) {
	  case O_XML:
		printf("</datasets>\n");
		break;
	  default:
		break;
	}

	return 0;
}