* doc/makefile:
authorMichael Vogt <michael.vogt@ubuntu.com>
Thu, 30 Jun 2011 07:33:19 +0000 (08:33 +0100)
committerMichael Vogt <michael.vogt@ubuntu.com>
Thu, 30 Jun 2011 07:33:19 +0000 (08:33 +0100)
  - create doxygen directory to avoid depending on magic (Closes: #628799)
* cmdline/apt-key:
  - explicitly state that net-update is not supported if no url is set
  - require to be root for add, rm, update and net-update
  - clarify update vs. net-update in different distros (Closes: #632043)
* debian/apt.symbols:
  - forgot 'mips' in the list for all architecture dependent symbols
  - comment out gcc-4.5 specific symbols as gcc-4.6 is now default
  - the symbol for PrintStatus() is architecture dependent
* apt-pkg/policy.cc:
  - do not segfault in pinning if a package with this name doesn't exist.
    Thanks to Ferdinand Thommes for the report!
  - Defaults is a vector of Pin not of PkgPin
  - ensure that only the first specific stanza for a package is used
  - save all stanzas which had no effect in Unmatched
  - allow package:architecure in Package:

apt-pkg/policy.cc
apt-pkg/policy.h
cmdline/apt-key
debian/apt.symbols
debian/changelog
doc/apt-key.8.xml
doc/apt-verbatim.ent
doc/makefile
test/integration/test-pin-non-existent-package [new file with mode: 0755]

index 2cc2e5e..bd213e0 100644 (file)
@@ -210,13 +210,20 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name,
 {
    if (Name.empty() == true)
    {
-      Pin *P = &*Defaults.insert(Defaults.end(),PkgPin());
+      Pin *P = &*Defaults.insert(Defaults.end(),Pin());
       P->Type = Type;
       P->Priority = Priority;
       P->Data = Data;
       return;
    }
-   
+
+   size_t found = Name.rfind(':');
+   string Arch;
+   if (found != string::npos) {
+      Arch = Name.substr(found+1);
+      Name.erase(found);
+   }
+
    // Allow pinning by wildcards
    // TODO: Maybe we should always prefer specific pins over non-
    // specific ones.
@@ -225,32 +232,49 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name,
       pkgVersionMatch match(Data, Type);
       for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G)
         if (match.ExpressionMatches(Name, G.Name()))
-           CreatePin(Type, G.Name(), Data, Priority);
+        {
+           if (Arch.empty() == false)
+              CreatePin(Type, string(G.Name()).append(":").append(Arch), Data, Priority);
+           else
+              CreatePin(Type, G.Name(), Data, Priority);
+        }
       return;
    }
 
-   // Get a spot to put the pin
-   pkgCache::GrpIterator Grp = Cache->FindGrp(Name);
-   for (pkgCache::PkgIterator Pkg = Grp.PackageList();
-       Pkg.end() != true; Pkg = Grp.NextPkg(Pkg))
+   // find the package (group) this pin applies to
+   pkgCache::GrpIterator Grp;
+   pkgCache::PkgIterator Pkg;
+   if (Arch.empty() == false)
+      Pkg = Cache->FindPkg(Name, Arch);
+   else {
+      Grp = Cache->FindGrp(Name);
+      if (Grp.end() == false)
+        Pkg = Grp.PackageList();
+   }
+
+   if (Pkg.end() == true)
    {
-      Pin *P = 0;
-      if (Pkg.end() == false)
-        P = Pins + Pkg->ID;
-      else
-      {
-        // Check the unmatched table
-        for (vector<PkgPin>::iterator I = Unmatched.begin();
-             I != Unmatched.end() && P == 0; I++)
-           if (I->Pkg == Name)
-              P = &*I;
+      PkgPin *P = &*Unmatched.insert(Unmatched.end(),PkgPin(Name));
+      if (Arch.empty() == false)
+        P->Pkg.append(":").append(Arch);
+      P->Type = Type;
+      P->Priority = Priority;
+      P->Data = Data;
+      return;
+   }
 
-        if (P == 0)
-           P = &*Unmatched.insert(Unmatched.end(),PkgPin());
-      }
+   for (; Pkg.end() != true; Pkg = Grp.NextPkg(Pkg))
+   {
+      Pin *P = Pins + Pkg->ID;
+      // the first specific stanza for a package is the ruler,
+      // all others need to be ignored
+      if (P->Type != pkgVersionMatch::None)
+        P = &*Unmatched.insert(Unmatched.end(),PkgPin(Pkg.FullName()));
       P->Type = Type;
       P->Priority = Priority;
       P->Data = Data;
+      if (Grp.end() == true)
+        break;
    }
 }
                                                                        /*}}}*/
