Beispiel #1
0
/**
 * 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;
}