00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "formatter.h"
00010 #include "inputDialog.h"
00011 #include "output.h"
00012
00013
00014 #include <opie2/odebug.h>
00015 #include <qpe/qpeapplication.h>
00016 #include <qpe/config.h>
00017 #include <qpe/mimetype.h>
00018 #include <qpe/qcopenvelope_qws.h>
00019 #include <qpe/storage.h>
00020 using namespace Opie::Core;
00021
00022
00023 #include <qmenubar.h>
00024 #include <qmultilineedit.h>
00025 #include <qstring.h>
00026 #include <qlist.h>
00027 #include <qstringlist.h>
00028 #include <qdir.h>
00029 #include <qfile.h>
00030 #include <qtstream.h>
00031 #include <qcombobox.h>
00032 #include <qpopupmenu.h>
00033 #include <qmessagebox.h>
00034 #include <qregexp.h>
00035 #include <qlabel.h>
00036 #include <qlineedit.h>
00037 #include <qpushbutton.h>
00038 #include <qtoolbar.h>
00039 #include <qtabwidget.h>
00040 #include <qwidget.h>
00041 #include <qlayout.h>
00042 #include <qvariant.h>
00043
00044
00045 #include <unistd.h>
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 #include <sys/vfs.h>
00049 #include <mntent.h>
00050 #include <string.h>
00051 #include <errno.h>
00052
00053 #define BLANK ' '
00054 #define DELIMITER '#'
00055
00056
00057
00058 FormatterApp::FormatterApp( QWidget* parent, const char* name, WFlags fl, bool )
00059 : QMainWindow( parent, name, fl )
00060
00061 {
00062 if ( !name )
00063 setName( "FormatterApp" );
00064 connect( qApp,SIGNAL( aboutToQuit()),SLOT( cleanUp()) );
00065
00066 setCaption( tr( "Formatter" ) );
00067 FormatterAppLayout = new QGridLayout( this );
00068 FormatterAppLayout->setSpacing( 2);
00069 FormatterAppLayout->setMargin( 2 );
00070
00071 TabWidget = new QTabWidget( this, "TabWidget" );
00072
00073 tab = new QWidget( TabWidget, "tab" );
00074 tabLayout = new QGridLayout( tab );
00075 tabLayout->setSpacing( 3);
00076 tabLayout->setMargin( 2);
00077
00078 storageComboBox = new QComboBox( FALSE, tab, "storageComboBox" );
00079 storageComboBox->setMaximumWidth(220);
00080
00081 tabLayout->addMultiCellWidget( storageComboBox, 0, 0, 0, 1);
00082
00083 TextLabel4 = new QLabel( tab, "TextLabel4" );
00084 TextLabel4->setText( tr( "Storage Type" ) );
00085
00086 tabLayout->addMultiCellWidget( TextLabel4, 1, 1, 0, 1);
00087
00088 TextLabel2 = new QLabel( tab, "TextLabel2" );
00089 TextLabel2->setText( tr( "File Systems" ) );
00090
00091 tabLayout->addMultiCellWidget( TextLabel2, 4, 4, 0, 1);
00092
00093 fileSystemsCombo = new QComboBox( FALSE, tab, "fileSystemsCombo" );
00094 fileSystemsCombo->setMaximumWidth(220);
00095
00096 tabLayout->addMultiCellWidget( fileSystemsCombo, 3, 3, 0, 1);
00097 QSpacerItem* spacer = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Minimum );
00098 tabLayout->addItem( spacer, 2, 0 );
00099
00100 formatPushButton = new QPushButton( tab, "formatPushButton" );
00101 formatPushButton->setText( tr( "Format" ) );
00102 formatPushButton->setMaximumWidth(170);
00103
00104 tabLayout->addMultiCellWidget( formatPushButton, 6, 6, 0, 1);
00105 QSpacerItem* spacer_2 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Minimum );
00106 tabLayout->addItem( spacer_2, 5, 0 );
00107
00108 TabWidget->insertTab( tab, tr( "Main" ) );
00109
00110 tab_2 = new QWidget( TabWidget, "tab_2" );
00111 tabLayout_2 = new QGridLayout( tab_2 );
00112 tabLayout_2->setSpacing(3);
00113 tabLayout_2->setMargin(2);
00114
00115 mountPointLineEdit = new QLineEdit( tab_2, "mountPointLineEdit" );
00116
00117 tabLayout_2->addMultiCellWidget( mountPointLineEdit, 0, 0, 0, 1);
00118
00119 deviceComboBox = new QComboBox( FALSE, tab_2, "deviceComboBox" );
00120
00121 tabLayout_2->addMultiCellWidget( deviceComboBox, 3, 3, 0, 1);
00122
00123 TextLabel5 = new QLabel( tab_2, "TextLabel5" );
00124 TextLabel5->setText( tr( "CAUTION:\n"
00125 "Changing parameters on this\n"
00126 "page may cause your system\n"
00127 "to stop functioning properly!" ) );
00128
00129 tabLayout_2->addMultiCellWidget( TextLabel5, 6, 6, 0, 1);
00130
00131 editPushButton = new QPushButton( tab_2, "editPushButton" );
00132 editPushButton->setText( tr( "Edit fstab" ) );
00133 editPushButton->setMaximumWidth(100);
00134
00135 tabLayout_2->addMultiCellWidget( editPushButton, 7, 7, 0, 0 );
00136
00137 fsckButton = new QPushButton( tab_2, "fsckPushButton" );
00138 fsckButton->setText( tr( "Check Disk" ) );
00139 fsckButton->setMaximumWidth(100);
00140
00141 tabLayout_2->addMultiCellWidget( fsckButton, 7, 7, 1, 1);
00142
00143 TextLabel3 = new QLabel( tab_2, "TextLabel3" );
00144 TextLabel3->setText( tr( "Device" ) );
00145
00146 tabLayout_2->addMultiCellWidget( TextLabel3, 4, 4, 0, 1 );
00147 QSpacerItem* spacer_3 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
00148 tabLayout_2->addItem( spacer_3, 5, 0 );
00149
00150 TextLabel1 = new QLabel( tab_2, "TextLabel1" );
00151 TextLabel1->setText( tr( "Mount Point" ) );
00152
00153 tabLayout_2->addMultiCellWidget( TextLabel1, 1, 1, 0, 1 );
00154 QSpacerItem* spacer_4 = new QSpacerItem( 20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding );
00155 tabLayout_2->addItem( spacer_4, 2, 1 );
00156 TabWidget->insertTab( tab_2, tr( "Advanced" ) );
00157
00158 FormatterAppLayout->addWidget( TabWidget, 0, 1 );
00159
00160 connect( formatPushButton ,SIGNAL(released()),this,SLOT( doFormat()) );
00161 connect( editPushButton ,SIGNAL(released()),this,SLOT( editFstab()) );
00162 connect( fsckButton ,SIGNAL(released()),this,SLOT( doFsck()) );
00163
00164 connect( fileSystemsCombo,SIGNAL(activated(int)),this,SLOT( fsComboSelected(int) ));
00165 connect( storageComboBox,SIGNAL(activated(int)),this,SLOT( storageComboSelected(int) ));
00166 connect( deviceComboBox,SIGNAL(activated(int)),this,SLOT( deviceComboSelected(int) ));
00167
00168
00169 fillCombos();
00170 }
00171
00172 FormatterApp::~FormatterApp()
00173 {}
00174
00175 void FormatterApp::doFormat()
00176 {
00177 int err=0;
00178 Output *outDlg;
00179 QString umountS, remountS;
00180 QString text = storageComboBox->currentText();
00181 QString currentText = storageComboBox->currentText();
00182 QString cmd;
00183 QString diskDevice = currentText.right( currentText.length() - currentText.find(" -> ",0,TRUE) - 4);
00184 QString diskName = currentText.left(currentText.find(" -> ",0,TRUE));
00185 QString fs = fileSystemsCombo->currentText();
00186
00187 #if defined(QT_QWS_IPAQ) || defined(QT_QWS_SL5XXX) // lets test on something cheap
00188 #else
00189 currentText = diskDevice = "/dev/fd0";
00190 umountS = "umount -v /floppy 2>&1";
00191 remountS = "mount -v /floppy 2>&1";
00192 #endif
00193
00194 if( currentText.find("CF",0,TRUE) != -1)
00195 {
00196 umountS = "umount ";
00197 remountS = "mount ";
00198
00199
00200
00201 }
00202 if( currentText.find("SD",0,TRUE) != -1)
00203 {
00204 umountS = "umount ";
00205 remountS = "mount ";
00206
00207
00208 }
00209
00210 switch ( QMessageBox::warning(this,tr("Format?")
00211 , tr("Really format\n") +diskName+" "+ currentText +
00212 tr("\nwith %1 filesystem?\nYou will loose all data!!").arg( fs )
00213 ,tr("Yes")
00214 ,tr("No")
00215 ,0
00216 ,1
00217 ,1) )
00218 {
00219 case 0:
00220 {
00221 if(fs == "vfat")
00222 cmd = "mkdosfs -v " + diskDevice+" 2>&1";
00223 else if(fs == "ext2")
00224 cmd = "mke2fs -v " + diskDevice+" 2>&1";
00225 else
00226 {
00227 QMessageBox::warning(this, tr("Formatter"),tr("Could not format.\nUnknown type"), tr("Ok"));
00228 break;
00229 }
00230
00231 outDlg = new Output(this, tr("Formatter Output"),FALSE);
00232 QPEApplication::showDialog( outDlg);
00233 qApp->processEvents();
00234 FILE *fp;
00235 char line[130];
00236
00237
00238 outDlg->OutputEdit->append( tr("Trying to umount %1.").arg( currentText) );
00239 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00240
00241 sleep(1);
00242 odebug << "Command is "+umountS << oendl;
00243 fp = popen( (const char *) umountS, "r");
00244
00245 if ( !fp )
00246 {
00247 odebug << "Could not execute '" + umountS + "'! err=" << err << "\n" +(QString)strerror(errno) << oendl;
00248 QMessageBox::warning( this, tr("Formatter"), tr("umount failed!"), tr("&OK") );
00249 pclose(fp);
00250 return;
00251 }
00252 else
00253 {
00254
00255
00256 while ( fgets( line, sizeof line, fp))
00257 {
00258 if( ((QString)line).find("busy",0,TRUE) != -1)
00259 {
00260 odebug << "Could not find '" + umountS << oendl;
00261 QMessageBox::warning( this, tr("Formatter"), tr("Could not umount.\nDevice is busy!"), tr("&OK") );
00262 pclose(fp);
00263 return;
00264 }
00265 else
00266 {
00267 QString lineStr = line;
00268 lineStr=lineStr.left(lineStr.length()-1);
00269 outDlg->OutputEdit->append(lineStr);
00270 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00271 }
00272 }
00273 }
00274 pclose(fp);
00275
00276 odebug << "Command would be: "+cmd << oendl;
00277 outDlg->OutputEdit->append( tr("Trying to format.") );
00278 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00279
00280 fp = popen( (const char *) cmd, "r");
00281 while ( fgets( line, sizeof line, fp))
00282 {
00283 if( ((QString)line).find("No such device",0,TRUE) != -1)
00284 {
00285 odebug << "No such device '" + umountS << oendl;
00286 QMessageBox::warning( this, tr("Formatter"), tr("No such device!"), tr("&OK") );
00287 pclose(fp);
00288
00289
00290 return;
00291 }
00292 else
00293 {
00294 QString lineStr = line;
00295 lineStr=lineStr.left(lineStr.length()-1);
00296 outDlg->OutputEdit->append(lineStr);
00297 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00298 }
00299 }
00300 outDlg->OutputEdit->append( currentText + tr("\nhas been successfully formatted."));
00301 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00302 pclose(fp);
00303
00304 outDlg->OutputEdit->append( tr("Trying to mount %1.").arg( currentText) );
00305 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00306 fp = popen( (const char *) remountS, "r");
00307 if ( !fp)
00308 {
00309 odebug << "Could not execute '" + remountS + "'! err=" << err << "\n" +(QString)strerror(errno) << oendl;
00310 QMessageBox::warning( this, tr("Formatter"), tr("Card mount failed!"), tr("&OK") );
00311
00312 }
00313 else
00314 {
00315 outDlg->OutputEdit->append(tr("%1\nhas been successfully mounted.").arg( currentText ));
00316 while ( fgets( line, sizeof line, fp))
00317 {
00318 QString lineStr = line;
00319 lineStr=lineStr.left(lineStr.length()-1);
00320 outDlg->OutputEdit->append(lineStr);
00321 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00322 }
00323 }
00324 pclose(fp);
00325 sleep(1);
00326
00327 outDlg->OutputEdit->append(tr("You can now close the output window."));
00328 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00329
00330
00331
00332 }
00333 break;
00334 };
00335 }
00336
00337 bool FormatterApp::doFdisk()
00338 {
00339 return FALSE;
00340
00341 }
00342
00343 void FormatterApp::fillCombos()
00344 {
00345
00346 StorageInfo storageInfo;
00347 const QList<FileSystem> &fs = storageInfo.fileSystems();
00348 QListIterator<FileSystem> it ( fs );
00349 QString storage;
00350 for( ; it.current(); ++it )
00351 {
00352 const QString name = (*it)->name();
00353 const QString path = (*it)->path();
00354 const QString disk = (*it)->disk();
00355 const QString options = (*it)->options();
00356 if( name.find( tr("Internal"),0,TRUE) == -1)
00357 {
00358 storageComboBox->insertItem(name +" -> "+disk);
00359 }
00360
00361 }
00362 parsetab("/etc/mtab");
00363
00364 fileSystemsCombo->insertStringList( fsList,-1);
00365 deviceComboBox->insertStringList( deviceList,-1);
00366 storageComboSelected(0);
00367 deviceComboSelected(0);
00368 }
00369
00370
00371 void FormatterApp::fsComboSelected(int )
00372 {}
00373
00374 void FormatterApp::storageComboSelected(int index )
00375 {
00376
00377 QString currentText = storageComboBox->text(index);
00378 QString nameS = currentText.left( currentText.find("->",0,TRUE));
00379
00380 TextLabel4->setText( tr( "Storage Type: %1").arg( nameS) );
00381 currentText = currentText.right( currentText.length() - currentText.find(" -> ",0,TRUE) - 4);
00382
00383 QString fsType = getFileSystemType((const QString &) currentText);
00384
00385 for(int i = 0; i < fileSystemsCombo->count(); i++)
00386 {
00387 if( fsType == fileSystemsCombo->text(i))
00388 fileSystemsCombo->setCurrentItem(i);
00389 }
00390
00391 }
00392
00393 void FormatterApp::deviceComboSelected(int index)
00394 {
00395
00396 StorageInfo storageInfo;
00397 QString totalS, usedS, avS, diskS, nameS, fsType, selectedText;
00398
00399 selectedText = deviceComboBox->text(index);
00400
00401 const QList<FileSystem> &fs = storageInfo.fileSystems();
00402 QListIterator<FileSystem> it ( fs );
00403 QString storage;
00404 for( ; it.current(); ++it )
00405 {
00406 const QString name = (*it)->name();
00407 const QString path = (*it)->path();
00408 const QString disk = (*it)->disk();
00409
00410 if( selectedText == disk)
00411 {
00412 diskS = disk; nameS= name;
00413 mountPointLineEdit->setText(path);
00414 long mult = (*it)->blockSize() / 1024;
00415 long div = 1024 / (*it)->blockSize();
00416 if ( !mult ) mult = 1;
00417 if ( !div ) div = 1;
00418 long total = (*it)->totalBlocks() * mult / div;
00419 long totalMb = total/1024;
00420 long avail = (*it)->availBlocks() * mult / div;
00421 long availMb = avail/1024;
00422 long used = total - avail;
00423 long usedMb = used/1024;
00424 totalS.sprintf(tr("Total: %1 kB ( %d mB)\n").arg( total ), totalMb );
00425 usedS.sprintf(tr("Used: %1 kB ( %d mB)\n").arg(used) ,usedMb);
00426 avS.sprintf( tr("Available: %1 kB ( %d mB)").arg(avail), availMb );
00427 }
00428 }
00429 fsType = getFileSystemType((const QString &)selectedText);
00430
00431 TextLabel5->setText(tr("Type: %1\nFormatted with %2\n%3, %4, %5").arg( nameS).arg( fsType).arg(totalS).arg( usedS).arg( avS ));
00432 TextLabel5->setTextFormat( Qt::RichText );
00433
00434 }
00435
00436 void FormatterApp::cleanUp()
00437 {}
00438
00439
00440 void FormatterApp::editFstab()
00441 {
00442 QCopEnvelope e("QPE/Application/textedit","setDocument(QString)");
00443 e << (const QString &)"/etc/fstab";
00444 }
00445
00446 void FormatterApp::parsetab(const QString &fileName)
00447 {
00448
00449 fileSystemTypeList.clear();
00450 fsList.clear();
00451 struct mntent *me;
00452
00453 FILE *mntfp = setmntent( fileName.latin1(), "r" );
00454 if ( mntfp )
00455 {
00456 while ( (me = getmntent( mntfp )) != 0 )
00457 {
00458 QString deviceName = me->mnt_fsname;
00459 QString filesystemType = me->mnt_type;
00460 if(deviceName != "none")
00461 {
00462 if( fsList.contains(filesystemType) == 0
00463 & filesystemType.find("proc",0,TRUE) == -1
00464 & filesystemType.find("cramfs",0,TRUE) == -1
00465 & filesystemType.find("auto",0,TRUE) == -1)
00466 fsList << filesystemType;
00467 deviceList << deviceName;
00468 odebug << deviceName+"::"+filesystemType << oendl;
00469 fileSystemTypeList << deviceName+"::"+filesystemType;
00470 }
00471 }
00472 }
00473 endmntent( mntfp );
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 }
00498
00499 QString FormatterApp::getFileSystemType(const QString ¤tText)
00500 {
00501
00502 parsetab("/etc/mtab");
00503
00504 for ( QStringList::Iterator it = fileSystemTypeList.begin(); it != fileSystemTypeList.end(); ++it )
00505 {
00506 QString temp = (*it);
00507 if( temp.find( currentText,0,TRUE) != -1)
00508 {
00509 return temp.right( temp.length() - temp.find("::",0,TRUE) - 2);
00510
00511 }
00512 }
00513 return "";
00514 }
00515
00516 bool FormatterApp::doFsck()
00517 {
00518
00519 Output *outDlg;
00520 QString selectedDevice;
00521
00522 selectedDevice = deviceComboBox->currentText();
00523 QString mountPoint = mountPointLineEdit->text();
00524 QString umountS = "umount -v "+mountPoint+" 2>&1";
00525 QString remountS = "mount -v "+mountPoint+" 2>&1";
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 QString fsType = getFileSystemType((const QString &)selectedDevice);
00536 QString cmd;
00537 odebug << selectedDevice +" "+ fsType << oendl;
00538 if(fsType == "vfat") cmd = "dosfsck -vy ";
00539 if(fsType == "ext2") cmd = "e2fsck -cpvy ";
00540 cmd += selectedDevice + " 2>&1";
00541
00542 outDlg = new Output(this, tr("Formatter Output"),FALSE);
00543 QPEApplication::showDialog( outDlg );
00544 qApp->processEvents();
00545 FILE *fp;
00546 char line[130];
00547 outDlg->OutputEdit->append( tr("Trying to umount."));
00548 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00549
00550 sleep(1);
00551
00552 fp = popen( (const char *) umountS, "r");
00553
00554 if ( !fp )
00555 {
00556 odebug << "Could not execute '" + umountS + "'!\n" +(QString)strerror(errno) << oendl;
00557 QMessageBox::warning( this, tr("Formatter"), tr("umount failed!"), tr("&OK") );
00558 pclose(fp);
00559 return false;
00560 }
00561 else
00562 {
00563
00564
00565 while ( fgets( line, sizeof line, fp))
00566 {
00567 if( ((QString)line).find("busy",0,TRUE) != -1)
00568 {
00569 odebug << "Could not find '" + umountS << oendl;
00570 QMessageBox::warning( this, tr("Formatter"),
00571 tr("Could not umount.\nDevice is busy!"), tr("&OK") );
00572 pclose(fp);
00573 return false;
00574 }
00575 else
00576 {
00577 QString lineStr = line;
00578 lineStr=lineStr.left(lineStr.length()-1);
00579 outDlg->OutputEdit->append(lineStr);
00580 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00581 }
00582 }
00583 }
00584 pclose(fp);
00586 fp = popen( (const char *) cmd, "r");
00587 while ( fgets( line, sizeof line, fp))
00588 {
00589 if( ((QString)line).find("No such device",0,TRUE) != -1)
00590 {
00591 odebug << "No such device '" + umountS << oendl;
00592 QMessageBox::warning( this, tr("Formatter"), tr("No such device!"), tr("&OK") );
00593 pclose(fp);
00594
00595
00596 return false;
00597 }
00598 else
00599 {
00600 QString lineStr = line;
00601 lineStr=lineStr.left(lineStr.length()-1);
00602 outDlg->OutputEdit->append(lineStr);
00603 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00604 }
00605 }
00606 outDlg->OutputEdit->append(tr("You can now close the output window."));
00607 outDlg->OutputEdit->setCursorPosition(outDlg->OutputEdit->numLines() + 1,0,FALSE);
00608
00609
00610 pclose(fp);
00611
00613
00614 return true;
00615 }
00616
00617 bool FormatterApp::doFsckCheck()
00618 {
00619
00620 return FALSE;
00621 }
00622
00623 int FormatterApp::formatCheck(const QString &)
00624 {
00625
00626 return -1;
00627 }
00628
00629 int FormatterApp::runCommand(const QString &)
00630 {
00631
00632 return -1;
00633 }