Просмотр исходного кода

merged from lp:~donkult/apt/sid

Michael Vogt лет назад: 14
Родитель
Сommit
1d51f78e9d

+ 5 - 5
apt-pkg/acquire-method.cc

@@ -285,12 +285,12 @@ bool pkgAcqMethod::Configuration(string Message)
       I += Length + 1;
       
       for (; I < MsgEnd && *I == ' '; I++);
-      const char *Equals = I;
-      for (; Equals < MsgEnd && *Equals != '='; Equals++);
-      const char *End = Equals;
-      for (; End < MsgEnd && *End != '\n'; End++);
-      if (End == Equals)
+      const char *Equals = (const char*) memchr(I, '=', MsgEnd - I);
+      if (Equals == NULL)
 	 return false;
+      const char *End = (const char*) memchr(Equals, '\n', MsgEnd - Equals);
+      if (End == NULL)
+	 End = MsgEnd;
       
       Cnf.Set(DeQuoteString(string(I,Equals-I)),
 	      DeQuoteString(string(Equals+1,End-Equals-1)));

+ 1 - 1
apt-pkg/algorithms.cc

@@ -1002,7 +1002,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 		     if (BrokenFix == false || DoUpgrade(I) == false)
 		     {
 			// Consider other options
-			if (InOr == false)
+			if (InOr == false || Cache[I].Garbage == true)
 			{
 			   if (Debug == true)
 			      clog << "  Removing " << I.FullName(false) << " rather than change " << Start.TargetPkg().FullName(false) << endl;

+ 4 - 2
apt-pkg/aptconfiguration.cc

@@ -140,7 +140,7 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
 		for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) {
 			string const name = Ent->d_name;
 			size_t const foundDash = name.rfind("-");
-			size_t const foundUnderscore = name.rfind("_");
+			size_t const foundUnderscore = name.rfind("_", foundDash);
 			if (foundDash == string::npos || foundUnderscore == string::npos ||
 			    foundDash <= foundUnderscore ||
 			    name.substr(foundUnderscore+1, foundDash-(foundUnderscore+1)) != "Translation")
@@ -151,7 +151,7 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
 			// Skip unusual files, like backups or that alike
 			string::const_iterator s = c.begin();
 			for (;s != c.end(); ++s) {
-				if (isalpha(*s) == 0)
+				if (isalpha(*s) == 0 && *s != '_')
 					break;
 			}
 			if (s != c.end())
@@ -232,6 +232,8 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
 			codes = environment;
 		} else if (forceLang != "none")
 			codes.push_back(forceLang);
+		else //if (forceLang == "none")
+			builtin.clear();
 		allCodes = codes;
 		for (std::vector<string>::const_iterator b = builtin.begin();
 		     b != builtin.end(); ++b)

+ 11 - 17
apt-pkg/contrib/cmndline.cc

@@ -87,9 +87,8 @@ bool CommandLine::Parse(int argc,const char **argv)
       Opt++;
 
       // Match up to a = against the list
-      const char *OptEnd = Opt;
       Args *A;
-      for (; *OptEnd != 0 && *OptEnd != '='; OptEnd++);
+      const char *OptEnd = strchrnul(Opt, '=');
       for (A = ArgList; A->end() == false && 
 	   stringcasecmp(Opt,OptEnd,A->LongOpt) != 0; A++);
       
@@ -97,9 +96,8 @@ bool CommandLine::Parse(int argc,const char **argv)
       bool PreceedMatch = false;
       if (A->end() == true)
       {
-	 for (; Opt != OptEnd && *Opt != '-'; Opt++);
-
-	 if (Opt == OptEnd)
+         Opt = (const char*) memchr(Opt, '-', OptEnd - Opt);
+	 if (Opt == NULL)
 	    return _error->Error(_("Command line option %s is not understood"),argv[I]);
 	 Opt++;
 	 
@@ -194,9 +192,8 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
       // Arbitrary item specification
       if ((A->Flags & ArbItem) == ArbItem)
       {
-	 const char *J;
-	 for (J = Argument; *J != 0 && *J != '='; J++);
-	 if (*J == 0)
+	 const char *J = strchr(Argument, '=');
+	 if (J == NULL)
 	    return _error->Error(_("Option %s: Configuration item specification must have an =<val>."),argv[I]);
 
 	 // = is trailing
@@ -212,8 +209,7 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
 	 return true;
       }
       
-      const char *I = A->ConfName;
-      for (; *I != 0 && *I != ' '; I++);
+      const char *I = strchrnul(A->ConfName, ' ');
       if (*I == ' ')
 	 Conf->Set(string(A->ConfName,0,I-A->ConfName),string(I+1) + Argument);
       else
@@ -269,10 +265,9 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
 	 // Skip the leading dash
 	 const char *J = argv[I];
 	 for (; *J != 0 && *J == '-'; J++);
-	 
-	 const char *JEnd = J;
-	 for (; *JEnd != 0 && *JEnd != '-'; JEnd++);
-	 if (*JEnd != 0)
+
+	 const char *JEnd = strchr(J, '-');
+	 if (JEnd != NULL)
 	 {
 	    strncpy(Buffer,J,JEnd - J);
 	    Buffer[JEnd - J] = 0;
@@ -373,9 +368,8 @@ void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * co
 	 {
 	    // That is possibly an option: Quote it if it includes spaces,
 	    // the benefit is that this will eliminate also most false positives
-	    const char* c = &argv[i][j+1];
-	    for (; *c != '\0' && *c != ' '; ++c);
-	    if (*c == '\0') continue;
+	    const char* c = strchr(&argv[i][j+1], ' ');
+	    if (c == NULL) continue;
 	    cmdline[++length] = '"';
 	    closeQuote = true;
 	 }

+ 7 - 8
apt-pkg/contrib/strutl.cc

@@ -179,14 +179,14 @@ bool ParseQuoteWord(const char *&String,string &Res)
    {
       if (*C == '"')
       {
-	 for (C++; *C != 0 && *C != '"'; C++);
-	 if (*C == 0)
+	 C = strchr(C + 1, '"');
+	 if (C == NULL)
 	    return false;
       }
       if (*C == '[')
       {
-	 for (C++; *C != 0 && *C != ']'; C++);
-	 if (*C == 0)
+	 C = strchr(C + 1, ']');
+	 if (C == NULL)
 	    return false;
       }
    }
@@ -904,11 +904,10 @@ bool StrToTime(const string &Val,time_t &Result)
 {
    struct tm Tm;
    char Month[10];
-   const char *I = Val.c_str();
-   
+
    // Skip the day of the week
-   for (;*I != 0  && *I != ' '; I++);
-   
+   const char *I = strchr(Val.c_str(), ' ');
+
    // Handle RFC 1123 time
    Month[0] = 0;
    if (sscanf(I," %d %3s %d %d:%d:%d GMT",&Tm.tm_mday,Month,&Tm.tm_year,

+ 8 - 13
apt-pkg/deb/deblistparser.cc

@@ -525,9 +525,9 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
       // Skip whitespace
       for (;I != Stop && isspace(*I) != 0; I++);
       Start = I;
-      for (;I != Stop && *I != ')'; I++);
-      if (I == Stop || Start == I)
-	 return 0;     
+      I = (const char*) memchr(I, ')', Stop - I);
+      if (I == NULL || Start == I)
+	 return 0;
       
       // Skip trailing whitespace
       const char *End = I;
@@ -800,21 +800,16 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
       }
 
       // seperate the tag from the data
-      for (; buffer[len] != ':' && buffer[len] != '\0'; ++len)
-         /* nothing */
-         ;
-      if (buffer[len] == '\0')
+      const char* dataStart = strchr(buffer + len, ':');
+      if (dataStart == NULL)
 	 continue;
-      char* dataStart = buffer + len;
+      len = dataStart - buffer;
       for (++dataStart; *dataStart == ' '; ++dataStart)
          /* nothing */
          ;
-      char* dataEnd = dataStart;
-      for (++dataEnd; *dataEnd != '\0'; ++dataEnd)
-         /* nothing */
-         ;
+      const char* dataEnd = (const char*)rawmemchr(dataStart, '\0');
       // The last char should be a newline, but we can never be sure: #633350
-      char* lineEnd = dataEnd;
+      const char* lineEnd = dataEnd;
       for (--lineEnd; *lineEnd == '\r' || *lineEnd == '\n'; --lineEnd)
          /* nothing */
          ;

+ 6 - 2
apt-pkg/deb/debmetaindex.cc

@@ -9,6 +9,7 @@
 #include <apt-pkg/error.h>
 
 #include <set>
+#include <algorithm>
 
 using namespace std;
 
@@ -195,7 +196,11 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
 		}
 	}
 
-	std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
+	std::vector<std::string> lang = APT::Configuration::getLanguages(true);
+	std::vector<std::string>::iterator lend = std::remove(lang.begin(), lang.end(), "none");
+	if (lend != lang.end())
+		lang.erase(lend);
+
 	if (lang.empty() == true)
 		return IndexTargets;
 
@@ -207,7 +212,6 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
 		     s != sections.end(); ++s) {
 			for (std::vector<std::string>::const_iterator l = lang.begin();
 			     l != lang.end(); ++l) {
-				if (*l == "none") continue;
 				IndexTarget * Target = new OptionalIndexTarget();
 				Target->ShortDesc = "Translation-" + *l;
 				Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s);

+ 10 - 15
apt-pkg/deb/debversion.cc

@@ -127,14 +127,12 @@ int debVersioningSystem::CmpFragment(const char *A,const char *AEnd,
 int debVersioningSystem::DoCmpVersion(const char *A,const char *AEnd,
 				      const char *B,const char *BEnd)
 {
-   // Strip off the epoch and compare it 
-   const char *lhs = A;
-   const char *rhs = B;
-   for (;lhs != AEnd && *lhs != ':'; lhs++);
-   for (;rhs != BEnd && *rhs != ':'; rhs++);
-   if (lhs == AEnd)
+   // Strip off the epoch and compare it
+   const char *lhs = (const char*) memchr(A, ':', AEnd - A);
+   const char *rhs = (const char*) memchr(B, ':', BEnd - B);
+   if (lhs == NULL)
       lhs = A;
-   if (rhs == BEnd)
+   if (rhs == NULL)
       rhs = B;
    
    // Special case: a zero epoch is the same as no epoch,
@@ -169,15 +167,12 @@ int debVersioningSystem::DoCmpVersion(const char *A,const char *AEnd,
    if (rhs != B)
       rhs++;
    
-   // Find the last - 
-   const char *dlhs = AEnd-1;
-   const char *drhs = BEnd-1;
-   for (;dlhs > lhs && *dlhs != '-'; dlhs--);
-   for (;drhs > rhs && *drhs != '-'; drhs--);
-
-   if (dlhs == lhs)
+   // Find the last -
+   const char *dlhs = (const char*) memrchr(lhs, '-', AEnd - lhs);
+   const char *drhs = (const char*) memrchr(rhs, '-', BEnd - rhs);
+   if (dlhs == NULL)
       dlhs = AEnd;
-   if (drhs == rhs)
+   if (drhs == NULL)
       drhs = BEnd;
    
    // Compare the main version

+ 78 - 72
apt-pkg/deb/dpkgpm.cc

@@ -887,6 +887,28 @@ bool pkgDPkgPM::Go(int OutStatusFd)
    // create log
    OpenLog();
 
+   // Generate the base argument list for dpkg
+   std::vector<const char *> Args;
+   unsigned long StartSize = 0;
+   string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
+   Args.push_back(Tmp.c_str());
+   StartSize += Tmp.length();
+
+   // Stick in any custom dpkg options
+   Configuration::Item const *Opts = _config->Tree("DPkg::Options");
+   if (Opts != 0)
+   {
+      Opts = Opts->Child;
+      for (; Opts != 0; Opts = Opts->Next)
+      {
+	 if (Opts->Value.empty() == true)
+	    continue;
+	 Args.push_back(Opts->Value.c_str());
+	 StartSize += Opts->Value.length();
+      }
+   }
+   size_t const BaseArgs = Args.size();
+
    // this loop is runs once per operation
    for (vector<Item>::const_iterator I = List.begin(); I != List.end();)
    {
@@ -908,11 +930,12 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 for (; J != List.end() && J->Op == I->Op; ++J)
 	    /* nothing */;
 
-      // Generate the argument list
-      const char *Args[MaxArgs + 50];
       // keep track of allocated strings for multiarch package names
-      char *Packages[MaxArgs + 50];
-      unsigned int pkgcount = 0;
+      std::vector<char *> Packages;
+
+      // start with the baseset of arguments
+      unsigned long Size = StartSize;
+      Args.erase(Args.begin() + BaseArgs, Args.end());
 
       // Now check if we are within the MaxArgs limit
       //
@@ -922,91 +945,67 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       // - with the split they may now be configured in different
       //   runs 
       if (J - I > (signed)MaxArgs)
+      {
 	 J = I + MaxArgs;
-      
-      unsigned int n = 0;
-      unsigned long Size = 0;
-      string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
-      Args[n++] = Tmp.c_str();
-      Size += strlen(Args[n-1]);
-      
-      // Stick in any custom dpkg options
-      Configuration::Item const *Opts = _config->Tree("DPkg::Options");
-      if (Opts != 0)
+	 Args.reserve(MaxArgs + 10);
+      }
+      else
       {
-	 Opts = Opts->Child;
-	 for (; Opts != 0; Opts = Opts->Next)
-	 {
-	    if (Opts->Value.empty() == true)
-	       continue;
-	    Args[n++] = Opts->Value.c_str();
-	    Size += Opts->Value.length();
-	 }	 
+	 Args.reserve((J - I) + 10);
       }
+
       
-      char status_fd_buf[20];
       int fd[2];
       pipe(fd);
-      
-      Args[n++] = "--status-fd";
-      Size += strlen(Args[n-1]);
+
+#define ADDARG(X) Args.push_back(X); Size += strlen(X)
+#define ADDARGC(X) Args.push_back(X); Size += sizeof(X) - 1
+
+      ADDARGC("--status-fd");
+      char status_fd_buf[20];
       snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]);
-      Args[n++] = status_fd_buf;
-      Size += strlen(Args[n-1]);
+      ADDARG(status_fd_buf);
 
       switch (I->Op)
       {
 	 case Item::Remove:
-	 Args[n++] = "--force-depends";
-	 Size += strlen(Args[n-1]);
-	 Args[n++] = "--force-remove-essential";
-	 Size += strlen(Args[n-1]);
-	 Args[n++] = "--remove";
-	 Size += strlen(Args[n-1]);
+	 ADDARGC("--force-depends");
+	 ADDARGC("--force-remove-essential");
+	 ADDARGC("--remove");
 	 break;
 	 
 	 case Item::Purge:
-	 Args[n++] = "--force-depends";
-	 Size += strlen(Args[n-1]);
-	 Args[n++] = "--force-remove-essential";
-	 Size += strlen(Args[n-1]);
-	 Args[n++] = "--purge";
-	 Size += strlen(Args[n-1]);
+	 ADDARGC("--force-depends");
+	 ADDARGC("--force-remove-essential");
+	 ADDARGC("--purge");
 	 break;
 	 
 	 case Item::Configure:
-	 Args[n++] = "--configure";
-	 Size += strlen(Args[n-1]);
+	 ADDARGC("--configure");
 	 break;
 
 	 case Item::ConfigurePending:
-	 Args[n++] = "--configure";
-	 Size += strlen(Args[n-1]);
-	 Args[n++] = "--pending";
-	 Size += strlen(Args[n-1]);
+	 ADDARGC("--configure");
+	 ADDARGC("--pending");
 	 break;
 
 	 case Item::TriggersPending:
-	 Args[n++] = "--triggers-only";
-	 Size += strlen(Args[n-1]);
-	 Args[n++] = "--pending";
-	 Size += strlen(Args[n-1]);
+	 ADDARGC("--triggers-only");
+	 ADDARGC("--pending");
 	 break;
 
 	 case Item::Install:
-	 Args[n++] = "--unpack";
-	 Size += strlen(Args[n-1]);
-	 Args[n++] = "--auto-deconfigure";
-	 Size += strlen(Args[n-1]);
+	 ADDARGC("--unpack");
+	 ADDARGC("--auto-deconfigure");
 	 break;
       }
 
       if (NoTriggers == true && I->Op != Item::TriggersPending &&
 	  I->Op != Item::ConfigurePending)
       {
-	 Args[n++] = "--no-triggers";
-	 Size += strlen(Args[n-1]);
+	 ADDARGC("--no-triggers");
       }
+#undef ADDARGC
 
       // Write in the file or package names
       if (I->Op == Item::Install)
@@ -1015,10 +1014,10 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 {
 	    if (I->File[0] != '/')
 	       return _error->Error("Internal Error, Pathname to install is not absolute '%s'",I->File.c_str());
-	    Args[n++] = I->File.c_str();
-	    Size += strlen(Args[n-1]);
+	    Args.push_back(I->File.c_str());
+	    Size += I->File.length();
 	 }
-      }      
+      }
       else
       {
 	 string const nativeArch = _config->Find("APT::Architecture");
@@ -1030,29 +1029,35 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	    if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end())
 	       continue;
 	    if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))
-	       Args[n++] = I->Pkg.Name();
+	    {
+	       char const * const name = I->Pkg.Name();
+	       ADDARG(name);
+	    }
 	    else
 	    {
-	       Packages[pkgcount] = strdup(I->Pkg.FullName(false).c_str());
-	       Args[n++] = Packages[pkgcount++];
+	       char * const fullname = strdup(I->Pkg.FullName(false).c_str());
+	       Packages.push_back(fullname);
+	       ADDARG(fullname);
 	    }
-	    Size += strlen(Args[n-1]);
 	 }
 	 // skip configure action if all sheduled packages disappeared
 	 if (oldSize == Size)
 	    continue;
       }
