]> git.saurik.com Git - apt.git/blobdiff - cmdline/apt-get.cc
fix apt-get download truncation (closes: #736962)
[apt.git] / cmdline / apt-get.cc
index 5f04135d267b1511d34b89ce9d69e1766bd45e3d..6bff6e7de5963d6097e976c2250f2a68b08aefb1 100644 (file)
@@ -135,16 +135,13 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache,
 }
                                                                        /*}}}*/
 
-// FIXME: move into more generic code (metaindex ?)
+
+// helper that can go wit hthe next ABI break
 #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13)
-std::string MetaIndexFileName(metaIndex *metaindex)
+std::string MetaIndexFileNameOnDisk(metaIndex *metaindex)
 {
    // FIXME: this cast is the horror, the horror
    debReleaseIndex *r = (debReleaseIndex*)metaindex;
-#else
-std::string MetaIndexFileName(metaIndex *r)
-{
-#endif
 
    // see if we have a InRelease file
    std::string PathInRelease =  r->MetaIndexFile("InRelease");
@@ -152,14 +149,22 @@ std::string MetaIndexFileName(metaIndex *r)
       return PathInRelease;
 
    // and if not return the normal one
-   return r->MetaIndexFile("Release");
+   if (FileExists(PathInRelease))
+      return r->MetaIndexFile("Release");
+
+   return "";
 }
+#endif
 
+// GetReleaseForSourceRecord - Return Suite for the given srcrecord    /*{{{*/
+// ---------------------------------------------------------------------
+/* */
 std::string GetReleaseForSourceRecord(pkgSourceList *SrcList,
                                       pkgSrcRecords::Parser *Parse)
 {
    // try to find release
-   const pkgIndexFile& SI = Parse->Index();
+   const pkgIndexFile& CurrentIndexFile = Parse->Index();
+
    for (pkgSourceList::const_iterator S = SrcList->begin(); 
         S != SrcList->end(); ++S)
    {
@@ -167,19 +172,25 @@ std::string GetReleaseForSourceRecord(pkgSourceList *SrcList,
       for (vector<pkgIndexFile *>::const_iterator IF = Indexes->begin();
            IF != Indexes->end(); ++IF)
       {
-         if (&SI == (*IF))
+         if (&CurrentIndexFile == (*IF))
          {
-            std::string path = MetaIndexFileName(*S);
-            indexRecords records;
-            records.Load(path);
-            return records.GetSuite();
+#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13)
+            std::string path = MetaIndexFileNameOnDisk(*S);
+#else
+            std::string path = (*S)->LocalFileName();
+#endif
+            if (path != "") 
+            {
+               indexRecords records;
+               records.Load(path);
+               return records.GetSuite();
+            }
          }
       }
    }
    return "";
 }
-
-
+                                                                       /*}}}*/
 // FindSrc - Find a source record                                      /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -187,18 +198,31 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
                               pkgSrcRecords &SrcRecs,string &Src,
                               CacheFile &CacheFile)
 {
-   string VerTag;
+   string VerTag, UserRequestedVerTag;
+   string ArchTag = "";
    string RelTag = _config->Find("APT::Default-Release");
    string TmpSrc = Name;
    pkgDepCache *Cache = CacheFile.GetDepCache();
 
-   // extract the version/release from the pkgname
-   const size_t found = TmpSrc.find_last_of("/=");
-   if (found != string::npos) {
-      if (TmpSrc[found] == '/')
-        RelTag = TmpSrc.substr(found+1);
-      else
-        VerTag = TmpSrc.substr(found+1);
+   // extract release
+   size_t found = TmpSrc.find_last_of("/");
+   if (found != string::npos) 
+   {
+      RelTag = TmpSrc.substr(found+1);
+      TmpSrc = TmpSrc.substr(0,found);
+   }
+   // extract the version
+   found = TmpSrc.find_last_of("=");
+   if (found != string::npos) 
+   {
+      VerTag = UserRequestedVerTag = TmpSrc.substr(found+1);
+      TmpSrc = TmpSrc.substr(0,found);
+   }
+   // extract arch 
+   found = TmpSrc.find_last_of(":");
+   if (found != string::npos) 
+   {
+      ArchTag = TmpSrc.substr(found+1);
       TmpSrc = TmpSrc.substr(0,found);
    }
 
@@ -206,10 +230,25 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
       install a version and determine the source package name, then look
       in the archive for a source package of the same name. */
    bool MatchSrcOnly = _config->FindB("APT::Get::Only-Source");
-   const pkgCache::PkgIterator Pkg = Cache->FindPkg(TmpSrc);
+   pkgCache::PkgIterator Pkg;
+   if (ArchTag != "")
+      Pkg = Cache->FindPkg(TmpSrc, ArchTag);
+   else
+      Pkg = Cache->FindPkg(TmpSrc);
+
+   // if we can't find a package but the user qualified with a arch,
+   // error out here
+   if (Pkg.end() && ArchTag != "")
+   {
+      Src = Name;
+      _error->Error(_("Can not find a package for architecture '%s'"),
+                    ArchTag.c_str());
+      return 0;
+   }
+
    if (MatchSrcOnly == false && Pkg.end() == false) 
    {
-      if(VerTag.empty() == false || RelTag.empty() == false) 
+      if(VerTag != "" || RelTag != "" || ArchTag != "")
       {
         bool fuzzy = false;
         // we have a default release, try to locate the pkg. we do it like
@@ -229,6 +268,17 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
               if (Ver.end() == true)
                  break;
            }
+
+            // ignore arches that are not for us
+            if (ArchTag != "" && Ver.Arch() != ArchTag)
+               continue;
+
+            // pick highest version for the arch unless the user wants
+            // something else
+            if (ArchTag != "" && VerTag == "" && RelTag == "")
+               if(Cache->VS().CmpVersion(VerTag, Ver.VerStr()) < 0)
+                  VerTag = Ver.VerStr();
+
            // We match against a concrete version (or a part of this version)
            if (VerTag.empty() == false &&
                (fuzzy == true || Cache->VS().CmpVersion(VerTag, Ver.VerStr()) != 0) && // exact match
@@ -269,6 +319,20 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
               break;
         }
       }
+
+      if (Src == "" && ArchTag != "")
+      {
+         if (VerTag != "")
+            _error->Error(_("Can not find a package '%s' with version '%s'"),
+                          Pkg.FullName().c_str(), VerTag.c_str());
+         if (RelTag != "")
+            _error->Error(_("Can not find a package '%s' with release '%s'"),
+                          Pkg.FullName().c_str(), RelTag.c_str());
+         Src = Name;
+         return 0;
+      }
+
+
       if (Src.empty() == true)
       {
         // if we don't have found a fitting package yet so we will
@@ -320,17 +384,15 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
         const string Ver = Parse->Version();
 
          // See if we need to look for a specific release tag
-         if (RelTag != "")
+         if (RelTag != "" && UserRequestedVerTag == "")
          {
             const string Rel = GetReleaseForSourceRecord(SrcList, Parse);
 
             if (Rel == RelTag)
             {
-               ioprintf(c1out, "Selectied version '%s' (%s) for %s\n", 
-                        Ver.c_str(), RelTag.c_str(), Src.c_str());
                Last = Parse;
                Offset = Parse->Offset();
-               break;
+               Version = Ver;
             }
          }
 
@@ -351,9 +413,13 @@ pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs,
          if (VerTag.empty() == false && (VerTag == Ver))
            break;
       }
+      if (UserRequestedVerTag == "" && Version != "" && RelTag != "")
+         ioprintf(c1out, "Selected version '%s' (%s) for %s\n", 
+                  Version.c_str(), RelTag.c_str(), Src.c_str());
+
       if (Last != 0 || VerTag.empty() == true)
         break;
-      _error->Error(_("Ignore unavailable version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str());
+      _error->Error(_("Can not find version '%s' of package '%s'"), VerTag.c_str(), TmpSrc.c_str());
       return 0;
    }
 
@@ -612,14 +678,17 @@ bool DoDownload(CommandLine &CmdL)
 
    // copy files in local sources to the current directory
    for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); ++I)
-      if ((*I)->Local == true && (*I)->Status == pkgAcquire::Item::StatDone)
+   {
+      std::string const filename = cwd + flNotDir((*I)->DestFile);
+      if ((*I)->Local == true &&
+          filename != (*I)->DestFile &&
+          (*I)->Status == pkgAcquire::Item::StatDone)
       {
-        std::string const filename = cwd + flNotDir((*I)->DestFile);
         std::ifstream src((*I)->DestFile.c_str(), std::ios::binary);
         std::ofstream dst(filename.c_str(), std::ios::binary);
         dst << src.rdbuf();
       }
-
+   }
    return Failed == false;
 }
                                                                        /*}}}*/
@@ -1470,14 +1539,12 @@ bool DoChangelog(CommandLine &CmdL)
    bool const downOnly = _config->FindB("APT::Get::Download-Only", false);
 
    char tmpname[100];
-   char* tmpdir = NULL;
+   const char* tmpdir = NULL;
    if (downOnly == false)
    {
-      const char* const tmpDir = getenv("TMPDIR");
-      if (tmpDir != NULL && *tmpDir != '\0')
-        snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", tmpDir);
-      else
-        strncpy(tmpname, "/tmp/apt-changelog-XXXXXX", sizeof(tmpname));
+      std::string systemTemp = GetTempDir();
+      snprintf(tmpname, sizeof(tmpname), "%s/apt-changelog-XXXXXX", 
+               systemTemp.c_str());
       tmpdir = mkdtemp(tmpname);
       if (tmpdir == NULL)
         return _error->Errno("mkdtemp", "mkdtemp failed");
@@ -1613,14 +1680,6 @@ void SigWinch(int)
    if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5)
       ScreenWidth = ws.ws_col - 1;
 #endif
-}
-                                                                       /*}}}*/
-bool DoUpgrade(CommandLine &CmdL)                                      /*{{{*/
-{
-   if (_config->FindB("APT::Get::Upgrade-Allow-New", false) == true)
-      return DoUpgradeWithAllowNewPackages(CmdL);
-   else
-      return DoUpgradeNoNewPackages(CmdL);
 }
                                                                        /*}}}*/
 int main(int argc,const char *argv[])                                  /*{{{*/