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