]> git.saurik.com Git - apt.git/blame - apt-pkg/sourcelist.cc
Change supposidly 'unclear' numerology.
[apt.git] / apt-pkg / sourcelist.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
1c193e02 3// $Id: sourcelist.cc,v 1.23 2002/07/01 21:41:11 jgg Exp $
6c139d6e
AL
4/* ######################################################################
5
6 List of Sources
7
8 ##################################################################### */
9 /*}}}*/
10// Include Files /*{{{*/
11#ifdef __GNUG__
094a497d 12#pragma implementation "apt-pkg/sourcelist.h"
6c139d6e
AL
13#endif
14
094a497d
AL
15#include <apt-pkg/sourcelist.h>
16#include <apt-pkg/error.h>
17#include <apt-pkg/fileutl.h>
18#include <apt-pkg/configuration.h>
cdcc6d34 19#include <apt-pkg/strutl.h>
6c139d6e 20
b2e465d6
AL
21#include <apti18n.h>
22
90f057fd 23#include <fstream>
b2e465d6
AL
24 /*}}}*/
25
4d6f8bdf
AL
26using namespace std;
27
28// Global list of Items supported
b2e465d6
AL
29static pkgSourceList::Type *ItmList[10];
30pkgSourceList::Type **pkgSourceList::Type::GlobalList = ItmList;
31unsigned long pkgSourceList::Type::GlobalListLen = 0;
32
33// Type::Type - Constructor /*{{{*/
34// ---------------------------------------------------------------------
35/* Link this to the global list of items*/
36pkgSourceList::Type::Type()
37{
38 ItmList[GlobalListLen] = this;
39 GlobalListLen++;
40}
41 /*}}}*/
42// Type::GetType - Get a specific meta for a given type /*{{{*/
43// ---------------------------------------------------------------------
44/* */
45pkgSourceList::Type *pkgSourceList::Type::GetType(const char *Type)
46{
47 for (unsigned I = 0; I != GlobalListLen; I++)
48 if (strcmp(GlobalList[I]->Name,Type) == 0)
49 return GlobalList[I];
50 return 0;
51}
52 /*}}}*/
53// Type::FixupURI - Normalize the URI and check it.. /*{{{*/
54// ---------------------------------------------------------------------
55/* */
56bool pkgSourceList::Type::FixupURI(string &URI) const
57{
58 if (URI.empty() == true)
59 return false;
60
61 if (URI.find(':') == string::npos)
62 return false;
63
64 URI = SubstVar(URI,"$(ARCH)",_config->Find("APT::Architecture"));
65
a7c835af 66 // Make sure that the URI is / postfixed
b2e465d6
AL
67 if (URI[URI.size() - 1] != '/')
68 URI += '/';
69
70 return true;
71}
72 /*}}}*/
73// Type::ParseLine - Parse a single line /*{{{*/
74// ---------------------------------------------------------------------
75/* This is a generic one that is the 'usual' format for sources.list
76 Weird types may override this. */
77bool pkgSourceList::Type::ParseLine(vector<pkgIndexFile *> &List,
a7c835af 78 Vendor const *Vendor,
b2e465d6
AL
79 const char *Buffer,
80 unsigned long CurLine,
81 string File) const
82{
83 string URI;
84 string Dist;
85 string Section;
86
87 if (ParseQuoteWord(Buffer,URI) == false)
88 return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
89 if (ParseQuoteWord(Buffer,Dist) == false)
90 return _error->Error(_("Malformed line %lu in source list %s (dist)"),CurLine,File.c_str());
91
92 if (FixupURI(URI) == false)
93 return _error->Error(_("Malformed line %lu in source list %s (URI parse)"),CurLine,File.c_str());
94
95 // Check for an absolute dists specification.
96 if (Dist.empty() == false && Dist[Dist.size() - 1] == '/')
97 {
98 if (ParseQuoteWord(Buffer,Section) == true)
99 return _error->Error(_("Malformed line %lu in source list %s (Absolute dist)"),CurLine,File.c_str());
100 Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
a7c835af 101 return CreateItem(List,URI,Dist,Section,Vendor);
b2e465d6
AL
102 }
103
104 // Grab the rest of the dists
105 if (ParseQuoteWord(Buffer,Section) == false)
106 return _error->Error(_("Malformed line %lu in source list %s (dist parse)"),CurLine,File.c_str());
107
108 do
109 {
a7c835af 110 if (CreateItem(List,URI,Dist,Section,Vendor) == false)
b2e465d6
AL
111 return false;
112 }
113 while (ParseQuoteWord(Buffer,Section) == true);
114
115 return true;
116}
6c139d6e
AL
117 /*}}}*/
118
119// SourceList::pkgSourceList - Constructors /*{{{*/
120// ---------------------------------------------------------------------
121/* */
122pkgSourceList::pkgSourceList()
123{
124}
125
126pkgSourceList::pkgSourceList(string File)
127{
128 Read(File);
129}
130 /*}}}*/
1c193e02
AL
131// SourceList::~pkgSourceList - Destructor /*{{{*/
132// ---------------------------------------------------------------------
133/* */
134pkgSourceList::~pkgSourceList()
135{
136 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
137 delete *I;
138 for (vector<Vendor const *>::const_iterator I = VendorList.begin();
139 I != VendorList.end(); I++)
140 delete *I;
141}
142 /*}}}*/
a7c835af
AL
143// SourceList::ReadVendors - Read list of known package vendors /*{{{*/
144// ---------------------------------------------------------------------
145/* This also scans a directory of vendor files similar to apt.conf.d
146 which can contain the usual suspects of distribution provided data.
147 The APT config mechanism allows the user to override these in their
148 configuration file. */
149bool pkgSourceList::ReadVendors()
150{
151 Configuration Cnf;
152
153 string CnfFile = _config->FindDir("Dir::Etc::vendorparts");
154 if (FileExists(CnfFile) == true)
155 if (ReadConfigDir(Cnf,CnfFile,true) == false)
156 return false;
157 CnfFile = _config->FindFile("Dir::Etc::vendorlist");
158 if (FileExists(CnfFile) == true)
159 if (ReadConfigFile(Cnf,CnfFile,true) == false)
160 return false;
161
1c193e02
AL
162 for (vector<Vendor const *>::const_iterator I = VendorList.begin();
163 I != VendorList.end(); I++)
164 delete *I;
165 VendorList.erase(VendorList.begin(),VendorList.end());
166
a7c835af
AL
167 // Process 'simple-key' type sections
168 const Configuration::Item *Top = Cnf.Tree("simple-key");
169 for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next)
170 {
171 Configuration Block(Top);
172 Vendor *Vendor;
173
174 Vendor = new pkgSourceList::Vendor;
175
176 Vendor->VendorID = Top->Tag;
177 Vendor->FingerPrint = Block.Find("Fingerprint");
178 Vendor->Description = Block.Find("Name");
179
180 if (Vendor->FingerPrint.empty() == true ||
181 Vendor->Description.empty() == true)
182 {
183 _error->Error(_("Vendor block %s is invalid"), Vendor->VendorID.c_str());
184 delete Vendor;
185 continue;
186 }
187
188 VendorList.push_back(Vendor);
189 }
190
5ef5c64e
AL
191 /* XXX Process 'group-key' type sections
192 This is currently faked out so that the vendors file format is
193 parsed but nothing is done with it except check for validity */
194 Top = Cnf.Tree("group-key");
195 for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next)
196 {
197 Configuration Block(Top);
198 Vendor *Vendor;
199
200 Vendor = new pkgSourceList::Vendor;
201
202 Vendor->VendorID = Top->Tag;
203 Vendor->Description = Block.Find("Name");
204
205 if (Vendor->Description.empty() == true)
206 {
207 _error->Error(_("Vendor block %s is invalid"),
208 Vendor->VendorID.c_str());
209 delete Vendor;
210 continue;
211 }
212
213 VendorList.push_back(Vendor);
214 }
215
a7c835af
AL
216 return !_error->PendingError();
217}
218 /*}}}*/
6c139d6e
AL
219// SourceList::ReadMainList - Read the main source list from etc /*{{{*/
220// ---------------------------------------------------------------------
221/* */
222bool pkgSourceList::ReadMainList()
223{
a7c835af 224 return ReadVendors() && Read(_config->FindFile("Dir::Etc::sourcelist"));
6c139d6e
AL
225}
226 /*}}}*/
227// SourceList::Read - Parse the sourcelist file /*{{{*/
228// ---------------------------------------------------------------------
229/* */
230bool pkgSourceList::Read(string File)
231{
232 // Open the stream for reading
4d6f8bdf 233 ifstream F(File.c_str(),ios::in /*| ios::nocreate*/);
6c139d6e 234 if (!F != 0)
b2e465d6 235 return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());
6c139d6e 236
1c193e02
AL
237 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
238 delete *I;
a7c835af 239 SrcList.erase(SrcList.begin(),SrcList.end());
6c139d6e
AL
240 char Buffer[300];
241
242 int CurLine = 0;
243 while (F.eof() == false)
244 {
245 F.getline(Buffer,sizeof(Buffer));
246 CurLine++;
247 _strtabexpand(Buffer,sizeof(Buffer));
b2e465d6
AL
248
249
250 char *I;
251 for (I = Buffer; *I != 0 && *I != '#'; I++);
252 *I = 0;
253
254 const char *C = _strstrip(Buffer);
6c139d6e
AL
255
256 // Comment or blank
b2e465d6 257 if (C[0] == '#' || C[0] == 0)
6c139d6e 258 continue;
b2e465d6 259
6c139d6e 260 // Grok it
b2e465d6
AL
261 string LineType;
262 if (ParseQuoteWord(C,LineType) == false)
263 return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str());
6c139d6e 264
b2e465d6
AL
265 Type *Parse = Type::GetType(LineType.c_str());
266 if (Parse == 0)
267 return _error->Error(_("Type '%s' is not known in on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
6c139d6e 268
a7c835af
AL
269 // Authenticated repository
270 Vendor const *Vndr = 0;
271 if (C[0] == '[')
272 {
273 string VendorID;
274
275 if (ParseQuoteWord(C,VendorID) == false)
276 return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
277
278 if (VendorID.length() < 2 || VendorID.end()[-1] != ']')
279 return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
280 VendorID = string(VendorID,1,VendorID.size()-2);
281
282 for (vector<Vendor const *>::const_iterator iter = VendorList.begin();
283 iter != VendorList.end(); iter++)
284 {
285 if ((*iter)->VendorID == VendorID)
286 {
287 Vndr = *iter;
288 break;
289 }
290 }
291
292 if (Vndr == 0)
293 return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"),
294 VendorID.c_str(),CurLine,File.c_str());
295 }
296
297 if (Parse->ParseLine(SrcList,Vndr,C,CurLine,File) == false)
b2e465d6 298 return false;
6c139d6e
AL
299 }
300 return true;
301}
302 /*}}}*/
b2e465d6 303// SourceList::FindIndex - Get the index associated with a file /*{{{*/
6c139d6e
AL
304// ---------------------------------------------------------------------
305/* */
b2e465d6
AL
306bool pkgSourceList::FindIndex(pkgCache::PkgFileIterator File,
307 pkgIndexFile *&Found) const
6c139d6e 308{
a7c835af 309 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
6c139d6e 310 {
b2e465d6
AL
311 if ((*I)->FindInCache(*File.Cache()) == File)
312 {
313 Found = *I;
314 return true;
315 }
be8922fd 316 }
6c139d6e 317
b2e465d6 318 return false;
36375005
AL
319}
320 /*}}}*/
b2e465d6 321// SourceList::GetIndexes - Load the index files into the downloader /*{{{*/
6c139d6e
AL
322// ---------------------------------------------------------------------
323/* */
b2e465d6 324bool pkgSourceList::GetIndexes(pkgAcquire *Owner) const
6c139d6e 325{
a7c835af 326 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
b2e465d6
AL
327 if ((*I)->GetIndexes(Owner) == false)
328 return false;
329 return true;
6c139d6e
AL
330}
331 /*}}}*/