diff --git a/include/drive.h b/include/drive.h index 5f7063a..e3862f7 100644 --- a/include/drive.h +++ b/include/drive.h @@ -18,7 +18,8 @@ public: SHRED_SELECTED, SHRED_ACTIVE, DELETE_SELECTED, - DELETE_ACTIVE + DELETE_ACTIVE, + FROZEN } state; bool bWasShredded = false; @@ -34,9 +35,11 @@ private: uint32_t u32ErrorCount = 0U; uint32_t u32PowerOnHours = 0U; //in hours 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) +private: + void setTimestamp(); protected: @@ -54,6 +57,7 @@ public: uint32_t getErrorCount(void); uint32_t getPowerOnHours(void); //in hours uint32_t getPowerCycles(void); + void checkFrozenDrive(void); void setDriveSMARTData( string modelFamily, string modelName, diff --git a/include/reHDD.h b/include/reHDD.h index b1defd5..5d6de82 100644 --- a/include/reHDD.h +++ b/include/reHDD.h @@ -8,15 +8,13 @@ #ifndef REHDD_H_ #define REHDD_H_ -//#define DRYRUN +#define DRYRUN +// 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 1 - -#define READ 0 -#define WRITE 1 +#define FROZEN_TIMEOUT 5 //After this timeout (minutes) the drive will be marked as frozen // Logger Settings #define LOG_PATH "./reHDD.log" @@ -30,6 +28,10 @@ #define LOG_LEVEL_LOW //log only user actions and tasks #endif +//IPC pipes +#define READ 0 +#define WRITE 1 + #include #include #include @@ -82,6 +84,7 @@ private: static void ThreadScannDevices(); static void ThreadUserInput(); static void ThreadShred(); + static void ThreadCheckFrozenDrives(); static void handleArrowKey(TUI::UserInput userInput); static void handleEnter(); static void handleESC(); diff --git a/include/tui.h b/include/tui.h index 3d4c3a9..135ff0d 100644 --- a/include/tui.h +++ b/include/tui.h @@ -56,10 +56,11 @@ private: 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 *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 *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); void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY); diff --git a/src/drive.cpp b/src/drive.cpp index 18441ff..36cd7c9 100644 --- a/src/drive.cpp +++ b/src/drive.cpp @@ -91,6 +91,7 @@ void Drive::setTaskPercentage(double d32TaskPercentage) if(d32TaskPercentage <= 100) { this->d32TaskPercentage = d32TaskPercentage; + this->setTimestamp(); //set timestamp for this progress for detecting a frozen drive } } double Drive::getTaskPercentage(void) @@ -125,4 +126,24 @@ void Drive::setDriveSMARTData( string modelFamily, u32ErrorCount = errorCount; u32PowerOnHours = powerOnHours; u32PowerCycles = powerCycle; +} + + +void Drive::setTimestamp() +{ + time(&this->u32Timestamp); +} + +void Drive::checkFrozenDrive(void) +{ + time_t u32localtime; + time(&u32localtime); + + if((u32localtime - this->u32Timestamp) >= (FROZEN_TIMEOUT*60) && (this->u32Timestamp > 0)) + { + Logger::logThis()->warning("Drive Frozen: " + this->getModelName() + " " + this->getSerial()); + this->bWasDeleteted = false; + this->bWasShredded = false; + this->state = Drive::FROZEN; + } } \ No newline at end of file diff --git a/src/reHDD.cpp b/src/reHDD.cpp index 1b55a6e..fbc8d96 100644 --- a/src/reHDD.cpp +++ b/src/reHDD.cpp @@ -52,6 +52,7 @@ void reHDD::app_logic(void) thread thDevices(ThreadScannDevices); //start thread that scanns for drives thread thUserInput(ThreadUserInput); //start thread that reads user input + thread thCheckFrozenDrives(ThreadCheckFrozenDrives); //start thread that checks timeout for drives while(1) { @@ -60,15 +61,14 @@ 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)) { char dummy; read (fdNewDrivesInformPipe[0],&dummy,1); - mxScannDrives.lock(); filterNewDrives(&vecDrives, &vecNewDrives); //filter and copy to app logic vector printDrives(&vecDrives); - mxScannDrives.unlock(); + } if (FD_ISSET(fdShredInformPipe[0], &selectSet)) @@ -77,9 +77,11 @@ void reHDD::app_logic(void) read (fdShredInformPipe[0],&dummy,1); } ui->updateTUI(&vecDrives, u8SelectedEntry); + mxScannDrives.unlock(); } //endless loop thDevices.join(); thUserInput.join(); + thCheckFrozenDrives.join(); } Drive* reHDD::getSelectedDrive() @@ -110,6 +112,25 @@ void reHDD::ThreadScannDevices() } } + + +void reHDD::ThreadCheckFrozenDrives() +{ + while(true) + { + mxScannDrives.lock(); + for(auto it = begin(vecDrives); it != end(vecDrives); ++it) + { + if(it->state == Drive::SHRED_ACTIVE) + { + it->checkFrozenDrive(); + } + } + mxScannDrives.unlock(); + sleep(5); //sleep 5 sec + } +} + void reHDD::ThreadUserInput() { while(true) diff --git a/src/shred/shred.cpp b/src/shred/shred.cpp index d5b3969..7f9377b 100644 --- a/src/shred/shred.cpp +++ b/src/shred/shred.cpp @@ -21,6 +21,7 @@ struct tfnge_stream }; static struct tfnge_stream tfnge; +#endif Shred::Shred() { @@ -34,7 +35,7 @@ Shred::~Shred() } -#endif + /** * \brief shred drive with shred * \param pointer of Drive instance @@ -51,7 +52,6 @@ void Shred::shredDrive(Drive* drive, int* ipSignalFd) } drive->setTaskPercentage(i+0.05); write(*ipSignalFd, "A",1); - usleep(20000); } #endif diff --git a/src/tui.cpp b/src/tui.cpp index 90cc902..e9d63fa 100644 --- a/src/tui.cpp +++ b/src/tui.cpp @@ -111,6 +111,10 @@ void TUI::updateTUI(vector * pvecDrives, uint8_t u8SelectedEntry) sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted } 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); + break; default: break; } @@ -276,11 +280,11 @@ WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart) string sLine01 = "reHDD - hard drive refurbishing tool"; string sLine02 = "Version: beta X.X.X"; - string sLine03 = "Available under GPL 3.0"; + string sLine03 = "Available under GPL 3.0"; string sLine04 = "https://git.mosad.xyz/localhorst/reHDD"; string sLine05 = "Delete: Wipe format table - this is NOT secure"; string sLine06 = "Shred: Overwite drive " + to_string(SHRED_ITERATIONS) + " iterations - this is secure"; - + uint16_t u16Line = 5; mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str()); @@ -395,6 +399,40 @@ WINDOW* TUI::createDialog(int iXSize, int iYSize, int iXStart, int iYStart, stri return newWindow; } +WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial) +{ + 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 frozen"; + string sLine01 = "Please detach this drive and check it manually:"; + string sLinePath = "Path: " +sPath; + string sLineModelFamlily = "ModelFamily: " + sModelFamily; + string sLineModelName = "ModelName: " + sModelName; + string sLineSerial = "Serial: " + sSerial; + + string sLine02 = "reHDD was not able to write data to the drive."; + string sLine03 = "This can be caused by an malfunctioning drive."; + + centerTitle(newWindow, sHeader.c_str()); + + uint16_t u16Line = 2; + mvwaddstr(newWindow,u16Line++, 3, sLine01.c_str()); + u16Line++; + mvwaddstr(newWindow,u16Line++, 3, sLinePath.c_str()); + mvwaddstr(newWindow,u16Line++, 3, sLineModelFamlily.c_str()); + mvwaddstr(newWindow,u16Line++, 3, sLineModelName.c_str()); + mvwaddstr(newWindow,u16Line++, 3, sLineSerial.c_str()); + u16Line++; + mvwaddstr(newWindow,u16Line++, 3, sLine02.c_str()); + mvwaddstr(newWindow,u16Line++, 3, sLine03.c_str()); + + return newWindow; +} + void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY) { struct MenuState menustate;