Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37531040
en ru br
Репозитории ALT
S:0.5.15lorg2-alt86
5.1: 0.5.15lorg2-alt33.M50P.1
4.1: 0.5.15lorg2-alt20.M41.1
4.0: 0.5.15lorg2-alt18.M40.1
+updates:0.5.15lorg2-alt18
3.0: 0.5.15cnc6-alt16
www.altlinux.org/Changes

Группа :: Система/Настройка/Пакеты
Пакет: apt

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: apt-0.5.15lorg2-alt44.patch
Скачать


 apt-pkg/Makefile.am          |   2 +-
 apt-pkg/acquire-item.cc      |  13 +++-
 apt-pkg/contrib/fileutl.cc   |   4 +-
 apt-pkg/deb/debrecords.cc    |   8 +++
 apt-pkg/deb/debrecords.h     |   1 +
 apt-pkg/deb/debsrcrecords.h  |   1 +
 apt-pkg/depcache.cc          | 138 ++++++++++++++++++++++++++++++++++++-------
 apt-pkg/depcache.h           |  15 +++++
 apt-pkg/luaiface.cc          |  14 +++++
 apt-pkg/luaiface.h           |  12 +++-
 apt-pkg/pkgcache.cc          | 100 +++++++++++++++++--------------
 apt-pkg/pkgcache.h           |  34 ++++++-----
 apt-pkg/pkgrecords.h         |   1 +
 apt-pkg/rpm/rpmpm.cc         |  63 +++++++++++---------
 apt-pkg/rpm/rpmrecords.cc    |  51 +++++++++++++---
 apt-pkg/rpm/rpmrecords.h     |   1 +
 apt-pkg/rpm/rpmsrcrecords.cc |  64 +++++++++++++++-----
 apt-pkg/rpm/rpmsrcrecords.h  |  11 ++--
 apt-pkg/rpm/rpmversion.cc    |   9 +++
 apt-pkg/srcrecords.h         |   1 +
 buildlib/tools.m4            |   8 ++-
 cmdline/apt-cache.cc         |   4 +-
 cmdline/apt-get.cc           |  24 +++++---
 cmdline/apt-shell.cc         |  25 ++++----
 po/ru.po                     |   9 ++-
 25 files changed, 444 insertions(+), 169 deletions(-)
diff --git a/apt-pkg/Makefile.am b/apt-pkg/Makefile.am
index ebf0398..b307eb6 100644
--- a/apt-pkg/Makefile.am
+++ b/apt-pkg/Makefile.am
@@ -2,7 +2,7 @@
 lib_LTLIBRARIES = libapt-pkg.la
 
 libapt_pkg_la_LIBADD = @RPMLIBS@
-libapt_pkg_la_LDFLAGS = -version-info 2:0:0 -release @GLIBC_VER@-@LIBSTDCPP_VER@
+libapt_pkg_la_LDFLAGS = -version-info 4:0:1 -release @GLIBC_VER@-@LIBSTDCPP_VER@
 
 AM_CPPFLAGS = -DLIBDIR=\"$(libdir)\"
 
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 15ea22d..9701947 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -191,7 +191,7 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,pkgRepository *Repository,
 
    // Create the item
    // CNC:2002-07-03
-   Desc.URI = URI + _config->Find("Acquire::ComprExtension", ".bz2");
+   Desc.URI = URI + ".bz2";
    Desc.Description = URIDesc;
    Desc.Owner = this;
    Desc.ShortDesc = ShortDesc;
@@ -227,6 +227,9 @@ pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,pkgRepository *Repository,
 	    unlink(FinalFile.c_str());
 	    unlink(DestFile.c_str());
 	 }
+
+	 if (Repository->FindChecksums(RealURI + ".xz", Size, MD5Hash) == true)
+	    Desc.URI = URI + ".xz";
       }
       else if (Repository->IsAuthenticated() == true)
       {
@@ -360,11 +363,15 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
    
    Decompression = true;
    DestFile += ".decomp";
+
    // CNC:2002-07-03
-   Desc.URI = "bzip2:" + FileName;
+   const char *prog = "bzip2";
+   if (flExtension(Desc.URI) == "xz")
+      prog = "xz";
+   Desc.URI = string(prog) + ":" + FileName;
    QueueURI(Desc);
    // CNC:2002-07-03
-   Mode = "bzip2";
+   Mode = prog;
 }
 									/*}}}*/
 
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 400ac67..0974e49 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -169,14 +169,14 @@ string flNotFile(string File)
    return string(File,0,Res);
 }
 									/*}}}*/
-// flExtension - Return the extension for the file			/*{{{*/
+// flExtension - Return the extension for the file or "" if none	/*{{{*/
 // ---------------------------------------------------------------------
 /* */
 string flExtension(string File)
 {
    string::size_type Res = File.rfind('.');
    if (Res == string::npos)
-      return File;
+      return string();
    Res++;
    return string(File,Res,Res - File.length());
 }
diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc
index aa6253a..7b31626 100644
--- a/apt-pkg/deb/debrecords.cc
+++ b/apt-pkg/deb/debrecords.cc
@@ -92,6 +92,14 @@ string debRecordParser::LongDesc()
    return Section.FindS("Description");
 }
 									/*}}}*/
+// RecordParser::Changelog - Return package changelog if any		/*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string debRecordParser::Changelog()
+{
+   return string("");
+}
+									/*}}}*/
 // RecordParser::SourcePkg - Return the source package name if any	/*{{{*/
 // ---------------------------------------------------------------------
 /* */
diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h
index 8760c38..a71e9bd 100644
--- a/apt-pkg/deb/debrecords.h
+++ b/apt-pkg/deb/debrecords.h
@@ -44,6 +44,7 @@ class debRecordParser : public pkgRecords::Parser
    virtual string ShortDesc();
    virtual string LongDesc();
    virtual string Name();
+   virtual string Changelog();
 
    virtual void GetRec(const char *&Start,const char *&Stop);
    
diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h
index ff14045..18a9339 100644
--- a/apt-pkg/deb/debsrcrecords.h
+++ b/apt-pkg/deb/debsrcrecords.h
@@ -38,6 +38,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser
    virtual string Version() const {return Sect.FindS("Version");};
    virtual string Maintainer() const {return Sect.FindS("Maintainer");};
    virtual string Section() const {return Sect.FindS("Section");};
