00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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;
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
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
00221
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
00236
00237
00238
00239
00240
00241 if ( s > 0 )
00242 {
00243 QStringList partl = QStringList::split(' ' , lt);
00244
00245
00246
00247
00248
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
00511 QString dcopServer;
00512
00513 for( it = users.begin(); it != users.end() || firstRun; ++it )
00514 {
00515 firstRun = false;
00516
00517
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 ) ) )
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
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
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
00638
00639
00640
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
00717
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
00735
00736 int res = callFunction( app, objid, function, params );
00737 retval = QMAX( retval, res );
00738 }
00739 break;
00740 }
00741
00742 if( users.isEmpty() )
00743 break;
00744 }
00745
00746
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
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;
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
00861 if (prog[prog.length()-1] != '*')
00862 {
00863
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
00924