File indexing completed on 2024-04-14 05:43:23
0001 /* 0002 0003 This file is part of the KFloppy program, part of the KDE project 0004 0005 Copyright (C) 2002 Adriaan de Groot <groot@kde.org> 0006 Copyright (C) 2004, 2005 Nicolas GOUTTE <goutte@kde.org> 0007 Copyright (C) 2015, 2016 Wolfgang Bauer <wbauer@tmo.at> 0008 0009 This program is free software; you can redistribute it and/or modify 0010 it under the terms of the GNU General Public License as published by 0011 the Free Software Foundation, version 2. 0012 0013 This program is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0016 GNU General Public License for more details. 0017 0018 You should have received a copy of the GNU General Public License 0019 along with this program; if not, write to the Free Software 0020 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0021 0022 */ 0023 0024 #include "format.h" 0025 0026 #include <stdlib.h> 0027 #include <unistd.h> 0028 0029 #include "qplatformdefs.h" 0030 #include <QRegExp> 0031 #include <QStandardPaths> 0032 #include <QTimer> 0033 0034 #include <KLocalizedString> 0035 #include <KProcess> 0036 0037 static QStringList extPath = QStringList(); 0038 0039 /* static */ QString findExecutable(const QString &e) 0040 { 0041 if (extPath.isEmpty()) { 0042 QStringList path = QString::fromLocal8Bit(qgetenv("PATH")).split(QStringLiteral(":")); 0043 path.append(QStringLiteral("/usr/sbin")); 0044 path.append(QStringLiteral("/sbin")); 0045 extPath = path; 0046 } 0047 0048 return QStandardPaths::findExecutable(e, extPath); 0049 } 0050 0051 KFAction::KFAction(QObject *parent) 0052 : QObject(parent) 0053 { 0054 DEBUGSETUP; 0055 } 0056 0057 KFAction::~KFAction() 0058 { 0059 DEBUGSETUP; 0060 quit(); 0061 } 0062 0063 /* slot */ void KFAction::quit() 0064 { 0065 DEBUGSETUP; 0066 } 0067 0068 /* slot */ void KFAction::exec() 0069 { 0070 DEBUGSETUP; 0071 } 0072 0073 class KFActionQueue_p 0074 { 0075 public: 0076 QList<KFAction *> list; 0077 }; 0078 0079 KFActionQueue::KFActionQueue(QObject *parent) 0080 : KFAction(parent) 0081 , d(new KFActionQueue_p) 0082 { 0083 DEBUGSETUP; 0084 } 0085 0086 KFActionQueue::~KFActionQueue() 0087 { 0088 DEBUGSETUP; 0089 qDeleteAll(d->list); 0090 d->list.clear(); 0091 delete d; 0092 } 0093 0094 void KFActionQueue::queue(KFAction *p) 0095 { 0096 DEBUGSETUP; 0097 0098 d->list.append(p); 0099 DEBUGS(p->objectName()); 0100 } 0101 0102 /* virtual */ void KFActionQueue::exec() 0103 { 0104 DEBUGSETUP; 0105 0106 actionDone(nullptr, true); 0107 } 0108 0109 /* slot */ void KFActionQueue::actionDone(KFAction *p, bool success) 0110 { 0111 DEBUGSETUP; 0112 0113 if (p) { 0114 if (!d->list.isEmpty() && d->list.first() == p) { 0115 d->list.removeFirst(); 0116 delete p; 0117 } else { 0118 DEBUGS("Strange pointer received."); 0119 Q_EMIT done(this, false); 0120 return; 0121 } 0122 } else { 0123 DEBUGS("Starting action queue."); 0124 } 0125 0126 if (!success) { 0127 DEBUGS("Action failed."); 0128 Q_EMIT done(this, false); 0129 return; 0130 } 0131 0132 KFAction *next = d->list.isEmpty() ? nullptr : d->list.first(); 0133 if (!next) { 0134 Q_EMIT done(this, true); 0135 } else { 0136 qCDebug(KFLOPPY_LOG) << "Running action " << next->objectName(); 0137 QObject::connect(next, &KFAction::done, this, &KFActionQueue::actionDone); 0138 // Propagate signals 0139 QObject::connect(next, &KFAction::status, this, &KFAction::status); 0140 QTimer::singleShot(0, next, &KFAction::exec); 0141 } 0142 } 0143 0144 // Here we have names of devices. The variable 0145 // names are basically the linux device names, 0146 // replace with whatever your OS needs instead. 0147 // 0148 // 0149 #ifdef ANY_LINUX 0150 0151 const char *const fd0H1440[] = {"/dev/fd0u1440", "/dev/floppy/0u1440", "/dev/fd0h1440", "/dev/fd0H1440", "/dev/fd0", nullptr}; 0152 const char *const fd0D720[] = {"/dev/fd0u720", "/dev/floppy/0u720", "/dev/fd0D720", "/dev/fd0h720", "/dev/fd0", nullptr}; 0153 const char *const fd0h1200[] = {"/dev/fd0h1200", "/dev/floppy/0h1200", "/dev/fd0", nullptr}; 0154 const char *const fd0h360[] = {"/dev/fd0u360", "/dev/floppy/0u360", "/dev/fd0h360", "/dev/fd0d360", "/dev/fd0", nullptr}; 0155 0156 const char *const fd1H1440[] = {"/dev/fd1u1440", "/dev/floppy/1u1440", "/dev/fd1h1440", "/dev/fd1H1440", "/dev/fd1", nullptr}; 0157 const char *const fd1D720[] = {"/dev/fd1u720", "/dev/floppy/1u720", "/dev/fd1D720", "/dev/fd1h720", "/dev/fd1", nullptr}; 0158 const char *const fd1h1200[] = {"/dev/fd1h1200", "/dev/floppy/1h1200", "/dev/fd1", nullptr}; 0159 const char *const fd1h360[] = {"/dev/fd1u360", "/dev/floppy/1u360", "/dev/fd1h360", "/dev/fd1d360", "/dev/fd1", nullptr}; 0160 0161 const char *const fd0auto[] = {"/dev/fd0", nullptr}; 0162 const char *const fd1auto[] = {"/dev/fd1", nullptr}; 0163 0164 #endif 0165 0166 #ifdef ANY_BSD 0167 const char *const fd0[] = {"/dev/fd0", nullptr}; 0168 const char *const fd1[] = {"/dev/fd1", nullptr}; 0169 #endif 0170 0171 // Next we have a table of device names and characteristics. 0172 // These are ordered according to 2*densityIndex+deviceIndex, 0173 // ie. primary (0) 1440K (0) is first, then secondary (1) 1440K is 0174 // second, down to secondary (1) 360k (4) in position 3*2+1=7. 0175 // 0176 // 0177 // Note that the data originally contained in KFloppy was 0178 // patently false, so most of this is fake. I guess no one ever 0179 // formatted a 5.25" floppy. 0180 // 0181 // The flags field is unused in this implementation. 0182 // 0183 // 0184 const fdinfo fdtable[] = { 0185 #ifdef ANY_LINUX 0186 // device drv blks trk flg 0187 {fd0H1440, 0, 1440, 80, 0}, 0188 {fd1H1440, 1, 1440, 80, 0}, 0189 {fd0D720, 0, 720, 80, 0}, 0190 {fd1D720, 1, 720, 80, 0}, 0191 {fd0h1200, 0, 1200, 80, 0}, 0192 {fd1h1200, 1, 1200, 80, 0}, 0193 {fd0h360, 0, 360, 40, 0}, 0194 {fd1h360, 1, 360, 40, 0}, 0195 {fd0auto, 0, 0, 80, 0}, 0196 {fd1auto, 1, 0, 80, 0}, 0197 #endif 0198 0199 #ifdef ANY_BSD 0200 // Instead of the number of tracks, which is 0201 // unneeded, we record the 0202 // number of F's printed during an fdformat 0203 {fd0, 0, 1440, 40, 0}, 0204 {fd1, 1, 1440, 40, 0}, 0205 {fd0, 0, 720, 40, 0}, 0206 {fd1, 1, 720, 40, 0}, 0207 {fd0, 0, 1200, 40, 0}, 0208 {fd1, 1, 1200, 40, 0}, 0209 {fd0, 0, 360, 40, 0}, 0210 {fd1, 1, 360, 40, 0}, 0211 #endif 0212 {nullptr, 0, 0, 0, 0}}; 0213 0214 FloppyAction::FloppyAction(QObject *p) 0215 : KFAction(p) 0216 , deviceInfo(nullptr) 0217 , theProcess(nullptr) 0218 { 0219 DEBUGSETUP; 0220 } 0221 0222 void FloppyAction::quit() 0223 { 0224 DEBUGSETUP; 0225 delete theProcess; 0226 theProcess = nullptr; 0227 0228 KFAction::quit(); 0229 } 0230 0231 bool FloppyAction::configureDevice(const QString &newDeviceName) 0232 { 0233 deviceInfo = nullptr; // We have not any idea what the device is 0234 deviceName = newDeviceName; 0235 return true; // No problem! 0236 } 0237 0238 bool FloppyAction::configureDevice(int drive, int density) 0239 { 0240 DEBUGSETUP; 0241 const char *devicename = nullptr; 0242 0243 deviceInfo = nullptr; 0244 deviceName.clear(); 0245 0246 if ((drive < 0) || (drive > 1)) { 0247 Q_EMIT status(i18n("Unexpected drive number %1.", drive), -1); 0248 return false; 0249 } 0250 0251 const fdinfo *deviceinfo = fdtable; 0252 for (; deviceinfo && (deviceinfo->devices); deviceinfo++) { 0253 if (deviceinfo->blocks != density) 0254 continue; 0255 } 0256 if (!deviceinfo) { 0257 Q_EMIT status(i18n("Unexpected density number %1.", density), -1); 0258 return false; 0259 } 0260 0261 deviceinfo = fdtable; 0262 for (; deviceinfo && (deviceinfo->devices); deviceinfo++) { 0263 if (deviceinfo->blocks != density) 0264 continue; 0265 if (deviceinfo->drive == drive) 0266 break; 0267 } 0268 0269 if (!deviceinfo || !deviceinfo->devices) { 0270 Q_EMIT status(i18n("Cannot find a device for drive %1 and density %2.", drive, density), -1); 0271 return false; 0272 } 0273 0274 for (const char *const *devices = deviceinfo->devices; *devices; devices++) { 0275 if (QT_ACCESS(*devices, W_OK) >= 0) { 0276 qCDebug(KFLOPPY_LOG) << "Found device " << *devices; 0277 devicename = *devices; 0278 break; 0279 } 0280 } 0281 0282 if (!devicename) { 0283 const QString str = i18n( 0284 "Cannot access %1\nMake sure that the device exists and that " 0285 "you have write permission to it.", 0286 QLatin1String(deviceinfo->devices[0])); 0287 Q_EMIT status(str, -1); 0288 return false; 0289 } 0290 0291 deviceName = QLatin1String(devicename); 0292 deviceInfo = deviceinfo; 0293 0294 return true; 0295 } 0296 0297 void FloppyAction::readStdOut() 0298 { 0299 processStdOut(QString::fromUtf8(theProcess->readAllStandardOutput())); 0300 } 0301 0302 void FloppyAction::readStdErr() 0303 { 0304 processStdOut(QString::fromUtf8(theProcess->readAllStandardError())); 0305 } 0306 0307 void FloppyAction::processDone(int exitCode, QProcess::ExitStatus exitStatus) 0308 { 0309 DEBUGSETUP; 0310 0311 if (exitStatus == QProcess::NormalExit) { 0312 if (exitCode == 0) { 0313 Q_EMIT status(QString(), 100); 0314 Q_EMIT done(this, true); 0315 } else { 0316 Q_EMIT status(i18n("The program %1 terminated with an error.", theProcessName), 100); 0317 Q_EMIT done(this, false); 0318 } 0319 } else { 0320 Q_EMIT status(i18n("The program %1 terminated abnormally.", theProcessName), 100); 0321 Q_EMIT done(this, false); 0322 } 0323 } 0324 0325 void FloppyAction::processStdOut(const QString &s) 0326 { 0327 qCDebug(KFLOPPY_LOG) << "stdout:" << s; 0328 } 0329 0330 void FloppyAction::processStdErr(const QString &s) 0331 { 0332 processStdOut(s); 0333 } 0334 0335 bool FloppyAction::startProcess() 0336 { 0337 DEBUGSETUP; 0338 0339 connect(theProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processDone(int, QProcess::ExitStatus))); 0340 connect(theProcess, &QProcess::readyReadStandardOutput, this, &FloppyAction::readStdOut); 0341 connect(theProcess, &QProcess::readyReadStandardError, this, &FloppyAction::readStdErr); 0342 0343 theProcess->setEnv(QStringLiteral("LC_ALL"), QStringLiteral("C")); // We need the untranslated output of the tool 0344 theProcess->setOutputChannelMode(KProcess::SeparateChannels); 0345 theProcess->start(); 0346 return (theProcess->exitStatus() == QProcess::NormalExit); 0347 } 0348 0349 /* static */ QString FDFormat::fdformatName = QString(); 0350 0351 FDFormat::FDFormat(QObject *p) 0352 : FloppyAction(p) 0353 , doVerify(true) 0354 { 0355 DEBUGSETUP; 0356 theProcessName = QStringLiteral("fdformat"); 0357 setObjectName(QStringLiteral("FDFormat")); 0358 } 0359 0360 /* static */ bool FDFormat::runtimeCheck() 0361 { 0362 fdformatName = findExecutable(QStringLiteral("fdformat")); 0363 return (!fdformatName.isEmpty()); 0364 } 0365 0366 bool FDFormat::configure(bool v) 0367 { 0368 doVerify = v; 0369 return true; 0370 } 0371 0372 /* virtual */ void FDFormat::exec() 0373 { 0374 DEBUGSETUP; 0375 0376 if (!deviceInfo || deviceName.isEmpty()) { 0377 Q_EMIT status(i18n("Internal error: device not correctly defined."), -1); 0378 Q_EMIT done(this, false); 0379 return; 0380 } 0381 0382 if (fdformatName.isEmpty()) { 0383 Q_EMIT status(i18n("Cannot find fdformat."), -1); 0384 Q_EMIT done(this, false); 0385 return; 0386 } 0387 0388 delete theProcess; 0389 theProcess = new KProcess; 0390 0391 formatTrackCount = 0; 0392 0393 *theProcess << fdformatName; 0394 0395 // Common to Linux and BSD, others may differ 0396 if (!doVerify) { 0397 *theProcess << QStringLiteral("-n"); 0398 } 0399 0400 #ifdef ANY_BSD 0401 *theProcess << QStringLiteral("-y") << QStringLiteral("-f") << QString::number(deviceInfo->blocks); 0402 #elif defined(ANY_LINUX) 0403 // No Linux-specific flags 0404 #endif 0405 0406 // Common to Linux and BSD, others may differ 0407 *theProcess << deviceName; 0408 0409 if (!startProcess()) { 0410 Q_EMIT status(i18n("Could not start fdformat."), -1); 0411 Q_EMIT done(this, false); 0412 } 0413 0414 // Now depend on fdformat running and producing output. 0415 } 0416 0417 // Parse some output from the fdformat process. Lots of 0418 // #ifdefs here to account for variations in the basic 0419 // fdformat. Uses gotos to branch to whatever error message we 0420 // need, since the messages can be standardized across OSsen. 0421 // 0422 // 0423 void FDFormat::processStdOut(const QString &s) 0424 { 0425 DEBUGSETUP; 0426 0427 #ifdef ANY_BSD 0428 if (s[0] == QLatin1Char('F')) { 0429 formatTrackCount++; 0430 Q_EMIT status(QString(), formatTrackCount * 100 / deviceInfo->tracks); 0431 } else if (s[0] == QLatin1Char('E')) { 0432 Q_EMIT status(i18n("Error formatting track %1.", formatTrackCount), -1); 0433 } else { 0434 if (s.contains(QLatin1String("ioctl(FD_FORM)"))) { 0435 Q_EMIT status(i18n("Cannot access floppy or floppy drive.\n" 0436 "Please insert a floppy and make sure that you " 0437 "have selected a valid floppy drive."), 0438 -1); 0439 return; 0440 } 0441 if (s.indexOf(QLatin1String("/dev/")) >= 0) { 0442 Q_EMIT status(s, -1); 0443 return; 0444 } 0445 DEBUGS(s); 0446 } 0447 #elif defined(ANY_LINUX) 0448 DEBUGS(s); 0449 QRegExp regexp(QStringLiteral("([0-9]+)")); 0450 if (s.startsWith(QLatin1String("bad data at cyl")) || s.contains(QLatin1String("Problem reading cylinder"))) { 0451 if (regexp.indexIn(s) > -1) { 0452 const int track = regexp.cap(1).toInt(); 0453 Q_EMIT status(i18n("Low-level formatting error at track %1.", track), -1); 0454 } else { 0455 // This error should not happen 0456 Q_EMIT status(i18n("Low-level formatting error: %1", s), -1); 0457 } 0458 return; 0459 } else if (s.contains(QLatin1String("ioctl(FDFMTBEG)"))) { 0460 Q_EMIT status(i18n("Cannot access floppy or floppy drive.\n" 0461 "Please insert a floppy and make sure that you " 0462 "have selected a valid floppy drive."), 0463 -1); 0464 return; 0465 } else if (s.contains(QLatin1String("busy"))) // "Device or resource busy" 0466 { 0467 Q_EMIT status(i18n("Device busy.\nPerhaps you need to unmount the floppy first."), -1); 0468 return; 0469 } 0470 // Be careful to leave "iotcl" as last before checking numbers 0471 else if (s.contains(QLatin1String("ioctl"))) { 0472 Q_EMIT status(i18n("Low-level format error: %1", s), -1); 0473 return; 0474 } 0475 // Check for numbers at last (as /dev/fd0u1440 has numbers too) 0476 else if (regexp.indexIn(s) > -1) { 0477 // Normal track number (formatting or verifying) 0478 const int p = regexp.cap(1).toInt(); 0479 if ((p >= 0) && (p < deviceInfo->tracks)) { 0480 Q_EMIT status(QString(), p * 100 / deviceInfo->tracks); 0481 } 0482 } 0483 #endif 0484 return; 0485 } 0486 0487 /* static */ QString DDZeroOut::m_ddName = QString(); 0488 0489 DDZeroOut::DDZeroOut(QObject *p) 0490 : FloppyAction(p) 0491 { 0492 qCDebug(KFLOPPY_LOG) << k_funcinfo; 0493 theProcessName = QStringLiteral("dd"); 0494 setObjectName(QStringLiteral("DD")); 0495 } 0496 0497 /* static */ bool DDZeroOut::runtimeCheck() 0498 { 0499 m_ddName = findExecutable(QStringLiteral("dd")); 0500 return (!m_ddName.isEmpty()); 0501 } 0502 0503 /* virtual */ void DDZeroOut::exec() 0504 { 0505 qCDebug(KFLOPPY_LOG) << k_funcinfo; 0506 0507 if (deviceName.isEmpty()) { 0508 Q_EMIT status(i18n("Internal error: device not correctly defined."), -1); 0509 Q_EMIT done(this, false); 0510 return; 0511 } 0512 0513 if (m_ddName.isEmpty()) { 0514 Q_EMIT status(i18n("Cannot find dd."), -1); 0515 Q_EMIT done(this, false); 0516 return; 0517 } 0518 0519 delete theProcess; 0520 theProcess = new KProcess; 0521 0522 *theProcess << m_ddName; 0523 0524 *theProcess << QStringLiteral("if=/dev/zero"); 0525 *theProcess << QStringLiteral("of=") + deviceName; 0526 0527 if (!startProcess()) { 0528 Q_EMIT status(i18n("Could not start dd."), -1); 0529 Q_EMIT done(this, false); 0530 } 0531 } 0532 0533 void DDZeroOut::processDone(int exitCode, QProcess::ExitStatus exitStatus) 0534 { 0535 Q_UNUSED(exitCode); 0536 Q_UNUSED(exitStatus); 0537 0538 qCDebug(KFLOPPY_LOG) << k_funcinfo; 0539 0540 /** 0541 * As we do not give a number of blocks to dd(1), it will stop 0542 * with the error "No space left on device" 0543 * 0544 * ### TODO: really check if the exit is not on an other error and then abort the formatting 0545 */ 0546 Q_EMIT status(QString(), 100); 0547 Q_EMIT done(this, true); 0548 } 0549 0550 /* static */ QString FATFilesystem::newfs_fat = QString(); 0551 0552 FATFilesystem::FATFilesystem(QObject *parent) 0553 : FloppyAction(parent) 0554 { 0555 DEBUGSETUP; 0556 runtimeCheck(); 0557 theProcessName = newfs_fat; 0558 setObjectName(QStringLiteral("FATFilesystem")); 0559 } 0560 0561 /* static */ bool FATFilesystem::runtimeCheck() 0562 { 0563 DEBUGSETUP; 0564 0565 #ifdef ANY_BSD 0566 newfs_fat = findExecutable(QStringLiteral("newfs_msdos")); 0567 #elif defined(ANY_LINUX) 0568 newfs_fat = findExecutable(QStringLiteral("mkdosfs")); 0569 #else 0570 return false; 0571 #endif 0572 0573 return !newfs_fat.isEmpty(); 0574 } 0575 0576 bool FATFilesystem::configure(bool v, bool l, const QString &lbl) 0577 { 0578 doVerify = v; 0579 doLabel = l; 0580 if (l) 0581 label = lbl.simplified(); 0582 else 0583 label.clear(); 0584 0585 return true; 0586 } 0587 0588 void FATFilesystem::exec() 0589 { 0590 DEBUGSETUP; 0591 0592 if ( 0593 #ifdef ANY_BSD // BSD needs the deviceInfo for the block count 0594 !deviceInfo || 0595 #endif 0596 deviceName.isEmpty()) { 0597 Q_EMIT status(i18n("Internal error: device not correctly defined."), -1); 0598 Q_EMIT done(this, false); 0599 return; 0600 } 0601 0602 if (newfs_fat.isEmpty()) { 0603 Q_EMIT status(i18n("Cannot find a program to create FAT filesystems."), -1); 0604 Q_EMIT done(this, false); 0605 return; 0606 } 0607 0608 delete theProcess; 0609 KProcess *p = theProcess = new KProcess; 0610 0611 *p << newfs_fat; 0612 #ifdef ANY_BSD 0613 *p << QStringLiteral("-f") << QString::number(deviceInfo->blocks); 0614 if (doLabel) { 0615 *p << QStringLiteral("-L") << label; 0616 } 0617 #else 0618 #ifdef ANY_LINUX 0619 if (doLabel) { 0620 *p << QStringLiteral("-n") << label; 0621 } 0622 if (doVerify) { 0623 *p << QStringLiteral("-c"); 0624 } 0625 #endif 0626 #endif 0627 *p << deviceName; 0628 0629 if (!startProcess()) { 0630 Q_EMIT status(i18n("Cannot start FAT format program."), -1); 0631 Q_EMIT done(this, false); 0632 } 0633 } 0634 0635 void FATFilesystem::processStdOut(const QString &s) 0636 { 0637 #ifdef ANY_BSD 0638 // ### TODO: do some checks 0639 #elif defined(ANY_LINUX) 0640 qCDebug(KFLOPPY_LOG) << s; 0641 if (s.contains(QLatin1String("mounted"))) // "/dev/fd0 contains a mounted filesystem" 0642 { 0643 Q_EMIT status(i18n("Floppy is mounted.\nYou need to unmount the floppy first."), -1); 0644 return; 0645 } else if (s.contains(QLatin1String("busy"))) // "Device or resource busy" 0646 { 0647 Q_EMIT status(i18n("Device busy.\nPerhaps you need to unmount the floppy first."), -1); 0648 return; 0649 } else if (s.contains(QLatin1String("denied"))) // "Permission denied" 0650 { 0651 Q_EMIT status(s, -1); 0652 return; 0653 } 0654 #if 0 0655 else if ( s.find( "mkdosfs" ) != -1 ) // DEBUG: get the program header and show it! 0656 { 0657 Q_EMIT status( s, -1 ); 0658 return; 0659 } 0660 #endif 0661 #endif 0662 } 0663 0664 #ifdef ANY_BSD 0665 0666 /* static */ QString UFSFilesystem::newfs = QString(); 0667 0668 UFSFilesystem::UFSFilesystem(QObject *parent) 0669 : FloppyAction(parent) 0670 { 0671 DEBUGSETUP; 0672 runtimeCheck(); 0673 theProcessName = newfs; 0674 setObjectName(QStringLiteral("UFSFilesystem")); 0675 } 0676 0677 /* static */ bool UFSFilesystem::runtimeCheck() 0678 { 0679 DEBUGSETUP; 0680 0681 newfs = findExecutable(QStringLiteral("newfs")); 0682 0683 return !newfs.isEmpty(); 0684 } 0685 0686 void UFSFilesystem::exec() 0687 { 0688 DEBUGSETUP; 0689 0690 if (deviceName.isEmpty()) { 0691 Q_EMIT status(i18n("Internal error: device not correctly defined."), -1); 0692 Q_EMIT done(this, false); 0693 return; 0694 } 0695 0696 if (newfs.isEmpty()) { 0697 Q_EMIT status(i18nc("BSD", "Cannot find a program to create UFS filesystems."), -1); 0698 Q_EMIT done(this, false); 0699 return; 0700 } 0701 0702 delete theProcess; 0703 KProcess *p = theProcess = new KProcess; 0704 0705 *p << newfs; 0706 0707 // ### TODO: is it still needed? (FreeBSD 5.3's man page says: "For backward compatibility.") 0708 if (deviceInfo) 0709 *p << QStringLiteral("-T") << QStringLiteral("fd%1").arg(deviceInfo->blocks); 0710 0711 *p << deviceName; 0712 0713 if (!startProcess()) { 0714 Q_EMIT status(i18nc("BSD", "Cannot start UFS format program."), -1); 0715 Q_EMIT done(this, false); 0716 } 0717 } 0718 #endif 0719 0720 /* static */ QString Ext2Filesystem::newfs = QString(); 0721 0722 Ext2Filesystem::Ext2Filesystem(QObject *parent) 0723 : FloppyAction(parent) 0724 { 0725 DEBUGSETUP; 0726 runtimeCheck(); 0727 theProcessName = QStringLiteral("mke2fs"); 0728 setObjectName(QStringLiteral("Ext2Filesystem")); 0729 } 0730 0731 /* static */ bool Ext2Filesystem::runtimeCheck() 0732 { 0733 DEBUGSETUP; 0734 0735 newfs = findExecutable(QStringLiteral("mke2fs")); 0736 0737 return !newfs.isEmpty(); 0738 } 0739 0740 bool Ext2Filesystem::configure(bool v, bool l, const QString &lbl) 0741 { 0742 doVerify = v; 0743 doLabel = l; 0744 if (l) { 0745 label = lbl.trimmed(); 0746 } else { 0747 label.clear(); 0748 } 0749 0750 return true; 0751 } 0752 0753 void Ext2Filesystem::exec() 0754 { 0755 DEBUGSETUP; 0756 0757 if ( 0758 #ifdef ANY_BSD // BSD needs the deviceInfo for the block count 0759 !deviceInfo || 0760 #endif 0761 deviceName.isEmpty()) { 0762 Q_EMIT status(i18n("Internal error: device not correctly defined."), -1); 0763 Q_EMIT done(this, false); 0764 return; 0765 } 0766 0767 if (newfs.isEmpty()) { 0768 Q_EMIT status(i18n("Cannot find a program to create ext2 filesystems."), -1); 0769 Q_EMIT done(this, false); 0770 return; 0771 } 0772 0773 delete theProcess; 0774 KProcess *p = theProcess = new KProcess; 0775 0776 *p << newfs; 0777 *p << QStringLiteral("-q"); 0778 if (doVerify) 0779 *p << QStringLiteral("-c"); 0780 if (doLabel) 0781 *p << QStringLiteral("-L") << label; 0782 0783 *p << deviceName; 0784 0785 if (!startProcess()) { 0786 Q_EMIT status(i18n("Cannot start ext2 format program."), -1); 0787 Q_EMIT done(this, false); 0788 } 0789 } 0790 0791 void Ext2Filesystem::processStdOut(const QString &s) 0792 { 0793 #ifdef ANY_BSD 0794 // ### TODO: do some checks 0795 #elif defined(ANY_LINUX) 0796 qCDebug(KFLOPPY_LOG) << s; 0797 if (s.contains(QLatin1String("mounted"))) // "/dev/fd0 is mounted; will not make a filesystem here!" 0798 { 0799 Q_EMIT status(i18n("Floppy is mounted.\nYou need to unmount the floppy first."), -1); 0800 return; 0801 } else if (s.contains(QLatin1String("busy"))) // "Device or resource busy" 0802 { 0803 Q_EMIT status(i18n("Device busy.\nPerhaps you need to unmount the floppy first."), -1); 0804 return; 0805 } else if (s.contains(QLatin1String("denied"))) // "Permission denied" 0806 { 0807 Q_EMIT status(s, -1); 0808 return; 0809 } 0810 #endif 0811 } 0812 0813 #ifdef ANY_LINUX 0814 /* static */ QString MinixFilesystem::newfs = QString(); 0815 0816 MinixFilesystem::MinixFilesystem(QObject *parent) 0817 : FloppyAction(parent) 0818 { 0819 DEBUGSETUP; 0820 runtimeCheck(); 0821 theProcessName = QStringLiteral("mkfs.minix"); 0822 setObjectName(QStringLiteral("Minix2Filesystem")); 0823 } 0824 0825 /* static */ bool MinixFilesystem::runtimeCheck() 0826 { 0827 DEBUGSETUP; 0828 0829 newfs = findExecutable(QStringLiteral("mkfs.minix")); 0830 0831 return !newfs.isEmpty(); 0832 } 0833 0834 bool MinixFilesystem::configure(bool v, bool l, const QString &lbl) 0835 { 0836 doVerify = v; 0837 doLabel = l; 0838 if (l) { 0839 label = lbl.trimmed(); 0840 } else { 0841 label.clear(); 0842 } 0843 0844 return true; 0845 } 0846 0847 void MinixFilesystem::exec() 0848 { 0849 DEBUGSETUP; 0850 0851 if (deviceName.isEmpty()) { 0852 Q_EMIT status(i18n("Internal error: device not correctly defined."), -1); 0853 Q_EMIT done(this, false); 0854 return; 0855 } 0856 0857 if (newfs.isEmpty()) { 0858 Q_EMIT status(i18n("Cannot find a program to create Minix filesystems."), -1); 0859 Q_EMIT done(this, false); 0860 return; 0861 } 0862 0863 delete theProcess; 0864 KProcess *p = theProcess = new KProcess; 0865 0866 *p << newfs; 0867 0868 // Labeling is not possible 0869 if (doVerify) 0870 *p << QStringLiteral("-c"); 0871 0872 *p << deviceName; 0873 0874 if (!startProcess()) { 0875 Q_EMIT status(i18n("Cannot start Minix format program."), -1); 0876 Q_EMIT done(this, false); 0877 } 0878 } 0879 0880 void MinixFilesystem::processStdOut(const QString &s) 0881 { 0882 qCDebug(KFLOPPY_LOG) << s; 0883 if (s.contains(QLatin1String("mounted"))) // "mkfs.minix: /dev/fd0 is mounted; will not make a filesystem here!" 0884 { 0885 Q_EMIT status(i18n("Floppy is mounted.\nYou need to unmount the floppy first."), -1); 0886 return; 0887 } else if (s.contains(QLatin1String("busy"))) // "Device or resource busy" 0888 { 0889 Q_EMIT status(i18n("Device busy.\nPerhaps you need to unmount the floppy first."), -1); 0890 return; 0891 } else if (s.contains(QLatin1String("denied"))) // "Permission denied" 0892 { 0893 Q_EMIT status(s, -1); 0894 return; 0895 } 0896 } 0897 0898 #endif