[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#189014: apt/preferences origin pins for file:// sources do not work



Package: apt
Version: 0.5.4
Severity: normal
Tags: patch

The documentation in the current apt_preferences man page says:
===
       The  final  selection  method is by origin. This is
       simply the site name  of  the  originating  package
       files. The empty string is used for file URIs.
===

That is the following pin should select all file:// URIs:
---
Package: *
Pin: origin
---

  It does not.

  In the current apt binary the pin above will match *all* sources, so 
every single source gets a pin priority of 989 assigned... add the pin
above and use "apt-cache policy apt".  You should see all sources have a
priority of 989, not just local file sources.

  Included is a code walk through of the current code involved, a short 
mention of the new apt_preferences man page, sample config from my local 
configuration, and a patch to fix the apt bug.

    Thanks,
      Mike Simons


Code that makes this a bug:
==========================
    For reference the apt_preferences file is parse by ReadPinFile in
  apt-pkg/policy.cc:251

  A blank origin like:
  ===
  Package: *
  Pin: origin
  ===

    Gets parsed correctly... with a blank Data string being given to
  CreatePin.


    However the login in the FileMatch function is broken...

  apt-pkg/versionmatch.cc:206  pkgVersionMatch::FileMatch
  ===
     if (Type == Origin)
     {
        if (OrSite.empty() == false)
          if (File->Site == 0 ||
              OrSite != File.Site())
             return false;
        return true;
     }
  ===

    In the if statement above is looped over for each apt_preferences Pin and 
  each sources_list Site.  The apt_preferences Pin "origin" value is
  stored in OrSite and the sources_list Site name is stored in File.Site.

    When origin is blank as the example the empty string "" is stored in the 
  OrSite variable, and OrSite.empty() returns true.  So the second if
  statement above is false, and the block above returns true... regardless
  of what is in File.
    For reference File->Site contains the hostname of the site the source
  being compared comes from... for file:// url's in sources.list this
  variable is the empty string ""... 


The new apt_preferences(5) man page:
===================================
    The latest version of the apt_preferences man page, which is being
  worked on by Thomas Hood, says

  http://lists.debian.org/deity/2003/deity-200303/msg00034.html:
  ===
    This general-form entry  in  the  APT  preferences  file
    applies  only  to  groups of packages.  For example, the
    following record assigns a high priority to all  package
    versions available from the local site.

    Package: *
    Pin: origin ""
    Pin-Priority: 999
  ===

    This is wrong.  If you try a pin like the one above it will appear
  that nothing at all happens.  "apt-cache policy" will show no
  difference before and after the addition of that pin to the
  preferences file.

    Given this input, ReadPinFile stores the string "\"\"" 
  (two double quote characters) into the Data part of the pin, when
  this reaches the FileMatch code above "\"\"" appears in the OrSite
  variable... this prevents the second if statement from bring true,
  and also fails the "OrSite != File.Site()" test which is required
  to get a "true" returned from the FileMatch function.


About my configuration:
======================

  In /etc/apt/source.list
  ====
  # local source build area
  deb file:///home/msimons/debian/apt/ ./

  # woody release
  deb http://http.us.debian.org/debian woody main contrib non-free
  deb http://non-us.debian.org/debian-non-US woody/non-US main contrib non-free

  # security
  deb http://security.debian.org/ woody/updates main contrib non-free

  ###########
  # Mozilla 1.3 backport from sid for woody
  deb http://debian.relativ.org/ ./

  # Flash 
  # deb http://marillat.free.fr stable main

  # open office
  # deb http://www.phy.olemiss.edu/openoffice/ testing main contrib
  deb http://ftp.freenet.de/pub/ftp.vpn-junkies.de/openoffice/ woody main contrib

  # java crap
  deb ftp://ftp.tux.org/pub/java/debian woody main non-free

  # Mozilla 1.1, Galleon backport
  # deb http://people.fsn.hu/~pasztor/debian woody mozilla

  # Mozilla 1.2.1 for woody
  # deb http://people.debian.org/~frankie/debian/woody/kalem/ /
  ###########

  # testing release
  deb http://http.us.debian.org/debian testing main contrib non-free
  deb http://non-us.debian.org/debian-non-US testing/non-US main contrib non-free

  # unstable release
  deb http://http.us.debian.org/debian unstable main contrib non-free
  deb http://non-us.debian.org/debian-non-US unstable/non-US main contrib non-free

  # source lines
  deb-src http://http.us.debian.org/debian unstable main contrib non-free
  deb-src http://non-us.debian.org/debian-non-US unstable/non-US main contrib non-free
  deb-src http://http.us.debian.org/debian testing main contrib non-free
  deb-src http://non-us.debian.org/debian-non-US testing/non-US main contrib non-free
  deb-src http://http.us.debian.org/debian woody main contrib non-free
  deb-src http://non-us.debian.org/debian-non-US woody/non-US main contrib non-free
  ===

  /etc/apt/preferences
  ===
  Package: *
  Pin: origin debian.relativ.org

  Package: *
  Pin: origin ftp.tux.org

  Package: *
  Pin: origin ftp.freenet.de

  Package: *
  Pin: release stable
  ===

  This gives me:
  - a default binary package source of debian stable.
  - allows apt-get -t FOO, to fetch packages from testing and unstable.

  - a default source package source of debian unstable.
  - allows apt-get -t FOO source, to get source from testing and stable.

  - prefers a set of packages from outside apt sources 
    (Java, Mozilla, and Openoffice).

    A file pin as given at the beginning of this mail would allow me to 
  override all other sources to prefer packages I personally compiled and
  put in that archive (normally backports from unstable).

    As a work around for this bug (lack of file:// pins) I actually
  use http://localhost/ and a "origin localhost" pin.  However
  I've found that by putting a Release file in my apt area I can do
  release and other style pins as well.


The Patch:
=========

===
diff -urp apt-0.5.4/apt-pkg/versionmatch.cc apt-0.5.4-patch1/apt-pkg/versionmatch.cc
--- apt-0.5.4/apt-pkg/versionmatch.cc	Sat Jun  9 21:57:45 2001
+++ apt-0.5.4-patch1/apt-pkg/versionmatch.cc	Mon Apr 14 15:16:38 2003
@@ -207,12 +207,11 @@ bool pkgVersionMatch::FileMatch(pkgCache
    }
    
    if (Type == Origin)
-   {
-      if (OrSite.empty() == false)
-	 if (File->Site == 0 ||
-	     OrSite != File.Site())
-	    return false;
-      return true;
+   { /* allow preference by site of origin */
+      if (!strcmp(File.Archive(),"now"))      /* ignore local "status" file */
+	 return false;
+
+      return (OrSite == File.Site());                 /* both strings match */
    }
    
    return false;
===

    The File.Archive check is required because the current
  /var/lib/dpkg/status file is a implicit file:// source which needs to be
  ignored.  Then a check for origin matching file.site... if they are both
  empty strings it's true, if they both have the same site name it's true,
  otherwise false.

-- System Information
Debian Release: 3.0
Architecture: i386
Kernel: Linux moria 2.4.18-bf2.4 #1 Son Apr 14 09:53:28 CEST 2002 i686
Locale: LANG=C, LC_CTYPE=C

Versions of packages apt depends on:
ii  libc6                  2.2.5-11.2        GNU C Library: Shared libraries an
ii  libstdc++2.10-glibc2.2 1:2.95.4-11woody1 The GNU stdc++ library


-- 
GPG key: http://simons-clan.com/~msimons/gpg/msimons.asc

Attachment: pgpnAuRtJkzLq.pgp
Description: PGP signature


Reply to: