]>
Commit | Line | Data |
---|---|---|
b2e465d6 AL |
1 | // -*- mode: cpp; mode: fold -*- |
2 | // Description /*{{{*/ | |
7db98ffc | 3 | // $Id: debindexfile.cc,v 1.5.2.3 2004/01/04 19:11:00 mdz Exp $ |
b2e465d6 AL |
4 | /* ###################################################################### |
5 | ||
6 | Debian Specific sources.list types and the three sorts of Debian | |
7 | index files. | |
8 | ||
9 | ##################################################################### */ | |
10 | /*}}}*/ | |
11 | // Include Files /*{{{*/ | |
ea542140 DK |
12 | #include <config.h> |
13 | ||
b2e465d6 AL |
14 | #include <apt-pkg/debindexfile.h> |
15 | #include <apt-pkg/debsrcrecords.h> | |
16 | #include <apt-pkg/deblistparser.h> | |
17 | #include <apt-pkg/debrecords.h> | |
b2e465d6 | 18 | #include <apt-pkg/configuration.h> |
b2e465d6 | 19 | #include <apt-pkg/error.h> |
453b82a3 DK |
20 | #include <apt-pkg/fileutl.h> |
21 | #include <apt-pkg/indexfile.h> | |
453b82a3 DK |
22 | #include <apt-pkg/pkgcache.h> |
23 | #include <apt-pkg/cacheiterators.h> | |
453b82a3 DK |
24 | #include <apt-pkg/pkgrecords.h> |
25 | #include <apt-pkg/srcrecords.h> | |
e011829d | 26 | |
453b82a3 DK |
27 | #include <stdio.h> |
28 | #include <iostream> | |
29 | #include <string> | |
ac7f8f79 | 30 | #include <sstream> |
88a8975f | 31 | |
b2e465d6 | 32 | #include <sys/stat.h> |
24a59c62 | 33 | #include <unistd.h> |
b2e465d6 AL |
34 | /*}}}*/ |
35 | ||
c9443c01 | 36 | // Sources Index /*{{{*/ |
e3c1cfc7 | 37 | debSourcesIndex::debSourcesIndex(IndexTarget const &Target,bool const Trusted) : |
c9443c01 | 38 | pkgDebianIndexTargetFile(Target, Trusted), d(NULL) |
b2e465d6 AL |
39 | { |
40 | } | |
c9443c01 | 41 | std::string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, |
b2e465d6 AL |
42 | pkgSrcRecords::File const &File) const |
43 | { | |
c9443c01 DK |
44 | // The result looks like: http://foo/debian/ stable/main src 1.1.1 (dsc) |
45 | std::string Res = Target.Description; | |
e3c1cfc7 DK |
46 | Res.erase(Target.Description.rfind(' ')); |
47 | ||
b2e465d6 AL |
48 | Res += " "; |
49 | Res += Record.Package(); | |
50 | Res += " "; | |
51 | Res += Record.Version(); | |
52 | if (File.Type.empty() == false) | |
53 | Res += " (" + File.Type + ")"; | |
54 | return Res; | |
55 | } | |
b2e465d6 AL |
56 | pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const |
57 | { | |
c9443c01 | 58 | std::string const SourcesURI = IndexFileName(); |
b0f4b486 MV |
59 | if (FileExists(SourcesURI)) |
60 | return new debSrcRecordParser(SourcesURI, this); | |
61 | return NULL; | |
c9443c01 DK |
62 | } |
63 | bool debSourcesIndex::OpenListFile(FileFd &, std::string const &) | |
64 | { | |
65 | return true; | |
66 | } | |
67 | pkgCacheListParser * debSourcesIndex::CreateListParser(FileFd &) | |
68 | { | |
69 | return NULL; | |
70 | } | |
71 | uint8_t debSourcesIndex::GetIndexFlags() const | |
72 | { | |
73 | return 0; | |
b2e465d6 AL |
74 | } |
75 | /*}}}*/ | |
c9443c01 | 76 | // Packages Index /*{{{*/ |
e3c1cfc7 | 77 | debPackagesIndex::debPackagesIndex(IndexTarget const &Target, bool const Trusted) : |
c9443c01 | 78 | pkgDebianIndexTargetFile(Target, Trusted), d(NULL) |
b2e465d6 AL |
79 | { |
80 | } | |
c9443c01 | 81 | std::string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator const &Ver) const |
b2e465d6 | 82 | { |
c9443c01 | 83 | std::string Res = Target.Description; |
8bd823d0 DK |
84 | { |
85 | auto const space = Target.Description.rfind(' '); | |
86 | if (space != std::string::npos) | |
87 | Res.erase(space); | |
88 | } | |
e3c1cfc7 | 89 | |
b2e465d6 AL |
90 | Res += " "; |
91 | Res += Ver.ParentPkg().Name(); | |
92 | Res += " "; | |
c9443c01 | 93 | std::string const Dist = Target.Option(IndexTarget::RELEASE); |
e3c1cfc7 | 94 | if (Dist.empty() == false && Dist[Dist.size() - 1] != '/') |
dd13742e | 95 | Res.append(Ver.Arch()).append(" "); |
b2e465d6 AL |
96 | Res += Ver.VerStr(); |
97 | return Res; | |
98 | } | |
c9443c01 | 99 | uint8_t debPackagesIndex::GetIndexFlags() const |
b2e465d6 | 100 | { |
c9443c01 | 101 | return 0; |
b2e465d6 AL |
102 | } |
103 | /*}}}*/ | |
c9443c01 | 104 | // Translation-* Index /*{{{*/ |
e3c1cfc7 | 105 | debTranslationsIndex::debTranslationsIndex(IndexTarget const &Target) : |
c9443c01 | 106 | pkgDebianIndexTargetFile(Target, true), d(NULL) |
45df0ad2 | 107 | {} |
c9443c01 | 108 | bool debTranslationsIndex::HasPackages() const |
11680bfd | 109 | { |
e3c1cfc7 | 110 | return Exists(); |
a52f938b | 111 | } |
c9443c01 DK |
112 | bool debTranslationsIndex::OpenListFile(FileFd &Pkg, std::string const &FileName) |
113 | { | |
114 | if (FileExists(FileName)) | |
115 | return pkgDebianIndexTargetFile::OpenListFile(Pkg, FileName); | |
a52f938b OS |
116 | return true; |
117 | } | |
c9443c01 | 118 | uint8_t debTranslationsIndex::GetIndexFlags() const |
c51c6f08 | 119 | { |
c9443c01 | 120 | return pkgCache::Flag::NotSource | pkgCache::Flag::NoPackages; |
c51c6f08 | 121 | } |
c9443c01 | 122 | std::string debTranslationsIndex::GetArchitecture() const |
b2e465d6 | 123 | { |
c9443c01 | 124 | return std::string(); |
b2e465d6 | 125 | } |
c9443c01 | 126 | pkgCacheListParser * debTranslationsIndex::CreateListParser(FileFd &Pkg) |
b2e465d6 | 127 | { |
c9443c01 | 128 | if (Pkg.IsOpen() == false) |
c48ef894 | 129 | return nullptr; |
c9443c01 DK |
130 | _error->PushToStack(); |
131 | pkgCacheListParser * const Parser = new debTranslationsParser(&Pkg); | |
132 | bool const newError = _error->PendingError(); | |
133 | _error->MergeWithStack(); | |
c48ef894 DK |
134 | if (newError) |
135 | { | |
136 | delete Parser; | |
137 | return nullptr; | |
138 | } | |
139 | else | |
140 | return Parser; | |
b2e465d6 AL |
141 | } |
142 | /*}}}*/ | |
c9443c01 DK |
143 | // dpkg/status Index /*{{{*/ |
144 | debStatusIndex::debStatusIndex(std::string const &File) : pkgDebianIndexRealFile(File, true), d(NULL) | |
b2e465d6 | 145 | { |
b2e465d6 | 146 | } |
c9443c01 | 147 | std::string debStatusIndex::GetArchitecture() const |
b2e465d6 | 148 | { |
c9443c01 | 149 | return std::string(); |
b2e465d6 | 150 | } |
c9443c01 | 151 | std::string debStatusIndex::GetComponent() const |
0d29b9d4 | 152 | { |
c9443c01 | 153 | return "now"; |
0d29b9d4 | 154 | } |
c9443c01 | 155 | uint8_t debStatusIndex::GetIndexFlags() const |
0d29b9d4 | 156 | { |
c9443c01 | 157 | return pkgCache::Flag::NotSource; |
0d29b9d4 | 158 | } |
1c73b0fc JAK |
159 | |
160 | pkgCacheListParser * debStatusIndex::CreateListParser(FileFd &Pkg) | |
161 | { | |
162 | if (Pkg.IsOpen() == false) | |
c48ef894 | 163 | return nullptr; |
1c73b0fc JAK |
164 | _error->PushToStack(); |
165 | pkgCacheListParser * const Parser = new debStatusListParser(&Pkg); | |
166 | bool const newError = _error->PendingError(); | |
167 | _error->MergeWithStack(); | |
c48ef894 DK |
168 | if (newError) |
169 | { | |
170 | delete Parser; | |
171 | return nullptr; | |
172 | } | |
173 | else | |
174 | return Parser; | |
1c73b0fc | 175 | } |
c9443c01 DK |
176 | /*}}}*/ |
177 | // DebPkgFile Index - a single .deb file as an index /*{{{*/ | |
178 | debDebPkgFileIndex::debDebPkgFileIndex(std::string const &DebFile) | |
179 | : pkgDebianIndexRealFile(DebFile, true), d(NULL), DebFile(DebFile) | |
0d29b9d4 | 180 | { |
0d29b9d4 | 181 | } |
2f6a2fbb | 182 | bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile) |
0d29b9d4 | 183 | { |
c9443c01 DK |
184 | struct stat Buf; |
185 | if (stat(debfile.c_str(), &Buf) != 0) | |
186 | return false; | |
187 | ||
2f6a2fbb DK |
188 | // get the control data out of the deb file via dpkg-deb -I |
189 | std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg-deb"); | |
fdff5b03 MV |
190 | std::vector<const char *> Args; |
191 | Args.push_back(dpkg.c_str()); | |
fdff5b03 | 192 | Args.push_back("-I"); |
2f6a2fbb | 193 | Args.push_back(debfile.c_str()); |
fdff5b03 MV |
194 | Args.push_back("control"); |
195 | Args.push_back(NULL); | |
a9d990a2 MV |
196 | FileFd PipeFd; |
197 | pid_t Child; | |
fdff5b03 | 198 | if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false) |
a9d990a2 | 199 | return _error->Error("Popen failed"); |
2f6a2fbb | 200 | |
2f91076d | 201 | content << "Filename: " << debfile << "\n"; |
b58e2c7c | 202 | content << "Size: " << std::to_string(Buf.st_size) << "\n"; |
2f91076d | 203 | bool first_line_seen = false; |
2f6a2fbb DK |
204 | char buffer[1024]; |
205 | do { | |
206 | unsigned long long actual = 0; | |
207 | if (PipeFd.Read(buffer, sizeof(buffer)-1, &actual) == false) | |
208 | return _error->Errno("read", "Failed to read dpkg pipe"); | |
209 | if (actual == 0) | |
210 | break; | |
211 | buffer[actual] = '\0'; | |
2f91076d DK |
212 | char const * b = buffer; |
213 | if (first_line_seen == false) | |
214 | { | |
215 | for (; *b != '\0' && (*b == '\n' || *b == '\r'); ++b) | |
216 | /* skip over leading newlines */; | |
217 | if (*b == '\0') | |
218 | continue; | |
219 | first_line_seen = true; | |
220 | } | |
221 | content << b; | |
2f6a2fbb | 222 | } while(true); |
a9d990a2 | 223 | ExecWait(Child, "Popen"); |
0d29b9d4 | 224 | |
2f6a2fbb DK |
225 | return true; |
226 | } | |
c9443c01 | 227 | bool debDebPkgFileIndex::OpenListFile(FileFd &Pkg, std::string const &FileName) |
2f6a2fbb | 228 | { |
2f6a2fbb | 229 | // write the control data to a tempfile |
c9443c01 | 230 | if (GetTempFile("deb-file-" + flNotDir(FileName), true, &Pkg) == NULL) |
0d29b9d4 | 231 | return false; |
2f6a2fbb | 232 | std::ostringstream content; |
c9443c01 | 233 | if (GetContent(content, FileName) == false) |
2f6a2fbb DK |
234 | return false; |
235 | std::string const contentstr = content.str(); | |
5465192b DK |
236 | if (contentstr.empty()) |
237 | return true; | |
c9443c01 DK |
238 | if (Pkg.Write(contentstr.c_str(), contentstr.length()) == false || Pkg.Seek(0) == false) |
239 | return false; | |
0d29b9d4 MV |
240 | return true; |
241 | } | |
c9443c01 DK |
242 | pkgCacheListParser * debDebPkgFileIndex::CreateListParser(FileFd &Pkg) |
243 | { | |
244 | if (Pkg.IsOpen() == false) | |
c48ef894 | 245 | return nullptr; |
c9443c01 DK |
246 | _error->PushToStack(); |
247 | pkgCacheListParser * const Parser = new debDebFileParser(&Pkg, DebFile); | |
248 | bool const newError = _error->PendingError(); | |
249 | _error->MergeWithStack(); | |
c48ef894 DK |
250 | if (newError) |
251 | { | |
252 | delete Parser; | |
253 | return nullptr; | |
254 | } | |
255 | else | |
256 | return Parser; | |
c9443c01 DK |
257 | } |
258 | uint8_t debDebPkgFileIndex::GetIndexFlags() const | |
259 | { | |
260 | return pkgCache::Flag::LocalSource; | |
261 | } | |
262 | std::string debDebPkgFileIndex::GetArchitecture() const | |
263 | { | |
264 | return std::string(); | |
265 | } | |
266 | std::string debDebPkgFileIndex::GetComponent() const | |
267 | { | |
268 | return "local-deb"; | |
269 | } | |
0d29b9d4 MV |
270 | pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const |
271 | { | |
c9443c01 | 272 | std::string const FileName = IndexFileName(); |
0d29b9d4 MV |
273 | pkgCache::PkgFileIterator File = Cache.FileBegin(); |
274 | for (; File.end() == false; ++File) | |
275 | { | |
c9443c01 | 276 | if (File.FileName() == NULL || FileName != File.FileName()) |
0d29b9d4 | 277 | continue; |
c9443c01 DK |
278 | // we can't do size checks here as file size != content size |
279 | return File; | |
0d29b9d4 | 280 | } |
5465192b | 281 | |
0d29b9d4 MV |
282 | return File; |
283 | } | |
64b66a46 DK |
284 | std::string debDebPkgFileIndex::ArchiveInfo_impl(pkgCache::VerIterator const &Ver) const |
285 | { | |
286 | std::string Res = IndexFileName() + " "; | |
287 | Res.append(Ver.ParentPkg().Name()).append(" "); | |
288 | Res.append(Ver.Arch()).append(" "); | |
289 | Res.append(Ver.VerStr()); | |
290 | return Res; | |
291 | } | |
c9443c01 DK |
292 | /*}}}*/ |
293 | // DscFile Index - a single .dsc file as an index /*{{{*/ | |
5465192b | 294 | debDscFileIndex::debDscFileIndex(std::string const &DscFile) |
c9443c01 | 295 | : pkgDebianIndexRealFile(DscFile, true), d(NULL) |
a49e7948 MV |
296 | { |
297 | } | |
a49e7948 MV |
298 | pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const |
299 | { | |
c9443c01 | 300 | if (Exists() == false) |
a49e7948 | 301 | return NULL; |
c9443c01 | 302 | return new debDscRecordParser(File, this); |
f359b7e8 DK |
303 | } |
304 | std::string debDscFileIndex::GetComponent() const | |
305 | { | |
306 | return "local-dsc"; | |
307 | } | |
308 | std::string debDscFileIndex::GetArchitecture() const | |
309 | { | |
310 | return "source"; | |
311 | } | |
312 | uint8_t debDscFileIndex::GetIndexFlags() const | |
313 | { | |
314 | return pkgCache::Flag::LocalSource; | |
315 | } | |
316 | /*}}}*/ | |
317 | // ControlFile Index - a directory with a debian/control file /*{{{*/ | |
318 | std::string debDebianSourceDirIndex::GetComponent() const | |
319 | { | |
320 | return "local-control"; | |
a49e7948 MV |
321 | } |
322 | /*}}}*/ | |
a249b3e6 DK |
323 | // String Package Index - a string of Packages file content /*{{{*/ |
324 | std::string debStringPackageIndex::GetArchitecture() const | |
325 | { | |
326 | return std::string(); | |
327 | } | |
328 | std::string debStringPackageIndex::GetComponent() const | |
329 | { | |
330 | return "apt-tmp-index"; | |
331 | } | |
332 | uint8_t debStringPackageIndex::GetIndexFlags() const | |
333 | { | |
334 | return pkgCache::Flag::NotSource; | |
335 | } | |
336 | const pkgIndexFile::Type *debStringPackageIndex::GetType() const | |
337 | { | |
338 | return pkgIndexFile::Type::GetType("Debian Package Index"); | |
339 | } | |
340 | debStringPackageIndex::debStringPackageIndex(std::string const &content) : | |
341 | pkgDebianIndexRealFile("", false), d(NULL) | |
342 | { | |
343 | char fn[1024]; | |
344 | std::string const tempdir = GetTempDir(); | |
345 | snprintf(fn, sizeof(fn), "%s/%s.XXXXXX", tempdir.c_str(), "apt-tmp-index"); | |
346 | int const fd = mkstemp(fn); | |
347 | File = fn; | |
348 | FileFd::Write(fd, content.data(), content.length()); | |
349 | close(fd); | |
350 | } | |
351 | debStringPackageIndex::~debStringPackageIndex() | |
352 | { | |
353 | RemoveFile("~debStringPackageIndex", File); | |
354 | } | |
355 | /*}}}*/ | |
5465192b | 356 | |
b2e465d6 | 357 | // Index File types for Debian /*{{{*/ |
dce45dbe | 358 | class APT_HIDDEN debIFTypeSrc : public pkgIndexFile::Type |
b2e465d6 AL |
359 | { |
360 | public: | |
b2e465d6 AL |
361 | debIFTypeSrc() {Label = "Debian Source Index";}; |
362 | }; | |
dce45dbe | 363 | class APT_HIDDEN debIFTypePkg : public pkgIndexFile::Type |
b2e465d6 AL |
364 | { |
365 | public: | |
c9443c01 | 366 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE |
b2e465d6 AL |
367 | { |
368 | return new debRecordParser(File.FileName(),*File.Cache()); | |
369 | }; | |
370 | debIFTypePkg() {Label = "Debian Package Index";}; | |
371 | }; | |
dce45dbe | 372 | class APT_HIDDEN debIFTypeTrans : public debIFTypePkg |
97234432 MV |
373 | { |
374 | public: | |
375 | debIFTypeTrans() {Label = "Debian Translation Index";}; | |
376 | }; | |
dce45dbe | 377 | class APT_HIDDEN debIFTypeStatus : public pkgIndexFile::Type |
b2e465d6 AL |
378 | { |
379 | public: | |
c9443c01 | 380 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE |
b2e465d6 AL |
381 | { |
382 | return new debRecordParser(File.FileName(),*File.Cache()); | |
383 | }; | |
384 | debIFTypeStatus() {Label = "Debian dpkg status file";}; | |
385 | }; | |
dce45dbe | 386 | class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type |
0d29b9d4 MV |
387 | { |
388 | public: | |
c9443c01 | 389 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE |
0d29b9d4 | 390 | { |
2f6a2fbb | 391 | return new debDebFileRecordParser(File.FileName()); |
0d29b9d4 | 392 | }; |
463c8d80 | 393 | debIFTypeDebPkgFile() {Label = "Debian deb file";}; |
0d29b9d4 | 394 | }; |
dce45dbe | 395 | class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type |
a49e7948 MV |
396 | { |
397 | public: | |
c9443c01 | 398 | virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &DscFile) const APT_OVERRIDE |
a49e7948 MV |
399 | { |
400 | return new debDscRecordParser(DscFile, NULL); | |
401 | }; | |
463c8d80 | 402 | debIFTypeDscFile() {Label = "Debian dsc file";}; |
a49e7948 | 403 | }; |
dce45dbe | 404 | class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type |
77da39b9 MV |
405 | { |
406 | public: | |
c9443c01 | 407 | virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &SourceDir) const APT_OVERRIDE |
77da39b9 | 408 | { |
c9443c01 | 409 | return new debDscRecordParser(SourceDir + std::string("/debian/control"), NULL); |
77da39b9 | 410 | }; |
463c8d80 | 411 | debIFTypeDebianSourceDir() {Label = "Debian control file";}; |
77da39b9 | 412 | }; |
a49e7948 | 413 | |
dce45dbe DK |
414 | APT_HIDDEN debIFTypeSrc _apt_Src; |
415 | APT_HIDDEN debIFTypePkg _apt_Pkg; | |
416 | APT_HIDDEN debIFTypeTrans _apt_Trans; | |
417 | APT_HIDDEN debIFTypeStatus _apt_Status; | |
418 | APT_HIDDEN debIFTypeDebPkgFile _apt_DebPkgFile; | |
a49e7948 | 419 | // file based pseudo indexes |
dce45dbe DK |
420 | APT_HIDDEN debIFTypeDscFile _apt_DscFile; |
421 | APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir; | |
b2e465d6 AL |
422 | |
423 | const pkgIndexFile::Type *debSourcesIndex::GetType() const | |
424 | { | |
425 | return &_apt_Src; | |
426 | } | |
427 | const pkgIndexFile::Type *debPackagesIndex::GetType() const | |
428 | { | |
429 | return &_apt_Pkg; | |
430 | } | |
a52f938b OS |
431 | const pkgIndexFile::Type *debTranslationsIndex::GetType() const |
432 | { | |
97234432 | 433 | return &_apt_Trans; |
a52f938b | 434 | } |
b2e465d6 AL |
435 | const pkgIndexFile::Type *debStatusIndex::GetType() const |
436 | { | |
437 | return &_apt_Status; | |
438 | } | |
0d29b9d4 MV |
439 | const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const |
440 | { | |
441 | return &_apt_DebPkgFile; | |
070536e6 | 442 | } |
a49e7948 MV |
443 | const pkgIndexFile::Type *debDscFileIndex::GetType() const |
444 | { | |
445 | return &_apt_DscFile; | |
446 | } | |
77da39b9 MV |
447 | const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const |
448 | { | |
449 | return &_apt_DebianSourceDir; | |
0d29b9d4 | 450 | } |
b2e465d6 | 451 | /*}}}*/ |
862bafea DK |
452 | |
453 | debStatusIndex::~debStatusIndex() {} | |
454 | debPackagesIndex::~debPackagesIndex() {} | |
455 | debTranslationsIndex::~debTranslationsIndex() {} | |
456 | debSourcesIndex::~debSourcesIndex() {} | |
457 | ||
458 | debDebPkgFileIndex::~debDebPkgFileIndex() {} | |
c8a4ce6c | 459 | debDscFileIndex::~debDscFileIndex() {} |