]> git.saurik.com Git - apt.git/commitdiff
Merge remote-tracking branch 'mvo/feature/build-dep-dsc2' into debian/experimental
authorMichael Vogt <mvo@debian.org>
Thu, 8 May 2014 12:29:30 +0000 (14:29 +0200)
committerMichael Vogt <mvo@debian.org>
Thu, 8 May 2014 12:29:30 +0000 (14:29 +0200)
Conflicts:
apt-pkg/deb/debindexfile.cc
apt-pkg/deb/debindexfile.h
apt-pkg/deb/debsrcrecords.cc

1  2 
apt-pkg/deb/debindexfile.cc
apt-pkg/deb/debindexfile.h
apt-pkg/deb/debmetaindex.cc
apt-pkg/deb/debsrcrecords.cc
apt-pkg/sourcelist.h
cmdline/apt-get.cc

index 86ef92bfbc681b6a9a643ea010e943aa2eb4466b,bb688412333e3a3d8866dd67901eef3146345eee..37efa05b02e09ffe5f8891a5851ee3fad26e3a94
@@@ -30,7 -30,6 +30,7 @@@
  #include <apt-pkg/pkgcachegen.h>
  #include <apt-pkg/pkgrecords.h>
  #include <apt-pkg/srcrecords.h>
 +#include <apt-pkg/sptr.h>
  
  #include <stdio.h>
  #include <iostream>
@@@ -668,97 -667,42 +668,132 @@@ APT_CONST bool debStatusIndex::Exists(
  }
                                                                        /*}}}*/
  
 +// debDebPkgFile - Single .deb file                                           /*{{{*/
 +// ---------------------------------------------------------------------
 +debDebPkgFileIndex::debDebPkgFileIndex(std::string DebFile)
 +   : pkgIndexFile(true), DebFile(DebFile)
 +{
 +   DebFileFullPath = flAbsPath(DebFile);
 +}
 +
 +std::string debDebPkgFileIndex::ArchiveURI(std::string /*File*/) const
 +{
 +   return "file:" + DebFileFullPath;
 +}
 +
 +bool debDebPkgFileIndex::Exists() const
 +{
 +   return FileExists(DebFile);
 +}
 +bool debDebPkgFileIndex::Merge(pkgCacheGenerator& Gen, OpProgress* Prog) const
 +{
 +   if(Prog)
 +      Prog->SubProgress(0, "Reading deb file");
 +
 +   // get the control data out of the deb file vid dpkg -I
 +   // ... can I haz libdpkg?
 +   const char *Args[5] = {"/usr/bin/dpkg",
 +                          "-I",
 +                          DebFile.c_str(),
 +                          "control",
 +                          NULL};
 +   FileFd PipeFd;
 +   pid_t Child;
 +   if(Popen(Args, PipeFd, Child, FileFd::ReadOnly) == false)
 +      return _error->Error("Popen failed");
 +   // FIXME: static buffer
 +   char buf[8*1024];
 +   unsigned long long n = 0;
 +   if(PipeFd.Read(buf, sizeof(buf)-1, &n) == false)
 +      return _error->Errno("read", "Failed to read dpkg pipe");
 +   ExecWait(Child, "Popen");
 +
 +   // now write the control data to a tempfile
 +   SPtr<FileFd> DebControl = GetTempFile("deb-file-" + DebFile);
 +   if(DebControl == NULL)
 +      return false;
 +   DebControl->Write(buf, n);
 +   // append size of the file
 +   FileFd Fd(DebFile, FileFd::ReadOnly);
 +   string Size;
 +   strprintf(Size, "Size: %llu\n", Fd.Size());
 +   DebControl->Write(Size.c_str(), Size.size());
 +   // and rewind for the listparser
 +   DebControl->Seek(0);
 +
 +   // and give it to the list parser
 +   debDebFileParser Parser(DebControl, DebFile);
 +   if(Gen.SelectFile(DebFile, "local", *this) == false)
 +      return _error->Error("Problem with SelectFile %s", DebFile.c_str());
 +
 +   pkgCache::PkgFileIterator File = Gen.GetCurFile();
 +   File->Size = DebControl->Size();
 +   File->mtime = DebControl->ModificationTime();
 +   
 +   if (Gen.MergeList(Parser) == false)
 +      return _error->Error("Problem with MergeLister for %s", DebFile.c_str());
 +
 +   return true;
 +}
 +pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const
 +{
 +   // FIXME: we could simply always return pkgCache::PkgFileIterator(Cache);
 +   //        to indicate its never in the cache which will force a Merge()
 +   pkgCache::PkgFileIterator File = Cache.FileBegin();
 +   for (; File.end() == false; ++File)
 +   {
 +       if (File.FileName() == NULL || DebFile != File.FileName())
 +       continue;
 +
 +       return File;
 +   }
 +   
 +   return File;
 +}
 +unsigned long debDebPkgFileIndex::Size() const
 +{
 +   struct stat buf;
 +   if(stat(DebFile.c_str(), &buf) != 0)
 +      return 0;
 +   return buf.st_size;
 +}
 +                                                                      /*}}}*/
  
