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

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