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

+ 9 - 30
apt-pkg/acquire-worker.cc

@@ -467,40 +467,19 @@ bool pkgAcquire::Worker::SendConfiguration()
 
 
    if (OutFd == -1)
    if (OutFd == -1)
       return false;
       return false;
-   
-   string Message = "601 Configuration\n";
-   Message.reserve(2000);
 
 
-   /* Write out all of the configuration directives by walking the 
+   /* Write out all of the configuration directives by walking the
       configuration tree */
       configuration tree */
-   const Configuration::Item *Top = _config->Tree(0);
-   for (; Top != 0;)
-   {
-      if (Top->Value.empty() == false)
-      {
-	 string Line = "Config-Item: " + QuoteString(Top->FullTag(),"=\"\n") + "=";
-	 Line += QuoteString(Top->Value,"\n") + '\n';
-	 Message += Line;
-      }
-      
-      if (Top->Child != 0)
-      {
-	 Top = Top->Child;
-	 continue;
-      }
-      
-      while (Top != 0 && Top->Next == 0)
-	 Top = Top->Parent;
-      if (Top != 0)
-	 Top = Top->Next;
-   }   
-   Message += '\n';
+   std::ostringstream Message;
+   Message << "601 Configuration\n";
+   _config->Dump(Message, NULL, "Config-Item: %F=%V\n", false);
+   Message << '\n';
 
 
    if (Debug == true)
    if (Debug == true)
-      clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl;
-   OutQueue += Message;
-   OutReady = true; 
-   
+      clog << " -> " << Access << ':' << QuoteString(Message.str(),"\n") << endl;
+   OutQueue += Message.str();
+   OutReady = true;
+
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 2 - 19
apt-pkg/cdrom.cc

@@ -409,27 +409,10 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf)
    
    
    /* Write out all of the configuration directives by walking the
    /* Write out all of the configuration directives by walking the
       configuration tree */
       configuration tree */
-   const Configuration::Item *Top = Cnf.Tree(0);
-   for (; Top != 0;)
-   {
-      // Print the config entry
-      if (Top->Value.empty() == false)
-	 Out <<  Top->FullTag() + " \"" << Top->Value << "\";" << endl;
-      
-      if (Top->Child != 0)
-      {
-	 Top = Top->Child;
-	 continue;
-      }
-      
-      while (Top != 0 && Top->Next == 0)
-	 Top = Top->Parent;
-      if (Top != 0)
-	 Top = Top->Next;
-   }   
+   _config->Dump(Out, NULL, "%f \"%v\";\n", false);
 
 
    Out.close();
    Out.close();
-   
+
    if (FileExists(DFile) == true && link(DFile.c_str(),string(DFile + '~').c_str()) != 0)
    if (FileExists(DFile) == true && link(DFile.c_str(),string(DFile + '~').c_str()) != 0)
       return _error->Errno("link", "Failed to link %s to %s~", DFile.c_str(), DFile.c_str());
       return _error->Errno("link", "Failed to link %s to %s~", DFile.c_str(), DFile.c_str());
    if (rename(NewFile.c_str(),DFile.c_str()) != 0)
    if (rename(NewFile.c_str(),DFile.c_str()) != 0)

+ 111 - 38
apt-pkg/contrib/configuration.cc

