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