summaryrefslogtreecommitdiff
path: root/core/launcher/qcopbridge.cpp
Unidiff
Diffstat (limited to 'core/launcher/qcopbridge.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/qcopbridge.cpp222
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
50const int block_size = 51200; 61const int block_size = 51200;
51 62
52QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent , 63QCopBridge::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
73QCopBridge::~QCopBridge() 85QCopBridge::~QCopBridge()
@@ -77,11 +89,28 @@ QCopBridge::~QCopBridge()
77#endif 89#endif
78} 90}
79 91
92void 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
80void QCopBridge::newConnection( int socket ) 104void 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
95void QCopBridge::connectionClosed( QCopBridgePI *pi ) 124void 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
113void QCopBridge::desktopMessage( const QCString &command, const QByteArray &args ) 147void 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( "&amp;" );
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
201QCopBridgePI::QCopBridgePI( int socket, QObject *parent , const char* name ) 169QCopBridgePI::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
236QCopBridgePI::~QCopBridgePI() 204QCopBridgePI::~QCopBridgePI()
237{ 205{
206}
238 207
208bool QCopBridgePI::verifyAuthorised()
209{
210 if ( !SyncAuthentication::isAuthorized(peerAddress()) ) {
211 state = Forbidden;
212 return FALSE;
213 }
214 return TRUE;
239} 215}
240 216
241void QCopBridgePI::connectionClosed() 217void QCopBridgePI::myConnectionClosed()
242{ 218{
243 emit connectionClosed( this ); 219 emit connectionClosed( this );
244 // qDebug( "Debug: Connection closed" );
245 delete this;
246} 220}
247 221
248void QCopBridgePI::sendDesktopMessage( const QString &msg ) 222void 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
228void 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
255void QCopBridgePI::send( const QString& msg ) 242void 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
262void QCopBridgePI::read() 251void 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
268void QCopBridgePI::process( const QString& message ) 259void 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
416void QCopBridgePI::timerEvent( QTimerEvent * )
417{
418 if ( connected )
419 connected = FALSE;
420 else
421 connectionClosed();
422}