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