00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qplatformdefs.h"
00025 #include "qabstractfileengine.h"
00026 #include "private/qfsfileengine_p.h"
00027 #ifndef QT_NO_REGEXP
00028 # include "qregexp.h"
00029 #endif
00030 #include "qfile.h"
00031 #include "qdir.h"
00032 #include "qdatetime.h"
00033 #include "qdebug.h"
00034 #include "qvarlengtharray.h"
00035
00036 #include <stdlib.h>
00037 #include <limits.h>
00038 #include <errno.h>
00039 #if !defined(QWS) && defined(Q_OS_MAC)
00040 # include <private/qcore_mac_p.h>
00041 #endif
00042
00043 void QFSFileEnginePrivate::init()
00044 {
00045 }
00046
00047 int QFSFileEnginePrivate::sysOpen(const QString &fileName, int flags)
00048 {
00049 return QT_OPEN(QFile::encodeName(fileName), flags, 0666);
00050 }
00051
00052 bool QFSFileEngine::remove()
00053 {
00054 Q_D(QFSFileEngine);
00055 return unlink(QFile::encodeName(d->file)) == 0;
00056 }
00057
00058 bool QFSFileEngine::copy(const QString &)
00059 {
00060 return false;
00061 }
00062
00063 bool QFSFileEngine::rename(const QString &newName)
00064 {
00065 Q_D(QFSFileEngine);
00066 return ::rename(QFile::encodeName(d->file), QFile::encodeName(newName)) == 0;
00067 }
00068
00069 bool QFSFileEngine::link(const QString &newName)
00070 {
00071 Q_D(QFSFileEngine);
00072 return ::symlink(QFile::encodeName(d->file), QFile::encodeName(newName)) == 0;
00073 }
00074
00075 qint64 QFSFileEngine::size() const
00076 {
00077 Q_D(const QFSFileEngine);
00078 QT_STATBUF st;
00079 int ret = 0;
00080 const_cast<QFSFileEngine *>(this)->flush();
00081 if(d->fd != -1)
00082 ret = QT_FSTAT(d->fd, &st);
00083 else
00084 ret = QT_STAT(QFile::encodeName(d->file), &st);
00085 if(ret == -1)
00086 return 0;
00087 return st.st_size;
00088 }
00089
00090 bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const
00091 {
00092 QString dirName = name;
00093 if(createParentDirectories) {
00094 dirName = QDir::cleanPath(dirName);
00095 for(int oldslash = -1, slash=0; slash != -1; oldslash = slash) {
00096 slash = dirName.indexOf(QDir::separator(), oldslash+1);
00097 if(slash == -1) {
00098 if(oldslash == dirName.length())
00099 break;
00100 slash = dirName.length();
00101 }
00102 if(slash) {
00103 QByteArray chunk = QFile::encodeName(dirName.left(slash));
00104 QT_STATBUF st;
00105 if(QT_STAT(chunk, &st) != -1) {
00106 if((st.st_mode & S_IFMT) != S_IFDIR)
00107 return false;
00108 } else if(::mkdir(chunk, 0777) != 0) {
00109 return false;
00110 }
00111 }
00112 }
00113 return true;
00114 }
00115 #if defined(Q_OS_DARWIN) // Mac X doesn't support trailing /'s
00116 if(dirName[dirName.length() - 1] == '/')
00117 dirName = dirName.left(dirName.length() - 1);
00118 #endif
00119 return (::mkdir(QFile::encodeName(dirName), 0777) == 0);
00120 }
00121
00122 bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const
00123 {
00124 QString dirName = name;
00125 if(recurseParentDirectories) {
00126 dirName = QDir::cleanPath(dirName);
00127 for(int oldslash = 0, slash=dirName.length(); slash > 0; oldslash = slash) {
00128 QByteArray chunk = QFile::encodeName(dirName.left(slash));
00129 QT_STATBUF st;
00130 if(QT_STAT(chunk, &st) != -1) {
00131 if((st.st_mode & S_IFMT) != S_IFDIR)
00132 return false;
00133 if(::rmdir(chunk) != 0)
00134 return oldslash != 0;
00135 } else {
00136 return false;
00137 }
00138 slash = dirName.lastIndexOf(QDir::separator(), oldslash-1);
00139 }
00140 return true;
00141 }
00142 return ::rmdir(QFile::encodeName(dirName)) == 0;
00143 }
00144
00145 QStringList QFSFileEngine::entryList(QDir::Filters filters, const QStringList &filterNames) const
00146 {
00147 Q_D(const QFSFileEngine);
00148 QStringList ret;
00149 DIR *dir = opendir(QFile::encodeName(d->file));
00150 if(!dir)
00151 return ret;
00152
00153 const bool filterPermissions = ((filters & QDir::PermissionMask) && (filters & QDir::PermissionMask) != QDir::PermissionMask);
00154 const bool skipDirs = !(filters & (QDir::Dirs | QDir::AllDirs));
00155 const bool skipFiles = !(filters & QDir::Files);
00156 const bool skipSymlinks = (filters & QDir::NoSymLinks);
00157 const bool doReadable = !filterPermissions || (filters & QDir::Readable);
00158 const bool doWritable = !filterPermissions || (filters & QDir::Writable);
00159 const bool doExecutable = !filterPermissions || (filters & QDir::Executable);
00160 const bool includeHidden = (filters & QDir::Hidden);
00161 const bool includeSystem = (filters & QDir::System);
00162
00163 #ifndef QT_NO_REGEXP
00164
00165 QList<QRegExp> regexps;
00166 for (int i = 0; i < filterNames.size(); ++i) {
00167 regexps << QRegExp(filterNames.at(i),
00168 (filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive,
00169 QRegExp::Wildcard);
00170 }
00171 #endif
00172
00173 QFileInfo fi;
00174 dirent *file;
00175 #if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
00176 union {
00177 struct dirent mt_file;
00178 char b[sizeof(struct dirent) + MAXNAMLEN + 1];
00179 } u;
00180 while (readdir_r(dir, &u.mt_file, &file) == 0 && file)
00181 #else
00182 while ((file = readdir(dir)))
00183 #endif // _POSIX_THREAD_SAFE_FUNCTIONS
00184 {
00185 QString fn = QFile::decodeName(QByteArray(file->d_name));
00186 if (fn.isEmpty()) {
00187
00188 continue;
00189 }
00190
00191 const QString filePath = d->file + QLatin1Char('/') + fn;
00192 fi.setFile(filePath);
00193
00194 #ifndef QT_NO_REGEXP
00195 if(!((filters & QDir::AllDirs) && fi.isDir())) {
00196 bool matched = false;
00197 for (int i = 0; i < regexps.size(); ++i) {
00198 if (regexps.at(i).exactMatch(fn)) {
00199 matched = true;
00200 break;
00201 }
00202 }
00203 if (!matched)
00204 continue;
00205 }
00206 #else
00207 Q_UNUSED(filterNames);
00208 #endif
00209 if ((filters & QDir::NoDotAndDotDot) && ((fn == QLatin1String(".") || fn == QLatin1String(".."))))
00210 continue;
00211 bool isHidden = (fn.at(0) == QLatin1Char('.') && fn.length() > 1 && fn != QLatin1String("..")
00212 #if defined(Q_WS_MAC)
00213 || d->isMacHidden(filePath)
00214 #endif
00215 );
00216
00217 if (!includeHidden && isHidden)
00218 continue;
00219
00220 bool alwaysShow = (filters & QDir::TypeMask) == 0
00221 && ((isHidden && includeHidden)
00222 || (includeSystem && ((fi.exists() && !fi.isFile() && !fi.isDir() && !fi.isSymLink())
00223 || (!fi.exists() && fi.isSymLink()))));
00224
00225
00226 if ((filters & QDir::AllDirs) == 0 && skipDirs && fi.isDir()) {
00227 if (!alwaysShow)
00228 continue;
00229 }
00230 if ((skipFiles && (fi.isFile() || !fi.exists()))
00231 || (skipSymlinks && fi.isSymLink())) {
00232 if (!alwaysShow)
00233 continue;
00234 }
00235 if (filterPermissions
00236 && !((doReadable && fi.isReadable())
00237 || (doWritable && fi.isWritable())
00238 || (doExecutable && fi.isExecutable()))) {
00239 continue;
00240 }
00241 if (!includeSystem && ((fi.exists() && !fi.isFile() && !fi.isDir() && !fi.isSymLink())
00242 || (!fi.exists() && fi.isSymLink()))) {
00243 continue;
00244 }
00245
00246 ret.append(fn);
00247 }
00248 if (closedir(dir) != 0) {
00249 qWarning("QDir::readDirEntries: Cannot close directory: %s", d->file.toLocal8Bit().data());
00250 }
00251 return ret;
00252 }
00253
00254 bool QFSFileEngine::caseSensitive() const
00255 {
00256 return true;
00257 }
00258
00259 bool QFSFileEngine::setCurrentPath(const QString &path)
00260 {
00261 int r;
00262 r = ::chdir(QFile::encodeName(path));
00263 return r >= 0;
00264 }
00265
00266 QString QFSFileEngine::currentPath(const QString &)
00267 {
00268 QString result;
00269 QT_STATBUF st;
00270 if(QT_STAT(".", &st) == 0) {
00271 char currentName[PATH_MAX+1];
00272 if(::getcwd(currentName, PATH_MAX))
00273 result = QFile::decodeName(QByteArray(currentName));
00274 #if defined(QT_DEBUG)
00275 if(result.isNull())
00276 qWarning("QDir::currentPath: getcwd() failed");
00277 #endif
00278 } else {
00279 #if defined(QT_DEBUG)
00280 qWarning("QDir::currentPath: stat(\".\") failed");
00281 #endif
00282 }
00283 return result;
00284 }
00285
00286 QString QFSFileEngine::homePath()
00287 {
00288 QString home = QFile::decodeName(qgetenv("HOME"));
00289 if(home.isNull())
00290 home = rootPath();
00291 return home;
00292 }
00293
00294 QString QFSFileEngine::rootPath()
00295 {
00296 return QString::fromLatin1("/");
00297 }
00298
00299 QString QFSFileEngine::tempPath()
00300 {
00301 QString temp = QFile::decodeName(qgetenv("TMPDIR"));
00302 if(temp.isEmpty())
00303 temp = QString::fromLatin1("/tmp/");
00304 return temp;
00305 }
00306
00307 QFileInfoList QFSFileEngine::drives()
00308 {
00309 QFileInfoList ret;
00310 ret.append(rootPath());
00311 return ret;
00312 }
00313
00314 bool QFSFileEnginePrivate::doStat() const
00315 {
00316 if (tried_stat == 0) {
00317 QFSFileEnginePrivate *that = const_cast<QFSFileEnginePrivate*>(this);
00318 if (fd != -1) {
00319 that->could_stat = (QT_FSTAT(fd, &st) == 0);
00320 } else {
00321 that->could_stat = (QT_STAT(QFile::encodeName(file), &st) == 0);
00322 }
00323 that->tried_stat = 1;
00324 }
00325 return could_stat;
00326 }
00327
00328 bool QFSFileEnginePrivate::isSymlink() const
00329 {
00330 if (need_lstat) {
00331 QFSFileEnginePrivate *that = const_cast<QFSFileEnginePrivate *>(this);
00332 that->need_lstat = false;
00333 QT_STATBUF st;
00334 that->is_link = (QT_LSTAT(QFile::encodeName(file), &st) == 0) ? S_ISLNK(st.st_mode) : false;
00335 }
00336 return is_link;
00337 }
00338
00339 #if defined (Q_WS_MAC)
00340 bool QFSFileEnginePrivate::isMacHidden(const QString &path) const
00341 {
00342 OSErr err = noErr;
00343 FSRef fsRef;
00344 err = FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(path)).data(), &fsRef, 0);
00345 if (err != noErr)
00346 return false;
00347
00348 FSCatalogInfo catInfo;
00349 err = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catInfo, NULL, NULL, NULL);
00350 if (err != noErr)
00351 return false;
00352
00353 FileInfo * const fileInfo = reinterpret_cast<FileInfo*>(&catInfo.finderInfo);
00354 bool result = (fileInfo->finderFlags & kIsInvisible);
00355 return result;
00356 }
00357 #endif
00358
00362 QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(FileFlags type) const
00363 {
00364 Q_D(const QFSFileEngine);
00365
00366 if (type & QAbstractFileEngine::FileFlag(0x1000000)) {
00367 d->tried_stat = 0;
00368 d->need_lstat = 1;
00369 }
00370
00371 QAbstractFileEngine::FileFlags ret = 0;
00372 bool exists = d->doStat();
00373 if (!exists && !d->isSymlink())
00374 return ret;
00375
00376 if (exists && (type & PermsMask)) {
00377 if(d->st.st_mode & S_IRUSR)
00378 ret |= ReadOwnerPerm;
00379 if(d->st.st_mode & S_IWUSR)
00380 ret |= WriteOwnerPerm;
00381 if(d->st.st_mode & S_IXUSR)
00382 ret |= ExeOwnerPerm;
00383 if(d->st.st_mode & S_IRUSR)
00384 ret |= ReadUserPerm;
00385 if(d->st.st_mode & S_IWUSR)
00386 ret |= WriteUserPerm;
00387 if(d->st.st_mode & S_IXUSR)
00388 ret |= ExeUserPerm;
00389 if(d->st.st_mode & S_IRGRP)
00390 ret |= ReadGroupPerm;
00391 if(d->st.st_mode & S_IWGRP)
00392 ret |= WriteGroupPerm;
00393 if(d->st.st_mode & S_IXGRP)
00394 ret |= ExeGroupPerm;
00395 if(d->st.st_mode & S_IROTH)
00396 ret |= ReadOtherPerm;
00397 if(d->st.st_mode & S_IWOTH)
00398 ret |= WriteOtherPerm;
00399 if(d->st.st_mode & S_IXOTH)
00400 ret |= ExeOtherPerm;
00401 }
00402 if(type & TypesMask) {
00403 #if !defined(QWS) && defined(Q_OS_MAC)
00404 bool foundAlias = false;
00405 {
00406 FSRef fref;
00407 if(FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->file)).data(),
00408 &fref, NULL) == noErr) {
00409 Boolean isAlias, isFolder;
00410 if(FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr && isAlias) {
00411 foundAlias = true;
00412 ret |= LinkType;
00413 }
00414 }
00415 }
00416 if(!foundAlias)
00417 #endif
00418 {
00419 if ((type & LinkType) && d->isSymlink())
00420 ret |= LinkType;
00421 if (exists && (d->st.st_mode & S_IFMT) == S_IFREG)
00422 ret |= FileType;
00423 else if (exists && (d->st.st_mode & S_IFMT) == S_IFDIR)
00424 ret |= DirectoryType;
00425 }
00426 }
00427 if(type & FlagsMask) {
00428 ret |= LocalDiskFlag;
00429 if (exists)
00430 ret |= ExistsFlag;
00431 if(fileName(BaseName)[0] == QLatin1Char('.')
00432 #if defined(Q_WS_MAC)
00433 || d->isMacHidden(d->file)
00434 #endif
00435 )
00436 ret |= HiddenFlag;
00437 if(d->file == QLatin1String("/"))
00438 ret |= RootFlag;
00439 }
00440 return ret;
00441 }
00442
00443 QString QFSFileEngine::fileName(FileName file) const
00444 {
00445 Q_D(const QFSFileEngine);
00446 if(file == BaseName) {
00447 int slash = d->file.lastIndexOf(QLatin1Char('/'));
00448 if(slash != -1)
00449 return d->file.mid(slash + 1);
00450 } else if(file == PathName) {
00451 int slash = d->file.lastIndexOf(QLatin1Char('/'));
00452 if(slash == -1)
00453 return QLatin1String(".");
00454 else if(!slash)
00455 return QLatin1String("/");
00456 return d->file.left(slash);
00457 } else if(file == AbsoluteName || file == AbsolutePathName) {
00458 QString ret;
00459 if(d->file.isEmpty() || !d->file.startsWith(QLatin1Char('/')))
00460 ret = QDir::currentPath();
00461 if(!d->file.isEmpty() && d->file != QLatin1String(".")) {
00462 if(!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
00463 ret += QLatin1Char('/');
00464 ret += d->file;
00465 }
00466 if (ret == QLatin1String("/"))
00467 return ret;
00468 bool isDir = ret.endsWith(QLatin1Char('/'));
00469 ret = QDir::cleanPath(ret);
00470 if (isDir)
00471 ret += QLatin1String("/");
00472 if(file == AbsolutePathName) {
00473 int slash = ret.lastIndexOf(QLatin1Char('/'));
00474 if(slash == -1)
00475 return QDir::currentPath();
00476 else if(!slash)
00477 return QLatin1String("/");
00478 return ret.left(slash);
00479 }
00480 return ret;
00481 } else if(file == CanonicalName || file == CanonicalPathName) {
00482 char cur[PATH_MAX+1];
00483 if(::getcwd(cur, PATH_MAX)) {
00484 QString ret;
00485 char real[PATH_MAX+1];
00486
00487
00488 if(::realpath(QFile::encodeName(d->file).data(), real))
00489 ret = QFile::decodeName(QByteArray(real));
00490 ::chdir(cur);
00491
00492 QT_STATBUF st;
00493 if(QT_STAT(QFile::encodeName(ret), &st) != 0)
00494 ret = QString();
00495 if(!ret.isEmpty() && file == CanonicalPathName) {
00496 int slash = ret.lastIndexOf(QLatin1Char('/'));
00497 if(slash == -1)
00498 return QDir::currentPath();
00499 else if(!slash)
00500 return QLatin1String("/");
00501 return ret.left(slash);
00502 }
00503 return ret;
00504 }
00505 if(file == CanonicalPathName)
00506 return fileName(AbsolutePathName);
00507 return fileName(AbsoluteName);
00508 } else if(file == LinkName) {
00509 if (d->isSymlink()) {
00510 char s[PATH_MAX+1];
00511 int len = readlink(QFile::encodeName(d->file), s, PATH_MAX);
00512 if(len > 0) {
00513 QString ret;
00514 if (S_ISDIR(d->st.st_mode) && s[0] != '/') {
00515 QDir parent(d->file);
00516 parent.cdUp();
00517 ret = parent.path();
00518 if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
00519 ret += QLatin1Char('/');
00520 }
00521 s[len] = '\0';
00522 ret += QFile::decodeName(QByteArray(s));
00523
00524 if (!ret.startsWith(QLatin1Char('/'))) {
00525 if (d->file.startsWith(QLatin1Char('/'))) {
00526 ret.prepend(d->file.left(d->file.lastIndexOf(QLatin1Char('/')))
00527 + QLatin1Char('/'));
00528 } else {
00529 ret.prepend(QDir::currentPath() + QLatin1Char('/'));
00530 }
00531 }
00532 ret = QDir::cleanPath(ret);
00533 if (ret.size() > 1 && ret.endsWith(QLatin1Char('/')))
00534 ret.chop(1);
00535 return ret;
00536 }
00537 }
00538 #if !defined(QWS) && defined(Q_OS_MAC)
00539 {
00540 FSRef fref;
00541 if(FSPathMakeRef((const UInt8 *)QFile::encodeName(QDir::cleanPath(d->file)).data(), &fref, 0) == noErr) {
00542 Boolean isAlias, isFolder;
00543 if(FSResolveAliasFile(&fref, true, &isFolder, &isAlias) == noErr && isAlias) {
00544 AliasHandle alias;
00545 if(FSNewAlias(0, &fref, &alias) == noErr && alias) {
00546 CFStringRef cfstr;
00547 if(FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr)
00548 return QCFString::toQString(cfstr);
00549 }
00550 }
00551 }
00552 }
00553 #endif
00554 return QString();
00555 }
00556 return d->file;
00557 }
00558
00559 bool QFSFileEngine::isRelativePath() const
00560 {
00561 Q_D(const QFSFileEngine);
00562 int len = d->file.length();
00563 if(len == 0)
00564 return true;
00565 return d->file[0] != QLatin1Char('/');
00566 }
00567
00568 uint QFSFileEngine::ownerId(FileOwner own) const
00569 {
00570 Q_D(const QFSFileEngine);
00571 static const uint nobodyID = (uint) -2;
00572 if(d->doStat()) {
00573 if(own == OwnerUser)
00574 return d->st.st_uid;
00575 else
00576 return d->st.st_gid;
00577 }
00578 return nobodyID;
00579 }
00580
00581 QString QFSFileEngine::owner(FileOwner own) const
00582 {
00583 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
00584 QVarLengthArray<char, 1024> buf(sysconf(_SC_GETPW_R_SIZE_MAX));
00585 #endif
00586
00587 if(own == OwnerUser) {
00588 struct passwd *pw = 0;
00589 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
00590 struct passwd entry;
00591 getpwuid_r(ownerId(own), &entry, buf.data(), buf.size(), &pw);
00592 #else
00593 pw = getpwuid(ownerId(own));
00594 #endif
00595 if(pw)
00596 return QFile::decodeName(QByteArray(pw->pw_name));
00597 } else if(own == OwnerGroup) {
00598 struct group *gr = 0;
00599 #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
00600 buf.resize(sysconf(_SC_GETGR_R_SIZE_MAX));
00601 struct group entry;
00602 getgrgid_r(ownerId(own), &entry, buf.data(), buf.size(), &gr);
00603 #else
00604 gr = getgrgid(ownerId(own));
00605 #endif
00606 if(gr)
00607 return QFile::decodeName(QByteArray(gr->gr_name));
00608 }
00609 return QString();
00610 }
00611
00612 bool QFSFileEngine::setPermissions(uint perms)
00613 {
00614 Q_D(QFSFileEngine);
00615 mode_t mode = 0;
00616 if(perms & ReadOwnerPerm)
00617 mode |= S_IRUSR;
00618 if(perms & WriteOwnerPerm)
00619 mode |= S_IWUSR;
00620 if(perms & ExeOwnerPerm)
00621 mode |= S_IXUSR;
00622 if(perms & ReadUserPerm)
00623 mode |= S_IRUSR;
00624 if(perms & WriteUserPerm)
00625 mode |= S_IWUSR;
00626 if(perms & ExeUserPerm)
00627 mode |= S_IXUSR;
00628 if(perms & ReadGroupPerm)
00629 mode |= S_IRGRP;
00630 if(perms & WriteGroupPerm)
00631 mode |= S_IWGRP;
00632 if(perms & ExeGroupPerm)
00633 mode |= S_IXGRP;
00634 if(perms & ReadOtherPerm)
00635 mode |= S_IROTH;
00636 if(perms & WriteOtherPerm)
00637 mode |= S_IWOTH;
00638 if(perms & ExeOtherPerm)
00639 mode |= S_IXOTH;
00640 if(d->fd != -1)
00641 return !fchmod(d->fd, mode);
00642 const QByteArray file = QFile::encodeName(d->file);
00643 return !::chmod(file.data(), mode);
00644 }
00645
00646 bool QFSFileEngine::setSize(qint64 size)
00647 {
00648 Q_D(QFSFileEngine);
00649 if(d->fd != -1)
00650 return !QT_FTRUNCATE(d->fd, size);
00651 const QByteArray file = QFile::encodeName(d->file);
00652 return !QT_TRUNCATE(file.data(), size);
00653 }
00654
00655 QDateTime QFSFileEngine::fileTime(FileTime time) const
00656 {
00657 Q_D(const QFSFileEngine);
00658 QDateTime ret;
00659 if(d->doStat()) {
00660 if(time == CreationTime)
00661 ret.setTime_t(d->st.st_ctime ? d->st.st_ctime : d->st.st_mtime);
00662 else if(time == ModificationTime)
00663 ret.setTime_t(d->st.st_mtime);
00664 else if(time == AccessTime)
00665 ret.setTime_t(d->st.st_atime);
00666 }
00667 return ret;
00668 }