mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-28 07:51:19 +02:00
Add small helper class to manage missing values e.g. needed for deallocated widget objects. This class we can also use for other things in future! In this context I added a vector for 'selected' values needed for deeper and deallocated submenues. The identification of widgets working now with a new widget parameter named 'w_index'. setSelected() and getSelected() functions are still working, but are not needed, if we use an index -add define for default widget index -add new header file for enums -adapted many menu classes for this parameter Hope it' works fine. If you find any menu without a 'memory', please add an index. git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-beta@1908 e54a6e83-5905-42d5-8d5c-058d10e6a962
556 lines
14 KiB
C++
556 lines
14 KiB
C++
/*
|
|
Neutrino-GUI - DBoxII-Project
|
|
|
|
Copyright (C) 2001 Steffen Hehn 'McClean'
|
|
Homepage: http://dbox.cyberphoria.org/
|
|
|
|
Kommentar:
|
|
|
|
Diese GUI wurde von Grund auf neu programmiert und sollte nun vom
|
|
Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert
|
|
auf der Client-Server Idee, diese GUI ist also von der direkten DBox-
|
|
Steuerung getrennt. Diese wird dann von Daemons uebernommen.
|
|
|
|
|
|
License: GPL
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <sys/time.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <dirent.h>
|
|
#include <dlfcn.h>
|
|
#include <sys/mount.h>
|
|
|
|
#include <global.h>
|
|
#include <neutrino.h>
|
|
#include <neutrino_menue.h>
|
|
|
|
#include <gui/widget/icons.h>
|
|
#include "gui/widget/stringinput.h"
|
|
#include "gui/widget/messagebox.h"
|
|
#include "gui/widget/hintbox.h"
|
|
#include "gui/widget/progresswindow.h"
|
|
|
|
#include "system/setting_helpers.h"
|
|
#include "system/settings.h"
|
|
#include "system/debug.h"
|
|
|
|
#include <gui/hdd_menu.h>
|
|
#include <mymenu.h>
|
|
#include <driver/screen_max.h>
|
|
|
|
|
|
static int my_filter(const struct dirent * dent)
|
|
{
|
|
if(dent->d_name[0] == 's' && dent->d_name[1] == 'd')
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
CHDDMenuHandler::CHDDMenuHandler()
|
|
{
|
|
width = w_max (58, 10);
|
|
}
|
|
|
|
CHDDMenuHandler::~CHDDMenuHandler()
|
|
{
|
|
|
|
}
|
|
|
|
int CHDDMenuHandler::exec(CMenuTarget* parent, const std::string &/*actionkey*/)
|
|
{
|
|
if (parent)
|
|
parent->hide();
|
|
|
|
return doMenu ();
|
|
}
|
|
|
|
int CHDDMenuHandler::doMenu ()
|
|
{
|
|
FILE * f;
|
|
int fd;
|
|
struct dirent **namelist;
|
|
int ret;
|
|
struct stat s;
|
|
int root_dev = -1;
|
|
|
|
bool hdd_found = 0;
|
|
int n = scandir("/sys/block", &namelist, my_filter, alphasort);
|
|
|
|
if (n < 0) {
|
|
perror("CHDDMenuHandler::doMenu: scandir(\"/sys/block\") failed");
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
|
|
|
|
CMenuWidget* hddmenu = new CMenuWidget(LOCALE_MAINMENU_SETTINGS, NEUTRINO_ICON_SETTINGS, width, 576, MN_WIDGET_ID_DRIVESETUP);
|
|
hddmenu->addIntroItems(LOCALE_HDD_SETTINGS);
|
|
|
|
hddmenu->addItem(new CMenuForwarder(LOCALE_HDD_ACTIVATE, true, "", new CHDDDestExec(), NULL, CRCInput::RC_red,NEUTRINO_ICON_BUTTON_RED));
|
|
|
|
hddmenu->addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_HDD_EXTENDED_SETTINGS));
|
|
|
|
hddmenu->addItem( new CMenuOptionChooser(LOCALE_HDD_SLEEP, &g_settings.hdd_sleep, HDD_SLEEP_OPTIONS, HDD_SLEEP_OPTION_COUNT, true));
|
|
hddmenu->addItem( new CMenuOptionChooser(LOCALE_HDD_NOISE, &g_settings.hdd_noise, HDD_NOISE_OPTIONS, HDD_NOISE_OPTION_COUNT, true));
|
|
|
|
//if(n > 0)
|
|
hddmenu->addItem(new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_HDD_MANAGE));
|
|
|
|
ret = stat("/", &s);
|
|
if (ret != -1)
|
|
root_dev = (s.st_dev & 0x0ffc0); /* hda = 0x0300, hdb = 0x0340 */
|
|
printf("HDD: root_dev: 0x%04x\n", root_dev);
|
|
std::string tmp_str[n];
|
|
CMenuWidget * tempMenu[n];
|
|
for(int i = 0; i < n;i++) {
|
|
char str[256];
|
|
char sstr[256];
|
|
char vendor[128], model[128];
|
|
int64_t bytes;
|
|
int64_t megabytes;
|
|
int removable = 0;
|
|
bool isroot = false;
|
|
|
|
printf("HDD: checking /sys/block/%s\n", namelist[i]->d_name);
|
|
snprintf(str, sizeof(str), "/dev/%s", namelist[i]->d_name);
|
|
fd = open(str, O_RDONLY);
|
|
if(fd < 0) {
|
|
printf("Cant open %s\n", str);
|
|
continue;
|
|
}
|
|
if (ioctl(fd, BLKGETSIZE64, &bytes))
|
|
perror("BLKGETSIZE64");
|
|
|
|
ret = fstat(fd, &s);
|
|
if (ret != -1) {
|
|
if ((int)(s.st_rdev & 0x0ffc0) == root_dev) {
|
|
isroot = true;
|
|
printf("-> root device is on this disk, skipping\n");
|
|
}
|
|
}
|
|
close(fd);
|
|
|
|
megabytes = bytes/1000000;
|
|
|
|
snprintf(str, sizeof(str), "/sys/block/%s/device/vendor", namelist[i]->d_name);
|
|
f = fopen(str, "r");
|
|
if(!f) {
|
|
printf("Cant open %s\n", str);
|
|
continue;
|
|
}
|
|
fscanf(f, "%s", vendor);
|
|
fclose(f);
|
|
|
|
snprintf(str, sizeof(str), "/sys/block/%s/device/model", namelist[i]->d_name);
|
|
f = fopen(str, "r");
|
|
if(!f) {
|
|
printf("Cant open %s\n", str);
|
|
continue;
|
|
}
|
|
fscanf(f, "%s", model);
|
|
fclose(f);
|
|
|
|
snprintf(str, sizeof(str), "/sys/block/%s/removable", namelist[i]->d_name);
|
|
f = fopen(str, "r");
|
|
if(!f) {
|
|
printf("Cant open %s\n", str);
|
|
continue;
|
|
}
|
|
fscanf(f, "%d", &removable);
|
|
fclose(f);
|
|
|
|
snprintf(str, sizeof(str), "%s %s %lld %s", vendor, model, megabytes < 10000 ? megabytes : megabytes/1000, megabytes < 10000 ? "MB" : "GB");
|
|
printf("HDD: %s\n", str);
|
|
tmp_str[i]=str;
|
|
tempMenu[i] = new CMenuWidget(str, NEUTRINO_ICON_SETTINGS);
|
|
tempMenu[i]->addIntroItems();
|
|
//tempMenu->addItem( new CMenuOptionChooser(LOCALE_HDD_FS, &g_settings.hdd_fs, HDD_FILESYS_OPTIONS, HDD_FILESYS_OPTION_COUNT, true));
|
|
tempMenu[i]->addItem(new CMenuForwarder(LOCALE_HDD_FORMAT, true, "", new CHDDFmtExec, namelist[i]->d_name));
|
|
tempMenu[i]->addItem(new CMenuForwarder(LOCALE_HDD_CHECK, true, "", new CHDDChkExec, namelist[i]->d_name));
|
|
|
|
snprintf(sstr, sizeof(sstr), "%s (%s)", g_Locale->getText(LOCALE_HDD_REMOVABLE_DEVICE), namelist[i]->d_name);
|
|
hddmenu->addItem(new CMenuForwarderNonLocalized((removable ? sstr : namelist[i]->d_name), (removable || isroot) ? false : true, tmp_str[i], tempMenu[i]));
|
|
|
|
hdd_found = 1;
|
|
free(namelist[i]);
|
|
}
|
|
if (n >= 0)
|
|
free(namelist);
|
|
|
|
if(!hdd_found)
|
|
hddmenu->addItem(new CMenuForwarder(LOCALE_HDD_NOT_FOUND, false));
|
|
|
|
ret = hddmenu->exec(NULL, "");
|
|
for(int i = 0; i < n;i++) {
|
|
if( hdd_found && tempMenu[i] != NULL ){
|
|
delete tempMenu[i];
|
|
}
|
|
}
|
|
|
|
delete hddmenu;
|
|
return ret;
|
|
}
|
|
|
|
int CHDDDestExec::exec(CMenuTarget* /*parent*/, const std::string&)
|
|
{
|
|
char cmd[100];
|
|
struct dirent **namelist;
|
|
int n = scandir("/sys/block", &namelist, my_filter, alphasort);
|
|
|
|
if (n < 0)
|
|
return 0;
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
printf("CHDDDestExec: noise %d sleep %d /dev/%s\n",
|
|
g_settings.hdd_noise, g_settings.hdd_sleep, namelist[i]->d_name);
|
|
//hdparm -M is not included in busybox hdparm!
|
|
//we need full version of hdparm or should remove -M parameter here
|
|
snprintf(cmd, sizeof(cmd), "hdparm -M%d -S%d /dev/%s >/dev/null 2>/dev/null &",
|
|
g_settings.hdd_noise, g_settings.hdd_sleep, namelist[i]->d_name);
|
|
system(cmd);
|
|
free(namelist[i]);
|
|
}
|
|
free(namelist);
|
|
return 1;
|
|
}
|
|
|
|
static int check_and_umount(char * dev, char * path)
|
|
{
|
|
char buffer[255];
|
|
FILE *f = fopen("/proc/mounts", "r");
|
|
if(f == NULL)
|
|
return -1;
|
|
while (fgets (buffer, 255, f) != NULL) {
|
|
if(strstr(buffer, dev)) {
|
|
printf("HDD: %s mounted\n", path);
|
|
fclose(f);
|
|
return umount(path);
|
|
}
|
|
}
|
|
fclose(f);
|
|
printf("HDD: %s not mounted\n", path);
|
|
return 0;
|
|
}
|
|
|
|
int CHDDFmtExec::exec(CMenuTarget* /*parent*/, const std::string& key)
|
|
{
|
|
char cmd[100];
|
|
char cmd2[100];
|
|
CHintBox * hintbox;
|
|
int res;
|
|
FILE * f;
|
|
char src[128], dst[128];
|
|
CProgressWindow * progress;
|
|
|
|
snprintf(src, sizeof(src), "/dev/%s1", key.c_str());
|
|
snprintf(dst, sizeof(dst), "/media/%s1", key.c_str());
|
|
|
|
printf("CHDDFmtExec: key %s\n", key.c_str());
|
|
|
|
res = ShowMsgUTF ( LOCALE_HDD_FORMAT, g_Locale->getText(LOCALE_HDD_FORMAT_WARN), CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo );
|
|
if(res != CMessageBox::mbrYes)
|
|
return 0;
|
|
|
|
bool srun = system("killall -9 smbd");
|
|
|
|
//res = check_and_umount(dst);
|
|
res = check_and_umount(src, dst);
|
|
printf("CHDDFmtExec: umount res %d\n", res);
|
|
|
|
if(res) {
|
|
hintbox = new CHintBox(LOCALE_HDD_FORMAT, g_Locale->getText(LOCALE_HDD_UMOUNT_WARN));
|
|
hintbox->paint();
|
|
sleep(2);
|
|
delete hintbox;
|
|
goto _return;
|
|
}
|
|
|
|
f = fopen("/proc/sys/kernel/hotplug", "w");
|
|
if(f) {
|
|
fprintf(f, "none\n");
|
|
fclose(f);
|
|
}
|
|
|
|
progress = new CProgressWindow();
|
|
progress->setTitle(LOCALE_HDD_FORMAT);
|
|
progress->exec(NULL,"");
|
|
progress->showStatusMessageUTF("Executing fdisk");
|
|
progress->showGlobalStatus(0);
|
|
|
|
if (access("/sbin/sfdisk", X_OK) == 0) {
|
|
snprintf(cmd, sizeof(cmd), "/sbin/sfdisk -f -uM /dev/%s", key.c_str());
|
|
strcpy(cmd2, "0,\n;\n;\n;\ny\n");
|
|
} else {
|
|
snprintf(cmd, sizeof(cmd), "/sbin/fdisk /dev/%s", key.c_str());
|
|
strcpy(cmd2, "o\nn\np\n1\n\n\nw\n");
|
|
}
|
|
|
|
printf("CHDDFmtExec: executing %s\n", cmd);
|
|
f=popen(cmd, "w");
|
|
if (!f) {
|
|
hintbox = new CHintBox(LOCALE_HDD_FORMAT, g_Locale->getText(LOCALE_HDD_FORMAT_FAILED));
|
|
hintbox->paint();
|
|
sleep(2);
|
|
delete hintbox;
|
|
goto _remount;
|
|
}
|
|
|
|
fprintf(f, "%s", cmd2);
|
|
pclose(f);
|
|
//sleep(1);
|
|
|
|
switch(g_settings.hdd_fs) {
|
|
case 0:
|
|
snprintf(cmd, sizeof(cmd), "/sbin/mkfs.ext3 -T largefile -m0 %s", src);
|
|
break;
|
|
case 1:
|
|
snprintf(cmd, sizeof(cmd), "/sbin/mkreiserfs -f -f %s", src);
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
printf("CHDDFmtExec: executing %s\n", cmd);
|
|
|
|
f=popen(cmd, "r");
|
|
if (!f) {
|
|
hintbox = new CHintBox(LOCALE_HDD_FORMAT, g_Locale->getText(LOCALE_HDD_FORMAT_FAILED));
|
|
hintbox->paint();
|
|
sleep(2);
|
|
delete hintbox;
|
|
goto _remount;
|
|
}
|
|
|
|
char buf[256];
|
|
setbuf(f, NULL);
|
|
int n, t, in, pos, stage;
|
|
pos = 0;
|
|
stage = 0;
|
|
while (true)
|
|
{
|
|
in = fgetc(f);
|
|
if (in == EOF)
|
|
break;
|
|
|
|
buf[pos] = (char)in;
|
|
pos++;
|
|
buf[pos] = 0;
|
|
if (in == '\b' || in == '\n')
|
|
pos = 0; /* start a new line */
|
|
//printf("%s", buf);
|
|
switch (stage) {
|
|
case 0:
|
|
if (strcmp(buf, "Writing inode tables:") == 0) {
|
|
stage++;
|
|
progress->showGlobalStatus(20);
|
|
progress->showStatusMessageUTF(buf);
|
|
}
|
|
break;
|
|
case 1:
|
|
if (in == '\b' && sscanf(buf, "%d/%d\b", &n, &t) == 2) {
|
|
int percent = 100 * n / t;
|
|
progress->showLocalStatus(percent);
|
|
progress->showGlobalStatus(20 + percent / 5);
|
|
}
|
|
if (strstr(buf, "done")) {
|
|
stage++;
|
|
pos = 0;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (strstr(buf, "blocks):") && sscanf(buf, "Creating journal (%d blocks):", &n) == 1) {
|
|
progress->showLocalStatus(0);
|
|
progress->showGlobalStatus(60);
|
|
progress->showStatusMessageUTF(buf);
|
|
pos = 0;
|
|
}
|
|
if (strstr(buf, "done")) {
|
|
stage++;
|
|
pos = 0;
|
|
}
|
|
break;
|
|
case 3:
|
|
if (strcmp(buf, "Writing superblocks and filesystem accounting information:") == 0) {
|
|
progress->showGlobalStatus(80);
|
|
progress->showStatusMessageUTF(buf);
|
|
pos = 0;
|
|
}
|
|
break;
|
|
default:
|
|
// printf("unknown stage! %d \n\t", stage);
|
|
break;
|
|
}
|
|
}
|
|
progress->showLocalStatus(100);
|
|
pclose(f);
|
|
progress->showGlobalStatus(100);
|
|
sleep(2);
|
|
|
|
snprintf(cmd, sizeof(cmd), "/sbin/tune2fs -r 0 -c 0 -i 0 %s", src);
|
|
printf("CHDDFmtExec: executing %s\n", cmd);
|
|
system(cmd);
|
|
|
|
_remount:
|
|
progress->hide();
|
|
delete progress;
|
|
|
|
switch(g_settings.hdd_fs) {
|
|
case 0:
|
|
res = mount(src, dst, "ext3", 0, NULL);
|
|
break;
|
|
case 1:
|
|
res = mount(src, dst, "reiserfs", 0, NULL);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
f = fopen("/proc/sys/kernel/hotplug", "w");
|
|
if(f) {
|
|
fprintf(f, "/sbin/hotplug\n");
|
|
fclose(f);
|
|
}
|
|
|
|
if(!res) {
|
|
snprintf(cmd, sizeof(cmd), "%s/movies", dst);
|
|
safe_mkdir((char *) cmd);
|
|
snprintf(cmd, sizeof(cmd), "%s/pictures", dst);
|
|
safe_mkdir((char *) cmd);
|
|
snprintf(cmd, sizeof(cmd), "%s/epg", dst);
|
|
safe_mkdir((char *) cmd);
|
|
snprintf(cmd, sizeof(cmd), "%s/music", dst);
|
|
safe_mkdir((char *) cmd);
|
|
sync();
|
|
}
|
|
_return:
|
|
if(!srun) system("smbd");
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
|
|
int CHDDChkExec::exec(CMenuTarget* /*parent*/, const std::string& key)
|
|
{
|
|
char cmd[100];
|
|
CHintBox * hintbox;
|
|
int res;
|
|
char src[128], dst[128];
|
|
FILE * f;
|
|
CProgressWindow * progress;
|
|
int oldpass = 0, pass, step, total;
|
|
int percent = 0, opercent = 0;
|
|
|
|
snprintf(src, sizeof(src), "/dev/%s1", key.c_str());
|
|
snprintf(dst, sizeof(dst), "/media/%s1", key.c_str());
|
|
|
|
printf("CHDDChkExec: key %s\n", key.c_str());
|
|
|
|
bool srun = system("killall -9 smbd");
|
|
|
|
//res = check_and_umount(dst);
|
|
res = check_and_umount(src, dst);
|
|
printf("CHDDChkExec: umount res %d\n", res);
|
|
if(res) {
|
|
hintbox = new CHintBox(LOCALE_HDD_CHECK, g_Locale->getText(LOCALE_HDD_UMOUNT_WARN));
|
|
hintbox->paint();
|
|
sleep(2);
|
|
delete hintbox;
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
|
|
switch(g_settings.hdd_fs) {
|
|
case 0:
|
|
snprintf(cmd, sizeof(cmd), "/sbin/fsck.ext3 -C 1 -f -y %s", src);
|
|
break;
|
|
case 1:
|
|
snprintf(cmd, sizeof(cmd), "/sbin/reiserfsck --fix-fixable %s", src);
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
printf("CHDDChkExec: Executing %s\n", cmd);
|
|
f=popen(cmd, "r");
|
|
if(!f) {
|
|
hintbox = new CHintBox(LOCALE_HDD_CHECK, g_Locale->getText(LOCALE_HDD_CHECK_FAILED));
|
|
hintbox->paint();
|
|
sleep(2);
|
|
delete hintbox;
|
|
goto ret1;
|
|
}
|
|
|
|
progress = new CProgressWindow();
|
|
progress->setTitle(LOCALE_HDD_CHECK);
|
|
progress->exec(NULL,"");
|
|
|
|
char buf[256];
|
|
while(fgets(buf, 255, f) != NULL)
|
|
{
|
|
if(isdigit(buf[0])) {
|
|
sscanf(buf, "%d %d %d\n", &pass, &step, &total);
|
|
if(total == 0)
|
|
total = 1;
|
|
if(oldpass != pass) {
|
|
oldpass = pass;
|
|
progress->showGlobalStatus(pass > 0 ? (pass-1)*20: 0);
|
|
}
|
|
percent = (step * 100) / total;
|
|
if(opercent != percent) {
|
|
opercent = percent;
|
|
//printf("CHDDChkExec: pass %d : %d\n", pass, percent);
|
|
progress->showLocalStatus(percent);
|
|
}
|
|
}
|
|
else if(!strncmp(buf, "Pass", 4)) {
|
|
char *t = strrchr(buf, '\n');
|
|
if (t)
|
|
*t = 0;
|
|
progress->showStatusMessageUTF(buf);
|
|
}
|
|
}
|
|
//printf("CHDDChkExec: %s\n", buf);
|
|
pclose(f);
|
|
progress->showGlobalStatus(100);
|
|
progress->showStatusMessageUTF(buf);
|
|
sleep(2);
|
|
progress->hide();
|
|
delete progress;
|
|
|
|
ret1:
|
|
switch(g_settings.hdd_fs) {
|
|
case 0:
|
|
res = mount(src, dst, "ext3", 0, NULL);
|
|
break;
|
|
case 1:
|
|
res = mount(src, dst, "reiserfs", 0, NULL);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
printf("CHDDChkExec: mount res %d\n", res);
|
|
|
|
if(!srun) system("smbd");
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|