• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

dcop

dcop.cpp

Go to the documentation of this file.
00001 /*****************************************************************
00002 Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00017 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00018 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00019 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00020 
00021 ******************************************************************/
00022 
00023 // putenv() is not available on all platforms, so make sure the emulation
00024 // wrapper is available in those cases by loading config.h!
00025 #include <config.h>
00026 
00027 #include <sys/types.h>
00028 #include <pwd.h>
00029 #include <ctype.h>
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 
00033 #include <qbuffer.h>
00034 #include <qcolor.h>
00035 #include <qdir.h>
00036 #include <qfile.h>
00037 #include <qfileinfo.h>
00038 #include <qimage.h>
00039 #include <qmap.h>
00040 #include <qstringlist.h>
00041 #include <qtextstream.h>
00042 #include <qvariant.h>
00043 
00044 #include "../dcopclient.h"
00045 #include "../dcopref.h"
00046 #include "../kdatastream.h"
00047 
00048 #include "marshall.cpp"
00049 
00050 #if defined Q_WS_X11
00051 #include <X11/Xlib.h>
00052 #include <X11/Xatom.h>
00053 #endif
00054 
00055 typedef QMap<QString, QString> UserList;
00056 
00057 static DCOPClient* dcop = 0;
00058 
00059 static QTextStream cin_ ( stdin,  IO_ReadOnly );
00060 static QTextStream cout_( stdout, IO_WriteOnly );
00061 static QTextStream cerr_( stderr, IO_WriteOnly );
00062 
00072 enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
00073 
00074 bool startsWith(const QCString &id, const char *str, int n)
00075 {
00076   return !n || (strncmp(id.data(), str, n) == 0);
00077 }
00078 
00079 bool endsWith(QCString &id, char c)
00080 {
00081    if (id.length() && (id[id.length()-1] == c))
00082    {
00083       id.truncate(id.length()-1);
00084       return true;
00085    }
00086    return false;
00087 }
00088 
00089 void queryApplications(const QCString &filter)
00090 {
00091     int filterLen = filter.length();
00092     QCStringList apps = dcop->registeredApplications();
00093     for ( QCStringList::Iterator it = apps.begin(); it != apps.end(); ++it )
00094     {
00095         QCString &clientId = *it;
00096     if ( (clientId != dcop->appId()) &&
00097              !startsWith(clientId, "anonymous",9) &&
00098              startsWith(clientId, filter, filterLen)
00099            )
00100         printf( "%s\n", clientId.data() );
00101     }
00102 
00103     if ( !dcop->isAttached() )
00104     {
00105     qWarning( "server not accessible" );
00106         exit(1);
00107     }
00108 }
00109 
00110 void queryObjects( const QCString &app, const QCString &filter )
00111 {
00112     int filterLen = filter.length();
00113     bool ok = false;
00114     bool isDefault = false;
00115     QCStringList objs = dcop->remoteObjects( app, &ok );
00116     for ( QCStringList::Iterator it = objs.begin(); it != objs.end(); ++it )
00117     {
00118         QCString &objId = *it;
00119 
00120         if (objId == "default")
00121         {
00122            isDefault = true;
00123            continue;
00124         }
00125 
00126         if (startsWith(objId, filter, filterLen))
00127         {
00128             if (isDefault)
00129                 printf( "%s (default)\n", objId.data() );
00130             else
00131                 printf( "%s\n", objId.data() );
00132         }
00133         isDefault = false;
00134     }
00135     if ( !ok )
00136     {
00137         if (!dcop->isApplicationRegistered(app))
00138             qWarning( "No such application: '%s'", app.data());
00139         else
00140             qWarning( "Application '%s' not accessible", app.data() );
00141         exit(1);
00142     }
00143 }
00144 
00145 void queryFunctions( const char* app, const char* obj )
00146 {
00147     bool ok = false;
00148     QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
00149     for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
00150     printf( "%s\n", (*it).data() );
00151     }
00152     if ( !ok )
00153     {
00154     qWarning( "object '%s' in application '%s' not accessible", obj, app );
00155     exit( 1 );
00156     }
00157 }
00158 
00159 int callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
00160 {
00161     QString f = func; // Qt is better with unicode strings, so use one.
00162     int left = f.find( '(' );
00163     int right = f.find( ')' );
00164 
00165     if ( right <  left )
00166     {
00167     qWarning( "parentheses do not match" );
00168     return( 1 );
00169     }
00170 
00171     if ( left < 0 ) {
00172     // try to get the interface from the server
00173     bool ok = false;
00174     QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
00175     QCString realfunc;
00176     if ( !ok && args.isEmpty() )
00177         goto doit;
00178     if ( !ok )
00179     {
00180         qWarning( "object not accessible" );
00181         return( 1 );
00182     }
00183     for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
00184         int l = (*it).find( '(' );
00185         int s;
00186         if (l > 0)
00187             s = (*it).findRev( ' ', l);
00188         else
00189             s = (*it).find( ' ' );
00190 
00191         if ( s < 0 )
00192         s = 0;
00193         else
00194         s++;
00195 
00196         if ( l > 0 && (*it).mid( s, l - s ) == func ) {
00197         realfunc = (*it).mid( s );
00198         const QString arguments = (*it).mid(l+1,(*it).find( ')' )-l-1);
00199         uint a = arguments.contains(',');
00200         if ( (a==0 && !arguments.isEmpty()) || a>0)
00201             a++;
00202         if ( a == args.count()  )
00203             break;
00204         }
00205     }
00206     if ( realfunc.isEmpty() )
00207     {
00208         qWarning("no such function");
00209         return( 1 );
00210     }
00211     f = realfunc;
00212     left = f.find( '(' );
00213     right = f.find( ')' );
00214     }
00215 
00216  doit:
00217     if ( left < 0 )
00218     f += "()";
00219 
00220     // This may seem expensive but is done only once per invocation
00221     // of dcop, so it should be OK.
00222     //
00223     //
00224     QStringList intTypes;
00225     intTypes << "int" << "unsigned" << "long" << "bool" ;
00226 
00227     QStringList types;
00228     if ( left >0 && left + 1 < right - 1) {
00229     types = QStringList::split( ',', f.mid( left + 1, right - left - 1) );
00230     for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
00231         QString lt = (*it).simplifyWhiteSpace();
00232 
00233         int s = lt.find(' ');
00234 
00235         // If there are spaces in the name, there may be two
00236         // reasons: the parameter name is still there, ie.
00237         // "QString URL" or it's a complicated int type, ie.
00238         // "unsigned long long int bool".
00239         //
00240         //
00241         if ( s > 0 )
00242         {
00243         QStringList partl = QStringList::split(' ' , lt);
00244 
00245         // The zero'th part is -- at the very least -- a
00246         // type part. Any trailing parts *might* be extra
00247         // int-type keywords, or at most one may be the
00248         // parameter name.
00249         //
00250         //
00251         s=1;
00252 
00253         while (s < static_cast<int>(partl.count()) && intTypes.contains(partl[s]))
00254         {
00255             s++;
00256         }
00257 
00258         if ( s < static_cast<int>(partl.count())-1)
00259         {
00260             qWarning("The argument `%s' seems syntactically wrong.",
00261                 lt.latin1());
00262         }
00263         if ( s == static_cast<int>(partl.count())-1)
00264         {
00265             partl.remove(partl.at(s));
00266         }
00267 
00268         lt = partl.join(" ");
00269         lt = lt.simplifyWhiteSpace();
00270         }
00271 
00272         (*it) = lt;
00273     }
00274     QString fc = f.left( left );
00275     fc += '(';
00276     bool first = true;
00277     for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
00278         if ( !first )
00279         fc +=",";
00280         first = false;
00281         fc += *it;
00282     }
00283     fc += ')';
00284     f = fc;
00285     }
00286 
00287     QByteArray data, replyData;
00288     QCString replyType;
00289     QDataStream arg(data, IO_WriteOnly);
00290 
00291     uint i = 0;
00292     for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
00293         marshall( arg, args, i, *it );
00294 
00295     if ( i != args.count() )
00296     {
00297     qWarning( "arguments do not match" );
00298     return( 1 );
00299     }
00300 
00301     if ( !dcop->call( app, obj, f.latin1(),  data, replyType, replyData) ) {
00302     qWarning( "call failed");
00303     return( 1 );
00304     } else {
00305     QDataStream reply(replyData, IO_ReadOnly);
00306 
00307         if ( replyType != "void" && replyType != "ASYNC" )
00308         {
00309             QCString replyString = demarshal( reply, replyType );
00310             if ( !replyString.isEmpty() )
00311                 printf( "%s\n", replyString.data() );
00312             else
00313                 printf("\n");
00314         }
00315     }
00316     return 0;
00317 }
00318 
00322 void showHelp( int exitCode = 0 )
00323 {
00324 #ifdef DCOPQUIT
00325    cout_ << "Usage: dcopquit [options] [application]" << endl
00326 #else
00327    cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
00328 #endif
00329          << "" << endl
00330      << "Console DCOP client" << endl
00331      << "" << endl
00332      << "Generic options:" << endl
00333      << "  --help          Show help about options" << endl
00334      << "" << endl
00335      << "Options:" << endl
00336      << "  --pipe          Call DCOP for each line read from stdin. The string '%1'" << endl
00337      << "                  will be used in the argument list as a placeholder for" << endl
00338      << "                  the substituted line." << endl
00339      << "                  For example," << endl
00340      << "                      dcop --pipe konqueror html-widget1 evalJS %1" << endl
00341      << "                  is equivalent to calling" << endl
00342      << "                      while read line ; do" << endl
00343      << "                          dcop konqueror html-widget1 evalJS \"$line\"" << endl
00344      << "                      done" << endl
00345      << "                  in bash, but because no new dcop instance has to be started" << endl
00346      << "                  for each line this is generally much faster, especially for" << endl
00347      << "                  the slower GNU dynamic linkers." << endl
00348      << "                  The '%1' placeholder cannot be used to replace e.g. the" << endl
00349      << "                  program, object or method name." << endl
00350      << "  --user <user>   Connect to the given user's DCOP server. This option will" << endl
00351      << "                  ignore the values of the environment vars $DCOPSERVER and" << endl
00352      << "                  $ICEAUTHORITY, even if they are set." << endl
00353      << "                  If the user has more than one open session, you must also" << endl
00354      << "                  use one of the --list-sessions, --session or --all-sessions" << endl
00355      << "                  command-line options." << endl
00356      << "  --all-users     Send the same DCOP call to all users with a running DCOP" << endl
00357      << "                  server. Only failed calls to existing DCOP servers will" << endl
00358      << "                  generate an error message. If no DCOP server is available" << endl
00359      << "                  at all, no error will be generated." << endl
00360      << "  --session <ses> Send to the given KDE session. This option can only be" << endl
00361      << "                  used in combination with the --user option." << endl
00362      << "  --all-sessions  Send to all sessions found. Only works with the --user" << endl
00363      << "                  and --all-users options." << endl
00364      << "  --list-sessions List all active KDE session for a user or all users." << endl
00365      << "  --no-user-time  Don't update the user activity timestamp in the called" << endl
00366      << "                  application (for usage in scripts running" << endl
00367      << "                  in the background)." << endl
00368      << endl;
00369 
00370     exit( exitCode );
00371 }
00372 
00377 static UserList userList()
00378 {
00379     UserList result;
00380 
00381     while( passwd* pstruct = getpwent() )
00382     {
00383         result[ QString::fromLocal8Bit(pstruct->pw_name) ] = QFile::decodeName(pstruct->pw_dir);
00384     }
00385 
00386     return result;
00387 }
00388 
00393 QStringList dcopSessionList( const QString &user, const QString &home )
00394 {
00395     if( home.isEmpty() )
00396     {
00397     cerr_ << "WARNING: Cannot determine home directory for user "
00398          << user << "!" << endl
00399          << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00400          << "calling dcop." << endl;
00401     return QStringList();
00402     }
00403 
00404     QStringList result;
00405     QFileInfo dirInfo( home );
00406     if( !dirInfo.exists() || !dirInfo.isReadable() )
00407     return result;
00408 
00409     QDir d( home );
00410     d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
00411     d.setNameFilter( ".DCOPserver*" );
00412 
00413     const QFileInfoList *list = d.entryInfoList();
00414     if( !list )
00415     return result;
00416 
00417     QFileInfoListIterator it( *list );
00418     QFileInfo *fi;
00419 
00420     while ( ( fi = it.current() ) != 0 )
00421     {
00422     if( fi->isReadable() )
00423         result.append( fi->fileName() );
00424     ++it;
00425     }
00426     return result;
00427 }
00428 
00429 void sendUserTime( const char* app )
00430 {
00431 #if defined Q_WS_X11
00432     static unsigned long time = 0;
00433     if( time == 0 )
00434     {
00435         Display* dpy = XOpenDisplay( NULL );
00436         if( dpy != NULL )
00437         {
00438             Window w = XCreateSimpleWindow( dpy, DefaultRootWindow( dpy ), 0, 0, 1, 1, 0, 0, 0 );
00439             XSelectInput( dpy, w, PropertyChangeMask );
00440             unsigned char data[ 1 ];
00441             XChangeProperty( dpy, w, XA_ATOM, XA_ATOM, 8, PropModeAppend, data, 1 );
00442             XEvent ev;
00443             XWindowEvent( dpy, w, PropertyChangeMask, &ev );
00444             time = ev.xproperty.time;
00445             XDestroyWindow( dpy, w );
00446         }
00447     }
00448     DCOPRef( app, "MainApplication-Interface" ).call( "updateUserTimestamp", time );
00449 #else
00450 // ...
00451 #endif
00452 }
00453 
00457 int runDCOP( QCStringList args, UserList users, Session session,
00458               const QString sessionName, bool readStdin, bool updateUserTime )
00459 {
00460     bool DCOPrefmode=false;
00461     QCString app;
00462     QCString objid;
00463     QCString function;
00464     QCStringList params;
00465     DCOPClient *client = 0L;
00466     int retval = 0;
00467     if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
00468     {
00469     int delimPos = args[ 0 ].findRev( ',' );
00470     if( delimPos == -1 )
00471         {
00472         cerr_ << "Error: '" << args[ 0 ]
00473          << "' is not a valid DCOP reference." << endl;
00474         exit( -1 );
00475         }
00476         app = args[ 0 ].mid( 8, delimPos-8 );
00477         delimPos++;
00478         objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
00479         if( args.count() > 1 )
00480         function = args[ 1 ];
00481     if( args.count() > 2 )
00482     {
00483         params = args;
00484         params.remove( params.begin() );
00485         params.remove( params.begin() );
00486     }
00487     DCOPrefmode=true;
00488     }
00489     else
00490     {
00491         if( !args.isEmpty() )
00492         app = args[ 0 ];
00493         if( args.count() > 1 )
00494         objid = args[ 1 ];
00495         if( args.count() > 2 )
00496         function = args[ 2 ];
00497         if( args.count() > 3)
00498     {
00499         params = args;
00500         params.remove( params.begin() );
00501         params.remove( params.begin() );
00502         params.remove( params.begin() );
00503     }
00504     }
00505 
00506     bool firstRun = true;
00507     UserList::Iterator it;
00508     QStringList sessions;
00509     bool presetDCOPServer = false;
00510 //    char *dcopStr = 0L;
00511     QString dcopServer;
00512 
00513     for( it = users.begin(); it != users.end() || firstRun; ++it )
00514     {
00515     firstRun = false;
00516 
00517     //cout_ << "Iterating '" << it.key() << "'" << endl;
00518 
00519     if( session == QuerySessions )
00520     {
00521         QStringList sessions = dcopSessionList( it.key(), it.data() );
00522         if( sessions.isEmpty() )
00523         {
00524         if( users.count() <= 1 )
00525         {
00526             cout_ << "No active sessions";
00527             if( !( *it ).isEmpty() )
00528             cout_ << " for user " << *it;
00529             cout_ << endl;
00530         }
00531         }
00532         else
00533         {
00534         cout_ << "Active sessions ";
00535         if( !( *it ).isEmpty() )
00536             cout_ << "for user " << *it << " ";
00537         cout_ << ":" << endl;
00538 
00539         QStringList::Iterator sIt = sessions.begin();
00540         for( ; sIt != sessions.end(); ++sIt )
00541             cout_ << "  " << *sIt << endl;
00542 
00543         cout_ << endl;
00544         }
00545         continue;
00546     }
00547 
00548     if( getenv( "DCOPSERVER" ) )
00549     {
00550         sessions.append( getenv( "DCOPSERVER" ) );
00551         presetDCOPServer = true;
00552     }
00553 
00554     if( users.count() > 1 || ( users.count() == 1 &&
00555         ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
00556     {
00557         sessions = dcopSessionList( it.key(), it.data() );
00558         if( sessions.isEmpty() )
00559         {
00560         if( users.count() > 1 )
00561             continue;
00562         else
00563         {
00564             cerr_ << "ERROR: No active KDE sessions!" << endl
00565              << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
00566              << "before calling dcop." << endl;
00567             exit( -1 );
00568         }
00569         }
00570         else if( !sessionName.isEmpty() )
00571         {
00572         if( sessions.contains( sessionName ) )
00573         {
00574             sessions.clear();
00575             sessions.append( sessionName );
00576         }
00577         else
00578         {
00579             cerr_ << "ERROR: The specified session doesn't exist!" << endl;
00580             exit( -1 );
00581         }
00582         }
00583         else if( sessions.count() > 1 && session != AllSessions )
00584         {
00585         cerr_ << "ERROR: Multiple available KDE sessions!" << endl
00586              << "Please specify the correct session to use with --session or use the" << endl
00587              << "--all-sessions option to broadcast to all sessions." << endl;
00588         exit( -1 );
00589         }
00590     }
00591 
00592     if( users.count() > 1 || ( users.count() == 1 &&
00593         ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
00594     {
00595         // Check for ICE authority file and if the file can be read by us
00596         QString home = it.data();
00597         QString iceFile = it.data() + "/.ICEauthority";
00598         QFileInfo fi( iceFile );
00599         if( iceFile.isEmpty() )
00600         {
00601         cerr_ << "WARNING: Cannot determine home directory for user "
00602              << it.key() << "!" << endl
00603              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00604              << "calling dcop." << endl;
00605         }
00606         else if( fi.exists() )
00607         {
00608         if( fi.isReadable() )
00609         {
00610             char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
00611             putenv( envStr );
00612             //cerr_ << "ice: " << envStr << endl;
00613         }
00614         else
00615         {
00616             cerr_ << "WARNING: ICE authority file " << iceFile
00617              << "is not readable by you!" << endl
00618              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00619              << "calling dcop." << endl;
00620         }
00621         }
00622         else
00623         {
00624         if( users.count() > 1 )
00625             continue;
00626         else
00627         {
00628             cerr_ << "WARNING: Cannot find ICE authority file "
00629                  << iceFile << "!" << endl
00630              << "Please check permissions or set the $ICEAUTHORITY"
00631              << " variable manually before" << endl
00632              << "calling dcop." << endl;
00633         }
00634         }
00635     }
00636 
00637     // Main loop
00638     // If users is an empty list we're calling for the currently logged
00639     // in user. In this case we don't have a session, but still want
00640     // to iterate the loop once.
00641     QStringList::Iterator sIt = sessions.begin();
00642     for( ; sIt != sessions.end() || users.isEmpty(); ++sIt )
00643     {
00644         if( !presetDCOPServer && !users.isEmpty() )
00645         {
00646         QString dcopFile = it.data() + "/" + *sIt;
00647         QFile f( dcopFile );
00648         if( !f.open( IO_ReadOnly ) )
00649         {
00650             cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
00651             exit( -1 );
00652         }
00653 
00654         QStringList l( QStringList::split( '\n', f.readAll() ) );
00655         dcopServer = l.first();
00656 
00657         if( dcopServer.isEmpty() )
00658         {
00659             cerr_ << "WARNING: Unable to determine DCOP server for session "
00660              << *sIt << "!" << endl
00661              << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00662              << "calling dcop." << endl;
00663             exit( -1 );
00664         }
00665         }
00666 
00667         delete client;
00668         client = new DCOPClient;
00669         if( !dcopServer.isEmpty() )
00670         client->setServerAddress( dcopServer.ascii() );
00671         bool success = client->attach();
00672         if( !success )
00673         {
00674         cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
00675         retval = QMAX( retval, 1 );
00676         if( users.isEmpty() )
00677             break;
00678         else
00679             continue;
00680         }
00681         dcop = client;
00682 
00683         int argscount = args.count();
00684         if ( DCOPrefmode )
00685           argscount++;
00686         switch ( argscount )
00687         {
00688         case 0:
00689         queryApplications("");
00690         break;
00691         case 1:
00692         if (endsWith(app, '*'))
00693            queryApplications(app);
00694         else
00695            queryObjects( app, "" );
00696         break;
00697         case 2:
00698         if (endsWith(objid, '*'))
00699            queryObjects(app, objid);
00700         else
00701            queryFunctions( app, objid );
00702         break;
00703         case 3:
00704         default:
00705                 if( updateUserTime )
00706                     sendUserTime( app );
00707         if( readStdin )
00708         {
00709             QCStringList::Iterator replaceArg = params.end();
00710 
00711             QCStringList::Iterator it = params.begin();
00712             for( ; it != params.end(); ++it )
00713             if( *it == "%1" )
00714                 replaceArg = it;
00715 
00716             // Read from stdin until EOF and call function for each
00717             // read line
00718             while ( !cin_.atEnd() )
00719             {
00720             QString buf = cin_.readLine();
00721 
00722             if( replaceArg != params.end() )
00723                 *replaceArg = buf.local8Bit();
00724 
00725             if( !buf.isNull() )
00726             {
00727                 int res = callFunction( app, objid, function, params );
00728                 retval = QMAX( retval, res );
00729             }
00730             }
00731         }
00732         else
00733         {
00734             // Just call function
00735 //          cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
00736             int res = callFunction( app, objid, function, params );
00737             retval = QMAX( retval, res );
00738         }
00739         break;
00740         }
00741         // Another sIt++ would make the loop infinite...
00742         if( users.isEmpty() )
00743         break;
00744     }
00745 
00746     // Another it++ would make the loop infinite...
00747     if( it == users.end() )
00748         break;
00749     }
00750 
00751     return retval;
00752 }
00753 
00754 #ifdef Q_OS_WIN
00755 # define main kdemain
00756 #endif
00757 
00758 int main( int argc, char** argv )
00759 {
00760     bool readStdin = false;
00761     int numOptions = 0;
00762     QString user;
00763     Session session = DefaultSession;
00764     QString sessionName;
00765     bool updateUserTime = true;
00766 
00767     cin_.setEncoding( QTextStream::Locale );
00768 
00769     // Scan for command-line options first
00770     for( int pos = 1 ; pos <= argc - 1 ; pos++ )
00771     {
00772     if( strcmp( argv[ pos ], "--help" ) == 0 )
00773         showHelp( 0 );
00774     else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
00775     {
00776         readStdin = true;
00777         numOptions++;
00778     }
00779     else if( strcmp( argv[ pos ], "--user" ) == 0 )
00780     {
00781         if( pos <= argc - 2 )
00782         {
00783         user = QString::fromLocal8Bit( argv[ pos + 1] );
00784         numOptions +=2;
00785         pos++;
00786         }
00787         else
00788         {
00789         cerr_ << "Missing username for '--user' option!" << endl << endl;
00790         showHelp( -1 );
00791         }
00792     }
00793     else if( strcmp( argv[ pos ], "--session" ) == 0 )
00794     {
00795         if( session == AllSessions )
00796         {
00797         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00798         showHelp( -1 );
00799         }
00800         else if( pos <= argc - 2 )
00801         {
00802         sessionName = QString::fromLocal8Bit( argv[ pos + 1] );
00803         numOptions +=2;
00804         pos++;
00805         }
00806         else
00807         {
00808         cerr_ << "Missing session name for '--session' option!" << endl << endl;
00809         showHelp( -1 );
00810         }
00811     }
00812     else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
00813     {
00814         user = "*";
00815         numOptions ++;
00816     }
00817     else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
00818     {
00819         session = QuerySessions;
00820         numOptions ++;
00821     }
00822     else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
00823     {
00824         if( !sessionName.isEmpty() )
00825         {
00826         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00827         showHelp( -1 );
00828         }
00829         session = AllSessions;
00830         numOptions ++;
00831     }
00832         else if( strcmp( argv[ pos ], "--no-user-time" ) == 0 )
00833         {
00834             updateUserTime = false;
00835             numOptions ++;
00836         }
00837     else if( argv[ pos ][ 0 ] == '-' )
00838     {
00839         cerr_ << "Unknown command-line option '" << argv[ pos ]
00840          << "'." << endl << endl;
00841         showHelp( -1 );
00842     }
00843     else
00844         break;  // End of options
00845     }
00846 
00847     argc -= numOptions;
00848 
00849     QCStringList args;
00850     
00851 #ifdef DCOPQUIT
00852     if (argc > 1)
00853     {
00854        QCString prog = argv[ numOptions + 1 ];
00855        
00856        if (!prog.isEmpty())
00857        {
00858           args.append( prog );
00859        
00860           // Pass as-is if it ends with a wildcard
00861           if (prog[prog.length()-1] != '*')
00862           {
00863              // Strip a trailing -<PID> part.
00864              int i = prog.findRev('-');
00865              if ((i >= 0) && prog.mid(i+1).toLong())
00866              {
00867                 prog = prog.left(i);      
00868              }
00869              args.append( "qt/"+prog ); 
00870              args.append( "quit()" );
00871           }
00872        }
00873     }
00874 #else
00875     for( int i = numOptions; i < argc + numOptions - 1; i++ )
00876        args.append( argv[ i + 1 ] );
00877 #endif
00878 
00879     if( readStdin && args.count() < 3 )
00880     {
00881     cerr_ << "--pipe option only supported for function calls!" << endl << endl;
00882     showHelp( -1 );
00883     }
00884 
00885     if( user == "*" && args.count() < 3 && session != QuerySessions )
00886     {
00887     cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
00888     showHelp( -1 );
00889     }
00890 
00891     if( session == QuerySessions && !args.isEmpty() )
00892     {
00893     cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
00894     showHelp( -1 );
00895     }
00896 
00897     if( session == QuerySessions && user.isEmpty() )
00898     {
00899     cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
00900          << "--all-users options!" << endl << endl;
00901     showHelp( -1 );
00902     }
00903 
00904     if( session != DefaultSession && session != QuerySessions &&
00905         args.count() < 3 )
00906     {
00907     cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
00908          << "calls!" << endl << endl;
00909     showHelp( -1 );
00910     }
00911 
00912     UserList users;
00913     if( user == "*" )
00914     users = userList();
00915     else if( !user.isEmpty() )
00916     users[ user ] = userList()[ user ];
00917 
00918     int retval = runDCOP( args, users, session, sessionName, readStdin, updateUserTime );
00919 
00920     return retval;
00921 }
00922 
00923 // vim: set ts=8 sts=4 sw=4 noet:
00924 

dcop

Skip menu "dcop"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal