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