• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdecore
 

kdecore

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

kdecore

Skip menu "kdecore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdecore

Skip menu "kdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdecore by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |