Exemple #1
0
char *PBS_get_server(

  const char         *server,  /* I (NULL|'\0' for not set,modified) */
  unsigned int *port)    /* O */

  {
  int   i;
  char *pc;

  for (i = 0;i < PBS_MAXSERVERNAME + 1;i++)
    {
    /* clear global server_name */

    server_name[i] = '\0';
    }

  if (dflt_port == 0)
    {
    dflt_port = get_svrport(
                  (char *)PBS_BATCH_SERVICE_NAME,
                  (char *)"tcp",
                  PBS_BATCH_SERVICE_PORT);
    }

  /* first, get the "net.address[:port]" into 'server_name' */

  if ((server == (char *)NULL) || (*server == '\0'))
    {
    if (pbs_default() == NULL)
      {
      return(NULL);
      }
    }
  else
    {
    snprintf(server_name, sizeof(server_name), "%s", server);
    }

  /* now parse out the parts from 'server_name' */

  if ((pc = strchr(server_name, (int)':')))
    {
    /* got a port number */

    *pc++ = '\0';

    *port = atoi(pc);
    }
  else
    {
    *port = dflt_port;
    }

  return(server_name);
  }  /* END PBS_get_server() */
Exemple #2
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;
}
void
start_tcl(void)
{
    char *id = "start_tcl";
    char buf[BUFSIZ];
    int fd;
    int tot, len;

    interp = Tcl_CreateInterp();

    if (Tcl_Init(interp) == TCL_ERROR)
    {
        sprintf(log_buffer, "Tcl_Init error: %s",
                Tcl_GetStringResult(interp));
        log_err(-1, id, log_buffer);
        die(0);
    }

#if TCLX
#if TCL_MINOR_VERSION < 5  && TCL_MAJOR_VERSION < 8
    if (TclX_Init(interp) == TCL_ERROR)
    {
#else

    if (Tclx_Init(interp) == TCL_ERROR)
    {
#endif
        sprintf(log_buffer, "Tclx_Init error: %s",
                Tcl_GetStringResult(interp));
        log_err(-1, id, log_buffer);
        die(0);
    }

#endif
    add_cmds(interp);

    if (initfil)
    {
        int  code;

        code = Tcl_EvalFile(interp, initfil);

        if (code != TCL_OK)
        {
            char *trace;

            trace = (char *)Tcl_GetVar(interp, "errorInfo", 0);

            if (trace == NULL)
                trace = (char *)Tcl_GetStringResult(interp);

            fprintf(stderr, "%s: TCL error @ line %d: %s\n",
                    initfil, interp->errorLine, trace);

            sprintf(log_buffer, "%s: TCL error @ line %d: %s",
                    initfil, interp->errorLine,
                    Tcl_GetStringResult(interp));

            log_err(-1, id, log_buffer);

            die(0);
        }

        sprintf(log_buffer, "init file %s", initfil);

        log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER,
                   id, log_buffer);
    }

    if ((fd = open(bodyfil, O_RDONLY)) == -1)
    {
        log_err(errno, id, bodyfil);
        die(0);
    }

    sprintf(log_buffer, "body file: %s", bodyfil);

    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    if (body)
        free(body);

    if ((body = malloc(BUFSIZ)) == NULL)
    {
        log_err(errno, id, "malloc");
        die(0);
    }

    for (tot = 0; (len = read(fd, buf, sizeof(buf))) > 0; tot += len)
    {
        if ((body = realloc(body, tot + len + 1)) == NULL)
        {
            log_err(errno, id, "realloc");
            die(0);
        }

        memcpy(&body[tot], buf, len);
    }

    if (len == -1)
    {
        log_err(errno, id, bodyfil);
        die(0);
    }

    body[tot] = '\0';

    close(fd);

#if TCL_MAJOR_VERSION >= 8

    if (body_obj == NULL)
    {
        body_obj = Tcl_NewStringObj(body, tot);
        Tcl_IncrRefCount(body_obj);
    }
    else
    {
        Tcl_SetStringObj(body_obj, body, tot);
    }

#endif
}

int

addclient(name)
char *name;
{
    static char id[] = "addclient";

    struct hostent  *host, *gethostbyname();

    struct  in_addr saddr;

    if ((host = gethostbyname(name)) == NULL)
    {
        sprintf(log_buffer, "host %s not found", name);
        log_err(-1, id, log_buffer);
        return -1;
    }

    if (numclients >= START_CLIENTS)
    {
        pbs_net_t *newclients;

        newclients = realloc(okclients,
                             sizeof(pbs_net_t) * (numclients + 1));

        if (newclients == NULL)
            return -1;

        okclients = newclients;
    }

    memcpy((char *)&saddr, host->h_addr, host->h_length);

    okclients[numclients++] = saddr.s_addr;
    return 0;
}

/*
 * read_config - read and process the configuration file (see -c option)
 *
 * Currently, the only statement is $clienthost to specify which systems
 * can contact the scheduler.
 */
