Exemple #1
0
void inifile_manager::directory_scan()
{
	// open extra INIs folder
	file_enumerator path(mame_machine_manager::instance()->ui().options().extraini_path());
	const osd_directory_entry *dir;

	// loop into folder's file
	while ((dir = path.next()) != nullptr)
	{
		int length = strlen(dir->name);
		std::string filename(dir->name);

		// check .ini file ending
		if ((length > 4) && dir->name[length - 4] == '.' && tolower((UINT8)dir->name[length - 3]) == 'i' &&
			tolower((UINT8)dir->name[length - 2]) == 'n' && tolower((UINT8)dir->name[length - 1]) == 'i')
		{
			// try to open file and indexing
			if (parseopen(filename.c_str()))
			{
				init_category(filename);
				parseclose();
			}
		}
	}

	// sort
	std::stable_sort(ini_index.begin(), ini_index.end());
}
Exemple #2
0
void inifile_manager::directory_scan()
{
	// open extra INIs folder
	file_enumerator path(machine().ui().options().extraini_path());
	const osd_directory_entry *dir;

	// loop into folder's file
	while ((dir = path.next()) != nullptr)
	{
		int length = strlen(dir->name);
		std::string filename(dir->name);

		// skip ui_favorite file
		if (!core_stricmp("ui_favorite.ini", filename.c_str()))
			continue;

		// check .ini file ending
		if ((length > 4) && dir->name[length - 4] == '.' && tolower((UINT8)dir->name[length - 3]) == 'i' &&
			tolower((UINT8)dir->name[length - 2]) == 'n' && tolower((UINT8)dir->name[length - 1]) == 'i')
		{
			// try to open file and indexing
			if (parseopen(filename.c_str()))
			{
				init_category(filename);
				parseclose();
			}
		}
	}
}
Exemple #3
0
inifile_manager::inifile_manager(ui_options &options)
	: m_options(options)
	, m_ini_index()
{
	// scan directories and create index
	file_enumerator path(m_options.categoryini_path());
	for (osd::directory::entry const *dir = path.next(); dir; dir = path.next())
	{
		std::string name(dir->name);
		if (core_filename_ends_with(name, ".ini"))
		{
			emu_file file(m_options.categoryini_path(), OPEN_FLAG_READ);
			if (file.open(name) == osd_file::error::NONE)
			{
				init_category(std::move(name), file);
				file.close();
			}
		}
	}
	std::stable_sort(m_ini_index.begin(), m_ini_index.end(), [] (auto const &x, auto const &y) { return 0 > core_stricmp(x.first.c_str(), y.first.c_str()); });
}
Exemple #4
0
struct amf_cluster *amf_config_read (char **error_string)
{
	char buf[1024];
	char *line;
	FILE *fp;
	const char *filename;
	amf_object_type_t current_parse = AMF_NONE;
	int line_number = 0;
	char *loc;
	int i;
	struct amf_cluster       *cluster;
	struct amf_application   *app = 0;
	struct amf_node          *node = 0;
	struct amf_sg            *sg = 0;
	struct amf_su            *su = 0;
	struct amf_comp          *comp = 0;
	struct amf_si            *si = 0;
	struct amf_si_ranked_su  *si_ranked_su = 0;
	struct amf_si_dependency *si_dependency = 0;
	struct amf_healthcheck   *healthcheck = 0;
	struct amf_csi           *csi = 0;
	struct amf_csi_attribute *attribute = 0;
	SaStringT                 env_var;
	int                       su_cnt = 0;
	int                       sg_cnt = 0;
	int                       comp_env_var_cnt = 0;
	int                       comp_cs_type_cnt = 0;
	int                       csi_attr_cnt = 0;
	int                       csi_dependencies_cnt = 0;
	const char                *error_reason = NULL;
	char                     *value;
	filename = getenv ("COROSYNC_AMF_CONFIG_FILE");
	if (!filename) {
		filename = COROSYSCONFDIR "/amf.conf";
	}

	fp = fopen (filename, "r");
	if (fp == 0) {
		sprintf (buf, "Can't read %s file reason = (%s).\n",
			filename, strerror (errno));
		*error_string = buf;
		return NULL;
	}

	cluster = amf_cluster_new ();
	assert (cluster != NULL);

