Exemplo n.º 1
0
/**
 * @brief
 *	shorten_and_cleanup_path: Takes a filename path, removes any trailing
 *	unprintable character on the name, and then returns the windows shortname
 *	equivalent.
 *
 * @param[in] - path - filename path
 *
 * @return	string
 * @retval	malloc-ed string	success
 * @retval	NULL			error
 *
 */
char *
shorten_and_cleanup_path(char *path)
{
	char *conf_filename2;
	char *conf_filename;
	int  i;

	conf_filename2 = (char *)malloc(strlen(path)+1);
	if (conf_filename2 == NULL)
		return NULL;

	strcpy(conf_filename2, path);
	i = strlen(conf_filename2);

	while (i > 0 && !isgraph(conf_filename2[i-1])) {
		conf_filename2[i-1] = '\0';
		i--;
	}

	if ((conf_filename = strdup(lpath2short(conf_filename2))) == NULL) {
		(void)free(conf_filename2);
		return NULL;
	}
	back2forward_slash(conf_filename);

	(void)free(conf_filename2);
	return (conf_filename);
}
Exemplo n.º 2
0
/**
 * @brief
 * 	just a placeholder for the unix equivalent function. 
 *
 * @param[in] path - file path
 * @param[in] resolved_path - resolved path
 *
 * @return	string
 * @retval	resolved path	succees
 *
 */
char *
realpath(const char *path, char *resolved_path)
{
	strcpy(resolved_path, path);
	back2forward_slash(resolved_path);
	return (resolved_path);
}
Exemplo n.º 3
0
/**
 * @brief
 *	pbs_loadconf - Populate the pbs_conf structure
 *
 * @par
 *	Load the pbs_conf structure.  The variables can be filled in
 *	from either the environment or the pbs.conf file.  The
 *	environment gets priority over the file.  If any of the
 *	primary variables are not filled in, the function fails.
 *	Primary vars: pbs_home_path, pbs_exec_path, pbs_server_name
 *
 * @note
 *	Clients can now be multithreaded. So dont call pbs_loadconf with
 *	reload = TRUE. Currently, the code flow ensures that the configuration
 *	is loaded only once (never used with reload true). Thus in the rest of
 *	the code a direct read of the pbs_conf.variables is fine. There is no
 *	race of access of pbs_conf vars against the loading of pbs_conf vars.
 *	However, if pbs_loadconf is called with reload = TRUE, this assumption
 *	will be void. In that case, access to every pbs_conf.variable has to be
 *	synchronized against the reload of those variables.
 *
 * @param[in] reload		Whether to attempt a reload
 *
 * @return int
 * @retval 1 Success
 * @retval 0 Failure
 */