+ // debDscFileIndex stuff
+ debDscFileIndex::debDscFileIndex(std::string &DscFile) 
+    : pkgIndexFile(true), DscFile(DscFile)
+ {
+ }
+ bool debDscFileIndex::Exists() const
+ {
+    return FileExists(DscFile);
+ }
+ unsigned long debDscFileIndex::Size() const
+ {
+    struct stat buf;
+    if(stat(DscFile.c_str(), &buf) == 0)
+       return buf.st_size;
+    return 0;
+ }
+ // DscFileIndex::CreateSrcParser - Get a parser for the .dsc file     /*{{{*/
+ // ---------------------------------------------------------------------
+ /* */
+ pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const
+ {
+    if (!FileExists(DscFile))
+       return NULL;
+    return new debDscRecordParser(DscFile,this);
+ }
+                                                                       /*}}}*/
+ // ---------------------------------------------------------------------
  // Index File types for Debian                                                /*{{{*/
  class debIFTypeSrc : public pkgIndexFile::Type
  {
@@@ -791,20 -735,32 +826,42 @@@ class debIFTypeStatus : public pkgIndex
     };
     debIFTypeStatus() {Label = "Debian dpkg status file";};
  };
 +class debIFTypeDebPkgFile : public pkgIndexFile::Type
 +{
 +   public:
 +   virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const 
 +   {
 +      return new debDebFileRecordParser(File.FileName(),*File.Cache());
 +   };
 +   debIFTypeDebPkgFile() {Label = "deb Package file";};
 +};
+ class debIFTypeDscFile : public pkgIndexFile::Type
+ {
+    public:
+    virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string DscFile) const
+    {
+       return new debDscRecordParser(DscFile, NULL);
+    };
+    debIFTypeDscFile() {Label = "dsc File Source Index";};
+ };
+ class debIFTypeDebianSourceDir : public pkgIndexFile::Type
+ {
+    public:
+    virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string SourceDir) const
+    {
+       return new debDscRecordParser(SourceDir + string("/debian/control"), NULL);
+    };
+    debIFTypeDebianSourceDir() {Label = "debian/control File Source Index";};
+ };
  static debIFTypeSrc _apt_Src;
  static debIFTypePkg _apt_Pkg;
  static debIFTypeTrans _apt_Trans;
  static debIFTypeStatus _apt_Status;
 +static debIFTypeDebPkgFile _apt_DebPkgFile;
