Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
	void *walk;

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

	for (walk = first_host(); (walk); walk=next_host(walk, 0)) {
		char *nk, *nktime, *tok;

		nk = xmh_item(walk, XMH_NK); if (!nk) continue;
		nktime = xmh_item(walk, XMH_NKTIME);

		nk = strdup(nk);

		tok = strtok(nk, ",");
		while (tok) {
			char *hostname = xmh_item(walk, XMH_HOSTNAME);
			char *startstr = "", *endstr = "", *ttgroup = "", *ttextra = "", *updinfo = "Migrated";
			int priority = 2;

			fprintf(stdout, "%s|%s|%s|%s|%s|%d|%s|%s|%s\n",
				hostname, tok,
				startstr, endstr,
				(nktime ? nktime : ""),
				priority, ttgroup, ttextra, updinfo);

			tok = strtok(NULL, ",");
		}

		xfree(nk);
	}

	return 0;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
	int argi;
	char *envarea = NULL;
	char *critconfig = NULL;
	char *hffile = "critical";

	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;
		}
		else if (strcmp(argv[argi], "--tooltips") == 0) {
			usetooltips = 1;
		}
		else if (argnmatch(argv[argi], "--acklevel=")) {
			char *p = strchr(argv[argi], '=');
			critacklevel = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--config=")) {
			char *p = strchr(argv[argi], '=');
			critconfig = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--hffile=")) {
			char *p = strchr(argv[argi], '=');
			hffile = strdup(p+1);
		}
	}

	redirect_cgilog("criticalview");

	setdocurl(hostsvcurl("%s", xgetenv("INFOCOLUMN"), 1));

	parse_query();
	load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
	load_critconfig(critconfig);
	load_all_links();
	fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

	if (loadstatus(maxprio, maxage, mincolor, wantacked) == 0) {
		use_recentgifs = 1;
		generate_critpage(stdout, hffile);
	}
	else {
		fprintf(stdout, "Cannot load Xymon status\n");
	}

	return 0;
}
Ejemplo n.º 3
0
/** Get full qualified domain name for current system.
 * Retreive the fqdn for the local machine
 * @return the fqdn on success, NULL otherwise
 */
