static void RescanServers (void) { Debug ("rescanning servers\n"); LogInfo ("Rescanning both config and servers files\n"); ForEachDisplay (MarkDisplay); SetConfigFileTime (); ReinitResources (); LoadDMResources (); ScanServers (); StartDisplays (); }
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(); }
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*/}
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(); }
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; }
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 (); }
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*/ }