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