Esempio n. 1
0
// ==================================================================
	void hatch::OnImportDiz()
// ==================================================================
{
FILE	*fp;
CString desc;
CString fname;
char	buf[1000];
char	path[MAX_PATH];
char	fpath[MAX_PATH];
int		ret=0;

	m_filename.GetWindowText(fname);
    trim_all(fname);
	if (fname.GetLength()<2)
		ERR_MSG_RET("W_NOFFFD");

	make_path(path,gc.BasePath,"_TMP");
	make_path(fpath,path,"file_id.diz");
	_mkdir(path);

	if (!extract_file(fname,path))
	{
		err_out("E_EXTFAD",fname);
		ret=0;
		goto exit;
	}
	fp=fopen(fpath,"rt");
	if (fp)
	{
		while (fgets(buf,999,fp))
			desc+=buf;

		ret=1;
		fclose(fp);
	}

exit:
	SafeFileDelete(path,FALSE);

	if (!ret)
		ERR_MSG_RET("W_NOFIDDF");

	trim_all(desc);
	desc.Replace("\n"," ");
	desc.OemToAnsi();
	m_description.SetWindowText(desc);
}
prvreader::PrvEvent* prvreader::PrvParser::parseLine()
{
    string line;
    PrvEvent* prvEvent;
    if (prvStream){
        if(getline(*prvStream,line)){
            lineNumber++;
            if (lineNumber%10000==0){
                Message::Debug(to_string(lineNumber)+ " lines processed");
            }
            replace(line.begin(), line.end(), '\t', ' ');
            std::size_t found = line.find_first_of("(");
            if ((found!=std::string::npos)&&(found+1<line.length())){
                found = line.find_first_of("a", found+1);
            }
            if ((found!=std::string::npos)&&(line[found+1]=='t')&&(found+5<line.length())&&(line[found+5]==PRV_HEADER_SEP_MAIN_CHAR)){
                line[found+5]='*';
            }
            replace(line.begin(), line.end(), PRV_HEADER_QUOTE_IN_CHAR, GENERIC_SEP_CHAR);
            replace(line.begin(), line.end(), PRV_HEADER_QUOTE_OUT_CHAR, GENERIC_SEP_CHAR);
            trim_all(line);
            if (!line.empty()){
                escaped_list_separator<char> sep(GENERIC_ESCAPE_CHAR, PRV_HEADER_SEP_MAIN_CHAR, GENERIC_QUOTE_CHAR);
                tokenizer<escaped_list_separator<char> > *tokens = new tokenizer<escaped_list_separator<char> >(line, sep);
                tokenizer<escaped_list_separator<char> >::iterator tokensIterator=tokens->begin();
                if (mode==Header){
                    prvEvent=parseHeader(tokens);
                    mode=Body;
                }else{
                    string eventType=*tokensIterator;
                    tokensIterator++;
                    //communicator
                    if (eventType.compare(PRV_BODY_COMMUNICATOR)==0){
                        prvEvent= new PrvOther(lineNumber, prveventtype::Skip);
                    //communications
                    }else if (eventType.compare(PRV_BODY_COMMUNICATION)==0){
                        prvEvent=parseCommunications(tokens, lineNumber);
                    }else if (eventType.compare(PRV_BODY_EVENTS)==0){
                        prvEvent=parseEvents(tokens, lineNumber);
                    }else if (eventType.compare(PRV_BODY_STATE)==0){
                        prvEvent=parseState(tokens, lineNumber);
                    }else{
                        prvEvent= new PrvOther(lineNumber, prveventtype::Skip);
                    }
                }
                delete tokens;
            } 
        }else{
            prvEvent=new PrvOther(lineNumber, prveventtype::End);
        }
    }
    return prvEvent;
}
Esempio n. 3
0
// ===========================================================================
// ASCII file import in format:   xxxxxxxxxx ?:???/?.?
	void receiver::OnImport()