#define CONF_LINE_LEN 120

static
int
read_config(file)
char *file;
{
    static char *id = "read_config";
    FILE *conf;
    int i;
    char line[CONF_LINE_LEN];
    char *token;

    struct specialconfig
    {
        char *name;
        int (*handler)();
    } special[] =

    {
        {"clienthost", addclient },
        { NULL,  NULL }
    };


#if !defined(DEBUG) && !defined(NO_SECURITY_CHECK)

    if (chk_file_sec(file, 0, 0, S_IWGRP | S_IWOTH, 1, 0))
        return (-1);

#endif

    if ((conf = fopen(file, "r")) == NULL)
    {
        log_err(errno, id, "cannot open config file");
        return (-1);
    }

    while (fgets(line, CONF_LINE_LEN, conf))
    {

        if ((line[0] == '#') || (line[0] == '\n'))
            continue;  /* ignore comment & null line */
        else if (line[0] == '$')   /* special */
        {

            if ((token = strtok(line, " \t")) == NULL)
                token = "";

            for (i = 0; special[i].name; i++)
            {
                if (strcmp(token + 1, special[i].name) == 0)
                    break;
            }

            if (special[i].name == NULL)
            {
                sprintf(log_buffer, "config name %s not known",
                        token);
                log_record(PBSEVENT_ERROR,
                           PBS_EVENTCLASS_SERVER,
                           msg_daemonname, log_buffer);
                return (-1);
            }

            token = strtok(NULL, " \t");

            if (*(token + strlen(token) - 1) == '\n')
                *(token + strlen(token) - 1) = '\0';

            if (special[i].handler(token))
            {
                fclose(conf);
                return (-1);
            }

        }
        else
        {
            log_record(PBSEVENT_ERROR, PBS_EVENTCLASS_SERVER,
                       msg_daemonname,
                       "invalid line in config file");
            fclose(conf);
            return (-1);
        }
    }

    fclose(conf);

    return (0);
}

void
restart(sig)
int sig;
{
    char    *id = "restart";

    if (sig)
    {
        sprintf(log_buffer, "restart on signal %d", sig);
        log_close(1);
        log_open(logfile, path_log);
    }
    else
    {
        sprintf(log_buffer, "restart command");
    }

    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    Tcl_DeleteInterp(interp);

    if (configfile)
    {
        if (read_config(configfile) != 0)
            die(0);
    }

    start_tcl();
}

void
badconn(msg)
char *msg;
{
    static char id[] = "badconn";

    struct in_addr addr;
    char  buf[5*sizeof(addr) + 100];

    struct hostent *phe;

    addr = saddr.sin_addr;
    phe = gethostbyaddr((void *) & addr, sizeof(addr), AF_INET);

    if (phe == NULL)
    {
        char hold[6];
        int i;
        union
        {

            struct in_addr aa;
            u_char  bb[sizeof(addr)];
        } uu;

        uu.aa = addr;
        sprintf(buf, "%u", uu.bb[0]);

        for (i = 1; i < (int)sizeof(addr); i++)
        {
            sprintf(hold, ".%u", uu.bb[i]);
            strcat(buf, hold);
        }
    }
    else
    {
        strncpy(buf, phe->h_name, sizeof(buf));
        buf[sizeof(buf)-1] = '\0';
    }

    sprintf(log_buffer, "%s on port %u %s", buf, ntohs(saddr.sin_port), msg);

    log_err(-1, id, log_buffer);
    return;
}

unsigned int
server_command()
{
    static char id[] = "server_command";
    int  new_socket;
    int  i;
    torque_socklen_t slen;
    unsigned int  cmd;
    pbs_net_t addr;

    slen = sizeof(saddr);
    new_socket = accept(server_sock,
                        (struct sockaddr *) & saddr, &slen);

    if (new_socket == -1)
    {
        log_err(errno, id, "accept");
        return SCH_ERROR;
    }

    if (ntohs(saddr.sin_port) >= IPPORT_RESERVED)
    {
        badconn("non-reserved port");
        close(new_socket);
        return SCH_ERROR;
    }

    addr = (pbs_net_t)saddr.sin_addr.s_addr;

    for (i = 0; i < numclients; i++)
    {
        if (addr == okclients[i])
            break;
    }

    if (i == numclients)
    {
        badconn("unauthorized host");
        close(new_socket);
        return SCH_ERROR;
    }

    if ((connector = socket_to_conn(new_socket)) < 0)
    {
        log_err(errno, id, "socket_to_conn");
        return SCH_ERROR;
    }

    if (get_4byte(new_socket, &cmd) != 1)
    {
        log_err(errno, id, "get4bytes");
        return SCH_ERROR;
    }

    return cmd;
}


/*
 * lock_out - lock out other daemons from this directory.
 */