int
pbs_loadconf(int reload)
{
	FILE *fp;
	char buf[256];
	char *conf_name; 		/* the name of the conf parameter */
	char *conf_value;		/* the value from the conf file or env*/
	char *gvalue;			/* used with getenv() */
	unsigned int uvalue;		/* used with sscanf() */
#ifndef WIN32
	struct servent *servent;	/* for use with getservent */
	char **servalias;		/* service alias list */
	unsigned int *pui;		/* for use with identify_service_entry */
#endif

	/* initialize the thread context data, if not already initialized */
	if (pbs_client_thread_init_thread_context() != 0)
		return 0;

	/* this section of the code modified the procecss-wide
	 * tcp array. Since multiple threads can get into this
	 * simultaneously, we need to serialize it
	 */
	if (pbs_client_thread_lock_conf() != 0)
		return 0;

	if (pbs_conf.loaded && !reload) {
		(void)pbs_client_thread_unlock_conf();
		return 1;
	}
	else if (pbs_conf.load_failed && !reload) {
		(void)pbs_client_thread_unlock_conf();
		return 0;
	}

	/*
	 * If there are service port definitions available, use them
	 * as the defaults. They may be overridden later by the config
	 * file or environment variables. If not available, retain
	 * whatever we were using before.
	 */
#ifdef WIN32
	/* Windows does not have the getservent() call. */
	pbs_conf.batch_service_port = get_svrport(
		PBS_BATCH_SERVICE_NAME, "tcp",
		pbs_conf.batch_service_port);
	pbs_conf.batch_service_port_dis = get_svrport(
		PBS_BATCH_SERVICE_NAME_DIS, "tcp",
		pbs_conf.batch_service_port_dis);
	pbs_conf.mom_service_port = get_svrport(
		PBS_MOM_SERVICE_NAME, "tcp",
		pbs_conf.mom_service_port);
	pbs_conf.manager_service_port = get_svrport(
		PBS_MANAGER_SERVICE_NAME, "tcp",
		pbs_conf.manager_service_port);
	pbs_conf.scheduler_service_port = get_svrport(
		PBS_SCHEDULER_SERVICE_NAME, "tcp",
		pbs_conf.scheduler_service_port);
	pbs_conf.pbs_data_service_port = get_svrport(
		PBS_DATA_SERVICE_NAME, "tcp",
		pbs_conf.pbs_data_service_port);
#else
	/* Non-Windows uses getservent() for better performance. */
	while ((servent = getservent()) != NULL) {
		if (strcmp(servent->s_proto, "tcp") != 0)
			continue;
		/* First, check the official service name. */
		pui = identify_service_entry(servent->s_name);
		if (pui != NULL) {
			*pui = (unsigned int)ntohs(servent->s_port);
			continue;
		}
		/* Next, check any aliases that may be defined. */
		for (servalias = servent->s_aliases; (servalias != NULL) && (*servalias != NULL); servalias++) {
			pui = identify_service_entry(*servalias);
			if (pui != NULL) {
				*pui = (unsigned int)ntohs(servent->s_port);
				break;
			}
		}
	}
	endservent();
#endif

	/*
	 * Once we determine the location of the pbs.conf file, it never changes.
	 * The fact that it is saved to the pbs_conf global structure means that
	 * we can always see its location when debugging.
	 */
	if (pbs_conf.pbs_conf_file == NULL)
		pbs_conf.pbs_conf_file = pbs_get_conf_file();

	/*
	 * Parse through the configuration file and set variables based
	 * on the contents of the file.
	 */
	if ((fp = fopen(pbs_conf.pbs_conf_file, "r")) != NULL) {
		while (parse_config_line(fp, &conf_name, &conf_value) != NULL) {
			if ((conf_name == NULL) || (*conf_name == '\0'))
				continue;

			if (!strcmp(conf_name, PBS_CONF_START_SERVER)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.start_server = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_START_MOM)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.start_mom = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_START_SCHED)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.start_sched = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_START_COMM)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.start_comm = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_LOCALLOG)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.locallog = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_SYSLOG)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.syslogfac = ((uvalue <= (23<<3)) ? uvalue : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_SYSLOGSEVR)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.syslogsvr = ((uvalue <= 7) ? uvalue : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_BATCH_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.batch_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_BATCH_SERVICE_PORT_DIS)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.batch_service_port_dis =
						((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port_dis);
			}
			else if (!strcmp(conf_name, PBS_CONF_MOM_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.mom_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.mom_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_MANAGER_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.manager_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.manager_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_SCHEDULER_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.scheduler_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.scheduler_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_DATA_SERVICE_PORT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_data_service_port =
						((uvalue <= 65535) ? uvalue : pbs_conf.pbs_data_service_port);
			}
			else if (!strcmp(conf_name, PBS_CONF_DATA_SERVICE_HOST)) {
				free(pbs_conf.pbs_data_service_host);
				pbs_conf.pbs_data_service_host = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_USE_TCP)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_use_tcp = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_USE_COMPRESSION)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_use_compression = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_USE_MCAST)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_use_mcast = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_FORCE_FT_COMM)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_use_ft = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_LEAF_NAME)) {
				if (pbs_conf.pbs_leaf_name)
					free(pbs_conf.pbs_leaf_name);
				pbs_conf.pbs_leaf_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_LEAF_ROUTERS)) {
				if (pbs_conf.pbs_leaf_routers)
					free(pbs_conf.pbs_leaf_routers);
				pbs_conf.pbs_leaf_routers = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_COMM_NAME)) {
				if (pbs_conf.pbs_comm_name)
					free(pbs_conf.pbs_comm_name);
				pbs_conf.pbs_comm_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_COMM_ROUTERS)) {
				if (pbs_conf.pbs_comm_routers)
					free(pbs_conf.pbs_comm_routers);
				pbs_conf.pbs_comm_routers = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_COMM_THREADS)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_comm_threads = uvalue;
			}
			else if (!strcmp(conf_name, PBS_CONF_COMM_LOG_EVENTS)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.pbs_comm_log_events = uvalue;
			}
			else if (!strcmp(conf_name, PBS_CONF_HOME)) {
				free(pbs_conf.pbs_home_path);
				pbs_conf.pbs_home_path = shorten_and_cleanup_path(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_EXEC)) {
				free(pbs_conf.pbs_exec_path);
				pbs_conf.pbs_exec_path = shorten_and_cleanup_path(conf_value);
			}
			/* Check for PBS_DEFAULT for backward compatibility */
			else if (!strcmp(conf_name, PBS_CONF_DEFAULT_NAME)) {
				free(pbs_conf.pbs_server_name);
				pbs_conf.pbs_server_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SERVER_NAME)) {
				free(pbs_conf.pbs_server_name);
				pbs_conf.pbs_server_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_RCP)) {
				free(pbs_conf.rcp_path);
				pbs_conf.rcp_path = shorten_and_cleanup_path(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SCP)) {
				free(pbs_conf.scp_path);
				pbs_conf.scp_path = shorten_and_cleanup_path(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_K5DCELOGIN)) {
				free(pbs_conf.k5dcelogin_path);
				pbs_conf.k5dcelogin_path = shorten_and_cleanup_path(conf_value);
			}
			/* rcp_path can be inferred from pbs_conf.pbs_exec_path - see below */
			/* pbs_demux_path is inferred from pbs_conf.pbs_exec_path - see below */
			else if (!strcmp(conf_name, PBS_CONF_ENVIRONMENT)) {
				free(pbs_conf.pbs_environment);
				pbs_conf.pbs_environment = shorten_and_cleanup_path(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_PRIMARY)) {
				free(pbs_conf.pbs_primary);
				pbs_conf.pbs_primary = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SECONDARY)) {
				free(pbs_conf.pbs_secondary);
				pbs_conf.pbs_secondary = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_MOM_HOME)) {
				free(pbs_conf.pbs_mom_home);
				pbs_conf.pbs_mom_home = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_CORE_LIMIT)) {
				free(pbs_conf.pbs_core_limit);
				pbs_conf.pbs_core_limit = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_LICENSE_STRING)) {
				free(pbs_conf.pbs_license_file_location);
				pbs_conf.pbs_license_file_location = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SERVER_HOST_NAME)) {
				free(pbs_conf.pbs_server_host_name);
				pbs_conf.pbs_server_host_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_PUBLIC_HOST_NAME)) {
				free(pbs_conf.pbs_public_host_name);
				pbs_conf.pbs_public_host_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_MAIL_HOST_NAME)) {
				free(pbs_conf.pbs_mail_host_name);
				pbs_conf.pbs_mail_host_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SMTP_SERVER_NAME)) {
				free(pbs_conf.pbs_smtp_server_name);
				pbs_conf.pbs_smtp_server_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_OUTPUT_HOST_NAME)) {
				free(pbs_conf.pbs_output_host_name);
				pbs_conf.pbs_output_host_name = strdup(conf_value);
			}
			else if (!strcmp(conf_name, PBS_CONF_SCHEDULER_MODIFY_EVENT)) {
				if (sscanf(conf_value, "%u", &uvalue) == 1)
					pbs_conf.sched_modify_event = ((uvalue > 0) ? 1 : 0);
			}
			else if (!strcmp(conf_name, PBS_CONF_MOM_NODE_NAME)) {
				free(pbs_conf.pbs_mom_node_name);
				pbs_conf.pbs_mom_node_name = strdup(conf_value);
			}
