• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdeutils
  • Sitemap
  • Contact Us
 

kdf

disklist.cpp

Go to the documentation of this file.
00001 /*
00002  * disklist.cpp
00003  *
00004  * Copyright (c) 1999 Michael Kropfberger <michael.kropfberger@gmx.net>
00005  *
00006  * Requires the Qt widget libraries, available at no cost at
00007  * http://www.troll.no/
00008  *
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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   * constructor
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    // BackgroundProcesses ****************************************
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   * destructor
00070 **/
00071 DiskList::~DiskList()
00072 {
00073    kDebug() ;
00074 }
00075 
00079 void DiskList::setUpdatesDisabled(bool disable)
00080 {
00081     updatesDisabled = disable;
00082 }
00083 
00084 /***************************************************************************
00085   * saves the KConfig for special mount/umount scripts
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   * reads the KConfig for special mount/umount scripts
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                // give up and not process anything else because I'm too lazy
00148                // to implement other escapes
00149                rc += '\\';
00150                rc += s[i];
00151             }
00152         } else {
00153             rc += s[i];
00154         }
00155     }
00156 return rc;
00157 }
00158 
00159 /***************************************************************************
00160   * tries to figure out the possibly mounted fs
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     //disks->clear(); // ############
00175 
00176     while (! t.atEnd()) {
00177       s=t.readLine();
00178       s=s.simplified();
00179       if ( (!s.isEmpty() ) && (s.indexOf(DELIMITER)!=0) ) {
00180                // not empty or commented out by '#'
00181     //  kDebug() << "GOT: [" << s << "]" ;
00182     disk = new DiskEntry();// Q_CHECK_PTR(disk);
00183         disk->setMounted(false);
00184         disk->setDeviceName(expandEscapes(s.left(s.indexOf(BLANK))));
00185             s=s.remove(0,s.indexOf(BLANK)+1 );
00186         //  kDebug() << "    deviceName:    [" << disk->deviceName() << "]" ;
00187 #ifdef _OS_SOLARIS_
00188             //device to fsck
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         //kDebug() << "    MountPoint:    [" << disk->mountPoint() << "]" ;
00194         //kDebug() << "    Icon:          [" << disk->iconName() << "]" ;
00195          disk->setFsType(s.left(s.indexOf(BLANK)) );
00196             s=s.remove(0,s.indexOf(BLANK)+1 );
00197         //kDebug() << "    FS-Type:       [" << disk->fsType() << "]" ;
00198          disk->setMountOptions(s.left(s.indexOf(BLANK)) );
00199             s=s.remove(0,s.indexOf(BLANK)+1 );
00200         //kDebug() << "    Mount-Options: [" << disk->mountOptions() << "]" ;
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       } //if not empty
00213     } //while
00214     f.close();
00215   } //if f.open
00216 
00217   loadSettings(); //to get the mountCommands
00218 
00219   //  kDebug() << "DiskList::readFSTAB DONE" ;
00220   return 1;
00221 }
00222 
00223 
00224 /***************************************************************************
00225   * reads the df-commands results
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   * is called, when the df-command has finished
00253 **/
00254 void DiskList::dfDone()
00255 {
00256   kDebug() ;
00257 
00258   if (updatesDisabled)
00259       return; //Don't touch the data for now..
00260 
00261   readingDFStdErrOut=true;
00262   for ( DiskEntry *disk=disks->first(); disk != 0; disk=disks->next() )
00263     disk->setMounted(false);  // set all devs unmounted
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))      // devicename was too long, rest in next line
00279     if ( !t.atEnd() ) {       // just appends the next line
00280             v=t.readLine();
00281             s=s.append(v );
00282             s=s.simplified();
00283         //kDebug() << "SPECIAL GOT: [" << s << "]" ;
00284      }//if silly linefeed
00285 
00286       //kDebug() << "EFFECTIVELY GOT " << s.length() << " chars: [" << s << "]" ;
00287 
00288       disk->setDeviceName(s.left(s.indexOf(BLANK)) );
00289       s=s.remove(0,s.indexOf(BLANK)+1 );
00290       //kDebug() << "    DeviceName:    [" << disk->deviceName() << "]" ;
00291 
00292       if (NO_FS_TYPE) {
00293     //kDebug() << "THERE IS NO FS_TYPE_FIELD!" ;
00294          disk->setFsType("?");
00295       } else {
00296          disk->setFsType(s.left(s.indexOf(BLANK)) );
00297          s=s.remove(0,s.indexOf(BLANK)+1 );
00298       };
00299       //kDebug() << "    FS-Type:       [" << disk->fsType() << "]" ;
00300       //kDebug() << "    Icon:          [" << disk->iconName() << "]" ;
00301 
00302       u=s.left(s.indexOf(BLANK));
00303       disk->setKBSize(u.toInt() );
00304       s=s.remove(0,s.indexOf(BLANK)+1 );
00305       //kDebug() << "    Size:       [" << disk->kBSize() << "]" ;
00306 
00307       u=s.left(s.indexOf(BLANK));
00308       disk->setKBUsed(u.toInt() );
00309       s=s.remove(0,s.indexOf(BLANK)+1 );
00310       //kDebug() << "    Used:       [" << disk->kBUsed() << "]" ;
00311 
00312       u=s.left(s.indexOf(BLANK));
00313       disk->setKBAvail(u.toInt() );
00314       s=s.remove(0,s.indexOf(BLANK)+1 );
00315       //kDebug() << "    Avail:       [" << disk->kBAvail() << "]" ;
00316 
00317 
00318       s=s.remove(0,s.indexOf(BLANK)+1 );  // delete the capacity 94%
00319       disk->setMountPoint(s);
00320       //kDebug() << "    MountPoint:       [" << disk->mountPoint() << "]" ;
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);    // its now mounted (df lists only mounted)
00331     replaceDeviceEntry(disk);
00332       } else
00333     delete disk;
00334 
00335     }//if not header
00336   }//while further lines available
00337 
00338   readingDFStdErrOut=false;
00339   loadSettings(); //to get the mountCommands
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   * updates or creates a new DiskEntry in the KDFList and TabListBox
00362 **/
00363 void DiskList::replaceDeviceEntry(DiskEntry *disk)
00364 {
00365   //kDebug() << disk->deviceRealName() << " " << disk->realMountPoint() ;
00366 
00367   //
00368   // The 'disks' may already already contain the 'disk'. If it do
00369   // we will replace some data. Otherwise 'disk' will be added to the list
00370   //
00371 
00372   //
00373   // 1999-27-11 Espen Sand:
00374   // I can't get find() to work. The Disks::compareItems(..) is
00375   // never called.
00376   //
00377   //int pos=disks->find(disk);
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     // no matching entry found for mounted disk
00400     if ((disk->fsType() == "?") || (disk->fsType() == "cachefs")) {
00401       //search for fitting cachefs-entry in static /etc/vfstab-data
00402       DiskEntry* olddisk = disks->first();
00403       while (olddisk != 0) {
00404         int p;
00405         // cachefs deviceNames have no / behind the host-column
00406     // eg. /cache/cache/.cfs_mnt_points/srv:_home_jesus
00407     //                                      ^    ^
00408         QString odiskName = olddisk->deviceName();
00409         int ci=odiskName.indexOf(':'); // goto host-column
00410         while ((ci =odiskName.indexOf('/',ci)) > 0) {
00411            odiskName.replace(ci,1,"_");
00412         }//while
00413         // check if there is something that is exactly the tail
00414     // eg. [srv:/tmp3] is exact tail of [/cache/.cfs_mnt_points/srv:_tmp3]
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(); //store the actual position
00422              disk->setDeviceName(olddisk->deviceName());
00423              olddisk=0;
00424     } else
00425           olddisk=disks->next();
00426       }// while
00427     }// if fsType == "?" or "cachefs"
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) {  // replace
00439       DiskEntry * olddisk = disks->at(pos);
00440       if ( (olddisk->mountOptions().contains("user")) &&
00441            ( disk->mountOptions().contains("user")) ) {
00442           // add "user" option to new diskEntry
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       // Same device name, but maybe one is a symlink and the other is its target
00452       // Keep the shorter one then, /dev/hda1 looks better than /dev/ide/host0/bus0/target0/lun0/part1
00453       // but redefine "shorter" to be the number of slashes in the path as a count on characters
00454       // breaks legitimate symlinks created by udev
00455       if ( disk->deviceName().count( '/' ) > olddisk->deviceName().count( '/' ) )
00456           disk->setDeviceName(olddisk->deviceName());
00457 
00458       //FStab after an older DF ... needed for critFull
00459       //so the DF-KBUsed survive a FStab lookup...
00460       //but also an unmounted disk may then have a kbused set...
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); // really deletes old one
00475       disks->insert(pos,disk);
00476   } else {
00477     disks->append(disk);
00478   }//if
00479 
00480 }
00481 
00482 #include "disklist.moc"
00483 
00484 
00485 
00486 
00487 
00488 

kdf

Skip menu "kdf"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

kdeutils

Skip menu "kdeutils"
  • ark
  • kcalc
  • kcharselect
  • kdessh
  • kdf
  • kfloppy
  • kgpg
  • ktimer
  • kwallet
  • okteta
  • printer-applet
  • superkaramba
  • sweeper
Generated for kdeutils by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal