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

dcop

  • dcop
  • client
dcop.cpp
1 /*****************************************************************
2 Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 ******************************************************************/
22 
23 // putenv() is not available on all platforms, so make sure the emulation
24 // wrapper is available in those cases by loading config.h!
25 #include <config.h>
26 
27 #include <sys/types.h>
28 #include <pwd.h>
29 #include <ctype.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 
33 #include <tqbuffer.h>
34 #include <tqcolor.h>
35 #include <tqdir.h>
36 #include <tqfile.h>
37 #include <tqfileinfo.h>
38 #include <tqimage.h>
39 #include <tqmap.h>
40 #include <tqstringlist.h>
41 #include <tqtextstream.h>
42 #include <tqvariant.h>
43 
44 #include "../dcopclient.h"
45 #include "../dcopref.h"
46 #include "../kdatastream.h"
47 
48 #include "marshall.cpp"
49 
50 #if defined Q_WS_X11
51 #include <X11/Xlib.h>
52 #include <X11/Xatom.h>
53 #endif
54 
55 typedef TQMap<TQString, TQString> UserList;
56 
57 static DCOPClient* dcop = 0;
58 
59 static TQTextStream cin_ ( stdin, IO_ReadOnly );
60 static TQTextStream cout_( stdout, IO_WriteOnly );
61 static TQTextStream cerr_( stderr, IO_WriteOnly );
62 
72 enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
73 
74 bool startsWith(const TQCString &id, const char *str, int n)
75 {
76  return !n || (strncmp(id.data(), str, n) == 0);
77 }
78 
79 bool endsWith(TQCString &id, char c)
80 {
81  if (id.length() && (id[id.length()-1] == c))
82  {
83  id.truncate(id.length()-1);
84  return true;
85  }
86  return false;
87 }
88 
89 void queryApplications(const TQCString &filter)
90 {
91  int filterLen = filter.length();
92  QCStringList apps = dcop->registeredApplications();
93  for ( QCStringList::Iterator it = apps.begin(); it != apps.end(); ++it )
94  {
95  TQCString &clientId = *it;
96  if ( (clientId != dcop->appId()) &&
97  !startsWith(clientId, "anonymous",9) &&
98  startsWith(clientId, filter, filterLen)
99  )
100  printf( "%s\n", clientId.data() );
101  }
102 
103  if ( !dcop->isAttached() )
104  {
105  tqWarning( "server not accessible" );
106  exit(1);
107  }
108 }
109 
110 void queryObjects( const TQCString &app, const TQCString &filter )
111 {
112  int filterLen = filter.length();
113  bool ok = false;
114  bool isDefault = false;
115  QCStringList objs = dcop->remoteObjects( app, &ok );
116  for ( QCStringList::Iterator it = objs.begin(); it != objs.end(); ++it )
117  {
118  TQCString &objId = *it;
119 
120  if (objId == "default")
121  {
122  isDefault = true;
123  continue;
124  }
125 
126  if (startsWith(objId, filter, filterLen))
127  {
128  if (isDefault)
129  printf( "%s (default)\n", objId.data() );
130  else
131  printf( "%s\n", objId.data() );
132  }
133  isDefault = false;
134  }
135  if ( !ok )
136  {
137  if (!dcop->isApplicationRegistered(app))
138  tqWarning( "No such application: '%s'", app.data());
139  else
140  tqWarning( "Application '%s' not accessible", app.data() );
141  exit(1);
142  }
143 }
144 
145 void queryFunctions( const char* app, const char* obj )
146 {
147  bool ok = false;
148  QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
149  for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
150  printf( "%s\n", (*it).data() );
151  }
152  if ( !ok )
153  {
154  tqWarning( "object '%s' in application '%s' not accessible", obj, app );
155  exit( 1 );
156  }
157 }
158 
159 int callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
160 {
161  TQString f = func; // Qt is better with unicode strings, so use one.
162  int left = f.find( '(' );
163  int right = f.find( ')' );
164 
165  if ( right < left )
166  {
167  tqWarning( "parentheses do not match" );
168  return( 1 );
169  }
170 
171  if ( left < 0 ) {
172  // try to get the interface from the server
173  bool ok = false;
174  QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
175  TQCString realfunc;
176  if ( !ok && args.isEmpty() )
177  goto doit;
178  if ( !ok )
179  {
180  tqWarning( "object not accessible" );
181  return( 1 );
182  }
183  for ( QCStringList::Iterator it = funcs.begin(); it != funcs.end(); ++it ) {
184  int l = (*it).find( '(' );
185  int s;
186  if (l > 0)
187  s = (*it).findRev( ' ', l);
188  else
189  s = (*it).find( ' ' );
190 
191  if ( s < 0 )
192  s = 0;
193  else
194  s++;
195 
196  if ( l > 0 && (*it).mid( s, l - s ) == func ) {
197  realfunc = (*it).mid( s );
198  const TQString arguments = (*it).mid(l+1,(*it).find( ')' )-l-1);
199  uint a = arguments.contains(',');
200  if ( (a==0 && !arguments.isEmpty()) || a>0)
201  a++;
202  if ( a == args.count() )
203  break;
204  }
205  }
206  if ( realfunc.isEmpty() )
207  {
208  tqWarning("no such function");
209  return( 1 );
210  }
211  f = realfunc;
212  left = f.find( '(' );
213  right = f.find( ')' );
214  }
215 
216  doit:
217  if ( left < 0 )
218  f += "()";
219 
220  // This may seem expensive but is done only once per invocation
221  // of dcop, so it should be OK.
222  //
223  //
224  TQStringList intTypes;
225  intTypes << "int" << "unsigned" << "long" << "bool" ;
226 
227  TQStringList types;
228  if ( left >0 && left + 1 < right - 1) {
229  types = TQStringList::split( ',', f.mid( left + 1, right - left - 1) );
230  for ( TQStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
231  TQString lt = (*it).simplifyWhiteSpace();
232 
233  int s = lt.find(' ');
234 
235  // If there are spaces in the name, there may be two
236  // reasons: the parameter name is still there, ie.
237  // "TQString URL" or it's a complicated int type, ie.
238  // "unsigned long long int bool".
239  //
240  //
241  if ( s > 0 )
242  {
243  TQStringList partl = TQStringList::split(' ' , lt);
244 
245  // The zero'th part is -- at the very least -- a
246  // type part. Any trailing parts *might* be extra
247  // int-type keywords, or at most one may be the
248  // parameter name.
249  //
250  //
251  s=1;
252 
253  while (s < static_cast<int>(partl.count()) && intTypes.contains(partl[s]))
254  {
255  s++;
256  }
257 
258  if ( s < static_cast<int>(partl.count())-1)
259  {
260  tqWarning("The argument `%s' seems syntactically wrong.",
261  lt.latin1());
262  }
263  if ( s == static_cast<int>(partl.count())-1)
264  {
265  partl.remove(partl.at(s));
266  }
267 
268  lt = partl.join(" ");
269  lt = lt.simplifyWhiteSpace();
270  }
271 
272  (*it) = lt;
273  }
274  TQString fc = f.left( left );
275  fc += '(';
276  bool first = true;
277  for ( TQStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
278  if ( !first )
279  fc +=",";
280  first = false;
281  fc += *it;
282  }
283  fc += ')';
284  f = fc;
285  }
286 
287  TQByteArray data, replyData;
288  TQCString replyType;
289  TQDataStream arg(data, IO_WriteOnly);
290 
291  uint i = 0;
292  for( TQStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
293  marshall( arg, args, i, *it );
294  }
295 
296  if ( i != args.count() )
297  {
298  tqWarning( "arguments do not match" );
299  return( 1 );
300  }
301 
302  if ( !dcop->call( app, obj, f.latin1(), data, replyType, replyData) ) {
303  tqWarning( "call failed");
304  return( 1 );
305  } else {
306  TQDataStream reply(replyData, IO_ReadOnly);
307 
308  if ( replyType != "void" && replyType != "ASYNC" )
309  {
310  TQCString replyString = demarshal( reply, replyType );
311  if ( !replyString.isEmpty() )
312  printf( "%s\n", replyString.data() );
313  else
314  printf("\n");
315  }
316  }
317  return 0;
318 }
319 
323 void showHelp( int exitCode = 0 )
324 {
325 #ifdef DCOPQUIT
326  cout_ << "Usage: dcopquit [options] [application]" << endl
327 #else
328  cout_ << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
329 #endif
330  << "" << endl
331  << "Console DCOP client" << endl
332  << "" << endl
333  << "Generic options:" << endl
334  << " --help Show help about options" << endl
335  << "" << endl
336  << "Options:" << endl
337  << " --pipe Call DCOP for each line read from stdin. The string '%1'" << endl
338  << " will be used in the argument list as a placeholder for" << endl
339  << " the substituted line." << endl
340  << " For example," << endl
341  << " dcop --pipe konqueror html-widget1 evalJS %1" << endl
342  << " is equivalent to calling" << endl
343  << " while read line ; do" << endl
344  << " dcop konqueror html-widget1 evalJS \"$line\"" << endl
345  << " done" << endl
346  << " in bash, but because no new dcop instance has to be started" << endl
347  << " for each line this is generally much faster, especially for" << endl
348  << " the slower GNU dynamic linkers." << endl
349  << " The '%1' placeholder cannot be used to replace e.g. the" << endl
350  << " program, object or method name." << endl
351  << " --user <user> Connect to the given user's DCOP server. This option will" << endl
352  << " ignore the values of the environment vars $DCOPSERVER and" << endl
353  << " $ICEAUTHORITY, even if they are set." << endl
354  << " If the user has more than one open session, you must also" << endl
355  << " use one of the --list-sessions, --session or --all-sessions" << endl
356  << " command-line options." << endl
357  << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
358  << " server. Only failed calls to existing DCOP servers will" << endl
359  << " generate an error message. If no DCOP server is available" << endl
360  << " at all, no error will be generated." << endl
361  << " --session <ses> Send to the given TDE session. This option can only be" << endl
362  << " used in combination with the --user option." << endl
363  << " --all-sessions Send to all sessions found. Only works with the --user" << endl
364  << " and --all-users options." << endl
365  << " --list-sessions List all active TDE session for a user or all users." << endl
366  << " --no-user-time Don't update the user activity timestamp in the called" << endl
367  << " application (for usage in scripts running" << endl
368  << " in the background)." << endl
369  << endl;
370 
371  exit( exitCode );
372 }
373 
378 static UserList userList()
379 {
380  UserList result;
381 
382  while( passwd* pstruct = getpwent() )
383  {
384  result[ TQString::fromLocal8Bit(pstruct->pw_name) ] = TQFile::decodeName(pstruct->pw_dir);
385  }
386 
387  return result;
388 }
389 
394 TQStringList dcopSessionList( const TQString &user, const TQString &home )
395 {
396  if( home.isEmpty() )
397  {
398  cerr_ << "WARNING: Cannot determine home directory for user "
399  << user << "!" << endl
400  << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
401  << "calling dcop." << endl;
402  return TQStringList();
403  }
404 
405  TQStringList result;
406  TQFileInfo dirInfo( home );
407  if( !dirInfo.exists() || !dirInfo.isReadable() )
408  return result;
409 
410  TQDir d( home );
411  d.setFilter( TQDir::Files | TQDir::Hidden | TQDir::NoSymLinks );
412  d.setNameFilter( ".DCOPserver*" );
413 
414  const TQFileInfoList *list = d.entryInfoList();
415  if( !list )
416  return result;
417 
418  TQFileInfoListIterator it( *list );
419  TQFileInfo *fi;
420 
421  while ( ( fi = it.current() ) != 0 )
422  {
423  if( fi->isReadable() )
424  result.append( fi->fileName() );
425  ++it;
426  }
427  return result;
428 }
429 
430 void sendUserTime( const char* app )
431 {
432 #if defined Q_WS_X11
433  static unsigned long time = 0;
434  if( time == 0 )
435  {
436  Display* dpy = XOpenDisplay( NULL );
437  if( dpy != NULL )
438  {
439  Window w = XCreateSimpleWindow( dpy, DefaultRootWindow( dpy ), 0, 0, 1, 1, 0, 0, 0 );
440  XSelectInput( dpy, w, PropertyChangeMask );
441  unsigned char data[ 1 ];
442  XChangeProperty( dpy, w, XA_ATOM, XA_ATOM, 8, PropModeAppend, data, 1 );
443  XEvent ev;
444  XWindowEvent( dpy, w, PropertyChangeMask, &ev );
445  time = ev.xproperty.time;
446  XDestroyWindow( dpy, w );
447  }
448  }
449  DCOPRef( app, "MainApplication-Interface" ).call( "updateUserTimestamp", time );
450 #else
451 // ...
452 #endif
453 }
454 
458 int runDCOP( QCStringList args, UserList users, Session session,
459  const TQString sessionName, bool readStdin, bool updateUserTime )
460 {
461  bool DCOPrefmode=false;
462  TQCString app;
463  TQCString objid;
464  TQCString function;
465  QCStringList params;
466  DCOPClient *client = 0L;
467  int retval = 0;
468  if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
469  {
470  int delimPos = args[ 0 ].findRev( ',' );
471  if( delimPos == -1 )
472  {
473  cerr_ << "Error: '" << args[ 0 ]
474  << "' is not a valid DCOP reference." << endl;
475  exit( -1 );
476  }
477  app = args[ 0 ].mid( 8, delimPos-8 );
478  delimPos++;
479  objid = args[ 0 ].mid( delimPos, args[ 0 ].length()-delimPos-1 );
480  if( args.count() > 1 )
481  function = args[ 1 ];
482  if( args.count() > 2 )
483  {
484  params = args;
485  params.remove( params.begin() );
486  params.remove( params.begin() );
487  }
488  DCOPrefmode=true;
489  }
490  else
491  {
492  if( !args.isEmpty() )
493  app = args[ 0 ];
494  if( args.count() > 1 )
495  objid = args[ 1 ];
496  if( args.count() > 2 )
497  function = args[ 2 ];
498  if( args.count() > 3)
499  {
500  params = args;
501  params.remove( params.begin() );
502  params.remove( params.begin() );
503  params.remove( params.begin() );
504  }
505  }
506 
507  bool firstRun = true;
508  UserList::Iterator it;
509  TQStringList sessions;
510  bool presetDCOPServer = false;
511 // char *dcopStr = 0L;
512  TQString dcopServer;
513 
514  for( it = users.begin(); it != users.end() || firstRun; ++it )
515  {
516  firstRun = false;
517 
518  //cout_ << "Iterating '" << it.key() << "'" << endl;
519 
520  if( session == QuerySessions )
521  {
522  TQStringList sessions = dcopSessionList( it.key(), it.data() );
523  if( sessions.isEmpty() )
524  {
525  if( users.count() <= 1 )
526  {
527  cout_ << "No active sessions";
528  if( !( *it ).isEmpty() )
529  cout_ << " for user " << *it;
530  cout_ << endl;
531  }
532  }
533  else
534  {
535  cout_ << "Active sessions ";
536  if( !( *it ).isEmpty() )
537  cout_ << "for user " << *it << " ";
538  cout_ << ":" << endl;
539 
540  TQStringList::Iterator sIt = sessions.begin();
541  for( ; sIt != sessions.end(); ++sIt )
542  cout_ << " " << *sIt << endl;
543 
544  cout_ << endl;
545  }
546  continue;
547  }
548 
549  if( getenv( "DCOPSERVER" ) )
550  {
551  sessions.append( getenv( "DCOPSERVER" ) );
552  presetDCOPServer = true;
553  }
554 
555  if( users.count() > 1 || ( users.count() == 1 &&
556  ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
557  {
558  sessions = dcopSessionList( it.key(), it.data() );
559  if( sessions.isEmpty() )
560  {
561  if( users.count() > 1 )
562  continue;
563  else
564  {
565  cerr_ << "ERROR: No active TDE sessions!" << endl
566  << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
567  << "before calling dcop." << endl;
568  exit( -1 );
569  }
570  }
571  else if( !sessionName.isEmpty() )
572  {
573  if( sessions.contains( sessionName ) )
574  {
575  sessions.clear();
576  sessions.append( sessionName );
577  }
578  else
579  {
580  cerr_ << "ERROR: The specified session doesn't exist!" << endl;
581  exit( -1 );
582  }
583  }
584  else if( sessions.count() > 1 && session != AllSessions )
585  {
586  cerr_ << "ERROR: Multiple available TDE sessions!" << endl
587  << "Please specify the correct session to use with --session or use the" << endl
588  << "--all-sessions option to broadcast to all sessions." << endl;
589  exit( -1 );
590  }
591  }
592 
593  if( users.count() > 1 || ( users.count() == 1 &&
594  ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
595  {
596  // Check for ICE authority file and if the file can be read by us
597  TQString iceFileBase = "ICEauthority";
598  TQString iceFile;
599  TQFileInfo fi;
600 
601  if (getenv("XDG_RUNTIME_DIR") != 0 )
602  {
603  TQFileInfo xdgRuntime(getenv("XDG_RUNTIME_DIR"));
604  passwd* pstruct = getpwnam(it.key().local8Bit());
605  if (pstruct)
606  {
607  iceFile = TQString("%1/%2/%3").arg(xdgRuntime.dirPath()).arg(pstruct->pw_uid).arg(iceFileBase);
608  fi.setFile(iceFile);
609  }
610  if (!pstruct || !fi.exists())
611  {
612  iceFile = TQString::null;
613  }
614  }
615  if (iceFile.isEmpty())
616  {
617  iceFile = TQString("%1/.%2").arg(it.data()).arg(iceFileBase);
618  fi.setFile(iceFile);
619  }
620  if( iceFile.isEmpty() )
621  {
622  cerr_ << "WARNING: Cannot determine home directory for user "
623  << it.key() << "!" << endl
624  << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
625  << "calling dcop." << endl;
626  }
627  else if( fi.exists() )
628  {
629  if( fi.isReadable() )
630  {
631  char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
632  putenv( envStr );
633  //cerr_ << "ice: " << envStr << endl;
634  }
635  else
636  {
637  cerr_ << "WARNING: ICE authority file " << iceFile
638  << "is not readable by you!" << endl
639  << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
640  << "calling dcop." << endl;
641  }
642  }
643  else
644  {
645  if( users.count() > 1 )
646  continue;
647  else
648  {
649  cerr_ << "WARNING: Cannot find ICE authority file "
650  << iceFile << "!" << endl
651  << "Please check permissions or set the $ICEAUTHORITY"
652  << " variable manually before" << endl
653  << "calling dcop." << endl;
654  }
655  }
656  }
657 
658  // Main loop
659  // If users is an empty list we're calling for the currently logged
660  // in user. In this case we don't have a session, but still want
661  // to iterate the loop once.
662  TQStringList::Iterator sIt = sessions.begin();
663  for( ; sIt != sessions.end() || users.isEmpty(); ++sIt )
664  {
665  if( !presetDCOPServer && !users.isEmpty() )
666  {
667  TQString dcopFile = it.data() + "/" + *sIt;
668  TQFile f( dcopFile );
669  if( !f.open( IO_ReadOnly ) )
670  {
671  cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
672  exit( -1 );
673  }
674 
675  TQStringList l( TQStringList::split( '\n', f.readAll() ) );
676  dcopServer = l.first();
677 
678  if( dcopServer.isEmpty() )
679  {
680  cerr_ << "WARNING: Unable to determine DCOP server for session "
681  << *sIt << "!" << endl
682  << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
683  << "calling dcop." << endl;
684  exit( -1 );
685  }
686  }
687 
688  delete client;
689  client = new DCOPClient;
690  if( !dcopServer.isEmpty() )
691  client->setServerAddress( dcopServer.ascii() );
692  bool success = client->attach();
693  if( !success )
694  {
695  cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
696  retval = TQMAX( retval, 1 );
697  if( users.isEmpty() )
698  break;
699  else
700  continue;
701  }
702  dcop = client;
703 
704  int argscount = args.count();
705  if ( DCOPrefmode )
706  argscount++;
707  switch ( argscount )
708  {
709  case 0:
710  queryApplications("");
711  break;
712  case 1:
713  if (endsWith(app, '*'))
714  queryApplications(app);
715  else
716  queryObjects( app, "" );
717  break;
718  case 2:
719  if (endsWith(objid, '*'))
720  queryObjects(app, objid);
721  else
722  queryFunctions( app, objid );
723  break;
724  case 3:
725  default:
726  if( updateUserTime )
727  sendUserTime( app );
728  if( readStdin )
729  {
730  QCStringList::Iterator replaceArg = params.end();
731 
732  QCStringList::Iterator it = params.begin();
733  for( ; it != params.end(); ++it )
734  if( *it == "%1" )
735  replaceArg = it;
736 
737  // Read from stdin until EOF and call function for each
738  // read line
739  while ( !cin_.atEnd() )
740  {
741  TQString buf = cin_.readLine();
742 
743  if( replaceArg != params.end() )
744  *replaceArg = buf.local8Bit();
745 
746  if( !buf.isNull() )
747  {
748  int res = callFunction( app, objid, function, params );
749  retval = TQMAX( retval, res );
750  }
751  }
752  }
753  else
754  {
755  // Just call function
756 // cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
757  int res = callFunction( app, objid, function, params );
758  retval = TQMAX( retval, res );
759  }
760  break;
761  }
762  // Another sIt++ would make the loop infinite...
763  if( users.isEmpty() )
764  break;
765  }
766 
767  // Another it++ would make the loop infinite...
768  if( it == users.end() )
769  break;
770  }
771 
772  return retval;
773 }
774 
775 #ifdef Q_OS_WIN
776 # define main kdemain
777 #endif
778 
779 int main( int argc, char** argv )
780 {
781  bool readStdin = false;
782  int numOptions = 0;
783  TQString user;
784  Session session = DefaultSession;
785  TQString sessionName;
786  bool updateUserTime = true;
787 
788  cin_.setEncoding( TQTextStream::Locale );
789 
790  // Scan for command-line options first
791  for( int pos = 1 ; pos <= argc - 1 ; pos++ )
792  {
793  if( strcmp( argv[ pos ], "--help" ) == 0 )
794  showHelp( 0 );
795  else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
796  {
797  readStdin = true;
798  numOptions++;
799  }
800  else if( strcmp( argv[ pos ], "--user" ) == 0 )
801  {
802  if( pos <= argc - 2 )
803  {
804  user = TQString::fromLocal8Bit( argv[ pos + 1] );
805  numOptions +=2;
806  pos++;
807  }
808  else
809  {
810  cerr_ << "Missing username for '--user' option!" << endl << endl;
811  showHelp( -1 );
812  }
813  }
814  else if( strcmp( argv[ pos ], "--session" ) == 0 )
815  {
816  if( session == AllSessions )
817  {
818  cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
819  showHelp( -1 );
820  }
821  else if( pos <= argc - 2 )
822  {
823  sessionName = TQString::fromLocal8Bit( argv[ pos + 1] );
824  numOptions +=2;
825  pos++;
826  }
827  else
828  {
829  cerr_ << "Missing session name for '--session' option!" << endl << endl;
830  showHelp( -1 );
831  }
832  }
833  else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
834  {
835  user = "*";
836  numOptions ++;
837  }
838  else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
839  {
840  session = QuerySessions;
841  numOptions ++;
842  }
843  else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
844  {
845  if( !sessionName.isEmpty() )
846  {
847  cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
848  showHelp( -1 );
849  }
850  session = AllSessions;
851  numOptions ++;
852  }
853  else if( strcmp( argv[ pos ], "--no-user-time" ) == 0 )
854  {
855  updateUserTime = false;
856  numOptions ++;
857  }
858  else if( argv[ pos ][ 0 ] == '-' )
859  {
860  cerr_ << "Unknown command-line option '" << argv[ pos ]
861  << "'." << endl << endl;
862  showHelp( -1 );
863  }
864  else
865  break; // End of options
866  }
867 
868  argc -= numOptions;
869 
870  QCStringList args;
871 
872 #ifdef DCOPQUIT
873  if (argc > 1)
874  {
875  TQCString prog = argv[ numOptions + 1 ];
876 
877  if (!prog.isEmpty())
878  {
879  args.append( prog );
880 
881  // Pass as-is if it ends with a wildcard
882  if (prog[prog.length()-1] != '*')
883  {
884  // Strip a trailing -<PID> part.
885  int i = prog.findRev('-');
886  if ((i >= 0) && prog.mid(i+1).toLong())
887  {
888  prog = prog.left(i);
889  }
890  args.append( "qt/"+prog );
891  args.append( "quit()" );
892  }
893  }
894  }
895 #else
896  for( int i = numOptions; i < argc + numOptions - 1; i++ )
897  args.append( argv[ i + 1 ] );
898 #endif
899 
900  if( readStdin && args.count() < 3 )
901  {
902  cerr_ << "--pipe option only supported for function calls!" << endl << endl;
903  showHelp( -1 );
904  }
905 
906  if( user == "*" && args.count() < 3 && session != QuerySessions )
907  {
908  cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
909  showHelp( -1 );
910  }
911 
912  if( session == QuerySessions && !args.isEmpty() )
913  {
914  cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
915  showHelp( -1 );
916  }
917 
918  if( session == QuerySessions && user.isEmpty() )
919  {
920  cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
921  << "--all-users options!" << endl << endl;
922  showHelp( -1 );
923  }
924 
925  if( session != DefaultSession && session != QuerySessions &&
926  args.count() < 3 )
927  {
928  cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
929  << "calls!" << endl << endl;
930  showHelp( -1 );
931  }
932 
933  UserList users;
934  if( user == "*" )
935  users = userList();
936  else if( !user.isEmpty() )
937  users[ user ] = userList()[ user ];
938 
939  int retval = runDCOP( args, users, session, sessionName, readStdin, updateUserTime );
940 
941  return retval;
942 }
DCOPClient::setServerAddress
static void setServerAddress(const TQCString &addr)
Sets the address of a server to use upon attaching.
Definition: dcopclient.cpp:671
DCOPClient::isApplicationRegistered
bool isApplicationRegistered(const TQCString &remApp)
Checks whether remApp is registered with the DCOP server.
Definition: dcopclient.cpp:1250
DCOPClient::attach
bool attach()
Attaches to the DCOP server.
Definition: dcopclient.cpp:679
DCOPRef
A DCOPRef(erence) encapsulates a remote DCOP object as a triple where type is optional...
Definition: dcopref.h:278
DCOPClient
Inter-process communication and remote procedure calls for KDE applications.
Definition: dcopclient.h:68
DCOPClient::registeredApplications
QCStringList registeredApplications()
Retrieves the list of all currently registered applications from dcopserver.
Definition: dcopclient.cpp:1264
DCOPRef::call
DCOPReply call(const TQCString &fun)
Calls the function fun on the object referenced by this reference.
Definition: dcopref.h:417
DCOPClient::appId
TQCString appId() const
Returns the current app id or a null string if the application hasn't yet been registered.
Definition: dcopclient.cpp:1024
DCOPClient::remoteFunctions
QCStringList remoteFunctions(const TQCString &remApp, const TQCString &remObj, bool *ok=0)
Retrieves the list of functions of the remote object remObj of application remApp.
Definition: dcopclient.cpp:1308
DCOPClient::remoteObjects
QCStringList remoteObjects(const TQCString &remApp, bool *ok=0)
Retrieves the list of objects of the remote application remApp.
Definition: dcopclient.cpp:1276
DCOPClient::isAttached
bool isAttached() const
Returns whether or not the client is attached to the server.
Definition: dcopclient.cpp:937
endl
kndbgstream & endl(kndbgstream &s)
DCOPClient::call
bool call(const TQCString &remApp, const TQCString &remObj, const TQCString &remFun, const TQByteArray &data, TQCString &replyType, TQByteArray &replyData, bool useEventLoop, int timeout, bool forceRemote)
Performs a synchronous send and receive.
Definition: dcopclient.cpp:1774

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for dcop by doxygen 1.8.8
This website is maintained by Timothy Pearson.