kdecore Library API Documentation

kstandarddirs.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 1999 Sirtaj Singh Kang <taj@kde.org>
00003    Copyright (C) 1999 Stephan Kulow <coolo@kde.org>
00004    Copyright (C) 1999 Waldo Bastian <bastian@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License version 2 as published by the Free Software Foundation.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 /*
00022  * Author: Stephan Kulow <coolo@kde.org> and Sirtaj Singh Kang <taj@kde.org>
00023  * Version: $Id: kstandarddirs.cpp,v 1.182.2.4 2004/09/13 13:04:15 waba Exp $
00024  * Generated:   Thu Mar  5 16:05:28 EST 1998
00025  */
00026 
00027 #include "config.h"
00028 
00029 #include <stdlib.h>
00030 #include <assert.h>
00031 #include <errno.h>
00032 #ifdef HAVE_SYS_STAT_H
00033 #include <sys/stat.h>
00034 #endif
00035 #include <sys/types.h>
00036 #include <dirent.h>
00037 #include <pwd.h>
00038 #include <grp.h>
00039 
00040 #include <qregexp.h>
00041 #include <qasciidict.h>
00042 #include <qdict.h>
00043 #include <qdir.h>
00044 #include <qfileinfo.h>
00045 #include <qstring.h>
00046 #include <qstringlist.h>
00047 
00048 #include "kstandarddirs.h"
00049 #include "kconfig.h"
00050 #include "kdebug.h"
00051 #include "kinstance.h"
00052 #include "kshell.h"
00053 #include "ksimpleconfig.h"
00054 #include "kuser.h"
00055 #include <sys/param.h>
00056 #include <unistd.h>
00057 
00058 bool have_custom_path_suffix = false;
00059 bool path_suffix_customized = false;
00060 QString custom_path_suffix("/");
00061 QString addCustomPathSuffix(QString prefix, QString alternate_suffix = QString::null )
00062 {
00063     if( ! have_custom_path_suffix )
00064     {
00065     QString standard_menu_user( QDir::homeDirPath() + "/.menu/disable_customization" );
00066     QString custom_menu_user( QDir::homeDirPath() + "/.menu/enable_customization" );
00067     QString standard_menu_system( "/etc/menu/disable_customization" );
00068 
00069         if( ! QFile(standard_menu_user).exists())
00070     {
00071         if( QFile(custom_menu_user).exists() )
00072         {
00073         custom_path_suffix = "-custom/";
00074             path_suffix_customized = true;
00075         }
00076             else
00077         {
00078         if( ! QFile(standard_menu_system).exists() )
00079         {
00080             custom_path_suffix = "-custom/";
00081                 path_suffix_customized = true;
00082         }
00083         }
00084     }
00085     have_custom_path_suffix = true;
00086     }
00087 
00088     if( path_suffix_customized )
00089     {
00090     if( alternate_suffix.isEmpty() )
00091             return prefix + custom_path_suffix;
00092     else
00093             return prefix + alternate_suffix;
00094     }
00095     else
00096     {
00097         return prefix + custom_path_suffix;
00098     }
00099 }
00100 
00101 template class QDict<QStringList>;
00102 
00103 class KStandardDirs::KStandardDirsPrivate
00104 {
00105 public:
00106    KStandardDirsPrivate()
00107     : restrictionsActive(false),
00108       dataRestrictionActive(false)
00109    { }
00110 
00111    bool restrictionsActive;
00112    bool dataRestrictionActive;
00113    QAsciiDict<bool> restrictions;
00114    QStringList xdgdata_prefixes;
00115    QStringList xdgconf_prefixes;
00116 };
00117 
00118 static const char* const types[] = {"html", "icon", "apps", "sound",
00119                   "data", "locale", "services", "mime",
00120                   "servicetypes", "config", "exe",
00121                   "wallpaper", "lib", "pixmap", "templates",
00122                   "module", "qtplugins",
00123                   "xdgdata-apps", "xdgdata-dirs", "xdgconf-menu",
00124                               "kcfg", 0 };
00125 
00126 static int tokenize( QStringList& token, const QString& str,
00127         const QString& delim );
00128 
00129 KStandardDirs::KStandardDirs( ) : addedCustoms(false)
00130 {
00131     d = new KStandardDirsPrivate;
00132     dircache.setAutoDelete(true);
00133     relatives.setAutoDelete(true);
00134     absolutes.setAutoDelete(true);
00135     savelocations.setAutoDelete(true);
00136     addKDEDefaults();
00137 }
00138 
00139 KStandardDirs::~KStandardDirs()
00140 {
00141     delete d;
00142 }
00143 
00144 bool KStandardDirs::isRestrictedResource(const char *type, const QString& relPath) const
00145 {
00146    if (!d || !d->restrictionsActive)
00147       return false;
00148 
00149    if (d->restrictions[type])
00150       return true;
00151 
00152    if (strcmp(type, "data")==0)
00153    {
00154       applyDataRestrictions(relPath);
00155       if (d->dataRestrictionActive)
00156       {
00157          d->dataRestrictionActive = false;
00158          return true;
00159       }
00160    }
00161    return false;
00162 }
00163 
00164 void KStandardDirs::applyDataRestrictions(const QString &relPath) const
00165 {
00166    QString key;
00167    int i = relPath.find('/');
00168    if (i != -1)
00169       key = "data_"+relPath.left(i);
00170    else
00171       key = "data_"+relPath;
00172 
00173    if (d && d->restrictions[key.latin1()])
00174       d->dataRestrictionActive = true;
00175 }
00176 
00177 
00178 QStringList KStandardDirs::allTypes() const
00179 {
00180     QStringList list;
00181     for (int i = 0; types[i] != 0; ++i)
00182         list.append(QString::fromLatin1(types[i]));
00183     return list;
00184 }
00185 
00186 static void priorityAdd(QStringList &prefixes, const QString& dir, bool priority)
00187 {
00188     if (priority && !prefixes.isEmpty())
00189     {
00190         // Add in front but behind $KDEHOME
00191         QStringList::iterator it = prefixes.begin();
00192         it++;
00193         prefixes.insert(it, 1, dir);
00194     }
00195     else
00196     {
00197         prefixes.append(dir);
00198     }
00199 }
00200 
00201 void KStandardDirs::addPrefix( const QString& _dir )
00202 {
00203     addPrefix(_dir, false);
00204 }
00205 
00206 void KStandardDirs::addPrefix( const QString& _dir, bool priority )
00207 {
00208     if (_dir.isEmpty())
00209     return;
00210 
00211     QString dir = _dir;
00212     if (dir.at(dir.length() - 1) != '/')
00213     dir += '/';
00214 
00215     if (!prefixes.contains(dir)) {
00216         priorityAdd(prefixes, dir, priority);
00217     dircache.clear();
00218     }
00219 }
00220 
00221 void KStandardDirs::addXdgConfigPrefix( const QString& _dir )
00222 {
00223     addXdgConfigPrefix(_dir, false);
00224 }
00225 
00226 void KStandardDirs::addXdgConfigPrefix( const QString& _dir, bool priority )
00227 {
00228     if (_dir.isEmpty())
00229     return;
00230 
00231     QString dir = _dir;
00232     if (dir.at(dir.length() - 1) != '/')
00233     dir += '/';
00234 
00235     if (!d->xdgconf_prefixes.contains(dir)) {
00236         priorityAdd(d->xdgconf_prefixes, dir, priority);
00237     dircache.clear();
00238     }
00239 }
00240 
00241 void KStandardDirs::addXdgDataPrefix( const QString& _dir )
00242 {
00243     addXdgDataPrefix(_dir, false);
00244 }
00245 
00246 void KStandardDirs::addXdgDataPrefix( const QString& _dir, bool priority )
00247 {
00248     if (_dir.isEmpty())
00249     return;
00250 
00251     QString dir = _dir;
00252     if (dir.at(dir.length() - 1) != '/')
00253     dir += '/';
00254 
00255     if (!d->xdgdata_prefixes.contains(dir)) {
00256     priorityAdd(d->xdgdata_prefixes, dir, priority);
00257     dircache.clear();
00258     }
00259 }
00260 
00261 QString KStandardDirs::kfsstnd_prefixes()
00262 {
00263    return prefixes.join(":");
00264 }
00265 
00266 bool KStandardDirs::addResourceType( const char *type,
00267                      const QString& relativename )
00268 {
00269     return addResourceType(type, relativename, true);
00270 }
00271 bool KStandardDirs::addResourceType( const char *type,
00272                      const QString& relativename,
00273                      bool priority )
00274 {
00275     if (relativename.isEmpty())
00276        return false;
00277 
00278     QStringList *rels = relatives.find(type);
00279     if (!rels) {
00280     rels = new QStringList();
00281     relatives.insert(type, rels);
00282     }
00283     QString copy = relativename;
00284     if (copy.at(copy.length() - 1) != '/')
00285     copy += '/';
00286     if (!rels->contains(copy)) {
00287         if (priority)
00288         rels->prepend(copy);
00289     else
00290         rels->append(copy);
00291     dircache.remove(type); // clean the cache
00292     return true;
00293     }
00294     return false;
00295 }
00296 
00297 bool KStandardDirs::addResourceDir( const char *type,
00298                     const QString& absdir)
00299 {
00300     // KDE4: change priority to bring in line with addResourceType
00301     return addResourceDir(type, absdir, false);
00302 }
00303 
00304 bool KStandardDirs::addResourceDir( const char *type,
00305                     const QString& absdir,
00306                     bool priority)
00307 {
00308     QStringList *paths = absolutes.find(type);
00309     if (!paths) {
00310     paths = new QStringList();
00311     absolutes.insert(type, paths);
00312     }
00313     QString copy = absdir;
00314     if (copy.at(copy.length() - 1) != '/')
00315       copy += '/';
00316 
00317     if (!paths->contains(copy)) {
00318         if (priority)
00319             paths->prepend(copy);
00320         else
00321         paths->append(copy);
00322     dircache.remove(type); // clean the cache
00323     return true;
00324     }
00325     return false;
00326 }
00327 
00328 QString KStandardDirs::findResource( const char *type,
00329                      const QString& filename ) const
00330 {
00331     if (filename.at(0) == '/')
00332     return filename; // absolute dirs are absolute dirs, right? :-/
00333 
00334     QString newFilename(filename);
00335     if ( strcmp(type, "module") == 0 )
00336     {
00337     if (newFilename.right(3) == ".la")
00338            newFilename = newFilename.replace( newFilename.length() - 3, 3, ".so" );
00339     }
00340 
00341 #if 0
00342 kdDebug() << "Find resource: " << type << endl;
00343 for (QStringList::ConstIterator pit = prefixes.begin();
00344      pit != prefixes.end();
00345      pit++)
00346 {
00347   kdDebug() << "Prefix: " << *pit << endl;
00348 }
00349 #endif
00350 
00351     QString dir = findResourceDir(type, newFilename);
00352     if (dir.isEmpty())
00353     return dir;
00354     else return dir + newFilename;
00355 }
00356 
00357 static Q_UINT32 updateHash(const QString &file, Q_UINT32 hash)
00358 {
00359     QCString cFile = QFile::encodeName(file);
00360     struct stat buff;
00361     if ((access(cFile, R_OK) == 0) &&
00362         (stat( cFile, &buff ) == 0) &&
00363         (S_ISREG( buff.st_mode )))
00364     {
00365        hash = hash + (Q_UINT32) buff.st_ctime;
00366     }
00367     return hash;
00368 }
00369 
00370 Q_UINT32 KStandardDirs::calcResourceHash( const char *type,
00371                   const QString& filename, bool deep) const
00372 {
00373     Q_UINT32 hash = 0;
00374 
00375     if (filename.at(0) == '/')
00376     {
00377         // absolute dirs are absolute dirs, right? :-/
00378     return updateHash(filename, hash);
00379     }
00380     if (d && d->restrictionsActive && (strcmp(type, "data")==0))
00381        applyDataRestrictions(filename);
00382     QStringList candidates = resourceDirs(type);
00383     QString fullPath;
00384 
00385     for (QStringList::ConstIterator it = candidates.begin();
00386      it != candidates.end(); it++)
00387     {
00388         hash = updateHash(*it + filename, hash);
00389         if (!deep && hash)
00390            return hash;
00391     }
00392     return hash;
00393 }
00394 
00395 
00396 QStringList KStandardDirs::findDirs( const char *type,
00397                                      const QString& reldir ) const
00398 {
00399     QDir testdir;
00400     QStringList list;
00401     if (reldir.startsWith("/"))
00402     {
00403         testdir.setPath(reldir);
00404         if (testdir.exists())
00405         {
00406             if (reldir.endsWith("/"))
00407                list.append(reldir);
00408             else
00409                list.append(reldir+'/');
00410         }
00411         return list;
00412     }
00413 
00414     checkConfig();
00415 
00416     if (d && d->restrictionsActive && (strcmp(type, "data")==0))
00417        applyDataRestrictions(reldir);
00418     QStringList candidates = resourceDirs(type);
00419 
00420     for (QStringList::ConstIterator it = candidates.begin();
00421          it != candidates.end(); it++) {
00422         testdir.setPath(*it + reldir);
00423         if (testdir.exists())
00424             list.append(testdir.absPath() + '/');
00425     }
00426 
00427     return list;
00428 }
00429 
00430 QString KStandardDirs::findResourceDir( const char *type,
00431                     const QString& filename) const
00432 {
00433 #ifndef NDEBUG
00434     if (filename.isEmpty()) {
00435       kdWarning() << "filename for type " << type << " in KStandardDirs::findResourceDir is not supposed to be empty!!" << endl;
00436       return QString::null;
00437     }
00438 #endif
00439 
00440     if (d && d->restrictionsActive && (strcmp(type, "data")==0))
00441        applyDataRestrictions(filename);
00442     QStringList candidates = resourceDirs(type);
00443     QString fullPath;
00444 
00445     for (QStringList::ConstIterator it = candidates.begin();
00446      it != candidates.end(); it++)
00447     {
00448       if ( QString::compare("exe", type) == 0 )
00449       {
00450       if (exists_exe(*it + filename))
00451           return *it;
00452       }
00453       else
00454       {
00455           if (exists(*it + filename))
00456           return *it;
00457       }
00458     }
00459 
00460 #ifndef NDEBUG
00461     if(false && type != "locale")
00462       kdDebug() << "KStdDirs::findResDir(): can't find \"" << filename << "\" in type \"" << type << "\"." << endl;
00463 #endif
00464 
00465     return QString::null;
00466 }
00467 
00468 bool KStandardDirs::exists_exe(const QString &fullPath)
00469 {
00470     struct stat buff;
00471     if (access(QFile::encodeName(fullPath), X_OK) == 0 && stat( QFile::encodeName(fullPath), &buff ) == 0)
00472     if (fullPath.at(fullPath.length() - 1) != '/') {
00473         if (S_ISREG( buff.st_mode ))
00474         return true;
00475     } else
00476         if (S_ISDIR( buff.st_mode ))
00477         return true;
00478     return false;
00479 }
00480 
00481 bool KStandardDirs::exists(const QString &fullPath)
00482 {
00483     struct stat buff;
00484     if (access(QFile::encodeName(fullPath), R_OK) == 0 && stat( QFile::encodeName(fullPath), &buff ) == 0)
00485     if (fullPath.at(fullPath.length() - 1) != '/') {
00486         if (S_ISREG( buff.st_mode ))
00487         return true;
00488     } else
00489         if (S_ISDIR( buff.st_mode ))
00490         return true;
00491     return false;
00492 }
00493 
00494 static void lookupDirectory(const QString& path, const QString &relPart,
00495                 const QRegExp &regexp,
00496                 QStringList& list,
00497                 QStringList& relList,
00498                 bool recursive, bool unique)
00499 {
00500   QString pattern = regexp.pattern();
00501   if (recursive || pattern.contains('?') || pattern.contains('*'))
00502   {
00503     // We look for a set of files.
00504     DIR *dp = opendir( QFile::encodeName(path));
00505     if (!dp)
00506       return;
00507 
00508     assert(path.at(path.length() - 1) == '/');
00509 
00510     struct dirent *ep;
00511     struct stat buff;
00512 
00513     QString _dot(".");
00514     QString _dotdot("..");
00515 
00516     while( ( ep = readdir( dp ) ) != 0L )
00517     {
00518       QString fn( QFile::decodeName(ep->d_name));
00519       if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1).latin1() == '~')
00520     continue;
00521 
00522       if (!recursive && !regexp.exactMatch(fn))
00523     continue; // No match
00524 
00525       QString pathfn = path + fn;
00526       if ( stat( QFile::encodeName(pathfn), &buff ) != 0 ) {
00527     kdDebug() << "Error stat'ing " << pathfn << " : " << perror << endl;
00528     continue; // Couldn't stat (e.g. no read permissions)
00529       }
00530       if ( recursive ) {
00531     if ( S_ISDIR( buff.st_mode )) {
00532       lookupDirectory(pathfn + '/', relPart + fn + '/', regexp, list, relList, recursive, unique);
00533     }
00534         if (!regexp.exactMatch(fn))
00535       continue; // No match
00536       }
00537       if ( S_ISREG( buff.st_mode))
00538       {
00539         if (!unique || !relList.contains(relPart + fn))
00540         {
00541         list.append( pathfn );
00542         relList.append( relPart + fn );
00543         }
00544       }
00545     }
00546     closedir( dp );
00547   }
00548   else
00549   {
00550      // We look for a single file.
00551      QString fn = pattern;
00552      QString pathfn = path + fn;
00553      struct stat buff;
00554      if ( stat( QFile::encodeName(pathfn), &buff ) != 0 )
00555         return; // File not found
00556      if ( S_ISREG( buff.st_mode))
00557      {
00558        if (!unique || !relList.contains(relPart + fn))
00559        {
00560          list.append( pathfn );
00561          relList.append( relPart + fn );
00562        }
00563      }
00564   }
00565 }
00566 
00567 static void lookupPrefix(const QString& prefix, const QString& relpath,
00568                          const QString& relPart,
00569              const QRegExp &regexp,
00570              QStringList& list,
00571              QStringList& relList,
00572              bool recursive, bool unique)
00573 {
00574     if (relpath.isEmpty()) {
00575        lookupDirectory(prefix, relPart, regexp, list,
00576                relList, recursive, unique);
00577        return;
00578     }
00579     QString path;
00580     QString rest;
00581 
00582     if (relpath.length())
00583     {
00584        int slash = relpath.find('/');
00585        if (slash < 0)
00586        rest = relpath.left(relpath.length() - 1);
00587        else {
00588        path = relpath.left(slash);
00589        rest = relpath.mid(slash + 1);
00590        }
00591     }
00592 
00593     assert(prefix.at(prefix.length() - 1) == '/');
00594 
00595     struct stat buff;
00596 
00597     if (path.contains('*') || path.contains('?')) {
00598 
00599     QRegExp pathExp(path, true, true);
00600     DIR *dp = opendir( QFile::encodeName(prefix) );
00601     if (!dp) {
00602         return;
00603     }
00604 
00605     struct dirent *ep;
00606 
00607         QString _dot(".");
00608         QString _dotdot("..");
00609 
00610     while( ( ep = readdir( dp ) ) != 0L )
00611         {
00612         QString fn( QFile::decodeName(ep->d_name));
00613         if (fn == _dot || fn == _dotdot || fn.at(fn.length() - 1) == '~')
00614             continue;
00615 
00616         if ( !pathExp.exactMatch(fn) )
00617             continue; // No match
00618         QString rfn = relPart+fn;
00619         fn = prefix + fn;
00620         if ( stat( QFile::encodeName(fn), &buff ) != 0 ) {
00621             kdDebug() << "Error statting " << fn << " : " << perror << endl;
00622             continue; // Couldn't stat (e.g. no permissions)
00623         }
00624         if ( S_ISDIR( buff.st_mode ))
00625             lookupPrefix(fn + '/', rest, rfn + '/', regexp, list, relList, recursive, unique);
00626         }
00627 
00628     closedir( dp );
00629     } else {
00630         // Don't stat, if the dir doesn't exist we will find out
00631         // when we try to open it.
00632         lookupPrefix(prefix + path + '/', rest,
00633                      relPart + path + '/', regexp, list,
00634                      relList, recursive, unique);
00635     }
00636 }
00637 
00638 QStringList
00639 KStandardDirs::findAllResources( const char *type,
00640                      const QString& filter,
00641                  bool recursive,
00642                      bool unique,
00643                                  QStringList &relList) const
00644 {
00645     QStringList list;
00646     QString filterPath;
00647     QString filterFile;
00648 
00649     if (filter.length())
00650     {
00651        int slash = filter.findRev('/');
00652        if (slash < 0)
00653        filterFile = filter;
00654        else {
00655        filterPath = filter.left(slash + 1);
00656        filterFile = filter.mid(slash + 1);
00657        }
00658     }
00659 
00660     checkConfig();
00661 
00662     QStringList candidates;
00663     if (filterPath.startsWith("/")) // absolute path
00664     {
00665         filterPath = filterPath.mid(1);
00666         candidates << "/";
00667     }
00668     else
00669     {
00670         if (d && d->restrictionsActive && (strcmp(type, "data")==0))
00671             applyDataRestrictions(filter);
00672         candidates = resourceDirs(type);
00673     }
00674     if (filterFile.isEmpty())
00675     filterFile = "*";
00676 
00677     QRegExp regExp(filterFile, true, true);
00678 
00679     for (QStringList::ConstIterator it = candidates.begin();
00680          it != candidates.end(); it++)
00681     {
00682         lookupPrefix(*it, filterPath, "", regExp, list,
00683                      relList, recursive, unique);
00684     }
00685 
00686     return list;
00687 }
00688 
00689 QStringList
00690 KStandardDirs::findAllResources( const char *type,
00691                      const QString& filter,
00692                  bool recursive,
00693                      bool unique) const
00694 {
00695     QStringList relList;
00696     return findAllResources(type, filter, recursive, unique, relList);
00697 }
00698 
00699 QString
00700 KStandardDirs::realPath(const QString &dirname)
00701 {
00702     char realpath_buffer[MAXPATHLEN + 1];
00703     memset(realpath_buffer, 0, MAXPATHLEN + 1);
00704 
00705     /* If the path contains symlinks, get the real name */
00706     if (realpath( QFile::encodeName(dirname).data(), realpath_buffer) != 0) {
00707         // succes, use result from realpath
00708         int len = strlen(realpath_buffer);
00709         realpath_buffer[len] = '/';
00710         realpath_buffer[len+1] = 0;
00711         return QFile::decodeName(realpath_buffer);
00712     }
00713 
00714     return dirname;
00715 }
00716 
00717 void KStandardDirs::createSpecialResource(const char *type)
00718 {
00719    char hostname[256];
00720    hostname[0] = 0;
00721    gethostname(hostname, 255);
00722    QString dir = QString("%1%2-%3").arg(localkdedir()).arg(type).arg(hostname);
00723    char link[1024];
00724    link[1023] = 0;
00725    int result = readlink(QFile::encodeName(dir).data(), link, 1023);
00726    bool relink = (result == -1) && (errno == ENOENT);
00727    if ((result > 0) && (link[0] == '/'))
00728    {
00729       link[result] = 0;
00730       struct stat stat_buf;
00731       int res = lstat(link, &stat_buf);
00732       if ((res == -1) && (errno == ENOENT))
00733       {
00734          relink = true;
00735       }
00736       else if ((res == -1) || (!S_ISDIR(stat_buf.st_mode)))
00737       {
00738          fprintf(stderr, "Error: \"%s\" is not a directory.\n", link);
00739          relink = true;
00740       }
00741       else if (stat_buf.st_uid != getuid())
00742       {
00743          fprintf(stderr, "Error: \"%s\" is owned by uid %d instead of uid %d.\n", link, stat_buf.st_uid, getuid());
00744          relink = true;
00745       }
00746    }
00747    if (relink)
00748    {
00749       QString srv = findExe(QString::fromLatin1("lnusertemp"), KDEDIR+QString::fromLatin1("/bin"));
00750       if (srv.isEmpty())
00751          srv = findExe(QString::fromLatin1("lnusertemp"));
00752       if (!srv.isEmpty())
00753       {
00754          system(QFile::encodeName(srv)+" "+type);
00755          result = readlink(QFile::encodeName(dir).data(), link, 1023);
00756       }
00757    }
00758    if (result > 0)
00759    {
00760       link[result] = 0;
00761       if (link[0] == '/')
00762          dir = QFile::decodeName(link);
00763       else
00764          dir = QDir::cleanDirPath(dir+QFile::decodeName(link));
00765    }
00766    addResourceDir(type, dir+'/');
00767 }
00768 
00769 QStringList KStandardDirs::resourceDirs(const char *type) const
00770 {
00771     QStringList *candidates = dircache.find(type);
00772 
00773     if (!candidates) { // filling cache
00774         if (strcmp(type, "socket") == 0)
00775            const_cast<KStandardDirs *>(this)->createSpecialResource(type);
00776         else if (strcmp(type, "tmp") == 0)
00777            const_cast<KStandardDirs *>(this)->createSpecialResource(type);
00778         else if (strcmp(type, "cache") == 0)
00779            const_cast<KStandardDirs *>(this)->createSpecialResource(type);
00780 
00781         QDir testdir;
00782 
00783         candidates = new QStringList();
00784         QStringList *dirs;
00785 
00786         bool restrictionActive = false;
00787         if (d && d->restrictionsActive)
00788         {
00789            if (d->dataRestrictionActive)
00790               restrictionActive = true;
00791            else if (d->restrictions["all"])
00792               restrictionActive = true;
00793            else if (d->restrictions[type])
00794               restrictionActive = true;
00795            d->dataRestrictionActive = false; // Reset
00796         }
00797 
00798         dirs = relatives.find(type);
00799         if (dirs)
00800         {
00801             bool local = true;
00802             const QStringList *prefixList = 0;
00803             if (strncmp(type, "xdgdata-", 8) == 0)
00804                 prefixList = &(d->xdgdata_prefixes);
00805             else if (strncmp(type, "xdgconf-", 8) == 0)
00806                 prefixList = &(d->xdgconf_prefixes);
00807             else
00808                 prefixList = &prefixes;
00809 
00810             for (QStringList::ConstIterator pit = prefixList->begin();
00811                  pit != prefixList->end();
00812                  pit++)
00813             {
00814                 for (QStringList::ConstIterator it = dirs->begin();
00815                      it != dirs->end(); ++it) {
00816                     QString path = realPath(*pit + *it);
00817                     testdir.setPath(path);
00818                     if (local && restrictionActive)
00819                        continue;
00820                     if ((local || testdir.exists()) && !candidates->contains(path))
00821                         candidates->append(path);
00822                 }
00823                 local = false;
00824             }
00825         }
00826         dirs = absolutes.find(type);
00827         if (dirs)
00828             for (QStringList::ConstIterator it = dirs->begin();
00829                  it != dirs->end(); ++it)
00830             {
00831                 testdir.setPath(*it);
00832                 if (testdir.exists())
00833                 {
00834                     QString filename = realPath(*it);
00835                     if (!candidates->contains(filename))
00836                         candidates->append(filename);
00837                 }
00838             }
00839         dircache.insert(type, candidates);
00840     }
00841 
00842 #if 0
00843     kdDebug() << "found dirs for resource " << type << ":" << endl;
00844     for (QStringList::ConstIterator pit = candidates->begin();
00845      pit != candidates->end();
00846      pit++)
00847     {
00848     fprintf(stderr, "%s\n", (*pit).latin1());
00849     }
00850 #endif
00851 
00852 
00853   return *candidates;
00854 }
00855 
00856 QStringList KStandardDirs::systemPaths( const QString& pstr )
00857 {
00858     QStringList tokens;
00859     QString p = pstr;
00860 
00861     if( p.isNull() )
00862     {
00863     p = getenv( "PATH" );
00864     }
00865 
00866     tokenize( tokens, p, ":\b" );
00867 
00868     QStringList exePaths;
00869 
00870     // split path using : or \b as delimiters
00871     for( unsigned i = 0; i < tokens.count(); i++ )
00872     {
00873     p = tokens[ i ];
00874 
00875         if ( p[ 0 ] == '~' )
00876         {
00877             int len = p.find( '/' );
00878             if ( len == -1 )
00879                 len = p.length();
00880             if ( len == 1 )
00881             {
00882                 p.replace( 0, 1, QDir::homeDirPath() );
00883             }
00884             else
00885             {
00886                 QString user = p.mid( 1, len - 1 );
00887                 struct passwd *dir = getpwnam( user.local8Bit().data() );
00888                 if ( dir && strlen( dir->pw_dir ) )
00889                     p.replace( 0, len, QString::fromLocal8Bit( dir->pw_dir ) );
00890             }
00891         }
00892 
00893     exePaths << p;
00894     }
00895 
00896     return exePaths;
00897 }
00898 
00899 
00900 QString KStandardDirs::findExe( const QString& appname,
00901                 const QString& pstr, bool ignore)
00902 {
00903     QFileInfo info;
00904 
00905     // absolute path ?
00906     if (appname.startsWith(QString::fromLatin1("/")))
00907     {
00908         info.setFile( appname );
00909         if( info.exists() && ( ignore || info.isExecutable() )
00910             && info.isFile() ) {
00911             return appname;
00912         }
00913         return QString::null;
00914     }
00915 
00916     QString p = QString("%1/%2").arg(__KDE_BINDIR).arg(appname);
00917     info.setFile( p );
00918     if( info.exists() && ( ignore || info.isExecutable() )
00919          && ( info.isFile() || info.isSymLink() )  ) {
00920          return p;
00921     }
00922 
00923     QStringList exePaths = systemPaths( pstr );
00924     for (QStringList::ConstIterator it = exePaths.begin(); it != exePaths.end(); it++)
00925     {
00926     p = (*it) + "/";
00927     p += appname;
00928 
00929     // Check for executable in this tokenized path
00930     info.setFile( p );
00931 
00932     if( info.exists() && ( ignore || info.isExecutable() )
00933            && ( info.isFile() || info.isSymLink() )  ) {
00934         return p;
00935     }
00936     }
00937 
00938     // If we reach here, the executable wasn't found.
00939     // So return empty string.
00940 
00941     return QString::null;
00942 }
00943 
00944 int KStandardDirs::findAllExe( QStringList& list, const QString& appname,
00945             const QString& pstr, bool ignore )
00946 {
00947     QFileInfo info;
00948     QString p;
00949     list.clear();
00950 
00951     QStringList exePaths = systemPaths( pstr );
00952     for (QStringList::ConstIterator it = exePaths.begin(); it != exePaths.end(); it++)
00953     {
00954     p = (*it) + "/";
00955     p += appname;
00956 
00957     info.setFile( p );
00958 
00959     if( info.exists() && (ignore || info.isExecutable())
00960         && info.isFile() ) {
00961         list.append( p );
00962     }
00963     }
00964 
00965     return list.count();
00966 }
00967 
00968 static int tokenize( QStringList& tokens, const QString& str,
00969              const QString& delim )
00970 {
00971     int len = str.length();
00972     QString token = "";
00973 
00974     for( int index = 0; index < len; index++)
00975     {
00976     if ( delim.find( str[ index ] ) >= 0 )
00977     {
00978         tokens.append( token );
00979         token = "";
00980     }
00981     else
00982     {
00983         token += str[ index ];
00984     }
00985     }
00986     if ( token.length() > 0 )
00987     {
00988     tokens.append( token );
00989     }
00990 
00991     return tokens.count();
00992 }
00993 
00994 QString KStandardDirs::kde_default(const char *type) {
00995     if (!strcmp(type, "data"))
00996     return "share/apps/";
00997     if (!strcmp(type, "html"))
00998     return "share/doc/HTML/";
00999     if (!strcmp(type, "icon"))
01000     return "share/icons/";
01001     if (!strcmp(type, "config"))
01002     return "share/config/";
01003     if (!strcmp(type, "pixmap"))
01004     return "share/pixmaps/";
01005     if (!strcmp(type, "apps"))
01006     return addCustomPathSuffix("share/applnk", "-alt/");
01007     if (!strcmp(type, "sound"))
01008     return "share/sounds/";
01009     if (!strcmp(type, "locale"))
01010     return "share/locale/";
01011     if (!strcmp(type, "services"))
01012     return "share/services/";
01013     if (!strcmp(type, "servicetypes"))
01014     return "share/servicetypes/";
01015     if (!strcmp(type, "mime"))
01016     return "share/mimelnk/";
01017     if (!strcmp(type, "cgi"))
01018     return "cgi-bin/";
01019     if (!strcmp(type, "wallpaper"))
01020     return "share/wallpapers/";
01021     if (!strcmp(type, "templates"))
01022     return "share/templates/";
01023     if (!strcmp(type, "exe"))
01024     return "bin/";
01025     if (!strcmp(type, "lib"))
01026     return "lib" KDELIBSUFF "/";
01027     if (!strcmp(type, "module"))
01028     return "lib" KDELIBSUFF "/kde3/";
01029     if (!strcmp(type, "qtplugins"))
01030         return "lib" KDELIBSUFF "/kde3/plugins";
01031     if (!strcmp(type, "xdgdata-apps"))
01032         return addCustomPathSuffix("applications", "-alt/");
01033     if (!strcmp(type, "xdgdata-dirs"))
01034         return addCustomPathSuffix("desktop-directories", "-alt/");
01035     if (!strcmp(type, "xdgconf-menu"))
01036         return addCustomPathSuffix("menus", "-alt/");
01037     if (!strcmp(type, "kcfg"))
01038     return "share/config.kcfg";
01039     qFatal("unknown resource type %s", type);
01040     return QString::null;
01041 }
01042 
01043 QString KStandardDirs::saveLocation(const char *type,
01044                     const QString& suffix,
01045                     bool create) const
01046 {
01047     checkConfig();
01048 
01049     QString *pPath = savelocations.find(type);
01050     if (!pPath)
01051     {
01052        QStringList *dirs = relatives.find(type);
01053        if (!dirs && (
01054                      (strcmp(type, "socket") == 0) ||
01055                      (strcmp(type, "tmp") == 0) ||
01056                      (strcmp(type, "cache") == 0) ))
01057        {
01058           (void) resourceDirs(type); // Generate socket|tmp|cache resource.
01059           dirs = relatives.find(type); // Search again.
01060        }
01061        if (dirs)
01062        {
01063           // Check for existence of typed directory + suffix
01064           if (strncmp(type, "xdgdata-", 8) == 0)
01065              pPath = new QString(realPath(localxdgdatadir() + dirs->last()));
01066           else if (strncmp(type, "xdgconf-", 8) == 0)
01067              pPath = new QString(realPath(localxdgconfdir() + dirs->last()));
01068           else
01069              pPath = new QString(realPath(localkdedir() + dirs->last()));
01070        }
01071        else {
01072           dirs = absolutes.find(type);
01073           if (!dirs)
01074              qFatal("KStandardDirs: The resource type %s is not registered", type);
01075           pPath = new QString(realPath(dirs->last()));
01076        }
01077 
01078        savelocations.insert(type, pPath);
01079     }
01080     QString fullPath = *pPath + suffix;
01081 
01082     struct stat st;
01083     if (stat(QFile::encodeName(fullPath), &st) != 0 || !(S_ISDIR(st.st_mode))) {
01084     if(!create) {
01085 #ifndef NDEBUG
01086         qDebug("save location %s doesn't exist", fullPath.latin1());
01087 #endif
01088         return fullPath;
01089     }
01090     if(!makeDir(fullPath, 0700)) {
01091             qWarning("failed to create %s", fullPath.latin1());
01092         return fullPath;
01093     }
01094         dircache.remove(type);
01095     }
01096     return fullPath;
01097 }
01098 
01099 QString KStandardDirs::relativeLocation(const char *type, const QString &absPath)
01100 {
01101     QString fullPath = absPath;
01102     int i = absPath.findRev('/');
01103     if (i != -1)
01104     {
01105        fullPath = realPath(absPath.left(i+1))+absPath.mid(i+1); // Normalize
01106     }
01107 
01108     QStringList candidates = resourceDirs(type);
01109 
01110     for (QStringList::ConstIterator it = candidates.begin();
01111      it != candidates.end(); it++)
01112       if (fullPath.startsWith(*it))
01113       {
01114     return fullPath.mid((*it).length());
01115       }
01116 
01117     return absPath;
01118 }
01119 
01120 
01121 bool KStandardDirs::makeDir(const QString& dir, int mode)
01122 {
01123     // we want an absolute path
01124     if (dir.at(0) != '/')
01125         return false;
01126 
01127     QString target = dir;
01128     uint len = target.length();
01129 
01130     // append trailing slash if missing
01131     if (dir.at(len - 1) != '/')
01132         target += '/';
01133 
01134     QString base("");
01135     uint i = 1;
01136 
01137     while( i < len )
01138     {
01139         struct stat st;
01140         int pos = target.find('/', i);
01141         base += target.mid(i - 1, pos - i + 1);
01142         QCString baseEncoded = QFile::encodeName(base);
01143         // bail out if we encountered a problem
01144         if (stat(baseEncoded, &st) != 0)
01145         {
01146           // Directory does not exist....
01147           // Or maybe a dangling symlink ?
01148           if (lstat(baseEncoded, &st) == 0)
01149               (void)unlink(baseEncoded); // try removing
01150 
01151       if ( mkdir(baseEncoded, (mode_t) mode) != 0) {
01152         perror("trying to create local folder");
01153         return false; // Couldn't create it :-(
01154       }
01155         }
01156         i = pos + 1;
01157     }
01158     return true;
01159 }
01160 
01161 static QString readEnvPath(const char *env)
01162 {
01163    QCString c_path = getenv(env);
01164    if (c_path.isEmpty())
01165       return QString::null;
01166    return QFile::decodeName(c_path);
01167 }
01168 
01169 #ifdef __linux__
01170 static QString executablePrefix()
01171 {
01172    char path_buffer[MAXPATHLEN + 1];
01173    path_buffer[MAXPATHLEN] = 0;
01174    int length = readlink ("/proc/self/exe", path_buffer, MAXPATHLEN);
01175    if (length == -1)
01176       return QString::null;
01177 
01178    path_buffer[length] = '\0';
01179 
01180    QString path = QFile::decodeName(path_buffer);
01181 
01182    if(path.isEmpty())
01183       return QString::null;
01184 
01185    int pos = path.findRev('/'); // Skip filename
01186    if(pos <= 0)
01187       return QString::null;
01188    pos = path.findRev('/', pos - 1); // Skip last directory
01189    if(pos <= 0)
01190       return QString::null;
01191 
01192    return path.left(pos);
01193 }
01194 #endif
01195 
01196 void KStandardDirs::addKDEDefaults()
01197 {
01198     QStringList kdedirList;
01199 
01200     // begin KDEDIRS
01201     QString kdedirs = readEnvPath("KDEDIRS");
01202     if (!kdedirs.isEmpty())
01203     {
01204     tokenize(kdedirList, kdedirs, ":");
01205     }
01206     else
01207     {
01208     QString kdedir = readEnvPath("KDEDIR");
01209     if (!kdedir.isEmpty())
01210         {
01211            kdedir = KShell::tildeExpand(kdedir);
01212        kdedirList.append(kdedir);
01213         }
01214     }
01215     kdedirList.append(KDEDIR);
01216 
01217 #ifdef __KDE_EXECPREFIX
01218     QString execPrefix(__KDE_EXECPREFIX);
01219     if (execPrefix!="NONE")
01220        kdedirList.append(execPrefix);
01221 #endif
01222 #ifdef __linux__
01223     kdedirList.append(executablePrefix());
01224 #endif
01225 
01226     // We treat root differently to prevent a "su" shell messing up the
01227     // file permissions in the user's home directory.
01228     QString localKdeDir = readEnvPath(getuid() ? "KDEHOME" : "KDEROOTHOME");
01229     if (!localKdeDir.isEmpty())
01230     {
01231        if (localKdeDir[localKdeDir.length()-1] != '/')
01232           localKdeDir += '/';
01233     }
01234     else
01235     {
01236        localKdeDir =  QDir::homeDirPath() + "/.kde/";
01237     }
01238 
01239     if (localKdeDir != "-/")
01240     {
01241         localKdeDir = KShell::tildeExpand(localKdeDir);
01242         addPrefix(localKdeDir);
01243     }
01244 
01245     for (QStringList::ConstIterator it = kdedirList.begin();
01246      it != kdedirList.end(); it++)
01247     {
01248         QString dir = KShell::tildeExpand(*it);
01249     addPrefix(dir);
01250     }
01251     // end KDEDIRS
01252 
01253     // begin XDG_CONFIG_XXX
01254     QStringList xdgdirList;
01255     QString xdgdirs = readEnvPath("XDG_CONFIG_DIRS");
01256     if (!xdgdirs.isEmpty())
01257     {
01258     tokenize(xdgdirList, xdgdirs, ":");
01259     }
01260     else
01261     {
01262     xdgdirList.clear();
01263         xdgdirList.append("/etc/xdg");
01264         xdgdirList.append(KDESYSCONFDIR "/xdg");
01265     }
01266 
01267     QString localXdgDir = readEnvPath("XDG_CONFIG_HOME");
01268     if (!localXdgDir.isEmpty())
01269     {
01270        if (localXdgDir[localXdgDir.length()-1] != '/')
01271           localXdgDir += '/';
01272     }
01273     else
01274     {
01275        localXdgDir =  QDir::homeDirPath() + "/.config/";
01276     }
01277 
01278     localXdgDir = KShell::tildeExpand(localXdgDir);
01279     addXdgConfigPrefix(localXdgDir);
01280 
01281     for (QStringList::ConstIterator it = xdgdirList.begin();
01282      it != xdgdirList.end(); it++)
01283     {
01284         QString dir = KShell::tildeExpand(*it);
01285     addXdgConfigPrefix(dir);
01286     }
01287     // end XDG_CONFIG_XXX
01288 
01289     // begin XDG_DATA_XXX
01290     xdgdirs = readEnvPath("XDG_DATA_DIRS");
01291     if (!xdgdirs.isEmpty())
01292     {
01293     tokenize(xdgdirList, xdgdirs, ":");
01294     }
01295     else
01296     {
01297     xdgdirList.clear();
01298         for (QStringList::ConstIterator it = kdedirList.begin();
01299            it != kdedirList.end(); it++)
01300         {
01301            QString dir = *it;
01302            if (dir[dir.length()-1] != '/')
01303              dir += '/';
01304            xdgdirList.append(dir+"share/");
01305         }
01306 
01307         xdgdirList.append("/usr/local/share/");
01308         xdgdirList.append("/usr/share/");
01309     }
01310 
01311     localXdgDir = readEnvPath("XDG_DATA_HOME");
01312     if (!localXdgDir.isEmpty())
01313     {
01314        if (localXdgDir[localXdgDir.length()-1] != '/')
01315           localXdgDir += '/';
01316     }
01317     else
01318     {
01319        localXdgDir = QDir::homeDirPath() + "/.local/share/";
01320     }
01321 
01322     localXdgDir = KShell::tildeExpand(localXdgDir);
01323     addXdgDataPrefix(localXdgDir);
01324 
01325     for (QStringList::ConstIterator it = xdgdirList.begin();
01326      it != xdgdirList.end(); it++)
01327     {
01328         QString dir = KShell::tildeExpand(*it);
01329     addXdgDataPrefix(dir);
01330     }
01331     // end XDG_DATA_XXX
01332 
01333 
01334     uint index = 0;
01335     while (types[index] != 0) {
01336     addResourceType(types[index], kde_default(types[index]));
01337     index++;
01338     }
01339 
01340     addResourceDir("home", QDir::homeDirPath());
01341 }
01342 
01343 void KStandardDirs::checkConfig() const
01344 {
01345     if (!addedCustoms && KGlobal::_instance && KGlobal::_instance->_config)
01346         const_cast<KStandardDirs*>(this)->addCustomized(KGlobal::_instance->_config);
01347 }
01348 
01349 static QStringList lookupProfiles(const QString &mapFile)
01350 {
01351     QStringList profiles;
01352 
01353     if (mapFile.isEmpty() || !QFile::exists(mapFile))
01354     {
01355        profiles << "default";
01356        return profiles;
01357     }
01358 
01359     struct passwd *pw = getpwuid(geteuid());
01360     if (!pw)
01361     {
01362         profiles << "default";
01363         return profiles; // Not good
01364     }
01365 
01366     QCString user = pw->pw_name;
01367     
01368     gid_t sup_gids[512];
01369     int sup_gids_nr = getgroups(512, sup_gids);
01370 
01371     KSimpleConfig mapCfg(mapFile, true);
01372     mapCfg.setGroup("Users");
01373     if (mapCfg.hasKey(user.data()))
01374     {
01375         profiles = mapCfg.readListEntry(user.data());
01376         return profiles; 
01377     }
01378         
01379     mapCfg.setGroup("General");
01380     QStringList groups = mapCfg.readListEntry("groups");
01381 
01382     mapCfg.setGroup("Groups");
01383 
01384     for( QStringList::ConstIterator it = groups.begin();
01385          it != groups.end(); ++it )
01386     {
01387         QCString grp = (*it).utf8();
01388         // Check if user is in this group
01389         struct group *grp_ent = getgrnam(grp);
01390         if (!grp_ent) continue;
01391         gid_t gid = grp_ent->gr_gid;
01392         if (pw->pw_gid == gid)
01393         {
01394             // User is in this group --> add profiles
01395             profiles += mapCfg.readListEntry(*it);
01396         }
01397         else
01398         {
01399             for(int i = 0; i < sup_gids_nr; i++)
01400             {
01401                 if (sup_gids[i] == gid)
01402                 {
01403                     // User is in this group --> add profiles
01404                     profiles += mapCfg.readListEntry(*it);
01405                     break;
01406                 }
01407             }
01408         }
01409     }
01410 
01411     if (profiles.isEmpty())
01412         profiles << "default";
01413     return profiles;
01414 }
01415 
01416 extern bool kde_kiosk_admin;
01417 
01418 bool KStandardDirs::addCustomized(KConfig *config)
01419 {
01420     if (addedCustoms) // there are already customized entries
01421         return false; // we just quit and hope they are the right ones
01422 
01423     // save it for future calls - that will return
01424     addedCustoms = true;
01425 
01426     // save the numbers of config directories. If this changes,
01427     // we will return true to give KConfig a chance to reparse
01428     uint configdirs = resourceDirs("config").count();
01429 
01430     // reading the prefixes in
01431     QString oldGroup = config->group();
01432     QString group = QString::fromLatin1("Directories");
01433     config->setGroup(group);
01434     
01435     QString kioskAdmin = config->readEntry("kioskAdmin");
01436     if (!kioskAdmin.isEmpty() && !kde_kiosk_admin)
01437     {
01438         int i = kioskAdmin.find(':');
01439         QString user = kioskAdmin.left(i);
01440         QString host = kioskAdmin.mid(i+1);
01441 
01442         KUser thisUser;
01443         char hostname[ 256 ];
01444         hostname[ 0 ] = '\0';
01445         if (!gethostname( hostname, 255 ))
01446             hostname[sizeof(hostname)-1] = '\0';
01447                        
01448         if ((user == thisUser.loginName()) &&
01449             (host.isEmpty() || (host == hostname)))
01450         {
01451             kde_kiosk_admin = true;
01452         }
01453     }
01454     
01455     bool readProfiles = true;
01456     
01457     if (kde_kiosk_admin && !QCString(getenv("KDE_KIOSK_NO_PROFILES")).isEmpty())
01458         readProfiles = false;
01459 
01460     QString userMapFile = config->readEntry("userProfileMapFile");
01461     QString profileDirsPrefix = config->readEntry("profileDirsPrefix");
01462     if (!profileDirsPrefix.isEmpty() && !profileDirsPrefix.endsWith("/"))
01463         profileDirsPrefix.append('/');
01464 
01465     QStringList profiles;
01466     if (readProfiles)
01467         profiles = lookupProfiles(userMapFile);
01468     QString profile;
01469     
01470     bool priority = false;
01471     while(true)
01472     {
01473         config->setGroup(group);
01474         QStringList list = config->readListEntry("prefixes");
01475         for (QStringList::ConstIterator it = list.begin(); it != list.end(); it++)
01476         {
01477             addPrefix(*it, priority);
01478         addXdgConfigPrefix(*it+"/etc/xdg", priority);
01479         addXdgDataPrefix(*it+"/share", priority);
01480     }
01481     // If there are no prefixes defined, check if there is a directory
01482     // for this profile under <profileDirsPrefix>
01483     if (list.isEmpty() && !profile.isEmpty() && !profileDirsPrefix.isEmpty())
01484     {
01485         QString dir = profileDirsPrefix + profile;
01486         addPrefix(dir, priority);
01487         addXdgConfigPrefix(dir+"/etc/xdg", priority);
01488         addXdgDataPrefix(dir+"/share", priority);
01489     }
01490 
01491         // iterating over all entries in the group Directories
01492         // to find entries that start with dir_$type
01493         QMap<QString, QString> entries = config->entryMap(group);
01494         for (QMap<QString, QString>::ConstIterator it2 = entries.begin(); 
01495              it2 != entries.end(); it2++)
01496         {
01497             QString key = it2.key();
01498             if (key.startsWith("dir_")) {
01499                 // generate directory list, there may be more than 1.
01500                 QStringList dirs = QStringList::split(',',
01501                           *it2);
01502                 QStringList::Iterator sIt(dirs.begin());
01503                 QString resType = key.mid(4, key.length());
01504                 for (; sIt != dirs.end(); ++sIt) {
01505                     addResourceDir(resType.latin1(), *sIt, priority);
01506                 }
01507             }
01508         }
01509         if (profiles.isEmpty())
01510            break;
01511         profile = profiles.back();
01512         group = QString::fromLatin1("Directories-%1").arg(profile);
01513         profiles.pop_back();
01514         priority = true;
01515     }
01516 
01517     // Process KIOSK restrictions.
01518     if (!kde_kiosk_admin || QCString(getenv("KDE_KIOSK_NO_RESTRICTIONS")).isEmpty())
01519     {
01520         config->setGroup("KDE Resource Restrictions");
01521         QMap<QString, QString> entries = config->entryMap("KDE Resource Restrictions");
01522         for (QMap<QString, QString>::ConstIterator it2 = entries.begin(); 
01523             it2 != entries.end(); it2++)
01524         {
01525             QString key = it2.key();
01526             if (!config->readBoolEntry(key, true))
01527             {
01528                 d->restrictionsActive = true;
01529                 d->restrictions.insert(key.latin1(), &d->restrictionsActive); // Anything will do
01530                 dircache.remove(key.latin1());
01531             }
01532         }
01533     }
01534 
01535     config->setGroup(oldGroup);
01536 
01537     // return true if the number of config dirs changed
01538     return (resourceDirs("config").count() != configdirs);
01539 }
01540 
01541 QString KStandardDirs::localkdedir() const
01542 {
01543     // Return the prefix to use for saving
01544     return prefixes.first();
01545 }
01546 
01547 QString KStandardDirs::localxdgdatadir() const
01548 {
01549     // Return the prefix to use for saving
01550     return d->xdgdata_prefixes.first();
01551 }
01552 
01553 QString KStandardDirs::localxdgconfdir() const
01554 {
01555     // Return the prefix to use for saving
01556     return d->xdgconf_prefixes.first();
01557 }
01558 
01559 
01560 // just to make code more readable without macros
01561 QString locate( const char *type,
01562         const QString& filename, const KInstance* inst )
01563 {
01564     return inst->dirs()->findResource(type, filename);
01565 }
01566 
01567 QString locateLocal( const char *type,
01568                  const QString& filename, const KInstance* inst )
01569 {
01570     return locateLocal(type, filename, true, inst);
01571 }
01572 
01573 QString locateLocal( const char *type,
01574                  const QString& filename, bool createDir, const KInstance* inst )
01575 {
01576     // try to find slashes. If there are some, we have to
01577     // create the subdir first
01578     int slash = filename.findRev('/')+1;
01579     if (!slash) // only one filename
01580     return inst->dirs()->saveLocation(type, QString::null, createDir) + filename;
01581 
01582     // split path from filename
01583     QString dir = filename.left(slash);
01584     QString file = filename.mid(slash);
01585     return inst->dirs()->saveLocation(type, dir, createDir) + file;
01586 }
KDE Logo
This file is part of the documentation for kdecore Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Jul 22 10:16:19 2005 by doxygen 1.3.6 written by Dimitri van Heesch, © 1997-2003