• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • dcop
 

dcop

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 <tqbuffer.h>
00034 #include <tqcolor.h>
00035 #include <tqdir.h>
00036 #include <tqfile.h>
00037 #include <tqfileinfo.h>
00038 #include <tqimage.h>
00039 #include <tqmap.h>
00040 #include <tqstringlist.h>
00041 #include <tqtextstream.h>
00042 #include <tqvariant.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 TQMap<TQString, TQString> UserList;
00056 
00057 static DCOPClient* dcop = 0;
00058 
00059 static TQTextStream cin_ ( stdin,  IO_ReadOnly );
00060 static TQTextStream cout_( stdout, IO_WriteOnly );
00061 static TQTextStream cerr_( stderr, IO_WriteOnly );
00062 
00072 enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
00073 
00074 bool startsWith(const TQCString &id, const char *str, int n)
00075 {
00076   return !n || (strncmp(id.data(), str, n) == 0);
00077 }
00078 
00079 bool endsWith(TQCString &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 TQCString &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         TQCString &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     tqWarning( "server not accessible" );
00106         exit(1);
00107     }
00108 }
00109 
00110 void queryObjects( const TQCString &app, const TQCString &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         TQCString &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             tqWarning( "No such application: '%s'", app.data());
00139         else
00140             tqWarning( "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     tqWarning( "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     TQString 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     tqWarning( "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     TQCString realfunc;
00176     if ( !ok && args.isEmpty() )
00177         goto doit;
00178     if ( !ok )
00179     {
00180         tqWarning( "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 TQString 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         tqWarning("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     TQStringList intTypes;
00225     intTypes << "int" << "unsigned" << "long" << "bool" ;
00226 
00227     TQStringList types;
00228     if ( left >0 && left + 1 < right - 1) {
00229     types = TQStringList::split( ',', f.mid( left + 1, right - left - 1) );
00230     for ( TQStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
00231         TQString 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         // "TQString URL" or it's a complicated int type, ie.
00238         // "unsigned long long int bool".
00239         //
00240         //
00241         if ( s > 0 )
00242         {
00243         TQStringList partl = TQStringList::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             tqWarning("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     TQString fc = f.left( left );
00275     fc += '(';
00276     bool first = true;
00277     for ( TQStringList::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     TQByteArray data, replyData;
00288     TQCString replyType;
00289     TQDataStream arg(data, IO_WriteOnly);
00290 
00291     uint i = 0;
00292     for( TQStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
00293         marshall( arg, args, i, *it );
00294     }
00295 
00296     if ( i != args.count() )
00297     {
00298     tqWarning( "arguments do not match" );
00299     return( 1 );
00300     }
00301 
00302     if ( !dcop->call( app, obj, f.latin1(),  data, replyType, replyData) ) {
00303     tqWarning( "call failed");
00304     return( 1 );
00305     } else {
00306     TQDataStream reply(replyData, IO_ReadOnly);
00307 
00308         if ( replyType != "void" && replyType != "ASYNC" )
00309         {
00310             TQCString replyString = demarshal( reply, replyType );
00311             if ( !replyString.isEmpty() )
00312                 printf( "%s\n", replyString.data() );
00313             else
00314                 printf("\n");
00315         }
00316     }
00317     return 0;
00318 }
00319 
00323 void showHelp( int exitCode = 0 )
00324 {
00325 #ifdef DCOPQUIT
00326    cout_ << "Usage: dcopquit [options] [application]" << endl
00327 #else
00328    cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
00329 #endif
00330          << "" << endl
00331      << "Console DCOP client" << endl
00332      << "" << endl
00333      << "Generic options:" << endl
00334      << "  --help          Show help about options" << endl
00335      << "" << endl
00336      << "Options:" << endl
00337      << "  --pipe          Call DCOP for each line read from stdin. The string '%1'" << endl
00338      << "                  will be used in the argument list as a placeholder for" << endl
00339      << "                  the substituted line." << endl
00340      << "                  For example," << endl
00341      << "                      dcop --pipe konqueror html-widget1 evalJS %1" << endl
00342      << "                  is equivalent to calling" << endl
00343      << "                      while read line ; do" << endl
00344      << "                          dcop konqueror html-widget1 evalJS \"$line\"" << endl
00345      << "                      done" << endl
00346      << "                  in bash, but because no new dcop instance has to be started" << endl
00347      << "                  for each line this is generally much faster, especially for" << endl
00348      << "                  the slower GNU dynamic linkers." << endl
00349      << "                  The '%1' placeholder cannot be used to replace e.g. the" << endl
00350      << "                  program, object or method name." << endl
00351      << "  --user <user>   Connect to the given user's DCOP server. This option will" << endl
00352      << "                  ignore the values of the environment vars $DCOPSERVER and" << endl
00353      << "                  $ICEAUTHORITY, even if they are set." << endl
00354      << "                  If the user has more than one open session, you must also" << endl
00355      << "                  use one of the --list-sessions, --session or --all-sessions" << endl
00356      << "                  command-line options." << endl
00357      << "  --all-users     Send the same DCOP call to all users with a running DCOP" << endl
00358      << "                  server. Only failed calls to existing DCOP servers will" << endl
00359      << "                  generate an error message. If no DCOP server is available" << endl
00360      << "                  at all, no error will be generated." << endl
00361      << "  --session <ses> Send to the given TDE session. This option can only be" << endl
00362      << "                  used in combination with the --user option." << endl
00363      << "  --all-sessions  Send to all sessions found. Only works with the --user" << endl
00364      << "                  and --all-users options." << endl
00365      << "  --list-sessions List all active TDE session for a user or all users." << endl
00366      << "  --no-user-time  Don't update the user activity timestamp in the called" << endl
00367      << "                  application (for usage in scripts running" << endl
00368      << "                  in the background)." << endl
00369      << endl;
00370 
00371     exit( exitCode );
00372 }
00373 
00378 static UserList userList()
00379 {
00380     UserList result;
00381 
00382     while( passwd* pstruct = getpwent() )
00383     {
00384         result[ TQString::fromLocal8Bit(pstruct->pw_name) ] = TQFile::decodeName(pstruct->pw_dir);
00385     }
00386 
00387     return result;
00388 }
00389 
00394 TQStringList dcopSessionList( const TQString &user, const TQString &home )
00395 {
00396     if( home.isEmpty() )
00397     {
00398     cerr_ << "WARNING: Cannot determine home directory for user "
00399          << user << "!" << endl
00400          << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00401          << "calling dcop." << endl;
00402     return TQStringList();
00403     }
00404 
00405     TQStringList result;
00406     TQFileInfo dirInfo( home );
00407     if( !dirInfo.exists() || !dirInfo.isReadable() )
00408     return result;
00409 
00410     TQDir d( home );
00411     d.setFilter( TQDir::Files | TQDir::Hidden | TQDir::NoSymLinks );
00412     d.setNameFilter( ".DCOPserver*" );
00413 
00414     const TQFileInfoList *list = d.entryInfoList();
00415     if( !list )
00416     return result;
00417 
00418     TQFileInfoListIterator it( *list );
00419     TQFileInfo *fi;
00420 
00421     while ( ( fi = it.current() ) != 0 )
00422     {
00423     if( fi->isReadable() )
00424         result.append( fi->fileName() );
00425     ++it;
00426     }
00427     return result;
00428 }
00429 
00430 void sendUserTime( const char* app )
00431 {
00432 #if defined Q_WS_X11
00433     static unsigned long time = 0;
00434     if( time == 0 )
00435     {
00436         Display* dpy = XOpenDisplay( NULL );
00437         if( dpy != NULL )
00438         {
00439             Window w = XCreateSimpleWindow( dpy, DefaultRootWindow( dpy ), 0, 0, 1, 1, 0, 0, 0 );
00440             XSelectInput( dpy, w, PropertyChangeMask );
00441             unsigned char data[ 1 ];
00442             XChangeProperty( dpy, w, XA_ATOM, XA_ATOM, 8, PropModeAppend, data, 1 );
00443             XEvent ev;
00444             XWindowEvent( dpy, w, PropertyChangeMask, &ev );
00445             time = ev.xproperty.time;
00446             XDestroyWindow( dpy, w );
00447         }
00448     }
00449     DCOPRef( app, "MainApplication-Interface" ).call( "updateUserTimestamp", time );
00450 #else
00451 // ...
00452 #endif
00453 }
00454 
00458 int runDCOP( QCStringList args, UserList users, Session session,
00459               const TQString sessionName, bool readStdin, bool updateUserTime )
00460 {
00461     bool DCOPrefmode=false;
00462     TQCString app;
00463     TQCString objid;
00464     TQCString function;
00465     QCStringList params;
00466     DCOPClient *client = 0L;
00467     int retval = 0;
00468     if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
00469     {
00470     int delimPos = args[ 0 ].findRev( ',' );
00471     if( delimPos == -1 )
00472         {
00473         cerr_ << "Error: '" << args[ 0 ]
00474          << "' is not a valid DCOP reference." << endl;
00475         exit( -1 );
00476         }
00477         app = args[ 0 ].mid( 8, delimPos-8 );
00478         delimPos++;
00479         objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
00480         if( args.count() > 1 )
00481         function = args[ 1 ];
00482     if( args.count() > 2 )
00483     {
00484         params = args;
00485         params.remove( params.begin() );
00486         params.remove( params.begin() );
00487     }
00488     DCOPrefmode=true;
00489     }
00490     else
00491     {
00492         if( !args.isEmpty() )
00493         app = args[ 0 ];
00494         if( args.count() > 1 )
00495         objid = args[ 1 ];
00496         if( args.count() > 2 )
00497         function = args[ 2 ];
00498         if( args.count() > 3)
00499     {
00500         params = args;
00501         params.remove( params.begin() );
00502         params.remove( params.begin() );
00503         params.remove( params.begin() );
00504     }
00505     }
00506 
00507     bool firstRun = true;
00508     UserList::Iterator it;
00509     TQStringList sessions;
00510     bool presetDCOPServer = false;
00511 //    char *dcopStr = 0L;
00512     TQString dcopServer;
00513 
00514     for( it = users.begin(); it != users.end() || firstRun; ++it )
00515     {
00516     firstRun = false;
00517 
00518     //cout_ << "Iterating '" << it.key() << "'" << endl;
00519 
00520     if( session == QuerySessions )
00521     {
00522         TQStringList sessions = dcopSessionList( it.key(), it.data() );
00523         if( sessions.isEmpty() )
00524         {
00525         if( users.count() <= 1 )
00526         {
00527             cout_ << "No active sessions";
00528             if( !( *it ).isEmpty() )
00529             cout_ << " for user " << *it;
00530             cout_ << endl;
00531         }
00532         }
00533         else
00534         {
00535         cout_ << "Active sessions ";
00536         if( !( *it ).isEmpty() )
00537             cout_ << "for user " << *it << " ";
00538         cout_ << ":" << endl;
00539 
00540         TQStringList::Iterator sIt = sessions.begin();
00541         for( ; sIt != sessions.end(); ++sIt )
00542             cout_ << "  " << *sIt << endl;
00543 
00544         cout_ << endl;
00545         }
00546         continue;
00547     }
00548 
00549     if( getenv( "DCOPSERVER" ) )
00550     {
00551         sessions.append( getenv( "DCOPSERVER" ) );
00552         presetDCOPServer = true;
00553     }
00554 
00555     if( users.count() > 1 || ( users.count() == 1 &&
00556         ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
00557     {
00558         sessions = dcopSessionList( it.key(), it.data() );
00559         if( sessions.isEmpty() )
00560         {
00561         if( users.count() > 1 )
00562             continue;
00563         else
00564         {
00565             cerr_ << "ERROR: No active TDE sessions!" << endl
00566              << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
00567              << "before calling dcop." << endl;
00568             exit( -1 );
00569         }
00570         }
00571         else if( !sessionName.isEmpty() )
00572         {
00573         if( sessions.contains( sessionName ) )
00574         {
00575             sessions.clear();
00576             sessions.append( sessionName );
00577         }
00578         else
00579         {
00580             cerr_ << "ERROR: The specified session doesn't exist!" << endl;
00581             exit( -1 );
00582         }
00583         }
00584         else if( sessions.count() > 1 && session != AllSessions )
00585         {
00586         cerr_ << "ERROR: Multiple available TDE sessions!" << endl
00587              << "Please specify the correct session to use with --session or use the" << endl
00588              << "--all-sessions option to broadcast to all sessions." << endl;
00589         exit( -1 );
00590         }
00591     }
00592 
00593     if( users.count() > 1 || ( users.count() == 1 &&
00594         ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
00595     {
00596         // Check for ICE authority file and if the file can be read by us
00597         TQString home = it.data();
00598         TQString iceFile = it.data() + "/.ICEauthority";
00599         TQFileInfo fi( iceFile );
00600         if( iceFile.isEmpty() )
00601         {
00602         cerr_ << "WARNING: Cannot determine home directory for user "
00603              << it.key() << "!" << endl
00604              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00605              << "calling dcop." << endl;
00606         }
00607         else if( fi.exists() )
00608         {
00609         if( fi.isReadable() )
00610         {
00611             char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
00612             putenv( envStr );
00613             //cerr_ << "ice: " << envStr << endl;
00614         }
00615         else
00616         {
00617             cerr_ << "WARNING: ICE authority file " << iceFile
00618              << "is not readable by you!" << endl
00619              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00620              << "calling dcop." << endl;
00621         }
00622         }
00623         else
00624         {
00625         if( users.count() > 1 )
00626             continue;
00627         else
00628         {
00629             cerr_ << "WARNING: Cannot find ICE authority file "
00630                  << iceFile << "!" << endl
00631              << "Please check permissions or set the $ICEAUTHORITY"
00632              << " variable manually before" << endl
00633              << "calling dcop." << endl;
00634         }
00635         }
00636     }
00637 
00638     // Main loop
00639     // If users is an empty list we're calling for the currently logged
00640     // in user. In this case we don't have a session, but still want
00641     // to iterate the loop once.
00642     TQStringList::Iterator sIt = sessions.begin();
00643     for( ; sIt != sessions.end() || users.isEmpty(); ++sIt )
00644     {
00645         if( !presetDCOPServer && !users.isEmpty() )
00646         {
00647         TQString dcopFile = it.data() + "/" + *sIt;
00648         TQFile f( dcopFile );
00649         if( !f.open( IO_ReadOnly ) )
00650         {
00651             cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
00652             exit( -1 );
00653         }
00654 
00655         TQStringList l( TQStringList::split( '\n', f.readAll() ) );
00656         dcopServer = l.first();
00657 
00658         if( dcopServer.isEmpty() )
00659         {
00660             cerr_ << "WARNING: Unable to determine DCOP server for session "
00661              << *sIt << "!" << endl
00662              << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00663              << "calling dcop." << endl;
00664             exit( -1 );
00665         }
00666         }
00667 
00668         delete client;
00669         client = new DCOPClient;
00670         if( !dcopServer.isEmpty() )
00671         client->setServerAddress( dcopServer.ascii() );
00672         bool success = client->attach();
00673         if( !success )
00674         {
00675         cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
00676         retval = TQMAX( retval, 1 );
00677         if( users.isEmpty() )
00678             break;
00679         else
00680             continue;
00681         }
00682         dcop = client;
00683 
00684         int argscount = args.count();
00685         if ( DCOPrefmode )
00686           argscount++;
00687         switch ( argscount )
00688         {
00689         case 0:
00690         queryApplications("");
00691         break;
00692         case 1:
00693         if (endsWith(app, '*'))
00694            queryApplications(app);
00695         else
00696            queryObjects( app, "" );
00697         break;
00698         case 2:
00699         if (endsWith(objid, '*'))
00700            queryObjects(app, objid);
00701         else
00702            queryFunctions( app, objid );
00703         break;
00704         case 3:
00705         default:
00706                 if( updateUserTime )
00707                     sendUserTime( app );
00708         if( readStdin )
00709         {
00710             QCStringList::Iterator replaceArg = params.end();
00711 
00712             QCStringList::Iterator it = params.begin();
00713             for( ; it != params.end(); ++it )
00714             if( *it == "%1" )
00715                 replaceArg = it;
00716 
00717             // Read from stdin until EOF and call function for each
00718             // read line
00719             while ( !cin_.atEnd() )
00720             {
00721             TQString buf = cin_.readLine();
00722 
00723             if( replaceArg != params.end() )
00724                 *replaceArg = buf.local8Bit();
00725 
00726             if( !buf.isNull() )
00727             {
00728                 int res = callFunction( app, objid, function, params );
00729                 retval = TQMAX( retval, res );
00730             }
00731             }
00732         }
00733         else
00734         {
00735             // Just call function
00736 //          cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
00737             int res = callFunction( app, objid, function, params );
00738             retval = TQMAX( retval, res );
00739         }
00740         break;
00741         }
00742         // Another sIt++ would make the loop infinite...
00743         if( users.isEmpty() )
00744         break;
00745     }
00746 
00747     // Another it++ would make the loop infinite...
00748     if( it == users.end() )
00749         break;
00750     }
00751 
00752     return retval;
00753 }
00754 
00755 #ifdef Q_OS_WIN
00756 # define main kdemain
00757 #endif
00758 
00759 int main( int argc, char** argv )
00760 {
00761     bool readStdin = false;
00762     int numOptions = 0;
00763     TQString user;
00764     Session session = DefaultSession;
00765     TQString sessionName;
00766     bool updateUserTime = true;
00767 
00768     cin_.setEncoding( TQTextStream::Locale );
00769 
00770     // Scan for command-line options first
00771     for( int pos = 1 ; pos <= argc - 1 ; pos++ )
00772     {
00773     if( strcmp( argv[ pos ], "--help" ) == 0 )
00774         showHelp( 0 );
00775     else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
00776     {
00777         readStdin = true;
00778         numOptions++;
00779     }
00780     else if( strcmp( argv[ pos ], "--user" ) == 0 )
00781     {
00782         if( pos <= argc - 2 )
00783         {
00784         user = TQString::fromLocal8Bit( argv[ pos + 1] );
00785         numOptions +=2;
00786         pos++;
00787         }
00788         else
00789         {
00790         cerr_ << "Missing username for '--user' option!" << endl << endl;
00791         showHelp( -1 );
00792         }
00793     }
00794     else if( strcmp( argv[ pos ], "--session" ) == 0 )
00795     {
00796         if( session == AllSessions )
00797         {
00798         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00799         showHelp( -1 );
00800         }
00801         else if( pos <= argc - 2 )
00802         {
00803         sessionName = TQString::fromLocal8Bit( argv[ pos + 1] );
00804         numOptions +=2;
00805         pos++;
00806         }
00807         else
00808         {
00809         cerr_ << "Missing session name for '--session' option!" << endl << endl;
00810         showHelp( -1 );
00811         }
00812     }
00813     else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
00814     {
00815         user = "*";
00816         numOptions ++;
00817     }
00818     else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
00819     {
00820         session = QuerySessions;
00821         numOptions ++;
00822     }
00823     else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
00824     {
00825         if( !sessionName.isEmpty() )
00826         {
00827         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00828         showHelp( -1 );
00829         }
00830         session = AllSessions;
00831         numOptions ++;
00832     }
00833         else if( strcmp( argv[ pos ], "--no-user-time" ) == 0 )
00834         {
00835             updateUserTime = false;
00836             numOptions ++;
00837         }
00838     else if( argv[ pos ][ 0 ] == '-' )
00839     {
00840         cerr_ << "Unknown command-line option '" << argv[ pos ]
00841          << "'." << endl << endl;
00842         showHelp( -1 );
00843     }
00844     else
00845         break;  // End of options
00846     }
00847 
00848     argc -= numOptions;
00849 
00850     QCStringList args;
00851     
00852 #ifdef DCOPQUIT
00853     if (argc > 1)
00854     {
00855        TQCString prog = argv[ numOptions + 1 ];
00856        
00857        if (!prog.isEmpty())
00858        {
00859           args.append( prog );
00860        
00861           // Pass as-is if it ends with a wildcard
00862           if (prog[prog.length()-1] != '*')
00863           {
00864              // Strip a trailing -<PID> part.
00865              int i = prog.findRev('-');
00866              if ((i >= 0) && prog.mid(i+1).toLong())
00867              {
00868                 prog = prog.left(i);      
00869              }
00870              args.append( "qt/"+prog ); 
00871              args.append( "quit()" );
00872           }
00873        }
00874     }
00875 #else
00876     for( int i = numOptions; i < argc + numOptions - 1; i++ )
00877        args.append( argv[ i + 1 ] );
00878 #endif
00879 
00880     if( readStdin && args.count() < 3 )
00881     {
00882     cerr_ << "--pipe option only supported for function calls!" << endl << endl;
00883     showHelp( -1 );
00884     }
00885 
00886     if( user == "*" && args.count() < 3 && session != QuerySessions )
00887     {
00888     cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
00889     showHelp( -1 );
00890     }
00891 
00892     if( session == QuerySessions && !args.isEmpty() )
00893     {
00894     cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
00895     showHelp( -1 );
00896     }
00897 
00898     if( session == QuerySessions && user.isEmpty() )
00899     {
00900     cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
00901          << "--all-users options!" << endl << endl;
00902     showHelp( -1 );
00903     }
00904 
00905     if( session != DefaultSession && session != QuerySessions &&
00906         args.count() < 3 )
00907     {
00908     cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
00909          << "calls!" << endl << endl;
00910     showHelp( -1 );
00911     }
00912 
00913     UserList users;
00914     if( user == "*" )
00915     users = userList();
00916     else if( !user.isEmpty() )
00917     users[ user ] = userList()[ user ];
00918 
00919     int retval = runDCOP( args, users, session, sessionName, readStdin, updateUserTime );
00920 
00921     return retval;
00922 }
00923 
00924 // vim: set ts=8 sts=4 sw=4 noet:
00925 

dcop

Skip menu "dcop"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

dcop

Skip menu "dcop"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for dcop by doxygen 1.7.1
This website is maintained by Timothy Pearson.