summaryrefslogtreecommitdiffstats
path: root/kfloppy
diff options
context:
space:
mode:
Diffstat (limited to 'kfloppy')
-rw-r--r--kfloppy/KFloppy.desktop96
-rw-r--r--kfloppy/Makefile.am23
-rw-r--r--kfloppy/README23
-rw-r--r--kfloppy/TODO47
-rw-r--r--kfloppy/debug.h65
-rw-r--r--kfloppy/floppy.cpp741
-rw-r--r--kfloppy/floppy.h128
-rw-r--r--kfloppy/floppy_format.desktop54
-rw-r--r--kfloppy/format.cpp996
-rw-r--r--kfloppy/format.h426
-rw-r--r--kfloppy/hi128-app-kfloppy.pngbin0 -> 12698 bytes
-rw-r--r--kfloppy/hi16-app-kfloppy.pngbin0 -> 1008 bytes
-rw-r--r--kfloppy/hi22-app-kfloppy.pngbin0 -> 1397 bytes
-rw-r--r--kfloppy/hi32-app-kfloppy.pngbin0 -> 2374 bytes
-rw-r--r--kfloppy/hi48-app-kfloppy.pngbin0 -> 3812 bytes
-rw-r--r--kfloppy/hi64-app-kfloppy.pngbin0 -> 5298 bytes
-rw-r--r--kfloppy/main.cpp79
-rw-r--r--kfloppy/zip.cpp305
-rw-r--r--kfloppy/zip.h106
19 files changed, 3089 insertions, 0 deletions
diff --git a/kfloppy/KFloppy.desktop b/kfloppy/KFloppy.desktop
new file mode 100644
index 0000000..113a24d
--- /dev/null
+++ b/kfloppy/KFloppy.desktop
@@ -0,0 +1,96 @@
+[Desktop Entry]
+GenericName=Floppy Formatter
+GenericName[af]=Sagteskyf Formateerder
+GenericName[ar]=مهئ الأقراص المرنة
+GenericName[az]=Disket Şəkilləndirici
+GenericName[bg]=Форматиране на дискети
+GenericName[br]=Furmader pladennig
+GenericName[bs]=Formatiranje disketa
+GenericName[ca]=Formatador de disquet
+GenericName[cs]=Formátovač disket
+GenericName[cy]=Fformatio Disg Meddal
+GenericName[da]=Disketteformatering
+GenericName[de]=Diskettenformatierer
+GenericName[el]=Εργαλείο διαμόρφωσης δισκέτας
+GenericName[eo]=Formatilo por disketoj
+GenericName[es]=Formateador de disquetes
+GenericName[et]=Diskettide vormindamise utiliit
+GenericName[eu]=Diskete Eratzailea
+GenericName[fa]=قالب‌بندی‌کنندۀ فلاپی
+GenericName[fi]=Levykkeiden alustusohjelma
+GenericName[fr]=Outil de formatage de disquette
+GenericName[ga]=Uirlis Fhormáidithe Dioscaí Boga
+GenericName[gl]=Formatador de Disquetes
+GenericName[he]=מאתחל תקליטונים
+GenericName[hi]=फ़्लॉपी फार्मेटर
+GenericName[hr]=Formatiranje disketa
+GenericName[hu]=Floppy-formázó
+GenericName[id]=Pemformat disket
+GenericName[is]=Tól til að forsníða disklinga
+GenericName[it]=Formattatore di dischetti
+GenericName[ja]=フロッピーをフォーマット
+GenericName[ka]=დისკეტის დამფორმატებელი
+GenericName[kk]=Иілгіш дискін пішімдеу
+GenericName[km]=កម្មវិធី​ធ្វើទ្រង់ទ្រាយ​ថាស់ទន់
+GenericName[ko]=플로피 디스크를 포맷해주는 도구
+GenericName[lt]=Diskelio formatavimas
+GenericName[lv]=Diskešu Formatētājs
+GenericName[mk]=Форматирање на дискети
+GenericName[ms]=Pengformat Cakera Liut
+GenericName[mt]=Għodda biex tifformattja floppies
+GenericName[nb]=Diskettformaterer
+GenericName[nds]=Diskettformaterer
+GenericName[ne]=फ्लपी ढाँचाकर्ता
+GenericName[nl]=Diskettes formatteren
+GenericName[nn]=Formaterer diskettar
+GenericName[pa]=ਫਲਾਪੀ ਫਾਰਮਿਟਰ
+GenericName[pl]=Program formatujący dyskietki
+GenericName[pt]=Formatação de Disquetes
+GenericName[pt_BR]=Formatador de disquetes
+GenericName[ro]=Formator floppy-disc-uri
+GenericName[ru]=Форматирование дискет
+GenericName[sk]=Formátovanie diskiet
+GenericName[sl]=Formatiranje disket
+GenericName[sr]=Форматирање дискета
+GenericName[sr@Latn]=Formatiranje disketa
+GenericName[sv]=Formatera disketter
+GenericName[ta]=நெகிழ்வட்டு வடிவமைப்பான்
+GenericName[tg]=Шаклбанднамоии Диски Нарм
+GenericName[th]=เครื่องมือฟอร์แมตแผ่นฟลอปปี้้
+GenericName[tr]=Disket Biçimlendirici
+GenericName[uk]=Відформатувати дискету
+GenericName[uz]=Disketni formatlagich
+GenericName[uz@cyrillic]=Дискетни форматлагич
+GenericName[ven]=Muvhekanyi wa Floppy
+GenericName[vi]=Trình định dạng đĩa
+GenericName[wa]=Usteye po-z abwesner des plaketes
+GenericName[xh]=Floppy formata
+GenericName[zh_CN]=软盘格式化程序
+GenericName[zh_TW]=軟碟格式化程式
+GenericName[zu]=Umakhi we-floppy
+Name=KFloppy
+Name[af]=Kfloppie
+Name[eo]=Disketingo
+Name[hi]=के-फ़्लॉपी
+Name[lv]=KMīkstnis
+Name[ne]=केडीई फ्लपी
+Name[pa]=ਕਫਲਾਪੀ
+Name[pl]=Dyskietka
+Name[pt_BR]=Disquete
+Name[sv]=Kfloppy
+Name[ta]=கேநெகிழ்வட்டு
+Name[tg]=KДиски Нарм
+Name[th]=ฟอร์แมตฟลอปปี้
+Name[tr]=Disket Biçimlendirici
+Name[wa]=KPlakete
+Name[zh_TW]=KDE 軟碟
+MimeType=
+DocPath=kfloppy/index.html
+Exec=kfloppy -caption "%c" %i %m
+Icon=kfloppy
+Path=
+Type=Application
+Terminal=false
+X-KDE-StartupNotify=true
+X-DCOP-ServiceType=Multi
+Categories=Qt;KDE;Utility;X-KDE-Utilities-Peripherals;
diff --git a/kfloppy/Makefile.am b/kfloppy/Makefile.am
new file mode 100644
index 0000000..83b0411
--- /dev/null
+++ b/kfloppy/Makefile.am
@@ -0,0 +1,23 @@
+kfloppy_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kfloppy_LDADD = $(LIB_KDEUI) -lm
+INCLUDES = $(all_includes)
+
+####### Files
+
+bin_PROGRAMS = kfloppy
+
+noinst_HEADERS = floppy.h
+kfloppy_SOURCES = main.cpp format.cpp floppy.cpp
+
+METASOURCES = format.moc floppy.moc
+
+KDE_ICON = kfloppy
+
+xdg_apps_DATA = KFloppy.desktop
+
+servicedata_DATA = floppy_format.desktop
+servicedatadir = $(kde_datadir)/konqueror/servicemenus
+
+messages:
+ $(XGETTEXT) $(kfloppy_SOURCES) -o $(podir)/kfloppy.pot
+
diff --git a/kfloppy/README b/kfloppy/README
new file mode 100644
index 0000000..79c40ce
--- /dev/null
+++ b/kfloppy/README
@@ -0,0 +1,23 @@
+KFloppy 2.1
+===========
+
+KFloppy was "done and feature complete and bug free", for systems
+running Linux. Other KDE platforms had an app that put up a warning
+box and was then totally inert. I've restructured the whole thing,
+cleaned up the code somewhat, and modularized it.
+
+Currently KFloppy is tested on a FBSD machine with a floppy drive
+and a zip drive. It should still behave on Linux, but I haven't tried.
+
+KFloppy 0.2
+===========
+
+ KFloppy formats disks and puts a DOS or ext2fs filesystem on
+them.
+
+Best Regards,
+Bernd Wuebben
+wuebben@kde.org
+
+
+
diff --git a/kfloppy/TODO b/kfloppy/TODO
new file mode 100644
index 0000000..6df5f2b
--- /dev/null
+++ b/kfloppy/TODO
@@ -0,0 +1,47 @@
+2005-06-07
+
+As I am wirting an answer to an email about the to-do in KFloppy,
+better have it in the source too.
+
+
+
+The biggest challenge was to support non-legacy (USB, IDE...) floppy drives.
+I have opened a way to it with what has the working title "user-given devices".
+(A better title for the feature would be a good thing too.
+It just mean that instead of selecting "Primary" or "Secondary" as floppy drive,
+you can give a device, like /dev/sda4 )
+
+The "user-given device" is pretty raw currently, allowing nearly no comfort for
+the user. So if you have an external drive (may a ZIP drive), you could try to
+make this mode better.
+
+A little variant would be to support the device like /dev/fd0u2880 for
+formatting. Currently it does not work with Full Format,
+as a "user-given device" is supposed not to be low-level formatable.
+(I do not know any Linux or BSD tool that can low-level format
+non-legacy drives.)
+
+Another thing that I have very recently discovered is that
+extended floppy drives will not work in "superfloppy" format
+(disks without partition table), as neither mkdosfs nor BSD's newfs allow this
+without a special parameter. (I have not checked the other tools used.)
+
+Before I forget it: in the "user-given device" mode, it would be nice if there
+was support from KDE (for example devices:/ ) to know what devices are really
+flopy drives (not that a user roasts an umounted partition of his harddisk.
+
+A much easier task would be perhaps to catch more errors from
+the external programs so that it is displayed to the user.
+(Also to catch anything error message having the string "error" in it,
+which is currently not done.)
+
+That is I think the list of what users could benefit.
+
+Internally, when the Qt4 switch is done, it would need a review to see how
+to improve the way how the classes calling the external applications are
+handled.
+
+Of course, when modifying, care must taken not to break the BSD part of the
+code. (Perhaps we need a way on Linux to be able to compile the BSD part,
+as there is nothing BSD specific in the code, only the external BSD programs
+are specific.)
diff --git a/kfloppy/debug.h b/kfloppy/debug.h
new file mode 100644
index 0000000..e0080da
--- /dev/null
+++ b/kfloppy/debug.h
@@ -0,0 +1,65 @@
+/*
+
+ This file is part of the KFloppy program, part of the KDE project
+
+ Copyright (C) 2003 Adriaan de Groot <groot@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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 in a file called COPYING; if not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+*/
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+/**
+ * \file debug.h
+ *
+ * \brief Debugging definitions for KFloppy.
+ *
+ * It also tries to map operating systems
+ * into families, so you can use ANY_LINUX or ANY_BSD
+ * in the code to differentiate those families.
+ * What happens on other systems is anyone's guess.
+ */
+
+
+#define KFAREA (2002)
+
+#ifndef NDEBUG
+#define DEBUGSETUP kdDebug(KFAREA) << (__PRETTY_FUNCTION__) << endl
+#define DEBUGS(a) kdDebug(KFAREA) << " " << a << endl
+#else
+#define DEBUGSETUP
+#define DEBUGS(a)
+#endif
+
+
+// Detect vaguely what OS we're working with. Map variants
+// to one known kind.
+//
+//
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#define ANY_BSD (1)
+#else
+#if defined(linux) || defined(LINUX) || defined (__linux) || defined(__linux__)
+#define ANY_LINUX (1)
+#endif
+#endif
+
+
+
+#endif
+
diff --git a/kfloppy/floppy.cpp b/kfloppy/floppy.cpp
new file mode 100644
index 0000000..043f2f0
--- /dev/null
+++ b/kfloppy/floppy.cpp
@@ -0,0 +1,741 @@
+/*
+
+ This file is part of the KFloppy program, part of the KDE project
+
+ Copyright (C) 1997 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 <qlayout.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qcursor.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qwhatsthis.h>
+
+#include <kconfig.h>
+
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <khelpmenu.h>
+#include <kpushbutton.h>
+#include <kpopupmenu.h>
+#include <kapplication.h>
+#include <kprogress.h>
+#include <klocale.h>
+#include <kcombobox.h>
+#include <klineedit.h>
+#include <dcopref.h>
+#include <kurl.h>
+
+#include "floppy.h"
+#include "format.h"
+
+FloppyData::FloppyData(QWidget * parent, const char * name)
+ : KDialog( parent, name ),
+ formatActions(0L), m_canLowLevel(false), m_canZeroOut( false )
+{
+
+ formating = false;
+ //abort = false;
+ blocks = 0;
+
+ QVBoxLayout* ml = new QVBoxLayout( this, 10 );
+
+ QHBoxLayout* h1 = new QHBoxLayout( ml );
+
+ QVBoxLayout* v1 = new QVBoxLayout( h1 );
+ h1->addSpacing( 5 );
+
+ QGridLayout* g1 = new QGridLayout( v1, 3, 2 );
+
+ deviceComboBox = new KComboBox( false, this, "ComboBox_1" );
+ label1 = new QLabel( deviceComboBox, i18n("Floppy &drive:"), this );
+ g1->addWidget( label1, 0, 0, AlignLeft );
+ g1->addWidget( deviceComboBox, 0, 1 );
+
+ // Make the combo box editable, so that the user can enter a device name
+ deviceComboBox->setEditable( true );
+
+ deviceComboBox->insertItem(i18n("Primary"));
+ deviceComboBox->insertItem(i18n("Secondary"));
+
+ const QString deviceWhatsThis = i18n("<qt>Select the floppy drive.</qt>");
+
+ QWhatsThis::add(label1, deviceWhatsThis);
+ QWhatsThis::add(deviceComboBox, deviceWhatsThis);
+
+
+ densityComboBox = new KComboBox( false, this, "ComboBox_1" );
+ label2 = new QLabel( densityComboBox, i18n("&Size:"), this);
+ g1->addWidget( label2, 1, 0, AlignLeft );
+ g1->addWidget( densityComboBox, 1, 1 );
+
+#if defined(ANY_LINUX)
+ densityComboBox->insertItem( i18n( "Auto-Detect" ) );
+#endif
+ densityComboBox->insertItem(i18n("3.5\" 1.44MB"));
+ densityComboBox->insertItem(i18n("3.5\" 720KB"));
+ densityComboBox->insertItem(i18n("5.25\" 1.2MB"));
+ densityComboBox->insertItem(i18n("5.25\" 360KB"));
+
+ const QString densityWhatsThis =
+ i18n("<qt>This allows you to select the "
+ "floppy disk's size and density.</qt>");
+
+ QWhatsThis::add(label2, densityWhatsThis);
+ QWhatsThis::add(densityComboBox, densityWhatsThis);
+
+
+ filesystemComboBox = new KComboBox( false, this, "ComboBox_2" );
+ label3 = new QLabel( filesystemComboBox, i18n("F&ile system:"), this);
+ g1->addWidget( label3, 2, 0, AlignLeft );
+ g1->addWidget( filesystemComboBox, 2, 1 );
+ g1->setColStretch(1, 1);
+
+#if defined(ANY_LINUX)
+ QWhatsThis::add( label3,
+ i18n( "Linux", "KFloppy supports three file formats under Linux: MS-DOS, Ext2, and Minix" ) );
+#elif defined(ANY_BSD)
+ QWhatsThis::add( label3,
+ i18n( "BSD", "KFloppy supports three file formats under BSD: MS-DOS, UFS, and Ext2" ) );
+#endif
+ // If you modify the user visible string, change them also (far) below
+
+ QString userFeedBack;
+ uint numFileSystems = 0;
+
+#if defined(ANY_LINUX)
+ QWhatsThis::add( filesystemComboBox,
+ i18n( "Linux", "KFloppy supports three file formats under Linux: MS-DOS, Ext2, and Minix" ) );
+ if (FATFilesystem::runtimeCheck()) {
+ filesystemComboBox->insertItem(i18n("DOS"));
+ ++numFileSystems;
+ userFeedBack += i18n( "Linux", "Program mkdosfs found." );
+ }
+ else {
+ userFeedBack += i18n( "Linux", "Program mkdosfs <b>not found</b>. MSDOS formatting <b>not available</b>." );
+ }
+ userFeedBack += "<br>";
+ if (Ext2Filesystem::runtimeCheck()) {
+ filesystemComboBox->insertItem(i18n("ext2"));
+ ++numFileSystems;
+ userFeedBack += i18n( "Program mke2fs found." );
+ }
+ else {
+ userFeedBack += i18n( "Program mke2fs <b>not found</b>. Ext2 formatting <b>not available</b>" );
+ }
+ userFeedBack += "<br>";
+ if (MinixFilesystem::runtimeCheck()) {
+ filesystemComboBox->insertItem(i18n("Minix"));
+ ++numFileSystems;
+ userFeedBack += i18n( "Linux", "Program mkfs.minix found." );
+ }
+ else {
+ userFeedBack += i18n( "Linux", "Program mkfs.minix <b>not found</b>. Minix formatting <b>not available</b>" );
+ }
+#elif defined(ANY_BSD)
+ QWhatsThis::add( filesystemComboBox,
+ i18n( "BSD", "KFloppy supports two file formats under BSD: MS-DOS and UFS" ) );
+ if (FATFilesystem::runtimeCheck()) {
+ filesystemComboBox->insertItem(i18n("DOS"));
+ ++numFileSystems;
+ userFeedBack += i18n( "BSD", "Program newfs_msdos found." );
+ }
+ else {
+ userFeedBack += i18n( "BSD", "Program newfs_msdos <b>not found</b>. MSDOS formatting <b>not available</b>." );
+ }
+ userFeedBack += "<br>";
+ if (UFSFilesystem::runtimeCheck()) {
+ filesystemComboBox->insertItem(i18n("UFS"));
+ ++numFileSystems;
+ userFeedBack += i18n( "BSD", "Program newfs found." );
+ }
+ else {
+ userFeedBack += i18n( "BSD", "Program newfs <b>not found</b>. UFS formatting <b>not available</b>." );
+ }
+ userFeedBack += "<br>";
+ if (Ext2Filesystem::runtimeCheck()) {
+ filesystemComboBox->insertItem(i18n("ext2"));
+ ++numFileSystems;
+ userFeedBack += i18n( "Program mke2fs found." );
+ }
+ else {
+ userFeedBack += i18n( "Program mke2fs <b>not found</b>. Ext2 formatting <b>not available</b>" );
+ }
+#endif
+
+ v1->addSpacing( 10 );
+
+ buttongroup = new QButtonGroup( 3, Qt::Vertical, i18n("&Formatting"), this, "ButtonGroup_1" );
+
+
+ quick = new QRadioButton( i18n( "Q&uick format" ), buttongroup, "RadioButton_2" );
+ QWhatsThis::add( quick,
+ i18n("<qt>Quick format is only a high-level format:"
+ " it creates only a file system.</qt>") );
+
+ zerooutformat = new QRadioButton( i18n( "&Zero out and quick format"), buttongroup, "RadioButton_ZeroOutFormat" );
+ QWhatsThis::add( zerooutformat,
+ i18n("<qt>This first erases the floppy by writing zeros and then it creates the file system.</qt>") );
+
+ fullformat = new QRadioButton( i18n( "Fu&ll format"), buttongroup, "RadioButton_3" );
+ QWhatsThis::add( fullformat,
+ i18n("Full format is a low-level and high-level format. It erases everything on the disk.") );
+
+ v1->addWidget( buttongroup );
+
+ // ### TODO: we need some user feedback telling why full formatting is disabled.
+ userFeedBack += "<br>";
+ m_canLowLevel = FDFormat::runtimeCheck();
+ if (m_canLowLevel){
+ fullformat->setChecked(true);
+ userFeedBack += i18n( "Program fdformat found." );
+ }
+ else {
+ fullformat->setDisabled(true);
+ quick->setChecked(true);
+ userFeedBack += i18n( "Program fdformat <b>not found</b>. Full formatting <b>disabled</b>." );
+ }
+ userFeedBack += "<br>";
+ m_canZeroOut = DDZeroOut::runtimeCheck();
+ if ( m_canZeroOut )
+ {
+ zerooutformat->setChecked( true );
+ userFeedBack += i18n( "Program dd found." );
+ }
+ else {
+ zerooutformat->setDisabled(true);
+ userFeedBack += i18n( "Program dd <b>not found</b>. Zeroing-out <b>disabled</b>." );
+ }
+
+ verifylabel = new QCheckBox( this, "CheckBox_Integrity" );
+ verifylabel->setText(i18n( "&Verify integrity" ));
+ verifylabel->setChecked(true);
+ v1->addWidget( verifylabel, AlignLeft );
+ QWhatsThis::add( verifylabel,
+ i18n("<qt>Check this if you want the floppy disk to be checked after formatting."
+ " Please note that the floppy will be checked twice if you have selected full formatting.</qt>") );
+
+ labellabel = new QCheckBox( this, "Checkbox_Label" );
+ labellabel->setText(i18n( "Volume la&bel:") );
+ labellabel->setChecked(true);
+ v1->addWidget( labellabel, AlignLeft );
+ QWhatsThis::add( labellabel,
+ i18n("<qt>Check this if you want a volume label for your floppy."
+ " Please note that Minix does not support labels at all.</qt>") );
+
+ QHBoxLayout* h2 = new QHBoxLayout( v1 );
+ h2->addSpacing( 20 );
+
+ lineedit = new KLineEdit( this, "Lineedit" );
+ // ### TODO ext2 supports 16 characters. Minix has not any label. UFS?
+ lineedit->setText(i18n( "Volume label, maximal 11 characters", "KDE Floppy" ) );
+ lineedit->setMaxLength(11);
+ h2->addWidget( lineedit, AlignRight );
+ QWhatsThis::add( lineedit,
+ i18n("<qt>This is for the volume label."
+ " Due to a limitation of MS-DOS the label can only be 11 characters long."
+ " Please note that Minix does not support labels, whatever you enter here.</qt>") );
+
+ connect(labellabel,SIGNAL(toggled(bool)),lineedit,SLOT(setEnabled(bool)));
+
+ QVBoxLayout* v3 = new QVBoxLayout( h1 );
+
+ formatbutton = new KPushButton( this, "PushButton_3" );
+ formatbutton->setText(i18n( "&Format") );
+ formatbutton->setAutoRepeat( false );
+ if (!numFileSystems)
+ formatbutton->setDisabled(false); // We have not any helper program for creating any file system
+ connect(formatbutton,SIGNAL(clicked()),this,SLOT(format()));
+ v3->addWidget( formatbutton );
+ QWhatsThis::add( formatbutton,
+ i18n("<qt>Click here to start formatting.</qt>") );
+
+ v3->addStretch( 1 );
+
+ //Setup the Help Menu
+ helpMenu = new KHelpMenu(this, KGlobal::instance()->aboutData(), false);
+
+ helpbutton = new KPushButton( KStdGuiItem::help(), this );
+ helpbutton->setAutoRepeat( false );
+ helpbutton->setPopup(helpMenu->menu());
+ v3->addWidget( helpbutton );
+
+ quitbutton = new KPushButton( KStdGuiItem::quit(), this );
+ quitbutton->setAutoRepeat( false );
+ connect(quitbutton,SIGNAL(clicked()),this,SLOT(quit()));
+ v3->addWidget( quitbutton );
+
+ ml->addSpacing( 10 );
+
+ frame = new QLabel( this, "NewsWindow" );
+ frame->setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ frame->setAlignment(WordBreak|ExpandTabs);
+ QWhatsThis::add( frame,
+ i18n("<qt>This is the status window, where error messages are displayed.</qt>") );
+
+ QString frameText( userFeedBack );
+ frameText.prepend( "<qt>" );
+ frameText.append( "</qt>" );
+ frame->setText( frameText );
+
+ ml->addWidget( frame );
+
+ progress = new KProgress( this, "Progress" );
+ progress->setDisabled( true );
+ ml->addWidget( progress );
+
+ QWhatsThis::add(progress,
+ i18n("<qt>Shows progress of the format.</qt>"));
+
+ readSettings();
+ setWidgets();
+
+ if (!numFileSystems) {
+ QString errorMessage;
+ errorMessage += "<qt>";
+ errorMessage += i18n("KFloppy cannot find any of the needed programs for creating file systems; please check your installation.<br><br>Log:");
+ errorMessage += "<br>";
+ errorMessage += userFeedBack;
+ errorMessage += "</qt>";
+ KMessageBox::error( this, errorMessage );
+ }
+}
+
+
+FloppyData::~FloppyData()
+{
+ delete formatActions;
+}
+
+void FloppyData::closeEvent(QCloseEvent*)
+{
+ quit();
+}
+
+void FloppyData::keyPressEvent(QKeyEvent *e)
+{
+ switch(e->key()) {
+ case Qt::Key_F1:
+ kapp->invokeHelp();
+ break;
+ default:
+ KDialog::keyPressEvent(e);
+ return;
+ }
+}
+
+void FloppyData::show() {
+ setCaption(i18n("KDE Floppy Formatter"));
+ KDialog::show();
+}
+
+bool FloppyData::findDevice()
+{
+ // Note: this function does not handle user-given devices
+
+ drive=-1;
+ if( deviceComboBox->currentText() == i18n("Primary") )
+ {
+ drive=0;
+ }
+ else if( deviceComboBox->currentText() == i18n("Secondary") )
+ {
+ drive=1;
+ }
+
+ blocks=-1;
+
+ if( densityComboBox->currentText() == i18n("3.5\" 1.44MB")){
+ blocks = 1440;
+ }
+ else
+ if( densityComboBox->currentText() == i18n("3.5\" 720KB")){
+ blocks = 720;
+ }
+ else
+ if( densityComboBox->currentText() == i18n("5.25\" 1.2MB")){
+ blocks = 1200;
+ }
+ else
+ if( densityComboBox->currentText() == i18n("5.25\" 360KB")){
+ blocks = 360;
+ }
+#if defined(ANY_LINUX)
+ else { // For Linux, anything else is Auto
+ blocks = 0;
+ }
+#endif
+
+ return true;
+}
+
+bool FloppyData::setInitialDevice(const QString& dev)
+{
+
+ QString newDevice = dev;
+
+ KURL url( newDevice );
+ if( url.isValid() && ( url.protocol() == "media" || url.protocol() == "system" ) ) {
+ QString name = url.fileName();
+
+ DCOPRef mediamanager( "kded", "mediamanager" );
+ DCOPReply reply = mediamanager.call("properties(QString)", name);
+ if (!reply.isValid()) {
+ kdError() << "Invalid reply from mediamanager" << endl;
+ } else {
+ QStringList properties = reply;
+ newDevice = properties[5];
+ }
+ }
+
+ int drive = -1;
+ if ( newDevice.startsWith("/dev/fd0") )
+ drive = 0;
+ if ( newDevice.startsWith("/dev/fd1"))
+ drive = 1;
+
+ // ### TODO user given devices
+
+ bool ok = (drive>=0);
+ if (ok)
+ deviceComboBox->setCurrentItem(drive);
+ return ok;
+}
+
+void FloppyData::quit(){
+ if (formatActions) formatActions->quit();
+ writeSettings();
+ kapp->quit();
+ delete this;
+}
+
+void FloppyData::setEnabled(bool b)
+{
+ if (b)
+ unsetCursor();
+ else
+ setCursor(QCursor(WaitCursor));
+ label1->setEnabled(b);
+ deviceComboBox->setEnabled(b);
+ label2->setEnabled(b);
+ densityComboBox->setEnabled(b);
+ label3->setEnabled(b);
+ filesystemComboBox->setEnabled(b);
+ buttongroup->setEnabled(b);
+ quick->setEnabled(b);
+ fullformat->setEnabled(b && m_canLowLevel);
+ zerooutformat->setEnabled(b && m_canZeroOut);
+ verifylabel->setEnabled(b);
+ labellabel->setEnabled(b);
+ lineedit->setEnabled(b && labellabel->isChecked() );
+ helpbutton->setEnabled(b);
+ quitbutton->setEnabled(b);
+ formatbutton->setEnabled(b);
+ progress->setDisabled( b ); // The other way round!
+}
+
+void FloppyData::reset()
+{
+ DEBUGSETUP;
+
+ formating = false;
+
+ if (formatActions)
+ {
+ formatActions->quit();
+ delete formatActions;
+ formatActions = 0L;
+ }
+
+ progress->setValue(0);
+ formatbutton->setText(i18n("&Format"));
+ setEnabled(true);
+}
+
+void FloppyData::format(){
+
+ if(formating){
+ //abort = true;
+ reset();
+ return;
+ }
+
+ frame->clear();
+
+ const QString currentComboBoxDevice ( deviceComboBox->currentText() );
+ const bool userDevice = ( currentComboBoxDevice.startsWith ("/dev/") );
+
+#ifdef ANY_BSD
+ if ( userDevice && filesystemComboBox->currentText() != i18n("UFS"))
+ {
+ KMessageBox::error( this, i18n("BSD", "Formatting with BSD on a user-given device is only possible with UFS") );
+ return;
+ }
+ // no "else" !
+#endif
+ if ( userDevice && ( quick->isChecked() || zerooutformat->isChecked() ) )
+ {
+ if (KMessageBox::warningContinueCancel( this,
+ i18n("<qt>Formatting will erase all data on the device:<br/><b>%1</b><br/>"
+ "(Please check the correctness of the device name.)<br/>"
+ "Are you sure you wish to proceed?</qt>").arg( currentComboBoxDevice )
+ , i18n("Proceed?") ) != KMessageBox::Continue)
+ {
+ return;
+ }
+ }
+ else if ( userDevice )
+ {
+ // The user has selected full formatting on a user-given device. That is not supported yet!
+ KMessageBox::error( this, "Full formatting of a user-given device is not possible!" );
+ return;
+ }
+ else
+ {
+ if (KMessageBox::warningContinueCancel( this,
+ i18n("Formatting will erase all data on the disk.\n"
+ "Are you sure you wish to proceed?"), i18n("Proceed?") ) !=
+ KMessageBox::Continue)
+ {
+ return;
+ }
+ }
+
+ // formatbutton->setText(i18n("A&bort"));
+ setEnabled(false);
+
+ // Erase text box
+ frame->setText( QString::null );
+
+ if ( !userDevice )
+ {
+ if ( !findDevice() )
+ {
+ reset();
+ return;
+ }
+ }
+
+ if (formatActions) delete formatActions;
+ formatActions = new KFActionQueue(this);
+
+ connect(formatActions,SIGNAL(status(const QString &,int)),
+ this,SLOT(formatStatus(const QString &,int)));
+ connect(formatActions,SIGNAL(done(KFAction *,bool)),
+ this,SLOT(reset()));
+
+ if ( quick->isChecked())
+ {
+ formating=false;
+ // No fdformat to push
+ }
+ else if ( zerooutformat->isChecked() )
+ {
+ DDZeroOut* f = new DDZeroOut( this );
+ if ( userDevice )
+ {
+ f->configureDevice( currentComboBoxDevice );
+ }
+ else
+ {
+ f->configureDevice( drive, blocks );
+ }
+ formatActions->queue(f);
+ }
+ else if ( userDevice )
+ {
+ // We should not have got here, assume quick format
+ formating=false;
+ // No fdformat to push
+ }
+ else
+ {
+ FDFormat *f = new FDFormat(this);
+ f->configureDevice(drive,blocks);
+ f->configure(verifylabel->isChecked());
+ formatActions->queue(f);
+ }
+
+ if ( filesystemComboBox->currentText() == i18n("DOS") )
+ {
+ FATFilesystem *f = new FATFilesystem(this);
+ f->configure(verifylabel->isChecked(),
+ labellabel->isChecked(),
+ lineedit->text());
+ if ( userDevice )
+ {
+ f->configureDevice( currentComboBoxDevice );
+ }
+ else
+ {
+ f->configureDevice(drive,blocks);
+ }
+ formatActions->queue(f);
+ }
+
+ else if ( filesystemComboBox->currentText() == i18n("ext2") )
+ {
+ Ext2Filesystem *f = new Ext2Filesystem(this);
+ f->configure(verifylabel->isChecked(),
+ labellabel->isChecked(),
+ lineedit->text());
+ if ( userDevice )
+ {
+ f->configureDevice( currentComboBoxDevice );
+ }
+ else
+ {
+ f->configureDevice(drive,blocks);
+ }
+ formatActions->queue(f);
+ }
+
+#ifdef ANY_BSD
+ else if ( filesystemComboBox->currentText() == i18n("UFS") )
+ {
+ FloppyAction *f = new UFSFilesystem(this);
+ f->configureDevice(drive,blocks);
+ formatActions->queue(f);
+ }
+#endif
+
+#ifdef ANY_LINUX
+ else if ( filesystemComboBox->currentText() == i18n("Minix") )
+ {
+ MinixFilesystem *f = new MinixFilesystem(this);
+ f->configure(verifylabel->isChecked(),
+ labellabel->isChecked(),
+ lineedit->text());
+ if ( userDevice )
+ {
+ f->configureDevice( currentComboBoxDevice );
+ }
+ else
+ {
+ f->configureDevice(drive,blocks);
+ }
+ formatActions->queue(f);
+ }
+#endif
+
+
+
+ formatActions->exec();
+}
+
+void FloppyData::formatStatus(const QString &s,int p)
+{
+ kdDebug(2002) << "FloppyData::formatStatus: " << s << " : " << p << endl;
+ if (!s.isEmpty())
+ {
+ const QString oldText ( frame->text() );
+ if ( oldText.isEmpty() )
+ {
+ frame->setText( s );
+ }
+ else
+ {
+ frame->setText( oldText + '\n' + s );
+ }
+ }
+
+ if ((0<=p) && (p<=100))
+ progress->setValue(p);
+}
+
+void FloppyData::writeSettings(){
+
+ config = kapp->config();
+ config->setGroup("GeneralData");
+
+ densityconfig = densityComboBox->currentText().stripWhiteSpace();
+ filesystemconfig = filesystemComboBox->currentText().stripWhiteSpace();
+ driveconfig = deviceComboBox->currentText().stripWhiteSpace();
+
+ quickformatconfig = quick->isChecked();
+
+ labelnameconfig = lineedit->text().stripWhiteSpace();
+
+ labelconfig = labellabel->isChecked();
+
+ verifyconfig = verifylabel->isChecked();
+
+ config->writeEntry("CreateLabel",labelconfig);
+ config->writeEntry("Label",labelnameconfig);
+
+
+ config->writeEntry("QuickFormat",quickformatconfig);
+ config->writeEntry("FloppyDrive",driveconfig);
+ config->writeEntry("Density",densityconfig);
+ config->writeEntry("Filesystem",filesystemconfig);
+ config->writeEntry("Verify",verifyconfig);
+ config->sync();
+
+}
+
+void FloppyData::readSettings(){
+
+ config = kapp->config();
+ config->setGroup("GeneralData");
+
+ verifyconfig = config->readNumEntry("Verify", 1);
+ labelconfig = config->readNumEntry("CreateLabel",1);
+ labelnameconfig = config->readEntry( "Label", i18n("Volume label, maximal 11 characters", "KDE Floppy") );
+ quickformatconfig = config->readNumEntry("QuickFormat",0);
+ driveconfig = config->readEntry( "FloppyDrive", i18n("Primary") );
+#if defined(ANY_LINUX)
+ densityconfig = config->readEntry( "Density", i18n( "Auto-Detect" ) );
+#else
+ densityconfig = config->readEntry( "Density", i18n("3.5\" 1.44MB") );
+#endif
+ filesystemconfig = config->readEntry( "Filesystem", i18n("DOS") );
+
+}
+
+void FloppyData::setWidgets(){
+
+ labellabel->setChecked(labelconfig);
+ verifylabel->setChecked(verifyconfig);
+ quick->setChecked(quickformatconfig || !m_canLowLevel);
+ fullformat->setChecked(!quickformatconfig && m_canLowLevel);
+ lineedit->setText(labelnameconfig);
+
+ for(int i = 0 ; i < deviceComboBox->count(); i++){
+ if ( deviceComboBox->text(i) == driveconfig){
+ deviceComboBox->setCurrentItem(i);
+ }
+ }
+
+ for(int i = 0 ; i < filesystemComboBox->count(); i++){
+ if ( filesystemComboBox->text(i) == filesystemconfig){
+ filesystemComboBox->setCurrentItem(i);
+ }
+ }
+
+ for(int i = 0 ; i < densityComboBox->count(); i++){
+ if ( densityComboBox->text(i) == densityconfig){
+ densityComboBox->setCurrentItem(i);
+ }
+ }
+}
+
+#include "floppy.moc"
diff --git a/kfloppy/floppy.h b/kfloppy/floppy.h
new file mode 100644
index 0000000..2d4d519
--- /dev/null
+++ b/kfloppy/floppy.h
@@ -0,0 +1,128 @@
+/*
+
+ This file is part of the KFloppy program, part of the KDE project
+
+ Copyright (C) 1997 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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.
+
+*/
+
+#ifndef FloppyData_included
+#define FloppyData_included
+
+#include <kdialog.h>
+
+class QCheckBox;
+class QLineEdit;
+class QLabel;
+class QRadioButton;
+class QComboBox;
+class QButtonGroup;
+class QGroupBox;
+
+class KProgress;
+class KConfig;
+class KPushButton;
+class KHelpMenu;
+class KFAction;
+class KFActionQueue;
+
+class FloppyData : public KDialog
+{
+ Q_OBJECT
+
+public:
+ FloppyData(QWidget* parent = 0, const char * name = 0);
+ virtual ~FloppyData();
+
+ /// Need to overload normal show() in order to mangle caption
+ void show();
+ /// Maps combobox selection to drive and density
+ bool findDevice();
+ /// set default device
+ bool setInitialDevice(const QString& dev);
+ /** Override closeEvent() in order to properly close
+ the entire application.*/
+ void closeEvent(QCloseEvent*);
+ /// Writing the user-visible settings.
+ void writeSettings();
+ /// Reading the user-visible settings.
+ void readSettings();
+ /// Map stored settings to widget status
+ void setWidgets();
+ /// A kind of QString::find()
+ int findKeyWord(QString &, const QString &);
+ /// Enable/disable all UI elements
+ void setEnabled(bool);
+
+public slots:
+ void quit();
+ void format();
+ void reset();
+
+ void formatStatus(const QString &,int);
+
+protected slots:
+
+private:
+ int verifyconfig;
+ int labelconfig;
+ QString labelnameconfig;
+ int quickformatconfig;
+ QString driveconfig;
+ QString densityconfig;
+ QString filesystemconfig;
+ KConfig *config;
+
+ int drive;
+ /// Number of blocks of the floppy (typically 1440)
+ int blocks;
+
+ bool formating;
+ //bool abort;
+
+ QGroupBox* outerframe;
+ QLabel* label1;
+ QLabel* label2;
+ QLabel* label3;
+ QButtonGroup* buttongroup;
+ QCheckBox* verifylabel;
+ QCheckBox* labellabel;
+ QLineEdit* lineedit;
+ QRadioButton* quick;
+ QRadioButton* zerooutformat;
+ KPushButton* quitbutton;
+ KPushButton* helpbutton;
+ QRadioButton* fullformat;
+ KPushButton* formatbutton;
+ QLabel* frame;
+ QComboBox* deviceComboBox;
+ QComboBox* filesystemComboBox;
+ QComboBox* densityComboBox;
+ KProgress* progress;
+ KHelpMenu* helpMenu;
+
+ KFActionQueue *formatActions;
+
+ bool m_canLowLevel; ///< Low level formatting is possible (i.e. was fdformat found?)
+ bool m_canZeroOut; ///< Is zero-out possible (i.e. was dd found?)
+protected:
+ void keyPressEvent(QKeyEvent *e);
+
+};
+
+#endif // FloppyData_included
diff --git a/kfloppy/floppy_format.desktop b/kfloppy/floppy_format.desktop
new file mode 100644
index 0000000..b780ac9
--- /dev/null
+++ b/kfloppy/floppy_format.desktop
@@ -0,0 +1,54 @@
+[Desktop Action Format]
+Exec=kfloppy %u
+Icon=kfloppy
+Name=Format
+Name[ar]=تهيئة
+Name[bg]=Форматиране
+Name[br]=Furmadiñ
+Name[ca]=Dona format
+Name[cs]=Formátovat
+Name[cy]=Fformat
+Name[de]=Formatieren
+Name[el]=Διαμόρφωση
+Name[eo]=Formato
+Name[es]=Formatear
+Name[et]=Vorminda
+Name[fa]=قالب‌بندی
+Name[fr]=Formater
+Name[ga]=Formáid
+Name[he]=פורמט
+Name[hu]=Formázás
+Name[is]=Forsníða
+Name[it]=Formatta
+Name[ja]=フォーマット
+Name[ka]=ფორმატი
+Name[kk]=Дискетаны пішімдеу
+Name[km]=ធ្វើ​ទ្រង់ទ្រាយ
+Name[lt]=Formatas
+Name[nds]=Formateren
+Name[ne]=ढाँचा
+Name[nl]=Formatteren
+Name[nn]=Formater
+Name[pa]=ਫਾਰਮਿਟ
+Name[pl]=Formatuj
+Name[pt]=Formatar
+Name[pt_BR]=Formatar
+Name[ru]=Форматирование дискет
+Name[rw]=Imiterere
+Name[sk]=Formátovanie
+Name[sl]=Formatiraj
+Name[sr]=Форматирај
+Name[sr@Latn]=Formatiraj
+Name[tr]=Biçimlendir
+Name[uk]=Форматування
+Name[uz]=Formatlash
+Name[uz@cyrillic]=Форматлаш
+Name[wa]=Abwesner
+Name[zh_CN]=格式化
+Name[zh_TW]=格式化
+
+[Desktop Entry]
+Actions=Format;
+ServiceTypes=media/floppy_unmounted,media/floppy5_unmounted
+X-KDE-Priority=TopLevel
+X-KDE-MediaNotifierHide=true
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"
diff --git a/kfloppy/format.h b/kfloppy/format.h
new file mode 100644
index 0000000..0200d22
--- /dev/null
+++ b/kfloppy/format.h
@@ -0,0 +1,426 @@
+/*
+
+ 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.
+
+*/
+
+#ifndef FORMAT_H
+#define FORMAT_H
+
+/** \file format.h
+ * This file defines a hierarchy of classes that
+ * can run a sequence of external programs (like
+ * fdformat, mkisofs, etc.) in sequence. Stdout
+ * and stderr of those programs can be captured
+ * and analyzed in order to provide feedback to
+ * the user.
+ *
+ * <ul>
+ * <li>KFAction: Base class, just for performing some action.
+ * <li>KFActionQueue: Provides sequencing of KFActions
+ * <li>FloppyAction: Weird name; handles running a program,
+ * understands FD device names. This can be
+ * considered the "useful" base class of
+ * programming actions.
+ * <li>FDFormat: Runs fdformat(1) under BSD or Linux.
+ * <li>FATFilesystem: Creates an msdos (FAT) filesystem.
+ * <li>Ext2Filesystem: Creates ext2 filesystems.
+ * <li>MinixFilesystem: Creates Minix filesystems, under Linux.
+ * <li>UFSFilesystem: Creates UFS filesystem, under BSD.
+ * </ul>
+ *
+ * \note Maybe this is overkill, since for floppies all you need is
+ * fdformat(1) and some create-filesystem program like newfs(1)
+ * or mke2fs(1). However, for Zip disks, should they ever be supported,
+ * this is quite useful since you need to dd, fdisk, disklabel, and
+ * newfs them.
+*/
+
+#include "debug.h"
+#include <qobject.h>
+
+/**
+ * \brief Abstract base class of actions to be undertaken.
+ *
+ * Basically you can create a KFActionStack (See below)
+ * and push a bunch of actions on it, then run exec()
+ * on the stack and wait for the done() signal.
+*/
+class KFAction : public QObject
+{
+Q_OBJECT
+
+public:
+ KFAction(QObject *parent = 0L);
+ virtual ~KFAction();
+
+public slots:
+ /**
+ * Exec() should return quickly to ensire that the GUI
+ * thread stays alive. quit() should abort the action.
+ */
+ virtual void exec();
+ /**
+ * Quit aborts the action. No done() signal should
+ * be emitted.
+ */
+ virtual void quit();
+
+signals:
+ /**
+ * done() should always be emitted with this as first
+ * parameter, to avoid sender() magic and the like.
+ * @p success indicates whether the action was
+ * successful.
+ */
+ void done(KFAction *me,bool success);
+
+ /**
+ * Emit this signal to inform the user of interesting
+ * changes; setting msg to an empty string doesn't
+ * change any visible user message. @p progress
+ * indicates the action's progress (if that can be determined)
+ * and sending -1 leaves the visible indicator unchanged.
+ */
+ void status(const QString &msg, int progress);
+
+ /** error() displays a box. It interrupts
+ * the user's work and should be used with care.
+ */
+ void error(const QString &msg, const QString &details);
+} ;
+
+
+/**
+ * Acts as a queue and executes the actions in the
+ * queue in FIFO order.
+ */
+class KFActionQueue : public KFAction
+{
+Q_OBJECT
+
+public:
+ KFActionQueue(QObject *parent = 0L);
+ virtual ~KFActionQueue();
+
+ /**
+ * Add a KFAction to the queue. When exec() is called,
+ * the actions are called one after the other (if each
+ * action is successful; if any action fails, the whole
+ * queue fails and the unsuccessful action is the last
+ * one run.) Actions become the property of the queue
+ * action. Note that queues can be nested.
+ */
+ void queue(KFAction *);
+
+ virtual void exec();
+
+protected slots:
+ void actionDone(KFAction *,bool);
+
+private:
+ class KFActionQueue_p *d;
+} ;
+
+
+/*
+** The remainder of the Actions are concrete ones and
+** might better go off to live in another header file,
+** but this is only needed if the number of supported
+** formats grows enormously.
+*/
+
+/**
+ * Description structure for floppy devices.
+ * devices is a list of possible device names (yay
+ * /dev/ consistency) while drive,blocks denotes
+ * fd0 or fd1, and the size of the disk (ought to
+ * be 1440, 1200, 720 or 360. I've never seen a 2880
+ * floppy drive).
+ *
+ * Tracks is pretty bogus; see the internal code for its use.
+ * Similarly, flags are internal too.
+ */
+
+typedef struct { const char **devices;
+ int drive;
+ int blocks;
+ int tracks;
+ int flags; } fdinfo;
+
+class KProcess;
+
+/**
+ * Concrete action for running a single external program.
+ */
+
+class FloppyAction : public KFAction
+{
+Q_OBJECT
+
+public:
+ FloppyAction(QObject *parent = 0L);
+
+ /**
+ * Kills the running process, if one exists.
+ */
+ virtual void quit();
+
+ /**
+ * ConfigureDevice() needs to be called prior to exec()
+ * or exec() will fail; this indicates which drive and
+ * density to use.
+ *
+ * \param driveno Number of drive (0 or 1)
+ * \param density Floppy density (in Kilobytes)
+ * \note This same function needs to be
+ * called on all subclasses in order to configure them
+ * for which drive to use, _along_ with their local
+ * configuration functions.
+ */
+
+ bool configureDevice(int driveno, int density );
+
+ /**
+ * \brief Configure the device with a device name
+ *
+ * This is an alternate to FloppyAction::configureDevice
+ * for user-given devices.
+ *
+ * \note It does not work for each type of FloppyAction yet
+ */
+ bool configureDevice( const QString& newDeviceName );
+
+protected:
+ fdinfo *deviceInfo; ///< Configuration info (Pointer into list of "/dev/..." entries)
+ QString deviceName; ///< Name of the device
+
+protected slots:
+ /**
+ * \brief Provide handling of the exit of the external program
+ */
+ virtual void processDone(KProcess *);
+ /**
+ * \brief Provide handling of stdout
+ */
+ virtual void processStdOut(KProcess *, char *, int);
+ /**
+ * \brief Provide handling stderr.
+ *
+ * The default implementation just sends stderr on
+ * to processStdOut(), so you need reimplement only
+ * FloppyAction::processStdOut if you choose.
+ */
+ virtual void processStdErr(KProcess *, char *, int);
+
+protected:
+ KProcess *theProcess;
+ QString theProcessName; ///< human-readable
+
+ /**
+ * Sets up connections, calls KProcess::run().
+ * You need to *theProcess << program << args ; first.
+ */
+
+ bool startProcess();
+} ;
+
+/**
+ * Concrete class that runs fdformat(1)
+ */
+
+class FDFormat : public FloppyAction
+{
+public:
+ FDFormat(QObject *parent = 0L);
+
+ virtual void exec();
+
+
+ /**
+ * Concrete classes can provide a runtimeCheck
+ * function (heck, this is static, so the name
+ * is up to you) that checks if the required
+ * applications are available. This way, the
+ * calling application can decide not to use
+ * actions whose prerequisites are absent anyway.
+ */
+ static bool runtimeCheck();
+
+ /** @p verify instructs fdformat(1) to verify the
+ * medium as well.
+ */
+
+ bool configure(bool verify);
+
+ virtual void processStdOut(KProcess *, char *,int);
+
+protected:
+ static QString fdformatName; ///< path to executable.
+ int formatTrackCount; ///< How many tracks formatted.
+ bool doVerify;
+} ;
+
+/**
+ * Zero out disk by runnind dd(1)
+ * \bug As dd terminates with the error "No space left on device", KFloppy aborts
+ */
+class DDZeroOut : public FloppyAction
+{
+public:
+ DDZeroOut(QObject *parent = 0L);
+
+ virtual void exec();
+
+ /**
+ * Concrete classes can provide a runtimeCheck
+ * function (heck, this is static, so the name
+ * is up to you) that checks if the required
+ * applications are available. This way, the
+ * calling application can decide not to use
+ * actions whose prerequisites are absent anyway.
+ */
+ static bool runtimeCheck();
+
+protected:
+ /**
+ * \brief Provide handling of the exit of the external program
+ */
+ virtual void processDone(KProcess *);
+protected:
+ static QString m_ddName; ///< path to executable.
+} ;
+
+
+/**
+ * Create an msdos (FAT) filesystem on the floppy.
+ */
+class FATFilesystem : public FloppyAction
+{
+public:
+ FATFilesystem(QObject *parent = 0L);
+
+ virtual void exec();
+
+ static bool runtimeCheck();
+
+ /**
+ * newfs_msdos(1) doesn't support an additional verify,
+ * but Linux mkdosfs(1) does. Enable additional medium
+ * verify with @p verify. Disks can be labeled (@p label) with the
+ * remaining parameters (@p l).
+ */
+ bool configure(bool verify, bool label, const QString &l);
+
+ /// Parse output
+ virtual void processStdOut(KProcess*, char* b, int l);
+
+protected:
+ static QString newfs_fat;
+
+ bool doVerify,doLabel;
+ QString label;
+
+} ;
+
+/**
+ * Format with Ext2
+ */
+class Ext2Filesystem : public FloppyAction
+{
+public:
+ Ext2Filesystem(QObject *parent = 0L);
+
+ virtual void exec();
+
+ static bool runtimeCheck();
+
+ /// Same args as FATFilesystem::configure
+ bool configure(bool verify, bool label, const QString &l);
+
+ /// Parse output
+ virtual void processStdOut(KProcess*, char* b, int l);
+
+protected:
+ static QString newfs;
+
+ bool doVerify,doLabel;
+ QString label;
+} ;
+
+#ifdef ANY_BSD
+
+/**
+ * \brief Format with UFS
+ * \note BSD only
+ */
+class UFSFilesystem : public FloppyAction
+{
+public:
+ UFSFilesystem(QObject *parent = 0L);
+
+ virtual void exec();
+
+ static bool runtimeCheck();
+
+protected:
+ static QString newfs;
+
+ bool doVerify,doLabel;
+ QString label;
+} ;
+#endif
+
+#ifdef ANY_LINUX
+/**
+ * \brief Format with Minix
+ * \note Linux only
+ */
+class MinixFilesystem : public FloppyAction
+{
+public:
+ MinixFilesystem(QObject *parent = 0L);
+
+ virtual void exec();
+
+ static bool runtimeCheck();
+
+ /// Same args as FATFilesystem::configure
+ bool configure(bool verify, bool label, const QString &l);
+
+ /// Parse output
+ virtual void processStdOut(KProcess*, char* b, int l);
+protected:
+ static QString newfs;
+
+ bool doVerify,doLabel;
+ QString label;
+} ;
+#endif
+
+/**
+ * Utility function that looks for executables in $PATH
+ * and in /sbin and /usr/sbin.
+ */
+
+QString findExecutable(const QString &);
+
+#endif
+
diff --git a/kfloppy/hi128-app-kfloppy.png b/kfloppy/hi128-app-kfloppy.png
new file mode 100644
index 0000000..ded3594
--- /dev/null
+++ b/kfloppy/hi128-app-kfloppy.png
Binary files differ
diff --git a/kfloppy/hi16-app-kfloppy.png b/kfloppy/hi16-app-kfloppy.png
new file mode 100644
index 0000000..3b272fb
--- /dev/null
+++ b/kfloppy/hi16-app-kfloppy.png
Binary files differ
diff --git a/kfloppy/hi22-app-kfloppy.png b/kfloppy/hi22-app-kfloppy.png
new file mode 100644
index 0000000..c0b2fe3
--- /dev/null
+++ b/kfloppy/hi22-app-kfloppy.png
Binary files differ
diff --git a/kfloppy/hi32-app-kfloppy.png b/kfloppy/hi32-app-kfloppy.png
new file mode 100644
index 0000000..a1bfb30
--- /dev/null
+++ b/kfloppy/hi32-app-kfloppy.png
Binary files differ
diff --git a/kfloppy/hi48-app-kfloppy.png b/kfloppy/hi48-app-kfloppy.png
new file mode 100644
index 0000000..b53fc09
--- /dev/null
+++ b/kfloppy/hi48-app-kfloppy.png
Binary files differ
diff --git a/kfloppy/hi64-app-kfloppy.png b/kfloppy/hi64-app-kfloppy.png
new file mode 100644
index 0000000..c03b4b3
--- /dev/null
+++ b/kfloppy/hi64-app-kfloppy.png
Binary files differ
diff --git a/kfloppy/main.cpp b/kfloppy/main.cpp
new file mode 100644
index 0000000..f6aa98f
--- /dev/null
+++ b/kfloppy/main.cpp
@@ -0,0 +1,79 @@
+/*
+
+ This file is part of the KFloppy program, part of the KDE project
+
+ Copyright (C) 1997 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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 <kdeversion.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+
+#include "floppy.h"
+
+
+static const char description[] =
+ I18N_NOOP("KDE Floppy Disk Utility");
+
+static const KCmdLineOptions options[] =
+{
+ { "+[device]", I18N_NOOP("Default device"), 0 },
+ KCmdLineLastOption
+};
+
+int main( int argc, char *argv[] )
+{
+ KAboutData aboutData("kfloppy",
+ I18N_NOOP("KFloppy"),
+ KDE_VERSION_STRING, description, KAboutData::License_GPL,
+ "(c) 1997, Bernd Johannes Wuebben\n"
+ "(c) 2001, Chris Howells\n"
+ "(c) 2002, Adriaan de Groot\n"
+ "(c) 2004, 2005, Nicolas Goutte",
+ I18N_NOOP("KFloppy helps you format floppies with the filesystem of your choice.")
+ );
+
+ aboutData.addAuthor("Bernd Johannes Wuebben", I18N_NOOP("Author and former maintainer"), "wuebben@kde.org");
+ aboutData.addCredit("Chris Howells", I18N_NOOP("User interface re-design"), "howells@kde.org");
+ aboutData.addCredit("Adriaan de Groot", I18N_NOOP("Add BSD support"), "groot@kde.org");
+ aboutData.addCredit("Nicolas Goutte", I18N_NOOP("Make KFloppy work again for KDE 3.4"), "goutte@kde.org");
+
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ QString device;
+ if (args->count()) {
+ device = args->arg(0);
+ }
+ args->clear();
+
+ KApplication a;
+
+ FloppyData* floppy = new FloppyData();
+ a.setMainWidget(floppy);
+ bool autoformat = floppy->setInitialDevice(device);
+ floppy->show();
+ if (autoformat)
+ floppy->format();
+ return a.exec();
+}
+
diff --git a/kfloppy/zip.cpp b/kfloppy/zip.cpp
new file mode 100644
index 0000000..8a0ff29
--- /dev/null
+++ b/kfloppy/zip.cpp
@@ -0,0 +1,305 @@
+/*
+
+ This file is part of the KFloppy program, part of the KDE project
+
+ Copyright (C) 2002 by Adriaan de Groot
+
+
+ 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.
+
+ 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <sys/types.h>
+#include <signal.h>
+
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "debug.h"
+#include "zip.moc"
+
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qwhatsthis.h>
+
+#include <klocale.h>
+#include <kprocess.h>
+#include <kconfig.h>
+
+ZipFormat::ZipFormat(QWidget *w,const char *n) :
+ DiskFormat(w,n),
+ zeroWholeDisk(0L),
+ p(0L),
+ formatStep(0),
+ statusTimer(0L)
+{
+ DEBUGSETUP;
+
+ QGridLayout *grid = new QGridLayout(this,1,1,10);
+
+ zeroWholeDisk = new QCheckBox(i18n("Zero entire disk"),this);
+ QWhatsThis::add(zeroWholeDisk,
+ i18n("Try to write zeroes to the entire disk "
+ "before adding a filesystem, in order "
+ "to check the disk's integrity."));
+ grid->addWidget(zeroWholeDisk,0,0);
+ enableSoftUpdates = new QCheckBox(i18n("Enable softupdates"),this);
+ grid->addWidget(enableSoftUpdates,1,0);
+
+ // Remember the stretch at the bottom to clear
+ // up layour problems when this widget is smaller
+ // than others in the stack.
+ //
+ grid->addRowSpacing(2,10);
+ grid->setRowStretch(2,100);
+
+ endInit();
+}
+
+const char fslabel[] = I18N_NOOP("UFS Zip100");
+
+FilesystemList ZipFormat::FSLabels() const
+{
+ FilesystemList l;
+ // THis isn't a basic format anywhere, I don't think.
+ l.append(new FilesystemData(i18n(fslabel),0xefc87329,(DiskFormat *)this));
+ return l;
+}
+
+/* static */ bool ZipFormat::runtimeCheck()
+{
+ DEBUGSETUP;
+ dd = findExecutable("dd");
+ newfs = findExecutable("newfs");
+ return !newfs.isEmpty() && !dd.isEmpty();
+}
+
+/* static */ QString ZipFormat::dd;
+/* static */ QString ZipFormat::newfs;
+
+/* virtual slot */ void ZipFormat::setEnabled(bool b)
+{
+ zeroWholeDisk->setEnabled(b);
+ enableSoftUpdates->setEnabled(b);
+}
+
+/* virtual */ void ZipFormat::readSettings(KConfig *c)
+{
+ c->setGroup(fslabel);
+ zeroWholeDisk->setChecked(
+ c->readBoolEntry("ZeroDisk",false));
+ enableSoftUpdates->setChecked(
+ c->readBoolEntry("SoftUpdates",false));
+}
+
+/* virtual */ void ZipFormat::writeSettings(KConfig *c)
+{
+ c->setGroup(fslabel);
+ c->writeEntry("ZeroDisk",zeroWholeDisk->isChecked());
+ c->writeEntry("SoftUpdates",enableSoftUpdates->isChecked());
+}
+
+void ZipFormat::quit()
+{
+ DEBUGSETUP;
+ if (p) delete p;
+ if (statusTimer) delete statusTimer;
+
+ p=0L;
+ statusTimer=0L;
+}
+
+/* virtual slot */ void ZipFormat::format(FilesystemData *f)
+{
+ DEBUGSETUP;
+
+ if (f->magic()!=0xefc87329)
+ {
+ complainAboutFormat(f);
+ return;
+ }
+
+ formatStep=0;
+
+ if (p) delete p;
+ p = new KProcess();
+
+ if (statusTimer) delete statusTimer;
+ statusTimer = new QTimer(this);
+
+ connect(p,SIGNAL(processExited(KProcess *)),
+ this,SLOT(transition()));
+ connect(p,SIGNAL(receivedStdout(KProcess *,char *,int)),
+ this,SLOT(processResult(KProcess *,char *,int)));
+ connect(p,SIGNAL(receivedStderr(KProcess *,char *,int)),
+ this,SLOT(processResult(KProcess *,char *,int)));
+ connect(statusTimer,SIGNAL(timeout()),
+ this,SLOT(statusRequest()));
+
+ transition();
+}
+
+void ZipFormat::transition()
+{
+ DEBUGSETUP;
+
+ switch(formatStep)
+ {
+ case 0 :
+ // We're using a larger block size to speed up writing.
+ // So instead of 196608 blocks of 512b, use 12288 blocks
+ // of 8k instead.
+ //
+ // For newfs we need to set the real number of blocks.
+ //
+ if (zeroWholeDisk->isChecked())
+ {
+ // Zeroing whole disk takes about 2 min.
+ // No point in making a dizzy display of it.
+ statusTimer->start(10000);
+ QTimer::singleShot(1000,this,
+ SLOT(statusRequest()));
+ totalBlocks=12288; // 196608 * 512b = 12288 * 8192b ;
+ }
+ else
+ {
+ // Takes about 5 seconds.
+ statusTimer->start(1000);
+ totalBlocks=100;
+ }
+
+ *p << dd
+ << "if=/dev/zero"
+ << "of=/dev/afd0c"
+ << "bs=8192" ;
+ *p << QString("count=%1").arg(totalBlocks);
+ if (!p->start(KProcess::NotifyOnExit,KProcess::AllOutput))
+ {
+ emit statusMessage(i18n("Cannot start dd to zero disk."));
+ emit formatDone(-1);
+ delete statusTimer;
+ delete p;
+ statusTimer=0L;
+ p=0L;
+ return;
+ }
+
+ formatStep=1;
+ emit statusMessage(i18n("Zeroing disk..."));
+ break;
+ case 1 :
+ statusTimer->stop();
+ // The dd for zeroing the disk has finished.
+ if (p->exitStatus())
+ {
+ emit statusMessage(i18n("Zeroing disk failed."));
+ emit formatDone(-1);
+ return;
+ }
+
+ totalBlocks=196608; // Now use the real number of 512b blocks
+
+ p->clearArguments();
+ *p << newfs << "-T" << "zip100" ;
+ if (enableSoftUpdates->isChecked())
+ {
+ *p << "-U" ;
+ }
+ *p << "/dev/afd0c" ;
+ if (!p->start(KProcess::NotifyOnExit,KProcess::AllOutput))
+ {
+ emit statusMessage(i18n("Cannot start newfs."));
+ emit formatDone(-1);
+ };
+ formatStep=2;
+ emit statusMessage(i18n("Making filesystem..."));
+ break;
+ case 2 :
+ if (p->exitStatus())
+ {
+ emit statusMessage(i18n("newfs failed."));
+ emit formatDone(-1);
+ }
+ else
+ {
+ emit statusMessage(i18n("Disk formatted successfully."));
+ emit formatDone(0);
+ }
+ break;
+ }
+}
+
+void ZipFormat::processResult(KProcess *, char *b, int l)
+{
+ DEBUGSETUP;
+
+#ifdef DEBUG
+ QString o = QString::fromLatin1(b,l);
+ DEBUGS(QString(" %1").arg(o).latin1());
+#endif
+
+ switch(formatStep)
+ {
+ case 1 : // These are messages from dd
+ if (strchr(b,'+'))
+ {
+ int currentblock=atoi(b);
+ emit setProgress(currentblock*100/totalBlocks);
+ if (totalBlocks>10000)
+ {
+ emit statusMessage(i18n("Zeroing block %1 of %2...")
+ .arg(currentblock)
+ .arg(totalBlocks));
+ }
+ }
+ break;
+ case 2 : // These are messages from newfs
+ if ((b[0]==' ') && isdigit(b[1]))
+ {
+ int currentblock=atoi(b+1);
+ emit setProgress(currentblock*100/totalBlocks);
+ }
+ else
+ {
+ // This is the initial display message from
+ // newfs. It writes a first block to sector 32.
+ //
+ //
+ emit setProgress(1);
+
+ // QString myBuf = QString::fromLatin1(b, l);
+ // DEBUGS(myBuf.latin1());
+ }
+ break;
+ }
+}
+
+void ZipFormat::statusRequest()
+{
+ if (formatStep!=1) // Not in dd mode?
+ return;
+ if (!p) // How can that happen?
+ return;
+
+#ifdef ANY_BSD
+ p->kill(SIGINFO);
+#endif
+}
+
+
diff --git a/kfloppy/zip.h b/kfloppy/zip.h
new file mode 100644
index 0000000..0054c50
--- /dev/null
+++ b/kfloppy/zip.h
@@ -0,0 +1,106 @@
+/*
+
+ This file is part of the KFloppy program, part of the KDE project
+
+ Copyright (C) 2002 by Adriaan de Groot
+
+
+ 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.
+
+ 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.
+
+*/
+
+
+#ifndef _ZIP_FORMAT_H
+#define _ZIP_FORMAT_H
+
+/**
+ * \file zip.h
+ *
+ * This file defines the ZipFormat class, a DiskFormat
+ * for KFloppy that deals with Zip disks and UFS under
+ * FreeBSD (and probably other BSD's, as well).
+ *
+ * \todo Add device selector to zip class
+ * \note This class is not used by KFloppy
+ * \bug This class assumes thatthe Zip disk has 100MB. It does not support 250MB and 750MB
+ */
+
+#include "format.h"
+
+class QCheckBox;
+class QTimer;
+class KProcess;
+class KConfig;
+
+class ZipFormat : public DiskFormat
+{
+Q_OBJECT
+
+public:
+ ZipFormat(QWidget *w, const char *n);
+
+ // All the virtuals we need to make
+ // a concrete DiskFormat class. See
+ // format.h for details.
+ //
+ virtual FilesystemList FSLabels() const;
+ virtual void setEnabled(bool);
+ virtual void format(FilesystemData *);
+ virtual void quit();
+ virtual void readSettings(KConfig *);
+ virtual void writeSettings(KConfig *);
+
+ /** Check for dd and newfs, which we
+ * need to do the formatting.
+ */
+ static bool runtimeCheck();
+
+protected:
+ QCheckBox *zeroWholeDisk;
+ QCheckBox *enableSoftUpdates;
+
+ static QString newfs,dd;
+
+ KProcess *p; ///< dd or newfs, doing the real work
+ int formatStep; ///< keeps track of what phase we are in
+
+ // Variables for the zeroing phase
+ int totalBlocks;
+ QTimer *statusTimer;
+
+protected slots:
+ /**
+ * transition() realises the state machine we use
+ * to handle the different phases of the format:
+ * startup, dd and newfs.
+ */
+ void transition();
+
+ /**
+ * processResult() reads output
+ * from either dd or newfs and interprets it.
+ */
+ void processResult(KProcess *,char *,int);
+
+ /**
+ *statusRequest()
+ * sends dd a SIGINFO to get it to print out block counts,
+ * which then triggers processResult() so that we can keep
+ * the progress bar moving.
+ */
+ void statusRequest();
+};
+
+#endif