]>
Commit | Line | Data |
---|---|---|
1 | // -*- mode: cpp; mode: fold -*- | |
2 | // Description /*{{{*/ | |
3 | // $Id: debindexfile.cc,v 1.5.2.3 2004/01/04 19:11:00 mdz Exp $ | |
4 | /* ###################################################################### | |
5 | ||
6 | Debian Specific sources.list types and the three sorts of Debian | |
7 | index files. | |
8 | ||
9 | ##################################################################### */ | |
10 | /*}}}*/ | |
11 | // Include Files /*{{{*/ | |
12 | #include <config.h> | |
13 | ||
14 | #include <apt-pkg/debindexfile.h> | |
15 | #include <apt-pkg/debsrcrecords.h> | |
16 | #include <apt-pkg/deblistparser.h> | |
17 | #include <apt-pkg/debrecords.h> | |
18 | #include <apt-pkg/configuration.h> | |
19 | #include <apt-pkg/progress.h> | |
20 | #include <apt-pkg/error.h> | |
21 | #include <apt-pkg/strutl.h> | |
22 | #include <apt-pkg/acquire-item.h> | |
23 | #include <apt-pkg/debmetaindex.h> | |
24 | #include <apt-pkg/gpgv.h> | |
25 | #include <apt-pkg/fileutl.h> | |
26 | #include <apt-pkg/indexfile.h> | |
27 | #include <apt-pkg/mmap.h> | |
28 | #include <apt-pkg/pkgcache.h> | |
29 | #include <apt-pkg/cacheiterators.h> | |
30 | #include <apt-pkg/pkgcachegen.h> | |
31 | #include <apt-pkg/pkgrecords.h> | |
32 | #include <apt-pkg/srcrecords.h> | |
33 | #include <apt-pkg/sptr.h> | |
34 | ||
35 | #include <stdio.h> | |
36 | #include <iostream> | |
37 | #include <sstream> | |
38 | #include <string> | |
39 | #include <memory> | |
40 | #include <sys/stat.h> | |
41 | /*}}}*/ | |
42 | ||
43 | // Sources Index /*{{{*/ | |
44 | debSourcesIndex::debSourcesIndex(IndexTarget const &Target,bool const Trusted) : | |
45 | pkgDebianIndexTargetFile(Target, Trusted), d(NULL) | |
46 | { | |
47 | } | |
48 | std::string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record, | |
49 | pkgSrcRecords::File const &File) const | |
50 | { | |
51 | // The result looks like: http://foo/debian/ stable/main src 1.1.1 (dsc) | |
52 | std::string Res = Target.Description; | |
53 | Res.erase(Target.Description.rfind(' ')); | |
54 | ||
55 | Res += " "; | |
56 | Res += Record.Package(); | |
57 | Res += " "; | |
58 | Res += Record.Version(); | |
59 | if (File.Type.empty() == false) | |
60 | Res += " (" + File.Type + ")"; | |
61 | return Res; | |
62 | } | |
63 | pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const | |
64 | { | |
65 | std::string const SourcesURI = IndexFileName(); | |
66 | if (FileExists(SourcesURI)) | |
67 | return new debSrcRecordParser(SourcesURI, this); | |
68 | return NULL; | |
69 | } | |
70 | bool debSourcesIndex::OpenListFile(FileFd &, std::string const &) | |
71 | { | |
72 | return true; | |
73 | } | |
74 | pkgCacheListParser * debSourcesIndex::CreateListParser(FileFd &) | |
75 | { | |
76 | return NULL; | |
77 | } | |
78 | uint8_t debSourcesIndex::GetIndexFlags() const | |
79 | { | |
80 | return 0; | |
81 | } | |
82 | /*}}}*/ | |
83 | // Packages Index /*{{{*/ | |
84 | debPackagesIndex::debPackagesIndex(IndexTarget const &Target, bool const Trusted) : | |
85 | pkgDebianIndexTargetFile(Target, Trusted), d(NULL) | |
86 | { | |
87 | } | |
88 | std::string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator const &Ver) const | |
89 | { | |
90 | std::string Res = Target.Description; | |
91 | Res.erase(Target.Description.rfind(' ')); | |
92 | ||
93 | Res += " "; | |
94 | Res += Ver.ParentPkg().Name(); | |
95 | Res += " "; | |
96 | std::string const Dist = Target.Option(IndexTarget::RELEASE); | |
97 | if (Dist.empty() == false && Dist[Dist.size() - 1] != '/') | |
98 | Res.append(Ver.Arch()).append(" "); | |
99 | Res += Ver.VerStr(); | |
100 | return Res; | |
101 | } | |
102 | uint8_t debPackagesIndex::GetIndexFlags() const | |
103 | { | |
104 | return 0; | |
105 | } | |
106 | /*}}}*/ | |
107 | // Translation-* Index /*{{{*/ | |
108 | debTranslationsIndex::debTranslationsIndex(IndexTarget const &Target) : | |
109 | pkgDebianIndexTargetFile(Target, true), d(NULL) | |
110 | {} | |
111 | bool debTranslationsIndex::HasPackages() const | |
112 | { | |
113 | return Exists(); | |
114 | } | |
115 | bool debTranslationsIndex::OpenListFile(FileFd &Pkg, std::string const &FileName) | |
116 | { | |
117 | if (FileExists(FileName)) | |
118 | return pkgDebianIndexTargetFile::OpenListFile(Pkg, FileName); | |
119 | return true; | |
120 | } | |
121 | uint8_t debTranslationsIndex::GetIndexFlags() const | |
122 | { | |
123 | return pkgCache::Flag::NotSource | pkgCache::Flag::NoPackages; | |
124 | } | |
125 | std::string debTranslationsIndex::GetArchitecture() const | |
126 | { | |
127 | return std::string(); | |
128 | } | |
129 | pkgCacheListParser * debTranslationsIndex::CreateListParser(FileFd &Pkg) | |
130 | { | |
131 | if (Pkg.IsOpen() == false) | |
132 | return NULL; | |
133 | _error->PushToStack(); | |
134 | pkgCacheListParser * const Parser = new debTranslationsParser(&Pkg); | |
135 | bool const newError = _error->PendingError(); | |
136 | _error->MergeWithStack(); | |
137 | return newError ? NULL : Parser; | |
138 | } | |
139 | /*}}}*/ | |
140 | // dpkg/status Index /*{{{*/ | |
141 | debStatusIndex::debStatusIndex(std::string const &File) : pkgDebianIndexRealFile(File, true), d(NULL) | |
142 | { | |
143 | } | |
144 | std::string debStatusIndex::GetArchitecture() const | |
145 | { | |
146 | return std::string(); | |
147 | } | |
148 | std::string debStatusIndex::GetComponent() const | |
149 | { | |
150 | return "now"; | |
151 | } | |
152 | uint8_t debStatusIndex::GetIndexFlags() const | |
153 | { | |
154 | return pkgCache::Flag::NotSource; | |
155 | } | |
156 | /*}}}*/ | |
157 | // DebPkgFile Index - a single .deb file as an index /*{{{*/ | |
158 | debDebPkgFileIndex::debDebPkgFileIndex(std::string const &DebFile) | |
159 | : pkgDebianIndexRealFile(DebFile, true), d(NULL), DebFile(DebFile) | |
160 | { | |
161 | } | |
162 | bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile) | |
163 | { | |
164 | struct stat Buf; | |
165 | if (stat(debfile.c_str(), &Buf) != 0) | |
166 | return false; | |
167 | ||
168 | // get the control data out of the deb file via dpkg-deb -I | |
169 | std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg-deb"); | |
170 | std::vector<const char *> Args; | |
171 | Args.push_back(dpkg.c_str()); | |
172 | Args.push_back("-I"); | |
173 | Args.push_back(debfile.c_str()); | |
174 | Args.push_back("control"); | |
175 | Args.push_back(NULL); | |
176 | FileFd PipeFd; | |
177 | pid_t Child; | |
178 | if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false) | |
179 | return _error->Error("Popen failed"); | |
180 | ||
181 | char buffer[1024]; | |
182 | do { | |
183 | unsigned long long actual = 0; | |
184 | if (PipeFd.Read(buffer, sizeof(buffer)-1, &actual) == false) | |
185 | return _error->Errno("read", "Failed to read dpkg pipe"); | |
186 | if (actual == 0) | |
187 | break; | |
188 | buffer[actual] = '\0'; | |
189 | content << buffer; | |
190 | } while(true); | |
191 | ExecWait(Child, "Popen"); | |
192 | ||
193 | content << "Filename: " << debfile << "\n"; | |
194 | content << "Size: " << Buf.st_size << "\n"; | |
195 | ||
196 | return true; | |
197 | } | |
198 | bool debDebPkgFileIndex::OpenListFile(FileFd &Pkg, std::string const &FileName) | |
199 | { | |
200 | // write the control data to a tempfile | |
201 | if (GetTempFile("deb-file-" + flNotDir(FileName), true, &Pkg) == NULL) | |
202 | return false; | |
203 | std::ostringstream content; | |
204 | if (GetContent(content, FileName) == false) | |
205 | return false; | |
206 | std::string const contentstr = content.str(); | |
207 | if (contentstr.empty()) | |
208 | return true; | |
209 | if (Pkg.Write(contentstr.c_str(), contentstr.length()) == false || Pkg.Seek(0) == false) | |
210 | return false; | |
211 | return true; | |
212 | } | |
213 | pkgCacheListParser * debDebPkgFileIndex::CreateListParser(FileFd &Pkg) | |
214 | { | |
215 | if (Pkg.IsOpen() == false) | |
216 | return NULL; | |
217 | _error->PushToStack(); | |
218 | pkgCacheListParser * const Parser = new debDebFileParser(&Pkg, DebFile); | |
219 | bool const newError = _error->PendingError(); | |
220 | _error->MergeWithStack(); | |
221 | return newError ? NULL : Parser; | |
222 | } | |
223 | uint8_t debDebPkgFileIndex::GetIndexFlags() const | |
224 | { | |
225 | return pkgCache::Flag::LocalSource; | |
226 | } | |
227 | std::string debDebPkgFileIndex::GetArchitecture() const | |
228 | { | |
229 | return std::string(); | |
230 | } | |
231 | std::string debDebPkgFileIndex::GetComponent() const | |
232 | { | |
233 | return "local-deb"; | |
234 | } | |
235 | pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const | |
236 | { | |
237 | std::string const FileName = IndexFileName(); | |
238 | pkgCache::PkgFileIterator File = Cache.FileBegin(); | |
239 | for (; File.end() == false; ++File) | |
240 | { | |
241 | if (File.FileName() == NULL || FileName != File.FileName()) | |
242 | continue; | |
243 | // we can't do size checks here as file size != content size | |
244 | return File; | |
245 | } | |
246 | ||
247 | return File; | |
248 | } | |
249 | ||
250 | /*}}}*/ | |
251 | // DscFile Index - a single .dsc file as an index /*{{{*/ | |
252 | debDscFileIndex::debDscFileIndex(std::string const &DscFile) | |
253 | : pkgDebianIndexRealFile(DscFile, true), d(NULL) | |
254 | { | |
255 | } | |
256 | pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const | |
257 | { | |
258 | if (Exists() == false) | |
259 | return NULL; | |
260 | return new debDscRecordParser(File, this); | |
261 | } | |
262 | /*}}}*/ | |
263 | ||
264 | // Index File types for Debian /*{{{*/ | |
265 | class APT_HIDDEN debIFTypeSrc : public pkgIndexFile::Type | |
266 | { | |
267 | public: | |
268 | debIFTypeSrc() {Label = "Debian Source Index";}; | |
269 | }; | |
270 | class APT_HIDDEN debIFTypePkg : public pkgIndexFile::Type | |
271 | { | |
272 | public: | |
273 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE | |
274 | { | |
275 | return new debRecordParser(File.FileName(),*File.Cache()); | |
276 | }; | |
277 | debIFTypePkg() {Label = "Debian Package Index";}; | |
278 | }; | |
279 | class APT_HIDDEN debIFTypeTrans : public debIFTypePkg | |
280 | { | |
281 | public: | |
282 | debIFTypeTrans() {Label = "Debian Translation Index";}; | |
283 | }; | |
284 | class APT_HIDDEN debIFTypeStatus : public pkgIndexFile::Type | |
285 | { | |
286 | public: | |
287 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE | |
288 | { | |
289 | return new debRecordParser(File.FileName(),*File.Cache()); | |
290 | }; | |
291 | debIFTypeStatus() {Label = "Debian dpkg status file";}; | |
292 | }; | |
293 | class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type | |
294 | { | |
295 | public: | |
296 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE | |
297 | { | |
298 | return new debDebFileRecordParser(File.FileName()); | |
299 | }; | |
300 | debIFTypeDebPkgFile() {Label = "Debian deb file";}; | |
301 | }; | |
302 | class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type | |
303 | { | |
304 | public: | |
305 | virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &DscFile) const APT_OVERRIDE | |
306 | { | |
307 | return new debDscRecordParser(DscFile, NULL); | |
308 | }; | |
309 | debIFTypeDscFile() {Label = "Debian dsc file";}; | |
310 | }; | |
311 | class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type | |
312 | { | |
313 | public: | |
314 | virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &SourceDir) const APT_OVERRIDE | |
315 | { | |
316 | return new debDscRecordParser(SourceDir + std::string("/debian/control"), NULL); | |
317 | }; | |
318 | debIFTypeDebianSourceDir() {Label = "Debian control file";}; | |
319 | }; | |
320 | ||
321 | APT_HIDDEN debIFTypeSrc _apt_Src; | |
322 | APT_HIDDEN debIFTypePkg _apt_Pkg; | |
323 | APT_HIDDEN debIFTypeTrans _apt_Trans; | |
324 | APT_HIDDEN debIFTypeStatus _apt_Status; | |
325 | APT_HIDDEN debIFTypeDebPkgFile _apt_DebPkgFile; | |
326 | // file based pseudo indexes | |
327 | APT_HIDDEN debIFTypeDscFile _apt_DscFile; | |
328 | APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir; | |
329 | ||
330 | const pkgIndexFile::Type *debSourcesIndex::GetType() const | |
331 | { | |
332 | return &_apt_Src; | |
333 | } | |
334 | const pkgIndexFile::Type *debPackagesIndex::GetType() const | |
335 | { | |
336 | return &_apt_Pkg; | |
337 | } | |
338 | const pkgIndexFile::Type *debTranslationsIndex::GetType() const | |
339 | { | |
340 | return &_apt_Trans; | |
341 | } | |
342 | const pkgIndexFile::Type *debStatusIndex::GetType() const | |
343 | { | |
344 | return &_apt_Status; | |
345 | } | |
346 | const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const | |
347 | { | |
348 | return &_apt_DebPkgFile; | |
349 | } | |
350 | const pkgIndexFile::Type *debDscFileIndex::GetType() const | |
351 | { | |
352 | return &_apt_DscFile; | |
353 | } | |
354 | const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const | |
355 | { | |
356 | return &_apt_DebianSourceDir; | |
357 | } | |
358 | /*}}}*/ | |
359 | ||
360 | debStatusIndex::~debStatusIndex() {} | |
361 | debPackagesIndex::~debPackagesIndex() {} | |
362 | debTranslationsIndex::~debTranslationsIndex() {} | |
363 | debSourcesIndex::~debSourcesIndex() {} | |
364 | ||
365 | debDebPkgFileIndex::~debDebPkgFileIndex() {} | |
366 | debDscFileIndex::~debDscFileIndex() {} |