1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
|
#ifndef _CACHEMAN_H_
#define _CACHEMAN_H_
#include "config.h"
#include "meta.h"
#include "acfg.h"
#include "dirwalk.h"
#include "maintenance.h"
#include "lockable.h"
#include "csmapping.h"
#include "bgtask.h"
#include "fileitem.h"
#include <unordered_map>
#include <unordered_set>
// #define USEDUPEFILTER
namespace acng
{
class dlcon;
// XXX: specific declarations, maybe move to a namespace
class tDlJobHints;
class tFileGroups;
struct tContentKey;
static cmstring sAbortMsg("<span class=\"ERROR\">Found errors during processing, "
"aborting as requested.</span>");
static cmstring sIndex("Index");
static cmstring sslIndex("/Index");
static cmstring sfxXzBz2GzLzma[] = { ".xz", ".bz2", ".gz", ".lzma"};
static cmstring sfxXzBz2GzLzmaNone[] = { ".xz", ".bz2", ".gz", ".lzma", ""};
bool CompDebVerLessThan(cmstring &s1, cmstring s2);
extern time_t m_gMaintTimeNow;
void DelTree(const string &what);
class cacheman :
public IFileHandler,
public tSpecOpDetachable
{
public:
cacheman(const tSpecialRequest::tRunParms& parms);
virtual ~cacheman();
enum enumMetaType
: uint8_t
{
EIDX_NOTREFINDEX = 0,
EIDX_RELEASE,
EIDX_PACKAGES,
EIDX_SOURCES,
EIDX_DIFFIDX,
EIDX_ARCHLXDB,
EIDX_CYGSETUP,
EIDX_SUSEREPO,
EIDX_XMLRPMLIST,
EIDX_RFC822WITHLISTS,
EIDX_TRANSIDX, // XXX: in the old times, there were special i18n/Index files, are they gone for good now?
EIDX_MD5DILIST,
EIDX_SHA256DILIST
};
struct tIfileAttribs
{
bool vfile_ondisk:1, uptodate:1, parseignore:1, hideDlErrors:1,
forgiveDlErrors:1, alreadyparsed:1;
enumMetaType eIdxType = EIDX_NOTREFINDEX;
tIfileAttribs *bro; // point to a related descriptor, circled single-linked list
off_t space = 0;
inline tIfileAttribs() :
vfile_ondisk(false), uptodate(false),
parseignore(false), hideDlErrors(false),
forgiveDlErrors(false), alreadyparsed(false)
{
bro = this;
};
#ifdef DEBUG
inline tSS toString() const
{
return tSS() << alreadyparsed << "|"
<< forgiveDlErrors << "|"
<< hideDlErrors << "|"
<< parseignore << "|"
<< space << "|"
<< uptodate << "|"
<< vfile_ondisk;
}
#endif
};
// helpers to keep the code cleaner and more readable
const tIfileAttribs &GetFlags(cmstring &sPathRel) const;
protected:
// this is not unordered because sometimes we make use of iterator references while
// doing modification of the map
std::map<mstring,tIfileAttribs> m_metaFilesRel;
tIfileAttribs &SetFlags(cmstring &sPathRel);
// evil shortcut, might point to read-only dummy... to be used with care
tIfileAttribs &GetRWFlags(cmstring &sPathRel);
void UpdateVolatileFiles();
void _BusyDisplayLogs();
void _Usermsg(mstring m);
bool AddIFileCandidate(const mstring &sFileRel);
// NOOP, implemented here for convenience
bool ProcessOthers(const mstring &sPath, const struct stat &);
bool ProcessDirAfter(const mstring &sPath, const struct stat &);
/*!
* As the name saids, processes all index files and calls a callback
* function maintenence::_HandlePkgEntry on each entry.
*
* If a string set object is passed then a little optimization might be
* enabled internally, which avoid repeated processing of a file when another
* one with the same contents was already processed. This is only applicable
* having strict path checking disabled, though.
*
* */
void ProcessSeenIndexFiles(std::function<void(tRemoteFileInfo)> pkgHandler);
void StartDlder();
enum eDlMsgPrio
{
eMsgHideAll,
eMsgHideErrors,
eMsgShow
};
bool Download(cmstring& sFilePathRel, bool bIsVolatileFile,
eDlMsgPrio msgLevel, tFileItemPtr pForcedItem=tFileItemPtr(),
const tHttpUrl *pForcedURL=nullptr, unsigned hints=0, cmstring* sGuessedFrom = nullptr);
#define DL_HINT_GUESS_REPLACEMENT 0x1
#define DL_HINT_NOTAG 0x2
// common helper variables
bool m_bErrAbort, m_bVerbose, m_bForceDownload, m_bSkipIxUpdate = false;
bool m_bScanInternals, m_bByPath, m_bByChecksum, m_bSkipHeaderChecks;
bool m_bTruncateDamaged;
int m_nErrorCount;
enumMetaType GuessMetaTypeFromURL(const mstring &sPath);
unsigned int m_nProgIdx, m_nProgTell;
void TellCount(unsigned nCount, off_t nSize);
/**
* @param collectAllCsTypes If set, will send callbacks for all identified checksum types. In addition, will set the value of Acquire-By-Hash to the pointed boolean.
*/
bool ParseAndProcessMetaFile(std::function<void(const tRemoteFileInfo&)> output_receiver,
const mstring &sPath, enumMetaType idxType, bool byHashMode = false);
std::unordered_map<mstring,bool> m_forceKeepInTrash;
bool GetAndCheckHead(cmstring & sHeadfile, cmstring &sFilePathRel, off_t nWantedSize);
bool Inject(cmstring &fromRel, cmstring &toRel,
bool bSetIfileFlags=true, const header *pForcedHeader=nullptr, bool bTryLink=false);
void PrintStats(cmstring &title);
mstring m_processedIfile;
void ProgTell();
void AddDelCbox(cmstring &sFileRel, cmstring& reason, bool bExtraFile = false);
// add certain files to the kill bill, to be removed after the activity is done
virtual void MarkObsolete(cmstring&) {};
// for compressed map of special stuff
inline mstring AddLookupGetKey(cmstring &sFilePathRel, cmstring& errorReason)
{
unsigned id = m_pathMemory.size();
auto it = m_pathMemory.find(sFilePathRel);
if(it==m_pathMemory.end())
m_pathMemory[sFilePathRel] = {errorReason, id};
else
id = it->second.id;
char buf[30];
return mstring(buf, snprintf(buf, sizeof(buf), " name=\"kf\" value=\"%x\"", id));
}
// stuff in those directories must be managed by some top-level index files
// whitelist patterns do not apply there!
tStrSet m_managedDirs;
private:
void ExtractAllRawReleaseDataFixStrandedPatchIndex(tFileGroups& ret, const tStrDeq& releaseFilesRel);
void FilterGroupData(tFileGroups& idxGroups);
void SortAndInterconnectGroupData(tFileGroups& idxGroups);
/**
* Adjust the configuration of related paths (relative to updatePath) to prevent
* smart downloads later, how exactly depends on current execution mode.
*
* If strict path checks are used the content may also be copied over.
*/
void SyncSiblings(cmstring &srcPathRel, const tStrDeq& targets);
cacheman(const cacheman&);
cacheman& operator=(const cacheman&);
dlcon *m_pDlcon = nullptr;
cmstring& GetFirstPresentPath(const tFileGroups& groups, const tContentKey& ckey);
/*
* Analyze patch base candidate, fetch patch files as suggested by index, patch, distribute result
*/
void PatchOne(cmstring& pindexPathRel, const tStrDeq& patchBaseCandidates);
void ParseGenericRfc822File(filereader& reader, cmstring& sExtListFilter,
map<string, deque<string> >& contents);
bool ParseDebianIndexLine(tRemoteFileInfo& info, cmstring& fline);
protected:
bool CalculateBaseDirectories(cmstring& sPath, enumMetaType idxType, mstring& sBaseDir, mstring& sBasePkgDir);
bool IsDeprecatedArchFile(cmstring &sFilePathRel);
/**
* @brief Process key:val type files, handling multiline values as lists
* @param ixInflatedChecksum Pass through as struct attribute to ret callback
* @param sExtListFilter If set to non-empty, will only extract value(s) for that key
* @param byHashMode Return without calbacks if AcquireByHash is not set to yes. Not setting list filter also makes sense in this mode.
*/
bool ParseDebianRfc822Index(filereader& reader, std::function<void(const tRemoteFileInfo&)> &ret,
cmstring& sCurFilesReferenceDirRel,
cmstring& sPkgBaseDir,
enumMetaType ixType, CSTYPES csType,
cmstring& sExtListFilter,
bool byHashMode);
const tIfileAttribs attr_dummy_pure = tIfileAttribs();
tIfileAttribs attr_dummy;
/* Little helper to check existence of specific name on disk, either in cache or replacement directory, depending on what the srcPrefix defines */
virtual bool _checkSolidHashOnDisk(cmstring& hexname, const tRemoteFileInfo &entry,
cmstring& srcPrefix);
// "can return false negatives" thing
// to be implemented in subclasses
virtual bool _QuickCheckSolidFileOnDisk(cmstring& /* sFilePathRel */) { return false; }
void BuildCacheFileList();
/**
* This is supposed to restore references to files that are no longer
* downloaded by apt directly but via semi-static files identified by hash
* value in their name.
*
* Without this link, the index processing would not be able to parse the
* lists correctly and expiration would eventually "expire" good data.
*
* The code identify the original location of the index
* file by Release file analysis. */
bool FixMissingByHashLinks(std::unordered_set<std::string> &oldReleaseFiles);
/**
* If the specified (In)Release file has By-Hash enabled, look for paths that match
* the hash reference and if found, restore the data contents on the location of the
* file that the by-hash blobs originated from.
* @param releasePathRel cache-relative location of InRelease file
* @param stripPrefix Optional prefix to prepend to releasePathRel but not to referenced files
*/
bool ProcessByHashReleaseFileRestoreFiles(cmstring& releasePathRel, cmstring& stripPrefix);
// simple helper for use by others as well, and let compiler do RVO
tStrDeq GetGoodReleaseFiles();
};
}
#endif /*_CACHEMAN_H_*/
|