- basic implementation of runtime access() dependencies
[apt.git] / apt-pkg / rpm / rpmlistparser.cc
index 4b54936..34dee2e 100644 (file)
@@ -35,6 +35,8 @@
 
 #define WITH_VERSION_CACHING 1
 
+string MultilibArchs[] = {"x86_64", "ia64", "ppc64", "sparc64"};
+
 // ListParser::rpmListParser - Constructor                             /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -120,7 +122,7 @@ string rpmListParser::Package()
    bool IsDup = false;
    string Name = str;
 
-   if (IsCompatArch(Architecture()) == true) {
+   if (RpmData->IsMultilibSys() && RpmData->IsCompatArch(Architecture())) {
         Name += ".32bit";       
         CurrentName = Name;
    }
@@ -165,21 +167,6 @@ string rpmListParser::Package()
    return Name;
 }
 
-bool rpmListParser::IsCompatArch(string Architecture)
-{
-   bool compat = false;
-   string BaseArch = _config->Find("APT::Architecture");
-   // ugh, gpg-pubkey doesn't have arch set
-   if (Architecture == "") {
-      return false;
-   }
-   // TODO: arch vs basearch isn't enough, should handle eg x86_64 vs ia32e
-   // and other fun..
-   if (Architecture != BaseArch && Architecture != "noarch") {
-      compat = true;
-   }
-   return compat;
-}
                                                                         /*}}}*/
 // ListParser::Arch - Return the architecture string                   /*{{{*/
 // ---------------------------------------------------------------------
@@ -426,20 +413,85 @@ bool rpmListParser::ParseDepends(pkgCache::VerIterator Ver,
       }
 
 #if RPM_VERSION >= 0x040404
-      if (namel[i][0] == 'g' && strncmp(namel[i], "getconf", 7) == 0)
+      // uhhuh, any of these changing would require full cache rebuild...
+      if (strncmp(namel[i], "getconf(", sizeof("getconf(")-1) == 0)
       {
         rpmds getconfProv = NULL;
         rpmds ds = rpmdsSingle(RPMTAG_PROVIDENAME,
                                namel[i], verl?verl[i]:NULL, flagl[i]);
         rpmdsGetconf(&getconfProv, NULL);
-        int res = rpmdsSearch(getconfProv, ds) >= 0;
+        int res = rpmdsSearch(getconfProv, ds);
         rpmdsFree(ds);
         rpmdsFree(getconfProv);
         if (res) continue;
       }
+
+      if (strncmp(namel[i], "cpuinfo(", sizeof("cpuinfo(")-1) == 0)
+      {
+        rpmds cpuinfoProv = NULL;
+        rpmds ds = rpmdsSingle(RPMTAG_PROVIDENAME,
+                               namel[i], verl?verl[i]:NULL, flagl[i]);
+        rpmdsCpuinfo(&cpuinfoProv, NULL);
+        int res = rpmdsSearch(cpuinfoProv, ds);
+        rpmdsFree(ds);
+        rpmdsFree(cpuinfoProv);
+        if (res) continue;
+      }
+
+      if (strncmp(namel[i], "sysinfo(", sizeof("sysinfo(")-1) == 0)
+      {
+        rpmds sysinfoProv = NULL;
+        rpmds ds = rpmdsSingle(RPMTAG_PROVIDENAME,
+                               namel[i], verl?verl[i]:NULL, flagl[i]);
+        rpmdsCpuinfo(&sysinfoProv, NULL);
+        int res = rpmdsSearch(sysinfoProv, ds);
+        rpmdsFree(ds);
+        rpmdsFree(sysinfoProv);
+        if (res) continue;
+      }
+
+      if (strncmp(namel[i], "uname(", sizeof("uname(")-1) == 0)
+      {
+        rpmds unameProv = NULL;
+        rpmds ds = rpmdsSingle(RPMTAG_PROVIDENAME,
+                               namel[i], verl?verl[i]:NULL, flagl[i]);
+        rpmdsUname(&unameProv, NULL);
+        int res = rpmdsSearch(unameProv, ds);
+        rpmdsFree(ds);
+        rpmdsFree(unameProv);
+        if (res) continue;
+      }
+
+      if (strlen(namel[i]) > 5 && namel[i][strlen(namel[i])-1] == ')' &&
+         ((strchr("Rr_", namel[i][0]) != NULL &&
+           strchr("Ww_", namel[i][1]) != NULL &&
+           strchr("Xx_", namel[i][2]) != NULL &&
+           namel[i][3] == '(') ||
+           strncmp(namel[i], "exists(", sizeof("exists(")-1) == 0 ||
+           strncmp(namel[i], "executable(", sizeof("executable(")-1) == 0 ||
+           strncmp(namel[i], "readable(", sizeof("readable(")-1) == 0 ||
+           strncmp(namel[i], "writable(", sizeof("writable(")-1)== 0 ))
+      {
+        int res = rpmioAccess(namel[i], NULL, X_OK);
+        if (res == 0)
+           continue;
+      }
+
+      /* TODO
+       * - /etc/rpm/sysinfo provides
+       * - macro probe provides 
+       * - actually implement soname() and access() dependencies
+       */
+      if (strncmp(namel[i], "soname(", sizeof("soname(")-1) == 0)
+      {
+        cout << "FIXME, ignoring soname() dependency: " << namel[i] << endl;
+        continue;
+      }
+      
+
 #endif
       
