Fix last fix, make sure we read something before giving up
[ntk/apt.git] / apt-pkg / sourcelist.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
90f057fd 3// $Id: sourcelist.cc,v 1.22 2002/03/26 07:38:58 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 /*}}}*/
a7c835af
AL
131// SourceList::ReadVendors - Read list of known package vendors /*{{{*/
132// ---------------------------------------------------------------------
133/* This also scans a directory of vendor files similar to apt.conf.d
134 which can contain the usual suspects of distribution provided data.
135 The APT config mechanism allows the user to override these in their
136 configuration file. */
137bool pkgSourceList::ReadVendors()
138{
139 Configuration Cnf;
140
141 string CnfFile = _config->FindDir("Dir::Etc::vendorparts");
142 if (FileExists(CnfFile) == true)
143 if (ReadConfigDir(Cnf,CnfFile,true) == false)
144 return false;
145 CnfFile = _config->FindFile("Dir::Etc::vendorlist");
146 if (FileExists(CnfFile) == true)
147 if (ReadConfigFile(Cnf,CnfFile,true) == false)
148 return false;
149
150 // Process 'simple-key' type sections
151 const Configuration::Item *Top = Cnf.Tree("simple-key");
152 for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next)
153 {
154 Configuration Block(Top);
155 Vendor *Vendor;
156
157 Vendor = new pkgSourceList::Vendor;
158
159 Vendor->VendorID = Top->Tag;
160 Vendor->FingerPrint = Block.Find("Fingerprint");
161 Vendor->Description = Block.Find("Name");
162
163 if (Vendor->FingerPrint.empty() == true ||
164 Vendor->Description.empty() == true)
165 {
166 _error->Error(_("Vendor block %s is invalid"), Vendor->VendorID.c_str());
167 delete Vendor;
168 continue;
169 }
170
171 VendorList.push_back(Vendor);
172 }
173
5ef5c64e
AL
174 /* XXX Process 'group-key' type sections
175 This is currently faked out so that the vendors file format is
176 parsed but nothing is done with it except check for validity */
177 Top = Cnf.Tree("group-key");
178 for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next)
179 {
180 Configuration Block(Top);
181 Vendor *Vendor;
182
183 Vendor = new pkgSourceList::Vendor;
184
185 Vendor->VendorID = Top->Tag;
186 Vendor->Description = Block.Find("Name");
187
188 if (Vendor->Description.empty() == true)
189 {
190 _error->Error(_("Vendor block %s is invalid"),
191 Vendor->VendorID.c_str());
192 delete Vendor;
193 continue;
194 }
195
196 VendorList.push_back(Vendor);
197 }
198
a7c835af
AL
199 return !_error->PendingError();
200}
201 /*}}}*/
6c139d6e
AL
202// SourceList::ReadMainList - Read the main source list from etc /*{{{*/
203// ---------------------------------------------------------------------
204/* */
205bool pkgSourceList::ReadMainList()
206{
a7c835af 207 return ReadVendors() && Read(_config->FindFile("Dir::Etc::sourcelist"));
6c139d6e
AL
208}
209 /*}}}*/
210// SourceList::Read - Parse the sourcelist file /*{{{*/
211// ---------------------------------------------------------------------
212/* */
213bool pkgSourceList::Read(string File)
214{
215 // Open the stream for reading
4d6f8bdf 216 ifstream F(File.c_str(),ios::in /*| ios::nocreate*/);
6c139d6e 217 if (!F != 0)
b2e465d6 218 return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());
6c139d6e 219
a7c835af 220 SrcList.erase(SrcList.begin(),SrcList.end());
6c139d6e
AL
221 char Buffer[300];
222
223 int CurLine = 0;
224 while (F.eof() == false)
225 {
226 F.getline(Buffer,sizeof(Buffer));
227 CurLine++;
228 _strtabexpand(Buffer,sizeof(Buffer));
b2e465d6
AL
229
230
231 char *I;
232 for (I = Buffer; *I != 0 && *I != '#'; I++);
233 *I = 0;
234
235 const char *C = _strstrip(Buffer);
6c139d6e
AL
236
237 // Comment or blank
b2e465d6 238 if (C[0] == '#' || C[0] == 0)
6c139d6e 239 continue;
b2e465d6 240
6c139d6e 241 // Grok it
b2e465d6
AL
242 string LineType;
243 if (ParseQuoteWord(C,LineType) == false)
244 return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str());
6c139d6e 245
b2e465d6
AL
246 Type *Parse = Type::GetType(LineType.c_str());
247 if (Parse == 0)
248 return _error->Error(_("Type '%s' is not known in on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
6c139d6e 249
a7c835af
AL
250 // Authenticated repository
251 Vendor const *Vndr = 0;
252 if (C[0] == '[')
253 {
254 string VendorID;
255
256 if (ParseQuoteWord(C,VendorID) == false)
257 return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
258
259 if (VendorID.length() < 2 || VendorID.end()[-1] != ']')
260 return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
261 VendorID = string(VendorID,1,VendorID.size()-2);
262
263 for (vector<Vendor const *>::const_iterator iter = VendorList.begin();
264 iter != VendorList.end(); iter++)
265 {
266 if ((*iter)->VendorID == VendorID)
267 {
268 Vndr = *iter;
269 break;
270 }
271 }
272
273 if (Vndr == 0)
274 return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"),
275 VendorID.c_str(),CurLine,File.c_str());
276 }
277
278 if (Parse->ParseLine(SrcList,Vndr,C,CurLine,File) == false)
b2e465d6 279 return false;
6c139d6e
AL
280 }
281 return true;
282}
283 /*}}}*/
b2e465d6 284// SourceList::FindIndex - Get the index associated with a file /*{{{*/
6c139d6e
AL
285// ---------------------------------------------------------------------
286/* */
b2e465d6
AL
287bool pkgSourceList::FindIndex(pkgCache::PkgFileIterator File,
288 pkgIndexFile *&Found) const
6c139d6e 289{
a7c835af 290 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
6c139d6e 291 {
b2e465d6
AL
292 if ((*I)->FindInCache(*File.Cache()) == File)
293 {
294 Found = *I;
295 return true;
296 }
be8922fd 297 }
6c139d6e 298
b2e465d6 299 return false;
36375005
AL
300}
301 /*}}}*/
b2e465d6 302// SourceList::GetIndexes - Load the index files into the downloader /*{{{*/
6c139d6e
AL
303// ---------------------------------------------------------------------
304/* */
b2e465d6 305bool pkgSourceList::GetIndexes(pkgAcquire *Owner) const
6c139d6e 306{
a7c835af 307 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
b2e465d6
AL
308 if ((*I)->GetIndexes(Owner) == false)
309 return false;
310 return true;
6c139d6e
AL
311}
312 /*}}}*/