40#include <config-prefix.h>
41#include <config-kstandarddirs.h>
64#define interface struct
67#include <QtCore/QVarLengthArray>
70#include <QtCore/QMutex>
71#include <QtCore/QRegExp>
73#include <QtCore/QFileInfo>
74#include <QtCore/QSettings>
77static Qt::CaseSensitivity
cs = Qt::CaseInsensitive;
79static Qt::CaseSensitivity
cs = Qt::CaseSensitive;
82class KStandardDirs::KStandardDirsPrivate
86 : m_restrictionsActive(
false),
87 m_checkRestrictions(
true),
88 m_cacheMutex(QMutex::Recursive),
92 bool hasDataRestrictions(
const QString &relPath)
const;
94 void createSpecialResource(
const char*);
96 bool m_restrictionsActive : 1;
97 bool m_checkRestrictions : 1;
194 "share/kde4/services\0"
196 "share/kde4/servicetypes\0"
210 "%lib/kde4/plugins\0"
212 "share/config.kcfg\0"
222 "desktop-directories\0"
226 "xdgconf-autostart\0"
231 0, 5, 16, 21, 36, 41, 53, 60,
232 73, 80, 94, 99, 112, 118, 131, 138,
233 151, 160, 180, 193, 217, 222, 236, 240,
234 248, 258, 275, 285, 301, 305, 309, 316,
235 326, 336, 354, 359, 377, 387, 403, 416,
236 429, 442, 448, 463, 471, 484, 504, 217,
237 517, 530, 536, 554, -1
244 : d(new KStandardDirsPrivate(this))
256 if (!d->m_restrictionsActive)
259 if (d->m_restrictions.value(type,
false))
262 if (strcmp(type,
"data")==0 && d->hasDataRestrictions(relPath))
268bool KStandardDirs::KStandardDirsPrivate::hasDataRestrictions(
const QString &relPath)
const
271 const int i = relPath.indexOf(QLatin1Char(
'/'));
273 key = QString::fromLatin1(
"data_") + relPath.left(i);
275 key = QString::fromLatin1(
"data_") + relPath;
277 return m_restrictions.value(key.toLatin1(),
false);
287 list.append(QString::fromLatin1(
"lib"));
291 list.append(QString::fromLatin1(
"socket"));
292 list.append(QString::fromLatin1(
"tmp"));
293 list.append(QString::fromLatin1(
"cache"));
295 list.append(QString::fromLatin1(
"include"));
304 if (priority && !prefixes.isEmpty())
307 QStringList::iterator it = prefixes.begin();
309 prefixes.insert(it, dir);
313 prefixes.append(dir);
328 if (dir.at(dir.length() - 1) != QLatin1Char(
'/'))
329 dir += QLatin1Char(
'/');
331 if (!d->m_prefixes.contains(dir,
cs)) {
333 d->m_dircache.clear();
348 if (dir.at(dir.length() - 1) != QLatin1Char(
'/'))
349 dir += QLatin1Char(
'/');
351 if (!d->xdgconf_prefixes.contains(dir,
cs)) {
353 d->m_dircache.clear();
368 if (dir.at(dir.length() - 1) != QLatin1Char(
'/'))
369 dir += QLatin1Char(
'/');
371 if (!d->xdgdata_prefixes.contains(dir,
cs)) {
373 d->m_dircache.clear();
379 return d->m_prefixes.join(
QString(QLatin1Char(KPATH_SEPARATOR)));
384 return d->xdgconf_prefixes.join(
QString(QLatin1Char(KPATH_SEPARATOR)));
389 return d->xdgdata_prefixes.join(
QString(QLatin1Char(KPATH_SEPARATOR)));
392#ifndef KDE_NO_DEPRECATED
402 const char *basetype,
406 if (relativename.isEmpty())
411 copy = QLatin1Char(
'%') + QString::fromLatin1(basetype) + QLatin1Char(
'/') + relativename;
413 if (!copy.endsWith(QLatin1Char(
'/')))
414 copy += QLatin1Char(
'/');
416 QByteArray typeBa = type;
419 if (!rels.contains(copy,
cs)) {
425 d->m_dircache.remove(typeBa);
426 d->m_savelocations.remove(typeBa);
436 if (absdir.isEmpty() || !type)
440 if (copy.at(copy.length() - 1) != QLatin1Char(
'/'))
441 copy += QLatin1Char(
'/');
443 QByteArray typeBa = type;
445 if (!paths.contains(copy,
cs)) {
451 d->m_dircache.remove(typeBa);
452 d->m_savelocations.remove(typeBa);
459 const QString& _filename )
const
461 if (!QDir::isRelativePath(_filename))
466 kDebug(180) <<
"Find resource: " << type;
467 for (QStringList::ConstIterator pit = m_prefixes.begin();
468 pit != m_prefixes.end();
471 kDebug(180) <<
"Prefix: " << *pit;
477 if(strcmp(type,
"exe") == 0) {
478 if(!filename.endsWith(QLatin1String(
".exe"), Qt::CaseInsensitive))
479 filename += QLatin1String(
".exe");
492 KDE_struct_stat buff;
493 if ((
KDE::access(file, R_OK) == 0) && (
KDE::stat(file, &buff) == 0) && (S_ISREG(buff.st_mode))) {
494 hash = hash +
static_cast<quint32>(buff.st_ctime);
501 SearchOptions options )
const
505 if (!QDir::isRelativePath(filename))
510 QStringList candidates = d->resourceDirs(type, filename);
512 foreach (
const QString& candidate, candidates )
514 hash =
updateHash(candidate + filename, hash);
515 if ( !( options &
Recursive ) && hash ) {
528 if (!QDir::isRelativePath(reldir))
530 testdir.setPath(reldir);
531 if (testdir.exists())
533 if (reldir.endsWith(QLatin1Char(
'/')))
536 list.append(reldir+QLatin1Char(
'/'));
541 const QStringList candidates = d->resourceDirs(type, reldir);
543 for (QStringList::ConstIterator it = candidates.begin();
544 it != candidates.end(); ++it) {
545 testdir.setPath(*it + reldir);
546 if (testdir.exists())
547 list.append(testdir.absolutePath() + QLatin1Char(
'/'));
554 const QString& _filename)
const
557 if (_filename.isEmpty()) {
558 kWarning() <<
"filename for type " << type <<
" in KStandardDirs::findResourceDir is not supposed to be empty!!";
565 if(strcmp(type,
"exe") == 0) {
566 if(!filename.endsWith(QLatin1String(
".exe"), Qt::CaseInsensitive))
567 filename += QLatin1String(
".exe");
570 const QStringList candidates = d->resourceDirs(type, filename);
572 for (QStringList::ConstIterator it = candidates.begin();
573 it != candidates.end(); ++it) {
574 if (
exists(*it + filename)) {
580 if(
false && strcmp(type,
"locale"))
581 kDebug(180) <<
"KStdDirs::findResDir(): can't find \"" << filename <<
"\" in type \"" << type <<
"\".";
593 if (fullPath.endsWith(QLatin1Char(
'/')))
594 return QDir(fullPath).exists();
595 return QFileInfo(fullPath).exists();
597 KDE_struct_stat buff;
598 QByteArray cFullPath = QFile::encodeName(fullPath);
599 if (access(cFullPath, R_OK) == 0 && KDE_stat( cFullPath, &buff ) == 0) {
600 if (!fullPath.endsWith(QLatin1Char(
'/'))) {
601 if (S_ISREG( buff.st_mode ))
604 if (S_ISDIR( buff.st_mode ))
612 const QRegExp ®exp,
615 bool recursive,
bool unique)
617 const QString pattern = regexp.pattern();
618 if (recursive || pattern.contains(QLatin1Char(
'?')) || pattern.contains(QLatin1Char(
'*')))
623 QString path_ = path + QLatin1String(
"*.*" );
624 WIN32_FIND_DATA findData;
625 HANDLE hFile = FindFirstFile( (LPWSTR)path_.utf16(), &findData );
626 if( hFile == INVALID_HANDLE_VALUE )
629 const int len = wcslen( findData.cFileName );
630 if (!( findData.cFileName[0] ==
'.' &&
631 findData.cFileName[1] ==
'\0' ) &&
632 !( findData.cFileName[0] ==
'.' &&
633 findData.cFileName[1] ==
'.' &&
634 findData.cFileName[2] ==
'\0' ) &&
635 ( findData.cFileName[len-1] !=
'~' ) ) {
636 QString fn = QString::fromUtf16( (
const unsigned short*)findData.cFileName );
637 if (!recursive && !regexp.exactMatch(fn))
640 bool bIsDir = ( ( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == FILE_ATTRIBUTE_DIRECTORY );
644 relPart + fn + QLatin1Char(
'/'),
645 regexp, list, relList, recursive, unique);
647 if (!regexp.exactMatch(fn))
652 if ( !unique || !relList.contains(relPart + fn,
cs) )
654 list.append( pathfn );
655 relList.append( relPart + fn );
659 }
while( FindNextFile( hFile, &findData ) != 0 );
663 DIR *dp = opendir( QFile::encodeName(path));
667 assert(path.endsWith(QLatin1Char(
'/')));
671 while( ( ep = readdir( dp ) ) != 0L )
673 QString fn( QFile::decodeName(ep->d_name));
674 if (fn == QString::fromLatin1(
".") || fn == QString::fromLatin1(
"..") || fn.at(fn.length() - 1) == QLatin1Char(
'~'))
677 if (!recursive && !regexp.exactMatch(fn))
684#ifdef HAVE_DIRENT_D_TYPE
685 isDir = ep->d_type == DT_DIR;
686 isReg = ep->d_type == DT_REG;
688 if (ep->d_type == DT_UNKNOWN || ep->d_type == DT_LNK)
691 KDE_struct_stat buff;
693 kDebug(180) <<
"Error stat'ing " << pathfn <<
" : " <<
perror;
696 isReg = S_ISREG (buff.st_mode);
697 isDir = S_ISDIR (buff.st_mode);
702 lookupDirectory(pathfn + QLatin1Char(
'/'), relPart + fn + QLatin1Char(
'/'), regexp, list, relList, recursive, unique);
704 if (!regexp.exactMatch(fn))
709 if (!unique || !relList.contains(relPart + fn,
cs))
711 list.append( pathfn );
712 relList.append( relPart + fn );
724 KDE_struct_stat buff;
727 if ( S_ISREG( buff.st_mode))
729 if (!unique || !relList.contains(relPart + fn,
cs))
731 list.append( pathfn );
732 relList.append( relPart + fn );
740 const QRegExp ®exp,
743 bool recursive,
bool unique)
745 if (relpath.isEmpty()) {
747 Q_ASSERT(
prefix != QLatin1String(
"/"));
749 relList, recursive, unique);
755 int slash = relpath.indexOf(QLatin1Char(
'/'));
757 rest = relpath.left(relpath.length() - 1);
759 path = relpath.left(slash);
760 rest = relpath.mid(slash + 1);
767 assert(
prefix.endsWith(QLatin1Char(
'/')));
769 if (path.contains(QLatin1Char(
'*')) || path.contains(QLatin1Char(
'?'))) {
771 QRegExp pathExp(path, Qt::CaseSensitive, QRegExp::Wildcard);
775 WIN32_FIND_DATA findData;
776 HANDLE hFile = FindFirstFile( (LPWSTR)prefix_.utf16(), &findData );
777 if( hFile == INVALID_HANDLE_VALUE )
780 const int len = wcslen( findData.cFileName );
781 if (!( findData.cFileName[0] ==
'.' &&
782 findData.cFileName[1] ==
'\0' ) &&
783 !( findData.cFileName[0] ==
'.' &&
784 findData.cFileName[1] ==
'.' &&
785 findData.cFileName[2] ==
'\0' ) &&
786 ( findData.cFileName[len-1] !=
'~' ) ) {
787 const QString fn = QString::fromUtf16( (
const unsigned short*)findData.cFileName );
788 if ( !pathExp.exactMatch(fn) )
790 if ( ( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == FILE_ATTRIBUTE_DIRECTORY )
792 rest, relPart + fn + QLatin1Char(
'/'),
793 regexp, list, relList, recursive, unique);
795 }
while( FindNextFile( hFile, &findData ) != 0 );
798 DIR *dp = opendir( QFile::encodeName(
prefix) );
805 while( ( ep = readdir( dp ) ) != 0L )
807 QString fn( QFile::decodeName(ep->d_name));
808 if (fn == QLatin1String(
".") || fn == QLatin1String(
"..") || fn.at(fn.length() - 1) == QLatin1Char(
'~'))
811 if ( !pathExp.exactMatch(fn) )
818#ifdef HAVE_DIRENT_D_TYPE
819 isDir = ep->d_type == DT_DIR;
821 if (ep->d_type == DT_UNKNOWN || ep->d_type == DT_LNK)
825 KDE_struct_stat buff;
827 kDebug(180) <<
"Error stat'ing " << fn <<
" : " <<
perror;
830 isDir = S_ISDIR (buff.st_mode);
833 lookupPrefix(fn + QLatin1Char(
'/'), rest, rfn + QLatin1Char(
'/'), regexp, list, relList, recursive, unique);
842 relPart + path + QLatin1Char(
'/'), regexp, list,
843 relList, recursive, unique);
850 SearchOptions options,
856 if ( !filter.isEmpty() )
858 int slash = filter.lastIndexOf(QLatin1Char(
'/'));
862 filterPath = filter.left(slash + 1);
863 filterFile = filter.mid(slash + 1);
868 if ( !QDir::isRelativePath(filter) )
871 candidates << filterPath.left(3);
872 filterPath = filterPath.mid(3);
874 candidates << QString::fromLatin1(
"/");
875 filterPath = filterPath.mid(1);
880 candidates = d->resourceDirs(type, filter);
883 if (filterFile.isEmpty()) {
884 filterFile =
QString(QLatin1Char(
'*'));
887 QRegExp regExp(filterFile, Qt::CaseSensitive, QRegExp::Wildcard);
890 foreach (
const QString& candidate, candidates )
902 SearchOptions options )
const
918 if (!strRet.endsWith(QLatin1Char(
'/')))
919 return strRet + QLatin1Char(
'/');
922 if (dirname.isEmpty() || (dirname.size() == 1 && dirname.at(0) == QLatin1Char(
'/')))
925 if (dirname.at(0) != QLatin1Char(
'/')) {
926 qWarning(
"realPath called with a relative path '%s', please fix", qPrintable(dirname));
930 char realpath_buffer[MAXPATHLEN + 1];
931 memset(realpath_buffer, 0, MAXPATHLEN + 1);
934 if (realpath( QFile::encodeName(dirname).constData(), realpath_buffer) != 0) {
936 int len = strlen(realpath_buffer);
937 realpath_buffer[len] =
'/';
938 realpath_buffer[len+1] = 0;
939 return QFile::decodeName(realpath_buffer);
947 if (!dir.endsWith(QLatin1Char(
'/')))
948 dir += QLatin1Char(
'/');
952 const int pos = dir.lastIndexOf(QLatin1Char(
'/'), -2);
954 relative.prepend(dir.mid(pos+1));
955 dir = dir.left(pos+1);
956 Q_ASSERT(dir.endsWith(QLatin1Char(
'/')));
958 Q_ASSERT(!relative.isEmpty());
959 if (!relative.isEmpty()) {
976 LPCWSTR lpIn = (LPCWSTR)filename.utf16();
977 QVarLengthArray<WCHAR, MAX_PATH> buf(MAX_PATH);
978 DWORD len = GetFullPathNameW(lpIn, buf.size(), buf.data(), NULL);
979 if (len > (DWORD)buf.size()) {
981 len = GetFullPathNameW(lpIn, buf.size(), buf.data(), NULL);
985 return QString::fromUtf16((
const unsigned short*)buf.data()).replace(QLatin1Char(
'\\'),QLatin1Char(
'/'));
987 char realpath_buffer[MAXPATHLEN + 1];
988 memset(realpath_buffer, 0, MAXPATHLEN + 1);
991 if (realpath( QFile::encodeName(filename).constData(), realpath_buffer) != 0) {
993 return QFile::decodeName(realpath_buffer);
1001void KStandardDirs::KStandardDirsPrivate::createSpecialResource(
const char *type)
1005 gethostname(hostname, 255);
1006 const QString localkdedir = m_prefixes.first();
1007 QString dir = localkdedir + QString::fromLatin1(type) + QLatin1Char(
'-') + QString::fromLocal8Bit(hostname);
1010 int result = readlink(QFile::encodeName(dir).constData(), link, 1023);
1011 bool relink = (result == -1) && (errno == ENOENT);
1015 if (!QDir::isRelativePath(QFile::decodeName(link)))
1017 KDE_struct_stat stat_buf;
1018 int res =
KDE::lstat(QFile::decodeName(link), &stat_buf);
1019 if ((res == -1) && (errno == ENOENT))
1023 else if ((res == -1) || (!S_ISDIR(stat_buf.st_mode)))
1025 fprintf(stderr,
"Error: \"%s\" is not a directory.\n", link);
1028 else if (stat_buf.st_uid != getuid())
1030 fprintf(stderr,
"Error: \"%s\" is owned by uid %d instead of uid %d.\n", link, stat_buf.st_uid, getuid());
1038 if (!makeDir(dir, 0700))
1039 fprintf(stderr,
"failed to create \"%s\"", qPrintable(dir));
1041 result = readlink(QFile::encodeName(dir).constData(), link, 1023);
1046 QString srv = findExe(QLatin1String(
"lnusertemp"), installPath(
"libexec"));
1048 srv = findExe(QLatin1String(
"lnusertemp"));
1051 if (system(QByteArray(QFile::encodeName(srv) +
' ' + type)) == -1) {
1052 fprintf(stderr,
"Error: unable to launch lnusertemp command" );
1054 result = readlink(QFile::encodeName(dir).constData(), link, 1023);
1061 dir = QFile::decodeName(link);
1063 dir = QDir::cleanPath(dir + QFile::decodeName(link));
1066 q->addResourceDir(type, dir + QLatin1Char(
'/'),
false);
1071 return d->resourceDirs(type,
QString());
1074QStringList KStandardDirs::KStandardDirsPrivate::resourceDirs(
const char* type,
const QString& subdirForRestrictions)
1076 QMutexLocker lock(&m_cacheMutex);
1077 const bool dataRestrictionActive = m_restrictionsActive
1078 && (strcmp(type,
"data") == 0)
1079 && hasDataRestrictions(subdirForRestrictions);
1085 if (dirCacheIt != m_dircache.constEnd() && !dataRestrictionActive) {
1087 candidates = *dirCacheIt;
1092 if (strcmp(type,
"socket") == 0)
1093 createSpecialResource(type);
1094 else if (strcmp(type,
"tmp") == 0)
1095 createSpecialResource(type);
1096 else if (strcmp(type,
"cache") == 0)
1097 createSpecialResource(type);
1101 bool restrictionActive =
false;
1102 if (m_restrictionsActive) {
1103 if (dataRestrictionActive)
1104 restrictionActive =
true;
1105 if (m_restrictions.value(
"all",
false))
1106 restrictionActive =
true;
1107 else if (m_restrictions.value(type,
false))
1108 restrictionActive =
true;
1112 const QString typeInstallPath = installPath(type);
1113 const QString installdir = typeInstallPath.isEmpty() ?
QString() : realPath(typeInstallPath);
1114 const QString installprefix = installPath(
"kdedir");
1115 if (!
dirs.isEmpty())
1119 for (QStringList::ConstIterator it =
dirs.constBegin();
1120 it !=
dirs.constEnd(); ++it)
1122 if ((*it).startsWith(QLatin1Char(
'%'))) {
1124 const int pos = (*it).indexOf(QLatin1Char(
'/'));
1125 QString rel = (*it).mid(1, pos - 1);
1126 QString rest = (*it).mid(pos + 1);
1127 const QStringList basedirs = resourceDirs(rel.toUtf8().constData(), subdirForRestrictions);
1128 for (QStringList::ConstIterator it2 = basedirs.begin();
1129 it2 != basedirs.end(); ++it2)
1131 const QString path = realPath( *it2 + rest );
1132 testdir.setPath(path);
1133 if ((local || testdir.exists()) && !candidates.contains(path,
cs))
1134 candidates.append(path);
1141 if (strncmp(type,
"xdgdata-", 8) == 0)
1142 prefixList = &(xdgdata_prefixes);
1143 else if (strncmp(type,
"xdgconf-", 8) == 0)
1144 prefixList = &(xdgconf_prefixes);
1146 prefixList = &m_prefixes;
1148 for (QStringList::ConstIterator pit = prefixList->begin();
1149 pit != prefixList->end();
1153 if((*pit).compare(installprefix,
cs) != 0 || installdir.isEmpty() || !strcmp(
"exe", type))
1155 for (QStringList::ConstIterator it =
dirs.constBegin();
1156 it !=
dirs.constEnd(); ++it)
1158 if ((*it).startsWith(QLatin1Char(
'%')))
1160 const QString path = realPath( *pit + *it );
1161 testdir.setPath(path);
1162 if (local && restrictionActive)
1164 if ((local || testdir.exists()) && !candidates.contains(path,
cs))
1165 candidates.append(path);
1170 if (local && !strcmp(
"config", type))
1171 candidates.append(QLatin1String(
"/etc/kde/"));
1177 testdir.setPath(installdir);
1178 if(testdir.exists() && ! candidates.contains(installdir,
cs))
1179 candidates.append(installdir);
1185 if (!installdir.isEmpty()) {
1187 foreach (
const QString &s, candidates) {
1188 if (installdir.startsWith(s,
cs)) {
1194 candidates.append(installdir);
1197 const QStringList absDirs = m_absolutes.value(type);
1198 for (QStringList::ConstIterator it = absDirs.constBegin();
1199 it != absDirs.constEnd(); ++it)
1201 testdir.setPath(*it);
1202 if (testdir.exists()) {
1203 const QString filename = realPath( *it );
1204 if (!candidates.contains(filename,
cs)) {
1205 candidates.append(filename);
1212 if (!dataRestrictionActive) {
1214 m_dircache.insert(type, candidates);
1219 kDebug(180) <<
"found dirs for resource" << type <<
":" << candidates;
1228 QStringList ret = QString::fromLocal8Bit(qgetenv(
"PATHEXT")).split(QLatin1Char(
';'));
1229 if (!ret.contains(QLatin1String(
".exe"), Qt::CaseInsensitive)) {
1232 ret << QLatin1String(
".exe")
1233 << QLatin1String(
".com")
1234 << QLatin1String(
".bat")
1235 << QLatin1String(
".cmd");
1248 p = QString::fromLocal8Bit( qgetenv(
"PATH" ) );
1251 QString delimiters(QLatin1Char(KPATH_SEPARATOR));
1252 delimiters += QLatin1Char(
'\b');
1258 for(
int i = 0; i < tokens.count(); i++ )
1272 bundle += QLatin1String(
".app/Contents/MacOS/") + bundle.section(QLatin1Char(
'/'), -1);
1273 info.setFile( bundle );
1275 if (file = fopen(info.absoluteFilePath().toUtf8().constData(),
"r")) {
1278 if ((stat(info.absoluteFilePath().toUtf8().constData(), &_stat)) < 0) {
1281 if ( ignore || (_stat.st_mode & S_IXUSR) ) {
1282 if ( ((_stat.st_mode & S_IFMT) == S_IFREG) || ((_stat.st_mode & S_IFMT) == S_IFLNK) ) {
1296 if ( !bundle.isEmpty() ) {
1301 QFileInfo info( path );
1302 QFileInfo orig = info;
1303#if defined(Q_OS_DARWIN) || defined(Q_OS_MAC)
1305 if (file = fopen(orig.absoluteFilePath().toUtf8().constData(),
"r")) {
1308 if ((stat(orig.absoluteFilePath().toUtf8().constData(), &_stat)) < 0) {
1311 if ( ignoreExecBit || (_stat.st_mode & S_IXUSR) ) {
1312 if ( ((_stat.st_mode & S_IFMT) == S_IFREG) || ((_stat.st_mode & S_IFMT) == S_IFLNK) ) {
1313 orig.makeAbsolute();
1314 return orig.filePath();
1320 if( info.exists() && info.isSymLink() )
1321 info = QFileInfo( info.canonicalFilePath() );
1322 if( info.exists() && ( ignoreExecBit || info.isExecutable() ) && info.isFile() ) {
1326 orig.makeAbsolute();
1327 return orig.filePath();
1336 SearchOptions options )
1342 if (!executable_extensions.contains(appname.section(QLatin1Char(
'.'), -1, -1, QString::SectionIncludeLeadingSep), Qt::CaseInsensitive)) {
1344 foreach (
const QString& extension, executable_extensions) {
1345 found_exe =
findExe(appname + extension, pstr, options);
1346 if (!found_exe.isEmpty()) {
1356 if (appname.contains(QDir::separator()))
1367 if (!result.isEmpty()) {
1374 for (QStringList::ConstIterator it = exePaths.begin(); it != exePaths.end(); ++it)
1376 p = (*it) + QLatin1Char(
'/');
1381 if (!result.isEmpty()) {
1391 if (!result.isEmpty()) {
1404 const QString& pstr, SearchOptions options )
1408 if (!executable_extensions.contains(appname.section(QLatin1Char(
'.'), -1, -1, QString::SectionIncludeLeadingSep), Qt::CaseInsensitive)) {
1410 foreach (
const QString& extension, executable_extensions) {
1411 total +=
findAllExe (list, appname + extension, pstr, options);
1421 for (QStringList::ConstIterator it = exePaths.begin(); it != exePaths.end(); ++it)
1423 p = (*it) + QLatin1Char(
'/');
1428 if ( !bundle.isEmpty() ) {
1430 list.append( bundle );
1436 if( info.exists() && ( ( options & IgnoreExecBit ) || info.isExecutable())
1437 && info.isFile() ) {
1442 return list.count();
1452 return f.absoluteFilePath();
1461 const int len = str.length();
1464 for(
int index = 0; index < len; index++) {
1465 if (delim.contains(str[index])) {
1469 token += str[index];
1472 if (!token.isEmpty()) {
1477#ifndef KDE_NO_DEPRECATED
1480 return QString(QLatin1Char(
'%')) + QString::fromLatin1(type) + QLatin1Char(
'/');
1488 QMutexLocker lock(&d->m_cacheMutex);
1489 QString path = d->m_savelocations.value(type);
1493 if (dirs.isEmpty() && (
1494 (strcmp(type,
"socket") == 0) ||
1495 (strcmp(type,
"tmp") == 0) ||
1496 (strcmp(type,
"cache") == 0) ))
1499 dirs = d->m_relatives.value(type);
1501 if (!dirs.isEmpty())
1503 path = dirs.first();
1505 if (path.startsWith(QLatin1Char(
'%'))) {
1507 const int pos = path.indexOf(QLatin1Char(
'/'));
1508 QString rel = path.mid(1, pos - 1);
1509 QString rest = path.mid(pos + 1);
1511 path = basepath + rest;
1515 if (strncmp(type,
"xdgdata-", 8) == 0) {
1517 }
else if (strncmp(type,
"xdgconf-", 8) == 0) {
1520 path =
realPath( localkdedir() + path );
1524 dirs = d->m_absolutes.value(type);
1525 if (dirs.isEmpty()) {
1526 qFatal(
"KStandardDirs: The resource type %s is not registered", type);
1532 d->m_savelocations.insert(type, path.endsWith(QLatin1Char(
'/')) ? path : path + QLatin1Char(
'/'));
1534 QString fullPath = path + suffix;
1537 if (
KDE::stat(fullPath, &st) != 0 || !(S_ISDIR(st.st_mode))) {
1546 if(!
makeDir(fullPath, 0700)) {
1549 d->m_dircache.remove(type);
1551 if (!fullPath.endsWith(QLatin1Char(
'/')))
1552 fullPath += QLatin1Char(
'/');
1560 int i = absPath.lastIndexOf(QLatin1Char(
'/'));
1567 for (QStringList::ConstIterator it = candidates.begin();
1568 it != candidates.end(); ++it) {
1569 if (fullPath.startsWith(*it,
cs)) {
1570 return fullPath.mid((*it).length());
1580 if (QDir::isRelativePath(dir))
1584 return QDir().mkpath(dir);
1587 uint len = target.length();
1590 if (dir.at(len - 1) != QLatin1Char(
'/'))
1591 target += QLatin1Char(
'/');
1599 int pos = target.indexOf(QLatin1Char(
'/'), i);
1600 base += target.mid(i - 1, pos - i + 1);
1601 QByteArray baseEncoded = QFile::encodeName(base);
1603 if (KDE_stat(baseEncoded, &st) != 0)
1607 if (KDE_lstat(baseEncoded, &st) == 0)
1608 (void)unlink(baseEncoded);
1610 if (KDE_mkdir(baseEncoded,
static_cast<mode_t
>(mode)) != 0) {
1611 baseEncoded.prepend(
"trying to create local folder " );
1612 perror(baseEncoded.constData());
1626 c_path = qgetenv(env);
1627 if (c_path.isEmpty())
1635 c_path = retval.toLatin1();
1638 return QDir::fromNativeSeparators(QFile::decodeName(c_path));
1642static QString executablePrefix()
1644 char path_buffer[MAXPATHLEN + 1];
1645 path_buffer[MAXPATHLEN] = 0;
1646 int length = readlink (
"/proc/self/exe", path_buffer, MAXPATHLEN);
1650 path_buffer[length] =
'\0';
1652 QString path = QFile::decodeName(path_buffer);
1657 int pos = path.lastIndexOf(QLatin1Char(
'/'));
1660 pos = path.lastIndexOf(QLatin1Char(
'/'), pos - 1);
1664 return path.left(pos);
1668void KStandardDirs::addResourcesFrom_krcdirs()
1670 QString localFile = QDir::currentPath() + QLatin1String(
"/.krcdirs");
1671 if (!QFile::exists(localFile))
1674 QSettings iniFile(localFile, QSettings::IniFormat);
1675 iniFile.beginGroup(QString::fromLatin1(
"KStandardDirs"));
1677 foreach(
const QString &key, resources)
1679 QDir path(iniFile.value(key).toString());
1683 if(path.makeAbsolute())
1688void KStandardDirs::addKDEDefaults()
1690 addResourcesFrom_krcdirs();
1696 if (!kdedirs.isEmpty())
1702 QString execPrefix(QFile::decodeName(EXEC_INSTALL_PREFIX));
1703 if (!execPrefix.isEmpty() && !kdedirList.contains(execPrefix,
cs))
1704 kdedirList.append(execPrefix);
1706 const QString linuxExecPrefix = executablePrefix();
1707 if ( !linuxExecPrefix.isEmpty() )
1708 kdedirList.append( linuxExecPrefix );
1714 if (!localKdeDir.isEmpty()) {
1715 if (!localKdeDir.endsWith(QLatin1Char(
'/')))
1716 localKdeDir += QLatin1Char(
'/');
1722#if defined(Q_WS_MACX)
1723 localKdeDir = QDir::homePath() + QLatin1String(
"/Library/Preferences/KDE/");
1724#elif defined(Q_WS_WIN)
1726 WCHAR wPath[MAX_PATH+1];
1727 if ( SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wPath) == S_OK) {
1728 localKdeDir = QDir::fromNativeSeparators(QString::fromUtf16((
const ushort *) wPath)) + QLatin1Char(
'/') + QString::fromLatin1(KDE_DEFAULT_HOME) + QLatin1Char(
'/');
1731 localKdeDir = QDir::homePath() + QLatin1Char(
'/') + QString::fromLatin1(KDE_DEFAULT_HOME) + QLatin1Char(
'/');
1736 localKdeDir = QDir::homePath() + QLatin1Char(
'/') + QString::fromLatin1(KDE_DEFAULT_HOME) + QLatin1Char(
'/');
1740 if (localKdeDir != QLatin1String(
"-/"))
1750 if (bundleDir.dirName() == QLatin1String(
"MacOS")) {
1758 QStringList::ConstIterator end(kdedirList.end());
1759 for (QStringList::ConstIterator it = kdedirList.constBegin();
1760 it != kdedirList.constEnd(); ++it)
1770 if (!xdgdirs.isEmpty())
1777 xdgdirList.append(QString::fromLatin1(
"/etc/xdg"));
1779 xdgdirList.append(
installPath(
"kdedir") + QString::fromLatin1(
"etc/xdg"));
1781 xdgdirList.append(QFile::decodeName(KDESYSCONFDIR
"/xdg"));
1786 if (!localXdgDir.isEmpty()) {
1787 if (!localXdgDir.endsWith(QLatin1Char(
'/')))
1788 localXdgDir += QLatin1Char(
'/');
1791 localXdgDir = QDir::homePath() + QString::fromLatin1(
"/Library/Preferences/XDG/");
1793 localXdgDir = QDir::homePath() + QString::fromLatin1(
"/.config/");
1800 for (QStringList::ConstIterator it = xdgdirList.constBegin();
1801 it != xdgdirList.constEnd(); ++it)
1810 for (QStringList::ConstIterator it = kdedirList.constBegin();
1811 it != kdedirList.constEnd(); ++it) {
1813 if (!dir.endsWith(QLatin1Char(
'/')))
1814 dir += QLatin1Char(
'/');
1815 kdedirDataDirs.append(dir + QLatin1String(
"share/"));
1819 if (!xdgdirs.isEmpty()) {
1824 Q_FOREACH(
const QString& dir, kdedirDataDirs) {
1825 if (!xdgdirList.contains(dir,
cs))
1826 xdgdirList.append(dir);
1829 xdgdirList = kdedirDataDirs;
1831 xdgdirList.append(QString::fromLatin1(
"/usr/local/share/"));
1832 xdgdirList.append(QString::fromLatin1(
"/usr/share/"));
1837 if (!localXdgDir.isEmpty())
1839 if (localXdgDir[localXdgDir.length()-1] != QLatin1Char(
'/'))
1840 localXdgDir += QLatin1Char(
'/');
1844 localXdgDir = QDir::homePath() + QLatin1String(
"/.local/share/");
1850 for (QStringList::ConstIterator it = xdgdirList.constBegin();
1851 it != xdgdirList.constEnd(); ++it)
1880 if (mapFile.isEmpty() || !QFile::exists(mapFile))
1882 profiles << QString::fromLatin1(
"default");
1886 struct passwd *pw = getpwuid(geteuid());
1889 profiles << QString::fromLatin1(
"default");
1893 QByteArray user = pw->pw_name;
1895 gid_t sup_gids[512];
1896 int sup_gids_nr = getgroups(512, sup_gids);
1900 if (mapCfg.
hasKey(user.constData()))
1911 for( QStringList::ConstIterator it = groups.begin();
1912 it != groups.end(); ++it )
1914 QByteArray grp = (*it).toUtf8();
1916 struct group *grp_ent = getgrnam(grp);
1917 if (!grp_ent)
continue;
1918 gid_t gid = grp_ent->gr_gid;
1919 if (pw->pw_gid == gid)
1926 for(
int i = 0; i < sup_gids_nr; i++)
1928 if (sup_gids[i] == gid)
1938 if (profiles.isEmpty())
1939 profiles << QString::fromLatin1(
"default");
1947 if (!d->m_checkRestrictions)
1957 QString group = QLatin1String(
"Directories");
1963 int i = kioskAdmin.indexOf(QLatin1Char(
':'));
1964 QString user = kioskAdmin.left(i);
1965 QString host = kioskAdmin.mid(i+1);
1968 char hostname[ 256 ];
1969 hostname[ 0 ] =
'\0';
1970 if (!gethostname( hostname, 255 ))
1971 hostname[
sizeof(hostname)-1] =
'\0';
1974 (host.isEmpty() || (host == QLatin1String(hostname))))
1980 bool readProfiles =
true;
1983 readProfiles =
false;
1987 if (!profileDirsPrefix.isEmpty() && !profileDirsPrefix.endsWith(QLatin1Char(
'/')))
1988 profileDirsPrefix.append(QLatin1Char(
'/'));
1995 bool priority =
false;
2000 for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it)
2008 if (list.isEmpty() && !profile.isEmpty() && !profileDirsPrefix.isEmpty())
2010 QString dir = profileDirsPrefix + profile;
2020 it2 != entries.end(); ++it2)
2022 const QString key = it2.key();
2023 if (key.startsWith(QLatin1String(
"dir_"))) {
2026 QStringList::ConstIterator sIt(dirs.begin());
2028 for (; sIt != dirs.end(); ++sIt)
2034 if (profiles.isEmpty())
2036 profile = profiles.back();
2037 group = QString::fromLatin1(
"Directories-%1").arg(profile);
2038 profiles.pop_back();
2044 if (!
kde_kiosk_admin || qgetenv(
"KDE_KIOSK_NO_RESTRICTIONS").isEmpty())
2049 it2 != entries.end(); ++it2)
2051 const QString key = it2.key();
2054 d->m_restrictionsActive =
true;
2055 const QByteArray cKey = key.toLatin1();
2056 d->m_restrictions.insert(cKey,
true);
2057 d->m_dircache.remove(cKey);
2058 d->m_savelocations.remove(cKey);
2064 bool configDirsChanged = (
resourceDirs(
"config").count() != configdirs);
2066 d->m_checkRestrictions = configDirsChanged;
2068 return configDirsChanged;
2074 return d->m_prefixes.first();
2080 return d->xdgdata_prefixes.first();
2086 return d->xdgconf_prefixes.first();
2104 const QString& filename,
bool createDir,
2109 int slash = filename.lastIndexOf(QLatin1Char(
'/')) + 1;
2115 QString dir = filename.left(slash);
2116 QString file = filename.mid(slash);
2123 if ( accessOK == 0 )
2129 if ( (mode & W_OK) == 0 )
2138 int pos = dirName.lastIndexOf(QLatin1Char(
'/'));
2141 else if ( pos == 0 )
2144 dirName.truncate(pos);
2148 if ( accessOK == 0 )
KStandardDirs * dirs() const
Returns the application standard dirs object.
A class for one specific group in a KConfig object.
T readEntry(const QString &key, const T &aDefault) const
Reads the value of an entry specified by pKey in the current group.
bool hasKey(const QString &key) const
Checks whether the key has an entry in this group.
QMap< QString, QString > entryMap() const
Returns a map (tree) of entries for all entries in this group.
The central class of the KDE configuration data system.
QMap< QString, QString > entryMap(const QString &aGroup=QString()) const
Returns a map (tree) of entries in a particular group.
QString localizedFilePath(const QString &filePath) const
Site-independent access to standard KDE directories.
QString localkdedir() const
Returns the toplevel directory in which KStandardDirs will store things.
KStandardDirs()
KStandardDirs' constructor.
void addXdgConfigPrefix(const QString &dir)
Adds another search dir to front of the XDG_CONFIG_XXX list of prefixes.
QString localxdgconfdir() const
static QString findExe(const QString &appname, const QString &pathstr=QString(), SearchOptions options=NoSearchOptions)
Finds the executable in the system path.
QString relativeLocation(const char *type, const QString &absPath)
Converts an absolute path to a path relative to a certain resource.
static bool exists(const QString &fullPath)
Checks for existence and accessability of a file or directory.
static bool checkAccess(const QString &pathname, int mode)
Check, if a file may be accessed in a given mode.
static QString kde_default(const char *type)
This returns a default relative path for the standard KDE resource types.
QStringList allTypes() const
This function will return a list of all the types that KStandardDirs supports.
static QString installPath(const char *type)
static bool makeDir(const QString &dir, int mode=0755)
Recursively creates still-missing directories in the given path.
static int findAllExe(QStringList &list, const QString &appname, const QString &pathstr=QString(), SearchOptions options=NoSearchOptions)
Finds all occurrences of an executable in the system path.
QString findResourceDir(const char *type, const QString &filename) const
Tries to find the directory the file is in.
QString kfsstnd_prefixes()
QString saveLocation(const char *type, const QString &suffix=QString(), bool create=true) const
Finds a location to save files into for the given type in the user's home directory.
QStringList findAllResources(const char *type, const QString &filter=QString(), SearchOptions options=NoSearchOptions) const
Tries to find all resources with the specified type.
QStringList findDirs(const char *type, const QString &reldir) const
Tries to find all directories whose names consist of the specified type and a relative path.
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
This function is much like locate.
virtual ~KStandardDirs()
KStandardDirs' destructor.
bool addResourceDir(const char *type, const QString &absdir, bool priority=true)
Adds absolute path at the beginning of the search path for particular types (for example in case of i...
QString kfsstnd_xdg_data_prefixes()
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
This function is just for convenience.
bool addResourceType(const char *type, const QString &relativename, bool priority=true)
Adds suffixes for types.
void addPrefix(const QString &dir)
Adds another search dir to front of the fsstnd list.
static QString realPath(const QString &dirname)
Expands all symbolic links and resolves references to '/.
void addXdgDataPrefix(const QString &dir)
Adds another search dir to front of the XDG_DATA_XXX list of prefixes.
static QStringList systemPaths(const QString &pstr=QString())
Returns a QStringList list of pathnames in the system path.
bool addCustomized(KConfig *config)
Reads customized entries out of the given config object and add them via addResourceDirs().
static QString realFilePath(const QString &filename)
Expands all symbolic links and resolves references to '/.
QString findResource(const char *type, const QString &filename) const
Tries to find a resource in the following order:
QString localxdgdatadir() const
bool isRestrictedResource(const char *type, const QString &relPath=QString()) const
Checks whether a resource is restricted as part of the KIOSK framework.
quint32 calcResourceHash(const char *type, const QString &filename, SearchOptions options=NoSearchOptions) const
Returns a number that identifies this version of the resource.
QString kfsstnd_xdg_conf_prefixes()
QStringList resourceDirs(const char *type) const
This function is used internally by almost all other function as it serves and fills the directories ...
Represents a user on your system.
QString loginName() const
The login name of the user.
QDebug perror(QDebug s, KDebugTag)
QString mac_app_filename()
Get the application name.
QString getWin32RegistryValue(HKEY key, const QString &subKey, const QString &item, bool *ok)
static Qt::CaseSensitivity cs
static Qt::CaseSensitivity cs
static void priorityAdd(QStringList &prefixes, const QString &dir, bool priority)
static void lookupDirectory(const QString &path, const QString &relPart, const QRegExp ®exp, QStringList &list, QStringList &relList, bool recursive, bool unique)
static quint32 updateHash(const QString &file, quint32 hash)
static QStringList executableExtensions()
static const int types_indices[]
static QString equalizePath(QString &str)
static QString getBundle(const QString &path, bool ignore)
static void tokenize(QStringList &token, const QString &str, const QString &delim)
static QString checkExecutable(const QString &path, bool ignoreExecBit)
static void lookupPrefix(const QString &prefix, const QString &relpath, const QString &relPart, const QRegExp ®exp, QStringList &list, QStringList &relList, bool recursive, bool unique)
static const char types_string[]
static QString readEnvPath(const char *env)
static QStringList lookupProfiles(const QString &mapFile)
int lstat(const QString &path, KDE_struct_stat *buf)
int stat(const QString &path, KDE_struct_stat *buf)
int access(const QString &path, int mode)
KStandardDirs * dirs()
Returns the application standard dirs object.
KLocale * locale()
Returns the global locale object.
QString tildeExpand(const QString &path)
Performs tilde expansion on path.