#ifdef WIN32
			else if (!strcmp(conf_name, PBS_CONF_REMOTE_VIEWER)) {
				free(pbs_conf.pbs_conf_remote_viewer);
				pbs_conf.pbs_conf_remote_viewer = strdup(conf_value);
			}
#endif
#ifndef WIN32
			else if (!strcmp(conf_name, PBS_CONF_AUTH)) {
				if (!strcasecmp(conf_value, "MUNGE")) {
				   pbs_conf.auth_method = AUTH_MUNGE;
				} else {
					fprintf(stderr, "pbsconf error: illegal value for %s\n",PBS_CONF_AUTH);
					goto err;
				}
			}
#endif
			/* iff_path is inferred from pbs_conf.pbs_exec_path - see below */
		}
		fclose(fp);
		free(pbs_loadconf_buf);
		pbs_loadconf_buf = NULL;
		pbs_loadconf_len = 0;
	}

	/*
	 * Next, check the environment variables and set values accordingly
	 * overriding those that were set in the configuration file.
	 */

	if ((gvalue = getenv(PBS_CONF_START_SERVER)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.start_server = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_START_MOM)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.start_mom = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_START_SCHED)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.start_sched = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_START_COMM)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.start_comm = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_LOCALLOG)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.locallog = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_SYSLOG)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.syslogfac = ((uvalue <= (23<<3)) ? uvalue : 0);
	}
	if ((gvalue = getenv(PBS_CONF_SYSLOGSEVR)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.syslogsvr = ((uvalue <= 7) ? uvalue : 0);
	}
	if ((gvalue = getenv(PBS_CONF_BATCH_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.batch_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_BATCH_SERVICE_PORT_DIS)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.batch_service_port_dis =
				((uvalue <= 65535) ? uvalue : pbs_conf.batch_service_port_dis);
	}
	if ((gvalue = getenv(PBS_CONF_MOM_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.mom_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.mom_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_MANAGER_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.manager_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.manager_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_SCHEDULER_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.scheduler_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.scheduler_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_HOME)) != NULL) {
		free(pbs_conf.pbs_home_path);
		pbs_conf.pbs_home_path = shorten_and_cleanup_path(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_EXEC)) != NULL) {
		free(pbs_conf.pbs_exec_path);
		pbs_conf.pbs_exec_path = shorten_and_cleanup_path(gvalue);
	}
	/* Check for PBS_DEFAULT for backward compatibility */
	if ((gvalue = getenv(PBS_CONF_DEFAULT_NAME)) != NULL) {
		free(pbs_conf.pbs_server_name);
		if ((pbs_conf.pbs_server_name = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_SERVER_NAME)) != NULL) {
		free(pbs_conf.pbs_server_name);
		if ((pbs_conf.pbs_server_name = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_RCP)) != NULL) {
		free(pbs_conf.rcp_path);
		pbs_conf.rcp_path = shorten_and_cleanup_path(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_SCP)) != NULL) {
		free(pbs_conf.scp_path);
		pbs_conf.scp_path = shorten_and_cleanup_path(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_K5DCELOGIN)) != NULL) {
		free(pbs_conf.k5dcelogin_path);
		pbs_conf.k5dcelogin_path = shorten_and_cleanup_path(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_PRIMARY)) != NULL) {
		free(pbs_conf.pbs_primary);
		if ((pbs_conf.pbs_primary = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_SECONDARY)) != NULL) {
		free(pbs_conf.pbs_secondary);
		if ((pbs_conf.pbs_secondary = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_MOM_HOME)) != NULL) {
		free(pbs_conf.pbs_mom_home);
		if ((pbs_conf.pbs_mom_home = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_CORE_LIMIT)) != NULL) {
		free(pbs_conf.pbs_core_limit);
		if ((pbs_conf.pbs_core_limit = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_DATA_SERVICE_HOST)) != NULL) {
		free(pbs_conf.pbs_data_service_host);
		if ((pbs_conf.pbs_data_service_host = strdup(gvalue)) == NULL) {
			goto err;
		}
	}
	if ((gvalue = getenv(PBS_CONF_USE_TCP)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_use_tcp = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_USE_COMPRESSION)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_use_compression = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_USE_MCAST)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_use_mcast = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_FORCE_FT_COMM)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_use_ft = ((uvalue > 0) ? 1 : 0);
	}
	if ((gvalue = getenv(PBS_CONF_LEAF_NAME)) != NULL) {
		if (pbs_conf.pbs_leaf_name)
			free(pbs_conf.pbs_leaf_name);
		pbs_conf.pbs_leaf_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_LEAF_ROUTERS)) != NULL) {
		if (pbs_conf.pbs_leaf_routers)
			free(pbs_conf.pbs_leaf_routers);
		pbs_conf.pbs_leaf_routers = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_COMM_NAME)) != NULL) {
		if (pbs_conf.pbs_comm_name)
			free(pbs_conf.pbs_comm_name);
		pbs_conf.pbs_comm_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_COMM_ROUTERS)) != NULL) {
		if (pbs_conf.pbs_comm_routers)
			free(pbs_conf.pbs_comm_routers);
		pbs_conf.pbs_comm_routers = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_COMM_THREADS)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_comm_threads = uvalue;
	}
	if ((gvalue = getenv(PBS_CONF_COMM_LOG_EVENTS)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_comm_log_events = uvalue;
	}
	if ((gvalue = getenv(PBS_CONF_DATA_SERVICE_PORT)) != NULL) {
		if (sscanf(gvalue, "%u", &uvalue) == 1)
			pbs_conf.pbs_data_service_port =
				((uvalue <= 65535) ? uvalue : pbs_conf.pbs_data_service_port);
	}
	if ((gvalue = getenv(PBS_CONF_SERVER_HOST_NAME)) != NULL) {
		free(pbs_conf.pbs_server_host_name);
		pbs_conf.pbs_server_host_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_PUBLIC_HOST_NAME)) != NULL) {
		free(pbs_conf.pbs_public_host_name);
		pbs_conf.pbs_public_host_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_MAIL_HOST_NAME)) != NULL) {
		free(pbs_conf.pbs_mail_host_name);
		pbs_conf.pbs_mail_host_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_SMTP_SERVER_NAME)) != NULL) {
		free(pbs_conf.pbs_smtp_server_name);
		pbs_conf.pbs_smtp_server_name = strdup(gvalue);
	}
	if ((gvalue = getenv(PBS_CONF_OUTPUT_HOST_NAME)) != NULL) {
		free(pbs_conf.pbs_output_host_name);
		pbs_conf.pbs_output_host_name = strdup(gvalue);
	}

	/* support PBS_MOM_NODE_NAME to tell MOM natural node name on server */
	if ((gvalue = getenv(PBS_CONF_MOM_NODE_NAME)) != NULL) {
		free(pbs_conf.pbs_mom_node_name);
		pbs_conf.pbs_mom_node_name = strdup(gvalue);
	}

	/* rcp_path is inferred from pbs_conf.pbs_exec_path - see below */
	/* pbs_demux_path is inferred from pbs_conf.pbs_exec_path - see below */
	if ((gvalue = getenv(PBS_CONF_ENVIRONMENT)) != NULL) {
		free(pbs_conf.pbs_environment);
		pbs_conf.pbs_environment = shorten_and_cleanup_path(gvalue);
	}