static void lock_out(fds, op)
int fds;
int op;  /* F_WRLCK  or  F_UNLCK */
{

    struct flock flock;

    flock.l_type   = op;
    flock.l_whence = SEEK_SET;
    flock.l_start  = 0;
    flock.l_len    = 0; /* whole file */

    if (fcntl(fds, F_SETLK, &flock) < 0)
    {
        (void)strcpy(log_buffer, "pbs_sched: another scheduler running\n");
        log_err(errno, msg_daemonname, log_buffer);
        fprintf(stderr, log_buffer);
        exit(1);
    }
}

int main(argc, argv)
int  argc;
char *argv[];
{
    char  *id = "main";
    int  code;

    struct hostent *hp;
    int  go, c, errflg = 0;
    int  lockfds;
    int  t = 1;
    char  *ptr;
    pid_t  pid;
    char  *cp, host[100];
    char  *homedir = PBS_SERVER_HOME;
    unsigned int port;
    char  path_priv[_POSIX_PATH_MAX];
    char  *dbfile = "sched_out";
    int  alarm_time = 180;

    struct sigaction act;
    caddr_t  curr_brk = 0, next_brk;
    extern char *optarg;
    extern int optind, opterr;
    fd_set  fdset;

#ifndef DEBUG
    if (IamRoot() == 0)
    {
        return (1);
    }
#endif /* DEBUG */

    glob_argv = argv;

    if ((cp = strrchr(argv[0], '/')) == NULL)
        cp = argv[0];
    else
        cp++;

    msg_daemonname = strdup(cp);

    port = get_svrport(PBS_SCHEDULER_SERVICE_NAME, "tcp",
                       PBS_SCHEDULER_SERVICE_PORT);

    while ((c = getopt(argc, argv, "L:S:d:i:b:t:p:a:vc:")) != EOF)
    {
        switch (c)
        {

        case 'L':
            logfile = optarg;
            break;

        case 'S':
            port = (unsigned int)atoi(optarg);

            if (port == 0)
            {
                fprintf(stderr,
                        "%s: illegal port\n", optarg);
                errflg = 1;
            }

            break;

        case 'd':
            homedir = optarg;
            break;

        case 'i':  /* initialize */
            initfil = optarg;
            break;

        case 'b':
            bodyfil = optarg;
            break;

        case 't':
            termfil = optarg;
            break;

        case 'p':
            dbfile = optarg;
            break;

        case 'a':
            alarm_time = strtol(optarg, &ptr, 10);

            if (alarm_time <= 0 || *ptr != '\0')
            {
                fprintf(stderr,
                        "%s: bad alarm time\n", optarg);
                errflg = 1;
            }

            break;

        case 'c':
            configfile = optarg;
            break;

        case 'v':
            verbose = 1;
            break;

        case '?':
            errflg = 1;
            break;
        }
    }

    if (errflg || optind != argc)
    {
        static char *options[] =
        {
            "[-L logfile]",
            "[-S port]",
            "[-d home]",
            "[-i init]",
            "[-b body]",
            "[-t term]",
            "[-p output]",
            "[-a alarm]",
            "[-c configfile]",
            "[-v]",
            NULL
        };
        int i;

        fprintf(stderr, "usage: %s\n", argv[0]);

        for (i = 0; options[i]; i++)
            fprintf(stderr, "\t%s\n", options[i]);

        exit(1);
    }

    /* Save the original working directory for "restart" */
    if ((oldpath = getcwd((char *)NULL, MAXPATHLEN)) == NULL)
    {
        fprintf(stderr, "cannot get current working directory\n");
        exit(1);
    }

    (void)sprintf(path_priv, "%s/sched_priv", homedir);
#if !defined(DEBUG) && !defined(NO_SECURITY_CHECK)
    c  = chk_file_sec(path_priv, 1, 0, S_IWGRP | S_IWOTH, 1, 0);
    c |= chk_file_sec(PBS_ENVIRON, 0, 0, S_IWGRP | S_IWOTH, 0, 0);

    if (c != 0) exit(1);

#endif  /* not DEBUG and not NO_SECURITY_CHECK */
    if (chdir(path_priv) == -1)
    {
        perror(path_priv);
        exit(1);
    }

    (void)sprintf(path_log, "%s/sched_logs", homedir);
    (void)strcpy(pbs_current_user, "Scheduler");

    /* The following is code to reduce security risks                */
    /* start out with standard umask, system resource limit infinite */

    umask(022);

    if (setup_env(PBS_ENVIRON) == -1)
        exit(1);

    c = getgid();

    (void)setgroups(1, (gid_t *)&c); /* secure suppl. group ids */

    c = sysconf(_SC_OPEN_MAX);

    while (--c > 2)
        (void)close(c); /* close any file desc left open by parent */

#ifndef DEBUG
#ifdef _CRAY
    (void)limit(C_JOB,      0, L_CPROC, 0);

    (void)limit(C_JOB,      0, L_CPU,   0);

    (void)limit(C_JOBPROCS, 0, L_CPU,   0);

    (void)limit(C_PROC,     0, L_FD,  255);

    (void)limit(C_JOB,      0, L_FSBLK, 0);

    (void)limit(C_JOBPROCS, 0, L_FSBLK, 0);

    (void)limit(C_JOB,      0, L_MEM  , 0);

    (void)limit(C_JOBPROCS, 0, L_MEM  , 0);

#else /* not  _CRAY */
    {

        struct rlimit rlimit;

        rlimit.rlim_cur = RLIM_INFINITY;
        rlimit.rlim_max = RLIM_INFINITY;
        (void)setrlimit(RLIMIT_CPU,   &rlimit);
        (void)setrlimit(RLIMIT_FSIZE, &rlimit);
        (void)setrlimit(RLIMIT_DATA,  &rlimit);
        (void)setrlimit(RLIMIT_STACK, &rlimit);
#ifdef  RLIMIT_RSS
        (void)setrlimit(RLIMIT_RSS  , &rlimit);
#endif  /* RLIMIT_RSS */
#ifdef  RLIMIT_VMEM
        (void)setrlimit(RLIMIT_VMEM  , &rlimit);
#endif  /* RLIMIT_VMEM */
    }
#endif /* not _CRAY */

#if !defined(NO_SECURITY_CHECK)
    c = 0;

    if (initfil)
    {
        if (*initfil != '/')
        {
            (void)sprintf(log_buffer, "%s/%s", path_priv, initfil);
            c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
        else
        {
            c |= chk_file_sec(initfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
    }

    if (bodyfil)
    {
        if (*bodyfil != '/')
        {
            (void)sprintf(log_buffer, "%s/%s", path_priv, bodyfil);
            c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
        else
        {
            c |= chk_file_sec(bodyfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
    }

    if (termfil)
    {
        if (*termfil != '/')
        {
            (void)sprintf(log_buffer, "%s/%s", path_priv, termfil);
            c |= chk_file_sec(log_buffer, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
        else
        {
            c |= chk_file_sec(termfil, 0, 0, S_IWGRP | S_IWOTH, 1, 0);
        }
    }

    if (c) exit(1);

#endif /* not NO_SECURITY_CHECK */
#endif /* not DEBUG */

    if (log_open(logfile, path_log) == -1)
    {
        fprintf(stderr, "%s: logfile could not be opened\n", argv[0]);
        exit(1);
    }

    if (gethostname(host, sizeof(host)) == -1)
    {
        char *prob = "gethostname";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    if ((hp = gethostbyname(host)) == NULL)
    {
        char *prob = "gethostbyname";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        char *prob = "socket";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR,
                   (char *)&t, sizeof(t)) == -1)
    {
        char *prob = "setsockopt";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    saddr.sin_family = AF_INET;

    saddr.sin_port = htons((unsigned short)port);
    memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);

    if (bind(server_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        char *prob = "bind";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    if (listen(server_sock, 5) < 0)
    {
        char *prob = "listen";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    okclients = (pbs_net_t *)calloc(START_CLIENTS, sizeof(pbs_net_t));

    addclient("localhost");   /* who has permission to call MOM */
    addclient(host);

    if (configfile)
    {
        if (read_config(configfile) != 0)
            die(0);
    }

    lockfds = open("sched.lock", O_CREAT | O_TRUNC | O_WRONLY, 0644);

    if (lockfds < 0)
    {
        char *prob = "lock file";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }

    lock_out(lockfds, F_WRLCK);

#ifndef DEBUG
    lock_out(lockfds, F_UNLCK);

    if ((pid = fork()) == -1)       /* error on fork */
    {
        char *prob = "fork";

        log_err(errno, id, prob);
        perror(prob);
        die(0);
    }
    else if (pid > 0)               /* parent exits */
        exit(0);

    if ((pid = setsid()) == -1)
    {
        log_err(errno, id, "setsid");
        die(0);
    }

    lock_out(lockfds, F_WRLCK);

    freopen(dbfile, "a", stdout);
    setvbuf(stdout, NULL, _IOLBF, 0);
    dup2(fileno(stdout), fileno(stderr));
#else
    pid = getpid();
    setvbuf(stdout, NULL, _IOLBF, 0);
    setvbuf(stderr, NULL, _IOLBF, 0);
#endif
    freopen("/dev/null", "r", stdin);

    /* write schedulers pid into lockfile */
    (void)sprintf(log_buffer, "%d\n", pid);
    (void)write(lockfds, log_buffer, strlen(log_buffer) + 1);

#if (PLOCK_DAEMONS & 2)
    (void)plock(PROCLOCK); /* lock daemon into memory */
#endif

    sprintf(log_buffer, "%s startup pid %d", argv[0], pid);
    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    sprintf(log_buffer, "%s using TCL %s (%s)", argv[0],
            TCL_VERSION, TCL_PATCH_LEVEL);
    fprintf(stderr, "%s\n", log_buffer);
    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    fullresp(0);
    sigemptyset(&allsigs);
    act.sa_flags = 0;
    sigaddset(&allsigs, SIGHUP);    /* remember to block these */
    sigaddset(&allsigs, SIGINT);    /* during critical sections */
    sigaddset(&allsigs, SIGTERM);   /* so we don't get confused */
    act.sa_mask = allsigs;

    act.sa_handler = restart;       /* do a restart on SIGHUP */
    sigaction(SIGHUP, &act, NULL);

    act.sa_handler = toolong; /* handle an alarm call */
    sigaction(SIGALRM, &act, NULL);

    act.sa_handler = die;           /* bite the biscuit for all following */
    sigaction(SIGINT, &act, NULL);
    sigaction(SIGTERM, &act, NULL);

    start_tcl();

    FD_ZERO(&fdset);

    for (go = 1; go;)
    {
        unsigned int cmd;


        FD_SET(server_sock, &fdset);

        if (select(FD_SETSIZE, &fdset, NULL, NULL, NULL) == -1)
        {
            if (errno != EINTR)
                log_err(errno, id, "select");

            continue;
        }

        if (!FD_ISSET(server_sock, &fdset))
            continue;

        cmd = server_command();

        if (cmd == (unsigned)SCH_ERROR || cmd == (unsigned)SCH_SCHEDULE_NULL)
            continue;

        if (sigprocmask(SIG_BLOCK, &allsigs, &oldsigs) == -1)
            log_err(errno, id, "sigprocmaskSIG_BLOCK)");

        if (verbose)
        {
            sprintf(log_buffer, "command %d", cmd);
            log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER,
                       id, log_buffer);
        }

        switch (cmd)
        {

        case SCH_SCHEDULE_NEW:

        case SCH_SCHEDULE_TERM:

        case SCH_SCHEDULE_TIME:

        case SCH_SCHEDULE_RECYC:

        case SCH_SCHEDULE_CMD:

        case SCH_SCHEDULE_FIRST:
            alarm(alarm_time);

#if TCL_MAJOR_VERSION >= 8
            /* execute compiled body code for TCL-8 */
            code = Tcl_EvalObj(interp, body_obj);
#else
            code = Tcl_Eval(interp, body);
#endif
            alarm(0);

            switch (code)
            {

            case TCL_OK:

            case TCL_RETURN:
                break;

            default:
            {

                char *trace;
                char  codename[20];

                switch (code)
                {

                case TCL_BREAK:
                    strcpy(codename, "break");
                    break;

                case TCL_CONTINUE:
                    strcpy(codename, "continue");
                    break;

                default:
                    strcpy(codename, "<unknown>");
                    break;
                }

                trace = (char *)Tcl_GetVar(interp, "errorInfo", 0);

                if (trace == NULL)
                    trace = (char *)Tcl_GetStringResult(interp);

                fprintf(stderr, "%s: TCL interpreter return code %d (%s) @ line %d: %s\n",
                        bodyfil, code, codename,
                        interp->errorLine, trace);

                sprintf(log_buffer,
                        "%s: TCL error @ line %d: %s",
                        bodyfil, interp->errorLine,
                        Tcl_GetStringResult(interp));

                log_err(-1, id, log_buffer);

                die(0);
            }
            }

            break;

        case SCH_CONFIGURE:

        case SCH_RULESET:
            restart(0);
            break;

        case SCH_QUIT:
            go = 0;
            break;

        default:
            log_err(-1, id, "unknown command");
            break;
        }

        if (connector >= 0 && server_disconnect(connector))
        {
            log_err(errno, id, "server_disconnect");
            die(0);
        }

        connector = -1;

        if (verbose)
        {
            next_brk = (caddr_t)sbrk(0);

            if (next_brk > curr_brk)
            {
                sprintf(log_buffer, "brk point %p", next_brk);
                log_record(PBSEVENT_SYSTEM,
                           PBS_EVENTCLASS_SERVER,
                           id, log_buffer);
                curr_brk = next_brk;
            }
        }

        if (sigprocmask(SIG_SETMASK, &oldsigs, NULL) == -1)
            log_err(errno, id, "sigprocmask(SIG_SETMASK)");
    }

    if (termfil)
    {
        code = Tcl_EvalFile(interp, termfil);

        if (code != TCL_OK)
        {
            char *trace;

            trace = (char *)Tcl_GetVar(interp, "errorInfo", 0);

            if (trace == NULL)
                trace = (char *)Tcl_GetStringResult(interp);

            fprintf(stderr, "%s: TCL error @ line %d: %s\n",
                    termfil, interp->errorLine, trace);

            sprintf(log_buffer, "%s: TCL error @ line %d: %s",
                    termfil, interp->errorLine,
                    Tcl_GetStringResult(interp));

            log_err(-1, id, log_buffer);

            die(0);
        }

        sprintf(log_buffer, "term file: %s", termfil);

        log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER,
                   id, log_buffer);
    }

    sprintf(log_buffer, "%s normal finish pid %d", argv[0], pid);

    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

    (void)close(server_sock);
    exit(0);
}
Exemple #4
0
int openrm(

  char         *host,  /* I */
  unsigned int  port)  /* I (optional,0=DEFAULT) */

  {
  int                 stream;
  int                 rc;
  int                 retries = 0;

  static unsigned int gotport = 0;

  if (port == 0)
    {
    if (gotport == 0)
      {
      gotport = get_svrport((char *)PBS_MANAGER_SERVICE_NAME, (char *)"tcp",
                            PBS_MANAGER_SERVICE_PORT);
      }  /* END if (gotport == 0) */

    port = gotport;
    }

  if ((stream = socket(AF_INET, SOCK_STREAM, 0)) != -1)
    {

    struct sockaddr_in  addr;
    struct addrinfo    *addr_info;

    if (pbs_getaddrinfo(host, NULL, &addr_info) != 0)
      {
      DBPRT(("host %s not found\n", host))
      close(stream);

      return(ENOENT * -1);
      }

    memset(&addr, '\0', sizeof(addr));

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    while (retries++ < MAX_RETRIES)
      {
      rc = bindresvport(stream, &addr);
      if (rc != 0)
        {
        if (retries >= MAX_RETRIES)
          {
          close(stream);
          return(-1*errno);
          }
        sleep(1);
        }
      else
        break;
      }

    memset(&addr, '\0', sizeof(addr));

    addr.sin_addr = ((struct sockaddr_in *)addr_info->ai_addr)->sin_addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons((unsigned short)port);

    if (connect(stream, (struct sockaddr *)&addr, sizeof(addr)) == -1)
      {
      close(stream);

      return(-1 * errno);
      }
    }    /* END if ((stream = socket(AF_INET,SOCK_STREAM,0)) != -1) */

  if (stream < 0)
    {
    return(-1 * errno);
    }

  if (addrm(stream) == -1)
    {
    close(stream);

    return(-1 * errno);
    }

  return(stream);
  }  /* END openrm() */
Exemple #5
0
int main(

  int   argc,
  char *argv[])

  {
  char  *id = "main";

  struct hostent *hp;
  int  go, c, errflg = 0;
  int  lockfds;
  int  t = 1;
  pid_t  pid;
  char  host[100];
  char  *homedir = PBS_SERVER_HOME;
  unsigned int port;
  char  *dbfile = "sched_out";

  struct sigaction act;
  sigset_t oldsigs;
  caddr_t curr_brk = 0;
  caddr_t next_brk;
  extern char *optarg;
  extern int optind, opterr;
  extern int rpp_fd;
  fd_set fdset;

  int  schedinit(int argc, char **argv);
  int  schedule(int com, int connector);

  glob_argv = argv;
  alarm_time = 180;

  /* The following is code to reduce security risks                */
  /* move this to a place where nss_ldap doesn't hold a socket yet */

  c = sysconf(_SC_OPEN_MAX);

  while (--c > 2)
    (void)close(c); /* close any file desc left open by parent */

  port = get_svrport(PBS_SCHEDULER_SERVICE_NAME, "tcp",
                     PBS_SCHEDULER_SERVICE_PORT);

  pbs_rm_port = get_svrport(PBS_MANAGER_SERVICE_NAME, "tcp",
                            PBS_MANAGER_SERVICE_PORT);

  strcpy(pbs_current_user, "Scheduler");

  msg_daemonname = strdup("pbs_sched");

  opterr = 0;

  while ((c = getopt(argc, argv, "L:S:R:d:p:c:a:-:")) != EOF)
    {
    switch (c)
      {

      case '-':

        if ((optarg == NULL) || (optarg[0] == '\0'))
          {
          errflg = 1;
          }

        if (!strcmp(optarg, "version"))
          {
          fprintf(stderr, "version: %s\n", PACKAGE_VERSION);
          exit(0);
          }
        else
          {
          errflg = 1;
          }

        break;

      case 'L':
        logfile = optarg;
        break;

      case 'S':
        port = atoi(optarg);

        if (port == 0)
          {
          fprintf(stderr,
                  "%s: illegal port\n", optarg);
          errflg = 1;
          }

        break;

      case 'R':

        if ((pbs_rm_port = atoi(optarg)) == 0)
          {
          (void)fprintf(stderr, "%s: bad -R %s\n",
                        argv[0], optarg);
          return 1;
          }

        break;

      case 'd':
        homedir = optarg;
        break;

      case 'p':
        dbfile = optarg;
        break;

      case 'c':
        configfile = optarg;
        break;

      case 'a':
        alarm_time = atoi(optarg);

        if (alarm_time == 0)
          {
          fprintf(stderr,
                  "%s: bad alarm time\n", optarg);
          errflg = 1;
          }

        break;

      case '?':
        errflg = 1;
        break;
      }
    }

  if (errflg)
    {
    fprintf(stderr, "usage: %s %s\n", argv[0], usage);
    exit(1);
    }

#ifndef DEBUG
  if (IamRoot() == 0)
    {
        return (1);
    }
#endif        /* DEBUG */

  /* Save the original working directory for "restart" */
  if ((oldpath = getcwd((char *)NULL, MAXPATHLEN)) == NULL)
    {
    fprintf(stderr, "cannot get current working directory\n");
    exit(1);
    }

  (void)sprintf(log_buffer, "%s/sched_priv", homedir);
#if !defined(DEBUG) && !defined(NO_SECURITY_CHECK)
  c  = chk_file_sec(log_buffer, 1, 0, S_IWGRP | S_IWOTH, 1, NULL);
  c |= chk_file_sec(PBS_ENVIRON, 0, 0, S_IWGRP | S_IWOTH, 0, NULL);

  if (c != 0) exit(1);

#endif  /* not DEBUG and not NO_SECURITY_CHECK */
  if (chdir(log_buffer) == -1)
    {
    perror("chdir");
    exit(1);
    }

  (void)sprintf(path_log,   "%s/sched_logs", homedir);
  (void)sprintf(path_acct,   "%s/%s", log_buffer, PBS_ACCT);


  /* The following is code to reduce security risks                */
  /* start out with standard umask, system resource limit infinite */

  umask(022);

  if (setup_env(PBS_ENVIRON) == -1)
    exit(1);

  c = getgid();

  (void)setgroups(1, (gid_t *)&c); /* secure suppl. groups */

#ifndef DEBUG
#ifdef _CRAY
  (void)limit(C_JOB,      0, L_CPROC, 0);

  (void)limit(C_JOB,      0, L_CPU,   0);

  (void)limit(C_JOBPROCS, 0, L_CPU,   0);

  (void)limit(C_PROC,     0, L_FD,  255);

  (void)limit(C_JOB,      0, L_FSBLK, 0);

  (void)limit(C_JOBPROCS, 0, L_FSBLK, 0);

  (void)limit(C_JOB,      0, L_MEM  , 0);

  (void)limit(C_JOBPROCS, 0, L_MEM  , 0);

#else /* not  _CRAY */
    {

    struct rlimit rlimit;

    rlimit.rlim_cur = RLIM_INFINITY;
    rlimit.rlim_max = RLIM_INFINITY;
    (void)setrlimit(RLIMIT_CPU,   &rlimit);
    (void)setrlimit(RLIMIT_FSIZE, &rlimit);
    (void)setrlimit(RLIMIT_DATA,  &rlimit);
    (void)setrlimit(RLIMIT_STACK, &rlimit);
#ifdef  RLIMIT_RSS
    (void)setrlimit(RLIMIT_RSS  , &rlimit);
#endif  /* RLIMIT_RSS */
#ifdef  RLIMIT_VMEM
    (void)setrlimit(RLIMIT_VMEM  , &rlimit);
#endif  /* RLIMIT_VMEM */
    }
#endif /* not _CRAY */
#endif /* DEBUG */

  if (log_open(logfile, path_log) == -1)
    {
    fprintf(stderr, "%s: logfile could not be opened\n", argv[0]);
    exit(1);
    }

  if (gethostname(host, sizeof(host)) == -1)
    {
    log_err(errno, id, "gethostname");
    die(0);
    }

  if ((hp = gethostbyname(host)) == NULL)
    {
    log_err(errno, id, "gethostbyname");
    die(0);
    }

  if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
    log_err(errno, id, "socket");
    die(0);
    }

  if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR,
                 (char *)&t, sizeof(t)) == -1)
    {
    log_err(errno, id, "setsockopt");
    die(0);
    }

  saddr.sin_family = AF_INET;

  saddr.sin_port = htons(port);
  memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);

  if (bind(server_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
    log_err(errno, id, "bind");
    die(0);
    }

  if (listen(server_sock, 5) < 0)
    {
    log_err(errno, id, "listen");
    die(0);
    }

  okclients = (pbs_net_t *)calloc(START_CLIENTS, sizeof(pbs_net_t));

  addclient("localhost");   /* who has permission to call MOM */
  addclient(host);

  if (configfile)
    {
    if (read_config(configfile) != 0)
      die(0);
    }

  lockfds = open("sched.lock", O_CREAT | O_TRUNC | O_WRONLY, 0644);

  if (lockfds < 0)
    {
    log_err(errno, id, "open lock file");
    exit(1);
    }

  lock_out(lockfds, F_WRLCK);

  fullresp(0);

  if (sigemptyset(&allsigs) == -1)
    {
    perror("sigemptyset");
    exit(1);
    }

  if (sigprocmask(SIG_SETMASK, &allsigs, NULL) == -1)   /* unblock */
    {
    perror("sigprocmask");
    exit(1);
    }

  act.sa_flags = 0;

  sigaddset(&allsigs, SIGHUP);    /* remember to block these */
  sigaddset(&allsigs, SIGINT);    /* during critical sections */
  sigaddset(&allsigs, SIGTERM);   /* so we don't get confused */
  act.sa_mask = allsigs;

  act.sa_handler = restart;       /* do a restart on SIGHUP */
  sigaction(SIGHUP, &act, NULL);

  act.sa_handler = toolong; /* handle an alarm call */
  sigaction(SIGALRM, &act, NULL);

  act.sa_handler = die;           /* bite the biscuit for all following */
  sigaction(SIGINT, &act, NULL);
  sigaction(SIGTERM, &act, NULL);

  /*
   * Catch these signals to ensure we core dump even if
   * our rlimit for core dumps is set to 0 initially.
   *
   * Chris Samuel - VPAC
   * [email protected] - 29th July 2003
   *
   * Now conditional on the PBSCOREDUMP environment variable
   */

  if (getenv("PBSCOREDUMP"))
    {
    act.sa_handler = catch_abort;   /* make sure we core dump */

    sigaction(SIGSEGV, &act, NULL);
    sigaction(SIGBUS, &act, NULL);
    sigaction(SIGFPE, &act, NULL);
    sigaction(SIGILL, &act, NULL);
    sigaction(SIGTRAP, &act, NULL);
    sigaction(SIGSYS, &act, NULL);
    }

  /*
   *  Local initialization stuff
   */

  if (schedinit(argc, argv))
    {
    (void) sprintf(log_buffer,
                   "local initialization failed, terminating");
    log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);
    exit(1);
    }

  if (getenv("PBSDEBUG") == NULL)
    {
    lock_out(lockfds, F_UNLCK);

#ifdef DISABLE_DAEMONS
    pid = getpid();
#else
    if ((pid = fork()) == -1)
      {
      /* error on fork */
      perror("fork");

      exit(1);
      }
    else
    if (pid > 0)               /* parent exits */
      {
      exit(0);
      }

    if ((pid = setsid()) == -1)
      {
      perror("setsid");

      exit(1);
      }
#endif  /*  DISABLE_DAEMONS  */

    lock_out(lockfds, F_WRLCK);

    if (freopen(dbfile, "a", stdout) == NULL)
      {
      perror("opening lockfile");

      exit(1);
      }


    setvbuf(stdout, NULL, _IOLBF, 0);

    dup2(fileno(stdout), fileno(stderr));
    }
  else
    {
    setvbuf(stdout, NULL, _IOLBF, 0);
    setvbuf(stderr, NULL, _IOLBF, 0);

    pid = getpid();
    }

  if (freopen("/dev/null", "r", stdin) == NULL)
    {
    perror("opening /dev/null");

    exit(1);
    }

  /* write scheduler's pid into lockfile */

  (void)sprintf(log_buffer, "%ld\n", (long)pid);

  if (write(lockfds, log_buffer, strlen(log_buffer) + 1) != (ssize_t)(strlen(log_buffer) + 1))
    {
    perror("writing to lockfile");

    exit(1);
    }

#if (PLOCK_DAEMONS & 2)
  (void)plock(PROCLOCK); /* lock daemon into memory */

#endif

  sprintf(log_buffer, "%s startup pid %ld", argv[0], (long)pid);

  log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

  FD_ZERO(&fdset);

  for (go = 1;go;)
    {
    int cmd;

    if (rpp_fd != -1)
      FD_SET(rpp_fd, &fdset);

    FD_SET(server_sock, &fdset);

    if (select(FD_SETSIZE, &fdset, NULL, NULL, NULL) == -1)
      {
      if (errno != EINTR)
        {
        log_err(errno, id, "select");
        die(0);
        }

      continue;
      }

    if (rpp_fd != -1 && FD_ISSET(rpp_fd, &fdset))
      {
      if (rpp_io() == -1)
        log_err(errno, id, "rpp_io");
      }

    if (!FD_ISSET(server_sock, &fdset))
      continue;

    cmd = server_command();

    if (sigprocmask(SIG_BLOCK, &allsigs, &oldsigs) == -1)
      log_err(errno, id, "sigprocmaskSIG_BLOCK)");

    alarm(alarm_time);

    if (schedule(cmd, connector)) /* magic happens here */
      go = 0;

    alarm(0);

    if (connector >= 0 && server_disconnect(connector))
      {
      log_err(errno, id, "server_disconnect");
      die(0);
      }

    next_brk = (caddr_t)sbrk(0);

    if (next_brk > curr_brk)
      {
      sprintf(log_buffer, "brk point %ld", (long)next_brk);
      log_record(PBSEVENT_DEBUG, PBS_EVENTCLASS_SERVER,
                 id, log_buffer);
      curr_brk = next_brk;
      }

    if (sigprocmask(SIG_SETMASK, &oldsigs, NULL) == -1)
      log_err(errno, id, "sigprocmask(SIG_SETMASK)");
    }

  sprintf(log_buffer, "%s normal finish pid %ld",

          argv[0],
          (long)pid);

  log_record(PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, id, log_buffer);

  close(server_sock);

  exit(0);
  }  /* END main() */