Bug fixes
[ntk/apt.git] / apt-pkg / sourcelist.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
421c8d10 3// $Id: sourcelist.cc,v 1.16 1999/09/30 06:30:34 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
AL
20
21#include <fstream.h>
22#include <stdio.h>
23#include <unistd.h>
24#include <sys/stat.h>
25 /*}}}*/
26
27// SourceList::pkgSourceList - Constructors /*{{{*/
28// ---------------------------------------------------------------------
29/* */
30pkgSourceList::pkgSourceList()
31{
32}
33
34pkgSourceList::pkgSourceList(string File)
35{
36 Read(File);
37}
38 /*}}}*/
39// SourceList::ReadMainList - Read the main source list from etc /*{{{*/
40// ---------------------------------------------------------------------
41/* */
42bool pkgSourceList::ReadMainList()
43{
3b5421b4 44 return Read(_config->FindFile("Dir::Etc::sourcelist"));
6c139d6e
AL
45}
46 /*}}}*/
47// SourceList::Read - Parse the sourcelist file /*{{{*/
48// ---------------------------------------------------------------------
49/* */
50bool pkgSourceList::Read(string File)
51{
52 // Open the stream for reading
53 ifstream F(File.c_str(),ios::in | ios::nocreate);
54 if (!F != 0)
55 return _error->Errno("ifstream::ifstream","Opening %s",File.c_str());
56
57 List.erase(List.begin(),List.end());
58 char Buffer[300];
59
60 int CurLine = 0;
61 while (F.eof() == false)
62 {
63 F.getline(Buffer,sizeof(Buffer));
64 CurLine++;
65 _strtabexpand(Buffer,sizeof(Buffer));
66 _strstrip(Buffer);
67
68 // Comment or blank
69 if (Buffer[0] == '#' || Buffer[0] == 0)
70 continue;
71
72 // Grok it
73 string Type;
74 string URI;
75 Item Itm;
727f18af 76 const char *C = Buffer;
6c139d6e
AL
77 if (ParseQuoteWord(C,Type) == false)
78 return _error->Error("Malformed line %u in source list %s (type)",CurLine,File.c_str());
79 if (ParseQuoteWord(C,URI) == false)
80 return _error->Error("Malformed line %u in source list %s (URI)",CurLine,File.c_str());
81 if (ParseQuoteWord(C,Itm.Dist) == false)
82 return _error->Error("Malformed line %u in source list %s (dist)",CurLine,File.c_str());
83 if (Itm.SetType(Type) == false)
84 return _error->Error("Malformed line %u in source list %s (type parse)",CurLine,File.c_str());
85 if (Itm.SetURI(URI) == false)
86 return _error->Error("Malformed line %u in source list %s (URI parse)",CurLine,File.c_str());
87
88 // Check for an absolute dists specification.
89 if (Itm.Dist.empty() == false && Itm.Dist[Itm.Dist.size() - 1] == '/')
90 {
91 if (ParseQuoteWord(C,Itm.Section) == true)
92 return _error->Error("Malformed line %u in source list %s (Absolute dist)",CurLine,File.c_str());
9c14e3d6 93 Itm.Dist = SubstVar(Itm.Dist,"$(ARCH)",_config->Find("APT::Architecture"));
6c139d6e
AL
94 List.push_back(Itm);
95 continue;
96 }
97
98 // Grab the rest of the dists
99 if (ParseQuoteWord(C,Itm.Section) == false)
100 return _error->Error("Malformed line %u in source list %s (dist parse)",CurLine,File.c_str());
101
102 do
103 {
104 List.push_back(Itm);
105 }
106 while (ParseQuoteWord(C,Itm.Section) == true);
107 }
108 return true;
109}
110 /*}}}*/
6c139d6e
AL
111// SourceList::Item << - Writes the item to a stream /*{{{*/
112// ---------------------------------------------------------------------
113/* This is not suitable for rebuilding the sourcelist file but it good for
114 debugging. */
115ostream &operator <<(ostream &O,pkgSourceList::Item &Itm)
116{
93641593 117 O << (int)Itm.Type << ' ' << Itm.URI << ' ' << Itm.Dist << ' ' << Itm.Section;
6c139d6e
AL
118 return O;
119}
120 /*}}}*/
121// SourceList::Item::SetType - Sets the distribution type /*{{{*/
122// ---------------------------------------------------------------------
123/* */
124bool pkgSourceList::Item::SetType(string S)
125{
126 if (S == "deb")
127 {
128 Type = Deb;
129 return true;
130 }
131
be8922fd
AL
132 if (S == "deb-src")
133 {
134 Type = DebSrc;
135 return true;
136 }
137
f956efb4 138 return false;
6c139d6e
AL
139}
140 /*}}}*/
141// SourceList::Item::SetURI - Set the URI /*{{{*/
142// ---------------------------------------------------------------------
143/* For simplicity we strip the scheme off the uri */
144bool pkgSourceList::Item::SetURI(string S)
145{
146 if (S.empty() == true)
147 return false;
148
149 if (S.find(':') == string::npos)
150 return false;
151
9c14e3d6 152 S = SubstVar(S,"$(ARCH)",_config->Find("APT::Architecture"));
6c139d6e
AL
153
154 // Make sure that the URN is / postfixed
155 URI = S;
156 if (URI[URI.size() - 1] != '/')
157 URI += '/';
158
159 return true;
160}
161 /*}}}*/
162// SourceList::Item::PackagesURI - Returns a URI to the packages file /*{{{*/
163// ---------------------------------------------------------------------
164/* */
165string pkgSourceList::Item::PackagesURI() const
166{
167 string Res;
168 switch (Type)
169 {
170 case Deb:
171 if (Dist[Dist.size() - 1] == '/')
d6101223
AL
172 {
173 if (Dist != "/")
174 Res = URI + Dist;
421c8d10
AL
175 else
176 Res = URI;
d6101223 177 }
6c139d6e 178 else
9c14e3d6
AL
179 Res = URI + "dists/" + Dist + '/' + Section +
180 "/binary-" + _config->Find("APT::Architecture") + '/';
6c139d6e
AL
181
182 Res += "Packages";
183 break;
be8922fd
AL
184
185 case DebSrc:
186 if (Dist[Dist.size() - 1] == '/')
187 Res = URI + Dist;
188 else
189 Res = URI + "dists/" + Dist + '/' + Section +
190 "/source/";
191
192 Res += "Sources";
193 break;
6c139d6e
AL
194 };
195 return Res;
196}
197 /*}}}*/
198// SourceList::Item::PackagesInfo - Shorter version of the URI /*{{{*/
199// ---------------------------------------------------------------------
200/* This is a shorter version that is designed to be < 60 chars or so */
201string pkgSourceList::Item::PackagesInfo() const
202{
203 string Res;
204 switch (Type)
205 {
206 case Deb:
207 Res += SiteOnly(URI) + ' ';
208 if (Dist[Dist.size() - 1] == '/')
d6101223
AL
209 {
210 if (Dist != "/")
211 Res += Dist;
212 }
6c139d6e
AL
213 else
214 Res += Dist + '/' + Section;
215
216 Res += " Packages";
217 break;
be8922fd
AL
218
219 case DebSrc:
220 Res += SiteOnly(URI) + ' ';
221 if (Dist[Dist.size() - 1] == '/')
222 Res += Dist;
223 else
224 Res += Dist + '/' + Section;
225
226 Res += " Sources";
227 break;
6c139d6e
AL
228 };
229 return Res;
230}
231 /*}}}*/
0118833a
AL
232// SourceList::Item::ReleaseURI - Returns a URI to the release file /*{{{*/
233// ---------------------------------------------------------------------
234/* */
235string pkgSourceList::Item::ReleaseURI() const
236{
237 string Res;
238 switch (Type)
239 {
240 case Deb:
241 if (Dist[Dist.size() - 1] == '/')
d6101223
AL
242 {
243 if (Dist != "/")
244 Res = URI + Dist;
421c8d10
AL
245 else
246 Res = URI;
d6101223 247 }
0118833a
AL
248 else
249 Res = URI + "dists/" + Dist + '/' + Section +
250 "/binary-" + _config->Find("APT::Architecture") + '/';
251
252 Res += "Release";
253 break;
be8922fd
AL
254
255 case DebSrc:
256 if (Dist[Dist.size() - 1] == '/')
257 Res = URI + Dist;
258 else
259 Res = URI + "dists/" + Dist + '/' + Section +
260 "/source/";
261
262 Res += "Release";
263 break;
0118833a
AL
264 };
265 return Res;
266}
267 /*}}}*/
268// SourceList::Item::ReleaseInfo - Shorter version of the URI /*{{{*/
269// ---------------------------------------------------------------------
270/* This is a shorter version that is designed to be < 60 chars or so */
271string pkgSourceList::Item::ReleaseInfo() const
272{
273 string Res;
274 switch (Type)
275 {
276 case Deb:
be8922fd 277 case DebSrc:
0118833a
AL
278 Res += SiteOnly(URI) + ' ';
279 if (Dist[Dist.size() - 1] == '/')
d6101223
AL
280 {
281 if (Dist != "/")
282 Res += Dist;
283 }
0118833a
AL
284 else
285 Res += Dist + '/' + Section;
286
287 Res += " Release";
288 break;
289 };
290 return Res;
291}
292 /*}}}*/
6c139d6e
AL
293// SourceList::Item::ArchiveInfo - Shorter version of the archive spec /*{{{*/
294// ---------------------------------------------------------------------
295/* This is a shorter version that is designed to be < 60 chars or so */
296string pkgSourceList::Item::ArchiveInfo(pkgCache::VerIterator Ver) const
297{
298 string Res;
299 switch (Type)
300 {
be8922fd 301 case DebSrc:
6c139d6e
AL
302 case Deb:
303 Res += SiteOnly(URI) + ' ';
304 if (Dist[Dist.size() - 1] == '/')
d6101223
AL
305 {
306 if (Dist != "/")
307 Res += Dist;
308 }
6c139d6e
AL
309 else
310 Res += Dist + '/' + Section;
311
312 Res += " ";
313 Res += Ver.ParentPkg().Name();
3d615484
AL
314 Res += " ";
315 Res += Ver.VerStr();
316
6c139d6e
AL
317 break;
318 };
319 return Res;
320}
321 /*}}}*/
322// SourceList::Item::ArchiveURI - Returns a URI to the given archive /*{{{*/
323// ---------------------------------------------------------------------
324/* */
325string pkgSourceList::Item::ArchiveURI(string File) const
326{
327 string Res;
328 switch (Type)
329 {
330 case Deb:
be8922fd 331 case DebSrc:
6c139d6e
AL
332 Res = URI + File;
333 break;
334 };
335 return Res;
336}
337 /*}}}*/
36375005
AL
338// SourceList::Item::SourceInfo - Returns an info line for a source /*{{{*/
339// ---------------------------------------------------------------------
340/* */
341string pkgSourceList::Item::SourceInfo(string Pkg,string Ver,string Comp) const
342{
343 string Res;
344 switch (Type)
345 {
346 case DebSrc:
347 case Deb:
348 Res += SiteOnly(URI) + ' ';
349 if (Dist[Dist.size() - 1] == '/')
d6101223
AL
350 {
351 if (Dist != "/")
352 Res += Dist;
353 }
36375005
AL
354 else
355 Res += Dist + '/' + Section;
356
357 Res += " ";
358 Res += Pkg;
359 Res += " ";
360 Res += Ver;
361 if (Comp.empty() == false)
362 Res += " (" + Comp + ")";
363 break;
364 };
365 return Res;
366}
367 /*}}}*/
6c139d6e
AL
368// SourceList::Item::SiteOnly - Strip off the path part of a URI /*{{{*/
369// ---------------------------------------------------------------------
370/* */
371string pkgSourceList::Item::SiteOnly(string URI) const
372{
373 unsigned int Pos = URI.find(':');
374 if (Pos == string::npos || Pos + 3 > URI.length())
375 return URI;
376 if (URI[Pos + 1] != '/' || URI[Pos + 2] != '/')
377 return URI;
378
379 Pos = URI.find('/',Pos + 3);
380 if (Pos == string::npos)
381 return URI;
382 return string(URI,0,Pos);
383}
384 /*}}}*/