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.
tdebase/ksmserver/main.cpp

248 lines
7.1 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 <qmessagebox.h>
#include <qdir.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 'kwin'"), 0},
{ "nolocal", I18N_NOOP("Also allow remote connections"), 0},
KCmdLineLastOption
};
extern KSMServer* the_server;
void IoErrorHandler ( IceConn iceConn)
{
the_server->ioError( iceConn );
}
bool writeTest(QCString 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[] )
{
QCString msg;
QCString path = getenv("HOME");
QCString 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 '"+QCString(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("KDETMP");
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 '"+QCString(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 '"+QCString(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);
QApplication a(argc, argv);
QCString qmsg(256+path.length());
qmsg.sprintf(msg.data(), path.data());
qmsg = msg_pre+qmsg+msg_post;
QMessageBox::critical(0, "KDE Installation Problem!",
QString::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(false, true); // 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;
}
QCString wm = args->getOption("windowmanager");
if ( wm.isEmpty() )
wm = "kwin";
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( QString::fromLatin1(wm), 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 );
QString 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();
}