]>
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 | // DebPkgFile Index - a single .deb file as an index /*{{{*/ | |
150 | debDebPkgFileIndex::debDebPkgFileIndex(std::string const &DebFile) | |
151 | : pkgDebianIndexRealFile(DebFile, true), d(NULL), DebFile(DebFile) | |
152 | { | |
153 | } | |
154 | bool debDebPkgFileIndex::GetContent(std::ostream &content, std::string const &debfile) | |
155 | { | |
156 | struct stat Buf; | |
157 | if (stat(debfile.c_str(), &Buf) != 0) | |
158 | return false; | |
159 | ||
160 | // get the control data out of the deb file via dpkg-deb -I | |
161 | std::string dpkg = _config->Find("Dir::Bin::dpkg","dpkg-deb"); | |
162 | std::vector<const char *> Args; | |
163 | Args.push_back(dpkg.c_str()); | |
164 | Args.push_back("-I"); | |
165 | Args.push_back(debfile.c_str()); | |
166 | Args.push_back("control"); | |
167 | Args.push_back(NULL); | |
168 | FileFd PipeFd; | |
169 | pid_t Child; | |
170 | if(Popen((const char**)&Args[0], PipeFd, Child, FileFd::ReadOnly) == false) | |
171 | return _error->Error("Popen failed"); | |
172 | ||
173 | char buffer[1024]; | |
174 | do { | |
175 | unsigned long long actual = 0; | |
176 | if (PipeFd.Read(buffer, sizeof(buffer)-1, &actual) == false) | |
177 | return _error->Errno("read", "Failed to read dpkg pipe"); | |
178 | if (actual == 0) | |
179 | break; | |
180 | buffer[actual] = '\0'; | |
181 | content << buffer; | |
182 | } while(true); | |
183 | ExecWait(Child, "Popen"); | |
184 | ||
185 | content << "Filename: " << debfile << "\n"; | |
186 | content << "Size: " << Buf.st_size << "\n"; | |
187 | ||
188 | return true; | |
189 | } | |
190 | bool debDebPkgFileIndex::OpenListFile(FileFd &Pkg, std::string const &FileName) | |
191 | { | |
192 | // write the control data to a tempfile | |
193 | if (GetTempFile("deb-file-" + flNotDir(FileName), true, &Pkg) == NULL) | |
194 | return false; | |
195 | std::ostringstream content; | |
196 | if (GetContent(content, FileName) == false) | |
197 | return false; | |
198 | std::string const contentstr = content.str(); | |
199 | if (contentstr.empty()) | |
200 | return true; | |
201 | if (Pkg.Write(contentstr.c_str(), contentstr.length()) == false || Pkg.Seek(0) == false) | |
202 | return false; | |
203 | return true; | |
204 | } | |
205 | pkgCacheListParser * debDebPkgFileIndex::CreateListParser(FileFd &Pkg) | |
206 | { | |
207 | if (Pkg.IsOpen() == false) | |
208 | return NULL; | |
209 | _error->PushToStack(); | |
210 | pkgCacheListParser * const Parser = new debDebFileParser(&Pkg, DebFile); | |
211 | bool const newError = _error->PendingError(); | |
212 | _error->MergeWithStack(); | |
213 | return newError ? NULL : Parser; | |
214 | } | |
215 | uint8_t debDebPkgFileIndex::GetIndexFlags() const | |
216 | { | |
217 | return pkgCache::Flag::LocalSource; | |
218 | } | |
219 | std::string debDebPkgFileIndex::GetArchitecture() const | |
220 | { | |
221 | return std::string(); | |
222 | } | |
223 | std::string debDebPkgFileIndex::GetComponent() const | |
224 | { | |
225 | return "local-deb"; | |
226 | } | |
227 | pkgCache::PkgFileIterator debDebPkgFileIndex::FindInCache(pkgCache &Cache) const | |
228 | { | |
229 | std::string const FileName = IndexFileName(); | |
230 | pkgCache::PkgFileIterator File = Cache.FileBegin(); | |
231 | for (; File.end() == false; ++File) | |
232 | { | |
233 | if (File.FileName() == NULL || FileName != File.FileName()) | |
234 | continue; | |
235 | // we can't do size checks here as file size != content size | |
236 | return File; | |
237 | } | |
238 | ||
239 | return File; | |
240 | } | |
241 | ||
242 | /*}}}*/ | |
243 | // DscFile Index - a single .dsc file as an index /*{{{*/ | |
244 | debDscFileIndex::debDscFileIndex(std::string const &DscFile) | |
245 | : pkgDebianIndexRealFile(DscFile, true), d(NULL) | |
246 | { | |
247 | } | |
248 | pkgSrcRecords::Parser *debDscFileIndex::CreateSrcParser() const | |
249 | { | |
250 | if (Exists() == false) | |
251 | return NULL; | |
252 | return new debDscRecordParser(File, this); | |
253 | } | |
254 | /*}}}*/ | |
255 | ||
256 | // Index File types for Debian /*{{{*/ | |
257 | class APT_HIDDEN debIFTypeSrc : public pkgIndexFile::Type | |
258 | { | |
259 | public: | |
260 | debIFTypeSrc() {Label = "Debian Source Index";}; | |
261 | }; | |
262 | class APT_HIDDEN debIFTypePkg : public pkgIndexFile::Type | |
263 | { | |
264 | public: | |
265 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE | |
266 | { | |
267 | return new debRecordParser(File.FileName(),*File.Cache()); | |
268 | }; | |
269 | debIFTypePkg() {Label = "Debian Package Index";}; | |
270 | }; | |
271 | class APT_HIDDEN debIFTypeTrans : public debIFTypePkg | |
272 | { | |
273 | public: | |
274 | debIFTypeTrans() {Label = "Debian Translation Index";}; | |
275 | }; | |
276 | class APT_HIDDEN debIFTypeStatus : public pkgIndexFile::Type | |
277 | { | |
278 | public: | |
279 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE | |
280 | { | |
281 | return new debRecordParser(File.FileName(),*File.Cache()); | |
282 | }; | |
283 | debIFTypeStatus() {Label = "Debian dpkg status file";}; | |
284 | }; | |
285 | class APT_HIDDEN debIFTypeDebPkgFile : public pkgIndexFile::Type | |
286 | { | |
287 | public: | |
288 | virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator const &File) const APT_OVERRIDE | |
289 | { | |
290 | return new debDebFileRecordParser(File.FileName()); | |
291 | }; | |
292 | debIFTypeDebPkgFile() {Label = "Debian deb file";}; | |
293 | }; | |
294 | class APT_HIDDEN debIFTypeDscFile : public pkgIndexFile::Type | |
295 | { | |
296 | public: | |
297 | virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &DscFile) const APT_OVERRIDE | |
298 | { | |
299 | return new debDscRecordParser(DscFile, NULL); | |
300 | }; | |
301 | debIFTypeDscFile() {Label = "Debian dsc file";}; | |
302 | }; | |
303 | class APT_HIDDEN debIFTypeDebianSourceDir : public pkgIndexFile::Type | |
304 | { | |
305 | public: | |
306 | virtual pkgSrcRecords::Parser *CreateSrcPkgParser(std::string const &SourceDir) const APT_OVERRIDE | |
307 | { | |
308 | return new debDscRecordParser(SourceDir + std::string("/debian/control"), NULL); | |
309 | }; | |
310 | debIFTypeDebianSourceDir() {Label = "Debian control file";}; | |
311 | }; | |
312 | ||
313 | APT_HIDDEN debIFTypeSrc _apt_Src; | |
314 | APT_HIDDEN debIFTypePkg _apt_Pkg; | |
315 | APT_HIDDEN debIFTypeTrans _apt_Trans; | |
316 | APT_HIDDEN debIFTypeStatus _apt_Status; | |
317 | APT_HIDDEN debIFTypeDebPkgFile _apt_DebPkgFile; | |
318 | // file based pseudo indexes | |
319 | APT_HIDDEN debIFTypeDscFile _apt_DscFile; | |
320 | APT_HIDDEN debIFTypeDebianSourceDir _apt_DebianSourceDir; | |
321 | ||
322 | const pkgIndexFile::Type *debSourcesIndex::GetType() const | |
323 | { | |
324 | return &_apt_Src; | |
325 | } | |
326 | const pkgIndexFile::Type *debPackagesIndex::GetType() const | |
327 | { | |
328 | return &_apt_Pkg; | |
329 | } | |
330 | const pkgIndexFile::Type *debTranslationsIndex::GetType() const | |
331 | { | |
332 | return &_apt_Trans; | |
333 | } | |
334 | const pkgIndexFile::Type *debStatusIndex::GetType() const | |
335 | { | |
336 | return &_apt_Status; | |
337 | } | |
338 | const pkgIndexFile::Type *debDebPkgFileIndex::GetType() const | |
339 | { | |
340 | return &_apt_DebPkgFile; | |
341 | } | |
342 | const pkgIndexFile::Type *debDscFileIndex::GetType() const | |
343 | { | |
344 | return &_apt_DscFile; | |
345 | } | |
346 | const pkgIndexFile::Type *debDebianSourceDirIndex::GetType() const | |
347 | { | |
348 | return &_apt_DebianSourceDir; | |
349 | } | |
350 | /*}}}*/ | |
351 | ||
352 | debStatusIndex::~debStatusIndex() {} | |
353 | debPackagesIndex::~debPackagesIndex() {} | |
354 | debTranslationsIndex::~debTranslationsIndex() {} | |
355 | debSourcesIndex::~debSourcesIndex() {} | |
356 | ||
357 | debDebPkgFileIndex::~debDebPkgFileIndex() {} | |
358 | debDscFileIndex::~debDscFileIndex() {} |