select drive based on arrow keys

This commit is contained in:
2020-08-07 11:38:00 +02:00
parent a92a9c2a2a
commit 1b0ea97ed1
7 changed files with 355 additions and 267 deletions

View File

@ -18,6 +18,11 @@ static std::mutex mxScannDrives;
static vector <Drive> vecNewDrives; //store found drives that are updated every 5sec
static vector <Drive> vecDrives; //stores all drive data from scann thread
TUI *ui;
static int32_t i32SelectedEntry;
static fd_set selectSet;
@ -29,8 +34,7 @@ static fd_set selectSet;
reHDD::reHDD(void)
{
cout << "created app" << endl;
i32SelectedEntry = 0;
}
/**
@ -41,9 +45,7 @@ reHDD::reHDD(void)
void reHDD::app_logic(void)
{
cout << "app logic" << endl;
ui = new TUI();
ui->initTUI();
pipe(fdSearchDrives);
@ -56,107 +58,124 @@ void reHDD::app_logic(void)
thread thDevices(ThreadScannDevices); //start thread that scanns for drives
thread thUserInput(ThreadUserInput); //start thread that reads user input
while(1) {
while(1)
{
select(FD_SETSIZE, &selectSet, NULL, NULL, NULL);
select(FD_SETSIZE, &selectSet, NULL, NULL, NULL);
if( FD_ISSET(fdSearchDrives[0], &selectSet)) {
char dummy;
read (fdSearchDrives[0],&dummy,1);
mxScannDrives.lock();
filterNewDrives(&vecDrives, &vecNewDrives);
//printDrives(&vecDrives);
//TODO update UI
if( FD_ISSET(fdSearchDrives[0], &selectSet))
{
char dummy;
read (fdSearchDrives[0],&dummy,1);
mxScannDrives.lock();
ui->updateTUI(&vecDrives);
filterNewDrives(&vecDrives, &vecNewDrives); //filter and copy to app logic vector
mxScannDrives.unlock();
//printDrives(&vecDrives);
//TODO update UI
mxScannDrives.unlock();
}
else if (FD_ISSET(fdWhipe[0], &selectSet)) {
cout << "Whipe signal" << endl;
}
} //endless loop
ui->updateTUI(&vecDrives, i32SelectedEntry);
}
else if (FD_ISSET(fdWhipe[0], &selectSet))
{
cout << "Whipe signal" << endl;
//update percantage & state
//update ui
}
} //endless loop
thDevices.join();
thUserInput.join();
}
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
}
}
void reHDD::ThreadUserInput() {
while(true) {
// cout << TUI::readUserInput() << endl;
switch (TUI::readUserInput())
void reHDD::ThreadScannDevices()
{
while(true)
{
case TUI::UserInput::DownKey:
/* code */
//cout << "Down" << endl;
break;
case TUI::UserInput::UpKey:
//cout << "Up" << endl;
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;
// 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
}
}
}
void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecNewDrives) {
void reHDD::ThreadUserInput()
{
while(true)
{
// 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;
}
}
}
void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecNewDrives)
{
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
for (itOld = pvecOldDrives->begin(); itOld != pvecOldDrives->end(); ++itOld)
{
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;
}
}
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;
}
}
if(bOldDriveIsOffline == true) {
//cout << "offline drive found: " << itOld->getPath() << endl;
//TODO kill wipe thread
if(bOldDriveIsOffline == true)
{
//cout << "offline drive found: " << itOld->getPath() << endl;
//TODO kill wipe thread
}
}
}
pvecOldDrives->clear();
for (long unsigned int i=0; i<pvecNewDrives->size(); i++) {
pvecOldDrives->push_back((*pvecNewDrives)[i]);
}
for (long unsigned int i=0; i<pvecNewDrives->size(); i++)
{
pvecOldDrives->push_back((*pvecNewDrives)[i]);
}
}
/**
@ -173,18 +192,18 @@ void reHDD::searchDrives(vector <Drive>* pvecDrives)
FILE* outputfileHwinfo = popen("hwinfo --short --disk", "r");
if (outputfileHwinfo == NULL)
{
exit(EXIT_FAILURE);
}
{
exit(EXIT_FAILURE);
}
while ((getline(&cLine, &len, outputfileHwinfo)) != -1)
{
if (string(cLine).find("/dev/sd") != string::npos)
{
Drive* tmpDrive = new Drive(string(cLine).substr (2,8));
pvecDrives->push_back(*tmpDrive);
if (string(cLine).find("/dev/sd") != string::npos)
{
Drive* tmpDrive = new Drive(string(cLine).substr (2,8));
pvecDrives->push_back(*tmpDrive);
}
}
}
fclose(outputfileHwinfo);
}
@ -206,72 +225,72 @@ void reHDD::filterIgnoredDrives(vector <Drive>* pvecDrives)
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
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)
{
vector <Drive>::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->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)
vector <Drive>::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
{
exit(EXIT_FAILURE);
}
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;
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
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;
}
}
}
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;
}
}
}
}
}
/**
@ -284,18 +303,18 @@ void reHDD::printDrives(vector <Drive>* pvecDrives)
cout << "------------DRIVES---------------" << endl;
vector <Drive>::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
{
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;
}
{
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;
}
cout << "---------------------------------" << endl;
}
@ -308,8 +327,33 @@ void reHDD::addSMARTData(vector <Drive>* pvecDrives)
{
vector <Drive>::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
{
Drive* pTmpDrive = iterator_to_pointer<Drive, std::vector<Drive>::iterator > (it);
SMART::readSMARTData(pTmpDrive);
}
{
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;
}
}