summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/transferserver.cpp6
1 files changed, 5 insertions, 1 deletions
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp
index 371400e..fde6f8b 100644
--- a/core/launcher/transferserver.cpp
+++ b/core/launcher/transferserver.cpp
@@ -1,1415 +1,1419 @@
1/********************************************************************** 1/**********************************************************************
2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. 2** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
3** 3**
4** This file is part of the Qtopia Environment. 4** This file is part of the Qtopia Environment.
5** 5**
6** This file may be distributed and/or modified under the terms of the 6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software 7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the 8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file. 9** packaging of this file.
10** 10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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//#define _XOPEN_SOURCE 20//#define _XOPEN_SOURCE
21 21
22#include <qtopia/global.h> 22#include <qtopia/global.h>
23#include <qtopia/qpeapplication.h> 23#include <qtopia/qpeapplication.h>
24 24
25#ifndef Q_OS_WIN32 25#ifndef Q_OS_WIN32
26#include <pwd.h> 26#include <pwd.h>
27#include <sys/types.h> 27#include <sys/types.h>
28#include <unistd.h> 28#include <unistd.h>
29#include <stdlib.h> 29#include <stdlib.h>
30#include <time.h> 30#include <time.h>
31#include <shadow.h> 31#include <shadow.h>
32#include <crypt.h> 32#include <crypt.h>
33 33
34#else 34#else
35#include <stdlib.h> 35#include <stdlib.h>
36#include <time.h> 36#include <time.h>
37#endif 37#endif
38 38
39 39
40#if defined(_OS_LINUX_) 40#if defined(_OS_LINUX_)
41#include <shadow.h> 41#include <shadow.h>
42#endif 42#endif
43 43
44#include <qdir.h> 44#include <qdir.h>
45#include <qfile.h> 45#include <qfile.h>
46#include <qtextstream.h> 46#include <qtextstream.h>
47#include <qdatastream.h> 47#include <qdatastream.h>
48#include <qmessagebox.h> 48#include <qmessagebox.h>
49#include <qstringlist.h> 49#include <qstringlist.h>
50#include <qfileinfo.h> 50#include <qfileinfo.h>
51#include <qregexp.h> 51#include <qregexp.h>
52//#include <qtopia/qcopchannel_qws.h> 52//#include <qtopia/qcopchannel_qws.h>
53#include <qtopia/process.h> 53#include <qtopia/process.h>
54#include <qtopia/global.h> 54#include <qtopia/global.h>
55#include <qtopia/config.h> 55#include <qtopia/config.h>
56#include <qtopia/private/contact.h> 56#include <qtopia/private/contact.h>
57#include <qtopia/quuid.h> 57#include <qtopia/quuid.h>
58#include <qtopia/version.h> 58#include <qtopia/version.h>
59#ifdef Q_WS_QWS 59#ifdef Q_WS_QWS
60#include <qtopia/qcopenvelope_qws.h> 60#include <qtopia/qcopenvelope_qws.h>
61#endif 61#endif
62 62
63#include "launcherglobal.h" 63#include "launcherglobal.h"
64 64
65#include "transferserver.h" 65#include "transferserver.h"
66#include <qtopia/qprocess.h> 66#include <qtopia/qprocess.h>
67 67
68const int block_size = 51200; 68const int block_size = 51200;
69 69
70TransferServer::TransferServer( Q_UINT16 port, QObject *parent, 70TransferServer::TransferServer( Q_UINT16 port, QObject *parent,
71 const char* name) 71 const char* name)
72 : QServerSocket( port, 1, parent, name ) 72 : QServerSocket( port, 1, parent, name )
73{ 73{
74 connections.setAutoDelete( TRUE ); 74 connections.setAutoDelete( TRUE );
75 if ( !ok() ) 75 if ( !ok() )
76 qWarning( "Failed to bind to port %d", port ); 76 qWarning( "Failed to bind to port %d", port );
77} 77}
78 78
79void TransferServer::authorizeConnections() 79void TransferServer::authorizeConnections()
80{ 80{
81 QListIterator<ServerPI> it(connections); 81 QListIterator<ServerPI> it(connections);
82 while ( it.current() ) { 82 while ( it.current() ) {
83 if ( !it.current()->verifyAuthorised() ) { 83 if ( !it.current()->verifyAuthorised() ) {
84 disconnect( it.current(), SIGNAL(connectionClosed(ServerPI *)), this, SLOT( closed(ServerPI *)) ); 84 disconnect( it.current(), SIGNAL(connectionClosed(ServerPI *)), this, SLOT( closed(ServerPI *)) );
85 connections.removeRef( it.current() ); 85 connections.removeRef( it.current() );
86 } else 86 } else
87 ++it; 87 ++it;
88 } 88 }
89} 89}
90 90
91void TransferServer::closed(ServerPI *item) 91void TransferServer::closed(ServerPI *item)
92{ 92{
93 connections.removeRef(item); 93 connections.removeRef(item);
94} 94}
95 95
96TransferServer::~TransferServer() 96TransferServer::~TransferServer()
97{ 97{
98} 98}
99 99
100void TransferServer::newConnection( int socket ) 100void TransferServer::newConnection( int socket )
101{ 101{
102 ServerPI *ptr = new ServerPI( socket, this ); 102 ServerPI *ptr = new ServerPI( socket, this );
103 connect( ptr, SIGNAL(connectionClosed(ServerPI *)), this, SLOT( closed(ServerPI *)) ); 103 connect( ptr, SIGNAL(connectionClosed(ServerPI *)), this, SLOT( closed(ServerPI *)) );
104 connections.append( ptr ); 104 connections.append( ptr );
105} 105}
106 106
107QString SyncAuthentication::serverId() 107QString SyncAuthentication::serverId()
108{ 108{
109 Config cfg("Security"); 109 Config cfg("Security");
110 cfg.setGroup("Sync"); 110 cfg.setGroup("Sync");
111 QString r = cfg.readEntry("serverid"); 111 QString r = cfg.readEntry("serverid");
112 112
113 if ( r.isEmpty() ) { 113 if ( r.isEmpty() ) {
114 r = Opie::Global::uuid(); 114 r = Opie::Global::uuid();
115 cfg.writeEntry("serverid", r ); 115 cfg.writeEntry("serverid", r );
116 } 116 }
117 return r; 117 return r;
118} 118}
119 119
120QString SyncAuthentication::ownerName() 120QString SyncAuthentication::ownerName()
121{ 121{
122 QString vfilename = Global::applicationFileName("addressbook", 122 QString vfilename = Global::applicationFileName("addressbook",
123 "businesscard.vcf"); 123 "businesscard.vcf");
124 if (QFile::exists(vfilename)) { 124 if (QFile::exists(vfilename)) {
125 Contact c; 125 Contact c;
126 c = Contact::readVCard( vfilename )[0]; 126 c = Contact::readVCard( vfilename )[0];
127 return c.fullName(); 127 return c.fullName();
128 } 128 }
129 129
130 return QString::null; 130 return QString::null;
131} 131}
132 132
133QString SyncAuthentication::loginName() 133QString SyncAuthentication::loginName()
134{ 134{
135 struct passwd *pw = 0L; 135 struct passwd *pw = 0L;
136#ifndef Q_OS_WIN32 136#ifndef Q_OS_WIN32
137 pw = getpwuid( geteuid() ); 137 pw = getpwuid( geteuid() );
138 return QString::fromLocal8Bit( pw->pw_name ); 138 return QString::fromLocal8Bit( pw->pw_name );
139#else 139#else
140 //### revise 140 //### revise
141 return QString(); 141 return QString();
142#endif 142#endif
143} 143}
144 144
145int SyncAuthentication::isAuthorized(QHostAddress peeraddress) 145int SyncAuthentication::isAuthorized(QHostAddress peeraddress)
146{ 146{
147 Config cfg("Security"); 147 Config cfg("Security");
148 cfg.setGroup("Sync"); 148 cfg.setGroup("Sync");
149 // QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0"); 149 // QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0");
150 uint auth_peer = cfg.readNumEntry("auth_peer", 0xc0a80100); 150 uint auth_peer = cfg.readNumEntry("auth_peer", 0xc0a80100);
151 151
152 // QHostAddress allowed; 152 // QHostAddress allowed;
153 // allowed.setAddress(allowedstr); 153 // allowed.setAddress(allowedstr);
154 // uint auth_peer = allowed.ip4Addr(); 154 // uint auth_peer = allowed.ip4Addr();
155 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits", 24); 155 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits", 24);
156 uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined 156 uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined
157 ? 0xffffffff : (((1 << auth_peer_bits) - 1) << (32 - auth_peer_bits)); 157 ? 0xffffffff : (((1 << auth_peer_bits) - 1) << (32 - auth_peer_bits));
158 158
159 return (peeraddress.ip4Addr() & mask) == auth_peer; 159 return (peeraddress.ip4Addr() & mask) == auth_peer;
160} 160}
161 161
162bool SyncAuthentication::checkUser( const QString& user ) 162bool SyncAuthentication::checkUser( const QString& user )
163{ 163{
164 if ( user.isEmpty() ) return FALSE; 164 if ( user.isEmpty() ) return FALSE;
165 QString euser = loginName(); 165 QString euser = loginName();
166 return user == euser; 166 return user == euser;
167} 167}
168 168
169bool SyncAuthentication::checkPassword( const QString& password ) 169bool SyncAuthentication::checkPassword( const QString& password )
170{ 170{
171#ifdef ALLOW_UNIX_USER_FTP 171#ifdef ALLOW_UNIX_USER_FTP
172 // First, check system password... 172 // First, check system password...
173 173
174 struct passwd *pw = 0; 174 struct passwd *pw = 0;
175 struct spwd *spw = 0; 175 struct spwd *spw = 0;
176 176
177 pw = getpwuid( geteuid() ); 177 pw = getpwuid( geteuid() );
178 spw = getspnam( pw->pw_name ); 178 spw = getspnam( pw->pw_name );
179 179
180 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); 180 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
181 if ( cpwd == "x" && spw ) 181 if ( cpwd == "x" && spw )
182 cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); 182 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
183 183
184 // Note: some systems use more than crypt for passwords. 184 // Note: some systems use more than crypt for passwords.
185 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); 185 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
186 if ( cpwd == cpassword ) 186 if ( cpwd == cpassword )
187 return TRUE; 187 return TRUE;
188#endif 188#endif
189 189
190 static int lastdenial=0; 190 static int lastdenial=0;
191 static int denials=0; 191 static int denials=0;
192 int now = time(0); 192 int now = time(0);
193 193
194 // Detect old Qtopia Desktop (no password) 194 // Detect old Qtopia Desktop (no password)
195 if ( password.isEmpty() ) { 195 if ( password.isEmpty() ) {
196 if ( denials < 1 || now > lastdenial+600 ) { 196 if ( denials < 1 || now > lastdenial+600 ) {
197 QMessageBox unauth( 197 QMessageBox unauth(
198 tr("Sync Connection"), 198 tr("Sync Connection"),
199 tr("<p>An unauthorized system is requesting access to this device." 199 tr("<p>An unauthorized system is requesting access to this device."
200 "<p>If you are using a version of Qtopia Desktop older than 1.5.1, " 200 "<p>If you are using a version of Qtopia Desktop older than 1.5.1, "
201 "please upgrade."), 201 "please upgrade."),
202 QMessageBox::Warning, 202 QMessageBox::Warning,
203 QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton, 203 QMessageBox::Cancel, QMessageBox::NoButton, QMessageBox::NoButton,
204 0, QString::null, TRUE, WStyle_StaysOnTop); 204 0, QString::null, TRUE, WStyle_StaysOnTop);
205 unauth.setButtonText(QMessageBox::Cancel, tr("Deny")); 205 unauth.setButtonText(QMessageBox::Cancel, tr("Deny"));
206 unauth.exec(); 206 unauth.exec();
207 207
208 denials++; 208 denials++;
209 lastdenial=now; 209 lastdenial=now;
210 } 210 }
211 return FALSE; 211 return FALSE;
212 } 212 }
213 213
214 // Second, check sync password... 214 // Second, check sync password...
215 215
216 static int lock=0; 216 static int lock=0;
217 if ( lock ) return FALSE; 217 if ( lock ) return FALSE;
218 218
219 ++lock; 219 ++lock;
220 if ( password.left(6) == "Qtopia" ) { 220
221 /*
222 * we need to support old Sync software and QtopiaDesktop
223 */
224 if ( password.left(6) == "Qtopia" || password.left(6) == "rootme" ) {
221 Config cfg( QPEApplication::qpeDir()+"/etc/Security.conf", Config::File ); 225 Config cfg( QPEApplication::qpeDir()+"/etc/Security.conf", Config::File );
222 cfg.setGroup("Sync"); 226 cfg.setGroup("Sync");
223 QStringList pwds = cfg.readListEntry("Passwords",' '); 227 QStringList pwds = cfg.readListEntry("Passwords",' ');
224 for (QStringList::ConstIterator it=pwds.begin(); it!=pwds.end(); ++it) { 228 for (QStringList::ConstIterator it=pwds.begin(); it!=pwds.end(); ++it) {
225#ifndef Q_OS_WIN32 229#ifndef Q_OS_WIN32
226 QString cpassword = QString::fromLocal8Bit( 230 QString cpassword = QString::fromLocal8Bit(
227 crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) ); 231 crypt( password.mid(8).local8Bit(), (*it).left(2).latin1() ) );
228#else 232#else
229 // ### revise 233 // ### revise
230 QString cpassword(""); 234 QString cpassword("");
231#endif 235#endif
232 if ( *it == cpassword ) { 236 if ( *it == cpassword ) {
233 lock--; 237 lock--;
234 return TRUE; 238 return TRUE;
235 } 239 }
236 } 240 }
237 241
238 // Unrecognized system. Be careful... 242 // Unrecognized system. Be careful...
239 QMessageBox unrecbox( 243 QMessageBox unrecbox(
240 tr("Sync Connection"), 244 tr("Sync Connection"),
241 tr("<p>An unrecognized system is requesting access to this device." 245 tr("<p>An unrecognized system is requesting access to this device."
242 "<p>If you have just initiated a Sync for the first time, this is normal."), 246 "<p>If you have just initiated a Sync for the first time, this is normal."),
243 QMessageBox::Warning, 247 QMessageBox::Warning,
244 QMessageBox::Cancel, QMessageBox::Yes, QMessageBox::NoButton, 248 QMessageBox::Cancel, QMessageBox::Yes, QMessageBox::NoButton,
245 0, QString::null, TRUE, WStyle_StaysOnTop); 249 0, QString::null, TRUE, WStyle_StaysOnTop);
246 unrecbox.setButtonText(QMessageBox::Cancel, tr("Deny")); 250 unrecbox.setButtonText(QMessageBox::Cancel, tr("Deny"));
247 unrecbox.setButtonText(QMessageBox::Yes, tr("Allow")); 251 unrecbox.setButtonText(QMessageBox::Yes, tr("Allow"));
248 252
249 if ( (denials > 2 && now < lastdenial+600) 253 if ( (denials > 2 && now < lastdenial+600)
250 || unrecbox.exec() != QMessageBox::Yes) 254 || unrecbox.exec() != QMessageBox::Yes)
251 { 255 {
252 denials++; 256 denials++;
253 lastdenial=now; 257 lastdenial=now;
254 lock--; 258 lock--;
255 return FALSE; 259 return FALSE;
256 } else { 260 } else {
257 const char salty[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/."; 261 const char salty[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/.";
258 char salt[2]; 262 char salt[2];
259 salt[0]= salty[rand() % (sizeof(salty)-1)]; 263 salt[0]= salty[rand() % (sizeof(salty)-1)];
260 salt[1]= salty[rand() % (sizeof(salty)-1)]; 264 salt[1]= salty[rand() % (sizeof(salty)-1)];
261#ifndef Q_OS_WIN32 265#ifndef Q_OS_WIN32
262 QString cpassword = QString::fromLocal8Bit( 266 QString cpassword = QString::fromLocal8Bit(
263 crypt( password.mid(8).local8Bit(), salt ) ); 267 crypt( password.mid(8).local8Bit(), salt ) );
264#else 268#else
265 //### revise 269 //### revise
266 QString cpassword(""); 270 QString cpassword("");
267#endif 271#endif
268 denials=0; 272 denials=0;
269 pwds.prepend(cpassword); 273 pwds.prepend(cpassword);
270 cfg.writeEntry("Passwords",pwds,' '); 274 cfg.writeEntry("Passwords",pwds,' ');
271 lock--; 275 lock--;
272 return TRUE; 276 return TRUE;
273 } 277 }
274 } 278 }
275 lock--; 279 lock--;
276 280
277 return FALSE; 281 return FALSE;
278} 282}
279 283
280 284
281ServerPI::ServerPI( int socket, QObject *parent, const char* name ) 285ServerPI::ServerPI( int socket, QObject *parent, const char* name )
282 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ), 286 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ),
283 storFileSize(-1) 287 storFileSize(-1)
284{ 288{
285 state = Connected; 289 state = Connected;
286 290
287 setSocket( socket ); 291 setSocket( socket );
288 292
289 peerport = peerPort(); 293 peerport = peerPort();
290 peeraddress = peerAddress(); 294 peeraddress = peerAddress();
291 295
292#ifndef INSECURE 296#ifndef INSECURE
293 if ( !SyncAuthentication::isAuthorized(peeraddress) ) { 297 if ( !SyncAuthentication::isAuthorized(peeraddress) ) {
294 state = Forbidden; 298 state = Forbidden;
295 startTimer( 0 ); 299 startTimer( 0 );
296 } else 300 } else
297#endif 301#endif
298 { 302 {
299 connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); 303 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
300 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 304 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
301 305
302 passiv = FALSE; 306 passiv = FALSE;
303 for( int i = 0; i < 4; i++ ) 307 for( int i = 0; i < 4; i++ )
304 wait[i] = FALSE; 308 wait[i] = FALSE;
305 309
306 send( "220 Qtopia " QPE_VERSION " FTP Server" ); // No tr 310 send( "220 Qtopia " QPE_VERSION " FTP Server" ); // No tr
307 state = Wait_USER; 311 state = Wait_USER;
308 312
309 dtp = new ServerDTP( this ); 313 dtp = new ServerDTP( this );
310 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) ); 314 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) );
311 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) ); 315 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) );
312 connect( dtp, SIGNAL( error( int ) ), SLOT( dtpError( int ) ) ); 316 connect( dtp, SIGNAL( error( int ) ), SLOT( dtpError( int ) ) );
313 317
314 318
315 directory = QDir::currentDirPath(); 319 directory = QDir::currentDirPath();
316 320
317 static int p = 1024; 321 static int p = 1024;
318 322
319 while ( !serversocket || !serversocket->ok() ) { 323 while ( !serversocket || !serversocket->ok() ) {
320 delete serversocket; 324 delete serversocket;
321 serversocket = new ServerSocket( ++p, this ); 325 serversocket = new ServerSocket( ++p, this );
322 } 326 }
323 connect( serversocket, SIGNAL( newIncomming( int ) ), 327 connect( serversocket, SIGNAL( newIncomming( int ) ),
324 SLOT( newConnection( int ) ) ); 328 SLOT( newConnection( int ) ) );
325 } 329 }
326} 330}
327 331
328ServerPI::~ServerPI() 332ServerPI::~ServerPI()
329{ 333{
330 close(); 334 close();
331 dtp->close(); 335 dtp->close();
332 delete dtp; 336 delete dtp;
333 delete serversocket; 337 delete serversocket;
334} 338}
335 339
336bool ServerPI::verifyAuthorised() 340bool ServerPI::verifyAuthorised()
337{ 341{
338 if ( !SyncAuthentication::isAuthorized(peerAddress()) ) { 342 if ( !SyncAuthentication::isAuthorized(peerAddress()) ) {
339 state = Forbidden; 343 state = Forbidden;
340 return FALSE; 344 return FALSE;
341 } 345 }
342 return TRUE; 346 return TRUE;
343} 347}
344 348
345void ServerPI::connectionClosed() 349void ServerPI::connectionClosed()
346{ 350{
347 // qDebug( "Debug: Connection closed" ); 351 // qDebug( "Debug: Connection closed" );
348 emit connectionClosed(this); 352 emit connectionClosed(this);
349} 353}
350 354
351void ServerPI::send( const QString& msg ) 355void ServerPI::send( const QString& msg )
352{ 356{
353 QTextStream os( this ); 357 QTextStream os( this );
354 os << msg << endl; 358 os << msg << endl;
355 //qDebug( "Reply: %s", msg.latin1() ); 359 //qDebug( "Reply: %s", msg.latin1() );
356} 360}
357 361
358void ServerPI::read() 362void ServerPI::read()
359{ 363{
360 while ( canReadLine() ) 364 while ( canReadLine() )
361 process( readLine().stripWhiteSpace() ); 365 process( readLine().stripWhiteSpace() );
362} 366}
363 367
364bool ServerPI::checkReadFile( const QString& file ) 368bool ServerPI::checkReadFile( const QString& file )
365{ 369{
366 QString filename; 370 QString filename;
367 371
368 if ( file[0] != "/" ) 372 if ( file[0] != "/" )
369 filename = directory.path() + "/" + file; 373 filename = directory.path() + "/" + file;
370 else 374 else
371 filename = file; 375 filename = file;
372 376
373 QFileInfo fi( filename ); 377 QFileInfo fi( filename );
374 return ( fi.exists() && fi.isReadable() ); 378 return ( fi.exists() && fi.isReadable() );
375} 379}
376 380
377bool ServerPI::checkWriteFile( const QString& file ) 381bool ServerPI::checkWriteFile( const QString& file )
378{ 382{
379 QString filename; 383 QString filename;
380 384
381 if ( file[0] != "/" ) 385 if ( file[0] != "/" )
382 filename = directory.path() + "/" + file; 386 filename = directory.path() + "/" + file;
383 else 387 else
384 filename = file; 388 filename = file;
385 389
386 QFileInfo fi( filename ); 390 QFileInfo fi( filename );
387 391
388 if ( fi.exists() ) 392 if ( fi.exists() )
389 if ( !QFile( filename ).remove() ) 393 if ( !QFile( filename ).remove() )
390 return FALSE; 394 return FALSE;
391 return TRUE; 395 return TRUE;
392} 396}
393 397
394void ServerPI::process( const QString& message ) 398void ServerPI::process( const QString& message )
395{ 399{
396 //qDebug( "Command: %s", message.latin1() ); 400 //qDebug( "Command: %s", message.latin1() );
397 401
398 // split message using "," as separator 402 // split message using "," as separator
399 QStringList msg = QStringList::split( " ", message ); 403 QStringList msg = QStringList::split( " ", message );
400 if ( msg.isEmpty() ) return; 404 if ( msg.isEmpty() ) return;
401 405
402 // command token 406 // command token
403 QString cmd = msg[0].upper(); 407 QString cmd = msg[0].upper();
404 408
405 // argument token 409 // argument token
406 QString arg; 410 QString arg;
407 if ( msg.count() >= 2 ) 411 if ( msg.count() >= 2 )
408 arg = msg[1]; 412 arg = msg[1];
409 413
410 // full argument string 414 // full argument string
411 QString args; 415 QString args;
412 if ( msg.count() >= 2 ) { 416 if ( msg.count() >= 2 ) {
413 QStringList copy( msg ); 417 QStringList copy( msg );
414 // FIXME: for Qt3 418 // FIXME: for Qt3
415 // copy.pop_front() 419 // copy.pop_front()
416 copy.remove( copy.begin() ); 420 copy.remove( copy.begin() );
417 args = copy.join( " " ); 421 args = copy.join( " " );
418 } 422 }
419 423
420 //qDebug( "args: %s", args.latin1() ); 424 //qDebug( "args: %s", args.latin1() );
421 425
422 // we always respond to QUIT, regardless of state 426 // we always respond to QUIT, regardless of state
423 if ( cmd == "QUIT" ) { 427 if ( cmd == "QUIT" ) {
424 send( "211 Good bye!" ); // No tr 428 send( "211 Good bye!" ); // No tr
425 close(); 429 close();
426 return; 430 return;
427 } 431 }
428 432
429 // connected to client 433 // connected to client
430 if ( Connected == state ) 434 if ( Connected == state )
431 return; 435 return;
432 436
433 // waiting for user name 437 // waiting for user name
434 if ( Wait_USER == state ) { 438 if ( Wait_USER == state ) {
435 439
436 if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { 440 if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) {
437 send( "530 Please login with USER and PASS" ); // No tr 441 send( "530 Please login with USER and PASS" ); // No tr
438 return; 442 return;
439 } 443 }
440 send( "331 User name ok, need password" ); // No tr 444 send( "331 User name ok, need password" ); // No tr
441 state = Wait_PASS; 445 state = Wait_PASS;
442 return; 446 return;
443 } 447 }
444 448
445 // waiting for password 449 // waiting for password
446 if ( Wait_PASS == state ) { 450 if ( Wait_PASS == state ) {
447 451
448 if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { 452 if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) {
449 send( "530 Please login with USER and PASS" ); // No tr 453 send( "530 Please login with USER and PASS" ); // No tr
450 return; 454 return;
451 } 455 }
452 send( "230 User logged in, proceed" ); // No tr 456 send( "230 User logged in, proceed" ); // No tr
453 state = Ready; 457 state = Ready;
454 return; 458 return;
455 } 459 }
456 460
457 // ACCESS CONTROL COMMANDS 461 // ACCESS CONTROL COMMANDS
458 462
459 // Only an ALLO sent immediately before STOR is valid. 463 // Only an ALLO sent immediately before STOR is valid.
460 if ( cmd != "STOR" ) 464 if ( cmd != "STOR" )
461 storFileSize = -1; 465 storFileSize = -1;
462 466
463 // account (ACCT) 467 // account (ACCT)
464 if ( cmd == "ACCT" ) { 468 if ( cmd == "ACCT" ) {
465 // even wu-ftp does not support it 469 // even wu-ftp does not support it
466 send( "502 Command not implemented" ); // No tr 470 send( "502 Command not implemented" ); // No tr
467 } 471 }
468 472
469 // change working directory (CWD) 473 // change working directory (CWD)
470 else if ( cmd == "CWD" ) { 474 else if ( cmd == "CWD" ) {
471 475
472 if ( !args.isEmpty() ) { 476 if ( !args.isEmpty() ) {
473 if ( directory.cd( args, TRUE ) ) 477 if ( directory.cd( args, TRUE ) )
474 send( "250 Requested file action okay, completed" ); // No tr 478 send( "250 Requested file action okay, completed" ); // No tr
475 else 479 else
476 send( "550 Requested action not taken" ); // No tr 480 send( "550 Requested action not taken" ); // No tr
477 } 481 }
478 else 482 else
479 send( "500 Syntax error, command unrecognized" ); // No tr 483 send( "500 Syntax error, command unrecognized" ); // No tr
480 } 484 }
481 485
482 // change to parent directory (CDUP) 486 // change to parent directory (CDUP)
483 else if ( cmd == "CDUP" ) { 487 else if ( cmd == "CDUP" ) {
484 if ( directory.cdUp() ) 488 if ( directory.cdUp() )
485 send( "250 Requested file action okay, completed" ); // No tr 489 send( "250 Requested file action okay, completed" ); // No tr
486 else 490 else
487 send( "550 Requested action not taken" ); // No tr 491 send( "550 Requested action not taken" ); // No tr
488 } 492 }
489 493
490 // structure mount (SMNT) 494 // structure mount (SMNT)
491 else if ( cmd == "SMNT" ) { 495 else if ( cmd == "SMNT" ) {
492 // even wu-ftp does not support it 496 // even wu-ftp does not support it
493 send( "502 Command not implemented" ); // No tr 497 send( "502 Command not implemented" ); // No tr
494 } 498 }
495 499
496 // reinitialize (REIN) 500 // reinitialize (REIN)
497 else if ( cmd == "REIN" ) { 501 else if ( cmd == "REIN" ) {
498 // even wu-ftp does not support it 502 // even wu-ftp does not support it
499 send( "502 Command not implemented" ); // No tr 503 send( "502 Command not implemented" ); // No tr
500 } 504 }
501 505
502 506
503 // TRANSFER PARAMETER COMMANDS 507 // TRANSFER PARAMETER COMMANDS
504 508
505 509
506 // data port (PORT) 510 // data port (PORT)
507 else if ( cmd == "PORT" ) { 511 else if ( cmd == "PORT" ) {
508 if ( parsePort( arg ) ) 512 if ( parsePort( arg ) )
509 send( "200 Command okay" ); // No tr 513 send( "200 Command okay" ); // No tr
510 else 514 else
511 send( "500 Syntax error, command unrecognized" ); // No tr 515 send( "500 Syntax error, command unrecognized" ); // No tr
512 } 516 }
513 517
514 // passive (PASV) 518 // passive (PASV)
515 else if ( cmd == "PASV" ) { 519 else if ( cmd == "PASV" ) {
516 passiv = TRUE; 520 passiv = TRUE;
517 send( "227 Entering Passive Mode (" // No tr 521 send( "227 Entering Passive Mode (" // No tr
518 + address().toString().replace( QRegExp( "\\." ), "," ) + "," 522 + address().toString().replace( QRegExp( "\\." ), "," ) + ","
519 + QString::number( ( serversocket->port() ) >> 8 ) + "," 523 + QString::number( ( serversocket->port() ) >> 8 ) + ","
520 + QString::number( ( serversocket->port() ) & 0xFF ) +")" ); 524 + QString::number( ( serversocket->port() ) & 0xFF ) +")" );
521 } 525 }
522 526
523 // representation type (TYPE) 527 // representation type (TYPE)
524 else if ( cmd == "TYPE" ) { 528 else if ( cmd == "TYPE" ) {
525 if ( arg.upper() == "A" || arg.upper() == "I" ) 529 if ( arg.upper() == "A" || arg.upper() == "I" )
526 send( "200 Command okay" ); // No tr 530 send( "200 Command okay" ); // No tr
527 else 531 else
528 send( "504 Command not implemented for that parameter" ); // No tr 532 send( "504 Command not implemented for that parameter" ); // No tr
529 } 533 }
530 534
531 // file structure (STRU) 535 // file structure (STRU)
532 else if ( cmd == "STRU" ) { 536 else if ( cmd == "STRU" ) {
533 if ( arg.upper() == "F" ) 537 if ( arg.upper() == "F" )
534 send( "200 Command okay" ); // No tr 538 send( "200 Command okay" ); // No tr
535 else 539 else
536 send( "504 Command not implemented for that parameter" ); // No tr 540 send( "504 Command not implemented for that parameter" ); // No tr
537 } 541 }
538 542
539 // transfer mode (MODE) 543 // transfer mode (MODE)
540 else if ( cmd == "MODE" ) { 544 else if ( cmd == "MODE" ) {
541 if ( arg.upper() == "S" ) 545 if ( arg.upper() == "S" )
542 send( "200 Command okay" ); // No tr 546 send( "200 Command okay" ); // No tr
543 else 547 else
544 send( "504 Command not implemented for that parameter" ); // No tr 548 send( "504 Command not implemented for that parameter" ); // No tr
545 } 549 }
546 550
547 551
548 // FTP SERVICE COMMANDS 552 // FTP SERVICE COMMANDS
549 553
550 554
551 // retrieve (RETR) 555 // retrieve (RETR)
552 else if ( cmd == "RETR" ) 556 else if ( cmd == "RETR" )
553 if ( !args.isEmpty() && checkReadFile( absFilePath( args ) ) 557 if ( !args.isEmpty() && checkReadFile( absFilePath( args ) )
554 || backupRestoreGzip( absFilePath( args ) ) ) { 558 || backupRestoreGzip( absFilePath( args ) ) ) {
555 send( "150 File status okay" ); // No tr 559 send( "150 File status okay" ); // No tr
556 sendFile( absFilePath( args ) ); 560 sendFile( absFilePath( args ) );
557 } 561 }
558 else { 562 else {
559 qDebug("550 Requested action not taken"); 563 qDebug("550 Requested action not taken");
560 send( "550 Requested action not taken" ); // No tr 564 send( "550 Requested action not taken" ); // No tr
561 } 565 }
562 566
563 // store (STOR) 567 // store (STOR)
564 else if ( cmd == "STOR" ) 568 else if ( cmd == "STOR" )
565 if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) { 569 if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) {
566 send( "150 File status okay" ); // No tr 570 send( "150 File status okay" ); // No tr
567 retrieveFile( absFilePath( args ) ); 571 retrieveFile( absFilePath( args ) );
568 } 572 }
569 else 573 else
570 send( "550 Requested action not taken" ); // No tr 574 send( "550 Requested action not taken" ); // No tr
571 575
572 // store unique (STOU) 576 // store unique (STOU)
573 else if ( cmd == "STOU" ) { 577 else if ( cmd == "STOU" ) {
574 send( "502 Command not implemented" ); // No tr 578 send( "502 Command not implemented" ); // No tr
575 } 579 }
576 580
577 // append (APPE) 581 // append (APPE)
578 else if ( cmd == "APPE" ) { 582 else if ( cmd == "APPE" ) {
579 send( "502 Command not implemented" ); // No tr 583 send( "502 Command not implemented" ); // No tr
580 } 584 }
581 585
582 // allocate (ALLO) 586 // allocate (ALLO)
583 else if ( cmd == "ALLO" ) { 587 else if ( cmd == "ALLO" ) {
584 storFileSize = args.toInt(); 588 storFileSize = args.toInt();
585 send( "200 Command okay" ); // No tr 589 send( "200 Command okay" ); // No tr
586 } 590 }
587 591
588 // restart (REST) 592 // restart (REST)
589 else if ( cmd == "REST" ) { 593 else if ( cmd == "REST" ) {
590 send( "502 Command not implemented" ); // No tr 594 send( "502 Command not implemented" ); // No tr
591 } 595 }
592 596
593 // rename from (RNFR) 597 // rename from (RNFR)
594 else if ( cmd == "RNFR" ) { 598 else if ( cmd == "RNFR" ) {
595 renameFrom = QString::null; 599 renameFrom = QString::null;
596 if ( args.isEmpty() ) 600 if ( args.isEmpty() )
597 send( "500 Syntax error, command unrecognized" ); // No tr 601 send( "500 Syntax error, command unrecognized" ); // No tr
598 else { 602 else {
599 QFile file( absFilePath( args ) ); 603 QFile file( absFilePath( args ) );
600 if ( file.exists() ) { 604 if ( file.exists() ) {
601 send( "350 File exists, ready for destination name" ); // No tr 605 send( "350 File exists, ready for destination name" ); // No tr
602 renameFrom = absFilePath( args ); 606 renameFrom = absFilePath( args );
603 } 607 }
604 else 608 else
605 send( "550 Requested action not taken" ); // No tr 609 send( "550 Requested action not taken" ); // No tr
606 } 610 }
607 } 611 }
608 612
609 // rename to (RNTO) 613 // rename to (RNTO)
610 else if ( cmd == "RNTO" ) { 614 else if ( cmd == "RNTO" ) {
611 if ( lastCommand != "RNFR" ) 615 if ( lastCommand != "RNFR" )
612 send( "503 Bad sequence of commands" ); // No tr 616 send( "503 Bad sequence of commands" ); // No tr
613 else if ( args.isEmpty() ) 617 else if ( args.isEmpty() )
614 send( "500 Syntax error, command unrecognized" ); // No tr 618 send( "500 Syntax error, command unrecognized" ); // No tr
615 else { 619 else {
616 QDir dir( absFilePath( args ) ); 620 QDir dir( absFilePath( args ) );
617 if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) ) 621 if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) )
618 send( "250 Requested file action okay, completed." ); // No tr 622 send( "250 Requested file action okay, completed." ); // No tr
619 else 623 else
620 send( "550 Requested action not taken" ); // No tr 624 send( "550 Requested action not taken" ); // No tr
621 } 625 }
622 } 626 }
623 627
624 // abort (ABOR) 628 // abort (ABOR)
625 else if ( cmd.contains( "ABOR" ) ) { 629 else if ( cmd.contains( "ABOR" ) ) {
626 dtp->close(); 630 dtp->close();
627 if ( dtp->dtpMode() != ServerDTP::Idle ) 631 if ( dtp->dtpMode() != ServerDTP::Idle )
628 send( "426 Connection closed; transfer aborted" ); // No tr 632 send( "426 Connection closed; transfer aborted" ); // No tr
629 else 633 else
630 send( "226 Closing data connection" ); // No tr 634 send( "226 Closing data connection" ); // No tr
631 } 635 }
632 636
633 // delete (DELE) 637 // delete (DELE)
634 else if ( cmd == "DELE" ) { 638 else if ( cmd == "DELE" ) {
635 if ( args.isEmpty() ) 639 if ( args.isEmpty() )
636 send( "500 Syntax error, command unrecognized" ); // No tr 640 send( "500 Syntax error, command unrecognized" ); // No tr
637 else { 641 else {
638 QFile file( absFilePath( args ) ) ; 642 QFile file( absFilePath( args ) ) ;
639 if ( file.remove() ) { 643 if ( file.remove() ) {
640 send( "250 Requested file action okay, completed" ); // No tr 644 send( "250 Requested file action okay, completed" ); // No tr
641 QCopEnvelope e("QPE/System", "linkChanged(QString)" ); 645 QCopEnvelope e("QPE/System", "linkChanged(QString)" );
642 e << file.name(); 646 e << file.name();
643 } else { 647 } else {
644 send( "550 Requested action not taken" ); // No tr 648 send( "550 Requested action not taken" ); // No tr
645 } 649 }
646 } 650 }
647 } 651 }
648 652
649 // remove directory (RMD) 653 // remove directory (RMD)
650 else if ( cmd == "RMD" ) { 654 else if ( cmd == "RMD" ) {
651 if ( args.isEmpty() ) 655 if ( args.isEmpty() )
652 send( "500 Syntax error, command unrecognized" ); // No tr 656 send( "500 Syntax error, command unrecognized" ); // No tr
653 else { 657 else {
654 QDir dir; 658 QDir dir;
655 if ( dir.rmdir( absFilePath( args ), TRUE ) ) 659 if ( dir.rmdir( absFilePath( args ), TRUE ) )
656 send( "250 Requested file action okay, completed" ); // No tr 660 send( "250 Requested file action okay, completed" ); // No tr
657 else 661 else
658 send( "550 Requested action not taken" ); // No tr 662 send( "550 Requested action not taken" ); // No tr
659 } 663 }
660 } 664 }
661 665
662 // make directory (MKD) 666 // make directory (MKD)
663 else if ( cmd == "MKD" ) { 667 else if ( cmd == "MKD" ) {
664 if ( args.isEmpty() ) { 668 if ( args.isEmpty() ) {
665 qDebug(" Error: no arg"); 669 qDebug(" Error: no arg");
666 send( "500 Syntax error, command unrecognized" ); // No tr 670 send( "500 Syntax error, command unrecognized" ); // No tr
667 } 671 }
668 else { 672 else {
669 QDir dir; 673 QDir dir;
670 if ( dir.mkdir( absFilePath( args ), TRUE ) ) 674 if ( dir.mkdir( absFilePath( args ), TRUE ) )
671 send( "250 Requested file action okay, completed." ); // No tr 675 send( "250 Requested file action okay, completed." ); // No tr
672 else 676 else
673 send( "550 Requested action not taken" ); // No tr 677 send( "550 Requested action not taken" ); // No tr
674 } 678 }
675 } 679 }
676 680
677 // print working directory (PWD) 681 // print working directory (PWD)
678 else if ( cmd == "PWD" ) { 682 else if ( cmd == "PWD" ) {
679 send( "257 \"" + directory.path() +"\"" ); 683 send( "257 \"" + directory.path() +"\"" );
680 } 684 }
681 685
682 // list (LIST) 686 // list (LIST)
683 else if ( cmd == "LIST" ) { 687 else if ( cmd == "LIST" ) {
684 if ( sendList( absFilePath( args ) ) ) 688 if ( sendList( absFilePath( args ) ) )
685 send( "150 File status okay" ); // No tr 689 send( "150 File status okay" ); // No tr
686 else 690 else
687 send( "500 Syntax error, command unrecognized" ); // No tr 691 send( "500 Syntax error, command unrecognized" ); // No tr
688 } 692 }
689 693
690 // size (SIZE) 694 // size (SIZE)
691 else if ( cmd == "SIZE" ) { 695 else if ( cmd == "SIZE" ) {
692 QString filePath = absFilePath( args ); 696 QString filePath = absFilePath( args );
693 QFileInfo fi( filePath ); 697 QFileInfo fi( filePath );
694 bool gzipfile = backupRestoreGzip( filePath ); 698 bool gzipfile = backupRestoreGzip( filePath );
695 if ( !fi.exists() && !gzipfile ) 699 if ( !fi.exists() && !gzipfile )
696 send( "500 Syntax error, command unrecognized" ); // No tr 700 send( "500 Syntax error, command unrecognized" ); // No tr
697 else { 701 else {
698 if ( !gzipfile ) 702 if ( !gzipfile )
699 send( "213 " + QString::number( fi.size() ) ); 703 send( "213 " + QString::number( fi.size() ) );
700 else { 704 else {
701 Process duproc( QString("du") ); 705 Process duproc( QString("du") );
702 duproc.addArgument("-s"); 706 duproc.addArgument("-s");
703 QString in, out; 707 QString in, out;
704 if ( !duproc.exec(in, out) ) { 708 if ( !duproc.exec(in, out) ) {
705 qDebug("du process failed; just sending back 1K"); 709 qDebug("du process failed; just sending back 1K");
706 send( "213 1024"); 710 send( "213 1024");
707 } 711 }
708 else { 712 else {
709 QString size = out.left( out.find("\t") ); 713 QString size = out.left( out.find("\t") );
710 int guess = size.toInt()/5; 714 int guess = size.toInt()/5;
711 if ( filePath.contains("doc") ) // No tr 715 if ( filePath.contains("doc") ) // No tr
712 guess *= 1000; 716 guess *= 1000;
713 qDebug("sending back gzip guess of %d", guess); 717 qDebug("sending back gzip guess of %d", guess);
714 send( "213 " + QString::number(guess) ); 718 send( "213 " + QString::number(guess) );
715 } 719 }
716 } 720 }
717 } 721 }
718 } 722 }
719 // name list (NLST) 723 // name list (NLST)
720 else if ( cmd == "NLST" ) { 724 else if ( cmd == "NLST" ) {
721 send( "502 Command not implemented" ); // No tr 725 send( "502 Command not implemented" ); // No tr
722 } 726 }
723 727
724 // site parameters (SITE) 728 // site parameters (SITE)
725 else if ( cmd == "SITE" ) { 729 else if ( cmd == "SITE" ) {
726 send( "502 Command not implemented" ); // No tr 730 send( "502 Command not implemented" ); // No tr
727 } 731 }
728 732
729 // system (SYST) 733 // system (SYST)
730 else if ( cmd == "SYST" ) { 734 else if ( cmd == "SYST" ) {
731 send( "215 UNIX Type: L8" ); // No tr 735 send( "215 UNIX Type: L8" ); // No tr
732 } 736 }
733 737
734 // status (STAT) 738 // status (STAT)
735 else if ( cmd == "STAT" ) { 739 else if ( cmd == "STAT" ) {
736 send( "502 Command not implemented" ); // No tr 740 send( "502 Command not implemented" ); // No tr
737 } 741 }
738 742
739 // help (HELP ) 743 // help (HELP )
740 else if ( cmd == "HELP" ) { 744 else if ( cmd == "HELP" ) {
741 send( "502 Command not implemented" ); // No tr 745 send( "502 Command not implemented" ); // No tr
742 } 746 }
743 747
744 // noop (NOOP) 748 // noop (NOOP)
745 else if ( cmd == "NOOP" ) { 749 else if ( cmd == "NOOP" ) {
746 send( "200 Command okay" ); // No tr 750 send( "200 Command okay" ); // No tr
747 } 751 }
748 752
749 // not implemented 753 // not implemented
750 else 754 else
751 send( "502 Command not implemented" ); // No tr 755 send( "502 Command not implemented" ); // No tr
752 756
753 lastCommand = cmd; 757 lastCommand = cmd;
754} 758}
755 759
756bool ServerPI::backupRestoreGzip( const QString &file ) 760bool ServerPI::backupRestoreGzip( const QString &file )
757{ 761{
758 return (file.find( "backup" ) != -1 && // No tr 762 return (file.find( "backup" ) != -1 && // No tr
759 file.findRev( ".tgz" ) == (int)file.length()-4 ); 763 file.findRev( ".tgz" ) == (int)file.length()-4 );
760} 764}
761 765
762bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets ) 766bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets )
763{ 767{
764 if ( file.find( "backup" ) != -1 && // No tr 768 if ( file.find( "backup" ) != -1 && // No tr
765 file.findRev( ".tgz" ) == (int)file.length()-4 ) { 769 file.findRev( ".tgz" ) == (int)file.length()-4 ) {
766 QFileInfo info( file ); 770 QFileInfo info( file );
767 targets = info.dirPath( TRUE ); 771 targets = info.dirPath( TRUE );
768 qDebug("ServerPI::backupRestoreGzip for %s = %s", file.latin1(), 772 qDebug("ServerPI::backupRestoreGzip for %s = %s", file.latin1(),
769 targets.join(" ").latin1() ); 773 targets.join(" ").latin1() );
770 return true; 774 return true;
771 } 775 }
772 return false; 776 return false;
773} 777}
774 778
775void ServerPI::sendFile( const QString& file ) 779void ServerPI::sendFile( const QString& file )
776{ 780{
777 if ( passiv ) { 781 if ( passiv ) {
778 wait[SendFile] = TRUE; 782 wait[SendFile] = TRUE;
779 waitfile = file; 783 waitfile = file;
780 if ( waitsocket ) 784 if ( waitsocket )
781 newConnection( waitsocket ); 785 newConnection( waitsocket );
782 } 786 }
783 else { 787 else {
784 QStringList targets; 788 QStringList targets;
785 if ( backupRestoreGzip( file, targets ) ) 789 if ( backupRestoreGzip( file, targets ) )
786 dtp->sendGzipFile( file, targets, peeraddress, peerport ); 790 dtp->sendGzipFile( file, targets, peeraddress, peerport );
787 else dtp->sendFile( file, peeraddress, peerport ); 791 else dtp->sendFile( file, peeraddress, peerport );
788 } 792 }
789} 793}
790 794
791void ServerPI::retrieveFile( const QString& file ) 795void ServerPI::retrieveFile( const QString& file )
792{ 796{
793 if ( passiv ) { 797 if ( passiv ) {
794 wait[RetrieveFile] = TRUE; 798 wait[RetrieveFile] = TRUE;
795 waitfile = file; 799 waitfile = file;
796 if ( waitsocket ) 800 if ( waitsocket )
797 newConnection( waitsocket ); 801 newConnection( waitsocket );
798 } 802 }
799 else { 803 else {
800 QStringList targets; 804 QStringList targets;
801 if ( backupRestoreGzip( file, targets ) ) 805 if ( backupRestoreGzip( file, targets ) )
802 dtp->retrieveGzipFile( file, peeraddress, peerport ); 806 dtp->retrieveGzipFile( file, peeraddress, peerport );
803 else 807 else
804 dtp->retrieveFile( file, peeraddress, peerport, storFileSize ); 808 dtp->retrieveFile( file, peeraddress, peerport, storFileSize );
805 } 809 }
806} 810}
807 811
808bool ServerPI::parsePort( const QString& pp ) 812bool ServerPI::parsePort( const QString& pp )
809{ 813{
810 QStringList p = QStringList::split( ",", pp ); 814 QStringList p = QStringList::split( ",", pp );
811 if ( p.count() != 6 ) return FALSE; 815 if ( p.count() != 6 ) return FALSE;
812 816
813 // h1,h2,h3,h4,p1,p2 817 // h1,h2,h3,h4,p1,p2
814 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) + 818 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) +
815 ( p[2].toInt() << 8 ) + p[3].toInt() ); 819 ( p[2].toInt() << 8 ) + p[3].toInt() );
816 peerport = ( p[4].toInt() << 8 ) + p[5].toInt(); 820 peerport = ( p[4].toInt() << 8 ) + p[5].toInt();
817 return TRUE; 821 return TRUE;
818} 822}
819 823
820void ServerPI::dtpCompleted() 824void ServerPI::dtpCompleted()
821{ 825{
822 send( "226 Closing data connection, file transfer successful" ); // No tr 826 send( "226 Closing data connection, file transfer successful" ); // No tr
823 if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) { 827 if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) {
824 QString fn = dtp->fileName(); 828 QString fn = dtp->fileName();
825 if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) { 829 if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) {
826 QCopEnvelope e("QPE/System", "linkChanged(QString)" ); 830 QCopEnvelope e("QPE/System", "linkChanged(QString)" );
827 e << fn; 831 e << fn;
828 } 832 }
829 } 833 }
830 waitsocket = 0; 834 waitsocket = 0;
831 dtp->close(); 835 dtp->close();
832 storFileSize = -1; 836 storFileSize = -1;
833} 837}
834 838
835void ServerPI::dtpFailed() 839void ServerPI::dtpFailed()
836{ 840{
837 dtp->close(); 841 dtp->close();
838 waitsocket = 0; 842 waitsocket = 0;
839 send( "451 Requested action aborted: local error in processing" ); // No tr 843 send( "451 Requested action aborted: local error in processing" ); // No tr
840 storFileSize = -1; 844 storFileSize = -1;
841} 845}
842 846
843void ServerPI::dtpError( int ) 847void ServerPI::dtpError( int )
844{ 848{
845 dtp->close(); 849 dtp->close();
846 waitsocket = 0; 850 waitsocket = 0;
847 send( "451 Requested action aborted: local error in processing" ); // No tr 851 send( "451 Requested action aborted: local error in processing" ); // No tr
848 storFileSize = -1; 852 storFileSize = -1;
849} 853}
850 854
851bool ServerPI::sendList( const QString& arg ) 855bool ServerPI::sendList( const QString& arg )
852{ 856{
853 QByteArray listing; 857 QByteArray listing;
854 QBuffer buffer( listing ); 858 QBuffer buffer( listing );
855 859
856 if ( !buffer.open( IO_WriteOnly ) ) 860 if ( !buffer.open( IO_WriteOnly ) )
857 return FALSE; 861 return FALSE;
858 862
859 QTextStream ts( &buffer ); 863 QTextStream ts( &buffer );
860 QString fn = arg; 864 QString fn = arg;
861 865
862 if ( fn.isEmpty() ) 866 if ( fn.isEmpty() )
863 fn = directory.path(); 867 fn = directory.path();
864 868
865 QFileInfo fi( fn ); 869 QFileInfo fi( fn );
866 if ( !fi.exists() ) return FALSE; 870 if ( !fi.exists() ) return FALSE;
867 871
868 // return file listing 872 // return file listing
869 if ( fi.isFile() ) { 873 if ( fi.isFile() ) {
870 ts << fileListing( &fi ) << endl; 874 ts << fileListing( &fi ) << endl;
871 } 875 }
872 876
873 // return directory listing 877 // return directory listing
874 else if ( fi.isDir() ) { 878 else if ( fi.isDir() ) {
875 QDir dir( fn ); 879 QDir dir( fn );
876 const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden ); 880 const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden );
877 881
878 QFileInfoListIterator it( *list ); 882 QFileInfoListIterator it( *list );
879 QFileInfo *info; 883 QFileInfo *info;
880 884
881 unsigned long total = 0; 885 unsigned long total = 0;
882 while ( ( info = it.current() ) ) { 886 while ( ( info = it.current() ) ) {
883 if ( info->fileName() != "." && info->fileName() != ".." ) 887 if ( info->fileName() != "." && info->fileName() != ".." )
884 total += info->size(); 888 total += info->size();
885 ++it; 889 ++it;
886 } 890 }
887 891
888 ts << "total " << QString::number( total / 1024 ) << endl; // No tr 892 ts << "total " << QString::number( total / 1024 ) << endl; // No tr
889 893
890 it.toFirst(); 894 it.toFirst();
891 while ( ( info = it.current() ) ) { 895 while ( ( info = it.current() ) ) {
892 if ( info->fileName() == "." || info->fileName() == ".." ) { 896 if ( info->fileName() == "." || info->fileName() == ".." ) {
893 ++it; 897 ++it;
894 continue; 898 continue;
895 } 899 }
896 ts << fileListing( info ) << endl; 900 ts << fileListing( info ) << endl;
897 ++it; 901 ++it;
898 } 902 }
899 } 903 }
900 904
901 if ( passiv ) { 905 if ( passiv ) {
902 waitarray = buffer.buffer(); 906 waitarray = buffer.buffer();
903 wait[SendByteArray] = TRUE; 907 wait[SendByteArray] = TRUE;
904 if ( waitsocket ) 908 if ( waitsocket )
905 newConnection( waitsocket ); 909 newConnection( waitsocket );
906 } 910 }
907 else 911 else
908 dtp->sendByteArray( buffer.buffer(), peeraddress, peerport ); 912 dtp->sendByteArray( buffer.buffer(), peeraddress, peerport );
909 return TRUE; 913 return TRUE;
910} 914}
911 915
912QString ServerPI::fileListing( QFileInfo *info ) 916QString ServerPI::fileListing( QFileInfo *info )
913{ 917{
914 if ( !info ) return QString::null; 918 if ( !info ) return QString::null;
915 QString s; 919 QString s;
916 920
917 // type char 921 // type char
918 if ( info->isDir() ) 922 if ( info->isDir() )
919 s += "d"; 923 s += "d";
920 else if ( info->isSymLink() ) 924 else if ( info->isSymLink() )
921 s += "l"; 925 s += "l";
922 else 926 else
923 s += "-"; 927 s += "-";
924 928
925 // permisson string 929 // permisson string
926 s += permissionString( info ) + " "; 930 s += permissionString( info ) + " ";
927 931
928 // number of hardlinks 932 // number of hardlinks
929 int subdirs = 1; 933 int subdirs = 1;
930 934
931 if ( info->isDir() ) 935 if ( info->isDir() )
932 subdirs = 2; 936 subdirs = 2;
933 // FIXME : this is to slow 937 // FIXME : this is to slow
934 //if ( info->isDir() ) 938 //if ( info->isDir() )
935 //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count(); 939 //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count();
936 940
937 s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " "; 941 s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " ";
938 942
939 // owner 943 // owner
940 QString o = info->owner(); 944 QString o = info->owner();
941 if ( o.isEmpty() ) 945 if ( o.isEmpty() )
942 o = QString::number(info->ownerId()); 946 o = QString::number(info->ownerId());
943 s += o.leftJustify( 8, ' ', TRUE ) + " "; 947 s += o.leftJustify( 8, ' ', TRUE ) + " ";
944 948
945 // group 949 // group
946 QString g = info->group(); 950 QString g = info->group();
947 if ( g.isEmpty() ) 951 if ( g.isEmpty() )
948 g = QString::number(info->groupId()); 952 g = QString::number(info->groupId());
949 s += g.leftJustify( 8, ' ', TRUE ) + " "; 953 s += g.leftJustify( 8, ' ', TRUE ) + " ";
950 954
951 // file size in bytes 955 // file size in bytes
952 s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " "; 956 s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " ";
953 957
954 // last modified date 958 // last modified date
955 QDate date = info->lastModified().date(); 959 QDate date = info->lastModified().date();
956 QTime time = info->lastModified().time(); 960 QTime time = info->lastModified().time();
957 s += date.monthName( date.month() ) + " " 961 s += date.monthName( date.month() ) + " "
958 + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " " 962 + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " "
959 + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":" 963 + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":"
960 + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " "; 964 + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " ";
961 965
962 // file name 966 // file name
963 s += info->fileName(); 967 s += info->fileName();
964 968
965 return s; 969 return s;
966} 970}
967 971
968QString ServerPI::permissionString( QFileInfo *info ) 972QString ServerPI::permissionString( QFileInfo *info )
969{ 973{
970 if ( !info ) return QString( "---------" ); 974 if ( !info ) return QString( "---------" );
971 QString s; 975 QString s;
972 976
973 // user 977 // user
974 if ( info->permission( QFileInfo::ReadUser ) ) s += "r"; 978 if ( info->permission( QFileInfo::ReadUser ) ) s += "r";
975 else s += "-"; 979 else s += "-";
976 if ( info->permission( QFileInfo::WriteUser ) ) s += "w"; 980 if ( info->permission( QFileInfo::WriteUser ) ) s += "w";
977 else s += "-"; 981 else s += "-";
978 if ( info->permission( QFileInfo::ExeUser ) ) s += "x"; 982 if ( info->permission( QFileInfo::ExeUser ) ) s += "x";
979 else s += "-"; 983 else s += "-";
980 984
981 // group 985 // group
982 if ( info->permission( QFileInfo::ReadGroup ) ) s += "r"; 986 if ( info->permission( QFileInfo::ReadGroup ) ) s += "r";
983 else s += "-"; 987 else s += "-";
984 if ( info->permission( QFileInfo::WriteGroup ) )s += "w"; 988 if ( info->permission( QFileInfo::WriteGroup ) )s += "w";
985 else s += "-"; 989 else s += "-";
986 if ( info->permission( QFileInfo::ExeGroup ) ) s += "x"; 990 if ( info->permission( QFileInfo::ExeGroup ) ) s += "x";
987 else s += "-"; 991 else s += "-";
988 992
989 // exec 993 // exec
990 if ( info->permission( QFileInfo::ReadOther ) ) s += "r"; 994 if ( info->permission( QFileInfo::ReadOther ) ) s += "r";
991 else s += "-"; 995 else s += "-";
992 if ( info->permission( QFileInfo::WriteOther ) ) s += "w"; 996 if ( info->permission( QFileInfo::WriteOther ) ) s += "w";
993 else s += "-"; 997 else s += "-";
994 if ( info->permission( QFileInfo::ExeOther ) ) s += "x"; 998 if ( info->permission( QFileInfo::ExeOther ) ) s += "x";
995 else s += "-"; 999 else s += "-";
996 1000
997 return s; 1001 return s;
998} 1002}
999 1003
1000void ServerPI::newConnection( int socket ) 1004void ServerPI::newConnection( int socket )
1001{ 1005{
1002 //qDebug( "New incomming connection" ); 1006 //qDebug( "New incomming connection" );
1003 1007
1004 if ( !passiv ) return; 1008 if ( !passiv ) return;
1005 1009
1006 if ( wait[SendFile] ) { 1010 if ( wait[SendFile] ) {
1007 QStringList targets; 1011 QStringList targets;
1008 if ( backupRestoreGzip( waitfile, targets ) ) 1012 if ( backupRestoreGzip( waitfile, targets ) )
1009 dtp->sendGzipFile( waitfile, targets ); 1013 dtp->sendGzipFile( waitfile, targets );
1010 else 1014 else
1011 dtp->sendFile( waitfile ); 1015 dtp->sendFile( waitfile );
1012 dtp->setSocket( socket ); 1016 dtp->setSocket( socket );
1013 } 1017 }
1014 else if ( wait[RetrieveFile] ) { 1018 else if ( wait[RetrieveFile] ) {
1015 qDebug("check retrieve file"); 1019 qDebug("check retrieve file");
1016 if ( backupRestoreGzip( waitfile ) ) 1020 if ( backupRestoreGzip( waitfile ) )
1017 dtp->retrieveGzipFile( waitfile ); 1021 dtp->retrieveGzipFile( waitfile );
1018 else 1022 else
1019 dtp->retrieveFile( waitfile, storFileSize ); 1023 dtp->retrieveFile( waitfile, storFileSize );
1020 dtp->setSocket( socket ); 1024 dtp->setSocket( socket );
1021 } 1025 }
1022 else if ( wait[SendByteArray] ) { 1026 else if ( wait[SendByteArray] ) {
1023 dtp->sendByteArray( waitarray ); 1027 dtp->sendByteArray( waitarray );
1024 dtp->setSocket( socket ); 1028 dtp->setSocket( socket );
1025 } 1029 }
1026 else if ( wait[RetrieveByteArray] ) { 1030 else if ( wait[RetrieveByteArray] ) {
1027 qDebug("retrieve byte array"); 1031 qDebug("retrieve byte array");
1028 dtp->retrieveByteArray(); 1032 dtp->retrieveByteArray();
1029 dtp->setSocket( socket ); 1033 dtp->setSocket( socket );
1030 } 1034 }
1031 else 1035 else
1032 waitsocket = socket; 1036 waitsocket = socket;
1033 1037
1034 for( int i = 0; i < 4; i++ ) 1038 for( int i = 0; i < 4; i++ )
1035 wait[i] = FALSE; 1039 wait[i] = FALSE;
1036} 1040}
1037 1041
1038QString ServerPI::absFilePath( const QString& file ) 1042QString ServerPI::absFilePath( const QString& file )
1039{ 1043{
1040 if ( file.isEmpty() ) return file; 1044 if ( file.isEmpty() ) return file;
1041 1045
1042 QString filepath( file ); 1046 QString filepath( file );
1043 if ( file[0] != "/" ) 1047 if ( file[0] != "/" )
1044 filepath = directory.path() + "/" + file; 1048 filepath = directory.path() + "/" + file;
1045 1049
1046 return filepath; 1050 return filepath;
1047} 1051}
1048 1052
1049 1053
1050void ServerPI::timerEvent( QTimerEvent * ) 1054void ServerPI::timerEvent( QTimerEvent * )
1051{ 1055{
1052 connectionClosed(); 1056 connectionClosed();
1053} 1057}
1054 1058
1055 1059
1056ServerDTP::ServerDTP( QObject *parent, const char* name) 1060ServerDTP::ServerDTP( QObject *parent, const char* name)
1057 : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ), 1061 : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ),
1058 retrieveTargzProc( 0 ) 1062 retrieveTargzProc( 0 )
1059{ 1063{
1060 1064
1061 connect( this, SIGNAL( connected() ), SLOT( connected() ) ); 1065 connect( this, SIGNAL( connected() ), SLOT( connected() ) );
1062 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 1066 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
1063 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) ); 1067 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) );
1064 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) ); 1068 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) );
1065 1069
1066 createTargzProc = new QProcess( QString("tar"), this, "createTargzProc"); // No tr 1070 createTargzProc = new QProcess( QString("tar"), this, "createTargzProc"); // No tr
1067 createTargzProc->setCommunication( QProcess::Stdout ); 1071 createTargzProc->setCommunication( QProcess::Stdout );
1068 createTargzProc->setWorkingDirectory( QDir::rootDirPath() ); 1072 createTargzProc->setWorkingDirectory( QDir::rootDirPath() );
1069 connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) ); 1073 connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) );
1070 1074
1071 retrieveTargzProc = new QProcess( this, "retrieveTargzProc" ); 1075 retrieveTargzProc = new QProcess( this, "retrieveTargzProc" );
1072 retrieveTargzProc->setCommunication( QProcess::Stdin ); 1076 retrieveTargzProc->setCommunication( QProcess::Stdin );
1073 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() ); 1077 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() );
1074 connect( retrieveTargzProc, SIGNAL( processExited() ), 1078 connect( retrieveTargzProc, SIGNAL( processExited() ),
1075 SIGNAL( completed() ) ); 1079 SIGNAL( completed() ) );
1076 connect( retrieveTargzProc, SIGNAL( processExited() ), 1080 connect( retrieveTargzProc, SIGNAL( processExited() ),
1077 SLOT( extractTarDone() ) ); 1081 SLOT( extractTarDone() ) );
1078} 1082}
1079 1083
1080ServerDTP::~ServerDTP() 1084ServerDTP::~ServerDTP()
1081{ 1085{
1082 buf.close(); 1086 buf.close();
1083 if ( RetrieveFile == mode && file.isOpen() ) { 1087 if ( RetrieveFile == mode && file.isOpen() ) {
1084 // We're being shutdown before the client closed. 1088 // We're being shutdown before the client closed.
1085 file.close(); 1089 file.close();
1086 if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { 1090 if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) {
1087 qDebug( "STOR incomplete" ); 1091 qDebug( "STOR incomplete" );
1088 file.remove(); 1092 file.remove();
1089 } 1093 }
1090 } else { 1094 } else {
1091 file.close(); 1095 file.close();
1092 } 1096 }
1093 createTargzProc->kill(); 1097 createTargzProc->kill();
1094} 1098}
1095 1099
1096void ServerDTP::extractTarDone() 1100void ServerDTP::extractTarDone()
1097{ 1101{
1098 qDebug("extract done"); 1102 qDebug("extract done");
1099#ifndef QT_NO_COP 1103#ifndef QT_NO_COP
1100 QCopEnvelope e( "QPE/System", "restoreDone(QString)" ); 1104 QCopEnvelope e( "QPE/System", "restoreDone(QString)" );
1101 e << file.name(); 1105 e << file.name();
1102#endif 1106#endif
1103} 1107}
1104 1108
1105void ServerDTP::connected() 1109void ServerDTP::connected()
1106{ 1110{
1107 // send file mode 1111 // send file mode
1108 switch ( mode ) { 1112 switch ( mode ) {
1109 case SendFile : 1113 case SendFile :
1110 if ( !file.exists() || !file.open( IO_ReadOnly) ) { 1114 if ( !file.exists() || !file.open( IO_ReadOnly) ) {
1111 emit failed(); 1115 emit failed();
1112 mode = Idle; 1116 mode = Idle;
1113 return; 1117 return;
1114 } 1118 }
1115 1119
1116 //qDebug( "Debug: Sending file '%s'", file.name().latin1() ); 1120 //qDebug( "Debug: Sending file '%s'", file.name().latin1() );
1117 1121
1118 bytes_written = 0; 1122 bytes_written = 0;
1119 if ( file.size() == 0 ) { 1123 if ( file.size() == 0 ) {
1120 //make sure it doesn't hang on empty files 1124 //make sure it doesn't hang on empty files
1121 file.close(); 1125 file.close();
1122 emit completed(); 1126 emit completed();
1123 mode = Idle; 1127 mode = Idle;
1124 } else { 1128 } else {
1125 // Don't write more if there is plenty buffered already. 1129 // Don't write more if there is plenty buffered already.
1126 if ( bytesToWrite() <= block_size && !file.atEnd() ) { 1130 if ( bytesToWrite() <= block_size && !file.atEnd() ) {
1127 QCString s; 1131 QCString s;
1128 s.resize( block_size ); 1132 s.resize( block_size );
1129 int bytes = file.readBlock( s.data(), block_size ); 1133 int bytes = file.readBlock( s.data(), block_size );
1130 writeBlock( s.data(), bytes ); 1134 writeBlock( s.data(), bytes );
1131 } 1135 }
1132 } 1136 }
1133 break; 1137 break;
1134 case SendGzipFile: 1138 case SendGzipFile:
1135 if ( createTargzProc->isRunning() ) { 1139 if ( createTargzProc->isRunning() ) {
1136 // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY 1140 // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY
1137 qWarning("Previous tar --gzip process is still running; killing it..."); 1141 qWarning("Previous tar --gzip process is still running; killing it...");
1138 createTargzProc->kill(); 1142 createTargzProc->kill();
1139 } 1143 }
1140 1144
1141 bytes_written = 0; 1145 bytes_written = 0;
1142 qDebug("==>start send tar process"); 1146 qDebug("==>start send tar process");
1143 if ( !createTargzProc->start() ) 1147 if ( !createTargzProc->start() )
1144 qWarning("Error starting %s", 1148 qWarning("Error starting %s",
1145 createTargzProc->arguments().join(" ").latin1()); 1149 createTargzProc->arguments().join(" ").latin1());
1146 break; 1150 break;
1147 case SendBuffer: 1151 case SendBuffer:
1148 if ( !buf.open( IO_ReadOnly) ) { 1152 if ( !buf.open( IO_ReadOnly) ) {
1149 emit failed(); 1153 emit failed();
1150 mode = Idle; 1154 mode = Idle;
1151 return; 1155 return;
1152 } 1156 }
1153 1157
1154 // qDebug( "Debug: Sending byte array" ); 1158 // qDebug( "Debug: Sending byte array" );
1155 bytes_written = 0; 1159 bytes_written = 0;
1156 while( !buf.atEnd() ) 1160 while( !buf.atEnd() )
1157 putch( buf.getch() ); 1161 putch( buf.getch() );
1158 buf.close(); 1162 buf.close();
1159 break; 1163 break;
1160 case RetrieveFile: 1164 case RetrieveFile:
1161 // retrieve file mode 1165 // retrieve file mode
1162 if ( file.exists() && !file.remove() ) { 1166 if ( file.exists() && !file.remove() ) {
1163 emit failed(); 1167 emit failed();
1164 mode = Idle; 1168 mode = Idle;
1165 return; 1169 return;
1166 } 1170 }
1167 1171
1168 if ( !file.open( IO_WriteOnly) ) { 1172 if ( !file.open( IO_WriteOnly) ) {
1169 emit failed(); 1173 emit failed();
1170 mode = Idle; 1174 mode = Idle;
1171 return; 1175 return;
1172 } 1176 }
1173 // qDebug( "Debug: Retrieving file %s", file.name().latin1() ); 1177 // qDebug( "Debug: Retrieving file %s", file.name().latin1() );
1174 break; 1178 break;
1175 case RetrieveGzipFile: 1179 case RetrieveGzipFile:
1176 qDebug("=-> starting tar process to receive .tgz file"); 1180 qDebug("=-> starting tar process to receive .tgz file");
1177 break; 1181 break;
1178 case RetrieveBuffer: 1182 case RetrieveBuffer:
1179 // retrieve buffer mode 1183 // retrieve buffer mode
1180 if ( !buf.open( IO_WriteOnly) ) { 1184 if ( !buf.open( IO_WriteOnly) ) {
1181 emit failed(); 1185 emit failed();
1182 mode = Idle; 1186 mode = Idle;
1183 return; 1187 return;
1184 } 1188 }
1185 // qDebug( "Debug: Retrieving byte array" ); 1189 // qDebug( "Debug: Retrieving byte array" );
1186 break; 1190 break;
1187 case Idle: 1191 case Idle:
1188 qDebug("connection established but mode set to Idle; BUG!"); 1192 qDebug("connection established but mode set to Idle; BUG!");
1189 break; 1193 break;
1190 } 1194 }
1191} 1195}
1192 1196
1193void ServerDTP::connectionClosed() 1197void ServerDTP::connectionClosed()
1194{ 1198{
1195 //qDebug( "Debug: Data connection closed %ld bytes written", bytes_written ); 1199 //qDebug( "Debug: Data connection closed %ld bytes written", bytes_written );
1196 1200
1197 // send file mode 1201 // send file mode
1198 if ( SendFile == mode ) { 1202 if ( SendFile == mode ) {
1199 if ( bytes_written == file.size() ) 1203 if ( bytes_written == file.size() )
1200 emit completed(); 1204 emit completed();
1201 else 1205 else
1202 emit failed(); 1206 emit failed();
1203 } 1207 }
1204 1208
1205 // send buffer mode 1209 // send buffer mode
1206 else if ( SendBuffer == mode ) { 1210 else if ( SendBuffer == mode ) {
1207 if ( bytes_written == buf.size() ) 1211 if ( bytes_written == buf.size() )
1208 emit completed(); 1212 emit completed();
1209 else 1213 else
1210 emit failed(); 1214 emit failed();
1211 } 1215 }
1212 1216
1213 // retrieve file mode 1217 // retrieve file mode
1214 else if ( RetrieveFile == mode ) { 1218 else if ( RetrieveFile == mode ) {
1215 file.close(); 1219 file.close();
1216 if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) { 1220 if ( recvFileSize >= 0 && (int)file.size() != recvFileSize ) {
1217 qDebug( "STOR incomplete" ); 1221 qDebug( "STOR incomplete" );
1218 file.remove(); 1222 file.remove();
1219 emit failed(); 1223 emit failed();
1220 } else { 1224 } else {
1221 emit completed(); 1225 emit completed();
1222 } 1226 }
1223 } 1227 }
1224 1228
1225 else if ( RetrieveGzipFile == mode ) { 1229 else if ( RetrieveGzipFile == mode ) {
1226 qDebug("Done writing ungzip file; closing input"); 1230 qDebug("Done writing ungzip file; closing input");
1227 retrieveTargzProc->flushStdin(); 1231 retrieveTargzProc->flushStdin();
1228 retrieveTargzProc->closeStdin(); 1232 retrieveTargzProc->closeStdin();
1229 } 1233 }
1230 1234
1231 // retrieve buffer mode 1235 // retrieve buffer mode
1232 else if ( RetrieveBuffer == mode ) { 1236 else if ( RetrieveBuffer == mode ) {
1233 buf.close(); 1237 buf.close();
1234 emit completed(); 1238 emit completed();
1235 } 1239 }
1236 1240
1237 mode = Idle; 1241 mode = Idle;
1238} 1242}
1239 1243
1240void ServerDTP::bytesWritten( int bytes ) 1244void ServerDTP::bytesWritten( int bytes )
1241{ 1245{
1242 bytes_written += bytes; 1246 bytes_written += bytes;
1243 1247
1244 // send file mode 1248 // send file mode
1245 if ( SendFile == mode ) { 1249 if ( SendFile == mode ) {
1246 1250
1247 if ( bytes_written == file.size() ) { 1251 if ( bytes_written == file.size() ) {
1248 // qDebug( "Debug: Sending complete: %d bytes", file.size() ); 1252 // qDebug( "Debug: Sending complete: %d bytes", file.size() );
1249 file.close(); 1253 file.close();
1250 emit completed(); 1254 emit completed();
1251 mode = Idle; 1255 mode = Idle;
1252 } 1256 }
1253 else if( !file.atEnd() ) { 1257 else if( !file.atEnd() ) {
1254 QCString s; 1258 QCString s;
1255 s.resize( block_size ); 1259 s.resize( block_size );
1256 int bytes = file.readBlock( s.data(), block_size ); 1260 int bytes = file.readBlock( s.data(), block_size );
1257 writeBlock( s.data(), bytes ); 1261 writeBlock( s.data(), bytes );
1258 } 1262 }
1259 } 1263 }
1260 1264
1261 // send buffer mode 1265 // send buffer mode
1262 if ( SendBuffer == mode ) { 1266 if ( SendBuffer == mode ) {
1263 1267
1264 if ( bytes_written == buf.size() ) { 1268 if ( bytes_written == buf.size() ) {
1265 // qDebug( "Debug: Sending complete: %d bytes", buf.size() ); 1269 // qDebug( "Debug: Sending complete: %d bytes", buf.size() );
1266 emit completed(); 1270 emit completed();
1267 mode = Idle; 1271 mode = Idle;
1268 } 1272 }
1269 } 1273 }
1270} 1274}
1271 1275
1272void ServerDTP::readyRead() 1276void ServerDTP::readyRead()
1273{ 1277{
1274 // retrieve file mode 1278 // retrieve file mode
1275 if ( RetrieveFile == mode ) { 1279 if ( RetrieveFile == mode ) {
1276 QCString s; 1280 QCString s;
1277 s.resize( bytesAvailable() ); 1281 s.resize( bytesAvailable() );
1278 readBlock( s.data(), bytesAvailable() ); 1282 readBlock( s.data(), bytesAvailable() );
1279 file.writeBlock( s.data(), s.size() ); 1283 file.writeBlock( s.data(), s.size() );
1280 } 1284 }
1281 else if ( RetrieveGzipFile == mode ) { 1285 else if ( RetrieveGzipFile == mode ) {
1282 if ( !retrieveTargzProc->isRunning() ) 1286 if ( !retrieveTargzProc->isRunning() )
1283 retrieveTargzProc->start(); 1287 retrieveTargzProc->start();
1284 1288
1285 QByteArray s; 1289 QByteArray s;
1286 s.resize( bytesAvailable() ); 1290 s.resize( bytesAvailable() );
1287 readBlock( s.data(), bytesAvailable() ); 1291 readBlock( s.data(), bytesAvailable() );
1288 retrieveTargzProc->writeToStdin( s ); 1292 retrieveTargzProc->writeToStdin( s );
1289 qDebug("wrote %d bytes to ungzip ", s.size() ); 1293 qDebug("wrote %d bytes to ungzip ", s.size() );
1290 } 1294 }
1291 // retrieve buffer mode 1295 // retrieve buffer mode
1292 else if ( RetrieveBuffer == mode ) { 1296 else if ( RetrieveBuffer == mode ) {
1293 QCString s; 1297 QCString s;
1294 s.resize( bytesAvailable() ); 1298 s.resize( bytesAvailable() );
1295 readBlock( s.data(), bytesAvailable() ); 1299 readBlock( s.data(), bytesAvailable() );
1296 buf.writeBlock( s.data(), s.size() ); 1300 buf.writeBlock( s.data(), s.size() );
1297 } 1301 }
1298} 1302}
1299 1303
1300void ServerDTP::writeTargzBlock() 1304void ServerDTP::writeTargzBlock()
1301{ 1305{
1302 QByteArray block = createTargzProc->readStdout(); 1306 QByteArray block = createTargzProc->readStdout();
1303 writeBlock( block.data(), block.size() ); 1307 writeBlock( block.data(), block.size() );
1304 qDebug("writeTargzBlock %d", block.size()); 1308 qDebug("writeTargzBlock %d", block.size());
1305} 1309}
1306 1310
1307void ServerDTP::targzDone() 1311void ServerDTP::targzDone()
1308{ 1312{
1309 qDebug("tar and gzip done"); 1313 qDebug("tar and gzip done");
1310 emit completed(); 1314 emit completed();
1311 mode = Idle; 1315 mode = Idle;
1312 disconnect( createTargzProc, SIGNAL( readyReadStdout() ), 1316 disconnect( createTargzProc, SIGNAL( readyReadStdout() ),
1313 this, SLOT( writeTargzBlock() ) ); 1317 this, SLOT( writeTargzBlock() ) );
1314} 1318}
1315 1319
1316void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port ) 1320void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port )
1317{ 1321{
1318 file.setName( fn ); 1322 file.setName( fn );
1319 mode = SendFile; 1323 mode = SendFile;
1320 connectToHost( host.toString(), port ); 1324 connectToHost( host.toString(), port );
1321} 1325}
1322 1326
1323void ServerDTP::sendFile( const QString fn ) 1327void ServerDTP::sendFile( const QString fn )
1324{ 1328{
1325 file.setName( fn ); 1329 file.setName( fn );
1326 mode = SendFile; 1330 mode = SendFile;
1327} 1331}
1328 1332
1329void ServerDTP::sendGzipFile( const QString &fn, 1333void ServerDTP::sendGzipFile( const QString &fn,
1330 const QStringList &archiveTargets, 1334 const QStringList &archiveTargets,
1331 const QHostAddress& host, Q_UINT16 port ) 1335 const QHostAddress& host, Q_UINT16 port )
1332{ 1336{
1333 sendGzipFile( fn, archiveTargets ); 1337 sendGzipFile( fn, archiveTargets );
1334 connectToHost( host.toString(), port ); 1338 connectToHost( host.toString(), port );
1335} 1339}
1336 1340
1337void ServerDTP::sendGzipFile( const QString &fn, 1341void ServerDTP::sendGzipFile( const QString &fn,
1338 const QStringList &archiveTargets ) 1342 const QStringList &archiveTargets )
1339{ 1343{
1340 mode = SendGzipFile; 1344 mode = SendGzipFile;
1341 file.setName( fn ); 1345 file.setName( fn );
1342 1346
1343 QStringList args = "targzip"; 1347 QStringList args = "targzip";
1344 //args += "-cv"; 1348 //args += "-cv";
1345 args += archiveTargets; 1349 args += archiveTargets;
1346 qDebug("sendGzipFile %s", args.join(" ").latin1() ); 1350 qDebug("sendGzipFile %s", args.join(" ").latin1() );
1347 createTargzProc->setArguments( args ); 1351 createTargzProc->setArguments( args );
1348 connect( createTargzProc, 1352 connect( createTargzProc,
1349 SIGNAL( readyReadStdout() ), SLOT( writeTargzBlock() ) ); 1353 SIGNAL( readyReadStdout() ), SLOT( writeTargzBlock() ) );
1350} 1354}
1351 1355
1352void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port, int fileSize ) 1356void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port, int fileSize )
1353{ 1357{
1354 recvFileSize = fileSize; 1358 recvFileSize = fileSize;
1355 file.setName( fn ); 1359 file.setName( fn );
1356 mode = RetrieveFile; 1360 mode = RetrieveFile;
1357 connectToHost( host.toString(), port ); 1361 connectToHost( host.toString(), port );
1358} 1362}
1359 1363
1360void ServerDTP::retrieveFile( const QString fn, int fileSize ) 1364void ServerDTP::retrieveFile( const QString fn, int fileSize )
1361{ 1365{
1362 recvFileSize = fileSize; 1366 recvFileSize = fileSize;
1363 file.setName( fn ); 1367 file.setName( fn );
1364 mode = RetrieveFile; 1368 mode = RetrieveFile;
1365} 1369}
1366 1370
1367void ServerDTP::retrieveGzipFile( const QString &fn ) 1371void ServerDTP::retrieveGzipFile( const QString &fn )
1368{ 1372{
1369 qDebug("retrieveGzipFile %s", fn.latin1()); 1373 qDebug("retrieveGzipFile %s", fn.latin1());
1370 file.setName( fn ); 1374 file.setName( fn );
1371 mode = RetrieveGzipFile; 1375 mode = RetrieveGzipFile;
1372 1376
1373 retrieveTargzProc->setArguments( "targunzip" ); 1377 retrieveTargzProc->setArguments( "targunzip" );
1374 connect( retrieveTargzProc, SIGNAL( processExited() ), 1378 connect( retrieveTargzProc, SIGNAL( processExited() ),
1375 SLOT( extractTarDone() ) ); 1379 SLOT( extractTarDone() ) );
1376} 1380}
1377 1381
1378void ServerDTP::retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port ) 1382void ServerDTP::retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port )
1379{ 1383{
1380 retrieveGzipFile( fn ); 1384 retrieveGzipFile( fn );
1381 connectToHost( host.toString(), port ); 1385 connectToHost( host.toString(), port );
1382} 1386}
1383 1387
1384void ServerDTP::sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port ) 1388void ServerDTP::sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port )
1385{ 1389{
1386 buf.setBuffer( array ); 1390 buf.setBuffer( array );
1387 mode = SendBuffer; 1391 mode = SendBuffer;
1388 connectToHost( host.toString(), port ); 1392 connectToHost( host.toString(), port );
1389} 1393}
1390 1394
1391void ServerDTP::sendByteArray( const QByteArray& array ) 1395void ServerDTP::sendByteArray( const QByteArray& array )
1392{ 1396{
1393 buf.setBuffer( array ); 1397 buf.setBuffer( array );
1394 mode = SendBuffer; 1398 mode = SendBuffer;
1395} 1399}
1396 1400
1397void ServerDTP::retrieveByteArray( const QHostAddress& host, Q_UINT16 port ) 1401void ServerDTP::retrieveByteArray( const QHostAddress& host, Q_UINT16 port )
1398{ 1402{
1399 buf.setBuffer( QByteArray() ); 1403 buf.setBuffer( QByteArray() );
1400 mode = RetrieveBuffer; 1404 mode = RetrieveBuffer;
1401 connectToHost( host.toString(), port ); 1405 connectToHost( host.toString(), port );
1402} 1406}
1403 1407
1404void ServerDTP::retrieveByteArray() 1408void ServerDTP::retrieveByteArray()
1405{ 1409{
1406 buf.setBuffer( QByteArray() ); 1410 buf.setBuffer( QByteArray() );
1407 mode = RetrieveBuffer; 1411 mode = RetrieveBuffer;
1408} 1412}
1409 1413
1410void ServerDTP::setSocket( int socket ) 1414void ServerDTP::setSocket( int socket )
1411{ 1415{
1412 QSocket::setSocket( socket ); 1416 QSocket::setSocket( socket );
1413 connected(); 1417 connected();
1414} 1418}
1415 1419