00001
00002
00003
00004
00005 #ifdef HAVE_CONFIG_H
00006 #include <config.h>
00007 #endif
00008
00009 #include <kmessagebox.h>
00010 #include <kdebug.h>
00011
00012 #include <assert.h>
00013 #include <qdir.h>
00014
00015 #include <klocale.h>
00016 #include <kstdguiitem.h>
00017
00018 #include <qwidget.h>
00019 #include <qfile.h>
00020 #include <qfileinfo.h>
00021 #include <sys/stat.h>
00022 #include <sys/types.h>
00023
00024 #include <kdepimmacros.h>
00025
00026 namespace KPIM {
00027
00028
00029 static void msgDialog(const QString &msg)
00030 {
00031 KMessageBox::sorry(0, msg, i18n("File I/O Error"));
00032 }
00033
00034
00035
00036 KDE_EXPORT QCString kFileToString(const QString &aFileName, bool aEnsureNL, bool aVerbose)
00037 {
00038 QCString result;
00039 QFileInfo info(aFileName);
00040 unsigned int readLen;
00041 unsigned int len = info.size();
00042 QFile file(aFileName);
00043
00044
00045 if( aFileName.isEmpty() )
00046 return "";
00047
00048 if (!info.exists())
00049 {
00050 if (aVerbose)
00051 msgDialog(i18n("The specified file does not exist:\n%1").arg(aFileName));
00052 return QCString();
00053 }
00054 if (info.isDir())
00055 {
00056 if (aVerbose)
00057 msgDialog(i18n("This is a folder and not a file:\n%1").arg(aFileName));
00058 return QCString();
00059 }
00060 if (!info.isReadable())
00061 {
00062 if (aVerbose)
00063 msgDialog(i18n("You do not have read permissions "
00064 "to the file:\n%1").arg(aFileName));
00065 return QCString();
00066 }
00067 if (len <= 0) return QCString();
00068
00069 if (!file.open(IO_Raw|IO_ReadOnly))
00070 {
00071 if (aVerbose) switch(file.status())
00072 {
00073 case IO_ReadError:
00074 msgDialog(i18n("Could not read file:\n%1").arg(aFileName));
00075 break;
00076 case IO_OpenError:
00077 msgDialog(i18n("Could not open file:\n%1").arg(aFileName));
00078 break;
00079 default:
00080 msgDialog(i18n("Error while reading file:\n%1").arg(aFileName));
00081 }
00082 return QCString();
00083 }
00084
00085 result.resize(len + (int)aEnsureNL + 1);
00086 readLen = file.readBlock(result.data(), len);
00087 if (aEnsureNL && result[len-1]!='\n')
00088 {
00089 result[len++] = '\n';
00090 readLen++;
00091 }
00092 result[len] = '\0';
00093
00094 if (readLen < len)
00095 {
00096 QString msg = i18n("Could only read %1 bytes of %2.")
00097 .arg(readLen).arg(len);
00098 msgDialog(msg);
00099 return QCString();
00100 }
00101
00102 return result;
00103 }
00104
00105
00106 #if 0 // unused
00107 QByteArray kFileToBytes(const QString &aFileName, bool aVerbose)
00108 {
00109 QByteArray result;
00110 QFileInfo info(aFileName);
00111 unsigned int readLen;
00112 unsigned int len = info.size();
00113 QFile file(aFileName);
00114
00115
00116 if( aFileName.isEmpty() )
00117 return result;
00118
00119 if (!info.exists())
00120 {
00121 if (aVerbose)
00122 msgDialog(i18n("The specified file does not exist:\n%1")
00123 .arg(aFileName));
00124 return result;
00125 }
00126 if (info.isDir())
00127 {
00128 if (aVerbose)
00129 msgDialog(i18n("This is a folder and not a file:\n%1")
00130 .arg(aFileName));
00131 return result;
00132 }
00133 if (!info.isReadable())
00134 {
00135 if (aVerbose)
00136 msgDialog(i18n("You do not have read permissions "
00137 "to the file:\n%1").arg(aFileName));
00138 return result;
00139 }
00140 if (len <= 0) return result;
00141
00142 if (!file.open(IO_Raw|IO_ReadOnly))
00143 {
00144 if (aVerbose) switch(file.status())
00145 {
00146 case IO_ReadError:
00147 msgDialog(i18n("Could not read file:\n%1").arg(aFileName));
00148 break;
00149 case IO_OpenError:
00150 msgDialog(i18n("Could not open file:\n%1").arg(aFileName));
00151 break;
00152 default:
00153 msgDialog(i18n("Error while reading file:\n%1").arg(aFileName));
00154 }
00155 return result;
00156 }
00157
00158 result.resize(len);
00159 readLen = file.readBlock(result.data(), len);
00160 kdDebug(5300) << QString( "len %1" ).arg(len) << endl;
00161
00162 if (readLen < len)
00163 {
00164 QString msg;
00165 msg = i18n("Could only read %1 bytes of %2.")
00166 .arg(readLen).arg(len);
00167 msgDialog(msg);
00168 return result;
00169 }
00170
00171 return result;
00172 }
00173 #endif
00174
00175
00176 KDE_EXPORT bool kBytesToFile(const char* aBuffer, int len,
00177 const QString &aFileName,
00178 bool aAskIfExists, bool aBackup, bool aVerbose)
00179 {
00180
00181 QFile file(aFileName);
00182 int writeLen, rc;
00183
00184
00185 if(aFileName.isEmpty())
00186 return FALSE;
00187
00188 if (file.exists())
00189 {
00190 if (aAskIfExists)
00191 {
00192 QString str;
00193 str = i18n("File %1 exists.\nDo you want to replace it?")
00194 .arg(aFileName);
00195 rc = KMessageBox::warningContinueCancel(0,
00196 str, i18n("Save to File"), i18n("&Replace"));
00197 if (rc != KMessageBox::Continue) return FALSE;
00198 }
00199 if (aBackup)
00200 {
00201
00202
00203 QString bakName = aFileName;
00204 bakName += '~';
00205 QFile::remove(bakName);
00206 if( !QDir::current().rename(aFileName, bakName) )
00207 {
00208
00209 if (!aVerbose) return FALSE;
00210 rc = KMessageBox::warningContinueCancel(0,
00211 i18n("Failed to make a backup copy of %1.\nContinue anyway?")
00212 .arg(aFileName),
00213 i18n("Save to File"), KStdGuiItem::save() );
00214 if (rc != KMessageBox::Continue) return FALSE;
00215 }
00216 }
00217 }
00218
00219 if (!file.open(IO_Raw|IO_WriteOnly|IO_Truncate))
00220 {
00221 if (aVerbose) switch(file.status())
00222 {
00223 case IO_WriteError:
00224 msgDialog(i18n("Could not write to file:\n%1").arg(aFileName));
00225 break;
00226 case IO_OpenError:
00227 msgDialog(i18n("Could not open file for writing:\n%1")
00228 .arg(aFileName));
00229 break;
00230 default:
00231 msgDialog(i18n("Error while writing file:\n%1").arg(aFileName));
00232 }
00233 return FALSE;
00234 }
00235
00236 writeLen = file.writeBlock(aBuffer, len);
00237
00238 if (writeLen < 0)
00239 {
00240 if (aVerbose)
00241 msgDialog(i18n("Could not write to file:\n%1").arg(aFileName));
00242 return FALSE;
00243 }
00244 else if (writeLen < len)
00245 {
00246 QString msg = i18n("Could only write %1 bytes of %2.")
00247 .arg(writeLen).arg(len);
00248 if (aVerbose)
00249 msgDialog(msg);
00250 return FALSE;
00251 }
00252
00253 return TRUE;
00254 }
00255
00256 KDE_EXPORT bool kCStringToFile(const QCString& aBuffer, const QString &aFileName,
00257 bool aAskIfExists, bool aBackup, bool aVerbose)
00258 {
00259 return kBytesToFile(aBuffer, aBuffer.length(), aFileName, aAskIfExists,
00260 aBackup, aVerbose);
00261 }
00262
00263 KDE_EXPORT bool kByteArrayToFile(const QByteArray& aBuffer, const QString &aFileName,
00264 bool aAskIfExists, bool aBackup, bool aVerbose)
00265 {
00266 return kBytesToFile(aBuffer, aBuffer.size(), aFileName, aAskIfExists,
00267 aBackup, aVerbose);
00268 }
00269
00270
00271 QString checkAndCorrectPermissionsIfPossible( const QString &toCheck,
00272 const bool recursive, const bool wantItReadable,
00273 const bool wantItWritable )
00274 {
00275
00276
00277
00278 QFileInfo fiToCheck(toCheck);
00279 fiToCheck.setCaching(false);
00280 QCString toCheckEnc = QFile::encodeName(toCheck);
00281 QString error;
00282 struct stat statbuffer;
00283
00284 if ( !fiToCheck.exists() ) {
00285 error.append( i18n("%1 does not exist")
00286 .arg(toCheck) + "\n");
00287 }
00288
00289
00290 if ( fiToCheck.isDir() ) {
00291 if ( stat( toCheckEnc,&statbuffer ) != 0 ) {
00292 kdDebug() << "wantItA: Can't read perms of " << toCheck << endl;
00293 }
00294 QDir g( toCheck );
00295 if ( !g.isReadable() ) {
00296 if ( chmod( toCheckEnc, statbuffer.st_mode + S_IXUSR ) != 0 ) {
00297 error.append( i18n("%1 is not accessible and that is "
00298 "unchangeable.").arg(toCheck) + "\n");
00299 } else {
00300 kdDebug() << "Changed access bit for " << toCheck << endl;
00301 }
00302 }
00303 }
00304
00305
00306
00307 if ( fiToCheck.isFile() || fiToCheck.isDir() ) {
00308
00309 if ( !fiToCheck.isReadable() && wantItReadable ) {
00310
00311
00312 if ( stat(toCheckEnc,&statbuffer) != 0 ) {
00313 kdDebug() << "wantItR: Can't read perms of " << toCheck << endl;
00314 }
00315
00316
00317 if ( chmod( toCheckEnc, statbuffer.st_mode + S_IRUSR ) != 0 ) {
00318 error.append( i18n("%1 is not readable and that is unchangeable.")
00319 .arg(toCheck) + "\n");
00320 } else {
00321 kdDebug() << "Changed the read bit for " << toCheck << endl;
00322 }
00323 }
00324
00325 if ( !fiToCheck.isWritable() && wantItWritable ) {
00326
00327
00328 if (stat(toCheckEnc,&statbuffer) != 0) {
00329 kdDebug() << "wantItW: Can't read perms of " << toCheck << endl;
00330 }
00331
00332
00333 if ( chmod (toCheckEnc, statbuffer.st_mode + S_IWUSR ) != 0 ) {
00334 error.append( i18n("%1 is not writable and that is unchangeable.")
00335 .arg(toCheck) + "\n");
00336 } else {
00337 kdDebug() << "Changed the write bit for " << toCheck << endl;
00338 }
00339 }
00340 }
00341
00342
00343
00344 if ( fiToCheck.isDir() && recursive ){
00345 QDir g(toCheck);
00346
00347
00348 if ( !g.isReadable() ){
00349 error.append(i18n("Folder %1 is inaccessible.").arg(toCheck) + "\n");
00350 } else {
00351 const QFileInfoList *list = g.entryInfoList();
00352 QFileInfoListIterator it( *list );
00353 QFileInfo *fi;
00354 while ((fi = it.current()) != 0) {
00355 QString newToCheck = toCheck + "/" + fi->fileName();
00356 QFileInfo fiNewToCheck(newToCheck);
00357 if ( fi->fileName() != "." && fi->fileName() != ".." ) {
00358 error.append ( checkAndCorrectPermissionsIfPossible( newToCheck,
00359 recursive, wantItReadable, wantItWritable) );
00360 }
00361 ++it;
00362 }
00363 }
00364 }
00365 return error;
00366 }
00367
00368 bool checkAndCorrectPermissionsIfPossibleWithErrorHandling( QWidget *parent,
00369 const QString &toCheck, const bool recursive, const bool wantItReadable,
00370 const bool wantItWritable )
00371 {
00372 QString error = checkAndCorrectPermissionsIfPossible(toCheck, recursive,
00373 wantItReadable, wantItWritable);
00374
00375
00376
00377 if ( !error.isEmpty() ) {
00378 kdDebug() << "checkPermissions found:" << error << endl;
00379 KMessageBox::detailedSorry(parent,
00380 i18n("Some files or folders do not have "
00381 "the right permissions, please correct them "
00382 "manually."),
00383 error, i18n("Permissions Check"), false);
00384 return false;
00385 } else {
00386 return true;
00387 }
00388 }
00389
00390 }