int main(int argc, char **argv) { char *queryp; int bool_balance; sanitize_input(&argc, argv); if (argv[1][0] == 's') { print_summary(argv[2]); exit(0); } mysql_start(); bool_balance = check_balance(&argc, argv); queryp = forge_query(&argc, argv); mysql_insert(queryp); if (bool_balance) calculate_balance(&argc, argv); mysql_stop(); return 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; }
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); }
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); }
/* * Encrypt the arbitrary input string under AES-CBC */ int encrypt(unsigned char **output, const char *input, unsigned int input_len) { unsigned int len, s_input_len; unsigned char *tmp; if (!rkey_init) { generate_rkey_and_iv(); rkey_init = 1; } s_input_len = sanitize_input(input, input_len); len = strlen(pre_str) + s_input_len + strlen(post_str); if (len % aes_128_block_len) len += (aes_128_block_len - (len % aes_128_block_len)); *output = malloc(len*sizeof(char)); if (NULL == output) return 0x00; tmp = malloc(len*sizeof(char)); if (NULL == tmp) return 0x00; memset(tmp, 0, len*sizeof(char)); memset(*output, 0, len*sizeof(char)); memcpy(tmp, pre_str, strlen(pre_str)*sizeof(*pre_str)); memcpy(tmp + strlen(pre_str)*sizeof(*pre_str), input , s_input_len*sizeof(*input)); memcpy(tmp + strlen(pre_str)*sizeof(*pre_str) + s_input_len*sizeof(*input), post_str , strlen(post_str)*sizeof(*post_str)); aes_128_encrypt_msg(*output, (unsigned char*) tmp, strlen(pre_str) + s_input_len + strlen(post_str), rkey, CBC, (union aes_128_init*) riv); free(tmp); return len; }
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; }
static void load_rrddefs(void) { char fn[PATH_MAX]; FILE *fd; strbuffer_t *inbuf = newstrbuffer(0); char *key = NULL, *p; char **defs = NULL; int defcount = 0; rrddeftree_t *newrec; rrddeftree = xtreeNew(strcasecmp); sprintf(fn, "%s/etc/rrddefinitions.cfg", xgetenv("XYMONHOME")); fd = stackfopen(fn, "r", NULL); if (fd == NULL) goto loaddone; while (stackfgets(inbuf, NULL)) { sanitize_input(inbuf, 1, 0); if (STRBUFLEN(inbuf) == 0) continue; if (*(STRBUF(inbuf)) == '[') { if (key && (defcount > 0)) { /* Save the current record */ newrec = (rrddeftree_t *)malloc(sizeof(rrddeftree_t)); newrec->key = key; newrec->defs = defs; newrec->count = defcount; xtreeAdd(rrddeftree, newrec->key, newrec); key = NULL; defs = NULL; defcount = 0; } key = strdup(STRBUF(inbuf)+1); p = strchr(key, ']'); if (p) *p = '\0'; } else if (key) { if (!defs) { defcount = 1; defs = (char **)malloc(sizeof(char *)); } else { defcount++; defs = (char **)realloc(defs, defcount * sizeof(char *)); } p = STRBUF(inbuf); p += strspn(p, " \t"); defs[defcount-1] = strdup(p); } } if (key && (defcount > 0)) { /* Save the last record */ newrec = (rrddeftree_t *)malloc(sizeof(rrddeftree_t)); newrec->key = key; newrec->defs = defs; newrec->count = defcount; xtreeAdd(rrddeftree, newrec->key, newrec); } stackfclose(fd); loaddone: freestrbuffer(inbuf); /* Check if the default record exists */ if (xtreeFind(rrddeftree, "") == xtreeEnd(rrddeftree)) { /* Create the default record */ newrec = (rrddeftree_t *)malloc(sizeof(rrddeftree_t)); newrec->key = strdup(""); newrec->defs = (char **)malloc(4 * sizeof(char *));; newrec->defs[0] = strdup("RRA:AVERAGE:0.5:1:576"); newrec->defs[1] = strdup("RRA:AVERAGE:0.5:6:576"); newrec->defs[2] = strdup("RRA:AVERAGE:0.5:24:576"); newrec->defs[3] = strdup("RRA:AVERAGE:0.5:288:576"); newrec->count = 4; xtreeAdd(rrddeftree, newrec->key, newrec); } }
/* * Load the $HOME/.netrc file with authentication tokens for HTTP tests. */ static void load_netrc(void) { #define WANT_TOKEN 0 #define MACHINEVAL 1 #define LOGINVAL 2 #define PASSVAL 3 #define OTHERVAL 4 static int loaded = 0; char netrcfn[MAXPATHLEN]; FILE *fd; strbuffer_t *inbuf; char *host, *login, *password, *p; int state = WANT_TOKEN; if (loaded) return; loaded = 1; MEMDEFINE(netrcfn); /* Look for $BBHOME/etc/netrc first, then the default ~/.netrc */ sprintf(netrcfn, "%s/etc/netrc", xgetenv("BBHOME")); fd = fopen(netrcfn, "r"); /* Can HOME be undefined ? Yes, on Solaris when started during boot */ if ((fd == NULL) && getenv("HOME")) { sprintf(netrcfn, "%s/.netrc", xgetenv("HOME")); fd = fopen(netrcfn, "r"); } if (fd == NULL) { MEMUNDEFINE(netrcfn); return; } host = login = password = NULL; initfgets(fd); inbuf = newstrbuffer(0); while (unlimfgets(inbuf, fd)) { sanitize_input(inbuf, 0, 0); if (STRBUFLEN(inbuf) != 0) { p = strtok(STRBUF(inbuf), " \t"); while (p) { switch (state) { case WANT_TOKEN: if (strcmp(p, "machine") == 0) state = MACHINEVAL; else if (strcmp(p, "login") == 0) state = LOGINVAL; else if (strcmp(p, "password") == 0) state = PASSVAL; else if (strcmp(p, "account") == 0) state = OTHERVAL; else if (strcmp(p, "macdef") == 0) state = OTHERVAL; else if (strcmp(p, "default") == 0) { host = ""; state = WANT_TOKEN; } else state = WANT_TOKEN; break; case MACHINEVAL: host = strdup(p); state = WANT_TOKEN; break; case LOGINVAL: login = strdup(p); state = WANT_TOKEN; break; case PASSVAL: password = strdup(p); state = WANT_TOKEN; break; case OTHERVAL: state = WANT_TOKEN; break; } if (host && login && password) { loginlist_t *item = (loginlist_t *) malloc(sizeof(loginlist_t)); item->host = host; item->auth = (char *) malloc(strlen(login) + strlen(password) + 2); sprintf(item->auth, "%s:%s", login, password); item->next = loginhead; loginhead = item; host = login = password = NULL; } p = strtok(NULL, " \t"); } } } fclose(fd); freestrbuffer(inbuf); MEMUNDEFINE(netrcfn); }
void load_checkpoint(char *filename) { char *subfn; FILE *fd; strbuffer_t *inbuf; char statuscmd[1024]; char *statusbuf = NULL; sendreturn_t *sres; fd = fopen(filename, "r"); if (fd == NULL) return; sprintf(statuscmd, "xymondboard color=%s fields=hostname,testname,color", xgetenv("ALERTCOLORS")); sres = newsendreturnbuf(1, NULL); sendmessage(statuscmd, NULL, XYMON_TIMEOUT, sres); statusbuf = getsendreturnstr(sres, 1); freesendreturnbuf(sres); initfgets(fd); inbuf = newstrbuffer(0); while (unlimfgets(inbuf, fd)) { char *item[20], *p; int i; sanitize_input(inbuf, 0, 0); i = 0; p = gettok(STRBUF(inbuf), "|"); while (p && (i < 20)) { item[i++] = p; p = gettok(NULL, "|"); } if (i == 9) { /* There was no ack message */ item[i++] = ""; } if (i > 9) { char *valid = NULL; activealerts_t *newalert = (activealerts_t *)calloc(1, sizeof(activealerts_t)); newalert->hostname = find_name(hostnames, item[0]); newalert->testname = find_name(testnames, item[1]); newalert->location = find_name(locations, item[2]); newalert->ip = strdup(item[3]); newalert->color = newalert->maxcolor = parse_color(item[4]); newalert->eventstart = (time_t) atoi(item[5]); newalert->nextalerttime = (time_t) atoi(item[6]); newalert->state = A_PAGING; if (statusbuf) { char *key; key = (char *)malloc(strlen(newalert->hostname) + strlen(newalert->testname) + 100); sprintf(key, "\n%s|%s|%s\n", newalert->hostname, newalert->testname, colorname(newalert->color)); valid = strstr(statusbuf, key); if (!valid && (strncmp(statusbuf, key+1, strlen(key+1)) == 0)) valid = statusbuf; xfree(key); } if (!valid) { errprintf("Stale alert for %s:%s dropped\n", newalert->hostname, newalert->testname); xfree(newalert); continue; } while (strcmp(item[7], statename[newalert->state]) && (newalert->state < A_DEAD)) newalert->state++; /* Config might have changed while we were down */ if (newalert->state == A_NORECIP) newalert->state = A_PAGING; newalert->pagemessage = newalert->ackmessage = NULL; if (strlen(item[8])) { nldecode(item[8]); newalert->pagemessage = strdup(item[8]); } if (strlen(item[9])) { nldecode(item[9]); newalert->ackmessage = strdup(item[9]); } add_active(newalert->hostname, newalert); } } fclose(fd); freestrbuffer(inbuf); subfn = (char *)malloc(strlen(filename)+5); sprintf(subfn, "%s.sub", filename); load_state(subfn, statusbuf); xfree(subfn); if (statusbuf) xfree(statusbuf); }
int main(int argc, char *argv[]) { strbuffer_t *inbuf; char *ackbuf; char *subjectline = NULL; char *returnpathline = NULL; char *fromline = NULL; char *firsttxtline = NULL; int inheaders = 1; char *p; pcre *subjexp; const char *errmsg; int errofs, result; int ovector[30]; char cookie[10]; int duration = 0; int argi; char *envarea = NULL; for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } } initfgets(stdin); inbuf = newstrbuffer(0); while (unlimfgets(inbuf, stdin)) { sanitize_input(inbuf, 0, 0); if (!inheaders) { /* We're in the message body. Look for a "delay=N" line here. */ if ((strncasecmp(STRBUF(inbuf), "delay=", 6) == 0) || (strncasecmp(STRBUF(inbuf), "delay ", 6) == 0)) { duration = durationvalue(STRBUF(inbuf)+6); continue; } else if ((strncasecmp(STRBUF(inbuf), "ack=", 4) == 0) || (strncasecmp(STRBUF(inbuf), "ack ", 4) == 0)) { /* Some systems cannot generate a subject. Allow them to ack * via text in the message body. */ subjectline = (char *)malloc(STRBUFLEN(inbuf) + 1024); sprintf(subjectline, "Subject: Xymon [%s]", STRBUF(inbuf)+4); } else if (*STRBUF(inbuf) && !firsttxtline) { /* Save the first line of the message body, but ignore blank lines */ firsttxtline = strdup(STRBUF(inbuf)); } continue; /* We don't care about the rest of the message body */ } /* See if we're at the end of the mail headers */ if (inheaders && (STRBUFLEN(inbuf) == 0)) { inheaders = 0; continue; } /* Is it one of those we want to keep ? */ if (strncasecmp(STRBUF(inbuf), "return-path:", 12) == 0) returnpathline = strdup(skipwhitespace(STRBUF(inbuf)+12)); else if (strncasecmp(STRBUF(inbuf), "from:", 5) == 0) fromline = strdup(skipwhitespace(STRBUF(inbuf)+5)); else if (strncasecmp(STRBUF(inbuf), "subject:", 8) == 0) subjectline = strdup(skipwhitespace(STRBUF(inbuf)+8)); } freestrbuffer(inbuf); /* No subject ? No deal */ if (subjectline == NULL) { dbgprintf("Subject-line not found\n"); return 1; } /* Get the alert cookie */ subjexp = pcre_compile(".*(Xymon|Hobbit|BB)[ -]* \\[*(-*[0-9]+)[\\]!]*", PCRE_CASELESS, &errmsg, &errofs, NULL); if (subjexp == NULL) { dbgprintf("pcre compile failed - 1\n"); return 2; } result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result < 0) { dbgprintf("Subject line did not match pattern\n"); return 3; /* Subject did not match what we expected */ } if (pcre_copy_substring(subjectline, ovector, result, 2, cookie, sizeof(cookie)) <= 0) { dbgprintf("Could not find cookie value\n"); return 4; /* No cookie */ } pcre_free(subjexp); /* See if there's a "DELAY=" delay-value also */ subjexp = pcre_compile(".*DELAY[ =]+([0-9]+[mhdw]*)", PCRE_CASELESS, &errmsg, &errofs, NULL); if (subjexp == NULL) { dbgprintf("pcre compile failed - 2\n"); return 2; } result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result >= 0) { char delaytxt[4096]; if (pcre_copy_substring(subjectline, ovector, result, 1, delaytxt, sizeof(delaytxt)) > 0) { duration = durationvalue(delaytxt); } } pcre_free(subjexp); /* See if there's a "msg" text also */ subjexp = pcre_compile(".*MSG[ =]+(.*)", PCRE_CASELESS, &errmsg, &errofs, NULL); if (subjexp == NULL) { dbgprintf("pcre compile failed - 3\n"); return 2; } result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (result >= 0) { char msgtxt[4096]; if (pcre_copy_substring(subjectline, ovector, result, 1, msgtxt, sizeof(msgtxt)) > 0) { firsttxtline = strdup(msgtxt); } } pcre_free(subjexp); /* Use the "return-path:" header if we didn't see a From: line */ if ((fromline == NULL) && returnpathline) fromline = returnpathline; if (fromline) { /* Remove '<' and '>' from the fromline - they mess up HTML */ while ((p = strchr(fromline, '<')) != NULL) *p = ' '; while ((p = strchr(fromline, '>')) != NULL) *p = ' '; } /* Setup the acknowledge message */ if (duration == 0) duration = 60; /* Default: Ack for 60 minutes */ if (firsttxtline == NULL) firsttxtline = "<No cause specified>"; ackbuf = (char *)malloc(4096 + strlen(firsttxtline) + (fromline ? strlen(fromline) : 0)); p = ackbuf; p += sprintf(p, "xymondack %s %d %s", cookie, duration, firsttxtline); if (fromline) { p += sprintf(p, "\nAcked by: %s", fromline); } if (debug) { printf("%s\n", ackbuf); return 0; } sendmessage(ackbuf, NULL, XYMON_TIMEOUT, NULL); return 0; }
int load_holidays(int year) { static void *configholidays = NULL; char fn[PATH_MAX]; FILE *fd; strbuffer_t *inbuf; holiday_t newholiday; xtreePos_t handle, commonhandle; char *setname = NULL; holidayset_t *commonhols; MEMDEFINE(fn); if (year == 0) { time_t tnow; struct tm *now; tnow = getcurrenttime(NULL); now = localtime(&tnow); year = now->tm_year; } else if (year > 1000) { year -= 1900; } sprintf(fn, "%s/etc/holidays.cfg", xgetenv("XYMONHOME")); /* First check if there were no modifications at all */ if (configholidays) { /* if the new year begins, the holidays have to be recalculated */ if (!stackfmodified(configholidays) && (year == current_year)){ dbgprintf("No files modified, skipping reload of %s\n", fn); MEMUNDEFINE(fn); return 0; } else { stackfclist(&configholidays); configholidays = NULL; } } reset_holidays(); fd = stackfopen(fn, "r", &configholidays); if (!fd) { errprintf("Cannot open configuration file %s\n", fn); MEMUNDEFINE(fn); return 0; } memset(&newholiday,0,sizeof(holiday_t)); inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { char *p, *delim, *arg1, *arg2; sanitize_input(inbuf, 1, 0); if (STRBUFLEN(inbuf) == 0) continue; p = STRBUF(inbuf); if (strncasecmp(p, "HOLIDAYLIKEWEEKDAY=", 19) == 0) { p+=19; holidays_like_weekday = atoi(p); if (holidays_like_weekday < -1 || holidays_like_weekday > 6) { holidays_like_weekday = -1; errprintf("Invalid HOLIDAYLIKEWEEKDAY in %s\n", fn); } continue; } if (*p == '[') { /* New set of holidays */ if (setname) xfree(setname); delim = strchr(p, ']'); if (delim) *delim = '\0'; setname = strdup(p+1); continue; } delim = strchr(p, ':'); if (delim) { memset(&newholiday,0,sizeof(holiday_t)); if (delim == p) { newholiday.desc = "untitled"; } else { *delim = '\0'; newholiday.desc = p; p=delim+1; } } arg1 = strtok(p, "="); while (arg1) { arg2=strtok(NULL," ,;\t\n\r"); if (!arg2) break; if (strncasecmp(arg1, "TYPE", 4) == 0) { if (strncasecmp(arg2, "STATIC", 6) == 0) newholiday.holtype = HOL_ABSOLUTE; else if (strncasecmp(arg2, "EASTER", 6) == 0) newholiday.holtype = HOL_EASTER; else if (strncasecmp(arg2, "4ADVENT", 7) == 0) newholiday.holtype = HOL_ADVENT; else if (strncasecmp(arg2, "MON", 3) == 0) newholiday.holtype = HOL_MON; else if (strncasecmp(arg2, "TUE", 3) == 0) newholiday.holtype = HOL_TUE; else if (strncasecmp(arg2, "WED", 3) == 0) newholiday.holtype = HOL_WED; else if (strncasecmp(arg2, "THU", 3) == 0) newholiday.holtype = HOL_THU; else if (strncasecmp(arg2, "FRI", 3) == 0) newholiday.holtype = HOL_FRI; else if (strncasecmp(arg2, "SAT", 3) == 0) newholiday.holtype = HOL_SAT; else if (strncasecmp(arg2, "SUN", 3) == 0) newholiday.holtype = HOL_SUN; else if (strncasecmp(arg2, "+MON", 4) == 0) newholiday.holtype = HOL_MON_AFTER; else if (strncasecmp(arg2, "+TUE", 4) == 0) newholiday.holtype = HOL_TUE_AFTER; else if (strncasecmp(arg2, "+WED", 4) == 0) newholiday.holtype = HOL_WED_AFTER; else if (strncasecmp(arg2, "+THU", 4) == 0) newholiday.holtype = HOL_THU_AFTER; else if (strncasecmp(arg2, "+FRI", 4) == 0) newholiday.holtype = HOL_FRI_AFTER; else if (strncasecmp(arg2, "+SAT", 4) == 0) newholiday.holtype = HOL_SAT_AFTER; else if (strncasecmp(arg2, "+SUN", 4) == 0) newholiday.holtype = HOL_SUN_AFTER; } else if (strncasecmp(arg1, "MONTH", 5) == 0) { newholiday.month=atoi(arg2); } else if (strncasecmp(arg1, "DAY", 3) == 0) { newholiday.day=atoi(arg2); } else if (strncasecmp(arg1, "OFFSET", 6) == 0) { newholiday.day=atoi(arg2); } else if (strncasecmp(arg1, "YEAR", 4) == 0) { newholiday.year=atoi(arg2); if (newholiday.year > 1000) { newholiday.year -= 1900; } } arg1 = strtok(NULL,"="); } add_holiday((setname ? setname : ""), year, &newholiday); } stackfclose(fd); freestrbuffer(inbuf); commonhandle = xtreeFind(holidays, ""); commonhols = (commonhandle != xtreeEnd(holidays)) ? (holidayset_t *)xtreeData(holidays, commonhandle) : NULL; for (handle = xtreeFirst(holidays); (handle != xtreeEnd(holidays)); handle = xtreeNext(holidays, handle)) { holidayset_t *oneset = (holidayset_t *)xtreeData(holidays, handle); if (commonhols && (oneset != commonhols)) { /* Add the common holidays to this set */ holiday_t *walk; for (walk = commonhols->head; (walk); walk = walk->next) add_holiday(oneset->key, year, walk); } oneset->head = msort(oneset->head, record_compare, record_getnext, record_setnext); } MEMUNDEFINE(fn); current_year = year; return 0; }
void load_config(char *conffn) { static void *configfiles = NULL; tasklist_t *twalk, *curtask = NULL; FILE *fd; strbuffer_t *inbuf; char *p; char myhostname[256]; /* First check if there were no modifications at all */ if (configfiles) { if (!stackfmodified(configfiles) && (!forcereload)) { dbgprintf("No files modified, skipping reload of %s\n", conffn); return; } else { stackfclist(&configfiles); configfiles = NULL; } } errprintf("Loading tasklist configuration from %s\n", conffn); if (gethostname(myhostname, sizeof(myhostname)) != 0) { errprintf("Cannot get the local hostname, using 'localhost' (error: %s)\n", strerror(errno)); strcpy(myhostname, "localhost"); } /* The cfload flag: -1=delete task, 0=old task unchanged, 1=new/changed task */ for (twalk = taskhead; (twalk); twalk = twalk->next) { twalk->cfload = -1; twalk->group = NULL; /* Create a copy, but retain the settings and pointers are the same */ twalk->copy = xmalloc(sizeof(tasklist_t)); memcpy(twalk->copy,twalk,sizeof(tasklist_t)); /* These should get cleared */ twalk->copy->next = NULL; twalk->copy->copy = NULL; /* And clean the values of all others, so that we really can detect a difference */ twalk->disabled = 0; twalk->cmd = NULL; twalk->interval = 0; twalk->maxruntime = 0; twalk->group = NULL; twalk->logfile = NULL; twalk->envfile = NULL; twalk->envarea = NULL; twalk->onhostptn = NULL; twalk->cronstr = NULL; twalk->crondate = NULL; twalk->depends = NULL; } fd = stackfopen(conffn, "r", &configfiles); if (fd == NULL) { errprintf("Cannot open configuration file %s: %s\n", conffn, strerror(errno)); return; } inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { sanitize_input(inbuf, 1, 0); if (STRBUFLEN(inbuf) == 0) continue; p = STRBUF(inbuf); if (*p == '[') { /* New task */ char *endp; /* get name */ p++; endp = strchr(p, ']'); if (endp == NULL) continue; *endp = '\0'; /* try to find the task */ for (twalk = taskhead; (twalk && (strcmp(twalk->key, p))); twalk = twalk->next); if (twalk) { curtask=twalk; } else { /* New task, just create it */ curtask = (tasklist_t *)calloc(1, sizeof(tasklist_t)); curtask->key = strdup(p); /* add it to the list */ if (taskhead == NULL) taskhead = curtask; else tasktail->next = curtask; tasktail = curtask; } /* mark task as configured */ curtask->cfload = 0; } else if (curtask && (strncasecmp(p, "CMD ", 4) == 0)) { p += 3; p += strspn(p, " \t"); /* Handle + - options as well */ if (*p == '+') { /* append to command */ if (curtask->cmd) { int l1 = strlen(curtask->cmd); int l2 = strlen(p); char *newcmd = xcalloc(1, l1+l2+1); strncpy(newcmd,curtask->cmd,l1); strncpy(newcmd+l1,p,l2); newcmd[l1]=' '; /* this also overwrites the + */ /* free and assign new */ xfreeassign(curtask->cmd,newcmd); } } else if (*p == '-') { /* remove from command */ if (curtask->cmd) { int l = strlen(p)-1; if (l > 0) { char *found; while((found = strstr(curtask->cmd,p+1)) != NULL) { /* doing a copy - can not use strcpy as we are overlapping */ char *s = found + l; while (*s) { *found=*s; found++; s++; } *found=0; } } else { errprintf("Configuration error, empty command removal (CMD -) for task %s\n", curtask->key); } } } else { xfreedup(curtask->cmd,p); } } else if (strncasecmp(p, "GROUP ", 6) == 0) { /* Note: GROUP can be used by itself to define a group, or inside a task definition */ char *groupname; int maxuse; grouplist_t *gwalk; p += 6; p += strspn(p, " \t"); groupname = p; p += strcspn(p, " \t"); if (isdigit((int) *p)) maxuse = atoi(p); else maxuse = 1; /* Find or create the grouplist entry */ for (gwalk = grouphead; (gwalk && (strcmp(gwalk->groupname, groupname))); gwalk = gwalk->next); if (gwalk == NULL) { gwalk = (grouplist_t *)malloc(sizeof(grouplist_t)); gwalk->groupname = strdup(groupname); gwalk->maxuse = maxuse; gwalk->currentuse = 0; gwalk->next = grouphead; grouphead = gwalk; } if (curtask) curtask->group = gwalk; } else if (curtask && (strncasecmp(p, "INTERVAL ", 9) == 0)) { char *tspec; p += 9; curtask->interval = atoi(p); tspec = p + strspn(p, "0123456789"); switch (*tspec) { case 'm': curtask->interval *= 60; break; /* Minutes */ case 'h': curtask->interval *= 3600; break; /* Hours */ case 'd': curtask->interval *= 86400; break; /* Days */ } } else if (curtask && (strncasecmp(p, "CRONDATE ", 9) == 0)) { p+= 9; xfreedup(curtask->cronstr,p); if (curtask->crondate) crondatefree(curtask->crondate); curtask->crondate = parse_cron_time(curtask->cronstr); if (!curtask->crondate) { errprintf("Can't parse cron date: %s->%s\n", curtask->key, curtask->cronstr); curtask->disabled = 1; } curtask->interval = -1; /* disable interval */ } else if (curtask && (strncasecmp(p, "MAXTIME ", 8) == 0)) { char *tspec; p += 8; curtask->maxruntime = atoi(p); tspec = p + strspn(p, "0123456789"); switch (*tspec) { case 'm': curtask->maxruntime *= 60; break; /* Minutes */ case 'h': curtask->maxruntime *= 3600; break; /* Hours */ case 'd': curtask->maxruntime *= 86400; break; /* Days */ } } else if (curtask && (strncasecmp(p, "LOGFILE ", 8) == 0)) { p += 7; p += strspn(p, " \t"); xfreedup(curtask->logfile,p); } else if (curtask && (strncasecmp(p, "NEEDS ", 6) == 0)) { p += 6; p += strspn(p, " \t"); for (twalk = taskhead; (twalk && strcmp(twalk->key, p)); twalk = twalk->next); if (twalk) { curtask->depends = twalk; } else { errprintf("Configuration error, unknown dependency %s->%s\n", curtask->key, p); } } else if (curtask && (strncasecmp(p, "ENVFILE ", 8) == 0)) { p += 7; p += strspn(p, " \t"); xfreedup(curtask->envfile,p); } else if (curtask && (strncasecmp(p, "ENVAREA ", 8) == 0)) { p += 7; p += strspn(p, " \t"); xfreedup(curtask->envarea,p); } else if (curtask && (strcasecmp(p, "DISABLED") == 0)) { curtask->disabled = 1; } else if (curtask && (strcasecmp(p, "ENABLED") == 0)) { curtask->disabled = 0; } else if (curtask && (strncasecmp(p, "ONHOST ", 7) == 0)) { regex_t cpattern; int status; p += 7; p += strspn(p, " \t"); xfreedup(curtask->onhostptn,p); /* Match the hostname against the pattern; if it doesnt match then disable the task */ status = regcomp(&cpattern, curtask->onhostptn, REG_EXTENDED|REG_ICASE|REG_NOSUB); if (status == 0) { status = regexec(&cpattern, myhostname, 0, NULL, 0); if (status == REG_NOMATCH) curtask->disabled = 1; } else { errprintf("ONHOST pattern '%s' is invalid\n", p); } } } stackfclose(fd); freestrbuffer(inbuf); /* Running tasks that have been deleted or changed are killed off now. */ for (twalk = taskhead; (twalk); twalk = twalk->next) { /* compare the current settings with the copy - if we have one */ if (twalk->cfload == 0) { if (twalk->copy) { /* compare the current version with the new version and decide if we have changed */ int changed=0; int reload=0; /* first the nummeric ones */ if (twalk->disabled!=twalk->copy->disabled) { changed++; } if (twalk->interval!=twalk->copy->interval) { changed++; } if (twalk->maxruntime!=twalk->copy->maxruntime) { changed++; } if (twalk->group!=twalk->copy->group) { changed++; reload++;} /* then the string versions */ #define twalkstrcmp(k,doreload) { \ if (twalk->k!=twalk->copy->k) { \ if (twalk->copy->k) { \ if (twalk->k) { \ if (strcmp(twalk->k,twalk->copy->k)) { \ changed++;reload+=doreload; \ } \ } else { \ changed++;reload+=doreload; \ } \ /* we can always delete the copy*/ \ xfree(twalk->copy->k); \ twalk->copy->k=NULL; \ } else { \ changed++;reload+=doreload; \ } \ } \ } twalkstrcmp(cmd,1); twalkstrcmp(logfile,1); twalkstrcmp(envfile,1); twalkstrcmp(envarea,1); twalkstrcmp(onhostptn,0); twalkstrcmp(cronstr,0); if ((twalk->copy->cronstr == NULL) && twalk->copy->crondate) { crondatefree(twalk->copy->crondate); twalk->copy->crondate = NULL; } /* we can release the copy now - not using xfree, as this releases it from the list making a mess...*/ xfreenull(twalk->copy); /* now make the decision for reloading - if we have changed, then we may assign cfload, - otherwise the entry does not exist any longer */ if (reload) { reload=1;} if (changed) { twalk->cfload=reload; } } else { /* new object, so we need to do this */ twalk->cfload=1; } } /* and based on this decide what to do */ switch (twalk->cfload) { case -1: /* Kill the task, if active */ if (twalk->pid) { dbgprintf("Killing task %s PID %d\n", twalk->key, (int)twalk->pid); twalk->beingkilled = 1; kill(twalk->pid, SIGTERM); } /* And prepare to free this tasklist entry */ xfreenull(twalk->key); xfreenull(twalk->cmd); xfreenull(twalk->logfile); xfreenull(twalk->envfile); xfreenull(twalk->envarea); xfreenull(twalk->onhostptn); xfreenull(twalk->cronstr); if (twalk->crondate) crondatefree(twalk->crondate); break; case 0: /* Do nothing */ break; case 1: /* Bounce the task, if it is active */ if (twalk->pid) { dbgprintf("Killing task %s PID %d\n", twalk->key, (int)twalk->pid); twalk->beingkilled = 1; kill(twalk->pid, SIGTERM); } break; } } /* First clean out dead tasks at the start of the list */ while (taskhead && (taskhead->cfload == -1)) { tasklist_t *tmp; tmp = taskhead; taskhead = taskhead->next; xfree(tmp); } /* Then unlink and free those inside the list */ twalk = taskhead; while (twalk && twalk->next) { tasklist_t *tmp; if (twalk->next->cfload == -1) { tmp = twalk->next; twalk->next = tmp->next; xfree(tmp); } else twalk = twalk->next; } if (taskhead == NULL) tasktail = NULL; else { tasktail = taskhead; while (tasktail->next) tasktail = tasktail->next; } /* Make sure group usage counts are correct (groups can change) */ for (twalk = taskhead; (twalk); twalk = twalk->next) { if (twalk->group) twalk->group->currentuse = 0; } for (twalk = taskhead; (twalk); twalk = twalk->next) { if (twalk->group && twalk->pid) twalk->group->currentuse++; } }
void load_config(char *conffn) { static void *configfiles = NULL; tasklist_t *twalk, *curtask = NULL; FILE *fd; strbuffer_t *inbuf; char *p; char myhostname[256]; /* First check if there were no modifications at all */ if (configfiles) { if (!stackfmodified(configfiles)){ dbgprintf("No files modified, skipping reload of %s\n", conffn); return; } else { stackfclist(&configfiles); configfiles = NULL; } } errprintf("Loading tasklist configuration from %s\n", conffn); if (gethostname(myhostname, sizeof(myhostname)) != 0) { errprintf("Cannot get the local hostname, using 'localhost' (error: %s)\n", strerror(errno)); strcpy(myhostname, "localhost"); } /* The cfload flag: -1=delete task, 0=old task unchanged, 1=new/changed task */ for (twalk = taskhead; (twalk); twalk = twalk->next) { twalk->cfload = -1; twalk->group = NULL; } fd = stackfopen(conffn, "r", &configfiles); if (fd == NULL) { errprintf("Cannot open configuration file %s: %s\n", conffn, strerror(errno)); return; } inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { sanitize_input(inbuf, 1, 0); if (STRBUFLEN(inbuf) == 0) continue; p = STRBUF(inbuf); if (*p == '[') { /* New task */ char *endp; if (curtask) { update_task(curtask); curtask = NULL; } p++; endp = strchr(p, ']'); if (endp == NULL) continue; *endp = '\0'; curtask = (tasklist_t *)calloc(1, sizeof(tasklist_t)); curtask->key = strdup(p); } else if (curtask && (strncasecmp(p, "CMD ", 4) == 0)) { p += 3; p += strspn(p, " \t"); curtask->cmd = strdup(p); } else if (strncasecmp(p, "GROUP ", 6) == 0) { /* Note: GROUP can be used by itself to define a group, or inside a task definition */ char *groupname; int maxuse; grouplist_t *gwalk; p += 6; p += strspn(p, " \t"); groupname = p; p += strcspn(p, " \t"); if (isdigit((int) *p)) maxuse = atoi(p); else maxuse = 1; /* Find or create the grouplist entry */ for (gwalk = grouphead; (gwalk && (strcmp(gwalk->groupname, groupname))); gwalk = gwalk->next); if (gwalk == NULL) { gwalk = (grouplist_t *)malloc(sizeof(grouplist_t)); gwalk->groupname = strdup(groupname); gwalk->maxuse = maxuse; gwalk->currentuse = 0; gwalk->next = grouphead; grouphead = gwalk; } if (curtask) curtask->group = gwalk; } else if (curtask && (strncasecmp(p, "INTERVAL ", 9) == 0)) { char *tspec; p += 9; curtask->interval = atoi(p); tspec = p + strspn(p, "0123456789"); switch (*tspec) { case 'm': curtask->interval *= 60; break; /* Minutes */ case 'h': curtask->interval *= 3600; break; /* Hours */ case 'd': curtask->interval *= 86400; break; /* Days */ } } else if (curtask && (strncasecmp(p, "CRONDATE ", 9) == 0)) { p+= 9; curtask->cronstr = strdup(p); curtask->crondate = parse_cron_time(curtask->cronstr); if (!curtask->crondate) { errprintf("Can't parse cron date: %s->%s", curtask->key, curtask->cronstr); curtask->disabled = 1; } curtask->interval = -1; /* disable interval */ } else if (curtask && (strncasecmp(p, "MAXTIME ", 8) == 0)) { char *tspec; p += 8; curtask->maxruntime = atoi(p); tspec = p + strspn(p, "0123456789"); switch (*tspec) { case 'm': curtask->maxruntime *= 60; break; /* Minutes */ case 'h': curtask->maxruntime *= 3600; break; /* Hours */ case 'd': curtask->maxruntime *= 86400; break; /* Days */ } } else if (curtask && (strncasecmp(p, "LOGFILE ", 8) == 0)) { p += 7; p += strspn(p, " \t"); curtask->logfile = strdup(p); } else if (curtask && (strncasecmp(p, "NEEDS ", 6) == 0)) { p += 6; p += strspn(p, " \t"); for (twalk = taskhead; (twalk && strcmp(twalk->key, p)); twalk = twalk->next); if (twalk) { curtask->depends = twalk; } else { errprintf("Configuration error, unknown dependency %s->%s", curtask->key, p); } } else if (curtask && (strncasecmp(p, "ENVFILE ", 8) == 0)) { p += 7; p += strspn(p, " \t"); curtask->envfile = strdup(p); } else if (curtask && (strncasecmp(p, "ENVAREA ", 8) == 0)) { p += 7; p += strspn(p, " \t"); curtask->envarea = strdup(p); } else if (curtask && (strcasecmp(p, "DISABLED") == 0)) { curtask->disabled = 1; } else if (curtask && (strncasecmp(p, "ONHOST ", 7) == 0)) { regex_t cpattern; int status; p += 7; p += strspn(p, " \t"); curtask->onhostptn = strdup(p); /* Match the hostname against the pattern; if it doesnt match then disable the task */ status = regcomp(&cpattern, curtask->onhostptn, REG_EXTENDED|REG_ICASE|REG_NOSUB); if (status == 0) { status = regexec(&cpattern, myhostname, 0, NULL, 0); if (status == REG_NOMATCH) curtask->disabled = 1; } else { errprintf("ONHOST pattern '%s' is invalid\n", p); } } } if (curtask) update_task(curtask); stackfclose(fd); freestrbuffer(inbuf); /* Running tasks that have been deleted or changed are killed off now. */ for (twalk = taskhead; (twalk); twalk = twalk->next) { switch (twalk->cfload) { case -1: /* Kill the task, if active */ if (twalk->pid) { dbgprintf("Killing task %s PID %d\n", twalk->key, (int)twalk->pid); twalk->beingkilled = 1; kill(twalk->pid, SIGTERM); } /* And prepare to free this tasklist entry */ xfree(twalk->key); xfree(twalk->cmd); if (twalk->logfile) xfree(twalk->logfile); if (twalk->envfile) xfree(twalk->envfile); if (twalk->envarea) xfree(twalk->envarea); if (twalk->onhostptn) xfree(twalk->onhostptn); if (twalk->cronstr) xfree(twalk->cronstr); if (twalk->crondate) crondatefree(twalk->crondate); break; case 0: /* Do nothing */ break; case 1: /* Bounce the task, if it is active */ if (twalk->pid) { dbgprintf("Killing task %s PID %d\n", twalk->key, (int)twalk->pid); twalk->beingkilled = 1; kill(twalk->pid, SIGTERM); } break; } } /* First clean out dead tasks at the start of the list */ while (taskhead && (taskhead->cfload == -1)) { tasklist_t *tmp; tmp = taskhead; taskhead = taskhead->next; xfree(tmp); } /* Then unlink and free those inside the list */ twalk = taskhead; while (twalk && twalk->next) { tasklist_t *tmp; if (twalk->next->cfload == -1) { tmp = twalk->next; twalk->next = tmp->next; xfree(tmp); } else twalk = twalk->next; } if (taskhead == NULL) tasktail = NULL; else { tasktail = taskhead; while (tasktail->next) tasktail = tasktail->next; } /* Make sure group usage counts are correct (groups can change) */ for (twalk = taskhead; (twalk); twalk = twalk->next) { if (twalk->group) twalk->group->currentuse = 0; } for (twalk = taskhead; (twalk); twalk = twalk->next) { if (twalk->group && twalk->pid) twalk->group->currentuse++; } }
int load_hostnames(char *bbhostsfn, char *extrainclude, int fqdn) { /* Return value: 0 for load OK, 1 for "No files changed since last load", -1 for error (file not found) */ static void *bbhfiles = NULL; FILE *bbhosts; int ip1, ip2, ip3, ip4, groupid, pageidx; char hostname[4096]; strbuffer_t *inbuf; pagelist_t *curtoppage, *curpage, *pgtail; namelist_t *nametail = NULL; RbtHandle htree; /* First check if there were no modifications at all */ if (bbhfiles) { if (!stackfmodified(bbhfiles)){ dbgprintf("No files modified, skipping reload of %s\n", bbhostsfn); return 1; } else { stackfclist(&bbhfiles); bbhfiles = NULL; } } MEMDEFINE(hostname); MEMDEFINE(l); configloaded = 1; initialize_hostlist(); curpage = curtoppage = pgtail = pghead; pageidx = groupid = 0; bbhosts = stackfopen(bbhostsfn, "r", &bbhfiles); if (bbhosts == NULL) return -1; inbuf = newstrbuffer(0); htree = rbtNew(name_compare); while (stackfgets(inbuf, extrainclude)) { sanitize_input(inbuf, 0, 0); if (strncmp(STRBUF(inbuf), "page", 4) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (get_page_name_title(STRBUF(inbuf), "page", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = strdup(name); newp->pagetitle = (title ? strdup(title) : NULL); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = curtoppage = newp; } } else if (strncmp(STRBUF(inbuf), "subpage", 7) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (get_page_name_title(STRBUF(inbuf), "subpage", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = malloc(strlen(curtoppage->pagepath) + strlen(name) + 2); sprintf(newp->pagepath, "%s/%s", curtoppage->pagepath, name); newp->pagetitle = malloc(strlen(curtoppage->pagetitle) + strlen(title) + 2); sprintf(newp->pagetitle, "%s/%s", curtoppage->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(STRBUF(inbuf), "subparent", 9) == 0) { pagelist_t *newp, *parent; char *pname, *name, *title; pageidx = groupid = 0; parent = NULL; if (get_page_name_title(STRBUF(inbuf), "subparent", &pname, &title) == 0) { for (parent = pghead; (parent && !pagematch(parent, pname)); parent = parent->next); } if (parent && (get_page_name_title(title, "", &name, &title) == 0)) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = malloc(strlen(parent->pagepath) + strlen(name) + 2); sprintf(newp->pagepath, "%s/%s", parent->pagepath, name); newp->pagetitle = malloc(strlen(parent->pagetitle) + strlen(title) + 2); sprintf(newp->pagetitle, "%s/%s", parent->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(STRBUF(inbuf), "group", 5) == 0) { groupid++; } else if (sscanf(STRBUF(inbuf), "%d.%d.%d.%d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) { char *startoftags, *tag, *delim; int elemidx, elemsize; char clientname[4096]; char downtime[4096]; char groupidstr[10]; RbtIterator handle; namelist_t *newitem = calloc(1, sizeof(namelist_t)); namelist_t *iwalk, *iprev; MEMDEFINE(clientname); MEMDEFINE(downtime); /* Hostname beginning with '@' are "no-display" hosts. But we still want them. */ if (*hostname == '@') memmove(hostname, hostname+1, strlen(hostname)); if (!fqdn) { /* Strip any domain from the hostname */ char *p = strchr(hostname, '.'); if (p) *p = '\0'; } sprintf(newitem->ip, "%d.%d.%d.%d", ip1, ip2, ip3, ip4); sprintf(groupidstr, "%d", groupid); newitem->groupid = strdup(groupidstr); newitem->pageindex = pageidx++; newitem->bbhostname = strdup(hostname); if (ip1 || ip2 || ip3 || ip4) newitem->preference = 1; else newitem->preference = 0; newitem->logname = strdup(newitem->bbhostname); { char *p = newitem->logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } } newitem->page = curpage; newitem->defaulthost = defaulthost; clientname[0] = downtime[0] = '\0'; startoftags = strchr(STRBUF(inbuf), '#'); if (startoftags == NULL) startoftags = ""; else startoftags++; startoftags += strspn(startoftags, " \t\r\n"); newitem->allelems = strdup(startoftags); elemsize = 5; newitem->elems = (char **)malloc((elemsize+1)*sizeof(char *)); tag = newitem->allelems; elemidx = 0; while (tag && *tag) { if (elemidx == elemsize) { elemsize += 5; newitem->elems = (char **)realloc(newitem->elems, (elemsize+1)*sizeof(char *)); } newitem->elems[elemidx] = tag; /* Skip until we hit a whitespace or a quote */ tag += strcspn(tag, " \t\r\n\""); if (*tag == '"') { delim = tag; /* Hit a quote - skip until the next matching quote */ tag = strchr(tag+1, '"'); if (tag != NULL) { /* Found end-quote, NULL the item here and move on */ *tag = '\0'; tag++; } /* Now move quoted data one byte down (including the NUL) to kill quotechar */ memmove(delim, delim+1, strlen(delim)); } else if (*tag) { /* Normal end of item, NULL it and move on */ *tag = '\0'; tag++; } else { /* End of line - no more to do. */ tag = NULL; } /* * If we find a "noconn", drop preference value to 0. * If we find a "prefer", up reference value to 2. */ if ((newitem->preference == 1) && (strcmp(newitem->elems[elemidx], "noconn") == 0)) newitem->preference = 0; else if (strcmp(newitem->elems[elemidx], "prefer") == 0) newitem->preference = 2; /* Skip whitespace until start of next tag */ if (tag) tag += strspn(tag, " \t\r\n"); elemidx++; } newitem->elems[elemidx] = NULL; /* See if this host is defined before */ handle = rbtFind(htree, newitem->bbhostname); if (strcasecmp(newitem->bbhostname, ".default.") == 0) { /* The pseudo DEFAULT host */ newitem->next = NULL; defaulthost = newitem; } else if (handle == rbtEnd(htree)) { /* New item, so add to end of list */ newitem->next = NULL; if (namehead == NULL) namehead = nametail = newitem; else { nametail->next = newitem; nametail = newitem; } rbtInsert(htree, newitem->bbhostname, newitem); } else { /* Find the existing record - compare the record pointer instead of the name */ namelist_t *existingrec = (namelist_t *)gettreeitem(htree, handle); for (iwalk = namehead, iprev = NULL; ((iwalk != existingrec) && iwalk); iprev = iwalk, iwalk = iwalk->next) ; if (newitem->preference <= iwalk->preference) { /* Add after the existing (more preferred) entry */ newitem->next = iwalk->next; iwalk->next = newitem; } else { /* New item has higher preference, so add before the iwalk item (i.e. after iprev) */ if (iprev == NULL) { newitem->next = namehead; namehead = newitem; } else { newitem->next = iprev->next; iprev->next = newitem; } } } newitem->clientname = bbh_find_item(newitem, BBH_CLIENTALIAS); if (newitem->clientname == NULL) newitem->clientname = newitem->bbhostname; newitem->downtime = bbh_find_item(newitem, BBH_DOWNTIME); MEMUNDEFINE(clientname); MEMUNDEFINE(downtime); } } stackfclose(bbhosts); freestrbuffer(inbuf); rbtDelete(htree); MEMUNDEFINE(hostname); MEMUNDEFINE(l); build_hosttree(); return 0; }
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); }
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); }
int load_alertconfig(char *configfn, int defcolors, int defaultinterval) { /* (Re)load the configuration file without leaking memory */ static void *configfiles = NULL; char fn[PATH_MAX]; FILE *fd; strbuffer_t *inbuf; char *p; rule_t *currule = NULL; recip_t *currcp = NULL, *rcptail = NULL; MEMDEFINE(fn); if (configfn) strcpy(fn, configfn); else sprintf(fn, "%s/etc/alerts.cfg", xgetenv("XYMONHOME")); /* First check if there were no modifications at all */ if (configfiles) { if (!stackfmodified(configfiles)){ dbgprintf("No files modified, skipping reload of %s\n", fn); MEMUNDEFINE(fn); return 0; } else { stackfclist(&configfiles); configfiles = NULL; } } fd = stackfopen(fn, "r", &configfiles); if (!fd) { errprintf("Cannot open configuration file %s: %s\n", fn, strerror(errno)); MEMUNDEFINE(fn); return 0; } /* First, clean out the old rule set */ while (rulehead) { rule_t *trule; if (rulehead->criteria) { free_criteria(rulehead->criteria); xfree(rulehead->criteria); } while (rulehead->recipients) { recip_t *trecip = rulehead->recipients; if (trecip->criteria) { recip_t *rwalk; /* Clear out the duplicate criteria that may exist, to avoid double-free'ing them */ for (rwalk = trecip->next; (rwalk); rwalk = rwalk->next) { if (rwalk->criteria == trecip->criteria) rwalk->criteria = NULL; } free_criteria(trecip->criteria); xfree(trecip->criteria); } if (trecip->recipient) xfree(trecip->recipient); if (trecip->scriptname) xfree(trecip->scriptname); rulehead->recipients = rulehead->recipients->next; xfree(trecip); } trule = rulehead; rulehead = rulehead->next; xfree(trule); } while (tokhead) { token_t *ttok; if (tokhead->name) xfree(tokhead->name); if (tokhead->value) xfree(tokhead->value); ttok = tokhead; tokhead = tokhead->next; xfree(ttok); } defaultcolors = defcolors; MEMDEFINE(cfline); cfid = 0; inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { int firsttoken = 1; int mailcmdactive = 0, scriptcmdactive = 0; recip_t *curlinerecips = NULL; cfid++; sanitize_input(inbuf, 1, 0); /* Skip empty lines */ if (STRBUFLEN(inbuf) == 0) continue; if ((*STRBUF(inbuf) == '$') && strchr(STRBUF(inbuf), '=')) { /* Define a macro */ token_t *newtok = (token_t *) malloc(sizeof(token_t)); char *delim; delim = strchr(STRBUF(inbuf), '='); *delim = '\0'; newtok->name = strdup(STRBUF(inbuf)+1); /* Skip the '$' */ newtok->value = strdup(preprocess(delim+1)); newtok->next = tokhead; tokhead = newtok; continue; } strncpy(cfline, STRBUF(inbuf), (sizeof(cfline)-1)); cfline[sizeof(cfline)-1] = '\0'; /* Expand macros inside the line before parsing */ p = strtok(preprocess(STRBUF(inbuf)), " \t"); while (p) { if ((strncasecmp(p, "PAGE=", 5) == 0) || (strncasecmp(p, "PAGES=", 6) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->pagespec = strdup(val); if (*(crit->pagespec) == '%') crit->pagespecre = compileregex(crit->pagespec+1); firsttoken = 0; } else if ((strncasecmp(p, "EXPAGE=", 7) == 0) || (strncasecmp(p, "EXPAGES=", 8) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->expagespec = strdup(val); if (*(crit->expagespec) == '%') crit->expagespecre = compileregex(crit->expagespec+1); firsttoken = 0; } else if ((strncasecmp(p, "DISPLAYGROUP=", 13) == 0) || (strncasecmp(p, "DISPLAYGROUPS=", 14) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->dgspec = strdup(val); if (*(crit->dgspec) == '%') crit->dgspecre = compileregex(crit->dgspec+1); firsttoken = 0; } else if ((strncasecmp(p, "EXDISPLAYGROUP=", 15) == 0) || (strncasecmp(p, "EXDISPLAYGROUPS=", 16) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exdgspec = strdup(val); if (*(crit->exdgspec) == '%') crit->exdgspecre = compileregex(crit->exdgspec+1); firsttoken = 0; } else if ((strncasecmp(p, "HOST=", 5) == 0) || (strncasecmp(p, "HOSTS=", 6) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->hostspec = strdup(val); if (*(crit->hostspec) == '%') crit->hostspecre = compileregex(crit->hostspec+1); firsttoken = 0; } else if ((strncasecmp(p, "EXHOST=", 7) == 0) || (strncasecmp(p, "EXHOSTS=", 8) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exhostspec = strdup(val); if (*(crit->exhostspec) == '%') crit->exhostspecre = compileregex(crit->exhostspec+1); firsttoken = 0; } else if ((strncasecmp(p, "SERVICE=", 8) == 0) || (strncasecmp(p, "SERVICES=", 9) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->svcspec = strdup(val); if (*(crit->svcspec) == '%') crit->svcspecre = compileregex(crit->svcspec+1); firsttoken = 0; } else if ((strncasecmp(p, "EXSERVICE=", 10) == 0) || (strncasecmp(p, "EXSERVICES=", 11) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exsvcspec = strdup(val); if (*(crit->exsvcspec) == '%') crit->exsvcspecre = compileregex(crit->exsvcspec+1); firsttoken = 0; } else if (strncasecmp(p, "CLASS=", 6) == 0) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->classspec = strdup(val); if (*(crit->classspec) == '%') crit->classspecre = compileregex(crit->classspec+1); firsttoken = 0; } else if (strncasecmp(p, "EXCLASS=", 8) == 0) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exclassspec = strdup(val); if (*(crit->exclassspec) == '%') crit->exclassspecre = compileregex(crit->exclassspec+1); firsttoken = 0; } else if (strncasecmp(p, "GROUP=", 6) == 0) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->groupspec = strdup(val); if (*(crit->groupspec) == '%') crit->groupspecre = compileregex(crit->groupspec+1); firsttoken = 0; } else if (strncasecmp(p, "EXGROUP=", 8) == 0) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->exgroupspec = strdup(val); if (*(crit->exgroupspec) == '%') crit->exgroupspecre = compileregex(crit->exgroupspec+1); firsttoken = 0; } else if ((strncasecmp(p, "COLOR=", 6) == 0) || (strncasecmp(p, "COLORS=", 7) == 0)) { criteria_t *crit; char *c1, *c2; int cval, reverse = 0; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); /* Put a value in crit->colors so we know there is an explicit color setting */ crit->colors = (1 << 30); c1 = strchr(p, '=')+1; /* * If the first colorspec is "!color", then apply the default colors and * subtract colors from that. */ if (*c1 == '!') crit->colors |= defaultcolors; do { c2 = strchr(c1, ','); if (c2) *c2 = '\0'; if (*c1 == '!') { reverse=1; c1++; } cval = (1 << parse_color(c1)); if (reverse) crit->colors &= (~cval); else crit->colors |= cval; if (c2) c1 = (c2+1); else c1 = NULL; } while (c1); firsttoken = 0; } else if ((strncasecmp(p, "TIME=", 5) == 0) || (strncasecmp(p, "TIMES=", 6) == 0)) { char *val; criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } val = strchr(p, '=')+1; crit = setup_criteria(&currule, &currcp); crit->timespec = strdup(val); firsttoken = 0; } else if (strncasecmp(p, "DURATION", 8) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); if (*(p+8) == '>') crit->minduration = 60*durationvalue(p+9); else if (*(p+8) == '<') crit->maxduration = 60*durationvalue(p+9); else errprintf("Ignoring invalid DURATION at line %d: %s\n",cfid, p); firsttoken = 0; } else if (strncasecmp(p, "RECOVERED", 9) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); crit->sendrecovered = SR_WANTED; firsttoken = 0; } else if (strncasecmp(p, "NORECOVERED", 11) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); crit->sendrecovered = SR_NOTWANTED; firsttoken = 0; } else if (strncasecmp(p, "NOTICE", 6) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); crit->sendnotice = SR_WANTED; firsttoken = 0; } else if (strncasecmp(p, "NONOTICE", 8) == 0) { criteria_t *crit; if (firsttoken) { flush_rule(currule); currule = NULL; currcp = NULL; pstate = P_NONE; } crit = setup_criteria(&currule, &currcp); crit->sendnotice = SR_NOTWANTED; firsttoken = 0; } else if ((pstate == P_RECIP) && (strncasecmp(p, "FORMAT=", 7) == 0)) { if (!currcp) errprintf("FORMAT used without a recipient (line %d), ignored\n", cfid); else if (strcasecmp(p+7, "TEXT") == 0) currcp->format = ALERTFORM_TEXT; else if (strcasecmp(p+7, "PLAIN") == 0) currcp->format = ALERTFORM_PLAIN; else if (strcasecmp(p+7, "SMS") == 0) currcp->format = ALERTFORM_SMS; else if (strcasecmp(p+7, "PAGER") == 0) currcp->format = ALERTFORM_PAGER; else if (strcasecmp(p+7, "SCRIPT") == 0) currcp->format = ALERTFORM_SCRIPT; else errprintf("Unknown FORMAT setting '%s' ignored\n", p); firsttoken = 0; } else if ((pstate == P_RECIP) && (strncasecmp(p, "REPEAT=", 7) == 0)) { if (!currcp) errprintf("REPEAT used without a recipient (line %d), ignored\n", cfid); else currcp->interval = 60*durationvalue(p+7); firsttoken = 0; } else if ((pstate == P_RECIP) && (strcasecmp(p, "STOP") == 0)) { if (!currcp) errprintf("STOP used without a recipient (line %d), ignored\n", cfid); else currcp->stoprule = 1; firsttoken = 0; } else if ((pstate == P_RECIP) && (strcasecmp(p, "UNMATCHED") == 0)) { if (!currcp) errprintf("UNMATCHED used without a recipient (line %d), ignored\n", cfid); else currcp->unmatchedonly = 1; firsttoken = 0; } else if ((pstate == P_RECIP) && (strncasecmp(p, "NOALERT", 7) == 0)) { if (!currcp) errprintf("NOALERT used without a recipient (line %d), ignored\n", cfid); else currcp->noalerts = 1; firsttoken = 0; } else if (currule && ((strncasecmp(p, "MAIL", 4) == 0) || mailcmdactive) ) { recip_t *newrcp; mailcmdactive = 1; newrcp = (recip_t *)calloc(1, sizeof(recip_t)); newrcp->cfid = cfid; newrcp->method = M_MAIL; newrcp->format = ALERTFORM_TEXT; if (strncasecmp(p, "MAIL=", 5) == 0) { p += 5; } else if (strcasecmp(p, "MAIL") == 0) { p = strtok(NULL, " \t"); } else { /* Second recipient on a rule - do nothing */ } if (p) { newrcp->recipient = strdup(p); newrcp->interval = defaultinterval; currcp = newrcp; if (curlinerecips == NULL) curlinerecips = newrcp; pstate = P_RECIP; if (currule->recipients == NULL) currule->recipients = rcptail = newrcp; else { rcptail->next = newrcp; rcptail = newrcp; } } else { errprintf("Ignoring MAIL with no recipient at line %d\n", cfid); xfree(newrcp); } firsttoken = 0; } else if (currule && ((strncasecmp(p, "SCRIPT", 6) == 0) || scriptcmdactive)) { recip_t *newrcp; scriptcmdactive = 1; newrcp = (recip_t *)calloc(1, sizeof(recip_t)); newrcp->cfid = cfid; newrcp->method = M_SCRIPT; newrcp->format = ALERTFORM_SCRIPT; if (strncasecmp(p, "SCRIPT=", 7) == 0) { p += 7; newrcp->scriptname = strdup(p); p = strtok(NULL, " \t"); } else if (strcasecmp(p, "SCRIPT") == 0) { p = strtok(NULL, " \t"); if (p) { newrcp->scriptname = strdup(p); p = strtok(NULL, " \t"); } else { errprintf("Invalid SCRIPT command at line %d\n", cfid); } } else { /* A second recipient for the same script as the previous one */ newrcp->scriptname = strdup(currcp->scriptname); } if (p) { newrcp->recipient = strdup(p); newrcp->interval = defaultinterval; currcp = newrcp; if (curlinerecips == NULL) curlinerecips = newrcp; pstate = P_RECIP; if (currule->recipients == NULL) currule->recipients = rcptail = newrcp; else { rcptail->next = newrcp; rcptail = newrcp; } } else { errprintf("Ignoring SCRIPT with no recipient at line %d\n", cfid); if (newrcp->scriptname) xfree(newrcp->scriptname); xfree(newrcp); } firsttoken = 0; } else if (currule && (strncasecmp(p, "IGNORE", 6) == 0)) { recip_t *newrcp; newrcp = (recip_t *)calloc(1, sizeof(recip_t)); newrcp->cfid = cfid; newrcp->method = M_IGNORE; newrcp->format = ALERTFORM_NONE; newrcp->interval = defaultinterval; newrcp->stoprule = 1; currcp = newrcp; if (curlinerecips == NULL) curlinerecips = newrcp; pstate = P_RECIP; if (currule->recipients == NULL) currule->recipients = rcptail = newrcp; else { rcptail->next = newrcp; rcptail = newrcp; } firsttoken = 0; } else { errprintf("Ignored unknown/unexpected token '%s' at line %d\n", p, cfid); } if (p) p = strtok(NULL, " \t"); } if (curlinerecips && currcp && (curlinerecips != currcp)) { /* We have multiple recipients on one line. Make sure criteria etc. get copied */ recip_t *rwalk; /* All criteria etc. have been set on the last recipient (currcp) */ for (rwalk = curlinerecips; (rwalk != currcp); rwalk = rwalk->next) { rwalk->format = currcp->format; rwalk->interval = currcp->interval; rwalk->criteria = currcp->criteria; rwalk->noalerts = currcp->noalerts; } } } flush_rule(currule); stackfclose(fd); freestrbuffer(inbuf); MEMUNDEFINE(cfline); MEMUNDEFINE(fn); return 1; }