dcop Library: dcop.cpp Source File (dcop Library)

| # dcop Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# 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 // putenv() is not available on all platforms, so make sure the emulation
    00024 // wrapper is available in those cases by loading config.h!
    00025 #include <config.h>
    00026
    00027 #include <sys/types.h>
    00028 #include <pwd.h>
    00029 #include <ctype.h>
    00030 #include <stdio.h>
    00031 #include <stdlib.h>
    00032
    00033 #include <qbuffer.h>
    00034 #include <qcolor.h>
    00035 #include <qdir.h>
    00036 #include <qfile.h>
    00037 #include <qfileinfo.h>
    00038 #include <qimage.h>
    00039 #include <qmap.h>
    00040 #include <qstringlist.h>
    00041 #include <qtextstream.h>
    00042 #include <qvariant.h>
    00043
    00044 #include "../dcopclient.h"
    00045 #include "../dcopref.h"
    00046 #include "../kdatastream.h"
    00047
    00048 #include "marshall.cpp"
    00049
    00050 #if defined Q_WS_X11
    00051 #include <X11/Xlib.h>
    00052 #include <X11/Xatom.h>
    00053 #endif
    00054
    00055 typedef QMap<QString, QString> UserList;
    00056
    00057 static DCOPClient* dcop = 0;
    00058
    00059 static QTextStream cin_ ( stdin,  IO_ReadOnly );
    00060 static QTextStream cout_( stdout, IO_WriteOnly );
    00061 static QTextStream cerr_( stderr, IO_WriteOnly );
    00062
    00072 enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
    00073
    00074 bool startsWith(const QCString &id, const char *str, int n)
    00075 {
    00076   return !n || (strncmp(id.data(), str, n) == 0);
    00077 }
    00078
    00079 bool endsWith(QCString &id, char c)
    00080 {
    00081    if (id.length() && (id[id.length()-1] == c))
    00082    {
    00083       id.truncate(id.length()-1);
    00084       return true;
    00085    }
    00086    return false;
    00087 }
    00088
    00089 void queryApplications(const QCString &filter)
    00090 {
    00091     int filterLen = filter.length();
    00092     QCStringList apps = dcop->registeredApplications();
    00093     for ( QCStringList::Iterator it = apps.begin(); it != apps.end(); ++it )
    00094     {
    00095         QCString &clientId = *it;
    00096     if ( (clientId != dcop->appId()) &&
    00097              !startsWith(clientId, "anonymous",9) &&
    00098              startsWith(clientId, filter, filterLen)
    00099            )
    00100         printf( "%s\n", clientId.data() );
    00101     }
    00102
    00103     if ( !dcop->isAttached() )
    00104     {
    00105     qWarning( "server not accessible" );
    00106         exit(1);
    00107     }
    00108 }
    00109
    00110 void queryObjects( const QCString &app, const QCString &filter )
    00111 {
    00112     int filterLen = filter.length();
    00113     bool ok = false;
    00114     bool isDefault = false;
    00115     QCStringList objs = dcop->remoteObjects( app, &ok );
    00116     for ( QCStringList::Iterator it = objs.begin(); it != objs.end(); ++it )
    00117     {
    00118         QCString &objId = *it;
    00119
    00120         if (objId == "default")
    00121         {
    00122            isDefault = true;
    00123            continue;
    00124         }
    00125
    00126         if (startsWith(objId, filter, filterLen))
    00127         {
    00128             if (isDefault)
    00129                 printf( "%s (default)\n", objId.data() );
    00130             else
    00131                 printf( "%s\n", objId.data() );
    00132         }
    00133         isDefault = false;
    00134     }
    00135     if ( !ok )
    00136     {
    00137         if (!dcop->isApplicationRegistered(app))
    00138             qWarning( "No such application: '%s'", app.data());
    00139         else
    00140             qWarning( "Application '%s' not accessible", app.data() );
    00141         exit(1);
    00142     }
    00143 }
    00144
    00145 void queryFunctions( const char* app, const char* obj )
    00146 {
    00147     bool ok = false;
    00148     QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
    00149     for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
    00150     printf( "%s\n", (*it).data() );
    00151     }
    00152     if ( !ok )
    00153     {
    00154     qWarning( "object '%s' in application '%s' not accessible", obj, app );
    00155     exit( 1 );
    00156     }
    00157 }
    00158
    00159 int callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
    00160 {
    00161     QString f = func; // Qt is better with unicode strings, so use one.
    00162     int left = f.find( '(' );
    00163     int right = f.find( ')' );
    00164
    00165     if ( right <  left )
    00166     {
    00167     qWarning( "parentheses do not match" );
    00168     return( 1 );
    00169     }
    00170
    00171     if ( left < 0 ) {
    00172     // try to get the interface from the server
    00173     bool ok = false;
    00174     QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
    00175     QCString realfunc;
    00176     if ( !ok && args.isEmpty() )
    00177         goto doit;
    00178     if ( !ok )
    00179     {
    00180         qWarning( "object not accessible" );
    00181         return( 1 );
    00182     }
    00183     for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
    00184         int l = (*it).find( '(' );
    00185         int s;
    00186         if (l > 0)
    00187             s = (*it).findRev( ' ', l);
    00188         else
    00189             s = (*it).find( ' ' );
    00190
    00191         if ( s < 0 )
    00192         s = 0;
    00193         else
    00194         s++;
    00195
    00196         if ( l > 0 && (*it).mid( s, l - s ) == func ) {
    00197         realfunc = (*it).mid( s );
    00198         const QString arguments = (*it).mid(l+1,(*it).find( ')' )-l-1);
    00199         uint a = arguments.contains(',');
    00200         if ( (a==0 && !arguments.isEmpty()) || a>0)
    00201             a++;
    00202         if ( a == args.count()  )
    00203             break;
    00204         }
    00205     }
    00206     if ( realfunc.isEmpty() )
    00207     {
    00208         qWarning("no such function");
    00209         return( 1 );
    00210     }
    00211     f = realfunc;
    00212     left = f.find( '(' );
    00213     right = f.find( ')' );
    00214     }
    00215
    00216  doit:
    00217     if ( left < 0 )
    00218     f += "()";
    00219
    00220     // This may seem expensive but is done only once per invocation
    00221     // of dcop, so it should be OK.
    00222     //
    00223     //
    00224     QStringList intTypes;
    00225     intTypes << "int" << "unsigned" << "long" << "bool" ;
    00226
    00227     QStringList types;
    00228     if ( left >0 && left + 1 < right - 1) {
    00229     types = QStringList::split( ',', f.mid( left + 1, right - left - 1) );
    00230     for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
    00231         QString lt = (*it).simplifyWhiteSpace();
    00232
    00233         int s = lt.find(' ');
    00234
    00235         // If there are spaces in the name, there may be two
    00236         // reasons: the parameter name is still there, ie.
    00237         // "QString URL" or it's a complicated int type, ie.
    00238         // "unsigned long long int bool".
    00239         //
    00240         //
    00241         if ( s > 0 )
    00242         {
    00243         QStringList partl = QStringList::split(' ' , lt);
    00244
    00245         // The zero'th part is -- at the very least -- a
    00246         // type part. Any trailing parts *might* be extra
    00247         // int-type keywords, or at most one may be the
    00248         // parameter name.
    00249         //
    00250         //
    00251         s=1;
    00252
    00253         while (s < static_cast<int>(partl.count()) && intTypes.contains(partl[s]))
    00254         {
    00255             s++;
    00256         }
    00257
    00258         if ( s < static_cast<int>(partl.count())-1)
    00259         {
    00260             qWarning("The argument `%s' seems syntactically wrong.",
    00261                 lt.latin1());
    00262         }
    00263         if ( s == static_cast<int>(partl.count())-1)
    00264         {
    00265             partl.remove(partl.at(s));
    00266         }
    00267
    00268         lt = partl.join(" ");
    00269         lt = lt.simplifyWhiteSpace();
    00270         }
    00271
    00272         (*it) = lt;
    00273     }
    00274     QString fc = f.left( left );
    00275     fc += '(';
    00276     bool first = true;
    00277     for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
    00278         if ( !first )
    00279         fc +=",";
    00280         first = false;
    00281         fc += *it;
    00282     }
    00283     fc += ')';
    00284     f = fc;
    00285     }
    00286
    00287     QByteArray data, replyData;
    00288     QCString replyType;
    00289     QDataStream arg(data, IO_WriteOnly);
    00290
    00291     uint i = 0;
    00292     for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
    00293         marshall( arg, args, i, *it );
    00294
    00295     if ( i != args.count() )
    00296     {
    00297     qWarning( "arguments do not match" );
    00298     return( 1 );
    00299     }
    00300
    00301     if ( !dcop->call( app, obj, f.latin1(),  data, replyType, replyData) ) {
    00302     qWarning( "call failed");
    00303     return( 1 );
    00304     } else {
    00305     QDataStream reply(replyData, IO_ReadOnly);
    00306
    00307         if ( replyType != "void" && replyType != "ASYNC" )
    00308         {
    00309             QCString replyString = demarshal( reply, replyType );
    00310             if ( !replyString.isEmpty() )
    00311                 printf( "%s\n", replyString.data() );
    00312             else
    00313                 printf("\n");
    00314         }
    00315     }
    00316     return 0;
    00317 }
    00318
    00322 void showHelp( int exitCode = 0 )
    00323 {
    00324 #ifdef DCOPQUIT
    00325    cout_ << "Usage: dcopquit [options] [application]" << endl
    00326 #else
    00327    cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
    00328 #endif
    00329          << "" << endl
    00330      << "Console DCOP client" << endl
    00331      << "" << endl
    00332      << "Generic options:" << endl
    00333      << "  --help          Show help about options" << endl
    00334      << "" << endl
    00335      << "Options:" << endl
    00336      << "  --pipe          Call DCOP for each line read from stdin. The string '%1'" << endl
    00337      << "                  will be used in the argument list as a placeholder for" << endl
    00338      << "                  the substituted line." << endl
    00339      << "                  For example," << endl
    00340      << "                      dcop --pipe konqueror html-widget1 evalJS %1" << endl
    00341      << "                  is equivalent to calling" << endl
    00342      << "                      while read line ; do" << endl
    00343      << "                          dcop konqueror html-widget1 evalJS \"$line\"" << endl
    00344      << "                      done" << endl
    00345      << "                  in bash, but because no new dcop instance has to be started" << endl
    00346      << "                  for each line this is generally much faster, especially for" << endl
    00347      << "                  the slower GNU dynamic linkers." << endl
    00348      << "                  The '%1' placeholder cannot be used to replace e.g. the" << endl
    00349      << "                  program, object or method name." << endl
    00350      << "  --user <user>   Connect to the given user's DCOP server. This option will" << endl
    00351      << "                  ignore the values of the environment vars $DCOPSERVER and" << endl
    00352      << "                  $ICEAUTHORITY, even if they are set." << endl
    00353      << "                  If the user has more than one open session, you must also" << endl
    00354      << "                  use one of the --list-sessions, --session or --all-sessions" << endl
    00355      << "                  command-line options." << endl
    00356      << "  --all-users     Send the same DCOP call to all users with a running DCOP" << endl
    00357      << "                  server. Only failed calls to existing DCOP servers will" << endl
    00358      << "                  generate an error message. If no DCOP server is available" << endl
    00359      << "                  at all, no error will be generated." << endl
    00360      << "  --session <ses> Send to the given KDE session. This option can only be" << endl
    00361      << "                  used in combination with the --user option." << endl
    00362      << "  --all-sessions  Send to all sessions found. Only works with the --user" << endl
    00363      << "                  and --all-users options." << endl
    00364      << "  --list-sessions List all active KDE session for a user or all users." << endl
    00365      << "  --no-user-time  Don't update the user activity timestamp in the called" << endl
    00366      << "                  application (for usage in scripts running" << endl
    00367      << "                  in the background)." << endl
    00368      << endl;
    00369
    00370     exit( exitCode );
    00371 }
    00372
    00377 static UserList userList()
    00378 {
    00379     UserList result;
    00380
    00381     while( passwd* pstruct = getpwent() )
    00382     {
    00383         result[ QString::fromLocal8Bit(pstruct->pw_name) ] = QFile::decodeName(pstruct->pw_dir);
    00384     }
    00385
    00386     return result;
    00387 }
    00388
    00393 QStringList dcopSessionList( const QString &user, const QString &home )
    00394 {
    00395     if( home.isEmpty() )
    00396     {
    00397     cerr_ << "WARNING: Cannot determine home directory for user "
    00398          << user << "!" << endl
    00399          << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
    00400          << "calling dcop." << endl;
    00401     return QStringList();
    00402     }
    00403
    00404     QStringList result;
    00405     QFileInfo dirInfo( home );
    00406     if( !dirInfo.exists() || !dirInfo.isReadable() )
    00407     return result;
    00408
    00409     QDir d( home );
    00410     d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
    00411     d.setNameFilter( ".DCOPserver*" );
    00412
    00413     const QFileInfoList *list = d.entryInfoList();
    00414     if( !list )
    00415     return result;
    00416
    00417     QFileInfoListIterator it( *list );
    00418     QFileInfo *fi;
    00419
    00420     while ( ( fi = it.current() ) != 0 )
    00421     {
    00422     if( fi->isReadable() )
    00423         result.append( fi->fileName() );
    00424     ++it;
    00425     }
    00426     return result;
    00427 }
    00428
    00429 void sendUserTime( const char* app )
    00430 {
    00431 #if defined Q_WS_X11
    00432     static unsigned long time = 0;
    00433     if( time == 0 )
    00434     {
    00435         Display* dpy = XOpenDisplay( NULL );
    00436         if( dpy != NULL )
    00437         {
    00438             Window w = XCreateSimpleWindow( dpy, DefaultRootWindow( dpy ), 0, 0, 1, 1, 0, 0, 0 );
    00439             XSelectInput( dpy, w, PropertyChangeMask );
    00440             unsigned char data[ 1 ];
    00441             XChangeProperty( dpy, w, XA_ATOM, XA_ATOM, 8, PropModeAppend, data, 1 );
    00442             XEvent ev;
    00443             XWindowEvent( dpy, w, PropertyChangeMask, &ev );
    00444             time = ev.xproperty.time;
    00445             XDestroyWindow( dpy, w );
    00446         }
    00447     }
    00448     DCOPRef( app, "MainApplication-Interface" ).call( "updateUserTimestamp", time );
    00449 #else
    00450 // ...
    00451 #endif
    00452 }
    00453
    00457 int runDCOP( QCStringList args, UserList users, Session session,
    00458               const QString sessionName, bool readStdin, bool updateUserTime )
    00459 {
    00460     bool DCOPrefmode=false;
    00461     QCString app;
    00462     QCString objid;
    00463     QCString function;
    00464     QCStringList params;
    00465     DCOPClient *client = 0L;
    00466     int retval = 0;
    00467     if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
    00468     {
    00469     int delimPos = args[ 0 ].findRev( ',' );
    00470     if( delimPos == -1 )
    00471         {
    00472         cerr_ << "Error: '" << args[ 0 ]
    00473          << "' is not a valid DCOP reference." << endl;
    00474         exit( -1 );
    00475         }
    00476         app = args[ 0 ].mid( 8, delimPos-8 );
    00477         delimPos++;
    00478         objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
    00479         if( args.count() > 1 )
    00480         function = args[ 1 ];
    00481     if( args.count() > 2 )
    00482     {
    00483         params = args;
    00484         params.remove( params.begin() );
    00485         params.remove( params.begin() );
    00486     }
    00487     DCOPrefmode=true;
    00488     }
    00489     else
    00490     {
    00491         if( !args.isEmpty() )
    00492         app = args[ 0 ];
    00493         if( args.count() > 1 )
    00494         objid = args[ 1 ];
    00495         if( args.count() > 2 )
    00496         function = args[ 2 ];
    00497         if( args.count() > 3)
    00498     {
    00499         params = args;
    00500         params.remove( params.begin() );
    00501         params.remove( params.begin() );
    00502         params.remove( params.begin() );
    00503     }
    00504     }
    00505
    00506     bool firstRun = true;
    00507     UserList::Iterator it;
    00508     QStringList sessions;
    00509     bool presetDCOPServer = false;
    00510 //    char *dcopStr = 0L;
    00511     QString dcopServer;
    00512
    00513     for( it = users.begin(); it != users.end() || firstRun; ++it )
    00514     {
    00515     firstRun = false;
    00516
    00517     //cout_ << "Iterating '" << it.key() << "'" << endl;
    00518
    00519     if( session == QuerySessions )
    00520     {
    00521         QStringList sessions = dcopSessionList( it.key(), it.data() );
    00522         if( sessions.isEmpty() )
    00523         {
    00524         if( users.count() <= 1 )
    00525         {
    00526             cout_ << "No active sessions";
    00527             if( !( *it ).isEmpty() )
    00528             cout_ << " for user " << *it;
    00529             cout_ << endl;
    00530         }
    00531         }
    00532         else
    00533         {
    00534         cout_ << "Active sessions ";
    00535         if( !( *it ).isEmpty() )
    00536             cout_ << "for user " << *it << " ";
    00537         cout_ << ":" << endl;
    00538
    00539         QStringList::Iterator sIt = sessions.begin();
    00540         for( ; sIt != sessions.end(); ++sIt )
    00541             cout_ << "  " << *sIt << endl;
    00542
    00543         cout_ << endl;
    00544         }
    00545         continue;
    00546     }
    00547
    00548     if( getenv( "DCOPSERVER" ) )
    00549     {
    00550         sessions.append( getenv( "DCOPSERVER" ) );
    00551         presetDCOPServer = true;
    00552     }
    00553
    00554     if( users.count() > 1 || ( users.count() == 1 &&
    00555         ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
    00556     {
    00557         sessions = dcopSessionList( it.key(), it.data() );
    00558         if( sessions.isEmpty() )
    00559         {
    00560         if( users.count() > 1 )
    00561             continue;
    00562         else
    00563         {
    00564             cerr_ << "ERROR: No active KDE sessions!" << endl
    00565              << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
    00566              << "before calling dcop." << endl;
    00567             exit( -1 );
    00568         }
    00569         }
    00570         else if( !sessionName.isEmpty() )
    00571         {
    00572         if( sessions.contains( sessionName ) )
    00573         {
    00574             sessions.clear();
    00575             sessions.append( sessionName );
    00576         }
    00577         else
    00578         {
    00579             cerr_ << "ERROR: The specified session doesn't exist!" << endl;
    00580             exit( -1 );
    00581         }
    00582         }
    00583         else if( sessions.count() > 1 && session != AllSessions )
    00584         {
    00585         cerr_ << "ERROR: Multiple available KDE sessions!" << endl
    00586              << "Please specify the correct session to use with --session or use the" << endl
    00587              << "--all-sessions option to broadcast to all sessions." << endl;
    00588         exit( -1 );
    00589         }
    00590     }
    00591
    00592     if( users.count() > 1 || ( users.count() == 1 &&
    00593         ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
    00594     {
    00595         // Check for ICE authority file and if the file can be read by us
    00596         QString home = it.data();
    00597         QString iceFile = it.data() + "/.ICEauthority";
    00598         QFileInfo fi( iceFile );
    00599         if( iceFile.isEmpty() )
    00600         {
    00601         cerr_ << "WARNING: Cannot determine home directory for user "
    00602              << it.key() << "!" << endl
    00603              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
    00604              << "calling dcop." << endl;
    00605         }
    00606         else if( fi.exists() )
    00607         {
    00608         if( fi.isReadable() )
    00609         {
    00610             char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
    00611             putenv( envStr );
    00612             //cerr_ << "ice: " << envStr << endl;
    00613         }
    00614         else
    00615         {
    00616             cerr_ << "WARNING: ICE authority file " << iceFile
    00617              << "is not readable by you!" << endl
    00618              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
    00619              << "calling dcop." << endl;
    00620         }
    00621         }
    00622         else
    00623         {
    00624         if( users.count() > 1 )
    00625             continue;
    00626         else
    00627         {
    00628             cerr_ << "WARNING: Cannot find ICE authority file "
    00629                  << iceFile << "!" << endl
    00630              << "Please check permissions or set the $ICEAUTHORITY"
    00631              << " variable manually before" << endl
    00632              << "calling dcop." << endl;
    00633         }
    00634         }
    00635     }
    00636
    00637     // Main loop
    00638     // If users is an empty list we're calling for the currently logged
    00639     // in user. In this case we don't have a session, but still want
    00640     // to iterate the loop once.
    00641     QStringList::Iterator sIt = sessions.begin();
    00642     for( ; sIt != sessions.end() || users.isEmpty(); ++sIt )
    00643     {
    00644         if( !presetDCOPServer && !users.isEmpty() )
    00645         {
    00646         QString dcopFile = it.data() + "/" + *sIt;
    00647         QFile f( dcopFile );
    00648         if( !f.open( IO_ReadOnly ) )
    00649         {
    00650             cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
    00651             exit( -1 );
    00652         }
    00653
    00654         QStringList l( QStringList::split( '\n', f.readAll() ) );
    00655         dcopServer = l.first();
    00656
    00657         if( dcopServer.isEmpty() )
    00658         {
    00659             cerr_ << "WARNING: Unable to determine DCOP server for session "
    00660              << *sIt << "!" << endl
    00661              << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
    00662              << "calling dcop." << endl;
    00663             exit( -1 );
    00664         }
    00665         }
    00666
    00667         delete client;
    00668         client = new DCOPClient;
    00669         if( !dcopServer.isEmpty() )
    00670         client->setServerAddress( dcopServer.ascii() );
    00671         bool success = client->attach();
    00672         if( !success )
    00673         {
    00674         cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
    00675         retval = QMAX( retval, 1 );
    00676         if( users.isEmpty() )
    00677             break;
    00678         else
    00679             continue;
    00680         }
    00681         dcop = client;
    00682
    00683         int argscount = args.count();
    00684         if ( DCOPrefmode )
    00685           argscount++;
    00686         switch ( argscount )
    00687         {
    00688         case 0:
    00689         queryApplications("");
    00690         break;
    00691         case 1:
    00692         if (endsWith(app, '*'))
    00693            queryApplications(app);
    00694         else
    00695            queryObjects( app, "" );
    00696         break;
    00697         case 2:
    00698         if (endsWith(objid, '*'))
    00699            queryObjects(app, objid);
    00700         else
    00701            queryFunctions( app, objid );
    00702         break;
    00703         case 3:
    00704         default:
    00705                 if( updateUserTime )
    00706                     sendUserTime( app );
    00707         if( readStdin )
    00708         {
    00709             QCStringList::Iterator replaceArg = params.end();
    00710
    00711             QCStringList::Iterator it = params.begin();
    00712             for( ; it != params.end(); ++it )
    00713             if( *it == "%1" )
    00714                 replaceArg = it;
    00715
    00716             // Read from stdin until EOF and call function for each
    00717             // read line
    00718             while ( !cin_.atEnd() )
    00719             {
    00720             QString buf = cin_.readLine();
    00721
    00722             if( replaceArg != params.end() )
    00723                 *replaceArg = buf.local8Bit();
    00724
    00725             if( !buf.isNull() )
    00726             {
    00727                 int res = callFunction( app, objid, function, params );
    00728                 retval = QMAX( retval, res );
    00729             }
    00730             }
    00731         }
    00732         else
    00733         {
    00734             // Just call function
    00735 //          cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
    00736             int res = callFunction( app, objid, function, params );
    00737             retval = QMAX( retval, res );
    00738         }
    00739         break;
    00740         }
    00741         // Another sIt++ would make the loop infinite...
    00742         if( users.isEmpty() )
    00743         break;
    00744     }
    00745
    00746     // Another it++ would make the loop infinite...
    00747     if( it == users.end() )
    00748         break;
    00749     }
    00750
    00751     return retval;
    00752 }
    00753
    00754
    00755 int main( int argc, char** argv )
    00756 {
    00757     bool readStdin = false;
    00758     int numOptions = 0;
    00759     QString user;
    00760     Session session = DefaultSession;
    00761     QString sessionName;
    00762     bool updateUserTime = true;
    00763
    00764     cin_.setEncoding( QTextStream::Locale );
    00765
    00766     // Scan for command-line options first
    00767     for( int pos = 1 ; pos <= argc - 1 ; pos++ )
    00768     {
    00769     if( strcmp( argv[ pos ], "--help" ) == 0 )
    00770         showHelp( 0 );
    00771     else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
    00772     {
    00773         readStdin = true;
    00774         numOptions++;
    00775     }
    00776     else if( strcmp( argv[ pos ], "--user" ) == 0 )
    00777     {
    00778         if( pos <= argc - 2 )
    00779         {
    00780         user = QString::fromLocal8Bit( argv[ pos + 1] );
    00781         numOptions +=2;
    00782         pos++;
    00783         }
    00784         else
    00785         {
    00786         cerr_ << "Missing username for '--user' option!" << endl << endl;
    00787         showHelp( -1 );
    00788         }
    00789     }
    00790     else if( strcmp( argv[ pos ], "--session" ) == 0 )
    00791     {
    00792         if( session == AllSessions )
    00793         {
    00794         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
    00795         showHelp( -1 );
    00796         }
    00797         else if( pos <= argc - 2 )
    00798         {
    00799         sessionName = QString::fromLocal8Bit( argv[ pos + 1] );
    00800         numOptions +=2;
    00801         pos++;
    00802         }
    00803         else
    00804         {
    00805         cerr_ << "Missing session name for '--session' option!" << endl << endl;
    00806         showHelp( -1 );
    00807         }
    00808     }
    00809     else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
    00810     {
    00811         user = "*";
    00812         numOptions ++;
    00813     }
    00814     else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
    00815     {
    00816         session = QuerySessions;
    00817         numOptions ++;
    00818     }
    00819     else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
    00820     {
    00821         if( !sessionName.isEmpty() )
    00822         {
    00823         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
    00824         showHelp( -1 );
    00825         }
    00826         session = AllSessions;
    00827         numOptions ++;
    00828     }
    00829         else if( strcmp( argv[ pos ], "--no-user-time" ) == 0 )
    00830         {
    00831             updateUserTime = false;
    00832             numOptions ++;
    00833         }
    00834     else if( argv[ pos ][ 0 ] == '-' )
    00835     {
    00836         cerr_ << "Unknown command-line option '" << argv[ pos ]
    00837          << "'." << endl << endl;
    00838         showHelp( -1 );
    00839     }
    00840     else
    00841         break;  // End of options
    00842     }
    00843
    00844     argc -= numOptions;
    00845
    00846     QCStringList args;
    00847
    00848 #ifdef DCOPQUIT
    00849     if (argc > 1)
    00850     {
    00851        QCString prog = argv[ numOptions + 1 ];
    00852
    00853        if (!prog.isEmpty())
    00854        {
    00855           args.append( prog );
    00856
    00857           // Pass as-is if it ends with a wildcard
    00858           if (prog[prog.length()-1] != '*')
    00859           {
    00860              // Strip a trailing -<PID> part.
    00861              int i = prog.findRev('-');
    00862              if ((i >= 0) && prog.mid(i+1).toLong())
    00863              {
    00864                 prog = prog.left(i);
    00865              }
    00866              args.append( "qt/"+prog );
    00867              args.append( "quit()" );
    00868           }
    00869        }
    00870     }
    00871 #else
    00872     for( int i = numOptions; i < argc + numOptions - 1; i++ )
    00873        args.append( argv[ i + 1 ] );
    00874 #endif
    00875
    00876     if( readStdin && args.count() < 3 )
    00877     {
    00878     cerr_ << "--pipe option only supported for function calls!" << endl << endl;
    00879     showHelp( -1 );
    00880     }
    00881
    00882     if( user == "*" && args.count() < 3 && session != QuerySessions )
    00883     {
    00884     cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
    00885     showHelp( -1 );
    00886     }
    00887
    00888     if( session == QuerySessions && !args.isEmpty() )
    00889     {
    00890     cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
    00891     showHelp( -1 );
    00892     }
    00893
    00894     if( session == QuerySessions && user.isEmpty() )
    00895     {
    00896     cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
    00897          << "--all-users options!" << endl << endl;
    00898     showHelp( -1 );
    00899     }
    00900
    00901     if( session != DefaultSession && session != QuerySessions &&
    00902         args.count() < 3 )
    00903     {
    00904     cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
    00905          << "calls!" << endl << endl;
    00906     showHelp( -1 );
    00907     }
    00908
    00909     UserList users;
    00910     if( user == "*" )
    00911     users = userList();
    00912     else if( !user.isEmpty() )
    00913     users[ user ] = userList()[ user ];
    00914
    00915     int retval = runDCOP( args, users, session, sessionName, readStdin, updateUserTime );
    00916
    00917     return retval;
    00918 }
    00919
    00920 // vim: set ts=8 sts=4 sw=4 noet:
    00921

This file is part of the documentation for dcop Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:16:55 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003