]> git.saurik.com Git - apt.git/blame - apt-pkg/deb/debsrcrecords.cc
Merge remote-tracking branch 'upstream/debian/experimental' into feature/acq-trans
[apt.git] / apt-pkg / deb / debsrcrecords.cc
CommitLineData
11e7af84
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
c33b707e 3// $Id: debsrcrecords.cc,v 1.6 2004/03/17 05:58:54 mdz Exp $
11e7af84
AL
4/* ######################################################################
5
6 Debian Source Package Records - Parser implementation for Debian style
7 source indexes
8
9 ##################################################################### */
10 /*}}}*/
11// Include Files /*{{{*/
ea542140
DK
12#include <config.h>
13
b2e465d6 14#include <apt-pkg/deblistparser.h>
11e7af84
AL
15#include <apt-pkg/debsrcrecords.h>
16#include <apt-pkg/error.h>
36f610f1 17#include <apt-pkg/strutl.h>
b0e1a43f 18#include <apt-pkg/aptconfiguration.h>
453b82a3
DK
19#include <apt-pkg/srcrecords.h>
20#include <apt-pkg/tagfile.h>
cb6a2b3e 21#include <apt-pkg/hashes.h>
feab34c5 22#include <apt-pkg/gpgv.h>
4ab24e53 23
453b82a3
DK
24#include <ctype.h>
25#include <stdlib.h>
26#include <string.h>
27#include <algorithm>
28#include <string>
29#include <vector>
11e7af84
AL
30 /*}}}*/
31
453b82a3 32using std::max;
8f3ba4e8
DK
33using std::string;
34
11e7af84
AL
35// SrcRecordParser::Binaries - Return the binaries field /*{{{*/
36// ---------------------------------------------------------------------
37/* This member parses the binaries field into a pair of class arrays and
38 returns a list of strings representing all of the components of the
39 binaries field. The returned array need not be freed and will be
b2e465d6
AL
40 reused by the next Binaries function call. This function is commonly
41 used during scanning to find the right package */
11e7af84
AL
42const char **debSrcRecordParser::Binaries()
43{
39fb1e24
DK
44 const char *Start, *End;
45 if (Sect.Find("Binary", Start, End) == false)
46 return NULL;
47 for (; isspace(*Start) != 0; ++Start);
48 if (Start >= End)
49 return NULL;
50
51 StaticBinList.clear();
52 free(Buffer);
53 Buffer = strndup(Start, End - Start);
c33b707e 54
39fb1e24
DK
55 char* bin = Buffer;
56 do {
57 char* binStartNext = strchrnul(bin, ',');
58 char* binEnd = binStartNext - 1;
59 for (; isspace(*binEnd) != 0; --binEnd)
80624be7 60 binEnd = 0;
39fb1e24
DK
61 StaticBinList.push_back(bin);
62 if (*binStartNext != ',')
63 break;
64 *binStartNext = '\0';
80624be7
MV
65 for (bin = binStartNext + 1; isspace(*bin) != 0; ++bin)
66 ;
39fb1e24
DK
67 } while (*bin != '\0');
68 StaticBinList.push_back(NULL);
c33b707e 69
e788a834 70 return &StaticBinList[0];
b2e465d6
AL
71}
72 /*}}}*/
73// SrcRecordParser::BuildDepends - Return the Build-Depends information /*{{{*/
74// ---------------------------------------------------------------------
75/* This member parses the build-depends information and returns a list of
76 package/version records representing the build dependency. The returned
77 array need not be freed and will be reused by the next call to this
78 function */
8f3ba4e8 79bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps,
41c81fd8 80 bool const &ArchOnly, bool const &StripMultiArch)
b2e465d6
AL
81{
82 unsigned int I;
83 const char *Start, *Stop;
84 BuildDepRec rec;
85 const char *fields[] = {"Build-Depends",
86 "Build-Depends-Indep",
87 "Build-Conflicts",
88 "Build-Conflicts-Indep"};
89
90 BuildDeps.clear();
11e7af84 91
b2e465d6 92 for (I = 0; I < 4; I++)
11e7af84 93 {
45430cbf
AL
94 if (ArchOnly && (I == 1 || I == 3))
95 continue;
96
b2e465d6
AL
97 if (Sect.Find(fields[I], Start, Stop) == false)
98 continue;
11e7af84 99
b2e465d6
AL
100 while (1)
101 {
102 Start = debListParser::ParseDepends(Start, Stop,
565ded7b 103 rec.Package,rec.Version,rec.Op,true,StripMultiArch,true);
b2e465d6
AL
104
105 if (Start == 0)
106 return _error->Error("Problem parsing dependency: %s", fields[I]);
107 rec.Type = I;
108
109 if (rec.Package != "")
110 BuildDeps.push_back(rec);
111
112 if (Start == Stop)
113 break;
114 }
11e7af84
AL
115 }
116
b2e465d6 117 return true;
11e7af84
AL
118}
119 /*}}}*/
36f610f1
AL
120// SrcRecordParser::Files - Return a list of files for this source /*{{{*/
121// ---------------------------------------------------------------------
122/* This parses the list of files and returns it, each file is required to have
123 a complete source package */
8f3ba4e8 124bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
36f610f1
AL
125{
126 List.erase(List.begin(),List.end());
cb6a2b3e 127
1262d358
DK
128 // Stash the / terminated directory prefix
129 string Base = Sect.FindS("Directory");
130 if (Base.empty() == false && Base[Base.length()-1] != '/')
131 Base += '/';
cb6a2b3e 132
1262d358 133 std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions();
cb6a2b3e 134
1262d358
DK
135 for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
136 {
137 // derive field from checksum type
138 std::string checksumField("Checksums-");
139 if (strcmp(*type, "MD5Sum") == 0)
140 checksumField = "Files"; // historic name for MD5 checksums
141 else
142 checksumField.append(*type);
143
144 string const Files = Sect.FindS(checksumField.c_str());
145 if (Files.empty() == true)
146 continue;
cb6a2b3e
MV
147
148 // Iterate over the entire list grabbing each triplet
149 const char *C = Files.c_str();
150 while (*C != 0)
1262d358
DK
151 {
152 string hash, size, path;
153
154 // Parse each of the elements
155 if (ParseQuoteWord(C, hash) == false ||
156 ParseQuoteWord(C, size) == false ||
157 ParseQuoteWord(C, path) == false)
158 return _error->Error("Error parsing file record in %s of source package %s", checksumField.c_str(), Package().c_str());
159
160 HashString const hashString(*type, hash);
161 if (Base.empty() == false)
162 path = Base + path;
163
164 // look if we have a record for this file already
165 std::vector<pkgSrcRecords::File>::iterator file = List.begin();
166 for (; file != List.end(); ++file)
167 if (file->Path == path)
168 break;
169
170 // we have it already, store the new hash and be done
171 if (file != List.end())
172 {
173#if __GNUC__ >= 4
174 // set for compatibility only, so warn users not us
175 #pragma GCC diagnostic push
176 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
177#endif
178 if (checksumField == "Files")
179 file->MD5Hash = hash;
180#if __GNUC__ >= 4
181 #pragma GCC diagnostic pop
182#endif
183 // an error here indicates that we have two different hashes for the same file
184 if (file->Hashes.push_back(hashString) == false)
185 return _error->Error("Error parsing checksum in %s of source package %s", checksumField.c_str(), Package().c_str());
186 continue;
187 }
188
189 // we haven't seen this file yet
190 pkgSrcRecords::File F;
191 F.Path = path;
192 F.Size = strtoull(size.c_str(), NULL, 10);
193 F.Hashes.push_back(hashString);
194
195#if __GNUC__ >= 4
196 // set for compatibility only, so warn users not us
197 #pragma GCC diagnostic push
198 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
199#endif
200 if (checksumField == "Files")
201 F.MD5Hash = hash;
202#if __GNUC__ >= 4
203 #pragma GCC diagnostic pop
204#endif
205
206 // Try to guess what sort of file it is we are getting.
207 string::size_type Pos = F.Path.length()-1;
208 while (1)
209 {
210 string::size_type Tmp = F.Path.rfind('.',Pos);
211 if (Tmp == string::npos)
212 break;
213 if (F.Type == "tar") {
214 // source v3 has extension 'debian.tar.*' instead of 'diff.*'
215 if (string(F.Path, Tmp+1, Pos-Tmp) == "debian")
216 F.Type = "diff";
217 break;
218 }
219 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
220
221 if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() ||
222 F.Type == "tar")
223 {
224 Pos = Tmp-1;
225 continue;
226 }
227
228 break;
229 }
230 List.push_back(F);
cb6a2b3e 231 }
36f610f1 232 }
1262d358
DK
233
234 return true;
36f610f1
AL
235}
236 /*}}}*/
7a9f09bd
MV
237// SrcRecordParser::~SrcRecordParser - Destructor /*{{{*/
238// ---------------------------------------------------------------------
239/* */
240debSrcRecordParser::~debSrcRecordParser()
241{
7f48c4df
MV
242 // was allocated via strndup()
243 free(Buffer);
7a9f09bd
MV
244}
245 /*}}}*/
feab34c5
MV
246
247
a49e7948
MV
248debDscRecordParser::debDscRecordParser(std::string const &DscFile, pkgIndexFile const *Index)
249 : debSrcRecordParser(DscFile, Index)
feab34c5
MV
250{
251 // support clear signed files
252 if (OpenMaybeClearSignedFile(DscFile, Fd) == false)
253 {
254 _error->Error("Failed to open %s", DscFile.c_str());
255 return;
256 }
257
258 // re-init to ensure the updated Fd is used
259 Tags.Init(&Fd);
260 // read the first (and only) record
261 Step();
262
263}