#ifdef WIN32
	if ((gvalue = getenv(PBS_CONF_REMOTE_VIEWER)) != NULL) {
		free(pbs_conf.pbs_conf_remote_viewer);
		pbs_conf.pbs_conf_remote_viewer = strdup(gvalue);
	}
	
#endif

	/* iff_path is inferred from pbs_conf.pbs_exec_path - see below */

	/*
	 * Now that we have parsed through the configuration file and the
	 * environment variables, check to make sure that all the critical
	 * items are set.
	 */

	buf[0] = '\0';
	if (pbs_conf.pbs_home_path == NULL)
		sprintf(buf, "%s %s", buf, PBS_CONF_HOME);
	if (pbs_conf.pbs_exec_path == NULL)
		sprintf(buf, "%s %s", buf, PBS_CONF_EXEC);
	if (pbs_conf.pbs_server_name == NULL)
		sprintf(buf, "%s %s", buf, PBS_CONF_SERVER_NAME);
	if (buf[0] != '\0') {
		fprintf(stderr, "pbsconf error: pbs conf variables not found: %s\n", buf);
		goto err;
	}

	/*
	 * Perform sanity checks on PBS_*_HOST_NAME values and PBS_CONF_SMTP_SERVER_NAME.
	 * See IDD for SPID 4534.
	 */
	buf[0] = '\0';
	if ((pbs_conf.pbs_server_host_name != NULL) &&
			(strchr(pbs_conf.pbs_server_host_name, ':') != NULL))
		strcpy(buf, PBS_CONF_SERVER_HOST_NAME);
	else if ((pbs_conf.pbs_public_host_name != NULL) &&
			(strchr(pbs_conf.pbs_public_host_name, ':') != NULL))
		strcpy(buf, PBS_CONF_PUBLIC_HOST_NAME);
	else if ((pbs_conf.pbs_mail_host_name != NULL) &&
			(strchr(pbs_conf.pbs_mail_host_name, ':') != NULL))
		strcpy(buf, PBS_CONF_MAIL_HOST_NAME);
	else if ((pbs_conf.pbs_smtp_server_name != NULL) &&
			(strchr(pbs_conf.pbs_smtp_server_name, ':') != NULL))
		strcpy(buf, PBS_CONF_SMTP_SERVER_NAME);
	else if ((pbs_conf.pbs_output_host_name != NULL) &&
			(strchr(pbs_conf.pbs_output_host_name, ':') != NULL))
		strcpy(buf, PBS_CONF_OUTPUT_HOST_NAME);
	else if ((pbs_conf.pbs_mom_node_name != NULL) &&
			(strchr(pbs_conf.pbs_mom_node_name, ':') != NULL))
		strcpy(buf, PBS_CONF_MOM_NODE_NAME);

	if (buf[0] != '\0') {
		fprintf(stderr, "pbsconf error: illegal value for: %s\n", buf);
		goto err;
	}

	/*
	 * Finally, fill in the blanks for variables with inferred values.
	 */

	if (pbs_conf.pbs_environment == NULL) {
		/* a reasonable default for the pbs_environment file is in pbs_home */
		/* strlen("/pbs_environment") + '\0' == 16 + 1 == 17 */
		if ((pbs_conf.pbs_environment =
			malloc(strlen(pbs_conf.pbs_home_path) + 17)) != NULL) {
			sprintf(pbs_conf.pbs_environment, "%s/pbs_environment",
				pbs_conf.pbs_home_path);
#ifdef WIN32
			back2forward_slash(pbs_conf.pbs_environment);
#endif
		} else {
			goto err;
		}
	}

	free(pbs_conf.iff_path);
	/* strlen("/sbin/pbs_iff") + '\0' == 13 + 1 == 14 */
	if ((pbs_conf.iff_path =
		malloc(strlen(pbs_conf.pbs_exec_path) + 14)) != NULL) {
		sprintf(pbs_conf.iff_path, "%s/sbin/pbs_iff", pbs_conf.pbs_exec_path);
#ifdef WIN32
		back2forward_slash(pbs_conf.iff_path);
#endif
	} else {
		goto err;
	}

	if (pbs_conf.rcp_path == NULL) {
		if ((pbs_conf.rcp_path =
			malloc(strlen(pbs_conf.pbs_exec_path) + 14)) != NULL) {
			sprintf(pbs_conf.rcp_path, "%s/sbin/pbs_rcp", pbs_conf.pbs_exec_path);
#ifdef WIN32
			back2forward_slash(pbs_conf.rcp_path);
#endif
		} else {
			goto err;
		}
	}

	free(pbs_conf.pbs_demux_path);
	/* strlen("/sbin/pbs_demux") + '\0' == 15 + 1 == 16 */
	if ((pbs_conf.pbs_demux_path =
		malloc(strlen(pbs_conf.pbs_exec_path) + 16)) != NULL) {
		sprintf(pbs_conf.pbs_demux_path, "%s/sbin/pbs_demux",
			pbs_conf.pbs_exec_path);
#ifdef WIN32
		back2forward_slash(pbs_conf.pbs_demux_path);
#endif
	} else {
		goto err;
	}

	if ((gvalue = getenv(PBS_CONF_LICENSE_STRING)) != NULL) {
		free(pbs_conf.pbs_license_file_location);
		if ((pbs_conf.pbs_license_file_location = strdup(gvalue)) == NULL) {
			goto err;
		}
	}

#ifndef WIN32
	if ((gvalue = getenv(PBS_CONF_AUTH)) != NULL) {
		if (!strcasecmp(gvalue, "MUNGE")) {
			pbs_conf.auth_method = AUTH_MUNGE;
		} else {
			fprintf(stderr, "pbsconf error: illegal value for %s\n",PBS_CONF_AUTH);
			goto err;
		}
	}
#endif

	pbs_conf.pbs_tmpdir = pbs_get_tmpdir();

	/* if routers has null value populate with server name as the default */
	if (pbs_conf.pbs_leaf_routers == NULL) {
		if (pbs_conf.pbs_primary && pbs_conf.pbs_secondary) {
			pbs_conf.pbs_leaf_routers = malloc(strlen(pbs_conf.pbs_primary) + strlen(pbs_conf.pbs_secondary) + 2);
			if (pbs_conf.pbs_leaf_routers == NULL) {
				fprintf(stderr, "Out of memory\n");
				goto err;
			}
			sprintf(pbs_conf.pbs_leaf_routers, "%s,%s", pbs_conf.pbs_primary, pbs_conf.pbs_secondary);
		} else {
			if (pbs_conf.pbs_server_host_name) {
				pbs_conf.pbs_leaf_routers = strdup(pbs_conf.pbs_server_host_name);
			} else if (pbs_conf.pbs_server_name) {
				pbs_conf.pbs_leaf_routers = strdup(pbs_conf.pbs_server_name);
			} else {
				fprintf(stderr, "PBS server undefined\n");
				goto err;
			}
			if (pbs_conf.pbs_leaf_routers == NULL) {
				fprintf(stderr, "Out of memory\n");
				goto err;
			}
		}
	}

	if (pbs_conf.pbs_use_tcp == 0) {
		pbs_conf.pbs_use_compression = 0;
		pbs_conf.pbs_use_mcast = 0;
		pbs_conf.pbs_use_ft = 0;
	}
	pbs_conf.loaded = 1;

	if (pbs_client_thread_unlock_conf() != 0)
		return 0;

	return 1;		/* success */

