30 Commits

Author SHA1 Message Date
0e391cebf3 display also days 2022-05-13 21:14:48 +02:00
ecc8a71c64 display shred duration after completion 2022-05-12 07:40:24 +02:00
48bbad914f display used time to shred drive 2022-05-11 23:45:05 +02:00
818e78796d updated ignoreDrive.conf 2022-05-11 22:32:43 +02:00
161e7f049b start reHDD on tty1 2022-05-11 22:31:08 +02:00
033760c328 disk uuid changed to 8 byte long 2022-05-11 21:53:58 +02:00
af38d60982 code cleanup 2022-01-26 19:33:41 +01:00
25d8ca6920 filter drives only based on UUID 2022-01-26 19:21:38 +01:00
84e42a430b dis[play capacity as double 2022-01-26 16:31:46 +01:00
77c7849484 Merge pull request 'fix' (#34) from fix into develop
Reviewed-on: #34
2022-01-26 15:45:59 +01:00
f2db85aa33 pclose instead fclose 2022-01-26 15:44:32 +01:00
c942f36e49 using lsblk for listing attached drives 2022-01-26 15:15:34 +01:00
068413c15d log attached drives 2022-01-26 13:52:21 +01:00
7748d49b54 Merge branch 'develop' into master 2020-09-21 22:10:00 +02:00
3cd6baed36 Merge branch 'master' into develop 2020-09-21 22:07:45 +02:00
3d34de1311 release of Beta 0.2.0 2020-09-21 21:56:26 +02:00
555da195b2 Merge branch 'develop' into master 2020-09-21 21:50:04 +02:00
e65af04488 changed vector to list; again 2020-09-21 21:47:29 +02:00
5e190ba08f merge 2020-09-21 21:19:58 +02:00
2a2bfc6fe6 delete task thread 2020-09-21 16:50:33 +02:00
13304c4705 update ui layout 2020-09-21 16:11:31 +02:00
ade79add2a increase visibility of smart values 2020-09-21 14:45:52 +02:00
65c19f6fb9 define-switch for frozen alert 2020-09-20 22:40:05 +02:00
66cfbb5da2 ls instead hwinfo; update UI even mutex is locked 2020-09-20 00:12:18 +02:00
04f46bb9d6 fixed delete cmd 2020-09-18 14:42:45 +02:00
1e67ddf5ea Merge pull request 'fix/list change vector to list' (#24) from fix/list into master
Reviewed-on: #24
2020-09-16 15:28:50 +02:00
9b9be1ea4a Merge branch 'master' into fix/list 2020-09-16 15:28:16 +02:00
93a741fc6f code cleanup 2020-09-16 15:27:25 +02:00
0fc3bc222e changed vector to list 2020-09-16 15:13:32 +02:00
6c06943f3e added update script 2020-09-16 14:42:51 +02:00
15 changed files with 401 additions and 251 deletions

3
.gitignore vendored
View File

@ -42,3 +42,6 @@
reHDD
reHDD.log
ignoreDrives.conf

View File

@ -11,31 +11,28 @@
## Debian Build Notes
* apt-get install ncurses-dev git make g++
* clone repo
* clone repo in /root/
* make release
## Create Standalone with Debian
## Create Standalone with Debian 11
Instructions how to create a standalone machine that boots directly to reHDD. This is aimed for production use, like several drives a day shredding.
### Software requirements
* apt-get install hwinfo
* wget http://ftp.de.debian.org/debian/pool/main/s/smartmontools/smartmontools_7.1-1_amd64.deb
* dpkg --install smartmontools_7.1-1_amd64.deb
* apt-get install hwinfo smartmontools curl
### Start reHDD after boot without login (as a tty shell)
nano /etc/systemd/system/reHDD.service
```
[Unit]
Description=Custom user interface on tty1
Conflicts=getty@tty1.service
Before=getty.target
mkdir /lib/systemd/system/getty@tty1.service.d/
nano /lib/systemd/system/getty@tty1.service.d/override.conf
```
[Service]
WorkingDirectory=/root/reHDD
ExecStart=/root/reHDD/reHDD
ExecStart=
ExecStart=-/root/reHDD/reHDD
StandardInput=tty
StandardOutput=tty
Restart=always
@ -47,10 +44,10 @@ TTYVHangup=yes
TTYVTDisallocate=yes
SendSIGHUP=yes
[Install]
WantedBy=multi-user.target
```
systemctl daemon-reload
nano /etc/systemd/system/reHDDSettings.service
```
[Service]
@ -66,14 +63,18 @@ nano /root/reHDDSettings.sh
```
#!/bin/bash
dmesg -n 1 #disable overlay if a drive is attached/detached
# remove comment for the following to activate log telemetie
# curl -k -T /root/reHDD/reHDD.log -u "fgggfffgfgfgfg:" -H 'X-Requested-With: XMLHttpRequest' https://schuttercloud.com/public.php/webdav/`echo $(date '+%Y-%m-%d_%H-%M')`_reHDD.log
rm -f /root/reHDD/reHDD.log
```
Make sure the binary reHDD is in /root/reHDD/
Add your system drive in /root/reHDD/ignoreDrives.conf like:
``` /dev/sdX:e102f49d-5ed5-462b-94c5-ef66a4345671```
Get your UUID via blkid /dev/sdX
chmod +x reHDDSettings.sh
systemctl enable reHDD.service
Make sure the binary reHDD is in /root/reHDD/
Add your system drive in /root/reHDD/ignoreDrives.conf like:
```e102f49d```
Get the first 8 Bytes from your UUID via blkid /dev/sdX
systemctl enable reHDDSettings.service

24
astyle.sh Normal file
View File

@ -0,0 +1,24 @@
#! /bin/bash
echo starting astyle for $PWD
astyle --style=gnu src/*.cpp
rm -f src/*.orig
astyle --style=gnu src/shred/*.cpp
rm -f src/shred/*.orig
astyle --style=gnu src/logger/*.cpp
rm -f src/logger/*.orig
astyle --style=gnu include/*.h
rm -f include//*.orig
astyle --style=gnu include//shred/*.h
rm -f include//shred/*.orig
astyle --style=gnu include//logger/*.h
rm -f include//logger/*.orig
echo finished astyle for $PWD

26
doc/update.sh Normal file
View File

@ -0,0 +1,26 @@
#! /usr/bin/bash
echo starting update
FILE=./ignoreDrives.conf
if test -f "$FILE"; then
echo backup exits
else
cp reHDD/ignoreDrives.conf ./ignoreDrives.conf
fi
cd reHDD
git reset
git stash force
git stash
git checkout master
git pull
make release
cp ../ignoreDrives.conf ./

View File

@ -1 +1 @@
4673974d

View File

@ -37,6 +37,8 @@ private:
uint32_t u32PowerCycles = 0U;
time_t u32Timestamp = 0U; //unix timestamp for detecting a frozen drive
double d32TaskPercentage = 0U; //in percent for Shred (1 to 100)
time_t u32TimestampTaskStart = 0U; //unix timestamp for duration of an action
time_t u32TaskDuration = 0U; //time needed to complete the task
private:
void setTimestamp();
@ -75,6 +77,12 @@ public:
void setTaskPercentage(double d32TaskPercentage);
double getTaskPercentage(void);
void setActionStartTimestamp();
time_t getActionStartTimestamp();
void calculateTaskDuration();
time_t getTaskDuration();
};
#endif // DRIVE_H_

View File

@ -1,6 +1,6 @@
/**
* @file reHDD.h
* @brief represent
* @brief app logic header
* @author hendrik schutter
* @date 01.05.2020
*/
@ -8,19 +8,17 @@
#ifndef REHDD_H_
#define REHDD_H_
#define REHDD_VERSION "bV0.1.0"
//#define DRYRUN
#define REHDD_VERSION "bV0.2.1"
// Drive handling Settings
#define WORSE_HOURS 19200 //mark drive if at this limit or beyond
#define WORSE_POWERUP 10000 //mark drive if at this limit or beyond
#define SHRED_ITERATIONS 3
#define FROZEN_TIMEOUT 5 //After this timeout (minutes) the drive will be marked as frozen
#define FROZEN_TIMEOUT 10 //After this timeout (minutes) the drive will be marked as frozen
// Logger Settings
#define LOG_PATH "./reHDD.log"
#define DESCRIPTION "reHDD - Copyright Hendrik Schutter 2020"
#define DESCRIPTION "reHDD - Copyright Hendrik Schutter 2022"
#define DEVICE_ID "generic"
#define SOFTWARE_VERSION "alpha"
#define HARDWARE_VERSION "generic"
@ -30,6 +28,10 @@
#define LOG_LEVEL_LOW //log only user actions and tasks
#endif
// Logic
#define DRYRUN //don´t touch the drives
#define FROZEN_ALERT //show alert if drive is frozen
//IPC pipes
#define READ 0
#define WRITE 1
@ -38,7 +40,7 @@
#include <string>
#include <fstream>
#include <tuple>
#include <vector>
#include <list>
#include <time.h>
#include <chrono>
#include <curses.h>
@ -78,14 +80,15 @@ public:
private:
static void searchDrives(vector <Drive>* pvecDrives);
static void printDrives(vector <Drive>* pvecDrives);
static void filterIgnoredDrives(vector <Drive>* pvecDrives);
static void filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecNewDrives);
static void addSMARTData(vector <Drive>* pvecDrives);
static void searchDrives(list <Drive>* plistDrives);
static void printDrives(list <Drive>* plistDrives);
static void filterIgnoredDrives(list <Drive>* plistDrives);
static void filterNewDrives(list <Drive>* plistOldDrives, list <Drive>* plistNewDrives);
static void addSMARTData(list <Drive>* plistDrives);
static void ThreadScannDevices();
static void ThreadUserInput();
static void ThreadShred();
static void ThreadDelete();
static void ThreadCheckFrozenDrives();
static void handleArrowKey(TUI::UserInput userInput);
static void handleEnter();
@ -94,5 +97,4 @@ private:
static Drive* getSelectedDrive();
};
#endif // REHDD_H_

View File

@ -36,7 +36,7 @@ public:
static void initTUI();
void updateTUI(vector <Drive>* pvecDrives, uint8_t u8SelectedEntry);
void updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry);
static enum UserInput readUserInput();
@ -45,24 +45,26 @@ private:
static string sRamUsage;
static string sLocalTime;
WINDOW* overview;
WINDOW* systemview;
WINDOW* detailview;
WINDOW* menuview;
WINDOW* dialog;
WINDOW* smartWarning;
static void centerTitle(WINDOW *pwin, const char * title);
static WINDOW *createOverViewWindow( int iXSize, int iYSize);
static WINDOW *createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive drive);
static WINDOW *overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart);
static WINDOW *createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, bool bSelected);
static WINDOW *createSystemStats(int iXSize, int iYSize, int iYStart);
static WINDOW *createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, string sTime, bool bSelected);
static WINDOW *createSystemStats(int iXSize, int iYSize, int iXStart, int iYStart);
static WINDOW *createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate);
static WINDOW *createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string selectedTask, string optionA, string optionB);
static WINDOW* createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial);
static WINDOW* createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, string sProgress);
static WINDOW* createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, uint32_t u32PowerOnHours, uint32_t u32PowerCycles, uint32_t u32ErrorCount);
void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY);
string formatTimeDuration(time_t u32Duration);
};
#endif // TUI_H_

