diff options
Diffstat (limited to 'kio/kio/krun.cpp')
-rw-r--r-- | kio/kio/krun.cpp | 1574 |
1 files changed, 0 insertions, 1574 deletions
diff --git a/kio/kio/krun.cpp b/kio/kio/krun.cpp deleted file mode 100644 index f99f636db..000000000 --- a/kio/kio/krun.cpp +++ /dev/null @@ -1,1574 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Torben Weis <weis@kde.org> - Copyright (C) 2006 David Faure <faure@kde.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "krun.h" - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <typeinfo> - -#include <tqwidget.h> -#include <tqguardedptr.h> - -#include "kuserprofile.h" -#include "kmimetype.h" -#include "kmimemagic.h" -#include "kio/job.h" -#include "kio/global.h" -#include "kio/scheduler.h" -#include "kio/netaccess.h" -#include "kfile/kopenwith.h" -#include "kfile/krecentdocument.h" - -#include <kdatastream.h> -#include <kmessageboxwrapper.h> -#include <kurl.h> -#include <kapplication.h> -#include <kdebug.h> -#include <klocale.h> -#include <kprotocolinfo.h> -#include <kstandarddirs.h> -#include <kprocess.h> -#include <dcopclient.h> -#include <tqfile.h> -#include <tqfileinfo.h> -#include <tqtextstream.h> -#include <tqdatetime.h> -#include <tqregexp.h> -#include <kdesktopfile.h> -#include <kstartupinfo.h> -#include <kmacroexpander.h> -#include <kshell.h> -#include <kde_file.h> -#include <kstringhandler.h> - -#ifdef Q_WS_X11 -#include <twin.h> -#endif - -class KRun::KRunPrivate -{ -public: - KRunPrivate() { m_showingError = false; } - - bool m_showingError; - bool m_runExecutables; - - TQString m_preferredService; - TQString m_externalBrowser; - TQString m_localPath; - TQString m_suggestedFileName; - TQGuardedPtr <TQWidget> m_window; - TQCString m_asn; -}; - -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype ) -{ - return runURL( u, _mimetype, false, true, TQString::null ); -} - -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype, bool tempFile ) -{ - return runURL( u, _mimetype, tempFile, true, TQString::null ); -} - -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype, bool tempFile, bool runExecutables ) -{ - return runURL( u, _mimetype, tempFile, runExecutables, TQString::null ); -} - -bool KRun::isExecutableFile( const KURL& url, const TQString &mimetype ) -{ - if ( !url.isLocalFile() ) - return false; - TQFileInfo file( url.path() ); - if ( file.isExecutable() ) // Got a prospective file to run - { - KMimeType::Ptr mimeType = KMimeType::mimeType( mimetype ); - - if ( mimeType->is("application/x-executable") || mimeType->is("application/x-executable-script") ) - return true; - } - return false; -} - -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype, bool tempFile, bool runExecutables, const TQString& suggestedFileName ) -{ - return runURL( u, _mimetype, NULL, "", tempFile, runExecutables, suggestedFileName ); -} - -// This is called by foundMimeType, since it knows the mimetype of the URL -pid_t KRun::runURL( const KURL& u, const TQString& _mimetype, TQWidget* window, const TQCString& asn, - bool tempFile, bool runExecutables, const TQString& suggestedFileName ) -{ - bool noRun = false; - bool noAuth = false; - if ( _mimetype == "inode/directory-locked" ) - { - KMessageBoxWrapper::error( window, - i18n("<qt>Unable to enter <b>%1</b>.\nYou do not have access rights to this location.</qt>").arg(u.htmlURL()) ); - return 0; - } - else if ( (_mimetype == "application/x-desktop") || - (_mimetype == "media/builtin-mydocuments") || - (_mimetype == "media/builtin-mycomputer") || - (_mimetype == "media/builtin-mynetworkplaces") || - (_mimetype == "media/builtin-printers") || - (_mimetype == "media/builtin-trash") || - (_mimetype == "media/builtin-webbrowser") ) - { - if ( u.isLocalFile() && runExecutables ) - return KDEDesktopMimeType::run( u, true ); - } - else if ( isExecutableFile(u, _mimetype) ) - { - if ( u.isLocalFile() && runExecutables) - { - if (kapp->authorize("shell_access")) - { - TQString path = u.path(); - shellQuote( path ); - return (KRun::runCommand(path, TQString::null, TQString::null, window, asn)); // just execute the url as a command - // ## TODO implement deleting the file if tempFile==true - } - else - { - noAuth = true; - } - } - else if (_mimetype == "application/x-executable") - noRun = true; - } - else if ( isExecutable(_mimetype) ) - { - if (!runExecutables) - noRun = true; - - if (!kapp->authorize("shell_access")) - noAuth = true; - } - - if ( noRun ) - { - KMessageBox::sorry( window, - i18n("<qt>The file <b>%1</b> is an executable program. " - "For safety it will not be started.</qt>").arg(u.htmlURL())); - return 0; - } - if ( noAuth ) - { - KMessageBoxWrapper::error( window, - i18n("<qt>You do not have permission to run <b>%1</b>.</qt>").arg(u.htmlURL()) ); - return 0; - } - - KURL::List lst; - lst.append( u ); - - static const TQString& app_str = TDEGlobal::staticQString("Application"); - - KService::Ptr offer = KServiceTypeProfile::preferredService( _mimetype, app_str ); - - if ( !offer ) - { - // Open-with dialog - // TODO : pass the mimetype as a parameter, to show it (comment field) in the dialog ! - // Hmm, in fact KOpenWithDlg::setServiceType already guesses the mimetype from the first URL of the list... - return displayOpenWithDialog( lst, tempFile, suggestedFileName ); - } - - return KRun::run( *offer, lst, window, asn, tempFile, suggestedFileName ); -} - -bool KRun::displayOpenWithDialog( const KURL::List& lst ) -{ - return displayOpenWithDialog( lst, false, TQString::null ); -} - -bool KRun::displayOpenWithDialog( const KURL::List& lst, bool tempFiles ) -{ - return displayOpenWithDialog( lst, tempFiles, TQString::null ); -} - -bool KRun::displayOpenWithDialog( const KURL::List& lst, bool tempFiles, const TQString& suggestedFileName ) -{ - if (kapp && !kapp->authorizeKAction("openwith")) - { - // TODO: Better message, i18n freeze :-( - KMessageBox::sorry(0L, i18n("You are not authorized to open this file.")); - return false; - } - - KOpenWithDlg l( lst, i18n("Open with:"), TQString::null, 0L ); - if ( l.exec() ) - { - KService::Ptr service = l.service(); - if ( !!service ) - return KRun::run( *service, lst, 0 /*window*/, tempFiles, suggestedFileName ); - - kdDebug(7010) << "No service set, running " << l.text() << endl; - return KRun::run( l.text(), lst, suggestedFileName ); // TODO handle tempFiles - } - return false; -} - -void KRun::shellQuote( TQString &_str ) -{ - // Credits to Walter, says Bernd G. :) - if (_str.isEmpty()) // Don't create an explicit empty parameter - return; - TQChar q('\''); - _str.replace(q, "'\\''").prepend(q).append(q); -} - - -class KRunMX1 : public KMacroExpanderBase { -public: - KRunMX1( const KService &_service ) : - KMacroExpanderBase( '%' ), hasUrls( false ), hasSpec( false ), service( _service ) {} - bool hasUrls:1, hasSpec:1; - -protected: - virtual int expandEscapedMacro( const TQString &str, uint pos, TQStringList &ret ); - -private: - const KService &service; -}; - -int -KRunMX1::expandEscapedMacro( const TQString &str, uint pos, TQStringList &ret ) -{ - uint option = str[pos + 1]; - switch( option ) { - case 'c': - ret << service.name().replace( '%', "%%" ); - break; - case 'k': - ret << service.desktopEntryPath().replace( '%', "%%" ); - break; - case 'i': - ret << "-icon" << service.icon().replace( '%', "%%" ); - break; - case 'm': - ret << "-miniicon" << service.icon().replace( '%', "%%" ); - break; - case 'u': - case 'U': - hasUrls = true; - /* fallthrough */ - case 'f': - case 'F': - case 'n': - case 'N': - case 'd': - case 'D': - case 'v': - hasSpec = true; - /* fallthrough */ - default: - return -2; // subst with same and skip - } - return 2; -} - -class KRunMX2 : public KMacroExpanderBase { -public: - KRunMX2( const KURL::List &_urls ) : - KMacroExpanderBase( '%' ), ignFile( false ), urls( _urls ) {} - bool ignFile:1; - -protected: - virtual int expandEscapedMacro( const TQString &str, uint pos, TQStringList &ret ); - -private: - void subst( int option, const KURL &url, TQStringList &ret ); - - const KURL::List &urls; -}; - -void -KRunMX2::subst( int option, const KURL &url, TQStringList &ret ) -{ - switch( option ) { - case 'u': - ret << url.pathOrURL(); - break; - case 'd': - ret << url.directory(); - break; - case 'f': - ret << url.path(); - break; - case 'n': - ret << url.fileName(); - break; - case 'v': - if (url.isLocalFile() && TQFile::exists( url.path() ) ) - ret << KDesktopFile( url.path(), true ).readEntry( "Dev" ); - break; - } - return; -} - -int -KRunMX2::expandEscapedMacro( const TQString &str, uint pos, TQStringList &ret ) -{ - uint option = str[pos + 1]; - switch( option ) { - case 'f': - case 'u': - case 'n': - case 'd': - case 'v': - if( urls.isEmpty() ) { - if (!ignFile) - kdDebug() << "KRun::processDesktopExec: No URLs supplied to single-URL service " << str << endl; - } else if( urls.count() > 1 ) - kdWarning() << "KRun::processDesktopExec: " << urls.count() << " URLs supplied to single-URL service " << str << endl; - else - subst( option, urls.first(), ret ); - break; - case 'F': - case 'U': - case 'N': - case 'D': - option += 'a' - 'A'; - for( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) - subst( option, *it, ret ); - break; - case '%': - ret = "%"; - break; - default: - return -2; // subst with same and skip - } - return 2; -} - -// BIC: merge methods below -TQStringList KRun::processDesktopExec(const KService &_service, const KURL::List& _urls, bool has_shell) { - return processDesktopExec( _service, _urls, has_shell, false, TQString::null ); -} - -TQStringList KRun::processDesktopExec(const KService &_service, const KURL::List& _urls, bool has_shell /* KDE4: remove */, bool tempFiles) -{ - return processDesktopExec( _service, _urls, has_shell, tempFiles, TQString::null ); -} - -TQStringList KRun::processDesktopExec(const KService &_service, const KURL::List& _urls, bool has_shell /* KDE4: remove */, bool tempFiles, const TQString& suggestedFileName) -{ - TQString exec = _service.exec(); - TQStringList result; - bool appHasTempFileOption; - - KRunMX1 mx1( _service ); - KRunMX2 mx2( _urls ); - - /// compatibility hack -- KDE 4: remove - TQRegExp re("^\\s*(?:/bin/)?sh\\s+-c\\s+(.*)$"); - if (!re.search( exec )) { - exec = TQString(re.cap( 1 )).stripWhiteSpace(); - for (uint pos = 0; pos < exec.length(); ) { - TQChar c = exec.unicode()[pos]; - if (c != '\'' && c != '"') - goto synerr; // what else can we do? after normal parsing the substs would be insecure - int pos2 = exec.find( c, pos + 1 ) - 1; - if (pos2 < 0) - goto synerr; // quoting error - memcpy( (void *)(exec.unicode() + pos), exec.unicode() + pos + 1, (pos2 - pos) * sizeof(TQChar)); - pos = pos2; - exec.remove( pos, 2 ); - } - } - - if( !mx1.expandMacrosShellQuote( exec ) ) - goto synerr; // error in shell syntax - - // FIXME: the current way of invoking kioexec disables term and su use - - // Check if we need "tempexec" (kioexec in fact) - appHasTempFileOption = tempFiles && _service.property("X-TDE-HasTempFileOption").toBool(); - if( tempFiles && !appHasTempFileOption && _urls.size() ) { - result << "kioexec" << "--tempfiles" << exec; - result += _urls.toStringList(); - if (has_shell) - result = KShell::joinArgs( result ); - return result; - } - - // Check if we need kioexec - if( !mx1.hasUrls ) { - for( KURL::List::ConstIterator it = _urls.begin(); it != _urls.end(); ++it ) - if ( !(*it).isLocalFile() && !KProtocolInfo::isHelperProtocol(*it) ) { - // We need to run the app through kioexec - result << "kioexec"; - if ( tempFiles ) - result << "--tempfiles"; - if ( !suggestedFileName.isEmpty() ) { - result << "--suggestedfilename"; - result << suggestedFileName; - } - result << exec; - result += _urls.toStringList(); - if (has_shell) - result = KShell::joinArgs( result ); - return result; - } - } - - if ( appHasTempFileOption ) - exec += " --tempfile"; - - // Did the user forget to append something like '%f'? - // If so, then assume that '%f' is the right choice => the application - // accepts only local files. - if( !mx1.hasSpec ) { - exec += " %f"; - mx2.ignFile = true; - } - - mx2.expandMacrosShellQuote( exec ); // syntax was already checked, so don't check return value - -/* - 1 = need_shell, 2 = terminal, 4 = su, 8 = has_shell - - 0 << split(cmd) - 1 << "sh" << "-c" << cmd - 2 << split(term) << "-e" << split(cmd) - 3 << split(term) << "-e" << "sh" << "-c" << cmd - - 4 << "tdesu" << "-u" << user << "-c" << cmd - 5 << "tdesu" << "-u" << user << "-c" << ("sh -c " + quote(cmd)) - 6 << split(term) << "-e" << "su" << user << "-c" << cmd - 7 << split(term) << "-e" << "su" << user << "-c" << ("sh -c " + quote(cmd)) - - 8 << cmd - 9 << cmd - a << term << "-e" << cmd - b << term << "-e" << ("sh -c " + quote(cmd)) - - c << "tdesu" << "-u" << user << "-c" << quote(cmd) - d << "tdesu" << "-u" << user << "-c" << quote("sh -c " + quote(cmd)) - e << term << "-e" << "su" << user << "-c" << quote(cmd) - f << term << "-e" << "su" << user << "-c" << quote("sh -c " + quote(cmd)) - - "sh -c" is needed in the "su" case, too, as su uses the user's login shell, not sh. - this could be optimized with the -s switch of some su versions (e.g., debian linux). -*/ - - if (_service.terminal()) { - TDEConfigGroupSaver gs(TDEGlobal::config(), "General"); - TQString terminal = TDEGlobal::config()->readPathEntry("TerminalApplication", "konsole"); - if (terminal == "konsole") - terminal += " -caption=%c %i %m"; - terminal += " "; - terminal += _service.terminalOptions(); - if( !mx1.expandMacrosShellQuote( terminal ) ) { - kdWarning() << "KRun: syntax error in command `" << terminal << "', service `" << _service.name() << "'" << endl; - return TQStringList(); - } - mx2.expandMacrosShellQuote( terminal ); - if (has_shell) - result << terminal; - else - result = KShell::splitArgs( terminal ); // assuming that the term spec never needs a shell! - result << "-e"; - } - - int err; - if (_service.substituteUid()) { - if (_service.terminal()) - result << "su"; - else - result << "tdesu" << "-u"; - result << _service.username() << "-c"; - KShell::splitArgs(exec, KShell::AbortOnMeta | KShell::TildeExpand, &err); - if (err == KShell::FoundMeta) { - shellQuote( exec ); - exec.prepend( "/bin/sh -c " ); - } else if (err != KShell::NoError) - goto synerr; - if (has_shell) - shellQuote( exec ); - result << exec; - } else { - if (has_shell) { - if (_service.terminal()) { - KShell::splitArgs(exec, KShell::AbortOnMeta | KShell::TildeExpand, &err); - if (err == KShell::FoundMeta) { - shellQuote( exec ); - exec.prepend( "/bin/sh -c " ); - } else if (err != KShell::NoError) - goto synerr; - } - result << exec; - } else { - result += KShell::splitArgs(exec, KShell::AbortOnMeta | KShell::TildeExpand, &err); - if (err == KShell::FoundMeta) - result << "/bin/sh" << "-c" << exec; - else if (err != KShell::NoError) - goto synerr; - } - } - - return result; - - synerr: - kdWarning() << "KRun: syntax error in command `" << _service.exec() << "', service `" << _service.name() << "'" << endl; - return TQStringList(); -} - -//static -TQString KRun::binaryName( const TQString & execLine, bool removePath ) -{ - // Remove parameters and/or trailing spaces. - TQStringList args = KShell::splitArgs( execLine ); - for (TQStringList::ConstIterator it = args.begin(); it != args.end(); ++it) - if (!(*it).contains('=')) - // Remove path if wanted - return removePath ? (*it).mid(TQString(*it).findRev('/') + 1) : *it; - return TQString(); -} - -static pid_t runCommandInternal( TDEProcess* proc, const KService* service, const TQString& binName, - const TQString &execName, const TQString & iconName, TQWidget* window, TQCString asn ) -{ - if (service && !service->desktopEntryPath().isEmpty() - && !KDesktopFile::isAuthorizedDesktopFile( service->desktopEntryPath() )) - { - kdWarning() << "No authorization to execute " << service->desktopEntryPath() << endl; - KMessageBox::sorry(window, i18n("You are not authorized to execute this file.")); - return 0; - } - TQString bin = KRun::binaryName( binName, true ); -#ifdef Q_WS_X11 // Startup notification doesn't work with QT/E, service isn't needed without Startup notification - bool silent; - TQCString wmclass; - KStartupInfoId id; - bool startup_notify = ( asn != "0" && KRun::checkStartupNotify( binName, service, &silent, &wmclass )); - if( startup_notify ) - { - id.initId( asn ); - id.setupStartupEnv(); - KStartupInfoData data; - data.setHostname(); - data.setBin( bin ); - if( !execName.isEmpty()) - data.setName( execName ); - else if( service && !service->name().isEmpty()) - data.setName( service->name()); - data.setDescription( i18n( "Launching %1" ).arg( data.name())); - if( !iconName.isEmpty()) - data.setIcon( iconName ); - else if( service && !service->icon().isEmpty()) - data.setIcon( service->icon()); - if( !wmclass.isEmpty()) - data.setWMClass( wmclass ); - if( silent ) - data.setSilent( KStartupInfoData::Yes ); - data.setDesktop( KWin::currentDesktop()); - if( window ) - data.setLaunchedBy( window->winId()); - KStartupInfo::sendStartup( id, data ); - } - pid_t pid = TDEProcessRunner::run( proc, binName, id ); - if( startup_notify && pid ) - { - KStartupInfoData data; - data.addPid( pid ); - KStartupInfo::sendChange( id, data ); - KStartupInfo::resetStartupEnv(); - } - return pid; -#else - Q_UNUSED( execName ); - Q_UNUSED( iconName ); - return TDEProcessRunner::run( proc, bin ); -#endif -} - -// This code is also used in klauncher. -bool KRun::checkStartupNotify( const TQString& /*binName*/, const KService* service, bool* silent_arg, TQCString* wmclass_arg ) -{ - bool silent = false; - TQCString wmclass; - if( service && service->property( "StartupNotify" ).isValid()) - { - silent = !service->property( "StartupNotify" ).toBool(); - wmclass = service->property( "StartupWMClass" ).toString().latin1(); - } - else if( service && service->property( "X-TDE-StartupNotify" ).isValid()) - { - silent = !service->property( "X-TDE-StartupNotify" ).toBool(); - wmclass = service->property( "X-TDE-WMClass" ).toString().latin1(); - } - else // non-compliant app - { - if( service ) - { - if( service->type() == "Application" ) - wmclass = "0"; // doesn't have .desktop entries needed, start as non-compliant - else - return false; // no startup notification at all - } - else - { -#if 0 - // Create startup notification even for apps for which there shouldn't be any, - // just without any visual feedback. This will ensure they'll be positioned on the proper - // virtual desktop, and will get user timestamp from the ASN ID. - wmclass = "0"; - silent = true; -#else // That unfortunately doesn't work, when the launched non-compliant application - // launches another one that is compliant and there is any delay inbetween (bnc:#343359) - return false; -#endif - } - } - if( silent_arg != NULL ) - *silent_arg = silent; - if( wmclass_arg != NULL ) - *wmclass_arg = wmclass; - return true; -} - -static pid_t runTempService( const KService& _service, const KURL::List& _urls, TQWidget* window, - const TQCString& asn, bool tempFiles, const TQString& suggestedFileName ) -{ - if (!_urls.isEmpty()) { - kdDebug(7010) << "runTempService: first url " << _urls.first().url() << endl; - } - - TQStringList args; - if ((_urls.count() > 1) && !_service.allowMultipleFiles()) - { - // We need to launch the application N times. That sucks. - // We ignore the result for application 2 to N. - // For the first file we launch the application in the - // usual way. The reported result is based on this - // application. - KURL::List::ConstIterator it = _urls.begin(); - while(++it != _urls.end()) - { - KURL::List singleUrl; - singleUrl.append(*it); - runTempService( _service, singleUrl, window, "", tempFiles, suggestedFileName ); - } - KURL::List singleUrl; - singleUrl.append(_urls.first()); - args = KRun::processDesktopExec(_service, singleUrl, false, tempFiles, suggestedFileName); - } - else - { - args = KRun::processDesktopExec(_service, _urls, false, tempFiles, suggestedFileName); - } - kdDebug(7010) << "runTempService: TDEProcess args=" << args << endl; - - TDEProcess * proc = new TDEProcess; - *proc << args; - - if (!_service.path().isEmpty()) - proc->setWorkingDirectory(_service.path()); - - return runCommandInternal( proc, &_service, KRun::binaryName( _service.exec(), false ), - _service.name(), _service.icon(), window, asn ); -} - -// WARNING: don't call this from processDesktopExec, since klauncher uses that too... -static KURL::List resolveURLs( const KURL::List& _urls, const KService& _service ) -{ - // Check which protocols the application supports. - // This can be a list of actual protocol names, or just KIO for KDE apps. - TQStringList supportedProtocols = _service.property("X-TDE-Protocols").toStringList(); - KRunMX1 mx1( _service ); - TQString exec = _service.exec(); - if ( mx1.expandMacrosShellQuote( exec ) && !mx1.hasUrls ) { - Q_ASSERT( supportedProtocols.isEmpty() ); // huh? If you support protocols you need %u or %U... - } else { - if ( supportedProtocols.isEmpty() ) - { - // compat mode: assume KIO if not set and it's a KDE app - TQStringList categories = _service.property("Categories").toStringList(); - if (( categories.find("TDE") != categories.end() ) && ( categories.find("KDE") != categories.end() )) - supportedProtocols.append( "KIO" ); - else { // if no KDE app, be a bit over-generic - supportedProtocols.append( "http"); - supportedProtocols.append( "ftp"); - } - } - } - kdDebug(7010) << "supportedProtocols:" << supportedProtocols << endl; - - KURL::List urls( _urls ); - if ( supportedProtocols.find( "KIO" ) == supportedProtocols.end() ) { - for( KURL::List::Iterator it = urls.begin(); it != urls.end(); ++it ) { - const KURL url = *it; - bool supported = url.isLocalFile() || supportedProtocols.find( url.protocol().lower() ) != supportedProtocols.end(); - kdDebug(7010) << "Looking at url=" << url << " supported=" << supported << endl; - if ( !supported && KProtocolInfo::protocolClass(url.protocol()) == ":local" ) - { - // Maybe we can resolve to a local URL? - KURL localURL = TDEIO::NetAccess::mostLocalURL( url, 0 ); - if ( localURL != url ) { - *it = localURL; - kdDebug(7010) << "Changed to " << localURL << endl; - } - } - } - } - return urls; -} - -// BIC merge methods below -pid_t KRun::run( const KService& _service, const KURL::List& _urls ) -{ - return run( _service, _urls, 0, false, TQString::null ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, bool tempFiles ) -{ - return run( _service, _urls, 0, tempFiles, TQString::null ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, TQWidget* window, bool tempFiles ) -{ - return run( _service, _urls, window, "", tempFiles, TQString::null ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, TQWidget* window, const TQCString& asn, bool tempFiles ) -{ - return run( _service, _urls, window, asn, tempFiles, TQString::null ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, TQWidget* window, bool tempFiles, const TQString& suggestedFileName ) -{ - return run( _service, _urls, window, "", tempFiles, suggestedFileName ); -} - -pid_t KRun::run( const KService& _service, const KURL::List& _urls, TQWidget* window, const TQCString& asn, - bool tempFiles, const TQString& suggestedFileName ) -{ - if (!_service.desktopEntryPath().isEmpty() && - !KDesktopFile::isAuthorizedDesktopFile( _service.desktopEntryPath())) - { - kdWarning() << "No authorization to execute " << _service.desktopEntryPath() << endl; - KMessageBox::sorry(window, i18n("You are not authorized to execute this service.")); - return 0; - } - - if ( !tempFiles ) - { - // Remember we opened those urls, for the "recent documents" menu in kicker - KURL::List::ConstIterator it = _urls.begin(); - for(; it != _urls.end(); ++it) { - //kdDebug(7010) << "KRecentDocument::adding " << (*it).url() << endl; - KRecentDocument::add( *it, _service.desktopEntryName() ); - } - } - - if ( tempFiles || _service.desktopEntryPath().isEmpty() || !suggestedFileName.isEmpty() ) - { - return runTempService(_service, _urls, window, asn, tempFiles, suggestedFileName); - } - - kdDebug(7010) << "KRun::run " << _service.desktopEntryPath() << endl; - - if (!_urls.isEmpty()) { - kdDebug(7010) << "First url " << _urls.first().url() << endl; - } - - // Resolve urls if needed, depending on what the app supports - const KURL::List urls = resolveURLs( _urls, _service ); - - TQString error; - int pid = 0; - - TQCString myasn = asn; - // startServiceByDesktopPath() doesn't take TQWidget*, add it to the startup info now - if( window != NULL ) - { - if( myasn.isEmpty()) - myasn = KStartupInfo::createNewStartupId(); - if( myasn != "0" ) - { - KStartupInfoId id; - id.initId( myasn ); - KStartupInfoData data; - data.setLaunchedBy( window->winId()); - KStartupInfo::sendChange( id, data ); - } - } - - int i = TDEApplication::startServiceByDesktopPath( - _service.desktopEntryPath(), urls.toStringList(), &error, 0L, &pid, myasn - ); - - if (i != 0) - { - kdDebug(7010) << error << endl; - KMessageBox::sorry( window, error ); - return 0; - } - - kdDebug(7010) << "startServiceByDesktopPath worked fine" << endl; - return (pid_t) pid; -} - - -pid_t KRun::run( const TQString& _exec, const KURL::List& _urls, const TQString& _name, - const TQString& _icon, const TQString&, const TQString&) -{ - KService::Ptr service = new KService(_name, _exec, _icon); - - return run(*service, _urls); -} - -pid_t KRun::runCommand( TQString cmd ) -{ - return KRun::runCommand( cmd, TQString::null, TQString::null, NULL, "" ); -} - -pid_t KRun::runCommand( const TQString& cmd, const TQString &execName, const TQString & iconName ) -{ - return KRun::runCommand( cmd, execName, iconName, NULL, "" ); -} - -pid_t KRun::runCommand( const TQString& cmd, const TQString &execName, const TQString & iconName, - TQWidget* window, const TQCString& asn ) -{ - kdDebug(7010) << "runCommand " << cmd << "," << execName << endl; - TDEProcess * proc = new TDEProcess; - proc->setUseShell(true); - *proc << cmd; - KService::Ptr service = KService::serviceByDesktopName( binaryName( execName, true ) ); - TQString bin = binaryName( cmd, false ); - int pos = bin.findRev( '/' ); - if (pos != -1) { - proc->setWorkingDirectory( bin.mid(0, pos) ); - } - return runCommandInternal( proc, service.data(), binaryName( execName, false ), execName, iconName, window, asn ); -} - -KRun::KRun( const KURL& url, mode_t mode, bool isLocalFile, bool showProgressInfo ) - :m_timer(0,"KRun::timer") -{ - init (url, 0, "", mode, isLocalFile, showProgressInfo); -} - -KRun::KRun( const KURL& url, TQWidget* window, mode_t mode, bool isLocalFile, - bool showProgressInfo ) - :m_timer(0,"KRun::timer") -{ - init (url, window, "", mode, isLocalFile, showProgressInfo); -} - -KRun::KRun( const KURL& url, TQWidget* window, const TQCString& asn, mode_t mode, bool isLocalFile, - bool showProgressInfo ) - :m_timer(0,"KRun::timer") -{ - init (url, window, asn, mode, isLocalFile, showProgressInfo); -} - -void KRun::init ( const KURL& url, TQWidget* window, const TQCString& asn, mode_t mode, bool isLocalFile, - bool showProgressInfo ) -{ - m_bFault = false; - m_bAutoDelete = true; - m_bProgressInfo = showProgressInfo; - m_bFinished = false; - m_job = 0L; - m_strURL = url; - m_bScanFile = false; - m_bIsDirectory = false; - m_bIsLocalFile = isLocalFile; - m_mode = mode; - d = new KRunPrivate; - d->m_runExecutables = true; - d->m_window = window; - d->m_asn = asn; - setEnableExternalBrowser(true); - - // Start the timer. This means we will return to the event - // loop and do initialization afterwards. - // Reason: We must complete the constructor before we do anything else. - m_bInit = true; - connect( &m_timer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( slotTimeout() ) ); - m_timer.start( 0, true ); - kdDebug(7010) << " new KRun " << this << " " << url.prettyURL() << " timer=" << &m_timer << endl; - - kapp->ref(); -} - -void KRun::init() -{ - kdDebug(7010) << "INIT called" << endl; - - bool bypassErrorMessage = false; - - if (m_strURL.url().startsWith("$(")) { - // check for environment variables and make necessary translations - TQString aValue = m_strURL.url(); - int nDollarPos = aValue.find( '$' ); - - while( nDollarPos != -1 && nDollarPos+1 < static_cast<int>(aValue.length())) { - // there is at least one $ - if( (aValue)[nDollarPos+1] == '(' ) { - uint nEndPos = nDollarPos+1; - // the next character is no $ - while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!=')') ) - nEndPos++; - nEndPos++; - TQString cmd = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); - - TQString result; - FILE *fs = popen(TQFile::encodeName(cmd).data(), "r"); - if (fs) - { - { - TQTextStream ts(fs, IO_ReadOnly); - result = ts.read().stripWhiteSpace(); - } - pclose(fs); - } - aValue.replace( nDollarPos, nEndPos-nDollarPos, result ); - } else if( (aValue)[nDollarPos+1] != '$' ) { - uint nEndPos = nDollarPos+1; - // the next character is no $ - TQString aVarName; - if (aValue[nEndPos]=='{') - { - while ( (nEndPos <= aValue.length()) && (aValue[nEndPos]!='}') ) - nEndPos++; - nEndPos++; - aVarName = aValue.mid( nDollarPos+2, nEndPos-nDollarPos-3 ); - } - else - { - while ( nEndPos <= aValue.length() && (aValue[nEndPos].isNumber() - || aValue[nEndPos].isLetter() || aValue[nEndPos]=='_' ) ) - nEndPos++; - aVarName = aValue.mid( nDollarPos+1, nEndPos-nDollarPos-1 ); - } - const char* pEnv = 0; - if (!aVarName.isEmpty()) - pEnv = getenv( aVarName.ascii() ); - if( pEnv ) { - // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!! - // A environment variables may contain values in 8bit - // locale cpecified encoding or in UTF8 encoding. - aValue.replace( nDollarPos, nEndPos-nDollarPos, KStringHandler::from8Bit( pEnv ) ); - } else - aValue.remove( nDollarPos, nEndPos-nDollarPos ); - } else { - // remove one of the dollar signs - aValue.remove( nDollarPos, 1 ); - nDollarPos++; - } - nDollarPos = aValue.find( '$', nDollarPos ); - } - m_strURL = KURL(aValue); - bypassErrorMessage = true; - } - - if ( !m_strURL.isValid() ) - { - if (bypassErrorMessage == false) { - d->m_showingError = true; - KMessageBoxWrapper::error( d->m_window, i18n( "Malformed URL\n%1" ).arg( m_strURL.url() ) ); - d->m_showingError = false; - } - m_bFault = true; - m_bFinished = true; - m_timer.start( 0, true ); - return; - } - if ( !kapp->authorizeURLAction( "open", KURL(), m_strURL)) - { - TQString msg = TDEIO::buildErrorString(TDEIO::ERR_ACCESS_DENIED, m_strURL.prettyURL()); - d->m_showingError = true; - KMessageBoxWrapper::error( d->m_window, msg ); - d->m_showingError = false; - m_bFault = true; - m_bFinished = true; - m_timer.start( 0, true ); - return; - } - - if ( !m_bIsLocalFile && m_strURL.isLocalFile() ) - m_bIsLocalFile = true; - - TQString exec; - if (m_strURL.protocol().startsWith("http")) - { - exec = d->m_externalBrowser; - } - - if ( m_bIsLocalFile ) - { - if ( m_mode == 0 ) - { - KDE_struct_stat buff; - if ( KDE_stat( TQFile::encodeName(m_strURL.path()), &buff ) == -1 ) - { - d->m_showingError = true; - KMessageBoxWrapper::error( d->m_window, i18n( "<qt>Unable to run the command specified. The file or folder <b>%1</b> does not exist.</qt>" ).arg( m_strURL.htmlURL() ) ); - d->m_showingError = false; - m_bFault = true; - m_bFinished = true; - m_timer.start( 0, true ); - return; - } - m_mode = buff.st_mode; - } - - KMimeType::Ptr mime = KMimeType::findByURL( m_strURL, m_mode, m_bIsLocalFile ); - assert( mime != 0L ); - kdDebug(7010) << "MIME TYPE is " << mime->name() << endl; - foundMimeType( mime->name() ); - return; - } - else if ( !exec.isEmpty() || KProtocolInfo::isHelperProtocol( m_strURL ) ) { - kdDebug(7010) << "Helper protocol" << endl; - - bool ok = false; - KURL::List urls; - if (!((m_strURL.protocol().startsWith("http")) && (m_strURL.url() == "http://default.browser"))) - urls.append( m_strURL ); - if (exec.isEmpty()) - { - exec = KProtocolInfo::exec( m_strURL.protocol() ); - if (exec.isEmpty()) - { - foundMimeType(KProtocolInfo::defaultMimetype(m_strURL)); - return; - } - run( exec, urls ); - ok = true; - } - else if (exec.startsWith("!")) - { - exec = exec.mid(1); // Literal command - exec += " %u"; - run( exec, urls ); - ok = true; - } - else - { - KService::Ptr service = KService::serviceByStorageId( exec ); - if (service) - { - run( *service, urls, d->m_window, d->m_asn ); - ok = true; - } - } - - if (ok) - { - m_bFinished = true; - // will emit the error and autodelete this - m_timer.start( 0, true ); - return; - } - } - - if ((m_strURL.protocol().startsWith("http")) && (m_strURL.url() == "http://default.browser")) { - KURL::List urls; - run( "kfmclient openProfile webbrowsing", urls ); - m_bFinished = true; - // will emit the error and autodelete this - m_timer.start( 0, true ); - return; - } - - // Did we already get the information that it is a directory ? - if ( S_ISDIR( m_mode ) ) - { - foundMimeType( "inode/directory" ); - return; - } - - // Let's see whether it is a directory - - if ( !KProtocolInfo::supportsListing( m_strURL ) ) - { - //kdDebug(7010) << "Protocol has no support for listing" << endl; - // No support for listing => it can't be a directory (example: http) - scanFile(); - return; - } - - kdDebug(7010) << "Testing directory (stating)" << endl; - - // It may be a directory or a file, let's stat - TDEIO::StatJob *job = TDEIO::stat( m_strURL, true, 0 /* no details */, m_bProgressInfo ); - job->setWindow (d->m_window); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - this, TQT_SLOT( slotStatResult( TDEIO::Job * ) ) ); - m_job = job; - kdDebug(7010) << " Job " << job << " is about stating " << m_strURL.url() << endl; -} - -KRun::~KRun() -{ - kdDebug(7010) << "KRun::~KRun() " << this << endl; - m_timer.stop(); - killJob(); - kapp->deref(); - kdDebug(7010) << "KRun::~KRun() done " << this << endl; - delete d; -} - -void KRun::scanFile() -{ - kdDebug(7010) << "###### KRun::scanFile " << m_strURL.url() << endl; - // First, let's check for well-known extensions - // Not when there is a query in the URL, in any case. - if ( m_strURL.query().isEmpty() ) - { - KMimeType::Ptr mime = KMimeType::findByURL( m_strURL ); - assert( mime != 0L ); - if ( mime->name() != "application/octet-stream" || m_bIsLocalFile ) - { - kdDebug(7010) << "Scanfile: MIME TYPE is " << mime->name() << endl; - foundMimeType( mime->name() ); - return; - } - } - - // No mimetype found, and the URL is not local (or fast mode not allowed). - // We need to apply the 'KIO' method, i.e. either asking the server or - // getting some data out of the file, to know what mimetype it is. - - if ( !KProtocolInfo::supportsReading( m_strURL ) ) - { - kdError(7010) << "#### NO SUPPORT FOR READING!" << endl; - m_bFault = true; - m_bFinished = true; - m_timer.start( 0, true ); - return; - } - kdDebug(7010) << this << " Scanning file " << m_strURL.url() << endl; - - TDEIO::TransferJob *job = TDEIO::get( m_strURL, false /*reload*/, m_bProgressInfo ); - job->setWindow (d->m_window); - connect(job, TQT_SIGNAL( result(TDEIO::Job *)), - this, TQT_SLOT( slotScanFinished(TDEIO::Job *))); - connect(job, TQT_SIGNAL( mimetype(TDEIO::Job *, const TQString &)), - this, TQT_SLOT( slotScanMimeType(TDEIO::Job *, const TQString &))); - m_job = job; - kdDebug(7010) << " Job " << job << " is about getting from " << m_strURL.url() << endl; -} - -void KRun::slotTimeout() -{ - kdDebug(7010) << this << " slotTimeout called" << endl; - if ( m_bInit ) - { - m_bInit = false; - init(); - return; - } - - if ( m_bFault ) { - emit error(); - } - if ( m_bFinished ) { - emit finished(); - } - else - { - if ( m_bScanFile ) - { - m_bScanFile = false; - scanFile(); - return; - } - else if ( m_bIsDirectory ) - { - m_bIsDirectory = false; - foundMimeType( "inode/directory" ); - return; - } - } - - if ( m_bAutoDelete ) - { - delete this; - return; - } -} - -void KRun::slotStatResult( TDEIO::Job * job ) -{ - m_job = 0L; - if (job->error()) - { - d->m_showingError = true; - kdError(7010) << this << " ERROR " << job->error() << " " << job->errorString() << endl; - job->showErrorDialog(); - //kdDebug(7010) << this << " KRun returning from showErrorDialog, starting timer to delete us" << endl; - d->m_showingError = false; - - m_bFault = true; - m_bFinished = true; - - // will emit the error and autodelete this - m_timer.start( 0, true ); - - } else { - - kdDebug(7010) << "Finished" << endl; - if(!dynamic_cast<TDEIO::StatJob*>(job)) - kdFatal() << "job is a " << typeid(*job).name() << " should be a StatJob" << endl; - - TQString knownMimeType; - TDEIO::UDSEntry entry = ((TDEIO::StatJob*)job)->statResult(); - TDEIO::UDSEntry::ConstIterator it = entry.begin(); - for( ; it != entry.end(); it++ ) { - switch( (*it).m_uds ) { - case TDEIO::UDS_FILE_TYPE: - if ( S_ISDIR( (mode_t)((*it).m_long) ) ) - m_bIsDirectory = true; // it's a dir - else - m_bScanFile = true; // it's a file - break; - case TDEIO::UDS_MIME_TYPE: // mimetype already known? (e.g. print:/manager) - knownMimeType = (*it).m_str; - break; - case TDEIO::UDS_LOCAL_PATH: - d->m_localPath = (*it).m_str; - break; - default: - break; - } - } - if ( !knownMimeType.isEmpty() ) - { - foundMimeType( knownMimeType ); - m_bFinished = true; - } - - // We should have found something - assert ( m_bScanFile || m_bIsDirectory ); - - // Start the timer. Once we get the timer event this - // protocol server is back in the pool and we can reuse it. - // This gives better performance than starting a new slave - m_timer.start( 0, true ); - } -} - -void KRun::slotScanMimeType( TDEIO::Job *, const TQString &mimetype ) -{ - if ( mimetype.isEmpty() ) - kdWarning(7010) << "KRun::slotScanFinished : MimetypeJob didn't find a mimetype! Probably a kioslave bug." << endl; - foundMimeType( mimetype ); - m_job = 0; -} - -void KRun::slotScanFinished( TDEIO::Job *job ) -{ - m_job = 0; - if (job->error()) - { - d->m_showingError = true; - kdError(7010) << this << " ERROR (stat) : " << job->error() << " " << job->errorString() << endl; - job->showErrorDialog(); - //kdDebug(7010) << this << " KRun returning from showErrorDialog, starting timer to delete us" << endl; - d->m_showingError = false; - - m_bFault = true; - m_bFinished = true; - - // will emit the error and autodelete this - m_timer.start( 0, true ); - } -} - -void KRun::foundMimeType( const TQString& type ) -{ - kdDebug(7010) << "Resulting mime type is " << type << endl; - -/* - // Automatically unzip stuff - - // Disabled since the new KIO doesn't have filters yet. - - if ( type == "application/x-gzip" || - type == "application/x-bzip" || - type == "application/x-bzip2" ) - { - KURL::List lst = KURL::split( m_strURL ); - if ( lst.isEmpty() ) - { - TQString tmp = i18n( "Malformed URL" ); - tmp += "\n"; - tmp += m_strURL.url(); - KMessageBoxWrapper::error( 0L, tmp ); - return; - } - - if ( type == "application/x-gzip" ) - lst.prepend( KURL( "gzip:/decompress" ) ); - else if ( type == "application/x-bzip" ) - lst.prepend( KURL( "bzip:/decompress" ) ); - else if ( type == "application/x-bzip2" ) - lst.prepend( KURL( "bzip2:/decompress" ) ); - else if ( type == "application/x-tar" ) - lst.prepend( KURL( "tar:/" ) ); - - // Move the HTML style reference to the leftmost URL - KURL::List::Iterator it = lst.begin(); - ++it; - (*lst.begin()).setRef( (*it).ref() ); - (*it).setRef( TQString::null ); - - // Create the new URL - m_strURL = KURL::join( lst ); - - kdDebug(7010) << "Now trying with " << debugString(m_strURL.url()) << endl; - - killJob(); - - // We don't know if this is a file or a directory. Let's test this first. - // (For instance a tar.gz is a directory contained inside a file) - // It may be a directory or a file, let's stat - TDEIO::StatJob *job = TDEIO::stat( m_strURL, m_bProgressInfo ); - connect( job, TQT_SIGNAL( result( TDEIO::Job * ) ), - this, TQT_SLOT( slotStatResult( TDEIO::Job * ) ) ); - m_job = job; - - return; - } -*/ - TDEIO::TransferJob *job = ::tqqt_cast<TDEIO::TransferJob *>( m_job ); - if ( job ) - { - job->putOnHold(); - TDEIO::Scheduler::publishSlaveOnHold(); - m_job = 0; - } - - Q_ASSERT( !m_bFinished ); - - // Suport for preferred service setting, see setPreferredService - if ( !d->m_preferredService.isEmpty() ) { - kdDebug(7010) << "Attempting to open with preferred service: " << d->m_preferredService << endl; - KService::Ptr serv = KService::serviceByDesktopName( d->m_preferredService ); - if ( serv && serv->hasServiceType( type ) ) - { - KURL::List lst; - lst.append( m_strURL ); - m_bFinished = KRun::run( *serv, lst, d->m_window, d->m_asn ); - /// Note: the line above means that if that service failed, we'll - /// go to runURL to maybe find another service, even though a dialog - /// box was displayed. That's good if runURL tries another service, - /// but it's not good if it tries the same one :} - } - } - - // Resolve .desktop files from media:/, remote:/, applications:/ etc. - if ( ((type == "application/x-desktop") || - (type == "media/builtin-mydocuments") || - (type == "media/builtin-mycomputer") || - (type == "media/builtin-mynetworkplaces") || - (type == "media/builtin-printers") || - (type == "media/builtin-trash") || - (type == "media/builtin-webbrowser")) /* or inheriting? */ && (!d->m_localPath.isEmpty()) ) - { - m_strURL = KURL(); - m_strURL.setPath( d->m_localPath ); - } - - if (!m_bFinished && KRun::runURL( m_strURL, type, d->m_window, d->m_asn, false, d->m_runExecutables, d->m_suggestedFileName )){ - m_bFinished = true; - } - else{ - m_bFinished = true; - m_bFault = true; - } - - m_timer.start( 0, true ); -} - -void KRun::killJob() -{ - if ( m_job ) - { - kdDebug(7010) << "KRun::killJob run=" << this << " m_job=" << m_job << endl; - m_job->kill(); - m_job = 0L; - } -} - -void KRun::abort() -{ - kdDebug(7010) << "KRun::abort " << this << " m_showingError=" << d->m_showingError << endl; - killJob(); - // If we're showing an error message box, the rest will be done - // after closing the msgbox -> don't autodelete nor emit signals now. - if ( d->m_showingError ) - return; - m_bFault = true; - m_bFinished = true; - m_bInit = false; - m_bScanFile = false; - - // will emit the error and autodelete this - m_timer.start( 0, true ); -} - -void KRun::setEnableExternalBrowser(bool b) -{ - if (b) - d->m_externalBrowser = TDEConfigGroup(TDEGlobal::config(), "General").readEntry("BrowserApplication"); - else - d->m_externalBrowser = TQString::null; -} - -void KRun::setPreferredService( const TQString& desktopEntryName ) -{ - d->m_preferredService = desktopEntryName; -} - -void KRun::setRunExecutables(bool b) -{ - d->m_runExecutables = b; -} - -void KRun::setSuggestedFileName( const TQString& fileName ) -{ - d->m_suggestedFileName = fileName; -} - -bool KRun::isExecutable( const TQString& serviceType ) -{ - return ( serviceType == "application/x-desktop" || - serviceType == "media/builtin-mydocuments" || - serviceType == "media/builtin-mycomputer" || - serviceType == "media/builtin-mynetworkplaces" || - serviceType == "media/builtin-printers" || - serviceType == "media/builtin-trash" || - serviceType == "media/builtin-webbrowser" || - serviceType == "application/x-executable" || - serviceType == "application/x-msdos-program" || - serviceType == "application/x-shellscript" ); -} - -/****************/ - -pid_t -TDEProcessRunner::run(TDEProcess * p, const TQString & binName) -{ - return (new TDEProcessRunner(p, binName))->pid(); -} - -#ifdef Q_WS_X11 -pid_t -TDEProcessRunner::run(TDEProcess * p, const TQString & binName, const KStartupInfoId& id ) -{ - return (new TDEProcessRunner(p, binName, id))->pid(); -} -#endif - -TDEProcessRunner::TDEProcessRunner(TDEProcess * p, const TQString & _binName ) - : TQObject(), - process_(p), - binName( _binName ) -{ - TQObject::connect( - process_, TQT_SIGNAL(processExited(TDEProcess *)), - this, TQT_SLOT(slotProcessExited(TDEProcess *))); - - process_->start(); - if ( !process_->pid() ) - slotProcessExited( process_ ); -} - -#ifdef Q_WS_X11 -TDEProcessRunner::TDEProcessRunner(TDEProcess * p, const TQString & _binName, const KStartupInfoId& id ) - : TQObject(), - process_(p), - binName( _binName ), - id_( id ) -{ - TQObject::connect( - process_, TQT_SIGNAL(processExited(TDEProcess *)), - this, TQT_SLOT(slotProcessExited(TDEProcess *))); - - process_->start(); - if ( !process_->pid() ) - slotProcessExited( process_ ); -} -#endif - -TDEProcessRunner::~TDEProcessRunner() -{ - delete process_; -} - - pid_t -TDEProcessRunner::pid() const -{ - return process_->pid(); -} - - void -TDEProcessRunner::slotProcessExited(TDEProcess * p) -{ - if (p != process_) - return; // Eh ? - - kdDebug(7010) << "slotProcessExited " << binName << endl; - kdDebug(7010) << "normalExit " << process_->normalExit() << endl; - kdDebug(7010) << "exitStatus " << process_->exitStatus() << endl; - bool showErr = process_->normalExit() - && ( process_->exitStatus() == 127 || process_->exitStatus() == 1 ); - if ( !binName.isEmpty() && ( showErr || process_->pid() == 0 ) ) - { - // Often we get 1 (zsh, csh) or 127 (ksh, bash) because the binary doesn't exist. - // We can't just rely on that, but it's a good hint. - // Before assuming its really so, we'll try to find the binName - // relatively to current directory, and then in the PATH. - if ( !TQFile( binName ).exists() && KStandardDirs::findExe( binName ).isEmpty() ) - { - kapp->ref(); - KMessageBox::sorry( 0L, i18n("Could not find the program '%1'").arg( binName ) ); - kapp->deref(); - } - } -#ifdef Q_WS_X11 - if( !id_.none()) - { - KStartupInfoData data; - data.addPid( pid()); // announce this pid for the startup notification has finished - data.setHostname(); - KStartupInfo::sendFinish( id_, data ); - } -#endif - deleteLater(); -} - -void KRun::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -#include "krun.moc" |