summaryrefslogtreecommitdiff
authorzecke <zecke>2002-10-04 21:16:03 (UTC)
committer zecke <zecke>2002-10-04 21:16:03 (UTC)
commit10048c2dd7f7cd26c582d64b5e255b00b47de304 (patch) (unidiff)
tree3b2a79d8218efe5f80d1b2e79e77b22cbc27c2ba
parentdc0344e987ba9b386056dd7bab7c5e34922eff5c (diff)
downloadopie-10048c2dd7f7cd26c582d64b5e255b00b47de304.zip
opie-10048c2dd7f7cd26c582d64b5e255b00b47de304.tar.gz
opie-10048c2dd7f7cd26c582d64b5e255b00b47de304.tar.bz2
Weird for some of you
_OS_LINUX_ does not get defined so now it's a if !define(_OS_LINUX) but this means you need to libuuid again I don't know how to fix that right. I should ask tt
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/transferserver.cpp14
1 files changed, 7 insertions, 7 deletions
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp
index a20df2f..f9204ab 100644
--- a/core/launcher/transferserver.cpp
+++ b/core/launcher/transferserver.cpp
@@ -1,1134 +1,1134 @@
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#include <pwd.h> 21#include <pwd.h>
22#include <sys/types.h> 22#include <sys/types.h>
23#include <unistd.h> 23#include <unistd.h>
24#include <stdlib.h> 24#include <stdlib.h>
25#include <time.h> 25#include <time.h>
26#include <shadow.h> 26#include <shadow.h>
27 27
28#ifndef _OS_LINUX_ 28#ifndef _OS_LINUX_
29 29
30extern "C" { 30extern "C" {
31#include <uuid/uuid.h> 31#include <uuid/uuid.h>
32#define UUID_H_INCLUDED 32#define UUID_H_INCLUDED
33} 33}
34 34
35#endif // not defined linux 35#endif // not defined linux
36 36
37#if defined(_OS_LINUX_) 37#if defined(_OS_LINUX_)
38#include <shadow.h> 38#include <shadow.h>
39#endif 39#endif
40 40
41#include <qdir.h> 41#include <qdir.h>
42#include <qfile.h> 42#include <qfile.h>
43#include <qtextstream.h> 43#include <qtextstream.h>
44#include <qdatastream.h> 44#include <qdatastream.h>
45#include <qmessagebox.h> 45#include <qmessagebox.h>
46#include <qstringlist.h> 46#include <qstringlist.h>
47#include <qfileinfo.h> 47#include <qfileinfo.h>
48#include <qregexp.h> 48#include <qregexp.h>
49//#include <qpe/qcopchannel_qws.h> 49//#include <qpe/qcopchannel_qws.h>
50#include <qpe/process.h> 50#include <qpe/process.h>
51#include <qpe/global.h> 51#include <qpe/global.h>
52#include <qpe/config.h> 52#include <qpe/config.h>
53#include <qpe/contact.h> 53#include <qpe/contact.h>
54#include <qpe/quuid.h> 54#include <qpe/quuid.h>
55#include <qpe/version.h> 55#include <qpe/version.h>
56#ifdef QWS 56#ifdef QWS
57#include <qpe/qcopenvelope_qws.h> 57#include <qpe/qcopenvelope_qws.h>
58#endif 58#endif
59 59
60#include "transferserver.h" 60#include "transferserver.h"
61#include "qprocess.h" 61#include "qprocess.h"
62 62
63const int block_size = 51200; 63const int block_size = 51200;
64 64
65TransferServer::TransferServer( Q_UINT16 port, QObject *parent , 65TransferServer::TransferServer( Q_UINT16 port, QObject *parent ,
66 const char* name ) 66 const char* name )
67 : QServerSocket( port, 1, parent, name ) 67 : QServerSocket( port, 1, parent, name )
68{ 68{
69 if ( !ok() ) 69 if ( !ok() )
70 qWarning( "Failed to bind to port %d", port ); 70 qWarning( "Failed to bind to port %d", port );
71} 71}
72 72
73TransferServer::~TransferServer() 73TransferServer::~TransferServer()
74{ 74{
75 75
76} 76}
77 77
78void TransferServer::newConnection( int socket ) 78void TransferServer::newConnection( int socket )
79{ 79{
80 (void) new ServerPI( socket, this ); 80 (void) new ServerPI( socket, this );
81} 81}
82 82
83/* 83/*
84 * small class in anonymous namespace 84 * small class in anonymous namespace
85 * to generate a QUUid for us 85 * to generate a QUUid for us
86 */ 86 */
87namespace { 87namespace {
88 struct UidGen { 88 struct UidGen {
89 QString uuid(); 89 QString uuid();
90 }; 90 };
91#if defined(_OS_LINUX_) 91#if !defined(_OS_LINUX_)
92 QString UidGen::uuid() {
93 uuid_t uuid;
94 uuid_generate( uuid );
95 return QUUid( uuid ).toString();
96 }
97#else
92 /* 98 /*
93 * linux got a /proc/sys/kernel/random/uuid file 99 * linux got a /proc/sys/kernel/random/uuid file
94 * it'll generate the uuids for us 100 * it'll generate the uuids for us
95 */ 101 */
96 QString UidGen::uuid() { 102 QString UidGen::uuid() {
97 QFile file( "/proc/sys/kernel/random/uuid" ); 103 QFile file( "/proc/sys/kernel/random/uuid" );
98 if (!file.open(IO_ReadOnly ) ) 104 if (!file.open(IO_ReadOnly ) )
99 return QString::null; 105 return QString::null;
100 106
101 QTextStream stream(&file); 107 QTextStream stream(&file);
102 108
103 return "{" + stream.read().stripWhiteSpace() + "}"; 109 return "{" + stream.read().stripWhiteSpace() + "}";
104 } 110 }
105#else
106 QString UidGen::uuid() {
107 uuid_t uuid;
108 uuid_generate( uuid );
109 return QUUid( uuid ).toString();
110 }
111#endif 111#endif
112} 112}
113 113
114QString SyncAuthentication::serverId() 114QString SyncAuthentication::serverId()
115{ 115{
116 Config cfg("Security"); 116 Config cfg("Security");
117 cfg.setGroup("Sync"); 117 cfg.setGroup("Sync");
118 QString r=cfg.readEntry("serverid"); 118 QString r=cfg.readEntry("serverid");
119 if ( r.isEmpty() ) { 119 if ( r.isEmpty() ) {
120 UidGen gen; 120 UidGen gen;
121 r = gen.uuid(); 121 r = gen.uuid();
122 cfg.writeEntry("serverid", r ); 122 cfg.writeEntry("serverid", r );
123 } 123 }
124 return r; 124 return r;
125} 125}
126 126
127QString SyncAuthentication::ownerName() 127QString SyncAuthentication::ownerName()
128{ 128{
129 QString vfilename = Global::applicationFileName("addressbook", 129 QString vfilename = Global::applicationFileName("addressbook",
130 "businesscard.vcf"); 130 "businesscard.vcf");
131 if (QFile::exists(vfilename)) { 131 if (QFile::exists(vfilename)) {
132 Contact c; 132 Contact c;
133 c = Contact::readVCard( vfilename )[0]; 133 c = Contact::readVCard( vfilename )[0];
134 return c.fullName(); 134 return c.fullName();
135 } 135 }
136 136
137 return ""; 137 return "";
138} 138}
139 139
140QString SyncAuthentication::loginName() 140QString SyncAuthentication::loginName()
141{ 141{
142 struct passwd *pw; 142 struct passwd *pw;
143 pw = getpwuid( geteuid() ); 143 pw = getpwuid( geteuid() );
144 return QString::fromLocal8Bit( pw->pw_name ); 144 return QString::fromLocal8Bit( pw->pw_name );
145} 145}
146 146
147int SyncAuthentication::isAuthorized(QHostAddress peeraddress) 147int SyncAuthentication::isAuthorized(QHostAddress peeraddress)
148{ 148{
149 Config cfg("Security"); 149 Config cfg("Security");
150 cfg.setGroup("Sync"); 150 cfg.setGroup("Sync");
151// QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0"); 151// QString allowedstr = cfg.readEntry("auth_peer","192.168.1.0");
152 uint auth_peer = cfg.readNumEntry("auth_peer",0xc0a80100); 152 uint auth_peer = cfg.readNumEntry("auth_peer",0xc0a80100);
153 153
154// QHostAddress allowed; 154// QHostAddress allowed;
155// allowed.setAddress(allowedstr); 155// allowed.setAddress(allowedstr);
156// uint auth_peer = allowed.ip4Addr(); 156// uint auth_peer = allowed.ip4Addr();
157 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24); 157 uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24);
158 uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined 158 uint mask = auth_peer_bits >= 32 // shifting by 32 is not defined
159 ? 0xffffffff : (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits)); 159 ? 0xffffffff : (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits));
160 return (peeraddress.ip4Addr() & mask) == auth_peer; 160 return (peeraddress.ip4Addr() & mask) == auth_peer;
161} 161}
162 162
163bool SyncAuthentication::checkUser( const QString& user ) 163bool SyncAuthentication::checkUser( const QString& user )
164{ 164{
165 if ( user.isEmpty() ) return FALSE; 165 if ( user.isEmpty() ) return FALSE;
166 QString euser = loginName(); 166 QString euser = loginName();
167 return user == euser; 167 return user == euser;
168} 168}
169 169
170bool SyncAuthentication::checkPassword( const QString& password ) 170bool SyncAuthentication::checkPassword( const QString& password )
171{ 171{
172#ifdef ALLOW_UNIX_USER_FTP 172#ifdef ALLOW_UNIX_USER_FTP
173 // First, check system password... 173 // First, check system password...
174 174
175 struct passwd *pw = 0; 175 struct passwd *pw = 0;
176 struct spwd *spw = 0; 176 struct spwd *spw = 0;
177 177
178 pw = getpwuid( geteuid() ); 178 pw = getpwuid( geteuid() );
179 spw = getspnam( pw->pw_name ); 179 spw = getspnam( pw->pw_name );
180 180
181 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd ); 181 QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
182 if ( cpwd == "x" && spw ) 182 if ( cpwd == "x" && spw )
183 cpwd = QString::fromLocal8Bit( spw->sp_pwdp ); 183 cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
184 184
185 // Note: some systems use more than crypt for passwords. 185 // Note: some systems use more than crypt for passwords.
186 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) ); 186 QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
187 if ( cpwd == cpassword ) 187 if ( cpwd == cpassword )
188 return TRUE; 188 return TRUE;
189#endif 189#endif
190 190
191 static int lastdenial=0; 191 static int lastdenial=0;
192 static int denials=0; 192 static int denials=0;
193 int now = time(0); 193 int now = time(0);
194 194
195 // Detect old Qtopia Desktop (no password) 195 // Detect old Qtopia Desktop (no password)
196 if ( password.isEmpty() ) { 196 if ( password.isEmpty() ) {
197 if ( denials < 1 || now > lastdenial+600 ) { 197 if ( denials < 1 || now > lastdenial+600 ) {
198 QMessageBox::warning( 0,tr("Sync Connection"), 198 QMessageBox::warning( 0,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 tr("Deny") ); 202 tr("Deny") );
203 denials++; 203 denials++;
204 lastdenial=now; 204 lastdenial=now;
205 } 205 }
206 return FALSE; 206 return FALSE;
207 } 207 }
208 208
209 // Second, check sync password... 209 // Second, check sync password...
210 QString pass = password.left(6); 210 QString pass = password.left(6);
211 /* old QtopiaDesktops are sending 211 /* old QtopiaDesktops are sending
212 * rootme newer versions got a Qtopia 212 * rootme newer versions got a Qtopia
213 * prefixed. Qtopia prefix will suceed 213 * prefixed. Qtopia prefix will suceed
214 * until the sync software syncs up 214 * until the sync software syncs up
215 * FIXME 215 * FIXME
216 */ 216 */
217 if ( pass == "rootme" || pass == "Qtopia") { 217 if ( pass == "rootme" || pass == "Qtopia") {
218 218
219 QString cpassword = QString::fromLocal8Bit( crypt( password.mid(8).local8Bit(), "qp" ) ); 219 QString cpassword = QString::fromLocal8Bit( crypt( password.mid(8).local8Bit(), "qp" ) );
220 Config cfg("Security"); 220 Config cfg("Security");
221 cfg.setGroup("Sync"); 221 cfg.setGroup("Sync");
222 QString pwds = cfg.readEntry("Passwords"); 222 QString pwds = cfg.readEntry("Passwords");
223 if ( QStringList::split(QChar(' '),pwds).contains(cpassword) ) 223 if ( QStringList::split(QChar(' '),pwds).contains(cpassword) )
224 return TRUE; 224 return TRUE;
225 225
226 // Unrecognized system. Be careful... 226 // Unrecognized system. Be careful...
227 227
228 if ( (denials > 2 && now < lastdenial+600) 228 if ( (denials > 2 && now < lastdenial+600)
229 || QMessageBox::warning(0,tr("Sync Connection"), 229 || QMessageBox::warning(0,tr("Sync Connection"),
230 tr("<p>An unrecognized system is requesting access to this device." 230 tr("<p>An unrecognized system is requesting access to this device."
231 "<p>If you have just initiated a Sync for the first time, this is normal."), 231 "<p>If you have just initiated a Sync for the first time, this is normal."),
232 tr("Allow"),tr("Deny"))==1 ) 232 tr("Allow"),tr("Deny"))==1 )
233 { 233 {
234 denials++; 234 denials++;
235 lastdenial=now; 235 lastdenial=now;
236 return FALSE; 236 return FALSE;
237 } else { 237 } else {
238 denials=0; 238 denials=0;
239 cfg.writeEntry("Passwords",pwds+" "+cpassword); 239 cfg.writeEntry("Passwords",pwds+" "+cpassword);
240 return TRUE; 240 return TRUE;
241 } 241 }
242 } 242 }
243 243
244 return FALSE; 244 return FALSE;
245} 245}
246 246
247ServerPI::ServerPI( int socket, QObject *parent , const char* name ) 247ServerPI::ServerPI( int socket, QObject *parent , const char* name )
248 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 ) 248 : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 )
249{ 249{
250 state = Connected; 250 state = Connected;
251 251
252 setSocket( socket ); 252 setSocket( socket );
253 253
254 peerport = peerPort(); 254 peerport = peerPort();
255 peeraddress = peerAddress(); 255 peeraddress = peerAddress();
256 256
257#ifndef INSECURE 257#ifndef INSECURE
258 if ( !SyncAuthentication::isAuthorized(peeraddress) ) { 258 if ( !SyncAuthentication::isAuthorized(peeraddress) ) {
259 state = Forbidden; 259 state = Forbidden;
260 startTimer( 0 ); 260 startTimer( 0 );
261 } else 261 } else
262#endif 262#endif
263 { 263 {
264 connect( this, SIGNAL( readyRead() ), SLOT( read() ) ); 264 connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
265 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 265 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
266 266
267 passiv = FALSE; 267 passiv = FALSE;
268 for( int i = 0; i < 4; i++ ) 268 for( int i = 0; i < 4; i++ )
269 wait[i] = FALSE; 269 wait[i] = FALSE;
270 270
271 send( "220 Qtopia " QPE_VERSION " FTP Server" ); 271 send( "220 Qtopia " QPE_VERSION " FTP Server" );
272 state = Wait_USER; 272 state = Wait_USER;
273 273
274 dtp = new ServerDTP( this ); 274 dtp = new ServerDTP( this );
275 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) ); 275 connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) );
276 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) ); 276 connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) );
277 connect( dtp, SIGNAL( error( int ) ), SLOT( dtpError( int ) ) ); 277 connect( dtp, SIGNAL( error( int ) ), SLOT( dtpError( int ) ) );
278 278
279 279
280 directory = QDir::currentDirPath(); 280 directory = QDir::currentDirPath();
281 281
282 static int p = 1024; 282 static int p = 1024;
283 283
284 while ( !serversocket || !serversocket->ok() ) { 284 while ( !serversocket || !serversocket->ok() ) {
285 delete serversocket; 285 delete serversocket;
286 serversocket = new ServerSocket( ++p, this ); 286 serversocket = new ServerSocket( ++p, this );
287 } 287 }
288 connect( serversocket, SIGNAL( newIncomming( int ) ), 288 connect( serversocket, SIGNAL( newIncomming( int ) ),
289 SLOT( newConnection( int ) ) ); 289 SLOT( newConnection( int ) ) );
290 } 290 }
291} 291}
292 292
293ServerPI::~ServerPI() 293ServerPI::~ServerPI()
294{ 294{
295 295
296} 296}
297 297
298void ServerPI::connectionClosed() 298void ServerPI::connectionClosed()
299{ 299{
300 // qDebug( "Debug: Connection closed" ); 300 // qDebug( "Debug: Connection closed" );
301 delete this; 301 delete this;
302} 302}
303 303
304void ServerPI::send( const QString& msg ) 304void ServerPI::send( const QString& msg )
305{ 305{
306 QTextStream os( this ); 306 QTextStream os( this );
307 os << msg << endl; 307 os << msg << endl;
308 //qDebug( "Reply: %s", msg.latin1() ); 308 //qDebug( "Reply: %s", msg.latin1() );
309} 309}
310 310
311void ServerPI::read() 311void ServerPI::read()
312{ 312{
313 while ( canReadLine() ) 313 while ( canReadLine() )
314 process( readLine().stripWhiteSpace() ); 314 process( readLine().stripWhiteSpace() );
315} 315}
316 316
317bool ServerPI::checkReadFile( const QString& file ) 317bool ServerPI::checkReadFile( const QString& file )
318{ 318{
319 QString filename; 319 QString filename;
320 320
321 if ( file[0] != "/" ) 321 if ( file[0] != "/" )
322 filename = directory.path() + "/" + file; 322 filename = directory.path() + "/" + file;
323 else 323 else
324 filename = file; 324 filename = file;
325 325
326 QFileInfo fi( filename ); 326 QFileInfo fi( filename );
327 return ( fi.exists() && fi.isReadable() ); 327 return ( fi.exists() && fi.isReadable() );
328} 328}
329 329
330bool ServerPI::checkWriteFile( const QString& file ) 330bool ServerPI::checkWriteFile( const QString& file )
331{ 331{
332 QString filename; 332 QString filename;
333 333
334 if ( file[0] != "/" ) 334 if ( file[0] != "/" )
335 filename = directory.path() + "/" + file; 335 filename = directory.path() + "/" + file;
336 else 336 else
337 filename = file; 337 filename = file;
338 338
339 QFileInfo fi( filename ); 339 QFileInfo fi( filename );
340 340
341 if ( fi.exists() ) 341 if ( fi.exists() )
342 if ( !QFile( filename ).remove() ) 342 if ( !QFile( filename ).remove() )
343 return FALSE; 343 return FALSE;
344 return TRUE; 344 return TRUE;
345} 345}
346 346
347void ServerPI::process( const QString& message ) 347void ServerPI::process( const QString& message )
348{ 348{
349 //qDebug( "Command: %s", message.latin1() ); 349 //qDebug( "Command: %s", message.latin1() );
350 350
351 // split message using "," as separator 351 // split message using "," as separator
352 QStringList msg = QStringList::split( " ", message ); 352 QStringList msg = QStringList::split( " ", message );
353 if ( msg.isEmpty() ) return; 353 if ( msg.isEmpty() ) return;
354 354
355 // command token 355 // command token
356 QString cmd = msg[0].upper(); 356 QString cmd = msg[0].upper();
357 357
358 // argument token 358 // argument token
359 QString arg; 359 QString arg;
360 if ( msg.count() >= 2 ) 360 if ( msg.count() >= 2 )
361 arg = msg[1]; 361 arg = msg[1];
362 362
363 // full argument string 363 // full argument string
364 QString args; 364 QString args;
365 if ( msg.count() >= 2 ) { 365 if ( msg.count() >= 2 ) {
366 QStringList copy( msg ); 366 QStringList copy( msg );
367 // FIXME: for Qt3 367 // FIXME: for Qt3
368 // copy.pop_front() 368 // copy.pop_front()
369 copy.remove( copy.begin() ); 369 copy.remove( copy.begin() );
370 args = copy.join( " " ); 370 args = copy.join( " " );
371 } 371 }
372 372
373 //qDebug( "args: %s", args.latin1() ); 373 //qDebug( "args: %s", args.latin1() );
374 374
375 // we always respond to QUIT, regardless of state 375 // we always respond to QUIT, regardless of state
376 if ( cmd == "QUIT" ) { 376 if ( cmd == "QUIT" ) {
377 send( "211 Good bye!" ); 377 send( "211 Good bye!" );
378 delete this; 378 delete this;
379 return; 379 return;
380 } 380 }
381 381
382 // connected to client 382 // connected to client
383 if ( Connected == state ) 383 if ( Connected == state )
384 return; 384 return;
385 385
386 // waiting for user name 386 // waiting for user name
387 if ( Wait_USER == state ) { 387 if ( Wait_USER == state ) {
388 388
389 if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) { 389 if ( cmd != "USER" || msg.count() < 2 || !SyncAuthentication::checkUser( arg ) ) {
390 send( "530 Please login with USER and PASS" ); 390 send( "530 Please login with USER and PASS" );
391 return; 391 return;
392 } 392 }
393 send( "331 User name ok, need password" ); 393 send( "331 User name ok, need password" );
394 state = Wait_PASS; 394 state = Wait_PASS;
395 return; 395 return;
396 } 396 }
397 397
398 // waiting for password 398 // waiting for password
399 if ( Wait_PASS == state ) { 399 if ( Wait_PASS == state ) {
400 400
401 if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) { 401 if ( cmd != "PASS" || !SyncAuthentication::checkPassword( arg ) ) {
402 send( "530 Please login with USER and PASS" ); 402 send( "530 Please login with USER and PASS" );
403 return; 403 return;
404 } 404 }
405 send( "230 User logged in, proceed" ); 405 send( "230 User logged in, proceed" );
406 state = Ready; 406 state = Ready;
407 return; 407 return;
408 } 408 }
409 409
410 // ACCESS CONTROL COMMANDS 410 // ACCESS CONTROL COMMANDS
411 411
412 412
413 // account (ACCT) 413 // account (ACCT)
414 if ( cmd == "ACCT" ) { 414 if ( cmd == "ACCT" ) {
415 // even wu-ftp does not support it 415 // even wu-ftp does not support it
416 send( "502 Command not implemented" ); 416 send( "502 Command not implemented" );
417 } 417 }
418 418
419 // change working directory (CWD) 419 // change working directory (CWD)
420 else if ( cmd == "CWD" ) { 420 else if ( cmd == "CWD" ) {
421 421
422 if ( !args.isEmpty() ) { 422 if ( !args.isEmpty() ) {
423 if ( directory.cd( args, TRUE ) ) 423 if ( directory.cd( args, TRUE ) )
424 send( "250 Requested file action okay, completed" ); 424 send( "250 Requested file action okay, completed" );
425 else 425 else
426 send( "550 Requested action not taken" ); 426 send( "550 Requested action not taken" );
427 } 427 }
428 else 428 else
429 send( "500 Syntax error, command unrecognized" ); 429 send( "500 Syntax error, command unrecognized" );
430 } 430 }
431 431
432 // change to parent directory (CDUP) 432 // change to parent directory (CDUP)
433 else if ( cmd == "CDUP" ) { 433 else if ( cmd == "CDUP" ) {
434 if ( directory.cdUp() ) 434 if ( directory.cdUp() )
435 send( "250 Requested file action okay, completed" ); 435 send( "250 Requested file action okay, completed" );
436 else 436 else
437 send( "550 Requested action not taken" ); 437 send( "550 Requested action not taken" );
438 } 438 }
439 439
440 // structure mount (SMNT) 440 // structure mount (SMNT)
441 else if ( cmd == "SMNT" ) { 441 else if ( cmd == "SMNT" ) {
442 // even wu-ftp does not support it 442 // even wu-ftp does not support it
443 send( "502 Command not implemented" ); 443 send( "502 Command not implemented" );
444 } 444 }
445 445
446 // reinitialize (REIN) 446 // reinitialize (REIN)
447 else if ( cmd == "REIN" ) { 447 else if ( cmd == "REIN" ) {
448 // even wu-ftp does not support it 448 // even wu-ftp does not support it
449 send( "502 Command not implemented" ); 449 send( "502 Command not implemented" );
450 } 450 }
451 451
452 452
453 // TRANSFER PARAMETER COMMANDS 453 // TRANSFER PARAMETER COMMANDS
454 454
455 455
456 // data port (PORT) 456 // data port (PORT)
457 else if ( cmd == "PORT" ) { 457 else if ( cmd == "PORT" ) {
458 if ( parsePort( arg ) ) 458 if ( parsePort( arg ) )
459 send( "200 Command okay" ); 459 send( "200 Command okay" );
460 else 460 else
461 send( "500 Syntax error, command unrecognized" ); 461 send( "500 Syntax error, command unrecognized" );
462 } 462 }
463 463
464 // passive (PASV) 464 // passive (PASV)
465 else if ( cmd == "PASV" ) { 465 else if ( cmd == "PASV" ) {
466 passiv = TRUE; 466 passiv = TRUE;
467 send( "227 Entering Passive Mode (" 467 send( "227 Entering Passive Mode ("
468 + address().toString().replace( QRegExp( "\\." ), "," ) + "," 468 + address().toString().replace( QRegExp( "\\." ), "," ) + ","
469 + QString::number( ( serversocket->port() ) >> 8 ) + "," 469 + QString::number( ( serversocket->port() ) >> 8 ) + ","
470 + QString::number( ( serversocket->port() ) & 0xFF ) +")" ); 470 + QString::number( ( serversocket->port() ) & 0xFF ) +")" );
471 } 471 }
472 472
473 // representation type (TYPE) 473 // representation type (TYPE)
474 else if ( cmd == "TYPE" ) { 474 else if ( cmd == "TYPE" ) {
475 if ( arg.upper() == "A" || arg.upper() == "I" ) 475 if ( arg.upper() == "A" || arg.upper() == "I" )
476 send( "200 Command okay" ); 476 send( "200 Command okay" );
477 else 477 else
478 send( "504 Command not implemented for that parameter" ); 478 send( "504 Command not implemented for that parameter" );
479 } 479 }
480 480
481 // file structure (STRU) 481 // file structure (STRU)
482 else if ( cmd == "STRU" ) { 482 else if ( cmd == "STRU" ) {
483 if ( arg.upper() == "F" ) 483 if ( arg.upper() == "F" )
484 send( "200 Command okay" ); 484 send( "200 Command okay" );
485 else 485 else
486 send( "504 Command not implemented for that parameter" ); 486 send( "504 Command not implemented for that parameter" );
487 } 487 }
488 488
489 // transfer mode (MODE) 489 // transfer mode (MODE)
490 else if ( cmd == "MODE" ) { 490 else if ( cmd == "MODE" ) {
491 if ( arg.upper() == "S" ) 491 if ( arg.upper() == "S" )
492 send( "200 Command okay" ); 492 send( "200 Command okay" );
493 else 493 else
494 send( "504 Command not implemented for that parameter" ); 494 send( "504 Command not implemented for that parameter" );
495 } 495 }
496 496
497 497
498 // FTP SERVICE COMMANDS 498 // FTP SERVICE COMMANDS
499 499
500 500
501 // retrieve (RETR) 501 // retrieve (RETR)
502 else if ( cmd == "RETR" ) 502 else if ( cmd == "RETR" )
503 if ( !args.isEmpty() && checkReadFile( absFilePath( args ) ) 503 if ( !args.isEmpty() && checkReadFile( absFilePath( args ) )
504 || backupRestoreGzip( absFilePath( args ) ) ) { 504 || backupRestoreGzip( absFilePath( args ) ) ) {
505 send( "150 File status okay" ); 505 send( "150 File status okay" );
506 sendFile( absFilePath( args ) ); 506 sendFile( absFilePath( args ) );
507 } 507 }
508 else { 508 else {
509 qDebug("550 Requested action not taken"); 509 qDebug("550 Requested action not taken");
510 send( "550 Requested action not taken" ); 510 send( "550 Requested action not taken" );
511 } 511 }
512 512
513 // store (STOR) 513 // store (STOR)
514 else if ( cmd == "STOR" ) 514 else if ( cmd == "STOR" )
515 if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) { 515 if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) {
516 send( "150 File status okay" ); 516 send( "150 File status okay" );
517 retrieveFile( absFilePath( args ) ); 517 retrieveFile( absFilePath( args ) );
518 } 518 }
519 else 519 else
520 send( "550 Requested action not taken" ); 520 send( "550 Requested action not taken" );
521 521
522 // store unique (STOU) 522 // store unique (STOU)
523 else if ( cmd == "STOU" ) { 523 else if ( cmd == "STOU" ) {
524 send( "502 Command not implemented" ); 524 send( "502 Command not implemented" );
525 } 525 }
526 526
527 // append (APPE) 527 // append (APPE)
528 else if ( cmd == "APPE" ) { 528 else if ( cmd == "APPE" ) {
529 send( "502 Command not implemented" ); 529 send( "502 Command not implemented" );
530 } 530 }
531 531
532 // allocate (ALLO) 532 // allocate (ALLO)
533 else if ( cmd == "ALLO" ) { 533 else if ( cmd == "ALLO" ) {
534 send( "200 Command okay" ); 534 send( "200 Command okay" );
535 } 535 }
536 536
537 // restart (REST) 537 // restart (REST)
538 else if ( cmd == "REST" ) { 538 else if ( cmd == "REST" ) {
539 send( "502 Command not implemented" ); 539 send( "502 Command not implemented" );
540 } 540 }
541 541
542 // rename from (RNFR) 542 // rename from (RNFR)
543 else if ( cmd == "RNFR" ) { 543 else if ( cmd == "RNFR" ) {
544 renameFrom = QString::null; 544 renameFrom = QString::null;
545 if ( args.isEmpty() ) 545 if ( args.isEmpty() )
546 send( "500 Syntax error, command unrecognized" ); 546 send( "500 Syntax error, command unrecognized" );
547 else { 547 else {
548 QFile file( absFilePath( args ) ); 548 QFile file( absFilePath( args ) );
549 if ( file.exists() ) { 549 if ( file.exists() ) {
550 send( "350 File exists, ready for destination name" ); 550 send( "350 File exists, ready for destination name" );
551 renameFrom = absFilePath( args ); 551 renameFrom = absFilePath( args );
552 } 552 }
553 else 553 else
554 send( "550 Requested action not taken" ); 554 send( "550 Requested action not taken" );
555 } 555 }
556 } 556 }
557 557
558 // rename to (RNTO) 558 // rename to (RNTO)
559 else if ( cmd == "RNTO" ) { 559 else if ( cmd == "RNTO" ) {
560 if ( lastCommand != "RNFR" ) 560 if ( lastCommand != "RNFR" )
561 send( "503 Bad sequence of commands" ); 561 send( "503 Bad sequence of commands" );
562 else if ( args.isEmpty() ) 562 else if ( args.isEmpty() )
563 send( "500 Syntax error, command unrecognized" ); 563 send( "500 Syntax error, command unrecognized" );
564 else { 564 else {
565 QDir dir( absFilePath( args ) ); 565 QDir dir( absFilePath( args ) );
566 if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) ) 566 if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) )
567 send( "250 Requested file action okay, completed." ); 567 send( "250 Requested file action okay, completed." );
568 else 568 else
569 send( "550 Requested action not taken" ); 569 send( "550 Requested action not taken" );
570 } 570 }
571 } 571 }
572 572
573 // abort (ABOR) 573 // abort (ABOR)
574 else if ( cmd.contains( "ABOR" ) ) { 574 else if ( cmd.contains( "ABOR" ) ) {
575 dtp->close(); 575 dtp->close();
576 if ( dtp->dtpMode() != ServerDTP::Idle ) 576 if ( dtp->dtpMode() != ServerDTP::Idle )
577 send( "426 Connection closed; transfer aborted" ); 577 send( "426 Connection closed; transfer aborted" );
578 else 578 else
579 send( "226 Closing data connection" ); 579 send( "226 Closing data connection" );
580 } 580 }
581 581
582 // delete (DELE) 582 // delete (DELE)
583 else if ( cmd == "DELE" ) { 583 else if ( cmd == "DELE" ) {
584 if ( args.isEmpty() ) 584 if ( args.isEmpty() )
585 send( "500 Syntax error, command unrecognized" ); 585 send( "500 Syntax error, command unrecognized" );
586 else { 586 else {
587 QFile file( absFilePath( args ) ) ; 587 QFile file( absFilePath( args ) ) ;
588 if ( file.remove() ) { 588 if ( file.remove() ) {
589 send( "250 Requested file action okay, completed" ); 589 send( "250 Requested file action okay, completed" );
590 QCopEnvelope e("QPE/System", "linkChanged(QString)" ); 590 QCopEnvelope e("QPE/System", "linkChanged(QString)" );
591 e << file.name(); 591 e << file.name();
592 } else { 592 } else {
593 send( "550 Requested action not taken" ); 593 send( "550 Requested action not taken" );
594 } 594 }
595 } 595 }
596 } 596 }
597 597
598 // remove directory (RMD) 598 // remove directory (RMD)
599 else if ( cmd == "RMD" ) { 599 else if ( cmd == "RMD" ) {
600 if ( args.isEmpty() ) 600 if ( args.isEmpty() )
601 send( "500 Syntax error, command unrecognized" ); 601 send( "500 Syntax error, command unrecognized" );
602 else { 602 else {
603 QDir dir; 603 QDir dir;
604 if ( dir.rmdir( absFilePath( args ), TRUE ) ) 604 if ( dir.rmdir( absFilePath( args ), TRUE ) )
605 send( "250 Requested file action okay, completed" ); 605 send( "250 Requested file action okay, completed" );
606 else 606 else
607 send( "550 Requested action not taken" ); 607 send( "550 Requested action not taken" );
608 } 608 }
609 } 609 }
610 610
611 // make directory (MKD) 611 // make directory (MKD)
612 else if ( cmd == "MKD" ) { 612 else if ( cmd == "MKD" ) {
613 if ( args.isEmpty() ) { 613 if ( args.isEmpty() ) {
614 qDebug(" Error: no arg"); 614 qDebug(" Error: no arg");
615 send( "500 Syntax error, command unrecognized" ); 615 send( "500 Syntax error, command unrecognized" );
616 } 616 }
617 else { 617 else {
618 QDir dir; 618 QDir dir;
619 if ( dir.mkdir( absFilePath( args ), TRUE ) ) 619 if ( dir.mkdir( absFilePath( args ), TRUE ) )
620 send( "250 Requested file action okay, completed." ); 620 send( "250 Requested file action okay, completed." );
621 else 621 else
622 send( "550 Requested action not taken" ); 622 send( "550 Requested action not taken" );
623 } 623 }
624 } 624 }
625 625
626 // print working directory (PWD) 626 // print working directory (PWD)
627 else if ( cmd == "PWD" ) { 627 else if ( cmd == "PWD" ) {
628 send( "257 \"" + directory.path() +"\"" ); 628 send( "257 \"" + directory.path() +"\"" );
629 } 629 }
630 630
631 // list (LIST) 631 // list (LIST)
632 else if ( cmd == "LIST" ) { 632 else if ( cmd == "LIST" ) {
633 if ( sendList( absFilePath( args ) ) ) 633 if ( sendList( absFilePath( args ) ) )
634 send( "150 File status okay" ); 634 send( "150 File status okay" );
635 else 635 else
636 send( "500 Syntax error, command unrecognized" ); 636 send( "500 Syntax error, command unrecognized" );
637 } 637 }
638 638
639 // size (SIZE) 639 // size (SIZE)
640 else if ( cmd == "SIZE" ) { 640 else if ( cmd == "SIZE" ) {
641 QString filePath = absFilePath( args ); 641 QString filePath = absFilePath( args );
642 QFileInfo fi( filePath ); 642 QFileInfo fi( filePath );
643 bool gzipfile = backupRestoreGzip( filePath ); 643 bool gzipfile = backupRestoreGzip( filePath );
644 if ( !fi.exists() && !gzipfile ) 644 if ( !fi.exists() && !gzipfile )
645 send( "500 Syntax error, command unrecognized" ); 645 send( "500 Syntax error, command unrecognized" );
646 else { 646 else {
647 if ( !gzipfile ) 647 if ( !gzipfile )
648 send( "213 " + QString::number( fi.size() ) ); 648 send( "213 " + QString::number( fi.size() ) );
649 else { 649 else {
650 Process duproc( QString("du") ); 650 Process duproc( QString("du") );
651 duproc.addArgument("-s"); 651 duproc.addArgument("-s");
652 QString in, out; 652 QString in, out;
653 if ( !duproc.exec(in, out) ) { 653 if ( !duproc.exec(in, out) ) {
654 qDebug("du process failed; just sending back 1K"); 654 qDebug("du process failed; just sending back 1K");
655 send( "213 1024"); 655 send( "213 1024");
656 } 656 }
657 else { 657 else {
658 QString size = out.left( out.find("\t") ); 658 QString size = out.left( out.find("\t") );
659 int guess = size.toInt()/5; 659 int guess = size.toInt()/5;
660 if ( filePath.contains("doc") ) 660 if ( filePath.contains("doc") )
661 guess *= 1000; 661 guess *= 1000;
662 qDebug("sending back gzip guess of %d", guess); 662 qDebug("sending back gzip guess of %d", guess);
663 send( "213 " + QString::number(guess) ); 663 send( "213 " + QString::number(guess) );
664 } 664 }
665 } 665 }
666 } 666 }
667 } 667 }
668 // name list (NLST) 668 // name list (NLST)
669 else if ( cmd == "NLST" ) { 669 else if ( cmd == "NLST" ) {
670 send( "502 Command not implemented" ); 670 send( "502 Command not implemented" );
671 } 671 }
672 672
673 // site parameters (SITE) 673 // site parameters (SITE)
674 else if ( cmd == "SITE" ) { 674 else if ( cmd == "SITE" ) {
675 send( "502 Command not implemented" ); 675 send( "502 Command not implemented" );
676 } 676 }
677 677
678 // system (SYST) 678 // system (SYST)
679 else if ( cmd == "SYST" ) { 679 else if ( cmd == "SYST" ) {
680 send( "215 UNIX Type: L8" ); 680 send( "215 UNIX Type: L8" );
681 } 681 }
682 682
683 // status (STAT) 683 // status (STAT)
684 else if ( cmd == "STAT" ) { 684 else if ( cmd == "STAT" ) {
685 send( "502 Command not implemented" ); 685 send( "502 Command not implemented" );
686 } 686 }
687 687
688 // help (HELP ) 688 // help (HELP )
689 else if ( cmd == "HELP" ) { 689 else if ( cmd == "HELP" ) {
690 send( "502 Command not implemented" ); 690 send( "502 Command not implemented" );
691 } 691 }
692 692
693 // noop (NOOP) 693 // noop (NOOP)
694 else if ( cmd == "NOOP" ) { 694 else if ( cmd == "NOOP" ) {
695 send( "200 Command okay" ); 695 send( "200 Command okay" );
696 } 696 }
697 697
698 // not implemented 698 // not implemented
699 else 699 else
700 send( "502 Command not implemented" ); 700 send( "502 Command not implemented" );
701 701
702 lastCommand = cmd; 702 lastCommand = cmd;
703} 703}
704 704
705bool ServerPI::backupRestoreGzip( const QString &file ) 705bool ServerPI::backupRestoreGzip( const QString &file )
706{ 706{
707 return (file.find( "backup" ) != -1 && 707 return (file.find( "backup" ) != -1 &&
708 file.findRev( ".tgz" ) == (int)file.length()-4 ); 708 file.findRev( ".tgz" ) == (int)file.length()-4 );
709} 709}
710 710
711bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets ) 711bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets )
712{ 712{
713 if ( file.find( "backup" ) != -1 && 713 if ( file.find( "backup" ) != -1 &&
714 file.findRev( ".tgz" ) == (int)file.length()-4 ) { 714 file.findRev( ".tgz" ) == (int)file.length()-4 ) {
715 QFileInfo info( file ); 715 QFileInfo info( file );
716 targets = info.dirPath( TRUE ); 716 targets = info.dirPath( TRUE );
717 qDebug("ServerPI::backupRestoreGzip for %s = %s", file.latin1(), 717 qDebug("ServerPI::backupRestoreGzip for %s = %s", file.latin1(),
718 targets.join(" ").latin1() ); 718 targets.join(" ").latin1() );
719 return true; 719 return true;
720 } 720 }
721 return false; 721 return false;
722} 722}
723 723
724void ServerPI::sendFile( const QString& file ) 724void ServerPI::sendFile( const QString& file )
725{ 725{
726 if ( passiv ) { 726 if ( passiv ) {
727 wait[SendFile] = TRUE; 727 wait[SendFile] = TRUE;
728 waitfile = file; 728 waitfile = file;
729 if ( waitsocket ) 729 if ( waitsocket )
730 newConnection( waitsocket ); 730 newConnection( waitsocket );
731 } 731 }
732 else { 732 else {
733 QStringList targets; 733 QStringList targets;
734 if ( backupRestoreGzip( file, targets ) ) 734 if ( backupRestoreGzip( file, targets ) )
735 dtp->sendGzipFile( file, targets, peeraddress, peerport ); 735 dtp->sendGzipFile( file, targets, peeraddress, peerport );
736 else dtp->sendFile( file, peeraddress, peerport ); 736 else dtp->sendFile( file, peeraddress, peerport );
737 } 737 }
738} 738}
739 739
740void ServerPI::retrieveFile( const QString& file ) 740void ServerPI::retrieveFile( const QString& file )
741{ 741{
742 if ( passiv ) { 742 if ( passiv ) {
743 wait[RetrieveFile] = TRUE; 743 wait[RetrieveFile] = TRUE;
744 waitfile = file; 744 waitfile = file;
745 if ( waitsocket ) 745 if ( waitsocket )
746 newConnection( waitsocket ); 746 newConnection( waitsocket );
747 } 747 }
748 else { 748 else {
749 QStringList targets; 749 QStringList targets;
750 if ( backupRestoreGzip( file, targets ) ) 750 if ( backupRestoreGzip( file, targets ) )
751 dtp->retrieveGzipFile( file, peeraddress, peerport ); 751 dtp->retrieveGzipFile( file, peeraddress, peerport );
752 else 752 else
753 dtp->retrieveFile( file, peeraddress, peerport ); 753 dtp->retrieveFile( file, peeraddress, peerport );
754 } 754 }
755} 755}
756 756
757bool ServerPI::parsePort( const QString& pp ) 757bool ServerPI::parsePort( const QString& pp )
758{ 758{
759 QStringList p = QStringList::split( ",", pp ); 759 QStringList p = QStringList::split( ",", pp );
760 if ( p.count() != 6 ) return FALSE; 760 if ( p.count() != 6 ) return FALSE;
761 761
762 // h1,h2,h3,h4,p1,p2 762 // h1,h2,h3,h4,p1,p2
763 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) + 763 peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) +
764 ( p[2].toInt() << 8 ) + p[3].toInt() ); 764 ( p[2].toInt() << 8 ) + p[3].toInt() );
765 peerport = ( p[4].toInt() << 8 ) + p[5].toInt(); 765 peerport = ( p[4].toInt() << 8 ) + p[5].toInt();
766 return TRUE; 766 return TRUE;
767} 767}
768 768
769void ServerPI::dtpCompleted() 769void ServerPI::dtpCompleted()
770{ 770{
771 send( "226 Closing data connection, file transfer successful" ); 771 send( "226 Closing data connection, file transfer successful" );
772 if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) { 772 if ( dtp->dtpMode() == ServerDTP::RetrieveFile ) {
773 QString fn = dtp->fileName(); 773 QString fn = dtp->fileName();
774 if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) { 774 if ( fn.right(8)==".desktop" && fn.find("/Documents/")>=0 ) {
775 QCopEnvelope e("QPE/System", "linkChanged(QString)" ); 775 QCopEnvelope e("QPE/System", "linkChanged(QString)" );
776 e << fn; 776 e << fn;
777 } 777 }
778 } 778 }
779 waitsocket = 0; 779 waitsocket = 0;
780 dtp->close(); 780 dtp->close();
781} 781}
782 782
783void ServerPI::dtpFailed() 783void ServerPI::dtpFailed()
784{ 784{
785 dtp->close(); 785 dtp->close();
786 waitsocket = 0; 786 waitsocket = 0;
787 send( "451 Requested action aborted: local error in processing" ); 787 send( "451 Requested action aborted: local error in processing" );
788} 788}
789 789
790void ServerPI::dtpError( int ) 790void ServerPI::dtpError( int )
791{ 791{
792 dtp->close(); 792 dtp->close();
793 waitsocket = 0; 793 waitsocket = 0;
794 send( "451 Requested action aborted: local error in processing" ); 794 send( "451 Requested action aborted: local error in processing" );
795} 795}
796 796
797bool ServerPI::sendList( const QString& arg ) 797bool ServerPI::sendList( const QString& arg )
798{ 798{
799 QByteArray listing; 799 QByteArray listing;
800 QBuffer buffer( listing ); 800 QBuffer buffer( listing );
801 801
802 if ( !buffer.open( IO_WriteOnly ) ) 802 if ( !buffer.open( IO_WriteOnly ) )
803 return FALSE; 803 return FALSE;
804 804
805 QTextStream ts( &buffer ); 805 QTextStream ts( &buffer );
806 QString fn = arg; 806 QString fn = arg;
807 807
808 if ( fn.isEmpty() ) 808 if ( fn.isEmpty() )
809 fn = directory.path(); 809 fn = directory.path();
810 810
811 QFileInfo fi( fn ); 811 QFileInfo fi( fn );
812 if ( !fi.exists() ) return FALSE; 812 if ( !fi.exists() ) return FALSE;
813 813
814 // return file listing 814 // return file listing
815 if ( fi.isFile() ) { 815 if ( fi.isFile() ) {
816 ts << fileListing( &fi ) << endl; 816 ts << fileListing( &fi ) << endl;
817 } 817 }
818 818
819 // return directory listing 819 // return directory listing
820 else if ( fi.isDir() ) { 820 else if ( fi.isDir() ) {
821 QDir dir( fn ); 821 QDir dir( fn );
822 const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden ); 822 const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden );
823 823
824 QFileInfoListIterator it( *list ); 824 QFileInfoListIterator it( *list );
825 QFileInfo *info; 825 QFileInfo *info;
826 826
827 unsigned long total = 0; 827 unsigned long total = 0;
828 while ( ( info = it.current() ) ) { 828 while ( ( info = it.current() ) ) {
829 if ( info->fileName() != "." && info->fileName() != ".." ) 829 if ( info->fileName() != "." && info->fileName() != ".." )
830 total += info->size(); 830 total += info->size();
831 ++it; 831 ++it;
832 } 832 }
833 833
834 ts << "total " << QString::number( total / 1024 ) << endl; 834 ts << "total " << QString::number( total / 1024 ) << endl;
835 835
836 it.toFirst(); 836 it.toFirst();
837 while ( ( info = it.current() ) ) { 837 while ( ( info = it.current() ) ) {
838 if ( info->fileName() == "." || info->fileName() == ".." ) { 838 if ( info->fileName() == "." || info->fileName() == ".." ) {
839 ++it; 839 ++it;
840 continue; 840 continue;
841 } 841 }
842 ts << fileListing( info ) << endl; 842 ts << fileListing( info ) << endl;
843 ++it; 843 ++it;
844 } 844 }
845 } 845 }
846 846
847 if ( passiv ) { 847 if ( passiv ) {
848 waitarray = buffer.buffer(); 848 waitarray = buffer.buffer();
849 wait[SendByteArray] = TRUE; 849 wait[SendByteArray] = TRUE;
850 if ( waitsocket ) 850 if ( waitsocket )
851 newConnection( waitsocket ); 851 newConnection( waitsocket );
852 } 852 }
853 else 853 else
854 dtp->sendByteArray( buffer.buffer(), peeraddress, peerport ); 854 dtp->sendByteArray( buffer.buffer(), peeraddress, peerport );
855 return TRUE; 855 return TRUE;
856} 856}
857 857
858QString ServerPI::fileListing( QFileInfo *info ) 858QString ServerPI::fileListing( QFileInfo *info )
859{ 859{
860 if ( !info ) return QString::null; 860 if ( !info ) return QString::null;
861 QString s; 861 QString s;
862 862
863 // type char 863 // type char
864 if ( info->isDir() ) 864 if ( info->isDir() )
865 s += "d"; 865 s += "d";
866 else if ( info->isSymLink() ) 866 else if ( info->isSymLink() )
867 s += "l"; 867 s += "l";
868 else 868 else
869 s += "-"; 869 s += "-";
870 870
871 // permisson string 871 // permisson string
872 s += permissionString( info ) + " "; 872 s += permissionString( info ) + " ";
873 873
874 // number of hardlinks 874 // number of hardlinks
875 int subdirs = 1; 875 int subdirs = 1;
876 876
877 if ( info->isDir() ) 877 if ( info->isDir() )
878 subdirs = 2; 878 subdirs = 2;
879 // FIXME : this is to slow 879 // FIXME : this is to slow
880 //if ( info->isDir() ) 880 //if ( info->isDir() )
881 //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count(); 881 //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count();
882 882
883 s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " "; 883 s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " ";
884 884
885 // owner 885 // owner
886 s += info->owner().leftJustify( 8, ' ', TRUE ) + " "; 886 s += info->owner().leftJustify( 8, ' ', TRUE ) + " ";
887 887
888 // group 888 // group
889 s += info->group().leftJustify( 8, ' ', TRUE ) + " "; 889 s += info->group().leftJustify( 8, ' ', TRUE ) + " ";
890 890
891 // file size in bytes 891 // file size in bytes
892 s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " "; 892 s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " ";
893 893
894 // last modified date 894 // last modified date
895 QDate date = info->lastModified().date(); 895 QDate date = info->lastModified().date();
896 QTime time = info->lastModified().time(); 896 QTime time = info->lastModified().time();
897 s += date.monthName( date.month() ) + " " 897 s += date.monthName( date.month() ) + " "
898 + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " " 898 + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " "
899 + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":" 899 + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":"
900 + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " "; 900 + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " ";
901 901
902 // file name 902 // file name
903 s += info->fileName(); 903 s += info->fileName();
904 904
905 return s; 905 return s;
906} 906}
907 907
908QString ServerPI::permissionString( QFileInfo *info ) 908QString ServerPI::permissionString( QFileInfo *info )
909{ 909{
910 if ( !info ) return QString( "---------" ); 910 if ( !info ) return QString( "---------" );
911 QString s; 911 QString s;
912 912
913 // user 913 // user
914 if ( info->permission( QFileInfo::ReadUser ) ) s += "r"; 914 if ( info->permission( QFileInfo::ReadUser ) ) s += "r";
915 else s += "-"; 915 else s += "-";
916 if ( info->permission( QFileInfo::WriteUser ) ) s += "w"; 916 if ( info->permission( QFileInfo::WriteUser ) ) s += "w";
917 else s += "-"; 917 else s += "-";
918 if ( info->permission( QFileInfo::ExeUser ) ) s += "x"; 918 if ( info->permission( QFileInfo::ExeUser ) ) s += "x";
919 else s += "-"; 919 else s += "-";
920 920
921 // group 921 // group
922 if ( info->permission( QFileInfo::ReadGroup ) ) s += "r"; 922 if ( info->permission( QFileInfo::ReadGroup ) ) s += "r";
923 else s += "-"; 923 else s += "-";
924 if ( info->permission( QFileInfo::WriteGroup ) )s += "w"; 924 if ( info->permission( QFileInfo::WriteGroup ) )s += "w";
925 else s += "-"; 925 else s += "-";
926 if ( info->permission( QFileInfo::ExeGroup ) ) s += "x"; 926 if ( info->permission( QFileInfo::ExeGroup ) ) s += "x";
927 else s += "-"; 927 else s += "-";
928 928
929 // exec 929 // exec
930 if ( info->permission( QFileInfo::ReadOther ) ) s += "r"; 930 if ( info->permission( QFileInfo::ReadOther ) ) s += "r";
931 else s += "-"; 931 else s += "-";
932 if ( info->permission( QFileInfo::WriteOther ) ) s += "w"; 932 if ( info->permission( QFileInfo::WriteOther ) ) s += "w";
933 else s += "-"; 933 else s += "-";
934 if ( info->permission( QFileInfo::ExeOther ) ) s += "x"; 934 if ( info->permission( QFileInfo::ExeOther ) ) s += "x";
935 else s += "-"; 935 else s += "-";
936 936
937 return s; 937 return s;
938} 938}
939 939
940void ServerPI::newConnection( int socket ) 940void ServerPI::newConnection( int socket )
941{ 941{
942 //qDebug( "New incomming connection" ); 942 //qDebug( "New incomming connection" );
943 943
944 if ( !passiv ) return; 944 if ( !passiv ) return;
945 945
946 if ( wait[SendFile] ) { 946 if ( wait[SendFile] ) {
947 QStringList targets; 947 QStringList targets;
948 if ( backupRestoreGzip( waitfile, targets ) ) 948 if ( backupRestoreGzip( waitfile, targets ) )
949 dtp->sendGzipFile( waitfile, targets ); 949 dtp->sendGzipFile( waitfile, targets );
950 else 950 else
951 dtp->sendFile( waitfile ); 951 dtp->sendFile( waitfile );
952 dtp->setSocket( socket ); 952 dtp->setSocket( socket );
953 } 953 }
954 else if ( wait[RetrieveFile] ) { 954 else if ( wait[RetrieveFile] ) {
955 qDebug("check retrieve file"); 955 qDebug("check retrieve file");
956 if ( backupRestoreGzip( waitfile ) ) 956 if ( backupRestoreGzip( waitfile ) )
957 dtp->retrieveGzipFile( waitfile ); 957 dtp->retrieveGzipFile( waitfile );
958 else 958 else
959 dtp->retrieveFile( waitfile ); 959 dtp->retrieveFile( waitfile );
960 dtp->setSocket( socket ); 960 dtp->setSocket( socket );
961 } 961 }
962 else if ( wait[SendByteArray] ) { 962 else if ( wait[SendByteArray] ) {
963 dtp->sendByteArray( waitarray ); 963 dtp->sendByteArray( waitarray );
964 dtp->setSocket( socket ); 964 dtp->setSocket( socket );
965 } 965 }
966 else if ( wait[RetrieveByteArray] ) { 966 else if ( wait[RetrieveByteArray] ) {
967 qDebug("retrieve byte array"); 967 qDebug("retrieve byte array");
968 dtp->retrieveByteArray(); 968 dtp->retrieveByteArray();
969 dtp->setSocket( socket ); 969 dtp->setSocket( socket );
970 } 970 }
971 else 971 else
972 waitsocket = socket; 972 waitsocket = socket;
973 973
974 for( int i = 0; i < 4; i++ ) 974 for( int i = 0; i < 4; i++ )
975 wait[i] = FALSE; 975 wait[i] = FALSE;
976} 976}
977 977
978QString ServerPI::absFilePath( const QString& file ) 978QString ServerPI::absFilePath( const QString& file )
979{ 979{
980 if ( file.isEmpty() ) return file; 980 if ( file.isEmpty() ) return file;
981 981
982 QString filepath( file ); 982 QString filepath( file );
983 if ( file[0] != "/" ) 983 if ( file[0] != "/" )
984 filepath = directory.path() + "/" + file; 984 filepath = directory.path() + "/" + file;
985 985
986 return filepath; 986 return filepath;
987} 987}
988 988
989 989
990void ServerPI::timerEvent( QTimerEvent * ) 990void ServerPI::timerEvent( QTimerEvent * )
991{ 991{
992 connectionClosed(); 992 connectionClosed();
993} 993}
994 994
995 995
996ServerDTP::ServerDTP( QObject *parent = 0, const char* name = 0) 996ServerDTP::ServerDTP( QObject *parent = 0, const char* name = 0)
997 : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ), 997 : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ),
998retrieveTargzProc( 0 ), gzipProc( 0 ) 998retrieveTargzProc( 0 ), gzipProc( 0 )
999{ 999{
1000 1000
1001 connect( this, SIGNAL( connected() ), SLOT( connected() ) ); 1001 connect( this, SIGNAL( connected() ), SLOT( connected() ) );
1002 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) ); 1002 connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
1003 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) ); 1003 connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) );
1004 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) ); 1004 connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) );
1005 1005
1006 gzipProc = new QProcess( this, "gzipProc" ); 1006 gzipProc = new QProcess( this, "gzipProc" );
1007 gzipProc->setCommunication( QProcess::Stdin | QProcess::Stdout ); 1007 gzipProc->setCommunication( QProcess::Stdin | QProcess::Stdout );
1008 1008
1009 createTargzProc = new QProcess( QString("tar"), this, "createTargzProc"); 1009 createTargzProc = new QProcess( QString("tar"), this, "createTargzProc");
1010 createTargzProc->setCommunication( QProcess::Stdout ); 1010 createTargzProc->setCommunication( QProcess::Stdout );
1011 createTargzProc->setWorkingDirectory( QDir::rootDirPath() ); 1011 createTargzProc->setWorkingDirectory( QDir::rootDirPath() );
1012 connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) ); 1012 connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) );
1013 1013
1014 QStringList args = "tar"; 1014 QStringList args = "tar";
1015 args += "-xv"; 1015 args += "-xv";
1016 retrieveTargzProc = new QProcess( args, this, "retrieveTargzProc" ); 1016 retrieveTargzProc = new QProcess( args, this, "retrieveTargzProc" );
1017 retrieveTargzProc->setCommunication( QProcess::Stdin ); 1017 retrieveTargzProc->setCommunication( QProcess::Stdin );
1018 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() ); 1018 retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() );
1019 connect( retrieveTargzProc, SIGNAL( processExited() ), 1019 connect( retrieveTargzProc, SIGNAL( processExited() ),
1020 SIGNAL( completed() ) ); 1020 SIGNAL( completed() ) );
1021 connect( retrieveTargzProc, SIGNAL( processExited() ), 1021 connect( retrieveTargzProc, SIGNAL( processExited() ),
1022 SLOT( extractTarDone() ) ); 1022 SLOT( extractTarDone() ) );
1023} 1023}
1024 1024
1025ServerDTP::~ServerDTP() 1025ServerDTP::~ServerDTP()
1026{ 1026{
1027 buf.close(); 1027 buf.close();
1028 file.close(); 1028 file.close();
1029 createTargzProc->kill(); 1029 createTargzProc->kill();
1030} 1030}
1031 1031
1032void ServerDTP::extractTarDone() 1032void ServerDTP::extractTarDone()
1033{ 1033{
1034 qDebug("extract done"); 1034 qDebug("extract done");
1035#ifndef QT_NO_COP 1035#ifndef QT_NO_COP
1036 QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" ); 1036 QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" );
1037 e << file.name(); 1037 e << file.name();
1038#endif 1038#endif
1039} 1039}
1040 1040
1041void ServerDTP::connected() 1041void ServerDTP::connected()
1042{ 1042{
1043 // send file mode 1043 // send file mode
1044 switch ( mode ) { 1044 switch ( mode ) {
1045 case SendFile : 1045 case SendFile :
1046 if ( !file.exists() || !file.open( IO_ReadOnly) ) { 1046 if ( !file.exists() || !file.open( IO_ReadOnly) ) {
1047 emit failed(); 1047 emit failed();
1048 mode = Idle; 1048 mode = Idle;
1049 return; 1049 return;
1050 } 1050 }
1051 1051
1052 //qDebug( "Debug: Sending file '%s'", file.name().latin1() ); 1052 //qDebug( "Debug: Sending file '%s'", file.name().latin1() );
1053 1053
1054 bytes_written = 0; 1054 bytes_written = 0;
1055 if ( file.size() == 0 ) { 1055 if ( file.size() == 0 ) {
1056 //make sure it doesn't hang on empty files 1056 //make sure it doesn't hang on empty files
1057 file.close(); 1057 file.close();
1058 emit completed(); 1058 emit completed();
1059 mode = Idle; 1059 mode = Idle;
1060 } else { 1060 } else {
1061 1061
1062 if( !file.atEnd() ) { 1062 if( !file.atEnd() ) {
1063 QCString s; 1063 QCString s;
1064 s.resize( block_size ); 1064 s.resize( block_size );
1065 int bytes = file.readBlock( s.data(), block_size ); 1065 int bytes = file.readBlock( s.data(), block_size );
1066 writeBlock( s.data(), bytes ); 1066 writeBlock( s.data(), bytes );
1067 } 1067 }
1068 } 1068 }
1069 break; 1069 break;
1070 case SendGzipFile: 1070 case SendGzipFile:
1071 if ( createTargzProc->isRunning() ) { 1071 if ( createTargzProc->isRunning() ) {
1072 // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY 1072 // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY
1073 qWarning("Previous tar --gzip process is still running; killing it..."); 1073 qWarning("Previous tar --gzip process is still running; killing it...");
1074 createTargzProc->kill(); 1074 createTargzProc->kill();
1075 } 1075 }
1076 1076
1077 bytes_written = 0; 1077 bytes_written = 0;
1078 qDebug("==>start send tar process"); 1078 qDebug("==>start send tar process");
1079 if ( !createTargzProc->start() ) 1079 if ( !createTargzProc->start() )
1080 qWarning("Error starting %s or %s", 1080 qWarning("Error starting %s or %s",
1081 createTargzProc->arguments().join(" ").latin1(), 1081 createTargzProc->arguments().join(" ").latin1(),
1082 gzipProc->arguments().join(" ").latin1() ); 1082 gzipProc->arguments().join(" ").latin1() );
1083 break; 1083 break;
1084 case SendBuffer: 1084 case SendBuffer:
1085 if ( !buf.open( IO_ReadOnly) ) { 1085 if ( !buf.open( IO_ReadOnly) ) {
1086 emit failed(); 1086 emit failed();
1087 mode = Idle; 1087 mode = Idle;
1088 return; 1088 return;
1089 } 1089 }
1090 1090
1091 // qDebug( "Debug: Sending byte array" ); 1091 // qDebug( "Debug: Sending byte array" );
1092 bytes_written = 0; 1092 bytes_written = 0;
1093 while( !buf.atEnd() ) 1093 while( !buf.atEnd() )
1094 putch( buf.getch() ); 1094 putch( buf.getch() );
1095 buf.close(); 1095 buf.close();
1096 break; 1096 break;
1097 case RetrieveFile: 1097 case RetrieveFile:
1098 // retrieve file mode 1098 // retrieve file mode
1099 if ( file.exists() && !file.remove() ) { 1099 if ( file.exists() && !file.remove() ) {
1100 emit failed(); 1100 emit failed();
1101 mode = Idle; 1101 mode = Idle;
1102 return; 1102 return;
1103 } 1103 }
1104 1104
1105 if ( !file.open( IO_WriteOnly) ) { 1105 if ( !file.open( IO_WriteOnly) ) {
1106 emit failed(); 1106 emit failed();
1107 mode = Idle; 1107 mode = Idle;
1108 return; 1108 return;
1109 } 1109 }
1110 // qDebug( "Debug: Retrieving file %s", file.name().latin1() ); 1110 // qDebug( "Debug: Retrieving file %s", file.name().latin1() );
1111 break; 1111 break;
1112 case RetrieveGzipFile: 1112 case RetrieveGzipFile:
1113 qDebug("=-> starting tar process to receive .tgz file"); 1113 qDebug("=-> starting tar process to receive .tgz file");
1114 break; 1114 break;
1115 case RetrieveBuffer: 1115 case RetrieveBuffer:
1116 // retrieve buffer mode 1116 // retrieve buffer mode
1117 if ( !buf.open( IO_WriteOnly) ) { 1117 if ( !buf.open( IO_WriteOnly) ) {
1118 emit failed(); 1118 emit failed();
1119 mode = Idle; 1119 mode = Idle;
1120 return; 1120 return;
1121 } 1121 }
1122 // qDebug( "Debug: Retrieving byte array" ); 1122 // qDebug( "Debug: Retrieving byte array" );
1123 break; 1123 break;
1124 case Idle: 1124 case Idle:
1125 qDebug("connection established but mode set to Idle; BUG!"); 1125 qDebug("connection established but mode set to Idle; BUG!");
1126 break; 1126 break;
1127 } 1127 }
1128} 1128}
1129 1129
1130void ServerDTP::connectionClosed() 1130void ServerDTP::connectionClosed()
1131{ 1131{
1132 //qDebug( "Debug: Data connection closed %ld bytes written", bytes_written ); 1132 //qDebug( "Debug: Data connection closed %ld bytes written", bytes_written );
1133 1133
1134 // send file mode 1134 // send file mode