CommonIO.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. This file is part of cpp-ethereum.
  3. cpp-ethereum is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. cpp-ethereum is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file CommonIO.cpp
  15. * @author Gav Wood <i@gavwood.com>
  16. * @date 2014
  17. */
  18. #include "CommonIO.h"
  19. #include <iostream>
  20. #include <cstdlib>
  21. #include <fstream>
  22. #include <stdio.h>
  23. #if defined(_WIN32)
  24. #include <windows.h>
  25. #else
  26. #include <termios.h>
  27. #endif
  28. #include <boost/filesystem.hpp>
  29. #include "Exceptions.h"
  30. using namespace std;
  31. using namespace dev;
  32. string dev::memDump(bytes const& _bytes, unsigned _width, bool _html)
  33. {
  34. stringstream ret;
  35. if (_html)
  36. ret << "<pre style=\"font-family: Monospace,Lucida Console,Courier,Courier New,sans-serif; font-size: small\">";
  37. for (unsigned i = 0; i < _bytes.size(); i += _width)
  38. {
  39. ret << hex << setw(4) << setfill('0') << i << " ";
  40. for (unsigned j = i; j < i + _width; ++j)
  41. if (j < _bytes.size())
  42. if (_bytes[j] >= 32 && _bytes[j] < 127)
  43. if ((char)_bytes[j] == '<' && _html)
  44. ret << "&lt;";
  45. else if ((char)_bytes[j] == '&' && _html)
  46. ret << "&amp;";
  47. else
  48. ret << (char)_bytes[j];
  49. else
  50. ret << '?';
  51. else
  52. ret << ' ';
  53. ret << " ";
  54. for (unsigned j = i; j < i + _width && j < _bytes.size(); ++j)
  55. ret << setfill('0') << setw(2) << hex << (unsigned)_bytes[j] << " ";
  56. ret << "\n";
  57. }
  58. if (_html)
  59. ret << "</pre>";
  60. return ret.str();
  61. }
  62. template <typename _T>
  63. inline _T contentsGeneric(std::string const& _file)
  64. {
  65. _T ret;
  66. size_t const c_elementSize = sizeof(typename _T::value_type);
  67. std::ifstream is(_file, std::ifstream::binary);
  68. if (!is)
  69. return ret;
  70. // get length of file:
  71. is.seekg(0, is.end);
  72. streamoff length = is.tellg();
  73. if (length == 0)
  74. return ret; // do not read empty file (MSVC does not like it)
  75. is.seekg(0, is.beg);
  76. ret.resize((length + c_elementSize - 1) / c_elementSize);
  77. is.read(const_cast<char*>(reinterpret_cast<char const*>(ret.data())), length);
  78. return ret;
  79. }
  80. bytes dev::contents(string const& _file)
  81. {
  82. return contentsGeneric<bytes>(_file);
  83. }
  84. bytesSec dev::contentsSec(string const& _file)
  85. {
  86. bytes b = contentsGeneric<bytes>(_file);
  87. bytesSec ret(b);
  88. bytesRef(&b).cleanse();
  89. return ret;
  90. }
  91. string dev::contentsString(string const& _file)
  92. {
  93. return contentsGeneric<string>(_file);
  94. }
  95. void dev::writeFile(std::string const& _file, bytesConstRef _data, bool _writeDeleteRename)
  96. {
  97. namespace fs = boost::filesystem;
  98. if (_writeDeleteRename)
  99. {
  100. fs::path tempPath = fs::unique_path(_file + "-%%%%%%");
  101. writeFile(tempPath.string(), _data, false);
  102. // will delete _file if it exists
  103. fs::rename(tempPath, _file);
  104. }
  105. else
  106. {
  107. // create directory if not existent
  108. fs::path p(_file);
  109. if (!fs::exists(p.parent_path()))
  110. {
  111. fs::create_directories(p.parent_path());
  112. DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all));
  113. }
  114. ofstream s(_file, ios::trunc | ios::binary);
  115. s.write(reinterpret_cast<char const*>(_data.data()), _data.size());
  116. if (!s)
  117. BOOST_THROW_EXCEPTION(FileError() << errinfo_comment("Could not write to file: " + _file));
  118. DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read|fs::owner_write));
  119. }
  120. }
  121. std::string dev::getPassword(std::string const& _prompt)
  122. {
  123. #if defined(_WIN32)
  124. cout << _prompt << flush;
  125. // Get current Console input flags
  126. HANDLE hStdin;
  127. DWORD fdwSaveOldMode;
  128. if ((hStdin = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)
  129. BOOST_THROW_EXCEPTION(ExternalFunctionFailure("GetStdHandle"));
  130. if (!GetConsoleMode(hStdin, &fdwSaveOldMode))
  131. BOOST_THROW_EXCEPTION(ExternalFunctionFailure("GetConsoleMode"));
  132. // Set console flags to no echo
  133. if (!SetConsoleMode(hStdin, fdwSaveOldMode & (~ENABLE_ECHO_INPUT)))
  134. BOOST_THROW_EXCEPTION(ExternalFunctionFailure("SetConsoleMode"));
  135. // Read the string
  136. std::string ret;
  137. std::getline(cin, ret);
  138. // Restore old input mode
  139. if (!SetConsoleMode(hStdin, fdwSaveOldMode))
  140. BOOST_THROW_EXCEPTION(ExternalFunctionFailure("SetConsoleMode"));
  141. return ret;
  142. #else
  143. struct termios oflags;
  144. struct termios nflags;
  145. char password[256];
  146. // disable echo in the terminal
  147. tcgetattr(fileno(stdin), &oflags);
  148. nflags = oflags;
  149. nflags.c_lflag &= ~ECHO;
  150. nflags.c_lflag |= ECHONL;
  151. if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0)
  152. BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr"));
  153. printf("%s", _prompt.c_str());
  154. if (!fgets(password, sizeof(password), stdin))
  155. BOOST_THROW_EXCEPTION(ExternalFunctionFailure("fgets"));
  156. password[strlen(password) - 1] = 0;
  157. // restore terminal
  158. if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0)
  159. BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr"));
  160. return password;
  161. #endif
  162. }