- basic implementation of runtime access() dependencies
[apt.git] / apt-pkg / rpm / rpmlistparser.cc
index fed1654..34dee2e 100644 (file)
@@ -35,6 +35,8 @@
 
 #define WITH_VERSION_CACHING 1
 
+string MultilibArchs[] = {"x86_64", "ia64", "ppc64", "sparc64"};
+
 // ListParser::rpmListParser - Constructor                             /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -47,16 +49,13 @@ rpmListParser::rpmListParser(RPMHandler *Handler)
    {
 #ifdef WITH_HASH_MAP
       SeenPackages = new SeenPackagesType(517);
-      SeenMultiPackages = new SeenMultiPackagesType(517);
 #else
       SeenPackages = new SeenPackagesType;
-      SeenMultiPackages = new SeenMultiPackagesType;
 #endif
    }
    else
    {
       SeenPackages = NULL;
-      SeenMultiPackages = NULL;
    }
    RpmData = RPMPackageData::Singleton();
 }
@@ -65,7 +64,6 @@ rpmListParser::rpmListParser(RPMHandler *Handler)
 rpmListParser::~rpmListParser()
 {
    delete SeenPackages;
-   delete SeenMultiPackages;
 }
 
 // ListParser::UniqFindTagWrite - Find the tag and write a unq string  /*{{{*/
@@ -93,6 +91,7 @@ unsigned long rpmListParser::UniqFindTagWrite(int Tag)
    
    return WriteUniqString(Start,Stop - Start);
 }
+
                                                                         /*}}}*/
 // ListParser::Package - Return the package name                       /*{{{*/
 // ---------------------------------------------------------------------
@@ -121,26 +120,11 @@ string rpmListParser::Package()
    } 
 
    bool IsDup = false;
-   bool IsMulti = false;
    string Name = str;
-   string BaseArch = _config->Find("APT::Architecture");
 
-   if (RpmData->IsMultiArchPackage(Name) == true)
-      IsMulti = true;
-   else if (SeenMultiPackages != NULL) {
-      if (SeenMultiPackages->find(Name.c_str()) != SeenMultiPackages->end())
-      {
-        RpmData->SetMultiArchPackage(Name);
-        MultiArchPackage(Name);
-        IsMulti = true;
-      }
-   }
-   if (IsMulti == true)
-   {
-      Name += "@" + Architecture();     
-      CurrentName = Name;
-      Multilib = true;
-      return Name;
+   if (RpmData->IsMultilibSys() && RpmData->IsCompatArch(Architecture())) {
+        Name += ".32bit";       
+        CurrentName = Name;
    }
 
    
@@ -182,6 +166,7 @@ string rpmListParser::Package()
    CurrentName = Name;
    return Name;
 }
+
                                                                         /*}}}*/
 // ListParser::Arch - Return the architecture string                   /*{{{*/
 // ---------------------------------------------------------------------
@@ -296,8 +281,6 @@ bool rpmListParser::UsePackage(pkgCache::PkgIterator Pkg,
 {
    if (SeenPackages != NULL)
       (*SeenPackages)[Pkg.Name()] = true;
-   if (SeenMultiPackages != NULL)
-      (*SeenMultiPackages)[Pkg.Name()] = true;
    if (Pkg->Section == 0)
       Pkg->Section = UniqFindTagWrite(RPMTAG_GROUP);
    if (_error->PendingError()) 
@@ -421,31 +404,94 @@ bool rpmListParser::ParseDepends(pkgCache::VerIterator Ver,
       if (DepMode == true) {
         if (flagl[i] & RPMSENSE_PREREQ)
            Type = pkgCache::Dep::PreDepends;
-        else if (flagl[i] & RPMSENSE_PREREQ)
-           Type = pkgCache::Dep::Depends;
 #if RPM_VERSION >= 0x040403
         else if (flagl[i] & RPMSENSE_MISSINGOK)
            Type = pkgCache::Dep::Suggests;
 #endif
         else
-           /* WTF? */;
+           Type = pkgCache::Dep::Depends;
       }
 
 #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;
@@ -564,6 +610,7 @@ bool rpmListParser::ParseDepends(pkgCache::VerIterator Ver,
       res = headerGetEntry(header, RPMTAG_SUGGESTSFLAGS, &type,
                           (void **)&flagl, &count);
       break;
+#if 0 // Enhances is not even known to apt, sigh...
    case pkgCache::Dep::Enhances:
       res = headerGetEntry(header, RPMTAG_ENHANCESNAME, &type, 
                           (void **)&namel, &count);
@@ -574,6 +621,7 @@ bool rpmListParser::ParseDepends(pkgCache::VerIterator Ver,
       res = headerGetEntry(header, RPMTAG_ENHANCESFLAGS, &type,
                           (void **)&flagl, &count);
       break;
+#endif
 #endif
    }
    
@@ -706,8 +754,6 @@ bool rpmListParser::Step()
       
       string RealName = Package();
 
-      if (Multilib == true)
-        RealName = RealName.substr(0,RealName.find('@'));
       if (Duplicated == true)
         RealName = RealName.substr(0,RealName.find('#'));
       if (RpmData->IgnorePackage(RealName) == true)
@@ -849,75 +895,6 @@ void rpmListParser::VirtualizePackage(string Name)
    FromPkgI->CurrentState = 0;
 }
 
-void rpmListParser::MultiArchPackage(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+"@"+string(FromVerI.Arch());
-
-      // 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