+   virtual string Changelog() const {return string("");};
    virtual const char **Binaries();
    virtual bool BuildDepends(vector<BuildDepRec> &BuildDeps, bool ArchOnly);
    virtual unsigned long Offset() {return iOffset;};
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index de8243f..b53049d 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -17,6 +17,9 @@
 #include <apt-pkg/sptr.h>
 #include <apt-pkg/algorithms.h>
 
+// for Debug::pkgMarkInstall
+#include <apt-pkg/configuration.h>
+
 // CNC:2002-07-05
 #include <apt-pkg/pkgsystem.h>
 
@@ -25,6 +28,8 @@
 #include <apt-pkg/luaiface.h>
     
 #include <apti18n.h>    
+
+#include <cstdio>
 									/*}}}*/
 
 // DepCache::pkgDepCache - Constructors					/*{{{*/
@@ -212,6 +217,18 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
    PkgIterator Dep_ParentPkg = Dep.ParentPkg();
    pkgVersioningSystem &VS = this->VS();
 
+   static const char *lastV;
+   static const pkgCache::Dependency *lastD;
+   static bool lastRet;
+#define VS_CheckDep(V, D) \
+   ({ \
+      if (!(lastV == V && lastD == D)) { \
+	 lastV = V; lastD = D; \
+	 lastRet = VS.CheckDep(V, D); \
+      } \
+      lastRet; \
+   })
+
    /* Check simple depends. A depends -should- never self match but 
       we allow it anyhow because dpkg does. Technically it is a packaging
       bug. Conflicts may never self match */
@@ -228,20 +245,20 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
 	       // CNC:2002-07-10 - RPM must check the dependency type to
 	       //		   properly define if it would be satisfied
 	       //		   or not.
-	       if (VS.CheckDep(Pkg.CurrentVer().VerStr(),Dep) == true)
+	       if (VS_CheckDep(Pkg.CurrentVer().VerStr(),Dep) == true)
 		  return true;
 	    break;
 
 	 case InstallVersion:
 	    if (PkgState[Pkg->ID].InstallVer != 0)
-	       if (VS.CheckDep(PkgState[Pkg->ID].InstVerIter(*this).VerStr(),
+	       if (VS_CheckDep(PkgState[Pkg->ID].InstVerIter(*this).VerStr(),
 				       Dep) == true)
 		  return true;
 	    break;
       
 	 case CandidateVersion:
 	    if (PkgState[Pkg->ID].CandidateVer != 0)
-	       if (VS.CheckDep(PkgState[Pkg->ID].CandidateVerIter(*this).VerStr(),
+	       if (VS_CheckDep(PkgState[Pkg->ID].CandidateVerIter(*this).VerStr(),
 				       Dep) == true)
 		  return true;
 	    break;
@@ -291,7 +308,7 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res)
       }
       
       // Compare the versions.
-      if (VS.CheckDep(P.ProvideVersion(),Dep) == true) // CNC:2002-07-10
+      if (VS_CheckDep(P.ProvideVersion(),Dep) == true) // CNC:2002-07-10
       {
 	 Res = P_OwnerPkg;
 	 return true;
@@ -737,15 +754,10 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge)
 // DepCache::MarkInstall - Put the package in the install state		/*{{{*/
 // ---------------------------------------------------------------------
 /* */
-void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
-			      unsigned long Depth)
+int pkgDepCache::MarkInstall0(PkgIterator const &Pkg)
 {
-   if (Depth > 100)
-      return;
-   
-   // Simplifies other routines.
    if (Pkg.end() == true)
-      return;
+      return -1;
    
    /* Check that it is not already marked for install and that it can be 
       installed */
@@ -756,16 +768,16 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    {
       if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0)
 	 MarkKeep(Pkg);
-      return;
+      return 0;
    }
 
    // See if there is even any possible instalation candidate
    if (P.CandidateVer == 0)
-      return;
+      return -1;
    
    // We dont even try to install virtual packages..
    if (Pkg->VersionList == 0)
-      return;
+      return -1;
    
    /* Target the candidate version and remove the autoflag. We reset the
       autoflag below if this was called recursively. Otherwise the user
@@ -782,11 +794,29 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
    AddStates(Pkg);
    Update(Pkg);
    AddSizes(Pkg);
-   
-   if (AutoInst == false)
+
+   return 1;
+}
+
+void pkgDepCache::MarkInstallRec(PkgIterator const &Pkg,
+      bool Restricted, std::set<PkgIterator> &MarkAgain,
+      unsigned long Depth, const char *DebugStr)
+{
+   if (Depth > 100)
       return;
+   if (MarkInstall0(Pkg) <= 0)
+      return;
+
+#define DEBUG_MI(n, fmt, ...) if (DebugStr) \
+   fprintf(stderr, "%s:%*s " fmt "\n", DebugStr, (int)Depth*2+n, "", __VA_ARGS__)
+#define DEBUG_THIS(fmt, ...) DEBUG_MI(0, fmt, __VA_ARGS__)
+#define DEBUG_NEXT(fmt, ...) DEBUG_MI(1, fmt, __VA_ARGS__)
+
+   DEBUG_THIS("mark %s", Pkg.Name());
 
+   StateCache &P = PkgState[Pkg->ID];
    DepIterator Dep = P.InstVerIter(*this).DependsList();
+   bool AddMarkAgain = false;
    for (; Dep.end() != true;)
    {
       // Grok or groups
@@ -849,20 +879,32 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	 // Select the highest priority providing package
 	 if (InstPkg.end() == true)
 	 {
+	    int CanSelect = 0;
 	    pkgPrioSortList(*Cache,Cur);
 	    for (; *Cur != 0; Cur++)
 	    {
 	       PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg);
 	       if (PkgState[Pkg->ID].CandidateVer != *Cur)
 		  continue;
-	       InstPkg = Pkg;
-	       break;
+	       if (CanSelect++ == 0)
+		  InstPkg = Pkg;
+	       else
+		  break;
+	    }
+	    // In restricted mode, skip ambiguous dependencies.
+	    if (Restricted && CanSelect > 1) {
+	       DEBUG_NEXT("target %s AMB", P.Name());
+	       AddMarkAgain = true;
+	       continue;
 	    }
 	 }
-	 
+
+	 DEBUG_NEXT("target %s", P.Name());
+
 	 if (InstPkg.end() == false)
 	 {
-	    MarkInstall(InstPkg,true,Depth + 1);
+	    // Recursion is always restricted
+	    MarkInstallRec(InstPkg,/*Restricted*/true,MarkAgain,Depth+1,DebugStr);
 
 	    // Set the autoflag, after MarkInstall because MarkInstall unsets it
 	    if (P->CurrentVer == 0)