@@ -171,48 +171,60 @@ string Configuration::Find(const char *Name,const char *Default) const
 string Configuration::FindFile(const char *Name,const char *Default) const
 string Configuration::FindFile(const char *Name,const char *Default) const
 {
 {
    const Item *RootItem = Lookup("RootDir");
    const Item *RootItem = Lookup("RootDir");
-   std::string rootDir =  (RootItem == 0) ? "" : RootItem->Value;
-   if(rootDir.size() > 0 && rootDir[rootDir.size() - 1] != '/')
-     rootDir.push_back('/');
+   std::string result =  (RootItem == 0) ? "" : RootItem->Value;
+   if(result.empty() == false && result[result.size() - 1] != '/')
+     result.push_back('/');
 
 
    const Item *Itm = Lookup(Name);
    const Item *Itm = Lookup(Name);
    if (Itm == 0 || Itm->Value.empty() == true)
    if (Itm == 0 || Itm->Value.empty() == true)
    {
    {
-      if (Default == 0)
-	 return rootDir;
-      else
-	 return rootDir + Default;
+      if (Default != 0)
+	 result.append(Default);
    }
    }
-   
-   string val = Itm->Value;
-   while (Itm->Parent != 0)
+   else
    {
    {
-      if (Itm->Parent->Value.empty() == true)
+      string val = Itm->Value;
+      while (Itm->Parent != 0)
       {
       {
-	 Itm = Itm->Parent;
-	 continue;
-      }
+	 if (Itm->Parent->Value.empty() == true)
+	 {
+	    Itm = Itm->Parent;
+	    continue;
+	 }
+
+	 // Absolute
+	 if (val.length() >= 1 && val[0] == '/')
+	 {
+	    if (val.compare(0, 9, "/dev/null") == 0)
+	       val.erase(9);
+	    break;
+	 }
 
 
-      // Absolute
-      if (val.length() >= 1 && val[0] == '/')
-         break;
+	 // ~/foo or ./foo
+	 if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
+	    break;
 
 
-      // ~/foo or ./foo 
-      if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
-	 break;
-	 
-      // ../foo 
-      if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
-	 break;
-      
-      if (Itm->Parent->Value.end()[-1] != '/')
-	 val.insert(0, "/");
+	 // ../foo
+	 if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
+	    break;
+
+	 if (Itm->Parent->Value.end()[-1] != '/')
+	    val.insert(0, "/");
 
 
-      val.insert(0, Itm->Parent->Value);
-      Itm = Itm->Parent;
+	 val.insert(0, Itm->Parent->Value);
+	 Itm = Itm->Parent;
+      }
+      result.append(val);
    }
    }
 
 
-   return rootDir + val;
+   // do some normalisation by removing // and /./ from the path
+   size_t found = string::npos;
+   while ((found = result.find("/./")) != string::npos)
+      result.replace(found, 3, "/");
+   while ((found = result.find("//")) != string::npos)
+      result.replace(found, 2, "/");
+
+   return result;
 }
 }
 									/*}}}*/
 									/*}}}*/
 // Configuration::FindDir - Find a directory name			/*{{{*/
 // Configuration::FindDir - Find a directory name			/*{{{*/
@@ -222,7 +234,12 @@ string Configuration::FindDir(const char *Name,const char *Default) const
 {
 {
    string Res = FindFile(Name,Default);
    string Res = FindFile(Name,Default);
    if (Res.end()[-1] != '/')
    if (Res.end()[-1] != '/')
+   {
+      size_t const found = Res.rfind("/dev/null");
+      if (found != string::npos && found == Res.size() - 9)
+	 return Res; // /dev/null returning
       return Res + '/';
       return Res + '/';
+   }
    return Res;
    return Res;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -482,24 +499,80 @@ bool Configuration::ExistsAny(const char *Name) const
 /* Dump the entire configuration space */
 /* Dump the entire configuration space */
 void Configuration::Dump(ostream& str)
 void Configuration::Dump(ostream& str)
 {
 {
-   /* Write out all of the configuration directives by walking the 
+   Dump(str, NULL, "%f \"%v\";\n", true);
+}
+void Configuration::Dump(ostream& str, char const * const root,
+			 char const * const formatstr, bool const emptyValue)
+{
+   const Configuration::Item* Top = Tree(root);
+   if (Top == 0)
+      return;
+   const Configuration::Item* const Root = (root == NULL) ? NULL : Top;
+   std::vector<std::string> const format = VectorizeString(formatstr, '%');
+
+   /* Write out all of the configuration directives by walking the
       configuration tree */
       configuration tree */
-   const Configuration::Item *Top = Tree(0);
-   for (; Top != 0;)
-   {
-      str << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
-      
+   do {
+      if (emptyValue == true || Top->Value.empty() == emptyValue)
+      {
+	 std::vector<std::string>::const_iterator f = format.begin();
+	 str << *f;
+	 for (++f; f != format.end(); ++f)
+	 {
+	    if (f->empty() == true)
+	    {
+	       ++f;
+	       str << '%' << *f;
+	       continue;
+	    }
+	    char const type = (*f)[0];
+	    if (type == 'f')
+	       str << Top->FullTag();
+	    else if (type == 't')
+	       str << Top->Tag;
+	    else if (type == 'v')
+	       str << Top->Value;
+	    else if (type == 'F')
+	       str << QuoteString(Top->FullTag(), "=\"\n");
+	    else if (type == 'T')
+	       str << QuoteString(Top->Tag, "=\"\n");
+	    else if (type == 'V')
+	       str << QuoteString(Top->Value, "=\"\n");
+	    else if (type == 'n')
+	       str << "\n";
+	    else if (type == 'N')
+	       str << "\t";
+	    else
+	       str << '%' << type;
+	    str << f->c_str() + 1;
+	 }
+      }
+
       if (Top->Child != 0)
       if (Top->Child != 0)
       {
       {
 	 Top = Top->Child;
 	 Top = Top->Child;
 	 continue;
 	 continue;
       }
       }
-      
+
       while (Top != 0 && Top->Next == 0)
       while (Top != 0 && Top->Next == 0)
 	 Top = Top->Parent;
 	 Top = Top->Parent;
       if (Top != 0)
       if (Top != 0)
 	 Top = Top->Next;
 	 Top = Top->Next;
-   }
+
+      if (Root != NULL)
+      {
+	 const Configuration::Item* I = Top;
+	 while(I != 0)
+	 {
+	    if (I == Root)
+	       break;
+	    else
+	       I = I->Parent;
+	 }
+	 if (I == 0)
+	    break;
+      }
+   } while (Top != 0);
 }
 }
 									/*}}}*/
 									/*}}}*/
 
 

+ 2 - 0
apt-pkg/contrib/configuration.h

@@ -103,6 +103,8 @@ class Configuration
 
 
    inline void Dump() { Dump(std::clog); };
    inline void Dump() { Dump(std::clog); };
    void Dump(std::ostream& str);
    void Dump(std::ostream& str);
+   void Dump(std::ostream& str, char const * const root,
+	     char const * const format, bool const emptyValue);
 
 
    Configuration(const Item *Root);
    Configuration(const Item *Root);
    Configuration();
    Configuration();

+ 37 - 20
apt-pkg/contrib/strutl.cc

@@ -23,6 +23,7 @@
 
 
 #include <ctype.h>
 #include <ctype.h>
 #include <string.h>
 #include <string.h>
+#include <sstream>
 #include <stdio.h>
 #include <stdio.h>
 #include <algorithm>
 #include <algorithm>
 #include <unistd.h>
 #include <unistd.h>
@@ -1168,34 +1169,50 @@ unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin,
    return Hits;
    return Hits;
 }
 }
 									/*}}}*/
 									/*}}}*/
