First draft of make system and name change to apt-pkg
[ntk/apt.git] / apt-pkg / sourcelist.cc
CommitLineData
6c139d6e
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
094a497d 3// $Id: sourcelist.cc,v 1.3 1998/07/12 23:58:36 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>
6c139d6e 19#include <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{
9c14e3d6 44 return Read(_config->Find("APT::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;
76 char *C = Buffer;
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 /*}}}*/
111// SourceList::SanitizeURI - Hash the uri /*{{{*/
112// ---------------------------------------------------------------------
113/* This converts a URI into a safe filename. It quotes all unsafe characters
114 and converts / to _ and removes the scheme identifier. */
115string pkgSourceList::SanitizeURI(string URI)
116{
117 string::const_iterator I = URI.begin() + URI.find(':') + 1;
118 for (; I < URI.end() && *I == '/'; I++);
119
120 // "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
121 URI = QuoteString(string(I,URI.end() - I),"\\|{}[]<>\"^~_=!@#$%^&*");
122 string::iterator J = URI.begin();
123 for (; J != URI.end(); J++)
124 if (*J == '/')
125 *J = '_';
126 return URI;
127}
128 /*}}}*/
129// SourceList::MatchPkgFile - Find the package file that has the ver /*{{{*/
130// ---------------------------------------------------------------------
131/* This will return List.end() if it could not find the matching
132 file */
133pkgSourceList::const_iterator pkgSourceList::MatchPkgFile(pkgCache::VerIterator Ver)
134{
9c14e3d6 135 string Base = _config->Find("APT::Architecture");
6c139d6e
AL
136 for (const_iterator I = List.begin(); I != List.end(); I++)
137 {
138 string URI = I->PackagesURI();
139 switch (I->Type)
140 {
141 case Item::Deb:
9c14e3d6
AL
142/* if (Base + SanitizeURI(URI) == Ver.File().FileName())
143 return I;*/
6c139d6e
AL
144 break;
145 };
146 }
147 return List.end();
148}
149 /*}}}*/
150// SourceList::Item << - Writes the item to a stream /*{{{*/
151// ---------------------------------------------------------------------
152/* This is not suitable for rebuilding the sourcelist file but it good for
153 debugging. */
154ostream &operator <<(ostream &O,pkgSourceList::Item &Itm)
155{
156 O << Itm.Type << ' ' << Itm.URI << ' ' << Itm.Dist << ' ' << Itm.Section;
157 return O;
158}
159 /*}}}*/
160// SourceList::Item::SetType - Sets the distribution type /*{{{*/
161// ---------------------------------------------------------------------
162/* */
163bool pkgSourceList::Item::SetType(string S)
164{
165 if (S == "deb")
166 {
167 Type = Deb;
168 return true;
169 }
170
171 return true;
172}
173 /*}}}*/
174// SourceList::Item::SetURI - Set the URI /*{{{*/
175// ---------------------------------------------------------------------
176/* For simplicity we strip the scheme off the uri */
177bool pkgSourceList::Item::SetURI(string S)
178{
179 if (S.empty() == true)
180 return false;
181
182 if (S.find(':') == string::npos)
183 return false;
184
9c14e3d6 185 S = SubstVar(S,"$(ARCH)",_config->Find("APT::Architecture"));
6c139d6e
AL
186
187 // Make sure that the URN is / postfixed
188 URI = S;
189 if (URI[URI.size() - 1] != '/')
190 URI += '/';
191
192 return true;
193}
194 /*}}}*/
195// SourceList::Item::PackagesURI - Returns a URI to the packages file /*{{{*/
196// ---------------------------------------------------------------------
197/* */
198string pkgSourceList::Item::PackagesURI() const
199{
200 string Res;
201 switch (Type)
202 {
203 case Deb:
204 if (Dist[Dist.size() - 1] == '/')
205 Res = URI + Dist;
206 else
9c14e3d6
AL
207 Res = URI + "dists/" + Dist + '/' + Section +
208 "/binary-" + _config->Find("APT::Architecture") + '/';
6c139d6e
AL
209
210 Res += "Packages";
211 break;
212 };
213 return Res;
214}
215 /*}}}*/
216// SourceList::Item::PackagesInfo - Shorter version of the URI /*{{{*/
217// ---------------------------------------------------------------------
218/* This is a shorter version that is designed to be < 60 chars or so */
219string pkgSourceList::Item::PackagesInfo() const
220{
221 string Res;
222 switch (Type)
223 {
224 case Deb:
225 Res += SiteOnly(URI) + ' ';
226 if (Dist[Dist.size() - 1] == '/')
227 Res += Dist;
228 else
229 Res += Dist + '/' + Section;
230
231 Res += " Packages";
232 break;
233 };
234 return Res;
235}
236 /*}}}*/
237// SourceList::Item::ArchiveInfo - Shorter version of the archive spec /*{{{*/
238// ---------------------------------------------------------------------
239/* This is a shorter version that is designed to be < 60 chars or so */
240string pkgSourceList::Item::ArchiveInfo(pkgCache::VerIterator Ver) const
241{
242 string Res;
243 switch (Type)
244 {
245 case Deb:
246 Res += SiteOnly(URI) + ' ';
247 if (Dist[Dist.size() - 1] == '/')
248 Res += Dist;
249 else
250 Res += Dist + '/' + Section;
251
252 Res += " ";
253 Res += Ver.ParentPkg().Name();
254 break;
255 };
256 return Res;
257}
258 /*}}}*/
259// SourceList::Item::ArchiveURI - Returns a URI to the given archive /*{{{*/
260// ---------------------------------------------------------------------
261/* */
262string pkgSourceList::Item::ArchiveURI(string File) const
263{
264 string Res;
265 switch (Type)
266 {
267 case Deb:
268 Res = URI + File;
269 break;
270 };
271 return Res;
272}
273 /*}}}*/
274// SourceList::Item::SiteOnly - Strip off the path part of a URI /*{{{*/
275// ---------------------------------------------------------------------
276/* */
277string pkgSourceList::Item::SiteOnly(string URI) const
278{
279 unsigned int Pos = URI.find(':');
280 if (Pos == string::npos || Pos + 3 > URI.length())
281 return URI;
282 if (URI[Pos + 1] != '/' || URI[Pos + 2] != '/')
283 return URI;
284
285 Pos = URI.find('/',Pos + 3);
286 if (Pos == string::npos)
287 return URI;
288 return string(URI,0,Pos);
289}
290 /*}}}*/