817
void FileProtocol::copy( const KUrl &src, const KUrl &dest,
818
int _mode, JobFlags _flags )
820
kDebug(7101) << "copy(): " << src << " -> " << dest << ", mode=" << _mode;
822
QByteArray _src( QFile::encodeName(src.toLocalFile()));
823
QByteArray _dest( QFile::encodeName(dest.toLocalFile()));
824
KDE_struct_stat buff_src;
825
#ifdef HAVE_POSIX_ACL
829
if ( KDE_stat( _src.data(), &buff_src ) == -1 ) {
830
if ( errno == EACCES )
831
error( KIO::ERR_ACCESS_DENIED, _src );
833
error( KIO::ERR_DOES_NOT_EXIST, _src );
837
if ( S_ISDIR( buff_src.st_mode ) ) {
838
error( KIO::ERR_IS_DIRECTORY, src.path() );
841
if ( S_ISFIFO( buff_src.st_mode ) || S_ISSOCK ( buff_src.st_mode ) ) {
842
error( KIO::ERR_CANNOT_OPEN_FOR_READING, src.path() );
846
KDE_struct_stat buff_dest;
847
bool dest_exists = ( KDE_lstat( _dest.data(), &buff_dest ) != -1 );
850
if (S_ISDIR(buff_dest.st_mode))
852
error( KIO::ERR_DIR_ALREADY_EXIST, _dest );
856
if ( same_inode( buff_dest, buff_src) )
858
error( KIO::ERR_IDENTICAL_FILES, _dest );
862
if (!(_flags & KIO::Overwrite))
864
error( KIO::ERR_FILE_ALREADY_EXIST, _dest );
868
// If the destination is a symlink and overwrite is TRUE,
869
// remove the symlink first to prevent the scenario where
870
// the symlink actually points to current source!
871
if ((_flags & KIO::Overwrite) && S_ISLNK(buff_dest.st_mode))
873
//kDebug(7101) << "copy(): LINK DESTINATION";
874
remove( _dest.data() );
878
int src_fd = KDE_open( _src.data(), O_RDONLY);
880
error( KIO::ERR_CANNOT_OPEN_FOR_READING, _src );
885
posix_fadvise(src_fd,0,0,POSIX_FADV_SEQUENTIAL);
887
// WABA: Make sure that we keep writing permissions ourselves,
888
// otherwise we can be in for a surprise on NFS.
891
initialMode = _mode | S_IWUSR;
895
int dest_fd = KDE_open(_dest.data(), O_CREAT | O_TRUNC | O_WRONLY, initialMode);
897
kDebug(7101) << "###### COULD NOT WRITE " << dest.url();
898
if ( errno == EACCES ) {
899
error( KIO::ERR_WRITE_ACCESS_DENIED, _dest );
901
error( KIO::ERR_CANNOT_OPEN_FOR_WRITING, _dest );
908
posix_fadvise(dest_fd,0,0,POSIX_FADV_SEQUENTIAL);
911
#ifdef HAVE_POSIX_ACL
912
acl = acl_get_fd(src_fd);
913
if ( acl && !isExtendedACL( acl ) ) {
914
kDebug(7101) << _dest.data() << " doesn't have extended ACL";
919
totalSize( buff_src.st_size );
921
KIO::filesize_t processed_size = 0;
922
char buffer[ MAX_IPC_SIZE ];
925
bool use_sendfile=buff_src.st_size < 0x7FFFFFFF;
931
off_t sf = processed_size;
932
n = KDE_sendfile( dest_fd, src_fd, &sf, MAX_IPC_SIZE );
934
if ( n == -1 && ( errno == EINVAL || errno == ENOSYS ) ) { //not all filesystems support sendfile()
935
kDebug(7101) << "sendfile() not supported, falling back ";
936
use_sendfile = false;
941
n = ::read( src_fd, buffer, MAX_IPC_SIZE );
948
if ( use_sendfile ) {
949
kDebug(7101) << "sendfile() error:" << strerror(errno);
950
if ( errno == ENOSPC ) // disk full
952
error( KIO::ERR_DISK_FULL, _dest );
953
remove( _dest.data() );
956
error( KIO::ERR_SLAVE_DEFINED,
957
i18n("Cannot copy file from %1 to %2. (Errno: %3)",
958
src.toLocalFile(), dest.toLocalFile(), errno ) );
962
error( KIO::ERR_COULD_NOT_READ, _src );
965
#ifdef HAVE_POSIX_ACL
966
if (acl) acl_free(acl);
973
if ( !use_sendfile ) {
975
if (write_all( dest_fd, buffer, n))
980
if ( errno == ENOSPC ) // disk full
982
error( KIO::ERR_DISK_FULL, _dest );
983
remove( _dest.data() );
987
kWarning(7101) << "Couldn't write[2]. Error:" << strerror(errno);
988
error( KIO::ERR_COULD_NOT_WRITE, _dest );
990
#ifdef HAVE_POSIX_ACL
991
if (acl) acl_free(acl);
999
processedSize( processed_size );
1004
if (::close( dest_fd))
1006
kWarning(7101) << "Error when closing file descriptor[2]:" << strerror(errno);
1007
error( KIO::ERR_COULD_NOT_WRITE, _dest );
1008
#ifdef HAVE_POSIX_ACL
1009
if (acl) acl_free(acl);
1014
// set final permissions
1017
if ( (::chmod(_dest.data(), _mode) != 0)
1018
#ifdef HAVE_POSIX_ACL
1019
|| (acl && acl_set_file(_dest.data(), ACL_TYPE_ACCESS, acl) != 0)
1023
KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByPath(_dest);
1024
// Eat the error if the filesystem apparently doesn't support chmod.
1025
if ( mp && mp->testFileSystemFlag( KMountPoint::SupportsChmod ) )
1026
warning( i18n( "Could not change permissions for\n%1" , dest.toLocalFile() ) );
1029
#ifdef HAVE_POSIX_ACL
1030
if (acl) acl_free(acl);
1033
// copy access and modification time
1035
ut.actime = buff_src.st_atime;
1036
ut.modtime = buff_src.st_mtime;
1037
if ( ::utime( _dest.data(), &ut ) != 0 )
1039
kWarning() << QString::fromLatin1("Couldn't preserve access and modification time for\n%1").arg( _dest.data() );
1042
processedSize( buff_src.st_size );
1046
void FileProtocol::rename( const KUrl &src, const KUrl &dest,
1047
KIO::JobFlags _flags )
1049
char off_t_should_be_64_bits[sizeof(off_t) >= 8 ? 1 : -1]; (void) off_t_should_be_64_bits;
1050
QByteArray _src(QFile::encodeName(src.toLocalFile()));
1051
QByteArray _dest(QFile::encodeName(dest.toLocalFile()));
1052
KDE_struct_stat buff_src;
1053
if ( KDE_lstat( _src.data(), &buff_src ) == -1 ) {
1054
if ( errno == EACCES )
1055
error( KIO::ERR_ACCESS_DENIED, _src );
1057
error( KIO::ERR_DOES_NOT_EXIST, _src );
1061
KDE_struct_stat buff_dest;
1062
// stat symlinks here (lstat, not stat), to avoid ERR_IDENTICAL_FILES when replacing symlink
1063
// with its target (#169547)
1064
bool dest_exists = ( KDE_lstat( _dest.data(), &buff_dest ) != -1 );
1067
if (S_ISDIR(buff_dest.st_mode))
1069
error( KIO::ERR_DIR_ALREADY_EXIST, _dest );
1073
if ( same_inode( buff_dest, buff_src) )
1075
error( KIO::ERR_IDENTICAL_FILES, _dest );
1079
if (!(_flags & KIO::Overwrite))
1081
error( KIO::ERR_FILE_ALREADY_EXIST, _dest );
1086
if ( KDE_rename( _src.data(), _dest.data()))
1088
if (( errno == EACCES ) || (errno == EPERM)) {
1089
error( KIO::ERR_ACCESS_DENIED, _dest );
1091
else if (errno == EXDEV) {
1092
error( KIO::ERR_UNSUPPORTED_ACTION, QLatin1String("rename"));
1094
else if (errno == EROFS) { // The file is on a read-only filesystem
1095
error( KIO::ERR_CANNOT_DELETE, _src );
1098
error( KIO::ERR_CANNOT_RENAME, _src );
1106
void FileProtocol::symlink( const QString &target, const KUrl &dest, KIO::JobFlags flags )
1108
// Assume dest is local too (wouldn't be here otherwise)
1109
if ( ::symlink( QFile::encodeName( target ), QFile::encodeName( dest.path() ) ) == -1 )
1111
// Does the destination already exist ?
1112
if ( errno == EEXIST )
1114
if ( (flags & KIO::Overwrite) )
1116
// Try to delete the destination
1117
if ( unlink( QFile::encodeName( dest.path() ) ) != 0 )
1119
error( KIO::ERR_CANNOT_DELETE, dest.path() );
1122
// Try again - this won't loop forever since unlink succeeded
1123
symlink( target, dest, flags );
1127
KDE_struct_stat buff_dest;
1128
KDE_lstat( QFile::encodeName( dest.path() ), &buff_dest );
1129
if (S_ISDIR(buff_dest.st_mode))
1130
error( KIO::ERR_DIR_ALREADY_EXIST, dest.path() );
1132
error( KIO::ERR_FILE_ALREADY_EXIST, dest.path() );
1138
// Some error occurred while we tried to symlink
1139
error( KIO::ERR_CANNOT_SYMLINK, dest.path() );
1146
void FileProtocol::del( const KUrl& url, bool isfile)
1148
QByteArray _path( QFile::encodeName(url.toLocalFile()));
1154
kDebug( 7101 ) << "Deleting file "<< url.url();
1156
// TODO deletingFile( source );
1158
if ( unlink( _path.data() ) == -1 ) {
1159
if ((errno == EACCES) || (errno == EPERM))
1160
error( KIO::ERR_ACCESS_DENIED, _path );
1161
else if (errno == EISDIR)
1162
error( KIO::ERR_IS_DIRECTORY, _path );
1164
error( KIO::ERR_CANNOT_DELETE, _path );
1170
* Delete empty directory
1173
kDebug( 7101 ) << "Deleting directory " << url.url();
1175
if ( ::rmdir( _path.data() ) == -1 ) {
1176
if ((errno == EACCES) || (errno == EPERM))
1177
error( KIO::ERR_ACCESS_DENIED, _path );
1179
kDebug( 7101 ) << "could not rmdir " << perror;
1180
error( KIO::ERR_COULD_NOT_RMDIR, _path );
1191
750
QString FileProtocol::getUserName( uid_t uid ) const
1193
752
if ( !mUsercache.contains( uid ) ) {
1341
void FileProtocol::listDir( const KUrl& url)
1343
kDebug(7101) << "========= LIST " << url.url() << " =========";
1344
if (!url.isLocalFile()) {
1346
redir.setProtocol(config()->readEntry("DefaultRemoteProtocol", "smb"));
1348
kDebug(7101) << "redirecting to " << redir.url();
1352
QByteArray _path( QFile::encodeName(url.toLocalFile()) );
1353
KDE_struct_stat buff;
1354
if ( KDE_stat( _path.data(), &buff ) == -1 ) {
1355
error( KIO::ERR_DOES_NOT_EXIST, _path );
1359
if ( !S_ISDIR( buff.st_mode ) ) {
1360
error( KIO::ERR_IS_FILE, _path );
1365
KDE_struct_dirent *ep;
1367
dp = opendir( _path.data() );
1373
error( ERR_SLAVE_DEFINED,
1374
i18n( "No media in device for %1", url.toLocalFile() ) );
1377
case ENOENT: // just to avoid the warning
1380
error( KIO::ERR_CANNOT_ENTER_DIRECTORY, _path );
1386
// Don't make this a QStringList. The locale file name we get here
1387
// should be passed intact to createUDSEntry to avoid problems with
1388
// files where QFile::encodeName(QFile::decodeName(a)) != a.
1389
QList<QByteArray> entryNames;
1390
while ( ( ep = KDE_readdir( dp ) ) != 0L )
1391
entryNames.append( ep->d_name );
1394
totalSize( entryNames.count() );
1396
/* set the current dir to the path to speed up
1397
in not having to pass an absolute path.
1398
We restore the path later to get out of the
1399
path - the kernel wouldn't unmount or delete
1400
directories we keep as active directory. And
1401
as the slave runs in the background, it's hard
1402
to see for the user what the problem would be */
1403
char path_buffer[PATH_MAX];
1404
getcwd(path_buffer, PATH_MAX - 1);
1405
if ( chdir( _path.data() ) ) {
1406
if (errno == EACCES)
1407
error(ERR_ACCESS_DENIED, _path);
1409
error(ERR_CANNOT_ENTER_DIRECTORY, _path);
1414
QList<QByteArray>::ConstIterator it = entryNames.constBegin();
1415
QList<QByteArray>::ConstIterator end = entryNames.constEnd();
1416
for (; it != end; ++it) {
1418
if ( createUDSEntry( QFile::decodeName(*it),
1419
*it /* we can use the filename as relative path*/,
1421
listEntry( entry, false);
1424
listEntry( entry, true ); // ready
1426
kDebug(7101) << "============= COMPLETED LIST ============";
1434
900
void FileProtocol::testDir( const QString& path )