-      Args[n] = 0;
+#undef ADDARG
+
       J = I;
       
       if (_config->FindB("Debug::pkgDPkgPM",false) == true)
       {
-	 for (unsigned int k = 0; k != n; k++)
-	    clog << Args[k] << ' ';
+	 for (std::vector<const char *>::const_iterator a = Args.begin();
+	      a != Args.end(); ++a)
+	    clog << *a << ' ';
 	 clog << endl;
 	 continue;
       }
-      
+      Args.push_back(NULL);
+
       cout << flush;
       clog << flush;
       cerr << flush;
@@ -1162,7 +1167,7 @@ bool pkgDPkgPM::Go(int OutStatusFd)
 	 /* No Job Control Stop Env is a magic dpkg var that prevents it
 	    from using sigstop */
 	 putenv((char *)"DPKG_NO_TSTP=yes");
-	 execvp(Args[0],(char **)Args);
+	 execvp(Args[0], (char**) &Args[0]);
 	 cerr << "Could not exec dpkg!" << endl;
 	 _exit(100);
       }      
@@ -1188,10 +1193,11 @@ bool pkgDPkgPM::Go(int OutStatusFd)
       sigemptyset(&sigmask);
       sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask);
 
-      /* clean up the temporary allocation for multiarch package names in
-         the parent, so we don't leak memory when we return. */
-      for (unsigned int i = 0; i < pkgcount; i++)
-	 free(Packages[i]);
+      /* free vectors (and therefore memory) as we don't need the included data anymore */
+      for (std::vector<char *>::const_iterator p = Packages.begin();
+	   p != Packages.end(); ++p)
+	 free(*p);
+      Packages.clear();
 
       // the result of the waitpid call
       int res;

+ 6 - 7
apt-pkg/init.cc

@@ -81,13 +81,12 @@ bool pkgInitConfig(Configuration &Cnf)
    Cnf.CndSet("Dir::Log::Terminal","term.log");
    Cnf.CndSet("Dir::Log::History","history.log");
 
-   if (Cnf.Exists("Dir::Ignore-Files-Silently") == false)
-   {
-      Cnf.Set("Dir::Ignore-Files-Silently::", "~$");
-      Cnf.Set("Dir::Ignore-Files-Silently::", "\\.disabled$");
-      Cnf.Set("Dir::Ignore-Files-Silently::", "\\.bak$");
-      Cnf.Set("Dir::Ignore-Files-Silently::", "\\.dpkg-[a-z]+$");
-   }
+   Cnf.Set("Dir::Ignore-Files-Silently::", "~$");
+   Cnf.Set("Dir::Ignore-Files-Silently::", "\\.disabled$");
+   Cnf.Set("Dir::Ignore-Files-Silently::", "\\.bak$");
+   Cnf.Set("Dir::Ignore-Files-Silently::", "\\.dpkg-[a-z]+$");
+   Cnf.Set("Dir::Ignore-Files-Silently::", "\\.save$");
+   Cnf.Set("Dir::Ignore-Files-Silently::", "\\.orig$");
 
    // Default cdrom mount point
    Cnf.CndSet("Acquire::cdrom::mount", "/media/cdrom/");

