Source Code (Use browser search to find items of interest.)
Class Index
kdelibs'DCOPServer (./kdelibs/dcop/dcopserver.h:51)
class DCOPServer : public QObject
{
Q_OBJECT
public:
DCOPServer();
~DCOPServer();
void* watchConnection( IceConn iceConn );
void removeConnection( void* data );
void processMessage( IceConn iceConn, int opcode, unsigned long length, Bool swap);
void ioError( IceConn iceConn );
virtual bool receive(const QCString &app, const QCString &obj,
const QCString &fun, const QByteArray& data,
QCString& replyType, QByteArray &replyData, IceConn iceConn);
private slots:
void newClient( int socket );
void processData( int socket );
private:
int majorOpcode;
QList<DCOPListener> listener;
QDict<DCOPConnection> appIds;
QPtrDict<DCOPConnection> clients;
class DCOPServerPrivate;
DCOPServerPrivate *d;
};
kdelibs'DCOPServer::processMessage() (./kdelibs/dcop/dcopserver.cpp:356)
void DCOPServer::processMessage( IceConn iceConn, int opcode,
unsigned long length, Bool /*swap*/)
{
switch( opcode ) {
case DCOPSend:
case DCOPReplyDelayed:
{
DCOPMsg *pMsg = 0;
IceReadMessageHeader(iceConn, sizeof(DCOPMsg), DCOPMsg, pMsg);
QByteArray ba( length );
IceReadData(iceConn, length, ba.data() );
QDataStream ds( ba, IO_ReadOnly );
QCString appFrom, app;
ds >> appFrom >> app;
DCOPConnection* target = appIds.find( app );
DCOPConnection* conn = clients.find( iceConn );
if ( opcode == DCOPReplyDelayed )
{
// qDebug("DCOPServer::Got DCOPReplyDelayed (from: \"%s\" to: \"%s\")",
// appFrom.data(), app.data());
if ( !target )
qWarning("DCOPServer::DCOPReplyDelayed for unknown connection.");
else if ( !conn )
qWarning("DCOPServer::DCOPReplyDelayed from unknown connection.");
else
{
if (iceConn != target->waitingOn)
qWarning("DCOPServer::DCOPReplyDelayed from/to does not match. (#1)");
if (!conn->waitingForDelayedReply.remove( target->iceConn ))
qWarning("DCOPServer::DCOPReplyDelayed from/to does not match. (#2)");
target->waitingOn = 0;
}
}
if ( target ) {
IceGetHeader( target->iceConn, majorOpcode, opcode,
sizeof(DCOPMsg), DCOPMsg, pMsg );
int datalen = ba.size();
pMsg->length += datalen;
IceSendData(target->iceConn, datalen, (char *) ba.data());
} else if ( app == "DCOPServer" ) {
QCString obj, fun;
QByteArray data;
ds >> obj >> fun >> data;
QCString replyType;
QByteArray replyData;
if ( !receive( app, obj, fun, data, replyType, replyData, iceConn ) ) {
qWarning("%s failure: object '%s' has no function '%s'", app.data(), obj.data(), fun.data() );
}
} else if ( app[app.length()-1] == '*') {
// handle a multicast.
QDictIterator<DCOPConnection> aIt(appIds);
int l = app.length()-1;
for ( ; aIt.current(); ++aIt)
{
DCOPConnection *client = aIt.current();
if (!l || (strncmp(client->appId.data(), app.data(), l) == 0))
{
IceGetHeader(client->iceConn, majorOpcode, DCOPSend,
sizeof(DCOPMsg), DCOPMsg, pMsg);
int datalen = ba.size();
pMsg->length += datalen;
IceSendData(client->iceConn, datalen, (char *) ba.data());
}
}
}
}
break;
case DCOPCall:
{
DCOPMsg *pMsg = 0;
IceReadMessageHeader(iceConn, sizeof(DCOPMsg), DCOPMsg, pMsg);
QByteArray ba( length );
IceReadData(iceConn, length, ba.data() );
QDataStream ds( ba, IO_ReadOnly );
QCString appFrom, app;
ds >> appFrom >> app;
DCOPConnection* conn = clients.find( iceConn );
DCOPConnection* target = appIds.find( app );
int datalen = ba.size();
if ( target ) {
target->waitingForReply.append( iceConn );
conn->waitingOn = target->iceConn;
IceGetHeader( target->iceConn, majorOpcode, DCOPCall,
sizeof(DCOPMsg), DCOPMsg, pMsg );
pMsg->length += datalen;
IceSendData(target->iceConn, datalen, (char *) ba.data());
} else {
QCString replyType;
QByteArray replyData;
bool b = FALSE;
if ( app == "DCOPServer" ) {
QCString obj, fun;
QByteArray data;
ds >> obj >> fun >> data;
b = receive( app, obj, fun, data, replyType, replyData, iceConn );
if ( !b )
qWarning("%s failure: object '%s' has no function '%s'", app.data(), obj.data(), fun.data() );
}
if (b)
{
QByteArray reply;
QDataStream replyStream( reply, IO_WriteOnly );
replyStream << replyType << replyData.size();
int datalen = reply.size() + replyData.size();
IceGetHeader( iceConn, majorOpcode, DCOPReply,
sizeof(DCOPMsg), DCOPMsg, pMsg );
pMsg->length += datalen;
IceSendData( iceConn, reply.size(), (char *) reply.data());
IceSendData( iceConn, replyData.size(), (char *) replyData.data());
}
else
{
QByteArray reply;
IceGetHeader( iceConn, majorOpcode, DCOPReplyFailed,
sizeof(DCOPMsg), DCOPMsg, pMsg );
pMsg->length += reply.size();
IceSendData( iceConn, reply.size(), (char *) reply.data());
}
}
}
break;
case DCOPReply:
case DCOPReplyFailed:
case DCOPReplyWait:
{
DCOPMsg *pMsg = 0;
IceReadMessageHeader(iceConn, sizeof(DCOPMsg), DCOPMsg, pMsg);
QByteArray ba( length );
IceReadData(iceConn, length, ba.data() );
DCOPConnection* conn = clients.find( iceConn );
DCOPConnection* connreply = clients.find( conn->waitingForReply.take(0) );
if ( !conn )
qWarning("DCOPServer::DCOPReply from unknown connection.");
else if ( !connreply )
qWarning("DCOPServer::DCOPReply for unknown connection.");
else if ( connreply->waitingOn != conn->iceConn )
qWarning("DCOPServer::Unexpected DCOPReply[Wait|Failed].");
else {
if ( opcode == DCOPReplyWait ) {
conn->waitingForDelayedReply.append( connreply->iceConn );
} else {
connreply->waitingOn = 0;
}
IceGetHeader( connreply->iceConn, majorOpcode, opcode,
sizeof(DCOPMsg), DCOPMsg, pMsg );
int datalen = ba.size();
pMsg->length += datalen;
IceSendData(connreply->iceConn, datalen, (char *) ba.data());
}
}
break;
default:
qWarning("DCOPServer::processMessage unknown message");
}
}
kdelibs'DCOPServer::DCOPServer() (./kdelibs/dcop/dcopserver.cpp:590)
DCOPServer::DCOPServer()
: QObject(0,0), appIds(200), clients(200)
{
extern int _IceLastMajorOpcode; // from libICE
if (_IceLastMajorOpcode < 1 )
registerXSM();
the_server = this;
if (( majorOpcode = IceRegisterForProtocolReply ((char *) "DCOP",
(char *) DCOPVendorString,
(char *) DCOPReleaseString,
1, DCOPVersions,
1, (char **) DCOPAuthNames,
DCOPServerAuthProcs,
HostBasedAuthProc,
DCOPServerProtocolSetupProc,
NULL, /* IceProtocolActivateProc - we don't care about
when the Protocol Reply is sent, because the
session manager can not immediately send a
message - it must wait for RegisterClient. */
NULL /* IceIOErrorProc */
)) < 0)
{
qWarning("Could not register DCOP protocol with ICE");
}
char errormsg[256];
if (!IceListenForConnections (&numTransports, &listenObjs,
256, errormsg))
{
fprintf (stderr, "%s\n", errormsg);
exit (1);
} else {
// publish available transports.
QCString fName = ::getenv("HOME");
fName += "/.DCOPserver";
FILE *f;
f = ::fopen(fName.data(), "w+");
fprintf(f, IceComposeNetworkIdList(numTransports, listenObjs));
fprintf(f, "\n%i\n", getpid());
fclose(f);
}
if (!SetAuthentication(numTransports, listenObjs, &authDataEntries))
qFatal("DCOPSERVER: authentication setup failed.");
IceAddConnectionWatch (DCOPWatchProc, (IcePointer) this);
listener.setAutoDelete( TRUE );
DCOPListener* con;
for ( int i = 0; i < numTransports; i++) {
con = new DCOPListener( listenObjs[i] );
listener.append( con );
connect( con, SIGNAL( activated(int) ), this, SLOT( newClient(int) ) );
}
char c;
(void) write(ready[1], &c, 1); // dcopserver is started
close(ready[1]);
}
kdelibs'DCOPServer::~DCOPServer() (./kdelibs/dcop/dcopserver.cpp:650)
DCOPServer::~DCOPServer()
{
IceFreeListenObjs (numTransports, listenObjs);
QCString fName;
fName = ::getenv("DCOPSERVER");
if (fName.isNull()) {
fName = ::getenv("HOME");
fName += "/.DCOPserver";
unlink(fName.data());
}
FreeAuthenticationData(numTransports, authDataEntries);
}
/*!
Called from our IceIoErrorHandler
*/
kdelibs'DCOPServer::ioError() (./kdelibs/dcop/dcopserver.cpp:669)
void DCOPServer::ioError( IceConn iceConn )
{
IceSetShutdownNegotiation (iceConn, False);
IceCloseConnection( iceConn );
}
kdelibs'DCOPServer::processData() (./kdelibs/dcop/dcopserver.cpp:676)
void DCOPServer::processData( int /*socket*/ )
{
(void ) IceProcessMessages( ((DCOPConnection*)sender())->iceConn, 0, 0 );
}
kdelibs'DCOPServer::newClient() (./kdelibs/dcop/dcopserver.cpp:681)
void DCOPServer::newClient( int /*socket*/ )
{
IceAcceptStatus status;
IceConn iceConn = IceAcceptConnection( ((DCOPListener*)sender())->listenObj, &status);
IceSetShutdownNegotiation( iceConn, False );
IceConnectStatus cstatus;
while ((cstatus = IceConnectionStatus (iceConn))==IceConnectPending) {
qApp->processOneEvent();
}
if (cstatus != IceConnectAccepted) {
if (cstatus == IceConnectIOError)
qWarning ("IO error opening ICE Connection!\n");
else
qWarning ("ICE Connection rejected!\n");
IceCloseConnection (iceConn);
}
}
kdelibs'DCOPServer::watchConnection() (./kdelibs/dcop/dcopserver.cpp:700)
void* DCOPServer::watchConnection( IceConn iceConn )
{
DCOPConnection* con = new DCOPConnection( iceConn );
connect( con, SIGNAL( activated(int) ), this, SLOT( processData(int) ) );
clients.insert(iceConn, con );
return (void*) con;
}
kdelibs'DCOPServer::removeConnection() (./kdelibs/dcop/dcopserver.cpp:710)
void DCOPServer::removeConnection( void* data )
{
DCOPConnection* conn = (DCOPConnection*)data;
clients.remove(conn->iceConn );
if (conn->waitingOn) {
DCOPConnection* target = clients.find( conn->waitingOn );
// We are expecting a response from 'target'.
// We should be in either target->waitingForReply
int i;
while ((i = target->waitingForReply.findRef( conn->iceConn )) != -1) {
target->waitingForReply.take(i);
target->waitingForReply.insert(i,0);
}
// or in target->waitingForDelayedReply
target->waitingForDelayedReply.remove( conn->iceConn );
}
// Send DCOPReplyFailed to all in conn->waitingForReply
while (!conn->waitingForReply.isEmpty()) {
IceConn iceConn = conn->waitingForReply.take(0);
if (iceConn)
{
DCOPConnection* target = clients.find( iceConn );
// if (target->waitingOn != conn->iceConn)
// qDebug("DCOP: waitingForReply list corrupted.");
target->waitingOn = 0L;
// qDebug("DCOP aborting call from '%s' to '%s'", target->appId.data(), conn->appId.data() );
QByteArray reply;
DCOPMsg *pMsg;
IceGetHeader( iceConn, majorOpcode, DCOPReplyFailed,
sizeof(DCOPMsg), DCOPMsg, pMsg );
pMsg->length += reply.size();
IceSendData( iceConn, reply.size(), (char *) reply.data());
}
}
// Send DCOPReplyFailed to all in conn->waitingForDelayedReply
while (!conn->waitingForDelayedReply.isEmpty()) {
IceConn iceConn = conn->waitingForDelayedReply.take();
if (iceConn)
{
DCOPConnection* target = clients.find( iceConn );
// if (target->waitingOn != conn->iceConn)
// qDebug("DCOP waitingForDelayedReply list corrupt.");
target->waitingOn = 0L;
// qDebug("DCOP aborting (delayed) call from '%s' to '%s'", target->appId.data(), conn->appId.data() );
QByteArray reply;
DCOPMsg *pMsg;
IceGetHeader( iceConn, majorOpcode, DCOPReplyFailed,
sizeof(DCOPMsg), DCOPMsg, pMsg );
pMsg->length += reply.size();
IceSendData( iceConn, reply.size(), (char *) reply.data());
}
}
// Send DCOPReplyDelayed with 0 seq to all in conn->waitingDelayedReply
if ( !conn->appId.isNull() ) {
qDebug("DCOP: unregister '%s'", conn->appId.data() );
appIds.remove( conn->appId );
QPtrDictIterator<DCOPConnection> it( clients );
QByteArray data;
QDataStream datas( data, IO_WriteOnly );
datas << conn->appId;
QByteArray ba;
QDataStream ds( ba, IO_WriteOnly );
ds << QCString("DCOPServer") << QCString("")
<< QCString("") << QCString("applicationRemoved(QCString)") << data;
int datalen = ba.size();
DCOPMsg *pMsg = 0;
while ( it.current() ) {
DCOPConnection* c = it.current();
++it;
if ( c->notifyRegister && (c != conn) ) {
IceGetHeader( c->iceConn, majorOpcode, DCOPSend,
sizeof(DCOPMsg), DCOPMsg, pMsg );
pMsg->length += datalen;
IceSendData(c->iceConn, datalen, (char *) ba.data());
}
}
}
delete conn;
}
kdelibs'DCOPServer::receive() (./kdelibs/dcop/dcopserver.cpp:795)
bool DCOPServer::receive(const QCString &/*app*/, const QCString &/*obj*/,
const QCString &fun, const QByteArray& data,
QCString& replyType, QByteArray &replyData,
IceConn iceConn)
{
if ( fun == "registerAs(QCString)" ) {
QDataStream args( data, IO_ReadOnly );
if (!args.atEnd()) {
QCString app2;
args >> app2;
QDataStream reply( replyData, IO_WriteOnly );
DCOPConnection* conn = clients.find( iceConn );
if ( conn && !app2.isEmpty() ) {
if ( !conn->appId.isNull() &&
appIds.find( conn->appId ) == conn ) {
appIds.remove( conn->appId );
}
if ( conn->appId.isNull() )
qDebug("DCOP: register '%s'", app2.data() );
else
qDebug("DCOP: '%s' now known as '%s'", conn->appId.data(), app2.data() );
conn->appId = app2;
if ( appIds.find( app2 ) != 0 ) {
// we already have this application, unify
int n = 1;
QCString tmp;
do {
n++;
tmp.setNum( n );
tmp.prepend("-");
tmp.prepend( app2 );
} while ( appIds.find( tmp ) != 0 );
conn->appId = tmp;
}
appIds.insert( conn->appId, conn );
QPtrDictIterator<DCOPConnection> it( clients );
QByteArray data;
QDataStream datas( data, IO_WriteOnly );
datas << conn->appId;
QByteArray ba;
QDataStream ds( ba, IO_WriteOnly );
ds <<QCString("DCOPServer") << QCString("") << QCString("")
<< QCString("applicationRegistered(QCString)") << data;
int datalen = ba.size();
DCOPMsg *pMsg = 0;
while ( it.current() ) {
DCOPConnection* c = it.current();
++it;
if ( c->notifyRegister && (c != conn) ) {
IceGetHeader( c->iceConn, majorOpcode, DCOPSend,
sizeof(DCOPMsg), DCOPMsg, pMsg );
pMsg->length += datalen;
IceWriteData( c->iceConn, datalen, (char *) ba.data());
IceFlush( c->iceConn );
}
}
}
replyType = "QCString";
reply << conn->appId;
return TRUE;
}
}
else if ( fun == "registeredApplications()" ) {
QDataStream reply( replyData, IO_WriteOnly );
QCStringList applications;
QDictIterator<DCOPConnection> it( appIds );
while ( it.current() ) {
applications << it.currentKey().ascii();
++it;
}
replyType = "QCStringList";
reply << applications;
return TRUE;
} else if ( fun == "isApplicationRegistered(QCString)" ) {
QDataStream args( data, IO_ReadOnly );
if (!args.atEnd()) {
QCString s;
args >> s;
QDataStream reply( replyData, IO_WriteOnly );
int b = ( appIds.find( s ) != 0 );
replyType = "bool";
reply << b;
return TRUE;
}
} else if ( fun == "setNotifications(bool)" ) {
QDataStream args( data, IO_ReadOnly );
if (!args.atEnd()) {
Q_INT8 notifyActive;
args >> notifyActive;
DCOPConnection* conn = clients.find( iceConn );
if ( conn )
conn->notifyRegister = (notifyActive != 0);
replyType = "void";
return TRUE;
}
}
return FALSE;
}