You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
250 lines
7.4 KiB
250 lines
7.4 KiB
/*****************************************************************
|
|
ksmserver - the KDE session management server
|
|
|
|
Copyright (C) 2000 Matthias Ettrich <ettrich@kde.org>
|
|
******************************************************************/
|
|
|
|
#include <config.h>
|
|
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
#include <dcopclient.h>
|
|
#include <tqmessagebox.h>
|
|
#include <tqdir.h>
|
|
|
|
#include <kapplication.h>
|
|
#include <kcmdlineargs.h>
|
|
#include <kaboutdata.h>
|
|
#include <kdebug.h>
|
|
#include <klocale.h>
|
|
#include <kglobal.h>
|
|
#include <kconfig.h>
|
|
#include "server.h"
|
|
|
|
|
|
static const char version[] = "0.4";
|
|
static const char description[] = I18N_NOOP( "The reliable KDE session manager that talks the standard X11R6 \nsession management protocol (XSMP)." );
|
|
|
|
static const KCmdLineOptions options[] =
|
|
{
|
|
{ "r", 0, 0 },
|
|
{ "restore", I18N_NOOP("Restores the saved user session if available"), 0},
|
|
{ "w", 0, 0 },
|
|
{ "windowmanager <wm>", I18N_NOOP("Starts 'wm' in case no other window manager is \nparticipating in the session. Default is 'twin'"), 0},
|
|
{ "windowmanageraddargs <wm>", I18N_NOOP("Pass additional arguments to the window manager. Default is ''"), 0},
|
|
{ "nolocal", I18N_NOOP("Also allow remote connections"), 0},
|
|
KCmdLineLastOption
|
|
};
|
|
|
|
extern KSMServer* the_server;
|
|
|
|
void IoErrorHandler ( IceConn iceConn)
|
|
{
|
|
the_server->ioError( iceConn );
|
|
}
|
|
|
|
bool writeTest(TQCString path)
|
|
{
|
|
path += "/XXXXXX";
|
|
int fd = mkstemp(path.data());
|
|
if (fd == -1)
|
|
return false;
|
|
if (write(fd, "Hello World\n", 12) == -1)
|
|
{
|
|
int save_errno = errno;
|
|
close(fd);
|
|
unlink(path.data());
|
|
errno = save_errno;
|
|
return false;
|
|
}
|
|
close(fd);
|
|
unlink(path.data());
|
|
return true;
|
|
}
|
|
|
|
void sanity_check( int argc, char* argv[] )
|
|
{
|
|
TQCString msg;
|
|
TQCString path = getenv("HOME");
|
|
TQCString readOnly = getenv("KDE_HOME_READONLY");
|
|
if (path.isEmpty())
|
|
{
|
|
msg = "$HOME not set!";
|
|
}
|
|
if (msg.isEmpty() && access(path.data(), W_OK))
|
|
{
|
|
if (errno == ENOENT)
|
|
msg = "$HOME directory (%s) does not exist.";
|
|
else if (readOnly.isEmpty())
|
|
msg = "No write access to $HOME directory (%s).";
|
|
}
|
|
if (msg.isEmpty() && access(path.data(), R_OK))
|
|
{
|
|
if (errno == ENOENT)
|
|
msg = "$HOME directory (%s) does not exist.";
|
|
else
|
|
msg = "No read access to $HOME directory (%s).";
|
|
}
|
|
if (msg.isEmpty() && readOnly.isEmpty() && !writeTest(path))
|
|
{
|
|
if (errno == ENOSPC)
|
|
msg = "$HOME directory (%s) is out of disk space.";
|
|
else
|
|
msg = "Writing to the $HOME directory (%s) failed with\n "
|
|
"the error '"+TQCString(strerror(errno))+"'";
|
|
}
|
|
if (msg.isEmpty())
|
|
{
|
|
path = getenv("ICEAUTHORITY");
|
|
if (path.isEmpty())
|
|
{
|
|
path = getenv("HOME");
|
|
path += "/.ICEauthority";
|
|
}
|
|
|
|
if (access(path.data(), W_OK) && (errno != ENOENT))
|
|
msg = "No write access to '%s'.";
|
|
else if (access(path.data(), R_OK) && (errno != ENOENT))
|
|
msg = "No read access to '%s'.";
|
|
}
|
|
if (msg.isEmpty())
|
|
{
|
|
path = DCOPClient::dcopServerFile();
|
|
if (access(path.data(), R_OK) && (errno == ENOENT))
|
|
{
|
|
// Check iceauth
|
|
if (DCOPClient::iceauthPath().isEmpty())
|
|
msg = "Could not find 'iceauth' in path.";
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
{
|
|
path = getenv("TDETMP");
|
|
if (path.isEmpty())
|
|
path = "/tmp";
|
|
if (!writeTest(path))
|
|
{
|
|
if (errno == ENOSPC)
|
|
msg = "Temp directory (%s) is out of disk space.";
|
|
else
|
|
msg = "Writing to the temp directory (%s) failed with\n "
|
|
"the error '"+TQCString(strerror(errno))+"'";
|
|
}
|
|
}
|
|
if (msg.isEmpty() && (path != "/tmp"))
|
|
{
|
|
path = "/tmp";
|
|
if (!writeTest(path))
|
|
{
|
|
if (errno == ENOSPC)
|
|
msg = "Temp directory (%s) is out of disk space.";
|
|
else
|
|
msg = "Writing to the temp directory (%s) failed with\n "
|
|
"the error '"+TQCString(strerror(errno))+"'";
|
|
}
|
|
}
|
|
if (msg.isEmpty())
|
|
{
|
|
path += ".ICE-unix";
|
|
if (access(path.data(), W_OK) && (errno != ENOENT))
|
|
msg = "No write access to '%s'.";
|
|
else if (access(path.data(), R_OK) && (errno != ENOENT))
|
|
msg = "No read access to '%s'.";
|
|
}
|
|
if (!msg.isEmpty())
|
|
{
|
|
const char *msg_pre =
|
|
"The following installation problem was detected\n"
|
|
"while trying to start KDE:"
|
|
"\n\n ";
|
|
const char *msg_post = "\n\nKDE is unable to start.\n";
|
|
fputs(msg_pre, stderr);
|
|
fprintf(stderr, msg.data(), path.data());
|
|
fputs(msg_post, stderr);
|
|
|
|
TQApplication a(argc, argv);
|
|
TQCString qmsg(256+path.length());
|
|
qmsg.sprintf(msg.data(), path.data());
|
|
qmsg = msg_pre+qmsg+msg_post;
|
|
TQMessageBox::critical(0, "KDE Installation Problem!",
|
|
TQString::fromLatin1(qmsg.data()));
|
|
exit(255);
|
|
}
|
|
}
|
|
|
|
extern "C" KDE_EXPORT int kdemain( int argc, char* argv[] )
|
|
{
|
|
sanity_check(argc, argv);
|
|
|
|
KAboutData aboutData( "ksmserver", I18N_NOOP("The KDE Session Manager"),
|
|
version, description, KAboutData::License_BSD,
|
|
"(C) 2000, The KDE Developers");
|
|
aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
|
|
aboutData.addAuthor("Luboš Luňák", I18N_NOOP( "Maintainer" ), "l.lunak@kde.org" );
|
|
|
|
KCmdLineArgs::init(argc, argv, &aboutData);
|
|
KCmdLineArgs::addCmdLineOptions( options );
|
|
|
|
putenv((char*)"SESSION_MANAGER=");
|
|
KApplication a(KApplication::openX11RGBADisplay(), false); // Disable styles until we need them.
|
|
fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, 1);
|
|
|
|
|
|
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
|
|
|
kapp->dcopClient()->registerAs("ksmserver", false);
|
|
if (!kapp->dcopClient()->isRegistered())
|
|
{
|
|
qWarning("Could not register with DCOPServer. Aborting.");
|
|
return 1;
|
|
}
|
|
|
|
TQCString wm = args->getOption("windowmanager");
|
|
TQCString wmaddargs = args->getOption("windowmanageraddargs");
|
|
if ( wm.isEmpty() )
|
|
wm = "twin";
|
|
|
|
bool only_local = args->isSet("local");
|
|
#ifndef HAVE__ICETRANSNOLISTEN
|
|
/* this seems strange, but the default is only_local, so if !only_local
|
|
* the option --nolocal was given, and we warn (the option --nolocal
|
|
* does nothing on this platform, as here the default is reversed)
|
|
*/
|
|
if (!only_local) {
|
|
qWarning("--[no]local is not supported on your platform. Sorry.");
|
|
}
|
|
only_local = false;
|
|
#endif
|
|
|
|
KSMServer *server = new KSMServer( TQString::fromLatin1(wm), TQString::fromLatin1(wmaddargs), only_local);
|
|
kapp->dcopClient()->setDefaultObject( server->objId() );
|
|
|
|
IceSetIOErrorHandler( IoErrorHandler );
|
|
|
|
KConfig *config = KGlobal::config();
|
|
config->setGroup( "General" );
|
|
|
|
int realScreenCount = ScreenCount( qt_xdisplay() );
|
|
bool screenCountChanged =
|
|
( config->readNumEntry( "screenCount", realScreenCount ) != realScreenCount );
|
|
|
|
TQString loginMode = config->readEntry( "loginMode", "restorePreviousLogout" );
|
|
|
|
if ( args->isSet("restore") && ! screenCountChanged )
|
|
server->restoreSession( SESSION_BY_USER );
|
|
else if ( loginMode == "default" || screenCountChanged )
|
|
server->startDefaultSession();
|
|
else if ( loginMode == "restorePreviousLogout" )
|
|
server->restoreSession( SESSION_PREVIOUS_LOGOUT );
|
|
else if ( loginMode == "restoreSavedSession" )
|
|
server->restoreSession( SESSION_BY_USER );
|
|
else
|
|
server->startDefaultSession();
|
|
return a.exec();
|
|
}
|
|
|