+ 2 - 1
apt-pkg/policy.cc

@@ -64,7 +64,8 @@ pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner)
       {
 	 if ((F->Archive != 0 && vm.ExpressionMatches(DefRel, F.Archive()) == true) ||
 	     (F->Codename != 0 && vm.ExpressionMatches(DefRel, F.Codename()) == true) ||
-	     (F->Version != 0 && vm.ExpressionMatches(DefRel, F.Version()) == true))
+	     (F->Version != 0 && vm.ExpressionMatches(DefRel, F.Version()) == true) ||
+	     (DefRel.length() > 2 && DefRel[1] == '='))
 	    found = true;
       }
       if (found == false)

+ 1 - 1
apt-pkg/sourcelist.cc

@@ -266,7 +266,7 @@ bool pkgSourceList::ReadAppend(string File)
       // CNC:2003-02-20 - Do not break if '#' is inside [].
       for (I = Buffer; *I != 0 && *I != '#'; I++)
          if (*I == '[')
-	    for (I++; *I != 0 && *I != ']'; I++);
+	    I = strchr(I + 1, ']');
       *I = 0;
       
       const char *C = _strstrip(Buffer);

+ 34 - 25
cmdline/apt-get.cc

@@ -1684,8 +1684,9 @@ bool DoAutomaticRemove(CacheFile &Cache)
 	    // install it in the first place, so nuke it instead of show it
 	    if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
 	    {
+	       if (Pkg.CandVersion() != 0)
+	          tooMuch.insert(Pkg);
 	       Cache->MarkDelete(Pkg, false);
-	       tooMuch.insert(Pkg);
 	    }
 	    // only show stuff in the list that is not yet marked for removal
 	    else if(hideAutoRemove == false && Cache[Pkg].Delete() == false) 
