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