123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* (c) Copyright 1997 The Open Group */
- /* *
- * (c) Copyright 1993, 1994 Hewlett-Packard Company *
- * (c) Copyright 1993, 1994 International Business Machines Corp. *
- * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
- * (c) Copyright 1993, 1994 Novell, Inc. *
- */
- /*
- * xdm - display manager daemon
- *
- * $TOG: dm.c /main/18 1999/01/19 17:44:08 mgreess $
- *
- * Copyright 1988 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. M.I.T. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * Author: Keith Packard, MIT X Consortium
- */
- /*
- * display manager
- */
- # include <sys/types.h>
- # include <sys/signal.h>
- # include <sys/stat.h>
- #if defined(__FreeBSD__) && OSMAJORVERSION > 8
- # include <utmpx.h>
- #else
- # include <utmp.h>
- #endif
- # include <time.h>
- # include <utime.h>
- # include <pwd.h>
- #if defined(__linux__) || defined(CSRG_BASED) || defined(sun)
- # include <stdarg.h>
- #else
- # include <varargs.h>
- #endif
- #if defined (SYSV) || defined (SVR4)
- #ifndef F_TLOCK
- # include <unistd.h>
- #endif
- #endif
- # include "dm.h"
- # include "vgmsg.h"
- #ifdef sun
- #include <sys/kbio.h>
- #include <sys/kbd.h>
- #endif
- #ifndef sigmask
- #define sigmask(m) (1 << (( m-1)))
- #endif
- /***************************************************************************
- *
- * Local procedure declarations
- *
- ***************************************************************************/
- static void CheckDisplayStatus( struct display *d) ;
- static void CheckRestartTime( void ) ;
- static void ChildNotify( int arg ) ;
- static void MarkDisplay( struct display *d) ;
- static void KillDisplay( struct display *d) ;
- static void MarkShutdownTime( void ) ;
- static void ProcessChildDeath( int pid, waitType status) ;
- static void RescanIfMod( void ) ;
- static void RescanNotify( int arg ) ;
- static void RescanServers( void ) ;
- static void RestartDisplay( struct display *d, int forceReserver) ;
- static int ScanServers( void ) ;
- static void SetAccessFileTime( void ) ;
- static void SetConfigFileTime( void ) ;
- static int StartGetty( struct display *d) ;
- static void StopAll( int arg ) ;
- static long StorePid( void ) ;
- static void TerminateProcess( int pid, int sig) ;
- static void UnlockPidFile( void ) ;
- static void dtMakeDefaultDir( void );
- static void dtmkdir(char *dir, mode_t dir_mode, int force);
- /***************************************************************************
- *
- * Global variables
- *
- ***************************************************************************/
- struct passwd puser; /* pseudo-user password entry */
- int Rescan;
- static long ServersModTime, ConfigModTime, AccessFileModTime;
- int wakeupTime = -1;
- char *progName;
- char DisplayName[32]="main";
- #ifdef OSFDEBUG
- int nofork_session = 0;
- #endif
- #ifndef NOXDMTITLE
- char *Title; /* Global argv[0] */
- int TitleLen;
- #endif
- static int parent_pid = -1; /* PID of parent dtlogin process */
- /***************************************************************************/
- int
- main( int argc, char **argv )
- {
- long oldpid;
- mode_t oldumask;
- struct passwd *p; /* pointer to passwd structure (pwd.h) */
-
- /*
- * 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
-
- /*
- * save program name and path...
- */
-
- if ( (progName = malloc(strlen(argv[0]) + 1)) != NULL )
- strcpy(progName, argv[0]);
-
- /*
- * Step 1 - load configuration parameters
- */
- InitResources (argc, argv);
- SetConfigFileTime ();
- LoadDMResources ();
- /*
- * Only allow root to run xdm to avoid problems (HP 700/X version)
- */
- if (debugLevel == 0 && getuid() != 0)
- {
- fprintf(stderr,
- (char *)ReadCatalog(MC_ERROR_SET,MC_BAD_ROOT,MC_DEF_BAD_ROOT),
- argv[0]);
- exit (1);
- }
- dtMakeDefaultDir(); /** Create /var/dt if needed **/
- CheckErrorFile(); /** verify that we can open an error log **/
- #ifdef OSFDEBUG
- if (debugLevel >= 10)
- nofork_session = 1;
- #endif
- if (debugLevel == 0 && daemonMode)
- BecomeDaemon ();
- if ( (oldpid = StorePid ()) != 0 )
- {
- if (oldpid == (long) -1)
- LogError(
- ReadCatalog(MC_LOG_SET,MC_LOG_NO_CREATE,MC_DEF_LOG_NO_CREATE),
- pidFile);
- else
- LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_LOCK,MC_DEF_LOG_NO_LOCK),
- pidFile, oldpid);
- exit (1);
- }
- /*
- * Check if we are restarting too fast...
- */
-
- CheckRestartTime();
- /*
- * Initialize error file, open XDMCP socket, and set up interrupt handlers.
- */
-
- InitErrorLog ();
- init_session_id ();
- CreateWellKnownSockets ();
- parent_pid = getpid(); /* PID of parent dtlogin process */
- (void) signal (SIGTERM, StopAll);
- (void) signal (SIGINT, StopAll);
- /*
- * Set pseudo-user to "nobody". Xserver will be run as that pseudo-user
- * rather than root (unless pseudo user is specifically set to another
- * user via the Xservers file).
- */
-
- if ( (p = getpwnam ("nobody")) != NULL) {
- puser = *p;
- } else {
- /*
- * This should not happen, the "nobody" user should always be present.
- * If it does, fall back to traditional values of the "root" user
- */
- puser.pw_uid = 0;
- puser.pw_gid = 1;
- }
- #ifdef __PASSWD_ETC
- /*
- * Ensure the interrupt handlers are set. The Passwd Etc. libraries
- * (getpwnam()) disable SIGTERM and SIGINT.
- */
-
- (void) signal (SIGTERM, StopAll);
- (void) signal (SIGINT, StopAll);
- #endif
- /*
- * Step 2 - Read /etc/Xservers and set up
- * the socket.
- *
- * Keep a sub-daemon running
- * for each entry
- */
- SetAccessFileTime ();
- ScanAccessDatabase ();
- #if !defined (ENABLE_DYNAMIC_LANGLIST)
- MakeLangList();
- #endif /* ENABLE_DYNAMIC_LANGLIST */
- ScanServers ();
- StartDisplays ();
- (void) signal (SIGHUP, RescanNotify);
- #if !defined(SYSV) || defined(hpux) || defined(_AIX) || defined(__linux__)
- (void) signal (SIGCHLD, ChildNotify);
- #endif
- while (AnyWellKnownSockets() || AnyDisplaysLeft ())
- {
- if (Rescan)
- {
- RescanServers ();
- Rescan = 0;
- }
- TrimErrorFile();
- #if defined(SYSV) && !defined(hpux) && !defined(_AIX) && !defined(__linux__)
- WaitForChild ();
- #else
- WaitForSomething ();
- #endif
- }
- UnlockPidFile();
- MarkShutdownTime();
- Debug ("Nothing left to do, exiting\n");
- }
- static SIGVAL
- RescanNotify( int arg )
- {
- Debug ("Caught SIGHUP\n");
- Rescan = 1;
- #if defined(SYSV) || defined(SVR4)
- signal (SIGHUP, RescanNotify);
- #endif
- }
- static int
- ScanServers( void )
- {
- char lineBuf[10240];
- int len;
- FILE *serversFile;
- struct stat statb;
- static DisplayType acceptableTypes[] =
- { { Local, Permanent, FromFile },
- { Foreign, Permanent, FromFile },
- };
- #define NumTypes (sizeof (acceptableTypes) / sizeof (acceptableTypes[0]))
- if (servers[0] == '/')
- {
- serversFile = fopen (servers, "r");
- if (serversFile == NULL)
- {
- LogError(
- ReadCatalog(MC_LOG_SET,MC_LOG_NO_SRVACC,MC_DEF_LOG_NO_SRVACC),
- servers);
- return 0;
- }
- if (ServersModTime == 0)
- {
- fstat (fileno (serversFile), &statb);
- ServersModTime = statb.st_mtime;
- }
- while (fgets (lineBuf, sizeof (lineBuf)-1, serversFile))
- {
- len = strlen (lineBuf);
- if (lineBuf[len-1] == '\n')
- lineBuf[len-1] = '\0';
- ParseDisplay (lineBuf, acceptableTypes, NumTypes, &puser);
- }
- fclose (serversFile);
- }
- else
- {
- ParseDisplay (servers, acceptableTypes, NumTypes, &puser);
- }
- return 1;
- }
- static void
- MarkDisplay( struct display *d )
- {
- d->state = MissingEntry;
- }
- static void
- KillDisplay( struct display *d )
- {
- if (d->name)
- Debug("Sending HUP to display %s\n", d->name);
- else
- Debug("Sending HUP to display ?\n");
- kill(d->pid, SIGHUP);
- }
- static void
- RescanServers( void )
- {
- Debug ("Rescanning servers\n");
- LogInfo (ReadCatalog(MC_ERROR_SET,MC_LOG_REBUILD,MC_DEF_LOG_REBUILD),
- DEF_NLS_DIR);
- #if !defined (ENABLE_DYNAMIC_LANGLIST)
- MakeLangList();
- #endif /* ENABLE_DYNAMIC_LANGLIST */
- LogInfo (ReadCatalog(MC_ERROR_SET,MC_LOG_RESCAN,MC_DEF_LOG_RESCAN));
- ForEachDisplay (MarkDisplay);
- ForEachDisplay (KillDisplay);
- ReinitResources ();
- LoadDMResources ();
- ScanServers ();
- SetAccessFileTime ();
- ScanAccessDatabase ();
- StartDisplays ();
- }
- static void
- SetConfigFileTime( void )
- {
- struct stat statb;
- if (stat (config, &statb) != -1)
- ConfigModTime = statb.st_mtime;
- }
- static void
- SetAccessFileTime( void )
- {
- struct stat statb;
- if (stat (accessFile, &statb) != -1)
- AccessFileModTime = statb.st_mtime;
- }
- static void
- RescanIfMod( void )
- {
- struct stat statb;
- if (stat (config, &statb) != -1)
- {
- if (statb.st_mtime != ConfigModTime)
- {
- Debug ("Config file %s has changed, rereading\n", config);
- LogInfo(
- ReadCatalog(MC_ERROR_SET,MC_LOG_REREADCFG,MC_DEF_LOG_REREADCFG),
- config);
- ConfigModTime = statb.st_mtime;
- ReinitResources ();
- LoadDMResources ();
- }
- }
- if (servers[0] == '/' && stat(servers, &statb) != -1)
- {
- if (statb.st_mtime != ServersModTime)
- {
- Debug ("Servers file %s has changed, rescanning\n", servers);
- LogInfo(
- ReadCatalog(MC_ERROR_SET,MC_LOG_REREADSRV,MC_DEF_LOG_REREADSRV),
- servers);
- ServersModTime = statb.st_mtime;
- ForEachDisplay (MarkDisplay);
- ScanServers ();
- }
- }
- if (accessFile && accessFile[0] && stat (accessFile, &statb) != -1)
- {
- if (statb.st_mtime != AccessFileModTime)
- {
- Debug ("Access file %s has changed, rereading\n", accessFile);
- LogInfo(
- ReadCatalog(MC_ERROR_SET,MC_LOG_REREADACC,MC_DEF_LOG_REREADACC),
- accessFile);
- AccessFileModTime = statb.st_mtime;
- ScanAccessDatabase ();
- }
- }
-
- }
- /*
- * catch a SIGTERM, kill all displays and exit
- */
- static int dt_shutdown = 0;
- static SIGVAL
- StopAll( int arg )
- {
- if (parent_pid != getpid())
- {
- /*
- * we got caught in a race condition - we are really a
- * child dtlogin process that has been killed by the parent
- * dtlogin process before we got a chance to return from
- * fork() and remove this signal handler
- */
- Debug ("Child dtlogin caught signal %d before it could become a real child\n", arg);
- (void) signal (arg, SIG_DFL); /* ensure no more handler */
- TerminateProcess (getpid(), arg); /* and send signal again */
- return;
- }
- Debug ("Shutting down entire manager\n");
- DestroyWellKnownSockets ();
- dt_shutdown = 1;
- MarkShutdownTime();
- ForEachDisplay (StopDisplay);
- #if defined(SYSV) || defined(SVR4)
- /* to avoid another one from killing us unceremoniously */
- (void) signal (SIGTERM, StopAll);
- (void) signal (SIGINT, StopAll);
- #endif
- }
- /*
- * notice that a child has died and may need another
- * sub-daemon started
- */
- int ChildReady = 0;
- #if !defined(SYSV) || defined(hpux) || defined(_AIX) || defined(__linux__) || defined(CSRG_BASED)
- static SIGVAL
- ChildNotify( int arg )
- {
- ChildReady = 1;
- }
- #endif
- /*
- In HP-UX, SIGCHLDs are queued rather than lost if we are in the middle
- of processing one (see SIGNAL(5), WARNINGS). The following code relies
- upon this.
-
- If we have a socket, then we are using "select" to block
- (WaitForSomething) rather than "wait". If a child dies, ChildReady is
- set and the select unblocks. We then loop, processing the child that
- died plus any that die while we are processing others. Finally we
- activate the signal handler again and go around one more time in case a
- child died right before activating the signal handler.
- */
- void
- WaitForChild( void )
- {
- int pid;
- waitType status;
- int mask;
- #if defined(SYSV) || defined(SVR4) || defined(hpux)
- if (AnyWellKnownSockets()) {
- while ( ChildReady ) {
- #ifdef SVR4
- while ((pid = waitpid((pid_t) -1, &status, WNOHANG)) > 0 )
- #else
- while ((pid = wait3 (&status, WNOHANG, NULL)) > 0 )
- #endif
- ProcessChildDeath(pid, status);
- ChildReady = 0;
- (void) signal (SIGCHLD, ChildNotify);
- sleep(1);
- }
- }
- else {
- /* XXX classic sysV signal race condition here with RescanNotify */
- if ((pid = wait (&status)) != -1)
- ProcessChildDeath(pid, status);
- }
- #else
- mask = sigblock (sigmask (SIGCHLD) | sigmask (SIGHUP));
- Debug ("Signals blocked, mask was 0x%x\n", mask);
- if (!ChildReady && !Rescan)
- sigpause (mask);
- ChildReady = 0;
- sigsetmask (mask);
- while ((pid = wait3 (&status, WNOHANG, (struct rusage *) 0)) > 0)
- ProcessChildDeath(pid, status);
- #endif
- StartDisplays ();
- }
-
- static void
- ProcessChildDeath( int pid, waitType status )
- {
- struct display *d;
- Debug ("Processing child death, pid = %d\n", pid);
- if (autoRescan)
- RescanIfMod ();
- if ( (d = FindDisplayByPid (pid)) != 0 ) {
- d->pid = -1;
- /*
- * do process accounting...
- */
- #if !defined(CSRG_BASED)
- Account(d, NULL, NULL, pid, DEAD_PROCESS, status);
- #endif
- /*
- * make sure authorization file is deleted...
- */
- /*
-
- if (d->authorization && d->authFile) {
- (void) unlink (d->authFile);
- }
- */
- /*
- * reset "startTries" ...
- *
- * Local displays: Only for clean exits of the server
- * Foreign displays: Always except for OPENFAILED_DISPLAY
- *
- * Note: if startTries expires and a "getty" is run on the local
- * display, startTries will be reset to zero before
- * attempting to restart the server.
- */
-
- switch (waitVal (status)) {
- case OBEYSESS_DISPLAY:
- case RESERVER_DISPLAY:
- d->startTries = 0;
- break;
- case OPENFAILED_DISPLAY:
- break;
- default:
- if (d->displayType.location != Local )
- d->startTries = 0;
- break;
- }
- /*
- * process exit status...
- */
-
- switch (waitVal (status)) {
- case UNMANAGE_DISPLAY:
- Debug ("Display exited with UNMANAGE_DISPLAY\n");
- StopDisplay (d);
- break;
- case OBEYSESS_DISPLAY:
- Debug ("Display exited with (check)OBEYSESS_DISPLAY\n");
- if (d->displayType.lifetime != Permanent || d->status == zombie)
- StopDisplay (d);
- else
- RestartDisplay (d, FALSE);
- break;
- default:
- Debug ("Display exited with unknown status %d\n", waitVal(status));
- LogError ((unsigned char *)"Unknown session exit code %d from process %d\n",
- waitVal (status), pid);
- StopDisplay (d);
- break;
- case OPENFAILED_DISPLAY:
- Debug ("Display exited with OPENFAILED_DISPLAY\n");
- if (d->displayType.origin == FromXDMCP)
- SendFailed (d, "Cannot open display");
- if (d->displayType.location != Local)
- d->startTries++;
- if (d->displayType.origin == FromXDMCP ||
- d->status == zombie ||
- d->startTries >= d->startAttempts)
- StopDisplay (d);
- else
- RestartDisplay (d, TRUE);
- break;
- case RESERVER_DISPLAY:
- Debug ("Display exited with RESERVER_DISPLAY\n");
- if (d->displayType.origin == FromXDMCP || d->status == zombie)
- StopDisplay(d);
- else
- RestartDisplay (d, TRUE);
- break;
- case waitCompose (SIGTERM,0,0):
- Debug ("Display exited on SIGTERM\n");
- if (d->displayType.origin == FromXDMCP || d->status == zombie)
- StopDisplay(d);
- else
- RestartDisplay (d, TRUE);
- break;
- case REMANAGE_DISPLAY:
- Debug ("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;
- case SUSPEND_DISPLAY:
- Debug ("Display exited with SUSPEND_DISPLAY\n");
- if (d->displayType.location == Local)
- StopDisplay(d);
- else
- RestartDisplay (d, FALSE);
- break;
- }
- }
- else if ( (d = FindDisplayByServerPid (pid)) != 0 )
- {
- d->serverPid = -1;
- /*
- * do process accounting...
- */
- #if !defined(CSRG_BASED)
- Account(d, NULL, NULL, pid, DEAD_PROCESS, status);
- #endif
- 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\n", d->name, waitVal (status));
- LogError ((unsigned char *)"Server for display %s terminated unexpectedly %d\n",
- d->name, waitVal(status) );
- if (d->pid != -1)
- {
- Debug ("Terminating session pid %d\n", d->pid);
- TerminateProcess (d->pid, SIGTERM);
- }
- break;
- case notRunning:
- Debug ("Server exited for notRunning session on display %s\n", d->name);
- break;
- case suspended:
- Debug ("Server for display %s is suspended\n", d->name);
- if (!StartGetty(d))
- d->status = notRunning;
- break;
- }
- }
- else
- {
- Debug ("Unknown child termination, status %d\n", waitVal (status));
- }
- }
- static void
- CheckDisplayStatus( struct display *d )
- {
- if (d->displayType.origin == FromFile)
- {
- switch (d->state) {
- case MissingEntry:
- dt_shutdown = 1;
- StopDisplay (d);
- dt_shutdown = 0;
- break;
- case NewEntry:
- d->state = OldEntry;
- case OldEntry:
- Debug("Check %s: status=%d wakeupTime=%d\n", d->name,
- d->status, wakeupTime);
- if (d->status == suspended && wakeupTime >= 0)
- if ( GettyRunning(d) || (d->gettyLine && (strcmp(d->gettyLine,"??") == 0)) )
- if ( wakeupTime == 0 ) {
- Debug("Polling of suspended server %s started.\n",
- d->name);
- wakeupTime = (wakeupInterval < 10
- ? 3 * wakeupInterval
- : 2 * wakeupInterval );
- }
- else {
- Debug("Polling of suspended server %s stopped.\n",
- d->name);
- wakeupTime = -1; /* disable polling */
- d->status = notRunning; /* restart server */
- d->startTries = 0;
- if ( !dt_shutdown ) GettyMessage(d,2);
- }
- else {
- Debug("Polling of suspended server %s continued.\n",
- d->name);
- wakeupTime = wakeupInterval; /* continue polling*/
- }
- if (d->status == notRunning)
- StartDisplay (d);
- break;
- }
- }
- }
- void
- StartDisplays( void )
- {
- ForEachDisplay (CheckDisplayStatus);
- }
- int
- StartDisplay(
- struct display *d )
- {
- waitType status;
- int pid;
- char* authFile_str;
- char start_fbconsole[1024];
- char buff[128];
- Debug ("StartDisplay(): %s\n", d->name);
- bzero(&status, sizeof(waitType));
- if (d->authFile == NULL)
- authFile_str = "NULL";
- else
- authFile_str = d->authFile;
- Debug("(Old StartDisplay) d->authfile %s; authDir %s\n",
- authFile_str, authDir);
- /*
- * The following call to RemoveDisplay is to catch race conditions during
- * shutdown. There is no point in starting a display if Dtlogin is in the
- * process of shutting down...
- */
- if (d->displayType.origin == FromFile && dt_shutdown ) {
- RemoveDisplay(d);
- return 0;
- }
-
- {
- /* make a backup of the authFile before loading resources and */
- /* copy it back to authFile field od display structure for X server */
- /* to reread the host database list on reset */
- /* RK 11.22.93 */
- char bkup[50];
- bkup[0] = '\0';
- if (d->authFile)
- snprintf(bkup, sizeof(bkup), "%s", d->authFile);
- LoadDisplayResources (d);
- /* The Xserver may NOT have been killed, so reuse the authFile. */
- if (NULL == d->authFile &&
- 0 < strlen(bkup) &&
- 0 == strncmp(authDir, bkup, strlen(authDir)))
- d->authFile= (char *) strdup(bkup);
- if (d->authFile == NULL)
- authFile_str = "NULL";
- else
- authFile_str = d->authFile;
- Debug("(Mid StartDisplay) d->authfile %s; authDir %s; bkup %s\n",
- authFile_str, authDir, bkup);
- }
- if (d->displayType.location == Local)
- {
- /* don't bother pinging local displays; we'll
- * certainly notice when they exit
- */
- d->pingInterval = 0;
- if (d->authorize)
- {
- Debug ("SetLocalAuthorization %s, auth %s\n",
- d->name, d->authNames);
- SetLocalAuthorization (d);
- /*
- * reset the server after writing the authorization information
- * to make it read the file (for compatibility with old
- * servers which read auth file only on reset instead of
- * at first connection)
- */
- if (d->serverPid != -1 && d->resetForAuth && d->resetSignal)
- kill (d->serverPid, d->resetSignal);
- }
- /*
- * initialize d->utmpId. Check to see if anyone else is using
- * the requested ID. Always allow the first request for "dt" to
- * succeed as utmp may have become corrupted.
- */
- if (d->utmpId == NULL) {
- static int firsttime = 1;
- static char letters[] = "0123456789abcdefghijklmnopqrstuvwxyzz";
- char *t;
- d->utmpId = malloc(5);
- strcpy(d->utmpId, UTMPREC_PREFIX);
- d->utmpId[4] = '\0';
-
- t = letters;
-
- do {
- if ( firsttime || UtmpIdOpen(d->utmpId)) {
- firsttime = 0;
- break;
- }
- else {
- strncpy(&(d->utmpId[strlen(d->utmpId)]), t++, 1);
- }
- } while (*t != '\0');
- if (*t == '\0') {
- Debug ("All DT utmp IDs already in use. Removing display %s\n",
- d->name);
- LogError ((unsigned char *)"All DT utmp IDs already in use. Removing display %s\n",
- d->name);
- RemoveDisplay(d);
- return 0;
- }
- }
- /*
- * set d->gettyLine to "console" for display ":0" if it is not
- * already set...
- */
- if (! d->gettyLine || strlen(d->gettyLine) == 0 ) {
- char *p;
-
- if ( (p = index(d->name,':')) != NULL &&
- ( strncmp(++p,"0",1) == 0 )) {
- d->gettyLine = (char *) malloc(8);
- strcpy(d->gettyLine, "console");
- }
- else {
- d->gettyLine = (char *) malloc(3);
- strcpy(d->gettyLine, "??");
- }
- }
- /*
- * if gettyLine is set to "console", set gettySpeed to "console" also
- */
-
- if (d->gettyLine && (strcmp(d->gettyLine, "console") == 0 ) ) {
- if (d->gettySpeed)
- free((char *) d->gettySpeed);
- d->gettySpeed = (char *) malloc(8);
- if (d->gettySpeed)
- strcpy(d->gettySpeed, "console");
- }
-
- /*
- * start server. If it cannot be started and this is the console,
- * run a getty...
- */
-
- Debug("Attempting to start server for %s. startTries = %d\n",
- d->name, d->startTries);
- if (d->serverPid == -1) {
- static int bootup = 0;
-
- while (bootup++ < 5) {
- if (GettyRunning(d)) {
- GettyMessage(d,3);
- bootup = 5;
- break;
- }
- else {
- sleep(1);
- }
- }
- }
-
- if (d->serverPid == -1 &&
- (d->startTries++ >= d->startAttempts ||
- !StartServer (d)))
- {
- LogError ((unsigned char *)"Server for display %s can't be started.\n", d->name);
- d->serverPid = -1;
- GettyMessage(d,4);
- if (!StartGetty(d))
- RemoveDisplay (d);
- return 0;
- }
- }
- else
- {
- /* this will only happen when using XDMCP */
- if (d->authorizations)
- SaveServerAuthorizations (d, d->authorizations, d->authNum);
- /*
- * Generate a utmp ID address for a foreign display. Use the last
- * four characters of the DISPLAY name, shifting left if they
- * are already in use...
- */
-
- #if !defined(CSRG_BASED)
- if (d->utmpId == NULL) {
- int i;
- char *p, *q;
- struct utmp *u;
-
- d->utmpId = malloc(sizeof(u->ut_id) +1);
-
- i = strlen (d->name);
- if (i >= sizeof (u->ut_id))
- i -= sizeof (u->ut_id);
- else
- i = 0;
-
- for ( p = d->name, q = d->name + i; p <= q; q-- ) {
- (void) strncpy (d->utmpId, q, sizeof (u->ut_id));
- d->utmpId[sizeof(u->ut_id)] = '\0';
- if (UtmpIdOpen(d->utmpId))
- break;
- }
- #ifdef DEF_NETWORK_DEV
- /*
- * If "networkDev" does not start with "/dev/" then foreign
- * accounting is turned off. Return utmpId to NULL.
- */
- if (networkDev && strncmp(networkDev,"/dev/",5) !=0 ) {
- free(d->utmpId);
- d->utmpId = NULL;
- }
- #endif
- }
- #endif
- }
- if (NULL == d->authFile)
- authFile_str = "NULL";
- else
- authFile_str = d->authFile;
- Debug("(New StartDisplay) d->authfile %s; authDir %s\n",
- authFile_str, authDir);
- /*
- * make sure stderr is pointing to the current error log file...
- */
- SyncErrorFile(0);
-
- #ifdef OSFDEBUG
- if (!nofork_session)
- pid = fork ();
- else
- pid = 0;
- switch (pid)
- #else
- switch (pid = fork ())
- #endif
- {
- case 0:
- #ifdef OSFDEBUG
- if (!nofork_session) {
- CleanUpChild ();
- signal (SIGPIPE, SIG_IGN);
- }
- #else
- CleanUpChild ();
- signal (SIGPIPE, SIG_IGN);
- #endif
- /*
- * set global display name for Debug()
- */
-
- {
- char *p, *s, *t;
-
- p = DisplayName;
-
- strncpy(p, d->name, sizeof(DisplayName) - 1);
- DisplayName[sizeof(DisplayName)-1] = '\0';
-
- if ( (s = strchr(p,':')) != NULL )
- if ( (t = strchr(p,'.')) != NULL )
- strcpy(t,s);
- }
-
- SetAuthorization (d);
- /*
- * do process accounting...
- */
- {
- char *line = (d->displayType.location==Local)
- ? d->gettyLine : d->name;
- #ifdef DEF_NETWORK_DEV
- if (d->displayType.location != Local &&
- networkDev && !strncmp(networkDev,"/dev/",5))
- {
- char *devname;
- int devexists;
- struct stat devinfo;
- devname = networkDev; /* networkDev resource */
- devexists = (lstat(devname,&devinfo)==0);
- if (!devexists && (MK_NETWORK_DEV(devname) < 0)) {
- Debug("Creation of file '%s' failed:\n %s (%d)\n",
- devname,strerror(errno),errno);
- } else {
- for (line=devname; *line; line++);
- while (line>devname && *line!='/') line--;
- if (*line=='/') line++;
- Debug("Using pseudo-tty %s; line=%s\n",
- devname,line);
- }
- }
- #endif
- #if !defined(CSRG_BASED)
- Account(d, "LOGIN", line, getpid(), LOGIN_PROCESS, status);
- #endif
- }
- if (!WaitForServer (d))
- exit (OPENFAILED_DISPLAY);
- /*
- * start the fallback console, if the display is local..
- *
- * if the display is remote, fbconsole should be started on
- * remote host.
- */
- #ifdef sun
- if (d->displayType.location==Local) {
- if (d->authFile && strlen(d->authFile) > 0 ) {
- strcpy(buff, "XAUTHORITY=");
- strcat(buff, d->authFile);
- putenv(buff);
- }
- sprintf(start_fbconsole,"%s -d %s &",FBCONSOLE, d->name);
- if(system(start_fbconsole) == -1)
- Debug("Failed to start the fallback console - %s\n",FBCONSOLE);
- }
- #endif
- if (d->useChooser)
- RunChooser (d);
- else
- ManageSession (d);
- exit (REMANAGE_DISPLAY);
- case -1:
- break;
- default:
- Debug ("Child manager process started for %s. pid = %d\n",
- d->name, pid);
- d->pid = pid;
- d->status = running;
- break;
- }
- return 1;
- }
- static void
- TerminateProcess(int pid, int sig )
- {
- kill (pid, sig);
- #ifdef SIGCONT
- kill (pid, SIGCONT);
- #endif
- }
- /*
- * transition from running to zombie, suspended, or deleted
- */
- void
- StopDisplay( struct display *d )
- {
- waitType status;
- bzero(&status, sizeof(waitType));
- Debug("StopDisplay(): %s, server pid = %d, manager pid = %d, dt_shutdown = %d\n",
- d->name, d->serverPid, d->pid, dt_shutdown);
-
- if (d->serverPid != -1)
- /* don't remove the console */
- if ((d->displayType.location == Local) && !dt_shutdown )
- d->status = suspended;
- else
- d->status = zombie; /* be careful about race conditions */
- if (d->pid != -1)
- TerminateProcess (d->pid, SIGTERM);
- if (d->serverPid != -1) {
- TerminateProcess (d->serverPid, d->termSignal);
- #ifdef sun
- {
- int kbd_fd;
- int translate=TR_ASCII;
- Debug ("Resetting keyboard\n");
- if ((kbd_fd = open("/dev/kbd", O_RDONLY, 0)) < 0) {
- Debug("/dev/kbd open failed\n");
- } else if (ioctl(kbd_fd, KIOCTRANS, (caddr_t) &translate)) {
- Debug("Could not set /dev/kbd back to ASCII mode\n");
- }
- }
- #endif
- }
- else
- if ((d->displayType.location == Local) || !dt_shutdown ) {
- /* don't remove the console */
- #if !defined(CSRG_BASED)
- Account(d, NULL, NULL, 0, DEAD_PROCESS, status);
- #endif
- RemoveDisplay (d);
- }
- }
- /*
- * transition from running to phoenix or notRunning
- */
- static void
- RestartDisplay( struct display *d, int forceReserver )
- {
- if (d->serverPid != -1 && (forceReserver || d->terminateServer))
- {
- TerminateProcess (d->serverPid, d->termSignal);
- d->status = phoenix;
- }
- else
- {
- d->status = notRunning;
- }
- }
- static FD_TYPE CloseMask;
- static int max;
- void
- RegisterCloseOnFork( int fd )
- {
- FD_SET (fd, &CloseMask);
- if (fd > max)
- max = fd;
- }
- #if 0 /* utility routine: activate if needed... */
- int
- CloseOnFork( void )
- {
- FD_CLR (fd, &CloseMask);
- if (fd == max) {
- while (--fd >= 0)
- if (FD_ISSET (fd, &CloseMask))
- break;
- max = fd;
- }
- }
- #endif
- int
- CloseOnFork (void)
- {
- int fd;
- for (fd = 0; fd <= max; fd++)
- if (FD_ISSET (fd, &CloseMask))
- close (fd);
- FD_ZERO (&CloseMask);
- max = 0;
-
- return 0;
- }
- static int pidFd;
- static FILE *pidFilePtr;
- static long
- StorePid( void )
- {
- long oldpid;
- if (pidFile && pidFile[0] != '\0') {
- pidFd = open (pidFile, 2);
- if (pidFd == -1 && errno == ENOENT)
- {
- /*
- * A Legacy OS wouldn't allow an fdopen
- * of a file descriptor handed back by creat(2).
- * The workaround is to close the created file, and
- * open it Read/Write. This will be transparent to HP-UX.
- * This code needs to be cleaned up - 05/22/18 - C
- */
- pidFd = creat (pidFile, 0644);
- if(pidFd != -1) {
- close( pidFd );
- }
- pidFd = open (pidFile, 2);
- }
- if (pidFd == -1 || !(pidFilePtr = fdopen (pidFd, "r+")))
- {
- LogError ((unsigned char *)"Process ID file %s cannot be opened\n",
- pidFile);
- return -1;
- }
- if (fscanf (pidFilePtr, "%ld", &oldpid) != 1)
- oldpid = -1;
- fseek (pidFilePtr, 0l, 0);
- if (lockPidFile)
- {
- #if defined (SYSV) || defined (SVR4)
- if (lockf (pidFd, F_TLOCK, 0) == -1)
- {
- if ((errno == EAGAIN) || (errno == EACCES))
- return oldpid;
- else
- return -1;
- }
- #else
- if (flock (pidFd, LOCK_EX|LOCK_NB) == -1)
- {
- if (errno == EWOULDBLOCK)
- return oldpid;
- else
- return -1;
- }
- #endif
- }
- /*
- * HPUX releases the lock on ANY close of the file, not just the
- * one that established the lock. -prr
- */
- /* close(creat(pidFile, 0644)); */
- (void) creat(pidFile, 0644);
- fprintf (pidFilePtr, "%ld\n", (long)getpid ());
- (void) fflush(pidFilePtr);
- RegisterCloseOnFork(pidFd);
- }
- return 0;
- }
- static void
- UnlockPidFile( void )
- {
- if (lockPidFile)
- #if defined (SYSV) || defined (SVR4)
- lockf (pidFd, F_ULOCK, 0);
- #else
- flock (pidFd, LOCK_UN);
- #endif
- close (pidFd);
- fclose (pidFilePtr);
- }
- int
- SetTitle( char *name, char *ptr )
- {
- #ifndef NOXDMTITLE
- char *p, *s, *t;
- int length;
- /*
- * remove domain qualifiers and screens from name...
- */
- if ( (p = malloc(strlen(name) + 1)) == NULL) return 0;
- strcpy(p, name);
- if ( (s = strchr(p,':')) == NULL ) {
- free(p);
- return 0;
- }
-
- if ( (t = strchr(s,'.')) != NULL )
- *t = '\0';
- if ( (t = strchr(p,'.')) != NULL )
- strcpy(t,s);
-
- /*
- * if there is enough room shift program name to left,
- * then append display name in remaining space.
- */
- s = Title;
- length = strlen(s);
-
- t = strrchr(s, '/');
- if ( (t != NULL) && ((t-s+1) >= (strlen(p) + 3)) ) {
- t++;
- strcpy(s,t); /* "program" */
- strcat(s," <"); /* "program <" */
- strcat(s,p); /* "program <displayName" */
- strcat(s,">"); /* "program <displayName>" */
- t = s + strlen(s);
- length = length - strlen(s);
- while (length > 0){
- *t++ = ' ';
- length--;
- }
- }
- free(p);
- #endif
- return 1;
- }
- /*****************************************************************************
- * StartGetty
- *
- * Start a "getty" running on the console...
- *
- *****************************************************************************/
- #if defined (_AIX) && defined (_POWER)
- #define GETTYPATH "/usr/sbin/getty"
- #elif defined(__OpenBSD__)
- #define GETTYPATH "/usr/libexec/getty"
- #elif defined(__linux__)
- #define GETTYPATH "/sbin/getty"
- #else
- #define GETTYPATH "/etc/getty"
- #endif
- static int
- StartGetty( struct display *d )
- {
- int pid;
- char tynm[20];
- waitType status;
- Debug ("StartGetty(): %s\n", d->name);
- bzero(&status, sizeof(waitType));
- /*
- * ensure that server is known dead...
- */
- d->serverPid = -1;
- #if !defined(GETTYPATH)
- return FALSE;
- #else
- /*
- * check to see if we have a valid device (at least a non-null name)...
- */
- if ( d->gettyLine &&
- (strlen(d->gettyLine) > 0) &&
- (strcmp(d->gettyLine,"??") != 0) )
- ;
- else
- return FALSE;
- /*
- * if there is already a getty running on the device, set up
- * to start watching it. When it exits, restart the server...
- */
- if ( GettyRunning(d) ) {
- d->status = suspended; /* set up to restart server */
- wakeupTime = 0; /* enable polling */
- sleep(1); /* wait for fbconsole to go away */
- GettyMessage(d,1); /* print a help message */
- return TRUE;
- }
-
- /*
- * there is no getty running on the device, try to start one...
- */
- d->status = phoenix; /* set up to restart server */
- d->startTries = 0;
-
- switch (pid = fork ()) {
- case 0:
- CleanUpChild ();
- /*
- * do process accounting...
- */
- #if !defined(CSRG_BASED)
- Account(d, "LOGIN", NULL, getpid(), LOGIN_PROCESS, status);
- #endif
- #ifdef _AIX
- /* The tty argument for getty on AIX must be of the form "/dev/any tty"
- and so the following logic
- Raghu krovvidi 07.07.93
- */
- strcpy(tynm,"/dev/");
- strcat(tynm,d->gettyLine);
- #else
- strcpy(tynm, d->gettyLine);
- #endif
- Debug(" execing getty on %s\n",tynm);
- execl(GETTYPATH, "getty", tynm, d->gettySpeed, (char *)0);
- LogError ((unsigned char *)"Can not execute %s for %s: errno = %d\n",
- GETTYPATH, d->name, errno);
- exit (UNMANAGE_DISPLAY);
- case -1:
- Debug ("Fork of /etc/getty failed %s\n", d->name);
- LogError ((unsigned char *)"Can not fork to execute /etc/getty %s\n", d->name);
- return FALSE;
- default:
- break;
- }
- Debug ("/etc/getty started on %s\n", d->name);
- d->serverPid = pid;
- return TRUE;
- #endif /* GETTYPATH not defined */
- }
-
- /***************************************************************************
- *
- * GettyMessage
- *
- * Print a message on the display device when going into No Windows mode.
- *
- ***************************************************************************/
- void
- GettyMessage( struct display *d, int msgnum )
- {
- FILE *tf;
- char buf[128];
- if (quiet) return;
- snprintf(buf, sizeof(buf), "/dev/%s", d->gettyLine);
-
- if ( (tf = fopen (buf, "a")) != NULL) {
- fprintf (tf,
- "\r\n\r\n*****************************************************************************\r\n*\r\n");
- switch (msgnum) {
- case 1:
-
- fprintf(tf, "%s", (char *)ReadCatalog(MC_LABEL_SET,MC_SUS1_LABEL,MC_DEF_SUS1_LABEL));
- fprintf(tf, "%s", (char *)ReadCatalog(MC_LABEL_SET,MC_SUS2_LABEL,MC_DEF_SUS2_LABEL));
- fprintf(tf, "%s", (char *)ReadCatalog(MC_LABEL_SET,MC_SUS3_LABEL,MC_DEF_SUS3_LABEL));
- break;
-
- case 2:
-
- fprintf(tf, "%s", (char *)ReadCatalog(MC_LABEL_SET,MC_RES_LABEL,MC_DEF_RES_LABEL));
- break;
-
- case 3:
-
- fprintf(tf,
- (char *)ReadCatalog(MC_LABEL_SET,MC_START_LBLDPY,MC_DEF_START_LBLDPY),
- d->name);
- fprintf(tf, "%s", (char *)ReadCatalog(MC_LABEL_SET,MC_WAIT_LABEL,MC_DEF_WAIT_LABEL));
- break;
-
- case 4:
-
- fprintf(tf,(char *)ReadCatalog(MC_LABEL_SET,MC_X_LABEL,MC_DEF_X_LABEL),
- d->name);
- break;
- }
-
- fprintf (tf,
- "*****************************************************************************\r\n");
- fclose (tf);
- }
- }
- /***************************************************************************
- *
- * GettyRunning
- *
- * See if a getty process is running against the display device. This
- * routine may need to be rewritten on other platforms if a different
- * mechanism is needed to make the determination.
- *
- * Output: TRUE == a login process is active on the requested device
- * FALSE == a login process is not active on the device.
- *
- * Sets d->gettyState:
- * NONE - no getty running or don't care
- * LOGIN - getty running
- * USER - user logged in on getty
- *
- * Note: The check for a getty process running is made by scanning
- * /etc/utmp, looking for a login process on the respective device.
- * However, the child Dtlogin spawned by the master Dtlogin to
- * handle this display also is a "login process" according to
- * /etc/utmp. It provides a login path and therefore must register
- * itself as so. If a getty is also running, there are actually two
- * login processes running against the same device at the same time.
- *
- * The child Dtlogin dies before the scan of /etc/utmp is made.
- * Provided /etc/utmp is updated correctly, the Dtlogin entry will
- * be marked as dead and will not show up in the scan of /etc/utmp.
- ***************************************************************************/
- int
- GettyRunning( struct display *d )
- {
- #if defined(__FreeBSD__) && OSMAJORVERSION > 8
- struct utmpx utmp; /* local struct for new entry */
- struct utmpx *u; /* pointer to entry in utmp file */
- #else
- struct utmp utmp; /* local struct for new entry */
- struct utmp *u; /* pointer to entry in utmp file */
- #endif
-
- int rvalue; /* return value (TRUE or FALSE) */
- char buf[32];
-
- d->gettyState = DM_GETTY_NONE;
- /*
- * check to see if we have a valid device (at least a non-null name)...
- */
- if ( d->gettyLine &&
- (strlen(d->gettyLine) > 0) &&
- (strcmp(d->gettyLine,"??") != 0) )
- ;
- else
- return FALSE;
- #if defined(__FreeBSD__) && OSMAJORVERSION > 8
- bzero(&utmp, sizeof(struct utmpx));
- #else
- bzero(&utmp, sizeof(struct utmp));
- #endif
- #ifdef _AIX
- if (!strcmp(d->gettyLine,"console")) {
- char *ttynm;
- int fd=0;
- fd = open("/dev/console",O_RDONLY);
- ttynm = ttyname(fd);
- ttynm += 5;
- strcpy(utmp.ut_line,ttynm);
- close(fd);
- }
- else
- {
- strncpy(utmp.ut_line, d->gettyLine, sizeof(utmp.ut_line) - 1);
- utmp.ut_line[sizeof(utmp.ut_line) - 1] = 0;
- }
- #else
- strncpy(utmp.ut_line, d->gettyLine, sizeof(utmp.ut_line) - 1);
- utmp.ut_line[sizeof(utmp.ut_line) - 1] = 0;
- #endif
-
- Debug("Checking for a getty on line %s.\n", utmp.ut_line);
-
- #if !defined(CSRG_BASED)
- setutent();
- rvalue = FALSE;
-
- while ( (u = getutent()) != NULL ) {
-
- if ((strncmp(u->ut_line, utmp.ut_line, sizeof(u->ut_line)) != 0) ||
- (strncmp(u->ut_id, d->utmpId, sizeof(u->ut_id)) == 0) )
- continue;
- switch (u->ut_type) {
-
- case INIT_PROCESS: strcpy(buf, "INIT_PROCESS"); break;
- case LOGIN_PROCESS: strcpy(buf, "LOGIN_PROCESS"); break;
- case USER_PROCESS: strcpy(buf, "USER_PROCESS"); break;
- case DEAD_PROCESS: strcpy(buf, "DEAD_PROCESS"); break;
- default: strcpy(buf, "UNKNOWN"); break;
- }
- Debug("Utmp info: id=%.4s, user=%s, line=%s, pid=%d, type=%s\n",
- u->ut_id, u->ut_user, u->ut_line, u->ut_pid, buf);
- if ( u->ut_type == INIT_PROCESS || u->ut_type == LOGIN_PROCESS) {
- d->gettyState = DM_GETTY_LOGIN;
- }
- else if (wakeupTime <= 0 && u->ut_type == USER_PROCESS) {
- d->gettyState = DM_GETTY_USER;
- }
-
- if (d->gettyState != DM_GETTY_NONE)
- {
- rvalue = TRUE;
- break;
- }
- }
- endutent();
- #endif /* !CSRG_BASED */
- return rvalue;
- }
-
- /***************************************************************************
- *
- * CheckRestartTime
- *
- * Check if enough time has elapsed since shutdown.
- *
- * This is primarily to work with /etc/shutdown. When shutdown kills
- * dtlogin (/etc/killall), init immediately restarts it. Shutdown kills
- * it again and init restarts it. At each restart, the X-server may start
- * on the local display and then subsequently be killed. The user sees a
- * flashing screen and sometimes the console is left in an unreset state.
- *
- * When Dtlogin shuts down, it touches the access time on the Xservers
- * file. (MarkShutdownTime()). This time is then used to determine if
- * sufficient time has elapsed before restarting.
- *
- ***************************************************************************/
- static void
- CheckRestartTime( void )
- {
- struct stat statb;
- int sleeptime;
-
- if (servers[0] == '/' && stat(servers, &statb) != -1) {
- Debug("Checking restart time.\n");
-
- #ifdef OSFDEBUG
- /* only those other systems are this slow :-) */
- sleeptime = 6 - (int) (time((time_t *) 0) - statb.st_atime);
- #else
- sleeptime = 30 - (int) (time((time_t *) 0) - statb.st_atime);
- #endif
-
- if ( sleeptime > 30 ) sleeptime = 30;
-
- if ( sleeptime > 0 ) {
- Debug("Restarting too soon after shutdown. Sleeping %d seconds.\n",
- sleeptime);
- sleep (sleeptime);
- }
- }
- }
-
- /***************************************************************************
- *
- * MarkShutdownTime
- *
- * Save the time when we shut down to check later for too fast of a restart.
- *
- ***************************************************************************/
- static void
- MarkShutdownTime( void )
- {
- struct stat statb;
- struct utimbuf timebuf;
-
- if (servers[0] == '/' && stat(servers, &statb) != -1) {
- Debug("Marking shutdown time.\n");
- timebuf.actime = time((time_t *) 0 );
- timebuf.modtime = statb.st_mtime;
- if ( (utime(servers, &timebuf)) != 0 ) {
- Debug("MarkShutdownTime(): utime() error = %d\n", errno);
- }
- }
- }
- /***************************************************************************
- *
- * dtMakeDefaultDir
- *
- * Make the default dt directory "/var/dt" if needed.
- *
- ***************************************************************************/
- static void
- dtMakeDefaultDir( void )
- {
- dtmkdir("/var", 0755, 0);
- dtmkdir("/var/dt", 0755, 1);
- dtmkdir("/var/dt/tmp", 0755, 1);
- dtmkdir("/var/dt/appconfig", 0755, 1);
- dtmkdir("/var/dt/appconfig/appmanager", 0755, 1);
- }
- static void
- dtmkdir(char *dir, mode_t dir_mode, int force)
- {
- struct stat file_status;
- if ( stat(dir, &file_status) != 0) {
- /** try to create it **/
- if ( mkdir(dir, dir_mode) == 0) {
- chmod(dir, dir_mode); /** since umask is non-zero **/
- Debug("Created dir %s\n", dir);
- } else {
- LogError((unsigned char *)"Unable to create dir %s\n", dir);
- }
- } else {
- if ( force && (file_status.st_mode & dir_mode) != dir_mode) {
- /** try to set correct permissions **/
- if ( chmod(dir, file_status.st_mode | dir_mode) == 0) {
- Debug("Set permissions on %s\n", dir);
- } else {
- LogError((unsigned char *)
- "Unable to set permissions on %s\n", dir);
- }
- }
- }
- }
|