diff --git a/Console/inc/Common.h b/Console/inc/Common.h index 0a287a4..86e0c24 100644 --- a/Console/inc/Common.h +++ b/Console/inc/Common.h @@ -26,29 +26,29 @@ #include "Macros.h" _CNSL_BEGIN - constexpr char LINE_FEED = '\n'; - constexpr char CHARRIGE = '\r'; - constexpr char BACKSPACE = '\b'; - constexpr char SPACE = ' '; - constexpr char ESCAPE = 27; - constexpr char TAB = '\t'; - - constexpr char CTRL_BACKSPACE = 127; - - constexpr char SPECIAL_LEADING = static_cast(224); - constexpr char SPECIAL_ARROW_UP = 72; - constexpr char SPECIAL_ARROW_DOWN = 80; - constexpr char SPECIAL_ARROW_LEFT = 75; - constexpr char SPECIAL_ARROW_RIGHT = 77; - constexpr char SPECIAL_DELETE = 83; - constexpr char SPECIAL_CTRL_DELETE = -109; - constexpr char SPECIAL_HOME = 71; - constexpr char SPECIAL_END = 79; - - constexpr char SPECIAL_ARROW_CTRL_UP = -115; - constexpr char SPECIAL_ARROW_CTRL_DOWN = -111; - constexpr char SPECIAL_ARROW_CTRL_LEFT = 115; - constexpr char SPECIAL_ARROW_CTRL_RIGHT = 116; +constexpr char LINE_FEED = '\n'; +constexpr char CHARRIGE = '\r'; +constexpr char BACKSPACE = '\b'; +constexpr char SPACE = ' '; +constexpr char ESCAPE = 27; +constexpr char TAB = '\t'; + +constexpr char CTRL_BACKSPACE = 127; + +constexpr char SPECIAL_LEADING = static_cast(224); +constexpr char SPECIAL_ARROW_UP = 72; +constexpr char SPECIAL_ARROW_DOWN = 80; +constexpr char SPECIAL_ARROW_LEFT = 75; +constexpr char SPECIAL_ARROW_RIGHT = 77; +constexpr char SPECIAL_DELETE = 83; +constexpr char SPECIAL_CTRL_DELETE = -109; +constexpr char SPECIAL_HOME = 71; +constexpr char SPECIAL_END = 79; + +constexpr char SPECIAL_ARROW_CTRL_UP = -115; +constexpr char SPECIAL_ARROW_CTRL_DOWN = -111; +constexpr char SPECIAL_ARROW_CTRL_LEFT = 115; +constexpr char SPECIAL_ARROW_CTRL_RIGHT = 116; _CNSL_END diff --git a/Console/inc/Console.h b/Console/inc/Console.h index ac7e89d..ee1d07f 100644 --- a/Console/inc/Console.h +++ b/Console/inc/Console.h @@ -29,45 +29,50 @@ _CNSL_BEGIN - struct TextAttribute - { - WORD foreground; - WORD background; - }; +struct TextAttribute +{ + WORD foreground; + WORD background; +}; + - constexpr int CNSL_BUFFER_SIZE = 32; +constexpr int CNSL_BUFFER_SIZE = 32; - struct ConsoleInfo + +struct ConsoleInfo +{ + union { - union - { - COORD size; + COORD size; + - struct - { - SHORT width; - SHORT height; - }; + struct + { + SHORT width; + SHORT height; }; + }; - COORD pos; - char* title; - char* copyright; - char* author; + COORD pos; - void (*headerPrinter)(void); + char* title; + char* copyright; + char* author; - bool overflowReprint; - bool headerReprint; + void (*headerPrinter)(void); - TextAttribute attr; + bool overflowReprint; + bool headerReprint; + + TextAttribute attr; + + ConsoleInfo(); + ~ConsoleInfo(); +}; - ConsoleInfo(); - ~ConsoleInfo(); - }; - // Additional colors +// Additional colors #define FOREGROUND_BLACK 0 #define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ) #define FOREGROUND_YELLOW (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLACK) @@ -82,77 +87,77 @@ _CNSL_BEGIN #define BACKGROUND_CYAN (BACKGROUND_BLACK | BACKGROUND_GREEN | BACKGROUND_BLUE ) #define BACKGROUND_LIGHT(COLOR) ((COLOR) | BACKGROUND_INTENSITY) - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Cursor Control - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - constexpr SHORT DFL_CNSL_WIDTH = 120; - constexpr SHORT DFL_CNSL_HEIGHT = 30; - - constexpr COORD ORIGIN = {0, 0}; - - const ConsoleInfo* GetConsoleInfo(); - - // for command prompt, Terminal won't be affected. - void InitConsoleSize(SHORT width, SHORT height); - void InitConsole(SHORT width = DFL_CNSL_WIDTH, SHORT height = DFL_CNSL_HEIGHT); - void SetConsoleSize(SHORT width, SHORT height); - SHORT GetConsoleWidth(); - SHORT GetConsoleHeight(); - - COORD GetCursorPosition(); - COORD SetCursorPosition(const COORD& coord); // Return old coordinate. - bool SetCursorPosition(const COORD& coord, COORD* old); - - void HideCursor(); - void ShowCursor(); - - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Basic Control - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - void Clear(); - void Clear(SHORT left); // Clear left to end of current line. - void Clear(SHORT left, SHORT right); // Clear left to right of current line. - void Clear(const COORD& upperLeft, const COORD& bottomRight); // Clear an area. - - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Text Attribute - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - void SetTextAttribute(const TextAttribute& attr, TextAttribute* old); - WORD SetTextForeground(WORD foreground); - WORD SetTextBackground(WORD background); - void RestoreTextAttribute(); - - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Header - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - void SetHeader( - const char* title, - const char* copyright, - const char* author); - void SetTitle(const char* title); - void SetCopyright(const char* copyright); - void SetAuthor(const char* author); - - void OverflowReprint(bool reprint); - void HeaderReprint(bool reprint); - - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Advanced Print - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - void SetHeaderPrinter(void (*printer)(void)); - void DefaultHeaderPrinter(); - void Print(); - void Reprint(); +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Cursor Control +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +constexpr SHORT DFL_CNSL_WIDTH = 120; +constexpr SHORT DFL_CNSL_HEIGHT = 30; + +constexpr COORD ORIGIN = { 0, 0 }; + +const ConsoleInfo* GetConsoleInfo(); + +// for command prompt, Terminal won't be affected. +void InitConsoleSize(SHORT width, SHORT height); +void InitConsole(SHORT width = DFL_CNSL_WIDTH, SHORT height = DFL_CNSL_HEIGHT); +void SetConsoleSize(SHORT width, SHORT height); +SHORT GetConsoleWidth(); +SHORT GetConsoleHeight(); + +COORD GetCursorPosition(); +COORD SetCursorPosition(const COORD& coord); // Return old coordinate. +bool SetCursorPosition(const COORD& coord, COORD* old); + +void HideCursor(); +void ShowCursor(); + +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Basic Control +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +void Clear(); +void Clear(SHORT left); // Clear left to end of current line. +void Clear(SHORT left, SHORT right); // Clear left to right of current line. +void Clear(const COORD& upperLeft, const COORD& bottomRight); // Clear an area. + +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Text Attribute +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +void SetTextAttribute(const TextAttribute& attr, TextAttribute* old); +WORD SetTextForeground(WORD foreground); +WORD SetTextBackground(WORD background); +void RestoreTextAttribute(); + +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Header +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +void SetHeader( + const char* title, + const char* copyright, + const char* author); +void SetTitle(const char* title); +void SetCopyright(const char* copyright); +void SetAuthor(const char* author); + +void OverflowReprint(bool reprint); +void HeaderReprint(bool reprint); + +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Advanced Print +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +void SetHeaderPrinter(void (*printer)(void)); +void DefaultHeaderPrinter(); +void Print(); +void Reprint(); _CNSL_END diff --git a/Console/inc/Input.h b/Console/inc/Input.h index 57815ee..bb78642 100644 --- a/Console/inc/Input.h +++ b/Console/inc/Input.h @@ -32,131 +32,142 @@ #include _CNSL_BEGIN - constexpr int INPUT_BUFFER_SIZE = 128; - extern char _default_buffer[INPUT_BUFFER_SIZE]; +constexpr int INPUT_BUFFER_SIZE = 128; +extern char _default_buffer[INPUT_BUFFER_SIZE]; - struct InputHistory - { - InputHistory(); - ~InputHistory(); - void Push(const char* history); - void Clear(); +struct InputHistory +{ + InputHistory(); + ~InputHistory(); - std::vector _record; - }; + void Push(const char* history); + void Clear(); - using Completer = const char* (*)(const char*, int*); - using CharsetVerifier = bool(*)(char); + std::vector _record; +}; - struct InputOptions - { - int minLen; - int maxLen; - InputHistory* history; +using Completer = const char* (*)(const char*, int*); +using CharsetVerifier = bool(*)(char); - Completer completer; - CharsetVerifier verifier; - // The default value before input. - const char* placeholder; +struct InputOptions +{ + int minLen; + int maxLen; - char decoy; - bool interruptible; + InputHistory* history; - InputOptions() : - minLen(1), - maxLen(INPUT_BUFFER_SIZE - 1), - history(nullptr), - completer(nullptr), - verifier(nullptr), - placeholder(nullptr), - decoy(0), - interruptible(false) - { - } + Completer completer; + CharsetVerifier verifier; - InputOptions(int _minLen, int _maxLen, char _decoy = 0, bool _interruptible = false) : - minLen(_minLen), maxLen(_maxLen), - history(nullptr), completer(nullptr), verifier(nullptr), - placeholder(nullptr), decoy(_decoy), interruptible(_interruptible) - { - } - }; + // The default value before input. + const char* placeholder; - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Input Control - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - int GetString(char* buffer, const InputOptions& options); + char decoy; + bool interruptible; - // Get a string with default options. - int GetString(char* buffer); - template - bool DefaultVerifier(_Ty value) { return true; } + InputOptions() : + minLen(1), + maxLen(INPUT_BUFFER_SIZE - 1), + history(nullptr), + completer(nullptr), + verifier(nullptr), + placeholder(nullptr), + decoy(0), + interruptible(false) + { + } - template - bool GetNumber(_Ty* value, bool (*verifier)(_Ty), const char* prompt) + InputOptions(int _minLen, int _maxLen, char _decoy = 0, bool _interruptible = false) : + minLen(_minLen), maxLen(_maxLen), + history(nullptr), completer(nullptr), verifier(nullptr), + placeholder(nullptr), decoy(_decoy), interruptible(_interruptible) { - COORD origin = GetCursorPosition(); + } +}; - GetString(_default_buffer); - std::stringstream stream(_default_buffer); - _Ty val; - bool err = false; - if (stream >> val) - { - if (verifier && !verifier(val)) - err = true; - } - else +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Input Control +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +int GetString(char* buffer, const InputOptions& options); + +// Get a string with default options. +int GetString(char* buffer); + + +template +bool DefaultVerifier(_Ty value) { return true; } + + +template +bool GetNumber(_Ty* value, bool (*verifier)(_Ty), const char* prompt) +{ + COORD origin = GetCursorPosition(); + + GetString(_default_buffer); + std::stringstream stream(_default_buffer); + + _Ty val; + bool err = false; + if (stream >> val) + { + if (verifier && !verifier(val)) err = true; + } + else + err = true; - if (err) + if (err) + { + Clear(origin.X); + SetCursorPosition(origin); + if (prompt) { + InsertText(prompt); + Sleep(1000); Clear(origin.X); SetCursorPosition(origin); - if (prompt) - { - InsertText(prompt); - Sleep(1000); - Clear(origin.X); - SetCursorPosition(origin); - } } - else - *value = val; - - return !err; } + else + *value = val; - template - bool GetNumber(_Ty* value) - { - return GetNumber(value, DefaultVerifier<_Ty>, nullptr); - } + return !err; +} - template - bool GetNumber(_Ty* value, bool (*verifier)(_Ty)) - { - return GetNumber(value, verifier, nullptr); - } - template - bool GetNumber(_Ty* value, const char* prompt) // error prompt - { - return GetNumber(value, DefaultVerifier, prompt); - } +template +bool GetNumber(_Ty* value) +{ + return GetNumber(value, DefaultVerifier<_Ty>, nullptr); +} + + +template +bool GetNumber(_Ty* value, bool (*verifier)(_Ty)) +{ + return GetNumber(value, verifier, nullptr); +} + + +template +bool GetNumber(_Ty* value, const char* prompt) // error prompt +{ + return GetNumber(value, DefaultVerifier, prompt); +} + - void FlushInput(); +void FlushInput(); - // Wait for key to continue, 0 means any. - void WaitForKey(const char* prompt, char key = 0); +// Wait for key to continue, 0 means any. +void WaitForKey(const char* prompt, char key = 0); _CNSL_END diff --git a/Console/inc/InputAux.h b/Console/inc/InputAux.h index 4e34fa4..d1449df 100644 --- a/Console/inc/InputAux.h +++ b/Console/inc/InputAux.h @@ -27,41 +27,43 @@ #include _CNSL_BEGIN - struct InputContext - { - char* buffer; - char** history_end; - char** history_begin; - char** history; - int pos; - int length; - COORD origin; +struct InputContext +{ + char* buffer; + char** history_end; + char** history_begin; + char** history; + int pos; + int length; + COORD origin; + + char ch; - char ch; - InputContext() : - buffer(nullptr), - history_end(nullptr), - history_begin(nullptr), - history(nullptr), - pos(0), - length(0), - origin({0, 0}), - ch(0) - { - } - }; + InputContext() : + buffer(nullptr), + history_end(nullptr), + history_begin(nullptr), + history(nullptr), + pos(0), + length(0), + origin({ 0, 0 }), + ch(0) + { + } +}; + - bool IsTerminator(char ch); +bool IsTerminator(char ch); - bool IsNullOrEmpty(const char* str); - bool IsEqual(const char* str1, const char* str2); +bool IsNullOrEmpty(const char* str); +bool IsEqual(const char* str1, const char* str2); - const char* BeginsWith(const char* str, const char* prefix); - const char* EndsWidth(const char* str, const char* suffix); +const char* BeginsWith(const char* str, const char* prefix); +const char* EndsWidth(const char* str, const char* suffix); - void FlushInput(); +void FlushInput(); - void WaitForKey(const char* prompt, char key); +void WaitForKey(const char* prompt, char key); _CNSL_END diff --git a/Console/inc/Output.h b/Console/inc/Output.h index 208872d..a25e1e2 100644 --- a/Console/inc/Output.h +++ b/Console/inc/Output.h @@ -29,43 +29,45 @@ #include _CNSL_BEGIN - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Output Control - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - void InsertLineFeed(); // Row++, col does not change. - void InsertLineFeed(int n); // Insert n line feeds. - void InsertCarrige(); // Row does not change, col back to zero. - void InsertNewLine(); // Row++, col back to zero. - void InsertNewLine(int n); // Insert n new lines. +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Output Control +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +void InsertLineFeed(); // Row++, col does not change. +void InsertLineFeed(int n); // Insert n line feeds. +void InsertCarrige(); // Row does not change, col back to zero. +void InsertNewLine(); // Row++, col back to zero. +void InsertNewLine(int n); // Insert n new lines. - void InsertReverseLineFeed(); - void InsertReverseLineFeed(int n); - void InsertReverseNewLine(); - void InsertReverseNewLine(int n); +void InsertReverseLineFeed(); +void InsertReverseLineFeed(int n); +void InsertReverseNewLine(); +void InsertReverseNewLine(int n); - void InsertBackspace(); - void InsertBackspace(int n); +void InsertBackspace(); +void InsertBackspace(int n); - void InsertDelete(); // Clear the last character and went back by one. - void InsertDelete(int n); +void InsertDelete(); // Clear the last character and went back by one. +void InsertDelete(int n); - void InsertChar(char ch); - void InsertChar(char ch, int n); - void InsertText(const char* format, ...); - void InsertText(WORD foreground, const char* format, ...); +void InsertChar(char ch); +void InsertChar(char ch, int n); +void InsertText(const char* format, ...); +void InsertText(WORD foreground, const char* format, ...); - void InsertSplitLine(char split); - void InsertHeaderLine(const char* header, char split = '-'); +void InsertSplitLine(char split); +void InsertHeaderLine(const char* header, char split = '-'); - template - void InsertNumber(_Ty val) - { - static_assert(std::is_arithmetic<_Ty>::value, "Must be arithmetic!"); - InsertText(std::to_string(val).c_str()); - } +template +void InsertNumber(_Ty val) +{ + static_assert(std::is_arithmetic<_Ty>::value, "Must be arithmetic!"); + + InsertText(std::to_string(val).c_str()); +} + _CNSL_END diff --git a/Console/src/Console.cpp b/Console/src/Console.cpp index 148d7eb..d90e9ac 100644 --- a/Console/src/Console.cpp +++ b/Console/src/Console.cpp @@ -36,391 +36,420 @@ _CNSL_BEGIN #undef max #endif - static ConsoleInfo gConsoleInfo; - static HANDLE hOutput = nullptr; +static ConsoleInfo gConsoleInfo; +static HANDLE hOutput = nullptr; - ConsoleInfo::ConsoleInfo() : - width(DFL_CNSL_WIDTH), height(DFL_CNSL_HEIGHT), - title(nullptr), copyright(nullptr), author(nullptr), - headerPrinter(nullptr), overflowReprint(true), headerReprint(true) - { - } - ConsoleInfo::~ConsoleInfo() - { - if (title) - free(title); - if (copyright) - free(copyright); - if (author) - free(author); - } +ConsoleInfo::ConsoleInfo() : + width(DFL_CNSL_WIDTH), height(DFL_CNSL_HEIGHT), + title(nullptr), copyright(nullptr), author(nullptr), + headerPrinter(nullptr), overflowReprint(true), headerReprint(true) +{ +} - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Cursor Control - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - static constexpr char DFL_TITLE[] = "Demo Project"; - static constexpr char DFL_COPYRIGHT[] = "Tony's Studio 2020 - 2023"; - static constexpr char DFL_AUTHOR[] = "Tony Skywalker"; +ConsoleInfo::~ConsoleInfo() +{ + if (title) + free(title); + if (copyright) + free(copyright); + if (author) + free(author); +} - const ConsoleInfo* GetConsoleInfo() - { - return &gConsoleInfo; - } - static bool IsValidPosition(const COORD& coord) - { - return ((coord.X < gConsoleInfo.size.X) && (coord.Y < gConsoleInfo.size.Y)); - } +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Cursor Control +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +static constexpr char DFL_TITLE[] = "Demo Project"; +static constexpr char DFL_COPYRIGHT[] = "Tony's Studio 2020 - 2023"; +static constexpr char DFL_AUTHOR[] = "Tony Skywalker"; - void InitConsoleSize(SHORT width, SHORT height) - { - char msg[48]; - sprintf_s(msg, "mode con cols=%hd", width); - system(msg); - } +const ConsoleInfo* GetConsoleInfo() +{ + return &gConsoleInfo; +} - void InitConsole(SHORT width, SHORT height) - { - SetConsoleSize(width, height); - RestoreTextAttribute(); - SetCursorPosition(ORIGIN); - hOutput = GetStdHandle(STD_OUTPUT_HANDLE); +static bool IsValidPosition(const COORD& coord) +{ + return ((coord.X < gConsoleInfo.size.X) && (coord.Y < gConsoleInfo.size.Y)); +} - SetHeader(DFL_TITLE, DFL_COPYRIGHT, DFL_AUTHOR); - SetHeaderPrinter(DefaultHeaderPrinter); - } - void SetConsoleSize(SHORT width, SHORT height) - { - gConsoleInfo.width = width; - gConsoleInfo.height = height; - } +void InitConsoleSize(SHORT width, SHORT height) +{ + char msg[48]; + sprintf_s(msg, "mode con cols=%hd", width); + system(msg); +} - SHORT GetConsoleWidth() - { - return gConsoleInfo.width; - } - SHORT GetConsoleHeight() - { - return gConsoleInfo.height; - } +void InitConsole(SHORT width, SHORT height) +{ + SetConsoleSize(width, height); + RestoreTextAttribute(); + SetCursorPosition(ORIGIN); - COORD GetCursorPosition() - { - CONSOLE_SCREEN_BUFFER_INFO pBuffer; + hOutput = GetStdHandle(STD_OUTPUT_HANDLE); - GetConsoleScreenBufferInfo(hOutput, &pBuffer); + SetHeader(DFL_TITLE, DFL_COPYRIGHT, DFL_AUTHOR); + SetHeaderPrinter(DefaultHeaderPrinter); +} - return pBuffer.dwCursorPosition; - } - COORD SetCursorPosition(const COORD& coord) - { - CONSOLE_SCREEN_BUFFER_INFO pBuffer; +void SetConsoleSize(SHORT width, SHORT height) +{ + gConsoleInfo.width = width; + gConsoleInfo.height = height; +} - GetConsoleScreenBufferInfo(hOutput, &pBuffer); - COORD ret = pBuffer.dwCursorPosition; - if (IsValidPosition(coord)) - SetConsoleCursorPosition(hOutput, coord); +SHORT GetConsoleWidth() +{ + return gConsoleInfo.width; +} - return ret; - } - bool SetCursorPosition(const COORD& coord, COORD* old) - { - CONSOLE_SCREEN_BUFFER_INFO pBuffer; +SHORT GetConsoleHeight() +{ + return gConsoleInfo.height; +} - GetConsoleScreenBufferInfo(hOutput, &pBuffer); - if (old) - *old = pBuffer.dwCursorPosition; - if (IsValidPosition(coord)) - SetConsoleCursorPosition(hOutput, coord); - else - return false; +COORD GetCursorPosition() +{ + CONSOLE_SCREEN_BUFFER_INFO pBuffer; - return true; - } + GetConsoleScreenBufferInfo(hOutput, &pBuffer); - void HideCursor() - { - CONSOLE_CURSOR_INFO pInfo; + return pBuffer.dwCursorPosition; +} - GetConsoleCursorInfo(hOutput, &pInfo); - pInfo.bVisible = false; - SetConsoleCursorInfo(hOutput, &pInfo); - } - void ShowCursor() - { - CONSOLE_CURSOR_INFO pInfo; +COORD SetCursorPosition(const COORD& coord) +{ + CONSOLE_SCREEN_BUFFER_INFO pBuffer; - GetConsoleCursorInfo(hOutput, &pInfo); - pInfo.bVisible = true; - SetConsoleCursorInfo(hOutput, &pInfo); - } + GetConsoleScreenBufferInfo(hOutput, &pBuffer); + COORD ret = pBuffer.dwCursorPosition; + + if (IsValidPosition(coord)) + SetConsoleCursorPosition(hOutput, coord); + return ret; +} - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Basic Control - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - void Clear() + +bool SetCursorPosition(const COORD& coord, COORD* old) +{ + CONSOLE_SCREEN_BUFFER_INFO pBuffer; + + GetConsoleScreenBufferInfo(hOutput, &pBuffer); + if (old) + *old = pBuffer.dwCursorPosition; + + if (IsValidPosition(coord)) + SetConsoleCursorPosition(hOutput, coord); + else + return false; + + return true; +} + + +void HideCursor() +{ + CONSOLE_CURSOR_INFO pInfo; + + GetConsoleCursorInfo(hOutput, &pInfo); + pInfo.bVisible = false; + SetConsoleCursorInfo(hOutput, &pInfo); +} + + +void ShowCursor() +{ + CONSOLE_CURSOR_INFO pInfo; + + GetConsoleCursorInfo(hOutput, &pInfo); + pInfo.bVisible = true; + SetConsoleCursorInfo(hOutput, &pInfo); +} + + +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Basic Control +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +void Clear() +{ + system("cls"); +} + + +void Clear(SHORT left) +{ + Clear(left, gConsoleInfo.width); +} + + +void Clear(SHORT left, SHORT right) +{ + right = std::min(right, gConsoleInfo.width); + if (right <= left) + return; + + COORD origin = GetCursorPosition(); + origin.X = left; + + if (!SetCursorPosition(origin, nullptr)) + return; + + while (left < right) { - system("cls"); + putchar(' '); + left++; } - void Clear(SHORT left) + SetCursorPosition(origin); +} + + +void Clear(const COORD& upperLeft, const COORD& bottomRight) +{ + SHORT XBound = std::min(bottomRight.X, gConsoleInfo.width); + SHORT YBound = std::min(bottomRight.X, gConsoleInfo.width); + + if ((XBound <= upperLeft.X) || (YBound <= upperLeft.X)) + return; + + COORD pos = upperLeft; + while (pos.Y < YBound) { - Clear(left, gConsoleInfo.width); + SetCursorPosition(pos); + Clear(pos.X, XBound); + pos.Y++; } +} - void Clear(SHORT left, SHORT right) - { - right = std::min(right, gConsoleInfo.width); - if (right <= left) - return; - COORD origin = GetCursorPosition(); - origin.X = left; +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Text Attribute +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +static constexpr WORD DFL_FOREGROUND = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; +static constexpr WORD DFL_BACKGROUND = 0; - if (!SetCursorPosition(origin, nullptr)) - return; - while (left < right) - { - putchar(' '); - left++; - } +static void ApplyTextAttribute() +{ + WORD color = gConsoleInfo.attr.foreground | gConsoleInfo.attr.background; + SetConsoleTextAttribute(hOutput, color); +} - SetCursorPosition(origin); - } - void Clear(const COORD& upperLeft, const COORD& bottomRight) - { - SHORT XBound = std::min(bottomRight.X, gConsoleInfo.width); - SHORT YBound = std::min(bottomRight.X, gConsoleInfo.width); +void SetTextAttribute(const TextAttribute& attr, TextAttribute* old) +{ + if (old) + *old = gConsoleInfo.attr; + gConsoleInfo.attr = attr; - if ((XBound <= upperLeft.X) || (YBound <= upperLeft.X)) - return; + ApplyTextAttribute(); +} - COORD pos = upperLeft; - while (pos.Y < YBound) - { - SetCursorPosition(pos); - Clear(pos.X, XBound); - pos.Y++; - } - } +WORD SetTextForeground(const WORD foreground) +{ + WORD old = gConsoleInfo.attr.foreground; + gConsoleInfo.attr.foreground = foreground; - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Text Attribute - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - static constexpr WORD DFL_FOREGROUND = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - static constexpr WORD DFL_BACKGROUND = 0; + ApplyTextAttribute(); - static void ApplyTextAttribute() - { - WORD color = gConsoleInfo.attr.foreground | gConsoleInfo.attr.background; - SetConsoleTextAttribute(hOutput, color); - } + return old; +} - void SetTextAttribute(const TextAttribute& attr, TextAttribute* old) - { - if (old) - *old = gConsoleInfo.attr; - gConsoleInfo.attr = attr; - ApplyTextAttribute(); - } +WORD SetTextBackground(const WORD background) +{ + WORD old = gConsoleInfo.attr.background; + gConsoleInfo.attr.background = background; - WORD SetTextForeground(const WORD foreground) - { - WORD old = gConsoleInfo.attr.foreground; - gConsoleInfo.attr.foreground = foreground; + ApplyTextAttribute(); - ApplyTextAttribute(); + return old; +} - return old; - } - WORD SetTextBackground(const WORD background) - { - WORD old = gConsoleInfo.attr.background; - gConsoleInfo.attr.background = background; +void RestoreTextAttribute() +{ + SetTextForeground(DFL_FOREGROUND); + SetTextBackground(DFL_BACKGROUND); + ApplyTextAttribute(); +} - ApplyTextAttribute(); - return old; - } +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Header +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +void SetHeader( + const char* title, + const char* copyright, + const char* author) +{ + SetTitle(title); + SetCopyright(copyright); + SetAuthor(author); +} - void RestoreTextAttribute() - { - SetTextForeground(DFL_FOREGROUND); - SetTextBackground(DFL_BACKGROUND); - ApplyTextAttribute(); - } +void SetTitle(const char* title) +{ + char* old = gConsoleInfo.title; - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Header - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - void SetHeader( - const char* title, - const char* copyright, - const char* author) + if (title) { - SetTitle(title); - SetCopyright(copyright); - SetAuthor(author); + gConsoleInfo.title = _strdup(title); + if (!gConsoleInfo.title) // memory allocation failed + { + gConsoleInfo.title = old; + return; + } } + else + gConsoleInfo.title = nullptr; - void SetTitle(const char* title) - { - char* old = gConsoleInfo.title; + if (old) + free(old); +} - if (title) - { - gConsoleInfo.title = _strdup(title); - if (!gConsoleInfo.title) // memory allocation failed - { - gConsoleInfo.title = old; - return; - } - } - else - gConsoleInfo.title = nullptr; - if (old) - free(old); - } +void SetCopyright(const char* copyright) +{ + char* old = gConsoleInfo.copyright; - void SetCopyright(const char* copyright) + if (copyright) { - char* old = gConsoleInfo.copyright; - - if (copyright) + gConsoleInfo.copyright = _strdup(copyright); + if (!gConsoleInfo.copyright) // memory allocation failed { - gConsoleInfo.copyright = _strdup(copyright); - if (!gConsoleInfo.copyright) // memory allocation failed - { - gConsoleInfo.copyright = old; - return; - } + gConsoleInfo.copyright = old; + return; } - else - gConsoleInfo.copyright = nullptr; - - if (old) - free(old); } + else + gConsoleInfo.copyright = nullptr; - void SetAuthor(const char* author) - { - char* old = gConsoleInfo.author; + if (old) + free(old); +} - if (author) - { - gConsoleInfo.author = _strdup(author); - if (!gConsoleInfo.author) // memory allocation failed - { - gConsoleInfo.author = old; - return; - } - } - else - gConsoleInfo.author = nullptr; - if (old) - free(old); - } +void SetAuthor(const char* author) +{ + char* old = gConsoleInfo.author; - void OverflowReprint(bool reprint) + if (author) { - gConsoleInfo.overflowReprint = reprint; + gConsoleInfo.author = _strdup(author); + if (!gConsoleInfo.author) // memory allocation failed + { + gConsoleInfo.author = old; + return; + } } + else + gConsoleInfo.author = nullptr; - void HeaderReprint(bool reprint) - { - gConsoleInfo.headerReprint = reprint; - } + if (old) + free(old); +} + + +void OverflowReprint(bool reprint) +{ + gConsoleInfo.overflowReprint = reprint; +} + + +void HeaderReprint(bool reprint) +{ + gConsoleInfo.headerReprint = reprint; +} + + +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Advanced Print +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +void SetHeaderPrinter(void (*printer)(void)) +{ + gConsoleInfo.headerPrinter = printer; +} - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Advanced Print - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ +void DefaultHeaderPrinter() +{ + char buffer[128]; - void SetHeaderPrinter(void (*printer)(void)) + TextAttribute attr; + TextAttribute old; + + attr.foreground = FOREGROUND_WHITE; + attr.background = BACKGROUND_BLACK; + SetTextAttribute(attr, &old); + + if (gConsoleInfo.title) + InsertHeaderLine(gConsoleInfo.title, '-'); + if (gConsoleInfo.author) { - gConsoleInfo.headerPrinter = printer; + sprintf_s(buffer, "Programmer - %s", gConsoleInfo.author); + InsertHeaderLine(buffer, ' '); } - - void DefaultHeaderPrinter() + if (gConsoleInfo.copyright) { - char buffer[128]; + sprintf_s(buffer, "Copyright (C) %s", gConsoleInfo.copyright); + InsertHeaderLine(buffer, ' '); + } - TextAttribute attr; - TextAttribute old; + InsertSplitLine('_'); - attr.foreground = FOREGROUND_WHITE; - attr.background = BACKGROUND_BLACK; - SetTextAttribute(attr, &old); + InsertNewLine(); - if (gConsoleInfo.title) - InsertHeaderLine(gConsoleInfo.title, '-'); - if (gConsoleInfo.author) - { - sprintf_s(buffer, "Programmer - %s", gConsoleInfo.author); - InsertHeaderLine(buffer, ' '); - } - if (gConsoleInfo.copyright) - { - sprintf_s(buffer, "Copyright (C) %s", gConsoleInfo.copyright); - InsertHeaderLine(buffer, ' '); - } + SetTextAttribute(old, nullptr); +} - InsertSplitLine('_'); - InsertNewLine(); +void Print() +{ + if (gConsoleInfo.headerPrinter) + gConsoleInfo.headerPrinter(); +} - SetTextAttribute(old, nullptr); - } - void Print() +void Reprint() +{ + if (gConsoleInfo.overflowReprint) { - if (gConsoleInfo.headerPrinter) + Clear(); + if (gConsoleInfo.headerReprint && gConsoleInfo.headerPrinter) gConsoleInfo.headerPrinter(); } - - void Reprint() + else { - if (gConsoleInfo.overflowReprint) - { - Clear(); - if (gConsoleInfo.headerReprint && gConsoleInfo.headerPrinter) - gConsoleInfo.headerPrinter(); - } - else - { - putchar('\n'); - } + putchar('\n'); } +} _CNSL_END diff --git a/Console/src/Input.cpp b/Console/src/Input.cpp index 8259846..e255e2e 100644 --- a/Console/src/Input.cpp +++ b/Console/src/Input.cpp @@ -40,357 +40,378 @@ #endif _CNSL_BEGIN - char _default_buffer[INPUT_BUFFER_SIZE]; +char _default_buffer[INPUT_BUFFER_SIZE]; - using _input_action_t = void(const InputOptions& opt, InputContext& ctx); +using _input_action_t = void(const InputOptions& opt, InputContext& ctx); - static void ResetInput(SHORT beginX, int maxLen, int& pos, int& length, char* input, char* history); - static void InputPlaceholder(const InputOptions& opt, InputContext& ctx); +static void ResetInput(SHORT beginX, int maxLen, int& pos, int& length, char* input, char* history); +static void InputPlaceholder(const InputOptions& opt, InputContext& ctx); - static _input_action_t _reset_input; +static _input_action_t _reset_input; - static _input_action_t _insert_char; - static _input_action_t _insert_backspace; - static _input_action_t _insert_ctrl_backspace; - static _input_action_t _insert_completion; +static _input_action_t _insert_char; +static _input_action_t _insert_backspace; +static _input_action_t _insert_ctrl_backspace; +static _input_action_t _insert_completion; - static void _special_input_handler(char ch, const InputOptions& opt, InputContext& ctx); +static void _special_input_handler(char ch, const InputOptions& opt, InputContext& ctx); - static _input_action_t _special_arrow_left; - static _input_action_t _special_arrow_right; - static _input_action_t _special_arrow_up; - static _input_action_t _special_arrow_down; - static _input_action_t _special_arrow_ctrl_left; - static _input_action_t _special_arrow_ctrl_right; +static _input_action_t _special_arrow_left; +static _input_action_t _special_arrow_right; +static _input_action_t _special_arrow_up; +static _input_action_t _special_arrow_down; +static _input_action_t _special_arrow_ctrl_left; +static _input_action_t _special_arrow_ctrl_right; - static _input_action_t _special_delete; - static _input_action_t _special_ctrl_delete; +static _input_action_t _special_delete; +static _input_action_t _special_ctrl_delete; - static _input_action_t _special_home; - static _input_action_t _special_end; +static _input_action_t _special_home; +static _input_action_t _special_end; - int GetString(char* buffer) + +int GetString(char* buffer) +{ + return GetString(buffer, InputOptions()); +} + + +int GetString(char* buffer, const InputOptions& options) +{ + InputOptions opt(options); + opt.minLen = std::max(opt.minLen, 0); + opt.maxLen = std::min(opt.maxLen, INPUT_BUFFER_SIZE - 1); + + InputContext ctx; + ctx.buffer = buffer; + ctx.buffer[0] = '\0'; + if (opt.history) { - return GetString(buffer, InputOptions()); + auto raw = opt.history->_record.data(); + ctx.history_end = raw; + ctx.history_begin = raw + (options.history->_record.size() - 1); + ctx.history = ctx.history_begin; } + ctx.origin = GetCursorPosition(); - int GetString(char* buffer, const InputOptions& options) + FlushInput(); + + InputPlaceholder(opt, ctx); + + char ch; + for (; ;) { - InputOptions opt(options); - opt.minLen = std::max(opt.minLen, 0); - opt.maxLen = std::min(opt.maxLen, INPUT_BUFFER_SIZE - 1); - - InputContext ctx; - ctx.buffer = buffer; - ctx.buffer[0] = '\0'; - if (opt.history) + ch = _getch(); + if (IsTerminator(ch)) { - auto raw = opt.history->_record.data(); - ctx.history_end = raw; - ctx.history_begin = raw + (options.history->_record.size() - 1); - ctx.history = ctx.history_begin; + if (ctx.length >= opt.minLen) + break; // goto normal exit (keep history) + if (opt.interruptible) + return ctx.length; + // abandon history } - ctx.origin = GetCursorPosition(); - - FlushInput(); - - InputPlaceholder(opt, ctx); - - char ch; - for (; ;) + else if ((ch == ESCAPE) && opt.interruptible) + { + return -1; + } + else if (ch == SPECIAL_LEADING) { ch = _getch(); - if (IsTerminator(ch)) - { - if (ctx.length >= opt.minLen) - break; // goto normal exit (keep history) - if (opt.interruptible) - return ctx.length; - // abandon history - } - else if ((ch == ESCAPE) && opt.interruptible) - { - return -1; - } - else if (ch == SPECIAL_LEADING) - { - ch = _getch(); - _special_input_handler(ch, opt, ctx); - } - else if (ch == BACKSPACE) - { - _insert_backspace(opt, ctx); - } - else if (ch == CTRL_BACKSPACE) - { - _insert_ctrl_backspace(opt, ctx); - } - else if (ch == TAB) - { - _insert_completion(opt, ctx); - } - else if (ctx.length < opt.maxLen) - { - ctx.ch = ch; - _insert_char(opt, ctx); - } + _special_input_handler(ch, opt, ctx); + } + else if (ch == BACKSPACE) + { + _insert_backspace(opt, ctx); } + else if (ch == CTRL_BACKSPACE) + { + _insert_ctrl_backspace(opt, ctx); + } + else if (ch == TAB) + { + _insert_completion(opt, ctx); + } + else if (ctx.length < opt.maxLen) + { + ctx.ch = ch; + _insert_char(opt, ctx); + } + } - if (ctx.history && !IsNullOrEmpty(ctx.buffer)) - opt.history->Push(ctx.buffer); + if (ctx.history && !IsNullOrEmpty(ctx.buffer)) + opt.history->Push(ctx.buffer); - return ctx.length; - } + return ctx.length; +} - static void ResetInput(SHORT beginX, int maxLen, int& pos, int& length, char* input, char* history) - { - if (!history) - return; - Clear(beginX, beginX + length); - InsertText("%.*s", maxLen, history); - length = std::min(maxLen, static_cast(strlen(history))); - pos = length; +static void ResetInput(SHORT beginX, int maxLen, int& pos, int& length, char* input, char* history) +{ + if (!history) + return; + + Clear(beginX, beginX + length); + InsertText("%.*s", maxLen, history); + length = std::min(maxLen, static_cast(strlen(history))); + pos = length; + + strncpy(input, history, length); + input[length] = '\0'; +} - strncpy(input, history, length); - input[length] = '\0'; - } - static void InputPlaceholder(const InputOptions& opt, InputContext& ctx) +static void InputPlaceholder(const InputOptions& opt, InputContext& ctx) +{ + if (!opt.placeholder) + return; + for (const char* p = opt.placeholder; *p; p++) { - if (!opt.placeholder) - return; - for (const char* p = opt.placeholder; *p; p++) - { - ctx.ch = *p; - _insert_char(opt, ctx); - } + ctx.ch = *p; + _insert_char(opt, ctx); } +} - static void _reset_input(const InputOptions& opt, InputContext& ctx) - { - if (!ctx.history) - return; - Clear(ctx.origin.X, ctx.origin.X + ctx.length); - InsertText("%.*s", opt.maxLen, *ctx.history); - ctx.length = std::min(opt.maxLen, static_cast(strlen(*ctx.history))); - ctx.pos = ctx.length; +static void _reset_input(const InputOptions& opt, InputContext& ctx) +{ + if (!ctx.history) + return; - strncpy(ctx.buffer, *ctx.history, ctx.length); - ctx.buffer[ctx.length] = '\0'; - } + Clear(ctx.origin.X, ctx.origin.X + ctx.length); + InsertText("%.*s", opt.maxLen, *ctx.history); + ctx.length = std::min(opt.maxLen, static_cast(strlen(*ctx.history))); + ctx.pos = ctx.length; - static void _insert_char(const InputOptions& opt, InputContext& ctx) - { - if (opt.verifier && !opt.verifier(ctx.ch)) - return; + strncpy(ctx.buffer, *ctx.history, ctx.length); + ctx.buffer[ctx.length] = '\0'; +} - if ((ctx.length < opt.maxLen) && isprint(ctx.ch)) - { - for (int i = ctx.length; i > ctx.pos; i--) - ctx.buffer[i] = ctx.buffer[i - 1]; - ctx.buffer[ctx.pos] = ctx.ch; - ctx.length++; - ctx.buffer[ctx.length] = '\0'; - for (int i = ctx.pos; i < ctx.length; i++) - InsertChar(opt.decoy ? opt.decoy : ctx.buffer[i]); - ctx.pos++; - InsertBackspace(ctx.length - ctx.pos); - } + +static void _insert_char(const InputOptions& opt, InputContext& ctx) +{ + if (opt.verifier && !opt.verifier(ctx.ch)) + return; + + if ((ctx.length < opt.maxLen) && isprint(ctx.ch)) + { + for (int i = ctx.length; i > ctx.pos; i--) + ctx.buffer[i] = ctx.buffer[i - 1]; + ctx.buffer[ctx.pos] = ctx.ch; + ctx.length++; + ctx.buffer[ctx.length] = '\0'; + for (int i = ctx.pos; i < ctx.length; i++) + InsertChar(opt.decoy ? opt.decoy : ctx.buffer[i]); + ctx.pos++; + InsertBackspace(ctx.length - ctx.pos); } +} - static void _insert_backspace(const InputOptions& opt, InputContext& ctx) + +static void _insert_backspace(const InputOptions& opt, InputContext& ctx) +{ + if (ctx.pos > 0) { - if (ctx.pos > 0) + InsertDelete(); + for (int i = ctx.pos; i < ctx.length; i++) { - InsertDelete(); - for (int i = ctx.pos; i < ctx.length; i++) - { - InsertChar(opt.decoy ? opt.decoy : ctx.buffer[i]); - ctx.buffer[i - 1] = ctx.buffer[i]; - } - InsertChar(SPACE); - InsertBackspace(ctx.length - ctx.pos + 1); - ctx.pos--; - ctx.length--; - ctx.buffer[ctx.length] = '\0'; + InsertChar(opt.decoy ? opt.decoy : ctx.buffer[i]); + ctx.buffer[i - 1] = ctx.buffer[i]; } + InsertChar(SPACE); + InsertBackspace(ctx.length - ctx.pos + 1); + ctx.pos--; + ctx.length--; + ctx.buffer[ctx.length] = '\0'; } +} - static void _insert_ctrl_backspace(const InputOptions& opt, InputContext& ctx) - { - while ((ctx.pos > 0) && !isalnum(ctx.buffer[ctx.pos - 1])) - _insert_backspace(opt, ctx); - while ((ctx.pos > 0) && isalnum(ctx.buffer[ctx.pos - 1])) - _insert_backspace(opt, ctx); - } - static void _insert_completion(const InputOptions& opt, InputContext& ctx) - { - if (!opt.completer) - return; +static void _insert_ctrl_backspace(const InputOptions& opt, InputContext& ctx) +{ + while ((ctx.pos > 0) && !isalnum(ctx.buffer[ctx.pos - 1])) + _insert_backspace(opt, ctx); + while ((ctx.pos > 0) && isalnum(ctx.buffer[ctx.pos - 1])) + _insert_backspace(opt, ctx); +} - int revert; - const char* completion = opt.completer(ctx.buffer, &revert); - if (!completion) - return; - _special_end(opt, ctx); // set cursor to the end of input - while (revert-- > 0) - _insert_backspace(opt, ctx); +static void _insert_completion(const InputOptions& opt, InputContext& ctx) +{ + if (!opt.completer) + return; - while (*completion) - { - ctx.ch = *completion; - _insert_char(opt, ctx); - completion++; - } - } + int revert; + const char* completion = opt.completer(ctx.buffer, &revert); + if (!completion) + return; + + _special_end(opt, ctx); // set cursor to the end of input + while (revert-- > 0) + _insert_backspace(opt, ctx); - static void _special_input_handler(char ch, const InputOptions& opt, InputContext& ctx) + while (*completion) { - switch (ch) - { - case SPECIAL_ARROW_LEFT: - _special_arrow_left(opt, ctx); - break; - case SPECIAL_ARROW_RIGHT: - _special_arrow_right(opt, ctx); - break; - case SPECIAL_ARROW_UP: - _special_arrow_up(opt, ctx); - break; - case SPECIAL_ARROW_DOWN: - _special_arrow_down(opt, ctx); - break; - case SPECIAL_ARROW_CTRL_LEFT: - _special_arrow_ctrl_left(opt, ctx); - break; - case SPECIAL_ARROW_CTRL_RIGHT: - _special_arrow_ctrl_right(opt, ctx); - break; - case SPECIAL_DELETE: - _special_delete(opt, ctx); - break; - case SPECIAL_CTRL_DELETE: - _special_ctrl_delete(opt, ctx); - break; - case SPECIAL_HOME: - _special_home(opt, ctx); - break; - case SPECIAL_END: - _special_end(opt, ctx); - break; - default: - break; - } + ctx.ch = *completion; + _insert_char(opt, ctx); + completion++; } +} - static void _special_arrow_left(const InputOptions& opt, InputContext& ctx) + +static void _special_input_handler(char ch, const InputOptions& opt, InputContext& ctx) +{ + switch (ch) { - if (ctx.pos > 0) - { - InsertBackspace(); - ctx.pos--; - } + case SPECIAL_ARROW_LEFT: + _special_arrow_left(opt, ctx); + break; + case SPECIAL_ARROW_RIGHT: + _special_arrow_right(opt, ctx); + break; + case SPECIAL_ARROW_UP: + _special_arrow_up(opt, ctx); + break; + case SPECIAL_ARROW_DOWN: + _special_arrow_down(opt, ctx); + break; + case SPECIAL_ARROW_CTRL_LEFT: + _special_arrow_ctrl_left(opt, ctx); + break; + case SPECIAL_ARROW_CTRL_RIGHT: + _special_arrow_ctrl_right(opt, ctx); + break; + case SPECIAL_DELETE: + _special_delete(opt, ctx); + break; + case SPECIAL_CTRL_DELETE: + _special_ctrl_delete(opt, ctx); + break; + case SPECIAL_HOME: + _special_home(opt, ctx); + break; + case SPECIAL_END: + _special_end(opt, ctx); + break; + default: + break; } +} - static void _special_arrow_right(const InputOptions& opt, InputContext& ctx) + +static void _special_arrow_left(const InputOptions& opt, InputContext& ctx) +{ + if (ctx.pos > 0) { - if (ctx.pos < ctx.length) - { - InsertChar(opt.decoy ? opt.decoy : ctx.buffer[ctx.pos]); - ctx.pos++; - } + InsertBackspace(); + ctx.pos--; } +} - static void _special_arrow_up(const InputOptions& opt, InputContext& ctx) + +static void _special_arrow_right(const InputOptions& opt, InputContext& ctx) +{ + if (ctx.pos < ctx.length) { - if (ctx.history) - { - if (ctx.history > ctx.history_end) - ctx.history--; - _reset_input(opt, ctx); - } + InsertChar(opt.decoy ? opt.decoy : ctx.buffer[ctx.pos]); + ctx.pos++; } +} + - static void _special_arrow_down(const InputOptions& opt, InputContext& ctx) +static void _special_arrow_up(const InputOptions& opt, InputContext& ctx) +{ + if (ctx.history) { - if (ctx.history) - { - if (ctx.history < ctx.history_begin) - ctx.history++; - _reset_input(opt, ctx); - } + if (ctx.history > ctx.history_end) + ctx.history--; + _reset_input(opt, ctx); } +} + - static void _special_arrow_ctrl_left(const InputOptions& opt, InputContext& ctx) +static void _special_arrow_down(const InputOptions& opt, InputContext& ctx) +{ + if (ctx.history) { - while ((ctx.pos > 0) && !isalnum(ctx.buffer[ctx.pos - 1])) - { - InsertBackspace(); - ctx.pos--; - } - while ((ctx.pos > 0) && isalnum(ctx.buffer[ctx.pos - 1])) - { - InsertBackspace(); - ctx.pos--; - } + if (ctx.history < ctx.history_begin) + ctx.history++; + _reset_input(opt, ctx); } +} + - static void _special_arrow_ctrl_right(const InputOptions& opt, InputContext& ctx) +static void _special_arrow_ctrl_left(const InputOptions& opt, InputContext& ctx) +{ + while ((ctx.pos > 0) && !isalnum(ctx.buffer[ctx.pos - 1])) { - while ((ctx.pos < ctx.length) && isalnum(ctx.buffer[ctx.pos])) - { - InsertChar(opt.decoy ? opt.decoy : ctx.buffer[ctx.pos]); - ctx.pos++; - } - while ((ctx.pos < ctx.length) && !isalnum(ctx.buffer[ctx.pos])) - { - InsertChar(opt.decoy ? opt.decoy : ctx.buffer[ctx.pos]); - ctx.pos++; - } + InsertBackspace(); + ctx.pos--; } + while ((ctx.pos > 0) && isalnum(ctx.buffer[ctx.pos - 1])) + { + InsertBackspace(); + ctx.pos--; + } +} + - static void _special_delete(const InputOptions& opt, InputContext& ctx) +static void _special_arrow_ctrl_right(const InputOptions& opt, InputContext& ctx) +{ + while ((ctx.pos < ctx.length) && isalnum(ctx.buffer[ctx.pos])) { - if (ctx.pos < ctx.length) - { - for (int i = ctx.pos + 1; i < ctx.length; i++) - { - ctx.buffer[i - 1] = ctx.buffer[i]; - InsertChar(opt.decoy ? opt.decoy : ctx.buffer[i]); - } - InsertChar(SPACE); - InsertBackspace(ctx.length - ctx.pos); - ctx.length--; - ctx.buffer[ctx.length] = '\0'; - } + InsertChar(opt.decoy ? opt.decoy : ctx.buffer[ctx.pos]); + ctx.pos++; + } + while ((ctx.pos < ctx.length) && !isalnum(ctx.buffer[ctx.pos])) + { + InsertChar(opt.decoy ? opt.decoy : ctx.buffer[ctx.pos]); + ctx.pos++; } +} + - static void _special_ctrl_delete(const InputOptions& opt, InputContext& ctx) +static void _special_delete(const InputOptions& opt, InputContext& ctx) +{ + if (ctx.pos < ctx.length) { - if (isalnum(ctx.buffer[ctx.pos])) + for (int i = ctx.pos + 1; i < ctx.length; i++) { - while ((ctx.pos < ctx.length) && isalnum(ctx.buffer[ctx.pos])) - _special_delete(opt, ctx); + ctx.buffer[i - 1] = ctx.buffer[i]; + InsertChar(opt.decoy ? opt.decoy : ctx.buffer[i]); } - while ((ctx.pos < ctx.length) && !isalnum(ctx.buffer[ctx.pos])) - _special_delete(opt, ctx); + InsertChar(SPACE); + InsertBackspace(ctx.length - ctx.pos); + ctx.length--; + ctx.buffer[ctx.length] = '\0'; } +} - static void _special_home(const InputOptions& opt, InputContext& ctx) - { - InsertBackspace(ctx.pos); - ctx.pos = 0; - } - static void _special_end(const InputOptions& opt, InputContext& ctx) +static void _special_ctrl_delete(const InputOptions& opt, InputContext& ctx) +{ + if (isalnum(ctx.buffer[ctx.pos])) { - for (int i = ctx.pos; i < ctx.length; i++) - InsertChar(opt.decoy ? opt.decoy : ctx.buffer[i]); - ctx.pos = ctx.length; + while ((ctx.pos < ctx.length) && isalnum(ctx.buffer[ctx.pos])) + _special_delete(opt, ctx); } + while ((ctx.pos < ctx.length) && !isalnum(ctx.buffer[ctx.pos])) + _special_delete(opt, ctx); +} + + +static void _special_home(const InputOptions& opt, InputContext& ctx) +{ + InsertBackspace(ctx.pos); + ctx.pos = 0; +} + + +static void _special_end(const InputOptions& opt, InputContext& ctx) +{ + for (int i = ctx.pos; i < ctx.length; i++) + InsertChar(opt.decoy ? opt.decoy : ctx.buffer[i]); + ctx.pos = ctx.length; +} + _CNSL_END diff --git a/Console/src/InputAux.cpp b/Console/src/InputAux.cpp index a54bce3..e0c5969 100644 --- a/Console/src/InputAux.cpp +++ b/Console/src/InputAux.cpp @@ -27,98 +27,106 @@ #include _CNSL_BEGIN - static constexpr char INPUT_TERMINATOR[] = "\n\r"; +static constexpr char INPUT_TERMINATOR[] = "\n\r"; - bool IsTerminator(char ch) - { - for (const char* p = INPUT_TERMINATOR; *p; p++) - { - if (*p == ch) - return true; - } - - return false; - } - bool IsNullOrEmpty(const char* str) +bool IsTerminator(char ch) +{ + for (const char* p = INPUT_TERMINATOR; *p; p++) { - return !str || !*str; + if (*p == ch) + return true; } - bool IsEqual(const char* str1, const char* str2) - { - return strcmp(str1, str2) == 0; - } + return false; +} - /* - * return the position after the end of the same part. - * Return value: - * nullptr: str and prefix are the same - * str : str does not begin with prefix - */ - const char* BeginsWith(const char* str, const char* prefix) - { - if (IsNullOrEmpty(str) || IsNullOrEmpty(prefix)) - return str; - - const char* original_str = str; - while (*prefix && *str) - { - if (*prefix != *str) - return original_str; - prefix++; - str++; - } +bool IsNullOrEmpty(const char* str) +{ + return !str || !*str; +} + + +bool IsEqual(const char* str1, const char* str2) +{ + return strcmp(str1, str2) == 0; +} + + +/* + * return the position after the end of the same part. + * Return value: + * nullptr: str and prefix are the same + * str : str does not begin with prefix + */ +const char* BeginsWith(const char* str, const char* prefix) +{ + if (IsNullOrEmpty(str) || IsNullOrEmpty(prefix)) return str; + + const char* original_str = str; + while (*prefix && *str) + { + if (*prefix != *str) + return original_str; + prefix++; + str++; } - /* - * return the position after the end of the same part. - * Return value: - * nullptr: str does not end with suffix - * str : str and suffix are the same - */ - const char* EndsWidth(const char* str, const char* suffix) + return str; +} + + +/* + * return the position after the end of the same part. + * Return value: + * nullptr: str does not end with suffix + * str : str and suffix are the same + */ +const char* EndsWidth(const char* str, const char* suffix) +{ + if (IsNullOrEmpty(str) || IsNullOrEmpty(suffix)) + return nullptr; + + const char* str_end = str + strlen(str); + const char* suffix_end = suffix + strlen(suffix); + + while (str_end >= str && suffix_end >= suffix) { - if (IsNullOrEmpty(str) || IsNullOrEmpty(suffix)) + if (*str_end != *suffix_end) return nullptr; + str_end--; + suffix_end--; + } - const char* str_end = str + strlen(str); - const char* suffix_end = suffix + strlen(suffix); + return str_end; +} - while (str_end >= str && suffix_end >= suffix) - { - if (*str_end != *suffix_end) - return nullptr; - str_end--; - suffix_end--; - } - return str_end; - } +void FlushInput() +{ + static HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); - void FlushInput() - { - static HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); + FlushConsoleInputBuffer(hInput); +} - FlushConsoleInputBuffer(hInput); - } - void WaitForKey(const char* prompt, char key) +void WaitForKey(const char* prompt, char key) +{ + InsertText(prompt); + + FlushInput(); + + for (int i = 0; ; i++) { - InsertText(prompt); - - FlushInput(); - - for (int i = 0; ; i++) - { - char ch = _getch(); - if (ch == key) - break; - if (key == static_cast(0)) - break; - } + char ch = _getch(); + if (ch == key) + break; + if (key == static_cast(0)) + break; } +} + _CNSL_END diff --git a/Console/src/InputHistory.cpp b/Console/src/InputHistory.cpp index 031359f..7135f84 100644 --- a/Console/src/InputHistory.cpp +++ b/Console/src/InputHistory.cpp @@ -24,31 +24,35 @@ #include "../inc/Input.h" _CNSL_BEGIN - InputHistory::InputHistory() - { - _record.push_back(_strdup("")); - } - - InputHistory::~InputHistory() - { - // Perhaps - for (auto it : _record) - free(it); - } - - void InputHistory::Push(const char* history) - { - if (!((_record.size() > 1) && (strcmp(*(_record.end() - 2), history) == 0))) - _record.insert(_record.end() - 1, _strdup(history)); - } - - void InputHistory::Clear() - { - for (auto it : _record) - free(it); - _record.clear(); - - _record.push_back(_strdup("")); - } +InputHistory::InputHistory() +{ + _record.push_back(_strdup("")); +} + + +InputHistory::~InputHistory() +{ + // Perhaps + for (auto it : _record) + free(it); +} + + +void InputHistory::Push(const char* history) +{ + if (!((_record.size() > 1) && (strcmp(*(_record.end() - 2), history) == 0))) + _record.insert(_record.end() - 1, _strdup(history)); +} + + +void InputHistory::Clear() +{ + for (auto it : _record) + free(it); + _record.clear(); + + _record.push_back(_strdup("")); +} + _CNSL_END diff --git a/Console/src/Output.cpp b/Console/src/Output.cpp index 0aea951..a54a2dd 100644 --- a/Console/src/Output.cpp +++ b/Console/src/Output.cpp @@ -29,210 +29,230 @@ #include _CNSL_BEGIN - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Output Control - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - static bool IsNewLine(char ch) +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Output Control +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +static bool IsNewLine(char ch) +{ + return (ch == LINE_FEED) || (ch == CHARRIGE); +} + + +void InsertLineFeed() +{ + COORD pos = GetCursorPosition(); + pos.Y++; + + if (!SetCursorPosition(pos, nullptr)) { - return (ch == LINE_FEED) || (ch == CHARRIGE); + // out of bound + Reprint(); } +} - void InsertLineFeed() - { - COORD pos = GetCursorPosition(); - pos.Y++; - - if (!SetCursorPosition(pos, nullptr)) - { - // out of bound - Reprint(); - } - } - void InsertLineFeed(int n) - { - for (int i = 0; i < n; i++) - InsertLineFeed(); - } +void InsertLineFeed(int n) +{ + for (int i = 0; i < n; i++) + InsertLineFeed(); +} - void InsertCarrige() - { - putchar(CHARRIGE); - } - void InsertNewLine() - { - putchar(CHARRIGE); - InsertLineFeed(); - } +void InsertCarrige() +{ + putchar(CHARRIGE); +} - void InsertNewLine(int n) - { - for (int i = 0; i < n; i++) - InsertNewLine(); - } - void InsertReverseLineFeed() - { - COORD pos = GetCursorPosition(); - if (pos.Y > 0) - { - pos.Y--; - SetCursorPosition(pos, nullptr); - } - } +void InsertNewLine() +{ + putchar(CHARRIGE); + InsertLineFeed(); +} + + +void InsertNewLine(int n) +{ + for (int i = 0; i < n; i++) + InsertNewLine(); +} - void InsertReverseLineFeed(int n) + +void InsertReverseLineFeed() +{ + COORD pos = GetCursorPosition(); + if (pos.Y > 0) { - for (int i = 0; i < n; i++) - InsertReverseLineFeed(); + pos.Y--; + SetCursorPosition(pos, nullptr); } +} - void InsertReverseNewLine() - { - putchar(CHARRIGE); + +void InsertReverseLineFeed(int n) +{ + for (int i = 0; i < n; i++) InsertReverseLineFeed(); - } +} - void InsertReverseNewLine(int n) - { - for (int i = 0; i < n; i++) - InsertReverseNewLine(); - } - void InsertBackspace() - { - putchar(BACKSPACE); - } +void InsertReverseNewLine() +{ + putchar(CHARRIGE); + InsertReverseLineFeed(); +} - void InsertBackspace(int n) - { - for (int i = 0; i < n; i++) - InsertBackspace(); - } - void InsertDelete() - { - putchar(BACKSPACE); - putchar(SPACE); - putchar(BACKSPACE); - } +void InsertReverseNewLine(int n) +{ + for (int i = 0; i < n; i++) + InsertReverseNewLine(); +} - void InsertDelete(int n) - { - for (int i = 0; i < n; i++) - InsertDelete(); - } - void InsertChar(const char ch) - { - if (ch == CHARRIGE) - InsertCarrige(); - else if (ch == LINE_FEED) - InsertLineFeed(); - else - putchar(ch); - } +void InsertBackspace() +{ + putchar(BACKSPACE); +} - void InsertChar(const char ch, int n) - { - for (int i = 0; i < n; i++) - InsertChar(ch); - } - void InsertText(const char* format, ...) - { - static char buffer[256]; +void InsertBackspace(int n) +{ + for (int i = 0; i < n; i++) + InsertBackspace(); +} - if (!format) - return; - va_list args; +void InsertDelete() +{ + putchar(BACKSPACE); + putchar(SPACE); + putchar(BACKSPACE); +} - va_start(args, format); - vsprintf_s(buffer, format, args); - va_end(args); - for (const char* p = buffer; *p; p++) - { - if (IsNewLine(*p)) - InsertNewLine(); - else - InsertChar(*p); - } - } +void InsertDelete(int n) +{ + for (int i = 0; i < n; i++) + InsertDelete(); +} + + +void InsertChar(const char ch) +{ + if (ch == CHARRIGE) + InsertCarrige(); + else if (ch == LINE_FEED) + InsertLineFeed(); + else + putchar(ch); +} + - void InsertText(WORD foreground, const char* format, ...) +void InsertChar(const char ch, int n) +{ + for (int i = 0; i < n; i++) + InsertChar(ch); +} + + +void InsertText(const char* format, ...) +{ + static char buffer[256]; + + if (!format) + return; + + va_list args; + + va_start(args, format); + vsprintf_s(buffer, format, args); + va_end(args); + + for (const char* p = buffer; *p; p++) { - static char buffer[256]; - - if (!format) - return; - - va_list args; - va_start(args, format); - vsprintf_s(buffer, format, args); - va_end(args); - - WORD old = SetTextForeground(foreground); - for (const char* p = buffer; *p; p++) - { - if (IsNewLine(*p)) - InsertNewLine(); - else - InsertChar(*p); - } - SetTextForeground(old); + if (IsNewLine(*p)) + InsertNewLine(); + else + InsertChar(*p); } +} - void InsertSplitLine(char split) - { - if (IsNewLine(split)) - return; - SHORT width = GetConsoleWidth(); +void InsertText(WORD foreground, const char* format, ...) +{ + static char buffer[256]; - Clear(0); - InsertCarrige(); + if (!format) + return; - for (SHORT i = 0; i < width; i++) - InsertChar(split); + va_list args; + va_start(args, format); + vsprintf_s(buffer, format, args); + va_end(args); - InsertNewLine(); + WORD old = SetTextForeground(foreground); + for (const char* p = buffer; *p; p++) + { + if (IsNewLine(*p)) + InsertNewLine(); + else + InsertChar(*p); } + SetTextForeground(old); +} - void InsertHeaderLine(const char* header, char split) - { - if (!header) - return; - if (IsNewLine(split)) - return; - SHORT width = GetConsoleWidth(); +void InsertSplitLine(char split) +{ + if (IsNewLine(split)) + return; - Clear(0); - InsertCarrige(); + SHORT width = GetConsoleWidth(); - SHORT length = static_cast(strlen(header)); - SHORT begin = (width - length) / static_cast(2); - SHORT i; + Clear(0); + InsertCarrige(); - for (i = 0; i < begin - 1; i++) - InsertChar(split); + for (SHORT i = 0; i < width; i++) + InsertChar(split); - InsertChar(SPACE); - i++; - InsertText(header); - i += length; - InsertChar(SPACE); - i++; + InsertNewLine(); +} - for (i; i < width; i++) - InsertChar(split); - InsertNewLine(); - } +void InsertHeaderLine(const char* header, char split) +{ + if (!header) + return; + if (IsNewLine(split)) + return; + + SHORT width = GetConsoleWidth(); + + Clear(0); + InsertCarrige(); + + SHORT length = static_cast(strlen(header)); + SHORT begin = (width - length) / static_cast(2); + SHORT i; + + for (i = 0; i < begin - 1; i++) + InsertChar(split); + + InsertChar(SPACE); + i++; + InsertText(header); + i += length; + InsertChar(SPACE); + i++; + + for (i; i < width; i++) + InsertChar(split); + + InsertNewLine(); +} + _CNSL_END diff --git a/Hash/inc/md5_core.h b/Hash/inc/md5_core.h index 864a5a6..16ab746 100644 --- a/Hash/inc/md5_core.h +++ b/Hash/inc/md5_core.h @@ -34,48 +34,52 @@ #include _HASH_BEGIN - class MD5 //: public Hash - { - public: - /// split into 64 byte blocks (=> 512 bits), hash is 16 bytes long - enum { BlockSize = 512 / 8, HashBytes = 16 }; - - /// same as reset() - MD5(); - - /// compute MD5 of a memory block - std::string operator()(const void* data, size_t numBytes); - /// compute MD5 of a string, excluding final zero - std::string operator()(const std::string& text); - - /// add arbitrary number of bytes - void Add(const void* data, size_t numBytes); - - /// return latest hash as 32 hex characters - std::string GetHash(); - /// return latest hash as bytes - void GetHash(unsigned char buffer[HashBytes]); - - /// restart - void Reset(); - - private: - /// process 64 bytes - void _ProcessBlock(const void* data); - /// process everything left in the internal buffer - void _ProcessBuffer(); - - /// size of processed data in bytes - uint64_t m_numBytes; - /// valid bytes in m_buffer - size_t m_bufferSize; - /// bytes not processed yet - uint8_t m_buffer[BlockSize]; - - enum { HashValues = HashBytes / 4 }; - - /// hash, stored as integers - uint32_t m_hash[HashValues]; - }; +class MD5 //: public Hash +{ +public: + /// split into 64 byte blocks (=> 512 bits), hash is 16 bytes long + enum { BlockSize = 512 / 8, HashBytes = 16 }; + + + /// same as reset() + MD5(); + + /// compute MD5 of a memory block + std::string operator()(const void* data, size_t numBytes); + /// compute MD5 of a string, excluding final zero + std::string operator()(const std::string& text); + + /// add arbitrary number of bytes + void Add(const void* data, size_t numBytes); + + /// return latest hash as 32 hex characters + std::string GetHash(); + /// return latest hash as bytes + void GetHash(unsigned char buffer[HashBytes]); + + /// restart + void Reset(); + +private: + /// process 64 bytes + void _ProcessBlock(const void* data); + /// process everything left in the internal buffer + void _ProcessBuffer(); + + /// size of processed data in bytes + uint64_t m_numBytes; + /// valid bytes in m_buffer + size_t m_bufferSize; + /// bytes not processed yet + uint8_t m_buffer[BlockSize]; + + + enum { HashValues = HashBytes / 4 }; + + + /// hash, stored as integers + uint32_t m_hash[HashValues]; +}; + _HASH_END diff --git a/Hash/src/md5_core.cpp b/Hash/src/md5_core.cpp index 9bd4847..270d59e 100644 --- a/Hash/src/md5_core.cpp +++ b/Hash/src/md5_core.cpp @@ -29,52 +29,56 @@ #include "../inc/md5_core.h" _HASH_BEGIN - /// same as reset() - MD5::MD5() - { - Reset(); - } +/// same as reset() +MD5::MD5() +{ + Reset(); +} - /// restart - void MD5::Reset() - { - m_numBytes = 0; - m_bufferSize = 0; +/// restart +void MD5::Reset() +{ + m_numBytes = 0; + m_bufferSize = 0; + + // according to RFC 1321 + m_hash[0] = 0x67452301; + m_hash[1] = 0xefcdab89; + m_hash[2] = 0x98badcfe; + m_hash[3] = 0x10325476; +} - // according to RFC 1321 - m_hash[0] = 0x67452301; - m_hash[1] = 0xefcdab89; - m_hash[2] = 0x98badcfe; - m_hash[3] = 0x10325476; - } +// mix functions for processBlock() +static inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d) +{ + return d ^ (b & (c ^ d)); // original: f = (b & c) | ((~b) & d); +} - // mix functions for processBlock() - static inline uint32_t f1(uint32_t b, uint32_t c, uint32_t d) - { - return d ^ (b & (c ^ d)); // original: f = (b & c) | ((~b) & d); - } - static inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d) - { - return c ^ (d & (b ^ c)); // original: f = (b & d) | (c & (~d)); - } +static inline uint32_t f2(uint32_t b, uint32_t c, uint32_t d) +{ + return c ^ (d & (b ^ c)); // original: f = (b & d) | (c & (~d)); +} - static inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d) - { - return b ^ c ^ d; - } - static inline uint32_t f4(uint32_t b, uint32_t c, uint32_t d) - { - return c ^ (b | ~d); - } +static inline uint32_t f3(uint32_t b, uint32_t c, uint32_t d) +{ + return b ^ c ^ d; +} - static inline uint32_t rotate(uint32_t a, uint32_t c) - { - return (a << c) | (a >> (32 - c)); - } + +static inline uint32_t f4(uint32_t b, uint32_t c, uint32_t d) +{ + return c ^ (b | ~d); +} + + +static inline uint32_t rotate(uint32_t a, uint32_t c) +{ + return (a << c) | (a >> (32 - c)); +} #if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN) inline uint32_t swap(uint32_t x) @@ -94,311 +98,312 @@ inline uint32_t swap(uint32_t x) #endif - /// process 64 bytes - void MD5::_ProcessBlock(const void* data) - { - // get last hash - uint32_t a = m_hash[0]; - uint32_t b = m_hash[1]; - uint32_t c = m_hash[2]; - uint32_t d = m_hash[3]; +/// process 64 bytes +void MD5::_ProcessBlock(const void* data) +{ + // get last hash + uint32_t a = m_hash[0]; + uint32_t b = m_hash[1]; + uint32_t c = m_hash[2]; + uint32_t d = m_hash[3]; - // data represented as 16x 32-bit words - const uint32_t* words = (uint32_t*)data; + // data represented as 16x 32-bit words + const uint32_t* words = (uint32_t*)data; - // computations are little endian, swap data if necessary + // computations are little endian, swap data if necessary #if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN) #define LITTLEENDIAN(x) swap(x) #else #define LITTLEENDIAN(x) (x) #endif - // first round - uint32_t word0 = LITTLEENDIAN(words[0]); - a = rotate(a + f1(b, c, d) + word0 + 0xd76aa478, 7) + b; - uint32_t word1 = LITTLEENDIAN(words[1]); - d = rotate(d + f1(a, b, c) + word1 + 0xe8c7b756, 12) + a; - uint32_t word2 = LITTLEENDIAN(words[2]); - c = rotate(c + f1(d, a, b) + word2 + 0x242070db, 17) + d; - uint32_t word3 = LITTLEENDIAN(words[3]); - b = rotate(b + f1(c, d, a) + word3 + 0xc1bdceee, 22) + c; - - uint32_t word4 = LITTLEENDIAN(words[4]); - a = rotate(a + f1(b, c, d) + word4 + 0xf57c0faf, 7) + b; - uint32_t word5 = LITTLEENDIAN(words[5]); - d = rotate(d + f1(a, b, c) + word5 + 0x4787c62a, 12) + a; - uint32_t word6 = LITTLEENDIAN(words[6]); - c = rotate(c + f1(d, a, b) + word6 + 0xa8304613, 17) + d; - uint32_t word7 = LITTLEENDIAN(words[7]); - b = rotate(b + f1(c, d, a) + word7 + 0xfd469501, 22) + c; - - uint32_t word8 = LITTLEENDIAN(words[8]); - a = rotate(a + f1(b, c, d) + word8 + 0x698098d8, 7) + b; - uint32_t word9 = LITTLEENDIAN(words[9]); - d = rotate(d + f1(a, b, c) + word9 + 0x8b44f7af, 12) + a; - uint32_t word10 = LITTLEENDIAN(words[10]); - c = rotate(c + f1(d, a, b) + word10 + 0xffff5bb1, 17) + d; - uint32_t word11 = LITTLEENDIAN(words[11]); - b = rotate(b + f1(c, d, a) + word11 + 0x895cd7be, 22) + c; - - uint32_t word12 = LITTLEENDIAN(words[12]); - a = rotate(a + f1(b, c, d) + word12 + 0x6b901122, 7) + b; - uint32_t word13 = LITTLEENDIAN(words[13]); - d = rotate(d + f1(a, b, c) + word13 + 0xfd987193, 12) + a; - uint32_t word14 = LITTLEENDIAN(words[14]); - c = rotate(c + f1(d, a, b) + word14 + 0xa679438e, 17) + d; - uint32_t word15 = LITTLEENDIAN(words[15]); - b = rotate(b + f1(c, d, a) + word15 + 0x49b40821, 22) + c; - - // second round - a = rotate(a + f2(b, c, d) + word1 + 0xf61e2562, 5) + b; - d = rotate(d + f2(a, b, c) + word6 + 0xc040b340, 9) + a; - c = rotate(c + f2(d, a, b) + word11 + 0x265e5a51, 14) + d; - b = rotate(b + f2(c, d, a) + word0 + 0xe9b6c7aa, 20) + c; - - a = rotate(a + f2(b, c, d) + word5 + 0xd62f105d, 5) + b; - d = rotate(d + f2(a, b, c) + word10 + 0x02441453, 9) + a; - c = rotate(c + f2(d, a, b) + word15 + 0xd8a1e681, 14) + d; - b = rotate(b + f2(c, d, a) + word4 + 0xe7d3fbc8, 20) + c; - - a = rotate(a + f2(b, c, d) + word9 + 0x21e1cde6, 5) + b; - d = rotate(d + f2(a, b, c) + word14 + 0xc33707d6, 9) + a; - c = rotate(c + f2(d, a, b) + word3 + 0xf4d50d87, 14) + d; - b = rotate(b + f2(c, d, a) + word8 + 0x455a14ed, 20) + c; - - a = rotate(a + f2(b, c, d) + word13 + 0xa9e3e905, 5) + b; - d = rotate(d + f2(a, b, c) + word2 + 0xfcefa3f8, 9) + a; - c = rotate(c + f2(d, a, b) + word7 + 0x676f02d9, 14) + d; - b = rotate(b + f2(c, d, a) + word12 + 0x8d2a4c8a, 20) + c; - - // third round - a = rotate(a + f3(b, c, d) + word5 + 0xfffa3942, 4) + b; - d = rotate(d + f3(a, b, c) + word8 + 0x8771f681, 11) + a; - c = rotate(c + f3(d, a, b) + word11 + 0x6d9d6122, 16) + d; - b = rotate(b + f3(c, d, a) + word14 + 0xfde5380c, 23) + c; - - a = rotate(a + f3(b, c, d) + word1 + 0xa4beea44, 4) + b; - d = rotate(d + f3(a, b, c) + word4 + 0x4bdecfa9, 11) + a; - c = rotate(c + f3(d, a, b) + word7 + 0xf6bb4b60, 16) + d; - b = rotate(b + f3(c, d, a) + word10 + 0xbebfbc70, 23) + c; - - a = rotate(a + f3(b, c, d) + word13 + 0x289b7ec6, 4) + b; - d = rotate(d + f3(a, b, c) + word0 + 0xeaa127fa, 11) + a; - c = rotate(c + f3(d, a, b) + word3 + 0xd4ef3085, 16) + d; - b = rotate(b + f3(c, d, a) + word6 + 0x04881d05, 23) + c; - - a = rotate(a + f3(b, c, d) + word9 + 0xd9d4d039, 4) + b; - d = rotate(d + f3(a, b, c) + word12 + 0xe6db99e5, 11) + a; - c = rotate(c + f3(d, a, b) + word15 + 0x1fa27cf8, 16) + d; - b = rotate(b + f3(c, d, a) + word2 + 0xc4ac5665, 23) + c; - - // fourth round - a = rotate(a + f4(b, c, d) + word0 + 0xf4292244, 6) + b; - d = rotate(d + f4(a, b, c) + word7 + 0x432aff97, 10) + a; - c = rotate(c + f4(d, a, b) + word14 + 0xab9423a7, 15) + d; - b = rotate(b + f4(c, d, a) + word5 + 0xfc93a039, 21) + c; - - a = rotate(a + f4(b, c, d) + word12 + 0x655b59c3, 6) + b; - d = rotate(d + f4(a, b, c) + word3 + 0x8f0ccc92, 10) + a; - c = rotate(c + f4(d, a, b) + word10 + 0xffeff47d, 15) + d; - b = rotate(b + f4(c, d, a) + word1 + 0x85845dd1, 21) + c; - - a = rotate(a + f4(b, c, d) + word8 + 0x6fa87e4f, 6) + b; - d = rotate(d + f4(a, b, c) + word15 + 0xfe2ce6e0, 10) + a; - c = rotate(c + f4(d, a, b) + word6 + 0xa3014314, 15) + d; - b = rotate(b + f4(c, d, a) + word13 + 0x4e0811a1, 21) + c; - - a = rotate(a + f4(b, c, d) + word4 + 0xf7537e82, 6) + b; - d = rotate(d + f4(a, b, c) + word11 + 0xbd3af235, 10) + a; - c = rotate(c + f4(d, a, b) + word2 + 0x2ad7d2bb, 15) + d; - b = rotate(b + f4(c, d, a) + word9 + 0xeb86d391, 21) + c; - - // update hash - m_hash[0] += a; - m_hash[1] += b; - m_hash[2] += c; - m_hash[3] += d; - } - - - /// add arbitrary number of bytes - void MD5::Add(const void* data, size_t numBytes) - { - auto current = static_cast(data); - - if (m_bufferSize > 0) - { - while (numBytes > 0 && m_bufferSize < BlockSize) - { - m_buffer[m_bufferSize++] = *current++; - numBytes--; - } - } - - // full buffer - if (m_bufferSize == BlockSize) - { - _ProcessBlock(m_buffer); - m_numBytes += BlockSize; - m_bufferSize = 0; - } + // first round + uint32_t word0 = LITTLEENDIAN(words[0]); + a = rotate(a + f1(b, c, d) + word0 + 0xd76aa478, 7) + b; + uint32_t word1 = LITTLEENDIAN(words[1]); + d = rotate(d + f1(a, b, c) + word1 + 0xe8c7b756, 12) + a; + uint32_t word2 = LITTLEENDIAN(words[2]); + c = rotate(c + f1(d, a, b) + word2 + 0x242070db, 17) + d; + uint32_t word3 = LITTLEENDIAN(words[3]); + b = rotate(b + f1(c, d, a) + word3 + 0xc1bdceee, 22) + c; + + uint32_t word4 = LITTLEENDIAN(words[4]); + a = rotate(a + f1(b, c, d) + word4 + 0xf57c0faf, 7) + b; + uint32_t word5 = LITTLEENDIAN(words[5]); + d = rotate(d + f1(a, b, c) + word5 + 0x4787c62a, 12) + a; + uint32_t word6 = LITTLEENDIAN(words[6]); + c = rotate(c + f1(d, a, b) + word6 + 0xa8304613, 17) + d; + uint32_t word7 = LITTLEENDIAN(words[7]); + b = rotate(b + f1(c, d, a) + word7 + 0xfd469501, 22) + c; + + uint32_t word8 = LITTLEENDIAN(words[8]); + a = rotate(a + f1(b, c, d) + word8 + 0x698098d8, 7) + b; + uint32_t word9 = LITTLEENDIAN(words[9]); + d = rotate(d + f1(a, b, c) + word9 + 0x8b44f7af, 12) + a; + uint32_t word10 = LITTLEENDIAN(words[10]); + c = rotate(c + f1(d, a, b) + word10 + 0xffff5bb1, 17) + d; + uint32_t word11 = LITTLEENDIAN(words[11]); + b = rotate(b + f1(c, d, a) + word11 + 0x895cd7be, 22) + c; + + uint32_t word12 = LITTLEENDIAN(words[12]); + a = rotate(a + f1(b, c, d) + word12 + 0x6b901122, 7) + b; + uint32_t word13 = LITTLEENDIAN(words[13]); + d = rotate(d + f1(a, b, c) + word13 + 0xfd987193, 12) + a; + uint32_t word14 = LITTLEENDIAN(words[14]); + c = rotate(c + f1(d, a, b) + word14 + 0xa679438e, 17) + d; + uint32_t word15 = LITTLEENDIAN(words[15]); + b = rotate(b + f1(c, d, a) + word15 + 0x49b40821, 22) + c; + + // second round + a = rotate(a + f2(b, c, d) + word1 + 0xf61e2562, 5) + b; + d = rotate(d + f2(a, b, c) + word6 + 0xc040b340, 9) + a; + c = rotate(c + f2(d, a, b) + word11 + 0x265e5a51, 14) + d; + b = rotate(b + f2(c, d, a) + word0 + 0xe9b6c7aa, 20) + c; + + a = rotate(a + f2(b, c, d) + word5 + 0xd62f105d, 5) + b; + d = rotate(d + f2(a, b, c) + word10 + 0x02441453, 9) + a; + c = rotate(c + f2(d, a, b) + word15 + 0xd8a1e681, 14) + d; + b = rotate(b + f2(c, d, a) + word4 + 0xe7d3fbc8, 20) + c; + + a = rotate(a + f2(b, c, d) + word9 + 0x21e1cde6, 5) + b; + d = rotate(d + f2(a, b, c) + word14 + 0xc33707d6, 9) + a; + c = rotate(c + f2(d, a, b) + word3 + 0xf4d50d87, 14) + d; + b = rotate(b + f2(c, d, a) + word8 + 0x455a14ed, 20) + c; + + a = rotate(a + f2(b, c, d) + word13 + 0xa9e3e905, 5) + b; + d = rotate(d + f2(a, b, c) + word2 + 0xfcefa3f8, 9) + a; + c = rotate(c + f2(d, a, b) + word7 + 0x676f02d9, 14) + d; + b = rotate(b + f2(c, d, a) + word12 + 0x8d2a4c8a, 20) + c; + + // third round + a = rotate(a + f3(b, c, d) + word5 + 0xfffa3942, 4) + b; + d = rotate(d + f3(a, b, c) + word8 + 0x8771f681, 11) + a; + c = rotate(c + f3(d, a, b) + word11 + 0x6d9d6122, 16) + d; + b = rotate(b + f3(c, d, a) + word14 + 0xfde5380c, 23) + c; + + a = rotate(a + f3(b, c, d) + word1 + 0xa4beea44, 4) + b; + d = rotate(d + f3(a, b, c) + word4 + 0x4bdecfa9, 11) + a; + c = rotate(c + f3(d, a, b) + word7 + 0xf6bb4b60, 16) + d; + b = rotate(b + f3(c, d, a) + word10 + 0xbebfbc70, 23) + c; + + a = rotate(a + f3(b, c, d) + word13 + 0x289b7ec6, 4) + b; + d = rotate(d + f3(a, b, c) + word0 + 0xeaa127fa, 11) + a; + c = rotate(c + f3(d, a, b) + word3 + 0xd4ef3085, 16) + d; + b = rotate(b + f3(c, d, a) + word6 + 0x04881d05, 23) + c; + + a = rotate(a + f3(b, c, d) + word9 + 0xd9d4d039, 4) + b; + d = rotate(d + f3(a, b, c) + word12 + 0xe6db99e5, 11) + a; + c = rotate(c + f3(d, a, b) + word15 + 0x1fa27cf8, 16) + d; + b = rotate(b + f3(c, d, a) + word2 + 0xc4ac5665, 23) + c; + + // fourth round + a = rotate(a + f4(b, c, d) + word0 + 0xf4292244, 6) + b; + d = rotate(d + f4(a, b, c) + word7 + 0x432aff97, 10) + a; + c = rotate(c + f4(d, a, b) + word14 + 0xab9423a7, 15) + d; + b = rotate(b + f4(c, d, a) + word5 + 0xfc93a039, 21) + c; + + a = rotate(a + f4(b, c, d) + word12 + 0x655b59c3, 6) + b; + d = rotate(d + f4(a, b, c) + word3 + 0x8f0ccc92, 10) + a; + c = rotate(c + f4(d, a, b) + word10 + 0xffeff47d, 15) + d; + b = rotate(b + f4(c, d, a) + word1 + 0x85845dd1, 21) + c; + + a = rotate(a + f4(b, c, d) + word8 + 0x6fa87e4f, 6) + b; + d = rotate(d + f4(a, b, c) + word15 + 0xfe2ce6e0, 10) + a; + c = rotate(c + f4(d, a, b) + word6 + 0xa3014314, 15) + d; + b = rotate(b + f4(c, d, a) + word13 + 0x4e0811a1, 21) + c; + + a = rotate(a + f4(b, c, d) + word4 + 0xf7537e82, 6) + b; + d = rotate(d + f4(a, b, c) + word11 + 0xbd3af235, 10) + a; + c = rotate(c + f4(d, a, b) + word2 + 0x2ad7d2bb, 15) + d; + b = rotate(b + f4(c, d, a) + word9 + 0xeb86d391, 21) + c; + + // update hash + m_hash[0] += a; + m_hash[1] += b; + m_hash[2] += c; + m_hash[3] += d; +} - // no more data ? - if (numBytes == 0) - return; - // process full blocks - while (numBytes >= BlockSize) - { - _ProcessBlock(current); - current += BlockSize; - m_numBytes += BlockSize; - numBytes -= BlockSize; - } +/// add arbitrary number of bytes +void MD5::Add(const void* data, size_t numBytes) +{ + auto current = static_cast(data); - // keep remaining bytes in buffer - while (numBytes > 0) + if (m_bufferSize > 0) + { + while (numBytes > 0 && m_bufferSize < BlockSize) { m_buffer[m_bufferSize++] = *current++; numBytes--; } } - - /// process final block, less than 64 bytes - void MD5::_ProcessBuffer() + // full buffer + if (m_bufferSize == BlockSize) { - // the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte - - // - append "1" bit to message - // - append "0" bits until message length in bit mod 512 is 448 - // - append length as 64 bit integer - - // number of bits - size_t paddedLength = m_bufferSize * 8; - - // plus one bit set to 1 (always appended) - paddedLength++; - - // number of bits must be (numBits % 512) = 448 - size_t lower11Bits = paddedLength & 511; - if (lower11Bits <= 448) - paddedLength += 448 - lower11Bits; - else - paddedLength += 512 + 448 - lower11Bits; - // convert from bits to bytes - paddedLength /= 8; - - // only needed if additional data flows over into a second block - unsigned char extra[BlockSize]; - - // append a "1" bit, 128 => binary 10000000 - if (m_bufferSize < BlockSize) - m_buffer[m_bufferSize] = 128; - else - extra[0] = 128; - - size_t i; - for (i = m_bufferSize + 1; i < BlockSize; i++) - m_buffer[i] = 0; - for (; i < paddedLength; i++) - extra[i - BlockSize] = 0; - - // add message length in bits as 64 bit number - uint64_t msgBits = 8 * (m_numBytes + m_bufferSize); - // find right position - unsigned char* addLength; - if (paddedLength < BlockSize) - addLength = m_buffer + paddedLength; - else - addLength = extra + paddedLength - BlockSize; - - // must be little endian - *addLength++ = msgBits & 0xFF; - msgBits >>= 8; - *addLength++ = msgBits & 0xFF; - msgBits >>= 8; - *addLength++ = msgBits & 0xFF; - msgBits >>= 8; - *addLength++ = msgBits & 0xFF; - msgBits >>= 8; - *addLength++ = msgBits & 0xFF; - msgBits >>= 8; - *addLength++ = msgBits & 0xFF; - msgBits >>= 8; - *addLength++ = msgBits & 0xFF; - msgBits >>= 8; - *addLength++ = msgBits & 0xFF; - - // process blocks _ProcessBlock(m_buffer); - // flowed over into a second block ? - if (paddedLength > BlockSize) - _ProcessBlock(extra); + m_numBytes += BlockSize; + m_bufferSize = 0; } + // no more data ? + if (numBytes == 0) + return; - /// return latest hash as 32 hex characters - std::string MD5::GetHash() + // process full blocks + while (numBytes >= BlockSize) { - // compute hash (as raw bytes) - unsigned char rawHash[HashBytes]; - GetHash(rawHash); - - // convert to hex string - std::string result; - result.reserve(2 * HashBytes); - for (int i = 0; i < HashBytes; i++) - { - static constexpr char dec2hex[16 + 1] = "0123456789abcdef"; - result += dec2hex[(rawHash[i] >> 4) & 15]; - result += dec2hex[rawHash[i] & 15]; - } + _ProcessBlock(current); + current += BlockSize; + m_numBytes += BlockSize; + numBytes -= BlockSize; + } - return result; + // keep remaining bytes in buffer + while (numBytes > 0) + { + m_buffer[m_bufferSize++] = *current++; + numBytes--; } +} + +/// process final block, less than 64 bytes +void MD5::_ProcessBuffer() +{ + // the input bytes are considered as bits strings, where the first bit is the most significant bit of the byte + + // - append "1" bit to message + // - append "0" bits until message length in bit mod 512 is 448 + // - append length as 64 bit integer + + // number of bits + size_t paddedLength = m_bufferSize * 8; + + // plus one bit set to 1 (always appended) + paddedLength++; + + // number of bits must be (numBits % 512) = 448 + size_t lower11Bits = paddedLength & 511; + if (lower11Bits <= 448) + paddedLength += 448 - lower11Bits; + else + paddedLength += 512 + 448 - lower11Bits; + // convert from bits to bytes + paddedLength /= 8; + + // only needed if additional data flows over into a second block + unsigned char extra[BlockSize]; + + // append a "1" bit, 128 => binary 10000000 + if (m_bufferSize < BlockSize) + m_buffer[m_bufferSize] = 128; + else + extra[0] = 128; + + size_t i; + for (i = m_bufferSize + 1; i < BlockSize; i++) + m_buffer[i] = 0; + for (; i < paddedLength; i++) + extra[i - BlockSize] = 0; + + // add message length in bits as 64 bit number + uint64_t msgBits = 8 * (m_numBytes + m_bufferSize); + // find right position + unsigned char* addLength; + if (paddedLength < BlockSize) + addLength = m_buffer + paddedLength; + else + addLength = extra + paddedLength - BlockSize; + + // must be little endian + *addLength++ = msgBits & 0xFF; + msgBits >>= 8; + *addLength++ = msgBits & 0xFF; + msgBits >>= 8; + *addLength++ = msgBits & 0xFF; + msgBits >>= 8; + *addLength++ = msgBits & 0xFF; + msgBits >>= 8; + *addLength++ = msgBits & 0xFF; + msgBits >>= 8; + *addLength++ = msgBits & 0xFF; + msgBits >>= 8; + *addLength++ = msgBits & 0xFF; + msgBits >>= 8; + *addLength++ = msgBits & 0xFF; + + // process blocks + _ProcessBlock(m_buffer); + // flowed over into a second block ? + if (paddedLength > BlockSize) + _ProcessBlock(extra); +} - /// return latest hash as bytes - void MD5::GetHash(unsigned char buffer[HashBytes]) + +/// return latest hash as 32 hex characters +std::string MD5::GetHash() +{ + // compute hash (as raw bytes) + unsigned char rawHash[HashBytes]; + GetHash(rawHash); + + // convert to hex string + std::string result; + result.reserve(2 * HashBytes); + for (int i = 0; i < HashBytes; i++) { - // save old hash if buffer is partially filled - uint32_t oldHash[HashValues]; - for (int i = 0; i < HashValues; i++) - oldHash[i] = m_hash[i]; + static constexpr char dec2hex[16 + 1] = "0123456789abcdef"; + result += dec2hex[(rawHash[i] >> 4) & 15]; + result += dec2hex[rawHash[i] & 15]; + } - // process remaining bytes - _ProcessBuffer(); + return result; +} - unsigned char* current = buffer; - for (int i = 0; i < HashValues; i++) - { - *current++ = m_hash[i] & 0xFF; - *current++ = (m_hash[i] >> 8) & 0xFF; - *current++ = (m_hash[i] >> 16) & 0xFF; - *current++ = (m_hash[i] >> 24) & 0xFF; - // restore old hash - m_hash[i] = oldHash[i]; - } - } +/// return latest hash as bytes +void MD5::GetHash(unsigned char buffer[HashBytes]) +{ + // save old hash if buffer is partially filled + uint32_t oldHash[HashValues]; + for (int i = 0; i < HashValues; i++) + oldHash[i] = m_hash[i]; + // process remaining bytes + _ProcessBuffer(); - /// compute MD5 of a memory block - std::string MD5::operator()(const void* data, size_t numBytes) + unsigned char* current = buffer; + for (int i = 0; i < HashValues; i++) { - Reset(); - Add(data, numBytes); - return GetHash(); + *current++ = m_hash[i] & 0xFF; + *current++ = (m_hash[i] >> 8) & 0xFF; + *current++ = (m_hash[i] >> 16) & 0xFF; + *current++ = (m_hash[i] >> 24) & 0xFF; + + // restore old hash + m_hash[i] = oldHash[i]; } +} - /// compute MD5 of a string, excluding final zero - std::string MD5::operator()(const std::string& text) - { - Reset(); - Add(text.c_str(), text.size()); - return GetHash(); - } +/// compute MD5 of a memory block +std::string MD5::operator()(const void* data, size_t numBytes) +{ + Reset(); + Add(data, numBytes); + return GetHash(); +} + + +/// compute MD5 of a string, excluding final zero +std::string MD5::operator()(const std::string& text) +{ + Reset(); + Add(text.c_str(), text.size()); + return GetHash(); +} + _HASH_END diff --git a/PassBashPro/inc/common/Constants.h b/PassBashPro/inc/common/Constants.h index 4132ef3..31ab45f 100644 --- a/PassBashPro/inc/common/Constants.h +++ b/PassBashPro/inc/common/Constants.h @@ -63,7 +63,7 @@ constexpr int MODE_EDIT = 2; constexpr char PASH_DIR[] = R"(.pash\)"; constexpr char HELP_ROOT_DIR[] = R"(manual\)"; -constexpr const char* const HELP_DIR[] = {R"(idle\)", R"(pash\)", R"(edit\)"}; +constexpr const char* const HELP_DIR[] = { R"(idle\)", R"(pash\)", R"(edit\)" }; constexpr char CACHE_FILE[] = "cache"; constexpr char CONFIG_FILE[] = "config"; diff --git a/PassBashPro/inc/common/Logger.h b/PassBashPro/inc/common/Logger.h index 2bc8fb4..af7579c 100644 --- a/PassBashPro/inc/common/Logger.h +++ b/PassBashPro/inc/common/Logger.h @@ -57,6 +57,7 @@ class Logger { } + static std::vector m_logs; static std::vector m_msgs; static char m_buffer[LOGGER_BUFFER_SIZE]; diff --git a/PassBashPro/inc/core/Env.h b/PassBashPro/inc/core/Env.h index 91f8309..eedd316 100644 --- a/PassBashPro/inc/core/Env.h +++ b/PassBashPro/inc/core/Env.h @@ -52,6 +52,7 @@ struct Env bool online; }; + using EnvPtr = std::shared_ptr; #endif diff --git a/PassBashPro/inc/core/Profile.h b/PassBashPro/inc/core/Profile.h index 087fd06..c890e08 100644 --- a/PassBashPro/inc/core/Profile.h +++ b/PassBashPro/inc/core/Profile.h @@ -31,6 +31,7 @@ #include #include + struct Profile { std::string username; @@ -43,8 +44,10 @@ struct Profile } }; + using ProfilePtr = std::shared_ptr; + class ProfilePool : public Singleton { friend class Singleton; @@ -58,6 +61,7 @@ class ProfilePool : public Singleton ProfilePtr Get(const std::string& username); + ProfilePtr operator[](size_t id) { return m_profiles[id]; @@ -67,6 +71,7 @@ class ProfilePool : public Singleton std::vector m_profiles; }; + using ProfilePoolPtr = ProfilePool*; #endif diff --git a/PassBashPro/inc/exec/Exec.h b/PassBashPro/inc/exec/Exec.h index 204045f..a3824df 100644 --- a/PassBashPro/inc/exec/Exec.h +++ b/PassBashPro/inc/exec/Exec.h @@ -36,6 +36,6 @@ constexpr char EXEC_EDIT[] = "editor"; constexpr char EXEC_HIDDEN[] = "hidden"; constexpr char EXEC_SERVICE[] = "service"; -const char* const MODE_TO_EXEC[] = {EXEC_IDLE, EXEC_GLOBAL, EXEC_EDIT}; +const char* const MODE_TO_EXEC[] = { EXEC_IDLE, EXEC_GLOBAL, EXEC_EDIT }; #endif diff --git a/PassBashPro/inc/exec/ExecFactory.h b/PassBashPro/inc/exec/ExecFactory.h index 0c9b394..c9e743e 100644 --- a/PassBashPro/inc/exec/ExecFactory.h +++ b/PassBashPro/inc/exec/ExecFactory.h @@ -47,6 +47,7 @@ class ExecFactory std::unordered_map m_records; }; + using ExecFactoryPtr = std::shared_ptr; diff --git a/PassBashPro/inc/exec/ExecHost.h b/PassBashPro/inc/exec/ExecHost.h index 5d539ee..ac2cb1d 100644 --- a/PassBashPro/inc/exec/ExecHost.h +++ b/PassBashPro/inc/exec/ExecHost.h @@ -50,10 +50,12 @@ class ExecHost : public Singleton { } + ~ExecHost() override { } + std::unordered_map m_pool; }; diff --git a/PassBashPro/inc/template/Singleton.h b/PassBashPro/inc/template/Singleton.h index 5c61e26..14a4a99 100644 --- a/PassBashPro/inc/template/Singleton.h +++ b/PassBashPro/inc/template/Singleton.h @@ -30,7 +30,7 @@ /******************************************************************** ** Lazy singleton. */ -template +template class Singleton { public: @@ -43,6 +43,7 @@ class Singleton return m_instance; } + Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; @@ -60,25 +61,29 @@ class Singleton } }; + Singleton() { } + virtual ~Singleton() { } + static T* m_instance; }; -template + +template T* Singleton::m_instance = nullptr; /******************************************************************** ** Hungry singleton. */ -template +template class SingletonHungry { public: @@ -90,6 +95,7 @@ class SingletonHungry return m_instance; } + SingletonHungry(const SingletonHungry&) = delete; SingletonHungry& operator=(const SingletonHungry&) = delete; @@ -107,13 +113,15 @@ class SingletonHungry } }; + SingletonHungry() = default; virtual ~SingletonHungry() = default; static T* m_instance; }; -template + +template T* SingletonHungry::m_instance = new T(); #endif diff --git a/PassBashPro/inc/utility/FileUtil.h b/PassBashPro/inc/utility/FileUtil.h index d8e63c8..afef125 100644 --- a/PassBashPro/inc/utility/FileUtil.h +++ b/PassBashPro/inc/utility/FileUtil.h @@ -73,6 +73,7 @@ class FileUtil _ALL = _FILE | _DIR }; + static bool _GetContent(const char* path, std::vector* paths, std::vector* names, @@ -85,6 +86,7 @@ class FileUtil static void _DeleteDirectory(const char* path); static void _DeleteDirectory(const wchar_t* path); + FileUtil() { } diff --git a/PassBashPro/inc/utility/PashDocUtil.h b/PassBashPro/inc/utility/PashDocUtil.h index fdeb891..29a6153 100644 --- a/PassBashPro/inc/utility/PashDocUtil.h +++ b/PassBashPro/inc/utility/PashDocUtil.h @@ -43,16 +43,19 @@ struct Entry const char* value; int weight; + Entry() : key(nullptr), value(nullptr), weight(0) { } + Entry(const char* _k, const char* _v, int _w) : key(_k), value(_v), weight(_w) { } }; + struct EntryCompare { bool operator()(const Entry& lhs, const Entry& rhs) @@ -63,6 +66,7 @@ struct EntryCompare }; }; + using EntryList = std::vector; diff --git a/PassBashPro/inc/utility/xml.h b/PassBashPro/inc/utility/xml.h index 21d1449..59d3f89 100644 --- a/PassBashPro/inc/utility/xml.h +++ b/PassBashPro/inc/utility/xml.h @@ -53,6 +53,7 @@ class XMLFile { } + ~XMLFile(); /* @@ -117,6 +118,7 @@ class XMLUtil { } + static void _GetElementsByTagName(XMLElement* node, const char* tag, std::vector& results); static void _GetElementsByAttrName(XMLElement* node, const char* attr, const char* name, std::vector& results); diff --git a/PassBashPro/src/Main.cpp b/PassBashPro/src/Main.cpp index d8ba097..357324f 100644 --- a/PassBashPro/src/Main.cpp +++ b/PassBashPro/src/Main.cpp @@ -46,6 +46,7 @@ #include "../inc/exec/ExecHost.h" #include "../inc/exec/Init.h" + int main(int argc, char* argv[]) { InitExecHost(); diff --git a/PassBashPro/src/common/Error.cpp b/PassBashPro/src/common/Error.cpp index c6a3f4a..acbe127 100644 --- a/PassBashPro/src/common/Error.cpp +++ b/PassBashPro/src/common/Error.cpp @@ -27,6 +27,7 @@ #include #include + void _panic(const char* filename, int line, const char* func, const char* format, ...) { static char message[1024]; diff --git a/PassBashPro/src/common/Logger.cpp b/PassBashPro/src/common/Logger.cpp index 0874cef..5b844d3 100644 --- a/PassBashPro/src/common/Logger.cpp +++ b/PassBashPro/src/common/Logger.cpp @@ -36,6 +36,7 @@ static char _format[LOGGER_BUFFER_SIZE]; static LoggerStatus status = LoggerStatus::GOOD; + void Logger::LogError(const char* func, const char* format, ...) { va_list args; @@ -54,12 +55,14 @@ void Logger::LogError(const char* func, const char* format, ...) status = LoggerStatus::BAD; } + void Logger::ClearErrors() { m_logs.clear(); status = LoggerStatus::GOOD; } + void Logger::PrintErrors() { WORD old = cnsl::SetTextForeground(FOREGROUND_RED); @@ -72,6 +75,7 @@ void Logger::PrintErrors() cnsl::SetTextForeground(old); } + void Logger::LogMessage(const char* func, const char* format, ...) { va_list args; @@ -88,11 +92,13 @@ void Logger::LogMessage(const char* func, const char* format, ...) m_msgs.push_back(m_buffer); } + void Logger::ClearMessages() { m_msgs.clear(); } + void Logger::PrintMessages() { WORD old = cnsl::SetTextForeground(FOREGROUND_LIGHT(FOREGROUND_MAGENTA)); @@ -105,6 +111,7 @@ void Logger::PrintMessages() cnsl::SetTextForeground(old); } + bool Logger::Good() { return status == LoggerStatus::GOOD; diff --git a/PassBashPro/src/core/Global.cpp b/PassBashPro/src/core/Global.cpp index df1a78b..112d499 100644 --- a/PassBashPro/src/core/Global.cpp +++ b/PassBashPro/src/core/Global.cpp @@ -43,7 +43,7 @@ bool g_isOnline; PashDoc g_doc; // Default data content. -const char DEFAULT_DATA[]{ +const char DEFAULT_DATA[] { R"( @@ -63,9 +63,9 @@ const char PASH_EDITOR_VERSION[] = "2.1.3"; int g_mode = MODE_IDLE; // Copyright info. -const char TITLE[]{"PassBash Pro"}; -const char COPYRIGHT[]{"Tony's Studio 2020 - 2024"}; -const char AUTHOR[]{"Tony Skywalker"}; +const char TITLE[] { "PassBash Pro" }; +const char COPYRIGHT[] { "Tony's Studio 2020 - 2024" }; +const char AUTHOR[] { "Tony Skywalker" }; // Original Logo from: https://textkool.com/en/ascii-art-generator const char LOGO[] = R"( diff --git a/PassBashPro/src/core/PashDoc.cpp b/PassBashPro/src/core/PashDoc.cpp index 27e906e..e6f60f0 100644 --- a/PassBashPro/src/core/PashDoc.cpp +++ b/PassBashPro/src/core/PashDoc.cpp @@ -41,11 +41,13 @@ PashDoc::PashDoc() : { } + PashDoc::~PashDoc() { UnLoad(); } + bool PashDoc::Load(EnvPtr env) { if (IsLoaded()) @@ -90,6 +92,7 @@ bool PashDoc::Load(EnvPtr env) return true; } + void PashDoc::UnLoad() { if (IsLoaded()) @@ -133,6 +136,7 @@ bool PashDoc::Save(EnvPtr env) return true; } + bool PashDoc::DebugLoad(EnvPtr env) { #ifdef PASH_CHEAT @@ -162,6 +166,7 @@ bool PashDoc::DebugLoad(EnvPtr env) #endif } + bool PashDoc::DebugSave(EnvPtr env) { #ifdef PASH_CHEAT @@ -177,11 +182,13 @@ bool PashDoc::DebugSave(EnvPtr env) #endif } + bool PashDoc::IsLoaded() const { return m_pFile && (m_pFile->IsLoaded()); } + XMLElementPtr PashDoc::SetCurrent(XMLElementPtr current) { if (!current) @@ -196,6 +203,7 @@ XMLElementPtr PashDoc::SetCurrent(XMLElementPtr current) return ret; } + XMLElementPtr PashDoc::NewElement(const char* name) { if (!IsLoaded()) @@ -204,21 +212,25 @@ XMLElementPtr PashDoc::NewElement(const char* name) return m_pFile->Doc().NewElement(name); } + void PashDoc::DeleteElement(XMLElementPtr node) { m_pFile->Doc().DeleteNode(node); } + void PashDoc::Mark() { m_modified = true; } + bool PashDoc::IsMarked() const { return m_modified; } + bool PashDoc::_GenerateData(EnvPtr env) { FILE* output; diff --git a/PassBashPro/src/core/Profile.cpp b/PassBashPro/src/core/Profile.cpp index be2ab10..b1f93bb 100644 --- a/PassBashPro/src/core/Profile.cpp +++ b/PassBashPro/src/core/Profile.cpp @@ -35,6 +35,7 @@ bool ProfilePool::Add(ProfilePtr profile) return true; } + bool ProfilePool::Remove(const std::string& username) { for (auto it = m_profiles.begin(); it != m_profiles.end(); ++it) @@ -49,21 +50,25 @@ bool ProfilePool::Remove(const std::string& username) return false; } + void ProfilePool::Clear() { m_profiles.clear(); } + bool ProfilePool::IsEmpty() { return m_profiles.empty(); } + int ProfilePool::Size() { return static_cast(m_profiles.size()); } + ProfilePtr ProfilePool::Get(const std::string& username) { for (auto it : m_profiles) diff --git a/PassBashPro/src/exec/ExecFactory.cpp b/PassBashPro/src/exec/ExecFactory.cpp index 50b678a..ace80d7 100644 --- a/PassBashPro/src/exec/ExecFactory.cpp +++ b/PassBashPro/src/exec/ExecFactory.cpp @@ -35,6 +35,7 @@ int ExecFactory::Hook(const char* descr, Exec exec) // already exists } + // If descr is nullptr, all contents will be cleared. int ExecFactory::UnHook(const char* descr, Exec exec) { @@ -50,6 +51,7 @@ int ExecFactory::UnHook(const char* descr, Exec exec) return -1; } + Exec ExecFactory::Get(const char* descr) { if (!descr) diff --git a/PassBashPro/src/exec/ExecHost.cpp b/PassBashPro/src/exec/ExecHost.cpp index d8499e1..579c398 100644 --- a/PassBashPro/src/exec/ExecHost.cpp +++ b/PassBashPro/src/exec/ExecHost.cpp @@ -39,6 +39,7 @@ int ExecHost::Register(const char* descr, ExecFactoryPtr factory) return 1; } + // if descr is nullptr, all factories will be cleared int ExecHost::UnRegister(const char* descr) { @@ -53,6 +54,7 @@ int ExecHost::UnRegister(const char* descr) return -1; } + ExecFactoryPtr ExecHost::GetFactory(const char* descr) { if (!descr) @@ -65,6 +67,7 @@ ExecFactoryPtr ExecHost::GetFactory(const char* descr) return ret->second; } + int ExecHost::execl(const char* descr, const char* cmd, ...) { static char* argv[EXEC_ARG_SIZE]; @@ -99,6 +102,7 @@ int ExecHost::execl(const char* descr, const char* cmd, ...) return exec(argc, argv); } + int ExecHost::execv(const char* descr, const char* cmd, char* argv[]) { auto factory = GetFactory(descr); diff --git a/PassBashPro/src/exec/Init.cpp b/PassBashPro/src/exec/Init.cpp index ad92894..32e78c8 100644 --- a/PassBashPro/src/exec/Init.cpp +++ b/PassBashPro/src/exec/Init.cpp @@ -42,6 +42,7 @@ static void _InitGlobal(); static void _InitEditor(); static void _InitHidden(); + void InitExecHost() { _InitService(); @@ -50,6 +51,7 @@ void InitExecHost() _InitHidden(); } + void InitConsole() { cnsl::InitConsoleSize(120, 30); @@ -62,11 +64,13 @@ void InitConsole() cnsl::OverflowReprint(false); } + void InitAddons() { SetRandomSeed(); } + static void _InitService() { ExecFactoryPtr factory(new ExecFactory()); @@ -87,6 +91,7 @@ static void _InitService() ExecHost::GetInstance()->Register(EXEC_SERVICE, factory); } + static void _InitGlobal() { ExecFactoryPtr factory(new ExecFactory()); @@ -148,6 +153,7 @@ static void _InitGlobal() ExecHost::GetInstance()->Register(EXEC_GLOBAL, factory); } + static void _InitEditor() { ExecFactoryPtr factory(new ExecFactory()); @@ -180,6 +186,7 @@ static void _InitEditor() ExecHost::GetInstance()->Register(EXEC_EDIT, factory); } + static void _InitHidden() { ExecFactoryPtr factory(new ExecFactory()); diff --git a/PassBashPro/src/exec/editor/EditorAux.cpp b/PassBashPro/src/exec/editor/EditorAux.cpp index 658172d..933c724 100644 --- a/PassBashPro/src/exec/editor/EditorAux.cpp +++ b/PassBashPro/src/exec/editor/EditorAux.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/editor/EditorHeader.h" + void _edit_print_header(bool showPrompt) { static char buffer[128]; @@ -33,12 +34,14 @@ void _edit_print_header(bool showPrompt) cnsl::InsertText(MESSAGE_COLOR, "Use \"help\" for more information.\n"); } + void _edit_print_footer() { cnsl::InsertNewLine(); cnsl::InsertHeaderLine("Pash Editor End", '-'); } + void _edit_print_prompt() { cnsl::InsertText(PROMPT_COLOR, "[Edit Mode] "); @@ -48,6 +51,7 @@ void _edit_print_prompt() cnsl::InsertText(PROMPT_COLOR, "> "); } + int _edit_parse_cmd(char* cmd, char** type, char** arg) { char* p = cmd; @@ -69,6 +73,7 @@ int _edit_parse_cmd(char* cmd, char** type, char** arg) return 0; } + int _edit_parse_params(char* arg, int argc, const char* params[]) { if (arg == nullptr) @@ -88,6 +93,7 @@ int _edit_parse_params(char* arg, int argc, const char* params[]) return cnt; } + int _set_key(const char* idStr, const char* newKey) { int id; @@ -118,6 +124,7 @@ int _set_key(const char* idStr, const char* newKey) return 0; } + int _set_value(const char* idStr, const char* value) { int id; @@ -148,6 +155,7 @@ int _set_value(const char* idStr, const char* value) return 0; } + int _set_weight(const char* idStr, const char* weightStr) { int id; @@ -184,6 +192,7 @@ int _set_weight(const char* idStr, const char* weightStr) return 0; } + int _set_entry(const char* key, const char* value, const char* weightStr) { if (!key) diff --git a/PassBashPro/src/exec/editor/exec_edit_clear.cpp b/PassBashPro/src/exec/editor/exec_edit_clear.cpp index defb52c..b96789a 100644 --- a/PassBashPro/src/exec/editor/exec_edit_clear.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_clear.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/editor/EditorHeader.h" + int exec_edit_clear(int argc, char* argv[]) { cnsl::Clear(); diff --git a/PassBashPro/src/exec/editor/exec_edit_exit.cpp b/PassBashPro/src/exec/editor/exec_edit_exit.cpp index 1224712..ddf927d 100644 --- a/PassBashPro/src/exec/editor/exec_edit_exit.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_exit.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/editor/EditorHeader.h" + int exec_edit_exit(int argc, char* argv[]) { return TERMINATION; diff --git a/PassBashPro/src/exec/editor/exec_edit_help.cpp b/PassBashPro/src/exec/editor/exec_edit_help.cpp index 801f09d..7d91a8f 100644 --- a/PassBashPro/src/exec/editor/exec_edit_help.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_help.cpp @@ -29,6 +29,7 @@ static char* _argv[EXEC_ARG_SIZE]; static char _buffer[EXEC_BUFFER_SIZE]; static char _cmd[] = "help"; + int exec_edit_help(int argc, char* argv[]) { if (argc != 2) diff --git a/PassBashPro/src/exec/editor/exec_edit_host.cpp b/PassBashPro/src/exec/editor/exec_edit_host.cpp index 06f821d..3430557 100644 --- a/PassBashPro/src/exec/editor/exec_edit_host.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_host.cpp @@ -33,6 +33,7 @@ cnsl::InputHistory _edit_history; static int _edit_host_parse_arg(int argc, char* argv[]); + int exec_edit_host(int argc, char* argv[]) { // Get Item to edit. @@ -97,6 +98,7 @@ int exec_edit_host(int argc, char* argv[]) return 0; } + static int _edit_host_parse_arg(int argc, char* argv[]) { if (argc != 2) diff --git a/PassBashPro/src/exec/editor/exec_edit_more.cpp b/PassBashPro/src/exec/editor/exec_edit_more.cpp index 6a256f5..cc48e99 100644 --- a/PassBashPro/src/exec/editor/exec_edit_more.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_more.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/editor/EditorHeader.h" + int exec_edit_more(int argc, char* argv[]) { _ShowItemSimple(_edit_item, true); diff --git a/PassBashPro/src/exec/editor/exec_edit_see.cpp b/PassBashPro/src/exec/editor/exec_edit_see.cpp index f82fb8e..db5b080 100644 --- a/PassBashPro/src/exec/editor/exec_edit_see.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_see.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/editor/EditorHeader.h" + int exec_edit_see(int argc, char* argv[]) { _ShowItemSimple(_edit_item, false); diff --git a/PassBashPro/src/exec/editor/exec_edit_set.cpp b/PassBashPro/src/exec/editor/exec_edit_set.cpp index 94e3428..211f54a 100644 --- a/PassBashPro/src/exec/editor/exec_edit_set.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_set.cpp @@ -24,9 +24,10 @@ static int _set_usage(); + int exec_edit_set(int argc, char* argv[]) { - const char* params[3] = {nullptr, nullptr, "-1"}; + const char* params[3] = { nullptr, nullptr, "-1" }; int ret = _edit_parse_params(argv[1], 3, params); if (ret < 2 || ret > 3) @@ -38,8 +39,9 @@ int exec_edit_set(int argc, char* argv[]) return _set_entry(params[0], params[1], params[2]); } + static int _set_usage() { return ExecHost::GetInstance() - ->execl(EXEC_EDIT, "help", "help", "set", nullptr); + ->execl(EXEC_EDIT, "help", "help", "set", nullptr); } diff --git a/PassBashPro/src/exec/editor/exec_edit_setk.cpp b/PassBashPro/src/exec/editor/exec_edit_setk.cpp index 476b20a..f4d1b56 100644 --- a/PassBashPro/src/exec/editor/exec_edit_setk.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_setk.cpp @@ -24,9 +24,10 @@ static void _setk_usage(); + int exec_edit_setk(int argc, char* argv[]) { - const char* params[2] = {nullptr, nullptr}; + const char* params[2] = { nullptr, nullptr }; int ret = _edit_parse_params(argv[1], 2, params); if (ret != 2) @@ -38,8 +39,9 @@ int exec_edit_setk(int argc, char* argv[]) return _set_key(params[0], params[1]); } + static void _setk_usage() { ExecHost::GetInstance() - ->execl(EXEC_EDIT, "help", "help", "setk", nullptr); + ->execl(EXEC_EDIT, "help", "help", "setk", nullptr); } diff --git a/PassBashPro/src/exec/editor/exec_edit_setv.cpp b/PassBashPro/src/exec/editor/exec_edit_setv.cpp index a2896d0..1679631 100644 --- a/PassBashPro/src/exec/editor/exec_edit_setv.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_setv.cpp @@ -24,9 +24,10 @@ static void _setv_usage(); + int exec_edit_setv(int argc, char* argv[]) { - const char* params[2] = {nullptr, nullptr}; + const char* params[2] = { nullptr, nullptr }; int ret = _edit_parse_params(argv[1], 2, params); if (ret != 2) @@ -38,8 +39,9 @@ int exec_edit_setv(int argc, char* argv[]) return _set_value(params[0], params[1]); } + static void _setv_usage() { ExecHost::GetInstance() - ->execl(EXEC_EDIT, "help", "help", "setv", nullptr); + ->execl(EXEC_EDIT, "help", "help", "setv", nullptr); } diff --git a/PassBashPro/src/exec/editor/exec_edit_setw.cpp b/PassBashPro/src/exec/editor/exec_edit_setw.cpp index 94fc79c..6c4db7a 100644 --- a/PassBashPro/src/exec/editor/exec_edit_setw.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_setw.cpp @@ -24,9 +24,10 @@ static void _setw_usage(); + int exec_edit_setw(int argc, char* argv[]) { - const char* params[2] = {nullptr, nullptr}; + const char* params[2] = { nullptr, nullptr }; int ret = _edit_parse_params(argv[1], 2, params); if (ret != 2) @@ -38,8 +39,9 @@ int exec_edit_setw(int argc, char* argv[]) return _set_weight(params[0], params[1]); } + static void _setw_usage() { ExecHost::GetInstance() - ->execl(EXEC_EDIT, "help", "help", "setw", nullptr); + ->execl(EXEC_EDIT, "help", "help", "setw", nullptr); } diff --git a/PassBashPro/src/exec/editor/exec_edit_unknown.cpp b/PassBashPro/src/exec/editor/exec_edit_unknown.cpp index e2cafb4..c609d1e 100644 --- a/PassBashPro/src/exec/editor/exec_edit_unknown.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_unknown.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/editor/EditorHeader.h" + int exec_edit_unknown(int argc, char* argv[]) { cnsl::InsertText(ERROR_COLOR, "\"%s\" is not an edit command.\n", argv[1]); diff --git a/PassBashPro/src/exec/editor/exec_edit_unset.cpp b/PassBashPro/src/exec/editor/exec_edit_unset.cpp index b7ed550..a98aeb2 100644 --- a/PassBashPro/src/exec/editor/exec_edit_unset.cpp +++ b/PassBashPro/src/exec/editor/exec_edit_unset.cpp @@ -24,9 +24,10 @@ static void _unset_usage(); + int exec_edit_unset(int argc, char* argv[]) { - const char* params[1] = {nullptr}; + const char* params[1] = { nullptr }; int ret = _edit_parse_params(argv[1], 1, params); if (ret != 1) @@ -54,8 +55,9 @@ int exec_edit_unset(int argc, char* argv[]) return 0; } + static void _unset_usage() { ExecHost::GetInstance() - ->execl(EXEC_EDIT, "help", "help", "unset", nullptr); + ->execl(EXEC_EDIT, "help", "help", "unset", nullptr); } diff --git a/PassBashPro/src/exec/function/exec_archive.cpp b/PassBashPro/src/exec/function/exec_archive.cpp index cf48e7a..2be806c 100644 --- a/PassBashPro/src/exec/function/exec_archive.cpp +++ b/PassBashPro/src/exec/function/exec_archive.cpp @@ -22,8 +22,9 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_archive(int argc, char* argv[]) { return ExecHost::GetInstance() - ->execv(EXEC_SERVICE, "archive", argv); -} \ No newline at end of file + ->execv(EXEC_SERVICE, "archive", argv); +} diff --git a/PassBashPro/src/exec/function/exec_branch.cpp b/PassBashPro/src/exec/function/exec_branch.cpp index e6d33ac..ca745f3 100644 --- a/PassBashPro/src/exec/function/exec_branch.cpp +++ b/PassBashPro/src/exec/function/exec_branch.cpp @@ -27,6 +27,7 @@ int _branch_list(); int _branch_create(int argc, char* argv[]); + int exec_branch(int argc, char* argv[]) { PASH_PANIC_ON(g_env == nullptr); @@ -36,6 +37,7 @@ int exec_branch(int argc, char* argv[]) return _branch_create(argc, argv); } + int _branch_list() { ProfilePoolPtr pool = ProfilePool::GetInstance(); @@ -56,6 +58,7 @@ int _branch_list() return 0; } + int _branch_create(int argc, char* argv[]) { return ExecHost::GetInstance()->execv(EXEC_SERVICE, "profile", argv); diff --git a/PassBashPro/src/exec/function/exec_cat.cpp b/PassBashPro/src/exec/function/exec_cat.cpp index ee4ea6e..b34d435 100644 --- a/PassBashPro/src/exec/function/exec_cat.cpp +++ b/PassBashPro/src/exec/function/exec_cat.cpp @@ -22,12 +22,14 @@ #include "../../../inc/exec/function/FuncHeader.h" + static int _cat_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "cat", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "cat", nullptr); } + int exec_cat(int argc, char* argv[]) { std::string path; diff --git a/PassBashPro/src/exec/function/exec_cd.cpp b/PassBashPro/src/exec/function/exec_cd.cpp index 798e42b..6d1d885 100644 --- a/PassBashPro/src/exec/function/exec_cd.cpp +++ b/PassBashPro/src/exec/function/exec_cd.cpp @@ -24,17 +24,20 @@ static XMLElementPtr last_dir = nullptr; + static int _cd_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "cd", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "cd", nullptr); } + static int _cd_parse_arg(int argc, char* argv[], std::string& path) { return _ParseArgs(argc, argv, path); } + int exec_cd(int argc, char* argv[]) { std::string path(SELF_DIR_NAME); diff --git a/PassBashPro/src/exec/function/exec_checkout.cpp b/PassBashPro/src/exec/function/exec_checkout.cpp index 00aa47d..d66566e 100644 --- a/PassBashPro/src/exec/function/exec_checkout.cpp +++ b/PassBashPro/src/exec/function/exec_checkout.cpp @@ -22,8 +22,9 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_checkout(int argc, char* argv[]) { return ExecHost::GetInstance() - ->execv(EXEC_SERVICE, "checkout", argv); + ->execv(EXEC_SERVICE, "checkout", argv); } diff --git a/PassBashPro/src/exec/function/exec_clear.cpp b/PassBashPro/src/exec/function/exec_clear.cpp index f76fb5f..590af41 100644 --- a/PassBashPro/src/exec/function/exec_clear.cpp +++ b/PassBashPro/src/exec/function/exec_clear.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_clear(int argc, char* argv[]) { cnsl::Clear(); diff --git a/PassBashPro/src/exec/function/exec_copy.cpp b/PassBashPro/src/exec/function/exec_copy.cpp index 717ab41..a3d6a13 100644 --- a/PassBashPro/src/exec/function/exec_copy.cpp +++ b/PassBashPro/src/exec/function/exec_copy.cpp @@ -28,6 +28,7 @@ int _copy(const std::string& data); + int exec_copy(int argc, char* argv[]) { std::string data; @@ -59,6 +60,7 @@ int exec_copy(int argc, char* argv[]) return 0; } + int _copy(const std::string& data) { HWND hWnd = nullptr; diff --git a/PassBashPro/src/exec/function/exec_echo.cpp b/PassBashPro/src/exec/function/exec_echo.cpp index 5b64888..77655aa 100644 --- a/PassBashPro/src/exec/function/exec_echo.cpp +++ b/PassBashPro/src/exec/function/exec_echo.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_echo(int argc, char* argv[]) { for (int i = 1; i < argc; i++) diff --git a/PassBashPro/src/exec/function/exec_edit.cpp b/PassBashPro/src/exec/function/exec_edit.cpp index 970bd70..b9cdf51 100644 --- a/PassBashPro/src/exec/function/exec_edit.cpp +++ b/PassBashPro/src/exec/function/exec_edit.cpp @@ -25,6 +25,7 @@ static int _edit_usage(); static int _edit_parse_args(int argc, char* argv[], std::string& path); + int exec_edit(int argc, char* argv[]) { std::string path; @@ -51,7 +52,7 @@ int exec_edit(int argc, char* argv[]) } int ret = ExecHost::GetInstance() - ->execl(EXEC_SERVICE, "editor", "editor", path.c_str(), nullptr); + ->execl(EXEC_SERVICE, "editor", "editor", path.c_str(), nullptr); if (ret != 0) { EXEC_PRINT_ERR("Failed to launch password editor!\n"); @@ -63,12 +64,14 @@ int exec_edit(int argc, char* argv[]) return 0; } + static int _edit_usage() { return ExecHost::GetInstance() - ->execl(MODE_TO_EXEC[g_mode], "help", "help", "edit", nullptr); + ->execl(MODE_TO_EXEC[g_mode], "help", "help", "edit", nullptr); } + static int _edit_parse_args(int argc, char* argv[], std::string& path) { return _ParseArgs(argc, argv, path); diff --git a/PassBashPro/src/exec/function/exec_exit.cpp b/PassBashPro/src/exec/function/exec_exit.cpp index 305e2a2..68fded8 100644 --- a/PassBashPro/src/exec/function/exec_exit.cpp +++ b/PassBashPro/src/exec/function/exec_exit.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_exit(int argc, char* argv[]) { return TERMINATION; diff --git a/PassBashPro/src/exec/function/exec_find.cpp b/PassBashPro/src/exec/function/exec_find.cpp index 03057ce..bb73fed 100644 --- a/PassBashPro/src/exec/function/exec_find.cpp +++ b/PassBashPro/src/exec/function/exec_find.cpp @@ -41,6 +41,7 @@ static void _search_item(XMLElementPtr root, SearchResultList& list); static void _search(XMLElementPtr root, SearchResultList& list); static void _find(SearchResultList& list); + int exec_find(int argc, char* argv[]) { _find_init(); @@ -86,6 +87,7 @@ int exec_find(int argc, char* argv[]) return 0; } + static void _find_init() { is_deep = false; @@ -94,12 +96,14 @@ static void _find_init() pattern = ""; } + static int _find_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "find", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "find", nullptr); } + static int _find_parse_args(int argc, char* argv[]) { int opt; @@ -148,6 +152,7 @@ static int _find_parse_args(int argc, char* argv[]) return 0; } + static void _search_item(XMLElementPtr root, SearchResultList& list) { if (!PashDocUtil::IsItem(root)) @@ -189,6 +194,7 @@ static void _search_item(XMLElementPtr root, SearchResultList& list) } } + static void _search(XMLElementPtr root, SearchResultList& list) { XMLElementPtr it = root->FirstChildElement(); @@ -207,6 +213,7 @@ static void _search(XMLElementPtr root, SearchResultList& list) } } + static void _find(SearchResultList& list) { XMLElementPtr node = PashDocUtil::GetNodeByPath(root_path); diff --git a/PassBashPro/src/exec/function/exec_gen.cpp b/PassBashPro/src/exec/function/exec_gen.cpp index db141ac..258f330 100644 --- a/PassBashPro/src/exec/function/exec_gen.cpp +++ b/PassBashPro/src/exec/function/exec_gen.cpp @@ -60,6 +60,7 @@ static std::string _generate_password(); static int _print_result(); + int exec_gen(int argc, char* argv[]) { _gen_init(); @@ -77,6 +78,7 @@ int exec_gen(int argc, char* argv[]) return 0; } + static void _gen_init() { length = 0; @@ -93,12 +95,14 @@ static void _gen_init() candidates.clear(); } + static int _gen_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "generate", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "generate", nullptr); } + // gen [-l 8] [-n 5] [-a -d -c] static int _gen_parse_args(int argc, char* argv[]) { @@ -175,6 +179,7 @@ static int _gen_parse_args(int argc, char* argv[]) return 0; } + static int _init_generation() { if (useDefault) @@ -198,6 +203,7 @@ static int _init_generation() return 0; } + static std::string _generate_password() { std::string password; @@ -211,9 +217,10 @@ static std::string _generate_password() return password; } + static int _print_result() { - constexpr WORD ENTRY_COLOR[2] = {FOREGROUND_WHITE, FOREGROUND_LIGHT(FOREGROUND_WHITE)}; + constexpr WORD ENTRY_COLOR[2] = { FOREGROUND_WHITE, FOREGROUND_LIGHT(FOREGROUND_WHITE) }; for (int i = 0; i < results.size(); i++) { diff --git a/PassBashPro/src/exec/function/exec_git.cpp b/PassBashPro/src/exec/function/exec_git.cpp index e5fb930..22eda35 100644 --- a/PassBashPro/src/exec/function/exec_git.cpp +++ b/PassBashPro/src/exec/function/exec_git.cpp @@ -22,15 +22,16 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_git(int argc, char* argv[]) { std::string pwd(g_pwd); int ret = ExecHost::GetInstance() - ->execv(EXEC_SERVICE, "git", argv); + ->execv(EXEC_SERVICE, "git", argv); ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "cd", "cd", pwd.c_str(), nullptr); + ->execl(EXEC_GLOBAL, "cd", "cd", pwd.c_str(), nullptr); return ret; } diff --git a/PassBashPro/src/exec/function/exec_help.cpp b/PassBashPro/src/exec/function/exec_help.cpp index 5cd2fd7..c71b7a1 100644 --- a/PassBashPro/src/exec/function/exec_help.cpp +++ b/PassBashPro/src/exec/function/exec_help.cpp @@ -45,6 +45,7 @@ static int _print_help(const char* path, bool brief); static bool _is_empty_line(const char* line); + int exec_help(int argc, char* argv[]) { target = ""; @@ -71,12 +72,14 @@ int exec_help(int argc, char* argv[]) return 0; } + static int _help_usage() { // Use '_help' to differentiate internal and external call. return ExecHost::GetInstance()->execl(EXEC_GLOBAL, "help", "_help", "help", nullptr); } + static int _help_parse_args(int argc, char* argv[]) { int opt; @@ -157,6 +160,7 @@ static int _help_single(const std::string& item, bool brief) // help single comm return 0; } + static int _help_current(const char* root) // help current faction (in brief) { std::string path; @@ -186,6 +190,7 @@ static int _help_current(const char* root) // help current faction (in brief) return 0; } + static int _help_all() // help all factions (in brief) { std::string path(HELP_ROOT_DIR); @@ -208,6 +213,7 @@ static int _help_all() // help all factions (in brief) return ret; } + static bool _is_empty_line(const char* line) { for (const char* p = line; *p; p++) @@ -219,6 +225,7 @@ static bool _is_empty_line(const char* line) return true; } + static int _print_help(const char* path, bool brief) { FILE* fp; diff --git a/PassBashPro/src/exec/function/exec_import.cpp b/PassBashPro/src/exec/function/exec_import.cpp index 699e30b..adfa2fd 100644 --- a/PassBashPro/src/exec/function/exec_import.cpp +++ b/PassBashPro/src/exec/function/exec_import.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_import(int argc, char* argv[]) { return ExecHost::GetInstance()->execv(EXEC_SERVICE, "import", argv); diff --git a/PassBashPro/src/exec/function/exec_ls.cpp b/PassBashPro/src/exec/function/exec_ls.cpp index 55b1a75..8713267 100644 --- a/PassBashPro/src/exec/function/exec_ls.cpp +++ b/PassBashPro/src/exec/function/exec_ls.cpp @@ -26,6 +26,7 @@ static int _ls_usage(); static int _ls_parse_arg(int argc, char* argv[], std::string& path); + int exec_ls(int argc, char* argv[]) { std::string path; @@ -76,13 +77,15 @@ int exec_ls(int argc, char* argv[]) return 0; } + static int _ls_parse_arg(int argc, char* argv[], std::string& path) { return _ParseOptionalArgs(argc, argv, path); } + static int _ls_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "ls", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "ls", nullptr); } diff --git a/PassBashPro/src/exec/function/exec_mkdir.cpp b/PassBashPro/src/exec/function/exec_mkdir.cpp index 010efa2..3e70b7f 100644 --- a/PassBashPro/src/exec/function/exec_mkdir.cpp +++ b/PassBashPro/src/exec/function/exec_mkdir.cpp @@ -25,6 +25,7 @@ static int _mkdir_usage(); static int _mkdir_parse_arg(int argc, char* argv[], std::string& path); + int exec_mkdir(int argc, char* argv[]) { std::string path; @@ -58,13 +59,15 @@ int exec_mkdir(int argc, char* argv[]) return 0; } + static int _mkdir_parse_arg(int argc, char* argv[], std::string& path) { return _ParseArgs(argc, argv, path); } + static int _mkdir_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "mkdir", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "mkdir", nullptr); } diff --git a/PassBashPro/src/exec/function/exec_more.cpp b/PassBashPro/src/exec/function/exec_more.cpp index bc362d2..3e58241 100644 --- a/PassBashPro/src/exec/function/exec_more.cpp +++ b/PassBashPro/src/exec/function/exec_more.cpp @@ -27,6 +27,7 @@ static char _param[] = "-m"; static int _more_usage(); + int exec_more(int argc, char* argv[]) { std::string path; @@ -55,8 +56,9 @@ int exec_more(int argc, char* argv[]) return 0; } + static int _more_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "more", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "more", nullptr); } diff --git a/PassBashPro/src/exec/function/exec_move.cpp b/PassBashPro/src/exec/function/exec_move.cpp index cd87f35..3425e85 100644 --- a/PassBashPro/src/exec/function/exec_move.cpp +++ b/PassBashPro/src/exec/function/exec_move.cpp @@ -25,6 +25,7 @@ static int _move_usage(); static int _move_parse_args(int argc, char* argv[], std::string& src, std::string& dest); + int exec_move(int argc, char* argv[]) { std::string srcPath; @@ -93,12 +94,14 @@ int exec_move(int argc, char* argv[]) return 0; } + static int _move_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "move", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "move", nullptr); } + static int _move_parse_args(int argc, char* argv[], std::string& src, std::string& dest) { return _ParseArgs(argc, argv, src, dest); diff --git a/PassBashPro/src/exec/function/exec_order.cpp b/PassBashPro/src/exec/function/exec_order.cpp index e7d1065..7e1700f 100644 --- a/PassBashPro/src/exec/function/exec_order.cpp +++ b/PassBashPro/src/exec/function/exec_order.cpp @@ -24,6 +24,7 @@ static int _order_parse_args(int argc, char* argv[], std::string& order); + int exec_order(int argc, char* argv[]) { std::string order; @@ -74,6 +75,7 @@ int exec_order(int argc, char* argv[]) return 0; } + static int _order_parse_args(int argc, char* argv[], std::string& order) { return _ParseArgs(argc, argv, order); diff --git a/PassBashPro/src/exec/function/exec_pash.cpp b/PassBashPro/src/exec/function/exec_pash.cpp index f442d6c..011dc4a 100644 --- a/PassBashPro/src/exec/function/exec_pash.cpp +++ b/PassBashPro/src/exec/function/exec_pash.cpp @@ -39,6 +39,7 @@ static constexpr WORD COLORS[] = { FOREGROUND_LIGHT(FOREGROUND_CYAN) }; + int exec_pash(int argc, char* argv[]) { cnsl::Clear(); diff --git a/PassBashPro/src/exec/function/exec_pwd.cpp b/PassBashPro/src/exec/function/exec_pwd.cpp index 8defad8..771d62f 100644 --- a/PassBashPro/src/exec/function/exec_pwd.cpp +++ b/PassBashPro/src/exec/function/exec_pwd.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_pwd(int argc, char* argv[]) { cnsl::InsertText("\t%s\n", g_pwd.c_str()); diff --git a/PassBashPro/src/exec/function/exec_remaster.cpp b/PassBashPro/src/exec/function/exec_remaster.cpp index bb41363..585b3a6 100644 --- a/PassBashPro/src/exec/function/exec_remaster.cpp +++ b/PassBashPro/src/exec/function/exec_remaster.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_remaster(int argc, char* argv[]) { return ExecHost::GetInstance()->execv(EXEC_SERVICE, "remaster", argv); diff --git a/PassBashPro/src/exec/function/exec_rename.cpp b/PassBashPro/src/exec/function/exec_rename.cpp index 923ba0b..d71d570 100644 --- a/PassBashPro/src/exec/function/exec_rename.cpp +++ b/PassBashPro/src/exec/function/exec_rename.cpp @@ -25,6 +25,7 @@ static int _rename_usage(); static int _rename_parse_args(int argc, char* argv[], std::string& src, std::string& dest); + int exec_rename(int argc, char* argv[]) { std::string srcPath; @@ -74,12 +75,14 @@ int exec_rename(int argc, char* argv[]) return 0; } + static int _rename_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "rename", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "rename", nullptr); } + static int _rename_parse_args(int argc, char* argv[], std::string& src, std::string& dest) { return _ParseArgs(argc, argv, src, dest); diff --git a/PassBashPro/src/exec/function/exec_rm.cpp b/PassBashPro/src/exec/function/exec_rm.cpp index 960ae3b..408a279 100644 --- a/PassBashPro/src/exec/function/exec_rm.cpp +++ b/PassBashPro/src/exec/function/exec_rm.cpp @@ -33,6 +33,7 @@ static int _remove_confirm(const char* prompt); static int _remove_root(); static int _remove_current(); + int exec_rm(int argc, char* argv[]) { std::string prompt; @@ -104,18 +105,21 @@ int exec_rm(int argc, char* argv[]) return true; } + static void _remove_init() { recursive = false; force = false; } + static int _remove_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "rm"); + ->execl(EXEC_GLOBAL, "help", "help", "rm"); } + static int _remove_parse_args(int argc, char* argv[]) { int opt; @@ -148,6 +152,7 @@ static int _remove_parse_args(int argc, char* argv[]) return 0; } + static int _remove_confirm(const char* prompt) { if (force) @@ -156,8 +161,7 @@ static int _remove_confirm(const char* prompt) char buffer[4]; cnsl::InputOptions options(1, 1); - options.verifier = [](char x) -> bool - { + options.verifier = [](char x) -> bool { return (tolower(x) == 'y' || (tolower(x) == 'n')); }; @@ -168,6 +172,7 @@ static int _remove_confirm(const char* prompt) return (tolower(buffer[0]) == 'y'); } + static int _remove_root() { bool old_force = force; @@ -188,6 +193,7 @@ static int _remove_root() return 0; } + static int _remove_current() { if (_remove_confirm("You're sure to delete current group? (Y/N) $ ")) diff --git a/PassBashPro/src/exec/function/exec_save.cpp b/PassBashPro/src/exec/function/exec_save.cpp index ee62f38..12db12c 100644 --- a/PassBashPro/src/exec/function/exec_save.cpp +++ b/PassBashPro/src/exec/function/exec_save.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_save(int argc, char* argv[]) { return ExecHost::GetInstance()->execv(EXEC_SERVICE, "save", argv); diff --git a/PassBashPro/src/exec/function/exec_tea.cpp b/PassBashPro/src/exec/function/exec_tea.cpp index f9b9536..6773c31 100644 --- a/PassBashPro/src/exec/function/exec_tea.cpp +++ b/PassBashPro/src/exec/function/exec_tea.cpp @@ -40,6 +40,7 @@ static int _open_files(FILE** pfin, const char* src, FILE** pfout, const char* d static void _close_files(FILE** fin, FILE** fout); static int _enctypt(FILE* fin, FILE* fout); + int exec_tea(int argc, char* argv[]) { _tea_init(); @@ -94,6 +95,7 @@ int exec_tea(int argc, char* argv[]) return 0; } + static void _tea_init() { _mode = 0; @@ -101,12 +103,14 @@ static void _tea_init() _src = _dst = ""; } + static int _tea_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "tea", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "tea", nullptr); } + static int _tea_parse_args(int argc, char* argv[]) { int opt; @@ -169,6 +173,7 @@ static int _tea_parse_args(int argc, char* argv[]) return 0; } + static int _open_files(FILE** pfin, const char* src, FILE** pfout, const char* dst) { if (FileUtil::Exists(dst)) @@ -196,6 +201,7 @@ static int _open_files(FILE** pfin, const char* src, FILE** pfout, const char* d return 0; } + static void _close_files(FILE** fin, FILE** fout) { if (fin && *fin) @@ -210,6 +216,7 @@ static void _close_files(FILE** fin, FILE** fout) } } + static int _enctypt(FILE* fin, FILE* fout) { auto reader = new tea::TEAFileReader(fin); diff --git a/PassBashPro/src/exec/function/exec_touch.cpp b/PassBashPro/src/exec/function/exec_touch.cpp index 7f4b028..0c61ee5 100644 --- a/PassBashPro/src/exec/function/exec_touch.cpp +++ b/PassBashPro/src/exec/function/exec_touch.cpp @@ -25,6 +25,7 @@ static int _touch_usage(); static int _touch_parse_arg(int argc, char* argv[], std::string& path); + int exec_touch(int argc, char* argv[]) { std::string path(""); @@ -66,12 +67,14 @@ int exec_touch(int argc, char* argv[]) return 0; } + static int _touch_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "touch", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "touch", nullptr); } + static int _touch_parse_arg(int argc, char* argv[], std::string& path) { return _ParseArgs(argc, argv, path); diff --git a/PassBashPro/src/exec/function/exec_tree.cpp b/PassBashPro/src/exec/function/exec_tree.cpp index bbb55f6..bbf35f8 100644 --- a/PassBashPro/src/exec/function/exec_tree.cpp +++ b/PassBashPro/src/exec/function/exec_tree.cpp @@ -29,6 +29,7 @@ static int _tree_usage(); static int _tree_parse_args(int argc, char* argv[], std::string& path); static void _tree(XMLElementPtr node, const std::string& leading); + int exec_tree(int argc, char* argv[]) { std::string path; @@ -54,17 +55,20 @@ int exec_tree(int argc, char* argv[]) return 0; } + static void _tree_init() { group_only = false; } + static int _tree_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "tree", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "tree", nullptr); } + static int _tree_parse_args(int argc, char* argv[], std::string& path) { int opt; @@ -112,6 +116,7 @@ static int _tree_parse_args(int argc, char* argv[], std::string& path) return 0; } + /******************************************************************** ** This is a little tricky. ** To make it clear, '.' is for leading space. diff --git a/PassBashPro/src/exec/function/exec_unknown.cpp b/PassBashPro/src/exec/function/exec_unknown.cpp index 0de76aa..291b112 100644 --- a/PassBashPro/src/exec/function/exec_unknown.cpp +++ b/PassBashPro/src/exec/function/exec_unknown.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_unknown(int argc, char* argv[]) { if (argc == 2) diff --git a/PassBashPro/src/exec/function/exec_version.cpp b/PassBashPro/src/exec/function/exec_version.cpp index 6da7ad5..5aaa22a 100644 --- a/PassBashPro/src/exec/function/exec_version.cpp +++ b/PassBashPro/src/exec/function/exec_version.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/function/FuncHeader.h" + int exec_version(int argc, char* argv[]) { cnsl::InsertText(FOREGROUND_LIGHT(FOREGROUND_CYAN), diff --git a/PassBashPro/src/exec/service/ServiceAux.cpp b/PassBashPro/src/exec/service/ServiceAux.cpp index 1d41527..e01946e 100644 --- a/PassBashPro/src/exec/service/ServiceAux.cpp +++ b/PassBashPro/src/exec/service/ServiceAux.cpp @@ -37,6 +37,7 @@ ProfilePtr CreateProfile(const std::string& username) return std::make_shared(username, path); } + EnvPtr CreateEnv(ProfilePtr profile) { if (!profile) @@ -54,6 +55,7 @@ EnvPtr CreateEnv(ProfilePtr profile) return env; } + int DeleteProfile(ProfilePtr profile, bool force) { if (!profile) @@ -71,6 +73,7 @@ int DeleteProfile(ProfilePtr profile, bool force) return 0; } + int InitConfig(EnvPtr env) { const char* configPath = env->configPath.c_str(); @@ -100,6 +103,7 @@ int InitConfig(EnvPtr env) return 0; } + int InitData(EnvPtr env) { const char* dataPath = env->dataPath.c_str(); @@ -152,7 +156,7 @@ int SaveConfig(EnvPtr env, bool overwrite) // Prevent premature exit auto reader = - new tea::TEARawBufferReader(hashPass, PASSWORD_MAX_LENGTH); + new tea::TEARawBufferReader(hashPass, PASSWORD_MAX_LENGTH); auto writer = new tea::TEAFileWriter(output); encode(reader, writer, hashPass); delete reader; @@ -161,6 +165,7 @@ int SaveConfig(EnvPtr env, bool overwrite) return 0; } + int SaveData(PashDoc& doc, EnvPtr env, bool overwrite) { if (!FileUtil::NewDirectory(env->rootPath.c_str())) @@ -180,6 +185,7 @@ int SaveData(PashDoc& doc, EnvPtr env, bool overwrite) return 0; } + int InitEnvFiles(EnvPtr env) { int ret; @@ -208,17 +214,20 @@ bool UsernameVerifier(char ch) return isalnum(ch) || (ch == '_'); } + bool PasswordVerifier(char ch) { return isgraph(ch); } + bool YesNoVerifier(char ch) { char lower = tolower(ch); return (lower == 'y') || (lower == 'n'); } + int UpdateCache() { PASH_PANIC_ON(g_env == NULL); @@ -242,6 +251,7 @@ int UpdateCache() static char _encoded_password[PASSWORD_BUFFER_SIZE]; static char _decoded_password[PASSWORD_BUFFER_SIZE]; + bool VerifyProfileInit(EnvPtr env) { FILE* input; @@ -263,6 +273,7 @@ bool VerifyProfileInit(EnvPtr env) return true; } + bool VerifyProfile(const char* password) { char hashPass[PASSWORD_BUFFER_SIZE]; @@ -270,7 +281,7 @@ bool VerifyProfile(const char* password) // MD5 vaule may contain 0x0 within!!! auto reader = - new tea::TEARawBufferReader(_encoded_password, PASSWORD_MAX_LENGTH); + new tea::TEARawBufferReader(_encoded_password, PASSWORD_MAX_LENGTH); auto writer = new tea::TEABufferWriter(_decoded_password); decode(reader, writer, hashPass); delete reader; @@ -337,6 +348,7 @@ bool VerifyUsername(const std::string& username) return true; } + bool VerifyPassword(const std::string& password) { if (password.length() < PASSWORD_MIN_LENGTH) diff --git a/PassBashPro/src/exec/service/srv_archive.cpp b/PassBashPro/src/exec/service/srv_archive.cpp index c14c34f..55f647a 100644 --- a/PassBashPro/src/exec/service/srv_archive.cpp +++ b/PassBashPro/src/exec/service/srv_archive.cpp @@ -22,7 +22,7 @@ #include "../../../inc/exec/service/ServiceHeader.h" - // archive -o -r src +// archive -o -r src static bool _remove; static bool _out; static bool _delete; @@ -39,6 +39,7 @@ static int _archive_delete(); static int _archive_move(const char* dst, const char* src, bool keepOriginal = false); static int _archive_list(); + int srv_archive(int argc, char* argv[]) { PASH_PANIC_ON(g_env == nullptr); @@ -102,6 +103,7 @@ int srv_archive(int argc, char* argv[]) return 0; } + // move file in static int _archive_archive(bool keepOriginal) { @@ -128,6 +130,7 @@ static int _archive_archive(bool keepOriginal) return _archive_move(dstPath.c_str(), _src.c_str(), keepOriginal); } + static int _archive_output(bool keepOriginal) { if (_src == "config" || _src == "data" || _src[0] == '.') @@ -153,6 +156,7 @@ static int _archive_output(bool keepOriginal) return _archive_move(_dst.c_str(), srcPath.c_str(), keepOriginal); } + static int _archive_delete() { if (_src == "config" || _src == "data" || _src[0] == '.') @@ -183,6 +187,7 @@ static int _archive_delete() return 0; } + // For now, just assume that the parent directory must exists. static int _archive_move(const char* dst, const char* src, bool keepOriginal) { @@ -211,6 +216,7 @@ static int _archive_move(const char* dst, const char* src, bool keepOriginal) return ret ? 0 : 31; } + static int _archive_list() { std::vector names; @@ -251,6 +257,7 @@ static int _archive_list() return 0; } + static void _archive_init() { _out = false; @@ -258,12 +265,14 @@ static void _archive_init() _delete = false; } + static int _archive_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "archive", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "archive", nullptr); } + static int _archive_parse_args(int argc, char* argv[]) { int opt; diff --git a/PassBashPro/src/exec/service/srv_checkout.cpp b/PassBashPro/src/exec/service/srv_checkout.cpp index 099be6a..fcd65a3 100644 --- a/PassBashPro/src/exec/service/srv_checkout.cpp +++ b/PassBashPro/src/exec/service/srv_checkout.cpp @@ -30,6 +30,7 @@ static int _checkout_parse_args(int argc, char* argv[]); static int _checkout_logout(); static int _checkout_login(EnvPtr env, PashDoc& doc); + int srv_checkout(int argc, char* argv[]) { PASH_PANIC_ON(g_env == nullptr); @@ -88,12 +89,14 @@ int srv_checkout(int argc, char* argv[]) return 0; } + static int _checkout_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "checkout", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "checkout", nullptr); } + static int _checkout_parse_args(int argc, char* argv[]) { int opt; @@ -153,6 +156,7 @@ static int _checkout_parse_args(int argc, char* argv[]) return 0; } + static int _checkout_logout() { PASH_TRY(SaveConfig(g_env, true)); @@ -161,6 +165,7 @@ static int _checkout_logout() return 0; } + static int _checkout_login(EnvPtr env, PashDoc& doc) { if (!doc.Load(env)) diff --git a/PassBashPro/src/exec/service/srv_export.cpp b/PassBashPro/src/exec/service/srv_export.cpp index 5a64257..ece610e 100644 --- a/PassBashPro/src/exec/service/srv_export.cpp +++ b/PassBashPro/src/exec/service/srv_export.cpp @@ -25,6 +25,7 @@ int _export_usage(); + int srv_export(int argc, char* argv[]) { if (argc != 2) @@ -76,8 +77,9 @@ int srv_export(int argc, char* argv[]) return 0; } + int _export_usage() { return ExecHost::GetInstance() - ->execl(MODE_TO_EXEC[g_mode], "help", "help", "export", nullptr); + ->execl(MODE_TO_EXEC[g_mode], "help", "help", "export", nullptr); } diff --git a/PassBashPro/src/exec/service/srv_git.cpp b/PassBashPro/src/exec/service/srv_git.cpp index fe02448..08b0a4a 100644 --- a/PassBashPro/src/exec/service/srv_git.cpp +++ b/PassBashPro/src/exec/service/srv_git.cpp @@ -32,6 +32,7 @@ int _git_verify(); int _git_reload(); + int srv_git(int argc, char* argv[]) { PASH_PANIC_ON(g_env == nullptr); @@ -135,12 +136,14 @@ int srv_git(int argc, char* argv[]) return ret; } + int _git_verify() { VerifyProfileInit(g_env); return VerifyProfile(g_env->password) ? 0 : 1; } + int _git_reload() { // nothing... diff --git a/PassBashPro/src/exec/service/srv_host.cpp b/PassBashPro/src/exec/service/srv_host.cpp index 0179dbf..4e9afda 100644 --- a/PassBashPro/src/exec/service/srv_host.cpp +++ b/PassBashPro/src/exec/service/srv_host.cpp @@ -51,6 +51,7 @@ static int _host_peek_command(); static int _host_peeker_standard(char* buffer, char** cmd, int* argc, char* argv[]); static int _host_peeker_advanced(char* buffer, char** cmd, int* argc, char* argv[]); + int srv_host(int argc, char* argv[]) { ExecHost* host = ExecHost::GetInstance(); @@ -86,6 +87,7 @@ int srv_host(int argc, char* argv[]) return 0; } + static void _host_greet() { cnsl::InsertText(GREETING_COLOR, "Pash Host fully operational!\n"); @@ -95,6 +97,7 @@ static void _host_greet() cnsl::FlushInput(); } + static const char* _get_completion(const char* input, int* revert) { if (revert) @@ -175,6 +178,7 @@ static const char* _get_completion(const char* input, int* revert) return completion; } + static void _get_candidates(const std::string& path) { XMLElementPtr node = PashDocUtil::GetNodeByPath(path); @@ -193,6 +197,7 @@ static void _get_candidates(const std::string& path) *candidate = nullptr; } + static void _host_parse_command(char* cmd) { std::string temp(cmd); @@ -222,6 +227,7 @@ static void _host_parse_command(char* cmd) strcpy_s(cmd, EXEC_BUFFER_SIZE, temp.c_str()); } + static int _host_peek_command() { _cmd = nullptr; @@ -246,6 +252,7 @@ static int _host_peek_command() return 0; } + static int _host_peeker_standard(char* buffer, char** cmd, int* argc, char* argv[]) { *cmd = nullptr; @@ -266,6 +273,7 @@ static int _host_peeker_standard(char* buffer, char** cmd, int* argc, char* argv return 0; } + static bool _is_in(char ch, const char* ignore) { for (const char* p = ignore; *p; p++) @@ -276,6 +284,7 @@ static bool _is_in(char ch, const char* ignore) return false; } + static int _host_peeker_advanced(char* buffer, char** cmd, int* argc, char* argv[]) { *cmd = nullptr; diff --git a/PassBashPro/src/exec/service/srv_import.cpp b/PassBashPro/src/exec/service/srv_import.cpp index 47f0211..1f85323 100644 --- a/PassBashPro/src/exec/service/srv_import.cpp +++ b/PassBashPro/src/exec/service/srv_import.cpp @@ -25,6 +25,7 @@ int _import_usage(); int _import_reload(); + int srv_import(int argc, char* argv[]) { if (argc != 2) @@ -89,12 +90,14 @@ int srv_import(int argc, char* argv[]) return 0; } + int _import_usage() { return ExecHost::GetInstance() - ->execl(MODE_TO_EXEC[g_mode], "help", "help", "import", nullptr); + ->execl(MODE_TO_EXEC[g_mode], "help", "help", "import", nullptr); } + int _import_reload() { if (!g_doc.Load(g_env)) diff --git a/PassBashPro/src/exec/service/srv_login.cpp b/PassBashPro/src/exec/service/srv_login.cpp index 348956f..4f1f96d 100644 --- a/PassBashPro/src/exec/service/srv_login.cpp +++ b/PassBashPro/src/exec/service/srv_login.cpp @@ -49,6 +49,7 @@ static bool _confirm_abort(); static int _handle_user_not_exists(const char* username); + int srv_login(int argc, char* argv[]) { // There must be at least one possible user! @@ -123,16 +124,19 @@ int srv_login(int argc, char* argv[]) return 0; } + static void _login_header() { cnsl::InsertText(GREETING_COLOR, "Logging in to PassBash...\n\n"); } + static void _login_footer() { cnsl::InsertText(GREETING_COLOR, "\nCredential confirmed!\n\n"); } + static int _login_list_users() { ProfilePoolPtr pool = ProfilePool::GetInstance(); @@ -158,6 +162,7 @@ static int _login_list_users() return 0; } + /******************************************************************** ** Receive username to login, and set g_env to the selected user. */ @@ -211,6 +216,7 @@ static int _login_receive_username() return 0; } + /******************************************************************** ** Receive password and make validation. Set g_env->password to the ** correct password after validation. @@ -264,17 +270,20 @@ static int _login_receive_password() return 0; } + static bool _login_check_env(EnvPtr env) { return (FileUtil::Exists(env->configPath.c_str()) && FileUtil::Exists(env->dataPath.c_str())); } + static bool _login_init_env(EnvPtr env) { return g_doc.Load(env); } + static bool _confirm_abort() { EXEC_PRINT_MSG("Abort login? (Y/N) "); @@ -292,6 +301,7 @@ static bool _confirm_abort() return tolower(buffer[0]) == 'y'; } + static const char* _get_completion(const char* input, int* revert) { if (!_candidates[0]) @@ -324,6 +334,7 @@ static const char* _get_completion(const char* input, int* revert) return completion; } + static int _handle_user_not_exists(const char* username) { cnsl::InsertNewLine(); diff --git a/PassBashPro/src/exec/service/srv_profile.cpp b/PassBashPro/src/exec/service/srv_profile.cpp index 53930ec..108c4ea 100644 --- a/PassBashPro/src/exec/service/srv_profile.cpp +++ b/PassBashPro/src/exec/service/srv_profile.cpp @@ -44,6 +44,7 @@ static int _profile_delete(); static int _profile_receive_username(bool showHelp = false); static int _profile_receive_password(bool showHelp = false); + int srv_profile(int argc, char* argv[]) { _profile_init(); @@ -76,6 +77,7 @@ int srv_profile(int argc, char* argv[]) return ret; } + static void _profile_init() { username = ""; @@ -86,12 +88,14 @@ static void _profile_init() isDelete = false; } + static int _profile_usage() { return ExecHost::GetInstance() - ->execl(EXEC_GLOBAL, "help", "help", "profile", nullptr); + ->execl(EXEC_GLOBAL, "help", "help", "profile", nullptr); } + static int _profile_parse_arg(int argc, char* argv[]) { int opt; @@ -157,6 +161,7 @@ static int _profile_parse_arg(int argc, char* argv[]) return 0; } + static int _profile_cli(bool showHelp) { int ret = _profile_receive_username(showHelp); @@ -170,6 +175,7 @@ static int _profile_cli(bool showHelp) return ret; } + static int _profile_silent() { ProfilePoolPtr pool = ProfilePool::GetInstance(); @@ -204,6 +210,7 @@ static int _profile_silent() return 0; } + static int _profile_delete_confirm() { EXEC_PRINT_MSG("Delete current profile? (Y/N) "); @@ -221,11 +228,13 @@ static int _profile_delete_confirm() return tolower(buffer[0]) != 'y'; } + static int _profile_delete_current() { return DeleteProfile(ProfilePool::GetInstance()->Get(username), true); } + static int _profile_delete() { if (!VerifyUsername(username)) @@ -287,6 +296,7 @@ static int _profile_delete() return 0; } + static int _profile_receive_username(bool showHelp) { char buffer[USERNAME_BUFFER_SIZE]; @@ -345,6 +355,7 @@ static int _profile_receive_username(bool showHelp) return 0; } + static int _profile_receive_password(bool showHelp) { char buffer[PASSWORD_BUFFER_SIZE]; diff --git a/PassBashPro/src/exec/service/srv_remaster.cpp b/PassBashPro/src/exec/service/srv_remaster.cpp index cd407f2..15d8f7f 100644 --- a/PassBashPro/src/exec/service/srv_remaster.cpp +++ b/PassBashPro/src/exec/service/srv_remaster.cpp @@ -28,6 +28,7 @@ static int _remaster_receive_password(); static int _remaster_reencrypt_data(); static void _remaster_abort(); + int srv_remaster(int argc, char* argv[]) { PASH_PANIC_ON(g_env == nullptr); @@ -61,12 +62,14 @@ int srv_remaster(int argc, char* argv[]) return 0; } + static void _remaster_greeting() { cnsl::InsertText(MESSAGE_COLOR, "You are now changing your master password.\n"); cnsl::InsertText(MESSAGE_COLOR, "Press ESC to abort.\n"); } + static int _remaster_authorize() { char buffer[PASSWORD_BUFFER_SIZE]; @@ -121,6 +124,7 @@ static int _remaster_authorize() return 0; } + static int _remaster_receive_password() { char buffer[PASSWORD_BUFFER_SIZE]; @@ -161,6 +165,7 @@ static int _remaster_receive_password() return 0; } + static int _remaster_reencrypt_data() { PASH_PANIC_ON(SaveConfig(g_env, true)); @@ -169,6 +174,7 @@ static int _remaster_reencrypt_data() return 0; } + static void _remaster_abort() { cnsl::InsertText(MESSAGE_COLOR, "Aborted! Master password remains!\n"); diff --git a/PassBashPro/src/exec/service/srv_save.cpp b/PassBashPro/src/exec/service/srv_save.cpp index eac3615..df95017 100644 --- a/PassBashPro/src/exec/service/srv_save.cpp +++ b/PassBashPro/src/exec/service/srv_save.cpp @@ -22,6 +22,7 @@ #include "../../../inc/exec/service/ServiceHeader.h" + int srv_save(int argc, char* argv[]) { if (g_doc.Save(g_env)) diff --git a/PassBashPro/src/exec/service/srv_start.cpp b/PassBashPro/src/exec/service/srv_start.cpp index 9627177..5178a97 100644 --- a/PassBashPro/src/exec/service/srv_start.cpp +++ b/PassBashPro/src/exec/service/srv_start.cpp @@ -35,6 +35,7 @@ static int _login_init_env(); static char _cached_user[USERNAME_BUFFER_SIZE]; + int srv_start(int argc, char* argv[]) { if (ExecHost::GetInstance() @@ -55,7 +56,7 @@ int srv_start(int argc, char* argv[]) { // Use absolute zero to indicate internal call. ret = ExecHost::GetInstance() - ->execl(EXEC_SERVICE, "profile", nullptr); + ->execl(EXEC_SERVICE, "profile", nullptr); if (ret != 0) { if (ret == TERMINATION) @@ -72,11 +73,11 @@ int srv_start(int argc, char* argv[]) RE_LOGIN: ret = ExecHost::GetInstance() - ->execl(EXEC_SERVICE, "login", "login", nullptr); + ->execl(EXEC_SERVICE, "login", "login", nullptr); while (ret == -1) // To create new user. { ret = ExecHost::GetInstance() - ->execl(EXEC_SERVICE, "profile", nullptr); + ->execl(EXEC_SERVICE, "profile", nullptr); if (ret != 0) { if (ret == TERMINATION) @@ -95,7 +96,7 @@ int srv_start(int argc, char* argv[]) // re-login ret = ExecHost::GetInstance() - ->execl(EXEC_SERVICE, "login", "login", nullptr); + ->execl(EXEC_SERVICE, "login", "login", nullptr); } if (ret != 0) @@ -107,7 +108,7 @@ int srv_start(int argc, char* argv[]) } ret = ExecHost::GetInstance() - ->execl(EXEC_SERVICE, "host", "host", nullptr); + ->execl(EXEC_SERVICE, "host", "host", nullptr); if (ret != 0) { if (ret == TERMINATION) @@ -122,6 +123,7 @@ int srv_start(int argc, char* argv[]) return 0; } + static int _ensure_env() { if (!FileUtil::Exists(PASH_DIR)) @@ -136,6 +138,7 @@ static int _ensure_env() return 0; } + static int _load_env() { _ensure_env(); @@ -148,6 +151,7 @@ static int _load_env() return 0; } + static int _load_profile() { std::vector dirs; @@ -170,6 +174,7 @@ static int _load_profile() return 0; } + static int _load_cache() { std::string path(PASH_DIR); @@ -218,6 +223,7 @@ static int _load_cache() return 0; } + static int _login_init_env() { ProfilePoolPtr pool = ProfilePool::GetInstance(); diff --git a/PassBashPro/src/utility/Argument.cpp b/PassBashPro/src/utility/Argument.cpp index af945e2..4a6aa49 100644 --- a/PassBashPro/src/utility/Argument.cpp +++ b/PassBashPro/src/utility/Argument.cpp @@ -34,6 +34,7 @@ int optopt; static int optind; + void resetopt() { optind = 0; @@ -42,6 +43,7 @@ void resetopt() optmsg = nullptr; } + static int _parseopt(const char* arg); // parse arg in opt. e.g. pthread from -lpthread @@ -50,6 +52,7 @@ static char* _parsearg(char* arg); static void _initopt(); + int getopt(int argc, char* argv[], const char* pattern) { _initopt(); @@ -103,6 +106,7 @@ int getopt(int argc, char* argv[], const char* pattern) return opt; } + static int _parseopt(const char* arg) { if (arg[0] == '-' && arg[1] != '\0') @@ -110,6 +114,7 @@ static int _parseopt(const char* arg) return 0; } + // parse arg in opt. e.g. pthread from -lpthread // Must checked by _parseopt first. static char* _parsearg(char* arg) @@ -119,6 +124,7 @@ static char* _parsearg(char* arg) return nullptr; } + static void _initopt() { optarg = nullptr; diff --git a/PassBashPro/src/utility/Auxiliary.cpp b/PassBashPro/src/utility/Auxiliary.cpp index b84c653..482e598 100644 --- a/PassBashPro/src/utility/Auxiliary.cpp +++ b/PassBashPro/src/utility/Auxiliary.cpp @@ -58,6 +58,7 @@ char* strstrip(char* str) return str; } + char* strtolower(char* str) { if (!str) @@ -69,6 +70,7 @@ char* strtolower(char* str) return str; } + char* strtoupper(char* str) { if (!str) @@ -86,6 +88,7 @@ bool is_null_or_empty(const char* str) return !str || !*str; } + bool begins_with(const char* str, const char* prefix) { if (is_null_or_empty(prefix)) @@ -105,6 +108,7 @@ bool begins_with(const char* str, const char* prefix) return !*prefix; } + bool ends_with(const char* str, const char* suffix) { if (is_null_or_empty(suffix)) @@ -241,6 +245,7 @@ const char* GetCurrentTimestamp() return _time_buffer; } + /****************************************************************************** * ResetRandomSeed -- Reset random seed. * * * @@ -257,9 +262,10 @@ const char* GetCurrentTimestamp() *============================================================================*/ void SetRandomSeed() { - srand(static_cast(time(NULL))); + srand(static_cast(time(nullptr))); } + /****************************************************************************** * Random -- Get a random number. * * * @@ -280,6 +286,7 @@ int Random(int upper) return (upper == 0) ? (0) : (rand() % upper); } + int Random(int lower, int upper) { if (upper <= lower) diff --git a/PassBashPro/src/utility/ExecUtil.cpp b/PassBashPro/src/utility/ExecUtil.cpp index 107c039..1a5f5b2 100644 --- a/PassBashPro/src/utility/ExecUtil.cpp +++ b/PassBashPro/src/utility/ExecUtil.cpp @@ -103,6 +103,7 @@ int _ParseOptionalArgs(int argc, char* argv[], std::string& _1) return 0; } + int _ParseArgs(int argc, char* argv[], std::string& _1) { int opt; @@ -261,7 +262,7 @@ int _ShowItem(XMLElementPtr node, bool detail, const char* key, WORD color) int id = 0; auto hidden = "******"; const char* value; - constexpr WORD ENTRY_COLOR[2] = {FOREGROUND_WHITE, FOREGROUND_LIGHT(FOREGROUND_WHITE)}; + constexpr WORD ENTRY_COLOR[2] = { FOREGROUND_WHITE, FOREGROUND_LIGHT(FOREGROUND_WHITE) }; for (auto& it : list) { value = (!detail && _IsSensitive(it.key)) ? hidden : it.value; @@ -333,7 +334,7 @@ int _ShowItemSimple(XMLElementPtr node, bool detail, const char* key, WORD color int id = 0; auto hidden = "******"; const char* value; - constexpr WORD ENTRY_COLOR[2] = {FOREGROUND_WHITE, FOREGROUND_LIGHT(FOREGROUND_WHITE)}; + constexpr WORD ENTRY_COLOR[2] = { FOREGROUND_WHITE, FOREGROUND_LIGHT(FOREGROUND_WHITE) }; for (auto& it : list) { value = (!detail && _IsSensitive(it.key)) ? hidden : it.value; @@ -359,6 +360,7 @@ int _ShowItemSimple(XMLElementPtr node, bool detail, const char* key, WORD color return 0; } + bool _IsSensitive(const char* descr) { static const char* const SENSITIVE_PATTERN[] = { @@ -380,6 +382,7 @@ bool _IsSensitive(const char* descr) return false; } + /* **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ** Password operations. @@ -396,6 +399,7 @@ void _FormatPassword(char* password) *p = '\0'; } + void _FormatPassword(const char* buffer, char* password) { memset(password, 0, sizeof(char) * PASSWORD_MAX_LENGTH); @@ -408,6 +412,7 @@ void _FormatPassword(const char* buffer, char* password) *q = '\0'; } + void _HashPassword(char* hashPass) { hash::MD5 md5; @@ -418,6 +423,7 @@ void _HashPassword(char* hashPass) // hashPass[PASSWORD_MAX_LENGTH] = '\0'; } + void _HashPassword(const char* password, char* hashPass) { hash::MD5 md5; diff --git a/PassBashPro/src/utility/FileUtil.cpp b/PassBashPro/src/utility/FileUtil.cpp index d787e43..1454ce3 100644 --- a/PassBashPro/src/utility/FileUtil.cpp +++ b/PassBashPro/src/utility/FileUtil.cpp @@ -33,16 +33,19 @@ static char buffer[PASH_BUFFER_SIZE]; + bool FileUtil::Exists(const char* path) { return (_access(path, 0) == 0); } + bool FileUtil::Exists(const wchar_t* path) { return (_waccess(path, 0) == 0); } + bool FileUtil::NewFile(const char* path) { // To be continued... @@ -50,6 +53,7 @@ bool FileUtil::NewFile(const char* path) return true; } + bool FileUtil::NewFile(const char* path, const char* filename) { std::string fullPath = path; @@ -60,6 +64,7 @@ bool FileUtil::NewFile(const char* path, const char* filename) return NewFile(fullPath.c_str()); } + bool FileUtil::NewDirectory(const char* path, bool hidden) { char* context = nullptr; @@ -98,6 +103,7 @@ bool FileUtil::NewDirectory(const char* path, bool hidden) return true; } + bool FileUtil::NewDirectory(const char* path, const char* dirname, bool hidden) { std::string fullPath = path; @@ -108,16 +114,19 @@ bool FileUtil::NewDirectory(const char* path, const char* dirname, bool hidden) return NewDirectory(fullPath.c_str(), hidden); } + bool FileUtil::DeleteFilePath(const char* path) { return DeleteFilePath(widen(path)); } + bool FileUtil::DeleteFilePath(const wchar_t* path) { return DeleteFile(path); } + bool FileUtil::DeletePath(const char* path) { if (!Exists(path)) @@ -143,6 +152,7 @@ bool FileUtil::DeletePath(const wchar_t* path) return true; } + bool FileUtil::CopyFileToNew(const char* src, const char* dst, bool overwrite) { if (!Exists(src)) @@ -162,6 +172,7 @@ bool FileUtil::CopyFileToNew(const char* src, const char* dst, bool overwrite) return ret; } + bool FileUtil::MoveFileToNew(const char* src, const char* dst) { if (!Exists(src)) @@ -181,6 +192,7 @@ bool FileUtil::MoveFileToNew(const char* src, const char* dst) return ret; } + bool FileUtil::GetFiles(const char* path, std::vector* files, std::vector* names) @@ -188,6 +200,7 @@ bool FileUtil::GetFiles(const char* path, return _GetContent(path, files, names, _FILE); } + bool FileUtil::GetDirectories(const char* path, std::vector* dirs, std::vector* names) @@ -195,6 +208,7 @@ bool FileUtil::GetDirectories(const char* path, return _GetContent(path, dirs, names, _DIR); } + bool FileUtil::GetContent(const char* path, std::vector* paths, std::vector* names) @@ -202,6 +216,7 @@ bool FileUtil::GetContent(const char* path, return _GetContent(path, paths, names, _ALL); } + bool FileUtil::_GetContent(const char* path, std::vector* paths, std::vector* names, @@ -220,6 +235,7 @@ bool FileUtil::_GetContent(const char* path, return true; } + void FileUtil::_GetContentAux(const char* path, std::vector* paths, std::vector* names, @@ -271,6 +287,7 @@ void FileUtil::_GetContentAux(const char* path, while (_findnext(hFile, &fileInfo) == 0); } + void FileUtil::_DeleteDirectory(const char* path) { long long hFile = 0; @@ -312,6 +329,7 @@ void FileUtil::_DeleteDirectory(const char* path) _rmdir(path); } + void FileUtil::_DeleteDirectory(const wchar_t* path) { long long hFile = 0; diff --git a/PassBashPro/src/utility/PassDocUtil.cpp b/PassBashPro/src/utility/PassDocUtil.cpp index cc42b10..6c8ca40 100644 --- a/PassBashPro/src/utility/PassDocUtil.cpp +++ b/PassBashPro/src/utility/PassDocUtil.cpp @@ -33,26 +33,31 @@ bool PashDocUtil::IsGroup(XMLElementPtr node) return _STR_SAME(node->Name(), GROUP_TAG); } + bool PashDocUtil::IsItem(XMLElementPtr node) { return _STR_SAME(node->Name(), ITEM_TAG); } + const char* PashDocUtil::GetNodeAttr(XMLElementPtr node, const char* attr) { return node->Attribute(attr); } + const char* PashDocUtil::GetNodeName(XMLElementPtr node) { return GetNodeAttr(node, "name"); } + XMLElementPtr PashDocUtil::GetParentNode(XMLElementPtr node) { return node->Parent()->ToElement(); } + bool PashDocUtil::IsLegalNodeName(const std::string& name) { return ( @@ -66,17 +71,20 @@ XMLElementPtr PashDocUtil::CreateNode(const char* tag) return g_doc.NewElement(tag); } + void PashDocUtil::DeleteNode(XMLElementPtr node) { g_doc.DeleteElement(node); } + XMLElementPtr PashDocUtil::AddChildNode(XMLElementPtr node, XMLElementPtr child) { node->InsertEndChild(child); return child; } + const char* PashDocUtil::GetNodeDirectory(XMLElementPtr node, std::string& path) { XMLElementPtr root = g_doc.GetRoot(); @@ -102,6 +110,7 @@ const char* PashDocUtil::GetNodeDirectory(XMLElementPtr node, std::string& path) return path.c_str(); } + const char* PashDocUtil::GetPresentWorkingDirectory(std::string& path) { return GetNodeDirectory(g_doc.GetCurrent(), path); @@ -131,6 +140,7 @@ XMLElementPtr PashDocUtil::GetDirectChildNode(XMLElementPtr node, const char* na return nullptr; } + bool PashDocUtil::GetChildren(XMLElementPtr node, XMLElementPtrList& nodes) { nodes.clear(); @@ -150,6 +160,7 @@ bool PashDocUtil::GetChildren(XMLElementPtr node, XMLElementPtrList& nodes) return true; } + XMLElementPtr PashDocUtil::GetNodeByPath(const std::string& path) { char* buffer = _strdup(path.c_str()); @@ -190,6 +201,7 @@ XMLElementPtr PashDocUtil::GetNodeByPath(const std::string& path) return node; } + XMLElementPtr PashDocUtil::GetChildNodeByPath(const std::string& path) { XMLElementPtr current = g_doc.GetCurrent(); @@ -200,6 +212,7 @@ XMLElementPtr PashDocUtil::GetChildNodeByPath(const std::string& path) return nullptr; } + XMLElementPtr PashDocUtil::GetOrCreateChildNode(XMLElementPtr node, const char* tag, const char* name) { XMLElementPtr child = GetDirectChildNode(node, name); @@ -213,6 +226,7 @@ XMLElementPtr PashDocUtil::GetOrCreateChildNode(XMLElementPtr node, const char* return child; } + void PashDocUtil::DeleteChildNode(XMLElementPtr node, const char* name) { XMLElementPtr child = GetDirectChildNode(node, name); @@ -220,11 +234,13 @@ void PashDocUtil::DeleteChildNode(XMLElementPtr node, const char* name) DeleteNode(child); } + void PashDocUtil::DeleteChildren(XMLElementPtr node) { node->DeleteChildren(); } + bool PashDocUtil::IsParent(XMLElementPtr parent, XMLElementPtr child) { XMLElementPtr root = g_doc.GetRoot(); @@ -242,6 +258,7 @@ bool PashDocUtil::IsParent(XMLElementPtr parent, XMLElementPtr child) return false; } + void PashDocUtil::GetBaseName(const std::string& path, std::string& name) { size_t pos = path.find_last_of('/'); @@ -266,6 +283,7 @@ void PashDocUtil::GetBaseName(const std::string& path, std::string& name) } } + void PashDocUtil::GetParentPath(const std::string& path, std::string& name) { std::string temp = path; @@ -323,6 +341,7 @@ XMLElementPtr PashDocUtil::CreateGroupNodeByPath(const std::string& path) return node; } + bool PashDocUtil::GetGroupChildren(XMLElementPtr node, XMLElementPtrList& nodes) { nodes.clear(); @@ -427,6 +446,7 @@ bool PashDocUtil::GetEntry(XMLElementPtr node, const char* key, Entry* entry) return false; } + bool PashDocUtil::GetEntries(XMLElementPtr node, EntryList& entries) { if (!IsItem(node)) @@ -453,6 +473,7 @@ bool PashDocUtil::GetEntries(XMLElementPtr node, EntryList& entries) return true; } + XMLElementPtr PashDocUtil::GetEntryNode(XMLElementPtr node, const char* key) { if (!IsItem(node)) @@ -469,6 +490,7 @@ XMLElementPtr PashDocUtil::GetEntryNode(XMLElementPtr node, const char* key) return p; } + XMLElementPtr PashDocUtil::GetEntryNode(XMLElementPtr node, int id) { if (!IsItem(node)) @@ -483,6 +505,7 @@ XMLElementPtr PashDocUtil::GetEntryNode(XMLElementPtr node, int id) return nullptr; } + XMLElementPtr PashDocUtil::GetOrCreateEntryNode(XMLElementPtr node, const char* key) { if (!IsItem(node)) @@ -499,6 +522,7 @@ XMLElementPtr PashDocUtil::GetOrCreateEntryNode(XMLElementPtr node, const char* return p; } + // If exists, it will override current one. bool PashDocUtil::SetEntry(XMLElementPtr node, const Entry& entry) { diff --git a/PassBashPro/src/utility/xml.cpp b/PassBashPro/src/utility/xml.cpp index 132f751..216ee77 100644 --- a/PassBashPro/src/utility/xml.cpp +++ b/PassBashPro/src/utility/xml.cpp @@ -83,6 +83,7 @@ bool XMLFile::Parse(const char* xml) return true; } + /****************************************************************************** * XMLFile::Load -- Load XML file from memory. * * * @@ -114,6 +115,7 @@ bool XMLFile::Load(const char* filename) return true; } + bool XMLFile::Save() { if (m_filename == "") @@ -126,6 +128,7 @@ bool XMLFile::Save() return Save(m_filename.c_str()); } + bool XMLFile::Save(const char* filename) { if (!m_isLoaded) @@ -291,6 +294,7 @@ std::vector XMLFile::GetElementsByTagName(const char* tag) return XMLUtil::GetElementsByTagName(GetRoot(), tag); } + std::vector XMLFile::GetElementsByAttrName(const char* attr, const char* name) { return XMLUtil::GetElementsByAttrName(GetRoot(), attr, name); @@ -324,6 +328,7 @@ XMLElement* XMLUtil::GetElementByTagName(XMLElement* node, const char* tag) return nullptr; } + XMLElement* XMLUtil::GetElementByAttrName(XMLElement* node, const char* attr, const char* name) { if (!node) @@ -349,6 +354,7 @@ XMLElement* XMLUtil::GetElementByAttrName(XMLElement* node, const char* attr, co return nullptr; } + std::vector XMLUtil::GetElementsByTagName(XMLElement* node, const char* tag) { std::vector results; @@ -358,6 +364,7 @@ std::vector XMLUtil::GetElementsByTagName(XMLElement* node, const c return results; } + std::vector XMLUtil::GetElementsByAttrName(XMLElement* node, const char* attr, const char* name) { std::vector results; @@ -367,6 +374,7 @@ std::vector XMLUtil::GetElementsByAttrName(XMLElement* node, const return results; } + void XMLUtil::_GetElementsByTagName(XMLElement* node, const char* tag, std::vector& results) { if (!node) @@ -384,6 +392,7 @@ void XMLUtil::_GetElementsByTagName(XMLElement* node, const char* tag, std::vect } } + void XMLUtil::_GetElementsByAttrName(XMLElement* node, const char* attr, const char* name, std::vector& results) { diff --git a/TEA/inc/tea_core.h b/TEA/inc/tea_core.h index c21fc49..ab7bcf8 100644 --- a/TEA/inc/tea_core.h +++ b/TEA/inc/tea_core.h @@ -26,20 +26,20 @@ #include "tea_defines.h" _TEA_BEGIN - // core algorithm - // v[2]: 8 characters to be encrypted = 8 Byte - // w[2]: save encrypted 8 characters = 8 Byte - // k[4]: the key = 16 Byte - // it only encrypt/decrypt part of the data - void encipher(const DATA* v, DATA* w, const DATA* k); - void decipher(const DATA* v, DATA* w, const DATA* k); +// core algorithm +// v[2]: 8 characters to be encrypted = 8 Byte +// w[2]: save encrypted 8 characters = 8 Byte +// k[4]: the key = 16 Byte +// it only encrypt/decrypt part of the data +void encipher(const DATA* v, DATA* w, const DATA* k); +void decipher(const DATA* v, DATA* w, const DATA* k); - // easy way to use - class TEAReader; - class TEAWriter; - // key must not be longer than 16! - void encode(TEAReader* input, TEAWriter* output, const char* key); - void decode(TEAReader* input, TEAWriter* output, const char* key); +// easy way to use +class TEAReader; +class TEAWriter; +// key must not be longer than 16! +void encode(TEAReader* input, TEAWriter* output, const char* key); +void decode(TEAReader* input, TEAWriter* output, const char* key); _TEA_END diff --git a/TEA/inc/tea_defines.h b/TEA/inc/tea_defines.h index 446533f..ae8c001 100644 --- a/TEA/inc/tea_defines.h +++ b/TEA/inc/tea_defines.h @@ -28,20 +28,20 @@ #define _TEA ::tea:: _TEA_BEGIN - using DATA = unsigned long; +using DATA = unsigned long; - /******************************************************************** - ** If TEA_CRACK is defined, the encrypted file will include original - ** file content for debug purpose, or as weak encryption. - */ +/******************************************************************** +** If TEA_CRACK is defined, the encrypted file will include original +** file content for debug purpose, or as weak encryption. +*/ #ifdef TEA_CRACK #define TEA_K 2 #else #define TEA_K 1 #endif - constexpr size_t NCHAR = 2 * sizeof(long); // 64 bit = 8 Byte = 8 char - constexpr size_t KCHAR = TEA_K * NCHAR; // 128 bit = 16 Byte = 16 char +constexpr size_t NCHAR = 2 * sizeof(long); // 64 bit = 8 Byte = 8 char +constexpr size_t KCHAR = TEA_K * NCHAR; // 128 bit = 16 Byte = 16 char _TEA_END diff --git a/TEA/inc/tea_util.h b/TEA/inc/tea_util.h index 0b5420c..e6724eb 100644 --- a/TEA/inc/tea_util.h +++ b/TEA/inc/tea_util.h @@ -28,154 +28,171 @@ #include _TEA_BEGIN - /******************************************************************** - ** Reader and Writer hides file details. read and write are not - ** recommended to call by your self. You'd better remember to close - ** them, but it's OK to leave it alone. - */ - class TEAReader +/******************************************************************** +** Reader and Writer hides file details. read and write are not +** recommended to call by your self. You'd better remember to close +** them, but it's OK to leave it alone. +*/ +class TEAReader +{ +public: + TEAReader() { - public: - TEAReader() - { - } + } - virtual ~TEAReader() = 0; - virtual bool Read(char* buffer, size_t nBytes) = 0; - virtual void Close() = 0; - }; + virtual ~TEAReader() = 0; - class TEAWriter + virtual bool Read(char* buffer, size_t nBytes) = 0; + virtual void Close() = 0; +}; + + +class TEAWriter +{ +public: + TEAWriter() { - public: - TEAWriter() - { - } + } + + + virtual ~TEAWriter() = 0; + + virtual bool Write(const char* buffer, size_t nBytes) = 0; + virtual void Close() = 0; +}; - virtual ~TEAWriter() = 0; - virtual bool Write(const char* buffer, size_t nBytes) = 0; - virtual void Close() = 0; - }; +struct TEAReadBuffer +{ + const char* base; + const char* pc; - struct TEAReadBuffer + + TEAReadBuffer(const char* _base) { - const char* base; - const char* pc; + base = _base; + pc = base; + } +}; + - TEAReadBuffer(const char* _base) - { - base = _base; - pc = base; - } - }; +struct TEAWriteBuffer +{ + char* base; + char* pc; - struct TEAWriteBuffer + + TEAWriteBuffer(char* _base) { - char* base; - char* pc; - - TEAWriteBuffer(char* _base) - { - base = _base; - pc = base; - } - }; - - - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Readers - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - class TEAFileReader : public TEAReader + base = _base; + pc = base; + } +}; + + +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Readers +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +class TEAFileReader : public TEAReader +{ +public: + TEAFileReader(FILE* input) : m_input(input) { - public: - TEAFileReader(FILE* input) : m_input(input) - { - } + } + - ~TEAFileReader() override { Close(); } + ~TEAFileReader() override { Close(); } - bool Read(char* buffer, size_t nBytes) override; - void Close() override; + bool Read(char* buffer, size_t nBytes) override; + void Close() override; - protected: - FILE* m_input; - }; +protected: + FILE* m_input; +}; - // No overflow check! Must terminate with '\0' - class TEABufferReader : public TEAReader + +// No overflow check! Must terminate with '\0' +class TEABufferReader : public TEAReader +{ +public: + TEABufferReader(const char* buffer) : m_buffer(buffer) { - public: - TEABufferReader(const char* buffer) : m_buffer(buffer) - { - } + } + + + ~TEABufferReader() override { Close(); } - ~TEABufferReader() override { Close(); } + bool Read(char* buffer, size_t nBytes) override; + void Close() override; - bool Read(char* buffer, size_t nBytes) override; - void Close() override; +protected: + TEAReadBuffer m_buffer; +}; - protected: - TEAReadBuffer m_buffer; - }; +// Will not teminate at '\0', length must be specified instead. +class TEARawBufferReader : public TEABufferReader +{ +public: + TEARawBufferReader(const char* buffer, size_t nBytes); - // Will not teminate at '\0', length must be specified instead. - class TEARawBufferReader : public TEABufferReader + + ~TEARawBufferReader() override { - public: - TEARawBufferReader(const char* buffer, size_t nBytes); + } + - ~TEARawBufferReader() override - { - } + bool Read(char* buffer, size_t nBytes) override; - bool Read(char* buffer, size_t nBytes) override; +protected: + size_t m_nBytes; +}; - protected: - size_t m_nBytes; - }; - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Writers - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - class TEAFileWriter : public TEAWriter +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Writers +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +class TEAFileWriter : public TEAWriter +{ +public: + TEAFileWriter(FILE* output) : m_output(output) { - public: - TEAFileWriter(FILE* output) : m_output(output) - { - } + } - ~TEAFileWriter() override { Close(); } - bool Write(const char* buffer, size_t nBytes) override; - void Close() override; + ~TEAFileWriter() override { Close(); } - protected: - FILE* m_output; - }; + bool Write(const char* buffer, size_t nBytes) override; + void Close() override; - // No overflow check! - class TEABufferWriter : public TEAWriter +protected: + FILE* m_output; +}; + + +// No overflow check! +class TEABufferWriter : public TEAWriter +{ +public: + TEABufferWriter(char* buffer) : m_buffer(buffer) { - public: - TEABufferWriter(char* buffer) : m_buffer(buffer) - { - } + } + + + ~TEABufferWriter() override { Close(); } - ~TEABufferWriter() override { Close(); } + bool Write(const char* buffer, size_t nBytes) override; + void Close() override; - bool Write(const char* buffer, size_t nBytes) override; - void Close() override; +protected: + TEAWriteBuffer m_buffer; +}; - protected: - TEAWriteBuffer m_buffer; - }; _TEA_END diff --git a/TEA/src/tea_core.cpp b/TEA/src/tea_core.cpp index dc8743c..8b7121d 100644 --- a/TEA/src/tea_core.cpp +++ b/TEA/src/tea_core.cpp @@ -29,73 +29,77 @@ */ _TEA_BEGIN - static constexpr DATA TEA_DELTA = 0x9E3779B9; - static constexpr DATA TEA_SUM = 0xC6EF3720; +static constexpr DATA TEA_DELTA = 0x9E3779B9; +static constexpr DATA TEA_SUM = 0xC6EF3720; - void encipher(const DATA* const v, DATA* const w, const DATA* const k) + +void encipher(const DATA* const v, DATA* const w, const DATA* const k) +{ + static_assert(sizeof(DATA) == 4, "Size of DATA wrong for TEA"); + + DATA y = v[0]; + DATA z = v[1]; + DATA sum = 0; + + for (DATA n = 32; n > 0; n--) { - static_assert(sizeof(DATA) == 4, "Size of DATA wrong for TEA"); - - DATA y = v[0]; - DATA z = v[1]; - DATA sum = 0; - - for (DATA n = 32; n > 0; n--) - { - y += ((z << 4) ^ (z >> 5)) + z ^ sum + k[sum & 3]; - sum += TEA_DELTA; - z += ((y << 4) ^ (y >> 5)) + y ^ sum + k[(sum >> 11) & 3]; - } - w[0] = y; - w[1] = z; + y += ((z << 4) ^ (z >> 5)) + z ^ sum + k[sum & 3]; + sum += TEA_DELTA; + z += ((y << 4) ^ (y >> 5)) + y ^ sum + k[(sum >> 11) & 3]; } + w[0] = y; + w[1] = z; +} + + +void decipher(const DATA* const v, DATA* const w, const DATA* const k) +{ + static_assert(sizeof(DATA) == 4, "Size of DATA wrong for TEA"); - void decipher(const DATA* const v, DATA* const w, const DATA* const k) + DATA y = v[0]; + DATA z = v[1]; + DATA sum = TEA_SUM; + + for (DATA n = 32; n > 0; n--) { - static_assert(sizeof(DATA) == 4, "Size of DATA wrong for TEA"); - - DATA y = v[0]; - DATA z = v[1]; - DATA sum = TEA_SUM; - - for (DATA n = 32; n > 0; n--) - { - z -= ((y << 4) ^ (y >> 5)) + y ^ sum + k[(sum >> 11) & 3]; - sum -= TEA_DELTA; - y -= ((z << 4) ^ (z >> 5)) + z ^ sum + k[sum & 3]; - } - w[0] = y; - w[1] = z; + z -= ((y << 4) ^ (y >> 5)) + y ^ sum + k[(sum >> 11) & 3]; + sum -= TEA_DELTA; + y -= ((z << 4) ^ (z >> 5)) + z ^ sum + k[sum & 3]; } + w[0] = y; + w[1] = z; +} + +void encode(TEAReader* input, TEAWriter* output, const char* key) +{ + DATA outptr[2]; + char inbuf[NCHAR]; + auto inptr = reinterpret_cast(inbuf); + auto k = reinterpret_cast(key); - void encode(TEAReader* input, TEAWriter* output, const char* key) + while (input->Read(inbuf, NCHAR)) { - DATA outptr[2]; - char inbuf[NCHAR]; - auto inptr = reinterpret_cast(inbuf); - auto k = reinterpret_cast(key); - - while (input->Read(inbuf, NCHAR)) - { - encipher(inptr, outptr, k); - output->Write((char*)outptr, KCHAR); - } + encipher(inptr, outptr, k); + output->Write((char*)outptr, KCHAR); } +} + - void decode(TEAReader* input, TEAWriter* output, const char* key) +void decode(TEAReader* input, TEAWriter* output, const char* key) +{ + DATA inptr[2]; + char outbuf[NCHAR + 1]; + auto outptr = reinterpret_cast(outbuf); + auto k = reinterpret_cast(key); + + outbuf[NCHAR] = '\0'; + while (input->Read((char*)inptr, KCHAR)) { - DATA inptr[2]; - char outbuf[NCHAR + 1]; - auto outptr = reinterpret_cast(outbuf); - auto k = reinterpret_cast(key); - - outbuf[NCHAR] = '\0'; - while (input->Read((char*)inptr, KCHAR)) - { - decipher(inptr, outptr, k); - output->Write((char*)outptr, NCHAR); - } + decipher(inptr, outptr, k); + output->Write((char*)outptr, NCHAR); } +} + _TEA_END diff --git a/TEA/src/tea_util.cpp b/TEA/src/tea_util.cpp index 76bd202..98de286 100644 --- a/TEA/src/tea_util.cpp +++ b/TEA/src/tea_util.cpp @@ -24,122 +24,131 @@ _TEA_BEGIN - TEAReader::~TEAReader() - { - } +TEAReader::~TEAReader() +{ +} - TEAWriter::~TEAWriter() - { - } - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Readers - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - bool TEAFileReader::Read(char* buffer, size_t nBytes) - { - size_t bytes = fread(buffer, sizeof(char), nBytes, m_input); +TEAWriter::~TEAWriter() +{ +} - if (bytes == 0) - return false; - while (bytes < nBytes) - buffer[bytes++] = '\0'; +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Readers +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +bool TEAFileReader::Read(char* buffer, size_t nBytes) +{ + size_t bytes = fread(buffer, sizeof(char), nBytes, m_input); - return true; - } + if (bytes == 0) + return false; + + while (bytes < nBytes) + buffer[bytes++] = '\0'; + + return true; +} - void TEAFileReader::Close() + +void TEAFileReader::Close() +{ + if (m_input) { - if (m_input) - { - fclose(m_input); - m_input = nullptr; - } + fclose(m_input); + m_input = nullptr; } +} - bool TEABufferReader::Read(char* buffer, size_t nBytes) - { - if (*m_buffer.pc == '\0') - return false; +bool TEABufferReader::Read(char* buffer, size_t nBytes) +{ + if (*m_buffer.pc == '\0') + return false; - size_t bytes = 0; - while ((*m_buffer.pc != '\0') && (bytes < nBytes)) - buffer[bytes++] = *(m_buffer.pc++); - while (bytes < nBytes) - buffer[bytes++] = '\0'; + size_t bytes = 0; + while ((*m_buffer.pc != '\0') && (bytes < nBytes)) + buffer[bytes++] = *(m_buffer.pc++); + while (bytes < nBytes) + buffer[bytes++] = '\0'; - return true; - } + return true; +} - void TEABufferReader::Close() - { - m_buffer.base = m_buffer.pc = nullptr; - } +void TEABufferReader::Close() +{ + m_buffer.base = m_buffer.pc = nullptr; +} - TEARawBufferReader::TEARawBufferReader(const char* buffer, size_t nBytes) - : TEABufferReader(buffer), m_nBytes(nBytes) - { - } - bool TEARawBufferReader::Read(char* buffer, size_t nBytes) - { - if (m_nBytes == 0) - return false; - - size_t bytes = 0; - while ((m_nBytes > 0) && (bytes < nBytes)) - { - buffer[bytes++] = *(m_buffer.pc++); - m_nBytes--; - } - while (bytes < nBytes) - buffer[bytes++] = '\0'; - - return true; - } +TEARawBufferReader::TEARawBufferReader(const char* buffer, size_t nBytes) + : TEABufferReader(buffer), m_nBytes(nBytes) +{ +} - /* - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ** Writers - **+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - bool TEAFileWriter::Write(const char* buffer, size_t nBytes) - { - size_t bytes = fwrite(buffer, sizeof(char), nBytes, m_output); - return (bytes == nBytes); - } +bool TEARawBufferReader::Read(char* buffer, size_t nBytes) +{ + if (m_nBytes == 0) + return false; - void TEAFileWriter::Close() + size_t bytes = 0; + while ((m_nBytes > 0) && (bytes < nBytes)) { - if (m_output) - { - fclose(m_output); - m_output = nullptr; - } + buffer[bytes++] = *(m_buffer.pc++); + m_nBytes--; } + while (bytes < nBytes) + buffer[bytes++] = '\0'; + return true; +} - bool TEABufferWriter::Write(const char* buffer, size_t nBytes) - { - size_t bytes = 0; - while (bytes < nBytes) - *(m_buffer.pc++) = buffer[bytes++]; +/* +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +** Writers +**+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ +bool TEAFileWriter::Write(const char* buffer, size_t nBytes) +{ + size_t bytes = fwrite(buffer, sizeof(char), nBytes, m_output); - // Always mark the end of the buffer. - *m_buffer.pc = '\0'; + return (bytes == nBytes); +} - return true; - } - void TEABufferWriter::Close() +void TEAFileWriter::Close() +{ + if (m_output) { - m_buffer.base = m_buffer.pc = nullptr; + fclose(m_output); + m_output = nullptr; } +} + + +bool TEABufferWriter::Write(const char* buffer, size_t nBytes) +{ + size_t bytes = 0; + + while (bytes < nBytes) + *(m_buffer.pc++) = buffer[bytes++]; + + // Always mark the end of the buffer. + *m_buffer.pc = '\0'; + + return true; +} + + +void TEABufferWriter::Close() +{ + m_buffer.base = m_buffer.pc = nullptr; +} + _TEA_END