// ===========================================================================
{
FILE *fp;
CString path,str;
char buf[300],fido[20];
int  zone,net,node,point,ret;
char *p;

	str.LoadString(IDS_TEXTFILT);
	CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,str);

	ret=dlg.DoModal();
	restore_base_path();
	if (ret!=IDOK)	return;
	BeginWaitCursor();
	path=dlg.GetPathName();
	fp=fopen(path,"rt");
	if (fp)
	{
		while (fgets(buf,199,fp))
		{
		   if (*buf==';')		   // comment
		      continue;

		   replace_tabs(buf);	   // remove TAB's
		   p=strchr(buf,':');
		   if (!p)
		      continue;
		   while (*p!=' ')
		         p--;
		   p++;
		   if (parse_address(p,&zone,&net,&node,&point)<3)
			  continue;

		   sscanf(p,"%s",fido);
		   *p=0;

		   m_edit_fido.SetWindowText(fido);
		   m_edit_name.SetWindowText(trim_all(buf));
		   OnAddMember();

		}
		fclose(fp);
	}
	else
		ERR_MSG2_RET("E_CANOPIM",path);

	EndWaitCursor();
}
Esempio n. 4
0
// ======================================================
	void simppoll::OnOK()
// ======================================================
{
CString str,full,info;
char	tmp[MAX_PATH],path[MAX_PATH];
char	eofchr[]={0,0};
time_t	oldsecs;
int		errorcode,zone,net,node,point;

OLDPKTHDR   po;   // groesse jeweils 58 bytes
NEWPKTHDR   *pn;
FILE		*fp;

	m_edit.GetWindowText(str);
    trim_all(str);

	int ret=expand_address(str,full,info,1,1,0,errorcode);
	if (!ret)	
		ERR_MSG_RET("W_NOFSFIM");

	CFido xx;
	xx=PS full;

	make_path(tmp,gc.OutboundPath,xx.GetAsDir(0));

	if (!access(tmp,0))
		ERR_MSG2_RET("M_PSAE",full);

	time(&oldsecs);
	str.Format("%08X",oldsecs);

	_mkdir(tmp);
	make_path(path,tmp,str);

	// now fill pkt-structure

	get_first_aka(&zone,&net,&node,&point);
	pn = (NEWPKTHDR *)&po;
	memset(pn,0,sizeof(NEWPKTHDR));

	pn->product	= 0;
	pn->rev_lev	= 0;
	pn->subver	= 2;
	pn->version	= 2;
	pn->ozone 	= zone;	  // main aka
	pn->onet 	= net;
	pn->onode 	= node;
	pn->opoint 	= point;
  	pn->dzone 	= xx.zone; // remote aka
	pn->dnet 	= xx.net;
	pn->dnode 	= xx.node;
	pn->dpoint 	= xx.point;

	fp=fopen(path,"wb");
	if (!fp)	
		ERR_MSG2_RET("E_CANTCREATEDUMMY",path);

	fwrite(pn,sizeof(NEWPKTHDR),1,fp);
	fwrite(eofchr,2,1,fp);
	fclose(fp);

	gMailer.ShowWindow(SW_SHOWNORMAL);
	gMailer.GraphicalStatusDisplay(1);

	CDialog::OnOK();
}
Esempio n. 5
0
// ==================================================================
	void hatch::OnOK()
// ==================================================================
{
CString str,areapath,filepath,magic,echotag,upl,desc;
int		zone,net,node,point,myzone,mynet,mynode,mypoint,sel,ret;
char	fpath[MAX_PATH],fname[MAX_PATH];

	sel=m_list.GetCurSel();
	if (sel==LB_ERR)
		ERR_MSG_RET("E_ETMBSEC");

	str=tics.GetString(sel);
	get_token(str,0,echotag);
	get_token(str,1,upl);
    trim_all(upl);
	get_token(str,3,areapath);

	m_description.GetWindowText(desc);
	trim_all(desc);
	desc.Replace("\r\n",". ");
//	if (strchr(desc,'\r') && err_out("DN_MULLDES")==IDNO)	return;

	m_filename.GetWindowText(filepath);
	if (filepath.GetLength()<2)
		ERR_MSG_RET("E_NOFILEGIVEN");

	m_edit_magic.GetWindowText(magic);
	get_filename(filepath,fname);
	make_path(fpath,areapath,fname);
	if (access(fpath,0) && err_out("DY_STFBCTDA",fpath)==IDYES)
	{
		if (!CopyFile(filepath,fpath,0))
		{
			err_out("E_CTFF",filepath,fpath);
			return;
		}
	}

	if (parse_address(upl,&zone,&net,&node,&point)<3)
		ERR_MSG2_RET("E_INVALUPL",upl);

	CFido fid=upl;
	char phone[300],psw[300],aka[300],ffixpsw[300],replace_buf[100];
	CString repl;

	memset(replace_buf,0,sizeof(replace_buf));
	fid.GetPhoneAndPwd(phone,psw,aka,ffixpsw);

	if (parse_address(aka,&myzone,&mynet,&mynode,&mypoint)<3)
		ERR_MSG2_RET("E_INVALUPO",upl);

	m_replace.GetWindowText(repl);
    trim_all(repl);
	if (repl.GetLength()>0)
		strcpy(replace_buf,repl);

	ret=make_tic_file(zone,net,node, point,myzone,mynet,mynode, mypoint,
		filepath,ffixpsw,desc,echotag,m_deleteafter.GetCheck(),
		replace_buf,magic);
	show_msg(ret ? L("S_176") : L("S_237"),200);	// Done/Error

	CDialog::OnOK();
}
Esempio n. 6
0
static int health_readfile(const char *filename, void *data) {
    RRDHOST *host = (RRDHOST *)data;

    debug(D_HEALTH, "Health configuration reading file '%s'", filename);

    static uint32_t
            hash_alarm = 0,
            hash_template = 0,
            hash_os = 0,
            hash_on = 0,
            hash_host = 0,
            hash_families = 0,
            hash_calc = 0,
            hash_green = 0,
            hash_red = 0,
            hash_warn = 0,
            hash_crit = 0,
            hash_exec = 0,
            hash_every = 0,
            hash_lookup = 0,
            hash_units = 0,
            hash_info = 0,
            hash_recipient = 0,
            hash_delay = 0,
            hash_options = 0;

    char buffer[HEALTH_CONF_MAX_LINE + 1];

    if(unlikely(!hash_alarm)) {
        hash_alarm = simple_uhash(HEALTH_ALARM_KEY);
        hash_template = simple_uhash(HEALTH_TEMPLATE_KEY);
        hash_on = simple_uhash(HEALTH_ON_KEY);
        hash_os = simple_uhash(HEALTH_OS_KEY);
        hash_host = simple_uhash(HEALTH_HOST_KEY);
        hash_families = simple_uhash(HEALTH_FAMILIES_KEY);
        hash_calc = simple_uhash(HEALTH_CALC_KEY);
        hash_lookup = simple_uhash(HEALTH_LOOKUP_KEY);
        hash_green = simple_uhash(HEALTH_GREEN_KEY);
        hash_red = simple_uhash(HEALTH_RED_KEY);
        hash_warn = simple_uhash(HEALTH_WARN_KEY);
        hash_crit = simple_uhash(HEALTH_CRIT_KEY);
        hash_exec = simple_uhash(HEALTH_EXEC_KEY);
        hash_every = simple_uhash(HEALTH_EVERY_KEY);
        hash_units = simple_hash(HEALTH_UNITS_KEY);
        hash_info = simple_hash(HEALTH_INFO_KEY);
        hash_recipient = simple_hash(HEALTH_RECIPIENT_KEY);
        hash_delay = simple_uhash(HEALTH_DELAY_KEY);
        hash_options = simple_uhash(HEALTH_OPTIONS_KEY);
    }

    FILE *fp = fopen(filename, "r");
    if(!fp) {
        error("Health configuration cannot read file '%s'.", filename);
        return 0;
    }

    RRDCALC *rc = NULL;
    RRDCALCTEMPLATE *rt = NULL;

    int ignore_this = 0;
    size_t line = 0, append = 0;
    char *s;
    while((s = fgets(&buffer[append], (int)(HEALTH_CONF_MAX_LINE - append), fp)) || append) {
        int stop_appending = !s;
        line++;
        s = trim(buffer);
        if(!s || *s == '#') continue;

        append = strlen(s);
        if(!stop_appending && s[append - 1] == '\\') {
            s[append - 1] = ' ';
            append = &s[append] - buffer;
            if(append < HEALTH_CONF_MAX_LINE)
                continue;
            else {
                error("Health configuration has too long muli-line at line %zu of file '%s'.", line, filename);
            }
        }
        append = 0;

        char *key = s;
        while(*s && *s != ':') s++;
        if(!*s) {
            error("Health configuration has invalid line %zu of file '%s'. It does not contain a ':'. Ignoring it.", line, filename);
            continue;
        }
        *s = '\0';
        s++;

        char *value = s;
        key = trim_all(key);
        value = trim_all(value);

        if(!key) {
            error("Health configuration has invalid line %zu of file '%s'. Keyword is empty. Ignoring it.", line, filename);
            continue;
        }

        if(!value) {
            error("Health configuration has invalid line %zu of file '%s'. value is empty. Ignoring it.", line, filename);
            continue;
        }

        uint32_t hash = simple_uhash(key);

        if(hash == hash_alarm && !strcasecmp(key, HEALTH_ALARM_KEY)) {
            if (rc && (ignore_this || !rrdcalc_add_alarm_from_config(host, rc)))
                rrdcalc_free(rc);

            if(rt) {
                if (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt))
                    rrdcalctemplate_free(rt);

                rt = NULL;
            }

            rc = callocz(1, sizeof(RRDCALC));
            rc->next_event_id = 1;
            rc->name = strdupz(value);
            rc->hash = simple_hash(rc->name);
            rc->source = health_source_file(line, filename);
            rc->green = NAN;
            rc->red = NAN;
            rc->value = NAN;
            rc->old_value = NAN;
            rc->delay_multiplier = 1.0;

            if(rrdvar_fix_name(rc->name))
                error("Health configuration renamed alarm '%s' to '%s'", value, rc->name);

            ignore_this = 0;
        }
        else if(hash == hash_template && !strcasecmp(key, HEALTH_TEMPLATE_KEY)) {
            if(rc) {
                if(ignore_this || !rrdcalc_add_alarm_from_config(host, rc))
                    rrdcalc_free(rc);

                rc = NULL;
            }

            if(rt && (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)))
                rrdcalctemplate_free(rt);

            rt = callocz(1, sizeof(RRDCALCTEMPLATE));
            rt->name = strdupz(value);
            rt->hash_name = simple_hash(rt->name);
            rt->source = health_source_file(line, filename);
            rt->green = NAN;
            rt->red = NAN;
            rt->delay_multiplier = 1.0;

            if(rrdvar_fix_name(rt->name))
                error("Health configuration renamed template '%s' to '%s'", value, rt->name);

            ignore_this = 0;
        }
        else if(hash == hash_os && !strcasecmp(key, HEALTH_OS_KEY)) {
            char *os_match = value;
            SIMPLE_PATTERN *os_pattern = simple_pattern_create(os_match, NULL, SIMPLE_PATTERN_EXACT);

            if(!simple_pattern_matches(os_pattern, host->os)) {
                if(rc)
                    debug(D_HEALTH, "HEALTH on '%s' ignoring alarm '%s' defined at %zu@%s: host O/S does not match '%s'", host->hostname, rc->name, line, filename, os_match);

                if(rt)
                    debug(D_HEALTH, "HEALTH on '%s' ignoring template '%s' defined at %zu@%s: host O/S does not match '%s'", host->hostname, rt->name, line, filename, os_match);

                ignore_this = 1;
            }

            simple_pattern_free(os_pattern);
        }
        else if(hash == hash_host && !strcasecmp(key, HEALTH_HOST_KEY)) {
            char *host_match = value;
            SIMPLE_PATTERN *host_pattern = simple_pattern_create(host_match, NULL, SIMPLE_PATTERN_EXACT);

            if(!simple_pattern_matches(host_pattern, host->hostname)) {
                if(rc)
                    debug(D_HEALTH, "HEALTH on '%s' ignoring alarm '%s' defined at %zu@%s: hostname does not match '%s'", host->hostname, rc->name, line, filename, host_match);

                if(rt)
                    debug(D_HEALTH, "HEALTH on '%s' ignoring template '%s' defined at %zu@%s: hostname does not match '%s'", host->hostname, rt->name, line, filename, host_match);

                ignore_this = 1;
            }

            simple_pattern_free(host_pattern);
        }
        else if(rc) {
            if(hash == hash_on && !strcasecmp(key, HEALTH_ON_KEY)) {
                if(rc->chart) {
                    if(strcmp(rc->chart, value) != 0)
                        error("Health configuration at line %zu of file '%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rc->name, key, rc->chart, value, value);

                    freez(rc->chart);
                }
                rc->chart = strdupz(value);
                rc->hash_chart = simple_hash(rc->chart);
            }
            else if(hash == hash_lookup && !strcasecmp(key, HEALTH_LOOKUP_KEY)) {
                health_parse_db_lookup(line, filename, value, &rc->group, &rc->after, &rc->before,
                        &rc->update_every,
                        &rc->options, &rc->dimensions);
            }
            else if(hash == hash_every && !strcasecmp(key, HEALTH_EVERY_KEY)) {
                if(!health_parse_duration(value, &rc->update_every))
                    error("Health configuration at line %zu of file '%s' for alarm '%s' at key '%s' cannot parse duration: '%s'.",
                            line, filename, rc->name, key, value);
            }
            else if(hash == hash_green && !strcasecmp(key, HEALTH_GREEN_KEY)) {
                char *e;
                rc->green = str2ld(value, &e);
                if(e && *e) {
                    error("Health configuration at line %zu of file '%s' for alarm '%s' at key '%s' leaves this string unmatched: '%s'.",
                            line, filename, rc->name, key, e);
                }
            }
            else if(hash == hash_red && !strcasecmp(key, HEALTH_RED_KEY)) {
                char *e;
                rc->red = str2ld(value, &e);
                if(e && *e) {
                    error("Health configuration at line %zu of file '%s' for alarm '%s' at key '%s' leaves this string unmatched: '%s'.",
                            line, filename, rc->name, key, e);
                }
            }
            else if(hash == hash_calc && !strcasecmp(key, HEALTH_CALC_KEY)) {
                const char *failed_at = NULL;
                int error = 0;
                rc->calculation = expression_parse(value, &failed_at, &error);
                if(!rc->calculation) {
                    error("Health configuration at line %zu of file '%s' for alarm '%s' at key '%s' has unparse-able expression '%s': %s at '%s'",
                            line, filename, rc->name, key, value, expression_strerror(error), failed_at);
                }
            }
            else if(hash == hash_warn && !strcasecmp(key, HEALTH_WARN_KEY)) {
                const char *failed_at = NULL;
                int error = 0;
                rc->warning = expression_parse(value, &failed_at, &error);
                if(!rc->warning) {
                    error("Health configuration at line %zu of file '%s' for alarm '%s' at key '%s' has unparse-able expression '%s': %s at '%s'",
                            line, filename, rc->name, key, value, expression_strerror(error), failed_at);
                }
            }
            else if(hash == hash_crit && !strcasecmp(key, HEALTH_CRIT_KEY)) {
                const char *failed_at = NULL;
                int error = 0;
                rc->critical = expression_parse(value, &failed_at, &error);
                if(!rc->critical) {
                    error("Health configuration at line %zu of file '%s' for alarm '%s' at key '%s' has unparse-able expression '%s': %s at '%s'",
                            line, filename, rc->name, key, value, expression_strerror(error), failed_at);
                }
            }
            else if(hash == hash_exec && !strcasecmp(key, HEALTH_EXEC_KEY)) {
                if(rc->exec) {
                    if(strcmp(rc->exec, value) != 0)
                        error("Health configuration at line %zu of file '%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rc->name, key, rc->exec, value, value);

                    freez(rc->exec);
                }
                rc->exec = strdupz(value);
            }
            else if(hash == hash_recipient && !strcasecmp(key, HEALTH_RECIPIENT_KEY)) {
                if(rc->recipient) {
                    if(strcmp(rc->recipient, value) != 0)
                        error("Health configuration at line %zu of file '%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rc->name, key, rc->recipient, value, value);

                    freez(rc->recipient);
                }
                rc->recipient = strdupz(value);
            }
            else if(hash == hash_units && !strcasecmp(key, HEALTH_UNITS_KEY)) {
                if(rc->units) {
                    if(strcmp(rc->units, value) != 0)
                        error("Health configuration at line %zu of file '%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rc->name, key, rc->units, value, value);

                    freez(rc->units);
                }
                rc->units = strdupz(value);
                strip_quotes(rc->units);
            }
            else if(hash == hash_info && !strcasecmp(key, HEALTH_INFO_KEY)) {
                if(rc->info) {
                    if(strcmp(rc->info, value) != 0)
                        error("Health configuration at line %zu of file '%s' for alarm '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rc->name, key, rc->info, value, value);

                    freez(rc->info);
                }
                rc->info = strdupz(value);
                strip_quotes(rc->info);
            }
            else if(hash == hash_delay && !strcasecmp(key, HEALTH_DELAY_KEY)) {
                health_parse_delay(line, filename, value, &rc->delay_up_duration, &rc->delay_down_duration, &rc->delay_max_duration, &rc->delay_multiplier);
            }
            else if(hash == hash_options && !strcasecmp(key, HEALTH_OPTIONS_KEY)) {
                rc->options |= health_parse_options(value);
            }
            else {
                error("Health configuration at line %zu of file '%s' for alarm '%s' has unknown key '%s'.",
                        line, filename, rc->name, key);
            }
        }
        else if(rt) {
            if(hash == hash_on && !strcasecmp(key, HEALTH_ON_KEY)) {
                if(rt->context) {
                    if(strcmp(rt->context, value) != 0)
                        error("Health configuration at line %zu of file '%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rt->name, key, rt->context, value, value);

                    freez(rt->context);
                }
                rt->context = strdupz(value);
                rt->hash_context = simple_hash(rt->context);
            }
            else if(hash == hash_families && !strcasecmp(key, HEALTH_FAMILIES_KEY)) {
                freez(rt->family_match);
                simple_pattern_free(rt->family_pattern);

                rt->family_match = strdupz(value);
                rt->family_pattern = simple_pattern_create(rt->family_match, NULL, SIMPLE_PATTERN_EXACT);
            }
            else if(hash == hash_lookup && !strcasecmp(key, HEALTH_LOOKUP_KEY)) {
                health_parse_db_lookup(line, filename, value, &rt->group, &rt->after, &rt->before,
                        &rt->update_every, &rt->options, &rt->dimensions);
            }
            else if(hash == hash_every && !strcasecmp(key, HEALTH_EVERY_KEY)) {
                if(!health_parse_duration(value, &rt->update_every))
                    error("Health configuration at line %zu of file '%s' for template '%s' at key '%s' cannot parse duration: '%s'.",
                            line, filename, rt->name, key, value);
            }
            else if(hash == hash_green && !strcasecmp(key, HEALTH_GREEN_KEY)) {
                char *e;
                rt->green = str2ld(value, &e);
                if(e && *e) {
                    error("Health configuration at line %zu of file '%s' for template '%s' at key '%s' leaves this string unmatched: '%s'.",
                            line, filename, rt->name, key, e);
                }
            }
            else if(hash == hash_red && !strcasecmp(key, HEALTH_RED_KEY)) {
                char *e;
                rt->red = str2ld(value, &e);
                if(e && *e) {
                    error("Health configuration at line %zu of file '%s' for template '%s' at key '%s' leaves this string unmatched: '%s'.",
                            line, filename, rt->name, key, e);
                }
            }
            else if(hash == hash_calc && !strcasecmp(key, HEALTH_CALC_KEY)) {
                const char *failed_at = NULL;
                int error = 0;
                rt->calculation = expression_parse(value, &failed_at, &error);
                if(!rt->calculation) {
                    error("Health configuration at line %zu of file '%s' for template '%s' at key '%s' has unparse-able expression '%s': %s at '%s'",
                            line, filename, rt->name, key, value, expression_strerror(error), failed_at);
                }
            }
            else if(hash == hash_warn && !strcasecmp(key, HEALTH_WARN_KEY)) {
                const char *failed_at = NULL;
                int error = 0;
                rt->warning = expression_parse(value, &failed_at, &error);
                if(!rt->warning) {
                    error("Health configuration at line %zu of file '%s' for template '%s' at key '%s' has unparse-able expression '%s': %s at '%s'",
                            line, filename, rt->name, key, value, expression_strerror(error), failed_at);
                }
            }
            else if(hash == hash_crit && !strcasecmp(key, HEALTH_CRIT_KEY)) {
                const char *failed_at = NULL;
                int error = 0;
                rt->critical = expression_parse(value, &failed_at, &error);
                if(!rt->critical) {
                    error("Health configuration at line %zu of file '%s' for template '%s' at key '%s' has unparse-able expression '%s': %s at '%s'",
                            line, filename, rt->name, key, value, expression_strerror(error), failed_at);
                }
            }
            else if(hash == hash_exec && !strcasecmp(key, HEALTH_EXEC_KEY)) {
                if(rt->exec) {
                    if(strcmp(rt->exec, value) != 0)
                        error("Health configuration at line %zu of file '%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rt->name, key, rt->exec, value, value);

                    freez(rt->exec);
                }
                rt->exec = strdupz(value);
            }
            else if(hash == hash_recipient && !strcasecmp(key, HEALTH_RECIPIENT_KEY)) {
                if(rt->recipient) {
                    if(strcmp(rt->recipient, value) != 0)
                        error("Health configuration at line %zu of file '%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rt->name, key, rt->recipient, value, value);

                    freez(rt->recipient);
                }
                rt->recipient = strdupz(value);
            }
            else if(hash == hash_units && !strcasecmp(key, HEALTH_UNITS_KEY)) {
                if(rt->units) {
                    if(strcmp(rt->units, value) != 0)
                        error("Health configuration at line %zu of file '%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rt->name, key, rt->units, value, value);

                    freez(rt->units);
                }
                rt->units = strdupz(value);
                strip_quotes(rt->units);
            }
            else if(hash == hash_info && !strcasecmp(key, HEALTH_INFO_KEY)) {
                if(rt->info) {
                    if(strcmp(rt->info, value) != 0)
                        error("Health configuration at line %zu of file '%s' for template '%s' has key '%s' twice, once with value '%s' and later with value '%s'. Using ('%s').",
                                line, filename, rt->name, key, rt->info, value, value);

                    freez(rt->info);
                }
                rt->info = strdupz(value);
                strip_quotes(rt->info);
            }
            else if(hash == hash_delay && !strcasecmp(key, HEALTH_DELAY_KEY)) {
                health_parse_delay(line, filename, value, &rt->delay_up_duration, &rt->delay_down_duration, &rt->delay_max_duration, &rt->delay_multiplier);
            }
            else if(hash == hash_options && !strcasecmp(key, HEALTH_OPTIONS_KEY)) {
                rt->options |= health_parse_options(value);
            }
            else {
                error("Health configuration at line %zu of file '%s' for template '%s' has unknown key '%s'.",
                        line, filename, rt->name, key);
            }
        }
        else {
            error("Health configuration at line %zu of file '%s' has unknown key '%s'. Expected either '" HEALTH_ALARM_KEY "' or '" HEALTH_TEMPLATE_KEY "'.",
                    line, filename, key);
        }
    }

    if(rc && (ignore_this || !rrdcalc_add_alarm_from_config(host, rc)))
        rrdcalc_free(rc);

    if(rt && (ignore_this || !rrdcalctemplate_add_template_from_config(host, rt)))
        rrdcalctemplate_free(rt);

    fclose(fp);
    return 1;
}