예제 #1
0
static void
RescanServers (void)
{
    Debug ("rescanning servers\n");
    LogInfo ("Rescanning both config and servers files\n");
    ForEachDisplay (MarkDisplay);
    SetConfigFileTime ();
    ReinitResources ();
    LoadDMResources ();
    ScanServers ();
    StartDisplays ();
}
예제 #2
0
파일: dm.c 프로젝트: bbidulock/wdm
static void RescanServers(void)
{
	WDMDebug("rescanning servers\n");
	WDMInfo("Rescanning both config and servers files\n");
	ForEachDisplay(MarkDisplay);
	SetConfigFileTime();
	ReinitResources();
	LoadDMResources();
	ScanServers();
	SetAccessFileTime();
#ifdef XDMCP
	ScanAccessDatabase();
#endif
	StartDisplays();
}
예제 #3
0
파일: dm.c 프로젝트: bbidulock/wdm
int main(int argc, char **argv)
{
	int oldpid, oldumask;
	char cmdbuf[1024];
	int debugMode = 0;

	/* make sure at least world write access is disabled */
	if (((oldumask = umask(022)) & 002) == 002)
		(void)umask(oldumask);
#ifndef NOXDMTITLE
	Title = argv[0];
	TitleLen = (argv[argc - 1] + strlen(argv[argc - 1])) - Title;
#endif

	/*
	 * Step 1 - load configuration parameters
	 */
	InitResources(argc, argv);
	SetConfigFileTime();
	LoadDMResources();
	/*
	 * Only allow root to run in non-debug mode to avoid problems
	 */
	debugMode = (debugLevel.i > WDM_LEVEL_WARNING);
	if (!debugMode && getuid() != 0) {
		fprintf(stderr, "Only root wants to run %s\n", argv[0]);
		exit(1);
	}
	if (!debugMode && daemonMode.i) {
		BecomeOrphan();
		BecomeDaemon();
	}
	/* SUPPRESS 560 */
	if ((oldpid = StorePid())) {
		if (oldpid == -1)
			WDMError("Can't create/lock pid file %s\n", pidFile);
		else
			WDMError("Can't lock pid file %s, another wdm is running " "(pid %d)\n", pidFile, oldpid);
		exit(1);
	}
	WDMLogLevel(debugLevel.i);
	if (useSyslog.i) {
		WDMUseSysLog("wdm", WDMStringToFacility(syslogFacility));
	} else if (errorLogFile && *errorLogFile) {
		int f;
		if ((f = open(errorLogFile, O_CREAT | O_WRONLY | O_APPEND, 0600)) == -1)
			WDMError("cannot open errorLogFile %s\n", errorLogFile);
		else
			WDMLogStream(fdopen(f, "w"));
	}
	/* redirect any messages for stderr into standard logging functions. */
	WDMRedirectStderr(WDM_LEVEL_ERROR);

	/* Clean up any old Authorization files */
	sprintf(cmdbuf, "/bin/rm -f %s/authdir/authfiles/A*", authDir);
	system(cmdbuf);

#ifdef XDMCP
	init_session_id();
	CreateWellKnownSockets();
#else
	WDMDebug("wdm: not compiled for XDMCP\n");
#endif
	parent_pid = getpid();
	(void)Signal(SIGTERM, StopAll);
	(void)Signal(SIGINT, StopAll);
	/*
	 * Step 2 - Read /etc/Xservers and set up
	 *      the socket.
	 *
	 *      Keep a sub-daemon running
	 *      for each entry
	 */
	SetAccessFileTime();
#ifdef XDMCP
	ScanAccessDatabase();
#endif
	ScanServers();
	StartDisplays();
	(void)Signal(SIGHUP, RescanNotify);
	(void)Signal(SIGCHLD, ChildNotify);
	while (
#ifdef XDMCP
			  AnyWellKnownSockets() ||
#endif
			  AnyDisplaysLeft()) {
		if (Rescan) {
			RescanServers();
			Rescan = 0;
		}
		WaitForSomething();
	}
	WDMDebug("Nothing left to do, exiting\n");
	exit(0);
 /*NOTREACHED*/}
