]> git.saurik.com Git - apt-legacy.git/blobdiff - apt-pkg/deb/deblistparser.cc
Support Architecture: cydia packages, for giggles.
[apt-legacy.git] / apt-pkg / deb / deblistparser.cc
index d0dc7a26038df7f222b94361458b3a6ef5a2cb54..6557e76c3dedcacd70240f378521bca7bd72a8aa 100644 (file)
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/crc-16.h>
+#include <apt-pkg/md5.h>
+#include <apt-pkg/macros.h>
 
 #include <ctype.h>
-
-#include <system.h>
                                                                        /*}}}*/
 
 static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important},
@@ -39,6 +39,18 @@ debListParser::debListParser(FileFd *File) : Tags(File)
 // ListParser::UniqFindTagWrite - Find the tag and write a unq string  /*{{{*/
 // ---------------------------------------------------------------------
 /* */
+unsigned long debListParser::FindTagWrite(const char *Tag)
+{
+   const char *Start;
+   const char *Stop;
+   if (Section.Find(Tag,Start,Stop) == false)
+      return 0;
+   return WriteString(Start,Stop - Start);
+}
+                                                                       /*}}}*/
+// ListParser::UniqFindTagWrite - Find the tag and write a unq string  /*{{{*/
+// ---------------------------------------------------------------------
+/* */
 unsigned long debListParser::UniqFindTagWrite(const char *Tag)
 {
    const char *Start;
@@ -74,6 +86,10 @@ string debListParser::Version()
 /* */
 bool debListParser::NewVersion(pkgCache::VerIterator Ver)
 {
+   Ver->Display = FindTagWrite("Name");
+   if (Ver->Display == 0)
+      Ver->Display = FindTagWrite("Maemo-Display-Name");
+
    // Parse the section
    Ver->Section = UniqFindTagWrite("Section");
    Ver->Arch = UniqFindTagWrite("Architecture");
@@ -90,7 +106,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
    const char *Stop;
    if (Section.Find("Priority",Start,Stop) == true)
    {      
-      if (GrabWord(string(Start,Stop-Start),PrioList,Ver->Priority) == false)
+      if (GrabWord(srkString(Start,Stop-Start),PrioList,Ver->Priority) == false)
         Ver->Priority = pkgCache::State::Extra;
    }
 
@@ -104,8 +120,12 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
       return false;
    if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false)
       return false;
+   if (ParseDepends(Ver,"Breaks",pkgCache::Dep::DpkgBreaks) == false)
+      return false;
    if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
       return false;
+   if (ParseDepends(Ver,"Enhances",pkgCache::Dep::Enhances) == false)
+      return false;
 
    // Obsolete.
    if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false)
@@ -117,6 +137,61 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
    return true;
 }
                                                                        /*}}}*/
+// ListParser::Description - Return the description string             /*{{{*/
+// ---------------------------------------------------------------------
+/* This is to return the string describing the package in debian
+   form. If this returns the blank string then the entry is assumed to
+   only describe package properties */
+string debListParser::Description()
+{
+   srkString description;
+   Description(description);
+   return description;
+}
+
+void debListParser::Description(srkString &Str) {
+   const char *Start, *Stop;
+   if (!Section.Find("Description", Start, Stop))
+      if (!Section.Find(("Description-" + pkgIndexFile::LanguageCode()).c_str(), Start, Stop)) {
+         Start = NULL;
+         Stop = NULL;
+      }
+   Str.assign(Start, Stop);
+}
+                                                                        /*}}}*/
+// ListParser::DescriptionLanguage - Return the description lang string        /*{{{*/
+// ---------------------------------------------------------------------
+/* This is to return the string describing the language of
+   description. If this returns the blank string then the entry is
+   assumed to describe original description. */
+string debListParser::DescriptionLanguage()
+{
+   const char *Start, *Stop;
+   return Section.Find("Description", Start, Stop) ? std::string() : pkgIndexFile::LanguageCode();
+}
+                                                                        /*}}}*/
+// ListParser::Description - Return the description_md5 MD5SumValue    /*{{{*/
+// ---------------------------------------------------------------------
+/* This is to return the md5 string to allow the check if it is the right
+   description. If no Description-md5 is found in the section it will be
+   calculated.
+ */
+MD5SumValue debListParser::Description_md5()
+{
+   const char *Start;
+   const char *Stop;
+   if (!Section.Find("Description-md5", Start, Stop))
+   {
+      MD5Summation md5;
+      srkString description;
+      Description(description);
+      md5.Add((const unsigned char *) description.Start, description.Size);
+      md5.Add("\n");
+      return md5.Result();
+   } else
+      return MD5SumValue(srkString(Start, Stop));
+}
+                                                                        /*}}}*/
 // ListParser::UsePackage - Update a package structure                 /*{{{*/
 // ---------------------------------------------------------------------
 /* This is called to update the package with any new information 
@@ -124,6 +199,10 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
 bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
                               pkgCache::VerIterator Ver)
 {
+   if (Pkg->Display == 0)
+      Pkg->Display = FindTagWrite("Name");
+   if (Pkg->Display == 0)
+      Pkg->Display = FindTagWrite("Maemo-Display-Name");
    if (Pkg->Section == 0)
       Pkg->Section = UniqFindTagWrite("Section");
    if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false)
@@ -136,6 +215,11 @@ bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
    
    if (ParseStatus(Pkg,Ver) == false)
       return false;
+
+   if (Pkg->TagList == 0)
+      if (ParseTag(Pkg) == false)
+         return false;
+
    return true;
 }
                                                                        /*}}}*/
