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