@@ -880,13 +922,67 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	 {
 	    VerIterator Ver(*this,*I);
 	    PkgIterator Pkg = Ver.ParentPkg();
-      
+	    DEBUG_NEXT("delete %s", Pkg.Name());
 	    MarkDelete(Pkg);
 	    PkgState[Pkg->ID].Flags |= Flag::Auto;
 	 }
 	 continue;
       }      
    }
+
+   if (AddMarkAgain)
+      MarkAgain.insert(Pkg);
+}
+
+void pkgDepCache::MarkInstall1(PkgIterator const &Pkg,
+      std::set<PkgIterator> &MarkAgain)
+{
+   bool Debug = _config->FindB("Debug::pkgMarkInstall", false);
+   const char *DebugA = Debug ? "MI1a" : NULL;
+   const char *DebugB = Debug ? "MI1b" : NULL;
+   std::set<PkgIterator> MA;
+   std::set<PkgIterator>::iterator I;
+   MarkInstallRec(Pkg, true, MA, 0, DebugA);
+   while (1) {
+      std::set<PkgIterator> MAA;
+      for (I = MA.begin(); I != MA.end(); ++I)
+	 MarkInstallRec(*I, true, MAA, 0, DebugB);
+      if (MA == MAA)
+	 break;
+      MA = MAA;
+   }
+   for (I = MA.begin(); I != MA.end(); ++I)
+      MarkAgain.insert(*I);
+}
+
+void pkgDepCache::MarkInstall2(PkgIterator const &Pkg)
+{
+   bool Debug = _config->FindB("Debug::pkgMarkInstall", false);
+   const char *DebugA = Debug ? "MI2a" : NULL;
+   const char *DebugB = Debug ? "MI2b" : NULL;
+   const char *DebugC = Debug ? "MI2c" : NULL;
+   std::set<PkgIterator> MA;
+   std::set<PkgIterator>::iterator I;
+   MarkInstallRec(Pkg, true, MA, 0, DebugA);
+   while (1) {
+      std::set<PkgIterator> MAA;
+      for (I = MA.begin(); I != MA.end(); ++I)
+	 MarkInstallRec(*I, true, MAA, 0, DebugB);
+      for (I = MA.begin(); I != MA.end(); ++I)
+	 MarkInstallRec(*I, false, MAA, 0, DebugC);
+      if (MA == MAA)
+	 break;
+      MA = MAA;
+   }
+}
+
+void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
+			      unsigned long Depth)
+{
+   if (AutoInst == false)
+      MarkInstall0(Pkg);
+   else
+      MarkInstall2(Pkg);
 }
 									/*}}}*/
 // DepCache::SetReInstall - Set the reinstallation flag			/*{{{*/
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index bb96afb..c7dd89e 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -42,6 +42,8 @@
 #pragma interface "apt-pkg/depcache.h"
 #endif
 
+#include <set>
+
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/progress.h>
 
@@ -195,8 +197,21 @@ class pkgDepCache : protected pkgCache::Namespace
    // Manipulators
    void MarkKeep(PkgIterator const &Pkg,bool Soft = false);
    void MarkDelete(PkgIterator const &Pkg,bool Purge = false);
+
+   // shallow mark; ret: -1 err, 0 already marked, 1 just marked
+   int MarkInstall0(PkgIterator const &Pkg);
+   // non-ambiguous recursive mark; MarkAgain should be marked again
+   void MarkInstall1(PkgIterator const &Pkg, std::set<PkgIterator> &MarkAgain);
+   // full wavefront recursive mark
+   void MarkInstall2(PkgIterator const &Pkg);
+   // compat
    void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
 		    unsigned long Depth = 0);
+   // implementation
+   void MarkInstallRec(PkgIterator const &Pkg,
+      bool Restricted, std::set<PkgIterator> &MarkAgain,
+      unsigned long Depth, const char *DebugStr);
+
    void SetReInstall(PkgIterator const &Pkg,bool To);
    void SetCandidateVersion(VerIterator TargetVer);
    
diff --git a/apt-pkg/luaiface.cc b/apt-pkg/luaiface.cc
index 28d3c17..a58efb1 100644
--- a/apt-pkg/luaiface.cc
+++ b/apt-pkg/luaiface.cc
@@ -1398,6 +1398,18 @@ static int AptLua_gettext(lua_State *L)
    return 0;
 }
 