err:
	if (pbs_conf.pbs_conf_file) {
		free(pbs_conf.pbs_conf_file);
		pbs_conf.pbs_conf_file = NULL;
	}
	if (pbs_conf.pbs_data_service_host) {
		free(pbs_conf.pbs_data_service_host);
		pbs_conf.pbs_data_service_host = NULL;
	}
	if (pbs_conf.pbs_home_path) {
		free(pbs_conf.pbs_home_path);
		pbs_conf.pbs_home_path = NULL;
	}
	if (pbs_conf.pbs_exec_path) {
		free(pbs_conf.pbs_exec_path);
		pbs_conf.pbs_exec_path = NULL;
	}
	if (pbs_conf.pbs_server_name) {
		free(pbs_conf.pbs_server_name);
		pbs_conf.pbs_server_name = NULL;
	}
	if (pbs_conf.rcp_path) {
		free(pbs_conf.rcp_path);
		pbs_conf.rcp_path = NULL;
	}
	if (pbs_conf.scp_path) {
		free(pbs_conf.scp_path);
		pbs_conf.scp_path = NULL;
	}
	if (pbs_conf.k5dcelogin_path) {
		free(pbs_conf.k5dcelogin_path);
		pbs_conf.k5dcelogin_path = NULL;
	}
	if (pbs_conf.pbs_environment) {
		free(pbs_conf.pbs_environment);
		pbs_conf.pbs_environment = NULL;
	}
	if (pbs_conf.pbs_primary) {
		free(pbs_conf.pbs_primary);
		pbs_conf.pbs_primary = NULL;
	}
	if (pbs_conf.pbs_secondary) {
		free(pbs_conf.pbs_secondary);
		pbs_conf.pbs_secondary = NULL;
	}
	if (pbs_conf.pbs_mom_home) {
		free(pbs_conf.pbs_mom_home);
		pbs_conf.pbs_mom_home = NULL;
	}
	if (pbs_conf.pbs_core_limit) {
		free(pbs_conf.pbs_core_limit);
		pbs_conf.pbs_core_limit = NULL;
	}
	if (pbs_conf.pbs_license_file_location) {
		free(pbs_conf.pbs_license_file_location);
		pbs_conf.pbs_license_file_location = NULL;
	}

	pbs_conf.load_failed = 1;
	(void)pbs_client_thread_unlock_conf();
	return 0;
}
Exemplo n.º 4
0
/**
 * @brief
 *	parses path and prepares complete path name
 *
 * @param[in]      path_in - the path name provided as input to be parsed
 * @param[out]     path_out - contains final parsed and prepared path, must
 *                            be at least MAXPATHLEN+1 bytes.
 *
 * @return int
 * @retval  0 - success in parsing
 * @retval  nonzero - error encountered in parsing
 */
