diff options
Diffstat (limited to 'kiostdetool/kioskrun.cpp')
-rw-r--r-- | kiostdetool/kioskrun.cpp | 1687 |
1 files changed, 0 insertions, 1687 deletions
diff --git a/kiostdetool/kioskrun.cpp b/kiostdetool/kioskrun.cpp deleted file mode 100644 index f5693ca..0000000 --- a/kiostdetool/kioskrun.cpp +++ /dev/null @@ -1,1687 +0,0 @@ -/* - * 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" - |