2020-05-01 18:31:02 +02:00
/**
2020-05-02 22:06:47 +02:00
* @ file reHDD . cpp
* @ brief app logic
* @ author hendrik schutter
* @ date 01.05 .2020
2020-05-01 18:31:02 +02:00
*/
2020-05-02 22:06:47 +02:00
# include "../include/reHDD.h"
2020-05-01 18:31:02 +02:00
2020-08-03 22:40:07 +02:00
2020-08-04 11:59:45 +02:00
static int fdSearchDrives [ 2 ] ; //File descriptor for pipe that informs if new drives are found
static int fdUserInput [ 2 ] ; //File descriptor for pipe that informs if a user input occoures
2020-08-04 22:35:29 +02:00
static int fdWhipe [ 2 ] ; //File descriptor for pipe that informs if a wipe thread signals
2020-08-04 11:59:45 +02:00
static std : : mutex mxScannDrives ;
static vector < Drive > vecNewDrives ; //store found drives that are updated every 5sec
2020-08-07 11:38:00 +02:00
static vector < Drive > vecDrives ; //stores all drive data from scann thread
TUI * ui ;
static int32_t i32SelectedEntry ;
2020-08-04 11:59:45 +02:00
static fd_set selectSet ;
2020-08-03 22:40:07 +02:00
2020-05-01 18:31:02 +02:00
/**
* \ brief app constructor
2020-05-02 17:15:55 +02:00
* \ param void
2020-05-01 18:31:02 +02:00
* \ return instance of App
*/
2020-05-02 22:06:47 +02:00
reHDD : : reHDD ( void )
2020-05-02 17:15:55 +02:00
{
2020-05-01 18:31:02 +02:00
cout < < " created app " < < endl ;
2020-08-07 11:38:00 +02:00
i32SelectedEntry = 0 ;
2020-05-01 18:31:02 +02:00
}
/**
* \ brief app logic
2020-05-02 17:15:55 +02:00
* \ param void
2020-05-01 18:31:02 +02:00
* \ return void
*/
2020-05-02 22:06:47 +02:00
void reHDD : : app_logic ( void )
2020-05-01 18:31:02 +02:00
{
cout < < " app logic " < < endl ;
2020-08-04 22:35:29 +02:00
ui = new TUI ( ) ;
ui - > initTUI ( ) ;
2020-08-03 22:40:07 +02:00
2020-08-04 17:18:32 +02:00
pipe ( fdSearchDrives ) ;
2020-08-04 22:35:29 +02:00
pipe ( fdWhipe ) ;
2020-08-03 22:40:07 +02:00
2020-08-04 11:59:45 +02:00
FD_ZERO ( & selectSet ) ;
FD_SET ( fdSearchDrives [ 0 ] , & selectSet ) ;
2020-08-04 22:35:29 +02:00
FD_SET ( fdWhipe [ 0 ] , & selectSet ) ;
2020-08-03 22:40:07 +02:00
2020-08-04 17:18:32 +02:00
thread thDevices ( ThreadScannDevices ) ; //start thread that scanns for drives
2020-08-06 22:45:05 +02:00
thread thUserInput ( ThreadUserInput ) ; //start thread that reads user input
2020-08-03 22:40:07 +02:00
2020-08-07 11:38:00 +02:00
while ( 1 )
{
2020-08-03 22:40:07 +02:00
2020-08-07 11:38:00 +02:00
select ( FD_SETSIZE , & selectSet , NULL , NULL , NULL ) ;
2020-08-04 11:59:45 +02:00
2020-08-07 11:38:00 +02:00
if ( FD_ISSET ( fdSearchDrives [ 0 ] , & selectSet ) )
{
char dummy ;
read ( fdSearchDrives [ 0 ] , & dummy , 1 ) ;
mxScannDrives . lock ( ) ;
2020-08-03 22:40:07 +02:00
2020-08-07 11:38:00 +02:00
filterNewDrives ( & vecDrives , & vecNewDrives ) ; //filter and copy to app logic vector
mxScannDrives . unlock ( ) ;
//printDrives(&vecDrives);
//TODO update UI
2020-08-04 11:59:45 +02:00
2020-08-07 11:38:00 +02:00
ui - > updateTUI ( & vecDrives , i32SelectedEntry ) ;
}
else if ( FD_ISSET ( fdWhipe [ 0 ] , & selectSet ) )
{
cout < < " Whipe signal " < < endl ;
//update percantage & state
//update ui
}
} //endless loop
2020-08-04 22:35:29 +02:00
thDevices . join ( ) ;
2020-08-06 22:45:05 +02:00
thUserInput . join ( ) ;
2020-08-03 22:40:07 +02:00
}
2020-08-07 11:38:00 +02:00
void reHDD : : ThreadScannDevices ( )
{
while ( true )
{
// cout << "Thread" << endl;
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
mxScannDrives . unlock ( ) ;
write ( fdSearchDrives [ 1 ] , " A " , 1 ) ;
sleep ( 5 ) ; //sleep 5 sec
}
2020-08-04 17:18:32 +02:00
}
2020-08-03 22:40:07 +02:00
2020-08-07 11:38:00 +02:00
void reHDD : : ThreadUserInput ( )
{
while ( true )
2020-08-06 22:45:05 +02:00
{
2020-08-07 11:38:00 +02:00
// cout << TUI::readUserInput() << endl;
switch ( TUI : : readUserInput ( ) )
{
case TUI : : UserInput : : DownKey :
//cout << "Down" << endl;
handleArrowKey ( TUI : : UserInput : : DownKey ) ;
ui - > updateTUI ( & vecDrives , i32SelectedEntry ) ;
break ;
case TUI : : UserInput : : UpKey :
//cout << "Up" << endl;
handleArrowKey ( TUI : : UserInput : : UpKey ) ;
ui - > updateTUI ( & vecDrives , i32SelectedEntry ) ;
break ;
case TUI : : UserInput : : Undefined :
//cout << "Undefined" << endl;
break ;
case TUI : : UserInput : : Abort :
//cout << "Abort" << endl;
break ;
case TUI : : UserInput : : Delete :
//cout << "Delete" << endl;
break ;
case TUI : : UserInput : : Shred :
//cout << "Shred" << endl;
break ;
case TUI : : UserInput : : Enter :
//cout << "Enter" << endl;
break ;
case TUI : : UserInput : : ESC :
//cout << "ESC" << endl;
break ;
default :
break ;
}
2020-08-06 22:45:05 +02:00
}
}
2020-08-04 22:35:29 +02:00
2020-08-07 11:38:00 +02:00
void reHDD : : filterNewDrives ( vector < Drive > * pvecOldDrives , vector < Drive > * pvecNewDrives )
{
2020-08-03 22:40:07 +02:00
2020-08-04 17:18:32 +02:00
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
2020-08-03 22:40:07 +02:00
2020-08-04 17:18:32 +02:00
for ( itOld = pvecOldDrives - > begin ( ) ; itOld ! = pvecOldDrives - > end ( ) ; + + itOld )
{
2020-08-07 11:38:00 +02:00
bool bOldDriveIsOffline = true ;
for ( itNew = pvecNewDrives - > begin ( ) ; itNew ! = pvecNewDrives - > end ( ) ; + + itNew )
{
if ( itOld - > getSerial ( ) = = itNew - > getSerial ( ) )
{
bOldDriveIsOffline = false ;
// cout << "already online drive found: " << itOld->getPath() << endl;
}
}
2020-05-01 18:31:02 +02:00
2020-08-07 11:38:00 +02:00
if ( bOldDriveIsOffline = = true )
{
//cout << "offline drive found: " << itOld->getPath() << endl;
//TODO kill wipe thread
}
2020-08-04 19:51:34 +02:00
}
2020-08-03 22:40:07 +02:00
2020-08-04 19:51:34 +02:00
pvecOldDrives - > clear ( ) ;
2020-08-07 11:38:00 +02:00
for ( long unsigned int i = 0 ; i < pvecNewDrives - > size ( ) ; i + + )
{
pvecOldDrives - > push_back ( ( * pvecNewDrives ) [ i ] ) ;
}
2020-08-03 22:40:07 +02:00
}
2020-05-01 18:31:02 +02:00
/**
* \ brief search attached drives on / dev / sd *
2020-05-02 17:15:55 +02:00
* \ param pointer of vector < Drive > * pvecDrives
2020-05-01 18:31:02 +02:00
* \ return void
*/
2020-08-04 17:18:32 +02:00
void reHDD : : searchDrives ( vector < Drive > * pvecDrives )
2020-05-01 18:31:02 +02:00
{
2020-08-06 11:41:38 +02:00
// cout << "search drives ..." << endl;
2020-05-01 18:31:02 +02:00
char * cLine = NULL ;
size_t len = 0 ;
2020-05-03 18:00:05 +02:00
FILE * outputfileHwinfo = popen ( " hwinfo --short --disk " , " r " ) ;
2020-05-01 18:31:02 +02:00
if ( outputfileHwinfo = = NULL )
2020-08-07 11:38:00 +02:00
{
exit ( EXIT_FAILURE ) ;
}
2020-05-01 18:31:02 +02:00
while ( ( getline ( & cLine , & len , outputfileHwinfo ) ) ! = - 1 )
{
2020-08-07 11:38:00 +02:00
if ( string ( cLine ) . find ( " /dev/sd " ) ! = string : : npos )
{
Drive * tmpDrive = new Drive ( string ( cLine ) . substr ( 2 , 8 ) ) ;
pvecDrives - > push_back ( * tmpDrive ) ;
}
2020-05-01 18:31:02 +02:00
}
fclose ( outputfileHwinfo ) ;
}
/**
* \ brief filter out drives that are listed in " ignoreDrives.conf "
2020-05-02 17:15:55 +02:00
* \ param pointer of vector < Drive > * pvecDrives
2020-05-01 18:31:02 +02:00
* \ return void
*/
2020-05-02 22:06:47 +02:00
void reHDD : : filterIgnoredDrives ( vector < Drive > * pvecDrives )
2020-05-01 18:31:02 +02:00
{
string sDelimiter = " : " ;
string sIgnoredDrivePath ;
string sIgnoredDriveUUID ;
vector < tuple < string , string > > vtlIgnoredDevices ; //store drives from ingnore file
2020-08-04 19:51:34 +02:00
//vector <Drive> vecTmpDrives
2020-05-01 18:31:02 +02:00
ifstream input ( " ignoreDrives.conf " ) ; //read ingnore file
for ( string sLine ; getline ( input , sLine ) ; )
{
2020-08-07 11:38:00 +02:00
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
//cout << "Path: " << sIgnoredDrivePath << std::endl;
//cout << "UUID: " << sIgnoredDriveUUID << std::endl;
vtlIgnoredDevices . emplace_back ( sIgnoredDrivePath , sIgnoredDriveUUID ) ; //add found path and uuid from ingnore file to vector
}
2020-05-01 18:31:02 +02:00
}
//loop through found entries in ingnore file
for ( auto row : vtlIgnoredDevices )
{
2020-08-07 11:38:00 +02:00
vector < Drive > : : iterator it ;
for ( it = pvecDrives - > begin ( ) ; it ! = pvecDrives - > end ( ) ; + + it )
2020-05-01 18:31:02 +02:00
{
2020-08-07 11:38:00 +02:00
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 )
{
exit ( EXIT_FAILURE ) ;
}
while ( ( getline ( & cLine , & len , outputfileBlkid ) ) ! = - 1 ) //parse UUID from blkid
{
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;
}
}
fclose ( 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 ;
exit ( EXIT_FAILURE ) ; // exit to prevent accidentally shred a system drive
}
else
{
// same uuid found than in ignore file --> ignore this drive
it = pvecDrives - > erase ( it ) ;
it - - ;
//cout << "same uuid found than in ignore file --> ignore this drive:" << it->getPath() << endl;
}
}
2020-05-01 18:31:02 +02:00
}
}
}
/**
* \ brief print drives with all information
2020-05-02 17:15:55 +02:00
* \ param pointer of vector < Drive > * pvecDrives
2020-05-01 18:31:02 +02:00
* \ return void
*/
2020-05-02 22:06:47 +02:00
void reHDD : : printDrives ( vector < Drive > * pvecDrives )
2020-05-01 18:31:02 +02:00
{
cout < < " ------------DRIVES--------------- " < < endl ;
2020-05-02 17:15:55 +02:00
vector < Drive > : : iterator it ;
for ( it = pvecDrives - > begin ( ) ; it ! = pvecDrives - > end ( ) ; + + it )
2020-08-07 11:38:00 +02:00
{
cout < < " Drive: " < < distance ( pvecDrives - > begin ( ) , it ) < < endl ;
cout < < " Path: " < < it - > getPath ( ) < < endl ;
cout < < " ModelFamily: " < < it - > getModelFamily ( ) < < endl ;
cout < < " ModelName: " < < it - > getModelName ( ) < < endl ;
cout < < " Capacity: " < < it - > getCapacity ( ) < < endl ;
cout < < " Serial: " < < it - > getSerial ( ) < < endl ;
cout < < " PowerOnHours: " < < it - > getPowerOnHours ( ) < < endl ;
cout < < " PowerCycle: " < < it - > getPowerCycles ( ) < < endl ;
cout < < " ErrorCount: " < < it - > getErrorCount ( ) < < endl ;
cout < < endl ;
}
2020-05-01 18:31:02 +02:00
cout < < " --------------------------------- " < < endl ;
}
2020-05-02 00:49:11 +02:00
2020-05-02 17:15:55 +02:00
/**
* \ brief add S . M . A . R . T data from SMART
* \ param pointer of vector < Drive > * pvecDrives
* \ return void
*/
2020-05-02 22:06:47 +02:00
void reHDD : : addSMARTData ( vector < Drive > * pvecDrives )
2020-05-02 17:15:55 +02:00
{
vector < Drive > : : iterator it ;
for ( it = pvecDrives - > begin ( ) ; it ! = pvecDrives - > end ( ) ; + + it )
2020-08-07 11:38:00 +02:00
{
Drive * pTmpDrive = iterator_to_pointer < Drive , std : : vector < Drive > : : iterator > ( it ) ;
SMART : : readSMARTData ( pTmpDrive ) ;
}
}
void reHDD : : handleArrowKey ( TUI : : UserInput userInput )
{
int32_t i32EntrySize = ( int32_t ) vecDrives . size ( ) ;
switch ( userInput )
{
case TUI : : UserInput : : DownKey :
i32SelectedEntry + + ;
if ( i32SelectedEntry > = i32EntrySize )
{
i32SelectedEntry = 0 ;
}
break ;
case TUI : : UserInput : : UpKey :
i32SelectedEntry - - ;
if ( i32SelectedEntry < 0 )
{
i32SelectedEntry = ( i32EntrySize - 1 ) ;
}
break ;
default :
i32SelectedEntry = 0 ;
break ;
}
2020-05-02 00:49:11 +02:00
}