Diffstat (limited to 'core/launcher/qcopbridge.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/launcher/qcopbridge.cpp | 222 |
1 files changed, 102 insertions, 120 deletions
diff --git a/core/launcher/qcopbridge.cpp b/core/launcher/qcopbridge.cpp index 6177a7c..f780235 100644 --- a/core/launcher/qcopbridge.cpp +++ b/core/launcher/qcopbridge.cpp | |||
@@ -21,35 +21,46 @@ | |||
21 | #include "qcopbridge.h" | 21 | #include "qcopbridge.h" |
22 | #include "transferserver.h" | 22 | #include "transferserver.h" |
23 | 23 | ||
24 | #include <qpe/qcopenvelope_qws.h> | 24 | #ifdef Q_WS_QWS |
25 | #include <qpe/qpeapplication.h> | 25 | #include <qtopia/qcopenvelope_qws.h> |
26 | #include <qpe/version.h> | 26 | #endif |
27 | #include <qtopia/qpeapplication.h> | ||
28 | #include <qtopia/global.h> | ||
29 | #include <qtopia/version.h> | ||
27 | 30 | ||
28 | #include <qdir.h> | 31 | #include <qdir.h> |
29 | #include <qfile.h> | 32 | #include <qfile.h> |
30 | #include <qtextstream.h> | 33 | #include <qtextstream.h> |
31 | #include <qdatastream.h> | 34 | #include <qdatastream.h> |
35 | #include <qcstring.h> | ||
32 | #include <qstringlist.h> | 36 | #include <qstringlist.h> |
33 | #include <qfileinfo.h> | 37 | #include <qfileinfo.h> |
34 | #include <qregexp.h> | 38 | #include <qregexp.h> |
35 | #ifdef QWS | 39 | #include <qtimer.h> |
40 | #ifdef Q_WS_QWS | ||
36 | #include <qcopchannel_qws.h> | 41 | #include <qcopchannel_qws.h> |
37 | #endif | 42 | #endif |
38 | 43 | ||
44 | #ifndef _XOPEN_SOURCE | ||
39 | #define _XOPEN_SOURCE | 45 | #define _XOPEN_SOURCE |
46 | #endif | ||
47 | #ifndef Q_OS_WIN32 | ||
40 | #include <pwd.h> | 48 | #include <pwd.h> |
41 | #include <sys/types.h> | ||
42 | #include <unistd.h> | 49 | #include <unistd.h> |
50 | #include <sys/types.h> | ||
51 | #endif | ||
43 | 52 | ||
44 | #if defined(_OS_LINUX_) | 53 | #if defined(_OS_LINUX_) |
45 | #include <shadow.h> | 54 | #include <shadow.h> |
46 | #endif | 55 | #endif |
47 | 56 | ||
57 | #include "launcherglobal.h" | ||
58 | |||
48 | //#define INSECURE | 59 | //#define INSECURE |
49 | 60 | ||
50 | const int block_size = 51200; | 61 | const int block_size = 51200; |
51 | 62 | ||
52 | QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent , | 63 | QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent, |
53 | const char* name ) | 64 | const char* name ) |
54 | : QServerSocket( port, 1, parent, name ), | 65 | : QServerSocket( port, 1, parent, name ), |
55 | desktopChannel( 0 ), | 66 | desktopChannel( 0 ), |
@@ -68,6 +79,7 @@ QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent , | |||
68 | #endif | 79 | #endif |
69 | } | 80 | } |
70 | sendSync = FALSE; | 81 | sendSync = FALSE; |
82 | openConnections.setAutoDelete( TRUE ); | ||
71 | } | 83 | } |
72 | 84 | ||
73 | QCopBridge::~QCopBridge() | 85 | QCopBridge::~QCopBridge() |
@@ -77,11 +89,28 @@ QCopBridge::~QCopBridge() | |||
77 | #endif | 89 | #endif |
78 | } | 90 | } |
79 | 91 | ||
92 | void QCopBridge::authorizeConnections() | ||
93 | { | ||
94 | QListIterator<QCopBridgePI> it(openConnections); | ||
95 | while ( it.current() ) { | ||
96 | if ( !it.current()->verifyAuthorised() ) { | ||
97 | disconnect ( it.current(), SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( closed( QCopBridgePI *) ) ); | ||
98 | openConnections.removeRef( it.current() ); | ||
99 | } else | ||
100 | ++it; | ||
101 | } | ||
102 | } | ||
103 | |||
80 | void QCopBridge::newConnection( int socket ) | 104 | void QCopBridge::newConnection( int socket ) |
81 | { | 105 | { |
82 | QCopBridgePI *pi = new QCopBridgePI( socket, this ); | 106 | QCopBridgePI *pi = new QCopBridgePI( socket, this ); |
83 | openConnections.append( pi ); | 107 | openConnections.append( pi ); |
84 | connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( connectionClosed( QCopBridgePI *) ) ); | 108 | connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( closed( QCopBridgePI *) ) ); |
109 | |||
110 | /* ### libqtopia merge FIXME */ | ||
111 | #if 0 | ||
112 | QPEApplication::setTempScreenSaverMode( QPEApplication::DisableSuspend ); | ||
113 | #endif | ||
85 | #ifndef QT_NO_COP | 114 | #ifndef QT_NO_COP |
86 | QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend; | 115 | QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend; |
87 | #endif | 116 | #endif |
@@ -92,12 +121,17 @@ void QCopBridge::newConnection( int socket ) | |||
92 | } | 121 | } |
93 | } | 122 | } |
94 | 123 | ||
95 | void QCopBridge::connectionClosed( QCopBridgePI *pi ) | 124 | void QCopBridge::closed( QCopBridgePI *pi ) |
96 | { | 125 | { |
97 | openConnections.remove( pi ); | 126 | emit connectionClosed( pi->peerAddress() ); |
127 | openConnections.removeRef( pi ); | ||
98 | if ( openConnections.count() == 0 ) { | 128 | if ( openConnections.count() == 0 ) { |
129 | /* ### FIXME libqtopia merge */ | ||
130 | #if 0 | ||
131 | QPEApplication::setTempScreenSaverMode( QPEApplication::Enable ); | ||
132 | #endif | ||
99 | #ifndef QT_NO_COP | 133 | #ifndef QT_NO_COP |
100 | QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; | 134 | QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; |
101 | #endif | 135 | #endif |
102 | } | 136 | } |
103 | } | 137 | } |
@@ -110,84 +144,18 @@ void QCopBridge::closeOpenConnections() | |||
110 | } | 144 | } |
111 | 145 | ||
112 | 146 | ||
113 | void QCopBridge::desktopMessage( const QCString &command, const QByteArray &args ) | 147 | void QCopBridge::desktopMessage( const QCString &command, const QByteArray &data ) |
114 | { | 148 | { |
115 | command.stripWhiteSpace(); | ||
116 | |||
117 | int paren = command.find( "(" ); | ||
118 | if ( paren <= 0 ) { | ||
119 | qDebug("DesktopMessage: bad qcop syntax"); | ||
120 | return; | ||
121 | } | ||
122 | |||
123 | QString params = command.mid( paren + 1 ); | ||
124 | if ( params[params.length()-1] != ')' ) { | ||
125 | qDebug("DesktopMessage: bad qcop syntax"); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | params.truncate( params.length()-1 ); | ||
130 | |||
131 | QStringList paramList = QStringList::split( ",", params ); | ||
132 | QString data; | ||
133 | if ( paramList.count() ) { | ||
134 | QDataStream stream( args, IO_ReadOnly ); | ||
135 | for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { | ||
136 | QString str; | ||
137 | if ( *it == "QString" ) { | ||
138 | stream >> str; | ||
139 | } else if ( *it == "QCString" ) { | ||
140 | QCString cstr; | ||
141 | stream >> cstr; | ||
142 | str = QString::fromLocal8Bit( cstr ); | ||
143 | } else if ( *it == "int" ) { | ||
144 | int i; | ||
145 | stream >> i; | ||
146 | str = QString::number( i ); | ||
147 | } else if ( *it == "bool" ) { | ||
148 | int i; | ||
149 | stream >> i; | ||
150 | str = QString::number( i ); | ||
151 | } else { | ||
152 | qDebug(" cannot route the argument type %s throught the qcop bridge", (*it).latin1() ); | ||
153 | return; | ||
154 | } | ||
155 | QString estr; | ||
156 | for (int i=0; i<(int)str.length(); i++) { | ||
157 | QChar ch = str[i]; | ||
158 | if ( ch.row() ) | ||
159 | goto quick; | ||
160 | switch (ch.cell()) { | ||
161 | case '&': | ||
162 | estr.append( "&" ); | ||
163 | break; | ||
164 | case ' ': | ||
165 | estr.append( "&0x20;" ); | ||
166 | break; | ||
167 | case '\n': | ||
168 | estr.append( "&0x0d;" ); | ||
169 | break; | ||
170 | case '\r': | ||
171 | estr.append( "&0x0a;" ); | ||
172 | break; | ||
173 | default: quick: | ||
174 | estr.append(ch); | ||
175 | } | ||
176 | } | ||
177 | data += " " + estr; | ||
178 | } | ||
179 | } | ||
180 | QString sendCommand = QString(command.data()) + data; | ||
181 | // send the command to all open connections | ||
182 | if ( command == "startSync()" ) { | 149 | if ( command == "startSync()" ) { |
183 | // we need to buffer it a bit | 150 | // we need to buffer it a bit |
184 | sendSync = TRUE; | 151 | sendSync = TRUE; |
185 | startTimer( 20000 ); | 152 | startTimer( 20000 ); |
186 | } | 153 | } |
187 | 154 | ||
155 | // send the command to all open connections | ||
188 | QCopBridgePI *pi; | 156 | QCopBridgePI *pi; |
189 | for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) { | 157 | for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) { |
190 | pi->sendDesktopMessage( sendCommand ); | 158 | pi->sendDesktopMessage( command, data ); |
191 | } | 159 | } |
192 | } | 160 | } |
193 | 161 | ||
@@ -198,7 +166,7 @@ void QCopBridge::timerEvent( QTimerEvent * ) | |||
198 | } | 166 | } |
199 | 167 | ||
200 | 168 | ||
201 | QCopBridgePI::QCopBridgePI( int socket, QObject *parent , const char* name ) | 169 | QCopBridgePI::QCopBridgePI( int socket, QObject *parent, const char* name ) |
202 | : QSocket( parent, name ) | 170 | : QSocket( parent, name ) |
203 | { | 171 | { |
204 | setSocket( socket ); | 172 | setSocket( socket ); |
@@ -209,51 +177,72 @@ QCopBridgePI::QCopBridgePI( int socket, QObject *parent , const char* name ) | |||
209 | #ifndef INSECURE | 177 | #ifndef INSECURE |
210 | if ( !SyncAuthentication::isAuthorized(peeraddress) ) { | 178 | if ( !SyncAuthentication::isAuthorized(peeraddress) ) { |
211 | state = Forbidden; | 179 | state = Forbidden; |
212 | startTimer( 0 ); | 180 | close(); |
213 | } else | 181 | } else |
214 | #endif | 182 | #endif |
215 | { | 183 | { |
216 | state = Connected; | 184 | state = Connected; |
217 | sendSync = FALSE; | ||
218 | connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); | 185 | connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); |
219 | connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); | ||
220 | |||
221 | QString intro="220 Qtopia "; | 186 | QString intro="220 Qtopia "; |
222 | intro += QPE_VERSION; intro += ";"; | 187 | intro += QPE_VERSION; intro += ";"; |
223 | intro += "challenge="; intro += SyncAuthentication::serverId(); intro += ";"; | 188 | intro += "challenge="; intro += SyncAuthentication::serverId(); intro += ";"; // No tr |
224 | intro += "loginname="; intro += SyncAuthentication::loginName(); intro += ";"; | 189 | intro += "loginname="; intro += SyncAuthentication::loginName(); intro += ";"; |
225 | intro += "displayname="; intro += SyncAuthentication::ownerName(); intro += ";"; | 190 | intro += "displayname="; intro += SyncAuthentication::ownerName(); intro += ";"; |
226 | send( intro ); | 191 | send( intro ); |
227 | state = Wait_USER; | 192 | state = Wait_USER; |
228 | |||
229 | // idle timer to close connections when not used anymore | ||
230 | startTimer( 60000 ); | ||
231 | connected = TRUE; | ||
232 | } | 193 | } |
194 | sendSync = FALSE; | ||
195 | connect( this, SIGNAL( connectionClosed() ), SLOT( myConnectionClosed() ) ); | ||
196 | |||
197 | // idle timer to close connections when not used anymore | ||
198 | timer = new QTimer(this); | ||
199 | connect( timer, SIGNAL(timeout()), this, SLOT(myConnectionClosed()) ); | ||
200 | timer->start( 300000, TRUE ); | ||
233 | } | 201 | } |
234 | 202 | ||
235 | 203 | ||
236 | QCopBridgePI::~QCopBridgePI() | 204 | QCopBridgePI::~QCopBridgePI() |
237 | { | 205 | { |
206 | } | ||
238 | 207 | ||
208 | bool QCopBridgePI::verifyAuthorised() | ||
209 | { | ||
210 | if ( !SyncAuthentication::isAuthorized(peerAddress()) ) { | ||
211 | state = Forbidden; | ||
212 | return FALSE; | ||
213 | } | ||
214 | return TRUE; | ||
239 | } | 215 | } |
240 | 216 | ||
241 | void QCopBridgePI::connectionClosed() | 217 | void QCopBridgePI::myConnectionClosed() |
242 | { | 218 | { |
243 | emit connectionClosed( this ); | 219 | emit connectionClosed( this ); |
244 | // qDebug( "Debug: Connection closed" ); | ||
245 | delete this; | ||
246 | } | 220 | } |
247 | 221 | ||
248 | void QCopBridgePI::sendDesktopMessage( const QString &msg ) | 222 | void QCopBridgePI::sendDesktopMessage( const QString &msg ) |
249 | { | 223 | { |
250 | QString str = "CALL QPE/Desktop " + msg; | 224 | QString str = "CALL QPE/Desktop " + msg; // No tr |
251 | send ( str ); | 225 | send ( str ); |
252 | } | 226 | } |
253 | 227 | ||
228 | void QCopBridgePI::sendDesktopMessage( const QCString &msg, const QByteArray& data ) | ||
229 | { | ||
230 | if ( !isOpen() ) // eg. Forbidden | ||
231 | return; | ||
232 | const char hdr[]="CALLB QPE/Desktop "; | ||
233 | writeBlock(hdr,sizeof(hdr)-1); | ||
234 | writeBlock(msg,msg.length()); | ||
235 | writeBlock(" ",1); | ||
236 | QByteArray b64 = Opie::Global::encodeBase64(data); | ||
237 | writeBlock(b64.data(),b64.size()); | ||
238 | writeBlock("\r\n",2); | ||
239 | } | ||
240 | |||
254 | 241 | ||
255 | void QCopBridgePI::send( const QString& msg ) | 242 | void QCopBridgePI::send( const QString& msg ) |
256 | { | 243 | { |
244 | if ( !isOpen() ) // eg. Forbidden | ||
245 | return; | ||
257 | QTextStream os( this ); | 246 | QTextStream os( this ); |
258 | os << msg << endl; | 247 | os << msg << endl; |
259 | //qDebug( "sending qcop message: %s", msg.latin1() ); | 248 | //qDebug( "sending qcop message: %s", msg.latin1() ); |
@@ -261,8 +250,10 @@ void QCopBridgePI::send( const QString& msg ) | |||
261 | 250 | ||
262 | void QCopBridgePI::read() | 251 | void QCopBridgePI::read() |
263 | { | 252 | { |
264 | while ( canReadLine() ) | 253 | while ( canReadLine() ) { |
254 | timer->start( 300000, TRUE ); | ||
265 | process( readLine().stripWhiteSpace() ); | 255 | process( readLine().stripWhiteSpace() ); |
256 | } | ||
266 | } | 257 | } |
267 | 258 | ||
268 | void QCopBridgePI::process( const QString& message ) | 259 | void QCopBridgePI::process( const QString& message ) |
@@ -283,8 +274,8 @@ void QCopBridgePI::process( const QString& message ) | |||
283 | 274 | ||
284 | // we always respond to QUIT, regardless of state | 275 | // we always respond to QUIT, regardless of state |
285 | if ( cmd == "QUIT" ) { | 276 | if ( cmd == "QUIT" ) { |
286 | send( "211 Have a nice day!" ); | 277 | send( "211 Have a nice day!" ); // No tr |
287 | delete this; | 278 | close(); |
288 | return; | 279 | return; |
289 | } | 280 | } |
290 | 281 | ||
@@ -296,10 +287,10 @@ void QCopBridgePI::process( const QString& message ) | |||
296 | if ( Wait_USER == state ) { | 287 | if ( Wait_USER == state ) { |
297 | 288 | ||
298 | if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { | 289 | if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { |
299 | send( "530 Please login with USER and PASS" ); | 290 | send( "530 Please login with USER and PASS" ); // No tr |
300 | return; | 291 | return; |
301 | } | 292 | } |
302 | send( "331 User name ok, need password" ); | 293 | send( "331 User name ok, need password" ); // No tr |
303 | state = Wait_PASS; | 294 | state = Wait_PASS; |
304 | return; | 295 | return; |
305 | } | 296 | } |
@@ -308,10 +299,10 @@ void QCopBridgePI::process( const QString& message ) | |||
308 | if ( Wait_PASS == state ) { | 299 | if ( Wait_PASS == state ) { |
309 | 300 | ||
310 | if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { | 301 | if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { |
311 | send( "530 Please login with USER and PASS" ); | 302 | send( "530 Please login with USER and PASS" ); // No tr |
312 | return; | 303 | return; |
313 | } | 304 | } |
314 | send( "230 User logged in, proceed" ); | 305 | send( "230 User logged in, proceed" ); // No tr |
315 | state = Ready; | 306 | state = Ready; |
316 | if ( sendSync ) { | 307 | if ( sendSync ) { |
317 | sendDesktopMessage( "startSync()" ); | 308 | sendDesktopMessage( "startSync()" ); |
@@ -322,8 +313,7 @@ void QCopBridgePI::process( const QString& message ) | |||
322 | 313 | ||
323 | // noop (NOOP) | 314 | // noop (NOOP) |
324 | else if ( cmd == "NOOP" ) { | 315 | else if ( cmd == "NOOP" ) { |
325 | connected = TRUE; | 316 | send( "200 Command okay" ); // No tr |
326 | send( "200 Command okay" ); | ||
327 | } | 317 | } |
328 | 318 | ||
329 | // call (CALL) | 319 | // call (CALL) |
@@ -332,7 +322,7 @@ void QCopBridgePI::process( const QString& message ) | |||
332 | // example: call QPE/System execute(QString) addressbook | 322 | // example: call QPE/System execute(QString) addressbook |
333 | 323 | ||
334 | if ( msg.count() < 3 ) { | 324 | if ( msg.count() < 3 ) { |
335 | send( "500 Syntax error, command unrecognized" ); | 325 | send( "500 Syntax error, command unrecognized" ); // No tr |
336 | } | 326 | } |
337 | else { | 327 | else { |
338 | 328 | ||
@@ -343,13 +333,13 @@ void QCopBridgePI::process( const QString& message ) | |||
343 | 333 | ||
344 | int paren = command.find( "(" ); | 334 | int paren = command.find( "(" ); |
345 | if ( paren <= 0 ) { | 335 | if ( paren <= 0 ) { |
346 | send( "500 Syntax error, command unrecognized" ); | 336 | send( "500 Syntax error, command unrecognized" ); // No tr |
347 | return; | 337 | return; |
348 | } | 338 | } |
349 | 339 | ||
350 | QString params = command.mid( paren + 1 ); | 340 | QString params = command.mid( paren + 1 ); |
351 | if ( params[params.length()-1] != ')' ) { | 341 | if ( params[(int)params.length()-1] != ')' ) { |
352 | send( "500 Syntax error, command unrecognized" ); | 342 | send( "500 Syntax error, command unrecognized" ); // No tr |
353 | return; | 343 | return; |
354 | } | 344 | } |
355 | 345 | ||
@@ -361,7 +351,7 @@ void QCopBridgePI::process( const QString& message ) | |||
361 | 351 | ||
362 | QStringList paramList = QStringList::split( ",", params ); | 352 | QStringList paramList = QStringList::split( ",", params ); |
363 | if ( paramList.count() > msg.count() - 3 ) { | 353 | if ( paramList.count() > msg.count() - 3 ) { |
364 | send( "500 Syntax error, command unrecognized" ); | 354 | send( "500 Syntax error, command unrecognized" ); // No tr |
365 | return; | 355 | return; |
366 | } | 356 | } |
367 | 357 | ||
@@ -381,7 +371,7 @@ void QCopBridgePI::process( const QString& message ) | |||
381 | else if ( *it == "bool" ) | 371 | else if ( *it == "bool" ) |
382 | ds << arg.toInt(); | 372 | ds << arg.toInt(); |
383 | else { | 373 | else { |
384 | send( "500 Syntax error, command unrecognized" ); | 374 | send( "500 Syntax error, command unrecognized" ); // No tr |
385 | return; | 375 | return; |
386 | } | 376 | } |
387 | msgId++; | 377 | msgId++; |
@@ -395,28 +385,20 @@ void QCopBridgePI::process( const QString& message ) | |||
395 | return; | 385 | return; |
396 | } | 386 | } |
397 | #endif | 387 | #endif |
398 | 388 | ||
399 | #ifndef QT_NO_COP | 389 | #ifndef QT_NO_COP |
400 | if ( paramList.count() ) | 390 | if ( paramList.count() ) |
401 | QCopChannel::send( channel.latin1(), command.latin1(), buffer ); | 391 | QCopChannel::send( channel.latin1(), command.latin1(), buffer ); |
402 | else | 392 | else |
403 | QCopChannel::send( channel.latin1(), command.latin1() ); | 393 | QCopChannel::send( channel.latin1(), command.latin1() ); |
404 | 394 | ||
405 | send( "200 Command okay" ); | 395 | send( "200 Command okay" ); // No tr |
406 | #endif | 396 | #endif |
407 | } | 397 | } |
408 | } | 398 | } |
409 | // not implemented | 399 | // not implemented |
410 | else | 400 | else |
411 | send( "502 Command not implemented" ); | 401 | send( "502 Command not implemented" ); // No tr |
412 | } | 402 | } |
413 | 403 | ||
414 | 404 | ||
415 | |||
416 | void QCopBridgePI::timerEvent( QTimerEvent * ) | ||
417 | { | ||
418 | if ( connected ) | ||
419 | connected = FALSE; | ||
420 | else | ||
421 | connectionClosed(); | ||
422 | } | ||