summaryrefslogtreecommitdiff
authorwaspe <waspe>2003-11-04 17:08:12 (UTC)
committer waspe <waspe>2003-11-04 17:08:12 (UTC)
commitdc96afa26288897a9d25ab8c321d8ad350c53f44 (patch) (unidiff)
tree62678d196ae984d246260279c16e49c2923d7a30
parent5865ec3970cead5b2cf3dd255a55cf2e1869e330 (diff)
downloadopie-dc96afa26288897a9d25ab8c321d8ad350c53f44.zip
opie-dc96afa26288897a9d25ab8c321d8ad350c53f44.tar.gz
opie-dc96afa26288897a9d25ab8c321d8ad350c53f44.tar.bz2
resolved merge conflict
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--library/filemanager.cpp66
1 files changed, 63 insertions, 3 deletions
diff --git a/library/filemanager.cpp b/library/filemanager.cpp
index 91986a0..1c1c998 100644
--- a/library/filemanager.cpp
+++ b/library/filemanager.cpp
@@ -17,368 +17,428 @@
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#include "filemanager.h" 20#include "filemanager.h"
21#include "applnk.h" 21#include "applnk.h"
22 22
23#include <qdir.h> 23#include <qdir.h>
24#include <qfile.h> 24#include <qfile.h>
25#include <qfileinfo.h> 25#include <qfileinfo.h>
26#include <qtextstream.h> 26#include <qtextstream.h>
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> 31#include <unistd.h>
32#include <sys/stat.h> 32#include <sys/stat.h>
33#include <dirent.h> 33#include <dirent.h>
34#ifdef Q_OS_MACX 34#ifdef Q_OS_MACX
35// MacOS X does not have sendfile.. :( 35// MacOS X does not have sendfile.. :(
36// But maybe in the future.. !? 36// But maybe in the future.. !?
37# ifdef SENDFILE 37# ifdef SENDFILE
38# include <sys/types.h> 38# include <sys/types.h>
39# include <sys/socket.h> 39# include <sys/socket.h>
40# endif 40# endif
41#else 41#else
42# include <sys/sendfile.h> 42# include <sys/sendfile.h>
43#endif /* Q_OS_MACX */ 43#endif /* Q_OS_MACX */
44#include <fcntl.h> 44#include <fcntl.h>
45 45
46/*! 46/*!
47 \class FileManager 47 \class FileManager
48 \brief The FileManager class assists with AppLnk input/output. 48 \brief The FileManager class assists with AppLnk input/output.
49*/ 49*/
50 50
51/*! 51/*!
52 Constructs a FileManager. 52 Constructs a FileManager.
53*/ 53*/
54FileManager::FileManager() 54FileManager::FileManager()
55{ 55{
56} 56}
57 57
58/*! 58/*!
59 Destroys a FileManager. 59 Destroys a FileManager.
60*/ 60*/
61FileManager::~FileManager() 61FileManager::~FileManager()
62{ 62{
63 63
64} 64}
65 65
66/*! 66/*!
67 Saves \a data as the document specified by \a f. 67 Saves \a data as the document specified by \a f.
68 68
69 Returns whether the operation succeeded. 69 Returns whether the operation succeeded.
70*/ 70*/
71bool FileManager::saveFile( const DocLnk &f, const QByteArray &data ) 71bool FileManager::saveFile( const DocLnk &f, const QByteArray &data )
72{ 72{
73 QString fn = f.file() + ".new"; 73 QString fn = f.file() + ".new";
74 ensurePathExists( fn ); 74 ensurePathExists( fn );
75 QFile fl( fn ); 75 QFile fl( fn );
76 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { 76 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
77 qWarning("open failed"); 77 qWarning("open failed");
78 return FALSE; 78 return FALSE;
79 } 79 }
80 int total_written = fl.writeBlock( data ); 80 int total_written = fl.writeBlock( data );
81 fl.close(); 81 fl.close();
82 if ( total_written != int(data.size()) || !f.writeLink() ) { 82 if ( total_written != int(data.size()) || !f.writeLink() ) {
83 QFile::remove( fn ); 83 QFile::remove( fn );
84 return FALSE; 84 return FALSE;
85 } 85 }
86 qDebug("total written %d out of %d", total_written, data.size()); 86 qDebug("total written %d out of %d", total_written, data.size());
87 // else rename the file... 87 // else rename the file...
88 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) { 88 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
89 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 89 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
90 f.file().latin1(), errno ); 90 f.file().latin1(), errno );
91 // remove the file... 91 // remove the file...
92 } 92 }
93 return TRUE; 93 return TRUE;
94} 94}
95 95
96/*! 96/*!
97 Saves \a text as the document specified by \a f. 97 Saves \a text as the document specified by \a f.
98 98
99 The text is saved in UTF8 format. 99 The text is saved in UTF8 format.
100 100
101 Returns whether the operation succeeded. 101 Returns whether the operation succeeded.
102*/ 102*/
103bool FileManager::saveFile( const DocLnk &f, const QString &text ) 103bool FileManager::saveFile( const DocLnk &f, const QString &text )
104{ 104{
105 QString fn = f.file() + ".new"; 105 QString fn = f.file() + ".new";
106 ensurePathExists( fn ); 106 ensurePathExists( fn );
107 QFile fl( fn ); 107 QFile fl( fn );
108 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) { 108 if ( !fl.open( IO_WriteOnly|IO_Raw ) ) {
109 qWarning("open failed"); 109 qWarning("open failed");
110 return FALSE; 110 return FALSE;
111 } 111 }
112 112
113 QCString cstr = text.utf8(); 113 QCString cstr = text.utf8();
114 int total_written; 114 int total_written;
115 total_written = fl.writeBlock( cstr.data(), cstr.length() ); 115 total_written = fl.writeBlock( cstr.data(), cstr.length() );
116 fl.close(); 116 fl.close();
117 if ( total_written != int(cstr.length()) || !f.writeLink() ) { 117 if ( total_written != int(cstr.length()) || !f.writeLink() ) {
118 QFile::remove( fn ); 118 QFile::remove( fn );
119 return FALSE; 119 return FALSE;
120 } 120 }
121 // okay now rename the file.. 121 // okay now rename the file..
122 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) { 122 if ( !renameFile( fn.latin1(), f.file().latin1() ) ) {
123 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 123 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
124 f.file().latin1(), errno ); 124 f.file().latin1(), errno );
125 125
126 } 126 }
127 return TRUE; 127 return TRUE;
128} 128}
129 129
130 130
131/*! 131/*!
132 Loads \a text from the document specified by \a f. 132 Loads \a text from the document specified by \a f.
133 133
134 The text is required to be in UTF8 format. 134 The text is required to be in UTF8 format.
135 135
136 Returns whether the operation succeeded. 136 Returns whether the operation succeeded.
137*/ 137*/
138bool FileManager::loadFile( const DocLnk &f, QString &text ) 138bool FileManager::loadFile( const DocLnk &f, QString &text )
139{ 139{
140 QString fn = f.file(); 140 QString fn = f.file();
141 QFile fl( fn ); 141 QFile fl( fn );
142 if ( !fl.open( IO_ReadOnly ) ) 142 if ( !fl.open( IO_ReadOnly ) )
143 return FALSE; 143 return FALSE;
144 QTextStream ts( &fl ); 144 QTextStream ts( &fl );
145#if QT_VERSION <= 230 && defined(QT_NO_CODECS) 145#if QT_VERSION <= 230 && defined(QT_NO_CODECS)
146 // The below should work, but doesn't in Qt 2.3.0 146 // The below should work, but doesn't in Qt 2.3.0
147 ts.setCodec( QTextCodec::codecForMib( 106 ) ); 147 ts.setCodec( QTextCodec::codecForMib( 106 ) );
148#else 148#else
149 ts.setEncoding( QTextStream::UnicodeUTF8 ); 149 ts.setEncoding( QTextStream::UnicodeUTF8 );
150#endif 150#endif
151 text = ts.read(); 151 text = ts.read();
152 fl.close(); 152 fl.close();
153 return TRUE; 153 return TRUE;
154} 154}
155 155
156 156
157/*! 157/*!
158 Loads \a ba from the document specified by \a f. 158 Loads \a ba from the document specified by \a f.
159 159
160 Returns whether the operation succeeded. 160 Returns whether the operation succeeded.
161*/ 161*/
162bool FileManager::loadFile( const DocLnk &f, QByteArray &ba ) 162bool FileManager::loadFile( const DocLnk &f, QByteArray &ba )
163{ 163{
164 QString fn = f.file(); 164 QString fn = f.file();
165 QFile fl( fn ); 165 QFile fl( fn );
166 if ( !fl.open( IO_ReadOnly ) ) 166 if ( !fl.open( IO_ReadOnly ) )
167 return FALSE; 167 return FALSE;
168 ba.resize( fl.size() ); 168 ba.resize( fl.size() );
169 if ( fl.size() > 0 ) 169 if ( fl.size() > 0 )
170 fl.readBlock( ba.data(), fl.size() ); 170 fl.readBlock( ba.data(), fl.size() );
171 fl.close(); 171 fl.close();
172 return TRUE; 172 return TRUE;
173} 173}
174 174
175/*! 175/*!
176 Copies the document specified by \a src to the document specified 176 Copies the document specified by \a src to the document specified
177 by \a dest. 177 by \a dest.
178 178
179 Returns whether the operation succeeded. 179 Returns whether the operation succeeded.
180*/ 180*/
181bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest ) 181bool FileManager::copyFile( const AppLnk &src, const AppLnk &dest )
182{ 182{
183 QFile sf( src.file() ); 183 QFile sf( src.file() );
184 if ( !sf.open( IO_ReadOnly ) ) 184 if ( !sf.open( IO_ReadOnly ) )
185 return FALSE; 185 return FALSE;
186 186
187 QString fn = dest.file() + ".new"; 187 QString fn = dest.file() + ".new";
188 ensurePathExists( fn ); 188 ensurePathExists( fn );
189 QFile df( fn ); 189 QFile df( fn );
190 if ( !df.open( IO_WriteOnly|IO_Raw ) ) 190 if ( !df.open( IO_WriteOnly|IO_Raw ) )
191 return FALSE; 191 return FALSE;
192 192
193 const int bufsize = 16384; 193 const int bufsize = 16384;
194 char buffer[bufsize]; 194 char buffer[bufsize];
195 bool ok = TRUE; 195 bool ok = TRUE;
196 int bytesRead = 0; 196 int bytesRead = 0;
197 while ( ok && !sf.atEnd() ) { 197 while ( ok && !sf.atEnd() ) {
198 bytesRead = sf.readBlock( buffer, bufsize ); 198 bytesRead = sf.readBlock( buffer, bufsize );
199 if ( bytesRead < 0 ) 199 if ( bytesRead < 0 )
200 ok = FALSE; 200 ok = FALSE;
201 while ( ok && bytesRead > 0 ) { 201 while ( ok && bytesRead > 0 ) {
202 int bytesWritten = df.writeBlock( buffer, bytesRead ); 202 int bytesWritten = df.writeBlock( buffer, bytesRead );
203 if ( bytesWritten < 0 ) 203 if ( bytesWritten < 0 )
204 ok = FALSE; 204 ok = FALSE;
205 else 205 else
206 bytesRead -= bytesWritten; 206 bytesRead -= bytesWritten;
207 } 207 }
208 } 208 }
209 209
210 if ( ok ) 210 if ( ok )
211 ok = dest.writeLink(); 211 ok = dest.writeLink();
212 212
213 if ( ok ) { 213 if ( ok ) {
214 // okay now rename the file... 214 // okay now rename the file...
215 if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) { 215 if ( !renameFile( fn.latin1(), dest.file().latin1() ) ) {
216 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(), 216 qWarning( "problem renaming file %s to %s, errno: %d", fn.latin1(),
217 dest.file().latin1(), errno ); 217 dest.file().latin1(), errno );
218 // remove the tmp file, otherwise, it will just lay around... 218 // remove the tmp file, otherwise, it will just lay around...
219 QFile::remove( fn.latin1() ); 219 QFile::remove( fn.latin1() );
220 } 220 }
221 } else { 221 } else {
222 QFile::remove( fn.latin1() ); 222 QFile::remove( fn.latin1() );
223 } 223 }
224 224
225 return ok; 225 return ok;
226} 226}
227 227
228
229
230bool FileManager::copyFile( const QString & src, const QString & dest ) { 228bool FileManager::copyFile( const QString & src, const QString & dest ) {
231 bool success = true; 229 bool success = true;
232 struct stat status; 230 struct stat status;
233 int read_fd=0; 231 int read_fd=0;
234 int write_fd=0; 232 int write_fd=0;
235 struct stat stat_buf; 233 struct stat stat_buf;
236 off_t offset = 0; 234 off_t offset = 0;
237 QFile srcFile(src); 235 QFile srcFile(src);
238 QFile destFile(dest); 236 QFile destFile(dest);
239 237
240 if(!srcFile.open( IO_ReadOnly|IO_Raw)) { 238 if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
241 return success = false; 239 return success = false;
242 } 240 }
243 read_fd = srcFile.handle(); 241 read_fd = srcFile.handle();
244 if(read_fd != -1) { 242 if(read_fd != -1) {
245 fstat (read_fd, &stat_buf); 243 fstat (read_fd, &stat_buf);
246 if( !destFile.open( IO_WriteOnly|IO_Raw ) ) 244 if( !destFile.open( IO_WriteOnly|IO_Raw ) )
247 return success = false; 245 return success = false;
248 write_fd = destFile.handle(); 246 write_fd = destFile.handle();
249 if(write_fd != -1) { 247 if(write_fd != -1) {
250 int err=0; 248 int err=0;
251 QString msg; 249 QString msg;
252#ifdef Q_OS_MACX 250#ifdef Q_OS_MACX
253#ifdef SENDMAIL 251#ifdef SENDMAIL
254 /* FreeBSD does support a different kind of 252 /* FreeBSD does support a different kind of
255 * sendfile. (eilers) 253 * sendfile. (eilers)
256 * I took this from Very Secure FTPd 254 * I took this from Very Secure FTPd
257 * Licence: GPL 255 * Licence: GPL
258 * Author: Chris Evans 256 * Author: Chris Evans
259 * sysdeputil.c 257 * sysdeputil.c
260 */ 258 */
261 /* XXX - start_pos will truncate on 32-bit machines - can we 259 /* XXX - start_pos will truncate on 32-bit machines - can we
262 * say "start from current pos"? 260 * say "start from current pos"?
263 */ 261 */
264 off_t written = 0; 262 off_t written = 0;
265 int retval = 0; 263 int retval = 0;
266 retval = sendfile(read_fd, write_fd, offset, stat_buf.st_size, NULL, 264 retval = sendfile(read_fd, write_fd, offset, stat_buf.st_size, NULL,
267 &written, 0); 265 &written, 0);
268 /* Translate to Linux-like retval */ 266 /* Translate to Linux-like retval */
269 if (written > 0) 267 if (written > 0)
270 { 268 {
271 err = (int) written; 269 err = (int) written;
272 } 270 }
273#else /* SENDMAIL */ 271#else /* SENDMAIL */
274 err == -1; 272 err == -1;
275 msg = "FAILURE: Using unsupported function \"sendfile()\" Need Workaround !!"; 273 msg = "FAILURE: Using unsupported function \"sendfile()\" Need Workaround !!";
276 success = false; 274 success = false;
277# warning "Need workaround for sendfile!!(eilers)" 275# warning "Need workaround for sendfile!!(eilers)"
278#endif /* SENDMAIL */ 276#endif /* SENDMAIL */
279 277
280#else 278#else
281 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size); 279 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
282 if( err == -1) { 280 if( err == -1) {
283 switch(err) { 281 switch(err) {
284 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. "; 282 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
285 case EINVAL: msg = "Descriptor is not valid or locked. "; 283 case EINVAL: msg = "Descriptor is not valid or locked. ";
286 case ENOMEM: msg = "Insufficient memory to read from in_fd."; 284 case ENOMEM: msg = "Insufficient memory to read from in_fd.";
287 case EIO: msg = "Unspecified error while reading from in_fd."; 285 case EIO: msg = "Unspecified error while reading from in_fd.";
288 }; 286 };
289 success = false; 287 success = false;
290 } 288 }
291#endif /* Q_OS_MACX */ 289#endif /* Q_OS_MACX */
292 if( !success ) 290 if( !success )
293 qWarning( msg ); 291 qWarning( msg );
294 } else { 292 } else {
295 qWarning("open write failed %s, %s",src.latin1(), dest.latin1()); 293 qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
296 success = false; 294 success = false;
297 } 295 }
298 } else { 296 } else {
299 qWarning("open read failed %s, %s",src.latin1(), dest.latin1()); 297 qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
300 success = false; 298 success = false;
301 } 299 }
302 srcFile.close(); 300 srcFile.close();
303 destFile.close(); 301 destFile.close();
304 // Set file permissions 302 // Set file permissions
305 if( stat( (const char *) src, &status ) == 0 ) { 303 if( stat( (const char *) src, &status ) == 0 ) {
306 chmod( (const char *) dest, status.st_mode ); 304 chmod( (const char *) dest, status.st_mode );
307 } 305 }
308 306
309 return success; 307 return success;
310} 308}
311 309
312 310
313bool FileManager::renameFile( const QString & src, const QString & dest ) { 311bool FileManager::renameFile( const QString & src, const QString & dest ) {
314 if(copyFile( src, dest )) { 312 if(copyFile( src, dest )) {
315 if(QFile::remove(src) ) { 313 if(QFile::remove(src) ) {
316 return true; 314 return true;
317 } 315 }
318 } 316 }
319 return false; 317 return false;
320} 318}
321 319
322 320
321=======
322bool FileManager::copyFile( const QString & src, const QString & dest ) {
323 bool success = true;
324 struct stat status;
325 int read_fd=0;
326 int write_fd=0;
327 struct stat stat_buf;
328 off_t offset = 0;
329 QFile srcFile(src);
330 QFile destFile(dest);
331
332 if(!srcFile.open( IO_ReadOnly|IO_Raw)) {
333 return success = false;
334 }
335 read_fd = srcFile.handle();
336 if(read_fd != -1) {
337 fstat (read_fd, &stat_buf);
338 if( !destFile.open( IO_WriteOnly|IO_Raw ) )
339 return success = false;
340 write_fd = destFile.handle();
341 if(write_fd != -1) {
342 int err=0;
343 QString msg;
344 err = sendfile(write_fd, read_fd, &offset, stat_buf.st_size);
345 if( err == -1) {
346 switch(err) {
347 case EBADF : msg = "The input file was not opened for reading or the output file was not opened for writing. ";
348 case EINVAL: msg = "Descriptor is not valid or locked. ";
349 case ENOMEM: msg = "Insufficient memory to read from in_fd.";
350 case EIO: msg = "Unspecified error while reading from in_fd.";
351 };
352 success = false;
353 }
354 } else {
355 qWarning("open write failed %s, %s",src.latin1(), dest.latin1());
356 success = false;
357 }
358 } else {
359 qWarning("open read failed %s, %s",src.latin1(), dest.latin1());
360 success = false;
361 }
362 srcFile.close();
363 destFile.close();
364 // Set file permissions
365 if( stat( (const char *) src, &status ) == 0 ) {
366 chmod( (const char *) dest, status.st_mode );
367 }
368
369 return success;
370}
371
372
373bool FileManager::renameFile( const QString & src, const QString & dest ) {
374 if(copyFile( src, dest )) {
375 if(QFile::remove(src) ) {
376 return true;
377 }
378 }
379 return false;
380}
381
382
323/*! 383/*!
324 Opens the document specified by \a f as a readable QIODevice. 384 Opens the document specified by \a f as a readable QIODevice.
325 The caller must delete the return value. 385 The caller must delete the return value.
326 386
327 Returns 0 if the operation fails. 387 Returns 0 if the operation fails.
328*/ 388*/
329QIODevice* FileManager::openFile( const DocLnk& f ) 389QIODevice* FileManager::openFile( const DocLnk& f )
330{ 390{
331 QString fn = f.file(); 391 QString fn = f.file();
332 QFile* fl = new QFile( fn ); 392 QFile* fl = new QFile( fn );
333 if ( !fl->open( IO_ReadOnly ) ) { 393 if ( !fl->open( IO_ReadOnly ) ) {
334 delete fl; 394 delete fl;
335 fl = 0; 395 fl = 0;
336 } 396 }
337 return fl; 397 return fl;
338} 398}
339 399
340/*! 400/*!
341 Opens the document specified by \a f as a writable QIODevice. 401 Opens the document specified by \a f as a writable QIODevice.
342 The caller must delete the return value. 402 The caller must delete the return value.
343 403
344 Returns 0 if the operation fails. 404 Returns 0 if the operation fails.
345*/ 405*/
346QIODevice* FileManager::saveFile( const DocLnk& f ) 406QIODevice* FileManager::saveFile( const DocLnk& f )
347{ 407{
348 QString fn = f.file(); 408 QString fn = f.file();
349 ensurePathExists( fn ); 409 ensurePathExists( fn );
350 QFile* fl = new QFile( fn ); 410 QFile* fl = new QFile( fn );
351 if ( fl->open( IO_WriteOnly ) ) { 411 if ( fl->open( IO_WriteOnly ) ) {
352 f.writeLink(); 412 f.writeLink();
353 } else { 413 } else {
354 delete fl; 414 delete fl;
355 fl = 0; 415 fl = 0;
356 } 416 }
357 return fl; 417 return fl;
358} 418}
359 419
360/*! 420/*!
361 Returns whether the document specified by \a f current exists 421 Returns whether the document specified by \a f current exists
362 as a file on disk. 422 as a file on disk.
363*/ 423*/
364bool FileManager::exists( const DocLnk &f ) 424bool FileManager::exists( const DocLnk &f )
365{ 425{
366 return QFile::exists(f.file()); 426 return QFile::exists(f.file());
367} 427}
368 428
369 429
370/*! 430/*!
371 Ensures that the path \a fn exists, by creating required directories. 431 Ensures that the path \a fn exists, by creating required directories.
372 Returns TRUE if successful. 432 Returns TRUE if successful.
373*/ 433*/
374bool FileManager::ensurePathExists( const QString &fn ) 434bool FileManager::ensurePathExists( const QString &fn )
375{ 435{
376 QFileInfo fi(fn); 436 QFileInfo fi(fn);
377 fi.setFile( fi.dirPath(TRUE) ); 437 fi.setFile( fi.dirPath(TRUE) );
378 if ( !fi.exists() ) { 438 if ( !fi.exists() ) {
379 if ( system(("mkdir -p "+fi.filePath())) ) 439 if ( system(("mkdir -p "+fi.filePath())) )
380 return FALSE; 440 return FALSE;
381 } 441 }
382 442
383 return TRUE; 443 return TRUE;
384} 444}