diff --git a/doc/diagrams/refurbishingHddTool.drawio b/doc/diagrams/refurbishingHddTool.drawio
index 3667556..9a4d547 100644
--- a/doc/diagrams/refurbishingHddTool.drawio
+++ b/doc/diagrams/refurbishingHddTool.drawio
@@ -1 +1 @@
-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
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/doc/diagrams/refurbishingHddTool.pdf b/doc/diagrams/refurbishingHddTool.pdf
index 6989d9c..db66b70 100644
Binary files a/doc/diagrams/refurbishingHddTool.pdf and b/doc/diagrams/refurbishingHddTool.pdf differ
diff --git a/doc/diagrams/states.drawio b/doc/diagrams/states.drawio
new file mode 100644
index 0000000..661e8c0
--- /dev/null
+++ b/doc/diagrams/states.drawio
@@ -0,0 +1 @@
+5Vtbd6M2EP41fkwOkrg+Ojbb3Z5sNo192u4jiRWbXYxcWV7b/fUVRgIL4Usag0jykqBBkmFmvtE3I9FDg/nmNxotZl/JBCc9aE02PTTsQeh6Dv+bCba5ANl+LpjSeJKLQCkYxf9iIbSEdBVP8FLpyAhJWLxQhU8kTfETU2QRpWStdnsmifqri2iKNcHoKUp06V/xhM1yqQ+9Uv4Zx9OZ/GXgBvmdeSQ7izdZzqIJWe+JUNhDA0oIy6/mmwFOMt1JveTjPh24WzwYxSk7ZwD78uOPwA1nv4++jj9B9/4n+7a+ssXTLtlWvjGecAWIJqFsRqYkjZKwlN5QskonOJvW4q2yzy0hCy4EXPgDM7YV1oxWjHDRjM0TcRdvYvZ3NvzaEa3ve3eGGzHzrrGVjZTR7d6grPl9/145bNeS4/L3y17qoN6EaElW9AkfUZb0v4hOMTvSDxbW5ajAZI758/BxFCcRi3+pzxEJ/5wW/UoT8gthxRdYVMz7K0pW4pd60E344948E/7C+6Z2/1kReeNquTNWn3cA/mJT3uRX0+z/aNx/GMup+JPls+X3dB9KEg7QzFfWs5jh0SLaKXbNQ4TqCeJhMWV4c9w+uj7FACQRJyOMwNu6hGsgRLM9pNpWQwaANQaoqEcFUAsqcmxFRYGuIgBrdOQ2pSMANJ20EXbKEGJ7Sgy5hs6JMLJr3WMacwVgevnYgs6MLZ7R2KK7crtmMxX5z7WO/0rr7Ib2KY22ex0WJE7Zcm/m+0xQotsGKroBqhCBSn8HwWP9+UX+BKWfFK/y/10HaVFxtKNjlP8dzSj3D7G0PFK5qgyLDkOccNR1LowCcGYcbWytsRta7O++3YXnrvVcn5l8ySj5iQckIVl0TEmaYf85TpKKaM8k2bQC9dCWbTFxdj8zVsypeD+JpymXzePJZBdSIiF44obLgvFlaIRqXL/GtlabtnW6xyN49qYCwDNOJBzDKxKwXZVJBL53Yl1qmkq4Zy5WyMRiBQPVhaB1fLFCHjzWv5nFCnga9sLRoNbTbqNHnKjeoUWng3GMYh6Io8fdfJkTCOXxyZ2bnjM8BlpR7xCDe0WVYd9hjiDmIMQ5NXaQKNG8zBNK08ku5Pl5yT2wivELGAgiw7A3RUTPxTYIXgnuV0VlV4fP3Th8KPjcFi91urdDmOiQku6tdecmzY0RAj0ovZjswdrKzueHMOPao/A2HIyzyw9F/KCNVEO7ppmf3z3mZ1eW4Q4wP9fwEuD5Sg0JXFvINsz8gi4zv2rZ4RTzs+VOUavMT8fe+2F+7gnm5yDXVVQuNxO6SwSRHho/BhE8F+rwtSXJVwXp4B0QQW3pM04EZdnx4kxwyBngOPy4VND2K6Y2TgVBbd28XvsNLURZ+Msd52J1dKnCI3X0OkDBxrSs19GHb17LDuialvXVwHhwr2b5sA7xreY10HReg5BS0eZ5DSh6GMprpAG6mdigSkkbtZGoQL0a1K91nDeXpsBTaYqN1AM/Iop0OEnxzUK697KjLiaAC00At/DJeuCe7A8sp3mg2/qBPlmwHZD5ovZgRAu4p4Rxy5BsVGA1EgfQgcxVTH/FVyrL87qOfajnav0iu+0/clx3jwPVHX1oNcGFus9fdqujPxh/+fOjnXCBdsXOjunsFupnXER96I3nXtCvqLrmULLbZu4F38CekvncCxk/VhBU95TM516d3lSyobpj0UruhfRy0TvJvdABI5a5l1U5Jtn95MvMF04lpoOg8q0BKAssXce0kbTMBS9Ly6r9A7/5EGDrtL7YPHnnadmBk2VlWga9SkLR/W1kCYgOZ2kaWzKepSEdAxfehvyQaVp1E7LJNI03yw+QczCVX3Gj8D8=
\ No newline at end of file
diff --git a/doc/diagrams/states.png b/doc/diagrams/states.png
new file mode 100644
index 0000000..41c861c
Binary files /dev/null and b/doc/diagrams/states.png differ
diff --git a/ignoreDrives.conf b/ignoreDrives.conf
index aef73e8..ed2b36a 100644
--- a/ignoreDrives.conf
+++ b/ignoreDrives.conf
@@ -1,3 +1,3 @@
-/dev/sda:508ef27d-5039-4e8b-9e2c-22d7528b7149
-/dev/sdb:07f4ad14-c4b6-46e7-9cdf-3cfa9841d53d
/dev/sdc:4673974d-1af2-44fd-996b-a2d8e4c43d9a
+/dev/sda:508ef27d-5039-4e8b-9e2c-22d7528b7149
+/dev/sdb:32b66944-ffa0-40e9-817c-3f0c52eefaf4
diff --git a/include/delete.h b/include/delete.h
new file mode 100644
index 0000000..d1e1381
--- /dev/null
+++ b/include/delete.h
@@ -0,0 +1,25 @@
+/**
+ * @file delete.h
+ * @brief delete drive
+ * @author hendrik schutter
+ * @date 23.08.2020
+ */
+
+#ifndef DELETE_H_
+#define DELETE_H_
+
+#include "reHDD.h"
+
+class Delete
+{
+protected:
+
+public:
+ static void deleteDrive(Drive* drive);
+
+private:
+ Delete(void);
+
+};
+
+#endif // DELETE_H_
diff --git a/include/drive.h b/include/drive.h
index 3d7f3b1..5f7063a 100644
--- a/include/drive.h
+++ b/include/drive.h
@@ -12,6 +12,32 @@
class Drive
{
+
+public:
+ enum TaskState {NONE,
+ SHRED_SELECTED,
+ SHRED_ACTIVE,
+ DELETE_SELECTED,
+ DELETE_ACTIVE
+ } state;
+
+ bool bWasShredded = false;
+ bool bWasDeleteted = false;
+ bool bIsOffline = false;
+
+private:
+ string sPath;
+ string sModelFamily;
+ string sModelName;
+ string sSerial;
+ uint64_t u64Capacity = 0U; //in byte
+ uint32_t u32ErrorCount = 0U;
+ uint32_t u32PowerOnHours = 0U; //in hours
+ uint32_t u32PowerCycles = 0U;
+
+ double d32TaskPercentage = 0U; //in percent for Shred (1 to 100)
+
+
protected:
public:
@@ -37,15 +63,14 @@ public:
uint32_t powerOnHours,
uint32_t powerCycles);
-private:
- string sPath;
- string sModelFamily;
- string sModelName;
- string sSerial;
- uint64_t u64Capacity = 0U; //in byte
- uint32_t u32ErrorCount = 0U;
- uint32_t u32PowerOnHours = 0U; //in hours
- uint32_t u32PowerCycles = 0U;
+ string sCapacityToText();
+ string sErrorCountToText();
+ string sPowerOnHoursToText();
+ string sPowerCyclesToText();
+
+ void setTaskPercentage(double d32TaskPercentage);
+ double getTaskPercentage(void);
+
};
#endif // DRIVE_H_
\ No newline at end of file
diff --git a/include/logger/logger.h b/include/logger/logger.h
new file mode 100644
index 0000000..b6751ea
--- /dev/null
+++ b/include/logger/logger.h
@@ -0,0 +1,80 @@
+/**
+ * @file logger.h
+ * @brief cppSimpleLogger Header
+ * @author hendrik schutter
+ * @date 04.09.2020
+ */
+
+#ifndef LOGGER_H_
+#define LOGGER_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+#define MENU_LINE_SIZE 110 //Size of menu lines
+
+#ifndef LOG_PATH
+//#define LOG_PATH "./test.txt"
+#endif
+
+#ifndef DESCRIPTION
+#define DESCRIPTION "Software-Name - Copyright Company 2020" //use your values here
+#endif
+
+#ifndef DEVICE_ID
+#define DEVICE_ID "Device-Name" //use your values here
+#endif
+
+#ifndef SOFTWARE_VERSION
+#define SOFTWARE_VERSION "0.1.1.8" //use your values here
+#endif
+
+#ifndef HARDWARE_VERSION
+#define HARDWARE_VERSION "7.77.9" //use your values here
+#endif
+
+class Logger
+{
+private:
+ string logPath;
+ mutex mtxLog;
+
+ static bool instanceFlag;
+ static Logger *single;
+
+ string getTimestamp();
+ void writeLog(string s);
+ string getMacAddress();
+ string padStringMenu(char cBorder, string text, uint8_t u8LineLenght);
+ string menuLine(char cBorder, uint8_t u8LineLenght);
+ Logger();
+ ~Logger();
+
+public:
+
+ void info(string s);
+ void warning(string s);
+ void error(string s);
+ void newLine();
+
+ static Logger* logThis();
+};
+
+#endif // LOGGER_H_
\ No newline at end of file
diff --git a/include/reHDD.h b/include/reHDD.h
index a05e1ad..b1defd5 100644
--- a/include/reHDD.h
+++ b/include/reHDD.h
@@ -8,6 +8,28 @@
#ifndef REHDD_H_
#define REHDD_H_
+//#define DRYRUN
+
+#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
+
+// Logger Settings
+#define LOG_PATH "./reHDD.log"
+#define DESCRIPTION "reHDD - Copyright Hendrik Schutter 2020"
+#define DEVICE_ID "generic"
+#define SOFTWARE_VERSION "alpha"
+#define HARDWARE_VERSION "generic"
+
+#define LOG_LEVEL_HIGH //log everything, like drive scann thread
+#ifndef LOG_LEVEL_HIGH
+#define LOG_LEVEL_LOW //log only user actions and tasks
+#endif
+
#include
#include
#include
@@ -15,12 +37,27 @@
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
using namespace std;
#include "drive.h"
#include "smart.h"
-#include "wipe.h"
+#include "shred/shred.h"
+#include "delete.h"
+#include "tui.h"
+#include "logger/logger.h"
+
+extern Logger* logging;
template T* iterator_to_pointer(I i)
{
@@ -33,17 +70,24 @@ protected:
public:
reHDD(void);
- void app_logic();
+ static void app_logic();
private:
- vector vecDrives; //stores all drive data
-
- void searchDrives(vector * pvecDrives);
- void printDrives(vector * pvecDrives);
- void filterIgnoredDrives(vector * pvecDrives);
- void addSMARTData(vector * pvecDrives);
+ static void searchDrives(vector * pvecDrives);
+ static void printDrives(vector * pvecDrives);
+ static void filterIgnoredDrives(vector * pvecDrives);
+ static void filterNewDrives(vector * pvecOldDrives, vector * pvecNewDrives);
+ static void addSMARTData(vector * pvecDrives);
+ static void ThreadScannDevices();
+ static void ThreadUserInput();
+ static void ThreadShred();
+ static void handleArrowKey(TUI::UserInput userInput);
+ static void handleEnter();
+ static void handleESC();
+ static void handleAbort();
+ static Drive* getSelectedDrive();
};
-#endif // REHDD_H_
\ No newline at end of file
+#endif // REHDD_H_
diff --git a/include/shred/machdefs.h b/include/shred/machdefs.h
new file mode 100644
index 0000000..a99d0eb
--- /dev/null
+++ b/include/shred/machdefs.h
@@ -0,0 +1,19 @@
+#ifndef _MACHINE_DEFINITIONS_HEADER
+#define _MACHINE_DEFINITIONS_HEADER
+
+#include
+#include
+
+#undef MACHINE_16BIT
+#undef MACHINE_32BIT
+#undef MACHINE_64BIT
+
+#if UINTPTR_MAX == UINT32_MAX
+#define MACHINE_32BIT
+#elif UINTPTR_MAX == UINT64_MAX
+#define MACHINE_64BIT
+#elif UINTPTR_MAX == UINT16_MAX
+#define MACHINE_16BIT
+#endif
+
+#endif
diff --git a/include/shred/shred.h b/include/shred/shred.h
new file mode 100644
index 0000000..dcefdfc
--- /dev/null
+++ b/include/shred/shred.h
@@ -0,0 +1,98 @@
+/**
+ * @file shred.h
+ * @brief shred drive
+ * @author hendrik schutter
+ * @date 03.05.2020
+ */
+
+#ifndef SHRED_H_
+#define SHRED_H_
+
+#include "../reHDD.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include "tfdef.h"
+#include "tfcore.h"
+//#include "tfe.h"
+
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE
+#endif
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 700
+#endif
+#ifndef _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE
+#endif
+#ifndef _FILE_OFFSET_BITS
+#define _FILE_OFFSET_BITS 64
+#endif
+
+#ifndef _TFNG_STREAM_CIPHER_DEFS
+#define _TFNG_STREAM_CIPHER_DEFS
+#endif
+
+#define PROCESS_BLOCKP(x,k1,k2,k3,k4,k5,k6) \
+ do { \
+ KE_MIX(Y, X, k1 + k2, k3, TFS_KS01); \
+ KE_MIX(T, Z, k4 + x, k5 + k6, TFS_KS02); \
+ \
+ BE_MIX(X, T, TFS_BS01); BE_MIX(Z, Y, TFS_BS02); \
+ BE_MIX(X, Y, TFS_BS03); BE_MIX(Z, T, TFS_BS04); \
+ BE_MIX(X, T, TFS_BS05); BE_MIX(Z, Y, TFS_BS06); \
+ } while (0)
+
+#define PROCESS_BLOCKN(x,k1,k2,k3,k4,k5,k6) \
+ do { \
+ KE_MIX(Y, X, k1 + k2, k3, TFS_KS03); \
+ KE_MIX(T, Z, k4 + x, k5 + k6, TFS_KS04); \
+ \
+ BE_MIX(X, T, TFS_BS07); BE_MIX(Z, Y, TFS_BS08); \
+ BE_MIX(X, Y, TFS_BS09); BE_MIX(Z, T, TFS_BS10); \
+ BE_MIX(X, T, TFS_BS11); BE_MIX(Z, Y, TFS_BS12); \
+ } while (0)
+
+
+#define NOSIZE ((size_t)-1)
+
+#define XRET(x) if (!xret && xret < x) xret = x
+
+class Shred
+{
+protected:
+
+public:
+
+ Shred();
+ ~Shred();
+ void shredDrive(Drive* drive, int* ipSignalFd);
+
+private:
+
+ unsigned long blockcount = 0UL;
+ long blockcount_max;
+ double d32Percent;
+
+ inline double calcProgress();
+ inline void tfnge_init_iv(struct tfnge_stream *tfe, const void *key, const void *iv);
+ inline void tfnge_init(struct tfnge_stream *tfe, const void *key);
+ inline void tfng_encrypt_rawblk(TFNG_UNIT_TYPE *O, const TFNG_UNIT_TYPE *I, const TFNG_UNIT_TYPE *K);
+ inline void tfnge_emit(void *dst, size_t szdst, struct tfnge_stream *tfe);
+
+};
+
+#endif // SHRED_H_
diff --git a/include/shred/tfcore.h b/include/shred/tfcore.h
new file mode 100644
index 0000000..2d9d53e
--- /dev/null
+++ b/include/shred/tfcore.h
@@ -0,0 +1,51 @@
+#ifndef _THREEFISH_NOISE_GENERATOR_CIPHER_CORE_HEADER
+#define _THREEFISH_NOISE_GENERATOR_CIPHER_CORE_HEADER
+
+#ifndef _THREEFISH_NOISE_GENERATOR_CIPHER_DEFINITIONS_HEADER
+#error Threefish definitions header is required! Include tfdef.h first.
+#endif
+
+#define ROL(x, s, max) ((x << s) | (x >> (-s & (max-1))))
+#define ROR(x, s, max) ((x >> s) | (x << (-s & (max-1))))
+
+#define KE_MIX(x, y, k1, k2, sl) \
+ do { \
+ x += k1; \
+ y += x; \
+ y += k2; \
+ x = ROL(x, sl, TFNG_UNIT_BITS); \
+ x ^= y; \
+ } while (0)
+
+#define BE_MIX(x, y, sl) \
+ do { \
+ x += y; \
+ y = ROL(y, sl, TFNG_UNIT_BITS); \
+ y ^= x; \
+ } while (0)
+
+#define KD_MIX(x, y, k1, k2, sr) \
+ do { \
+ x ^= y; \
+ x = ROR(x, sr, TFNG_UNIT_BITS); \
+ y -= x; \
+ y -= k2; \
+ x -= k1; \
+ } while (0)
+
+#define BD_MIX(x, y, sr) \
+ do { \
+ y ^= x; \
+ y = ROR(y, sr, TFNG_UNIT_BITS); \
+ x -= y; \
+ } while (0)
+
+enum tfng_rotations
+{
+ TFS_KS01 = 7, TFS_KS02 = 25, TFS_KS03 = 19, TFS_KS04 = 7,
+ TFS_BS01 = 5, TFS_BS02 = 27, TFS_BS03 = 26, TFS_BS04 = 6,
+ TFS_BS05 = 14, TFS_BS06 = 11, TFS_BS07 = 24, TFS_BS08 = 18,
+ TFS_BS09 = 9, TFS_BS10 = 24, TFS_BS11 = 6, TFS_BS12 = 7,
+};
+
+#endif
diff --git a/include/shred/tfdef.h b/include/shred/tfdef.h
new file mode 100644
index 0000000..ea0bd0b
--- /dev/null
+++ b/include/shred/tfdef.h
@@ -0,0 +1,39 @@
+#ifndef _THREEFISH_NOISE_GENERATOR_CIPHER_DEFINITIONS_HEADER
+#define _THREEFISH_NOISE_GENERATOR_CIPHER_DEFINITIONS_HEADER
+
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE
+#endif
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+
+#include
+#include
+#include "machdefs.h"
+
+#if defined(MACHINE_64BIT)
+#define TFNG_UNIT_TYPE uint64_t
+#define TFNG_NR_BLOCK_BITS 256
+#define TFNG_NR_KEY_BITS 512
+#else
+#define TFNG_UNIT_TYPE uint32_t
+#define TFNG_NR_BLOCK_BITS 128
+#define TFNG_NR_KEY_BITS 256
+#endif
+
+#define TFNG_NR_BLOCK_UNITS 4
+#define TFNG_NR_KEY_UNITS 8
+
+#define TFNG_BYTE_TYPE uint8_t
+#define TFNG_SIZE_UNIT (sizeof(TFNG_UNIT_TYPE))
+#define TFNG_BLOCK_SIZE (TFNG_SIZE_UNIT * TFNG_NR_BLOCK_UNITS)
+#define TFNG_KEY_SIZE (TFNG_SIZE_UNIT * TFNG_NR_KEY_UNITS)
+
+#define TFNG_TO_BITS(x) ((x) * 8)
+#define TFNG_FROM_BITS(x) ((x) / 8)
+#define TFNG_MAX_BITS TFNG_NR_BLOCK_BITS
+#define TFNG_UNIT_BITS (TFNG_SIZE_UNIT * 8)
+
+#endif
diff --git a/include/tui.h b/include/tui.h
new file mode 100644
index 0000000..3d4c3a9
--- /dev/null
+++ b/include/tui.h
@@ -0,0 +1,67 @@
+/**
+ * @file tui.h
+ * @brief display user interface
+ * @author hendrik schutter
+ * @date 03.08.2020
+ */
+
+#ifndef TUI_H_
+#define TUI_H_
+
+#include "reHDD.h"
+
+#define COLOR_AREA_STDSCR 1
+#define COLOR_AREA_OVERVIEW 2
+#define COLOR_AREA_ENTRY 3
+#define COLOR_AREA_ENTRY_SELECTED 4
+#define COLOR_AREA_DETAIL 5
+
+class TUI
+{
+protected:
+
+public:
+
+ enum UserInput { UpKey, DownKey, Abort, Shred, Delete, Enter, ESC, Undefined};
+ struct MenuState
+ {
+ bool bAbort;
+ bool bShred;
+ bool bDelete;
+ bool bConfirmShred;
+ bool bConfirmDelete;
+ };
+
+ TUI(void);
+
+ static void initTUI();
+
+ void updateTUI(vector * pvecDrives, uint8_t u8SelectedEntry);
+
+ static enum UserInput readUserInput();
+
+private:
+ static string sCpuUsage;
+ static string sRamUsage;
+ static string sLocalTime;
+
+
+ WINDOW* overview;
+ WINDOW* systemview;
+ WINDOW* detailview;
+ WINDOW* menuview;
+ WINDOW* dialog;
+
+ 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 *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);
+
+ void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY);
+
+};
+#endif // TUI_H_
\ No newline at end of file
diff --git a/include/wipe.h b/include/wipe.h
deleted file mode 100644
index 21c8d5f..0000000
--- a/include/wipe.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * @file wipe.h
- * @brief wipe drive
- * @author hendrik schutter
- * @date 03.05.2020
- */
-
-#ifndef WIPE_H_
-#define WIPE_H_
-
-#include "reHDD.h"
-
-class Wipe
-{
-protected:
-
-public:
- static void wipeDrive(Drive* drive);
-
-private:
- Wipe(void);
-
-};
-
-#endif // WIPE_H_
\ No newline at end of file
diff --git a/makefile b/makefile
index c76a225..4e3c0b5 100644
--- a/makefile
+++ b/makefile
@@ -10,7 +10,7 @@ SRC_PATH = src
# Space-separated pkg-config libraries used by this project
LIBS =
# General compiler flags
-COMPILE_FLAGS = -std=c++11 -Wall -Wextra -g
+COMPILE_FLAGS = -std=c++17 -Wall -Wextra -g
# Additional release-specific flags
RCOMPILE_FLAGS = -D NDEBUG
# Additional debug-specific flags
@@ -18,7 +18,7 @@ DCOMPILE_FLAGS = -D DEBUG
# Add additional include paths
INCLUDES = include
# General linker settings
-LINK_FLAGS =
+LINK_FLAGS = -lpthread -lncurses
# Doc
DOCDIR = doc
#### END PROJECT SETTINGS ####
diff --git a/out.txt b/out.txt
new file mode 100644
index 0000000..60fffd1
--- /dev/null
+++ b/out.txt
@@ -0,0 +1 @@
+date
diff --git a/shred_dummy.sh b/shred_dummy.sh
new file mode 100644
index 0000000..afc4268
--- /dev/null
+++ b/shred_dummy.sh
@@ -0,0 +1,12 @@
+#! /bin/bash
+
+echo "starting SHRED DUMMY"
+
+for i in {0..100..10}
+do
+ #echo "DUMMY shred $i%"
+ echo $date > out.txt
+ sleep 1
+done
+
+echo "finished SHRED DUMMY"
diff --git a/src/delete.cpp b/src/delete.cpp
new file mode 100644
index 0000000..a34db6e
--- /dev/null
+++ b/src/delete.cpp
@@ -0,0 +1,41 @@
+/**
+ * @file delete.cpp
+ * @brief delete drive
+ * @author hendrik schutter
+ * @date 23.08.2020
+ */
+
+#include "../include/reHDD.h"
+
+/**
+ * \brief delete drive with wipefs
+ * \param pointer of Drive instance
+ * \return void
+ */
+void Delete::deleteDrive(Drive* drive)
+
+{
+ size_t len = 0; //lenght of found line
+ char* cLine = NULL; //found line
+
+#ifndef DRYRUN
+ string sCMD = ("wipefs -af ");
+ sCMD.append(drive->getPath());
+#endif
+
+#ifdef DRYRUN
+ //cout << "dryrun for " << drive->getPath() << endl;
+ string sCMD = ("echo");
+#endif
+
+ const char* cpComand = sCMD.c_str();
+ //cout << "delete: " << cpComand << endl;
+
+ FILE* deleteCmdOutput = popen(cpComand, "r");
+
+ while ((getline(&cLine, &len, deleteCmdOutput)) != -1)
+ {
+ //wipefs running
+ }
+ fclose(deleteCmdOutput);
+}
diff --git a/src/drive.cpp b/src/drive.cpp
index c597b1e..18441ff 100644
--- a/src/drive.cpp
+++ b/src/drive.cpp
@@ -46,6 +46,59 @@ uint32_t Drive::getPowerCycles(void)
return u32PowerCycles;
}
+string Drive::sCapacityToText()
+{
+ if(getCapacity() <= (999*1000000000UL))
+ {
+ // Less or even 999 GB --> GB
+ return to_string(getCapacity() / 1000000000UL) + " GB";
+ }
+ else
+ {
+ // More 999 GB --> TB
+ return to_string(getCapacity() / 1000000000000UL) + " TB";
+ }
+ return "ERROR";
+}
+
+string Drive::sErrorCountToText()
+{
+ return to_string(getErrorCount());
+}
+
+
+string Drive::sPowerOnHoursToText()
+{
+ double dYears = 0U;
+ uint32_t u32Hours = getPowerOnHours();
+ stringstream stream;
+
+ dYears = (double) ((double)u32Hours/(double)8760U);
+
+ stream << fixed << setprecision(2) << dYears;
+ string sRet = to_string(getPowerOnHours()) + " hours or " + stream.str() + " years";
+
+ return sRet;
+}
+
+string Drive::sPowerCyclesToText()
+{
+ return to_string(getPowerCycles());
+}
+
+void Drive::setTaskPercentage(double d32TaskPercentage)
+{
+ if(d32TaskPercentage <= 100)
+ {
+ this->d32TaskPercentage = d32TaskPercentage;
+ }
+}
+double Drive::getTaskPercentage(void)
+{
+ return this->d32TaskPercentage;
+}
+
+
/**
* \brief set S.M.A.R.T. values in model
* \param string modelFamily
diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp
new file mode 100644
index 0000000..5708359
--- /dev/null
+++ b/src/logger/logger.cpp
@@ -0,0 +1,235 @@
+/**
+ * @file logger.cpp
+ * @brief cppSimpleLogger implementation
+ * @author hendrik schutter
+ * @date 04.09.2020
+ */
+
+
+#include "../../include/reHDD.h" //for logger settings
+#include "../../include/logger/logger.h"
+
+using namespace std;
+
+string version = "0.2.1"; //logger version
+
+bool Logger::instanceFlag = false;
+Logger* Logger::single = NULL;
+
+/**
+ * \brief create new logger instance
+ * \param path to log file
+ * \param struct with data
+ * \return instance of Logger
+ */
+Logger::Logger()
+{
+ this->logPath = LOG_PATH;
+
+ writeLog(menuLine('+', MENU_LINE_SIZE));
+ writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
+
+ writeLog(padStringMenu('+', ("Device: " + string(DEVICE_ID) + " -- " + string(DESCRIPTION)), MENU_LINE_SIZE));
+ writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
+
+ writeLog(padStringMenu('+', ("Software ID: " + string(SOFTWARE_VERSION) + " -- Build time: " + __DATE__ + " " + __TIME__), MENU_LINE_SIZE));
+ writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
+
+ writeLog(padStringMenu('+', ("Hardware ID: " + string(HARDWARE_VERSION) + " -- MAC: " + getMacAddress()), MENU_LINE_SIZE));
+ writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
+
+ writeLog(padStringMenu('+', ("cppSimpleLogger -- available from https://git.mosad.xyz/localhorst/cppSimpleLogger -- Version: " + version), MENU_LINE_SIZE));
+ writeLog(padStringMenu('+', " ", MENU_LINE_SIZE));
+
+ writeLog(menuLine('+', MENU_LINE_SIZE));
+ newLine();
+ info("Created new log file");
+ newLine();
+}
+
+/**
+ * \brief deconstructor
+ * \return void
+ */
+Logger::~Logger()
+{
+ instanceFlag = false;
+}
+
+/**
+ * \brief log info
+ * \param log-text as string
+ * \return void
+ */
+void Logger::info(string s)
+{
+ string tmp = getTimestamp() + " [INFO] " + s;
+ writeLog(tmp);
+}
+
+/**
+ * \brief log warning
+ * \param log-text as string
+ * \return void
+ */
+void Logger::warning(string s)
+{
+ string tmp = getTimestamp() + " [WARNING] " + s;
+ writeLog(tmp);
+}
+
+/**
+ * \brief log error
+ * \param log-text as string
+ * \return void
+ */
+void Logger::error(string s)
+{
+ string tmp = getTimestamp() + " [ERROR] " + s;
+ writeLog(tmp);
+}
+
+/**
+ * \brief write to log file
+ * \param log as string
+ * \return void
+ */
+void Logger::writeLog(string s)
+{
+ ofstream logFile;
+ Logger::mtxLog.lock(); //lock this section for other threads
+ logFile.open(this->logPath, ios_base::app);
+
+ logFile << (s + "\n"); //append to existing file
+
+ logFile.close();
+ Logger::mtxLog.unlock(); //unlock this section for other threads
+}
+
+/**
+ * \brief write new line to log file
+ * \return void
+ */
+void Logger::newLine()
+{
+ writeLog(" ");
+}
+
+/**
+ * \brief get timestamp (system time) as string
+ * \param void
+ * \return string timestamp (formatted)
+ */
+string Logger::getTimestamp()
+{
+ struct tm * timeinfo;
+ struct timeval tv;
+ int millisec;
+ char cpDate [80];
+ char buffer [120];
+
+ gettimeofday(&tv, NULL);
+ millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
+ if (millisec>=1000) // Allow for rounding up to nearest second
+ {
+ millisec -=1000;
+ tv.tv_sec++;
+ }
+ timeinfo = localtime(&tv.tv_sec);
+ strftime (cpDate,80,"%d/%m/%Y %T",timeinfo);
+ sprintf(buffer, "%s.%03d", cpDate, millisec);
+ return buffer;
+}
+
+/**
+ * \brief get MAC address (system first eth0 interface) as string
+ * \param void
+ * \return string MAC address (formatted)
+ */
+string Logger::getMacAddress()
+{
+ struct ifreq ifr;
+ int s = socket(AF_INET, SOCK_STREAM,0);
+
+ strcpy(ifr.ifr_name, "eth0");
+ if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0)
+ {
+ strcpy(ifr.ifr_name, "eno1");
+
+ }
+
+ unsigned char *hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data;
+ char buffer [80];
+ sprintf(buffer,"%02X:%02X:%02X:%02X:%02X:%02X", hwaddr[0], hwaddr[1], hwaddr[2],
+ hwaddr[3], hwaddr[4], hwaddr[5]);
+ close(s);
+ string tmp = buffer;
+ return tmp;
+}
+
+/**
+ * \brief format menu text in center
+ * \param char for border
+ * \param menu text
+ * \param size of menu line
+ * \return string menu line
+ */
+string Logger::padStringMenu(char cBorder, string text, uint8_t u8LineLenght)
+{
+ string result(1,cBorder);
+ uint8_t u8TextSize = text.length();
+ uint8_t u8Padding = ((u8LineLenght-u8TextSize)/2);
+
+ for(uint8_t i = 0 ; i < u8Padding; i++)
+ {
+ result.append(" ");
+ }
+
+ result.append(text);
+
+ while((uint8_t)result.length() < (u8LineLenght-1))
+ {
+
+ result.append(" ");
+ }
+
+ result.append(string(1, cBorder));
+ return result;
+}
+
+/**
+ * \brief format a separator
+ * \param char for border
+ * \param size of menu line
+ * \return string menu line
+ */
+string Logger::menuLine(char cBorder, uint8_t u8LineLenght)
+{
+ string result(1,cBorder);
+
+ while((uint8_t)result.length() < u8LineLenght)
+ {
+ result.append(string(1, cBorder));
+ }
+ return result;
+}
+
+/**
+ * \brief return a instance of the logger
+ * \return logger obj
+ */
+Logger* Logger::logThis()
+{
+ if (!instanceFlag)
+ {
+ single = new Logger(); //create new obj
+ instanceFlag = true;
+ return single;
+ }
+ else
+ {
+ return single; //return existing obj
+ }
+}
+
+
diff --git a/src/main.cpp b/src/main.cpp
index 4978cb8..96a915e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -14,7 +14,7 @@
*/
int main(void)
{
- cout << "refurbishingHddTool" << endl;
+ // cout << "refurbishingHddTool" << endl;
reHDD* app = new reHDD();
app->app_logic();
diff --git a/src/reHDD.cpp b/src/reHDD.cpp
index ec03080..1b55a6e 100644
--- a/src/reHDD.cpp
+++ b/src/reHDD.cpp
@@ -7,6 +7,24 @@
#include "../include/reHDD.h"
+static int fdNewDrivesInformPipe[2];//File descriptor for pipe that informs if new drives are found
+
+static int fdShredInformPipe[2];//File descriptor for pipe that informs if a wipe thread signals
+
+static std::mutex mxScannDrives;
+
+vector vecNewDrives; //store found drives that are updated every 5sec
+
+static vector vecDrives; //stores all drive data from scann thread
+
+TUI *ui;
+
+static uint8_t u8SelectedEntry;
+
+static fd_set selectSet;
+
+//static struct TUI::MenuState menustate;
+
/**
* \brief app constructor
* \param void
@@ -14,7 +32,9 @@
*/
reHDD::reHDD(void)
{
- cout << "created app" << endl;
+ u8SelectedEntry = 0U;
+
+ vecDrives.reserve(128);
}
/**
@@ -24,24 +44,211 @@ reHDD::reHDD(void)
*/
void reHDD::app_logic(void)
{
- cout << "app logic" << endl;
+ ui = new TUI();
+ ui->initTUI();
- searchDrives(&vecDrives); //search for new drives and store them in list
- filterIgnoredDrives(&vecDrives); //filter out ignored drives
- addSMARTData(&vecDrives); //add S.M.A.R.T. Data to the drives
- printDrives(&vecDrives); //print currently attached drives
+ pipe(fdNewDrivesInformPipe);
+ pipe(fdShredInformPipe);
- size_t u64SelectedDriveIndex = 0U;
- size_t u64DriveVecSize = (vecDrives.size());
+ thread thDevices(ThreadScannDevices); //start thread that scanns for drives
+ thread thUserInput(ThreadUserInput); //start thread that reads user input
- cout << "Select drive to wipe:" << endl;
- cin >> u64SelectedDriveIndex;
- cout << "Selected drive index: " << u64SelectedDriveIndex << endl;
+ while(1)
+ {
+ FD_ZERO(&selectSet);
+ FD_SET(fdNewDrivesInformPipe[0], &selectSet);
+ FD_SET(fdShredInformPipe[0], &selectSet);
- if(u64SelectedDriveIndex < (u64DriveVecSize)) {
- Wipe::wipeDrive(&vecDrives[u64SelectedDriveIndex]);
- }
+ select(FD_SETSIZE, &selectSet, NULL, NULL, NULL);
+ 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))
+ {
+ char dummy;
+ read (fdShredInformPipe[0],&dummy,1);
+ }
+ ui->updateTUI(&vecDrives, u8SelectedEntry);
+ } //endless loop
+ thDevices.join();
+ thUserInput.join();
+}
+
+Drive* reHDD::getSelectedDrive()
+{
+ if(u8SelectedEntry < vecDrives.size() )
+ {
+ return &(vecDrives.at(u8SelectedEntry));
+ }
+ else
+ {
+ Logger::logThis()->warning("selected drive not present");
+ return {};
+ }
+}
+
+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
+ mxScannDrives.unlock();
+ write(fdNewDrivesInformPipe[1], "A",1);
+ sleep(5); //sleep 5 sec
+ }
+}
+
+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, u8SelectedEntry);
+ break;
+ case TUI::UserInput::UpKey:
+ //cout << "Up" << endl;
+ handleArrowKey(TUI::UserInput::UpKey);
+ ui->updateTUI(&vecDrives, u8SelectedEntry);
+ break;
+ case TUI::UserInput::Undefined:
+ //cout << "Undefined" << endl;
+ break;
+ case TUI::UserInput::Abort:
+ //cout << "Abort" << endl;
+ handleAbort();
+ ui->updateTUI(&vecDrives, u8SelectedEntry);
+ break;
+ case TUI::UserInput::Delete:
+ //cout << "Delete" << endl;
+
+ if (getSelectedDrive() != nullptr)
+ {
+ if(getSelectedDrive()->state == Drive::NONE)
+ {
+ getSelectedDrive()->state = Drive::DELETE_SELECTED;
+ }
+ }
+ ui->updateTUI(&vecDrives, u8SelectedEntry);
+ break;
+ case TUI::UserInput::Shred:
+ //cout << "Shred" << endl;
+
+ if (getSelectedDrive() != nullptr)
+ {
+ if(getSelectedDrive()->state == Drive::NONE)
+ {
+ getSelectedDrive()->state = Drive::SHRED_SELECTED;
+ }
+ }
+ ui->updateTUI(&vecDrives, u8SelectedEntry);
+ break;
+ case TUI::UserInput::Enter:
+ //cout << "Enter" << endl;
+ handleEnter();
+ ui->updateTUI(&vecDrives, u8SelectedEntry);
+ break;
+ case TUI::UserInput::ESC:
+ //cout << "ESC" << endl;
+ handleESC();
+ ui->updateTUI(&vecDrives, u8SelectedEntry);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void reHDD::ThreadShred()
+{
+ if (getSelectedDrive() != nullptr)
+ {
+ 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);
+ }
+}
+
+void reHDD::filterNewDrives(vector * pvecOldDrives, vector * pvecNewDrives)
+{
+ vector ::iterator itOld; //Iterator for current (old) drive list
+ vector ::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();)
+ {
+ if(itOld->bIsOffline == true)
+ {
+ Logger::logThis()->warning("Offline drive found: " + itOld->getPath());
+ itOld = pvecOldDrives->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
+ u8SelectedEntry = 0U;
+ }
+ */
+ }
+ else
+ {
+ ++itOld;
+ }
+ }
+
+ //search offline drives and mark them
+ for (itOld = pvecOldDrives->begin(); itOld != pvecOldDrives->end(); ++itOld)
+ {
+ itOld->bIsOffline = true; //set offline befor seachring in the new list
+ for (itNew = pvecNewDrives->begin(); itNew != pvecNewDrives->end();)
+ {
+ if(itOld->getSerial() == itNew->getSerial())
+ {
+ itOld->bIsOffline = false; //drive is still attached
+#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
+ }
+ else
+ {
+ ++itNew;
+ }
+ }
+ }
+
+ //mark offline old drives
+ for (itOld = pvecOldDrives->begin(); itOld != pvecOldDrives->end(); ++itOld)
+ {
+ if(itOld->bIsOffline == true)
+ {
+ //cout << "offline drive found: " << itOld->getPath() << endl;
+ Logger::logThis()->warning("Mark offline drive found: " + itOld->getPath());
+ itOld->state = Drive::NONE; //clear state --> shred task will terminate
+ }
+ }
+
+ //add new drives to drive list
+ for (itNew = pvecNewDrives->begin(); itNew != pvecNewDrives->end(); ++itNew)
+ {
+ pvecOldDrives->push_back(pvecNewDrives->at(itNew - pvecNewDrives->begin()));
+ Logger::logThis()->info("Add new drive: " + itNew->getModelName());
+ }
+ pvecNewDrives->clear();
}
/**
@@ -51,25 +258,28 @@ void reHDD::app_logic(void)
*/
void reHDD::searchDrives(vector * pvecDrives)
{
- cout << "search drives ..." << endl;
+ // cout << "search drives ..." << endl;
+ Logger::logThis()->info("--> search drives <--");
char * cLine = NULL;
size_t len = 0;
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));
+ tmpDrive->state = Drive::NONE;
+ tmpDrive->bIsOffline = false;
+ pvecDrives->push_back(*tmpDrive);
+ }
}
- }
fclose(outputfileHwinfo);
}
@@ -89,74 +299,73 @@ void reHDD::filterIgnoredDrives(vector * 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
+ 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)
- {
- auto it = pvecDrives->begin();
- while (it != pvecDrives->end())
{
- it++;
- string sUUID;
- if (!get<0>(row).compare(it->getPath())) //find same drive based on path
- {
- // cout << "Same drive path found" << endl;
- 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 ::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;
+ 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
+#ifdef LOG_LEVEL_HIGH
+ Logger::logThis()->info("same uuid found than in ignore file --> ignore this drive: " + it->getPath());
+#endif
+ it = pvecDrives->erase(it);
+ it--;
+ }
+ }
}
- else
- {
- // same uuid found than in ignore file --> ignore this drive
- it = pvecDrives->erase(it);
- }
-
- }
}
- }
}
/**
@@ -166,22 +375,33 @@ void reHDD::filterIgnoredDrives(vector * pvecDrives)
*/
void reHDD::printDrives(vector * pvecDrives)
{
- cout << "------------DRIVES---------------" << endl;
+#ifdef LOG_LEVEL_HIGH
+ Logger::logThis()->info("------------DRIVES---------------");
+ //cout << "------------DRIVES---------------" << endl;
vector ::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 << "---------------------------------" << 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;*/
+
+ 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());
+ }
+ Logger::logThis()->info("---------------------------------");
+ //cout << "---------------------------------" << endl;
+#endif
}
/**
@@ -193,8 +413,97 @@ void reHDD::addSMARTData(vector * pvecDrives)
{
vector ::iterator it;
for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
- {
- Drive* pTmpDrive = iterator_to_pointer::iterator > (it);
- SMART::readSMARTData(pTmpDrive);
- }
-}
\ No newline at end of file
+ {
+ Drive* pTmpDrive = iterator_to_pointer::iterator > (it);
+ SMART::readSMARTData(pTmpDrive);
+ }
+}
+
+void reHDD::handleArrowKey(TUI::UserInput userInput)
+{
+ int8_t u8EntrySize = (int8_t) vecDrives.size();
+ switch (userInput)
+ {
+ case TUI::UserInput::DownKey:
+ u8SelectedEntry++;
+ if(u8SelectedEntry >= u8EntrySize)
+ {
+ u8SelectedEntry = 0;
+ }
+ break;
+ case TUI::UserInput::UpKey:
+ if(u8SelectedEntry == 0)
+ {
+ u8SelectedEntry = (u8EntrySize-1);
+ }
+ else
+ {
+ u8SelectedEntry--;
+ }
+ break;
+ default:
+ u8SelectedEntry = 0;
+ break;
+ }
+
+ Logger::logThis()->info("ArrowKey - selected drive: " + to_string(u8SelectedEntry));
+}
+
+void reHDD::handleEnter()
+{
+ if (getSelectedDrive() != nullptr)
+ {
+ if(getSelectedDrive()->state == Drive::TaskState::SHRED_SELECTED)
+ {
+ Logger::logThis()->info("Started shred for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
+ getSelectedDrive()->state = Drive::TaskState::SHRED_ACTIVE;
+ //task for drive is running --> don´t show more task options
+ thread(ThreadShred).detach();
+ }
+
+ if(getSelectedDrive()->state == Drive::TaskState::DELETE_SELECTED)
+ {
+ 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());
+ }
+ }
+}
+
+void reHDD::handleESC()
+{
+ if (getSelectedDrive() != nullptr)
+ {
+ if(getSelectedDrive()->state == Drive::TaskState::SHRED_SELECTED)
+ {
+ getSelectedDrive()->state = Drive::TaskState::NONE;
+ //task for drive is selected --> remove selection
+ }
+
+ if(getSelectedDrive()->state == Drive::TaskState::DELETE_SELECTED)
+ {
+ getSelectedDrive()->state = Drive::TaskState::NONE;
+ //task for drive is selected --> remove selection
+ }
+ }
+}
+
+void reHDD::handleAbort()
+{
+ if (getSelectedDrive() != nullptr)
+ {
+ if(getSelectedDrive()->state == Drive::SHRED_ACTIVE || getSelectedDrive()->state == Drive::DELETE_ACTIVE )
+ {
+ getSelectedDrive()->state = Drive::NONE;
+ Logger::logThis()->info("Abort-Shred-Signal for: " + getSelectedDrive()->getModelName() + "-" + getSelectedDrive()->getSerial());
+ //task for drive is running --> remove selection
+ }
+ }
+}
+
+
+
diff --git a/src/shred/shred.cpp b/src/shred/shred.cpp
new file mode 100644
index 0000000..d5b3969
--- /dev/null
+++ b/src/shred/shred.cpp
@@ -0,0 +1,404 @@
+/**
+ * @file shred.cpp
+ * @brief shred drive
+ * @author hendrik schutter
+ * @date 03.05.2020
+ */
+
+#include "../../include/reHDD.h"
+#ifndef DRYRUN
+static char *randsrc = (char*) "/dev/urandom";
+static int force = 0, rmf = 0, zrf = 0, noround = 0, verbose = 0, syncio = 0, alwaysrand = 0, reqrand = 0;
+
+static char sfbuf[PATH_MAX*2];
+
+struct tfnge_stream
+{
+ TFNG_UNIT_TYPE key[TFNG_NR_KEY_UNITS];
+ TFNG_UNIT_TYPE iv[TFNG_NR_BLOCK_UNITS];
+ TFNG_BYTE_TYPE carry_block[TFNG_BLOCK_SIZE];
+ size_t carry_bytes;
+};
+
+static struct tfnge_stream tfnge;
+
+Shred::Shred()
+{
+
+}
+
+
+Shred::~Shred()
+{
+
+}
+
+
+#endif
+/**
+ * \brief shred drive with shred
+ * \param pointer of Drive instance
+ * \return void
+ */
+void Shred::shredDrive(Drive* drive, int* ipSignalFd)
+{
+#ifdef DRYRUN
+ for(int i = 0; i<=100; i++)
+ {
+ if(drive->state != Drive::SHRED_ACTIVE)
+ {
+ return;
+ }
+ drive->setTaskPercentage(i+0.05);
+ write(*ipSignalFd, "A",1);
+
+ usleep(20000);
+ }
+#endif
+
+#ifndef DRYRUN
+
+ struct stat st;
+ char *buf, *s, *d, rc = 0;
+ int f, rsf;
+ int xret = 0, pat = 0, last = 0, special = 0, iIteration = 0;
+ size_t blksz = 0, x, y;
+ size_t l, ll = NOSIZE;
+
+ const char *cpDrivePath = drive->getPath().c_str();
+
+ blockcount_max = SHRED_ITERATIONS*(drive->getCapacity()/4096);
+
+#ifdef LOG_LEVEL_HIGH
+ Logger::logThis()->info("Shred-Task: Max-BlockCount: " + to_string(blockcount_max) + " - Drive: " + drive->getSerial());
+#endif
+
+ d32Percent = 0U;
+
+ rsf = open(randsrc, O_RDONLY | O_LARGEFILE);
+ if (rsf == -1)
+ {
+ perror(randsrc);
+ exit(1);
+ }
+
+ special = pat = 0;
+ iIteration = SHRED_ITERATIONS;
+ if (verbose) fprintf(stderr, "destroying %s ...\n", cpDrivePath);
+
+ if (stat(cpDrivePath, &st) == -1)
+ {
+ perror(cpDrivePath);
+ XRET(1);
+ goto _return;
+ }
+ if (!blksz) blksz = (size_t)st.st_blksize;
+
+ else l = ll = st.st_size;
+ if (l == 0 && !S_ISREG(st.st_mode)) special = 1;
+ memset(&st, 0, sizeof(struct stat));
+
+ if (force) if (chmod(cpDrivePath, S_IRUSR|S_IWUSR) == -1)
+ {
+ perror(cpDrivePath);
+ XRET(1);
+ }
+ f = open(cpDrivePath, O_WRONLY | O_LARGEFILE | O_NOCTTY | syncio);
+ if (f == -1)
+ {
+ XRET(1);
+ perror(cpDrivePath);
+ goto _return;
+ }
+
+ buf = (char*) malloc(blksz);
+ if (!buf)
+ {
+ perror("malloc");
+ XRET(2);
+ fprintf(stderr, "Continuing with fixed buffer (%zu bytes long)\n", sizeof(sfbuf));
+ buf = sfbuf;
+ blksz = sizeof(sfbuf);
+ }
+ memset(buf, 0, blksz);
+
+ if (read(rsf, buf, blksz) <= 0) fprintf(stderr, "%s: read 0 bytes (wanted %zu)\n", randsrc, blksz);
+ tfnge_init(&tfnge, buf);
+
+ //iteration loop
+ while (iIteration)
+ {
+ lseek(f, 0L, SEEK_SET);
+
+ if (iIteration <= 1 && zrf)
+ {
+ pat = 1;
+ rc = 0;
+ }
+ else if (iIteration == SHRED_ITERATIONS && reqrand)
+ {
+ pat = 0;
+ }
+ else if (!alwaysrand)
+ {
+ if (read(rsf, &rc, 1) <= 0) fprintf(stderr, "%s: read 0 bytes (wanted 1)\n", randsrc);
+ pat = rc%2;
+ if (read(rsf, &rc, 1) <= 0) fprintf(stderr, "%s: read 0 bytes (wanted 1)\n", randsrc);
+ }
+ else pat = 0;
+
+ if (verbose)
+ {
+ if (pat) fprintf(stderr, "iteration (pat) %d (%02hhx%02hhx%02hhx) ...\n", SHRED_ITERATIONS-iIteration+1, rc, rc, rc);
+ else fprintf(stderr, "iteration (!pat) %d (random) ...\n", SHRED_ITERATIONS-iIteration+1);
+ }
+ // write block loop
+ while (1)
+ {
+ if(drive->state != Drive::SHRED_ACTIVE)
+ {
+ drive->setTaskPercentage(0);
+ d32Percent = 0.00;
+ blockcount = 0;
+ blockcount_max = 0;
+ Logger::logThis()->info("Aborted shred for: " + drive->getModelName() + "-" + drive->getSerial());
+ goto _return;
+ }
+
+ double d32TmpPercent = calcProgress();
+
+
+
+ if((d32TmpPercent-d32Percent) >= 0.09)
+ {
+ drive->setTaskPercentage(d32TmpPercent);
+ d32Percent = d32TmpPercent;
+#ifdef LOG_LEVEL_HIGH
+ Logger::logThis()->info("Shred-Task: BlockCount: " + to_string(blockcount) + " - progress: " + to_string(d32Percent) + " - Drive: " + drive->getSerial());
+#endif
+ write(*ipSignalFd, "A",1);
+ }
+
+ if (!pat)
+ {
+ tfnge_emit(buf, blksz, &tfnge);
+ }
+ else
+ {
+ memset(buf, rc, blksz);
+ }
+
+ if (l <= blksz && !special)
+ {
+ last = 1;
+ }
+ errno = 0;
+ l -= write(f, buf, (noround && last) ? l : blksz);
+ if (errno)
+ {
+ perror(cpDrivePath);
+ errno = 0;
+ break;
+ }
+
+ if (last)
+ {
+ last = 0;
+ break;
+ }
+ }
+ // write block loop end
+ l = ll;
+ fdatasync(f);
+ iIteration--;
+ } //iteration loop end
+
+ if (rmf)
+ {
+ close(f);
+ f = open(cpDrivePath, O_WRONLY | O_TRUNC | O_LARGEFILE | O_NOCTTY | syncio);
+ if (verbose) fprintf(stderr, "removing %s ...\n", cpDrivePath);
+ x = strnlen(cpDrivePath, sizeof(sfbuf)/2);
+ s = sfbuf+(sizeof(sfbuf)/2);
+ memcpy(sfbuf, cpDrivePath, x);
+ *(sfbuf+x) = 0;
+ d = strrchr(sfbuf, '/');
+ if (d)
+ {
+ d++;
+ y = d-sfbuf;
+ memset(d, '0', x-(d-sfbuf));
+ }
+ else
+ {
+ y = 0;
+ memset(sfbuf, '0', x);
+ }
+ memcpy(s, sfbuf, x);
+ *(s+x) = 0;
+
+ /* Somehow I need to rename original to destination */
+ if (access(s, R_OK) != -1)
+ {
+ fprintf(stderr, "%s already exists!\n", s);
+ unlink(cpDrivePath);
+ goto _return;
+ }
+ if (verbose) fprintf(stderr, "%s -> %s\n", cpDrivePath, s);
+ if (rename(cpDrivePath, s) == -1)
+ {
+ perror(s);
+ goto _return;
+ }
+
+ while (x > y+1)
+ {
+ *(sfbuf+x) = 0;
+ x--;
+ *(s+x) = 0;
+ if (access(s, R_OK) != -1)
+ {
+ fprintf(stderr, "%s already exists!\n", s);
+ unlink(sfbuf);
+ goto _return;
+ }
+ if (verbose) fprintf(stderr, "%s -> %s\n", sfbuf, s);
+ if (rename(sfbuf, s) == -1)
+ {
+ perror(s);
+ goto _return;
+ }
+ }
+
+ if (verbose) fprintf(stderr, "remove %s\n", s);
+ unlink(s);
+ if (verbose) fprintf(stderr, "done away with %s.\n", cpDrivePath);
+ }
+
+ tfnge_emit(NULL, 0, &tfnge);
+ if (buf && buf != sfbuf) free(buf);
+ if (f != -1) close(f);
+
+_return:
+ optind++;
+ close(rsf);
+#endif
+ if(drive->state == Drive::SHRED_ACTIVE)
+ {
+ drive->bWasShredded = true;
+ drive->state= Drive::NONE;
+ drive->setTaskPercentage(0);
+ Logger::logThis()->info("Finished shred for: " + drive->getModelName() + "-" + drive->getSerial());
+ }
+}
+#ifndef DRYRUN
+
+double Shred::calcProgress()
+{
+ blockcount++;
+ return ((((double)blockcount/(double)blockcount_max))*100);
+}
+
+
+void Shred::tfnge_init_iv(struct tfnge_stream *tfe, const void *key, const void *iv)
+{
+ memset(tfe, 0, sizeof(struct tfnge_stream));
+ memcpy(tfe->key, key, TFNG_KEY_SIZE);
+ if (iv) memcpy(tfe->iv, iv, TFNG_BLOCK_SIZE);
+ tfe->carry_bytes = 0;
+}
+
+void Shred::tfnge_init(struct tfnge_stream *tfe, const void *key)
+{
+ tfnge_init_iv(tfe, key, NULL);
+}
+
+void Shred::tfng_encrypt_rawblk(TFNG_UNIT_TYPE *O, const TFNG_UNIT_TYPE *I, const TFNG_UNIT_TYPE *K)
+{
+ TFNG_UNIT_TYPE X, Y, Z, T;
+ TFNG_UNIT_TYPE K0, K1, K2, K3;
+ TFNG_UNIT_TYPE K4, T0, T1, T2;
+
+ X = I[0];
+ Y = I[1];
+ Z = I[2];
+ T = I[3];
+
+ K0 = K[0];
+ K1 = K[1];
+ K2 = K[2];
+ K3 = K[3];
+ K4 = K[4];
+ T0 = K[5];
+ T1 = K[6];
+ T2 = K[7];
+
+ PROCESS_BLOCKP( 1,K1,T0,K0,K3,K2,T1);
+ PROCESS_BLOCKN( 2,K2,T1,K1,K4,K3,T2);
+ PROCESS_BLOCKP( 3,K3,T2,K2,K0,K4,T0);
+ PROCESS_BLOCKN( 4,K4,T0,K3,K1,K0,T1);
+
+ PROCESS_BLOCKP( 5,K0,T1,K4,K2,K1,T2);
+ PROCESS_BLOCKN( 6,K1,T2,K0,K3,K2,T0);
+ PROCESS_BLOCKP( 7,K2,T0,K1,K4,K3,T1);
+ PROCESS_BLOCKN( 8,K3,T1,K2,K0,K4,T2);
+
+ PROCESS_BLOCKP( 9,K4,T2,K3,K1,K0,T0);
+ PROCESS_BLOCKN(10,K0,T0,K4,K2,K1,T1);
+ PROCESS_BLOCKP(11,K1,T1,K0,K3,K2,T2);
+ PROCESS_BLOCKN(12,K2,T2,K1,K4,K3,T0);
+
+ O[0] = X + K3;
+ O[1] = Y + K4 + T0;
+ O[2] = Z + K0 + T1;
+ O[3] = T + K1 + 18;
+}
+
+void Shred::tfnge_emit(void *dst, size_t szdst, struct tfnge_stream *tfe)
+{
+ TFNG_BYTE_TYPE *udst = (uint8_t*) dst;
+ size_t sz = szdst;
+
+ if (!dst && szdst == 0)
+ {
+ memset(tfe, 0, sizeof(struct tfnge_stream));
+ return;
+ }
+
+ if (tfe->carry_bytes > 0)
+ {
+ if (tfe->carry_bytes > szdst)
+ {
+ memcpy(udst, tfe->carry_block, szdst);
+ memmove(tfe->carry_block, tfe->carry_block+szdst, tfe->carry_bytes-szdst);
+ tfe->carry_bytes -= szdst;
+ return;
+ }
+
+ memcpy(udst, tfe->carry_block, tfe->carry_bytes);
+ udst += tfe->carry_bytes;
+ sz -= tfe->carry_bytes;
+ tfe->carry_bytes = 0;
+ }
+
+ if (sz >= TFNG_BLOCK_SIZE)
+ {
+ do
+ {
+ tfng_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
+ memcpy(udst, tfe->iv, TFNG_BLOCK_SIZE);
+ udst += TFNG_BLOCK_SIZE;
+ }
+ while ((sz -= TFNG_BLOCK_SIZE) >= TFNG_BLOCK_SIZE);
+ }
+
+ if (sz)
+ {
+ tfng_encrypt_rawblk(tfe->iv, tfe->iv, tfe->key);
+ memcpy(udst, tfe->iv, sz);
+ udst = (TFNG_BYTE_TYPE *)tfe->iv;
+ tfe->carry_bytes = TFNG_BLOCK_SIZE-sz;
+ memcpy(tfe->carry_block, udst+sz, tfe->carry_bytes);
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/smart.cpp b/src/smart.cpp
index f85cab1..815ef00 100644
--- a/src/smart.cpp
+++ b/src/smart.cpp
@@ -40,17 +40,17 @@ void SMART::readSMARTData(Drive* drive)
FILE* outputfileSmart = popen(cpComand, "r");
while ((getline(&cLine, &len, outputfileSmart)) != -1)
- {
- string sLine = string(cLine);
+ {
+ string sLine = string(cLine);
- SMART::parseModelFamily(sLine);
- SMART::parseModelName(sLine);
- SMART::parseSerial(sLine);
- SMART::parseCapacity(sLine);
- SMART::parseErrorCount(sLine);
- SMART::parsePowerOnHours(sLine);
- SMART::parsePowerCycle(sLine);
- }
+ SMART::parseModelFamily(sLine);
+ SMART::parseModelName(sLine);
+ SMART::parseSerial(sLine);
+ SMART::parseCapacity(sLine);
+ SMART::parseErrorCount(sLine);
+ SMART::parsePowerOnHours(sLine);
+ SMART::parsePowerCycle(sLine);
+ }
fclose(outputfileSmart);
drive->setDriveSMARTData(modelFamily, modelName, serial, capacity, errorCount, powerOnHours, powerCycle); //wirte data in drive
}
@@ -64,11 +64,12 @@ void SMART::parseModelFamily(string sLine)
{
string search("\"model_family\": ");
size_t found = sLine.find(search);
- if (found!=string::npos) {
- sLine.erase(0, sLine.find(": ") + 3);
- sLine.erase(sLine.length()-3, 3);
- modelFamily = sLine;
- }
+ if (found!=string::npos)
+ {
+ sLine.erase(0, sLine.find(": ") + 3);
+ sLine.erase(sLine.length()-3, 3);
+ modelFamily = sLine;
+ }
}
/**
@@ -80,11 +81,12 @@ void SMART::parseModelName(string sLine)
{
string search("\"model_name\": ");
size_t found = sLine.find(search);
- if (found!=string::npos) {
- sLine.erase(0, sLine.find(": ") + 3);
- sLine.erase(sLine.length()-3, 3);
- modelName = sLine;
- }
+ if (found!=string::npos)
+ {
+ sLine.erase(0, sLine.find(": ") + 3);
+ sLine.erase(sLine.length()-3, 3);
+ modelName = sLine;
+ }
}
/**
@@ -96,11 +98,12 @@ void SMART::parseSerial(string sLine)
{
string search("\"serial_number\": ");
size_t found = sLine.find(search);
- if (found!=string::npos) {
- sLine.erase(0, sLine.find(": ") + 3);
- sLine.erase(sLine.length()-3, 3);
- serial = sLine;
- }
+ if (found!=string::npos)
+ {
+ sLine.erase(0, sLine.find(": ") + 3);
+ sLine.erase(sLine.length()-3, 3);
+ serial = sLine;
+ }
}
/**
@@ -112,11 +115,12 @@ void SMART::parseCapacity(string sLine)
{
string search("\"bytes\": ");
size_t found = sLine.find(search);
- if (found!=string::npos) {
- sLine.erase(0, sLine.find(": ") + 2);
- sLine.erase(sLine.length()-1, 1);
- capacity = stol(sLine);
- }
+ if (found!=string::npos)
+ {
+ sLine.erase(0, sLine.find(": ") + 2);
+ sLine.erase(sLine.length()-1, 1);
+ capacity = stol(sLine);
+ }
}
/**
@@ -129,11 +133,11 @@ void SMART::parseErrorCount(string sLine)
string search("\"error_count_total\": ");
size_t found = sLine.find(search);
if (found!=string::npos)
- {
- sLine.erase(0, sLine.find(": ")+2);
- sLine.erase(sLine.length()-2, 2);
- errorCount = stol(sLine);
- }
+ {
+ sLine.erase(0, sLine.find(": ")+2);
+ sLine.erase(sLine.length()-2, 2);
+ errorCount = stol(sLine);
+ }
}
/**
@@ -146,12 +150,12 @@ void SMART::parsePowerOnHours(string sLine)
string search("\"hours\": ");
size_t found = sLine.find(search);
if (found!=string::npos)
- {
- sLine.erase(0, sLine.find(": ") + 2);
- sLine.erase(sLine.length()-1, 1);
- powerOnHours = stol(sLine);
+ {
+ sLine.erase(0, sLine.find(": ") + 2);
+ sLine.erase(sLine.length()-1, 1);
+ powerOnHours = stol(sLine);
- }
+ }
}
/**
@@ -164,11 +168,11 @@ void SMART::parsePowerCycle(string sLine)
string search("\"power_cycle_count\": ");
size_t found = sLine.find(search);
if (found!=string::npos)
- {
- sLine.erase(0, sLine.find(": ") + 2);
- sLine.erase(sLine.length()-2, 2);
- powerCycle = stol(sLine);
+ {
+ sLine.erase(0, sLine.find(": ") + 2);
+ sLine.erase(sLine.length()-2, 2);
+ powerCycle = stol(sLine);
- }
+ }
}
diff --git a/src/tui.cpp b/src/tui.cpp
new file mode 100644
index 0000000..8e011bf
--- /dev/null
+++ b/src/tui.cpp
@@ -0,0 +1,453 @@
+/**
+ * @file tui.cpp
+ * @brief display user interface
+ * @author hendrik schutter
+ * @date 03.08.2020
+ */
+
+#include "../include/reHDD.h"
+
+static std::mutex mxUIrefresh;
+
+TUI::TUI(void)
+{
+}
+
+/**
+ * \brief wipe drive with shred
+ * \param pointer of Drive instance
+ * \return void
+ */
+
+void TUI::initTUI()
+{
+ initscr();
+ raw();
+ keypad(stdscr,TRUE);
+ if(has_colors() == TRUE)
+ {
+ start_color();
+ }
+ else
+ {
+ printf("Your terminal does not support color\n");
+ Logger::logThis()->error("Your terminal does not support color");
+ exit(1);
+ }
+ clear();
+ curs_set(0);
+ noecho();
+ cbreak();
+ init_pair(COLOR_AREA_STDSCR,COLOR_WHITE, COLOR_BLUE);
+ wbkgd(stdscr, COLOR_PAIR(COLOR_AREA_STDSCR));
+
+ init_pair(COLOR_AREA_ENTRY, COLOR_BLACK, COLOR_WHITE);
+ init_pair(COLOR_AREA_ENTRY_SELECTED, COLOR_BLACK, COLOR_RED);
+ init_pair(COLOR_AREA_OVERVIEW, COLOR_BLACK, COLOR_WHITE);
+ init_pair(COLOR_AREA_DETAIL, COLOR_BLACK, COLOR_WHITE);
+
+ mvprintw(0, 2, "reHDD - HDD refurbishing tool - GPL 3.0 ");
+ Logger::logThis()->info("UI successfully initialized");
+}
+
+void TUI::updateTUI(vector * pvecDrives, uint8_t u8SelectedEntry)
+{
+ mxUIrefresh.lock();
+ int stdscrX, stdscrY;
+ getmaxyx(stdscr, stdscrY, stdscrX);
+
+ init_pair(COLOR_AREA_STDSCR,COLOR_WHITE, COLOR_BLUE);
+ wbkgd(stdscr, COLOR_PAIR(COLOR_AREA_STDSCR));
+
+ refresh();
+
+ overview=createOverViewWindow((int)(stdscrX/3), (stdscrY-15));
+ wrefresh(overview);
+
+ systemview=createSystemStats((int)(stdscrX/3), 10, (stdscrY-11));
+ wrefresh(systemview);
+
+ delwin(detailview);
+
+ vector ::iterator it;
+ for (it = pvecDrives->begin(); it != pvecDrives->end(); ++it)
+ {
+ string sModelFamily = it->getModelFamily();
+ string sModelName = it->getModelName();
+ string sCapacity = it->sCapacityToText();
+ string sState = " ";
+
+ bool bSelectedEntry = false;
+
+ if(u8SelectedEntry == (it - pvecDrives->begin()))
+ {
+ bSelectedEntry = true; //mark this drive in entries list
+ displaySelectedDrive(pvecDrives->at(u8SelectedEntry), stdscrX, stdscrY);
+ }
+
+ stringstream stream;
+
+ switch (it->state)
+ {
+ case Drive::SHRED_ACTIVE:
+
+ stream << fixed << setprecision(2) << (it->getTaskPercentage());
+ sState = "Shredding: " + stream.str() + "%";
+ break;
+
+ case Drive::DELETE_ACTIVE:
+ sState = "Deleting ...";
+ break;
+
+ case Drive::NONE:
+ case Drive::SHRED_SELECTED:
+ case Drive::DELETE_SELECTED:
+ if (it->bWasDeleteted)
+ {
+ sState = "DELETED"; //mark drive as deleted previously
+ }
+ if (it->bWasShredded)
+ {
+ sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted
+ }
+ break;
+ default:
+ break;
+ }
+
+ WINDOW * tmp = createEntryWindow( ((int)(stdscrX/3) - 2), 5, 3, (5* (it - pvecDrives->begin()) )+3, sModelFamily, sModelName, sCapacity, sState, bSelectedEntry);
+ wrefresh(tmp);
+ }//end loop though drives
+
+ if(pvecDrives->size() == 0)
+ {
+ //no selected drive present
+ Logger::logThis()->warning("no selected drive present");
+ struct MenuState menustate;
+ menustate.bAbort = false;
+ menustate.bConfirmDelete = false;
+ menustate.bConfirmShred = false;
+ menustate.bDelete = false;
+ menustate.bShred = false;
+
+ menuview=createMenuView(((stdscrX)-(int)(stdscrX/3)-7), 10, (int)(stdscrX/3)+5,(stdscrY-11), menustate);
+ wrefresh(menuview);
+
+ detailview=overwriteDetailViewWindow(((stdscrX)-(int)(stdscrX/3)-7), (stdscrY-15), (int)(stdscrX/3)+5);
+ wrefresh(detailview);
+ }
+
+ mxUIrefresh.unlock();
+}
+
+enum TUI::UserInput TUI::readUserInput()
+{
+ int ch = wgetch(stdscr);
+ switch(ch)
+ {
+ case KEY_UP:
+ return TUI::UserInput::UpKey;
+ break;
+ case KEY_DOWN:
+ return TUI::UserInput::DownKey;
+ break;
+ case 10:
+ return TUI::UserInput::Enter;
+ break;
+ case 27:
+ return TUI::UserInput::ESC;
+ break;
+ case 'a':
+ return TUI::UserInput::Abort;
+ break;
+ case 'd':
+ return TUI::UserInput::Delete;
+ break;
+ case 's':
+ return TUI::UserInput::Shred;
+ break;
+ default:
+ return TUI::UserInput::Undefined;
+ break;
+ }
+ return TUI::UserInput::Undefined;
+}
+
+void TUI::centerTitle(WINDOW *pwin, const char * title)
+{
+ int x, maxX, stringSize;
+ getmaxyx(pwin, maxX, maxX);
+ stringSize = 4 + strlen(title);
+ x = (maxX - stringSize)/2;
+ mvwaddch(pwin, 0, x, ACS_RTEE);
+ waddch(pwin, ' ');
+ waddstr(pwin, title);
+ waddch(pwin, ' ');
+ waddch(pwin, ACS_LTEE);
+}
+
+WINDOW* TUI::createOverViewWindow( int iXSize, int iYSize)
+{
+ WINDOW *newWindow;
+ newWindow = newwin(iYSize, iXSize, 2, 2);
+
+ wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_OVERVIEW));
+ box(newWindow, ACS_VLINE, ACS_HLINE);
+
+ centerTitle(newWindow, "Detected Drives");
+
+ return newWindow;
+}
+
+WINDOW* TUI::createDetailViewWindow( int iXSize, int iYSize, int iXStart, Drive drive)
+{
+ WINDOW *newWindow;
+ newWindow = newwin(iYSize, iXSize, 2, iXStart);
+ wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_DETAIL));
+ box(newWindow, ACS_VLINE, ACS_HLINE);
+
+ string title = "Selected Drive: " + drive.getModelName() + " " + drive.sCapacityToText();
+ centerTitle(newWindow, title.c_str());
+
+ string sPath = "Path: " +drive.getPath();
+ string sModelFamlily = "ModelFamily: " + drive.getModelFamily();
+ string sModelName = "ModelName: " + drive.getModelName();
+ string sCapacity = "Capacity: " + drive.sCapacityToText();
+ string sSerial = "Serial: " + drive.getSerial();
+ string sPowerOnHours = "PowerOnHours: " + drive.sPowerOnHoursToText();
+ string sPowerCycle = "PowerCycle: " + drive.sPowerCyclesToText();
+ string sErrorCount = "ErrorCount: " + drive.sErrorCountToText();
+
+ uint16_t u16Line = 2;
+
+ mvwaddstr(newWindow,u16Line++, 3, sPath.c_str());
+ mvwaddstr(newWindow,u16Line++, 3, sModelFamlily.c_str());
+ mvwaddstr(newWindow,u16Line++, 3, sModelName.c_str());
+ mvwaddstr(newWindow,u16Line++, 3, sCapacity.c_str());
+ mvwaddstr(newWindow,u16Line++, 3, sSerial.c_str());
+
+ 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());
+ }
+
+ return newWindow;
+}
+
+WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart)
+{
+ WINDOW *newWindow;
+ newWindow = newwin(iYSize, iXSize, 2, iXStart);
+ wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_DETAIL));
+ box(newWindow, ACS_VLINE, ACS_HLINE);
+
+ string title = "About this tool";
+ centerTitle(newWindow, title.c_str());
+
+ string sLine01 = "Path: NextLine ";
+ string sLine02 = "Path: NextLine ";
+ string sLine03 = "Path: NextLine ";
+ string sLine04 = "Path: NextLine ";
+ string sLine05 = "Path: NextLine ";
+ string sLine06 = "Path: NextLine ";
+ string sLine07 = "Path: NextLine ";
+
+ uint16_t u16Line = 5;
+
+ mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str());
+ mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine02.size()/2), sLine02.c_str());
+ mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine03.size()/2), sLine03.c_str());
+ mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine04.size()/2), sLine04.c_str());
+ mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine05.size()/2), sLine05.c_str());
+ mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine06.size()/2), sLine06.c_str());
+ mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine07.size()/2), sLine07.c_str());
+
+ attroff(COLOR_PAIR(COLOR_AREA_DETAIL));
+
+ return newWindow;
+}
+
+WINDOW* TUI::createEntryWindow(int iXSize, int iYSize, int iXStart, int iYStart, string sModelFamily, string sModelName, string sCapacity, string sState, bool bSelected)
+{
+ WINDOW *newWindow;
+ newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
+
+ if(!bSelected)
+ {
+ // entry is NOT selected
+ attron(COLOR_PAIR(COLOR_AREA_ENTRY));
+ wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY));
+ }
+ else
+ {
+ // entry IS selected
+ attron(COLOR_PAIR(COLOR_AREA_ENTRY));
+ wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
+ }
+
+ box(newWindow, ACS_VLINE, ACS_HLINE);
+
+ mvwaddstr(newWindow,1, 1, sModelFamily.c_str());
+ mvwaddstr(newWindow,2, 1, sModelName.c_str());
+ mvwaddstr(newWindow,3, 1, sCapacity.c_str());
+
+ mvwaddstr(newWindow,2, iXSize-sState.length()-5, sState.c_str());
+
+ return newWindow;
+}
+
+WINDOW* TUI::createSystemStats(int iXSize, int iYSize, int iYStart)
+{
+ WINDOW *newWindow;
+ newWindow = newwin(iYSize, iXSize, iYStart, 2);
+
+ wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_OVERVIEW));
+ box(newWindow, ACS_VLINE, ACS_HLINE);
+
+ centerTitle(newWindow, "System");
+
+ time_t rawtime;
+ struct tm * timeinfo;
+ char buffer[80];
+ time (&rawtime);
+ timeinfo = localtime(&rawtime);
+ strftime(buffer,sizeof(buffer),"Date: %d-%m-%Y Time: %H:%M",timeinfo);
+ string time(buffer);
+
+ mvwaddstr(newWindow,2, 2, time.c_str());
+
+ return newWindow;
+}
+
+WINDOW* TUI::createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate)
+{
+ WINDOW *newWindow;
+ newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
+
+ wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_OVERVIEW));
+ box(newWindow, ACS_VLINE, ACS_HLINE);
+
+ centerTitle(newWindow, "Controls");
+
+
+ uint16_t u16Line = 2;
+
+ if(menustate.bAbort)
+ {
+ mvwaddstr(newWindow,u16Line++, 3, "Press A for Abort");
+ }
+ if(menustate.bShred)
+ {
+ mvwaddstr(newWindow,u16Line++, 3, "Press S for Shred");
+ }
+ if(menustate.bDelete)
+ {
+ mvwaddstr(newWindow,u16Line++, 3, "Press D for Delete");
+ }
+
+ return newWindow;
+}
+
+WINDOW* TUI::createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string task, string optionA, string optionB)
+{
+ WINDOW *newWindow;
+ newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
+
+ wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
+ box(newWindow, ACS_VLINE, ACS_HLINE);
+
+ centerTitle(newWindow, task.c_str());
+
+ uint16_t u16Line = 2;
+ mvwaddstr(newWindow,u16Line++, 3, optionA.c_str());
+ mvwaddstr(newWindow,u16Line++, 3, optionB.c_str());
+
+ return newWindow;
+}
+
+void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
+{
+ struct MenuState menustate;
+ menustate.bAbort = false;
+ menustate.bConfirmDelete = false;
+ menustate.bConfirmShred = false;
+ menustate.bDelete = false;
+ menustate.bShred = false;
+
+ // set menustate based on drive state
+ switch (drive.state)
+ {
+ case Drive::NONE: //no task running or selected for this drive
+ menustate.bShred = true;
+ menustate.bDelete = true;
+ break;
+ case Drive::DELETE_ACTIVE : //delete task running for this drive
+ menustate.bAbort = true;
+ break;
+
+ case Drive::SHRED_ACTIVE : //shred task running for this drive
+ menustate.bAbort = true;
+ break;
+
+ case Drive::DELETE_SELECTED : //delete task selected for this drive
+ menustate.bConfirmDelete = true;
+ break;
+
+ case Drive::SHRED_SELECTED : //shred task selected for this drive
+ menustate.bConfirmShred = true;
+ break;
+ default:
+ break;
+ }
+
+ 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);
+ 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");
+ 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");
+ wrefresh(dialog);
+ }
+ else
+ {
+ delwin(dialog);
+ }
+}
\ No newline at end of file
diff --git a/src/wipe.cpp b/src/wipe.cpp
deleted file mode 100644
index a5626f9..0000000
--- a/src/wipe.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * @file wipe.cpp
- * @brief wipe drive
- * @author hendrik schutter
- * @date 03.05.2020
- */
-
-#include "../include/reHDD.h"
-
-//#define DRYRUN //if defined the drive will not be wiped, a ping cmd is attempted instead
-
-/**
- * \brief wipe drive with shred
- * \param pointer of Drive instance
- * \return void
- */
-void Wipe::wipeDrive(Drive* drive)
-{
- size_t len = 0; //lenght of found line
- char* cLine = NULL; //found line
-
-#ifndef DRYRUN
- string sCMD = ("shred -v ");
- sCMD.append(drive->getPath());
-#endif
-#ifdef DRYRUN
- cout << "dryrun for " << drive->getPath() << endl;
- string sCMD = ("ping ::1 -c 5");
-#endif
- const char* cpComand = sCMD.c_str();
-
- cout << "wipe: " << cpComand << endl;
-
- auto t_start = chrono::high_resolution_clock::now();
-
- FILE* outputfileSmart = popen(cpComand, "r");
-
- while ((getline(&cLine, &len, outputfileSmart)) != -1)
- {
- string sLine = string(cLine);
- cout << sLine;
- }
- fclose(outputfileSmart);
-
- auto t_end = chrono::high_resolution_clock::now();
-
- uint64_t u64TimeMS = chrono::duration(t_end-t_start).count();
-
- uint64_t u64hours = 0U;
- uint64_t u64minutes = 0U;
- uint64_t u64seconds = 0U;
-
- while(u64TimeMS >= 1000)
- {
- u64seconds++;
- u64TimeMS = u64TimeMS - 1000;
- }
-
- while(u64seconds >= 60)
- {
- u64minutes++;
- u64seconds = u64seconds - 60;
- }
-
- while(u64minutes >= 60)
- {
- u64hours++;
- u64minutes = u64minutes - 60;
- }
-
- cout << "Elapsed time: " << u64hours << " h - " << u64minutes << " min - " << u64seconds << " sec" << endl;
-}
diff --git a/vcCodium.code-workspace b/vcCodium.code-workspace
index 6b6425d..9e8c99c 100644
--- a/vcCodium.code-workspace
+++ b/vcCodium.code-workspace
@@ -12,7 +12,57 @@
"unordered_map": "cpp",
"string_view": "cpp",
"ostream": "cpp",
- "chrono": "cpp"
- }
+ "chrono": "cpp",
+ "thread": "cpp",
+ "deque": "cpp",
+ "vector": "cpp",
+ "cctype": "cpp",
+ "clocale": "cpp",
+ "cmath": "cpp",
+ "cstdarg": "cpp",
+ "cstddef": "cpp",
+ "cstdio": "cpp",
+ "cstdlib": "cpp",
+ "cstring": "cpp",
+ "ctime": "cpp",
+ "cwchar": "cpp",
+ "cwctype": "cpp",
+ "array": "cpp",
+ "atomic": "cpp",
+ "bit": "cpp",
+ "compare": "cpp",
+ "concepts": "cpp",
+ "condition_variable": "cpp",
+ "cstdint": "cpp",
+ "exception": "cpp",
+ "algorithm": "cpp",
+ "functional": "cpp",
+ "iterator": "cpp",
+ "memory": "cpp",
+ "memory_resource": "cpp",
+ "numeric": "cpp",
+ "optional": "cpp",
+ "random": "cpp",
+ "ratio": "cpp",
+ "system_error": "cpp",
+ "tuple": "cpp",
+ "type_traits": "cpp",
+ "utility": "cpp",
+ "fstream": "cpp",
+ "initializer_list": "cpp",
+ "iosfwd": "cpp",
+ "istream": "cpp",
+ "limits": "cpp",
+ "mutex": "cpp",
+ "new": "cpp",
+ "ranges": "cpp",
+ "sstream": "cpp",
+ "stdexcept": "cpp",
+ "stop_token": "cpp",
+ "streambuf": "cpp",
+ "typeinfo": "cpp",
+ "iomanip": "cpp"
+ },
+ "git.ignoreLimitWarning": true
}
}
\ No newline at end of file