summaryrefslogtreecommitdiff
path: root/x11/ipc
Unidiff
Diffstat (limited to 'x11/ipc') (more/less context) (ignore whitespace changes)
-rw-r--r--x11/ipc/client/ocopclient.cpp129
-rw-r--r--x11/ipc/client/ocopclient.h56
-rw-r--r--x11/ipc/server/ocopserver.cpp1
3 files changed, 186 insertions, 0 deletions
diff --git a/x11/ipc/client/ocopclient.cpp b/x11/ipc/client/ocopclient.cpp
new file mode 100644
index 0000000..1c25271
--- a/dev/null
+++ b/x11/ipc/client/ocopclient.cpp
@@ -0,0 +1,129 @@
1#include <errno.h>
2#include <stdlib.h>
3#include <stdio.h>
4#include <unistd.h>
5#include <sys/socket.h>
6#include <sys/un.h>
7
8
9#include <qfile.h>
10#include <qtimer.h>
11
12#include "../common/ocoppacket.h"
13
14#include "ocopclient.h"
15
16OCOPClient::OCOPClient( const QString& path, QObject* obj )
17 : QObject( obj )
18{
19 init(QFile::encodeName(path) );
20}
21OCOPClient::~OCOPClient() {
22 close( m_socket );
23}
24void OCOPClient::init( const QCString& str ) {
25 struct sockaddr_un unix_adr;
26 if ( (m_socket = socket(PF_UNIX, SOCK_STREAM, 0) ) < 0 ) {
27 qWarning("could not socket");
28 QTimer::singleShot(400, this,SLOT(init() ) );
29 return;
30 }
31 memset(&unix_adr, 0, sizeof(unix_adr ) );
32 unix_adr.sun_family = AF_UNIX;
33 sprintf(unix_adr.sun_path,"%s/.opie.cop", getenv("HOME") );
34 int length = sizeof(unix_adr.sun_family) + strlen(unix_adr.sun_path);
35
36 if ( ::connect(m_socket, (struct sockaddr*)&unix_adr, length ) < 0 ) {
37 qWarning("could not connect %d", errno );
38 close( m_socket );
39 QTimer::singleShot(400, this, SLOT(init() ) );
40 return;
41 }
42 m_notify = new QSocketNotifier(m_socket, QSocketNotifier::Read, this );
43 connect( m_notify, SIGNAL(activated(int) ),
44 this, SLOT(newData() ) );
45}
46/**
47 * new data
48 * read the header check magic number
49 * and maybe read body
50 */
51void OCOPClient::newData() {
52 OCOPPacket pack = packet();
53 if ( pack.channel().isEmpty() )
54 return;
55
56 switch( pack.type() ) {
57 case OCOPPacket::Register:
58 case OCOPPacket::Unregister:
59 case OCOPPacket::Method:
60 case OCOPPacket::RegisterChannel:
61 case OCOPPacket::UnregisterChannel:
62 case OCOPPacket::Return:
63 case OCOPPacket::Signal:
64 /* is Registered should be handled sync */
65 case OCOPPacket::isRegistered:
66 break;
67 /* emit the signal */
68 case OCOPPacket::Call:
69 emit called( pack.channel(), pack.header(), pack.content() );
70 break;
71 }
72}
73OCOPPacket OCOPClient::packet() {
74 QCString chan;
75 QCString func;
76 QByteArray ar;
77 OCOPHead head;
78 memset(&head, 0, sizeof(head) );
79 read(m_socket, &head, sizeof(head) );
80 if ( head.magic == 47 ) {
81 read(m_socket, chan.data(), head.chlen );
82 read(m_socket, func.data(), head.funclen );
83 read(m_socket, ar.data(), head.datalen );
84 }
85 OCOPPacket pack(head.type, chan, func, data );
86 return pack;
87}
88/*
89 * we've blocking IO here on these sockets
90 * so we send and go on read
91 * this will be blocked
92 */
93bool OCOPClient::isRegistered( const QCString& chan ) {
94 /* should I disconnect the socket notfier? */
95 OCOPPacket packe(OCOPPacket::IsRegistered, chan );
96 OCOPHead head = packe.head();
97 write(m_socket, &head, sizeof(head) );
98
99 /* block */
100 OCOPPacket pack = packet();
101
102 /* connect here again */
103 if ( pack.channel() == chan ) {
104 QCString func = pack.header();
105 if (func[0] == 1 )
106 return;
107 }
108
109 return false;
110};
111void OCOPClient::send( const QCString& chan, const QCString& fu, const QByteArray& arr ) {
112 OCOPPacket pack(OCOPPacket::Call, chan, fu, arr );
113 call( pack );
114}
115void OCOPClient::addChannel(const QCString& channet) {
116 OCOPPacket pack(OCOPPacket::RegisterChannel, channel );
117 call( pack );
118}
119void OCOPClient::delChannel(const QCString& chan ) {
120 OCOPPacket pack(OCOPPacket::UnregisterChannel, channel );
121 call( pack );
122}
123void OCOPPacket::call( const OCOPPacket& pack ) {
124 OCOPHead head = pack.head();
125 write(m_socket, &head, sizeof(head) );
126 write(m_socket, pack.channel().data(), pack.channel().size() );
127 write(m_socket, pack.header().data(), pack.header().size() );
128 write(m_socket, pack.content().data(), pack.content().size() );
129}
diff --git a/x11/ipc/client/ocopclient.h b/x11/ipc/client/ocopclient.h
new file mode 100644
index 0000000..5300132
--- a/dev/null
+++ b/x11/ipc/client/ocopclient.h
@@ -0,0 +1,56 @@
1#ifndef OPIE_OCOP_CLIENT_H
2#define OPIE_OCOP_CLIENT_H
3
4
5#include <qobject.h>
6#include <qcstring.h>
7#include <qmap.h>
8#include <qsignal.h>
9#include <qstring.h>
10#include <qsocketnotifier.h>
11
12
13/**
14 * This is the OCOP client
15 * It currently only supports
16 * asking if a Channel is registered,
17 * calling and receiving calls
18 */
19class OCOPPacket;
20class OCOPClient : public QObject{
21 Q_OBJECT
22public:
23
24 /**
25 * Occasionally I decide to start a Server from here
26 */
27 OCOPClient(const QString& pathToServer = QString::null, QObject* obj = 0l);
28 ~OCOPClient();
29
30 bool isRegistered( const QCString& )const;
31 void send( const QCString& chan, const QCString&, const QByteArray& msg );
32
33 /**
34 * add a channel and does connect to a signal
35 * callback is the object
36 * slot is the SLOT()
37 */
38 void addChannel( const QCString& channel );
39 void delChannel( const QCString& channel );
40/* no direct signals due the design */
41signals:
42 void called(const QCString&, const QCString&, const QByteArray );
43private slots:
44 void init(const QCString& pa);
45 void newData();
46private:
47 OCOPPacket packet();
48 void call( const OCOPPacket& );
49
50 QSocketNotifier* m_notify;
51 int m_socket;
52private slots:
53
54};
55
56#endif
diff --git a/x11/ipc/server/ocopserver.cpp b/x11/ipc/server/ocopserver.cpp
index 3df574b..e76657e 100644
--- a/x11/ipc/server/ocopserver.cpp
+++ b/x11/ipc/server/ocopserver.cpp
@@ -1,383 +1,384 @@
1#include <errno.h> 1#include <errno.h>
2#include <signal.h> 2#include <signal.h>
3#include <stdio.h> 3#include <stdio.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <unistd.h> 5#include <unistd.h>
6#include <sys/socket.h> 6#include <sys/socket.h>
7#include <sys/un.h> 7#include <sys/un.h>
8 8
9#include <qcstring.h> 9#include <qcstring.h>
10#include <qtimer.h> 10#include <qtimer.h>
11 11
12#include "ocopserver.h" 12#include "ocopserver.h"
13 13
14OCopServer::OCopServer() 14OCopServer::OCopServer()
15 : QObject() 15 : QObject()
16{ 16{
17 setName( "ocopserver"); 17 setName( "ocopserver");
18 18
19 /* 19 /*
20 * init the server 20 * init the server
21 */ 21 */
22 init(); 22 init();
23 initSocket(); 23 initSocket();
24} 24}
25OCopServer::~OCopServer() { 25OCopServer::~OCopServer() {
26// socket notifiers should be deleted 26// socket notifiers should be deleted
27 close(m_serverfd ); 27 close(m_serverfd );
28} 28}
29void OCopServer::init() { 29void OCopServer::init() {
30 /* 30 /*
31 * we set SIGPIPE to SIG_IGN 31 * we set SIGPIPE to SIG_IGN
32 * to get EPIPE on reads ;) 32 * to get EPIPE on reads ;)
33 */ 33 */
34 qWarning("SIGPIPE to be ignored"); 34 qWarning("SIGPIPE to be ignored");
35 signal(SIGPIPE, SIG_IGN ); 35 signal(SIGPIPE, SIG_IGN );
36 36
37 /* 37 /*
38 * initialize some variables 38 * initialize some variables
39 */ 39 */
40 m_server = 0l; 40 m_server = 0l;
41 m_serverError = 0l; 41 m_serverError = 0l;
42} 42}
43 43
44/** 44/**
45 * here we will init our server 45 * here we will init our server
46 * socket and bind and do the listen 46 * socket and bind and do the listen
47 */ 47 */
48void OCopServer::initSocket() { 48void OCopServer::initSocket() {
49 /* get the home dir */ 49 /* get the home dir */
50 QCString home( getenv("HOME") ); 50 QCString home( getenv("HOME") );
51 QCString path( home + "/.opie.cop"); 51 QCString path( home + "/.opie.cop");
52 52
53 if ( ( m_serverfd = socket( PF_UNIX, SOCK_STREAM, 0 ) ) == -1 ) { 53 if ( ( m_serverfd = socket( PF_UNIX, SOCK_STREAM, 0 ) ) == -1 ) {
54 qWarning("failed to create server socket"); 54 qWarning("failed to create server socket");
55 /* try again later */ 55 /* try again later */
56 QTimer::singleShot( 400, this, SLOT(initSocket() ) ); 56 QTimer::singleShot( 400, this, SLOT(initSocket() ) );
57 return; 57 return;
58 } 58 }
59 qWarning( "unlinking file %s", path.data() ); 59 qWarning( "unlinking file %s", path.data() );
60 60
61 /* unlink previous sockets */ 61 /* unlink previous sockets */
62 unlink( path.data() ); 62 unlink( path.data() );
63 63
64 struct sockaddr_un m_address; 64 struct sockaddr_un m_address;
65 memset(&m_address, 0, sizeof(m_address ) ); 65 memset(&m_address, 0, sizeof(m_address ) );
66 m_address.sun_family = AF_UNIX; /* unix domain socket */ 66 m_address.sun_family = AF_UNIX; /* unix domain socket */
67 strcpy(m_address.sun_path, path.data() ); 67 strcpy(m_address.sun_path, path.data() );
68 m_adrlaenge = sizeof(m_address.sun_family) + strlen(m_address.sun_path ); 68 m_adrlaenge = sizeof(m_address.sun_family) + strlen(m_address.sun_path );
69 69
70 /* cast to make it a (sockadr*) */ 70 /* cast to make it a (sockadr*) */
71 if (bind(m_serverfd, (struct sockaddr*)&m_address, m_adrlaenge ) == -1 ) { 71 if (bind(m_serverfd, (struct sockaddr*)&m_address, m_adrlaenge ) == -1 ) {
72 qWarning("Server could not bind try again"); 72 qWarning("Server could not bind try again");
73 close(m_serverfd); 73 close(m_serverfd);
74 QTimer::singleShot(400, this, SLOT(initSocket() ) ); 74 QTimer::singleShot(400, this, SLOT(initSocket() ) );
75 return; 75 return;
76 } 76 }
77 77
78 /* tell the kernel that we're listening and accepting 78 /* tell the kernel that we're listening and accepting
79 * 5 pending connections */ 79 * 5 pending connections */
80 if (listen(m_serverfd, 5) == -1 ) { 80 if (listen(m_serverfd, 5) == -1 ) {
81 qWarning("could not listen"); 81 qWarning("could not listen");
82 close(m_serverfd ); 82 close(m_serverfd );
83 QTimer::singleShot(400, this, SLOT(initSocket() ) ); 83 QTimer::singleShot(400, this, SLOT(initSocket() ) );
84 return; 84 return;
85 } 85 }
86 86
87 /* 87 /*
88 * now we will create two QSocketNotifier 88 * now we will create two QSocketNotifier
89 * which will us notify on reads 89 * which will us notify on reads
90 * and errors 90 * and errors
91 * we do this because they integrate 91 * we do this because they integrate
92 * nicely into the QApplication eventloop 92 * nicely into the QApplication eventloop
93 */ 93 */
94 m_server = new QSocketNotifier(m_serverfd, QSocketNotifier::Read, this ); 94 m_server = new QSocketNotifier(m_serverfd, QSocketNotifier::Read, this );
95 connect( m_server, SIGNAL(activated(int) ), 95 connect( m_server, SIGNAL(activated(int) ),
96 this, SLOT(newOnServer() ) ); 96 this, SLOT(newOnServer() ) );
97 97
98 m_serverError = new QSocketNotifier( m_serverfd, QSocketNotifier::Exception, this); 98 m_serverError = new QSocketNotifier( m_serverfd, QSocketNotifier::Exception, this);
99 connect(m_serverError, SIGNAL(activated(int) ), 99 connect(m_serverError, SIGNAL(activated(int) ),
100 this, SLOT(errorOnServer() ) ); 100 this, SLOT(errorOnServer() ) );
101 101
102 qWarning("done with registering"); 102 qWarning("done with registering");
103} 103}
104/** 104/**
105 * we got the possibility to read 105 * we got the possibility to read
106 * on the server 106 * on the server
107 * this is mostly due a connect 107 * this is mostly due a connect
108 * on a client side 108 * on a client side
109 * we will accept it 109 * we will accept it
110 * add it to our list 110 * add it to our list
111 */ 111 */
112void OCopServer::newOnServer() { 112void OCopServer::newOnServer() {
113 int fd = accept(); 113 int fd = accept();
114 if ( fd < 0 ) 114 if ( fd < 0 )
115 return; 115 return;
116 116
117 /* 117 /*
118 * we got a successfull new connection 118 * we got a successfull new connection
119 * be happy 119 * be happy
120 * set SocketNotifier 120 * set SocketNotifier
121 * connect it 121 * connect it
122 * and a OCOPClient 122 * and a OCOPClient
123 */ 123 */
124 qWarning("Heureka new connection %d", fd ); 124 qWarning("Heureka new connection %d", fd );
125 125
126 126
127 registerClient( fd ); 127 registerClient( fd );
128} 128}
129int OCopServer::accept() { 129int OCopServer::accept() {
130 /* 130 /*
131 * accept it 131 * accept it
132 * the socket is currently blocking IIRC 132 * the socket is currently blocking IIRC
133 */ 133 */
134 return ::accept( m_serverfd, (struct sockaddr*)&m_address, &m_adrlaenge ); 134 return ::accept( m_serverfd, (struct sockaddr*)&m_address, &m_adrlaenge );
135} 135}
136void OCopServer::newOnClient( int fd ) { 136void OCopServer::newOnClient( int fd ) {
137 int bug[4096]; 137 int bug[4096];
138 //qWarning("new stuff for client on fd %d", fd ); 138 //qWarning("new stuff for client on fd %d", fd );
139 errno = 0; 139 errno = 0;
140 OCOPHead head; 140 OCOPHead head;
141 memset(&head, 0, sizeof(head) ); 141 memset(&head, 0, sizeof(head) );
142 int rea = ::read(fd, &head, sizeof(head) ); 142 int rea = ::read(fd, &head, sizeof(head) );
143 //qWarning("read %d %d", rea, errno); 143 //qWarning("read %d %d", rea, errno);
144 /* 144 /*
145 * I should get EPIPE but nothing like this happens 145 * I should get EPIPE but nothing like this happens
146 * so if rea == 0 and we were signaled by the notifier 146 * so if rea == 0 and we were signaled by the notifier
147 * we close it and drop the clients... 147 * we close it and drop the clients...
148 */ 148 */
149 if ( rea <= 0 ) { 149 if ( rea <= 0 ) {
150 deregisterClient( fd ); 150 deregisterClient( fd );
151 return; 151 return;
152 } 152 }
153 /* 153 /*
154 * OCOPHead 154 * OCOPHead
155 */ 155 */
156 qWarning("data %s %d", bug, rea ); 156 qWarning("data %s %d", bug, rea );
157 157
158 /* 158 /*
159 * Check the magic 159 * Check the magic
160 * if chcked read till EOF if magic does not match 160 * if chcked read till EOF if magic does not match
161 * otherwise do read 161 * otherwise do read
162 * channel 162 * channel
163 * func 163 * func
164 * data into mem 164 * data into mem
165 * and then send the OCOPPacket 165 * and then send the OCOPPacket
166 * 166 *
167 */ 167 */
168 if (head.magic == 47 ) { 168 if (head.magic == 47 ) {
169 qWarning("magic match"); 169 qWarning("magic match");
170 QCString channel( head.chlen+1 ); 170 QCString channel( head.chlen+1 );
171 QCString func( head.funclen+1 ); 171 QCString func( head.funclen+1 );
172 QByteArray data ( head.datalen ); 172 QByteArray data ( head.datalen );
173 173
174 /* 174 /*
175 * we do not check for errors 175 * we do not check for errors
176 */ 176 */
177 int s = read(fd, channel.data(), head.chlen ); 177 int s = read(fd, channel.data(), head.chlen );
178 s = read(fd, func.data(), head.funclen ); 178 s = read(fd, func.data(), head.funclen );
179 s = read(fd, data.data(), head.datalen ); 179 s = read(fd, data.data(), head.datalen );
180 180
181 /* debug output */ 181 /* debug output */
182 qWarning("channel %s %d", channel.data(), head.chlen ); 182 qWarning("channel %s %d", channel.data(), head.chlen );
183 qWarning("func %s %d", func.data(), head.funclen ); 183 qWarning("func %s %d", func.data(), head.funclen );
184 /* debug end */ 184 /* debug end */
185 185
186 /* 186 /*
187 * now that we got the complete body 187 * now that we got the complete body
188 * we need to make a package 188 * we need to make a package
189 * and then we need to send it to clients 189 * and then we need to send it to clients
190 * making a package is done here 190 * making a package is done here
191 * dispatching it not 191 * dispatching it not
192 */ 192 */
193 OCOPPacket packet( head.type, channel, func, data ); 193 OCOPPacket packet( head.type, channel, func, data );
194 dispatch( packet, fd ); 194 dispatch( packet, fd );
195 195
196 }else{ 196 }else{
197 qWarning("magic does not match"); 197 qWarning("magic does not match");
198 qWarning("magic %d", head.magic ); 198 qWarning("magic %d", head.magic );
199 } 199 }
200} 200}
201void OCopServer::registerClient( int fd ) { 201void OCopServer::registerClient( int fd ) {
202 if (m_clients.contains(fd) ) 202 if (m_clients.contains(fd) )
203 return; 203 return;
204 204
205 QSocketNotifier* notify = new QSocketNotifier(fd, QSocketNotifier::Read, this ); 205 QSocketNotifier* notify = new QSocketNotifier(fd, QSocketNotifier::Read, this );
206 connect(notify, SIGNAL(activated(int) ), 206 connect(notify, SIGNAL(activated(int) ),
207 this, SLOT(newOnClient(int) ) ); 207 this, SLOT(newOnClient(int) ) );
208 OCOPClient client; 208 OCOPClient client;
209 client.fd = fd; 209 client.fd = fd;
210 client.notify = notify; 210 client.notify = notify;
211 m_clients.insert( client.fd, client ); 211 m_clients.insert( client.fd, client );
212 qWarning("clients are up to %d", m_clients.count() ); 212 qWarning("clients are up to %d", m_clients.count() );
213}; 213};
214void OCopServer::deregisterClient(int fd ) { 214void OCopServer::deregisterClient(int fd ) {
215 QMap<int, OCOPClient>::Iterator it = m_clients.find( fd ); 215 QMap<int, OCOPClient>::Iterator it = m_clients.find( fd );
216 if (it != m_clients.end() ) { 216 if (it != m_clients.end() ) {
217 OCOPClient client = (*it); 217 OCOPClient client = (*it);
218 delete client.notify; 218 delete client.notify;
219 m_clients.remove(fd ); 219 m_clients.remove(fd );
220 close(fd ); 220 close(fd );
221 /* 221 /*
222 * TIME_ME 222 * TIME_ME
223 * 223 *
224 * now delete from all channels 224 * now delete from all channels
225 * go through all channels 225 * go through all channels
226 * remove the fd from the list 226 * remove the fd from the list
227 * if count becomes 0 remove the channel 227 * if count becomes 0 remove the channel
228 * otherwise replace QArray<int> 228 * otherwise replace QArray<int>
229 */ 229 */
230 QMap<QCString, QValueList<int> >::Iterator it; 230 QMap<QCString, QValueList<int> >::Iterator it;
231 for ( it = m_channels.begin(); it != m_channels.end(); ++it ) { 231 for ( it = m_channels.begin(); it != m_channels.end(); ++it ) {
232 /* 232 /*
233 * The channel contains this fd 233 * The channel contains this fd
234 */ 234 */
235 if ( it.data().contains( fd ) ) { 235 if ( it.data().contains( fd ) ) {
236 QValueList<int> array = it.data(); 236 QValueList<int> array = it.data();
237 237
238 /* 238 /*
239 * remove channel or just replace 239 * remove channel or just replace
240 */ 240 */
241 if ( array.count() == 1 ) { 241 if ( array.count() == 1 ) {
242 /* is the list now invalidatet? */ 242 /* is the list now invalidatet? */
243 m_channels.remove( it ); 243 m_channels.remove( it );
244 }else{ 244 }else{
245 array.remove( fd ); 245 array.remove( fd );
246 it = m_channels.replace( it.key(), array ); 246 it = m_channels.replace( it.key(), array );
247 } 247 }
248 } 248 }
249 } // off all channels 249 } // off all channels
250 } 250 }
251 qWarning("clients are now at %d", m_clients.count() ); 251 qWarning("clients are now at %d", m_clients.count() );
252}; 252};
253/** 253/**
254 * this function will evaluate 254 * this function will evaluate
255 * the package and then do the appropriate thins 255 * the package and then do the appropriate thins
256 */ 256 */
257void OCopServer::dispatch( const OCOPPacket& packet, int sourceFD ) { 257void OCopServer::dispatch( const OCOPPacket& packet, int sourceFD ) {
258 qWarning("packet.type() == %d", packet.type() ); 258 qWarning("packet.type() == %d", packet.type() );
259 switch( packet.type() ) { 259 switch( packet.type() ) {
260 case OCOPPacket::Register: 260 case OCOPPacket::Register:
261 registerClient(sourceFD ); 261 registerClient(sourceFD );
262 break; 262 break;
263 case OCOPPacket::Unregister: 263 case OCOPPacket::Unregister:
264 deregisterClient(sourceFD ); 264 deregisterClient(sourceFD );
265 break; 265 break;
266 case OCOPPacket::Call: 266 case OCOPPacket::Call:
267 call( packet, sourceFD ); 267 call( packet, sourceFD );
268 break; 268 break;
269 /* not implemented */ 269 /* not implemented */
270 case OCOPPacket::Method: 270 case OCOPPacket::Method:
271 break; 271 break;
272 /* nit implemented */ 272 /* nit implemented */
273 case OCOPPacket::Reply: 273 case OCOPPacket::Reply:
274 break; 274 break;
275 case OCOPPacket::RegisterChannel: 275 case OCOPPacket::RegisterChannel:
276 addChannel( packet.channel() , sourceFD ); 276 addChannel( packet.channel() , sourceFD );
277 break; 277 break;
278 case OCOPPacket::UnregisterChannel: 278 case OCOPPacket::UnregisterChannel:
279 delChannel( packet.channel(), sourceFD ); 279 delChannel( packet.channel(), sourceFD );
280 break; 280 break;
281 /* not implemented */ 281 /* not implemented */
282 case OCOPPacket::Return: 282 case OCOPPacket::Return:
283 break; 283 break;
284 /* not implemented :( */ 284 /* not implemented :( */
285 case OCOPPacket::Signal: 285 case OCOPPacket::Signal:
286 break; 286 break;
287 case OCOPPacket::IsRegistered: 287 case OCOPPacket::IsRegistered:
288 isRegistered( packet.channel(), sourceFD ); 288 isRegistered( packet.channel(), sourceFD );
289 break; 289 break;
290 }; 290 };
291} 291}
292void OCopServer::errorOnServer() { 292void OCopServer::errorOnServer() {
293 /* 293 /*
294 * something is wrong on the server socket? 294 * something is wrong on the server socket?
295 * what should we do? 295 * what should we do?
296 * FIXME 296 * FIXME
297 */ 297 */
298} 298}
299QStringList OCopServer::channels() { 299QStringList OCopServer::channels() {
300 QStringList list; 300 QStringList list;
301 { 301 {
302 QMap<QCString, QValueList<int> >::Iterator it; 302 QMap<QCString, QValueList<int> >::Iterator it;
303 for (it = m_channels.begin(); it != m_channels.end(); ++it ) { 303 for (it = m_channels.begin(); it != m_channels.end(); ++it ) {
304 list << it.key(); 304 list << it.key();
305 }; 305 };
306 } 306 }
307 return list; 307 return list;
308} 308}
309bool OCopServer::isChannelRegistered( const QCString& chan ) const{ 309bool OCopServer::isChannelRegistered( const QCString& chan ) const{
310 return m_channels.contains( chan ); 310 return m_channels.contains( chan );
311} 311}
312void OCopServer::addChannel( const QCString& channel, 312void OCopServer::addChannel( const QCString& channel,
313 int fd ) { 313 int fd ) {
314 QMap<QCString, QValueList<int> >::Iterator it; 314 QMap<QCString, QValueList<int> >::Iterator it;
315 it = m_channels.find( channel ); 315 it = m_channels.find( channel );
316 316
317 /* could be empty */ 317 /* could be empty */
318 QValueList<int> list = it.data(); 318 QValueList<int> list = it.data();
319 list.append( fd ); 319 list.append( fd );
320 it = m_channels.replace( channel, list ); 320 it = m_channels.replace( channel, list );
321}; 321};
322void OCopServer::delChannel( const QCString& channel, 322void OCopServer::delChannel( const QCString& channel,
323 int fd ) { 323 int fd ) {
324 if (!m_channels.contains( channel ) ) 324 if (!m_channels.contains( channel ) )
325 return; 325 return;
326 326
327 QMap<QCString, QValueList<int> >::Iterator it; 327 QMap<QCString, QValueList<int> >::Iterator it;
328 it = m_channels.find( channel ); 328 it = m_channels.find( channel );
329 329
330 if ( it.data().contains(fd) ) { 330 if ( it.data().contains(fd) ) {
331 331
332 QValueList<int> ints = it.data(); 332 QValueList<int> ints = it.data();
333 if ( ints.count() == 1 ) 333 if ( ints.count() == 1 )
334 m_channels.remove( it ); 334 m_channels.remove( it );
335 else{ 335 else{
336 QValueList<int> ints = it.data(); 336 QValueList<int> ints = it.data();
337 ints.remove( fd ); 337 ints.remove( fd );
338 m_channels.replace( it.key(), ints ); 338 m_channels.replace( it.key(), ints );
339 } 339 }
340 } 340 }
341} 341}
342void OCopServer::isRegistered( const QCString& channel, int fd) { 342void OCopServer::isRegistered( const QCString& channel, int fd) {
343 OCOPHead head; 343 OCOPHead head;
344 QCString func(2); 344 QCString func(2);
345 345
346 memset(&head, 0, sizeof(head ) ); 346 memset(&head, 0, sizeof(head ) );
347 head.magic = 47; 347 head.magic = 47;
348 head.type = OCOPPacket::IsRegistered; 348 head.type = OCOPPacket::IsRegistered;
349 head.chlen = channel.size(); 349 head.chlen = channel.size();
350 head.funclen = func.size(); 350 head.funclen = func.size();
351 head.datalen = 0; 351 head.datalen = 0;
352 352
353 if ( isChannelRegistered( channel ) ) { 353 if ( isChannelRegistered( channel ) ) {
354 //is registered 354 //is registered
355 func[0] = 1; 355 func[0] = 1;
356 }else{ 356 }else{
357 func[0] = 0; 357 func[0] = 0;
358 } 358 }
359 359
360 /** 360 /**
361 * write the head 361 * write the head
362 * and then channel 362 * and then channel
363 * success/failure inside func 363 * success/failure inside func
364 */ 364 */
365 write(fd, &head, sizeof(head) ); 365 write(fd, &head, sizeof(head) );
366 write(fd, channel.data(), channel.size() ); 366 write(fd, channel.data(), channel.size() );
367 write(fd, func.data(), func.size() ); 367 write(fd, func.data(), func.size() );
368} 368}
369QValueList<int> OCopServer::clients( const QCString& channel ) { 369QValueList<int> OCopServer::clients( const QCString& channel ) {
370 return m_channels[channel]; 370 return m_channels[channel];
371} 371}
372void OCopServer::call( const OCOPPacket& p, int fd ) { 372void OCopServer::call( const OCOPPacket& p, int fd ) {
373 QValueList<int> cli = clients( p.channel() ); 373 QValueList<int> cli = clients( p.channel() );
374 QValueList<int>::Iterator it; 374 QValueList<int>::Iterator it;
375 375
376 OCOPHead head = p.head(); 376 OCOPHead head = p.head();
377 for (it = cli.begin(); it != cli.end(); ++it ) { 377 for (it = cli.begin(); it != cli.end(); ++it ) {
378 write( (*it), &head, sizeof(head ) ); 378 write( (*it), &head, sizeof(head ) );
379 /* expl. shared! */
379 write( (*it), p.channel().data(), p.channel().size() ); 380 write( (*it), p.channel().data(), p.channel().size() );
380 write( (*it), p.header().data(), p.header().size() ); 381 write( (*it), p.header().data(), p.header().size() );
381 write( (*it), p.content().data(), p.content().size() ); 382 write( (*it), p.content().data(), p.content().size() );
382 }; 383 };
383} 384}