-// ioprintf - C format string outputter to C++ iostreams		/*{{{*/
+// {str,io}printf - C format string outputter to C++ strings/iostreams	/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This is used to make the internationalization strings easier to translate
 /* This is used to make the internationalization strings easier to translate
    and to allow reordering of parameters */
    and to allow reordering of parameters */
-void ioprintf(ostream &out,const char *format,...) 
+static bool iovprintf(ostream &out, const char *format,
+		      va_list &args, ssize_t &size) {
+   char *S = (char*)malloc(size);
+   ssize_t const n = vsnprintf(S, size, format, args);
+   if (n > -1 && n < size) {
+      out << S;
+      free(S);
+      return true;
+   } else {
+      if (n > -1)
+	 size = n + 1;
+      else
+	 size *= 2;
+   }
+   free(S);
+   return false;
+}
+void ioprintf(ostream &out,const char *format,...)
 {
 {
    va_list args;
    va_list args;
-   va_start(args,format);
-   
-   // sprintf the description
-   char S[4096];
-   vsnprintf(S,sizeof(S),format,args);
-   out << S;
+   ssize_t size = 400;
+   while (true) {
+      va_start(args,format);
+      if (iovprintf(out, format, args, size) == true)
+	 return;
+      va_end(args);
+   }
 }
 }
-									/*}}}*/
-// strprintf - C format string outputter to C++ strings 		/*{{{*/
-// ---------------------------------------------------------------------
-/* This is used to make the internationalization strings easier to translate
-   and to allow reordering of parameters */
-void strprintf(string &out,const char *format,...) 
+void strprintf(string &out,const char *format,...)
 {
 {
    va_list args;
    va_list args;
-   va_start(args,format);
-   
-   // sprintf the description
-   char S[4096];
-   vsnprintf(S,sizeof(S),format,args);
-   out = string(S);
+   ssize_t size = 400;
+   std::ostringstream outstr;
+   while (true) {
+      va_start(args,format);
+      if (iovprintf(outstr, format, args, size) == true)
+	 break;
+      va_end(args);
+   }
+   out = outstr.str();
 }
 }
 									/*}}}*/
 									/*}}}*/
 // safe_snprintf - Safer snprintf					/*{{{*/
 // safe_snprintf - Safer snprintf					/*{{{*/

+ 14 - 13
apt-pkg/depcache.cc

