apt  2.2.4
About: Apt (Advanced Package Tool) is a management system for software packages (Debian/Ubuntu). Release series 2.2.
  Fossies Dox: apt-2.2.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

debrecords.cc
Go to the documentation of this file.
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* ######################################################################
4 
5  Debian Package Records - Parser for debian package records
6 
7  ##################################################################### */
8  /*}}}*/
9 // Include Files /*{{{*/
10 #include <config.h>
11 
13 #include <apt-pkg/debindexfile.h>
14 #include <apt-pkg/debrecords.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/fileutl.h>
17 #include <apt-pkg/pkgcache.h>
18 #include <apt-pkg/strutl.h>
19 #include <apt-pkg/tagfile.h>
20 
21 #include <algorithm>
22 #include <sstream>
23 #include <string>
24 #include <vector>
25 #include <langinfo.h>
26 #include <string.h>
27 
28 #include <apti18n.h>
29  /*}}}*/
30 
31 using std::string;
32 
33 // RecordParser::debRecordParser - Constructor /*{{{*/
34 debRecordParser::debRecordParser(string FileName,pkgCache &Cache) :
35  debRecordParserBase(), d(NULL), File(FileName, FileFd::ReadOnly, FileFd::Extension),
36  Tags(&File, std::max(Cache.Head().MaxVerFileSize, Cache.Head().MaxDescFileSize) + 200)
37 {
38 }
39  /*}}}*/
40 // RecordParser::Jump - Jump to a specific record /*{{{*/
42 {
43  if (Ver.end() == true)
44  return false;
45  return Tags.Jump(Section,Ver->Offset);
46 }
48 {
49  if (Desc.end() == true)
50  return false;
51  return Tags.Jump(Section,Desc->Offset);
52 }
53  /*}}}*/
55 
57 // RecordParserBase::FileName - Return the archive filename on the site /*{{{*/
59 {
60  return Section.FindS("Filename");
61 }
62  /*}}}*/
63 // RecordParserBase::Name - Return the package name /*{{{*/
65 {
66  string Result = Section.FindS("Package");
67 
68  // Normalize mixed case package names to lower case, like dpkg does
69  // See Bug#807012 for details
70  std::transform(Result.begin(), Result.end(), Result.begin(), tolower_ascii);
71 
72  return Result;
73 }
74  /*}}}*/
75 // RecordParserBase::Homepage - Return the package homepage /*{{{*/
77 {
78  return Section.FindS("Homepage");
79 }
80  /*}}}*/
81 // RecordParserBase::Hashes - return the available archive hashes /*{{{*/
83 {
84  HashStringList hashes;
85  for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
86  {
87  std::string const hash = Section.FindS(*type);
88  if (hash.empty() == false)
89  hashes.push_back(HashString(*type, hash));
90  }
91  auto const size = Section.FindULL("Size", 0);
92  if (size != 0)
93  hashes.FileSize(size);
94  return hashes;
95 }
96  /*}}}*/
97 // RecordParserBase::Maintainer - Return the maintainer email /*{{{*/
99 {
100  return Section.FindS("Maintainer");
101 }
102  /*}}}*/
103 // RecordParserBase::RecordField - Return the value of an arbitrary field /*{{*/
104 string debRecordParserBase::RecordField(const char *fieldName)
105 {
106  return Section.FindS(fieldName);
107 }
108  /*}}}*/
109 // RecordParserBase::ShortDesc - Return a 1 line description /*{{{*/
110 string debRecordParserBase::ShortDesc(std::string const &lang)
111 {
112  string const Res = LongDesc(lang);
113  if (Res.empty() == true)
114  return "";
115  string::size_type const Pos = Res.find('\n');
116  if (Pos == string::npos)
117  return Res;
118  return string(Res,0,Pos);
119 }
120  /*}}}*/
121 // RecordParserBase::LongDesc - Return a longer description /*{{{*/
122 string debRecordParserBase::LongDesc(std::string const &lang)
123 {
124  string orig;
125  if (lang.empty() == true)
126  {
127  std::vector<string> const lang = APT::Configuration::getLanguages();
128  for (std::vector<string>::const_iterator l = lang.begin();
129  l != lang.end(); ++l)
130  {
131  std::string const tagname = "Description-" + *l;
132  orig = Section.FindS(tagname.c_str());
133  if (orig.empty() == false)
134  break;
135  else if (*l == "en")
136  {
137  orig = Section.FindS("Description");
138  if (orig.empty() == false)
139  break;
140  }
141  }
142  if (orig.empty() == true)
143  orig = Section.FindS("Description");
144  }
145  else
146  {
147  std::string const tagname = "Description-" + lang;
148  orig = Section.FindS(tagname.c_str());
149  if (orig.empty() == true && lang == "en")
150  orig = Section.FindS("Description");
151  }
152 
153  char const * const codeset = nl_langinfo(CODESET);
154  if (strcmp(codeset,"UTF-8") != 0) {
155  string dest;
156  UTF8ToCodeset(codeset, orig, &dest);
157  return dest;
158  }
159 
160  return orig;
161 }
162  /*}}}*/
163 
164 static const char * const SourceVerSeparators = " ()";
165 // RecordParserBase::SourcePkg - Return the source package name if any /*{{{*/
167 {
168  string Res = Section.FindS("Source");
169  string::size_type Pos = Res.find_first_of(SourceVerSeparators);
170  if (Pos == string::npos)
171  return Res;
172  return string(Res,0,Pos);
173 }
174  /*}}}*/
175 // RecordParserBase::SourceVer - Return the source version number if present /*{{{*/
177 {
178  string Pkg = Section.FindS("Source");
179  string::size_type Pos = Pkg.find_first_of(SourceVerSeparators);
180  if (Pos == string::npos)
181  return "";
182 
183  string::size_type VerStart = Pkg.find_first_not_of(SourceVerSeparators, Pos);
184  if(VerStart == string::npos)
185  return "";
186 
187  string::size_type VerEnd = Pkg.find_first_of(SourceVerSeparators, VerStart);
188  if(VerEnd == string::npos)
189  // Corresponds to the case of, e.g., "foo (1.2" without a closing
190  // paren. Be liberal and guess what it means.
191  return string(Pkg, VerStart);
192  else
193  return string(Pkg, VerStart, VerEnd - VerStart);
194 }
195  /*}}}*/
196 // RecordParserBase::GetRec - Return the whole record /*{{{*/
197 void debRecordParserBase::GetRec(const char *&Start,const char *&Stop)
198 {
199  Section.GetSection(Start,Stop);
200 }
201  /*}}}*/
203 
205 {
206  // load content only once
207  if (controlContent.empty() == false)
208  return true;
209 
210  std::ostringstream content;
211  if (debDebPkgFileIndex::GetContent(content, debFileName) == false)
212  return false;
213  // add two newlines to make sure the scanner finds the section,
214  // which is usually done by pkgTagFile automatically if needed.
215  content << "\n\n";
216 
217  controlContent = content.str();
218  if (Section.Scan(controlContent.c_str(), controlContent.length()) == false)
219  return _error->Error(_("Unable to parse package file %s (%d)"), debFileName.c_str(), 3);
220  return true;
221 }
225 
226 debDebFileRecordParser::debDebFileRecordParser(std::string FileName) : debRecordParserBase(), d(NULL), debFileName(FileName) {}
Definition: fileutl.h:39
bool push_back(const HashString &hashString)
Definition: hashes.cc:232
unsigned long long FileSize() const
Definition: hashes.cc:210
static APT_PURE const char ** SupportedHashes()
Definition: hashes.cc:135
virtual ~debDebFileRecordParser()
Definition: debrecords.cc:227
std::string controlContent
Definition: debrecords.h:74
APT_HIDDEN bool LoadContent()
Definition: debrecords.cc:204
virtual std::string FileName() APT_OVERRIDE
Definition: debrecords.cc:224
bool Jump(pkgCache::VerFileIterator const &) APT_OVERRIDE
Definition: debrecords.cc:222
std::string debFileName
Definition: debrecords.h:73
debDebFileRecordParser(std::string FileName)
Definition: debrecords.cc:226
static bool GetContent(std::ostream &content, std::string const &debfile)
virtual void GetRec(const char *&Start, const char *&Stop) APT_OVERRIDE
Definition: debrecords.cc:197
virtual ~debRecordParserBase()
Definition: debrecords.cc:202
pkgTagSection Section
Definition: debrecords.h:28
virtual std::string SourceVer() APT_OVERRIDE
Definition: debrecords.cc:176
virtual std::string SourcePkg() APT_OVERRIDE
Definition: debrecords.cc:166
virtual HashStringList Hashes() const APT_OVERRIDE
Definition: debrecords.cc:82
virtual std::string Name() APT_OVERRIDE
Definition: debrecords.cc:64
virtual std::string FileName() APT_OVERRIDE
Definition: debrecords.cc:58
virtual std::string Homepage() APT_OVERRIDE
Definition: debrecords.cc:76
virtual std::string LongDesc(std::string const &lang) APT_OVERRIDE
Definition: debrecords.cc:122
virtual std::string ShortDesc(std::string const &lang) APT_OVERRIDE
Definition: debrecords.cc:110
virtual std::string Maintainer() APT_OVERRIDE
Definition: debrecords.cc:98
virtual std::string RecordField(const char *fieldName) APT_OVERRIDE
Definition: debrecords.cc:104
debRecordParser(std::string FileName, pkgCache &Cache)
Definition: debrecords.cc:34
pkgTagFile Tags
Definition: debrecords.h:59
virtual bool Jump(pkgCache::VerFileIterator const &Ver) APT_OVERRIDE
Definition: debrecords.cc:41
virtual ~debRecordParser()
Definition: debrecords.cc:54
bool Jump(pkgTagSection &Tag, unsigned long long Offset)
Definition: tagfile.cc:432
APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength, bool const Restart=true)
searches the boundaries of the current section
Definition: tagfile.cc:484
void GetSection(const char *&Start, const char *&Stop) const
Definition: tagfile.h:135
std::string FindS(APT::StringView sv) const
Definition: tagfile.h:70
APT_HIDDEN unsigned long long FindULL(Key key, unsigned long long const &Default=0) const
Definition: tagfile.cc:812
static const char *const SourceVerSeparators
Definition: debrecords.cc:164
APT_PUBLIC std::vector< std::string > const getLanguages(bool const &All=false, bool const &Cached=true, char const **const Locale=0)
Returns a vector of Language Codes.
pkgCache - Structure definitions for the cache file
bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest)
Definition: strutl.cc:155
int tolower_ascii(int const c) APT_PURE APT_COLD
Definition: strutl.cc:1503