summaryrefslogtreecommitdiffstats
path: root/kiostdetool/kioskrun.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kiostdetool/kioskrun.cpp')
-rw-r--r--kiostdetool/kioskrun.cpp1687
1 files changed, 1687 insertions, 0 deletions
diff --git a/kiostdetool/kioskrun.cpp b/kiostdetool/kioskrun.cpp
new file mode 100644
index 0000000..f5693ca
--- /dev/null
+++ b/kiostdetool/kioskrun.cpp
@@ -0,0 +1,1687 @@
+/*
+ * kioskrun.cpp
+ *
+ * Copyright (C) 2004 Waldo Bastian <bastian@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "kioskrun.h"
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <tqdir.h>
+#include <tqfile.h>
+
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <tdeconfig.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kprocess.h>
+#include <ksavefile.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+#include <kurl.h>
+#include <kuser.h>
+
+#include "kiosksync.h"
+
+#include <tdeio/netaccess.h>
+#define NETACCESS TDEIO::NetAccess
+
+#undef DEBUG_ENTRIES
+
+KioskRun *KioskRun::s_self = 0;
+
+KioskRun::KioskRun( TQObject* parent, const char* name)
+ : TQObject(parent, name), m_dcopClient(0), m_instance(0), m_localKdercConfig(0)
+{
+ m_noRestrictions = false;
+ m_forceSycocaUpdate = false;
+ s_self = this;
+ m_saveConfigCache.setAutoDelete(true);
+ m_immutableStatusCache.setAutoDelete(true);
+ m_homeDir = TQDir::homeDirPath()+"/.trinity-test";
+ TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
+ m_kderc = TQFile::decodeName(args->getOption("kderc"));
+ m_isRoot = (getuid() == 0);
+}
+
+KioskRun::~KioskRun()
+{
+ shutdownRuntimeEnv();
+ s_self = 0;
+}
+
+void
+KioskRun::setUser(const TQString &user)
+{
+ if (m_user == user) return;
+
+ shutdownRuntimeEnv();
+ shutdownConfigEnv();
+ m_user = user;
+}
+
+static void filterDupes(TQStringList &list)
+{
+ TQStringList tmp;
+ for(TQStringList::ConstIterator it = list.begin();
+ it != list.end(); ++it)
+ {
+ if (!tmp.contains(*it))
+ tmp.append(*it);
+ }
+ list = tmp;
+}
+
+void
+KioskRun::setKdeDirs(const TQStringList &dirs)
+{
+ if (m_kdeDirs == dirs) return;
+
+ shutdownRuntimeEnv();
+ shutdownConfigEnv();
+ m_kdeDirs = dirs;
+ TQStringList xdgDataDirs = TQStringList::split(':', TQFile::decodeName(getenv("XDG_DATA_DIRS")));
+ if (xdgDataDirs.isEmpty())
+ {
+ xdgDataDirs = TQStringList::split(':', TDEGlobal::dirs()->kfsstnd_prefixes());
+ xdgDataDirs.pop_front();
+ for(TQStringList::Iterator it = xdgDataDirs.begin();
+ it != xdgDataDirs.end(); ++it)
+ {
+ *it += "share";
+ }
+ xdgDataDirs << "/usr/local/share" << "/usr/share";
+ }
+
+ m_xdgDataDirs.clear();
+ for(TQStringList::ConstIterator it = dirs.begin();
+ it != dirs.end(); ++it)
+ {
+ m_xdgDataDirs.append(*it+"/share");
+ }
+ m_xdgDataDirs += xdgDataDirs;
+ filterDupes(m_xdgDataDirs);
+
+ TQStringList xdgConfigDirs = TQStringList::split(':', TQFile::decodeName(getenv("XDG_CONFIG_DIRS")));
+ if (xdgConfigDirs.isEmpty())
+ {
+ xdgConfigDirs << "/etc/xdg";
+ TQString sysconfMenuDir = TDEGlobal::dirs()->findDirs("xdgconf-menu", TQString()).last();
+ if (sysconfMenuDir.endsWith("/menus/"))
+ xdgConfigDirs << sysconfMenuDir.left(sysconfMenuDir.length()-7);
+
+ }
+
+ m_xdgConfigDirs.clear();
+ for(TQStringList::ConstIterator it = dirs.begin();
+ it != dirs.end(); ++it)
+ {
+ m_xdgConfigDirs.append(*it+"/etc/xdg");
+ }
+
+ m_xdgConfigDirs += xdgConfigDirs;
+ filterDupes(m_xdgConfigDirs);
+}
+
+void
+KioskRun::deleteDir(const TQString &dir)
+{
+ if (dir.length() <= 1) // Safety
+ return;
+ if (!dir.startsWith("/")) // Safety
+ return;
+ Q_ASSERT(dir.startsWith(m_homeDir));
+
+ TDEProcess proc;
+ proc << "rm" << "-rf" << dir;
+ proc.start(TDEProcess::Block);
+}
+
+void
+KioskRun::applyEnvironment(TDEProcess *p)
+{
+ p->setEnvironment("HOME", m_homeDir);
+ p->setEnvironment("TDEHOME", m_homeDir+"/.trinity");
+ p->setEnvironment("TDEROOTHOME", m_homeDir+"/.trinity");
+ p->setEnvironment("TDEDIRS", m_kdeDirs.join(":"));
+ p->setEnvironment("XDG_DATA_HOME", m_homeDir+"/.local/share");
+ p->setEnvironment("XDG_DATA_DIRS", m_xdgDataDirs.join(":"));
+ p->setEnvironment("XDG_CONFIG_HOME", m_homeDir+"/.config");
+ p->setEnvironment("XDG_CONFIG_DIRS", m_xdgConfigDirs.join(":"));
+ p->setEnvironment("DCOPAUTHORITY", m_homeDir+"/.trinity/DCOPserver");
+ p->setEnvironment("TDE_KIOSK_NO_PROFILES", "true");
+ if (m_noRestrictions)
+ p->setEnvironment("TDE_KIOSK_NO_RESTRICTIONS", "true");
+}
+
+bool
+KioskRun::prepare()
+{
+ bool result = setupRuntimeEnv();
+
+ deleteDir(m_configDir);
+ deleteDir(locateLocal("data"));
+ deleteDir(m_desktopPath);
+ deleteDir(m_homeDir+"/.config");
+ deleteDir(m_homeDir+"/.local/share");
+ return result;
+}
+
+void
+KioskRun::updateSycoca()
+{
+ // Force update
+ TQString sycocaUpdateFile = KioskRun::self()->locateLocal("services", "update_tdesycoca");
+ TQFile file(sycocaUpdateFile);
+ file.remove();
+ file.open(IO_WriteOnly);
+ file.close();
+
+ dcopRef("kded", "tdebuildsycoca").call("recreate");
+}
+
+TDEProcess*
+KioskRun::run(const TQString &cmd, const TQStringList &args)
+{
+ TDEProcess *proc = new TDEProcess(this);
+
+ applyEnvironment(proc);
+
+ *proc << cmd;
+ *proc << args;
+
+ proc->start(TDEProcess::NotifyOnExit);
+ return proc;
+}
+
+class SetEnv
+{
+public:
+ SetEnv(const char *key, const TQString &value) : m_key(key)
+ {
+ m_oldValue = getenv(m_key);
+ setenv(m_key, TQFile::encodeName(value), 1);
+ }
+
+ ~SetEnv()
+ {
+ if (m_oldValue.isEmpty())
+ setenv(m_key,"",1);
+ else
+ setenv(m_key,m_oldValue.data(),1);
+ }
+
+private:
+ const char* m_key;
+ TQCString m_oldValue;
+};
+
+void
+KioskRun::setupConfigEnv()
+{
+ if (m_instance) return;
+
+ // ::locateLocal must be called before we change the env. vars!
+ TQString newTmpDir = ::locateLocal("tmp", "kioskdir");
+ TQString newSocketDir = ::locateLocal("socket", "kioskdir");
+
+ SetEnv home("HOME", m_homeDir);
+ TQString kdeHome = m_homeDir+"/.trinity";
+ SetEnv tdehome("TDEHOME", kdeHome);
+ SetEnv tderoothome("TDEROOTHOME", kdeHome);
+ SetEnv tdedirs("TDEDIRS", m_kdeDirs.join(":"));
+ SetEnv xdgDataHome("XDG_DATA_HOME", m_homeDir+"/.local/share");
+ SetEnv xdgDataDirs("XDG_DATA_DIRS", m_xdgDataDirs.join(":"));
+ SetEnv xdgConfigHome("XDG_CONFIG_HOME", m_homeDir+"/.config");
+ SetEnv xdgConfigDirs("XDG_CONFIG_DIRS", m_xdgConfigDirs.join(":"));
+
+ ::mkdir(TQFile::encodeName(m_homeDir), 0700);
+ ::mkdir(TQFile::encodeName(kdeHome), 0700);
+
+ // Create temp & socket dirs.
+ char hostname[256];
+ hostname[0] = 0;
+ gethostname(hostname, 255);
+
+ TQString tmpDir = TQString("%1/%2-%3").arg(kdeHome).arg("tmp").arg(hostname);
+ deleteDir(tmpDir);
+ ::mkdir(TQFile::encodeName(newTmpDir), 0700);
+ ::symlink(TQFile::encodeName(newTmpDir), TQFile::encodeName(tmpDir));
+
+ TQString socketDir = TQString("%1/%2-%3").arg(kdeHome).arg("socket").arg(hostname);
+ deleteDir(socketDir);
+ ::mkdir(TQFile::encodeName(newSocketDir), 0700);
+ ::symlink(TQFile::encodeName(newSocketDir), TQFile::encodeName(socketDir));
+
+ m_configDir = TQString("%1/.trinity/share/config/").arg(m_homeDir);
+
+ m_instance = new TDEInstance("kioskrun");
+ (void) m_instance->dirs(); // Create TDEStandardDirs obj
+
+ m_desktopPath = m_homeDir + "/Desktop/";
+ m_desktopPath = m_instance->config()->readPathEntry( "Desktop", m_desktopPath);
+ m_desktopPath = TQDir::cleanDirPath( m_desktopPath );
+ if ( !m_desktopPath.endsWith("/") )
+ m_desktopPath.append('/');
+
+ {
+ SetEnv tdehome("TDEHOME", "-");
+ SetEnv tderoothome("TDEROOTHOME", "-");
+ SetEnv xdgDataHome("XDG_DATA_HOME", m_xdgDataDirs.first());
+ SetEnv xdgConfigHome("XDG_CONFIG_HOME", m_xdgConfigDirs.first());
+
+ m_saveInstance = new TDEInstance("kioskrun");
+ (void) m_saveInstance->dirs(); // Create TDEStandardDirs obj
+ }
+}
+
+TQString
+KioskRun::locate(const char *resource, const TQString &filename)
+{
+ setupConfigEnv();
+
+ return m_saveInstance->dirs()->findResource(resource, filename);
+}
+
+TQString
+KioskRun::locateSave(const char *resource, const TQString &filename)
+{
+ setupConfigEnv();
+
+ // split path from filename
+ int slash = filename.findRev('/')+1;
+ TQString dir = filename.left(slash);
+ TQString file = filename.mid(slash);
+ return m_saveInstance->dirs()->saveLocation(resource, dir, false) + file;
+}
+
+TQString
+KioskRun::locateLocal(const char *resource, const TQString &filename)
+{
+ setupConfigEnv();
+
+ // split path from filename
+ int slash = filename.findRev('/')+1;
+ TQString dir = filename.left(slash);
+ TQString file = filename.mid(slash);
+ return m_instance->dirs()->saveLocation(resource, dir, true) + file;
+}
+
+
+void
+KioskRun::shutdownConfigEnv()
+{
+ if (!m_instance) return;
+
+ delete m_instance;
+ m_instance = 0;
+}
+
+class ImmutableStatus
+{
+public:
+ bool m_fileScope;
+ TQDict<int> m_lines;
+ TQString m_tmpFile;
+ bool m_dirty;
+};
+
+
+bool
+KioskRun::isConfigImmutable(const TQString &filename, const TQString &group)
+{
+ (void) configFile(filename);
+ ImmutableStatus *status = m_immutableStatusCache.find(filename);
+ assert(status);
+ if (group.isEmpty())
+ return status->m_fileScope;
+
+ return status->m_lines.find(group);
+}
+
+void
+KioskRun::setConfigImmutable(const TQString &filename, const TQString &_group, bool bImmutable)
+{
+ (void) configFile(filename);
+ ImmutableStatus *status = m_immutableStatusCache.find(filename);
+ assert(status);
+ if (_group.isEmpty())
+ {
+ if (status->m_fileScope != bImmutable)
+ {
+ status->m_fileScope = bImmutable;
+ status->m_dirty = true;
+ m_forceSycocaUpdate = true;
+ }
+ }
+ else
+ {
+ TQString group = TQString("[%1]").arg(_group);
+ if (status->m_lines.find(group))
+ {
+ if (!bImmutable)
+ {
+ status->m_lines.remove(group);
+ status->m_dirty = true;
+ m_forceSycocaUpdate = true;
+ }
+ }
+ else
+ {
+ if (bImmutable)
+ {
+ status->m_lines.insert(group, (int *) 1);
+ status->m_dirty = true;
+ m_forceSycocaUpdate = true;
+ }
+ }
+ }
+}
+
+static void stripImmutable(TQString &ext)
+{
+ ext.replace("i", "");
+ if (ext == "[$]")
+ ext = TQString();
+}
+
+static void addImmutable(TQString &ext)
+{
+ ext.replace("[$", "[$i");
+}
+
+TQString
+KioskRun::saveImmutableStatus(const TQString &filename)
+{
+ ImmutableStatus *status = new ImmutableStatus;
+ status->m_fileScope = false;
+ status->m_dirty = false;
+ m_immutableStatusCache.insert(filename, status);
+
+ KTempFile tmp;
+ tmp.close();
+
+ TQString newPath = tmp.name();
+ status->m_tmpFile = tmp.name();
+
+ TQString path = m_saveInstance->dirs()->findResource("config", filename);
+ if (path.isEmpty())
+ return newPath; // Nothing to do
+
+ TQFile oldCfg(path);
+
+ if (!oldCfg.open( IO_ReadOnly ))
+ return newPath; // Error
+
+ TQFile newCfg(newPath);
+ if (!newCfg.open( IO_WriteOnly ))
+ return newPath; // Error
+
+ TQTextStream txtIn(&oldCfg);
+ txtIn.setEncoding(TQTextStream::UnicodeUTF8);
+
+ TQTextStream pTxtOut(&newCfg);
+ pTxtOut.setEncoding(TQTextStream::UnicodeUTF8);
+
+ TQRegExp immutable("(\\[\\$e?ie?\\])$");
+
+ // TODO: Use "group+key" instead of "key" as index, otherwise it might not be unique
+
+ while(! txtIn.atEnd())
+ {
+ TQString line = txtIn.readLine().stripWhiteSpace();
+
+ if (line.startsWith("#"))
+ {
+ // Comment, do nothing...
+ }
+ else if (line.startsWith("["))
+ {
+ int pos = immutable.searchRev(line);
+ if (pos != -1)
+ {
+ TQString group = line.left(pos);
+ TQString ext = immutable.cap(0);
+ stripImmutable(ext);
+ if (pos == 0)
+ {
+ status->m_fileScope = true;
+ continue;
+ }
+ status->m_lines.replace(group, (int *)1 );
+ line = group + ext;
+ }
+ }
+ else
+ {
+ int equal = line.find('=');
+ if (equal != -1)
+ {
+ TQString key = line.left(equal).stripWhiteSpace();
+ int pos = immutable.searchRev(key);
+ if (pos != -1)
+ {
+ key = key.left(pos);
+ TQString ext = immutable.cap(0);
+ stripImmutable(ext);
+ status->m_lines.replace(key, (int *)1 );
+ line = key + ext + line.mid(equal);
+ }
+ }
+ }
+
+ pTxtOut << line << endl;
+ }
+ oldCfg.close();
+ newCfg.close();
+
+ if (newCfg.status() != IO_Ok )
+ {
+ kdWarning() << "Error writing " << newPath << endl;
+ return newPath;
+ }
+ return newPath;
+}
+
+bool
+KioskRun::restoreImmutableStatus(const TQString &filename, bool force)
+{
+ ImmutableStatus *status = m_immutableStatusCache.take(filename);
+ if (!status)
+ {
+ kdDebug() << "KioskRun::restoreImmutableStatus(" << filename << ") status info missing" << endl;
+ return true;
+ }
+ if (!force && !status->m_dirty)
+ {
+ kdDebug() << "KioskRun::restoreImmutableStatus(" << filename << ") not changed" << endl;
+ delete status;
+ return true;
+ }
+ kdDebug() << "KioskRun::restoreImmutableStatus(" << filename << ") restoring" << endl;
+
+ TQString path = status->m_tmpFile;
+
+ KSaveFile newCfg(path);
+ if (newCfg.status() != 0)
+ {
+ delete status;
+ return true; // Continue
+ }
+
+ TQTextStream *pTxtOut = newCfg.textStream();
+ pTxtOut->setEncoding(TQTextStream::UnicodeUTF8);
+
+ TQRegExp option("(\\[\\$e\\])$");
+
+ if (status->m_fileScope)
+ {
+ kdDebug() << "Marking file " << filename << " immutable" << endl;
+ (*pTxtOut) << "[$i]" << endl;
+ }
+
+ TQFile oldCfg(path);
+ if (oldCfg.open( IO_ReadOnly ))
+ {
+
+ TQTextStream txtIn(&oldCfg);
+ txtIn.setEncoding(TQTextStream::UnicodeUTF8);
+
+ while(! txtIn.atEnd())
+ {
+ TQString line = txtIn.readLine().stripWhiteSpace();
+
+ if (line.startsWith("#"))
+ {
+ // Comment, do nothing...
+ }
+ else if (line.startsWith("["))
+ {
+ if (status->m_lines.take(line))
+ line += "[$i]";
+ }
+ else
+ {
+ int equal = line.find('=');
+ if (equal != -1)
+ {
+ TQString key = line.left(equal).stripWhiteSpace();
+ int pos = option.searchRev(key);
+ if (pos != -1)
+ {
+ key = key.left(pos);
+ TQString ext = option.cap(0);
+ if (status->m_lines.take(key))
+ addImmutable(ext);
+ line = key + ext + line.mid(equal);
+ }
+ else
+ {
+ if (status->m_lines.take(key))
+ line = key + "[$i]" + line.mid(equal);
+ }
+ }
+ }
+
+ (*pTxtOut) << line << endl;
+ }
+ oldCfg.close();
+ }
+
+ // Create remaining groups that were marked as immutable
+ TQDictIterator<int> it( status->m_lines );
+ for( ; it.current(); ++it )
+ {
+ TQString group = it.currentKey();
+ if ( it.current() )
+ (*pTxtOut) << endl << group << "[$i]" << endl;
+ }
+
+ if (!newCfg.close())
+ {
+ kdWarning() << "Error writing" << path << endl;
+ delete status;
+ return true; // Continue
+ }
+
+ TQString installLocation = m_saveInstance->dirs()->saveLocation("config", TQString(), false) + filename;
+ if (!install(path, installLocation))
+ {
+ m_immutableStatusCache.insert(filename, status); // Keep it around
+ return false;
+ }
+ delete status;
+ return true;
+}
+
+bool
+KioskRun::flushConfigCache()
+{
+ while ( !m_saveConfigCache.isEmpty() )
+ {
+ TQDictIterator<TDEConfig> it( m_saveConfigCache );
+ TQString file = it.currentKey();
+ TDEConfig *config = it.current();
+ bool dirty = config->isDirty();
+ config->sync(); // Save
+ if (!restoreImmutableStatus(file, dirty))
+ return false;
+ m_saveConfigCache.remove(file);
+ }
+
+ if (m_forceSycocaUpdate)
+ forceSycocaUpdate();
+ return true;
+}
+
+TDEConfig *
+KioskRun::configFile(const TQString &filename)
+{
+ TDEConfig *config = m_saveConfigCache.find(filename);
+ if (config)
+ return config;
+
+ kdDebug() << "KioskRun::configFile(" << filename << ") loading file" << endl;
+
+ setupConfigEnv();
+
+ TQString saveLocation = saveImmutableStatus(filename);
+ config = new KSimpleConfig(saveLocation);
+ m_saveConfigCache.insert(filename, config);
+
+ return config;
+}
+
+void
+KioskRun::makeMutable(bool bMutable)
+{
+ TDEConfig *config = configFile("kdeglobals");
+
+ m_noRestrictions = bMutable;
+ if (KDE::version() < TDE_MAKE_VERSION(3,2,4))
+ {
+ config->setGroup("KDE Action Restrictions");
+ if (bMutable)
+ {
+ KUser thisUser;
+ config->writeEntry("kiosk_exception", thisUser.loginName()+":"); // This user, all hosts
+ }
+ else
+ {
+ config->writeEntry("kiosk_exception", TQString());
+ }
+ }
+ // Propagate to tdeinit
+ dcopRef("tdelauncher", "tdelauncher").call("setLaunchEnv",
+ TQCString("TDE_KIOSK_NO_RESTRICTIONS"), TQCString(m_noRestrictions ? "true" : ""));
+
+ setConfigImmutable("kdeglobals", "KDE Action Restrictions", true);
+}
+
+TQStringList
+KioskRun::newConfigFiles()
+{
+ setupConfigEnv();
+
+ TQStringList exceptions;
+ exceptions << "tdeconf_updaterc";
+
+ TQStringList result;
+ TQDir dir(m_configDir);
+ dir.setFilter( TQDir::Files | TQDir::NoSymLinks );
+
+ const TQFileInfoList *list = dir.entryInfoList();
+ if (!list) return result;
+
+ TQFileInfoListIterator it( *list );
+ TQFileInfo *fi;
+ while ( (fi = it.current()) != 0 )
+ {
+ TQString file = fi->fileName();
+ if (!file.endsWith("~") && !exceptions.contains(file)) // Skip backup files & exceptions
+ result.append(file);
+ ++it;
+ }
+ return result;
+}
+
+void
+KioskRun::mergeConfigFile(const TQString &filename)
+{
+ TDEConfig *saveCfg = configFile(filename);
+
+ kdDebug() << "KioskRun::mergeConfigFile(" << (m_configDir + filename) << ")" << endl;
+ KSimpleConfig newCfg(m_configDir + filename);
+
+ TQStringList groups = newCfg.groupList();
+ for(TQStringList::ConstIterator it = groups.begin();
+ it != groups.end(); ++it)
+ {
+ saveCfg->setGroup(*it);
+ TQMap<TQString, TQString> map = newCfg.entryMap(*it);
+ for(TQMap<TQString, TQString>::Iterator it2 = map.begin();
+ it2 != map.end(); ++it2)
+ {
+#ifdef DEBUG_ENTRIES
+tqWarning("[%s] %s --> %s", (*it).latin1(), it2.key().latin1(), it2.data().latin1());
+#endif
+ saveCfg->writeEntry(it2.key(), it2.data());
+ }
+ }
+}
+
+bool
+KioskRun::setupRuntimeEnv()
+{
+ if (m_dcopClient) return true;
+
+ KioskRunProgressDialog dlg(kapp->mainWidget(), "kioskrun_progress",
+ i18n("Setting Up Configuration Environment"),
+ i18n("Setting up configuration environment."));
+
+ char hostname[256];
+ hostname[0] = 0;
+ gethostname(hostname, 255);
+ TQString cacheDir = TQString("%1/.trinity/cache-%2").arg(m_homeDir).arg(hostname);
+
+ deleteDir(cacheDir);
+ TDEStandardDirs::makeDir(cacheDir);
+ deleteDir(m_homeDir+"/.qt");
+ ::unlink(TQFile::encodeName(m_homeDir+".kderc"));
+
+
+ TQString iceAuth = TQString("%1/.ICEauthority").arg(TQDir::homeDirPath());
+ setenv("ICEAUTHORITY", TQFile::encodeName(iceAuth), 0); // Don't overwrite existing setting
+
+ TQString xAuth = TQString("%1/.Xauthority").arg(TQDir::homeDirPath());
+ setenv("XAUTHORITY", TQFile::encodeName(xAuth), 0); // Don't overwrite existing setting
+
+ TQString dcopServerFile = m_homeDir+"/.trinity/DCOPserver";
+
+ TDEProcess tdeinit;
+
+ applyEnvironment(&tdeinit);
+
+ tdeinit << "tdeinit";
+
+ connect(&tdeinit, TQT_SIGNAL(processExited(TDEProcess *)), &dlg, TQT_SLOT(slotFinished()));
+
+ tdeinit.start(TDEProcess::NotifyOnExit);
+
+ dlg.exec();
+
+ TQCString dcopSrv;
+ TQFile f(dcopServerFile);
+ if (f.open(IO_ReadOnly))
+ {
+ int size = TQMIN( 1024, f.size() ); // protection against a huge file
+ TQCString contents( size+1 );
+ if ( f.readBlock( contents.data(), size ) == size )
+ {
+ contents[size] = '\0';
+ int pos = contents.find('\n');
+ if ( pos == -1 ) // Shouldn't happen
+ dcopSrv = contents;
+ else
+ dcopSrv = contents.left( pos );
+ }
+ }
+
+ if (dcopSrv.isEmpty())
+ {
+ kdWarning() << "Error reading " << dcopServerFile << endl;
+ m_dcopClient = new DCOPClient;
+ shutdownRuntimeEnv();
+ return false;
+ }
+
+ m_dcopClient = new DCOPClient;
+ m_dcopClient->setServerAddress(dcopSrv);
+ unsetenv("DCOPSERVER"); // Don't propagate it
+ m_dcopClient->attach();
+ return true;
+}
+
+void
+KioskRun::shutdownRuntimeEnv()
+{
+ if (!m_dcopClient) return;
+
+ delete m_dcopClient;
+ m_dcopClient = 0;
+
+ TDEProcess tdeinit;
+ applyEnvironment(&tdeinit);
+
+ tdeinit << "tdeinit_shutdown";
+
+ tdeinit.start(TDEProcess::Block);
+
+ TDEProcess dcopserver;
+ applyEnvironment(&dcopserver);
+
+ dcopserver << "dcopserver_shutdown";
+
+ dcopserver.start(TDEProcess::Block);
+}
+
+DCOPRef
+KioskRun::dcopRef(const TQCString &appId, const TQCString &objId)
+{
+ if (!setupRuntimeEnv())
+ return DCOPRef();
+ DCOPRef ref(appId, objId);
+ ref.setDCOPClient(m_dcopClient);
+ return ref;
+}
+
+// Lookup the setting for a custom action
+bool
+KioskRun::lookupCustomAction(const TQString &action)
+{
+ TDEConfig *cfg = KioskRun::self()->configFile("kdeglobals");
+ cfg->setGroup("KDE Custom Restrictions");
+ return cfg->readBoolEntry(action, false);
+}
+
+// Change the setting for a custom action
+void
+KioskRun::setCustomAction(const TQString &action, bool checked)
+{
+ TDEConfig *cfg = KioskRun::self()->configFile("kdeglobals");
+ cfg->setGroup("KDE Custom Restrictions");
+ if (cfg->readBoolEntry(action, false) != checked)
+ {
+ cfg->writeEntry(action, checked);
+ KioskRun::self()->scheduleSycocaUpdate();
+
+ if (action == "restrict_file_browsing")
+ {
+ setCustomRestrictionFileBrowsing(checked);
+ }
+ }
+}
+
+// Create directory
+bool
+KioskRun::createDir(const TQString &dir)
+{
+ if (TQDir(dir).exists())
+ return true; // Exists already
+
+ KURL dest;
+ if (!m_isRoot || (m_user != "root"))
+ {
+ dest.setProtocol("fish");
+ dest.setHost("localhost");
+ dest.setUser(m_user);
+ }
+ dest.setPath(dir);
+
+ if (dir.length() > 1)
+ {
+ KURL parent = dest.upURL();
+
+ bool result = createDir(parent.path());
+ if (!result)
+ return false;
+ }
+
+ do
+ {
+ if (NETACCESS::exists(dest, false, kapp->mainWidget()))
+ return true;
+
+ bool result = NETACCESS::mkdir(dest, kapp->mainWidget(), 0755);
+ if (result == true)
+ return true;
+
+ TQString error = NETACCESS::lastErrorString();
+ TQString msg;
+
+ if (error.isEmpty())
+ msg = i18n("<qt>The directory <b>%1</b> could not be created because of an unspecified problem.<p>")
+ .arg(dir);
+ else
+ msg = i18n("<qt>The directory <b>%1</b> could not be created because of the following problem:"
+ "<p>%2<p>")
+ .arg(dir, NETACCESS::lastErrorString());
+
+ msg += i18n("Without this directory your changes can not be saved.<p>"
+ "Do you want to retry creating the directory or abort the saving of changes?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(),
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return false;
+
+ // Maybe the user created it in the meantime
+ if (TQDir(dir).exists())
+ return true; // Exists already
+ }
+ while (true);
+ return false;
+}
+
+// Create directory
+bool
+KioskRun::createRemoteDirRecursive(const KURL &dest, bool ask)
+{
+ if (NETACCESS::exists(dest, false, kapp->mainWidget()))
+ return true;
+
+ KURL parent = dest.upURL();
+
+ if (NETACCESS::exists(dest, false, kapp->mainWidget()))
+ {
+ return createRemoteDir(dest);
+ }
+
+ if (ask)
+ {
+ // Parent doesn't exist,
+ int result = KMessageBox::warningContinueCancel(kapp->mainWidget(),
+ i18n("<qt>The directory <b>%1</b> does not yet exist. "
+ "Do you want to create it?").arg(parent.prettyURL()), TQString(),
+ i18n("Create &Dir"));
+ if (result != KMessageBox::Continue)
+ return false;
+ }
+
+ TQString path = dest.path(1);
+ int i = 0;
+ while ( (i = path.find('/', i+1)) != -1)
+ {
+ parent.setPath(path.left(i+1));
+ if (! createRemoteDir(parent))
+ return false;
+ }
+ return true;
+}
+
+// Create directory
+bool
+KioskRun::createRemoteDir(const KURL &dest)
+{
+ do
+ {
+ if (NETACCESS::exists(dest, false, kapp->mainWidget()))
+ return true;
+
+ if (NETACCESS::mkdir(dest, kapp->mainWidget(), 0755))
+ return true;
+
+#if KDE_IS_VERSION(3,2,91)
+ if (NETACCESS::lastError() == TDEIO::ERR_DIR_ALREADY_EXIST)
+ return true;
+#endif
+
+ //TODO Check directory already exists error
+ TQString error = NETACCESS::lastErrorString();
+ TQString msg;
+
+ if (error.isEmpty())
+ msg = i18n("<qt>The directory <b>%1</b> could not be created because of an unspecified problem.<p>")
+ .arg(dest.prettyURL());
+ else
+ msg = i18n("<qt>The directory <b>%1</b> could not be created because of the following problem:"
+ "<p>%2<p>")
+ .arg(dest.prettyURL(), NETACCESS::lastErrorString());
+
+ msg += i18n("Without this directory your files can not be uploaded.<p>"
+ "Do you want to retry creating the directory or abort uploading?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(),
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return false;
+ }
+ while (true);
+ return false;
+}
+
+// Install file
+bool
+KioskRun::install(const TQString &file, const TQString &destination)
+{
+ KURL dest;
+ if (!m_isRoot || (m_user != "root"))
+ {
+ dest.setProtocol("fish");
+ dest.setHost("localhost");
+ dest.setUser(m_user);
+ }
+ dest.setPath(destination);
+
+ if (!createDir(dest.upURL().path()))
+ return false;
+
+ do
+ {
+ KURL src;
+ src.setPath(file);
+ bool result = NETACCESS::file_copy(src, dest, 0644, true, false, kapp->mainWidget());
+ if (result == true)
+ {
+ ::unlink(TQFile::encodeName(file));
+ return true;
+ }
+
+ TQString error = NETACCESS::lastErrorString();
+ TQString msg;
+ if (error.isEmpty())
+ msg = i18n("<qt>The file <b>%1</b> could not be installed because of an unspecified problem.")
+ .arg(destination);
+ else
+ msg = i18n("<qt>The file <b>%1</b> could not be installed because of the following problem:"
+ "<p>%2<p>")
+ .arg(destination, NETACCESS::lastErrorString());
+
+ msg += i18n("Do you want to retry the installation or abort the saving of changes?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(),
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return false;
+ }
+ while (true);
+ return false;
+}
+
+// Upload file
+bool
+KioskRun::uploadRemote(const TQString &file, const KURL &dest)
+{
+ do
+ {
+ KURL src;
+ src.setPath(file);
+ bool result = NETACCESS::file_copy(src, dest, 0644, true, false, kapp->mainWidget());
+ if (result == true)
+ return true;
+
+ TQString error = NETACCESS::lastErrorString();
+ TQString msg;
+ if (error.isEmpty())
+ msg = i18n("<qt>The file <b>%1</b> could not be uploaded to <b>%2</b> because of an unspecified problem.")
+ .arg(file, dest.prettyURL());
+ else
+ msg = i18n("<qt>The file <b>%1</b> could not be uploaded to <b>%2</b> because of the following problem:"
+ "<p>%3<p>")
+ .arg(file, dest.prettyURL(),NETACCESS::lastErrorString());
+
+ msg += i18n("Do you want to retry or abort the uploading?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(),
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return false;
+ }
+ while (true);
+ return false;
+}
+
+// Remove file
+bool
+KioskRun::remove(const TQString &destination)
+{
+ KURL dest;
+ if (!m_isRoot || (m_user != "root"))
+ {
+ dest.setProtocol("fish");
+ dest.setHost("localhost");
+ dest.setUser(m_user);
+ }
+ dest.setPath(destination);
+
+ return NETACCESS::del(dest, kapp->mainWidget());
+}
+
+// Move file or directory
+bool
+KioskRun::move(const TQString &source, const TQString &destination, const TQStringList &files)
+{
+ KURL src;
+ KURL dest;
+ if (!m_isRoot || (m_user != "root"))
+ {
+ dest.setProtocol("fish");
+ dest.setHost("localhost");
+ dest.setUser(m_user);
+ src.setProtocol("fish");
+ src.setHost("localhost");
+ src.setUser(m_user);
+ }
+
+ for(TQStringList::ConstIterator it = files.begin();
+ it != files.end(); ++it)
+ {
+ src.setPath(source + *it);
+ dest.setPath(destination + *it);
+
+kdDebug() << "Moving " << src << " --> " << dest << endl;
+ if (!createRemoteDirRecursive(dest.upURL(), false))
+ return false;
+
+ if (!NETACCESS::file_move(src, dest, -1, true, false, kapp->mainWidget()))
+ {
+ // TODO add error message + retry
+ return false;
+ }
+ }
+ return true;
+}
+
+// Read information of profile @p profile
+void
+KioskRun::getProfileInfo(const TQString &profile, TQString &description, TQString &installDir, TQString &installUser)
+{
+ TDEConfig *config = kapp->config();
+
+ TQString defaultInstallDir = getProfilePrefix();
+ if (defaultInstallDir.isEmpty())
+ {
+ defaultInstallDir = "/etc/kde-profile/";
+ }
+ if (!defaultInstallDir.endsWith("/"))
+ defaultInstallDir.append("/");
+ TQString tmp = profile;
+ tmp.replace(" ", "_");
+ tmp.replace(":", "_");
+ tmp.replace("/", "_");
+ defaultInstallDir += tmp+"/";
+
+ TQString group = TQString("Directories-%1").arg(profile);
+ config->setGroup(group);
+
+ installDir = config->readEntry("prefixes", defaultInstallDir);
+ if (!installDir.endsWith("/"))
+ installDir.append("/");
+
+ TQString profileInfoFile = installDir + ".kdeprofile";
+ if (TQFile::exists(profileInfoFile))
+ {
+ KSimpleConfig profileInfo(profileInfoFile, true);
+ description = profileInfo.readEntry("Description");
+ installUser = profileInfo.readEntry("InstallUser", "root");
+ return;
+ }
+
+ TQString defaultDescription;
+ if (profile == "default")
+ defaultDescription = i18n("Default profile");
+
+ description = config->readEntry("ProfileDescription", defaultDescription);
+ installUser = config->readEntry("ProfileInstallUser", "root");
+}
+
+KSimpleConfig *
+KioskRun::openKderc()
+{
+ if (m_localKdercConfig)
+ return m_localKdercConfig;
+
+ KURL settingsUrl;
+ settingsUrl.setPath(m_kderc);
+
+ m_localKderc = ::locateLocal("tmp", "kderc_"+kapp->randomString(5));
+ ::unlink(TQFile::encodeName(m_localKderc));
+
+ KURL localCopyUrl;
+ localCopyUrl.setPath(m_localKderc);
+
+ if (TQFile::exists(settingsUrl.path()))
+ {
+
+ while (!NETACCESS::copy(settingsUrl, localCopyUrl, kapp->mainWidget()))
+ {
+ TQString error = NETACCESS::lastErrorString();
+ TQString msg;
+ if (error.isEmpty())
+ msg = i18n("<qt>The file <b>%1</b> could not be accessed because of an unspecified problem.")
+ .arg(settingsUrl.path());
+ else
+ msg = i18n("<qt>The file <b>%1</b> could not be accessed because of the following problem:"
+ "<p>%2<p>")
+ .arg(settingsUrl.path(), error);
+
+ msg += i18n("Do you want to retry the operation or abort the saving of changes?</qt>");
+
+ int msgResult = KMessageBox::warningYesNo(kapp->mainWidget(), msg, TQString(),
+ i18n("&Retry"), i18n("&Abort"));
+
+ if (msgResult == KMessageBox::No)
+ return 0;
+ }
+ }
+
+ m_localKdercConfig = new KSimpleConfig(m_localKderc);
+ return m_localKdercConfig;
+}
+
+bool
+KioskRun::closeKderc()
+{
+ if (!m_localKdercConfig)
+ return false;
+ m_localKdercConfig->sync();
+ delete m_localKdercConfig;
+ m_localKdercConfig = 0;
+
+ TQString saveUser = m_user;
+ m_user = "root";
+ bool result = install(m_localKderc, m_kderc);
+ m_localKderc = TQString();
+ m_user = saveUser;
+ kapp->config()->reparseConfiguration();
+ return result;
+}
+
+// Store information for profile @p profile
+bool
+KioskRun::setProfileInfo(const TQString &profile, const TQString &description, const TQString &_installDir, const TQString &installUser, bool deleteProfile, bool deleteFiles)
+{
+ TQString installDir = _installDir;
+ if (!installDir.endsWith("/"))
+ installDir.append("/");
+
+ TQString saveProfileInfo = installDir + ".kdeprofile";
+ KSimpleConfig profileInfo(saveProfileInfo, true);
+ TQString oldDescription = profileInfo.readEntry("Description");
+ TQString oldInstallUser = profileInfo.readEntry("InstallUser");
+ if (deleteProfile && !installDir.isEmpty())
+ {
+ bool result = true;
+ KioskSync profileDir(kapp->mainWidget());
+ profileDir.addDir(installDir, KURL());
+ TQStringList allFiles = profileDir.listFiles();
+ allFiles.remove(".kdeprofile");
+ if (allFiles.isEmpty())
+ {
+ if (TQDir(installDir).exists())
+ {
+ m_user = installUser;
+ remove(installDir);
+ m_user = TQString();
+ }
+ }
+ else if (deleteFiles)
+ {
+ int msgResult = KMessageBox::warningYesNoCancelList(kapp->mainWidget(),
+ i18n("<qt>The profile directory <b>%1</b> contains the following files, "
+ "do you wish to delete these files?").arg(installDir),
+ allFiles,
+ i18n("Deleting Profile"),
+#if KDE_IS_VERSION(3,2,91)
+ KStdGuiItem::del(),
+#else
+ i18n("&Delete"),
+#endif
+ i18n("&Keep Files")
+ );
+ switch(msgResult)
+ {
+ case KMessageBox::Yes:
+ // Delete files
+ m_user = installUser;
+ result = remove(installDir);
+ m_user = TQString();
+ if (!result)
+ return false;
+ break;
+
+ case KMessageBox::No:
+ // Keep files
+ break;
+
+ default:
+ // Cancel
+ return false;
+ }
+ }
+
+ m_user = installUser;
+ if (TQFile::exists(saveProfileInfo))
+ result = remove(saveProfileInfo);
+ m_user = TQString();
+ if (!result)
+ return false;
+ }
+ else if ((description != oldDescription) ||
+ (installUser != oldInstallUser))
+ {
+ TQString localProfileInfo = ::locateLocal("tmp", "kdeprofile_"+kapp->randomString(5));
+ ::unlink(TQFile::encodeName(localProfileInfo));
+ KSimpleConfig newProfileInfo(localProfileInfo);
+ newProfileInfo.writeEntry("Description", description);
+ newProfileInfo.writeEntry("InstallUser", installUser);
+ newProfileInfo.sync();
+ bool result = install(localProfileInfo, saveProfileInfo);
+ if (!result)
+ return false;
+ }
+
+ KUser thisUser;
+ TQString newAdmin = thisUser.loginName()+":"; // This user, all hosts
+
+ TDEConfig *config = kapp->config();
+
+ config->setGroup("Directories");
+ TQString oldAdmin = config->readEntry("kioskAdmin");
+
+ TQString group = TQString("Directories-%1").arg(profile);
+ config->setGroup(group);
+
+ if ((installDir == config->readEntry("prefixes")) &&
+ (newAdmin == oldAdmin) &&
+ !deleteProfile)
+ return true; // Nothing to do
+
+ KSimpleConfig *cfg = openKderc();
+ if (!cfg)
+ return false;
+
+ cfg->setGroup("Directories");
+ cfg->writeEntry("kioskAdmin", newAdmin);
+
+ if (deleteProfile)
+ {
+ cfg->deleteGroup(group);
+ }
+ else
+ {
+ cfg->setGroup(group);
+ // TODO: update prefixes
+ cfg->writeEntry("prefixes", installDir);
+ }
+ cfg->sync();
+
+ return closeKderc();
+}
+
+bool
+KioskRun::deleteProfile(const TQString &profile, bool deleteFiles)
+{
+ TQString description;
+ TQString installDir;
+ TQString installUser;
+ getProfileInfo(profile, description, installDir, installUser);
+ return setProfileInfo(profile, description, installDir, installUser, true, deleteFiles);
+}
+
+// Read profile prefix
+TQString
+KioskRun::getProfilePrefix()
+{
+ TDEConfig *config = kapp->config();
+
+ config->setGroup("Directories");
+
+ TQString prefix = config->readEntry("profileDirsPrefix");
+ if (!prefix.isEmpty() && !prefix.endsWith("/"))
+ prefix.append('/');
+ return prefix;
+}
+
+// Store profile prefix
+bool
+KioskRun::setProfilePrefix(const TQString &_prefix)
+{
+ TQString prefix = _prefix;
+
+ if (!prefix.isEmpty() && !prefix.endsWith("/"))
+ prefix.append('/');
+
+ if (prefix == getProfilePrefix())
+ return true; // Nothing to do
+
+ KSimpleConfig *cfg = openKderc();
+ if (!cfg)
+ return false;
+
+ cfg->setGroup("Directories");
+ cfg->writeEntry("profileDirsPrefix", prefix);
+
+ cfg->sync();
+
+ return closeKderc();
+}
+
+TQString
+KioskRun::newProfile()
+{
+ TQString profilePrefix = getProfilePrefix();
+
+ TDEConfig *config = kapp->config();
+ for(int p = 1; p; p++)
+ {
+ TQString profile = TQString("profile%1").arg(p);
+ TQString group = TQString("Directories-%1").arg(profile);
+ if (!config->hasGroup(group))
+ {
+ if (profilePrefix.isEmpty())
+ return profile;
+
+ TQString profileDir = profilePrefix + profile;
+ if (!TQDir(profileDir).exists() && !TQFile::exists(profileDir))
+ return profile;
+
+ // Keep on looking...
+ }
+ }
+ return TQString();
+}
+
+TQStringList
+KioskRun::allProfiles()
+{
+ TDEConfig *config = kapp->config();
+ TQStringList groups = config->groupList();
+ TQStringList profiles;
+ TQStringList directories;
+ for(TQStringList::ConstIterator it = groups.begin();
+ it != groups.end(); ++it)
+ {
+ if (!(*it).startsWith("Directories-"))
+ continue;
+ profiles.append((*it).mid(12));
+ config->setGroup(*it);
+ TQString installDir = config->readEntry("prefixes");
+ if (!installDir.endsWith("/"))
+ installDir.append("/");
+ directories.append(installDir);
+ }
+
+ TQString profilePrefix = getProfilePrefix();
+ if (!profilePrefix.isEmpty())
+ {
+ TQDir dir(profilePrefix, TQString(), TQDir::Unsorted, TQDir::Dirs);
+ TQStringList profileDirs = dir.entryList();
+ for(TQStringList::ConstIterator it = profileDirs.begin();
+ it != profileDirs.end(); ++it)
+ {
+ if ((*it).startsWith("."))
+ continue;
+ TQString dir = profilePrefix + *it + "/";
+ if (directories.contains(dir))
+ {
+ kdDebug() << "Skipping " << dir << ", dir already listed" << endl;
+ continue;
+ }
+ if (profiles.contains(*it))
+ {
+ kdDebug() << "Skipping " << dir << ", profile [" << (*it) << "] already listed" << endl;
+ continue;
+ }
+
+ if (!TQFile::exists(dir+".kdeprofile"))
+ {
+ kdDebug() << "Skipping " << dir << ", no profile info" << endl;
+ continue;
+ }
+ profiles.append(*it);
+ directories.append(dir);
+ }
+ }
+
+ if (!profiles.contains("default"))
+ profiles.append("default");
+
+ return profiles;
+}
+
+void
+KioskRun::getUserProfileMappings( ProfileMapping &groups, ProfileMapping &users, TQStringList &groupOrder)
+{
+ groups.clear();
+ users.clear();
+
+ TDEConfig *config = kapp->config();
+ config->setGroup("Directories");
+ TQString mapFile = config->readEntry("userProfileMapFile");
+
+ if (mapFile.isEmpty() || !TQFile::exists(mapFile))
+ return;
+
+ KSimpleConfig mapCfg(mapFile, true);
+
+ mapCfg.setGroup("General");
+ groupOrder = mapCfg.readListEntry("groups");
+
+ mapCfg.setGroup("Groups");
+ for ( TQStringList::ConstIterator it = groupOrder.begin();
+ it != groupOrder.end(); ++it )
+ {
+ TQString group = *it;
+ TQStringList profiles = mapCfg.readListEntry(group);
+ if (!profiles.isEmpty())
+ groups.insert(group, profiles);
+ }
+
+ TQMap<TQString, TQString> cfg_users = mapCfg.entryMap("Users");
+ for ( TQMap<TQString, TQString>::Iterator it = cfg_users.begin();
+ it != cfg_users.end(); ++it )
+ {
+ TQString user = it.key();
+ TQStringList profiles = TQStringList::split(",", it.data());
+ if (!profiles.isEmpty())
+ users.insert(user, profiles);
+ }
+}
+
+bool
+KioskRun::setUserProfileMappings( const ProfileMapping &groups, const ProfileMapping &users, const TQStringList &groupOrder)
+{
+ TDEConfig *config = kapp->config();
+ config->setGroup("Directories");
+ TQString mapFile = config->readEntry("userProfileMapFile");
+ if (mapFile.isEmpty())
+ {
+ mapFile = "/etc/kde-user-profile";
+
+ KSimpleConfig *cfg = openKderc();
+ if (!cfg)
+ return false;
+
+ cfg->setGroup("Directories");
+ cfg->writeEntry("userProfileMapFile", mapFile);
+ if (!closeKderc())
+ return false;
+ }
+
+ TQString localMapFile = ::locateLocal("tmp", "kde-user-profile_"+kapp->randomString(5));
+ ::unlink(TQFile::encodeName(localMapFile));
+
+ KSimpleConfig mapConfig(localMapFile);
+
+ mapConfig.setGroup("General");
+ mapConfig.writeEntry("groups", groupOrder);
+
+ KioskRun::ProfileMapping::ConstIterator it;
+
+ mapConfig.setGroup("Groups");
+ for ( it = groups.begin(); it != groups.end(); ++it )
+ {
+ TQString group = it.key();
+ mapConfig.writeEntry(group, it.data());
+ }
+ mapConfig.setGroup("Users");
+ for ( it = users.begin(); it != users.end(); ++it )
+ {
+ TQString user = it.key();
+ mapConfig.writeEntry(user, it.data());
+ }
+
+ mapConfig.sync();
+
+ TQString saveUser = m_user;
+ m_user = "root";
+ bool result = install(localMapFile, mapFile);
+ m_user = saveUser;
+ return result;
+}
+
+void
+KioskRun::forceSycocaUpdate()
+{
+ // Touch $TDEDIR/share/services/update_tdesycoca
+ KTempFile tempFile;
+ tempFile.close();
+ TQString sycocaUpdateFile = locateSave("services", "update_tdesycoca");
+ remove(sycocaUpdateFile);
+ install(tempFile.name(), sycocaUpdateFile);
+}
+
+void
+KioskRun::scheduleSycocaUpdate()
+{
+ m_forceSycocaUpdate = true;
+}
+
+void
+KioskRun::setCustomRestrictionFileBrowsing(bool restrict)
+{
+ TQString file = "kdeglobals";
+ TQString group = "KDE URL Restrictions";
+ TDEConfig *cfg = KioskRun::self()->configFile(file);
+ cfg->setGroup(group);
+ int count = cfg->readNumEntry("rule_count");
+ TQStringList urlRestrictions;
+ for(int i = 0; i < count; i++)
+ {
+ TQString key = TQString("rule_%1").arg(i+1);
+ if (cfg->hasKey(key))
+ urlRestrictions.append(cfg->readEntry(key));
+ }
+
+ TQStringList newRestrictions;
+ newRestrictions << "list,,,,file,,,false";
+ newRestrictions << "list,,,,file,,$HOME,true";
+
+ for(TQStringList::ConstIterator it = newRestrictions.begin();
+ it != newRestrictions.end(); ++it)
+ {
+ urlRestrictions.remove(*it);
+ }
+
+ if (restrict)
+ {
+ newRestrictions += urlRestrictions;
+ urlRestrictions = newRestrictions;
+ }
+
+ count = urlRestrictions.count();
+ cfg->writeEntry("rule_count", count);
+
+ for(int i = 0; i < count; i++)
+ {
+ TQString key = TQString("rule_%1").arg(i+1);
+ cfg->writeEntry(key, urlRestrictions[i]);
+ }
+ KioskRun::self()->setConfigImmutable(file, group, true);
+}
+
+KioskRunProgressDialog::KioskRunProgressDialog(TQWidget *parent, const char *name,
+ const TQString &caption, const TQString &text)
+ : KProgressDialog(parent, name, caption, text, true)
+{
+ connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotProgress()));
+ progressBar()->setTotalSteps(20);
+ m_timeStep = 700;
+ m_timer.start(m_timeStep);
+ setAutoClose(false);
+}
+
+void
+KioskRunProgressDialog::slotProgress()
+{
+ int p = progressBar()->progress();
+ if (p == 18)
+ {
+ progressBar()->reset();
+ progressBar()->setProgress(1);
+ m_timeStep = m_timeStep * 2;
+ m_timer.start(m_timeStep);
+ }
+ else
+ {
+ progressBar()->setProgress(p+1);
+ }
+}
+
+void
+KioskRunProgressDialog::slotFinished()
+{
+ progressBar()->setProgress(20);
+ m_timer.stop();
+ TQTimer::singleShot(1000, this, TQT_SLOT(close()));
+}
+
+
+#include "kioskrun.moc"
+