00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00037
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;
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
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
00204
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
00219
00220
00221
00222
00223
00224 if ( s > 0 )
00225 {
00226 QStringList partl = QStringList::split(' ' , lt);
00227
00228
00229
00230
00231
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 #ifdef DCOPQUIT
00308 cout_ << "Usage: dcopquit [options] [application]" << endl
00309 #else
00310 cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
00311 #endif
00312 << "" << endl
00313 << "Console DCOP client" << endl
00314 << "" << endl
00315 << "Generic options:" << endl
00316 << " --help Show help about options" << endl
00317 << "" << endl
00318 << "Options:" << endl
00319 << " --pipe Call DCOP for each line read from stdin. The string '%1'" << endl
00320 << " will be used in the argument list as a placeholder for" << endl
00321 << " the substituted line." << endl
00322 << " For example," << endl
00323 << " dcop --pipe konqueror html-widget1 evalJS %1" << endl
00324 << " is equivalent to calling" << endl
00325 << " while read line ; do" << endl
00326 << " dcop konqueror html-widget1 evalJS \"$line\"" << endl
00327 << " done" << endl
00328 << " in bash, but because no new dcop instance has to be started" << endl
00329 << " for each line this is generally much faster, especially for" << endl
00330 << " the slower GNU dynamic linkers." << endl
00331 << " The '%1' placeholder cannot be used to replace e.g. the" << endl
00332 << " program, object or method name." << endl
00333 << " --user <user> Connect to the given user's DCOP server. This option will" << endl
00334 << " ignore the values of the environment vars $DCOPSERVER and" << endl
00335 << " $ICEAUTHORITY, even if they are set." << endl
00336 << " If the user has more than one open session, you must also" << endl
00337 << " use one of the --list-sessions, --session or --all-sessions" << endl
00338 << " command-line options." << endl
00339 << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
00340 << " server. Only failed calls to existing DCOP servers will" << endl
00341 << " generate an error message. If no DCOP server is available" << endl
00342 << " at all, no error will be generated." << endl
00343 << " --session <ses> Send to the given KDE session. This option can only be" << endl
00344 << " used in combination with the --user option." << endl
00345 << " --all-sessions Send to all sessions found. Only works with the --user" << endl
00346 << " and --all-users options." << endl
00347 << " --list-sessions List all active KDE session for a user or all users." << endl
00348 << endl;
00349
00350 exit( exitCode );
00351 }
00352
00357 static UserList userList()
00358 {
00359 UserList result;
00360
00361 QFile f( "/etc/passwd" );
00362
00363 if( !f.open( IO_ReadOnly ) )
00364 {
00365 cerr_ << "Can't open /etc/passwd for reading!" << endl;
00366 return result;
00367 }
00368
00369 QStringList l( QStringList::split( '\n', f.readAll() ) );
00370
00371 for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
00372 {
00373 QStringList userInfo( QStringList::split( ':', *it, true ) );
00374 result[ userInfo[ 0 ] ] = userInfo[ 5 ];
00375 }
00376
00377 return result;
00378 }
00379
00384 QStringList dcopSessionList( const QString &user, const QString &home )
00385 {
00386 if( home.isEmpty() )
00387 {
00388 cerr_ << "WARNING: Cannot determine home directory for user "
00389 << user << "!" << endl
00390 << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00391 << "calling dcop." << endl;
00392 return QStringList();
00393 }
00394
00395 QStringList result;
00396 QFileInfo dirInfo( home );
00397 if( !dirInfo.exists() || !dirInfo.isReadable() )
00398 return result;
00399
00400 QDir d( home );
00401 d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
00402 d.setNameFilter( ".DCOPserver*" );
00403
00404 const QFileInfoList *list = d.entryInfoList();
00405 if( !list )
00406 return result;
00407
00408 QFileInfoListIterator it( *list );
00409 QFileInfo *fi;
00410
00411 while ( ( fi = it.current() ) != 0 )
00412 {
00413 if( fi->isReadable() )
00414 result.append( fi->fileName() );
00415 ++it;
00416 }
00417 return result;
00418 }
00419
00423 int runDCOP( QCStringList args, UserList users, Session session,
00424 const QString sessionName, bool readStdin )
00425 {
00426 bool DCOPrefmode=false;
00427 QCString app;
00428 QCString objid;
00429 QCString function;
00430 QCStringList params;
00431 DCOPClient *client = 0L;
00432 int retval = 0;
00433 if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
00434 {
00435 int delimPos = args[ 0 ].findRev( ',' );
00436 if( delimPos == -1 )
00437 {
00438 cerr_ << "Error: '" << args[ 0 ]
00439 << "' is not a valid DCOP reference." << endl;
00440 exit( -1 );
00441 }
00442 app = args[ 0 ].mid( 8, delimPos-8 );
00443 delimPos++;
00444 objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
00445 if( args.count() > 1 )
00446 function = args[ 1 ];
00447 if( args.count() > 2 )
00448 {
00449 params = args;
00450 params.remove( params.begin() );
00451 params.remove( params.begin() );
00452 }
00453 DCOPrefmode=true;
00454 }
00455 else
00456 {
00457 if( !args.isEmpty() )
00458 app = args[ 0 ];
00459 if( args.count() > 1 )
00460 objid = args[ 1 ];
00461 if( args.count() > 2 )
00462 function = args[ 2 ];
00463 if( args.count() > 3)
00464 {
00465 params = args;
00466 params.remove( params.begin() );
00467 params.remove( params.begin() );
00468 params.remove( params.begin() );
00469 }
00470 }
00471
00472 bool firstRun = true;
00473 UserList::Iterator it;
00474 QStringList sessions;
00475 bool presetDCOPServer = false;
00476
00477 QString dcopServer;
00478
00479 for( it = users.begin(); it != users.end() || firstRun; ++it )
00480 {
00481 firstRun = false;
00482
00483
00484
00485 if( session == QuerySessions )
00486 {
00487 QStringList sessions = dcopSessionList( it.key(), it.data() );
00488 if( sessions.isEmpty() )
00489 {
00490 if( users.count() <= 1 )
00491 {
00492 cout_ << "No active sessions";
00493 if( !( *it ).isEmpty() )
00494 cout_ << " for user " << *it;
00495 cout_ << endl;
00496 }
00497 }
00498 else
00499 {
00500 cout_ << "Active sessions ";
00501 if( !( *it ).isEmpty() )
00502 cout_ << "for user " << *it << " ";
00503 cout_ << ":" << endl;
00504
00505 QStringList::Iterator sIt = sessions.begin();
00506 for( ; sIt != sessions.end(); ++sIt )
00507 cout_ << " " << *sIt << endl;
00508
00509 cout_ << endl;
00510 }
00511 continue;
00512 }
00513
00514 if( getenv( "DCOPSERVER" ) )
00515 {
00516 sessions.append( getenv( "DCOPSERVER" ) );
00517 presetDCOPServer = true;
00518 }
00519
00520 if( users.count() > 1 || ( users.count() == 1 &&
00521 ( getenv( "DCOPSERVER" ) == 0 ) ) )
00522 {
00523 sessions = dcopSessionList( it.key(), it.data() );
00524 if( sessions.isEmpty() )
00525 {
00526 if( users.count() > 1 )
00527 continue;
00528 else
00529 {
00530 cerr_ << "ERROR: No active KDE sessions!" << endl
00531 << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
00532 << "before calling dcop." << endl;
00533 exit( -1 );
00534 }
00535 }
00536 else if( !sessionName.isEmpty() )
00537 {
00538 if( sessions.contains( sessionName ) )
00539 {
00540 sessions.clear();
00541 sessions.append( sessionName );
00542 }
00543 else
00544 {
00545 cerr_ << "ERROR: The specified session doesn't exist!" << endl;
00546 exit( -1 );
00547 }
00548 }
00549 else if( sessions.count() > 1 && session != AllSessions )
00550 {
00551 cerr_ << "ERROR: Multiple available KDE sessions!" << endl
00552 << "Please specify the correct session to use with --session or use the" << endl
00553 << "--all-sessions option to broadcast to all sessions." << endl;
00554 exit( -1 );
00555 }
00556 }
00557
00558 if( users.count() > 1 || ( users.count() == 1 &&
00559 ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
00560 {
00561
00562 QString home = it.data();
00563 QString iceFile = it.data() + "/.ICEauthority";
00564 QFileInfo fi( iceFile );
00565 if( iceFile.isEmpty() )
00566 {
00567 cerr_ << "WARNING: Cannot determine home directory for user "
00568 << it.key() << "!" << endl
00569 << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00570 << "calling dcop." << endl;
00571 }
00572 else if( fi.exists() )
00573 {
00574 if( fi.isReadable() )
00575 {
00576 char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
00577 putenv( envStr );
00578
00579 }
00580 else
00581 {
00582 cerr_ << "WARNING: ICE authority file " << iceFile
00583 << "is not readable by you!" << endl
00584 << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00585 << "calling dcop." << endl;
00586 }
00587 }
00588 else
00589 {
00590 if( users.count() > 1 )
00591 continue;
00592 else
00593 {
00594 cerr_ << "WARNING: Cannot find ICE authority file "
00595 << iceFile << "!" << endl
00596 << "Please check permissions or set the $ICEAUTHORITY"
00597 << " variable manually before" << endl
00598 << "calling dcop." << endl;
00599 }
00600 }
00601 }
00602
00603
00604
00605
00606
00607 QStringList::Iterator sIt = sessions.begin();
00608 for( ; sIt != sessions.end() || users.isEmpty(); ++sIt )
00609 {
00610 if( !presetDCOPServer && !users.isEmpty() )
00611 {
00612 QString dcopFile = it.data() + "/" + *sIt;
00613 QFile f( dcopFile );
00614 if( !f.open( IO_ReadOnly ) )
00615 {
00616 cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
00617 exit( -1 );
00618 }
00619
00620 QStringList l( QStringList::split( '\n', f.readAll() ) );
00621 dcopServer = l.first();
00622
00623 if( dcopServer.isEmpty() )
00624 {
00625 cerr_ << "WARNING: Unable to determine DCOP server for session "
00626 << *sIt << "!" << endl
00627 << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00628 << "calling dcop." << endl;
00629 exit( -1 );
00630 }
00631 }
00632
00633 delete client;
00634 client = new DCOPClient;
00635 if( !dcopServer.isEmpty() )
00636 client->setServerAddress( dcopServer.ascii() );
00637 bool success = client->attach();
00638 if( !success )
00639 {
00640 cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
00641 retval = QMAX( retval, 1 );
00642 if( users.isEmpty() )
00643 break;
00644 else
00645 continue;
00646 }
00647 dcop = client;
00648
00649 int argscount = args.count();
00650 if ( DCOPrefmode )
00651 argscount++;
00652 switch ( argscount )
00653 {
00654 case 0:
00655 queryApplications("");
00656 break;
00657 case 1:
00658 if (endsWith(app, '*'))
00659 queryApplications(app);
00660 else
00661 queryObjects( app, "" );
00662 break;
00663 case 2:
00664 if (endsWith(objid, '*'))
00665 queryObjects(app, objid);
00666 else
00667 queryFunctions( app, objid );
00668 break;
00669 case 3:
00670 default:
00671 if( readStdin )
00672 {
00673 QCStringList::Iterator replaceArg = params.end();
00674
00675 QCStringList::Iterator it = params.begin();
00676 for( ; it != params.end(); ++it )
00677 if( *it == "%1" )
00678 replaceArg = it;
00679
00680
00681
00682 while ( !cin_.atEnd() )
00683 {
00684 QString buf = cin_.readLine();
00685
00686 if( replaceArg != params.end() )
00687 *replaceArg = buf.local8Bit();
00688
00689 if( !buf.isNull() )
00690 {
00691 int res = callFunction( app, objid, function, params );
00692 retval = QMAX( retval, res );
00693 }
00694 }
00695 }
00696 else
00697 {
00698
00699
00700 int res = callFunction( app, objid, function, params );
00701 retval = QMAX( retval, res );
00702 }
00703 break;
00704 }
00705
00706 if( users.isEmpty() )
00707 break;
00708 }
00709
00710
00711 if( it == users.end() )
00712 break;
00713 }
00714
00715 return retval;
00716 }
00717
00718
00719 int main( int argc, char** argv )
00720 {
00721 bool readStdin = false;
00722 int numOptions = 0;
00723 QString user;
00724 Session session = DefaultSession;
00725 QString sessionName;
00726
00727 cin_.setEncoding( QTextStream::Locale );
00728
00729
00730 for( int pos = 1 ; pos <= argc - 1 ; pos++ )
00731 {
00732 if( strcmp( argv[ pos ], "--help" ) == 0 )
00733 showHelp( 0 );
00734 else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
00735 {
00736 readStdin = true;
00737 numOptions++;
00738 }
00739 else if( strcmp( argv[ pos ], "--user" ) == 0 )
00740 {
00741 if( pos <= argc - 2 )
00742 {
00743 user = QString::fromLocal8Bit( argv[ pos + 1] );
00744 numOptions +=2;
00745 pos++;
00746 }
00747 else
00748 {
00749 cerr_ << "Missing username for '--user' option!" << endl << endl;
00750 showHelp( -1 );
00751 }
00752 }
00753 else if( strcmp( argv[ pos ], "--session" ) == 0 )
00754 {
00755 if( session == AllSessions )
00756 {
00757 cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00758 showHelp( -1 );
00759 }
00760 else if( pos <= argc - 2 )
00761 {
00762 sessionName = QString::fromLocal8Bit( argv[ pos + 1] );
00763 numOptions +=2;
00764 pos++;
00765 }
00766 else
00767 {
00768 cerr_ << "Missing session name for '--session' option!" << endl << endl;
00769 showHelp( -1 );
00770 }
00771 }
00772 else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
00773 {
00774 user = "*";
00775 numOptions ++;
00776 }
00777 else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
00778 {
00779 session = QuerySessions;
00780 numOptions ++;
00781 }
00782 else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
00783 {
00784 if( !sessionName.isEmpty() )
00785 {
00786 cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00787 showHelp( -1 );
00788 }
00789 session = AllSessions;
00790 numOptions ++;
00791 }
00792 else if( argv[ pos ][ 0 ] == '-' )
00793 {
00794 cerr_ << "Unknown command-line option '" << argv[ pos ]
00795 << "'." << endl << endl;
00796 showHelp( -1 );
00797 }
00798 else
00799 break;
00800 }
00801
00802 argc -= numOptions;
00803
00804 QCStringList args;
00805
00806 #ifdef DCOPQUIT
00807 if (argc > 1)
00808 {
00809 QCString prog = argv[ numOptions + 1 ];
00810
00811 if (!prog.isEmpty())
00812 {
00813 args.append( prog );
00814
00815
00816 if (prog[prog.length()-1] != '*')
00817 {
00818
00819 int i = prog.findRev('-');
00820 if ((i >= 0) && prog.mid(i+1).toLong())
00821 {
00822 prog = prog.left(i);
00823 }
00824 args.append( "qt/"+prog );
00825 args.append( "quit()" );
00826 }
00827 }
00828 }
00829 #else
00830 for( int i = numOptions; i < argc + numOptions - 1; i++ )
00831 args.append( argv[ i + 1 ] );
00832 #endif
00833
00834 if( readStdin && args.count() < 3 )
00835 {
00836 cerr_ << "--pipe option only supported for function calls!" << endl << endl;
00837 showHelp( -1 );
00838 }
00839
00840 if( user == "*" && args.count() < 3 && session != QuerySessions )
00841 {
00842 cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
00843 showHelp( -1 );
00844 }
00845
00846 if( session == QuerySessions && !args.isEmpty() )
00847 {
00848 cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
00849 showHelp( -1 );
00850 }
00851
00852 if( session == QuerySessions && user.isEmpty() )
00853 {
00854 cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
00855 << "--all-users options!" << endl << endl;
00856 showHelp( -1 );
00857 }
00858
00859 if( session != DefaultSession && session != QuerySessions &&
00860 args.count() < 3 )
00861 {
00862 cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
00863 << "calls!" << endl << endl;
00864 showHelp( -1 );
00865 }
00866
00867 UserList users;
00868 if( user == "*" )
00869 users = userList();
00870 else if( !user.isEmpty() )
00871 users[ user ] = userList()[ user ];
00872
00873 int retval = runDCOP( args, users, session, sessionName, readStdin );
00874
00875 return retval;
00876 }
00877
00878
00879