	while (fgets (buf, 255, fp)) {
		line_number += 1;
		line = buf;
		if (strlen(line) > 0) {
			line[strlen(line) - 1] = '\0';
		}
		/*
		 * Clear out comments and empty lines
		 */
		if (line[0] == '#' || line[0] == '\0' || line[0] == '\n') {
			continue;
		}

		/*
		 * Clear out white space and tabs
		 */
		for (i = strlen (line) - 1; i > -1; i--) {
			if (line[i] == '\t' || line[i] == ' ') {
				line[i] = '\0';
			} else {
				break;
			}
		}

		/* Trim whitespace from beginning of string */
		line = rm_beginning_ws(line);
		error_reason = line;
		error_reason = NULL;
		switch (current_parse) {
		case AMF_NONE:
			if ((loc = strstr_rs (line, "safAmfCluster=")) != 0) {
				setSaNameT (&cluster->name, trim_str (loc));
				current_parse = AMF_CLUSTER;
			} else {
				goto parse_error;
			}
			break;

		case AMF_CLUSTER:
			if ((loc = strstr_rs (line, "saAmfClusterClmCluster=")) != 0) {
				setSaNameT (&cluster->saAmfClusterClmCluster, loc);
			} else if ((loc = strstr_rs (line, "saAmfClusterStartupTimeout=")) != 0) {
				cluster->saAmfClusterStartupTimeout = atol(loc);
			} else if ((loc = strstr_rs (line, "safAmfNode=")) != 0) {
				node = amf_node_new (cluster, trim_str (loc));
				cluster->node_head = node;
				current_parse = AMF_NODE;
			} else if ((loc = strstr_rs (line, "safApp=")) != 0) {
				app = amf_application_new (cluster);
				setSaNameT (&app->name, trim_str (loc));
				current_parse = AMF_APPLICATION;
				sg_cnt = 0;
			} else if (strstr_rs (line, "}")) {
				if (cluster->saAmfClusterStartupTimeout == -1) {
					error_reason = "saAmfClusterStartupTimeout missing";
					goto parse_error;
				}
				/* spec: set to default value if zero */
				if (cluster->saAmfClusterStartupTimeout == 0) {
					cluster->saAmfClusterStartupTimeout = COROSYNC_CLUSTER_STARTUP_TIMEOUT;
				}
				current_parse = AMF_NONE;
			} else {
				goto parse_error;
			}
			break;

		case AMF_NODE:
			if ((loc = strstr_rs (line, "saAmfNodeSuFailOverProb=")) != 0) {
				node->saAmfNodeSuFailOverProb = atol(loc);
			} else if ((loc = strstr_rs (line, "saAmfNodeSuFailoverMax=")) != 0) {
				node->saAmfNodeSuFailoverMax = atol(loc);
			} else if ((loc = strstr_rs (line, "saAmfNodeClmNode=")) != 0) {
				setSaNameT (&node->saAmfNodeClmNode, trim_str (loc));
			} else if ((loc = strstr_rs (line, "saAmfNodeAutoRepair=")) != 0) {
				if (strcmp (loc, "true") == 0) {
					node->saAmfNodeAutoRepair = SA_TRUE;
				} else if (strcmp (loc, "false") == 0) {
					node->saAmfNodeAutoRepair = SA_FALSE;
				} else {
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfNodeRebootOnTerminationFailure=")) != 0) {
				if (strcmp (loc, "true") == 0) {
					node->saAmfNodeRebootOnTerminationFailure = SA_TRUE;
				} else if (strcmp (loc, "false") == 0) {
					node->saAmfNodeRebootOnTerminationFailure = SA_FALSE;
				} else {
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfNodeRebootOnInstantiationFailure=")) != 0) {
				if (strcmp (loc, "true") == 0) {
					node->saAmfNodeRebootOnInstantiationFailure = SA_TRUE;
				} else if (strcmp (loc, "false") == 0) {
					node->saAmfNodeRebootOnInstantiationFailure = SA_FALSE;
				} else {
					goto parse_error;
				}
			} else if (strstr_rs (line, "}")) {
				if (node->saAmfNodeSuFailOverProb == -1) {
					error_reason = "saAmfNodeSuFailOverProb missing";
					goto parse_error;
				}
				if (node->saAmfNodeSuFailoverMax == ~0) {
					error_reason = "saAmfNodeSuFailoverMax missing";
					goto parse_error;
				}
				if (node->saAmfNodeClmNode.length == 0) {
					error_reason = "saAmfNodeClmNode missing";
					goto parse_error;
				}
				current_parse = AMF_CLUSTER;
			} else {
				goto parse_error;
			}
			break;

		case AMF_APPLICATION:
			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
				app->clccli_path = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "safSg=")) != 0) {
				sg = amf_sg_new (app, trim_str (loc));
				sg_cnt++;
				sg->recovery_scope.comp = NULL;
				sg->recovery_scope.event_type = 0;
				sg->recovery_scope.node = NULL;
				sg->recovery_scope.sis = NULL;
				sg->recovery_scope.sus = NULL;
				current_parse = AMF_SG;
				su_cnt = 0;
			} else if ((loc = strstr_rs (line, "safSi=")) != 0) {
				si = amf_si_new (app, trim_str (loc));
				current_parse = AMF_SI;
			} else if ((loc = strstr_rs (line, "safCSType=")) != 0) {
				current_parse = AMF_CS_TYPE;
			} else if (strstr_rs (line, "}")) {
				if (sg_cnt == 1) {
					for (si = app->si_head; si != NULL; si = si->next) {
						memcpy (&si->saAmfSIProtectedbySG, &sg->name,
							sizeof (SaNameT));
					}
				} else {
					for (si = app->si_head; si != NULL; si = si->next) {
						if (si->saAmfSIProtectedbySG.length == 0) {
							error_reason = "saAmfSIProtectedbySG not set in SI"
								", needed when several SGs are specified.";
							goto parse_error;
						}
					}
				}
				current_parse = AMF_CLUSTER;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SG:
			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
				sg->clccli_path = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfSGRedundancyModel=")) != 0) {
				if (strcmp (loc, "2n") == 0) {
					sg->saAmfSGRedundancyModel = SA_AMF_2N_REDUNDANCY_MODEL;
				} else if (strcmp (loc, "nplusm") == 0) {
					sg->saAmfSGRedundancyModel = SA_AMF_NPM_REDUNDANCY_MODEL;
				} else if (strcmp (loc, "nway") == 0) {
					error_reason = "nway redundancy model not supported";
					goto parse_error;
				} else if (strcmp (loc, "nwayactive") == 0) {
					error_reason = "nway active redundancy model not supported";
					goto parse_error;
				} else if (strcmp (loc, "noredundancy") == 0) {
					sg->saAmfSGRedundancyModel = SA_AMF_NO_REDUNDANCY_MODEL;
				} else {
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfSGNumPrefActiveSUs=")) != 0) {
				sg->saAmfSGNumPrefActiveSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGNumPrefStandbySUs=")) != 0) {
				sg->saAmfSGNumPrefStandbySUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGNumPrefInserviceSUs=")) != 0) {
				sg->saAmfSGNumPrefInserviceSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGNumPrefAssignedSUs=")) != 0) {
				sg->saAmfSGNumPrefAssignedSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGMaxActiveSIsperSUs=")) != 0) {
				sg->saAmfSGMaxActiveSIsperSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGMaxStandbySIsperSUs=")) != 0) {
				sg->saAmfSGMaxStandbySIsperSUs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGCompRestartProb=")) != 0) {
				sg->saAmfSGCompRestartProb = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGCompRestartMax=")) != 0) {
				sg->saAmfSGCompRestartMax = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGSuRestartProb=")) != 0) {
				sg->saAmfSGSuRestartProb = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGSuRestartMax=")) != 0) {
				sg->saAmfSGSuRestartMax = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGAutoAdjustProb=")) != 0) {
				sg->saAmfSGAutoAdjustProb = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSGAutoRepair=")) != 0) {
				sg->saAmfSGAutoRepair = atoi (loc);
			} else if ((loc = strstr_rs (line, "safSu=")) != 0) {
				su = amf_su_new (sg, trim_str (loc));
				su_cnt++;
				current_parse = AMF_SU;
			} else if (strstr_rs (line, "}")) {
				if (sg->saAmfSGRedundancyModel == 0) {
					error_reason = "saAmfSGRedundancyModel missing";
					goto parse_error;
				}
				if (sg->saAmfSGCompRestartProb == -1) {
					error_reason = "saAmfSGCompRestartProb missing";
					goto parse_error;
				}
				if (sg->saAmfSGCompRestartMax == ~0) {
					error_reason = "saAmfSGCompRestartMax missing";
					goto parse_error;
				}
				if (sg->saAmfSGSuRestartProb == -1) {
					error_reason = "saAmfSGSuRestartProb missing";
					goto parse_error;
				}
				if (sg->saAmfSGSuRestartMax == ~0) {
					error_reason = "saAmfSGSuRestartMax missing";
					goto parse_error;
				}
				if (sg->saAmfSGAutoAdjustProb == -1) {
					error_reason = "saAmfSGAutoAdjustProb missing";
					goto parse_error;
				}
				if (sg->saAmfSGAutoRepair > 1) {
					error_reason = "saAmfSGAutoRepair erroneous";
					goto parse_error;
				}
				if (sg->saAmfSGNumPrefInserviceSUs == ~0) {
					sg->saAmfSGNumPrefInserviceSUs = su_cnt;
				}
				if (sg->saAmfSGNumPrefAssignedSUs == ~0) {
					sg->saAmfSGNumPrefAssignedSUs =
						sg->saAmfSGNumPrefInserviceSUs;
				}
				current_parse = AMF_APPLICATION;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SU:
			if ((loc = strstr_rs (line, "saAmfSUNumComponents=")) != 0) {
				su->saAmfSUNumComponents = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSUIsExternal=")) != 0) {
				su->saAmfSUIsExternal = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSUFailover=")) != 0) {
				su->saAmfSUFailover = atoi (loc);
			} else if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
				su->clccli_path = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfSUHostedByNode=")) != 0) {
				setSaNameT (&su->saAmfSUHostedByNode, loc);
			} else if ((loc = strstr_rs (line, "safComp=")) != 0) {
				comp = amf_comp_new (su, trim_str (loc));
				comp_env_var_cnt = 0;
				comp_cs_type_cnt = 0;
				current_parse = AMF_COMP;
			} else if (strstr_rs (line, "}")) {
				if (su->saAmfSUNumComponents == 0) {
					error_reason = "saAmfSUNumComponents missing";
					goto parse_error;
				}
				if (su->saAmfSUIsExternal > 1) {
					error_reason = "saAmfSUIsExternal erroneous";
					goto parse_error;
				}
				if (su->saAmfSUFailover > 1) {
					error_reason = "saAmfSUFailover erroneous";
					goto parse_error;
				}
				if (strcmp ((char*)su->saAmfSUHostedByNode.value, "") == 0) {
					error_reason = "saAmfSUHostedByNode missing";
					goto parse_error;
				}
				current_parse = AMF_SG;
			} else {
				goto parse_error;
			}
			break;

		case AMF_COMP:
			if ((loc = strstr_rs (line, "clccli_path=")) != 0) {
				comp->clccli_path = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfCompCsTypes{")) != 0) {
				current_parse = AMF_COMP_CS_TYPE;
			} else if ((loc = strstr_rs(line, "saAmfCompCategory=")) != 0) {
				if (init_category(comp, loc) != 0) {
					error_reason = "unknown category";
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfCompCapability=")) != 0) {
				if (init_capability(comp, loc) != 0) {
					error_reason = "unknown capability model";
					goto parse_error;
				}
			} else if ((loc = strstr_rs(line, "saAmfCompNumMaxActiveCsi=")) != 0) {
				comp->saAmfCompNumMaxActiveCsi = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompNumMaxStandbyCsi=")) != 0) {
				comp->saAmfCompNumMaxStandbyCsi = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompCmdEnv{")) != 0) {
				current_parse = AMF_COMP_ENV_VAR;
			} else if ((loc = strstr_rs(line, "saAmfCompDefaultClcCliTimeout=")) != 0) {
				comp->saAmfCompDefaultClcCliTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompDefaultCallbackTimeOut=")) != 0) {
				comp->saAmfCompDefaultCallbackTimeOut = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompInstantiateCmdArgv=")) != 0) {
				comp->saAmfCompInstantiateCmdArgv = amf_strdup(loc);
			} else if ((loc = strstr_rs ( line, "saAmfCompInstantiateCmd=")) != 0) {
				comp->saAmfCompInstantiateCmd = amf_strdup(loc);
			} else if ((loc = strstr_rs(line, "saAmfCompInstantiateTimeout=")) != 0) {
				comp->saAmfCompInstantiateTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompInstantiationLevel=")) != 0) {
				comp->saAmfCompInstantiationLevel = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompNumMaxInstantiateWithoutDelay=")) != 0) {
				comp->saAmfCompNumMaxInstantiateWithoutDelay = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompNumMaxInstantiateWithDelay=")) != 0) {
				comp->saAmfCompNumMaxInstantiateWithDelay = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompDelayBetweenInstantiateAttempts=")) != 0) {
				comp->saAmfCompDelayBetweenInstantiateAttempts = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompTerminateCmdArgv=")) != 0) {
				comp->saAmfCompTerminateCmdArgv = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfCompTerminateCmd=")) != 0) {
				comp->saAmfCompTerminateCmd = amf_strdup(loc);
			} else if ((loc = strstr_rs(line, "saAmfCompTerminateTimeout=")) != 0) {
				comp->saAmfCompTerminateTimeout = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompCleanupCmdArgv=")) != 0) {
				comp->saAmfCompCleanupCmdArgv = amf_strdup(loc);
			} else if ((loc = strstr_rs (line, "saAmfCompCleanupCmd=")) != 0) {
				comp->saAmfCompCleanupCmd = amf_strdup(loc);
			} else if ((loc = strstr_rs(line, "saAmfCompCleanupTimeout=")) != 0) {
				comp->saAmfCompCleanupTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompTerminateCallbackTimeout=")) != 0) {
				comp->saAmfCompTerminateCallbackTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompCSISetCallbackTimeout=")) != 0) {
				comp->saAmfCompCSISetCallbackTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompQuiescingCompleteTimeout=")) != 0) {
				comp->saAmfCompQuiescingCompleteTimeout = atol (loc);
			} else if ((loc = strstr_rs(line, "saAmfCompCSIRmvCallbackTimeout=")) != 0) {
				comp->saAmfCompCSIRmvCallbackTimeout = atol (loc);
			} else if ((loc = strstr_rs (line, "saAmfCompRecoveryOnError=")) != 0) {
				if (init_recovery_on_error (comp, loc) != 0) {
					error_reason = "bad value";
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfCompDisableRestart=")) != 0) {
				if (strcmp (loc, "false") == 0) {
					comp->saAmfCompDisableRestart = SA_FALSE;
				} else if (strcmp (loc, "true") == 0) {
					comp->saAmfCompDisableRestart = SA_TRUE;
				} else {
					error_reason = "bad value";
					goto parse_error;
				}
			} else if ((loc = strstr_rs (line, "saAmfCompProxyCsi=")) != 0) {
				setSaNameT (&comp->saAmfCompProxyCsi, loc);
			} else if ((loc = strstr_rs (line, "safHealthcheckKey=")) != 0) {
				healthcheck = calloc (1, sizeof (struct amf_healthcheck));
				healthcheck->next = comp->healthcheck_head;
				comp->healthcheck_head = healthcheck;
				healthcheck->comp = comp;
				strcpy ((char *)healthcheck->safHealthcheckKey.key, trim_str (loc));
				healthcheck->safHealthcheckKey.keyLen = strlen (loc);
				current_parse = AMF_HEALTHCHECK;
			} else if (strstr_rs (line, "}")) {
				if (comp->saAmfCompCategory == 0) {
					error_reason = "category missing";
					goto parse_error;
				}
				if (comp->saAmfCompCapability == 0) {
					error_reason = "capability model missing";
					goto parse_error;
				}
				if (comp->saAmfCompCategory == SA_AMF_COMP_SA_AWARE) {
					comp->comptype = clc_component_sa_aware;
				} else if (comp->saAmfCompCategory == SA_AMF_COMP_PROXY) {
					if (comp->saAmfCompCapability == SA_AMF_COMP_NON_PRE_INSTANTIABLE) {
						comp->comptype = clc_component_proxied_non_pre;
					} else {
						comp->comptype = clc_component_proxied_pre;
					}
				} else if (comp->saAmfCompCategory == SA_AMF_COMP_LOCAL) {
					comp->comptype = clc_component_non_proxied_non_sa_aware;
				}
				if (comp->saAmfCompNumMaxActiveCsi == 0) {
					error_reason = "saAmfCompNumMaxActiveCsi missing";
					goto parse_error;
				}
				if (comp->saAmfCompNumMaxStandbyCsi == 0) {
					error_reason = "saAmfCompNumMaxStandbyCsi missing";
					goto parse_error;
				}
				if (comp->saAmfCompDefaultClcCliTimeout == 0) {
					error_reason = "saAmfCompDefaultClcCliTimeout missing or erroneous";
					goto parse_error;
				}
				if (comp->saAmfCompDefaultCallbackTimeOut == 0) {
					error_reason = "saAmfCompDefaultCallbackTimeOut missing or erroneous";
					goto parse_error;
				}
				if (comp->saAmfCompRecoveryOnError == 0) {
					error_reason = "saAmfCompRecoveryOnError missing";
					goto parse_error;
				}
				post_init_comp (comp);
				current_parse = AMF_SU;
			} else {
				error_reason = line;
				goto parse_error;
			}
			break;

		case AMF_COMP_CS_TYPE:
			if (strstr_rs (line, "}")) {
				current_parse = AMF_COMP;
			} else {
				comp_cs_type_cnt++;
				comp->saAmfCompCsTypes = realloc (comp->saAmfCompCsTypes,
					(comp_cs_type_cnt + 1) * sizeof(SaNameT));
				comp->saAmfCompCsTypes[comp_cs_type_cnt] = NULL;
				comp->saAmfCompCsTypes[comp_cs_type_cnt - 1] = amf_malloc (sizeof(SaNameT));
				setSaNameT (comp->saAmfCompCsTypes[comp_cs_type_cnt - 1], line);
			}
			break;

		case AMF_COMP_ENV_VAR:
			if (strstr_rs (line, "}")) {
				current_parse = AMF_COMP;
			} else if ((loc = strchr (line, '=')) != 0) {
				comp_env_var_cnt++;
				comp->saAmfCompCmdEnv = realloc (comp->saAmfCompCmdEnv,
					(comp_env_var_cnt + 1) * sizeof(SaStringT));
				comp->saAmfCompCmdEnv[comp_env_var_cnt] = NULL;
				env_var = comp->saAmfCompCmdEnv[comp_env_var_cnt - 1] = amf_strdup(line);
			} else {
				goto parse_error;
			}
			break;

		case AMF_HEALTHCHECK:
			if ((loc = strstr_rs (line, "saAmfHealthcheckPeriod=")) != 0) {
				healthcheck->saAmfHealthcheckPeriod = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfHealthcheckMaxDuration=")) != 0) {
				healthcheck->saAmfHealthcheckMaxDuration = atoi (loc);
			} else if (strstr_rs (line, "}")) {
				current_parse = AMF_COMP;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SI:
			if ((loc = strstr_rs (line, "safRankedSu=")) != 0) {
				si_ranked_su = calloc (1, sizeof(struct amf_si_ranked_su));
				si_ranked_su->si_next = si->ranked_sus;
				si->ranked_sus = si_ranked_su;
				si_ranked_su->si = si;
				setSaNameT (&si_ranked_su->name, trim_str (loc));
				current_parse = AMF_SI_RANKED_SU;
			} else if ((loc = strstr_rs (line, "safDepend=")) != 0) {
				si_dependency = calloc (1, sizeof(struct amf_si_dependency));
				si_dependency->next = si->depends_on;
				si->depends_on = si_dependency;
				setSaNameT (&si_dependency->name, trim_str (loc));
				current_parse = AMF_SI_DEPENDENCY;
			} else if ((loc = strstr_rs (line, "safCsi=")) != 0) {
				csi = calloc (1, sizeof(struct amf_csi));
				csi->next = si->csi_head;
				si->csi_head = csi;
				csi->si = si;
				setSaNameT (&csi->name, trim_str (loc));
				current_parse = AMF_CSI;
			} else if ((loc = strstr_rs (line, "saAmfSIProtectedbySG=")) != 0) {
				setSaNameT (&si->saAmfSIProtectedbySG, loc);
			} else if ((loc = strstr_rs (line, "saAmfSIRank=")) != 0) {
				si->saAmfSIRank = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSINumCSIs=")) != 0) {
				si->saAmfSINumCSIs = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSIPrefActiveAssignments=")) != 0) {
				si->saAmfSIPrefActiveAssignments = atoi (loc);
			} else if ((loc = strstr_rs (line, "saAmfSIPrefActiveAssignments=")) != 0) {
				si->saAmfSIPrefStandbyAssignments = atoi (loc);
			} else if (strstr_rs (line, "}")) {
				if (si->saAmfSINumCSIs == 0) {
					error_reason = "saAmfSINumCSIs missing";
					goto parse_error;
				}
				current_parse = AMF_APPLICATION;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SI_RANKED_SU:
			if ((loc = strstr_rs (line, "saAmfRank=")) != 0) {
				si_ranked_su->saAmfRank = atoi (loc);
			} else if (strstr_rs (line, "}")) {
				current_parse = AMF_SI;
			} else {
				goto parse_error;
			}
			break;

		case AMF_SI_DEPENDENCY:
			if ((loc = strstr_rs (line, "saAmfToleranceTime=")) != 0) {
				si_dependency->saAmfToleranceTime = atoi (loc);
			} else if (strstr_rs (line, "}")) {
				current_parse = AMF_SI;
			} else {
				goto parse_error;
			}
			break;

		case AMF_CSI:
			if ((loc = strstr_rs (line, "saAmfCSTypeName=")) != 0) {
				setSaNameT (&csi->saAmfCSTypeName, loc);
			} else if ((loc = strstr_rs (line, "safCSIAttr=")) != 0) {
				attribute = calloc (1, sizeof(struct amf_csi_attribute));
				attribute->next = csi->attributes_head;
				csi->attributes_head = attribute;
				attribute->name = amf_strdup(loc);
				csi_attr_cnt = 1;
				current_parse = AMF_CSI_ATTRIBUTE;
			} else if ((loc = strstr_rs (line, "saAmfCsiDependencies{")) != 0) {
				csi_dependencies_cnt = 0;
				current_parse = AMF_CSI_DEPENDENCIES;
			} else if (strstr_rs (line, "}")) {
				if (strcmp(getSaNameT(&csi->saAmfCSTypeName), "") == 0) {
					error_reason = "saAmfCSTypeName missing";
					goto parse_error;
				}
				current_parse = AMF_SI;
			} else {
				goto parse_error;
			}
			break;

		case AMF_CSI_DEPENDENCIES:
			if (strstr_rs (line, "}")) {
				current_parse = AMF_CSI;
			} else if ((loc = strstr_rs (line, "saAmfCSIDependency=")) != 0) {
				csi_dependencies_cnt++;
				csi->saAmfCSIDependencies = realloc (csi->saAmfCSIDependencies,
					(csi_dependencies_cnt + 1) * sizeof(SaNameT));
				csi->saAmfCSIDependencies[csi_dependencies_cnt] = NULL;
				csi->saAmfCSIDependencies[csi_dependencies_cnt - 1] =
					amf_malloc (sizeof(SaNameT));
				setSaNameT (
					csi->saAmfCSIDependencies[csi_dependencies_cnt - 1], loc);
			} else {
				goto parse_error;
			}
			break;

		case AMF_CSI_ATTRIBUTE:
			if ((loc = strstr_rs (line, "}")) != 0) {
				current_parse = AMF_CSI;
			} else {
				value = rm_beginning_ws (line);
				attribute->value = realloc (attribute->value,
					sizeof (SaStringT) * (csi_attr_cnt + 1));
				attribute->value[csi_attr_cnt - 1] = amf_strdup(value);
				attribute->value[csi_attr_cnt] = NULL;
				csi_attr_cnt++;
			}
			break;

		case AMF_CS_TYPE:
			if ((loc = strstr_rs (line, "}")) != 0) {
				current_parse = AMF_APPLICATION;
			}
			break;

		default:
			error_reason = "Invalid state\n";
			goto parse_error;
			break;
		}
	}

	fclose (fp);

	sprintf (buf, "Successfully read AMF configuration file '%s'.\n", filename);
	*error_string = buf;

	return cluster;

parse_error:
	sprintf (buf, "parse error at %s: %d: %s\n",
		filename, line_number, error_reason);
	*error_string = buf;
	fclose (fp);
	return NULL;
}