+ // file based pseudo indexes
+ static debIFTypeDscFile _apt_DscFile;
+ static debIFTypeDebianSourceDir _apt_DebianSourceDir;
  
  const pkgIndexFile::Type *debSourcesIndex::GetType() const
  {
@@@ -822,8 -778,13 +879,16 @@@ const pkgIndexFile::Type *debStatusInde
  {
     return &_apt_Status;
  }
 +const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const
 +{
 +   return &_apt_DebPkgFile;
++}
+ const pkgIndexFile::Type *debDscFileIndex::GetType() const
+ {
+    return &_apt_DscFile;
+ }
+ const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const
+ {
+    return &_apt_DebianSourceDir;
  }
 -
                                                                        /*}}}*/
index 69754e79d469490a3fee43eca7dc35014ce98f03,64ca558d2d4589041c1d59b63e73621f23ecebb0..18322dc1b1b3902750f38017a63073afcc988c65
@@@ -164,35 -164,27 +164,57 @@@ class debSourcesIndex : public pkgIndex
     virtual ~debSourcesIndex() {};
  };
  
-    
 +class debDebPkgFileIndex : public pkgIndexFile
 +{
 + private:
 +   void *d;
 +   std::string DebFile;
 +   std::string DebFileFullPath;
 +
 + public:
 +   virtual const Type *GetType() const APT_CONST;
 +
 +   virtual std::string Describe(bool /*Short*/) const {
 +      return DebFile;
 +   }
 +
 +   // Interface for the Cache Generator
 +   virtual bool Exists() const;
 +   virtual bool HasPackages() const {
 +      return true;
 +   };
 +   virtual unsigned long Size() const;
 +   virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const;
 +   virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
 +
 +   // Interface for acquire
 +   virtual std::string ArchiveURI(std::string /*File*/) const;
 +
 +   debDebPkgFileIndex(std::string DebFile);
 +   virtual ~debDebPkgFileIndex() {};
++};   
++
+ class debDscFileIndex : public pkgIndexFile
+ {
+  private:
+    std::string DscFile;
+  public:
+    virtual const Type *GetType() const APT_CONST;
+    virtual pkgSrcRecords::Parser *CreateSrcParser() const;
+    virtual bool Exists() const;
+    virtual bool HasPackages() const {return false;};
+    virtual unsigned long Size() const;
+    virtual std::string Describe(bool /*Short*/) const {
+       return DscFile;
+    };
+    debDscFileIndex(std::string &DscFile);
+    virtual ~debDscFileIndex() {};
+ };
+ class debDebianSourceDirIndex : public debDscFileIndex
+ {
+    virtual const Type *GetType() const APT_CONST;
  };
  
  #endif
index 56eecdca11c201fa14efdac74557fdeead141619,6fd12add8f3589cf02fdb1fd84b596e70f7986b4..b4839ada4cfb6e2dfa37071546f6cbdbe22605b4
@@@ -471,15 -471,6 +471,15 @@@ class debSLTypeDebian : public pkgSourc
     }
  };
  
 +debDebFileMetaIndex::debDebFileMetaIndex(std::string const &DebFile)
 +   : metaIndex(DebFile, "local-uri", "deb-dist"), DebFile(DebFile)
 +{
 +   DebIndex = new debDebPkgFileIndex(DebFile);
 +   Indexes = new vector<pkgIndexFile *>();
 +   Indexes->push_back(DebIndex);
 +}
 +
 +
  class debSLTypeDeb : public debSLTypeDebian
  {
     public:
@@@ -516,25 -507,5 +516,25 @@@ class debSLTypeDebSrc : public debSLTyp
     }   
  };
  
-                  string const &Dist, string const &Section,
-                  std::map<string, string> const &Options) const
 +class debSLTypeDebFile : public pkgSourceList::Type
 +{
 +   public:
 +
 +   bool CreateItem(vector<metaIndex *> &List, string const &URI,
++                 string const &/*Dist*/, string const &/*Section*/,
++                 std::map<string, string> const &/*Options*/) const
 +   {
 +      metaIndex *mi = new debDebFileMetaIndex(URI);
 +      List.push_back(mi);
 +      return true;
 +   }
 +   
 +   debSLTypeDebFile()
 +   {
 +      Name = "deb-file";
 +      Label = "Debian Deb File";
 +   }   
 +};
  debSLTypeDeb _apt_DebType;
  debSLTypeDebSrc _apt_DebSrcType;
 +debSLTypeDebFile _apt_DebFileType;
