1 /* 2 * Copyright (C) 2019 Red Hat, Inc. 3 * 4 * Licensed under the GNU Lesser General Public License Version 2.1 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef _LIBDNF_REPO_PRIVATE_HPP 22 #define _LIBDNF_REPO_PRIVATE_HPP 23 24 #include "Repo.hpp" 25 #include "../dnf-utils.h" 26 #include "../hy-iutil.h" 27 #include "../hy-util-private.hpp" 28 #include "../hy-types.h" 29 30 #include <utils.hpp> 31 32 #include <librepo/librepo.h> 33 #include <stdlib.h> 34 #include <sys/stat.h> 35 #include <sys/types.h> 36 #include <unistd.h> 37 38 #include <gpgme.h> 39 40 #include <solv/chksum.h> 41 #include <solv/repo.h> 42 #include <solv/util.h> 43 44 #include <cctype> 45 #include <map> 46 #include <mutex> 47 #include <set> 48 49 #include <string.h> 50 #include <time.h> 51 52 #define MD_TYPE_PRIMARY "primary" 53 #define MD_TYPE_FILELISTS "filelists" 54 #define MD_TYPE_PRESTODELTA "prestodelta" 55 #define MD_TYPE_GROUP_GZ "group_gz" 56 #define MD_TYPE_GROUP "group" 57 #define MD_TYPE_UPDATEINFO "updateinfo" 58 #define MD_TYPE_MODULES "modules" 59 /* "other" in this context is not a generic "any other metadata", but real metadata type named "other" 60 * containing changelogs for packages */ 61 #define MD_TYPE_OTHER "other" 62 63 enum _hy_repo_state { 64 _HY_NEW, 65 _HY_LOADED_FETCH, 66 _HY_LOADED_CACHE, 67 _HY_WRITTEN 68 }; 69 70 namespace std { 71 72 template<> 73 struct default_delete<LrHandle> { operator ()std::default_delete74 void operator()(LrHandle * ptr) noexcept { lr_handle_free(ptr); } 75 }; 76 77 } // namespace std 78 79 namespace libdnf { 80 81 typedef ::Repo LibsolvRepo; 82 83 class Key { 84 public: Key(gpgme_key_t key,gpgme_subkey_t subkey)85 Key(gpgme_key_t key, gpgme_subkey_t subkey) 86 { 87 id = subkey->keyid; 88 fingerprint = subkey->fpr; 89 timestamp = subkey->timestamp; 90 userid = key->uids->uid; 91 } 92 getId() const93 std::string getId() const { return id; } getUserId() const94 std::string getUserId() const { return userid; } getFingerprint() const95 std::string getFingerprint() const { return fingerprint; } getTimestamp() const96 long int getTimestamp() const { return timestamp; } 97 98 std::vector<char> rawKey; 99 std::string url; 100 101 private: 102 std::string id; 103 std::string fingerprint; 104 std::string userid; 105 long int timestamp; 106 }; 107 108 class Repo::Impl { 109 public: 110 Impl(Repo & owner, const std::string & id, Type type, std::unique_ptr<ConfigRepo> && conf); 111 ~Impl(); 112 113 bool load(); 114 bool loadCache(bool throwExcept, bool ignoreMissing=false); 115 void downloadMetadata(const std::string & destdir); 116 bool isInSync(); 117 void fetch(const std::string & destdir, std::unique_ptr<LrHandle> && h); 118 std::string getCachedir() const; 119 std::string getPersistdir() const; 120 int getAge() const; 121 void expire(); 122 bool isExpired() const; 123 int getExpiresIn() const; 124 void downloadUrl(const char * url, int fd); 125 void addCountmeFlag(LrHandle *handle); 126 void setHttpHeaders(const char * headers[]); 127 const char * const * getHttpHeaders() const; 128 const std::string & getMetadataPath(const std::string &metadataType) const; 129 130 std::unique_ptr<LrHandle> lrHandleInitBase(); 131 std::unique_ptr<LrHandle> lrHandleInitLocal(); 132 std::unique_ptr<LrHandle> lrHandleInitRemote(const char *destdir); 133 134 void attachLibsolvRepo(LibsolvRepo * libsolvRepo); 135 void detachLibsolvRepo(); 136 137 // Converts configuration string of proxy authorization methods to librepo enum. 138 static LrAuth stringToProxyAuthMethods(const std::string & proxy_auth_method) noexcept; 139 140 std::string id; 141 Type type; 142 std::unique_ptr<ConfigRepo> conf; 143 144 char ** mirrors{nullptr}; 145 int maxMirrorTries{0}; // try them all 146 // 0 forces expiration on the next call to load(), -1 means undefined value 147 int timestamp; 148 int maxTimestamp{0}; 149 bool preserveRemoteTime{false}; 150 bool fresh{false}; 151 std::string repomdFn; 152 std::set<std::string> additionalMetadata; 153 std::string revision; 154 std::vector<std::string> content_tags; 155 std::vector<std::pair<std::string, std::string>> distro_tags; 156 std::vector<std::pair<std::string, std::string>> metadata_locations; 157 unsigned char checksum[CHKSUM_BYTES]; 158 bool useIncludes{false}; 159 bool loadMetadataOther; 160 std::map<std::string, std::string> substitutions; 161 162 std::unique_ptr<RepoCB> callbacks; 163 std::string repoFilePath; 164 LrHandle * getCachedHandle(); 165 166 SyncStrategy syncStrategy; 167 std::map<std::string, std::string> metadataPaths; 168 169 LibsolvRepo * libsolvRepo{nullptr}; 170 bool needs_internalizing{false}; 171 int nrefs{1}; 172 173 enum _hy_repo_state state_main{_HY_NEW}; 174 enum _hy_repo_state state_filelists{_HY_NEW}; 175 enum _hy_repo_state state_presto{_HY_NEW}; 176 enum _hy_repo_state state_updateinfo{_HY_NEW}; 177 enum _hy_repo_state state_other{_HY_NEW}; 178 Id filenames_repodata{0}; 179 Id presto_repodata{0}; 180 Id updateinfo_repodata{0}; 181 Id other_repodata{0}; 182 int load_flags{0}; 183 /* the following three elements are needed for repo rewriting */ 184 int main_nsolvables{0}; 185 int main_nrepodata{0}; 186 int main_end{0}; 187 188 // Lock attachLibsolvRepo(), detachLibsolvRepo() and hy_repo_free() to ensure atomic behavior 189 // in threaded environment such as PackageKit. 190 std::mutex attachLibsolvMutex; 191 192 private: 193 Repo * owner; 194 std::unique_ptr<LrResult> lrHandlePerform(LrHandle * handle, const std::string & destDirectory, 195 bool setGPGHomeDir); 196 bool isMetalinkInSync(); 197 bool isRepomdInSync(); 198 void resetMetadataExpired(); 199 std::vector<Key> retrieve(const std::string & url); 200 void importRepoKeys(); 201 202 static int progressCB(void * data, double totalToDownload, double downloaded); 203 static void fastestMirrorCB(void * data, LrFastestMirrorStages stage, void *ptr); 204 static int mirrorFailureCB(void * data, const char * msg, const char * url, const char * metadata); 205 206 bool expired; 207 std::unique_ptr<LrHandle> handle; 208 std::unique_ptr<char*[], std::function<void(char **)>> httpHeaders{nullptr, [](char ** ptr) __anon714b6b6f0102(char ** ptr) 209 { 210 for (auto item = ptr; *item; ++item) 211 delete[] *item; 212 delete[] ptr; 213 }}; 214 bool endsWith(std::string const &str, std::string const &ending) const; 215 std::string getHash() const; 216 }; 217 218 } 219 220 #endif 221