dcop.cpp Source File (dcop Library)

| # dcop Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# dcop.cpp

    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 #include <ctype.h>
    00024 #include <stdio.h>
    00025 #include <stdlib.h>
    00026
    00027 #include <qcolor.h>
    00028 #include <qdir.h>
    00029 #include <qfile.h>
    00030 #include <qfileinfo.h>
    00031 #include <qmap.h>
    00032 #include <qstringlist.h>
    00033 #include <qtextstream.h>
    00034 #include <qvariant.h>
    00035
    00036 // putenv() is not available on all platforms, so make sure the emulation
    00037 // wrapper is available in those cases by loading config.h!
    00038 #include <config.h>
    00039
    00040 #include "../dcopclient.h"
    00041 #include "../dcopref.h"
    00042 #include "../kdatastream.h"
    00043
    00044 #include "marshall.cpp"
    00045
    00046 typedef QMap<QString, QString> UserList;
    00047
    00048 static DCOPClient* dcop = 0;
    00049
    00050 static QTextStream cin_ ( stdin,  IO_ReadOnly );
    00051 static QTextStream cout_( stdout, IO_WriteOnly );
    00052 static QTextStream cerr_( stderr, IO_WriteOnly );
    00053
    00063 enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
    00064
    00065 bool startsWith(const QCString &id, const char *str, int n)
    00066 {
    00067   return !n || (strncmp(id.data(), str, n) == 0);
    00068 }
    00069
    00070 bool endsWith(QCString &id, char c)
    00071 {
    00072    if (id.length() && (id[id.length()-1] == c))
    00073    {
    00074       id.truncate(id.length()-1);
    00075       return true;
    00076    }
    00077    return false;
    00078 }
    00079
    00080 void queryApplications(const QCString &filter)
    00081 {
    00082     int filterLen = filter.length();
    00083     QCStringList apps = dcop->registeredApplications();
    00084     for ( QCStringList::Iterator it = apps.begin(); it != apps.end(); ++it )
    00085     {
    00086         QCString &clientId = *it;
    00087         if ( (clientId != dcop->appId()) &&
    00088              !startsWith(clientId, "anonymous",9) &&
    00089              startsWith(clientId, filter, filterLen)
    00090            )
    00091             printf( "%s\n", clientId.data() );
    00092     }
    00093
    00094     if ( !dcop->isAttached() )
    00095     {
    00096         qWarning( "server not accessible" );
    00097         exit(1);
    00098     }
    00099 }
    00100
    00101 void queryObjects( const QCString &app, const QCString &filter )
    00102 {
    00103     int filterLen = filter.length();
    00104     bool ok = false;
    00105     bool isDefault = false;
    00106     QCStringList objs = dcop->remoteObjects( app, &ok );
    00107     for ( QCStringList::Iterator it = objs.begin(); it != objs.end(); ++it )
    00108     {
    00109         QCString &objId = *it;
    00110
    00111         if (objId == "default")
    00112         {
    00113            isDefault = true;
    00114            continue;
    00115         }
    00116
    00117         if (startsWith(objId, filter, filterLen))
    00118         {
    00119             if (isDefault)
    00120                 printf( "%s (default)\n", objId.data() );
    00121             else
    00122                 printf( "%s\n", objId.data() );
    00123         }
    00124         isDefault = false;
    00125     }
    00126     if ( !ok )
    00127     {
    00128         if (!dcop->isApplicationRegistered(app))
    00129             qWarning( "No such application: '%s'", app.data());
    00130         else
    00131             qWarning( "Application '%s' not accessible", app.data() );
    00132         exit(1);
    00133     }
    00134 }
    00135
    00136 void queryFunctions( const char* app, const char* obj )
    00137 {
    00138     bool ok = false;
    00139     QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
    00140     for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
    00141         printf( "%s\n", (*it).data() );
    00142     }
    00143     if ( !ok )
    00144     {
    00145         qWarning( "object '%s' in application '%s' not accessible", obj, app );
    00146         exit( 1 );
    00147     }
    00148 }
    00149
    00150 int callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
    00151 {
    00152     QString f = func; // Qt is better with unicode strings, so use one.
    00153     int left = f.find( '(' );
    00154     int right = f.find( ')' );
    00155
    00156     if ( right <  left )
    00157     {
    00158         qWarning( "parentheses do not match" );
    00159         return( 1 );
    00160     }
    00161
    00162     if ( left < 0 ) {
    00163         // try to get the interface from the server
    00164         bool ok = false;
    00165         QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
    00166         QCString realfunc;
    00167         if ( !ok && args.isEmpty() )
    00168             goto doit;
    00169         if ( !ok )
    00170         {
    00171             qWarning( "object not accessible" );
    00172             return( 1 );
    00173         }
    00174         for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
    00175             int l = (*it).find( '(' );
    00176             int s = (*it).find( ' ');
    00177             if ( s < 0 )
    00178                 s = 0;
    00179             else
    00180                 s++;
    00181
    00182             if ( l > 0 && (*it).mid( s, l - s ) == func ) {
    00183                 realfunc = (*it).mid( s );
    00184                 uint a = (*it).contains(',');
    00185                 if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
    00186                     break;
    00187             }
    00188         }
    00189         if ( realfunc.isEmpty() )
    00190         {
    00191             qWarning("no such function");
    00192             return( 1 );
    00193         }
    00194         f = realfunc;
    00195         left = f.find( '(' );
    00196         right = f.find( ')' );
    00197     }
    00198
    00199  doit:
    00200     if ( left < 0 )
    00201         f += "()";
    00202
    00203     // This may seem expensive but is done only once per invocation
    00204     // of dcop, so it should be OK.
    00205     //
    00206     //
    00207     QStringList intTypes;
    00208     intTypes << "int" << "unsigned" << "long" << "bool" ;
    00209
    00210     QStringList types;
    00211     if ( left >0 && left + 1 < right - 1) {
    00212         types = QStringList::split( ',', f.mid( left + 1, right - left - 1) );
    00213         for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
    00214             QString lt = (*it).simplifyWhiteSpace();
    00215
    00216             int s = lt.find(' ');
    00217
    00218             // If there are spaces in the name, there may be two
    00219             // reasons: the parameter name is still there, ie.
    00220             // "QString URL" or it's a complicated int type, ie.
    00221             // "unsigned long long int bool".
    00222             //
    00223             //
    00224             if ( s > 0 )
    00225             {
    00226                 QStringList partl = QStringList::split(' ' , lt);
    00227
    00228                 // The zero'th part is -- at the very least -- a
    00229                 // type part. Any trailing parts *might* be extra
    00230                 // int-type keywords, or at most one may be the
    00231                 // parameter name.
    00232                 //
    00233                 //
    00234                 s=1;
    00235
    00236                 while (s < static_cast<int>(partl.count()) && intTypes.contains(partl[s]))
    00237                 {
    00238                         s++;
    00239                 }
    00240
    00241                 if ( s < static_cast<int>(partl.count())-1)
    00242                 {
    00243                         qWarning("The argument `%s' seems syntactically wrong.",
    00244                                 lt.latin1());
    00245                 }
    00246                 if ( s == static_cast<int>(partl.count())-1)
    00247                 {
    00248                         partl.remove(partl.at(s));
    00249                 }
    00250
    00251                 lt = partl.join(" ");
    00252                 lt = lt.simplifyWhiteSpace();
    00253             }
    00254
    00255             (*it) = lt;
    00256         }
    00257         QString fc = f.left( left );
    00258         fc += '(';
    00259         bool first = TRUE;
    00260         for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
    00261             if ( !first )
    00262                 fc +=",";
    00263             first = FALSE;
    00264             fc += *it;
    00265         }
    00266         fc += ')';
    00267         f = fc;
    00268     }
    00269
    00270     QByteArray data, replyData;
    00271     QCString replyType;
    00272     QDataStream arg(data, IO_WriteOnly);
    00273
    00274     uint i = 0;
    00275     for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
    00276         marshall( arg, args, i, *it );
    00277
    00278     if ( i != args.count() )
    00279     {
    00280         qWarning( "arguments do not match" );
    00281         return( 1 );
    00282     }
    00283
    00284     if ( !dcop->call( app, obj, f.latin1(),  data, replyType, replyData) ) {
    00285         qWarning( "call failed");
    00286         return( 1 );
    00287     } else {
    00288         QDataStream reply(replyData, IO_ReadOnly);
    00289
    00290         if ( replyType != "void" && replyType != "ASYNC" )
    00291         {
    00292             QCString replyString = demarshal( reply, replyType );
    00293             if ( !replyString.isEmpty() )
    00294             printf( "%s\n", replyString.data() );
    00295             else
    00296                 printf("\n");
    00297         }
    00298     }
    00299     return 0;
    00300 }
    00301
    00305 void showHelp( int exitCode = 0 )
    00306 {
    00307     cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
    00308          << "" << endl
    00309          << "Console DCOP client" << endl
    00310          << "" << endl
    00311          << "Generic options:" << endl
    00312          << "  --help          Show help about options" << endl
    00313          << "" << endl
    00314          << "Options:" << endl
    00315          << "  --pipe          Call DCOP for each line read from stdin" << endl
    00316          << "                  This is roughly equivalent to calling" << endl
    00317          << "                      'while read line ; do dcop $line ; done'" << endl
    00318          << "                  but because no new dcop instance has to be started for" << endl
    00319          << "                  each line this is generally much faster, especially" << endl
    00320          << "                  for the slower GNU dynamic linkers." << endl
    00321          << "  --user <user>   Connect to the given user's DCOP server. This option will" << endl
    00322          << "                  ignore the values of the environment vars $DCOPSERVER and" << endl
    00323          << "                  $ICEAUTHORITY, even if they are set." << endl
    00324          << "                  If the user has more than one open session, you must also" << endl
    00325          << "                  use one of the --list-sessions, --session or --all-sessions" << endl
    00326          << "                  command-line options." << endl
    00327          << "  --all-users     Send the same DCOP call to all users with a running DCOP" << endl
    00328          << "                  server. Only failed calls to existing DCOP servers will" << endl
    00329          << "                  generate an error message. If no DCOP server is available" << endl
    00330          << "                  at all, no error will be generated." << endl
    00331          << "  --session <ses> Send to the given KDE session. This option can only be" << endl
    00332          << "                  used in combination with the --user option." << endl
    00333          << "  --all-sessions  Send to all sessions found. Only works with the --user" << endl
    00334          << "                  and --all-users options." << endl
    00335          << "  --list-sessions List all active KDE session for a user or all users." << endl
    00336          << endl;
    00337
    00338     exit( exitCode );
    00339 }
    00340
    00345 static UserList userList()
    00346 {
    00347     UserList result;
    00348
    00349     QFile f( "/etc/passwd" );
    00350
    00351     if( !f.open( IO_ReadOnly ) )
    00352     {
    00353         cerr_ << "Can't open /etc/passwd for reading!" << endl;
    00354         return result;
    00355     }
    00356
    00357     QStringList l( QStringList::split( '\n', f.readAll() ) );
    00358
    00359     for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
    00360     {
    00361         QStringList userInfo( QStringList::split( ':', *it, true ) );
    00362         result[ userInfo[ 0 ] ] = userInfo[ 5 ];
    00363     }
    00364
    00365     return result;
    00366 }
    00367
    00372 QStringList dcopSessionList( const QString &user, const QString &home )
    00373 {
    00374     if( home.isEmpty() )
    00375     {
    00376         cerr_ << "WARNING: Cannot determine home directory for user "
    00377              << user << "!" << endl
    00378              << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
    00379              << "calling dcop." << endl;
    00380         return QStringList();
    00381     }
    00382
    00383     QStringList result;
    00384     QFileInfo dirInfo( home );
    00385     if( !dirInfo.exists() || !dirInfo.isReadable() )
    00386         return result;
    00387
    00388     QDir d( home );
    00389     d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
    00390     d.setNameFilter( ".DCOPserver*" );
    00391
    00392     const QFileInfoList *list = d.entryInfoList();
    00393     if( !list )
    00394         return result;
    00395
    00396     QFileInfoListIterator it( *list );
    00397     QFileInfo *fi;
    00398
    00399     while ( ( fi = it.current() ) != 0 )
    00400     {
    00401         if( fi->isReadable() )
    00402             result.append( fi->fileName() );
    00403         ++it;
    00404     }
    00405     return result;
    00406 }
    00407
    00411 int runDCOP( QCStringList args, UserList users, Session session,
    00412               const QString sessionName, bool readStdin )
    00413 {
    00414     bool DCOPrefmode=false;
    00415     QCString app;
    00416     QCString objid;
    00417     QCString function;
    00418     QCStringList params;
    00419     DCOPClient *client = 0L;
    00420     int retval = 0;
    00421     if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
    00422     {
    00423         int delimPos = args[ 0 ].findRev( ',' );
    00424         if( delimPos == -1 )
    00425         {
    00426             cerr_ << "Error: '" << args[ 0 ]
    00427                  << "' is not a valid DCOP reference." << endl;
    00428             exit( -1 );
    00429         }
    00430         app = args[ 0 ].mid( 8, delimPos-8 );
    00431         delimPos++;
    00432         objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
    00433         if( args.count() > 1 )
    00434             function = args[ 1 ];
    00435         if( args.count() > 2 )
    00436         {
    00437             params = args;
    00438             params.remove( params.begin() );
    00439             params.remove( params.begin() );
    00440         }
    00441         DCOPrefmode=true;
    00442     }
    00443     else
    00444     {
    00445         if( !args.isEmpty() )
    00446             app = args[ 0 ];
    00447         if( args.count() > 1 )
    00448             objid = args[ 1 ];
    00449         if( args.count() > 2 )
    00450             function = args[ 2 ];
    00451         if( args.count() > 3)
    00452         {
    00453             params = args;
    00454             params.remove( params.begin() );
    00455             params.remove( params.begin() );
    00456             params.remove( params.begin() );
    00457         }
    00458     }
    00459
    00460     bool firstRun = true;
    00461     UserList::Iterator it;
    00462     QStringList sessions;
    00463     bool presetDCOPServer = false;
    00464 //    char *dcopStr = 0L;
    00465     QString dcopServer;
    00466
    00467     for( it = users.begin(); it != users.end() || firstRun; it++ )
    00468     {
    00469         firstRun = false;
    00470
    00471         //cout_ << "Iterating '" << it.key() << "'" << endl;
    00472
    00473         if( session == QuerySessions )
    00474         {
    00475             QStringList sessions = dcopSessionList( it.key(), it.data() );
    00476             if( sessions.isEmpty() )
    00477             {
    00478                 if( users.count() <= 1 )
    00479                 {
    00480                     cout_ << "No active sessions";
    00481                     if( !( *it ).isEmpty() )
    00482                         cout_ << " for user " << *it;
    00483                     cout_ << endl;
    00484                 }
    00485             }
    00486             else
    00487             {
    00488                 cout_ << "Active sessions ";
    00489                 if( !( *it ).isEmpty() )
    00490                     cout_ << "for user " << *it << " ";
    00491                 cout_ << ":" << endl;
    00492
    00493                 QStringList::Iterator sIt;
    00494                 for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
    00495                     cout_ << "  " << *sIt << endl;
    00496
    00497                 cout_ << endl;
    00498             }
    00499             continue;
    00500         }
    00501
    00502         if( getenv( "DCOPSERVER" ) )
    00503         {
    00504             sessions.append( getenv( "DCOPSERVER" ) );
    00505             presetDCOPServer = true;
    00506         }
    00507
    00508         if( users.count() > 1 || ( users.count() == 1 &&
    00509             ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
    00510         {
    00511             sessions = dcopSessionList( it.key(), it.data() );
    00512             if( sessions.isEmpty() )
    00513             {
    00514                 if( users.count() > 1 )
    00515                     continue;
    00516                 else
    00517                 {
    00518                     cerr_ << "ERROR: No active KDE sessions!" << endl
    00519                          << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
    00520                          << "before calling dcop." << endl;
    00521                     exit( -1 );
    00522                 }
    00523             }
    00524             else if( !sessionName.isEmpty() )
    00525             {
    00526                 if( sessions.contains( sessionName ) )
    00527                 {
    00528                     sessions.clear();
    00529                     sessions.append( sessionName );
    00530                 }
    00531                 else
    00532                 {
    00533                     cerr_ << "ERROR: The specified session doesn't exist!" << endl;
    00534                     exit( -1 );
    00535                 }
    00536             }
    00537             else if( sessions.count() > 1 && session != AllSessions )
    00538             {
    00539                 cerr_ << "ERROR: Multiple available KDE sessions!" << endl
    00540                      << "Please specify the correct session to use with --session or use the" << endl
    00541                      << "--all-sessions option to broadcast to all sessions." << endl;
    00542                 exit( -1 );
    00543             }
    00544         }
    00545
    00546         if( users.count() > 1 || ( users.count() == 1 &&
    00547             ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
    00548         {
    00549             // Check for ICE authority file and if the file can be read by us
    00550             QString home = it.data();
    00551             QString iceFile = it.data() + "/.ICEauthority";
    00552             QFileInfo fi( iceFile );
    00553             if( iceFile.isEmpty() )
    00554             {
    00555                 cerr_ << "WARNING: Cannot determine home directory for user "
    00556                      << it.key() << "!" << endl
    00557                      << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
    00558                      << "calling dcop." << endl;
    00559             }
    00560             else if( fi.exists() )
    00561             {
    00562                 if( fi.isReadable() )
    00563                 {
    00564                     char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
    00565                     putenv( envStr );
    00566                     //cerr_ << "ice: " << envStr << endl;
    00567                 }
    00568                 else
    00569                 {
    00570                     cerr_ << "WARNING: ICE authority file " << iceFile
    00571                          << "is not readable by you!" << endl
    00572                          << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
    00573                          << "calling dcop." << endl;
    00574                 }
    00575             }
    00576             else
    00577             {
    00578                 if( users.count() > 1 )
    00579                     continue;
    00580                 else
    00581                 {
    00582                     cerr_ << "WARNING: Cannot find ICE authority file "
    00583                          << iceFile << "!" << endl
    00584                          << "Please check permissions or set the $ICEAUTHORITY"
    00585                          << " variable manually before" << endl
    00586                          << "calling dcop." << endl;
    00587                 }
    00588             }
    00589         }
    00590
    00591         // Main loop
    00592         // If users is an empty list we're calling for the currently logged
    00593         // in user. In this case we don't have a session, but still want
    00594         // to iterate the loop once.
    00595         QStringList::Iterator sIt = sessions.begin();
    00596         for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
    00597         {
    00598             if( !presetDCOPServer && !users.isEmpty() )
    00599             {
    00600                 QString dcopFile = it.data() + "/" + *sIt;
    00601                 QFile f( dcopFile );
    00602                 if( !f.open( IO_ReadOnly ) )
    00603                 {
    00604                     cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
    00605                     exit( -1 );
    00606                 }
    00607
    00608                 QStringList l( QStringList::split( '\n', f.readAll() ) );
    00609                 dcopServer = l.first();
    00610
    00611                 if( dcopServer.isEmpty() )
    00612                 {
    00613                     cerr_ << "WARNING: Unable to determine DCOP server for session "
    00614                          << *sIt << "!" << endl
    00615                          << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
    00616                          << "calling dcop." << endl;
    00617                     exit( -1 );
    00618                 }
    00619             }
    00620
    00621             delete client;
    00622             client = new DCOPClient;
    00623             if( !dcopServer.isEmpty() )
    00624                 client->setServerAddress( dcopServer.ascii() );
    00625             bool success = client->attach();
    00626             if( !success )
    00627             {
    00628                 cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
    00629                 retval = QMAX( retval, 1 );
    00630                 if( users.isEmpty() )
    00631                     break;
    00632                 else
    00633                     continue;
    00634             }
    00635             dcop = client;
    00636
    00637             int argscount = args.count();
    00638             if ( DCOPrefmode )
    00639               argscount++;
    00640             switch ( argscount )
    00641             {
    00642             case 0:
    00643                 queryApplications("");
    00644                 break;
    00645             case 1:
    00646                 if (endsWith(app, '*'))
    00647                    queryApplications(app);
    00648                 else
    00649                    queryObjects( app, "" );
    00650                 break;
    00651             case 2:
    00652                 if (endsWith(objid, '*'))
    00653                    queryObjects(app, objid);
    00654                 else
    00655                    queryFunctions( app, objid );
    00656                 break;
    00657             case 3:
    00658             default:
    00659                 if( readStdin )
    00660                 {
    00661                     QCStringList::Iterator replaceArg = params.end();
    00662
    00663                     QCStringList::Iterator it;
    00664                     for( it = params.begin(); it != params.end(); it++ )
    00665                         if( *it == "%1" )
    00666                             replaceArg = it;
    00667
    00668                     // Read from stdin until EOF and call function for each
    00669                     // read line
    00670                     while ( !cin_.atEnd() )
    00671                     {
    00672                         QString buf = cin_.readLine();
    00673
    00674                         if( replaceArg != params.end() )
    00675                             *replaceArg = buf.local8Bit();
    00676
    00677                         if( !buf.isNull() )
    00678                         {
    00679                             int res = callFunction( app, objid, function, params );
    00680                             retval = QMAX( retval, res );
    00681                         }
    00682                     }
    00683                 }
    00684                 else
    00685                 {
    00686                     // Just call function
    00687 //                  cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
    00688                     int res = callFunction( app, objid, function, params );
    00689                     retval = QMAX( retval, res );
    00690                 }
    00691                 break;
    00692             }
    00693             // Another sIt++ would make the loop infinite...
    00694             if( users.isEmpty() )
    00695                 break;
    00696         }
    00697
    00698         // Another it++ would make the loop infinite...
    00699         if( it == users.end() )
    00700             break;
    00701     }
    00702
    00703     return retval;
    00704 }
    00705
    00706
    00707 int main( int argc, char** argv )
    00708 {
    00709     bool readStdin = false;
    00710     int numOptions = 0;
    00711     QString user;
    00712     Session session = DefaultSession;
    00713     QString sessionName;
    00714
    00715     cin_.setEncoding( QTextStream::Locale );
    00716
    00717     // Scan for command-line options first
    00718     for( int pos = 1 ; pos <= argc - 1 ; pos++ )
    00719     {
    00720         if( strcmp( argv[ pos ], "--help" ) == 0 )
    00721             showHelp( 0 );
    00722         else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
    00723         {
    00724             readStdin = true;
    00725             numOptions++;
    00726         }
    00727         else if( strcmp( argv[ pos ], "--user" ) == 0 )
    00728         {
    00729             if( pos <= argc - 2 )
    00730             {
    00731                 user = QString::fromLocal8Bit( argv[ pos + 1] );
    00732                 numOptions +=2;
    00733                 pos++;
    00734             }
    00735             else
    00736             {
    00737                 cerr_ << "Missing username for '--user' option!" << endl << endl;
    00738                 showHelp( -1 );
    00739             }
    00740         }
    00741         else if( strcmp( argv[ pos ], "--session" ) == 0 )
    00742         {
    00743             if( session == AllSessions )
    00744             {
    00745                 cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
    00746                 showHelp( -1 );
    00747             }
    00748             else if( pos <= argc - 2 )
    00749             {
    00750                 sessionName = QString::fromLocal8Bit( argv[ pos + 1] );
    00751                 numOptions +=2;
    00752                 pos++;
    00753             }
    00754             else
    00755             {
    00756                 cerr_ << "Missing session name for '--session' option!" << endl << endl;
    00757                 showHelp( -1 );
    00758             }
    00759         }
    00760         else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
    00761         {
    00762             user = "*";
    00763             numOptions ++;
    00764         }
    00765         else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
    00766         {
    00767             session = QuerySessions;
    00768             numOptions ++;
    00769         }
    00770         else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
    00771         {
    00772             if( !sessionName.isEmpty() )
    00773             {
    00774                 cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
    00775                 showHelp( -1 );
    00776             }
    00777             session = AllSessions;
    00778             numOptions ++;
    00779         }
    00780         else if( argv[ pos ][ 0 ] == '-' )
    00781         {
    00782             cerr_ << "Unknown command-line option '" << argv[ pos ]
    00783                  << "'." << endl << endl;
    00784             showHelp( -1 );
    00785         }
    00786         else
    00787             break;      // End of options
    00788     }
    00789
    00790     argc -= numOptions;
    00791
    00792     QCStringList args;
    00793     for( int i = numOptions; i < argc + numOptions - 1; i++ )
    00794         args.append( argv[ i + 1 ] );
    00795
    00796     if( readStdin && args.count() < 3 )
    00797     {
    00798         cerr_ << "--pipe option only supported for function calls!" << endl << endl;
    00799         showHelp( -1 );
    00800     }
    00801
    00802     if( user == "*" && args.count() < 3 && session != QuerySessions )
    00803     {
    00804         cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
    00805         showHelp( -1 );
    00806     }
    00807
    00808     if( session == QuerySessions && !args.isEmpty() )
    00809     {
    00810         cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
    00811         showHelp( -1 );
    00812     }
    00813
    00814     if( session == QuerySessions && user.isEmpty() )
    00815     {
    00816         cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
    00817              << "--all-users options!" << endl << endl;
    00818         showHelp( -1 );
    00819     }
    00820
    00821     if( session != DefaultSession && session != QuerySessions &&
    00822         args.count() < 3 )
    00823     {
    00824         cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
    00825              << "calls!" << endl << endl;
    00826         showHelp( -1 );
    00827     }
    00828
    00829     UserList users;
    00830     if( user == "*" )
    00831         users = userList();
    00832     else if( !user.isEmpty() )
    00833         users[ user ] = userList()[ user ];
    00834
    00835     int retval = runDCOP( args, users, session, sessionName, readStdin );
    00836
    00837     return retval;
    00838 }
    00839
    00840 // vim: set ts=8 sts=4 sw=4 noet:
    00841

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:42:41 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001