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