index 615f0f57d4dbfe0c3c67b57011ec3be296f33966,8aad81e3cfd839d029f96efe0147d88e61e8e6d5..7b9a828d3fba5a5d6902748bf9b6400bfeee0c1d
@@@ -18,7 -18,7 +18,8 @@@
  #include <apt-pkg/aptconfiguration.h>
  #include <apt-pkg/srcrecords.h>
  #include <apt-pkg/tagfile.h>
 +#include <apt-pkg/hashes.h>
+ #include <apt-pkg/gpgv.h>
  
  #include <ctype.h>
  #include <stdlib.h>
@@@ -122,86 -122,64 +123,86 @@@ bool debSrcRecordParser::BuildDepends(s
  bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
  {
     List.erase(List.begin(),List.end());
 +
 +   // map from the Hashsum field to the hashsum function,
 +   // unfortunately this is not a 1:1 mapping from
 +   // Hashes::SupporedHashes as e.g. Files is a historic name for the md5
 +   const std::pair<const char*, const char*> SourceHashFields[] = {
 +      std::make_pair( "Checksums-Sha512",  "SHA512"),
 +      std::make_pair( "Checksums-Sha256",  "SHA256"),
 +      std::make_pair( "Checksums-Sha1",  "SHA1"),
 +      std::make_pair( "Files",  "MD5Sum"),      // historic Name
 +   };
     
 -   string Files = Sect.FindS("Files");
 -   if (Files.empty() == true)
 -      return false;
 -
 -   // Stash the / terminated directory prefix
 -   string Base = Sect.FindS("Directory");
 -   if (Base.empty() == false && Base[Base.length()-1] != '/')
 -      Base += '/';
 -
 -   std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions();
 -
 -   // Iterate over the entire list grabbing each triplet
 -   const char *C = Files.c_str();
 -   while (*C != 0)
 -   {   
 -      pkgSrcRecords::File F;
 -      string Size;
 -      
 -      // Parse each of the elements
 -      if (ParseQuoteWord(C,F.MD5Hash) == false ||
 -        ParseQuoteWord(C,Size) == false ||
 -        ParseQuoteWord(C,F.Path) == false)
 -       return _error->Error("Error parsing file record");
 -      
 -      // Parse the size and append the directory
 -      F.Size = atoi(Size.c_str());
 -      F.Path = Base + F.Path;
 -      
 -      // Try to guess what sort of file it is we are getting.
 -      string::size_type Pos = F.Path.length()-1;
 -      while (1)
 -      {
 -       string::size_type Tmp = F.Path.rfind('.',Pos);
 -       if (Tmp == string::npos)
 -          break;
 -       if (F.Type == "tar") {
 -          // source v3 has extension 'debian.tar.*' instead of 'diff.*'
 -          if (string(F.Path, Tmp+1, Pos-Tmp) == "debian")
 -             F.Type = "diff";
 -          break;
 -       }
 -       F.Type = string(F.Path,Tmp+1,Pos-Tmp);
 -       
 -       if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() ||
 -           F.Type == "tar")
 -       {
 -          Pos = Tmp-1;
 -          continue;
 -       }
 +   for (unsigned int i=0;
 +        i < sizeof(SourceHashFields)/sizeof(SourceHashFields[0]);
 +        i++)
 +   {
 +      string Files = Sect.FindS(SourceHashFields[i].first);
 +      if (Files.empty() == true)
 +         continue;
 +
 +      // Stash the / terminated directory prefix
 +      string Base = Sect.FindS("Directory");
 +      if (Base.empty() == false && Base[Base.length()-1] != '/')
 +         Base += '/';
 +
 +      std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions();
 +
 +      // Iterate over the entire list grabbing each triplet
 +      const char *C = Files.c_str();
 +      while (*C != 0)
 +      {   
 +         pkgSrcRecords::File F;
 +         string Size;
 +         
 +         // Parse each of the elements
 +         std::string RawHash;
 +         if (ParseQuoteWord(C, RawHash) == false ||
 +             ParseQuoteWord(C, Size) == false ||
 +             ParseQuoteWord(C, F.Path) == false)
 +            return _error->Error("Error parsing '%s' record", 
 +                                 SourceHashFields[i].first);
 +         // assign full hash string
 +         F.Hash = HashString(SourceHashFields[i].second, RawHash).toStr();
 +         // API compat hack 
 +         if(strcmp(SourceHashFields[i].second, "MD5Sum") == 0)
 +            F.MD5Hash = RawHash;
 +         
 +         // Parse the size and append the directory
 +         F.Size = atoi(Size.c_str());
 +         F.Path = Base + F.Path;
 +         
 +         // Try to guess what sort of file it is we are getting.
 +         string::size_type Pos = F.Path.length()-1;
 +         while (1)
 +         {
 +            string::size_type Tmp = F.Path.rfind('.',Pos);
 +            if (Tmp == string::npos)
 +               break;
 +            if (F.Type == "tar") {
 +               // source v3 has extension 'debian.tar.*' instead of 'diff.*'
 +               if (string(F.Path, Tmp+1, Pos-Tmp) == "debian")
 +                  F.Type = "diff";
 +               break;
 +            }
 +            F.Type = string(F.Path,Tmp+1,Pos-Tmp);
 +            
 +            if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() ||
 +                F.Type == "tar")
 +            {
 +               Pos = Tmp-1;
 +               continue;
 +            }
         
 -       break;
 -      }
 +            break;
 +         }
        
 -      List.push_back(F);
 +         List.push_back(F);
 +      }
 +      break;
     }
 -   
 -   return true;
 +   return (List.size() > 0);
  }
                                                                        /*}}}*/
  // SrcRecordParser::~SrcRecordParser - Destructor                     /*{{{*/