@@ -1152,9 +1152,8 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
       }
       }
 
 
       /* This bit is for processing the possibilty of an install/upgrade
       /* This bit is for processing the possibilty of an install/upgrade
-         fixing the problem */
-      if (Start->Type != Dep::DpkgBreaks &&
-	  (DepState[Start->ID] & DepCVer) == DepCVer)
+         fixing the problem for "positive" dependencies */
+      if (Start.IsNegative() == false && (DepState[Start->ID] & DepCVer) == DepCVer)
       {
       {
 	 APT::VersionList verlist;
 	 APT::VersionList verlist;
 	 pkgCache::VerIterator Cand = PkgState[Start.TargetPkg()->ID].CandidateVerIter(*this);
 	 pkgCache::VerIterator Cand = PkgState[Start.TargetPkg()->ID].CandidateVerIter(*this);
@@ -1165,7 +1164,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	    pkgCache::VerIterator V = Prv.OwnerVer();
 	    pkgCache::VerIterator V = Prv.OwnerVer();
 	    pkgCache::VerIterator Cand = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this);
 	    pkgCache::VerIterator Cand = PkgState[Prv.OwnerPkg()->ID].CandidateVerIter(*this);
 	    if (Cand.end() == true || V != Cand ||
 	    if (Cand.end() == true || V != Cand ||
-		VS().CheckDep(Cand.VerStr(), Start->CompareOp, Start.TargetVer()) == false)
+		VS().CheckDep(Prv.ProvideVersion(), Start->CompareOp, Start.TargetVer()) == false)
 	       continue;
 	       continue;
 	    verlist.insert(Cand);
 	    verlist.insert(Cand);
 	 }
 	 }
@@ -1198,13 +1197,13 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	 }
 	 }
 	 continue;
 	 continue;
       }
       }
-
-      /* For conflicts we just de-install the package and mark as auto,
-         Conflicts may not have or groups.  For dpkg's Breaks we try to
-         upgrade the package. */
-      if (Start.IsNegative() == true)
+      /* Negative dependencies have no or-group
+	 If the dependency isn't versioned, we try if an upgrade might solve the problem.
+	 Otherwise we remove the offender if needed */
+      else if (Start.IsNegative() == true && Start->Type != pkgCache::Dep::Obsoletes)
       {
       {
 	 SPtrArray<Version *> List = Start.AllTargets();
 	 SPtrArray<Version *> List = Start.AllTargets();
+	 pkgCache::PkgIterator TrgPkg = Start.TargetPkg();
 	 for (Version **I = List; *I != 0; I++)
 	 for (Version **I = List; *I != 0; I++)
 	 {
 	 {
 	    VerIterator Ver(*this,*I);
 	    VerIterator Ver(*this,*I);
@@ -1215,15 +1214,17 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	    if (PkgState[Pkg->ID].InstallVer == 0)
 	    if (PkgState[Pkg->ID].InstallVer == 0)
 	       continue;
 	       continue;
 
 
-	    if (PkgState[Pkg->ID].CandidateVer != *I &&
-		Start->Type == Dep::DpkgBreaks &&
+	    if ((Start->Version != 0 || TrgPkg != Pkg) &&
+		PkgState[Pkg->ID].CandidateVer != PkgState[Pkg->ID].InstallVer &&
+		PkgState[Pkg->ID].CandidateVer != *I &&
 		MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps) == true)
 		MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps) == true)
 	       continue;
 	       continue;
-	    else if (MarkDelete(Pkg,false,Depth + 1, false) == false)
+	    else if ((Start->Type == pkgCache::Dep::Conflicts || Start->Type == pkgCache::Dep::DpkgBreaks) &&
+		     MarkDelete(Pkg,false,Depth + 1, false) == false)
 	       break;
 	       break;
 	 }
 	 }
 	 continue;
 	 continue;
-      }      
+      }
    }
    }
 
 
    return Dep.end() == true;
    return Dep.end() == true;

+ 1 - 1
apt-pkg/edsp/edspsystem.cc

@@ -91,7 +91,7 @@ signed edspSystem::Score(Configuration const &Cnf)
 {
 {
    if (Cnf.Find("edsp::scenario", "") == "stdin")
    if (Cnf.Find("edsp::scenario", "") == "stdin")
       return 1000;
       return 1000;
-   if (FileExists(Cnf.FindFile("edsp::scenario","")) == true)
+   if (RealFileExists(Cnf.FindFile("edsp::scenario","")) == true)
       return 1000;
       return 1000;
    return -1000;
    return -1000;
 }
 }

+ 9 - 1
cmdline/apt-config.cc

