301 lines
7.2 KiB
C++
301 lines
7.2 KiB
C++
#ifndef GERMANAIRLINESVA_GACONNECTOR_UTIL_H
|
|
#define GERMANAIRLINESVA_GACONNECTOR_UTIL_H
|
|
|
|
#define BUFSIZE 1024
|
|
#define MD5LEN 16
|
|
#define EARTH_M 6371000
|
|
|
|
#ifdef IBM
|
|
// clang-format off
|
|
#include <wtypes.h>
|
|
#include <wincrypt.h>
|
|
// clang-format on
|
|
#endif
|
|
#ifdef APL
|
|
#include <CommonCrypto/CommonDigest.h>
|
|
#include <sys/mman.h>
|
|
#endif
|
|
#ifdef LIN
|
|
#include <openssl/md5.h>
|
|
#include <sys/mman.h>
|
|
#endif
|
|
|
|
#if defined APL || defined LIN
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#include <algorithm>
|
|
#include <fstream>
|
|
#include <functional>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace germanairlinesva
|
|
{
|
|
namespace util
|
|
{
|
|
template <typename T>
|
|
static inline std::vector<T>
|
|
select_T(const std::vector<T> &inVec,
|
|
std::function<bool(const T &)> predicate)
|
|
{
|
|
std::vector<T> result;
|
|
copy_if(inVec.begin(), inVec.end(), back_inserter(result), predicate);
|
|
return result;
|
|
}
|
|
|
|
#if defined APL || defined LIN
|
|
static inline unsigned long get_size_by_fd(int fd)
|
|
{
|
|
struct stat buf {
|
|
};
|
|
if (fstat(fd, &buf) < 0)
|
|
return 0;
|
|
return buf.st_size;
|
|
}
|
|
#endif
|
|
|
|
static inline void to_hex(const char *hash, char *buffer)
|
|
{
|
|
for (int i = 0; i < MD5LEN; i++) {
|
|
if (buffer != nullptr) {
|
|
sprintf(&buffer[2 * i], "%02x", hash[i] & 0xff);
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline bool fileExists(const char *path)
|
|
{
|
|
return static_cast<bool>(std::ifstream(path));
|
|
}
|
|
|
|
#ifdef IBM
|
|
static inline int
|
|
generateMD5(const char *filepath,
|
|
char *lastHash,
|
|
const std::function<void(const std::string)> toLog)
|
|
{
|
|
BOOL bResult = FALSE;
|
|
HCRYPTPROV hProv = 0;
|
|
HCRYPTHASH hHash = 0;
|
|
HANDLE hFile;
|
|
BYTE rgbFile[BUFSIZE] = {0};
|
|
DWORD cbRead = 0;
|
|
BYTE rgbHash[MD5LEN] = {0};
|
|
DWORD cbHash = 0;
|
|
|
|
// Logic to check usage goes here.
|
|
hFile = CreateFile(filepath,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
nullptr,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_SEQUENTIAL_SCAN,
|
|
nullptr);
|
|
|
|
// Get handle to the crypto provider
|
|
if (!CryptAcquireContext(&hProv,
|
|
nullptr,
|
|
nullptr,
|
|
PROV_RSA_FULL,
|
|
CRYPT_VERIFYCONTEXT)) {
|
|
toLog("CryptAcquireContext returned with error " +
|
|
std::to_string(GetLastError()));
|
|
|
|
CloseHandle(hFile);
|
|
return 1;
|
|
}
|
|
|
|
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
|
|
toLog("CryptCreateHash returned with error " +
|
|
std::to_string(GetLastError()));
|
|
|
|
CloseHandle(hFile);
|
|
CryptReleaseContext(hProv, 0);
|
|
return 1;
|
|
}
|
|
|
|
while ((bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, nullptr))) {
|
|
if (0 == cbRead) {
|
|
break;
|
|
}
|
|
|
|
if (!CryptHashData(hHash, rgbFile, cbRead, 0)) {
|
|
toLog("CryptHashData returned with error " +
|
|
std::to_string(GetLastError()));
|
|
|
|
CryptReleaseContext(hProv, 0);
|
|
CryptDestroyHash(hHash);
|
|
CloseHandle(hFile);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!bResult) {
|
|
toLog("ReadFile returned with error " + std::to_string(GetLastError()));
|
|
|
|
CryptReleaseContext(hProv, 0);
|
|
CryptDestroyHash(hHash);
|
|
CloseHandle(hFile);
|
|
return 1;
|
|
}
|
|
|
|
cbHash = MD5LEN;
|
|
if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) {
|
|
to_hex((char *)rgbHash, lastHash);
|
|
} else {
|
|
toLog("CryptGetHashParam returned with error " +
|
|
std::to_string(GetLastError()));
|
|
}
|
|
|
|
CryptDestroyHash(hHash);
|
|
CryptReleaseContext(hProv, 0);
|
|
CloseHandle(hFile);
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
#ifdef APL
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
|
static inline int
|
|
generateMD5(const char *filepath,
|
|
char *lastHash,
|
|
const std::function<void(const std::string)> toLog)
|
|
{
|
|
int file_descript;
|
|
unsigned long file_size;
|
|
char *file_buffer;
|
|
unsigned char result[MD5LEN];
|
|
|
|
file_descript = open(filepath, O_RDONLY);
|
|
if (file_descript < 0)
|
|
return 1;
|
|
|
|
file_size = get_size_by_fd(file_descript);
|
|
|
|
file_buffer =
|
|
(char *)mmap(0, file_size, PROT_READ, MAP_SHARED, file_descript, 0);
|
|
|
|
CC_MD5_CTX context;
|
|
CC_MD5_Init(&context);
|
|
CC_MD5_Update(&context, file_buffer, (CC_LONG)file_size);
|
|
CC_MD5_Final(result, &context);
|
|
|
|
munmap(file_buffer, file_size);
|
|
close(file_descript);
|
|
|
|
to_hex((char *)result, lastHash);
|
|
return 0;
|
|
}
|
|
#pragma clang diagnostic pop
|
|
#endif
|
|
#ifdef LIN
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
|
static inline int
|
|
generateMD5(const char *filepath,
|
|
char *buffer,
|
|
const std::function<void(const std::string)> toLog)
|
|
{
|
|
int file_descriptor;
|
|
unsigned long file_size;
|
|
char *file_buffer;
|
|
unsigned char result[MD5LEN];
|
|
|
|
file_descriptor = open(filepath, O_RDONLY);
|
|
if (file_descriptor < 0)
|
|
return 1;
|
|
|
|
file_size = get_size_by_fd(file_descriptor);
|
|
if (file_size == 0)
|
|
return 1;
|
|
|
|
file_buffer = (char *)
|
|
mmap(nullptr, file_size, PROT_READ, MAP_SHARED, file_descriptor, 0);
|
|
|
|
MD5((unsigned char *)file_buffer, file_size, result);
|
|
|
|
munmap(file_buffer, file_size);
|
|
close(file_descriptor);
|
|
|
|
to_hex((char *)result, buffer);
|
|
return 0;
|
|
}
|
|
#pragma clang diagnostic pop
|
|
#endif
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wunused-parameter"
|
|
static inline void setThreadName(const std::string &name)
|
|
{
|
|
#ifdef APL
|
|
//
|
|
// Apple reserves 16 bytes for its thread names
|
|
// Notice that the Apple version of pthread_setname_np
|
|
// does not take a pthread_t argument
|
|
//
|
|
pthread_setname_np(name.substr(0, 63).c_str());
|
|
#endif
|
|
#ifdef LIN
|
|
//
|
|
// Linux only reserves 16 bytes for its thread names
|
|
// See prctl and PR_SET_NAME property in
|
|
// http://man7.org/linux/man-pages/man2/prctl.2.html
|
|
//
|
|
pthread_setname_np(pthread_self(), name.substr(0, 15).c_str());
|
|
#endif
|
|
}
|
|
#pragma clang diagnostic pop
|
|
|
|
// trim from start (in place)
|
|
static inline void ltrim(std::string &s)
|
|
{
|
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
|
return !std::isspace(ch);
|
|
}));
|
|
}
|
|
|
|
// trim from end (in place)
|
|
static inline void rtrim(std::string &s)
|
|
{
|
|
s.erase(std::find_if(s.rbegin(),
|
|
s.rend(),
|
|
[](unsigned char ch) { return !std::isspace(ch); })
|
|
.base(),
|
|
s.end());
|
|
}
|
|
|
|
static inline std::string rtrim_copy(std::string s)
|
|
{
|
|
rtrim(s);
|
|
return s;
|
|
}
|
|
|
|
// trim from both ends (in place)
|
|
static inline void trim(std::string &s)
|
|
{
|
|
ltrim(s);
|
|
rtrim(s);
|
|
}
|
|
|
|
static inline std::vector<std::string> split(const std::string &s, char delim)
|
|
{
|
|
std::vector<std::string> result;
|
|
std::stringstream ss(s);
|
|
std::string item;
|
|
|
|
while (getline(ss, item, delim)) {
|
|
result.emplace_back(item);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
} // namespace util
|
|
} // namespace germanairlinesva
|
|
|
|
#endif
|