Aktualizr
C++ SOTA Client
utils.h
1 #ifndef UTILS_H_
2 #define UTILS_H_
3 
4 #include <glob.h>
5 #include <boost/filesystem.hpp>
6 #include <memory>
7 #include <string>
8 
9 #include <curl/curl.h>
10 #include <netinet/in.h>
11 
12 #include "json/json.h"
13 
14 struct Utils {
15  static std::string fromBase64(std::string base64_string);
16  static std::string toBase64(const std::string &tob64);
17  static std::string stripQuotes(const std::string &value);
18  static std::string addQuotes(const std::string &value);
19  static std::string extractField(const std::string &in, unsigned int field_id);
20  static Json::Value parseJSON(const std::string &json_str);
21  static Json::Value parseJSONFile(const boost::filesystem::path &filename);
22  static std::string jsonToStr(const Json::Value &json);
23  static std::string jsonToCanonicalStr(const Json::Value &json);
24  static std::string genPrettyName();
25  static std::string readFile(const boost::filesystem::path &filename, bool trim = false);
26 
27  static void writeFile(const boost::filesystem::path &filename, const char *content, size_t size);
28  static void writeFile(const boost::filesystem::path &filename, const std::string &content,
29  bool create_directories = true);
30  static void writeFile(const boost::filesystem::path &filename, const Json::Value &content,
31  bool create_directories = true);
32  static void copyDir(const boost::filesystem::path &from, const boost::filesystem::path &to);
33  static std::string readFileFromArchive(std::istream &as, const std::string &filename, bool trim = false);
34  static void writeArchive(const std::map<std::string, std::string> &entries, std::ostream &as);
35  static Json::Value getHardwareInfo();
36  static Json::Value getNetworkInfo();
37  static std::string getHostname();
38  static std::string randomUuid();
39  static sockaddr_storage ipGetSockaddr(int fd);
40  static std::string ipDisplayName(const sockaddr_storage &saddr);
41  static int ipPort(const sockaddr_storage &saddr);
42  static void clearUbootCounter();
43  static void setUbootUpgraded();
44  static int shell(const std::string &command, std::string *output, bool include_stderr = false);
45  static boost::filesystem::path absolutePath(const boost::filesystem::path &root, const boost::filesystem::path &file);
46  static void setSocketPort(sockaddr_storage *addr, in_port_t port);
47  static std::vector<boost::filesystem::path> glob(const std::string &pat);
48  static void createDirectories(const boost::filesystem::path &path, mode_t mode);
49  static std::string urlEncode(const std::string &input);
50  static CURL *curlDupHandleWrapper(CURL *curl_in, bool using_pkcs11);
51 };
52 
53 /**
54  * RAII Temporary file creation
55  */
57  public:
58  explicit TemporaryFile(const std::string &hint = "file");
59  TemporaryFile(const TemporaryFile &) = delete;
60  TemporaryFile operator=(const TemporaryFile &) = delete;
61  ~TemporaryFile();
62  void PutContents(const std::string &contents);
63  boost::filesystem::path Path() const;
64  std::string PathString() const;
65 
66  private:
67  boost::filesystem::path tmp_name_;
68 };
69 
71  public:
72  explicit TemporaryDirectory(const std::string &hint = "dir");
73  TemporaryDirectory(const TemporaryDirectory &) = delete;
74  TemporaryDirectory operator=(TemporaryDirectory &) = delete;
76  boost::filesystem::path Path() const;
77  std::string PathString() const;
78  boost::filesystem::path operator/(const boost::filesystem::path &subdir) const;
79 
80  private:
81  boost::filesystem::path tmp_name_;
82 };
83 
84 // Can represent an absolute or relative path, only readable through the
85 // `.get()` method
86 //
87 // The intent is to avoid unintentional use of the "naked" relative path by
88 // mandating a base directory for each instantiation
89 class BasedPath {
90  public:
91  BasedPath(boost::filesystem::path p) : p_(std::move(p)) {}
92 
93  boost::filesystem::path get(const boost::filesystem::path &base) const {
94  // note: BasedPath(bp.get()) == bp
95  return Utils::absolutePath(base, p_);
96  }
97 
98  bool empty() const { return p_.empty(); }
99  bool operator==(const BasedPath &b) const { return p_ == b.p_; }
100  bool operator!=(const BasedPath &b) const { return !(*this == b); }
101 
102  private:
103  boost::filesystem::path p_;
104 };
105 
106 // helper template for C (mostly openssl) data structured
107 // user should still take care about the order of destruction
108 // by instantiating StructGuard<> in a right order.
109 // BTW local variables are destructed in reverse order of instantiation
110 template <typename T>
111 using StructGuard = std::unique_ptr<T, void (*)(T *)>;
112 
113 // helper object for RAII socket management
114 struct SocketCloser {
115  void operator()(const int *ptr) const {
116  close(*ptr);
117  delete ptr;
118  }
119 };
120 
121 using SocketHandle = std::unique_ptr<int, SocketCloser>;
122 bool operator<(const sockaddr_storage &left, const sockaddr_storage &right); // required by std::map
123 
124 // wrapper for curl handles
126  public:
127  CurlEasyWrapper() {
128  handle = curl_easy_init();
129  if (handle == nullptr) {
130  throw std::runtime_error("Could not initialize curl handle");
131  }
132  }
133  ~CurlEasyWrapper() {
134  if (handle != nullptr) {
135  curl_easy_cleanup(handle);
136  }
137  }
138  CURL *get() { return handle; }
139 
140  private:
141  CURL *handle;
142 };
143 
144 template <typename... T>
145 static void curlEasySetoptWrapper(CURL *curl_handle, CURLoption option, T &&... args) {
146  const CURLcode retval = curl_easy_setopt(curl_handle, option, std::forward<T>(args)...);
147  if (retval != 0u) {
148  throw std::runtime_error(std::string("curl_easy_setopt error: ") + curl_easy_strerror(retval));
149  }
150 }
151 
152 // this is reference implementation of make_unique which is not yet included to C++11
153 namespace std_ {
154 template <class T>
155 struct _Unique_if {
156  using _Single_object = std::unique_ptr<T>;
157 };
158 
159 template <class T>
160 struct _Unique_if<T[]> {
161  using _Unknown_bound = std::unique_ptr<T[]>;
162 };
163 
164 template <class T, size_t N>
165 struct _Unique_if<T[N]> {
166  using _Known_bound = void;
167 };
168 
169 template <class T, class... Args>
170 typename _Unique_if<T>::_Single_object make_unique(Args &&... args) {
171  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
172 }
173 
174 template <class T>
175 typename _Unique_if<T>::_Unknown_bound make_unique(size_t n) {
176  using U = typename std::remove_extent<T>::type;
177  return std::unique_ptr<T>(new U[n]());
178 }
179 
180 template <class T, class... Args>
181 typename _Unique_if<T>::_Known_bound make_unique(Args &&...) = delete;
182 } // namespace std_
183 
184 #endif // UTILS_H_
Definition: utils.h:153
Definition: utils.h:14
RAII Temporary file creation.
Definition: utils.h:56