/******************************************************************************/ /* SlunkCrypt, by LoRd_MuldeR */ /* This work has been released under the CC0 1.0 Universal license! */ /******************************************************************************/ #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN 1 # define _CRT_SECURE_NO_WARNINGS 1 #else # define _GNU_SOURCE 1 #endif /* Internal */ #include #include "utils.h" /* CRT */ #include #include #include /* Platform support */ #ifdef _WIN32 # include # include # include # define STAT_T struct _stati64 # define FSTAT(X,Y) _fstati64((X),(Y)) # define FILENO(X) _fileno((X)) # define S_IFMT _S_IFMT # define S_IFDIR _S_IFDIR # define S_IFIFO _S_IFIFO # ifndef _O_U8TEXT # define _O_U8TEXT 0x40000 # endif #else # if defined(__USE_LARGEFILE64) && (__USE_LARGEFILE64) # define STAT_T struct stat64 # define FSTAT(X,Y) fstat64((X),(Y)) # else # define STAT_T struct stat # define FSTAT(X,Y) fstat((X),(Y)) # endif # define FILENO(X) fileno((X)) #endif // ========================================================================== // Terminal initialization // ========================================================================== #ifdef _WIN32 #ifdef _DLL #define _acmdln GetCommandLineA() #define _wcmdln GetCommandLineW() #else extern char *const _acmdln; extern wchar_t *const _wcmdln; #endif static void clear_cmdline_args(char *const acmdln, wchar_t *const wcmdln) { if (acmdln && acmdln[0U]) { const size_t len = strlen(acmdln); slunkcrypt_bzero(acmdln, len * sizeof(char)); if (len > 5U) strcpy(acmdln, "slunk"); } if (wcmdln && wcmdln[0U]) { const size_t len = wcslen(wcmdln); slunkcrypt_bzero(wcmdln, len * sizeof(wchar_t)); if (len > 5U) wcscpy(wcmdln, L"slunk"); } } #endif void init_terminal(void) { #ifdef _WIN32 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); _setmode(_fileno(stdout), _O_BINARY); _setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stderr), _O_U8TEXT); clear_cmdline_args(_acmdln, _wcmdln); #endif } // ========================================================================== // Signal handling // ========================================================================== void setup_signal_handler(const int signo, signal_handler_t* const handler) { #ifdef _WIN32 signal(signo, handler); #else struct sigaction act; act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(signo, &act, NULL); #endif } // ========================================================================== // Character set conversion // ========================================================================== char* CHR_to_utf8(const CHR*const input) { #ifdef _WIN32 char* buffer; DWORD buffer_size = 0U, result = 0U; buffer_size = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL); if (buffer_size < 1U) { return NULL; } buffer = (char*)malloc(sizeof(char) * buffer_size); if (!buffer) { return NULL; } result = WideCharToMultiByte(CP_UTF8, 0, input, -1, (LPSTR)buffer, buffer_size, NULL, NULL); if ((result > 0U) && (result <= buffer_size)) { return buffer; } free(buffer); return NULL; #else return strdup(input); #endif } // ========================================================================== // Byte-order support // ========================================================================== #if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) # define BIG_ENDIAN_BYTE_ORDER 1 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) # define BIG_ENDIAN_BYTE_ORDER 1 #else # define BIG_ENDIAN_BYTE_ORDER 0 #endif uint64_t swap_bytes_u64(const uint64_t value) { #if BIG_ENDIAN_BYTE_ORDER return (((value) >> 56) & 0x00000000000000FF) | (((value) >> 40) & 0x000000000000FF00) | (((value) >> 24) & 0x0000000000FF0000) | (((value) >> 8) & 0x00000000FF000000) | (((value) << 8) & 0x000000FF00000000) | (((value) << 24) & 0x0000FF0000000000) | (((value) << 40) & 0x00FF000000000000) | (((value) << 56) & 0xFF00000000000000); #else return value; /*nothing to do*/ #endif } // ========================================================================== // File functions // ========================================================================== uint64_t get_file_size(FILE* const file) { STAT_T stat; if (FSTAT(FILENO(file), &stat) == 0) { const uint16_t file_type = stat.st_mode & S_IFMT; if ((file_type != S_IFDIR) && (file_type != S_IFIFO)) { const int64_t ssize = stat.st_size; return (ssize >= 0) ? ((uint64_t)ssize) : 0U; } return 0U; } return UINT64_MAX; } const CHR* get_file_name(const CHR* path) { const CHR* ptr; while ((ptr = STRRCHR(path, T('/')))) { path = ptr + 1U; } while ((ptr = STRRCHR(path, T('\\')))) { path = ptr + 1U; } return path; } // ========================================================================== // Math functions // ========================================================================== uint64_t round_down(const uint64_t value, const uint64_t base) { const uint64_t modulus = value % base; return modulus ? (value - modulus) : value; }