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