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

dcop

  • dcop
  • client
dcop.cpp
1/*****************************************************************
2Copyright (c) 2000 Matthias Ettrich <ettrich@kde.org>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION 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
55typedef TQMap<TQString, TQString> UserList;
56
57static DCOPClient* dcop = 0;
58
59static TQTextStream cin_ ( stdin, IO_ReadOnly );
60static TQTextStream cout_( stdout, IO_WriteOnly );
61static TQTextStream cerr_( stderr, IO_WriteOnly );
62
72enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
73
74bool startsWith(const TQCString &id, const char *str, int n)
75{
76 return !n || (strncmp(id.data(), str, n) == 0);
77}
78
79bool 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
89void 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
110void 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
145void 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
159int 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
323void 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
378static 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
394TQStringList 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
430void 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
458int 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
786int 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.4
This website is maintained by Timothy Pearson.