+static int AptLua_savestate(lua_State *L)
+{
+   _lua->SaveState();
+   return 0;
+}
+
+static int AptLua_restorestate(lua_State *L)
+{
+   _lua->RestoreState();
+   return 0;
+}
+
 static const luaL_reg aptlib[] = {
    {"confget",		AptLua_confget},
    {"confgetlist",	AptLua_confgetlist},
@@ -1446,6 +1458,8 @@ static const luaL_reg aptlib[] = {
    {"apterror",		AptLua_apterror},
    {"aptwarning",	AptLua_aptwarning},
    {"_",		AptLua_gettext},
+   {"savestate",	AptLua_savestate},
+   {"restorestate",	AptLua_restorestate},
    {NULL, NULL}
 };
 
diff --git a/apt-pkg/luaiface.h b/apt-pkg/luaiface.h
index ef783b3..79a980a 100644
--- a/apt-pkg/luaiface.h
+++ b/apt-pkg/luaiface.h
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include <apt-pkg/pkgcache.h>
+#include <apt-pkg/depcache.h>
 
 using namespace std;
 
@@ -38,8 +39,9 @@ class Lua {
 
    vector<string> Globals;
 
-   pkgDepCache *DepCache;
    pkgCache *Cache;
+   pkgDepCache *DepCache;
+   pkgDepCache::State DepCacheState;
 
    LuaCacheControl *CacheControl;
 
@@ -100,6 +102,14 @@ class Lua {
    void ResetCaches()
       { DepCache = NULL; Cache = NULL; Fix = NULL; DontFix = false; };
 
+   void SaveState() {
+      DepCacheState.Save(DepCache);
+   };
+
+   void RestoreState() {
+      DepCacheState.Restore();
+   };
+
    // For API functions
    pkgDepCache *GetDepCache(lua_State *L=NULL);
    pkgCache *GetCache(lua_State *L=NULL);
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 317e064..bbff8b4 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -25,6 +25,7 @@
 #pragma implementation "apt-pkg/cacheiterators.h"
 #endif 
 
+#define PKGCACHE_FINDPKG_ABI
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/error.h>
@@ -37,6 +38,8 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <assert.h>
+
 #include <ctype.h>
 #include <system.h>
 									/*}}}*/
@@ -183,22 +186,16 @@ unsigned long pkgCache::sHash(const char *Str) const
 // Cache::FindPkg - Locate a package by name				/*{{{*/
 // ---------------------------------------------------------------------
 /* Returns 0 on error, pointer to the package otherwise */
+pkgCache::PkgIterator pkgCache::FindPkg(const string &Name)
+{
+   return PkgIterator(*this,FindPackage(Name.c_str()));
+}
+#ifdef PKGCACHE_FINDPKG_ABI
 pkgCache::PkgIterator pkgCache::FindPkg(string Name)
 {
-   // Look at the hash bucket
-   Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)];
-   const char *name = Name.c_str(); // CNC:2003-02-17
-   for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
-   {
-      // CNC:2003-02-17 - We use case sensitive package names. Also,
-      //                  store Pkg->Name in a temporary variable.
-      map_ptrloc PkgName = Pkg->Name;
-      if (PkgName != 0 && StrP[PkgName] == name[0] &&
-	  strcmp(name,StrP + PkgName) == 0)
-	 return PkgIterator(*this,Pkg);
-   }
-   return PkgIterator(*this,0);
+   return PkgIterator(*this,FindPackage(Name.c_str()));
 }
+#endif
 									/*}}}*/
 
 // CNC:2003-02-17 - A slightly changed FindPkg(), hacked for performance.
@@ -211,12 +208,13 @@ pkgCache::Package *pkgCache::FindPackage(const char *Name)
    Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)];
    for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
    {
-      // CNC:2003-02-17 - We use case sensitive package names. Also,
-      //                  store Pkg->Name in a temporary variable.
+      // CNC:2003-02-17 - We use case sensitive package names.
       map_ptrloc PkgName = Pkg->Name;
-      if (PkgName != 0 && StrP[PkgName] == Name[0] &&
-	  strcmp(Name,StrP + PkgName) == 0)
-	 return Pkg;
+      if (PkgName != 0) {
+	 const char *S = StrP + PkgName;
+	 if (*S == *Name && strcmp(S, Name) == 0)
+	    return Pkg;
+      }
    }
    return NULL;
 }
@@ -393,11 +391,9 @@ bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result)
    must be delete [] 'd */
 pkgCache::Version **pkgCache::DepIterator::AllTargets()
 {
-   Version **Res = 0;
-   unsigned long Size =0;
-   while (1)
+   Version *Res[1024];
+   unsigned int Size = 0;
    {
-      Version **End = Res;
       PkgIterator DPkg = TargetPkg();
 
       // Walk along the actual package providing versions
@@ -410,10 +406,23 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets()
 	      Dep->Type == pkgCache::Dep::Obsoletes) &&
 	     ParentPkg() == I.ParentPkg())
 	    continue;
-	 
-	 Size++;
-	 if (Res != 0)
-	    *End++ = I;
+
+	 Version *v = I;
+	 if (Res != 0 && Size > 0) {
+	    bool seen = false;
+	    for (unsigned int j = 0; j < Size; ++j) {
+	       Version *vj = Res[j];
+	       if (v == vj) {
+		  seen = true;
+		  break;
+	       }
+	    }
+	    if (seen)
+	       continue;
+	 }
+
+	 assert(Size < sizeof(Res)/sizeof(*Res));
+	 Res[Size++] = v;
       }
       
       // Follow all provides
@@ -426,26 +435,31 @@ pkgCache::Version **pkgCache::DepIterator::AllTargets()
 	      Dep->Type == pkgCache::Dep::Obsoletes) &&
 	     ParentPkg() == I.OwnerPkg())
 	    continue;
-	 
-	 Size++;
-	 if (Res != 0)
-	    *End++ = I.OwnerVer();
-      }
-      
-      // Do it again and write it into the array
-      if (Res == 0)
-      {
-	 Res = new Version *[Size+1];
-	 Size = 0;
+
+	 Version *v = I.OwnerVer();
+	 if (Res != 0 && Size > 0) {
+	    bool seen = false;
+	    for (unsigned int j = 0; j < Size; ++j) {
+	       Version *vj = Res[j];
+	       if (v == vj) {
+		  seen = true;
+		  break;
+	       }
+	    }
+	    if (seen)
+	       continue;
+	 }
+
+	 assert(Size < sizeof(Res)/sizeof(*Res));
+	 Res[Size++] = v;
       }
-      else
-      {
-	 *End = 0;
-	 break;
-      }      
    }
    
-   return Res;
+   Version **Ret = new Version *[Size+1];
+   if (Size)
+      memcpy(Ret, Res, Size*sizeof(*Res));
+   Ret[Size] = 0;
+   return Ret;
 }
 									/*}}}*/
 // DepIterator::GlobOr - Compute an OR group				/*{{{*/
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index 5069bc0..90e5116 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -110,7 +110,7 @@ class pkgCache
 
    // CNC:2003-02-16 - Inlined here.
    inline unsigned long sHash(const char *S) const;
-   inline unsigned long sHash(string S) const {return sHash(S.c_str());};
+   inline unsigned long sHash(const string &S) const {return sHash(S.c_str());};
    
    public:
    
@@ -131,14 +131,17 @@ class pkgCache
    inline void *DataEnd() {return ((unsigned char *)Map.Data()) + Map.Size();};
       
    // String hashing function (512 range)
-   inline unsigned long Hash(string S) const {return sHash(S);};
-   inline unsigned long Hash(const char *S) const {return sHash(S);};
+   inline unsigned long Hash(const char *S) const;
+   inline unsigned long Hash(const string &S) const {return Hash(S.c_str());};
 
    // Usefull transformation things
    const char *Priority(unsigned char Priority);
    
    // Accessors
+   PkgIterator FindPkg(const string &Name);
+#ifdef PKGCACHE_FINDPKG_ABI
    PkgIterator FindPkg(string Name);
+#endif
    // CNC:2003-02-17 - A slightly changed FindPkg(), hacked for performance.
    Package *FindPackage(const char *Name);
    Header &Head() {return *HeaderP;};
@@ -203,7 +206,7 @@ struct pkgCache::Header
    DynamicMMap::Pool Pools[7];
    
    // Rapid package name lookup
-   map_ptrloc HashTable[8*1048];
+   map_ptrloc HashTable[64*1024];
 
    bool CheckSizes(Header &Against) const;
    Header();
@@ -227,7 +230,7 @@ struct pkgCache::Package
    unsigned char InstState;         // Flags
    unsigned char CurrentState;      // State
    
-   unsigned short ID;
+   unsigned int ID;
    unsigned long Flags;
 };
 
@@ -275,8 +278,8 @@ struct pkgCache::Version
    
    map_ptrloc Size;              // These are the .deb size
    map_ptrloc InstalledSize;
-   unsigned short Hash;
-   unsigned short ID;
+   unsigned int Hash;
+   unsigned int ID;
    unsigned char Priority;
 };
 
@@ -312,15 +315,18 @@ struct pkgCache::StringItem
 #include <apt-pkg/cacheiterators.h>
 
 // CNC:2003-02-16 - Inlined here.
-#include <ctype.h>
+inline unsigned long pkgCache::sHash(const char *S) const
+{
+   unsigned long h = 5381;
+   unsigned char c;
+   for (c = *S; c != '\0'; c = *++S)
+      h = h * 33 + c;
+   return h;
+}
 #define hash_count(a) (sizeof(a)/sizeof(a[0]))
-inline unsigned long pkgCache::sHash(const char *Str) const
+inline unsigned long pkgCache::Hash(const char *S) const
 {
-   unsigned long Hash = 0;
-   for (const char *I = Str; *I != 0; I++)
-      //Hash = 5*Hash + tolower(*I);
-      Hash = 5*Hash + *I;
-   return Hash % hash_count(HeaderP->HashTable);
+   return sHash(S) % hash_count(HeaderP->HashTable);
 }
 #undef hash_count
 
diff --git a/apt-pkg/pkgrecords.h b/apt-pkg/pkgrecords.h
index 1bf1f9e..9f831a3 100644
--- a/apt-pkg/pkgrecords.h
+++ b/apt-pkg/pkgrecords.h
@@ -67,6 +67,7 @@ class pkgRecords::Parser
    virtual string ShortDesc() {return string();};
    virtual string LongDesc() {return string();};
    virtual string Name() {return string();};
+   virtual string Changelog() {return string();};
    
    // The record in binary form
    virtual void GetRec(const char *&Start,const char *&Stop) {Start = Stop = 0;};
