summaryrefslogtreecommitdiff
authorllornkcor <llornkcor>2003-07-17 02:25:08 (UTC)
committer llornkcor <llornkcor>2003-07-17 02:25:08 (UTC)
commit6ca1d7605597f4b8a7559167e5cf3d6e093805cd (patch) (side-by-side diff)
tree93096c3d0df0c0f02c75d2acc2f481120914945c
parent115e09bdeb2ee3c7c0b9344f95179e1d10e86e48 (diff)
downloadopie-6ca1d7605597f4b8a7559167e5cf3d6e093805cd.zip
opie-6ca1d7605597f4b8a7559167e5cf3d6e093805cd.tar.gz
opie-6ca1d7605597f4b8a7559167e5cf3d6e093805cd.tar.bz2
fix filesaving when filename contains extended characters
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/filemanager.cpp167
-rw-r--r--library/filemanager.h6
2 files changed, 121 insertions, 52 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp
index 2b97846..cc657fa 100644
--- a/library/filemanager.cpp
+++ b/library/filemanager.cpp
@@ -28,6 +28,11 @@
#include <errno.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <sys/sendfile.h>
+#include <fcntl.h>
/*!
\class FileManager
@@ -56,23 +61,25 @@ FileManager::~FileManager()
*/
bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
{
- QString fn = f.file() + ".new";
+ QString fn = f.file() + ".new";
ensurePathExists( fn );
QFile fl( fn );
- if ( !fl.open( IO_WriteOnly|IO_Raw ) )
- return FALSE;
+ if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
+ qWarning("open failed");
+ return FALSE;
+ }
int total_written = fl.writeBlock( data );
fl.close();
if ( total_written != int(data.size()) || !f.writeLink() ) {
- QFile::remove( fn );
- return FALSE;
+ QFile::remove( fn );
+ return FALSE;
}
+ qDebug("total written %d out of %d", total_written, data.size());
// else rename the file...
- if ( ::rename( fn.latin1(), f.file().latin1() ) < 0 ) {
- qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
- f.file().latin1(), errno );
- // remove the file...
- QFile::remove( fn );
+ if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
+ qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
+ f.file().latin1(), errno );
+ // remove the file...
}
return TRUE;
}
@@ -86,12 +93,12 @@ bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
*/
bool FileManager::saveFile( const DocLnk &f, const QString &text )
{
- QString fn = f.file() + ".new";
+ QString fn = f.file() + ".new";
ensurePathExists( fn );
QFile fl( fn );
if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
- qDebug( "open failed: %s", fn.latin1() );
- return FALSE;
+ qWarning("open failed");
+ return FALSE;
}
QCString cstr = text.utf8();
@@ -99,15 +106,14 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text )
total_written = fl.writeBlock( cstr.data(), cstr.length() );
fl.close();
if ( total_written != int(cstr.length()) || !f.writeLink() ) {
- QFile::remove( fn );
- return FALSE;
+ QFile::remove( fn );
+ return FALSE;
}
- // okay now rename the file...
- if ( ::rename( fn.latin1(), f.file().latin1() ) < 0 ) {
- qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
- f.file().latin1(), errno );
- // remove the tmp file, otherwise, it will just lay around...
- QFile::remove( fn.latin1() );
+ // okay now rename the file..
+ if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
+ qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
+ f.file().latin1(), errno );
+
}
return TRUE;
}
@@ -125,7 +131,7 @@ bool FileManager::loadFile( const DocLnk &f, QString &text )
QString fn = f.file();
QFile fl( fn );
if ( !fl.open( IO_ReadOnly ) )
- return FALSE;
+ return FALSE;
QTextStream ts( &fl );
#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
// The below should work, but doesn't in Qt 2.3.0
@@ -149,10 +155,10 @@ bool FileManager::loadFile( const DocLnk &f, QByteArray &ba )
QString fn = f.file();
QFile fl( fn );
if ( !fl.open( IO_ReadOnly ) )
- return FALSE;
+ return FALSE;
ba.resize( fl.size() );
if ( fl.size() > 0 )
- fl.readBlock( ba.data(), fl.size() );
+ fl.readBlock( ba.data(), fl.size() );
fl.close();
return TRUE;
}
@@ -167,49 +173,110 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
{
QFile sf( src.file() );
if ( !sf.open( IO_ReadOnly ) )
- return FALSE;
+ return FALSE;
QString fn = dest.file() + ".new";
ensurePathExists( fn );
QFile df( fn );
if ( !df.open( IO_WriteOnly|IO_Raw ) )
- return FALSE;
+ return FALSE;
const int bufsize = 16384;
char buffer[bufsize];
bool ok = TRUE;
int bytesRead = 0;
while ( ok && !sf.atEnd() ) {
- bytesRead = sf.readBlock( buffer, bufsize );
- if ( bytesRead < 0 )
- ok = FALSE;
- while ( ok && bytesRead > 0 ) {
- int bytesWritten = df.writeBlock( buffer, bytesRead );
- if ( bytesWritten < 0 )
- ok = FALSE;
- else
- bytesRead -= bytesWritten;
- }
+ bytesRead = sf.readBlock( buffer, bufsize );
+ if ( bytesRead < 0 )
+ ok = FALSE;
+ while ( ok && bytesRead > 0 ) {
+ int bytesWritten = df.writeBlock( buffer, bytesRead );
+ if ( bytesWritten < 0 )
+ ok = FALSE;
+ else
+ bytesRead -= bytesWritten;
+ }
}
if ( ok )
- ok = dest.writeLink();
+ ok = dest.writeLink();
if ( ok ) {
- // okay now rename the file...
- if ( ::rename( fn.latin1(), dest.file().latin1() ) < 0 ) {
- qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
- dest.file().latin1(), errno );
- // remove the tmp file, otherwise, it will just lay around...
- QFile::remove( fn.latin1() );
- }
+ // okay now rename the file...
+ if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) {
+ qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
+ dest.file().latin1(), errno );
+ // remove the tmp file, otherwise, it will just lay around...
+ QFile::remove( fn.latin1() );
+ }
} else {
- QFile::remove( fn.latin1() );
+ QFile::remove( fn.latin1() );
}
return ok;
}
+bool FileManager::copyFile( const QString & src, const QString & dest ) {
+ bool success = true;
+ struct stat status;
+ int read_fd=0;
+ int write_fd=0;
+ struct stat stat_buf;
+ off_t offset = 0;
+ QFile srcFile(src);
+ QFile destFile(dest);
+
+ if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
+ return success = false;
+ }
+ read_fd = srcFile.handle();
+ if(read_fd != -1) {
+ fstat (read_fd, &stat_buf);
+ if( !destFile.open( IO_WriteOnly|IO_Raw ) )
+ return success = false;
+ write_fd = destFile.handle();
+ if(write_fd != -1) {
+ int err=0;
+ QString msg;
+ err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
+ if( err == -1) {
+ switch(err) {
+ case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
+ case EINVAL: msg = "Descriptor is not valid or locked. ";
+ case ENOMEM: msg = "Insufficient memory to read from in_fd.";
+ case EIO: msg = "Unspecified error while reading from in_fd.";
+ };
+ success = false;
+ }
+ } else {
+ qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
+ success = false;
+ }
+ } else {
+ qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
+ success = false;
+ }
+ srcFile.close();
+ destFile.close();
+ // Set file permissions
+ if( stat( (const char *) src, &status ) == 0 ) {
+ chmod( (const char *) dest, status.st_mode );
+ }
+
+ return success;
+}
+
+
+bool FileManager::renameFile( const QString & src, const QString & dest ) {
+ if(copyFile( src, dest )) {
+ if(QFile::remove(src) ) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
/*!
Opens the document specified by \a f as a readable QIODevice.
The caller must delete the return value.
@@ -221,7 +288,7 @@ QIODevice* FileManager::openFile( const DocLnk& f )
QString fn = f.file();
QFile* fl = new QFile( fn );
if ( !fl->open( IO_ReadOnly ) ) {
- delete fl;
+ delete fl;
fl = 0;
}
return fl;
@@ -239,9 +306,9 @@ QIODevice* FileManager::saveFile( const DocLnk& f )
ensurePathExists( fn );
QFile* fl = new QFile( fn );
if ( fl->open( IO_WriteOnly ) ) {
- f.writeLink();
+ f.writeLink();
} else {
- delete fl;
+ delete fl;
fl = 0;
}
return fl;
@@ -266,8 +333,8 @@ bool FileManager::ensurePathExists( const QString &fn )
QFileInfo fi(fn);
fi.setFile( fi.dirPath(TRUE) );
if ( !fi.exists() ) {
- if ( system(("mkdir -p "+fi.filePath())) )
- return FALSE;
+ if ( system(("mkdir -p "+fi.filePath())) )
+ return FALSE;
}
return TRUE;
diff --git a/library/filemanager.h b/library/filemanager.h
index f8d9425..61a3341 100644
--- a/library/filemanager.h
+++ b/library/filemanager.h
@@ -38,8 +38,10 @@ public:
bool loadFile( const DocLnk&, QByteArray &data );
bool loadFile( const DocLnk&, QString &text );
bool copyFile( const AppLnk &src, const AppLnk &dest );
-
- // The caller must delete the return values.
+ bool copyFile( const QString & src, const QString & dest );
+ bool renameFile( const QString &, const QString &);
+
+// The caller must delete the return values.
QIODevice* openFile( const DocLnk& );
QIODevice* saveFile( const DocLnk& );