• 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 home = it.data();
598  TQString iceFile = it.data() + "/.ICEauthority";
599  TQFileInfo fi( iceFile );
600  if( iceFile.isEmpty() )
601  {
602  cerr_ << "WARNING: Cannot determine home directory for user "
603  << it.key() << "!" << endl
604  << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
605  << "calling dcop." << endl;
606  }
607  else if( fi.exists() )
608  {
609  if( fi.isReadable() )
610  {
611  char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
612  putenv( envStr );
613  //cerr_ << "ice: " << envStr << endl;
614  }
615  else
616  {
617  cerr_ << "WARNING: ICE authority file " << iceFile
618  << "is not readable by you!" << endl
619  << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
620  << "calling dcop." << endl;
621  }
622  }
623  else
624  {
625  if( users.count() > 1 )
626  continue;
627  else
628  {
629  cerr_ << "WARNING: Cannot find ICE authority file "
630  << iceFile << "!" << endl
631  << "Please check permissions or set the $ICEAUTHORITY"
632  << " variable manually before" << endl
633  << "calling dcop." << endl;
634  }
635  }
636  }
637 
638  // Main loop
639  // If users is an empty list we're calling for the currently logged
640  // in user. In this case we don't have a session, but still want
641  // to iterate the loop once.
642  TQStringList::Iterator sIt = sessions.begin();
643  for( ; sIt != sessions.end() || users.isEmpty(); ++sIt )
644  {
645  if( !presetDCOPServer && !users.isEmpty() )
646  {
647  TQString dcopFile = it.data() + "/" + *sIt;
648  TQFile f( dcopFile );
649  if( !f.open( IO_ReadOnly ) )
650  {
651  cerr_ << "Can't open " << dcopFile << " for reading!" << endl;
652  exit( -1 );
653  }
654 
655  TQStringList l( TQStringList::split( '\n', f.readAll() ) );
656  dcopServer = l.first();
657 
658  if( dcopServer.isEmpty() )
659  {
660  cerr_ << "WARNING: Unable to determine DCOP server for session "
661  << *sIt << "!" << endl
662  << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
663  << "calling dcop." << endl;
664  exit( -1 );
665  }
666  }
667 
668  delete client;
669  client = new DCOPClient;
670  if( !dcopServer.isEmpty() )
671  client->setServerAddress( dcopServer.ascii() );
672  bool success = client->attach();
673  if( !success )
674  {
675  cerr_ << "ERROR: Couldn't attach to DCOP server!" << endl;
676  retval = TQMAX( retval, 1 );
677  if( users.isEmpty() )
678  break;
679  else
680  continue;
681  }
682  dcop = client;
683 
684  int argscount = args.count();
685  if ( DCOPrefmode )
686  argscount++;
687  switch ( argscount )
688  {
689  case 0:
690  queryApplications("");
691  break;
692  case 1:
693  if (endsWith(app, '*'))
694  queryApplications(app);
695  else
696  queryObjects( app, "" );
697  break;
698  case 2:
699  if (endsWith(objid, '*'))
700  queryObjects(app, objid);
701  else
702  queryFunctions( app, objid );
703  break;
704  case 3:
705  default:
706  if( updateUserTime )
707  sendUserTime( app );
708  if( readStdin )
709  {
710  QCStringList::Iterator replaceArg = params.end();
711 
712  QCStringList::Iterator it = params.begin();
713  for( ; it != params.end(); ++it )
714  if( *it == "%1" )
715  replaceArg = it;
716 
717  // Read from stdin until EOF and call function for each
718  // read line
719  while ( !cin_.atEnd() )
720  {
721  TQString buf = cin_.readLine();
722 
723  if( replaceArg != params.end() )
724  *replaceArg = buf.local8Bit();
725 
726  if( !buf.isNull() )
727  {
728  int res = callFunction( app, objid, function, params );
729  retval = TQMAX( retval, res );
730  }
731  }
732  }
733  else
734  {
735  // Just call function
736 // cout_ << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
737  int res = callFunction( app, objid, function, params );
738  retval = TQMAX( retval, res );
739  }
740  break;
741  }
742  // Another sIt++ would make the loop infinite...
743  if( users.isEmpty() )
744  break;
745  }
746 
747  // Another it++ would make the loop infinite...
748  if( it == users.end() )
749  break;
750  }
751 
752  return retval;
753 }
754 
755 #ifdef Q_OS_WIN
756 # define main kdemain
757 #endif
758 
759 int main( int argc, char** argv )
760 {
761  bool readStdin = false;
762  int numOptions = 0;
763  TQString user;
764  Session session = DefaultSession;
765  TQString sessionName;
766  bool updateUserTime = true;
767 
768  cin_.setEncoding( TQTextStream::Locale );
769 
770  // Scan for command-line options first
771  for( int pos = 1 ; pos <= argc - 1 ; pos++ )
772  {
773  if( strcmp( argv[ pos ], "--help" ) == 0 )
774  showHelp( 0 );
775  else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
776  {
777  readStdin = true;
778  numOptions++;
779  }
780  else if( strcmp( argv[ pos ], "--user" ) == 0 )
781  {
782  if( pos <= argc - 2 )
783  {
784  user = TQString::fromLocal8Bit( argv[ pos + 1] );
785  numOptions +=2;
786  pos++;
787  }
788  else
789  {
790  cerr_ << "Missing username for '--user' option!" << endl << endl;
791  showHelp( -1 );
792  }
793  }
794  else if( strcmp( argv[ pos ], "--session" ) == 0 )
795  {
796  if( session == AllSessions )
797  {
798  cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
799  showHelp( -1 );
800  }
801  else if( pos <= argc - 2 )
802  {
803  sessionName = TQString::fromLocal8Bit( argv[ pos + 1] );
804  numOptions +=2;
805  pos++;
806  }
807  else
808  {
809  cerr_ << "Missing session name for '--session' option!" << endl << endl;
810  showHelp( -1 );
811  }
812  }
813  else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
814  {
815  user = "*";
816  numOptions ++;
817  }
818  else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
819  {
820  session = QuerySessions;
821  numOptions ++;
822  }
823  else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
824  {
825  if( !sessionName.isEmpty() )
826  {
827  cerr_ << "ERROR: --session cannot be mixed with --all-sessions!" << endl << endl;
828  showHelp( -1 );
829  }
830  session = AllSessions;
831  numOptions ++;
832  }
833  else if( strcmp( argv[ pos ], "--no-user-time" ) == 0 )
834  {
835  updateUserTime = false;
836  numOptions ++;
837  }
838  else if( argv[ pos ][ 0 ] == '-' )
839  {
840  cerr_ << "Unknown command-line option '" << argv[ pos ]
841  << "'." << endl << endl;
842  showHelp( -1 );
843  }
844  else
845  break; // End of options
846  }
847 
848  argc -= numOptions;
849 
850  QCStringList args;
851 
852 #ifdef DCOPQUIT
853  if (argc > 1)
854  {
855  TQCString prog = argv[ numOptions + 1 ];
856 
857  if (!prog.isEmpty())
858  {
859  args.append( prog );
860 
861  // Pass as-is if it ends with a wildcard
862  if (prog[prog.length()-1] != '*')
863  {
864  // Strip a trailing -<PID> part.
865  int i = prog.findRev('-');
866  if ((i >= 0) && prog.mid(i+1).toLong())
867  {
868  prog = prog.left(i);
869  }
870  args.append( "qt/"+prog );
871  args.append( "quit()" );
872  }
873  }
874  }
875 #else
876  for( int i = numOptions; i < argc + numOptions - 1; i++ )
877  args.append( argv[ i + 1 ] );
878 #endif
879 
880  if( readStdin && args.count() < 3 )
881  {
882  cerr_ << "--pipe option only supported for function calls!" << endl << endl;
883  showHelp( -1 );
884  }
885 
886  if( user == "*" && args.count() < 3 && session != QuerySessions )
887  {
888  cerr_ << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
889  showHelp( -1 );
890  }
891 
892  if( session == QuerySessions && !args.isEmpty() )
893  {
894  cerr_ << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
895  showHelp( -1 );
896  }
897 
898  if( session == QuerySessions && user.isEmpty() )
899  {
900  cerr_ << "ERROR: The --list-sessions option can only be used with the --user or" << endl
901  << "--all-users options!" << endl << endl;
902  showHelp( -1 );
903  }
904 
905  if( session != DefaultSession && session != QuerySessions &&
906  args.count() < 3 )
907  {
908  cerr_ << "ERROR: The --session and --all-sessions options are only supported for function" << endl
909  << "calls!" << endl << endl;
910  showHelp( -1 );
911  }
912 
913  UserList users;
914  if( user == "*" )
915  users = userList();
916  else if( !user.isEmpty() )
917  users[ user ] = userList()[ user ];
918 
919  int retval = runDCOP( args, users, session, sessionName, readStdin, updateUserTime );
920 
921  return retval;
922 }
923 
924 // vim: set ts=8 sts=4 sw=4 noet:
925 
DCOPClient::setServerAddress
static void setServerAddress(const TQCString &addr)
Sets the address of a server to use upon attaching.
Definition: dcopclient.cpp:657
DCOPClient::isApplicationRegistered
bool isApplicationRegistered(const TQCString &remApp)
Checks whether remApp is registered with the DCOP server.
Definition: dcopclient.cpp:1227
DCOPClient::attach
bool attach()
Attaches to the DCOP server.
Definition: dcopclient.cpp:665
DCOPRef
A DCOPRef(erence) encapsulates a remote DCOP object as a triple <app,obj,type> 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:1241
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&#39;t yet been registered.
Definition: dcopclient.cpp:1001
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:1285
DCOPClient::remoteObjects
QCStringList remoteObjects(const TQCString &remApp, bool *ok=0)
Retrieves the list of objects of the remote application remApp.
Definition: dcopclient.cpp:1253
DCOPClient::isAttached
bool isAttached() const
Returns whether or not the client is attached to the server.
Definition: dcopclient.cpp:914
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:1751

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