Diffstat (limited to 'noncore/applets/memoryapplet/swapfile.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/applets/memoryapplet/swapfile.cpp | 436 |
1 files changed, 436 insertions, 0 deletions
diff --git a/noncore/applets/memoryapplet/swapfile.cpp b/noncore/applets/memoryapplet/swapfile.cpp new file mode 100644 index 0000000..06746a7 --- a/dev/null +++ b/noncore/applets/memoryapplet/swapfile.cpp | |||
@@ -0,0 +1,436 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "swapfile.h" | ||
22 | |||
23 | #include <qlabel.h> | ||
24 | #include <qtimer.h> | ||
25 | #include <qfile.h> | ||
26 | #include <qtextstream.h> | ||
27 | #include <qlayout.h> | ||
28 | #include <qpushbutton.h> | ||
29 | #include <qhbuttongroup.h> | ||
30 | #include <qradiobutton.h> | ||
31 | #include <qlineedit.h> | ||
32 | #include <qprogressbar.h> | ||
33 | #include <qcombobox.h> | ||
34 | #include <qvgroupbox.h> | ||
35 | #include <qhbox.h> | ||
36 | #include <qmessagebox.h> | ||
37 | #include <stdio.h> | ||
38 | #include <stdlib.h> | ||
39 | #include <string.h> | ||
40 | #include <qfile.h> | ||
41 | #include <qtextstream.h> | ||
42 | |||
43 | #include <qcopchannel_qws.h> | ||
44 | #include <qpe/resource.h> | ||
45 | |||
46 | #include <unistd.h> | ||
47 | #include <fcntl.h> | ||
48 | #include <sys/vfs.h> | ||
49 | #include <mntent.h> | ||
50 | #include <unistd.h> | ||
51 | #include <sys/types.h> | ||
52 | |||
53 | Swapfile::Swapfile( QWidget *parent, const char *name, WFlags f ) | ||
54 | : QWidget( parent, name, f ) | ||
55 | { | ||
56 | // are we running as root? | ||
57 | isRoot = geteuid() == 0; | ||
58 | |||
59 | QVBoxLayout* vb = new QVBoxLayout(this, 5); | ||
60 | |||
61 | QHButtonGroup* cfsdRBG = new QHButtonGroup(tr("Swapfile location"), this); | ||
62 | cfsdRBG->setRadioButtonExclusive(true); | ||
63 | vb->addWidget(cfsdRBG); | ||
64 | |||
65 | ramRB = new QRadioButton(tr("RAM"), cfsdRBG); | ||
66 | cfRB = new QRadioButton(tr("CF Card"), cfsdRBG); | ||
67 | sdRB = new QRadioButton(tr("SD Card"), cfsdRBG); | ||
68 | |||
69 | QHBox *hb1 = new QHBox(this); | ||
70 | hb1->setSpacing(5); | ||
71 | |||
72 | swapPath1 = new QLineEdit(hb1); | ||
73 | swapPath1->setEnabled(false); | ||
74 | |||
75 | QPushButton* swapOn = new QPushButton(tr(" On "), hb1); | ||
76 | QPushButton* swapOff = new QPushButton(tr(" Off "), hb1); | ||
77 | vb->addWidget(hb1); | ||
78 | |||
79 | QVGroupBox* box1 = new QVGroupBox(tr("Manage Swapfile"), this); | ||
80 | vb->addWidget(box1); | ||
81 | |||
82 | QHBox *hb2 = new QHBox(box1); | ||
83 | hb2->setSpacing(5); | ||
84 | QPushButton* mkSwap = new QPushButton(tr("Generate"), hb2); | ||
85 | QPushButton* rmSwap = new QPushButton(tr("Remove"), hb2); | ||
86 | |||
87 | QHBox *hb3 = new QHBox(box1); | ||
88 | hb3->setSpacing(5); | ||
89 | swapSize = new QComboBox(hb3); | ||
90 | swapSize->insertStringList(QStringList::split(",", tr("2 Mb,4 Mb,6 Mb,8 Mb"))); | ||
91 | |||
92 | mkswapProgress = new QProgressBar(3, hb3); | ||
93 | mkswapProgress->setCenterIndicator(true); | ||
94 | |||
95 | QHBox *hb4 = new QHBox(this); | ||
96 | hb4->setSpacing(5); | ||
97 | |||
98 | swapStatusIcon = new QLabel(hb4); | ||
99 | swapStatus = new QLabel(tr(""), hb4); | ||
100 | hb4->setStretchFactor(swapStatus, 99); | ||
101 | vb->addWidget(hb4); | ||
102 | |||
103 | connect(swapOn, SIGNAL(clicked()), this, SLOT(swapon())); | ||
104 | connect(swapOff, SIGNAL(clicked()), this, SLOT(swapoff())); | ||
105 | connect(cfRB, SIGNAL(clicked()), this, SLOT(cfsdchecked())); | ||
106 | connect(sdRB, SIGNAL(clicked()), this, SLOT(cfsdchecked())); | ||
107 | connect(ramRB, SIGNAL(clicked()), this, SLOT(cfsdchecked())); | ||
108 | connect(mkSwap, SIGNAL(clicked()), this, SLOT(makeswapfile())); | ||
109 | connect(rmSwap, SIGNAL(clicked()), this, SLOT(removeswapfile())); | ||
110 | |||
111 | cfRB->setEnabled(FALSE); | ||
112 | sdRB->setEnabled(FALSE); | ||
113 | |||
114 | QCopChannel *pcmciaChannel = new QCopChannel("QPE/Card", this); | ||
115 | connect(pcmciaChannel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(cardnotify(const QCString &, const QByteArray &))); | ||
116 | QCopChannel *sdChannel = new QCopChannel("QPE/Card", this); | ||
117 | connect(sdChannel, SIGNAL(received(const QCString &, const QByteArray &)), this, SLOT(cardnotify(const QCString &, const QByteArray &))); | ||
118 | |||
119 | cardInPcmcia0 = FALSE; | ||
120 | cardInPcmcia1 = FALSE; | ||
121 | cardInSd = FALSE; | ||
122 | |||
123 | Swapfile::status(); | ||
124 | Swapfile::getStatusPcmcia(); | ||
125 | Swapfile::getStatusSd(); | ||
126 | } | ||
127 | |||
128 | int Swapfile::exec(const QString& arg) | ||
129 | { | ||
130 | return system((!isRoot ? "sudo " : "") + arg); | ||
131 | } | ||
132 | |||
133 | |||
134 | Swapfile::~Swapfile() | ||
135 | { | ||
136 | } | ||
137 | |||
138 | void Swapfile::cardnotify(const QCString & msg, const QByteArray &) | ||
139 | { | ||
140 | if (msg == "stabChanged()") | ||
141 | { | ||
142 | getStatusPcmcia(); | ||
143 | } | ||
144 | else if (msg == "mtabChanged()") | ||
145 | { | ||
146 | getStatusSd(); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | void Swapfile::getStatusPcmcia() | ||
151 | { | ||
152 | |||
153 | bool cardWas0 = cardInPcmcia0;// remember last state | ||
154 | bool cardWas1 = cardInPcmcia1; | ||
155 | |||
156 | QString fileName; | ||
157 | |||
158 | // one of these 3 files should exist | ||
159 | if (QFile::exists("/var/run/stab")) { | ||
160 | fileName = "/var/run/stab"; | ||
161 | } else if (QFile::exists("/var/state/pcmcia/stab")) { | ||
162 | fileName = "/var/state/pcmcia/stab"; | ||
163 | } else { | ||
164 | fileName = "/var/lib/pcmcia/stab"; | ||
165 | } | ||
166 | |||
167 | QFile f(fileName); | ||
168 | |||
169 | if (f.open(IO_ReadOnly)) { | ||
170 | QStringList list; | ||
171 | QTextStream stream(&f); | ||
172 | QString streamIn; | ||
173 | streamIn = stream.read(); | ||
174 | list = QStringList::split("\n", streamIn); | ||
175 | for (QStringList::Iterator line = list.begin(); line != list.end(); | ||
176 | line++) { | ||
177 | if ((*line).startsWith("Socket 0:")) { | ||
178 | if ((*line).startsWith("Socket 0: empty") && cardInPcmcia0) { | ||
179 | cardInPcmcia0 = FALSE; | ||
180 | } else if (!(*line).startsWith("Socket 0: empty") | ||
181 | && !cardInPcmcia0) { | ||
182 | cardInPcmcia0 = TRUE; | ||
183 | } | ||
184 | } else if ((*line).startsWith("Socket 1:")) { | ||
185 | if ((*line).startsWith("Socket 1: empty") && cardInPcmcia1) { | ||
186 | cardInPcmcia1 = FALSE; | ||
187 | } else if (!(*line).startsWith("Socket 1: empty") | ||
188 | && !cardInPcmcia1) { | ||
189 | cardInPcmcia1 = TRUE; | ||
190 | } | ||
191 | } | ||
192 | } | ||
193 | f.close(); | ||
194 | |||
195 | if (cardWas0 != cardInPcmcia0 || cardWas1 != cardInPcmcia1) { | ||
196 | QString text = QString::null; | ||
197 | QString what = QString::null; | ||
198 | if (cardWas0 != cardInPcmcia0) { | ||
199 | if (cardInPcmcia0) { | ||
200 | cfRB->setEnabled(TRUE); | ||
201 | } else { | ||
202 | cfRB->setChecked(FALSE); | ||
203 | cfRB->setEnabled(FALSE); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | if (cardWas1 != cardInPcmcia1) { | ||
208 | if (cardInPcmcia1) { | ||
209 | cfRB->setEnabled(TRUE); | ||
210 | } else { | ||
211 | cfRB->setChecked(FALSE); | ||
212 | cfRB->setEnabled(FALSE); | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | } else { | ||
217 | // no file found | ||
218 | qDebug("no file found"); | ||
219 | cardInPcmcia0 = FALSE; | ||
220 | cardInPcmcia1 = FALSE; | ||
221 | } | ||
222 | Swapfile::cfsdchecked(); | ||
223 | } | ||
224 | |||
225 | |||
226 | void Swapfile::getStatusSd() | ||
227 | { | ||
228 | |||
229 | bool cardWas = cardInSd;// remember last state | ||
230 | cardInSd = FALSE; | ||
231 | |||
232 | #if defined(_OS_LINUX_) || defined(Q_OS_LINUX) | ||
233 | struct mntent *me; | ||
234 | FILE *mntfp = setmntent("/etc/mtab", "r"); | ||
235 | |||
236 | if (mntfp) { | ||
237 | while ((me = getmntent(mntfp)) != 0) { | ||
238 | QString fs = me->mnt_fsname; | ||
239 | if (fs.left(14) == "/dev/mmc/part1" || fs.left(7) == "/dev/sd" | ||
240 | || fs.left(9) == "/dev/mmcd") { | ||
241 | cardInSd = TRUE; | ||
242 | show(); | ||
243 | } | ||
244 | } | ||
245 | endmntent(mntfp); | ||
246 | } | ||
247 | |||
248 | if (cardWas != cardInSd) { | ||
249 | QString text = QString::null; | ||
250 | QString what = QString::null; | ||
251 | if (cardInSd) { | ||
252 | sdRB->setEnabled(TRUE); | ||
253 | } else { | ||
254 | sdRB->setChecked(FALSE); | ||
255 | sdRB->setEnabled(FALSE); | ||
256 | } | ||
257 | } | ||
258 | #else | ||
259 | #error "Not on Linux" | ||
260 | #endif | ||
261 | Swapfile::cfsdchecked(); | ||
262 | } | ||
263 | |||
264 | int rc=0; | ||
265 | |||
266 | void Swapfile::swapon() | ||
267 | { | ||
268 | char swapcmd[128] ="swapon "; | ||
269 | Swapfile::cfsdchecked(); | ||
270 | strcat(swapcmd,swapPath1->text()); | ||
271 | char *runcmd = swapcmd; | ||
272 | rc = exec(QString("%1").arg(runcmd)); | ||
273 | if (rc != 0) { | ||
274 | setStatusMessage("Failed to attach swapfile.", true); | ||
275 | } | ||
276 | else { | ||
277 | /* QMessageBox::information(this, "Information", "Swapfile is active!"); */ | ||
278 | setStatusMessage("Swapfile activated."); | ||
279 | } | ||
280 | Swapfile::status(); | ||
281 | } | ||
282 | |||
283 | |||
284 | void Swapfile::setStatusMessage(const QString& text, bool error /* = false */) | ||
285 | { | ||
286 | swapStatus->setText("<b>" + text + "</b>"); | ||
287 | swapStatusIcon->setPixmap(Resource::loadPixmap(error ? "close" : "done")); | ||
288 | } | ||
289 | |||
290 | |||
291 | void Swapfile::swapoff() | ||
292 | { | ||
293 | char swapcmd[128] ="swapoff "; | ||
294 | if (Swapfile::cfRB->isChecked() == TRUE) | ||
295 | Swapfile::cfsdchecked(); | ||
296 | strcat(swapcmd,swapPath1->text()); | ||
297 | char *runcmd = swapcmd; | ||
298 | rc = exec(QString("%1").arg(runcmd)); | ||
299 | if (rc != 0) { | ||
300 | setStatusMessage(tr("Failed to detach swapfile."), true); | ||
301 | } | ||
302 | else { | ||
303 | /* QMessageBox::information(this, "Information", "Swapfile is inactive!"); */ | ||
304 | setStatusMessage(tr("Swapfile deactivated.")); | ||
305 | /* Swapfile::swapPath->clear();*/ | ||
306 | } | ||
307 | Swapfile::status(); | ||
308 | } | ||
309 | |||
310 | void Swapfile::cfsdchecked() | ||
311 | { | ||
312 | /* Swapfile::swapPath->clear();*/ | ||
313 | Swapfile::swapPath1->clear(); | ||
314 | if (Swapfile::ramRB->isChecked() == TRUE) | ||
315 | { | ||
316 | Swapfile::swapPath1->insert("/home/swapfile"); | ||
317 | } | ||
318 | if (Swapfile::sdRB->isChecked() == TRUE) | ||
319 | { | ||
320 | Swapfile::swapPath1->insert("/mnt/card/swapfile"); | ||
321 | } | ||
322 | if (Swapfile::cfRB->isChecked() == TRUE) | ||
323 | { | ||
324 | Swapfile::swapPath1->insert("/mnt/cf/swapfile"); | ||
325 | } | ||
326 | /*Swapfile::swapPath->insert(Swapfile::swapPath1->text());*/ | ||
327 | } | ||
328 | |||
329 | void Swapfile::makeswapfile() | ||
330 | { | ||
331 | int i = swapSize->currentItem(); | ||
332 | |||
333 | mkswapProgress->setProgress(1); | ||
334 | switch ( i ) { | ||
335 | case 0: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=2048").arg(swapPath1->text())); | ||
336 | break; | ||
337 | case 1: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=4096").arg(swapPath1->text())); | ||
338 | break; | ||
339 | case 2: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=6144").arg(swapPath1->text())); | ||
340 | break; | ||
341 | case 3: rc=exec(QString("dd if=/dev/zero of=%1 bs=1k count=8192").arg(swapPath1->text())); | ||
342 | break; | ||
343 | } | ||
344 | if (rc != 0) { | ||
345 | setStatusMessage(tr("Failed to create swapfile."), true); | ||
346 | } | ||
347 | |||
348 | mkswapProgress->setProgress(2); | ||
349 | rc=exec(QString("mkswap %1").arg(swapPath1->text())); | ||
350 | if (rc != 0) { | ||
351 | setStatusMessage(tr("Failed to initialize swapfile."), true); | ||
352 | } | ||
353 | mkswapProgress->setProgress(3); | ||
354 | mkswapProgress->reset(); | ||
355 | setStatusMessage(tr("Swapfile created.")); | ||
356 | } | ||
357 | |||
358 | void Swapfile::removeswapfile() | ||
359 | { | ||
360 | exec(QString("swapoff %1").arg(swapPath1->text())); | ||
361 | rc=exec(QString("rm -rf %1").arg(swapPath1->text())); | ||
362 | if (rc != 0) { | ||
363 | setStatusMessage(tr("Failed to remove swapfile."), true); | ||
364 | } | ||
365 | Swapfile::status(); | ||
366 | Swapfile::cfsdchecked(); | ||
367 | setStatusMessage(tr("Swapfile removed.")); | ||
368 | } | ||
369 | |||
370 | void Swapfile::status() | ||
371 | { | ||
372 | FILE *fp; | ||
373 | char buffer[128], swapfile[128], temp[128]; | ||
374 | int swapsize=2000, i=1; | ||
375 | |||
376 | fp=fopen("/proc/swaps", "r"); | ||
377 | while ( (fgets(buffer,128,fp)) != NULL ) { | ||
378 | sscanf(buffer, "%s %s %d %s %s\n", swapfile, temp, &swapsize, temp, temp); | ||
379 | } | ||
380 | fclose(fp); | ||
381 | |||
382 | ramRB->setChecked(FALSE); | ||
383 | cfRB->setChecked(FALSE); | ||
384 | sdRB->setChecked(FALSE); | ||
385 | |||
386 | i=strcmp(swapfile, "/home/swapfile"); | ||
387 | if ( i == 0 ) { | ||
388 | ramRB->setChecked(TRUE); | ||
389 | /* QMessageBox::information(this, "Information", "Swapfile is active!"); */ | ||
390 | setStatusMessage(tr("Swapfile activated.")); | ||
391 | } | ||
392 | i=strcmp(swapfile, "/usr/mnt.rom/cf/swapfile"); | ||
393 | if ( i == 0 ) { | ||
394 | cfRB->setChecked(TRUE); | ||
395 | /* QMessageBox::information(this, "Information", "Swapfile is active!"); */ | ||
396 | setStatusMessage(tr("Swapfile activated.")); | ||
397 | } | ||
398 | i=strcmp(swapfile, "/mnt/cf/swapfile"); | ||
399 | if ( i == 0 ) { | ||
400 | cfRB->setChecked(TRUE); | ||
401 | /* QMessageBox::information(this, "Information", "Swapfile is active!"); */ | ||
402 | setStatusMessage(tr("Swapfile activated.")); | ||
403 | } | ||
404 | i=strcmp(swapfile, "/usr/mnt.rom/card/swapfile"); | ||
405 | if ( i == 0 ) { | ||
406 | sdRB->setChecked(TRUE); | ||
407 | /* QMessageBox::information(this, "Information", "Swapfile is active!"); */ | ||
408 | setStatusMessage(tr("Swapfile activated.")); | ||
409 | } | ||
410 | i=strcmp(swapfile, "/mnt/card/swapfile"); | ||
411 | if ( i == 0 ) { | ||
412 | sdRB->setChecked(TRUE); | ||
413 | /* QMessageBox::information(this, "Information", "Swapfile is active!"); */ | ||
414 | setStatusMessage(tr("Swapfile activated.")); | ||
415 | } | ||
416 | |||
417 | Swapfile::cfsdchecked(); | ||
418 | |||
419 | |||
420 | swapsize /=1000; | ||
421 | |||
422 | switch ( swapsize ) { | ||
423 | case 2: swapSize->setCurrentItem(0); | ||
424 | break; | ||
425 | case 4: swapSize->setCurrentItem(1); | ||
426 | break; | ||
427 | case 6: swapSize->setCurrentItem(2); | ||
428 | break; | ||
429 | case 8: swapSize->setCurrentItem(3); | ||
430 | break; | ||
431 | } | ||
432 | |||
433 | |||
434 | } | ||
435 | |||
436 | |||