diff --git a/src/cpphelp.cpp b/src/cpphelp.cpp index fb56e22..ed43d33 100644 --- a/src/cpphelp.cpp +++ b/src/cpphelp.cpp @@ -1,335 +1,348 @@ /* @file cpphelp.h * @brief Common cpp helper stuff * * Copyright (C) 2018 Intevation GmbH * * This file is part of GpgOL. * * GpgOL is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * GpgOL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "cpphelp.h" #include #include #include #include #include "common_indep.h" #include #include #include #ifdef HAVE_W32_SYSTEM # include "common.h" # include #else #include "common_indep.h" #endif void release_cArray (char **carray) { if (carray) { for (int idx = 0; carray[idx]; idx++) { xfree (carray[idx]); } xfree (carray); } } void rtrim(std::string &s) { s.erase (std::find_if (s.rbegin(), s.rend(), [] (int ch) { return !std::isspace(ch); }).base(), s.end()); } void ltrim(std::string &s) { s.erase (s.begin(), std::find_if (s.begin(), s.end(), [] (int ch) { return !std::isspace(ch); })); } void trim(std::string &s) { ltrim (s); rtrim (s); } void remove_whitespace (std::string &s) { s.erase(remove_if(s.begin(), s.end(), isspace), s.end()); } void join(const std::vector& v, const char *c, std::string& s) { s.clear(); for (auto p = v.begin(); p != v.end(); ++p) { s += *p; if (p != v.end() - 1) { s += c; } } } char ** vector_to_cArray(const std::vector &vec) { char ** ret = (char**) xmalloc (sizeof (char*) * (vec.size() + 1)); for (size_t i = 0; i < vec.size(); i++) { ret[i] = xstrdup (vec[i].c_str()); } ret[vec.size()] = NULL; return ret; } std::vector cArray_to_vector(const char **cArray) { std::vector ret; if (!cArray) { return ret; } for (int i = 0; cArray[i]; i++) { ret.push_back (std::string (cArray[i])); } return ret; } bool in_de_vs_mode() { /* We cache the values only once. A change requires restart. This is because checking this is very expensive as gpgconf spawns each process to query the settings. */ static bool checked; static bool vs_mode; if (checked) { return vs_mode; } checked = true; GpgME::Error err; const auto components = GpgME::Configuration::Component::load (err); log_debug ("%s:%s: Checking for de-vs mode.", SRCNAME, __func__); if (err) { log_error ("%s:%s: Failed to get gpgconf components: %s", SRCNAME, __func__, err.asString ()); vs_mode = false; return vs_mode; } for (const auto &component: components) { if (component.name () && !strcmp (component.name (), "gpg")) { for (const auto &option: component.options ()) { if (option.name () && !strcmp (option.name (), "compliance") && option.currentValue ().stringValue () && #ifdef HAVE_W32_SYSTEM !stricmp (option.currentValue ().stringValue (), "de-vs")) #else !strcasecmp (option.currentValue ().stringValue (), "de-vs")) #endif { log_debug ("%s:%s: Detected de-vs mode", SRCNAME, __func__); vs_mode = true; return vs_mode; } } vs_mode = false; return vs_mode; } } vs_mode = false; return false; } #ifdef HAVE_W32_SYSTEM std::map get_registry_subkeys (const char *path) { HKEY theKey; std::map ret; std::string regPath = GPGOL_REGPATH; regPath += "\\"; regPath += path; if (RegOpenKeyEx (HKEY_CURRENT_USER, regPath.c_str (), 0, KEY_ENUMERATE_SUB_KEYS | KEY_READ, &theKey) != ERROR_SUCCESS) { TRACEPOINT; return ret; } DWORD values = 0, maxValueName = 0, maxValueLen = 0; DWORD err = RegQueryInfoKey (theKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &values, &maxValueName, &maxValueLen, nullptr, nullptr); if (err != ERROR_SUCCESS) { TRACEPOINT; RegCloseKey (theKey); return ret; } /* Add space for NULL */ maxValueName++; maxValueLen++; char name[maxValueName + 1]; char value[maxValueLen + 1]; for (int i = 0; i < values; i++) { DWORD nameLen = maxValueName; err = RegEnumValue (theKey, i, name, &nameLen, nullptr, nullptr, nullptr, nullptr); if (err != ERROR_SUCCESS) { TRACEPOINT; continue; } DWORD type; DWORD valueLen = maxValueLen; err = RegQueryValueEx (theKey, name, NULL, &type, (BYTE*)value, &valueLen); if (err != ERROR_SUCCESS) { TRACEPOINT; continue; } if (type != REG_SZ) { TRACEPOINT; continue; } ret.insert (std::make_pair (std::string (name, nameLen), std::string (value, valueLen))); } RegCloseKey (theKey); return ret; } #endif template void internal_split (const std::string &s, char delim, Out result) { std::stringstream ss(s); std::string item; while (std::getline (ss, item, delim)) { *(result++) = item; } } std::vector gpgol_split (const std::string &s, char delim) { std::vector elems; internal_split (s, delim, std::back_inserter (elems)); return elems; } std::string string_to_hex(const std::string& input) { static const char* const lut = "0123456789ABCDEF"; size_t len = input.length(); std::string output; output.reserve (3 * len + (len * 3 / 26)); for (size_t i = 0; i < len; ++i) { const unsigned char c = input[i]; output.push_back (lut[c >> 4]); output.push_back (lut[c & 15]); output.push_back (' '); if (i % 26 == 0) { output.push_back ('\n'); } } return output; } bool is_binary (const std::string &input) { for (int i = 0; i < input.size() - 1; ++i) { const unsigned char c = input[i]; if (c < 32 && c != 0x0d && c != 0x0a) { return true; } } return false; } const char * to_cstr (const GpgME::Protocol &prot) { return prot == GpgME::CMS ? "S/MIME" : prot == GpgME::OpenPGP ? "OpenPGP" : "Unknown Protocol"; } + +void +find_and_replace(std::string& source, const std::string &find, + const std::string &replace) +{ + TSTART; + for(std::string::size_type i = 0; (i = source.find(find, i)) != std::string::npos;) + { + source.replace(i, find.length(), replace); + i += replace.length(); + } + TRETURN; +} diff --git a/src/cpphelp.h b/src/cpphelp.h index 9167f29..3710ea7 100644 --- a/src/cpphelp.h +++ b/src/cpphelp.h @@ -1,67 +1,71 @@ #ifndef CPPHELP_H #define CPPHELP_H /* @file cpphelp.h * @brief Common cpp helper stuff * * Copyright (C) 2018 Intevation GmbH * * This file is part of GpgOL. * * GpgOL is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * GpgOL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . */ #include #include #include #include /* Stuff that should be in common but is c++ so it does not fit in there. */ /* Release a null terminated char* array */ void release_cArray (char **carray); /* Trim whitespace from a string. */ void rtrim (std::string &s); void ltrim (std::string &s); void trim (std::string &s); void remove_whitespace (std::string &s); /* Join a string vector */ void join(const std::vector& v, const char *c, std::string& s); /* Convert a string vector to a null terminated char array */ char **vector_to_cArray (const std::vector &vec); std::vector cArray_to_vector (const char **cArray); /* Check if we are in de_vs mode. */ bool in_de_vs_mode (); #ifdef HAVE_W32_SYSTEM /* Get a map of all subkey value pairs in a registry key */ std::map get_registry_subkeys (const char *path); #endif std::vector gpgol_split (const std::string &s, char delim); /* Convert a string to a hex representation */ std::string string_to_hex (const std::string& input); /* Check if a string contains a char < 32 */ bool is_binary (const std::string &input); /* Return a string repr of the GpgME Protocol */ const char *to_cstr (const GpgME::Protocol &prot); + +/* Modify source and find and replace stuff */ +void find_and_replace(std::string& source, const std::string &find, + const std::string &replace); #endif // CPPHELP_H