]> git.saurik.com Git - apt.git/blame - apt-pkg/sourcelist.cc
* New no_NO.po file from Tollef Fog Heen <tfheen@debian...
[apt.git] / apt-pkg / sourcelist.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
ba1045b4 3// $Id: sourcelist.cc,v 1.24 2002/07/08 04:18:07 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));
ba1045b4
AL
248 if (F.fail() && !F.eof())
249 return _error->Error(_("Line %u too long in source list %s."),
250 CurLine,File.c_str());
251
b2e465d6
AL
252
253 char *I;
254 for (I = Buffer; *I != 0 && *I != '#'; I++);
255 *I = 0;
256
257 const char *C = _strstrip(Buffer);
6c139d6e
AL
258
259 // Comment or blank
b2e465d6 260 if (C[0] == '#' || C[0] == 0)
6c139d6e 261 continue;
b2e465d6 262
6c139d6e 263 // Grok it
b2e465d6
AL
264 string LineType;
265 if (ParseQuoteWord(C,LineType) == false)
266 return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str());
6c139d6e 267
b2e465d6
AL
268 Type *Parse = Type::GetType(LineType.c_str());
269 if (Parse == 0)
270 return _error->Error(_("Type '%s' is not known in on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
6c139d6e 271
a7c835af
AL
272 // Authenticated repository
273 Vendor const *Vndr = 0;
274 if (C[0] == '[')
275 {
276 string VendorID;
277
278 if (ParseQuoteWord(C,VendorID) == false)
279 return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
280
281 if (VendorID.length() < 2 || VendorID.end()[-1] != ']')
282 return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
283 VendorID = string(VendorID,1,VendorID.size()-2);
284
285 for (vector<Vendor const *>::const_iterator iter = VendorList.begin();
286 iter != VendorList.end(); iter++)
287 {
288 if ((*iter)->VendorID == VendorID)
289 {
290 Vndr = *iter;
291 break;
292 }
293 }
294
295 if (Vndr == 0)
296 return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"),
297 VendorID.c_str(),CurLine,File.c_str());
298 }
299
300 if (Parse->ParseLine(SrcList,Vndr,C,CurLine,File) == false)
b2e465d6 301 return false;
6c139d6e
AL
302 }
303 return true;
304}
305 /*}}}*/
b2e465d6 306// SourceList::FindIndex - Get the index associated with a file /*{{{*/
6c139d6e
AL
307// ---------------------------------------------------------------------
308/* */
b2e465d6
AL
309bool pkgSourceList::FindIndex(pkgCache::PkgFileIterator File,
310 pkgIndexFile *&Found) const
6c139d6e 311{
a7c835af 312 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
6c139d6e 313 {
b2e465d6
AL
314 if ((*I)->FindInCache(*File.Cache()) == File)
315 {
316 Found = *I;
317 return true;
318 }
be8922fd 319 }
6c139d6e 320
b2e465d6 321 return false;
36375005
AL
322}
323 /*}}}*/
b2e465d6 324// SourceList::GetIndexes - Load the index files into the downloader /*{{{*/
6c139d6e
AL
325// ---------------------------------------------------------------------
326/* */
b2e465d6 327bool pkgSourceList::GetIndexes(pkgAcquire *Owner) const
6c139d6e 328{
a7c835af 329 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
b2e465d6
AL
330 if ((*I)->GetIndexes(Owner) == false)
331 return false;
332 return true;
6c139d6e
AL
333}
334 /*}}}*/