summaryrefslogtreecommitdiff
authorar <ar>2004-06-15 22:33:30 (UTC)
committer ar <ar>2004-06-15 22:33:30 (UTC)
commit80bf424ffc8394026c8bea825d91413b472d502a (patch) (unidiff)
treebf0aa66a5743d5389626de9d6e3a4366eb61cea2
parent4b1fb9237a832aaa34c97421165916e1583b8b1a (diff)
downloadopie-80bf424ffc8394026c8bea825d91413b472d502a.zip
opie-80bf424ffc8394026c8bea825d91413b472d502a.tar.gz
opie-80bf424ffc8394026c8bea825d91413b472d502a.tar.bz2
- remove sendfile. it doesn't work on linux kernel 2.6 and on mac os x
- cleanup code
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--library/filemanager.cpp308
1 files changed, 98 insertions, 210 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp
index adfe590..47af1c6 100644
--- a/library/filemanager.cpp
+++ b/library/filemanager.cpp
@@ -19,2 +19,3 @@
19**********************************************************************/ 19**********************************************************************/
20
20#include "filemanager.h" 21#include "filemanager.h"
@@ -22,2 +23,4 @@
22 23
24/* QT */
25#include <qdir.h>
23#include <qfileinfo.h> 26#include <qfileinfo.h>
@@ -25,18 +28,5 @@
25 28
26#include <errno.h> 29/* STD */
27#include <stdlib.h> 30#include <stdlib.h>
28#include <unistd.h>
29#include <sys/stat.h> 31#include <sys/stat.h>
30#include <dirent.h>
31#ifdef Q_OS_MACX
32// MacOS X does not have sendfile.. :(
33// But maybe in the future.. !?
34# ifdef SENDFILE
35# include <sys/types.h>
36# include <sys/socket.h>
37# endif
38#else
39# include <sys/sendfile.h>
40#endif /* Q_OS_MACX */
41#include <fcntl.h>
42 32
@@ -59,3 +49,2 @@ FileManager::~FileManager()
59{ 49{
60
61} 50}
@@ -69,6 +58,9 @@ bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
69{ 58{
70 QString fn = f.file() + ".new"; 59 QString fileName = f.file() + ".new";
71 ensurePathExists( fn ); 60 ensurePathExists( fileName );
72 QFile fl( fn ); 61 QFile file( fileName );
73 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { 62
63 //write data in temporary .new file
64 if ( !file.open( IO_WriteOnly|IO_Raw ) )
65 {
74 qWarning("open failed"); 66 qWarning("open failed");
@@ -76,6 +68,8 @@ bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
76 } 68 }
77 int total_written = fl.writeBlock( data ); 69 int total_written = file.writeBlock( data );
78 fl.close(); 70 file.close();
79 if ( total_written != int(data.size()) || !f.writeLink() ) { 71 //check if every was written
80 QFile::remove( fn ); 72 if ( total_written != int(data.size()) || !f.writeLink() )
73 {
74 QFile::remove( fileName );
81 return FALSE; 75 return FALSE;
@@ -83,8 +77,6 @@ bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
83 qDebug("total written %d out of %d", total_written, data.size()); 77 qDebug("total written %d out of %d", total_written, data.size());
84 // else rename the file... 78
85 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) { 79 //rename temporary .new file in original filenam
86 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 80 if ( !renameFile( fileName, f.file() ) )
87 f.file().latin1(), errno ); 81 QFile::remove( fileName);
88 // remove the file...
89 }
90 return TRUE; 82 return TRUE;
@@ -101,6 +93,9 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text )
101{ 93{
102 QString fn = f.file() + ".new"; 94 QString fileName = f.file() + ".new";
103 ensurePathExists( fn ); 95 ensurePathExists( fileName );
104 QFile fl( fn ); 96 QFile file( fileName );
105 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { 97
98 //write data in temporary .new file
99 if ( !file.open( IO_WriteOnly|IO_Raw ) )
100 {
106 qWarning("open failed"); 101 qWarning("open failed");
@@ -111,14 +106,13 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text )
111 int total_written; 106 int total_written;
112 total_written = fl.writeBlock( cstr.data(), cstr.length() ); 107 total_written = file.writeBlock( cstr.data(), cstr.length() );
113 fl.close(); 108 file.close();
114 if ( total_written != int(cstr.length()) || !f.writeLink() ) { 109 if ( total_written != int(cstr.length()) || !f.writeLink() )
115 QFile::remove( fn ); 110 {
111 QFile::remove( fileName );
116 return FALSE; 112 return FALSE;
117 } 113 }
118 // okay now rename the file..
119 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
120 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
121 f.file().latin1(), errno );
122 114
123 } 115 // okay now rename the file..
116 if ( !renameFile( fileName, f.file() ) )
117 QFile::remove( fileName);
124 return TRUE; 118 return TRUE;
@@ -179,28 +173,12 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
179{ 173{
180 QFile sf( src.file() ); 174 QFile srcFile( src.file() );
181 if ( !sf.open( IO_ReadOnly ) ) 175 if ( !srcFile.open( IO_ReadOnly ) )
182 return FALSE; 176 return FALSE;
183 177
184 QString fn = dest.file() + ".new"; 178 QString fileName = dest.file() + ".new";
185 ensurePathExists( fn ); 179
186 QFile df( fn ); 180 ensurePathExists( fileName );
187 if ( !df.open( IO_WriteOnly|IO_Raw ) )
188 return FALSE;
189 181
190 const int bufsize = 16384;
191 char buffer[bufsize];
192 bool ok = TRUE; 182 bool ok = TRUE;
193 int bytesRead = 0; 183 ok = copyFile( src.file(), fileName );
194 while ( ok && !sf.atEnd() ) {
195 bytesRead = sf.readBlock( buffer, bufsize );
196 if ( bytesRead < 0 )
197 ok = FALSE;
198 while ( ok && bytesRead > 0 ) {
199 int bytesWritten = df.writeBlock( buffer, bytesRead );
200 if ( bytesWritten < 0 )
201 ok = FALSE;
202 else
203 bytesRead -= bytesWritten;
204 }
205 }
206 184
@@ -209,14 +187,13 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
209 187
210 if ( ok ) { 188 if ( ok )
189 {
211 // okay now rename the file... 190 // okay now rename the file...
212 if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) { 191 if ( !renameFile( fileName.latin1(), dest.file().latin1() ) )
213 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
214 dest.file().latin1(), errno );
215 // remove the tmp file, otherwise, it will just lay around... 192 // remove the tmp file, otherwise, it will just lay around...
216 QFile::remove( fn.latin1() ); 193 QFile::remove( fileName.latin1() );
217 } 194 }
218 } else { 195 else
219 QFile::remove( fn.latin1() ); 196 {
197 QFile::remove( fileName.latin1() );
220 } 198 }
221
222 return ok; 199 return ok;
@@ -224,134 +201,39 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
224 201
225bool FileManager::copyFile( const QString & src, const QString & dest ) { 202bool FileManager::copyFile( const QString & src, const QString & dest )
226 bool success = true; 203{
227 struct stat status; 204 //open read file
228 int read_fd=0;
229 int write_fd=0;
230 struct stat stat_buf;
231 off_t offset = 0;
232 QFile srcFile(src); 205 QFile srcFile(src);
233 QFile destFile(dest); 206 if( !srcFile.open( IO_ReadOnly|IO_Raw) )
234
235 if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
236 return success = false;
237 }
238 read_fd = srcFile.handle();
239 if(read_fd != -1) {
240 fstat (read_fd, &stat_buf);
241 if( !destFile.open( IO_WriteOnly|IO_Raw ) )
242 return success = false;
243 write_fd = destFile.handle();
244 if(write_fd != -1) {
245 int err=0;
246 QString msg;
247#ifdef Q_OS_MACX
248#ifdef SENDFILE
249 /* FreeBSD does support a different kind of
250 * sendfile. (eilers)
251 * I took this from Very Secure FTPd
252 * Licence: GPL
253 * Author: Chris Evans
254 * sysdeputil.c
255 */
256 /* XXX - start_pos will truncate on 32-bit machines - can we
257 * say "start from current pos"?
258 */
259 off_t written = 0;
260 int retval = 0;
261 retval = sendfile(read_fd, write_fd, offset, stat_buf.st_size, NULL,
262 &written, 0);
263 /* Translate to Linux-like retval */
264 if (written > 0)
265 { 207 {
266 err = (int) written;
267 }
268#else /* SENDFILE */
269 err == -1;
270 msg = "FAILURE: Using unsupported function \"sendfile()\" Need Workaround !!";
271 success = false;
272# warning "Need workaround for sendfile!!(eilers)"
273#endif /* SENDFILE */
274
275#else
276 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
277 if( err == -1) {
278 switch(errno) {
279 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
280 case EINVAL: msg = "Descriptor is not valid or locked. ";
281 case ENOMEM: msg = "Insufficient memory to read from in_fd.";
282 case EIO: msg = "Unspecified error while reading from in_fd.";
283 };
284 success = false;
285 }
286#endif /* Q_OS_MACX */
287 if( !success )
288 qWarning( msg );
289 } else {
290 qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
291 success = false;
292 }
293 } else {
294 qWarning("open read failed %s, %s",src.latin1(), dest.latin1()); 208 qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
295 success = false; 209 return FALSE;
296 }
297 srcFile.close();
298 destFile.close();
299 // Set file permissions
300 if( stat( (const char *) src, &status ) == 0 ) {
301 chmod( (const char *) dest, status.st_mode );
302 }
303
304 return success;
305}
306
307
308bool FileManager::renameFile( const QString & src, const QString & dest ) {
309 if(copyFile( src, dest )) {
310 if(QFile::remove(src) ) {
311 return true;
312 }
313 }
314 return false;
315} 210}
316 211
317/* 212 //open write file
318bool FileManager::copyFile( const QString & src, const QString & dest ) {
319 bool success = true;
320 struct stat status;
321 int read_fd=0;
322 int write_fd=0;
323 struct stat stat_buf;
324 off_t offset = 0;
325 QFile srcFile(src);
326 QFile destFile(dest); 213 QFile destFile(dest);
327
328 if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
329 return success = false;
330 }
331 read_fd = srcFile.handle();
332 if(read_fd != -1) {
333 fstat (read_fd, &stat_buf);
334 if( !destFile.open( IO_WriteOnly|IO_Raw ) ) 214 if( !destFile.open( IO_WriteOnly|IO_Raw ) )
335 return success = false; 215 {
336 write_fd = destFile.handle();
337 if(write_fd != -1) {
338 int err=0;
339 QString msg;
340 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
341 if( err == -1) {
342 switch(err) {
343 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
344 case EINVAL: msg = "Descriptor is not valid or locked. ";
345 case ENOMEM: msg = "Insufficient memory to read from in_fd.";
346 case EIO: msg = "Unspecified error while reading from in_fd.";
347 };
348 success = false;
349 }
350 } else {
351 qWarning("open write failed %s, %s",src.latin1(), dest.latin1()); 216 qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
352 success = false; 217 srcFile.close();
218 return FALSE;
219 }
220
221 //copy content
222 const int bufsize = 16384;
223 char buffer[bufsize];
224 bool ok = TRUE;
225 int bytesRead = 0;
226 while ( ok && !srcFile.atEnd() )
227 {
228 bytesRead = srcFile.readBlock( buffer, bufsize );
229 if ( bytesRead < 0 )
230 ok = FALSE;
231 while ( ok && bytesRead > 0 )
232 {
233 int bytesWritten = destFile.writeBlock( buffer, bytesRead );
234 if ( bytesWritten < 0 )
235 ok = FALSE;
236 else
237 bytesRead -= bytesWritten;
353 } 238 }
354 } else {
355 qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
356 success = false;
357 } 239 }
@@ -360,7 +242,8 @@ bool FileManager::copyFile( const QString & src, const QString & dest ) {
360 // Set file permissions 242 // Set file permissions
361 if( stat( (const char *) src, &status ) == 0 ) { 243 struct stat status;
244 if( stat( (const char *) src, &status ) == 0 )
245 {
362 chmod( (const char *) dest, status.st_mode ); 246 chmod( (const char *) dest, status.st_mode );
363 } 247 }
364 248 return ok;
365 return success;
366} 249}
@@ -368,11 +251,12 @@ bool FileManager::copyFile( const QString & src, const QString & dest ) {
368 251
369bool FileManager::renameFile( const QString & src, const QString & dest ) { 252bool FileManager::renameFile( const QString & src, const QString & dest )
370 if(copyFile( src, dest )) { 253{
371 if(QFile::remove(src) ) { 254 QDir dir( QFileInfo( src ).absFilePath() );
372 return true; 255 if ( !dir.rename( src, dest ) )
373 } 256 {
374 } 257 qWarning( "problem renaming file %s to %s", src, dest );
375 return false; 258 return false;
376} 259}
377*/ 260 return true;
261}
378 262
@@ -388,3 +272,4 @@ QIODevice* FileManager::openFile( const DocLnk& f )
388 QFile* fl = new QFile( fn ); 272 QFile* fl = new QFile( fn );
389 if ( !fl->open( IO_ReadOnly ) ) { 273 if ( !fl->open( IO_ReadOnly ) )
274 {
390 delete fl; 275 delete fl;
@@ -406,5 +291,8 @@ QIODevice* FileManager::saveFile( const DocLnk& f )
406 QFile* fl = new QFile( fn ); 291 QFile* fl = new QFile( fn );
407 if ( fl->open( IO_WriteOnly ) ) { 292 if ( fl->open( IO_WriteOnly ) )
293 {
408 f.writeLink(); 294 f.writeLink();
409 } else { 295 }
296 else
297 {
410 delete fl; 298 delete fl;
@@ -424,3 +312,2 @@ bool FileManager::exists( const DocLnk &f )
424 312
425
426/*! 313/*!
@@ -433,3 +320,4 @@ bool FileManager::ensurePathExists( const QString &fn )
433 fi.setFile( fi.dirPath(TRUE) ); 320 fi.setFile( fi.dirPath(TRUE) );
434 if ( !fi.exists() ) { 321 if ( !fi.exists() )
322 {
435 if ( system(("mkdir -p "+fi.filePath())) ) 323 if ( system(("mkdir -p "+fi.filePath())) )