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.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:14:33 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001