char *
get_local_fqdn (void) /*{{{*/
{
	char		*fqdn;
	struct utsname	un;
	
	fqdn = NULL;
	if (uname (& un) != -1)
		fqdn = get_fqdn (un.nodename);
	return fqdn;
}/*}}}*/
Ejemplo n.º 4
0
void loadhostdata(char *hostname, char **ip, char **displayname)
{
	namelist_t *hinfo = NULL;

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

	if ((hinfo = hostinfo(hostname)) == NULL) {
		errormsg("No such host");
		exit(1);
	}

	*ip = bbh_item(hinfo, BBH_IP);
	*displayname = bbh_item(hinfo, BBH_DISPLAYNAME);
	if (!(*displayname)) *displayname = hostname;
}
Ejemplo n.º 5
0
int main(int argc, char *argv[])
{
	int argi;
	char *envarea = NULL;

	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;
		}
	}

	redirect_cgilog("hobbit-notifylog");
	load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn());

	fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

	cgidata = cgi_request();
	if (cgidata == NULL) {
		/* Present the query form */
		sethostenv("", "", "", colorname(COL_BLUE), NULL);
		showform(stdout, "notify", "notify_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL);
		return 0;
	}

	parse_query();

	/* Now generate the webpage */
	headfoot(stdout, "notify", "", "header", COL_GREEN);
	fprintf(stdout, "<center>\n");
	do_notifylog(stdout, maxcount, maxminutes, fromtime, totime, 
			pageregex, expageregex, 
			hostregex, exhostregex, 
			testregex, extestregex,
			rcptregex, exrcptregex);
	fprintf(stdout, "</center>\n");
	headfoot(stdout, "notify", "", "footer", COL_GREEN);

	return 0;
}
Ejemplo n.º 6
0
static SSLCertificate *ssl_certificate_new_lookup(X509 *x509_cert,
	const char *host, int port, int lookup)
{
	SSLCertificate *cert = g_new0(SSLCertificate, 1);

	if (host == NULL || x509_cert == NULL) {
		ssl_certificate_destroy(cert);
		return NULL;
	}
	cert->x509_cert = X509_dup(x509_cert);
	if (lookup)
		cert->host = get_fqdn(host, port);
	else
		cert->host = g_strdup(host);
	cert->port = port;
	return cert;
}
Ejemplo n.º 7
0
void *hostinfo(char *hostname)
{
	RbtIterator hosthandle;
	namelist_t *result = NULL;
	time_t now = getcurrenttime(NULL);

	if (!configloaded) load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn());

	hosthandle = rbtFind(rbhosts, hostname);
	if (hosthandle != rbtEnd(rbhosts)) {
		void *k1, *k2;

		rbtKeyValue(rbhosts, hosthandle, &k1, &k2);
		result = (namelist_t *)k2;

		if ((result->notbefore > now) || (result->notafter < now)) return NULL;
	}

	return result;
}
Ejemplo n.º 8
0
SSLCertificate *ssl_certificate_find_lookup(const char *host, int port,
	int lookup)
{
	char *file = NULL;
	char *buf = NULL;
	char *fqdn_host = NULL;
	SSLCertificate *cert = NULL;
	X509 *tmp_x509 = NULL;
	FILE *fp = NULL;

	if (lookup)
		fqdn_host = get_fqdn(host, port);
	else
		fqdn_host = g_strdup(host);

	buf = g_strdup_printf("%d", port);
	file = g_strconcat(config_dir, G_DIR_SEPARATOR_S,
		"certs", G_DIR_SEPARATOR_S, fqdn_host, ".", buf, ".cert", NULL);

	g_free(buf);
	fp = fopen(file, "rb");
	if (fp == NULL) {
		g_free(file);
		g_free(fqdn_host);
		return NULL;
	}

	if ((tmp_x509 = d2i_X509_fp(fp, 0)) != NULL) {
		cert = ssl_certificate_new_lookup(tmp_x509, fqdn_host, port,
			lookup);
		X509_free(tmp_x509);
	}
	fclose(fp);
	g_free(file);
	g_free(fqdn_host);

	return cert;
}
Ejemplo n.º 9
0
int main(int argc, char *argv[])
{
        void *hwalk;
	int argi;
	strbuffer_t *statusmsg, *jrockout, *qout;

	for (argi = 1; (argi < argc); argi++) {
		if ((strcmp(argv[argi], "--help") == 0)) {
			printf("beastat version %s\n\n", VERSION);
			printf("Usage:\n%s [--debug] [--no-update] [--port=SNMPPORT] [--community=SNMPCOMMUNITY]\n", 
				argv[0]);
			exit(0);
		}
		else if ((strcmp(argv[argi], "--version") == 0)) {
			printf("beastat version %s\n", VERSION);
			exit(0);
		}
		else if ((strcmp(argv[argi], "--debug") == 0)) {
			debug = 1;
		}
		else if ((strcmp(argv[argi], "--no-update") == 0)) {
			dontsendmessages = 1;
		}
		else if (argnmatch(argv[argi], "--timeout=")) {
			char *p = strchr(argv[argi], '=');
			extcmdtimeout = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--port=")) {
			char *p = strchr(argv[argi], '=');
			default_port = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--community=")) {
			char *p = strchr(argv[argi], '=');
			default_community = strdup(p+1);
		}
	}

        load_hostnames(xgetenv("BBHOSTS"), "netinclude", get_fqdn());
        if (first_host() == NULL) {
                errprintf("Cannot load bb-hosts\n");
                return 1;
        }

        if (xgetenv("BBLOCATION")) location = strdup(xgetenv("BBLOCATION"));

	init_timestamp();
	combo_start();
	statusmsg = newstrbuffer(0);
	jrockout = newstrbuffer(0);
	qout = newstrbuffer(0);

	for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) {
		char *tspec = bbh_custom_item(hwalk, "bea=");
		char *snmpcommunity = default_community;
		char *beadomain = "";
		int snmpport = default_port;
		char *p;
		char pipecmd[4096];
		int jrockres, qres;

		clearstrbuffer(statusmsg);
		clearstrbuffer(jrockout);
		clearstrbuffer(qout);

		/* Check if we have a "bea" test for this host, and it is a host we want to test */
                if (!tspec || !wanted_host(hwalk, location)) continue;

		/* Parse the testspec: bea=[SNMPCOMMUNITY@]BEADOMAIN[:SNMPPORT] */
		tspec = strdup(tspec+strlen("bea="));

		p = strchr(tspec, ':');
		if (p) {
			*p = '\0';
			snmpport = atoi(p+1);
		}

		p = strchr(tspec, '@');
		if (p) {
			*p = '\0';
			snmpcommunity = strdup(tspec);
			beadomain = strdup(p+1);
		}
		else {
			beadomain = strdup(tspec);
		}

		/* Prepare for the host status */
		statuscolor = COL_GREEN;

		/* Setup the snmpwalk pipe-command for jrockit stats */
		sprintf(pipecmd, "snmpwalk -m BEA-WEBLOGIC-MIB -c %s@%s -v 1 %s:%d enterprises.140.625.302.1",
			snmpcommunity, beadomain, bbh_item(hwalk, BBH_IP), snmpport);
		jrockres = run_command(pipecmd, NULL, jrockout, 0, extcmdtimeout);
		if (jrockres == 0) {
			find_idxes(STRBUF(jrockout), "BEA-WEBLOGIC-MIB::jrockitRuntimeIndex.");
			send_data(hwalk, beadomain, STRBUF(jrockout), jrockitems);
		}
		else {
			if (statuscolor < COL_YELLOW) statuscolor = COL_YELLOW;
			sprintf(msgline, "Could not retrieve BEA jRockit statistics from %s:%d domain %s (code %d)\n",
				bbh_item(hwalk, BBH_IP), snmpport, beadomain, jrockres);
			addtobuffer(statusmsg, msgline);
		}

		/* Setup the snmpwalk pipe-command for executeQueur stats */
		sprintf(pipecmd, "snmpwalk -m BEA-WEBLOGIC-MIB -c %s@%s -v 1 %s:%d enterprises.140.625.180.1",
			snmpcommunity, beadomain, bbh_item(hwalk, BBH_IP), snmpport);
		qres = run_command(pipecmd, NULL, qout, 0, extcmdtimeout);
		if (qres == 0) {
			find_idxes(STRBUF(qout), "BEA-WEBLOGIC-MIB::executeQueueRuntimeIndex.");
			send_data(hwalk, beadomain, STRBUF(qout), qitems);
		}
		else {
			if (statuscolor < COL_YELLOW) statuscolor = COL_YELLOW;
			sprintf(msgline, "Could not retrieve BEA executeQueue statistics from %s:%d domain %s (code %d)\n",
				bbh_item(hwalk, BBH_IP), snmpport, beadomain, qres);
			addtobuffer(statusmsg, msgline);
		}

		/* FUTURE: Have the statuscolor/statusmsg be updated to check against thresholds */
		/* Right now, the "bea" status is always green */
		init_status(statuscolor);
		sprintf(msgline, "status %s.%s %s %s\n\n", commafy(bbh_item(hwalk, BBH_HOSTNAME)), "bea", colorname(statuscolor), timestamp);
		addtostatus(msgline);
		if (STRBUFLEN(statusmsg) == 0) addtobuffer(statusmsg, "All BEA monitors OK\n");
		addtostrstatus(statusmsg);
		finish_status();
	}

	combo_end();
	freestrbuffer(statusmsg);
	freestrbuffer(jrockout);
	freestrbuffer(qout);

	return 0;
}
Ejemplo n.º 10
0
int main(int argc, char *argv[])
{
	int argi;
	struct sigaction sa;
	namelist_t *hostwalk;
	time_t nexttimeout;

	for (argi=1; (argi < argc); argi++) {
		if (argnmatch(argv[argi], "--server=")) {
			char *p = strchr(argv[argi], '=');
			serverip = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--interval=")) {
			char *p = strchr(argv[argi], '=');
			pollinterval = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--log-interval=")) {
			char *p = strchr(argv[argi], '=');
			errorloginterval = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--id=")) {
			char *p = strchr(argv[argi], '=');
			serverid = atoi(p+1);
		}
		else if (strcmp(argv[argi], "--debug") == 0) {
			debug = 1;
		}
	}

	setup_signalhandler("hobbitfetch");
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sigmisc_handler;
	sigaction(SIGHUP, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGUSR1, &sa, NULL);	/* SIGUSR1 triggers logging of active requests */

	clients = rbtNew(name_compare);
	nexttimeout = time(NULL) + 60;

	{
		/* Seed the random number generator */
		struct timeval tv;
		struct timezone tz;

		gettimeofday(&tv, &tz);
		srandom(tv.tv_usec);
	}

	do {
		RbtIterator handle;
		conn_t *connwalk, *cprev;
		fd_set fdread, fdwrite;
		int n, maxfd;
		struct timeval tmo;
		time_t now;
		
		now = time(NULL);
		if (now > reloadtime) {
			/* Time to reload the bb-hosts file */
			reloadtime = now + 600;

			load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn());
			for (hostwalk = first_host(); (hostwalk); hostwalk = hostwalk->next) {
				char *hname;
				clients_t *newclient;

				if (!bbh_item(hostwalk, BBH_FLAG_PULLDATA)) continue;

				hname = bbh_item(hostwalk, BBH_HOSTNAME);
				handle = rbtFind(clients, hname);
				if (handle == rbtEnd(clients)) {
					newclient = (clients_t *)calloc(1, sizeof(clients_t));
					newclient->hostname = strdup(hname);
					rbtInsert(clients, newclient->hostname, newclient);
					whentoqueue = now;
				}
			}
		}

		now = time(NULL);
		if (now > nexttimeout) {
			/* Check for connections that have timed out */
			nexttimeout = now + 60;

			for (connwalk = chead; (connwalk); connwalk = connwalk->next) {
				if ((connwalk->tstamp + 60) < now) {
					if (debug || (connwalk->client->nexterrortxt < now)) {
						errprintf("Timeout while talking to %s (req %lu): Aborting session\n",
							  addrstring(&connwalk->caddr), connwalk->seq);
						connwalk->client->nexterrortxt = now + errorloginterval;
					}
					flag_cleanup(connwalk);
				}
			}
		}

		if (needcleanup) {
			/* Remove any finished requests */
			needcleanup = 0;
			connwalk = chead; cprev = NULL;
			dbgprintf("Doing cleanup\n");

			while (connwalk) {
				conn_t *zombie;

				if ((connwalk->action == C_READING) || (connwalk->action == C_WRITING)) {
					/* Active connection - skip to the next conn_t record */
					cprev = connwalk;
					connwalk = connwalk->next;
					continue;
				}

				if (connwalk->action == C_CLEANUP) {
					if (connwalk->ctype == C_CLIENT) {
						/* 
						 * Finished getting data from a client, 
						 * flag idle and set next poll time.
						 */
						connwalk->client->busy = 0;
						set_polltime(connwalk->client);
					}
					else if (connwalk->ctype == C_SERVER) {
						/* Nothing needed for server cleanups */
					}
				}

				/* Unlink the request from the list of active connections */
				zombie = connwalk;
				if (cprev == NULL) {
					chead = zombie->next;
					connwalk = chead;
					cprev = NULL;
				}
				else {
					cprev->next = zombie->next;
					connwalk = zombie->next;
				}

				/* Purge the zombie */
				dbgprintf("Request completed: req %lu, peer %s, action was %d, type was %d\n", 
					zombie->seq, addrstring(&zombie->caddr), 
					zombie->action, zombie->ctype);
				close(zombie->sockfd);
				freestrbuffer(zombie->msgbuf);
				xfree(zombie);
			}

			/* Set the tail pointer correctly */
			ctail = chead;
			if (ctail) { while (ctail->next) ctail = ctail->next; }
		}

		if (dumpsessions) {
			/* Set by SIGUSR1 - dump the list of active requests */
			dumpsessions = 0;
			for (connwalk = chead; (connwalk); connwalk = connwalk->next) {
				char *ctypestr, *actionstr;
				char timestr[30];

				switch (connwalk->ctype) {
				  case C_CLIENT: ctypestr = "client"; break;
				  case C_SERVER: ctypestr = "server"; break;
				}

				switch (connwalk->action) {
				  case C_READING: actionstr = "reading"; break;
				  case C_WRITING: actionstr = "writing"; break;
				  case C_CLEANUP: actionstr = "cleanup"; break;
				}

				strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S",
					 localtime(&connwalk->tstamp));

				errprintf("Request %lu: state %s/%s, peer %s, started %s (%lu secs ago)\n",
					  connwalk->seq, ctypestr, actionstr, addrstring(&connwalk->caddr),
					  timestr, (now - connwalk->tstamp));
			}
		}

		now = time(NULL);
		if (now >= whentoqueue) {
			/* Scan host-tree for clients we need to contact */
			for (handle = rbtBegin(clients); (handle != rbtEnd(clients)); handle = rbtNext(clients, handle)) {
				clients_t *clientwalk;
				char msgline[100];
				strbuffer_t *request;
				char *pullstr, *ip;
				int port;

				clientwalk = (clients_t *)gettreeitem(clients, handle);
				if (clientwalk->busy) continue;
				if (clientwalk->nextpoll > now) continue;

				/* Deleted hosts stay in our tree - but should disappear from the known hosts */
				hostwalk = hostinfo(clientwalk->hostname); if (!hostwalk) continue;
				pullstr = bbh_item(hostwalk, BBH_FLAG_PULLDATA); if (!pullstr) continue;

				ip = strchr(pullstr, '=');
				port = atoi(xgetenv("BBPORT"));

				if (!ip) {
					ip = strdup(bbh_item(hostwalk, BBH_IP));
				}
				else {
					/* There is an explicit IP setting in the pulldata tag */
					char *p;

					ip++; /* Skip the '=' */
					ip = strdup(ip);
					p = strchr(ip, ':');
					if (p) { *p = '\0'; port = atoi(p+1); }

					if (*ip == '\0') {
						/* No IP given, just a port number */
						xfree(ip);
						ip = strdup(bbh_item(hostwalk, BBH_IP));
					}
				}

				if (strcmp(ip, "0.0.0.0") == 0) {
					struct hostent *hent;

					xfree(ip); ip = NULL;
					hent = gethostbyname(clientwalk->hostname);
					if (hent) {
						struct in_addr addr;

						memcpy(&addr, *(hent->h_addr_list), sizeof(addr));
						ip = strdup(inet_ntoa(addr));
					}
				}

				if (!ip) continue;

				/* 
				 * Build the "pullclient" request, which includes the latest
				 * clientdata config we got from the server. Keep the clientdata
				 * here - we send "pullclient" requests more often that we actually
				 * contact the server, but we should provide the config data always.
				 */
				request = newstrbuffer(0);
				sprintf(msgline, "pullclient %d\n", serverid);
				addtobuffer(request, msgline);
				if (clientwalk->clientdata) addtobuffer(request, clientwalk->clientdata);

				/* Put the request on the connection queue */
				addrequest(C_CLIENT, ip, port, request, clientwalk);
				clientwalk->busy = 1;

				xfree(ip);
			}
		}

		/* Handle request queue */
		FD_ZERO(&fdread);
		FD_ZERO(&fdwrite);
		maxfd = -1;
		for (connwalk = chead; (connwalk); connwalk = connwalk->next) {
			switch (connwalk->action) {
			  case C_READING: 
				FD_SET(connwalk->sockfd, &fdread);
				if (connwalk->sockfd > maxfd) maxfd = connwalk->sockfd;
				break;

			  case C_WRITING: 
				FD_SET(connwalk->sockfd, &fdwrite);
				if (connwalk->sockfd > maxfd) maxfd = connwalk->sockfd;
				break;

			  case C_CLEANUP:
				break;
			}
		}

		/* Do select with a 1 second timeout */
		tmo.tv_sec = 1;
		tmo.tv_usec = 0;
		n = select(maxfd+1, &fdread, &fdwrite, NULL, &tmo);

		if (n == -1) {
			if (errno == EINTR) continue;	/* Interrupted, e.g. a SIGHUP */

			/* This is a "cannot-happen" failure. Bail out */
			errprintf("select failure: %s\n", strerror(errno));
			return 0;
		}

		if (n == 0) continue;	/* Timeout */

		for (connwalk = chead; (connwalk); connwalk = connwalk->next) {
			switch (connwalk->action) {
			  case C_READING: 
				if (FD_ISSET(connwalk->sockfd, &fdread)) grabdata(connwalk);
				break;

			  case C_WRITING: 
				if (FD_ISSET(connwalk->sockfd, &fdwrite)) senddata(connwalk);
				break;

			  case C_CLEANUP:
				break;
			}
		}

	} while (running);

	return 0;
}
Ejemplo n.º 11
0
int main(int argc, char *argv[])
{
	int argi;
	DIR *histdir = NULL;
	struct dirent *hent;
	struct stat st;
	time_t cutoff = 0;
	int dropsvcs = 0;
	int dropfiles = 0;
	int droplogs = 0;
	char *envarea = NULL;

	for (argi = 1; (argi < argc); argi++) {
		if (argnmatch(argv[argi], "--cutoff=")) {
			char *p = strchr(argv[argi], '=');
			cutoff = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--outdir=")) {
			char *p = strchr(argv[argi], '=');
			outdir = strdup(p+1);
		}
		else if (strcmp(argv[argi], "--drop") == 0) {
			dropfiles = 1;
		}
		else if (strcmp(argv[argi], "--dropsvcs") == 0) {
			dropsvcs = 1;
		}
		else if (strcmp(argv[argi], "--droplogs") == 0) {
			droplogs = 1;
		}
		else if (strcmp(argv[argi], "--progress") == 0) {
			progressinfo = 100;
		}
		else if (argnmatch(argv[argi], "--progress=")) {
			char *p = strchr(argv[argi], '=');
			progressinfo = atoi(p+1);
		}
		else if (strcmp(argv[argi], "--debug") == 0) {
			debug = 1;
		}
		else if (strcmp(argv[argi], "--help") == 0) {
			printf("Usage:\n\n\t%s --cutoff=TIME\n\nTIME is in seconds since epoch\n", argv[0]);
			return 0;
		}
		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);
		}
	}

	if (cutoff == 0) {
		errprintf("Must have a cutoff-time\n");
		return 1;
	}

	if (chdir(xgetenv("BBHIST")) == -1) {
		errprintf("Cannot cd to history directory: %s\n", strerror(errno));
		return 1;
	}

	histdir = opendir(".");
	if (!histdir) {
		errprintf("Cannot read history directory: %s\n", strerror(errno));
		return 1;
	}

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

	/* First scan the directory for all files, and pick up the ones we want to process */
	while ((hent = readdir(histdir)) != NULL) {
		char *hostname = NULL;
		char hostip[IP_ADDR_STRLEN];
		int ghosthandling = 1;

		if (stat(hent->d_name, &st) == -1) {
			errprintf("Odd entry %s - cannot stat: %s\n", hent->d_name, strerror(errno));
			continue;
		}

		if ((*(hent->d_name) == '.') || S_ISDIR(st.st_mode)) continue;

		if (strcmp(hent->d_name, "allevents") == 0) {
			/* Special all-hosts-services event log */
			add_to_filelist(hent->d_name, F_ALLEVENTS);
			continue;
		}

		hostname = knownhost(hent->d_name, hostip, ghosthandling);
		if (hostname) {
			/* Host history file. */
			add_to_filelist(hent->d_name, F_HOSTHISTORY);
		}
		else {
			char *delim, *p, *hname, *tname;

			delim = strrchr(hent->d_name, '.');
			if (!delim) {
				/* It's a host history file (no dot in filename), but the host does not exist */
				errprintf("Orphaned host-history file %s - no host\n", hent->d_name);
				if (dropfiles) add_to_filelist(hent->d_name, F_DROPIT);
				continue;
			}

			*delim = '\0'; hname = strdup(hent->d_name); tname = delim+1; *delim = '.';
			p = strchr(hname, ','); while (p) { *p = '.'; p = strchr(p, ','); }
			hostname = knownhost(hname, hostip, ghosthandling);
			if (!hostname) {
				errprintf("Orphaned service-history file %s - no host\n", hent->d_name);
				if (dropfiles) add_to_filelist(hent->d_name, F_DROPIT);
			}
			else if (dropsvcs && !validstatus(hostname, tname)) {
				errprintf("Orphaned service-history file %s - no service\n", hent->d_name);
				if (dropfiles) add_to_filelist(hent->d_name, F_DROPIT);
			}
			else {
				/* Service history file */
				add_to_filelist(hent->d_name, F_SERVICEHISTORY);
			}
			xfree(hname);
		}
	}

	closedir(histdir);

	/* Then process the files */
	if (progressinfo) errprintf("Starting trim of %d history-logs\n", totalitems);
	trim_files(cutoff);


	/* Process statuslogs also ? */
	if (!droplogs) return 0;

	flhead = NULL;  /* Dirty - we should clean it up properly - but I dont care */
	totalitems = 0;
	if (chdir(xgetenv("BBHISTLOGS")) == -1) {
		errprintf("Cannot cd to historical statuslogs directory: %s\n", strerror(errno));
		return 1;
	}

	histdir = opendir(".");
	if (!histdir) {
		errprintf("Cannot read historical statuslogs directory: %s\n", strerror(errno));
		return 1;
	}

	while ((hent = readdir(histdir)) != NULL) {
		if (stat(hent->d_name, &st) == -1) {
			errprintf("Odd entry %s - cannot stat: %s\n", hent->d_name, strerror(errno));
			continue;
		}

		if ((*(hent->d_name) == '.') || !S_ISDIR(st.st_mode)) continue;

		if (knownloghost(hent->d_name)) {
			add_to_filelist(hent->d_name, F_PURGELOGS);
		}
		else {
			add_to_filelist(hent->d_name, F_DROPIT);
		}
	}

	closedir(histdir);

	if (progressinfo) errprintf("Starting trim of %d status-log collections\n", totalitems);
	trim_logs(cutoff);

	return 0;
}
Ejemplo n.º 12
0
int main(int argc, char *argv[])
{ 
	void *hwalk;
	char *hostsfn = NULL;
	char *netstring = NULL;
	char *include2 = NULL;
	int extras = 1;
	int testuntagged = 0;
	int nodownhosts = 0;
	int onlypreferredentry = 0;
	char *p;
	char **lookv;
	int argi, lookc;
	strbuffer_t *wantedtags;

	if ((argc <= 1) || (strcmp(argv[1], "--help") == 0)) {
		printf("Usage:\n%s test1 [test1] [test2] ... \n", argv[0]);
		exit(1);
	}

	lookv = (char **)malloc(argc*sizeof(char *));
	lookc = 0;

	hostsfn = xgetenv("HOSTSCFG");
	conncolumn = xgetenv("PINGCOLUMN");

	for (argi=1; (argi < argc); argi++) {
		if (strcmp(argv[argi], "--noextras") == 0) {
			extras = 0;
		}
		else if (strcmp(argv[argi], "--test-untagged") == 0) {
			testuntagged = 1;
		}
		else if (argnmatch(argv[argi], "--no-down")) {
			char *p;
			nodownhosts = 1;
			p = strchr(argv[argi], '=');
			if (p) testcolumn = strdup(p+1);
		}
		else if (strcmp(argv[argi], "--version") == 0) {
			printf("xymongrep version %s\n", VERSION);
			exit(0);
		}
		else if ((strcmp(argv[argi], "--net") == 0) || (strcmp(argv[argi], "--bbnet") == 0)) {
			include2 = "netinclude";
			onlypreferredentry = 0;
		}
		else if ((strcmp(argv[argi], "--web") == 0) || (strcmp(argv[argi], "--bbdisp") == 0)) {
			include2 = "dispinclude";
			onlypreferredentry = 1;
		}
		else if (argnmatch(argv[argi], "--hosts=")) {
			hostsfn = strchr(argv[argi], '=') + 1;
		}
		else {
			lookv[lookc] = strdup(argv[argi]);
			lookc++;
		}
	}
	lookv[lookc] = NULL;

	if ((hostsfn == NULL) || (strlen(hostsfn) == 0)) {
		errprintf("Environment variable HOSTSCFG is not set - aborting\n");
		exit(2);
	}

	load_hostnames(hostsfn, include2, get_fqdn());
	if (first_host() == NULL) {
		errprintf("Cannot load %s, or file is empty\n", hostsfn);
		exit(3);
	}

	/* If we must avoid downed or disabled hosts, let's find out what those are */
	if (nodownhosts) load_hoststatus();

	/* Each network test tagged with NET:locationname */
	p = xgetenv("XYMONNETWORK");
	if ((p == NULL) || (strlen(p) == 0)) p = xgetenv("BBLOCATION");
	if (p && strlen(p)) netstring = strdup(p);

	hwalk = first_host();
	wantedtags = newstrbuffer(0);
	while (hwalk) {
		char hostip[IP_ADDR_STRLEN];
		char *curnet = xmh_item(hwalk, XMH_NET);
		char *curname = xmh_item(hwalk, XMH_HOSTNAME);

		/* 
		 * Only look at the hosts whose NET: definition matches the wanted one.
		 * Must also check if the host is currently down (not responding to ping).
		 * And if the host is OK with knownhost(), because it may be time-limited.
		 */
		if (netok(netstring, curnet, testuntagged) && downok(curname, nodownhosts) && knownhost(curname, hostip, GH_IGNORE)) {
			char *item;

			clearstrbuffer(wantedtags);
			for (item = xmh_item_walk(hwalk); (item); item = xmh_item_walk(NULL)) {
				int i;
				char *realitem = item + strspn(item, "!~?");

				for (i=0; lookv[i]; i++) {
					char *outitem = NULL;

					if (lookv[i][strlen(lookv[i])-1] == '*') {
						if (strncasecmp(realitem, lookv[i], strlen(lookv[i])-1) == 0) {
							outitem = (extras ? item : realitem);
						}
					}
					else if (strcasecmp(realitem, lookv[i]) == 0) {
						outitem = (extras ? item : realitem);
					}

					if (outitem) {
						int needquotes = ((strchr(outitem, ' ') != NULL) || (strchr(outitem, '\t') != NULL));
						addtobuffer(wantedtags, " ");
						if (needquotes) addtobuffer(wantedtags, "\"");
						addtobuffer(wantedtags, outitem);
						if (needquotes) addtobuffer(wantedtags, "\"");
					}
				}
			}

			if (STRBUF(wantedtags) && (*STRBUF(wantedtags) != '\0') && extras) {
				if (xmh_item(hwalk, XMH_FLAG_DIALUP)) addtobuffer(wantedtags, " dialup");
				if (xmh_item(hwalk, XMH_FLAG_TESTIP)) addtobuffer(wantedtags, " testip");
			}

			if (STRBUF(wantedtags) && *STRBUF(wantedtags)) {
				printf("%s %s #%s\n", xmh_item(hwalk, XMH_IP), xmh_item(hwalk, XMH_HOSTNAME), STRBUF(wantedtags));
			}
		}

		do { hwalk = next_host(hwalk, 1); } while (hwalk && onlypreferredentry && (strcmp(curname, xmh_item(hwalk, XMH_HOSTNAME)) == 0));
	}

	return 0;
}
Ejemplo n.º 13
0
int main(int argc, char *argv[])
{
	FILE	*pf;
	char	buff[BUFSIZE];
	int		c, i, port;
	unsigned int tsp;
	char	*scheme, *user, *host, *backup;
	pid_t 	pid;
	struct 	timespec ts;
	int 	upp;

#ifdef HAVE_GETOPT_LONG
	int option_index = 0;
	static struct option l_opts[] = {
		{"help", 0, 0, 'X'},
		{"version", 0, 0, 'V'},
		{"filename", 1, 0, 'f'},
		{"sip-uri", 1, 0, 's'},
		{"traceroute-mode", 0, 0, 'T'},
		{"usrloc-mode", 0, 0, 'U'},
		{"invite-mode", 0, 0, 'I'},
		{"message-mode", 0, 0, 'M'},
		{"contact", 1, 0, 'C'},
		{"appendix-begin", 1, 0, 'b'},
		{"appendix-end", 1, 0, 'e'},
		{"sleep", 1, 0, 'o'},
		{"expires", 1, 0, 'x'},
		{"remove-bindings", 1, 0, 'z'},
		{"flood-mode", 0, 0, 'F'},
		{"random-mode", 0, 0, 'R'},
		{"trash-chars", 1, 0, 't'},
		{"local-port", 1, 0, 'l'},
		{"remote-port", 1, 0, 'r'},
		{"outbound-proxy", 1, 0, 'p'},
		{"hostname", 1, 0, 'H'},
		{"max-fowards", 1, 0, 'm'},
		{"numeric", 0, 0, 'n'},
		{"no-via", 0, 0, 'i'},
		{"password", 1, 0, 'a'},
		{"ignore-redirects", 0, 0, 'd'},
		{"verbose", 0, 0, 'v'},
		{"extract-ip", 0, 0, 'w'},
		{"replace-string", 0, 0, 'g'},
		{"replace", 0, 0, 'G'},
		{"nagios-code", 0, 0, 'N'},
		{"nagios-warn", 1, 0, 'W'},
		{"search", 1, 0, 'q'},
		{"message-body", 1, 0, 'B'},
		{"disposition", 1, 0, 'O'},
		{"processes", 1, 0, 'P'},
		{"auth-username", 1, 0, 'u'},
		{"no-crlf", 0, 0, 'L'},
		{"timing", 1, 0, 'A'},
		{"symmetric", 0, 0, 'S'},
		{"from", 1, 0, 'c'},
		{"timeout-factor", 1, 0, 'D'},
		{"transport", 1, 0, 'E'},
		{"headers", 1, 0, 'j'},
		{0, 0, 0, 0}
	};
#endif
	/* some initialisation to be shure */
	file_b=uri_b=trace=lport=usrloc=flood=verbose=randtrash=trashchar = 0;
	warning_ext=rand_rem=nonce_count=replace_b=invite=message = 0;
	sleep_ms=empty_contact=nagios_warn=timing=outbound_proxy=symmetric = 0;
	namebeg=nameend=maxforw= -1;
	numeric=via_ins=redirects=fix_crlf=processes = 1;
	username=password=replace_str=hostname=contact_uri=mes_body = NULL;
	con_dis=auth_username=from_uri=headers = NULL;
	scheme = user = host = backup = req = rep = rec = NULL;
	re = NULL;
	address= 0;
	transport=tsp = 0;
	rport = port = 0;
	expires_t = USRLOC_EXP_DEF;
	inv_final = 64 * SIP_T1;
	memset(buff, 0, BUFSIZE);
	memset(fqdn, 0, FQDN_SIZE);

	if (argc==1) {
		print_help();
	}

	/* lots of command line switches to handle*/
#ifdef HAVE_GETOPT_LONG
	while ((c=getopt_long(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:Xz:", l_opts, &option_index)) != EOF){
#else
	while ((c=getopt(argc, argv, "a:A:b:B:c:C:dD:e:E:f:Fg:GhH:iIj:l:Lm:MnNo:O:p:P:q:r:Rs:St:Tu:UvVwW:x:z:")) != EOF){
#endif
		switch(c){
			case 'a':
				if (strlen(optarg) == 1 && STRNCASECMP(optarg, "-", 1) == 0) {
					password = str_alloc(SIPSAK_MAX_PASSWD_LEN);
					printf("Please enter the password (max. length %i): ", SIPSAK_MAX_PASSWD_LEN);
					if (read_stdin(password, SIPSAK_MAX_PASSWD_LEN, 1) == 0) {
						exit_code(0);
					}
				}
				else {
					password=str_alloc(strlen(optarg) + 1);
					strncpy(password, optarg, strlen(optarg));
				}
				break;
			case 'A':
				timing=str_to_int(optarg);
				break;
			case 'b':
				namebeg=str_to_int(optarg);
				break;
			case 'B':
				mes_body=str_alloc(strlen(optarg) + 1);
				strncpy(mes_body, optarg, strlen(optarg));
				break;
			case 'c':
				backup=str_alloc(strlen(optarg)+1);
				strncpy(backup, optarg, strlen(optarg));
				parse_uri(backup, &scheme, &user, &host, &port);
				if (scheme  == NULL) {
					fprintf(stderr, "error: missing scheme in From URI\n");
					exit_code(2);
				}
				else if (user == NULL) {
					fprintf(stderr, "error: missing username in From URI\n");
					exit_code(2);
				}
				else if (host == NULL) {
					fprintf(stderr, "error: missing host in From URI\n");
					exit_code(2);
				}
				else {
					from_uri=str_alloc(strlen(optarg)+1);
					strncpy(from_uri, optarg, strlen(optarg));
				}
				free(backup);
				break;
			case 'C':
				if ((strlen(optarg) == 5 && STRNCASECMP(optarg, "empty", 5) == 0) || 
					(strlen(optarg) == 4 && STRNCASECMP(optarg, "none", 4) == 0)) {
					empty_contact = 1;
				}
				else if (strlen(optarg) == 1 && STRNCASECMP(optarg, "*", 1) == 0) {
					contact_uri=str_alloc(strlen(optarg)+1);
					strncpy(contact_uri, optarg, strlen(optarg));
				}
				else {
					backup=str_alloc(strlen(optarg)+1);
					strncpy(backup, optarg, strlen(optarg));
					parse_uri(backup, &scheme, &user, &host, &port);
					if (scheme == NULL) {
					    fprintf(stderr, "error: REGISTER Contact uri doesn't not contain "
						   "sip:, sips:, *, or is not empty\n");
				    	exit_code(2);
					}
					else if (user == NULL) {
						fprintf(stderr, "error: missing username in Contact uri\n");
						exit_code(2);
					}
					else if (host == NULL) {
						fprintf(stderr, "error: missing host in Contact uri\n");
						exit_code(2);
					}
					else {
						contact_uri=str_alloc(strlen(optarg)+1);
						strncpy(contact_uri, optarg, strlen(optarg));
					}
					free(backup);
				}
				break;
			case 'd':
				redirects=0;
				break;
			case 'D':
				inv_final = str_to_int(optarg) * SIP_T1;
				break;
			case 'e':
				nameend=str_to_int(optarg);
				break;
			case 'E':
				if (strlen(optarg) == 3 && 
					STRNCASECMP(optarg, "udp", 3) == 0) {
					transport = SIP_UDP_TRANSPORT;
				}
				else if (strlen(optarg) == 3 &&
						STRNCASECMP(optarg, "tcp", 3) == 0) {
					transport = SIP_TCP_TRANSPORT;
				}
				else if (strlen(optarg) == 3 &&
						STRNCASECMP(optarg, "tls", 3) == 0) {
					fprintf(stderr, "error: TLS is not supported yet, supported values: udp, tcp\n");
					exit_code(2);
					transport = SIP_TLS_TRANSPORT;
				}
				else {
					fprintf(stderr, "error: unsupported transport '%s', supported values: udp, tcp\n", optarg);
					exit_code(2);
				}
				break;
			case 'F':
				flood=1;
				break;
			case 'f':
				if (strlen(optarg) != 1 && STRNCASECMP(optarg, "-", 1) != 0) {
					/* file is opened in binary mode so that the cr-lf is 
					   preserved */
					pf = fopen(optarg, "rb");
					if (!pf){
						fprintf(stderr, "error: unable to open the file '%s'.\n", optarg);
						exit_code(2);
					}
					if (fread(buff, 1, sizeof(buff), pf) >= sizeof(buff)){
						fprintf(stderr, "error:the file is too big. try files of less "
							"than %i bytes.\n", BUFSIZE);
						fprintf(stderr, "      or recompile the program with bigger "
							"BUFSIZE defined.\n");
						exit_code(2);
					}
					fclose(pf);
				}
				else if (strlen(optarg) == 1 && STRNCASECMP(optarg, "-", 1) == 0) {
					if (read_stdin(&buff[0], sizeof(buff), 0) == 0) {
						exit_code(0);
					}
				}
				else {
					fprintf(stderr, "error: unable to handle input file name: %s\n", optarg);
					exit_code(2);
				}
				file_b=1;
				break;
			case 'g':
				replace_str=optarg;
				break;
			case 'G':
				replace_b=1;
				break;
			case 'h':
				print_help();
				break;
			case 'H':
				hostname=optarg;
				break;
			case 'i':
				via_ins=0;
				break;
			case 'I':
				invite=1;
				break;
			case 'j':
				headers=optarg;
				break;
			case 'l':
				lport=str_to_int(optarg);
				break;
			case 'L':
				fix_crlf=0;
				break;
			case 'm':
				maxforw=str_to_int(optarg);
				break;
			case 'M':
				message=1;
				break;
			case 'n':
				numeric = 0;
				break;
			case 'N':
				exit_mode=EM_NAGIOS;
				break;
			case 'o':
				sleep_ms = 0;
				if (strlen(optarg) == 4 && STRNCASECMP(optarg, "rand", 4) == 0) {
					sleep_ms = -2;
				}
				else {
					sleep_ms = str_to_int(optarg);
				}
				break;
			case 'O':
				con_dis=str_alloc(strlen(optarg) + 1);
				strncpy(con_dis, optarg, strlen(optarg));
				break;
			case 'p':
				parse_uri(optarg, &scheme, &user, &host, &rport);
				if (host == NULL) {
					fprintf(stderr, "error: missing in host in outbound proxy\n");
					exit_code(2);
				}
				if (is_ip(host)) {
					address = getaddress(host);
					if (transport == 0)
						transport = SIP_UDP_TRANSPORT;
				}
				else {
					if (!rport) {
						address = getsrvadr(host, &rport, &tsp);
						if (tsp != 0)
							transport = tsp;
					}
					if (!address) {
						address = getaddress(host);
						if (address && verbose > 1)
							printf("using A record: %s\n", host);
					}
					if (!address){
						fprintf(stderr, "error:unable to determine the outbound proxy "
							"address\n");
						exit_code(2);
					}
				}
				outbound_proxy=1;
				break;
			case 'P':
				processes=str_to_int(optarg);
				break;
			case 'q':
				if (re) {
					/* previously allocated -- free */
					regfree(re);
				} else {
					/* never tried -- allocate */
					re=malloc(sizeof(regex_t));
				};
				if (!re) {
					fprintf(stderr, "Error: can't allocate RE\n");
					exit_code(2);
				};
				if (regcomp(re, optarg, REG_EXTENDED|REG_ICASE|REG_NEWLINE )!=0) {
					fprintf(stderr, "Error: compiling RE: %s\n", optarg );
					exit_code(2);
				};
				break;
			case 'r':
				port = 0;
				port=str_to_int(optarg);
				if (rport) {
					fprintf(stderr, "warning: you are overwritting the destination port with the r argument\n");
				}
				rport = port;
				break;
			case 'R':
				randtrash=1;
				break;
			case 's':
				parse_uri(optarg, &scheme, &user, &host, &port);
				if (scheme == NULL) {
					fprintf(stderr, "error: missing scheme in sip uri\n");
					exit_code(2);
				}
				if (strlen(optarg) == 4 && STRNCASECMP(optarg,"sips",4) == 0){
					fprintf(stderr, "error: sips is not supported yet\n");
					exit_code(2);
				}
				else if (strlen(optarg) != 3 || STRNCASECMP(optarg,"sip",3) != 0){
					fprintf(stderr, "error: scheme of sip uri has to be sip\n");
					exit_code(2);
				}
				if (user != NULL) {
					username = user;
				}
				if (host != NULL) {
					domainname = host;
				}
				else {
					fprintf(stderr, "error: missing hostname in sip uri\n");
					exit_code(2);
				}
				if (port && !rport) {
					rport = port;
				}
				if (is_ip(domainname)) {
					address = getaddress(domainname);
					if (transport == 0)
						transport = SIP_UDP_TRANSPORT;
				}
				else {
					if (!rport && !address) {
						address = getsrvadr(domainname, &rport, &tsp);
						if (tsp != 0)
							transport = tsp;
					}
					if (!address) {
						address = getaddress(domainname);
						if (address && verbose > 1)
							printf("using A record: %s\n", domainname);
					}
					if (!address){
						fprintf(stderr, "error:unable to determine the IP address for: %s\n", domainname);
						exit_code(2);
					}
				}
				if (port != 0) {
					backup = str_alloc(strlen(domainname)+1+6);
					snprintf(backup, strlen(domainname)+6, "%s:%i", domainname, port);
					domainname = backup;
				}
				uri_b=1;
				break;
			case 'S':
				fprintf(stderr, "warning: symmetric does not work with a-symmetric servers\n");
				symmetric=1;
				break;
			case 't':
				trashchar=str_to_int(optarg);
				break;
			case 'T':
				trace=1;
				break;
			case 'U':
				usrloc=1;
				break;
			case 'u':
				auth_username=str_alloc(strlen(optarg) + 1);
				strncpy(auth_username, optarg, strlen(optarg));
				break;
			case 'v':
				verbose++;
				break;
			case 'V':
				printf("sipsak %s  by Nils Ohlmeier\n Copyright (C) 2002-2004"
						" FhG Fokus\n Copyright (C) 2004-2005 Nils Ohlmeier\n", 
						SIPSAK_VERSION);
				printf(" compiled with DEFAULT_TIMEOUT=%i, FQDN_SIZE=%i",
						DEFAULT_TIMEOUT, FQDN_SIZE);
#ifdef RAW_SUPPORT
				printf(", RAW_SUPPORT");
#endif
#ifdef HAVE_GETOPT_LONG
				printf(", LONG_OPTS");
#endif
#ifdef HAVE_GNUTLS
				printf(", GNUTLS_MD5");
#else
# ifdef HAVE_FULL_OPENSSL
				printf(", OPENSSL_MD5");
# else
				printf(", INTERNAL_MD5");
# endif
#endif
#ifdef HAVE_OPENSSL_SHA1
				printf(", OPENSSL_SHA1");
#endif
#ifdef HAVE_CARES_H
				printf(", SRV_SUPPORT(ARES)");
#else
# ifdef HAVE_RULI_H
				printf(", SRV_SUPPORT(RULI)");
# endif
#endif
#ifdef HAVE_STRCASESTR
				printf(", STR_CASE_INSENSITIVE");
#endif
#ifdef HAVE_STRNCASECMP
				printf(", CMP_CASE_INSENSITIVE");
#endif
				printf("\n");
				exit_code(0);
				break;
			case 'w':
				warning_ext=1;
				break;
			case 'W':
				nagios_warn = str_to_int(optarg);
				break;
			case 'x':
				expires_t=str_to_int(optarg);
				break;
#ifdef HAVE_GETOPT_LONG
			case 'X':
				print_long_help();
				break;
#endif
			case 'z':
				rand_rem=str_to_int(optarg);
				if (rand_rem < 0 || rand_rem > 100) {
					fprintf(stderr, "error: z option must between 0 and 100\n");
					exit_code(2);
				}
				break;
			default:
				fprintf(stderr, "error: unknown parameter %c\n", c);
				exit_code(2);
				break;
		}
	}

	if (rport == 0) {
		rport =  5060;
	}
	if (rport > 65535 || rport <= 0) {
		fprintf(stderr, "error: invalid remote port: %i\n", rport);
		exit_code(2);
	}
	if (transport == 0) {
		transport = SIP_UDP_TRANSPORT;
	}

	/* replace LF with CRLF if we read from a file */
	if ((file_b) && (fix_crlf)) {
		insert_cr(buff);
	}
	if (headers) {
		backup = str_alloc(strlen(headers) + 30); // FIXME
		strcpy(backup, headers);
		headers = backup;
		replace_string(headers, "\\n", "\r\n");
		backup = headers + strlen(headers) - 1;
		if (*backup != '\n') {
			strcpy(backup + 1, "\r\n");
		}
		if (file_b)
			insert_header(buff, headers, 1);
	}
	/* lots of conditions to check */
	if (trace) {
		if (usrloc || flood || randtrash) {
			fprintf(stderr, "error: trace can't be combined with usrloc, random or "
				"flood\n");
			exit_code(2);
		}
		if (!uri_b) {
			fprintf(stderr, "error: for trace mode a SIPURI is realy needed\n");
			exit_code(2);
		}
		if (file_b) {
			fprintf(stderr, "warning: file will be ignored for tracing.");
		}
		if (!username) {
			fprintf(stderr, "error: for trace mode without a file the SIPURI have to "
				"contain a username\n");
			exit_code(2);
		}
		if (!via_ins){
			fprintf(stderr, "warning: Via-Line is needed for tracing. Ignoring -i\n");
			via_ins=1;
		}
		if (!warning_ext) {
			fprintf(stderr, "warning: IP extract from warning activated to be more "
				"informational\n");
			warning_ext=1;
		}
		if (maxforw==-1) maxforw=255;
	}
	else if (usrloc || invite || message) {
		if (trace || flood || randtrash) {
			fprintf(stderr, "error: usrloc can't be combined with trace, random or "
				"flood\n");
			exit_code(2);
		}
		if (!username || !uri_b) {
			fprintf(stderr, "error: for the USRLOC mode you have to give a SIPURI with "
				"a username\n       at least\n");
			exit_code(2);
		}
		if (namebeg>0 && nameend==-1) {
			fprintf(stderr, "error: if a starting numbers is given also an ending "
				"number have to be specified\n");
			exit_code(2);
		}
		if (invite && message) {
			fprintf(stderr, "error: invite and message tests are XOR\n");
			exit_code(2);
		}
		if (!usrloc && invite && !lport) {
			fprintf(stderr, "warning: Do NOT use the usrloc invite mode without "
				"registering sipsak before.\n         See man page for "
				"details.\n");
			exit_code(2);
		}
		if (contact_uri!=NULL) {
			if (invite || message) {
				fprintf(stderr, "error: Contact uri is not support for invites or "
					"messages\n");
				exit_code(2);
			}
			if (nameend!=-1 || namebeg!=-1) {
				fprintf(stderr, "warning: ignoring starting or ending number if Contact"
					" is given\n");
				nameend=namebeg=0;
			}
			if (rand_rem) {
				fprintf(stderr, "warning: ignoring -z option when Contact is given\n");
				rand_rem=0;
			}
		}
		if (via_ins) {
			fprintf(stderr, "warning: ignoring -i option when in usrloc mode\n");
			via_ins=0;
		}
		if (nameend==-1)
			nameend=0;
		if (namebeg==-1)
			namebeg=0;
	}
	else if (flood) {
		if (trace || usrloc || randtrash) {
			fprintf(stderr, "error: flood can't be combined with trace, random or "
				"usrloc\n");
			exit_code(2);
		}
		if (!uri_b) {
			fprintf(stderr, "error: we need at least a sip uri for flood\n");
			exit_code(2);
		}
		if (redirects) {
			fprintf(stderr, "warning: redirects are not expected in flood. "
				"disableing\n");
			redirects=0;
		}
	}
	else if (randtrash) {
		if (trace || usrloc || flood) {
			fprintf(stderr, "error: random can't be combined with trace, flood or "
				"usrloc\n");
			exit_code(2);
		}
		if (!uri_b) {
			fprintf(stderr, "error: need at least a sip uri for random\n");
			exit_code(2);
		}
		if (redirects) {
			fprintf(stderr, "warning: redirects are not expected in random. "
				"disableing\n");
			redirects=0;
		}
		if (verbose) {
			fprintf(stderr, "warning: random characters may destroy your terminal "
				"output\n");
		}
	}
	else if (mes_body) {
		if (!message) {
			fprintf(stderr, "warning: to send a message mode (-M) is required. activating\n");
			message=1;
		}
		if (!uri_b) {
			fprintf(stderr, "error: need at least a sip uri to send a meesage\n");
			exit_code(2);
		}
		if (nameend==-1)
			nameend=0;
		if (namebeg==-1)
			namebeg=0;
	}
	else {
		if (!uri_b) {
			fprintf(stderr, "error: a spi uri is needed at least\n");
			exit_code(2);
		}
	}

	switch (transport) {
		case SIP_TLS_TRANSPORT:
			transport_str = TRANSPORT_TLS_STR;
			break;
		case SIP_TCP_TRANSPORT:
			transport_str = TRANSPORT_TCP_STR;
			break;
		case SIP_UDP_TRANSPORT:
			transport_str = TRANSPORT_UDP_STR;
			break;
		default:
			fprintf(stderr, "unknown transport: %i\n", transport);
			exit_code(2);
	}

	/* determine our hostname */
	get_fqdn();
	
	/* this is not a cryptographic random number generator,
	   but hey this is only a test-tool => should be satisfying*/
	srand(time(0) ^ getpid());
	
	if (processes > 1) {
		if (signal(SIGCHLD , sigchld_handler)  == SIG_ERR ) {
			fprintf(stderr, "error: Could not install SIGCHLD handler\n");
			exit_code(2);
		}
	}

	for(i = 0; i < processes - 1; i++) {
		if ((pid = fork()) < 0) {
			fprintf(stderr, "error: Cannot fork\n");
			exit_code(2);
		}
		
		if (pid == 0){
	    	/* child */
			upp = (nameend - namebeg + 1) / processes;
			namebeg = namebeg + upp * i;
			nameend = namebeg + upp;
			shoot(&buff[0], sizeof(buff));
		} else {
			if (lport) {
				lport++;
			}
		}
		
		/* Delay execution of children so that the
		 * time of the first transmission gets spread over
		 * the retransmission interval evenly
		 */
		ts.tv_sec = 0;
		ts.tv_nsec = (float)DEFAULT_TIMEOUT / (float)processes * (float)1000 * (float)1000;
		nanosleep(&ts, 0);
	}

	/* here we go...*/
	if (processes > 1) {
		upp = (nameend - namebeg + 1) / processes;
		namebeg = namebeg + upp * i;
		nameend = namebeg + upp;
	}
	shoot(&buff[0], sizeof(buff));

	/* normaly we won't come back here, but to satisfy the compiler */
	return 0;
}
Ejemplo n.º 14
0
int main(int argc, char *argv[])
{
	char *msg;
	int seq;
	int argi;
	int alertcolors, alertinterval;
	char *configfn = NULL;
	char *checkfn = NULL;
	int checkpointinterval = 900;
	char acklogfn[PATH_MAX];
	FILE *acklogfd = NULL;
	char notiflogfn[PATH_MAX];
	FILE *notiflogfd = NULL;
	char *tracefn = NULL;
	struct sigaction sa;
	int configchanged;
	time_t lastxmit = 0;

	MEMDEFINE(acklogfn);
	MEMDEFINE(notiflogfn);

	libxymon_init(argv[0]);

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

	/* Load alert config */
	alertcolors = colorset(xgetenv("ALERTCOLORS"), ((1 << COL_GREEN) | (1 << COL_BLUE)));
	alertinterval = 60*atoi(xgetenv("ALERTREPEAT"));

	/* Create our loookup-trees */
	hostnames = xtreeNew(strcasecmp);
	testnames = xtreeNew(strcasecmp);
	locations = xtreeNew(strcasecmp);

	for (argi=1; (argi < argc); argi++) {
		if (argnmatch(argv[argi], "--config=")) {
			configfn = strdup(strchr(argv[argi], '=')+1);
		}
		else if (argnmatch(argv[argi], "--checkpoint-file=")) {
			checkfn = strdup(strchr(argv[argi], '=')+1);
		}
		else if (argnmatch(argv[argi], "--checkpoint-interval=")) {
			char *p = strchr(argv[argi], '=') + 1;
			checkpointinterval = atoi(p);
		}
		else if (argnmatch(argv[argi], "--dump-config")) {
			load_alertconfig(configfn, alertcolors, alertinterval);
			dump_alertconfig(1);
			return 0;
		}
		else if (argnmatch(argv[argi], "--cfid")) {
			include_configid = 1;
		}
		else if (argnmatch(argv[argi], "--test")) {
			char *testhost = NULL, *testservice = NULL, *testpage = NULL, 
			     *testcolor = "red", *testgroups = NULL;
			void *hinfo;
			int testdur = 0;
			FILE *logfd = NULL;
			activealerts_t *awalk = NULL;
			int paramno = 0;

			argi++; if (argi < argc) testhost = argv[argi];
			argi++; if (argi < argc) testservice = argv[argi];
			argi++; 
			while (argi < argc) {
				if (strncasecmp(argv[argi], "--duration=", 11) == 0) {
					testdur = durationvalue(strchr(argv[argi], '=')+1);
				}
				else if (strncasecmp(argv[argi], "--color=", 8) == 0) {
					testcolor = strchr(argv[argi], '=')+1;
				}
				else if (strncasecmp(argv[argi], "--group=", 8) == 0) {
					testgroups = strchr(argv[argi], '=')+1;
				}
				else if (strncasecmp(argv[argi], "--time=", 7) == 0) {
					fakestarttime = (time_t)atoi(strchr(argv[argi], '=')+1);
				}
				else {
					paramno++;
					if (paramno == 1) testdur = atoi(argv[argi]);
					else if (paramno == 2) testcolor = argv[argi];
					else if (paramno == 3) fakestarttime = (time_t) atoi(argv[argi]);
				}

				argi++;
			}

			if ((testhost == NULL) || (testservice == NULL)) {
				printf("Usage: xymond_alert --test HOST SERVICE [options]\n");
				printf("Possible options:\n\t[--duration=MINUTES]\n\t[--color=COLOR]\n\t[--group=GROUPNAME]\n\t[--time=TIMESPEC]\n");

				return 1;
			}

			load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
			hinfo = hostinfo(testhost);
			if (hinfo) {
				testpage = strdup(xmh_item(hinfo, XMH_ALLPAGEPATHS));
			}
			else {
				errprintf("Host not found in hosts.cfg - assuming it is on the top page\n");
				testpage = "";
			}

			awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t));
			awalk->hostname = find_name(hostnames, testhost);
			awalk->testname = find_name(testnames, testservice);
			awalk->location = find_name(locations, testpage);
			awalk->ip = strdup("127.0.0.1");
			awalk->color = awalk->maxcolor = parse_color(testcolor);
			awalk->pagemessage = "Test of the alert configuration";
			awalk->eventstart = getcurrenttime(NULL) - testdur*60;
			awalk->groups = (testgroups ? strdup(testgroups) : NULL);
			awalk->state = A_PAGING;
			awalk->cookie = 12345;
			awalk->next = NULL;

			logfd = fopen("/dev/null", "w");
			starttrace(NULL);
			testonly = 1;

			load_alertconfig(configfn, alertcolors, alertinterval);
			load_holidays(0);
			send_alert(awalk, logfd);
			return 0;
		}
		else if (argnmatch(argv[argi], "--trace=")) {
			tracefn = strdup(strchr(argv[argi], '=')+1);
			starttrace(tracefn);
		}
		else if (net_worker_option(argv[argi])) {
			/* Handled in the subroutine */
		}
		else if (standardoption(argv[argi])) {
			if (showhelp) return 0;
		}
		else {
			errprintf("Unknown option '%s'\n", argv[argi]);
		}
	}

	/* Do the network stuff if needed */
	net_worker_run(ST_ALERT, LOC_SINGLESERVER, NULL);

	if (checkfn) {
		load_checkpoint(checkfn);
		nextcheckpoint = gettimer() + checkpointinterval;
		dbgprintf("Next checkpoint at %d, interval %d\n", (int) nextcheckpoint, checkpointinterval);
	}

	setup_signalhandler("xymond_alert");
	/* Need to handle these ourselves, so we can shutdown and save state-info */
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sig_handler;
	sigaction(SIGPIPE, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGINT,  &sa, NULL);
	sigaction(SIGCHLD, &sa, NULL);
	sigaction(SIGUSR1, &sa, NULL);
	sigaction(SIGHUP,  &sa, NULL);

	if (xgetenv("XYMONSERVERLOGS")) {
		sprintf(acklogfn, "%s/acknowledge.log", xgetenv("XYMONSERVERLOGS"));
		acklogfd = fopen(acklogfn, "a");
		sprintf(notiflogfn, "%s/notifications.log", xgetenv("XYMONSERVERLOGS"));
		notiflogfd = fopen(notiflogfn, "a");
	}

	/*
	 * The general idea here is that this loop handles receiving of alert-
	 * and ack-messages from the master daemon, and maintains a list of 
	 * host+test combinations that may have alerts going out.
	 *
	 * This module does not deal with any specific alert-configuration, 
	 * it just picks up the alert messages, maintains the list of 
	 * known tests that are in some sort of critical condition, and
	 * periodically pushes alerts to the do_alert.c module for handling.
	 *
	 * The only modification of alerts that happen here is the handling
	 * of when the next alert is due. It calls into the next_alert() 
	 * routine to learn when an alert should be repeated, and also 
	 * deals with Acknowledgments that stop alerts from going out for
	 * a period of time.
	 */
	while (running) {
		char *eoln, *restofmsg;
		char *metadata[20];
		char *p;
		int metacount;
		char *hostname = NULL, *testname = NULL;
		struct timespec timeout;
		time_t now, nowtimer;
		int anytogo;
		activealerts_t *awalk;
		int childstat;

		nowtimer = gettimer();
		if (checkfn && (nowtimer > nextcheckpoint)) {
			dbgprintf("Saving checkpoint\n");
			nextcheckpoint = nowtimer + checkpointinterval;
			save_checkpoint(checkfn);

			if (acklogfd) acklogfd = freopen(acklogfn, "a", acklogfd);
			if (notiflogfd) notiflogfd = freopen(notiflogfn, "a", notiflogfd);
		}

		timeout.tv_sec = 60; timeout.tv_nsec = 0;
		msg = get_xymond_message(C_PAGE, "xymond_alert", &seq, &timeout);
		if (msg == NULL) {
			running = 0;
			continue;
		}

		/* See what time it is - must happen AFTER the timeout */
		now = getcurrenttime(NULL);

		/* Split the message in the first line (with meta-data), and the rest */
 		eoln = strchr(msg, '\n');
		if (eoln) {
			*eoln = '\0';
			restofmsg = eoln+1;
		}
		else {
			restofmsg = "";
		}

		/* 
		 * Now parse the meta-data into elements.
		 * We use our own "gettok()" routine which works
		 * like strtok(), but can handle empty elements.
		 */
		metacount = 0; 
		memset(&metadata, 0, sizeof(metadata));
		p = gettok(msg, "|");
		while (p && (metacount < 19)) {
			metadata[metacount] = p;
			metacount++;
			p = gettok(NULL, "|");
		}
		metadata[metacount] = NULL;

		if (metacount > 3) hostname = metadata[3];
		if (metacount > 4) testname = metadata[4];

		if ((metacount > 10) && (strncmp(metadata[0], "@@page", 6) == 0)) {
			/* @@page|timestamp|sender|hostname|testname|hostip|expiretime|color|prevcolor|changetime|location|cookie|osname|classname|grouplist|modifiers */

			int newcolor, newalertstatus, oldalertstatus;

			dbgprintf("Got page message from %s:%s\n", hostname, testname);
			traceprintf("@@page %s:%s:%s=%s\n", hostname, testname, metadata[10], metadata[7]);

			awalk = find_active(hostname, testname);
			if (awalk == NULL) {
				char *hwalk = find_name(hostnames, hostname);
				char *twalk = find_name(testnames, testname);
				char *pwalk = find_name(locations, metadata[10]);

				awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t));
				awalk->hostname = hwalk;
				awalk->testname = twalk;
				awalk->location = pwalk;
				awalk->cookie = -1;
				awalk->state = A_DEAD;
				/*
				 * Use changetime here, if we restart the alert module then
				 * this gets the duration values more right than using "now".
				 * Also, define this only when a new alert arrives - we should
				 * NOT clear this when a status goes yellow->red, or if it
				 * flaps between yellow and red.
				 */
				awalk->eventstart = atoi(metadata[9]);
				add_active(awalk->hostname, awalk);
				traceprintf("New record\n");
			}

			newcolor = parse_color(metadata[7]);
			oldalertstatus = ((alertcolors & (1 << awalk->color)) != 0);
			newalertstatus = ((alertcolors & (1 << newcolor)) != 0);

			traceprintf("state %d->%d\n", oldalertstatus, newalertstatus);

			if (newalertstatus) {
				/* It's in an alert state. */
				awalk->color = newcolor;
				awalk->state = A_PAGING;

				if (newcolor > awalk->maxcolor) {
					if (awalk->maxcolor != 0) {
						/*
						 * Severity has increased (yellow -> red).
						 * Clear the repeat-interval, and set maxcolor to
						 * the new color. If it drops to yellow again,
						 * maxcolor stays at red, so a test that flaps
						 * between yellow and red will only alert on red
						 * the first time, and then follow the repeat
						 * interval.
						 */
						dbgprintf("Severity increased, cleared repeat interval: %s/%s %s->%s\n",
							awalk->hostname, awalk->testname,
							colorname(awalk->maxcolor), colorname(newcolor));
						clear_interval(awalk);
					}

					awalk->maxcolor = newcolor;
				}
			}
			else {
				/* 
				 * Send one "recovered" message out now, then go to A_DEAD.
				 * Dont update the color here - we want recoveries to go out 
				 * only if the alert color triggered an alert
				 */
				awalk->state = (newcolor == COL_BLUE) ? A_DISABLED : A_RECOVERED;
			}

			if (oldalertstatus != newalertstatus) {
				dbgprintf("Alert status changed from %d to %d\n", oldalertstatus, newalertstatus);
				clear_interval(awalk);
			}

			if (awalk->ip) xfree(awalk->ip);
			awalk->ip = strdup(metadata[5]);
			awalk->cookie = atoi(metadata[11]);
			if (awalk->osname) xfree(awalk->osname);
			awalk->osname    = (metadata[12] ? strdup(metadata[12]) : NULL);
			if (awalk->classname) xfree(awalk->classname);
			awalk->classname = (metadata[13] ? strdup(metadata[13]) : NULL);
			if (awalk->groups) xfree(awalk->groups);
			awalk->groups    = (metadata[14] ? strdup(metadata[14]) : NULL);
			if (awalk->pagemessage) xfree(awalk->pagemessage);
			if (metadata[15]) {
				/* Modifiers are more interesting than the message itself */
				awalk->pagemessage = (char *)malloc(strlen(awalk->hostname) + strlen(awalk->testname) + strlen(colorname(awalk->color)) + strlen(metadata[15]) + strlen(restofmsg) + 10);
				sprintf(awalk->pagemessage, "%s:%s %s\n%s\n%s",
					awalk->hostname, awalk->testname, colorname(awalk->color), metadata[15], restofmsg);
			}
			else {
				awalk->pagemessage = strdup(restofmsg);
			}
		}
		else if ((metacount > 5) && (strncmp(metadata[0], "@@ack", 5) == 0)) {
 			/* @@ack|timestamp|sender|hostname|testname|hostip|expiretime */

			/*
			 * An ack is handled simply by setting the next
			 * alert-time to when the ack expires.
			 */
			time_t nextalert = atoi(metadata[6]);

			dbgprintf("Got ack message from %s:%s\n", hostname, testname);
			traceprintf("@@ack: %s:%s now=%d, ackeduntil %d\n",
				     hostname, testname, (int)now, (int)nextalert);

			awalk = find_active(hostname, testname);

			if (acklogfd) {
				int cookie = (awalk ? awalk->cookie : -1);
				int color  = (awalk ? awalk->color : 0);

				fprintf(acklogfd, "%d\t%d\t%d\t%d\t%s\t%s.%s\t%s\t%s\n",
					(int)now, cookie, 
					(int)((nextalert - now) / 60), cookie,
					"np_filename_not_used", 
					hostname, testname, 
					colorname(color),
					nlencode(restofmsg));
				fflush(acklogfd);
			}

			if (awalk && (awalk->state == A_PAGING)) {
				traceprintf("Record updated\n");
				awalk->state = A_ACKED;
				awalk->nextalerttime = nextalert;
				if (awalk->ackmessage) xfree(awalk->ackmessage);
				awalk->ackmessage = strdup(restofmsg);
			}
			else {
				traceprintf("No record\n");
			}
		}
		else if ((metacount > 4) && (strncmp(metadata[0], "@@notify", 5) == 0)) {
			/* @@notify|timestamp|sender|hostname|testname|pagepath */

			char *hwalk = find_name(hostnames, hostname);
			char *twalk = find_name(testnames, testname);
			char *pwalk = find_name(locations, (metadata[5] ? metadata[5] : ""));

			awalk = (activealerts_t *)calloc(1, sizeof(activealerts_t));
			awalk->hostname = hwalk;
			awalk->testname = twalk;
			awalk->location = pwalk;
			awalk->cookie = -1;
			awalk->pagemessage = strdup(restofmsg);
			awalk->eventstart = getcurrenttime(NULL);
			awalk->state = A_NOTIFY;
			add_active(awalk->hostname, awalk);
		}
		else if ((metacount > 3) && 
			 ((strncmp(metadata[0], "@@drophost", 10) == 0) || (strncmp(metadata[0], "@@dropstate", 11) == 0))) {
			/* @@drophost|timestamp|sender|hostname */
			/* @@dropstate|timestamp|sender|hostname */
			xtreePos_t handle;

			handle = xtreeFind(hostnames, hostname);
			if (handle != xtreeEnd(hostnames)) {
				alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, handle);
				for (awalk = anchor->head; (awalk); awalk = awalk->next) awalk->state = A_DEAD;
			}
		}
		else if ((metacount > 4) && (strncmp(metadata[0], "@@droptest", 10) == 0)) {
			/* @@droptest|timestamp|sender|hostname|testname */

			awalk = find_active(hostname, testname);
			if (awalk) awalk->state = A_DEAD;
		}
		else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) {
			/* @@renamehost|timestamp|sender|hostname|newhostname */

			/* 
			 * We handle rename's simply by dropping the alert. If there is still an
			 * active alert for the host, it will have to be dealt with when the next
			 * status update arrives.
			 */
			xtreePos_t handle;

			handle = xtreeFind(hostnames, hostname);
			if (handle != xtreeEnd(hostnames)) {
				alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, handle);
				for (awalk = anchor->head; (awalk); awalk = awalk->next) awalk->state = A_DEAD;
			}
		}
		else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) {
			/* @@renametest|timestamp|sender|hostname|oldtestname|newtestname */

			/* 
			 * We handle rename's simply by dropping the alert. If there is still an
			 * active alert for the host, it will have to be dealt with when the next
			 * status update arrives.
			 */
			awalk = find_active(hostname, testname);
			if (awalk) awalk->state = A_DEAD;
		}
		else if (strncmp(metadata[0], "@@shutdown", 10) == 0) {
			running = 0;
			errprintf("Got a shutdown message\n");
			continue;
		}
		else if (strncmp(metadata[0], "@@logrotate", 11) == 0) {
			char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME");
			if (fn && strlen(fn)) {
				reopen_file(fn, "a", stdout);
				reopen_file(fn, "a", stderr);

				if (tracefn) {
					stoptrace();
					starttrace(tracefn);
				}
			}
			continue;
		}
		else if (strncmp(metadata[0], "@@reload", 8) == 0) {
			/* Nothing ... right now */
		}
		else if (strncmp(metadata[0], "@@idle", 6) == 0) {
			/* Timeout */
		}

		/*
		 * When a burst of alerts happen, we get lots of alert messages
		 * coming in quickly. So lets handle them in bunches and only 
		 * do the full alert handling once every 10 secs - that lets us
		 * combine a bunch of alerts into one transmission process.
		 */
		if (nowtimer < (lastxmit+10)) continue;
		lastxmit = nowtimer;

		/* 
		 * Loop through the activealerts list and see if anything is pending.
		 * This is an optimization, we could just as well just fork off the
		 * notification child and let it handle all of it. But there is no
		 * reason to fork a child process unless it is going to do something.
		 */
		configchanged = load_alertconfig(configfn, alertcolors, alertinterval);
		configchanged += load_holidays(0);
		anytogo = 0;
		for (awalk = alistBegin(); (awalk); awalk = alistNext()) {
			int anymatch = 0;

			switch (awalk->state) {
			  case A_NORECIP:
				if (!configchanged) break;

				/* The configuration has changed - switch NORECIP -> PAGING */
				awalk->state = A_PAGING;
				clear_interval(awalk);
				/* Fall through */

			  case A_PAGING:
				if (have_recipient(awalk, &anymatch)) {
					if (awalk->nextalerttime <= now) anytogo++;
				}
				else {
					if (!anymatch) {
						awalk->state = A_NORECIP;
						cleanup_alert(awalk);
					}
				}
				break;

			  case A_ACKED:
				if (awalk->nextalerttime <= now) {
					/* An ack has expired, so drop the ack message and switch to A_PAGING */
					anytogo++;
					if (awalk->ackmessage) xfree(awalk->ackmessage);
					awalk->state = A_PAGING;
				}
				break;

			  case A_RECOVERED:
			  case A_DISABLED:
			  case A_NOTIFY:
				anytogo++;
				break;

			  case A_DEAD:
				break;
			}
		}
		dbgprintf("%d alerts to go\n", anytogo);

		if (anytogo) {
			pid_t childpid;

			childpid = fork();
			if (childpid == 0) {
				/* The child */
				start_alerts();
				for (awalk = alistBegin(); (awalk); awalk = alistNext()) {
					switch (awalk->state) {
					  case A_PAGING:
						if (awalk->nextalerttime <= now) {
							send_alert(awalk, notiflogfd);
						}
						break;

					  case A_ACKED:
						/* Cannot be A_ACKED unless the ack is still valid, so no alert. */
						break;

					  case A_RECOVERED:
					  case A_DISABLED:
					  case A_NOTIFY:
						send_alert(awalk, notiflogfd);
						break;

					  case A_NORECIP:
					  case A_DEAD:
						break;
					}
				}
				finish_alerts();

				/* Child does not continue */
				exit(0);
			}
			else if (childpid < 0) {
				errprintf("Fork failed, cannot send alerts: %s\n", strerror(errno));
			}
		}

		/* Update the state flag and the next-alert timestamp */
		for (awalk = alistBegin(); (awalk); awalk = alistNext()) {
			switch (awalk->state) {
			  case A_PAGING:
				if (awalk->nextalerttime <= now) awalk->nextalerttime = next_alert(awalk);
				break;

			  case A_NORECIP:
				break;

			  case A_ACKED:
				/* Still cannot get here except if ack is still valid */
				break;

			  case A_RECOVERED:
			  case A_DISABLED:
			  case A_NOTIFY:
				awalk->state = A_DEAD;
				/* Fall through */

			  case A_DEAD:
				cleanup_alert(awalk); 
				break;
			}
		}

		clean_all_active();

		/* Pickup any finished child processes to avoid zombies */
		while (wait3(&childstat, WNOHANG, NULL) > 0) ;
	}

	if (checkfn) save_checkpoint(checkfn);
	if (acklogfd) fclose(acklogfd);
	if (notiflogfd) fclose(notiflogfd);
	stoptrace();

	MEMUNDEFINE(notiflogfn);
	MEMUNDEFINE(acklogfn);

	if (termsig >= 0) {
		errprintf("Terminated by signal %d\n", termsig);
	}

	return 0;
}
Ejemplo n.º 15
0
int main(int argc, char *argv[])
{
	void *hostwalk, *clonewalk;
	int argi;
	char *envarea = NULL;

	strbuffer_t *outbuf;
	char msgline[4096];
	char oneurl[10240];
	int gotany = 0;
	enum { OP_INITIAL, OP_YES, OP_NO } gotonepage = OP_INITIAL; /* Tracks if all matches are on one page */
	char *onepage = NULL;	/* If gotonepage==OP_YES, then this is the page */

	/*[wm] regex support */
	#define BUFSIZE		256
	regex_t re;
	char    re_errstr[BUFSIZE];
	int 	re_status;

	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);
		}
	}

	redirect_cgilog("findhost");

	cgidata = cgi_request();
	if (cgidata == NULL) {
		/* Present the query form */
		sethostenv("", "", "", colorname(COL_BLUE), NULL);
		printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
		showform(stdout, "findhost", "findhost_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL);
		return 0;
	}

	parse_query();

	if ( (re_status = regcomp(&re, pSearchPat, re_flag)) != 0 ) {
		regerror(re_status, &re, re_errstr, BUFSIZE);

		print_header();
		printf("<tr><td align=left><font color=red>%s</font></td>\n",  pSearchPat);
		printf("<td align=left><font color=red>%s</font></td></tr>\n", re_errstr);
		print_footer();

		return 0;
	}

	outbuf = newstrbuffer(0);
	load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
	hostwalk = first_host();
	while (hostwalk) {
		/* 
		 * [wm] - Allow the search to be done on the hostname
		 * 	also on the "displayname" and the host comment
		 *	Maybe this should be implemented by changing the HTML form, but until than..
		 * we're supposing that hostname will NEVER be null	
		 */
		char *hostname, *displayname, *comment, *ip;

		hostname = xmh_item(hostwalk, XMH_HOSTNAME);
		displayname = xmh_item(hostwalk, XMH_DISPLAYNAME);
		comment = xmh_item(hostwalk, XMH_COMMENT);
		ip = xmh_item(hostwalk, XMH_IP);

       		if ( regexec (&re, hostname, (size_t)0, NULL, 0) == 0  ||
			(regexec(&re, ip, (size_t)0, NULL, 0) == 0)    ||
       			(displayname && regexec (&re, displayname, (size_t)0, NULL, 0) == 0) ||
			(comment     && regexec (&re, comment, 	   (size_t)0, NULL, 0) == 0)   ) {
	
			/*  match */
			addtobuffer(outbuf, "<tr>\n");
			sprintf(msgline, "<td align=left> %s </td>\n", displayname ? displayname : hostname);
			addtobuffer(outbuf, msgline);
			sprintf(oneurl, "%s/%s/#%s",
				xgetenv("XYMONWEB"), xmh_item(hostwalk, XMH_PAGEPATH), hostname);
			sprintf(msgline, "<td align=left> <a href=\"%s\">%s</a>\n",
				oneurl, xmh_item(hostwalk, XMH_PAGEPATHTITLE));
			addtobuffer(outbuf, msgline);
			gotany++;

			/* See if all of the matches so far are on one page */
			switch (gotonepage) {
			  case OP_INITIAL:
				gotonepage = OP_YES;
				onepage = xmh_item(hostwalk, XMH_PAGEPATH);
				break;

			  case OP_YES:
				if (strcmp(onepage, xmh_item(hostwalk, XMH_PAGEPATH)) != 0) gotonepage = OP_NO;
				break;

			  case OP_NO:
				break;
			}

			clonewalk = next_host(hostwalk, 1);
			while (clonewalk && (strcmp(xmh_item(hostwalk, XMH_HOSTNAME), xmh_item(clonewalk, XMH_HOSTNAME)) == 0)) {
				sprintf(msgline, "<br><a href=\"%s/%s/#%s\">%s</a>\n",
					xgetenv("XYMONWEB"), 
					xmh_item(clonewalk, XMH_PAGEPATH),
					xmh_item(clonewalk, XMH_HOSTNAME),
					xmh_item(clonewalk, XMH_PAGEPATHTITLE));
				addtobuffer(outbuf, msgline);
				clonewalk = next_host(clonewalk, 1);
				gotany++;
			}

			addtobuffer(outbuf, "</td>\n</tr>\n");
	
			hostwalk = clonewalk;
		}
		else {
			hostwalk = next_host(hostwalk, 0);
		}
	}
	regfree (&re); 	/*[wm] - free regex compiled patern */
	
	if (dojump) {
		if (gotany == 1) {
			printf("Location: %s%s\n\n", xgetenv("XYMONWEBHOST"), oneurl);
			return 0;
		}
		else if ((gotany > 1) && (gotonepage == OP_YES)) {
			printf("Location: %s%s/%s/\n\n", 
			       xgetenv("XYMONWEBHOST"), xgetenv("XYMONWEB"), onepage);
			return 0;
		}
	}

	print_header();
	if (!gotany) {
		printf("<tr><td align=left>%s</td><td align=left>Not found</td></tr>\n", pSearchPat);
	}
	else {
		printf("%s", grabstrbuffer(outbuf));
	}
	print_footer();

	/* [wm] - Free the strdup allocated memory */
	if (pSearchPat) xfree(pSearchPat);

	return 0;
}
Ejemplo n.º 16
0
int main(int argc, char *argv[])
{
	FILE	*pf;
	char	buff[BUFSIZE];
	int	length, c, i, j;
	char	*delim, *delim2;
	pid_t 	pid;
	struct timespec ts;
	int 	upp;

#ifdef HAVE_GETOPT_LONG
	int option_index = 0;
	static struct option l_opts[] = {
		{"help", 0, 0, 'X'},
		{"version", 0, 0, 'V'},
		{"filename", 1, 0, 'f'},
		{"sip-uri", 1, 0, 's'},
		{"traceroute-mode", 0, 0, 'T'},
		{"usrloc-mode", 0, 0, 'U'},
		{"invite-mode", 0, 0, 'I'},
		{"message-mode", 0, 0, 'M'},
		{"contact", 1, 0, 'C'},
		{"appendix-begin", 1, 0, 'b'},
		{"appendix-end", 1, 0, 'e'},
		{"sleep", 1, 0, 'o'},
		{"expires", 1, 0, 'x'},
		{"remove-bindings", 0, 0, 'z'},
		{"flood-mode", 0, 0, 'F'},
		{"cseq-max", 1, 0, 'c'},
		{"random-mode", 0, 0, 'R'},
		{"trash-chars", 1, 0, 't'},
		{"local-port", 1, 0, 'l'},
		{"remote-port", 1, 0, 'r'},
		{"outbound-proxy", 1, 0, 'p'},
		{"hostname", 1, 0, 'H'},
		{"max-fowards", 1, 0, 'm'},
		{"numeric", 0, 0, 'n'},
		{"no-via", 0, 0, 'i'},
		{"password", 1, 0, 'a'},
		{"ignore-redirects", 0, 0, 'd'},
		{"verbose", 0, 0, 'v'},
		{"extract-ip", 0, 0, 'w'},
		{"replace-string", 0, 0, 'g'},
		{"replace", 0, 0, 'G'},
		{"nagios-code", 0, 0, 'N'},
		{"nagios-warn", 1, 0, 'W'},
		{"search", 1, 0, 'q'},
		{"message-body", 1, 0, 'B'},
		{"disposition", 1, 0, 'O'},
		{"processes", 1, 0, 'P'},
		{"auth-username", 1, 0, 'u'},
		{"no-crlf", 0, 0, 'L'},
		{"timing", 0, 0, 'A'},
		{0, 0, 0, 0}
	};
#endif
	/* some initialisation to be shure */
	file_b=uri_b=trace=lport=usrloc=flood=verbose=randtrash=trashchar = 0;
	warning_ext=rand_rem=nonce_count=replace_b=invite=message = 0;
	sleep_ms=empty_contact=nagios_warn=timing = 0;
	namebeg=nameend=maxforw= -1;
	numeric=via_ins=redirects=fix_crlf=processes  = 1;
	username=password=replace_str=hostname=contact_uri=mes_body = NULL;
	con_dis=auth_username = NULL;
	re = NULL;
	address = 0;
	rport = 5060;
	expires_t = USRLOC_EXP_DEF;
	memset(buff, 0, BUFSIZE);
	memset(confirm, 0, BUFSIZE);
	memset(ack, 0, BUFSIZE);
	memset(fqdn, 0, FQDN_SIZE);
	memset(messusern, 0, FQDN_SIZE);

	if (argc==1) print_help();

	/* lots of command line switches to handle*/
#ifdef HAVE_GETOPT_LONG
	while ((c=getopt_long(argc, argv, "a:AB:b:c:C:de:f:Fg:GhH:iIl:Lm:MnNo:O:p:P:q:r:Rs:t:Tu:UvVwW:x:z", l_opts, &option_index)) != EOF){
#else
	while ((c=getopt(argc,argv,"a:AB:b:c:C:de:f:Fg:GhH:iIl:Lm:MnNo:O:p:P:q:r:Rs:t:Tu:UvVwW:x:z")) != EOF){
#endif
		switch(c){
			case 'a':
				password=malloc(strlen(optarg));
				strncpy(password, optarg, strlen(optarg));
				*(password+strlen(optarg)) = '\0';
				break;
			case 'A':
				timing=1;
				break;
			case 'b':
				if ((namebeg=atoi(optarg))==-1) {
					printf("error: non-numerical appendix begin for the "
						"username\n");
					exit_code(2);
				}
				break;
			case 'B':
				mes_body=malloc(strlen(optarg));
				strncpy(mes_body, optarg, strlen(optarg));
				*(mes_body+strlen(optarg)) = '\0';
				break;
			case 'C':
				if (!strncmp(optarg, "empty", 5) || !strncmp(optarg, "none", 4)) {
					empty_contact = 1;
				}
				else if (((delim=STRSTR(optarg,"sip:"))!=NULL) ||
					((delim=STRSTR(optarg,"sips:"))!=NULL)) {
			 		if (strchr(optarg,'@')<delim) {
						printf("error: missing '@' in Contact uri\n");
						exit_code(2);
					}
					else {
						contact_uri=malloc(strlen(optarg)+1);
						memset(contact_uri, 0, strlen(optarg)+1);
						strncpy(contact_uri, optarg, strlen(optarg));
					}
				}
				else if ((strlen(optarg)==1) && (!strncmp(optarg, "*", 1))) {
					contact_uri=malloc(strlen(optarg)+1);
					memset(contact_uri, 0, strlen(optarg)+1);
					strncpy(contact_uri, optarg, strlen(optarg));
				}
				else{
				    printf("error: REGISTER Contact uri doesn't not contain "
					   "sip:, *, or is not empty\n");
				    exit_code(2);
				}
				break;
			case 'c':
				if ((namebeg=atoi(optarg))==-1) {
					printf("error: non-numerical CSeq maximum\n");
					exit_code(2);
				}
				break;
			case 'd':
				redirects=0;
				break;
			case 'e':
				if ((nameend=atoi(optarg))==-1) {
					printf("error: non-numerical appendix end for the "
						"username\n");
					exit_code(2);
				}
				break;
			case 'F':
				flood=1;
				break;
			case 'f':
				if (strncmp(optarg, "-", 1)) {
					/* file is opened in binary mode so that the cr-lf is 
					   preserved */
					pf = fopen(optarg, "rb");
					if (!pf){
						printf("error: unable to open the file '%s'.\n", optarg);
						exit_code(2);
					}
					length  = fread(buff, 1, sizeof(buff), pf);
					if (length >= sizeof(buff)){
						printf("error:the file is too big. try files of less "
							"than %i bytes.\n", BUFSIZE);
						printf("      or recompile the program with bigger "
							"BUFSIZE defined.\n");
						exit_code(2);
					}
					fclose(pf);
				}
				else {
					for(i = 0; i < BUFSIZE - 1; i++) {
						j = getchar();
						if (j == EOF)
							break;
						else
							buff[i] = j;
					}
					length = i;
				}
				buff[length] = '\0';
				file_b=1;
				break;
			case 'g':
				replace_str=optarg;
				break;
			case 'G':
				replace_b=1;
				break;
			case 'h':
				print_help();
				break;
			case 'H':
				hostname=optarg;
				break;
			case 'i':
				via_ins=0;
				break;
			case 'I':
				invite=1;
				break;
			case 'l':
				lport=atoi(optarg);
				if (!lport) {
					printf("error: non-numerical local port number");
					exit_code(2);
				}
				break;
			case 'L':
				fix_crlf=0;
				break;
			case 'm':
				maxforw=atoi(optarg);
				if (maxforw==-1) {
					printf("error: non-numerical number of max-forwards\n");
					exit_code(2);
				}
				break;
			case 'M':
				message=1;
				break;
			case 'n':
				numeric = 0;
				break;
			case 'N':
				exit_mode=EM_NAGIOS;
				break;
			case 'o':
				sleep_ms = 0;
				if (strncmp(optarg, "rand", 4)==0) {
					sleep_ms = -2;
				}
				else {
					sleep_ms = atoi(optarg);
					if (!sleep_ms) {
						printf("error: non-numerical sleep value\n");
						exit_code(2);
					}
				}
				break;
			case 'O':
				con_dis=malloc(strlen(optarg));
				strncpy(con_dis, optarg, strlen(optarg));
				*(con_dis+strlen(optarg)) = '\0';
				break;
			case 'p':
				address = getaddress(optarg);
				break;
		        case 'P':
				processes=atoi(optarg);
				if (!processes) {
					printf("error: non-numerical number of processes\n");
					exit_code(2);
				}
				break;
			case 'q':
				if (re) {
					/* previously allocated -- free */
					regfree(re);
				} else {
					/* never tried -- allocate */
					re=malloc(sizeof(regex_t));
				};
				if (!re) {
					fprintf(stderr, "Error: can't allocate RE\n");
					exit_code(2);
				};
				if (regcomp(re, optarg, REG_EXTENDED|REG_ICASE|REG_NEWLINE )!=0) {
					fprintf(stderr, "Error: compiling RE: %s\n", optarg );
					exit_code(2);
				};
				break;
			case 'r':
				rport=atoi(optarg);
				if (!rport) {
					printf("error: non-numerical remote port number\n");
					exit_code(2);
				}
				break;
			case 'R':
				randtrash=1;
				break;
			case 's':
				/* we try to extract as much informationas we can from the uri*/
				if (!strncmp(optarg,"sip",3)){
					if ((delim=strchr(optarg,':'))!=NULL){
						delim++;
						if ((delim2=strchr(delim,'@'))!=NULL){
							username=malloc(delim2-delim+1);
							strncpy(username, delim, delim2-delim);
							*(username+(delim2-delim)) = '\0';
							delim2++;
							delim=delim2;
						}
						if ((delim2=strchr(delim,':'))!=NULL){
							domainname=malloc(strlen(delim)+1);
							strncpy(domainname, delim, strlen(delim));
							*(domainname+strlen(delim)) = '\0';
							*delim2 = '\0';
							delim2++;
							rport = atoi(delim2);
							if (!rport) {
								printf("error: non-numerical remote port "
									"number\n");
								exit_code(2);
							}
						}
						else {
							domainname=malloc(strlen(delim)+1);
							strncpy(domainname, delim, strlen(delim));
							*(domainname+strlen(delim)) = '\0';
						}
						if (!address)
							address = getaddress(delim);
						if (!address){
							printf("error:unable to determine the remote host "
								"address\n");
							exit_code(2);
						}
					}
					else{
						printf("error: SIPURI doesn't contain a : ?!\n");
						exit_code(2);
					}
				}
				else{
					printf("error: SIPURI doesn't not begin with sip\n");
					exit_code(2);
				}
				uri_b=1;
				break;			break;
			case 't':
				trashchar=atoi(optarg);
				if (!trashchar) {
					printf("error: non-numerical number of trashed "
						"character\n");
					exit_code(2);
				}
				break;
			case 'T':
				trace=1;
				break;
			case 'U':
				usrloc=1;
				break;
			case 'u':
				auth_username=malloc(strlen(optarg));
				strncpy(auth_username, optarg, strlen(optarg));
				*(auth_username+strlen(optarg)) = '\0';
				break;
			case 'v':
				verbose++;
				break;
			case 'V':
				printf("sipsak %s  by Nils Ohlmeier\n Copyright (C) 2002-2004"
						" FhG Fokus\n Copyright (C) 2004-2005 Nils Ohlmeier\n", 
						SIPSAK_VERSION);
				printf(" compiled with DEFAULT_RETRYS=%i, DEFAULT_TIMEOUT=%i, FQDN_SIZE=%i",
						DEFAULT_RETRYS, DEFAULT_TIMEOUT, FQDN_SIZE);
#ifdef RAW_SUPPORT
				printf(", RAW_SUPPORT");
#endif
#ifdef HAVE_GETOPT_LONG
				printf(", LONG_OPTS");
#endif
				printf("\n");
				exit_code(0);
				break;
			case 'w':
				warning_ext=1;
				break;
			case 'W':
				nagios_warn = atoi(optarg);
				break;
			case 'x':
				expires_t=atoi(optarg);
				break;
#ifdef HAVE_GETOPT_LONG
			case 'X':
				print_long_help();
				break;
#endif
			case 'z':
				rand_rem=1;
				break;
			default:
				printf("error: unknown parameter %c\n", c);
				exit_code(2);
				break;
		}
	}

	/* replace LF with CRLF if we read from a file */
	if ((file_b) && (fix_crlf)) {
		insert_cr(buff);
	}
	/* lots of conditions to check */
	if (trace) {
		if (usrloc || flood || randtrash) {
			printf("error: trace can't be combined with usrloc, random or "
				"flood\n");
			exit_code(2);
		}
		if (!uri_b) {
			printf("error: for trace mode a SIPURI is realy needed\n");
			exit_code(2);
		}
		if (file_b) {
			printf("warning: file will be ignored for tracing.");
		}
		if (!username) {
			printf("error: for trace mode without a file the SIPURI have to "
				"contain a username\n");
			exit_code(2);
		}
		if (!via_ins){
			printf("warning: Via-Line is needed for tracing. Ignoring -i\n");
			via_ins=1;
		}
		if (!warning_ext) {
			printf("warning: IP extract from warning activated to be more "
				"informational\n");
			warning_ext=1;
		}
		if (maxforw==-1) maxforw=255;
	}
	else if (usrloc || invite || message) {
		if (trace || flood || randtrash) {
			printf("error: usrloc can't be combined with trace, random or "
				"flood\n");
			exit_code(2);
		}
		if (!username || !uri_b) {
			printf("error: for the USRLOC mode you have to give a SIPURI with "
				"a username\n       at least\n");
			exit_code(2);
		}
		if (namebeg>0 && nameend==-1) {
			printf("error: if a starting numbers is given also an ending "
				"number have to be specified\n");
			exit_code(2);
		}
		if (invite && message) {
			printf("error: invite and message tests are XOR\n");
			exit_code(2);
		}
		if (!usrloc && invite && !lport) {
			printf("WARNING: Do NOT use the usrloc invite mode without "
				"registering sipsak before.\n         See man page for "
				"details.\n");
			exit_code(2);
		}
		if (contact_uri!=NULL) {
			if (invite || message) {
				printf("error: Contact uri is not support for invites or "
					"messages\n");
				exit_code(2);
			}
			if (nameend!=-1 || namebeg!=-1) {
				printf("warning: ignoring starting or ending number if Contact"
					" is given\n");
				nameend=namebeg=0;
			}
			if (rand_rem) {
				printf("warning: ignoring -z option when Contact is given\n");
				rand_rem=0;
			}
		}
		if (via_ins) {
			printf("warning: ignoring -i option when in usrloc mode\n");
			via_ins=0;
		}
		if (nameend==-1)
			nameend=0;
		if (namebeg==-1)
			namebeg=0;
	}
	else if (flood) {
		if (trace || usrloc || randtrash) {
			printf("error: flood can't be combined with trace, random or "
				"usrloc\n");
			exit_code(2);
		}
		if (!uri_b) {
			printf("error: we need at least a sip uri for flood\n");
			exit_code(2);
		}
		if (redirects) {
			printf("warning: redirects are not expected in flood. "
				"disableing\n");
			redirects=0;
		}
	}
	else if (randtrash) {
		if (trace || usrloc || flood) {
			printf("error: random can't be combined with trace, flood or "
				"usrloc\n");
			exit_code(2);
		}
		if (!uri_b) {
			printf("error: need at least a sip uri for random\n");
			exit_code(2);
		}
		if (redirects) {
			printf("warning: redirects are not expected in random. "
				"disableing\n");
			redirects=0;
		}
		if (verbose) {
			printf("warning: random characters may destroy your terminal "
				"output\n");
		}
	}
	else if (mes_body) {
		if (!message) {
			printf("warning: to send a message mode (-M) is required. activating\n");
			message=1;
		}
		if (!uri_b) {
			printf("error: need at least a sip uri to send a meesage\n");
			exit_code(2);
		}
		if (nameend==-1)
			nameend=0;
		if (namebeg==-1)
			namebeg=0;
	}
	else {
		if (!uri_b) {
			printf("error: a spi uri is needed at least\n");
			exit_code(2);
		}
	}
	/* determine our hostname */
	get_fqdn();
	
	/* this is not a cryptographic random number generator,
	   but hey this is only a test-tool => should be satisfying*/
	srand(time(0));
	
	if (processes > 1) {
		if (signal(SIGCHLD , sigchld_handler)  == SIG_ERR ) {
			printf("error: Could not install SIGCHLD handler\n");
			exit_code(2);
		}
	}

	for(i = 0; i < processes - 1; i++) {
		if ((pid = fork()) < 0) {
			printf("error: Cannot fork\n");
			exit_code(2);
		}
		
		if (pid == 0){
	    	/* child */
			upp = (nameend - namebeg + 1) / processes;
			namebeg = namebeg + upp * i;
			nameend = namebeg + upp;
			shoot(buff);
		} else {
			if (lport) {
				lport++;
			}
		}
		
		/* Delay execution of children so that the
		 * time of the first transmission gets spread over
		 * the retransmission interval evenly
		 */
		ts.tv_sec = 0;
		ts.tv_nsec = (float)DEFAULT_TIMEOUT / (float)processes * (float)1000 * (float)1000;
		nanosleep(&ts, 0);
	}

	/* here we go...*/
	if (processes > 1) {
		upp = (nameend - namebeg + 1) / processes;
		namebeg = namebeg + upp * i;
		nameend = namebeg + upp;
	}
	shoot(buff);

	/* normaly we won't come back here, but to satisfy the compiler */
	return 0;
}
Ejemplo n.º 17
0
int main(int argc, char *argv[])
{
	int argi;
	char *envarea = NULL;

	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 (argnmatch(argv[argi], "--top")) {
			topcount = 10;
			webfile_hf = "topchanges";
			webfile_form = "topchanges_form";
			maxminutes = -1;
			maxcount = -1;
		}
		else if (strcmp(argv[argi], "--debug=")) {
			debug = 1;
		}
	}

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

	fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

	cgidata = cgi_request();
	if (cgidata == NULL) {
		/* Present the query form */
		sethostenv("", "", "", colorname(COL_BLUE), NULL);
		showform(stdout, webfile_hf, webfile_form, COL_BLUE, getcurrenttime(NULL), NULL, NULL);
		return 0;
	}

	*periodstring = '\0';
	parse_query();

	if ((*periodstring == '\0') && (fromtime || totime)) {
		if (fromtime && totime) sprintf(periodstring, "Events between %s - %s", fromtime, totime);
		else if (fromtime) sprintf(periodstring, "Events since %s", fromtime);
		else if (totime) sprintf(periodstring, "Events until %s", totime);
	}

	/* Now generate the webpage */
	headfoot(stdout, webfile_hf, "", "header", COL_GREEN);
	fprintf(stdout, "<center>\n");

	if (topcount == 0) {
		do_eventlog(stdout, maxcount, maxminutes, fromtime, totime, 
			    pageregex, expageregex, hostregex, exhostregex, testregex, extestregex,
			    colorregex, ignoredialups, NULL,
			    NULL, NULL, NULL, counttype, summarybar, periodstring);
	}
	else {
		countlist_t *hcounts, *scounts;
		event_t *events;
		time_t firstevent, lastevent;

		do_eventlog(NULL, -1, -1, fromtime, totime, 
			    pageregex, expageregex, hostregex, exhostregex, testregex, extestregex,
			    colorregex, ignoredialups, NULL,
			    &events, &hcounts, &scounts, counttype, XYMON_S_NONE, NULL);

		lastevent = (totime ? eventreport_time(totime) : getcurrenttime(NULL));

		if (fromtime) {
			firstevent = eventreport_time(fromtime);
		}
		else if (events) {
			event_t *ewalk;
			ewalk = events; while (ewalk->next) ewalk = ewalk->next;
			firstevent = ewalk->eventtime;
		}
		else
			firstevent = 0;

		show_topchanges(stdout, hcounts, scounts, events, topcount, firstevent, lastevent);
	}

	fprintf(stdout, "</center>\n");
	headfoot(stdout, webfile_hf, "", "footer", COL_GREEN);

	return 0;
}
Ejemplo n.º 18
0
xymongen_page_t *load_layout(char *pgset)
{
	char	pagetag[100], subpagetag[100], subparenttag[100], 
		vpagetag[100], vsubpagetag[100], vsubparenttag[100], 
		grouptag[100], summarytag[100], titletag[100], hosttag[100];
	char 	*name, *link, *onlycols, *exceptcols;
	char 	hostname[MAX_LINE_LEN];
	xymongen_page_t 	*toppage, *curpage, *cursubpage, *cursubparent;
	group_t *curgroup;
	host_t	*curhost;
	char	*curtitle;
	int	ip1, ip2, ip3, ip4;
	char	*p;
	int	fqdn = get_fqdn();
	char	*cfgdata, *inbol, *ineol, insavchar = '\0';

	if (loadhostsfromxymond) {
		if (load_hostnames("@", NULL, fqdn) != 0) {
			errprintf("Cannot load host configuration from xymond\n");
			return NULL;
		}
	}
	else {
		if (load_hostnames(xgetenv("HOSTSCFG"), "dispinclude", fqdn) != 0) {
			errprintf("Cannot load host configuration from %s\n", xgetenv("HOSTSCFG"));
			return NULL;
		}
	}

	if (first_host() == NULL) {
		errprintf("Empty configuration from %s\n", (loadhostsfromxymond ? "xymond" : xgetenv("HOSTSCFG")));
		return NULL;
	}

	dbgprintf("load_layout(pgset=%s)\n", textornull(pgset));

	/*
	 * load_hostnames() picks up the hostname definitions, but not the page
	 * layout. So we will scan the file again, this time doing the layout.
	 */

	if (pgset == NULL) pgset = "";
	sprintf(pagetag, "%spage", pgset);
	sprintf(subpagetag, "%ssubpage", pgset);
	sprintf(subparenttag, "%ssubparent", pgset);
	sprintf(vpagetag, "v%spage", pgset);
	sprintf(vsubpagetag, "v%ssubpage", pgset);
	sprintf(vsubparenttag, "v%ssubparent", pgset);
	sprintf(grouptag, "%sgroup", pgset);
	sprintf(summarytag, "%ssummary", pgset);
	sprintf(titletag, "%stitle", pgset);
	sprintf(hosttag, "%s:", pgset); for (p=hosttag; (*p); p++) *p = toupper((int)*p);

	toppage = init_page("", "", 0);
	addtopagelist(toppage);
	curpage = NULL;
	cursubpage = NULL;
	curgroup = NULL;
	curhost = NULL;
	cursubparent = NULL;
	curtitle = NULL;

	inbol = cfgdata = hostscfg_content();
	while (inbol && *inbol) {
		inbol += strspn(inbol, " \t");
		ineol = strchr(inbol, '\n');
		if (ineol) {
			while ((ineol > inbol) && (isspace(*ineol) || (*ineol == '\n'))) ineol--;
			if (*ineol != '\n') ineol++;

			insavchar = *ineol;
			*ineol = '\0';
		}

		dbgprintf("load_layout: -- got line '%s'\n", inbol);

		if ((strncmp(inbol, pagetag, strlen(pagetag)) == 0) || (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0)) {
			getnamelink(inbol, &name, &link);
			if (curpage == NULL) {
				/* First page - hook it on toppage as a subpage from there */
				curpage = toppage->subpages = init_page(name, link, (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0));
			}
			else {
				curpage = curpage->next = init_page(name, link, (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0));
			}

			curpage->parent = toppage;
			if (curtitle) { 
				curpage->pretitle = curtitle; 
				curtitle = NULL; 
			}
			cursubpage = NULL;
			cursubparent = NULL;
			curgroup = NULL;
			curhost = NULL;
			addtopagelist(curpage);
		}
		else if ( (strncmp(inbol, subpagetag, strlen(subpagetag)) == 0) || (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0) ) {
			if (curpage == NULL) {
				errprintf("'subpage' ignored, no preceding 'page' tag : %s\n", inbol);
				goto nextline;
			}

			getnamelink(inbol, &name, &link);
			if (cursubpage == NULL) {
				cursubpage = curpage->subpages = init_page(name, link, (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0));
			}
			else {
				cursubpage = cursubpage->next = init_page(name, link, (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0));
			}
			cursubpage->parent = curpage;
			if (curtitle) { 
				cursubpage->pretitle = curtitle; 
				curtitle = NULL;
			}
			cursubparent = NULL;
			curgroup = NULL;
			curhost = NULL;
			addtopagelist(cursubpage);
		}
		else if ( (strncmp(inbol, subparenttag, strlen(subparenttag)) == 0) || (strncmp(inbol, vsubparenttag, strlen(vsubparenttag)) == 0) ) {
			xymongen_page_t *parentpage, *walk;

			getparentnamelink(inbol, toppage, &parentpage, &name, &link);
			if (parentpage == NULL) {
				errprintf("'subparent' ignored, unknown parent page: %s\n", inbol);
				goto nextline;
			}

			cursubparent = init_page(name, link, (strncmp(inbol, vsubparenttag, strlen(vsubparenttag)) == 0));
			if (parentpage->subpages == NULL) {
				parentpage->subpages = cursubparent;
			} 
			else {
				for (walk = parentpage->subpages; (walk->next); (walk = walk->next)) ;
				walk->next = cursubparent;
			}
			if (curtitle) { 
				cursubparent->pretitle = curtitle; 
				curtitle = NULL;
			}
			cursubparent->parent = parentpage;
			curgroup = NULL;
			curhost = NULL;
			addtopagelist(cursubparent);
		}
		else if (strncmp(inbol, grouptag, strlen(grouptag)) == 0) {
			int sorthosts = (strstr(inbol, "group-sorted") != NULL);

			getgrouptitle(inbol, pgset, &link, &onlycols, &exceptcols);
			if (curgroup == NULL) {
				curgroup = init_group(link, onlycols, exceptcols, sorthosts);
				if (cursubparent != NULL) {
					cursubparent->groups = curgroup;
				}
				else if (cursubpage != NULL) {
					/* We're in a subpage */
					cursubpage->groups = curgroup;
				}
				else if (curpage != NULL) {
					/* We're on a main page */
					curpage->groups = curgroup;
				}
				else {
					/* We're on the top page */
					toppage->groups = curgroup;
				}
			}
			else {
				curgroup->next = init_group(link, onlycols, exceptcols, sorthosts);
				curgroup = curgroup->next;
			}
			if (curtitle) { curgroup->pretitle = curtitle; curtitle = NULL; }
			curhost = NULL;
		}
		else if (sscanf(inbol, "%3d.%3d.%3d.%3d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) {
			void *xymonhost = NULL;
			int dialup, nonongreen, crittime = 1;
			double warnpct = reportwarnlevel;
			int warnstops = reportwarnstops;
			char *displayname, *clientalias, *comment, *description;
			char *alertlist, *onwaplist, *reporttime;
			char *nopropyellowlist, *nopropredlist, *noproppurplelist, *nopropacklist;
			char *targetpagelist[MAX_TARGETPAGES_PER_HOST];
			int targetpagecount;
			char *hval;

			/* Check for ".default." hosts - they are ignored. */
			if (*hostname == '.') goto nextline;

			if (!fqdn) {
				/* Strip any domain from the hostname */
				char *p = strchr(hostname, '.');
				if (p) *p = '\0';
			}

			/* Get the info */
			xymonhost = hostinfo(hostname);
			if (xymonhost == NULL) {
				errprintf("Confused - hostname '%s' cannot be found. Ignored\n", hostname);
				goto nextline;
			}

			/* Check for no-display hosts - they are ignored. */
			/* But only when we're building the default pageset */
			if ((strlen(pgset) == 0) && (xmh_item(xymonhost, XMH_FLAG_NODISP) != NULL)) goto nextline;

			for (targetpagecount=0; (targetpagecount < MAX_TARGETPAGES_PER_HOST); targetpagecount++) 
				targetpagelist[targetpagecount] = NULL;
			targetpagecount = 0;

			dialup = (xmh_item(xymonhost, XMH_FLAG_DIALUP) != NULL);
			nonongreen = (xmh_item(xymonhost, XMH_FLAG_NONONGREEN) != NULL);

			alertlist = xmh_item(xymonhost, XMH_NK);
			hval = xmh_item(xymonhost, XMH_NKTIME); if (hval) crittime = within_sla(xmh_item(xymonhost, XMH_HOLIDAYS), hval, 0);

			onwaplist = xmh_item(xymonhost, XMH_WML);
			nopropyellowlist = xmh_item(xymonhost, XMH_NOPROPYELLOW);
			if (nopropyellowlist == NULL) nopropyellowlist = xmh_item(xymonhost, XMH_NOPROP);
			nopropredlist = xmh_item(xymonhost, XMH_NOPROPRED);
			noproppurplelist = xmh_item(xymonhost, XMH_NOPROPPURPLE);
			nopropacklist = xmh_item(xymonhost, XMH_NOPROPACK);
			displayname = xmh_item(xymonhost, XMH_DISPLAYNAME);
			comment = xmh_item(xymonhost, XMH_COMMENT);
			description = xmh_item(xymonhost, XMH_DESCRIPTION);
			hval = xmh_item(xymonhost, XMH_WARNPCT); if (hval) warnpct = atof(hval);
			hval = xmh_item(xymonhost, XMH_WARNSTOPS); if (hval) warnstops = atof(hval);
			reporttime = xmh_item(xymonhost, XMH_REPORTTIME);

			clientalias = xmh_item(xymonhost, XMH_CLIENTALIAS);
			if (xymonhost && (strcmp(xmh_item(xymonhost, XMH_HOSTNAME), clientalias) == 0)) clientalias = NULL;

			if (xymonhost && (strlen(pgset) > 0)) {
				/* Walk the clone-list and pick up the target pages for this host */
				void *cwalk = xymonhost;
				do {
					hval = xmh_item_walk(cwalk);
					while (hval) {
						if (strncasecmp(hval, hosttag, strlen(hosttag)) == 0)
							targetpagelist[targetpagecount++] = strdup(hval+strlen(hosttag));
						hval = xmh_item_walk(NULL);
					}

					cwalk = next_host(cwalk, 1);
				} while (cwalk && 
					 (strcmp(xmh_item(cwalk, XMH_HOSTNAME), xmh_item(xymonhost, XMH_HOSTNAME)) == 0) &&
					 (targetpagecount < MAX_TARGETPAGES_PER_HOST) );

				/*
				 * HACK: Check if the pageset tag is present at all in the host
				 * entry. If it isn't, then drop this incarnation of the host.
				 *
				 * Without this, the following hosts.cfg file will have the
				 * www.hswn.dk host listed twice on the alternate pageset:
				 *
				 * adminpage nyc NYC
				 *
				 * 127.0.0.1   localhost      # bbd http://localhost/ CLIENT:osiris
				 * 172.16.10.2 www.xymon.com  # http://www.xymon.com/ ADMIN:nyc ssh noinfo
				 *
				 * page superdome Superdome
				 * 172.16.10.2 www.xymon.com # noconn
				 *
				 */
				if (strstr(inbol, hosttag) == NULL) targetpagecount = 0;
			}

			if (strlen(pgset) == 0) {
				/*
				 * Default pageset generated. Put the host into
				 * whatever group or page is current.
				 */
				if (curhost == NULL) {
					curhost = init_host(hostname, 0, displayname, clientalias,
							    comment, description,
							    ip1, ip2, ip3, ip4, dialup, 
							    warnpct, warnstops, reporttime,
							    alertlist, crittime, onwaplist,
							    nopropyellowlist, nopropredlist, noproppurplelist, nopropacklist);
					if (curgroup != NULL) {
						curgroup->hosts = curhost;
					}
					else if (cursubparent != NULL) {
						cursubparent->hosts = curhost;
					}
					else if (cursubpage != NULL) {
						cursubpage->hosts = curhost;
					}
					else if (curpage != NULL) {
						curpage->hosts = curhost;
					}
					else {
						toppage->hosts = curhost;
					}
				}
				else {
					curhost = curhost->next = init_host(hostname, 0, displayname, clientalias,
									    comment, description,
									    ip1, ip2, ip3, ip4, dialup,
									    warnpct, warnstops, reporttime,
									    alertlist, crittime, onwaplist,
									    nopropyellowlist,nopropredlist, 
									    noproppurplelist, nopropacklist);
				}
				curhost->parent = (cursubparent ? cursubparent : (cursubpage ? cursubpage : curpage));
				if (curtitle) { curhost->pretitle = curtitle; curtitle = NULL; }
				curhost->nonongreen = nonongreen;
			}
			else if (targetpagecount) {

				int pgnum;

				for (pgnum=0; (pgnum < targetpagecount); pgnum++) {
					char *targetpagename = targetpagelist[pgnum];

					char savechar;
					int wantedgroup = 0;
					xymonpagelist_t *targetpage = NULL;

					/* Put the host into the page specified by the PGSET: tag */
					p = strchr(targetpagename, ',');
					if (p) {
						savechar = *p;
						*p = '\0';
						wantedgroup = atoi(p+1);
					}
					else {
						savechar = '\0';
						p = targetpagename + strlen(targetpagename);
					}

					/* Find the page */
					if (strcmp(targetpagename, "*") == 0) {
						*targetpagename = '\0';
					}
					for (targetpage = pagelisthead; (targetpage && (strcmp(targetpagename, targetpage->pageentry->name) != 0)); targetpage = targetpage->next) ;

					*p = savechar;
					if (targetpage == NULL) {
						errprintf("Warning: Cannot find any target page named '%s' in set '%s' - dropping host '%s'\n", 
							targetpagename, pgset, hostname);
					}
					else {
						host_t *newhost = init_host(hostname, 0, displayname, clientalias,
									    comment, description,
									    ip1, ip2, ip3, ip4, dialup,
									    warnpct, warnstops, reporttime,
									    alertlist, crittime, onwaplist,
									    nopropyellowlist,nopropredlist, 
									    noproppurplelist, nopropacklist);

						if (wantedgroup > 0) {
							group_t *gwalk;
							host_t  *hwalk;
							int i;

							for (gwalk = targetpage->pageentry->groups, i=1; (gwalk && (i < wantedgroup)); i++,gwalk=gwalk->next) ;
							if (gwalk) {
								if (gwalk->hosts == NULL)
									gwalk->hosts = newhost;
								else {
									for (hwalk = gwalk->hosts; (hwalk->next); hwalk = hwalk->next) ;
									hwalk->next = newhost;
								}
							}
							else {
								errprintf("Warning: Cannot find group %d for host %s - dropping host\n",
									wantedgroup, hostname);
							}
						}
						else {
							/* Just put in on the page's hostlist */
							host_t *walk;
	
							if (targetpage->pageentry->hosts == NULL)
								targetpage->pageentry->hosts = newhost;
							else {
								for (walk = targetpage->pageentry->hosts; (walk->next); walk = walk->next) ;
								walk->next = newhost;
							}
						}

						newhost->parent = targetpage->pageentry;
						if (curtitle) newhost->pretitle = curtitle;
					}

					curtitle = NULL;
				}
			}
		}
		else if (strncmp(inbol, summarytag, strlen(summarytag)) == 0) {
			/* summary row.column      IP-ADDRESS-OF-PARENT    http://xymon.com/ */
			char sumname[MAX_LINE_LEN];
			char receiver[MAX_LINE_LEN];
			char url[MAX_LINE_LEN];
			summary_t *newsum;

			if (sscanf(inbol, "summary %s %s %s", sumname, receiver, url) == 3) {
				newsum = init_summary(sumname, receiver, url);
				newsum->next = sumhead;
				sumhead = newsum;
			}
		}
		else if (strncmp(inbol, titletag, strlen(titletag)) == 0) {
			/* Save the title for the next entry */
			curtitle = strdup(skipwhitespace(skipword(inbol)));
		}

nextline:
		if (ineol) {
			*ineol = insavchar;
			if (*ineol != '\n') ineol = strchr(ineol, '\n');

			inbol = (ineol ? ineol+1 : NULL);
		}
		else
			inbol = NULL;
	}

	xfree(cfgdata);
	return toppage;
}
Ejemplo n.º 19
0
static int client_conf_checks(struct conf **c, const char *path, int *r)
{
	const char *autoupgrade_os=get_string(c[OPT_AUTOUPGRADE_OS]);
	if(!get_string(c[OPT_CNAME]))
	{
		if(get_cname_from_ssl_cert(c)) return -1;
		// There was no error. This is probably a new install.
		// Try getting the fqdn and using that.
		if(!get_string(c[OPT_CNAME]))
		{
			if(get_fqdn(c)) return -1;
			if(!get_string(c[OPT_CNAME]))
				conf_problem(path, "client name unset", r);
		}
	}
	if(!get_string(c[OPT_PASSWORD]))
	{
		logp("password not set, falling back to \"password\"\n");
		if(set_string(c[OPT_PASSWORD], "password"))
			return -1;
	}
	if(!get_string(c[OPT_SERVER]))
		conf_problem(path, "server unset", r);
	if(!get_string(c[OPT_STATUS_PORT])) // carry on if not set.
		logp("%s: status_port unset\n", path);
	if(!get_string(c[OPT_SSL_PEER_CN]))
	{
		const char *server=get_string(c[OPT_SERVER]);
		logp("ssl_peer_cn unset\n");
		if(!server)
		{
			logp("falling back to '%s'\n", server);
			if(set_string(c[OPT_SSL_PEER_CN], server))
				return -1;
		}
	}
	if(autoupgrade_os
	  && strstr(autoupgrade_os, ".."))
		conf_problem(path,
			"autoupgrade_os must not contain a '..' component", r);
	if(!get_string(c[OPT_CA_BURP_CA]))
	{
		if(!get_string(c[OPT_CA_CSR_DIR]))
			conf_problem(path,
				"ca_burp_ca set, but ca_csr_dir not set\n", r);
		if(!get_string(c[OPT_SSL_CERT_CA]))
			conf_problem(path,
				"ca_burp_ca set, but ssl_cert_ca not set\n", r);
		if(!get_string(c[OPT_SSL_CERT]))
			conf_problem(path,
				"ca_burp_ca set, but ssl_cert not set\n", r);
		if(!get_string(c[OPT_SSL_KEY]))
			conf_problem(path,
				"ca_burp_ca set, but ssl_key not set\n", r);
	}

	if(!r)
	{
		struct strlist *l;
		logp("Listing configured paths:\n");
		for(l=get_strlist(c[OPT_INCEXCDIR]); l; l=l->next)
			logp("%s: %s\n", l->flag?"include":"exclude", l->path);
		logp("Listing starting paths:\n");
		for(l=get_strlist(c[OPT_STARTDIR]); l; l=l->next)
			if(l->flag) logp("%s\n", l->path);
	}
	return 0;
}
Ejemplo n.º 20
0
int main(int argc, char *argv[])
{
	char histlogfn[PATH_MAX];
	FILE *fd;
	char textrepfullfn[PATH_MAX], textrepfn[1024], textrepurl[PATH_MAX];
	FILE *textrep;
	reportinfo_t repinfo;
	int argi;
	char *envarea = NULL;
	void *hinfo;

	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);
		}
	}

	redirect_cgilog("reportlog");

	cgidata = cgi_request();
	parse_query();
	load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
        if ((hinfo = hostinfo(hostname)) == NULL) {
		errormsg("No such host");
		return 1;
	}
	ip = xmh_item(hinfo, XMH_IP);
	displayname = xmh_item(hinfo, XMH_DISPLAYNAME);
	if (!displayname) displayname = hostname;

	sprintf(histlogfn, "%s/%s.%s", xgetenv("XYMONHISTDIR"), commafy(hostname), service);
	fd = fopen(histlogfn, "r");
	if (fd == NULL) {
		errormsg("Cannot open history file");
	}

	color = parse_historyfile(fd, &repinfo, hostname, service, st, end, 0, reportwarnlevel, reportgreenlevel, reportwarnstops, reporttime);
	fclose(fd);

	sprintf(textrepfn, "avail-%s-%s-%u-%u.txt", hostname, service, (unsigned int)getcurrenttime(NULL), (int)getpid());
	sprintf(textrepfullfn, "%s/%s", xgetenv("XYMONREPDIR"), textrepfn);
	sprintf(textrepurl, "%s/%s", xgetenv("XYMONREPURL"), textrepfn);
	textrep = fopen(textrepfullfn, "w");

	/* Now generate the webpage */
	printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

	generate_replog(stdout, textrep, textrepurl, 
			hostname, service, color, style, 
			ip, displayname,
			st, end, reportwarnlevel, reportgreenlevel, reportwarnstops, 
			&repinfo);

	if (textrep) fclose(textrep);
	return 0;
}
Ejemplo n.º 21
0
int main(int argc, char *argv[])
{
	char		*pagedir;
	bbgen_page_t 	*p;
	dispsummary_t	*s;
	int		i;
	char		*pageset = NULL;
	char		*nssidebarfilename = NULL;
	char		*egocolumn = NULL;
	char		*csvfile = NULL;
	char		csvdelim = ',';
	int		embedded = 0;
	int		hobbitddump = 0;
	char		*envarea = NULL;
	int		do_normal_pages = 1;

	/* Setup standard header+footer (might be modified by option pageset) */
	select_headers_and_footers("bb");

	bb_color = bb2_color = bbnk_color = -1;
	pagedir = NULL;
	init_timestamp();
	fqdn = get_fqdn();

	/* Setup values from env. vars that may be overridden via commandline options */
	if (xgetenv("MKBB2COLREPEAT")) {
		int i = atoi(xgetenv("MKBB2COLREPEAT"));

		if (i > 0) maxrowsbeforeheading = i;
	}

	for (i = 1; (i < argc); i++) {
		if ( (strcmp(argv[i], "--hobbitd") == 0)       ||
		     (argnmatch(argv[i], "--purplelifetime=")) ||
		     (strcmp(argv[i], "--nopurple") == 0)      ) {
			/* Deprecated */
		}
		else if (argnmatch(argv[i], "--env=")) {
			char *lp = strchr(argv[i], '=');
			loadenv(lp+1, envarea);
		}
		else if (argnmatch(argv[i], "--area=")) {
			char *lp = strchr(argv[i], '=');
			envarea = strdup(lp+1);
		}
		else if (argnmatch(argv[i], "--hobbitddump")) {
			hobbitddump = 1;
		}

		else if (argnmatch(argv[i], "--ignorecolumns=")) {
			char *lp = strchr(argv[i], '=');
			ignorecolumns = (char *) malloc(strlen(lp)+2);
			sprintf(ignorecolumns, ",%s,", (lp+1));
		}
		else if (argnmatch(argv[i], "--nk-reds-only")) {
			nkonlyreds = 1;
		}
		else if (argnmatch(argv[i], "--bb2-ignorecolumns=")) {
			char *lp = strchr(argv[i], '=');
			bb2ignorecolumns = (char *) malloc(strlen(lp)+2);
			sprintf(bb2ignorecolumns, ",%s,", (lp+1));
		}
		else if (argnmatch(argv[i], "--bb2-colors=")) {
			char *lp = strchr(argv[i], '=') + 1;
			bb2colors = colorset(lp, (1 << COL_GREEN));
		}
		else if (argnmatch(argv[i], "--bb2-ignorepurples")) {
			bb2colors = (bb2colors & ~(1 << COL_PURPLE));
		}
		else if (argnmatch(argv[i], "--bb2-ignoredialups")) {
			bb2nodialups = 1;
		}
		else if (argnmatch(argv[i], "--includecolumns=")) {
			char *lp = strchr(argv[i], '=');
			includecolumns = (char *) malloc(strlen(lp)+2);
			sprintf(includecolumns, ",%s,", (lp+1));
		}
		else if (argnmatch(argv[i], "--eventignore=")) {
			char *lp = strchr(argv[i], '=');
			eventignorecolumns = (char *) malloc(strlen(lp)+2);
			sprintf(eventignorecolumns, ",%s,", (lp+1));
		}
		else if (argnmatch(argv[i], "--doccgi=")) {
			char *lp = strchr(argv[i], '=');
			char *url = (char *)malloc(strlen(xgetenv("CGIBINURL"))+strlen(lp+1)+2);
			sprintf(url, "%s/%s", xgetenv("CGIBINURL"), lp+1);
			setdocurl(url);
			xfree(url);
		}
		else if (argnmatch(argv[i], "--docurl=")) {
			char *lp = strchr(argv[i], '=');
			setdocurl(lp+1);
		}
		else if (argnmatch(argv[i], "--no-doc-window")) {
			/* This is a no-op now */
		}
		else if (argnmatch(argv[i], "--doc-window")) {
			setdocurl("TARGET=\"_blank\"");
		}
		else if (argnmatch(argv[i], "--htmlextension=")) {
			char *lp = strchr(argv[i], '=');
			htmlextension = strdup(lp+1);
		}
		else if (argnmatch(argv[i], "--htaccess")) {
			char *lp = strchr(argv[i], '=');
			if (lp) htaccess = strdup(lp+1);
			else htaccess = ".htaccess";
		}
		else if ((strcmp(argv[i], "--wml") == 0) || argnmatch(argv[i], "--wml=")) {
			char *lp = strchr(argv[i], '=');

			if (lp) {
				wapcolumns = (char *) malloc(strlen(lp)+2);
				sprintf(wapcolumns, ",%s,", (lp+1));
			}
			enable_wmlgen = 1;
		}
		else if (argnmatch(argv[i], "--nstab=")) {
			char *lp = strchr(argv[i], '=');

			if (strlen(lp+1) > 0) {
				nssidebarfilename = strdup(lp+1);
			}
			else errprintf("--nstab requires a filename\n");
		}
		else if (argnmatch(argv[i], "--nslimit=")) {
			char *lp = strchr(argv[i], '=');
			nssidebarcolorlimit = parse_color(lp+1);
		}
		else if (argnmatch(argv[i], "--rssversion=")) {
			char *lp = strchr(argv[i], '=');

			rssversion = strdup(lp+1);
		}
		else if (argnmatch(argv[i], "--rsslimit=")) {
			char *lp = strchr(argv[i], '=');
			rsscolorlimit = parse_color(lp+1);
		}
		else if (argnmatch(argv[i], "--rss")) {
			wantrss = 1;
		}
		else if (argnmatch(argv[i], "--rssextension=")) {
			char *lp = strchr(argv[i], '=');
			rssextension = strdup(lp+1);
		}
		else if (argnmatch(argv[i], "--reportopts=")) {
			char style[MAX_LINE_LEN];
			unsigned int rstart, rend;

			int count = sscanf(argv[i], "--reportopts=%u:%u:%d:%s", 
					   &rstart, &rend, &dynamicreport, style);
			reportstart = rstart; reportend = rend;

			if (count < 2) {
				errprintf("Invalid --reportopts option: Must have start- and end-times\n");
				return 1;
			}

			if (count < 3) dynamicreport = 1;
			if (count == 4) {
				if (strcmp(style, stylenames[STYLE_CRIT]) == 0) reportstyle = STYLE_CRIT;
				else if (strcmp(style, stylenames[STYLE_NONGR]) == 0) reportstyle = STYLE_NONGR;
				else reportstyle = STYLE_OTHER;
			}

			if (reportstart < 788918400) reportstart = 788918400;
			if (reportend > time(NULL)) reportend = time(NULL);

			if (xgetenv("BBREPWARN")) reportwarnlevel = atof(xgetenv("BBREPWARN"));
			if (xgetenv("BBREPGREEN")) reportgreenlevel = atof(xgetenv("BBREPGREEN"));

			if ((reportwarnlevel < 0.0) || (reportwarnlevel > 100.0)) reportwarnlevel = 97.0;
			if ((reportgreenlevel < 0.0) || (reportgreenlevel > 100.0)) reportgreenlevel = 99.995;

			select_headers_and_footers("bbrep");
			sethostenv_report(reportstart, reportend, reportwarnlevel, reportgreenlevel);
		}
		else if (argnmatch(argv[i], "--csv="))  {
			char *lp = strchr(argv[i], '=');
			csvfile = strdup(lp+1);
		}
		else if (argnmatch(argv[i], "--csvdelim="))  {
			char *lp = strchr(argv[i], '=');
			csvdelim = *(lp+1);
		}
		else if (argnmatch(argv[i], "--snapshot=")) {
			char *lp = strchr(argv[i], '=');

			snapshot = atol(lp+1);
			select_headers_and_footers("bbsnap");
			sethostenv_snapshot(snapshot);
		}

		else if (strcmp(argv[i], "--pages-first") == 0) {
			hostsbeforepages = 0;
		}
		else if (strcmp(argv[i], "--pages-last") == 0) {
			hostsbeforepages = 1;
		}
		else if (argnmatch(argv[i], "--subpagecolumns=")) {
			char *lp = strchr(argv[i], '=');

			subpagecolumns = atoi(lp+1);
			if (subpagecolumns < 1) subpagecolumns=1;
		}
		else if (argnmatch(argv[i], "--maxrows=")) {
			char *lp = strchr(argv[i], '=');

			maxrowsbeforeheading = atoi(lp+1);
			if (maxrowsbeforeheading < 0) maxrowsbeforeheading=0;
		}
		else if (strcmp(argv[i], "--recentgifs") == 0) {
			use_recentgifs = 1;
		}
		else if (argnmatch(argv[i], "--recentgifs=")) {
			char *lp = strchr(argv[i], '=');

			use_recentgifs = 1;
			recentgif_limit = 60*durationvalue(lp+1);
		}
		else if (strcmp(argv[i], "--sort-group-only-items") == 0) {
			sort_grouponly_items = 1;
		}
		else if (argnmatch(argv[i], "--page-title=")) {
			char *lp = strchr(argv[i], '=');

			defaultpagetitle = strdup(lp+1);
		}
		else if (argnmatch(argv[i], "--dialupskin=")) {
			char *lp = strchr(argv[i], '=');

			dialupskin = strdup(lp+1);
		}
		else if (argnmatch(argv[i], "--reverseskin=")) {
			char *lp = strchr(argv[i], '=');

			reverseskin = strdup(lp+1);
		}
		else if (strcmp(argv[i], "--pagetitle-links") == 0) {
			pagetitlelinks = 1;
		}
		else if (strcmp(argv[i], "--pagetext-headings") == 0) {
			pagetextheadings = 1;
		}
		else if (strcmp(argv[i], "--underline-headings") == 0) {
			underlineheadings = 1;
		}
		else if (strcmp(argv[i], "--no-underline-headings") == 0) {
			underlineheadings = 0;
		}
		else if (strcmp(argv[i], "--no-eventlog") == 0) {
			bb2eventlog = 0;
		}
		else if (argnmatch(argv[i], "--max-eventcount=")) {
			char *lp = strchr(argv[i], '=');

			bb2eventlogmaxcount = atoi(lp+1);
		}
		else if (argnmatch(argv[i], "--max-eventtime=")) {
			char *lp = strchr(argv[i], '=');

			bb2eventlogmaxtime = atoi(lp+1);
		}
		else if (argnmatch(argv[i], "--max-ackcount=")) {
			char *lp = strchr(argv[i], '=');

			bb2acklogmaxcount = atoi(lp+1);
		}
		else if (argnmatch(argv[i], "--max-acktime=")) {
			char *lp = strchr(argv[i], '=');

			bb2acklogmaxtime = atoi(lp+1);
		}
		else if (strcmp(argv[i], "--no-acklog") == 0) {
			bb2acklog = 0;
		}
		else if (strcmp(argv[i], "--no-pages") == 0) {
			do_normal_pages = 0;
		}

		else if (argnmatch(argv[i], "--noprop=")) {
			char *lp = strchr(argv[i], '=');
			nopropyellowdefault = (char *) malloc(strlen(lp)+2);
			sprintf(nopropyellowdefault, ",%s,", (lp+1));
			errprintf("--noprop is deprecated - use --nopropyellow instead\n");
		}
		else if (argnmatch(argv[i], "--nopropyellow=")) {
			char *lp = strchr(argv[i], '=');
			nopropyellowdefault = (char *) malloc(strlen(lp)+2);
			sprintf(nopropyellowdefault, ",%s,", (lp+1));
		}
		else if (argnmatch(argv[i], "--nopropred=")) {
			char *lp = strchr(argv[i], '=');
			nopropreddefault = (char *) malloc(strlen(lp)+2);
			sprintf(nopropreddefault, ",%s,", (lp+1));
		}
		else if (argnmatch(argv[i], "--noproppurple=")) {
			char *lp = strchr(argv[i], '=');
			noproppurpledefault = (char *) malloc(strlen(lp)+2);
			sprintf(noproppurpledefault, ",%s,", (lp+1));
		}
		else if (argnmatch(argv[i], "--nopropack=")) {
			char *lp = strchr(argv[i], '=');
			nopropackdefault = (char *) malloc(strlen(lp)+2);
			sprintf(nopropackdefault, ",%s,", (lp+1));
		}

		else if (strcmp(argv[i], "--bbpageONLY") == 0) {
			/* Deprecated */
			errprintf("--bbpageONLY is deprecated - use --pageset=NAME to generate pagesets\n");
		}
		else if (strcmp(argv[i], "--embedded") == 0) {
			embedded = 1;
		}
		else if (argnmatch(argv[i], "--pageset=")) {
			char *lp = strchr(argv[i], '=');
			pageset = strdup(lp+1);
		}
		else if (argnmatch(argv[i], "--template=")) {
			char *lp = strchr(argv[i], '=');
			lp++;
			select_headers_and_footers(lp);
		}

		else if (argnmatch(argv[i], "--purplelog=")) {
			char *lp = strchr(argv[i], '=');
			if (*(lp+1) == '/') purplelogfn = strdup(lp+1);
			else {
				purplelogfn = (char *) malloc(strlen(xgetenv("BBHOME"))+1+strlen(lp+1)+1);
				sprintf(purplelogfn, "%s/%s", xgetenv("BBHOME"), (lp+1));
			}
		}
		else if (argnmatch(argv[i], "--report=") || (strcmp(argv[i], "--report") == 0)) {
			char *lp = strchr(argv[i], '=');
			if (lp) {
				egocolumn = strdup(lp+1);
			}
			else egocolumn = "bbgen";
			timing = 1;
		}
		else if (argnmatch(argv[i], "--nklog=") || (strcmp(argv[i], "--nklog") == 0)) {
			char *lp = strchr(argv[i], '=');
			if (lp) {
				lognkstatus = strdup(lp+1);
			}
			else lognkstatus = "nk";
		}
		else if (strcmp(argv[i], "--timing") == 0) {
			timing = 1;
		}
		else if (strcmp(argv[i], "--debug") == 0) {
			debug = 1;
		}
		else if (strcmp(argv[i], "--no-update") == 0) {
			dontsendmessages = 1;
		}
		else if (strcmp(argv[i], "--version") == 0) {
			printf("bbgen version %s\n", VERSION);
			printf("\n");
			exit(0);
		}

		else if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-?") == 0)) {
			printf("bbgen for Hobbit version %s\n\n", VERSION);
			printf("Usage: %s [options] [WebpageDirectory]\n", argv[0]);
			printf("Options:\n");
			printf("    --ignorecolumns=test[,test] : Completely ignore these columns\n");
			printf("    --nk-reds-only              : Only show red statuses on the NK page\n");
			printf("    --bb2-ignorecolumns=test[,test]: Ignore these columns for the BB2 page\n");
			printf("    --bb2-ignorepurples         : Ignore all-purple hosts on BB2 page\n");
			printf("    --includecolumns=test[,test]: Always include these columns on BB2 page\n");
		        printf("    --max-eventcount=N          : Max number of events to include in eventlog\n");
		        printf("    --max-eventtime=N           : Show events that occurred within the last N minutes\n");
			printf("    --eventignore=test[,test]   : Columns to ignore in bb2 event-log display\n");
			printf("    --no-eventlog               : Do not generate the bb2 eventlog display\n");
			printf("    --no-acklog                 : Do not generate the bb2 ack-log display\n");
			printf("    --no-pages                  : Generate only the bb2 and bbnk pages\n");
			printf("    --docurl=documentation-URL  : Hostnames link to a general (dynamic) web page for docs\n");
			printf("    --no-doc-window             : Open doc-links in same window\n");
			printf("    --htmlextension=.EXT        : Sets filename extension for generated file (default: .html\n");
			printf("    --report[=COLUMNNAME]       : Send a status report about the running of bbgen\n");
			printf("    --reportopts=ST:END:DYN:STL : Run in Hobbit Reporting mode\n");
			printf("    --csv=FILENAME              : For Hobbit Reporting, output CSV file\n");
			printf("    --csvdelim=CHARACTER        : Delimiter in CSV file output (default: comma)\n");
			printf("    --snapshot=TIME             : Snapshot mode\n");
			printf("\nPage layout options:\n");
			printf("    --pages-first               : Put page- and subpage-links before hosts (default)\n");
			printf("    --pages-last                : Put page- and subpage-links after hosts\n");
			printf("    --subpagecolumns=N          : Number of columns for links to pages and subpages\n");
			printf("    --maxrows=N                 : Repeat column headings for every N hosts shown\n");
			printf("    --recentgifs                : Use xxx-recent.gif icons for newly changed tests\n");
			printf("    --sort-group-only-items     : Display group-only items in alphabetical order\n");
			printf("    --page-title=TITLE          : Set a default page title for all pages\n");
			printf("    --dialupskin=URL            : Use a different icon skin for dialup tests\n");
			printf("    --reverseskin=URL           : Use a different icon skin for reverse tests\n");
			printf("    --pagetitle-links           : Make page- and subpage-titles act as links\n");
			printf("    --pagetext-headings         : Use page texts as headings\n");
			printf("    --no-underline-headings     : Do not underline the page headings\n");
			printf("\nStatus propagation control options:\n");
			printf("    --noprop=test[,test]        : Disable upwards status propagation when YELLOW\n");
			printf("    --nopropred=test[,test]     : Disable upwards status propagation when RED or YELLOW\n");
			printf("    --noproppurple=test[,test]  : Disable upwards status propagation when PURPLE\n");
			printf("\nAlternate pageset generation support:\n");
			printf("    --pageset=SETNAME           : Generate non-standard pageset with tag SETNAME\n");
			printf("    --template=TEMPLATE         : template for header and footer files\n");
			printf("\nAlternate output formats:\n");
			printf("    --wml[=test1,test2,...]     : Generate a small (bb2-style) WML page\n");
			printf("    --nstab=FILENAME            : Generate a Netscape Sidebar feed\n");
			printf("    --nslimit=COLOR             : Minimum color to include on Netscape sidebar\n");
			printf("    --rss                       : Generate a RSS/RDF feed of alerts\n");
			printf("    --rssextension=.EXT         : Sets filename extension for RSS files (default: .rss\n");
			printf("    --rssversion={0.91|0.92|1.0|2.0} : Specify RSS/RDF version (default: 0.91)\n");
			printf("    --rsslimit=COLOR            : Minimum color to include on RSS feed\n");
			printf("\nDebugging/troubleshooting options:\n");
			printf("    --timing                    : Collect timing information\n");
			printf("    --debug                     : Debugging information\n");
			printf("    --version                   : Show version information\n");
			printf("    --purplelog=FILENAME        : Create a log of purple hosts and tests\n");
			exit(0);
		}
		else if (argnmatch(argv[i], "-")) {
			errprintf("Unknown option : %s\n", argv[i]);
		}

		else {
			/* Last argument is pagedir */
			pagedir = strdup(argv[i]);
		}
	}

	/* In case they changed the name of our column ... */
	if (egocolumn) setup_signalhandler(egocolumn);

	if (debug) {
		int i;
		printf("Command: bbgen");
		for (i=1; (i<argc); i++) printf(" '%s'", argv[i]);
		printf("\n");
		printf("Environment BBHOSTS='%s'\n", textornull(xgetenv("BBHOSTS")));
		printf("\n");
	}

	add_timestamp("Startup");

	/* Check that all needed environment vars are defined */
	envcheck(reqenv);

	/* Catch a SEGV fault */
	setup_signalhandler("bbgen");

	/* Set umask to 0022 so that the generated HTML pages have world-read access */
	umask(0022);

	if (pagedir == NULL) {
		if (xgetenv("BBWWW")) {
			pagedir = strdup(xgetenv("BBWWW"));
		}
		else {
			pagedir = (char *) malloc(strlen(xgetenv("BBHOME"))+5);
			sprintf(pagedir, "%s/www", xgetenv("BBHOME"));
		}
	}

	if (xgetenv("BBHTACCESS")) bbhtaccess = strdup(xgetenv("BBHTACCESS"));
	if (xgetenv("BBPAGEHTACCESS")) bbpagehtaccess = strdup(xgetenv("BBPAGEHTACCESS"));
	if (xgetenv("BBSUBPAGEHTACCESS")) bbsubpagehtaccess = strdup(xgetenv("BBSUBPAGEHTACCESS"));

	/*
	 * When doing alternate pagesets, disable some stuff:
	 * No WML or RSS pages.
	 */
	if (pageset || embedded || snapshot) enable_wmlgen = wantrss = 0;
	if (embedded) {
		egocolumn = htaccess = NULL;

		/*
		 * Need to have default SIGPIPE handling when doing embedded stuff.
		 * We are probably run from a CGI script or something similar.
		 */
		signal(SIGPIPE, SIG_DFL);
	}

	/* Load all data from the various files */
	load_all_links();
	add_timestamp("Load links done");
	pagehead = load_bbhosts(pageset);
	add_timestamp("Load bbhosts done");

	if (!embedded) {
		/* Remove old acknowledgements */
		delete_old_acks();
		add_timestamp("ACK removal done");
	}

	statehead = load_state(&dispsums);
	if (embedded || snapshot) dispsums = NULL;
	add_timestamp("Load STATE done");

	if (hobbitddump) {
		dump_hobbitdchk();
		return 0;
	}

	/* Calculate colors of hosts and pages */
	calc_hostcolors(bb2ignorecolumns);
	calc_pagecolors(pagehead);

	/* Topmost page (background color for bb.html) */
	for (p=pagehead; (p); p = p->next) {
		if (p->color > pagehead->color) pagehead->color = p->color;
	}
	bb_color = pagehead->color;

	if (xgetenv("SUMMARY_SET_BKG") && (strcmp(xgetenv("SUMMARY_SET_BKG"), "TRUE") == 0)) {
		/*
		 * Displayed summaries affect the BB page only, 
		 * but should not go into the color we report to
		 * others.
		 */
		for (s=dispsums; (s); s = s->next) {
			if (s->color > pagehead->color) pagehead->color = s->color;
		}
	}
	add_timestamp("Color calculation done");

	if (debug) dumpall(pagehead);

	/* Generate pages */
	if (chdir(pagedir) != 0) {
		errprintf("Cannot change to webpage directory %s\n", pagedir);
		exit(1);
	}

	if (embedded) {
		/* Just generate that one page */
		do_one_page(pagehead, NULL, 1);
		return 0;
	}

	/* The main page - bb.html and pages/subpages thereunder */
	add_timestamp("Hobbit pagegen start");
	if (reportstart && csvfile) {
		csv_availability(csvfile, csvdelim);
	}
	else if (do_normal_pages) {
		do_page_with_subs(pagehead, dispsums);
	}
	add_timestamp("Hobbit pagegen done");

	if (reportstart) {
		/* Reports end here */
		return 0;
	}

	/* The full summary page - bb2.html */
	bb2_color = do_bb2_page(nssidebarfilename, PAGE_BB2);
	add_timestamp("BB2 generation done");

	/* Reduced summary (alerts) page - bbnk.html */
	bbnk_color = do_bb2_page(NULL, PAGE_NK);
	add_timestamp("BBNK generation done");

	if (snapshot) {
		/* Snapshots end here */
		return 0;
	}

	/* Send summary notices - only once, so not on pagesets */
	if (pageset == NULL) {
		send_summaries(sumhead);
		add_timestamp("Summary transmission done");
	}

	/* Generate WML cards */
	if (enable_wmlgen) {
		do_wml_cards(pagedir);
		add_timestamp("WML generation done");
	}

	/* Need to do this before sending in our report */
	add_timestamp("Run completed");

	/* Tell about us */
	if (egocolumn) {
		char msgline[4096];
		char *timestamps;
		long bbsleep = (xgetenv("BBSLEEP") ? atol(xgetenv("BBSLEEP")) : 300);
		int color;

		/* Go yellow if it runs for too long */
		if (total_runtime() > bbsleep) {
			errprintf("WARNING: Runtime %ld longer than BBSLEEP (%ld)\n", total_runtime(), bbsleep);
		}
		color = (errbuf ? COL_YELLOW : COL_GREEN);

		combo_start();
		init_status(color);
		sprintf(msgline, "status %s.%s %s %s\n\n", xgetenv("MACHINE"), egocolumn, colorname(color), timestamp);
		addtostatus(msgline);

		sprintf(msgline, "bbgen for Hobbit version %s\n", VERSION);
		addtostatus(msgline);

		sprintf(msgline, "\nStatistics:\n Hosts               : %5d\n Status messages     : %5d\n Purple messages     : %5d\n Pages               : %5d\n", 
			hostcount, statuscount, purplecount, pagecount);
		addtostatus(msgline);

		if (errbuf) {
			addtostatus("\n\nError output:\n");
			addtostatus(errbuf);
		}

		show_timestamps(&timestamps);
		addtostatus(timestamps);

		finish_status();
		combo_end();
	}
	else show_timestamps(NULL);

	return 0;
}
Ejemplo n.º 22
0
int main(int argc, char *argv[])
{
	int argi, i;
	char *username = getenv("REMOTE_USER");
	char *userhost = getenv("REMOTE_HOST");
	char *userip   = getenv("REMOTE_ADDR");
	char *fullmsg = "No cause specified";
	char *envarea = NULL;
	int  obeycookies = 1;
	char *accessfn = NULL;

	if ((username == NULL) || (strlen(username) == 0)) username = "******";
	if ((userhost == NULL) || (strlen(userhost) == 0)) userhost = userip;
	
	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], "--no-cookies") == 0) {
			obeycookies = 0;
		}
		else if (strcmp(argv[argi], "--debug") == 0) {
			debug = 1;
		}
		else if (argnmatch(argv[argi], "--access=")) {
			char *p = strchr(argv[argi], '=');
			accessfn = strdup(p+1);
		}
	}

	redirect_cgilog("enadis");

	parse_cgi();
	if (debug) preview = 1;

	if (cgi_method == CGI_GET) {
		/*
		 * It's a GET, so the initial request.
		 * If we have a pagepath cookie, use that as the initial
		 * host-name filter.
		 */
		char *pagepath;

		action = ACT_FILTER;
		pagepath = get_cookie("pagepath");
		if (obeycookies && pagepath && *pagepath) pagepattern = strdup(pagepath);
	}

	if (action == ACT_FILTER) {
		/* Present the query form */

		load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
		sethostenv("", "", "", colorname(COL_BLUE), NULL);
		sethostenv_filter(hostpattern, pagepattern, ippattern, classpattern);
		printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
		showform(stdout, "maint", "maint_form", COL_BLUE, getcurrenttime(NULL), NULL, NULL);
		return 0;
	}

	fullmsg = (char *)malloc(1024 + strlen(username) + strlen(userhost) + strlen(disablemsg));
	sprintf(fullmsg, "\nDisabled by: %s @ %s\nReason: %s\n", username, userhost, disablemsg);

	/*
	 * Ready ... go build the webpage.
	 */
	printf("Content-Type: %s\n", xgetenv("HTMLCONTENTTYPE"));
	if (!preview) {
		char *returl;
		// dbgprintf("Not a preview: sending to %s\n", textornull(getenv("HTTP_REFERER")));
		/* We're done -- figure out where to send them */
		if (getenv("HTTP_REFERER")) printf("Location: %s\n\n", getenv("HTTP_REFERER"));
		else {
			returl = (char *)malloc(1024);
			snprintf(returl, sizeof(returl), "%s/%s", xgetenv("SECURECGIBINURL"), "enadis.sh");
			printf("Location: %s?\n\n", returl);
		}
	}
	else {
		printf("\n");
	}

        /* It's ok with these hardcoded values, as they are not used for this page */
	sethostenv("", "", "", colorname(COL_BLUE), NULL);
	if (preview) headfoot(stdout, "maintact", "", "header", COL_BLUE);

	if (debug) {
		printf("<pre>\n");
		switch (action) {
		  case ACT_NONE   : dbgprintf("Action = none\n"); break;

		  case ACT_FILTER : dbgprintf("Action = filter\n"); break;

		  case ACT_ENABLE : dbgprintf("Action = enable\n"); 
				    dbgprintf("Tests = ");
				    for (i=0; (i < enablecount); i++) printf("%s ", enabletest[i]);
				    printf("\n");
				    break;

		  case ACT_DISABLE: dbgprintf("Action = disable\n"); 
				    dbgprintf("Tests = ");
				    for (i=0; (i < disablecount); i++) printf("%s ", disabletest[i]);
				    printf("\n");
				    if (disableend == DISABLE_UNTIL) {
				    	dbgprintf("Disable until: endtime = %d, duration = %d, scale = %d\n", endtime, duration, scale);
				     }	
			            else {
				    	dbgprintf("Duration = %d, scale = %d\n", duration, scale);
				    }
				    dbgprintf("Cause = %s\n", textornull(disablemsg));
				    break;

		  case ACT_SCHED_DISABLE:
				    dbgprintf("Action = schedule\n");
				    dbgprintf("Time = %s\n", ctime(&schedtime));
				    dbgprintf("Tests = ");
				    for (i=0; (i < disablecount); i++) printf("%s ", disabletest[i]);
				    printf("\n");
				    if (disableend == DISABLE_UNTIL) {
						  dbgprintf("Disable until: endtime = %d, duration = %d, scale = %d\n", endtime, duration, scale);
					  }	
			            else {
				    		  dbgprintf("Duration = %d, scale = %d\n", duration, scale);
				    }
				    dbgprintf("Cause = %s\n", textornull(disablemsg));
				    break;

		  case ACT_SCHED_CANCEL:
				    dbgprintf("Action = cancel\n");
				    dbgprintf("ID = %d\n", cancelid);
				    break;
		}
		printf("</pre>\n");
	}

	if (preview) printf("<table align=\"center\" summary=\"Actions performed\" width=\"60%%\">\n");


	if (action == ACT_SCHED_CANCEL) {
		do_one_host(NULL, NULL, username);
	}
	else {
		/* Load the host data (for access control) */
		if (accessfn) {
			load_web_access_config(accessfn);

			for (i = 0; (i < hostcount); i++) {
				if (web_access_allowed(getenv("REMOTE_USER"), hostnames[i], NULL, WEB_ACCESS_CONTROL)) {
					do_one_host(hostnames[i], fullmsg, username);
				}
			}
		}
		else {
			for (i = 0; (i < hostcount); i++) do_one_host(hostnames[i], fullmsg, username);
		}
	}
	if (preview) {
		printf("<tr><td align=center><br><br><form method=\"GET\" ACTION=\"%s\"><input type=submit value=\"Continue\"></form></td></tr>\n", xgetenv("HTTP_REFERER"));
		printf("</table>\n");

		headfoot(stdout, "maintact", "", "footer", COL_BLUE);
	}

	return 0;
}
Ejemplo n.º 23
0
int main(int argc, char *argv[])
{
	int argi;
	char *envarea = NULL;
	char **critconfig = NULL;
	int cccount = 0;
	char *hffile = "critical";

	critconfig = (char **)calloc(1, sizeof(char *));

	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;
		}
		else if (strcmp(argv[argi], "--tooltips") == 0) {
			usetooltips = 1;
		}
		else if (argnmatch(argv[argi], "--acklevel=")) {
			char *p = strchr(argv[argi], '=');
			critacklevel = atoi(p+1);
		}
		else if (argnmatch(argv[argi], "--config=")) {
			char *p = strchr(argv[argi], '=');

			critconfig[cccount] = strdup(p+1);
			cccount++;
			critconfig = (char **)realloc(critconfig, (1 + cccount)*sizeof(char *));
			critconfig[cccount] = NULL;
		}
		else if (argnmatch(argv[argi], "--hffile=")) {
			char *p = strchr(argv[argi], '=');
			hffile = strdup(p+1);
		}
	}

	if (!critconfig[0]) {
		critconfig = (char **)realloc(critconfig, 2*sizeof(char *));
		critconfig[0] = (char *)malloc(strlen(xgetenv("XYMONHOME")) + strlen(DEFAULT_CRITCONFIGFN) + 2);
		sprintf(critconfig[0], "%s/%s", xgetenv("XYMONHOME"), DEFAULT_CRITCONFIGFN);
		critconfig[1] = NULL;
	}

	redirect_cgilog("criticalview");

	setdocurl(hostsvcurl("%s", xgetenv("INFOCOLUMN"), 1));

	parse_query();
	load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
	load_all_links();
	fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

	use_recentgifs = 1;

	if (getboard(mincolor) == 0) {
		int i;
		char *oneconfig, *onename;
		int *partcolor = NULL, *partprio = NULL;
		xtreePos_t hhandle;

		for (i=0; (critconfig[i]); i++) {
			oneconfig = strchr(critconfig[i], ':');
			load_critconfig(oneconfig ? oneconfig+1 : critconfig[i]);
			loadstatus(maxprio, maxage, mincolor, wantacked);

			/* Determine background color and max. priority */
			if (i == 0) {
				partcolor = (int *)malloc(sizeof(int));
				partprio = (int *)malloc(sizeof(int));
			}
			else {
				partcolor = (int *)realloc(partcolor, (i+1)*sizeof(int));
				partprio = (int *)realloc(partprio, (i+1)*sizeof(int));
			}
			partcolor[i] = COL_GREEN;
			partprio[i] = 0;

			for (hhandle = xtreeFirst(rbstate[i]); (hhandle != xtreeEnd(rbstate[i])); hhandle = xtreeNext(rbstate[i], hhandle)) {
				hstatus_t *itm;

				itm = (hstatus_t *)xtreeData(rbstate[i], hhandle);

				if (itm->color > partcolor[i]) partcolor[i] = itm->color;
				if (itm->config->priority > partprio[i]) partprio[i] = itm->config->priority;
			}

			if (partcolor[i] > pagecolor) pagecolor = partcolor[i];
		}

		for (i=0; (critconfig[i]); i++) {
			oneconfig = strchr(critconfig[i], ':'); 
			if (oneconfig) {
				*oneconfig = '\0';
				oneconfig++;
				onename = (char *)malloc(strlen("DIVIDERTEXT=") + strlen(critconfig[i]) + 1);
				sprintf(onename, "DIVIDERTEXT=%s", critconfig[i]);
				putenv(onename);
			}
			else {
				oneconfig = critconfig[i];
				putenv("DIVIDERTEXT=");
			}

			generate_critpage(rbstate[i], hostsonpage[i], stdout, 
					  (i == 0) ? (critconfig[1] ? "critmulti" : hffile) : "divider", 
					  (critconfig[i+1] == NULL) ? hffile : "divider",
					  partcolor[i], partprio[i]);
		}
	}
	else {
		fprintf(stdout, "Cannot load Xymon status\n");
	}

	return 0;
}
Ejemplo n.º 24
0
int main(int argc, char *argv[])
{
	int argi;
	namelist_t *h;
	char *val;

	load_hostnames(argv[1], NULL, get_fqdn());

	for (argi = 2; (argi < argc); argi++) {
		char s[1024];
		char *p;
		char *hname;
		char hostip[IP_ADDR_STRLEN];

handlehost:
		hname = knownhost(argv[argi], hostip, 1);
		if (hname == NULL) {
			printf("Unknown host '%s'\n", argv[argi]);
			continue;
		}
		if (strcmp(hname, argv[argi])) {
			printf("Using canonical name '%s'\n", hname);
		}
		h = hostinfo(hname);

		if (h == NULL) { printf("Host %s not found\n", argv[argi]); continue; }

		val = bbh_item_walk(h);
		printf("Entry for host %s\n", h->bbhostname);
		while (val) {
			printf("\t%s\n", val);
			val = bbh_item_walk(NULL);
		}

		do {
			*s = '\0';
			printf("Pick item:"); fflush(stdout); fgets(s, sizeof(s), stdin);
			p = strchr(s, '\n'); if (p) *p = '\0';
			if (*s == '!') {
				load_hostnames(argv[1], NULL, get_fqdn());
				/* Must restart! The "h" handle is no longer valid. */
				goto handlehost;
			}
			else if (*s == '>') {
				val = bbh_item_multi(h, BBH_PAGEPATH);
				while (val) {
					printf("\t%s value is: '%s'\n", s, val);
					val = bbh_item_multi(NULL, BBH_PAGEPATH);
				}
			}
			else if (strncmp(s, "set ", 4) == 0) {
				bbh_set_item(h, BBH_DATA, strdup(s+4));
			}
			else if (*s) {
				val = bbh_item_byname(h, s);
				if (val) printf("\t%s value is: '%s'\n", s, val);
				else printf("\t%s not found\n", s);
			}
		} while (*s);
	}

	return 0;
}
Ejemplo n.º 25
0
int main(int argc, char *argv[])
{
	char *msg;
	int argi;
	struct sigaction sa;
	char *exthandler = NULL;
	char *extids = NULL;
	char *processor = NULL;
	struct sockaddr_un ctlsockaddr;
	int ctlsocket;

	/* Handle program options. */
	for (argi = 1; (argi < argc); argi++) {
		if (strcmp(argv[argi], "--debug") == 0) {
			debug = 1;
		}
		else if (argnmatch(argv[argi], "--rrddir=")) {
			char *p = strchr(argv[argi], '=');
			rrddir = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--extra-script=")) {
			char *p = strchr(argv[argi], '=');
			exthandler = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--extra-tests=")) {
			char *p = strchr(argv[argi], '=');
			extids = strdup(p+1);
		}
		else if (argnmatch(argv[argi], "--processor=")) {
			char *p = strchr(argv[argi], '=');
			processor = strdup(p+1);
		}
		else if (strcmp(argv[argi], "--no-cache") == 0) {
			use_rrd_cache = 0;
		}
		else if (net_worker_option(argv[argi])) {
			/* Handled in the subroutine */
		}
	}

	save_errbuf = 0;

	if ((rrddir == NULL) && xgetenv("XYMONRRDS")) {
		rrddir = strdup(xgetenv("XYMONRRDS"));
	}

	if (exthandler && extids) setup_exthandler(exthandler, extids);

	/* Do the network stuff if needed */
	net_worker_run(ST_RRD, LOC_STICKY, update_locator_hostdata);

	setup_signalhandler("xymond_rrd");
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sig_handler;
	sigaction(SIGHUP, &sa, NULL);
	sigaction(SIGCHLD, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGINT, &sa, NULL);
	signal(SIGPIPE, SIG_DFL);

	/* Setup the control socket that receives cache-flush commands */
	memset(&ctlsockaddr, 0, sizeof(ctlsockaddr));
	sprintf(ctlsockaddr.sun_path, "%s/rrdctl.%d", xgetenv("XYMONTMP"), getpid());
	unlink(ctlsockaddr.sun_path);     /* In case it was accidentally left behind */
	ctlsockaddr.sun_family = AF_UNIX;
	ctlsocket = socket(AF_UNIX, SOCK_DGRAM, 0);
	if (ctlsocket == -1) {
		errprintf("Cannot create cache-control socket (%s)\n", strerror(errno));
		return 1;
	}
	fcntl(ctlsocket, F_SETFL, O_NONBLOCK);
	if (bind(ctlsocket, (struct sockaddr *)&ctlsockaddr, sizeof(ctlsockaddr)) == -1) {
		errprintf("Cannot bind to cache-control socket (%s)\n", strerror(errno));
		return 1;
	}
	/* Linux obeys filesystem permissions on the socket file, so make it world-accessible */
	if (chmod(ctlsockaddr.sun_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) == -1) {
		errprintf("Setting permissions on cache-control socket failed: %s\n", strerror(errno));
	}

	/* Load the RRD definitions */
	load_rrddefs();

	/* If we are passing data to an external processor, create the pipe to it */
	setup_extprocessor(processor);

	running = 1;
	while (running) {
		char *eoln, *restofmsg = NULL;
		char *metadata[MAX_META+1];
		int metacount;
		char *p;
		char *hostname = NULL, *testname = NULL, *sender = NULL, *classname = NULL, *pagepaths = NULL;
		xymonrrd_t *ldef = NULL;
		time_t tstamp;
		int childstat;
                ssize_t n;
		char ctlbuf[PATH_MAX];
		int gotcachectlmessage;
		time_t now;

		/* See if we have any cache-control messages pending */
		do {
			n = recv(ctlsocket, ctlbuf, sizeof(ctlbuf), 0);
			gotcachectlmessage = (n > 0);
			if (gotcachectlmessage) {
				/* We have a control message */
				char *bol, *eol;

				ctlbuf[n] = '\0';
				bol = ctlbuf;
				do {
					eol = strchr(bol, '\n'); if (eol) *eol = '\0';
					rrdcacheflushhost(bol);
					if (eol) { bol = eol+1; } else bol = NULL;
				} while (bol && *bol);
			}
		} while (gotcachectlmessage);

		/* Get next message */
		msg = get_xymond_message(C_LAST, argv[0], &seq, NULL);
		if (msg == NULL) {
			running = 0;
			continue;
		}

		now = gettimer();
		if (reloadtime < now) {
			/* Reload configuration files */
			load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
			load_client_config(NULL);
			reloadtime = now + 600;
		}

		/* Split the message in the first line (with meta-data), and the rest */
 		eoln = strchr(msg, '\n');
		if (eoln) {
			*eoln = '\0';
			restofmsg = eoln+1;
		}

		/* Parse the meta-data */
		metacount = 0; 
		memset(&metadata, 0, sizeof(metadata));
		p = gettok(msg, "|");
		while (p && (metacount < MAX_META)) {
			metadata[metacount++] = p;
			p = gettok(NULL, "|");
		}
		metadata[metacount] = NULL;

		if ((metacount >= 14) && (strncmp(metadata[0], "@@status", 8) == 0)) {
			/*
			 * @@status|timestamp|sender|origin|hostname|testname|expiretime|color|testflags|\
			 * prevcolor|changetime|ackexpiretime|ackmessage|disableexpiretime|disablemessage|\
			 * clienttstamp|flapping|classname|pagepaths
			 */
			int color = parse_color(metadata[7]);

			switch (color) {
			  case COL_GREEN:
			  case COL_YELLOW:
			  case COL_RED:
			  case COL_BLUE: /* Blue is OK, because it only arrives here when an update is sent */
				tstamp = atoi(metadata[1]);
				sender = metadata[2];
				hostname = metadata[4]; 
				testname = metadata[5];
				classname = (metadata[17] ? metadata[17] : "");
				pagepaths = (metadata[18] ? metadata[18] : "");
				ldef = find_xymon_rrd(testname, metadata[8]);
				update_rrd(hostname, testname, restofmsg, tstamp, sender, ldef, classname, pagepaths);
				break;

			  default:
				/* Ignore reports with purple, blue or clear - they have no data we want. */
				break;
			}
		}
		else if ((metacount > 5) && (strncmp(metadata[0], "@@data", 6) == 0)) {
			/* @@data|timestamp|sender|origin|hostname|testname|classname|pagepaths */
			tstamp = atoi(metadata[1]);
			sender = metadata[2];
			hostname = metadata[4]; 
			testname = metadata[5];
			classname = (metadata[6] ? metadata[6] : "");
			pagepaths = (metadata[7] ? metadata[7] : "");
			ldef = find_xymon_rrd(testname, "");
			update_rrd(hostname, testname, restofmsg, tstamp, sender, ldef, classname, pagepaths);
		}
		else if (strncmp(metadata[0], "@@shutdown", 10) == 0) {
			running = 0;
			continue;
		}
		else if (strncmp(metadata[0], "@@idle", 6) == 0) {
			/* Ignored */
			continue;
		}
		else if (strncmp(metadata[0], "@@logrotate", 11) == 0) {
			char *fn = xgetenv("XYMONCHANNEL_LOGFILENAME");
			if (fn && strlen(fn)) {
				freopen(fn, "a", stdout);
				freopen(fn, "a", stderr);
			}
			continue;
		}
		else if (strncmp(metadata[0], "@@reload", 8) == 0) {
			reloadtime = 0;
		}
		else if ((metacount > 3) && (strncmp(metadata[0], "@@drophost", 10) == 0)) {
			char hostdir[PATH_MAX];
			hostname = metadata[3];

			MEMDEFINE(hostdir);

			sprintf(hostdir, "%s/%s", rrddir, hostname);
			dropdirectory(hostdir, 1);

			MEMUNDEFINE(hostdir);
		}
		else if ((metacount > 4) && (strncmp(metadata[0], "@@droptest", 10) == 0)) {
			/*
			 * Not implemented. Mappings of testnames -> rrd files is
			 * too complex, so on the rare occasion that a single test
			 * is deleted, they will have to delete the rrd files themselves.
			 */
		}
		else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) {
			char oldhostdir[PATH_MAX];
			char newhostdir[PATH_MAX];
			char *newhostname;

			MEMDEFINE(oldhostdir);
			MEMDEFINE(newhostdir);

			hostname = metadata[3];
			newhostname = metadata[4];
			sprintf(oldhostdir, "%s/%s", rrddir, hostname);
			sprintf(newhostdir, "%s/%s", rrddir, newhostname);
			rename(oldhostdir, newhostdir);

			if (net_worker_locatorbased()) locator_rename_host(hostname, newhostname, ST_RRD);

			MEMUNDEFINE(newhostdir);
			MEMUNDEFINE(oldhostdir);
		}
		else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) {
			/* Not implemented. See "droptest". */
		}

		/* 
		 * We fork a subprocess when processing drophost requests.
		 * Pickup any finished child processes to avoid zombies
		 */
		while (wait3(&childstat, WNOHANG, NULL) > 0) ;
	}

	/* Flush all cached updates to disk */
	errprintf("Shutting down, flushing cached updates to disk\n");
	rrdcacheflushall();
	errprintf("Cache flush completed\n");

	/* Close the external processor */
	shutdown_extprocessor();

	/* Close the control socket */
	close(ctlsocket);
	unlink(ctlsockaddr.sun_path);

	return 0;
}
Ejemplo n.º 26
0
Archivo: tlog-rec.c Proyecto: opuk/tlog
int
main(int argc, char **argv)
{
    const int exit_sig[] = {SIGINT, SIGTERM, SIGHUP};
    char *fqdn = NULL;
    struct passwd *passwd;
    struct tlog_writer *writer = NULL;
    clockid_t clock_id;
    struct timespec timestamp;
    struct tlog_sink *sink = NULL;
    tlog_grc grc;
    ssize_t rc;
    int master_fd;
    pid_t child_pid;
    unsigned int session_id;
    sig_atomic_t last_sigwinch_caught = 0;
    sig_atomic_t new_sigwinch_caught;
    sig_atomic_t last_alarm_caught = 0;
    sig_atomic_t new_alarm_caught;
    bool alarm_set = false;
    bool io_pending = false;
    bool term_attrs_set = false;
    struct termios orig_termios;
    struct termios raw_termios;
    struct winsize winsize;
    struct winsize new_winsize;
    size_t i, j;
    struct sigaction sa;
    struct pollfd fds[FD_IDX_NUM];
    uint8_t input_buf[BUF_SIZE];
    size_t input_pos = 0;
    size_t input_len = 0;
    uint8_t output_buf[BUF_SIZE];
    size_t output_pos = 0;
    size_t output_len = 0;
    struct tlog_pkt pkt = TLOG_PKT_VOID;
    int status = 1;

    (void)argv;
    if (argc > 1) {
        fprintf(stderr, "Arguments are not accepted\n");
        goto cleanup;
    }

    /* Get host FQDN */
    grc = get_fqdn(&fqdn);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed retrieving host FQDN: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Get session ID */
    grc = get_session_id(&session_id);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed retrieving session ID: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Open syslog */
    openlog("tlog", LOG_NDELAY, LOG_LOCAL0);
    /* Create the syslog writer */
    grc = tlog_syslog_writer_create(&writer, LOG_INFO);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed creating syslog writer: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Get effective user entry */
    errno = 0;
    passwd = getpwuid(geteuid());
    if (passwd == NULL) {
        if (errno == 0)
            fprintf(stderr, "User entry not found\n");
        else
            fprintf(stderr, "Failed retrieving user entry: %s\n",
                    strerror(errno));
        goto cleanup;
    }

    /*
     * Choose the clock: try to use coarse monotonic clock (which is faster),
     * if it provides resolution of at least one millisecond.
     */
    if (clock_getres(CLOCK_MONOTONIC_COARSE, &timestamp) == 0 &&
        timestamp.tv_sec == 0 && timestamp.tv_nsec < 1000000) {
        clock_id = CLOCK_MONOTONIC_COARSE;
    } else if (clock_getres(CLOCK_MONOTONIC, NULL) == 0) {
        clock_id = CLOCK_MONOTONIC;
    } else {
        fprintf(stderr, "No clock to use\n");
        goto cleanup;
    }

    /* Create the log sink */
    grc = tlog_sink_create(&sink, writer, fqdn, passwd->pw_name,
                           session_id, BUF_SIZE);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed creating log sink: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Get terminal attributes */
    rc = tcgetattr(STDOUT_FILENO, &orig_termios);
    if (rc < 0) {
        fprintf(stderr, "Failed retrieving tty attributes: %s\n",
                strerror(errno));
        goto cleanup;
    }

    /* Get terminal window size */
    rc = ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize);
    if (rc < 0) {
        fprintf(stderr, "Failed retrieving tty window size: %s\n",
                strerror(errno));
        goto cleanup;
    }

    /* Fork a child under a slave pty */
    child_pid = forkpty(&master_fd, NULL, &orig_termios, &winsize);
    if (child_pid < 0) {
        fprintf(stderr, "Failed forking a pty: %s\n", strerror(errno));
        goto cleanup;
    } else if (child_pid == 0) {
        /*
         * Child
         */
        execl("/bin/bash", "/bin/bash", NULL);
        fprintf(stderr, "Failed to execute the shell: %s",
                strerror(errno));
        goto cleanup;
    }

    /*
     * Parent
     */
    /* Log initial window size */
    clock_gettime(clock_id, &timestamp);
    tlog_pkt_init_window(&pkt, &timestamp,
                         winsize.ws_col, winsize.ws_row);
    grc = tlog_sink_write(sink, &pkt);
    tlog_pkt_cleanup(&pkt);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed logging window size: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Setup signal handlers to terminate gracefully */
    for (i = 0; i < ARRAY_SIZE(exit_sig); i++) {
        sigaction(exit_sig[i], NULL, &sa);
        if (sa.sa_handler != SIG_IGN)
        {
            sa.sa_handler = exit_sighandler;
            sigemptyset(&sa.sa_mask);
            for (j = 0; j < ARRAY_SIZE(exit_sig); j++)
                sigaddset(&sa.sa_mask, exit_sig[j]);
            /* NOTE: no SA_RESTART on purpose */
            sa.sa_flags = 0;
            sigaction(exit_sig[i], &sa, NULL);
        }
    }

    /* Setup WINCH signal handler */
    sa.sa_handler = winch_sighandler;
    sigemptyset(&sa.sa_mask);
    /* NOTE: no SA_RESTART on purpose */
    sa.sa_flags = 0;
    sigaction(SIGWINCH, &sa, NULL);

    /* Setup ALRM signal handler */
    sa.sa_handler = alarm_sighandler;
    sigemptyset(&sa.sa_mask);
    /* NOTE: no SA_RESTART on purpose */
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);

    /* Switch the terminal to raw mode */
    raw_termios = orig_termios;
    raw_termios.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
    raw_termios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR |
                             INPCK | ISTRIP | IXON | PARMRK);
    raw_termios.c_oflag &= ~OPOST;
    raw_termios.c_cc[VMIN] = 1;
    raw_termios.c_cc[VTIME] = 0;
    rc = tcsetattr(STDOUT_FILENO, TCSAFLUSH, &raw_termios);
    if (rc < 0) {
        fprintf(stderr, "Failed setting tty attributes: %s\n",
                strerror(errno));
        goto cleanup;
    }
    term_attrs_set = true;

    /*
     * Transfer I/O and window changes
     */
    fds[FD_IDX_STDIN].fd        = STDIN_FILENO;
    fds[FD_IDX_STDIN].events    = POLLIN;
    fds[FD_IDX_MASTER].fd       = master_fd;
    fds[FD_IDX_MASTER].events   = POLLIN;

    while (exit_signum == 0) {
        /*
         * Handle SIGWINCH
         */
        new_sigwinch_caught = sigwinch_caught;
        if (new_sigwinch_caught != last_sigwinch_caught) {
            /* Retrieve window size */
            rc = ioctl(STDOUT_FILENO, TIOCGWINSZ, &new_winsize);
            if (rc < 0) {
                if (errno == EBADF)
                    status = 0;
                else
                    fprintf(stderr, "Failed retrieving window size: %s\n",
                            strerror(errno));
                break;
            }
            /* If window size has changed */
            if (new_winsize.ws_row != winsize.ws_row ||
                new_winsize.ws_col != winsize.ws_col) {
                /* Log window size */
                clock_gettime(clock_id, &timestamp);
                tlog_pkt_init_window(&pkt, &timestamp,
                                     new_winsize.ws_col,
                                     new_winsize.ws_row);
                grc = tlog_sink_write(sink, &pkt);
                tlog_pkt_cleanup(&pkt);
                if (grc != TLOG_RC_OK) {
                    fprintf(stderr, "Failed logging window size: %s\n",
                            tlog_grc_strerror(grc));
                    break;
                }
                /* Propagate window size */
                rc = ioctl(master_fd, TIOCSWINSZ, &new_winsize);
                if (rc < 0) {
                    if (errno == EBADF)
                        status = 0;
                    else
                        fprintf(stderr, "Failed setting window size: %s\n",
                                strerror(errno));
                    break;
                }
                winsize = new_winsize;
            }
            /* Mark SIGWINCH processed */
            last_sigwinch_caught = new_sigwinch_caught;
        }

        /*
         * Deliver I/O
         */
        clock_gettime(clock_id, &timestamp);

        if (input_pos < input_len) {
            rc = write(master_fd, input_buf + input_pos,
                       input_len - input_pos);
            if (rc >= 0) {
                if (rc > 0) {
                    /* Log delivered input */
                    tlog_pkt_init_io(&pkt, &timestamp,
                                     false, input_buf + input_pos,
                                     false, (size_t)rc);
                    grc = tlog_sink_write(sink, &pkt);
                    tlog_pkt_cleanup(&pkt);
                    if (grc != TLOG_RC_OK) {
                        fprintf(stderr, "Failed logging input: %s\n",
                                tlog_grc_strerror(grc));
                        break;
                    }
                    io_pending = true;
                    input_pos += rc;
                }
                /* If interrupted by a signal handler */
                if (input_pos < input_len)
                    continue;
                /* Exhausted */
                input_pos = input_len = 0;
            } else {
                if (errno == EINTR)
                    continue;
                else if (errno == EBADF || errno == EINVAL)
                    status = 0;
                else
                    fprintf(stderr, "Failed to write to master: %s\n",
                            strerror(errno));
                break;
            };
        }
        if (output_pos < output_len) {
            rc = write(STDOUT_FILENO, output_buf + output_pos,
                       output_len - output_pos);
            if (rc >= 0) {
                if (rc > 0) {
                    /* Log delivered output */
                    tlog_pkt_init_io(&pkt, &timestamp,
                                     true, output_buf + output_pos,
                                     false, (size_t)rc);
                    grc = tlog_sink_write(sink, &pkt);
                    tlog_pkt_cleanup(&pkt);
                    if (grc != TLOG_RC_OK) {
                        fprintf(stderr, "Failed logging output: %s\n",
                                tlog_grc_strerror(grc));
                        break;
                    }
                    io_pending = true;
                    output_pos += rc;
                }
                /* If interrupted by a signal handler */
                if (output_pos < output_len)
                    continue;
                /* Exhausted */
                output_pos = output_len = 0;
            } else {
                if (errno == EINTR)
                    continue;
                else if (errno == EBADF || errno == EINVAL)
                    status = 0;
                else
                    fprintf(stderr, "Failed to write to stdout: %s\n",
                            strerror(errno));
                break;
            };
        }

        /*
         * Handle I/O latency limit
         */
        new_alarm_caught = alarm_caught;
        if (new_alarm_caught != last_alarm_caught) {
            alarm_set = false;
            grc = tlog_sink_flush(sink);
            if (grc != TLOG_RC_OK) {
                fprintf(stderr, "Failed flushing I/O log: %s\n",
                        tlog_grc_strerror(grc));
                goto cleanup;
            }
            last_alarm_caught = new_alarm_caught;
            io_pending = false;
        } else if (io_pending && !alarm_set) {
            alarm(IO_LATENCY);
            alarm_set = true;
        }

        /*
         * Wait for I/O
         */
        rc = poll(fds, sizeof(fds) / sizeof(fds[0]), -1);
        if (rc < 0) {
            if (errno == EINTR)
                continue;
            else
                fprintf(stderr, "Failed waiting for I/O: %s\n",
                        strerror(errno));
            break;
        }

        /*
         * Retrieve I/O
         *
         * NOTE: Reading master first in case child went away.
         *       Otherwise writing to it can block
         */
        if (fds[FD_IDX_MASTER].revents & (POLLIN | POLLHUP | POLLERR)) {
            rc = read(master_fd, output_buf, sizeof(output_buf));
            if (rc <= 0) {
                if (rc < 0 && errno == EINTR)
                    continue;
                status = 0;
                break;
            }
            output_len = rc;
        }
        if (fds[FD_IDX_STDIN].revents & (POLLIN | POLLHUP | POLLERR)) {
            rc = read(STDIN_FILENO, input_buf, sizeof(input_buf));
            if (rc <= 0) {
                if (rc < 0 && errno == EINTR)
                    continue;
                status = 0;
                break;
            }
            input_len = rc;
        }
    }

    /* Cut I/O log (write incomplete characters as binary) */
    grc = tlog_sink_cut(sink);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed cutting-off I/O log: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Flush I/O log */
    grc = tlog_sink_flush(sink);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed flushing I/O log: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

