コード例 #1
0
static int prepare_fromfile(char *hostsfn, char *extrainclude)
{
	static void *hostfiles = NULL;
	FILE *hosts;
	strbuffer_t *inbuf;

	/* First check if there were no modifications at all */
	if (hostfiles) {
		if (!stackfmodified(hostfiles)){
			return 1;
		}
		else {
			stackfclist(&hostfiles);
			hostfiles = NULL;
		}
	}

	if (!contentbuffer) contentbuffer = newstrbuffer(0);
	clearstrbuffer(contentbuffer);

	hosts = stackfopen(hostsfn, "r", &hostfiles);
	if (hosts == NULL) return -1;

	inbuf = newstrbuffer(0);
	while (stackfgets(inbuf, extrainclude)) {
		sanitize_input(inbuf, 0, 0);
		addtostrbuffer(contentbuffer, inbuf);
		addtobuffer(contentbuffer, "\n");
	}

	stackfclose(hosts);
	freestrbuffer(inbuf);

	return 0;
}
コード例 #2
0
ファイル: webaccess.c プロジェクト: Kotty666/xymon
void *load_web_access_config(char *accessfn)
{
	FILE *fd;
	strbuffer_t *buf;

	if (acctree) return 0;
	acctree = xtreeNew(strcasecmp);

	fd = stackfopen(accessfn, "r", NULL);
	if (fd == NULL) return NULL;

	buf = newstrbuffer(0);
	while (stackfgets(buf, NULL)) {
		char *group, *member;
		char *key;

		group = strtok(STRBUF(buf), ": \n");
		if (!group) continue;

		member = strtok(NULL, ", \n");
		while (member) {
			key = (char *)malloc(strlen(group) + strlen(member) + 2);
			sprintf(key, "%s %s", group, member);
			xtreeAdd(acctree, key, NULL);
			member = strtok(NULL, ", \n");
		}
	}
	stackfclose(fd);

	return acctree;
}
コード例 #3
0
ファイル: beastat.c プロジェクト: tjyang/abmon
void send_data(void *host, char *beadomain, char *databuf, char **items)
{
	bea_idx_t *idxwalk;
	strbuffer_t *msgbuf;
	char *p;
	int i;

	msgbuf = newstrbuffer(0);

        for (idxwalk = bea_idxhead; (idxwalk); idxwalk = idxwalk->next) {
		sprintf(msgline, "data %s.bea\n\n", commafy(bbh_item(host, BBH_HOSTNAME)));
		addtobuffer(msgbuf, msgline);

		if (beadomain && *beadomain) {
			sprintf(msgline, "DOMAIN:%s\n", beadomain);
			addtobuffer(msgbuf, msgline);
		}

		for (i=0; (items[i]); i++) {
			p = getstring(databuf, idxwalk->idx, items[i]);
			sprintf(msgline, "%s\n", p);
			addtobuffer(msgbuf, msgline);
		}

		sendmessage(STRBUF(msgbuf), NULL, BBTALK_TIMEOUT, NULL);
		clearstrbuffer(msgbuf);
	}

	freestrbuffer(msgbuf);
}
コード例 #4
0
ファイル: zvm.c プロジェクト: tjyang/abmon
static void zvm_mdc_report(char *hostname, char *clientclass, enum ostype_t os,
                     void *hinfo, char *fromline, char *timestr, char *cpuutilstr)
{
        char *p;
        int mdcreads, mdcwrites, mdchitpct;
        char mdcresult[100];

        char msgline[256];
        strbuffer_t *msg;

        if (!cpuutilstr) return;
        msg = newstrbuffer(0);

        /*
         *  Looking for MDC info in 'IND' command response
         *  MDC READS-000001/SEC WRITES-000001/SEC HIT RATIO-098%
         */
        *mdcresult = '\0';
        /*  Skip past three newlines in message to the PAGING text  */
        p=strstr(cpuutilstr,"READS-");
        if (p) {
		p += 6;
        	sscanf(p, "%d/SEC", &mdcreads);
        	p=strstr(cpuutilstr,"WRITES-") + 7;
        	sscanf(p, "%d/SEC", &mdcwrites);
        	p=strstr(cpuutilstr,"RATIO-") + 6;
        	sscanf(p, "%d", &mdchitpct);

	        sprintf(msgline, "data %s.mdc\n%s\n%d:%d:%d\n", commafy(hostname), osname(os), mdcreads, mdcwrites, mdchitpct);
        	addtobuffer(msg, msgline);
		sendmessage(STRBUF(msg), NULL, BBTALK_TIMEOUT, NULL);
        	}

        freestrbuffer(msg);
}
コード例 #5
0
ファイル: strfunc.c プロジェクト: tjyang/cpam
char *htmlquoted(char *s)
{
	/*
	 * This routine converts a plain string into an html-quoted string
	 */

	static strbuffer_t *result = NULL;
	char *inp, *endp;
	char c;

	if (!result) result = newstrbuffer(4096);
	clearstrbuffer(result);

	inp = s;
	do {
		endp = inp + strcspn(inp, "\"&<> ");
		c = *endp;
		if (endp > inp) addtobufferraw(result, inp, endp-inp);
		switch (c) {
		  case '"': addtobuffer(result, "&quot;"); break;
		  case '&': addtobuffer(result, "&amp;"); break;
		  case '<': addtobuffer(result, "&lt;"); break;
		  case '>': addtobuffer(result, "&gt;"); break;
		  case ' ': addtobuffer(result, "&nbsp;"); break;
		  default: break;
		}
		inp = (c == '\0') ? NULL : endp+1;
	} while (inp);

	return STRBUF(result);
}
コード例 #6
0
ファイル: sendmsg.c プロジェクト: tjyang/cpam
void init_status(int color)
{
	if (msgbuf == NULL) msgbuf = newstrbuffer(0);
	clearstrbuffer(msgbuf);
	msgcolor = color;
	xymonstatuscount++;
}
コード例 #7
0
static void zvse_paging_report(char *hostname, char *clientclass, enum ostype_t os,
                     void *hinfo, char *fromline, char *timestr, char *pagingstr)
{
	char *p;
        int ipagerate, pagingyellow, pagingred;
        float fpagerate=0.0;
        char pagingresult[100];

        int pagingcolor = COL_GREEN;
        char msgline[4096];
        strbuffer_t *upmsg;

        if (!pagingstr) return;
        /*
         *  Looking for Paging rate in message
         *  Page Rate=0.00 /sec
         */
        *pagingresult = '\0';

	ipagerate=0;
	p = strstr(pagingstr, "Page Rate=") + 10; 
	if (p) {
        	if (sscanf(p, "%f", &fpagerate) == 1) {
			ipagerate=fpagerate + 0.5;   /*  Rounding up */
                	sprintf(pagingresult, "z/VSE Paging Rate %d per second\n", ipagerate);
                	}
		}
	else
		sprintf(pagingresult, "Can not find page rate value in:\n%s\n", pagingstr);

        get_paging_thresholds(hinfo, clientclass, &pagingyellow, &pagingred);

        upmsg = newstrbuffer(0);

        if (ipagerate > pagingred) {
                pagingcolor = COL_RED;
                addtobuffer(upmsg, "&red Paging Rate is CRITICAL\n");
        }
        else if (ipagerate > pagingyellow) {
                pagingcolor = COL_YELLOW;
                addtobuffer(upmsg, "&yellow Paging Rate is HIGH\n");
        }

        init_status(pagingcolor);
        sprintf(msgline, "status %s.paging %s %s %s %s\n",
                commafy(hostname), colorname(pagingcolor),
                (timestr ? timestr : "<no timestamp data>"),
                pagingresult, pagingstr);
        addtostatus(msgline);
        if (STRBUFLEN(upmsg)) {
                addtostrstatus(upmsg);
                addtostatus("\n");
        }

        if (fromline && !localmode) addtostatus(fromline);
        finish_status();

        freestrbuffer(upmsg);
}
コード例 #8
0
ファイル: sendmsg.c プロジェクト: tjyang/cpam
void combo_start(void)
{
	combo_params();

	if (xymonmsg == NULL) xymonmsg = newstrbuffer(0);
	clearstrbuffer(xymonmsg);
	addtobuffer(xymonmsg, "combo\n");
	xymonmsgqueued = 0;
}
コード例 #9
0
ファイル: stackio.c プロジェクト: osvaldsson/xymon
int main(int argc, char *argv[])
{
	char *fn, *p;
	char cmd[1024];
	FILE *fd;
	strbuffer_t *inbuf = newstrbuffer(0);
	void *listhead = NULL;
	int done, linenum;

	fn = strdup(argv[1]);
	strcpy(cmd, "!");
	done = 0;
	while (!done) {
		if (*cmd == '!') {
			fd = stackfopen(fn, "r", &listhead);
			linenum = 1;
			if (!fd) { errprintf("Cannot open file %s\n", fn); continue; }

			while (stackfgets(inbuf, NULL)) {
				linenum++;
				printf("%s", STRBUF(inbuf));
			}
			stackfclose(fd);
		}
		else if (*cmd == '?') {
			filelist_t *walk = (filelist_t *)listhead;

			while (walk) {
				printf("%s %lu\n", walk->filename, (unsigned long)walk->fsize);
				walk = walk->next;
			}
			if (stackfmodified(listhead)) printf("File(s) have been modified\n");
			else printf("No changes\n");
		}
		else if (*cmd == '.') {
			done = 1;
			continue;
		}
		else {
			xfree(fn); fn = strdup(cmd);
			stackfclist(&listhead);
			strcpy(cmd, "!");
			continue;
		}

		printf("\nCmd: "); fflush(stdout);
		fgets(cmd, sizeof(cmd), stdin);
		p = strchr(cmd, '\n'); if (p) *p = '\0';
	}

	xfree(fn);
	stackfclist(&listhead);

	return 0;
}
コード例 #10
0
ファイル: zvm.c プロジェクト: tjyang/abmon
static void zvm_paging_report(char *hostname, char *clientclass, enum ostype_t os,
                     void *hinfo, char *fromline, char *timestr, char *cpuutilstr)
{
        char *p;
        int pagerate, pagingyellow, pagingred;
        char pagingresult[100];

        int pagingcolor = COL_GREEN;
        char msgline[256];
        strbuffer_t *upmsg;

        if (!cpuutilstr) return;
        /*
         *  Looking for Paging rate info in 'IND' command response
         *  PAGING-0000/SEC
         */
        *pagingresult = '\0';
	/*  Skip past three newlines in message to the PAGING text  */
	p=strstr(cpuutilstr,"PAGING-") + 7;
	if (sscanf(p, "%d/SEC", &pagerate) == 1) {
               	sprintf(pagingresult, "z/VM Paging Rate %d per second\n", pagerate);
        }

        get_paging_thresholds(hinfo, clientclass, &pagingyellow, &pagingred);

        upmsg = newstrbuffer(0);

        if (pagerate > pagingred) {
                pagingcolor = COL_RED;
                addtobuffer(upmsg, "&red Paging Rate is CRITICAL\n");
        }
        else if (pagerate > pagingyellow) {
                pagingcolor = COL_YELLOW;
                addtobuffer(upmsg, "&yellow Paging Rate is HIGH\n");
        }

        init_status(pagingcolor);
        sprintf(msgline, "status %s.paging %s %s %s %s\n",
                commafy(hostname), colorname(pagingcolor),
                (timestr ? timestr : "<no timestamp data>"),
                pagingresult,
                cpuutilstr);
        addtostatus(msgline);
        if (STRBUFLEN(upmsg)) {
                addtostrstatus(upmsg);
                addtostatus("\n");
        }

        if (fromline && !localmode) addtostatus(fromline);
        finish_status();

        freestrbuffer(upmsg);
}
コード例 #11
0
ファイル: environ.c プロジェクト: tjyang/abmon
void loadenv(char *envfile, char *area)
{
	FILE *fd;
	strbuffer_t *inbuf;
	char *p, *oneenv;
	int n;

	MEMDEFINE(l);
	inbuf = newstrbuffer(0);

	fd = stackfopen(envfile, "r", NULL);
	if (fd) {
		while (stackfgets(inbuf, NULL)) {
			sanitize_input(inbuf, 1, 1);

			if (STRBUFLEN(inbuf) && strchr(STRBUF(inbuf), '=')) {
				/*
				 * Do the environment "area" stuff: If the input
				 * is of the form AREA/NAME=VALUE, then setup the variable
				 * only if we're called with the correct AREA setting.
				 */
				oneenv = NULL;

				p = STRBUF(inbuf) + strcspn(STRBUF(inbuf), "=/");
				if (*p == '/') {
					if (area) {
						*p = '\0';
						if (strcasecmp(STRBUF(inbuf), area) == 0) oneenv = strdup(expand_env(p+1));
					}
				}
				else oneenv = strdup(expand_env(STRBUF(inbuf)));

				if (oneenv) {
					p = strchr(oneenv, '=');
					if (*(p+1) == '"') {
						/* Move string over the first '"' */
						memmove(p+1, p+2, strlen(p+2)+1);
						/* Kill a trailing '"' */
						if (*(oneenv + strlen(oneenv) - 1) == '"') *(oneenv + strlen(oneenv) - 1) = '\0';
					}
					n = putenv(oneenv);
				}
			}
		}
		stackfclose(fd);
	}
	else {
		errprintf("Cannot open env file %s - %s\n", envfile, strerror(errno));
	}

	freestrbuffer(inbuf);
	MEMUNDEFINE(l);
}
コード例 #12
0
int main(int argc, char *argv[])
{ 
	FILE *bbhosts;
	char *fn = NULL;
	strbuffer_t *inbuf;
	int argi;
	char *include2 = NULL;


	for (argi=1; (argi < argc); argi++) {
		if (strcmp(argv[argi], "--version") == 0) {
			printf("bbhostshow version %s\n", VERSION);
			exit(0);
		}
		else if (strcmp(argv[argi], "--help") == 0) {
			printf("Usage:\n%s [filename]\n", argv[0]);
			exit(0);
		}
		else if (strcmp(argv[argi], "--bbnet") == 0) {
			include2 = "netinclude";
		}
		else if (strcmp(argv[argi], "--bbdisp") == 0) {
			include2 = "dispinclude";
		}
		else if (*argv[argi] != '-') {
			fn = strdup(argv[argi]);
		}
	}

	if (!fn || (strlen(fn) == 0)) {
		fn = getenv("BBHOSTS");
		if (!fn) {
			errprintf("Environment variable BBHOSTS is not set - aborting\n");
			exit(2);
		}
	}

	bbhosts = stackfopen(fn, "r", NULL);
	if (bbhosts == NULL) {
		printf("Cannot open the BBHOSTS file '%s'\n", fn);
		exit(1);
	}

	inbuf = newstrbuffer(0);
	while (stackfgets(inbuf, include2)) {
		printf("%s", STRBUF(inbuf));
	}

	stackfclose(bbhosts);
	freestrbuffer(inbuf);
	return 0;
}
コード例 #13
0
ファイル: strfunc.c プロジェクト: tjyang/cpam
strbuffer_t *dupstrbuffer(char *src)
{
	strbuffer_t *newbuf;
	int len = 0;
	
	newbuf = newstrbuffer(0);
	if (src) {
		newbuf->s = strdup(src);
		len = strlen(src);
		newbuf->used = newbuf->sz = len;
	}

	return newbuf;
}
コード例 #14
0
ファイル: do_alert.c プロジェクト: osvaldsson/xymon
void load_state(char *filename, char *statusbuf)
{
    FILE *fd = fopen(filename, "r");
    strbuffer_t *inbuf;
    char *p;

    if (fd == NULL) return;

    initfgets(fd);
    inbuf = newstrbuffer(0);
    while (unlimfgets(inbuf, fd)) {
        sanitize_input(inbuf, 0, 0);

        p = strchr(STRBUF(inbuf), '|');
        if (p) {
            repeat_t *newrpt;

            *p = '\0';
            if (atoi(STRBUF(inbuf)) > getcurrenttime(NULL)) {
                char *found = NULL;

                if (statusbuf) {
                    char *htend;

                    /* statusbuf contains lines with "HOSTNAME|TESTNAME|COLOR" */
                    htend = strchr(p+1, '|');
                    if (htend) htend = strchr(htend+1, '|');
                    if (htend) {
                        *htend = '\0';
                        *p = '\n';
                        found = strstr(statusbuf, p);
                        if (!found && (strncmp(statusbuf, p+1, strlen(p+1)) == 0))
                            found = statusbuf;
                        *htend = '|';
                    }
                }
                if (!found) continue;

                newrpt = (repeat_t *)malloc(sizeof(repeat_t));
                newrpt->recipid = strdup(p+1);
                newrpt->nextalert = atoi(STRBUF(inbuf));
                newrpt->next = rpthead;
                rpthead = newrpt;
            }
        }
    }

    fclose(fd);
    freestrbuffer(inbuf);
}
コード例 #15
0
ファイル: sendmsg.c プロジェクト: tjyang/cpam
sendreturn_t *newsendreturnbuf(int fullresponse, FILE *respfd)
{
	sendreturn_t *result;

	result = (sendreturn_t *)calloc(1, sizeof(sendreturn_t));
	result->fullresponse = fullresponse;
	result->respfd = respfd;
	if (!respfd) {
		/* No response file, so return it in a strbuf */
		result->respstr = newstrbuffer(0);
	}
	result->haveseenhttphdrs = 1;

	return result;
}
コード例 #16
0
ファイル: misc.c プロジェクト: gvsurenderreddy/xymon-2
void do_extensions(FILE *output, char *extenv, char *family)
{
	/*
	 * Extension scripts. These are ad-hoc, and implemented as a
	 * simple pipe. So we do a fork here ...
	 */

	char *exts, *p;
	FILE *inpipe;
	char extfn[PATH_MAX];
	strbuffer_t *inbuf;

	p = xgetenv(extenv);
	if (p == NULL) {
		/* No extension */
		return;
	}

	MEMDEFINE(extfn);

	exts = strdup(p);
	p = strtok(exts, "\t ");
	inbuf = newstrbuffer(0);

	while (p) {
		/* Dont redo the eventlog or acklog things */
		if ((strcmp(p, "eventlog.sh") != 0) &&
		    (strcmp(p, "acklog.sh") != 0)) {
			sprintf(extfn, "%s/ext/%s/%s", xgetenv("XYMONHOME"), family, p);
			inpipe = popen(extfn, "r");
			if (inpipe) {
				initfgets(inpipe);
				while (unlimfgets(inbuf, inpipe)) fputs(STRBUF(inbuf), output);
				pclose(inpipe);
				freestrbuffer(inbuf);
			}
		}
		p = strtok(NULL, "\t ");
	}

	xfree(exts);

	MEMUNDEFINE(extfn);
	MEMUNDEFINE(buf);
}
コード例 #17
0
ファイル: sendresults.c プロジェクト: gvsurenderreddy/xymon-2
static void add_to_sub_queue(myconn_t *rec, char *moduleid, char *location, ...)
{
	va_list extraparams;
	char *s;
	strbuffer_t *extrastr = newstrbuffer(0);

	if (!rec || !moduleid) return;

	va_start(extraparams, location);
	while ((s = va_arg(extraparams, char *)) != NULL) {
		if (STRBUFLEN(extrastr) > 0) addtobuffer(extrastr, "\t");
		addtobuffer(extrastr, s);
	}
	va_end(extraparams);

	xymon_sqldb_netmodule_additem(moduleid, location, xmh_item(rec->hostinfo, XMH_HOSTNAME), rec->netparams.destinationip, rec->testspec, STRBUF(extrastr), rec->interval*1000, rec->timeout*1000);
	freestrbuffer(extrastr);
}
コード例 #18
0
ファイル: sendmsg.c プロジェクト: tjyang/cpam
char *getsendreturnstr(sendreturn_t *s, int takeover)
{
	char *result = NULL;

	if (!s) return NULL;
	if (!s->respstr) return NULL;
	result = STRBUF(s->respstr);
	if (takeover) {
		/*
		 * We cannot leave respstr as NULL, because later calls 
		 * to sendmessage() might re-use this sendreturn_t struct
		 * and expect to get the data back. So allocate a new
		 * responsebuffer for future use - if it isn't used, it
		 * will be freed by freesendreturnbuf().
		 */
		s->respstr = newstrbuffer(0);
	}

	return result;
}
コード例 #19
0
ファイル: loadalerts.c プロジェクト: osvaldsson/xymon
static char *preprocess(char *buf)
{
	/* Expands config-file macros */
	static strbuffer_t *result = NULL;
	char *inp;

	if (result == NULL) result = newstrbuffer(8192);
	clearstrbuffer(result);

	inp = buf;
	while (inp) {
		char *p;

		p = strchr(inp, '$');
		if (p == NULL) {
			addtobuffer(result, inp);
			inp = NULL;
		}
		else {
			token_t *twalk;
			char savech;
			int n;

			*p = '\0';
			addtobuffer(result, inp);
			p = (p+1);

			n = strcspn(p, "\t $.,|%!()[]{}+?/&@:;*");
			savech = *(p+n);
			*(p+n) = '\0';
			for (twalk = tokhead; (twalk && strcmp(p, twalk->name)); twalk = twalk->next) ;
			*(p+n) = savech;

			if (twalk) addtobuffer(result, twalk->value);
			inp = p+n;
		}
	}

	return STRBUF(result);
}
コード例 #20
0
ファイル: hobbit-confreport.c プロジェクト: tjyang/abmon
void load_columndocs(void)
{
    char fn[PATH_MAX];
    FILE *fd;
    strbuffer_t *inbuf;

    sprintf(fn, "%s/etc/columndoc.csv", xgetenv("BBHOME"));
    fd = fopen(fn, "r");
    if (!fd) return;

    inbuf = newstrbuffer(0);
    initfgets(fd);

    /* Skip the header line */
    if (!unlimfgets(inbuf, fd)) {
        fclose(fd);
        freestrbuffer(inbuf);
        return;
    }

    while (unlimfgets(inbuf, fd)) {
        char *s1 = NULL, *s2 = NULL;

        s1 = strtok(STRBUF(inbuf), coldelim);
        if (s1) s2 = strtok(NULL, coldelim);

        if (s1 && s2) {
            coltext_t *newitem = (coltext_t *)calloc(1, sizeof(coltext_t));
            newitem->colname = strdup(s1);
            newitem->coldescr = strdup(s2);
            newitem->next = chead;
            chead = newitem;
            ccount++;
        }
    }
    fclose(fd);
    freestrbuffer(inbuf);
}
コード例 #21
0
ファイル: do_external.c プロジェクト: osvaldsson/xymon
int do_external_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) 
{ 
	pid_t childpid;

	dbgprintf("-> do_external(%s, %s)\n", hostname, testname);

	childpid = fork();
	if (childpid == 0) {
		FILE *fd;
		char fn[PATH_MAX];
		enum { R_DEFS, R_FN, R_DATA, R_NEXT } pstate;
		FILE *extfd;
		char extcmd[2*PATH_MAX];
		strbuffer_t *inbuf;
		char *p;
		char **params = NULL;
		int paridx = 0;
		pid_t mypid = getpid();
		
		MEMDEFINE(fn); MEMDEFINE(extcmd);

		sprintf(fn, "%s/rrd_msg_%d", xgetenv("XYMONTMP"), (int) getpid());
		dbgprintf("%09d : Saving msg to file %s\n", (int)mypid, fn);

		fd = fopen(fn, "w");
		if (fd == NULL) {
			errprintf("Cannot create temp file %s\n", fn);
			exit(1);
		}
		if (fwrite(msg, strlen(msg), 1, fd) != 1) {
			errprintf("Error writing to file %s: %s\n", fn, strerror(errno));
			exit(1) ;
		}
		if (fclose(fd)) errprintf("Error closing file %s: %s\n", fn, strerror(errno));

		/* 
		 * Disable the RRD update cache.
		 * We cannot use the cache, because this child
		 * process terminates without flushing the cache,
		 * and it cannot feed the update-data back to the
		 * parent process which owns the cache. So using
		 * an external handler means the updates will be
		 * sync'ed to disk immediately.
		 *
		 * NB: It is OK to do this now and not re-enable it,
		 * since we're running in the external helper
		 * child process - so this only affects the current
		 * update.
		 *
		 * Thanks to Graham Nayler for the analysis.
		 */
		use_rrd_cache = 0;

		inbuf = newstrbuffer(0);

		/* Now call the external helper */
		sprintf(extcmd, "%s %s %s %s", exthandler, hostname, testname, fn);
		dbgprintf("%09d : Calling helper script %s\n", (int)mypid, extcmd);
		extfd = popen(extcmd, "r");
		if (extfd) {
			pstate = R_DEFS;
			initfgets(extfd);

			while (unlimfgets(inbuf, extfd)) {
				p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0';
				dbgprintf("%09d : Helper input '%s'\n", (int)mypid, STRBUF(inbuf));
				if (STRBUFLEN(inbuf) == 0) continue;

				if (pstate == R_NEXT) {
					/* After doing one set of data, allow script to re-use the same DS defs */
					if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) {
						/* New DS definitions, scratch the old ones */
						if (params) {
							for (paridx=0; (params[paridx] != NULL); paridx++) 
								xfree(params[paridx]);
							xfree(params);
							params = NULL;
						}
						pstate = R_DEFS;
					}
					else pstate = R_FN;
				}

				switch (pstate) {
				  case R_DEFS:
					if (params == NULL) {
						params = (char **)calloc(1, sizeof(char *));
						paridx = 0;
					}

					if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) {
						/* Dataset definition */
						params[paridx] = strdup(STRBUF(inbuf));
						paridx++;
						params = (char **)realloc(params, (1 + paridx)*sizeof(char *));
						params[paridx] = NULL;
						break;
					}
					else {
						/* No more DS defs */
						pstate = R_FN;
					}
					/* Fall through */
				  case R_FN:
					setupfn("%s", STRBUF(inbuf));
					pstate = R_DATA;
					break;

				  case R_DATA:
					snprintf(rrdvalues, sizeof(rrdvalues)-1, "%d:%s", (int)tstamp, STRBUF(inbuf));
					rrdvalues[sizeof(rrdvalues)-1] = '\0';
					create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL);
					pstate = R_NEXT;
					break;

				  case R_NEXT:
					/* Should not happen */
					break;
				}
			}
			pclose(extfd);
		}
		else {
			errprintf("Pipe open of RRD handler failed: %s\n", strerror(errno));
		}

		if (params) {
			for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]);
			xfree(params);
		}

		dbgprintf("%09d : Unlinking temp file\n", (int)mypid);
		unlink(fn);
		freestrbuffer(inbuf);

		exit(0);
	}
	else if (childpid > 0) {
		/* Parent continues */
	}
	else {
		errprintf("Fork failed in RRD handler: %s\n", strerror(errno));
	}

	dbgprintf("<- do_external(%s, %s)\n", hostname, testname);
	return 0;
}
コード例 #22
0
char *init_tcp_services(void)
{
	static char *xymonnetsvcs = NULL;
	static time_t lastupdate = 0;

	char filename[PATH_MAX];
	struct stat st;
	FILE *fd = NULL;
	strbuffer_t *inbuf;
	svclist_t *head, *tail, *first, *walk;
	char *searchstring;
	int svcnamebytes = 0;
	int svccount = 0;
	int i;

	MEMDEFINE(filename);

	filename[0] = '\0';
	if (xgetenv("XYMONHOME")) {
		sprintf(filename, "%s/etc/", xgetenv("XYMONHOME"));
	}
	strcat(filename, "protocols.cfg");

	if ((stat(filename, &st) == 0) && xymonnetsvcs) {
		/* See if we have already run and the file is unchanged - if so just pickup the result */
		if (st.st_mtime == lastupdate) return xymonnetsvcs;

		/* File has changed - reload configuration. But clean up first so we dont leak memory. */
		if (svcinfo != default_svcinfo) {
			for (i=0; (svcinfo[i].svcname); i++) {
				if (svcinfo[i].svcname) xfree(svcinfo[i].svcname);
				if (svcinfo[i].sendtxt) xfree(svcinfo[i].sendtxt);
				if (svcinfo[i].exptext) xfree(svcinfo[i].exptext);
			}
			xfree(svcinfo);
			svcinfo = default_svcinfo;
		}

		xfree(xymonnetsvcs); xymonnetsvcs = NULL;
	}

	if (xgetenv("XYMONNETSVCS") == NULL) {
		putenv("XYMONNETSVCS=smtp telnet ftp pop pop3 pop-3 ssh imap ssh1 ssh2 imap2 imap3 imap4 pop2 pop-2 nntp");
	}

	fd = fopen(filename, "r");
	if (fd == NULL) {
		errprintf("Cannot open TCP service-definitions file %s - using defaults\n", filename);
		xymonnetsvcs = strdup(xgetenv("XYMONNETSVCS"));

		MEMUNDEFINE(filename);
		return xymonnetsvcs;
	}

	lastupdate = st.st_mtime;
	head = tail = first = NULL;

	inbuf = newstrbuffer(0);
	initfgets(fd);
	while (unlimfgets(inbuf, fd)) {
		char *l, *eol;

		sanitize_input(inbuf, 1, 0);
		l = STRBUF(inbuf);

		if (*l == '[') {
			char *svcname;

			eol = strchr(l, ']'); if (eol) *eol = '\0';
			l = skipwhitespace(l+1);

			svcname = strtok(l, "|"); first = NULL;
			while (svcname) {
				svclist_t *newitem;

				svccount++;
				svcnamebytes += (strlen(svcname) + 1);

				newitem = (svclist_t *) malloc(sizeof(svclist_t));
				newitem->rec = (svcinfo_t *)calloc(1, sizeof(svcinfo_t));
				newitem->rec->svcname = strdup(svcname);
				newitem->next = NULL;

				if (first == NULL) first = newitem;

				if (head == NULL) {
					head = tail = newitem;
				}
				else {
					tail->next = newitem;
					tail = newitem;
				}

				svcname = strtok(NULL, "|");
			}
		}
		else if (strncmp(l, "send ", 5) == 0) {
			if (first) {
				getescapestring(skipwhitespace(l+4), &first->rec->sendtxt, &first->rec->sendlen);
				for (walk = first->next; (walk); walk = walk->next) {
					walk->rec->sendtxt = strdup(first->rec->sendtxt);
					walk->rec->sendlen = first->rec->sendlen;
				}
			}
		}
		else if (strncmp(l, "expect ", 7) == 0) {
			if (first) {
				getescapestring(skipwhitespace(l+6), &first->rec->exptext, &first->rec->explen);
				for (walk = first->next; (walk); walk = walk->next) {
					walk->rec->exptext = strdup(first->rec->exptext);
					walk->rec->explen = first->rec->explen;
					walk->rec->expofs = 0; /* HACK - not used right now */
				}
			}
		}
		else if (strncmp(l, "options ", 8) == 0) {
			if (first) {
				char *opt;

				first->rec->flags = 0;
				l = skipwhitespace(l+7);
				opt = strtok(l, ",");
				while (opt) {
					if      (strcmp(opt, "ssl") == 0)    first->rec->flags |= TCP_SSL;
					else if (strcmp(opt, "banner") == 0) first->rec->flags |= TCP_GET_BANNER;
					else if (strcmp(opt, "telnet") == 0) first->rec->flags |= TCP_TELNET;
					else errprintf("Unknown option: %s\n", opt);

					opt = strtok(NULL, ",");
				}
				for (walk = first->next; (walk); walk = walk->next) {
					walk->rec->flags = first->rec->flags;
				}
			}
		}
		else if (strncmp(l, "port ", 5) == 0) {
			if (first) {
				first->rec->port = atoi(skipwhitespace(l+4));
				for (walk = first->next; (walk); walk = walk->next) {
					walk->rec->port = first->rec->port;
				}
			}
		}
	}

	if (fd) fclose(fd);
	freestrbuffer(inbuf);

	/* Copy from the svclist to svcinfo table */
	svcinfo = (svcinfo_t *) malloc((svccount+1) * sizeof(svcinfo_t));
	for (walk=head, i=0; (walk && (i < svccount)); walk = walk->next, i++) {
		svcinfo[i].svcname = walk->rec->svcname;
		svcinfo[i].sendtxt = walk->rec->sendtxt;
		svcinfo[i].sendlen = walk->rec->sendlen;
		svcinfo[i].exptext = walk->rec->exptext;
		svcinfo[i].explen  = walk->rec->explen;
		svcinfo[i].expofs  = walk->rec->expofs;
		svcinfo[i].flags   = walk->rec->flags;
		svcinfo[i].port    = walk->rec->port;
	}
	memset(&svcinfo[svccount], 0, sizeof(svcinfo_t));

	/* This should not happen */
	if (walk) {
		errprintf("Whoa - didnt copy all services! svccount=%d, next service '%s'\n", 
			svccount, walk->rec->svcname);
	}

	/* Free the temp. svclist list */
	while (head) {
		/*
		 * Note: Dont free the strings inside the records, 
		 * as they are now owned by the svcinfo records.
		 */
		walk = head;
		head = head->next;
		xfree(walk);
	}

	searchstring = strdup(xgetenv("XYMONNETSVCS"));
	xymonnetsvcs = (char *) malloc(strlen(xgetenv("XYMONNETSVCS")) + svcnamebytes + 1);
	strcpy(xymonnetsvcs, xgetenv("XYMONNETSVCS"));
	for (i=0; (svcinfo[i].svcname); i++) {
		char *p;

		strcpy(searchstring, xgetenv("XYMONNETSVCS"));
		p = strtok(searchstring, " ");
		while (p && (strcmp(p, svcinfo[i].svcname) != 0)) p = strtok(NULL, " ");

		if (p == NULL) {
			strcat(xymonnetsvcs, " ");
			strcat(xymonnetsvcs, svcinfo[i].svcname);
		}
	}
	xfree(searchstring);

	if (debug) {
		dump_tcp_services();
		dbgprintf("XYMONNETSVCS set to : %s\n", xymonnetsvcs);
	}

	MEMUNDEFINE(filename);
	return xymonnetsvcs;
}
コード例 #23
0
void sendresult(void)
{
	struct req_t *rwalk;
	struct oid_t *owalk;
	char msgline[1024];
	char *currdev, *currhost;
	mibdef_t *mib;
	strbuffer_t *clientmsg = newstrbuffer(0);
	int havemsg = 0;
	int itemcount = 0;

	currhost = "";
	for (rwalk = reqhead; (rwalk); rwalk = rwalk->next) {
		if (strcmp(rwalk->hostname, currhost) != 0) {
			/* Flush buffer */
			if (havemsg) {
				sprintf(msgline, "\n.<!-- linecount=%d -->\n", itemcount);
				addtobuffer(clientmsg, msgline);
				sendmessage(STRBUF(clientmsg), NULL, XYMON_TIMEOUT, NULL);
			}
			clearstrbuffer(clientmsg);
			havemsg = 0;
			itemcount = 0;

			sprintf(msgline, "client/snmpcollect %s.snmpcollect snmp\n\n", rwalk->hostname);
			addtobuffer(clientmsg, msgline);
		}

		currdev = "";

		for (mib = first_mib(); (mib); mib = next_mib()) {
			clearstrbuffer(mib->resultbuf);
			mib->haveresult = 0;

			sprintf(msgline, "\n[%s]\nInterval=%d\nActiveIP=%s\n\n",
				mib->mibname,
				atoi(xgetenv("TASKSLEEP")),
				rwalk->hostip[rwalk->hostipidx]);
			addtobuffer(mib->resultbuf, msgline);
		}

		for (owalk = rwalk->oidhead; (owalk); owalk = owalk->next) {
			if (strcmp(currdev, owalk->devname)) {
				currdev = owalk->devname;	/* OK, because ->devname is permanent */

				if (*owalk->devname && (*owalk->devname != '-') ) {
					addtobuffer(owalk->mib->resultbuf, "\n<");
					addtobuffer(owalk->mib->resultbuf, owalk->devname);
					addtobuffer(owalk->mib->resultbuf, ">\n");
					itemcount++;
				}
			}

			addtobuffer(owalk->mib->resultbuf, "\t");
			addtobuffer(owalk->mib->resultbuf, owalk->oiddef->dsname);
			addtobuffer(owalk->mib->resultbuf, " = ");
			if (owalk->result) {
				int ival;
				unsigned int uval;

				switch (owalk->oiddef->conversion) {
				  case OID_CONVERT_U32:
					ival = atoi(owalk->result);
					memcpy(&uval, &ival, sizeof(uval));
					sprintf(msgline, "%u", uval);
					addtobuffer(owalk->mib->resultbuf, msgline);
					break;

				  default:
					addtobuffer(owalk->mib->resultbuf, owalk->result);
					break;
				}
			}
			else
				addtobuffer(owalk->mib->resultbuf, "NODATA");
			addtobuffer(owalk->mib->resultbuf, "\n");
			owalk->mib->haveresult = 1;
		}

		for (mib = first_mib(); (mib); mib = next_mib()) {
			if (mib->haveresult) {
				addtostrbuffer(clientmsg, mib->resultbuf);
				havemsg = 1;
			}
		}
	}

	if (havemsg) {
		sendmessage(STRBUF(clientmsg), NULL, XYMON_TIMEOUT, NULL);
	}
	
	freestrbuffer(clientmsg);
}
コード例 #24
0
void readconfig(char *cfgfn, int verbose)
{
	static void *cfgfiles = NULL;
	FILE *cfgfd;
	strbuffer_t *inbuf;

	struct req_t *reqitem = NULL;
	int tasksleep = atoi(xgetenv("TASKSLEEP"));

	mibdef_t *mib;

	/* Check if config was modified */
	if (cfgfiles) {
		if (!stackfmodified(cfgfiles)) {
			dbgprintf("No files changed, skipping reload\n");
			return;
		}
		else {
			stackfclist(&cfgfiles);
			cfgfiles = NULL;
		}
	}

	cfgfd = stackfopen(cfgfn, "r", &cfgfiles);
	if (cfgfd == NULL) {
		errprintf("Cannot open configuration files %s\n", cfgfn);
		return;
	}

	inbuf = newstrbuffer(0);
	while (stackfgets(inbuf, NULL)) {
		char *bot, *p, *mibidx;
		char savech;

		sanitize_input(inbuf, 0, 0);
		bot = STRBUF(inbuf) + strspn(STRBUF(inbuf), " \t");
		if ((*bot == '\0') || (*bot == '#')) continue;

		if (*bot == '[') {
			char *intvl = strchr(bot, '/');

			/*
			 * See if we're running a non-standard interval.
			 * If yes, then process only the records that match
			 * this TASKSLEEP setting.
			 */
			if (tasksleep != 300) {
				/* Non-default interval. Skip the host if it HASN'T got an interval setting */
				if (!intvl) continue;

				/* Also skip the hosts that have an interval different from the current */
				*intvl = '\0';	/* Clip the interval from the hostname */
				if (atoi(intvl+1) != tasksleep) continue;
			}
			else {
				/* Default interval. Skip the host if it HAS an interval setting */
				if (intvl) continue;
			}

			reqitem = (req_t *)calloc(1, sizeof(req_t));

			p = strchr(bot, ']'); if (p) *p = '\0';
			reqitem->hostname = strdup(bot + 1);
			if (p) *p = ']';

			reqitem->hostip[0] = reqitem->hostname;
			reqitem->version = SNMP_VERSION_1;
			reqitem->authmethod = SNMP_V3AUTH_MD5;
			reqitem->next = reqhead;
			reqhead = reqitem;

			continue;
		}

		/* If we have nowhere to put the data, then skip further processing */
		if (!reqitem) continue;

		if (strncmp(bot, "ip=", 3) == 0) {
			char *nextip = strtok(strdup(bot+3), ",");
			int i = 0;

			do {
				reqitem->hostip[i++] = nextip;
				nextip = strtok(NULL, ",");
			} while (nextip);
			continue;
		}

		if (strncmp(bot, "version=", 8) == 0) {
			switch (*(bot+8)) {
			  case '1': reqitem->version = SNMP_VERSION_1; break;
			  case '2': reqitem->version = SNMP_VERSION_2c; break;
			  case '3': reqitem->version = SNMP_VERSION_3; break;
			}
			continue;
		}

		if (strncmp(bot, "community=", 10) == 0) {
			reqitem->community = strdup(bot+10);
			continue;
		}

		if (strncmp(bot, "username="******"passphrase=", 10) == 0) {
			reqitem->passphrase = strdup(bot+10);
			continue;
		}

		if (strncmp(bot, "authmethod=", 10) == 0) {
			if (strcasecmp(bot+10, "md5") == 0)
				reqitem->authmethod = SNMP_V3AUTH_MD5;
			else if (strcasecmp(bot+10, "sha1") == 0)
				reqitem->authmethod = SNMP_V3AUTH_SHA1;
			else
				errprintf("Unknown SNMPv3 authentication method '%s'\n", bot+10);

			continue;
		}

		/* Custom mibs */
		p = bot + strcspn(bot, "= \t\r\n"); savech = *p; *p = '\0';
		mib = find_mib(bot);
		*p = savech; 
		p += strspn(p, "= \t");
		mibidx = p;
		if (mib) {
			int i;
			mibidx_t *iwalk = NULL;
			char *oid, *oidbuf;
			char *devname;
			oidset_t *swalk;

			setupmib(mib, verbose);
			if (mib->loadstatus != MIB_STATUS_LOADED) continue;	/* Cannot use this MIB */

			/* See if this is an entry where we must determine the index ourselves */
			if (*mibidx) {
				for (iwalk = mib->idxlist; (iwalk && (*mibidx != iwalk->marker)); iwalk = iwalk->next) ;
			}

			if ((*mibidx == '*') && !iwalk) {
				errprintf("Cannot do wildcard matching without an index (host %s, mib %s)\n",
					  reqitem->hostname, mib->mibname);
				continue;
			}

			if (!iwalk) {
				/* No key lookup */
				swalk = mib->oidlisthead;
				while (swalk) {
					reqitem->setnumber++;

					for (i=0; (i <= swalk->oidcount); i++) {
						if (*mibidx) {
							oid = oidbuf = (char *)malloc(strlen(swalk->oids[i].oid) + strlen(mibidx) + 2);
							sprintf(oidbuf, "%s.%s", swalk->oids[i].oid, mibidx);
							devname = mibidx;
						}
						else {
							oid = swalk->oids[i].oid;
							oidbuf = NULL;
							devname = "-";
						}

						make_oitem(mib, devname, &swalk->oids[i], oid, reqitem);
						if (oidbuf) xfree(oidbuf);
					}

					swalk = swalk->next;
				}

				reqitem->next_oid = reqitem->oidhead;
			}
			else {
				/* Add a key-record so we can try to locate the index */
				keyrecord_t *newitem = (keyrecord_t *)calloc(1, sizeof(keyrecord_t));
				char endmarks[6];

				mibidx++;	/* Skip the key-marker */
				sprintf(endmarks, "%s%c", ")]}>", iwalk->marker);
				p = mibidx + strcspn(mibidx, endmarks); *p = '\0';
				newitem->key = strdup(mibidx);
				newitem->indexmethod = iwalk;
				newitem->mib = mib;
				newitem->next = reqitem->keyrecords;
				reqitem->currentkey = reqitem->keyrecords = newitem;
			}

			continue;
		}
		else {
			errprintf("Unknown MIB (not in snmpmibs.cfg): '%s'\n", bot);
		}
	}

	stackfclose(cfgfd);
	freestrbuffer(inbuf);
}
コード例 #25
0
void add_http_test(testitem_t *t)
{
	http_data_t *httptest;

	char *dnsip = NULL;
	ssloptions_t *sslopt = NULL;
	char *sslopt_ciphers = NULL;
	int sslopt_version = SSLVERSION_DEFAULT;
	char *sslopt_clientcert = NULL;
	int  httpversion = HTTPVER_11;
	cookielist_t *ck = NULL;
	int firstcookie = 1;
	char *decodedurl;
	strbuffer_t *httprequest = newstrbuffer(0);

	/* Allocate the private data and initialize it */
	httptest = (http_data_t *) calloc(1, sizeof(http_data_t));
	t->privdata = (void *) httptest;

	decodedurl = decode_url(t->testspec, &httptest->weburl);
	if (!decodedurl) {
		errprintf("Invalid URL for http check: %s\n", t->testspec);
		return;
	}

	httptest->url = strdup(decodedurl);
	httptest->contlen = -1;
	httptest->parsestatus = (httptest->weburl.proxyurl ? httptest->weburl.proxyurl->parseerror : httptest->weburl.desturl->parseerror);

	/* If there was a parse error in the URL, dont run the test */
	if (httptest->parsestatus) return;


	if (httptest->weburl.proxyurl && (httptest->weburl.proxyurl->ip == NULL)) {
		dnsip = dnsresolve(httptest->weburl.proxyurl->host);
		if (dnsip) {
			httptest->weburl.proxyurl->ip = strdup(dnsip);
		}
		else {
			dbgprintf("Could not resolve URL hostname '%s'\n", httptest->weburl.proxyurl->host);
		}
	}
	else if (httptest->weburl.desturl->ip == NULL) {
		dnsip = dnsresolve(httptest->weburl.desturl->host);
		if (dnsip) {
			httptest->weburl.desturl->ip = strdup(dnsip);
		}
		else {
			dbgprintf("Could not resolve URL hostname '%s'\n", httptest->weburl.desturl->host);
		}
	}

	switch (httptest->weburl.testtype) {
	  case WEBTEST_PLAIN:
	  case WEBTEST_STATUS:
		httptest->contentcheck = CONTENTCHECK_NONE;
		break;

	  case WEBTEST_CONTENT:
		{
			FILE *contentfd;
			char contentfn[PATH_MAX];
			sprintf(contentfn, "%s/content/%s.substring", xgetenv("XYMONHOME"), commafy(t->host->hostname));
			contentfd = fopen(contentfn, "r");
			if (contentfd) {
				char l[MAX_LINE_LEN];
				char *p;

				if (fgets(l, sizeof(l), contentfd)) {
					p = strchr(l, '\n'); if (p) { *p = '\0'; };
					httptest->weburl.expdata = strdup(l);
				}
				else {
					httptest->contstatus = STATUS_CONTENTMATCH_NOFILE;
				}
				fclose(contentfd);
			}
			else {
				httptest->contstatus = STATUS_CONTENTMATCH_NOFILE;
			}
			httptest->contentcheck = CONTENTCHECK_REGEX;
		}
		break;

	  case WEBTEST_CONT:
		httptest->contentcheck = ((*httptest->weburl.expdata == '#') ?  CONTENTCHECK_DIGEST : CONTENTCHECK_REGEX);
		break;

	  case WEBTEST_NOCONT:
		httptest->contentcheck = CONTENTCHECK_NOREGEX;
		break;

	  case WEBTEST_POST:
	  case WEBTEST_SOAP:
		if (httptest->weburl.expdata == NULL) {
			httptest->contentcheck = CONTENTCHECK_NONE;
		}
		else {
			httptest->contentcheck = ((*httptest->weburl.expdata == '#') ?  CONTENTCHECK_DIGEST : CONTENTCHECK_REGEX);
		}
		break;

	  case WEBTEST_NOPOST:
	  case WEBTEST_NOSOAP:
		if (httptest->weburl.expdata == NULL) {
			httptest->contentcheck = CONTENTCHECK_NONE;
		}
		else {
			httptest->contentcheck = CONTENTCHECK_NOREGEX;
		}
		break;

	  case WEBTEST_TYPE:
		httptest->contentcheck = CONTENTCHECK_CONTENTTYPE;
		break;
	}

	/* Compile the hashes and regex's for those tests that use it */
	switch (httptest->contentcheck) {
	  case CONTENTCHECK_DIGEST:
		{
			char *hashfunc;

			httptest->exp = (void *) strdup(httptest->weburl.expdata+1);
			hashfunc = strchr(httptest->exp, ':');
			if (hashfunc) {
				*hashfunc = '\0';
				httptest->digestctx = digest_init(httptest->exp);
				*hashfunc = ':';
			}
		}
		break;

	  case CONTENTCHECK_REGEX:
	  case CONTENTCHECK_NOREGEX:
		{
			int status;

			httptest->exp = (void *) malloc(sizeof(regex_t));
			status = regcomp((regex_t *)httptest->exp, httptest->weburl.expdata, REG_EXTENDED|REG_NOSUB);
			if (status) {
				errprintf("Failed to compile regexp '%s' for URL %s\n", httptest->weburl.expdata, httptest->url);
				httptest->contstatus = STATUS_CONTENTMATCH_BADREGEX;
			}
		}
		break;

	  case CONTENTCHECK_CONTENTTYPE:
		httptest->exp = httptest->weburl.expdata;
		break;
	}

	if (httptest->weburl.desturl->schemeopts) {
		if      (strstr(httptest->weburl.desturl->schemeopts, "3"))      sslopt_version = SSLVERSION_V3;
		else if (strstr(httptest->weburl.desturl->schemeopts, "2"))      sslopt_version = SSLVERSION_V2;

		if      (strstr(httptest->weburl.desturl->schemeopts, "h"))      sslopt_ciphers = ciphershigh;
		else if (strstr(httptest->weburl.desturl->schemeopts, "m"))      sslopt_ciphers = ciphersmedium;

		if      (strstr(httptest->weburl.desturl->schemeopts, "10"))     httpversion    = HTTPVER_10;
		else if (strstr(httptest->weburl.desturl->schemeopts, "11"))     httpversion    = HTTPVER_11;
	}

	/* Get any cookies */
	load_cookies();

	/* Generate the request */
	addtobuffer(httprequest, (httptest->weburl.postdata ? "POST " : "GET "));
	switch (httpversion) {
		case HTTPVER_10: 
			addtobuffer(httprequest, (httptest->weburl.proxyurl ? httptest->url : httptest->weburl.desturl->relurl));
			addtobuffer(httprequest, " HTTP/1.0\r\n"); 
			break;

		case HTTPVER_11: 
			/*
			 * Experience shows that even though HTTP/1.1 says you should send the
			 * full URL, some servers (e.g. SunOne App server 7) choke on it.
			 * So just send the good-old relative URL unless we're proxying.
			 */
			addtobuffer(httprequest, (httptest->weburl.proxyurl ? httptest->url : httptest->weburl.desturl->relurl));
			addtobuffer(httprequest, " HTTP/1.1\r\n"); 
			addtobuffer(httprequest, "Connection: close\r\n"); 
			break;
	}

	addtobuffer(httprequest, "Host: ");
	addtobuffer(httprequest, httptest->weburl.desturl->host);
	if ((httptest->weburl.desturl->port != 80) && (httptest->weburl.desturl->port != 443)) {
		char hostporthdr[20];

		sprintf(hostporthdr, ":%d", httptest->weburl.desturl->port);
		addtobuffer(httprequest, hostporthdr);
	}
	addtobuffer(httprequest, "\r\n");

	if (httptest->weburl.postdata) {
		char hdr[100];
		int contlen = strlen(httptest->weburl.postdata);

		if (strncmp(httptest->weburl.postdata, "file:", 5) == 0) {
			/* Load the POST data from a file */
			FILE *pf = fopen(httptest->weburl.postdata+5, "r");
			if (pf == NULL) {
				errprintf("Cannot open POST data file %s\n", httptest->weburl.postdata+5);
				xfree(httptest->weburl.postdata);
				httptest->weburl.postdata = strdup("");
				contlen = 0;
			}
			else {
				struct stat st;

				if (fstat(fileno(pf), &st) == 0) {
					int n;

					xfree(httptest->weburl.postdata);
					httptest->weburl.postdata = (char *)malloc(st.st_size + 1); *(httptest->weburl.postdata) = '\0';
					n = fread(httptest->weburl.postdata, 1, st.st_size, pf);
					if (n == st.st_size) {
						*(httptest->weburl.postdata+n) = '\0';
						contlen = n;
					}
					else {
						errprintf("Cannot read file %s: %s\n", httptest->weburl.postdata+5, strerror(errno));
						contlen = 0;
					}
				}
				else {
					errprintf("Cannot stat file %s\n", httptest->weburl.postdata+5);
					httptest->weburl.postdata = strdup("");
					contlen = 0;
				}

				fclose(pf);
			}
		}

		addtobuffer(httprequest, "Content-type: ");
		if      (httptest->weburl.postcontenttype) 
			addtobuffer(httprequest, httptest->weburl.postcontenttype);
		else if ((httptest->weburl.testtype == WEBTEST_SOAP) || (httptest->weburl.testtype == WEBTEST_NOSOAP)) 
			addtobuffer(httprequest, "application/soap+xml; charset=utf-8");
		else 
			addtobuffer(httprequest, "application/x-www-form-urlencoded");
		addtobuffer(httprequest, "\r\n");

		sprintf(hdr, "Content-Length: %d\r\n", contlen);
		addtobuffer(httprequest, hdr);
	}
	{
		char useragent[100];
		void *hinfo;
		char *browser = NULL;

		hinfo = hostinfo(t->host->hostname);
		if (hinfo) browser = xmh_item(hinfo, XMH_BROWSER);

		if (browser) {
			sprintf(useragent, "User-Agent: %s\r\n", browser);
		}
		else {
			sprintf(useragent, "User-Agent: Xymon xymonnet/%s\r\n", VERSION);
		}

		addtobuffer(httprequest, useragent);
	}
	if (httptest->weburl.desturl->auth) {
		if (strncmp(httptest->weburl.desturl->auth, "CERT:", 5) == 0) {
			sslopt_clientcert = httptest->weburl.desturl->auth+5;
		}
		else {
			addtobuffer(httprequest, "Authorization: Basic ");
			addtobuffer(httprequest, base64encode(httptest->weburl.desturl->auth));
			addtobuffer(httprequest, "\r\n");
		}
	}
	if (httptest->weburl.proxyurl && httptest->weburl.proxyurl->auth) {
		addtobuffer(httprequest, "Proxy-Authorization: Basic ");
		addtobuffer(httprequest, base64encode(httptest->weburl.proxyurl->auth));
		addtobuffer(httprequest, "\r\n");
	}
	for (ck = cookiehead; (ck); ck = ck->next) {
		int useit = 0;

		if (ck->tailmatch) {
			int startpos = strlen(httptest->weburl.desturl->host) - strlen(ck->host);

			if (startpos > 0) useit = (strcmp(httptest->weburl.desturl->host+startpos, ck->host) == 0);
		}
		else useit = (strcmp(httptest->weburl.desturl->host, ck->host) == 0);
		if (useit) useit = (strncmp(ck->path, httptest->weburl.desturl->relurl, strlen(ck->path)) == 0);

		if (useit) {
			if (firstcookie) {
				addtobuffer(httprequest, "Cookie: ");
				firstcookie = 0;
			}
			addtobuffer(httprequest, ck->name);
			addtobuffer(httprequest, "=");
			addtobuffer(httprequest, ck->value);
			addtobuffer(httprequest, "\r\n");
		}
	}

	/* Some standard stuff */
	addtobuffer(httprequest, "Accept: */*\r\n");
	addtobuffer(httprequest, "Pragma: no-cache\r\n");

	if ((httptest->weburl.testtype == WEBTEST_SOAP) || (httptest->weburl.testtype == WEBTEST_NOSOAP)) {
		/* Must provide a SOAPAction header */
		addtobuffer(httprequest, "SOAPAction: ");
		addtobuffer(httprequest, httptest->url);
		addtobuffer(httprequest, "\r\n");
	}
	
	/* The final blank line terminates the headers */
	addtobuffer(httprequest, "\r\n");

	/* Post data goes last */
	if (httptest->weburl.postdata) addtobuffer(httprequest, httptest->weburl.postdata);

	/* Pickup any SSL options the user wants */
	if (sslopt_ciphers || (sslopt_version != SSLVERSION_DEFAULT) || sslopt_clientcert){
		sslopt = (ssloptions_t *) malloc(sizeof(ssloptions_t));
		sslopt->cipherlist = sslopt_ciphers;
		sslopt->sslversion = sslopt_version;
		sslopt->clientcert = sslopt_clientcert;
	}

	/* Add to TCP test queue */
	if (httptest->weburl.proxyurl == NULL) {
		httptest->tcptest = add_tcp_test(httptest->weburl.desturl->ip, 
						 httptest->weburl.desturl->port, 
						 httptest->weburl.desturl->scheme,
						 sslopt, t->srcip,
						 t->testspec, t->silenttest, grabstrbuffer(httprequest), 
						 httptest, tcp_http_data_callback, tcp_http_final_callback);
	}
	else {
		httptest->tcptest = add_tcp_test(httptest->weburl.proxyurl->ip, 
						 httptest->weburl.proxyurl->port, 
						 httptest->weburl.proxyurl->scheme,
						 sslopt, t->srcip,
						 t->testspec, t->silenttest, grabstrbuffer(httprequest), 
						 httptest, tcp_http_data_callback, tcp_http_final_callback);
	}
}
コード例 #26
0
ファイル: msgcache.c プロジェクト: tjyang/cpam
void grabdata(conn_t *conn)
{
	int n;
	char buf[8192];
	int pollid = 0;

	/* Get data from the connection socket - we know there is some */
	n = read(conn->sockfd, buf, sizeof(buf)-1);
	if (n <= -1) {
		/* Read failure */
		errprintf("Connection lost during read: %s\n", strerror(errno));
		conn->action = C_DONE;
		return;
	}

	if (n > 0) {
		/* Got some data - store it */
		buf[n] = '\0';
		addtobuffer(conn->msgbuf, buf);
		return;
	}

	/* Done reading - process the data */
	if (STRBUFLEN(conn->msgbuf) == 0) {
		/* No data ? We're done */
		conn->action = C_DONE;
		return;
	}

	/* 
	 * See what kind of message this is. If it's a "pullclient" message,
	 * save the contents of the message - this is the client configuration
	 * that we'll return the next time a client sends us the "client" message.
	 */

	if (strncmp(STRBUF(conn->msgbuf), "pullclient", 10) == 0) {
		char *clientcfg;
		int idnum;

		/* Access check */
		if (!oksender(serverlist, NULL, conn->caddr.sin_addr, STRBUF(conn->msgbuf))) {
			errprintf("Rejected pullclient request from %s\n",
				  inet_ntoa(conn->caddr.sin_addr));
			conn->action = C_DONE;
			return;
		}

		dbgprintf("Got pullclient request: %s\n", STRBUF(conn->msgbuf));

		/*
		 * The pollid is unique for each Xymon server. It is to allow
		 * multiple servers to pick up the same message, for resiliance.
		 */
		idnum = atoi(STRBUF(conn->msgbuf) + 10);
		if ((idnum <= 0) || (idnum > 31)) {
			pollid = 0;
		}
		else {
			pollid = (1 << idnum);
		}

		conn->ctype = C_SERVER;
		conn->action = C_WRITING;

		/* Save any client config sent to us */
		clientcfg = strchr(STRBUF(conn->msgbuf), '\n');
		if (clientcfg) {
			clientcfg++;
			if (client_response) xfree(client_response);
			client_response = strdup(clientcfg);
			dbgprintf("Saved client response: %s\n", client_response);
		}
	}
	else if (strncmp(STRBUF(conn->msgbuf), "client ", 7) == 0) {
		/*
		 * Got a "client" message. Return the client-response saved from
		 * earlier, if there is any. If not, then we're done.
		 */
		conn->ctype = C_CLIENT_CLIENT;
		conn->action = (client_response ? C_WRITING : C_DONE);
	}
	else {
		/* Message from a client, but not the "client" message. So no response. */
		conn->ctype = C_CLIENT_OTHER;
		conn->action = C_DONE;
	}

	/*
	 * Messages we receive from clients are stored on our outbound queue.
	 * If it's a local "client" message, respond with the queued response
	 * from the Xymon server. Other client messages get no response.
	 *
	 * Server messages get our outbound queue back in response.
	 */
	if (conn->ctype != C_SERVER) {
		/* Messages from clients go on the outbound queue */
		msgqueue_t *newq = calloc(1, sizeof(msgqueue_t));
		dbgprintf("Queuing outbound message\n");
		newq->tstamp = conn->tstamp;
		newq->msgbuf = conn->msgbuf;
		conn->msgbuf = NULL;
		if (qtail) {
			qtail->next = newq;
			qtail = newq;
		}
		else {
			qhead = qtail = newq;
		}

		if ((conn->ctype == C_CLIENT_CLIENT) && (conn->action == C_WRITING)) {
			/* Send the response back to the client */
			conn->msgbuf = newstrbuffer(0);
			addtobuffer(conn->msgbuf, client_response);

			/* 
			 * Dont drop the client response data. If for some reason
			 * the "client" request is repeated, he should still get
			 * the right answer that we have.
			 */
		}
	}
	else {
		/* A server has asked us for our list of messages */
		time_t now = getcurrenttime(NULL);
		msgqueue_t *mwalk;

		if (!qhead) {
			/* No queued messages */
			conn->action = C_DONE;
		}
		else {
			/* Build a message of all the queued data */
			clearstrbuffer(conn->msgbuf);

			/* Index line first */
			for (mwalk = qhead; (mwalk); mwalk = mwalk->next) {
				if ((mwalk->sentto & pollid) == 0) {
					char idx[20];
					sprintf(idx, "%d:%ld ", 
						STRBUFLEN(mwalk->msgbuf), (long)(now - mwalk->tstamp));
					addtobuffer(conn->msgbuf, idx);
				}
			}

			if (STRBUFLEN(conn->msgbuf) > 0) addtobuffer(conn->msgbuf, "\n");

			/* Then the stream of messages */
			for (mwalk = qhead; (mwalk); mwalk = mwalk->next) {
				if ((mwalk->sentto & pollid) == 0) {
					if (pollid) mwalk->sentto |= pollid;
					addtostrbuffer(conn->msgbuf, mwalk->msgbuf);
				}
			}

			if (STRBUFLEN(conn->msgbuf) == 0) {
				/* No data for this server */
				conn->action = C_DONE;
			}
		}
	}
}
コード例 #27
0
ファイル: msgcache.c プロジェクト: tjyang/cpam
int main(int argc, char *argv[])
{
	int daemonize = 1;
	int listenq = 10;
	char *pidfile = "msgcache.pid";
	int lsocket;
	struct sockaddr_in laddr;
	struct sigaction sa;
	int opt;

	/* Dont save the output from errprintf() */
	save_errbuf = 0;

	memset(&laddr, 0, sizeof(laddr));
	inet_aton("0.0.0.0", (struct in_addr *) &laddr.sin_addr.s_addr);
	laddr.sin_port = htons(1984);
	laddr.sin_family = AF_INET;

	for (opt=1; (opt < argc); opt++) {
		if (argnmatch(argv[opt], "--listen=")) {
			char *locaddr, *p;
			int locport;

			locaddr = strchr(argv[opt], '=')+1;
			p = strchr(locaddr, ':');
			if (p) { locport = atoi(p+1); *p = '\0'; } else locport = 1984;

			memset(&laddr, 0, sizeof(laddr));
			laddr.sin_port = htons(locport);
			laddr.sin_family = AF_INET;
			if (inet_aton(locaddr, (struct in_addr *) &laddr.sin_addr.s_addr) == 0) {
				errprintf("Invalid listen address %s\n", locaddr);
				return 1;
			}
		}
		else if (argnmatch(argv[opt], "--server=")) {
			/* Who is allowed to fetch cached messages */
			char *p = strchr(argv[opt], '=');
			serverlist = getsenderlist(p+1);
		}
		else if (argnmatch(argv[opt], "--max-age=")) {
			char *p = strchr(argv[opt], '=');
			maxage = atoi(p+1);
		}
		else if (argnmatch(argv[opt], "--lqueue=")) {
			char *p = strchr(argv[opt], '=');
			listenq = atoi(p+1);
		}
		else if (strcmp(argv[opt], "--daemon") == 0) {
			daemonize = 1;
		}
		else if (strcmp(argv[opt], "--no-daemon") == 0) {
			daemonize = 0;
		}
		else if (argnmatch(argv[opt], "--pidfile=")) {
			char *p = strchr(argv[opt], '=');
			pidfile = strdup(p+1);
		}
		else if (argnmatch(argv[opt], "--logfile=")) {
			char *p = strchr(argv[opt], '=');
			logfile = strdup(p+1);
		}
		else if (strcmp(argv[opt], "--debug") == 0) {
			debug = 1;
		}
		else if (strcmp(argv[opt], "--version") == 0) {
			printf("xymonproxy version %s\n", VERSION);
			return 0;
		}
	}

	/* Set up a socket to listen for new connections */
	lsocket = socket(AF_INET, SOCK_STREAM, 0);
	if (lsocket == -1) {
		errprintf("Cannot create listen socket (%s)\n", strerror(errno));
		return 1;
	}
	opt = 1;
	setsockopt(lsocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	fcntl(lsocket, F_SETFL, O_NONBLOCK);
	if (bind(lsocket, (struct sockaddr *)&laddr, sizeof(laddr)) == -1) {
		errprintf("Cannot bind to listen socket (%s)\n", strerror(errno));
		return 1;
	}

	if (listen(lsocket, listenq) == -1) {
		errprintf("Cannot listen (%s)\n", strerror(errno));
		return 1;
	}

	/* Redirect logging to the logfile, if requested */
	if (logfile) {
		reopen_file(logfile, "a", stdout);
		reopen_file(logfile, "a", stderr);
	}

	errprintf("Xymon msgcache version %s starting\n", VERSION);
	errprintf("Listening on %s:%d\n", inet_ntoa(laddr.sin_addr), ntohs(laddr.sin_port));

	if (daemonize) {
		pid_t childpid;

		reopen_file("/dev/null", "r", stdin);

		/* Become a daemon */
		childpid = fork();
		if (childpid < 0) {
			/* Fork failed */
			errprintf("Could not fork\n");
			exit(1);
		}
		else if (childpid > 0) {
			/* Parent - save PID and exit */
			FILE *fd = fopen(pidfile, "w");
			if (fd) {
				fprintf(fd, "%d\n", (int)childpid);
				fclose(fd);
			}
			exit(0);
		}
		/* Child (daemon) continues here */
		setsid();
	}

	setup_signalhandler("msgcache");
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sigmisc_handler;
	sigaction(SIGHUP, &sa, NULL);
	sigaction(SIGTERM, &sa, NULL);

	do {
		fd_set fdread, fdwrite;
		int maxfd;
		int n;
		conn_t *cwalk, *cprev;
		msgqueue_t *qwalk, *qprev;
		time_t mintstamp;

		/* Remove any finished connections */
		cwalk = chead; cprev = NULL;
		while (cwalk) {
			conn_t *zombie;

			if (cwalk->action != C_DONE) {
				cprev = cwalk;
				cwalk = cwalk->next;
				continue;
			}

			/* Close the socket */
			close(cwalk->sockfd);

			zombie = cwalk;
			if (cprev == NULL) {
				chead = zombie->next;
				cwalk = chead;
				cprev = NULL;
			}
			else {
				cprev->next = zombie->next;
				cwalk = zombie->next;
			}

			freestrbuffer(zombie->msgbuf);
			xfree(zombie);
		}
		ctail = chead;
		if (ctail) { while (ctail->next) ctail = ctail->next; }


		/* Remove expired messages */
		qwalk = qhead; qprev = NULL;
		mintstamp = getcurrenttime(NULL) - maxage;
		while (qwalk) {
			msgqueue_t *zombie;

			if (qwalk->tstamp > mintstamp) {
				/* Hasn't expired yet */
				qprev = qwalk;
				qwalk = qwalk->next;
				continue;
			}

			zombie = qwalk;
			if (qprev == NULL) {
				qhead = zombie->next;
				qwalk = qhead;
				qprev = NULL;
			}
			else {
				qprev->next = zombie->next;
				qwalk = zombie->next;
			}

			freestrbuffer(zombie->msgbuf);
			xfree(zombie);
		}
		qtail = qhead;
		if (qtail) { while (qtail->next) qtail = qtail->next; }


		/* Now we're ready to handle some data */
		FD_ZERO(&fdread);
		FD_ZERO(&fdwrite);

		/* Add the listen socket */
		FD_SET(lsocket, &fdread); 
		maxfd = lsocket;

		for (cwalk = chead; (cwalk); cwalk = cwalk->next) {
			switch (cwalk->action) {
			  case C_READING:
				FD_SET(cwalk->sockfd, &fdread); 
				if (cwalk->sockfd > maxfd) maxfd = cwalk->sockfd; 
				break;

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

			  case C_DONE:
				break;
			}
		}

		n = select(maxfd+1, &fdread, &fdwrite, NULL, NULL);

		if (n < 0) {
			if (errno == EINTR) continue;
			errprintf("select failed: %s\n", strerror(errno));
			return 0;
		}

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

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

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

			  case C_DONE:
				break;
			}
		}

		if (FD_ISSET(lsocket, &fdread)) {
			/* New incoming connection */
			conn_t *newconn;
			int caddrsize;

			dbgprintf("New connection\n");
			newconn = calloc(1, sizeof(conn_t));

			caddrsize = sizeof(newconn->caddr);
			newconn->sockfd = accept(lsocket, (struct sockaddr *)&newconn->caddr, &caddrsize);
			if (newconn->sockfd == -1) {
				/* accept() failure. Yes, it does happen! */
				dbgprintf("accept failure, ignoring connection (%s)\n", strerror(errno));
				xfree(newconn);
				newconn = NULL;
			}
			else {
				fcntl(newconn->sockfd, F_SETFL, O_NONBLOCK);
				newconn->action = C_READING;
				newconn->msgbuf = newstrbuffer(0);
				newconn->tstamp = getcurrenttime(NULL);
			}

			if (newconn) {
				if (ctail) { ctail->next = newconn; ctail = newconn; }
				else chead = ctail = newconn;
			}
		}

	} while (keeprunning);

	if (pidfile) unlink(pidfile);
	return 0;
}
コード例 #28
0
ファイル: environ.c プロジェクト: gvsurenderreddy/xymon-2
void loadenv(char *envfile, char *area)
{
	FILE *fd;
	strbuffer_t *inbuf;
	char *p, *oneenv;

	MEMDEFINE(l);
	inbuf = newstrbuffer(0);

	fd = stackfopen(envfile, "r", NULL);
	if (fd) {
		while (stackfgets(inbuf, NULL)) {
			char *equalpos;
			int appendto = 0;

			sanitize_input(inbuf, 1, 1);

			if ((STRBUFLEN(inbuf) == 0) || ((equalpos = strchr(STRBUF(inbuf), '=')) == NULL)) continue;

			appendto = ((equalpos > STRBUF(inbuf)) && (*(equalpos-1) == '+'));

			/*
			 * Do the environment "area" stuff: If the input
			 * is of the form AREA/NAME=VALUE, then setup the variable
			 * only if we're called with the correct AREA setting.
			 */
			oneenv = NULL;

			p = STRBUF(inbuf) + strcspn(STRBUF(inbuf), "=/");
			if (*p == '/') {
				if (area) {
					*p = '\0';
					if (strcasecmp(STRBUF(inbuf), area) == 0) oneenv = strdup(expand_env(p+1));
				}
			}
			else oneenv = strdup(expand_env(STRBUF(inbuf)));

			if (oneenv) {
				p = strchr(oneenv, '=');
				if (*(p+1) == '"') {
					/* Move string over the first '"' */
					memmove(p+1, p+2, strlen(p+2)+1);
					/* Kill a trailing '"' */
					if (*(oneenv + strlen(oneenv) - 1) == '"') *(oneenv + strlen(oneenv) - 1) = '\0';
				}

				if (appendto) {
					char *oldval, *addstring, *p;

					addstring = strchr(oneenv, '='); if (addstring) { *addstring = '\0'; addstring++; }
					p = strchr(oneenv, '+'); if (p) *p = '\0';

					oldval = getenv(oneenv);
					if (oldval) {
						char *combinedenv = (char *)malloc(strlen(oneenv) + strlen(oldval) + strlen(addstring) + 2);
						sprintf(combinedenv, "%s=%s%s", oneenv, oldval, (addstring));
						xfree(oneenv);
						oneenv = combinedenv;
					}
					else {
						/* oneenv is now VARxxVALUE, so fix it to be a normal env. variable format */
						strcat(oneenv, "=");
						memmove(oneenv+strlen(oneenv), addstring, strlen(addstring) + 1);
					}
				}

				if (putenv(oneenv) != 0) errprintf("Cannot set environment: %s\n", strerror(errno));
			}
		}
		stackfclose(fd);
	}
	else {
		errprintf("Cannot open env file %s - %s\n", envfile, strerror(errno));
	}

	freestrbuffer(inbuf);
	MEMUNDEFINE(l);
}
コード例 #29
0
ファイル: xymongrep.c プロジェクト: osvaldsson/xymon
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;
}
コード例 #30
0
ファイル: hobbit-confreport.c プロジェクト: tjyang/abmon
static void print_host(hostlist_t *host, htnames_t *testnames[], int testcount)
{
    int testi, rowcount, netcount;
    void *hinfo = hostinfo(host->hostname);
    char *dispname = NULL, *clientalias = NULL, *comment = NULL, *description = NULL, *pagepathtitle = NULL;
    char *net = NULL, *nkalerts = NULL;
    char *nktime = NULL, *downtime = NULL, *reporttime = NULL;
    char *itm;
    tag_t *taghead = NULL;
    int contidx = 0, haveping = 0;
    char contcol[1024];
    activealerts_t *alert;
    strbuffer_t *buf = newstrbuffer(0);

    fprintf(stdout, "<p style=\"page-break-before: always\">\n");
    fprintf(stdout, "<table width=\"100%%\" border=1 summary=\"%s configuration\">\n", host->hostname);

    pagepathtitle = bbh_item(hinfo, BBH_PAGEPATHTITLE);
    if (!pagepathtitle || (strlen(pagepathtitle) == 0)) pagepathtitle = "Top page";
    dispname = bbh_item(hinfo, BBH_DISPLAYNAME);
    if (dispname && (strcmp(dispname, host->hostname) == 0)) dispname = NULL;
    clientalias = bbh_item(hinfo, BBH_CLIENTALIAS);
    if (clientalias && (strcmp(clientalias, host->hostname) == 0)) clientalias = NULL;
    comment = bbh_item(hinfo, BBH_COMMENT);
    description = bbh_item(hinfo, BBH_DESCRIPTION);
    net = bbh_item(hinfo, BBH_NET);
    nkalerts = bbh_item(hinfo, BBH_NK);
    nktime = bbh_item(hinfo, BBH_NKTIME);
    if (!nktime) nktime = "24x7";
    else nktime = strdup(timespec_text(nktime));
    downtime = bbh_item(hinfo, BBH_DOWNTIME);
    if (downtime) downtime = strdup(timespec_text(downtime));
    reporttime = bbh_item(hinfo, BBH_REPORTTIME);
    if (!reporttime) reporttime = "24x7";
    else reporttime = strdup(timespec_text(reporttime));

    rowcount = 1;
    if (pagepathtitle) rowcount++;
    if (dispname || clientalias) rowcount++;
    if (comment) rowcount++;
    if (description) rowcount++;
    if (!newnkconfig && nktime) rowcount++;
    if (downtime) rowcount++;
    if (reporttime) rowcount++;

    fprintf(stdout, "<tr>\n");
    fprintf(stdout, "<th rowspan=%d align=left width=\"25%%\" valign=top>Basics</th>\n", rowcount);
    fprintf(stdout, "<th align=center>%s (%s)</th>\n",
            (dispname ? dispname : host->hostname), bbh_item(hinfo, BBH_IP));
    fprintf(stdout, "</tr>\n");

    if (dispname || clientalias) {
        fprintf(stdout, "<tr><td>Aliases:");
        if (dispname) fprintf(stdout, " %s", dispname);
        if (clientalias) fprintf(stdout, " %s", clientalias);
        fprintf(stdout, "</td></tr>\n");
    }
    if (pagepathtitle) fprintf(stdout, "<tr><td>Monitoring location: %s</td></tr>\n", pagepathtitle);
    if (comment) fprintf(stdout, "<tr><td>Comment: %s</td></tr>\n", comment);
    if (description) fprintf(stdout, "<tr><td>Description: %s</td></tr>\n", description);
    if (!newnkconfig && nktime) fprintf(stdout, "<tr><td>NK monitoring period: %s</td></tr>\n", nktime);
    if (downtime) fprintf(stdout, "<tr><td>Planned downtime: %s</td></tr>\n", downtime);
    if (reporttime) fprintf(stdout, "<tr><td>SLA Reporting Period: %s</td></tr>\n", reporttime);


    /* Build a list of the network tests */
    itm = bbh_item_walk(hinfo);
    while (itm) {
        char *visdata = NULL, *colname = NULL, *expdata = NULL;
        bburl_t bu;
        int dialuptest = 0, reversetest = 0, alwaystruetest = 0, httpextra = 0;

        if (*itm == '?') {
            dialuptest=1;
            itm++;
        }
        if (*itm == '!') {
            reversetest=1;
            itm++;
        }
        if (*itm == '~') {
            alwaystruetest=1;
            itm++;
        }

        if ( argnmatch(itm, "http")         ||
                argnmatch(itm, "content=http") ||
                argnmatch(itm, "cont;http")    ||
                argnmatch(itm, "cont=")        ||
                argnmatch(itm, "nocont;http")  ||
                argnmatch(itm, "nocont=")      ||
                argnmatch(itm, "post;http")    ||
                argnmatch(itm, "post=")        ||
                argnmatch(itm, "nopost;http")  ||
                argnmatch(itm, "nopost=")      ||
                argnmatch(itm, "type;http")    ||
                argnmatch(itm, "type=")        ) {
            visdata = decode_url(itm, &bu);
            colname = bu.columnname;
            if (!colname) {
                if (bu.expdata) {
                    httpextra = 1;
                    if (contidx == 0) {
                        colname = "content";
                        contidx++;
                    }
                    else {
                        sprintf(contcol, "content%d", contidx);
                        colname = contcol;
                        contidx++;
                    }
                }
                else {
                    colname = "http";
                }
            }
            expdata = bu.expdata;
        }
        else if (strncmp(itm, "rpc=", 4) == 0) {
            colname = "rpc";
            visdata = strdup(itm+4);
        }
        else if (strncmp(itm, "dns=", 4) == 0) {
            colname = "dns";
            visdata = strdup(itm+4);
        }
        else if (strncmp(itm, "dig=", 4) == 0) {
            colname = "dns";
            visdata = strdup(itm+4);
        }
        else if (strncmp(itm, pingplus, strlen(pingplus)) == 0) {
            haveping = 1;
            colname = pingcolumn;
            visdata = strdup(itm+strlen(pingplus));
        }
        else if (is_net_test(itm)) {
            colname = strdup(itm);
        }


        if (colname) {
            tag_t *newitem;

addtolist:
            for (newitem = taghead; (newitem && strcmp(newitem->columnname, colname)); newitem = newitem->next);

            if (!newitem) {
                newitem = (tag_t *)calloc(1, sizeof(tag_t));
                newitem->columnname = strdup(colname);
                newitem->visualdata = (visdata ? strdup(visdata) : NULL);
                newitem->expdata = (expdata ? strdup(expdata) : NULL);
                newitem->next = taghead;
                taghead = newitem;
            }
            else {
                /* Multiple tags for one column - must be http */
                newitem->visualdata = (char *)realloc(newitem->visualdata, strlen(newitem->visualdata) + strlen(visdata) + 5);
                strcat(newitem->visualdata, "<br>");
                strcat(newitem->visualdata, visdata);
            }

            if (httpextra) {
                httpextra = 0;
                colname = "http";
                expdata = NULL;
                goto addtolist;
            }
        }

        itm = bbh_item_walk(NULL);
    }

    if (!haveping && !bbh_item(hinfo, BBH_FLAG_NOCONN)) {
        for (testi = 0; (testi < testcount); testi++) {
            if (strcmp(testnames[testi]->name, pingcolumn) == 0) {
                tag_t *newitem = (tag_t *)calloc(1, sizeof(tag_t));
                newitem->columnname = strdup(pingcolumn);
                newitem->next = taghead;
                taghead = newitem;
            }
        }
    }

    /* Add the "badFOO" settings */
    itm = bbh_item_walk(hinfo);
    while (itm) {
        if (strncmp(itm, "bad", 3) == 0) {
            char *tname, *p;
            int b1, b2, b3, n = -1;
            tag_t *tag = NULL;

            tname = itm+3;
            p = strchr(tname, ':');
            if (p) {
                *p = '\0';
                n = sscanf(p+1, "%d:%d:%d", &b1, &b2, &b3);
                for (tag = taghead; (tag && strcmp(tag->columnname, tname)); tag = tag->next);
                *p = ':';
            }

            if (tag && (n == 3)) {
                tag->b1 = b1;
                tag->b2 = b2;
                tag->b3 = b3;
            }
        }

        itm = bbh_item_walk(NULL);
    }

    if (taghead) {
        fprintf(stdout, "<tr>\n");
        fprintf(stdout, "<th align=left valign=top>Network tests");
        if (net) fprintf(stdout, "<br>(from %s)", net);
        fprintf(stdout, "</th>\n");

        fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s network tests\">\n", host->hostname);
        fprintf(stdout, "<tr><th align=left valign=top>Service</th><th align=left valign=top>NK</th><th align=left valign=top>C/Y/R limits</th><th align=left valign=top>Specifics</th></tr>\n");
    }
    for (testi = 0, netcount = 0; (testi < testcount); testi++) {
        tag_t *twalk;

        for (twalk = taghead; (twalk && strcasecmp(twalk->columnname, testnames[testi]->name)); twalk = twalk->next);
        if (!twalk) continue;

        use_columndoc(testnames[testi]->name);
        fprintf(stdout, "<tr>");
        fprintf(stdout, "<td valign=top>%s</td>", testnames[testi]->name);
        fprintf(stdout, "<td valign=top>%s</td>", nkval(host->hostname, testnames[testi]->name, nkalerts));

        fprintf(stdout, "<td valign=top>");
        if (twalk->b1 || twalk->b2 || twalk->b3) {
            fprintf(stdout, "%d/%d/%d", twalk->b1, twalk->b2, twalk->b3);
        }
        else {
            fprintf(stdout, "-/-/-");
        }
        fprintf(stdout, "</td>");

        fprintf(stdout, "<td valign=top>");
        fprintf(stdout, "<i>%s</i>", (twalk->visualdata ? twalk->visualdata : "&nbsp;"));
        if (twalk->expdata) fprintf(stdout, " must return <i>'%s'</i>", twalk->expdata);
        fprintf(stdout, "</td>");

        fprintf(stdout, "</tr>");
        netcount++;
    }
    if (taghead) {
        fprintf(stdout, "</table></td>\n");
        fprintf(stdout, "</tr>\n");
    }


    if (netcount != testcount) {
        fprintf(stdout, "<tr>\n");
        fprintf(stdout, "<th align=left valign=top>Local tests</th>\n");
        fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s local tests\">\n", host->hostname);
        fprintf(stdout, "<tr><th align=left valign=top>Service</th><th align=left valign=top>NK</th><th align=left valign=top>C/Y/R limits</th><th align=left valign=top>Configuration <i>(NB: Thresholds on client may differ)</i></th></tr>\n");
    }
    for (testi = 0; (testi < testcount); testi++) {
        tag_t *twalk;

        for (twalk = taghead; (twalk && strcasecmp(twalk->columnname, testnames[testi]->name)); twalk = twalk->next);
        if (twalk) continue;

        use_columndoc(testnames[testi]->name);
        fprintf(stdout, "<tr>");
        fprintf(stdout, "<td valign=top>%s</td>", testnames[testi]->name);
        fprintf(stdout, "<td valign=top>%s</td>", nkval(host->hostname, testnames[testi]->name, nkalerts));
        fprintf(stdout, "<td valign=top>-/-/-</td>");

        /* Make up some default configuration data */
        fprintf(stdout, "<td valign=top>");
        if (strcmp(testnames[testi]->name, "cpu") == 0) {
            fprintf(stdout, "UNIX - Yellow: Load average > 1.5, Red: Load average > 3.0<br>");
            fprintf(stdout, "Windows - Yellow: CPU utilisation > 80%%, Red: CPU utilisation > 95%%");
        }
        else if (strcmp(testnames[testi]->name, "disk") == 0) {
            fprintf(stdout, "Default limits: Yellow 90%% full, Red 95%% full<br>\n");
            print_disklist(host->hostname);
        }
        else if (strcmp(testnames[testi]->name, "memory") == 0) {
            fprintf(stdout, "Yellow: swap/pagefile use > 80%%, Red: swap/pagefile use > 90%%");
        }
        else if (strcmp(testnames[testi]->name, "procs") == 0) {
            htnames_t *walk;

            if (!host->procs) fprintf(stdout, "No processes monitored<br>\n");

            for (walk = host->procs; (walk); walk = walk->next) {
                fprintf(stdout, "%s<br>\n", walk->name);
            }
        }
        else if (strcmp(testnames[testi]->name, "svcs") == 0) {
            htnames_t *walk;

            if (!host->svcs) fprintf(stdout, "No services monitored<br>\n");

            for (walk = host->svcs; (walk); walk = walk->next) {
                fprintf(stdout, "%s<br>\n", walk->name);
            }
        }
        else {
            fprintf(stdout, "&nbsp;");
        }
        fprintf(stdout, "</td>");

        fprintf(stdout, "</tr>");
    }
    if (netcount != testcount) {
        fprintf(stdout, "</table></td>\n");
        fprintf(stdout, "</tr>\n");
    }

    /* Do the alerts */
    alert = (activealerts_t *)calloc(1, sizeof(activealerts_t));
    alert->hostname = host->hostname;
    alert->location = bbh_item(hinfo, BBH_ALLPAGEPATHS);
    strcpy(alert->ip, "127.0.0.1");
    alert->color = COL_RED;
    alert->pagemessage = "";
    alert->state = A_PAGING;
    alert->cookie = 12345;
    alert_printmode(2);
    for (testi = 0; (testi < testcount); testi++) {
        alert->testname = testnames[testi]->name;
        if (have_recipient(alert, NULL)) print_alert_recipients(alert, buf);
    }
    xfree(alert);

    if (STRBUFLEN(buf) > 0) {
        fprintf(stdout, "<tr>\n");
        fprintf(stdout, "<th align=left valign=top>Alerts</th>\n");
        fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s alerts\">\n", host->hostname);
        fprintf(stdout, "<tr><th>Service</th><th>Recipient</th><th>1st Delay</th><th>Stop after</th><th>Repeat</th><th>Time of Day</th><th>Colors</th></tr>\n");

        fprintf(stdout, "%s", STRBUF(buf));

        fprintf(stdout, "</table></td>\n");
        fprintf(stdout, "</tr>\n");
    }

    /* Finish off this host */
    fprintf(stdout, "</table>\n");

    freestrbuffer(buf);
}