@@ -150,6 +234,7 @@ unsigned short debListParser::VersionHash()
 //                            "Suggests",
 //                            "Recommends",
                             "Conflicts",
+                            "Breaks",
                             "Replaces",0};
    unsigned long Result = INIT_FCS;
    char S[1024];
@@ -167,7 +252,7 @@ unsigned short debListParser::VersionHash()
       for (; Start != End; Start++)
       {
         if (isspace(*Start) == 0)
-           *I++ = tolower(*Start);
+           *I++ = tolower_ascii(*Start);
         if (*Start == '<' && Start[1] != '<' && Start[1] != '=')
            *I++ = '=';
         if (*Start == '>' && Start[1] != '>' && Start[1] != '=')
@@ -214,7 +299,7 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
                           {"deinstall",pkgCache::State::DeInstall},
                           {"purge",pkgCache::State::Purge},
                           {}};
-   if (GrabWord(string(Start,I-Start),WantList,Pkg->SelectedState) == false)
+   if (GrabWord(srkString(Start,I-Start),WantList,Pkg->SelectedState) == false)
       return _error->Error("Malformed 1st word in the Status line");
 
    // Isloate the next word
@@ -230,7 +315,7 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
                           {"hold",pkgCache::State::HoldInst},
                           {"hold-reinstreq",pkgCache::State::HoldReInstReq},
                           {}};
-   if (GrabWord(string(Start,I-Start),FlagList,Pkg->InstState) == false)
+   if (GrabWord(srkString(Start,I-Start),FlagList,Pkg->InstState) == false)
       return _error->Error("Malformed 2nd word in the Status line");
 
    // Isloate the last word
@@ -247,10 +332,12 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
                             {"installed",pkgCache::State::Installed},
                             {"half-installed",pkgCache::State::HalfInstalled},
                             {"config-files",pkgCache::State::ConfigFiles},
+                            {"triggers-awaited",pkgCache::State::TriggersAwaited},
+                            {"triggers-pending",pkgCache::State::TriggersPending},
                             {"post-inst-failed",pkgCache::State::HalfConfigured},
                             {"removal-failed",pkgCache::State::HalfInstalled},
                             {}};
-   if (GrabWord(string(Start,I-Start),StatusList,Pkg->CurrentState) == false)
+   if (GrabWord(srkString(Start,I-Start),StatusList,Pkg->CurrentState) == false)
       return _error->Error("Malformed 3rd word in the Status line");
 
    /* A Status line marks the package as indicating the current
@@ -335,6 +422,17 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
 const char *debListParser::ParseDepends(const char *Start,const char *Stop,
                                        string &Package,string &Ver,
                                        unsigned int &Op, bool ParseArchFlags)
+{
+   srkString cPackage, cVer;
+   const char *Value = ParseDepends(Start, Stop, cPackage, cVer, Op, ParseArchFlags);
+   Package = cPackage;
+   Ver = cVer;
+   return Value;
+}
+
+const char *debListParser::ParseDepends(const char *Start,const char *Stop,
+                                       srkString &Package,srkString &Ver,
+                                       unsigned int &Op, bool ParseArchFlags)
 {
    // Strip off leading space
    for (;Start != Stop && isspace(*Start) != 0; Start++);
@@ -435,7 +533,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
            Found = !Found;
         
          if (Found == false)
-           Package = ""; /* not for this arch */
+           Package.clear(); /* not for this arch */
       }
       
       // Skip whitespace