cleanup:

    tlog_sink_destroy(sink);
    tlog_writer_destroy(writer);
    free(fqdn);

    /* Restore signal handlers */
    for (i = 0; i < ARRAY_SIZE(exit_sig); i++) {
        sigaction(exit_sig[i], NULL, &sa);
        if (sa.sa_handler != SIG_IGN)
            signal(exit_sig[i], SIG_DFL);
    }

    /* Restore terminal attributes */
    if (term_attrs_set) {
        rc = tcsetattr(STDOUT_FILENO, TCSAFLUSH, &orig_termios);
        if (rc < 0 && errno != EBADF) {
            fprintf(stderr, "Failed restoring tty attributes: %s\n",
                    strerror(errno));
            return 1;
        }
    }

    /* Reproduce the exit signal to get proper exit status */
    if (exit_signum != 0)
        raise(exit_signum);

    return status;
}
Ejemplo n.º 27
0
int main(int argc, char *argv[])
{
    int argi, hosti, testi;
    char *pagepattern = NULL, *hostpattern = NULL;
    char *envarea = NULL, *cookie = NULL, *nexthost;
    char *hobbitcmd, *procscmd, *svcscmd;
    int alertcolors, alertinterval;
    char configfn[PATH_MAX];
    char *respbuf = NULL, *procsbuf = NULL, *svcsbuf = NULL;
    hostlist_t *hwalk;
    htnames_t *twalk;
    hostlist_t **allhosts = NULL;
    htnames_t **alltests = NULL;
    int hostcount = 0, maxtests = 0;
    time_t now = getcurrenttime(NULL);
    sendreturn_t *sres;

    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;
        }
        else if (argnmatch(argv[argi], "--delimiter=")) {
            char *p = strchr(argv[argi], '=');
            coldelim = strdup(p+1);
        }
        else if (strcmp(argv[argi], "--critical") == 0) {
            nkonly = 1;
        }
        else if (strcmp(argv[argi], "--old-nk-config") == 0) {
            newnkconfig = 0;
        }
    }

    redirect_cgilog("hobbit-confreport");

    load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn());
    load_nkconfig(NULL);

    /* Setup the filter we use for the report */
    cookie = get_cookie("pagepath");
    if (cookie && *cookie) pagepattern = strdup(cookie);
    cookie = get_cookie("host");
    if (cookie && *cookie) hostpattern = strdup(cookie);

    /* Fetch the list of host+test statuses we currently know about */
    if (pagepattern) {
        hobbitcmd = (char *)malloc(2*strlen(pagepattern) + 1024);
        procscmd = (char *)malloc(2*strlen(pagepattern) + 1024);
        svcscmd = (char *)malloc(2*strlen(pagepattern) + 1024);

        sprintf(hobbitcmd, "hobbitdboard page=^%s$|^%s/.+ fields=hostname,testname",
                pagepattern, pagepattern);
        sprintf(procscmd,  "hobbitdboard page=^%s$|^%s/.+ test=procs fields=hostname,msg",
                pagepattern, pagepattern);
        sprintf(svcscmd,   "hobbitdboard page=^%s$|^%s/.+ test=svcs fields=hostname,msg",
                pagepattern, pagepattern);
    }
    else if (hostpattern) {
        hobbitcmd = (char *)malloc(strlen(hostpattern) + 1024);
        procscmd = (char *)malloc(strlen(hostpattern) + 1024);
        svcscmd = (char *)malloc(strlen(hostpattern) + 1024);

        sprintf(hobbitcmd, "hobbitdboard host=^%s$ fields=hostname,testname", hostpattern);
        sprintf(procscmd,  "hobbitdboard host=^%s$ test=procs fields=hostname,msg", hostpattern);
        sprintf(svcscmd,   "hobbitdboard host=^%s$ test=svcs fields=hostname,msg", hostpattern);
    }
    else {
        hobbitcmd = (char *)malloc(1024);
        procscmd = (char *)malloc(1024);
        svcscmd = (char *)malloc(1024);

        sprintf(hobbitcmd, "hobbitdboard fields=hostname,testname");
        sprintf(procscmd,  "hobbitdboard test=procs fields=hostname,msg");
        sprintf(svcscmd,   "hobbitdboard test=svcs fields=hostname,msg");
    }

    sres = newsendreturnbuf(1, NULL);

    if (sendmessage(hobbitcmd, NULL, BBTALK_TIMEOUT, sres) != BB_OK) {
        errormsg("Cannot contact the Hobbit server\n");
        return 1;
    }
    respbuf = getsendreturnstr(sres, 1);
    if (sendmessage(procscmd, NULL, BBTALK_TIMEOUT, sres) != BB_OK) {
        errormsg("Cannot contact the Hobbit server\n");
        return 1;
    }
    procsbuf = getsendreturnstr(sres, 1);
    if (sendmessage(svcscmd, NULL, BBTALK_TIMEOUT, sres) != BB_OK) {
        errormsg("Cannot contact the Hobbit server\n");
        return 1;
    }
    svcsbuf = getsendreturnstr(sres, 1);

    freesendreturnbuf(sres);

    if (!respbuf) {
        errormsg("Unable to find host information\n");
        return 1;
    }

    /* Parse it into a usable list */
    nexthost = respbuf;
    do {
        char *hname, *tname, *eoln;
        int wanted = 1;

        eoln = strchr(nexthost, '\n');
        if (eoln) *eoln = '\0';
        hname = nexthost;
        tname = strchr(nexthost, '|');
        if (tname) {
            *tname = '\0';
            tname++;
        }

        if (nkonly) {
            void *hinfo = hostinfo(hname);
            char *nkalerts = bbh_item(hinfo, BBH_NK);

            if (newnkconfig) {
                if (strcmp(nkval(hname, tname, nkalerts), "No") == 0 ) wanted = 0;
            } else {
                if (!nkalerts) wanted = 0;
            }
        }

        if (wanted && hname && tname && strcmp(hname, "summary") && strcmp(tname, xgetenv("INFOCOLUMN")) && strcmp(tname, xgetenv("TRENDSCOLUMN"))) {
            htnames_t *newitem = (htnames_t *)malloc(sizeof(htnames_t));

            for (hwalk = hosthead; (hwalk && strcmp(hwalk->hostname, hname)); hwalk = hwalk->next);
            if (!hwalk) {
                hwalk = (hostlist_t *)calloc(1, sizeof(hostlist_t));
                hwalk->hostname = strdup(hname);
                hwalk->procs = get_proclist(hname, procsbuf);
                hwalk->svcs  = get_proclist(hname, svcsbuf);
                hwalk->next = hosthead;
                hosthead = hwalk;
                hostcount++;
            }

            newitem->name = strdup(tname);
            newitem->next = hwalk->tests;
            hwalk->tests = newitem;
            hwalk->testcount++;
        }

        if (eoln) {
            nexthost = eoln+1;
            if (*nexthost == '\0') nexthost = NULL;
        }
    } while (nexthost);

    allhosts = (hostlist_t **) malloc(hostcount * sizeof(hostlist_t *));
    for (hwalk = hosthead, hosti=0; (hwalk); hwalk = hwalk->next, hosti++) {
        allhosts[hosti] = hwalk;
        if (hwalk->testcount > maxtests) maxtests = hwalk->testcount;
    }
    alltests = (htnames_t **) malloc(maxtests * sizeof(htnames_t *));
    qsort(&allhosts[0], hostcount, sizeof(hostlist_t **), host_compare);

    /* Get the static info */
    load_all_links();
    init_tcp_services();
    pingcolumn = xgetenv("PINGCOLUMN");
    pingplus = (char *)malloc(strlen(pingcolumn) + 2);
    sprintf(pingplus, "%s=", pingcolumn);

    /* Load alert config */
    alertcolors = colorset(xgetenv("ALERTCOLORS"), ((1 << COL_GREEN) | (1 << COL_BLUE)));
    alertinterval = 60*atoi(xgetenv("ALERTREPEAT"));
    sprintf(configfn, "%s/etc/hobbit-alerts.cfg", xgetenv("BBHOME"));
    load_alertconfig(configfn, alertcolors, alertinterval);
    load_columndocs();


    printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
    sethostenv("", "", "", colorname(COL_BLUE), NULL);
    headfoot(stdout, "confreport", "", "header", COL_BLUE);

    fprintf(stdout, "<table width=\"100%%\" border=0>\n");
    fprintf(stdout, "<tr><th align=center colspan=2><font size=\"+2\">Hobbit configuration Report</font></th></tr>\n");
    fprintf(stdout, "<tr><th valign=top align=left>Date</th><td>%s</td></tr>\n", ctime(&now));
    fprintf(stdout, "<tr><th valign=top align=left>%d hosts included</th><td>\n", hostcount);
    for (hosti=0; (hosti < hostcount); hosti++) {
        fprintf(stdout, "%s ", allhosts[hosti]->hostname);
    }
    fprintf(stdout, "</td></tr>\n");
    if (nkonly) {
        fprintf(stdout, "<tr><th valign=top align=left>Filter</th><td>Only data for the &quot;Critical Systems&quot; view reported</td></tr>\n");
    }
    fprintf(stdout, "</table>\n");

    headfoot(stdout, "confreport", "", "front", COL_BLUE);

    for (hosti=0; (hosti < hostcount); hosti++) {
        for (twalk = allhosts[hosti]->tests, testi = 0; (twalk); twalk = twalk->next, testi++) {
            alltests[testi] = twalk;
        }
        qsort(&alltests[0], allhosts[hosti]->testcount, sizeof(htnames_t **), test_compare);

        print_host(allhosts[hosti], alltests, allhosts[hosti]->testcount);
    }

    headfoot(stdout, "confreport", "", "back", COL_BLUE);
    print_columndocs();

    headfoot(stdout, "confreport", "", "footer", COL_BLUE);

    return 0;
}
Ejemplo n.º 28
0
int main(int argc, char *argv[])
{
	FILE	*pf;
	char	buff[BUFSIZE];
	int		length, c;
	char	*delim, *delim2;

	/* some initialisation to be shure */
	file_b=uri_b=trace=lport=usrloc=flood=verbose=randtrash=trashchar = 0;
	numeric=warning_ext=rand_rem=nonce_count=replace_b=invite=message = 0;
	sleep_ms = 0;
	namebeg=nameend=maxforw= -1;
	via_ins=redirects = 1;
	username=password=replace_str=hostname = NULL;
	address = 0;
    rport = 5060;
	expires_t = USRLOC_EXP_DEF;
	memset(buff, 0, BUFSIZE);
	memset(confirm, 0, BUFSIZE);
	memset(ack, 0, BUFSIZE);
	memset(fqdn, 0, FQDN_SIZE);
	memset(messusern, 0, FQDN_SIZE);

	if (argc==1) print_help();

	/* lots of command line switches to handle*/
	while ((c=getopt(argc,argv,"a:b:c:de:f:Fg:GhH:iIl:m:Mno:r:Rs:t:TUvVwx:z")) != EOF){
		switch(c){
			case 'a':
				password=malloc(strlen(optarg));
				strncpy(password, optarg, strlen(optarg));
				break;
			case 'b':
				if ((namebeg=atoi(optarg))==-1) {
					printf("error: non-numerical appendix begin for the "
						"username\n");
					exit(2);
				}
				break;
			case 'c':
				if ((namebeg=atoi(optarg))==-1) {
					printf("error: non-numerical CSeq maximum\n");
					exit(2);
				}
				break;
			case 'd':
				redirects=0;
				break;
			case 'e':
				if ((nameend=atoi(optarg))==-1) {
					printf("error: non-numerical appendix end for the "
						"username\n");
					exit(2);
				}
				break;
			case 'F':
				flood=1;
				break;
			case 'f':
				/* file is opened in binary mode so that the cr-lf is 
				   preserved */
				pf = fopen(optarg, "rb");
				if (!pf){
					puts("unable to open the file.\n");
					exit(2);
				}
				length  = fread(buff, 1, sizeof(buff), pf);
				if (length >= sizeof(buff)){
					printf("error:the file is too big. try files of less "
						"than %i bytes.\n", BUFSIZE);
					printf("      or recompile the program with bigger "
						"BUFSIZE defined.\n");
					exit(2);
				}
				fclose(pf);
				buff[length] = '\0';
				file_b=1;
				break;
			case 'g':
				replace_str=optarg;
				break;
			case 'G':
				replace_b=1;
				break;
			case 'h':
				print_help();
				break;
			case 'H':
				hostname=optarg;
				break;
			case 'i':
				via_ins=0;
				break;
			case 'I':
				invite=1;
				break;
			case 'l':
				lport=atoi(optarg);
				if (!lport) {
					puts("error: non-numerical local port number");
					exit(2);
				}
				break;
			case 'm':
				maxforw=atoi(optarg);
				if (maxforw==-1) {
					printf("error: non-numerical number of max-forwards\n");
					exit(2);
				}
				break;
			case 'M':
				message=1;
				break;
			case 'n':
				numeric = 1;
				break;
			case 'o':
				sleep_ms = 0;
				if (strncmp(optarg, "rand", 4)==0) {
					sleep_ms = -2;
				}
				else {
					sleep_ms = atoi(optarg);
					if (!sleep_ms) {
						printf("error: non-numerical sleep value\n");
						exit(2);
					}
				}
				break;
			case 'r':
				rport=atoi(optarg);
				if (!rport) {
					printf("error: non-numerical remote port number\n");
					exit(2);
				}
				break;
			case 'R':
				randtrash=1;
				break;
			case 's':
				/* we try to extract as much informationas we can from the uri*/
				if (!strncmp(optarg,"sip",3)){
					if ((delim=strchr(optarg,':'))!=NULL){
						delim++;
						if ((delim2=strchr(delim,'@'))!=NULL){
							username=malloc(delim2-delim+1);
							strncpy(username, delim, delim2-delim);
							*(username+(delim2-delim)) = '\0';
							delim2++;
							delim=delim2;
						}
						if ((delim2=strchr(delim,':'))!=NULL){
							domainname=malloc(strlen(delim)+1);
							strncpy(domainname, delim, strlen(delim));
							*(domainname+strlen(delim)) = '\0';
							*delim2 = '\0';
							delim2++;
							rport = atoi(delim2);
							if (!rport) {
								printf("error: non-numerical remote port "
									"number\n");
								exit(2);
							}
						}
						else {
							domainname=malloc(strlen(delim)+1);
							strncpy(domainname, delim, strlen(delim));
							*(domainname+strlen(delim)) = '\0';
						}
						address = getaddress(delim);
						if (!address){
							printf("error:unable to determine the remote host "
								"address\n");
							exit(2);
						}
					}
					else{
						printf("error: sip:uri doesn't contain a : ?!\n");
						exit(2);
					}
				}
				else{
					printf("error: sip:uri doesn't not begin with sip\n");
					exit(2);
				}
				uri_b=1;
				break;			break;
			case 't':
				trashchar=atoi(optarg);
				if (!trashchar) {
					printf("error: non-numerical number of trashed "
						"character\n");
					exit(2);
				}
				break;
			case 'T':
				trace=1;
				break;
			case 'U':
				usrloc=1;
				break;
			case 'v':
				verbose++;
				break;
			case 'V':
				printf("sipsak %s   by Nils Ohlmeier\n Copyright (C) 2002-2003"
						" FhG Fokus\n", SIPSAK_VERSION);
				exit(0);
				break;
			case 'w':
				warning_ext=1;
				break;
			case 'x':
				expires_t=atoi(optarg);
				break;
			case 'z':
				rand_rem=1;
				break;
			default:
				printf("error: unknown parameter %c\n", c);
				exit(2);
				break;
		}
	}

	/* lots of conditions to check */
	if (trace) {
		if (usrloc || flood || randtrash) {
			printf("error: trace can't be combined with usrloc, random or "
				"flood\n");
			exit(2);
		}
		if (!uri_b) {
			printf("error: for trace mode a sip:uri is realy needed\n");
			exit(2);
		}
		if (file_b) {
			printf("warning: file will be ignored for tracing.");
		}
		if (!username) {
			printf("error: for trace mode without a file the sip:uir have to "
				"contain a username\n");
			exit(2);
		}
		if (!via_ins){
			printf("warning: Via-Line is needed for tracing. Ignoring -i\n");
			via_ins=1;
		}
		if (!warning_ext) {
			printf("warning: IP extract from warning activated to be more "
				"informational\n");
			warning_ext=1;
		}
		if (maxforw==-1) maxforw=255;
	}
	else if (usrloc || invite || message) {
		if (trace || flood || randtrash) {
			printf("error: usrloc can't be combined with trace, random or "
				"flood\n");
			exit(2);
		}
		if (!username || !uri_b) {
			printf("error: for the USRLOC mode you have to give a sip:uri with "
				"a username\n       at least\n");
			exit(2);
		}
		if (namebeg>0 && nameend==-1) {
			printf("error: if a starting numbers is given also an ending "
				"number have to be specified\n");
			exit(2);
		}
		if (invite && message) {
			printf("error: invite and message tests are XOR\n");
			exit(2);
		}
		if (!usrloc && invite && !lport) {
			printf("WARNING: Do NOT use the usrloc invite mode without "
				"registering sipsak before.\n         See man page for "
				"details.\n");
			exit(2);
		}
		if (via_ins) {
			via_ins=0;
		}
		if (redirects) {
			printf("warning: redirects are not expected in USRLOC. "
				"disableing\n");
			redirects=0;
		}
		if (nameend==-1)
			nameend=0;
		if (namebeg==-1)
			namebeg=0;
	}
	else if (flood) {
		if (trace || usrloc || randtrash) {
			printf("error: flood can't be combined with trace, random or "
				"usrloc\n");
			exit(2);
		}
		if (!uri_b) {
			printf("error: we need at least a sip uri for flood\n");
			exit(2);
		}
		if (redirects) {
			printf("warning: redirects are not expected in flood. "
				"disableing\n");
			redirects=0;
		}
	}
	else if (randtrash) {
		if (trace || usrloc || flood) {
			printf("error: random can't be combined with trace, flood or "
				"usrloc\n");
			exit(2);
		}
		if (!uri_b) {
			printf("error: need at least a sip uri for random\n");
			exit(2);
		}
		if (redirects) {
			printf("warning: redirects are not expected in random. "
				"disableing\n");
			redirects=0;
		}
		if (verbose) {
			printf("warning: random characters may destroy your terminal "
				"output\n");
		}
	}
	else {
		if (!uri_b) {
			printf("error: a spi uri is needed at least\n");
			exit(2);
		}
/*		if (!(username || file_b)) {
			printf("error: ether a file or an username in the sip uri is "
				"required\n");
			exit(2);
		}*/
		
	}
	/* determine our hostname */
	get_fqdn();
	
	/* this is not a cryptographic random number generator,
	   but hey this is only a test-tool => should be satisfying*/
	srand(time(0));

	/* here we go...*/
	shoot(buff);

	/* normaly we won't come back here, but to satisfy the compiler */
	return 0;
}
Ejemplo n.º 29
0
/**
 * Create the log sink according to configuration.
 *
 * @param psink Location for the created sink pointer.
 * @param conf  Configuration JSON object.
 *
 * @return Global return code.
 */