@@ -1709,33 +1710,41 @@ bool DoAutomaticRemove(CacheFile &Cache)
       bool Changed;
       do {
 	 Changed = false;
-	 for (APT::PackageSet::const_iterator P = tooMuch.begin();
-	      P != tooMuch.end() && Changed == false; ++P)
+	 for (APT::PackageSet::const_iterator Pkg = tooMuch.begin();
+	      Pkg != tooMuch.end() && Changed == false; ++Pkg)
 	 {
-	    for (pkgCache::DepIterator R = P.RevDependsList();
-		 R.end() == false; ++R)
-	    {
-	       if (R.IsNegative() == true ||
-		   Cache->IsImportantDep(R) == false)
-		  continue;
-	       pkgCache::PkgIterator N = R.ParentPkg();
-	       if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
-		  continue;
-	       if (Debug == true)
-		  std::clog << "Save " << P << " as another installed garbage package depends on it" << std::endl;
-	       Cache->MarkInstall(P, false);
-	       if(hideAutoRemove == false)
+	    APT::PackageSet too;
+	    too.insert(Pkg);
+	    for (pkgCache::PrvIterator Prv = Cache[Pkg].CandidateVerIter(Cache).ProvidesList();
+		 Prv.end() == false; ++Prv)
+	       too.insert(Prv.ParentPkg());
+	    for (APT::PackageSet::const_iterator P = too.begin();
+		 P != too.end() && Changed == false; ++P) {
+	       for (pkgCache::DepIterator R = P.RevDependsList();
+		    R.end() == false; ++R)
 	       {
-		  ++autoRemoveCount;
-		  if (smallList == false)
-		  {
-		     autoremovelist += P.FullName(true) + " ";
-		     autoremoveversions += string(Cache[P].CandVersion) + "\n";
-		  }
+		  if (R.IsNegative() == true ||
+		      Cache->IsImportantDep(R) == false)
+		     continue;
+		 pkgCache::PkgIterator N = R.ParentPkg();
+		 if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
+		    continue;
+		 if (Debug == true)
+		    std::clog << "Save " << Pkg << " as another installed garbage package depends on it" << std::endl;
+		 Cache->MarkInstall(Pkg, false);
+		 if (hideAutoRemove == false)
+		 {
+		    ++autoRemoveCount;
+		    if (smallList == false)
+		    {
+		       autoremovelist += Pkg.FullName(true) + " ";
+		       autoremoveversions += string(Cache[Pkg].CandVersion) + "\n";
+		    }
+		 }
+		 tooMuch.erase(Pkg);
+		 Changed = true;
+		 break;
 	       }
-	       tooMuch.erase(P);
-	       Changed = true;
-	       break;
 	    }
 	 }
       } while (Changed == true);

+ 28 - 6
debian/changelog

@@ -1,21 +1,43 @@
 apt (0.8.15.9) UNRELEASED; urgency=low
 
+  [ David Kalnischkies ]
+  * Symbol file update
+  * doc/apt-get.8.xml:
+    - change wording of autoremove description as suggested
+      by Robert Simmons, thanks! (Closes: #641490)
+  * apt-pkg/deb/dpkgpm.cc:
+    - use std::vector instead of fixed size arrays to store args and
+      multiarch-packagename strings
+    - load the dpkg base arguments only one time and reuse them later
+  * cmdline/apt-get.cc:
+    - follow Provides in the evaluation of saving candidates, too, for
+      statisfying garbage package dependencies (Closes: #640590)
+  * apt-pkg/algorithms.cc:
+    - if a package is garbage, don't try to save it with FixByInstall
+  * apt-pkg/init.cc:
+    - silently ignore *.orig and *.save files by default
+  * apt-pkg/policy.cc:
+    - accept generic release pin expressions again in -t (Closes: #644166)
+  * apt-pkg/deb/debmetaindex.cc:
+    - none is a separator, not a language: no need for Index (Closes: #624218)
+  * apt-pkg/aptconfiguration.cc:
+    - do not builtin languages only if none is forced (Closes: #643787)
+  * doc/apt.conf.5.xml:
+    - apply spelling fix by Kevin Lyda, thanks! (Closes: #644104)
+
   [ Christian Perrier ]
   * Fix spelling error (sensée) in French translation. Thanks
     to Corentin Le Gall for spotting it.
-  
-  [ David Kalnischkies ]
-  * Symbol file update
 
   [ Colin Watson ]
   * ftparchive/cachedb.cc:
     - fix buffersize in bytes2hex
-  
+
   [ Michael Vogt ]
   * ftparchive/cachedb.cc:
     - make buffer fully dynamic (thanks to Colin Watson)
-  
- -- Christian Perrier <bubulle@debian.org>  Wed, 14 Sep 2011 20:13:40 +0200
+
+ -- David Kalnischkies <kalnischkies@gmail.com>  Wed, 05 Oct 2011 23:07:35 +0200
 
 apt (0.8.15.8) unstable; urgency=low
 

+ 1 - 1
doc/apt-get.8.xml

@@ -317,7 +317,7 @@
 
      <varlistentry><term>autoremove</term>
      <listitem><para><literal>autoremove</literal> is used to remove packages that were automatically
-     installed to satisfy dependencies for some package and that are no more needed.</para></listitem>
+     installed to satisfy dependencies for other packages and are now no longer needed.</para></listitem>
      </varlistentry>
 
      <varlistentry><term>changelog</term>

+ 1 - 1
doc/apt.conf.5.xml

@@ -294,7 +294,7 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
 	 <para>Two sub-options to limit the use of PDiffs are also available:
 	 With <literal>FileLimit</literal> can be specified how many PDiff files
 	 are downloaded at most to patch a file. <literal>SizeLimit</literal>
-	 on the other hand is the maximum precentage of the size of all patches
+	 on the other hand is the maximum percentage of the size of all patches
 	 compared to the size of the targeted file. If one of these limits is
 	 exceeded the complete file is downloaded instead of the patches.
 	 </para></listitem>

Разница между файлами не показана из-за своего большого размера
+ 477 - 389
doc/po/apt-doc.pot


Разница между файлами не показана из-за своего большого размера
+ 587 - 405
doc/po/de.po


+ 1 - 1
doc/po/es.po

@@ -6152,7 +6152,7 @@ msgid ""
 "Two sub-options to limit the use of PDiffs are also available: With "
 "<literal>FileLimit</literal> can be specified how many PDiff files are "
 "downloaded at most to patch a file. <literal>SizeLimit</literal> on the "
-"other hand is the maximum precentage of the size of all patches compared to "
+"other hand is the maximum percentage of the size of all patches compared to "
 "the size of the targeted file. If one of these limits is exceeded the "
 "complete file is downloaded instead of the patches."
 msgstr ""

+ 1 - 1
doc/po/fr.po

@@ -6094,7 +6094,7 @@ msgid ""
 "Two sub-options to limit the use of PDiffs are also available: With "
 "<literal>FileLimit</literal> can be specified how many PDiff files are "
 "downloaded at most to patch a file. <literal>SizeLimit</literal> on the "
-"other hand is the maximum precentage of the size of all patches compared to "
+"other hand is the maximum percentage of the size of all patches compared to "
 "the size of the targeted file. If one of these limits is exceeded the "
 "complete file is downloaded instead of the patches."
 msgstr ""

+ 1 - 1
doc/po/it.po

@@ -4575,7 +4575,7 @@ msgid ""
 "Two sub-options to limit the use of PDiffs are also available: With "
 "<literal>FileLimit</literal> can be specified how many PDiff files are "
 "downloaded at most to patch a file. <literal>SizeLimit</literal> on the "
-"other hand is the maximum precentage of the size of all patches compared to "
+"other hand is the maximum percentage of the size of all patches compared to "
 "the size of the targeted file. If one of these limits is exceeded the "
 "complete file is downloaded instead of the patches."
 msgstr ""

+ 1 - 1
doc/po/ja.po

@@ -6258,7 +6258,7 @@ msgid ""
 "Two sub-options to limit the use of PDiffs are also available: With "
 "<literal>FileLimit</literal> can be specified how many PDiff files are "
 "downloaded at most to patch a file. <literal>SizeLimit</literal> on the "
-"other hand is the maximum precentage of the size of all patches compared to "
+"other hand is the maximum percentage of the size of all patches compared to "
 "the size of the targeted file. If one of these limits is exceeded the "
 "complete file is downloaded instead of the patches."
 msgstr ""

+ 1 - 1
doc/po/pl.po

@@ -5880,7 +5880,7 @@ msgid ""
 "Two sub-options to limit the use of PDiffs are also available: With "
 "<literal>FileLimit</literal> can be specified how many PDiff files are "
 "downloaded at most to patch a file. <literal>SizeLimit</literal> on the "
-"other hand is the maximum precentage of the size of all patches compared to "
+"other hand is the maximum percentage of the size of all patches compared to "
 "the size of the targeted file. If one of these limits is exceeded the "
 "complete file is downloaded instead of the patches."
 msgstr ""

+ 1 - 1
doc/po/pt.po

@@ -6071,7 +6071,7 @@ msgid ""
 "Two sub-options to limit the use of PDiffs are also available: With "
 "<literal>FileLimit</literal> can be specified how many PDiff files are "
 "downloaded at most to patch a file. <literal>SizeLimit</literal> on the "
-"other hand is the maximum precentage of the size of all patches compared to "
+"other hand is the maximum percentage of the size of all patches compared to "
 "the size of the targeted file. If one of these limits is exceeded the "
 "complete file is downloaded instead of the patches."
 msgstr ""

+ 1 - 1
doc/po/pt_BR.po

@@ -4636,7 +4636,7 @@ msgid ""
 "Two sub-options to limit the use of PDiffs are also available: With "
 "<literal>FileLimit</literal> can be specified how many PDiff files are "
 "downloaded at most to patch a file. <literal>SizeLimit</literal> on the "
-"other hand is the maximum precentage of the size of all patches compared to "
+"other hand is the maximum percentage of the size of all patches compared to "
 "the size of the targeted file. If one of these limits is exceeded the "
 "complete file is downloaded instead of the patches."
 msgstr ""

+ 21 - 2
test/integration/test-bug-407511-fail-invalid-default-release

@@ -23,18 +23,31 @@ getreleaseversionfromsuite() {
 	fi
 }
 
+getlabelfromsuite() {
+	if [ "$SUITE" = 'unstable' ]; then
+		echo -n 'UnstableTestcases'
+	else
+		echo -n 'Testcases'
+	fi
+}
+
 setupaptarchive
 
 passdist() {
-	msgtest "Test that target-release is accepted" $1
+	msgtest 'Test that target-release is accepted' $1
 	aptget dist-upgrade -t $1 -qq && msgpass || msgfail
+	msgtest 'Test that target-release pins with' $1
+	aptcache policy -t $1 | grep -q ' 990' && msgpass || msgfail
 }
 
 faildist() {
-	msgtest "Test that target-release is refused" $1
+	msgtest 'Test that target-release is refused' $1
 	aptget dist-upgrade -t $1 -qq 2> /dev/null && msgfail || msgpass
 }
 
+msgtest 'Test that no default-release is active in this test' 'setup'
+aptcache policy | grep -q ' 990' && msgfall || msgpass
+
 passdist unstable
 passdist sid
 faildist sidd
@@ -45,3 +58,9 @@ passdist 42*
 passdist 4*.0
 faildist 21.0
 faildist 21*
+# we accept, but don't validate the following
+passdist a=unstable
+passdist n=sid
+passdist v=42.0
+passdist c=main
+passdist l=UnstableTestcases

+ 87 - 0
test/integration/test-bug-624218-Translation-file-handling

@@ -0,0 +1,87 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386'
+
+buildsimplenativepackage 'coolstuff' 'all' '1.0' 'unstable'
+
+setupaptarchive
+
+changetowebserver
+
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'No download of non-existent locals' 'with Index'
+LC_ALL="" aptget update -o Acquire::Languages=en | grep -q -e 'Translation-[^e][^n] ' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of existent locals' 'with Index'
+LC_ALL="" aptget update | grep -q -e 'Translation-en ' && msgpass || msgfail
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of en in LC_ALL=C' 'with Index'
+LC_ALL=C aptget update | grep -q -e 'Translation-en ' && msgpass || msgfail
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of en as forced language' 'with Index'
+aptget update -o Acquire::Languages=en | grep -q -e 'Translation-en ' && msgpass || msgfail
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of nothing else in forced language' 'with Index'
+aptget update -o Acquire::Languages=en | grep -q -e 'Translation-[^e][^n] ' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download no Translation- if forced language is non-existent' 'with Index'
+aptget update -o Acquire::Languages=ast_DE | grep -q -e 'Translation-' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of nothing if none is forced' 'with Index'
+aptget update -o Acquire::Languages=none | grep -q -e 'Translation' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists
+
+sed -i '/i18n\/Index$/ d' $(find aptarchive -name 'Release')
+signreleasefiles
+
+# we have to try as not every archive includes the i18n Index in the Release file - if it has one at all
+msgtest 'Download no Translation- if forced language is non-existent' 'with not-announced Index'
+aptget update -o Acquire::Languages=ast_DE | grep -q -e 'Translation-' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists
+
+find aptarchive -name 'Index' -delete
+
+msgtest 'Download of en as forced language' 'without Index'
+aptget update -o Acquire::Languages=en | grep -q -e 'Translation-en ' && msgpass || msgfail
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of nothing else in forced language' 'without Index'
+aptget update -o Acquire::Languages=en | grep -q -e 'Translation-[^e][^n] ' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of ast_DE as forced language' 'without Index'
+aptget update -o Acquire::Languages=ast_DE | grep -q -e 'Translation-ast_DE$' && msgpass || msgfail
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of nothing else in forced language' 'without Index'
+aptget update -o Acquire::Languages=ast_DE | grep -q -e 'Translation-[^a][^s]' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists
+
+msgtest 'Download of nothing if none is forced' 'without Index'
+aptget update -o Acquire::Languages=none | grep -q -e 'Translation' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists
+
+mkdir -p rootdir/var/lib/apt/lists
+touch rootdir/var/lib/apt/lists/localhost:8080_dists_unstable_main_i18n_Translation-ast_DE
+
+msgtest 'Download of builtin files' 'without Index'
+aptget update | grep -q -e 'Translation-ast_DE' && msgpass || msgfail
+rm -rf rootdir/var/lib/apt/lists
+
+mkdir -p rootdir/var/lib/apt/lists
+touch rootdir/var/lib/apt/lists/localhost:8080_dists_unstable_main_i18n_Translation-ast_DE
+
+msgtest 'Download of nothing (even builtin) if none is forced' 'without Index'
+aptget update -o Acquire::Languages=none | grep -q -e 'Translation' && msgfail || msgpass
+rm -rf rootdir/var/lib/apt/lists

+ 50 - 8
test/integration/test-policy-pinning

@@ -25,28 +25,70 @@ testequalpolicy() {
 Pinned packages:" aptcache policy $*
 }
 
-aptget update -qq
+aptgetupdate() {
+	# just to be sure that no old files are used
+	rm -rf rootdir/var/lib/apt
+	if aptget update -qq 2>&1 | grep '^E: '; then
+		msgwarn 'apt-get update failed with an error'
+	fi
+}
+
+### not signed archive
+
+aptgetupdate
 testequalpolicy 100 500
 testequalpolicy 990 500 -t now
 
 sed -i aptarchive/Release -e 1i"NotAutomatic: yes"
-aptget update -qq
+aptgetupdate
 
 testequalpolicy 100 1 -o Test=NotAutomatic
 testequalpolicy 990 1 -o Test=NotAutomatic -t now
 
 sed -i aptarchive/Release -e 1i"ButAutomaticUpgrades: yes"
-aptget update -qq
+aptgetupdate
 
 testequalpolicy 100 100 -o Test=ButAutomaticUpgrades
 testequalpolicy 990 100 -o Test=ButAutomaticUpgrades -t now
 
 sed -i aptarchive/Release -e 's#NotAutomatic: yes#NotAutomatic: no#' -e '/ButAutomaticUpgrades: / d'
-aptget update -qq
+aptgetupdate
 
 testequalpolicy 100 500 -o Test=Automatic
 testequalpolicy 990 500 -o Test=Automatic -t now
 
+sed -i aptarchive/Release -e '/NotAutomatic: / d' -e '/ButAutomaticUpgrades: / d'
+
+### signed but no key in trusted
+
+signreleasefiles 'Marvin Paranoid'
+aptgetupdate
+testequalpolicy 100 500
+testequalpolicy 990 500 -t now
+
+sed -i aptarchive/Release -e 1i"NotAutomatic: yes"
+signreleasefiles 'Marvin Paranoid'
+aptgetupdate
+
+testequalpolicy 100 1 -o Test=NotAutomatic
+testequalpolicy 990 1 -o Test=NotAutomatic -t now
+
+sed -i aptarchive/Release -e 1i"ButAutomaticUpgrades: yes"
+signreleasefiles 'Marvin Paranoid'
+aptgetupdate
+
+testequalpolicy 100 100 -o Test=ButAutomaticUpgrades
+testequalpolicy 990 100 -o Test=ButAutomaticUpgrades -t now
+
+sed -i aptarchive/Release -e 's#NotAutomatic: yes#NotAutomatic: no#' -e '/ButAutomaticUpgrades: / d'
+signreleasefiles 'Marvin Paranoid'
+aptgetupdate
+
+testequalpolicy 100 500 -o Test=Automatic
+testequalpolicy 990 500 -o Test=Automatic -t now
+
+### signed and valid key
+
 buildsimplenativepackage "coolstuff" "all" "1.0" "stable"
 buildsimplenativepackage "coolstuff" "all" "2.0~bpo1" "backports"
 
@@ -132,7 +174,7 @@ Pin-Priority: -1" > rootdir/etc/apt/preferences
 rm rootdir/etc/apt/preferences
 sed -i aptarchive/dists/backports/Release -e 1i"NotAutomatic: yes"
 signreleasefiles
-aptget update -qq
+aptgetupdate
 
 testequalpolicycoolstuff "" "1.0" 1 500 0 "" -o Test=NotAutomatic
 testequalpolicycoolstuff "" "1.0" 1 990 0 "" -o Test=NotAutomatic -t stable
@@ -160,7 +202,7 @@ testequalpolicycoolstuff "" "1.0" 1 990 600 "2.0~bpo1" -o Test=NotAutomatic -t s
 rm rootdir/etc/apt/preferences
 sed -i aptarchive/dists/backports/Release -e 1i"ButAutomaticUpgrades: yes"
 signreleasefiles
-aptget update -qq
+aptgetupdate
 
 testequalpolicycoolstuff "" "1.0" 100 500 0 "" -o Test=ButAutomaticUpgrades
 testequalpolicycoolstuff "" "1.0" 100 990 0 "" -o Test=ButAutomaticUpgrades -t stable
@@ -206,7 +248,7 @@ setupaptarchive
 
 sed -i aptarchive/dists/backports/Release -e 1i"NotAutomatic: yes"
 signreleasefiles
-aptget update -qq
+aptgetupdate
 
 testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 1 500 0 "" "2.0~bpo2" -o Test=NotAutomatic
 testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo1" 1 990 0 "" "2.0~bpo2" -o Test=NotAutomatic -t stable
@@ -214,7 +256,7 @@ testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 990 500 0 "" "2.0~bpo2" -o Test=N
 
 sed -i aptarchive/dists/backports/Release -e 1i"ButAutomaticUpgrades: yes"
 signreleasefiles
-aptget update -qq
+aptgetupdate
 
 testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 100 500 0 "" "2.0~bpo2" -o Test=ButAutomaticUpgrades
 testequalpolicycoolstuff "2.0~bpo1" "2.0~bpo2" 100 990 0 "" "2.0~bpo2" -o Test=ButAutomaticUpgrades -t stable

+ 15 - 0
test/libapt/assert.h

@@ -54,6 +54,21 @@ void assertEqualsOr2(int const &expect1, int const &expect2, unsigned int const
 }
 
 
+#define equalsOr3(w,x,y,z) assertEqualsOr3(x, y, z, w, __LINE__)
+
+template < typename X, typename Y >
+void OutputAssertEqualOr3(X expect1, X expect2, X expect3, char const* compare, Y get, unsigned long const &line) {
+	std::cerr << "Test FAILED: »" << expect1 << "« or »" << expect2 << "« or »" << expect3 << "« " << compare << " »" << get << "« at line " << line << std::endl;
+}
+
+template < typename X, typename Y >
+void assertEqualsOr3(X expect1, X expect2, X expect3, Y get, unsigned long const &line) {
+	if (expect1 == get || expect2 == get || expect3 == get)
+		return;
+	OutputAssertEqualOr3(expect1, expect2, expect3, "==", get, line);
+}
+
+
 // simple helper to quickly output a vectors
 template < typename X >
 void dumpVector(X vec) {

+ 9 - 3
test/libapt/getlanguages_test.cc

@@ -126,13 +126,19 @@ int main(int argc,char *argv[])
 
 	_config->Set("Dir::State::lists", argv[1]);
 	vec = APT::Configuration::getLanguages(true, false, env);
-	equals(vec.size(), 6);
+	equals(vec.size(), 7);
 	equals(vec[0], "de_DE");
 	equals(vec[1], "de");
 	equals(vec[2], "en");
 	equals(vec[3], "none");
-	equalsOr2(vec[4], "pt", "tr");
-	equalsOr2(vec[5], "tr", "pt");
+	equalsOr3(vec[4], "pt", "tr", "ast_DE");
+	equalsOr3(vec[5], "tr", "pt", "ast_DE");
+	equalsOr3(vec[6], "tr", "pt", "ast_DE");
+
+	_config->Set("Acquire::Languages", "none");
+	vec = APT::Configuration::getLanguages(true, false, env);
+	equals(vec.size(), 0);
+	_config->Set("Acquire::Languages", "");
 
 	_config->Set("Dir::State::lists", "/non-existing-dir");
 	_config->Set("Acquire::Languages::1", "none");

+ 2 - 1
test/libapt/run-tests

@@ -64,7 +64,8 @@ do
 		touch "${tmppath}/ftp.de.debian.org_debian_dists_sid_main_i18n_Translation-tr" \
 			"${tmppath}/ftp.de.debian.org_debian_dists_sid_main_i18n_Translation-pt" \
 			"${tmppath}/ftp.de.debian.org_debian_dists_sid_main_i18n_Translation-se~" \
-			"${tmppath}/ftp.de.debian.org_debian_dists_sid_main_i18n_Translation-st.bak"
+			"${tmppath}/ftp.de.debian.org_debian_dists_sid_main_i18n_Translation-st.bak" \
+			"${tmppath}/ftp.de.debian.org_debian_dists_sid_main_i18n_Translation-ast_DE"
 	elif [ $name = "CompareVersion${EXT}" ]; then
 		tmppath="${DIR}/versions.lst"
 	fi