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