static tlog_grc
create_log_sink(struct tlog_sink **psink, struct json_object *conf)
{
    tlog_grc grc;
    int64_t num;
    const char *str;
    struct json_object *obj;
    struct tlog_sink *sink = NULL;
    struct tlog_json_writer *writer = NULL;
    int fd = -1;
    char *fqdn = NULL;
    struct passwd *passwd;
    unsigned int session_id;

    /*
     * Create the writer
     */
    if (!json_object_object_get_ex(conf, "writer", &obj)) {
        fprintf(stderr, "Writer type is not specified\n");
        grc = TLOG_RC_FAILURE;
        goto cleanup;
    }
    str = json_object_get_string(obj);
    if (strcmp(str, "file") == 0) {
        struct json_object *conf_file;

        /* Get file writer conf container */
        if (!json_object_object_get_ex(conf, "file", &conf_file)) {
            fprintf(stderr, "File writer parameters are not specified\n");
            grc = TLOG_RC_FAILURE;
            goto cleanup;
        }

        /* Get the file path */
        if (!json_object_object_get_ex(conf_file, "path", &obj)) {
            fprintf(stderr, "Log file path is not specified\n");
            grc = TLOG_RC_FAILURE;
            goto cleanup;
        }
        str = json_object_get_string(obj);

        /* Open the file */
        fd = open(str, O_WRONLY | O_CREAT | O_APPEND, S_IRWXU | S_IRWXG);
        if (fd < 0) {
            grc = TLOG_GRC_ERRNO;
            fprintf(stderr, "Failed opening log file \"%s\": %s\n",
                    str, tlog_grc_strerror(grc));
            goto cleanup;
        }

        /* Create the writer, letting it take over the FD */
        grc = tlog_fd_json_writer_create(&writer, fd, true);
        if (grc != TLOG_RC_OK) {
            fprintf(stderr, "Failed creating file writer: %s\n",
                    tlog_grc_strerror(grc));
            goto cleanup;
        }
        fd = -1;
    } else if (strcmp(str, "syslog") == 0) {
        struct json_object *conf_syslog;
        int facility;
        int priority;

        /* Get syslog writer conf container */
        if (!json_object_object_get_ex(conf, "syslog", &conf_syslog)) {
            fprintf(stderr, "Syslog writer parameters are not specified\n");
            grc = TLOG_RC_FAILURE;
            goto cleanup;
        }

        /* Get facility */
        if (!json_object_object_get_ex(conf_syslog, "facility", &obj)) {
            fprintf(stderr, "Syslog facility is not specified\n");
            grc = TLOG_RC_FAILURE;
            goto cleanup;
        }
        str = json_object_get_string(obj);
        facility = tlog_syslog_facility_from_str(str);
        if (facility < 0) {
            fprintf(stderr, "Unknown syslog facility: %s\n", str);
            grc = TLOG_RC_FAILURE;
            goto cleanup;
        }

        /* Get priority */
        if (!json_object_object_get_ex(conf_syslog, "priority", &obj)) {
            fprintf(stderr, "Syslog priority is not specified\n");
            grc = TLOG_RC_FAILURE;
            goto cleanup;
        }
        str = json_object_get_string(obj);
        priority = tlog_syslog_priority_from_str(str);
        if (priority < 0) {
            fprintf(stderr, "Unknown syslog priority: %s\n", str);
            grc = TLOG_RC_FAILURE;
            goto cleanup;
        }

        /* Create the writer */
        openlog("tlog", LOG_NDELAY, facility);
        grc = tlog_syslog_json_writer_create(&writer, priority);
        if (grc != TLOG_RC_OK) {
            fprintf(stderr, "Failed creating syslog writer: %s\n",
                    tlog_grc_strerror(grc));
            goto cleanup;
        }
    } else {
        fprintf(stderr, "Unknown writer type: %s\n", str);
        grc = TLOG_RC_FAILURE;
        goto cleanup;
    }

    /*
     * Create the sink
     */
    /* Get host FQDN */
    grc = get_fqdn(&fqdn);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed retrieving host FQDN: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Get session ID */
    grc = get_session_id(&session_id);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed retrieving session ID: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Get effective user entry */
    errno = 0;
    passwd = getpwuid(geteuid());
    if (passwd == NULL) {
        if (errno == 0) {
            grc = TLOG_RC_FAILURE;
            fprintf(stderr, "User entry not found\n");
        } else {
            grc = TLOG_GRC_ERRNO;
            fprintf(stderr, "Failed retrieving user entry: %s\n",
                    tlog_grc_strerror(grc));
        }
        goto cleanup;
    }

    /* Get the maximum payload size */
    if (!json_object_object_get_ex(conf, "payload", &obj)) {
        fprintf(stderr, "Maximum payload size is not specified\n");
        grc = TLOG_RC_FAILURE;
        goto cleanup;
    }
    num = json_object_get_int64(obj);

    /* Create the sink, letting it take over the writer */
    grc = tlog_json_sink_create(&sink, writer, true,
                                fqdn, passwd->pw_name,
                                session_id, (size_t)num);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed creating log sink: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }
    writer = NULL;

    *psink = sink;
    sink = NULL;
    grc = TLOG_RC_OK;
