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
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-04 22:35:29 +02:00
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-03 22:40:07 +02:00
2020-08-04 17:18:32 +02:00
while ( 1 ) {
2020-08-03 22:40:07 +02:00
2020-08-04 17:18:32 +02:00
select ( FD_SETSIZE , & selectSet , NULL , NULL , NULL ) ;
2020-08-04 11:59:45 +02:00
2020-08-04 17:18:32 +02:00
if ( FD_ISSET ( fdSearchDrives [ 0 ] , & selectSet ) ) {
char dummy ;
read ( fdSearchDrives [ 0 ] , & dummy , 1 ) ;
mxScannDrives . lock ( ) ;
2020-08-04 19:51:34 +02:00
filterNewDrives ( & vecDrives , & vecNewDrives ) ;
2020-08-04 22:35:29 +02:00
//printDrives(&vecDrives);
//TODO update UI
2020-08-03 22:40:07 +02:00
2020-08-04 22:35:29 +02:00
ui - > updateTUI ( & vecDrives ) ;
2020-08-04 11:59:45 +02:00
2020-08-04 17:18:32 +02:00
mxScannDrives . unlock ( ) ;
2020-08-03 22:40:07 +02:00
}
2020-08-04 22:35:29 +02:00
else if ( FD_ISSET ( fdWhipe [ 0 ] , & selectSet ) ) {
cout < < " Whipe signal " < < endl ;
2020-08-04 17:18:32 +02:00
}
2020-08-04 22:35:29 +02:00
} //endless loop
thDevices . join ( ) ;
2020-08-03 22:40:07 +02:00
}
2020-08-04 17:18:32 +02:00
void reHDD : : ThreadScannDevices ( ) {
while ( true ) {
2020-08-04 22:35:29 +02:00
// cout << "Thread" << endl;
2020-08-04 17:18:32 +02:00
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-03 22:40:07 +02:00
2020-08-04 22:35:29 +02:00
2020-08-04 19:51:34 +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-04 19:51:34 +02:00
bool bOldDriveIsOffline = true ;
for ( itNew = pvecNewDrives - > begin ( ) ; itNew ! = pvecNewDrives - > end ( ) ; + + itNew )
2020-08-04 17:18:32 +02:00
{
2020-08-04 19:51:34 +02:00
if ( itOld - > getSerial ( ) = = itNew - > getSerial ( ) ) {
bOldDriveIsOffline = false ;
2020-08-04 22:35:29 +02:00
// cout << "already online drive found: " << itOld->getPath() << endl;
2020-08-04 17:18:32 +02:00
}
}
2020-05-01 18:31:02 +02:00
2020-08-04 19:51:34 +02:00
if ( bOldDriveIsOffline = = true ) {
cout < < " offline drive found: " < < itOld - > getPath ( ) < < endl ;
//TODO kill wipe thread
}
}
2020-08-03 22:40:07 +02:00
2020-08-04 19:51:34 +02:00
pvecOldDrives - > clear ( ) ;
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-04 22:35:29 +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 )
{
exit ( EXIT_FAILURE ) ;
}
while ( ( getline ( & cLine , & len , outputfileHwinfo ) ) ! = - 1 )
{
if ( string ( cLine ) . find ( " /dev/sd " ) ! = string : : npos )
{
2020-05-01 22:18:01 +02:00
Drive * tmpDrive = new Drive ( string ( cLine ) . substr ( 2 , 8 ) ) ;
2020-05-02 17:15:55 +02:00
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 ) ; )
{
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
}
}
//loop through found entries in ingnore file
for ( auto row : vtlIgnoredDevices )
{
2020-08-04 19:51:34 +02:00
vector < Drive > : : iterator it ;
for ( it = pvecDrives - > begin ( ) ; it ! = pvecDrives - > end ( ) ; + + it )
2020-05-01 18:31:02 +02:00
{
string sUUID ;
2020-05-01 22:18:01 +02:00
if ( ! get < 0 > ( row ) . compare ( it - > getPath ( ) ) ) //find same drive based on path
2020-05-01 18:31:02 +02:00
{
char * cLine = NULL ;
size_t len = 0 ;
2020-05-03 18:00:05 +02:00
string sCMD = " blkid " ;
2020-05-01 22:18:01 +02:00
sCMD . append ( it - > getPath ( ) ) ;
2020-08-04 19:51:34 +02:00
//cout << "cmd: " << sCMD << endl;
2020-05-01 18:31:02 +02:00
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 ) ;
2020-08-04 19:51:34 +02:00
//cout << "blkid uuid:" << sUUID << endl;
2020-05-01 18:31:02 +02:00
if ( get < 1 > ( row ) . compare ( sUUID ) ) //compare uuid from ignore file and uuid from drive
{
2020-05-01 22:18:01 +02:00
cout < < " [ERROR] different uuid found than in ignore file: " < < it - > getPath ( ) < < endl ;
2020-05-01 18:31:02 +02:00
exit ( EXIT_FAILURE ) ; // exit to prevent accidentally shred a system drive
}
else
{
// same uuid found than in ignore file --> ignore this drive
2020-05-02 17:15:55 +02:00
it = pvecDrives - > erase ( it ) ;
2020-08-04 19:51:34 +02:00
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-05-01 18:31:02 +02:00
{
2020-05-03 17:17:20 +02:00
cout < < " Drive: " < < distance ( pvecDrives - > begin ( ) , it ) < < endl ;
2020-05-01 22:18:01 +02:00
cout < < " Path: " < < it - > getPath ( ) < < endl ;
2020-05-02 00:49:11 +02:00
cout < < " ModelFamily: " < < it - > getModelFamily ( ) < < endl ;
cout < < " ModelName: " < < it - > getModelName ( ) < < endl ;
2020-05-01 22:18:01 +02:00
cout < < " Capacity: " < < it - > getCapacity ( ) < < endl ;
cout < < " Serial: " < < it - > getSerial ( ) < < endl ;
cout < < " PowerOnHours: " < < it - > getPowerOnHours ( ) < < endl ;
2020-05-02 17:15:55 +02:00
cout < < " PowerCycle: " < < it - > getPowerCycles ( ) < < endl ;
2020-05-01 22:18:01 +02:00
cout < < " ErrorCount: " < < it - > getErrorCount ( ) < < endl ;
2020-05-01 18:31:02 +02:00
cout < < endl ;
}
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-05-02 00:49:11 +02:00
{
2020-05-02 17:15:55 +02:00
Drive * pTmpDrive = iterator_to_pointer < Drive , std : : vector < Drive > : : iterator > ( it ) ;
SMART : : readSMARTData ( pTmpDrive ) ;
2020-05-02 00:49:11 +02:00
}
}