"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. For more information about "indexfile.cc" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.2.3_vs_2.2.4.

    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() {}