00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "swapfile.h"
00023
00024
00025 #include <opie2/odebug.h>
00026 #include <opie2/oresource.h>
00027 using namespace Opie::Core;
00028
00029
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
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
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;
00163 bool cardWas1 = cardInPcmcia1;
00164
00165 QString fileName;
00166
00167
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
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;
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
00287 setStatusMessage("Swapfile activated.");
00288 }
00289 Swapfile::status();
00290 }
00291
00292
00293 void Swapfile::setStatusMessage(const QString& text, bool error )
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
00313 setStatusMessage(tr("Swapfile deactivated."));
00314
00315 }
00316 Swapfile::status();
00317 }
00318
00319 void Swapfile::cfsdchecked()
00320 {
00321
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
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
00406 setStatusMessage(tr("Swapfile activated."));
00407 }
00408 i=strcmp(swapfile, "/usr/mnt.rom/cf/swapfile");
00409 if ( i == 0 ) {
00410 cfRB->setChecked(TRUE);
00411
00412 setStatusMessage(tr("Swapfile activated."));
00413 }
00414 i=strcmp(swapfile, "/mnt/cf/swapfile");
00415 if ( i == 0 ) {
00416 cfRB->setChecked(TRUE);
00417
00418 setStatusMessage(tr("Swapfile activated."));
00419 }
00420 i=strcmp(swapfile, "/usr/mnt.rom/card/swapfile");
00421 if ( i == 0 ) {
00422 sdRB->setChecked(TRUE);
00423
00424 setStatusMessage(tr("Swapfile activated."));
00425 }
00426 i=strcmp(swapfile, "/mnt/card/swapfile");
00427 if ( i == 0 ) {
00428 sdRB->setChecked(TRUE);
00429
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