summaryrefslogtreecommitdiffstats
path: root/kfloppy/format.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kfloppy/format.cpp')
-rw-r--r--kfloppy/format.cpp996
1 files changed, 996 insertions, 0 deletions
diff --git a/kfloppy/format.cpp b/kfloppy/format.cpp
new file mode 100644
index 0000000..6d76de3
--- /dev/null
+++ b/kfloppy/format.cpp
@@ -0,0 +1,996 @@
+/*
+
+ This file is part of the KFloppy program, part of the KDE project
+
+ Copyright (C) 2002 Adriaan de Groot <groot@kde.org>
+ Copyright (C) 2004, 2005 Nicolas GOUTTE <goutte@kde.org>
+
+ 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, version 2.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <qtimer.h>
+#include <qregexp.h>
+
+#include <klocale.h>
+#include <kprocess.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+
+#include "format.h"
+
+static QString extPath = QString::null;
+
+/* static */ QString findExecutable(const QString &e)
+{
+ if (extPath.isEmpty())
+ {
+ QString path = getenv("PATH");
+ if (!path.isEmpty()) path.append(":");
+ path.append("/usr/sbin:/sbin");
+ extPath = path;
+ }
+
+ return KGlobal::dirs()->findExe(e, extPath);
+}
+
+
+
+KFAction::KFAction(QObject *parent) :
+ QObject(parent)
+{
+ DEBUGSETUP;
+}
+
+KFAction::~KFAction()
+{
+ DEBUGSETUP;
+ quit();
+}
+
+/* slot */ void KFAction::quit()
+{
+ DEBUGSETUP;
+}
+
+/* slot */ void KFAction::exec()
+{
+ DEBUGSETUP;
+}
+
+class KFActionQueue_p
+{
+public:
+ QPtrList<KFAction> list;
+} ;
+
+KFActionQueue::KFActionQueue(QObject *parent) :
+ KFAction(parent),
+ d(new KFActionQueue_p)
+{
+ DEBUGSETUP;
+ d->list.setAutoDelete(true);
+}
+
+KFActionQueue::~KFActionQueue()
+{
+ DEBUGSETUP;
+ delete d;
+}
+
+void KFActionQueue::queue(KFAction *p)
+{
+ DEBUGSETUP;
+
+ d->list.append(p);
+ DEBUGS(p->name());
+}
+
+/* virtual */ void KFActionQueue::exec()
+{
+ DEBUGSETUP;
+
+ actionDone(0L,true);
+}
+
+/* slot */ void KFActionQueue::actionDone(KFAction *p,bool success)
+{
+ DEBUGSETUP;
+
+ if (p)
+ {
+ if (d->list.first()==p)
+ {
+ d->list.removeFirst();
+ // delete p; /* auto-delete */
+ }
+ else
+ {
+ DEBUGS( "Strange pointer received.");
+ emit done(this,false);
+ return;
+ }
+ }
+ else
+ {
+ DEBUGS("Starting action queue.");
+ }
+
+ if (!success)
+ {
+ DEBUGS("Action failed.");
+ emit done(this,false);
+ return;
+ }
+
+ KFAction *next = d->list.first();
+ if (!next)
+ {
+ emit done(this,true);
+ }
+ else
+ {
+ kdDebug(KFAREA) << "Running action " << next->name() << endl;
+ QObject::connect(next,SIGNAL(done(KFAction *,bool)),
+ this,SLOT(actionDone(KFAction *,bool)));
+ // Propagate signals
+ QObject::connect(next,SIGNAL(status(const QString &,int)),
+ this,SIGNAL(status(const QString &,int)));
+ QTimer::singleShot(0,next,SLOT(exec()));
+ }
+}
+
+
+
+
+// Here we have names of devices. The variable
+// names are basically the linux device names,
+// replace with whatever your OS needs instead.
+//
+//
+#ifdef ANY_LINUX
+
+const char *fd0H1440[] = { "/dev/fd0u1440", "/dev/floppy/0u1440", "/dev/fd0h1440", "/dev/fd0H1440", "/dev/fd0", 0L } ;
+const char *fd0D720[] = { "/dev/fd0u720", "/dev/floppy/0u720", "/dev/fd0D720", "/dev/fd0h720", "/dev/fd0", 0L };
+const char *fd0h1200[] = { "/dev/fd0h1200", "/dev/floppy/0h1200", "/dev/fd0", 0L };
+const char *fd0h360[] = { "/dev/fd0u360", "/dev/floppy/0u360", "/dev/fd0h360", "/dev/fd0d360", "/dev/fd0", 0L };
+
+const char *fd1H1440[] = { "/dev/fd1u1440", "/dev/floppy/1u1440","/dev/fd1h1440", "/dev/fd1H1440", "/dev/fd1", 0L } ;
+const char *fd1D720[] = { "/dev/fd1u720", "/dev/floppy/1u720", "/dev/fd1D720", "/dev/fd1h720", "/dev/fd1", 0L };
+const char *fd1h1200[] = { "/dev/fd1h1200", "/dev/floppy/1h1200", "/dev/fd1", 0L };
+const char *fd1h360[] = { "/dev/fd1u360", "/dev/floppy/1u360","/dev/fd1h360", "/dev/fd1d360", "/dev/fd1", 0L };
+
+const char *fd0auto[] = { "/dev/fd0", 0L };
+const char *fd1auto[] = { "/dev/fd1", 0L };
+
+#endif
+
+
+#ifdef ANY_BSD
+const char *fd0[] = { "/dev/fd0", 0L } ;
+const char *fd1[] = { "/dev/fd1", 0L } ;
+#endif
+
+// Next we have a table of device names and characteristics.
+// These are ordered according to 2*densityIndex+deviceIndex,
+// ie. primary (0) 1440K (0) is first, then secondary (1) 1440K is
+// second, down to secondary (1) 360k (4) in position 3*2+1=7.
+//
+//
+// Note that the data originally contained in KFloppy was
+// patently false, so most of this is fake. I guess noone ever
+// formatted a 5.25" floppy.
+//
+// The flags field is unused in this implementation.
+//
+//
+fdinfo fdtable[] =
+{
+#ifdef ANY_LINUX
+ // device drv blks trk flg
+ { fd0H1440, 0, 1440, 80, 0 },
+ { fd1H1440, 1, 1440, 80, 0 },
+ { fd0D720, 0, 720, 80, 0 },
+ { fd1D720, 1, 720, 80, 0 },
+ { fd0h1200, 0, 1200, 80, 0 },
+ { fd1h1200, 1, 1200, 80, 0 },
+ { fd0h360, 0, 360, 40, 0 },
+ { fd1h360, 1, 360, 40, 0 },
+ { fd0auto, 0, 0, 80, 0 },
+ { fd1auto, 1, 0, 80, 0 },
+#endif
+
+#ifdef ANY_BSD
+ // Instead of the number of tracks, which is
+ // unneeded, we record the
+ // number of F's printed during an fdformat
+ { fd0, 0, 1440, 40, 0 },
+ { fd1, 1, 1440, 40, 0 },
+ { fd0, 0, 720, 40, 0 },
+ { fd1, 1, 720, 40, 0 },
+ { fd0, 0, 1200, 40, 0},
+ { fd1, 1, 1200, 40, 0},
+ { fd0, 0, 360, 40, 0},
+ { fd1, 1, 360, 40, 0},
+#endif
+ { 0L, 0, 0, 0, 0 }
+} ;
+
+
+FloppyAction::FloppyAction(QObject *p) :
+ KFAction(p),
+ deviceInfo(0L),
+ theProcess(0L)
+{
+ DEBUGSETUP;
+}
+
+void FloppyAction::quit()
+{
+ DEBUGSETUP;
+ delete theProcess;
+ theProcess=0L;
+
+ KFAction::quit();
+}
+
+bool FloppyAction::configureDevice( const QString& newDeviceName )
+{
+ deviceInfo = 0; // We have not any idea what the device is
+ deviceName = newDeviceName;
+ return true; // No problem!
+}
+
+bool FloppyAction::configureDevice(int drive,int density)
+{
+ DEBUGSETUP;
+ const char *devicename = 0L;
+
+ deviceInfo=0L;
+ deviceName = QString::null;
+
+ if ((drive<0) || (drive>1))
+ {
+ emit status(i18n("Unexpected drive number %1.").arg(drive),-1);
+ return false;
+ }
+
+ fdinfo *deviceinfo = fdtable;
+ for ( ; deviceinfo && (deviceinfo->devices) ; deviceinfo++)
+ {
+ if (deviceinfo->blocks != density)
+ continue;
+ }
+ if (!deviceinfo)
+ {
+ emit status(i18n("Unexpected density number %1.").arg(density),-1);
+ return false;
+ }
+
+ deviceinfo = fdtable;
+ for ( ; deviceinfo && (deviceinfo->devices) ; deviceinfo++)
+ {
+ if (deviceinfo->blocks != density)
+ continue;
+ if (deviceinfo->drive == drive)
+ break;
+ }
+
+ if (!deviceinfo || !deviceinfo->devices)
+ {
+ emit status(i18n("Cannot find a device for drive %1 and density %2.")
+ .arg(drive).arg(density),-1);
+ return false;
+ }
+
+ for (const char **devices=deviceinfo->devices ;
+ *devices ; devices++)
+ {
+ if (access(*devices,W_OK)>=0)
+ {
+ kdDebug(KFAREA) << "Found device " << *devices << endl;
+ devicename=*devices;
+ break;
+ }
+ }
+
+ if (!devicename)
+ {
+ const QString str = i18n(
+ "Cannot access %1\nMake sure that the device exists and that "
+ "you have write permission to it.").arg(deviceinfo->devices[0]);
+ emit status(str,-1);
+ return false;
+ }
+
+ deviceName = devicename;
+ deviceInfo = deviceinfo;
+
+ return true;
+}
+
+void FloppyAction::processDone(KProcess *p)
+{
+ DEBUGSETUP;
+
+ if (p!=theProcess)
+ {
+ DEBUGS(" Strange process exited.");
+ return;
+ }
+
+ if (p->normalExit())
+ {
+ if (p->exitStatus() == 0)
+ {
+ emit status(QString::null,100);
+ emit done(this,true);
+ }
+ else
+ {
+ emit status(i18n("The program %1 terminated with an error.").arg(theProcessName),100);
+ emit done(this,false);
+ }
+ }
+ else
+ {
+ emit status(i18n("The program %1 terminated abnormally.").arg(theProcessName),100);
+ emit done(this,false);
+ }
+}
+
+void FloppyAction::processStdOut(KProcess *, char *b, int l)
+{
+ Q_UNUSED(b);
+ Q_UNUSED(l);
+ kdDebug(KFAREA) << "stdout:" << QString::fromLatin1(b,l) << endl;
+}
+
+void FloppyAction::processStdErr(KProcess *p, char *b, int l)
+{
+ processStdOut(p,b,l);
+}
+
+bool FloppyAction::startProcess()
+{
+ DEBUGSETUP;
+
+ connect(theProcess,SIGNAL(processExited(KProcess *)),
+ this,SLOT(processDone(KProcess *)));
+ connect(theProcess,SIGNAL(receivedStdout(KProcess *,char *,int)),
+ this,SLOT(processStdOut(KProcess *,char *,int)));
+ connect(theProcess,SIGNAL(receivedStderr(KProcess *,char *,int)),
+ this,SLOT(processStdErr(KProcess *,char *,int)));
+
+ theProcess->setEnvironment( "LC_ALL", "C" ); // We need the untranslated output of the tool
+ return theProcess->start(KProcess::NotifyOnExit,
+ KProcess::AllOutput);
+}
+
+
+/* static */ QString FDFormat::fdformatName = QString::null;
+
+FDFormat::FDFormat(QObject *p) :
+ FloppyAction(p),
+ doVerify(true)
+{
+ DEBUGSETUP;
+ theProcessName = QString::fromLatin1("fdformat");
+ setName("FDFormat");
+}
+
+/* static */ bool FDFormat::runtimeCheck()
+{
+ fdformatName = findExecutable("fdformat");
+ return (!fdformatName.isEmpty());
+}
+
+bool FDFormat::configure(bool v)
+{
+ doVerify=v;
+ return true;
+}
+
+/* virtual */ void FDFormat::exec()
+{
+ DEBUGSETUP;
+
+ if ( !deviceInfo || deviceName.isEmpty() )
+ {
+ emit status( i18n("Internal error: device not correctly defined."), -1 );
+ emit done(this,false);
+ return;
+ }
+
+ if (fdformatName.isEmpty())
+ {
+ emit status(i18n("Cannot find fdformat."),-1);
+ emit done(this,false);
+ return;
+ }
+
+ if (theProcess) delete theProcess;
+ theProcess = new KProcess;
+
+ formatTrackCount=0;
+
+ *theProcess << fdformatName ;
+
+ // Common to Linux and BSD, others may differ
+ if (!doVerify)
+ {
+ *theProcess << "-n";
+ }
+
+#ifdef ANY_BSD
+ *theProcess
+ << "-y"
+ << "-f"
+ << QString::number(deviceInfo->blocks) ;
+#elif defined(ANY_LINUX)
+ // No Linux-specific flags
+#endif
+
+ // Common to Linux and BSD, others may differ
+ *theProcess << deviceName;
+
+ if (!startProcess())
+ {
+ emit status(i18n("Could not start fdformat."),-1);
+ emit done(this,false);
+ }
+
+ // Now depend on fdformat running and producing output.
+}
+
+// Parse some output from the fdformat process. Lots of
+// #ifdefs here to account for variations in the basic
+// fdformat. Uses gotos to branch to whatever error message we
+// need, since the messages can be standardized across OSsen.
+//
+//
+void FDFormat::processStdOut(KProcess *, char *b, int l)
+{
+ DEBUGSETUP;
+ QString s;
+
+#ifdef ANY_BSD
+ if (b[0]=='F')
+ {
+ formatTrackCount++;
+ emit status(QString::null,
+ formatTrackCount * 100 / deviceInfo->tracks);
+ }
+ else if (b[0]=='E')
+ {
+ emit status(i18n("Error formatting track %1.").arg(formatTrackCount),-1);
+ }
+ else
+ {
+ s = QString::fromLatin1(b,l);
+ if (s.contains("ioctl(FD_FORM)"))
+ {
+ emit status (i18n(
+ "Cannot access floppy or floppy drive.\n"
+ "Please insert a floppy and make sure that you "
+ "have selected a valid floppy drive."),-1);
+ return;
+ }
+ if (s.find("/dev/")>=0)
+ {
+ emit status(s,-1);
+ return;
+ }
+ DEBUGS(s);
+ }
+#elif defined(ANY_LINUX)
+ s = QString::fromLatin1(b,l);
+ DEBUGS(s);
+ QRegExp regexp( "([0-9]+)" );
+ if ( s.startsWith( "bad data at cyl" ) || ( s.find( "Problem reading cylinder" ) != -1 ) )
+ {
+ if ( regexp.search( s ) > -1 )
+ {
+ const int track = regexp.cap(1).toInt();
+ emit status(i18n("Low-level formatting error at track %1.").arg(track), -1);
+ }
+ else
+ {
+ // This error should not happen
+ emit status(i18n("Low-level formatting error: %1").arg(s), -1);
+ }
+ return;
+ }
+ else if (s.find("ioctl(FDFMTBEG)")!=-1)
+ {
+ emit status (i18n(
+ "Cannot access floppy or floppy drive.\n"
+ "Please insert a floppy and make sure that you "
+ "have selected a valid floppy drive."),-1);
+ return;
+ }
+ else if (s.find("busy")!=-1) // "Device or resource busy"
+ {
+ emit status(i18n("Device busy.\nPerhaps you need to unmount the floppy first."),-1);
+ return;
+ }
+ // Be careful to leave "iotcl" as last before checking numbers
+ else if (s.find("ioctl")!=-1)
+ {
+ emit status(i18n("Low-level format error: %1").arg(s),-1);
+ return;
+ }
+ // Check for numbers at last (as /dev/fd0u1440 has numbers too)
+ else if ( regexp.search(s) > -1 )
+ {
+ // Normal track number (formatting or verifying)
+ const int p = regexp.cap(1).toInt();
+ if ((p>=0) && (p<deviceInfo->tracks))
+ {
+ emit status(QString::null,
+ p * 100 / deviceInfo->tracks);
+ }
+ }
+#endif
+ return;
+}
+
+
+/* static */ QString DDZeroOut::m_ddName = QString::null;
+
+DDZeroOut::DDZeroOut(QObject *p) :
+ FloppyAction(p)
+{
+ kdDebug(KFAREA) << (__PRETTY_FUNCTION__) << endl;
+ theProcessName = QString::fromLatin1("dd");
+ setName("DD");
+}
+
+/* static */ bool DDZeroOut::runtimeCheck()
+{
+ m_ddName = findExecutable("dd");
+ return (!m_ddName.isEmpty());
+}
+
+/* virtual */ void DDZeroOut::exec()
+{
+ kdDebug(KFAREA) << (__PRETTY_FUNCTION__) << endl;
+
+ if ( deviceName.isEmpty() )
+ {
+ emit status( i18n("Internal error: device not correctly defined."), -1 );
+ emit done( this, false );
+ return;
+ }
+
+ if ( m_ddName.isEmpty() )
+ {
+ emit status( i18n("Cannot find dd."), -1 );
+ emit done( this, false );
+ return;
+ }
+
+ delete theProcess;
+ theProcess = new KProcess;
+
+ *theProcess << m_ddName ;
+
+ *theProcess << "if=/dev/zero" ;
+ *theProcess << "of="+deviceName;
+
+ if ( !startProcess() )
+ {
+ emit status( i18n("Could not start dd."), -1 );
+ emit done( this, false );
+ }
+
+}
+
+void DDZeroOut::processDone(KProcess *p)
+{
+ kdDebug(KFAREA) << (__PRETTY_FUNCTION__) << endl;
+
+ if (p!=theProcess)
+ {
+ kdDebug(KFAREA) << "Strange process exited." << endl;
+ return;
+ }
+
+ /**
+ * As we do not give a number of blocks to dd(1), it will stop
+ * with the error "No space left on device"
+ *
+ * ### TODO: really check if the exit is not on an other error and then abort the formatting
+ */
+ emit status(QString::null,100);
+ emit done(this,true);
+}
+
+
+
+/* static */ QString FATFilesystem::newfs_fat = QString::null ;
+
+FATFilesystem::FATFilesystem(QObject *parent) :
+ FloppyAction(parent)
+{
+ DEBUGSETUP;
+ runtimeCheck();
+ theProcessName=newfs_fat;
+ setName("FATFilesystem");
+}
+
+/* static */ bool FATFilesystem::runtimeCheck()
+{
+ DEBUGSETUP;
+
+#ifdef ANY_BSD
+ newfs_fat = findExecutable("newfs_msdos");
+#elif defined(ANY_LINUX)
+ newfs_fat = findExecutable("mkdosfs");
+#else
+ return false;
+#endif
+
+ return !newfs_fat.isEmpty();
+}
+
+bool FATFilesystem::configure(bool v,bool l,const QString &lbl)
+{
+ doVerify=v;
+ doLabel=l;
+ if (l)
+ label=lbl.simplifyWhiteSpace();
+ else
+ label=QString::null;
+
+ return true;
+}
+
+void FATFilesystem::exec()
+{
+ DEBUGSETUP;
+
+
+ if (
+#ifdef ANY_BSD // BSD needs the deviceInfo for the block count
+ !deviceInfo ||
+#endif
+ deviceName.isEmpty())
+ {
+ emit status( i18n("Internal error: device not correctly defined."), -1 );
+ emit done(this,false);
+ return;
+ }
+
+ if (newfs_fat.isEmpty())
+ {
+ emit status(i18n("Cannot find a program to create FAT filesystems."),-1);
+ emit done(this,false);
+ return;
+ }
+
+ if (theProcess) delete theProcess;
+ KProcess *p = theProcess = new KProcess;
+
+ *p << newfs_fat;
+#ifdef ANY_BSD
+ *p << "-f" << QString::number(deviceInfo->blocks);
+ if (doLabel)
+ {
+ *p << "-L" << label ;
+ }
+#else
+#ifdef ANY_LINUX
+ if (doLabel)
+ {
+ *p << "-n" << label ;
+ }
+ if (doVerify)
+ {
+ *p << "-c";
+ }
+#endif
+#endif
+ *p << deviceName ;
+
+ if (!startProcess())
+ {
+ emit status(i18n("Cannot start FAT format program."),-1);
+ emit done(this,false);
+ }
+}
+
+void FATFilesystem::processStdOut(KProcess *, char *b, int l)
+{
+#ifdef ANY_BSD
+ // ### TODO: do some checks
+#elif defined(ANY_LINUX)
+ QString s ( QString::fromLatin1( b, l ) );
+ kdDebug(KFAREA) << s << endl;
+ if (s.find("mounted file system")!=-1) // "/dev/fd0 contains a mounted file system
+ {
+ emit status(i18n("Floppy is mounted.\nYou need to unmount the floppy first."),-1);
+ return;
+ }
+ else if (s.find("busy")!=-1) // "Device or resource busy"
+ {
+ emit status(i18n("Device busy.\nPerhaps you need to unmount the floppy first."),-1);
+ return;
+ }
+# if 0
+ else if ( s.find( "mkdosfs" ) != -1 ) // DEBUG: get the program header and show it!
+ {
+ emit status( s, -1 );
+ return;
+ }
+# endif
+#endif
+}
+
+
+
+
+#ifdef ANY_BSD
+
+/* static */ QString UFSFilesystem::newfs = QString::null ;
+
+UFSFilesystem::UFSFilesystem(QObject *parent) :
+ FloppyAction(parent)
+{
+ DEBUGSETUP;
+ runtimeCheck();
+ theProcessName=newfs;
+ setName("UFSFilesystem");
+}
+
+/* static */ bool UFSFilesystem::runtimeCheck()
+{
+ DEBUGSETUP;
+
+ newfs = findExecutable("newfs");
+
+ return !newfs.isEmpty();
+}
+
+void UFSFilesystem::exec()
+{
+ DEBUGSETUP;
+
+ if ( deviceName.isEmpty() )
+ {
+ emit status( i18n("Internal error: device not correctly defined."), -1 );
+ emit done(this,false);
+ return;
+ }
+
+ if (newfs.isEmpty())
+ {
+ emit status(i18n("BSD", "Cannot find a program to create UFS filesystems."),-1);
+ emit done(this,false);
+ return;
+ }
+
+ if (theProcess) delete theProcess;
+ KProcess *p = theProcess = new KProcess;
+
+ *p << newfs;
+
+ // ### TODO: is it still needed? (FreeBSD 5.3's man page says: "For backward compatibility.")
+ if ( deviceInfo )
+ *p << "-T" << QString("fd%1").arg(deviceInfo->blocks);
+
+ *p << deviceName;
+
+ if (!startProcess())
+ {
+ emit status(i18n("BSD", "Cannot start UFS format program."),-1);
+ emit done(this,false);
+ }
+}
+#endif
+
+
+
+/* static */ QString Ext2Filesystem::newfs = QString::null ;
+
+Ext2Filesystem::Ext2Filesystem(QObject *parent) :
+ FloppyAction(parent)
+{
+ DEBUGSETUP;
+ runtimeCheck();
+ theProcessName="mke2fs";
+ setName("Ext2Filesystem");
+}
+
+/* static */ bool Ext2Filesystem::runtimeCheck()
+{
+ DEBUGSETUP;
+
+ newfs = findExecutable("mke2fs");
+
+ return !newfs.isEmpty();
+}
+
+bool Ext2Filesystem::configure(bool v,bool l,const QString &lbl)
+{
+ doVerify=v;
+ doLabel=l;
+ if (l)
+ {
+ label=lbl.stripWhiteSpace();
+ }
+ else
+ {
+ label=QString::null;
+ }
+
+ return true;
+}
+
+void Ext2Filesystem::exec()
+{
+ DEBUGSETUP;
+
+ if (
+#ifdef ANY_BSD // BSD needs the deviceInfo for the block count
+ !deviceInfo ||
+#endif
+ deviceName.isEmpty() )
+ {
+ emit status( i18n("Internal error: device not correctly defined."), -1 );
+ emit done(this,false);
+ return;
+ }
+
+ if (newfs.isEmpty())
+ {
+ emit status(i18n("Cannot find a program to create ext2 filesystems."),-1);
+ emit done(this,false);
+ return;
+ }
+
+ if (theProcess) delete theProcess;
+ KProcess *p = theProcess = new KProcess;
+
+ *p << newfs;
+ *p << "-q";
+ if (doVerify) *p << "-c" ;
+ if (doLabel) *p << "-L" << label ;
+
+ *p << deviceName ;
+
+ if (!startProcess())
+ {
+ emit status(i18n("Cannot start ext2 format program."),-1);
+ emit done(this,false);
+ }
+}
+
+void Ext2Filesystem::processStdOut(KProcess *, char *b, int l)
+{
+#ifdef ANY_BSD
+ // ### TODO: do some checks
+#elif defined(ANY_LINUX)
+ QString s ( QString::fromLatin1( b, l ) );
+ kdDebug(KFAREA) << s << endl;
+ if (s.find("mounted")!=-1) // "/dev/fd0 is mounted; will not make a filesystem here!"
+ {
+ emit status(i18n("Floppy is mounted.\nYou need to unmount the floppy first."),-1);
+ return;
+ }
+ else if (s.find("busy")!=-1) // "Device or resource busy"
+ {
+ emit status(i18n("Device busy.\nPerhaps you need to unmount the floppy first."),-1);
+ return;
+ }
+#endif
+}
+
+
+
+#ifdef ANY_LINUX
+/* static */ QString MinixFilesystem::newfs = QString::null ;
+
+MinixFilesystem::MinixFilesystem(QObject *parent) :
+ FloppyAction(parent)
+{
+ DEBUGSETUP;
+ runtimeCheck();
+ theProcessName="mkfs.minix";
+ setName("Minix2Filesystem");
+}
+
+/* static */ bool MinixFilesystem::runtimeCheck()
+{
+ DEBUGSETUP;
+
+ newfs = findExecutable("mkfs.minix");
+
+ return !newfs.isEmpty();
+}
+
+bool MinixFilesystem::configure(bool v,bool l,const QString &lbl)
+{
+ doVerify=v;
+ doLabel=l;
+ if (l)
+ {
+ label=lbl.stripWhiteSpace();
+ }
+ else
+ {
+ label=QString::null;
+ }
+
+ return true;
+}
+
+void MinixFilesystem::exec()
+{
+ DEBUGSETUP;
+
+ if ( deviceName.isEmpty() )
+ {
+ emit status( i18n("Internal error: device not correctly defined."), -1 );
+ emit done(this,false);
+ return;
+ }
+
+ if (newfs.isEmpty())
+ {
+ emit status(i18n("Cannot find a program to create Minix filesystems."),-1);
+ emit done(this,false);
+ return;
+ }
+
+ if (theProcess) delete theProcess;
+ KProcess *p = theProcess = new KProcess;
+
+ *p << newfs;
+
+ // Labeling is not possible
+ if (doVerify) *p << "-c" ;
+
+ *p << deviceName ;
+
+ if (!startProcess())
+ {
+ emit status(i18n("Cannot start Minix format program."),-1);
+ emit done(this,false);
+ }
+}
+
+void MinixFilesystem::processStdOut(KProcess *, char *b, int l)
+{
+ QString s ( QString::fromLatin1( b, l ) );
+ kdDebug(KFAREA) << s << endl;
+ if (s.find("mounted")!=-1) // "mkfs.minix: /dev/fd0 is mounted; will not make a filesystem here!"
+ {
+ emit status(i18n("Floppy is mounted.\nYou need to unmount the floppy first."),-1);
+ return;
+ }
+ else if (s.find("busy")!=-1) // "Device or resource busy"
+ {
+ emit status(i18n("Device busy.\nPerhaps you need to unmount the floppy first."),-1);
+ return;
+ }
+}
+
+#endif
+
+#include "format.moc"