diff --git a/apt-pkg/rpm/rpmpm.cc b/apt-pkg/rpm/rpmpm.cc
index c5a13dc..741fb9b 100644
--- a/apt-pkg/rpm/rpmpm.cc
+++ b/apt-pkg/rpm/rpmpm.cc
@@ -259,23 +259,38 @@ bool pkgRPMPM::Go()
    
    for (vector<Item>::iterator I = List.begin(); I != List.end(); I++)
    {
+      string Name = I->Pkg.Name();
+      string::size_type loc;
+      bool NeedLabel;
+
       switch (I->Op)
       {
       case Item::Purge:
       case Item::Remove:
-	 if (strchr(I->Pkg.Name(), '#') != NULL)
-	 {
-	    char *name = strdup(I->Pkg.Name());
-	    char *p = strchr(name, '#');
-	    *(p++) = '-';
-	    const char *epoch = strchr(p, ':');
-	    if (epoch != NULL)
-	       memmove(p, epoch+1, strlen(epoch+1)+1);
-	    unalloc.push_back(name);
-	    uninstall.push_back(name);
+	 // Unmunge our package names so rpm can find them...
+	 NeedLabel = false;
+	 if ((loc = Name.find('#')) != string::npos) {
+	    Name = Name.substr(0,loc);
+	    NeedLabel = true;
 	 }
-	 else
-	    uninstall.push_back(I->Pkg.Name());
+	 if ((loc = Name.rfind(".32bit")) != string::npos &&
+	       loc == Name.length() - strlen(".32bit"))
+	    Name = Name.substr(0,loc);
+	 if (NeedLabel) {
+	    const char *VerStr = I->Pkg.CurrentVer().VerStr();
+	    const char *Epoch = strchr(VerStr, ':');
+	    if (Epoch)
+	       VerStr = Epoch + 1;
+	    Name += "-";
+	    Name += VerStr;
+	 }
+#if RPM_VERSION >= 0x040202
+	 // This is needed for removal to work on multilib packages, but old
+	 // rpm versions don't support name.arch in RPMDBI_LABEL, oh well...
+	 Name = Name + "." + I->Pkg.CurrentVer().Arch();
+#endif
+	 uninstall.push_back(strdup(Name.c_str()));
+	 unalloc.push_back(strdup(Name.c_str()));
 	 pkgs_uninstall.push_back(I->Pkg);
 	 break;
 
@@ -283,12 +298,9 @@ bool pkgRPMPM::Go()
 	 break;
 
        case Item::Install:
-	 if (strchr(I->Pkg.Name(), '#') != NULL) {
-	    char *name = strdup(I->Pkg.Name());
-	    char *p = strchr(name, '#');
-	    *p = 0;
-	    PkgIterator Pkg = Cache.FindPkg(name);
-	    free(name);
+	 if ((loc = Name.find('#')) != string::npos) {
+	    Name = Name.substr(0,loc);
+	    PkgIterator Pkg = Cache.FindPkg(Name);
 	    PrvIterator Prv = Pkg.ProvidesList();
 	    bool Installed = false;
 	    for (; Prv.end() == false; Prv++) {
@@ -783,11 +795,6 @@ bool pkgRPMLibPM::Process(vector<const char*> &install,
    TS = rpmtransCreateSet(DB, Dir.c_str());
 #endif
 
-#if RPM_VERSION >= 0x040000
-   if (rpmExpandNumeric("%{?_repackage_all_erasures}"))
-      tsFlags |= RPMTRANS_FLAG_REPACKAGE;
-#endif
-		     
 #if RPM_VERSION >= 0x040300
    /* Initialize security context patterns for SELinux */
    if (!(tsFlags & RPMTRANS_FLAG_NOCONTEXTS)) {
@@ -840,14 +847,14 @@ bool pkgRPMLibPM::Process(vector<const char*> &install,
       }
    }
 #else
+   if (_config->FindB("RPM::NoDeps", false) == false) {
 #if RPM_VERSION < 0x040000
-   rpmDependencyConflict *conflicts;
+      rpmDependencyConflict *conflicts = NULL;
 #else
-   rpmDependencyConflict conflicts;
+      rpmDependencyConflict conflicts = NULL;
 #endif
-   if (_config->FindB("RPM::NoDeps", false) == false) {
       int numConflicts;
-      if (rpmdepCheck(TS, &conflicts, &numConflicts)) {
+      if (rpmdepCheck(TS, &conflicts, &numConflicts) || conflicts) {
 	 _error->Error(_("Transaction set check failed"));
 	 if (conflicts) {
 	    printDepProblems(stderr, conflicts, numConflicts);
@@ -939,8 +946,6 @@ bool pkgRPMLibPM::ParseRpmOpts(const char *Cnf, int *tsFlags, int *probFilter)
 #if RPM_VERSION >= 0x040000
 	 else if (Opts->Value == "--nomd5")
 	    *tsFlags |= RPMTRANS_FLAG_NOMD5;
-	 else if (Opts->Value == "--repackage")
-	    *tsFlags |= RPMTRANS_FLAG_REPACKAGE;
 #endif
 #if RPM_VERSION >= 0x040200
 	 else if (Opts->Value == "--noconfigs" ||
diff --git a/apt-pkg/rpm/rpmrecords.cc b/apt-pkg/rpm/rpmrecords.cc
index 6f8f270..0671a85 100644
--- a/apt-pkg/rpm/rpmrecords.cc
+++ b/apt-pkg/rpm/rpmrecords.cc
@@ -171,6 +171,27 @@ string rpmRecordParser::LongDesc()
    return Ret;
 }
 									/*}}}*/
+// RecordParser::Changelog - Return package changelog if any		/*{{{*/
+// -----------------------------------------------
+string rpmRecordParser::Changelog()
+{
+   char *str;
+   string rval("");
+
+   str = headerSprintf(HeaderP,
+         "[* %{CHANGELOGTIME:day} %{CHANGELOGNAME}\n%{CHANGELOGTEXT}\n\n]",
+         rpmTagTable, rpmHeaderFormats, NULL);
+
+   if (str && *str) {
+	  rval = (const char *)str;
+   }
+   if (str)
+      str = (char *)_free(str);
+
+   return rval;
+}
+
+									/*}}}*/
 // RecordParser::SourcePkg - Return the source package name if any	/*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -256,20 +277,23 @@ void rpmRecordParser::BufCatDep(const char *pkg,
 void rpmRecordParser::BufCatDescr(const char *descr)
 {
    const char *begin = descr;
+   const char *p = descr;
 
-   while (*descr) 
+   while (*p)
    {
-      if (*descr=='\n') 
+      if (*p=='\n')
       {
 	 BufCat(" ");
-	 BufCat(begin, descr+1);
-	 begin = descr+1;
+	 BufCat(begin, p+1);
+	 begin = p+1;
       }
-      descr++;
+      p++;
+   }
+   if (*begin) {
+      BufCat(" ");
+      BufCat(begin, p);
+      BufCat("\n");
    }
-   BufCat(" ");
-   BufCat(begin, descr);
-   BufCat("\n");
 }
 
 
@@ -419,6 +443,17 @@ void rpmRecordParser::GetRec(const char *&Start,const char *&Stop)
    BufCat("\n");
    headerGetEntry(HeaderP, RPMTAG_DESCRIPTION, &type, (void **)&str, &count);
    BufCatDescr(str);
+
+   str = headerSprintf(HeaderP,
+         "[* %{CHANGELOGTIME:day} %{CHANGELOGNAME}\n%{CHANGELOGTEXT}\n]",
+         rpmTagTable, rpmHeaderFormats, NULL);
+   if (str && *str) {
+      BufCat("Changelog:\n");
+      BufCatDescr(str);
+   }
+   if (str)
+      str = (char *)_free(str);
+
    BufCat("\n");
    
    Start = Buffer;
diff --git a/apt-pkg/rpm/rpmrecords.h b/apt-pkg/rpm/rpmrecords.h
index 71e3325..d8a72d5 100644
--- a/apt-pkg/rpm/rpmrecords.h
+++ b/apt-pkg/rpm/rpmrecords.h
@@ -59,6 +59,7 @@ class rpmRecordParser : public pkgRecords::Parser
    virtual string ShortDesc();
    virtual string LongDesc();
    virtual string Name();
+   virtual string Changelog();
    
    inline Header GetRecord() { return HeaderP; };
 
diff --git a/apt-pkg/rpm/rpmsrcrecords.cc b/apt-pkg/rpm/rpmsrcrecords.cc
index 49256d4..7cdd6cd 100644
--- a/apt-pkg/rpm/rpmsrcrecords.cc
+++ b/apt-pkg/rpm/rpmsrcrecords.cc
@@ -191,18 +191,38 @@ string rpmSrcRecordParser::Section() const
    return string(rc?str:"");
 }
 
+// SrcRecordParser::Changelog - Package changelog
+// ----------------------------------------------
+string rpmSrcRecordParser::Changelog() const
+{
+   char *str;
+   string rval("");
+
+   str = headerSprintf(HeaderP,
+         "[* %{CHANGELOGTIME:day} %{CHANGELOGNAME}\n%{CHANGELOGTEXT}\n\n]",
+         rpmTagTable, rpmHeaderFormats, NULL);
+
+   if (str && *str) {
+	  rval = (const char *)str;
+   }
+   if (str)
+      str = (char *)_free(str);
+
+   return rval;
+}
+
 unsigned long rpmSrcRecordParser::Offset() 
 {
     return Handler->Offset();
 }
 
-void rpmSrcRecordParser::BufCat(char *text)
+void rpmSrcRecordParser::BufCat(const char *text)
 {
    if (text != NULL)
       BufCat(text, text+strlen(text));
 }
 
-void rpmSrcRecordParser::BufCat(char *begin, char *end)
+void rpmSrcRecordParser::BufCat(const char *begin, const char *end)
 {
    unsigned len = end - begin;
     
@@ -222,13 +242,15 @@ void rpmSrcRecordParser::BufCat(char *begin, char *end)
    BufUsed += len;
 }
 
-void rpmSrcRecordParser::BufCatTag(char *tag, char *value)
+void rpmSrcRecordParser::BufCatTag(const char *tag, const char *value)
 {
    BufCat(tag);
    BufCat(value);
 }
 
-void rpmSrcRecordParser::BufCatDep(char *pkg, char *version, int flags)
+void rpmSrcRecordParser::BufCatDep(const char *pkg,
+				   const char *version,
+				   int flags)
 {
    char buf[16];
    char *ptr = (char*)buf;
@@ -265,23 +287,26 @@ void rpmSrcRecordParser::BufCatDep(char *pkg, char *version, int flags)
    }
 }
 
-void rpmSrcRecordParser::BufCatDescr(char *descr)
+void rpmSrcRecordParser::BufCatDescr(const char *descr)
 {
-   char *begin = descr;
+   const char *begin = descr;
+   const char *p = descr;
 
-   while (*descr) 
+   while (*p)
    {
-      if (*descr=='\n') 
+      if (*p=='\n')
       {
 	 BufCat(" ");
-	 BufCat(begin, descr+1);
-	 begin = descr+1;
+	 BufCat(begin, p+1);
+	 begin = p+1;
       }
-      descr++;
+      p++;
+   }
+   if (*begin) {
+      BufCat(" ");
+      BufCat(begin, p);
+      BufCat("\n");
    }
-   BufCat(" ");
-   BufCat(begin, descr);
-   BufCat("\n");
 }
 
 // SrcRecordParser::AsStr - The record in raw text
@@ -394,6 +419,17 @@ string rpmSrcRecordParser::AsStr()
    BufCat("\n");
    headerGetEntry(HeaderP, RPMTAG_DESCRIPTION, &type, (void **)&str, &count);
    BufCatDescr(str);
+
+   str = headerSprintf(HeaderP,
+         "[* %{CHANGELOGTIME:day} %{CHANGELOGNAME}\n%{CHANGELOGTEXT}\n]",
+         rpmTagTable, rpmHeaderFormats, NULL);
+   if (str && *str) {
+      BufCat("Changelog:\n");
+      BufCatDescr(str);
+   }
+   if (str)
+      str = (char *)_free(str);
+
    BufCat("\n");
    
    return string(Buffer, BufUsed);
diff --git a/apt-pkg/rpm/rpmsrcrecords.h b/apt-pkg/rpm/rpmsrcrecords.h
index 2e8f691..41505ae 100644
--- a/apt-pkg/rpm/rpmsrcrecords.h
+++ b/apt-pkg/rpm/rpmsrcrecords.h
@@ -33,11 +33,11 @@ class rpmSrcRecordParser : public pkgSrcRecords::Parser
    unsigned int BufSize;
    unsigned int BufUsed;
    
-   void BufCat(char *text);
-   void BufCat(char *begin, char *end);
-   void BufCatTag(char *tag, char *value);
-   void BufCatDep(char *pkg, char *version, int flags);
-   void BufCatDescr(char *descr);
+   void BufCat(const char *text);
+   void BufCat(const char *begin, const char *end);
+   void BufCatTag(const char *tag, const char *value);
+   void BufCatDep(const char *pkg, const char *version, int flags);
+   void BufCatDescr(const char *descr);
 
 public:
    virtual bool Restart();
@@ -48,6 +48,7 @@ public:
    virtual string Version() const;
    virtual string Maintainer() const;
    virtual string Section() const;
+   virtual string Changelog() const;
    virtual const char **Binaries();
    virtual unsigned long Offset();
    virtual string AsStr();
diff --git a/apt-pkg/rpm/rpmversion.cc b/apt-pkg/rpm/rpmversion.cc
index d3f5efd..d335b74 100644
--- a/apt-pkg/rpm/rpmversion.cc
+++ b/apt-pkg/rpm/rpmversion.cc
@@ -194,10 +194,19 @@ bool rpmVersioningSystem::CheckDep(const char *PkgVer,
       break;
       
     default:
+      // optimize: no need to check version
+      return true;
+      // old code:
       DepFlags = RPMSENSE_ANY;
       break;
    }
 
+   // optimize: equal version strings => equal versions
+   if ((DepFlags & RPMSENSE_SENSEMASK) == RPMSENSE_EQUAL)
+      if (PkgVer && DepVer)
+	 if (strcmp(PkgVer, DepVer) == 0)
+	    return invert ? false : true;
+
 #if RPM_VERSION >= 0x040100
    rpmds pds = rpmdsSingle(RPMTAG_PROVIDENAME, "", PkgVer, PkgFlags);
    rpmds dds = rpmdsSingle(RPMTAG_REQUIRENAME, "", DepVer, DepFlags);
diff --git a/apt-pkg/srcrecords.h b/apt-pkg/srcrecords.h
index 006c9d3..8bc013f 100644
--- a/apt-pkg/srcrecords.h
+++ b/apt-pkg/srcrecords.h
@@ -70,6 +70,7 @@ class pkgSrcRecords
       virtual string Version() const = 0;
       virtual string Maintainer() const = 0;
       virtual string Section() const = 0;
+      virtual string Changelog() const = 0;
       virtual const char **Binaries() = 0;   // Ownership does not transfer
 
       virtual bool BuildDepends(vector<BuildDepRec> &BuildDeps, bool ArchOnly) = 0;
diff --git a/buildlib/tools.m4 b/buildlib/tools.m4
index 21ac652..ebee7c4 100644
--- a/buildlib/tools.m4
+++ b/buildlib/tools.m4
@@ -96,11 +96,15 @@ AC_DEFUN([rc_GLIBC_VER],
 #include <features.h>
 #include <stdio.h>
 #include <stdlib.h>
-int main(int argc, char **argv) { printf("libc6.%d",__GLIBC_MINOR__); exit(0); }
+int main(int argc, char **argv) { printf("%d",__GLIBC_MINOR__); exit(0); }
 _GLIBC_
 	${CC-cc} $dummy.c -o $dummy > /dev/null 2>&1
 	if test "$?" = 0; then
-		GLIBC_VER=`./$dummy`
+		GLIBC_MINOR=`./$dummy`
+		if test "$GLIBC_MINOR" -gt 9; then
+			GLIBC_MINOR=9
+		fi
+		GLIBC_VER="libc6.$GLIBC_MINOR"
 		AC_MSG_RESULT([$GLIBC_VER])
 		dnl CNC:2003-03-25
 		GLIBC_VER="$GLIBC_VER"
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index 6240edc..3077200 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -356,6 +356,7 @@ bool Dump(CommandLine &Cmd)
    pkgCache &Cache = *GCache;
    cout << "Using Versioning System: " << Cache.VS->Label << endl;
    
+   if (_config->FindB("APT::Cache::DumpPackages",true) == true)
    for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
    {
       cout << "Package: " << P.Name() << endl;
@@ -878,8 +879,7 @@ bool WhatDepends(CommandLine &CmdL)
 		  continue;
 	       LocalColours[Parent->ID] = 1;
 		  
-	       if (Ver.end() == false &&
-		   Cache.VS->CheckDep(Ver.VerStr(),RD) == false)
+	       if (Cache.VS->CheckDep(RDPrv.ProvideVersion(),RD) == false)
 		  continue;
 
 	       if (Recurse == true && Colours[Parent->ID] == 0)
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index c0749e6..779677f 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -1428,12 +1428,15 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
    {
       if (_config->FindB("APT::Get::ReInstall",false) == true)
       {
-	 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
-	    ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
+	 if (Pkg->CurrentVer == 0)
+	    ioprintf(c1out,_("Reinstallation of %s is not possible.\n"),
 		     Pkg.Name());
+	 else if (Pkg.CurrentVer().Downloadable() == false)
+	    ioprintf(c1out,_("Reinstallation of %s %s is not possible, it cannot be downloaded.\n"),
+		     Pkg.Name(), Pkg.CurrentVer().VerStr());
 	 else
 	    Cache.SetReInstall(Pkg,true);
-      }      
+      }
       else
       {
 	 if (AllowFail == true)
@@ -1897,7 +1900,10 @@ bool DoInstall(CommandLine &CmdL)
 		  return _error->Error(_("Couldn't parse name '%s'"),S);
 	    }
 	    *sep = '\0';
-	    VerTag = p;
+	    /* S may be overwritten later, for example, if it contains
+	     * a file name that will be resolved to a package.
+	     * So we point VerTag to the same offset in OrigS. */
+	    VerTag = (p - S) + OrigS;
 	 }
 	 
 	 // CNC:2003-11-21 - Try to handle unknown file items.
@@ -1989,7 +1995,7 @@ bool DoInstall(CommandLine &CmdL)
 	    if (Hit == true)
 	       continue;
 #endif
-	    return _error->Error(_("Couldn't find package %s"),S);
+	    return _error->Error(_("Couldn't find package %s"), OrigS);
 	 }
 
 	 // Regexs must always be confirmed
@@ -2015,7 +2021,7 @@ bool DoInstall(CommandLine &CmdL)
 	    
 	    // CNC:2003-11-23
 	    ioprintf(c1out,_("Selecting %s for '%s'\n"),
-		     Pkg.Name(),S);
+		     Pkg.Name(), OrigS);
 	    
 	    if (VerTag != 0)
 	       // CNC:2003-11-05
@@ -2028,7 +2034,7 @@ bool DoInstall(CommandLine &CmdL)
 	 regfree(&Pattern);
 	 
 	 if (Hit == false)
-	    return _error->Error(_("Couldn't find package %s"),S);
+	    return _error->Error(_("Couldn't find package %s"), OrigS);
       }
       else
       {
@@ -3244,7 +3250,9 @@ int main(int argc,const char *argv[])
 	 if (strstr(*I, "://") != NULL)
 	 {
 	    URLLst.push_back(*I);
-	    *I = strrchr(*I, '/')+1;
+	    const char *N = strdup(strrchr(*I, '/')+1);
+	    free((void *)*I);
+	    *I = N;
 	 }
       }
 
diff --git a/cmdline/apt-shell.cc b/cmdline/apt-shell.cc
index 6d1f767..06acf1e 100644
--- a/cmdline/apt-shell.cc
+++ b/cmdline/apt-shell.cc
@@ -1100,10 +1100,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
 		 " ?] "),Prompt);
       c2out << flush;
       if (AnalPrompt(Prompt) == false)
-      {
-	 c2out << _("Abort.") << endl;
-	 exit(1);
-      }     
+	 return _error->Error(_("Operation cancelled."));
    }
    else
    {      
@@ -1119,10 +1116,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
 	    c2out << _("Do you want to continue? [Y/n] ") << flush;
 	 
 	    if (YnPrompt() == false)
-	    {
-	       c2out << _("Abort.") << endl;
-	       exit(1);
-	    }     
+	       return _error->Error(_("Operation cancelled."));
 	 }	 
       }      
    }
@@ -1504,12 +1498,15 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
    {
       if (_config->FindB("APT::Get::ReInstall",false) == true)
       {
-	 if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
-	    ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
+	 if (Pkg->CurrentVer == 0)
+	    ioprintf(c1out,_("Reinstallation of %s is not possible.\n"),
 		     Pkg.Name());
+	 else if (Pkg.CurrentVer().Downloadable() == false)
+	    ioprintf(c1out,_("Reinstallation of %s %s is not possible, it cannot be downloaded.\n"),
+		     Pkg.Name(), Pkg.CurrentVer().VerStr());
 	 else
 	    Cache.SetReInstall(Pkg,true);
-      }      
+      }
       else
       {
 	 if (AllowFail == true)
@@ -2062,7 +2059,7 @@ bool DoInstall(CommandLine &CmdL)
 	    if (Hit == true)
 	       continue;
 #endif
-	    return _error->Error(_("Couldn't find package %s"),S);
+	    return _error->Error(_("Couldn't find package %s"), OrigS);
 	 }
 
 	 // Regexs must always be confirmed
@@ -2088,7 +2085,7 @@ bool DoInstall(CommandLine &CmdL)
 	    
 	    // CNC:2003-11-23
 	    ioprintf(c1out,_("Selecting %s for '%s'\n"),
-		     Pkg.Name(),S);
+		     Pkg.Name(), OrigS);
 	    StateGuard->Ignore(Pkg);
 	    
 	    if (VerTag != 0)
@@ -2102,7 +2099,7 @@ bool DoInstall(CommandLine &CmdL)
 	 regfree(&Pattern);
 	 
 	 if (Hit == false)
-	    return _error->Error(_("Couldn't find package %s"),S);
+	    return _error->Error(_("Couldn't find package %s"), OrigS);
       }
       else
       {
diff --git a/po/ru.po b/po/ru.po
index 3f60732..717ce2d 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -789,8 +789,13 @@ msgstr "
 
 #: cmdline/apt-get.cc:1432 cmdline/apt-shell.cc:1507
 #, c-format
-msgid "Reinstallation of %s is not possible, it cannot be downloaded.\n"
-msgstr "Переустановить %s невозможно, потому что этот пакет нельзя скачать.\n"
+msgid "Reinstallation of %s is not possible.\n"
+msgstr "Переустановить %s невозможно.\n"
+
+#: cmdline/apt-get.cc:1432 cmdline/apt-shell.cc:1507
+#, c-format
+msgid "Reinstallation of %s-%s is not possible, it cannot be downloaded.\n"
+msgstr "Переустановить %s-%s невозможно, потому что этот пакет нельзя скачать.\n"
 
 #: cmdline/apt-get.cc:1440 cmdline/apt-shell.cc:1515
 #, c-format
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin