author | llornkcor <llornkcor> | 2003-07-17 02:25:08 (UTC) |
---|---|---|
committer | llornkcor <llornkcor> | 2003-07-17 02:25:08 (UTC) |
commit | 6ca1d7605597f4b8a7559167e5cf3d6e093805cd (patch) (unidiff) | |
tree | 93096c3d0df0c0f02c75d2acc2f481120914945c | |
parent | 115e09bdeb2ee3c7c0b9344f95179e1d10e86e48 (diff) | |
download | opie-6ca1d7605597f4b8a7559167e5cf3d6e093805cd.zip opie-6ca1d7605597f4b8a7559167e5cf3d6e093805cd.tar.gz opie-6ca1d7605597f4b8a7559167e5cf3d6e093805cd.tar.bz2 |
fix filesaving when filename contains extended characters
-rw-r--r-- | library/filemanager.cpp | 85 | ||||
-rw-r--r-- | library/filemanager.h | 2 |
2 files changed, 78 insertions, 9 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp index 2b97846..cc657fa 100644 --- a/library/filemanager.cpp +++ b/library/filemanager.cpp | |||
@@ -27,8 +27,13 @@ | |||
27 | #include <qtextcodec.h> | 27 | #include <qtextcodec.h> |
28 | 28 | ||
29 | #include <errno.h> | 29 | #include <errno.h> |
30 | #include <stdlib.h> | 30 | #include <stdlib.h> |
31 | #include <unistd.h> | ||
32 | #include <sys/stat.h> | ||
33 | #include <dirent.h> | ||
34 | #include <sys/sendfile.h> | ||
35 | #include <fcntl.h> | ||
31 | 36 | ||
32 | /*! | 37 | /*! |
33 | \class FileManager | 38 | \class FileManager |
34 | \brief The FileManager class assists with AppLnk input/output. | 39 | \brief The FileManager class assists with AppLnk input/output. |
@@ -58,22 +63,24 @@ bool FileManager::saveFile( const DocLnk &f, const QByteArray &data ) | |||
58 | { | 63 | { |
59 | QString fn = f.file() + ".new"; | 64 | QString fn = f.file() + ".new"; |
60 | ensurePathExists( fn ); | 65 | ensurePathExists( fn ); |
61 | QFile fl( fn ); | 66 | QFile fl( fn ); |
62 | if ( !fl.open( IO_WriteOnly|IO_Raw ) ) | 67 | if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { |
68 | qWarning("open failed"); | ||
63 | return FALSE; | 69 | return FALSE; |
70 | } | ||
64 | int total_written = fl.writeBlock( data ); | 71 | int total_written = fl.writeBlock( data ); |
65 | fl.close(); | 72 | fl.close(); |
66 | if ( total_written != int(data.size()) || !f.writeLink() ) { | 73 | if ( total_written != int(data.size()) || !f.writeLink() ) { |
67 | QFile::remove( fn ); | 74 | QFile::remove( fn ); |
68 | return FALSE; | 75 | return FALSE; |
69 | } | 76 | } |
77 | qDebug("total written %d out of %d", total_written, data.size()); | ||
70 | // else rename the file... | 78 | // else rename the file... |
71 | if ( ::rename( fn.latin1(), f.file().latin1() ) < 0 ) { | 79 | if ( !renameFile( fn.latin1(), f.file().latin1() ) ) { |
72 | qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), | 80 | qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), |
73 | f.file().latin1(), errno ); | 81 | f.file().latin1(), errno ); |
74 | // remove the file... | 82 | // remove the file... |
75 | QFile::remove( fn ); | ||
76 | } | 83 | } |
77 | return TRUE; | 84 | return TRUE; |
78 | } | 85 | } |
79 | 86 | ||
@@ -89,9 +96,9 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text ) | |||
89 | QString fn = f.file() + ".new"; | 96 | QString fn = f.file() + ".new"; |
90 | ensurePathExists( fn ); | 97 | ensurePathExists( fn ); |
91 | QFile fl( fn ); | 98 | QFile fl( fn ); |
92 | if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { | 99 | if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { |
93 | qDebug( "open failed: %s", fn.latin1() ); | 100 | qWarning("open failed"); |
94 | return FALSE; | 101 | return FALSE; |
95 | } | 102 | } |
96 | 103 | ||
97 | QCString cstr = text.utf8(); | 104 | QCString cstr = text.utf8(); |
@@ -101,14 +108,13 @@ bool FileManager::saveFile( const DocLnk &f, const QString &text ) | |||
101 | if ( total_written != int(cstr.length()) || !f.writeLink() ) { | 108 | if ( total_written != int(cstr.length()) || !f.writeLink() ) { |
102 | QFile::remove( fn ); | 109 | QFile::remove( fn ); |
103 | return FALSE; | 110 | return FALSE; |
104 | } | 111 | } |
105 | // okay now rename the file... | 112 | // okay now rename the file.. |
106 | if ( ::rename( fn.latin1(), f.file().latin1() ) < 0 ) { | 113 | if ( !renameFile( fn.latin1(), f.file().latin1() ) ) { |
107 | qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), | 114 | qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), |
108 | f.file().latin1(), errno ); | 115 | f.file().latin1(), errno ); |
109 | // remove the tmp file, otherwise, it will just lay around... | 116 | |
110 | QFile::remove( fn.latin1() ); | ||
111 | } | 117 | } |
112 | return TRUE; | 118 | return TRUE; |
113 | } | 119 | } |
114 | 120 | ||
@@ -196,9 +202,9 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) | |||
196 | ok = dest.writeLink(); | 202 | ok = dest.writeLink(); |
197 | 203 | ||
198 | if ( ok ) { | 204 | if ( ok ) { |
199 | // okay now rename the file... | 205 | // okay now rename the file... |
200 | if ( ::rename( fn.latin1(), dest.file().latin1() ) < 0 ) { | 206 | if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) { |
201 | qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), | 207 | qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), |
202 | dest.file().latin1(), errno ); | 208 | dest.file().latin1(), errno ); |
203 | // remove the tmp file, otherwise, it will just lay around... | 209 | // remove the tmp file, otherwise, it will just lay around... |
204 | QFile::remove( fn.latin1() ); | 210 | QFile::remove( fn.latin1() ); |
@@ -209,8 +215,69 @@ bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) | |||
209 | 215 | ||
210 | return ok; | 216 | return ok; |
211 | } | 217 | } |
212 | 218 | ||
219 | bool FileManager::copyFile( const QString & src, const QString & dest ) { | ||
220 | bool success = true; | ||
221 | struct stat status; | ||
222 | int read_fd=0; | ||
223 | int write_fd=0; | ||
224 | struct stat stat_buf; | ||
225 | off_t offset = 0; | ||
226 | QFile srcFile(src); | ||
227 | QFile destFile(dest); | ||
228 | |||
229 | if(!srcFile.open( IO_ReadOnly|IO_Raw)) { | ||
230 | return success = false; | ||
231 | } | ||
232 | read_fd = srcFile.handle(); | ||
233 | if(read_fd != -1) { | ||
234 | fstat (read_fd, &stat_buf); | ||
235 | if( !destFile.open( IO_WriteOnly|IO_Raw ) ) | ||
236 | return success = false; | ||
237 | write_fd = destFile.handle(); | ||
238 | if(write_fd != -1) { | ||
239 | int err=0; | ||
240 | QString msg; | ||
241 | err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size); | ||
242 | if( err == -1) { | ||
243 | switch(err) { | ||
244 | case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. "; | ||
245 | case EINVAL: msg = "Descriptor is not valid or locked. "; | ||
246 | case ENOMEM: msg = "Insufficient memory to read from in_fd."; | ||
247 | case EIO: msg = "Unspecified error while reading from in_fd."; | ||
248 | }; | ||
249 | success = false; | ||
250 | } | ||
251 | } else { | ||
252 | qWarning("open write failed %s, %s",src.latin1(), dest.latin1()); | ||
253 | success = false; | ||
254 | } | ||
255 | } else { | ||
256 | qWarning("open read failed %s, %s",src.latin1(), dest.latin1()); | ||
257 | success = false; | ||
258 | } | ||
259 | srcFile.close(); | ||
260 | destFile.close(); | ||
261 | // Set file permissions | ||
262 | if( stat( (const char *) src, &status ) == 0 ) { | ||
263 | chmod( (const char *) dest, status.st_mode ); | ||
264 | } | ||
265 | |||
266 | return success; | ||
267 | } | ||
268 | |||
269 | |||
270 | bool FileManager::renameFile( const QString & src, const QString & dest ) { | ||
271 | if(copyFile( src, dest )) { | ||
272 | if(QFile::remove(src) ) { | ||
273 | return true; | ||
274 | } | ||
275 | } | ||
276 | return false; | ||
277 | } | ||
278 | |||
279 | |||
213 | /*! | 280 | /*! |
214 | Opens the document specified by \a f as a readable QIODevice. | 281 | Opens the document specified by \a f as a readable QIODevice. |
215 | The caller must delete the return value. | 282 | The caller must delete the return value. |
216 | 283 | ||
diff --git a/library/filemanager.h b/library/filemanager.h index f8d9425..61a3341 100644 --- a/library/filemanager.h +++ b/library/filemanager.h | |||
@@ -37,8 +37,10 @@ public: | |||
37 | bool saveFile( const DocLnk&, const QString &text ); | 37 | bool saveFile( const DocLnk&, const QString &text ); |
38 | bool loadFile( const DocLnk&, QByteArray &data ); | 38 | bool loadFile( const DocLnk&, QByteArray &data ); |
39 | bool loadFile( const DocLnk&, QString &text ); | 39 | bool loadFile( const DocLnk&, QString &text ); |
40 | bool copyFile( const AppLnk &src, const AppLnk &dest ); | 40 | bool copyFile( const AppLnk &src, const AppLnk &dest ); |
41 | bool copyFile( const QString & src, const QString & dest ); | ||
42 | bool renameFile( const QString &, const QString &); | ||
41 | 43 | ||
42 | // The caller must delete the return values. | 44 | // The caller must delete the return values. |
43 | QIODevice* openFile( const DocLnk& ); | 45 | QIODevice* openFile( const DocLnk& ); |
44 | QIODevice* saveFile( const DocLnk& ); | 46 | QIODevice* saveFile( const DocLnk& ); |