int
prepare_path(char *path_in, char *path_out)
{
	char *c = NULL;
	int have_fqdn = 0;
	/* Initialization with {'\0'} populates entire array */
	char host_name[PBS_MAXSERVERNAME + 1] = {'\0'};	/* short host name */
	int h_pos = 0;
	char path_name[MAXPATHLEN + 1] = {'\0'};
	size_t path_len;
	int p_pos = 0;
	char *host_given = NULL;
	struct stat statbuf = {0};
	dev_t dev = 0;
	ino_t ino = 0;

	if (!path_out)
		return 1;
	*path_out = '\0';
	if (!path_in)
		return 1;

	/* Begin the parse */
	for (c = path_in; *c; c++) {
		if (isspace(*c) == 0)
			break;
	}
	if (*c == '\0')
		return 1;

#ifdef WIN32
	/* Check for drive letter in Windows */
	if (!(isalpha(*c) && (*(c + 1) == ':')))
#endif
	{
		/* Looking for a hostname */
		if ((host_given = strchr(c, ':')) != NULL) {
			/* Capture the hostname portion */
			for (h_pos = 0; (h_pos < sizeof(host_name)); h_pos++, c++) {
				if (isalnum(*c) || (*c == '.') || (*c == '-')
#ifdef WIN32
					/* Underscores are legal in Windows */
					|| (*c == '_')
#endif
					) {
					host_name[h_pos] = *c;
				} else {
					break;
				}
			}
			if (*c != ':')
				return 1;
			/* Advance past the colon */
			c++;
		}
	}

	/* Looking for a posix path */
	for (p_pos = 0; p_pos < sizeof(path_name); p_pos++, c++) {
		if (!isprint(*c))
			break;
		path_name[p_pos] = *c;
	}
	/* Should be at end of string */
	if (*c != '\0')
		return 1;

	path_len = strlen(path_name);
	if (path_len == 0 && strlen(host_name) == 0)
		return 1;

	/* appending a slash in the end to indicate that it is a directory */
	if ((path_name[path_len - 1] != '/') &&
	    (path_name[path_len - 1] != '\\') &&
	    (stat(path_name, &statbuf) == 0) &&
            S_ISDIR(statbuf.st_mode)) {
		if ((path_len + 1) < sizeof(path_name)) {
			strcat(path_name, "/");
			path_len++;
		}
	}

#ifdef WIN32
	if (IS_UNCPATH(path_name)) {
		/*
		 * given path is UNC path
		 * so just skip hostname
		 * as UNC path dose not require it
		 */
		host_given = NULL;
		host_name[0] = '\0';
	} else
#endif
	{
		/* get full host name */
		if (host_name[0] == '\0') {
			if (pbs_conf.pbs_output_host_name) {
				/* use the specified host for returning the file */
				snprintf(host_name, sizeof(host_name), "%s", pbs_conf.pbs_output_host_name);
				have_fqdn = 1;
			} else {
				if (gethostname(host_name, sizeof(host_name)) != 0)
					return 2;
				host_name[sizeof(host_name) - 1] = '\0';
			}
		}
		if (have_fqdn == 0) {
			char host_fqdn[PBS_MAXSERVERNAME + 1] = {'\0'};
			/* need to fully qualify the host name */
			if (get_fullhostname(host_name, host_fqdn, PBS_MAXSERVERNAME) != 0)
				return 2;
			strncpy(path_out, host_fqdn, MAXPATHLEN); /* FQ host name */
		} else {
			strncpy(path_out, host_name, MAXPATHLEN); /* "localhost" or pbs_output_host_name */
		}
		path_out[MAXPATHLEN - 1] = '\0';

		/* finish preparing complete host name */
		if (strlen(path_out) < MAXPATHLEN)
			strcat(path_out, ":");
	}

#ifdef WIN32
	if (path_name[0] != '/' && path_name[0] != '\\' &&
		host_given == NULL && strchr(path_name, ':') == NULL )
#else
	if (path_name[0] != '/' && host_given == NULL)
#endif
	{
		char cwd[MAXPATHLEN + 1] = {'\0'};

		c = getenv("PWD");		/* PWD carries a name that will cause */
		if (c != NULL) {		/* the NFS to mount */

			if (stat(c, &statbuf) < 0) {	/* can't stat PWD */
				c = NULL;
			} else {
				dev = statbuf.st_dev;
				ino = statbuf.st_ino;
				if (stat(".", &statbuf) < 0) {
					perror("prepare_path: cannot stat current directory:");
					*path_out = '\0';
					return (1);
				}
			}
			if (dev == statbuf.st_dev && ino == statbuf.st_ino) {
				snprintf(cwd, sizeof(cwd), "%s", c);
			} else {
				c = NULL;
			}
		}
		if (c == NULL) {
			c = getcwd(cwd, MAXPATHLEN);
			if (c == NULL) {
				perror("prepare_path: getcwd failed : ");
				*path_out = '\0';
				return (1);
			}
		}
#ifdef WIN32
		/* get UNC path (if available) if it is mapped drive */
		get_uncpath(cwd);
		if (IS_UNCPATH(cwd)) {
			strcpy(path_out, cwd);
			if (cwd[strlen(cwd)-1] != '\\')
				strcat(path_out, "\\");
		} else
#endif
		{
			strncat(path_out, cwd, (MAXPATHLEN + 1) - strlen(path_out));
			if (strlen(path_out) < MAXPATHLEN)
				strcat(path_out, "/");
		}
	}


#ifdef WIN32
	/* get UNC path (if available) if it is mapped drive */
	get_uncpath(path_name);
	if (IS_UNCPATH(path_name))
		strcpy(path_out, path_name);
	else {
		/*
		 * check whether given <path_name> is relative path
		 * without drive on localhost and <cwd> is not UNC path?
		 * if yes then do not append drive into <path_out>
		 * otherwise append drive into <path_out>
		 */
		if (is_local_host(host_name) &&
			(strchr(path_name, ':') == NULL) &&
			(path_out[strlen(path_out) - 1] != '/') &&
			(!IS_UNCPATH(path_out))) {

			char drivestr[3] = {'\0'};
			char drivestr_unc[MAXPATHLEN + 1] = {'\0'};

			drivestr[0] = _getdrive() + 'A' - 1;
			drivestr[1] = ':';
			drivestr[2] = '\0';
			/*
			 * check whether <drivestr> is mapped drive?
			 * by calling get_uncpath()
			 * if yes then remove <hostname> part from <path_out>
			 *
			 * This is the case when user submit job
			 * from mapped drive with relative path without drive
			 * in path ex. localhost:err or localhost:out
			 */
			snprintf(drivestr_unc, sizeof(drivestr_unc), "%s\\", drivestr);
			get_uncpath(drivestr_unc);
			if (IS_UNCPATH(drivestr_unc)) {
				strncpy(path_out, drivestr_unc, MAXPATHLEN);
			} else {
				strncat(path_out, drivestr, MAXPATHLEN - strlen(path_out));
			}
		}
		strncat(path_out, path_name, MAXPATHLEN - strlen(path_out));
	}
	back2forward_slash(path_out);	/* "\" translate to "/" for path */
	strcpy(path_out, replace_space(path_out, "\\ "));
	path_out[MAXPATHLEN - 1] = '\0';
#else
	strncat(path_out, path_name, (MAXPATHLEN + 1) - strlen(path_out));
#endif

	return (0);
}
Exemplo n.º 5
0
/**
 * @brief 
 *	sets the environment for reservation
 *
 * @param[in] envp - pointer to pointer to the environment variable
 *
 * @return - Boolean value
 * @retval   TRUE  Success
 * @retval   FALSE Failure
 *
 */