@@ -63,7 +63,13 @@ bool DoShell(CommandLine &CmdL)
 /* */
 /* */
 bool DoDump(CommandLine &CmdL)
 bool DoDump(CommandLine &CmdL)
 {
 {
-   _config->Dump(cout);
+   bool const empty = _config->FindB("APT::Config::Dump::EmptyValue", true);
+   std::string const format = _config->Find("APT::Config::Dump::Format", "%f \"%v\";\n");
+   if (CmdL.FileSize() == 1)
+      _config->Dump(cout, NULL, format.c_str(), empty);
+   else
+      for (const char **I = CmdL.FileList + 1; *I != 0; ++I)
+	 _config->Dump(cout, *I, format.c_str(), empty);
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -100,6 +106,8 @@ int main(int argc,const char *argv[])					/*{{{*/
       {'v',"version","version",0},
       {'v',"version","version",0},
       {'c',"config-file",0,CommandLine::ConfigFile},
       {'c',"config-file",0,CommandLine::ConfigFile},
       {'o',"option",0,CommandLine::ArbItem},
       {'o',"option",0,CommandLine::ArbItem},
+      {0,"empty","APT::Config::Dump::EmptyValue",CommandLine::Boolean},
+      {0,"format","APT::Config::Dump::Format",CommandLine::HasArg},
       {0,0,0,0}};
       {0,0,0,0}};
    CommandLine::Dispatch Cmds[] = {{"shell",&DoShell},
    CommandLine::Dispatch Cmds[] = {{"shell",&DoShell},
                                    {"dump",&DoDump},
                                    {"dump",&DoDump},

+ 29 - 0
debian/changelog

@@ -1,3 +1,32 @@
+apt (0.9.3) unstable; urgency=low
+
+  [ David Kalnischkies ]
+  * apt-pkg/contrib/strutl.cc:
+    - remove the message size limit from ioprintf and strprintf
+  * apt-pkg/contrib/configuration.cc:
+    - add a more versatile Dump() method
+    - normalize a bit by replacing // and /./ with / in FindFile
+    - /dev/null is a special absolute path as it has no subdirectories
+  * apt-pkg/acquire-worker.cc:
+    - use Dump() to generate the configuration message for sending
+  * cmdline/apt-config.cc:
+    - make it possible to limit dump to a subtree
+    - implement --empty and --format option for dump
+  * apt-pkg/cdrom.cc:
+    - use Dump() to generate the configuration output
+  * apt-pkg/depcache.cc:
+    - clearly separate 'positive' and 'negative' dependencies and
+      their upgrade-resolution tries in MarkInstall and especially don't
+      treat Conflicts differently compared to Breaks here
+    - provider is only a possible solution if the provides has the right
+      version (or none as we have no versioned provides in debian) and not
+      if the version of the provider matches
+  * edsp/edspsystem.cc:
+    - check with RealFileExists for scenario file as otherwise a directory
+      like one provided with RootDir triggers the usage of EDSP
+
+ -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 23 Apr 2012 22:02:58 +0200
+
 apt (0.9.2) unstable; urgency=low
 apt (0.9.2) unstable; urgency=low
 
 
   [ Michael Vogt ]
   [ Michael Vogt ]

+ 15 - 1
doc/apt-config.8.xml

@@ -85,7 +85,21 @@ eval $RES
    &apt-cmdblurb;
    &apt-cmdblurb;
    
    
    <variablelist>
    <variablelist>
-   
+     <varlistentry>
+      <term><option>--empty</option></term>
+      <listitem><para>Include options which have an empty value. This is the default, so
+		      use --no-empty to remove them from the output.</para></listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term><option>--format '<replaceable>&percnt;f &#x0022;&percnt;v&#x0022;;&percnt;n</replaceable>'</option></term>
+      <listitem><para>Defines the output of each config option. &percnt;t will be replaced with the tagname,
+		      &percnt;f with the complete tagname and &percnt;v with the value of the option.
+		      Use uppercase letters and the respective values will be quoted. Additionally
+		      &percnt;n will be replaced by a newline, &percnt;N by a tab. A &percnt; can be
+		      printed by using &percnt;&percnt;.</para></listitem>
+     </varlistentry>
+
      &apt-commonoptions;
      &apt-commonoptions;
      
      
    </variablelist>
    </variablelist>

+ 3 - 0
doc/apt-verbatim.ent

@@ -269,8 +269,11 @@
 		&synopsis-help;
 		&synopsis-help;
 	</group>
 	</group>
 </cmdsynopsis></refsynopsisdiv>">
 </cmdsynopsis></refsynopsisdiv>">
+<!--<arg><option>- -format '<replaceable>&#37;f \"&#37;v\";&#37;n</replaceable>'</option></arg>-->
 <!ENTITY synopsis-command-apt-config "<refsynopsisdiv><cmdsynopsis>
 <!ENTITY synopsis-command-apt-config "<refsynopsisdiv><cmdsynopsis>
 	<command>apt-config</command>
 	<command>apt-config</command>
+	<arg><option>--empty</option></arg>
+	<arg><option>--format '<replaceable>&percnt;f &#x0022;&percnt;v&#x0022;;&percnt;n</replaceable>'</option></arg>
 	&synopsis-arg-option;
 	&synopsis-arg-option;
 	&synopsis-arg-config;
 	&synopsis-arg-config;
 	<group choice='req'>
 	<group choice='req'>

+ 150 - 0
test/integration/test-ignore-provides-if-versioned-breaks

@@ -0,0 +1,150 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386' 'amd64'
+
+insertpackage 'unstable' 'unrlated' 'all' '1.0'
+
+insertinstalledpackage 'foo' 'i386' '2.0'
+insertpackage 'unstable' 'foo' 'i386' '4.0'
+insertpackage 'unstable' 'foo-provider' 'i386' '1.0' 'Provides: foo'
+insertpackage 'unstable' 'foo-breaker-3' 'i386' '1.0' 'Breaks: foo (<< 3.0)'
+insertpackage 'unstable' 'foo-breaker-2' 'i386' '1.0' 'Breaks: foo (<< 2.0)'
+insertpackage 'unstable' 'foo-breaker-none' 'i386' '1.0' 'Breaks: foo'
+
+insertinstalledpackage 'foo-foreign' 'amd64' '2.0' 'Multi-Arch: foreign'
+insertpackage 'unstable' 'foo-foreign' 'amd64' '4.0' 'Multi-Arch: foreign'
+insertpackage 'unstable' 'foo-foreign-provider' 'i386' '1.0' 'Provides: foo-foreign'
+insertpackage 'unstable' 'foo-foreign-breaker-3' 'i386' '1.0' 'Breaks: foo-foreign (<< 3.0)'
+insertpackage 'unstable' 'foo-foreign-breaker-2' 'i386' '1.0' 'Breaks: foo-foreign (<< 2.0)'
+insertpackage 'unstable' 'foo-foreign-breaker-none' 'i386' '1.0' 'Breaks: foo-foreign'
+
+insertinstalledpackage 'foo-same' 'i386,amd64' '2.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'foo-same' 'i386,amd64' '4.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'foo-same-provider' 'i386' '1.0' 'Provides: foo-same'
+insertpackage 'unstable' 'foo-same-breaker-3' 'i386' '1.0' 'Breaks: foo-same (<< 3.0)'
+insertpackage 'unstable' 'foo-same-breaker-2' 'i386' '1.0' 'Breaks: foo-same (<< 2.0)'
+insertpackage 'unstable' 'foo-same-breaker-none' 'i386' '1.0' 'Breaks: foo-same'
+
+
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-breaker-none : Breaks: foo
+E: Unable to correct problems, you have held broken packages.' aptget install foo-provider foo-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  foo-breaker-2 foo-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-breaker-2 (1.0 unstable [i386])
+Inst foo-provider (1.0 unstable [i386])
+Conf foo-breaker-2 (1.0 unstable [i386])
+Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  foo
+The following NEW packages will be installed:
+  foo-breaker-3 foo-provider
+The following packages will be upgraded:
+  foo
+1 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
+Inst foo [2.0] (4.0 unstable [i386])
+Inst foo-breaker-3 (1.0 unstable [i386])
+Inst foo-provider (1.0 unstable [i386])
+Conf foo (4.0 unstable [i386])
+Conf foo-breaker-3 (1.0 unstable [i386])
+Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-3 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-foreign-breaker-none : Breaks: foo-foreign
+E: Unable to correct problems, you have held broken packages.' aptget install foo-foreign-provider foo-foreign-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  foo-foreign-breaker-2 foo-foreign-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-foreign-breaker-2 (1.0 unstable [i386])
+Inst foo-foreign-provider (1.0 unstable [i386])
+Conf foo-foreign-breaker-2 (1.0 unstable [i386])
+Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  foo-foreign:amd64
+The following NEW packages will be installed:
+  foo-foreign-breaker-3 foo-foreign-provider
+The following packages will be upgraded:
+  foo-foreign:amd64
+1 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
+Inst foo-foreign:amd64 [2.0] (4.0 unstable [amd64])
+Inst foo-foreign-breaker-3 (1.0 unstable [i386])
+Inst foo-foreign-provider (1.0 unstable [i386])
+Conf foo-foreign:amd64 (4.0 unstable [amd64])
+Conf foo-foreign-breaker-3 (1.0 unstable [i386])
+Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-3 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-same-breaker-none : Breaks: foo-same
+E: Unable to correct problems, you have held broken packages.' aptget install foo-same-provider foo-same-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  foo-same-breaker-2 foo-same-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-same-breaker-2 (1.0 unstable [i386])
+Inst foo-same-provider (1.0 unstable [i386])
+Conf foo-same-breaker-2 (1.0 unstable [i386])
+Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  foo-same:amd64 foo-same
+The following NEW packages will be installed:
+  foo-same-breaker-3 foo-same-provider
+The following packages will be upgraded:
+  foo-same:amd64 foo-same
+2 upgraded, 2 newly installed, 0 to remove and 2 not upgraded.
+Inst foo-same:amd64 [2.0] (4.0 unstable [amd64]) [foo-same:amd64 on foo-same:i386] [foo-same:i386 on foo-same:amd64] [foo-same:i386 ]
+Inst foo-same [2.0] (4.0 unstable [i386])
+Conf foo-same:amd64 (4.0 unstable [amd64])
+Conf foo-same (4.0 unstable [i386])
+Inst foo-same-breaker-3 (1.0 unstable [i386])
+Inst foo-same-provider (1.0 unstable [i386])
+Conf foo-same-breaker-3 (1.0 unstable [i386])
+Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-3 -s

+ 150 - 0
test/integration/test-ignore-provides-if-versioned-conflicts

@@ -0,0 +1,150 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'i386' 'amd64'
+
+insertpackage 'unstable' 'unrlated' 'all' '1.0'
+
+insertinstalledpackage 'foo' 'i386' '2.0'
+insertpackage 'unstable' 'foo' 'i386' '4.0'
+insertpackage 'unstable' 'foo-provider' 'i386' '1.0' 'Provides: foo'
+insertpackage 'unstable' 'foo-breaker-3' 'i386' '1.0' 'Conflicts: foo (<< 3.0)'
+insertpackage 'unstable' 'foo-breaker-2' 'i386' '1.0' 'Conflicts: foo (<< 2.0)'
+insertpackage 'unstable' 'foo-breaker-none' 'i386' '1.0' 'Conflicts: foo'
+
+insertinstalledpackage 'foo-foreign' 'amd64' '2.0' 'Multi-Arch: foreign'
+insertpackage 'unstable' 'foo-foreign' 'amd64' '4.0' 'Multi-Arch: foreign'
+insertpackage 'unstable' 'foo-foreign-provider' 'i386' '1.0' 'Provides: foo-foreign'
+insertpackage 'unstable' 'foo-foreign-breaker-3' 'i386' '1.0' 'Conflicts: foo-foreign (<< 3.0)'
+insertpackage 'unstable' 'foo-foreign-breaker-2' 'i386' '1.0' 'Conflicts: foo-foreign (<< 2.0)'
+insertpackage 'unstable' 'foo-foreign-breaker-none' 'i386' '1.0' 'Conflicts: foo-foreign'
+
+insertinstalledpackage 'foo-same' 'i386,amd64' '2.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'foo-same' 'i386,amd64' '4.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'foo-same-provider' 'i386' '1.0' 'Provides: foo-same'
+insertpackage 'unstable' 'foo-same-breaker-3' 'i386' '1.0' 'Conflicts: foo-same (<< 3.0)'
+insertpackage 'unstable' 'foo-same-breaker-2' 'i386' '1.0' 'Conflicts: foo-same (<< 2.0)'
+insertpackage 'unstable' 'foo-same-breaker-none' 'i386' '1.0' 'Conflicts: foo-same'
+
+
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-breaker-none : Conflicts: foo
+E: Unable to correct problems, you have held broken packages.' aptget install foo-provider foo-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  foo-breaker-2 foo-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-breaker-2 (1.0 unstable [i386])
+Inst foo-provider (1.0 unstable [i386])
+Conf foo-breaker-2 (1.0 unstable [i386])
+Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  foo
+The following NEW packages will be installed:
+  foo-breaker-3 foo-provider
+The following packages will be upgraded:
+  foo
+1 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
+Inst foo [2.0] (4.0 unstable [i386])
+Inst foo-breaker-3 (1.0 unstable [i386])
+Inst foo-provider (1.0 unstable [i386])
+Conf foo (4.0 unstable [i386])
+Conf foo-breaker-3 (1.0 unstable [i386])
+Conf foo-provider (1.0 unstable [i386])' aptget install foo-provider foo-breaker-3 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-foreign-breaker-none : Conflicts: foo-foreign
+E: Unable to correct problems, you have held broken packages.' aptget install foo-foreign-provider foo-foreign-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  foo-foreign-breaker-2 foo-foreign-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-foreign-breaker-2 (1.0 unstable [i386])
+Inst foo-foreign-provider (1.0 unstable [i386])
+Conf foo-foreign-breaker-2 (1.0 unstable [i386])
+Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  foo-foreign:amd64
+The following NEW packages will be installed:
+  foo-foreign-breaker-3 foo-foreign-provider
+The following packages will be upgraded:
+  foo-foreign:amd64
+1 upgraded, 2 newly installed, 0 to remove and 3 not upgraded.
+Inst foo-foreign:amd64 [2.0] (4.0 unstable [amd64])
+Inst foo-foreign-breaker-3 (1.0 unstable [i386])
+Inst foo-foreign-provider (1.0 unstable [i386])
+Conf foo-foreign:amd64 (4.0 unstable [amd64])
+Conf foo-foreign-breaker-3 (1.0 unstable [i386])
+Conf foo-foreign-provider (1.0 unstable [i386])' aptget install foo-foreign-provider foo-foreign-breaker-3 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+Some packages could not be installed. This may mean that you have
+requested an impossible situation or if you are using the unstable
+distribution that some required packages have not yet been created
+or been moved out of Incoming.
+The following information may help to resolve the situation:
+
+The following packages have unmet dependencies:
+ foo-same-breaker-none : Conflicts: foo-same
+E: Unable to correct problems, you have held broken packages.' aptget install foo-same-provider foo-same-breaker-none -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  foo-same-breaker-2 foo-same-provider
+0 upgraded, 2 newly installed, 0 to remove and 4 not upgraded.
+Inst foo-same-breaker-2 (1.0 unstable [i386])
+Inst foo-same-provider (1.0 unstable [i386])
+Conf foo-same-breaker-2 (1.0 unstable [i386])
+Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-2 -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following extra packages will be installed:
+  foo-same:amd64 foo-same
+The following NEW packages will be installed:
+  foo-same-breaker-3 foo-same-provider
+The following packages will be upgraded:
+  foo-same:amd64 foo-same
+2 upgraded, 2 newly installed, 0 to remove and 2 not upgraded.
+Inst foo-same:amd64 [2.0] (4.0 unstable [amd64]) [foo-same:amd64 on foo-same:i386] [foo-same:i386 on foo-same:amd64] [foo-same:i386 ]
+Inst foo-same [2.0] (4.0 unstable [i386])
+Conf foo-same:amd64 (4.0 unstable [amd64])
+Conf foo-same (4.0 unstable [i386])
+Inst foo-same-breaker-3 (1.0 unstable [i386])
+Inst foo-same-provider (1.0 unstable [i386])
+Conf foo-same-breaker-3 (1.0 unstable [i386])
+Conf foo-same-provider (1.0 unstable [i386])' aptget install foo-same-provider foo-same-breaker-3 -s

+ 18 - 0
test/libapt/configuration_test.cc

@@ -80,6 +80,24 @@ int main(int argc,const char *argv[]) {
 	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
 	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
 	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
 	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
 
 
+	Cnf.Set("RootDir", "/");
+	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
+	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+	Cnf.Set("RootDir", "//./////.////");
+	equals(Cnf.FindFile("Dir::State"), "/srv/sid/var/lib/apt");
+	equals(Cnf.FindFile("Dir::Aptitude::State"), "/srv/sid/var/lib/aptitude");
+	Cnf.Set("RootDir", "/rootdir");
+	equals(Cnf.FindFile("Dir::State"), "/rootdir/srv/sid/var/lib/apt");
+	equals(Cnf.FindFile("Dir::Aptitude::State"), "/rootdir/srv/sid/var/lib/aptitude");
+	Cnf.Set("RootDir", "/rootdir/");
+	equals(Cnf.FindFile("Dir::State"), "/rootdir/srv/sid/var/lib/apt");
+	equals(Cnf.FindFile("Dir::Aptitude::State"), "/rootdir/srv/sid/var/lib/aptitude");
+
+	Cnf.Set("Dir::State", "/dev/null");
+	Cnf.Set("Dir::State::lists", "lists/");
+	equals(Cnf.FindDir("Dir::State"), "/rootdir/dev/null");
+	equals(Cnf.FindDir("Dir::State::lists"), "/rootdir/dev/null");
+
 	//FIXME: Test for configuration file parsing;
 	//FIXME: Test for configuration file parsing;
 	// currently only integration/ tests test them implicitly
 	// currently only integration/ tests test them implicitly