View File

@ -167,6 +167,7 @@ clean:
@echo "Deleting directories"
@$(RM) -r build
@$(RM) -r bin
@$(RM) -f reHDD.log
# Main rule, checks the executable and symlinks to the output
all: $(BIN_PATH)/$(BIN_NAME)
@ -199,6 +200,7 @@ $(BUILD_PATH)/%.o: $(SRC_PATH)/%.$(SRC_EXT)
docs:
@$(RM) -r $(DOCDIR)/html
@doxygen $(DOCDIR)/doxyfile
.PHONY: style
style:
@bash astyle.sh

View File

@ -21,6 +21,7 @@ void Delete::deleteDrive(Drive* drive)
#ifndef DRYRUN
string sCMD = ("wipefs -af ");
sCMD.append(drive->getPath());
sCMD.append("*");
#endif
#ifdef DRYRUN
@ -37,5 +38,5 @@ void Delete::deleteDrive(Drive* drive)
{
//wipefs running
}
fclose(deleteCmdOutput);
pclose(deleteCmdOutput);
}

View File

@ -48,17 +48,18 @@ uint32_t Drive::getPowerCycles(void)
string Drive::sCapacityToText()
{
if(getCapacity() <= (999*1000000000UL))
char acBuffer[16];
double dSize = (double) getCapacity();
uint16_t u16UnitIndex = 0;
const char* units[] = {"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
while (dSize >= 1000) //using the marketing capacity
{
// Less or even 999 GB --> GB
return to_string(getCapacity() / 1000000000UL) + " GB";
dSize /= 1000;
u16UnitIndex++;
}
else
{
// More 999 GB --> TB
return to_string(getCapacity() / 1000000000000UL) + " TB";
}
return "ERROR";
sprintf(acBuffer, "%.*f %s", u16UnitIndex-3, dSize, units[u16UnitIndex]);
return acBuffer;
}
string Drive::sErrorCountToText()
@ -69,14 +70,19 @@ string Drive::sErrorCountToText()
string Drive::sPowerOnHoursToText()
{
double dDays = 0U;
double dYears = 0U;
uint32_t u32Hours = getPowerOnHours();
stringstream stream;
stringstream streamDays;
stringstream streamYears;
dDays = (double) ((double)u32Hours/(double)24U);
dYears = (double) ((double)u32Hours/(double)8760U);
stream << fixed << setprecision(2) << dYears;
string sRet = to_string(getPowerOnHours()) + " hours or " + stream.str() + " years";
streamDays << fixed << setprecision(0) << dDays;
streamYears << fixed << setprecision(1) << dYears;
string sRet = to_string(getPowerOnHours()) + " hours or " + streamDays.str() + " days or " + streamYears.str() + " years";
return sRet;
}
@ -126,14 +132,37 @@ void Drive::setDriveSMARTData( string modelFamily,
u32ErrorCount = errorCount;
u32PowerOnHours = powerOnHours;
u32PowerCycles = powerCycle;
}
}
void Drive::setTimestamp()
{
time(&this->u32Timestamp);
}
void Drive::setActionStartTimestamp()
{
time(&this->u32TimestampTaskStart);
}
time_t Drive::getActionStartTimestamp()
{
return this->u32TimestampTaskStart;
}
void Drive::calculateTaskDuration()
{
time_t u32localtime;
time(&u32localtime);
this->u32TaskDuration = u32localtime - this->u32TimestampTaskStart;
}
time_t Drive::getTaskDuration()
{
return this->u32TaskDuration;
}
void Drive::checkFrozenDrive(void)
{
time_t u32localtime;

View File

@ -13,9 +13,9 @@ static int fdShredInformPipe[2];//File descriptor for pipe that informs if a wip
static std::mutex mxScannDrives;
vector <Drive> vecNewDrives; //store found drives that are updated every 5sec
list <Drive> listNewDrives; //store found drives that are updated every 5sec
static vector <Drive> vecDrives; //stores all drive data from scann thread
static list <Drive> listDrives; //stores all drive data from scann thread
TUI *ui;
@ -23,8 +23,6 @@ static uint8_t u8SelectedEntry;
static fd_set selectSet;
//static struct TUI::MenuState menustate;
/**
* \brief app constructor
* \param void
@ -33,8 +31,6 @@ static fd_set selectSet;
reHDD::reHDD(void)
{
u8SelectedEntry = 0U;
vecDrives.reserve(128);
}
/**
@ -61,23 +57,25 @@ void reHDD::app_logic(void)
FD_SET(fdShredInformPipe[0], &selectSet);
select(FD_SETSIZE, &selectSet, NULL, NULL, NULL);
mxScannDrives.lock();
if( FD_ISSET(fdNewDrivesInformPipe[0], &selectSet))
if(FD_ISSET(fdNewDrivesInformPipe[0], &selectSet))
{
mxScannDrives.lock();
char dummy;
read (fdNewDrivesInformPipe[0],&dummy,1);
filterNewDrives(&vecDrives, &vecNewDrives); //filter and copy to app logic vector
printDrives(&vecDrives);
filterNewDrives(&listDrives, &listNewDrives); //filter and copy to app logic vector
printDrives(&listDrives);
mxScannDrives.unlock();
}
if (FD_ISSET(fdShredInformPipe[0], &selectSet))
if(FD_ISSET(fdShredInformPipe[0], &selectSet))
{
char dummy;
read (fdShredInformPipe[0],&dummy,1);
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("got progress signal from a shred task");
#endif
}
ui->updateTUI(&vecDrives, u8SelectedEntry);
mxScannDrives.unlock();
ui->updateTUI(&listDrives, u8SelectedEntry);
} //endless loop
thDevices.join();
thUserInput.join();
@ -86,9 +84,11 @@ void reHDD::app_logic(void)
Drive* reHDD::getSelectedDrive()
{
if(u8SelectedEntry < vecDrives.size() )
if(u8SelectedEntry < listDrives.size() )
{
return &(vecDrives.at(u8SelectedEntry));
list<Drive>::iterator it = listDrives.begin();
advance(it, u8SelectedEntry);
return &(*it);
}
else
{
@ -102,24 +102,22 @@ void reHDD::ThreadScannDevices()
while(true)
{
mxScannDrives.lock();
vecNewDrives.clear();
searchDrives(&vecNewDrives); //search for new drives and store them in list
filterIgnoredDrives(&vecNewDrives); //filter out ignored drives
addSMARTData(&vecNewDrives); //add S.M.A.R.T. Data to the drives
listNewDrives.clear();
searchDrives(&listNewDrives); //search for new drives and store them in list
filterIgnoredDrives(&listNewDrives); //filter out ignored drives
addSMARTData(&listNewDrives); //add S.M.A.R.T. Data to the drives
mxScannDrives.unlock();
write(fdNewDrivesInformPipe[1], "A",1);
sleep(5); //sleep 5 sec
}
}
void reHDD::ThreadCheckFrozenDrives()
{
while(true)
{
mxScannDrives.lock();
for(auto it = begin(vecDrives); it != end(vecDrives); ++it)
for(auto it = begin(listDrives); it != end(listDrives); ++it)
{
if(it->state == Drive::SHRED_ACTIVE)
{
@ -127,7 +125,7 @@ void reHDD::ThreadCheckFrozenDrives()
}
}
mxScannDrives.unlock();
sleep(5); //sleep 5 sec
sleep(13); //sleep 13 sec
}
}
@ -141,12 +139,12 @@ void reHDD::ThreadUserInput()
case TUI::UserInput::DownKey:
//cout << "Down" << endl;
handleArrowKey(TUI::UserInput::DownKey);
ui->updateTUI(&vecDrives, u8SelectedEntry);
ui->updateTUI(&listDrives, u8SelectedEntry);
break;
case TUI::UserInput::UpKey:
//cout << "Up" << endl;
handleArrowKey(TUI::UserInput::UpKey);
ui->updateTUI(&vecDrives, u8SelectedEntry);
ui->updateTUI(&listDrives, u8SelectedEntry);
break;
case TUI::UserInput::Undefined:
//cout << "Undefined" << endl;
@ -154,7 +152,7 @@ void reHDD::ThreadUserInput()
case TUI::UserInput::Abort:
//cout << "Abort" << endl;
handleAbort();
ui->updateTUI(&vecDrives, u8SelectedEntry);
ui->updateTUI(&listDrives, u8SelectedEntry);
break;
case TUI::UserInput::Delete:
//cout << "Delete" << endl;
@ -166,7 +164,7 @@ void reHDD::ThreadUserInput()
getSelectedDrive()->state = Drive::DELETE_SELECTED;
}
}
ui->updateTUI(&vecDrives, u8SelectedEntry);
ui->updateTUI(&listDrives, u8SelectedEntry);
break;
case TUI::UserInput::Shred:
//cout << "Shred" << endl;
@ -178,17 +176,17 @@ void reHDD::ThreadUserInput()
getSelectedDrive()->state = Drive::SHRED_SELECTED;
}
}
ui->updateTUI(&vecDrives, u8SelectedEntry);
ui->updateTUI(&listDrives, u8SelectedEntry);
break;
case TUI::UserInput::Enter:
//cout << "Enter" << endl;
handleEnter();
ui->updateTUI(&vecDrives, u8SelectedEntry);
ui->updateTUI(&listDrives, u8SelectedEntry);
break;
case TUI::UserInput::ESC:
//cout << "ESC" << endl;
handleESC();
ui->updateTUI(&vecDrives, u8SelectedEntry);
ui->updateTUI(&listDrives, u8SelectedEntry);
break;
default:
break;
@ -200,27 +198,41 @@ void reHDD::ThreadShred()
{
if (getSelectedDrive() != nullptr)
{
getSelectedDrive()->setActionStartTimestamp(); //save timestamp at start of shredding
Shred* pShredTask = new Shred(); //create new shred task
pShredTask->shredDrive(getSelectedDrive(), &fdShredInformPipe[1]); //start new shred task
delete pShredTask; //delete shred task
ui->updateTUI(&vecDrives, u8SelectedEntry);
ui->updateTUI(&listDrives, u8SelectedEntry);
}
}
void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecNewDrives)
void reHDD::ThreadDelete()
{
vector <Drive>::iterator itOld; //Iterator for current (old) drive list
vector <Drive>::iterator itNew; //Iterator for new drive list that was created from to scann thread
if (getSelectedDrive() != nullptr)
{
getSelectedDrive()->setActionStartTimestamp(); //save timestamp at start of deleting
Delete::deleteDrive(getSelectedDrive()); //blocking, no thread
getSelectedDrive()->state = Drive::TaskState::NONE; //delete finished
getSelectedDrive()->bWasDeleteted = true;
Logger::logThis()->info("Finished delete for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
ui->updateTUI(&listDrives, u8SelectedEntry);
}
}
void reHDD::filterNewDrives(list <Drive>* plistOldDrives, list <Drive>* plistNewDrives)
{
list <Drive>::iterator itOld; //Iterator for current (old) drive list
list <Drive>::iterator itNew; //Iterator for new drive list that was created from to scann thread
//remove offline old drives from previously run
for (itOld = pvecOldDrives->begin(); itOld != pvecOldDrives->end();)
for (itOld = plistOldDrives->begin(); itOld != plistOldDrives->end();)
{
if(itOld->bIsOffline == true)
{
Logger::logThis()->warning("Offline drive found: " + itOld->getPath());
itOld = pvecOldDrives->erase(itOld);
itOld = plistOldDrives->erase(itOld);
/*
if(pvecOldDrives->size() > 0){ //This can be a risk if the user starts a task for the selected drive and the selected drive changes
if(plistOldDrives->size() > 0){ //This can be a risk if the user starts a task for the selected drive and the selected drive changes
u8SelectedEntry = 0U;
}
*/
@ -232,10 +244,10 @@ void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecN
}
//search offline drives and mark them
for (itOld = pvecOldDrives->begin(); itOld != pvecOldDrives->end(); ++itOld)
for (itOld = plistOldDrives->begin(); itOld != plistOldDrives->end(); ++itOld)
{
itOld->bIsOffline = true; //set offline befor seachring in the new list
for (itNew = pvecNewDrives->begin(); itNew != pvecNewDrives->end();)
for (itNew = plistNewDrives->begin(); itNew != plistNewDrives->end();)
{
if((itOld->getSerial() == itNew->getSerial()) || (itOld->getPath() == itNew->getPath()))
{
@ -243,7 +255,7 @@ void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecN
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("Delete new drive, because allready attached: " + itNew->getModelName());
#endif
itNew = pvecNewDrives->erase(itNew); //This drive is allready attached, remove from new list
itNew = plistNewDrives->erase(itNew); //This drive is allready attached, remove from new list
}
else
{
@ -253,7 +265,7 @@ void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecN
}
//mark offline old drives
for (itOld = pvecOldDrives->begin(); itOld != pvecOldDrives->end(); ++itOld)
for (itOld = plistOldDrives->begin(); itOld != plistOldDrives->end(); ++itOld)
{
if(itOld->bIsOffline == true)
{
@ -264,126 +276,102 @@ void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecN
}
//add new drives to drive list
for (itNew = pvecNewDrives->begin(); itNew != pvecNewDrives->end(); ++itNew)
for (itNew = plistNewDrives->begin(); itNew != plistNewDrives->end(); ++itNew)
{
pvecOldDrives->push_back(pvecNewDrives->at(itNew - pvecNewDrives->begin()));
plistOldDrives->push_back(*itNew);
Logger::logThis()->info("Add new drive: " + itNew->getModelName());
}
pvecNewDrives->clear();
plistNewDrives->clear();
}
/**
* \brief search attached drives on /dev/sd*
* \param pointer of vector <Drive>* pvecDrives
* \param pointer of list <Drive>* plistDrives
* \return void
*/
void reHDD::searchDrives(vector <Drive>* pvecDrives)
void reHDD::searchDrives(list <Drive>* plistDrives)
{
// cout << "search drives ..." << endl;
Logger::logThis()->info("--> search drives <--");
char * cLine = NULL;
size_t len = 0;
FILE* outputfileHwinfo = popen("hwinfo --short --disk", "r");
FILE* outputfileHwinfo = popen("lsblk -I 8 -d -o NAME", "r");
if (outputfileHwinfo == NULL)
{
Logger::logThis()->error("Unable to scan attached drives");
exit(EXIT_FAILURE);
}
while ((getline(&cLine, &len, outputfileHwinfo)) != -1)
{
if (string(cLine).find("/dev/sd") != string::npos)
if (string(cLine).length() == 4)
{
Drive* tmpDrive = new Drive(string(cLine).substr (2,8));
Drive* tmpDrive = new Drive("/dev/" + string(cLine).substr(0, 3));
tmpDrive->state = Drive::NONE;
tmpDrive->bIsOffline = false;
pvecDrives->push_back(*tmpDrive);
plistDrives->push_back(*tmpDrive);
//Logger::logThis()->info("drive found: " + tmpDrive->getPath());
}
}
fclose(outputfileHwinfo);
pclose(outputfileHwinfo);
}
/**
* \brief filter out drives that are listed in "ignoreDrives.conf"
* \param pointer of vector <Drive>* pvecDrives
* \param pointer of list <Drive>* plistDrives
* \return void
*/
void reHDD::filterIgnoredDrives(vector <Drive>* pvecDrives)
void reHDD::filterIgnoredDrives(list <Drive>* plistDrives)
{
string sDelimiter = ":";
string sIgnoredDrivePath;
string sIgnoredDriveUUID;
vector<tuple<string, string>> vtlIgnoredDevices; //store drives from ingnore file
list<tuple<string>> vtlIgnoredDevices; //store drives from ingnore file
ifstream input( "ignoreDrives.conf" ); //read ingnore file
for(string sLine; getline( input, sLine );)
{
if (string(sLine).find("/dev/sd") != string::npos)
{
size_t pos = 0;
string token;
while ((pos = sLine.find(sDelimiter)) != string::npos)
{
token = sLine.substr(0, pos);
sIgnoredDrivePath = token;
sLine.erase(0, pos + sDelimiter.length());
sIgnoredDriveUUID = sLine;
} //end while
vtlIgnoredDevices.emplace_back(sIgnoredDrivePath, sIgnoredDriveUUID); //add found path and uuid from ingnore file to vector
}
Logger::logThis()->info("read uuid: " + sLine);
vtlIgnoredDevices.emplace_back(sLine); //add found path and uuid from ignore file to vector
}
//loop through found entries in ingnore file
for(auto row : vtlIgnoredDevices)
{
vector <Drive>::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
list <Drive>::iterator it;
for (it = plistDrives->begin(); it != plistDrives->end(); ++it)
{
string sUUID;
if (!get<0>(row).compare(it->getPath())) //find same drive based on path
char * cLine = NULL;
size_t len = 0;
string sCMD = "blkid ";
sCMD.append(it->getPath());
//cout << "cmd: " << sCMD << endl;
FILE* outputfileBlkid = popen(sCMD.c_str(), "r"); //get UUID from drive
if (outputfileBlkid == NULL)
{
char * cLine = NULL;
size_t len = 0;
string sCMD = "blkid ";
sCMD.append(it->getPath());
//cout << "cmd: " << sCMD << endl;
FILE* outputfileBlkid = popen(sCMD.c_str(), "r"); //get UUID from drive
if (outputfileBlkid == NULL)
{
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
}
while ((getline(&cLine, &len, outputfileBlkid)) != -1) //parse UUID from blkid
while ((getline(&cLine, &len, outputfileBlkid)) != -1) //parse UUID from blkid
{
if (string(cLine).find("PTUUID") != string::npos)
{
if (string(cLine).find("PTUUID") != string::npos)
{
string sBlkidOut = string(cLine);
sBlkidOut.erase(0, 18);
sBlkidOut.erase(36, sBlkidOut.length() - 36);
sUUID = sBlkidOut;
//cout << "blkid uuid:" << sUUID << endl;
}
string sBlkidOut = string(cLine);
sBlkidOut.erase(0, 18);
sBlkidOut.erase(8, sBlkidOut.length());
sUUID = sBlkidOut;
//cout << "blkid uuid:" << sUUID << endl;
}
fclose(outputfileBlkid);
//cout << "blkid uuid:" << sUUID << endl;
}
pclose(outputfileBlkid);
//cout << "blkid uuid:" << sUUID << endl;
if (get<1>(row).compare(sUUID)) //compare uuid from ignore file and uuid from drive
{
cout << "[ERROR] different uuid found than in ignore file:" << it->getPath() << endl;
Logger::logThis()->error("[ERROR] different uuid found than in ignore file: " + it->getPath());
exit(EXIT_FAILURE); // exit to prevent accidentally shred a system drive
}
else
{
// same uuid found than in ignore file --> ignore this drive
if (!get<0>(row).compare(sUUID)) //compare uuid from ignore file and uuid from drive
{
// same uuid found than in ignore file --> ignore this drive
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("same uuid found than in ignore file --> ignore this drive: " + it->getPath());
Logger::logThis()->info("same uuid found than in ignore file --> ignore this drive: " + it->getPath());
#endif
it = pvecDrives->erase(it);
it--;
}
it = plistDrives->erase(it);
it--;
}
}
}
@ -391,16 +379,17 @@ void reHDD::filterIgnoredDrives(vector <Drive>* pvecDrives)
/**
* \brief print drives with all information
* \param pointer of vector <Drive>* pvecDrives
* \param pointer of list <Drive>* plistDrives
* \return void
*/
void reHDD::printDrives(vector <Drive>* pvecDrives)
void reHDD::printDrives(list <Drive>* plistDrives)
{
#ifdef LOG_LEVEL_HIGH
Logger::logThis()->info("------------DRIVES---------------");
Logger::logThis()->info("------------DRIVES START------------");
//cout << "------------DRIVES---------------" << endl;
vector <Drive>::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
list <Drive>::iterator it;
uint8_t u8Index = 0;
for (it = plistDrives->begin(); it != plistDrives->end(); ++it)
{
/*
cout << " Drive: " << distance(pvecDrives->begin(), it) << endl;
@ -415,34 +404,32 @@ void reHDD::printDrives(vector <Drive>* pvecDrives)
cout << endl;*/
ostringstream address;
address << (void const *)&pvecDrives->at(it - pvecDrives->begin());
Logger::logThis()->info(to_string(it - pvecDrives->begin()) + ": " + it->getPath() + " - " + it->getModelFamily() + " - " + it->getSerial() + " @" + address.str());
address << (void const *)&(*it);
Logger::logThis()->info(to_string(u8Index++) + ": " + it->getPath() + " - " + it->getModelFamily() + " - " + it->getSerial() + " @" + address.str());
}
Logger::logThis()->info("---------------------------------");
Logger::logThis()->info("------------DRIVES END--------------");
//cout << "---------------------------------" << endl;
#endif
}
/**
* \brief add S.M.A.R.T data from SMART
* \param pointer of vector <Drive>* pvecDrives
* \param pointer of list <Drive>* plistDrives
* \return void
*/
void reHDD::addSMARTData(vector <Drive>* pvecDrives)
void reHDD::addSMARTData(list <Drive>* plistDrives)
{
vector <Drive>::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
list <Drive>::iterator it;
for (it = plistDrives->begin(); it != plistDrives->end(); ++it)
{
Drive* pTmpDrive = iterator_to_pointer<Drive, std::vector<Drive>::iterator > (it);
Drive* pTmpDrive = iterator_to_pointer<Drive, std::list<Drive>::iterator > (it);
SMART::readSMARTData(pTmpDrive);
}
}
void reHDD::handleArrowKey(TUI::UserInput userInput)
{
int8_t u8EntrySize = (int8_t) vecDrives.size();
int8_t u8EntrySize = (int8_t) listDrives.size();
switch (userInput)
{
case TUI::UserInput::DownKey:
@ -487,10 +474,7 @@ void reHDD::handleEnter()
Logger::logThis()->info("Started delete for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
getSelectedDrive()->state = Drive::TaskState::DELETE_ACTIVE;
//task for drive is running --> don´t show more task options
Delete::deleteDrive(getSelectedDrive()); //blocking, no thread
getSelectedDrive()->state = Drive::TaskState::NONE; //delete finished
getSelectedDrive()->bWasDeleteted = true;
Logger::logThis()->info("Finished delete for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
thread(ThreadDelete).detach();
}
}
}

View File

@ -43,8 +43,9 @@ Shred::~Shred()
*/
void Shred::shredDrive(Drive* drive, int* ipSignalFd)
{
#ifdef DRYRUN
for(int i = 0; i<=100; i++)
for(int i = 0; i<=500; i++)
{
if(drive->state != Drive::SHRED_ACTIVE)
{

View File

@ -51,7 +51,7 @@ void SMART::readSMARTData(Drive* drive)
SMART::parsePowerOnHours(sLine);
SMART::parsePowerCycle(sLine);
}
fclose(outputfileSmart);
pclose(outputfileSmart);
drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycle); //wirte data in drive
}

View File

@ -50,53 +50,68 @@ void TUI::initTUI()
Logger::logThis()->info("UI successfully initialized");
}
void TUI::updateTUI(vector <Drive>* pvecDrives, uint8_t u8SelectedEntry)
void TUI::updateTUI(list <Drive>* plistDrives, uint8_t u8SelectedEntry)
{
mxUIrefresh.lock();
int stdscrX, stdscrY;
getmaxyx(stdscr, stdscrY, stdscrX);
uint16_t u16StdscrX, u16StdscrY;
getmaxyx(stdscr, u16StdscrY, u16StdscrX);
init_pair(COLOR_AREA_STDSCR,COLOR_WHITE, COLOR_BLUE);
wbkgd(stdscr, COLOR_PAIR(COLOR_AREA_STDSCR));
refresh();
overview=createOverViewWindow((int)(stdscrX/3), (stdscrY-15));
overview=createOverViewWindow((int)(u16StdscrX/3), (u16StdscrY-3));
wrefresh(overview);
systemview=createSystemStats((int)(stdscrX/3), 10, (stdscrY-11));
systemview=createSystemStats((int)(u16StdscrX/3), 10, u16StdscrX-(int)(u16StdscrX/3)-2, (u16StdscrY-11 ));
wrefresh(systemview);
delwin(detailview);
vector <Drive>::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
list <Drive>::iterator it;
uint8_t u8Index = 0U;
for (it = plistDrives->begin(); it != plistDrives->end(); ++it)
{
string sModelFamily = it->getModelFamily();
string sModelName = it->getModelName();
string sCapacity = it->sCapacityToText();
string sState = " ";
string sTime = " ";
bool bSelectedEntry = false;
if(u8SelectedEntry == (it - pvecDrives->begin()))
if(u8SelectedEntry == u8Index)
{
bSelectedEntry = true; //mark this drive in entries list
displaySelectedDrive(pvecDrives->at(u8SelectedEntry), stdscrX, stdscrY);
displaySelectedDrive(*it, u16StdscrX, u16StdscrY);
if((it->getPowerOnHours() >= WORSE_HOURS) || (it->getPowerCycles() >= WORSE_POWERUP) || (it->getErrorCount() > 0))
{
// smart values are bad --> show warning
smartWarning=createSmartWarning(50, 10, ((u16StdscrX)-(int)(u16StdscrX/2)+35),(int)(u16StdscrY/2)-5, it->getPath(), it->getPowerOnHours(), it->getPowerCycles(), it->getErrorCount());
wrefresh(smartWarning);
}
}
stringstream stream;
switch (it->state)
{
case Drive::SHRED_ACTIVE:
stream << fixed << setprecision(2) << (it->getTaskPercentage());
sState = "Shredding: " + stream.str() + "%";
break;
it->calculateTaskDuration();
sTime = this->formatTimeDuration(it->getTaskDuration());
break;
case Drive::DELETE_ACTIVE:
sState = "Deleting ...";
it->calculateTaskDuration();
sTime = this->formatTimeDuration(it->getTaskDuration());
break;
case Drive::NONE:
@ -109,21 +124,30 @@ void TUI::updateTUI(vector <Drive>* pvecDrives, uint8_t u8SelectedEntry)
if (it->bWasShredded)
{
sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted
sTime = this->formatTimeDuration(it->getTaskDuration());
}
break;
case Drive::FROZEN:
dialog=createFrozenWarning(70, 16, ((stdscrX)-(int)(stdscrX/2)-35),(int)(stdscrY/2)-8, it->getPath(), it->getModelFamily(), it->getModelName(), it->getSerial());
wrefresh(dialog);
stream << fixed << setprecision(2) << (it->getTaskPercentage());
#ifdef FROZEN_ALERT
if(bSelectedEntry)
{
dialog=createFrozenWarning(70, 16, ((u16StdscrX)-(int)(u16StdscrX/2)-20),(int)(u16StdscrY/2)-8, it->getPath(), it->getModelFamily(), it->getModelName(), it->getSerial(), stream.str() + "%");
wrefresh(dialog);
}
#endif
sState = "FROZEN " + stream.str() + "%"; //mark drive as frozen and reached progress
break;
default:
break;
}
WINDOW * tmp = createEntryWindow( ((int)(stdscrX/3) - 2), 5, 3, (5* (it - pvecDrives->begin()) )+3, sModelFamily, sModelName, sCapacity, sState, bSelectedEntry);
WINDOW * tmp = createEntryWindow( ((int)(u16StdscrX/3) - 2), 5, 3, (5* (u8Index) )+3, sModelFamily, sModelName, sCapacity, sState, sTime, bSelectedEntry);
wrefresh(tmp);
u8Index++;
}//end loop though drives
if(pvecDrives->size() == 0)
if(plistDrives->size() == 0)
{
//no selected drive present
Logger::logThis()->warning("no selected drive present");
@ -134,10 +158,10 @@ void TUI::updateTUI(vector <Drive>* pvecDrives, uint8_t u8SelectedEntry)
menustate.bDelete = false;
menustate.bShred = false;
menuview=createMenuView(((stdscrX)-(int)(stdscrX/3)-7), 10, (int)(stdscrX/3)+5,(stdscrY-11), menustate);
menuview=createMenuView(((int)(u16StdscrX/3)-10 ), 10, (int)(u16StdscrX/3)+5,(u16StdscrY-11), menustate);
wrefresh(menuview);
detailview=overwriteDetailViewWindow(((stdscrX)-(int)(stdscrX/3)-7), (stdscrY-15), (int)(stdscrX/3)+5);
detailview=overwriteDetailViewWindow(((u16StdscrX)-(int)(u16StdscrX/3)-7), (u16StdscrY-15), (int)(u16StdscrX/3)+5);
wrefresh(detailview);
}
@ -232,38 +256,9 @@ WINDOW* TUI::createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive
attroff(COLOR_PAIR(COLOR_AREA_DETAIL));
if(drive.getPowerOnHours() >= WORSE_HOURS)
{
mvwaddstr(newWindow,u16Line++, 3, "------------> WARNING: OPERATING HOURS <-----------");
mvwaddstr(newWindow,u16Line++, 3, sPowerOnHours.c_str());
mvwaddstr(newWindow,u16Line++, 3, "---------------------------------------------------");
}
else
{
mvwaddstr(newWindow,u16Line++, 3, sPowerOnHours.c_str());
}
if(drive.getPowerCycles() >= WORSE_POWERUP)
{
mvwaddstr(newWindow,u16Line++, 3, "------------> WARNING: POWER-ON <------------------");
mvwaddstr(newWindow,u16Line++, 3, sPowerCycle.c_str());
mvwaddstr(newWindow,u16Line++, 3, "---------------------------------------------------");
}
else
{
mvwaddstr(newWindow,u16Line++, 3, sPowerCycle.c_str());
}
if(drive.getErrorCount() > 0)
{
mvwaddstr(newWindow,u16Line++, 3, "------------> WARNING: S.M.A.R.T ERROR <-----------");
mvwaddstr(newWindow,u16Line++, 3, sErrorCount.c_str());
mvwaddstr(newWindow,u16Line++, 3, "---------------------------------------------------");
}
else
{
mvwaddstr(newWindow,u16Line++, 3, sErrorCount.c_str());
}
mvwaddstr(newWindow,u16Line++, 3, sPowerOnHours.c_str());
mvwaddstr(newWindow,u16Line++, 3, sPowerCycle.c_str());
mvwaddstr(newWindow,u16Line++, 3, sErrorCount.c_str());
return newWindow;
}
@ -301,7 +296,7 @@ WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart)
return newWindow;
}
WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, bool bSelected)
WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, string sTime, bool bSelected)
{
WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
@ -326,14 +321,15 @@ WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart,
mvwaddstr(newWindow,3, 1, sCapacity.c_str());
mvwaddstr(newWindow,2, iXSize-sState.length()-5, sState.c_str());
mvwaddstr(newWindow,3, iXSize-sState.length()-5, sTime.c_str());
return newWindow;
}
WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iYStart)
WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iXStart, int iYStart)
{
WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, 2);
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_OVERVIEW));
box(newWindow, ACS_VLINE, ACS_HLINE);
@ -348,7 +344,19 @@ WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iYStart)
strftime(buffer,sizeof(buffer),"Date: %d-%m-%Y Time: %H:%M",timeinfo);
string time(buffer);
mvwaddstr(newWindow,2, 2, time.c_str());
string sLine01 = "reHDD - hard drive refurbishing tool";
string sLine02 = "Version: " + string(REHDD_VERSION);
string sLine03 = "Available under GPL 3.0";
string sLine04 = "https://git.mosad.xyz/localhorst/reHDD";
uint16_t u16Line = 2;
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str());
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine02.c_str());
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine03.c_str());
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine04.c_str());
u16Line++;
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), time.c_str());
return newWindow;
}
@ -363,20 +371,24 @@ WINDOW* TUI::createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, st
centerTitle(newWindow, "Controls");
uint16_t u16Line = 2;
if(menustate.bAbort)
{
mvwaddstr(newWindow,u16Line++, 3, "Press A for Abort");
string sLineTmp = "Press A for Abort";
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLineTmp.size()/2), sLineTmp.c_str());
u16Line++;
}
if(menustate.bShred)
{
mvwaddstr(newWindow,u16Line++, 3, "Press S for Shred");
string sLineTmp = "Press S for Shred ";
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLineTmp.size()/2), sLineTmp.c_str());
u16Line++;
}
if(menustate.bDelete)
{
mvwaddstr(newWindow,u16Line++, 3, "Press D for Delete");
string sLineTmp = "Press D for Delete";
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLineTmp.size()/2), sLineTmp.c_str());
}
return newWindow;
@ -392,14 +404,15 @@ WINDOW* TUI::createDialog(int iXSize, int iYSize, int iXStart, int iYStart, stri
centerTitle(newWindow, task.c_str());
uint16_t u16Line = 2;
mvwaddstr(newWindow,u16Line++, 3, optionA.c_str());
mvwaddstr(newWindow,u16Line++, 3, optionB.c_str());
uint16_t u16Line = 3;
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(optionA.size()/2), optionA.c_str());
u16Line++;
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(optionB.size()/2), optionB.c_str());
return newWindow;
}
WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial)
WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial, string sProgress)
{
WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
@ -409,6 +422,7 @@ WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStar
string sHeader = "Drive " + sPath + " is frozen";
string sLine01 = "Please detach this drive and check it manually:";
string sShredState = "Shredding stopped after " + sProgress;
string sLinePath = "Path: " +sPath;
string sLineModelFamlily = "ModelFamily: " + sModelFamily;
string sLineModelName = "ModelName: " + sModelName;
@ -429,10 +443,24 @@ WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStar
u16Line++;
mvwaddstr(newWindow,u16Line++, 3, sLine02.c_str());
mvwaddstr(newWindow,u16Line++, 3, sLine03.c_str());
mvwaddstr(newWindow,u16Line++, 3, sShredState.c_str());
return newWindow;
}
string TUI::formatTimeDuration(time_t u32Duration)
{
std::ostringstream out;
int dy=(int)((u32Duration)/86400);
int hr=(int)(((u32Duration)/3600)%24);
int min=((int)((u32Duration)/60))%60;
int sec=(int)((u32Duration)%60);
char s[25];
sprintf(s, "%02d:%02d:%02d:%02d", dy, hr, min, sec);
out << s;
return out.str();
}
void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
{
struct MenuState menustate;
@ -471,17 +499,17 @@ void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
detailview=createDetailViewWindow(((stdscrX)-(int)(stdscrX/3)-7), (stdscrY-15), (int)(stdscrX/3)+5, drive);
wrefresh(detailview);
menuview=createMenuView(((stdscrX)-(int)(stdscrX/3)-7), 10, (int)(stdscrX/3)+5,(stdscrY-11), menustate);
menuview=createMenuView(((int)(stdscrX/3)-10 ), 10, (int)(stdscrX/3)+5,(stdscrY-11), menustate);
wrefresh(menuview);
if(menustate.bConfirmShred == true)
{
dialog=createDialog(70, 10, ((stdscrX)-(int)(stdscrX/3)-7)-(int)((stdscrX/3)+5)/2,(int)(stdscrY/2)-5, "Confirm SHRED", "Press ENTER for SHRED", "Press ESC for cancel");
dialog=createDialog(40, 10, ((stdscrX)-(int)(stdscrX/3)-7)-(int)((stdscrX/3)+5)/2,(int)(stdscrY/2)-5, "Confirm SHRED", "Press ENTER for SHRED", "Press ESC for cancel");
wrefresh(dialog);
}
else if(menustate.bConfirmDelete == true)
{
dialog=createDialog(70, 10, ((stdscrX)-(int)(stdscrX/3)-7)-(int)((stdscrX/3)+5)/2,(int)(stdscrY/2)-5, "Confirm DELETE", "Press ENTER for DELETE", "Press ESC for cancel");
dialog=createDialog(40, 10, ((stdscrX)-(int)(stdscrX/3)-7)-(int)((stdscrX/3)+5)/2,(int)(stdscrY/2)-5, "Confirm DELETE", "Press ENTER for DELETE", "Press ESC for cancel");
wrefresh(dialog);
}
else
@ -489,3 +517,42 @@ void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
delwin(dialog);
}
}
WINDOW* TUI::createSmartWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, uint32_t u32PowerOnHours, uint32_t u32PowerCycles, uint32_t u32ErrorCount)
{
WINDOW *newWindow;
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
box(newWindow, ACS_VLINE, ACS_HLINE);
string sHeader = "Drive " + sPath + " is suspicious";
string sLine01 = "Please evaluate this drive carefully.";
centerTitle(newWindow, sHeader.c_str());
uint16_t u16Line = 2;
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str());
u16Line++;
if(u32PowerOnHours > WORSE_HOURS)
{
string sLineTmp = "Operating hours exceeded " + to_string(WORSE_HOURS) + " hours: " + to_string(u32PowerOnHours);
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLineTmp.c_str());
u16Line++;
}
if(u32PowerCycles > WORSE_POWERUP)
{
string sLineTmp = "Power-on exceeded " + to_string(WORSE_POWERUP) + " cycles: " + to_string(u32PowerCycles);
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLineTmp.c_str());
u16Line++;
}
if(u32ErrorCount > 0)
{
string sLineTmp = "S.M.A.R.T. erros detected: " + to_string(u32ErrorCount);
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLineTmp.c_str());
}
return newWindow;
}