diff --git a/sftp/kio_sftp.cpp b/sftp/kio_sftp.cpp --- a/sftp/kio_sftp.cpp +++ b/sftp/kio_sftp.cpp @@ -342,6 +342,9 @@ mode_t type; mode_t access; char *link; + bool isBrokenLink = false; + long long fileType = S_IFREG; + long long size = 0LL; Q_ASSERT(entry.count() == 0); @@ -353,54 +356,53 @@ entry.insert(KIO::UDSEntry::UDS_NAME, filename); if (sb->type == SSH_FILEXFER_TYPE_SYMLINK) { - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); link = sftp_readlink(mSftp, path.constData()); if (link == nullptr) { sftp_attributes_free(sb); return false; } entry.insert(KIO::UDSEntry::UDS_LINK_DEST, QFile::decodeName(link)); - delete link; + free(link); // A symlink -> follow it only if details > 1 if (details > 1) { sftp_attributes sb2 = sftp_stat(mSftp, path.constData()); if (sb2 == nullptr) { - // It is a link pointing to nowhere - type = S_IFMT - 1; - access = S_IRWXU | S_IRWXG | S_IRWXO; - entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, type); - entry.insert( KIO::UDSEntry::UDS_ACCESS, access); - entry.insert( KIO::UDSEntry::UDS_SIZE, 0LL ); - - goto notype; + isBrokenLink = true; + } else { + sftp_attributes_free(sb); + sb = sb2; } - sftp_attributes_free(sb); - sb = sb2; } } - switch (sb->type) { - case SSH_FILEXFER_TYPE_REGULAR: - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); - break; - case SSH_FILEXFER_TYPE_DIRECTORY: - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); - break; - case SSH_FILEXFER_TYPE_SYMLINK: - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFLNK); - break; - case SSH_FILEXFER_TYPE_SPECIAL: - case SSH_FILEXFER_TYPE_UNKNOWN: - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFMT - 1); - break; + if (isBrokenLink) { + // It is a link pointing to nowhere + fileType = S_IFMT - 1; + access = S_IRWXU | S_IRWXG | S_IRWXO; + size = 0LL; + } else { + switch (sb->type) { + case SSH_FILEXFER_TYPE_REGULAR: + fileType = S_IFREG; + break; + case SSH_FILEXFER_TYPE_DIRECTORY: + fileType = S_IFDIR; + break; + case SSH_FILEXFER_TYPE_SYMLINK: + fileType = S_IFLNK; + break; + case SSH_FILEXFER_TYPE_SPECIAL: + case SSH_FILEXFER_TYPE_UNKNOWN: + fileType = S_IFMT - 1; + break; + } + access = sb->permissions & 07777; + size = sb->size; } - - access = sb->permissions & 07777; + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, fileType); entry.insert(KIO::UDSEntry::UDS_ACCESS, access); + entry.insert( KIO::UDSEntry::UDS_SIZE, size); - entry.insert(KIO::UDSEntry::UDS_SIZE, sb->size); - -notype: if (details > 0) { if (sb->owner) { entry.insert(KIO::UDSEntry::UDS_USER, QString::fromUtf8(sb->owner)); @@ -419,6 +421,7 @@ entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, sb->createtime); } + sftp_attributes_free(sb); return true; @@ -1830,6 +1833,9 @@ mode_t access; mode_t type; char *link; + bool isBrokenLink = false; + long long fileType = S_IFREG; + long long size = 0LL; dirent = sftp_readdir(mSftp, dp); if (dirent == nullptr) { @@ -1842,55 +1848,54 @@ if (dirent->type == SSH_FILEXFER_TYPE_SYMLINK) { QByteArray file = path + '/' + QFile::decodeName(dirent->name).toUtf8(); - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); - link = sftp_readlink(mSftp, file.constData()); if (link == nullptr) { sftp_attributes_free(dirent); error(KIO::ERR_INTERNAL, i18n("Could not read link: %1", QString::fromUtf8(file))); return; } entry.insert(KIO::UDSEntry::UDS_LINK_DEST, QFile::decodeName(link)); - delete link; + free(link); // A symlink -> follow it only if details > 1 if (details > 1) { sftp_attributes sb = sftp_stat(mSftp, file.constData()); if (sb == nullptr) { - // It is a link pointing to nowhere - type = S_IFMT - 1; - access = S_IRWXU | S_IRWXG | S_IRWXO; - entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, type); - entry.insert( KIO::UDSEntry::UDS_ACCESS, access); - entry.insert( KIO::UDSEntry::UDS_SIZE, 0LL ); - - goto notype; + isBrokenLink = true; + } else { + sftp_attributes_free(dirent); + dirent = sb; } - sftp_attributes_free(dirent); - dirent = sb; } } - switch (dirent->type) { - case SSH_FILEXFER_TYPE_REGULAR: - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); - break; - case SSH_FILEXFER_TYPE_DIRECTORY: - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); - break; - case SSH_FILEXFER_TYPE_SYMLINK: - entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFLNK); - break; - case SSH_FILEXFER_TYPE_SPECIAL: - case SSH_FILEXFER_TYPE_UNKNOWN: - break; - } + if (isBrokenLink) { + // It is a link pointing to nowhere + fileType = S_IFMT - 1; + access = S_IRWXU | S_IRWXG | S_IRWXO; + size = 0LL; + } else { + switch (dirent->type) { + case SSH_FILEXFER_TYPE_REGULAR: + fileType = S_IFREG; + break; + case SSH_FILEXFER_TYPE_DIRECTORY: + fileType = S_IFDIR; + break; + case SSH_FILEXFER_TYPE_SYMLINK: + fileType = S_IFLNK; + break; + case SSH_FILEXFER_TYPE_SPECIAL: + case SSH_FILEXFER_TYPE_UNKNOWN: + break; + } - access = dirent->permissions & 07777; + access = dirent->permissions & 07777; + size = dirent->size; + } + entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, fileType); entry.insert(KIO::UDSEntry::UDS_ACCESS, access); + entry.insert(KIO::UDSEntry::UDS_SIZE, size); - entry.insert(KIO::UDSEntry::UDS_SIZE, dirent->size); - -notype: if (details > 0) { if (dirent->owner) { entry.insert(KIO::UDSEntry::UDS_USER, QString::fromUtf8(dirent->owner));