• 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 iceFileBase = "ICEauthority";
00598         TQString iceFile;
00599         TQFileInfo fi;
00600 
00601         if (getenv("XDG_RUNTIME_DIR") != 0 )
00602         {
00603         TQFileInfo xdgRuntime(getenv("XDG_RUNTIME_DIR"));
00604         passwd* pstruct = getpwnam(it.key().local8Bit());
00605         if (pstruct)
00606         {
00607             iceFile = TQString("%1/%2/%3").arg(xdgRuntime.dirPath()).arg(pstruct->pw_uid).arg(iceFileBase);
00608             fi.setFile(iceFile);
00609         }
00610         if (!pstruct || !fi.exists())
00611         {
00612             iceFile = TQString::null;
00613         }
00614         }
00615         if (iceFile.isEmpty())
00616         {
00617         iceFile = TQString("%1/.%2").arg(it.data()).arg(iceFileBase);
00618         fi.setFile(iceFile);
00619         }
00620         if( iceFile.isEmpty() )
00621         {
00622         cerr_ << "WARNING: Cannot determine home directory for user "
00623              << it.key() << "!" << endl
00624              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00625              << "calling dcop." << endl;
00626         }
00627         else if( fi.exists() )
00628         {
00629         if( fi.isReadable() )
00630         {
00631             char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
00632             putenv( envStr );
00633             //cerr_ << "ice: " << envStr << endl;
00634         }
00635         else
00636         {
00637             cerr_ << "WARNING: ICE authority file " << iceFile
00638              << "is not readable by you!" << endl
00639              << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
00640              << "calling dcop." << endl;
00641         }
00642         }
00643         else
00644         {
00645         if( users.count() > 1 )
00646             continue;
00647         else
00648         {
00649             cerr_ << "WARNING: Cannot find ICE authority file "
00650                  << iceFile << "!" << endl
00651              << "Please check permissions or set the $ICEAUTHORITY"
00652              << " variable manually before" << endl
00653              << "calling dcop." << endl;
00654         }
00655         }
00656     }
00657 
00658     // Main loop
00659     // If users is an empty list we're calling for the currently logged
00660     // in user. In this case we don't have a session, but still want
00661     // to iterate the loop once.
00662     TQStringList::Iterator sIt = sessions.begin();
00663     for( ; sIt != sessions.end() || users.isEmpty(); ++sIt )
00664     {
00665         if( !presetDCOPServer && !users.isEmpty() )
00666         {
00667         TQString dcopFile = it.data() + "/" + *sIt;
00668         TQFile f( dcopFile );
00669         if( !f.open( IO_ReadOnly ) )
00670         {
00671             cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
00672             exit( -1 );
00673         }
00674 
00675         TQStringList l( TQStringList::split( '\n', f.readAll() ) );
00676         dcopServer = l.first();
00677 
00678         if( dcopServer.isEmpty() )
00679         {
00680             cerr_ << "WARNING: Unable to determine DCOP server for session "
00681              << *sIt << "!" << endl
00682              << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
00683              << "calling dcop." << endl;
00684             exit( -1 );
00685         }
00686         }
00687 
00688         delete client;
00689         client = new DCOPClient;
00690         if( !dcopServer.isEmpty() )
00691         client->setServerAddress( dcopServer.ascii() );
00692         bool success = client->attach();
00693         if( !success )
00694         {
00695         cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
00696         retval = TQMAX( retval, 1 );
00697         if( users.isEmpty() )
00698             break;
00699         else
00700             continue;
00701         }
00702         dcop = client;
00703 
00704         int argscount = args.count();
00705         if ( DCOPrefmode )
00706           argscount++;
00707         switch ( argscount )
00708         {
00709         case 0:
00710         queryApplications("");
00711         break;
00712         case 1:
00713         if (endsWith(app, '*'))
00714            queryApplications(app);
00715         else
00716            queryObjects( app, "" );
00717         break;
00718         case 2:
00719         if (endsWith(objid, '*'))
00720            queryObjects(app, objid);
00721         else
00722            queryFunctions( app, objid );
00723         break;
00724         case 3:
00725         default:
00726                 if( updateUserTime )
00727                     sendUserTime( app );
00728         if( readStdin )
00729         {
00730             QCStringList::Iterator replaceArg = params.end();
00731 
00732             QCStringList::Iterator it = params.begin();
00733             for( ; it != params.end(); ++it )
00734             if( *it == "%1" )
00735                 replaceArg = it;
00736 
00737             // Read from stdin until EOF and call function for each
00738             // read line
00739             while ( !cin_.atEnd() )
00740             {
00741             TQString buf = cin_.readLine();
00742 
00743             if( replaceArg != params.end() )
00744                 *replaceArg = buf.local8Bit();
00745 
00746             if( !buf.isNull() )
00747             {
00748                 int res = callFunction( app, objid, function, params );
00749                 retval = TQMAX( retval, res );
00750             }
00751             }
00752         }
00753         else
00754         {
00755             // Just call function
00756 //          cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
00757             int res = callFunction( app, objid, function, params );
00758             retval = TQMAX( retval, res );
00759         }
00760         break;
00761         }
00762         // Another sIt++ would make the loop infinite...
00763         if( users.isEmpty() )
00764         break;
00765     }
00766 
00767     // Another it++ would make the loop infinite...
00768     if( it == users.end() )
00769         break;
00770     }
00771 
00772     return retval;
00773 }
00774 
00775 #ifdef Q_OS_WIN
00776 # define main kdemain
00777 #endif
00778 
00779 int main( int argc, char** argv )
00780 {
00781     bool readStdin = false;
00782     int numOptions = 0;
00783     TQString user;
00784     Session session = DefaultSession;
00785     TQString sessionName;
00786     bool updateUserTime = true;
00787 
00788     cin_.setEncoding( TQTextStream::Locale );
00789 
00790     // Scan for command-line options first
00791     for( int pos = 1 ; pos <= argc - 1 ; pos++ )
00792     {
00793     if( strcmp( argv[ pos ], "--help" ) == 0 )
00794         showHelp( 0 );
00795     else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
00796     {
00797         readStdin = true;
00798         numOptions++;
00799     }
00800     else if( strcmp( argv[ pos ], "--user" ) == 0 )
00801     {
00802         if( pos <= argc - 2 )
00803         {
00804         user = TQString::fromLocal8Bit( argv[ pos + 1] );
00805         numOptions +=2;
00806         pos++;
00807         }
00808         else
00809         {
00810         cerr_ << "Missing username for '--user' option!" << endl << endl;
00811         showHelp( -1 );
00812         }
00813     }
00814     else if( strcmp( argv[ pos ], "--session" ) == 0 )
00815     {
00816         if( session == AllSessions )
00817         {
00818         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00819         showHelp( -1 );
00820         }
00821         else if( pos <= argc - 2 )
00822         {
00823         sessionName = TQString::fromLocal8Bit( argv[ pos + 1] );
00824         numOptions +=2;
00825         pos++;
00826         }
00827         else
00828         {
00829         cerr_ << "Missing session name for '--session' option!" << endl << endl;
00830         showHelp( -1 );
00831         }
00832     }
00833     else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
00834     {
00835         user = "*";
00836         numOptions ++;
00837     }
00838     else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
00839     {
00840         session = QuerySessions;
00841         numOptions ++;
00842     }
00843     else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
00844     {
00845         if( !sessionName.isEmpty() )
00846         {
00847         cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
00848         showHelp( -1 );
00849         }
00850         session = AllSessions;
00851         numOptions ++;
00852     }
00853         else if( strcmp( argv[ pos ], "--no-user-time" ) == 0 )
00854         {
00855             updateUserTime = false;
00856             numOptions ++;
00857         }
00858     else if( argv[ pos ][ 0 ] == '-' )
00859     {
00860         cerr_ << "Unknown command-line option '" << argv[ pos ]
00861          << "'." << endl << endl;
00862         showHelp( -1 );
00863     }
00864     else
00865         break;  // End of options
00866     }
00867 
00868     argc -= numOptions;
00869 
00870     QCStringList args;
00871     
00872 #ifdef DCOPQUIT
00873     if (argc > 1)
00874     {
00875        TQCString prog = argv[ numOptions + 1 ];
00876        
00877        if (!prog.isEmpty())
00878        {
00879           args.append( prog );
00880        
00881           // Pass as-is if it ends with a wildcard
00882           if (prog[prog.length()-1] != '*')
00883           {
00884              // Strip a trailing -<PID> part.
00885              int i = prog.findRev('-');
00886              if ((i >= 0) && prog.mid(i+1).toLong())
00887              {
00888                 prog = prog.left(i);      
00889              }
00890              args.append( "qt/"+prog ); 
00891              args.append( "quit()" );
00892           }
00893        }
00894     }
00895 #else
00896     for( int i = numOptions; i < argc + numOptions - 1; i++ )
00897        args.append( argv[ i + 1 ] );
00898 #endif
00899 
00900     if( readStdin && args.count() < 3 )
00901     {
00902     cerr_ << "--pipe option only supported for function calls!" << endl << endl;
00903     showHelp( -1 );
00904     }
00905 
00906     if( user == "*" && args.count() < 3 && session != QuerySessions )
00907     {
00908     cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
00909     showHelp( -1 );
00910     }
00911 
00912     if( session == QuerySessions && !args.isEmpty() )
00913     {
00914     cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
00915     showHelp( -1 );
00916     }
00917 
00918     if( session == QuerySessions && user.isEmpty() )
00919     {
00920     cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
00921          << "--all-users options!" << endl << endl;
00922     showHelp( -1 );
00923     }
00924 
00925     if( session != DefaultSession && session != QuerySessions &&
00926         args.count() < 3 )
00927     {
00928     cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
00929          << "calls!" << endl << endl;
00930     showHelp( -1 );
00931     }
00932 
00933     UserList users;
00934     if( user == "*" )
00935     users = userList();
00936     else if( !user.isEmpty() )
00937     users[ user ] = userList()[ user ];
00938 
00939     int retval = runDCOP( args, users, session, sessionName, readStdin, updateUserTime );
00940 
00941     return retval;
00942 }
00943 
00944 // vim: set ts=8 sts=4 sw=4 noet:
00945 

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.6.1
This website is maintained by Timothy Pearson.