"Fossies" - the Fresh Open Source Software Archive

Member "apt-2.2.4/apt-pkg/indexfile.cc" (10 Jun 2021, 11738 Bytes) of package /linux/misc/apt-2.2.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // -*- mode: cpp; mode: fold -*-
    2 // Description                              /*{{{*/
    3 /* ######################################################################
    4 
    5    Index File - Abstraction for an index of archive/source file.
    6    
    7    ##################################################################### */
    8                                     /*}}}*/
    9 // Include Files                            /*{{{*/
   10 #include <config.h>
   11 
   12 #include <apt-pkg/acquire.h>
   13 #include <apt-pkg/aptconfiguration.h>
   14 #include <apt-pkg/configuration.h>
   15 #include <apt-pkg/deblistparser.h>
   16 #include <apt-pkg/error.h>
   17 #include <apt-pkg/fileutl.h>
   18 #include <apt-pkg/indexfile.h>
   19 #include <apt-pkg/macros.h>
   20 #include <apt-pkg/pkgcache.h>
   21 #include <apt-pkg/pkgcachegen.h>
   22 #include <apt-pkg/progress.h>
   23 #include <apt-pkg/srcrecords.h>
   24 #include <apt-pkg/strutl.h>
   25 
   26 #include <apt-pkg/debindexfile.h>
   27 
   28 #include <sys/stat.h>
   29 
   30 #include <clocale>
   31 #include <cstring>
   32 #include <memory>
   33 #include <string>
   34 #include <vector>
   35                                     /*}}}*/
   36 
   37 // Global list of Item supported
   38 static  pkgIndexFile::Type *ItmList[10];
   39 pkgIndexFile::Type **pkgIndexFile::Type::GlobalList = ItmList;
   40 unsigned long pkgIndexFile::Type::GlobalListLen = 0;
   41 
   42 // Type::Type - Constructor                     /*{{{*/
   43 // ---------------------------------------------------------------------
   44 /* */
   45 pkgIndexFile::Type::Type()
   46 {
   47    ItmList[GlobalListLen] = this;
   48    GlobalListLen++;
   49    Label = NULL;
   50 }
   51                                     /*}}}*/
   52 // Type::GetType - Locate the type by name              /*{{{*/
   53 // ---------------------------------------------------------------------
   54 /* */
   55 pkgIndexFile::Type *pkgIndexFile::Type::GetType(const char *Type)
   56 {
   57    for (unsigned I = 0; I != GlobalListLen; I++)
   58       if (strcmp(GlobalList[I]->Label,Type) == 0)
   59      return GlobalList[I];
   60    return 0;
   61 }
   62                                     /*}}}*/
   63 pkgIndexFile::pkgIndexFile(bool const Trusted) :            /*{{{*/
   64    d(NULL), Trusted(Trusted)
   65 {
   66 }
   67                                     /*}}}*/
   68 // IndexFile::ArchiveInfo - Stub                    /*{{{*/
   69 std::string pkgIndexFile::ArchiveInfo(pkgCache::VerIterator const &) const
   70 {
   71    return std::string();
   72 }
   73                                     /*}}}*/
   74 // IndexFile::FindInCache - Stub                    /*{{{*/
   75 pkgCache::PkgFileIterator pkgIndexFile::FindInCache(pkgCache &Cache) const
   76 {
   77    return pkgCache::PkgFileIterator(Cache);
   78 }
   79                                     /*}}}*/
   80 // IndexFile::SourceIndex - Stub                    /*{{{*/
   81 std::string pkgIndexFile::SourceInfo(pkgSrcRecords::Parser const &/*Record*/,
   82                 pkgSrcRecords::File const &/*File*/) const
   83 {
   84    return std::string();
   85 }
   86                                     /*}}}*/
   87 
   88 // IndexTarget - Constructor                        /*{{{*/
   89 IndexTarget::IndexTarget(std::string const &MetaKey, std::string const &ShortDesc,
   90       std::string const &LongDesc, std::string const &URI, bool const IsOptional,
   91       bool const KeepCompressed, std::map<std::string, std::string> const &Options) :
   92    URI(URI), Description(LongDesc), ShortDesc(ShortDesc), MetaKey(MetaKey),
   93    IsOptional(IsOptional), KeepCompressed(KeepCompressed), Options(Options)
   94 {
   95 }
   96                                     /*}}}*/
   97 std::string IndexTarget::Option(OptionKeys const EnumKey) const     /*{{{*/
   98 {
   99    std::string Key;
  100    switch (EnumKey)
  101    {
  102 #define APT_CASE(X) case X: Key = #X; break
  103       APT_CASE(SITE);
  104       APT_CASE(RELEASE);
  105       APT_CASE(COMPONENT);
  106       APT_CASE(LANGUAGE);
  107       APT_CASE(ARCHITECTURE);
  108       APT_CASE(BASE_URI);
  109       APT_CASE(REPO_URI);
  110       APT_CASE(IDENTIFIER);
  111       APT_CASE(TARGET_OF);
  112       APT_CASE(CREATED_BY);
  113       APT_CASE(FALLBACK_OF);
  114       APT_CASE(PDIFFS);
  115       APT_CASE(DEFAULTENABLED);
  116       APT_CASE(COMPRESSIONTYPES);
  117       APT_CASE(SOURCESENTRY);
  118       APT_CASE(BY_HASH);
  119       APT_CASE(KEEPCOMPRESSEDAS);
  120       APT_CASE(ALLOW_INSECURE);
  121       APT_CASE(ALLOW_WEAK);
  122       APT_CASE(ALLOW_DOWNGRADE_TO_INSECURE);
  123       APT_CASE(INRELEASE_PATH);
  124 #undef APT_CASE
  125       case FILENAME:
  126       {
  127      auto const M = Options.find("FILENAME");
  128      if (M == Options.end())
  129         return _config->FindDir("Dir::State::lists") + URItoFileName(URI);
  130      return M->second;
  131       }
  132       case EXISTING_FILENAME:
  133      std::string const filename = Option(FILENAME);
  134      std::vector<std::string> const types = VectorizeString(Option(COMPRESSIONTYPES), ' ');
  135      for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  136      {
  137         if (t->empty())
  138            continue;
  139         std::string const file = (*t == "uncompressed") ? filename : (filename + "." + *t);
  140         if (FileExists(file))
  141            return file;
  142      }
  143      return "";
  144    }
  145    std::map<std::string,std::string>::const_iterator const M = Options.find(Key);
  146    if (M == Options.end())
  147       return "";
  148    return M->second;
  149 }
  150                                     /*}}}*/
  151 bool IndexTarget::OptionBool(OptionKeys const EnumKey) const        /*{{{*/
  152 {
  153    return StringToBool(Option(EnumKey), false);
  154 }
  155                                     /*}}}*/
  156 std::string IndexTarget::Format(std::string format) const       /*{{{*/
  157 {
  158    for (std::map<std::string, std::string>::const_iterator O = Options.begin(); O != Options.end(); ++O)
  159    {
  160       format = SubstVar(format, std::string("$(") + O->first + ")", O->second);
  161    }
  162    format = SubstVar(format, "$(METAKEY)", MetaKey);
  163    format = SubstVar(format, "$(SHORTDESC)", ShortDesc);
  164    format = SubstVar(format, "$(DESCRIPTION)", Description);
  165    format = SubstVar(format, "$(URI)", URI);
  166    format = SubstVar(format, "$(FILENAME)", Option(IndexTarget::FILENAME));
  167    return format;
  168 }
  169                                     /*}}}*/
  170 
  171 pkgDebianIndexTargetFile::pkgDebianIndexTargetFile(IndexTarget const &Target, bool const Trusted) :/*{{{*/
  172    pkgDebianIndexFile(Trusted), d(NULL), Target(Target)
  173 {
  174 }
  175                                     /*}}}*/
  176 std::string pkgDebianIndexTargetFile::ArchiveURI(std::string const &File) const/*{{{*/
  177 {
  178    return Target.Option(IndexTarget::REPO_URI) + pkgAcquire::URIEncode(File);
  179 }
  180                                     /*}}}*/
  181 std::string pkgDebianIndexTargetFile::Describe(bool const Short) const  /*{{{*/
  182 {
  183    if (Short)
  184       return Target.Description;
  185    return Target.Description + " (" + IndexFileName() + ")";
  186 }
  187                                     /*}}}*/
  188 std::string pkgDebianIndexTargetFile::IndexFileName() const         /*{{{*/
  189 {
  190    std::string const s = Target.Option(IndexTarget::FILENAME);
  191    if (FileExists(s))
  192       return s;
  193 
  194    std::vector<std::string> const types = VectorizeString(Target.Option(IndexTarget::COMPRESSIONTYPES), ' ');
  195    for (std::vector<std::string>::const_iterator t = types.begin(); t != types.end(); ++t)
  196    {
  197       std::string p = s + '.' + *t;
  198       if (FileExists(p))
  199          return p;
  200    }
  201    return s;
  202 }
  203                                     /*}}}*/
  204 unsigned long pkgDebianIndexTargetFile::Size() const                /*{{{*/
  205 {
  206    unsigned long size = 0;
  207 
  208    /* we need to ignore errors here; if the lists are absent, just return 0 */
  209    _error->PushToStack();
  210 
  211    FileFd f(IndexFileName(), FileFd::ReadOnly, FileFd::Extension);
  212    if (!f.Failed())
  213       size = f.Size();
  214 
  215    if (_error->PendingError() == true)
  216        size = 0;
  217    _error->RevertToStack();
  218 
  219    return size;
  220 }
  221                                     /*}}}*/
  222 bool pkgDebianIndexTargetFile::Exists() const                   /*{{{*/
  223 {
  224    return FileExists(IndexFileName());
  225 }
  226                                     /*}}}*/
  227 std::string pkgDebianIndexTargetFile::GetArchitecture() const           /*{{{*/
  228 {
  229    return Target.Option(IndexTarget::ARCHITECTURE);
  230 }
  231                                     /*}}}*/
  232 std::string pkgDebianIndexTargetFile::GetComponent() const          /*{{{*/
  233 {
  234    return Target.Option(IndexTarget::COMPONENT);
  235 }
  236                                     /*}}}*/
  237 bool pkgDebianIndexTargetFile::OpenListFile(FileFd &Pkg, std::string const &FileName)/*{{{*/
  238 {
  239    if (Pkg.Open(FileName, FileFd::ReadOnly, FileFd::Extension) == false)
  240       return _error->Error("Problem opening %s",FileName.c_str());
  241    return true;
  242 }
  243                                     /*}}}*/
  244 std::string pkgDebianIndexTargetFile::GetProgressDescription() const
  245 {
  246    return Target.Description;
  247 }
  248 IndexTarget pkgDebianIndexTargetFile::GetIndexTarget() const
  249 {
  250    return Target;
  251 }
  252 
  253 pkgDebianIndexRealFile::pkgDebianIndexRealFile(std::string const &pFile, bool const Trusted) :/*{{{*/
  254    pkgDebianIndexFile(Trusted), d(NULL)
  255 {
  256    if (pFile.empty())
  257       ;
  258    else if (pFile == "/nonexistent/stdin")
  259       File = pFile;
  260    else
  261       File = flAbsPath(pFile);
  262 }
  263                                     /*}}}*/
  264 // IndexRealFile::Size - Return the size of the index           /*{{{*/
  265 unsigned long pkgDebianIndexRealFile::Size() const
  266 {
  267    struct stat S;
  268    if (stat(File.c_str(),&S) != 0)
  269       return 0;
  270    return S.st_size;
  271 }
  272                                     /*}}}*/
  273 bool pkgDebianIndexRealFile::Exists() const                 /*{{{*/
  274 {
  275    return FileExists(File);
  276 }
  277                                     /*}}}*/
  278 std::string pkgDebianIndexRealFile::Describe(bool const /*Short*/) const/*{{{*/
  279 {
  280    return File;
  281 }
  282                                     /*}}}*/
  283 std::string pkgDebianIndexRealFile::ArchiveURI(std::string const &/*File*/) const/*{{{*/
  284 {
  285    return "file:" + pkgAcquire::URIEncode(File);
  286 }
  287                                     /*}}}*/
  288 std::string pkgDebianIndexRealFile::IndexFileName() const           /*{{{*/
  289 {
  290    return File;
  291 }
  292                                     /*}}}*/
  293 std::string pkgDebianIndexRealFile::GetProgressDescription() const
  294 {
  295    return File;
  296 }
  297 bool pkgDebianIndexRealFile::OpenListFile(FileFd &Pkg, std::string const &FileName)/*{{{*/
  298 {
  299    if (Pkg.Open(FileName, FileFd::ReadOnly, FileFd::Extension) == false)
  300       return _error->Error("Problem opening %s",FileName.c_str());
  301    return true;
  302 }
  303                                     /*}}}*/
  304 
  305 pkgDebianIndexFile::pkgDebianIndexFile(bool const Trusted) : pkgIndexFile(Trusted)
  306 {
  307 }
  308 pkgDebianIndexFile::~pkgDebianIndexFile()
  309 {
  310 }
  311 pkgCacheListParser * pkgDebianIndexFile::CreateListParser(FileFd &Pkg)
  312 {
  313    if (Pkg.IsOpen() == false)
  314       return nullptr;
  315    _error->PushToStack();
  316    std::unique_ptr<pkgCacheListParser> Parser(new debListParser(&Pkg));
  317    bool const newError = _error->PendingError();
  318    _error->MergeWithStack();
  319    return newError ? nullptr : Parser.release();
  320 }
  321 bool pkgDebianIndexFile::Merge(pkgCacheGenerator &Gen,OpProgress * const Prog)
  322 {
  323    std::string const PackageFile = IndexFileName();
  324    FileFd Pkg;
  325    if (OpenListFile(Pkg, PackageFile) == false)
  326       return false;
  327    _error->PushToStack();
  328    std::unique_ptr<pkgCacheListParser> Parser(CreateListParser(Pkg));
  329    bool const newError = _error->PendingError();
  330    _error->MergeWithStack();
  331    if (newError == false && Parser == nullptr)
  332       return true;
  333    if (Parser == NULL)
  334       return false;
  335 
  336    if (Prog != NULL)
  337       Prog->SubProgress(0, GetProgressDescription());
  338 
  339    if (Gen.SelectFile(PackageFile, *this, GetArchitecture(), GetComponent(), GetIndexFlags()) == false)
  340       return _error->Error("Problem with SelectFile %s",PackageFile.c_str());
  341 
  342    // Store the IMS information
  343    pkgCache::PkgFileIterator File = Gen.GetCurFile();
  344    pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
  345    File->Size = Pkg.FileSize();
  346    File->mtime = Pkg.ModificationTime();
  347 
  348    if (Gen.MergeList(*Parser) == false)
  349       return _error->Error("Problem with MergeList %s",PackageFile.c_str());
  350    return true;
  351 }
  352 pkgCache::PkgFileIterator pkgDebianIndexFile::FindInCache(pkgCache &Cache) const
  353 {
  354    std::string const FileName = IndexFileName();
  355    pkgCache::PkgFileIterator File = Cache.FileBegin();
  356    for (; File.end() == false; ++File)
  357    {
  358        if (File.FileName() == NULL || FileName != File.FileName())
  359      continue;
  360 
  361       struct stat St;
  362       if (stat(File.FileName(),&St) != 0)
  363       {
  364          if (_config->FindB("Debug::pkgCacheGen", false))
  365         std::clog << "DebianIndexFile::FindInCache - stat failed on " << File.FileName() << std::endl;
  366      return pkgCache::PkgFileIterator(Cache);
  367       }
  368       if ((map_filesize_t)St.st_size != File->Size || St.st_mtime != File->mtime)
  369       {
  370          if (_config->FindB("Debug::pkgCacheGen", false))
  371         std::clog << "DebianIndexFile::FindInCache - size (" << St.st_size << " <> " << File->Size
  372             << ") or mtime (" << St.st_mtime << " <> " << File->mtime
  373             << ") doesn't match for " << File.FileName() << std::endl;
  374      return pkgCache::PkgFileIterator(Cache);
  375       }
  376       return File;
  377    }
  378 
  379    return File;
  380 }
  381 
  382 pkgIndexFile::~pkgIndexFile() {}
  383 pkgDebianIndexTargetFile::~pkgDebianIndexTargetFile() {}
  384 pkgDebianIndexRealFile::~pkgDebianIndexRealFile() {}