25 #define QT_NO_CAST_FROM_ASCII
28 #include <QDirIterator>
31 #include <config-kioslave-file.h>
34 #include <sys/types.h>
37 #include <sys/socket.h>
38 #ifdef HAVE_SYS_TIME_H
58 #include <QtCore/QByteRef>
59 #include <QtCore/QDate>
60 #include <QtCore/QVarLengthArray>
61 #include <QtCore/QCoreApplication>
62 #include <QtCore/QRegExp>
63 #include <QtCore/QFile>
65 #include <QtCore/QDir>
66 #include <QtCore/QFileInfo>
83 #include <sys/mnttab.h>
94 #define MAX_IPC_SIZE (1024*32)
98 static void appendACLAtoms(
const QByteArray & path,
UDSEntry& entry,
99 mode_t type,
bool withACL );
104 QCoreApplication app( argc, argv );
106 ( void ) KGlobal::locale();
108 kDebug(7101) <<
"Starting" << getpid();
112 fprintf(stderr,
"Usage: kio_file protocol domain-socket1 domain-socket2\n");
117 slave.dispatchLoop();
124 :
SlaveBase(
"file", pool, app ), openFd(-1)
132 #ifdef HAVE_POSIX_ACL
133 static QString aclToText(acl_t acl) {
135 char* txt = acl_to_text(acl, &size);
136 const QString ret = QString::fromLatin1(txt, size);
142 int FileProtocol::setACL(
const char *path, mode_t perm,
bool directoryDefault )
145 #ifdef HAVE_POSIX_ACL
147 const QString ACLString = metaData(QLatin1String(
"ACL_STRING"));
148 const QString defaultACLString = metaData(QLatin1String(
"DEFAULT_ACL_STRING"));
150 if ( !ACLString.isEmpty() ) {
152 if (ACLString == QLatin1String(
"ACL_DELETE")) {
155 acl = acl_from_mode( perm );
157 acl = acl_from_text( ACLString.toLatin1() );
158 if ( acl_valid( acl ) == 0 ) {
159 ret = acl_set_file( path, ACL_TYPE_ACCESS, acl );
160 kDebug(7101) <<
"Set ACL on:" << path <<
"to:" << aclToText(acl);
163 if ( ret != 0 )
return ret;
166 if ( directoryDefault && !defaultACLString.isEmpty() ) {
167 if ( defaultACLString == QLatin1String(
"ACL_DELETE") ) {
169 ret += acl_delete_def_file( path );
171 acl_t acl = acl_from_text( defaultACLString.toLatin1() );
172 if ( acl_valid( acl ) == 0 ) {
173 ret += acl_set_file( path, ACL_TYPE_DEFAULT, acl );
174 kDebug(7101) <<
"Set Default ACL on:" << path <<
"to:" << aclToText(acl);
182 Q_UNUSED(directoryDefault);
190 const QByteArray _path( QFile::encodeName(path) );
192 if ( KDE::chmod( path, permissions ) == -1 ||
193 ( setACL( _path.data(), permissions, false ) == -1 ) ||
195 ( setACL( _path.data(), permissions, true ) == -1 && errno != ENOTDIR ) ) {
200 error(KIO::ERR_ACCESS_DENIED, path);
204 error(KIO::ERR_UNSUPPORTED_ACTION,
i18n(
"Setting ACL for %1", path));
208 error(KIO::ERR_DISK_FULL, path);
211 error(KIO::ERR_CANNOT_CHMOD, path);
220 KDE_struct_stat statbuf;
221 if (KDE::lstat(path, &statbuf) == 0) {
222 struct utimbuf utbuf;
223 utbuf.actime = statbuf.st_atime;
224 utbuf.modtime = mtime.toTime_t();
225 if (KDE::utime(path, &utbuf) != 0) {
227 error(KIO::ERR_CANNOT_SETTIME, path);
232 error(KIO::ERR_DOES_NOT_EXIST, path);
240 kDebug(7101) << path <<
"permission=" << permissions;
243 if (metaData(QLatin1String(
"overwrite")) == QLatin1String(
"true"))
246 KDE_struct_stat buff;
247 if ( KDE::lstat( path, &buff ) == -1 ) {
248 if ( KDE::mkdir( path, 0777 ) != 0 ) {
249 if ( errno == EACCES ) {
250 error(KIO::ERR_ACCESS_DENIED, path);
252 }
else if ( errno == ENOSPC ) {
253 error(KIO::ERR_DISK_FULL, path);
256 error(KIO::ERR_COULD_NOT_MKDIR, path);
260 if ( permissions != -1 )
261 chmod( url, permissions );
268 if ( S_ISDIR( buff.st_mode ) ) {
269 kDebug(7101) <<
"ERR_DIR_ALREADY_EXIST";
270 error(KIO::ERR_DIR_ALREADY_EXIST, path);
273 error(KIO::ERR_FILE_ALREADY_EXIST, path);
288 KDE_struct_stat buff;
289 if ( KDE::stat( path, &buff ) == -1 ) {
290 if ( errno == EACCES )
291 error(KIO::ERR_ACCESS_DENIED, path);
293 error(KIO::ERR_DOES_NOT_EXIST, path);
297 if ( S_ISDIR( buff.st_mode ) ) {
298 error(KIO::ERR_IS_DIRECTORY, path);
301 if ( !S_ISREG( buff.st_mode ) ) {
302 error(KIO::ERR_CANNOT_OPEN_FOR_READING, path);
306 int fd = KDE::open( path, O_RDONLY);
308 error(KIO::ERR_CANNOT_OPEN_FOR_READING, path);
313 posix_fadvise( fd, 0, 0, POSIX_FADV_SEQUENTIAL);
321 KMimeType::Ptr mt = KMimeType::findByUrl( url, buff.st_mode,
true );
322 emit mimeType( mt->name() );
324 totalSize( buff.st_size );
326 KIO::filesize_t processed_size = 0;
328 const QString resumeOffset = metaData(QLatin1String(
"resume"));
329 if ( !resumeOffset.isEmpty() )
332 KIO::fileoffset_t offset = resumeOffset.toLongLong(&ok);
333 if (ok && (offset > 0) && (offset < buff.st_size))
335 if (KDE_lseek(fd, offset, SEEK_SET) == offset)
338 processed_size = offset;
339 kDebug(7101) <<
"Resume offset:" << KIO::number(offset);
354 error(KIO::ERR_COULD_NOT_READ, path);
361 array = QByteArray::fromRawData(buffer, n);
366 processedSize( processed_size );
371 data( QByteArray() );
375 processedSize( buff.st_size );
383 ssize_t written = write(fd, buf, len);
401 KDE_struct_stat buff;
402 if (KDE::stat(openPath, &buff) == -1) {
403 if ( errno == EACCES )
404 error(KIO::ERR_ACCESS_DENIED, openPath);
406 error(KIO::ERR_DOES_NOT_EXIST, openPath);
410 if ( S_ISDIR( buff.st_mode ) ) {
411 error(KIO::ERR_IS_DIRECTORY, openPath);
414 if ( !S_ISREG( buff.st_mode ) ) {
415 error(KIO::ERR_CANNOT_OPEN_FOR_READING, openPath);
420 if (mode & QIODevice::ReadOnly) {
421 if (mode & QIODevice::WriteOnly) {
422 flags = O_RDWR | O_CREAT;
426 }
else if (mode & QIODevice::WriteOnly) {
427 flags = O_WRONLY | O_CREAT;
430 if (mode & QIODevice::Append) {
432 }
else if (mode & QIODevice::Truncate) {
437 if ( flags & O_CREAT)
438 fd = KDE::open( openPath, flags, 0666);
440 fd = KDE::open( openPath, flags);
442 error(KIO::ERR_CANNOT_OPEN_FOR_READING, openPath);
449 if (mode & QIODevice::ReadOnly){
450 KMimeType::Ptr mt = KMimeType::findByUrl( url, buff.st_mode,
true );
451 emit mimeType( mt->name() );
454 totalSize( buff.st_size );
463 kDebug(7101) <<
"File::open -- read";
464 Q_ASSERT(openFd != -1);
466 QVarLengthArray<char> buffer(bytes);
470 res =
::read(openFd, buffer.data(), bytes);
471 }
while (res == -1 && errno == EINTR);
474 QByteArray array = QByteArray::fromRawData(buffer.data(), res);
481 error(KIO::ERR_COULD_NOT_READ, openPath);
486 if (bytes <= 0)
break;
492 kDebug(7101) <<
"File::open -- write";
493 Q_ASSERT(openFd != -1);
495 if (
write_all(openFd, data.constData(), data.size())) {
496 if (errno == ENOSPC) {
497 error(KIO::ERR_DISK_FULL, openPath);
500 kWarning(7101) <<
"Couldn't write. Error:" << strerror(errno);
501 error(KIO::ERR_COULD_NOT_WRITE, openPath);
505 written(data.size());
511 kDebug(7101) <<
"File::open -- seek";
512 Q_ASSERT(openFd != -1);
514 int res = KDE_lseek(openFd, offset, SEEK_SET);
518 error(KIO::ERR_COULD_NOT_SEEK, openPath);
525 kDebug(7101) <<
"File::open -- close ";
526 Q_ASSERT(openFd != -1);
539 kDebug(7101) << dest_orig <<
"mode=" << _mode;
541 QString dest_part(dest_orig + QLatin1String(
".part"));
543 KDE_struct_stat buff_orig;
544 const bool bOrigExists = (KDE::lstat(dest_orig, &buff_orig) != -1);
545 bool bPartExists =
false;
546 const bool bMarkPartial =
config()->readEntry(
"MarkPartial",
true);
550 KDE_struct_stat buff_part;
551 bPartExists = (KDE::stat( dest_part, &buff_part ) != -1);
553 if (bPartExists && !(_flags & KIO::Resume) && !(_flags & KIO::Overwrite) && buff_part.st_size > 0 && S_ISREG(buff_part.st_mode))
555 kDebug(7101) <<
"calling canResume with" << KIO::number(buff_part.st_size);
560 _flags |= canResume( buff_part.st_size ) ? KIO::Resume : KIO::DefaultFlags;
562 kDebug(7101) <<
"got answer" << (_flags & KIO::Resume);
566 if ( bOrigExists && !(_flags & KIO::Overwrite) && !(_flags & KIO::Resume))
568 if (S_ISDIR(buff_orig.st_mode))
569 error( KIO::ERR_DIR_ALREADY_EXIST, dest_orig );
571 error( KIO::ERR_FILE_ALREADY_EXIST, dest_orig );
586 result = readData( buffer );
594 kDebug(7101) <<
"Appending .part extension to" << dest_orig;
596 if ( bPartExists && !(_flags & KIO::Resume) )
598 kDebug(7101) <<
"Deleting partial file" << dest_part;
599 QFile::remove( dest_part );
606 if ( bOrigExists && !(_flags & KIO::Resume) )
608 kDebug(7101) <<
"Deleting destination file" << dest_orig;
609 QFile::remove( dest_orig );
614 if ( (_flags & KIO::Resume) )
616 fd = KDE::open( dest, O_RDWR );
618 KDE_lseek(fd, 0, SEEK_END);
627 initialMode = _mode | S_IWUSR | S_IRUSR;
631 fd = KDE::open(dest, O_CREAT | O_TRUNC | O_WRONLY, initialMode);
636 kDebug(7101) <<
"####################### COULD NOT WRITE" << dest <<
"_mode=" << _mode;
637 kDebug(7101) <<
"errno==" << errno <<
"(" << strerror(errno) <<
")";
638 if ( errno == EACCES )
639 error(KIO::ERR_WRITE_ACCESS_DENIED, dest);
641 error(KIO::ERR_CANNOT_OPEN_FOR_WRITING, dest);
646 if (
write_all( fd, buffer.data(), buffer.size()))
648 if ( errno == ENOSPC )
650 error(KIO::ERR_DISK_FULL, dest_orig);
655 kWarning(7101) <<
"Couldn't write. Error:" << strerror(errno);
656 error(KIO::ERR_COULD_NOT_WRITE, dest_orig);
662 while ( result > 0 );
667 kDebug(7101) <<
"Error during 'put'. Aborting.";
673 KDE_struct_stat buff;
674 if (bMarkPartial && KDE::stat( dest, &buff ) == 0)
677 if (buff.st_size < size)
678 remove(_dest.data());
693 kWarning(7101) <<
"Error when closing file descriptor:" << strerror(errno);
694 error(KIO::ERR_COULD_NOT_WRITE, dest_orig);
704 if( (_flags & KIO::Overwrite) && S_ISLNK( buff_orig.st_mode ) )
705 QFile::remove( dest_orig );
706 if ( KDE::rename( dest, dest_orig ) )
708 kWarning(7101) <<
" Couldn't rename " << _dest <<
" to " << dest_orig;
709 error(KIO::ERR_CANNOT_RENAME_PARTIAL, dest_orig);
712 org::kde::KDirNotify::emitFileRenamed(dest, dest_orig);
716 if ( _mode != -1 && !(_flags & KIO::Resume) )
718 if (KDE::chmod(dest_orig, _mode) != 0)
723 warning(
i18n(
"Could not change permissions for\n%1" , dest_orig ) );
728 const QString mtimeStr = metaData(QLatin1String(
"modified"));
729 if ( !mtimeStr.isEmpty() ) {
730 QDateTime dt = QDateTime::fromString( mtimeStr, Qt::ISODate );
731 if ( dt.isValid() ) {
732 KDE_struct_stat dest_statbuf;
733 if (KDE::stat( dest_orig, &dest_statbuf ) == 0) {
734 struct timeval utbuf[2];
736 utbuf[0].tv_sec = dest_statbuf.st_atime;
737 utbuf[0].tv_usec = 0;
739 utbuf[1].tv_sec = dt.toTime_t();
740 utbuf[1].tv_usec = dt.time().msec() * 1000;
741 utimes( QFile::encodeName(dest_orig), utbuf );
751 QString FileProtocol::getUserName( uid_t uid )
const
753 if ( !mUsercache.contains( uid ) ) {
754 struct passwd *user = getpwuid( uid );
756 mUsercache.insert( uid, QString::fromLatin1(user->pw_name) );
759 return QString::number( uid );
761 return mUsercache[uid];
764 QString FileProtocol::getGroupName( gid_t gid )
const
766 if ( !mGroupcache.contains( gid ) ) {
767 struct group *grp = getgrgid( gid );
769 mGroupcache.insert( gid, QString::fromLatin1(grp->gr_name) );
772 return QString::number( gid );
774 return mGroupcache[gid];
777 bool FileProtocol::createUDSEntry(
const QString & filename,
const QByteArray & path,
UDSEntry & entry,
778 short int details,
bool withACL )
780 #ifndef HAVE_POSIX_ACL
783 assert(entry.
count() == 0);
790 KDE_struct_stat buff;
792 if ( KDE_lstat( path.data(), &buff ) == 0 ) {
799 if (S_ISLNK(buff.st_mode)) {
801 char buffer2[ 1000 ];
802 int n = readlink( path.data(), buffer2, 999 );
810 if ( details > 1 && KDE_stat( path.data(), &buff ) == -1 ) {
813 access = S_IRWXU | S_IRWXG | S_IRWXO;
827 type = buff.st_mode & S_IFMT;
828 access = buff.st_mode & 07777;
835 #ifdef HAVE_POSIX_ACL
840 appendACLAtoms( path, entry, type, withACL );
862 QDataStream stream(data);
871 stream >> iRo >> fstype >> dev >> point;
873 bool ro = ( iRo != 0 );
875 kDebug(7101) <<
"MOUNTING fstype=" << fstype <<
" dev=" << dev <<
" point=" << point <<
" ro=" << ro;
880 mount( ro, fstype.toLatin1(), dev, point );
903 kDebug(7101) <<
"fstype=" << _fstype;
911 QByteArray devname = QFile::encodeName( _dev );
913 if( volmgt_running() ) {
915 if( volmgt_check( devname.data() ) == 0 ) {
916 kDebug(7101) <<
"VOLMGT: no media in "
918 err =
i18n(
"No Media inserted or Media not recognized.");
919 error( KIO::ERR_COULD_NOT_MOUNT, err );
922 kDebug(7101) <<
"VOLMGT: " << devname.data()
928 err =
i18n(
"\"vold\" is not running.");
929 kDebug(7101) <<
"VOLMGT: " << err;
930 error( KIO::ERR_COULD_NOT_MOUNT, err );
937 tmpFile.setAutoRemove(
false);
939 QByteArray tmpFileName = QFile::encodeName(tmpFile.fileName());
941 if (_dev.startsWith(QLatin1String(
"LABEL="))) {
942 QString labelName = _dev.mid( 6 );
944 dev += QFile::encodeName( KShell::quoteArg( labelName ) );
945 }
else if (_dev.startsWith(QLatin1String(
"UUID="))) {
946 QString uuidName = _dev.mid( 5 );
948 dev += QFile::encodeName( KShell::quoteArg( uuidName ) );
951 dev = QFile::encodeName( KShell::quoteArg(_dev) );
953 QByteArray point = QFile::encodeName( KShell::quoteArg(_point) );
954 bool fstype_empty = !_fstype || !*_fstype;
955 QByteArray fstype = KShell::quoteArg(QString::fromLatin1(_fstype)).toLatin1();
956 QByteArray readonly = _ro ?
"-r" :
"";
957 QString epath = QString::fromLocal8Bit(qgetenv(
"PATH"));
958 QString path = QLatin1String(
"/sbin:/bin");
960 path += QLatin1String(
":") + epath;
961 QByteArray mountProg = KGlobal::dirs()->findExe(QLatin1String(
"mount"), path).toLocal8Bit();
962 if (mountProg.isEmpty()){
963 error( KIO::ERR_COULD_NOT_MOUNT,
i18n(
"Could not find program \"mount\""));
968 for (
int step = 0 ; step <= 1 ; step++ )
970 QByteArray buffer = mountProg +
' ';
972 if ( !dev.isEmpty() && _point.isEmpty() && fstype_empty )
976 if ( !_point.isEmpty() && dev.isEmpty() && fstype_empty )
980 if ( !_point.isEmpty() && !dev.isEmpty() && fstype_empty )
981 buffer += readonly +
' ' + dev +
' ' + point;
984 #if defined(__svr4__) && defined(Q_OS_SOLARIS) // MARCO for Solaris 8 and I
986 buffer +=
"-F " + fstype +
' ' + (_ro ?
"-oro" :
"") +
' ' + dev +
' ' + point;
988 buffer += readonly +
" -t " + fstype +
' ' + dev +
' ' + point;
990 buffer +=
" 2>" + tmpFileName;
993 int mount_ret = system( buffer.constData() );
996 if ( err.isEmpty() && mount_ret == 0)
1006 if ( mp && mount_ret == 0)
1008 kDebug(7101) <<
"mount got a warning:" << err;
1015 if ( (step == 0) && !_point.isEmpty())
1018 kDebug(7101) <<
"Mounting with those options didn't work, trying with only mountpoint";
1020 fstype_empty =
true;
1033 error( KIO::ERR_COULD_NOT_MOUNT, err );
1042 err =
i18n(
"mounting is not supported by wince.");
1043 error( KIO::ERR_COULD_NOT_MOUNT, err );
1055 tmpFile.setAutoRemove(
false);
1057 QByteArray tmpFileName = QFile::encodeName(tmpFile.fileName());
1069 if( volmgt_running() ) {
1070 kDebug(7101) <<
"VOLMGT: looking for "
1071 << _point.toLocal8Bit();
1073 if( (mnttab = KDE_fopen(
MNTTAB,
"r" )) == NULL ) {
1074 err = QLatin1String(
"could not open mnttab");
1075 kDebug(7101) <<
"VOLMGT: " << err;
1076 error( KIO::ERR_COULD_NOT_UNMOUNT, err );
1088 while( getmntent( mnttab, &mnt ) == 0 ) {
1089 if( strcmp( _point.toLocal8Bit(), mnt.mnt_mountp ) == 0 ){
1090 devname = mnt.mnt_special;
1096 if( devname == NULL ) {
1097 err = QLatin1String(
"not in mnttab");
1098 kDebug(7101) <<
"VOLMGT: "
1099 << QFile::encodeName(_point).data()
1101 error( KIO::ERR_COULD_NOT_UNMOUNT, err );
1110 ptr = strrchr( devname,
'/' );
1112 QByteArray qdevname(QFile::encodeName(KShell::quoteArg(QFile::decodeName(QByteArray(devname)))).data());
1113 buffer =
"/usr/bin/eject " + qdevname +
" 2>" + tmpFileName;
1114 kDebug(7101) <<
"VOLMGT: eject " << qdevname;
1120 if( WEXITSTATUS( system( buffer.constData() )) == 4 ) {
1137 err =
i18n(
"\"vold\" is not running.");
1138 kDebug(7101) <<
"VOLMGT: " << err;
1139 error( KIO::ERR_COULD_NOT_UNMOUNT, err );
1143 QString epath = QString::fromLocal8Bit(qgetenv(
"PATH"));
1144 QString path = QLatin1String(
"/sbin:/bin");
1145 if (!epath.isEmpty())
1146 path += QLatin1Char(
':') + epath;
1147 QByteArray umountProg = KGlobal::dirs()->findExe(QLatin1String(
"umount"), path).toLocal8Bit();
1149 if (umountProg.isEmpty()) {
1150 error( KIO::ERR_COULD_NOT_UNMOUNT,
i18n(
"Could not find program \"umount\""));
1153 buffer = umountProg +
' ' + QFile::encodeName(KShell::quoteArg(_point)) +
" 2>" + tmpFileName;
1154 system( buffer.constData() );
1158 if ( err.isEmpty() )
1161 error( KIO::ERR_COULD_NOT_UNMOUNT, err );
1164 err =
i18n(
"unmounting is not supported by wince.");
1165 error( KIO::ERR_COULD_NOT_MOUNT, err );
1178 QString epath = QString::fromLocal8Bit(qgetenv(
"PATH"));
1179 QString path = QLatin1String(
"/sbin:/bin");
1180 if (!epath.isEmpty())
1181 path += QLatin1Char(
':') + epath;
1182 QString pmountProg = KGlobal::dirs()->findExe(QLatin1String(
"pmount"), path);
1184 if (pmountProg.isEmpty())
1187 QByteArray buffer = QFile::encodeName(pmountProg) +
' ' +
1188 QFile::encodeName(KShell::quoteArg(dev));
1190 int res = system( buffer.constData() );
1204 QString dev = mp->realDeviceName();
1205 if (dev.isEmpty())
return false;
1207 QString epath = QString::fromLocal8Bit(qgetenv(
"PATH"));
1208 QString path = QLatin1String(
"/sbin:/bin");
1209 if (!epath.isEmpty())
1210 path += QLatin1Char(
':') + epath;
1211 QString pumountProg = KGlobal::dirs()->findExe(QLatin1String(
"pumount"), path);
1213 if (pumountProg.isEmpty())
1216 QByteArray buffer = QFile::encodeName(pumountProg);
1218 buffer += QFile::encodeName(KShell::quoteArg(dev));
1220 int res = system( buffer.data() );
1237 QFile file(QFile::decodeName(_filename));
1238 if (file.open(QIODevice::ReadOnly)) {
1239 result = QString::fromLocal8Bit(file.readAll());
1241 (void)file.remove();
1250 #ifdef HAVE_POSIX_ACL
1252 bool FileProtocol::isExtendedACL( acl_t acl )
1254 return ( acl_equiv_mode( acl, 0 ) != 0 );
1257 static void appendACLAtoms(
const QByteArray & path,
UDSEntry& entry, mode_t type,
bool withACL )
1260 if ( acl_extended_file( path.data() ) == 0 )
return;
1263 acl_t defaultAcl = 0;
1264 bool isDir = S_ISDIR( type );
1266 acl = acl_get_file( path.data(), ACL_TYPE_ACCESS );
1271 if ( !FileProtocol::isExtendedACL( acl ) ) {
1276 defaultAcl = acl_get_file( path.data(), ACL_TYPE_DEFAULT );
1278 if ( acl || defaultAcl ) {
1279 kDebug(7101) << path.constData() <<
"has extended ACL entries";
1284 const QString str = aclToText(acl);
1286 kDebug(7101) << path.constData() <<
"ACL:" << str;
1289 const QString str = aclToText(defaultAcl);
1291 kDebug(7101) << path.constData() <<
"DEFAULT ACL:" << str;
1294 if ( acl ) acl_free( acl );
1295 if ( defaultAcl ) acl_free( defaultAcl );
1301 bool FileProtocol::deleteRecursive(
const QString& path)
1304 QDirIterator it(path, QDir::AllEntries | QDir::NoDotAndDotDot | QDir::System | QDir::Hidden,
1305 QDirIterator::Subdirectories);
1307 while ( it.hasNext() ) {
1308 const QString itemPath = it.next();
1310 const QFileInfo info = it.fileInfo();
1311 if (info.isDir() && !info.isSymLink())
1312 dirsToDelete.prepend(itemPath);
1315 if (!QFile::remove(itemPath)) {
1316 error(KIO::ERR_CANNOT_DELETE, itemPath);
1322 Q_FOREACH(
const QString& itemPath, dirsToDelete) {
1324 if (!dir.rmdir(itemPath)) {
1325 error(KIO::ERR_CANNOT_DELETE, itemPath);