@@ -467,8 +565,8 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
    if (Section.Find(Tag,Start,Stop) == false)
       return true;
    
-   string Package;
-   string Version;
+   srkString Package;
+   srkString Version;
    unsigned int Op;
 
    while (1)
@@ -495,8 +593,8 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
    if (Section.Find("Provides",Start,Stop) == false)
       return true;
    
-   string Package;
-   string Version;
+   srkString Package;
+   srkString Version;
    unsigned int Op;
 
    while (1)
@@ -505,7 +603,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
       if (Start == 0)
         return _error->Error("Problem parsing Provides line");
       if (Op != pkgCache::Dep::NoOp) {
-        _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str());
+        _error->Warning("Ignoring Provides line with DepCompareOp for package %s", std::string(Package).c_str());
       } else {
         if (NewProvides(Ver,Package,Version) == false)
            return false;
@@ -515,6 +613,46 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
         break;
    }
    
+   return true;
+}
+                                                                       /*}}}*/
+// ListParser::ParseTag - Parse the tag list                           /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool debListParser::ParseTag(pkgCache::PkgIterator Pkg)
+{
+   const char *Start;
+   const char *Stop;
+   if (Section.Find("Tag",Start,Stop) == false)
+      return true;
+   
+   while (1) {
+      while (1) {
+         if (Start == Stop)
+            return true;
+         if (Stop[-1] != ' ' && Stop[-1] != '\t')
+            break;
+         --Stop;
+      }
+
+      const char *Begin = Stop - 1;
+      while (Begin != Start && Begin[-1] != ' ' && Begin[-1] != ',')
+         --Begin;
+
+      if (NewTag(Pkg, Begin, Stop - Begin) == false)
+         return false;
+
+      while (1) {
+         if (Begin == Start)
+            return true;
+         if (Begin[-1] == ',')
+            break;
+         --Begin;
+      }
+
+      Stop = Begin - 1;
+   }
+
    return true;
 }
                                                                        /*}}}*/
@@ -522,10 +660,15 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
 // ---------------------------------------------------------------------
 /* Looks for a word in a list of words - for ParseStatus */
 bool debListParser::GrabWord(string Word,WordList *List,unsigned char &Out)
+{
+   return GrabWord(srkString(Word), List, Out);
+}
+
+bool debListParser::GrabWord(const srkString &Word,WordList *List,unsigned char &Out)
 {
    for (unsigned int C = 0; List[C].Str != 0; C++)
    {
-      if (strcasecmp(Word.c_str(),List[C].Str) == 0)
+      if (strncasecmp(Word.Start,List[C].Str,Word.Size) == 0)
       {
         Out = List[C].Val;
         return true;
@@ -542,11 +685,18 @@ bool debListParser::Step()
    iOffset = Tags.Offset();
    while (Tags.Step(Section) == true)
    {      
+      const char *Start;
+      const char *Stop;
+
+      if (Section.Find("Package",Start,Stop) == false) {
+         _error->Warning("Encountered a section with no Package: header");
+        continue;
+      }
+
       /* See if this is the correct Architecture, if it isn't then we
          drop the whole section. A missing arch tag only happens (in theory)
          inside the Status file, so that is a positive return */
-      const char *Start;
-      const char *Stop;
+
       if (Section.Find("Architecture",Start,Stop) == false)
         return true;
 
@@ -556,6 +706,9 @@ bool debListParser::Step()
       if (stringcmp(Start,Stop,"all") == 0)
         return true;
 
+      if (stringcmp(Start,Stop,"cydia") == 0)
+        return true;
+
       iOffset = Tags.Offset();
    }   
    return false;