mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-30 08:51:04 +02:00
"using namespace std" in headers is considered bad practice, so move it
either into the respective cpp files or (for files which have lots of
other std::xxx usage anyway) just write it out explicitly.
Looking at the headers and the affected cpp files, one can actually see
why it is bad practice, as it's spreading very far ;-)
Origin commit data
------------------
Commit: 0d9139054a
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2017-10-01 (Sun, 01 Oct 2017)
747 lines
21 KiB
C++
747 lines
21 KiB
C++
/*
|
|
update with settings - Neutrino-GUI
|
|
|
|
Copyright (C) 2001 Steffen Hehn 'McClean'
|
|
and some other guys
|
|
Homepage: http://dbox.cyberphoria.org/
|
|
|
|
Copyright (C) 2012-2013 M. Liebmann (micha-bbg)
|
|
|
|
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
|
|
Library 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.
|
|
*/
|
|
|
|
//#define UPDATE_DEBUG_TIMER
|
|
//#define UPDATE_DEBUG
|
|
|
|
#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 <gui/widget/msgbox.h>
|
|
#include <gui/widget/hintbox.h>
|
|
#include <system/flashtool.h>
|
|
#include <lib/libnet/libnet.h>
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/mount.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
#include <fnmatch.h>
|
|
#include <fstream>
|
|
#include <sys/utsname.h>
|
|
|
|
CHintBox * hintBox = 0;
|
|
|
|
CExtUpdate::CExtUpdate()
|
|
{
|
|
imgFilename = "";
|
|
mtdRamError = "";
|
|
mtdNumber = -1;
|
|
backupList = CONFIGDIR "/settingsupdate.conf";
|
|
defaultBackup = CONFIGDIR;
|
|
|
|
fUpdate = NULL;
|
|
updateLogBuf[0] = '\0';
|
|
fLogEnabled = 1;
|
|
fLogfile = "/tmp/update.log";
|
|
mountPkt = "/tmp/image_mount";
|
|
FileHelpers = NULL;
|
|
MTDBuf = NULL;
|
|
flashErrorFlag = false;
|
|
bsize = 0;
|
|
total = used = 0;
|
|
free1 = free2 = free3 = 0;
|
|
|
|
copyList.clear();
|
|
blackList.clear();
|
|
deleteList.clear();
|
|
}
|
|
|
|
CExtUpdate::~CExtUpdate()
|
|
{
|
|
if(FileHelpers)
|
|
delete[] FileHelpers;
|
|
if(MTDBuf)
|
|
delete[] MTDBuf;
|
|
copyList.clear();
|
|
blackList.clear();
|
|
deleteList.clear();
|
|
}
|
|
|
|
CExtUpdate* CExtUpdate::getInstance()
|
|
{
|
|
static CExtUpdate* ExtUpdate = NULL;
|
|
if(!ExtUpdate)
|
|
ExtUpdate = new CExtUpdate();
|
|
return ExtUpdate;
|
|
}
|
|
|
|
bool CExtUpdate::ErrorReset(bool modus, const std::string & msg1, const std::string & msg2)
|
|
{
|
|
char buf[1024];
|
|
|
|
if (modus & RESET_UNLOAD) {
|
|
umount(mountPkt.c_str());
|
|
// my_system(2,"rmmod", mtdramDriver.c_str());
|
|
}
|
|
if (modus & CLOSE_FD1)
|
|
close(fd1);
|
|
if (modus & CLOSE_FD2)
|
|
close(fd2);
|
|
if (modus & CLOSE_F1)
|
|
fclose(f1);
|
|
if (modus & DELETE_MTDBUF) {
|
|
if (MTDBuf != NULL)
|
|
delete[] MTDBuf;
|
|
MTDBuf = NULL;
|
|
}
|
|
|
|
if (msg2.empty())
|
|
snprintf(buf, sizeof(buf), "%s\n", msg1.c_str());
|
|
else
|
|
snprintf(buf, sizeof(buf), "%s %s\n", msg1.c_str(), msg2.c_str());
|
|
|
|
if ((!msg1.empty()) || (!msg2.empty())) {
|
|
mtdRamError = buf;
|
|
WRITE_UPDATE_LOG("ERROR: %s", buf);
|
|
printf(mtdRamError.c_str());
|
|
}
|
|
if(hintBox)
|
|
hintBox->hide();
|
|
sync();
|
|
return false;
|
|
}
|
|
|
|
bool CExtUpdate::applySettings(std::string & filename, int mode)
|
|
{
|
|
if(!FileHelpers)
|
|
FileHelpers = new CFileHelpers();
|
|
|
|
if (mode == MODE_EXPERT)
|
|
imgFilename = (std::string)g_settings.update_dir + "/" + FILESYSTEM_ENCODING_TO_UTF8_STRING(filename);
|
|
else
|
|
imgFilename = FILESYSTEM_ENCODING_TO_UTF8_STRING(filename);
|
|
|
|
DBG_TIMER_START()
|
|
|
|
std::string oldFilename = imgFilename;
|
|
std::string hostName ="";
|
|
netGetHostname(hostName);
|
|
std::string orgPath = getPathName(imgFilename);
|
|
std::string orgName = getBaseName(imgFilename);
|
|
orgName = getFileName(orgName);
|
|
std::string orgExt = "." + getFileExt(imgFilename);
|
|
std::string timeStr = getNowTimeStr("_%Y%m%d_%H%M");
|
|
std::string settingsStr = "+settings";
|
|
|
|
if (orgPath != "/tmp") {
|
|
if (g_settings.softupdate_name_mode_apply == CExtUpdate::SOFTUPDATE_NAME_HOSTNAME_TIME)
|
|
imgFilename = orgPath + "/" + hostName + timeStr + settingsStr + orgExt;
|
|
else if (g_settings.softupdate_name_mode_apply == CExtUpdate::SOFTUPDATE_NAME_ORGNAME_TIME)
|
|
imgFilename = orgPath + "/" + orgName + timeStr + settingsStr + orgExt;
|
|
else
|
|
imgFilename = orgPath + "/" + orgName + settingsStr + orgExt;
|
|
FileHelpers->copyFile(oldFilename.c_str(), imgFilename.c_str(), 0644);
|
|
}
|
|
else
|
|
imgFilename = oldFilename;
|
|
filename = imgFilename;
|
|
|
|
bool ret = applySettings();
|
|
DBG_TIMER_STOP("Image editing")
|
|
if (!ret) {
|
|
if ((!mtdRamError.empty()) && (!flashErrorFlag))
|
|
DisplayErrorMessage(mtdRamError.c_str());
|
|
|
|
// error, delete image file
|
|
unlink(imgFilename.c_str());
|
|
}
|
|
else {
|
|
if (mode == MODE_EXPERT) {
|
|
if ((mtdNumber < 3) || (mtdNumber > 4)) {
|
|
const char *err = "invalid mtdNumber\n";
|
|
printf(err);
|
|
DisplayErrorMessage(err);
|
|
WRITE_UPDATE_LOG("ERROR: %s", err);
|
|
return false;
|
|
}
|
|
}
|
|
WRITE_UPDATE_LOG("\n");
|
|
WRITE_UPDATE_LOG("##### Settings taken. #####\n");
|
|
if (mode == MODE_EXPERT)
|
|
CFlashExpert::getInstance()->writemtd(filename, mtdNumber);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool CExtUpdate::isMtdramLoad()
|
|
{
|
|
bool ret = false;
|
|
FILE* f = fopen("/proc/modules", "r");
|
|
if (f) {
|
|
char buf[256] = "";
|
|
while(fgets(buf, sizeof(buf), f) != NULL) {
|
|
if (strstr(buf, "mtdram") != NULL) {
|
|
ret = true;
|
|
break;
|
|
}
|
|
}
|
|
fclose(f);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool CExtUpdate::applySettings()
|
|
{
|
|
if(!hintBox)
|
|
hintBox = new CHintBox(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_PROCESSED));
|
|
hintBox->paint();
|
|
mtdRamError = "";
|
|
std::string osrelease = "";
|
|
mtdramDriver = ""; // driver path
|
|
char buf1[256] = "";
|
|
char buf2[256] = "";
|
|
|
|
CMTDInfo * mtdInfo = CMTDInfo::getInstance();
|
|
std::string mtdFilename = mtdInfo->findMTDsystem(); // /dev/mtdX
|
|
if (mtdFilename.empty())
|
|
return ErrorReset(0, "error system mtd not found");
|
|
|
|
#ifdef BOXMODEL_CS_HD2
|
|
uint64_t mtdSize = 65536*1024; // FIXME hack, mtd size more than free RAM
|
|
#else
|
|
uint64_t mtdSize = mtdInfo->getMTDSize(mtdFilename);
|
|
#endif
|
|
uint64_t mtdEraseSize = mtdInfo->getMTDEraseSize(mtdFilename);
|
|
mtdNumber = mtdInfo->findMTDNumber(mtdFilename);
|
|
|
|
// get osrelease
|
|
struct utsname uts_info;
|
|
if( uname(&uts_info) == 0 ) {
|
|
osrelease = uts_info.release;
|
|
size_t pos = osrelease.find_first_of(" ");
|
|
if (pos != std::string::npos)
|
|
osrelease = osrelease.substr(0, pos);
|
|
}
|
|
else
|
|
return ErrorReset(0, "error no kernel info");
|
|
|
|
// check if mtdram driver is already loaded
|
|
if (!isMtdramLoad()) {
|
|
// check if exist mtdram driver
|
|
snprintf(buf1, sizeof(buf1), "/lib/modules/%s/mtdram.ko", osrelease.c_str());
|
|
mtdramDriver = buf1;
|
|
if ( !file_exists(mtdramDriver.c_str()) )
|
|
return ErrorReset(0, "no mtdram driver available");
|
|
// load mtdram driver
|
|
snprintf(buf1, sizeof(buf1), "total_size=%llu", mtdSize/1024);
|
|
snprintf(buf2, sizeof(buf2), "erase_size=%llu", mtdEraseSize/1024);
|
|
my_system(4, "insmod", mtdramDriver.c_str(), buf1, buf2);
|
|
// check if mtdram driver is now loaded
|
|
if (!isMtdramLoad())
|
|
return ErrorReset(0, "error load mtdram driver");
|
|
}
|
|
else {
|
|
DBG_MSG("mtdram driver is already loaded");
|
|
}
|
|
|
|
// find mtdram device
|
|
std::string mtdRamFilename = "", mtdBlockFileName = "";
|
|
uint64_t mtdRamSize = 0, mtdRamEraseSize = 0;
|
|
int mtdRamNr = 0;
|
|
f1 = fopen("/proc/mtd", "r");
|
|
if(!f1)
|
|
return ErrorReset(RESET_UNLOAD, "cannot read /proc/mtd");
|
|
fgets(buf1, sizeof(buf1), f1);
|
|
while(!feof(f1)) {
|
|
if(fgets(buf1, sizeof(buf1), f1)!=NULL) {
|
|
char dummy[50] = "";
|
|
uint32_t tmp1, tmp2;
|
|
sscanf(buf1, "mtd%1d: %8x %8x \"%48s\"\n", &mtdRamNr, &tmp1, &tmp2, dummy);
|
|
mtdRamSize = (uint64_t)tmp1;
|
|
mtdRamEraseSize = (uint64_t)tmp2;
|
|
if (strstr(buf1, "mtdram test device") != NULL) {
|
|
sprintf(buf1, "/dev/mtd%d", mtdRamNr);
|
|
mtdRamFilename = buf1;
|
|
sprintf(buf1, "/dev/mtdblock%d", mtdRamNr);
|
|
mtdBlockFileName = buf1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
fclose(f1);
|
|
|
|
if (mtdRamFilename.empty())
|
|
return ErrorReset(RESET_UNLOAD, "no mtdram test device found");
|
|
else {
|
|
// check mtdRamSize / mtdRamEraseSize
|
|
if ((mtdRamSize != mtdSize) || (mtdRamEraseSize != mtdEraseSize)) {
|
|
snprintf(buf2, sizeof(buf2), "error MTDSize(%08llx/%08llx) or MTDEraseSize(%08llx/%08llx)\n", mtdSize, mtdRamSize, mtdEraseSize, mtdRamEraseSize);
|
|
return ErrorReset(RESET_UNLOAD, buf2);
|
|
}
|
|
}
|
|
|
|
int MTDBufSize = 0xFFFF;
|
|
MTDBuf = new char[MTDBufSize];
|
|
// copy image to mtdblock
|
|
if (MTDBuf == NULL)
|
|
return ErrorReset(RESET_UNLOAD, "memory allocation error");
|
|
fd1 = open(imgFilename.c_str(), O_RDONLY);
|
|
if (fd1 < 0)
|
|
return ErrorReset(RESET_UNLOAD | DELETE_MTDBUF, "cannot read image file: " + imgFilename);
|
|
uint64_t filesize = (uint64_t)lseek(fd1, 0, SEEK_END);
|
|
lseek(fd1, 0, SEEK_SET);
|
|
if(filesize == 0)
|
|
return ErrorReset(RESET_UNLOAD | CLOSE_FD1 | DELETE_MTDBUF, "image filesize is 0");
|
|
if(filesize > mtdSize)
|
|
return ErrorReset(RESET_UNLOAD | CLOSE_FD1 | DELETE_MTDBUF, "image filesize too large");
|
|
fd2 = -1;
|
|
int tmpCount = 0;
|
|
while (fd2 < 0) {
|
|
fd2 = open(mtdBlockFileName.c_str(), O_WRONLY, 00644);
|
|
tmpCount++;
|
|
if (tmpCount > 3)
|
|
break;
|
|
sleep(1);
|
|
}
|
|
if (fd2 < 0)
|
|
return ErrorReset(RESET_UNLOAD | CLOSE_FD1 | DELETE_MTDBUF, "cannot open mtdBlock");
|
|
uint64_t fsize = filesize;
|
|
uint32_t block;
|
|
while(fsize > 0) {
|
|
block = (uint32_t)fsize;
|
|
if(block > (uint32_t)MTDBufSize)
|
|
block = MTDBufSize;
|
|
read(fd1, MTDBuf, block);
|
|
write(fd2, MTDBuf, block);
|
|
fsize -= block;
|
|
}
|
|
close(fd1);
|
|
close(fd2);
|
|
|
|
FileHelpers->createDir(mountPkt.c_str(), 0755);
|
|
int res = mount(mtdBlockFileName.c_str(), mountPkt.c_str(), "jffs2", 0, NULL);
|
|
if (res)
|
|
return ErrorReset(RESET_UNLOAD | DELETE_MTDBUF, "mount error");
|
|
|
|
if (get_fs_usage(mountPkt.c_str(), total, used, &bsize))
|
|
free1 = (total * bsize) / 1024 - (used * bsize) / 1024;
|
|
|
|
if (!readBackupList(mountPkt)) {
|
|
if (MTDBuf != NULL)
|
|
delete[] MTDBuf;
|
|
MTDBuf = NULL;
|
|
if (flashErrorFlag)
|
|
return false;
|
|
return ErrorReset(0, "error readBackupList");
|
|
}
|
|
|
|
res = umount(mountPkt.c_str());
|
|
if (res)
|
|
return ErrorReset(RESET_UNLOAD | DELETE_MTDBUF, "unmount error");
|
|
|
|
unlink(imgFilename.c_str());
|
|
|
|
// copy mtdblock to image
|
|
if (MTDBuf == NULL)
|
|
return ErrorReset(RESET_UNLOAD, "memory allocation error");
|
|
fd1 = open(mtdBlockFileName.c_str(), O_RDONLY);
|
|
if (fd1 < 0)
|
|
return ErrorReset(RESET_UNLOAD | DELETE_MTDBUF, "cannot read mtdBlock");
|
|
fsize = mtdRamSize;
|
|
fd2 = open(imgFilename.c_str(), O_WRONLY | O_CREAT, 00644);
|
|
if (fd2 < 0)
|
|
return ErrorReset(RESET_UNLOAD | CLOSE_FD1 | DELETE_MTDBUF, "cannot open image file: ", imgFilename);
|
|
while(fsize > 0) {
|
|
block = (uint32_t)fsize;
|
|
if(block > (uint32_t)MTDBufSize)
|
|
block = MTDBufSize;
|
|
read(fd1, MTDBuf, block);
|
|
write(fd2, MTDBuf, block);
|
|
fsize -= block;
|
|
}
|
|
lseek(fd2, 0, SEEK_SET);
|
|
uint64_t fsizeDst = (uint64_t)lseek(fd2, 0, SEEK_END);
|
|
close(fd1);
|
|
close(fd2);
|
|
// check image file size
|
|
if (mtdRamSize != fsizeDst) {
|
|
unlink(imgFilename.c_str());
|
|
return ErrorReset(DELETE_MTDBUF, "error file size: ", imgFilename);
|
|
}
|
|
|
|
// unload mtdramDriver only
|
|
ErrorReset(RESET_UNLOAD);
|
|
|
|
if(hintBox)
|
|
hintBox->hide();
|
|
|
|
if (MTDBuf != NULL)
|
|
delete[] MTDBuf;
|
|
MTDBuf = NULL;
|
|
sync();
|
|
return true;
|
|
}
|
|
|
|
std::string Wildcard = "";
|
|
|
|
int fileSelect(const struct dirent *entry)
|
|
{
|
|
if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0))
|
|
return 0;
|
|
else
|
|
if ((!Wildcard.empty()) && (fnmatch(Wildcard.c_str(), entry->d_name, FNM_FILE_NAME)))
|
|
return 0;
|
|
else
|
|
return 1;
|
|
|
|
}
|
|
|
|
bool CExtUpdate::copyFileList(const std::string & fileList, const std::string & dstPath)
|
|
{
|
|
Wildcard = "";
|
|
struct dirent **namelist;
|
|
std::string fList = fileList, dst;
|
|
static struct stat FileInfo;
|
|
|
|
size_t pos = fileList.find_last_of("/");
|
|
fList = fileList.substr(0, pos);
|
|
Wildcard = fileList.substr(pos+1);
|
|
|
|
int n = scandir(fList.c_str(), &namelist, fileSelect, 0);
|
|
if (n > 0) {
|
|
dst = dstPath + fList;
|
|
FileHelpers->createDir(dst.c_str(), 0755);
|
|
while (n--) {
|
|
std::string dName = namelist[n]->d_name;
|
|
if (lstat((fList+"/"+dName).c_str(), &FileInfo) != -1) {
|
|
if (S_ISLNK(FileInfo.st_mode)) {
|
|
char buf[PATH_MAX];
|
|
int len = readlink((fList+"/"+dName).c_str(), buf, sizeof(buf)-1);
|
|
if (len != -1) {
|
|
buf[len] = '\0';
|
|
WRITE_UPDATE_LOG("symlink: %s => %s\n", (dst+"/"+dName).c_str(), buf);
|
|
symlink(buf, (dst+"/"+dName).c_str());
|
|
}
|
|
}
|
|
else
|
|
if (S_ISREG(FileInfo.st_mode)) {
|
|
WRITE_UPDATE_LOG("copy %s => %s\n", (fList+"/"+dName).c_str(), (dst+"/"+dName).c_str());
|
|
std::string save = (isBlacklistEntry(fList+"/"+dName)) ? ".save" : "";
|
|
if (!FileHelpers->copyFile((fList+"/"+dName).c_str(), (dst + "/" + dName + save).c_str(), FileInfo.st_mode & 0x0FFF))
|
|
return ErrorReset(0, "copyFile error");
|
|
}
|
|
}
|
|
free(namelist[n]);
|
|
}
|
|
free(namelist);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CExtUpdate::deleteFileList(const std::string & fileList)
|
|
{
|
|
Wildcard = "";
|
|
struct dirent **namelist;
|
|
std::string fList = fileList;
|
|
static struct stat FileInfo;
|
|
|
|
size_t pos = fileList.find_last_of("/");
|
|
fList = fileList.substr(0, pos);
|
|
Wildcard = fileList.substr(pos+1);
|
|
|
|
int n = scandir(fList.c_str(), &namelist, fileSelect, 0);
|
|
if (n > 0) {
|
|
while (n--) {
|
|
std::string dName = namelist[n]->d_name;
|
|
if (lstat((fList+"/"+dName).c_str(), &FileInfo) != -1) {
|
|
if (S_ISDIR(FileInfo.st_mode)) {
|
|
// Directory
|
|
WRITE_UPDATE_LOG("delete directory: %s\n", (fList+"/"+dName).c_str());
|
|
FileHelpers->removeDir((fList+"/"+dName).c_str());
|
|
}
|
|
else if (S_ISREG(FileInfo.st_mode)) {
|
|
// File
|
|
WRITE_UPDATE_LOG("delete file: %s\n", (fList+"/"+dName).c_str());
|
|
unlink((fList+"/"+dName).c_str());
|
|
}
|
|
}
|
|
free(namelist[n]);
|
|
}
|
|
free(namelist);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CExtUpdate::findConfigEntry(std::string & line, std::string find)
|
|
{
|
|
if (line.find("#:" + find + "=") == 0) {
|
|
size_t pos = line.find_first_of('=');
|
|
line = line.substr(pos+1);
|
|
line = trim(line);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CExtUpdate::readConfig(const std::string & line)
|
|
{
|
|
std::string tmp1 = line;
|
|
if (findConfigEntry(tmp1, "Log")) {
|
|
if (!tmp1.empty())
|
|
fLogEnabled = atoi(tmp1.c_str());
|
|
return true;
|
|
}
|
|
tmp1 = line;
|
|
if (findConfigEntry(tmp1, "LogFile")) {
|
|
if (!tmp1.empty())
|
|
fLogfile = tmp1;
|
|
return true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CExtUpdate::isBlacklistEntry(const std::string & file)
|
|
{
|
|
for(std::vector<std::string>::iterator it = blackList.begin(); it != blackList.end(); ++it) {
|
|
if (*it == file) {
|
|
DBG_MSG("BlacklistEntry %s\n", (*it).c_str());
|
|
WRITE_UPDATE_LOG("BlacklistEntry: %s\n", (*it).c_str());
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CExtUpdate::checkSpecialFolders(std::string line, bool copy)
|
|
{
|
|
if ((line == "/") || (line == "/*") || (line == "/*.*") || (line.find("/dev") == 0) || (line.find("/proc") == 0) ||
|
|
(line.find("/sys") == 0) || (line.find("/mnt") == 0) || (line.find("/tmp") == 0)) {
|
|
char buf[PATH_MAX];
|
|
neutrino_locale_t msg = (copy) ? LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_SKIPPED : LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_DEL_SKIPPED;
|
|
snprintf(buf, sizeof(buf), g_Locale->getText(msg), line.c_str());
|
|
WRITE_UPDATE_LOG("%s%s", buf, "\n");
|
|
ShowMsg(LOCALE_MESSAGEBOX_INFO, buf, CMsgBox::mbrOk, CMsgBox::mbOk, NEUTRINO_ICON_INFO);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CExtUpdate::readBackupList(const std::string & dstPath)
|
|
{
|
|
char buf[PATH_MAX];
|
|
static struct stat FileInfo;
|
|
std::vector<std::string>::iterator it;
|
|
|
|
f1 = fopen(backupList.c_str(), "r");
|
|
if (f1 == NULL) {
|
|
f1 = fopen(backupList.c_str(), "w");
|
|
if (f1 != NULL) {
|
|
char tmp1[1024];
|
|
snprintf(tmp1, sizeof(tmp1), "Log=%d\nLogFile=%s\n\n%s\n\n", fLogEnabled, fLogfile.c_str(), defaultBackup.c_str());
|
|
fwrite(tmp1, 1, strlen(tmp1), f1);
|
|
fclose(f1);
|
|
}
|
|
else
|
|
return ErrorReset(0, "cannot create missing backuplist file: " + backupList);
|
|
}
|
|
|
|
f1 = fopen(backupList.c_str(), "r");
|
|
if (f1 == NULL)
|
|
return ErrorReset(0, "cannot read backuplist file: " + backupList);
|
|
fpos_t fz;
|
|
fseek(f1, 0, SEEK_END);
|
|
fgetpos(f1, &fz);
|
|
fseek(f1, 0, SEEK_SET);
|
|
if (fz.__pos == 0)
|
|
return ErrorReset(CLOSE_F1, "backuplist filesize is 0");
|
|
size_t pos;
|
|
std::string line;
|
|
|
|
// read blacklist and config vars
|
|
copyList.clear();
|
|
blackList.clear();
|
|
deleteList.clear();
|
|
while(fgets(buf, sizeof(buf), f1) != NULL) {
|
|
std::string tmpLine;
|
|
line = buf;
|
|
line = trim(line);
|
|
// ignore comments
|
|
if (line.find_first_of("#") == 0) {
|
|
// config vars
|
|
if (line.find_first_of(":") == 1) {
|
|
if (line.length() > 1)
|
|
readConfig(line);
|
|
}
|
|
continue;
|
|
}
|
|
pos = line.find_first_of("#");
|
|
if (pos != std::string::npos) {
|
|
line = line.substr(0, pos);
|
|
line = trim(line);
|
|
}
|
|
// find blackList entry
|
|
if (line.find_first_of("-") == 0) {
|
|
tmpLine = line.substr(1);
|
|
if ((tmpLine.length() > 1) && (lstat(tmpLine.c_str(), &FileInfo) != -1)) {
|
|
if (S_ISREG(FileInfo.st_mode))
|
|
blackList.push_back(tmpLine);
|
|
}
|
|
}
|
|
// find deleteList entry
|
|
else if (line.find_first_of("~") == 0) {
|
|
tmpLine = line.substr(1);
|
|
if (checkSpecialFolders(tmpLine, false))
|
|
continue;
|
|
tmpLine = dstPath + tmpLine;
|
|
if (line.length() > 2)
|
|
deleteList.push_back(tmpLine);
|
|
}
|
|
// find copyList entry
|
|
else {
|
|
tmpLine = (line.find_first_of("+") == 0) ? line.substr(1) : line; // '+' add entry = default
|
|
if (checkSpecialFolders(tmpLine, true))
|
|
continue;
|
|
if (tmpLine.length() > 1)
|
|
copyList.push_back(tmpLine);
|
|
}
|
|
}
|
|
fclose(f1);
|
|
|
|
// read DeleteList
|
|
for(it = deleteList.begin(); it != deleteList.end(); ++it) {
|
|
line = *it;
|
|
if ((line.find("*") != std::string::npos) || (line.find("?") != std::string::npos)) {
|
|
// Wildcards
|
|
WRITE_UPDATE_LOG("delete file list: %s\n", line.c_str());
|
|
deleteFileList(line.c_str());
|
|
}
|
|
else if (lstat(line.c_str(), &FileInfo) != -1) {
|
|
if (S_ISREG(FileInfo.st_mode)) {
|
|
// File
|
|
WRITE_UPDATE_LOG("delete file: %s\n", line.c_str());
|
|
unlink(line.c_str());
|
|
}
|
|
else if (S_ISDIR(FileInfo.st_mode)){
|
|
// Directory
|
|
WRITE_UPDATE_LOG("delete directory: %s\n", line.c_str());
|
|
FileHelpers->removeDir(line.c_str());
|
|
}
|
|
}
|
|
}
|
|
sync();
|
|
|
|
if (get_fs_usage(mountPkt.c_str(), total, used, &bsize))
|
|
free2 = (total * bsize) / 1024 - (used * bsize) / 1024;
|
|
|
|
// read copyList
|
|
for(it = copyList.begin(); it != copyList.end(); ++it) {
|
|
line = *it;
|
|
line = trim(line);
|
|
// remove '/' from line end
|
|
size_t len = line.length();
|
|
pos = line.find_last_of("/");
|
|
if (len == pos+1)
|
|
line = line.substr(0, pos);
|
|
std::string dst = dstPath + line;
|
|
if ((line.find("*") != std::string::npos) || (line.find("?") != std::string::npos)) {
|
|
// Wildcards
|
|
DBG_MSG("Wildcards: %s\n", dst.c_str());
|
|
WRITE_UPDATE_LOG("\n");
|
|
WRITE_UPDATE_LOG("--------------------\n");
|
|
WRITE_UPDATE_LOG("Wildcards: %s\n", dst.c_str());
|
|
copyFileList(line, dstPath);
|
|
}
|
|
else {
|
|
if (lstat(line.c_str(), &FileInfo) != -1) {
|
|
if (S_ISREG(FileInfo.st_mode)) {
|
|
// one file only
|
|
pos = dst.find_last_of("/");
|
|
std::string dir = dst.substr(0, pos);
|
|
FileHelpers->createDir(dir.c_str(), 0755);
|
|
DBG_MSG("file: %s => %s\n", line.c_str(), dst.c_str());
|
|
WRITE_UPDATE_LOG("\n");
|
|
WRITE_UPDATE_LOG("file: %s => %s\n", line.c_str(), dst.c_str());
|
|
WRITE_UPDATE_LOG("--------------------\n");
|
|
std::string save = (isBlacklistEntry(line)) ? ".save" : "";
|
|
if (!FileHelpers->copyFile(line.c_str(), (dst + save).c_str(), FileInfo.st_mode & 0x0FFF))
|
|
return ErrorReset(0, "copyFile error");
|
|
}
|
|
else if (S_ISDIR(FileInfo.st_mode)) {
|
|
// directory
|
|
DBG_MSG("directory: %s => %s\n", line.c_str(), dst.c_str());
|
|
WRITE_UPDATE_LOG("\n");
|
|
WRITE_UPDATE_LOG("directory: %s => %s\n", line.c_str(), dst.c_str());
|
|
WRITE_UPDATE_LOG("--------------------\n");
|
|
FileHelpers->copyDir(line.c_str(), dst.c_str(), true);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
sync();
|
|
|
|
if (get_fs_usage(mountPkt.c_str(), total, used, &bsize)) {
|
|
uint64_t flashWarning = 1000; // 1MB
|
|
uint64_t flashError = 600; // 600KB
|
|
char buf1[1024];
|
|
total = (total * bsize) / 1024;
|
|
free3 = total - (used * bsize) / 1024;
|
|
printf("##### [%s] %llu KB free org, %llu KB free after delete, %llu KB free now\n", __FUNCTION__, free1, free2, free3);
|
|
memset(buf1, '\0', sizeof(buf1));
|
|
if (free3 <= flashError) {
|
|
snprintf(buf1, sizeof(buf1)-1, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_ERROR), free3, total);
|
|
ShowMsg(LOCALE_MESSAGEBOX_ERROR, buf1, CMsgBox::mbrOk, CMsgBox::mbOk, NEUTRINO_ICON_ERROR);
|
|
flashErrorFlag = true;
|
|
return false;
|
|
}
|
|
else if (free3 <= flashWarning) {
|
|
snprintf(buf1, sizeof(buf1)-1, g_Locale->getText(LOCALE_FLASHUPDATE_UPDATE_WITH_SETTINGS_WARNING), free3, total);
|
|
if (ShowMsg(LOCALE_MESSAGEBOX_INFO, buf1, CMsgBox::mbrNo, CMsgBox::mbYes | CMsgBox::mbNo, NEUTRINO_ICON_INFO) != CMsgBox::mbrYes) {
|
|
flashErrorFlag = true;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CExtUpdate::updateLog(const char *buf)
|
|
{
|
|
if ((!fUpdate) && (fLogEnabled))
|
|
fUpdate = fopen(fLogfile.c_str(), "a");
|
|
if (fUpdate) {
|
|
fwrite(buf, 1, strlen(buf), fUpdate);
|
|
fclose(fUpdate);
|
|
fUpdate = NULL;
|
|
}
|
|
}
|