diff --git a/src/widgets/krun.h b/src/widgets/krun.h --- a/src/widgets/krun.h +++ b/src/widgets/krun.h @@ -506,6 +506,12 @@ */ virtual void slotStatResult(KJob *); + /** + * This slot is called when 'chmod' job has finished. + * It is only used when user asks to make a file executable for him. + */ + void slotChmodFinished(KJob *); + protected: /** * All following protected methods are used by subclasses of KRun! diff --git a/src/widgets/krun.cpp b/src/widgets/krun.cpp --- a/src/widgets/krun.cpp +++ b/src/widgets/krun.cpp @@ -57,6 +57,7 @@ #include "kopenwithdialog.h" #include "krecentdocument.h" #include "kdesktopfileactions.h" +#include "kfileitem.h" #include "executablefileopendialog_p.h" #include @@ -132,24 +133,20 @@ bool KRun::isExecutableFile(const QUrl &url, const QString &mimetype) { + //File not local if (!url.isLocalFile()) { return false; } QFileInfo file(url.toLocalFile()); - if (file.isExecutable()) { // Got a prospective file to run - QMimeDatabase db; - QMimeType mimeType = db.mimeTypeForName(mimetype); - if (mimeType.inherits(QStringLiteral("application/x-executable")) || -#ifdef Q_OS_WIN - mimeType.inherits(QStringLiteral("application/x-ms-dos-executable")) || -#endif - mimeType.inherits(QStringLiteral("application/x-executable-script")) || - mimeType.inherits(QStringLiteral("application/x-sharedlib")) - ) { - return true; - } + //File not marked as executable + if (!file.isExecutable()) { + return false; } - return false; + //File does not have correct mimetype + if (!isExecutable(mimetype)) { + return false; + } + return true; } void KRun::handleInitError(int kioErrorCode, const QString &errorMsg) @@ -1305,6 +1302,26 @@ } } +void KRun::slotChmodFinished(KJob *job) +{ + d->m_job = nullptr; + const int errCode = job->error(); + if (errCode) { + // ERR_NO_CONTENT is not an error, but an indication no further + // actions needs to be taken. + if (errCode != KIO::ERR_NO_CONTENT) { + qCWarning(KIO_WIDGETS) << this << "ERROR (stat):" << job->error() << ' ' << job->errorString(); + handleError(job); + + d->m_bFault = true; + } + } else { + //If job was succesfull, then restart KRun for the same file. + KRun *rerun = new KRun(d->m_strURL, d->m_window, d->m_bProgressInfo, d->m_asn); + } + setFinished(true); +} + void KRun::mimeTypeDetermined(const QString &mimeType) { // foundMimeType reimplementations might show a dialog box; @@ -1369,7 +1386,33 @@ KRun::RunFlags runFlags; if (d->m_runExecutables) { runFlags |= KRun::RunExecutables; + //If file is executable but doesn't have +x permission, ask user if he wants to set +x + if (!isExecutableFile(d->m_strURL, type) && isExecutable(type)) { + KMessageBox::ButtonCode makeExecutable = KMessageBox::questionYesNo( + d->m_window, + i18n("File %1 is not marked as executable. Do you wish to run it?
" + "Keep in mind that if you don't know the source of this file, it may be unsafe to run it!", + d->m_strURL.toLocalFile()), + i18n("Run executable file"), + KGuiItem(i18n("Make executable and run")), + KGuiItem(i18n("Open")) + ); + //If the answer was Yes, start KIO::chmod job + if (makeExecutable == KMessageBox::ButtonCode::Yes) { + KFileItem binaryFile(d->m_strURL); + mode_t newPermissions = binaryFile.permissions() | S_IXUSR; + KIO::Job* chmodJob = KIO::chmod(d->m_strURL, newPermissions); + connect(chmodJob, &KJob::result, + this, &KRun::slotChmodFinished); + chmodJob->start(); + d->m_job = chmodJob; + //Stop further execution, it will later be restarted or abandoned after the job finishes + return; + } + //If the answer was No, then execute normally + } } + if (!KRun::runUrl(d->m_strURL, type, d->m_window, runFlags, d->m_suggestedFileName, d->m_asn)) { d->m_bFault = true; } @@ -1486,12 +1529,14 @@ bool KRun::isExecutable(const QString &serviceType) { - return (serviceType == QLatin1String("application/x-desktop") || - serviceType == QLatin1String("application/x-executable") || + QMimeDatabase db; + QMimeType mimeType = db.mimeTypeForName(serviceType); + return (mimeType.inherits(QLatin1String("application/x-desktop")) || + mimeType.inherits(QLatin1String("application/x-executable")) || /* See https://bugs.freedesktop.org/show_bug.cgi?id=97226 */ - serviceType == QLatin1String("application/x-sharedlib") || - serviceType == QLatin1String("application/x-ms-dos-executable") || - serviceType == QLatin1String("application/x-shellscript")); + mimeType.inherits(QLatin1String("application/x-sharedlib")) || + mimeType.inherits(QLatin1String("application/x-ms-dos-executable")) || + mimeType.inherits(QLatin1String("application/x-shellscript"))); } void KRun::setUrl(const QUrl &url)