@@@ -212,3 -190,21 +213,21 @@@ debSrcRecordParser::~debSrcRecordParser
     delete[] Buffer;
  }
                                                                        /*}}}*/
+ debDscRecordParser::debDscRecordParser(std::string const &DscFile, pkgIndexFile const *Index)
+    : debSrcRecordParser(DscFile, Index)
+ {
+    // support clear signed files
+    if (OpenMaybeClearSignedFile(DscFile, Fd) == false)
+    {
+       _error->Error("Failed to open %s", DscFile.c_str());
+       return;
+    }
+    // re-init to ensure the updated Fd is used
+    Tags.Init(&Fd);
+    // read the first (and only) record
+    Step();
+ }
diff --combined apt-pkg/sourcelist.h
index 99e83f45469efd718ee137e4789674db8508c71a,0ebf4e0807ec7d326fe49bce377564374920d21c..261dd81613739286ecb2d2bdec625d37317c0b82
@@@ -52,15 -52,7 +52,15 @@@ class pkgAcquire
  class pkgIndexFile;
  class metaIndex;
  
 -class pkgSourceList
 +class pkgSource
 +{
 +   protected:
 +
 +   std::vector<metaIndex *> SrcList;
 +
 +};
 +
 +class pkgSourceList : public pkgSource
  {
     public:
     
@@@ -94,7 -86,7 +94,7 @@@
     
     typedef std::vector<metaIndex *>::const_iterator const_iterator;
     
-    protected:
+    public:
  
     std::vector<metaIndex *> SrcList;
  
diff --combined cmdline/apt-get.cc
index f682074a7c9ad462792419b509f757798c9f4d7f,6d6ba5ff9ccd31ecc18ac0e5c4cd718ef09d61a5..1148dbbf38bb73686f2adf5e20a7b4fe64a12e45
@@@ -828,10 -828,13 +828,10 @@@ static bool DoSource(CommandLine &CmdL
         queued.insert(Last->Index().ArchiveURI(I->Path));
  
         // check if we have a file with that md5 sum already localy
 -       if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path)))  
 +       if(!I->Hash.empty() && FileExists(flNotDir(I->Path)))  
         {
 -          FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly);
 -          MD5Summation sum;
 -          sum.AddFD(Fd.Fd(), Fd.Size());
 -          Fd.Close();
 -          if((string)sum.Result() == I->MD5Hash) 
 +            HashString hash_string = HashString(I->Hash);
 +            if(hash_string.VerifyFile(flNotDir(I->Path)))
            {
               ioprintf(c1out,_("Skipping already downloaded file '%s'\n"),
                        flNotDir(I->Path).c_str());
         }
  
         new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path),
 -                      I->MD5Hash,I->Size,
 +                      I->Hash,I->Size,
                        Last->Index().SourceInfo(*Last,*I),Src);
        }
     }
