cvs20080628 - trunk
[gitenigma.git] / src / flashtool.cpp
blobdc67c3b663e28ef65140b3c10aaf2e96da527c6e
1 #ifdef ENABLE_FLASHTOOL
2 /**********************************************
4 * $Revision: 1.11 $
6 **********************************************/
8 #include <flashtool.h>
9 #include <enigma.h>
11 #include <lib/gui/emessage.h>
12 #include <lib/gui/eprogress.h>
13 #include <lib/dvb/decoder.h>
15 #include <sys/wait.h>
16 #include <sys/reboot.h>
17 #include <unistd.h>
18 #include <signal.h>
19 #include <dirent.h>
21 #include <fcntl.h>
22 #include <sys/ioctl.h>
23 #include <sys/mount.h>
24 #include <linux/version.h>
25 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
26 #include <linux/compiler.h>
27 #endif
28 #include <mtd/mtd-user.h>
30 class FlashProgressWindow: public eWindow
32 public:
33 eProgress progress;
34 FlashProgressWindow(const char *);
37 FlashProgressWindow::FlashProgressWindow(const char *wtext)
38 :eWindow(0), progress(this)
40 move(ePoint(100,250));
41 cresize(eSize(470,50));
42 setText(wtext);
43 progress.move(ePoint(10,10));
44 progress.resize(eSize(450,30));
48 eFlashtoolMain::eFlashtoolMain()
49 :eListBoxWindow<eListBoxEntryText>(_("Flashtool"), 2, 350)
51 move(ePoint(150, 100));
52 new eListBoxEntryText(&list, _("Save image or part of it"), (void *)0);
53 new eListBoxEntryText(&list, _("Flash image or part of it"), (void *)1);
54 CONNECT(list.selected, eFlashtoolMain::sel_item);
57 void eFlashtoolMain::sel_item(eListBoxEntryText *sel)
59 if (sel)
61 int flashtool=(int)sel->getKey();
62 /*if (flashtool==-1)
64 close(0);
65 return;
66 }*/
68 hide();
69 eFlashtool flash(flashtool);
70 flash.show();
71 flash.exec();
72 flash.hide();
73 show();
77 eFlashtoolMain::~eFlashtoolMain()
81 eFlashtool::eFlashtool(int direction)
82 :eListBoxWindow<eListBoxEntryText>(_("Partitions"), 12, 400)
84 /* direction == 0 --> read
85 * direction == 1 --> write
88 flashimage = direction;
89 move(ePoint(150, 100));
90 //new eListBoxEntryText(&list, _("back"), (void *)-1);
92 FILE* fd = fopen("/proc/mtd", "r");
93 if (!fd)
95 perror("cannot read /proc/mtd");
96 return;
99 int entries = 0;
100 char buf[1000];
101 fgets(buf,sizeof(buf), fd);
102 while(!feof(fd))
104 if (fgets(buf, sizeof(buf), fd) != NULL)
106 char mtdname[50] = "";
107 int mtdnr = 0;
108 int mtdsize = 0;
109 int mtderasesize = 0;
110 sscanf(buf, "mtd%d: %x %x \"%[a-zA-Z0-9 =/+`äö<>@^°!?'.:,_-()#\\]\"\n", &mtdnr, &mtdsize, &mtderasesize, mtdname);
111 new eListBoxEntryText(&list, _(mtdname), (void*)mtdnr);
112 entries++;
115 fclose(fd);
117 cresize(eSize(400, 10 + entries * eListBoxEntryText::getEntryHeight()));
118 list.move(ePoint(10, 5));
119 list.resize(eSize(getClientSize().width() - 20, getClientSize().height() - 5));
121 CONNECT(list.selected, eFlashtool::sel_item);
124 eFlashtool::~eFlashtool()
128 void eFlashtool::sel_item(eListBoxEntryText *sel)
130 if (sel)
132 mtd = (int)sel->getKey();
134 /*if (mtd == -1)
136 eWidget::accept();
137 return;
140 hide();
142 char destination[100];
143 eFlashtoolSource imagesource(flashimage);
144 imagesource.show();
145 int res = imagesource.exec();
146 imagesource.hide();
147 strcpy(destination, imagesource.getDestination());
149 if (res == 2)
150 if (flashimage == 0)
151 readmtd(destination);
152 else
154 eMessageBox box(_("Do you really want to flash a new image now?"), _("Flash"), eMessageBox::btYes|eMessageBox::btNo|eMessageBox::iconWarning, eMessageBox::btNo);
155 box.show();
156 int res = box.exec();
157 box.hide();
158 if (res == eMessageBox::btYes)
159 programm(destination);
161 show();
165 void eFlashtool::programm(char filename[])
167 char mtddev[20];
169 sprintf(mtddev,"/dev/mtd/%d", mtd);
171 if (access(filename, R_OK) == 0)
173 int fd1, fd2;
174 unsigned long filesize;
176 hide();
178 if ((fd1 = open(filename, O_RDONLY)) < 0)
180 eMessageBox box(_("Can't read image!"), _("Flash"), eMessageBox::iconInfo|eMessageBox::btOK);
181 box.show();
182 box.exec();
183 box.hide();
184 return;
187 filesize = lseek(fd1, 0, SEEK_END);
188 lseek(fd1, 0, SEEK_SET);
190 if (filesize==0)
192 eMessageBox box(_("Image has file size of 0 bytes!"), _("Flash"), eMessageBox::iconInfo|eMessageBox::btOK);
193 box.show();
194 box.exec();
195 box.hide();
196 return;
199 if ((fd2 = open(mtddev, O_WRONLY)) < 0)
201 eMessageBox box(_("Can't open mtd!"), _("Flash"), eMessageBox::iconInfo|eMessageBox::btOK);
202 box.show();
203 box.exec();
204 box.hide();
205 ::close(fd2);
206 return;
209 mtd_info_t meminfo;
210 if (ioctl(fd2, MEMGETINFO, &meminfo) != 0)
212 return;
215 if (filesize > meminfo.size)
217 eMessageBox box(_("Image size is too big! Can't flash!"), _("Flash"), eMessageBox::iconInfo|eMessageBox::btOK);
218 box.show();
219 box.exec();
220 box.hide();
221 return;
224 if (filesize < ((meminfo.size/100)*70))
226 eMessageBox box(_("Image size is too small! Do you really want to flash it?"), _("Flash"), eMessageBox::btYes|eMessageBox::btNo|eMessageBox::iconWarning, eMessageBox::btNo);
227 box.show();
228 int res=box.exec();
229 box.hide();
230 if (res == eMessageBox::btNo)
232 return;
236 eMessageBox mb(_("Please wait... do NOT switch off the receiver!"),_("flashing in progress"), eMessageBox::iconWarning);
237 mb.show();
239 sync();
240 Decoder::Flush();
242 // without this nice we have not enough priority for
243 // file operations... then the update ist very slow on the
244 // dreambox
245 nice(-10);
247 printf("Starting erasing %s...\n",mtddev);
249 if (!erase())
251 eMessageBox box(_("Erase error!"), _("Flash"), eMessageBox::iconInfo|eMessageBox::btOK);
252 box.show();
253 box.exec();
254 box.hide();
255 return;
258 FlashProgressWindow wnd(_("Writing image to flash...\n"));
259 wnd.show();
261 char buf[meminfo.erasesize];
262 long fsize = filesize;
264 printf("flashing now...\n");
265 while (fsize > 0)
267 long block = fsize;
268 if (block>(long)sizeof(buf))
270 block = sizeof(buf);
272 read(fd1, buf, block);
273 write(fd2, buf, block);
274 fsize -= block;
275 wnd.progress.setPerc(((filesize - fsize) * 100) / filesize);
278 ::close(fd1);
279 ::close(fd2);
280 wnd.hide();
281 mb.hide();
282 printf("finished\n");
283 eMessageBox mbend(_("Flashing successful! restarting..."),
284 _("flashing ok"),eMessageBox::btOK|eMessageBox::iconInfo);
285 mbend.show();
286 mbend.exec();
287 mbend.hide();
288 ::reboot(RB_AUTOBOOT);
289 system("reboot");
290 return;
292 else
294 eMessageBox box(_("Image not found!"), _("Flash"), eMessageBox::iconWarning|eMessageBox::btOK);
295 box.show();
296 box.exec();
297 box.hide();
301 bool eFlashtool::erase()
303 int fd;
304 mtd_info_t meminfo;
305 erase_info_t erase;
307 eString mtddev;
308 mtddev.sprintf("/dev/mtd/%d", mtd);
310 if ((fd = open(mtddev.c_str(), O_RDWR)) < 0)
312 return false;
315 if (ioctl(fd, MEMGETINFO, &meminfo) != 0)
317 return false;
320 FlashProgressWindow wnd(_("Erasing flash..."));
321 wnd.show();
322 erase.length = meminfo.erasesize;
323 for (erase.start = 0; erase.start < meminfo.size; erase.start += meminfo.erasesize)
326 printf("\rErasing %u KByte @ %x -- %2u %% complete.",
327 meminfo.erasesize / 1024, erase.start,
328 erase.start * 100 / meminfo.size);
330 wnd.progress.setPerc(erase.start * 100 / meminfo.size);
331 if (ioctl(fd, MEMERASE, &erase) != 0)
333 ::close(fd);
334 return false;
338 ::close(fd);
339 wnd.hide();
340 return true;
343 bool eFlashtool::readmtd(char destination[])
345 int fd1, fd2;
346 char mtddev[50];
347 long filesize;
348 mtd_info_t meminfo;
350 FILE *fd = fopen("/.version", "r");
352 char filename[50];
353 sprintf(filename, "%s/mtd%d.img", destination, mtd);
354 if (fd)
356 char buffer[100];
357 fgets(buffer, sizeof(buffer), fd);
358 fclose(fd);
359 char date[9];
360 char time[5];
361 sscanf(buffer,"version=%*2s%*2s%8s%4s", date, time);
362 sprintf(filename,"%s/%s_%s_mtd%d.img", destination, date, time, mtd);
365 sprintf(mtddev, "/dev/mtd/%d", mtd);
367 if ((fd1 = open(mtddev, O_RDONLY)) < 0)
369 eMessageBox box(_("Can't open mtd device!"), _("Flash"), eMessageBox::iconWarning|eMessageBox::btOK);
370 box.show();
371 box.exec();
372 box.hide();
373 return false;
376 if (ioctl(fd1, MEMGETINFO, &meminfo) != 0)
378 return false;
381 if ((fd2 = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) < 0)
383 eString message = eString(_("Can't open ")) + eString(destination) + eString(_(" for writing!"));
384 eMessageBox box(message.c_str(), _("Flash"), eMessageBox::iconWarning|eMessageBox::btOK);
385 box.show();
386 box.exec();
387 box.hide();
388 ::close(fd1);
389 return false;
392 filesize = meminfo.size;
394 eMessageBox mb(_("Please wait while partition is being saved..."),_("saving in progress"), eMessageBox::iconInfo);
395 mb.show();
397 FlashProgressWindow wnd(_("Read Flash..."));
398 wnd.show();
399 char buf[meminfo.erasesize];
400 long fsize = filesize;
401 while(fsize > 0)
403 long block = fsize;
404 if (block > (long)sizeof(buf))
405 block = sizeof(buf);
406 read(fd1, &buf, block);
407 write(fd2, &buf, block);
408 fsize -= block;
409 wnd.progress.setPerc(((filesize - fsize) * 100) / filesize);
411 ::close(fd1);
412 ::close(fd2);
413 wnd.hide();
415 eString message = eString(_("Image saved to: ")) + eString(filename);
416 eMessageBox boxend(message.c_str(), _("Flash"), eMessageBox::iconInfo|eMessageBox::btOK);
417 boxend.show();
418 boxend.exec();
419 boxend.hide();
421 mb.hide();
423 return true;
426 eFlashtoolImageView::eFlashtoolImageView(char folder[])
427 :eListBoxWindow<eListBoxEntryText>(_("Image list"), 11, 530)
429 new eListBoxEntryText(&list, _("back"), (void *)new eString("back"), 0, "Choose your image and press OK...");
431 move(ePoint(100, 100));
432 int entries = 2;
433 struct dirent **namelist;
434 int n = scandir(folder, &namelist, 0, alphasort);
435 if (n < 0)
437 perror("no flash images available");
439 else
441 for(int count = 0; count < n; count++)
443 eString filen = namelist[count]->d_name;
444 int pos = filen.find(".img");
445 if (pos != -1)
447 char tmp[100];
448 char helptext[100];
449 int fd1;
450 sprintf(tmp, "%s/%s", folder, filen.c_str());
451 if ((fd1 = open(tmp, O_RDONLY)) < 0)
452 sprintf(helptext, "WARNING: can't open this image!");
453 else
455 int filesize = lseek(fd1, 0, SEEK_END);
456 lseek(fd1, 0, SEEK_SET);
457 sprintf(helptext, "Image size: %d byte\n", filesize);
458 ::close(fd1);
461 new eListBoxEntryText(&list, filen, (void *)new eString(tmp), 0, helptext);
462 entries++;
464 free(namelist[count]);
466 free(namelist);
469 cresize(eSize(530, 10 + (entries > 10 ? 10 : entries) * eListBoxEntryText::getEntryHeight()));
470 list.move(ePoint(10, 5));
471 list.resize(eSize(getClientSize().width() - 20, getClientSize().height() - 30));
473 CONNECT(list.selected, eFlashtoolImageView::sel_item);
475 statusbar = new eStatusBar(this);
476 statusbar->move(ePoint(0, clientrect.height() - 30));
477 statusbar->resize(eSize(clientrect.width(), 30));
478 statusbar->setText("");
479 statusbar->loadDeco();
482 void eFlashtoolImageView::sel_item(eListBoxEntryText *sel)
484 if (sel)
486 sprintf(buffer,((eString *)sel->getKey())->c_str());
487 close(1);
489 else
490 close(0);
493 char* eFlashtoolImageView::getFilename()
495 return buffer;
498 eFlashtoolImageView::~eFlashtoolImageView()
502 eFlashtoolSource::eFlashtoolSource(int direction)
503 #ifndef DISABLE_FILE
504 :eListBoxWindow<eListBoxEntryText>(_("Save to..."), 5, 400)
505 #else
506 :eListBoxWindow<eListBoxEntryText>(_("Save to..."), 3, 400)
507 #endif
509 flash = false;
511 if (direction == 1)
513 setText(_("Select source..."));
514 flash = true;
517 move(ePoint(150, 100));
518 //new eListBoxEntryText(&list, _("back"), (void *)"back");
519 new eListBoxEntryText(&list, "tmp", (void *)"/tmp");
520 #ifndef DISABLE_FILE
521 if (access("/hdd/images", W_OK) == 0)
522 new eListBoxEntryText(&list, "HDD", (void *)"/hdd/images");
523 if (access("/var/mnt/usb/images", W_OK) == 0)
524 new eListBoxEntryText(&list, "USB", (void *)"/var/mnt/usb/images");
525 #endif
526 if (access("/var/mnt/nfs/images", W_OK) == 0)
527 new eListBoxEntryText(&list, "NFS", (void *)"/var/mnt/nfs/images");
528 if (access("/var/mnt/cifs/images", W_OK) == 0)
529 new eListBoxEntryText(&list, "CIFS", (void *)"/var/mnt/cifs/images");
530 CONNECT(list.selected, eFlashtoolSource::sel_item);
533 void eFlashtoolSource::sel_item(eListBoxEntryText *sel)
535 if (sel)
537 strcpy(buffer, (char *)sel->getKey());
539 if (strcmp(buffer, "back") == 0)
541 close(1);
542 return;
545 hide();
547 int res = 1;
548 if (flash)
550 eFlashtoolImageView image(buffer);
551 image.show();
552 res = image.exec();
553 image.hide();
554 strcpy(buffer, image.getFilename());
556 if (strcmp(buffer, "back") == 0 || res == 0)
557 show();
558 else
559 close(2);
563 char* eFlashtoolSource::getDestination()
565 return buffer;
568 eFlashtoolSource::~eFlashtoolSource()
572 #endif // ENABLE_FLASHTOOL