]> git.saurik.com Git - apt.git/blob - apt-pkg/sourcelist.cc
Added diff-only and tar-only options
[apt.git] / apt-pkg / sourcelist.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: sourcelist.cc,v 1.15 1999/09/09 06:15:51 jgg 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/configuration.h>
19 #include <apt-pkg/strutl.h>
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 /* */
30 pkgSourceList::pkgSourceList()
31 {
32 }
33
34 pkgSourceList::pkgSourceList(string File)
35 {
36 Read(File);
37 }
38 /*}}}*/
39 // SourceList::ReadMainList - Read the main source list from etc /*{{{*/
40 // ---------------------------------------------------------------------
41 /* */
42 bool pkgSourceList::ReadMainList()
43 {
44 return Read(_config->FindFile("Dir::Etc::sourcelist"));
45 }
46 /*}}}*/
47 // SourceList::Read - Parse the sourcelist file /*{{{*/
48 // ---------------------------------------------------------------------
49 /* */
50 bool 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 const 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());
93 Itm.Dist = SubstVar(Itm.Dist,"$(ARCH)",_config->Find("APT::Architecture"));
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::Item << - Writes the item to a stream /*{{{*/
112 // ---------------------------------------------------------------------
113 /* This is not suitable for rebuilding the sourcelist file but it good for
114 debugging. */
115 ostream &operator <<(ostream &O,pkgSourceList::Item &Itm)
116 {
117 O << (int)Itm.Type << ' ' << Itm.URI << ' ' << Itm.Dist << ' ' << Itm.Section;
118 return O;
119 }
120 /*}}}*/
121 // SourceList::Item::SetType - Sets the distribution type /*{{{*/
122 // ---------------------------------------------------------------------
123 /* */
124 bool pkgSourceList::Item::SetType(string S)
125 {
126 if (S == "deb")
127 {
128 Type = Deb;
129 return true;
130 }
131
132 if (S == "deb-src")
133 {
134 Type = DebSrc;
135 return true;
136 }
137
138 return false;
139 }
140 /*}}}*/
141 // SourceList::Item::SetURI - Set the URI /*{{{*/
142 // ---------------------------------------------------------------------
143 /* For simplicity we strip the scheme off the uri */
144 bool 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
152 S = SubstVar(S,"$(ARCH)",_config->Find("APT::Architecture"));
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 /* */
165 string pkgSourceList::Item::PackagesURI() const
166 {
167 string Res;
168 switch (Type)
169 {
170 case Deb:
171 if (Dist[Dist.size() - 1] == '/')
172 {
173 if (Dist != "/")
174 Res = URI + Dist;
175 }
176 else
177 Res = URI + "dists/" + Dist + '/' + Section +
178 "/binary-" + _config->Find("APT::Architecture") + '/';
179
180 Res += "Packages";
181 break;
182
183 case DebSrc:
184 if (Dist[Dist.size() - 1] == '/')
185 Res = URI + Dist;
186 else
187 Res = URI + "dists/" + Dist + '/' + Section +
188 "/source/";
189
190 Res += "Sources";
191 break;
192 };
193 return Res;
194 }
195 /*}}}*/
196 // SourceList::Item::PackagesInfo - Shorter version of the URI /*{{{*/
197 // ---------------------------------------------------------------------
198 /* This is a shorter version that is designed to be < 60 chars or so */
199 string pkgSourceList::Item::PackagesInfo() const
200 {
201 string Res;
202 switch (Type)
203 {
204 case Deb:
205 Res += SiteOnly(URI) + ' ';
206 if (Dist[Dist.size() - 1] == '/')
207 {
208 if (Dist != "/")
209 Res += Dist;
210 }
211 else
212 Res += Dist + '/' + Section;
213
214 Res += " Packages";
215 break;
216
217 case DebSrc:
218 Res += SiteOnly(URI) + ' ';
219 if (Dist[Dist.size() - 1] == '/')
220 Res += Dist;
221 else
222 Res += Dist + '/' + Section;
223
224 Res += " Sources";
225 break;
226 };
227 return Res;
228 }
229 /*}}}*/
230 // SourceList::Item::ReleaseURI - Returns a URI to the release file /*{{{*/
231 // ---------------------------------------------------------------------
232 /* */
233 string pkgSourceList::Item::ReleaseURI() const
234 {
235 string Res;
236 switch (Type)
237 {
238 case Deb:
239 if (Dist[Dist.size() - 1] == '/')
240 {
241 if (Dist != "/")
242 Res = URI + Dist;
243 }
244 else
245 Res = URI + "dists/" + Dist + '/' + Section +
246 "/binary-" + _config->Find("APT::Architecture") + '/';
247
248 Res += "Release";
249 break;
250
251 case DebSrc:
252 if (Dist[Dist.size() - 1] == '/')
253 Res = URI + Dist;
254 else
255 Res = URI + "dists/" + Dist + '/' + Section +
256 "/source/";
257
258 Res += "Release";
259 break;
260 };
261 return Res;
262 }
263 /*}}}*/
264 // SourceList::Item::ReleaseInfo - Shorter version of the URI /*{{{*/
265 // ---------------------------------------------------------------------
266 /* This is a shorter version that is designed to be < 60 chars or so */
267 string pkgSourceList::Item::ReleaseInfo() const
268 {
269 string Res;
270 switch (Type)
271 {
272 case Deb:
273 case DebSrc:
274 Res += SiteOnly(URI) + ' ';
275 if (Dist[Dist.size() - 1] == '/')
276 {
277 if (Dist != "/")
278 Res += Dist;
279 }
280 else
281 Res += Dist + '/' + Section;
282
283 Res += " Release";
284 break;
285 };
286 return Res;
287 }
288 /*}}}*/
289 // SourceList::Item::ArchiveInfo - Shorter version of the archive spec /*{{{*/
290 // ---------------------------------------------------------------------
291 /* This is a shorter version that is designed to be < 60 chars or so */
292 string pkgSourceList::Item::ArchiveInfo(pkgCache::VerIterator Ver) const
293 {
294 string Res;
295 switch (Type)
296 {
297 case DebSrc:
298 case Deb:
299 Res += SiteOnly(URI) + ' ';
300 if (Dist[Dist.size() - 1] == '/')
301 {
302 if (Dist != "/")
303 Res += Dist;
304 }
305 else
306 Res += Dist + '/' + Section;
307
308 Res += " ";
309 Res += Ver.ParentPkg().Name();
310 Res += " ";
311 Res += Ver.VerStr();
312
313 break;
314 };
315 return Res;
316 }
317 /*}}}*/
318 // SourceList::Item::ArchiveURI - Returns a URI to the given archive /*{{{*/
319 // ---------------------------------------------------------------------
320 /* */
321 string pkgSourceList::Item::ArchiveURI(string File) const
322 {
323 string Res;
324 switch (Type)
325 {
326 case Deb:
327 case DebSrc:
328 Res = URI + File;
329 break;
330 };
331 return Res;
332 }
333 /*}}}*/
334 // SourceList::Item::SourceInfo - Returns an info line for a source /*{{{*/
335 // ---------------------------------------------------------------------
336 /* */
337 string pkgSourceList::Item::SourceInfo(string Pkg,string Ver,string Comp) const
338 {
339 string Res;
340 switch (Type)
341 {
342 case DebSrc:
343 case Deb:
344 Res += SiteOnly(URI) + ' ';
345 if (Dist[Dist.size() - 1] == '/')
346 {
347 if (Dist != "/")
348 Res += Dist;
349 }
350 else
351 Res += Dist + '/' + Section;
352
353 Res += " ";
354 Res += Pkg;
355 Res += " ";
356 Res += Ver;
357 if (Comp.empty() == false)
358 Res += " (" + Comp + ")";
359 break;
360 };
361 return Res;
362 }
363 /*}}}*/
364 // SourceList::Item::SiteOnly - Strip off the path part of a URI /*{{{*/
365 // ---------------------------------------------------------------------
366 /* */
367 string pkgSourceList::Item::SiteOnly(string URI) const
368 {
369 unsigned int Pos = URI.find(':');
370 if (Pos == string::npos || Pos + 3 > URI.length())
371 return URI;
372 if (URI[Pos + 1] != '/' || URI[Pos + 2] != '/')
373 return URI;
374
375 Pos = URI.find('/',Pos + 3);
376 if (Pos == string::npos)
377 return URI;
378 return string(URI,0,Pos);
379 }
380 /*}}}*/