@@@ -1050,7 -1053,30 +1050,30 @@@ static bool DoBuildDep(CommandLine &Cmd
     for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
     {
        string Src;
-       pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,Cache);
+       pkgSrcRecords::Parser *Last = 0;
+       // a unpacked debian source tree
+       if (DirectoryExists(*I))
+       {
+          // FIXME: how can we make this more elegant?
+          std::string TypeName = "debian/control File Source Index";
+          pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str());
+          if(Type != NULL)
+             Last = Type->CreateSrcPkgParser(*I);
+       }
+       // if its a local file (e.g. .dsc) use this
+       else if (FileExists(*I))
+       {
+          // see if we can get a parser for this pkgIndexFile type
+          string TypeName = flExtension(*I) + " File Source Index";
+          pkgIndexFile::Type *Type = pkgIndexFile::Type::GetType(TypeName.c_str());
+          if(Type != NULL)
+             Last = Type->CreateSrcPkgParser(*I);
+       } else {
+          // normal case, search the cache for the source file
+          Last = FindSrc(*I,Recs,SrcRecs,Src,Cache);
+       }
        if (Last == 0)
         return _error->Error(_("Unable to find a source package for %s"),Src.c_str());
              
        }
        else if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only", false), StripMultiArch) == false)
            return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str());
-    
        // Also ensure that build-essential packages are present
        Configuration::Item const *Opts = _config->Tree("APT::Build-Essential");
        if (Opts) 
@@@ -1661,6 -1687,20 +1684,6 @@@ static bool ShowHelp(CommandLine &
        "pages for more information and options.\n"
        "                       This APT has Super Cow Powers.\n");
     return true;
 -}
 -                                                                      /*}}}*/
 -// SigWinch - Window size change signal handler                               /*{{{*/
 -// ---------------------------------------------------------------------
 -/* */
 -static void SigWinch(int)
 -{
 -   // Riped from GNU ls
 -#ifdef TIOCGWINSZ
 -   struct winsize ws;
 -  
 -   if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
 -      ScreenWidth = ws.ws_col - 1;
 -#endif
  }
                                                                        /*}}}*/
  int main(int argc,const char *argv[])                                 /*{{{*/
     // see if we are in simulate mode
     CheckSimulateMode(CmdL);
  
 +   // Init the signals
 +   InitSignals();
 +
     // Setup the output streams
     InitOutput();
  
 -   // Setup the signals
 -   signal(SIGPIPE,SIG_IGN);
 -   signal(SIGWINCH,SigWinch);
 -   SigWinch(0);
 -
     // Match the operation
     CmdL.DispatchArg(Cmds);