-      if (namel[i][0] == 'r' && strncmp(namel[i], "rpmlib", 6) == 0)
+      if (strncmp(namel[i], "rpmlib(", sizeof("rpmlib(")-1) == 0)
       {
 #if RPM_VERSION >= 0x040404
         rpmds rpmlibProv = NULL;
@@ -843,75 +895,6 @@ void rpmListParser::VirtualizePackage(string Name)
    FromPkgI->CurrentState = 0;
 }
 
-void rpmListParser::CompatArchPackage(string Name)
-{
-   pkgCache::PkgIterator FromPkgI = Owner->GetCache().FindPkg(Name);
-
-   // Should always be false
-   if (FromPkgI.end() == true)
-      return;
-
-   pkgCache::VerIterator FromVerI = FromPkgI.VersionList();
-   while (FromVerI.end() == false) {
-      string MangledName = Name+".32bit";
-
-      // Get the new package.
-      pkgCache::PkgIterator ToPkgI = Owner->GetCache().FindPkg(MangledName);
-      if (ToPkgI.end() == true) {
-        // Theoretically, all packages virtualized should pass here at least
-        // once for each new version in the list, since either the package was
-        // already setup as Allow-Duplicated (and this method would never be
-        // called), or the package doesn't exist before getting here. If
-        // we discover that this assumption is false, then we must do
-        // something to order the version list correctly, since the package
-        // could already have some other version there.
-        Owner->NewPackage(ToPkgI, MangledName);
-
-        // Should it get the flags from the original package? Probably not,
-        // or automatic Allow-Duplicated would work differently than
-        // hardcoded ones.
-        ToPkgI->Flags |= RpmData->PkgFlags(MangledName);
-        ToPkgI->Section = FromPkgI->Section;
-      }
-      
-      // Move the version to the new package.
-      FromVerI->ParentPkg = ToPkgI.Index();
-
-      // Put it at the end of the version list (about ordering,
-      // read the comment above).
-      map_ptrloc *ToVerLast = &ToPkgI->VersionList;
-      for (pkgCache::VerIterator ToVerLastI = ToPkgI.VersionList();
-          ToVerLastI.end() == false; ToVerLastI++)
-          ToVerLast = &ToVerLastI->NextVer;
-
-      *ToVerLast = FromVerI.Index();
-
-      // Provide the real package name with the current version.
-      NewProvides(FromVerI, Name, FromVerI.VerStr());
-
-      // Is this the current version of the old package? If yes, set it
-      // as the current version of the new package as well.
-      if (FromVerI == FromPkgI.CurrentVer()) {
-        ToPkgI->CurrentVer = FromVerI.Index();
-        ToPkgI->SelectedState = pkgCache::State::Install;
-        ToPkgI->InstState = pkgCache::State::Ok;
-        ToPkgI->CurrentState = pkgCache::State::Installed;
-      }
-
-      // Move the iterator before reseting the NextVer.
-      pkgCache::Version *FromVer = (pkgCache::Version*)FromVerI;
-      FromVerI++;
-      FromVer->NextVer = 0;
-   }
-
-   // Reset original package data.
-   FromPkgI->CurrentVer = 0;
-   FromPkgI->VersionList = 0;
-   FromPkgI->Section = 0;
-   FromPkgI->SelectedState = 0;
-   FromPkgI->InstState = 0;
-   FromPkgI->CurrentState = 0;
-}
 #endif /* HAVE_RPM */
 
 // vim:sts=3:sw=3