-rw-r--r-- | core/launcher/qcopbridge.cpp | 222 | ||||
-rw-r--r-- | core/launcher/qcopbridge.h | 25 | ||||
-rw-r--r-- | core/launcher/runningappbar.cpp | 356 |
3 files changed, 228 insertions, 375 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 | |||
@@ -18,41 +18,52 @@ | |||
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | 20 | ||
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 ), |
56 | cardChannel( 0 ) | 67 | cardChannel( 0 ) |
57 | { | 68 | { |
58 | if ( !ok() ) | 69 | if ( !ok() ) |
@@ -65,207 +76,187 @@ QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent , | |||
65 | cardChannel = new QCopChannel( "QPE/Card", this ); | 76 | cardChannel = new QCopChannel( "QPE/Card", this ); |
66 | connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)), | 77 | connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)), |
67 | this, SLOT(desktopMessage( const QCString &, const QByteArray &)) ); | 78 | this, SLOT(desktopMessage( const QCString &, const QByteArray &)) ); |
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() |
74 | { | 86 | { |
75 | #ifndef QT_NO_COP | 87 | #ifndef QT_NO_COP |
76 | delete desktopChannel; | 88 | delete desktopChannel; |
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 |
88 | 117 | ||
89 | if ( sendSync ) { | 118 | if ( sendSync ) { |
90 | pi ->startSync(); | 119 | pi ->startSync(); |
91 | sendSync = FALSE; | 120 | sendSync = FALSE; |
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 | } |
104 | 138 | ||
105 | void QCopBridge::closeOpenConnections() | 139 | void QCopBridge::closeOpenConnections() |
106 | { | 140 | { |
107 | QCopBridgePI *pi; | 141 | QCopBridgePI *pi; |
108 | for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) | 142 | for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) |
109 | pi->close(); | 143 | pi->close(); |
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 | ||
194 | void QCopBridge::timerEvent( QTimerEvent * ) | 162 | void QCopBridge::timerEvent( QTimerEvent * ) |
195 | { | 163 | { |
196 | sendSync = FALSE; | 164 | sendSync = FALSE; |
197 | killTimers(); | 165 | killTimers(); |
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 ); |
205 | 173 | ||
206 | peerport = peerPort(); | 174 | peerport = peerPort(); |
207 | peeraddress = peerAddress(); | 175 | peeraddress = peerAddress(); |
208 | 176 | ||
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() ); |
260 | } | 249 | } |
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 ) |
269 | { | 260 | { |
270 | //qDebug( "Command: %s", message.latin1() ); | 261 | //qDebug( "Command: %s", message.latin1() ); |
271 | 262 | ||
@@ -280,91 +271,90 @@ void QCopBridgePI::process( const QString& message ) | |||
280 | QString arg; | 271 | QString arg; |
281 | if ( msg.count() >= 2 ) | 272 | if ( msg.count() >= 2 ) |
282 | arg = msg[1]; | 273 | arg = msg[1]; |
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 | ||
291 | // connected to client | 282 | // connected to client |
292 | if ( Connected == state ) | 283 | if ( Connected == state ) |
293 | return; | 284 | return; |
294 | 285 | ||
295 | // waiting for user name | 286 | // waiting for user name |
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 | } |
306 | 297 | ||
307 | // waiting for password | 298 | // waiting for password |
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()" ); |
318 | sendSync = FALSE; | 309 | sendSync = FALSE; |
319 | } | 310 | } |
320 | return; | 311 | return; |
321 | } | 312 | } |
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) |
330 | else if ( cmd == "CALL" ) { | 320 | else if ( cmd == "CALL" ) { |
331 | 321 | ||
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 | ||
339 | QString channel = msg[1]; | 329 | QString channel = msg[1]; |
340 | QString command = msg[2]; | 330 | QString command = msg[2]; |
341 | 331 | ||
342 | command.stripWhiteSpace(); | 332 | command.stripWhiteSpace(); |
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 | ||
356 | params.truncate( params.length()-1 ); | 346 | params.truncate( params.length()-1 ); |
357 | QByteArray buffer; | 347 | QByteArray buffer; |
358 | QDataStream ds( buffer, IO_WriteOnly ); | 348 | QDataStream ds( buffer, IO_WriteOnly ); |
359 | 349 | ||
360 | int msgId = 3; | 350 | int msgId = 3; |
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 | ||
368 | for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { | 358 | for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) { |
369 | 359 | ||
370 | QString arg = msg[msgId]; | 360 | QString arg = msg[msgId]; |
@@ -378,13 +368,13 @@ void QCopBridgePI::process( const QString& message ) | |||
378 | ds << arg.local8Bit(); | 368 | ds << arg.local8Bit(); |
379 | else if ( *it == "int" ) | 369 | else if ( *it == "int" ) |
380 | ds << arg.toInt(); | 370 | ds << arg.toInt(); |
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++; |
388 | } | 378 | } |
389 | 379 | ||
390 | #ifndef QT_NO_COP | 380 | #ifndef QT_NO_COP |
@@ -392,31 +382,23 @@ void QCopBridgePI::process( const QString& message ) | |||
392 | // send message back about it | 382 | // send message back about it |
393 | QString answer = "599 ChannelNotRegistered " + channel; | 383 | QString answer = "599 ChannelNotRegistered " + channel; |
394 | send( answer ); | 384 | send( answer ); |
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 | } | ||
diff --git a/core/launcher/qcopbridge.h b/core/launcher/qcopbridge.h index 408d10d..bae3f88 100644 --- a/core/launcher/qcopbridge.h +++ b/core/launcher/qcopbridge.h | |||
@@ -17,40 +17,46 @@ | |||
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | **********************************************************************/ | 19 | **********************************************************************/ |
20 | #ifndef __qcopbridge_h__ | 20 | #ifndef __qcopbridge_h__ |
21 | #define __qcopbridge_h__ | 21 | #define __qcopbridge_h__ |
22 | 22 | ||
23 | #include <qtopia/global.h> | ||
23 | #include <qserversocket.h> | 24 | #include <qserversocket.h> |
24 | #include <qsocket.h> | 25 | #include <qsocket.h> |
25 | #include <qdir.h> | 26 | #include <qdir.h> |
26 | #include <qfile.h> | 27 | #include <qfile.h> |
27 | #include <qbuffer.h> | 28 | #include <qbuffer.h> |
28 | 29 | ||
29 | class QFileInfo; | 30 | class QFileInfo; |
30 | class QCopBridgePI; | 31 | class QCopBridgePI; |
31 | class QCopChannel; | 32 | class QCopChannel; |
33 | class QTimer; | ||
32 | 34 | ||
33 | class QCopBridge : public QServerSocket | 35 | class QCopBridge : public QServerSocket |
34 | { | 36 | { |
35 | Q_OBJECT | 37 | Q_OBJECT |
36 | 38 | ||
37 | public: | 39 | public: |
38 | QCopBridge( Q_UINT16 port, QObject *parent = 0, const char* name = 0 ); | 40 | QCopBridge( Q_UINT16 port, QObject *parent = 0, const char* name = 0 ); |
39 | virtual ~QCopBridge(); | 41 | virtual ~QCopBridge(); |
40 | 42 | ||
41 | void newConnection( int socket ); | 43 | void newConnection( int socket ); |
42 | void closeOpenConnections(); | 44 | void closeOpenConnections(); |
45 | void authorizeConnections(); | ||
43 | 46 | ||
44 | public slots: | 47 | public slots: |
45 | void connectionClosed( QCopBridgePI *pi ); | 48 | void closed( QCopBridgePI *pi ); |
46 | void desktopMessage( const QCString &call, const QByteArray & ); | 49 | void desktopMessage( const QCString &call, const QByteArray & ); |
47 | 50 | ||
51 | signals: | ||
52 | void connectionClosed( const QHostAddress & ); | ||
53 | |||
48 | protected: | 54 | protected: |
49 | void timerEvent( QTimerEvent * ); | 55 | void timerEvent( QTimerEvent * ); |
50 | 56 | ||
51 | private: | 57 | private: |
52 | QCopChannel *desktopChannel; | 58 | QCopChannel *desktopChannel; |
53 | QCopChannel *cardChannel; | 59 | QCopChannel *cardChannel; |
54 | QList<QCopBridgePI> openConnections; | 60 | QList<QCopBridgePI> openConnections; |
55 | bool sendSync; | 61 | bool sendSync; |
56 | }; | 62 | }; |
@@ -64,29 +70,28 @@ class QCopBridgePI : public QSocket | |||
64 | 70 | ||
65 | public: | 71 | public: |
66 | QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 ); | 72 | QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 ); |
67 | virtual ~QCopBridgePI(); | 73 | virtual ~QCopBridgePI(); |
68 | 74 | ||
69 | void sendDesktopMessage( const QString &msg ); | 75 | void sendDesktopMessage( const QString &msg ); |
76 | void sendDesktopMessage( const QCString &msg, const QByteArray& ); | ||
70 | void startSync() { sendSync = TRUE; } | 77 | void startSync() { sendSync = TRUE; } |
71 | 78 | bool verifyAuthorised(); | |
79 | |||
72 | signals: | 80 | signals: |
73 | void connectionClosed( QCopBridgePI *); | 81 | void connectionClosed( QCopBridgePI *); |
74 | 82 | ||
75 | protected slots: | 83 | protected slots: |
76 | void read(); | 84 | void read(); |
77 | void send( const QString& msg ); | 85 | void send( const QString& msg ); |
78 | void process( const QString& command ); | 86 | void process( const QString& command ); |
79 | void connectionClosed(); | 87 | void myConnectionClosed(); |
80 | |||
81 | protected: | ||
82 | void timerEvent( QTimerEvent *e ); | ||
83 | 88 | ||
84 | private: | 89 | private: |
85 | State state; | 90 | State state; |
86 | Q_UINT16 peerport; | 91 | Q_UINT16 peerport; |
87 | QHostAddress peeraddress; | 92 | QHostAddress peeraddress; |
88 | bool connected; | ||
89 | bool sendSync; | 93 | bool sendSync; |
94 | QTimer *timer; | ||
90 | }; | 95 | }; |
91 | 96 | ||
92 | #endif | 97 | #endif |
diff --git a/core/launcher/runningappbar.cpp b/core/launcher/runningappbar.cpp index 356200b..1fda5a4 100644 --- a/core/launcher/runningappbar.cpp +++ b/core/launcher/runningappbar.cpp | |||
@@ -13,301 +13,167 @@ | |||
13 | ** | 13 | ** |
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
15 | ** | 15 | ** |
16 | ** Contact info@trolltech.com if any conditions of this licensing are | 16 | ** Contact info@trolltech.com if any conditions of this licensing are |
17 | ** not clear to you. | 17 | ** not clear to you. |
18 | ** | 18 | ** |
19 | ********************************************************************** | 19 | ***********************************************************************/ |
20 | */ | ||
21 | 20 | ||
22 | #define QTOPIA_INTERNAL_PRELOADACCESS | 21 | #define QTOPIA_INTERNAL_PRELOADACCESS |
23 | 22 | ||
24 | // For "kill" | 23 | #include <qtopia/global.h> |
25 | #include <sys/types.h> | 24 | |
26 | #include <signal.h> | ||
27 | #include <stdio.h> | ||
28 | #include <stdlib.h> | 25 | #include <stdlib.h> |
29 | 26 | ||
30 | #include <qdir.h> | ||
31 | #include <qtimer.h> | 27 | #include <qtimer.h> |
32 | #include <qpopupmenu.h> | 28 | #include <qpopupmenu.h> |
33 | #include <qmessagebox.h> | ||
34 | #include <qpainter.h> | 29 | #include <qpainter.h> |
35 | #include <opie/oprocess.h> | 30 | #include <qmessagebox.h> |
36 | #include <qpe/qpeapplication.h> | 31 | |
37 | #include <qpe/applnk.h> | 32 | #include <qtopia/qpeapplication.h> |
38 | #include <qpe/qcopenvelope_qws.h> | 33 | #include <qtopia/applnk.h> |
39 | #include <qpe/global.h> | 34 | #include <qtopia/qcopenvelope_qws.h> |
40 | #include <qwindowsystem_qws.h> | 35 | #include <qtopia/mimetype.h> |
36 | |||
41 | #include "runningappbar.h" | 37 | #include "runningappbar.h" |
38 | #include "serverinterface.h" | ||
42 | 39 | ||
43 | RunningAppBar::RunningAppBar(QWidget* parent) | 40 | RunningAppBar::RunningAppBar(QWidget* parent) |
44 | : QFrame(parent), m_AppLnkSet(0L), m_SelectedAppIndex( -1) | 41 | : QFrame(parent), selectedAppIndex(-1) |
45 | { | 42 | { |
46 | setBackgroundMode( PaletteBackground ); | 43 | QCopChannel* channel = new QCopChannel( "QPE/System", this ); |
47 | 44 | connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), | |
48 | m_AppLnkSet = new AppLnkSet( QPEApplication::qpeDir() + "apps" ); | 45 | this, SLOT(received(const QCString&, const QByteArray&)) ); |
49 | |||
50 | #ifdef QWS | ||
51 | 46 | ||
52 | connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&))); | 47 | spacing = AppLnk::smallIconSize()+3; |
53 | connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&))); | ||
54 | #endif | ||
55 | |||
56 | QCopChannel* channel = new QCopChannel( "QPE/System", this ); | ||
57 | connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), | ||
58 | this, SLOT(received(const QCString&, const QByteArray&)) ); | ||
59 | |||
60 | spacing = AppLnk::smallIconSize() + 3; | ||
61 | } | 48 | } |
62 | 49 | ||
63 | RunningAppBar::~RunningAppBar() | 50 | RunningAppBar::~RunningAppBar() |
64 | {} | ||
65 | |||
66 | void RunningAppBar::newQcopChannel(const QString& channelName) | ||
67 | { | ||
68 | QString prefix("QPE/Application/"); | ||
69 | if (channelName.startsWith(prefix)) { | ||
70 | QString appName = channelName.mid(prefix.length()); | ||
71 | // qDebug("App %s just connected!", appName.latin1()); | ||
72 | const AppLnk* newGuy = m_AppLnkSet->findExec(appName); | ||
73 | if (newGuy && !newGuy->isPreloaded()) { | ||
74 | addTask(*newGuy); | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | |||
79 | void RunningAppBar::removedQcopChannel(const QString& channelName) | ||
80 | { | 51 | { |
81 | QString prefix("QPE/Application/"); | ||
82 | if (channelName.startsWith(prefix)) { | ||
83 | QString appName = channelName.mid(prefix.length()); | ||
84 | qDebug("App %s just disconnected!", appName.latin1()); | ||
85 | const AppLnk* newGuy = m_AppLnkSet->findExec(appName); | ||
86 | if (newGuy) { | ||
87 | removeTask(*newGuy); | ||
88 | } | ||
89 | } | ||
90 | } | 52 | } |
91 | 53 | ||
92 | void RunningAppBar::received(const QCString& msg, const QByteArray& data) | 54 | void RunningAppBar::received(const QCString& msg, const QByteArray& data) { |
93 | { | 55 | // Since fast apps appear and disappear without disconnecting from their |
94 | // Since fast apps appear and disappear without disconnecting from their | 56 | // channel we need to watch for the showing/hiding events and update according. |
95 | // channel we need to watch for the showing/hiding events and update according. | 57 | QDataStream stream( data, IO_ReadOnly ); |
96 | QDataStream stream( data, IO_ReadOnly ); | 58 | if ( msg == "fastAppShowing(QString)") { |
97 | if ( msg == "fastAppShowing(QString)") { | 59 | QString appName; |
98 | QString appName; | 60 | stream >> appName; |
99 | stream >> appName; | 61 | // qDebug("fastAppShowing %s", appName.data() ); |
100 | addTask(*m_AppLnkSet->findExec(appName)); | 62 | const AppLnk* f = ServerInterface::appLnks().findExec(appName); |
101 | } | 63 | if ( f ) addTask(*f); |
102 | else if ( msg == "fastAppHiding(QString)") { | 64 | } else if ( msg == "fastAppHiding(QString)") { |
103 | QString appName; | 65 | QString appName; |
104 | stream >> appName; | 66 | stream >> appName; |
105 | removeTask(*m_AppLnkSet->findExec(appName)); | 67 | const AppLnk* f = ServerInterface::appLnks().findExec(appName); |
106 | } | 68 | if ( f ) removeTask(*f); |
69 | } | ||
107 | } | 70 | } |
108 | 71 | ||
109 | void RunningAppBar::addTask(const AppLnk& appLnk) | 72 | void RunningAppBar::addTask(const AppLnk& appLnk) { |
110 | { | 73 | qDebug("Added %s to app list.", appLnk.name().latin1()); |
111 | // qDebug("Added %s to app list.", appLnk.name().latin1()); | 74 | AppLnk* newApp = new AppLnk(appLnk); |
112 | AppLnk* newApp = new AppLnk(appLnk); | 75 | newApp->setExec(appLnk.exec()); |
113 | newApp->setExec(appLnk.exec()); | 76 | appList.prepend(newApp); |
114 | m_AppList.prepend(newApp); | 77 | update(); |
115 | update(); | ||
116 | } | 78 | } |
117 | 79 | ||
118 | void RunningAppBar::removeTask(const AppLnk& appLnk) | 80 | void RunningAppBar::removeTask(const AppLnk& appLnk) { |
119 | { | 81 | unsigned int i = 0; |
120 | unsigned int i = 0; | 82 | for (; i < appList.count() ; i++) { |
121 | for (; i < m_AppList.count() ; i++) { | 83 | AppLnk* target = appList.at(i); |
122 | AppLnk* target = m_AppList.at(i); | 84 | if (target->exec() == appLnk.exec()) { |
123 | if (target->exec() == appLnk.exec()) { | 85 | qDebug("Removing %s from app list.", appLnk.name().latin1()); |
124 | qDebug("Removing %s from app list.", appLnk.name().latin1()); | 86 | appList.remove(); |
125 | m_AppList.remove(); | 87 | delete target; |
126 | 88 | } | |
127 | delete target; | 89 | } |
128 | } | 90 | update(); |
129 | } | ||
130 | update(); | ||
131 | } | 91 | } |
132 | 92 | ||
133 | void RunningAppBar::mousePressEvent(QMouseEvent *e) | 93 | void RunningAppBar::mousePressEvent(QMouseEvent *e) |
134 | { | 94 | { |
135 | // Find out if the user is clicking on an app icon... | 95 | // Find out if the user is clicking on an app icon... |
136 | // If so, snag the index so when we repaint we show it | 96 | // If so, snag the index so when we repaint we show it |
137 | // as highlighed. | 97 | // as highlighed. |
138 | m_SelectedAppIndex = 0; | 98 | selectedAppIndex = 0; |
139 | int x = 0; | 99 | int x=0; |
140 | QListIterator<AppLnk> it( m_AppList ); | 100 | QListIterator<AppLnk> it( appList ); |
141 | for ( ; it.current(); ++it, ++m_SelectedAppIndex, x += spacing ) { | 101 | for ( ; it.current(); ++it,++selectedAppIndex,x+=spacing ) { |
142 | if ( x + spacing <= width() ) { | 102 | if ( x + spacing <= width() ) { |
143 | if ( e->x() >= x && e->x() < x + spacing ) { | 103 | if ( e->x() >= x && e->x() < x+spacing ) { |
144 | if ( m_SelectedAppIndex < (int)m_AppList.count() ) { | 104 | if ( selectedAppIndex < (int)appList.count() ) { |
145 | repaint(FALSE); | 105 | repaint(FALSE); |
146 | return ; | 106 | return; |
147 | } | ||
148 | } | ||
149 | } | ||
150 | else { | ||
151 | break; | ||
152 | } | ||
153 | } | 107 | } |
154 | m_SelectedAppIndex = -1; | 108 | } |
155 | repaint( FALSE ); | 109 | } else { |
110 | break; | ||
111 | } | ||
112 | } | ||
113 | selectedAppIndex = -1; | ||
114 | repaint( FALSE ); | ||
156 | } | 115 | } |
157 | 116 | ||
158 | void RunningAppBar::mouseReleaseEvent(QMouseEvent *e) | 117 | void RunningAppBar::mouseReleaseEvent(QMouseEvent *e) |
159 | { | 118 | { |
160 | if (e->button() == QMouseEvent::RightButton) { | 119 | if (e->button() == QMouseEvent::RightButton) |
161 | return ; | 120 | return; |
162 | } | 121 | if ( selectedAppIndex >= 0 ) { |
163 | if ( m_SelectedAppIndex >= 0 ) { | 122 | QString app = appList.at(selectedAppIndex)->exec(); |
164 | QString channel = QString("QPE/Application/") + m_AppList.at(m_SelectedAppIndex)->exec(); | 123 | QCopEnvelope e("QPE/System", "raise(QString)"); |
165 | if (QCopChannel::isRegistered(channel.latin1())) { | 124 | e << app; |
166 | // qDebug("%s is running!", m_AppList.at(m_SelectedAppIndex)->exec().latin1()); | 125 | selectedAppIndex = -1; |
167 | QCopEnvelope e(channel.latin1(), "raise()"); | 126 | update(); |
168 | // This class will delete itself after hearing from the app or the timer expiring | 127 | } |
169 | (void)new AppMonitor(*m_AppList.at(m_SelectedAppIndex), *this); | ||
170 | } | ||
171 | else { | ||
172 | removeTask(*m_AppList.at(m_SelectedAppIndex)); | ||
173 | } | ||
174 | |||
175 | m_SelectedAppIndex = -1; | ||
176 | update(); | ||
177 | } | ||
178 | } | 128 | } |
179 | 129 | ||
180 | void RunningAppBar::paintEvent( QPaintEvent * ) | 130 | void RunningAppBar::paintEvent( QPaintEvent * ) |
181 | { | 131 | { |
182 | QPainter p( this ); | 132 | QPainter p( this ); |
183 | AppLnk *curApp; | 133 | AppLnk *curApp; |
184 | int x = 0; | 134 | int x = 0; |
185 | int y = (height() - AppLnk::smallIconSize()) / 2; | 135 | int y = (height() - AppLnk::smallIconSize()) / 2; |
186 | int i = 0; | 136 | int i = 0; |
187 | 137 | ||
188 | //p.fillRect( 0, 0, width(), height(), colorGroup().background() ); | 138 | p.fillRect( 0, 0, width(), height(), colorGroup().background() ); |
189 | 139 | ||
190 | QListIterator<AppLnk> it(m_AppList); | 140 | QListIterator<AppLnk> it(appList); |
191 | 141 | ||
192 | for (; it.current(); i++, ++it ) { | 142 | for (; it.current(); i++, ++it ) { |
193 | if ( x + spacing <= width() ) { | 143 | if ( x + spacing <= width() ) { |
194 | curApp = it.current(); | 144 | curApp = it.current(); |
195 | if ( (int)i == m_SelectedAppIndex ) | 145 | qWarning("Drawing %s", curApp->name().latin1() ); |
196 | p.fillRect( x, y, spacing, curApp->pixmap().height() + 1, colorGroup().highlight() ); | 146 | if ( (int)i == selectedAppIndex ) |
197 | else | 147 | p.fillRect( x, y, spacing, curApp->pixmap().height()+1, colorGroup().highlight() ); |
198 | // p.eraseRect( x, y, spacing, curApp->pixmap().height()+1 ); | 148 | else |
199 | p.drawPixmap( x, y, curApp->pixmap() ); | 149 | p.eraseRect( x, y, spacing, curApp->pixmap().height()+1 ); |
200 | x += spacing; | 150 | p.drawPixmap( x, y, curApp->pixmap() ); |
201 | } | 151 | x += spacing; |
202 | } | 152 | } |
153 | } | ||
203 | } | 154 | } |
204 | 155 | ||
205 | QSize RunningAppBar::sizeHint() const | 156 | QSize RunningAppBar::sizeHint() const |
206 | { | 157 | { |
207 | return QSize( frameWidth(), AppLnk::smallIconSize() + frameWidth()*2 + 3 ); | 158 | return QSize( frameWidth(), AppLnk::smallIconSize()+frameWidth()*2+3 ); |
208 | } | 159 | } |
209 | 160 | ||
210 | const int AppMonitor::RAISE_TIMEOUT_MS = 500; | 161 | void RunningAppBar::applicationLaunched(const QString &appName) |
211 | |||
212 | AppMonitor::AppMonitor(const AppLnk& app, RunningAppBar& owner) | ||
213 | : QObject(0L), m_Owner(owner), m_App(app), m_AppKillerBox(0L) | ||
214 | { | 162 | { |
215 | QCopChannel* channel = new QCopChannel( "QPE/System", this ); | 163 | qDebug("desktop:: app: %s launched with pid ", appName.data() ); |
216 | connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), | 164 | const AppLnk* newGuy = ServerInterface::appLnks().findExec(appName); |
217 | this, SLOT(received(const QCString&, const QByteArray&)) ); | 165 | if ( newGuy && !newGuy->isPreloaded() ) { |
218 | connect(&m_Timer, SIGNAL(timeout()), this, SLOT(timerExpired())); | 166 | addTask( *newGuy ); |
219 | m_Timer.start(RAISE_TIMEOUT_MS, TRUE); | 167 | } |
220 | } | 168 | } |
221 | 169 | ||
222 | AppMonitor::~AppMonitor() | 170 | void RunningAppBar::applicationTerminated(const QString &app) |
223 | { | 171 | { |
224 | if (m_AppKillerBox) { | 172 | const AppLnk* gone = ServerInterface::appLnks().findExec(app); |
225 | delete m_AppKillerBox; | 173 | if ( gone ) { |
226 | m_AppKillerBox = 0L; | 174 | removeTask(*gone); |
227 | } | 175 | } |
228 | } | ||
229 | |||
230 | void AppMonitor::received(const QCString& msg, const QByteArray& data) | ||
231 | { | ||
232 | QDataStream stream( data, IO_ReadOnly ); | ||
233 | |||
234 | if (msg == "appRaised(QString)") { | ||
235 | QString appName; | ||
236 | stream >> appName; | ||
237 | if (appName == m_App.exec()) { | ||
238 | // qDebug("Got a heartbeat from %s", appName.latin1()); | ||
239 | m_Timer.stop(); | ||
240 | // Check to make sure we're not waiting on user input... | ||
241 | if (m_AppKillerBox) { | ||
242 | // If we are, we kill the dialog box, and the code waiting on the result | ||
243 | // will clean us up (basically the user said "no"). | ||
244 | delete m_AppKillerBox; | ||
245 | m_AppKillerBox = 0L; | ||
246 | } | ||
247 | else { | ||
248 | // Ok, we're not waiting on user input, so clean us up now. | ||
249 | // WE DELETE OURSELVES HERE! Don't do anything else!! | ||
250 | delete this; | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | } | 176 | } |
255 | 177 | ||
256 | void AppMonitor::timerExpired() | ||
257 | { | ||
258 | // We store this incase the application responds while we're | ||
259 | // waiting for user input so we know not to delete ourselves. This | ||
260 | // will be cleaned up in the destructor. | ||
261 | m_AppKillerBox = new QMessageBox(tr("Application Problem"), | ||
262 | tr("<p>%1 is not responding.</p>").arg(m_App.name()) + | ||
263 | tr("<p>Would you like to force the application to exit?</p>"), | ||
264 | QMessageBox::Warning, QMessageBox::Yes, | ||
265 | QMessageBox::No | QMessageBox::Default, | ||
266 | QMessageBox::NoButton); | ||
267 | if ( m_AppKillerBox-> exec ( ) == QMessageBox::Yes ) { | ||
268 | QDir proc ( "/proc/", "[0-9]*", QDir::Name | QDir::Reversed, QDir::Dirs ); | ||
269 | QStringList allprocs = proc. entryList ( ); | ||
270 | |||
271 | pid_t mypid = ::getpid ( ); | ||
272 | |||
273 | for ( QStringList::Iterator it = allprocs. begin ( ); it != allprocs. end ( ); ++it ) { | ||
274 | if (( *it ). toInt ( ) <= mypid ) // only interested in children | ||
275 | continue; | ||
276 | |||
277 | QCString s = QString ( "/proc/" + *it + "/stat" ). local8Bit ( ); | ||
278 | |||
279 | FILE *fp = ::fopen ( s. data ( ), "r" ); | ||
280 | if ( fp ) { | ||
281 | pid_t pid, ppid; | ||
282 | char *execptr, *exec = 0; | ||
283 | |||
284 | if ( ::fscanf ( fp, "%d %as %*c %d ", &pid, &execptr, &ppid ) == 3 ) { | ||
285 | exec = execptr [0] ? execptr + 1 : execptr; | ||
286 | if ( exec [0] ) | ||
287 | exec [::strlen ( exec ) - 1] = 0; | ||
288 | |||
289 | if (( ppid == ::getpid ( )) && ( m_App. exec ( ). local8Bit ( ) == exec )) { | ||
290 | bool success = false; | ||
291 | 178 | ||
292 | qDebug ( "trying to kill pid=%d, exec=%s, ppid=%d", pid, exec, ppid ); | ||
293 | |||
294 | |||
295 | success |= ( ::kill ( pid, SIGTERM ) == 0 ); | ||
296 | ::usleep ( 1000 * 500 ); | ||
297 | success |= ( ::kill ( pid, SIGKILL ) == 0 ); | ||
298 | |||
299 | if ( success ) | ||
300 | m_Owner. removeTask ( m_App ); | ||
301 | |||
302 | ::free ( execptr ); | ||
303 | break; | ||
304 | } | ||
305 | ::free ( execptr ); | ||
306 | } | ||
307 | ::fclose ( fp ); | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | delete this; | ||
312 | } | ||
313 | 179 | ||