]> git.saurik.com Git - apt.git/blob - apt-pkg/deb/debsrcrecords.cc
apt-pkg/deb/debindexfile.cc: do not hardcode dpkg
[apt.git] / apt-pkg / deb / debsrcrecords.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: debsrcrecords.cc,v 1.6 2004/03/17 05:58:54 mdz Exp $
4 /* ######################################################################
5
6 Debian Source Package Records - Parser implementation for Debian style
7 source indexes
8
9 ##################################################################### */
10 /*}}}*/
11 // Include Files /*{{{*/
12 #include <config.h>
13
14 #include <apt-pkg/deblistparser.h>
15 #include <apt-pkg/debsrcrecords.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/strutl.h>
18 #include <apt-pkg/aptconfiguration.h>
19 #include <apt-pkg/srcrecords.h>
20 #include <apt-pkg/tagfile.h>
21 #include <apt-pkg/hashes.h>
22 #include <apt-pkg/gpgv.h>
23
24 #include <ctype.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <algorithm>
28 #include <string>
29 #include <vector>
30 /*}}}*/
31
32 using std::max;
33 using std::string;
34
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
40 reused by the next Binaries function call. This function is commonly
41 used during scanning to find the right package */
42 const char **debSrcRecordParser::Binaries()
43 {
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);
54
55 char* bin = Buffer;
56 do {
57 char* binStartNext = strchrnul(bin, ',');
58 char* binEnd = binStartNext - 1;
59 for (; isspace(*binEnd) != 0; --binEnd)
60 binEnd = '\0';
61 StaticBinList.push_back(bin);
62 if (*binStartNext != ',')
63 break;
64 *binStartNext = '\0';
65 for (bin = binStartNext + 1; isspace(*bin) != 0; ++bin);
66 } while (*bin != '\0');
67 StaticBinList.push_back(NULL);
68
69 return &StaticBinList[0];
70 }
71 /*}}}*/
72 // SrcRecordParser::BuildDepends - Return the Build-Depends information /*{{{*/
73 // ---------------------------------------------------------------------
74 /* This member parses the build-depends information and returns a list of
75 package/version records representing the build dependency. The returned
76 array need not be freed and will be reused by the next call to this
77 function */
78 bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDepRec> &BuildDeps,
79 bool const &ArchOnly, bool const &StripMultiArch)
80 {
81 unsigned int I;
82 const char *Start, *Stop;
83 BuildDepRec rec;
84 const char *fields[] = {"Build-Depends",
85 "Build-Depends-Indep",
86 "Build-Conflicts",
87 "Build-Conflicts-Indep"};
88
89 BuildDeps.clear();
90
91 for (I = 0; I < 4; I++)
92 {
93 if (ArchOnly && (I == 1 || I == 3))
94 continue;
95
96 if (Sect.Find(fields[I], Start, Stop) == false)
97 continue;
98
99 while (1)
100 {
101 Start = debListParser::ParseDepends(Start, Stop,
102 rec.Package,rec.Version,rec.Op,true,StripMultiArch,true);
103
104 if (Start == 0)
105 return _error->Error("Problem parsing dependency: %s", fields[I]);
106 rec.Type = I;
107
108 if (rec.Package != "")
109 BuildDeps.push_back(rec);
110
111 if (Start == Stop)
112 break;
113 }
114 }
115
116 return true;
117 }
118 /*}}}*/
119 // SrcRecordParser::Files - Return a list of files for this source /*{{{*/
120 // ---------------------------------------------------------------------
121 /* This parses the list of files and returns it, each file is required to have
122 a complete source package */
123 bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
124 {
125 List.erase(List.begin(),List.end());
126
127 // map from the Hashsum field to the hashsum function,
128 // unfortunately this is not a 1:1 mapping from
129 // Hashes::SupporedHashes as e.g. Files is a historic name for the md5
130 const std::pair<const char*, const char*> SourceHashFields[] = {
131 std::make_pair( "Checksums-Sha512", "SHA512"),
132 std::make_pair( "Checksums-Sha256", "SHA256"),
133 std::make_pair( "Checksums-Sha1", "SHA1"),
134 std::make_pair( "Files", "MD5Sum"), // historic Name
135 };
136
137 for (unsigned int i=0;
138 i < sizeof(SourceHashFields)/sizeof(SourceHashFields[0]);
139 i++)
140 {
141 string Files = Sect.FindS(SourceHashFields[i].first);
142 if (Files.empty() == true)
143 continue;
144
145 // Stash the / terminated directory prefix
146 string Base = Sect.FindS("Directory");
147 if (Base.empty() == false && Base[Base.length()-1] != '/')
148 Base += '/';
149
150 std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions();
151
152 // Iterate over the entire list grabbing each triplet
153 const char *C = Files.c_str();
154 while (*C != 0)
155 {
156 pkgSrcRecords::File F;
157 string Size;
158
159 // Parse each of the elements
160 std::string RawHash;
161 if (ParseQuoteWord(C, RawHash) == false ||
162 ParseQuoteWord(C, Size) == false ||
163 ParseQuoteWord(C, F.Path) == false)
164 return _error->Error("Error parsing '%s' record",
165 SourceHashFields[i].first);
166 // assign full hash string
167 F.Hash = HashString(SourceHashFields[i].second, RawHash).toStr();
168 // API compat hack
169 if(strcmp(SourceHashFields[i].second, "MD5Sum") == 0)
170 F.MD5Hash = RawHash;
171
172 // Parse the size and append the directory
173 F.Size = atoi(Size.c_str());
174 F.Path = Base + F.Path;
175
176 // Try to guess what sort of file it is we are getting.
177 string::size_type Pos = F.Path.length()-1;
178 while (1)
179 {
180 string::size_type Tmp = F.Path.rfind('.',Pos);
181 if (Tmp == string::npos)
182 break;
183 if (F.Type == "tar") {
184 // source v3 has extension 'debian.tar.*' instead of 'diff.*'
185 if (string(F.Path, Tmp+1, Pos-Tmp) == "debian")
186 F.Type = "diff";
187 break;
188 }
189 F.Type = string(F.Path,Tmp+1,Pos-Tmp);
190
191 if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() ||
192 F.Type == "tar")
193 {
194 Pos = Tmp-1;
195 continue;
196 }
197
198 break;
199 }
200
201 List.push_back(F);
202 }
203 break;
204 }
205 return (List.size() > 0);
206 }
207 /*}}}*/
208 // SrcRecordParser::~SrcRecordParser - Destructor /*{{{*/
209 // ---------------------------------------------------------------------
210 /* */
211 debSrcRecordParser::~debSrcRecordParser()
212 {
213 delete[] Buffer;
214 }
215 /*}}}*/
216
217
218 debDscRecordParser::debDscRecordParser(std::string const &DscFile, pkgIndexFile const *Index)
219 : debSrcRecordParser(DscFile, Index)
220 {
221 // support clear signed files
222 if (OpenMaybeClearSignedFile(DscFile, Fd) == false)
223 {
224 _error->Error("Failed to open %s", DscFile.c_str());
225 return;
226 }
227
228 // re-init to ensure the updated Fd is used
229 Tags.Init(&Fd);
230 // read the first (and only) record
231 Step();
232
233 }