Merge apt--authentication--0
[ntk/apt.git] / apt-pkg / sourcelist.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: sourcelist.cc,v 1.25 2004/06/07 23:08:00 mdz Exp $
4 /* ######################################################################
5
6 List of Sources
7
8 ##################################################################### */
9 /*}}}*/
10 // Include Files /*{{{*/
11 #ifdef __GNUG__
12 #pragma implementation "apt-pkg/sourcelist.h"
13 #endif
14
15 #include <apt-pkg/sourcelist.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/fileutl.h>
18 #include <apt-pkg/strutl.h>
19 #include <apt-pkg/configuration.h>
20
21 #include <apti18n.h>
22
23 #include <fstream>
24 /*}}}*/
25
26 using namespace std;
27
28 // Global list of Items supported
29 static pkgSourceList::Type *ItmList[10];
30 pkgSourceList::Type **pkgSourceList::Type::GlobalList = ItmList;
31 unsigned long pkgSourceList::Type::GlobalListLen = 0;
32
33 // Type::Type - Constructor /*{{{*/
34 // ---------------------------------------------------------------------
35 /* Link this to the global list of items*/
36 pkgSourceList::Type::Type()
37 {
38 ItmList[GlobalListLen] = this;
39 GlobalListLen++;
40 }
41 /*}}}*/
42 // Type::GetType - Get a specific meta for a given type /*{{{*/
43 // ---------------------------------------------------------------------
44 /* */
45 pkgSourceList::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 /* */
56 bool 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
66 // Make sure that the URI is / postfixed
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. */
77 bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
78 const char *Buffer,
79 unsigned long CurLine,
80 string File) const
81 {
82 string URI;
83 string Dist;
84 string Section;
85
86 if (ParseQuoteWord(Buffer,URI) == false)
87 return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
88 if (ParseQuoteWord(Buffer,Dist) == false)
89 return _error->Error(_("Malformed line %lu in source list %s (dist)"),CurLine,File.c_str());
90
91 if (FixupURI(URI) == false)
92 return _error->Error(_("Malformed line %lu in source list %s (URI parse)"),CurLine,File.c_str());
93
94 // Check for an absolute dists specification.
95 if (Dist.empty() == false && Dist[Dist.size() - 1] == '/')
96 {
97 if (ParseQuoteWord(Buffer,Section) == true)
98 return _error->Error(_("Malformed line %lu in source list %s (Absolute dist)"),CurLine,File.c_str());
99 Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
100 return CreateItem(List,URI,Dist,Section);
101 }
102
103 // Grab the rest of the dists
104 if (ParseQuoteWord(Buffer,Section) == false)
105 return _error->Error(_("Malformed line %lu in source list %s (dist parse)"),CurLine,File.c_str());
106
107 do
108 {
109 if (CreateItem(List,URI,Dist,Section) == false)
110 return false;
111 }
112 while (ParseQuoteWord(Buffer,Section) == true);
113
114 return true;
115 }
116 /*}}}*/
117
118 // SourceList::pkgSourceList - Constructors /*{{{*/
119 // ---------------------------------------------------------------------
120 /* */
121 pkgSourceList::pkgSourceList()
122 {
123 }
124
125 pkgSourceList::pkgSourceList(string File)
126 {
127 Read(File);
128 }
129 /*}}}*/
130 // SourceList::~pkgSourceList - Destructor /*{{{*/
131 // ---------------------------------------------------------------------
132 /* */
133 pkgSourceList::~pkgSourceList()
134 {
135 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
136 delete *I;
137 }
138 /*}}}*/
139 /*}}}*/
140 // SourceList::ReadMainList - Read the main source list from etc /*{{{*/
141 // ---------------------------------------------------------------------
142 /* */
143 bool pkgSourceList::ReadMainList()
144 {
145 return Read(_config->FindFile("Dir::Etc::sourcelist"));
146 }
147 /*}}}*/
148 // SourceList::Read - Parse the sourcelist file /*{{{*/
149 // ---------------------------------------------------------------------
150 /* */
151 bool pkgSourceList::Read(string File)
152 {
153 // Open the stream for reading
154 ifstream F(File.c_str(),ios::in /*| ios::nocreate*/);
155 if (!F != 0)
156 return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());
157
158 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
159 delete *I;
160 SrcList.erase(SrcList.begin(),SrcList.end());
161 char Buffer[300];
162
163 int CurLine = 0;
164 while (F.eof() == false)
165 {
166 F.getline(Buffer,sizeof(Buffer));
167 CurLine++;
168 _strtabexpand(Buffer,sizeof(Buffer));
169 if (F.fail() && !F.eof())
170 return _error->Error(_("Line %u too long in source list %s."),
171 CurLine,File.c_str());
172
173
174 char *I;
175 for (I = Buffer; *I != 0 && *I != '#'; I++);
176 *I = 0;
177
178 const char *C = _strstrip(Buffer);
179
180 // Comment or blank
181 if (C[0] == '#' || C[0] == 0)
182 continue;
183
184 // Grok it
185 string LineType;
186 if (ParseQuoteWord(C,LineType) == false)
187 return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str());
188
189 Type *Parse = Type::GetType(LineType.c_str());
190 if (Parse == 0)
191 return _error->Error(_("Type '%s' is not known on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
192
193 // Vendor name specified
194 if (C[0] == '[')
195 {
196 string VendorID;
197
198 if (ParseQuoteWord(C,VendorID) == false)
199 return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
200
201 if (VendorID.length() < 2 || VendorID.end()[-1] != ']')
202 return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
203 VendorID = string(VendorID,1,VendorID.size()-2);
204
205 // for (vector<const Vendor *>::const_iterator iter = VendorList.begin();
206 // iter != VendorList.end(); iter++)
207 // {
208 // if ((*iter)->GetVendorID() == VendorID)
209 // {
210 // if (_config->FindB("Debug::sourceList", false))
211 // std::cerr << "Comparing VendorID \"" << VendorID << "\" with \"" << (*iter)->GetVendorID() << '"' << std::endl;
212 // Verifier = *iter;
213 // break;
214 // }
215 // }
216
217 // if (Verifier == 0)
218 // return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"),
219 // VendorID.c_str(),CurLine,File.c_str());
220 }
221
222 if (Parse->ParseLine(SrcList,C,CurLine,File) == false)
223 return false;
224 }
225 return true;
226 }
227 /*}}}*/
228 // SourceList::FindIndex - Get the index associated with a file /*{{{*/
229 // ---------------------------------------------------------------------
230 /* */
231 bool pkgSourceList::FindIndex(pkgCache::PkgFileIterator File,
232 pkgIndexFile *&Found) const
233 {
234 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
235 {
236 vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles();
237 for (vector<pkgIndexFile *>::const_iterator J = Indexes->begin();
238 J != Indexes->end(); J++)
239 {
240 if ((*J)->FindInCache(*File.Cache()) == File)
241 {
242 Found = (*J);
243 return true;
244 }
245 }
246 }
247
248 return false;
249 }
250 /*}}}*/
251 // SourceList::GetIndexes - Load the index files into the downloader /*{{{*/
252 // ---------------------------------------------------------------------
253 /* */
254 bool pkgSourceList::GetIndexes(pkgAcquire *Owner, bool GetAll) const
255 {
256 for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
257 if ((*I)->GetIndexes(Owner,GetAll) == false)
258 return false;
259 return true;
260 }
261 /*}}}*/