예제 #4
0
파일: dm.c 프로젝트: bbidulock/wdm
void WaitForChild(void)
{
	int pid;
	struct display *d;
	waitType status;
	sigset_t mask, omask;

	sigemptyset(&mask);
	sigaddset(&mask, SIGCHLD);
	sigaddset(&mask, SIGHUP);
	sigprocmask(SIG_BLOCK, &mask, &omask);
	WDMDebug("signals blocked\n");
	if (!ChildReady && !Rescan)
		sigsuspend(&omask);
	ChildReady = 0;
	sigprocmask(SIG_SETMASK, &omask, (sigset_t *) NULL);
	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
	{
		WDMDebug("Manager wait returns pid: %d sig %d core %d code %d\n", pid, waitSig(status), waitCore(status), waitCode(status));
		if (autoRescan.i)
			RescanIfMod();
		/* SUPPRESS 560 */
		if ((d = FindDisplayByPid(pid))) {
			d->pid = -1;
			switch (waitVal(status)) {
			case UNMANAGE_DISPLAY:
				WDMDebug("Display exited with UNMANAGE_DISPLAY\n");
				StopDisplay(d);
				break;
			case OBEYSESS_DISPLAY:
				d->startTries = 0;
				WDMDebug("Display exited with OBEYSESS_DISPLAY\n");
				if (d->displayType.lifetime != Permanent || d->status == zombie)
					StopDisplay(d);
				else
					RestartDisplay(d, FALSE);
				break;
			default:
				WDMDebug("Display exited with unknown status %d\n", waitVal(status));
				WDMError("Unknown session exit code %d from process %d\n", waitVal(status), pid);
				StopDisplay(d);
				break;
			case OPENFAILED_DISPLAY:
				WDMDebug("Display exited with OPENFAILED_DISPLAY, try %d of %d\n", d->startTries, d->startAttempts);
				WDMError("Display %s cannot be opened\n", d->name);
				/*
				 * no display connection was ever made, tell the
				 * terminal that the open attempt failed
				 */
#ifdef XDMCP
				if (d->displayType.origin == FromXDMCP)
					SendFailed(d, "Cannot open display");
#endif
				if (d->displayType.origin == FromXDMCP || d->status == zombie || ++d->startTries >= d->startAttempts) {
					WDMError("Display %s is being disabled\n", d->name);
					StopDisplay(d);
				} else {
					RestartDisplay(d, TRUE);
				}
				break;
			case RESERVER_DISPLAY:
				d->startTries = 0;
				WDMDebug("Display exited with RESERVER_DISPLAY\n");
				if (d->displayType.origin == FromXDMCP || d->status == zombie)
					StopDisplay(d);
				else
					RestartDisplay(d, TRUE);
				{
					Time_t Time;
					time(&Time);
					WDMDebug("time %i %i\n", (int)Time, (int)d->lastCrash);
					if (d->lastCrash && ((Time - d->lastCrash) < XDM_BROKEN_INTERVAL)) {
						WDMDebug("Server crash frequency too high:" " removing display %s\n", d->name);
						WDMError("Server crash rate too high:" " removing display %s\n", d->name);
						RemoveDisplay(d);
					} else
						d->lastCrash = Time;
				}
				break;
			case waitCompose(SIGTERM, 0, 0):
				WDMDebug("Display exited on SIGTERM, try %d of %d\n", d->startTries, d->startAttempts);
				if (d->displayType.origin == FromXDMCP || d->status == zombie || ++d->startTries >= d->startAttempts) {
					WDMError("Display %s is being disabled\n", d->name);
					StopDisplay(d);
				} else
					RestartDisplay(d, TRUE);
				break;
			case REMANAGE_DISPLAY:
				d->startTries = 0;
				WDMDebug("Display exited with REMANAGE_DISPLAY\n");
				/*
				 * XDMCP will restart the session if the display
				 * requests it
				 */
				if (d->displayType.origin == FromXDMCP || d->status == zombie)
					StopDisplay(d);
				else
					RestartDisplay(d, FALSE);
				break;
			}
		}
		/* SUPPRESS 560 */
		else if ((d = FindDisplayByServerPid(pid))) {
			d->serverPid = -1;
			switch (d->status) {
			case zombie:
				WDMDebug("Zombie server reaped, removing display %s\n", d->name);
				RemoveDisplay(d);
				break;
			case phoenix:
				WDMDebug("Phoenix server arises, restarting display %s\n", d->name);
				d->status = notRunning;
				break;
			case running:
				WDMDebug("Server for display %s terminated unexpectedly, status %d %d\n", d->name, waitVal(status), status);
				WDMError("Server for display %s terminated unexpectedly: %d\n", d->name, waitVal(status));
				d->status = notRunning;
				if (d->pid != -1) {
					WDMDebug("Terminating session pid %d\n", d->pid);
					TerminateProcess(d->pid, SIGTERM);
				}
				break;
			case notRunning:
				WDMDebug("Server exited for notRunning session on display %s\n", d->name);
				break;
			}
		} else {
			WDMDebug("Unknown child termination, status %d\n", waitVal(status));
		}
	}
	StartDisplays();
}
예제 #5
0
int
main (int argc, char **argv)
{
    mode_t oldumask;
    char cmdbuf[1024];

    /* make sure at least world write access is disabled */
    if (((oldumask = umask(022)) & 002) == 002)
	(void) umask (oldumask);

    /*
     * Step 1 - load configuration parameters
     */
    InitResources (argc, argv);
    SetConfigFileTime ();
    LoadDMResources ();
    /*
     * Only allow root to run in non-debug mode to avoid problems
     */
    if (debugLevel == 0 && getuid() != 0)
    {
	fprintf (stderr, "Only root wants to run %s\n", argv[0]);
	exit (1);
    }
    if (debugLevel == 0 && daemonMode) {
      if (daemon (0, 0) < 0) {
	/* error */
	LogError("daemon() failed, %s\n", _SysErrorMsg (errno));
	exit(1);
      }
    }
    if (debugLevel == 0)
	InitErrorLog ();
    if (debugLevel >= 10)
	nofork_session = 1;
    LogInfo ("Starting\n");

    if (nofork_session == 0) {
	/* Clean up any old Authorization files */
	/* AUD: all good? */
	snprintf(cmdbuf, sizeof(cmdbuf), "/bin/rm -f %s/authdir/authfiles/A*", authDir);
	system(cmdbuf);
    }
    parent_pid = getpid ();
    (void) signal (SIGTERM, StopAll);
    (void) signal (SIGINT, StopAll);
    /*
     * Step 2 - Read Xservers and set up
     *	    the socket.
     *
     *	    Keep a sub-daemon running
     *	    for each entry
     */
    ScanServers ();
    StartDisplays ();
    (void) signal (SIGHUP, RescanNotify);
    (void) signal (SIGCHLD, ChildNotify);
    Debug ("startup successful; entering main loop\n");
    while (AnyDisplaysLeft ())
    {
	if (Rescan)
	{
	    RescanServers ();
	    Rescan = 0;
	}
	WaitForChild ();
    }
    Debug ("Nothing left to do, exiting\n");
    LogInfo ("Exiting\n");
    return 0;
}
예제 #6
0
void
WaitForChild (void)
{
    pid_t		pid;
    struct display	*d;
    waitType	status;
    sigset_t mask, omask;

    sigemptyset(&mask);
    sigaddset(&mask, SIGCHLD);
    sigaddset(&mask, SIGHUP);
    sigprocmask(SIG_BLOCK, &mask, &omask);
    Debug ("signals blocked\n");
    if (!ChildReady && !Rescan)
	sigsuspend(&omask);
    ChildReady = 0;
    sigprocmask(SIG_SETMASK, &omask, (sigset_t *)NULL);
    while ((pid = waitpid (-1, &status, WNOHANG)) > 0)
    {
	Debug ("Manager wait returns pid: %d sig %d core %d code %d\n",
	       pid, waitSig(status), waitCore(status), waitCode(status));
	if (autoRescan)
	    RescanIfMod ();
	/* SUPPRESS 560 */
	if ((d = FindDisplayByPid (pid))) {
	    d->pid = -1;
	    switch (waitVal (status)) {
	    case UNMANAGE_DISPLAY:
		Debug ("Display exited with UNMANAGE_DISPLAY\n");
		StopDisplay (d);
		break;
	    case OBEYSESS_DISPLAY:
		d->startTries = 0;
		d->reservTries = 0;
		Debug ("Display exited with OBEYSESS_DISPLAY\n");
		if (d->status == zombie)
		    StopDisplay (d);
		else
		    RestartDisplay (d, FALSE);
		break;
	    case OPENFAILED_DISPLAY:
		Debug ("Display exited with OPENFAILED_DISPLAY, try %d of %d\n",
		       d->startTries, d->startAttempts);
		LogError ("Display %s cannot be opened\n", d->name);
		/*
		 * no display connection was ever made, tell the
		 * terminal that the open attempt failed
		 */
		if (d->status == zombie ||
		    ++d->startTries >= d->startAttempts)
		{
		    LogError ("Display %s is being disabled\n", d->name);
		    StopDisplay (d);
		}
		else
		{
		    RestartDisplay (d, TRUE);
		}
		break;
	    case RESERVER_DISPLAY:
		d->startTries = 0;
		Debug ("Display exited with RESERVER_DISPLAY\n");
		if (d->status == zombie)
		    StopDisplay(d);
		else {
		  Time_t now;
		  int crash;

		  time(&now);
		  crash = d->lastReserv &&
		    ((now - d->lastReserv) < XDM_BROKEN_INTERVAL);
		  Debug("time %lli %lli try %i of %i%s\n", 
			(long long)now, (long long)d->lastReserv,
			d->reservTries, d->reservAttempts,
			crash ? " crash" : "");

		  if (!crash)
		    d->reservTries = 0;

		  if (crash && ++d->reservTries >= d->reservAttempts) {
		    const char *msg =
			"Server crash frequency too high: stopping display";
		    Debug("%s %s\n", msg, d->name);
		    LogError("%s %s\n", msg, d->name);
		    /* For a local X server either:
		     * 1. The server exit was returned by waitpid().  So
		     *    serverPid==-1 => StopDisplay() calls RemoveDisplay()
		     *
		     * 2. The server is in zombie state or still running.  So
		     *    serverPid>1 => StopDisplay()
		     *                   a. sets status=zombie,
		     *                   b. kills the server.
		     *    The next waitpid() returns this zombie server pid
		     *    and the 'case zombie:' below then calls
		     *    RemoveDisplay().
		     */
		    StopDisplay(d);
		  } else {
		    RestartDisplay(d, TRUE);
		  }
		  d->lastReserv = now;
		}
		break;
	    case waitCompose (SIGTERM,0,0):
		Debug ("Display exited on SIGTERM, try %d of %d\n",
			d->startTries, d->startAttempts);
		if (d->status == zombie ||
		    ++d->startTries >= d->startAttempts)
		{
		    /*
		     * During normal xdm shutdown, killed local X servers
		     * can be zombies; this is not an error.
		     */
		    if (d->status == zombie &&
			(d->startTries < d->startAttempts))
			LogInfo ("display %s is being disabled\n", d->name);
		    else
			LogError ("display %s is being disabled\n", d->name);
		    StopDisplay(d);
		} else
		    RestartDisplay (d, TRUE);
		break;
	    case REMANAGE_DISPLAY:
		d->startTries = 0;
		Debug ("Display exited with REMANAGE_DISPLAY\n");
		/*
		 * XDMCP will restart the session if the display
		 * requests it
		 */
		if (d->status == zombie)
		    StopDisplay(d);
		else
		    RestartDisplay (d, FALSE);
		break;
	    default:
		Debug ("Display exited with unknown status %d\n", waitVal(status));
		LogError ("Unknown session exit code %d from process %d\n",
			  waitVal (status), pid);
		StopDisplay (d);
		break;
	    }
	}
	/* SUPPRESS 560 */
	else if ((d = FindDisplayByServerPid (pid)))
	{
	    d->serverPid = -1;
	    switch (d->status)
	    {
	    case zombie:
		Debug ("Zombie server reaped, removing display %s\n", d->name);
		RemoveDisplay (d);
		break;
	    case phoenix:
		Debug ("Phoenix server arises, restarting display %s\n", d->name);
		d->status = notRunning;
		break;
	    case running:
		Debug ("Server for display %s terminated unexpectedly, status %d %d\n", d->name, waitVal (status), status);
		LogError ("Server for display %s terminated unexpectedly: %d\n", d->name, waitVal (status));
		if (d->pid != -1)
		{
		    Debug ("Terminating session pid %d\n", d->pid);
		    kill (d->pid, SIGTERM);
		}
		break;
	    case notRunning:
		Debug ("Server exited for notRunning session on display %s\n", d->name);
		break;
	    }
	}
	else
	{
	    Debug ("Unknown child termination, status %d\n", waitVal (status));
	}
    }
    StartDisplays ();
}
예제 #7
0
int
main (int argc, char **argv)
{
    int	oldpid;
    mode_t oldumask;
    char cmdbuf[1024];

    /* make sure at least world write access is disabled */
    if (((oldumask = umask(022)) & 002) == 002)
	(void) umask (oldumask);
#ifndef NOXDMTITLE
    Title = argv[0];
    TitleLen = (argv[argc - 1] + strlen(argv[argc - 1])) - Title;
#endif

#ifdef USESECUREWARE
    set_auth_parameters (argc, argv);
#endif

    /*
     * Step 1 - load configuration parameters
     */
    InitResources (argc, argv);
    SetConfigFileTime ();
    LoadDMResources ();
    /*
     * Only allow root to run in non-debug mode to avoid problems
     */
    if (debugLevel == 0 && getuid() != 0)
    {
	fprintf (stderr, "Only root wants to run %s\n", argv[0]);
	exit (1);
    }
    if (debugLevel == 0 && daemonMode)
	BecomeDaemon ();
    if (debugLevel == 0)
	InitErrorLog ();
    if (debugLevel >= 10)
	nofork_session = 1;
    /* SUPPRESS 560 */
    if ((oldpid = StorePid ()))
    {
	if (oldpid == -1)
	    LogError ("Can't create/lock pid file %s\n", pidFile);
	else
	    LogError ("Can't lock pid file %s, another xdm is running (pid %d)\n",
		 pidFile, oldpid);
	exit (1);
    }

    LogInfo ("Starting\n");

    if (atexit (RemovePid))
	LogError ("could not register RemovePid() with atexit()\n");

    if (nofork_session == 0) {
	/* Clean up any old Authorization files */
	/* AUD: all good? */
	snprintf(cmdbuf, sizeof(cmdbuf), "/bin/rm -f %s/authdir/authfiles/A*", authDir);
	system(cmdbuf);
    }
#if!defined(HAVE_ARC4RANDOM) && !defined(DEV_RANDOM)
    AddOtherEntropy ();
#endif
#ifdef XDMCP
    init_session_id ();
    CreateWellKnownSockets ();
#else
    Debug ("xdm: not compiled for XDMCP\n");
#endif
    parent_pid = getpid ();
    (void) Signal (SIGTERM, StopAll);
    (void) Signal (SIGINT, StopAll);
    /*
     * Step 2 - Read /etc/Xservers and set up
     *	    the socket.
     *
     *	    Keep a sub-daemon running
     *	    for each entry
     */
    SetAccessFileTime ();
#ifdef XDMCP
    ScanAccessDatabase ();
    UpdateListenSockets ();
#endif
    ScanServers ();
    StartDisplays ();
#if !defined(HAVE_ARC4RANDOM) && !defined(DEV_RANDOM)
    AddOtherEntropy();
#endif
    (void) Signal (SIGHUP, RescanNotify);
#ifndef UNRELIABLE_SIGNALS
    (void) Signal (SIGCHLD, ChildNotify);
#endif
    Debug ("startup successful; entering main loop\n");
    while (
#ifdef XDMCP
	   AnyWellKnownSockets() ||
#endif
	   AnyDisplaysLeft ())
    {
	if (Rescan)
	{
	    RescanServers ();
	    Rescan = 0;
	}
#if defined(UNRELIABLE_SIGNALS) || !defined(XDMCP)
	WaitForChild ();
#else
	WaitForSomething ();
#endif
    }
    Debug ("Nothing left to do, exiting\n");
    LogInfo ("Exiting\n");
    exit(0);
    /*NOTREACHED*/
}