diff options
Diffstat (limited to 'krusader/MountMan/kmountman.cpp')
-rw-r--r-- | krusader/MountMan/kmountman.cpp | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/krusader/MountMan/kmountman.cpp b/krusader/MountMan/kmountman.cpp new file mode 100644 index 0000000..7728fc4 --- /dev/null +++ b/krusader/MountMan/kmountman.cpp @@ -0,0 +1,327 @@ +/*************************************************************************** + kmountman.cpp + ------------------- +copyright : (C) 2000 by Shie Erlich & Rafi Yanai +e-mail : krusader@users.sourceforge.net +web site : http://krusader.sourceforge.net +--------------------------------------------------------------------------- + +A + +db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. +88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D +88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' +88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b +88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. +YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD + + S o u r c e F i l e + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + + +#include <sys/param.h> +#include <time.h> +#include "kmountman.h" +// KDE includes +#include <kmessagebox.h> +#include <kprocess.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kdebug.h> + +// Krusader includes +#include "../krusader.h" +#include "../defaults.h" +#include "../Dialogs/krdialogs.h" +#include "../krservices.h" +#include "kmountmangui.h" +#include <unistd.h> +#include "../Dialogs/krprogress.h" +#include "../VFS/krpermhandler.h" + +#ifdef _OS_SOLARIS_ +#define FSTAB "/etc/vfstab" +#else +#define FSTAB "/etc/fstab" +#endif + +static int __delayedIdx; // ugly: pass the processEvents deadlock + +KMountMan::KMountMan() : QObject(), Operational( false ), waiting(false), mountManGui( 0 ) { + _actions = 0L; + + // added as a precaution, although we use kde services now + if( !KrServices::cmdExist( "df" ) || !KrServices::cmdExist( "mount" ) ) { + Operational = false; + } else { + Operational = true; + } + + // list of FS that we don't manage at all + invalid_fs << "swap" << "/dev/pts" << "tmpfs" << "devpts" << "sysfs" << "rpc_pipefs" << "usbfs" << "binfmt_misc"; +#if defined(BSD) + invalid_fs << "procfs"; +#else + invalid_fs << "proc"; +#endif + + // list of FS that we don't allow to mount/unmount + nonmount_fs << "supermount"; + { + KConfigGroupSaver saver(krConfig, "Advanced"); + QStringList nonmount = QStringList::split(",", krConfig->readEntry("Nonmount Points", _NonMountPoints)); + nonmount_fs_mntpoint += nonmount; + // simplify the white space + for ( QStringList::Iterator it = nonmount_fs_mntpoint.begin(); it != nonmount_fs_mntpoint.end(); ++it ) { + *it = (*it).simplifyWhiteSpace(); + } + } + +} + +KMountMan::~KMountMan() {} + +bool KMountMan::invalidFilesystem(QString type) { + return (invalid_fs.contains(type) > 0); +} + +// this is an ugly hack, but type can actually be a mountpoint. oh well... +bool KMountMan::nonmountFilesystem(QString type, QString mntPoint) { + return((nonmount_fs.contains(type) > 0) || (nonmount_fs_mntpoint.contains(mntPoint) > 0)); +} + +void KMountMan::mainWindow() { + mountManGui = new KMountManGUI(); + delete mountManGui; /* as KMountManGUI is modal, we can now delete it */ + mountManGui = 0; /* for sanity */ +} + +KMountPoint *KMountMan::findInListByMntPoint(KMountPoint::List &lst, QString value) { + KMountPoint *m; + for (KMountPoint::List::iterator it = lst.begin(); it != lst.end(); ++it) { + m = *it; + if (m->mountPoint() == value) + return m; + } + + return 0; +} + +void KMountMan::jobResult(KIO::Job *job) { + waiting = false; + if ( job->error() ) + job->showErrorDialog( 0 ); +} + +void KMountMan::mount( QString mntPoint, bool blocking ) { + KMountPoint::List possible = KMountPoint::possibleMountPoints(KMountPoint::NeedMountOptions); + KMountPoint *m = findInListByMntPoint(possible, mntPoint); + if (!m) return; + if (blocking) + waiting = true; // prepare to block + KIO::SimpleJob *job = KIO::mount(false, m->mountType().local8Bit(), m->mountedFrom(), m->mountPoint(), false); + new KrProgress(job); + connect(job, SIGNAL(result(KIO::Job* )), this, SLOT(jobResult(KIO::Job* ))); + while (blocking && waiting) { + qApp->processEvents(); + usleep( 1000 ); + } +} + +void KMountMan::unmount( QString mntPoint, bool blocking ) { + if (blocking) + waiting = true; // prepare to block + KIO::SimpleJob *job = KIO::unmount(mntPoint, false); + new KrProgress(job); + connect(job, SIGNAL(result(KIO::Job* )), this, SLOT(jobResult(KIO::Job* ))); + while (blocking && waiting) { + qApp->processEvents(); + usleep( 1000 ); + } +} + +KMountMan::mntStatus KMountMan::getStatus( QString mntPoint ) { + KMountPoint::List::iterator it; + KMountPoint *m; + + // 1: is it already mounted + KMountPoint::List current = KMountPoint::currentMountPoints(); + m = findInListByMntPoint(current, mntPoint); + if (m) + return MOUNTED; + + // 2: is it a mount point but not mounted? + KMountPoint::List possible = KMountPoint::possibleMountPoints(); + m = findInListByMntPoint(possible, mntPoint); + if (m) + return NOT_MOUNTED; + + // 3: unknown + return DOESNT_EXIST; +} + + +void KMountMan::toggleMount( QString mntPoint ) { + mntStatus status = getStatus(mntPoint); + switch (status) { + case MOUNTED: + unmount(mntPoint); + break; + case NOT_MOUNTED: + mount(mntPoint); + break; + case DOESNT_EXIST: + // do nothing: no-op to make the compiler quiet ;-) + break; + } +} + +void KMountMan::autoMount( QString path ) { + if ( getStatus( path ) == NOT_MOUNTED ) + mount( path ); +} + +void KMountMan::eject( QString mntPoint ) { + KShellProcess proc; + proc << KrServices::fullPathName( "eject" ) << "'" + mntPoint + "'"; + proc.start( KProcess::Block ); + if ( !proc.normalExit() || proc.exitStatus() != 0 ) // if we failed with eject + KMessageBox::information( 0, i18n( "Error ejecting device! You need to have 'eject' in your path." ), i18n( "Error" ), "CantExecuteEjectWarning" ); +} + +// returns true if the path is an ejectable mount point (at the moment CDROM and DVD) +bool KMountMan::ejectable( QString path ) { +#if !defined(BSD) && !defined(_OS_SOLARIS_) + KMountPoint::List possible = KMountPoint::possibleMountPoints(); + KMountPoint *m = findInListByMntPoint(possible, path); + if (m && (m->mountType()=="iso9660" || m->mountedFrom().left(7)=="/dev/cd" || m->mountedFrom().left(8)=="/dev/dvd")) + return KrServices::cmdExist( "eject" ); +#endif + + return false; +} + + +// a mountMan special version of KIO::convertSize, which deals +// with large filesystems ==> >4GB, it actually recieve size in +// a minimum block of 1024 ==> data is KB not bytes +QString KMountMan::convertSize( KIO::filesize_t size ) { + float fsize; + QString s; + // Tera-byte + if ( size >= 1073741824 ) { + fsize = ( float ) size / ( float ) 1073741824; + if ( fsize > 1024 ) // no name for something bigger than tera byte + // let's call it Zega-Byte, who'll ever find out? :-) + s = i18n( "%1 ZB" ).arg( KGlobal::locale() ->formatNumber( fsize / ( float ) 1024, 1 ) ); + else + s = i18n( "%1 TB" ).arg( KGlobal::locale() ->formatNumber( fsize, 1 ) ); + } + // Giga-byte + else if ( size >= 1048576 ) { + fsize = ( float ) size / ( float ) 1048576; + s = i18n( "%1 GB" ).arg( KGlobal::locale() ->formatNumber( fsize, 1 ) ); + } + // Mega-byte + else if ( size > 1024 ) { + fsize = ( float ) size / ( float ) 1024; + s = i18n( "%1 MB" ).arg( KGlobal::locale() ->formatNumber( fsize, 1 ) ); + } + // Kilo-byte + else { + fsize = ( float ) size; + s = i18n( "%1 KB" ).arg( KGlobal::locale() ->formatNumber( fsize, 0 ) ); + } + return s; +} + + +// populate the pop-up menu of the mountman tool-button with actions +void KMountMan::quickList() { + if ( !Operational ) { + KMessageBox::error( 0, i18n( "MountMan is not operational. Sorry" ) ); + return ; + } + + // clear the popup menu + ( ( KToolBarPopupAction* ) krMountMan ) ->popupMenu() ->clear(); + + // create lists of current and possible mount points + KMountPoint::List current = KMountPoint::currentMountPoints(); + KMountPoint::List possible = KMountPoint::possibleMountPoints(); + + // create a popupmenu, displaying mountpoints with possible actions + // also, populate a small array with the actions + if ( _actions ) + delete[] _actions; + _actions = new QString[ possible.size() ]; + + KMountPoint::List::iterator it; + KMountPoint *m; + int idx; + for ( it = possible.begin(), idx = 0; it != possible.end(); ++it, ++idx ) { + m = *it; + // skip nonmountable file systems + if (nonmountFilesystem(m->mountType(), m->mountPoint()) || invalidFilesystem(m->mountType())) + continue; + // does the mountpoint exist in current list? if so, it can only + // be umounted, otherwise, it can be mounted + bool needUmount = false; + KMountPoint::List::iterator otherIt; + for ( otherIt = current.begin(); otherIt != current.end(); ++otherIt ) { + if ( ( *otherIt ) ->mountPoint() == m->mountPoint() ) { // found it, in needs umount + needUmount = true; + break; + } + } + // add the item to the menu + _actions[ idx ] = QString( needUmount ? "_U_" : "_M_" ) + m->mountPoint(); + QString text = QString( ( needUmount ? i18n( "Unmount" ) : i18n( "Mount" ) ) ) + " " + m->mountPoint() + + " (" + m->mountedFrom() + ")"; + + + ( ( KToolBarPopupAction* ) krMountMan ) ->popupMenu() ->insertItem( text, idx ); + } + connect( ( ( KToolBarPopupAction* ) krMountMan ) ->popupMenu(), SIGNAL( activated( int ) ), + this, SLOT( delayedPerformAction( int ) ) ); + +} + +void KMountMan::delayedPerformAction( int idx ) { + __delayedIdx = idx; + QTimer::singleShot(0, this, SLOT(performAction(int))); +} + +void KMountMan::performAction( int idx ) { + while ( qApp->hasPendingEvents() ) + qApp->processEvents(); + + // ugly !!! take idx from the value put there by delayedPerformAction so + // as to NOT DIE because of a processEvents deadlock!!! @#$@!@ + idx = __delayedIdx; + + if ( idx < 0 ) + return ; + bool domount = _actions[ idx ].left( 3 ) == "_M_"; + QString mountPoint = _actions[ idx ].mid( 3 ); + if ( !domount ) { // umount + unmount( mountPoint); + } else { // mount + mount( mountPoint); + } + + // free memory + delete[] _actions; + _actions = 0L; + disconnect( ( ( KToolBarPopupAction* ) krMountMan ) ->popupMenu(), SIGNAL( activated( int ) ), 0, 0 ); +} + +#include "kmountman.moc" |