Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

swapfile.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000 Trolltech AS.  All rights reserved.
00003 ** Copyright (C) 2002-2005 the Opie Team <opie-devel@handhelds.org>
00004 **
00005 ** This file is part of Opie Environment.
00006 **
00007 ** This file may be distributed and/or modified under the terms of the
00008 ** GNU General Public License version 2 as published by the Free Software
00009 ** Foundation and appearing in the file LICENSE.GPL included in the
00010 ** packaging of this file.
00011 **
00012 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 **
00015 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00016 **
00017 ** Contact info@trolltech.com if any conditions of this licensing are
00018 ** not clear to you.
00019 **
00020 **********************************************************************/
00021 
00022 #include "swapfile.h"
00023 
00024 /* OPIE */
00025 #include <opie2/odebug.h>
00026 #include <opie2/oresource.h>
00027 using namespace Opie::Core;
00028 
00029 /* QT */
00030 #include <qfile.h>
00031 #include <qtextstream.h>
00032 #include <qlabel.h>
00033 #include <qtimer.h>
00034 #include <qlayout.h>
00035 #include <qpushbutton.h>
00036 #include <qhbuttongroup.h>
00037 #include <qradiobutton.h>
00038 #include <qlineedit.h>
00039 #include <qprogressbar.h>
00040 #include <qcombobox.h>
00041 #include <qvgroupbox.h>
00042 #include <qhbox.h>
00043 #include <qmessagebox.h>
00044 #include <qcopchannel_qws.h>
00045 
00046 /* STD */
00047 #include <stdio.h>
00048 #include <stdlib.h>
00049 #include <string.h>
00050 #include <unistd.h>
00051 #include <fcntl.h>
00052 #include <sys/vfs.h>
00053 #include <mntent.h>
00054 #include <unistd.h>
00055 #include <sys/types.h>
00056 
00057 Swapfile::Swapfile( QWidget *parent, const char *name, WFlags f )
00058     : QWidget( parent, name, f )
00059 {
00060         if ( !QFile::exists( "/proc/swaps" ) )
00061         {
00062                 QLabel *text = new QLabel( tr( "Swap disabled in kernel" ), this );
00063                 return;
00064         }
00065         // are we running as root?
00066         isRoot = geteuid() == 0;
00067 
00068         QVBoxLayout* vb = new QVBoxLayout(this, 5);
00069 
00070         QHButtonGroup* cfsdRBG = new QHButtonGroup(tr("Swapfile location"), this);
00071         cfsdRBG->setRadioButtonExclusive(true);
00072         vb->addWidget(cfsdRBG);
00073 
00074         ramRB = new QRadioButton(tr("RAM"), cfsdRBG);
00075         cfRB = new QRadioButton(tr("CF Card"), cfsdRBG);
00076         sdRB = new QRadioButton(tr("SD Card"), cfsdRBG);
00077 
00078         QHBox *hb1 = new QHBox(this);
00079         hb1->setSpacing(5);
00080 
00081         swapPath1 = new QLineEdit(hb1);
00082         swapPath1->setEnabled(false);
00083 
00084         QPushButton* swapOn = new QPushButton(tr(" On "), hb1);
00085         QPushButton* swapOff = new QPushButton(tr(" Off "), hb1);
00086         vb->addWidget(hb1);
00087 
00088         QVGroupBox* box1 = new QVGroupBox(tr("Manage Swapfile"), this);
00089         vb->addWidget(box1);
00090 
00091         QHBox *hb2 = new QHBox(box1);
00092         hb2->setSpacing(5);
00093         QPushButton* mkSwap = new QPushButton(tr("Generate"), hb2);
00094         QPushButton* rmSwap = new QPushButton(tr("Remove"), hb2);
00095 
00096         QHBox *hb3 = new QHBox(box1);
00097         hb3->setSpacing(5);
00098         swapSize = new QComboBox(hb3);
00099         swapSize->insertStringList(QStringList::split(",", tr("2 Mb,4 Mb,6 Mb,8 Mb,16 Mb,32 Mb,64 Mb")));
00100 
00101         mkswapProgress = new QProgressBar(3, hb3);
00102         mkswapProgress->setCenterIndicator(true);
00103 
00104         QHBox *hb4 = new QHBox(this);
00105         hb4->setSpacing(5);
00106 
00107         swapStatusIcon = new QLabel(hb4);
00108         swapStatus = new QLabel("", hb4);
00109         hb4->setStretchFactor(swapStatus, 99);
00110     vb->addWidget(hb4);
00111 
00112     connect(swapOn, SIGNAL(clicked()), this, SLOT(swapon()));
00113     connect(swapOff, SIGNAL(clicked()), this, SLOT(swapoff()));
00114     connect(cfRB, SIGNAL(clicked()), this, SLOT(cfsdchecked()));
00115     connect(sdRB, SIGNAL(clicked()), this, SLOT(cfsdchecked()));
00116     connect(ramRB, SIGNAL(clicked()), this, SLOT(cfsdchecked()));
00117     connect(mkSwap, SIGNAL(clicked()), this, SLOT(makeswapfile()));
00118     connect(rmSwap, SIGNAL(clicked()), this, SLOT(removeswapfile()));
00119 
00120         cfRB->setEnabled(FALSE);
00121     sdRB->setEnabled(FALSE);
00122 
00123     QCopChannel *pcmciaChannel = new QCopChannel("QPE/Card", this);
00124     connect(pcmciaChannel, SIGNAL(received(const QCString&,const QByteArray&)), this, SLOT(cardnotify(const QCString&,const QByteArray&)));
00125     QCopChannel *sdChannel = new QCopChannel("QPE/Card", this);
00126     connect(sdChannel, SIGNAL(received(const QCString&,const QByteArray&)), this, SLOT(cardnotify(const QCString&,const QByteArray&)));
00127 
00128     cardInPcmcia0 = FALSE;
00129     cardInPcmcia1 = FALSE;
00130     cardInSd = FALSE;
00131 
00132     Swapfile::status();
00133     Swapfile::getStatusPcmcia();
00134     Swapfile::getStatusSd();
00135 }
00136 
00137 int Swapfile::exec(const QString& arg)
00138 {
00139         return system((!isRoot ? "sudo " : "") + arg);
00140 }
00141 
00142 
00143 Swapfile::~Swapfile()
00144 {
00145 }
00146 
00147 void Swapfile::cardnotify(const QCString & msg, const QByteArray &)
00148 {
00149     if (msg == "stabChanged()")
00150         {
00151         getStatusPcmcia();
00152     }
00153         else if (msg == "mtabChanged()")
00154         {
00155         getStatusSd();
00156         }
00157 }
00158 
00159 void Swapfile::getStatusPcmcia()
00160 {
00161 
00162     bool cardWas0 = cardInPcmcia0;      // remember last state
00163     bool cardWas1 = cardInPcmcia1;
00164 
00165     QString fileName;
00166 
00167     // one of these 3 files should exist
00168     if (QFile::exists("/var/run/stab")) {
00169         fileName = "/var/run/stab";
00170     } else if (QFile::exists("/var/state/pcmcia/stab")) {
00171         fileName = "/var/state/pcmcia/stab";
00172     } else {
00173         fileName = "/var/lib/pcmcia/stab";
00174     }
00175 
00176     QFile f(fileName);
00177 
00178     if (f.open(IO_ReadOnly)) {
00179         QStringList list;
00180         QTextStream stream(&f);
00181         QString streamIn;
00182         streamIn = stream.read();
00183         list = QStringList::split("\n", streamIn);
00184         for (QStringList::Iterator line = list.begin(); line != list.end();
00185              line++) {
00186             if ((*line).startsWith("Socket 0:")) {
00187                 if ((*line).startsWith("Socket 0: empty") && cardInPcmcia0) {
00188                     cardInPcmcia0 = FALSE;
00189                 } else if (!(*line).startsWith("Socket 0: empty")
00190                            && !cardInPcmcia0) {
00191                     cardInPcmcia0 = TRUE;
00192                 }
00193             } else if ((*line).startsWith("Socket 1:")) {
00194                 if ((*line).startsWith("Socket 1: empty") && cardInPcmcia1) {
00195                     cardInPcmcia1 = FALSE;
00196                 } else if (!(*line).startsWith("Socket 1: empty")
00197                            && !cardInPcmcia1) {
00198                     cardInPcmcia1 = TRUE;
00199                 }
00200             }
00201         }
00202         f.close();
00203 
00204         if (cardWas0 != cardInPcmcia0 || cardWas1 != cardInPcmcia1) {
00205             QString text = QString::null;
00206             QString what = QString::null;
00207             if (cardWas0 != cardInPcmcia0) {
00208                 if (cardInPcmcia0) {
00209                    cfRB->setEnabled(TRUE);
00210                 } else {
00211                    cfRB->setChecked(FALSE);
00212                    cfRB->setEnabled(FALSE);
00213                 }
00214             }
00215 
00216             if (cardWas1 != cardInPcmcia1) {
00217                 if (cardInPcmcia1) {
00218                    cfRB->setEnabled(TRUE);
00219                 } else {
00220                    cfRB->setChecked(FALSE);
00221                    cfRB->setEnabled(FALSE);
00222                 }
00223             }
00224         }
00225     } else {
00226         // no file found
00227         odebug << "no file found" << oendl; 
00228         cardInPcmcia0 = FALSE;
00229         cardInPcmcia1 = FALSE;
00230     }
00231     Swapfile::cfsdchecked();
00232 }
00233 
00234 
00235 void Swapfile::getStatusSd()
00236 {
00237 
00238     bool cardWas = cardInSd;    // remember last state
00239     cardInSd = FALSE;
00240 
00241 #if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
00242     struct mntent *me;
00243     FILE *mntfp = setmntent("/etc/mtab", "r");
00244 
00245     if (mntfp) {
00246         while ((me = getmntent(mntfp)) != 0) {
00247             QString fs = me->mnt_fsname;
00248             if (fs.left(14) == "/dev/mmc/part1" || fs.left(7) == "/dev/sd"
00249                 || fs.left(9) == "/dev/mmcd") {
00250                 cardInSd = TRUE;
00251                 show();
00252             }
00253         }
00254         endmntent(mntfp);
00255     }
00256 
00257     if (cardWas != cardInSd) {
00258         QString text = QString::null;
00259         QString what = QString::null;
00260         if (cardInSd) {
00261            sdRB->setEnabled(TRUE);
00262         } else {
00263            sdRB->setChecked(FALSE);
00264            sdRB->setEnabled(FALSE);
00265         }
00266     }
00267 #else
00268 #error "Not on Linux"
00269 #endif
00270         Swapfile::cfsdchecked();
00271 }
00272 
00273 int rc=0;
00274 
00275 void Swapfile::swapon()
00276 {
00277         char swapcmd[128] ="swapon ";
00278         Swapfile::cfsdchecked();
00279         strcat(swapcmd,swapPath1->text());
00280         char *runcmd = swapcmd;
00281         rc = exec(QString("%1").arg(runcmd));
00282         if (rc != 0) {
00283                setStatusMessage("Failed to attach swapfile.", true);
00284         }
00285         else {
00286 /*             QMessageBox::information(this, "Information", "Swapfile is active!"); */
00287                setStatusMessage("Swapfile activated.");
00288         }
00289        Swapfile::status();
00290 }
00291 
00292 
00293 void Swapfile::setStatusMessage(const QString& text, bool error /* = false */)
00294 {
00295         swapStatus->setText("<b>" + text + "</b>");
00296         swapStatusIcon->setPixmap(Opie::Core::OResource::loadPixmap(error ? "close" : "done", Opie::Core::OResource::SmallIcon));
00297 }
00298 
00299 
00300 void Swapfile::swapoff()
00301 {
00302         char swapcmd[128] ="swapoff ";
00303         if (Swapfile::cfRB->isChecked() == TRUE)
00304         Swapfile::cfsdchecked();
00305         strcat(swapcmd,swapPath1->text());
00306         char *runcmd = swapcmd;
00307         rc = exec(QString("%1").arg(runcmd));
00308         if (rc != 0) {
00309                setStatusMessage(tr("Failed to detach swapfile."), true);
00310         }
00311         else {
00312 /*             QMessageBox::information(this, "Information", "Swapfile is inactive!"); */
00313                setStatusMessage(tr("Swapfile deactivated."));
00314 /*                     Swapfile::swapPath->clear();*/
00315         }
00316        Swapfile::status();
00317 }
00318 
00319 void Swapfile::cfsdchecked()
00320 {
00321 /*              Swapfile::swapPath->clear();*/
00322         Swapfile::swapPath1->clear();
00323         if (Swapfile::ramRB->isChecked() == TRUE)
00324         {
00325                 Swapfile::swapPath1->insert("/home/swapfile");
00326         }
00327         if  (Swapfile::sdRB->isChecked() == TRUE)
00328         {
00329                 Swapfile::swapPath1->insert("/mnt/card/swapfile");
00330         }
00331         if  (Swapfile::cfRB->isChecked() == TRUE)
00332         {
00333                 Swapfile::swapPath1->insert("/mnt/cf/swapfile");
00334         }
00335 /*      Swapfile::swapPath->insert(Swapfile::swapPath1->text());*/
00336 }
00337 
00338 void Swapfile::makeswapfile()
00339 {
00340         int i = swapSize->currentItem();
00341 
00342         mkswapProgress->setProgress(1);
00343         switch ( i ) {
00344                 case 0: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=2048").arg(swapPath1->text()));
00345                 break;
00346                 case 1: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=4096").arg(swapPath1->text()));
00347                 break;
00348                 case 2: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=6144").arg(swapPath1->text()));
00349                 break;
00350                 case 3: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=8192").arg(swapPath1->text()));
00351                 break;
00352         case 4: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=16384").arg(swapPath1->text()));
00353         break;
00354         case 5: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=32768").arg(swapPath1->text()));
00355         break;
00356         case 6: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=65536").arg(swapPath1->text()));
00357         break;
00358 
00359         }
00360         if (rc != 0) {
00361                    setStatusMessage(tr("Failed to create swapfile."), true);
00362         }
00363 
00364         mkswapProgress->setProgress(2);
00365         rc=exec(QString("mkswap %1").arg(swapPath1->text()));
00366         if (rc != 0) {
00367                    setStatusMessage(tr("Failed to initialize swapfile."), true);
00368         }
00369         mkswapProgress->setProgress(3);
00370         mkswapProgress->reset();
00371         setStatusMessage(tr("Swapfile created."));
00372 }
00373 
00374 void Swapfile::removeswapfile()
00375 {
00376         exec(QString("swapoff %1").arg(swapPath1->text()));
00377         rc=exec(QString("rm -rf %1").arg(swapPath1->text()));
00378         if (rc != 0) {
00379                    setStatusMessage(tr("Failed to remove swapfile."), true);
00380         }
00381         Swapfile::status();
00382         Swapfile::cfsdchecked();
00383         setStatusMessage(tr("Swapfile removed."));
00384 }
00385 
00386 void Swapfile::status()
00387 {
00388         FILE *fp;
00389         char buffer[128], swapfile[128], temp[128];
00390         int swapsize=2000, i=1;
00391 
00392         fp=fopen("/proc/swaps", "r");
00393         while  ( (fgets(buffer,128,fp)) != NULL ) {
00394                sscanf(buffer, "%s %s %d %s %s\n", swapfile, temp, &swapsize, temp, temp);
00395         }
00396         fclose(fp);
00397 
00398         ramRB->setChecked(FALSE);
00399         cfRB->setChecked(FALSE);
00400         sdRB->setChecked(FALSE);
00401 
00402         i=strcmp(swapfile, "/home/swapfile");
00403         if ( i == 0 ) {
00404            ramRB->setChecked(TRUE);
00405 /*         QMessageBox::information(this, "Information", "Swapfile is active!"); */
00406            setStatusMessage(tr("Swapfile activated."));
00407         }
00408         i=strcmp(swapfile, "/usr/mnt.rom/cf/swapfile");
00409         if ( i == 0 ) {
00410            cfRB->setChecked(TRUE);
00411 /*         QMessageBox::information(this, "Information", "Swapfile is active!"); */
00412            setStatusMessage(tr("Swapfile activated."));
00413         }
00414         i=strcmp(swapfile, "/mnt/cf/swapfile");
00415         if ( i == 0 ) {
00416            cfRB->setChecked(TRUE);
00417 /*         QMessageBox::information(this, "Information", "Swapfile is active!"); */
00418            setStatusMessage(tr("Swapfile activated."));
00419         }
00420         i=strcmp(swapfile, "/usr/mnt.rom/card/swapfile");
00421         if ( i == 0 ) {
00422            sdRB->setChecked(TRUE);
00423 /*         QMessageBox::information(this, "Information", "Swapfile is active!"); */
00424            setStatusMessage(tr("Swapfile activated."));
00425         }
00426         i=strcmp(swapfile, "/mnt/card/swapfile");
00427         if ( i == 0 ) {
00428            sdRB->setChecked(TRUE);
00429 /*         QMessageBox::information(this, "Information", "Swapfile is active!"); */
00430            setStatusMessage(tr("Swapfile activated."));
00431         }
00432 
00433         Swapfile::cfsdchecked();
00434 
00435 
00436         swapsize /=1000;
00437 
00438         switch ( swapsize ) {
00439                 case 2: swapSize->setCurrentItem(0);
00440                 break;
00441                 case 4: swapSize->setCurrentItem(1);
00442                 break;
00443                 case 6: swapSize->setCurrentItem(2);
00444                 break;
00445                 case 8: swapSize->setCurrentItem(3);
00446                 break;
00447         case 16: swapSize->setCurrentItem(4);
00448         break;
00449         case 32: swapSize->setCurrentItem(5);
00450         break;
00451         case 64: swapSize->setCurrentItem(6);
00452         break;
00453         }
00454 
00455 
00456 }
00457 
00458 

Generated on Sat Nov 5 16:16:44 2005 for OPIE by  doxygen 1.4.2