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