index f8b2678..a5e6c60 100644 (file)
@@ -55,6 +55,7 @@ class pkgPolicy : public pkgDepCache::Policy
    struct PkgPin : Pin
    {
       string Pkg;
+      PkgPin(string const &Pkg) : Pin(), Pkg(Pkg) {};
    };
    
    Pin *Pins;
index 3838faf..843163f 100755 (executable)
@@ -21,6 +21,13 @@ ARCHIVE_KEYRING_URI=""
 ARCHIVE_KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg
 REMOVED_KEYS=/usr/share/keyrings/debian-archive-removed-keys.gpg
 
+requires_root() {
+       if [ "$(id -u)" -ne 0 ]; then
+               echo >&1 "ERROR: This command can only be used by root."
+               exit 1
+       fi
+}
+
 add_keys_with_verify_against_master_keyring() {
     ADD_KEYRING=$1
     MASTER=$2
@@ -59,13 +66,14 @@ add_keys_with_verify_against_master_keyring() {
 # (otherwise it does not make sense from a security POV)
 net_update() {
     if [ -z "$ARCHIVE_KEYRING_URI" ]; then
-       echo "ERROR: no location for the archive-keyring given"
+       echo >&2 "ERROR: Your distribution is not supported in net-update as no uri for the archive-keyring is set"
        exit 1
     fi
+    requires_root
     # in theory we would need to depend on wget for this, but this feature
     # isn't useable in debian anyway as we have no keyring uri nor a master key
     if ! which wget >/dev/null 2>&1; then
-       echo "ERROR: an installed wget is required for a network-based update"
+       echo >&2 "ERROR: an installed wget is required for a network-based update"
        exit 1
     fi
     if [ ! -d /var/lib/apt/keyrings ]; then
@@ -93,6 +101,7 @@ update() {
        echo >&2 "Is the debian-archive-keyring package installed?"
        exit 1
     fi
+    requires_root
 
     # add new keys from the package;
 
@@ -184,10 +193,12 @@ fi
 
 case "$command" in
     add)
+        requires_root
         $GPG --quiet --batch --import "$1"
         echo "OK"
         ;;
     del|rm|remove)
+        requires_root
         $GPG --quiet --batch --delete-key --yes "$1"
         echo "OK"
         ;;
index fb84038..04e13ed 100644 (file)
@@ -1230,37 +1230,45 @@ libapt-pkg.so.4.10 libapt-pkg4.10
 # (c++|regex|optional=std)"^std::vector<.+ >::(vector|push_back|erase|_[^ ]+)\(.+\)( const|)@Base$" 0.8.0
 # (c++|regex|optional=std)"^pkgCache::(Dep|Pkg|Ver|Grp|Prv|Desc|PkgFile)Iterator\*\* std::_.+@Base$" 0.8.0
 ### gcc-4.5 specific
- (c++|regex|optional=std)"^char\* std::[^ ]+<.+ >::_.+@Base$" 0.8.0
- (c++|optional=inline)"FileFd::FileFd(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, FileFd::OpenMode, unsigned long)@Base" 0.8.0
- (c++|regex|optional=template)"^SPtrArray<[^ ]+>::~SPtrArray\(\)@Base$" 0.8.0
- (c++|optional=template)"SPtrArray<unsigned char>::~SPtrArray()@Base" 0.8.0
+# (c++|regex|optional=std)"^char\* std::[^ ]+<.+ >::_.+@Base$" 0.8.0
+# (c++|optional=inline)"FileFd::FileFd(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, FileFd::OpenMode, unsigned long)@Base" 0.8.0
+# (c++|regex|optional=template)"^SPtrArray<[^ ]+>::~SPtrArray\(\)@Base$" 0.8.0
+# (c++|optional=template)"SPtrArray<unsigned char>::~SPtrArray()@Base" 0.8.0
 ### gcc-4.6 specific
  (c++|optional=template)"SPtrArray<pkgCache::Version*>::~SPtrArray()@Base" 0.8.0
  (c++|regex|optional=std)"^std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string<char( const|)\*>\(.+\)@Base$" 0.8.0
  (c++|regex|optional=std)"^std::vector<DiffInfo, .+@Base$" 0.8.0
  (c++|regex|optional=std)"^std::vector<.+ >::(vector|push_back|erase|_[^ ]+)\(.+\)( const|)@Base$" 0.8.0
- (c++|optional=strange)"pkgCache::VerIterator::VerIterator(pkgCache&, pkgCache::Version*)@Base" 0.8.0
+# (c++|optional=strange)"pkgCache::VerIterator::VerIterator(pkgCache&, pkgCache::Version*)@Base" 0.8.0
+### architecture specific: va_list
+ (arch=armel armhf|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, std::__va_list&) const@Base" 0.8.15~exp1 1
+ (arch=i386 hurd-i386 kfreebsd-i386|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, char*&) const@Base" 0.8.15~exp1 1
+ (arch=hppa ia64 mips mipsel sparc sparc64|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, void*&) const@Base" 0.8.15~exp1 1
+ (arch=amd64 kfreebsd-amd64 powerpc powerpcspe s390|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, __va_list_tag (&) [1]) const@Base" 0.8.15~exp1 1
+ (arch=sh4|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, __builtin_va_list&) const@Base" 0.8.15~exp1 1
+ (arch=alpha|c++)"pkgAcqMethod::PrintStatus(char const*, char const*, __va_list_tag&) const@Base" 0.8.15~exp1 1
 ### architecture specific: va_list & size_t
  (arch=i386 hurd-i386 kfreebsd-i386|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, char*&, unsigned int&)@Base" 0.8.11.4 1
  (arch=armel armhf|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, std::__va_list&, unsigned int&)@Base" 0.8.11.4 1
  (arch=alpha|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag&, unsigned long&)@Base" 0.8.11.4 1
  (arch=powerpc powerpcspe|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag (&) [1], unsigned int&)@Base" 0.8.11.4 1
  (arch=amd64 kfreebsd-amd64 s390|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __va_list_tag (&) [1], unsigned long&)@Base" 0.8.11.4 1
- (arch=hppa mipsel sparc|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, void*&, unsigned int&)@Base" 0.8.11.4 1
+ (arch=hppa mips mipsel sparc|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, void*&, unsigned int&)@Base" 0.8.11.4 1
  (arch=ia64 sparc64|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, void*&, unsigned long&)@Base" 0.8.11.4 1
  (arch=sh4|c++|optional=private)"GlobalError::Insert(GlobalError::MsgType, char const*, __builtin_va_list&, unsigned int&)@Base" 0.8.11.4 1
+
  (arch=i386 hurd-i386 kfreebsd-i386|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, char*&, int, unsigned int&)@Base" 0.8.11.4 1
  (arch=armel armhf|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, std::__va_list&, int, unsigned int&)@Base" 0.8.11.4 1
  (arch=alpha|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag&, int, unsigned long&)@Base" 0.8.11.4 1
  (arch=powerpc powerpcspe|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag (&) [1], int, unsigned int&)@Base" 0.8.11.4 1
  (arch=amd64 kfreebsd-amd64 s390|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __va_list_tag (&) [1], int, unsigned long&)@Base" 0.8.11.4 1
- (arch=hppa mipsel sparc|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, void*&, int, unsigned int&)@Base" 0.8.11.4 1
+ (arch=hppa mips mipsel sparc|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, void*&, int, unsigned int&)@Base" 0.8.11.4 1
  (arch=ia64 sparc64|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, void*&, int, unsigned long&)@Base" 0.8.11.4 1
  (arch=sh4|c++|optional=private)"GlobalError::InsertErrno(GlobalError::MsgType, char const*, char const*, __builtin_va_list&, int, unsigned int&)@Base" 0.8.11.4 1
 ### architecture specific: size_t
- (arch=i386 armel armhf hppa hurd-i386 kfreebsd-i386 mipsel powerpc powerpcspe sh4 sparc|c++)"_strtabexpand(char*, unsigned int)@Base" 0.8.0
+ (arch=i386 armel armhf hppa hurd-i386 kfreebsd-i386 mips mipsel powerpc powerpcspe sh4 sparc|c++)"_strtabexpand(char*, unsigned int)@Base" 0.8.0
  (arch=alpha amd64 ia64 kfreebsd-amd64 s390 sparc64|c++)"_strtabexpand(char*, unsigned long)@Base" 0.8.0
- (arch=i386 armel armhf hppa hurd-i386 kfreebsd-i386 mipsel powerpc powerpcspe sh4 sparc|c++)"indexRecords::parseSumData(char const*&, char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned int&)@Base" 0.8.0
+ (arch=i386 armel armhf hppa hurd-i386 kfreebsd-i386 mips mipsel powerpc powerpcspe sh4 sparc|c++)"indexRecords::parseSumData(char const*&, char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned int&)@Base" 0.8.0
  (arch=alpha amd64 ia64 kfreebsd-amd64 s390 sparc64|c++)"indexRecords::parseSumData(char const*&, char const*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, unsigned long&)@Base" 0.8.0
 ### try to ignore std:: template instances
  (c++|regex|optional=std)"^(void |)std::[^ ]+<.+ >::(_|~).+\(.*\)@Base$" 0.8.0
@@ -1319,5 +1327,4 @@ libapt-pkg.so.4.10 libapt-pkg4.10
  (c++|optional=private)"PrintMode(char)@Base" 0.8.13.2 1
  (c++)"pkgDepCache::IsModeChangeOk(pkgDepCache::ModeList, pkgCache::PkgIterator const&, unsigned long, bool)@Base" 0.8.13.2 1
  (c++)"pkgPackageManager::SmartUnPack(pkgCache::PkgIterator, bool)@Base" 0.8.15~exp1 1
- (c++)"pkgAcqMethod::PrintStatus(char const*, char const*, char*&) const@Base" 0.8.15~exp1 1
  (c++)"pkgCache::DepIterator::IsNegative() const@Base" 0.8.15~exp1 1
index 7598a13..d56d6b8 100644 (file)
@@ -1,3 +1,26 @@
+apt (0.8.15.1) UNRELEASEDunstable; urgency=low
+
+  [ David Kalnischkies ]
+  * doc/makefile:
+    - create doxygen directory to avoid depending on magic (Closes: #628799)
+  * cmdline/apt-key:
+    - explicitly state that net-update is not supported if no url is set
+    - require to be root for add, rm, update and net-update
+    - clarify update vs. net-update in different distros (Closes: #632043)
+  * debian/apt.symbols:
+    - forgot 'mips' in the list for all architecture dependent symbols
+    - comment out gcc-4.5 specific symbols as gcc-4.6 is now default
+    - the symbol for PrintStatus() is architecture dependent
+  * apt-pkg/policy.cc:
+    - do not segfault in pinning if a package with this name doesn't exist.
+      Thanks to Ferdinand Thommes for the report!
+    - Defaults is a vector of Pin not of PkgPin
+    - ensure that only the first specific stanza for a package is used
+    - save all stanzas which had no effect in Unmatched
+    - allow package:architecure in Package:
+
+ -- David Kalnischkies <kalnischkies@gmail.com>  Thu, 30 Jun 2011 00:02:15 +0200
+
 apt (0.8.15) unstable; urgency=low
 
   [ Julian Andres Klode ]
index 9bfab84..f17f0c4 100644 (file)
      <listitem>
      <para>
 
-       Update the local keyring with the keyring of Debian archive
-       keys and removes from the keyring the archive keys which are no
-       longer valid.
+       Update the local keyring with the archive keyring and remove from
+       the local keyring the archive keys which are no longer valid.
+       The archive keyring is shipped in the <literal>archive-keyring</literal> package of your
+       distribution, e.g. the <literal>debian-archive-keyring</literal> package in Debian.
 
      </para>
 
      <listitem>
      <para>
 
-       Update the local keyring with the keys of a key server
-       and removes from the keyring the archive keys which are no
-       longer valid. This requires an installed wget and an APT
-       build configured to have a server to fetch from. APT in
-       Debian does not support this command, but Ubuntu's APT
-       does.
+       Work similar to the <command>update</command> command above, but get the
+       archive keyring from an URI instead and validate it against a master key.
+
+       This requires an installed &wget; and an APT build configured to have
+       a server to fetch from and a master keyring to validate.
+
+       APT in Debian does not support this command and relies on
+       <command>update</command> instead, but Ubuntu's APT does.
 
      </para>
 
index a194a9d..14cd70e 100644 (file)
   </citerefentry>"
 >
 
+<!ENTITY wget "<citerefentry>
+    <refentrytitle><command>wget</command></refentrytitle>
+    <manvolnum>1</manvolnum>
+  </citerefentry>"
+>
+
 <!-- Boiler plate docinfo section -->
 <!ENTITY apt-email "
    <address>
index 8a889c9..4fcf3bd 100644 (file)
@@ -101,6 +101,7 @@ $(BUILD)/doc/Doxyfile: Doxyfile.in
 
 $(BUILD)/doc/doxygen-stamp: $(DOXYGEN_SOURCES) $(BUILD)/doc/Doxyfile
        rm -fr $(BUILD)/doc/doxygen
+       mkdir $(BUILD)/doc/doxygen  # some versions seem to not create this directory #628799
        $(DOXYGEN) $(BUILD)/doc/Doxyfile
        touch $(BUILD)/doc/doxygen-stamp
 
diff --git a/test/integration/test-pin-non-existent-package b/test/integration/test-pin-non-existent-package
new file mode 100755 (executable)
index 0000000..c91e778
--- /dev/null
@@ -0,0 +1,72 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture "i386"
+
+insertpackage 'unstable' 'apt' 'i386' '0.8.15'
+insertpackage 'unstable' 'arch' 'i386' '1.0'
+
+setupaptarchive
+
+testcandidate() {
+       msgtest "Test that the Candidate for $1 is" $2
+       if [ "$(aptcache policy $1 | grep '^  Candidate:')" = "  Candidate: $2" ]; then
+               msgpass
+       else
+               echo
+               aptcache policy $1
+               msgfail
+       fi
+}
+
+testcandidate apt '0.8.15'
+testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
+testequal 'Reading package lists...
+Building dependency tree...
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+
+echo 'Package: apt
+Pin: release a=unstable
+Pin-Priority: -1' > rootdir/etc/apt/preferences
+
+testcandidate apt '(none)'
+testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
+testequal 'Reading package lists...
+Building dependency tree...
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+
+echo '
+Package: doesntexist
+Pin: release a=unstable
+Pin-Priority: 1000' >> rootdir/etc/apt/preferences
+
+testcandidate apt '(none)'
+
+echo '
+Package: apt
+Pin: release a=unstable
+Pin-Priority: 1000' >> rootdir/etc/apt/preferences
+
+testcandidate apt '(none)'
+testequal 'N: Unable to locate package doesntexist' aptcache policy doesntexist -q=0
+
+testequal 'Reading package lists...
+Building dependency tree...
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade
+
+echo 'Package: arch:amd64
+Pin: release a=unstable
+Pin-Priority: -1' > rootdir/etc/apt/preferences
+
+testcandidate arch '1.0'
+
+echo '
+Package: arch:i386
+Pin: release a=unstable
+Pin-Priority: -1' >> rootdir/etc/apt/preferences
+
+testcandidate arch '(none)'
+