KStringList KDEsuClient::getKeys(const QCString &group) { QCString cmd = "GETK "; cmd += escape(group); cmd += "\n"; QCString reply; command(cmd, &reply); int index = 0, pos; KStringList list; if(!reply.isEmpty()) { // kdDebug(900) << "Found a matching entry: " << reply << endl; while(1) { pos = reply.find('\007', index); if(pos == -1) { if(index == 0) list.append(reply); else list.append(reply.mid(index)); break; } else { list.append(reply.mid(index, pos - index)); } index = pos + 1; } } return list; }
static void continueInWindow(QString _wname) { QCString wname = _wname.latin1(); int id = -1; KStringList apps = kapp->dcopClient()->registeredApplications(); for(KStringList::Iterator it = apps.begin(); it != apps.end(); ++it) { QCString &clientId = *it; if(qstrncmp(clientId, wname, wname.length()) != 0) continue; DCOPRef client(clientId.data(), wname + "-mainwindow#1"); DCOPReply result = client.call("getWinID()"); if(result.isValid()) { id = (int)result; break; } } KWin::activateWindow(id); }
void KopeteApplication::slotAllPluginsLoaded() { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); // --noconnect not specified? if ( args->isSet( "connect" ) && KopetePrefs::prefs()->autoConnect() ) Kopete::AccountManager::self()->connectAll(); // Handle things like '--autoconnect foo,bar --autoconnect foobar' KStringList connectArgsC = args->getOptionList( "autoconnect" ); QStringList connectArgs; for ( KStringList::ConstIterator it = connectArgsC.begin(); it != connectArgsC.end(); ++it ) { QStringList split = QStringList::split( ',', QString::fromLatin1( *it ) ); for ( QStringList::ConstIterator it2 = split.begin(); it2 != split.end(); ++it2 ) { connectArgs.append( *it2 ); } } for ( QStringList::ConstIterator i = connectArgs.begin(); i != connectArgs.end(); ++i ) { QRegExp rx( QString::fromLatin1( "([^\\|]*)\\|\\|(.*)" ) ); rx.search( *i ); QString protocolId = rx.cap( 1 ); QString accountId = rx.cap( 2 ); if ( accountId.isEmpty() ) { if ( protocolId.isEmpty() ) accountId = *i; else continue; } QPtrListIterator<Kopete::Account> it( Kopete::AccountManager::self()->accounts() ); Kopete::Account *account; while ( ( account = it.current() ) != 0 ) { ++it; if ( ( account->accountId() == accountId ) ) { if ( protocolId.isEmpty() || account->protocol()->pluginId() == protocolId ) { account->connect(); break; } } } } // Parse any passed URLs/files handleURLArgs(); }
int KDEsuClient::exec(const QCString &prog, const QCString &user, const QCString &options, const KStringList &env) { QCString cmd; cmd = "EXEC "; cmd += escape(prog); cmd += " "; cmd += escape(user); if(!options.isEmpty() || !env.isEmpty()) { cmd += " "; cmd += escape(options); for(KStringList::ConstIterator it = env.begin(); it != env.end(); ++it) { cmd += " "; cmd += escape(*it); } } cmd += "\n"; return command(cmd); }
int Application::newInstance() { if(!isRestored()) { DCOPRef akr("akregator", "AkregatorIface"); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); if(!mMainWindow) { mMainWindow = new Akregator::MainWindow(); setMainWidget(mMainWindow); mMainWindow->loadPart(); mMainWindow->setupProgressWidgets(); if(!args->isSet("hide-mainwindow")) mMainWindow->show(); akr.send("openStandardFeedList"); } QString addFeedGroup = !args->getOption("group").isEmpty() ? QString::fromLocal8Bit(args->getOption("group")) : i18n("Imported Folder"); KStringList feeds = args->getOptionList("addfeed"); QStringList feedsToAdd; KStringList::ConstIterator end(feeds.end()); for(KStringList::ConstIterator it = feeds.begin(); it != end; ++it) feedsToAdd.append(*it); if(!feedsToAdd.isEmpty()) akr.send("addFeedsToGroup", feedsToAdd, addFeedGroup); args->clear(); } return KUniqueApplication::newInstance(); }
void PrintWrapper::slotPrint() { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; #endif /* HAVE_SIGACTION && !HAVE_SIGSET*/ // read variables from command line QString printer = args->getOption("d"); QString title = args->getOption("t"); int ncopies = QString(args->getOption("n")).toInt(); QString job_mode = args->getOption("j"); QString system = args->getOption("system"); KStringList optlist = args->getOptionList("o"); QMap< QString, QString > opts; KURL::List files; QStringList filestoprint; force_stdin = args->isSet("stdin"); docopy = args->isSet("c"); bool nodialog = !(args->isSet("dialog")); if(isatty(0)) { kdDebug(500) << "stdin is a terminal, disabling it" << endl; check_stdin = false; } // parse options for(KStringList::ConstIterator it = optlist.begin(); it != optlist.end(); ++it) { QStringList l = QStringList::split('=', QString(*it), false); if(l.count() >= 1) opts[l[0]] = (l.count() == 2 ? l[1] : QString::null); } // read file list for(int i = 0; i < args->count(); i++) files.append(args->url(i)); // some clean-up args->clear(); // set default values if necessary if(job_mode == "console") job_output = 1; else if(job_mode == "none") job_output = 2; else job_output = 0; // some checking if(files.count() > 0) { check_stdin = false; if(force_stdin) { showmsg(i18n("A file has been specified on the command line. Printing from STDIN will be disabled."), 1); force_stdin = false; } } if(nodialog && files.count() == 0 && !force_stdin && !check_stdin) { errormsg(i18n("When using '--nodialog', you must at least specify one file to print or use the '--stdin' flag.")); } if(check_stdin) { // check if there's any input on stdin fd_set in; struct timeval tm; tm.tv_sec = 0; tm.tv_usec = 0; FD_ZERO(&in); FD_SET(0, &in); if(select(1, &in, NULL, NULL, &tm)) { // we have data on stdin if(read(0, &readchar, 1) > 0) { force_stdin = true; check_stdin = false; dataread = true; kdDebug(500) << "input detected on stdin" << endl; } else { force_stdin = check_stdin = false; kdDebug(500) << "stdin closed and empty" << endl; } } else kdDebug(500) << "no input on stdin at startup" << endl; } // force_stdin ? or also check_stdin ? KPrinter::ApplicationType dialog_mode = (force_stdin || nodialog ? KPrinter::StandAlone : KPrinter::StandAlonePersistent); KPrinter::setApplicationType(dialog_mode); if(!force_stdin) KPrinter::addStandardPage(KPrinter::FilesPage); KPrinter kprinter; if(nodialog) { KMPrinter *prt(0); KMManager *mgr = KMManager::self(); mgr->printerList(false); if(!printer.isEmpty()) prt = mgr->findPrinter(printer); else prt = mgr->defaultPrinter(); if(prt == 0) errormsg(i18n("The specified printer or the default printer could not be found.")); else if(!prt->autoConfigure(&kprinter)) errormsg(i18n("Operation aborted.")); } else if(!printer.isEmpty()) kprinter.setSearchName(printer); kprinter.setDocName(title); kprinter.initOptions(opts); kprinter.setOption("kde-filelist", files.toStringList().join("@@")); kdDebug(500) << kprinter.option("kde-filelist") << endl; if(ncopies > 0) kprinter.setNumCopies(ncopies); if(nodialog) slotPrintRequested(&kprinter); else { dlg = KPrintDialog::printerDialog(&kprinter, 0); if(dlg) { connect(dlg, SIGNAL(printRequested(KPrinter *)), SLOT(slotPrintRequested(KPrinter *))); if(check_stdin) { notif = new QSocketNotifier(0, QSocketNotifier::Read, this); connect(notif, SIGNAL(activated(int)), this, SLOT(slotGotStdin())); kdDebug(500) << "waiting for input on stdin" << endl; } dlg->exec(); delete dlg; } else errormsg(i18n("Unable to construct the print dialog.")); }
int ConnectionHandler::doCommand(QCString buf) { if((uid_t)peerUid() != getuid()) { kdWarning(1205) << "Peer uid not equal to me\n"; kdWarning(1205) << "Peer: " << peerUid() << " Me: " << getuid() << endl; return -1; } QCString key, command, pass, name, user, value, env_check; Data_entry data; Lexer *l = new Lexer(buf); int tok = l->lex(); switch(tok) { case Lexer::Tok_pass: // "PASS password:string timeout:int\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; m_Pass.fill('x'); m_Pass = l->lval(); tok = l->lex(); if(tok != Lexer::Tok_num) goto parse_error; m_Timeout = l->lval().toInt(); if(l->lex() != '\n') goto parse_error; if(m_Pass.isNull()) m_Pass = ""; kdDebug(1205) << "Password set!\n"; respond(Res_OK); break; case Lexer::Tok_host: // "HOST host:string\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; m_Host = l->lval(); if(l->lex() != '\n') goto parse_error; kdDebug(1205) << "Host set to " << m_Host << endl; respond(Res_OK); break; case Lexer::Tok_prio: // "PRIO priority:int\n" tok = l->lex(); if(tok != Lexer::Tok_num) goto parse_error; m_Priority = l->lval().toInt(); if(l->lex() != '\n') goto parse_error; kdDebug(1205) << "priority set to " << m_Priority << endl; respond(Res_OK); break; case Lexer::Tok_sched: // "SCHD scheduler:int\n" tok = l->lex(); if(tok != Lexer::Tok_num) goto parse_error; m_Scheduler = l->lval().toInt(); if(l->lex() != '\n') goto parse_error; kdDebug(1205) << "Scheduler set to " << m_Scheduler << endl; respond(Res_OK); break; case Lexer::Tok_exec: // "EXEC command:string user:string [options:string (env:string)*]\n" { QCString options; KStringList env; tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; command = l->lval(); tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; user = l->lval(); tok = l->lex(); if(tok != '\n') { if(tok != Lexer::Tok_str) goto parse_error; options = l->lval(); tok = l->lex(); while(tok != '\n') { if(tok != Lexer::Tok_str) goto parse_error; QCString env_str = l->lval(); env.append(env_str); if(strncmp(env_str, "DESKTOP_STARTUP_ID=", strlen("DESKTOP_STARTUP_ID=")) != 0) env_check += "*" + env_str; tok = l->lex(); } } QCString auth_user; if((m_Scheduler != SuProcess::SchedNormal) || (m_Priority > 50)) auth_user = "******"; else auth_user = user; key = makeKey(2, m_Host, auth_user, command); // We only use the command if the environment is the same. if(repo->find(key) == env_check) { key = makeKey(0, m_Host, auth_user, command); pass = repo->find(key); } if(pass.isNull()) // isNull() means no password, isEmpty() can mean empty password { if(m_Pass.isNull()) { respond(Res_NO); break; } data.value = env_check; data.timeout = m_Timeout; key = makeKey(2, m_Host, auth_user, command); repo->add(key, data); data.value = m_Pass; data.timeout = m_Timeout; key = makeKey(0, m_Host, auth_user, command); repo->add(key, data); pass = m_Pass; } // Execute the command asynchronously kdDebug(1205) << "Executing command: " << command << endl; pid_t pid = fork(); if(pid < 0) { kdDebug(1205) << "fork(): " << strerror(errno) << endl; respond(Res_NO); break; } else if(pid > 0) { m_pid = pid; respond(Res_OK); break; } // Ignore SIGCHLD because "class SuProcess" needs waitpid() signal(SIGCHLD, SIG_DFL); int ret; if(m_Host.isEmpty()) { SuProcess proc; proc.setCommand(command); proc.setUser(user); if(options.contains('x')) proc.setXOnly(true); if(options.contains('f')) proc.setDCOPForwarding(true); proc.setPriority(m_Priority); proc.setScheduler(m_Scheduler); proc.setEnvironment(env); ret = proc.exec(pass.data()); } else { SshProcess proc; proc.setCommand(command); proc.setUser(user); proc.setHost(m_Host); ret = proc.exec(pass.data()); } kdDebug(1205) << "Command completed: " << command << endl; _exit(ret); } case Lexer::Tok_delCmd: // "DEL command:string user:string\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; command = l->lval(); tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; user = l->lval(); if(l->lex() != '\n') goto parse_error; key = makeKey(0, m_Host, user, command); if(repo->remove(key) < 0) { kdDebug(1205) << "Unknown command: " << command << endl; respond(Res_NO); } else { kdDebug(1205) << "Deleted command: " << command << ", user = "******"DELV name:string \n" { tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; name = l->lval(); tok = l->lex(); if(tok != '\n') goto parse_error; key = makeKey(1, name); if(repo->remove(key) < 0) { kdDebug(1205) << "Unknown name: " << name << endl; respond(Res_NO); } else { kdDebug(1205) << "Deleted name: " << name << endl; respond(Res_OK); } break; } case Lexer::Tok_delGroup: // "DELG group:string\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; name = l->lval(); if(repo->removeGroup(name) < 0) { kdDebug(1205) << "No keys found under group: " << name << endl; respond(Res_NO); } else { kdDebug(1205) << "Removed all keys under group: " << name << endl; respond(Res_OK); } break; case Lexer::Tok_delSpecialKey: // "DELS special_key:string\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; name = l->lval(); if(repo->removeSpecialKey(name) < 0) respond(Res_NO); else respond(Res_OK); break; case Lexer::Tok_set: // "SET name:string value:string group:string timeout:int\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; name = l->lval(); tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; data.value = l->lval(); tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; data.group = l->lval(); tok = l->lex(); if(tok != Lexer::Tok_num) goto parse_error; data.timeout = l->lval().toInt(); if(l->lex() != '\n') goto parse_error; key = makeKey(1, name); repo->add(key, data); kdDebug(1205) << "Stored key: " << key << endl; respond(Res_OK); break; case Lexer::Tok_get: // "GET name:string\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; name = l->lval(); if(l->lex() != '\n') goto parse_error; key = makeKey(1, name); kdDebug(1205) << "Request for key: " << key << endl; value = repo->find(key); if(!value.isEmpty()) respond(Res_OK, value); else respond(Res_NO); break; case Lexer::Tok_getKeys: // "GETK groupname:string\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; name = l->lval(); if(l->lex() != '\n') goto parse_error; kdDebug(1205) << "Request for group key: " << name << endl; value = repo->findKeys(name); if(!value.isEmpty()) respond(Res_OK, value); else respond(Res_NO); break; case Lexer::Tok_chkGroup: // "CHKG groupname:string\n" tok = l->lex(); if(tok != Lexer::Tok_str) goto parse_error; name = l->lval(); if(l->lex() != '\n') goto parse_error; kdDebug(1205) << "Checking for group key: " << name << endl; if(repo->hasGroup(name) < 0) respond(Res_NO); else respond(Res_OK); break; case Lexer::Tok_ping: // "PING\n" tok = l->lex(); if(tok != '\n') goto parse_error; respond(Res_OK); break; case Lexer::Tok_exit: // "EXIT\n" tok = l->lex(); if(tok != '\n') goto parse_error; m_needExitCode = true; if(m_hasExitCode) sendExitCode(); break; case Lexer::Tok_stop: // "STOP\n" tok = l->lex(); if(tok != '\n') goto parse_error; kdDebug(1205) << "Stopping by command" << endl; respond(Res_OK); kdesud_cleanup(); exit(0); default: kdWarning(1205) << "Unknown command: " << l->lval() << endl; respond(Res_NO); goto parse_error; } delete l; return 0; parse_error: kdWarning(1205) << "Parse error" << endl; delete l; return -1; }
bool findObject(const char *app, const char *obj, const char *func, KStringList args) { QString f = func; // Qt is better with unicode strings, so use one. int left = f.find('('); int right = f.find(')'); if(right < left) { qWarning("parentheses do not match"); exit(1); } if(!f.isEmpty() && (left < 0)) f += "()"; // This may seem expensive but is done only once per invocation // of dcop, so it should be OK. // // QStringList intTypes; intTypes << "int" << "unsigned" << "long" << "bool"; QStringList types; if(left > 0 && left + 1 < right - 1) { types = QStringList::split(',', f.mid(left + 1, right - left - 1)); for(QStringList::Iterator it = types.begin(); it != types.end(); ++it) { QString lt = (*it).simplifyWhiteSpace(); int s = lt.find(' '); // If there are spaces in the name, there may be two // reasons: the parameter name is still there, ie. // "QString URL" or it's a complicated int type, ie. // "unsigned long long int bool". // // if(s > 0) { QStringList partl = QStringList::split(' ', lt); // The zero'th part is -- at the very least -- a // type part. Any trailing parts *might* be extra // int-type keywords, or at most one may be the // parameter name. // // s = 1; while(s < (int)partl.count() && intTypes.contains(partl[s])) { s++; } if(s < (int)partl.count() - 1) { qWarning("The argument `%s' seems syntactically wrong.", lt.latin1()); } if(s == (int)partl.count() - 1) { partl.remove(partl.at(s)); } lt = partl.join(" "); lt = lt.simplifyWhiteSpace(); } (*it) = lt; } QString fc = f.left(left); fc += '('; bool first = true; for(QStringList::Iterator it = types.begin(); it != types.end(); ++it) { if(!first) fc += ","; first = false; fc += *it; } fc += ')'; f = fc; } if(types.count() != args.count()) { qWarning("arguments do not match"); exit(1); } QByteArray data; QDataStream arg(data, IO_WriteOnly); uint i = 0; for(QStringList::Iterator it = types.begin(); it != types.end(); ++it) { marshall(arg, args, i, *it); } if((uint)i != args.count()) { qWarning("arguments do not match"); exit(1); } QCString foundApp; QCString foundObj; if(dcop->findObject(app, obj, f.latin1(), data, foundApp, foundObj)) { if(bAppIdOnly) puts(foundApp.data()); else printf("DCOPRef(%s,%s)\n", qStringToC(foundApp), qStringToC(foundObj)); return true; } return false; }
int main(int argc, char **argv) { int argi = 1; while((argi < argc) && (argv[argi][0] == '-')) { switch(argv[argi][1]) { case 'l': bLaunchApp = true; break; case 'a': bAppIdOnly = true; break; default: usage(); } argi++; } if(argc <= argi) usage(); DCOPClient client; client.attach(); dcop = &client; QCString app; QCString objid; QCString function; char **args = 0; if((argc > argi) && (strncmp(argv[argi], "DCOPRef(", 8)) == 0) { char *delim = strchr(argv[argi], ','); if(!delim) { fprintf(stderr, "Error: '%s' is not a valid DCOP reference.\n", argv[argi]); return 1; } *delim = 0; app = argv[argi++] + 8; delim++; delim[strlen(delim) - 1] = 0; objid = delim; } else { if(argc > argi) app = argv[argi++]; if(argc > argi) objid = argv[argi++]; } if(argc > argi) function = argv[argi++]; if(argc > argi) { args = &argv[argi]; argc = argc - argi; } else { argc = 0; } KStringList params; for(int i = 0; i < argc; i++) params.append(args[i]); bool ok = findObject(app, objid, function, params); if(ok) return 0; if(bLaunchApp) { ok = launchApp(app); if(!ok) return 2; ok = findObject(app, objid, function, params); } return 1; }
/****************************************************************************** * Send a DCOP message to KAlarm telling it that an alarm should now be handled. * Reply = false if the event should be held pending until KAlarm can be started. */ bool AlarmDaemon::notifyEvent(ADCalendar *calendar, const QString &eventID) { if(!calendar) return true; QCString appname = calendar->appName(); const ClientInfo *client = ClientInfo::get(appname); if(!client) { kdDebug(5900) << "AlarmDaemon::notifyEvent(" << appname << "): unknown client" << endl; return false; } kdDebug(5900) << "AlarmDaemon::notifyEvent(" << appname << ", " << eventID << "): notification type=" << client->startClient() << endl; QString id = QString::fromLatin1("ad:") + eventID; // prefix to indicate that the notification if from the daemon // Check if the client application is running and ready to receive notification bool registered = kapp->dcopClient()->isApplicationRegistered(static_cast<const char *>(appname)); bool ready = registered; if(registered) { // It's running, but check if it has created our DCOP interface yet KStringList objects = kapp->dcopClient()->remoteObjects(appname); if(objects.find(client->dcopObject()) == objects.end()) ready = false; } if(!ready) { // KAlarm is not running, or is not yet ready to receive notifications. if(!client->startClient()) { if(registered) kdDebug(5900) << "AlarmDaemon::notifyEvent(): client not ready\n"; else kdDebug(5900) << "AlarmDaemon::notifyEvent(): don't start client\n"; return false; } // Start KAlarm, using the command line to specify the alarm KProcess p; QString cmd = locate("exe", appname); if(cmd.isEmpty()) { kdDebug(5900) << "AlarmDaemon::notifyEvent(): '" << appname << "' not found" << endl; return true; } p << cmd; p << "--handleEvent" << id << "--calendarURL" << calendar->urlString(); p.start(KProcess::DontCare); kdDebug(5900) << "AlarmDaemon::notifyEvent(): used command line" << endl; return true; } // Notify the client by telling it the calendar URL and event ID AlarmGuiIface_stub stub(appname, client->dcopObject()); stub.handleEvent(calendar->urlString(), id); if(!stub.ok()) { kdDebug(5900) << "AlarmDaemon::notifyEvent(): dcop send failed" << endl; return false; } return true; }
int main(int argc, char **argv) { bool readStdin = false; int numOptions = 0; QString user; Session session = DefaultSession; QString sessionName; bool updateUserTime = true; cin_.setEncoding(QTextStream::Locale); // Scan for command-line options first for(int pos = 1; pos <= argc - 1; pos++) { if(strcmp(argv[pos], "--help") == 0) showHelp(0); else if(strcmp(argv[pos], "--pipe") == 0) { readStdin = true; numOptions++; } else if(strcmp(argv[pos], "--user") == 0) { if(pos <= argc - 2) { user = QString::fromLocal8Bit(argv[pos + 1]); numOptions += 2; pos++; } else { cerr_ << "Missing username for '--user' option!" << endl << endl; showHelp(-1); } } else if(strcmp(argv[pos], "--session") == 0) { if(session == AllSessions) { cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl; showHelp(-1); } else if(pos <= argc - 2) { sessionName = QString::fromLocal8Bit(argv[pos + 1]); numOptions += 2; pos++; } else { cerr_ << "Missing session name for '--session' option!" << endl << endl; showHelp(-1); } } else if(strcmp(argv[pos], "--all-users") == 0) { user = "******"; numOptions++; } else if(strcmp(argv[pos], "--list-sessions") == 0) { session = QuerySessions; numOptions++; } else if(strcmp(argv[pos], "--all-sessions") == 0) { if(!sessionName.isEmpty()) { cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl; showHelp(-1); } session = AllSessions; numOptions++; } else if(strcmp(argv[pos], "--no-user-time") == 0) { updateUserTime = false; numOptions++; } else if(argv[pos][0] == '-') { cerr_ << "Unknown command-line option '" << argv[pos] << "'." << endl << endl; showHelp(-1); } else break; // End of options } argc -= numOptions; KStringList args; #ifdef DCOPQUIT if(argc > 1) { QCString prog = argv[numOptions + 1]; if(!prog.isEmpty()) { args.append(prog); // Pass as-is if it ends with a wildcard if(prog[prog.length() - 1] != '*') { // Strip a trailing -<PID> part. int i = prog.findRev('-'); if((i >= 0) && prog.mid(i + 1).toLong()) { prog = prog.left(i); } args.append("qt/" + prog); args.append("quit()"); } } } #else for(int i = numOptions; i < argc + numOptions - 1; i++) args.append(argv[i + 1]); #endif if(readStdin && args.count() < 3) { cerr_ << "--pipe option only supported for function calls!" << endl << endl; showHelp(-1); } if(user == "*" && args.count() < 3 && session != QuerySessions) { cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl; showHelp(-1); } if(session == QuerySessions && !args.isEmpty()) { cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl; showHelp(-1); } if(session == QuerySessions && user.isEmpty()) { cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl << "--all-users options!" << endl << endl; showHelp(-1); } if(session != DefaultSession && session != QuerySessions && args.count() < 3) { cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl << "calls!" << endl << endl; showHelp(-1); } UserList users; if(user == "*") users = userList(); else if(!user.isEmpty()) users[user] = userList()[user]; int retval = runDCOP(args, users, session, sessionName, readStdin, updateUserTime); return retval; }
/** * Do the actual DCOP call */ int runDCOP(KStringList args, UserList users, Session session, const QString sessionName, bool readStdin, bool updateUserTime) { bool DCOPrefmode = false; QCString app; QCString objid; QCString function; KStringList params; DCOPClient *client = 0L; int retval = 0; if(!args.isEmpty() && args[0].find("DCOPRef(") == 0) { int delimPos = args[0].findRev(','); if(delimPos == -1) { cerr_ << "Error: '" << args[0] << "' is not a valid DCOP reference." << endl; exit(-1); } app = args[0].mid(8, delimPos - 8); delimPos++; objid = args[0].mid(delimPos, args[0].length() - delimPos - 1); if(args.count() > 1) function = args[1]; if(args.count() > 2) { params = args; params.remove(params.begin()); params.remove(params.begin()); } DCOPrefmode = true; } else { if(!args.isEmpty()) app = args[0]; if(args.count() > 1) objid = args[1]; if(args.count() > 2) function = args[2]; if(args.count() > 3) { params = args; params.remove(params.begin()); params.remove(params.begin()); params.remove(params.begin()); } } bool firstRun = true; UserList::Iterator it; QStringList sessions; bool presetDCOPServer = false; // char *dcopStr = 0L; QString dcopServer; for(it = users.begin(); it != users.end() || firstRun; ++it) { firstRun = false; // cout_ << "Iterating '" << it.key() << "'" << endl; if(session == QuerySessions) { QStringList sessions = dcopSessionList(it.key(), it.data()); if(sessions.isEmpty()) { if(users.count() <= 1) { cout_ << "No active sessions"; if(!(*it).isEmpty()) cout_ << " for user " << *it; cout_ << endl; } } else { cout_ << "Active sessions "; if(!(*it).isEmpty()) cout_ << "for user " << *it << " "; cout_ << ":" << endl; QStringList::Iterator sIt = sessions.begin(); for(; sIt != sessions.end(); ++sIt) cout_ << " " << *sIt << endl; cout_ << endl; } continue; } if(getenv("DCOPSERVER")) { sessions.append(getenv("DCOPSERVER")); presetDCOPServer = true; } if(users.count() > 1 || (users.count() == 1 && (getenv("DCOPSERVER") == 0 /*&& getenv( "DISPLAY" ) == 0*/))) { sessions = dcopSessionList(it.key(), it.data()); if(sessions.isEmpty()) { if(users.count() > 1) continue; else { cerr_ << "ERROR: No active KDE sessions!" << endl << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl << "before calling dcop." << endl; exit(-1); } } else if(!sessionName.isEmpty()) { if(sessions.contains(sessionName)) { sessions.clear(); sessions.append(sessionName); } else { cerr_ << "ERROR: The specified session doesn't exist!" << endl; exit(-1); } } else if(sessions.count() > 1 && session != AllSessions) { cerr_ << "ERROR: Multiple available KDE sessions!" << endl << "Please specify the correct session to use with --session or use the" << endl << "--all-sessions option to broadcast to all sessions." << endl; exit(-1); } } if(users.count() > 1 || (users.count() == 1 && (getenv("ICEAUTHORITY") == 0 || getenv("DISPLAY") == 0))) { // Check for ICE authority file and if the file can be read by us QString home = it.data(); QString iceFile = it.data() + "/.ICEauthority"; QFileInfo fi(iceFile); if(iceFile.isEmpty()) { cerr_ << "WARNING: Cannot determine home directory for user " << it.key() << "!" << endl << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl << "calling dcop." << endl; } else if(fi.exists()) { if(fi.isReadable()) { char *envStr = strdup(("ICEAUTHORITY=" + iceFile).ascii()); putenv(envStr); // cerr_ << "ice: " << envStr << endl; } else { cerr_ << "WARNING: ICE authority file " << iceFile << "is not readable by you!" << endl << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl << "calling dcop." << endl; } } else { if(users.count() > 1) continue; else { cerr_ << "WARNING: Cannot find ICE authority file " << iceFile << "!" << endl << "Please check permissions or set the $ICEAUTHORITY" << " variable manually before" << endl << "calling dcop." << endl; } } } // Main loop // If users is an empty list we're calling for the currently logged // in user. In this case we don't have a session, but still want // to iterate the loop once. QStringList::Iterator sIt = sessions.begin(); for(; sIt != sessions.end() || users.isEmpty(); ++sIt) { if(!presetDCOPServer && !users.isEmpty()) { QString dcopFile = it.data() + "/" + *sIt; QFile f(dcopFile); if(!f.open(IO_ReadOnly)) { cerr_ << "Can't open " << dcopFile << " for reading!" << endl; exit(-1); } QStringList l(QStringList::split('\n', f.readAll())); dcopServer = l.first(); if(dcopServer.isEmpty()) { cerr_ << "WARNING: Unable to determine DCOP server for session " << *sIt << "!" << endl << "Please check permissions or set the $DCOPSERVER variable manually before" << endl << "calling dcop." << endl; exit(-1); } } delete client; client = new DCOPClient; if(!dcopServer.isEmpty()) client->setServerAddress(dcopServer.ascii()); bool success = client->attach(); if(!success) { cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl; retval = QMAX(retval, 1); if(users.isEmpty()) break; else continue; } dcop = client; int argscount = args.count(); if(DCOPrefmode) argscount++; switch(argscount) { case 0: queryApplications(""); break; case 1: if(endsWith(app, '*')) queryApplications(app); else queryObjects(app, ""); break; case 2: if(endsWith(objid, '*')) queryObjects(app, objid); else queryFunctions(app, objid); break; case 3: default: if(updateUserTime) sendUserTime(app); if(readStdin) { KStringList::Iterator replaceArg = params.end(); KStringList::Iterator it = params.begin(); for(; it != params.end(); ++it) if(*it == "%1") replaceArg = it; // Read from stdin until EOF and call function for each // read line while(!cin_.atEnd()) { QString buf = cin_.readLine(); if(replaceArg != params.end()) *replaceArg = buf.local8Bit(); if(!buf.isNull()) { int res = callFunction(app, objid, function, params); retval = QMAX(retval, res); } } } else { // Just call function // cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl; int res = callFunction(app, objid, function, params); retval = QMAX(retval, res); } break; } // Another sIt++ would make the loop infinite... if(users.isEmpty()) break; } // Another it++ would make the loop infinite... if(it == users.end()) break; } return retval; }
int callFunction(const char *app, const char *obj, const char *func, const KStringList args) { QString f = func; // Qt is better with unicode strings, so use one. int left = f.find('('); int right = f.find(')'); if(right < left) { qWarning("parentheses do not match"); return (1); } if(left < 0) { // try to get the interface from the server bool ok = false; KStringList funcs = dcop->remoteFunctions(app, obj, &ok); QCString realfunc; if(!ok && args.isEmpty()) goto doit; if(!ok) { qWarning("object not accessible"); return (1); } for(const auto &it : funcs) { int l = it.find('('); int s; if(l > 0) s = it.findRev(' ', l); else s = it.find(' '); if(s < 0) s = 0; else s++; if(l > 0 && it.mid(s, l - s) == func) { realfunc = it.mid(s); const QString arguments = it.mid(l + 1, it.find(')') - l - 1); uint a = arguments.contains(','); if((a == 0 && !arguments.isEmpty()) || a > 0) a++; if(a == args.count()) break; } } if(realfunc.isEmpty()) { qWarning("no such function"); return (1); } f = realfunc; left = f.find('('); right = f.find(')'); } doit: if(left < 0) f += "()"; // This may seem expensive but is done only once per invocation // of dcop, so it should be OK. // // QStringList intTypes; intTypes << "int" << "unsigned" << "long" << "bool"; QStringList types; if(left > 0 && left + 1 < right - 1) { types = QStringList::split(',', f.mid(left + 1, right - left - 1)); for(QStringList::Iterator it = types.begin(); it != types.end(); ++it) { QString lt = (*it).simplifyWhiteSpace(); int s = lt.find(' '); // If there are spaces in the name, there may be two // reasons: the parameter name is still there, ie. // "QString URL" or it's a complicated int type, ie. // "unsigned long long int bool". // // if(s > 0) { QStringList partl = QStringList::split(' ', lt); // The zero'th part is -- at the very least -- a // type part. Any trailing parts *might* be extra // int-type keywords, or at most one may be the // parameter name. // // s = 1; while(s < static_cast< int >(partl.count()) && intTypes.contains(partl[s])) { s++; } if(s < static_cast< int >(partl.count()) - 1) { qWarning("The argument `%s' seems syntactically wrong.", lt.latin1()); } if(s == static_cast< int >(partl.count()) - 1) { partl.remove(partl.at(s)); } lt = partl.join(" "); lt = lt.simplifyWhiteSpace(); } (*it) = lt; } QString fc = f.left(left); fc += '('; bool first = true; for(QStringList::Iterator it = types.begin(); it != types.end(); ++it) { if(!first) fc += ","; first = false; fc += *it; } fc += ')'; f = fc; } QByteArray data, replyData; QCString replyType; QDataStream arg(data, IO_WriteOnly); uint i = 0; for(QStringList::Iterator it = types.begin(); it != types.end(); ++it) marshall(arg, args, i, *it); if(i != args.count()) { qWarning("arguments do not match"); return (1); } if(!dcop->call(app, obj, f.latin1(), data, replyType, replyData)) { qWarning("call failed"); return (1); } else { QDataStream reply(replyData, IO_ReadOnly); if(replyType != "void" && replyType != "ASYNC") { QCString replyString = demarshal(reply, replyType); if(!replyString.isEmpty()) printf("%s\n", replyString.data()); else printf("\n"); } } return 0; }