mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-27 07:23:09 +02:00
It should be more sensefull to set release cycle inside environment than hard coding inside neutrino code. Neutrino package version is not the same like image release cycle, therefore here it is separated from package info.
1310 lines
40 KiB
C++
1310 lines
40 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., 51 Franklin St, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <gui/update.h>
|
|
#include <gui/update_ext.h>
|
|
|
|
#include <global.h>
|
|
#include <neutrino.h>
|
|
#include <neutrino_menue.h>
|
|
#include <mymenu.h>
|
|
|
|
#include <driver/fontrenderer.h>
|
|
#include <driver/rcinput.h>
|
|
#include <driver/screen_max.h>
|
|
|
|
#include <gui/color.h>
|
|
#include <gui/filebrowser.h>
|
|
#include <gui/opkg_manager.h>
|
|
#include <gui/widget/msgbox.h>
|
|
#include <gui/widget/hintbox.h>
|
|
|
|
#include <system/flashtool.h>
|
|
#include <system/httptool.h>
|
|
#include <system/helpers.h>
|
|
#include <system/debug.h>
|
|
|
|
#include <lib/libnet/libnet.h>
|
|
|
|
#define SQUASHFS
|
|
|
|
#include <curl/curl.h>
|
|
#include <curl/easy.h>
|
|
|
|
#if LIBCURL_VERSION_NUM < 0x071507
|
|
#include <curl/types.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/ioctl.h>
|
|
#include <dirent.h>
|
|
|
|
#include <fstream>
|
|
|
|
#include <cs_api.h>
|
|
|
|
extern int allow_flash;
|
|
|
|
//#define DRYRUN
|
|
|
|
//#define gTmpPath "/var/update/"
|
|
#define gTmpPath "/tmp/"
|
|
#define gUserAgent "neutrino/softupdater 1.0"
|
|
|
|
#define LIST_OF_UPDATES_LOCAL_FILENAME "coolstream.list"
|
|
#define UPDATE_LOCAL_FILENAME "update.img"
|
|
#define FILEBROWSER_UPDATE_FILTER "img"
|
|
|
|
#define MTD_OF_WHOLE_IMAGE 0
|
|
#ifdef BOXMODEL_CS_HD2
|
|
#define MTD_DEVICE_OF_UPDATE_PART "/dev/mtd0"
|
|
#else
|
|
#define MTD_DEVICE_OF_UPDATE_PART "/dev/mtd3"
|
|
#endif
|
|
int pinghost (const std::string &hostname, std::string *ip = NULL);
|
|
|
|
CFlashUpdate::CFlashUpdate()
|
|
:CProgressWindow()
|
|
{
|
|
width = 40;
|
|
setTitle(LOCALE_FLASHUPDATE_HEAD);
|
|
sysfs = CMTDInfo::getInstance()->findMTDsystem();
|
|
if (sysfs.empty())
|
|
sysfs = MTD_DEVICE_OF_UPDATE_PART;
|
|
printf("Mtd partition to update: %s\n", sysfs.c_str());
|
|
notify = true;
|
|
}
|
|
|
|
|
|
|
|
class CUpdateMenuTarget : public CMenuTarget
|
|
{
|
|
int myID;
|
|
int * myselectedID;
|
|
|
|
public:
|
|
CUpdateMenuTarget(const int id, int * const selectedID)
|
|
{
|
|
myID = id;
|
|
myselectedID = selectedID;
|
|
}
|
|
|
|
virtual int exec(CMenuTarget *, const std::string &)
|
|
{
|
|
*myselectedID = myID;
|
|
return menu_return::RETURN_EXIT_ALL;
|
|
}
|
|
};
|
|
|
|
bool CFlashUpdate::checkOnlineVersion()
|
|
{
|
|
CHTTPTool httpTool;
|
|
std::string url;
|
|
std::string name;
|
|
std::string version;
|
|
std::string md5;
|
|
std::vector<std::string> updates_lists, urls, names, versions, descriptions, md5s;
|
|
int curVer, newVer;
|
|
bool newfound = false;
|
|
|
|
std::vector<CUpdateMenuTarget*> update_t_list;
|
|
|
|
CConfigFile _configfile('\t');
|
|
const char * versionString = (_configfile.loadConfig( "/.version")) ? (_configfile.getString( "version", "????????????????").c_str()) : "????????????????";
|
|
#ifdef DEBUG
|
|
printf("[update] file %s\n", g_settings.softupdate_url_file.c_str());
|
|
#endif
|
|
CFlashVersionInfo curInfo(versionString);
|
|
curVer = curInfo.getVersion();
|
|
printf("current flash-version: %s (%d) date %s (%ld)\n", versionString, curInfo.getVersion(), curInfo.getDate(), curInfo.getDateTime());
|
|
|
|
std::ifstream urlFile(g_settings.softupdate_url_file.c_str());
|
|
if (urlFile >> url) {
|
|
/* extract domain name */
|
|
std::string::size_type startpos, endpos;
|
|
std::string host;
|
|
startpos = url.find("//");
|
|
if (startpos != std::string::npos) {
|
|
startpos += 2;
|
|
endpos = url.find('/', startpos);
|
|
host = url.substr(startpos, endpos - startpos);
|
|
}
|
|
printf("[update] host %s\n", host.c_str());
|
|
if (host.empty() || (pinghost(host) != 1))
|
|
return false;
|
|
if (httpTool.downloadFile(url, gTmpPath LIST_OF_UPDATES_LOCAL_FILENAME, 20)) {
|
|
std::ifstream in(gTmpPath LIST_OF_UPDATES_LOCAL_FILENAME);
|
|
while (in >> url >> version >> md5 >> std::ws) {
|
|
std::getline(in, name);
|
|
CFlashVersionInfo versionInfo(version);
|
|
newVer = versionInfo.getVersion();
|
|
#ifdef DEBUG
|
|
printf("[update] url %s version %s (%d) timestamp %s (%ld) md5 %s name %s\n", url.c_str(), version.c_str(), newVer, versionInfo.getDate(), versionInfo.getDateTime(), md5.c_str(), name.c_str());
|
|
#endif
|
|
if(versionInfo.snapshot <= '2' && (newVer > curVer || versionInfo.getDateTime() > curInfo.getDateTime())) {
|
|
newfound = true;
|
|
printf("[update] found new image\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return newfound;
|
|
}
|
|
|
|
//#define DEBUG
|
|
bool CFlashUpdate::selectHttpImage(void)
|
|
{
|
|
CHTTPTool httpTool;
|
|
std::string url;
|
|
std::string name;
|
|
std::string version;
|
|
std::string md5;
|
|
std::vector<std::string> updates_lists, urls, names, versions, descriptions, md5s;
|
|
char fileTypes[128];
|
|
int selected = -1, listWidth = 80;
|
|
int curVer, newVer, newfound = 0;
|
|
|
|
CConfigFile _configfile('\t');
|
|
std::string versionString = "????????????????";
|
|
if (_configfile.loadConfig("/.version"))
|
|
versionString = _configfile.getString("version", "????????????????");
|
|
|
|
CFlashVersionInfo curInfo(versionString.c_str());
|
|
printf("current flash-version: %s (%d) date %s (%ld)\n", versionString.c_str(), curInfo.getVersion(), curInfo.getDate(), curInfo.getDateTime());
|
|
curVer = curInfo.getVersion();
|
|
|
|
httpTool.setStatusViewer(this);
|
|
showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_GETINFOFILE));
|
|
|
|
char current[200];
|
|
snprintf(current, 200, "%s: %s %s %s %s %s", g_Locale->getText(LOCALE_FLASHUPDATE_CURRENTVERSION_SEP), curInfo.getReleaseCycle(),
|
|
g_Locale->getText(LOCALE_FLASHUPDATE_CURRENTVERSIONDATE), curInfo.getDate(),
|
|
g_Locale->getText(LOCALE_FLASHUPDATE_CURRENTVERSIONTIME), curInfo.getTime());
|
|
|
|
CMenuWidget SelectionWidget(LOCALE_FLASHUPDATE_SELECTIMAGE, NEUTRINO_ICON_UPDATE, listWidth, MN_WIDGET_ID_IMAGESELECTOR);
|
|
|
|
SelectionWidget.addItem(GenericMenuSeparator);
|
|
SelectionWidget.addItem(GenericMenuBack);
|
|
SelectionWidget.addItem(new CMenuSeparator(CMenuSeparator::LINE));
|
|
|
|
SelectionWidget.addItem(new CMenuForwarder(current, false));
|
|
std::ifstream urlFile(g_settings.softupdate_url_file.c_str());
|
|
#ifdef DEBUG
|
|
printf("[update] file %s\n", g_settings.softupdate_url_file.c_str());
|
|
#endif
|
|
|
|
unsigned int i = 0;
|
|
while (urlFile >> url)
|
|
{
|
|
std::string::size_type startpos, endpos;
|
|
#ifdef DEBUG
|
|
printf("[update] url %s\n", url.c_str());
|
|
#endif
|
|
|
|
/* extract domain name */
|
|
startpos = url.find("//");
|
|
if (startpos == std::string::npos)
|
|
{
|
|
startpos = 0;
|
|
}
|
|
else
|
|
{
|
|
startpos = url.find('/', startpos+2)+1;
|
|
}
|
|
endpos = std::string::npos;
|
|
updates_lists.push_back(url.substr(startpos, endpos - startpos));
|
|
|
|
SelectionWidget.addItem(new CMenuSeparator(CMenuSeparator::STRING | CMenuSeparator::LINE, updates_lists.rbegin()->c_str()));
|
|
if (httpTool.downloadFile(url, gTmpPath LIST_OF_UPDATES_LOCAL_FILENAME, 20))
|
|
{
|
|
std::ifstream in(gTmpPath LIST_OF_UPDATES_LOCAL_FILENAME);
|
|
bool enabled;
|
|
CMenuForwarder * mf;
|
|
while (in >> url >> version >> md5 >> std::ws)
|
|
{
|
|
urls.push_back(url);
|
|
versions.push_back(version);
|
|
std::getline(in, name);
|
|
names.push_back(name);
|
|
//std::getline(in, md5);
|
|
md5s.push_back(md5);
|
|
enabled = true;
|
|
|
|
CFlashVersionInfo versionInfo(versions[i]);
|
|
newVer = versionInfo.getVersion();
|
|
#ifdef DEBUG
|
|
printf("[update] url %s version %s (%d) timestamp %s (%ld) md5 %s name %s\n", url.c_str(), version.c_str(), newVer, versionInfo.getDate(), versionInfo.getDateTime(), md5.c_str(), name.c_str());
|
|
#endif
|
|
if(versionInfo.snapshot <= '2' && (newVer > curVer || versionInfo.getDateTime() > curInfo.getDateTime()))
|
|
newfound = 1;
|
|
if(!allow_flash && (versionInfo.snapshot <= '2'))
|
|
enabled = false;
|
|
fileTypes[i] = versionInfo.snapshot;
|
|
std::string description = versionInfo.getReleaseCycle();
|
|
description += ' ';
|
|
description += versionInfo.getType();
|
|
description += ' ';
|
|
description += versionInfo.getDate();
|
|
description += ' ';
|
|
description += versionInfo.getTime();
|
|
|
|
descriptions.push_back(description); /* workaround since CMenuForwarder does not store the Option String itself */
|
|
|
|
CUpdateMenuTarget * up = new CUpdateMenuTarget(i, &selected);
|
|
mf = new CMenuDForwarder(descriptions[i].c_str(), enabled, names[i].c_str(), up);
|
|
//TODO mf->setHint(NEUTRINO_ICON_HINT_SW_UPDATE, "");
|
|
SelectionWidget.addItem(mf);
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
hide();
|
|
|
|
if (urls.empty())
|
|
{
|
|
ShowMsg(LOCALE_MESSAGEBOX_ERROR, LOCALE_FLASHUPDATE_GETINFOFILEERROR, CMsgBox::mbrOk, CMsgBox::mbOk);
|
|
return false;
|
|
}
|
|
if (notify) {
|
|
if(newfound)
|
|
ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_NEW_FOUND, CMsgBox::mbrOk, CMsgBox::mbOk, NEUTRINO_ICON_INFO, MSGBOX_MIN_WIDTH, 6 );
|
|
#if 0
|
|
else
|
|
ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_NEW_NOTFOUND, CMsgBox::mbrOk, CMsgBox::mbOk, NEUTRINO_ICON_INFO, MSGBOX_MIN_WIDTH, 6);
|
|
#endif
|
|
}
|
|
|
|
menu_ret = SelectionWidget.exec(NULL, "");
|
|
|
|
if (selected == -1)
|
|
return false;
|
|
|
|
filename = urls[selected];
|
|
newVersion = versions[selected];
|
|
file_md5 = md5s[selected];
|
|
fileType = fileTypes[selected];
|
|
#ifdef BOXMODEL_CS_HD2
|
|
if(fileType <= '2') {
|
|
int esize = CMTDInfo::getInstance()->getMTDEraseSize(sysfs);
|
|
printf("[update] erase size is %x\n", esize);
|
|
if (esize == 0x40000) {
|
|
filename += ".256k";
|
|
}
|
|
}
|
|
#endif
|
|
#if HAVE_ARM_HARDWARE
|
|
if ((fileType <= '2') && (filename.substr(filename.find_last_of(".") + 1) == "tgz"))
|
|
{
|
|
// manipulate fileType for tgz-packages
|
|
fileType = 'Z';
|
|
}
|
|
#endif
|
|
#ifdef DEBUG
|
|
printf("[update] filename %s type %c newVersion %s md5 %s\n", filename.c_str(), fileType, newVersion.c_str(), file_md5.c_str());
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CFlashUpdate::getUpdateImage(const std::string & version)
|
|
{
|
|
CHTTPTool httpTool;
|
|
char const * fname;
|
|
char dest_name[100];
|
|
httpTool.setStatusViewer(this);
|
|
|
|
fname = rindex(filename.c_str(), '/');
|
|
if(fname != NULL) fname++;
|
|
else return false;
|
|
|
|
sprintf(dest_name, "%s/%s", g_settings.update_dir.c_str(), fname);
|
|
showStatusMessageUTF(std::string(g_Locale->getText(LOCALE_FLASHUPDATE_GETUPDATEFILE)) + ' ' + version);
|
|
|
|
printf("get update (url): %s - %s\n", filename.c_str(), dest_name);
|
|
return httpTool.downloadFile(filename, dest_name, 40 );
|
|
}
|
|
|
|
bool CFlashUpdate::checkVersion4Update()
|
|
{
|
|
char msg[400];
|
|
CFlashVersionInfo * versionInfo;
|
|
neutrino_locale_t msg_body;
|
|
#ifdef DEBUG
|
|
printf("[update] mode is %d\n", softupdate_mode);
|
|
#endif
|
|
if(softupdate_mode==1) //internet-update
|
|
{
|
|
if(!selectHttpImage())
|
|
return false;
|
|
|
|
showLocalStatus(100);
|
|
showGlobalStatus(20);
|
|
showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_VERSIONCHECK));
|
|
|
|
printf("internet version: %s\n", newVersion.c_str());
|
|
|
|
showLocalStatus(100);
|
|
showGlobalStatus(20);
|
|
hide();
|
|
|
|
msg_body = LOCALE_FLASHUPDATE_MSGBOX;
|
|
#ifdef SQUASHFS
|
|
versionInfo = new CFlashVersionInfo(newVersion);//Memory leak: versionInfo
|
|
sprintf(msg, g_Locale->getText(msg_body), versionInfo->getDate(), versionInfo->getTime(), versionInfo->getReleaseCycle(), versionInfo->getType());
|
|
|
|
if(fileType <= '2')
|
|
{
|
|
if ((strncmp(RELEASE_CYCLE, versionInfo->getReleaseCycle(), 2) != 0) &&
|
|
(ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_WRONGBASE, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE) != CMsgBox::mbrYes))
|
|
{
|
|
delete versionInfo;
|
|
//ShowHint(LOCALE_MESSAGEBOX_ERROR, LOCALE_FLASHUPDATE_WRONGBASE);
|
|
return false;
|
|
}
|
|
|
|
if ((strcmp("Release", versionInfo->getType()) != 0) &&
|
|
//(ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_EXPERIMENTALIMAGE, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE) != CMsgBox::mbrYes))
|
|
(ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_EXPERIMENTALIMAGE, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE) != CMsgBox::mbrYes))
|
|
{
|
|
delete versionInfo;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
delete versionInfo;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
CFileBrowser UpdatesBrowser;
|
|
|
|
CFileFilter UpdatesFilter;
|
|
if (allow_flash)
|
|
UpdatesFilter.addFilter(FILEBROWSER_UPDATE_FILTER);
|
|
|
|
std::string filters[] = {"bin", "txt", "opk", "ipk"};
|
|
for(size_t i=0; i<sizeof(filters)/sizeof(filters[0]) ;i++)
|
|
UpdatesFilter.addFilter(filters[i]);
|
|
|
|
#if HAVE_ARM_HARDWARE
|
|
UpdatesFilter.addFilter("tgz");
|
|
#endif
|
|
|
|
UpdatesBrowser.Filter = &UpdatesFilter;
|
|
|
|
CFile * file_selected = NULL;
|
|
if (!(UpdatesBrowser.exec(g_settings.update_dir.c_str()))) {
|
|
menu_ret = UpdatesBrowser.getMenuRet();
|
|
return false;
|
|
}
|
|
|
|
file_selected = UpdatesBrowser.getSelectedFile();
|
|
|
|
if (file_selected == NULL)
|
|
return false;
|
|
|
|
filename = file_selected->Name;
|
|
|
|
FILE* fd = fopen(filename.c_str(), "r");
|
|
if(fd)
|
|
fclose(fd);
|
|
else {
|
|
hide();
|
|
printf("flash/package-file not found: %s\n", filename.c_str());
|
|
DisplayErrorMessage(g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENFILE));
|
|
return false;
|
|
}
|
|
hide();
|
|
|
|
//package install:
|
|
if (file_selected->getType() == CFile::FILE_PKG_PACKAGE){
|
|
COPKGManager opkg;
|
|
if (opkg.hasOpkgSupport()){
|
|
int msgres = ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_OPKG_WARNING_3RDPARTY_PACKAGES, CMsgBox::mbrNo, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE, 700);
|
|
if (msgres == CMsgBox::mbrYes){
|
|
if (!opkg.installPackage(UpdatesBrowser.getSelectedFile()->Name))
|
|
DisplayErrorMessage(g_Locale->getText(LOCALE_OPKG_FAILURE_INSTALL));
|
|
}
|
|
}
|
|
else
|
|
DisplayInfoMessage(g_Locale->getText(LOCALE_MESSAGEBOX_FEATURE_NOT_SUPPORTED));
|
|
//!always leave here!
|
|
return false;
|
|
}
|
|
#if HAVE_ARM_HARDWARE
|
|
//tgz package install:
|
|
else if (file_selected->getType() == CFile::FILE_TGZ_PACKAGE){
|
|
fileType = 'Z';
|
|
//!always leave here!
|
|
return true;
|
|
}
|
|
#endif
|
|
//set internal filetype
|
|
char const * ptr = rindex(filename.c_str(), '.');
|
|
if(ptr) {
|
|
ptr++;
|
|
if(!strcmp(ptr, "bin"))
|
|
fileType = 'A';
|
|
else if(!strcmp(ptr, "txt"))
|
|
fileType = 'T';
|
|
else if(!allow_flash)
|
|
return false;
|
|
else
|
|
fileType = 0;
|
|
#ifdef DEBUG
|
|
printf("[update] manual file type: %s %c\n", ptr, fileType);
|
|
#endif
|
|
}
|
|
|
|
strcpy(msg, g_Locale->getText(LOCALE_FLASHUPDATE_NOVERSION));
|
|
}
|
|
return (ShowMsg(LOCALE_MESSAGEBOX_INFO, msg, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE) == CMsgBox::mbrYes);
|
|
}
|
|
|
|
int CFlashUpdate::exec(CMenuTarget* parent, const std::string &actionKey)
|
|
{
|
|
printf("CFlashUpdate::exec: [%s]\n", actionKey.c_str());
|
|
if (actionKey == "local")
|
|
softupdate_mode = 0;
|
|
else
|
|
softupdate_mode = 1;
|
|
|
|
if(parent)
|
|
parent->hide();
|
|
|
|
menu_ret = menu_return::RETURN_REPAINT;
|
|
paint();
|
|
|
|
if(sysfs.size() < 8) {
|
|
ShowHint(LOCALE_MESSAGEBOX_ERROR, LOCALE_FLASHUPDATE_CANTOPENMTD);
|
|
hide();
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
if(!checkVersion4Update()) {
|
|
hide();
|
|
return menu_ret;
|
|
}
|
|
|
|
#ifdef VFD_UPDATE
|
|
CVFD::getInstance()->showProgressBar2(0,"checking",0,"Update Neutrino");
|
|
CVFD::getInstance()->setMode(CLCD::MODE_PROGRESSBAR2);
|
|
#endif // VFD_UPDATE
|
|
|
|
|
|
paint();
|
|
showGlobalStatus(20);
|
|
|
|
if(softupdate_mode==1) //internet-update
|
|
{
|
|
char const * fname = rindex(filename.c_str(), '/') +1;
|
|
char fullname[255];
|
|
|
|
if(!getUpdateImage(newVersion)) {
|
|
hide();
|
|
ShowHint(LOCALE_MESSAGEBOX_ERROR, LOCALE_FLASHUPDATE_GETUPDATEFILEERROR);
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
sprintf(fullname, "%s/%s", g_settings.update_dir.c_str(), fname);
|
|
filename = std::string(fullname);
|
|
}
|
|
|
|
showGlobalStatus(40);
|
|
|
|
CFlashTool ft;
|
|
ft.setMTDDevice(sysfs);
|
|
ft.setStatusViewer(this);
|
|
|
|
showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_MD5CHECK));
|
|
if((softupdate_mode==1) && !ft.check_md5(filename, file_md5)) {
|
|
hide();
|
|
ShowHint(LOCALE_MESSAGEBOX_ERROR, LOCALE_FLASHUPDATE_MD5SUMERROR);
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
if(softupdate_mode==1) { //internet-update
|
|
if ( ShowMsg(LOCALE_MESSAGEBOX_INFO, (fileType <= '2') ? LOCALE_FLASHUPDATE_INSTALL_IMAGE : LOCALE_FLASHUPDATE_INSTALL_PACKAGE, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE) != CMsgBox::mbrYes)
|
|
{
|
|
hide();
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
}
|
|
|
|
showGlobalStatus(60);
|
|
|
|
#ifdef DEBUG
|
|
printf("[update] flash/install filename %s type %c\n", filename.c_str(), fileType);
|
|
#endif
|
|
if(fileType <= '2') {
|
|
//flash it...
|
|
#if ENABLE_EXTUPDATE
|
|
#ifndef BOXMODEL_CS_HD2
|
|
if (g_settings.apply_settings) {
|
|
if (ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_APPLY_SETTINGS, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE) == CMsgBox::mbrYes)
|
|
if (!CExtUpdate::getInstance()->applySettings(filename, CExtUpdate::MODE_SOFTUPDATE)) {
|
|
hide();
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef DRYRUN
|
|
if(1) {
|
|
#else
|
|
if(!ft.program(filename, 80, 100)) {
|
|
#endif
|
|
hide();
|
|
ShowHint(LOCALE_MESSAGEBOX_ERROR, ft.getErrorMessage().c_str());
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
|
|
//status anzeigen
|
|
showGlobalStatus(100);
|
|
showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_READY));
|
|
hide();
|
|
ShowHint(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_FLASHREADYREBOOT);
|
|
sleep(2);
|
|
ft.reboot();
|
|
}
|
|
else if(fileType == 'T') // display file contents
|
|
{
|
|
FILE* fd = fopen(filename.c_str(), "r");
|
|
if(fd) {
|
|
char * buffer;
|
|
off_t filesize = lseek(fileno(fd), 0, SEEK_END);
|
|
lseek(fileno(fd), 0, SEEK_SET);
|
|
buffer =(char *) malloc((uint32_t)filesize+1);
|
|
fread(buffer, (uint32_t)filesize, 1, fd);
|
|
fclose(fd);
|
|
buffer[filesize] = 0;
|
|
ShowMsg(LOCALE_MESSAGEBOX_INFO, buffer, CMsgBox::mbrBack, CMsgBox::mbBack);
|
|
free(buffer);
|
|
}
|
|
}
|
|
#if HAVE_ARM_HARDWARE
|
|
else if (fileType == 'Z')
|
|
{
|
|
showGlobalStatus(100);
|
|
|
|
// create settings package
|
|
int copy_settings = ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_COPY_SETTINGS, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE);
|
|
if (copy_settings == CMsgBox::mbrYes)
|
|
{
|
|
CHintBox hintBox(LOCALE_MESSAGEBOX_INFO, LOCALE_SETTINGS_BACKUP);
|
|
hintBox.paint();
|
|
/*
|
|
Settings tarball is created in /tmp directory.
|
|
ofgwrite will copy this tarball to new rootfs.
|
|
It's untared at first start of new image.
|
|
*/
|
|
my_system(3, "/bin/backup.sh", "/tmp", "backup_flash.tar.gz");
|
|
hintBox.hide();
|
|
}
|
|
|
|
// get active partition
|
|
char c[2] = {0};
|
|
FILE *f;
|
|
f = fopen("/sys/firmware/devicetree/base/chosen/kerneldev", "r");
|
|
if (f)
|
|
{
|
|
if (fseek(f, -2, SEEK_END) == 0)
|
|
{
|
|
c[0] = fgetc(f);
|
|
printf("[update] Current partition: %s\n", c);
|
|
}
|
|
fclose(f);
|
|
}
|
|
|
|
// select partition
|
|
int selected = 0;
|
|
CMenuSelectorTarget *selector = new CMenuSelectorTarget(&selected);
|
|
|
|
CMenuWidget m(LOCALE_FLASHUPDATE_CHOOSE_PARTITION, NEUTRINO_ICON_SETTINGS);
|
|
m.addItem(GenericMenuSeparator);
|
|
CMenuForwarder *mf;
|
|
|
|
for (int i = 1; i < 4+1; i++)
|
|
{
|
|
bool active = !strcmp(c, to_string(i).c_str());
|
|
std::string m_title = "Partition " + to_string(i);
|
|
mf = new CMenuForwarder(m_title, true, NULL, selector, to_string(i).c_str(), CRCInput::convertDigitToKey(i));
|
|
mf->iconName_Info_right = active ? NEUTRINO_ICON_CHECKMARK : NULL;
|
|
m.addItem(mf, active);
|
|
}
|
|
|
|
m.enableSaveScreen(true);
|
|
m.exec(NULL, "");
|
|
|
|
delete selector;
|
|
|
|
printf("[update] Flash into partition %d\n", selected);
|
|
|
|
int restart = CMsgBox::mbNo;
|
|
|
|
std::string ofgwrite_options("");
|
|
if (selected > 0 && strcmp(c, to_string(selected).c_str()))
|
|
{
|
|
// align ofgwrite options
|
|
ofgwrite_options = "-m" + to_string(selected);
|
|
printf("[update] ofgwrite_options: %s\n", ofgwrite_options.c_str());
|
|
|
|
// start selected partition?
|
|
restart = ShowMsg(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_START_SELECTED_PARTITION, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE);
|
|
if (restart == CMsgBox::mbrYes)
|
|
{
|
|
std::string startup_new = "/boot/STARTUP_" + to_string(selected);
|
|
printf("[update] Start selected partition %d (%s)\n", selected, startup_new.c_str());
|
|
#ifndef DRYRUN
|
|
CFileHelpers fh;
|
|
fh.copyFile(startup_new.c_str(), "/boot/STARTUP");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
ShowHint(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_START_OFGWRITE);
|
|
hide();
|
|
|
|
const char ofgwrite_tgz[] = "/bin/ofgwrite_tgz";
|
|
printf("[update] calling %s %s %s %s\n", ofgwrite_tgz, g_settings.update_dir.c_str(), filename.c_str(), ofgwrite_options.c_str());
|
|
#ifndef DRYRUN
|
|
my_system(4, ofgwrite_tgz, g_settings.update_dir.c_str(), filename.c_str(), ofgwrite_options.c_str());
|
|
|
|
/*
|
|
TODO: fix osd-flickering
|
|
Neutrino is clearing framebuffer, so ofgwrite's gui is cleared too.
|
|
*/
|
|
|
|
if (restart == CMsgBox::mbrYes)
|
|
CNeutrinoApp::getInstance()->exec(NULL, "reboot");
|
|
#endif
|
|
return menu_return::RETURN_EXIT_ALL;
|
|
}
|
|
#endif
|
|
else // not image, install
|
|
{
|
|
const char install_sh[] = "/bin/install.sh";
|
|
printf("[update] calling %s %s %s\n",install_sh, g_settings.update_dir.c_str(), filename.c_str() );
|
|
#ifndef DRYRUN
|
|
my_system(3, install_sh, g_settings.update_dir.c_str(), filename.c_str());
|
|
#endif
|
|
showGlobalStatus(100);
|
|
ShowHint(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_READY);
|
|
}
|
|
hide();
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
|
|
CFlashExpert::CFlashExpert()
|
|
:CProgressWindow()
|
|
{
|
|
selectedMTD = -1;
|
|
width = 40;
|
|
#ifdef BOXMODEL_CS_HD2
|
|
forceOtherFilename = false;
|
|
otherFilename = "";
|
|
createimage_other = 0;
|
|
#endif
|
|
}
|
|
|
|
CFlashExpert* CFlashExpert::getInstance()
|
|
{
|
|
static CFlashExpert* FlashExpert = NULL;
|
|
if(!FlashExpert)
|
|
FlashExpert = new CFlashExpert();
|
|
return FlashExpert;
|
|
}
|
|
|
|
bool CFlashExpert::checkSize(int mtd, std::string &backupFile)
|
|
{
|
|
#ifndef BOXMODEL_CS_HD2
|
|
if (mtd < 0) return false;
|
|
#endif
|
|
char errMsg[1024] = {0};
|
|
std::string path = getPathName(backupFile);
|
|
if (!file_exists(path.c_str())) {
|
|
snprintf(errMsg, sizeof(errMsg)-1, g_Locale->getText(LOCALE_FLASHUPDATE_READ_DIRECTORY_NOT_EXIST), path.c_str());
|
|
ShowHint(LOCALE_MESSAGEBOX_ERROR, errMsg);
|
|
return false;
|
|
}
|
|
|
|
uint64_t btotal = 0, bused = 0;
|
|
long bsize = 0;
|
|
uint64_t backupRequiredSize = 0;
|
|
#ifdef BOXMODEL_CS_HD2
|
|
if (mtd == -1) { // check disk space for image creation
|
|
if (!get_fs_usage("/", btotal, bused, &bsize)) {
|
|
snprintf(errMsg, sizeof(errMsg)-1, g_Locale->getText(LOCALE_FLASHUPDATE_READ_VOLUME_ERROR), "root0");
|
|
ShowHint(LOCALE_MESSAGEBOX_ERROR, errMsg);
|
|
return false;
|
|
}
|
|
backupRequiredSize = ((bused * bsize) / 1024ULL) * 2ULL; // twice disk space for summarized image
|
|
dprintf(DEBUG_INFO, "##### [%s] backupRequiredSize: %" PRIu64 ", btotal: %" PRIu64 ", bused: %" PRIu64 ", bsize: %ld\n",
|
|
__func__, backupRequiredSize, btotal, bused, bsize);
|
|
}
|
|
else
|
|
#endif
|
|
backupRequiredSize = CMTDInfo::getInstance()->getMTDSize(mtd) / 1024ULL;
|
|
|
|
btotal = 0; bused = 0; bsize = 0;
|
|
if (!get_fs_usage(path.c_str(), btotal, bused, &bsize)) {
|
|
snprintf(errMsg, sizeof(errMsg)-1, g_Locale->getText(LOCALE_FLASHUPDATE_READ_VOLUME_ERROR), path.c_str());
|
|
ShowHint(LOCALE_MESSAGEBOX_ERROR, errMsg);
|
|
return false;
|
|
}
|
|
uint64_t backupMaxSize = (btotal - bused) * (uint64_t)bsize;
|
|
uint64_t res = 10; // Reserved 10% of available space
|
|
backupMaxSize = (backupMaxSize - ((backupMaxSize * res) / 100ULL)) / 1024ULL;
|
|
dprintf(DEBUG_INFO, "##### [%s] backupMaxSize: %" PRIu64 ", btotal: %" PRIu64 ", bused: %" PRIu64 ", bsize: %ld\n",
|
|
__func__, backupMaxSize, btotal, bused, bsize);
|
|
|
|
if (backupMaxSize < backupRequiredSize) {
|
|
snprintf(errMsg, sizeof(errMsg)-1, g_Locale->getText(LOCALE_FLASHUPDATE_READ_NO_AVAILABLE_SPACE), path.c_str(), to_string(backupMaxSize).c_str(), to_string(backupRequiredSize).c_str());
|
|
ShowHint(LOCALE_MESSAGEBOX_ERROR, errMsg);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#ifdef BOXMODEL_CS_HD2
|
|
bool CFlashExpert::readDevtableFile(std::string &devtableFile, CMkfsJFFS2::v_devtable_t &v_devtable)
|
|
{
|
|
FILE *fd = fopen(devtableFile.c_str(), "r");
|
|
if (!fd) return false;
|
|
char lineRead[1024];
|
|
memset(lineRead, 0, sizeof(lineRead));
|
|
bool status = false;
|
|
while (fgets(lineRead, sizeof(lineRead)-1, fd)) {
|
|
std::string line = lineRead;
|
|
line = trim(line);
|
|
// ignore comments
|
|
if (line.find_first_of("#") == 0) {
|
|
continue;
|
|
}
|
|
// ignore comments after the entry
|
|
size_t pos = line.find_first_of("#");
|
|
if (pos != std::string::npos) {
|
|
line = line.substr(0, pos);
|
|
line = trim(line);
|
|
}
|
|
// minimal entry: "/dev/x x 0000"
|
|
// length = 13
|
|
if (line.length() > 12) {
|
|
v_devtable.push_back(line);
|
|
status = true;
|
|
}
|
|
memset(lineRead, 0, sizeof(lineRead));
|
|
}
|
|
fclose(fd);
|
|
if (!status) return false;
|
|
return true;
|
|
}
|
|
|
|
void CFlashExpert::readmtdJFFS2(std::string &filename, std::string title/*=""*/, std::string path/*="/"*/, bool makeDevTable/*=true*/)
|
|
{
|
|
if (!checkSize(-1, filename))
|
|
return;
|
|
CProgressWindow progress;
|
|
if (title == "")
|
|
progress.setTitle(LOCALE_FLASHUPDATE_TITLEREADFLASH);
|
|
else
|
|
progress.setTitle(g_Locale->getText(LOCALE_FLASHUPDATE_TITLEREADFLASH) + title);
|
|
progress.paint();
|
|
|
|
int eSize = CMTDInfo::getInstance()->getMTDEraseSize(CMTDInfo::getInstance()->findMTDsystem());
|
|
if (createimage_other == 1) {
|
|
if (eSize == 0x40000) eSize = 0x20000;
|
|
else if (eSize == 0x20000) eSize = 0x40000;
|
|
}
|
|
CMkfsJFFS2 mkfs;
|
|
if (makeDevTable) {
|
|
CMkfsJFFS2::v_devtable_t v_devtable;
|
|
bool devtableFileIO = false;
|
|
std::string devtableFile = (std::string)CONFIGDIR + "/devtable.txt";
|
|
if (file_exists(devtableFile.c_str())) {
|
|
if (readDevtableFile(devtableFile, v_devtable))
|
|
devtableFileIO = true;
|
|
}
|
|
if (!devtableFileIO || v_devtable.empty()) {
|
|
v_devtable.push_back("/dev/console c 0600 0 0 5 1 0 0 0");
|
|
v_devtable.push_back("/dev/null c 0666 0 0 1 3 0 0 0");
|
|
}
|
|
mkfs.makeJffs2Image(path, filename, eSize, 0, 0, __LITTLE_ENDIAN, true, true, &progress, &v_devtable);
|
|
}
|
|
else
|
|
mkfs.makeJffs2Image(path, filename, eSize, 0, 0, __LITTLE_ENDIAN, true, true, &progress);
|
|
|
|
progress.hide();
|
|
|
|
char message[500];
|
|
snprintf(message, sizeof(message)-1, g_Locale->getText(LOCALE_FLASHUPDATE_SAVESUCCESS), filename.c_str());
|
|
ShowHint(LOCALE_MESSAGEBOX_INFO, message);
|
|
}
|
|
#endif
|
|
|
|
void CFlashExpert::readmtd(int preadmtd)
|
|
{
|
|
std::string filename;
|
|
CMTDInfo* mtdInfo = CMTDInfo::getInstance();
|
|
std::string hostName ="";
|
|
netGetHostname(hostName);
|
|
std::string timeStr = getNowTimeStr("_%Y%m%d_%H%M");
|
|
std::string tankStr = "";
|
|
|
|
#if ENABLE_EXTUPDATE
|
|
#ifdef BOXMODEL_CS_HD2
|
|
int eSize = CMTDInfo::getInstance()->getMTDEraseSize(CMTDInfo::getInstance()->findMTDsystem());
|
|
if (preadmtd == 0) {
|
|
if (createimage_other == 0) {
|
|
if (eSize == 0x40000) tankStr = ".256k";
|
|
if (eSize == 0x20000) tankStr = "";
|
|
}
|
|
else if (createimage_other == 1) {
|
|
if (eSize == 0x40000) tankStr = "";
|
|
if (eSize == 0x20000) tankStr = ".256k";
|
|
}
|
|
}
|
|
#endif
|
|
if (g_settings.softupdate_name_mode_backup == CExtUpdate::SOFTUPDATE_NAME_HOSTNAME_TIME)
|
|
filename = (std::string)g_settings.update_dir + "/" + mtdInfo->getMTDName(preadmtd) + timeStr + "_" + hostName + tankStr + ".img";
|
|
else
|
|
#endif
|
|
filename = (std::string)g_settings.update_dir + "/" + mtdInfo->getMTDName(preadmtd) + timeStr + tankStr + ".img";
|
|
|
|
#ifdef BOXMODEL_CS_HD2
|
|
std::string title = " (" + CMTDInfo::getInstance()->getMTDName(preadmtd) + ")";
|
|
std::string mountp = getJFFS2MountPoint(preadmtd);
|
|
if (preadmtd == 0) {
|
|
readmtdJFFS2(filename, title);
|
|
return;
|
|
}
|
|
if (preadmtd == 1) {
|
|
if (mountp != "")
|
|
readmtdJFFS2(filename, title, mountp.c_str(), false);
|
|
return;
|
|
}
|
|
if (preadmtd == 2) {
|
|
if (mountp != "")
|
|
readmtdJFFS2(filename, title, mountp.c_str(), false);
|
|
return;
|
|
}
|
|
#endif
|
|
if (preadmtd == -1) {
|
|
filename = (std::string)g_settings.update_dir + "/flashimage.img"; // US-ASCII (subset of UTF-8 and ISO8859-1)
|
|
preadmtd = MTD_OF_WHOLE_IMAGE;
|
|
}
|
|
|
|
bool skipCheck = false;
|
|
#ifndef BOXMODEL_CS_HD2
|
|
if ((std::string)g_settings.update_dir == "/tmp")
|
|
skipCheck = true;
|
|
#else
|
|
if (forceOtherFilename)
|
|
filename = otherFilename;
|
|
#endif
|
|
if ((!skipCheck) && (!checkSize(preadmtd, filename)))
|
|
return;
|
|
|
|
setTitle(LOCALE_FLASHUPDATE_TITLEREADFLASH);
|
|
paint();
|
|
showGlobalStatus(0);
|
|
showStatusMessageUTF((std::string(g_Locale->getText(LOCALE_FLASHUPDATE_ACTIONREADFLASH)) + " (" + mtdInfo->getMTDName(preadmtd) + ')'));
|
|
CFlashTool ft;
|
|
ft.setStatusViewer( this );
|
|
ft.setMTDDevice(mtdInfo->getMTDFileName(preadmtd));
|
|
|
|
if(!ft.readFromMTD(filename, 100)) {
|
|
showStatusMessageUTF(ft.getErrorMessage());
|
|
sleep(10);
|
|
} else {
|
|
showGlobalStatus(100);
|
|
showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_READY));
|
|
char message[500];
|
|
sprintf(message, g_Locale->getText(LOCALE_FLASHUPDATE_SAVESUCCESS), filename.c_str());
|
|
sleep(1);
|
|
hide();
|
|
#ifdef BOXMODEL_CS_HD2
|
|
if (!forceOtherFilename)
|
|
ShowHint(LOCALE_MESSAGEBOX_INFO, message);
|
|
#else
|
|
ShowHint(LOCALE_MESSAGEBOX_INFO, message);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void CFlashExpert::writemtd(const std::string & filename, int mtdNumber)
|
|
{
|
|
char message[500];
|
|
|
|
snprintf(message, sizeof(message),
|
|
g_Locale->getText(LOCALE_FLASHUPDATE_REALLYFLASHMTD),
|
|
FILESYSTEM_ENCODING_TO_UTF8_STRING(filename).c_str(),
|
|
CMTDInfo::getInstance()->getMTDName(mtdNumber).c_str());
|
|
|
|
if (ShowMsg(LOCALE_MESSAGEBOX_INFO, message, CMsgBox::mbrNo, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE) != CMsgBox::mbrYes)
|
|
return;
|
|
#ifdef VFD_UPDATE
|
|
CVFD::getInstance()->showProgressBar2(0,"checking",0,"Update Neutrino");
|
|
CVFD::getInstance()->setMode(CLCD::MODE_PROGRESSBAR2);
|
|
#endif // VFD_UPDATE
|
|
|
|
setTitle(LOCALE_FLASHUPDATE_TITLEWRITEFLASH);
|
|
paint();
|
|
showGlobalStatus(0);
|
|
CFlashTool ft;
|
|
ft.setStatusViewer( this );
|
|
ft.setMTDDevice( CMTDInfo::getInstance()->getMTDFileName(mtdNumber) );
|
|
if(!ft.program( (std::string)g_settings.update_dir + "/" + filename, 50, 100)) {
|
|
showStatusMessageUTF(ft.getErrorMessage());
|
|
sleep(10);
|
|
} else {
|
|
showGlobalStatus(100);
|
|
showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_READY));
|
|
sleep(2);
|
|
hide();
|
|
ShowHint(LOCALE_MESSAGEBOX_INFO, LOCALE_FLASHUPDATE_FLASHREADYREBOOT);
|
|
ft.reboot();
|
|
}
|
|
}
|
|
|
|
int CFlashExpert::showMTDSelector(const std::string & actionkey)
|
|
{
|
|
int shortcut = 0;
|
|
|
|
mn_widget_id_t widget_id = NO_WIDGET_ID;
|
|
if (actionkey == "readmtd")
|
|
widget_id = MN_WIDGET_ID_MTDREAD_SELECTOR;
|
|
else if (actionkey == "writemtd")
|
|
widget_id = MN_WIDGET_ID_MTDWRITE_SELECTOR;
|
|
|
|
//generate mtd-selector
|
|
CMenuWidget* mtdselector = new CMenuWidget(LOCALE_SERVICEMENU_UPDATE, NEUTRINO_ICON_UPDATE, width, widget_id);
|
|
mtdselector->addIntroItems(LOCALE_FLASHUPDATE_MTDSELECTOR, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL);
|
|
|
|
CMTDInfo* mtdInfo =CMTDInfo::getInstance();
|
|
for(int lx=0;lx<mtdInfo->getMTDCount();lx++) {
|
|
char sActionKey[20];
|
|
bool enabled = true;
|
|
#ifdef BOXMODEL_CS_HD2
|
|
// disable write uboot / uldr / env
|
|
if ((actionkey == "writemtd") && (lx == mtdInfo->findMTDNumberFromName("u-boot") ||
|
|
lx == mtdInfo->findMTDNumberFromName("uldr") ||
|
|
lx == mtdInfo->findMTDNumberFromName("env")))
|
|
enabled = false;
|
|
if (actionkey == "readmtd") {
|
|
// Enabled when file system is mounted
|
|
if (lx == mtdInfo->findMTDNumberFromName("var"))
|
|
enabled = (getJFFS2MountPoint(lx) == "") ? false : true;
|
|
else if (lx == mtdInfo->findMTDNumberFromName("root1"))
|
|
enabled = (getJFFS2MountPoint(lx) == "") ? false : true;
|
|
}
|
|
if (lx == 3)
|
|
mtdselector->addItem(GenericMenuSeparatorLine);
|
|
#else
|
|
// disable write uboot
|
|
if ((actionkey == "writemtd") && (lx == mtdInfo->findMTDNumberFromName("U-Boot")))
|
|
enabled = false;
|
|
#endif
|
|
sprintf(sActionKey, "%s%d", actionkey.c_str(), lx);
|
|
mtdselector->addItem(new CMenuForwarder(mtdInfo->getMTDName(lx).c_str(), enabled, NULL, this, sActionKey, CRCInput::convertDigitToKey(shortcut++)));
|
|
}
|
|
#if ENABLE_EXTUPDATE
|
|
#ifndef BOXMODEL_CS_HD2
|
|
if (actionkey == "writemtd")
|
|
mtdselector->addItem(new CMenuForwarder("systemFS with settings", true, NULL, this, "writemtd10", CRCInput::convertDigitToKey(shortcut++)));
|
|
#endif
|
|
#endif
|
|
int res = mtdselector->exec(NULL,"");
|
|
delete mtdselector;
|
|
return res;
|
|
}
|
|
|
|
int CFlashExpert::showFileSelector(const std::string & actionkey)
|
|
{
|
|
CMenuWidget* fileselector = new CMenuWidget(LOCALE_SERVICEMENU_UPDATE, NEUTRINO_ICON_UPDATE, width, MN_WIDGET_ID_FILESELECTOR);
|
|
fileselector->addIntroItems(LOCALE_FLASHUPDATE_FILESELECTOR, NONEXISTANT_LOCALE, CMenuWidget::BTN_TYPE_CANCEL);
|
|
|
|
struct dirent **namelist;
|
|
int n = scandir(g_settings.update_dir.c_str(), &namelist, 0, alphasort);
|
|
if (n < 0)
|
|
{
|
|
perror("no flashimages available");
|
|
//should be available...
|
|
}
|
|
else
|
|
{
|
|
for(int count=0;count<n;count++)
|
|
{
|
|
std::string filen = namelist[count]->d_name;
|
|
int pos = filen.find(".img");
|
|
if(pos!=-1)
|
|
{
|
|
fileselector->addItem(new CMenuForwarder(filen.c_str(), true, NULL, this, (actionkey + filen).c_str()));
|
|
//TODO make sure filen is UTF-8 encoded
|
|
}
|
|
free(namelist[count]);
|
|
}
|
|
free(namelist);
|
|
}
|
|
int res = fileselector->exec(NULL,"");
|
|
delete fileselector;
|
|
return res;
|
|
}
|
|
|
|
int CFlashExpert::exec(CMenuTarget* parent, const std::string & actionKey)
|
|
{
|
|
int res = menu_return::RETURN_REPAINT;
|
|
if(parent)
|
|
parent->hide();
|
|
|
|
if(actionKey=="readflash") {
|
|
readmtd(-1);
|
|
}
|
|
else if(actionKey=="writeflash") {
|
|
res = showFileSelector("");
|
|
}
|
|
else if(actionKey=="readflashmtd") {
|
|
res = showMTDSelector("readmtd");
|
|
}
|
|
else if(actionKey=="writeflashmtd") {
|
|
res = showMTDSelector("writemtd");
|
|
}
|
|
else {
|
|
int iReadmtd = -1;
|
|
int iWritemtd = -1;
|
|
sscanf(actionKey.c_str(), "readmtd%d", &iReadmtd);
|
|
sscanf(actionKey.c_str(), "writemtd%d", &iWritemtd);
|
|
if(iReadmtd!=-1) {
|
|
readmtd(iReadmtd);
|
|
}
|
|
else if(iWritemtd!=-1) {
|
|
printf("mtd-write\n\n");
|
|
selectedMTD = iWritemtd;
|
|
showFileSelector("");
|
|
} else {
|
|
#if ENABLE_EXTUPDATE
|
|
if(selectedMTD == 10) {
|
|
std::string aK = actionKey;
|
|
CExtUpdate::getInstance()->applySettings(aK, CExtUpdate::MODE_EXPERT);
|
|
}
|
|
else
|
|
#endif
|
|
if (selectedMTD == -1) {
|
|
writemtd(actionKey, MTD_OF_WHOLE_IMAGE);
|
|
} else {
|
|
writemtd(actionKey, selectedMTD);
|
|
selectedMTD=-1;
|
|
}
|
|
}
|
|
res = menu_return::RETURN_REPAINT;
|
|
}
|
|
hide();
|
|
return res;
|
|
}
|
|
|
|
#ifdef BOXMODEL_CS_HD2
|
|
CFlashExpertSetup::CFlashExpertSetup()
|
|
{
|
|
width = 40;
|
|
}
|
|
|
|
void CFlashExpertSetup::readMTDPart(int mtd, const std::string &fileName)
|
|
{
|
|
CFlashExpert *cfe = CFlashExpert::getInstance();
|
|
if (file_exists(fileName.c_str()))
|
|
unlink(fileName.c_str());
|
|
cfe->otherFilename = fileName;
|
|
cfe->readmtd(mtd);
|
|
sync();
|
|
}
|
|
|
|
#define UBOOT_BIN
|
|
//#define SPARE_BIN
|
|
|
|
int CFlashExpertSetup::exec(CMenuTarget* parent, const std::string &actionKey)
|
|
{
|
|
#define UPDATEDIR "/var/update"
|
|
if (parent)
|
|
parent->hide();
|
|
|
|
if (actionKey == "readmtd0") {
|
|
CFlashExpert *cfe = CFlashExpert::getInstance();
|
|
CMTDInfo *mtdInfo = CMTDInfo::getInstance();
|
|
bool skipImage = false;
|
|
if (cfe->createimage_other == 1) {
|
|
char message[512] = {0};
|
|
// create image warning
|
|
const char *box = (mtdInfo->getMTDEraseSize(mtdInfo->findMTDsystem()) == 0x40000) ? "Trinity" : "Tank";
|
|
snprintf(message, sizeof(message)-1, g_Locale->getText(LOCALE_FLASHUPDATE_CREATEIMAGE_WARNING), box, box);
|
|
if (ShowMsg(LOCALE_MESSAGEBOX_INFO, message, CMsgBox::mbrNo, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_UPDATE, 600) != CMsgBox::mbrYes)
|
|
skipImage = true;
|
|
}
|
|
if (!skipImage) {
|
|
std::string uldrName = (std::string)UPDATEDIR + "/uldr.bin";
|
|
cfe->forceOtherFilename = true;
|
|
if (g_settings.flashupdate_createimage_add_uldr == 1)
|
|
readMTDPart(mtdInfo->findMTDNumberFromName("uldr"), uldrName);
|
|
#ifdef UBOOT_BIN
|
|
std::string ubootName = (std::string)UPDATEDIR + "/u-boot.bin";
|
|
if (g_settings.flashupdate_createimage_add_u_boot == 1)
|
|
readMTDPart(mtdInfo->findMTDNumberFromName("u-boot"), ubootName);
|
|
std::string envName = (std::string)UPDATEDIR + "/env.bin";
|
|
if (g_settings.flashupdate_createimage_add_env == 1)
|
|
readMTDPart(mtdInfo->findMTDNumberFromName("env"), envName);
|
|
#endif
|
|
#ifdef SPARE_BIN
|
|
std::string spareName = (std::string)UPDATEDIR + "/spare.bin";
|
|
if (g_settings.flashupdate_createimage_add_spare == 1)
|
|
readMTDPart(mtdInfo->findMTDNumberFromName("spare"), spareName);
|
|
#endif
|
|
std::string kernelName = (std::string)UPDATEDIR + "/vmlinux.ub.gz";
|
|
if (g_settings.flashupdate_createimage_add_kernel == 1)
|
|
readMTDPart(mtdInfo->findMTDNumberFromName("kernel"), kernelName);
|
|
cfe->forceOtherFilename = false;
|
|
cfe->otherFilename = "";
|
|
|
|
if (g_settings.flashupdate_createimage_add_var == 1)
|
|
cfe->readmtd(1);
|
|
|
|
if (g_settings.flashupdate_createimage_add_root1 == 1)
|
|
cfe->readmtd(2);
|
|
|
|
cfe->readmtd(0);
|
|
|
|
if (g_settings.flashupdate_createimage_add_uldr == 1)
|
|
unlink(uldrName.c_str());
|
|
#ifdef UBOOT_BIN
|
|
if (g_settings.flashupdate_createimage_add_u_boot == 1)
|
|
unlink(ubootName.c_str());
|
|
if (g_settings.flashupdate_createimage_add_env == 1)
|
|
unlink(envName.c_str());
|
|
#endif
|
|
#ifdef SPARE_BIN
|
|
if (g_settings.flashupdate_createimage_add_spare == 1)
|
|
unlink(spareName.c_str());
|
|
#endif
|
|
if (g_settings.flashupdate_createimage_add_kernel == 1)
|
|
unlink(kernelName.c_str());
|
|
sync();
|
|
}
|
|
|
|
cfe->createimage_other = 0;
|
|
return menu_return::RETURN_REPAINT;
|
|
}
|
|
return showMenu();
|
|
}
|
|
|
|
int CFlashExpertSetup::showMenu()
|
|
{
|
|
CFlashExpert *cfe = CFlashExpert::getInstance();
|
|
CMenuWidget *rootfsSetup = new CMenuWidget(LOCALE_SERVICEMENU_UPDATE, NEUTRINO_ICON_UPDATE, width, MN_WIDGET_ID_MTDREAD_ROOT0);
|
|
rootfsSetup->addIntroItems(LOCALE_FLASHUPDATE_CREATEIMAGE_MENU);
|
|
|
|
CMenuSeparator *s1 = new CMenuSeparator(CMenuSeparator::LINE | CMenuSeparator::STRING, LOCALE_FLASHUPDATE_CREATEIMAGE_OPTIONS);
|
|
CMenuForwarder *m1 = new CMenuForwarder(LOCALE_FLASHUPDATE_CREATEIMAGE, true, NULL, this, "readmtd0", CRCInput::convertDigitToKey(0));
|
|
bool isMountVar = (getJFFS2MountPoint(1) == "") ? false : true;
|
|
CMenuOptionChooser *m8=NULL;
|
|
if (isMountVar)
|
|
m8 = new CMenuOptionChooser(LOCALE_FLASHUPDATE_CREATEIMAGE_ADD_VAR, &g_settings.flashupdate_createimage_add_var,
|
|
MESSAGEBOX_NO_YES_OPTIONS, MESSAGEBOX_NO_YES_OPTION_COUNT, true);
|
|
|
|
bool isMountRoot1 = (getJFFS2MountPoint(2) == "") ? false : true;
|
|
CMenuOptionChooser *m9=NULL;
|
|
if (isMountRoot1)
|
|
m9 = new CMenuOptionChooser(LOCALE_FLASHUPDATE_CREATEIMAGE_ADD_ROOT1, &g_settings.flashupdate_createimage_add_root1,
|
|
MESSAGEBOX_NO_YES_OPTIONS, MESSAGEBOX_NO_YES_OPTION_COUNT, true);
|
|
|
|
CMenuOptionChooser *m2 = new CMenuOptionChooser(LOCALE_FLASHUPDATE_CREATEIMAGE_ADD_ULDR, &g_settings.flashupdate_createimage_add_uldr,
|
|
MESSAGEBOX_NO_YES_OPTIONS, MESSAGEBOX_NO_YES_OPTION_COUNT, true);
|
|
#ifndef UBOOT_BIN
|
|
g_settings.flashupdate_createimage_add_u_boot = 0;
|
|
g_settings.flashupdate_createimage_add_env = 0;
|
|
#endif
|
|
#ifdef UBOOT_BIN
|
|
CMenuOptionChooser *m3 = new CMenuOptionChooser(LOCALE_FLASHUPDATE_CREATEIMAGE_ADD_U_BOOT, &g_settings.flashupdate_createimage_add_u_boot,
|
|
MESSAGEBOX_NO_YES_OPTIONS, MESSAGEBOX_NO_YES_OPTION_COUNT, true);
|
|
CMenuOptionChooser *m4 = new CMenuOptionChooser(LOCALE_FLASHUPDATE_CREATEIMAGE_ADD_ENV, &g_settings.flashupdate_createimage_add_env,
|
|
MESSAGEBOX_NO_YES_OPTIONS, MESSAGEBOX_NO_YES_OPTION_COUNT, true);
|
|
#endif
|
|
#ifndef SPARE_BIN
|
|
g_settings.flashupdate_createimage_add_spare = 0;
|
|
#endif
|
|
#ifdef SPARE_BIN
|
|
CMenuOptionChooser *m5 = new CMenuOptionChooser(LOCALE_FLASHUPDATE_CREATEIMAGE_ADD_SPARE, &g_settings.flashupdate_createimage_add_spare,
|
|
MESSAGEBOX_NO_YES_OPTIONS, MESSAGEBOX_NO_YES_OPTION_COUNT, true);
|
|
#endif
|
|
CMenuOptionChooser *m6 = new CMenuOptionChooser(LOCALE_FLASHUPDATE_CREATEIMAGE_ADD_KERNEL, &g_settings.flashupdate_createimage_add_kernel,
|
|
MESSAGEBOX_NO_YES_OPTIONS, MESSAGEBOX_NO_YES_OPTION_COUNT, true);
|
|
|
|
rootfsSetup->addItem(m1); // create image
|
|
rootfsSetup->addItem(s1);
|
|
if (isMountVar)
|
|
rootfsSetup->addItem(m8); // include var
|
|
if (isMountRoot1)
|
|
rootfsSetup->addItem(m9); // include root1
|
|
rootfsSetup->addItem(m2); // include uldr
|
|
#ifdef UBOOT_BIN
|
|
rootfsSetup->addItem(m3); // include u-boot
|
|
rootfsSetup->addItem(m4); // include env
|
|
#endif
|
|
#ifdef SPARE_BIN
|
|
rootfsSetup->addItem(m5); // include spare
|
|
#endif
|
|
rootfsSetup->addItem(m6); // include kernel
|
|
|
|
if (cs_get_revision() != 12) { // not kronos
|
|
CMTDInfo *mtdInfo = CMTDInfo::getInstance();
|
|
const char *box = (mtdInfo->getMTDEraseSize(mtdInfo->findMTDsystem()) == 0x40000) ? "Trinity" : "Tank";
|
|
char mText[512] = {0};
|
|
snprintf(mText, sizeof(mText)-1, g_Locale->getText(LOCALE_FLASHUPDATE_CREATEIMAGE_OTHER), box);
|
|
CMenuOptionChooser *m7 = new CMenuOptionChooser(mText, &(cfe->createimage_other), MESSAGEBOX_NO_YES_OPTIONS, MESSAGEBOX_NO_YES_OPTION_COUNT, true);
|
|
|
|
rootfsSetup->addItem(GenericMenuSeparatorLine);
|
|
rootfsSetup->addItem(m7); // create image for other STB
|
|
} else
|
|
cfe->createimage_other = 0;
|
|
|
|
int res = rootfsSetup->exec (NULL, "");
|
|
delete rootfsSetup;
|
|
|
|
cfe->createimage_other = 0;
|
|
return res;
|
|
}
|
|
#endif // BOXMODEL_CS_HD2
|