int
set_resv_env(char **envp)
{
	char *job_env;
	char *c, *env;
	char host[PBS_MAXHOSTNAME+1];
	int len;
	int rc;

	/* Calculate how big to make the variable string. */
	len = 0;
	env = getenv("HOME");
	if (env != NULL) len += strlen(env);
	env = getenv("LANG");
	if (env != NULL) len += strlen(env);
	env = getenv("LOGNAME");
	if (env != NULL) len += strlen(env);
	env = getenv("PATH");
	if (env != NULL) len += strlen(env);
	env = getenv("MAIL");
	if (env != NULL) len += strlen(env);
	env = getenv("SHELL");
	if (env != NULL) len += strlen(env);
	env = getenv("TZ");
	if (env != NULL) len += strlen(env);
	len += PBS_MAXHOSTNAME;
	len += MAXPATHLEN;
	len += len;     /* Double it for all the commas, etc. */
	if ((job_env = (char *) malloc(len)) == NULL) {
		fprintf(stderr, "pbs_rsub: Out of memory\n");
		return FALSE;
	}
	*job_env = '\0';

	/* Send the required variables with the job. */
	c = getenv("LOGNAME");
	if (c != NULL) {
		strcat(job_env, "PBS_O_LOGNAME=");
		strcat(job_env, c);
	}
	if ((rc = gethostname(host, (sizeof(host) - 1))) == 0) {
		if ((rc = get_fullhostname(host, host, (sizeof(host) - 1))) == 0) {
			if (*job_env)
				strcat(job_env, ",PBS_O_HOST=");
			else
				strcat(job_env, "PBS_O_HOST=");
			strcat(job_env, host);
		}
	}

	c = getenv("MAIL");
	if (c != NULL) {
#ifdef WIN32
		back2forward_slash(c);
#endif
		strcat(job_env, ",PBS_O_MAIL=");
		strcat(job_env, c);
	}
	if (rc != 0) {
		fprintf(stderr, "pbs_rsub: cannot get full local host name\n");
		exit(3);
	}
	c = getenv("PBS_TZID");
	if (c != NULL) {
		strcat(job_env, ",PBS_TZID=");
		strcat(job_env, c);
		set_attr(&attrib, ATTR_resv_timezone, c);
	}
	else if (is_stdng_resv) {
		fprintf(stderr, "pbs_rsub error: a valid PBS_TZID timezone environment variable is required.\n");
		exit(2);
	}

	set_attr(&attrib, ATTR_v, job_env);
	free(job_env);
	return TRUE;
}
Exemplo n.º 6
0
/** @fn int parse_at_list(char *list, int use_count, int abs_path)
 * @brief	parse a comma-separated list of name[@host] items
 *
 * @param[in]	list
 * @param[out]	use_count	if true, make sure no host is repeated
 *				in the list, and host is defaulted only
 *				once
 * @param[out]	abs_path	if true, make sure the item appears to
 *				begin with an absolute path name
 *
 * @return	int
 * @retval	1	parsing failure
 * @retval	0	success

 * @par MT-Safe:	no
 * @par Side Effects:
 *	exits with return code 1 on memory allocation failure
 */
int
parse_at_list(char *list, int use_count, int abs_path)
{
	char *b, *c, *s, *list_dup;
	int rc = 0;
	char user[MAXPATHLEN+1];
	char host[PBS_MAXSERVERNAME];
	struct hostlist *ph, *nh, *hostlist = NULL;

	if ((list == NULL) || (*list == '\0'))
		return 1;

#ifdef WIN32
	back2forward_slash(list);        /* "\" translate to "/" for path */
#endif

	if ((list_dup = strdup(list)) == NULL) {
		fprintf(stderr, "Out of memory.\n");
		return 1;
	}

	for (c = list_dup; *c != '\0'; rc = 0) {
		rc = 1;

		/* Drop leading white space */
		while (isspace(*c))
			c++;

		/* If requested, is this an absolute path */
		if (abs_path && !is_full_path(c))
			break;

		/* Find the next comma */
		for (s = c; *c && *c != ','; c++)
			;

		/* Drop any trailing blanks */
		for (b = c - 1; (b >= list_dup) && isspace(*b); b--)
			*b = '\0';

		/* Make sure the list does not end with a comma */
		if (*c == ',') {
			*c++ = '\0';
			if (*c == '\0')
				break;
		}

		/* Parse the individual list item */
		if (parse_at_item(s, user, host))
			break;

		/* The user part must be given */
		if (*user == '\0')
			break;

		/* If requested, make sure the host name is not repeated */
		if (use_count) {
			ph = hostlist;
			while (ph) {
				if (strcmp(ph->host, host) == 0)
					goto duplicate;
				ph = ph->next;
			}
			nh = (struct hostlist *) malloc(sizeof(struct hostlist));
			if (nh == NULL) {
				fprintf(stderr, "Out of memory\n");
				return 1;
			}
			nh->next = hostlist;
			strcpy(nh->host, host);
			hostlist = nh;
		}
	}
duplicate:

	/* Release memory for hostlist and argument list */
	ph = hostlist;
	while (ph) {
		nh = ph->next;
		free(ph);
		ph = nh;
	}
	free(list_dup);

	return rc;
}