kdf
disklist.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "disklist.h"
00025
00026 #include <math.h>
00027 #include <stdlib.h>
00028 #include <kdebug.h>
00029
00030 #include <QtCore/QTextStream>
00031 #include <kglobal.h>
00032 #include <kconfiggroup.h>
00033 #include <kdefakes.h>
00034 #include <kprocess.h>
00035
00036 #define BLANK ' '
00037 #define DELIMITER '#'
00038 #define FULL_PERCENT 95.0
00039
00040
00041
00042
00043 DiskList::DiskList(QObject *parent)
00044 : QObject(parent), dfProc(new KProcess(this))
00045 {
00046 kDebug() ;
00047
00048 updatesDisabled = false;
00049
00050 if (NO_FS_TYPE) {
00051 kDebug() << "df gives no FS_TYPE" ;
00052 }
00053
00054 disks = new Disks;
00055 disks->setAutoDelete(true);
00056
00057
00058 dfProc->setOutputChannelMode(KProcess::MergedChannels);
00059 connect(dfProc,SIGNAL(finished(int, QProcess::ExitStatus) ),
00060 this, SLOT(dfDone() ) );
00061
00062 readingDFStdErrOut=false;
00063 config = KGlobal::config();
00064 loadSettings();
00065 }
00066
00067
00068
00069
00070
00071 DiskList::~DiskList()
00072 {
00073 kDebug() ;
00074 }
00075
00079 void DiskList::setUpdatesDisabled(bool disable)
00080 {
00081 updatesDisabled = disable;
00082 }
00083
00084
00085
00086
00087 void DiskList::applySettings()
00088 {
00089 kDebug() ;
00090
00091 KConfigGroup group(config, "DiskList");
00092 QString key;
00093 DiskEntry *disk;
00094 for (disk=disks->first();disk!=0;disk=disks->next()) {
00095 key = QLatin1String("Mount") + SEPARATOR + disk->deviceName() + SEPARATOR + disk->mountPoint();
00096 group.writePathEntry(key,disk->mountCommand());
00097
00098 key = QLatin1String("Umount") + SEPARATOR + disk->deviceName() + SEPARATOR + disk->mountPoint();
00099 group.writePathEntry(key,disk->umountCommand());
00100
00101 key = QLatin1String("Icon") + SEPARATOR + disk->deviceName() + SEPARATOR + disk->mountPoint();
00102 group.writePathEntry(key,disk->realIconName());
00103 }
00104 group.sync();
00105 }
00106
00107
00108
00109
00110
00111 void DiskList::loadSettings()
00112 {
00113 kDebug() ;
00114
00115 const KConfigGroup group(config, "DiskList");
00116 QString key;
00117 DiskEntry *disk;
00118 for (disk=disks->first();disk!=0;disk=disks->next()) {
00119 key = QLatin1String("Mount") + SEPARATOR + disk->deviceName() + SEPARATOR + disk->mountPoint();
00120 disk->setMountCommand(group.readPathEntry(key, QString()));
00121
00122 key = QLatin1String("Umount") + SEPARATOR + disk->deviceName() + SEPARATOR + disk->mountPoint();
00123 disk->setUmountCommand(group.readPathEntry(key, QString()));
00124
00125 key = QLatin1String("Icon") + SEPARATOR + disk->deviceName() + SEPARATOR + disk->mountPoint();
00126 QString icon=group.readPathEntry(key, QString());
00127 if (!icon.isEmpty()) disk->setIconName(icon);
00128 }
00129 }
00130
00131
00132 static QString expandEscapes(const QString& s) {
00133 QString rc;
00134 for (int i = 0; i < s.length(); i++) {
00135 if (s[i] == '\\') {
00136 i++;
00137 QChar str=s.at(i);
00138 if( str == '\\')
00139 rc += '\\';
00140 else if( str == '0')
00141 {
00142 rc += static_cast<char>(s.mid(i,3).toInt(0, 8));
00143 i += 2;
00144 }
00145 else
00146 {
00147
00148
00149 rc += '\\';
00150 rc += s[i];
00151 }
00152 } else {
00153 rc += s[i];
00154 }
00155 }
00156 return rc;
00157 }
00158
00159
00160
00161
00162 int DiskList::readFSTAB()
00163 {
00164 kDebug() ;
00165
00166 if (readingDFStdErrOut || (dfProc->state() != QProcess::NotRunning)) return -1;
00167
00168 QFile f(FSTAB);
00169 if ( f.open(QIODevice::ReadOnly) ) {
00170 QTextStream t (&f);
00171 QString s;
00172 DiskEntry *disk;
00173
00174
00175
00176 while (! t.atEnd()) {
00177 s=t.readLine();
00178 s=s.simplified();
00179 if ( (!s.isEmpty() ) && (s.indexOf(DELIMITER)!=0) ) {
00180
00181
00182 disk = new DiskEntry();
00183 disk->setMounted(false);
00184 disk->setDeviceName(expandEscapes(s.left(s.indexOf(BLANK))));
00185 s=s.remove(0,s.indexOf(BLANK)+1 );
00186
00187 #ifdef _OS_SOLARIS_
00188
00189 s=s.remove(0,s.indexOf(BLANK)+1 );
00190 #endif
00191 disk->setMountPoint(expandEscapes(s.left(s.indexOf(BLANK))));
00192 s=s.remove(0,s.indexOf(BLANK)+1 );
00193
00194
00195 disk->setFsType(s.left(s.indexOf(BLANK)) );
00196 s=s.remove(0,s.indexOf(BLANK)+1 );
00197
00198 disk->setMountOptions(s.left(s.indexOf(BLANK)) );
00199 s=s.remove(0,s.indexOf(BLANK)+1 );
00200
00201 if ( (disk->deviceName() != "none")
00202 && (disk->fsType() != "swap")
00203 && (disk->fsType() != "sysfs")
00204 && (disk->mountPoint() != "/dev/swap")
00205 && (disk->mountPoint() != "/dev/pts")
00206 && (disk->mountPoint() != "/dev/shm")
00207 && (!disk->mountPoint().contains("/proc") ) )
00208 replaceDeviceEntry(disk);
00209 else
00210 delete disk;
00211
00212 }
00213 }
00214 f.close();
00215 }
00216
00217 loadSettings();
00218
00219
00220 return 1;
00221 }
00222
00223
00224
00225
00226
00227 int DiskList::readDF()
00228 {
00229 kDebug() ;
00230
00231 if (readingDFStdErrOut || (dfProc->state() != QProcess::NotRunning)) return -1;
00232
00233 dfProc->clearProgram();
00234
00235 QStringList dfenv;
00236 dfenv << "LANG=en_US";
00237 dfenv << "LC_ALL=en_US";
00238 dfenv << "LC_MESSAGES=en_US";
00239 dfenv << "LC_TYPE=en_US";
00240 dfenv << "LANGUAGE=en_US";
00241 dfenv << "LC_ALL=POSIX";
00242 dfProc->setEnvironment(dfenv);
00243 (*dfProc) << DF_COMMAND << DF_ARGS;
00244 dfProc->start();
00245 if (!dfProc->waitForStarted(-1))
00246 qFatal("%s", qPrintable(i18n("could not execute [%1]", QLatin1String(DF_COMMAND))));
00247 return 1;
00248 }
00249
00250
00251
00252
00253
00254 void DiskList::dfDone()
00255 {
00256 kDebug() ;
00257
00258 if (updatesDisabled)
00259 return;
00260
00261 readingDFStdErrOut=true;
00262 for ( DiskEntry *disk=disks->first(); disk != 0; disk=disks->next() )
00263 disk->setMounted(false);
00264
00265 QString dfStringErrOut = QString::fromLatin1(dfProc->readAllStandardOutput());
00266 QTextStream t (&dfStringErrOut, QIODevice::ReadOnly);
00267 QString s=t.readLine();
00268 if ( ( s.isEmpty() ) || ( s.left(10) != "Filesystem" ) )
00269 qFatal("Error running df command... got [%s]",qPrintable(s));
00270 while ( !t.atEnd() ) {
00271 QString u,v;
00272 DiskEntry *disk;
00273 s=t.readLine();
00274 s=s.simplified();
00275 if ( !s.isEmpty() ) {
00276 disk = new DiskEntry(); Q_CHECK_PTR(disk);
00277
00278 if (!s.contains(BLANK))
00279 if ( !t.atEnd() ) {
00280 v=t.readLine();
00281 s=s.append(v );
00282 s=s.simplified();
00283
00284 }
00285
00286
00287
00288 disk->setDeviceName(s.left(s.indexOf(BLANK)) );
00289 s=s.remove(0,s.indexOf(BLANK)+1 );
00290
00291
00292 if (NO_FS_TYPE) {
00293
00294 disk->setFsType("?");
00295 } else {
00296 disk->setFsType(s.left(s.indexOf(BLANK)) );
00297 s=s.remove(0,s.indexOf(BLANK)+1 );
00298 };
00299
00300
00301
00302 u=s.left(s.indexOf(BLANK));
00303 disk->setKBSize(u.toInt() );
00304 s=s.remove(0,s.indexOf(BLANK)+1 );
00305
00306
00307 u=s.left(s.indexOf(BLANK));
00308 disk->setKBUsed(u.toInt() );
00309 s=s.remove(0,s.indexOf(BLANK)+1 );
00310
00311
00312 u=s.left(s.indexOf(BLANK));
00313 disk->setKBAvail(u.toInt() );
00314 s=s.remove(0,s.indexOf(BLANK)+1 );
00315
00316
00317
00318 s=s.remove(0,s.indexOf(BLANK)+1 );
00319 disk->setMountPoint(s);
00320
00321
00322 if ( (disk->kBSize() > 0)
00323 && (disk->deviceName() != "none")
00324 && (disk->fsType() != "swap")
00325 && (disk->fsType() != "sysfs")
00326 && (disk->mountPoint() != "/dev/swap")
00327 && (disk->mountPoint() != "/dev/pts")
00328 && (disk->mountPoint() != "/dev/shm")
00329 && (!disk->mountPoint().contains("/proc") ) ) {
00330 disk->setMounted(true);
00331 replaceDeviceEntry(disk);
00332 } else
00333 delete disk;
00334
00335 }
00336 }
00337
00338 readingDFStdErrOut=false;
00339 loadSettings();
00340 emit readDFDone();
00341 }
00342
00343
00344 void DiskList::deleteAllMountedAt(const QString &mountpoint)
00345 {
00346 kDebug() ;
00347
00348
00349 for ( DiskEntry *item = disks->first(); item; )
00350 {
00351 if (item->mountPoint() == mountpoint ) {
00352 kDebug() << "delete " << item->deviceName() ;
00353 disks->remove(item);
00354 item = disks->current();
00355 } else
00356 item = disks->next();
00357 }
00358 }
00359
00360
00361
00362
00363 void DiskList::replaceDeviceEntry(DiskEntry *disk)
00364 {
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 QString deviceRealName = disk->deviceRealName();
00380 QString realMountPoint = disk->realMountPoint();
00381
00382 int pos = -1;
00383 for( u_int i=0; i<disks->count(); i++ )
00384 {
00385 DiskEntry *item = disks->at(i);
00386 int res = deviceRealName.compare( item->deviceRealName() );
00387 if( res == 0 )
00388 {
00389 res = realMountPoint.compare( item->realMountPoint() );
00390 }
00391 if( res == 0 )
00392 {
00393 pos = i;
00394 break;
00395 }
00396 }
00397
00398 if ((pos == -1) && (disk->mounted()) )
00399
00400 if ((disk->fsType() == "?") || (disk->fsType() == "cachefs")) {
00401
00402 DiskEntry* olddisk = disks->first();
00403 while (olddisk != 0) {
00404 int p;
00405
00406
00407
00408 QString odiskName = olddisk->deviceName();
00409 int ci=odiskName.indexOf(':');
00410 while ((ci =odiskName.indexOf('/',ci)) > 0) {
00411 odiskName.replace(ci,1,"_");
00412 }
00413
00414
00415 if ( ( (p=disk->deviceName().lastIndexOf(odiskName
00416 ,disk->deviceName().length()) )
00417 != -1)
00418 && (p + odiskName.length()
00419 == disk->deviceName().length()) )
00420 {
00421 pos = disks->at();
00422 disk->setDeviceName(olddisk->deviceName());
00423 olddisk=0;
00424 } else
00425 olddisk=disks->next();
00426 }
00427 }
00428
00429
00430 #ifdef NO_FS_TYPE
00431 if (pos != -1) {
00432 DiskEntry * olddisk = disks->at(pos);
00433 if (olddisk)
00434 disk->setFsType(olddisk->fsType());
00435 }
00436 #endif
00437
00438 if (pos != -1) {
00439 DiskEntry * olddisk = disks->at(pos);
00440 if ( (olddisk->mountOptions().contains("user")) &&
00441 ( disk->mountOptions().contains("user")) ) {
00442
00443 QString s=disk->mountOptions();
00444 if (s.length()>0) s.append(",");
00445 s.append("user");
00446 disk->setMountOptions(s);
00447 }
00448 disk->setMountCommand(olddisk->mountCommand());
00449 disk->setUmountCommand(olddisk->umountCommand());
00450
00451
00452
00453
00454
00455 if ( disk->deviceName().count( '/' ) > olddisk->deviceName().count( '/' ) )
00456 disk->setDeviceName(olddisk->deviceName());
00457
00458
00459
00460
00461 if ( (olddisk->mounted()) && (!disk->mounted()) ) {
00462 disk->setKBSize(olddisk->kBSize());
00463 disk->setKBUsed(olddisk->kBUsed());
00464 disk->setKBAvail(olddisk->kBAvail());
00465 }
00466 if ( (olddisk->percentFull() != -1) &&
00467 (olddisk->percentFull() < FULL_PERCENT) &&
00468 (disk->percentFull() >= FULL_PERCENT) ) {
00469 kDebug() << "Device " << disk->deviceName()
00470 << " is critFull! " << olddisk->percentFull()
00471 << "--" << disk->percentFull() << endl;
00472 emit criticallyFull(disk);
00473 }
00474 disks->remove(pos);
00475 disks->insert(pos,disk);
00476 } else {
00477 disks->append(disk);
00478 }
00479
00480 }
00481
00482 #include "disklist.moc"
00483
00484
00485
00486
00487
00488