KIOSlave
file_unix.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright (C) 2000-2002 Stephan Kulow <coolo@kde.org> 00003 Copyright (C) 2000-2002 David Faure <faure@kde.org> 00004 Copyright (C) 2000-2002 Waldo Bastian <bastian@kde.org> 00005 Copyright (C) 2006 Allan Sandfeld Jensen <sandfeld@kde.org> 00006 Copyright (C) 2007 Thiago Macieira <thiago@kde.org> 00007 Copyright (C) 2007 Christian Ehrlicher <ch.ehrlicher@gmx.de> 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Library General Public 00011 License (LGPL) as published by the Free Software Foundation; 00012 either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Library General Public License for more details. 00019 00020 You should have received a copy of the GNU Library General Public License 00021 along with this library; see the file COPYING.LIB. If not, write to 00022 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00023 Boston, MA 02110-1301, USA. 00024 */ 00025 00026 #define QT_NO_CAST_FROM_ASCII 00027 00028 #include "file.h" 00029 00030 #include <config.h> 00031 #include <config-kioslave-file.h> 00032 00033 #include <QtCore/QFile> 00034 00035 #include <kde_file.h> 00036 #include <kdebug.h> 00037 #include <kconfiggroup.h> 00038 #include <kmountpoint.h> 00039 00040 #include <dirent.h> 00041 #include <errno.h> 00042 #include <fcntl.h> 00043 #include <grp.h> 00044 #include <utime.h> 00045 #include <pwd.h> 00046 #include <stdlib.h> 00047 00048 #if defined(HAVE_LIMITS_H) 00049 #include <limits.h> // PATH_MAX 00050 #endif 00051 00052 //sendfile has different semantics in different platforms 00053 #if defined HAVE_SENDFILE && defined Q_OS_LINUX 00054 #define USE_SENDFILE 1 00055 #endif 00056 00057 #ifdef USE_SENDFILE 00058 #include <sys/sendfile.h> 00059 #endif 00060 00061 namespace KDEPrivate 00062 { 00063 00064 struct CharArrayDeleter 00065 { 00066 CharArrayDeleter(char *b) : buf(b) {} 00067 ~CharArrayDeleter() { free(buf); } 00068 char *buf; 00069 }; 00070 00071 } 00072 00073 using namespace KIO; 00074 00075 #define MAX_IPC_SIZE (1024*32) 00076 00077 static bool 00078 same_inode(const KDE_struct_stat &src, const KDE_struct_stat &dest) 00079 { 00080 if (src.st_ino == dest.st_ino && 00081 src.st_dev == dest.st_dev) 00082 return true; 00083 00084 return false; 00085 } 00086 00087 extern int write_all(int fd, const char *buf, size_t len); 00088 00089 void FileProtocol::copy( const KUrl &srcUrl, const KUrl &destUrl, 00090 int _mode, JobFlags _flags ) 00091 { 00092 kDebug(7101) << "copy(): " << srcUrl << " -> " << destUrl << ", mode=" << _mode; 00093 00094 const QString src = srcUrl.toLocalFile(); 00095 const QString dest = destUrl.toLocalFile(); 00096 QByteArray _src( QFile::encodeName(src)); 00097 QByteArray _dest( QFile::encodeName(dest)); 00098 KDE_struct_stat buff_src; 00099 #ifdef HAVE_POSIX_ACL 00100 acl_t acl; 00101 #endif 00102 00103 if ( KDE_stat( _src.data(), &buff_src ) == -1 ) { 00104 if ( errno == EACCES ) 00105 error(KIO::ERR_ACCESS_DENIED, src); 00106 else 00107 error(KIO::ERR_DOES_NOT_EXIST, src); 00108 return; 00109 } 00110 00111 if ( S_ISDIR( buff_src.st_mode ) ) { 00112 error(KIO::ERR_IS_DIRECTORY, src); 00113 return; 00114 } 00115 if ( S_ISFIFO( buff_src.st_mode ) || S_ISSOCK ( buff_src.st_mode ) ) { 00116 error(KIO::ERR_CANNOT_OPEN_FOR_READING, src); 00117 return; 00118 } 00119 00120 KDE_struct_stat buff_dest; 00121 bool dest_exists = ( KDE_lstat( _dest.data(), &buff_dest ) != -1 ); 00122 if ( dest_exists ) 00123 { 00124 if (S_ISDIR(buff_dest.st_mode)) 00125 { 00126 error(KIO::ERR_DIR_ALREADY_EXIST, dest); 00127 return; 00128 } 00129 00130 if ( same_inode( buff_dest, buff_src) ) 00131 { 00132 error(KIO::ERR_IDENTICAL_FILES, dest); 00133 return; 00134 } 00135 00136 if (!(_flags & KIO::Overwrite)) 00137 { 00138 error(KIO::ERR_FILE_ALREADY_EXIST, dest); 00139 return; 00140 } 00141 00142 // If the destination is a symlink and overwrite is TRUE, 00143 // remove the symlink first to prevent the scenario where 00144 // the symlink actually points to current source! 00145 if ((_flags & KIO::Overwrite) && S_ISLNK(buff_dest.st_mode)) 00146 { 00147 //kDebug(7101) << "copy(): LINK DESTINATION"; 00148 remove( _dest.data() ); 00149 } 00150 } 00151 00152 int src_fd = KDE_open( _src.data(), O_RDONLY); 00153 if ( src_fd < 0 ) { 00154 error(KIO::ERR_CANNOT_OPEN_FOR_READING, src); 00155 return; 00156 } 00157 00158 #if HAVE_FADVISE 00159 posix_fadvise(src_fd,0,0,POSIX_FADV_SEQUENTIAL); 00160 #endif 00161 // WABA: Make sure that we keep writing permissions ourselves, 00162 // otherwise we can be in for a surprise on NFS. 00163 mode_t initialMode; 00164 if (_mode != -1) 00165 initialMode = _mode | S_IWUSR; 00166 else 00167 initialMode = 0666; 00168 00169 int dest_fd = KDE_open(_dest.data(), O_CREAT | O_TRUNC | O_WRONLY, initialMode); 00170 if ( dest_fd < 0 ) { 00171 kDebug(7101) << "###### COULD NOT WRITE " << dest; 00172 if ( errno == EACCES ) { 00173 error(KIO::ERR_WRITE_ACCESS_DENIED, dest); 00174 } else { 00175 error(KIO::ERR_CANNOT_OPEN_FOR_WRITING, dest); 00176 } 00177 ::close(src_fd); 00178 return; 00179 } 00180 00181 #if HAVE_FADVISE 00182 posix_fadvise(dest_fd,0,0,POSIX_FADV_SEQUENTIAL); 00183 #endif 00184 00185 #ifdef HAVE_POSIX_ACL 00186 acl = acl_get_fd(src_fd); 00187 if ( acl && !isExtendedACL( acl ) ) { 00188 kDebug(7101) << _dest.data() << " doesn't have extended ACL"; 00189 acl_free( acl ); 00190 acl = NULL; 00191 } 00192 #endif 00193 totalSize( buff_src.st_size ); 00194 00195 KIO::filesize_t processed_size = 0; 00196 char buffer[ MAX_IPC_SIZE ]; 00197 int n; 00198 #ifdef USE_SENDFILE 00199 bool use_sendfile=buff_src.st_size < 0x7FFFFFFF; 00200 #endif 00201 while( 1 ) 00202 { 00203 #ifdef USE_SENDFILE 00204 if (use_sendfile) { 00205 off_t sf = processed_size; 00206 n = KDE_sendfile( dest_fd, src_fd, &sf, MAX_IPC_SIZE ); 00207 processed_size = sf; 00208 if ( n == -1 && ( errno == EINVAL || errno == ENOSYS ) ) { //not all filesystems support sendfile() 00209 kDebug(7101) << "sendfile() not supported, falling back "; 00210 use_sendfile = false; 00211 } 00212 } 00213 if (!use_sendfile) 00214 #endif 00215 n = ::read( src_fd, buffer, MAX_IPC_SIZE ); 00216 00217 if (n == -1) 00218 { 00219 if (errno == EINTR) 00220 continue; 00221 #ifdef USE_SENDFILE 00222 if ( use_sendfile ) { 00223 kDebug(7101) << "sendfile() error:" << strerror(errno); 00224 if ( errno == ENOSPC ) // disk full 00225 { 00226 error(KIO::ERR_DISK_FULL, dest); 00227 remove( _dest.data() ); 00228 } 00229 else { 00230 error(KIO::ERR_SLAVE_DEFINED, 00231 i18n("Cannot copy file from %1 to %2. (Errno: %3)", 00232 src, dest, errno)); 00233 } 00234 } else 00235 #endif 00236 error(KIO::ERR_COULD_NOT_READ, src); 00237 ::close(src_fd); 00238 ::close(dest_fd); 00239 #ifdef HAVE_POSIX_ACL 00240 if (acl) acl_free(acl); 00241 #endif 00242 return; 00243 } 00244 if (n == 0) 00245 break; // Finished 00246 #ifdef USE_SENDFILE 00247 if ( !use_sendfile ) { 00248 #endif 00249 if (write_all( dest_fd, buffer, n)) 00250 { 00251 ::close(src_fd); 00252 ::close(dest_fd); 00253 00254 if ( errno == ENOSPC ) // disk full 00255 { 00256 error(KIO::ERR_DISK_FULL, dest); 00257 remove( _dest.data() ); 00258 } 00259 else 00260 { 00261 kWarning(7101) << "Couldn't write[2]. Error:" << strerror(errno); 00262 error(KIO::ERR_COULD_NOT_WRITE, dest); 00263 } 00264 #ifdef HAVE_POSIX_ACL 00265 if (acl) acl_free(acl); 00266 #endif 00267 return; 00268 } 00269 processed_size += n; 00270 #ifdef USE_SENDFILE 00271 } 00272 #endif 00273 processedSize( processed_size ); 00274 } 00275 00276 ::close( src_fd ); 00277 00278 if (::close( dest_fd)) 00279 { 00280 kWarning(7101) << "Error when closing file descriptor[2]:" << strerror(errno); 00281 error(KIO::ERR_COULD_NOT_WRITE, dest); 00282 #ifdef HAVE_POSIX_ACL 00283 if (acl) acl_free(acl); 00284 #endif 00285 return; 00286 } 00287 00288 // set final permissions 00289 if ( _mode != -1 ) 00290 { 00291 if ( (::chmod(_dest.data(), _mode) != 0) 00292 #ifdef HAVE_POSIX_ACL 00293 || (acl && acl_set_file(_dest.data(), ACL_TYPE_ACCESS, acl) != 0) 00294 #endif 00295 ) 00296 { 00297 KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByPath(dest); 00298 // Eat the error if the filesystem apparently doesn't support chmod. 00299 if ( mp && mp->testFileSystemFlag( KMountPoint::SupportsChmod ) ) 00300 warning(i18n("Could not change permissions for\n%1", dest)); 00301 } 00302 } 00303 #ifdef HAVE_POSIX_ACL 00304 if (acl) acl_free(acl); 00305 #endif 00306 00307 // copy access and modification time 00308 struct utimbuf ut; 00309 ut.actime = buff_src.st_atime; 00310 ut.modtime = buff_src.st_mtime; 00311 if ( ::utime( _dest.data(), &ut ) != 0 ) 00312 { 00313 kWarning() << QString::fromLatin1("Couldn't preserve access and modification time for\n%1").arg(dest); 00314 } 00315 00316 processedSize( buff_src.st_size ); 00317 finished(); 00318 } 00319 00320 void FileProtocol::listDir( const KUrl& url) 00321 { 00322 if (!url.isLocalFile()) { 00323 KUrl redir(url); 00324 redir.setProtocol(config()->readEntry("DefaultRemoteProtocol", "smb")); 00325 redirection(redir); 00326 kDebug(7101) << "redirecting to " << redir.url(); 00327 finished(); 00328 return; 00329 } 00330 const QString path(url.toLocalFile()); 00331 const QByteArray _path(QFile::encodeName(path)); 00332 DIR* dp = opendir(_path.data()); 00333 if ( dp == 0 ) { 00334 switch (errno) { 00335 case ENOENT: 00336 error(KIO::ERR_DOES_NOT_EXIST, path); 00337 return; 00338 case ENOTDIR: 00339 error(KIO::ERR_IS_FILE, path); 00340 break; 00341 #ifdef ENOMEDIUM 00342 case ENOMEDIUM: 00343 error(ERR_SLAVE_DEFINED, 00344 i18n("No media in device for %1", path)); 00345 break; 00346 #endif 00347 default: 00348 error(KIO::ERR_CANNOT_ENTER_DIRECTORY, path); 00349 break; 00350 } 00351 return; 00352 } 00353 00354 const QString sDetails = metaData(QLatin1String("details")); 00355 const int details = sDetails.isEmpty() ? 2 : sDetails.toInt(); 00356 //kDebug(7101) << "========= LIST " << url << "details=" << details << " ========="; 00357 UDSEntry entry; 00358 00359 #ifndef HAVE_DIRENT_D_TYPE 00360 KDE_struct_stat st; 00361 #endif 00362 // Don't make this a QStringList. The locale file name we get here 00363 // should be passed intact to createUDSEntry to avoid problems with 00364 // files where QFile::encodeName(QFile::decodeName(a)) != a. 00365 QList<QByteArray> entryNames; 00366 KDE_struct_dirent *ep; 00367 if (details == 0) { 00368 // Fast path (for recursive deletion, mostly) 00369 // Simply emit the name and file type, nothing else. 00370 while ( ( ep = KDE_readdir( dp ) ) != 0 ) { 00371 entry.clear(); 00372 entry.insert(KIO::UDSEntry::UDS_NAME, QFile::decodeName(ep->d_name)); 00373 #ifdef HAVE_DIRENT_D_TYPE 00374 entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, 00375 (ep->d_type & DT_DIR) ? S_IFDIR : S_IFREG ); 00376 const bool isSymLink = (ep->d_type & DT_LNK); 00377 #else 00378 // oops, no fast way, we need to stat (e.g. on Solaris) 00379 if (KDE_lstat(ep->d_name, &st) == -1) { 00380 continue; // how can stat fail? 00381 } 00382 entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, 00383 (S_ISDIR(st.st_mode)) ? S_IFDIR : S_IFREG ); 00384 const bool isSymLink = S_ISLNK(st.st_mode); 00385 #endif 00386 if (isSymLink) { 00387 // for symlinks obey the UDSEntry contract and provide UDS_LINK_DEST 00388 // even if we don't know the link dest (and DeleteJob doesn't care...) 00389 entry.insert(KIO::UDSEntry::UDS_LINK_DEST, QLatin1String("Dummy Link Target")); 00390 } 00391 listEntry(entry, false); 00392 } 00393 closedir( dp ); 00394 listEntry( entry, true ); // ready 00395 } else { 00396 while ( ( ep = KDE_readdir( dp ) ) != 0 ) { 00397 entryNames.append( ep->d_name ); 00398 } 00399 00400 closedir( dp ); 00401 totalSize( entryNames.count() ); 00402 00403 /* set the current dir to the path to speed up 00404 in not having to pass an absolute path. 00405 We restore the path later to get out of the 00406 path - the kernel wouldn't unmount or delete 00407 directories we keep as active directory. And 00408 as the slave runs in the background, it's hard 00409 to see for the user what the problem would be */ 00410 #if !defined(PATH_MAX) && defined(__GLIBC__) 00411 char *path_buffer = ::get_current_dir_name(); 00412 const KDEPrivate::CharArrayDeleter path_buffer_deleter(path_buffer); 00413 #else 00414 char path_buffer[PATH_MAX]; 00415 path_buffer[0] = '\0'; 00416 (void) getcwd(path_buffer, PATH_MAX - 1); 00417 #endif 00418 if ( chdir( _path.data() ) ) { 00419 if (errno == EACCES) 00420 error(ERR_ACCESS_DENIED, path); 00421 else 00422 error(ERR_CANNOT_ENTER_DIRECTORY, path); 00423 finished(); 00424 } 00425 00426 QList<QByteArray>::ConstIterator it = entryNames.constBegin(); 00427 QList<QByteArray>::ConstIterator end = entryNames.constEnd(); 00428 for (; it != end; ++it) { 00429 entry.clear(); 00430 if ( createUDSEntry( QFile::decodeName(*it), 00431 *it /* we can use the filename as relative path*/, 00432 entry, details, true ) ) 00433 listEntry( entry, false); 00434 } 00435 00436 listEntry( entry, true ); // ready 00437 00438 //kDebug(7101) << "============= COMPLETED LIST ============"; 00439 00440 #if !defined(PATH_MAX) && defined(__GLIBC__) 00441 if (path_buffer) 00442 #else 00443 if (*path_buffer) 00444 #endif 00445 { 00446 chdir(path_buffer); 00447 } 00448 } 00449 finished(); 00450 } 00451 00452 void FileProtocol::rename( const KUrl &srcUrl, const KUrl &destUrl, 00453 KIO::JobFlags _flags ) 00454 { 00455 char off_t_should_be_64_bits[sizeof(off_t) >= 8 ? 1 : -1]; (void) off_t_should_be_64_bits; 00456 const QString src = srcUrl.toLocalFile(); 00457 const QString dest = destUrl.toLocalFile(); 00458 const QByteArray _src(QFile::encodeName(src)); 00459 const QByteArray _dest(QFile::encodeName(dest)); 00460 KDE_struct_stat buff_src; 00461 if ( KDE_lstat( _src.data(), &buff_src ) == -1 ) { 00462 if ( errno == EACCES ) 00463 error(KIO::ERR_ACCESS_DENIED, src); 00464 else 00465 error(KIO::ERR_DOES_NOT_EXIST, src); 00466 return; 00467 } 00468 00469 KDE_struct_stat buff_dest; 00470 // stat symlinks here (lstat, not stat), to avoid ERR_IDENTICAL_FILES when replacing symlink 00471 // with its target (#169547) 00472 bool dest_exists = ( KDE_lstat( _dest.data(), &buff_dest ) != -1 ); 00473 if ( dest_exists ) 00474 { 00475 if (S_ISDIR(buff_dest.st_mode)) 00476 { 00477 error(KIO::ERR_DIR_ALREADY_EXIST, dest); 00478 return; 00479 } 00480 00481 if ( same_inode( buff_dest, buff_src) ) 00482 { 00483 error(KIO::ERR_IDENTICAL_FILES, dest); 00484 return; 00485 } 00486 00487 if (!(_flags & KIO::Overwrite)) 00488 { 00489 error(KIO::ERR_FILE_ALREADY_EXIST, dest); 00490 return; 00491 } 00492 } 00493 00494 if ( KDE_rename( _src.data(), _dest.data())) 00495 { 00496 if (( errno == EACCES ) || (errno == EPERM)) { 00497 error(KIO::ERR_ACCESS_DENIED, dest); 00498 } 00499 else if (errno == EXDEV) { 00500 error(KIO::ERR_UNSUPPORTED_ACTION, QLatin1String("rename")); 00501 } 00502 else if (errno == EROFS) { // The file is on a read-only filesystem 00503 error(KIO::ERR_CANNOT_DELETE, src); 00504 } 00505 else { 00506 error(KIO::ERR_CANNOT_RENAME, src); 00507 } 00508 return; 00509 } 00510 00511 finished(); 00512 } 00513 00514 void FileProtocol::symlink( const QString &target, const KUrl &destUrl, KIO::JobFlags flags ) 00515 { 00516 const QString dest = destUrl.toLocalFile(); 00517 // Assume dest is local too (wouldn't be here otherwise) 00518 if ( ::symlink( QFile::encodeName(target), QFile::encodeName(dest) ) == -1 ) 00519 { 00520 // Does the destination already exist ? 00521 if ( errno == EEXIST ) 00522 { 00523 if ( (flags & KIO::Overwrite) ) 00524 { 00525 // Try to delete the destination 00526 if ( unlink( QFile::encodeName(dest) ) != 0 ) 00527 { 00528 error(KIO::ERR_CANNOT_DELETE, dest); 00529 return; 00530 } 00531 // Try again - this won't loop forever since unlink succeeded 00532 symlink( target, destUrl, flags ); 00533 } 00534 else 00535 { 00536 KDE_struct_stat buff_dest; 00537 KDE_lstat( QFile::encodeName(dest), &buff_dest ); 00538 if (S_ISDIR(buff_dest.st_mode)) 00539 error(KIO::ERR_DIR_ALREADY_EXIST, dest); 00540 else 00541 error(KIO::ERR_FILE_ALREADY_EXIST, dest); 00542 return; 00543 } 00544 } 00545 else 00546 { 00547 // Some error occurred while we tried to symlink 00548 error(KIO::ERR_CANNOT_SYMLINK, dest); 00549 return; 00550 } 00551 } 00552 finished(); 00553 } 00554 00555 void FileProtocol::del(const KUrl& url, bool isfile) 00556 { 00557 const QString path = url.toLocalFile(); 00558 const QByteArray _path( QFile::encodeName(path)); 00559 /***** 00560 * Delete files 00561 *****/ 00562 00563 if (isfile) { 00564 kDebug(7101) << "Deleting file "<< url; 00565 00566 if ( unlink( _path.data() ) == -1 ) { 00567 if ((errno == EACCES) || (errno == EPERM)) 00568 error(KIO::ERR_ACCESS_DENIED, path); 00569 else if (errno == EISDIR) 00570 error(KIO::ERR_IS_DIRECTORY, path); 00571 else 00572 error(KIO::ERR_CANNOT_DELETE, path); 00573 return; 00574 } 00575 } else { 00576 00577 /***** 00578 * Delete empty directory 00579 *****/ 00580 00581 kDebug( 7101 ) << "Deleting directory " << url.url(); 00582 if (metaData(QLatin1String("recurse")) == QLatin1String("true")) { 00583 if (!deleteRecursive(path)) 00584 return; 00585 } 00586 if ( ::rmdir( _path.data() ) == -1 ) { 00587 if ((errno == EACCES) || (errno == EPERM)) 00588 error(KIO::ERR_ACCESS_DENIED, path); 00589 else { 00590 kDebug( 7101 ) << "could not rmdir " << perror; 00591 error(KIO::ERR_COULD_NOT_RMDIR, path); 00592 return; 00593 } 00594 } 00595 } 00596 00597 finished(); 00598 } 00599 00600 void FileProtocol::chown( const KUrl& url, const QString& owner, const QString& group ) 00601 { 00602 const QString path = url.toLocalFile(); 00603 const QByteArray _path( QFile::encodeName(path) ); 00604 uid_t uid; 00605 gid_t gid; 00606 00607 // get uid from given owner 00608 { 00609 struct passwd *p = ::getpwnam(owner.toAscii()); 00610 00611 if ( ! p ) { 00612 error( KIO::ERR_SLAVE_DEFINED, 00613 i18n( "Could not get user id for given user name %1", owner ) ); 00614 return; 00615 } 00616 00617 uid = p->pw_uid; 00618 } 00619 00620 // get gid from given group 00621 { 00622 struct group *p = ::getgrnam(group.toAscii()); 00623 00624 if ( ! p ) { 00625 error( KIO::ERR_SLAVE_DEFINED, 00626 i18n( "Could not get group id for given group name %1", group ) ); 00627 return; 00628 } 00629 00630 gid = p->gr_gid; 00631 } 00632 00633 if ( ::chown(_path, uid, gid) == -1 ) { 00634 switch ( errno ) { 00635 case EPERM: 00636 case EACCES: 00637 error(KIO::ERR_ACCESS_DENIED, path); 00638 break; 00639 case ENOSPC: 00640 error(KIO::ERR_DISK_FULL, path); 00641 break; 00642 default: 00643 error(KIO::ERR_CANNOT_CHOWN, path); 00644 } 00645 } else 00646 finished(); 00647 } 00648 00649 void FileProtocol::stat( const KUrl & url ) 00650 { 00651 if (!url.isLocalFile()) { 00652 KUrl redir(url); 00653 redir.setProtocol(config()->readEntry("DefaultRemoteProtocol", "smb")); 00654 redirection(redir); 00655 kDebug(7101) << "redirecting to " << redir.url(); 00656 finished(); 00657 return; 00658 } 00659 00660 /* directories may not have a slash at the end if 00661 * we want to stat() them; it requires that we 00662 * change into it .. which may not be allowed 00663 * stat("/is/unaccessible") -> rwx------ 00664 * stat("/is/unaccessible/") -> EPERM H.Z. 00665 * This is the reason for the -1 00666 */ 00667 const QString path(url.path(KUrl::RemoveTrailingSlash)); 00668 const QByteArray _path( QFile::encodeName(path)); 00669 const QString sDetails = metaData(QLatin1String("details")); 00670 const int details = sDetails.isEmpty() ? 2 : sDetails.toInt(); 00671 00672 UDSEntry entry; 00673 if ( !createUDSEntry( url.fileName(), _path, entry, details, true /*with acls*/ ) ) 00674 { 00675 error(KIO::ERR_DOES_NOT_EXIST, path); 00676 return; 00677 } 00678 #if 0 00679 00680 MetaData::iterator it1 = mOutgoingMetaData.begin(); 00681 for ( ; it1 != mOutgoingMetaData.end(); it1++ ) { 00682 kDebug(7101) << it1.key() << " = " << it1.data(); 00683 } 00685 #endif 00686 statEntry( entry ); 00687 00688 finished(); 00689 }
KDE 4.7 API Reference