dcop Library API Documentation

dcop.cpp

00001 /*****************************************************************
00002 Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00017 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00018 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00019 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00020 
00021 ******************************************************************/
00022 
00023 #include <ctype.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 
00027 #include <qcolor.h>
00028 #include <qdir.h>
00029 #include <qfile.h>
00030 #include <qfileinfo.h>
00031 #include <qmap.h>
00032 #include <qstringlist.h>
00033 #include <qtextstream.h>
00034 #include <qvariant.h>
00035 
00036 // putenv() is not available on all platforms, so make sure the emulation
00037 // wrapper is available in those cases by loading config.h!
00038 #include <config.h>
00039 
00040 #include "../dcopclient.h"
00041 #include "../dcopref.h"
00042 #include "../kdatastream.h"
00043 
00044 #include "marshall.cpp"
00045 
00046 typedef QMap<QString, QString> UserList;
00047 
00048 static DCOPClient* dcop = 0;
00049 
00050 static QTextStream cin_ ( stdin,  IO_ReadOnly );
00051 static QTextStream cout_( stdout, IO_WriteOnly );
00052 static QTextStream cerr_( stderr, IO_WriteOnly );
00053 
00063 enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
00064 
00065 bool startsWith(const QCString &id, const char *str, int n)
00066 {
00067   return !n || (strncmp(id.data(), str, n) == 0);
00068 }
00069 
00070 bool endsWith(QCString &id, char c)
00071 {
00072    if (id.length() && (id[id.length()-1] == c))
00073    {
00074       id.truncate(id.length()-1);
00075       return true;
00076    }
00077    return false;
00078 }
00079 
00080 void queryApplications(const QCString &filter)
00081 {
00082     int filterLen = filter.length();
00083     QCStringList apps = dcop->registeredApplications();
00084     for ( QCStringList::Iterator it = apps.begin(); it != apps.end(); ++it )
00085     {
00086         QCString &clientId = *it;
00087         if ( (clientId != dcop->appId()) &&
00088              !startsWith(clientId, "anonymous",9) &&
00089              startsWith(clientId, filter, filterLen)
00090            )
00091             printf( "%s\n", clientId.data() );
00092     }
00093 
00094     if ( !dcop->isAttached() )
00095     {
00096         qWarning( "server not accessible" );
00097         exit(1);
00098     }
00099 }
00100 
00101 void queryObjects( const QCString &app, const QCString &filter )
00102 {
00103     int filterLen = filter.length();
00104     bool ok = false;
00105     bool isDefault = false;
00106     QCStringList objs = dcop->remoteObjects( app, &ok );
00107     for ( QCStringList::Iterator it = objs.begin(); it != objs.end(); ++it )
00108     {
00109         QCString &objId = *it;
00110 
00111         if (objId == "default")
00112         {
00113            isDefault = true;
00114            continue;
00115         }
00116 
00117         if (startsWith(objId, filter, filterLen))
00118         {
00119             if (isDefault)
00120                 printf( "%s (default)\n", objId.data() );
00121             else
00122                 printf( "%s\n", objId.data() );
00123         }
00124         isDefault = false;
00125     }
00126     if ( !ok )
00127     {
00128         if (!dcop->isApplicationRegistered(app))
00129             qWarning( "No such application: '%s'", app.data());
00130         else
00131             qWarning( "Application '%s' not accessible", app.data() );
00132         exit(1);
00133     }
00134 }
00135 
00136 void queryFunctions( const char* app, const char* obj )
00137 {
00138     bool ok = false;
00139     QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
00140     for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
00141         printf( "%s\n", (*it).data() );
00142     }
00143     if ( !ok )
00144     {
00145         qWarning( "object '%s' in application '%s' not accessible", obj, app );
00146         exit( 1 );
00147     }
00148 }
00149 
00150 int callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
00151 {
00152     QString f = func; // Qt is better with unicode strings, so use one.
00153     int left = f.find( '(' );
00154     int right = f.find( ')' );
00155 
00156     if ( right <  left )
00157     {
00158         qWarning( "parentheses do not match" );
00159         return( 1 );
00160     }
00161 
00162     if ( left < 0 ) {
00163         // try to get the interface from the server
00164         bool ok = false;
00165         QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
00166         QCString realfunc;
00167         if ( !ok && args.isEmpty() )
00168             goto doit;
00169         if ( !ok )
00170         {
00171             qWarning( "object not accessible" );
00172             return( 1 );
00173         }
00174         for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
00175             int l = (*it).find( '(' );
00176             int s = (*it).find( ' ');
00177             if ( s < 0 )
00178                 s = 0;
00179             else
00180                 s++;
00181 
00182             if ( l > 0 && (*it).mid( s, l - s ) == func ) {
00183                 realfunc = (*it).mid( s );
00184                 uint a = (*it).contains(',');
00185                 if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
00186                     break;
00187             }
00188         }
00189         if ( realfunc.isEmpty() )
00190         {
00191             qWarning("no such function");
00192             return( 1 );
00193         }
00194         f = realfunc;
00195         left = f.find( '(' );
00196         right = f.find( ')' );
00197     }
00198 
00199  doit:
00200     if ( left < 0 )
00201         f += "()";
00202 
00203     // This may seem expensive but is done only once per invocation
00204     // of dcop, so it should be OK.
00205     //
00206     //
00207     QStringList intTypes;
00208     intTypes << "int" << "unsigned" << "long" << "bool" ;
00209 
00210     QStringList types;
00211     if ( left >0 && left + 1 < right - 1) {
00212         types = QStringList::split( ',', f.mid( left + 1, right - left - 1) );
00213         for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
00214             QString lt = (*it).simplifyWhiteSpace();
00215 
00216             int s = lt.find(' ');
00217 
00218             // If there are spaces in the name, there may be two
00219             // reasons: the parameter name is still there, ie.
00220             // "QString URL" or it's a complicated int type, ie.
00221             // "unsigned long long int bool".
00222             //
00223             //
00224             if ( s > 0 )
00225             {
00226                 QStringList partl = QStringList::split(' ' , lt);
00227 
00228                 // The zero'th part is -- at the very least -- a
00229                 // type part. Any trailing parts *might* be extra
00230                 // int-type keywords, or at most one may be the
00231                 // parameter name.
00232                 //
00233                 //
00234                 s=1;
00235 
00236                 while (s < static_cast<int>(partl.count()) && intTypes.contains(partl[s]))
00237                 {
00238                         s++;
00239                 }
00240 
00241                 if ( s < static_cast<int>(partl.count())-1)
00242                 {
00243                         qWarning("The argument `%s' seems syntactically wrong.",
00244                                 lt.latin1());
00245                 }
00246                 if ( s == static_cast<int>(partl.count())-1)
00247                 {
00248                         partl.remove(partl.at(s));
00249                 }
00250 
00251                 lt = partl.join(" ");
00252                 lt = lt.simplifyWhiteSpace();
00253             }
00254 
00255             (*it) = lt;
00256         }
00257         QString fc = f.left( left );
00258         fc += '(';
00259         bool first = TRUE;
00260         for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
00261             if ( !first )
00262                 fc +=",";
00263             first = FALSE;
00264             fc += *it;
00265         }
00266         fc += ')';
00267         f = fc;
00268     }
00269 
00270     QByteArray data, replyData;
00271     QCString replyType;
00272     QDataStream arg(data, IO_WriteOnly);
00273 
00274     uint i = 0;
00275     for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
00276         marshall( arg, args, i, *it );
00277 
00278     if ( i != args.count() )
00279     {
00280         qWarning( "arguments do not match" );
00281         return( 1 );
00282     }
00283 
00284     if ( !dcop->call( app, obj, f.latin1(),  data, replyType, replyData) ) {
00285         qWarning( "call failed");
00286         return( 1 );
00287     } else {
00288         QDataStream reply(replyData, IO_ReadOnly);
00289 
00290         if ( replyType != "void" && replyType != "ASYNC" )
00291         {
00292             QCString replyString = demarshal( reply, replyType );
00293             if ( !replyString.isEmpty() )
00294             printf( "%s\n", replyString.data() );
00295             else
00296                 printf("\n");
00297         }
00298     }
00299     return 0;
00300 }
00301 
00305 void showHelp( int exitCode = 0 )
00306 {
00307     cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
00308          << "" << endl
00309          << "Console DCOP client" << endl
00310          << "" << endl
00311          << "Generic options:" << endl
00312          << "  --help          Show help about options" << endl
00313          << "" << endl
00314          << "Options:" << endl
00315          << "  --pipe          Call DCOP for each line read from stdin" << endl
00316          << "                  This is roughly equivalent to calling" << endl
00317          << "                      'while read line ; do dcop $line ; done'" << endl
00318          << "                  but because no new dcop instance has to be started for" << endl
00319          << "                  each line this is generally much faster, especially" << endl
00320          << "                  for the slower GNU dynamic linkers." << endl
00321          << "  --user <user>   Connect to the given user's DCOP server. This option will" << endl
00322          << "                  ignore the values of the environment vars $DCOPSERVER and" << endl
00323          << "                  $ICEAUTHORITY, even if they are set." << endl
00324          << "                  If the user has more than one open session, you must also" << endl
00325          << "                  use one of the --list-sessions, --session or --all-sessions" << endl
00326          << "                  command-line options." << endl
00327          << "  --all-users     Send the same DCOP call to all users with a running DCOP" << endl
00328          << "                  server. Only failed calls to existing DCOP servers will" << endl
00329          << "                  generate an error message. If no DCOP server is available" << endl
00330          << "                  at all, no error will be generated." << endl
00331          << "  --session <ses> Send to the given KDE session. This option can only be" << endl
00332          << "                  used in combination with the --user option." << endl
00333          << "  --all-sessions  Send to all sessions found. Only works with the --user" << endl
00334          << "                  and --all-users options." << endl
00335          << "  --list-sessions List all active KDE session for a user or all users." << endl
00336          << endl;
00337 
00338     exit( exitCode );
00339 }
00340 
00345 static UserList userList()
00346 {
00347     UserList result;
00348 
00349     QFile f( "/etc/passwd" );
00350 
00351     if( !f.open( IO_ReadOnly ) )
00352     {
00353         cerr_ << "Can't open /etc/passwd for reading!" << endl;
00354         return result;
00355     }
00356 
00357     QStringList l( QStringList::split( '\n', f.readAll() ) );
00358 
00359     for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
00360     {
00361         QStringList userInfo( QStringList::split( ':', *it, true ) );
00362         result[ userInfo[ 0 ] ] = userInfo[ 5 ];
00363     }
00364 
00365     return result;
00366 }
00367 
00372 QStringList dcopSessionList( const QString &user, const QString &home )
00373 {
00374     if( home.isEmpty() )
00375     {
00376         cerr_ << "WARNING: Cannot determine home directory for user "
00377              << user << "!" << endl
00378              << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00379              << "calling dcop." << endl;
00380         return QStringList();
00381     }
00382 
00383     QStringList result;
00384     QFileInfo dirInfo( home );
00385     if( !dirInfo.exists() || !dirInfo.isReadable() )
00386         return result;
00387 
00388     QDir d( home );
00389     d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
00390     d.setNameFilter( ".DCOPserver*" );
00391 
00392     const QFileInfoList *list = d.entryInfoList();
00393     if( !list )
00394         return result;
00395 
00396     QFileInfoListIterator it( *list );
00397     QFileInfo *fi;
00398 
00399     while ( ( fi = it.current() ) != 0 )
00400     {
00401         if( fi->isReadable() )
00402             result.append( fi->fileName() );
00403         ++it;
00404     }
00405     return result;
00406 }
00407 
00411 int runDCOP( QCStringList args, UserList users, Session session,
00412               const QString sessionName, bool readStdin )
00413 {
00414     bool DCOPrefmode=false;
00415     QCString app;
00416     QCString objid;
00417     QCString function;
00418     QCStringList params;
00419     DCOPClient *client = 0L;
00420     int retval = 0;
00421     if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
00422     {
00423         int delimPos = args[ 0 ].findRev( ',' );
00424         if( delimPos == -1 )
00425         {
00426             cerr_ << "Error: '" << args[ 0 ]
00427                  << "' is not a valid DCOP reference." << endl;
00428             exit( -1 );
00429         }
00430         app = args[ 0 ].mid( 8, delimPos-8 );
00431         delimPos++;
00432         objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
00433         if( args.count() > 1 )
00434             function = args[ 1 ];
00435         if( args.count() > 2 )
00436         {
00437             params = args;
00438             params.remove( params.begin() );
00439             params.remove( params.begin() );
00440         }
00441         DCOPrefmode=true;
00442     }
00443     else
00444     {
00445         if( !args.isEmpty() )
00446             app = args[ 0 ];
00447         if( args.count() > 1 )
00448             objid = args[ 1 ];
00449         if( args.count() > 2 )
00450             function = args[ 2 ];
00451         if( args.count() > 3)
00452         {
00453             params = args;
00454             params.remove( params.begin() );
00455             params.remove( params.begin() );
00456             params.remove( params.begin() );
00457         }
00458     }
00459 
00460     bool firstRun = true;
00461     UserList::Iterator it;
00462     QStringList sessions;
00463     bool presetDCOPServer = false;
00464 //    char *dcopStr = 0L;
00465     QString dcopServer;
00466 
00467     for( it = users.begin(); it != users.end() || firstRun; it++ )
00468     {
00469         firstRun = false;
00470 
00471         //cout_ << "Iterating '" << it.key() << "'" << endl;
00472 
00473         if( session == QuerySessions )
00474         {
00475             QStringList sessions = dcopSessionList( it.key(), it.data() );
00476             if( sessions.isEmpty() )
00477             {
00478                 if( users.count() <= 1 )
00479                 {
00480                     cout_ << "No active sessions";
00481                     if( !( *it ).isEmpty() )
00482                         cout_ << " for user " << *it;
00483                     cout_ << endl;
00484                 }
00485             }
00486             else
00487             {
00488                 cout_ << "Active sessions ";
00489                 if( !( *it ).isEmpty() )
00490                     cout_ << "for user " << *it << " ";
00491                 cout_ << ":" << endl;
00492 
00493                 QStringList::Iterator sIt;
00494                 for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
00495                     cout_ << "  " << *sIt << endl;
00496 
00497                 cout_ << endl;
00498             }
00499             continue;
00500         }
00501 
00502         if( getenv( "DCOPSERVER" ) )
00503         {
00504             sessions.append( getenv( "DCOPSERVER" ) );
00505             presetDCOPServer = true;
00506         }
00507 
00508         if( users.count() > 1 || ( users.count() == 1 &&
00509             ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
00510         {
00511             sessions = dcopSessionList( it.key(), it.data() );
00512             if( sessions.isEmpty() )
00513             {
00514                 if( users.count() > 1 )
00515                     continue;
00516                 else
00517                 {
00518                     cerr_ << "ERROR: No active KDE sessions!" << endl
00519                          << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
00520                          << "before calling dcop." << endl;
00521                     exit( -1 );
00522                 }
00523             }
00524             else if( !sessionName.isEmpty() )
00525             {
00526                 if( sessions.contains( sessionName ) )
00527                 {
00528                     sessions.clear();
00529                     sessions.append( sessionName );
00530                 }
00531                 else
00532                 {
00533                     cerr_ << "ERROR: The specified session doesn't exist!" << endl;
00534                     exit( -1 );
00535                 }
00536             }
00537             else if( sessions.count() > 1 && session != AllSessions )
00538             {
00539                 cerr_ << "ERROR: Multiple available KDE sessions!" << endl
00540                      << "Please specify the correct session to use with --session or use the" << endl
00541                      << "--all-sessions option to broadcast to all sessions." << endl;
00542                 exit( -1 );
00543             }
00544         }
00545 
00546         if( users.count() > 1 || ( users.count() == 1 &&
00547             ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
00548         {
00549             // Check for ICE authority file and if the file can be read by us
00550             QString home = it.data();
00551             QString iceFile = it.data() + "/.ICEauthority";
00552             QFileInfo fi( iceFile );
00553             if( iceFile.isEmpty() )
00554             {
00555                 cerr_ << "WARNING: Cannot determine home directory for user "
00556                      << it.key() << "!" << endl
00557                      << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00558                      << "calling dcop." << endl;
00559             }
00560             else if( fi.exists() )
00561             {
00562                 if( fi.isReadable() )
00563                 {
00564                     char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
00565                     putenv( envStr );
00566                     //cerr_ << "ice: " << envStr << endl;
00567                 }
00568                 else
00569                 {
00570                     cerr_ << "WARNING: ICE authority file " << iceFile
00571                          << "is not readable by you!" << endl
00572                          << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00573                          << "calling dcop." << endl;
00574                 }
00575             }
00576             else
00577             {
00578                 if( users.count() > 1 )
00579                     continue;
00580                 else
00581                 {
00582                     cerr_ << "WARNING: Cannot find ICE authority file "
00583                          << iceFile << "!" << endl
00584                          << "Please check permissions or set the $ICEAUTHORITY"
00585                          << " variable manually before" << endl
00586                          << "calling dcop." << endl;
00587                 }
00588             }
00589         }
00590 
00591         // Main loop
00592         // If users is an empty list we're calling for the currently logged
00593         // in user. In this case we don't have a session, but still want
00594         // to iterate the loop once.
00595         QStringList::Iterator sIt = sessions.begin();
00596         for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
00597         {
00598             if( !presetDCOPServer && !users.isEmpty() )
00599             {
00600                 QString dcopFile = it.data() + "/" + *sIt;
00601                 QFile f( dcopFile );
00602                 if( !f.open( IO_ReadOnly ) )
00603                 {
00604                     cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
00605                     exit( -1 );
00606                 }
00607 
00608                 QStringList l( QStringList::split( '\n', f.readAll() ) );
00609                 dcopServer = l.first();
00610 
00611                 if( dcopServer.isEmpty() )
00612                 {
00613                     cerr_ << "WARNING: Unable to determine DCOP server for session "
00614                          << *sIt << "!" << endl
00615                          << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00616                          << "calling dcop." << endl;
00617                     exit( -1 );
00618                 }
00619             }
00620 
00621             delete client;
00622             client = new DCOPClient;
00623             if( !dcopServer.isEmpty() )
00624                 client->setServerAddress( dcopServer.ascii() );
00625             bool success = client->attach();
00626             if( !success )
00627             {
00628                 cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
00629                 retval = QMAX( retval, 1 );
00630                 if( users.isEmpty() )
00631                     break;
00632                 else
00633                     continue;
00634             }
00635             dcop = client;
00636 
00637             int argscount = args.count();
00638             if ( DCOPrefmode )
00639               argscount++;
00640             switch ( argscount )
00641             {
00642             case 0:
00643                 queryApplications("");
00644                 break;
00645             case 1:
00646                 if (endsWith(app, '*'))
00647                    queryApplications(app);
00648                 else
00649                    queryObjects( app, "" );
00650                 break;
00651             case 2:
00652                 if (endsWith(objid, '*'))
00653                    queryObjects(app, objid);
00654                 else
00655                    queryFunctions( app, objid );
00656                 break;
00657             case 3:
00658             default:
00659                 if( readStdin )
00660                 {
00661                     QCStringList::Iterator replaceArg = params.end();
00662 
00663                     QCStringList::Iterator it;
00664                     for( it = params.begin(); it != params.end(); it++ )
00665                         if( *it == "%1" )
00666                             replaceArg = it;
00667 
00668                     // Read from stdin until EOF and call function for each
00669                     // read line
00670                     while ( !cin_.atEnd() )
00671                     {
00672                         QString buf = cin_.readLine();
00673 
00674                         if( replaceArg != params.end() )
00675                             *replaceArg = buf.local8Bit();
00676 
00677                         if( !buf.isNull() )
00678                         {
00679                             int res = callFunction( app, objid, function, params );
00680                             retval = QMAX( retval, res );
00681                         }
00682                     }
00683                 }
00684                 else
00685                 {
00686                     // Just call function
00687 //                  cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
00688                     int res = callFunction( app, objid, function, params );
00689                     retval = QMAX( retval, res );
00690                 }
00691                 break;
00692             }
00693             // Another sIt++ would make the loop infinite...
00694             if( users.isEmpty() )
00695                 break;
00696         }
00697 
00698         // Another it++ would make the loop infinite...
00699         if( it == users.end() )
00700             break;
00701     }
00702 
00703     return retval;
00704 }
00705 
00706 
00707 int main( int argc, char** argv )
00708 {
00709     bool readStdin = false;
00710     int numOptions = 0;
00711     QString user;
00712     Session session = DefaultSession;
00713     QString sessionName;
00714 
00715     cin_.setEncoding( QTextStream::Locale );
00716 
00717     // Scan for command-line options first
00718     for( int pos = 1 ; pos <= argc - 1 ; pos++ )
00719     {
00720         if( strcmp( argv[ pos ], "--help" ) == 0 )
00721             showHelp( 0 );
00722         else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
00723         {
00724             readStdin = true;
00725             numOptions++;
00726         }
00727         else if( strcmp( argv[ pos ], "--user" ) == 0 )
00728         {
00729             if( pos <= argc - 2 )
00730             {
00731                 user = QString::fromLocal8Bit( argv[ pos + 1] );
00732                 numOptions +=2;
00733                 pos++;
00734             }
00735             else
00736             {
00737                 cerr_ << "Missing username for '--user' option!" << endl << endl;
00738                 showHelp( -1 );
00739             }
00740         }
00741         else if( strcmp( argv[ pos ], "--session" ) == 0 )
00742         {
00743             if( session == AllSessions )
00744             {
00745                 cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00746                 showHelp( -1 );
00747             }
00748             else if( pos <= argc - 2 )
00749             {
00750                 sessionName = QString::fromLocal8Bit( argv[ pos + 1] );
00751                 numOptions +=2;
00752                 pos++;
00753             }
00754             else
00755             {
00756                 cerr_ << "Missing session name for '--session' option!" << endl << endl;
00757                 showHelp( -1 );
00758             }
00759         }
00760         else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
00761         {
00762             user = "*";
00763             numOptions ++;
00764         }
00765         else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
00766         {
00767             session = QuerySessions;
00768             numOptions ++;
00769         }
00770         else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
00771         {
00772             if( !sessionName.isEmpty() )
00773             {
00774                 cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00775                 showHelp( -1 );
00776             }
00777             session = AllSessions;
00778             numOptions ++;
00779         }
00780         else if( argv[ pos ][ 0 ] == '-' )
00781         {
00782             cerr_ << "Unknown command-line option '" << argv[ pos ]
00783                  << "'." << endl << endl;
00784             showHelp( -1 );
00785         }
00786         else
00787             break;      // End of options
00788     }
00789 
00790     argc -= numOptions;
00791 
00792     QCStringList args;
00793     for( int i = numOptions; i < argc + numOptions - 1; i++ )
00794         args.append( argv[ i + 1 ] );
00795 
00796     if( readStdin && args.count() < 3 )
00797     {
00798         cerr_ << "--pipe option only supported for function calls!" << endl << endl;
00799         showHelp( -1 );
00800     }
00801 
00802     if( user == "*" && args.count() < 3 && session != QuerySessions )
00803     {
00804         cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
00805         showHelp( -1 );
00806     }
00807 
00808     if( session == QuerySessions && !args.isEmpty() )
00809     {
00810         cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
00811         showHelp( -1 );
00812     }
00813 
00814     if( session == QuerySessions && user.isEmpty() )
00815     {
00816         cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
00817              << "--all-users options!" << endl << endl;
00818         showHelp( -1 );
00819     }
00820 
00821     if( session != DefaultSession && session != QuerySessions &&
00822         args.count() < 3 )
00823     {
00824         cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
00825              << "calls!" << endl << endl;
00826         showHelp( -1 );
00827     }
00828 
00829     UserList users;
00830     if( user == "*" )
00831         users = userList();
00832     else if( !user.isEmpty() )
00833         users[ user ] = userList()[ user ];
00834 
00835     int retval = runDCOP( args, users, session, sessionName, readStdin );
00836 
00837     return retval;
00838 }
00839 
00840 // vim: set ts=8 sts=4 sw=4 noet:
00841 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:42:41 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001