Exemplo n.º 1
0
int
main( int argc, char **argv )
{
	int oldpid, oldumask, fd, noDaemonMode;
	char *pt, *errorLogFile, **opts;

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

	/* give /dev/null as stdin */
	if ((fd = open( "/dev/null", O_RDONLY )) > 0) {
		dup2( fd, 0 );
		close( fd );
	}
	if (fcntl( 1, F_GETFD ) < 0)
		dup2( 0, 1 );
	if (fcntl( 2, F_GETFD ) < 0)
		dup2( 0, 2 );

	if (argv[0][0] == '/') {
		if (!StrDup( &progpath, argv[0] ))
			Panic( "Out of memory" );
	} else
#ifdef __linux__
	{
		/* note that this will resolve symlinks ... */
		int len;
		char fullpath[PATH_MAX];
		if ((len = readlink( "/proc/self/exe", fullpath, sizeof(fullpath) )) < 0)
			Panic( "Invoke with full path specification or mount /proc" );
		if (!StrNDup( &progpath, fullpath, len ))
			Panic( "Out of memory" );
	}
#else
# if 0
		Panic( "Must be invoked with full path specification" );
# else
	{
		char directory[PATH_MAX+1];
		if (!getcwd( directory, sizeof(directory) ))
			Panic( "Can't find myself (getcwd failed)" );
		if (strchr( argv[0], '/' ))
			StrApp( &progpath, directory, "/", argv[0], (char *)0 );
		else {
			int len;
			char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1];

			if (!(path = getenv( "PATH" )))
				Panic( "Can't find myself (no PATH)" );
			len = strlen( argv[0] );
			name = nambuf + PATH_MAX - len;
			memcpy( name, argv[0], len + 1 );
			*--name = '/';
			do {
				if (!(pathe = strchr( path, ':' )))
					pathe = path + strlen( path );
				len = pathe - path;
				if (!len || (len == 1 && *path == '.')) {
					len = strlen( directory );
					path = directory;
				}
				thenam = name - len;
				if (thenam >= nambuf) {
					memcpy( thenam, path, len );
					if (!access( thenam, X_OK ))
						goto found;
				}
				path = pathe;
			} while (*path++ != '\0');
			Panic( "Can't find myself (not in PATH)" );
		  found:
			if (!StrDup( &progpath, thenam ))
				Panic( "Out of memory" );
		}
	}
# endif
#endif
	prog = strrchr( progpath, '/' ) + 1;

#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE)
	Title = argv[0];
	TitleLen = (argv[argc - 1] + strlen( argv[argc - 1] )) - Title;
#endif

	/*
	 * Parse command line options
	 */
	noDaemonMode = getppid();
	errorLogFile = 0;
	if (!(opts = Malloc( 2 * sizeof(char *) )))
		return 1;
	opts[0] = (char *)"";
	opts[1] = 0;
	while (*++argv) {
		if (**argv != '-')
			break;
		pt = *argv + 1;
		if (*pt == '-')
			pt++;
		if (!strcmp( pt, "help" ) || !strcmp( pt, "h" )) {
			printf( "Usage: %s [options] [tty]\n"
"  -daemon\t  - Daemonize even when started by init\n"
"  -nodaemon\t  - Don't daemonize even when started from command line\n"
"  -config <file>  - Use alternative master configuration file\n"
"  -xrm <res>\t  - Override frontend-specific resource\n"
"  -error <file>\t  - Use alternative log file\n"
"  -debug <num>\t  - Debug option bitfield:\n"
"\t\t\t0x1 - core log\n"
"\t\t\t0x2 - config reader log\n"
"\t\t\t0x4 - greeter log\n"
"\t\t\t0x8 - IPC log\n"
"\t\t\t0x10 - session sub-daemon post-fork delay\n"
"\t\t\t0x20 - config reader post-start delay\n"
"\t\t\t0x40 - greeter post-start delay\n"
"\t\t\t0x80 - don't use syslog\n"
"\t\t\t0x100 - core Xauth log\n"
"\t\t\t0x400 - valgrind config reader and greeter\n"
"\t\t\t0x800 - strace config reader and greeter\n"
			        , prog );
			exit( 0 );
		} else if (!strcmp( pt, "daemon" ))
			noDaemonMode = 0;
		else if (!strcmp( pt, "nodaemon" ))
			noDaemonMode = 1;
		else if (argv[1] && !strcmp( pt, "config" ))
			StrDup( opts, *++argv );
		else if (argv[1] && !strcmp( pt, "xrm" ))
			opts = addStrArr( opts, *++argv, -1 );
		else if (argv[1] && !strcmp( pt, "debug" ))
			sscanf( *++argv, "%i", &debugLevel );
		else if (argv[1] && (!strcmp( pt, "error" ) || !strcmp( pt, "logfile" )))
			errorLogFile = *++argv;
		else {
			fprintf( stderr, "\"%s\" is an unknown option or is missing a parameter\n", *argv );
			exit( 1 );
		}
	}

	/*
	 * Only allow root to run in non-debug mode to avoid problems
	 */
	if (!debugLevel && getuid()) {
		fprintf( stderr, "Only root wants to run %s\n", prog );
		exit( 1 );
	}

	InitErrorLog( errorLogFile );

	if (noDaemonMode != 1)
		BecomeDaemon();

	/*
	 * Step 1 - load configuration parameters
	 */
	if (!InitResources( opts ) || ScanConfigs( FALSE ) < 0)
		LogPanic( "Config reader failed. Aborting ...\n" );

	/* 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 );
	}

#ifdef NEED_ENTROPY
	AddOtherEntropy();
#endif

	/*
	 * We used to clean up old authorization files here. As authDir is
	 * supposed to be /var/run/xauth or /tmp, we needn't to care for it.
	 */

#ifdef XDMCP
	init_session_id();
#else
	Debug( "not compiled for XDMCP\n" );
#endif
	if (pipe( signalFds ))
		LogPanic( "Unable to create signal notification pipe.\n" );
	RegisterInput( signalFds[0] );
	RegisterCloseOnFork( signalFds[0] );
	RegisterCloseOnFork( signalFds[1] );
	(void)Signal( SIGTERM, SigHandler );
	(void)Signal( SIGINT, SigHandler );
	(void)Signal( SIGHUP, SigHandler );
	(void)Signal( SIGCHLD, SigHandler );
	(void)Signal( SIGUSR1, SigHandler );

	/*
	 * Step 2 - run a sub-daemon for each entry
	 */
#ifdef XDMCP
	UpdateListenSockets();
#endif
	openCtrl( 0 );
	MainLoop();
	closeCtrl( 0 );
	if (sdRec.how) {
		commitBootOption();
		if (Fork() <= 0) {
			char *cmd = sdRec.how == SHUT_HALT ? cmdHalt : cmdReboot;
			execute( parseArgs( (char **)0, cmd ), (char **)0 );
			LogError( "Failed to execute shutdown command %\"s\n", cmd );
			exit( 1 );
		} else {
			sigset_t mask;
			sigemptyset( &mask );
			sigaddset( &mask, SIGCHLD );
			sigaddset( &mask, SIGHUP );
			sigsuspend( &mask );
		}
	}
	Debug( "nothing left to do, exiting\n" );
	return 0;
}
Exemplo n.º 2
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*/
}