int main(int argc, char *argv[]) { // FIXME: this can be considered a poor man's solution, as it's not // directly obvious to a gui user. :) // anyway, i vote against removing it even when we have a proper gui // implementation. -- ossi const char *duser = ::getenv("ADMIN_ACCOUNT"); if (duser && duser[0]) options[3].def = duser; KAboutData aboutData("kdesu", I18N_NOOP("KDE su"), Version, I18N_NOOP("Runs a program with elevated privileges."), KAboutData::License_Artistic, "Copyright (c) 1998-2000 Geert Jansen, Pietro Iglio"); aboutData.addAuthor("Geert Jansen", I18N_NOOP("Maintainer"), "*****@*****.**", "http://www.stack.nl/~geertj/"); aboutData.addAuthor("Pietro Iglio", I18N_NOOP("Original author"), "*****@*****.**"); KCmdLineArgs::init(argc, argv, &aboutData); KCmdLineArgs::addCmdLineOptions(options); KApplication::disableAutoDcopRegistration(); // kdesu doesn't process SM events, so don't even connect to ksmserver QCString session_manager = getenv( "SESSION_MANAGER" ); unsetenv( "SESSION_MANAGER" ); KApplication app; // but propagate it to the started app if (session_manager.data()) { setenv( "SESSION_MANAGER", session_manager.data(), 1 ); } { KStartupInfoId id; id.initId( kapp->startupId()); id.setupStartupEnv(); // make DESKTOP_STARTUP_ID env. var. available again } int result = startApp(); if (result == 127) { KMessageBox::sorry(0, i18n("Command '%1' not found.").arg(command)); } return result; }
bool PimUniqueApplication::start( KUniqueApplication::StartFlags flags ) { const QString appName = KCmdLineArgs::aboutData()->appName(); // Try talking to /appName_PimApplication in org.kde.appName, // (which could be kontact or the standalone application), // otherwise fall back to standard KUniqueApplication behavior (start appName). const QString serviceName = "org.kde." + appName; if ( tryToInitDBusConnection().interface()->isServiceRegistered( serviceName ) ) { QByteArray saved_args; QDataStream ds( &saved_args, QIODevice::WriteOnly ); KCmdLineArgs::saveAppArgs( ds ); QByteArray new_asn_id; #if defined Q_WS_X11 KStartupInfoId id; if ( kapp ) { // KApplication constructor unsets the env. variable id.initId( kapp->startupId() ); } else { id = KStartupInfo::currentStartupIdEnv(); } if ( !id.none() ) { new_asn_id = id.id(); } #endif KWindowSystem::allowExternalProcessWindowActivation(); const QString objectName = QString( '/' ) + appName + "_PimApplication"; //kDebug() << objectName; QDBusInterface iface( serviceName, objectName, "org.kde.KUniqueApplication", QDBusConnection::sessionBus() ); QDBusReply<int> reply; if ( iface.isValid() && ( reply = iface.call( "newInstance", new_asn_id, saved_args ) ).isValid() ) { return false; // success means that main() can exit now. } } QDBusConnection::disconnectFromBus( _k_sessionBusName ); //kDebug() << "kontact not running -- start standalone application"; // kontact not running -- start standalone application. return KUniqueApplication::start( flags ); }
void KIOExec::slotRunApp() { if ( fileList.isEmpty() ) { qDebug() << "No files downloaded -> exiting"; mExited = true; QApplication::exit(1); return; } KService service(QStringLiteral("dummy"), command, QString()); QList<QUrl> list; // Store modification times QList<FileInfo>::Iterator it = fileList.begin(); for ( ; it != fileList.end() ; ++it ) { QFileInfo info(QFile::encodeName(it->path)); it->time = info.lastModified(); QUrl url = QUrl::fromLocalFile(it->path); list << url; } KIO::DesktopExecParser execParser(service, list); QStringList params = execParser.resultingArguments(); qDebug() << "EXEC " << params.join(QStringLiteral(" ")); #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) // propagate the startup identification to the started process KStartupInfoId id; QByteArray startupId; #if HAVE_X11 if (QX11Info::isPlatformX11()) { startupId = QX11Info::nextStartupId(); } #endif id.initId(startupId); id.setupStartupEnv(); #endif QString exe( params.takeFirst() ); const int exit_code = QProcess::execute( exe, params ); #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) KStartupInfo::resetStartupEnv(); #endif qDebug() << "EXEC done"; // Test whether one of the files changed for(it = fileList.begin(); it != fileList.end(); ++it ) { QString src = it->path; const QUrl dest = it->url; QFileInfo info(src); if ( info.exists() && (it->time != info.lastModified()) ) { if ( mTempFiles ) { if ( KMessageBox::questionYesNo( 0L, i18n( "The supposedly temporary file\n%1\nhas been modified.\nDo you still want to delete it?", dest.toDisplayString(QUrl::PreferLocalFile)), i18n( "File Changed" ), KStandardGuiItem::del(), KGuiItem(i18n("Do Not Delete")) ) != KMessageBox::Yes ) continue; // don't delete the temp file } else if ( ! dest.isLocalFile() ) // no upload when it's already a local file { if ( KMessageBox::questionYesNo( 0L, i18n( "The file\n%1\nhas been modified.\nDo you want to upload the changes?" , dest.toDisplayString()), i18n( "File Changed" ), KGuiItem(i18n("Upload")), KGuiItem(i18n("Do Not Upload")) ) == KMessageBox::Yes ) { qDebug() << "src='" << src << "' dest='" << dest << "'"; // Do it the synchronous way. KIO::CopyJob* job = KIO::copy(QUrl::fromLocalFile(src), dest); if ( !job->exec() ) { KMessageBox::error( 0L, job->errorText() ); continue; // don't delete the temp file } } } } if ((!dest.isLocalFile() || mTempFiles) && exit_code == 0) { // Wait for a reasonable time so that even if the application forks on startup (like OOo or amarok) // it will have time to start up and read the file before it gets deleted. #130709. qDebug() << "sleeping..."; QThread::currentThread()->sleep(180); // 3 mn qDebug() << "about to delete " << src; QFile( QFile::encodeName(src) ).remove(); } } mExited = true; QApplication::exit(exit_code); }
static int startApp() { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); // Stop daemon and exit? if (args->isSet("s")) { KDEsuClient client; if (client.ping() == -1) { kdError(1206) << "Daemon not running -- nothing to stop\n"; exit(1); } if (client.stopServer() != -1) { kdDebug(1206) << "Daemon stopped\n"; exit(0); } kdError(1206) << "Could not stop daemon\n"; exit(1); } QString icon; if ( args->isSet("i")) icon = args->getOption("i"); bool prompt = true; if ( args->isSet("d")) prompt = false; // Get target uid QCString user = args->getOption("u"); QCString auth_user = user; struct passwd *pw = getpwnam(user); if (pw == 0L) { kdError(1206) << "User " << user << " does not exist\n"; exit(1); } bool change_uid = (getuid() != pw->pw_uid); // If file is writeable, do not change uid QString file = QFile::decodeName(args->getOption("f")); if (change_uid && !file.isEmpty()) { if (file.at(0) != '/') { KStandardDirs dirs; dirs.addKDEDefaults(); file = dirs.findResource("config", file); if (file.isEmpty()) { kdError(1206) << "Config file not found: " << file << "\n"; exit(1); } } QFileInfo fi(file); if (!fi.exists()) { kdError(1206) << "File does not exist: " << file << "\n"; exit(1); } change_uid = !fi.isWritable(); } // Get priority/scheduler QCString tmp = args->getOption("p"); bool ok; int priority = tmp.toInt(&ok); if (!ok || (priority < 0) || (priority > 100)) { KCmdLineArgs::usage(i18n("Illegal priority: %1").arg(tmp)); exit(1); } int scheduler = SuProcess::SchedNormal; if (args->isSet("r")) scheduler = SuProcess::SchedRealtime; if ((priority > 50) || (scheduler != SuProcess::SchedNormal)) { change_uid = true; auth_user = "******"; } // Get command if (args->isSet("c")) { command = args->getOption("c"); for (int i=0; i<args->count(); i++) { QString arg = QFile::decodeName(args->arg(i)); KRun::shellQuote(arg); command += " "; command += QFile::encodeName(arg); } } else { if( args->count() == 0 ) { KCmdLineArgs::usage(i18n("No command specified.")); exit(1); } command = args->arg(0); for (int i=1; i<args->count(); i++) { QString arg = QFile::decodeName(args->arg(i)); KRun::shellQuote(arg); command += " "; command += QFile::encodeName(arg); } } // Don't change uid if we're don't need to. if (!change_uid) { int result = system(command); result = WEXITSTATUS(result); return result; } // Check for daemon and start if necessary bool just_started = false; bool have_daemon = true; KDEsuClient client; if (!client.isServerSGID()) { kdWarning(1206) << "Daemon not safe (not sgid), not using it.\n"; have_daemon = false; } else if (client.ping() == -1) { if (client.startServer() == -1) { kdWarning(1206) << "Could not start daemon, reduced functionality.\n"; have_daemon = false; } just_started = true; } // Try to exec the command with kdesud. bool keep = !args->isSet("n") && have_daemon; bool terminal = args->isSet("t"); bool new_dcop = args->isSet("newdcop"); bool withIgnoreButton = args->isSet("ignorebutton"); QCStringList env; QCString options; env << ( "DESKTOP_STARTUP_ID=" + kapp->startupId()); if (pw->pw_uid) { // Only propagate KDEHOME for non-root users, // root uses KDEROOTHOME // Translate the KDEHOME of this user to the new user. QString kdeHome = KGlobal::dirs()->relativeLocation("home", KGlobal::dirs()->localkdedir()); if (kdeHome[0] != '/') kdeHome.prepend("~/"); else kdeHome=QString::null; // Use default env << ("KDEHOME="+ QFile::encodeName(kdeHome)); } KUser u; env << (QCString) ("KDESU_USER="******"KDESYCOCA="+QFile::encodeName(locateLocal("cache", "ksycoca")); env << ksycoca; options += "xf"; // X-only, dcop forwarding enabled. } if (keep && !terminal && !just_started) { client.setPriority(priority); client.setScheduler(scheduler); int result = client.exec(command, user, options, env); if (result == 0) { result = client.exitCode(); return result; } } // Set core dump size to 0 because we will have // root's password in memory. struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = 0; if (setrlimit(RLIMIT_CORE, &rlim)) { kdError(1206) << "rlimit(): " << ERR << "\n"; exit(1); } // Read configuration KConfig *config = KGlobal::config(); config->setGroup("Passwords"); int timeout = config->readNumEntry("Timeout", defTimeout); // Check if we need a password SuProcess proc; proc.setUser(auth_user); int needpw = proc.checkNeedPassword(); if (needpw < 0) { QString err = i18n("Su returned with an error.\n"); KMessageBox::error(0L, err); exit(1); } if (needpw == 0) { keep = 0; kdDebug() << "Don't need password!!\n"; } // Start the dialog QCString password; if (needpw) { KStartupInfoId id; id.initId( kapp->startupId()); KStartupInfoData data; data.setSilent( KStartupInfoData::Yes ); KStartupInfo::sendChange( id, data ); KDEsuDialog dlg(user, auth_user, keep && !terminal,icon, withIgnoreButton); if (prompt) dlg.addLine(i18n("Command:"), command); if ((priority != 50) || (scheduler != SuProcess::SchedNormal)) { QString prio; if (scheduler == SuProcess::SchedRealtime) prio += i18n("realtime: "); prio += QString("%1/100").arg(priority); if (prompt) dlg.addLine(i18n("Priority:"), prio); } int ret = dlg.exec(); if (ret == KDEsuDialog::Rejected) { KStartupInfo::sendFinish( id ); exit(0); } if (ret == KDEsuDialog::AsUser) change_uid = false; password = dlg.password(); keep = dlg.keep(); data.setSilent( KStartupInfoData::No ); KStartupInfo::sendChange( id, data ); } // Some events may need to be handled (like a button animation) kapp->processEvents(); // Run command if (!change_uid) { int result = system(command); result = WEXITSTATUS(result); return result; } else if (keep && have_daemon) { client.setPass(password, timeout); client.setPriority(priority); client.setScheduler(scheduler); int result = client.exec(command, user, options, env); if (result == 0) { result = client.exitCode(); return result; } } else { SuProcess proc; proc.setTerminal(terminal); proc.setErase(true); proc.setUser(user); if (!new_dcop) { proc.setXOnly(true); proc.setDCOPForwarding(true); } proc.setEnvironment(env); proc.setPriority(priority); proc.setScheduler(scheduler); proc.setCommand(command); int result = proc.exec(password); return result; } return -1; }
void KrashConfig :: readConfig() { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); m_signalnum = args->getOption( "signal" ).toInt(); m_pid = args->getOption( "pid" ).toInt(); m_startedByKdeinit = args->isSet("kdeinit"); m_safeMode = args->isSet("safer"); m_execname = args->getOption( "appname" ); if ( !args->getOption( "apppath" ).isEmpty() ) m_execname.prepend( args->getOption( "apppath" ) + '/' ); QCString programname = args->getOption("programname"); if (programname.isEmpty()) programname.setStr(I18N_NOOP("unknown")); // leak some memory... Well. It's only done once anyway :-) const char * progname = qstrdup(programname); m_aboutData = new KAboutData(args->getOption("appname"), progname, args->getOption("appversion"), 0, 0, 0, 0, 0, args->getOption("bugaddress")); QCString startup_id( args->getOption( "startupid" )); if (!startup_id.isEmpty()) { // stop startup notification KStartupInfoId id; id.initId( startup_id ); KStartupInfo::sendFinish( id ); } KConfig *config = KGlobal::config(); config->setGroup("drkonqi"); // maybe we should check if it's relative? QString configname = config->readEntry("ConfigName", QString::fromLatin1("enduser")); QString debuggername = config->readEntry("Debugger", QString::fromLatin1("gdb")); KConfig debuggers(QString::fromLatin1("debuggers/%1rc").arg(debuggername), true, false, "appdata"); debuggers.setGroup("General"); m_debugger = debuggers.readPathEntry("Exec"); m_debuggerBatch = debuggers.readPathEntry("ExecBatch"); m_tryExec = debuggers.readPathEntry("TryExec"); m_backtraceCommand = debuggers.readEntry("BacktraceCommand"); m_removeFromBacktraceRegExp = debuggers.readEntry("RemoveFromBacktraceRegExp"); m_invalidStackFrameRegExp = debuggers.readEntry("InvalidStackFrameRegExp"); m_frameRegExp = debuggers.readEntry("FrameRegExp"); m_neededInValidBacktraceRegExp = debuggers.readEntry("NeededInValidBacktraceRegExp"); m_kcrashRegExp = debuggers.readEntry("KCrashRegExp"); KConfig preset(QString::fromLatin1("presets/%1rc").arg(configname), true, false, "appdata"); preset.setGroup("ErrorDescription"); if (preset.readBoolEntry("Enable"), true) m_errorDescriptionText = preset.readEntry("Name"); preset.setGroup("WhatToDoHint"); if (preset.readBoolEntry("Enable")) m_whatToDoText = preset.readEntry("Name"); preset.setGroup("General"); m_showbugreport = preset.readBoolEntry("ShowBugReportButton", false); m_showdebugger = m_showbacktrace = m_pid != 0; if (m_showbacktrace) { m_showbacktrace = preset.readBoolEntry("ShowBacktraceButton", true); m_showdebugger = preset.readBoolEntry("ShowDebugButton", true); } m_disablechecks = preset.readBoolEntry("DisableChecks", false); bool b = preset.readBoolEntry("SignalDetails", true); QString str = QString::number(m_signalnum); // use group unknown if signal not found if (!preset.hasGroup(str)) str = QString::fromLatin1("unknown"); preset.setGroup(str); m_signalName = preset.readEntry("Name"); if (b) m_signalText = preset.readEntry("Comment"); }
int main(int argc, char *argv[]) { // FIXME: this can be considered a poor man's solution, as it's not // directly obvious to a gui user. :) // anyway, i vote against removing it even when we have a proper gui // implementation. -- ossi QByteArray duser = qgetenv("ADMIN_ACCOUNT"); if (duser.isEmpty()) duser = "******"; KAboutData aboutData("kdesu", 0, ki18n("KDE su"), Version, ki18n("Runs a program with elevated privileges."), KAboutData::License_Artistic, ki18n("Copyright (c) 1998-2000 Geert Jansen, Pietro Iglio")); aboutData.addAuthor(ki18n("Geert Jansen"), ki18n("Maintainer"), "*****@*****.**", "http://www.stack.nl/~geertj/"); aboutData.addAuthor(ki18n("Pietro Iglio"), ki18n("Original author"), "*****@*****.**"); aboutData.setProgramIconName("dialog-password"); KCmdLineArgs::init(argc, argv, &aboutData); // NOTE: if you change the position of the -u switch, be sure to adjust it // at the beginning of main() KCmdLineOptions options; options.add("!+command", ki18n("Specifies the command to run as separate arguments")); options.add("c <command>", ki18n("Specifies the command to run as one string")); options.add("f <file>", ki18n("Run command under target uid if <file> is not writable")); options.add("u <user>", ki18n("Specifies the target uid"), duser); options.add("n", ki18n("Do not keep password")); options.add("s", ki18n("Stop the daemon (forgets all passwords)")); options.add("t", ki18n("Enable terminal output (no password keeping)")); options.add("p <prio>", ki18n("Set priority value: 0 <= prio <= 100, 0 is lowest"), "50"); options.add("r", ki18n("Use realtime scheduling")); options.add("noignorebutton", ki18n("Do not display ignore button")); options.add("i <icon name>", ki18n("Specify icon to use in the password dialog")); options.add("d", ki18n("Do not show the command to be run in the dialog")); #ifdef Q_WS_X11 /* KDialog originally used --embed for attaching the dialog box. However this is misleading and so we changed to --attach. * For consistancy, we silently map --embed to --attach */ options.add("attach <winid>", ki18nc("Transient means that the kdesu app will be attached to the app specified by the winid so that it is like a dialog box rather than some separate program", "Makes the dialog transient for an X app specified by winid")); options.add("embed <winid>"); #endif KCmdLineArgs::addCmdLineOptions(options); //KApplication::disableAutoDcopRegistration(); // kdesu doesn't process SM events, so don't even connect to ksmserver QByteArray session_manager = qgetenv( "SESSION_MANAGER" ); if (!session_manager.isEmpty()) unsetenv( "SESSION_MANAGER" ); KApplication app; // but propagate it to the started app if (!session_manager.isEmpty()) setenv( "SESSION_MANAGER", session_manager.data(), 1 ); { #ifdef Q_WS_X11 KStartupInfoId id; id.initId( kapp->startupId()); id.setupStartupEnv(); // make DESKTOP_STARTUP_ID env. var. available again #endif } int result = startApp(); if (result == 127) { KMessageBox::sorry(0, i18n("Cannot execute command '%1'.", QString::fromLocal8Bit(command))); } return result; }
static int startApp() { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); // Stop daemon and exit? if (args->isSet("s")) { KDEsuClient client; if (client.ping() == -1) { kError(1206) << "Daemon not running -- nothing to stop\n"; exit(1); } if (client.stopServer() != -1) { kDebug(1206) << "Daemon stopped\n"; exit(0); } kError(1206) << "Could not stop daemon\n"; exit(1); } QString icon; if ( args->isSet("i")) icon = args->getOption("i"); bool prompt = true; if ( args->isSet("d")) prompt = false; // Get target uid QByteArray user = args->getOption("u").toLocal8Bit(); QByteArray auth_user = user; struct passwd *pw = getpwnam(user); if (pw == 0L) { kError(1206) << "User " << user << " does not exist\n"; exit(1); } bool other_uid = (getuid() != pw->pw_uid); bool change_uid = other_uid; if (!change_uid) { char *cur_user = getenv("USER"); if (!cur_user) cur_user = getenv("LOGNAME"); change_uid = (!cur_user || user != cur_user); } // If file is writeable, do not change uid QString file = args->getOption("f"); if (other_uid && !file.isEmpty()) { if (file.at(0) != '/') { KStandardDirs dirs; file = dirs.findResource("config", file); if (file.isEmpty()) { kError(1206) << "Config file not found: " << file << "\n"; exit(1); } } QFileInfo fi(file); if (!fi.exists()) { kError(1206) << "File does not exist: " << file << "\n"; exit(1); } change_uid = !fi.isWritable(); } // Get priority/scheduler QString tmp = args->getOption("p"); bool ok; int priority = tmp.toInt(&ok); if (!ok || (priority < 0) || (priority > 100)) { KCmdLineArgs::usageError(i18n("Illegal priority: %1", tmp)); exit(1); } int scheduler = SuProcess::SchedNormal; if (args->isSet("r")) scheduler = SuProcess::SchedRealtime; if ((priority > 50) || (scheduler != SuProcess::SchedNormal)) { change_uid = true; auth_user = "******"; } // Get command if (args->isSet("c")) { command = args->getOption("c").toLocal8Bit(); // Accepting additional arguments here is somewhat weird, // but one can conceive use cases: have a complex command with // redirections and additional file names which need to be quoted // safely. } else { if( args->count() == 0 ) { KCmdLineArgs::usageError(i18n("No command specified.")); exit(1); } } for (int i = 0; i < args->count(); i++) { command += ' '; command += QFile::encodeName(KShell::quoteArg(args->arg(i))); } // Don't change uid if we're don't need to. if (!change_uid) { int result = system(command); result = WEXITSTATUS(result); return result; } // Check for daemon and start if necessary bool just_started = false; bool have_daemon = true; KDEsuClient client; if (!client.isServerSGID()) { kWarning(1206) << "Daemon not safe (not sgid), not using it.\n"; have_daemon = false; } else if (client.ping() == -1) { if (client.startServer() == -1) { kWarning(1206) << "Could not start daemon, reduced functionality.\n"; have_daemon = false; } just_started = true; } // Try to exec the command with kdesud. bool keep = !args->isSet("n") && have_daemon; bool terminal = args->isSet("t"); bool withIgnoreButton = args->isSet("ignorebutton"); int winid = -1; bool attach = args->isSet("attach"); if(attach) { winid = args->getOption("attach").toInt(&attach, 0); //C style parsing. If the string begins with "0x", base 16 is used; if the string begins with "0", base 8 is used; otherwise, base 10 is used. if(!attach) kWarning(1206) << "Specified winid to attach to is not a valid number"; } else if(args->isSet("embed")) { /* KDialog originally used --embed for attaching the dialog box. However this is misleading and so we changed to --attach. * For consistancy, we silently map --embed to --attach */ attach = true; winid = args->getOption("embed").toInt(&attach, 0); //C style parsing. If the string begins with "0x", base 16 is used; if the string begins with "0", base 8 is used; otherwise, base 10 is used. if(!attach) kWarning(1206) << "Specified winid to attach to is not a valid number"; } QList<QByteArray> env; QByteArray options; env << ( "DESKTOP_STARTUP_ID=" + kapp->startupId()); if (pw->pw_uid) { // Only propagate KDEHOME for non-root users, // root uses KDEROOTHOME // Translate the KDEHOME of this user to the new user. QString kdeHome = KGlobal::dirs()->relativeLocation("home", KGlobal::dirs()->localkdedir()); if (kdeHome[0] != '/') kdeHome.prepend("~/"); else kdeHome.clear(); // Use default env << ("KDEHOME="+ QFile::encodeName(kdeHome)); } KUser u; env << (QByteArray) ("KDESU_USER="******"rlimit(): " << ERR << "\n"; exit(1); } // Read configuration KConfigGroup config(KGlobal::config(), "Passwords"); int timeout = config.readEntry("Timeout", defTimeout); // Check if we need a password SuProcess proc; proc.setUser(auth_user); int needpw = proc.checkNeedPassword(); if (needpw < 0) { QString err = i18n("Su returned with an error.\n"); KMessageBox::error(0L, err); exit(1); } if (needpw == 0) { keep = 0; kDebug() << "Don't need password!!\n"; } // Start the dialog QString password; if (needpw) { #ifdef Q_WS_X11 KStartupInfoId id; id.initId( kapp->startupId()); KStartupInfoData data; data.setSilent( KStartupInfoData::Yes ); KStartupInfo::sendChange( id, data ); #endif KDEsuDialog dlg(user, auth_user, keep && !terminal, icon, withIgnoreButton); if (prompt) dlg.addCommentLine(i18n("Command:"), QFile::decodeName(command)); if (defKeep) dlg.setKeepPassword(true); if ((priority != 50) || (scheduler != SuProcess::SchedNormal)) { QString prio; if (scheduler == SuProcess::SchedRealtime) prio += i18n("realtime: "); prio += QString("%1/100").arg(priority); if (prompt) dlg.addCommentLine(i18n("Priority:"), prio); } //Attach dialog #ifdef Q_WS_X11 if(attach) KWindowSystem::setMainWindow(&dlg, (WId)winid); #endif int ret = dlg.exec(); if (ret == KDEsuDialog::Rejected) { #ifdef Q_WS_X11 KStartupInfo::sendFinish( id ); #endif exit(1); } if (ret == KDEsuDialog::AsUser) change_uid = false; password = dlg.password(); keep = dlg.keepPassword(); #ifdef Q_WS_X11 data.setSilent( KStartupInfoData::No ); KStartupInfo::sendChange( id, data ); #endif } // Some events may need to be handled (like a button animation) kapp->processEvents(); // Run command if (!change_uid) { int result = system(command); result = WEXITSTATUS(result); return result; } else if (keep && have_daemon) { client.setPass(password.toLocal8Bit(), timeout); client.setPriority(priority); client.setScheduler(scheduler); int result = client.exec(command, user, options, env); if (result == 0) { result = client.exitCode(); return result; } } else { SuProcess proc; proc.setTerminal(terminal); proc.setErase(true); proc.setUser(user); proc.setEnvironment(env); proc.setPriority(priority); proc.setScheduler(scheduler); proc.setCommand(command); int result = proc.exec(password.toLocal8Bit()); return result; } return -1; }