cleanup:

    if (fd >= 0) {
        close(fd);
    }
    tlog_json_writer_destroy(writer);
    free(fqdn);
    tlog_sink_destroy(sink);
    return grc;
}
Ejemplo n.º 30
0
int main(int argc, char *argv[])
{
	int argi;
	char *envarea = NULL;
	char *hffile = "ghosts";
	int bgcolor = COL_BLUE;
	char *ghosts = NULL;
	sendreturn_t *sres;

	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;
		}
		else if (argnmatch(argv[argi], "--hffile=")) {
			char *p = strchr(argv[argi], '=');
			hffile = strdup(p+1);
		}
	}

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

	switch (outform) {
	  case O_HTML:
		fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
		headfoot(stdout, hffile, "", "header", bgcolor);
		break;
	  case O_TXT:
		fprintf(stdout, "Content-type: text/plain\n\n");
		break;
	}

	sres = newsendreturnbuf(1, NULL);

	if (sendmessage("ghostlist", NULL, XYMON_TIMEOUT, sres) == XYMONSEND_OK) {
		char *bol, *eoln, *name, *sender, *timestr;
		time_t tstamp, now;
		int count, idx;
		ghost_t *ghosttable;

		ghosts = getsendreturnstr(sres, 1);

		/* Count the number of lines */
		for (bol = ghosts, count=0; (bol); bol = strchr(bol, '\n')) {
			if (*bol == '\n') bol++;
			count++;
		}
		ghosttable = (ghost_t *)calloc(count+1, sizeof(ghost_t));

		idx = count = 0;
		tstamp = now = getcurrenttime(NULL);
		bol = ghosts;
		while (bol) {
			name = sender = timestr = NULL;

			eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0';
			name = strtok(bol, "|");
			if (name) sender = strtok(NULL, "|");
			if (sender) timestr = strtok(NULL, "|");

			if (timestr) tstamp = atol(timestr);

			if (name && sender && timestr && (tstamp > (now - maxage))) {
				int i1, i2, i3, i4;

				sscanf(sender, "%d.%d.%d.%d", &i1, &i2, &i3, &i4);
				ghosttable[idx].sender = sender;
				ghosttable[idx].senderval = (i1 << 24) + (i2 << 16) + (i3 << 8) + i4;
				ghosttable[idx].name = name;
				ghosttable[idx].tstamp = tstamp;
				find_candidate(&ghosttable[idx]);
				idx++; count++;
			}

			if (eoln) eoln++;
			bol = eoln;
		}

		switch (sorttype) {
		  case S_NAME:
			qsort(&ghosttable[0], count, sizeof(ghost_t), hostname_compare);
			break;

		  case S_SENDER:
			qsort(&ghosttable[0], count, sizeof(ghost_t), sender_compare);
			break;

		  case S_TIME:
			qsort(&ghosttable[0], count, sizeof(ghost_t), time_compare);
			break;
		}

		if (outform == O_HTML) {
			fprintf(stdout, "<table align=center>\n");
			fprintf(stdout, "<tr>");
			fprintf(stdout, "<th align=left><a href=\"ghostlist.sh?SORT=name&MAXAGE=%d\">Hostname</a></th>", maxage);
			fprintf(stdout, "<th align=left><a href=\"ghostlist.sh?SORT=sender&MAXAGE=%d\">Sent from</a></th>", maxage);
			fprintf(stdout, "<th align=left>Candidate</th>");
			fprintf(stdout, "<th align=right><a href=\"ghostlist.sh?SORT=time&MAXAGE=%d\">Report age</a></th>", maxage);
			fprintf(stdout, "</tr>\n");
		}

		for (idx = 0; (idx < count); idx++) {
			if (!ghosttable[idx].name) continue;
			if (!ghosttable[idx].sender) continue;

			switch (outform) {
			  case O_HTML:
				fprintf(stdout, "<tr><td align=left>%s</td><td align=left>%s</td>",
					ghosttable[idx].name, 
					ghosttable[idx].sender);

				if (ghosttable[idx].candidate) {
					fprintf(stdout, "<td align=left><a href=\"%s\">%s</a></td>",
						hostsvcurl(xmh_item(ghosttable[idx].candidate, XMH_HOSTNAME), xgetenv("INFOCOLUMN"), 1),
						xmh_item(ghosttable[idx].candidate, XMH_HOSTNAME));
				}
				else {
					fprintf(stdout, "<td>&nbsp;</td>");
				}

				fprintf(stdout, "<td align=right>%ld:%02ld</td></tr>\n",
					(now - ghosttable[idx].tstamp)/60, (now - ghosttable[idx].tstamp)%60);
				break;

			  case O_TXT:
				fprintf(stdout, "%s\t\t%s\n", ghosttable[idx].sender, ghosttable[idx].name);
				break;
			}
		}

		if (outform == O_HTML) {
			fprintf(stdout, "</table>\n");
			fprintf(stdout, "<br><br><center><a href=\"ghostlist.sh?SORT=%s&MAXAGE=%d&TEXT\">Text report</a></center>\n", htmlquoted(sortstring), maxage);
		}
	}
	else
		fprintf(stdout, "<h3><center>Failed to retrieve ghostlist from server</center></h3>\n");

	freesendreturnbuf(sres);

	if (outform == O_HTML) {
		headfoot(stdout, hffile, "", "footer", bgcolor);
	}

	return 0;
}