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             printf( "%s\n", replyString.data() );
00294         }
00295     }
00296     return 0;
00297 }
00298 
00302 void showHelp( int exitCode = 0 )
00303 {
00304     cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
00305      << "" << endl
00306      << "Console DCOP client" << endl
00307      << "" << endl
00308      << "Generic options:" << endl
00309      << "  --help          Show help about options" << endl
00310      << "" << endl
00311      << "Options:" << endl
00312      << "  --pipe          Call DCOP for each line read from stdin" << endl
00313      << "                  This is roughly equivalent to calling" << endl
00314      << "                      'while read line ; do dcop $line ; done'" << endl
00315      << "                  but because no new dcop instance has to be started for" << endl
00316      << "                  each line this is generally much faster, especially" << endl
00317      << "                  for the slower GNU dynamic linkers." << endl
00318      << "  --user <user>   Connect to the given user's DCOP server. This option will" << endl
00319      << "                  ignore the values of the environment vars $DCOPSERVER and" << endl
00320      << "                  $ICEAUTHORITY, even if they are set." << endl
00321      << "                  If the user has more than one open session, you must also" << endl
00322      << "                  use one of the --list-sessions, --session or --all-sessions" << endl
00323      << "                  command-line options." << endl
00324      << "  --all-users     Send the same DCOP call to all users with a running DCOP" << endl
00325      << "                  server. Only failed calls to existing DCOP servers will" << endl
00326      << "                  generate an error message. If no DCOP server is available" << endl
00327      << "                  at all, no error will be generated." << endl
00328      << "  --session <ses> Send to the given KDE session. This option can only be" << endl
00329      << "                  used in combination with the --user option." << endl
00330      << "  --all-sessions  Send to all sessions found. Only works with the --user" << endl
00331      << "                  and --all-users options." << endl
00332      << "  --list-sessions List all active KDE session for a user or all users." << endl
00333      << endl;
00334 
00335     exit( exitCode );
00336 }
00337 
00342 static UserList userList()
00343 {
00344     UserList result;
00345 
00346     QFile f( "/etc/passwd" );
00347 
00348     if( !f.open( IO_ReadOnly ) )
00349     {
00350     cerr_ << "Can't open /etc/passwd for reading!" << endl;
00351     return result;
00352     }
00353 
00354     QStringList l( QStringList::split( '\n', f.readAll() ) );
00355 
00356     for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
00357     {
00358     QStringList userInfo( QStringList::split( ':', *it, true ) );
00359     result[ userInfo[ 0 ] ] = userInfo[ 5 ];
00360     }
00361 
00362     return result;
00363 }
00364 
00369 QStringList dcopSessionList( const QString &user, const QString &home )
00370 {
00371     if( home.isEmpty() )
00372     {
00373     cerr_ << "WARNING: Cannot determine home directory for user "
00374          << user << "!" << endl
00375          << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00376          << "calling dcop." << endl;
00377     return QStringList();
00378     }
00379 
00380     QStringList result;
00381     QFileInfo dirInfo( home );
00382     if( !dirInfo.exists() || !dirInfo.isReadable() )
00383     return result;
00384 
00385     QDir d( home );
00386     d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
00387     d.setNameFilter( ".DCOPserver*" );
00388 
00389     const QFileInfoList *list = d.entryInfoList();
00390     if( !list )
00391     return result;
00392 
00393     QFileInfoListIterator it( *list );
00394     QFileInfo *fi;
00395 
00396     while ( ( fi = it.current() ) != 0 )
00397     {
00398     if( fi->isReadable() )
00399         result.append( fi->fileName() );
00400     ++it;
00401     }
00402     return result;
00403 }
00404 
00408 int runDCOP( QCStringList args, UserList users, Session session,
00409               const QString sessionName, bool readStdin )
00410 {
00411     bool DCOPrefmode=false;
00412     QCString app;
00413     QCString objid;
00414     QCString function;
00415     QCStringList params;
00416     DCOPClient *client = 0L;
00417     int retval = 0;
00418     if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
00419     {
00420     int delimPos = args[ 0 ].findRev( ',' );
00421     if( delimPos == -1 )
00422         {
00423         cerr_ << "Error: '" << args[ 0 ]
00424          << "' is not a valid DCOP reference." << endl;
00425         exit( -1 );
00426         }
00427         app = args[ 0 ].mid( 8, delimPos-8 );
00428         delimPos++;
00429         objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
00430         if( args.count() > 1 )
00431         function = args[ 1 ];
00432     if( args.count() > 2 )
00433     {
00434         params = args;
00435         params.remove( params.begin() );
00436         params.remove( params.begin() );
00437     }
00438     DCOPrefmode=true;
00439     }
00440     else
00441     {
00442         if( !args.isEmpty() )
00443         app = args[ 0 ];
00444         if( args.count() > 1 )
00445         objid = args[ 1 ];
00446         if( args.count() > 2 )
00447         function = args[ 2 ];
00448         if( args.count() > 3)
00449     {
00450         params = args;
00451         params.remove( params.begin() );
00452         params.remove( params.begin() );
00453         params.remove( params.begin() );
00454     }
00455     }
00456 
00457     bool firstRun = true;
00458     UserList::Iterator it;
00459     QStringList sessions;
00460     bool presetDCOPServer = false;
00461 //    char *dcopStr = 0L;
00462     QString dcopServer;
00463 
00464     for( it = users.begin(); it != users.end() || firstRun; it++ )
00465     {
00466     firstRun = false;
00467 
00468     //cout_ << "Iterating '" << it.key() << "'" << endl;
00469 
00470     if( session == QuerySessions )
00471     {
00472         QStringList sessions = dcopSessionList( it.key(), it.data() );
00473         if( sessions.isEmpty() )
00474         {
00475         if( users.count() <= 1 )
00476         {
00477             cout_ << "No active sessions";
00478             if( !( *it ).isEmpty() )
00479             cout_ << " for user " << *it;
00480             cout_ << endl;
00481         }
00482         }
00483         else
00484         {
00485         cout_ << "Active sessions ";
00486         if( !( *it ).isEmpty() )
00487             cout_ << "for user " << *it << " ";
00488         cout_ << ":" << endl;
00489 
00490         QStringList::Iterator sIt;
00491         for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
00492             cout_ << "  " << *sIt << endl;
00493 
00494         cout_ << endl;
00495         }
00496         continue;
00497     }
00498 
00499     if( getenv( "DCOPSERVER" ) )
00500     {
00501         sessions.append( getenv( "DCOPSERVER" ) );
00502         presetDCOPServer = true;
00503     }
00504 
00505     if( users.count() > 1 || ( users.count() == 1 &&
00506         ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
00507     {
00508         sessions = dcopSessionList( it.key(), it.data() );
00509         if( sessions.isEmpty() )
00510         {
00511         if( users.count() > 1 )
00512             continue;
00513         else
00514         {
00515             cerr_ << "ERROR: No active KDE sessions!" << endl
00516              << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
00517              << "before calling dcop." << endl;
00518             exit( -1 );
00519         }
00520         }
00521         else if( !sessionName.isEmpty() )
00522         {
00523         if( sessions.contains( sessionName ) )
00524         {
00525             sessions.clear();
00526             sessions.append( sessionName );
00527         }
00528         else
00529         {
00530             cerr_ << "ERROR: The specified session doesn't exist!" << endl;
00531             exit( -1 );
00532         }
00533         }
00534         else if( sessions.count() > 1 && session != AllSessions )
00535         {
00536         cerr_ << "ERROR: Multiple available KDE sessions!" << endl
00537              << "Please specify the correct session to use with --session or use the" << endl
00538              << "--all-sessions option to broadcast to all sessions." << endl;
00539         exit( -1 );
00540         }
00541     }
00542 
00543     if( users.count() > 1 || ( users.count() == 1 &&
00544         ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
00545     {
00546         // Check for ICE authority file and if the file can be read by us
00547         QString home = it.data();
00548         QString iceFile = it.data() + "/.ICEauthority";
00549         QFileInfo fi( iceFile );
00550         if( iceFile.isEmpty() )
00551         {
00552         cerr_ << "WARNING: Cannot determine home directory for user "
00553              << it.key() << "!" << endl
00554              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00555              << "calling dcop." << endl;
00556         }
00557         else if( fi.exists() )
00558         {
00559         if( fi.isReadable() )
00560         {
00561             char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
00562             putenv( envStr );
00563             //cerr_ << "ice: " << envStr << endl;
00564         }
00565         else
00566         {
00567             cerr_ << "WARNING: ICE authority file " << iceFile
00568              << "is not readable by you!" << endl
00569              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00570              << "calling dcop." << endl;
00571         }
00572         }
00573         else
00574         {
00575         if( users.count() > 1 )
00576             continue;
00577         else
00578         {
00579             cerr_ << "WARNING: Cannot find ICE authority file "
00580                  << iceFile << "!" << endl
00581              << "Please check permissions or set the $ICEAUTHORITY"
00582              << " variable manually before" << endl
00583              << "calling dcop." << endl;
00584         }
00585         }
00586     }
00587 
00588     // Main loop
00589     // If users is an empty list we're calling for the currently logged
00590     // in user. In this case we don't have a session, but still want
00591     // to iterate the loop once.
00592     QStringList::Iterator sIt = sessions.begin();
00593     for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
00594     {
00595         if( !presetDCOPServer && !users.isEmpty() )
00596         {
00597         QString dcopFile = it.data() + "/" + *sIt;
00598         QFile f( dcopFile );
00599         if( !f.open( IO_ReadOnly ) )
00600         {
00601             cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
00602             exit( -1 );
00603         }
00604 
00605         QStringList l( QStringList::split( '\n', f.readAll() ) );
00606         dcopServer = l.first();
00607 
00608         if( dcopServer.isEmpty() )
00609         {
00610             cerr_ << "WARNING: Unable to determine DCOP server for session "
00611              << *sIt << "!" << endl
00612              << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00613              << "calling dcop." << endl;
00614             exit( -1 );
00615         }
00616         }
00617 
00618         delete client;
00619         client = new DCOPClient;
00620         if( !dcopServer.isEmpty() )
00621         client->setServerAddress( dcopServer.ascii() );
00622         bool success = client->attach();
00623         if( !success )
00624         {
00625         cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
00626         if( users.isEmpty() )
00627             break;
00628         else
00629             continue;
00630         }
00631         dcop = client;
00632 
00633         int argscount = args.count();
00634         if ( DCOPrefmode )
00635           argscount++;
00636         switch ( argscount )
00637         {
00638         case 0:
00639         queryApplications("");
00640         break;
00641         case 1:
00642         if (endsWith(app, '*'))
00643            queryApplications(app);
00644         else
00645            queryObjects( app, "" );
00646         break;
00647         case 2:
00648         if (endsWith(objid, '*'))
00649            queryObjects(app, objid);
00650         else
00651            queryFunctions( app, objid );
00652         break;
00653         case 3:
00654         default:
00655         if( readStdin )
00656         {
00657             QCStringList::Iterator replaceArg = params.end();
00658 
00659             QCStringList::Iterator it;
00660             for( it = params.begin(); it != params.end(); it++ )
00661             if( *it == "%1" )
00662                 replaceArg = it;
00663 
00664             // Read from stdin until EOF and call function for each
00665             // read line
00666             while ( !cin_.atEnd() )
00667             {
00668             QString buf = cin_.readLine();
00669 
00670             if( replaceArg != params.end() )
00671                 *replaceArg = buf.local8Bit();
00672 
00673             if( !buf.isNull() )
00674             {
00675                 int res = callFunction( app, objid, function, params );
00676                 retval = QMAX( retval, res );
00677             }
00678             }
00679         }
00680         else
00681         {
00682             // Just call function
00683 //          cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
00684             int res = callFunction( app, objid, function, params );
00685             retval = QMAX( retval, res );
00686         }
00687         break;
00688         }
00689         // Another sIt++ would make the loop infinite...
00690         if( users.isEmpty() )
00691         break;
00692     }
00693 
00694     // Another it++ would make the loop infinite...
00695     if( it == users.end() )
00696         break;
00697     }
00698 
00699     return retval;
00700 }
00701 
00702 
00703 int main( int argc, char** argv )
00704 {
00705     bool readStdin = false;
00706     int numOptions = 0;
00707     QString user;
00708     Session session = DefaultSession;
00709     QString sessionName;
00710 
00711     cin_.setEncoding( QTextStream::Locale );
00712 
00713     // Scan for command-line options first
00714     for( int pos = 1 ; pos <= argc - 1 ; pos++ )
00715     {
00716     if( strcmp( argv[ pos ], "--help" ) == 0 )
00717         showHelp( 0 );
00718     else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
00719     {
00720         readStdin = true;
00721         numOptions++;
00722     }
00723     else if( strcmp( argv[ pos ], "--user" ) == 0 )
00724     {
00725         if( pos <= argc - 2 )
00726         {
00727         user = QString::fromLocal8Bit( argv[ pos + 1] );
00728         numOptions +=2;
00729         pos++;
00730         }
00731         else
00732         {
00733         cerr_ << "Missing username for '--user' option!" << endl << endl;
00734         showHelp( -1 );
00735         }
00736     }
00737     else if( strcmp( argv[ pos ], "--session" ) == 0 )
00738     {
00739         if( session == AllSessions )
00740         {
00741         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00742         showHelp( -1 );
00743         }
00744         else if( pos <= argc - 2 )
00745         {
00746         sessionName = QString::fromLocal8Bit( argv[ pos + 1] );
00747         numOptions +=2;
00748         pos++;
00749         }
00750         else
00751         {
00752         cerr_ << "Missing session name for '--session' option!" << endl << endl;
00753         showHelp( -1 );
00754         }
00755     }
00756     else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
00757     {
00758         user = "*";
00759         numOptions ++;
00760     }
00761     else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
00762     {
00763         session = QuerySessions;
00764         numOptions ++;
00765     }
00766     else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
00767     {
00768         if( !sessionName.isEmpty() )
00769         {
00770         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00771         showHelp( -1 );
00772         }
00773         session = AllSessions;
00774         numOptions ++;
00775     }
00776     else if( argv[ pos ][ 0 ] == '-' )
00777     {
00778         cerr_ << "Unknown command-line option '" << argv[ pos ]
00779          << "'." << endl << endl;
00780         showHelp( -1 );
00781     }
00782     else
00783         break;  // End of options
00784     }
00785 
00786     argc -= numOptions;
00787 
00788     QCStringList args;
00789     for( int i = numOptions; i < argc + numOptions - 1; i++ )
00790     args.append( argv[ i + 1 ] );
00791 
00792     if( readStdin && args.count() < 3 )
00793     {
00794     cerr_ << "--pipe option only supported for function calls!" << endl << endl;
00795     showHelp( -1 );
00796     }
00797 
00798     if( user == "*" && args.count() < 3 && session != QuerySessions )
00799     {
00800     cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
00801     showHelp( -1 );
00802     }
00803 
00804     if( session == QuerySessions && !args.isEmpty() )
00805     {
00806     cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
00807     showHelp( -1 );
00808     }
00809 
00810     if( session == QuerySessions && user.isEmpty() )
00811     {
00812     cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
00813          << "--all-users options!" << endl << endl;
00814     showHelp( -1 );
00815     }
00816 
00817     if( session != DefaultSession && session != QuerySessions &&
00818         args.count() < 3 )
00819     {
00820     cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
00821          << "calls!" << endl << endl;
00822     showHelp( -1 );
00823     }
00824 
00825     UserList users;
00826     if( user == "*" )
00827     users = userList();
00828     else if( !user.isEmpty() )
00829     users[ user ] = userList()[ user ];
00830 
00831     int retval = runDCOP( args, users, session, sessionName, readStdin );
00832 
00833     return retval;
00834 }
00835 
00836 // vim: set ts=8 sts=4 sw=4 noet:
00837 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:20:25 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001